From b095518ef51c37658c58367bd19240b8a113f25c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 12 May 2005 15:45:22 -0400 Subject: [PATCH 0001/1940] [libata] ATA passthru (arbitrary ATA command execution) Authors: Brett Russ John W. Linville Andy Warner --- drivers/scsi/libata-scsi.c | 659 +++++++++++++++++++++++++++++++------ drivers/scsi/libata.h | 3 +- include/scsi/scsi.h | 3 + 3 files changed, 556 insertions(+), 109 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 4c96df060c3b..22c77a113536 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -29,10 +29,13 @@ #include "scsi.h" #include #include +#include #include #include "libata.h" +#define SECTOR_SIZE 512 + typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd); static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev); @@ -67,6 +70,148 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, return 0; } +/** + * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl + * @dev: Device to whom we are issuing command + * @arg: User provided data for issuing command + * + * LOCKING: + * Defined by the SCSI layer. We don't really care. + * + * RETURNS: + * Zero on success, negative errno on error. + */ + +int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) +{ + int rc = 0; + u8 scsi_cmd[MAX_COMMAND_SIZE]; + u8 args[4], *argbuf = NULL; + int argsize = 0; + struct scsi_request *sreq; + + if (NULL == (void *)arg) + return -EINVAL; + + if (copy_from_user(args, arg, sizeof(args))) + return -EFAULT; + + sreq = scsi_allocate_request(scsidev, GFP_KERNEL); + if (!sreq) + return -EINTR; + + memset(scsi_cmd, 0, sizeof(scsi_cmd)); + + if (args[3]) { + argsize = SECTOR_SIZE * args[3]; + argbuf = kmalloc(argsize, GFP_KERNEL); + if (argbuf == NULL) + return -ENOMEM; + + scsi_cmd[1] = (4 << 1); /* PIO Data-in */ + scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, + block count in sector count field */ + sreq->sr_data_direction = DMA_FROM_DEVICE; + } else { + scsi_cmd[1] = (3 << 1); /* Non-data */ + /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ + sreq->sr_data_direction = DMA_NONE; + } + + scsi_cmd[0] = ATA_16; + + scsi_cmd[4] = args[2]; + if (args[0] == WIN_SMART) { /* hack -- ide driver does this too... */ + scsi_cmd[6] = args[3]; + scsi_cmd[8] = args[1]; + scsi_cmd[10] = 0x4f; + scsi_cmd[12] = 0xc2; + } else { + scsi_cmd[6] = args[1]; + } + scsi_cmd[14] = args[0]; + + /* Good values for timeout and retries? Values below + from scsi_ioctl_send_command() for default case... */ + scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5); + + if (sreq->sr_result) { + rc = -EIO; + goto error; + } + + /* Need code to retrieve data from check condition? */ + + if ((argbuf) + && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize)) + rc = -EFAULT; +error: + scsi_release_request(sreq); + + if (argbuf) + kfree(argbuf); + + return rc; +} + +/** + * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl + * @dev: Device to whom we are issuing command + * @arg: User provided data for issuing command + * + * LOCKING: + * Defined by the SCSI layer. We don't really care. + * + * RETURNS: + * Zero on success, negative errno on error. + */ +int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) +{ + int rc = 0; + u8 scsi_cmd[MAX_COMMAND_SIZE]; + u8 args[7]; + struct scsi_request *sreq; + + if (NULL == (void *)arg) + return -EINVAL; + + if (copy_from_user(args, arg, sizeof(args))) + return -EFAULT; + + memset(scsi_cmd, 0, sizeof(scsi_cmd)); + scsi_cmd[0] = ATA_16; + scsi_cmd[1] = (3 << 1); /* Non-data */ + /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ + scsi_cmd[4] = args[1]; + scsi_cmd[6] = args[2]; + scsi_cmd[8] = args[3]; + scsi_cmd[10] = args[4]; + scsi_cmd[12] = args[5]; + scsi_cmd[14] = args[0]; + + sreq = scsi_allocate_request(scsidev, GFP_KERNEL); + if (!sreq) { + rc = -EINTR; + goto error; + } + + sreq->sr_data_direction = DMA_NONE; + /* Good values for timeout and retries? Values below + from scsi_ioctl_send_command() for default case... */ + scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5); + + if (sreq->sr_result) { + rc = -EIO; + goto error; + } + + /* Need code to retrieve data from check condition? */ + +error: + scsi_release_request(sreq); + return rc; +} + int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) { struct ata_port *ap; @@ -96,6 +241,16 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) return -EINVAL; return 0; + case HDIO_DRIVE_CMD: + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) + return -EACCES; + return ata_cmd_ioctl(scsidev, arg); + + case HDIO_DRIVE_TASK: + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) + return -EACCES; + return ata_task_ioctl(scsidev, arg); + default: rc = -ENOTTY; break; @@ -154,24 +309,69 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap, } /** - * ata_to_sense_error - convert ATA error to SCSI error - * @qc: Command that we are erroring out - * @drv_stat: value contained in ATA status register + * ata_dump_status - user friendly display of error info + * @id: id of the port in question + * @tf: ptr to filled out taskfile * - * Converts an ATA error into a SCSI error. While we are at it - * we decode and dump the ATA error for the user so that they - * have some idea what really happened at the non make-believe - * layer. + * Decode and dump the ATA error/status registers for the user so + * that they have some idea what really happened at the non + * make-believe layer. + * + * LOCKING: + * inherited from caller + */ +void ata_dump_status(unsigned id, struct ata_taskfile *tf) +{ + u8 stat = tf->command, err = tf->feature; + + printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat); + if (stat & ATA_BUSY) { + printk("Busy }\n"); /* Data is not valid in this case */ + } else { + if (stat & 0x40) printk("DriveReady "); + if (stat & 0x20) printk("DeviceFault "); + if (stat & 0x10) printk("SeekComplete "); + if (stat & 0x08) printk("DataRequest "); + if (stat & 0x04) printk("CorrectedError "); + if (stat & 0x02) printk("Index "); + if (stat & 0x01) printk("Error "); + printk("}\n"); + + if (err) { + printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err); + if (err & 0x04) printk("DriveStatusError "); + if (err & 0x80) { + if (err & 0x04) printk("BadCRC "); + else printk("Sector "); + } + if (err & 0x40) printk("UncorrectableError "); + if (err & 0x10) printk("SectorIdNotFound "); + if (err & 0x02) printk("TrackZeroNotFound "); + if (err & 0x01) printk("AddrMarkNotFound "); + printk("}\n"); + } + } +} + +/** + * ata_to_sense_error - convert ATA error to SCSI error + * @drv_stat: value contained in ATA status register + * @drv_err: value contained in ATA error register + * @sk: the sense key we'll fill out + * @asc: the additional sense code we'll fill out + * @ascq: the additional sense code qualifier we'll fill out + * + * Converts an ATA error into a SCSI error. Fill out pointers to + * SK, ASC, and ASCQ bytes for later use in fixed or descriptor + * format sense blocks. * * LOCKING: * spin_lock_irqsave(host_set lock) */ - -void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) +void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, + u8 *ascq) { - struct scsi_cmnd *cmd = qc->scsicmd; - u8 err = 0; - unsigned char *sb = cmd->sense_buffer; + int i; /* Based on the 3ware driver translation table */ static unsigned char sense_table[][4] = { /* BBD|ECC|ID|MAR */ @@ -212,105 +412,183 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) {0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; - int i = 0; - - cmd->result = SAM_STAT_CHECK_CONDITION; /* * Is this an error we can process/parse */ - - if(drv_stat & ATA_ERR) - /* Read the err bits */ - err = ata_chk_err(qc->ap); - - /* Display the ATA level error info */ - - printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat); - if(drv_stat & 0x80) - { - printk("Busy "); - err = 0; /* Data is not valid in this case */ + if (drv_stat & ATA_BUSY) { + drv_err = 0; /* Ignore the err bits, they're invalid */ } - else { - if(drv_stat & 0x40) printk("DriveReady "); - if(drv_stat & 0x20) printk("DeviceFault "); - if(drv_stat & 0x10) printk("SeekComplete "); - if(drv_stat & 0x08) printk("DataRequest "); - if(drv_stat & 0x04) printk("CorrectedError "); - if(drv_stat & 0x02) printk("Index "); - if(drv_stat & 0x01) printk("Error "); - } - printk("}\n"); - if(err) - { - printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err); - if(err & 0x04) printk("DriveStatusError "); - if(err & 0x80) - { - if(err & 0x04) - printk("BadCRC "); - else - printk("Sector "); + if (drv_err) { + /* Look for drv_err */ + for (i = 0; sense_table[i][0] != 0xFF; i++) { + /* Look for best matches first */ + if ((sense_table[i][0] & drv_err) == + sense_table[i][0]) { + *sk = sense_table[i][1]; + *asc = sense_table[i][2]; + *ascq = sense_table[i][3]; + goto translate_done; + } } - if(err & 0x40) printk("UncorrectableError "); - if(err & 0x10) printk("SectorIdNotFound "); - if(err & 0x02) printk("TrackZeroNotFound "); - if(err & 0x01) printk("AddrMarkNotFound "); - printk("}\n"); - - /* Should we dump sector info here too ?? */ + /* No immediate match */ + printk(KERN_WARNING "ata%u: no sense translation for " + "error 0x%02x\n", id, drv_err); } - - /* Look for err */ - while(sense_table[i][0] != 0xFF) - { - /* Look for best matches first */ - if((sense_table[i][0] & err) == sense_table[i][0]) - { - sb[0] = 0x70; - sb[2] = sense_table[i][1]; - sb[7] = 0x0a; - sb[12] = sense_table[i][2]; - sb[13] = sense_table[i][3]; - return; - } - i++; - } - /* No immediate match */ - if(err) - printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err); - - i = 0; /* Fall back to interpreting status bits */ - while(stat_table[i][0] != 0xFF) - { - if(stat_table[i][0] & drv_stat) - { - sb[0] = 0x70; - sb[2] = stat_table[i][1]; - sb[7] = 0x0a; - sb[12] = stat_table[i][2]; - sb[13] = stat_table[i][3]; - return; + for (i = 0; stat_table[i][0] != 0xFF; i++) { + if (stat_table[i][0] & drv_stat) { + *sk = stat_table[i][1]; + *asc = stat_table[i][2]; + *ascq = stat_table[i][3]; + goto translate_done; } - i++; } - /* No error ?? */ - printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat); - /* additional-sense-code[-qualifier] */ + /* No error? Undecoded? */ + printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", + id, drv_stat); + + /* For our last chance pick, use medium read error because + * it's much more common than an ATA drive telling you a write + * has failed. + */ + *sk = MEDIUM_ERROR; + *asc = 0x11; /* "unrecovered read error" */ + *ascq = 0x04; /* "auto-reallocation failed" */ + + translate_done: + printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to " + "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err, + *sk, *asc, *ascq); + return; +} + +/* + * ata_gen_ata_desc_sense - Generate check condition sense block. + * @qc: Command that completed. + * + * This function is specific to the ATA descriptor format sense + * block specified for the ATA pass through commands. Regardless + * of whether the command errored or not, return a sense + * block. Copy all controller registers into the sense + * block. Clear sense key, ASC & ASCQ if there is no error. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->tf; + unsigned char *sb = cmd->sense_buffer; + unsigned char *desc = sb + 8; + + memset(sb, 0, SCSI_SENSE_BUFFERSIZE); + + cmd->result = SAM_STAT_CHECK_CONDITION; + + /* + * Read the controller registers. + */ + assert(NULL != qc->ap->ops->tf_read); + qc->ap->ops->tf_read(qc->ap, tf); + + /* + * Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. + */ + if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { + ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + &sb[1], &sb[2], &sb[3]); + sb[1] &= 0x0f; + } + + /* + * Sense data is current and format is descriptor. + */ + sb[0] = 0x72; + + desc[0] = 0x09; + + /* + * Set length of additional sense data. + * Since we only populate descriptor 0, the total + * length is the same (fixed) length as descriptor 0. + */ + desc[1] = sb[7] = 14; + + /* + * Copy registers into sense buffer. + */ + desc[2] = 0x00; + desc[3] = tf->feature; /* == error reg */ + desc[5] = tf->nsect; + desc[7] = tf->lbal; + desc[9] = tf->lbam; + desc[11] = tf->lbah; + desc[12] = tf->device; + desc[13] = tf->command; /* == status reg */ + + /* + * Fill in Extend bit, and the high order bytes + * if applicable. + */ + if (tf->flags & ATA_TFLAG_LBA48) { + desc[2] |= 0x01; + desc[4] = tf->hob_nsect; + desc[6] = tf->hob_lbal; + desc[8] = tf->hob_lbam; + desc[10] = tf->hob_lbah; + } +} + +/** + * ata_gen_fixed_sense - generate a SCSI fixed sense block + * @qc: Command that we are erroring out + * + * Leverage ata_to_sense_error() to give us the codes. Fit our + * LBA in here if there's room. + * + * LOCKING: + * inherited from caller + */ +void ata_gen_fixed_sense(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->tf; + unsigned char *sb = cmd->sense_buffer; + + memset(sb, 0, SCSI_SENSE_BUFFERSIZE); + + cmd->result = SAM_STAT_CHECK_CONDITION; + + /* + * Read the controller registers. + */ + assert(NULL != qc->ap->ops->tf_read); + qc->ap->ops->tf_read(qc->ap, tf); + + /* + * Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. + */ + if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { + ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + &sb[2], &sb[12], &sb[13]); + sb[2] &= 0x0f; + } sb[0] = 0x70; - sb[2] = MEDIUM_ERROR; - sb[7] = 0x0A; - if (cmd->sc_data_direction == DMA_FROM_DEVICE) { - sb[12] = 0x11; /* "unrecovered read error" */ - sb[13] = 0x04; - } else { - sb[12] = 0x0C; /* "write error - */ - sb[13] = 0x02; /* auto-reallocation failed" */ + sb[7] = 0x0a; + if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { + /* A small (28b) LBA will fit in the 32b info field */ + sb[0] |= 0x80; /* set valid bit */ + sb[3] = tf->device & 0x0f; + sb[4] = tf->lbah; + sb[5] = tf->lbam; + sb[6] = tf->lbal; } } @@ -626,11 +904,36 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { struct scsi_cmnd *cmd = qc->scsicmd; + int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); - if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) - ata_to_sense_error(qc, drv_stat); - else - cmd->result = SAM_STAT_GOOD; + /* For ATA pass thru (SAT) commands, generate a sense block if + * user mandated it or if there's an error. Note that if we + * generate because the user forced us to, a check condition + * is generated and the ATA register values are returned + * whether the command completed successfully or not. If there + * was no error, SK, ASC and ASCQ will all be zero. + */ + if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && + ((cmd->cmnd[2] & 0x20) || need_sense)) { + ata_gen_ata_desc_sense(qc); + } else { + if (!need_sense) { + cmd->result = SAM_STAT_GOOD; + } else { + /* TODO: decide which descriptor format to use + * for 48b LBA devices and call that here + * instead of the fixed desc, which is only + * good for smaller LBA (and maybe CHS?) + * devices. + */ + ata_gen_fixed_sense(qc); + } + } + + if (need_sense) { + /* The ata_gen_..._sense routines fill in tf */ + ata_dump_status(qc->ap->id, &qc->tf); + } qc->scsidone(cmd); @@ -671,8 +974,8 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, return; /* data is present; dma-map it */ - if (cmd->sc_data_direction == DMA_FROM_DEVICE || - cmd->sc_data_direction == DMA_TO_DEVICE) { + if (cmd->sc_data_direction == SCSI_DATA_READ || + cmd->sc_data_direction == SCSI_DATA_WRITE) { if (unlikely(cmd->request_bufflen < 1)) { printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", ap->id, dev->devno); @@ -692,7 +995,6 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, if (xlat_func(qc, scsicmd)) goto err_out; - /* select device, send command to hardware */ if (ata_qc_issue(qc)) goto err_out; @@ -1304,7 +1606,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) struct scsi_cmnd *cmd = qc->scsicmd; struct ata_device *dev = qc->dev; int using_pio = (dev->flags & ATA_DFLAG_PIO); - int nodata = (cmd->sc_data_direction == DMA_NONE); + int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE); if (!using_pio) /* Check whether ATAPI DMA is safe */ @@ -1316,7 +1618,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) qc->complete_fn = atapi_qc_complete; qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - if (cmd->sc_data_direction == DMA_TO_DEVICE) { + if (cmd->sc_data_direction == SCSI_DATA_WRITE) { qc->tf.flags |= ATA_TFLAG_WRITE; DPRINTK("direction: write\n"); } @@ -1340,7 +1642,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) #ifdef ATAPI_ENABLE_DMADIR /* some SATA bridges need us to indicate data xfer direction */ - if (cmd->sc_data_direction != DMA_TO_DEVICE) + if (cmd->sc_data_direction != SCSI_DATA_WRITE) qc->tf.feature |= ATAPI_DMADIR; #endif } @@ -1393,6 +1695,143 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev) return dev; } +/* + * ata_scsi_map_proto - Map pass-thru protocol value to taskfile value. + * @byte1: Byte 1 from pass-thru CDB. + * + * RETURNS: + * ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise. + */ +static u8 +ata_scsi_map_proto(u8 byte1) +{ + switch((byte1 & 0x1e) >> 1) { + case 3: /* Non-data */ + return ATA_PROT_NODATA; + + case 6: /* DMA */ + return ATA_PROT_DMA; + + case 4: /* PIO Data-in */ + case 5: /* PIO Data-out */ + if (byte1 & 0xe0) { + return ATA_PROT_PIO_MULT; + } + return ATA_PROT_PIO; + + case 10: /* Device Reset */ + case 0: /* Hard Reset */ + case 1: /* SRST */ + case 2: /* Bus Idle */ + case 7: /* Packet */ + case 8: /* DMA Queued */ + case 9: /* Device Diagnostic */ + case 11: /* UDMA Data-in */ + case 12: /* UDMA Data-Out */ + case 13: /* FPDMA */ + default: /* Reserved */ + break; + } + + return ATA_PROT_UNKNOWN; +} + +/** + * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile + * @qc: command structure to be initialized + * @cmd: SCSI command to convert + * + * Handles either 12 or 16-byte versions of the CDB. + * + * RETURNS: + * Zero on success, non-zero on failure. + */ +static unsigned int +ata_scsi_pass_thru(struct ata_queued_cmd *qc, u8 *scsicmd) +{ + struct ata_taskfile *tf = &(qc->tf); + struct scsi_cmnd *cmd = qc->scsicmd; + + if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) + return 1; + + /* + * 12 and 16 byte CDBs use different offsets to + * provide the various register values. + */ + if (scsicmd[0] == ATA_16) { + /* + * 16-byte CDB - may contain extended commands. + * + * If that is the case, copy the upper byte register values. + */ + if (scsicmd[1] & 0x01) { + tf->hob_feature = scsicmd[3]; + tf->hob_nsect = scsicmd[5]; + tf->hob_lbal = scsicmd[7]; + tf->hob_lbam = scsicmd[9]; + tf->hob_lbah = scsicmd[11]; + tf->flags |= ATA_TFLAG_LBA48; + } else + tf->flags &= ~ATA_TFLAG_LBA48; + + /* + * Always copy low byte, device and command registers. + */ + tf->feature = scsicmd[4]; + tf->nsect = scsicmd[6]; + tf->lbal = scsicmd[8]; + tf->lbam = scsicmd[10]; + tf->lbah = scsicmd[12]; + tf->device = scsicmd[13]; + tf->command = scsicmd[14]; + } else { + /* + * 12-byte CDB - incapable of extended commands. + */ + tf->flags &= ~ATA_TFLAG_LBA48; + + tf->feature = scsicmd[3]; + tf->nsect = scsicmd[4]; + tf->lbal = scsicmd[5]; + tf->lbam = scsicmd[6]; + tf->lbah = scsicmd[7]; + tf->device = scsicmd[8]; + tf->command = scsicmd[9]; + } + + /* + * Filter SET_FEATURES - XFER MODE command -- otherwise, + * SET_FEATURES - XFER MODE must be preceded/succeeded + * by an update to hardware-specific registers for each + * controller (i.e. the reason for ->set_piomode(), + * ->set_dmamode(), and ->post_set_mode() hooks). + */ + if ((tf->command == ATA_CMD_SET_FEATURES) + && (tf->feature == SETFEATURES_XFER)) + return 1; + + /* + * Set flags so that all registers will be written, + * and pass on write indication (used for PIO/DMA + * setup.) + */ + tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE); + + if (cmd->sc_data_direction == SCSI_DATA_WRITE) + tf->flags |= ATA_TFLAG_WRITE; + + /* + * Set transfer length. + * + * TODO: find out if we need to do more here to + * cover scatter/gather case. + */ + qc->nsect = cmd->bufflen / ATA_SECT_SIZE; + + return 0; +} + /** * ata_get_xlat_func - check if SCSI to ATA translation is possible * @dev: ATA device @@ -1425,6 +1864,10 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case VERIFY: case VERIFY_16: return ata_scsi_verify_xlat; + + case ATA_12: + case ATA_16: + return ata_scsi_pass_thru; } return NULL; @@ -1581,7 +2024,7 @@ void ata_scsi_simulate(u16 *id, ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); break; - /* mandantory commands we haven't implemented yet */ + /* mandatory commands we haven't implemented yet */ case REQUEST_SENSE: /* all other commands */ diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 6518226b8f87..c595f5f58c16 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -44,10 +44,11 @@ extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf); extern void swap_buf_le16(u16 *buf, unsigned int buf_words); +extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); +extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); /* libata-scsi.c */ -extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat); extern int ata_scsi_error(struct Scsi_Host *host); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen); diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 659ecf48fb4a..27d4d9ea6c6d 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -113,6 +113,9 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; /* values for service action in */ #define SAI_READ_CAPACITY_16 0x10 +/* Values for T10/04-262r7 */ +#define ATA_16 0x85 /* 16-byte pass-thru */ +#define ATA_12 0xa1 /* 12-byte pass-thru */ /* * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft From 36358c21423d58dde90aedde2b8517192c4092f4 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 2 Jun 2005 20:01:16 -0500 Subject: [PATCH 0002/1940] [CIFS] fs/cifs/netmisc.c: fix sparse warning Signed-off-by: Steve French Signed-off-by: Alexey Dobriyan Signed-off-by: Domen Puncer --- fs/cifs/netmisc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index a92af41d4411..873b812c0f40 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -133,7 +133,6 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { int cifs_inet_pton(int address_family, char *cp,void *dst) { - struct in_addr address; int value; int digit; int i; @@ -190,8 +189,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst) if (value > addr_class_max[end - bytes]) return 0; - address.s_addr = *((__be32 *) bytes) | htonl(value); - *((__be32 *)dst) = address.s_addr; + *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value); return 1; /* success */ } From d6e04ae64c6b06ef76a5d4fb49106b393b7fa50a Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 13 Jun 2005 13:24:43 -0500 Subject: [PATCH 0003/1940] [CIFS] CIFS writepage improvements - eliminate double copy Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsproto.h | 6 +- fs/cifs/cifssmb.c | 57 ++++++----- fs/cifs/file.c | 21 ++++- fs/cifs/transport.c | 225 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 232 insertions(+), 77 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ea239dea571e..b43ac9230eab 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -47,6 +47,10 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , int * /* bytes returned */ , const int long_op); +extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, + struct smb_hdr * /* input */ , int hdr_len, + const char * /* SMB data to send */ , int data_len, + int * /* bytes returned */ , const int long_op); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb); @@ -222,7 +226,7 @@ extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, const int netfid, const unsigned int count, const __u64 offset, unsigned int *nbytes, - const char __user *buf,const int long_op); + const char *buf,const int long_op); extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, __u64 * inode_number, const struct nls_table *nls_codepage, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3c628bf667a5..b4f7b9859e3b 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -951,56 +951,69 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, } #ifdef CONFIG_CIFS_EXPERIMENTAL -int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, +int +CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, const int netfid, const unsigned int count, - const __u64 offset, unsigned int *nbytes, const char __user *buf, + const __u64 offset, unsigned int *nbytes, const char *buf, const int long_op) { int rc = -EACCES; WRITE_REQ *pSMB = NULL; - WRITE_RSP *pSMBr = NULL; - /*int bytes_returned;*/ - unsigned bytes_sent; + int bytes_returned; + int smb_hdr_len; + __u32 bytes_sent; __u16 byte_count; + cERROR(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); - if (rc) return rc; - - pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */ - /* tcon and ses pointer are checked in smb_init */ if (tcon->ses->server == NULL) return -ECONNABORTED; - pSMB->AndXCommand = 0xFF; /* none */ + pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = netfid; pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); pSMB->OffsetHigh = cpu_to_le32(offset >> 32); pSMB->Reserved = 0xFFFFFFFF; pSMB->WriteMode = 0; pSMB->Remaining = 0; - bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF; + + /* Can increase buffer size if buffer is big enough in some cases - ie + can send more if LARGE_WRITE_X capability returned by the server and if + our buffer is big enough or if we convert to iovecs on socket writes + and eliminate the copy to the CIFS buffer */ + if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) { + bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); + } else { + bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) + & ~0xFF; + } + if (bytes_sent > count) bytes_sent = count; - pSMB->DataLengthHigh = 0; pSMB->DataOffset = cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); - byte_count = bytes_sent + 1 /* pad */ ; - pSMB->DataLengthLow = cpu_to_le16(bytes_sent); - pSMB->DataLengthHigh = 0; - pSMB->hdr.smb_buf_length += byte_count; + byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */ + pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); + pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); + smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ + pSMB->hdr.smb_buf_length += bytes_sent+1; pSMB->ByteCount = cpu_to_le16(byte_count); -/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */ + rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len, + buf, bytes_sent, &bytes_returned, long_op); if (rc) { - cFYI(1, ("Send error in write2 (large write) = %d", rc)); + cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; - } else - *nbytes = le16_to_cpu(pSMBr->Count); + } else { + WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB; + *nbytes = le16_to_cpu(pSMBr->CountHigh); + *nbytes = (*nbytes) << 16; + *nbytes += le16_to_cpu(pSMBr->Count); + } cifs_small_buf_release(pSMB); @@ -1009,6 +1022,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, return rc; } + + #endif /* CIFS_EXPERIMENTAL */ int diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dde2d251fc3d..ca74c1151be9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -791,9 +791,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data, pTcon = cifs_sb->tcon; - /* cFYI(1, - (" write %d bytes to offset %lld of %s", write_size, - *poffset, file->f_dentry->d_name.name)); */ + cFYI(1,(" write %d bytes to offset %lld of %s", write_size, + *poffset, file->f_dentry->d_name.name)); /* BB removeme BB */ if (file->private_data == NULL) return -EBADF; @@ -846,7 +845,21 @@ static ssize_t cifs_write(struct file *file, const char *write_data, if (rc != 0) break; } - +#ifdef CIFS_EXPERIMENTAL + /* BB FIXME We can not sign across two buffers yet */ + cERROR(1,("checking signing")); /* BB removeme BB */ + if(pTcon->ses->server->secMode & + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED) == 0) + rc = CIFSSMBWrite2(xid, pTcon, + open_file->netfid, + min_t(const int, cifs_sb->wsize, + write_size - total_written), + *poffset, &bytes_written, + write_data + total_written, + long_op); + } else + /* BB FIXME fixup indentation of line below */ +#endif rc = CIFSSMBWrite(xid, pTcon, open_file->netfid, min_t(const int, cifs_sb->wsize, diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 0046c219833d..04f4af07fdd4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -49,7 +49,8 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) return NULL; } - temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS); + temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, + SLAB_KERNEL | SLAB_NOFS); if (temp == NULL) return temp; else { @@ -179,27 +180,24 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, return rc; } -#ifdef CIFS_EXPERIMENTAL -/* BB finish off this function, adding support for writing set of pages as iovec */ -/* and also adding support for operations that need to parse the response smb */ - -int -smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, - unsigned int smb_buf_length, struct kvec * write_vector - /* page list */, struct sockaddr *sin) +#ifdef CONFIG_CIFS_EXPERIMENTAL +static int +smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, + unsigned int smb_hdr_length, const char * data, unsigned int datalen, + struct sockaddr *sin) { int rc = 0; int i = 0; struct msghdr smb_msg; - number_of_pages += 1; /* account for SMB header */ - struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); - unsigned len = smb_buf_length + 4; - + struct kvec iov[2]; + unsigned len = smb_hdr_length + 4; + if(ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ - iov.iov_base = smb_buffer; - iov.iov_len = len; - + iov[0].iov_base = smb_buffer; + iov[0].iov_len = len; + iov[1].iov_base = data; + iov[2].iov_len = datalen; smb_msg.msg_name = sin; smb_msg.msg_namelen = sizeof (struct sockaddr); smb_msg.msg_control = NULL; @@ -212,12 +210,11 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, Flags2 is converted in SendReceive */ smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); - cFYI(1, ("Sending smb of length %d ", smb_buf_length)); + cFYI(1, ("Sending smb of length %d ", len + datalen)); dump_smb(smb_buffer, len); - while (len > 0) { - rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, - len); + while (len + datalen > 0) { + rc = kernel_sendmsg(ssocket, &smb_msg, iov, 2, len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; if(i > 60) { @@ -232,9 +229,22 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, } if (rc < 0) break; - iov.iov_base += rc; - iov.iov_len -= rc; - len -= rc; + if(iov[0].iov_len > 0) { + if(rc >= len) { + iov[0].iov_len = 0; + rc -= len; + } else { /* some of hdr was not sent */ + len -= rc; + iov[0].iov_len -= rc; + iov[0].iov_base += rc; + continue; + } + } + if((iov[0].iov_len == 0) && (rc > 0)){ + iov[1].iov_base += rc; + iov[1].iov_len -= rc; + datalen -= rc; + } } if (rc < 0) { @@ -246,14 +256,15 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, return rc; } - int -CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, - struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op) +SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, + struct smb_hdr *in_buf, int hdrlen, const char * data, + int datalen, int *pbytes_returned, const int long_op) { int rc = 0; - unsigned long timeout = 15 * HZ; - struct mid_q_entry *midQ = NULL; + unsigned int receive_len; + unsigned long timeout; + struct mid_q_entry *midQ; if (ses == NULL) { cERROR(1,("Null smb session")); @@ -263,14 +274,8 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, cERROR(1,("Null tcp session")); return -EIO; } - if(pbytes_returned == NULL) - return -EIO; - else - *pbytes_returned = 0; - - - if(ses->server->tcpStatus == CIFS_EXITING) + if(ses->server->tcpStatus == CifsExiting) return -ENOENT; /* Ensure that we do not send more than 50 overlapping requests @@ -282,7 +287,8 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, } else { spin_lock(&GlobalMid_Lock); while(1) { - if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ + if(atomic_read(&ses->server->inFlight) >= + cifs_max_pending){ spin_unlock(&GlobalMid_Lock); wait_event(ses->server->request_q, atomic_read(&ses->server->inFlight) @@ -314,17 +320,17 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, if (ses->server->tcpStatus == CifsExiting) { rc = -ENOENT; - goto cifs_out_label; + goto out_unlock2; } else if (ses->server->tcpStatus == CifsNeedReconnect) { cFYI(1,("tcp session dead - return to caller to retry")); rc = -EAGAIN; - goto cifs_out_label; + goto out_unlock2; } else if (ses->status != CifsGood) { /* check if SMB session is bad because we are setting it up */ if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && (in_buf->Command != SMB_COM_NEGOTIATE)) { rc = -EAGAIN; - goto cifs_out_label; + goto out_unlock2; } /* else ok - we are setting up session */ } midQ = AllocMidQEntry(in_buf, ses); @@ -352,13 +358,12 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, return -EIO; } - /* BB can we sign efficiently in this path? */ - rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); +/* BB FIXME */ +/* rc = cifs_sign_smb2(in_buf, data, ses->server, &midQ->sequence_number); */ midQ->midState = MID_REQUEST_SUBMITTED; -/* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, - piovec, - (struct sockaddr *) &(ses->server->addr.sockAddr));*/ + rc = smb_send2(ses->server->ssocket, in_buf, hdrlen, data, datalen, + (struct sockaddr *) &(ses->server->addr.sockAddr)); if(rc < 0) { DeleteMidQEntry(midQ); up(&ses->server->tcpSem); @@ -370,19 +375,137 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, return rc; } else up(&ses->server->tcpSem); -cifs_out_label: - if(midQ) - DeleteMidQEntry(midQ); - + if (long_op == -1) + goto cifs_no_response_exit2; + else if (long_op == 2) /* writes past end of file can take loong time */ + timeout = 300 * HZ; + else if (long_op == 1) + timeout = 45 * HZ; /* should be greater than + servers oplock break timeout (about 43 seconds) */ + else if (long_op > 2) { + timeout = MAX_SCHEDULE_TIMEOUT; + } else + timeout = 15 * HZ; + /* wait for 15 seconds or until woken up due to response arriving or + due to last connection to this server being unmounted */ + if (signal_pending(current)) { + /* if signal pending do not hold up user for full smb timeout + but we still give response a change to complete */ + timeout = 2 * HZ; + } + + /* No user interrupts in wait - wreaks havoc with performance */ + if(timeout != MAX_SCHEDULE_TIMEOUT) { + timeout += jiffies; + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + time_after(jiffies, timeout) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } else { + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } + + spin_lock(&GlobalMid_Lock); + if (midQ->resp_buf) { + spin_unlock(&GlobalMid_Lock); + receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); + } else { + cERROR(1,("No response buffer")); + if(midQ->midState == MID_REQUEST_SUBMITTED) { + if(ses->server->tcpStatus == CifsExiting) + rc = -EHOSTDOWN; + else { + ses->server->tcpStatus = CifsNeedReconnect; + midQ->midState = MID_RETRY_NEEDED; + } + } + + if (rc != -EHOSTDOWN) { + if(midQ->midState == MID_RETRY_NEEDED) { + rc = -EAGAIN; + cFYI(1,("marking request for retry")); + } else { + rc = -EIO; + } + } + spin_unlock(&GlobalMid_Lock); + DeleteMidQEntry(midQ); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return rc; + } + + if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { + cERROR(1, ("Frame too large received. Length: %d Xid: %d", + receive_len, xid)); + rc = -EIO; + } else { /* rcvd frame is ok */ + + if (midQ->resp_buf && + (midQ->midState == MID_RESPONSE_RECEIVED)) { + in_buf->smb_buf_length = receive_len; + /* BB verify that length would not overrun small buf */ + memcpy((char *)in_buf + 4, + (char *)midQ->resp_buf + 4, + receive_len); + + dump_smb(in_buf, 80); + /* convert the length into a more usable form */ + if((receive_len > 24) && + (ses->server->secMode & (SECMODE_SIGN_REQUIRED | + SECMODE_SIGN_ENABLED))) { + rc = cifs_verify_signature(in_buf, + ses->server->mac_signing_key, + midQ->sequence_number+1); + if(rc) { + cERROR(1,("Unexpected SMB signature")); + /* BB FIXME add code to kill session */ + } + } + + *pbytes_returned = in_buf->smb_buf_length; + + /* BB special case reconnect tid and uid here? */ + rc = map_smb_to_linux_error(in_buf); + + /* convert ByteCount if necessary */ + if (receive_len >= + sizeof (struct smb_hdr) - + 4 /* do not count RFC1001 header */ + + (2 * in_buf->WordCount) + 2 /* bcc */ ) + BCC(in_buf) = le16_to_cpu(BCC(in_buf)); + } else { + rc = -EIO; + cFYI(1,("Bad MID state? ")); + } + } +cifs_no_response_exit2: + DeleteMidQEntry(midQ); + if(long_op < 3) { - atomic_dec(&ses->server->inFlight); + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + + return rc; + +out_unlock2: + up(&ses->server->tcpSem); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return rc; } - - #endif /* CIFS_EXPERIMENTAL */ int From 0274aa2506fd2fe89a58dd6cd64d3b3f7b976af8 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 22 Jun 2005 13:50:56 -0400 Subject: [PATCH 0004/1940] libata: Update 'passthru' branch for latest libata --- drivers/scsi/libata-scsi.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index cdc0a10a606c..c1cf5e038967 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -582,7 +582,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[0] = 0x70; sb[7] = 0x0a; + +#if 0 /* when C/H/S support is merged */ if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { +#endif + if (!(tf->flags & ATA_TFLAG_LBA48)) { /* A small (28b) LBA will fit in the 32b info field */ sb[0] |= 0x80; /* set valid bit */ sb[3] = tf->device & 0x0f; @@ -977,8 +981,8 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, return; /* data is present; dma-map it */ - if (cmd->sc_data_direction == SCSI_DATA_READ || - cmd->sc_data_direction == SCSI_DATA_WRITE) { + if (cmd->sc_data_direction == DMA_FROM_DEVICE || + cmd->sc_data_direction == DMA_TO_DEVICE) { if (unlikely(cmd->request_bufflen < 1)) { printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", ap->id, dev->devno); @@ -1609,7 +1613,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) struct scsi_cmnd *cmd = qc->scsicmd; struct ata_device *dev = qc->dev; int using_pio = (dev->flags & ATA_DFLAG_PIO); - int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE); + int nodata = (cmd->sc_data_direction == DMA_NONE); if (!using_pio) /* Check whether ATAPI DMA is safe */ @@ -1621,7 +1625,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) qc->complete_fn = atapi_qc_complete; qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - if (cmd->sc_data_direction == SCSI_DATA_WRITE) { + if (cmd->sc_data_direction == DMA_TO_DEVICE) { qc->tf.flags |= ATA_TFLAG_WRITE; DPRINTK("direction: write\n"); } @@ -1645,7 +1649,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) #ifdef ATAPI_ENABLE_DMADIR /* some SATA bridges need us to indicate data xfer direction */ - if (cmd->sc_data_direction != SCSI_DATA_WRITE) + if (cmd->sc_data_direction != DMA_TO_DEVICE) qc->tf.feature |= ATAPI_DMADIR; #endif } @@ -1821,7 +1825,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, u8 *scsicmd) */ tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE); - if (cmd->sc_data_direction == SCSI_DATA_WRITE) + if (cmd->sc_data_direction == DMA_TO_DEVICE) tf->flags |= ATA_TFLAG_WRITE; /* From dfb7533b5f157ac7135da23883e80d895227d965 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 22 Jun 2005 17:13:47 -0700 Subject: [PATCH 0005/1940] [CIFS] Add stats for findfirst, findnext, findclose Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsglob.h | 3 +++ fs/cifs/cifssmb.c | 13 ++++++++++++- fs/cifs/readdir.c | 16 ++++++++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 81babab265e1..4ed9c13fff55 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -219,6 +219,9 @@ struct cifsTconInfo { atomic_t num_rmdirs; atomic_t num_renames; atomic_t num_t2renames; + atomic_t num_ffirst; + atomic_t num_fnext; + atomic_t num_fclose; __u64 bytes_read; __u64 bytes_written; spinlock_t stat_lock; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3c628bf667a5..b31158a2643d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2396,7 +2396,9 @@ int CIFSFindSingle(const int xid, struct cifsTconInfo *tcon, if (rc) { cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); } else { /* decode response */ - +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_ffirst); +#endif /* BB fill in */ } @@ -2509,6 +2511,9 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, if (rc == -EAGAIN) goto findFirstRetry; } else { /* decode response */ +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_ffirst); +#endif /* BB remember to free buffer if error BB */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); if(rc == 0) { @@ -2622,6 +2627,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, } else cFYI(1, ("FindNext returned = %d", rc)); } else { /* decode response */ +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_fnext); +#endif rc = validate_t2((struct smb_t2_rsp *)pSMBr); if(rc == 0) { @@ -2691,6 +2699,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle if (rc) { cERROR(1, ("Send error in FindClose = %d", rc)); } +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_fclose); +#endif cifs_small_buf_release(pSMB); /* Since session is dead, search handle closed on server already */ diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 22557716f9af..487221eeddb7 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -190,8 +190,9 @@ static void fill_in_inode(struct inode *tmp_inode, tmp_inode->i_data.a_ops = &cifs_addr_ops; if(isNewInode) - return; /* No sense invalidating pages for new inode since we - have not started caching readahead file data yet */ + return; /* No sense invalidating pages for new inode + since have not started caching readahead file + data yet */ if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && (local_size == tmp_inode->i_size)) { @@ -536,7 +537,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ cFYI(1,("calling findnext2")); - rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf); + rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, + &cifsFile->srch_inf); if(rc) return -ENOENT; } @@ -555,7 +557,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); current_entry = cifsFile->srch_inf.srch_entries_start; for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { - /* go entry to next entry figuring out which we need to start with */ + /* go entry by entry figuring out which is first */ /* if( . or ..) skip */ rc = cifs_entry_is_dot(current_entry,cifsFile); @@ -721,7 +723,8 @@ static int cifs_filldir(char *pfindEntry, struct file *file, (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc); } - rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type); + rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, + tmp_inode->i_ino,obj_type); if(rc) { cFYI(1,("filldir rc = %d",rc)); } @@ -906,7 +909,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) cifs_save_resume_key(current_entry,cifsFile); break; } else - current_entry = nxt_dir_entry(current_entry,end_of_smb); + current_entry = nxt_dir_entry(current_entry, + end_of_smb); } kfree(tmp_buf); break; From ac67055ef2378ea95c34b593ddf9d0a0737a240a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Jun 2005 17:26:35 -0700 Subject: [PATCH 0006/1940] [CIFS] POSIX extensions, SetFSInfo added Signed-off-by: Steve French@sfrench@us.ibm.com Signed-off-by: Jeremy Allison (jra@samba.org) --- fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifsglob.h | 7 ++++ fs/cifs/cifspdu.h | 46 ++++++++++++++++++++++++++ fs/cifs/cifsproto.h | 7 ++-- fs/cifs/cifssmb.c | 77 ++++++++++++++++++++++++++++++++++++++++++-- fs/cifs/connect.c | 20 ++++++++++++ fs/cifs/dir.c | 10 +++--- fs/cifs/fcntl.c | 2 +- fs/cifs/file.c | 4 +-- fs/cifs/inode.c | 14 ++++---- fs/cifs/link.c | 15 +++++---- fs/cifs/readdir.c | 4 +-- fs/cifs/xattr.c | 8 ++--- 13 files changed, 182 insertions(+), 33 deletions(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index ec00d61d5308..5dc5fe6b486d 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -24,6 +24,7 @@ #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ +#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ struct cifs_sb_info { struct cifsTconInfo *tcon; /* primary mount */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 4ed9c13fff55..d3773e57acf9 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -309,6 +309,13 @@ CIFS_SB(struct super_block *sb) return sb->s_fs_info; } +static inline const char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) +{ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) + return '/'; + else + return '\\'; +} /* one of these for every pending CIFS request to the server */ struct mid_q_entry { diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index aede6a813167..84d37f8e986e 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -59,6 +59,7 @@ #define TRANS2_FIND_FIRST 0x01 #define TRANS2_FIND_NEXT 0x02 #define TRANS2_QUERY_FS_INFORMATION 0x03 +#define TRANS2_SET_FS_INFORMATION 0x04 #define TRANS2_QUERY_PATH_INFORMATION 0x05 #define TRANS2_SET_PATH_INFORMATION 0x06 #define TRANS2_QUERY_FILE_INFORMATION 0x07 @@ -1411,6 +1412,43 @@ typedef struct smb_com_transaction_qfsi_rsp { __u8 Pad; /* may be three bytes *//* followed by data area */ } TRANSACTION2_QFSI_RSP; + +/* SETFSInfo Levels */ +#define SMB_SET_CIFS_UNIX_INFO 0x200 +typedef struct smb_com_transaction2_setfsi_req { + struct smb_hdr hdr; /* wct = 15 */ + __le16 TotalParameterCount; + __le16 TotalDataCount; + __le16 MaxParameterCount; + __le16 MaxDataCount; + __u8 MaxSetupCount; + __u8 Reserved; + __le16 Flags; + __le32 Timeout; + __u16 Reserved2; + __le16 ParameterCount; /* 4 */ + __le16 ParameterOffset; + __le16 DataCount; /* 12 */ + __le16 DataOffset; + __u8 SetupCount; /* one */ + __u8 Reserved3; + __le16 SubCommand; /* TRANS2_SET_FS_INFORMATION */ + __le16 ByteCount; + __u8 Pad; + __u16 FileNum; /* Parameters start. */ + __le16 InformationLevel;/* Parameters end. */ + __le16 ClientUnixMajor; /* Data start. */ + __le16 ClientUnixMinor; + __le64 ClientUnixCap; /* Data end */ +} TRANSACTION2_SETFSI_REQ; + +typedef struct smb_com_transaction2_setfsi_rsp { + struct smb_hdr hdr; /* wct = 10 */ + struct trans2_resp t2; + __u16 ByteCount; +} TRANSACTION2_SETFSI_RSP; + + typedef struct smb_com_transaction2_get_dfs_refer_req { struct smb_hdr hdr; /* wct = 15 */ __le16 TotalParameterCount; @@ -1551,12 +1589,20 @@ typedef struct { __le16 MinorVersionNumber; __le64 Capability; } FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ + +/* Version numbers for CIFS UNIX major and minor. */ +#define CIFS_UNIX_MAJOR_VERSION 1 +#define CIFS_UNIX_MINOR_VERSION 0 + /* Linux/Unix extensions capability flags */ #define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ #define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ #define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ +#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */ + #define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ + typedef struct { /* For undefined recommended transfer size return -1 in that field */ __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ea239dea571e..db2adf0b206c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -40,7 +40,7 @@ extern unsigned int _GetXid(void); extern void _FreeXid(unsigned int); #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} -extern char *build_path_from_dentry(struct dentry *); +extern char *build_path_from_dentry(struct dentry *, const struct cifs_sb_info *cifs_sb); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern void renew_parental_timestamps(struct dentry *direntry); extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, @@ -89,7 +89,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, const char *searchName, const struct nls_table *nls_codepage, - __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map); + __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep); extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, __u16 searchHandle, struct cifs_search_info * psrch_inf); @@ -125,6 +125,9 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, int remap); extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData); +extern int CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, + __u64 cap); + extern int CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b31158a2643d..81c9d3f393f5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2416,7 +2416,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, const char *searchName, const struct nls_table *nls_codepage, __u16 * pnetfid, - struct cifs_search_info * psrch_inf, int remap) + struct cifs_search_info * psrch_inf, int remap, const char dirsep) { /* level 257 SMB_ */ TRANSACTION2_FFIRST_REQ *pSMB = NULL; @@ -2443,7 +2443,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, it got remapped to 0xF03A as if it were part of the directory name instead of a wildcard */ name_len *= 2; - pSMB->FileName[name_len] = '\\'; + pSMB->FileName[name_len] = dirsep; pSMB->FileName[name_len+1] = 0; pSMB->FileName[name_len+2] = '*'; pSMB->FileName[name_len+3] = 0; @@ -2457,7 +2457,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, if(name_len > buffersize-header) free buffer exit; BB */ strncpy(pSMB->FileName, searchName, name_len); - pSMB->FileName[name_len] = '\\'; + pSMB->FileName[name_len] = dirsep; pSMB->FileName[name_len+1] = '*'; pSMB->FileName[name_len+2] = 0; name_len += 3; @@ -3265,6 +3265,77 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) return rc; } +int +CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) +{ +/* level 0x200 SMB_SET_CIFS_UNIX_INFO */ + TRANSACTION2_SETFSI_REQ *pSMB = NULL; + TRANSACTION2_SETFSI_RSP *pSMBr = NULL; + int rc = 0; + int bytes_returned = 0; + __u16 params, param_offset, offset, byte_count; + + cFYI(1, ("In SETFSUnixInfo")); +SETFSUnixRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + params = 4; /* 2 bytes zero followed by info level. */ + pSMB->MaxSetupCount = 0; + pSMB->Reserved = 0; + pSMB->Flags = 0; + pSMB->Timeout = 0; + pSMB->Reserved2 = 0; + param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4; + offset = param_offset + params; + + pSMB->MaxParameterCount = cpu_to_le16(4); + pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */ + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); + byte_count = 1 /* pad */ + params + 12; + + pSMB->DataCount = cpu_to_le16(12); + pSMB->ParameterCount = cpu_to_le16(params); + pSMB->TotalDataCount = pSMB->DataCount; + pSMB->TotalParameterCount = pSMB->ParameterCount; + pSMB->ParameterOffset = cpu_to_le16(param_offset); + pSMB->DataOffset = cpu_to_le16(offset); + + /* Params. */ + pSMB->FileNum = 0; + pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); + + /* Data. */ + pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); + pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); + pSMB->ClientUnixCap = cpu_to_le64(cap); + + pSMB->hdr.smb_buf_length += byte_count; + pSMB->ByteCount = cpu_to_le16(byte_count); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cERROR(1, ("Send error in SETFSUnixInfo = %d", rc)); + } else { /* decode response */ + rc = validate_t2((struct smb_t2_rsp *)pSMBr); + if (rc) { + rc = -EIO; /* bad smb */ + } + } + cifs_buf_release(pSMB); + + if (rc == -EAGAIN) + goto SETFSUnixRetry; + + return rc; +} + + int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e568cc47a7f9..bef5d6f30975 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -74,6 +74,7 @@ struct smb_vol { unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ unsigned direct_io:1; unsigned remap:1; /* set to remap seven reserved chars in filenames */ + unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ unsigned int rsize; unsigned int wsize; unsigned int sockopt; @@ -745,6 +746,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ vol->rw = TRUE; + /* default is always to request posix paths. */ + vol->posix_paths = 1; + if (!options) return 1; @@ -1023,6 +1027,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->remap = 1; } else if (strnicmp(data, "nomapchars", 10) == 0) { vol->remap = 0; + } else if (strnicmp(data, "posixpaths", 10) == 0) { + vol->posix_paths = 1; + } else if (strnicmp(data, "noposixpaths", 12) == 0) { + vol->posix_paths = 0; } else if (strnicmp(data, "setuids", 7) == 0) { vol->setuids = 1; } else if (strnicmp(data, "nosetuids", 9) == 0) { @@ -1679,6 +1687,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; if(volume_info.no_xattr) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; + if(volume_info.direct_io) { cERROR(1,("mounting share using direct i/o")); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; @@ -1781,6 +1790,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cFYI(1,("server negotiated posix acl support")); sb->s_flags |= MS_POSIXACL; } + + /* Try and negotiate POSIX pathnames if we can. */ + if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & + le64_to_cpu(tcon->fsUnixInfo.Capability))) { + if (!CIFSSMBSETFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP, 0)) { + cFYI(1,("negotiated posix pathnames support")); + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; + } else { + cFYI(1,("posix pathnames support requested but not supported")); + } + } } } } diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3f3538d4a1fa..9360d8fb9ef7 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -43,7 +43,7 @@ renew_parental_timestamps(struct dentry *direntry) /* Note: caller must free return buffer */ char * -build_path_from_dentry(struct dentry *direntry) +build_path_from_dentry(struct dentry *direntry, const struct cifs_sb_info *cifs_sb) { struct dentry *temp; int namelen = 0; @@ -74,7 +74,7 @@ build_path_from_dentry(struct dentry *direntry) if (namelen < 0) { break; } else { - full_path[namelen] = '\\'; + full_path[namelen] = CIFS_DIR_SEP(cifs_sb); strncpy(full_path + namelen + 1, temp->d_name.name, temp->d_name.len); cFYI(0, (" name: %s ", full_path + namelen)); @@ -138,7 +138,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&direntry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -299,7 +299,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&direntry->d_sb->s_vfs_rename_sem); if(full_path == NULL) rc = -ENOMEM; @@ -360,7 +360,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name /* can not grab the rename sem here since it would deadlock in the cases (beginning of sys_rename itself) in which we already have the sb rename sem */ - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); if(full_path == NULL) { FreeXid(xid); return ERR_PTR(-ENOMEM); diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 7d2a9202c39a..d47ce7f49dc3 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -83,7 +83,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg) pTcon = cifs_sb->tcon; down(&file->f_dentry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry); + full_path = build_path_from_dentry(file->f_dentry, cifs_sb); up(&file->f_dentry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 30ab70ce5547..8dd11fecaaca 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -196,7 +196,7 @@ int cifs_open(struct inode *inode, struct file *file) } down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry); + full_path = build_path_from_dentry(file->f_dentry, cifs_sb); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -359,7 +359,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, those that already have the rename sem can end up causing writepage to get called and if the server was down that means we end up here, and we can never tell if the caller already has the rename_sem */ - full_path = build_path_from_dentry(file->f_dentry); + full_path = build_path_from_dentry(file->f_dentry, cifs_sb); if (full_path == NULL) { up(&pCifsFile->fh_sem); FreeXid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8d336a900255..95354da606d6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -412,7 +412,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) /* Unlink can be called from rename so we can not grab the sem here since we deadlock otherwise */ /* down(&direntry->d_sb->s_vfs_rename_sem);*/ - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); /* up(&direntry->d_sb->s_vfs_rename_sem);*/ if (full_path == NULL) { FreeXid(xid); @@ -556,7 +556,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -627,7 +627,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -680,8 +680,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, /* we already have the rename sem so we do not need to grab it again here to protect the path integrity */ - fromName = build_path_from_dentry(source_direntry); - toName = build_path_from_dentry(target_direntry); + fromName = build_path_from_dentry(source_direntry, cifs_sb_source); + toName = build_path_from_dentry(target_direntry, cifs_sb_target); if ((fromName == NULL) || (toName == NULL)) { rc = -ENOMEM; goto cifs_rename_exit; @@ -797,7 +797,7 @@ int cifs_revalidate(struct dentry *direntry) /* can not safely grab the rename sem here if rename calls revalidate since that would deadlock */ - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); if (full_path == NULL) { FreeXid(xid); return -ENOMEM; @@ -946,7 +946,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&direntry->d_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index bde0fabfece0..214aa816f669 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -49,8 +49,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, BB note DFS case in future though (when we may have to check) */ down(&inode->i_sb->s_vfs_rename_sem); - fromName = build_path_from_dentry(old_file); - toName = build_path_from_dentry(direntry); + fromName = build_path_from_dentry(old_file, cifs_sb_target); + toName = build_path_from_dentry(direntry, cifs_sb_target); up(&inode->i_sb->s_vfs_rename_sem); if((fromName == NULL) || (toName == NULL)) { rc = -ENOMEM; @@ -105,16 +105,17 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) xid = GetXid(); + cifs_sb = CIFS_SB(inode->i_sb); + pTcon = cifs_sb->tcon; + down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&direntry->d_sb->s_vfs_rename_sem); if (!full_path) goto out_no_free; cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); - cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; target_path = kmalloc(PATH_MAX, GFP_KERNEL); if (!target_path) { target_path = ERR_PTR(-ENOMEM); @@ -167,7 +168,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&inode->i_sb->s_vfs_rename_sem); if(full_path == NULL) { @@ -233,7 +234,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) /* BB would it be safe against deadlock to grab this sem even though rename itself grabs the sem and calls lookup? */ /* down(&inode->i_sb->s_vfs_rename_sem);*/ - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); /* up(&inode->i_sb->s_vfs_rename_sem);*/ if(full_path == NULL) { diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 487221eeddb7..42310281871c 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -354,7 +354,7 @@ static int initiate_cifs_search(const int xid, struct file *file) return -EINVAL; down(&file->f_dentry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry); + full_path = build_path_from_dentry(file->f_dentry, cifs_sb); up(&file->f_dentry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { @@ -375,7 +375,7 @@ static int initiate_cifs_search(const int xid, struct file *file) rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, &cifsFile->netfid, &cifsFile->srch_inf, - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); if(rc == 0) cifsFile->invalidHandle = FALSE; if((rc == -EOPNOTSUPP) && diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index c1e02eff1d25..f4fc8ddebba7 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -63,7 +63,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name) pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -118,7 +118,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name, pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -227,7 +227,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -328,7 +328,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(direntry, cifs_sb); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); From 45abc6ee2b916a235d6824a41225177bd6e5e24f Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 23 Jun 2005 13:42:03 -0500 Subject: [PATCH 0007/1940] [CIFS] Fix typo in POSIX SetFSInfo call Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsproto.h | 2 +- fs/cifs/cifssmb.c | 2 +- fs/cifs/connect.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c7b220206ce0..66eaa6b40373 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -129,7 +129,7 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, int remap); extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData); -extern int CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, +extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap); extern int CIFSSMBQFSAttributeInfo(const int xid, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 7d14f2414812..f3dfae7788fd 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3281,7 +3281,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) } int -CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) +CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) { /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ TRANSACTION2_SETFSI_REQ *pSMB = NULL; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index bef5d6f30975..f6d2a7974fc1 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1794,7 +1794,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, /* Try and negotiate POSIX pathnames if we can. */ if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { - if (!CIFSSMBSETFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP, 0)) { + if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) { cFYI(1,("negotiated posix pathnames support")); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; } else { From 0c0ff09329dafb165c0d9ac08965ddc0615020b1 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 23 Jun 2005 19:31:17 -0500 Subject: [PATCH 0008/1940] [CIFS] Performance improvement, finish up adding CIFSSMBWrite2 Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_debug.c | 10 ++++++++-- fs/cifs/cifssmb.c | 2 +- fs/cifs/file.c | 7 +++---- fs/cifs/transport.c | 6 ++++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 4061e43471c1..838171328076 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -283,6 +283,12 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&tcon->num_t2renames)); buf += item_length; length += item_length; + item_length = sprintf(buf,"\nFindFirst: %d FNext %d FClose %d", + atomic_read(&tcon->num_ffirst), + atomic_read(&tcon->num_fnext), + atomic_read(&tcon->num_fclose)); + buf += item_length; + length += item_length; } read_unlock(&GlobalSMBSeslock); @@ -360,7 +366,7 @@ cifs_proc_init(void) if (pde) pde->write_proc = oplockEnabled_write; - pde = create_proc_read_entry("ReenableOldCifsReaddirCode", 0, proc_fs_cifs, + pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, quotaEnabled_read, NULL); if (pde) pde->write_proc = quotaEnabled_write; @@ -419,7 +425,7 @@ cifs_proc_clean(void) remove_proc_entry("ExtendedSecurity",proc_fs_cifs); remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs); - remove_proc_entry("ReenableOldCifsReaddirCode",proc_fs_cifs); + remove_proc_entry("Experimental",proc_fs_cifs); remove_proc_entry("LookupCacheEnabled",proc_fs_cifs); remove_proc_entry("cifs", proc_root_fs); } diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f3dfae7788fd..56d79fd90679 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -964,7 +964,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, __u32 bytes_sent; __u16 byte_count; - cERROR(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ + cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); if (rc) return rc; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index f55c0c7aeeb0..ddb25a0a63d5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -845,11 +845,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data, if (rc != 0) break; } -#ifdef CIFS_EXPERIMENTAL +#ifdef CONFIG_CIFS_EXPERIMENTAL /* BB FIXME We can not sign across two buffers yet */ - cERROR(1,("checking signing")); /* BB removeme BB */ - if(pTcon->ses->server->secMode & - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED) == 0) + if((experimEnabled) && ((pTcon->ses->server->secMode & + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) { rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, min_t(const int, cifs_sb->wsize, diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 04f4af07fdd4..496a2738bbe3 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -197,7 +197,7 @@ smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, iov[0].iov_base = smb_buffer; iov[0].iov_len = len; iov[1].iov_base = data; - iov[2].iov_len = datalen; + iov[1].iov_len = datalen; smb_msg.msg_name = sin; smb_msg.msg_namelen = sizeof (struct sockaddr); smb_msg.msg_control = NULL; @@ -210,7 +210,8 @@ smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, Flags2 is converted in SendReceive */ smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); - cFYI(1, ("Sending smb of length %d ", len + datalen)); + cFYI(1, ("Sending smb: hdrlen %d datalen %d", + smb_hdr_length,datalen)); dump_smb(smb_buffer, len); while (len + datalen > 0) { @@ -233,6 +234,7 @@ smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, if(rc >= len) { iov[0].iov_len = 0; rc -= len; + len = 0; } else { /* some of hdr was not sent */ len -= rc; iov[0].iov_len -= rc; From d7245c2ccf14cde2023273c1ec246732d96e2c27 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 14 Jul 2005 18:25:12 -0500 Subject: [PATCH 0009/1940] [CIFS] Add compat with SFU (part 1) This should help the case of creating fifos and other special files to servers which do not support the Unix extensions. Signed-off-by: Steve French (sfrench@us.ibm.com) Thanks to Martin Koeppe for his suggestions and good analysis --- fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/connect.c | 7 +++++++ fs/cifs/dir.c | 12 +++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 5dc5fe6b486d..6b93587c490e 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -25,6 +25,7 @@ #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ +#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ struct cifs_sb_info { struct cifsTconInfo *tcon; /* primary mount */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f6d2a7974fc1..36f78596c81a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -75,6 +75,7 @@ struct smb_vol { unsigned direct_io:1; unsigned remap:1; /* set to remap seven reserved chars in filenames */ unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ + unsigned sfu_emul:1; unsigned int rsize; unsigned int wsize; unsigned int sockopt; @@ -1027,6 +1028,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->remap = 1; } else if (strnicmp(data, "nomapchars", 10) == 0) { vol->remap = 0; + } else if (strnicmp(data, "sfu", 3) == 0) { + vol->sfu_emul = 1; + } else if (strnicmp(data, "nosfu", 5) == 0) { + vol->sfu_emul = 0; } else if (strnicmp(data, "posixpaths", 10) == 0) { vol->posix_paths = 1; } else if (strnicmp(data, "noposixpaths", 12) == 0) { @@ -1687,6 +1692,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; if(volume_info.no_xattr) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; + if(volume_info.sfu_emul) + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; if(volume_info.direct_io) { cERROR(1,("mounting share using direct i/o")); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 9360d8fb9ef7..0d5e27fec92b 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -209,7 +209,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, CIFS_MOUNT_MAP_SPECIAL_CHR); } else { - /* BB implement via Windows security descriptors */ + /* BB implement mode setting via Windows security descriptors */ /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ /* could set r/o dos attribute if mode & 0222 == 0 */ } @@ -326,6 +326,16 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev if(rc == 0) d_instantiate(direntry, newinode); } + } else { + if((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (special_file(mode))) { + + cFYI(1,("sfu compat create special file")); + /* Attributes = cpu_to_le32(ATTR_SYSTEM); + rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, ...); */ + + /* add code here to set EAs */ + } } kfree(full_path); From f4cfd69cf349dd27e00d5cf804b57aee04e059c2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 14 Jul 2005 18:29:02 -0500 Subject: [PATCH 0010/1940] [CIFS] Fix path name conversion for long filenames when mapchars mount option was specified at mount time. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 6 ++++++ fs/cifs/misc.c | 1 + 2 files changed, 7 insertions(+) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index dab4774ee7bb..3196d4c4eed3 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,9 @@ +Version 1.35 +------------ +Add writepage performance improvements. Fix path name conversions +for long filenames on mounts which were done with "mapchars" mount option +specified. + Version 1.34 ------------ Fix error mapping of the TOO_MANY_LINKS (hardlinks) case. diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 072b4ee8c53e..20ae4153f791 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -611,6 +611,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, src_char = source[i]; switch (src_char) { case 0: + target[j] = 0; goto ctoUCS_out; case ':': target[j] = cpu_to_le16(UNI_COLON); From eda3c029899cbf435d76fea43b7e1404439ccec9 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 21 Jul 2005 15:20:28 -0700 Subject: [PATCH 0011/1940] [CIFS] Add compat with SFU (part 2) Creating FIFOs to non-Unix servers (with cifs mounts for which sfu option was specified) now works. Signed-off-by: Steve French (sfrench@us.ibm.com) Thanks to Martin Koeppe for his assistance --- fs/cifs/cifspdu.h | 10 +++++++++- fs/cifs/cifssmb.c | 10 ++++++++-- fs/cifs/dir.c | 34 ++++++++++++++++++++++++++++++---- fs/cifs/inode.c | 10 ++++++++++ fs/cifs/readdir.c | 7 +++++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 84d37f8e986e..3cef57b7a34f 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -268,10 +268,18 @@ /* CreateOptions */ #define CREATE_NOT_FILE 0x00000001 /* if set must not be file */ #define CREATE_WRITE_THROUGH 0x00000002 -#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */ +#define CREATE_SEQUENTIAL 0x00000004 +#define CREATE_SYNC_ALERT 0x00000010 +#define CREATE_ASYNC_ALERT 0x00000020 +#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */ +#define CREATE_NO_EA_KNOWLEDGE 0x00000200 +#define CREATE_EIGHT_DOT_THREE 0x00000400 #define CREATE_RANDOM_ACCESS 0x00000800 #define CREATE_DELETE_ON_CLOSE 0x00001000 +#define CREATE_OPEN_BY_ID 0x00002000 #define OPEN_REPARSE_POINT 0x00200000 +#define CREATE_OPTIONS_MASK 0x007FFFFF +#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ /* ImpersonationLevel flags */ #define SECURITY_ANONYMOUS 0 diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 56d79fd90679..fbe651858c88 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -738,7 +738,13 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, } pSMB->DesiredAccess = cpu_to_le32(access_flags); pSMB->AllocationSize = 0; - pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); + /* set file as system file if special file such + as fifo and server expecting SFU style and + no Unix extensions */ + if(create_options & CREATE_OPTION_SPECIAL) + pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); + else + pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); /* XP does not handle ATTR_POSIX_SEMANTICS */ /* but it helps speed up case sensitive checks for other servers such as Samba */ @@ -752,7 +758,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, being created */ pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); pSMB->CreateDisposition = cpu_to_le32(openDisposition); - pSMB->CreateOptions = cpu_to_le32(create_options); + pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); /* BB Expirement with various impersonation levels and verify */ pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); pSMB->SecurityFlags = diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 0d5e27fec92b..c0f20fc09290 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -327,13 +327,39 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev d_instantiate(direntry, newinode); } } else { - if((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && - (special_file(mode))) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { + int oplock = 0; + u16 fileHandle; + FILE_ALL_INFO * buf; cFYI(1,("sfu compat create special file")); - /* Attributes = cpu_to_le32(ATTR_SYSTEM); - rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, ...); */ + buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); + if(buf == NULL) { + kfree(full_path); + FreeXid(xid); + return -ENOMEM; + } + + rc = CIFSSMBOpen(xid, pTcon, full_path, + FILE_CREATE, /* fail if exists */ + GENERIC_WRITE /* BB would + WRITE_OWNER | WRITE_DAC be better? */, + /* Create a file and set the + file attribute to SYSTEM */ + CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, + &fileHandle, &oplock, buf, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + + if(!rc) { + /* BB Do not bother to decode buf since no + local inode yet to put timestamps in */ + CIFSSMBClose(xid, pTcon, fileHandle); + d_drop(direntry); + } + kfree(buf); /* add code here to set EAs */ } } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 95354da606d6..628aa1a9fe64 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -320,6 +320,16 @@ int cifs_get_inode_info(struct inode **pinode, on dirs */ inode->i_mode = cifs_sb->mnt_dir_mode; inode->i_mode |= S_IFDIR; + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (cifsInfo->cifsAttrs & ATTR_SYSTEM) && + /* No need to le64 convert size of zero */ + (pfindData->EndOfFile == 0)) { + inode->i_mode = cifs_sb->mnt_file_mode; + inode->i_mode |= S_IFIFO; +/* BB Finish for SFU style symlinks and devies */ +/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ + } else { inode->i_mode |= S_IFREG; /* treat the dos attribute of read-only as read-only diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 42310281871c..dec3c9dd04d7 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -148,6 +148,13 @@ static void fill_in_inode(struct inode *tmp_inode, tmp_inode->i_mode = cifs_sb->mnt_dir_mode; } tmp_inode->i_mode |= S_IFDIR; + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (attr & ATTR_SYSTEM) && (end_of_file == 0)) { + *pobject_type = DT_FIFO; + tmp_inode->i_mode |= S_IFIFO; +/* BB Finish for SFU style symlinks and devies */ +/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (attr & ATTR_SYSTEM) && ) { */ /* we no longer mark these because we could not follow them */ /* } else if (attr & ATTR_REPARSE) { *pobject_type = DT_LNK; From ef6724e32142c2d9ca252d423cacc435c142734e Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 2 Aug 2005 21:31:05 -0700 Subject: [PATCH 0012/1940] [CIFS] Fix missing entries in search results when very long file names and more than 50 (or so) of such long search entries in the directory. FindNext could send corrupt last byte of resume name when resume key was a few hundred bytes long file name or longer. Fixes Samba Bug # 2932 Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifssmb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index fbe651858c88..e555cb5cf493 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2628,6 +2628,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, if(name_len < PATH_MAX) { memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); byte_count += name_len; + /* 14 byte parm len above enough for 2 byte null terminator */ + pSMB->ResumeFileName[name_len] = 0; + pSMB->ResumeFileName[name_len+1] = 0; } else { rc = -EINVAL; goto FNext2_err_exit; From 885ececaa9e20750d147557fa7f39dbcdac77daa Mon Sep 17 00:00:00 2001 From: Alex Aizman Date: Thu, 4 Aug 2005 19:31:27 -0700 Subject: [PATCH 0013/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Makefile Updates Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 3746fb9fa2f5..e11220a23cc6 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o +obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o From 39e84790d3b65a4af1ea1fb0d8f06c3ad75304b3 Mon Sep 17 00:00:00 2001 From: Alex Aizman Date: Thu, 4 Aug 2005 19:31:00 -0700 Subject: [PATCH 0014/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Header files open-iscsi-headers.patch - common header files: - iscsi_if.h (user/kernel #defines and user/kernel events); - iscsi_proto.h (RFC3720 #defines and types); - scsi_transport_iscsi.h (transport API, transport #defines and types). Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/iscsi_if.h | 245 ++++++++++++ include/scsi/iscsi_proto.h | 566 ++++++++++++++++++++++++++++ include/scsi/scsi_transport_iscsi.h | 202 +++------- 3 files changed, 866 insertions(+), 147 deletions(-) create mode 100644 include/scsi/iscsi_if.h create mode 100644 include/scsi/iscsi_proto.h diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h new file mode 100644 index 000000000000..be1bc792ab18 --- /dev/null +++ b/include/scsi/iscsi_if.h @@ -0,0 +1,245 @@ +/* + * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc) + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * 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. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_IF_H +#define ISCSI_IF_H + +#include + +#define UEVENT_BASE 10 +#define KEVENT_BASE 100 +#define ISCSI_ERR_BASE 1000 + +enum iscsi_uevent_e { + ISCSI_UEVENT_UNKNOWN = 0, + + /* down events */ + ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1, + ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2, + ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3, + ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4, + ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5, + ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6, + ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7, + ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8, + ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9, + ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10, + ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11, + + /* up events */ + ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, + ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, + ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, +}; + +struct iscsi_uevent { + uint32_t type; /* k/u events type */ + uint32_t iferror; /* carries interface or resource errors */ + uint64_t transport_handle; + + union { + /* messages u -> k */ + struct msg_create_session { + uint32_t initial_cmdsn; + } c_session; + struct msg_destroy_session { + uint64_t session_handle; + uint32_t sid; + } d_session; + struct msg_create_conn { + uint64_t session_handle; + uint32_t cid; + uint32_t sid; + } c_conn; + struct msg_bind_conn { + uint64_t session_handle; + uint64_t conn_handle; + uint32_t transport_fd; + uint32_t is_leading; + } b_conn; + struct msg_destroy_conn { + uint64_t conn_handle; + uint32_t cid; + } d_conn; + struct msg_send_pdu { + uint32_t hdr_size; + uint32_t data_size; + uint64_t conn_handle; + } send_pdu; + struct msg_set_param { + uint64_t conn_handle; + uint32_t param; /* enum iscsi_param */ + uint32_t value; + } set_param; + struct msg_start_conn { + uint64_t conn_handle; + } start_conn; + struct msg_stop_conn { + uint64_t conn_handle; + uint32_t flag; + } stop_conn; + struct msg_get_stats { + uint64_t conn_handle; + } get_stats; + } u; + union { + /* messages k -> u */ + uint64_t handle; + int retcode; + struct msg_create_session_ret { + uint64_t session_handle; + uint32_t sid; + } c_session_ret; + struct msg_recv_req { + uint64_t recv_handle; + uint64_t conn_handle; + } recv_req; + struct msg_conn_error { + uint64_t conn_handle; + uint32_t error; /* enum iscsi_err */ + } connerror; + } r; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +/* + * Common error codes + */ +enum iscsi_err { + ISCSI_OK = 0, + + ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1, + ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2, + ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3, + ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4, + ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5, + ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6, + ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7, + ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8, + ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9, + ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10, + ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11, + ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12, + ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13, + ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14, + ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, + ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16 +}; + +/* + * iSCSI Parameters (RFC3720) + */ +enum iscsi_param { + ISCSI_PARAM_MAX_RECV_DLENGTH = 0, + ISCSI_PARAM_MAX_XMIT_DLENGTH = 1, + ISCSI_PARAM_HDRDGST_EN = 2, + ISCSI_PARAM_DATADGST_EN = 3, + ISCSI_PARAM_INITIAL_R2T_EN = 4, + ISCSI_PARAM_MAX_R2T = 5, + ISCSI_PARAM_IMM_DATA_EN = 6, + ISCSI_PARAM_FIRST_BURST = 7, + ISCSI_PARAM_MAX_BURST = 8, + ISCSI_PARAM_PDU_INORDER_EN = 9, + ISCSI_PARAM_DATASEQ_INORDER_EN = 10, + ISCSI_PARAM_ERL = 11, + ISCSI_PARAM_IFMARKER_EN = 12, + ISCSI_PARAM_OFMARKER_EN = 13, +}; +#define ISCSI_PARAM_MAX 14 + +typedef uint64_t iscsi_sessionh_t; /* iSCSI Data-Path session handle */ +typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */ + +#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) +#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) +#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long)) + +/* + * These flags presents iSCSI Data-Path capabilities. + */ +#define CAP_RECOVERY_L0 0x1 +#define CAP_RECOVERY_L1 0x2 +#define CAP_RECOVERY_L2 0x4 +#define CAP_MULTI_R2T 0x8 +#define CAP_HDRDGST 0x10 +#define CAP_DATADGST 0x20 +#define CAP_MULTI_CONN 0x40 +#define CAP_TEXT_NEGO 0x80 +#define CAP_MARKERS 0x100 + +/* + * These flags describes reason of stop_conn() call + */ +#define STOP_CONN_TERM 0x1 +#define STOP_CONN_SUSPEND 0x2 +#define STOP_CONN_RECOVER 0x3 + +#define ISCSI_STATS_CUSTOM_MAX 32 +#define ISCSI_STATS_CUSTOM_DESC_MAX 64 +struct iscsi_stats_custom { + char desc[ISCSI_STATS_CUSTOM_DESC_MAX]; + uint64_t value; +}; + +/* + * struct iscsi_stats - iSCSI Statistics (iSCSI MIB) + * + * Note: this structure contains counters collected on per-connection basis. + */ +struct iscsi_stats { + /* octets */ + uint64_t txdata_octets; + uint64_t rxdata_octets; + + /* xmit pdus */ + uint32_t noptx_pdus; + uint32_t scsicmd_pdus; + uint32_t tmfcmd_pdus; + uint32_t login_pdus; + uint32_t text_pdus; + uint32_t dataout_pdus; + uint32_t logout_pdus; + uint32_t snack_pdus; + + /* recv pdus */ + uint32_t noprx_pdus; + uint32_t scsirsp_pdus; + uint32_t tmfrsp_pdus; + uint32_t textrsp_pdus; + uint32_t datain_pdus; + uint32_t logoutrsp_pdus; + uint32_t r2t_pdus; + uint32_t async_pdus; + uint32_t rjt_pdus; + + /* errors */ + uint32_t digest_err; + uint32_t timeout_err; + + /* + * iSCSI Custom Statistics support, i.e. Transport could + * extend existing MIB statistics with its own specific statistics + * up to ISCSI_STATS_CUSTOM_MAX + */ + uint32_t custom_length; + struct iscsi_stats_custom custom[0] + __attribute__ ((aligned (sizeof(uint64_t)))); +}; + +#endif diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h new file mode 100644 index 000000000000..6c08551c79f5 --- /dev/null +++ b/include/scsi/iscsi_proto.h @@ -0,0 +1,566 @@ +/* + * RFC 3720 (iSCSI) protocol data types + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * 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. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_PROTO_H +#define ISCSI_PROTO_H + +#define ISCSI_VERSION_STR "0.3" +#define ISCSI_DATE_STR "22-Apr-2005" +#define ISCSI_DRAFT20_VERSION 0x00 + +/* default iSCSI listen port for incoming connections */ +#define ISCSI_LISTEN_PORT 3260 + +/* Padding word length */ +#define PAD_WORD_LEN 4 + +/* + * useful common(control and data pathes) macro + */ +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) +#define hton24(p, v) { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ +} +#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;} + +/* + * iSCSI Template Message Header + */ +struct iscsi_hdr { + uint8_t opcode; + uint8_t flags; /* Final bit */ + uint8_t rsvd2[2]; + uint8_t hlength; /* AHSs total length */ + uint8_t dlength[3]; /* Data length */ + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Task Tag */ + __be32 statsn; + __be32 exp_statsn; + uint8_t other[16]; +}; + +/************************* RFC 3720 Begin *****************************/ + +#define ISCSI_RESERVED_TAG 0xffffffff + +/* Opcode encoding bits */ +#define ISCSI_OP_RETRY 0x80 +#define ISCSI_OP_IMMEDIATE 0x40 +#define ISCSI_OPCODE_MASK 0x3F + +/* Initiator Opcode values */ +#define ISCSI_OP_NOOP_OUT 0x00 +#define ISCSI_OP_SCSI_CMD 0x01 +#define ISCSI_OP_SCSI_TMFUNC 0x02 +#define ISCSI_OP_LOGIN 0x03 +#define ISCSI_OP_TEXT 0x04 +#define ISCSI_OP_SCSI_DATA_OUT 0x05 +#define ISCSI_OP_LOGOUT 0x06 +#define ISCSI_OP_SNACK 0x10 + +/* Target Opcode values */ +#define ISCSI_OP_NOOP_IN 0x20 +#define ISCSI_OP_SCSI_CMD_RSP 0x21 +#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22 +#define ISCSI_OP_LOGIN_RSP 0x23 +#define ISCSI_OP_TEXT_RSP 0x24 +#define ISCSI_OP_SCSI_DATA_IN 0x25 +#define ISCSI_OP_LOGOUT_RSP 0x26 +#define ISCSI_OP_R2T 0x31 +#define ISCSI_OP_ASYNC_EVENT 0x32 +#define ISCSI_OP_REJECT 0x3f + +/* iSCSI PDU Header */ +struct iscsi_cmd { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2; + uint8_t cmdrn; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 data_length; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t cdb[16]; /* SCSI Command Block */ + /* Additional Data (Command Dependent) */ +}; + +/* Command PDU flags */ +#define ISCSI_FLAG_CMD_FINAL 0x80 +#define ISCSI_FLAG_CMD_READ 0x40 +#define ISCSI_FLAG_CMD_WRITE 0x20 +#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */ + +/* SCSI Command Attribute values */ +#define ISCSI_ATTR_UNTAGGED 0 +#define ISCSI_ATTR_SIMPLE 1 +#define ISCSI_ATTR_ORDERED 2 +#define ISCSI_ATTR_HEAD_OF_QUEUE 3 +#define ISCSI_ATTR_ACA 4 + +/* SCSI Response Header */ +struct iscsi_cmd_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 rsvd1; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 exp_datasn; + __be32 bi_residual_count; + __be32 residual_count; + /* Response or Sense Data (optional) */ +}; + +/* Command Response PDU flags */ +#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10 +#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08 +#define ISCSI_FLAG_CMD_OVERFLOW 0x04 +#define ISCSI_FLAG_CMD_UNDERFLOW 0x02 + +/* iSCSI Status values. Valid if Rsp Selector bit is not set */ +#define ISCSI_STATUS_CMD_COMPLETED 0 +#define ISCSI_STATUS_TARGET_FAILURE 1 +#define ISCSI_STATUS_SUBSYS_FAILURE 2 + +/* Asynchronous Event Header */ +struct iscsi_async { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + uint8_t rsvd4[8]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t async_event; + uint8_t async_vcode; + __be16 param1; + __be16 param2; + __be16 param3; + uint8_t rsvd5[4]; +}; + +/* iSCSI Event Codes */ +#define ISCSI_ASYNC_MSG_SCSI_EVENT 0 +#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1 +#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2 +#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3 +#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4 +#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255 + +/* NOP-Out Message */ +struct iscsi_nopout { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* NOP-In Message */ +struct iscsi_nopin { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd4[12]; +}; + +/* SCSI Task Management Message Header */ +struct iscsi_tm { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 rtt; /* Reference Task Tag */ + __be32 cmdsn; + __be32 exp_statsn; + __be32 refcmdsn; + __be32 exp_datasn; + uint8_t rsvd2[8]; +}; + +#define ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK 0x7F + +/* Function values */ +#define ISCSI_TM_FUNC_ABORT_TASK 1 +#define ISCSI_TM_FUNC_ABORT_TASK_SET 2 +#define ISCSI_TM_FUNC_CLEAR_ACA 3 +#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4 +#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5 +#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6 +#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7 +#define ISCSI_TM_FUNC_TASK_REASSIGN 8 + +/* SCSI Task Management Response Header */ +struct iscsi_tm_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Response values below */ + uint8_t qualifier; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 rtt; /* Reference Task Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd3[12]; +}; + +/* Response values */ +#define SCSI_TCP_TM_RESP_COMPLETE 0x00 +#define SCSI_TCP_TM_RESP_NO_TASK 0x01 +#define SCSI_TCP_TM_RESP_NO_LUN 0x02 +#define SCSI_TCP_TM_RESP_TASK_ALLEGIANT 0x03 +#define SCSI_TCP_TM_RESP_NO_FAILOVER 0x04 +#define SCSI_TCP_TM_RESP_NOT_SUPPORTED 0x05 +#define SCSI_TCP_TM_RESP_AUTH_FAILED 0x06 +#define SCSI_TCP_TM_RESP_REJECTED 0xff + +/* Ready To Transfer Header */ +struct iscsi_r2t_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 r2tsn; + __be32 data_offset; + __be32 data_length; +}; + +/* SCSI Data Hdr */ +struct iscsi_data { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; + __be32 ttt; + __be32 rsvd4; + __be32 exp_statsn; + __be32 rsvd5; + __be32 datasn; + __be32 offset; + __be32 rsvd6; + /* Payload */ +}; + +/* SCSI Data Response Hdr */ +struct iscsi_data_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + __be32 itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + __be32 offset; + __be32 residual_count; +}; + +/* Data Response PDU flags */ +#define ISCSI_FLAG_DATA_ACK 0x40 +#define ISCSI_FLAG_DATA_OVERFLOW 0x04 +#define ISCSI_FLAG_DATA_UNDERFLOW 0x02 +#define ISCSI_FLAG_DATA_STATUS 0x01 + +/* Text Header */ +struct iscsi_text { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + __be32 itt; + __be32 ttt; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; + /* Text - key=value pairs */ +}; + +#define ISCSI_FLAG_TEXT_CONTINUE 0x40 + +/* Text Response Header */ +struct iscsi_text_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + __be32 itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd5[12]; + /* Text Response - key:value pairs */ +}; + +/* Login Header */ +struct iscsi_login { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t min_version; /* Min. version supported */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + __be32 itt; /* Initiator Task Tag */ + __be16 cid; + __be16 rsvd3; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; +}; + +/* Login PDU flags */ +#define ISCSI_FLAG_LOGIN_TRANSIT 0x80 +#define ISCSI_FLAG_LOGIN_CONTINUE 0x40 +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */ +#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */ + +#define ISCSI_LOGIN_CURRENT_STAGE(flags) \ + ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) +#define ISCSI_LOGIN_NEXT_STAGE(flags) \ + (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK) + +/* Login Response Header */ +struct iscsi_login_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t active_version; /* Active version */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + __be32 itt; /* Initiator Task Tag */ + __be32 rsvd3; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t status_class; /* see Login RSP ststus classes below */ + uint8_t status_detail; /* see Login RSP Status details below */ + uint8_t rsvd4[10]; +}; + +/* Login stage (phase) codes for CSG, NSG */ +#define ISCSI_INITIAL_LOGIN_STAGE -1 +#define ISCSI_SECURITY_NEGOTIATION_STAGE 0 +#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1 +#define ISCSI_FULL_FEATURE_PHASE 3 + +/* Login Status response classes */ +#define ISCSI_STATUS_CLS_SUCCESS 0x00 +#define ISCSI_STATUS_CLS_REDIRECT 0x01 +#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02 +#define ISCSI_STATUS_CLS_TARGET_ERR 0x03 + +/* Login Status response detail codes */ +/* Class-0 (Success) */ +#define ISCSI_LOGIN_STATUS_ACCEPT 0x00 + +/* Class-1 (Redirection) */ +#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01 +#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02 + +/* Class-2 (Initiator Error) */ +#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00 +#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01 +#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02 +#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03 +#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04 +#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05 +#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06 +#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07 +#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08 +#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09 +#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a +#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b + +/* Class-3 (Target Error) */ +#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00 +#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01 +#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02 + +/* Logout Header */ +struct iscsi_logout { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + __be32 itt; /* Initiator Task Tag */ + __be16 cid; + uint8_t rsvd3[2]; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* Logout PDU flags */ +#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F + +/* logout reason_code values */ + +#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0 +#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1 +#define ISCSI_LOGOUT_REASON_RECOVERY 2 +#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3 + +/* Logout Response Header */ +struct iscsi_logout_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Logout response values below */ + uint8_t rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd3[8]; + __be32 itt; /* Initiator Task Tag */ + __be32 rsvd4; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 rsvd5; + __be16 t2wait; + __be16 t2retain; + __be32 rsvd6; +}; + +/* logout response status values */ + +#define ISCSI_LOGOUT_SUCCESS 0 +#define ISCSI_LOGOUT_CID_NOT_FOUND 1 +#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2 +#define ISCSI_LOGOUT_CLEANUP_FAILED 3 + +/* SNACK Header */ +struct iscsi_snack { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[14]; + __be32 itt; + __be32 begrun; + __be32 runlength; + __be32 exp_statsn; + __be32 rsvd3; + __be32 exp_datasn; + uint8_t rsvd6[8]; +}; + +/* SNACK PDU flags */ +#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */ + +/* Reject Message Header */ +struct iscsi_reject { + uint8_t opcode; + uint8_t flags; + uint8_t reason; + uint8_t rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t rsvd4[16]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + uint8_t rsvd5[8]; + /* Text - Rejected hdr */ +}; + +/* Reason for Reject */ +#define CMD_BEFORE_LOGIN 1 +#define DATA_DIGEST_ERROR 2 +#define DATA_SNACK_REJECT 3 +#define ISCSI_PROTOCOL_ERROR 4 +#define CMD_NOT_SUPPORTED 5 +#define IMM_CMD_REJECT 6 +#define TASK_IN_PROGRESS 7 +#define INVALID_SNACK 8 +#define BOOKMARK_REJECTED 9 +#define BOOKMARK_NO_RESOURCES 10 +#define NEGOTIATION_RESET 11 + +/* Max. number of Key=Value pairs in a text message */ +#define MAX_KEY_VALUE_PAIRS 8192 + +/* maximum length for text keys/values */ +#define KEY_MAXLEN 64 +#define VALUE_MAXLEN 255 +#define TARGET_NAME_MAXLEN VALUE_MAXLEN + +#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192 + +/************************* RFC 3720 End *****************************/ + +#endif /* ISCSI_PROTO_H */ diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 1b26a6c0aa2a..f25041c386ec 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -1,8 +1,10 @@ -/* +/* * iSCSI transport class definitions * * Copyright (C) IBM Corporation, 2004 - * Copyright (C) Mike Christie, 2004 + * Copyright (C) Mike Christie, 2004 - 2005 + * Copyright (C) Dmitry Yusupov, 2004 - 2005 + * Copyright (C) Alex Aizman, 2004 - 2005 * * 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 @@ -21,158 +23,64 @@ #ifndef SCSI_TRANSPORT_ISCSI_H #define SCSI_TRANSPORT_ISCSI_H -#include -#include -#include +#include -struct scsi_transport_template; - -struct iscsi_class_session { - uint8_t isid[6]; - uint16_t tsih; - int header_digest; /* 1 CRC32, 0 None */ - int data_digest; /* 1 CRC32, 0 None */ - uint16_t tpgt; - union { - struct in6_addr sin6_addr; - struct in_addr sin_addr; - } u; - sa_family_t addr_type; /* must be AF_INET or AF_INET6 */ - uint16_t port; /* must be in network byte order */ - int initial_r2t; /* 1 Yes, 0 No */ - int immediate_data; /* 1 Yes, 0 No */ - uint32_t max_recv_data_segment_len; - uint32_t max_burst_len; - uint32_t first_burst_len; - uint16_t def_time2wait; - uint16_t def_time2retain; - uint16_t max_outstanding_r2t; - int data_pdu_in_order; /* 1 Yes, 0 No */ - int data_sequence_in_order; /* 1 Yes, 0 No */ - int erl; +/** + * struct iscsi_transport - iSCSI Transport template + * + * @name: transport name + * @caps: iSCSI Data-Path capabilities + * @create_session: create new iSCSI session object + * @destroy_session: destroy existing iSCSI session object + * @create_conn: create new iSCSI connection + * @bind_conn: associate this connection with existing iSCSI session + * and specified transport descriptor + * @destroy_conn: destroy inactive iSCSI connection + * @set_param: set iSCSI Data-Path operational parameter + * @start_conn: set connection to be operational + * @stop_conn: suspend/recover/terminate connection + * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. + * + * Template API provided by iSCSI Transport + */ +struct iscsi_transport { + struct module *owner; + char *name; + unsigned int caps; + struct scsi_host_template *host_template; + int hostdata_size; + int max_lun; + unsigned int max_conn; + unsigned int max_cmd_len; + iscsi_sessionh_t (*create_session) (uint32_t initial_cmdsn, + struct Scsi_Host *shost); + void (*destroy_session) (iscsi_sessionh_t session); + iscsi_connh_t (*create_conn) (iscsi_sessionh_t session, uint32_t cid); + int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn, + uint32_t transport_fd, int is_leading); + int (*start_conn) (iscsi_connh_t conn); + void (*stop_conn) (iscsi_connh_t conn, int flag); + void (*destroy_conn) (iscsi_connh_t conn); + int (*set_param) (iscsi_connh_t conn, enum iscsi_param param, + uint32_t value); + int (*get_param) (iscsi_connh_t conn, enum iscsi_param param, + uint32_t *value); + int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); + void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats); }; /* - * accessor macros + * transport registration upcalls */ -#define iscsi_isid(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->isid) -#define iscsi_tsih(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->tsih) -#define iscsi_header_digest(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->header_digest) -#define iscsi_data_digest(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->data_digest) -#define iscsi_port(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->port) -#define iscsi_addr_type(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->addr_type) -#define iscsi_sin_addr(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr) -#define iscsi_sin6_addr(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr) -#define iscsi_tpgt(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->tpgt) -#define iscsi_initial_r2t(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t) -#define iscsi_immediate_data(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->immediate_data) -#define iscsi_max_recv_data_segment_len(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len) -#define iscsi_max_burst_len(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len) -#define iscsi_first_burst_len(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len) -#define iscsi_def_time2wait(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait) -#define iscsi_def_time2retain(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain) -#define iscsi_max_outstanding_r2t(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t) -#define iscsi_data_pdu_in_order(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order) -#define iscsi_data_sequence_in_order(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order) -#define iscsi_erl(x) \ - (((struct iscsi_class_session *)&(x)->starget_data)->erl) +extern int iscsi_register_transport(struct iscsi_transport *tt); +extern int iscsi_unregister_transport(struct iscsi_transport *tt); /* - * The functions by which the transport class and the driver communicate + * control plane upcalls */ -struct iscsi_function_template { - /* - * target attrs - */ - void (*get_isid)(struct scsi_target *); - void (*get_tsih)(struct scsi_target *); - void (*get_header_digest)(struct scsi_target *); - void (*get_data_digest)(struct scsi_target *); - void (*get_port)(struct scsi_target *); - void (*get_tpgt)(struct scsi_target *); - /* - * In get_ip_address the lld must set the address and - * the address type - */ - void (*get_ip_address)(struct scsi_target *); - /* - * The lld should snprintf the name or alias to the buffer - */ - ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t); - ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t); - void (*get_initial_r2t)(struct scsi_target *); - void (*get_immediate_data)(struct scsi_target *); - void (*get_max_recv_data_segment_len)(struct scsi_target *); - void (*get_max_burst_len)(struct scsi_target *); - void (*get_first_burst_len)(struct scsi_target *); - void (*get_def_time2wait)(struct scsi_target *); - void (*get_def_time2retain)(struct scsi_target *); - void (*get_max_outstanding_r2t)(struct scsi_target *); - void (*get_data_pdu_in_order)(struct scsi_target *); - void (*get_data_sequence_in_order)(struct scsi_target *); - void (*get_erl)(struct scsi_target *); - - /* - * host atts - */ - - /* - * The lld should snprintf the name or alias to the buffer - */ - ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t); - ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t); - /* - * The driver sets these to tell the transport class it - * wants the attributes displayed in sysfs. If the show_ flag - * is not set, the attribute will be private to the transport - * class. We could probably just test if a get_ fn was set - * since we only use the values for sysfs but this is how - * fc does it too. - */ - unsigned long show_isid:1; - unsigned long show_tsih:1; - unsigned long show_header_digest:1; - unsigned long show_data_digest:1; - unsigned long show_port:1; - unsigned long show_tpgt:1; - unsigned long show_ip_address:1; - unsigned long show_target_name:1; - unsigned long show_target_alias:1; - unsigned long show_initial_r2t:1; - unsigned long show_immediate_data:1; - unsigned long show_max_recv_data_segment_len:1; - unsigned long show_max_burst_len:1; - unsigned long show_first_burst_len:1; - unsigned long show_def_time2wait:1; - unsigned long show_def_time2retain:1; - unsigned long show_max_outstanding_r2t:1; - unsigned long show_data_pdu_in_order:1; - unsigned long show_data_sequence_in_order:1; - unsigned long show_erl:1; - unsigned long show_initiator_name:1; - unsigned long show_initiator_alias:1; -}; - -struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *); -void iscsi_release_transport(struct scsi_transport_template *); +extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error); +extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); #endif From c213ca0792bd83075233a48090c46155249b3991 Mon Sep 17 00:00:00 2001 From: Alex Aizman Date: Thu, 4 Aug 2005 19:30:31 -0700 Subject: [PATCH 0015/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Initiator header drivers/scsi/iscsi_tcp.h, header file. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.h | 322 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 drivers/scsi/iscsi_tcp.h diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h new file mode 100644 index 000000000000..d23ae68fae0d --- /dev/null +++ b/drivers/scsi/iscsi_tcp.h @@ -0,0 +1,322 @@ +/* + * iSCSI Initiator TCP Transport + * Copyright (C) 2004 Dmitry Yusupov + * Copyright (C) 2004 Alex Aizman + * Copyright (C) 2005 Mike Christie + * maintained by open-iscsi@googlegroups.com + * + * 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. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_TCP_H +#define ISCSI_TCP_H + +/* Session's states */ +#define ISCSI_STATE_FREE 1 +#define ISCSI_STATE_LOGGED_IN 2 +#define ISCSI_STATE_FAILED 3 +#define ISCSI_STATE_TERMINATE 4 + +/* Connection's states */ +#define ISCSI_CONN_INITIAL_STAGE 0 +#define ISCSI_CONN_STARTED 1 +#define ISCSI_CONN_STOPPED 2 +#define ISCSI_CONN_CLEANUP_WAIT 3 + +/* Connection suspend "bit" */ +#define SUSPEND_BIT 1 + +/* Socket's Receive state machine */ +#define IN_PROGRESS_WAIT_HEADER 0x0 +#define IN_PROGRESS_HEADER_GATHER 0x1 +#define IN_PROGRESS_DATA_RECV 0x2 +#define IN_PROGRESS_DDIGEST_RECV 0x3 + +/* Task Mgmt states */ +#define TMABORT_INITIAL 0x0 +#define TMABORT_SUCCESS 0x1 +#define TMABORT_FAILED 0x2 +#define TMABORT_TIMEDOUT 0x3 + +/* xmit state machine */ +#define XMSTATE_IDLE 0x0 +#define XMSTATE_R_HDR 0x1 +#define XMSTATE_W_HDR 0x2 +#define XMSTATE_IMM_HDR 0x4 +#define XMSTATE_IMM_DATA 0x8 +#define XMSTATE_UNS_INIT 0x10 +#define XMSTATE_UNS_HDR 0x20 +#define XMSTATE_UNS_DATA 0x40 +#define XMSTATE_SOL_HDR 0x80 +#define XMSTATE_SOL_DATA 0x100 +#define XMSTATE_W_PAD 0x200 +#define XMSTATE_DATA_DIGEST 0x400 + +#define ISCSI_CONN_MAX 1 +#define ISCSI_CONN_RCVBUF_MIN 262144 +#define ISCSI_CONN_SNDBUF_MIN 262144 +#define ISCSI_PAD_LEN 4 +#define ISCSI_R2T_MAX 16 +#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */ +#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ +#define ISCSI_MGMT_ITT_OFFSET 0xa00 +#define ISCSI_SG_TABLESIZE SG_ALL +#define ISCSI_CMD_PER_LUN 128 +#define ISCSI_TCP_MAX_CMD_LEN 16 + +#define ITT_MASK (0xfff) +#define CID_SHIFT 12 +#define CID_MASK (0xffff< Date: Thu, 4 Aug 2005 19:33:07 -0700 Subject: [PATCH 0016/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Transport class update for iSCSI Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 1397 ++++++++++++++++++++++----- 1 file changed, 1141 insertions(+), 256 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 8bb8222ea589..2effa1c33fb2 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1,8 +1,10 @@ -/* +/* * iSCSI transport class definitions * * Copyright (C) IBM Corporation, 2004 - * Copyright (C) Mike Christie, 2004 + * Copyright (C) Mike Christie, 2004 - 2005 + * Copyright (C) Dmitry Yusupov, 2004 - 2005 + * Copyright (C) Alex Aizman, 2004 - 2005 * * 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 @@ -19,370 +21,1253 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include +#include #include #include #include #include #include +#include -#define ISCSI_SESSION_ATTRS 20 -#define ISCSI_HOST_ATTRS 2 +#define ISCSI_SESSION_ATTRS 8 +#define ISCSI_CONN_ATTRS 6 struct iscsi_internal { struct scsi_transport_template t; - struct iscsi_function_template *fnt; + struct iscsi_transport *iscsi_transport; + struct list_head list; + /* + * List of sessions for this transport + */ + struct list_head sessions; + /* + * lock to serialize access to the sessions list which must + * be taken after the rx_queue_sema + */ + spinlock_t session_lock; + /* + * based on transport capabilities, at register time we set these + * bits to tell the transport class it wants attributes displayed + * in sysfs or that it can support different iSCSI Data-Path + * capabilities + */ + uint32_t param_mask; + + struct class_device cdev; /* * We do not have any private or other attrs. */ + struct transport_container conn_cont; + struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; + struct transport_container session_cont; struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; - struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; }; -#define to_iscsi_internal(tmpl) container_of(tmpl, struct iscsi_internal, t) +/* + * list of registered transports and lock that must + * be held while accessing list. The iscsi_transport_lock must + * be acquired after the rx_queue_sema. + */ +static LIST_HEAD(iscsi_transports); +static DEFINE_SPINLOCK(iscsi_transport_lock); -static DECLARE_TRANSPORT_CLASS(iscsi_transport_class, - "iscsi_transport", +#define to_iscsi_internal(tmpl) \ + container_of(tmpl, struct iscsi_internal, t) + +#define cdev_to_iscsi_internal(_cdev) \ + container_of(_cdev, struct iscsi_internal, cdev) + +static void iscsi_transport_release(struct class_device *cdev) +{ + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); + kfree(priv); +} + +/* + * iscsi_transport_class represents the iscsi_transports that are + * registered. + */ +static struct class iscsi_transport_class = { + .name = "iscsi_transport", + .release = iscsi_transport_release, +}; + +static ssize_t +show_transport_handle(struct class_device *cdev, char *buf) +{ + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); + return sprintf(buf, "%llu", iscsi_handle(priv->iscsi_transport)); +} +static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); + +#define show_transport_attr(name, format) \ +static ssize_t \ +show_transport_##name(struct class_device *cdev, char *buf) \ +{ \ + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \ + return sprintf(buf, format"\n", priv->iscsi_transport->name); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); + +show_transport_attr(caps, "0x%x"); +show_transport_attr(max_lun, "%d"); +show_transport_attr(max_conn, "%d"); +show_transport_attr(max_cmd_len, "%d"); + +static struct attribute *iscsi_transport_attrs[] = { + &class_device_attr_handle.attr, + &class_device_attr_caps.attr, + &class_device_attr_max_lun.attr, + &class_device_attr_max_conn.attr, + &class_device_attr_max_cmd_len.attr, + NULL, +}; + +static struct attribute_group iscsi_transport_group = { + .attrs = iscsi_transport_attrs, +}; + +static DECLARE_TRANSPORT_CLASS(iscsi_session_class, + "iscsi_session", NULL, NULL, NULL); -static DECLARE_TRANSPORT_CLASS(iscsi_host_class, - "iscsi_host", +static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, + "iscsi_connection", NULL, NULL, NULL); + +static struct sock *nls; +static int daemon_pid; +static DECLARE_MUTEX(rx_queue_sema); + +struct mempool_zone { + mempool_t *pool; + atomic_t allocated; + int size; + int hiwat; + struct list_head freequeue; + spinlock_t freelock; +}; + +static struct mempool_zone z_reply; + /* - * iSCSI target and session attrs + * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time + * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM + * so daemon will notice OOM on NETLINK tranposrt level and will + * be able to predict or change operational behavior */ -#define iscsi_session_show_fn(field, format) \ - \ -static ssize_t \ -show_session_##field(struct class_device *cdev, char *buf) \ -{ \ - struct scsi_target *starget = transport_class_to_starget(cdev); \ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ - \ - if (i->fnt->get_##field) \ - i->fnt->get_##field(starget); \ - return snprintf(buf, 20, format"\n", iscsi_##field(starget)); \ -} +#define Z_MAX_REPLY 8 +#define Z_HIWAT_REPLY 6 +#define Z_MAX_PDU 8 +#define Z_HIWAT_PDU 6 +#define Z_MAX_ERROR 16 +#define Z_HIWAT_ERROR 12 -#define iscsi_session_rd_attr(field, format) \ - iscsi_session_show_fn(field, format) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_##field, NULL); +struct iscsi_if_conn { + struct list_head conn_list; /* item in connlist */ + struct list_head session_list; /* item in session->connections */ + iscsi_connh_t connh; + int active; /* must be accessed with the connlock */ + struct Scsi_Host *host; /* originated shost */ + struct device dev; /* sysfs transport/container device */ + struct iscsi_transport *transport; + struct mempool_zone z_error; + struct mempool_zone z_pdu; + struct list_head freequeue; +}; -iscsi_session_rd_attr(tpgt, "%hu"); -iscsi_session_rd_attr(tsih, "%2x"); -iscsi_session_rd_attr(max_recv_data_segment_len, "%u"); -iscsi_session_rd_attr(max_burst_len, "%u"); -iscsi_session_rd_attr(first_burst_len, "%u"); -iscsi_session_rd_attr(def_time2wait, "%hu"); -iscsi_session_rd_attr(def_time2retain, "%hu"); -iscsi_session_rd_attr(max_outstanding_r2t, "%hu"); -iscsi_session_rd_attr(erl, "%d"); +#define iscsi_dev_to_if_conn(_dev) \ + container_of(_dev, struct iscsi_if_conn, dev) +#define iscsi_cdev_to_if_conn(_cdev) \ + iscsi_dev_to_if_conn(_cdev->dev) -#define iscsi_session_show_bool_fn(field) \ - \ -static ssize_t \ -show_session_bool_##field(struct class_device *cdev, char *buf) \ -{ \ - struct scsi_target *starget = transport_class_to_starget(cdev); \ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ - \ - if (i->fnt->get_##field) \ - i->fnt->get_##field(starget); \ - \ - if (iscsi_##field(starget)) \ - return sprintf(buf, "Yes\n"); \ - return sprintf(buf, "No\n"); \ -} +static LIST_HEAD(connlist); +static DEFINE_SPINLOCK(connlock); -#define iscsi_session_rd_bool_attr(field) \ - iscsi_session_show_bool_fn(field) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_bool_##field, NULL); +struct iscsi_if_session { + struct list_head list; /* item in session_list */ + struct list_head connections; + iscsi_sessionh_t sessionh; + struct iscsi_transport *transport; + struct device dev; /* sysfs transport/container device */ +}; -iscsi_session_rd_bool_attr(initial_r2t); -iscsi_session_rd_bool_attr(immediate_data); -iscsi_session_rd_bool_attr(data_pdu_in_order); -iscsi_session_rd_bool_attr(data_sequence_in_order); +#define iscsi_dev_to_if_session(_dev) \ + container_of(_dev, struct iscsi_if_session, dev) -#define iscsi_session_show_digest_fn(field) \ - \ -static ssize_t \ -show_##field(struct class_device *cdev, char *buf) \ -{ \ - struct scsi_target *starget = transport_class_to_starget(cdev); \ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ - \ - if (i->fnt->get_##field) \ - i->fnt->get_##field(starget); \ - \ - if (iscsi_##field(starget)) \ - return sprintf(buf, "CRC32C\n"); \ - return sprintf(buf, "None\n"); \ -} +#define iscsi_cdev_to_if_session(_cdev) \ + iscsi_dev_to_if_session(_cdev->dev) -#define iscsi_session_rd_digest_attr(field) \ - iscsi_session_show_digest_fn(field) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); +#define iscsi_if_session_to_shost(_session) \ + dev_to_shost(_session->dev.parent) -iscsi_session_rd_digest_attr(header_digest); -iscsi_session_rd_digest_attr(data_digest); - -static ssize_t -show_port(struct class_device *cdev, char *buf) +static struct iscsi_if_conn* +iscsi_if_find_conn(uint64_t key) { - struct scsi_target *starget = transport_class_to_starget(cdev); - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); + unsigned long flags; + struct iscsi_if_conn *conn; - if (i->fnt->get_port) - i->fnt->get_port(starget); - - return snprintf(buf, 20, "%hu\n", ntohs(iscsi_port(starget))); + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &connlist, conn_list) + if (conn->connh == key) { + spin_unlock_irqrestore(&connlock, flags); + return conn; + } + spin_unlock_irqrestore(&connlock, flags); + return NULL; } -static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static ssize_t -show_ip_address(struct class_device *cdev, char *buf) +static struct iscsi_internal * +iscsi_if_transport_lookup(struct iscsi_transport *tt) { - struct scsi_target *starget = transport_class_to_starget(cdev); - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); + struct iscsi_internal *priv; + unsigned long flags; - if (i->fnt->get_ip_address) - i->fnt->get_ip_address(starget); - - if (iscsi_addr_type(starget) == AF_INET) - return sprintf(buf, "%u.%u.%u.%u\n", - NIPQUAD(iscsi_sin_addr(starget))); - else if(iscsi_addr_type(starget) == AF_INET6) - return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - NIP6(iscsi_sin6_addr(starget))); - return -EINVAL; + spin_lock_irqsave(&iscsi_transport_lock, flags); + list_for_each_entry(priv, &iscsi_transports, list) { + if (tt == priv->iscsi_transport) { + spin_unlock_irqrestore(&iscsi_transport_lock, flags); + return priv; + } + } + spin_unlock_irqrestore(&iscsi_transport_lock, flags); + return NULL; } -static CLASS_DEVICE_ATTR(ip_address, S_IRUGO, show_ip_address, NULL); -static ssize_t -show_isid(struct class_device *cdev, char *buf) +static inline struct list_head *skb_to_lh(struct sk_buff *skb) { - struct scsi_target *starget = transport_class_to_starget(cdev); - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); - - if (i->fnt->get_isid) - i->fnt->get_isid(starget); - - return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n", - iscsi_isid(starget)[0], iscsi_isid(starget)[1], - iscsi_isid(starget)[2], iscsi_isid(starget)[3], - iscsi_isid(starget)[4], iscsi_isid(starget)[5]); + return (struct list_head *)&skb->cb; +} + +static void* +mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) +{ + struct mempool_zone *zone = pool_data; + + return alloc_skb(zone->size, gfp_mask); +} + +static void +mempool_zone_free_skb(void *element, void *pool_data) +{ + kfree_skb(element); +} + +static void +mempool_zone_complete(struct mempool_zone *zone) +{ + unsigned long flags; + struct list_head *lh, *n; + + spin_lock_irqsave(&zone->freelock, flags); + list_for_each_safe(lh, n, &zone->freequeue) { + struct sk_buff *skb = (struct sk_buff *)((char *)lh - + offsetof(struct sk_buff, cb)); + if (!skb_shared(skb)) { + list_del(skb_to_lh(skb)); + mempool_free(skb, zone->pool); + atomic_dec(&zone->allocated); + } + } + spin_unlock_irqrestore(&zone->freelock, flags); +} + +static int +mempool_zone_init(struct mempool_zone *zp, unsigned max, unsigned size, + unsigned hiwat) +{ + zp->pool = mempool_create(max, mempool_zone_alloc_skb, + mempool_zone_free_skb, zp); + if (!zp->pool) + return -ENOMEM; + + zp->size = size; + zp->hiwat = hiwat; + + INIT_LIST_HEAD(&zp->freequeue); + spin_lock_init(&zp->freelock); + atomic_set(&zp->allocated, 0); + + return 0; +} + + +static struct sk_buff* +mempool_zone_get_skb(struct mempool_zone *zone) +{ + struct sk_buff *skb; + + skb = mempool_alloc(zone->pool, GFP_ATOMIC); + if (skb) + atomic_inc(&zone->allocated); + return skb; +} + +static int +iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) +{ + unsigned long flags; + int rc; + + skb_get(skb); + rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT); + if (rc < 0) { + mempool_free(skb, zone->pool); + printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); + return rc; + } + + spin_lock_irqsave(&zone->freelock, flags); + list_add(skb_to_lh(skb), &zone->freequeue); + spin_unlock_irqrestore(&zone->freelock, flags); + + return 0; +} + +int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) +{ + struct nlmsghdr *nlh; + struct sk_buff *skb; + struct iscsi_uevent *ev; + struct iscsi_if_conn *conn; + char *pdu; + int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + + data_size); + + conn = iscsi_if_find_conn(connh); + BUG_ON(!conn); + + mempool_zone_complete(&conn->z_pdu); + + skb = mempool_zone_get_skb(&conn->z_pdu); + if (!skb) { + iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED); + printk(KERN_ERR "iscsi%d: can not deliver control PDU: OOM\n", + conn->host->host_no); + return -ENOMEM; + } + + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + ev = NLMSG_DATA(nlh); + memset(ev, 0, sizeof(*ev)); + ev->transport_handle = iscsi_handle(conn->transport); + ev->type = ISCSI_KEVENT_RECV_PDU; + if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat) + ev->iferror = -ENOMEM; + ev->r.recv_req.conn_handle = connh; + pdu = (char*)ev + sizeof(*ev); + memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); + memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); + + return iscsi_unicast_skb(&conn->z_pdu, skb); +} +EXPORT_SYMBOL_GPL(iscsi_recv_pdu); + +void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error) +{ + struct nlmsghdr *nlh; + struct sk_buff *skb; + struct iscsi_uevent *ev; + struct iscsi_if_conn *conn; + int len = NLMSG_SPACE(sizeof(*ev)); + + conn = iscsi_if_find_conn(connh); + BUG_ON(!conn); + + mempool_zone_complete(&conn->z_error); + + skb = mempool_zone_get_skb(&conn->z_error); + if (!skb) { + printk(KERN_ERR "iscsi%d: gracefully ignored conn error (%d)\n", + conn->host->host_no, error); + return; + } + + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + ev = NLMSG_DATA(nlh); + ev->transport_handle = iscsi_handle(conn->transport); + ev->type = ISCSI_KEVENT_CONN_ERROR; + if (atomic_read(&conn->z_error.allocated) >= conn->z_error.hiwat) + ev->iferror = -ENOMEM; + ev->r.connerror.error = error; + ev->r.connerror.conn_handle = connh; + + iscsi_unicast_skb(&conn->z_error, skb); + + printk(KERN_INFO "iscsi%d: detected conn error (%d)\n", + conn->host->host_no, error); +} +EXPORT_SYMBOL_GPL(iscsi_conn_error); + +static int +iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, + void *payload, int size) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + int len = NLMSG_SPACE(size); + int flags = multi ? NLM_F_MULTI : 0; + int t = done ? NLMSG_DONE : type; + + mempool_zone_complete(&z_reply); + + skb = mempool_zone_get_skb(&z_reply); + /* + * FIXME: + * user is supposed to react on iferror == -ENOMEM; + * see iscsi_if_rx(). + */ + BUG_ON(!skb); + + nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); + nlh->nlmsg_flags = flags; + memcpy(NLMSG_DATA(nlh), payload, size); + return iscsi_unicast_skb(&z_reply, skb); } -static CLASS_DEVICE_ATTR(isid, S_IRUGO, show_isid, NULL); /* - * This is used for iSCSI names. Normally, we follow - * the transport class convention of having the lld - * set the field, but in these cases the value is - * too large. + * iSCSI Session's hostdata organization: + * + * *------------------* <== host->hostdata + * | transport | + * |------------------| <== iscsi_hostdata(host->hostdata) + * | transport's data | + * |------------------| <== hostdata_session(host->hostdata) + * | interface's data | + * *------------------* */ -#define iscsi_session_show_str_fn(field) \ - \ + +#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \ + _t->hostdata_size % sizeof(unsigned long) + \ + sizeof(struct iscsi_if_session)) + +#define hostdata_session(_hostdata) ((void*)_hostdata + sizeof(unsigned long) + \ + ((struct iscsi_transport *) \ + iscsi_ptr(*(uint64_t *)_hostdata))->hostdata_size) + +static void iscsi_if_session_dev_release(struct device *dev) +{ + struct iscsi_if_session *session = iscsi_dev_to_if_session(dev); + struct iscsi_transport *transport = session->transport; + struct Scsi_Host *shost = iscsi_if_session_to_shost(session); + struct iscsi_if_conn *conn, *tmp; + unsigned long flags; + + /* now free connections */ + spin_lock_irqsave(&connlock, flags); + list_for_each_entry_safe(conn, tmp, &session->connections, + session_list) { + list_del(&conn->session_list); + mempool_destroy(conn->z_pdu.pool); + mempool_destroy(conn->z_error.pool); + kfree(conn); + } + spin_unlock_irqrestore(&connlock, flags); + scsi_host_put(shost); + module_put(transport->owner); +} + +static int +iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) +{ + struct iscsi_transport *transport = priv->iscsi_transport; + struct iscsi_if_session *session; + struct Scsi_Host *shost; + unsigned long flags; + int error; + + if (!try_module_get(transport->owner)) + return -EPERM; + + shost = scsi_host_alloc(transport->host_template, + hostdata_privsize(transport)); + if (!shost) { + ev->r.c_session_ret.session_handle = iscsi_handle(NULL); + printk(KERN_ERR "iscsi: can not allocate SCSI host for " + "session\n"); + error = -ENOMEM; + goto out_module_put; + } + shost->max_id = 1; + shost->max_channel = 0; + shost->max_lun = transport->max_lun; + shost->max_cmd_len = transport->max_cmd_len; + shost->transportt = &priv->t; + + /* store struct iscsi_transport in hostdata */ + *(uint64_t*)shost->hostdata = ev->transport_handle; + + ev->r.c_session_ret.session_handle = transport->create_session( + ev->u.c_session.initial_cmdsn, shost); + if (ev->r.c_session_ret.session_handle == iscsi_handle(NULL)) { + error = 0; + goto out_host_put; + } + + /* host_no becomes assigned SID */ + ev->r.c_session_ret.sid = shost->host_no; + /* initialize session */ + session = hostdata_session(shost->hostdata); + INIT_LIST_HEAD(&session->connections); + INIT_LIST_HEAD(&session->list); + session->sessionh = ev->r.c_session_ret.session_handle; + session->transport = transport; + + error = scsi_add_host(shost, NULL); + if (error) + goto out_destroy_session; + + /* + * this is released in the dev's release function) + */ + scsi_host_get(shost); + snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no); + session->dev.parent = &shost->shost_gendev; + session->dev.release = iscsi_if_session_dev_release; + error = device_register(&session->dev); + if (error) { + printk(KERN_ERR "iscsi: could not register session%d's dev\n", + shost->host_no); + goto out_remove_host; + } + transport_register_device(&session->dev); + + /* add this session to the list of active sessions */ + spin_lock_irqsave(&priv->session_lock, flags); + list_add(&session->list, &priv->sessions); + spin_unlock_irqrestore(&priv->session_lock, flags); + + return 0; + +out_remove_host: + scsi_remove_host(shost); +out_destroy_session: + transport->destroy_session(ev->r.c_session_ret.session_handle); + ev->r.c_session_ret.session_handle = iscsi_handle(NULL); +out_host_put: + scsi_host_put(shost); +out_module_put: + module_put(transport->owner); + return error; +} + +static int +iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) +{ + struct iscsi_transport *transport = priv->iscsi_transport; + struct Scsi_Host *shost; + struct iscsi_if_session *session; + unsigned long flags; + struct iscsi_if_conn *conn; + int error = 0; + + shost = scsi_host_lookup(ev->u.d_session.sid); + if (shost == ERR_PTR(-ENXIO)) + return -EEXIST; + session = hostdata_session(shost->hostdata); + + /* check if we have active connections */ + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &session->connections, session_list) { + if (conn->active) { + printk(KERN_ERR "iscsi%d: can not destroy session: " + "has active connection (%p)\n", + shost->host_no, iscsi_ptr(conn->connh)); + spin_unlock_irqrestore(&connlock, flags); + error = EIO; + goto out_release_ref; + } + } + spin_unlock_irqrestore(&connlock, flags); + + scsi_remove_host(shost); + transport->destroy_session(ev->u.d_session.session_handle); + transport_unregister_device(&session->dev); + device_unregister(&session->dev); + + /* remove this session from the list of active sessions */ + spin_lock_irqsave(&priv->session_lock, flags); + list_del(&session->list); + spin_unlock_irqrestore(&priv->session_lock, flags); + + /* ref from host alloc */ + scsi_host_put(shost); +out_release_ref: + /* ref from host lookup */ + scsi_host_put(shost); + return error; +} + +static void iscsi_if_conn_dev_release(struct device *dev) +{ + struct iscsi_if_conn *conn = iscsi_dev_to_if_conn(dev); + struct Scsi_Host *shost = conn->host; + + scsi_host_put(shost); +} + +static int +iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) +{ + struct iscsi_if_session *session; + struct Scsi_Host *shost; + struct iscsi_if_conn *conn; + unsigned long flags; + int error; + + shost = scsi_host_lookup(ev->u.c_conn.sid); + if (shost == ERR_PTR(-ENXIO)) + return -EEXIST; + session = hostdata_session(shost->hostdata); + + conn = kmalloc(sizeof(struct iscsi_if_conn), GFP_KERNEL); + if (!conn) { + error = -ENOMEM; + goto out_release_ref; + } + memset(conn, 0, sizeof(struct iscsi_if_conn)); + INIT_LIST_HEAD(&conn->session_list); + INIT_LIST_HEAD(&conn->conn_list); + conn->host = shost; + conn->transport = transport; + + error = mempool_zone_init(&conn->z_pdu, Z_MAX_PDU, + NLMSG_SPACE(sizeof(struct iscsi_uevent) + + sizeof(struct iscsi_hdr) + + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), + Z_HIWAT_PDU); + if (error) { + printk(KERN_ERR "iscsi%d: can not allocate pdu zone for new " + "conn\n", shost->host_no); + goto out_free_conn; + } + error = mempool_zone_init(&conn->z_error, Z_MAX_ERROR, + NLMSG_SPACE(sizeof(struct iscsi_uevent)), + Z_HIWAT_ERROR); + if (error) { + printk(KERN_ERR "iscsi%d: can not allocate error zone for " + "new conn\n", shost->host_no); + goto out_free_pdu_pool; + } + + ev->r.handle = transport->create_conn(ev->u.c_conn.session_handle, + ev->u.c_conn.cid); + if (!ev->r.handle) { + error = -ENODEV; + goto out_free_error_pool; + } + + conn->connh = ev->r.handle; + + /* + * this is released in the dev's release function + */ + if (!scsi_host_get(shost)) + goto out_destroy_conn; + snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", + shost->host_no, ev->u.c_conn.cid); + conn->dev.parent = &session->dev; + conn->dev.release = iscsi_if_conn_dev_release; + error = device_register(&conn->dev); + if (error) { + printk(KERN_ERR "iscsi%d: could not register connections%u " + "dev\n", shost->host_no, ev->u.c_conn.cid); + goto out_release_parent_ref; + } + transport_register_device(&conn->dev); + + spin_lock_irqsave(&connlock, flags); + list_add(&conn->conn_list, &connlist); + list_add(&conn->session_list, &session->connections); + conn->active = 1; + spin_unlock_irqrestore(&connlock, flags); + + scsi_host_put(shost); + return 0; + +out_release_parent_ref: + scsi_host_put(shost); +out_destroy_conn: + transport->destroy_conn(ev->r.handle); +out_free_error_pool: + mempool_destroy(conn->z_error.pool); +out_free_pdu_pool: + mempool_destroy(conn->z_pdu.pool); +out_free_conn: + kfree(conn); +out_release_ref: + scsi_host_put(shost); + return error; +} + +static int +iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) +{ + unsigned long flags; + struct iscsi_if_conn *conn; + + conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle); + if (!conn) + return -EEXIST; + + transport->destroy_conn(ev->u.d_conn.conn_handle); + + spin_lock_irqsave(&connlock, flags); + conn->active = 0; + list_del(&conn->conn_list); + spin_unlock_irqrestore(&connlock, flags); + + transport_unregister_device(&conn->dev); + device_unregister(&conn->dev); + return 0; +} + +static int +iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, + struct nlmsghdr *nlh) +{ + struct iscsi_uevent *ev = NLMSG_DATA(nlh); + struct iscsi_stats *stats; + struct sk_buff *skbstat; + struct iscsi_if_conn *conn; + struct nlmsghdr *nlhstat; + struct iscsi_uevent *evstat; + int len = NLMSG_SPACE(sizeof(*ev) + + sizeof(struct iscsi_stats) + + sizeof(struct iscsi_stats_custom) * + ISCSI_STATS_CUSTOM_MAX); + int err = 0; + + conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle); + if (!conn) + return -EEXIST; + + do { + int actual_size; + + mempool_zone_complete(&conn->z_pdu); + + skbstat = mempool_zone_get_skb(&conn->z_pdu); + if (!skbstat) { + printk(KERN_ERR "iscsi%d: can not deliver stats: OOM\n", + conn->host->host_no); + return -ENOMEM; + } + + nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0, + (len - sizeof(*nlhstat)), 0); + evstat = NLMSG_DATA(nlhstat); + memset(evstat, 0, sizeof(*evstat)); + evstat->transport_handle = iscsi_handle(conn->transport); + evstat->type = nlh->nlmsg_type; + if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat) + evstat->iferror = -ENOMEM; + evstat->u.get_stats.conn_handle = + ev->u.get_stats.conn_handle; + stats = (struct iscsi_stats *) + ((char*)evstat + sizeof(*evstat)); + memset(stats, 0, sizeof(*stats)); + + transport->get_stats(ev->u.get_stats.conn_handle, stats); + actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) + + sizeof(struct iscsi_stats) + + sizeof(struct iscsi_stats_custom) * + stats->custom_length); + actual_size -= sizeof(*nlhstat); + actual_size = NLMSG_LENGTH(actual_size); + skb_trim(skb, NLMSG_ALIGN(actual_size)); + nlhstat->nlmsg_len = actual_size; + + err = iscsi_unicast_skb(&conn->z_pdu, skbstat); + } while (err < 0 && err != -ECONNREFUSED); + + return err; +} + +static int +iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +{ + int err = 0; + struct iscsi_uevent *ev = NLMSG_DATA(nlh); + struct iscsi_transport *transport = NULL; + struct iscsi_internal *priv; + + if (NETLINK_CREDS(skb)->uid) + return -EPERM; + + priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); + if (!priv) + return -EINVAL; + transport = priv->iscsi_transport; + + daemon_pid = NETLINK_CREDS(skb)->pid; + + switch (nlh->nlmsg_type) { + case ISCSI_UEVENT_CREATE_SESSION: + err = iscsi_if_create_session(priv, ev); + break; + case ISCSI_UEVENT_DESTROY_SESSION: + err = iscsi_if_destroy_session(priv, ev); + break; + case ISCSI_UEVENT_CREATE_CONN: + err = iscsi_if_create_conn(transport, ev); + break; + case ISCSI_UEVENT_DESTROY_CONN: + err = iscsi_if_destroy_conn(transport, ev); + break; + case ISCSI_UEVENT_BIND_CONN: + if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle)) + return -EEXIST; + ev->r.retcode = transport->bind_conn( + ev->u.b_conn.session_handle, + ev->u.b_conn.conn_handle, + ev->u.b_conn.transport_fd, + ev->u.b_conn.is_leading); + break; + case ISCSI_UEVENT_SET_PARAM: + if (!iscsi_if_find_conn(ev->u.set_param.conn_handle)) + return -EEXIST; + ev->r.retcode = transport->set_param( + ev->u.set_param.conn_handle, + ev->u.set_param.param, ev->u.set_param.value); + break; + case ISCSI_UEVENT_START_CONN: + if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle)) + return -EEXIST; + ev->r.retcode = transport->start_conn( + ev->u.start_conn.conn_handle); + break; + case ISCSI_UEVENT_STOP_CONN: + if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle)) + return -EEXIST; + transport->stop_conn(ev->u.stop_conn.conn_handle, + ev->u.stop_conn.flag); + break; + case ISCSI_UEVENT_SEND_PDU: + if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle)) + return -EEXIST; + ev->r.retcode = transport->send_pdu( + ev->u.send_pdu.conn_handle, + (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), + (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, + ev->u.send_pdu.data_size); + break; + case ISCSI_UEVENT_GET_STATS: + err = iscsi_if_get_stats(transport, skb, nlh); + break; + default: + err = -EINVAL; + break; + } + + return err; +} + +/* Get message from skb (based on rtnetlink_rcv_skb). Each message is + * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are + * discarded silently. */ +static void +iscsi_if_rx(struct sock *sk, int len) +{ + struct sk_buff *skb; + + down(&rx_queue_sema); + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { + while (skb->len >= NLMSG_SPACE(0)) { + int err; + uint32_t rlen; + struct nlmsghdr *nlh; + struct iscsi_uevent *ev; + + nlh = (struct nlmsghdr *)skb->data; + if (nlh->nlmsg_len < sizeof(*nlh) || + skb->len < nlh->nlmsg_len) { + break; + } + ev = NLMSG_DATA(nlh); + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + err = iscsi_if_recv_msg(skb, nlh); + if (err) { + ev->type = ISCSI_KEVENT_IF_ERROR; + ev->iferror = err; + } + do { + /* + * special case for GET_STATS: + * on success - sending reply and stats from + * inside of if_recv_msg(), + * on error - fall through. + */ + if (ev->type == ISCSI_UEVENT_GET_STATS && !err) + break; + err = iscsi_if_send_reply( + NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, + nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); + if (atomic_read(&z_reply.allocated) >= + z_reply.hiwat) + ev->iferror = -ENOMEM; + } while (err < 0 && err != -ECONNREFUSED); + skb_pull(skb, rlen); + } + kfree_skb(skb); + } + up(&rx_queue_sema); +} + +/* + * iSCSI connection attrs + */ +#define iscsi_conn_int_attr_show(param, format) \ static ssize_t \ -show_session_str_##field(struct class_device *cdev, char *buf) \ +show_conn_int_param_##param(struct class_device *cdev, char *buf) \ { \ - ssize_t ret = 0; \ - struct scsi_target *starget = transport_class_to_starget(cdev); \ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ + uint32_t value = 0; \ + struct iscsi_if_conn *conn = iscsi_cdev_to_if_conn(cdev); \ + struct iscsi_internal *priv; \ \ - if (i->fnt->get_##field) \ - ret = i->fnt->get_##field(starget, buf, PAGE_SIZE); \ - return ret; \ + priv = to_iscsi_internal(conn->host->transportt); \ + if (priv->param_mask & (1 << param)) \ + priv->iscsi_transport->get_param(conn->connh, param, &value); \ + return snprintf(buf, 20, format"\n", value); \ } -#define iscsi_session_rd_str_attr(field) \ - iscsi_session_show_str_fn(field) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_str_##field, NULL); +#define iscsi_conn_int_attr(field, param, format) \ + iscsi_conn_int_attr_show(param, format) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL); -iscsi_session_rd_str_attr(target_name); -iscsi_session_rd_str_attr(target_alias); +iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); +iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); +iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); +iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); +iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); +iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); /* - * iSCSI host attrs + * iSCSI session attrs */ - -/* - * Again, this is used for iSCSI names. Normally, we follow - * the transport class convention of having the lld set - * the field, but in these cases the value is too large. - */ -#define iscsi_host_show_str_fn(field) \ - \ +#define iscsi_session_int_attr_show(param, format) \ static ssize_t \ -show_host_str_##field(struct class_device *cdev, char *buf) \ +show_session_int_param_##param(struct class_device *cdev, char *buf) \ { \ - int ret = 0; \ - struct Scsi_Host *shost = transport_class_to_shost(cdev); \ - struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ + uint32_t value = 0; \ + struct iscsi_if_session *session = iscsi_cdev_to_if_session(cdev); \ + struct Scsi_Host *shost = iscsi_if_session_to_shost(session); \ + struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \ + struct iscsi_if_conn *conn = NULL; \ + unsigned long flags; \ \ - if (i->fnt->get_##field) \ - ret = i->fnt->get_##field(shost, buf, PAGE_SIZE); \ - return ret; \ + spin_lock_irqsave(&connlock, flags); \ + if (!list_empty(&session->connections)) \ + conn = list_entry(session->connections.next, \ + struct iscsi_if_conn, session_list); \ + spin_unlock_irqrestore(&connlock, flags); \ + \ + if (conn && (priv->param_mask & (1 << param))) \ + priv->iscsi_transport->get_param(conn->connh, param, &value);\ + return snprintf(buf, 20, format"\n", value); \ } -#define iscsi_host_rd_str_attr(field) \ - iscsi_host_show_str_fn(field) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_host_str_##field, NULL); +#define iscsi_session_int_attr(field, param, format) \ + iscsi_session_int_attr_show(param, format) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL); -iscsi_host_rd_str_attr(initiator_name); -iscsi_host_rd_str_attr(initiator_alias); +iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); +iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); +iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d"); +iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u"); +iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); +iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); +iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); +iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); -#define SETUP_SESSION_RD_ATTR(field) \ - if (i->fnt->show_##field) { \ - i->session_attrs[count] = &class_device_attr_##field; \ +#define SETUP_SESSION_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->session_attrs[count] = &class_device_attr_##field;\ count++; \ } -#define SETUP_HOST_RD_ATTR(field) \ - if (i->fnt->show_##field) { \ - i->host_attrs[count] = &class_device_attr_##field; \ +#define SETUP_CONN_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->conn_attrs[count] = &class_device_attr_##field; \ count++; \ } -static int iscsi_host_match(struct attribute_container *cont, - struct device *dev) +static int iscsi_is_session_dev(const struct device *dev) { - struct Scsi_Host *shost; - struct iscsi_internal *i; - - if (!scsi_is_host_device(dev)) - return 0; - - shost = dev_to_shost(dev); - if (!shost->transportt || shost->transportt->host_attrs.ac.class - != &iscsi_host_class.class) - return 0; - - i = to_iscsi_internal(shost->transportt); - - return &i->t.host_attrs.ac == cont; + return dev->release == iscsi_if_session_dev_release; } -static int iscsi_target_match(struct attribute_container *cont, - struct device *dev) +static int iscsi_session_match(struct attribute_container *cont, + struct device *dev) { + struct iscsi_if_session *session; struct Scsi_Host *shost; - struct iscsi_internal *i; + struct iscsi_internal *priv; - if (!scsi_is_target_device(dev)) + if (!iscsi_is_session_dev(dev)) return 0; - shost = dev_to_shost(dev->parent); - if (!shost->transportt || shost->transportt->host_attrs.ac.class - != &iscsi_host_class.class) + session = iscsi_dev_to_if_session(dev); + shost = iscsi_if_session_to_shost(session); + if (!shost->transportt) return 0; - i = to_iscsi_internal(shost->transportt); - - return &i->t.target_attrs.ac == cont; + priv = to_iscsi_internal(shost->transportt); + if (priv->session_cont.ac.class != &iscsi_session_class.class) + return 0; + + return &priv->session_cont.ac == cont; } -struct scsi_transport_template * -iscsi_attach_transport(struct iscsi_function_template *fnt) +static int iscsi_is_conn_dev(const struct device *dev) { - struct iscsi_internal *i = kmalloc(sizeof(struct iscsi_internal), - GFP_KERNEL); - int count = 0; + return dev->release == iscsi_if_conn_dev_release; +} - if (unlikely(!i)) - return NULL; +static int iscsi_conn_match(struct attribute_container *cont, + struct device *dev) +{ + struct iscsi_if_conn *conn; + struct Scsi_Host *shost; + struct iscsi_internal *priv; - memset(i, 0, sizeof(struct iscsi_internal)); - i->fnt = fnt; + if (!iscsi_is_conn_dev(dev)) + return 0; - i->t.target_attrs.ac.attrs = &i->session_attrs[0]; - i->t.target_attrs.ac.class = &iscsi_transport_class.class; - i->t.target_attrs.ac.match = iscsi_target_match; - transport_container_register(&i->t.target_attrs); - i->t.target_size = sizeof(struct iscsi_class_session); + conn = iscsi_dev_to_if_conn(dev); + shost = conn->host; + if (!shost->transportt) + return 0; - SETUP_SESSION_RD_ATTR(tsih); - SETUP_SESSION_RD_ATTR(isid); - SETUP_SESSION_RD_ATTR(header_digest); - SETUP_SESSION_RD_ATTR(data_digest); - SETUP_SESSION_RD_ATTR(target_name); - SETUP_SESSION_RD_ATTR(target_alias); - SETUP_SESSION_RD_ATTR(port); - SETUP_SESSION_RD_ATTR(tpgt); - SETUP_SESSION_RD_ATTR(ip_address); - SETUP_SESSION_RD_ATTR(initial_r2t); - SETUP_SESSION_RD_ATTR(immediate_data); - SETUP_SESSION_RD_ATTR(max_recv_data_segment_len); - SETUP_SESSION_RD_ATTR(max_burst_len); - SETUP_SESSION_RD_ATTR(first_burst_len); - SETUP_SESSION_RD_ATTR(def_time2wait); - SETUP_SESSION_RD_ATTR(def_time2retain); - SETUP_SESSION_RD_ATTR(max_outstanding_r2t); - SETUP_SESSION_RD_ATTR(data_pdu_in_order); - SETUP_SESSION_RD_ATTR(data_sequence_in_order); - SETUP_SESSION_RD_ATTR(erl); + priv = to_iscsi_internal(shost->transportt); + if (priv->conn_cont.ac.class != &iscsi_connection_class.class) + return 0; + + return &priv->conn_cont.ac == cont; +} + +int iscsi_register_transport(struct iscsi_transport *tt) +{ + struct iscsi_internal *priv; + unsigned long flags; + int count = 0, err; + + BUG_ON(!tt); + + priv = iscsi_if_transport_lookup(tt); + if (priv) + return -EEXIST; + + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + memset(priv, 0, sizeof(*priv)); + INIT_LIST_HEAD(&priv->list); + INIT_LIST_HEAD(&priv->sessions); + spin_lock_init(&priv->session_lock); + priv->iscsi_transport = tt; + + priv->cdev.class = &iscsi_transport_class; + snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name); + err = class_device_register(&priv->cdev); + if (err) + goto free_priv; + + err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group); + if (err) + goto unregister_cdev; + + /* setup parameters mask */ + priv->param_mask = 0xFFFFFFFF; + if (!(tt->caps & CAP_MULTI_R2T)) + priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T); + if (!(tt->caps & CAP_HDRDGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN); + if (!(tt->caps & CAP_DATADGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN); + if (!(tt->caps & CAP_MARKERS)) { + priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN); + priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN); + } + + /* connection parameters */ + priv->conn_cont.ac.attrs = &priv->conn_attrs[0]; + priv->conn_cont.ac.class = &iscsi_connection_class.class; + priv->conn_cont.ac.match = iscsi_conn_match; + transport_container_register(&priv->conn_cont); + + SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); + SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); + SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN); + SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN); + SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN); + SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN); + + BUG_ON(count > ISCSI_CONN_ATTRS); + priv->conn_attrs[count] = NULL; + count = 0; + + /* session parameters */ + priv->session_cont.ac.attrs = &priv->session_attrs[0]; + priv->session_cont.ac.class = &iscsi_session_class.class; + priv->session_cont.ac.match = iscsi_session_match; + transport_container_register(&priv->session_cont); + + SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); + SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); + SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN); + SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST); + SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST); + SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); + SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN) + SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL); BUG_ON(count > ISCSI_SESSION_ATTRS); - i->session_attrs[count] = NULL; + priv->session_attrs[count] = NULL; - i->t.host_attrs.ac.attrs = &i->host_attrs[0]; - i->t.host_attrs.ac.class = &iscsi_host_class.class; - i->t.host_attrs.ac.match = iscsi_host_match; - transport_container_register(&i->t.host_attrs); - i->t.host_size = 0; + spin_lock_irqsave(&iscsi_transport_lock, flags); + list_add(&priv->list, &iscsi_transports); + spin_unlock_irqrestore(&iscsi_transport_lock, flags); - count = 0; - SETUP_HOST_RD_ATTR(initiator_name); - SETUP_HOST_RD_ATTR(initiator_alias); + printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name); + return 0; - BUG_ON(count > ISCSI_HOST_ATTRS); - i->host_attrs[count] = NULL; - - return &i->t; +unregister_cdev: + class_device_unregister(&priv->cdev); +free_priv: + kfree(priv); + return err; } +EXPORT_SYMBOL_GPL(iscsi_register_transport); -EXPORT_SYMBOL(iscsi_attach_transport); - -void iscsi_release_transport(struct scsi_transport_template *t) +int iscsi_unregister_transport(struct iscsi_transport *tt) { - struct iscsi_internal *i = to_iscsi_internal(t); + struct iscsi_internal *priv; + unsigned long flags; - transport_container_unregister(&i->t.target_attrs); - transport_container_unregister(&i->t.host_attrs); - - kfree(i); + BUG_ON(!tt); + + down(&rx_queue_sema); + + priv = iscsi_if_transport_lookup(tt); + BUG_ON (!priv); + + spin_lock_irqsave(&priv->session_lock, flags); + if (!list_empty(&priv->sessions)) { + spin_unlock_irqrestore(&priv->session_lock, flags); + up(&rx_queue_sema); + return -EPERM; + } + spin_unlock_irqrestore(&priv->session_lock, flags); + + spin_lock_irqsave(&iscsi_transport_lock, flags); + list_del(&priv->list); + spin_unlock_irqrestore(&iscsi_transport_lock, flags); + + transport_container_unregister(&priv->conn_cont); + transport_container_unregister(&priv->session_cont); + + sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group); + class_device_unregister(&priv->cdev); + up(&rx_queue_sema); + + return 0; +} +EXPORT_SYMBOL_GPL(iscsi_unregister_transport); + +static int +iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct netlink_notify *n = ptr; + + if (event == NETLINK_URELEASE && + n->protocol == NETLINK_ISCSI && n->pid) { + struct iscsi_if_conn *conn; + unsigned long flags; + + mempool_zone_complete(&z_reply); + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &connlist, conn_list) { + mempool_zone_complete(&conn->z_error); + mempool_zone_complete(&conn->z_pdu); + } + spin_unlock_irqrestore(&connlock, flags); + } + + return NOTIFY_DONE; } -EXPORT_SYMBOL(iscsi_release_transport); +static struct notifier_block iscsi_nl_notifier = { + .notifier_call = iscsi_rcv_nl_event, +}; static __init int iscsi_transport_init(void) { - int err = transport_class_register(&iscsi_transport_class); + int err; + err = class_register(&iscsi_transport_class); if (err) return err; - return transport_class_register(&iscsi_host_class); + + err = transport_class_register(&iscsi_connection_class); + if (err) + goto unregister_transport_class; + + err = transport_class_register(&iscsi_session_class); + if (err) + goto unregister_conn_class; + + err = netlink_register_notifier(&iscsi_nl_notifier); + if (err) + goto unregister_session_class; + + nls = netlink_kernel_create(NETLINK_ISCSI, iscsi_if_rx); + if (!nls) { + err = -ENOBUFS; + goto unregister_notifier; + } + + err = mempool_zone_init(&z_reply, Z_MAX_REPLY, + NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY); + if (!err) + return 0; + + sock_release(nls->sk_socket); +unregister_notifier: + netlink_unregister_notifier(&iscsi_nl_notifier); +unregister_session_class: + transport_class_unregister(&iscsi_session_class); +unregister_conn_class: + transport_class_unregister(&iscsi_connection_class); +unregister_transport_class: + class_unregister(&iscsi_transport_class); + return err; } static void __exit iscsi_transport_exit(void) { - transport_class_unregister(&iscsi_host_class); - transport_class_unregister(&iscsi_transport_class); + mempool_destroy(z_reply.pool); + sock_release(nls->sk_socket); + netlink_unregister_notifier(&iscsi_nl_notifier); + transport_class_unregister(&iscsi_connection_class); + transport_class_unregister(&iscsi_session_class); + class_unregister(&iscsi_transport_class); } module_init(iscsi_transport_init); module_exit(iscsi_transport_exit); -MODULE_AUTHOR("Mike Christie"); -MODULE_DESCRIPTION("iSCSI Transport Attributes"); +MODULE_AUTHOR("Mike Christie , " + "Dmitry Yusupov , " + "Alex Aizman "); +MODULE_DESCRIPTION("iSCSI Transport Interface"); MODULE_LICENSE("GPL"); From c899e4ef96f01b7e051045e08f3a8fe5e5f2bbb7 Mon Sep 17 00:00:00 2001 From: Alex Aizman Date: Thu, 4 Aug 2005 19:33:15 -0700 Subject: [PATCH 0017/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Kconfig update Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index f1e8c4223ed1..ff105c7b966c 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -223,12 +223,35 @@ config SCSI_FC_ATTRS config SCSI_ISCSI_ATTRS tristate "iSCSI Transport Attributes" - depends on SCSI + depends on SCSI && NET help If you wish to export transport-specific information about each attached iSCSI device to sysfs, say Y. Otherwise, say N. +config ISCSI_TCP + tristate "iSCSI Initiator over TCP/IP" + depends on SCSI && INET && SCSI_ISCSI_ATTRS + select CRYPTO + select CRYPTO_MD5 + select CRYPTO_CRC32C + help + The iSCSI Driver provides a host with the ability to access storage + through an IP network. The driver uses the iSCSI protocol to transport + SCSI requests and responses over a TCP/IP network between the host + (the "initiator") and "targets". Architecturally, the iSCSI driver + combines with the host's TCP/IP stack, network drivers, and Network + Interface Card (NIC) to provide the same functions as a SCSI or a + Fibre Channel (FC) adapter driver with a Host Bus Adapter (HBA). + + To compile this driver as a module, choose M here: the + module will be called iscsi_tcp. + + The userspace component needed to initialize the driver, documentation, + and sample configuration files can be found here: + + http://linux-iscsi.sf.net + endmenu menu "SCSI low-level drivers" From 7ba2471389071707cb45e7f755b417edad68049d Mon Sep 17 00:00:00 2001 From: Alex Aizman Date: Thu, 4 Aug 2005 19:30:08 -0700 Subject: [PATCH 0018/1940] [SCSI] open-iscsi/linux-iscsi-5 Initiator: Initiator code drivers/scsi/iscsi_tcp.c, iscsi data path. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 3627 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3627 insertions(+) create mode 100644 drivers/scsi/iscsi_tcp.c diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c new file mode 100644 index 000000000000..810e5e59658f --- /dev/null +++ b/drivers/scsi/iscsi_tcp.c @@ -0,0 +1,3627 @@ +/* + * iSCSI Initiator over TCP/IP Data-Path + * + * Copyright (C) 2004 Dmitry Yusupov + * Copyright (C) 2004 Alex Aizman + * Copyright (C) 2005 Mike Christie + * maintained by open-iscsi@googlegroups.com + * + * 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. + * + * See the file COPYING included with this distribution for more details. + * + * Credits: + * Christoph Hellwig + * FUJITA Tomonori + * Arne Redlich + * Zhenyu Wang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iscsi_tcp.h" + +MODULE_AUTHOR("Dmitry Yusupov , " + "Alex Aizman "); +MODULE_DESCRIPTION("iSCSI/TCP data-path"); +MODULE_LICENSE("GPL"); + +/* #define DEBUG_TCP */ +/* #define DEBUG_SCSI */ +#define DEBUG_ASSERT + +#ifdef DEBUG_TCP +#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt) +#else +#define debug_tcp(fmt...) +#endif + +#ifdef DEBUG_SCSI +#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt) +#else +#define debug_scsi(fmt...) +#endif + +#ifndef DEBUG_ASSERT +#ifdef BUG_ON +#undef BUG_ON +#endif +#define BUG_ON(expr) +#endif + +#define INVALID_SN_DELTA 0xffff + +static unsigned int iscsi_max_lun = 512; +module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); + +/* global data */ +static kmem_cache_t *taskcache; + +static inline void +iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size) +{ + sg_init_one(&ibuf->sg, (u8 *)vbuf, size); + ibuf->sent = 0; +} + +static inline void +iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) +{ + ibuf->sg.page = (void*)vbuf; + ibuf->sg.offset = (unsigned int)-1; + ibuf->sg.length = size; + ibuf->sent = 0; +} + +static inline void* +iscsi_buf_iov_base(struct iscsi_buf *ibuf) +{ + return (char*)ibuf->sg.page + ibuf->sent; +} + +static inline void +iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg) +{ + /* + * Fastpath: sg element fits into single page + */ + if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) { + ibuf->sg.page = sg->page; + ibuf->sg.offset = sg->offset; + ibuf->sg.length = sg->length; + } else + iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length); + ibuf->sent = 0; +} + +static inline int +iscsi_buf_left(struct iscsi_buf *ibuf) +{ + int rc; + + rc = ibuf->sg.length - ibuf->sent; + BUG_ON(rc < 0); + return rc; +} + +static inline void +iscsi_buf_init_hdr(struct iscsi_conn *conn, struct iscsi_buf *ibuf, + char *vbuf, u8 *crc) +{ + iscsi_buf_init_virt(ibuf, vbuf, sizeof(struct iscsi_hdr)); + if (conn->hdrdgst_en) { + crypto_digest_digest(conn->tx_tfm, &ibuf->sg, 1, crc); + ibuf->sg.length += sizeof(uint32_t); + } +} + +static void +iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) +{ + struct iscsi_session *session = conn->session; + unsigned long flags; + + spin_lock_irqsave(&session->lock, flags); + if (session->conn_cnt == 1 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + spin_unlock_irqrestore(&session->lock, flags); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + iscsi_conn_error(iscsi_handle(conn), err); +} + +static inline int +iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) +{ + uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn); + uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn); + + if (max_cmdsn < exp_cmdsn -1 && + max_cmdsn > exp_cmdsn - INVALID_SN_DELTA) + return ISCSI_ERR_MAX_CMDSN; + if (max_cmdsn > session->max_cmdsn || + max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA) + session->max_cmdsn = max_cmdsn; + if (exp_cmdsn > session->exp_cmdsn || + exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA) + session->exp_cmdsn = exp_cmdsn; + + return 0; +} + +static inline int +iscsi_hdr_extract(struct iscsi_conn *conn) +{ + struct sk_buff *skb = conn->in.skb; + + if (conn->in.copy >= conn->hdr_size && + conn->in_progress == IN_PROGRESS_WAIT_HEADER) { + /* + * Zero-copy PDU Header: using connection context + * to store header pointer. + */ + if (skb_shinfo(skb)->frag_list == NULL && + !skb_shinfo(skb)->nr_frags) + conn->in.hdr = (struct iscsi_hdr *) + ((char*)skb->data + conn->in.offset); + else { + /* ignoring return code since we checked + * in.copy before */ + skb_copy_bits(skb, conn->in.offset, + &conn->hdr, conn->hdr_size); + conn->in.hdr = &conn->hdr; + } + conn->in.offset += conn->hdr_size; + conn->in.copy -= conn->hdr_size; + } else { + int hdr_remains; + int copylen; + + /* + * PDU header scattered across SKB's, + * copying it... This'll happen quite rarely. + */ + + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER) + conn->in.hdr_offset = 0; + + hdr_remains = conn->hdr_size - conn->in.hdr_offset; + BUG_ON(hdr_remains <= 0); + + copylen = min(conn->in.copy, hdr_remains); + skb_copy_bits(skb, conn->in.offset, + (char*)&conn->hdr + conn->in.hdr_offset, copylen); + + debug_tcp("PDU gather offset %d bytes %d in.offset %d " + "in.copy %d\n", conn->in.hdr_offset, copylen, + conn->in.offset, conn->in.copy); + + conn->in.offset += copylen; + conn->in.copy -= copylen; + if (copylen < hdr_remains) { + conn->in_progress = IN_PROGRESS_HEADER_GATHER; + conn->in.hdr_offset += copylen; + return -EAGAIN; + } + conn->in.hdr = &conn->hdr; + conn->discontiguous_hdr_cnt++; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + + return 0; +} + +static inline void +iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct scsi_cmnd *sc = ctask->sc; + struct iscsi_session *session = conn->session; + + spin_lock(&session->lock); + if (unlikely(!sc)) { + spin_unlock(&session->lock); + return; + } + if (sc->sc_data_direction == DMA_TO_DEVICE) { + struct iscsi_data_task *dtask, *n; + /* WRITE: cleanup Data-Out's if any */ + spin_lock(&conn->lock); + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } + spin_unlock(&conn->lock); + } + ctask->xmstate = XMSTATE_IDLE; + ctask->r2t = NULL; + ctask->sc = NULL; + __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + spin_unlock(&session->lock); +} + +/** + * iscsi_cmd_rsp - SCSI Command Response processing + * @conn: iscsi connection + * @ctask: scsi command task + **/ +static int +iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + int rc; + struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr; + struct iscsi_session *session = conn->session; + struct scsi_cmnd *sc = ctask->sc; + + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); + if (rc) { + sc->result = (DID_ERROR << 16); + goto out; + } + + conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; + + sc->result = (DID_OK << 16) | rhdr->cmd_status; + + if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) { + sc->result = (DID_ERROR << 16); + goto out; + } + + if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) { + int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE); + + memcpy(sc->sense_buffer, conn->data + 2, sensecopy); + debug_scsi("copied %d bytes of sense\n", sensecopy); + } + + if (sc->sc_data_direction == DMA_TO_DEVICE) + goto out; + + if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { + int res_count = be32_to_cpu(rhdr->residual_count); + + if (res_count > 0 && res_count <= sc->request_bufflen) + sc->resid = res_count; + else + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) + sc->resid = be32_to_cpu(rhdr->residual_count); + +out: + debug_scsi("done [sc %lx res %d itt 0x%x]\n", + (long)sc, sc->result, ctask->itt); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); + return rc; +} + +/** + * iscsi_data_rsp - SCSI Data-In Response processing + * @conn: iscsi connection + * @ctask: scsi command task + **/ +static int +iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + int rc; + struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)conn->in.hdr; + struct iscsi_session *session = conn->session; + int datasn = be32_to_cpu(rhdr->datasn); + + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); + if (rc) + return rc; + /* + * setup Data-In byte counter (gets decremented..) + */ + ctask->data_count = conn->in.datalen; + + if (conn->in.datalen == 0) + return 0; + + if (ctask->datasn != datasn) + return ISCSI_ERR_DATASN; + + ctask->datasn++; + + ctask->data_offset = be32_to_cpu(rhdr->offset); + if (ctask->data_offset + conn->in.datalen > ctask->total_length) + return ISCSI_ERR_DATA_OFFSET; + + if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) { + struct scsi_cmnd *sc = ctask->sc; + + conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; + if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { + int res_count = be32_to_cpu(rhdr->residual_count); + + if (res_count > 0 && + res_count <= sc->request_bufflen) { + sc->resid = res_count; + sc->result = (DID_OK << 16) | rhdr->cmd_status; + } else + sc->result = (DID_BAD_TARGET << 16) | + rhdr->cmd_status; + } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) { + sc->resid = be32_to_cpu(rhdr->residual_count); + sc->result = (DID_OK << 16) | rhdr->cmd_status; + } else + sc->result = (DID_OK << 16) | rhdr->cmd_status; + } + + conn->datain_pdus_cnt++; + return 0; +} + +/** + * iscsi_solicit_data_init - initialize first Data-Out + * @conn: iscsi connection + * @ctask: scsi command task + * @r2t: R2T info + * + * Notes: + * Initialize first Data-Out within this R2T sequence and finds + * proper data_offset within this SCSI command. + * + * This function is called with connection lock taken. + **/ +static void +iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct iscsi_r2t_info *r2t) +{ + struct iscsi_data *hdr; + struct iscsi_data_task *dtask; + struct scsi_cmnd *sc = ctask->sc; + + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; + memset(hdr, 0, sizeof(struct iscsi_data)); + hdr->ttt = r2t->ttt; + hdr->datasn = cpu_to_be32(r2t->solicit_datasn); + r2t->solicit_datasn++; + hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; + hdr->exp_statsn = r2t->exp_statsn; + hdr->offset = cpu_to_be32(r2t->data_offset); + if (r2t->data_length > conn->max_xmit_dlength) { + hton24(hdr->dlength, conn->max_xmit_dlength); + r2t->data_count = conn->max_xmit_dlength; + hdr->flags = 0; + } else { + hton24(hdr->dlength, r2t->data_length); + r2t->data_count = r2t->data_length; + hdr->flags = ISCSI_FLAG_CMD_FINAL; + } + conn->dataout_pdus_cnt++; + + r2t->sent = 0; + + iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr, + (u8 *)dtask->hdrext); + + r2t->dtask = dtask; + + if (sc->use_sg) { + int i, sg_count = 0; + struct scatterlist *sg = sc->request_buffer; + + r2t->sg = NULL; + for (i = 0; i < sc->use_sg; i++, sg += 1) { + /* FIXME: prefetch ? */ + if (sg_count + sg->length > r2t->data_offset) { + int page_offset; + + /* sg page found! */ + + /* offset within this page */ + page_offset = r2t->data_offset - sg_count; + + /* fill in this buffer */ + iscsi_buf_init_sg(&r2t->sendbuf, sg); + r2t->sendbuf.sg.offset += page_offset; + r2t->sendbuf.sg.length -= page_offset; + + /* xmit logic will continue with next one */ + r2t->sg = sg + 1; + break; + } + sg_count += sg->length; + } + BUG_ON(r2t->sg == NULL); + } else + iscsi_buf_init_iov(&ctask->sendbuf, + (char*)sc->request_buffer + r2t->data_offset, + r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); +} + +/** + * iscsi_r2t_rsp - iSCSI R2T Response processing + * @conn: iscsi connection + * @ctask: scsi command task + **/ +static int +iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_r2t_info *r2t; + struct iscsi_session *session = conn->session; + struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr; + int r2tsn = be32_to_cpu(rhdr->r2tsn); + int rc; + + if (conn->in.ahslen) + return ISCSI_ERR_AHSLEN; + + if (conn->in.datalen) + return ISCSI_ERR_DATALEN; + + if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn) + return ISCSI_ERR_R2TSN; + + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); + if (rc) + return rc; + + /* FIXME: use R2TSN to detect missing R2T */ + + /* fill-in new R2T associated with the task */ + spin_lock(&session->lock); + if (!ctask->sc || ctask->mtask || + session->state != ISCSI_STATE_LOGGED_IN) { + printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in " + "recovery...\n", ctask->itt); + spin_unlock(&session->lock); + return 0; + } + rc = __kfifo_get(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + BUG_ON(!rc); + + r2t->exp_statsn = rhdr->statsn; + r2t->data_length = be32_to_cpu(rhdr->data_length); + if (r2t->data_length == 0 || + r2t->data_length > session->max_burst) { + spin_unlock(&session->lock); + return ISCSI_ERR_DATALEN; + } + + r2t->data_offset = be32_to_cpu(rhdr->data_offset); + if (r2t->data_offset + r2t->data_length > ctask->total_length) { + spin_unlock(&session->lock); + return ISCSI_ERR_DATALEN; + } + + r2t->ttt = rhdr->ttt; /* no flip */ + r2t->solicit_datasn = 0; + + iscsi_solicit_data_init(conn, ctask, r2t); + + ctask->exp_r2tsn = r2tsn + 1; + ctask->xmstate |= XMSTATE_SOL_HDR; + __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*)); + __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*)); + + schedule_work(&conn->xmitwork); + conn->r2t_pdus_cnt++; + spin_unlock(&session->lock); + + return 0; +} + +static int +iscsi_hdr_recv(struct iscsi_conn *conn) +{ + int rc = 0; + struct iscsi_hdr *hdr; + struct iscsi_cmd_task *ctask; + struct iscsi_session *session = conn->session; + uint32_t cdgst, rdgst = 0; + + hdr = conn->in.hdr; + + /* verify PDU length */ + conn->in.datalen = ntoh24(hdr->dlength); + if (conn->in.datalen > conn->max_recv_dlength) { + printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n", + conn->in.datalen, conn->max_recv_dlength); + return ISCSI_ERR_DATALEN; + } + conn->data_copied = 0; + + /* read AHS */ + conn->in.ahslen = hdr->hlength*(4*sizeof(__u16)); + conn->in.offset += conn->in.ahslen; + conn->in.copy -= conn->in.ahslen; + if (conn->in.copy < 0) { + printk(KERN_ERR "iscsi_tcp: can't handle AHS with length " + "%d bytes\n", conn->in.ahslen); + return ISCSI_ERR_AHSLEN; + } + + /* calculate read padding */ + conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1); + if (conn->in.padding) { + conn->in.padding = ISCSI_PAD_LEN - conn->in.padding; + debug_scsi("read padding %d bytes\n", conn->in.padding); + } + + if (conn->hdrdgst_en) { + struct scatterlist sg; + + sg_init_one(&sg, (u8 *)hdr, + sizeof(struct iscsi_hdr) + conn->in.ahslen); + crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst); + rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + + conn->in.ahslen); + } + + /* save opcode for later */ + conn->in.opcode = hdr->opcode; + + /* verify itt (itt encoding: age+cid+itt) */ + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if ((hdr->itt & AGE_MASK) != + (session->age << AGE_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x expected " + "session age (%x)\n", hdr->itt, + session->age & AGE_MASK); + return ISCSI_ERR_BAD_ITT; + } + + if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x, expected " + "CID (%x)\n", hdr->itt, conn->id); + return ISCSI_ERR_BAD_ITT; + } + conn->in.itt = hdr->itt & ITT_MASK; + } else + conn->in.itt = hdr->itt; + + debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n", + hdr->opcode, conn->in.offset, conn->in.copy, + conn->in.ahslen, conn->in.datalen); + + if (conn->in.itt < session->cmds_max) { + if (conn->hdrdgst_en && cdgst != rdgst) { + printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error " + "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst, + cdgst); + return ISCSI_ERR_HDR_DGST; + } + + ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt]; + + if (!ctask->sc) { + printk(KERN_INFO "iscsi_tcp: dropping ctask with " + "itt 0x%x\n", ctask->itt); + conn->in.datalen = 0; /* force drop */ + return 0; + } + + if (ctask->sc->SCp.phase != session->age) { + printk(KERN_ERR "iscsi_tcp: ctask's session age %d, " + "expected %d\n", ctask->sc->SCp.phase, + session->age); + return ISCSI_ERR_SESSION_FAILED; + } + + conn->in.ctask = ctask; + + debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n", + hdr->opcode, conn->id, (long)ctask->sc, + ctask->itt, conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_SCSI_CMD_RSP: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE) + rc = iscsi_cmd_rsp(conn, ctask); + else if (!conn->in.datalen) + rc = iscsi_cmd_rsp(conn, ctask); + else + /* + * got sense or response data; copying PDU + * Header to the connection's header + * placeholder + */ + memcpy(&conn->hdr, hdr, + sizeof(struct iscsi_hdr)); + break; + case ISCSI_OP_SCSI_DATA_IN: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + /* save flags for non-exceptional status */ + conn->in.flags = hdr->flags; + /* save cmd_status for sense data */ + conn->in.cmd_status = + ((struct iscsi_data_rsp*)hdr)->cmd_status; + rc = iscsi_data_rsp(conn, ctask); + break; + case ISCSI_OP_R2T: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE && + ctask->sc->sc_data_direction == DMA_TO_DEVICE) + rc = iscsi_r2t_rsp(conn, ctask); + else + rc = ISCSI_ERR_PROTO; + break; + case ISCSI_OP_NOOP_IN: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGOUT_RSP: + case ISCSI_OP_ASYNC_EVENT: + case ISCSI_OP_REJECT: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + /* update ExpStatSN */ + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + if (!conn->in.datalen) { + struct iscsi_mgmt_task *mtask; + + rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, + NULL, 0); + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET && + conn->in.itt < ISCSI_MGMT_ITT_OFFSET + + session->mgmtpool_max) { + struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + + debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", + conn->in.opcode, conn->id, mtask->itt, + conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_TEXT_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (!conn->in.datalen) { + rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, + NULL, 0); + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + case ISCSI_OP_SCSI_TMFUNC_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (conn->in.datalen || conn->in.ahslen) { + rc = ISCSI_ERR_PROTO; + break; + } + conn->tmfrsp_pdus_cnt++; + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + conn->tmabort_state = + ((struct iscsi_tm_rsp *)hdr)-> + response == SCSI_TCP_TM_RESP_COMPLETE ? + TMABORT_SUCCESS:TMABORT_FAILED; + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt == ISCSI_RESERVED_TAG) { + if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) { + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (!rc) + rc = iscsi_recv_pdu(iscsi_handle(conn), + hdr, NULL, 0); + } + else + rc = ISCSI_ERR_BAD_OPCODE; + } else + rc = ISCSI_ERR_BAD_ITT; + + return rc; +} + +/** + * iscsi_ctask_copy - copy skb bits to the destanation cmd task + * @conn: iscsi connection + * @ctask: scsi command task + * @buf: buffer to copy to + * @buf_size: size of buffer + * @offset: offset within the buffer + * + * Notes: + * The function calls skb_copy_bits() and updates per-connection and + * per-cmd byte counters. + * + * Read counters (in bytes): + * + * conn->in.offset offset within in progress SKB + * conn->in.copy left to copy from in progress SKB + * including padding + * conn->in.copied copied already from in progress SKB + * conn->data_copied copied already from in progress buffer + * ctask->sent total bytes sent up to the MidLayer + * ctask->data_count left to copy from in progress Data-In + * buf_left left to copy from in progress buffer + **/ +static inline int +iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + void *buf, int buf_size, int offset) +{ + int buf_left = buf_size - (conn->data_copied + offset); + int size = min(conn->in.copy, buf_left); + int rc; + + size = min(size, ctask->data_count); + + debug_tcp("ctask_copy %d bytes at offset %d copied %d\n", + size, conn->in.offset, conn->in.copied); + + BUG_ON(size <= 0); + BUG_ON(ctask->sent + size > ctask->total_length); + + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + (offset + conn->data_copied), size); + /* must fit into skb->len */ + BUG_ON(rc); + + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; + ctask->sent += size; + ctask->data_count -= size; + + BUG_ON(conn->in.copy < 0); + BUG_ON(ctask->data_count < 0); + + if (buf_size != (conn->data_copied + offset)) { + if (!ctask->data_count) { + BUG_ON(buf_size - conn->data_copied < 0); + /* done with this PDU */ + return buf_size - conn->data_copied; + } + return -EAGAIN; + } + + /* done with this buffer or with both - PDU and buffer */ + conn->data_copied = 0; + return 0; +} + +/** + * iscsi_tcp_copy - copy skb bits to the destanation buffer + * @conn: iscsi connection + * @buf: buffer to copy to + * @buf_size: number of bytes to copy + * + * Notes: + * The function calls skb_copy_bits() and updates per-connection + * byte counters. + **/ +static inline int +iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size) +{ + int buf_left = buf_size - conn->data_copied; + int size = min(conn->in.copy, buf_left); + int rc; + + debug_tcp("tcp_copy %d bytes at offset %d copied %d\n", + size, conn->in.offset, conn->data_copied); + BUG_ON(size <= 0); + + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + conn->data_copied, size); + BUG_ON(rc); + + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; + + if (buf_size != conn->data_copied) + return -EAGAIN; + + return 0; +} + +static inline void +partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg, + int offset, int length) +{ + struct scatterlist temp; + + memcpy(&temp, sg, sizeof(struct scatterlist)); + temp.offset = offset; + temp.length = length; + crypto_digest_update(conn->data_rx_tfm, &temp, 1); +} + +static int iscsi_scsi_data_in(struct iscsi_conn *conn) +{ + struct iscsi_cmd_task *ctask = conn->in.ctask; + struct scsi_cmnd *sc = ctask->sc; + struct scatterlist tmp, *sg; + int i, offset, rc = 0; + + BUG_ON((void*)ctask != sc->SCp.ptr); + + /* + * copying Data-In into the Scsi_Cmnd + */ + if (!sc->use_sg) { + i = ctask->data_count; + rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer, + sc->request_bufflen, ctask->data_offset); + if (rc == -EAGAIN) + return rc; + if (conn->datadgst_en) { + sg_init_one(&tmp, sc->request_buffer, i); + crypto_digest_update(conn->data_rx_tfm, &tmp, 1); + } + rc = 0; + goto done; + } + + offset = ctask->data_offset; + sg = sc->request_buffer; + + if (ctask->data_offset) + for (i = 0; i < ctask->sg_count; i++) + offset -= sg[i].length; + /* we've passed through partial sg*/ + if (offset < 0) + offset = 0; + + for (i = ctask->sg_count; i < sc->use_sg; i++) { + char *dest; + + dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0); + rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset, + sg[i].length, offset); + kunmap_atomic(dest, KM_SOFTIRQ0); + if (rc == -EAGAIN) + /* continue with the next SKB/PDU */ + return rc; + if (!rc) { + if (conn->datadgst_en) { + if (!offset) + crypto_digest_update(conn->data_rx_tfm, + &sg[i], 1); + else + partial_sg_digest_update(conn, &sg[i], + sg[i].offset + offset, + sg[i].length - offset); + } + offset = 0; + ctask->sg_count++; + } + + if (!ctask->data_count) { + if (rc && conn->datadgst_en) + /* + * data-in is complete, but buffer not... + */ + partial_sg_digest_update(conn, &sg[i], + sg[i].offset, sg[i].length-rc); + rc = 0; + break; + } + + if (!conn->in.copy) + return -EAGAIN; + } + BUG_ON(ctask->data_count); + +done: + /* check for non-exceptional status */ + if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) { + debug_scsi("done [sc %lx res %d itt 0x%x]\n", + (long)sc, sc->result, ctask->itt); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); + } + + return rc; +} + +static int +iscsi_data_recv(struct iscsi_conn *conn) +{ + struct iscsi_session *session = conn->session; + int rc = 0; + + switch(conn->in.opcode) { + case ISCSI_OP_SCSI_DATA_IN: + rc = iscsi_scsi_data_in(conn); + break; + case ISCSI_OP_SCSI_CMD_RSP: { + /* + * SCSI Sense Data: + * copying the entire Data Segment. + */ + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { + rc = -EAGAIN; + goto exit; + } + + /* + * check for sense + */ + conn->in.hdr = &conn->hdr; + conn->senselen = (conn->data[0] << 8) | conn->data[1]; + rc = iscsi_cmd_rsp(conn, conn->in.ctask); + } + break; + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_NOOP_IN: { + struct iscsi_mgmt_task *mtask = NULL; + + if (conn->in.itt != ISCSI_RESERVED_TAG) + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + + /* + * Collect data segment to the connection's data + * placeholder + */ + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { + rc = -EAGAIN; + goto exit; + } + + rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, + conn->data, conn->in.datalen); + + if (mtask && conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&mtask, + sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + default: + BUG_ON(1); + } +exit: + return rc; +} + +/** + * iscsi_tcp_data_recv - TCP receive in sendfile fashion + * @rd_desc: read descriptor + * @skb: socket buffer + * @offset: offset in skb + * @len: skb->len - offset + **/ +static int +iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, + unsigned int offset, size_t len) +{ + int rc; + struct iscsi_conn *conn = rd_desc->arg.data; + int start = skb_headlen(skb); + int processed; + char pad[ISCSI_PAD_LEN]; + struct scatterlist sg; + + /* + * Save current SKB and its offset in the corresponding + * connection context. + */ + conn->in.copy = start - offset; + conn->in.offset = offset; + conn->in.skb = skb; + conn->in.len = conn->in.copy; + BUG_ON(conn->in.copy <= 0); + debug_tcp("in %d bytes\n", conn->in.copy); + +more: + conn->in.copied = 0; + rc = 0; + + if (unlikely(conn->suspend_rx)) { + debug_tcp("conn %d Rx suspended!\n", conn->id); + return 0; + } + + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER || + conn->in_progress == IN_PROGRESS_HEADER_GATHER) { + rc = iscsi_hdr_extract(conn); + if (rc) { + if (rc == -EAGAIN) + goto nomore; + else { + iscsi_conn_failure(conn, rc); + return 0; + } + } + + /* + * Verify and process incoming PDU header. + */ + rc = iscsi_hdr_recv(conn); + if (!rc && conn->in.datalen) { + if (conn->datadgst_en && + conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { + BUG_ON(!conn->data_rx_tfm); + crypto_digest_init(conn->data_rx_tfm); + } + conn->in_progress = IN_PROGRESS_DATA_RECV; + } else if (rc) { + iscsi_conn_failure(conn, rc); + return 0; + } + } + + if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { + debug_tcp("extra data_recv offset %d copy %d\n", + conn->in.offset, conn->in.copy); + if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { + uint32_t recv_digest; + skb_copy_bits(conn->in.skb, conn->in.offset, + &recv_digest, 4); + conn->in.offset += 4; + conn->in.copy -= 4; + if (recv_digest != conn->in.datadgst) { + debug_tcp("iscsi_tcp: data digest error!" + "0x%x != 0x%x\n", recv_digest, + conn->in.datadgst); + iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST); + return 0; + } else { + debug_tcp("iscsi_tcp: data digest match!" + "0x%x == 0x%x\n", recv_digest, + conn->in.datadgst); + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + } + } + + if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) { + + debug_tcp("data_recv offset %d copy %d\n", + conn->in.offset, conn->in.copy); + + rc = iscsi_data_recv(conn); + if (rc) { + if (rc == -EAGAIN) { + rd_desc->count = conn->in.datalen - + conn->in.ctask->data_count; + goto again; + } + iscsi_conn_failure(conn, rc); + return 0; + } + conn->in.copy -= conn->in.padding; + conn->in.offset += conn->in.padding; + if (conn->datadgst_en && + conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { + if (conn->in.padding) { + debug_tcp("padding -> %d\n", conn->in.padding); + memset(pad, 0, conn->in.padding); + sg_init_one(&sg, pad, conn->in.padding); + crypto_digest_update(conn->data_rx_tfm, &sg, 1); + } + crypto_digest_final(conn->data_rx_tfm, + (u8 *) & conn->in.datadgst); + debug_tcp("rx digest 0x%x\n", conn->in.datadgst); + conn->in_progress = IN_PROGRESS_DDIGEST_RECV; + } else + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + + debug_tcp("f, processed %d from out of %d padding %d\n", + conn->in.offset - offset, (int)len, conn->in.padding); + BUG_ON(conn->in.offset - offset > len); + + if (conn->in.offset - offset != len) { + debug_tcp("continue to process %d bytes\n", + (int)len - (conn->in.offset - offset)); + goto more; + } + +nomore: + processed = conn->in.offset - offset; + BUG_ON(processed == 0); + return processed; + +again: + processed = conn->in.offset - offset; + debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n", + processed, (int)len, (int)rd_desc->count); + BUG_ON(processed == 0); + BUG_ON(processed > len); + + conn->rxdata_octets += processed; + return processed; +} + +static void +iscsi_tcp_data_ready(struct sock *sk, int flag) +{ + struct iscsi_conn *conn = sk->sk_user_data; + read_descriptor_t rd_desc; + + read_lock(&sk->sk_callback_lock); + + /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */ + rd_desc.arg.data = conn; + rd_desc.count = 0; + tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv); + + read_unlock(&sk->sk_callback_lock); +} + +static void +iscsi_tcp_state_change(struct sock *sk) +{ + struct iscsi_conn *conn; + struct iscsi_session *session; + void (*old_state_change)(struct sock *); + + read_lock(&sk->sk_callback_lock); + + conn = (struct iscsi_conn*)sk->sk_user_data; + session = conn->session; + + if (sk->sk_state == TCP_CLOSE_WAIT || + sk->sk_state == TCP_CLOSE) { + debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n"); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + } + + old_state_change = conn->old_state_change; + + read_unlock(&sk->sk_callback_lock); + + old_state_change(sk); +} + +/** + * iscsi_write_space - Called when more output buffer space is available + * @sk: socket space is available for + **/ +static void +iscsi_write_space(struct sock *sk) +{ + struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data; + conn->old_write_space(sk); + debug_tcp("iscsi_write_space: cid %d\n", conn->id); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); + schedule_work(&conn->xmitwork); +} + +static void +iscsi_conn_set_callbacks(struct iscsi_conn *conn) +{ + struct sock *sk = conn->sock->sk; + + /* assign new callbacks */ + write_lock_bh(&sk->sk_callback_lock); + sk->sk_user_data = conn; + conn->old_data_ready = sk->sk_data_ready; + conn->old_state_change = sk->sk_state_change; + conn->old_write_space = sk->sk_write_space; + sk->sk_data_ready = iscsi_tcp_data_ready; + sk->sk_state_change = iscsi_tcp_state_change; + sk->sk_write_space = iscsi_write_space; + write_unlock_bh(&sk->sk_callback_lock); +} + +static void +iscsi_conn_restore_callbacks(struct iscsi_conn *conn) +{ + struct sock *sk = conn->sock->sk; + + /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ + write_lock_bh(&sk->sk_callback_lock); + sk->sk_user_data = NULL; + sk->sk_data_ready = conn->old_data_ready; + sk->sk_state_change = conn->old_state_change; + sk->sk_write_space = conn->old_write_space; + sk->sk_no_check = 0; + write_unlock_bh(&sk->sk_callback_lock); +} + +/** + * iscsi_send - generic send routine + * @sk: kernel's socket + * @buf: buffer to write from + * @size: actual size to write + * @flags: socket's flags + * + * Notes: + * depending on buffer will use tcp_sendpage() or tcp_sendmsg(). + * buf->sg.offset == -1 tells us that buffer is non S/G and forces + * to use tcp_sendmsg(). + */ +static inline int +iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags) +{ + int res; + + if ((int)buf->sg.offset >= 0) { + int offset = buf->sg.offset + buf->sent; + + /* tcp_sendpage */ + res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags); + } else { + struct msghdr msg; + + buf->iov.iov_base = iscsi_buf_iov_base(buf); + buf->iov.iov_len = size; + + memset(&msg, 0, sizeof(struct msghdr)); + + /* tcp_sendmsg */ + res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size); + } + + return res; +} + +/** + * iscsi_sendhdr - send PDU Header via tcp_sendpage() + * @conn: iscsi connection + * @buf: buffer to write from + * @datalen: lenght of data to be sent after the header + * + * Notes: + * (Tx, Fast Path) + **/ +static inline int +iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) +{ + struct socket *sk = conn->sock; + int flags = 0; /* MSG_DONTWAIT; */ + int res, size; + + size = buf->sg.length - buf->sent; + BUG_ON(buf->sent + size > buf->sg.length); + if (buf->sent + size != buf->sg.length || datalen) + flags |= MSG_MORE; + + res = iscsi_send(sk, buf, size, flags); + debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); + if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; + if (size != res) + return -EAGAIN; + return 0; + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + return res; +} + +/** + * iscsi_sendpage - send one page of iSCSI Data-Out. + * @conn: iscsi connection + * @buf: buffer to write from + * @count: remaining data + * @sent: number of bytes sent + * + * Notes: + * (Tx, Fast Path) + **/ +static inline int +iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, + int *count, int *sent) +{ + struct socket *sk = conn->sock; + int flags = 0; /* MSG_DONTWAIT; */ + int res, size; + + size = buf->sg.length - buf->sent; + BUG_ON(buf->sent + size > buf->sg.length); + if (size > *count) + size = *count; + if (buf->sent + size != buf->sg.length) + flags |= MSG_MORE; + + res = iscsi_send(sk, buf, size, flags); + debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", + size, buf->sent, *count, *sent, res); + if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; + *count -= res; + *sent += res; + if (size != res) + return -EAGAIN; + return 0; + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + return res; +} + +static inline void +iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + BUG_ON(!conn->data_tx_tfm); + crypto_digest_init(conn->data_tx_tfm); + ctask->digest_count = 4; +} + +static inline void +iscsi_buf_data_digest_update(struct iscsi_conn *conn, struct iscsi_buf *buf) +{ + struct scatterlist sg; + + if (buf->sg.offset != -1) + crypto_digest_update(conn->data_tx_tfm, &buf->sg, 1); + else { + sg_init_one(&sg, (char *)buf->sg.page, buf->sg.length); + crypto_digest_update(conn->data_tx_tfm, &sg, 1); + } +} + +static inline int +iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct iscsi_buf *buf, uint32_t *digest, int final) +{ + int rc = 0; + int sent = 0; + + if (final) + crypto_digest_final(conn->data_tx_tfm, (u8*)digest); + + iscsi_buf_init_virt(buf, (char*)digest, 4); + rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent); + if (rc) { + ctask->datadigest = *digest; + ctask->xmstate |= XMSTATE_DATA_DIGEST; + } else + ctask->digest_count = 4; + return rc; +} + +/** + * iscsi_solicit_data_cont - initialize next Data-Out + * @conn: iscsi connection + * @ctask: scsi command task + * @r2t: R2T info + * @left: bytes left to transfer + * + * Notes: + * Initialize next Data-Out within this R2T sequence and continue + * to process next Scatter-Gather element(if any) of this SCSI command. + * + * Called under connection lock. + **/ +static void +iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct iscsi_r2t_info *r2t, int left) +{ + struct iscsi_data *hdr; + struct iscsi_data_task *dtask; + struct scsi_cmnd *sc = ctask->sc; + int new_offset; + + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; + memset(hdr, 0, sizeof(struct iscsi_data)); + hdr->ttt = r2t->ttt; + hdr->datasn = cpu_to_be32(r2t->solicit_datasn); + r2t->solicit_datasn++; + hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; + hdr->exp_statsn = r2t->exp_statsn; + new_offset = r2t->data_offset + r2t->sent; + hdr->offset = cpu_to_be32(new_offset); + if (left > conn->max_xmit_dlength) { + hton24(hdr->dlength, conn->max_xmit_dlength); + r2t->data_count = conn->max_xmit_dlength; + } else { + hton24(hdr->dlength, left); + r2t->data_count = left; + hdr->flags = ISCSI_FLAG_CMD_FINAL; + } + conn->dataout_pdus_cnt++; + + iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr, + (u8 *)dtask->hdrext); + + r2t->dtask = dtask; + + if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { + BUG_ON(ctask->bad_sg == r2t->sg); + iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); + r2t->sg += 1; + } else + iscsi_buf_init_iov(&ctask->sendbuf, + (char*)sc->request_buffer + new_offset, + r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); +} + +static void +iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_data *hdr; + struct iscsi_data_task *dtask; + + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; + memset(hdr, 0, sizeof(struct iscsi_data)); + hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + hdr->datasn = cpu_to_be32(ctask->unsol_datasn); + ctask->unsol_datasn++; + hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; + hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); + hdr->offset = cpu_to_be32(ctask->total_length - + ctask->r2t_data_count - + ctask->unsol_count); + if (ctask->unsol_count > conn->max_xmit_dlength) { + hton24(hdr->dlength, conn->max_xmit_dlength); + ctask->data_count = conn->max_xmit_dlength; + hdr->flags = 0; + } else { + hton24(hdr->dlength, ctask->unsol_count); + ctask->data_count = ctask->unsol_count; + hdr->flags = ISCSI_FLAG_CMD_FINAL; + } + + iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)hdr, + (u8 *)dtask->hdrext); + + list_add(&dtask->item, &ctask->dataqueue); + + ctask->dtask = dtask; +} + +/** + * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands + * @conn: iscsi connection + * @ctask: scsi command task + * @sc: scsi command + **/ +static void +iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct scsi_cmnd *sc) +{ + struct iscsi_session *session = conn->session; + + BUG_ON(__kfifo_len(ctask->r2tqueue)); + + ctask->sc = sc; + ctask->conn = conn; + ctask->hdr.opcode = ISCSI_OP_SCSI_CMD; + ctask->hdr.flags = ISCSI_ATTR_SIMPLE; + int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun); + ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen); + ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; + ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn); + memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len); + memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); + + ctask->mtask = NULL; + ctask->sent = 0; + ctask->sg_count = 0; + + ctask->total_length = sc->request_bufflen; + + if (sc->sc_data_direction == DMA_TO_DEVICE) { + ctask->exp_r2tsn = 0; + ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE; + BUG_ON(ctask->total_length == 0); + if (sc->use_sg) { + struct scatterlist *sg = sc->request_buffer; + + iscsi_buf_init_sg(&ctask->sendbuf, + &sg[ctask->sg_count++]); + ctask->sg = sg; + ctask->bad_sg = sg + sc->use_sg; + } else { + iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer, + sc->request_bufflen); + } + + /* + * Write counters: + * + * imm_count bytes to be sent right after + * SCSI PDU Header + * + * unsol_count bytes(as Data-Out) to be sent + * without R2T ack right after + * immediate data + * + * r2t_data_count bytes to be sent via R2T ack's + * + * pad_count bytes to be sent as zero-padding + */ + ctask->imm_count = 0; + ctask->unsol_count = 0; + ctask->unsol_datasn = 0; + ctask->xmstate = XMSTATE_W_HDR; + /* calculate write padding */ + ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1); + if (ctask->pad_count) { + ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count; + debug_scsi("write padding %d bytes\n", + ctask->pad_count); + ctask->xmstate |= XMSTATE_W_PAD; + } + if (session->imm_data_en) { + if (ctask->total_length >= session->first_burst) + ctask->imm_count = min(session->first_burst, + conn->max_xmit_dlength); + else + ctask->imm_count = min(ctask->total_length, + conn->max_xmit_dlength); + hton24(ctask->hdr.dlength, ctask->imm_count); + ctask->xmstate |= XMSTATE_IMM_DATA; + } else + zero_data(ctask->hdr.dlength); + + if (!session->initial_r2t_en) + ctask->unsol_count = min(session->first_burst, + ctask->total_length) - ctask->imm_count; + if (!ctask->unsol_count) + /* No unsolicit Data-Out's */ + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + else + ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; + + ctask->r2t_data_count = ctask->total_length - + ctask->imm_count - + ctask->unsol_count; + + debug_scsi("cmd [itt %x total %d imm %d imm_data %d " + "r2t_data %d]\n", + ctask->itt, ctask->total_length, ctask->imm_count, + ctask->unsol_count, ctask->r2t_data_count); + } else { + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + if (sc->sc_data_direction == DMA_FROM_DEVICE) + ctask->hdr.flags |= ISCSI_FLAG_CMD_READ; + ctask->datasn = 0; + ctask->xmstate = XMSTATE_R_HDR; + zero_data(ctask->hdr.dlength); + } + + iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)&ctask->hdr, + (u8 *)ctask->hdrext); + conn->scsicmd_pdus_cnt++; +} + +/** + * iscsi_mtask_xmit - xmit management(immediate) task + * @conn: iscsi connection + * @mtask: task management task + * + * Notes: + * The function can return -EAGAIN in which case caller must + * call it again later, or recover. '0' return code means successful + * xmit. + * + * Management xmit state machine consists of two states: + * IN_PROGRESS_IMM_HEAD - PDU Header xmit in progress + * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress + **/ +static int +iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) +{ + + debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", + conn->id, mtask->xmstate, mtask->itt); + + if (mtask->xmstate & XMSTATE_IMM_HDR) { + mtask->xmstate &= ~XMSTATE_IMM_HDR; + if (mtask->data_count) + mtask->xmstate |= XMSTATE_IMM_DATA; + if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) { + mtask->xmstate |= XMSTATE_IMM_HDR; + if (mtask->data_count) + mtask->xmstate &= ~XMSTATE_IMM_DATA; + return -EAGAIN; + } + } + + if (mtask->xmstate & XMSTATE_IMM_DATA) { + BUG_ON(!mtask->data_count); + mtask->xmstate &= ~XMSTATE_IMM_DATA; + /* FIXME: implement. + * Virtual buffer could be spreaded across multiple pages... + */ + do { + if (iscsi_sendpage(conn, &mtask->sendbuf, + &mtask->data_count, &mtask->sent)) { + mtask->xmstate |= XMSTATE_IMM_DATA; + return -EAGAIN; + } + } while (mtask->data_count); + } + + BUG_ON(mtask->xmstate != XMSTATE_IDLE); + return 0; +} + +static inline int +handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + ctask->xmstate &= ~XMSTATE_R_HDR; + if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { + BUG_ON(ctask->xmstate != XMSTATE_IDLE); + return 0; /* wait for Data-In */ + } + ctask->xmstate |= XMSTATE_R_HDR; + return -EAGAIN; +} + +static inline int +handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + ctask->xmstate &= ~XMSTATE_W_HDR; + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { + ctask->xmstate |= XMSTATE_W_HDR; + return -EAGAIN; + } + return 0; +} + +static inline int +handle_xmstate_data_digest(struct iscsi_conn *conn, + struct iscsi_cmd_task *ctask) +{ + ctask->xmstate &= ~XMSTATE_DATA_DIGEST; + debug_tcp("resent data digest 0x%x\n", ctask->datadigest); + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->datadigest, 0)) { + ctask->xmstate |= XMSTATE_DATA_DIGEST; + debug_tcp("resent data digest 0x%x fail!\n", + ctask->datadigest); + return -EAGAIN; + } + return 0; +} + +static inline int +handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + BUG_ON(!ctask->imm_count); + ctask->xmstate &= ~XMSTATE_IMM_DATA; + + if (conn->datadgst_en) { + iscsi_data_digest_init(conn, ctask); + ctask->immdigest = 0; + } + + for (;;) { + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count, + &ctask->sent)) { + ctask->xmstate |= XMSTATE_IMM_DATA; + if (conn->datadgst_en) { + crypto_digest_final(conn->data_tx_tfm, + (u8*)&ctask->immdigest); + debug_tcp("tx imm sendpage fail 0x%x\n", + ctask->datadigest); + } + return -EAGAIN; + } + if (conn->datadgst_en) + iscsi_buf_data_digest_update(conn, &ctask->sendbuf); + + if (!ctask->imm_count) + break; + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); + } + + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { + debug_tcp("sending imm digest 0x%x fail!\n", + ctask->immdigest); + return -EAGAIN; + } + debug_tcp("sending imm digest 0x%x\n", ctask->immdigest); + } + + return 0; +} + +static inline int +handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_data_task *dtask; + + ctask->xmstate |= XMSTATE_UNS_DATA; + if (ctask->xmstate & XMSTATE_UNS_INIT) { + iscsi_unsolicit_data_init(conn, ctask); + BUG_ON(!ctask->dtask); + dtask = ctask->dtask; + + ctask->xmstate &= ~XMSTATE_UNS_INIT; + } + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) { + ctask->xmstate &= ~XMSTATE_UNS_DATA; + ctask->xmstate |= XMSTATE_UNS_HDR; + return -EAGAIN; + } + + debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", + ctask->itt, ctask->unsol_count, ctask->sent); + return 0; +} + +static inline int +handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_data_task *dtask = ctask->dtask; + + BUG_ON(!ctask->data_count); + ctask->xmstate &= ~XMSTATE_UNS_DATA; + + if (conn->datadgst_en) { + iscsi_data_digest_init(conn, ctask); + dtask->digest = 0; + } + + for (;;) { + int start = ctask->sent; + + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count, + &ctask->sent)) { + ctask->unsol_count -= ctask->sent - start; + ctask->xmstate |= XMSTATE_UNS_DATA; + /* will continue with this ctask later.. */ + if (conn->datadgst_en) { + crypto_digest_final(conn->data_tx_tfm, + (u8 *)&dtask->digest); + debug_tcp("tx uns data fail 0x%x\n", + dtask->digest); + } + return -EAGAIN; + } + + BUG_ON(ctask->sent > ctask->total_length); + ctask->unsol_count -= ctask->sent - start; + + /* + * XXX:we may run here with un-initial sendbuf. + * so pass it + */ + if (conn->datadgst_en && ctask->sent - start > 0) + iscsi_buf_data_digest_update(conn, &ctask->sendbuf); + + if (!ctask->data_count) + break; + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); + } + BUG_ON(ctask->unsol_count < 0); + + /* + * Done with the Data-Out. Next, check if we need + * to send another unsolicited Data-Out. + */ + if (ctask->unsol_count) { + if (conn->datadgst_en) { + if (iscsi_digest_final_send(conn, ctask, + &dtask->digestbuf, + &dtask->digest, 1)) { + debug_tcp("send uns digest 0x%x fail\n", + dtask->digest); + return -EAGAIN; + } + debug_tcp("sending uns digest 0x%x, more uns\n", + dtask->digest); + } + ctask->xmstate |= XMSTATE_UNS_INIT; + return 1; + } + + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, + &dtask->digestbuf, + &dtask->digest, 1)) { + debug_tcp("send last uns digest 0x%x fail\n", + dtask->digest); + return -EAGAIN; + } + debug_tcp("sending uns digest 0x%x\n",dtask->digest); + } + + return 0; +} + +static inline int +handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_session *session = conn->session; + struct iscsi_r2t_info *r2t = ctask->r2t; + struct iscsi_data_task *dtask = r2t->dtask; + int left; + + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->dtask = dtask; + + if (conn->datadgst_en) { + iscsi_data_digest_init(conn, ctask); + dtask->digest = 0; + } +solicit_again: + /* + * send Data-Out whitnin this R2T sequence. + */ + if (!r2t->data_count) + goto data_out_done; + + if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) { + ctask->xmstate |= XMSTATE_SOL_DATA; + /* will continue with this ctask later.. */ + if (conn->datadgst_en) { + crypto_digest_final(conn->data_tx_tfm, + (u8 *)&dtask->digest); + debug_tcp("r2t data send fail 0x%x\n", dtask->digest); + } + return -EAGAIN; + } + + BUG_ON(r2t->data_count < 0); + if (conn->datadgst_en) + iscsi_buf_data_digest_update(conn, &r2t->sendbuf); + + if (r2t->data_count) { + BUG_ON(ctask->sc->use_sg == 0); + if (!iscsi_buf_left(&r2t->sendbuf)) { + BUG_ON(ctask->bad_sg == r2t->sg); + iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); + r2t->sg += 1; + } + goto solicit_again; + } + +data_out_done: + /* + * Done with this Data-Out. Next, check if we have + * to send another Data-Out for this R2T. + */ + BUG_ON(r2t->data_length - r2t->sent < 0); + left = r2t->data_length - r2t->sent; + if (left) { + if (conn->datadgst_en) { + if (iscsi_digest_final_send(conn, ctask, + &dtask->digestbuf, + &dtask->digest, 1)) { + debug_tcp("send r2t data digest 0x%x" + "fail\n", dtask->digest); + return -EAGAIN; + } + debug_tcp("r2t data send digest 0x%x\n", + dtask->digest); + } + iscsi_solicit_data_cont(conn, ctask, r2t, left); + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; + return 1; + } + + /* + * Done with this R2T. Check if there are more + * outstanding R2Ts ready to be processed. + */ + BUG_ON(ctask->r2t_data_count - r2t->data_length < 0); + if (conn->datadgst_en) { + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, + &dtask->digest, 1)) { + debug_tcp("send last r2t data digest 0x%x" + "fail\n", dtask->digest); + return -EAGAIN; + } + debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); + } + + ctask->r2t_data_count -= r2t->data_length; + ctask->r2t = NULL; + spin_lock_bh(&session->lock); + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + spin_unlock_bh(&session->lock); + if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { + ctask->r2t = r2t; + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; + return 1; + } + + return 0; +} + +static inline int +handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_data_task *dtask = ctask->dtask; + int sent; + + ctask->xmstate &= ~XMSTATE_W_PAD; + iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad, + ctask->pad_count); + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) { + ctask->xmstate |= XMSTATE_W_PAD; + return -EAGAIN; + } + + if (conn->datadgst_en) { + iscsi_buf_data_digest_update(conn, &ctask->sendbuf); + /* imm data? */ + if (!dtask) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { + debug_tcp("send padding digest 0x%x" + "fail!\n", ctask->immdigest); + return -EAGAIN; + } + debug_tcp("done with padding, digest 0x%x\n", + ctask->datadigest); + } else { + if (iscsi_digest_final_send(conn, ctask, + &dtask->digestbuf, + &dtask->digest, 1)) { + debug_tcp("send padding digest 0x%x" + "fail\n", dtask->digest); + return -EAGAIN; + } + debug_tcp("done with padding, digest 0x%x\n", + dtask->digest); + } + } + + return 0; +} + +static int +iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + int rc = 0; + + debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n", + conn->id, ctask->xmstate, ctask->itt); + + /* + * serialize with TMF AbortTask + */ + if (ctask->mtask) + return rc; + + if (ctask->xmstate & XMSTATE_R_HDR) { + rc = handle_xmstate_r_hdr(conn, ctask); + return rc; + } + + if (ctask->xmstate & XMSTATE_W_HDR) { + rc = handle_xmstate_w_hdr(conn, ctask); + if (rc) + return rc; + } + + /* XXX: for data digest xmit recover */ + if (ctask->xmstate & XMSTATE_DATA_DIGEST) { + rc = handle_xmstate_data_digest(conn, ctask); + if (rc) + return rc; + } + + if (ctask->xmstate & XMSTATE_IMM_DATA) { + rc = handle_xmstate_imm_data(conn, ctask); + if (rc) + return rc; + } + + if (ctask->xmstate & XMSTATE_UNS_HDR) { + BUG_ON(!ctask->unsol_count); + ctask->xmstate &= ~XMSTATE_UNS_HDR; +unsolicit_head_again: + rc = handle_xmstate_uns_hdr(conn, ctask); + if (rc) + return rc; + } + + if (ctask->xmstate & XMSTATE_UNS_DATA) { + rc = handle_xmstate_uns_data(conn, ctask); + if (rc == 1) + goto unsolicit_head_again; + else if (rc) + return rc; + goto done; + } + + if (ctask->xmstate & XMSTATE_SOL_HDR) { + struct iscsi_r2t_info *r2t; + + ctask->xmstate &= ~XMSTATE_SOL_HDR; + ctask->xmstate |= XMSTATE_SOL_DATA; + if (!ctask->r2t) + __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t, + sizeof(void*)); +solicit_head_again: + r2t = ctask->r2t; + + if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->xmstate |= XMSTATE_SOL_HDR; + return -EAGAIN; + } + + debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n", + r2t->solicit_datasn - 1, ctask->itt, r2t->data_count, + r2t->sent); + } + + if (ctask->xmstate & XMSTATE_SOL_DATA) { + rc = handle_xmstate_sol_data(conn, ctask); + if (rc == 1) + goto solicit_head_again; + if (rc) + return rc; + } + +done: + /* + * Last thing to check is whether we need to send write + * padding. Note that we check for xmstate equality, not just the bit. + */ + if (ctask->xmstate == XMSTATE_W_PAD) + rc = handle_xmstate_w_pad(conn, ctask); + + return rc; +} + +/** + * iscsi_data_xmit - xmit any command into the scheduled connection + * @conn: iscsi connection + * + * Notes: + * The function can return -EAGAIN in which case the caller must + * re-schedule it again later or recover. '0' return code means + * successful xmit. + **/ +static int +iscsi_data_xmit(struct iscsi_conn *conn) +{ + if (unlikely(conn->suspend_tx)) { + debug_tcp("conn %d Tx suspended!\n", conn->id); + return 0; + } + + /* + * Transmit in the following order: + * + * 1) un-finished xmit (ctask or mtask) + * 2) immediate control PDUs + * 3) write data + * 4) SCSI commands + * 5) non-immediate control PDUs + * + * No need to lock around __kfifo_get as long as + * there's one producer and one consumer. + */ + + BUG_ON(conn->ctask && conn->mtask); + + if (conn->ctask) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + /* done with this in-progress ctask */ + conn->ctask = NULL; + } + if (conn->mtask) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + /* done with this in-progress mtask */ + conn->mtask = NULL; + } + + /* process immediate first */ + if (unlikely(__kfifo_len(conn->immqueue))) { + struct iscsi_session *session = conn->session; + while (__kfifo_get(conn->immqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + /* process write queue */ + while (__kfifo_get(conn->writequeue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + + /* process command queue */ + while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + /* done with this ctask */ + conn->ctask = NULL; + + /* process the rest control plane PDUs, if any */ + if (unlikely(__kfifo_len(conn->mgmtqueue))) { + struct iscsi_session *session = conn->session; + + while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + return 0; + +again: + if (unlikely(conn->suspend_tx)) + return 0; + + return -EAGAIN; +} + +static void +iscsi_xmitworker(void *data) +{ + struct iscsi_conn *conn = data; + + /* + * serialize Xmit worker on a per-connection basis. + */ + down(&conn->xmitsema); + if (iscsi_data_xmit(conn)) + schedule_work(&conn->xmitwork); + up(&conn->xmitsema); +} + +#define FAILURE_BAD_HOST 1 +#define FAILURE_SESSION_FAILED 2 +#define FAILURE_SESSION_FREED 3 +#define FAILURE_WINDOW_CLOSED 4 +#define FAILURE_SESSION_TERMINATE 5 + +static int +iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) +{ + struct Scsi_Host *host; + int reason = 0; + struct iscsi_session *session; + struct iscsi_conn *conn = NULL; + struct iscsi_cmd_task *ctask = NULL; + + sc->scsi_done = done; + sc->result = 0; + + host = sc->device->host; + session = iscsi_hostdata(host->hostdata); + BUG_ON(host != session->host); + + spin_lock(&session->lock); + + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_FAILED) { + reason = FAILURE_SESSION_FAILED; + goto reject; + } else if (session->state == ISCSI_STATE_TERMINATE) { + reason = FAILURE_SESSION_TERMINATE; + goto fault; + } + reason = FAILURE_SESSION_FREED; + goto fault; + } + + /* + * Check for iSCSI window and take care of CmdSN wrap-around + */ + if ((int)(session->max_cmdsn - session->cmdsn) < 0) { + reason = FAILURE_WINDOW_CLOSED; + goto reject; + } + + conn = session->leadconn; + + __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + BUG_ON(ctask->sc); + + sc->SCp.phase = session->age; + sc->SCp.ptr = (char*)ctask; + iscsi_cmd_init(conn, ctask, sc); + + __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); + debug_scsi( + "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", + sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", + conn->id, (long)sc, ctask->itt, sc->request_bufflen, + session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); + spin_unlock(&session->lock); + + if (!in_interrupt() && !down_trylock(&conn->xmitsema)) { + spin_unlock_irq(host->host_lock); + if (iscsi_data_xmit(conn)) + schedule_work(&conn->xmitwork); + up(&conn->xmitsema); + spin_lock_irq(host->host_lock); + } else + schedule_work(&conn->xmitwork); + + return 0; + +reject: + spin_unlock(&session->lock); + debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); + return SCSI_MLQUEUE_HOST_BUSY; + +fault: + spin_unlock(&session->lock); + printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n", + sc->cmnd[0], reason); + sc->sense_buffer[0] = 0x70; + sc->sense_buffer[2] = NOT_READY; + sc->sense_buffer[7] = 0x6; + sc->sense_buffer[12] = 0x08; + sc->sense_buffer[13] = 0x00; + sc->result = (DID_NO_CONNECT << 16); + sc->resid = sc->request_bufflen; + sc->scsi_done(sc); + return 0; +} + +static int +iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) +{ + int i; + + *items = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (*items == NULL) + return -ENOMEM; + + q->max = max; + q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (q->pool == NULL) { + kfree(*items); + return -ENOMEM; + } + + q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), + GFP_KERNEL, NULL); + if (q->queue == ERR_PTR(-ENOMEM)) { + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + + for (i = 0; i < max; i++) { + q->pool[i] = kmalloc(item_size, GFP_KERNEL); + if (q->pool[i] == NULL) { + int j; + + for (j = 0; j < i; j++) + kfree(q->pool[j]); + + kfifo_free(q->queue); + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + memset(q->pool[i], 0, item_size); + (*items)[i] = q->pool[i]; + __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); + } + return 0; +} + +static void +iscsi_pool_free(struct iscsi_queue *q, void **items) +{ + int i; + + for (i = 0; i < q->max; i++) + kfree(items[i]); + kfree(q->pool); + kfree(items); +} + +static iscsi_connh_t +iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) +{ + struct iscsi_session *session = iscsi_ptr(sessionh); + struct iscsi_conn *conn = NULL; + + conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL); + if (conn == NULL) + goto conn_alloc_fail; + memset(conn, 0, sizeof(struct iscsi_conn)); + + conn->c_stage = ISCSI_CONN_INITIAL_STAGE; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->id = conn_idx; + conn->exp_statsn = 0; + conn->tmabort_state = TMABORT_INITIAL; + + /* initial operational parameters */ + conn->hdr_size = sizeof(struct iscsi_hdr); + conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + + spin_lock_init(&conn->lock); + + /* initialize general xmit PDU commands queue */ + conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->xmitqueue == ERR_PTR(-ENOMEM)) + goto xmitqueue_alloc_fail; + + /* initialize write response PDU commands queue */ + conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->writequeue == ERR_PTR(-ENOMEM)) + goto writequeue_alloc_fail; + + /* initialize general immediate & non-immediate PDU commands queue */ + conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->immqueue == ERR_PTR(-ENOMEM)) + goto immqueue_alloc_fail; + + conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) + goto mgmtqueue_alloc_fail; + + INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); + + /* allocate login_mtask used for the login/text sequences */ + spin_lock_bh(&session->lock); + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&conn->login_mtask, + sizeof(void*))) { + spin_unlock_bh(&session->lock); + goto login_mtask_alloc_fail; + } + spin_unlock_bh(&session->lock); + + /* allocate initial PDU receive place holder */ + if (conn->data_size <= PAGE_SIZE) + conn->data = kmalloc(conn->data_size, GFP_KERNEL); + else + conn->data = (void*)__get_free_pages(GFP_KERNEL, + get_order(conn->data_size)); + if (!conn->data) + goto max_recv_dlenght_alloc_fail; + + init_timer(&conn->tmabort_timer); + init_MUTEX(&conn->xmitsema); + init_waitqueue_head(&conn->ehwait); + + return iscsi_handle(conn); + +max_recv_dlenght_alloc_fail: + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); +login_mtask_alloc_fail: + kfifo_free(conn->mgmtqueue); +mgmtqueue_alloc_fail: + kfifo_free(conn->immqueue); +immqueue_alloc_fail: + kfifo_free(conn->writequeue); +writequeue_alloc_fail: + kfifo_free(conn->xmitqueue); +xmitqueue_alloc_fail: + kfree(conn); +conn_alloc_fail: + return iscsi_handle(NULL); +} + +static void +iscsi_conn_destroy(iscsi_connh_t connh) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_session *session = conn->session; + + down(&conn->xmitsema); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) { + struct sock *sk = conn->sock->sk; + + /* + * conn_start() has never been called! + * need to cleanup the socket. + */ + write_lock_bh(&sk->sk_callback_lock); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&sk->sk_callback_lock); + + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + sock_release(conn->sock); + conn->sock = NULL; + } + + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; + if (session->leadconn == conn) { + /* + * leading connection? then give up on recovery. + */ + session->state = ISCSI_STATE_TERMINATE; + wake_up(&conn->ehwait); + } + spin_unlock_bh(&session->lock); + + up(&conn->xmitsema); + + /* + * Block until all in-progress commands for this connection + * time out or fail. + */ + for (;;) { + spin_lock_bh(&conn->lock); + if (!session->host->host_busy) { /* OK for ERL == 0 */ + spin_unlock_bh(&conn->lock); + break; + } + spin_unlock_bh(&conn->lock); + msleep_interruptible(500); + printk("conn_destroy(): host_busy %d host_failed %d\n", + session->host->host_busy, session->host->host_failed); + /* + * force eh_abort() to unblock + */ + wake_up(&conn->ehwait); + } + + /* now free crypto */ + if (conn->hdrdgst_en || conn->datadgst_en) { + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); + } + + /* free conn->data, size = MaxRecvDataSegmentLength */ + if (conn->data_size <= PAGE_SIZE) + kfree(conn->data); + else + free_pages((unsigned long)conn->data, + get_order(conn->data_size)); + + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + list_del(&conn->item); + if (list_empty(&session->connections)) + session->leadconn = NULL; + if (session->leadconn && session->leadconn == conn) + session->leadconn = container_of(session->connections.next, + struct iscsi_conn, item); + + if (session->leadconn == NULL) + /* none connections exits.. reset sequencing */ + session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; + spin_unlock_bh(&session->lock); + + kfifo_free(conn->xmitqueue); + kfifo_free(conn->writequeue); + kfifo_free(conn->immqueue); + kfifo_free(conn->mgmtqueue); + kfree(conn); +} + +static int +iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, + uint32_t transport_fd, int is_leading) +{ + struct iscsi_session *session = iscsi_ptr(sessionh); + struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh); + struct sock *sk; + struct socket *sock; + int err; + + /* lookup for existing socket */ + sock = sockfd_lookup(transport_fd, &err); + if (!sock) { + printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err); + return -EEXIST; + } + + /* lookup for existing connection */ + spin_lock_bh(&session->lock); + list_for_each_entry(tmp, &session->connections, item) { + if (tmp == conn) { + if (conn->c_stage != ISCSI_CONN_STOPPED || + conn->stop_stage == STOP_CONN_TERM) { + printk(KERN_ERR "iscsi_tcp: can't bind " + "non-stopped connection (%d:%d)\n", + conn->c_stage, conn->stop_stage); + spin_unlock_bh(&session->lock); + return -EIO; + } + break; + } + } + if (tmp != conn) { + /* bind new iSCSI connection to session */ + conn->session = session; + + list_add(&conn->item, &session->connections); + } + spin_unlock_bh(&session->lock); + + if (conn->stop_stage != STOP_CONN_SUSPEND) { + /* bind iSCSI connection and socket */ + conn->sock = sock; + + /* setup Socket parameters */ + sk = sock->sk; + sk->sk_reuse = 1; + sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ + sk->sk_allocation = GFP_ATOMIC; + + /* FIXME: disable Nagle's algorithm */ + + /* + * Intercept TCP callbacks for sendfile like receive + * processing. + */ + iscsi_conn_set_callbacks(conn); + + /* + * set receive state machine into initial state + */ + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + + if (is_leading) + session->leadconn = conn; + + /* + * Unblock xmitworker(), Login Phase will pass through. + */ + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); + + return 0; +} + +static int +iscsi_conn_start(iscsi_connh_t connh) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_session *session = conn->session; + struct sock *sk; + + /* FF phase warming up... */ + + if (session == NULL) { + printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n"); + return -EPERM; + } + + sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_STARTED; + session->state = ISCSI_STATE_LOGGED_IN; + + switch(conn->stop_stage) { + case STOP_CONN_RECOVER: + /* + * unblock eh_abort() if it is blocked. re-try all + * commands after successful recovery + */ + session->conn_cnt++; + conn->stop_stage = 0; + conn->tmabort_state = TMABORT_INITIAL; + session->age++; + wake_up(&conn->ehwait); + break; + case STOP_CONN_TERM: + session->conn_cnt++; + conn->stop_stage = 0; + break; + case STOP_CONN_SUSPEND: + conn->stop_stage = 0; + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); + break; + default: + break; + } + spin_unlock_bh(&session->lock); + write_unlock_bh(&sk->sk_callback_lock); + + return 0; +} + +static void +iscsi_conn_stop(iscsi_connh_t connh, int flag) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_session *session = conn->session; + struct sock *sk; + unsigned long flags; + + BUG_ON(!conn->sock); + sk = conn->sock->sk; + write_lock_bh(&sk->sk_callback_lock); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&sk->sk_callback_lock); + + down(&conn->xmitsema); + + spin_lock_irqsave(session->host->host_lock, flags); + spin_lock(&session->lock); + conn->stop_stage = flag; + conn->c_stage = ISCSI_CONN_STOPPED; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + + if (flag != STOP_CONN_SUSPEND) + session->conn_cnt--; + + if (session->conn_cnt == 0 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + + spin_unlock(&session->lock); + spin_unlock_irqrestore(session->host->host_lock, flags); + + if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) { + struct iscsi_cmd_task *ctask; + struct iscsi_mgmt_task *mtask; + + /* + * Socket must go now. + */ + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + + /* + * flush xmit queues. + */ + spin_lock_bh(&session->lock); + while (__kfifo_get(conn->writequeue, (void*)&ctask, + sizeof(void*)) || + __kfifo_get(conn->xmitqueue, (void*)&ctask, + sizeof(void*))) { + struct iscsi_r2t_info *r2t; + + /* + * flush ctask's r2t queues + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + + spin_unlock_bh(&session->lock); + local_bh_disable(); + iscsi_ctask_cleanup(conn, ctask); + local_bh_enable(); + spin_lock_bh(&session->lock); + } + conn->ctask = NULL; + while (__kfifo_get(conn->immqueue, (void*)&mtask, + sizeof(void*)) || + __kfifo_get(conn->mgmtqueue, (void*)&mtask, + sizeof(void*))) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + } + conn->mtask = NULL; + spin_unlock_bh(&session->lock); + + /* + * release socket only after we stopped data_xmit() + * activity and flushed all outstandings + */ + sock_release(conn->sock); + conn->sock = NULL; + + /* + * for connection level recovery we should not calculate + * header digest. conn->hdr_size used for optimization + * in hdr_extract() and will be re-negotiated at + * set_param() time. + */ + if (flag == STOP_CONN_RECOVER) + conn->hdr_size = sizeof(struct iscsi_hdr); + } + up(&conn->xmitsema); +} + +static int +iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) +{ + struct iscsi_session *session = conn->session; + struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; + struct iscsi_mgmt_task *mtask; + + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + return -EPERM; + } + if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || + hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + /* + * Login and Text are sent serially, in + * request-followed-by-response sequence. + * Same mtask can be used. Same ITT must be used. + * Note that login_mtask is preallocated at conn_create(). + */ + mtask = conn->login_mtask; + else { + BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); + BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); + + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*))) { + spin_unlock_bh(&session->lock); + return -ENOSPC; + } + } + + /* + * pre-format CmdSN and ExpStatSN for outgoing PDU. + */ + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + hdr->itt = mtask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + nop->cmdsn = cpu_to_be32(session->cmdsn); + if (conn->c_stage == ISCSI_CONN_STARTED && + !(hdr->opcode & ISCSI_OP_IMMEDIATE)) + session->cmdsn++; + } else + /* do not advance CmdSN */ + nop->cmdsn = cpu_to_be32(session->cmdsn); + + nop->exp_statsn = cpu_to_be32(conn->exp_statsn); + + memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr)); + + if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE || + conn->stop_stage == STOP_CONN_RECOVER) + iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr, + sizeof(struct iscsi_hdr)); + else + /* this will update header digest */ + iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr, + (u8 *)mtask->hdrext); + + spin_unlock_bh(&session->lock); + + if (data_size) { + memcpy(mtask->data, data, data_size); + mtask->data_count = data_size; + } else + mtask->data_count = 0; + + mtask->xmstate = XMSTATE_IMM_HDR; + + if (mtask->data_count) { + iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data, + mtask->data_count); + } + + debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", + hdr->opcode, hdr->itt, data_size); + + /* + * since send_pdu() could be called at least from two contexts, + * we need to serialize __kfifo_put, so we don't have to take + * additional lock on fast data-path + */ + if (hdr->opcode & ISCSI_OP_IMMEDIATE) + __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*)); + else + __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); + + schedule_work(&conn->xmitwork); + + return 0; +} + +static int +iscsi_eh_host_reset(struct scsi_cmnd *sc) +{ + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + debug_scsi("failing host reset: session terminated " + "[CID %d age %d]", conn->id, session->age); + spin_unlock_bh(&session->lock); + return FAILED; + } + spin_unlock_bh(&session->lock); + + debug_scsi("failing connection CID %d due to SCSI host reset " + "[itt 0x%x age %d]", conn->id, ctask->itt, + session->age); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + return SUCCESS; +} + +static void +iscsi_tmabort_timedout(unsigned long data) +{ + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&ctask->mtask, sizeof(void*)); + conn->tmabort_state = TMABORT_TIMEDOUT; + debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n", + (long)ctask->sc, ctask->itt); + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); +} + +static int +iscsi_eh_abort(struct scsi_cmnd *sc) +{ + int rc; + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + conn->eh_abort_cnt++; + debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + + /* + * two cases for ERL=0 here: + * + * 1) connection-level failure; + * 2) recovery due protocol error; + */ + down(&conn->xmitsema); + spin_lock_bh(&session->lock); + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + up(&conn->xmitsema); + goto failed; + } + spin_unlock_bh(&session->lock); + } else { + struct iscsi_tm *hdr = &conn->tmhdr; + + /* + * Still LOGGED_IN... + */ + + if (!ctask->sc || sc->SCp.phase != session->age) { + /* + * 1) ctask completed before time out. But session + * is still ok => Happy Retry. + * 2) session was re-open during time out of ctask. + */ + spin_unlock_bh(&session->lock); + up(&conn->xmitsema); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + + /* + * ctask timed out but session is OK + * ERL=0 requires task mgmt abort to be issued on each + * failed command. requests must be serialized. + */ + memset(hdr, 0, sizeof(struct iscsi_tm)); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; + hdr->flags = ISCSI_TM_FUNC_ABORT_TASK; + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->rtt = ctask->hdr.itt; + hdr->refcmdsn = ctask->hdr.cmdsn; + + rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr, + NULL, 0); + if (rc) { + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + debug_scsi("abort sent failure [itt 0x%x]", ctask->itt); + } else { + struct iscsi_r2t_info *r2t; + + /* + * TMF abort vs. TMF response race logic + */ + spin_lock_bh(&session->lock); + ctask->mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[(hdr->itt & ITT_MASK) - + ISCSI_MGMT_ITT_OFFSET]; + /* + * have to flush r2tqueue to avoid r2t leaks + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) { + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + } + if (conn->tmabort_state == TMABORT_INITIAL) { + conn->tmfcmd_pdus_cnt++; + conn->tmabort_timer.expires = 3*HZ + jiffies; + conn->tmabort_timer.function = + iscsi_tmabort_timedout; + conn->tmabort_timer.data = (unsigned long)ctask; + add_timer(&conn->tmabort_timer); + debug_scsi("abort sent [itt 0x%x]", ctask->itt); + } else { + if (!ctask->sc || + conn->tmabort_state == TMABORT_SUCCESS) { + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + up(&conn->xmitsema); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + } + spin_unlock_bh(&session->lock); + } + } + up(&conn->xmitsema); + + + /* + * block eh thread until: + * + * 1) abort response; + * 2) abort timeout; + * 3) session re-opened; + * 4) session terminated; + */ + for (;;) { + int p_state = session->state; + + rc = wait_event_interruptible(conn->ehwait, + (p_state == ISCSI_STATE_LOGGED_IN ? + (session->state == ISCSI_STATE_TERMINATE || + conn->tmabort_state != TMABORT_INITIAL) : + (session->state == ISCSI_STATE_TERMINATE || + session->state == ISCSI_STATE_LOGGED_IN))); + if (rc) { + /* shutdown.. */ + session->state = ISCSI_STATE_TERMINATE; + goto failed; + } + + if (signal_pending(current)) + flush_signals(current); + + if (session->state == ISCSI_STATE_TERMINATE) + goto failed; + + spin_lock_bh(&session->lock); + if (sc->SCp.phase == session->age && + (conn->tmabort_state == TMABORT_TIMEDOUT || + conn->tmabort_state == TMABORT_FAILED)) { + conn->tmabort_state = TMABORT_INITIAL; + if (!ctask->sc) { + /* + * ctask completed before tmf abort response or + * time out. + * But session is still ok => Happy Retry. + */ + spin_unlock_bh(&session->lock); + break; + } + spin_unlock_bh(&session->lock); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + continue; + } + spin_unlock_bh(&session->lock); + break; + } + +success: + debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = SUCCESS; + goto exit; + +failed: + debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = FAILED; + +exit: + del_timer_sync(&conn->tmabort_timer); + + down(&conn->xmitsema); + if (conn->sock) { + struct sock *sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + iscsi_ctask_cleanup(conn, ctask); + write_unlock_bh(&sk->sk_callback_lock); + } + up(&conn->xmitsema); + return rc; +} + +static int +iscsi_r2tpool_alloc(struct iscsi_session *session) +{ + int i; + int cmd_i; + + /* + * initialize per-task: R2T pool and xmit queue + */ + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { + struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; + + /* + * pre-allocated x4 as much r2ts to handle race when + * target acks DataOut faster than we data_xmit() queues + * could replenish r2tqueue. + */ + + /* R2T pool */ + if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4, + (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) { + goto r2t_alloc_fail; + } + + /* R2T xmit queue */ + ctask->r2tqueue = kfifo_alloc( + session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); + if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) { + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); + goto r2t_alloc_fail; + } + + /* + * number of + * Data-Out PDU's within R2T-sequence can be quite big; + * using mempool + */ + ctask->datapool = mempool_create(ISCSI_DTASK_DEFAULT_MAX, + mempool_alloc_slab, mempool_free_slab, taskcache); + if (ctask->datapool == NULL) { + kfifo_free(ctask->r2tqueue); + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); + goto r2t_alloc_fail; + } + INIT_LIST_HEAD(&ctask->dataqueue); + } + + return 0; + +r2t_alloc_fail: + for (i = 0; i < cmd_i; i++) { + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); + } + return -ENOMEM; +} + +static void +iscsi_r2tpool_free(struct iscsi_session *session) +{ + int i; + + for (i = 0; i < session->cmds_max; i++) { + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); + } +} + +static struct scsi_host_template iscsi_sht = { + .name = "iSCSI Initiator over TCP/IP, v." + ISCSI_VERSION_STR, + .queuecommand = iscsi_queuecommand, + .can_queue = ISCSI_XMIT_CMDS_MAX - 1, + .sg_tablesize = ISCSI_SG_TABLESIZE, + .cmd_per_lun = ISCSI_CMD_PER_LUN, + .eh_abort_handler = iscsi_eh_abort, + .eh_host_reset_handler = iscsi_eh_host_reset, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "iscsi_tcp", + .this_id = -1, +}; + +static iscsi_sessionh_t +iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) +{ + int cmd_i; + struct iscsi_session *session; + + session = iscsi_hostdata(host->hostdata); + memset(session, 0, sizeof(struct iscsi_session)); + + session->host = host; + session->id = host->host_no; + session->state = ISCSI_STATE_LOGGED_IN; + session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; + session->cmds_max = ISCSI_XMIT_CMDS_MAX; + session->cmdsn = initial_cmdsn; + session->exp_cmdsn = initial_cmdsn + 1; + session->max_cmdsn = initial_cmdsn + 1; + session->max_r2t = 1; + + /* initialize SCSI PDU commands pool */ + if (iscsi_pool_init(&session->cmdpool, session->cmds_max, + (void***)&session->cmds, sizeof(struct iscsi_cmd_task))) + goto cmdpool_alloc_fail; + + /* pre-format cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) + session->cmds[cmd_i]->itt = cmd_i; + + spin_lock_init(&session->lock); + INIT_LIST_HEAD(&session->connections); + + /* initialize immediate command pool */ + if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, + (void***)&session->mgmt_cmds, sizeof(struct iscsi_mgmt_task))) + goto mgmtpool_alloc_fail; + + + /* pre-format immediate cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { + session->mgmt_cmds[cmd_i]->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; + session->mgmt_cmds[cmd_i]->data = kmalloc( + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); + if (!session->mgmt_cmds[cmd_i]->data) { + int j; + + for (j = 0; j < cmd_i; j++) + kfree(session->mgmt_cmds[j]->data); + goto immdata_alloc_fail; + } + } + + if (iscsi_r2tpool_alloc(session)) + goto r2tpool_alloc_fail; + + return iscsi_handle(session); + +r2tpool_alloc_fail: + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); +immdata_alloc_fail: +mgmtpool_alloc_fail: + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); +cmdpool_alloc_fail: + return iscsi_handle(NULL); +} + +static void +iscsi_session_destroy(iscsi_sessionh_t sessionh) +{ + int cmd_i; + struct iscsi_data_task *dtask, *n; + struct iscsi_session *session = iscsi_ptr(sessionh); + + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { + struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } + } + + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); + + iscsi_r2tpool_free(session); + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); +} + +static int +iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, + uint32_t value) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_session *session = conn->session; + + spin_lock_bh(&session->lock); + if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && + conn->stop_stage != STOP_CONN_RECOVER) { + printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n", + param); + spin_unlock_bh(&session->lock); + return 0; + } + spin_unlock_bh(&session->lock); + + switch(param) { + case ISCSI_PARAM_MAX_RECV_DLENGTH: { + char *saveptr = conn->data; + int flags = GFP_KERNEL; + + if (conn->data_size >= value) { + conn->max_recv_dlength = value; + break; + } + + spin_lock_bh(&session->lock); + if (conn->stop_stage == STOP_CONN_RECOVER) + flags = GFP_ATOMIC; + spin_unlock_bh(&session->lock); + + if (value <= PAGE_SIZE) + conn->data = kmalloc(value, flags); + else + conn->data = (void*)__get_free_pages(flags, + get_order(value)); + if (conn->data == NULL) { + conn->data = saveptr; + return -ENOMEM; + } + if (conn->data_size <= PAGE_SIZE) + kfree(saveptr); + else + free_pages((unsigned long)saveptr, + get_order(conn->data_size)); + conn->max_recv_dlength = value; + conn->data_size = value; + } + break; + case ISCSI_PARAM_MAX_XMIT_DLENGTH: + conn->max_xmit_dlength = value; + break; + case ISCSI_PARAM_HDRDGST_EN: + conn->hdrdgst_en = value; + conn->hdr_size = sizeof(struct iscsi_hdr); + if (conn->hdrdgst_en) { + conn->hdr_size += sizeof(__u32); + if (!conn->tx_tfm) + conn->tx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->tx_tfm) + return -ENOMEM; + if (!conn->rx_tfm) + conn->rx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->rx_tfm) { + crypto_free_tfm(conn->tx_tfm); + return -ENOMEM; + } + } else { + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); + } + break; + case ISCSI_PARAM_DATADGST_EN: + conn->datadgst_en = value; + if (conn->datadgst_en) { + if (!conn->data_tx_tfm) + conn->data_tx_tfm = + crypto_alloc_tfm("crc32c", 0); + if (!conn->data_tx_tfm) + return -ENOMEM; + if (!conn->data_rx_tfm) + conn->data_rx_tfm = + crypto_alloc_tfm("crc32c", 0); + if (!conn->data_rx_tfm) { + crypto_free_tfm(conn->data_tx_tfm); + return -ENOMEM; + } + } else { + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); + } + break; + case ISCSI_PARAM_INITIAL_R2T_EN: + session->initial_r2t_en = value; + break; + case ISCSI_PARAM_MAX_R2T: + if (session->max_r2t == roundup_pow_of_two(value)) + break; + iscsi_r2tpool_free(session); + session->max_r2t = value; + if (session->max_r2t & (session->max_r2t - 1)) + session->max_r2t = roundup_pow_of_two(session->max_r2t); + if (iscsi_r2tpool_alloc(session)) + return -ENOMEM; + break; + case ISCSI_PARAM_IMM_DATA_EN: + session->imm_data_en = value; + break; + case ISCSI_PARAM_FIRST_BURST: + session->first_burst = value; + break; + case ISCSI_PARAM_MAX_BURST: + session->max_burst = value; + break; + case ISCSI_PARAM_PDU_INORDER_EN: + session->pdu_inorder_en = value; + break; + case ISCSI_PARAM_DATASEQ_INORDER_EN: + session->dataseq_inorder_en = value; + break; + case ISCSI_PARAM_ERL: + session->erl = value; + break; + case ISCSI_PARAM_IFMARKER_EN: + BUG_ON(value); + session->ifmarker_en = value; + break; + case ISCSI_PARAM_OFMARKER_EN: + BUG_ON(value); + session->ofmarker_en = value; + break; + default: + break; + } + + return 0; +} + +static int +iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, + uint32_t *value) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_session *session = conn->session; + + switch(param) { + case ISCSI_PARAM_MAX_RECV_DLENGTH: + *value = conn->max_recv_dlength; + break; + case ISCSI_PARAM_MAX_XMIT_DLENGTH: + *value = conn->max_xmit_dlength; + break; + case ISCSI_PARAM_HDRDGST_EN: + *value = conn->hdrdgst_en; + break; + case ISCSI_PARAM_DATADGST_EN: + *value = conn->datadgst_en; + break; + case ISCSI_PARAM_INITIAL_R2T_EN: + *value = session->initial_r2t_en; + break; + case ISCSI_PARAM_MAX_R2T: + *value = session->max_r2t; + break; + case ISCSI_PARAM_IMM_DATA_EN: + *value = session->imm_data_en; + break; + case ISCSI_PARAM_FIRST_BURST: + *value = session->first_burst; + break; + case ISCSI_PARAM_MAX_BURST: + *value = session->max_burst; + break; + case ISCSI_PARAM_PDU_INORDER_EN: + *value = session->pdu_inorder_en; + break; + case ISCSI_PARAM_DATASEQ_INORDER_EN: + *value = session->dataseq_inorder_en; + break; + case ISCSI_PARAM_ERL: + *value = session->erl; + break; + case ISCSI_PARAM_IFMARKER_EN: + *value = session->ifmarker_en; + break; + case ISCSI_PARAM_OFMARKER_EN: + *value = session->ofmarker_en; + break; + default: + return ISCSI_ERR_PARAM_NOT_FOUND; + } + + return 0; +} + +static void +iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + + stats->txdata_octets = conn->txdata_octets; + stats->rxdata_octets = conn->rxdata_octets; + stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; + stats->dataout_pdus = conn->dataout_pdus_cnt; + stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; + stats->datain_pdus = conn->datain_pdus_cnt; + stats->r2t_pdus = conn->r2t_pdus_cnt; + stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; + stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; + stats->custom_length = 3; + strcpy(stats->custom[0].desc, "tx_sendpage_failures"); + stats->custom[0].value = conn->sendpage_failures_cnt; + strcpy(stats->custom[1].desc, "rx_discontiguous_hdr"); + stats->custom[1].value = conn->discontiguous_hdr_cnt; + strcpy(stats->custom[2].desc, "eh_abort_cnt"); + stats->custom[2].value = conn->eh_abort_cnt; +} + +static int +iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data, + uint32_t data_size) +{ + struct iscsi_conn *conn = iscsi_ptr(connh); + int rc; + + down(&conn->xmitsema); + rc = iscsi_conn_send_generic(conn, hdr, data, data_size); + up(&conn->xmitsema); + + return rc; +} + +static struct iscsi_transport iscsi_tcp_transport = { + .owner = THIS_MODULE, + .name = "tcp", + .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST + | CAP_DATADGST, + .host_template = &iscsi_sht, + .hostdata_size = sizeof(struct iscsi_session), + .max_conn = 1, + .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, + .create_session = iscsi_session_create, + .destroy_session = iscsi_session_destroy, + .create_conn = iscsi_conn_create, + .bind_conn = iscsi_conn_bind, + .destroy_conn = iscsi_conn_destroy, + .set_param = iscsi_conn_set_param, + .get_param = iscsi_conn_get_param, + .start_conn = iscsi_conn_start, + .stop_conn = iscsi_conn_stop, + .send_pdu = iscsi_conn_send_pdu, + .get_stats = iscsi_conn_get_stats, +}; + +static int __init +iscsi_tcp_init(void) +{ + int error; + + if (iscsi_max_lun < 1) { + printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); + return -EINVAL; + } + iscsi_tcp_transport.max_lun = iscsi_max_lun; + + taskcache = kmem_cache_create("iscsi_taskcache", + sizeof(struct iscsi_data_task), 0, + SLAB_HWCACHE_ALIGN | SLAB_NO_REAP, NULL, NULL); + if (!taskcache) + return -ENOMEM; + + error = iscsi_register_transport(&iscsi_tcp_transport); + if (error) + kmem_cache_destroy(taskcache); + + return error; +} + +static void __exit +iscsi_tcp_exit(void) +{ + iscsi_unregister_transport(&iscsi_tcp_transport); + kmem_cache_destroy(taskcache); +} + +module_init(iscsi_tcp_init); +module_exit(iscsi_tcp_exit); From 20e007b8cc1266ff78810457d6e26c35c6b810ba Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 6 Aug 2005 11:50:03 -0500 Subject: [PATCH 0019/1940] [SCSI] iscsi: fix 64 bit compile warning drivers/scsi/scsi_transport_iscsi.c: In function `show_transport_handle': drivers/scsi/scsi_transport_iscsi.c:100: warning: long long unsigned int format, long unsigned int arg (arg 3) is caused because uint64_t is only unsigned long on a 64 bit platform. Fix this by casting to unsigned long long. Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 2effa1c33fb2..f189ce7541ff 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -97,7 +97,7 @@ static ssize_t show_transport_handle(struct class_device *cdev, char *buf) { struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); - return sprintf(buf, "%llu", iscsi_handle(priv->iscsi_transport)); + return sprintf(buf, "%llu", (unsigned long long)iscsi_handle(priv->iscsi_transport)); } static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); From 4a6d87f1db06c9670251d6c72a89319e7d1cbaee Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 13 Aug 2005 08:15:54 -0700 Subject: [PATCH 0020/1940] [CIFS] Add missing check for path name allocation failure. Remove four redundant null pointer checks before cifs_buf_release. Found by coverity analyzer. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifssmb.c | 24 +++++++++++------------- fs/cifs/dir.c | 6 +++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index e555cb5cf493..459320222cf7 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -415,15 +415,16 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if(server->secMode & SECMODE_SIGN_REQUIRED) cERROR(1, ("Server requires /proc/fs/cifs/PacketSigningEnabled")); - server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); + server->secMode &= ~(SECMODE_SIGN_ENABLED | + SECMODE_SIGN_REQUIRED); } else if(sign_CIFS_PDUs == 1) { if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) - server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); + server->secMode &= ~(SECMODE_SIGN_ENABLED | + SECMODE_SIGN_REQUIRED); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); return rc; } @@ -537,9 +538,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) rc = -ESHUTDOWN; } } - if (pSMB) - cifs_small_buf_release(pSMB); - up(&ses->sesSem); + up(&ses->sesSem) + cifs_small_buf_release(pSMB); /* if session dead then we do not need to do ulogoff, since server closed smb session, no sense reporting @@ -1796,8 +1796,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, } } qreparse_out: - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -2520,12 +2519,11 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ + if (rc) {/* BB add logic to retry regular search if Unix search + rejected unexpectedly by server */ /* BB Add code to handle unsupported level rc */ cFYI(1, ("Error in FindFirst = %d", rc)); - - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); /* BB eventually could optimize out free and realloc of buf */ /* for this case */ diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index c0f20fc09290..c619d45060ce 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -226,7 +226,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, } if (rc != 0) { - cFYI(1,("Create worked but get_inode_info failed with rc = %d", + cFYI(1, + ("Create worked but get_inode_info failed rc = %d", rc)); } else { direntry->d_op = &cifs_dentry_ops; @@ -303,8 +304,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev up(&direntry->d_sb->s_vfs_rename_sem); if(full_path == NULL) rc = -ENOMEM; - - if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) { + else if (pTcon->ses->capabilities & CAP_UNIX) { if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,(__u64)current->euid,(__u64)current->egid, From a59c658607b63ec7b6c2536597a075ee307b1b4c Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 17 Aug 2005 12:12:19 -0700 Subject: [PATCH 0021/1940] [CIFS] Missing ; from previous fix. Pointed out by Shaggy. Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 459320222cf7..1b073546f5d9 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -538,7 +538,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) rc = -ESHUTDOWN; } } - up(&ses->sesSem) + up(&ses->sesSem); cifs_small_buf_release(pSMB); /* if session dead then we do not need to do ulogoff, From 1982c344f1bf08118f7c224958b30c64e162009e Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 17 Aug 2005 12:38:22 -0700 Subject: [PATCH 0022/1940] [CIFS] Ensure that cifs multiplex ids do not collide. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsglob.h | 1 + fs/cifs/cifspdu.h | 19 +++++----- fs/cifs/cifsproto.h | 6 ++-- fs/cifs/cifssmb.c | 23 ++++++++----- fs/cifs/connect.c | 9 +++++ fs/cifs/misc.c | 84 +++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 113 insertions(+), 29 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index d3773e57acf9..e8287f76484f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -147,6 +147,7 @@ struct TCP_Server_Info { /* (returned on Negotiate */ int capabilities; /* allow selective disabling of caps by smb sess */ __u16 timeZone; + __u16 CurrentMid; /* multiplex id - rotating counter */ char cryptKey[CIFS_CRYPTO_KEY_SIZE]; char workstation_RFC1001_name[16]; /* 16th byte is always zero */ __u32 sequence_number; /* needed for CIFS PDU signature */ diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 3cef57b7a34f..49cc66825309 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1961,18 +1961,17 @@ struct data_blob { perhaps add a CreateDevice - to create Pipes and other special .inodes Also note POSIX open flags 2) Close - to return the last write time to do cache across close more safely - 3) PosixQFSInfo - to return statfs info - 4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes) - 5) Mkdir - set mode + 3) FindFirst return unique inode number - what about resume key, two + forms short (matches readdir) and full (enough info to cache inodes) + 4) Mkdir - set mode And under consideration: - 6) FindClose2 (return nanosecond timestamp ??) - 7) Use nanosecond timestamps throughout all time fields if + 5) FindClose2 (return nanosecond timestamp ??) + 6) Use nanosecond timestamps throughout all time fields if corresponding attribute flag is set - 8) sendfile - handle based copy - 9) Direct i/o - 10) "POSIX ACL" support - 11) Misc fcntls? + 7) sendfile - handle based copy + 8) Direct i/o + 9) Misc fcntls? what about fixing 64 bit alignment @@ -2028,7 +2027,7 @@ struct data_blob { */ -/* xsymlink is a symlink format that can be used +/* xsymlink is a symlink format (used by MacOS) that can be used to save symlink info in a regular file when mounted to operating systems that do not support the cifs Unix extensions or EAs (for xattr diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 66eaa6b40373..b9b13e3fe79d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -61,9 +61,9 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length, extern int cifs_inet_pton(int, char * source, void *dst); extern int map_smb_to_linux_error(struct smb_hdr *smb); extern void header_assemble(struct smb_hdr *, char /* command */ , - const struct cifsTconInfo *, int /* specifies length - of fixed section (word count) in two byte units */ - ); + const struct cifsTconInfo *, int /* length of + fixed section (word count) in two byte units */); +extern __u16 GetNextMid(struct TCP_Server_Info *server); extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *); extern void DeleteOplockQEntry(struct oplock_q_entry *); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1b073546f5d9..930be0927de2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -330,7 +330,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; - + pSMB->hdr.Mid = GetNextMid(server); pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; if (extended_security) pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; @@ -415,15 +415,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if(server->secMode & SECMODE_SIGN_REQUIRED) cERROR(1, ("Server requires /proc/fs/cifs/PacketSigningEnabled")); - server->secMode &= ~(SECMODE_SIGN_ENABLED | - SECMODE_SIGN_REQUIRED); + server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); } else if(sign_CIFS_PDUs == 1) { if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) - server->secMode &= ~(SECMODE_SIGN_ENABLED | - SECMODE_SIGN_REQUIRED); + server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); } } + cifs_buf_release(pSMB); return rc; } @@ -519,6 +518,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ if(ses->server) { + pSMB->hdr.Mid = GetNextMid(ses->server); + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; @@ -2519,11 +2520,12 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) {/* BB add logic to retry regular search if Unix search - rejected unexpectedly by server */ + if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ /* BB Add code to handle unsupported level rc */ cFYI(1, ("Error in FindFirst = %d", rc)); - cifs_buf_release(pSMB); + + if (pSMB) + cifs_buf_release(pSMB); /* BB eventually could optimize out free and realloc of buf */ /* for this case */ @@ -2857,7 +2859,10 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, (void **) &pSMBr); if (rc) return rc; - + + /* server pointer checked in called function, + but should never be null here anyway */ + pSMB->hdr.Mid = GetNextMid(ses->server); pSMB->hdr.Tid = ses->ipc_tid; pSMB->hdr.Uid = ses->Suid; if (ses->capabilities & CAP_STATUS32) { diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 36f78596c81a..9e8256003f73 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1857,6 +1857,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, NULL /* no tCon exists yet */ , 13 /* wct */ ); + smb_buffer->Mid = GetNextMid(ses->server); pSMB->req_no_secext.AndXCommand = 0xFF; pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); @@ -2132,6 +2133,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, /* send SMBsessionSetup here */ header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, NULL /* no tCon exists yet */ , 12 /* wct */ ); + + smb_buffer->Mid = GetNextMid(ses->server); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.AndXCommand = 0xFF; pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); @@ -2398,6 +2401,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, /* send SMBsessionSetup here */ header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, NULL /* no tCon exists yet */ , 12 /* wct */ ); + + smb_buffer->Mid = GetNextMid(ses->server); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); @@ -2740,6 +2745,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, /* send SMBsessionSetup here */ header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, NULL /* no tCon exists yet */ , 12 /* wct */ ); + + smb_buffer->Mid = GetNextMid(ses->server); pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.AndXCommand = 0xFF; @@ -3111,6 +3118,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, NULL /*no tid */ , 4 /*wct */ ); + + smb_buffer->Mid = GetNextMid(ses->server); smb_buffer->Uid = ses->Suid; pSMB = (TCONX_REQ *) smb_buffer; pSMBr = (TCONX_RSP *) smb_buffer_response; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 20ae4153f791..beeff8284169 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -34,8 +34,6 @@ extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern struct task_struct * oplockThread; -static __u16 GlobalMid; /* multiplex id - rotating counter */ - /* The xid serves as a useful identifier for each incoming vfs request, in a similar way to the mid which is useful to track each sent smb, and CurrentXid can also provide a running counter (although it @@ -51,6 +49,8 @@ _GetXid(void) GlobalTotalActiveXid++; if (GlobalTotalActiveXid > GlobalMaxActiveXid) GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ + if(GlobalTotalActiveXid > 65000) + cFYI(1,("warning: more than 65000 requests active")); xid = GlobalCurrentXid++; spin_unlock(&GlobalMid_Lock); return xid; @@ -218,6 +218,76 @@ cifs_small_buf_release(void *buf_to_free) return; } +/* + Find a free multiplex id (SMB mid). Otherwise there could be + mid collisions which might cause problems, demultiplexing the + wrong response to this request. Multiplex ids could collide if + one of a series requests takes much longer than the others, or + if a very large number of long lived requests (byte range + locks or FindNotify requests) are pending. No more than + 64K-1 requests can be outstanding at one time. If no + mids are available, return zero. A future optimization + could make the combination of mids and uid the key we use + to demultiplex on (rather than mid alone). + In addition to the above check, the cifs demultiplex + code already used the command code as a secondary + check of the frame and if signing is negotiated the + response would be discarded if the mid were the same + but the signature was wrong. Since the mid is not put in the + pending queue until later (when it is about to be dispatched) + we do have to limit the number of outstanding requests + to somewhat less than 64K-1 although it is hard to imagine + so many threads being in the vfs at one time. +*/ +__u16 GetNextMid(struct TCP_Server_Info *server) +{ + __u16 mid = 0; + __u16 last_mid; + int collision; + + if(server == NULL) + return mid; + + spin_lock(&GlobalMid_Lock); + last_mid = server->CurrentMid; /* we do not want to loop forever */ + server->CurrentMid++; + /* This nested loop looks more expensive than it is. + In practice the list of pending requests is short, + fewer than 50, and the mids are likely to be unique + on the first pass through the loop unless some request + takes longer than the 64 thousand requests before it + (and it would also have to have been a request that + did not time out) */ + while(server->CurrentMid != last_mid) { + struct list_head *tmp; + struct mid_q_entry *mid_entry; + + collision = 0; + if(server->CurrentMid == 0) + server->CurrentMid++; + + list_for_each(tmp, &server->pending_mid_q) { + mid_entry = list_entry(tmp, struct mid_q_entry, qhead); + + if ((mid_entry->mid == server->CurrentMid) && + (mid_entry->midState == MID_REQUEST_SUBMITTED)) { + /* This mid is in use, try a different one */ + collision = 1; + break; + } + } + if(collision == 0) { + mid = server->CurrentMid; + break; + } + server->CurrentMid++; + } + spin_unlock(&GlobalMid_Lock); + return mid; +} + +/* NB: MID can not be set if treeCon not passed in, in that + case it is responsbility of caller to set the mid */ void header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , const struct cifsTconInfo *treeCon, int word_count @@ -233,7 +303,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , (2 * word_count) + sizeof (struct smb_hdr) - 4 /* RFC 1001 length field does not count */ + 2 /* for bcc field itself */ ; - /* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */ + /* Note that this is the only network field that has to be converted + to big endian and it is done just before we send it */ buffer->Protocol[0] = 0xFF; buffer->Protocol[1] = 'S'; @@ -245,8 +316,6 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , buffer->Pid = cpu_to_le16((__u16)current->tgid); buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16)); spin_lock(&GlobalMid_Lock); - GlobalMid++; - buffer->Mid = GlobalMid; spin_unlock(&GlobalMid_Lock); if (treeCon) { buffer->Tid = treeCon->tid; @@ -256,8 +325,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , if (treeCon->ses->capabilities & CAP_STATUS32) { buffer->Flags2 |= SMBFLG2_ERR_STATUS; } - - buffer->Uid = treeCon->ses->Suid; /* always in LE format */ + /* Uid is not converted */ + buffer->Uid = treeCon->ses->Suid; + buffer->Mid = GetNextMid(treeCon->ses->server); if(multiuser_mount != 0) { /* For the multiuser case, there are few obvious technically */ /* possible mechanisms to match the local linux user (uid) */ From f191401f5906f4d942fac87ebeb4671faf1ba7d6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 18 Aug 2005 09:37:34 -0700 Subject: [PATCH 0023/1940] [CIFS] rmmod cifs can oops if done soon after the last cifs unmount Signed-off-by: Shaggy (shaggy@austin.ibm.com) Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsfs.c | 2 +- fs/cifs/connect.c | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8cc23e7d0d5d..7fda0f7d9c00 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -834,8 +834,8 @@ static int cifs_oplock_thread(void * dummyarg) spin_unlock(&GlobalMid_Lock); } } while(!signal_pending(current)); - complete_and_exit (&cifs_oplock_exited, 0); oplockThread = NULL; + complete_and_exit (&cifs_oplock_exited, 0); } static int __init diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9e8256003f73..ef0432c44482 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include "cifspdu.h" @@ -44,6 +45,8 @@ #define CIFS_PORT 445 #define RFC1001_PORT 139 +static DECLARE_COMPLETION(cifsd_complete); + extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, @@ -339,6 +342,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) atomic_inc(&tcpSesAllocCount); length = tcpSesAllocCount.counter; write_unlock(&GlobalSMBSeslock); + complete(&cifsd_complete); if(length > 1) { mempool_resize(cifs_req_poolp, length + cifs_min_rcv, @@ -676,7 +680,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) msleep(125); } - if (list_empty(&server->pending_mid_q)) { + if (!list_empty(&server->pending_mid_q)) { /* mpx threads have not exited yet give them at least the smb send timeout time for long ops */ /* due to delays on oplock break requests, we need @@ -713,7 +717,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) GFP_KERNEL); } - msleep(250); + complete_and_exit(&cifsd_complete, 0); return 0; } @@ -1617,8 +1621,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, kfree(volume_info.password); FreeXid(xid); return rc; - } else - rc = 0; + } + wait_for_completion(&cifsd_complete); + rc = 0; memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); srvTcp->sequence_number = 0; } @@ -1759,8 +1764,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, spin_lock(&GlobalMid_Lock); srvTcp->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); - if(srvTcp->tsk) + if(srvTcp->tsk) { send_sig(SIGKILL,srvTcp->tsk,1); + wait_for_completion(&cifsd_complete); + } } /* If find_unc succeeded then rc == 0 so we can not end */ if (tcon) /* up accidently freeing someone elses tcon struct */ @@ -1773,8 +1780,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, temp_rc = CIFSSMBLogoff(xid, pSesInfo); /* if the socketUseCount is now zero */ if((temp_rc == -ESHUTDOWN) && - (pSesInfo->server->tsk)) + (pSesInfo->server->tsk)) { send_sig(SIGKILL,pSesInfo->server->tsk,1); + wait_for_completion(&cifsd_complete); + } } else cFYI(1, ("No session or bad tcon")); sesInfoFree(pSesInfo); @@ -3241,8 +3250,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) return 0; } else if (rc == -ESHUTDOWN) { cFYI(1,("Waking up socket by sending it signal")); - if(cifsd_task) + if(cifsd_task) { send_sig(SIGKILL,cifsd_task,1); + wait_for_completion(&cifsd_complete); + } rc = 0; } /* else - we have an smb session left on this socket do not kill cifsd */ From 8d0d50948b276b46b75b1b5855d3f9fab1e0fd92 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 18 Aug 2005 09:41:43 -0700 Subject: [PATCH 0024/1940] [CIFS] Change Notify support part 1 - add dnotify thread for processing notify responses. Signed-off-by: Asser Ferno Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 7fda0f7d9c00..d77abe236a67 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0; unsigned int sign_CIFS_PDUs = 1; extern struct task_struct * oplockThread; /* remove sparse warning */ struct task_struct * oplockThread = NULL; +extern struct task_struct * dnotifyThread; /* remove sparse warning */ +struct task_struct * dnotifyThread = NULL; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; module_param(CIFSMaxBufSize, int, 0); MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); @@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0); MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); static DECLARE_COMPLETION(cifs_oplock_exited); +static DECLARE_COMPLETION(cifs_dnotify_exited); extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; @@ -838,6 +841,19 @@ static int cifs_oplock_thread(void * dummyarg) complete_and_exit (&cifs_oplock_exited, 0); } +static int cifs_dnotify_thread(void * dummyarg) +{ + daemonize("cifsdnotifyd"); + allow_signal(SIGTERM); + + dnotifyThread = current; + do { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(39*HZ); + } while(!signal_pending(current)); + complete_and_exit (&cifs_dnotify_exited, 0); +} + static int __init init_cifs(void) { @@ -884,10 +900,16 @@ init_cifs(void) if (!rc) { rc = (int)kernel_thread(cifs_oplock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_VM); - if(rc > 0) - return 0; - else + if(rc > 0) { + rc = (int)kernel_thread(cifs_dnotify_thread, NULL, + CLONE_FS | CLONE_FILES | CLONE_VM); + if(rc > 0) + return 0; + else + cERROR(1,("error %d create dnotify thread", rc)); + } else { cERROR(1,("error %d create oplock thread",rc)); + } } cifs_destroy_request_bufs(); } @@ -916,6 +938,10 @@ exit_cifs(void) send_sig(SIGTERM, oplockThread, 1); wait_for_completion(&cifs_oplock_exited); } + if(dnotifyThread) { + send_sig(SIGTERM, dnotifyThread, 1); + wait_for_completion(&cifs_dnotify_exited); + } } MODULE_AUTHOR("Steve French "); From c46fa8acdc533e8084359ea11c79d56eb98313fb Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 18 Aug 2005 20:49:57 -0700 Subject: [PATCH 0025/1940] [CIFS] Add mount option for disabling sending byte range lock requests over the wire (to help the case when applications break with cifs mandatory lock behavior. Add part one of mount option for requesting case insensitive path name matching. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 8 ++++++++ fs/cifs/README | 7 +++++++ fs/cifs/cifs_fs_sb.h | 2 ++ fs/cifs/cifsfs.h | 2 +- fs/cifs/connect.c | 14 +++++++++++++- fs/cifs/inode.c | 4 ++++ fs/cifs/readdir.c | 10 ++++------ 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 3196d4c4eed3..b0429ea524fb 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,11 @@ +Version 1.36 +------------ +Add mount option for disabling the default behavior of sending byte range lock +requests to the server (necessary for certain applications which break with +mandatory lock behavior such as Evolution), and also mount option for +requesting case insensitive matching for path based requests (requesting +case sensitive is the default). + Version 1.35 ------------ Add writepage performance improvements. Fix path name conversions diff --git a/fs/cifs/README b/fs/cifs/README index 34b0cf7111f3..3b610d08dc1e 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -407,6 +407,13 @@ A partial list of the supported mount options follows: This has no effect if the server does not support Unicode on the wire. nomapchars Do not translate any of these seven characters (default). + nocase Request case insensitive path name matching (case + sensitive is the default if the server suports it). + nobrl Do not send byte range lock requests to the server. + This is necessary for certain applications that break + with cifs style mandatory byte range locks (and most + cifs servers do not yet support requesting advisory + byte range locks). remount remount the share (often used to change from ro to rw mounts or vice versa) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 6b93587c490e..5fb695f1e50b 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -26,6 +26,8 @@ #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ +#define CIFS_MOUNT_CASE_INSENS 0x100 /* Request case insenstive searches */ +#define CIFS_MOUNT_NO_BRL 0x200 /* No sending byte range locks to srv */ struct cifs_sb_info { struct cifsTconInfo *tcon; /* primary mount */ diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 78af5850c558..cf45ca359dba 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -96,5 +96,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.35" +#define CIFS_VERSION "1.36" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ef0432c44482..6b21f6aa9f60 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -79,6 +79,8 @@ struct smb_vol { unsigned remap:1; /* set to remap seven reserved chars in filenames */ unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ unsigned sfu_emul:1; + unsigned nocase; /* request case insensitive filenames */ + unsigned nobrl; /* disable sending byte range locks to srv */ unsigned int rsize; unsigned int wsize; unsigned int sockopt; @@ -1040,6 +1042,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->posix_paths = 1; } else if (strnicmp(data, "noposixpaths", 12) == 0) { vol->posix_paths = 0; + } else if (strnicmp(data, "nocase", 6) == 0) { + vol->nocase = 1; + } else if (strnicmp(data, "brl", 3) == 0) { + vol->nobrl = 0; + } else if (strnicmp(data, "nobrl", 5) == 0) { + vol->nobrl = 1; } else if (strnicmp(data, "setuids", 7) == 0) { vol->setuids = 1; } else if (strnicmp(data, "nosetuids", 9) == 0) { @@ -1699,9 +1707,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; if(volume_info.sfu_emul) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; + if(volume_info.nocase) + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CASE_INSENS; + if(volume_info.nobrl) + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; if(volume_info.direct_io) { - cERROR(1,("mounting share using direct i/o")); + cFYI(1,("mounting share using direct i/o")); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 628aa1a9fe64..ed3e9207d92e 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -166,6 +166,8 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop->lock = NULL; inode->i_data.a_ops = &cifs_addr_ops; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode")); @@ -369,6 +371,8 @@ int cifs_get_inode_info(struct inode **pinode, inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop->lock = NULL; inode->i_data.a_ops = &cifs_addr_ops; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode ")); diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index dec3c9dd04d7..ef5eb804ce82 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -194,6 +194,8 @@ static void fill_in_inode(struct inode *tmp_inode, tmp_inode->i_fop = &cifs_file_direct_ops; else tmp_inode->i_fop = &cifs_file_ops; + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + tmp_inode->i_fop->lock = NULL; tmp_inode->i_data.a_ops = &cifs_addr_ops; if(isNewInode) @@ -298,6 +300,8 @@ static void unix_fill_in_inode(struct inode *tmp_inode, tmp_inode->i_fop = &cifs_file_direct_ops; else tmp_inode->i_fop = &cifs_file_ops; + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + tmp_inode->i_fop->lock = NULL; tmp_inode->i_data.a_ops = &cifs_addr_ops; if(isNewInode) @@ -557,7 +561,6 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + smbCalcSize((struct smb_hdr *) cifsFile->srch_inf.ntwrk_buf_start); -/* dump_cifs_file_struct(file,"found entry in fce "); */ first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.entries_in_buffer; pos_in_buf = index_to_find - first_entry_in_buffer; @@ -595,7 +598,6 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, *num_to_ret = 0; } else *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; -/* dump_cifs_file_struct(file, "end fce ");*/ return rc; } @@ -815,14 +817,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) FreeXid(xid); return -EIO; } -/* dump_cifs_file_struct(file, "Begin rdir "); */ cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; if(pTcon == NULL) return -EINVAL; -/* cFYI(1,("readdir2 pos: %lld",file->f_pos)); */ switch ((int) file->f_pos) { case 0: @@ -876,7 +876,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) cifsFile->search_resume_name = NULL; */ /* BB account for . and .. in f_pos as special case */ - /* dump_cifs_file_struct(file, "rdir after default ");*/ rc = find_cifs_entry(xid,pTcon, file, ¤t_entry,&num_to_fill); @@ -924,7 +923,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) } /* end switch */ rddir2_exit: - /* dump_cifs_file_struct(file, "end rdir "); */ FreeXid(xid); return rc; } From d3485d37c0b3292aec0618b6663c57542df5da99 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 19 Aug 2005 11:04:29 -0700 Subject: [PATCH 0026/1940] [CIFS] Finish cifs mount option which requests case insensitive path name matching. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_fs_sb.h | 3 +-- fs/cifs/cifsglob.h | 5 +++-- fs/cifs/connect.c | 9 +++++++-- fs/cifs/misc.c | 2 ++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 5fb695f1e50b..f799f6f0e729 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -26,8 +26,7 @@ #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ -#define CIFS_MOUNT_CASE_INSENS 0x100 /* Request case insenstive searches */ -#define CIFS_MOUNT_NO_BRL 0x200 /* No sending byte range locks to srv */ +#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ struct cifs_sb_info { struct cifsTconInfo *tcon; /* primary mount */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e8287f76484f..e7ba48c61a7a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -110,8 +110,8 @@ enum protocolEnum { */ struct TCP_Server_Info { - char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20'in 16th */ - char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; /* Unicode version of server_Name */ + char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20' 16th */ + char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; struct socket *ssocket; union { struct sockaddr_in sockAddr; @@ -231,6 +231,7 @@ struct cifsTconInfo { FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ FILE_SYSTEM_UNIX_INFO fsUnixInfo; unsigned retry:1; + unsigned nocase:1; /* BB add field for back pointer to sb struct? */ }; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6b21f6aa9f60..ac2c8bdc8e55 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1048,6 +1048,11 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->nobrl = 0; } else if (strnicmp(data, "nobrl", 5) == 0) { vol->nobrl = 1; + /* turn off mandatory locking in mode + if remote locking is turned off since the + local vfs will do advisory */ + if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP))) + vol->file_mode = S_IALLUGO; } else if (strnicmp(data, "setuids", 7) == 0) { vol->setuids = 1; } else if (strnicmp(data, "nosetuids", 9) == 0) { @@ -1707,8 +1712,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; if(volume_info.sfu_emul) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; - if(volume_info.nocase) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CASE_INSENS; if(volume_info.nobrl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; @@ -1727,6 +1730,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, to the same server share the last value passed in for the retry flag is used */ tcon->retry = volume_info.retry; + tcon->nocase = volume_info.nocase; } else { tcon = tconInfoAlloc(); if (tcon == NULL) @@ -1755,6 +1759,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, if (!rc) { atomic_inc(&pSesInfo->inUse); tcon->retry = volume_info.retry; + tcon->nocase = volume_info.nocase; } } } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index beeff8284169..40d50b77bfe7 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -375,6 +375,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , } if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) buffer->Flags2 |= SMBFLG2_DFS; + if (treeCon->nocase) + buffer->Flags |= SMBFLG_CASELESS; if((treeCon->ses) && (treeCon->ses->server)) if(treeCon->ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) From a5a2b489bae8f66559a531df99a26eb16b42299e Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 20 Aug 2005 21:42:53 -0700 Subject: [PATCH 0027/1940] [CIFS] Make CIFS statistics more accurate and add some stats that were missing. Most importantly SMB reads were undercounted. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_debug.c | 30 ++++++++++----- fs/cifs/cifsglob.h | 20 +++++++++- fs/cifs/cifssmb.c | 89 +++++++++++++++++++++++++------------------- fs/cifs/file.c | 5 --- fs/cifs/transport.c | 2 +- 5 files changed, 91 insertions(+), 55 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 838171328076..f4c6544468ab 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -254,36 +254,46 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, buf += sprintf(buf, "\tDISCONNECTED "); length += 14; } - item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d", + item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d", atomic_read(&tcon->num_smbs_sent), atomic_read(&tcon->num_oplock_brks)); buf += item_length; length += item_length; - item_length = sprintf(buf,"\nReads: %d Bytes %lld", + item_length = sprintf(buf, "\nReads: %d Bytes %lld", atomic_read(&tcon->num_reads), (long long)(tcon->bytes_read)); buf += item_length; length += item_length; - item_length = sprintf(buf,"\nWrites: %d Bytes: %lld", + item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", atomic_read(&tcon->num_writes), (long long)(tcon->bytes_written)); + buf += item_length; + length += item_length; + item_length = sprintf(buf, + "\nLocks: %d HardLinks: %d Symlinks: %d", + atomic_read(&tcon->num_locks), + atomic_read(&tcon->num_hardlinks), + atomic_read(&tcon->num_symlinks)); + buf += item_length; + length += item_length; + + item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", + atomic_read(&tcon->num_opens), + atomic_read(&tcon->num_closes), + atomic_read(&tcon->num_deletes)); buf += item_length; length += item_length; - item_length = sprintf(buf, - "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d", - atomic_read(&tcon->num_opens), - atomic_read(&tcon->num_deletes), + item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d", atomic_read(&tcon->num_mkdirs), atomic_read(&tcon->num_rmdirs)); buf += item_length; length += item_length; - item_length = sprintf(buf, - "\nRenames: %d T2 Renames %d", + item_length = sprintf(buf, "\nRenames: %d T2 Renames %d", atomic_read(&tcon->num_renames), atomic_read(&tcon->num_t2renames)); buf += item_length; length += item_length; - item_length = sprintf(buf,"\nFindFirst: %d FNext %d FClose %d", + item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d", atomic_read(&tcon->num_ffirst), atomic_read(&tcon->num_fnext), atomic_read(&tcon->num_fclose)); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e7ba48c61a7a..6a8c7d1bee8c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -215,6 +215,7 @@ struct cifsTconInfo { atomic_t num_reads; atomic_t num_oplock_brks; atomic_t num_opens; + atomic_t num_closes; atomic_t num_deletes; atomic_t num_mkdirs; atomic_t num_rmdirs; @@ -223,10 +224,27 @@ struct cifsTconInfo { atomic_t num_ffirst; atomic_t num_fnext; atomic_t num_fclose; + atomic_t num_hardlinks; + atomic_t num_symlinks; + atomic_t num_locks; +#ifdef CONFIG_CIFS_STATS2 + unsigned long long time_writes; + unsigned long long time_reads; + unsigned long long time_opens; + unsigned long long time_deletes; + unsigned long long time_closes; + unsigned long long time_mkdirs; + unsigned long long time_rmdirs; + unsigned long long time_renames; + unsigned long long time_t2renames; + unsigned long long time_ffirst; + unsigned long long time_fnext; + unsigned long long time_fclose; +#endif /* CONFIG_CIFS_STATS2 */ __u64 bytes_read; __u64 bytes_written; spinlock_t stat_lock; -#endif +#endif /* CONFIG_CIFS_STATS */ FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ FILE_SYSTEM_UNIX_INFO fsUnixInfo; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 930be0927de2..1292db50fe65 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -584,14 +584,12 @@ CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_deletes); +#endif if (rc) { cFYI(1, ("Error in RMFile = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - else { - atomic_inc(&tcon->num_deletes); - } -#endif cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -633,14 +631,12 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_rmdirs); +#endif if (rc) { cFYI(1, ("Error in RMDir = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - else { - atomic_inc(&tcon->num_rmdirs); - } -#endif cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -681,14 +677,13 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_mkdirs); +#endif if (rc) { cFYI(1, ("Error in Mkdir = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - else { - atomic_inc(&tcon->num_mkdirs); - } -#endif + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto MkDirRetry; @@ -772,6 +767,9 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, /* long_op set to 1 to allow for oplock break timeouts */ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 1); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_opens); +#endif if (rc) { cFYI(1, ("Error in Open = %d", rc)); } else { @@ -789,11 +787,8 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, pfile_info->EndOfFile = pSMBr->EndOfFile; pfile_info->NumberOfLinks = cpu_to_le32(1); } - -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_opens); -#endif } + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto openRetry; @@ -838,6 +833,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_reads); +#endif if (rc) { cERROR(1, ("Send error in read = %d", rc)); } else { @@ -940,6 +938,9 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, long_op); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_writes); +#endif if (rc) { cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; @@ -1012,6 +1013,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len, buf, bytes_sent, &bytes_returned, long_op); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_writes); +#endif if (rc) { cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; @@ -1087,7 +1091,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, timeout); - +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_locks); +#endif if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); } @@ -1121,6 +1127,9 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) pSMB->ByteCount = 0; rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_closes); +#endif if (rc) { if(rc!=-EINTR) { /* EINTR is expected when user ctl-c to kill app */ @@ -1193,16 +1202,13 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_renames); +#endif if (rc) { cFYI(1, ("Send error in rename = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - else { - atomic_inc(&tcon->num_renames); - } -#endif - cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -1277,14 +1283,13 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&pTcon->num_t2renames); +#endif if (rc) { cFYI(1,("Send error in Rename (by file handle) = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - else { - atomic_inc(&pTcon->num_t2renames); - } -#endif + cifs_buf_release(pSMB); /* Note: On -EAGAIN error only caller can retry on handle based calls @@ -1438,6 +1443,9 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_symlinks); +#endif if (rc) { cFYI(1, ("Send error in SetPathInfo (create symlink) = %d", @@ -1527,6 +1535,9 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_hardlinks); +#endif if (rc) { cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); } @@ -1597,6 +1608,9 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_hardlinks); +#endif if (rc) { cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); } @@ -2519,6 +2533,9 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_ffirst); +#endif if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ /* BB Add code to handle unsupported level rc */ @@ -2532,9 +2549,6 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, if (rc == -EAGAIN) goto findFirstRetry; } else { /* decode response */ -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_ffirst); -#endif /* BB remember to free buffer if error BB */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); if(rc == 0) { @@ -2643,7 +2657,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - +#ifdef CONFIG_CIFS_STATS + atomic_inc(&tcon->num_fnext); +#endif if (rc) { if (rc == -EBADF) { psrch_inf->endOfSearch = TRUE; @@ -2651,9 +2667,6 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, } else cFYI(1, ("FindNext returned = %d", rc)); } else { /* decode response */ -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_fnext); -#endif rc = validate_t2((struct smb_t2_rsp *)pSMBr); if(rc == 0) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ddb25a0a63d5..b054df2dee1e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -746,7 +746,6 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, #ifdef CONFIG_CIFS_STATS if (total_written > 0) { - atomic_inc(&pTcon->num_writes); spin_lock(&pTcon->stat_lock); pTcon->bytes_written += total_written; spin_unlock(&pTcon->stat_lock); @@ -881,7 +880,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data, #ifdef CONFIG_CIFS_STATS if (total_written > 0) { - atomic_inc(&pTcon->num_writes); spin_lock(&pTcon->stat_lock); pTcon->bytes_written += total_written; spin_unlock(&pTcon->stat_lock); @@ -1248,7 +1246,6 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, } } else { #ifdef CONFIG_CIFS_STATS - atomic_inc(&pTcon->num_reads); spin_lock(&pTcon->stat_lock); pTcon->bytes_read += total_read; spin_unlock(&pTcon->stat_lock); @@ -1316,7 +1313,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, } } else { #ifdef CONFIG_CIFS_STATS - atomic_inc(&pTcon->num_reads); spin_lock(&pTcon->stat_lock); pTcon->bytes_read += total_read; spin_unlock(&pTcon->stat_lock); @@ -1493,7 +1489,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, i += bytes_read >> PAGE_CACHE_SHIFT; #ifdef CONFIG_CIFS_STATS - atomic_inc(&pTcon->num_reads); spin_lock(&pTcon->stat_lock); pTcon->bytes_read += bytes_read; spin_unlock(&pTcon->stat_lock); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 496a2738bbe3..96f89eb66040 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -735,7 +735,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, BCC(out_buf) = le16_to_cpu(BCC(out_buf)); } else { rc = -EIO; - cFYI(1,("Bad MID state? ")); + cERROR(1,("Bad MID state? ")); } } cifs_no_response_exit: From b92327fe6b25d60004b79df9e3c19091c03118ba Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 22 Aug 2005 20:09:43 -0700 Subject: [PATCH 0028/1940] [CIFS] Finish up of case-insensitive dentry handling for cifs. This will eventually (or should eventually) be common code for jfs, smbfs, etc. but in the meantime is small enough and necessary when mounting case insensitive to Windows (nocase). Signed-off-by: Shaggy (shaggy@austin.ibm.com) Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsfs.h | 1 + fs/cifs/dir.c | 54 ++++++++++++++++++++++++++++++++++++++++++++--- fs/cifs/inode.c | 5 ++++- fs/cifs/link.c | 5 ++++- fs/cifs/readdir.c | 5 ++++- 5 files changed, 64 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index d5fb3441555f..bb3404a99e5f 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -81,6 +81,7 @@ extern int cifs_dir_notify(struct file *, unsigned long arg); /* Functions related to dir entries */ extern struct dentry_operations cifs_dentry_ops; +extern struct dentry_operations cifs_ci_dentry_ops; /* Functions related to symlinks */ extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index c619d45060ce..5311c50734b0 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -230,7 +230,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ("Create worked but get_inode_info failed rc = %d", rc)); } else { - direntry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + direntry->d_op = &cifs_ci_dentry_ops; + else + direntry->d_op = &cifs_dentry_ops; d_instantiate(direntry, newinode); } if((nd->flags & LOOKUP_OPEN) == FALSE) { @@ -322,7 +325,10 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev if(!rc) { rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,xid); - direntry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + direntry->d_op = &cifs_ci_dentry_ops; + else + direntry->d_op = &cifs_dentry_ops; if(rc == 0) d_instantiate(direntry, newinode); } @@ -418,7 +424,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name parent_dir_inode->i_sb,xid); if ((rc == 0) && (newInode != NULL)) { - direntry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + direntry->d_op = &cifs_ci_dentry_ops; + else + direntry->d_op = &cifs_dentry_ops; d_add(direntry, newInode); /* since paths are not looked up by component - the parent directories are presumed to be good here */ @@ -477,3 +486,42 @@ struct dentry_operations cifs_dentry_ops = { /* d_delete: cifs_d_delete, *//* not needed except for debugging */ /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */ }; + +static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) +{ + struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; + unsigned long hash; + int i; + + hash = init_name_hash(); + for (i = 0; i < q->len; i++) + hash = partial_name_hash(nls_tolower(codepage, q->name[i]), + hash); + q->hash = end_name_hash(hash); + + return 0; +} + +static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, + struct qstr *b) +{ + struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; + + if ((a->len == b->len) && + (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) { + /* + * To preserve case, don't let an existing negative dentry's + * case take precedence. If a is not a negative dentry, this + * should have no side effects + */ + memcpy((unsigned char *)a->name, b->name, a->len); + return 0; + } + return 1; +} + +struct dentry_operations cifs_ci_dentry_ops = { + .d_revalidate = cifs_d_revalidate, + .d_hash = cifs_ci_hash, + .d_compare = cifs_ci_compare, +}; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ed3e9207d92e..2d50b3507d13 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -591,7 +591,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) rc = cifs_get_inode_info(&newinode, full_path, NULL, inode->i_sb,xid); - direntry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + direntry->d_op = &cifs_ci_dentry_ops; + else + direntry->d_op = &cifs_dentry_ops; d_instantiate(direntry, newinode); if (direntry->d_inode) direntry->d_inode->i_nlink = 2; diff --git a/fs/cifs/link.c b/fs/cifs/link.c index da420e8c3298..b8ec6646456a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -199,7 +199,10 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) ("Create symlink worked but get_inode_info failed with rc = %d ", rc)); } else { - direntry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + direntry->d_op = &cifs_ci_dentry_ops; + else + direntry->d_op = &cifs_dentry_ops; d_instantiate(direntry, newinode); } } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index ef5eb804ce82..f769292e2a93 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -91,7 +91,10 @@ static int construct_dentry(struct qstr *qstring, struct file *file, } *ptmp_inode = new_inode(file->f_dentry->d_sb); - tmp_dentry->d_op = &cifs_dentry_ops; + if (pTcon->nocase) + tmp_dentry->d_op = &cifs_ci_dentry_ops; + else + tmp_dentry->d_op = &cifs_dentry_ops; if(*ptmp_inode == NULL) return rc; rc = 1; From a10faeb2a3e266385cc334fe9af76e08e5e4330f Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 22 Aug 2005 21:38:31 -0700 Subject: [PATCH 0029/1940] [CIFS] Support for mounting to older, pre-CIFS servers added. This allows specifying an RFC1001 target "called" name (netbios name of the server, which can now be pecified as mount option "servernetbiosname" but will eventually be passed in automatically on retry of host down error messages caused when server refuses to handle default server name and can not handle port 445). This is an important step, but additional testing and fixup is needed to add remaining function needed for these. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 7 +++++- fs/cifs/cifsglob.h | 6 +++-- fs/cifs/connect.c | 57 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index b0429ea524fb..2137002aecc4 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,5 +1,6 @@ Version 1.36 ------------ +Add support for moounting to older pre-CIFS servers such as Windows9x and ME. Add mount option for disabling the default behavior of sending byte range lock requests to the server (necessary for certain applications which break with mandatory lock behavior such as Evolution), and also mount option for @@ -10,7 +11,11 @@ Version 1.35 ------------ Add writepage performance improvements. Fix path name conversions for long filenames on mounts which were done with "mapchars" mount option -specified. +specified. Ensure multiplex ids do not collide. Fix case in which +rmmod can oops if done soon after last unmount. Fix truncated +search (readdir) output when resume filename was a long filename. +Fix filename conversion when mapchars mount option was specified and +filename was a long filename. Version 1.34 ------------ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 6a8c7d1bee8c..f143975627e0 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -110,7 +110,8 @@ enum protocolEnum { */ struct TCP_Server_Info { - char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20' 16th */ + /* 15 character server name + 0x20 16th byte indicating type = srv */ + char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; struct socket *ssocket; union { @@ -149,7 +150,8 @@ struct TCP_Server_Info { __u16 timeZone; __u16 CurrentMid; /* multiplex id - rotating counter */ char cryptKey[CIFS_CRYPTO_KEY_SIZE]; - char workstation_RFC1001_name[16]; /* 16th byte is always zero */ + /* 16th byte of RFC1001 workstation name is always null */ + char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* needed for CIFS PDU signature */ char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; }; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ac2c8bdc8e55..9d61844e89b6 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -63,6 +63,7 @@ struct smb_vol { char *in6_addr; /* ipv6 address as human readable form of in6_addr */ char *iocharset; /* local code page for mapping to and from Unicode */ char source_rfc1001_name[16]; /* netbios name of client */ + char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ uid_t linux_uid; gid_t linux_gid; mode_t file_mode; @@ -89,7 +90,8 @@ struct smb_vol { static int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, - char * netb_name); + char * netb_name, + char * server_netb_name); static int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket); @@ -182,7 +184,8 @@ cifs_reconnect(struct TCP_Server_Info *server) } else { rc = ipv4_connect(&server->addr.sockAddr, &server->ssocket, - server->workstation_RFC1001_name); + server->workstation_RFC1001_name, + server->server_RFC1001_name); } if(rc) { msleep(3000); @@ -743,7 +746,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) toupper(system_utsname.nodename[i]); } vol->source_rfc1001_name[15] = 0; - + /* null target name indicates to use *SMBSERVR default called name + if we end up sending RFC1001 session initialize */ + vol->target_rfc1001_name[0] = 0; vol->linux_uid = current->uid; /* current->euid instead? */ vol->linux_gid = current->gid; vol->dir_mode = S_IRWXUGO; @@ -996,7 +1001,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) /* The string has 16th byte zero still from set at top of the function */ if((i==15) && (value[i] != 0)) - printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n"); + printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); + } + } else if (strnicmp(data, "servern", 7) == 0) { + /* servernetbiosname specified override *SMBSERVER */ + if (!value || !*value || (*value == ' ')) { + cFYI(1,("empty server netbiosname specified")); + } else { + /* last byte, type, is 0x20 for servr type */ + memset(vol->target_rfc1001_name,0x20,16); + + for(i=0;i<15;i++) { + /* BB are there cases in which a comma can be + valid in this workstation netbios name (and need + special handling)? */ + + /* user or mount helper must uppercase netbiosname */ + if (value[i]==0) + break; + else + vol->target_rfc1001_name[i] = value[i]; + } + /* The string has 16th byte zero still from + set at top of the function */ + if((i==15) && (value[i] != 0)) + printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); } } else if (strnicmp(data, "credentials", 4) == 0) { /* ignore */ @@ -1042,7 +1071,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->posix_paths = 1; } else if (strnicmp(data, "noposixpaths", 12) == 0) { vol->posix_paths = 0; - } else if (strnicmp(data, "nocase", 6) == 0) { + } else if ((strnicmp(data, "nocase", 6) == 0) || + (strnicmp(data, "ignorecase", 10) == 0)) { vol->nocase = 1; } else if (strnicmp(data, "brl", 3) == 0) { vol->nobrl = 0; @@ -1272,7 +1302,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length) static int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, - char * netbios_name) + char * netbios_name, char * target_name) { int rc = 0; int connected = 0; @@ -1350,8 +1380,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL); if(ses_init_buf) { ses_init_buf->trailer.session_req.called_len = 32; - rfc1002mangle(ses_init_buf->trailer.session_req.called_name, - DEFAULT_CIFS_CALLED_NAME,16); + if(target_name && (target_name[0] != 0)) { + rfc1002mangle(ses_init_buf->trailer.session_req.called_name, + target_name, 16); + } else { + rfc1002mangle(ses_init_buf->trailer.session_req.called_name, + DEFAULT_CIFS_CALLED_NAME,16); + } + ses_init_buf->trailer.session_req.calling_len = 32; /* calling name ends in null (byte 16) from old smb convention. */ @@ -1584,7 +1620,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, sin_server.sin_port = htons(volume_info.port); else sin_server.sin_port = 0; - rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name); + rc = ipv4_connect(&sin_server,&csocket, + volume_info.source_rfc1001_name, + volume_info.target_rfc1001_name); if (rc < 0) { cERROR(1, ("Error connecting to IPv4 socket. Aborting operation")); @@ -1638,6 +1676,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, wait_for_completion(&cifsd_complete); rc = 0; memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); + memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16); srvTcp->sequence_number = 0; } } From 6b8edfe0f918e7585acb3bd63f62ff56e32dd3d2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 23 Aug 2005 20:26:03 -0700 Subject: [PATCH 0030/1940] [CIFS] Support for mounting to older servers part 2. Add support for legacy getattr (lookup). Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 2 ++ fs/cifs/cifspdu.h | 17 +++++++++++++ fs/cifs/cifsproto.h | 4 +++ fs/cifs/cifssmb.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/connect.c | 5 ++-- fs/cifs/inode.c | 12 ++++++++- 6 files changed, 96 insertions(+), 3 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 2137002aecc4..299ed312cea5 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,6 +1,8 @@ Version 1.36 ------------ Add support for moounting to older pre-CIFS servers such as Windows9x and ME. +For these older servers, add option for passing netbios name of server in +on mount (servernetbiosname). Add mount option for disabling the default behavior of sending byte range lock requests to the server (necessary for certain applications which break with mandatory lock behavior such as Evolution), and also mount option for diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 49cc66825309..42c16cf32284 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -36,6 +36,7 @@ #define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */ #define SMB_COM_DELETE 0x06 /* trivial response */ #define SMB_COM_RENAME 0x07 /* trivial response */ +#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */ #define SMB_COM_SETATTR 0x09 /* trivial response */ #define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */ #define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/ @@ -885,6 +886,22 @@ typedef struct smb_com_create_directory_rsp { __u16 ByteCount; /* bct = 0 */ } CREATE_DIRECTORY_RSP; +typedef struct smb_com_query_information_req { + struct smb_hdr hdr; /* wct = 0 */ + __le16 ByteCount; /* 1 + namelen + 1 */ + __u8 BufferFormat; /* 4 = ASCII */ + unsigned char FileName[1]; +} QUERY_INFORMATION_REQ; + +typedef struct smb_com_query_information_rsp { + struct smb_hdr hdr; /* wct = 10 */ + __le16 attr; + __le32 last_write_time; + __le32 size; + __u16 reserved[5]; + __le16 ByteCount; /* bcc = 0 */ +} QUERY_INFORMATION_RSP; + typedef struct smb_com_setattr_req { struct smb_hdr hdr; /* wct = 8 */ __le16 attr; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index b9b13e3fe79d..0cc0612eacb4 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -105,6 +105,10 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO * findData, const struct nls_table *nls_codepage, int remap); +extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + FILE_ALL_INFO * findData, + const struct nls_table *nls_codepage, int remap); extern int CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1292db50fe65..811ab3dffafa 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2200,6 +2200,65 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, #endif /* CONFIG_POSIX */ +/* Legacy Query Path Information call for lookup to old servers such + as Win9x/WinME */ +int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + FILE_ALL_INFO * pFinfo, + const struct nls_table *nls_codepage, int remap) +{ + QUERY_INFORMATION_REQ * pSMB; + QUERY_INFORMATION_RSP * pSMBr; + int rc = 0; + int bytes_returned; + int name_len; + + cFYI(1, ("In SMBQPath path %s", searchName)); +QInfRetry: + rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { + name_len = + cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, + PATH_MAX, nls_codepage, remap); + name_len++; /* trailing null */ + name_len *= 2; + } else { + name_len = strnlen(searchName, PATH_MAX); + name_len++; /* trailing null */ + strncpy(pSMB->FileName, searchName, name_len); + } + pSMB->BufferFormat = 0x04; + name_len++; /* account for buffer type byte */ + pSMB->hdr.smb_buf_length += (__u16) name_len; + pSMB->ByteCount = cpu_to_le16(name_len); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QueryInfo = %d", rc)); + } else if (pFinfo) { /* decode response */ + memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); + pFinfo->AllocationSize = (__le64) pSMBr->size; + pFinfo->EndOfFile = (__le64) pSMBr->size; + pFinfo->Attributes = (__le32) pSMBr->attr; + } else + rc = -EIO; /* bad buffer passed in */ + + cifs_buf_release(pSMB); + + if (rc == -EAGAIN) + goto QInfRetry; + + return rc; +} + + + + int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9d61844e89b6..c75bae1242dc 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1730,8 +1730,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, else cifs_sb->wsize = CIFSMaxBufSize; /* default */ if(cifs_sb->rsize < PAGE_CACHE_SIZE) { - cifs_sb->rsize = PAGE_CACHE_SIZE; - cERROR(1,("Attempt to set readsize for mount to less than one page (4096)")); + cifs_sb->rsize = PAGE_CACHE_SIZE; + /* Windows ME does this */ + cFYI(1,("Attempt to set readsize for mount to less than one page (4096)")); } cifs_sb->mnt_uid = volume_info.linux_uid; cifs_sb->mnt_gid = volume_info.linux_gid; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 2d50b3507d13..34f0168c4041 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -215,8 +215,18 @@ int cifs_get_inode_info(struct inode **pinode, pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + /* BB optimize code so we do not make the above call + when server claims no NT SMB support and the above call + failed at least once - set flag in tcon or mount */ + if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { + rc = SMBQueryInformation(xid, pTcon, search_path, + pfindData, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + } + } /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ if (rc) { From a45443475835ab4d1c753159812aca21b5c333a3 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 13:59:35 -0700 Subject: [PATCH 0031/1940] CIFS: Reduce CONFIG_CIFS_STATS ifdefs Make cifs_stats code conditional in the header files to avoid ifdefs in the main code. Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 28 +++++++++++++++ fs/cifs/cifssmb.c | 88 +++++++++++++--------------------------------- fs/cifs/file.c | 34 +++--------------- fs/cifs/misc.c | 4 +-- 4 files changed, 58 insertions(+), 96 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f143975627e0..9a3c85bdd77e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -339,6 +339,34 @@ static inline const char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) return '\\'; } +#ifdef CONFIG_CIFS_STATS +#define cifs_stats_inc atomic_inc + +static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon, + unsigned int bytes) +{ + if (bytes) { + spin_lock(&tcon->stat_lock); + tcon->bytes_written += bytes; + spin_unlock(&tcon->stat_lock); + } +} + +static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon, + unsigned int bytes) +{ + spin_lock(&tcon->stat_lock); + tcon->bytes_read += bytes; + spin_unlock(&tcon->stat_lock); +} +#else + +#define cifs_stats_inc(field) do {} while(0) +#define cifs_stats_bytes_written(tcon, bytes) do {} while(0) +#define cifs_stats_bytes_read(tcon, bytes) do {} while(0) + +#endif + /* one of these for every pending CIFS request to the server */ struct mid_q_entry { struct list_head qhead; /* mids waiting on reply from this server */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 811ab3dffafa..698cdcebca04 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -166,11 +166,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); -#ifdef CONFIG_CIFS_STATS - if(tcon != NULL) { - atomic_inc(&tcon->num_smbs_sent); - } -#endif /* CONFIG_CIFS_STATS */ + if(tcon != NULL) + cifs_stats_inc(&tcon->num_smbs_sent); + return rc; } @@ -269,11 +267,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, wct /*wct */ ); -#ifdef CONFIG_CIFS_STATS - if(tcon != NULL) { - atomic_inc(&tcon->num_smbs_sent); - } -#endif /* CONFIG_CIFS_STATS */ + if(tcon != NULL) + cifs_stats_inc(&tcon->num_smbs_sent); + return rc; } @@ -584,9 +580,7 @@ CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_deletes); -#endif + cifs_stats_inc(&tcon->num_deletes); if (rc) { cFYI(1, ("Error in RMFile = %d", rc)); } @@ -631,9 +625,7 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_rmdirs); -#endif + cifs_stats_inc(&tcon->num_rmdirs); if (rc) { cFYI(1, ("Error in RMDir = %d", rc)); } @@ -677,9 +669,7 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_mkdirs); -#endif + cifs_stats_inc(&tcon->num_mkdirs); if (rc) { cFYI(1, ("Error in Mkdir = %d", rc)); } @@ -767,9 +757,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, /* long_op set to 1 to allow for oplock break timeouts */ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 1); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_opens); -#endif + cifs_stats_inc(&tcon->num_opens); if (rc) { cFYI(1, ("Error in Open = %d", rc)); } else { @@ -833,9 +821,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_reads); -#endif + cifs_stats_inc(&tcon->num_reads); if (rc) { cERROR(1, ("Send error in read = %d", rc)); } else { @@ -938,9 +924,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, long_op); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_writes); -#endif + cifs_stats_inc(&tcon->num_writes); if (rc) { cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; @@ -1013,9 +997,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len, buf, bytes_sent, &bytes_returned, long_op); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_writes); -#endif + cifs_stats_inc(&tcon->num_writes); if (rc) { cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; @@ -1091,9 +1073,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, timeout); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_locks); -#endif + cifs_stats_inc(&tcon->num_locks); if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); } @@ -1127,9 +1107,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) pSMB->ByteCount = 0; rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_closes); -#endif + cifs_stats_inc(&tcon->num_closes); if (rc) { if(rc!=-EINTR) { /* EINTR is expected when user ctl-c to kill app */ @@ -1202,9 +1180,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_renames); -#endif + cifs_stats_inc(&tcon->num_renames); if (rc) { cFYI(1, ("Send error in rename = %d", rc)); } @@ -1283,9 +1259,7 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&pTcon->num_t2renames); -#endif + cifs_stats_inc(&pTcon->num_t2renames); if (rc) { cFYI(1,("Send error in Rename (by file handle) = %d", rc)); } @@ -1443,9 +1417,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_symlinks); -#endif + cifs_stats_inc(&tcon->num_symlinks); if (rc) { cFYI(1, ("Send error in SetPathInfo (create symlink) = %d", @@ -1535,9 +1507,7 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_hardlinks); -#endif + cifs_stats_inc(&tcon->num_hardlinks); if (rc) { cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); } @@ -1608,9 +1578,7 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_hardlinks); -#endif + cifs_stats_inc(&tcon->num_hardlinks); if (rc) { cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); } @@ -2490,9 +2458,7 @@ int CIFSFindSingle(const int xid, struct cifsTconInfo *tcon, if (rc) { cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); } else { /* decode response */ -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_ffirst); -#endif + cifs_stats_inc(&tcon->num_ffirst); /* BB fill in */ } @@ -2592,9 +2558,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_ffirst); -#endif + cifs_stats_inc(&tcon->num_ffirst); if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ /* BB Add code to handle unsupported level rc */ @@ -2716,9 +2680,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_fnext); -#endif + cifs_stats_inc(&tcon->num_fnext); if (rc) { if (rc == -EBADF) { psrch_inf->endOfSearch = TRUE; @@ -2795,9 +2757,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle if (rc) { cERROR(1, ("Send error in FindClose = %d", rc)); } -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_fclose); -#endif + cifs_stats_inc(&tcon->num_fclose); cifs_small_buf_release(pSMB); /* Since session is dead, search handle closed on server already */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b054df2dee1e..5857d12611e6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -744,13 +744,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, 15 seconds is plenty */ } -#ifdef CONFIG_CIFS_STATS - if (total_written > 0) { - spin_lock(&pTcon->stat_lock); - pTcon->bytes_written += total_written; - spin_unlock(&pTcon->stat_lock); - } -#endif + cifs_stats_bytes_written(pTcon, total_written); /* since the write may have blocked check these pointers again */ if (file->f_dentry) { @@ -878,13 +872,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, 15 seconds is plenty */ } -#ifdef CONFIG_CIFS_STATS - if (total_written > 0) { - spin_lock(&pTcon->stat_lock); - pTcon->bytes_written += total_written; - spin_unlock(&pTcon->stat_lock); - } -#endif + cifs_stats_bytes_written(pTcon, total_written); /* since the write may have blocked check these pointers again */ if (file->f_dentry) { @@ -1245,11 +1233,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, return rc; } } else { -#ifdef CONFIG_CIFS_STATS - spin_lock(&pTcon->stat_lock); - pTcon->bytes_read += total_read; - spin_unlock(&pTcon->stat_lock); -#endif + cifs_stats_bytes_read(pTcon, bytes_read); *poffset += bytes_read; } } @@ -1312,11 +1296,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, return rc; } } else { -#ifdef CONFIG_CIFS_STATS - spin_lock(&pTcon->stat_lock); - pTcon->bytes_read += total_read; - spin_unlock(&pTcon->stat_lock); -#endif + cifs_stats_bytes_read(pTcon, total_read); *poffset += bytes_read; } } @@ -1488,11 +1468,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, le16_to_cpu(pSMBr->DataOffset), &lru_pvec); i += bytes_read >> PAGE_CACHE_SHIFT; -#ifdef CONFIG_CIFS_STATS - spin_lock(&pTcon->stat_lock); - pTcon->bytes_read += bytes_read; - spin_unlock(&pTcon->stat_lock); -#endif + cifs_stats_bytes_read(pTcon, bytes_read); if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { i++; /* account for partial page */ diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 40d50b77bfe7..fafbdbfa63a1 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -520,9 +520,7 @@ is_valid_oplock_break(struct smb_hdr *buf) list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); if (tcon->tid == buf->Tid) { -#ifdef CONFIG_CIFS_STATS - atomic_inc(&tcon->num_oplock_brks); -#endif + cifs_stats_inc(&tcon->num_oplock_brks); list_for_each(tmp1,&tcon->openFileList){ netfile = list_entry(tmp1,struct cifsFileInfo, tlist); From c0c3e8edaabcb6cf6786226813cf087ad21f0743 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 14:01:13 -0700 Subject: [PATCH 0032/1940] CIFS: Fix typos in fs/cifs/CHANGES Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/CHANGES | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 299ed312cea5..340b4ffb3493 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,6 +1,6 @@ Version 1.36 ------------ -Add support for moounting to older pre-CIFS servers such as Windows9x and ME. +Add support for mounting to older pre-CIFS servers such as Windows9x and ME. For these older servers, add option for passing netbios name of server in on mount (servernetbiosname). Add mount option for disabling the default behavior of sending byte range lock @@ -26,7 +26,7 @@ Do not oops if root user kills cifs oplock kernel thread or kills the cifsd thread (NB: killing the cifs kernel threads is not recommended, unmount and rmmod cifs will kill them when they are no longer needed). Fix readdir to ASCII servers (ie older servers -which do not support Unicode) and also require asterik. +which do not support Unicode) and also require asterisk. Fix out of memory case in which data could be written one page off in the page cache. @@ -116,7 +116,7 @@ improperly zeroed buffer in CIFS Unix extensions set times call. Version 1.25 ------------ -Fix internationlization problem in cifs readdir with filenames that map to +Fix internationalization problem in cifs readdir with filenames that map to longer UTF8 strings than the string on the wire was in Unicode. Add workaround for readdir to netapp servers. Fix search rewind (seek into readdir to return non-consecutive entries). Do not do readdir when server negotiates @@ -291,7 +291,7 @@ Fix caching problem when files opened by multiple clients in which page cache could contain stale data, and write through did not occur often enough while file was still open when read ahead (read oplock) not allowed. Treat "sep=" when first mount option -as an overrride of comma as the default separator between mount +as an override of comma as the default separator between mount options. Version 1.01 @@ -301,7 +301,7 @@ Allow passwords longer than 16 bytes. Allow null password string. Version 1.00 ------------ Gracefully clean up failed mounts when attempting to mount to servers such as -Windows 98 that terminate tcp sessions during prototocol negotiation. Handle +Windows 98 that terminate tcp sessions during protocol negotiation. Handle embedded commas in mount parsing of passwords. Version 0.99 @@ -310,7 +310,7 @@ Invalidate local inode cached pages on oplock break and when last file instance is closed so that the client does not continue using stale local copy rather than later modified server copy of file. Do not reconnect when server drops the tcp session prematurely before negotiate -protocol response. Fix oops in roepen_file when dentry freed. Allow +protocol response. Fix oops in reopen_file when dentry freed. Allow the support for CIFS Unix Extensions to be disabled via proc interface. Version 0.98 @@ -652,7 +652,7 @@ versions of 2.4 kernel (now builds and works again on kernels at least as early Version 0.41 ------------ Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked -files now return the correct rumber of links on fstat as they are repeatedly linked and unlinked. +files now return the correct number of links on fstat as they are repeatedly linked and unlinked. Version 0.40 ------------ @@ -719,7 +719,7 @@ session) and cleaned them up and made them more consistent with other cifs functions. 7) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways -(with or without Unix exentions) but FindNext and QueryPathInfo with the Unix extensions are not completed, +(with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed, nor is the symlink support using the Unix extensions 8) Started adding the readlink and follow_link code From e2a98a7543696306346ba8302a8df6cedf20fdfc Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 14:43:14 -0700 Subject: [PATCH 0033/1940] [CIFS] Update thanks/contributor list with Miklos Szeredi (Signed-off-by: Miklos Szeredi also should have been listed on the last cifs patch fixing some lookup intent handling in cifs) Signed-off-by: Steve French --- fs/cifs/AUTHORS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS index 72fdc10dfdd7..8848e4dfa026 100644 --- a/fs/cifs/AUTHORS +++ b/fs/cifs/AUTHORS @@ -32,6 +32,10 @@ Domen Puncer Jesper Juhl (in particular for lots of whitespace/formatting cleanup) Vince Negri and Dave Stahl (for finding an important caching bug) Adrian Bunk (kcalloc cleanups) +Miklos Szeredi +Kazeon team for various fixes especially for 2.4 version. +Asser Ferno (Change Notify support) +Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup Test case and Bug Report contributors ------------------------------------- From ff5dbd9ead0d82466cab8bdbdcbc9666707d328a Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 17:10:36 -0700 Subject: [PATCH 0034/1940] [CIFS] Change notify support part 2 Signed-off-by: Asser Ferno Signed-off-by: Steve French and lightly modified --- fs/cifs/cifsglob.h | 17 +++++++++++++++++ fs/cifs/cifspdu.h | 1 + fs/cifs/cifssmb.c | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 9a3c85bdd77e..92fba7609e67 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -391,6 +391,20 @@ struct oplock_q_entry { __u16 netfid; }; +/* for pending dnotify requests */ +struct dir_notify_req { + struct list_head lhead; + __le16 Pid; + __le16 PidHigh; + __u16 Mid; + __u16 Tid; + __u16 Uid; + __u16 netfid; + __u32 filter; /* CompletionFilter (for multishot) */ + int multishot; + struct dentry * dentry; +}; + #define MID_FREE 0 #define MID_REQUEST_ALLOCATED 1 #define MID_REQUEST_SUBMITTED 2 @@ -459,6 +473,9 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */ GLOBAL_EXTERN struct list_head GlobalOplock_Q; +GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ +GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */ + /* * Global transaction id (XID) information */ diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 42c16cf32284..026c88f486a2 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -53,6 +53,7 @@ #define SMB_COM_NT_TRANSACT 0xA0 #define SMB_COM_NT_TRANSACT_SECONDARY 0xA1 #define SMB_COM_NT_CREATE_ANDX 0xA2 +#define SMB_COM_NT_CANCEL 0xA4 /* no response */ #define SMB_COM_NT_RENAME 0xA5 /* trivial response */ /* Transact2 subcommand codes */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 698cdcebca04..36d45b1dffc2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -4015,6 +4015,22 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, (struct smb_hdr *) pSMBr, &bytes_returned, -1); if (rc) { cFYI(1, ("Error in Notify = %d", rc)); + } else { + /* Add file to outstanding requests */ + dnotify_req = (struct dir_notify_req *) kmalloc( + sizeof(struct dir_notify_req), GFP_KERNEL); + dnotify_req->Pid = pSMB->hdr.Pid; + dnotify_req->PidHigh = pSMB->hdr.PidHigh; + dnotify_req->Mid = pSMB->hdr.Mid; + dnotify_req->Tid = pSMB->hdr.Tid; + dnotify_req->Uid = pSMB->hdr.Uid; + dnotify_req->netfid = netfid; + dnotify_req->dentry = dentry; + dnotify_req->filter = filter; + dnotify_req->multishot = multishot; + spin_lock(&GlobalMid_Lock); + list_add_tail(&dnotify_req->lhead, &GlobalDnotifyReqList); + spin_unlock(&GlobalMid_Lock); } cifs_buf_release(pSMB); return rc; From abb15b8ae4eb7cdff0061e7ac5eca1f8dd8a84af Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 18:51:02 -0700 Subject: [PATCH 0035/1940] [CIFS] Missing line from previous patch Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifssmb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 36d45b1dffc2..be2a3b9a718c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3983,6 +3983,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, int rc = 0; struct smb_com_transaction_change_notify_req * pSMB = NULL; struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; + struct dir_notify_req *dnotify_req; int bytes_returned; cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); From 167a251ad6678ad26aa3cf27bab677b274374ab6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 20:03:11 -0700 Subject: [PATCH 0036/1940] [CIFS] Change notify support part 3 Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 2 +- fs/cifs/cifsproto.h | 3 ++- fs/cifs/cifssmb.c | 7 ++++--- fs/cifs/fcntl.c | 8 +++++--- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 92fba7609e67..236de07cbda6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -402,7 +402,7 @@ struct dir_notify_req { __u16 netfid; __u32 filter; /* CompletionFilter (for multishot) */ int multishot; - struct dentry * dentry; + struct file * dentry; }; #define MID_FREE 0 diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 0cc0612eacb4..28b1ebbd3801 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -275,7 +275,8 @@ extern int CIFSSMBCopy(int xid, int remap_special_chars); extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, const int notify_subdirs,const __u16 netfid, - __u32 filter, const struct nls_table *nls_codepage); + __u32 filter, struct file * file, int multishot, + const struct nls_table *nls_codepage); extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, char * EAData, size_t bufsize, const struct nls_table *nls_codepage, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index be2a3b9a718c..67a6240ff2ba 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3977,8 +3977,9 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, } int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, - const int notify_subdirs, const __u16 netfid, - __u32 filter, const struct nls_table *nls_codepage) + const int notify_subdirs, const __u16 netfid, + __u32 filter, struct file * pfile, int multishot, + const struct nls_table *nls_codepage) { int rc = 0; struct smb_com_transaction_change_notify_req * pSMB = NULL; @@ -4026,7 +4027,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, dnotify_req->Tid = pSMB->hdr.Tid; dnotify_req->Uid = pSMB->hdr.Uid; dnotify_req->netfid = netfid; - dnotify_req->dentry = dentry; + dnotify_req->pfile = pfile; dnotify_req->filter = filter; dnotify_req->multishot = multishot; spin_lock(&GlobalMid_Lock); diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index d47ce7f49dc3..2e5137b7352a 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -100,8 +100,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg) } else { filter = convert_to_cifs_notify_flags(arg); if(filter != 0) { - rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, - filter, cifs_sb->local_nls); + rc = CIFSSMBNotify(xid, pTcon, + 0 /* no subdirs */, netfid, + filter, file, arg & DN_MULTISHOT, + cifs_sb->local_nls); } else { rc = -EINVAL; } @@ -109,7 +111,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg) it would close automatically but may be a way to do it easily when inode freed or when notify info is cleared/changed */ - cERROR(1,("notify rc %d",rc)); + cFYI(1,("notify rc %d",rc)); } } From e22cb8bcb8bce94bf5cca90c98933a28816c6a75 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 20:25:21 -0700 Subject: [PATCH 0037/1940] [CIFS] Use file instead of dentry in cifs dir_notify struct Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 236de07cbda6..a9c791edede5 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -402,7 +402,7 @@ struct dir_notify_req { __u16 netfid; __u32 filter; /* CompletionFilter (for multishot) */ int multishot; - struct file * dentry; + struct file * pfile; }; #define MID_FREE 0 From a9d02ad49013c8fc527f06ca66417103cdbb08b6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 24 Aug 2005 23:06:05 -0700 Subject: [PATCH 0038/1940] [CIFS] Support for legacy servers part 3 - Add support for Open and most of Read support. Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 73 +++++++++++++++ fs/cifs/cifsproto.h | 8 ++ fs/cifs/cifssmb.c | 215 ++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/dir.c | 7 ++ fs/cifs/file.c | 29 +++++- 5 files changed, 330 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 026c88f486a2..cf466595b0d4 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -40,6 +40,7 @@ #define SMB_COM_SETATTR 0x09 /* trivial response */ #define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */ #define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/ +#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */ #define SMB_COM_READ_ANDX 0x2E #define SMB_COM_WRITE_ANDX 0x2F #define SMB_COM_TRANSACTION2 0x32 @@ -625,6 +626,7 @@ typedef struct smb_com_findclose_req { } FINDCLOSE_REQ; /* OpenFlags */ +#define REQ_MORE_INFO 0x00000001 /* legacy (OPEN_AND_X) only */ #define REQ_OPLOCK 0x00000002 #define REQ_BATCHOPLOCK 0x00000004 #define REQ_OPENDIRONLY 0x00000008 @@ -680,6 +682,62 @@ typedef struct smb_com_open_rsp { __u16 ByteCount; /* bct = 0 */ } OPEN_RSP; +/* format of legacy open request */ +typedef struct smb_com_openx_req { + struct smb_hdr hdr; /* wct = 15 */ + __u8 AndXCommand; + __u8 AndXReserved; + __le16 AndXOffset; + __le16 OpenFlags; + __le16 Mode; + __le16 Sattr; /* search attributes */ + __le16 FileAttributes; /* dos attrs */ + __le32 CreateTime; /* os2 format */ + __le16 OpenFunction; + __le32 EndOfFile; + __le32 Timeout; + __le32 Reserved; + __u16 ByteCount; /* file name follows */ + char fileName[1]; +} OPENX_REQ; + +typedef struct smb_com_openx_rsp { + struct smb_hdr hdr; /* wct = 15 */ + __u8 AndXCommand; + __u8 AndXReserved; + __le16 AndXOffset; + __u16 Fid; + __le16 FileAttributes; + __le32 LastWriteTime; /* os2 format */ + __le32 EndOfFile; + __le16 Access; + __le16 FileType; + __le16 IPCState; + __le16 Action; + __u32 FileId; + __u16 Reserved; + __u16 ByteCount; +} OPENX_RSP; + +/* Legacy write request for older servers */ +typedef struct smb_com_writex_req { + struct smb_hdr hdr; /* wct = 12 */ + __u8 AndXCommand; + __u8 AndXReserved; + __le16 AndXOffset; + __u16 Fid; + __le32 OffsetLow; + __u32 Reserved; /* Timeout */ + __le16 WriteMode; /* 1 = write through */ + __le16 Remaining; + __le16 Reserved2; + __le16 DataLengthLow; + __le16 DataOffset; + __le16 ByteCount; + __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ + char Data[0]; +} WRITEX_REQ; + typedef struct smb_com_write_req { struct smb_hdr hdr; /* wct = 14 */ __u8 AndXCommand; @@ -711,6 +769,21 @@ typedef struct smb_com_write_rsp { __u16 ByteCount; } WRITE_RSP; +/* legacy read request for older servers */ +typedef struct smb_com_readx_req { + struct smb_hdr hdr; /* wct = 10 */ + __u8 AndXCommand; + __u8 AndXReserved; + __le16 AndXOffset; + __u16 Fid; + __le32 OffsetLow; + __le16 MaxCount; + __le16 MinCount; /* obsolete */ + __le32 Reserved; + __le16 Remaining; + __le16 ByteCount; +} READX_REQ; + typedef struct smb_com_read_req { struct smb_hdr hdr; /* wct = 12 */ __u8 AndXCommand; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 28b1ebbd3801..c411f2e001aa 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -218,9 +218,17 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, const int access_flags, const int omode, __u16 * netfid, int *pOplock, FILE_ALL_INFO *, const struct nls_table *nls_codepage, int remap); +extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, + const char *fileName, const int disposition, + const int access_flags, const int omode, + __u16 * netfid, int *pOplock, FILE_ALL_INFO *, + const struct nls_table *nls_codepage, int remap); extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, const int smb_file_id); +extern int SMBLegacyRead(const int xid, struct cifsTconInfo *tcon, + const int netfid, unsigned int count, + const __u64 lseek, unsigned int *nbytes, char **buf); extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, unsigned int count, const __u64 lseek, unsigned int *nbytes, char **buf); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 67a6240ff2ba..c8ae3ef422ba 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -680,6 +680,146 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, return rc; } +static __u16 convert_disposition(int disposition) +{ + __u16 ofun = 0; + + switch (disposition) { + case FILE_SUPERSEDE: + ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; + break; + case FILE_OPEN: + ofun = SMBOPEN_OAPPEND; + break; + case FILE_CREATE: + ofun = SMBOPEN_OCREATE; + break; + case FILE_OPEN_IF: + ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND; + break; + case FILE_OVERWRITE: + ofun = SMBOPEN_OTRUNC; + break; + case FILE_OVERWRITE_IF: + ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; + break; + default: + cFYI(1,("unknown disposition %d",disposition)); + ofun = SMBOPEN_OAPPEND; /* regular open */ + } + return ofun; +} + +int +SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, + const char *fileName, const int openDisposition, + const int access_flags, const int create_options, __u16 * netfid, + int *pOplock, FILE_ALL_INFO * pfile_info, + const struct nls_table *nls_codepage, int remap) +{ + int rc = -EACCES; + OPENX_REQ *pSMB = NULL; + OPENX_RSP *pSMBr = NULL; + int bytes_returned; + int name_len; + __u16 count; + +OldOpenRetry: + rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + pSMB->AndXCommand = 0xFF; /* none */ + + if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { + count = 1; /* account for one byte pad to word boundary */ + name_len = + cifsConvertToUCS((__le16 *) (pSMB->fileName + 1), + fileName, PATH_MAX, nls_codepage, remap); + name_len++; /* trailing null */ + name_len *= 2; + } else { /* BB improve check for buffer overruns BB */ + count = 0; /* no pad */ + name_len = strnlen(fileName, PATH_MAX); + name_len++; /* trailing null */ + strncpy(pSMB->fileName, fileName, name_len); + } + if (*pOplock & REQ_OPLOCK) + pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); + else if (*pOplock & REQ_BATCHOPLOCK) { + pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); + } + pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); + /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ + /* 0 = read + 1 = write + 2 = rw + 3 = execute + */ + pSMB->Mode = cpu_to_le16(2); + pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ + /* set file as system file if special file such + as fifo and server expecting SFU style and + no Unix extensions */ + + if(create_options & CREATE_OPTION_SPECIAL) + pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); + else + pSMB->FileAttributes = cpu_to_le16(ATTR_NORMAL); + + /* if ((omode & S_IWUGO) == 0) + pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ + /* Above line causes problems due to vfs splitting create into two + pieces - need to set mode after file created not while it is + being created */ + + /* BB FIXME BB */ +/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */ + /* BB FIXME END BB */ + pSMB->OpenFunction = convert_disposition(openDisposition); + count += name_len; + pSMB->hdr.smb_buf_length += count; + + pSMB->ByteCount = cpu_to_le16(count); + /* long_op set to 1 to allow for oplock break timeouts */ + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 1); + cifs_stats_inc(&tcon->num_opens); + if (rc) { + cFYI(1, ("Error in Open = %d", rc)); + } else { + /* BB verify if wct == 15 */ + +/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */ + + *netfid = pSMBr->Fid; /* cifs fid stays in le */ + /* Let caller know file was created so we can set the mode. */ + /* Do we care about the CreateAction in any other cases? */ + /* BB FIXME BB */ +/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) + *pOplock |= CIFS_CREATE_ACTION; */ + /* BB FIXME END */ + + if(pfile_info) { + pfile_info->CreationTime = 0; /* BB convert CreateTime*/ + pfile_info->LastAccessTime = 0; /* BB fixme */ + pfile_info->LastWriteTime = 0; /* BB fixme */ + pfile_info->ChangeTime = 0; /* BB fixme */ + pfile_info->Attributes = pSMBr->FileAttributes; + /* the file_info buf is endian converted by caller */ + pfile_info->AllocationSize = pSMBr->EndOfFile; + pfile_info->EndOfFile = pSMBr->EndOfFile; + pfile_info->NumberOfLinks = cpu_to_le32(1); + } + } + + cifs_buf_release(pSMB); + if (rc == -EAGAIN) + goto OldOpenRetry; + return rc; +} + int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, const char *fileName, const int openDisposition, @@ -783,6 +923,81 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, return rc; } +int +SMBLegacyRead(const int xid, struct cifsTconInfo *tcon, + const int netfid, unsigned int count, + const __u64 lseek, unsigned int *nbytes, char **buf) +{ + int rc = -EACCES; + READX_REQ *pSMB = NULL; + READ_RSP *pSMBr = NULL; + char *pReadData = NULL; + int bytes_returned; + + cFYI(1,("Legacy read %d bytes fid %d",count,netfid)); + + /* field is shorter in legacy read, only 16 bits */ + if(count > 2048) + count = 2048; /* BB FIXME make this configurable */ + + if(lseek > 0xFFFFFFFF) + return -EIO; /* can not read that far into file on old server */ + + *nbytes = 0; + rc = smb_init(SMB_COM_READ_ANDX, 10, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + /* tcon and ses pointer are checked in smb_init */ + if (tcon->ses->server == NULL) + return -ECONNABORTED; + + pSMB->AndXCommand = 0xFF; /* none */ + pSMB->Fid = netfid; + pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); + pSMB->Remaining = 0; + pSMB->MaxCount = cpu_to_le16(count); + pSMB->Reserved = 0; /* Must Be Zero */ + pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + cifs_stats_inc(&tcon->num_reads); + if (rc) { + cERROR(1, ("Send error in legacy read = %d", rc)); + } else { + int data_length = le16_to_cpu(pSMBr->DataLengthHigh); + data_length = data_length << 16; + data_length += le16_to_cpu(pSMBr->DataLength); + *nbytes = data_length; + + /*check that DataLength would not go beyond end of SMB */ + if ((data_length > CIFSMaxBufSize) || (data_length > count)) { + cFYI(1,("bad length %d for count %d",data_length,count)); + rc = -EIO; + *nbytes = 0; + } else { + pReadData = (char *) (&pSMBr->hdr.Protocol) + + le16_to_cpu(pSMBr->DataOffset); +/* if(rc = copy_to_user(buf, pReadData, data_length)) { + cERROR(1,("Faulting on read rc = %d",rc)); + rc = -EFAULT; + }*/ /* can not use copy_to_user when using page cache*/ + if(*buf) + memcpy(*buf,pReadData,data_length); + } + } + if(*buf) + cifs_buf_release(pSMB); + else + *buf = (char *)pSMB; + + /* Note: On -EAGAIN error only caller can retry on handle based calls + since file handle passed in no longer valid */ + return rc; +} + /* If no buffer passed in, then caller wants to do the copy as in the case of readpages so the SMB buffer must be freed by the caller */ diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 5311c50734b0..248ddebd67f4 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -184,6 +184,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, desiredAccess, CREATE_NOT_DIR, &fileHandle, &oplock, buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + if(rc == -EIO) { + /* old server, retry the open legacy style */ + rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, + desiredAccess, CREATE_NOT_DIR, + &fileHandle, &oplock, buf, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + } if (rc) { cFYI(1, ("cifs_create returned 0x%x ", rc)); } else { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5857d12611e6..8ae962e7c93f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -256,6 +256,13 @@ int cifs_open(struct inode *inode, struct file *file) CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc == -EIO) { + /* Old server, try legacy style OpenX */ + rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, + desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags + & CIFS_MOUNT_MAP_SPECIAL_CHR); + } if (rc) { cFYI(1, ("cifs_open returned 0x%x ", rc)); goto out; @@ -1210,7 +1217,12 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, open_file->netfid, current_read_size, *poffset, &bytes_read, &smb_read_data); - + if(rc == -EINVAL) { + rc = SMBLegacyRead(xid, pTcon, + open_file->netfid, + current_read_size, *poffset, + &bytes_read, &smb_read_data); + } pSMBr = (struct smb_com_read_rsp *)smb_read_data; if (copy_to_user(current_offset, smb_read_data + 4 /* RFC1001 hdr */ @@ -1287,6 +1299,12 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, open_file->netfid, current_read_size, *poffset, &bytes_read, ¤t_offset); + if(rc == -EINVAL) { + rc = SMBLegacyRead(xid, pTcon, + open_file->netfid, + current_read_size, *poffset, + &bytes_read, ¤t_offset); + } } if (rc || (bytes_read == 0)) { if (total_read) { @@ -1443,7 +1461,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, open_file->netfid, read_size, offset, &bytes_read, &smb_read_data); - /* BB need to check return code here */ + if (rc == -EINVAL) { + rc = SMBLegacyRead(xid, pTcon, + open_file->netfid, + read_size, offset, + &bytes_read, &smb_read_data); + } + + /* BB more RC checks ? */ if (rc== -EAGAIN) { if (smb_read_data) { cifs_buf_release(smb_read_data); From 7f57356b70dda014ef269135942426e4a852023e Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 30 Aug 2005 11:32:14 -0700 Subject: [PATCH 0039/1940] [CIFS] Remove cifs_sb argument from *build_path_from_dentry This argument was added in a recent patch, but is unnecessary, since the superblock is easily obtained from the dentry. Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 +- fs/cifs/dir.c | 11 ++++++----- fs/cifs/fcntl.c | 2 +- fs/cifs/file.c | 4 ++-- fs/cifs/inode.c | 14 +++++++------- fs/cifs/link.c | 15 +++++++-------- fs/cifs/readdir.c | 2 +- fs/cifs/xattr.c | 8 ++++---- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c411f2e001aa..656b78ddf674 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -40,7 +40,7 @@ extern unsigned int _GetXid(void); extern void _FreeXid(unsigned int); #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} -extern char *build_path_from_dentry(struct dentry *, const struct cifs_sb_info *cifs_sb); +extern char *build_path_from_dentry(struct dentry *); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern void renew_parental_timestamps(struct dentry *direntry); extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 248ddebd67f4..cf90c9ad2c87 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -43,11 +43,12 @@ renew_parental_timestamps(struct dentry *direntry) /* Note: caller must free return buffer */ char * -build_path_from_dentry(struct dentry *direntry, const struct cifs_sb_info *cifs_sb) +build_path_from_dentry(struct dentry *direntry) { struct dentry *temp; int namelen = 0; char *full_path; + char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); if(direntry == NULL) return NULL; /* not much we can do if dentry is freed and @@ -74,7 +75,7 @@ build_path_from_dentry(struct dentry *direntry, const struct cifs_sb_info *cifs_ if (namelen < 0) { break; } else { - full_path[namelen] = CIFS_DIR_SEP(cifs_sb); + full_path[namelen] = dirsep; strncpy(full_path + namelen + 1, temp->d_name.name, temp->d_name.len); cFYI(0, (" name: %s ", full_path + namelen)); @@ -138,7 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&direntry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -310,7 +311,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&direntry->d_sb->s_vfs_rename_sem); if(full_path == NULL) rc = -ENOMEM; @@ -409,7 +410,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name /* can not grab the rename sem here since it would deadlock in the cases (beginning of sys_rename itself) in which we already have the sb rename sem */ - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); if(full_path == NULL) { FreeXid(xid); return ERR_PTR(-ENOMEM); diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 2e5137b7352a..d527e2c76073 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -83,7 +83,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg) pTcon = cifs_sb->tcon; down(&file->f_dentry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry, cifs_sb); + full_path = build_path_from_dentry(file->f_dentry); up(&file->f_dentry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8ae962e7c93f..026b5c5ccc89 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -196,7 +196,7 @@ int cifs_open(struct inode *inode, struct file *file) } down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry, cifs_sb); + full_path = build_path_from_dentry(file->f_dentry); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -366,7 +366,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, those that already have the rename sem can end up causing writepage to get called and if the server was down that means we end up here, and we can never tell if the caller already has the rename_sem */ - full_path = build_path_from_dentry(file->f_dentry, cifs_sb); + full_path = build_path_from_dentry(file->f_dentry); if (full_path == NULL) { up(&pCifsFile->fh_sem); FreeXid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 34f0168c4041..0485c6d6ecd5 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -436,7 +436,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) /* Unlink can be called from rename so we can not grab the sem here since we deadlock otherwise */ /* down(&direntry->d_sb->s_vfs_rename_sem);*/ - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); /* up(&direntry->d_sb->s_vfs_rename_sem);*/ if (full_path == NULL) { FreeXid(xid); @@ -580,7 +580,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -654,7 +654,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&inode->i_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); @@ -707,8 +707,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, /* we already have the rename sem so we do not need to grab it again here to protect the path integrity */ - fromName = build_path_from_dentry(source_direntry, cifs_sb_source); - toName = build_path_from_dentry(target_direntry, cifs_sb_target); + fromName = build_path_from_dentry(source_direntry); + toName = build_path_from_dentry(target_direntry); if ((fromName == NULL) || (toName == NULL)) { rc = -ENOMEM; goto cifs_rename_exit; @@ -824,7 +824,7 @@ int cifs_revalidate(struct dentry *direntry) /* can not safely grab the rename sem here if rename calls revalidate since that would deadlock */ - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); if (full_path == NULL) { FreeXid(xid); return -ENOMEM; @@ -973,7 +973,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) pTcon = cifs_sb->tcon; down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&direntry->d_sb->s_vfs_rename_sem); if (full_path == NULL) { FreeXid(xid); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index b8ec6646456a..b43e071fe110 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -49,8 +49,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, BB note DFS case in future though (when we may have to check) */ down(&inode->i_sb->s_vfs_rename_sem); - fromName = build_path_from_dentry(old_file, cifs_sb_target); - toName = build_path_from_dentry(direntry, cifs_sb_target); + fromName = build_path_from_dentry(old_file); + toName = build_path_from_dentry(direntry); up(&inode->i_sb->s_vfs_rename_sem); if((fromName == NULL) || (toName == NULL)) { rc = -ENOMEM; @@ -105,17 +105,16 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) xid = GetXid(); - cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; - down(&direntry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&direntry->d_sb->s_vfs_rename_sem); if (!full_path) goto out_no_free; cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); + cifs_sb = CIFS_SB(inode->i_sb); + pTcon = cifs_sb->tcon; target_path = kmalloc(PATH_MAX, GFP_KERNEL); if (!target_path) { target_path = ERR_PTR(-ENOMEM); @@ -168,7 +167,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) pTcon = cifs_sb->tcon; down(&inode->i_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&inode->i_sb->s_vfs_rename_sem); if(full_path == NULL) { @@ -237,7 +236,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) /* BB would it be safe against deadlock to grab this sem even though rename itself grabs the sem and calls lookup? */ /* down(&inode->i_sb->s_vfs_rename_sem);*/ - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); /* up(&inode->i_sb->s_vfs_rename_sem);*/ if(full_path == NULL) { diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index f769292e2a93..9780f4ee7f12 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -368,7 +368,7 @@ static int initiate_cifs_search(const int xid, struct file *file) return -EINVAL; down(&file->f_dentry->d_sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(file->f_dentry, cifs_sb); + full_path = build_path_from_dentry(file->f_dentry); up(&file->f_dentry->d_sb->s_vfs_rename_sem); if(full_path == NULL) { diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index f4fc8ddebba7..c1e02eff1d25 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -63,7 +63,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name) pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -118,7 +118,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name, pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -227,7 +227,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); @@ -328,7 +328,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) pTcon = cifs_sb->tcon; down(&sb->s_vfs_rename_sem); - full_path = build_path_from_dentry(direntry, cifs_sb); + full_path = build_path_from_dentry(direntry); up(&sb->s_vfs_rename_sem); if(full_path == NULL) { FreeXid(xid); From 16abbecdad3367c76c12537450eba0d86943fe2c Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 30 Aug 2005 13:10:14 -0700 Subject: [PATCH 0040/1940] [CIFS] Add support for suspend cifsd had been preventing software suspend from completing. Signed-off-by: pavel@suse.de Signed-off-by: Steve French lightly modified --- fs/cifs/CHANGES | 3 ++- fs/cifs/cifsfs.c | 4 ++++ fs/cifs/connect.c | 2 ++ 3 files changed, 8 insertions(+), 1 deletions(-) --- fs/cifs/CHANGES | 3 ++- fs/cifs/cifsfs.c | 4 ++++ fs/cifs/connect.c | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 340b4ffb3493..6c73f020ef40 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -2,7 +2,8 @@ Version 1.36 ------------ Add support for mounting to older pre-CIFS servers such as Windows9x and ME. For these older servers, add option for passing netbios name of server in -on mount (servernetbiosname). +on mount (servernetbiosname). Add suspend support for power management, to +avoid cifsd thread preventing software suspend from working. Add mount option for disabling the default behavior of sending byte range lock requests to the server (necessary for certain applications which break with mandatory lock behavior such as Evolution), and also mount option for diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d77abe236a67..43fb2aafa528 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -784,6 +784,8 @@ static int cifs_oplock_thread(void * dummyarg) oplockThread = current; do { + if(try_to_freeze()) + continue; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1*HZ); @@ -848,6 +850,8 @@ static int cifs_dnotify_thread(void * dummyarg) dnotifyThread = current; do { + if(try_to_freeze()) + continue; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(39*HZ); } while(!signal_pending(current)); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c75bae1242dc..134195cc4073 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -355,6 +355,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } while (server->tcpStatus != CifsExiting) { + if(try_to_freeze()) + continue; if (bigbuf == NULL) { bigbuf = cifs_buf_get(); if(bigbuf == NULL) { From cb8be64084e6294fcb9e558188fe104050b94f0b Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 30 Aug 2005 15:25:52 -0700 Subject: [PATCH 0041/1940] [CIFS] Add nolock synonym (ala nfs) for nobrl to disable sending byte range locks remotely. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/connect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 134195cc4073..f784b70abfeb 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1078,7 +1078,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) vol->nocase = 1; } else if (strnicmp(data, "brl", 3) == 0) { vol->nobrl = 0; - } else if (strnicmp(data, "nobrl", 5) == 0) { + } else if ((strnicmp(data, "nobrl", 5) == 0) || + (strnicmp(data, "nolock", 6)) { vol->nobrl = 1; /* turn off mandatory locking in mode if remote locking is turned off since the From 1c9551878c4629ca78dfe12ed23b9dc8d97770cc Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 30 Aug 2005 20:58:07 -0700 Subject: [PATCH 0042/1940] [CIFS] Add support for legacy servers part 4 Fix WriteX support for old servers which do not support large files. Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 27 ++++++++++++++++--- fs/cifs/connect.c | 2 +- fs/cifs/file.c | 66 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c8ae3ef422ba..74733851cfad 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1082,12 +1082,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, int rc = -EACCES; WRITE_REQ *pSMB = NULL; WRITE_RSP *pSMBr = NULL; - int bytes_returned; + int bytes_returned, wct; __u32 bytes_sent; __u16 byte_count; /* cFYI(1,("write at %lld %d bytes",offset,count));*/ - rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB, + if(tcon->ses == NULL) + return -ECONNABORTED; + + if(tcon->ses->capabilities & CAP_LARGE_FILES) + wct = 14; + else + wct = 12; + + rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; @@ -1098,7 +1106,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = netfid; pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); - pSMB->OffsetHigh = cpu_to_le32(offset >> 32); + if(wct == 14) + pSMB->OffsetHigh = cpu_to_le32(offset >> 32); + else if((offset >> 32) > 0) /* can not handle this big offset for old */ + return -EIO; + pSMB->Reserved = 0xFFFFFFFF; pSMB->WriteMode = 0; pSMB->Remaining = 0; @@ -1135,7 +1147,14 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); pSMB->hdr.smb_buf_length += bytes_sent+1; - pSMB->ByteCount = cpu_to_le16(byte_count); + + if(wct == 14) + pSMB->ByteCount = cpu_to_le16(byte_count); + else { /* old style write has byte count 4 bytes earlier */ + struct smb_com_writex_req * pSMBW = + (struct smb_com_writex_req *)pSMB; + pSMBW->ByteCount = cpu_to_le16(byte_count); + } rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, long_op); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f784b70abfeb..196976049c00 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1079,7 +1079,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) } else if (strnicmp(data, "brl", 3) == 0) { vol->nobrl = 0; } else if ((strnicmp(data, "nobrl", 5) == 0) || - (strnicmp(data, "nolock", 6)) { + (strnicmp(data, "nolock", 6) == 0)) { vol->nobrl = 1; /* turn off mandatory locking in mode if remote locking is turned off since the diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ef455dda0473..b6c303f6373f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1183,11 +1183,16 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, char *smb_read_data; char __user *current_offset; struct smb_com_read_rsp *pSMBr; + int use_old_read = FALSE; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; + if(pTcon->ses) + if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) + use_old_read = TRUE; + if (file->private_data == NULL) { FreeXid(xid); return -EBADF; @@ -1212,16 +1217,21 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, if (rc != 0) break; } - - rc = CIFSSMBRead(xid, pTcon, - open_file->netfid, - current_read_size, *poffset, - &bytes_read, &smb_read_data); - if(rc == -EINVAL) { + if(use_old_read) rc = SMBLegacyRead(xid, pTcon, open_file->netfid, current_read_size, *poffset, &bytes_read, &smb_read_data); + else { + rc = CIFSSMBRead(xid, pTcon, + open_file->netfid, + current_read_size, *poffset, + &bytes_read, &smb_read_data); + if(rc == -EINVAL) { + use_old_read = TRUE; + rc = -EAGAIN; + continue; + } } pSMBr = (struct smb_com_read_rsp *)smb_read_data; if (copy_to_user(current_offset, @@ -1266,6 +1276,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, int xid; char *current_offset; struct cifsFileInfo *open_file; + int use_old_read = FALSE; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); @@ -1276,6 +1287,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, return -EBADF; } open_file = (struct cifsFileInfo *)file->private_data; + if(pTcon->ses) + if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) + use_old_read = TRUE; if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, ("attempting read on write only file instance")); @@ -1294,16 +1308,23 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, if (rc != 0) break; } - - rc = CIFSSMBRead(xid, pTcon, - open_file->netfid, - current_read_size, *poffset, - &bytes_read, ¤t_offset); - if(rc == -EINVAL) { + if(use_old_read) rc = SMBLegacyRead(xid, pTcon, + open_file->netfid, + current_read_size, *poffset, + &bytes_read, ¤t_offset); + else { + rc = CIFSSMBRead(xid, pTcon, open_file->netfid, current_read_size, *poffset, &bytes_read, ¤t_offset); + /* check if server disavows support for + 64 bit offsets */ + if(rc == -EINVAL) { + rc = -EAGAIN; + use_old_read = TRUE; + continue; + } } } if (rc || (bytes_read == 0)) { @@ -1402,6 +1423,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, struct smb_com_read_rsp *pSMBr; struct pagevec lru_pvec; struct cifsFileInfo *open_file; + int use_old_read = FALSE; xid = GetXid(); if (file->private_data == NULL) { @@ -1411,7 +1433,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, open_file = (struct cifsFileInfo *)file->private_data; cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; - + if(pTcon->ses) + if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) + use_old_read = TRUE; pagevec_init(&lru_pvec, 0); for (i = 0; i < num_pages; ) { @@ -1457,15 +1481,21 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, break; } - rc = CIFSSMBRead(xid, pTcon, - open_file->netfid, - read_size, offset, - &bytes_read, &smb_read_data); - if (rc == -EINVAL) { + if(use_old_read) rc = SMBLegacyRead(xid, pTcon, open_file->netfid, read_size, offset, &bytes_read, &smb_read_data); + else { + rc = CIFSSMBRead(xid, pTcon, + open_file->netfid, + read_size, offset, + &bytes_read, &smb_read_data); + if(rc == -EINVAL) { + use_old_read = TRUE; + rc = -EAGAIN; + continue; + } } /* BB more RC checks ? */ From bfa0d75a1eee59f0577e3c1697ff570b77581a35 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 31 Aug 2005 21:50:37 -0700 Subject: [PATCH 0043/1940] [CIFS] Add support for legacy servers part 5 Handle small negotiated read sizes (under 4K) and finish up read and write support. Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 3 -- fs/cifs/cifssmb.c | 99 +++++++++------------------------------------ fs/cifs/file.c | 58 ++------------------------ fs/cifs/inode.c | 7 ++++ fs/cifs/readdir.c | 9 ++++- 5 files changed, 39 insertions(+), 137 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 656b78ddf674..6943f7c6de08 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -226,9 +226,6 @@ extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, const int smb_file_id); -extern int SMBLegacyRead(const int xid, struct cifsTconInfo *tcon, - const int netfid, unsigned int count, - const __u64 lseek, unsigned int *nbytes, char **buf); extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, unsigned int count, const __u64 lseek, unsigned int *nbytes, char **buf); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 74733851cfad..b8830118f09a 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -923,81 +923,6 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, return rc; } -int -SMBLegacyRead(const int xid, struct cifsTconInfo *tcon, - const int netfid, unsigned int count, - const __u64 lseek, unsigned int *nbytes, char **buf) -{ - int rc = -EACCES; - READX_REQ *pSMB = NULL; - READ_RSP *pSMBr = NULL; - char *pReadData = NULL; - int bytes_returned; - - cFYI(1,("Legacy read %d bytes fid %d",count,netfid)); - - /* field is shorter in legacy read, only 16 bits */ - if(count > 2048) - count = 2048; /* BB FIXME make this configurable */ - - if(lseek > 0xFFFFFFFF) - return -EIO; /* can not read that far into file on old server */ - - *nbytes = 0; - rc = smb_init(SMB_COM_READ_ANDX, 10, tcon, (void **) &pSMB, - (void **) &pSMBr); - if (rc) - return rc; - - /* tcon and ses pointer are checked in smb_init */ - if (tcon->ses->server == NULL) - return -ECONNABORTED; - - pSMB->AndXCommand = 0xFF; /* none */ - pSMB->Fid = netfid; - pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); - pSMB->Remaining = 0; - pSMB->MaxCount = cpu_to_le16(count); - pSMB->Reserved = 0; /* Must Be Zero */ - pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ - - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); - cifs_stats_inc(&tcon->num_reads); - if (rc) { - cERROR(1, ("Send error in legacy read = %d", rc)); - } else { - int data_length = le16_to_cpu(pSMBr->DataLengthHigh); - data_length = data_length << 16; - data_length += le16_to_cpu(pSMBr->DataLength); - *nbytes = data_length; - - /*check that DataLength would not go beyond end of SMB */ - if ((data_length > CIFSMaxBufSize) || (data_length > count)) { - cFYI(1,("bad length %d for count %d",data_length,count)); - rc = -EIO; - *nbytes = 0; - } else { - pReadData = (char *) (&pSMBr->hdr.Protocol) + - le16_to_cpu(pSMBr->DataOffset); -/* if(rc = copy_to_user(buf, pReadData, data_length)) { - cERROR(1,("Faulting on read rc = %d",rc)); - rc = -EFAULT; - }*/ /* can not use copy_to_user when using page cache*/ - if(*buf) - memcpy(*buf,pReadData,data_length); - } - } - if(*buf) - cifs_buf_release(pSMB); - else - *buf = (char *)pSMB; - - /* Note: On -EAGAIN error only caller can retry on handle based calls - since file handle passed in no longer valid */ - return rc; -} - /* If no buffer passed in, then caller wants to do the copy as in the case of readpages so the SMB buffer must be freed by the caller */ @@ -1012,11 +937,16 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, READ_RSP *pSMBr = NULL; char *pReadData = NULL; int bytes_returned; + int wct; cFYI(1,("Reading %d bytes on fid %d",count,netfid)); + if(tcon->ses->capabilities & CAP_LARGE_FILES) + wct = 12; + else + wct = 10; /* old style read */ *nbytes = 0; - rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, + rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; @@ -1028,12 +958,23 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = netfid; pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); - pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); + if(wct == 12) + pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); + else if((lseek >> 32) > 0) /* can not handle this big offset for old */ + return -EIO; + pSMB->Remaining = 0; pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); pSMB->MaxCountHigh = cpu_to_le32(count >> 16); - pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ - + if(wct == 12) + pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ + else { + /* old style read */ + struct smb_com_readx_req * pSMBW = + (struct smb_com_readx_req *)pSMB; + pSMBW->ByteCount = 0; + } + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_reads); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b6c303f6373f..5ecda554f913 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1183,16 +1183,11 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, char *smb_read_data; char __user *current_offset; struct smb_com_read_rsp *pSMBr; - int use_old_read = FALSE; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; - if(pTcon->ses) - if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) - use_old_read = TRUE; - if (file->private_data == NULL) { FreeXid(xid); return -EBADF; @@ -1217,22 +1212,10 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, if (rc != 0) break; } - if(use_old_read) - rc = SMBLegacyRead(xid, pTcon, + rc = CIFSSMBRead(xid, pTcon, open_file->netfid, current_read_size, *poffset, &bytes_read, &smb_read_data); - else { - rc = CIFSSMBRead(xid, pTcon, - open_file->netfid, - current_read_size, *poffset, - &bytes_read, &smb_read_data); - if(rc == -EINVAL) { - use_old_read = TRUE; - rc = -EAGAIN; - continue; - } - } pSMBr = (struct smb_com_read_rsp *)smb_read_data; if (copy_to_user(current_offset, smb_read_data + 4 /* RFC1001 hdr */ @@ -1276,7 +1259,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, int xid; char *current_offset; struct cifsFileInfo *open_file; - int use_old_read = FALSE; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); @@ -1287,9 +1269,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, return -EBADF; } open_file = (struct cifsFileInfo *)file->private_data; - if(pTcon->ses) - if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) - use_old_read = TRUE; if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, ("attempting read on write only file instance")); @@ -1308,24 +1287,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, if (rc != 0) break; } - if(use_old_read) - rc = SMBLegacyRead(xid, pTcon, - open_file->netfid, - current_read_size, *poffset, - &bytes_read, ¤t_offset); - else { - rc = CIFSSMBRead(xid, pTcon, + rc = CIFSSMBRead(xid, pTcon, open_file->netfid, current_read_size, *poffset, &bytes_read, ¤t_offset); - /* check if server disavows support for - 64 bit offsets */ - if(rc == -EINVAL) { - rc = -EAGAIN; - use_old_read = TRUE; - continue; - } - } } if (rc || (bytes_read == 0)) { if (total_read) { @@ -1423,7 +1388,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, struct smb_com_read_rsp *pSMBr; struct pagevec lru_pvec; struct cifsFileInfo *open_file; - int use_old_read = FALSE; xid = GetXid(); if (file->private_data == NULL) { @@ -1433,9 +1397,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, open_file = (struct cifsFileInfo *)file->private_data; cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; - if(pTcon->ses) - if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) - use_old_read = TRUE; + pagevec_init(&lru_pvec, 0); for (i = 0; i < num_pages; ) { @@ -1481,22 +1443,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, break; } - if(use_old_read) - rc = SMBLegacyRead(xid, pTcon, + rc = CIFSSMBRead(xid, pTcon, open_file->netfid, read_size, offset, &bytes_read, &smb_read_data); - else { - rc = CIFSSMBRead(xid, pTcon, - open_file->netfid, - read_size, offset, - &bytes_read, &smb_read_data); - if(rc == -EINVAL) { - use_old_read = TRUE; - rc = -EAGAIN; - continue; - } - } /* BB more RC checks ? */ if (rc== -EAGAIN) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0485c6d6ecd5..0fbe02ebc033 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -169,6 +169,10 @@ int cifs_get_inode_info_unix(struct inode **pinode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop->lock = NULL; inode->i_data.a_ops = &cifs_addr_ops; + /* check if server can support readpages */ + if(pTcon->ses->server->maxBuf < + 4096 + MAX_CIFS_HDR_SIZE) + inode->i_data.a_ops->readpages = NULL; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode")); inode->i_op = &cifs_dir_inode_ops; @@ -384,6 +388,9 @@ int cifs_get_inode_info(struct inode **pinode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop->lock = NULL; inode->i_data.a_ops = &cifs_addr_ops; + if(pTcon->ses->server->maxBuf < + 4096 + MAX_CIFS_HDR_SIZE) + inode->i_data.a_ops->readpages = NULL; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode ")); inode->i_op = &cifs_dir_inode_ops; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9780f4ee7f12..a1e8dc901de4 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -200,7 +200,10 @@ static void fill_in_inode(struct inode *tmp_inode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) tmp_inode->i_fop->lock = NULL; tmp_inode->i_data.a_ops = &cifs_addr_ops; - + if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && + (cifs_sb->tcon->ses->server->maxBuf < + 4096 + MAX_CIFS_HDR_SIZE)) + tmp_inode->i_data.a_ops->readpages = NULL; if(isNewInode) return; /* No sense invalidating pages for new inode since have not started caching readahead file @@ -306,6 +309,10 @@ static void unix_fill_in_inode(struct inode *tmp_inode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) tmp_inode->i_fop->lock = NULL; tmp_inode->i_data.a_ops = &cifs_addr_ops; + if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && + (cifs_sb->tcon->ses->server->maxBuf < + 4096 + MAX_CIFS_HDR_SIZE)) + tmp_inode->i_data.a_ops->readpages = NULL; if(isNewInode) return; /* No sense invalidating pages for new inode since we From 25732ad493b22b7d9f0d250c5a9ad17219f96a47 Mon Sep 17 00:00:00 2001 From: Bruce Losure Date: Fri, 2 Sep 2005 15:16:35 -0500 Subject: [PATCH 0044/1940] [IA64] Altix patch for fpga reset 1) workaround a h/w reset issue 2) to improve the determination of FPGA-based h/w in the arch/ia64/sn/kernel/tiocx code. Signed-off-by: Bruce Losure Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/tiocx.c | 58 +++++++++++++++++++----------------- include/asm-ia64/sn/l1.h | 12 ++++++++ include/asm-ia64/sn/sn_sal.h | 43 ++++++++++++++++++++++++++ include/asm-ia64/sn/tiocx.h | 3 +- 4 files changed, 88 insertions(+), 28 deletions(-) diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 254fe15c064b..d8664715764b 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -183,11 +183,12 @@ int cx_driver_unregister(struct cx_drv *cx_driver) * @part_num: device's part number * @mfg_num: device's manufacturer number * @hubdev: hub info associated with this device + * @bt: board type of the device * */ int cx_device_register(nasid_t nasid, int part_num, int mfg_num, - struct hubdev_info *hubdev) + struct hubdev_info *hubdev, int bt) { struct cx_dev *cx_dev; @@ -200,6 +201,7 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->cx_id.mfg_num = mfg_num; cx_dev->cx_id.nasid = nasid; cx_dev->hubdev = hubdev; + cx_dev->bt = bt; cx_dev->dev.parent = NULL; cx_dev->dev.bus = &tiocx_bus_type; @@ -238,7 +240,8 @@ static int cx_device_reload(struct cx_dev *cx_dev) { cx_device_unregister(cx_dev); return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, - cx_dev->cx_id.mfg_num, cx_dev->hubdev); + cx_dev->cx_id.mfg_num, cx_dev->hubdev, + cx_dev->bt); } static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, @@ -365,26 +368,20 @@ static void tio_corelet_reset(nasid_t nasid, int corelet) udelay(2000); } -static int tiocx_btchar_get(int nasid) +static int is_fpga_tio(int nasid, int *bt) { - moduleid_t module_id; - geoid_t geoid; - int cnodeid; + int ioboard_type; - cnodeid = nasid_to_cnodeid(nasid); - geoid = cnodeid_get_geoid(cnodeid); - module_id = geo_module(geoid); - return MODULE_GET_BTCHAR(module_id); -} + ioboard_type = ia64_sn_sysctl_ioboard_get(nasid); -static int is_fpga_brick(int nasid) -{ - switch (tiocx_btchar_get(nasid)) { + switch (ioboard_type) { case L1_BRICKTYPE_SA: case L1_BRICKTYPE_ATHENA: - case L1_BRICKTYPE_DAYTONA: + case L1_BOARDTYPE_DAYTONA: + *bt = ioboard_type; return 1; } + return 0; } @@ -407,16 +404,22 @@ static int tiocx_reload(struct cx_dev *cx_dev) if (bitstream_loaded(nasid)) { uint64_t cx_id; + int rv; - cx_id = - *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + + rv = ia64_sn_sysctl_tio_clock_reset(nasid); + if (rv) { + printk(KERN_ALERT "CX port JTAG reset failed.\n"); + } else { + cx_id = *(volatile uint64_t *) + (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + WIDGET_ID); - part_num = XWIDGET_PART_NUM(cx_id); - mfg_num = XWIDGET_MFG_NUM(cx_id); - DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num); - /* just ignore it if it's a CE */ - if (part_num == TIO_CE_ASIC_PARTNUM) - return 0; + part_num = XWIDGET_PART_NUM(cx_id); + mfg_num = XWIDGET_MFG_NUM(cx_id); + DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num); + /* just ignore it if it's a CE */ + if (part_num == TIO_CE_ASIC_PARTNUM) + return 0; + } } cx_dev->cx_id.part_num = part_num; @@ -436,10 +439,10 @@ static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *a { struct cx_dev *cx_dev = to_cx_dev(dev); - return sprintf(buf, "0x%x 0x%x 0x%x %d\n", + return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n", cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, - tiocx_btchar_get(cx_dev->cx_id.nasid)); + cx_dev->bt); } static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf, @@ -488,11 +491,12 @@ static int __init tiocx_init(void) for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { nasid_t nasid; + int bt; if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) break; /* No more nasids .. bail out of loop */ - if ((nasid & 0x1) && is_fpga_brick(nasid)) { + if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) { struct hubdev_info *hubdev; struct xwidget_info *widgetp; @@ -512,7 +516,7 @@ static int __init tiocx_init(void) if (cx_device_register (nasid, widgetp->xwi_hwid.part_num, - widgetp->xwi_hwid.mfg_num, hubdev) < 0) + widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0) return -ENXIO; else found_tiocx_device++; diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h index 2e5f0aa38889..e3b819110d47 100644 --- a/include/asm-ia64/sn/l1.h +++ b/include/asm-ia64/sn/l1.h @@ -35,4 +35,16 @@ #define L1_BRICKTYPE_ATHENA 0x2b /* + */ #define L1_BRICKTYPE_DAYTONA 0x7a /* z */ +/* board type response codes */ +#define L1_BOARDTYPE_IP69 0x0100 /* CA */ +#define L1_BOARDTYPE_IP63 0x0200 /* CB */ +#define L1_BOARDTYPE_BASEIO 0x0300 /* IB */ +#define L1_BOARDTYPE_PCIE2SLOT 0x0400 /* IC */ +#define L1_BOARDTYPE_PCIX3SLOT 0x0500 /* ID */ +#define L1_BOARDTYPE_PCIXPCIE4SLOT 0x0600 /* IE */ +#define L1_BOARDTYPE_ABACUS 0x0700 /* AB */ +#define L1_BOARDTYPE_DAYTONA 0x0800 /* AD */ +#define L1_BOARDTYPE_INVAL (-1) /* invalid brick type */ + + #endif /* _ASM_IA64_SN_L1_H */ diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index e67825ad1930..6f96ae8b4fbe 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -47,6 +47,7 @@ #define SN_SAL_CONSOLE_PUTB 0x02000028 #define SN_SAL_CONSOLE_XMIT_CHARS 0x0200002a #define SN_SAL_CONSOLE_READC 0x0200002b +#define SN_SAL_SYSCTL_OP 0x02000030 #define SN_SAL_SYSCTL_MODID_GET 0x02000031 #define SN_SAL_SYSCTL_GET 0x02000032 #define SN_SAL_SYSCTL_IOBRICK_MODULE_GET 0x02000033 @@ -97,6 +98,13 @@ #define SAL_INTR_ALLOC 1 #define SAL_INTR_FREE 2 +/* + * operations available on the generic SN_SAL_SYSCTL_OP + * runtime service + */ +#define SAL_SYSCTL_OP_IOBOARD 0x0001 /* retrieve board type */ +#define SAL_SYSCTL_OP_TIO_JLCK_RST 0x0002 /* issue TIO clock reset */ + /* * IRouter (i.e. generalized system controller) operations */ @@ -876,6 +884,41 @@ ia64_sn_sysctl_event_init(nasid_t nasid) return (int) rv.v0; } +/* + * Ask the system controller on the specified nasid to reset + * the CX corelet clock. Only valid on TIO nodes. + */ +static inline int +ia64_sn_sysctl_tio_clock_reset(nasid_t nasid) +{ + struct ia64_sal_retval rv; + SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST, + nasid, 0, 0, 0, 0, 0); + if (rv.status != 0) + return (int)rv.status; + if (rv.v0 != 0) + return (int)rv.v0; + + return 0; +} + +/* + * Get the associated ioboard type for a given nasid. + */ +static inline int +ia64_sn_sysctl_ioboard_get(nasid_t nasid) +{ + struct ia64_sal_retval rv; + SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD, + nasid, 0, 0, 0, 0, 0); + if (rv.v0 != 0) + return (int)rv.v0; + if (rv.v1 != 0) + return (int)rv.v1; + + return 0; +} + /** * ia64_sn_get_fit_compt - read a FIT entry from the PROM header * @nasid: NASID of node to read diff --git a/include/asm-ia64/sn/tiocx.h b/include/asm-ia64/sn/tiocx.h index c5447a504509..5699e75e5024 100644 --- a/include/asm-ia64/sn/tiocx.h +++ b/include/asm-ia64/sn/tiocx.h @@ -19,6 +19,7 @@ struct cx_id_s { struct cx_dev { struct cx_id_s cx_id; + int bt; /* board/blade type */ void *soft; /* driver specific */ struct hubdev_info *hubdev; struct device dev; @@ -59,7 +60,7 @@ struct cx_drv { extern struct sn_irq_info *tiocx_irq_alloc(nasid_t, int, int, nasid_t, int); extern void tiocx_irq_free(struct sn_irq_info *); extern int cx_device_unregister(struct cx_dev *); -extern int cx_device_register(nasid_t, int, int, struct hubdev_info *); +extern int cx_device_register(nasid_t, int, int, struct hubdev_info *, int); extern int cx_driver_unregister(struct cx_drv *); extern int cx_driver_register(struct cx_drv *); extern uint64_t tiocx_dma_addr(uint64_t addr); From 9a899e76683639486846ce17dbaa0c2ec1ae5ab5 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 6 Sep 2005 15:55:49 -0700 Subject: [PATCH 0045/1940] [CIFS] Update cifs TODO list with additional new features that have been requested. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/TODO | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 8cc881694e29..0593f6447319 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO @@ -1,4 +1,4 @@ -version 1.34 April 29, 2005 +version 1.36 September 6, 2005 A Partial List of Missing Features ================================== @@ -7,15 +7,15 @@ Contributions are welcome. There are plenty of opportunities for visible, important contributions to this module. Here is a partial list of the known problems and missing features: -a) Support for SecurityDescriptors for chmod/chgrp/chown so -these can be supported for Windows servers +a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown +so that these operations can be supported to Windows servers -b) Better pam/winbind integration (e.g. to handle uid mapping +b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS +SecurityDescriptors + +c) Better pam/winbind integration (e.g. to handle uid mapping better) -c) multi-user mounts - multiplexed sessionsetups over single vc -(ie tcp session) - more testing needed - d) Kerberos/SPNEGO session setup support - (started) e) NTLMv2 authentication (mostly implemented) @@ -29,12 +29,17 @@ f) Directory entry caching relies on a 1 second timer, rather than using FindNotify or equivalent. - (started) g) A few byte range testcases fail due to POSIX vs. Windows/CIFS -style byte range lock differences +style byte range lock differences. Save byte range locks so +reconnect can replay them. -h) quota support +h) Support unlock all (unlock 0,MAX_OFFSET) +by unlocking all known byte range locks that we locked on the file. + +i) quota support (needs minor kernel change since quota calls +to make it to network filesystems or deviceless filesystems) j) finish writepages support (multi-page write behind for improved -performance) and syncpage +performance) and syncpage. Started by Shaggy. k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the extra copy in/out of the socket buffers in some cases. @@ -57,20 +62,18 @@ p) Add support for storing symlink and fifo info to Windows servers in the Extended Attribute format their SFU clients would recognize. q) Finish fcntl D_NOTIFY support so kde and gnome file list windows -will autorefresh (started) +will autorefresh (partially complete by Asser). Needs minor kernel +vfs change to support removing D_NOTIFY on a file. r) Add GUI tool to configure /proc/fs/cifs settings and for display of the CIFS statistics (started) -q) implement support for security and trusted categories of xattrs +s) implement support for security and trusted categories of xattrs (requires minor protocol extension) to enable better support for SELINUX -r) Implement O_DIRECT flag on open (already supported on mount) +t) Implement O_DIRECT flag on open (already supported on mount) -s) Allow remapping of last remaining character (\) to +0xF000 which -(this character is valid for POSIX but not for Windows) - -t) Create UID mapping facility so server UIDs can be mapped on a per +u) Create UID mapping facility so server UIDs can be mapped on a per mount or a per server basis to client UIDs or nobody if no mapping exists. This is helpful when Unix extensions are negotiated to allow better permission checking when UIDs differ on the server @@ -78,6 +81,17 @@ and client. Add new protocol request to the CIFS protocol standard for asking the server for the corresponding name of a particular uid. +v) Add support for CIFS Unix and also the newer POSIX extensions to the +server side for Samba 4. + +w) Finish up the dos time conversion routines needed to return old server +time to the client (default time, of now or time 0 is used now for these +very old servers) + +x) Add support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) + +y) Finish testing of Windows 9x/Windows ME server support (started). + KNOWN BUGS (updated April 29, 2005) ==================================== See http://bugzilla.samba.org - search on product "CifsVFS" for From a607c38971fd078865fa9bef39e6c1d4435680c8 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Thu, 1 Sep 2005 14:01:37 -0500 Subject: [PATCH 0046/1940] [IA64-SGI] get XPC to cleanly disengage from remote memory references When XPC is being shutdown (i.e., rmmod, reboot) it doesn't ensure that other partitions with whom it was connected have completely disengaged from any attempt at cross-partition memory references. This can lead to MCAs in any of these other partitions when the partition is reset. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/xpc.h | 288 +++++++++++++++++++++++-- arch/ia64/sn/kernel/xpc_channel.c | 222 +++++++++++--------- arch/ia64/sn/kernel/xpc_main.c | 242 +++++++++++++++------ arch/ia64/sn/kernel/xpc_partition.c | 314 +++++++++++++++++++++++----- include/asm-ia64/sn/xp.h | 10 +- 5 files changed, 830 insertions(+), 246 deletions(-) diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index d0ee635daf2e..565822ab3d08 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h @@ -57,7 +57,7 @@ #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2) #define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */ -#define XPC_HB_CHECK_DEFAULT_TIMEOUT 20 /* check HB every x secs */ +#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */ /* define the process name of HB checker and the CPU it is pinned to */ #define XPC_HB_CHECK_THREAD_NAME "xpc_hb" @@ -67,11 +67,6 @@ #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" -#define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p))) -#define XPC_ALLOW_HB(_p, _v) (_v)->heartbeating_to_mask |= (1UL << (_p)) -#define XPC_DISALLOW_HB(_p, _v) (_v)->heartbeating_to_mask &= (~(1UL << (_p))) - - /* * Reserved Page provided by SAL. * @@ -88,14 +83,38 @@ struct xpc_rsvd_page { u8 version; u8 pad[6]; /* pad to u64 align */ volatile u64 vars_pa; + struct timespec stamp; /* time when reserved page was initialized */ u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; }; -#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */ #define XPC_RSVD_PAGE_ALIGNED_SIZE \ (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))) +#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */ + +#define XPC_SUPPORTS_RP_STAMP(_version) \ + (_version >= _XPC_VERSION(1,1)) + +/* + * compare stamps - the return value is: + * + * < 0, if stamp1 < stamp2 + * = 0, if stamp1 == stamp2 + * > 0, if stamp1 > stamp2 + */ +static inline int +xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2) +{ + int ret; + + + if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) { + ret = stamp1->tv_nsec - stamp2->tv_nsec; + } + return ret; +} + /* * Define the structures by which XPC variables can be exported to other @@ -121,12 +140,61 @@ struct xpc_vars { u64 vars_part_pa; u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ - AMO_t *act_amos; /* pointer to the first activation AMO */ }; -#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */ #define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars))) +#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */ + +#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ + (_version >= _XPC_VERSION(3,1)) + + +static inline int +xpc_hb_allowed(partid_t partid, struct xpc_vars *vars) +{ + return ((vars->heartbeating_to_mask & (1UL << partid)) != 0); +} + +static inline void +xpc_allow_hb(partid_t partid, struct xpc_vars *vars) +{ + u64 old_mask, new_mask; + + do { + old_mask = vars->heartbeating_to_mask; + new_mask = (old_mask | (1UL << partid)); + } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != + old_mask); +} + +static inline void +xpc_disallow_hb(partid_t partid, struct xpc_vars *vars) +{ + u64 old_mask, new_mask; + + do { + old_mask = vars->heartbeating_to_mask; + new_mask = (old_mask & ~(1UL << partid)); + } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != + old_mask); +} + + +/* + * The AMOs page consists of a number of AMO variables which are divided into + * four groups, The first two groups are used to identify an IRQ's sender. + * These two groups consist of 64 and 16 AMO variables respectively. The last + * two groups, consisting of just one AMO variable each, are used to identify + * the remote partitions that are currently engaged (from the viewpoint of + * the XPC running on the remote partition). + */ +#define XPC_NOTIFY_IRQ_AMOS 0 +#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS) +#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS) +#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1) + + /* * The following structure describes the per partition specific variables. * @@ -358,7 +426,7 @@ struct xpc_channel { void *key; /* pointer to user's key */ struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ - struct semaphore teardown_sema; /* wait for teardown completion */ + struct semaphore wdisconnect_sema; /* wait for channel disconnect */ struct xpc_openclose_args *local_openclose_args; /* args passed on */ /* opening or closing of channel */ @@ -410,6 +478,7 @@ struct xpc_channel { #define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ #define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ +#define XPC_C_WDISCONNECT 0x00008000 /* waiting for channel disconnect */ @@ -422,6 +491,8 @@ struct xpc_partition { /* XPC HB infrastructure */ + u8 remote_rp_version; /* version# of partition's rsvd pg */ + struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */ u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ u64 remote_vars_pa; /* phys addr of partition's vars */ u64 remote_vars_part_pa; /* phys addr of partition's vars part */ @@ -432,10 +503,14 @@ struct xpc_partition { u32 act_IRQ_rcvd; /* IRQs since activation */ spinlock_t act_lock; /* protect updating of act_state */ u8 act_state; /* from XPC HB viewpoint */ + u8 remote_vars_version; /* version# of partition's vars */ enum xpc_retval reason; /* reason partition is deactivating */ int reason_line; /* line# deactivation initiated from */ int reactivate_nasid; /* nasid in partition to reactivate */ + unsigned long disengage_request_timeout; /* timeout in XPC_TICKS */ + struct timer_list disengage_request_timer; + /* XPC infrastructure referencing and teardown control */ @@ -454,6 +529,7 @@ struct xpc_partition { u8 nchannels; /* #of defined channels supported */ atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */ + atomic_t nchannels_engaged;/* #of channels engaged with remote part */ struct xpc_channel *channels;/* array of channel structures */ void *local_GPs_base; /* base address of kmalloc'd space */ @@ -518,6 +594,7 @@ struct xpc_partition { #define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */ + /* * struct xpc_partition IPI_timer #of seconds to wait before checking for * dropped IPIs. These occur whenever an IPI amo write doesn't complete until @@ -526,6 +603,13 @@ struct xpc_partition { #define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ) +/* number of seconds to wait for other partitions to disengage */ +#define XPC_DISENGAGE_REQUEST_TIMELIMIT 90 + +/* interval in seconds to print 'waiting disengagement' messages */ +#define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 + + #define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) @@ -550,8 +634,6 @@ extern void xpc_activate_partition(struct xpc_partition *); /* found in xpc_partition.c */ extern int xpc_exiting; -extern int xpc_hb_interval; -extern int xpc_hb_check_interval; extern struct xpc_vars *xpc_vars; extern struct xpc_rsvd_page *xpc_rsvd_page; extern struct xpc_vars_part *xpc_vars_part; @@ -561,6 +643,7 @@ extern struct xpc_rsvd_page *xpc_rsvd_page_init(void); extern void xpc_allow_IPI_ops(void); extern void xpc_restrict_IPI_ops(void); extern int xpc_identify_act_IRQ_sender(void); +extern int xpc_partition_disengaged(struct xpc_partition *); extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *); extern void xpc_mark_partition_inactive(struct xpc_partition *); extern void xpc_discovery(void); @@ -585,8 +668,8 @@ extern void xpc_connected_callout(struct xpc_channel *); extern void xpc_deliver_msg(struct xpc_channel *); extern void xpc_disconnect_channel(const int, struct xpc_channel *, enum xpc_retval, unsigned long *); -extern void xpc_disconnected_callout(struct xpc_channel *); -extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval); +extern void xpc_disconnecting_callout(struct xpc_channel *); +extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); extern void xpc_teardown_infrastructure(struct xpc_partition *); @@ -673,6 +756,157 @@ xpc_part_ref(struct xpc_partition *part) +/* + * This next set of inlines are used to keep track of when a partition is + * potentially engaged in accessing memory belonging to another partition. + */ + +static inline void +xpc_mark_partition_engaged(struct xpc_partition *part) +{ + unsigned long irq_flags; + AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + + (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); + + + local_irq_save(irq_flags); + + /* set bit corresponding to our partid in remote partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, + (1UL << sn_partition_id)); + /* + * We must always use the nofault function regardless of whether we + * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we + * didn't, we'd never know that the other partition is down and would + * keep sending IPIs and AMOs to it until the heartbeat times out. + */ + (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> + variable), xp_nofault_PIOR_target)); + + local_irq_restore(irq_flags); +} + +static inline void +xpc_mark_partition_disengaged(struct xpc_partition *part) +{ + unsigned long irq_flags; + AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + + (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); + + + local_irq_save(irq_flags); + + /* clear bit corresponding to our partid in remote partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, + ~(1UL << sn_partition_id)); + /* + * We must always use the nofault function regardless of whether we + * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we + * didn't, we'd never know that the other partition is down and would + * keep sending IPIs and AMOs to it until the heartbeat times out. + */ + (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> + variable), xp_nofault_PIOR_target)); + + local_irq_restore(irq_flags); +} + +static inline void +xpc_request_partition_disengage(struct xpc_partition *part) +{ + unsigned long irq_flags; + AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + + (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); + + + local_irq_save(irq_flags); + + /* set bit corresponding to our partid in remote partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, + (1UL << sn_partition_id)); + /* + * We must always use the nofault function regardless of whether we + * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we + * didn't, we'd never know that the other partition is down and would + * keep sending IPIs and AMOs to it until the heartbeat times out. + */ + (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> + variable), xp_nofault_PIOR_target)); + + local_irq_restore(irq_flags); +} + +static inline void +xpc_cancel_partition_disengage_request(struct xpc_partition *part) +{ + unsigned long irq_flags; + AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + + (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); + + + local_irq_save(irq_flags); + + /* clear bit corresponding to our partid in remote partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, + ~(1UL << sn_partition_id)); + /* + * We must always use the nofault function regardless of whether we + * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we + * didn't, we'd never know that the other partition is down and would + * keep sending IPIs and AMOs to it until the heartbeat times out. + */ + (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> + variable), xp_nofault_PIOR_target)); + + local_irq_restore(irq_flags); +} + +static inline u64 +xpc_partition_engaged(u64 partid_mask) +{ + AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; + + + /* return our partition's AMO variable ANDed with partid_mask */ + return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & + partid_mask); +} + +static inline u64 +xpc_partition_disengage_requested(u64 partid_mask) +{ + AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; + + + /* return our partition's AMO variable ANDed with partid_mask */ + return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & + partid_mask); +} + +static inline void +xpc_clear_partition_engaged(u64 partid_mask) +{ + AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; + + + /* clear bit(s) based on partid_mask in our partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, + ~partid_mask); +} + +static inline void +xpc_clear_partition_disengage_request(u64 partid_mask) +{ + AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; + + + /* clear bit(s) based on partid_mask in our partition's AMO */ + FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, + ~partid_mask); +} + + + /* * The following set of macros and inlines are used for the sending and * receiving of IPIs (also known as IRQs). There are two flavors of IPIs, @@ -722,13 +956,13 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) * Flag the appropriate AMO variable and send an IPI to the specified node. */ static inline void -xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid, +xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid, int to_phys_cpuid) { int w_index = XPC_NASID_W_INDEX(from_nasid); int b_index = XPC_NASID_B_INDEX(from_nasid); - AMO_t *amos = (AMO_t *) __va(amos_page + - (XP_MAX_PARTITIONS * sizeof(AMO_t))); + AMO_t *amos = (AMO_t *) __va(amos_page_pa + + (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t))); (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid, @@ -756,6 +990,13 @@ xpc_IPI_send_reactivate(struct xpc_partition *part) xpc_vars->act_nasid, xpc_vars->act_phys_cpuid); } +static inline void +xpc_IPI_send_disengage(struct xpc_partition *part) +{ + xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), + part->remote_act_nasid, part->remote_act_phys_cpuid); +} + /* * IPIs associated with SGI_XPC_NOTIFY IRQ. @@ -903,17 +1144,18 @@ xpc_IPI_send_local_msgrequest(struct xpc_channel *ch) * cacheable mapping for the entire region. This will prevent speculative * reading of cached copies of our lines from being issued which will cause * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 - * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c) - * and an additional 16 AMO variables for partition activation (xpc_hb.c). + * (XP_MAX_PARTITIONS) AMO variables for message notification and an + * additional 16 (XP_NASID_MASK_WORDS) AMO variables for partition activation + * and 2 AMO variables for partition deactivation. */ static inline AMO_t * -xpc_IPI_init(partid_t partid) +xpc_IPI_init(int index) { - AMO_t *part_amo = xpc_vars->amos_page + partid; + AMO_t *amo = xpc_vars->amos_page + index; - xpc_IPI_receive(part_amo); - return part_amo; + (void) xpc_IPI_receive(amo); /* clear AMO variable */ + return amo; } diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 94698bea7be0..195ac1b8e262 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c @@ -57,6 +57,7 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid) spin_lock_init(&ch->lock); sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ + sema_init(&ch->wdisconnect_sema, 0); /* event wait */ atomic_set(&ch->n_on_msg_allocate_wq, 0); init_waitqueue_head(&ch->msg_allocate_wq); @@ -166,6 +167,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) xpc_initialize_channels(part, partid); atomic_set(&part->nchannels_active, 0); + atomic_set(&part->nchannels_engaged, 0); /* local_IPI_amo were set to 0 by an earlier memset() */ @@ -555,8 +557,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch) sema_init(&ch->notify_queue[i].sema, 0); } - sema_init(&ch->teardown_sema, 0); /* event wait */ - spin_lock_irqsave(&ch->lock, irq_flags); ch->flags |= XPC_C_SETUP; spin_unlock_irqrestore(&ch->lock, irq_flags); @@ -625,6 +625,55 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) } +/* + * Notify those who wanted to be notified upon delivery of their message. + */ +static void +xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put) +{ + struct xpc_notify *notify; + u8 notify_type; + s64 get = ch->w_remote_GP.get - 1; + + + while (++get < put && atomic_read(&ch->n_to_notify) > 0) { + + notify = &ch->notify_queue[get % ch->local_nentries]; + + /* + * See if the notify entry indicates it was associated with + * a message who's sender wants to be notified. It is possible + * that it is, but someone else is doing or has done the + * notification. + */ + notify_type = notify->type; + if (notify_type == 0 || + cmpxchg(¬ify->type, notify_type, 0) != + notify_type) { + continue; + } + + DBUG_ON(notify_type != XPC_N_CALL); + + atomic_dec(&ch->n_to_notify); + + if (notify->func != NULL) { + dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, " + "msg_number=%ld, partid=%d, channel=%d\n", + (void *) notify, get, ch->partid, ch->number); + + notify->func(reason, ch->partid, ch->number, + notify->key); + + dev_dbg(xpc_chan, "notify->func() returned, " + "notify=0x%p, msg_number=%ld, partid=%d, " + "channel=%d\n", (void *) notify, get, + ch->partid, ch->number); + } + } +} + + /* * Free up message queues and other stuff that were allocated for the specified * channel. @@ -669,9 +718,6 @@ xpc_free_msgqueues(struct xpc_channel *ch) ch->remote_msgqueue = NULL; kfree(ch->notify_queue); ch->notify_queue = NULL; - - /* in case someone is waiting for the teardown to complete */ - up(&ch->teardown_sema); } } @@ -683,7 +729,7 @@ static void xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) { struct xpc_partition *part = &xpc_partitions[ch->partid]; - u32 ch_flags = ch->flags; + u32 channel_was_connected = (ch->flags & XPC_C_WASCONNECTED); DBUG_ON(!spin_is_locked(&ch->lock)); @@ -701,12 +747,13 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) } DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); - /* it's now safe to free the channel's message queues */ + if (part->act_state == XPC_P_DEACTIVATING) { + /* can't proceed until the other side disengages from us */ + if (xpc_partition_engaged(1UL << ch->partid)) { + return; + } - xpc_free_msgqueues(ch); - DBUG_ON(ch->flags & XPC_C_SETUP); - - if (part->act_state != XPC_P_DEACTIVATING) { + } else { /* as long as the other side is up do the full protocol */ @@ -724,16 +771,33 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) } } + /* wake those waiting for notify completion */ + if (atomic_read(&ch->n_to_notify) > 0) { + /* >>> we do callout while holding ch->lock */ + xpc_notify_senders(ch, ch->reason, ch->w_local_GP.put); + } + /* both sides are disconnected now */ - ch->flags = XPC_C_DISCONNECTED; /* clear all flags, but this one */ + /* it's now safe to free the channel's message queues */ + xpc_free_msgqueues(ch); + + /* mark disconnected, clear all other flags except XPC_C_WDISCONNECT */ + ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT)); atomic_dec(&part->nchannels_active); - if (ch_flags & XPC_C_WASCONNECTED) { + if (channel_was_connected) { dev_info(xpc_chan, "channel %d to partition %d disconnected, " "reason=%d\n", ch->number, ch->partid, ch->reason); } + + /* wake the thread that is waiting for this channel to disconnect */ + if (ch->flags & XPC_C_WDISCONNECT) { + spin_unlock_irqrestore(&ch->lock, *irq_flags); + up(&ch->wdisconnect_sema); + spin_lock_irqsave(&ch->lock, *irq_flags); + } } @@ -764,7 +828,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, /* * If RCLOSEREQUEST is set, we're probably waiting for * RCLOSEREPLY. We should find it and a ROPENREQUEST packed - * with this RCLOSEQREUQEST in the IPI_flags. + * with this RCLOSEREQUEST in the IPI_flags. */ if (ch->flags & XPC_C_RCLOSEREQUEST) { @@ -852,7 +916,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, "channel=%d\n", args->msg_size, args->local_nentries, ch->partid, ch->number); - if ((ch->flags & XPC_C_DISCONNECTING) || + if ((ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) || part->act_state == XPC_P_DEACTIVATING) { spin_unlock_irqrestore(&ch->lock, irq_flags); return; @@ -1039,55 +1103,6 @@ xpc_connect_channel(struct xpc_channel *ch) } -/* - * Notify those who wanted to be notified upon delivery of their message. - */ -static void -xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put) -{ - struct xpc_notify *notify; - u8 notify_type; - s64 get = ch->w_remote_GP.get - 1; - - - while (++get < put && atomic_read(&ch->n_to_notify) > 0) { - - notify = &ch->notify_queue[get % ch->local_nentries]; - - /* - * See if the notify entry indicates it was associated with - * a message who's sender wants to be notified. It is possible - * that it is, but someone else is doing or has done the - * notification. - */ - notify_type = notify->type; - if (notify_type == 0 || - cmpxchg(¬ify->type, notify_type, 0) != - notify_type) { - continue; - } - - DBUG_ON(notify_type != XPC_N_CALL); - - atomic_dec(&ch->n_to_notify); - - if (notify->func != NULL) { - dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, " - "msg_number=%ld, partid=%d, channel=%d\n", - (void *) notify, get, ch->partid, ch->number); - - notify->func(reason, ch->partid, ch->number, - notify->key); - - dev_dbg(xpc_chan, "notify->func() returned, " - "notify=0x%p, msg_number=%ld, partid=%d, " - "channel=%d\n", (void *) notify, get, - ch->partid, ch->number); - } - } -} - - /* * Clear some of the msg flags in the local message queue. */ @@ -1240,6 +1255,7 @@ xpc_process_channel_activity(struct xpc_partition *part) u64 IPI_amo, IPI_flags; struct xpc_channel *ch; int ch_number; + u32 ch_flags; IPI_amo = xpc_get_IPI_flags(part); @@ -1266,8 +1282,9 @@ xpc_process_channel_activity(struct xpc_partition *part) xpc_process_openclose_IPI(part, ch_number, IPI_flags); } + ch_flags = ch->flags; /* need an atomic snapshot of flags */ - if (ch->flags & XPC_C_DISCONNECTING) { + if (ch_flags & XPC_C_DISCONNECTING) { spin_lock_irqsave(&ch->lock, irq_flags); xpc_process_disconnect(ch, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); @@ -1278,9 +1295,9 @@ xpc_process_channel_activity(struct xpc_partition *part) continue; } - if (!(ch->flags & XPC_C_CONNECTED)) { - if (!(ch->flags & XPC_C_OPENREQUEST)) { - DBUG_ON(ch->flags & XPC_C_SETUP); + if (!(ch_flags & XPC_C_CONNECTED)) { + if (!(ch_flags & XPC_C_OPENREQUEST)) { + DBUG_ON(ch_flags & XPC_C_SETUP); (void) xpc_connect_channel(ch); } else { spin_lock_irqsave(&ch->lock, irq_flags); @@ -1305,8 +1322,8 @@ xpc_process_channel_activity(struct xpc_partition *part) /* - * XPC's heartbeat code calls this function to inform XPC that a partition has - * gone down. XPC responds by tearing down the XPartition Communication + * XPC's heartbeat code calls this function to inform XPC that a partition is + * going down. XPC responds by tearing down the XPartition Communication * infrastructure used for the just downed partition. * * XPC's heartbeat code will never call this function and xpc_partition_up() @@ -1314,7 +1331,7 @@ xpc_process_channel_activity(struct xpc_partition *part) * at the same time. */ void -xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason) +xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason) { unsigned long irq_flags; int ch_number; @@ -1330,12 +1347,11 @@ xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason) } - /* disconnect all channels associated with the downed partition */ + /* disconnect channels associated with the partition going down */ for (ch_number = 0; ch_number < part->nchannels; ch_number++) { ch = &part->channels[ch_number]; - xpc_msgqueue_ref(ch); spin_lock_irqsave(&ch->lock, irq_flags); @@ -1370,6 +1386,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part) * this partition. */ + DBUG_ON(atomic_read(&part->nchannels_engaged) != 0); DBUG_ON(atomic_read(&part->nchannels_active) != 0); DBUG_ON(part->setup_state != XPC_P_SETUP); part->setup_state = XPC_P_WTEARDOWN; @@ -1506,8 +1523,12 @@ xpc_initiate_disconnect(int ch_number) spin_lock_irqsave(&ch->lock, irq_flags); - XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering, + if (!(ch->flags & XPC_C_DISCONNECTED)) { + ch->flags |= XPC_C_WDISCONNECT; + + XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering, &irq_flags); + } spin_unlock_irqrestore(&ch->lock, irq_flags); @@ -1523,8 +1544,9 @@ xpc_initiate_disconnect(int ch_number) /* * To disconnect a channel, and reflect it back to all who may be waiting. * - * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by - * >>> xpc_free_msgqueues(). + * An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by + * xpc_process_disconnect(), and if set, XPC_C_WDISCONNECT is cleared by + * xpc_disconnect_wait(). * * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN. */ @@ -1532,7 +1554,7 @@ void xpc_disconnect_channel(const int line, struct xpc_channel *ch, enum xpc_retval reason, unsigned long *irq_flags) { - u32 flags; + u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED); DBUG_ON(!spin_is_locked(&ch->lock)); @@ -1547,37 +1569,28 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, XPC_SET_REASON(ch, reason, line); - flags = ch->flags; + ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING); /* some of these may not have been set */ ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY | XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | XPC_C_CONNECTING | XPC_C_CONNECTED); - ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING); xpc_IPI_send_closerequest(ch, irq_flags); - if (flags & XPC_C_CONNECTED) { + if (channel_was_connected) { ch->flags |= XPC_C_WASCONNECTED; } - if (atomic_read(&ch->kthreads_idle) > 0) { - /* wake all idle kthreads so they can exit */ - wake_up_all(&ch->idle_wq); - } - spin_unlock_irqrestore(&ch->lock, *irq_flags); - - /* wake those waiting to allocate an entry from the local msg queue */ - - if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) { - wake_up(&ch->msg_allocate_wq); + /* wake all idle kthreads so they can exit */ + if (atomic_read(&ch->kthreads_idle) > 0) { + wake_up_all(&ch->idle_wq); } - /* wake those waiting for notify completion */ - - if (atomic_read(&ch->n_to_notify) > 0) { - xpc_notify_senders(ch, reason, ch->w_local_GP.put); + /* wake those waiting to allocate an entry from the local msg queue */ + if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) { + wake_up(&ch->msg_allocate_wq); } spin_lock_irqsave(&ch->lock, *irq_flags); @@ -1585,23 +1598,24 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, void -xpc_disconnected_callout(struct xpc_channel *ch) +xpc_disconnecting_callout(struct xpc_channel *ch) { /* - * Let the channel's registerer know that the channel is now + * Let the channel's registerer know that the channel is being * disconnected. We don't want to do this if the registerer was never - * informed of a connection being made, unless the disconnect was for - * abnormal reasons. + * informed of a connection being made. */ if (ch->func != NULL) { - dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, " - "channel=%d\n", ch->reason, ch->partid, ch->number); + dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting," + " partid=%d, channel=%d\n", ch->partid, ch->number); - ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key); + ch->func(xpcDisconnecting, ch->partid, ch->number, NULL, + ch->key); - dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, " - "channel=%d\n", ch->reason, ch->partid, ch->number); + dev_dbg(xpc_chan, "ch->func() returned, reason=" + "xpcDisconnecting, partid=%d, channel=%d\n", + ch->partid, ch->number); } } @@ -1848,7 +1862,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, xpc_notify_func func, void *key) { enum xpc_retval ret = xpcSuccess; - struct xpc_notify *notify = NULL; // >>> to keep the compiler happy!! + struct xpc_notify *notify = notify; s64 put, msg_number = msg->number; diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index bb1d5cf30440..feece200b3c3 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -82,11 +83,13 @@ struct device *xpc_chan = &xpc_chan_dbg_subname; /* systune related variables for /proc/sys directories */ -static int xpc_hb_min = 1; -static int xpc_hb_max = 10; +static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; +static int xpc_hb_min_interval = 1; +static int xpc_hb_max_interval = 10; -static int xpc_hb_check_min = 10; -static int xpc_hb_check_max = 120; +static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL; +static int xpc_hb_check_min_interval = 10; +static int xpc_hb_check_max_interval = 120; static ctl_table xpc_sys_xpc_hb_dir[] = { { @@ -99,7 +102,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = { &proc_dointvec_minmax, &sysctl_intvec, NULL, - &xpc_hb_min, &xpc_hb_max + &xpc_hb_min_interval, + &xpc_hb_max_interval }, { 2, @@ -111,7 +115,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = { &proc_dointvec_minmax, &sysctl_intvec, NULL, - &xpc_hb_check_min, &xpc_hb_check_max + &xpc_hb_check_min_interval, + &xpc_hb_check_max_interval }, {0} }; @@ -148,11 +153,11 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); static unsigned long xpc_hb_check_timeout; -/* xpc_hb_checker thread exited notification */ -static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); +/* used as an indication of when the xpc_hb_checker thread is inactive */ +static DECLARE_MUTEX_LOCKED(xpc_hb_checker_inactive); -/* xpc_discovery thread exited notification */ -static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); +/* used as an indication of when the xpc_discovery thread is inactive */ +static DECLARE_MUTEX_LOCKED(xpc_discovery_inactive); static struct timer_list xpc_hb_timer; @@ -161,6 +166,30 @@ static struct timer_list xpc_hb_timer; static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *); +static int xpc_system_reboot(struct notifier_block *, unsigned long, void *); +static struct notifier_block xpc_reboot_notifier = { + .notifier_call = xpc_system_reboot, +}; + + +/* + * Timer function to enforce the timelimit on the partition disengage request. + */ +static void +xpc_timeout_partition_disengage_request(unsigned long data) +{ + struct xpc_partition *part = (struct xpc_partition *) data; + + + DBUG_ON(XPC_TICKS < part->disengage_request_timeout); + + (void) xpc_partition_disengaged(part); + + DBUG_ON(part->disengage_request_timeout != 0); + DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0); +} + + /* * Notify the heartbeat check thread that an IRQ has been received. */ @@ -214,12 +243,6 @@ xpc_hb_checker(void *ignore) while (!(volatile int) xpc_exiting) { - /* wait for IRQ or timeout */ - (void) wait_event_interruptible(xpc_act_IRQ_wq, - (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) || - jiffies >= xpc_hb_check_timeout || - (volatile int) xpc_exiting)); - dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have " "been received\n", (int) (xpc_hb_check_timeout - jiffies), @@ -240,6 +263,7 @@ xpc_hb_checker(void *ignore) } + /* check for outstanding IRQs */ new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd); if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) { force_IRQ = 0; @@ -257,13 +281,19 @@ xpc_hb_checker(void *ignore) xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ); } + + /* wait for IRQ or timeout */ + (void) wait_event_interruptible(xpc_act_IRQ_wq, + (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) || + jiffies >= xpc_hb_check_timeout || + (volatile int) xpc_exiting)); } dev_dbg(xpc_part, "heartbeat checker is exiting\n"); /* mark this thread as inactive */ - up(&xpc_hb_checker_exited); + up(&xpc_hb_checker_inactive); return 0; } @@ -283,7 +313,7 @@ xpc_initiate_discovery(void *ignore) dev_dbg(xpc_part, "discovery thread is exiting\n"); /* mark this thread as inactive */ - up(&xpc_discovery_exited); + up(&xpc_discovery_inactive); return 0; } @@ -309,7 +339,7 @@ xpc_make_first_contact(struct xpc_partition *part) "partition %d\n", XPC_PARTID(part)); /* wait a 1/4 of a second or so */ - msleep_interruptible(250); + (void) msleep_interruptible(250); if (part->act_state == XPC_P_DEACTIVATING) { return part->reason; @@ -336,7 +366,8 @@ static void xpc_channel_mgr(struct xpc_partition *part) { while (part->act_state != XPC_P_DEACTIVATING || - atomic_read(&part->nchannels_active) > 0) { + atomic_read(&part->nchannels_active) > 0 || + !xpc_partition_disengaged(part)) { xpc_process_channel_activity(part); @@ -360,7 +391,8 @@ xpc_channel_mgr(struct xpc_partition *part) (volatile u64) part->local_IPI_amo != 0 || ((volatile u8) part->act_state == XPC_P_DEACTIVATING && - atomic_read(&part->nchannels_active) == 0))); + atomic_read(&part->nchannels_active) == 0 && + xpc_partition_disengaged(part)))); atomic_set(&part->channel_mgr_requests, 1); // >>> Does it need to wakeup periodically as well? In case we @@ -482,7 +514,7 @@ xpc_activating(void *__partid) return 0; } - XPC_ALLOW_HB(partid, xpc_vars); + xpc_allow_hb(partid, xpc_vars); xpc_IPI_send_activated(part); @@ -492,6 +524,7 @@ xpc_activating(void *__partid) */ (void) xpc_partition_up(part); + xpc_disallow_hb(partid, xpc_vars); xpc_mark_partition_inactive(part); if (part->reason == xpcReactivating) { @@ -704,11 +737,14 @@ xpc_daemonize_kthread(void *args) xpc_kthread_waitmsgs(part, ch); } - if (atomic_dec_return(&ch->kthreads_assigned) == 0 && - ((ch->flags & XPC_C_CONNECTCALLOUT) || - (ch->reason != xpcUnregistering && - ch->reason != xpcOtherUnregistering))) { - xpc_disconnected_callout(ch); + if (atomic_dec_return(&ch->kthreads_assigned) == 0) { + if (ch->flags & XPC_C_CONNECTCALLOUT) { + xpc_disconnecting_callout(ch); + } + if (atomic_dec_return(&part->nchannels_engaged) == 0) { + xpc_mark_partition_disengaged(part); + xpc_IPI_send_disengage(part); + } } @@ -740,6 +776,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed) unsigned long irq_flags; pid_t pid; u64 args = XPC_PACK_ARGS(ch->partid, ch->number); + struct xpc_partition *part = &xpc_partitions[ch->partid]; while (needed-- > 0) { @@ -770,9 +807,13 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed) * kthread. That kthread is responsible for doing the * counterpart to the following before it exits. */ - (void) xpc_part_ref(&xpc_partitions[ch->partid]); + (void) xpc_part_ref(part); xpc_msgqueue_ref(ch); - atomic_inc(&ch->kthreads_assigned); + if (atomic_inc_return(&ch->kthreads_assigned) == 1) { + if (atomic_inc_return(&part->nchannels_engaged) == 1) { + xpc_mark_partition_engaged(part); + } + } ch->kthreads_created++; // >>> temporary debug only!!! } } @@ -781,6 +822,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed) void xpc_disconnect_wait(int ch_number) { + unsigned long irq_flags; partid_t partid; struct xpc_partition *part; struct xpc_channel *ch; @@ -793,10 +835,13 @@ xpc_disconnect_wait(int ch_number) if (xpc_part_ref(part)) { ch = &part->channels[ch_number]; -// >>> how do we keep from falling into the window between our check and going -// >>> down and coming back up where sema is re-inited? - if (ch->flags & XPC_C_SETUP) { - (void) down(&ch->teardown_sema); + if (ch->flags & XPC_C_WDISCONNECT) { + if (!(ch->flags & XPC_C_DISCONNECTED)) { + (void) down(&ch->wdisconnect_sema); + } + spin_lock_irqsave(&ch->lock, irq_flags); + ch->flags &= ~XPC_C_WDISCONNECT; + spin_unlock_irqrestore(&ch->lock, irq_flags); } xpc_part_deref(part); @@ -806,62 +851,89 @@ xpc_disconnect_wait(int ch_number) static void -xpc_do_exit(void) +xpc_do_exit(enum xpc_retval reason) { partid_t partid; int active_part_count; struct xpc_partition *part; + unsigned long printmsg_time; - /* now it's time to eliminate our heartbeat */ - del_timer_sync(&xpc_hb_timer); - xpc_vars->heartbeating_to_mask = 0; - - /* indicate to others that our reserved page is uninitialized */ - xpc_rsvd_page->vars_pa = 0; + /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ + DBUG_ON(xpc_exiting == 1); /* - * Ignore all incoming interrupts. Without interupts the heartbeat - * checker won't activate any new partitions that may come up. - */ - free_irq(SGI_XPC_ACTIVATE, NULL); - - /* - * Cause the heartbeat checker and the discovery threads to exit. - * We don't want them attempting to activate new partitions as we - * try to deactivate the existing ones. + * Let the heartbeat checker thread and the discovery thread + * (if one is running) know that they should exit. Also wake up + * the heartbeat checker thread in case it's sleeping. */ xpc_exiting = 1; wake_up_interruptible(&xpc_act_IRQ_wq); - /* wait for the heartbeat checker thread to mark itself inactive */ - down(&xpc_hb_checker_exited); + /* ignore all incoming interrupts */ + free_irq(SGI_XPC_ACTIVATE, NULL); /* wait for the discovery thread to mark itself inactive */ - down(&xpc_discovery_exited); + down(&xpc_discovery_inactive); + + /* wait for the heartbeat checker thread to mark itself inactive */ + down(&xpc_hb_checker_inactive); - msleep_interruptible(300); + /* sleep for a 1/3 of a second or so */ + (void) msleep_interruptible(300); /* wait for all partitions to become inactive */ + printmsg_time = jiffies; + do { active_part_count = 0; for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; - if (part->act_state != XPC_P_INACTIVE) { - active_part_count++; - - XPC_DEACTIVATE_PARTITION(part, xpcUnloading); + if (xpc_partition_disengaged(part) && + part->act_state == XPC_P_INACTIVE) { + continue; } + + active_part_count++; + + XPC_DEACTIVATE_PARTITION(part, reason); } - if (active_part_count) - msleep_interruptible(300); - } while (active_part_count > 0); + if (active_part_count == 0) { + break; + } + if (jiffies >= printmsg_time) { + dev_info(xpc_part, "waiting for partitions to " + "deactivate/disengage, active count=%d, remote " + "engaged=0x%lx\n", active_part_count, + xpc_partition_engaged(1UL << partid)); + + printmsg_time = jiffies + + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); + } + + /* sleep for a 1/3 of a second or so */ + (void) msleep_interruptible(300); + + } while (1); + + DBUG_ON(xpc_partition_engaged(-1UL)); + + + /* indicate to others that our reserved page is uninitialized */ + xpc_rsvd_page->vars_pa = 0; + + /* now it's time to eliminate our heartbeat */ + del_timer_sync(&xpc_hb_timer); + DBUG_ON(xpc_vars->heartbeating_to_mask == 0); + + /* take ourselves off of the reboot_notifier_list */ + (void) unregister_reboot_notifier(&xpc_reboot_notifier); /* close down protections for IPI operations */ xpc_restrict_IPI_ops(); @@ -876,6 +948,34 @@ xpc_do_exit(void) } +/* + * This function is called when the system is being rebooted. + */ +static int +xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) +{ + enum xpc_retval reason; + + + switch (event) { + case SYS_RESTART: + reason = xpcSystemReboot; + break; + case SYS_HALT: + reason = xpcSystemHalt; + break; + case SYS_POWER_OFF: + reason = xpcSystemPoweroff; + break; + default: + reason = xpcSystemGoingDown; + } + + xpc_do_exit(reason); + return NOTIFY_DONE; +} + + int __init xpc_init(void) { @@ -920,6 +1020,12 @@ xpc_init(void) spin_lock_init(&part->act_lock); part->act_state = XPC_P_INACTIVE; XPC_SET_REASON(part, 0, 0); + + init_timer(&part->disengage_request_timer); + part->disengage_request_timer.function = + xpc_timeout_partition_disengage_request; + part->disengage_request_timer.data = (unsigned long) part; + part->setup_state = XPC_P_UNSET; init_waitqueue_head(&part->teardown_wq); atomic_set(&part->references, 0); @@ -976,6 +1082,13 @@ xpc_init(void) } + /* add ourselves to the reboot_notifier_list */ + ret = register_reboot_notifier(&xpc_reboot_notifier); + if (ret != 0) { + dev_warn(xpc_part, "can't register reboot notifier\n"); + } + + /* * Set the beating to other partitions into motion. This is * the last requirement for other partitions' discovery to @@ -997,6 +1110,9 @@ xpc_init(void) /* indicate to others that our reserved page is uninitialized */ xpc_rsvd_page->vars_pa = 0; + /* take ourselves off of the reboot_notifier_list */ + (void) unregister_reboot_notifier(&xpc_reboot_notifier); + del_timer_sync(&xpc_hb_timer); free_irq(SGI_XPC_ACTIVATE, NULL); xpc_restrict_IPI_ops(); @@ -1018,9 +1134,9 @@ xpc_init(void) dev_err(xpc_part, "failed while forking discovery thread\n"); /* mark this new thread as a non-starter */ - up(&xpc_discovery_exited); + up(&xpc_discovery_inactive); - xpc_do_exit(); + xpc_do_exit(xpcUnloading); return -EBUSY; } @@ -1039,7 +1155,7 @@ module_init(xpc_init); void __exit xpc_exit(void) { - xpc_do_exit(); + xpc_do_exit(xpcUnloading); } module_exit(xpc_exit); diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 578265ea9e67..79a0fc4c860c 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -76,11 +76,6 @@ char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE]; -/* systune related variables */ -int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; -int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT; - - /* * Given a nasid, get the physical address of the partition's reserved page * for that nasid. This function returns 0 on any error. @@ -239,16 +234,21 @@ xpc_rsvd_page_init(void) xpc_vars->amos_page = amos_page; /* save for next load of XPC */ - /* - * Initialize the activation related AMO variables. - */ - xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS); - for (i = 1; i < XP_NASID_MASK_WORDS; i++) { - xpc_IPI_init(i + XP_MAX_PARTITIONS); + /* initialize the activate IRQ related AMO variables */ + for (i = 0; i < XP_NASID_MASK_WORDS; i++) { + (void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); } + + /* initialize the engaged remote partitions related AMO variables */ + (void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); + (void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO); + /* export AMO page's physical address to other partitions */ xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page); + /* timestamp of when reserved page was initialized */ + rp->stamp = CURRENT_TIME; + /* * This signifies to the remote partition that our reserved * page is initialized. @@ -387,6 +387,11 @@ xpc_check_remote_hb(void) remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { + + if (xpc_exiting) { + break; + } + if (partid == sn_partition_id) { continue; } @@ -417,7 +422,7 @@ xpc_check_remote_hb(void) if (((remote_vars->heartbeat == part->last_heartbeat) && (remote_vars->kdb_status == 0)) || - !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { + !xpc_hb_allowed(sn_partition_id, remote_vars)) { XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); continue; @@ -436,23 +441,23 @@ xpc_check_remote_hb(void) */ static enum xpc_retval xpc_get_remote_rp(int nasid, u64 *discovered_nasids, - struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa) + struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa) { int bres, i; /* get the reserved page's physical address */ - *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, + *remote_rp_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, XPC_RSVD_PAGE_ALIGNED_SIZE); - if (*remote_rsvd_page_pa == 0) { + if (*remote_rp_pa == 0) { return xpcNoRsvdPageAddr; } /* pull over the reserved page structure */ - bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp), + bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp), XPC_RSVD_PAGE_ALIGNED_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { @@ -523,6 +528,55 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) } +/* + * Update the remote partition's info. + */ +static void +xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version, + struct timespec *remote_rp_stamp, u64 remote_rp_pa, + u64 remote_vars_pa, struct xpc_vars *remote_vars) +{ + part->remote_rp_version = remote_rp_version; + dev_dbg(xpc_part, " remote_rp_version = 0x%016lx\n", + part->remote_rp_version); + + part->remote_rp_stamp = *remote_rp_stamp; + dev_dbg(xpc_part, " remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n", + part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec); + + part->remote_rp_pa = remote_rp_pa; + dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa); + + part->remote_vars_pa = remote_vars_pa; + dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", + part->remote_vars_pa); + + part->last_heartbeat = remote_vars->heartbeat; + dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", + part->last_heartbeat); + + part->remote_vars_part_pa = remote_vars->vars_part_pa; + dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n", + part->remote_vars_part_pa); + + part->remote_act_nasid = remote_vars->act_nasid; + dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n", + part->remote_act_nasid); + + part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid; + dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n", + part->remote_act_phys_cpuid); + + part->remote_amos_page_pa = remote_vars->amos_page_pa; + dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n", + part->remote_amos_page_pa); + + part->remote_vars_version = remote_vars->version; + dev_dbg(xpc_part, " remote_vars_version = 0x%x\n", + part->remote_vars_version); +} + + /* * Prior code has determine the nasid which generated an IPI. Inspect * that nasid to determine if its partition needs to be activated or @@ -542,8 +596,12 @@ xpc_identify_act_IRQ_req(int nasid) { struct xpc_rsvd_page *remote_rp; struct xpc_vars *remote_vars; - u64 remote_rsvd_page_pa; + u64 remote_rp_pa; u64 remote_vars_pa; + int remote_rp_version; + int reactivate = 0; + int stamp_diff; + struct timespec remote_rp_stamp = { 0, 0 }; partid_t partid; struct xpc_partition *part; enum xpc_retval ret; @@ -553,7 +611,7 @@ xpc_identify_act_IRQ_req(int nasid) remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer; - ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa); + ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); if (ret != xpcSuccess) { dev_warn(xpc_part, "unable to get reserved page from nasid %d, " "which sent interrupt, reason=%d\n", nasid, ret); @@ -561,6 +619,10 @@ xpc_identify_act_IRQ_req(int nasid) } remote_vars_pa = remote_rp->vars_pa; + remote_rp_version = remote_rp->version; + if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { + remote_rp_stamp = remote_rp->stamp; + } partid = remote_rp->partid; part = &xpc_partitions[partid]; @@ -586,44 +648,117 @@ xpc_identify_act_IRQ_req(int nasid) "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd, remote_vars->heartbeat, remote_vars->heartbeating_to_mask); + if (xpc_partition_disengaged(part) && + part->act_state == XPC_P_INACTIVE) { - if (part->act_state == XPC_P_INACTIVE) { + xpc_update_partition_info(part, remote_rp_version, + &remote_rp_stamp, remote_rp_pa, + remote_vars_pa, remote_vars); - part->remote_rp_pa = remote_rsvd_page_pa; - dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", - part->remote_rp_pa); - - part->remote_vars_pa = remote_vars_pa; - dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", - part->remote_vars_pa); - - part->last_heartbeat = remote_vars->heartbeat; - dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", - part->last_heartbeat); - - part->remote_vars_part_pa = remote_vars->vars_part_pa; - dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n", - part->remote_vars_part_pa); - - part->remote_act_nasid = remote_vars->act_nasid; - dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n", - part->remote_act_nasid); - - part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid; - dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n", - part->remote_act_phys_cpuid); - - part->remote_amos_page_pa = remote_vars->amos_page_pa; - dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n", - part->remote_amos_page_pa); + if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { + if (xpc_partition_disengage_requested(1UL << partid)) { + /* + * Other side is waiting on us to disengage, + * even though we already have. + */ + return; + } + } else { + /* other side doesn't support disengage requests */ + xpc_clear_partition_disengage_request(1UL << partid); + } xpc_activate_partition(part); + return; + } - } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa || - !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { + DBUG_ON(part->remote_rp_version == 0); + DBUG_ON(part->remote_vars_version == 0); + if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) { + DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part-> + remote_vars_version)); + + if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { + DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> + version)); + /* see if the other side rebooted */ + if (part->remote_amos_page_pa == + remote_vars->amos_page_pa && + xpc_hb_allowed(sn_partition_id, + remote_vars)) { + /* doesn't look that way, so ignore the IPI */ + return; + } + } + + /* + * Other side rebooted and previous XPC didn't support the + * disengage request, so we don't need to do anything special. + */ + + xpc_update_partition_info(part, remote_rp_version, + &remote_rp_stamp, remote_rp_pa, + remote_vars_pa, remote_vars); part->reactivate_nasid = nasid; XPC_DEACTIVATE_PARTITION(part, xpcReactivating); + return; + } + + DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)); + + if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { + DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); + + /* + * Other side rebooted and previous XPC did support the + * disengage request, but the new one doesn't. + */ + + xpc_clear_partition_engaged(1UL << partid); + xpc_clear_partition_disengage_request(1UL << partid); + + xpc_update_partition_info(part, remote_rp_version, + &remote_rp_stamp, remote_rp_pa, + remote_vars_pa, remote_vars); + reactivate = 1; + + } else { + DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); + + stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp, + &remote_rp_stamp); + if (stamp_diff != 0) { + DBUG_ON(stamp_diff >= 0); + + /* + * Other side rebooted and the previous XPC did support + * the disengage request, as does the new one. + */ + + DBUG_ON(xpc_partition_engaged(1UL << partid)); + DBUG_ON(xpc_partition_disengage_requested(1UL << + partid)); + + xpc_update_partition_info(part, remote_rp_version, + &remote_rp_stamp, remote_rp_pa, + remote_vars_pa, remote_vars); + reactivate = 1; + } + } + + if (!xpc_partition_disengaged(part)) { + /* still waiting on other side to disengage from us */ + return; + } + + if (reactivate) { + part->reactivate_nasid = nasid; + XPC_DEACTIVATE_PARTITION(part, xpcReactivating); + + } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) && + xpc_partition_disengage_requested(1UL << partid)) { + XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown); } } @@ -646,12 +781,16 @@ xpc_identify_act_IRQ_sender(void) struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page; - act_amos = xpc_vars->act_amos; + act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; /* scan through act AMO variable looking for non-zero entries */ for (word = 0; word < XP_NASID_MASK_WORDS; word++) { + if (xpc_exiting) { + break; + } + nasid_mask = xpc_IPI_receive(&act_amos[word]); if (nasid_mask == 0) { /* no IRQs from nasids in this variable */ @@ -687,6 +826,55 @@ xpc_identify_act_IRQ_sender(void) } +/* + * See if the other side has responded to a partition disengage request + * from us. + */ +int +xpc_partition_disengaged(struct xpc_partition *part) +{ + partid_t partid = XPC_PARTID(part); + int disengaged; + + + disengaged = (xpc_partition_engaged(1UL << partid) == 0); + if (part->disengage_request_timeout) { + if (!disengaged) { + if (jiffies < part->disengage_request_timeout) { + /* timelimit hasn't been reached yet */ + return 0; + } + + /* + * Other side hasn't responded to our disengage + * request in a timely fashion, so assume it's dead. + */ + + xpc_clear_partition_engaged(1UL << partid); + disengaged = 1; + } + part->disengage_request_timeout = 0; + + /* cancel the timer function, provided it's not us */ + if (!in_interrupt()) { + del_singleshot_timer_sync(&part-> + disengage_request_timer); + } + + DBUG_ON(part->act_state != XPC_P_DEACTIVATING && + part->act_state != XPC_P_INACTIVE); + if (part->act_state != XPC_P_INACTIVE) { + xpc_wakeup_channel_mgr(part); + } + + if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { + xpc_cancel_partition_disengage_request(part); + } + } + return disengaged; +} + + /* * Mark specified partition as active. */ @@ -721,7 +909,6 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, enum xpc_retval reason) { unsigned long irq_flags; - partid_t partid = XPC_PARTID(part); spin_lock_irqsave(&part->act_lock, irq_flags); @@ -749,17 +936,27 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, spin_unlock_irqrestore(&part->act_lock, irq_flags); - XPC_DISALLOW_HB(partid, xpc_vars); + if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { + xpc_request_partition_disengage(part); + xpc_IPI_send_disengage(part); + + /* set a timelimit on the disengage request */ + part->disengage_request_timeout = jiffies + + (XPC_DISENGAGE_REQUEST_TIMELIMIT * HZ); + part->disengage_request_timer.expires = + part->disengage_request_timeout; + add_timer(&part->disengage_request_timer); + } dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid, reason); - xpc_partition_down(part, reason); + xpc_partition_going_down(part, reason); } /* - * Mark specified partition as active. + * Mark specified partition as inactive. */ void xpc_mark_partition_inactive(struct xpc_partition *part) @@ -792,7 +989,7 @@ xpc_discovery(void) void *remote_rp_base; struct xpc_rsvd_page *remote_rp; struct xpc_vars *remote_vars; - u64 remote_rsvd_page_pa; + u64 remote_rp_pa; u64 remote_vars_pa; int region; int max_regions; @@ -877,7 +1074,7 @@ xpc_discovery(void) /* pull over the reserved page structure */ ret = xpc_get_remote_rp(nasid, discovered_nasids, - remote_rp, &remote_rsvd_page_pa); + remote_rp, &remote_rp_pa); if (ret != xpcSuccess) { dev_dbg(xpc_part, "unable to get reserved page " "from nasid %d, reason=%d\n", nasid, @@ -948,6 +1145,13 @@ xpc_discovery(void) remote_vars->act_nasid, remote_vars->act_phys_cpuid); + if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> + version)) { + part->remote_amos_page_pa = + remote_vars->amos_page_pa; + xpc_mark_partition_disengaged(part); + xpc_cancel_partition_disengage_request(part); + } xpc_IPI_send_activate(remote_vars); } } diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index 1df1c9f61a65..f3052a54932b 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h @@ -217,7 +217,15 @@ enum xpc_retval { xpcInvalidPartid, /* 42: invalid partition ID */ xpcLocalPartid, /* 43: local partition ID */ - xpcUnknownReason /* 44: unknown reason -- must be last in list */ + xpcOtherGoingDown, /* 44: other side going down, reason unknown */ + xpcSystemGoingDown, /* 45: system is going down, reason unknown */ + xpcSystemHalt, /* 46: system is being halted */ + xpcSystemReboot, /* 47: system is being rebooted */ + xpcSystemPoweroff, /* 48: system is being powered off */ + + xpcDisconnecting, /* 49: channel disconnecting (closing) */ + + xpcUnknownReason /* 50: unknown reason -- must be last in list */ }; From 5fbcf9a5c6904bd563f584d12d1f4d3f68a19d7d Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Tue, 6 Sep 2005 13:03:51 -0500 Subject: [PATCH 0047/1940] [IA64-SGI] volatile semantics in places where it seems necessary Resend using accessors instead of volatile qualifiers per hch comments, and easier to understand convenience macros per rja comments. Patch to apply volatile semantics when accessing MMR's in various SN files. Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/sn/pci/pcibr/pcibr_reg.c | 58 ++++++++++++++-------------- arch/ia64/sn/pci/tioca_provider.c | 31 +++++++-------- arch/ia64/sn/pci/tioce_provider.c | 29 +++++++------- include/asm-ia64/sn/io.h | 9 +++++ include/asm-ia64/sn/tioca_provider.h | 14 +++---- 5 files changed, 76 insertions(+), 65 deletions(-) diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 21426d02fbe6..1624b39cb3ec 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c @@ -29,10 +29,10 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_control &= ~bits; + __sn_clrq_relaxed(&ptr->tio.cp_control, bits); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_wid_control &= ~bits; + __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits); break; default: panic @@ -49,10 +49,10 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_control |= bits; + __sn_setq_relaxed(&ptr->tio.cp_control, bits); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_wid_control |= bits; + __sn_setq_relaxed(&ptr->pic.p_wid_control, bits); break; default: panic @@ -73,10 +73,10 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ret = ptr->tio.cp_tflush; + ret = __sn_readq_relaxed(&ptr->tio.cp_tflush); break; case PCIBR_BRIDGETYPE_PIC: - ret = ptr->pic.p_wid_tflush; + ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush); break; default: panic @@ -103,10 +103,10 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ret = ptr->tio.cp_int_status; + ret = __sn_readq_relaxed(&ptr->tio.cp_int_status); break; case PCIBR_BRIDGETYPE_PIC: - ret = ptr->pic.p_int_status; + ret = __sn_readq_relaxed(&ptr->pic.p_int_status); break; default: panic @@ -127,10 +127,10 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_int_enable &= ~bits; + __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_int_enable &= ~bits; + __sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits); break; default: panic @@ -147,10 +147,10 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_int_enable |= bits; + __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_int_enable |= bits; + __sn_setq_relaxed(&ptr->pic.p_int_enable, bits); break; default: panic @@ -171,14 +171,16 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_int_addr[int_n] &= ~TIOCP_HOST_INTR_ADDR; - ptr->tio.cp_int_addr[int_n] |= - (addr & TIOCP_HOST_INTR_ADDR); + __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n], + TIOCP_HOST_INTR_ADDR); + __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n], + (addr & TIOCP_HOST_INTR_ADDR)); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_int_addr[int_n] &= ~PIC_HOST_INTR_ADDR; - ptr->pic.p_int_addr[int_n] |= - (addr & PIC_HOST_INTR_ADDR); + __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n], + PIC_HOST_INTR_ADDR); + __sn_setq_relaxed(&ptr->pic.p_int_addr[int_n], + (addr & PIC_HOST_INTR_ADDR)); break; default: panic @@ -198,10 +200,10 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_force_pin[int_n] = 1; + writeq(1, &ptr->tio.cp_force_pin[int_n]); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_force_pin[int_n] = 1; + writeq(1, &ptr->pic.p_force_pin[int_n]); break; default: panic @@ -222,10 +224,12 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ret = ptr->tio.cp_wr_req_buf[device]; + ret = + __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]); break; case PCIBR_BRIDGETYPE_PIC: - ret = ptr->pic.p_wr_req_buf[device]; + ret = + __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]); break; default: panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr); @@ -244,10 +248,10 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ptr->tio.cp_int_ate_ram[ate_index] = (uint64_t) val; + writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]); break; case PCIBR_BRIDGETYPE_PIC: - ptr->pic.p_int_ate_ram[ate_index] = (uint64_t) val; + writeq(val, &ptr->pic.p_int_ate_ram[ate_index]); break; default: panic @@ -265,12 +269,10 @@ uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { case PCIBR_BRIDGETYPE_TIOCP: - ret = - (uint64_t *) & (ptr->tio.cp_int_ate_ram[ate_index]); + ret = &ptr->tio.cp_int_ate_ram[ate_index]; break; case PCIBR_BRIDGETYPE_PIC: - ret = - (uint64_t *) & (ptr->pic.p_int_ate_ram[ate_index]); + ret = &ptr->pic.p_int_ate_ram[ate_index]; break; default: panic diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index ea09c12f0258..eaae2472d6b4 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -37,7 +37,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) uint64_t offset; struct page *tmp; struct tioca_common *tioca_common; - volatile struct tioca *ca_base; + struct tioca *ca_base; tioca_common = tioca_kern->ca_common; ca_base = (struct tioca *)tioca_common->ca_common.bs_base; @@ -174,27 +174,29 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) * DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029 */ - ca_base->ca_control1 |= CA_AGPDMA_OP_ENB_COMBDELAY; /* PV895469 ? */ - ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM); - ca_base->ca_control2 |= (0x2ull << CA_GART_MEM_PARAM_SHFT); + __sn_setq_relaxed(&ca_base->ca_control1, + CA_AGPDMA_OP_ENB_COMBDELAY); /* PV895469 ? */ + __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM); + __sn_setq_relaxed(&ca_base->ca_control2, + (0x2ull << CA_GART_MEM_PARAM_SHFT)); tioca_kern->ca_gart_iscoherent = 1; - ca_base->ca_control2 &= - ~(CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB); + __sn_clrq_relaxed(&ca_base->ca_control2, + (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB)); /* * Unmask GART fetch error interrupts. Clear residual errors first. */ - ca_base->ca_int_status_alias = CA_GART_FETCH_ERR; - ca_base->ca_mult_error_alias = CA_GART_FETCH_ERR; - ca_base->ca_int_mask &= ~CA_GART_FETCH_ERR; + writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias); + writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias); + __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR); /* * Program the aperature and gart registers in TIOCA */ - ca_base->ca_gart_aperature = ap_reg; - ca_base->ca_gart_ptr_table = tioca_kern->ca_gart_coretalk_addr | 1; + writeq(ap_reg, &ca_base->ca_gart_aperature); + writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table); return 0; } @@ -211,7 +213,6 @@ void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) { int cap_ptr; - uint64_t ca_control1; uint32_t reg; struct tioca *tioca_base; struct pci_dev *pdev; @@ -256,9 +257,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) */ tioca_base = (struct tioca *)common->ca_common.bs_base; - ca_control1 = tioca_base->ca_control1; - ca_control1 |= CA_AGP_FW_ENABLE; - tioca_base->ca_control1 = ca_control1; + __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE); } EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */ @@ -345,7 +344,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) return 0; } - agp_dma_extn = ca_base->ca_agp_dma_addr_extn; + agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn); if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) { printk(KERN_ERR "%s: coretalk upper node (%u) " "mismatch with ca_agp_dma_addr_extn (%lu)\n", diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 8e75db2b825d..204826c2fa44 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -227,7 +227,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, ate = ATE_MAKE(addr, pagesize); ate_shadow[i + j] = ate; - ate_reg[i + j] = ate; + writeq(ate, &ate_reg[i + j]); addr += pagesize; } @@ -268,10 +268,10 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port); if (ce_kern->ce_port[port].dirmap_refcnt == 0) { - volatile uint64_t tmp; + uint64_t tmp; ce_kern->ce_port[port].dirmap_shadow = ct_upper; - ce_mmr->ce_ure_dir_map[port] = ct_upper; + writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); tmp = ce_mmr->ce_ure_dir_map[port]; dma_ok = 1; } else @@ -343,7 +343,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) if (TIOCE_D32_ADDR(bus_addr)) { if (--ce_kern->ce_port[port].dirmap_refcnt == 0) { ce_kern->ce_port[port].dirmap_shadow = 0; - ce_mmr->ce_ure_dir_map[port] = 0; + writeq(0, &ce_mmr->ce_ure_dir_map[port]); } } else { struct tioce_dmamap *map; @@ -582,18 +582,18 @@ tioce_kern_init(struct tioce_common *tioce_common) */ tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; - tioce_mmr->ce_ure_page_map &= ~CE_URE_PAGESIZE_MASK; - tioce_mmr->ce_ure_page_map |= CE_URE_256K_PAGESIZE; + __sn_clrq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK); + __sn_setq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_256K_PAGESIZE); tioce_kern->ce_ate3240_pagesize = KB(256); for (i = 0; i < TIOCE_NUM_M40_ATES; i++) { tioce_kern->ce_ate40_shadow[i] = 0; - tioce_mmr->ce_ure_ate40[i] = 0; + writeq(0, &tioce_mmr->ce_ure_ate40[i]); } for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) { tioce_kern->ce_ate3240_shadow[i] = 0; - tioce_mmr->ce_ure_ate3240[i] = 0; + writeq(0, &tioce_mmr->ce_ure_ate3240[i]); } return tioce_kern; @@ -665,7 +665,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) default: return; } - ce_mmr->ce_adm_force_int = force_int_val; + writeq(force_int_val, &ce_mmr->ce_adm_force_int); } /** @@ -686,6 +686,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) struct tioce_common *ce_common; struct tioce *ce_mmr; int bit; + uint64_t vector; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; if (!pcidev_info) @@ -696,11 +697,11 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) bit = sn_irq_info->irq_int_bit; - ce_mmr->ce_adm_int_mask |= (1UL << bit); - ce_mmr->ce_adm_int_dest[bit] = - ((uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT) | - sn_irq_info->irq_xtalkaddr; - ce_mmr->ce_adm_int_mask &= ~(1UL << bit); + __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); + vector = (uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; + vector |= sn_irq_info->irq_xtalkaddr; + writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); + __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); tioce_force_interrupt(sn_irq_info); } diff --git a/include/asm-ia64/sn/io.h b/include/asm-ia64/sn/io.h index 42209733f6b1..7597a52b426c 100644 --- a/include/asm-ia64/sn/io.h +++ b/include/asm-ia64/sn/io.h @@ -35,6 +35,15 @@ extern void sn_dma_flush(unsigned long); #define __sn_readl_relaxed ___sn_readl_relaxed #define __sn_readq_relaxed ___sn_readq_relaxed +/* + * Convenience macros for setting/clearing bits using the above accessors + */ + +#define __sn_setq_relaxed(addr, val) \ + writeq((__sn_readq_relaxed(addr) | (val)), (addr)) +#define __sn_clrq_relaxed(addr, val) \ + writeq((__sn_readq_relaxed(addr) & ~(val)), (addr)) + /* * The following routines are SN Platform specific, called when * a reference is made to inX/outX set macros. SN Platform diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h index 5ccec608d325..b532ef6148ed 100644 --- a/include/asm-ia64/sn/tioca_provider.h +++ b/include/asm-ia64/sn/tioca_provider.h @@ -182,11 +182,11 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel) * touch every CL aligned GART entry. */ - ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM); - ca_base->ca_control2 |= CA_GART_FLUSH_TLB; - ca_base->ca_control2 |= - (0x2ull << CA_GART_MEM_PARAM_SHFT); - tmp = ca_base->ca_control2; + __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM); + __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB); + __sn_setq_relaxed(&ca_base->ca_control2, + (0x2ull << CA_GART_MEM_PARAM_SHFT)); + tmp = __sn_readq_relaxed(&ca_base->ca_control2); } return; @@ -196,8 +196,8 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel) * Gart in uncached mode ... need an explicit flush. */ - ca_base->ca_control2 |= CA_GART_FLUSH_TLB; - tmp = ca_base->ca_control2; + __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB); + tmp = __sn_readq_relaxed(&ca_base->ca_control2); } extern uint32_t tioca_gart_found; From d8c97d5f3aa348272df2ccb4e224b1cf9a1eb6d7 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 8 Sep 2005 12:39:59 -0700 Subject: [PATCH 0048/1940] [IA64] simplified efi memory map parsing New version leaves the original memory map unmodified. Also saves any granule trimmings for use by the uncached memory allocator. Inspired by Khalid Aziz (various traces of his patch still remain). Fixes to uncached_build_memmap() and sn2 testing by Martin Hicks. Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 423 +++++++++++++++++++++--------------- arch/ia64/kernel/setup.c | 3 + arch/ia64/kernel/uncached.c | 17 +- include/asm-ia64/meminit.h | 4 +- 4 files changed, 254 insertions(+), 193 deletions(-) diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 179f230816ed..1291db581721 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -239,57 +239,30 @@ is_available_memory (efi_memory_desc_t *md) return 0; } -/* - * Trim descriptor MD so its starts at address START_ADDR. If the descriptor covers - * memory that is normally available to the kernel, issue a warning that some memory - * is being ignored. - */ -static void -trim_bottom (efi_memory_desc_t *md, u64 start_addr) -{ - u64 num_skipped_pages; +typedef struct kern_memdesc { + u64 attribute; + u64 start; + u64 num_pages; +} kern_memdesc_t; - if (md->phys_addr >= start_addr || !md->num_pages) - return; - - num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT; - if (num_skipped_pages > md->num_pages) - num_skipped_pages = md->num_pages; - - if (is_available_memory(md)) - printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole " - "at 0x%lx\n", __FUNCTION__, - (num_skipped_pages << EFI_PAGE_SHIFT) >> 10, - md->phys_addr, start_addr - IA64_GRANULE_SIZE); - /* - * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory - * descriptor list to become unsorted. In such a case, md->num_pages will be - * zero, so the Right Thing will happen. - */ - md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT; - md->num_pages -= num_skipped_pages; -} +static kern_memdesc_t *kern_memmap; static void -trim_top (efi_memory_desc_t *md, u64 end_addr) +walk (efi_freemem_callback_t callback, void *arg, u64 attr) { - u64 num_dropped_pages, md_end_addr; + kern_memdesc_t *k; + u64 start, end, voff; - md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); - - if (md_end_addr <= end_addr || !md->num_pages) - return; - - num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT; - if (num_dropped_pages > md->num_pages) - num_dropped_pages = md->num_pages; - - if (is_available_memory(md)) - printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole " - "at 0x%lx\n", __FUNCTION__, - (num_dropped_pages << EFI_PAGE_SHIFT) >> 10, - md->phys_addr, end_addr); - md->num_pages -= num_dropped_pages; + voff = (attr == EFI_MEMORY_WB) ? PAGE_OFFSET : __IA64_UNCACHED_OFFSET; + for (k = kern_memmap; k->start != ~0UL; k++) { + if (k->attribute != attr) + continue; + start = PAGE_ALIGN(k->start); + end = (k->start + (k->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK; + if (start < end) + if ((*callback)(start + voff, end + voff, arg) < 0) + return; + } } /* @@ -299,148 +272,19 @@ trim_top (efi_memory_desc_t *md, u64 end_addr) void efi_memmap_walk (efi_freemem_callback_t callback, void *arg) { - int prev_valid = 0; - struct range { - u64 start; - u64 end; - } prev, curr; - void *efi_map_start, *efi_map_end, *p, *q; - efi_memory_desc_t *md, *check_md; - u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0; - unsigned long total_mem = 0; - - efi_map_start = __va(ia64_boot_param->efi_memmap); - efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; - efi_desc_size = ia64_boot_param->efi_memdesc_size; - - for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { - md = p; - - /* skip over non-WB memory descriptors; that's all we're interested in... */ - if (!(md->attribute & EFI_MEMORY_WB)) - continue; - - /* - * granule_addr is the base of md's first granule. - * [granule_addr - first_non_wb_addr) is guaranteed to - * be contiguous WB memory. - */ - granule_addr = GRANULEROUNDDOWN(md->phys_addr); - first_non_wb_addr = max(first_non_wb_addr, granule_addr); - - if (first_non_wb_addr < md->phys_addr) { - trim_bottom(md, granule_addr + IA64_GRANULE_SIZE); - granule_addr = GRANULEROUNDDOWN(md->phys_addr); - first_non_wb_addr = max(first_non_wb_addr, granule_addr); - } - - for (q = p; q < efi_map_end; q += efi_desc_size) { - check_md = q; - - if ((check_md->attribute & EFI_MEMORY_WB) && - (check_md->phys_addr == first_non_wb_addr)) - first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT; - else - break; /* non-WB or hole */ - } - - last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr); - if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) - trim_top(md, last_granule_addr); - - if (is_available_memory(md)) { - if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) { - if (md->phys_addr >= max_addr) - continue; - md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT; - first_non_wb_addr = max_addr; - } - - if (total_mem >= mem_limit) - continue; - - if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { - unsigned long limit_addr = md->phys_addr; - - limit_addr += mem_limit - total_mem; - limit_addr = GRANULEROUNDDOWN(limit_addr); - - if (md->phys_addr > limit_addr) - continue; - - md->num_pages = (limit_addr - md->phys_addr) >> - EFI_PAGE_SHIFT; - first_non_wb_addr = max_addr = md->phys_addr + - (md->num_pages << EFI_PAGE_SHIFT); - } - total_mem += (md->num_pages << EFI_PAGE_SHIFT); - - if (md->num_pages == 0) - continue; - - curr.start = PAGE_OFFSET + md->phys_addr; - curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT); - - if (!prev_valid) { - prev = curr; - prev_valid = 1; - } else { - if (curr.start < prev.start) - printk(KERN_ERR "Oops: EFI memory table not ordered!\n"); - - if (prev.end == curr.start) { - /* merge two consecutive memory ranges */ - prev.end = curr.end; - } else { - start = PAGE_ALIGN(prev.start); - end = prev.end & PAGE_MASK; - if ((end > start) && (*callback)(start, end, arg) < 0) - return; - prev = curr; - } - } - } - } - if (prev_valid) { - start = PAGE_ALIGN(prev.start); - end = prev.end & PAGE_MASK; - if (end > start) - (*callback)(start, end, arg); - } + walk(callback, arg, EFI_MEMORY_WB); } /* - * Walk the EFI memory map to pull out leftover pages in the lower - * memory regions which do not end up in the regular memory map and - * stick them into the uncached allocator - * - * The regular walk function is significantly more complex than the - * uncached walk which means it really doesn't make sense to try and - * marge the two. + * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that + * has memory that is available for uncached allocator. */ -void __init -efi_memmap_walk_uc (efi_freemem_callback_t callback) +void +efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg) { - void *efi_map_start, *efi_map_end, *p; - efi_memory_desc_t *md; - u64 efi_desc_size, start, end; - - efi_map_start = __va(ia64_boot_param->efi_memmap); - efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; - efi_desc_size = ia64_boot_param->efi_memdesc_size; - - for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { - md = p; - if (md->attribute == EFI_MEMORY_UC) { - start = PAGE_ALIGN(md->phys_addr); - end = PAGE_ALIGN((md->phys_addr+(md->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK); - if ((*callback)(start, end, NULL) < 0) - return; - } - } + walk(callback, arg, EFI_MEMORY_UC); } - /* * Look for the PAL_CODE region reported by EFI and maps it using an * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor @@ -862,3 +706,220 @@ efi_uart_console_only(void) printk(KERN_ERR "Malformed %s value\n", name); return 0; } + +#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT) + +static inline u64 +kmd_end(kern_memdesc_t *kmd) +{ + return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT)); +} + +static inline u64 +efi_md_end(efi_memory_desc_t *md) +{ + return (md->phys_addr + efi_md_size(md)); +} + +static inline int +efi_wb(efi_memory_desc_t *md) +{ + return (md->attribute & EFI_MEMORY_WB); +} + +static inline int +efi_uc(efi_memory_desc_t *md) +{ + return (md->attribute & EFI_MEMORY_UC); +} + +/* + * Look for the first granule aligned memory descriptor memory + * that is big enough to hold EFI memory map. Make sure this + * descriptor is atleast granule sized so it does not get trimmed + */ +struct kern_memdesc * +find_memmap_space (void) +{ + u64 contig_low=0, contig_high=0; + u64 as = 0, ae; + void *efi_map_start, *efi_map_end, *p, *q; + efi_memory_desc_t *md, *pmd = NULL, *check_md; + u64 space_needed, efi_desc_size; + unsigned long total_mem = 0; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + /* + * Worst case: we need 3 kernel descriptors for each efi descriptor + * (if every entry has a WB part in the middle, and UC head and tail), + * plus one for the end marker. + */ + space_needed = sizeof(kern_memdesc_t) * + (3 * (ia64_boot_param->efi_memmap_size/efi_desc_size) + 1); + + for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) { + md = p; + if (!efi_wb(md)) { + continue; + } + if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) { + contig_low = GRANULEROUNDUP(md->phys_addr); + contig_high = efi_md_end(md); + for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) { + check_md = q; + if (!efi_wb(check_md)) + break; + if (contig_high != check_md->phys_addr) + break; + contig_high = efi_md_end(check_md); + } + contig_high = GRANULEROUNDDOWN(contig_high); + } + if (!is_available_memory(md) || md->type == EFI_LOADER_DATA) + continue; + + /* Round ends inward to granule boundaries */ + as = max(contig_low, md->phys_addr); + ae = min(contig_high, efi_md_end(md)); + + /* keep within max_addr= command line arg */ + ae = min(ae, max_addr); + if (ae <= as) + continue; + + /* avoid going over mem= command line arg */ + if (total_mem + (ae - as) > mem_limit) + ae -= total_mem + (ae - as) - mem_limit; + + if (ae <= as) + continue; + + if (ae - as > space_needed) + break; + } + if (p >= efi_map_end) + panic("Can't allocate space for kernel memory descriptors"); + + return __va(as); +} + +/* + * Walk the EFI memory map and gather all memory available for kernel + * to use. We can allocate partial granules only if the unavailable + * parts exist, and are WB. + */ +void +efi_memmap_init(unsigned long *s, unsigned long *e) +{ + struct kern_memdesc *k, *prev = 0; + u64 contig_low=0, contig_high=0; + u64 as, ae, lim; + void *efi_map_start, *efi_map_end, *p, *q; + efi_memory_desc_t *md, *pmd = NULL, *check_md; + u64 efi_desc_size; + unsigned long total_mem = 0; + + k = kern_memmap = find_memmap_space(); + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) { + md = p; + if (!efi_wb(md)) { + if (efi_uc(md) && (md->type == EFI_CONVENTIONAL_MEMORY || + md->type == EFI_BOOT_SERVICES_DATA)) { + k->attribute = EFI_MEMORY_UC; + k->start = md->phys_addr; + k->num_pages = md->num_pages; + k++; + } + continue; + } + if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) { + contig_low = GRANULEROUNDUP(md->phys_addr); + contig_high = efi_md_end(md); + for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) { + check_md = q; + if (!efi_wb(check_md)) + break; + if (contig_high != check_md->phys_addr) + break; + contig_high = efi_md_end(check_md); + } + contig_high = GRANULEROUNDDOWN(contig_high); + } + if (!is_available_memory(md)) + continue; + + /* + * Round ends inward to granule boundaries + * Give trimmings to uncached allocator + */ + if (md->phys_addr < contig_low) { + lim = min(efi_md_end(md), contig_low); + if (efi_uc(md)) { + if (k > kern_memmap && (k-1)->attribute == EFI_MEMORY_UC && + kmd_end(k-1) == md->phys_addr) { + (k-1)->num_pages += (lim - md->phys_addr) >> EFI_PAGE_SHIFT; + } else { + k->attribute = EFI_MEMORY_UC; + k->start = md->phys_addr; + k->num_pages = (lim - md->phys_addr) >> EFI_PAGE_SHIFT; + k++; + } + } + as = contig_low; + } else + as = md->phys_addr; + + if (efi_md_end(md) > contig_high) { + lim = max(md->phys_addr, contig_high); + if (efi_uc(md)) { + if (lim == md->phys_addr && k > kern_memmap && + (k-1)->attribute == EFI_MEMORY_UC && + kmd_end(k-1) == md->phys_addr) { + (k-1)->num_pages += md->num_pages; + } else { + k->attribute = EFI_MEMORY_UC; + k->start = lim; + k->num_pages = (efi_md_end(md) - lim) >> EFI_PAGE_SHIFT; + k++; + } + } + ae = contig_high; + } else + ae = efi_md_end(md); + + /* keep within max_addr= command line arg */ + ae = min(ae, max_addr); + if (ae <= as) + continue; + + /* avoid going over mem= command line arg */ + if (total_mem + (ae - as) > mem_limit) + ae -= total_mem + (ae - as) - mem_limit; + + if (ae <= as) + continue; + if (prev && kmd_end(prev) == md->phys_addr) { + prev->num_pages += (ae - as) >> EFI_PAGE_SHIFT; + total_mem += ae - as; + continue; + } + k->attribute = EFI_MEMORY_WB; + k->start = as; + k->num_pages = (ae - as) >> EFI_PAGE_SHIFT; + total_mem += ae - as; + prev = k++; + } + k->start = ~0L; /* end-marker */ + + /* reserve the memory we are using for kern_memmap */ + *s = (u64)kern_memmap; + *e = (u64)++k; +} diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 84f89da7c640..1658d687b79c 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -211,6 +211,9 @@ reserve_memory (void) } #endif + efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); + n++; + /* end of memory marker */ rsvd_region[n].start = ~0UL; rsvd_region[n].end = ~0UL; diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index 4e9d06c48a8b..c6d40446c2c4 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -205,23 +205,18 @@ EXPORT_SYMBOL(uncached_free_page); static int __init uncached_build_memmap(unsigned long start, unsigned long end, void *arg) { - long length; - unsigned long vstart, vend; + long length = end - start; int node; - length = end - start; - vstart = start + __IA64_UNCACHED_OFFSET; - vend = end + __IA64_UNCACHED_OFFSET; - dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); - memset((char *)vstart, 0, length); + memset((char *)start, 0, length); - node = paddr_to_nid(start); + node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET); - for (; vstart < vend ; vstart += PAGE_SIZE) { - dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart); - gen_pool_free(uncached_pool[node], vstart, PAGE_SIZE); + for (; start < end ; start += PAGE_SIZE) { + dprintk(KERN_INFO "sticking %lx into the pool!\n", start); + gen_pool_free(uncached_pool[node], start, PAGE_SIZE); } return 0; diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h index 1590dc65b30b..90646632237c 100644 --- a/include/asm-ia64/meminit.h +++ b/include/asm-ia64/meminit.h @@ -16,10 +16,11 @@ * - initrd (optional) * - command line string * - kernel code & data + * - Kernel memory map built from EFI memory map * * More could be added if necessary */ -#define IA64_MAX_RSVD_REGIONS 5 +#define IA64_MAX_RSVD_REGIONS 6 struct rsvd_region { unsigned long start; /* virtual address of beginning of element */ @@ -33,6 +34,7 @@ extern void find_memory (void); extern void reserve_memory (void); extern void find_initrd (void); extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); +extern void efi_memmap_init(unsigned long *, unsigned long *); /* * For rounding an address to the next IA64_GRANULE_SIZE or order From 2290d2b63c2d25b0d554d68e54cbd1cc87d951d5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 8 Sep 2005 10:14:11 -0500 Subject: [PATCH 0049/1940] [SCSI] iscsi_tcp: make iscsi compile again after recent netlink changes netlink_kernel_create now has two new arguments; the module (which is easy) and the number of groups, which I arbitrarily set to one. Acked by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index f189ce7541ff..e4fceca49e56 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1230,7 +1230,8 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_session_class; - nls = netlink_kernel_create(NETLINK_ISCSI, iscsi_if_rx); + nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, + THIS_MODULE); if (!nls) { err = -ENOBUFS; goto unregister_notifier; From 1fa92957282e4595727c1a21bf6687ea5a2d612f Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 9 Sep 2005 11:41:12 -0700 Subject: [PATCH 0050/1940] [IA64] Need to include in a few more places. Signed-off-by: Tony Luck --- arch/ia64/sn/pci/pcibr/pcibr_reg.c | 1 + arch/ia64/sn/pci/tioca_provider.c | 1 + arch/ia64/sn/pci/tioce_provider.c | 1 + drivers/char/agp/sgi-agp.c | 1 + 4 files changed, 4 insertions(+) diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 1624b39cb3ec..4f718c3e93d3 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index eaae2472d6b4..9b8dbce2b7b6 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 204826c2fa44..9f03d4e5121c 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index d3aa159c9dec..7957fc91f6ad 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include From 96bad874e7b047ec1e6fade09acba47fd19211c5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 8 Sep 2005 09:56:18 -0500 Subject: [PATCH 0051/1940] [SCSI] move iscsi to a better place in Kconfig Now it looks like we'll have multiple users of the iscsi transport class, the iscsi initiator shouldn't really be a dependency of it. This patch moves iscsi to being an initiator in its own right which selects the transport attributes. Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 1c60c568e911..c76a3b8b5569 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -235,12 +235,18 @@ config SCSI_ISCSI_ATTRS each attached iSCSI device to sysfs, say Y. Otherwise, say N. +endmenu + +menu "SCSI low-level drivers" + depends on SCSI!=n + config ISCSI_TCP tristate "iSCSI Initiator over TCP/IP" - depends on SCSI && INET && SCSI_ISCSI_ATTRS + depends on SCSI && INET select CRYPTO select CRYPTO_MD5 select CRYPTO_CRC32C + select SCSI_ISCSI_ATTRS help The iSCSI Driver provides a host with the ability to access storage through an IP network. The driver uses the iSCSI protocol to transport @@ -258,11 +264,6 @@ config ISCSI_TCP http://linux-iscsi.sf.net -endmenu - -menu "SCSI low-level drivers" - depends on SCSI!=n - config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" depends on SGI_IP22 && SCSI From 70dfcfea4b728ab26af1a3e0f331cc63a7e3554b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Sep 2005 19:37:29 +1000 Subject: [PATCH 0052/1940] drm: missing drm_vm.c changes for consistent maps This adds a missing change from CVS for consistent maps. Signed-off-by: Dave Airlie --- drivers/char/drm/drm_vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index ced4215e2275..a13d07f44202 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c @@ -148,7 +148,8 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; - page = vmalloc_to_page((void *)i); + page = (map->type == _DRM_CONSISTENT) ? + virt_to_page((void *)i) : vmalloc_to_page((void *)i); if (!page) return NOPAGE_OOM; get_page(page); From 9d17601c4e132eee9fe450191f6866fb9fb5a762 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Sep 2005 19:55:53 +1000 Subject: [PATCH 0053/1940] drm: update radeon driver to 1.18 Add support for GL_ATI_fragment_shader, new packets R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) From: Roland Scheidegger, David Airlie Signed-off-by: David Airlie --- drivers/char/drm/radeon_drm.h | 11 ++++++++++- drivers/char/drm/radeon_drv.h | 11 +++++++++-- drivers/char/drm/radeon_state.c | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 3792798270a4..67a8bf04970e 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h @@ -153,7 +153,16 @@ #define RADEON_EMIT_PP_CUBIC_FACES_2 82 #define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83 #define R200_EMIT_PP_TRI_PERF_CNTL 84 -#define RADEON_MAX_STATE_PACKETS 85 +#define R200_EMIT_PP_AFS_0 85 +#define R200_EMIT_PP_AFS_1 86 +#define R200_EMIT_ATF_TFACTOR 87 +#define R200_EMIT_PP_TXCTLALL_0 88 +#define R200_EMIT_PP_TXCTLALL_1 89 +#define R200_EMIT_PP_TXCTLALL_2 90 +#define R200_EMIT_PP_TXCTLALL_3 91 +#define R200_EMIT_PP_TXCTLALL_4 92 +#define R200_EMIT_PP_TXCTLALL_5 93 +#define RADEON_MAX_STATE_PACKETS 94 /* Commands understood by cmd_buffer ioctl. More can be added but * obviously these can't be removed or changed: diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index f12a963ede18..430598e1fa67 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20050311" +#define DRIVER_DATE "20050720" /* Interface history: * @@ -83,9 +83,13 @@ * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear * texture filtering on r200 * 1.17- Add initial support for R300 (3D). + * 1.18- Add support for GL_ATI_fragment_shader, new packets + * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces + * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR + * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 17 +#define DRIVER_MINOR 18 #define DRIVER_PATCHLEVEL 0 #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) @@ -857,6 +861,9 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define R200_PP_TRI_PERF 0x2cf8 +#define R200_PP_AFS_0 0x2f80 +#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 64a3e3a406ef..c4325f1e2294 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -207,6 +207,15 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case RADEON_EMIT_PP_CUBIC_FACES_1: case RADEON_EMIT_PP_CUBIC_FACES_2: case R200_EMIT_PP_TRI_PERF_CNTL: + case R200_EMIT_PP_AFS_0: + case R200_EMIT_PP_AFS_1: + case R200_EMIT_ATF_TFACTOR: + case R200_EMIT_PP_TXCTLALL_0: + case R200_EMIT_PP_TXCTLALL_1: + case R200_EMIT_PP_TXCTLALL_2: + case R200_EMIT_PP_TXCTLALL_3: + case R200_EMIT_PP_TXCTLALL_4: + case R200_EMIT_PP_TXCTLALL_5: /* These packets don't contain memory offsets */ break; @@ -568,6 +577,15 @@ static struct { { RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, { RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, { R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, + { R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ + { R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, + { R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, + { R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, + { R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, + { R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, + { R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, + { R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, + { R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, }; From ea98a92ff18c03bf7f4d21536986cbbcb4c10cd9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Sep 2005 20:28:11 +1000 Subject: [PATCH 0054/1940] drm: add radeon PCI express support Add support for Radeon PCI Express cards (needs a new X.org DDX) Also allows PCI GART table to be stored in VRAM for non PCIE cards Signed-off-by: Dave Airlie --- drivers/char/drm/ati_pcigart.c | 82 ++++++++++++++++++++------------- drivers/char/drm/drmP.h | 24 +++++++--- drivers/char/drm/r128_cce.c | 16 ++++--- drivers/char/drm/r128_drv.h | 3 +- drivers/char/drm/radeon_cp.c | 77 ++++++++++++++++++++++++++++--- drivers/char/drm/radeon_drm.h | 1 + drivers/char/drm/radeon_drv.h | 39 ++++++++++++++-- drivers/char/drm/radeon_state.c | 3 ++ 8 files changed, 186 insertions(+), 59 deletions(-) diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 0aec5ef481b8..957596c63934 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c @@ -91,9 +91,7 @@ static void drm_ati_free_pcigart_table( unsigned long address ) free_pages( address, ATI_PCIGART_TABLE_ORDER ); } -int drm_ati_pcigart_cleanup( drm_device_t *dev, - unsigned long addr, - dma_addr_t bus_addr) +int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) { drm_sg_mem_t *entry = dev->sg; unsigned long pages; @@ -105,10 +103,12 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev, return 0; } - if ( bus_addr ) { - pci_unmap_single(dev->pdev, bus_addr, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); + if (gart_info->bus_addr) { + if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) { + pci_unmap_single(dev->pdev, gart_info->bus_addr, + ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, + PCI_DMA_TODEVICE); + } pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) ? entry->pages : ATI_MAX_PCIGART_PAGES; @@ -118,19 +118,21 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev, pci_unmap_single(dev->pdev, entry->busaddr[i], PAGE_SIZE, PCI_DMA_TODEVICE); } + + if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) + gart_info->bus_addr=0; } - if ( addr ) { - drm_ati_free_pcigart_table( addr ); + if (gart_info->gart_table_location==DRM_ATI_GART_MAIN && gart_info->addr) { + drm_ati_free_pcigart_table(gart_info->addr); + gart_info->addr=0; } return 1; } EXPORT_SYMBOL(drm_ati_pcigart_cleanup); -int drm_ati_pcigart_init( drm_device_t *dev, - unsigned long *addr, - dma_addr_t *bus_addr) +int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) { drm_sg_mem_t *entry = dev->sg; unsigned long address = 0; @@ -143,25 +145,36 @@ int drm_ati_pcigart_init( drm_device_t *dev, goto done; } - address = drm_ati_alloc_pcigart_table(); - if ( !address ) { - DRM_ERROR( "cannot allocate PCI GART page!\n" ); - goto done; - } + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) + { + DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); + + address = drm_ati_alloc_pcigart_table(); + if ( !address ) { + DRM_ERROR( "cannot allocate PCI GART page!\n" ); + goto done; + } + + if ( !dev->pdev ) { + DRM_ERROR( "PCI device unknown!\n" ); + goto done; + } - if ( !dev->pdev ) { - DRM_ERROR( "PCI device unknown!\n" ); - goto done; + bus_address = pci_map_single(dev->pdev, (void *)address, + ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, + PCI_DMA_TODEVICE); + if (bus_address == 0) { + DRM_ERROR( "unable to map PCIGART pages!\n" ); + drm_ati_free_pcigart_table( address ); + address = 0; + goto done; + } } - - bus_address = pci_map_single(dev->pdev, (void *)address, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); - if (bus_address == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - drm_ati_free_pcigart_table( address ); - address = 0; - goto done; + else + { + address = gart_info->addr; + bus_address = gart_info->bus_addr; + DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", bus_address, address); } pci_gart = (u32 *)address; @@ -179,7 +192,7 @@ int drm_ati_pcigart_init( drm_device_t *dev, PCI_DMA_TODEVICE); if (entry->busaddr[i] == 0) { DRM_ERROR( "unable to map PCIGART pages!\n" ); - drm_ati_pcigart_cleanup( dev, address, bus_address ); + drm_ati_pcigart_cleanup(dev, gart_info); address = 0; bus_address = 0; goto done; @@ -187,7 +200,10 @@ int drm_ati_pcigart_init( drm_device_t *dev, page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - *pci_gart++ = cpu_to_le32( page_base ); + if (gart_info->is_pcie) + *pci_gart = (cpu_to_le32(page_base)>>8) | 0xc; + else + *pci_gart++ = cpu_to_le32( page_base ); page_base += ATI_PCIGART_PAGE_SIZE; } } @@ -201,8 +217,8 @@ int drm_ati_pcigart_init( drm_device_t *dev, #endif done: - *addr = address; - *bus_addr = bus_address; + gart_info->addr = address; + gart_info->bus_addr = bus_address; return ret; } EXPORT_SYMBOL(drm_ati_pcigart_init); diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 6f98701dfe15..c164c76e33f3 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -532,6 +532,17 @@ typedef struct drm_vbl_sig { } drm_vbl_sig_t; +/* location of GART table */ +#define DRM_ATI_GART_MAIN 1 +#define DRM_ATI_GART_FB 2 + +typedef struct ati_pcigart_info { + int gart_table_location; + int is_pcie; + unsigned long addr; + dma_addr_t bus_addr; +} drm_ati_pcigart_info; + /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -975,12 +986,8 @@ extern int drm_sg_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); /* ATI PCIGART support (ati_pcigart.h) */ -extern int drm_ati_pcigart_init(drm_device_t *dev, - unsigned long *addr, - dma_addr_t *bus_addr); -extern int drm_ati_pcigart_cleanup(drm_device_t *dev, - unsigned long addr, - dma_addr_t bus_addr); +extern int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info); +extern int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info); extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr); @@ -1038,6 +1045,11 @@ static __inline__ int drm_device_is_agp(drm_device_t *dev) return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP); } +static __inline__ int drm_device_is_pcie(drm_device_t *dev) +{ + return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); +} + static __inline__ void drm_core_dropmap(struct drm_map *map) { } diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index 895152206b31..ac3ea2bc9b28 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c @@ -562,14 +562,16 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) #if __OS_HAS_AGP if ( dev_priv->is_pci ) { #endif - if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart) ) { + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; + dev_priv->gart_info.is_pcie = 0; + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR( "failed to init PCI GART!\n" ); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); return DRM_ERR(ENOMEM); } - R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); + R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); #if __OS_HAS_AGP } #endif @@ -607,10 +609,10 @@ int r128_do_cleanup_cce( drm_device_t *dev ) } else #endif { - if (!drm_ati_pcigart_cleanup( dev, - dev_priv->phys_pci_gart, - dev_priv->bus_pci_gart )) - DRM_ERROR( "failed to cleanup PCI GART!\n" ); + if (dev_priv->gart_info.bus_addr) + if (!drm_ati_pcigart_cleanup( dev, + &dev_priv->gart_info)) + DRM_ERROR( "failed to cleanup PCI GART!\n" ); } drm_free( dev->dev_private, sizeof(drm_r128_private_t), diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 0fb687c9505e..938dfaea553a 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h @@ -88,8 +88,6 @@ typedef struct drm_r128_private { int usec_timeout; int is_pci; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; unsigned long cce_buffers_offset; atomic_t idle_count; @@ -120,6 +118,7 @@ typedef struct drm_r128_private { drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; drm_local_map_t *agp_textures; + drm_ati_pcigart_info gart_info; } drm_r128_private_t; typedef struct drm_r128_buf_priv { diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 6d9080a3ca7e..6dff5e43f713 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -825,6 +825,12 @@ static int RADEON_READ_PLL(drm_device_t *dev, int addr) return RADEON_READ(RADEON_CLOCK_CNTL_DATA); } +static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +{ + RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); + return RADEON_READ(RADEON_PCIE_DATA); +} + #if RADEON_FIFO_DEBUG static void radeon_status( drm_radeon_private_t *dev_priv ) { @@ -1241,17 +1247,46 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); } +/* Enable or disable PCI-E GART on the chip */ +static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) +{ + u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); + if (on) { + + DRM_DEBUG("programming pcie %08X %08lX %08X\n", + dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start + + dev_priv->gart_size - 1); + + RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ + + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); + } else { + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); + } +} + /* Enable or disable PCI GART on the chip */ static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) { u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); + if (dev_priv->flags & CHIP_IS_PCIE) + { + radeon_set_pciegart(dev_priv, on); + return; + } + if ( on ) { RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); /* set PCI GART page-table base address */ - RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); + RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); /* set address range for PCI address translate */ @@ -1519,8 +1554,28 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } else #endif { - if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart)) { + /* if we have an offset set from userspace */ + if (dev_priv->pcigart_offset) { + dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.addr = (unsigned long)drm_ioremap(dev_priv->gart_info.bus_addr, RADEON_PCIGART_TABLE_SIZE, dev); + + dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; + + DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); + } + else { + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr= 0; + if (dev_priv->flags & CHIP_IS_PCIE) + { + DRM_ERROR("Cannot use PCI Express without GART in FB memory\n"); + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + } + + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR( "failed to init PCI GART!\n" ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); @@ -1568,10 +1623,15 @@ static int radeon_do_cleanup_cp( drm_device_t *dev ) } else #endif { - if (!drm_ati_pcigart_cleanup( dev, - dev_priv->phys_pci_gart, - dev_priv->bus_pci_gart )) - DRM_ERROR( "failed to cleanup PCI GART!\n" ); + if (dev_priv->gart_info.bus_addr) + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) + { + drm_ioremapfree((void *)dev_priv->gart_info.addr, RADEON_PCIGART_TABLE_SIZE, dev); + dev_priv->gart_info.addr = 0; + } } /* only clear to the start of flags */ @@ -2057,6 +2117,9 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) if (drm_device_is_agp(dev)) dev_priv->flags |= CHIP_IS_AGP; + if (drm_device_is_pcie(dev)) + dev_priv->flags |= CHIP_IS_PCIE; + DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); return ret; diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 67a8bf04970e..dd526617faec 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h @@ -698,6 +698,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ +#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ /* 1.14: Clients can allocate/free a surface */ diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 430598e1fa67..9c10141845e7 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20050720" +#define DRIVER_DATE "20050911" /* Interface history: * @@ -87,9 +87,10 @@ * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) + * 1.19- Add support for gart table in FB memory and PCIE r300 */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 18 +#define DRIVER_MINOR 19 #define DRIVER_PATCHLEVEL 0 #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) @@ -134,6 +135,7 @@ enum radeon_chip_flags { CHIP_SINGLE_CRTC = 0x00040000UL, CHIP_IS_AGP = 0x00080000UL, CHIP_HAS_HIERZ = 0x00100000UL, + CHIP_IS_PCIE = 0x00200000UL, }; typedef struct drm_radeon_freelist { @@ -213,8 +215,6 @@ typedef struct drm_radeon_private { int microcode_version; int is_pci; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; struct { u32 boxes; @@ -270,6 +270,9 @@ typedef struct drm_radeon_private { struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; + unsigned long pcigart_offset; + drm_ati_pcigart_info gart_info; + /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ } drm_radeon_private_t; @@ -373,6 +376,25 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define RADEON_CRTC2_OFFSET 0x0324 #define RADEON_CRTC2_OFFSET_CNTL 0x0328 +#define RADEON_PCIE_INDEX 0x0030 +#define RADEON_PCIE_DATA 0x0034 +#define RADEON_PCIE_TX_GART_CNTL 0x10 +# define RADEON_PCIE_TX_GART_EN (1 << 0) +# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1) +# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1) +# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1) +# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3) +# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3) +# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5) +# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8) +#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11 +#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12 +#define RADEON_PCIE_TX_GART_BASE 0x13 +#define RADEON_PCIE_TX_GART_START_LO 0x14 +#define RADEON_PCIE_TX_GART_START_HI 0x15 +#define RADEON_PCIE_TX_GART_END_LO 0x16 +#define RADEON_PCIE_TX_GART_END_HI 0x17 + #define RADEON_MPP_TB_CONFIG 0x01c0 #define RADEON_MEM_CNTL 0x0140 #define RADEON_MEM_SDRAM_MODE_REG 0x0158 @@ -878,6 +900,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define RADEON_RING_HIGH_MARK 128 +#define RADEON_PCIGART_TABLE_SIZE (32*1024) + #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) @@ -890,6 +914,13 @@ do { \ RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ } while (0) +#define RADEON_WRITE_PCIE( addr, val ) \ +do { \ + RADEON_WRITE8( RADEON_PCIE_INDEX, \ + ((addr) & 0xff)); \ + RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ +} while (0) + #define CP_PACKET0( reg, n ) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET0_TABLE( reg, n ) \ diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index c4325f1e2294..74c2fe8033c2 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -3034,6 +3034,9 @@ static int radeon_cp_setparam( DRM_IOCTL_ARGS ) { dev_priv->sarea_priv->tiling_enabled = 1; } break; + case RADEON_SETPARAM_PCIGART_LOCATION: + dev_priv->pcigart_offset = sp.value; + break; default: DRM_DEBUG( "Invalid parameter %d\n", sp.param ); return DRM_ERR( EINVAL ); From 0b9afede3d9c66fef06f1d5ef5ff15c4b97730fc Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 6 Sep 2005 11:20:49 -0600 Subject: [PATCH 0055/1940] [IA64] more robust zx1/sx1000 machvec support Machine vector selection has always been a bit of a hack given how early in system boot it needs to be done. Services like ACPI namespace are not available and there are non-trivial problems to moving them to early boot. However, there's no reason we can't change to a different machvec later in boot when the services we need are available. By adding a entry point for later initialization of the swiotlb, we can add an error path for the hpzx1 machevec initialization and fall back to the DIG machine vector if IOMMU hardware isn't found in the system. Since ia64 uses 4GB for zone DMA (no ISA support), it's trivial to allocate a contiguous range from the slab for bounce buffer usage. Signed-off-by: Alex Williamson Signed-off-by: Tony Luck --- arch/ia64/hp/common/hwsw_iommu.c | 13 ++- arch/ia64/hp/common/sba_iommu.c | 47 +++++++---- arch/ia64/lib/swiotlb.c | 102 +++++++++++++++++++++++ include/asm-ia64/machvec_hpzx1.h | 21 +++-- include/asm-ia64/machvec_hpzx1_swiotlb.h | 3 +- 5 files changed, 157 insertions(+), 29 deletions(-) diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 80f8ef013939..317c334c5a18 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -17,7 +17,7 @@ #include /* swiotlb declarations & definitions: */ -extern void swiotlb_init_with_default_size (size_t size); +extern int swiotlb_late_init_with_default_size (size_t size); extern ia64_mv_dma_alloc_coherent swiotlb_alloc_coherent; extern ia64_mv_dma_free_coherent swiotlb_free_coherent; extern ia64_mv_dma_map_single swiotlb_map_single; @@ -67,7 +67,16 @@ void hwsw_init (void) { /* default to a smallish 2MB sw I/O TLB */ - swiotlb_init_with_default_size (2 * (1<<20)); + if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) { +#ifdef CONFIG_IA64_GENERIC + /* Better to have normal DMA than panic */ + printk(KERN_WARNING "%s: Failed to initialize software I/O TLB," + " reverting to hpzx1 platform vector\n", __FUNCTION__); + machvec_init("hpzx1"); +#else + panic("Unable to initialize software I/O TLB services"); +#endif + } } void * diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 11957598a8b9..e64ca04ace89 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2028,10 +2028,41 @@ static struct acpi_driver acpi_sba_ioc_driver = { static int __init sba_init(void) { - acpi_bus_register_driver(&acpi_sba_ioc_driver); - if (!ioc_list) + if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb")) return 0; + acpi_bus_register_driver(&acpi_sba_ioc_driver); + if (!ioc_list) { +#ifdef CONFIG_IA64_GENERIC + extern int swiotlb_late_init_with_default_size (size_t size); + + /* + * If we didn't find something sba_iommu can claim, we + * need to setup the swiotlb and switch to the dig machvec. + */ + if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) + panic("Unable to find SBA IOMMU or initialize " + "software I/O TLB: Try machvec=dig boot option"); + machvec_init("dig"); +#else + panic("Unable to find SBA IOMMU: Try a generic or DIG kernel"); +#endif + return 0; + } + +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB) + /* + * hpzx1_swiotlb needs to have a fairly small swiotlb bounce + * buffer setup to support devices with smaller DMA masks than + * sba_iommu can handle. + */ + if (ia64_platform_is("hpzx1_swiotlb")) { + extern void hwsw_init(void); + + hwsw_init(); + } +#endif + #ifdef CONFIG_PCI { struct pci_bus *b = NULL; @@ -2048,18 +2079,6 @@ sba_init(void) subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */ -extern void dig_setup(char**); -/* - * MAX_DMA_ADDRESS needs to be setup prior to paging_init to do any good, - * so we use the platform_setup hook to fix it up. - */ -void __init -sba_setup(char **cmdline_p) -{ - MAX_DMA_ADDRESS = ~0UL; - dig_setup(cmdline_p); -} - static int __init nosbagart(char *str) { diff --git a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c index dbc0b3e449c5..875b0c16250c 100644 --- a/arch/ia64/lib/swiotlb.c +++ b/arch/ia64/lib/swiotlb.c @@ -49,6 +49,15 @@ */ #define IO_TLB_SHIFT 11 +#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) + +/* + * Minimum IO TLB size to bother booting with. Systems with mainly + * 64bit capable cards will only lightly use the swiotlb. If we can't + * allocate a contiguous 1MB, we're probably in trouble anyway. + */ +#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) + int swiotlb_force; /* @@ -154,6 +163,99 @@ swiotlb_init (void) swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ } +/* + * Systems with larger DMA zones (those that don't support ISA) can + * initialize the swiotlb later using the slab allocator if needed. + * This should be just like above, but with some error catching. + */ +int +swiotlb_late_init_with_default_size (size_t default_size) +{ + unsigned long i, req_nslabs = io_tlb_nslabs; + unsigned int order; + + if (!io_tlb_nslabs) { + io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); + io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); + } + + /* + * Get IO TLB memory from the low pages + */ + order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + io_tlb_nslabs = SLABS_PER_PAGE << order; + + while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { + io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN, + order); + if (io_tlb_start) + break; + order--; + } + + if (!io_tlb_start) + goto cleanup1; + + if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) { + printk(KERN_WARNING "Warning: only able to allocate %ld MB " + "for software IO TLB\n", (PAGE_SIZE << order) >> 20); + io_tlb_nslabs = SLABS_PER_PAGE << order; + } + io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); + memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + + /* + * Allocate and initialize the free list array. This array is used + * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE + * between io_tlb_start and io_tlb_end. + */ + io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * sizeof(int))); + if (!io_tlb_list) + goto cleanup2; + + for (i = 0; i < io_tlb_nslabs; i++) + io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); + io_tlb_index = 0; + + io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * sizeof(char *))); + if (!io_tlb_orig_addr) + goto cleanup3; + + memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); + + /* + * Get the overflow emergency buffer + */ + io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA, + get_order(io_tlb_overflow)); + if (!io_tlb_overflow_buffer) + goto cleanup4; + + printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - " + "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20, + virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); + + return 0; + +cleanup4: + free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs * + sizeof(char *))); + io_tlb_orig_addr = NULL; +cleanup3: + free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * + sizeof(int))); + io_tlb_list = NULL; + io_tlb_end = NULL; +cleanup2: + free_pages((unsigned long)io_tlb_start, order); + io_tlb_start = NULL; +cleanup1: + io_tlb_nslabs = req_nslabs; + return -ENOMEM; +} + static inline int address_needs_mapping(struct device *hwdev, dma_addr_t addr) { diff --git a/include/asm-ia64/machvec_hpzx1.h b/include/asm-ia64/machvec_hpzx1.h index daafe504c5f4..e90daf9ce340 100644 --- a/include/asm-ia64/machvec_hpzx1.h +++ b/include/asm-ia64/machvec_hpzx1.h @@ -1,8 +1,7 @@ #ifndef _ASM_IA64_MACHVEC_HPZX1_h #define _ASM_IA64_MACHVEC_HPZX1_h -extern ia64_mv_setup_t dig_setup; -extern ia64_mv_setup_t sba_setup; +extern ia64_mv_setup_t dig_setup; extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; extern ia64_mv_dma_free_coherent sba_free_coherent; extern ia64_mv_dma_map_single sba_map_single; @@ -19,15 +18,15 @@ extern ia64_mv_dma_mapping_error sba_dma_mapping_error; * platform's machvec structure. When compiling a non-generic kernel, * the macros are used directly. */ -#define platform_name "hpzx1" -#define platform_setup sba_setup -#define platform_dma_init machvec_noop -#define platform_dma_alloc_coherent sba_alloc_coherent -#define platform_dma_free_coherent sba_free_coherent -#define platform_dma_map_single sba_map_single -#define platform_dma_unmap_single sba_unmap_single -#define platform_dma_map_sg sba_map_sg -#define platform_dma_unmap_sg sba_unmap_sg +#define platform_name "hpzx1" +#define platform_setup dig_setup +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent sba_alloc_coherent +#define platform_dma_free_coherent sba_free_coherent +#define platform_dma_map_single sba_map_single +#define platform_dma_unmap_single sba_unmap_single +#define platform_dma_map_sg sba_map_sg +#define platform_dma_unmap_sg sba_unmap_sg #define platform_dma_sync_single_for_cpu machvec_dma_sync_single #define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg #define platform_dma_sync_single_for_device machvec_dma_sync_single diff --git a/include/asm-ia64/machvec_hpzx1_swiotlb.h b/include/asm-ia64/machvec_hpzx1_swiotlb.h index 9924b1b00a6c..f00a34a148ff 100644 --- a/include/asm-ia64/machvec_hpzx1_swiotlb.h +++ b/include/asm-ia64/machvec_hpzx1_swiotlb.h @@ -2,7 +2,6 @@ #define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h extern ia64_mv_setup_t dig_setup; -extern ia64_mv_dma_init hwsw_init; extern ia64_mv_dma_alloc_coherent hwsw_alloc_coherent; extern ia64_mv_dma_free_coherent hwsw_free_coherent; extern ia64_mv_dma_map_single hwsw_map_single; @@ -26,7 +25,7 @@ extern ia64_mv_dma_sync_sg_for_device hwsw_sync_sg_for_device; #define platform_name "hpzx1_swiotlb" #define platform_setup dig_setup -#define platform_dma_init hwsw_init +#define platform_dma_init machvec_noop #define platform_dma_alloc_coherent hwsw_alloc_coherent #define platform_dma_free_coherent hwsw_free_coherent #define platform_dma_map_single hwsw_map_single From f2b518d71636c2bda65a837b0a93c3365207a4f0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 14 Sep 2005 16:50:19 -0600 Subject: [PATCH 0056/1940] [IA64] Update default configs PNP and PNPACPI turned on i8042 recently changed from ACPI to PNP detection. Without PNP, it probes legacy I/O ports for the keyboard controller, which causes an MCA on HP boxes. Also, I'm about to remove 8250_acpi.c, so we'll need PNP to detect non-PCI serial ports. Until 8250_acpi.c is removed, some systems will see serial ports reported twice (once from 8250_acpi.c and again from 8250_pnp.c). This is harmless. PNPACPI is still marked EXPERIMENTAL, but I'm not aware of any outstanding issues on ia64. IDE_GENERIC turned off (except for SGI simulator, all ia64 IDE is PCI) ide-generic probes compiled-in legacy I/O ports for IDE devices, which again causes an MCA. It would be nicer to just get rid of all the legacy junk from include/asm-ia64/ide.h, but that is a bit riskier because it could break ide-cs and the HDIO_REGISTER_HWIF ioctl (http://www.ussg.iu.edu/hypermail/linux/kernel/0508.2/0049.html). Here's the essence of the patch: -# CONFIG_PNP is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set Tested on tiger, bigsur, and zx1. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/configs/bigsur_defconfig | 421 +++++++++++++++++++---------- arch/ia64/configs/tiger_defconfig | 86 ++++-- arch/ia64/configs/zx1_defconfig | 92 +++++-- arch/ia64/defconfig | 265 +++++++++++------- 4 files changed, 589 insertions(+), 275 deletions(-) diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index 3b65cbb31b1d..b40672bb3ab0 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc2 -# Mon Nov 29 13:27:48 2004 +# Linux kernel version: 2.6.14-rc1 +# Wed Sep 14 15:18:49 2005 # # @@ -10,34 +10,40 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=16 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -58,12 +64,15 @@ CONFIG_IA64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_IA64_GENERIC is not set CONFIG_IA64_DIG=y # CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_HP_SIM is not set CONFIG_ITANIUM=y @@ -72,17 +81,30 @@ CONFIG_ITANIUM=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_BRL_EMU=y CONFIG_IA64_L1_CACHE_SHIFT=6 # CONFIG_NUMA is not set # CONFIG_VIRTUAL_MEM_MAP is not set # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=2 # CONFIG_HOTPLUG_CPU is not set +# CONFIG_SCHED_SMT is not set CONFIG_PREEMPT=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -95,6 +117,7 @@ CONFIG_IA64_PALINFO=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y +# CONFIG_DELL_RBU is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -102,18 +125,26 @@ CONFIG_BINFMT_MISC=m # Power management and ACPI # CONFIG_PM=y -CONFIG_ACPI=y +# CONFIG_PM_DEBUG is not set # # ACPI (Advanced Configuration and Power Interface) Support # +CONFIG_ACPI=y CONFIG_ACPI_BUTTON=m CONFIG_ACPI_FAN=m CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_CONTAINER is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set # # Bus options (PCI, PCMCIA) @@ -122,7 +153,7 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCI Hotplug Support @@ -135,8 +166,70 @@ CONFIG_PCI_NAMES=y # CONFIG_PCCARD is not set # -# PC-card bridges +# Networking # +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -150,6 +243,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -163,7 +261,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -172,14 +276,15 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -189,6 +294,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -211,7 +317,8 @@ CONFIG_BLK_DEV_IDEFLOPPY=m # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=m +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -233,6 +340,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=m +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -250,6 +358,7 @@ CONFIG_IDEDMA_AUTO=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -261,6 +370,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -274,6 +384,8 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SPI_ATTRS=m # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -288,18 +400,13 @@ CONFIG_SCSI_SPI_ATTRS=m # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y # CONFIG_SCSI_QLOGIC_1280_1040 is not set @@ -309,7 +416,8 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -332,11 +440,14 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set # # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -349,78 +460,25 @@ CONFIG_DM_ZERO=m # CONFIG_I2O is not set # -# Networking support +# Network device support # -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -443,7 +501,6 @@ CONFIG_NET_PCI=y # CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set CONFIG_EEPRO100=y -# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -465,13 +522,17 @@ CONFIG_EEPRO100=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set @@ -496,6 +557,8 @@ CONFIG_EEPRO100=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -524,18 +587,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -553,6 +604,17 @@ CONFIG_MOUSE_PS2=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -571,7 +633,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -579,6 +640,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -603,14 +665,22 @@ CONFIG_EFI_RTC=y # CONFIG_AGP=m CONFIG_AGP_I460=m -CONFIG_DRM=y +CONFIG_DRM=m # CONFIG_DRM_TDFX is not set CONFIG_DRM_R128=m # CONFIG_DRM_RADEON is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -635,7 +705,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set -# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -651,41 +721,16 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_PCA_ISA is not set # -# Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support +# Miscellaneous I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -696,10 +741,55 @@ CONFIG_I2C_ALGOBIT=y # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -752,11 +842,12 @@ CONFIG_SND_OPL3_LIB=m # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_BUS=m # # PCI devices # -CONFIG_SND_AC97_CODEC=m # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set # CONFIG_SND_ATIIXP_MODEM is not set @@ -768,6 +859,8 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_CS46XX is not set CONFIG_SND_CS4281=m # CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set # CONFIG_SND_KORG1212 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -775,9 +868,10 @@ CONFIG_SND_CS4281=m # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set -# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_AD1889 is not set # CONFIG_SND_CMIPCI is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set @@ -791,13 +885,14 @@ CONFIG_SND_CS4281=m # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set # # Open Sound System @@ -807,6 +902,8 @@ CONFIG_SND_CS4281=m # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=m # CONFIG_USB_DEBUG is not set @@ -818,35 +915,38 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers # # CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_OHCI_HCD is not set CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # -CONFIG_USB_AUDIO=m +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_BLUETOOTH_TTY=m -CONFIG_USB_MIDI=m CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set # # USB Input Devices @@ -863,19 +963,23 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -894,6 +998,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -909,7 +1014,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -918,10 +1022,12 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -929,11 +1035,26 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_GADGET is not set +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -945,17 +1066,20 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=y -# CONFIG_XFS_RT is not set +CONFIG_XFS_EXPORT=y CONFIG_XFS_QUOTA=y CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_QUOTACTL=y CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -982,14 +1106,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS_XATTR=y -CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1013,15 +1134,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1031,9 +1155,11 @@ CONFIG_CIFS=m CONFIG_CIFS_STATS=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1103,8 +1229,12 @@ CONFIG_NLS_UTF8=m # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y # # Profiling support @@ -1115,14 +1245,20 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set # CONFIG_IA64_GRANULE_16MB is not set CONFIG_IA64_GRANULE_64MB=y # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1149,6 +1285,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set @@ -1164,3 +1301,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index d452e18ac494..9bc8bcafc905 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-rc6-tiger-smp -# Wed Aug 17 10:19:51 2005 +# Linux kernel version: 2.6.14-rc1 +# Wed Sep 14 15:17:57 2005 # # @@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y @@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y +# CONFIG_DELL_RBU is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -122,20 +126,27 @@ CONFIG_BINFMT_MISC=m # Power management and ACPI # CONFIG_PM=y -CONFIG_ACPI=y +# CONFIG_PM_DEBUG is not set # # ACPI (Advanced Configuration and Power Interface) Support # +CONFIG_ACPI=y CONFIG_ACPI_BUTTON=m CONFIG_ACPI_FAN=m CONFIG_ACPI_PROCESSOR=m -# CONFIG_ACPI_HOTPLUG_CPU is not set +CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y -# CONFIG_ACPI_CONTAINER is not set +CONFIG_ACPI_CONTAINER=m + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set # # Bus options (PCI, PCMCIA) @@ -144,7 +155,6 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y # CONFIG_PCI_DEBUG is not set # @@ -188,13 +198,18 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + # # SCTP Configuration (EXPERIMENTAL) # @@ -218,9 +233,11 @@ CONFIG_TCP_CONG_BIC=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETFILTER_NETLINK is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -234,6 +251,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -247,7 +269,13 @@ CONFIG_FW_LOADER=m # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -266,7 +294,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -299,7 +326,8 @@ CONFIG_BLK_DEV_IDESCSI=m # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -339,6 +367,7 @@ CONFIG_IDEDMA_AUTO=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -366,6 +395,7 @@ CONFIG_CHR_DEV_SG=m CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -454,12 +484,18 @@ CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -481,6 +517,7 @@ CONFIG_TULIP=m # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set @@ -512,6 +549,7 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set @@ -521,6 +559,7 @@ CONFIG_TIGON3=y # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set @@ -618,6 +657,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_ROCKETPORT is not set # CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set @@ -675,6 +715,7 @@ CONFIG_DRM_RADEON=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m # CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set CONFIG_RAW_DRIVER=m CONFIG_HPET=y # CONFIG_HPET_RTC_IRQ is not set @@ -691,7 +732,6 @@ CONFIG_MAX_RAW_DEVS=256 # I2C support # # CONFIG_I2C is not set -# CONFIG_I2C_SENSOR is not set # # Dallas's 1-wire bus @@ -702,12 +742,17 @@ CONFIG_MAX_RAW_DEVS=256 # Hardware Monitoring support # CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -800,9 +845,11 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MTOUCH is not set # CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set # CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices @@ -902,16 +949,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y - -# -# XFS support -# CONFIG_XFS_FS=y CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -919,6 +962,7 @@ CONFIG_INOTIFY=y CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -947,13 +991,11 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_TMPFS_XATTR=y -CONFIG_TMPFS_SECURITY=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1003,6 +1045,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1072,10 +1115,12 @@ CONFIG_NLS_UTF8=m # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y # # Profiling support @@ -1089,6 +1134,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=20 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 80b0e9eb7fb3..0856ca67dd50 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-rc6 -# Wed Aug 17 10:02:43 2005 +# Linux kernel version: 2.6.14-rc1 +# Wed Sep 14 15:15:01 2005 # # @@ -18,6 +18,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set @@ -29,6 +30,7 @@ CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set # CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set @@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y +# CONFIG_DELL_RBU is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y @@ -122,20 +126,27 @@ CONFIG_BINFMT_MISC=y # Power management and ACPI # CONFIG_PM=y -CONFIG_ACPI=y +# CONFIG_PM_DEBUG is not set # # ACPI (Advanced Configuration and Power Interface) Support # +CONFIG_ACPI=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y # CONFIG_ACPI_CONTAINER is not set +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + # # Bus options (PCI, PCMCIA) # @@ -143,7 +154,6 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y # CONFIG_PCI_DEBUG is not set # @@ -187,8 +197,8 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set -# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y @@ -204,13 +214,17 @@ CONFIG_NETFILTER=y # IP: Netfilter Configuration # # CONFIG_IP_NF_CONNTRACK is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set # CONFIG_IP_NF_QUEUE is not set # CONFIG_IP_NF_IPTABLES is not set CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set # CONFIG_IP_NF_ARP_MANGLE is not set +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + # # SCTP Configuration (EXPERIMENTAL) # @@ -234,9 +248,11 @@ CONFIG_IP_NF_ARPTABLES=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETFILTER_NETLINK is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -250,6 +266,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -263,7 +284,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -282,7 +309,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -315,7 +341,8 @@ CONFIG_BLK_DEV_IDECD=y # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -354,6 +381,7 @@ CONFIG_BLK_DEV_IDEDMA=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -381,6 +409,7 @@ CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -457,12 +486,18 @@ CONFIG_DUMMY=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -485,6 +520,7 @@ CONFIG_TULIP_NAPI_HW_MITIGATION=y # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set @@ -516,6 +552,7 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set @@ -525,6 +562,7 @@ CONFIG_TIGON3=y # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set @@ -650,12 +688,12 @@ CONFIG_AGP=y CONFIG_AGP_HP_ZX1=y CONFIG_DRM=y # CONFIG_DRM_TDFX is not set -# CONFIG_DRM_GAMMA is not set # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=y # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set # CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set # CONFIG_HANGCHECK_TIMER is not set @@ -689,7 +727,6 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -703,7 +740,6 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set # CONFIG_I2C_PCA_ISA is not set -# CONFIG_I2C_SENSOR is not set # # Miscellaneous I2C Chip support @@ -730,11 +766,16 @@ CONFIG_I2C_ALGOPCF=y # Hardware Monitoring support # # CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -806,6 +847,7 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set # CONFIG_FB_S1D13XXX is not set @@ -862,11 +904,12 @@ CONFIG_SND_OPL3_LIB=y # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y # # PCI devices # -CONFIG_SND_AC97_CODEC=y # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set # CONFIG_SND_ATIIXP_MODEM is not set @@ -890,7 +933,7 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set -# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_AD1889 is not set # CONFIG_SND_CMIPCI is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set @@ -952,9 +995,8 @@ CONFIG_USB_UHCI_HCD=y # # USB Device Class drivers # -# CONFIG_USB_AUDIO is not set +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set @@ -971,6 +1013,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set # # USB Input Devices @@ -987,9 +1030,11 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_MTOUCH is not set # CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set # CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices @@ -1088,10 +1133,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set - -# -# XFS support -# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1100,6 +1141,7 @@ CONFIG_FS_MBCACHE=y CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -1126,13 +1168,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_TMPFS_XATTR=y -CONFIG_TMPFS_SECURITY=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1177,6 +1217,7 @@ CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1246,10 +1287,12 @@ CONFIG_NLS_UTF8=y # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y # # Profiling support @@ -1263,6 +1306,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=17 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 5da208115ea1..6e3f147e03e5 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12 -# Tue Jun 21 11:30:42 2005 +# Linux kernel version: 2.6.14-rc1 +# Wed Sep 14 15:13:03 2005 # # @@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y @@ -80,6 +82,10 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 CONFIG_NUMA=y CONFIG_VIRTUAL_MEM_MAP=y @@ -87,12 +93,21 @@ CONFIG_HOLES_IN_ZONE=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=512 CONFIG_HOTPLUG_CPU=y # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -105,6 +120,7 @@ CONFIG_IA64_PALINFO=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y +# CONFIG_DELL_RBU is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -112,22 +128,29 @@ CONFIG_BINFMT_MISC=m # Power management and ACPI # CONFIG_PM=y -CONFIG_ACPI=y +# CONFIG_PM_DEBUG is not set # # ACPI (Advanced Configuration and Power Interface) Support # +CONFIG_ACPI=y CONFIG_ACPI_BUTTON=m CONFIG_ACPI_FAN=m CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=m CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_ACPI_CONTAINER=m +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + # # Bus options (PCI, PCMCIA) # @@ -135,7 +158,6 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y # CONFIG_PCI_DEBUG is not set # @@ -147,12 +169,80 @@ CONFIG_HOTPLUG_PCI_ACPI=m # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set # CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI_SGI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -162,9 +252,14 @@ CONFIG_HOTPLUG_PCI_ACPI=m # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -178,7 +273,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -197,7 +298,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -230,7 +330,8 @@ CONFIG_BLK_DEV_IDESCSI=m # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -252,6 +353,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -270,6 +372,7 @@ CONFIG_IDEDMA_AUTO=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -297,6 +400,7 @@ CONFIG_CHR_DEV_SG=m CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -314,6 +418,7 @@ CONFIG_SCSI_SATA=y # CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set # CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_MV is not set # CONFIG_SCSI_SATA_NV is not set # CONFIG_SCSI_SATA_PROMISE is not set # CONFIG_SCSI_SATA_QSTOR is not set @@ -335,7 +440,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set CONFIG_SCSI_QLOGIC_1280=y # CONFIG_SCSI_QLOGIC_1280_1040 is not set CONFIG_SCSI_QLA2XXX=y @@ -344,6 +448,7 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -390,80 +495,25 @@ CONFIG_FUSION_MAX_SGE=128 # CONFIG_I2O is not set # -# Networking support +# Network device support # -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -485,6 +535,7 @@ CONFIG_TULIP=m # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set @@ -516,6 +567,7 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set @@ -525,6 +577,7 @@ CONFIG_TIGON3=y # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set @@ -549,6 +602,10 @@ CONFIG_TIGON3=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y # # ISDN subsystem @@ -607,9 +664,7 @@ CONFIG_GAMEPORT=m # CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_VORTEX is not set # CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_CS461X is not set # # Character devices @@ -620,6 +675,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_ROCKETPORT is not set # CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set @@ -641,7 +697,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -650,8 +705,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SGI_L1_CONSOLE=y -CONFIG_SERIAL_SGI_IOC4=y # CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_SGI_IOC4=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -684,6 +739,8 @@ CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set CONFIG_RAW_DRIVER=m CONFIG_HPET=y # CONFIG_HPET_RTC_IRQ is not set @@ -707,10 +764,21 @@ CONFIG_MMTIMER=y # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -753,6 +821,7 @@ CONFIG_SND_PCM_OSS=m CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_VERBOSE_PRINTK=y # CONFIG_SND_DEBUG is not set +CONFIG_SND_GENERIC_DRIVER=y # # Generic devices @@ -764,11 +833,12 @@ CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m CONFIG_SND_SERIAL_U16550=m CONFIG_SND_MPU401=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_BUS=m # # PCI devices # -CONFIG_SND_AC97_CODEC=m # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set # CONFIG_SND_ATIIXP_MODEM is not set @@ -790,9 +860,10 @@ CONFIG_SND_EMU10K1=m # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set -# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_AD1889 is not set # CONFIG_SND_CMIPCI is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set @@ -844,6 +915,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -853,9 +925,8 @@ CONFIG_USB_UHCI_HCD=m # # USB Device Class drivers # -# CONFIG_USB_AUDIO is not set +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set @@ -888,12 +959,17 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices @@ -918,7 +994,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set -CONFIG_USB_MON=m +CONFIG_USB_MON=y # # USB port drivers @@ -944,10 +1020,11 @@ CONFIG_USB_MON=m # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -964,6 +1041,8 @@ CONFIG_USB_MON=m # InfiniBand support # CONFIG_INFINIBAND=m +# CONFIG_INFINIBAND_USER_MAD is not set +# CONFIG_INFINIBAND_USER_ACCESS is not set CONFIG_INFINIBAND_MTHCA=m # CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m @@ -981,6 +1060,7 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -996,22 +1076,20 @@ CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y - -# -# XFS support -# CONFIG_XFS_FS=y CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -1040,14 +1118,11 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_TMPFS_XATTR=y -CONFIG_TMPFS_SECURITY=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1071,15 +1146,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1094,6 +1172,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1163,10 +1242,12 @@ CONFIG_NLS_UTF8=m # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y # # HP Simulator drivers @@ -1187,6 +1268,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=20 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1194,6 +1276,7 @@ CONFIG_LOG_BUF_SHIFT=20 # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1215,7 +1298,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set From 24ee0a6d7b0a52b140c880aae24c255de3b4a9a1 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Mon, 12 Sep 2005 12:15:43 -0500 Subject: [PATCH 0057/1940] [IA64] Cleanup use of various #defines related to nodes Some of the SN code & #defines related to compact nodes & IO discovery have gotten stale over the years. This patch attempts to clean them up. Some of the various SN MAX_xxx #defines were also unclear & misused. The primary changes are: - use MAX_NUMNODES. This is the generic linux #define for the number of nodes that are known to the generic kernel. Arrays & loops for constructs that are 1:1 with linux-defined nodes should use the linux #define - not an SN equivalent. - use MAX_COMPACT_NODES for MAX_NUMNODES + NUM_TIOS. This is the number of nodes in the SSI system. Compact nodes are a hack to get around the IA64 architectural limit of 256 nodes. Large SGI systems have more than 256 nodes. When we upgrade to ACPI3.0, I _hope_ that all nodes will be real nodes that are known to the generic kernel. That will allow us to delete the notion of "compact nodes". - add MAX_NUMALINK_NODES for the total number of nodes that are in the numalink domain - all partitions. - simplified (understandable) scan_for_ionodes() - small amount of cleanup related to cnodes Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/io_init.c | 4 +- arch/ia64/sn/kernel/setup.c | 164 +++++++++------------------- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 4 +- arch/ia64/sn/kernel/tiocx.c | 5 +- arch/ia64/sn/kernel/xpc_partition.c | 2 +- drivers/char/snsc.c | 4 +- include/asm-ia64/sn/arch.h | 36 ++++-- include/asm-ia64/sn/io.h | 2 +- include/asm-ia64/sn/klconfig.h | 34 +----- include/asm-ia64/sn/sn_cpuid.h | 3 - include/asm-ia64/sn/sn_sal.h | 12 +- include/asm-ia64/sn/xp.h | 2 +- 12 files changed, 94 insertions(+), 178 deletions(-) diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 906622d9f933..b4f5053f5e1b 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -22,8 +22,6 @@ #include "xtalk/hubdev.h" #include "xtalk/xwidgetdev.h" -nasid_t master_nasid = INVALID_NASID; /* Partition Master */ - static struct list_head sn_sysdata_list; /* sysdata list struct */ @@ -165,7 +163,7 @@ static void sn_fixup_ionodes(void) * Get SGI Specific HUB chipset information. * Inform Prom that this kernel can support domain bus numbering. */ - for (i = 0; i < numionodes; i++) { + for (i = 0; i < num_cnodes; i++) { hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); nasid = cnodeid_to_nasid(i); hubdev->max_segment_number = 0xffffffff; diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 6f8c5883716b..0fb579ef18c2 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -59,8 +59,6 @@ DEFINE_PER_CPU(struct pda_s, pda_percpu); #define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */ -lboard_t *root_lboard[MAX_COMPACT_NODES]; - extern void bte_init_node(nodepda_t *, cnodeid_t); extern void sn_timer_init(void); @@ -97,15 +95,15 @@ u8 sn_region_size; EXPORT_SYMBOL(sn_region_size); int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ -short physical_node_map[MAX_PHYSNODE_ID]; +short physical_node_map[MAX_NUMALINK_NODES]; static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS]; EXPORT_SYMBOL(physical_node_map); -int numionodes; +int num_cnodes; static void sn_init_pdas(char **); -static void scan_for_ionodes(void); +static void build_cnode_tables(void); static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; @@ -139,19 +137,6 @@ extern char drive_info[4 * 16]; char drive_info[4 * 16]; #endif -/* - * Get nasid of current cpu early in boot before nodepda is initialized - */ -static int -boot_get_nasid(void) -{ - int nasid; - - if (ia64_sn_get_sapic_info(get_sapicid(), &nasid, NULL, NULL)) - BUG(); - return nasid; -} - /* * This routine can only be used during init, since * smp_boot_data is an init data structure. @@ -223,7 +208,6 @@ void __init early_sn_setup(void) } extern int platform_intr_list[]; -extern nasid_t master_nasid; static int __initdata shub_1_1_found = 0; /* @@ -269,7 +253,6 @@ static void __init sn_check_for_wars(void) void __init sn_setup(char **cmdline_p) { long status, ticks_per_sec, drift; - int pxm; u32 version = sn_sal_rev(); extern void sn_cpu_init(void); @@ -300,11 +283,10 @@ void __init sn_setup(char **cmdline_p) MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY; - memset(physical_node_map, -1, sizeof(physical_node_map)); - for (pxm = 0; pxm < MAX_PXM_DOMAINS; pxm++) - if (pxm_to_nid_map[pxm] != -1) - physical_node_map[pxm_to_nasid(pxm)] = - pxm_to_nid_map[pxm]; + /* + * Build the tables for managing cnodes. + */ + build_cnode_tables(); /* * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard @@ -319,8 +301,6 @@ void __init sn_setup(char **cmdline_p) printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); - master_nasid = boot_get_nasid(); - status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift); @@ -378,15 +358,6 @@ static void __init sn_init_pdas(char **cmdline_p) { cnodeid_t cnode; - memset(sn_cnodeid_to_nasid, -1, - sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); - for_each_online_node(cnode) - sn_cnodeid_to_nasid[cnode] = - pxm_to_nasid(nid_to_pxm_map[cnode]); - - numionodes = num_online_nodes(); - scan_for_ionodes(); - /* * Allocate & initalize the nodepda for each node. */ @@ -402,7 +373,7 @@ static void __init sn_init_pdas(char **cmdline_p) /* * Allocate & initialize nodepda for TIOs. For now, put them on node 0. */ - for (cnode = num_online_nodes(); cnode < numionodes; cnode++) { + for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) { nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t)); memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); @@ -411,7 +382,7 @@ static void __init sn_init_pdas(char **cmdline_p) /* * Now copy the array of nodepda pointers to each nodepda. */ - for (cnode = 0; cnode < numionodes; cnode++) + for (cnode = 0; cnode < num_cnodes; cnode++) memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr)); @@ -428,7 +399,7 @@ static void __init sn_init_pdas(char **cmdline_p) * Initialize the per node hubdev. This includes IO Nodes and * headless/memless nodes. */ - for (cnode = 0; cnode < numionodes; cnode++) { + for (cnode = 0; cnode < num_cnodes; cnode++) { hubdev_init_node(nodepdaindr[cnode], cnode); } } @@ -553,87 +524,58 @@ void __init sn_cpu_init(void) } /* - * Scan klconfig for ionodes. Add the nasids to the - * physical_node_map and the pda and increment numionodes. + * Build tables for converting between NASIDs and cnodes. */ - -static void __init scan_for_ionodes(void) +static inline int __init board_needs_cnode(int type) { - int nasid = 0; + return (type == KLTYPE_SNIA || type == KLTYPE_TIO); +} + +void __init build_cnode_tables(void) +{ + int nasid; + int node; lboard_t *brd; + memset(physical_node_map, -1, sizeof(physical_node_map)); + memset(sn_cnodeid_to_nasid, -1, + sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); + + /* + * First populate the tables with C/M bricks. This ensures that + * cnode == node for all C & M bricks. + */ + for_each_online_node(node) { + nasid = pxm_to_nasid(nid_to_pxm_map[node]); + sn_cnodeid_to_nasid[node] = nasid; + physical_node_map[nasid] = node; + } + + /* + * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node + * limit on the number of nodes, we can't use the generic node numbers + * for this. Note that num_cnodes is incremented below as TIOs or + * headless/memoryless nodes are discovered. + */ + num_cnodes = num_online_nodes(); + /* fakeprom does not support klgraph */ if (IS_RUNNING_ON_FAKE_PROM()) return; - /* Setup ionodes with memory */ - for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { - char *klgraph_header; - cnodeid_t cnodeid; - - if (physical_node_map[nasid] == -1) - continue; - - cnodeid = -1; - klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid)); - if (!klgraph_header) { - BUG(); /* All nodes must have klconfig tables! */ - } - cnodeid = nasid_to_cnodeid(nasid); - root_lboard[cnodeid] = (lboard_t *) - NODE_OFFSET_TO_LBOARD((nasid), - ((kl_config_hdr_t - *) (klgraph_header))-> - ch_board_info); - } - - /* Scan headless/memless IO Nodes. */ - for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { - /* if there's no nasid, don't try to read the klconfig on the node */ - if (physical_node_map[nasid] == -1) - continue; - brd = find_lboard_any((lboard_t *) - root_lboard[nasid_to_cnodeid(nasid)], - KLTYPE_SNIA); - if (brd) { - brd = KLCF_NEXT_ANY(brd); /* Skip this node's lboard */ - if (!brd) - continue; - } - - brd = find_lboard_any(brd, KLTYPE_SNIA); - + /* Find TIOs & headless/memoryless nodes and add them to the tables */ + for_each_online_node(node) { + kl_config_hdr_t *klgraph_header; + nasid = cnodeid_to_nasid(node); + if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL) + BUG(); + brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); while (brd) { - sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid; - physical_node_map[brd->brd_nasid] = numionodes; - root_lboard[numionodes] = brd; - numionodes++; - brd = KLCF_NEXT_ANY(brd); - if (!brd) - break; - - brd = find_lboard_any(brd, KLTYPE_SNIA); - } - } - - /* Scan for TIO nodes. */ - for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { - /* if there's no nasid, don't try to read the klconfig on the node */ - if (physical_node_map[nasid] == -1) - continue; - brd = find_lboard_any((lboard_t *) - root_lboard[nasid_to_cnodeid(nasid)], - KLTYPE_TIO); - while (brd) { - sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid; - physical_node_map[brd->brd_nasid] = numionodes; - root_lboard[numionodes] = brd; - numionodes++; - brd = KLCF_NEXT_ANY(brd); - if (!brd) - break; - - brd = find_lboard_any(brd, KLTYPE_TIO); + if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) { + sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid; + physical_node_map[brd->brd_nasid] = num_cnodes++; + } + brd = find_lboard_next(brd); } } } diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 0513aacac8c1..6c6fbca3229c 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -476,8 +476,8 @@ static int sn_topology_show(struct seq_file *s, void *d) for_each_online_cpu(j) { seq_printf(s, j ? ":%d" : ", dist %d", node_distance( - cpuid_to_cnodeid(i), - cpuid_to_cnodeid(j))); + cpu_to_node(i), + cpu_to_node(j))); } seq_putc(s, '\n'); } diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index b45db5133f55..7e9764a69dc8 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -486,11 +486,10 @@ static int __init tiocx_init(void) bus_register(&tiocx_bus_type); - for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { + for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { nasid_t nasid; - if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) - break; /* No more nasids .. bail out of loop */ + nasid = cnodeid_to_nasid(cnodeid); if ((nasid & 0x1) && is_fpga_brick(nasid)) { struct hubdev_info *hubdev; diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 578265ea9e67..72ef330fb784 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -44,7 +44,7 @@ static u64 xpc_sh2_IPI_access3; /* original protection values for each node */ -u64 xpc_prot_vec[MAX_COMPACT_NODES]; +u64 xpc_prot_vec[MAX_NUMNODES]; /* this partition's reserved page */ diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 261a41bf6d02..a025a89ea70a 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -377,7 +377,7 @@ scdrv_init(void) dev_t first_dev, dev; nasid_t event_nasid = ia64_sn_get_console_nasid(); - if (alloc_chrdev_region(&first_dev, 0, numionodes, + if (alloc_chrdev_region(&first_dev, 0, num_cnodes, SYSCTL_BASENAME) < 0) { printk("%s: failed to register SN system controller device\n", __FUNCTION__); @@ -385,7 +385,7 @@ scdrv_init(void) } snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); - for (cnode = 0; cnode < numionodes; cnode++) { + for (cnode = 0; cnode < num_cnodes; cnode++) { geoid = cnodeid_get_geoid(cnode); devnamep = devname; format_module_id(devnamep, geo_module(geoid), diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h index ab827d298569..8fce5a6db951 100644 --- a/include/asm-ia64/sn/arch.h +++ b/include/asm-ia64/sn/arch.h @@ -17,6 +17,32 @@ #include #include +/* + * This is the maximum number of NUMALINK nodes that can be part of a single + * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in + * remote partitions are NOT included in this number. + * The number of compact nodes cannot exceed size of a coherency domain. + * The purpose of this define is to specify a node count that includes + * all C/M/TIO nodes in an SSI system. + * + * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes. + * + * Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade + * to ACPI3.0, this limit will be removed. The notion of "compact nodes" + * should be deleted and TIOs should be included in MAX_NUMNODES. + */ +#define MAX_COMPACT_NODES 512 + +/* + * Maximum number of nodes in all partitions and in all coherency domains. + * This is the total number of nodes accessible in the numalink fabric. It + * includes all C & M bricks, plus all TIOs. + * + * This value is also the value of the maximum number of NASIDs in the numalink + * fabric. + */ +#define MAX_NUMALINK_NODES 2048 + /* * The following defines attributes of the HUB chip. These attributes are * frequently referenced. They are kept in the per-cpu data areas of each cpu. @@ -40,15 +66,6 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); #define enable_shub_wars_1_1() (sn_hub_info->shub_1_1_found) -/* - * This is the maximum number of nodes that can be part of a kernel. - * Effectively, it's the maximum number of compact node ids (cnodeid_t). - * This is not necessarily the same as MAX_NASIDS. - */ -#define MAX_COMPACT_NODES 2048 -#define CPUS_PER_NODE 4 - - /* * Compact node ID to nasid mappings kept in the per-cpu data areas of each * cpu. @@ -57,7 +74,6 @@ DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); #define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0])) - extern u8 sn_partition_id; extern u8 sn_system_size; extern u8 sn_sharing_domain_size; diff --git a/include/asm-ia64/sn/io.h b/include/asm-ia64/sn/io.h index 42209733f6b1..ac30c747c5ab 100644 --- a/include/asm-ia64/sn/io.h +++ b/include/asm-ia64/sn/io.h @@ -14,7 +14,7 @@ extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */ extern void __sn_mmiowb(void); /* Forward definition */ -extern int numionodes; +extern int num_cnodes; #define __sn_mf_a() ia64_mfa() diff --git a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h index 9f920c70a62a..bcbf209d63be 100644 --- a/include/asm-ia64/sn/klconfig.h +++ b/include/asm-ia64/sn/klconfig.h @@ -208,19 +208,6 @@ typedef struct lboard_s { klconf_off_t brd_next_same; /* Next BOARD with same nasid */ } lboard_t; -#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts) -#define NODE_OFFSET_TO_KLINFO(n,off) ((klinfo_t*) TO_NODE_CAC(n,off)) -#define KLCF_NEXT(_brd) \ - ((_brd)->brd_next_same ? \ - (NODE_OFFSET_TO_LBOARD((_brd)->brd_next_same_host, (_brd)->brd_next_same)): NULL) -#define KLCF_NEXT_ANY(_brd) \ - ((_brd)->brd_next_any ? \ - (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next_any)): NULL) -#define KLCF_COMP(_brd, _ndx) \ - ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \ - (NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)]))) - - /* * Generic info structure. This stores common info about a * component. @@ -249,24 +236,11 @@ typedef struct klinfo_s { /* Generic info */ } klinfo_t ; -static inline lboard_t *find_lboard_any(lboard_t * start, unsigned char brd_type) +static inline lboard_t *find_lboard_next(lboard_t * brd) { - /* Search all boards stored on this node. */ - - while (start) { - if (start->brd_type == brd_type) - return start; - start = KLCF_NEXT_ANY(start); - } - /* Didn't find it. */ - return (lboard_t *) NULL; + if (brd && brd->brd_next_any) + return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any); + return NULL; } - -/* external declarations of Linux kernel functions. */ - -extern lboard_t *root_lboard[]; -extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type); -extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type); - #endif /* _ASM_IA64_SN_KLCONFIG_H */ diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h index d2c1d34dcce4..749deb2ca6c1 100644 --- a/include/asm-ia64/sn/sn_cpuid.h +++ b/include/asm-ia64/sn/sn_cpuid.h @@ -105,7 +105,6 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */ #define cpuid_to_nasid(cpuid) (sn_nodepda->phys_cpuid[cpuid].nasid) #define cpuid_to_subnode(cpuid) (sn_nodepda->phys_cpuid[cpuid].subnode) #define cpuid_to_slice(cpuid) (sn_nodepda->phys_cpuid[cpuid].slice) -#define cpuid_to_cnodeid(cpuid) (physical_node_map[cpuid_to_nasid(cpuid)]) /* @@ -113,8 +112,6 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */ * of potentially large tables. */ extern int nasid_slice_to_cpuid(int, int); -#define nasid_slice_to_cpu_physical_id(nasid, slice) \ - cpu_physical_id(nasid_slice_to_cpuid(nasid, slice)) /* * cnodeid_to_nasid - convert a cnodeid to a NASID diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index fea35b33d4e4..5ad855db8464 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -198,26 +198,16 @@ ia64_sn_get_master_baseio_nasid(void) return ret_stuff.v0; } -static inline char * +static inline void * ia64_sn_get_klconfig_addr(nasid_t nasid) { struct ia64_sal_retval ret_stuff; - int cnodeid; - cnodeid = nasid_to_cnodeid(nasid); ret_stuff.status = 0; ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0); - - /* - * We should panic if a valid cnode nasid does not produce - * a klconfig address. - */ - if (ret_stuff.status != 0) { - panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status); - } return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL; } diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index 1df1c9f61a65..75a2f39c6ac6 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h @@ -49,7 +49,7 @@ * C-brick nasids, thus the need for bitmaps which don't account for * odd-numbered (non C-brick) nasids. */ -#define XP_MAX_PHYSNODE_ID (MAX_PHYSNODE_ID / 2) +#define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2) #define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8) #define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64) From 55642d36cd0f626c614f6dfa1151a5af1ff84f36 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 15 Sep 2005 17:00:10 -0700 Subject: [PATCH 0058/1940] [IA64] Two more uses of cpuid_to_cnodeid() must go. s/cpuid_to_cnodeid/cpu_to_node/ Signed-off-by: Tony Luck --- drivers/char/mmtimer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 12006182f575..78c89a3e7825 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -441,7 +441,7 @@ static irqreturn_t mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; - mmtimer_t *base = timers + cpuid_to_cnodeid(smp_processor_id()) * + mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) * NUM_COMPARATORS; unsigned long expires = 0; int result = IRQ_NONE; @@ -608,7 +608,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, */ preempt_disable(); - nodeid = cpuid_to_cnodeid(smp_processor_id()); + nodeid = cpu_to_node(smp_processor_id()); base = timers + nodeid * NUM_COMPARATORS; retry: /* Don't use an allocated timer, or a deleted one that's pending */ From ab2f218f4fa2c36ecd39ac1406eec1e63cd430bd Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 15 Sep 2005 20:44:50 -0700 Subject: [PATCH 0059/1940] [CIFS] Fix compiler warnings Fix some compiler warnings noticed on x64 by me and ppc64 by Shaggy Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/asn1.c | 3 ++- fs/cifs/cifsglob.h | 2 +- fs/cifs/file.c | 4 ++-- fs/cifs/transport.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index e02010dd73ec..98539e2afe81 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -191,7 +191,8 @@ asn1_header_decode(struct asn1_ctx *ctx, unsigned char **eoc, unsigned int *cls, unsigned int *con, unsigned int *tag) { - unsigned int def, len; + unsigned int def = 0; + unsigned int len = 0; if (!asn1_id_decode(ctx, cls, con, tag)) return 0; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a9c791edede5..cd421c76805e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -331,7 +331,7 @@ CIFS_SB(struct super_block *sb) return sb->s_fs_info; } -static inline const char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) +static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) return '/'; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5ecda554f913..4173f23a71d9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -791,8 +791,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data, pTcon = cifs_sb->tcon; - cFYI(1,(" write %d bytes to offset %lld of %s", write_size, - *poffset, file->f_dentry->d_name.name)); /* BB removeme BB */ + cFYI(1,("write %zd bytes to offset %lld of %s", write_size, + *poffset, file->f_dentry->d_name.name)); if (file->private_data == NULL) return -EBADF; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 96f89eb66040..d5e0c4018f92 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -485,7 +485,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, BCC(in_buf) = le16_to_cpu(BCC(in_buf)); } else { rc = -EIO; - cFYI(1,("Bad MID state? ")); + cFYI(1,("Bad MID state?")); } } cifs_no_response_exit2: From eafe87012159a40a1e7151cc576e99a22aea2f0b Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 15 Sep 2005 21:47:30 -0700 Subject: [PATCH 0060/1940] [CIFS] Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 5 +++++ fs/cifs/cifsfs.h | 2 +- fs/cifs/readdir.c | 37 ++++++++++++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 6c73f020ef40..8b55e56cf1fe 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,8 @@ +Version 1.37 +------------ +Fix readdir caching when unlink removes file in current search buffer, +and this is followed by a rewind search to just before the deleted entry. + Version 1.36 ------------ Add support for mounting to older pre-CIFS servers such as Windows9x and ME. diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index bb3404a99e5f..0f6d352ab813 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -97,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.36" +#define CIFS_VERSION "1.37" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index a1e8dc901de4..a86bd1c07602 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -396,7 +396,8 @@ static int initiate_cifs_search(const int xid, struct file *file) rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, &cifsFile->netfid, &cifsFile->srch_inf, - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); if(rc == 0) cifsFile->invalidHandle = FALSE; if((rc == -EOPNOTSUPP) && @@ -513,6 +514,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) return rc; } +/* Check if directory that we are searching has changed so we can decide + whether we can use the cached search results from the previous search */ +static int is_dir_changed(struct file * file) +{ + struct inode * inode; + struct cifsInodeInfo *cifsInfo; + + if(file->f_dentry == NULL) + return 0; + + inode = file->f_dentry->d_inode; + + if(inode == NULL) + return 0; + + cifsInfo = CIFS_I(inode); + + if(cifsInfo->time == 0) + return 1; /* directory was changed, perhaps due to unlink */ + else + return 0; + +} + /* find the corresponding entry in the search */ /* Note that the SMB server returns search entries for . and .. which complicates logic here if we choose to parse for them and we do not @@ -529,7 +554,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, struct cifsFileInfo * cifsFile = file->private_data; /* check if index in the buffer */ - if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) + if((cifsFile == NULL) || (ppCurrentEntry == NULL) || + (num_to_ret == NULL)) return -ENOENT; *ppCurrentEntry = NULL; @@ -537,7 +563,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.entries_in_buffer; /* dump_cifs_file_struct(file, "In fce ");*/ - if(index_to_find < first_entry_in_buffer) { + if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && + is_dir_changed(file)) || + (index_to_find < first_entry_in_buffer)) { /* close and restart search */ cFYI(1,("search backing up - close and restart search")); cifsFile->invalidHandle = TRUE; @@ -604,7 +632,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, } if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { - cFYI(1,("can not return entries when pos_in_buf beyond last entry")); + cFYI(1,("can not return entries pos_in_buf beyond last entry")); *num_to_ret = 0; } else *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; @@ -833,7 +861,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) if(pTcon == NULL) return -EINVAL; - switch ((int) file->f_pos) { case 0: /*if (filldir(direntry, ".", 1, file->f_pos, From f9f5c81769f88bccd177423a30a7d30461754c39 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 15 Sep 2005 23:06:38 -0700 Subject: [PATCH 0061/1940] [CIFS] Add support for legacy servers part six. Fix read syntax so we do not request more than negotiated buffer size even if buffer size is small (smaller than one page) Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/file.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4173f23a71d9..3766db2bb7f2 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1278,6 +1278,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, total_read += bytes_read, current_offset += bytes_read) { current_read_size = min_t(const int, read_size - total_read, cifs_sb->rsize); + /* For windows me and 9x we do not want to request more + than it negotiated since it will refuse the read then */ + if((pTcon->ses) && + !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { + current_read_size = min_t(const int, current_read_size, + pTcon->ses->server->maxBuf - 128); + } rc = -EAGAIN; while (rc == -EAGAIN) { if ((open_file->invalidHandle) && From 54703d3678d13e7406d0b5aa451abb9526d53b9d Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 14 Sep 2005 10:33:40 -0500 Subject: [PATCH 0062/1940] [IA64] Increase max NR_CPUS on IA64 from 512 to 1024 This patch increases the maximum number of cpus supported on IA64 to 1024. No changes are made to the default SSI size. The patch simply allows specifying up to 1024p. There are certainly scaling (& other) issues that also need to be addressed!!! Additional patches will follow..... Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 945c15a0722b..cb7fc19ff080 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -254,8 +254,8 @@ config SMP If you don't know what to do here, say N. config NR_CPUS - int "Maximum number of CPUs (2-512)" - range 2 512 + int "Maximum number of CPUs (2-1024)" + range 2 1024 depends on SMP default "64" help From 0a1e1222b77b9b02457d8126f598e3713559d5c7 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Tue, 6 Sep 2005 15:51:47 -0500 Subject: [PATCH 0063/1940] [PATCH] powerpc: Merge kmap_types.h Here is a patch to merge the ppc and pp64 version of kmap_types.h Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-powerpc/kmap_types.h | 33 ++++++++++++++++++++++++++++++++ include/asm-ppc/kmap_types.h | 25 ------------------------ include/asm-ppc64/kmap_types.h | 23 ---------------------- 3 files changed, 33 insertions(+), 48 deletions(-) create mode 100644 include/asm-powerpc/kmap_types.h delete mode 100644 include/asm-ppc/kmap_types.h delete mode 100644 include/asm-ppc64/kmap_types.h diff --git a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h new file mode 100644 index 000000000000..b6bac6f61c16 --- /dev/null +++ b/include/asm-powerpc/kmap_types.h @@ -0,0 +1,33 @@ +#ifndef _ASM_POWERPC_KMAP_TYPES_H +#define _ASM_POWERPC_KMAP_TYPES_H + +#ifdef __KERNEL__ + +/* + * 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. + */ + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_PPC_SYNC_PAGE, + KM_PPC_SYNC_ICACHE, + KM_TYPE_NR +}; + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_KMAP_TYPES_H */ diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h deleted file mode 100644 index 6d6fc78731e5..000000000000 --- a/include/asm-ppc/kmap_types.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H - -enum km_type { - KM_BOUNCE_READ, - KM_SKB_SUNRPC_DATA, - KM_SKB_DATA_SOFTIRQ, - KM_USER0, - KM_USER1, - KM_BIO_SRC_IRQ, - KM_BIO_DST_IRQ, - KM_PTE0, - KM_PTE1, - KM_IRQ0, - KM_IRQ1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, - KM_PPC_SYNC_PAGE, - KM_PPC_SYNC_ICACHE, - KM_TYPE_NR -}; - -#endif -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h deleted file mode 100644 index fd1574648223..000000000000 --- a/include/asm-ppc64/kmap_types.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H - -enum km_type { - KM_BOUNCE_READ, - KM_SKB_SUNRPC_DATA, - KM_SKB_DATA_SOFTIRQ, - KM_USER0, - KM_USER1, - KM_BIO_SRC_IRQ, - KM_BIO_DST_IRQ, - KM_PTE0, - KM_PTE1, - KM_IRQ0, - KM_IRQ1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, - KM_TYPE_NR -}; - -#endif -#endif /* __KERNEL__ */ From 5f7c690728ace1404f72d74972dcc261674c0dd4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 9 Sep 2005 15:02:25 -0500 Subject: [PATCH 0064/1940] [PATCH] powerpc: Merged ppc_asm.h Merged ppc_asm.h between ppc32 & ppc64. The majority of the file is common between the two architectures excluding how a single GPR is saved/restored and which GPRs are non-volatile. Additionally, moved the ASM_CONST macro used on ppc64 into ppc_asm.h. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/head.S | 6 +- arch/ppc/kernel/head_fsl_booke.S | 6 +- include/{asm-ppc => asm-powerpc}/ppc_asm.h | 211 ++++++++++++------ include/asm-ppc64/cputable.h | 2 +- include/asm-ppc64/mmu.h | 1 + include/asm-ppc64/page.h | 8 +- include/asm-ppc64/ppc_asm.h | 242 --------------------- 7 files changed, 158 insertions(+), 318 deletions(-) rename include/{asm-ppc => asm-powerpc}/ppc_asm.h (62%) delete mode 100644 include/asm-ppc64/ppc_asm.h diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 1960fb8c259c..d05509f197d0 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -804,7 +804,7 @@ load_up_altivec: beq 1f add r4,r4,r6 addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */ - SAVE_32VR(0,r10,r4) + SAVE_32VRS(0,r10,r4) mfvscr vr0 li r10,THREAD_VSCR stvx vr0,r10,r4 @@ -824,7 +824,7 @@ load_up_altivec: stw r4,THREAD_USED_VR(r5) lvx vr0,r10,r5 mtvscr vr0 - REST_32VR(0,r10,r5) + REST_32VRS(0,r10,r5) #ifndef CONFIG_SMP subi r4,r5,THREAD sub r4,r4,r6 @@ -870,7 +870,7 @@ giveup_altivec: addi r3,r3,THREAD /* want THREAD of task */ lwz r5,PT_REGS(r3) cmpwi 0,r5,0 - SAVE_32VR(0, r4, r3) + SAVE_32VRS(0, r4, r3) mfvscr vr0 li r4,THREAD_VSCR stvx vr0,r4,r3 diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index 8e52e8408316..eba5a5f8ff08 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S @@ -853,7 +853,7 @@ load_up_spe: cmpi 0,r4,0 beq 1f addi r4,r4,THREAD /* want THREAD of last_task_used_spe */ - SAVE_32EVR(0,r10,r4) + SAVE_32EVRS(0,r10,r4) evxor evr10, evr10, evr10 /* clear out evr10 */ evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */ li r5,THREAD_ACC @@ -873,7 +873,7 @@ load_up_spe: stw r4,THREAD_USED_SPE(r5) evlddx evr4,r10,r5 evmra evr4,evr4 - REST_32EVR(0,r10,r5) + REST_32EVRS(0,r10,r5) #ifndef CONFIG_SMP subi r4,r5,THREAD stw r4,last_task_used_spe@l(r3) @@ -963,7 +963,7 @@ _GLOBAL(giveup_spe) addi r3,r3,THREAD /* want THREAD of task */ lwz r5,PT_REGS(r3) cmpi 0,r5,0 - SAVE_32EVR(0, r4, r3) + SAVE_32EVRS(0, r4, r3) evxor evr6, evr6, evr6 /* clear out evr6 */ evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */ li r4,THREAD_ACC diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h similarity index 62% rename from include/asm-ppc/ppc_asm.h rename to include/asm-powerpc/ppc_asm.h index bb53e2def363..553035cda00e 100644 --- a/include/asm-ppc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -1,37 +1,39 @@ /* - * include/asm-ppc/ppc_asm.h - * - * Definitions used by various bits of low-level assembly code on PowerPC. - * * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. - * - * 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. */ -#include +#ifndef _ASM_POWERPC_PPC_ASM_H +#define _ASM_POWERPC_PPC_ASM_H + +#ifdef __ASSEMBLY__ /* * Macros for storing registers into and loading registers from * exception frames. */ +#ifdef __powerpc64__ +#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base) +#define REST_GPR(n, base) ld n,GPR0+8*(n)(base) +#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base) +#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base) +#else #define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) -#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) -#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) -#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) -#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) #define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) -#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) -#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) -#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) -#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) - #define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \ SAVE_10GPRS(22, base) #define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \ REST_10GPRS(22, base) +#endif + + +#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) +#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) +#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) +#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) +#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) +#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) +#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) +#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) #define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base) #define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) @@ -47,32 +49,80 @@ #define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) #define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base -#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) -#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base) -#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base) -#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base) -#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base) +#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) +#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) +#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) +#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) +#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) #define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base -#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) -#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base) -#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base) -#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) -#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) +#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) +#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) +#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) +#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) +#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) #define SAVE_EVR(n,s,base) evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base) -#define SAVE_2EVR(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base) -#define SAVE_4EVR(n,s,base) SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base) -#define SAVE_8EVR(n,s,base) SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base) -#define SAVE_16EVR(n,s,base) SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base) -#define SAVE_32EVR(n,s,base) SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base) - +#define SAVE_2EVRS(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base) +#define SAVE_4EVRS(n,s,base) SAVE_2EVRS(n,s,base); SAVE_2EVRS(n+2,s,base) +#define SAVE_8EVRS(n,s,base) SAVE_4EVRS(n,s,base); SAVE_4EVRS(n+4,s,base) +#define SAVE_16EVRS(n,s,base) SAVE_8EVRS(n,s,base); SAVE_8EVRS(n+8,s,base) +#define SAVE_32EVRS(n,s,base) SAVE_16EVRS(n,s,base); SAVE_16EVRS(n+16,s,base) #define REST_EVR(n,s,base) lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n -#define REST_2EVR(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base) -#define REST_4EVR(n,s,base) REST_2EVR(n,s,base); REST_2EVR(n+2,s,base) -#define REST_8EVR(n,s,base) REST_4EVR(n,s,base); REST_4EVR(n+4,s,base) -#define REST_16EVR(n,s,base) REST_8EVR(n,s,base); REST_8EVR(n+8,s,base) -#define REST_32EVR(n,s,base) REST_16EVR(n,s,base); REST_16EVR(n+16,s,base) +#define REST_2EVRS(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base) +#define REST_4EVRS(n,s,base) REST_2EVRS(n,s,base); REST_2EVRS(n+2,s,base) +#define REST_8EVRS(n,s,base) REST_4EVRS(n,s,base); REST_4EVRS(n+4,s,base) +#define REST_16EVRS(n,s,base) REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base) +#define REST_32EVRS(n,s,base) REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base) +/* Macros to adjust thread priority for Iseries hardware multithreading */ +#define HMT_LOW or 1,1,1 +#define HMT_MEDIUM or 2,2,2 +#define HMT_HIGH or 3,3,3 + +/* handle instructions that older assemblers may not know */ +#define RFCI .long 0x4c000066 /* rfci instruction */ +#define RFDI .long 0x4c00004e /* rfdi instruction */ +#define RFMCI .long 0x4c00004c /* rfmci instruction */ + +/* + * LOADADDR( rn, name ) + * loads the address of 'name' into 'rn' + * + * LOADBASE( rn, name ) + * loads the address (less the low 16 bits) of 'name' into 'rn' + * suitable for base+disp addressing + */ +#ifdef __powerpc64__ +#define LOADADDR(rn,name) \ + lis rn,name##@highest; \ + ori rn,rn,name##@higher; \ + rldicr rn,rn,32,31; \ + oris rn,rn,name##@h; \ + ori rn,rn,name##@l + +#define LOADBASE(rn,name) \ + lis rn,name@highest; \ + ori rn,rn,name@higher; \ + rldicr rn,rn,32,31; \ + oris rn,rn,name@ha + + +#define SET_REG_TO_CONST(reg, value) \ + lis reg,(((value)>>48)&0xFFFF); \ + ori reg,reg,(((value)>>32)&0xFFFF); \ + rldicr reg,reg,32,31; \ + oris reg,reg,(((value)>>16)&0xFFFF); \ + ori reg,reg,((value)&0xFFFF); + +#define SET_REG_TO_LABEL(reg, label) \ + lis reg,(label)@highest; \ + ori reg,reg,(label)@higher; \ + rldicr reg,reg,32,31; \ + oris reg,reg,(label)@h; \ + ori reg,reg,(label)@l; +#endif + +/* various errata or part fixups */ #ifdef CONFIG_PPC601_SYNC_FIX #define SYNC \ BEGIN_FTR_SECTION \ @@ -93,6 +143,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) #define ISYNC_601 #endif + #ifndef CONFIG_SMP #define TLBSYNC #else /* CONFIG_SMP */ @@ -104,6 +155,7 @@ BEGIN_FTR_SECTION \ END_FTR_SECTION_IFCLR(CPU_FTR_601) #endif + /* * This instruction is not implemented on the PPC 603 or 601; however, on * the 403GCX and 405GP tlbia IS defined and tlbie is not. @@ -121,14 +173,44 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) bdnz 0b #endif -#ifdef CONFIG_BOOKE + +#ifdef CONFIG_IBM405_ERR77 +#define PPC405_ERR77(ra,rb) dcbt ra, rb; +#define PPC405_ERR77_SYNC sync; +#else +#define PPC405_ERR77(ra,rb) +#define PPC405_ERR77_SYNC +#endif + + +#ifdef CONFIG_IBM440EP_ERR42 +#define PPC440EP_ERR42 isync +#else +#define PPC440EP_ERR42 +#endif + + +#if defined(CONFIG_BOOKE) #define tophys(rd,rs) \ addis rd,rs,0 #define tovirt(rd,rs) \ addis rd,rs,0 -#else /* CONFIG_BOOKE */ +#elif defined(CONFIG_PPC64) +/* PPPBBB - DRENG If KERNELBASE is always 0xC0..., + * Then we can easily do this with one asm insn. -Peter + */ +#define tophys(rd,rs) \ + lis rd,((KERNELBASE>>48)&0xFFFF); \ + rldicr rd,rd,32,31; \ + sub rd,rs,rd + +#define tovirt(rd,rs) \ + lis rd,((KERNELBASE>>48)&0xFFFF); \ + rldicr rd,rd,32,31; \ + add rd,rs,rd +#else /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the * physical base address of RAM at compile time. @@ -146,14 +228,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .align 1; \ .long 0b; \ .previous -#endif /* CONFIG_BOOKE */ +#endif /* * On 64-bit cpus, we use the rfid instruction instead of rfi, but * we then have to make sure we preserve the top 32 bits except for * the 64-bit mode bit, which we clear. */ -#ifdef CONFIG_PPC64BRIDGE +#if defined(CONFIG_PPC64BRIDGE) #define FIX_SRR1(ra, rb) \ mr rb,ra; \ mfmsr ra; \ @@ -162,6 +244,17 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define RFI .long 0x4c000024 /* rfid instruction */ #define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */ #define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ +#elif defined(CONFIG_PPC64) +/* Insert the high 32 bits of the MSR into what will be the new + MSR (via SRR1 and rfid) This preserves the MSR.SF and MSR.ISF + bits. */ + +#define FIX_SRR1(ra, rb) \ + mr rb,ra; \ + mfmsr ra; \ + rldimi ra,rb,0,32 + +#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ #else #define FIX_SRR1(ra, rb) @@ -172,24 +265,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #endif #define MTMSRD(r) mtmsr r #define CLR_TOP32(r) -#endif /* CONFIG_PPC64BRIDGE */ - -#define RFCI .long 0x4c000066 /* rfci instruction */ -#define RFDI .long 0x4c00004e /* rfdi instruction */ -#define RFMCI .long 0x4c00004c /* rfmci instruction */ - -#ifdef CONFIG_IBM405_ERR77 -#define PPC405_ERR77(ra,rb) dcbt ra, rb; -#define PPC405_ERR77_SYNC sync; -#else -#define PPC405_ERR77(ra,rb) -#define PPC405_ERR77_SYNC -#endif - -#ifdef CONFIG_IBM440EP_ERR42 -#define PPC440EP_ERR42 isync -#else -#define PPC440EP_ERR42 #endif /* The boring bits... */ @@ -277,6 +352,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define fr30 30 #define fr31 31 +/* AltiVec Registers (VPRs) */ + #define vr0 0 #define vr1 1 #define vr2 2 @@ -310,6 +387,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define vr30 30 #define vr31 31 +/* SPE Registers (EVPRs) */ + #define evr0 0 #define evr1 1 #define evr2 2 @@ -348,3 +427,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define N_RSYM 64 #define N_SLINE 68 #define N_SO 100 + +#define ASM_CONST(x) x +#else + #define __ASM_CONST(x) x##UL + #define ASM_CONST(x) __ASM_CONST(x) +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_PPC_ASM_H */ diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h index acc9b4d6c168..35121408ed1c 100644 --- a/include/asm-ppc64/cputable.h +++ b/include/asm-ppc64/cputable.h @@ -16,7 +16,7 @@ #define __ASM_PPC_CPUTABLE_H #include -#include /* for ASM_CONST */ +#include /* for ASM_CONST */ /* Exposed to userland CPU features - Must match ppc32 definitions */ #define PPC_FEATURE_32 0x80000000 diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 7bc42eb087ad..737e85a5ce3c 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h @@ -14,6 +14,7 @@ #define _PPC64_MMU_H_ #include +#include /* for ASM_CONST */ #include /* diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index a15422bcf30d..d404431f0a9a 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h @@ -11,13 +11,7 @@ */ #include - -#ifdef __ASSEMBLY__ - #define ASM_CONST(x) x -#else - #define __ASM_CONST(x) x##UL - #define ASM_CONST(x) __ASM_CONST(x) -#endif +#include /* for ASM_CONST */ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 diff --git a/include/asm-ppc64/ppc_asm.h b/include/asm-ppc64/ppc_asm.h deleted file mode 100644 index 9031d8a29aca..000000000000 --- a/include/asm-ppc64/ppc_asm.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * arch/ppc64/kernel/ppc_asm.h - * - * Definitions used by various bits of low-level assembly code on PowerPC. - * - * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. - * - * 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. - */ - -#ifndef _PPC64_PPC_ASM_H -#define _PPC64_PPC_ASM_H -/* - * Macros for storing registers into and loading registers from - * exception frames. - */ -#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base) -#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) -#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) -#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) -#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) -#define REST_GPR(n, base) ld n,GPR0+8*(n)(base) -#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) -#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) -#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) -#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) - -#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base) -#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base) - -#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base) -#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) -#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) -#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) -#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) -#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) -#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*(n)(base) -#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base) -#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base) -#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base) -#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) -#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) - -#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base -#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) -#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) -#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) -#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) -#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) -#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base -#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) -#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) -#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) -#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) -#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) - -/* Macros to adjust thread priority for Iseries hardware multithreading */ -#define HMT_LOW or 1,1,1 -#define HMT_MEDIUM or 2,2,2 -#define HMT_HIGH or 3,3,3 - -/* Insert the high 32 bits of the MSR into what will be the new - MSR (via SRR1 and rfid) This preserves the MSR.SF and MSR.ISF - bits. */ - -#define FIX_SRR1(ra, rb) \ - mr rb,ra; \ - mfmsr ra; \ - rldimi ra,rb,0,32 - -#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ - -/* - * LOADADDR( rn, name ) - * loads the address of 'name' into 'rn' - * - * LOADBASE( rn, name ) - * loads the address (less the low 16 bits) of 'name' into 'rn' - * suitable for base+disp addressing - */ -#define LOADADDR(rn,name) \ - lis rn,name##@highest; \ - ori rn,rn,name##@higher; \ - rldicr rn,rn,32,31; \ - oris rn,rn,name##@h; \ - ori rn,rn,name##@l - -#define LOADBASE(rn,name) \ - lis rn,name@highest; \ - ori rn,rn,name@higher; \ - rldicr rn,rn,32,31; \ - oris rn,rn,name@ha - - -#define SET_REG_TO_CONST(reg, value) \ - lis reg,(((value)>>48)&0xFFFF); \ - ori reg,reg,(((value)>>32)&0xFFFF); \ - rldicr reg,reg,32,31; \ - oris reg,reg,(((value)>>16)&0xFFFF); \ - ori reg,reg,((value)&0xFFFF); - -#define SET_REG_TO_LABEL(reg, label) \ - lis reg,(label)@highest; \ - ori reg,reg,(label)@higher; \ - rldicr reg,reg,32,31; \ - oris reg,reg,(label)@h; \ - ori reg,reg,(label)@l; - - -/* PPPBBB - DRENG If KERNELBASE is always 0xC0..., - * Then we can easily do this with one asm insn. -Peter - */ -#define tophys(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - sub rd,rs,rd - -#define tovirt(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - add rd,rs,rd - -/* Condition Register Bit Fields */ - -#define cr0 0 -#define cr1 1 -#define cr2 2 -#define cr3 3 -#define cr4 4 -#define cr5 5 -#define cr6 6 -#define cr7 7 - - -/* General Purpose Registers (GPRs) */ - -#define r0 0 -#define r1 1 -#define r2 2 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 -#define r9 9 -#define r10 10 -#define r11 11 -#define r12 12 -#define r13 13 -#define r14 14 -#define r15 15 -#define r16 16 -#define r17 17 -#define r18 18 -#define r19 19 -#define r20 20 -#define r21 21 -#define r22 22 -#define r23 23 -#define r24 24 -#define r25 25 -#define r26 26 -#define r27 27 -#define r28 28 -#define r29 29 -#define r30 30 -#define r31 31 - - -/* Floating Point Registers (FPRs) */ - -#define fr0 0 -#define fr1 1 -#define fr2 2 -#define fr3 3 -#define fr4 4 -#define fr5 5 -#define fr6 6 -#define fr7 7 -#define fr8 8 -#define fr9 9 -#define fr10 10 -#define fr11 11 -#define fr12 12 -#define fr13 13 -#define fr14 14 -#define fr15 15 -#define fr16 16 -#define fr17 17 -#define fr18 18 -#define fr19 19 -#define fr20 20 -#define fr21 21 -#define fr22 22 -#define fr23 23 -#define fr24 24 -#define fr25 25 -#define fr26 26 -#define fr27 27 -#define fr28 28 -#define fr29 29 -#define fr30 30 -#define fr31 31 - -#define vr0 0 -#define vr1 1 -#define vr2 2 -#define vr3 3 -#define vr4 4 -#define vr5 5 -#define vr6 6 -#define vr7 7 -#define vr8 8 -#define vr9 9 -#define vr10 10 -#define vr11 11 -#define vr12 12 -#define vr13 13 -#define vr14 14 -#define vr15 15 -#define vr16 16 -#define vr17 17 -#define vr18 18 -#define vr19 19 -#define vr20 20 -#define vr21 21 -#define vr22 22 -#define vr23 23 -#define vr24 24 -#define vr25 25 -#define vr26 26 -#define vr27 27 -#define vr28 28 -#define vr29 29 -#define vr30 30 -#define vr31 31 - -#endif /* _PPC64_PPC_ASM_H */ From 7da8f8600a4751d7f0248e00d973901b7371fabc Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 16 Sep 2005 11:37:33 -0500 Subject: [PATCH 0065/1940] [PATCH] ppc32: Removed non-inlined versions of local_irq* functions We always use the inlined versions of local_irq_enable, local_irq_disable, local_save_flags_ptr, and local_irq_restore on ppc32 so the non-inlined versions where just taking up space. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/misc.S | 128 ------------------------------------ arch/ppc/kernel/ppc_ksyms.c | 10 --- include/asm-ppc/hw_irq.h | 16 ----- 3 files changed, 154 deletions(-) diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 90d917d2e856..9d2cb79475c6 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -273,134 +273,6 @@ _GLOBAL(low_choose_7447a_dfs) #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */ -/* void local_save_flags_ptr(unsigned long *flags) */ -_GLOBAL(local_save_flags_ptr) - mfmsr r4 - stw r4,0(r3) - blr - /* - * Need these nops here for taking over save/restore to - * handle lost intrs - * -- Cort - */ - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -_GLOBAL(local_save_flags_ptr_end) - -/* void local_irq_restore(unsigned long flags) */ -_GLOBAL(local_irq_restore) -/* - * Just set/clear the MSR_EE bit through restore/flags but do not - * change anything else. This is needed by the RT system and makes - * sense anyway. - * -- Cort - */ - mfmsr r4 - /* Copy all except the MSR_EE bit from r4 (current MSR value) - to r3. This is the sort of thing the rlwimi instruction is - designed for. -- paulus. */ - rlwimi r3,r4,0,17,15 - /* Check if things are setup the way we want _already_. */ - cmpw 0,r3,r4 - beqlr -1: SYNC - mtmsr r3 - SYNC - blr - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -_GLOBAL(local_irq_restore_end) - -_GLOBAL(local_irq_disable) - mfmsr r0 /* Get current interrupt state */ - rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */ - rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - SYNC /* Some chip revs have problems here... */ - mtmsr r0 /* Update machine state */ - blr /* Done */ - /* - * Need these nops here for taking over save/restore to - * handle lost intrs - * -- Cort - */ - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -_GLOBAL(local_irq_disable_end) - -_GLOBAL(local_irq_enable) - mfmsr r3 /* Get current state */ - ori r3,r3,MSR_EE /* Turn on 'EE' bit */ - SYNC /* Some chip revs have problems here... */ - mtmsr r3 /* Update machine state */ - blr - /* - * Need these nops here for taking over save/restore to - * handle lost intrs - * -- Cort - */ - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -_GLOBAL(local_irq_enable_end) - /* * complement mask on the msr then "or" some values on. * _nmask_and_or_msr(nmask, value_to_or) diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 88f6bb7b6964..1545621d44d2 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -272,16 +272,6 @@ EXPORT_SYMBOL(screen_info); #endif EXPORT_SYMBOL(__delay); -#ifndef INLINE_IRQS -EXPORT_SYMBOL(local_irq_enable); -EXPORT_SYMBOL(local_irq_enable_end); -EXPORT_SYMBOL(local_irq_disable); -EXPORT_SYMBOL(local_irq_disable_end); -EXPORT_SYMBOL(local_save_flags_ptr); -EXPORT_SYMBOL(local_save_flags_ptr_end); -EXPORT_SYMBOL(local_irq_restore); -EXPORT_SYMBOL(local_irq_restore_end); -#endif EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(tb_ticks_per_jiffy); diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 47dc7990fb26..51a1d7ef5253 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -10,12 +10,8 @@ extern void timer_interrupt(struct pt_regs *); -#define INLINE_IRQS - #define irqs_disabled() ((mfmsr() & MSR_EE) == 0) -#ifdef INLINE_IRQS - static inline void local_irq_disable(void) { unsigned long msr; @@ -45,18 +41,6 @@ static inline void local_irq_save_ptr(unsigned long *flags) #define local_irq_save(flags) local_irq_save_ptr(&flags) #define local_irq_restore(flags) mtmsr(flags) -#else - -extern void local_irq_enable(void); -extern void local_irq_disable(void); -extern void local_irq_restore(unsigned long); -extern void local_save_flags_ptr(unsigned long *); - -#define local_save_flags(flags) local_save_flags_ptr(&flags) -#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();}) - -#endif - extern void do_lost_interrupts(unsigned long); #define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);}) From f495a8bfd6a52cf32859f93d5320bb234d8a9560 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Sat, 17 Sep 2005 10:35:08 -0500 Subject: [PATCH 0066/1940] [PATCH] powerpc: Remove sections use from ppc Here is a new patch that removes all notion of the pmac, prep, chrp and openfirmware initialization sections, and then unifies the sections.h files without those __pmac, etc, sections identifiers cluttering things up. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/pci.c | 10 +- arch/ppc/kernel/setup.c | 2 +- arch/ppc/platforms/chrp_pci.c | 8 +- arch/ppc/platforms/chrp_setup.c | 16 +-- arch/ppc/platforms/chrp_smp.c | 2 +- arch/ppc/platforms/chrp_time.c | 8 +- arch/ppc/platforms/pmac_backlight.c | 16 +-- arch/ppc/platforms/pmac_cpufreq.c | 36 +++--- arch/ppc/platforms/pmac_feature.c | 176 ++++++++++++++-------------- arch/ppc/platforms/pmac_nvram.c | 42 +++---- arch/ppc/platforms/pmac_pci.c | 22 ++-- arch/ppc/platforms/pmac_pic.c | 26 ++-- arch/ppc/platforms/pmac_setup.c | 12 +- arch/ppc/platforms/pmac_smp.c | 10 +- arch/ppc/platforms/pmac_time.c | 8 +- arch/ppc/platforms/prep_pci.c | 64 +++++----- arch/ppc/platforms/prep_setup.c | 44 +++---- arch/ppc/platforms/residual.c | 2 +- arch/ppc/syslib/btext.c | 6 +- arch/ppc/syslib/prep_nvram.c | 13 +- arch/ppc/syslib/prom.c | 18 +-- 21 files changed, 269 insertions(+), 272 deletions(-) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 854e45beb387..2d3c557538b5 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -644,7 +644,7 @@ pcibios_alloc_controller(void) /* * Functions below are used on OpenFirmware machines. */ -static void __openfirmware +static void make_one_node_map(struct device_node* node, u8 pci_bus) { int *bus_range; @@ -678,7 +678,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus) } } -void __openfirmware +void pcibios_make_OF_bus_map(void) { int i; @@ -720,7 +720,7 @@ pcibios_make_OF_bus_map(void) typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); -static struct device_node* __openfirmware +static struct device_node* scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) { struct device_node* sub_node; @@ -761,7 +761,7 @@ scan_OF_pci_childs_iterator(struct device_node* node, void* data) return 0; } -static struct device_node* __openfirmware +static struct device_node* scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) { u8 filter_data[2] = {bus, dev_fn}; @@ -842,7 +842,7 @@ pci_find_hose_for_OF_device(struct device_node* node) return NULL; } -static int __openfirmware +static int find_OF_pci_device_filter(struct device_node* node, void* data) { return ((void *)node == data); diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 545cfd0fab59..8b06b8e00332 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -339,7 +339,7 @@ early_init(int r3, int r4, int r5) * Assume here that all clock rates are the same in a * smp system. -- Cort */ -int __openfirmware +int of_show_percpuinfo(struct seq_file *m, int i) { struct device_node *cpu_node; diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index 7d3fbb5c5db2..f12192cc4d42 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c @@ -29,7 +29,7 @@ void __iomem *gg2_pci_config_base; * limit the bus number to 3 bits */ -int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, +int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, int len, u32 *val) { volatile void __iomem *cfg_data; @@ -56,7 +56,7 @@ int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, return PCIBIOS_SUCCESSFUL; } -int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off, +int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off, int len, u32 val) { volatile void __iomem *cfg_data; @@ -92,7 +92,7 @@ static struct pci_ops gg2_pci_ops = /* * Access functions for PCI config space using RTAS calls. */ -int __chrp +int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -108,7 +108,7 @@ rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; } -int __chrp +int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 57f29ab29bda..47b154c27617 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -105,7 +105,7 @@ static const char *gg2_cachemodes[4] = { "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" }; -int __chrp +int chrp_show_cpuinfo(struct seq_file *m) { int i, sdramen; @@ -303,7 +303,7 @@ void __init chrp_setup_arch(void) pci_create_OF_bus_map(); } -void __chrp +void chrp_event_scan(void) { unsigned char log[1024]; @@ -314,7 +314,7 @@ chrp_event_scan(void) ppc_md.heartbeat_count = ppc_md.heartbeat_reset; } -void __chrp +void chrp_restart(char *cmd) { printk("RTAS system-reboot returned %d\n", @@ -322,7 +322,7 @@ chrp_restart(char *cmd) for (;;); } -void __chrp +void chrp_power_off(void) { /* allow power on only with power button press */ @@ -331,13 +331,13 @@ chrp_power_off(void) for (;;); } -void __chrp +void chrp_halt(void) { chrp_power_off(); } -u_int __chrp +u_int chrp_irq_canonicalize(u_int irq) { if (irq == 2) @@ -572,7 +572,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); } -void __chrp +void rtas_display_progress(char *s, unsigned short hex) { int width; @@ -599,7 +599,7 @@ rtas_display_progress(char *s, unsigned short hex) call_rtas( "display-character", 1, 1, NULL, ' ' ); } -void __chrp +void rtas_indicator_progress(char *s, unsigned short hex) { call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c index 0ea1f7d9e46a..dc62e3209443 100644 --- a/arch/ppc/platforms/chrp_smp.c +++ b/arch/ppc/platforms/chrp_smp.c @@ -88,7 +88,7 @@ smp_chrp_take_timebase(void) } /* CHRP with openpic */ -struct smp_ops_t chrp_smp_ops __chrpdata = { +struct smp_ops_t chrp_smp_ops = { .message_pass = smp_openpic_message_pass, .probe = smp_chrp_probe, .kick_cpu = smp_chrp_kick_cpu, diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c index 6037ce7796f5..29d074c305f0 100644 --- a/arch/ppc/platforms/chrp_time.c +++ b/arch/ppc/platforms/chrp_time.c @@ -52,7 +52,7 @@ long __init chrp_time_init(void) return 0; } -int __chrp chrp_cmos_clock_read(int addr) +int chrp_cmos_clock_read(int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); @@ -60,7 +60,7 @@ int __chrp chrp_cmos_clock_read(int addr) return (inb(nvram_data)); } -void __chrp chrp_cmos_clock_write(unsigned long val, int addr) +void chrp_cmos_clock_write(unsigned long val, int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); @@ -72,7 +72,7 @@ void __chrp chrp_cmos_clock_write(unsigned long val, int addr) /* * Set the hardware clock. -- Cort */ -int __chrp chrp_set_rtc_time(unsigned long nowtime) +int chrp_set_rtc_time(unsigned long nowtime) { unsigned char save_control, save_freq_select; struct rtc_time tm; @@ -118,7 +118,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) return 0; } -unsigned long __chrp chrp_get_rtc_time(void) +unsigned long chrp_get_rtc_time(void) { unsigned int year, mon, day, hour, min, sec; int uip, i; diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c index ed2b1cebc19a..8be2f7d071f0 100644 --- a/arch/ppc/platforms/pmac_backlight.c +++ b/arch/ppc/platforms/pmac_backlight.c @@ -37,7 +37,7 @@ static int backlight_req_enable = -1; static void backlight_callback(void *); static DECLARE_WORK(backlight_work, backlight_callback, NULL); -void __pmac register_backlight_controller(struct backlight_controller *ctrler, +void register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type) { struct device_node* bk_node; @@ -99,7 +99,7 @@ void __pmac register_backlight_controller(struct backlight_controller *ctrler, } EXPORT_SYMBOL(register_backlight_controller); -void __pmac unregister_backlight_controller(struct backlight_controller +void unregister_backlight_controller(struct backlight_controller *ctrler, void *data) { /* We keep the current backlight level (for now) */ @@ -108,7 +108,7 @@ void __pmac unregister_backlight_controller(struct backlight_controller } EXPORT_SYMBOL(unregister_backlight_controller); -static int __pmac __set_backlight_enable(int enable) +static int __set_backlight_enable(int enable) { int rc; @@ -122,7 +122,7 @@ static int __pmac __set_backlight_enable(int enable) release_console_sem(); return rc; } -int __pmac set_backlight_enable(int enable) +int set_backlight_enable(int enable) { if (!backlighter) return -ENODEV; @@ -133,7 +133,7 @@ int __pmac set_backlight_enable(int enable) EXPORT_SYMBOL(set_backlight_enable); -int __pmac get_backlight_enable(void) +int get_backlight_enable(void) { if (!backlighter) return -ENODEV; @@ -141,7 +141,7 @@ int __pmac get_backlight_enable(void) } EXPORT_SYMBOL(get_backlight_enable); -static int __pmac __set_backlight_level(int level) +static int __set_backlight_level(int level) { int rc = 0; @@ -165,7 +165,7 @@ static int __pmac __set_backlight_level(int level) } return rc; } -int __pmac set_backlight_level(int level) +int set_backlight_level(int level) { if (!backlighter) return -ENODEV; @@ -176,7 +176,7 @@ int __pmac set_backlight_level(int level) EXPORT_SYMBOL(set_backlight_level); -int __pmac get_backlight_level(void) +int get_backlight_level(void) { if (!backlighter) return -ENODEV; diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index c0605244edda..ebb8be9bf8aa 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c @@ -136,7 +136,7 @@ static inline void debug_calc_bogomips(void) /* Switch CPU speed under 750FX CPU control */ -static int __pmac cpu_750fx_cpu_speed(int low_speed) +static int cpu_750fx_cpu_speed(int low_speed) { u32 hid2; @@ -172,7 +172,7 @@ static int __pmac cpu_750fx_cpu_speed(int low_speed) return 0; } -static unsigned int __pmac cpu_750fx_get_cpu_speed(void) +static unsigned int cpu_750fx_get_cpu_speed(void) { if (mfspr(SPRN_HID1) & HID1_PS) return low_freq; @@ -181,7 +181,7 @@ static unsigned int __pmac cpu_750fx_get_cpu_speed(void) } /* Switch CPU speed using DFS */ -static int __pmac dfs_set_cpu_speed(int low_speed) +static int dfs_set_cpu_speed(int low_speed) { if (low_speed == 0) { /* ramping up, set voltage first */ @@ -205,7 +205,7 @@ static int __pmac dfs_set_cpu_speed(int low_speed) return 0; } -static unsigned int __pmac dfs_get_cpu_speed(void) +static unsigned int dfs_get_cpu_speed(void) { if (mfspr(SPRN_HID1) & HID1_DFS) return low_freq; @@ -216,7 +216,7 @@ static unsigned int __pmac dfs_get_cpu_speed(void) /* Switch CPU speed using slewing GPIOs */ -static int __pmac gpios_set_cpu_speed(int low_speed) +static int gpios_set_cpu_speed(int low_speed) { int gpio, timeout = 0; @@ -258,7 +258,7 @@ static int __pmac gpios_set_cpu_speed(int low_speed) /* Switch CPU speed under PMU control */ -static int __pmac pmu_set_cpu_speed(int low_speed) +static int pmu_set_cpu_speed(int low_speed) { struct adb_request req; unsigned long save_l2cr; @@ -354,7 +354,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed) return 0; } -static int __pmac do_set_cpu_speed(int speed_mode, int notify) +static int do_set_cpu_speed(int speed_mode, int notify) { struct cpufreq_freqs freqs; unsigned long l3cr; @@ -391,17 +391,17 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) return 0; } -static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu) +static unsigned int pmac_cpufreq_get_speed(unsigned int cpu) { return cur_freq; } -static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy) +static int pmac_cpufreq_verify(struct cpufreq_policy *policy) { return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); } -static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy, +static int pmac_cpufreq_target( struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { @@ -414,13 +414,13 @@ static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy, return do_set_cpu_speed(newstate, 1); } -unsigned int __pmac pmac_get_one_cpufreq(int i) +unsigned int pmac_get_one_cpufreq(int i) { /* Supports only one CPU for now */ return (i == 0) ? cur_freq : 0; } -static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) +static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) { if (policy->cpu != 0) return -ENODEV; @@ -433,7 +433,7 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); } -static u32 __pmac read_gpio(struct device_node *np) +static u32 read_gpio(struct device_node *np) { u32 *reg = (u32 *)get_property(np, "reg", NULL); u32 offset; @@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np) return offset; } -static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) +static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) { /* Ok, this could be made a bit smarter, but let's be robust for now. We * always force a speed change to high speed before sleep, to make sure @@ -468,7 +468,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message return 0; } -static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy) +static int pmac_cpufreq_resume(struct cpufreq_policy *policy) { /* If we resume, first check if we have a get() function */ if (get_speed_proc) @@ -501,7 +501,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = { }; -static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) +static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) { struct device_node *volt_gpio_np = of_find_node_by_name(NULL, "voltage-gpio"); @@ -593,7 +593,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) return 0; } -static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) +static int pmac_cpufreq_init_7447A(struct device_node *cpunode) { struct device_node *volt_gpio_np; @@ -620,7 +620,7 @@ static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) return 0; } -static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode) +static int pmac_cpufreq_init_750FX(struct device_node *cpunode) { struct device_node *volt_gpio_np; u32 pvr, *value; diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c index 867336ad5d36..e8cd0a8b6a76 100644 --- a/arch/ppc/platforms/pmac_feature.c +++ b/arch/ppc/platforms/pmac_feature.c @@ -63,7 +63,7 @@ extern struct device_node *k2_skiplist[2]; * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -static DEFINE_SPINLOCK(feature_lock __pmacdata); +static DEFINE_SPINLOCK(feature_lock); #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); @@ -72,9 +72,9 @@ static DEFINE_SPINLOCK(feature_lock __pmacdata); /* * Instance of some macio stuffs */ -struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata; +struct macio_chip macio_chips[MAX_MACIO_CHIPS]; -struct macio_chip* __pmac macio_find(struct device_node* child, int type) +struct macio_chip* macio_find(struct device_node* child, int type) { while(child) { int i; @@ -89,7 +89,7 @@ struct macio_chip* __pmac macio_find(struct device_node* child, int type) } EXPORT_SYMBOL_GPL(macio_find); -static const char* macio_names[] __pmacdata = +static const char* macio_names[] = { "Unknown", "Grand Central", @@ -116,10 +116,10 @@ static const char* macio_names[] __pmacdata = #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) -static struct device_node* uninorth_node __pmacdata; -static u32 __iomem * uninorth_base __pmacdata; -static u32 uninorth_rev __pmacdata; -static int uninorth_u3 __pmacdata; +static struct device_node* uninorth_node; +static u32 __iomem * uninorth_base; +static u32 uninorth_rev; +static int uninorth_u3; static void __iomem *u3_ht; /* @@ -142,13 +142,13 @@ struct pmac_mb_def struct feature_table_entry* features; unsigned long board_flags; }; -static struct pmac_mb_def pmac_mb __pmacdata; +static struct pmac_mb_def pmac_mb; /* * Here are the chip specific feature functions */ -static inline int __pmac +static inline int simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value) { struct macio_chip* macio; @@ -170,7 +170,7 @@ simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int #ifndef CONFIG_POWER4 -static long __pmac +static long ohare_htw_scc_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -263,21 +263,21 @@ ohare_htw_scc_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long ohare_floppy_enable(struct device_node* node, long param, long value) { return simple_feature_tweak(node, macio_ohare, OHARE_FCR, OH_FLOPPY_ENABLE, value); } -static long __pmac +static long ohare_mesh_enable(struct device_node* node, long param, long value) { return simple_feature_tweak(node, macio_ohare, OHARE_FCR, OH_MESH_ENABLE, value); } -static long __pmac +static long ohare_ide_enable(struct device_node* node, long param, long value) { switch(param) { @@ -298,7 +298,7 @@ ohare_ide_enable(struct device_node* node, long param, long value) } } -static long __pmac +static long ohare_ide_reset(struct device_node* node, long param, long value) { switch(param) { @@ -313,7 +313,7 @@ ohare_ide_reset(struct device_node* node, long param, long value) } } -static long __pmac +static long ohare_sleep_state(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -329,7 +329,7 @@ ohare_sleep_state(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long heathrow_modem_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -373,7 +373,7 @@ heathrow_modem_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long heathrow_floppy_enable(struct device_node* node, long param, long value) { return simple_feature_tweak(node, macio_unknown, @@ -382,7 +382,7 @@ heathrow_floppy_enable(struct device_node* node, long param, long value) value); } -static long __pmac +static long heathrow_mesh_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -411,7 +411,7 @@ heathrow_mesh_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long heathrow_ide_enable(struct device_node* node, long param, long value) { switch(param) { @@ -426,7 +426,7 @@ heathrow_ide_enable(struct device_node* node, long param, long value) } } -static long __pmac +static long heathrow_ide_reset(struct device_node* node, long param, long value) { switch(param) { @@ -441,7 +441,7 @@ heathrow_ide_reset(struct device_node* node, long param, long value) } } -static long __pmac +static long heathrow_bmac_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -470,7 +470,7 @@ heathrow_bmac_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long heathrow_sound_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -501,16 +501,16 @@ heathrow_sound_enable(struct device_node* node, long param, long value) return 0; } -static u32 save_fcr[6] __pmacdata; -static u32 save_mbcr __pmacdata; -static u32 save_gpio_levels[2] __pmacdata; -static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata; -static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata; -static u32 save_unin_clock_ctl __pmacdata; -static struct dbdma_regs save_dbdma[13] __pmacdata; -static struct dbdma_regs save_alt_dbdma[13] __pmacdata; +static u32 save_fcr[6]; +static u32 save_mbcr; +static u32 save_gpio_levels[2]; +static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; +static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; +static u32 save_unin_clock_ctl; +static struct dbdma_regs save_dbdma[13]; +static struct dbdma_regs save_alt_dbdma[13]; -static void __pmac +static void dbdma_save(struct macio_chip* macio, struct dbdma_regs* save) { int i; @@ -527,7 +527,7 @@ dbdma_save(struct macio_chip* macio, struct dbdma_regs* save) } } -static void __pmac +static void dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save) { int i; @@ -547,7 +547,7 @@ dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save) } } -static void __pmac +static void heathrow_sleep(struct macio_chip* macio, int secondary) { if (secondary) { @@ -580,7 +580,7 @@ heathrow_sleep(struct macio_chip* macio, int secondary) (void)MACIO_IN32(HEATHROW_FCR); } -static void __pmac +static void heathrow_wakeup(struct macio_chip* macio, int secondary) { if (secondary) { @@ -605,7 +605,7 @@ heathrow_wakeup(struct macio_chip* macio, int secondary) } } -static long __pmac +static long heathrow_sleep_state(struct device_node* node, long param, long value) { if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) @@ -622,7 +622,7 @@ heathrow_sleep_state(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_scc_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -723,7 +723,7 @@ core99_scc_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_modem_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -775,7 +775,7 @@ core99_modem_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long pangea_modem_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -830,7 +830,7 @@ pangea_modem_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_ata100_enable(struct device_node* node, long value) { unsigned long flags; @@ -860,7 +860,7 @@ core99_ata100_enable(struct device_node* node, long value) return 0; } -static long __pmac +static long core99_ide_enable(struct device_node* node, long param, long value) { /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2 @@ -883,7 +883,7 @@ core99_ide_enable(struct device_node* node, long param, long value) } } -static long __pmac +static long core99_ide_reset(struct device_node* node, long param, long value) { switch(param) { @@ -901,7 +901,7 @@ core99_ide_reset(struct device_node* node, long param, long value) } } -static long __pmac +static long core99_gmac_enable(struct device_node* node, long param, long value) { unsigned long flags; @@ -918,7 +918,7 @@ core99_gmac_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_gmac_phy_reset(struct device_node* node, long param, long value) { unsigned long flags; @@ -943,7 +943,7 @@ core99_gmac_phy_reset(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_sound_chip_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -973,7 +973,7 @@ core99_sound_chip_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_airport_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -1060,7 +1060,7 @@ core99_airport_enable(struct device_node* node, long param, long value) } #ifdef CONFIG_SMP -static long __pmac +static long core99_reset_cpu(struct device_node* node, long param, long value) { unsigned int reset_io = 0; @@ -1104,7 +1104,7 @@ core99_reset_cpu(struct device_node* node, long param, long value) } #endif /* CONFIG_SMP */ -static long __pmac +static long core99_usb_enable(struct device_node* node, long param, long value) { struct macio_chip* macio; @@ -1257,7 +1257,7 @@ core99_usb_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_firewire_enable(struct device_node* node, long param, long value) { unsigned long flags; @@ -1284,7 +1284,7 @@ core99_firewire_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long core99_firewire_cable_power(struct device_node* node, long param, long value) { unsigned long flags; @@ -1315,7 +1315,7 @@ core99_firewire_cable_power(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long intrepid_aack_delay_enable(struct device_node* node, long param, long value) { unsigned long flags; @@ -1336,7 +1336,7 @@ intrepid_aack_delay_enable(struct device_node* node, long param, long value) #endif /* CONFIG_POWER4 */ -static long __pmac +static long core99_read_gpio(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -1345,7 +1345,7 @@ core99_read_gpio(struct device_node* node, long param, long value) } -static long __pmac +static long core99_write_gpio(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -1356,7 +1356,7 @@ core99_write_gpio(struct device_node* node, long param, long value) #ifdef CONFIG_POWER4 -static long __pmac +static long g5_gmac_enable(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -1380,7 +1380,7 @@ g5_gmac_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long g5_fw_enable(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -1403,7 +1403,7 @@ g5_fw_enable(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long g5_mpic_enable(struct device_node* node, long param, long value) { unsigned long flags; @@ -1419,7 +1419,7 @@ g5_mpic_enable(struct device_node* node, long param, long value) } #ifdef CONFIG_SMP -static long __pmac +static long g5_reset_cpu(struct device_node* node, long param, long value) { unsigned int reset_io = 0; @@ -1465,7 +1465,7 @@ g5_reset_cpu(struct device_node* node, long param, long value) * This takes the second CPU off the bus on dual CPU machines * running UP */ -void __pmac g5_phy_disable_cpu1(void) +void g5_phy_disable_cpu1(void) { UN_OUT(U3_API_PHY_CONFIG_1, 0); } @@ -1474,7 +1474,7 @@ void __pmac g5_phy_disable_cpu1(void) #ifndef CONFIG_POWER4 -static void __pmac +static void keylargo_shutdown(struct macio_chip* macio, int sleep_mode) { u32 temp; @@ -1528,7 +1528,7 @@ keylargo_shutdown(struct macio_chip* macio, int sleep_mode) (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } -static void __pmac +static void pangea_shutdown(struct macio_chip* macio, int sleep_mode) { u32 temp; @@ -1562,7 +1562,7 @@ pangea_shutdown(struct macio_chip* macio, int sleep_mode) (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } -static void __pmac +static void intrepid_shutdown(struct macio_chip* macio, int sleep_mode) { u32 temp; @@ -1591,7 +1591,7 @@ intrepid_shutdown(struct macio_chip* macio, int sleep_mode) } -void __pmac pmac_tweak_clock_spreading(int enable) +void pmac_tweak_clock_spreading(int enable) { struct macio_chip* macio = &macio_chips[0]; @@ -1698,7 +1698,7 @@ void __pmac pmac_tweak_clock_spreading(int enable) } -static int __pmac +static int core99_sleep(void) { struct macio_chip* macio; @@ -1791,7 +1791,7 @@ core99_sleep(void) return 0; } -static int __pmac +static int core99_wake_up(void) { struct macio_chip* macio; @@ -1854,7 +1854,7 @@ core99_wake_up(void) return 0; } -static long __pmac +static long core99_sleep_state(struct device_node* node, long param, long value) { /* Param == 1 means to enter the "fake sleep" mode that is @@ -1884,7 +1884,7 @@ core99_sleep_state(struct device_node* node, long param, long value) #endif /* CONFIG_POWER4 */ -static long __pmac +static long generic_dev_can_wake(struct device_node* node, long param, long value) { /* Todo: eventually check we are really dealing with on-board @@ -1896,7 +1896,7 @@ generic_dev_can_wake(struct device_node* node, long param, long value) return 0; } -static long __pmac +static long generic_get_mb_info(struct device_node* node, long param, long value) { switch(param) { @@ -1919,7 +1919,7 @@ generic_get_mb_info(struct device_node* node, long param, long value) /* Used on any machine */ -static struct feature_table_entry any_features[] __pmacdata = { +static struct feature_table_entry any_features[] = { { PMAC_FTR_GET_MB_INFO, generic_get_mb_info }, { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake }, { 0, NULL } @@ -1931,7 +1931,7 @@ static struct feature_table_entry any_features[] __pmacdata = { * 2400,3400 and 3500 series powerbooks. Some older desktops seem * to have issues with turning on/off those asic cells */ -static struct feature_table_entry ohare_features[] __pmacdata = { +static struct feature_table_entry ohare_features[] = { { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable }, { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable }, @@ -1945,7 +1945,7 @@ static struct feature_table_entry ohare_features[] __pmacdata = { * Separated as some features couldn't be properly tested * and the serial port control bits appear to confuse it. */ -static struct feature_table_entry heathrow_desktop_features[] __pmacdata = { +static struct feature_table_entry heathrow_desktop_features[] = { { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, @@ -1957,7 +1957,7 @@ static struct feature_table_entry heathrow_desktop_features[] __pmacdata = { /* Heathrow based laptop, that is the Wallstreet and mainstreet * powerbooks. */ -static struct feature_table_entry heathrow_laptop_features[] __pmacdata = { +static struct feature_table_entry heathrow_laptop_features[] = { { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, @@ -1973,7 +1973,7 @@ static struct feature_table_entry heathrow_laptop_features[] __pmacdata = { /* Paddington based machines * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4. */ -static struct feature_table_entry paddington_features[] __pmacdata = { +static struct feature_table_entry paddington_features[] = { { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, @@ -1991,7 +1991,7 @@ static struct feature_table_entry paddington_features[] __pmacdata = { * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo * used on iBook2 & iMac "flow power". */ -static struct feature_table_entry core99_features[] __pmacdata = { +static struct feature_table_entry core99_features[] = { { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, { PMAC_FTR_MODEM_ENABLE, core99_modem_enable }, { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, @@ -2014,7 +2014,7 @@ static struct feature_table_entry core99_features[] __pmacdata = { /* RackMac */ -static struct feature_table_entry rackmac_features[] __pmacdata = { +static struct feature_table_entry rackmac_features[] = { { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, { PMAC_FTR_IDE_RESET, core99_ide_reset }, @@ -2034,7 +2034,7 @@ static struct feature_table_entry rackmac_features[] __pmacdata = { /* Pangea features */ -static struct feature_table_entry pangea_features[] __pmacdata = { +static struct feature_table_entry pangea_features[] = { { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, @@ -2054,7 +2054,7 @@ static struct feature_table_entry pangea_features[] __pmacdata = { /* Intrepid features */ -static struct feature_table_entry intrepid_features[] __pmacdata = { +static struct feature_table_entry intrepid_features[] = { { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, @@ -2077,7 +2077,7 @@ static struct feature_table_entry intrepid_features[] __pmacdata = { /* G5 features */ -static struct feature_table_entry g5_features[] __pmacdata = { +static struct feature_table_entry g5_features[] = { { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable }, { PMAC_FTR_1394_ENABLE, g5_fw_enable }, { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable }, @@ -2091,7 +2091,7 @@ static struct feature_table_entry g5_features[] __pmacdata = { #endif /* CONFIG_POWER4 */ -static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { +static struct pmac_mb_def pmac_mb_defs[] = { #ifndef CONFIG_POWER4 /* * Desktops @@ -2352,7 +2352,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { /* * The toplevel feature_call callback */ -long __pmac +long pmac_do_feature_call(unsigned int selector, ...) { struct device_node* node; @@ -2935,8 +2935,8 @@ void __init pmac_check_ht_link(void) * Early video resume hook */ -static void (*pmac_early_vresume_proc)(void *data) __pmacdata; -static void *pmac_early_vresume_data __pmacdata; +static void (*pmac_early_vresume_proc)(void *data); +static void *pmac_early_vresume_data; void pmac_set_early_video_resume(void (*proc)(void *data), void *data) { @@ -2949,7 +2949,7 @@ void pmac_set_early_video_resume(void (*proc)(void *data), void *data) } EXPORT_SYMBOL(pmac_set_early_video_resume); -void __pmac pmac_call_early_video_resume(void) +void pmac_call_early_video_resume(void) { if (pmac_early_vresume_proc) pmac_early_vresume_proc(pmac_early_vresume_data); @@ -2959,11 +2959,11 @@ void __pmac pmac_call_early_video_resume(void) * AGP related suspend/resume code */ -static struct pci_dev *pmac_agp_bridge __pmacdata; -static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata; -static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata; +static struct pci_dev *pmac_agp_bridge; +static int (*pmac_agp_suspend)(struct pci_dev *bridge); +static int (*pmac_agp_resume)(struct pci_dev *bridge); -void __pmac pmac_register_agp_pm(struct pci_dev *bridge, +void pmac_register_agp_pm(struct pci_dev *bridge, int (*suspend)(struct pci_dev *bridge), int (*resume)(struct pci_dev *bridge)) { @@ -2980,7 +2980,7 @@ void __pmac pmac_register_agp_pm(struct pci_dev *bridge, } EXPORT_SYMBOL(pmac_register_agp_pm); -void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev) +void pmac_suspend_agp_for_card(struct pci_dev *dev) { if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL) return; @@ -2990,7 +2990,7 @@ void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev) } EXPORT_SYMBOL(pmac_suspend_agp_for_card); -void __pmac pmac_resume_agp_for_card(struct pci_dev *dev) +void pmac_resume_agp_for_card(struct pci_dev *dev) { if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL) return; diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c index c9de64205996..8c9b008c7226 100644 --- a/arch/ppc/platforms/pmac_nvram.c +++ b/arch/ppc/platforms/pmac_nvram.c @@ -88,17 +88,17 @@ extern int system_running; static int (*core99_write_bank)(int bank, u8* datas); static int (*core99_erase_bank)(int bank); -static char *nvram_image __pmacdata; +static char *nvram_image; -static unsigned char __pmac core99_nvram_read_byte(int addr) +static unsigned char core99_nvram_read_byte(int addr) { if (nvram_image == NULL) return 0xff; return nvram_image[addr]; } -static void __pmac core99_nvram_write_byte(int addr, unsigned char val) +static void core99_nvram_write_byte(int addr, unsigned char val) { if (nvram_image == NULL) return; @@ -106,18 +106,18 @@ static void __pmac core99_nvram_write_byte(int addr, unsigned char val) } -static unsigned char __openfirmware direct_nvram_read_byte(int addr) +static unsigned char direct_nvram_read_byte(int addr) { return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]); } -static void __openfirmware direct_nvram_write_byte(int addr, unsigned char val) +static void direct_nvram_write_byte(int addr, unsigned char val) { out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val); } -static unsigned char __pmac indirect_nvram_read_byte(int addr) +static unsigned char indirect_nvram_read_byte(int addr) { unsigned char val; unsigned long flags; @@ -130,7 +130,7 @@ static unsigned char __pmac indirect_nvram_read_byte(int addr) return val; } -static void __pmac indirect_nvram_write_byte(int addr, unsigned char val) +static void indirect_nvram_write_byte(int addr, unsigned char val) { unsigned long flags; @@ -143,13 +143,13 @@ static void __pmac indirect_nvram_write_byte(int addr, unsigned char val) #ifdef CONFIG_ADB_PMU -static void __pmac pmu_nvram_complete(struct adb_request *req) +static void pmu_nvram_complete(struct adb_request *req) { if (req->arg) complete((struct completion *)req->arg); } -static unsigned char __pmac pmu_nvram_read_byte(int addr) +static unsigned char pmu_nvram_read_byte(int addr) { struct adb_request req; DECLARE_COMPLETION(req_complete); @@ -165,7 +165,7 @@ static unsigned char __pmac pmu_nvram_read_byte(int addr) return req.reply[0]; } -static void __pmac pmu_nvram_write_byte(int addr, unsigned char val) +static void pmu_nvram_write_byte(int addr, unsigned char val) { struct adb_request req; DECLARE_COMPLETION(req_complete); @@ -183,7 +183,7 @@ static void __pmac pmu_nvram_write_byte(int addr, unsigned char val) #endif /* CONFIG_ADB_PMU */ -static u8 __pmac chrp_checksum(struct chrp_header* hdr) +static u8 chrp_checksum(struct chrp_header* hdr) { u8 *ptr; u16 sum = hdr->signature; @@ -194,7 +194,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr) return sum; } -static u32 __pmac core99_calc_adler(u8 *buffer) +static u32 core99_calc_adler(u8 *buffer) { int cnt; u32 low, high; @@ -216,7 +216,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer) return (high << 16) | low; } -static u32 __pmac core99_check(u8* datas) +static u32 core99_check(u8* datas) { struct core99_header* hdr99 = (struct core99_header*)datas; @@ -235,7 +235,7 @@ static u32 __pmac core99_check(u8* datas) return hdr99->generation; } -static int __pmac sm_erase_bank(int bank) +static int sm_erase_bank(int bank) { int stat, i; unsigned long timeout; @@ -267,7 +267,7 @@ static int __pmac sm_erase_bank(int bank) return 0; } -static int __pmac sm_write_bank(int bank, u8* datas) +static int sm_write_bank(int bank, u8* datas) { int i, stat = 0; unsigned long timeout; @@ -302,7 +302,7 @@ static int __pmac sm_write_bank(int bank, u8* datas) return 0; } -static int __pmac amd_erase_bank(int bank) +static int amd_erase_bank(int bank) { int i, stat = 0; unsigned long timeout; @@ -349,7 +349,7 @@ static int __pmac amd_erase_bank(int bank) return 0; } -static int __pmac amd_write_bank(int bank, u8* datas) +static int amd_write_bank(int bank, u8* datas) { int i, stat = 0; unsigned long timeout; @@ -430,7 +430,7 @@ static void __init lookup_partitions(void) DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]); } -static void __pmac core99_nvram_sync(void) +static void core99_nvram_sync(void) { struct core99_header* hdr99; unsigned long flags; @@ -554,12 +554,12 @@ void __init pmac_nvram_init(void) lookup_partitions(); } -int __pmac pmac_get_partition(int partition) +int pmac_get_partition(int partition) { return nvram_partitions[partition]; } -u8 __pmac pmac_xpram_read(int xpaddr) +u8 pmac_xpram_read(int xpaddr) { int offset = nvram_partitions[pmac_nvram_XPRAM]; @@ -569,7 +569,7 @@ u8 __pmac pmac_xpram_read(int xpaddr) return ppc_md.nvram_read_val(xpaddr + offset); } -void __pmac pmac_xpram_write(int xpaddr, u8 data) +void pmac_xpram_write(int xpaddr, u8 data) { int offset = nvram_partitions[pmac_nvram_XPRAM]; diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c index 719fb49fe2bc..1dc638f72239 100644 --- a/arch/ppc/platforms/pmac_pci.c +++ b/arch/ppc/platforms/pmac_pci.c @@ -141,7 +141,7 @@ fixup_bus_range(struct device_node *bridge) |(((unsigned long)(off)) & 0xFCUL) \ |1UL) -static void volatile __iomem * __pmac +static void volatile __iomem * macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { unsigned int caddr; @@ -162,7 +162,7 @@ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) return hose->cfg_data + offset; } -static int __pmac +static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -190,7 +190,7 @@ macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return PCIBIOS_SUCCESSFUL; } -static int __pmac +static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { @@ -230,7 +230,7 @@ static struct pci_ops macrisc_pci_ops = /* * Verifiy that a specific (bus, dev_fn) exists on chaos */ -static int __pmac +static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) { struct device_node *np; @@ -252,7 +252,7 @@ chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) return PCIBIOS_SUCCESSFUL; } -static int __pmac +static int chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -264,7 +264,7 @@ chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return macrisc_read_config(bus, devfn, offset, len, val); } -static int __pmac +static int chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { @@ -294,7 +294,7 @@ static struct pci_ops chaos_pci_ops = + (((unsigned long)bus) << 16) \ + 0x01000000UL) -static void volatile __iomem * __pmac +static void volatile __iomem * u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) { if (bus == hose->first_busno) { @@ -307,7 +307,7 @@ u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); } -static int __pmac +static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -357,7 +357,7 @@ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return PCIBIOS_SUCCESSFUL; } -static int __pmac +static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { @@ -899,7 +899,7 @@ pmac_pcibios_fixup(void) pcibios_fixup_OF_interrupts(); } -int __pmac +int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) { struct device_node* node; @@ -1096,7 +1096,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); * Disable second function on K2-SATA, it's broken * and disable IO BARs on first one */ -void __pmac pmac_pci_fixup_k2_sata(struct pci_dev* dev) +void pmac_pci_fixup_k2_sata(struct pci_dev* dev) { int i; u16 cmd; diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 2ce058895e03..3349cfb624a0 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -53,7 +53,7 @@ struct pmac_irq_hw { }; /* Default addresses */ -static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = { +static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { (struct pmac_irq_hw *) 0xf3000020, (struct pmac_irq_hw *) 0xf3000010, (struct pmac_irq_hw *) 0xf4000020, @@ -64,22 +64,22 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = { #define OHARE_LEVEL_MASK 0x1ff00000 #define HEATHROW_LEVEL_MASK 0x1ff00000 -static int max_irqs __pmacdata; -static int max_real_irqs __pmacdata; -static u32 level_mask[4] __pmacdata; +static int max_irqs; +static int max_real_irqs; +static u32 level_mask[4]; -static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata); +static DEFINE_SPINLOCK(pmac_pic_lock); #define GATWICK_IRQ_POOL_SIZE 10 -static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata; +static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; /* * Mark an irq as "lost". This is only used on the pmac * since it can lose interrupts (see pmac_set_irq_mask). * -- Cort */ -void __pmac +void __set_lost(unsigned long irq_nr, int nokick) { if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { @@ -89,7 +89,7 @@ __set_lost(unsigned long irq_nr, int nokick) } } -static void __pmac +static void pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); @@ -114,7 +114,7 @@ pmac_mask_and_ack_irq(unsigned int irq_nr) spin_unlock_irqrestore(&pmac_pic_lock, flags); } -static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) +static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; @@ -147,7 +147,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) /* When an irq gets requested for the first client, if it's an * edge interrupt, we clear any previous one on the controller */ -static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr) +static unsigned int pmac_startup_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; @@ -160,20 +160,20 @@ static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr) return 0; } -static void __pmac pmac_mask_irq(unsigned int irq_nr) +static void pmac_mask_irq(unsigned int irq_nr) { clear_bit(irq_nr, ppc_cached_irq_mask); pmac_set_irq_mask(irq_nr, 0); mb(); } -static void __pmac pmac_unmask_irq(unsigned int irq_nr) +static void pmac_unmask_irq(unsigned int irq_nr) { set_bit(irq_nr, ppc_cached_irq_mask); pmac_set_irq_mask(irq_nr, 0); } -static void __pmac pmac_end_irq(unsigned int irq_nr) +static void pmac_end_irq(unsigned int irq_nr) { if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && irq_desc[irq_nr].action) { diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index b392b9a15987..12cbc85555d9 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -123,7 +123,7 @@ extern struct smp_ops_t psurge_smp_ops; extern struct smp_ops_t core99_smp_ops; #endif /* CONFIG_SMP */ -static int __pmac +static int pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; @@ -227,7 +227,7 @@ pmac_show_cpuinfo(struct seq_file *m) return 0; } -static int __openfirmware +static int pmac_show_percpuinfo(struct seq_file *m, int i) { #ifdef CONFIG_CPU_FREQ_PMAC @@ -486,7 +486,7 @@ static int pmac_late_init(void) late_initcall(pmac_late_init); /* can't be __init - can be called whenever a disk is first accessed */ -void __pmac +void note_bootable_part(dev_t dev, int part, int goodness) { static int found_boot = 0; @@ -512,7 +512,7 @@ note_bootable_part(dev_t dev, int part, int goodness) } } -static void __pmac +static void pmac_restart(char *cmd) { #ifdef CONFIG_ADB_CUDA @@ -537,7 +537,7 @@ pmac_restart(char *cmd) } } -static void __pmac +static void pmac_power_off(void) { #ifdef CONFIG_ADB_CUDA @@ -562,7 +562,7 @@ pmac_power_off(void) } } -static void __pmac +static void pmac_halt(void) { pmac_power_off(); diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c index 794a23994b82..e613f0e0d9eb 100644 --- a/arch/ppc/platforms/pmac_smp.c +++ b/arch/ppc/platforms/pmac_smp.c @@ -186,7 +186,7 @@ static inline void psurge_clr_ipi(int cpu) */ static unsigned long psurge_smp_message[NR_CPUS]; -void __pmac psurge_smp_message_recv(struct pt_regs *regs) +void psurge_smp_message_recv(struct pt_regs *regs) { int cpu = smp_processor_id(); int msg; @@ -203,13 +203,13 @@ void __pmac psurge_smp_message_recv(struct pt_regs *regs) smp_message_recv(msg, regs); } -irqreturn_t __pmac psurge_primary_intr(int irq, void *d, struct pt_regs *regs) +irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) { psurge_smp_message_recv(regs); return IRQ_HANDLED; } -static void __pmac smp_psurge_message_pass(int target, int msg, unsigned long data, +static void smp_psurge_message_pass(int target, int msg, unsigned long data, int wait) { int i; @@ -629,7 +629,7 @@ void smp_core99_give_timebase(void) /* PowerSurge-style Macs */ -struct smp_ops_t psurge_smp_ops __pmacdata = { +struct smp_ops_t psurge_smp_ops = { .message_pass = smp_psurge_message_pass, .probe = smp_psurge_probe, .kick_cpu = smp_psurge_kick_cpu, @@ -639,7 +639,7 @@ struct smp_ops_t psurge_smp_ops __pmacdata = { }; /* Core99 Macs (dual G4s) */ -struct smp_ops_t core99_smp_ops __pmacdata = { +struct smp_ops_t core99_smp_ops = { .message_pass = smp_openpic_message_pass, .probe = smp_core99_probe, .kick_cpu = smp_core99_kick_cpu, diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c index 778ce4fec368..ff6adff36cb8 100644 --- a/arch/ppc/platforms/pmac_time.c +++ b/arch/ppc/platforms/pmac_time.c @@ -77,7 +77,7 @@ pmac_time_init(void) #endif } -unsigned long __pmac +unsigned long pmac_get_rtc_time(void) { #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) @@ -118,7 +118,7 @@ pmac_get_rtc_time(void) return 0; } -int __pmac +int pmac_set_rtc_time(unsigned long nowtime) { #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) @@ -210,7 +210,7 @@ via_calibrate_decr(void) /* * Reset the time after a sleep. */ -static int __pmac +static int time_sleep_notify(struct pmu_sleep_notifier *self, int when) { static unsigned long time_diff; @@ -235,7 +235,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) return PBOOK_SLEEP_OK; } -static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = { +static struct pmu_sleep_notifier time_sleep_notifier = { time_sleep_notify, SLEEP_LEVEL_MISC, }; #endif /* CONFIG_PM */ diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c index 4760cb64251d..e50b9996848c 100644 --- a/arch/ppc/platforms/prep_pci.c +++ b/arch/ppc/platforms/prep_pci.c @@ -43,7 +43,7 @@ static unsigned long *ProcInfo; /* Tables for known hardware */ /* Motorola PowerStackII - Utah */ -static char Utah_pci_IRQ_map[23] __prepdata = +static char Utah_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -72,7 +72,7 @@ static char Utah_pci_IRQ_map[23] __prepdata = 0, /* Slot 22 - unused */ }; -static char Utah_pci_IRQ_routes[] __prepdata = +static char Utah_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 9, /* Line 1 */ @@ -84,7 +84,7 @@ static char Utah_pci_IRQ_routes[] __prepdata = /* Motorola PowerStackII - Omaha */ /* no integrated SCSI or ethernet */ -static char Omaha_pci_IRQ_map[23] __prepdata = +static char Omaha_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -111,7 +111,7 @@ static char Omaha_pci_IRQ_map[23] __prepdata = 0, }; -static char Omaha_pci_IRQ_routes[] __prepdata = +static char Omaha_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 9, /* Line 1 */ @@ -121,7 +121,7 @@ static char Omaha_pci_IRQ_routes[] __prepdata = }; /* Motorola PowerStack */ -static char Blackhawk_pci_IRQ_map[19] __prepdata = +static char Blackhawk_pci_IRQ_map[19] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -144,7 +144,7 @@ static char Blackhawk_pci_IRQ_map[19] __prepdata = 3, /* Slot P5 */ }; -static char Blackhawk_pci_IRQ_routes[] __prepdata = +static char Blackhawk_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 9, /* Line 1 */ @@ -154,7 +154,7 @@ static char Blackhawk_pci_IRQ_routes[] __prepdata = }; /* Motorola Mesquite */ -static char Mesquite_pci_IRQ_map[23] __prepdata = +static char Mesquite_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -182,7 +182,7 @@ static char Mesquite_pci_IRQ_map[23] __prepdata = }; /* Motorola Sitka */ -static char Sitka_pci_IRQ_map[21] __prepdata = +static char Sitka_pci_IRQ_map[21] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -208,7 +208,7 @@ static char Sitka_pci_IRQ_map[21] __prepdata = }; /* Motorola MTX */ -static char MTX_pci_IRQ_map[23] __prepdata = +static char MTX_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -237,7 +237,7 @@ static char MTX_pci_IRQ_map[23] __prepdata = /* Motorola MTX Plus */ /* Secondary bus interrupt routing is not supported yet */ -static char MTXplus_pci_IRQ_map[23] __prepdata = +static char MTXplus_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -264,13 +264,13 @@ static char MTXplus_pci_IRQ_map[23] __prepdata = 0, /* Slot 22 - unused */ }; -static char Raven_pci_IRQ_routes[] __prepdata = +static char Raven_pci_IRQ_routes[] = { 0, /* This is a dummy structure */ }; /* Motorola MVME16xx */ -static char Genesis_pci_IRQ_map[16] __prepdata = +static char Genesis_pci_IRQ_map[16] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -290,7 +290,7 @@ static char Genesis_pci_IRQ_map[16] __prepdata = 0, /* Slot 15 - unused */ }; -static char Genesis_pci_IRQ_routes[] __prepdata = +static char Genesis_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 10, /* Line 1 */ @@ -299,7 +299,7 @@ static char Genesis_pci_IRQ_routes[] __prepdata = 15 /* Line 4 */ }; -static char Genesis2_pci_IRQ_map[23] __prepdata = +static char Genesis2_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -327,7 +327,7 @@ static char Genesis2_pci_IRQ_map[23] __prepdata = }; /* Motorola Series-E */ -static char Comet_pci_IRQ_map[23] __prepdata = +static char Comet_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -354,7 +354,7 @@ static char Comet_pci_IRQ_map[23] __prepdata = 0, }; -static char Comet_pci_IRQ_routes[] __prepdata = +static char Comet_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 10, /* Line 1 */ @@ -364,7 +364,7 @@ static char Comet_pci_IRQ_routes[] __prepdata = }; /* Motorola Series-EX */ -static char Comet2_pci_IRQ_map[23] __prepdata = +static char Comet2_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -391,7 +391,7 @@ static char Comet2_pci_IRQ_map[23] __prepdata = 0, }; -static char Comet2_pci_IRQ_routes[] __prepdata = +static char Comet2_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 10, /* Line 1 */ @@ -405,7 +405,7 @@ static char Comet2_pci_IRQ_routes[] __prepdata = * This is actually based on the Carolina motherboard * -- Cort */ -static char ibm8xx_pci_IRQ_map[23] __prepdata = { +static char ibm8xx_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ 0, /* Slot 2 - unused */ @@ -431,7 +431,7 @@ static char ibm8xx_pci_IRQ_map[23] __prepdata = { 2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */ }; -static char ibm8xx_pci_IRQ_routes[] __prepdata = { +static char ibm8xx_pci_IRQ_routes[] = { 0, /* Line 0 - unused */ 15, /* Line 1 */ 15, /* Line 2 */ @@ -443,7 +443,7 @@ static char ibm8xx_pci_IRQ_routes[] __prepdata = { * a 6015 ibm board * -- Cort */ -static char ibm6015_pci_IRQ_map[23] __prepdata = { +static char ibm6015_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ 0, /* Slot 2 - unused */ @@ -469,7 +469,7 @@ static char ibm6015_pci_IRQ_map[23] __prepdata = { 2, /* Slot 22 - */ }; -static char ibm6015_pci_IRQ_routes[] __prepdata = { +static char ibm6015_pci_IRQ_routes[] = { 0, /* Line 0 - unused */ 13, /* Line 1 */ 15, /* Line 2 */ @@ -479,7 +479,7 @@ static char ibm6015_pci_IRQ_routes[] __prepdata = { /* IBM Nobis and Thinkpad 850 */ -static char Nobis_pci_IRQ_map[23] __prepdata ={ +static char Nobis_pci_IRQ_map[23] ={ 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ 0, /* Slot 2 - unused */ @@ -498,7 +498,7 @@ static char Nobis_pci_IRQ_map[23] __prepdata ={ 0, /* Slot 15 - unused */ }; -static char Nobis_pci_IRQ_routes[] __prepdata = { +static char Nobis_pci_IRQ_routes[] = { 0, /* Line 0 - Unused */ 13, /* Line 1 */ 13, /* Line 2 */ @@ -510,7 +510,7 @@ static char Nobis_pci_IRQ_routes[] __prepdata = { * IBM RS/6000 43p/140 -- paulus * XXX we should get all this from the residual data */ -static char ibm43p_pci_IRQ_map[23] __prepdata = { +static char ibm43p_pci_IRQ_map[23] = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ 0, /* Slot 2 - unused */ @@ -536,7 +536,7 @@ static char ibm43p_pci_IRQ_map[23] __prepdata = { 1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */ }; -static char ibm43p_pci_IRQ_routes[] __prepdata = { +static char ibm43p_pci_IRQ_routes[] = { 0, /* Line 0 - unused */ 15, /* Line 1 */ 15, /* Line 2 */ @@ -559,7 +559,7 @@ struct powerplus_irq_list * are routed to OpenPIC inputs 5-8. These values are offset by * 16 in the table to reflect the Linux kernel interrupt value. */ -struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata = +struct powerplus_irq_list Powerplus_pci_IRQ_list = { {25, 26, 27, 28}, {21, 22, 23, 24} @@ -572,7 +572,7 @@ struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata = * are routed to OpenPIC inputs 12-15. These values are offset by * 16 in the table to reflect the Linux kernel interrupt value. */ -struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata = +struct powerplus_irq_list Mesquite_pci_IRQ_list = { {24, 25, 26, 27}, {28, 29, 30, 31} @@ -582,7 +582,7 @@ struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata = * This table represents the standard PCI swizzle defined in the * PCI bus specification. */ -static unsigned char prep_pci_intpins[4][4] __prepdata = +static unsigned char prep_pci_intpins[4][4] = { { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */ { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */ @@ -622,7 +622,7 @@ static unsigned char prep_pci_intpins[4][4] __prepdata = #define MIN_DEVNR 11 #define MAX_DEVNR 22 -static int __prep +static int prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -652,7 +652,7 @@ prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return PCIBIOS_SUCCESSFUL; } -static int __prep +static int prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { @@ -804,7 +804,7 @@ struct mot_info { void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */ struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */ unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */ -} mot_info[] __prepdata = { +} mot_info[] = { {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00}, diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index bc926be95472..fccafbcd4b58 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -173,7 +173,7 @@ prep_carolina_enable_l2(void) } /* cpuinfo code common to all IBM PReP */ -static void __prep +static void prep_ibm_cpuinfo(struct seq_file *m) { unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); @@ -209,14 +209,14 @@ prep_ibm_cpuinfo(struct seq_file *m) } } -static int __prep +static int prep_gen_cpuinfo(struct seq_file *m) { prep_ibm_cpuinfo(m); return 0; } -static int __prep +static int prep_sandalfoot_cpuinfo(struct seq_file *m) { unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); @@ -243,7 +243,7 @@ prep_sandalfoot_cpuinfo(struct seq_file *m) return 0; } -static int __prep +static int prep_thinkpad_cpuinfo(struct seq_file *m) { unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); @@ -314,7 +314,7 @@ prep_thinkpad_cpuinfo(struct seq_file *m) return 0; } -static int __prep +static int prep_carolina_cpuinfo(struct seq_file *m) { unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); @@ -350,7 +350,7 @@ prep_carolina_cpuinfo(struct seq_file *m) return 0; } -static int __prep +static int prep_tiger1_cpuinfo(struct seq_file *m) { unsigned int l2_reg = inb(PREP_IBM_L2INFO); @@ -393,7 +393,7 @@ prep_tiger1_cpuinfo(struct seq_file *m) /* Used by all Motorola PReP */ -static int __prep +static int prep_mot_cpuinfo(struct seq_file *m) { unsigned int cachew = *((unsigned char *)CACHECRBA); @@ -454,7 +454,7 @@ prep_mot_cpuinfo(struct seq_file *m) return 0; } -static void __prep +static void prep_restart(char *cmd) { #define PREP_SP92 0x92 /* Special Port 92 */ @@ -473,7 +473,7 @@ prep_restart(char *cmd) #undef PREP_SP92 } -static void __prep +static void prep_halt(void) { local_irq_disable(); /* no interrupts */ @@ -488,7 +488,7 @@ prep_halt(void) /* Carrera is the power manager in the Thinkpads. Unfortunately not much is * known about it, so we can't power down. */ -static void __prep +static void prep_carrera_poweroff(void) { prep_halt(); @@ -501,7 +501,7 @@ prep_carrera_poweroff(void) * somewhat in the IBM Carolina Technical Specification. * -Hollis */ -static void __prep +static void utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value) { /* @@ -539,7 +539,7 @@ utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value) udelay(100); /* important: let controller recover */ } -static void __prep +static void prep_sig750_poweroff(void) { /* tweak the power manager found in most IBM PRePs (except Thinkpads) */ @@ -554,7 +554,7 @@ prep_sig750_poweroff(void) /* not reached */ } -static int __prep +static int prep_show_percpuinfo(struct seq_file *m, int i) { /* PREP's without residual data will give incorrect values here */ @@ -700,12 +700,12 @@ prep_set_bat(void) /* * IBM 3-digit status LED */ -static unsigned int ibm_statusled_base __prepdata; +static unsigned int ibm_statusled_base; -static void __prep +static void ibm_statusled_progress(char *s, unsigned short hex); -static int __prep +static int ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2, void * dummy3) { @@ -713,13 +713,13 @@ ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2, return NOTIFY_DONE; } -static struct notifier_block ibm_statusled_block __prepdata = { +static struct notifier_block ibm_statusled_block = { ibm_statusled_panic, NULL, INT_MAX /* try to do it first */ }; -static void __prep +static void ibm_statusled_progress(char *s, unsigned short hex) { static int notifier_installed; @@ -945,7 +945,7 @@ prep_calibrate_decr(void) todc_calibrate_decr(); } -static unsigned int __prep +static unsigned int prep_irq_canonicalize(u_int irq) { if (irq == 2) @@ -996,7 +996,7 @@ prep_init_IRQ(void) /* * IDE stuff. */ -static int __prep +static int prep_ide_default_irq(unsigned long base) { switch (base) { @@ -1010,7 +1010,7 @@ prep_ide_default_irq(unsigned long base) } } -static unsigned long __prep +static unsigned long prep_ide_default_io_base(int index) { switch (index) { @@ -1055,7 +1055,7 @@ smp_prep_setup_cpu(int cpu_nr) do_openpic_setup_cpu(); } -static struct smp_ops_t prep_smp_ops __prepdata = { +static struct smp_ops_t prep_smp_ops = { smp_openpic_message_pass, smp_prep_probe, smp_prep_kick_cpu, diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c index 0f84ca603612..c9911601cfdf 100644 --- a/arch/ppc/platforms/residual.c +++ b/arch/ppc/platforms/residual.c @@ -47,7 +47,7 @@ #include -unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,}; +unsigned char __res[sizeof(RESIDUAL)] = {0,}; RESIDUAL *res = (RESIDUAL *)&__res; char * PnP_BASE_TYPES[] __initdata = { diff --git a/arch/ppc/syslib/btext.c b/arch/ppc/syslib/btext.c index 7734f6836174..12fa83e6774a 100644 --- a/arch/ppc/syslib/btext.c +++ b/arch/ppc/syslib/btext.c @@ -53,8 +53,8 @@ extern char *klimit; * chrp only uses it during early boot. */ #ifdef CONFIG_XMON -#define BTEXT __pmac -#define BTDATA __pmacdata +#define BTEXT +#define BTDATA #else #define BTEXT __init #define BTDATA __initdata @@ -187,7 +187,7 @@ btext_setup_display(int width, int height, int depth, int pitch, * changes. */ -void __openfirmware +void map_boot_text(void) { unsigned long base, offset, size; diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c index 8599850ca772..2c6364d9641f 100644 --- a/arch/ppc/syslib/prep_nvram.c +++ b/arch/ppc/syslib/prep_nvram.c @@ -22,14 +22,14 @@ static char nvramData[MAX_PREP_NVRAM]; static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0]; -unsigned char __prep prep_nvram_read_val(int addr) +unsigned char prep_nvram_read_val(int addr) { outb(addr, PREP_NVRAM_AS0); outb(addr>>8, PREP_NVRAM_AS1); return inb(PREP_NVRAM_DATA); } -void __prep prep_nvram_write_val(int addr, +void prep_nvram_write_val(int addr, unsigned char val) { outb(addr, PREP_NVRAM_AS0); @@ -81,8 +81,7 @@ void __init init_prep_nvram(void) } } -__prep -char __prep *prep_nvram_get_var(const char *name) +char *prep_nvram_get_var(const char *name) { char *cp; int namelen; @@ -101,8 +100,7 @@ char __prep *prep_nvram_get_var(const char *name) return NULL; } -__prep -char __prep *prep_nvram_first_var(void) +char *prep_nvram_first_var(void) { if (nvram->Header.GELength == 0) { return NULL; @@ -112,8 +110,7 @@ char __prep *prep_nvram_first_var(void) } } -__prep -char __prep *prep_nvram_next_var(char *name) +char *prep_nvram_next_var(char *name) { char *cp; diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c index 2c64ed627475..278da6ee62ea 100644 --- a/arch/ppc/syslib/prom.c +++ b/arch/ppc/syslib/prom.c @@ -89,7 +89,7 @@ extern char cmd_line[512]; /* XXX */ extern boot_infos_t *boot_infos; unsigned long dev_tree_size; -void __openfirmware +void phys_call_rtas(int service, int nargs, int nret, ...) { va_list list; @@ -862,7 +862,7 @@ find_type_devices(const char *type) /* * Returns all nodes linked together */ -struct device_node * __openfirmware +struct device_node * find_all_nodes(void) { struct device_node *head, **prevp, *np; @@ -1165,7 +1165,7 @@ get_property(struct device_node *np, const char *name, int *lenp) /* * Add a property to a node */ -void __openfirmware +void prom_add_property(struct device_node* np, struct property* prop) { struct property **next = &np->properties; @@ -1177,7 +1177,7 @@ prom_add_property(struct device_node* np, struct property* prop) } /* I quickly hacked that one, check against spec ! */ -static inline unsigned long __openfirmware +static inline unsigned long bus_space_to_resource_flags(unsigned int bus_space) { u8 space = (bus_space >> 24) & 0xf; @@ -1194,7 +1194,7 @@ bus_space_to_resource_flags(unsigned int bus_space) } } -static struct resource* __openfirmware +static struct resource* find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) { unsigned long mask; @@ -1224,7 +1224,7 @@ find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) * or other nodes attached to the root node. Ultimately, put some * link to resources in the OF node. */ -struct resource* __openfirmware +struct resource* request_OF_resource(struct device_node* node, int index, const char* name_postfix) { struct pci_dev* pcidev; @@ -1280,7 +1280,7 @@ request_OF_resource(struct device_node* node, int index, const char* name_postfi return NULL; } -int __openfirmware +int release_OF_resource(struct device_node* node, int index) { struct pci_dev* pcidev; @@ -1346,7 +1346,7 @@ release_OF_resource(struct device_node* node, int index) } #if 0 -void __openfirmware +void print_properties(struct device_node *np) { struct property *pp; @@ -1400,7 +1400,7 @@ print_properties(struct device_node *np) static DEFINE_SPINLOCK(rtas_lock); /* this can be called after setup -- Cort */ -int __openfirmware +int call_rtas(const char *service, int nargs, int nret, unsigned long *outputs, ...) { From aacaf9bd9646f6f611a08fca976411b6e5ddefe2 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Sat, 17 Sep 2005 10:36:54 -0500 Subject: [PATCH 0067/1940] [PATCH] powerpc: Remove sections use from ppc64 and drivers Here is a new patch that removes all notion of the pmac, prep, chrp and openfirmware initialization sections, and then unifies the sections.h files without those __pmac, etc, sections identifiers cluttering things up. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/pmac_feature.c | 60 +++++++------- arch/ppc64/kernel/pmac_nvram.c | 30 +++---- arch/ppc64/kernel/pmac_pci.c | 12 +-- arch/ppc64/kernel/pmac_setup.c | 10 +-- arch/ppc64/kernel/pmac_smp.c | 2 +- arch/ppc64/kernel/pmac_time.c | 4 +- drivers/ide/ppc/pmac.c | 80 +++++++++---------- drivers/macintosh/ans-lcd.c | 10 +-- drivers/macintosh/mediabay.c | 56 +++++++------- drivers/macintosh/via-cuda.c | 1 - drivers/macintosh/via-pmu.c | 129 +++++++++++++++---------------- drivers/macintosh/via-pmu68k.c | 15 ++-- 12 files changed, 203 insertions(+), 206 deletions(-) diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c index eb4e6c3f694d..26075f11db77 100644 --- a/arch/ppc64/kernel/pmac_feature.c +++ b/arch/ppc64/kernel/pmac_feature.c @@ -53,7 +53,7 @@ * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -static DEFINE_SPINLOCK(feature_lock __pmacdata); +static DEFINE_SPINLOCK(feature_lock); #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); @@ -62,9 +62,9 @@ static DEFINE_SPINLOCK(feature_lock __pmacdata); /* * Instance of some macio stuffs */ -struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata; +struct macio_chip macio_chips[MAX_MACIO_CHIPS] ; -struct macio_chip* __pmac macio_find(struct device_node* child, int type) +struct macio_chip* macio_find(struct device_node* child, int type) { while(child) { int i; @@ -79,7 +79,7 @@ struct macio_chip* __pmac macio_find(struct device_node* child, int type) } EXPORT_SYMBOL_GPL(macio_find); -static const char* macio_names[] __pmacdata = +static const char* macio_names[] = { "Unknown", "Grand Central", @@ -106,9 +106,9 @@ static const char* macio_names[] __pmacdata = #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) -static struct device_node* uninorth_node __pmacdata; -static u32* uninorth_base __pmacdata; -static u32 uninorth_rev __pmacdata; +static struct device_node* uninorth_node; +static u32* uninorth_base; +static u32 uninorth_rev; static void *u3_ht; extern struct device_node *k2_skiplist[2]; @@ -133,14 +133,14 @@ struct pmac_mb_def struct feature_table_entry* features; unsigned long board_flags; }; -static struct pmac_mb_def pmac_mb __pmacdata; +static struct pmac_mb_def pmac_mb; /* * Here are the chip specific feature functions */ -static long __pmac g5_read_gpio(struct device_node* node, long param, long value) +static long g5_read_gpio(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -148,7 +148,7 @@ static long __pmac g5_read_gpio(struct device_node* node, long param, long value } -static long __pmac g5_write_gpio(struct device_node* node, long param, long value) +static long g5_write_gpio(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; @@ -156,7 +156,7 @@ static long __pmac g5_write_gpio(struct device_node* node, long param, long valu return 0; } -static long __pmac g5_gmac_enable(struct device_node* node, long param, long value) +static long g5_gmac_enable(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; @@ -181,7 +181,7 @@ static long __pmac g5_gmac_enable(struct device_node* node, long param, long val return 0; } -static long __pmac g5_fw_enable(struct device_node* node, long param, long value) +static long g5_fw_enable(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; @@ -206,7 +206,7 @@ static long __pmac g5_fw_enable(struct device_node* node, long param, long value return 0; } -static long __pmac g5_mpic_enable(struct device_node* node, long param, long value) +static long g5_mpic_enable(struct device_node* node, long param, long value) { unsigned long flags; @@ -220,7 +220,7 @@ static long __pmac g5_mpic_enable(struct device_node* node, long param, long val return 0; } -static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long value) +static long g5_eth_phy_reset(struct device_node* node, long param, long value) { struct macio_chip* macio = &macio_chips[0]; struct device_node *phy; @@ -250,7 +250,7 @@ static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long v return 0; } -static long __pmac g5_i2s_enable(struct device_node *node, long param, long value) +static long g5_i2s_enable(struct device_node *node, long param, long value) { /* Very crude implementation for now */ struct macio_chip* macio = &macio_chips[0]; @@ -275,7 +275,7 @@ static long __pmac g5_i2s_enable(struct device_node *node, long param, long valu #ifdef CONFIG_SMP -static long __pmac g5_reset_cpu(struct device_node* node, long param, long value) +static long g5_reset_cpu(struct device_node* node, long param, long value) { unsigned int reset_io = 0; unsigned long flags; @@ -320,12 +320,12 @@ static long __pmac g5_reset_cpu(struct device_node* node, long param, long value * This takes the second CPU off the bus on dual CPU machines * running UP */ -void __pmac g5_phy_disable_cpu1(void) +void g5_phy_disable_cpu1(void) { UN_OUT(U3_API_PHY_CONFIG_1, 0); } -static long __pmac generic_get_mb_info(struct device_node* node, long param, long value) +static long generic_get_mb_info(struct device_node* node, long param, long value) { switch(param) { case PMAC_MB_INFO_MODEL: @@ -347,14 +347,14 @@ static long __pmac generic_get_mb_info(struct device_node* node, long param, lon /* Used on any machine */ -static struct feature_table_entry any_features[] __pmacdata = { +static struct feature_table_entry any_features[] = { { PMAC_FTR_GET_MB_INFO, generic_get_mb_info }, { 0, NULL } }; /* G5 features */ -static struct feature_table_entry g5_features[] __pmacdata = { +static struct feature_table_entry g5_features[] = { { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable }, { PMAC_FTR_1394_ENABLE, g5_fw_enable }, { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable }, @@ -368,7 +368,7 @@ static struct feature_table_entry g5_features[] __pmacdata = { { 0, NULL } }; -static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { +static struct pmac_mb_def pmac_mb_defs[] = { { "PowerMac7,2", "PowerMac G5", PMAC_TYPE_POWERMAC_G5, g5_features, 0, @@ -394,7 +394,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { /* * The toplevel feature_call callback */ -long __pmac pmac_do_feature_call(unsigned int selector, ...) +long pmac_do_feature_call(unsigned int selector, ...) { struct device_node* node; long param, value; @@ -706,8 +706,8 @@ void __init pmac_check_ht_link(void) * Early video resume hook */ -static void (*pmac_early_vresume_proc)(void *data) __pmacdata; -static void *pmac_early_vresume_data __pmacdata; +static void (*pmac_early_vresume_proc)(void *data); +static void *pmac_early_vresume_data; void pmac_set_early_video_resume(void (*proc)(void *data), void *data) { @@ -725,11 +725,11 @@ EXPORT_SYMBOL(pmac_set_early_video_resume); * AGP related suspend/resume code */ -static struct pci_dev *pmac_agp_bridge __pmacdata; -static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata; -static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata; +static struct pci_dev *pmac_agp_bridge; +static int (*pmac_agp_suspend)(struct pci_dev *bridge); +static int (*pmac_agp_resume)(struct pci_dev *bridge); -void __pmac pmac_register_agp_pm(struct pci_dev *bridge, +void pmac_register_agp_pm(struct pci_dev *bridge, int (*suspend)(struct pci_dev *bridge), int (*resume)(struct pci_dev *bridge)) { @@ -746,7 +746,7 @@ void __pmac pmac_register_agp_pm(struct pci_dev *bridge, } EXPORT_SYMBOL(pmac_register_agp_pm); -void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev) +void pmac_suspend_agp_for_card(struct pci_dev *dev) { if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL) return; @@ -756,7 +756,7 @@ void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev) } EXPORT_SYMBOL(pmac_suspend_agp_for_card); -void __pmac pmac_resume_agp_for_card(struct pci_dev *dev) +void pmac_resume_agp_for_card(struct pci_dev *dev) { if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL) return; diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c index e32a902236e3..11586d535f81 100644 --- a/arch/ppc64/kernel/pmac_nvram.c +++ b/arch/ppc64/kernel/pmac_nvram.c @@ -82,10 +82,10 @@ extern int system_running; static int (*core99_write_bank)(int bank, u8* datas); static int (*core99_erase_bank)(int bank); -static char *nvram_image __pmacdata; +static char *nvram_image; -static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index) +static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index) { int i; @@ -103,7 +103,7 @@ static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index) return count; } -static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index) +static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index) { int i; @@ -121,14 +121,14 @@ static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index) return count; } -static ssize_t __pmac core99_nvram_size(void) +static ssize_t core99_nvram_size(void) { if (nvram_image == NULL) return -ENODEV; return NVRAM_SIZE; } -static u8 __pmac chrp_checksum(struct chrp_header* hdr) +static u8 chrp_checksum(struct chrp_header* hdr) { u8 *ptr; u16 sum = hdr->signature; @@ -139,7 +139,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr) return sum; } -static u32 __pmac core99_calc_adler(u8 *buffer) +static u32 core99_calc_adler(u8 *buffer) { int cnt; u32 low, high; @@ -161,7 +161,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer) return (high << 16) | low; } -static u32 __pmac core99_check(u8* datas) +static u32 core99_check(u8* datas) { struct core99_header* hdr99 = (struct core99_header*)datas; @@ -180,7 +180,7 @@ static u32 __pmac core99_check(u8* datas) return hdr99->generation; } -static int __pmac sm_erase_bank(int bank) +static int sm_erase_bank(int bank) { int stat, i; unsigned long timeout; @@ -212,7 +212,7 @@ static int __pmac sm_erase_bank(int bank) return 0; } -static int __pmac sm_write_bank(int bank, u8* datas) +static int sm_write_bank(int bank, u8* datas) { int i, stat = 0; unsigned long timeout; @@ -247,7 +247,7 @@ static int __pmac sm_write_bank(int bank, u8* datas) return 0; } -static int __pmac amd_erase_bank(int bank) +static int amd_erase_bank(int bank) { int i, stat = 0; unsigned long timeout; @@ -294,7 +294,7 @@ static int __pmac amd_erase_bank(int bank) return 0; } -static int __pmac amd_write_bank(int bank, u8* datas) +static int amd_write_bank(int bank, u8* datas) { int i, stat = 0; unsigned long timeout; @@ -341,7 +341,7 @@ static int __pmac amd_write_bank(int bank, u8* datas) } -static int __pmac core99_nvram_sync(void) +static int core99_nvram_sync(void) { struct core99_header* hdr99; unsigned long flags; @@ -431,7 +431,7 @@ int __init pmac_nvram_init(void) return 0; } -int __pmac pmac_get_partition(int partition) +int pmac_get_partition(int partition) { struct nvram_partition *part; const char *name; @@ -459,7 +459,7 @@ int __pmac pmac_get_partition(int partition) return part->index; } -u8 __pmac pmac_xpram_read(int xpaddr) +u8 pmac_xpram_read(int xpaddr) { int offset = pmac_get_partition(pmac_nvram_XPRAM); loff_t index; @@ -476,7 +476,7 @@ u8 __pmac pmac_xpram_read(int xpaddr) return buf; } -void __pmac pmac_xpram_write(int xpaddr, u8 data) +void pmac_xpram_write(int xpaddr, u8 data) { int offset = pmac_get_partition(pmac_nvram_XPRAM); loff_t index; diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index dc40a0cad0b4..1f61aa4746ec 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -121,7 +121,7 @@ static void __init fixup_bus_range(struct device_node *bridge) |(((unsigned long)(off)) & 0xFCUL) \ |1UL) -static unsigned long __pmac macrisc_cfg_access(struct pci_controller* hose, +static unsigned long macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { unsigned int caddr; @@ -142,7 +142,7 @@ static unsigned long __pmac macrisc_cfg_access(struct pci_controller* hose, return ((unsigned long)hose->cfg_data) + offset; } -static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn, +static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; @@ -173,7 +173,7 @@ static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } -static int __pmac macrisc_write_config(struct pci_bus *bus, unsigned int devfn, +static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; @@ -265,7 +265,7 @@ static int u3_ht_skip_device(struct pci_controller *hose, + (((unsigned long)bus) << 16) \ + 0x01000000UL) -static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose, +static unsigned long u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) { if (bus == hose->first_busno) { @@ -277,7 +277,7 @@ static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose, return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); } -static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, +static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; @@ -327,7 +327,7 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } -static int __pmac u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, +static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 325426c7bed0..1f5118078f7d 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -98,7 +98,7 @@ EXPORT_SYMBOL(smu_cmdbuf_abs); extern void udbg_init_scc(struct device_node *np); -static void __pmac pmac_show_cpuinfo(struct seq_file *m) +static void pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; char *pp; @@ -210,7 +210,7 @@ static int pmac_late_init(void) late_initcall(pmac_late_init); /* can't be __init - can be called whenever a disk is first accessed */ -void __pmac note_bootable_part(dev_t dev, int part, int goodness) +void note_bootable_part(dev_t dev, int part, int goodness) { extern dev_t boot_dev; char *p; @@ -231,7 +231,7 @@ void __pmac note_bootable_part(dev_t dev, int part, int goodness) } } -static void __pmac pmac_restart(char *cmd) +static void pmac_restart(char *cmd) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU @@ -250,7 +250,7 @@ static void __pmac pmac_restart(char *cmd) } } -static void __pmac pmac_power_off(void) +static void pmac_power_off(void) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU @@ -268,7 +268,7 @@ static void __pmac pmac_power_off(void) } } -static void __pmac pmac_halt(void) +static void pmac_halt(void) { pmac_power_off(); } diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c index a23de37227bf..9fd23ea55bc9 100644 --- a/arch/ppc64/kernel/pmac_smp.c +++ b/arch/ppc64/kernel/pmac_smp.c @@ -310,7 +310,7 @@ static void __init smp_core99_setup_cpu(int cpu_nr) } } -struct smp_ops_t core99_smp_ops __pmacdata = { +struct smp_ops_t core99_smp_ops = { .message_pass = smp_mpic_message_pass, .probe = smp_core99_probe, .kick_cpu = smp_core99_kick_cpu, diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index 3059edb09cc8..6c8c99295e7a 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c @@ -51,7 +51,7 @@ extern struct timezone sys_tz; extern void to_tm(int tim, struct rtc_time * tm); -void __pmac pmac_get_rtc_time(struct rtc_time *tm) +void pmac_get_rtc_time(struct rtc_time *tm) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU @@ -92,7 +92,7 @@ void __pmac pmac_get_rtc_time(struct rtc_time *tm) } } -int __pmac pmac_set_rtc_time(struct rtc_time *tm) +int pmac_set_rtc_time(struct rtc_time *tm) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 87d1f8a1f41e..d8c3d8ebad30 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -81,7 +81,7 @@ typedef struct pmac_ide_hwif { } pmac_ide_hwif_t; -static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata; +static pmac_ide_hwif_t pmac_ide[MAX_HWIFS]; static int pmac_ide_count; enum { @@ -242,7 +242,7 @@ struct mdma_timings_t { int cycleTime; }; -struct mdma_timings_t mdma_timings_33[] __pmacdata = +struct mdma_timings_t mdma_timings_33[] = { { 240, 240, 480 }, { 180, 180, 360 }, @@ -255,7 +255,7 @@ struct mdma_timings_t mdma_timings_33[] __pmacdata = { 0, 0, 0 } }; -struct mdma_timings_t mdma_timings_33k[] __pmacdata = +struct mdma_timings_t mdma_timings_33k[] = { { 240, 240, 480 }, { 180, 180, 360 }, @@ -268,7 +268,7 @@ struct mdma_timings_t mdma_timings_33k[] __pmacdata = { 0, 0, 0 } }; -struct mdma_timings_t mdma_timings_66[] __pmacdata = +struct mdma_timings_t mdma_timings_66[] = { { 240, 240, 480 }, { 180, 180, 360 }, @@ -286,7 +286,7 @@ struct { int addrSetup; /* ??? */ int rdy2pause; int wrDataSetup; -} kl66_udma_timings[] __pmacdata = +} kl66_udma_timings[] = { { 0, 180, 120 }, /* Mode 0 */ { 0, 150, 90 }, /* 1 */ @@ -301,7 +301,7 @@ struct kauai_timing { u32 timing_reg; }; -static struct kauai_timing kauai_pio_timings[] __pmacdata = +static struct kauai_timing kauai_pio_timings[] = { { 930 , 0x08000fff }, { 600 , 0x08000a92 }, @@ -316,7 +316,7 @@ static struct kauai_timing kauai_pio_timings[] __pmacdata = { 120 , 0x04000148 } }; -static struct kauai_timing kauai_mdma_timings[] __pmacdata = +static struct kauai_timing kauai_mdma_timings[] = { { 1260 , 0x00fff000 }, { 480 , 0x00618000 }, @@ -330,7 +330,7 @@ static struct kauai_timing kauai_mdma_timings[] __pmacdata = { 0 , 0 }, }; -static struct kauai_timing kauai_udma_timings[] __pmacdata = +static struct kauai_timing kauai_udma_timings[] = { { 120 , 0x000070c0 }, { 90 , 0x00005d80 }, @@ -341,7 +341,7 @@ static struct kauai_timing kauai_udma_timings[] __pmacdata = { 0 , 0 }, }; -static struct kauai_timing shasta_pio_timings[] __pmacdata = +static struct kauai_timing shasta_pio_timings[] = { { 930 , 0x08000fff }, { 600 , 0x0A000c97 }, @@ -356,7 +356,7 @@ static struct kauai_timing shasta_pio_timings[] __pmacdata = { 120 , 0x0400010a } }; -static struct kauai_timing shasta_mdma_timings[] __pmacdata = +static struct kauai_timing shasta_mdma_timings[] = { { 1260 , 0x00fff000 }, { 480 , 0x00820800 }, @@ -370,7 +370,7 @@ static struct kauai_timing shasta_mdma_timings[] __pmacdata = { 0 , 0 }, }; -static struct kauai_timing shasta_udma133_timings[] __pmacdata = +static struct kauai_timing shasta_udma133_timings[] = { { 120 , 0x00035901, }, { 90 , 0x000348b1, }, @@ -522,7 +522,7 @@ pmu_hd_blink_init(void) * N.B. this can't be an initfunc, because the media-bay task can * call ide_[un]register at any time. */ -void __pmac +void pmac_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq) @@ -559,7 +559,7 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw, * timing register when selecting that unit. This version is for * ASICs with a single timing register */ -static void __pmac +static void pmac_ide_selectproc(ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -579,7 +579,7 @@ pmac_ide_selectproc(ide_drive_t *drive) * timing register when selecting that unit. This version is for * ASICs with a dual timing register (Kauai) */ -static void __pmac +static void pmac_ide_kauai_selectproc(ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -600,7 +600,7 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive) /* * Force an update of controller timing values for a given drive */ -static void __pmac +static void pmac_ide_do_update_timings(ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -633,7 +633,7 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port) * to sort that out sooner or later and see if I can finally get the * common version to work properly in all cases */ -static int __pmac +static int pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) { ide_hwif_t *hwif = HWIF(drive); @@ -710,7 +710,7 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) /* * Old tuning functions (called on hdparm -p), sets up drive PIO timings */ -static void __pmac +static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio) { ide_pio_data_t d; @@ -801,7 +801,7 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio) /* * Calculate KeyLargo ATA/66 UDMA timings */ -static int __pmac +static int set_timings_udma_ata4(u32 *timings, u8 speed) { unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks; @@ -829,7 +829,7 @@ set_timings_udma_ata4(u32 *timings, u8 speed) /* * Calculate Kauai ATA/100 UDMA timings */ -static int __pmac +static int set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed) { struct ide_timing *t = ide_timing_find_mode(speed); @@ -849,7 +849,7 @@ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed) /* * Calculate Shasta ATA/133 UDMA timings */ -static int __pmac +static int set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) { struct ide_timing *t = ide_timing_find_mode(speed); @@ -869,7 +869,7 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) /* * Calculate MDMA timings for all cells */ -static int __pmac +static int set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, u8 speed, int drive_cycle_time) { @@ -1014,7 +1014,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, * our dedicated function is more precise as it uses the drive provided * cycle time value. We should probably fix this one to deal with that too... */ -static int __pmac +static int pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) { int unit = (drive->select.b.unit & 0x01); @@ -1092,7 +1092,7 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) * Blast some well known "safe" values to the timing registers at init or * wakeup from sleep time, before we do real calculation */ -static void __pmac +static void sanitize_timings(pmac_ide_hwif_t *pmif) { unsigned int value, value2 = 0; @@ -1123,13 +1123,13 @@ sanitize_timings(pmac_ide_hwif_t *pmif) pmif->timings[2] = pmif->timings[3] = value2; } -unsigned long __pmac +unsigned long pmac_ide_get_base(int index) { return pmac_ide[index].regbase; } -int __pmac +int pmac_ide_check_base(unsigned long base) { int ix; @@ -1140,7 +1140,7 @@ pmac_ide_check_base(unsigned long base) return -1; } -int __pmac +int pmac_ide_get_irq(unsigned long base) { int ix; @@ -1151,7 +1151,7 @@ pmac_ide_get_irq(unsigned long base) return 0; } -static int ide_majors[] __pmacdata = { 3, 22, 33, 34, 56, 57 }; +static int ide_majors[] = { 3, 22, 33, 34, 56, 57 }; dev_t __init pmac_find_ide_boot(char *bootdevice, int n) @@ -1701,7 +1701,7 @@ pmac_ide_probe(void) * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */ -static int __pmac +static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) { struct dbdma_cmd *table; @@ -1785,7 +1785,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) } /* Teardown mappings after DMA has completed. */ -static void __pmac +static void pmac_ide_destroy_dmatable (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; @@ -1802,7 +1802,7 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive) /* * Pick up best MDMA timing for the drive and apply it */ -static int __pmac +static int pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) { ide_hwif_t *hwif = HWIF(drive); @@ -1859,7 +1859,7 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) /* * Pick up best UDMA timing for the drive and apply it */ -static int __pmac +static int pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) { ide_hwif_t *hwif = HWIF(drive); @@ -1915,7 +1915,7 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) * Check what is the best DMA timing setting for the drive and * call appropriate functions to apply it. */ -static int __pmac +static int pmac_ide_dma_check(ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -1967,7 +1967,7 @@ pmac_ide_dma_check(ide_drive_t *drive) * Prepare a DMA transfer. We build the DMA table, adjust the timings for * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion */ -static int __pmac +static int pmac_ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); @@ -1997,7 +1997,7 @@ pmac_ide_dma_setup(ide_drive_t *drive) return 0; } -static void __pmac +static void pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) { /* issue cmd to drive */ @@ -2008,7 +2008,7 @@ pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) * Kick the DMA controller into life after the DMA command has been issued * to the drive. */ -static void __pmac +static void pmac_ide_dma_start(ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -2024,7 +2024,7 @@ pmac_ide_dma_start(ide_drive_t *drive) /* * After a DMA transfer, make sure the controller is stopped */ -static int __pmac +static int pmac_ide_dma_end (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -2052,7 +2052,7 @@ pmac_ide_dma_end (ide_drive_t *drive) * that's not implemented yet), on the other hand, we don't have shared interrupts * so it's not really a problem */ -static int __pmac +static int pmac_ide_dma_test_irq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -2108,19 +2108,19 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) return 1; } -static int __pmac +static int pmac_ide_dma_host_off (ide_drive_t *drive) { return 0; } -static int __pmac +static int pmac_ide_dma_host_on (ide_drive_t *drive) { return 0; } -static int __pmac +static int pmac_ide_dma_lostirq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index 5e0811dc6536..2b8a6e821d44 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -27,7 +27,7 @@ static volatile unsigned char __iomem *anslcd_ptr; #undef DEBUG -static void __pmac +static void anslcd_write_byte_ctrl ( unsigned char c ) { #ifdef DEBUG @@ -43,14 +43,14 @@ anslcd_write_byte_ctrl ( unsigned char c ) } } -static void __pmac +static void anslcd_write_byte_data ( unsigned char c ) { out_8(anslcd_ptr + ANSLCD_DATA_IX, c); udelay(anslcd_short_delay); } -static ssize_t __pmac +static ssize_t anslcd_write( struct file * file, const char __user * buf, size_t count, loff_t *ppos ) { @@ -73,7 +73,7 @@ anslcd_write( struct file * file, const char __user * buf, return p - buf; } -static int __pmac +static int anslcd_ioctl( struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg ) { @@ -115,7 +115,7 @@ anslcd_ioctl( struct inode * inode, struct file * file, } } -static int __pmac +static int anslcd_open( struct inode * inode, struct file * file ) { return 0; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index c0712a1ea5af..b856bb67169c 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -167,19 +167,19 @@ enum { * Functions for polling content of media bay */ -static u8 __pmac +static u8 ohare_mb_content(struct media_bay_info *bay) { return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7; } -static u8 __pmac +static u8 heathrow_mb_content(struct media_bay_info *bay) { return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7; } -static u8 __pmac +static u8 keylargo_mb_content(struct media_bay_info *bay) { int new_gpio; @@ -205,7 +205,7 @@ keylargo_mb_content(struct media_bay_info *bay) * into reset state as well */ -static void __pmac +static void ohare_mb_power(struct media_bay_info* bay, int on_off) { if (on_off) { @@ -224,7 +224,7 @@ ohare_mb_power(struct media_bay_info* bay, int on_off) MB_BIC(bay, OHARE_MBCR, 0x00000F00); } -static void __pmac +static void heathrow_mb_power(struct media_bay_info* bay, int on_off) { if (on_off) { @@ -243,7 +243,7 @@ heathrow_mb_power(struct media_bay_info* bay, int on_off) MB_BIC(bay, HEATHROW_MBCR, 0x00000F00); } -static void __pmac +static void keylargo_mb_power(struct media_bay_info* bay, int on_off) { if (on_off) { @@ -267,7 +267,7 @@ keylargo_mb_power(struct media_bay_info* bay, int on_off) * enable the related busses */ -static int __pmac +static int ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id) { switch(device_id) { @@ -287,7 +287,7 @@ ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id) return -ENODEV; } -static int __pmac +static int heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id) { switch(device_id) { @@ -307,7 +307,7 @@ heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id) return -ENODEV; } -static int __pmac +static int keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id) { switch(device_id) { @@ -330,43 +330,43 @@ keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id) * Functions for tweaking resets */ -static void __pmac +static void ohare_mb_un_reset(struct media_bay_info* bay) { MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N); } -static void __pmac keylargo_mb_init(struct media_bay_info *bay) +static void keylargo_mb_init(struct media_bay_info *bay) { MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE); } -static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay) +static void heathrow_mb_un_reset(struct media_bay_info* bay) { MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N); } -static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay) +static void keylargo_mb_un_reset(struct media_bay_info* bay) { MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET); } -static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay) +static void ohare_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N); } -static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay) +static void heathrow_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N); } -static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay) +static void keylargo_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N); } -static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff) +static inline void set_mb_power(struct media_bay_info* bay, int onoff) { /* Power up up and assert the bay reset line */ if (onoff) { @@ -382,7 +382,7 @@ static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff) bay->timer = msecs_to_jiffies(MB_POWER_DELAY); } -static void __pmac poll_media_bay(struct media_bay_info* bay) +static void poll_media_bay(struct media_bay_info* bay) { int id = bay->ops->content(bay); @@ -415,7 +415,7 @@ static void __pmac poll_media_bay(struct media_bay_info* bay) } } -int __pmac check_media_bay(struct device_node *which_bay, int what) +int check_media_bay(struct device_node *which_bay, int what) { #ifdef CONFIG_BLK_DEV_IDE int i; @@ -432,7 +432,7 @@ int __pmac check_media_bay(struct device_node *which_bay, int what) } EXPORT_SYMBOL(check_media_bay); -int __pmac check_media_bay_by_base(unsigned long base, int what) +int check_media_bay_by_base(unsigned long base, int what) { #ifdef CONFIG_BLK_DEV_IDE int i; @@ -449,7 +449,7 @@ int __pmac check_media_bay_by_base(unsigned long base, int what) return -ENODEV; } -int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, +int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, int irq, int index) { #ifdef CONFIG_BLK_DEV_IDE @@ -489,7 +489,7 @@ int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long return -ENODEV; } -static void __pmac media_bay_step(int i) +static void media_bay_step(int i) { struct media_bay_info* bay = &media_bays[i]; @@ -619,7 +619,7 @@ static void __pmac media_bay_step(int i) * with the IDE driver. It needs to be a thread because * ide_register can't be called from interrupt context. */ -static int __pmac media_bay_task(void *x) +static int media_bay_task(void *x) { int i; @@ -704,7 +704,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de } -static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state) +static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state) { struct media_bay_info *bay = macio_get_drvdata(mdev); @@ -719,7 +719,7 @@ static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state) return 0; } -static int __pmac media_bay_resume(struct macio_dev *mdev) +static int media_bay_resume(struct macio_dev *mdev) { struct media_bay_info *bay = macio_get_drvdata(mdev); @@ -760,7 +760,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev) /* Definitions of "ops" structures. */ -static struct mb_ops ohare_mb_ops __pmacdata = { +static struct mb_ops ohare_mb_ops = { .name = "Ohare", .content = ohare_mb_content, .power = ohare_mb_power, @@ -769,7 +769,7 @@ static struct mb_ops ohare_mb_ops __pmacdata = { .un_reset_ide = ohare_mb_un_reset_ide, }; -static struct mb_ops heathrow_mb_ops __pmacdata = { +static struct mb_ops heathrow_mb_ops = { .name = "Heathrow", .content = heathrow_mb_content, .power = heathrow_mb_power, @@ -778,7 +778,7 @@ static struct mb_ops heathrow_mb_ops __pmacdata = { .un_reset_ide = heathrow_mb_un_reset_ide, }; -static struct mb_ops keylargo_mb_ops __pmacdata = { +static struct mb_ops keylargo_mb_ops = { .name = "KeyLargo", .init = keylargo_mb_init, .content = keylargo_mb_content, diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 417deb5de108..d843a6c9c6df 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(cuda_lock); #ifdef CONFIG_MAC #define CUDA_IRQ IRQ_MAC_ADB -#define __openfirmware #define eieio() #else #define CUDA_IRQ vias->intrs[0].line diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 645a2e5c70ab..76719451e384 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -244,7 +244,7 @@ int pmu_wink(struct adb_request *req); * - the number of response bytes which the PMU will return, or * -1 if it will send a length byte. */ -static const s8 pmu_data_len[256][2] __openfirmwaredata = { +static const s8 pmu_data_len[256][2] = { /* 0 1 2 3 4 5 6 7 */ /*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, /*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, @@ -295,7 +295,7 @@ static struct backlight_controller pmu_backlight_controller = { }; #endif /* CONFIG_PMAC_BACKLIGHT */ -int __openfirmware +int find_via_pmu(void) { if (via != 0) @@ -374,7 +374,7 @@ find_via_pmu(void) } #ifdef CONFIG_ADB -static int __openfirmware +static int pmu_probe(void) { return vias == NULL? -ENODEV: 0; @@ -520,7 +520,7 @@ static int __init via_pmu_dev_init(void) device_initcall(via_pmu_dev_init); -static int __openfirmware +static int init_pmu(void) { int timeout; @@ -625,7 +625,7 @@ static void pmu_set_server_mode(int server_mode) /* This new version of the code for 2400/3400/3500 powerbooks * is inspired from the implementation in gkrellm-pmu */ -static void __pmac +static void done_battery_state_ohare(struct adb_request* req) { /* format: @@ -713,7 +713,7 @@ done_battery_state_ohare(struct adb_request* req) clear_bit(0, &async_req_locks); } -static void __pmac +static void done_battery_state_smart(struct adb_request* req) { /* format: @@ -791,7 +791,7 @@ done_battery_state_smart(struct adb_request* req) clear_bit(0, &async_req_locks); } -static void __pmac +static void query_battery_state(void) { if (test_and_set_bit(0, &async_req_locks)) @@ -804,7 +804,7 @@ query_battery_state(void) 2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1); } -static int __pmac +static int proc_get_info(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -819,7 +819,7 @@ proc_get_info(char *page, char **start, off_t off, return p - page; } -static int __pmac +static int proc_get_irqstats(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -846,7 +846,7 @@ proc_get_irqstats(char *page, char **start, off_t off, return p - page; } -static int __pmac +static int proc_get_batt(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -870,7 +870,7 @@ proc_get_batt(char *page, char **start, off_t off, return p - page; } -static int __pmac +static int proc_read_options(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -887,7 +887,7 @@ proc_read_options(char *page, char **start, off_t off, return p - page; } -static int __pmac +static int proc_write_options(struct file *file, const char __user *buffer, unsigned long count, void *data) { @@ -934,7 +934,7 @@ proc_write_options(struct file *file, const char __user *buffer, #ifdef CONFIG_ADB /* Send an ADB command */ -static int __pmac +static int pmu_send_request(struct adb_request *req, int sync) { int i, ret; @@ -1014,7 +1014,7 @@ pmu_send_request(struct adb_request *req, int sync) } /* Enable/disable autopolling */ -static int __pmac +static int pmu_adb_autopoll(int devs) { struct adb_request req; @@ -1037,7 +1037,7 @@ pmu_adb_autopoll(int devs) } /* Reset the ADB bus */ -static int __pmac +static int pmu_adb_reset_bus(void) { struct adb_request req; @@ -1072,7 +1072,7 @@ pmu_adb_reset_bus(void) #endif /* CONFIG_ADB */ /* Construct and send a pmu request */ -int __openfirmware +int pmu_request(struct adb_request *req, void (*done)(struct adb_request *), int nbytes, ...) { @@ -1098,7 +1098,7 @@ pmu_request(struct adb_request *req, void (*done)(struct adb_request *), return pmu_queue_request(req); } -int __pmac +int pmu_queue_request(struct adb_request *req) { unsigned long flags; @@ -1190,7 +1190,7 @@ pmu_done(struct adb_request *req) (*done)(req); } -static void __pmac +static void pmu_start(void) { struct adb_request *req; @@ -1214,7 +1214,7 @@ pmu_start(void) send_byte(req->data[0]); } -void __openfirmware +void pmu_poll(void) { if (!via) @@ -1224,7 +1224,7 @@ pmu_poll(void) via_pmu_interrupt(0, NULL, NULL); } -void __openfirmware +void pmu_poll_adb(void) { if (!via) @@ -1239,7 +1239,7 @@ pmu_poll_adb(void) || req_awaiting_reply)); } -void __openfirmware +void pmu_wait_complete(struct adb_request *req) { if (!via) @@ -1253,7 +1253,7 @@ pmu_wait_complete(struct adb_request *req) * This is done to avoid spurrious shutdowns when we know we'll have * interrupts switched off for a long time */ -void __openfirmware +void pmu_suspend(void) { unsigned long flags; @@ -1293,7 +1293,7 @@ pmu_suspend(void) } while (1); } -void __openfirmware +void pmu_resume(void) { unsigned long flags; @@ -1323,7 +1323,7 @@ pmu_resume(void) } /* Interrupt data could be the result data from an ADB cmd */ -static void __pmac +static void pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) { unsigned char ints, pirq; @@ -1435,7 +1435,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) goto next; } -static struct adb_request* __pmac +static struct adb_request* pmu_sr_intr(struct pt_regs *regs) { struct adb_request *req; @@ -1541,7 +1541,7 @@ pmu_sr_intr(struct pt_regs *regs) return NULL; } -static irqreturn_t __pmac +static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; @@ -1629,7 +1629,7 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) return IRQ_RETVAL(handled); } -void __pmac +void pmu_unlock(void) { unsigned long flags; @@ -1642,7 +1642,7 @@ pmu_unlock(void) } -static irqreturn_t __pmac +static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; @@ -1663,12 +1663,12 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) } #ifdef CONFIG_PMAC_BACKLIGHT -static int backlight_to_bright[] __pmacdata = { +static int backlight_to_bright[] = { 0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e, 0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e }; -static int __openfirmware +static int pmu_set_backlight_enable(int on, int level, void* data) { struct adb_request req; @@ -1688,7 +1688,7 @@ pmu_set_backlight_enable(int on, int level, void* data) return 0; } -static void __openfirmware +static void pmu_bright_complete(struct adb_request *req) { if (req == &bright_req_1) @@ -1697,7 +1697,7 @@ pmu_bright_complete(struct adb_request *req) clear_bit(2, &async_req_locks); } -static int __openfirmware +static int pmu_set_backlight_level(int level, void* data) { if (vias == NULL) @@ -1717,7 +1717,7 @@ pmu_set_backlight_level(int level, void* data) } #endif /* CONFIG_PMAC_BACKLIGHT */ -void __pmac +void pmu_enable_irled(int on) { struct adb_request req; @@ -1732,7 +1732,7 @@ pmu_enable_irled(int on) pmu_wait_complete(&req); } -void __pmac +void pmu_restart(void) { struct adb_request req; @@ -1757,7 +1757,7 @@ pmu_restart(void) ; } -void __pmac +void pmu_shutdown(void) { struct adb_request req; @@ -2076,7 +2076,7 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) } /* Sleep is broadcast last-to-first */ -static int __pmac +static int broadcast_sleep(int when, int fallback) { int ret = PBOOK_SLEEP_OK; @@ -2101,7 +2101,7 @@ broadcast_sleep(int when, int fallback) } /* Wake is broadcast first-to-last */ -static int __pmac +static int broadcast_wake(void) { int ret = PBOOK_SLEEP_OK; @@ -2132,7 +2132,7 @@ static struct pci_save { } *pbook_pci_saves; static int pbook_npci_saves; -static void __pmac +static void pbook_alloc_pci_save(void) { int npci; @@ -2149,7 +2149,7 @@ pbook_alloc_pci_save(void) pbook_npci_saves = npci; } -static void __pmac +static void pbook_free_pci_save(void) { if (pbook_pci_saves == NULL) @@ -2159,7 +2159,7 @@ pbook_free_pci_save(void) pbook_npci_saves = 0; } -static void __pmac +static void pbook_pci_save(void) { struct pci_save *ps = pbook_pci_saves; @@ -2190,7 +2190,7 @@ pbook_pci_save(void) * during boot, it will be in the pci dev list. If it's disabled at this point * (and it will probably be), then you can't access it's config space. */ -static void __pmac +static void pbook_pci_restore(void) { u16 cmd; @@ -2238,7 +2238,7 @@ pbook_pci_restore(void) #ifdef DEBUG_SLEEP /* N.B. This doesn't work on the 3400 */ -void __pmac +void pmu_blink(int n) { struct adb_request req; @@ -2277,9 +2277,9 @@ pmu_blink(int n) * Put the powerbook to sleep. */ -static u32 save_via[8] __pmacdata; +static u32 save_via[8]; -static void __pmac +static void save_via_state(void) { save_via[0] = in_8(&via[ANH]); @@ -2291,7 +2291,7 @@ save_via_state(void) save_via[6] = in_8(&via[T1CL]); save_via[7] = in_8(&via[T1CH]); } -static void __pmac +static void restore_via_state(void) { out_8(&via[ANH], save_via[0]); @@ -2307,7 +2307,7 @@ restore_via_state(void) out_8(&via[IER], IER_SET | SR_INT | CB1_INT); } -static int __pmac +static int pmac_suspend_devices(void) { int ret; @@ -2397,7 +2397,7 @@ pmac_suspend_devices(void) return 0; } -static int __pmac +static int pmac_wakeup_devices(void) { mdelay(100); @@ -2436,7 +2436,7 @@ pmac_wakeup_devices(void) #define GRACKLE_NAP (1<<4) #define GRACKLE_SLEEP (1<<3) -int __pmac +int powerbook_sleep_grackle(void) { unsigned long save_l2cr; @@ -2520,7 +2520,7 @@ powerbook_sleep_grackle(void) return 0; } -static int __pmac +static int powerbook_sleep_Core99(void) { unsigned long save_l2cr; @@ -2620,7 +2620,7 @@ powerbook_sleep_Core99(void) #define PB3400_MEM_CTRL 0xf8000000 #define PB3400_MEM_CTRL_SLEEP 0x70 -static int __pmac +static int powerbook_sleep_3400(void) { int ret, i, x; @@ -2720,9 +2720,9 @@ struct pmu_private { }; static LIST_HEAD(all_pmu_pvt); -static DEFINE_SPINLOCK(all_pvt_lock __pmacdata); +static DEFINE_SPINLOCK(all_pvt_lock); -static void __pmac +static void pmu_pass_intr(unsigned char *data, int len) { struct pmu_private *pp; @@ -2751,7 +2751,7 @@ pmu_pass_intr(unsigned char *data, int len) spin_unlock_irqrestore(&all_pvt_lock, flags); } -static int __pmac +static int pmu_open(struct inode *inode, struct file *file) { struct pmu_private *pp; @@ -2773,7 +2773,7 @@ pmu_open(struct inode *inode, struct file *file) return 0; } -static ssize_t __pmac +static ssize_t pmu_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -2825,14 +2825,14 @@ pmu_read(struct file *file, char __user *buf, return ret; } -static ssize_t __pmac +static ssize_t pmu_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { return 0; } -static unsigned int __pmac +static unsigned int pmu_fpoll(struct file *filp, poll_table *wait) { struct pmu_private *pp = filp->private_data; @@ -2849,7 +2849,7 @@ pmu_fpoll(struct file *filp, poll_table *wait) return mask; } -static int __pmac +static int pmu_release(struct inode *inode, struct file *file) { struct pmu_private *pp = file->private_data; @@ -2874,8 +2874,7 @@ pmu_release(struct inode *inode, struct file *file) return 0; } -/* Note: removed __openfirmware here since it causes link errors */ -static int __pmac +static int pmu_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) { @@ -2957,7 +2956,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, return error; } -static struct file_operations pmu_device_fops __pmacdata = { +static struct file_operations pmu_device_fops = { .read = pmu_read, .write = pmu_write, .poll = pmu_fpoll, @@ -2966,7 +2965,7 @@ static struct file_operations pmu_device_fops __pmacdata = { .release = pmu_release, }; -static struct miscdevice pmu_device __pmacdata = { +static struct miscdevice pmu_device = { PMU_MINOR, "pmu", &pmu_device_fops }; @@ -2982,7 +2981,7 @@ device_initcall(pmu_device_init); #ifdef DEBUG_SLEEP -static inline void __pmac +static inline void polled_handshake(volatile unsigned char __iomem *via) { via[B] &= ~TREQ; eieio(); @@ -2993,7 +2992,7 @@ polled_handshake(volatile unsigned char __iomem *via) ; } -static inline void __pmac +static inline void polled_send_byte(volatile unsigned char __iomem *via, int x) { via[ACR] |= SR_OUT | SR_EXT; eieio(); @@ -3001,7 +3000,7 @@ polled_send_byte(volatile unsigned char __iomem *via, int x) polled_handshake(via); } -static inline int __pmac +static inline int polled_recv_byte(volatile unsigned char __iomem *via) { int x; @@ -3013,7 +3012,7 @@ polled_recv_byte(volatile unsigned char __iomem *via) return x; } -int __pmac +int pmu_polled_request(struct adb_request *req) { unsigned long flags; diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index 820dc52e30bc..6f80d76ac17c 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -835,7 +835,7 @@ static struct pci_save { } *pbook_pci_saves; static int n_pbook_pci_saves; -static inline void __openfirmware +static inline void pbook_pci_save(void) { int npci; @@ -863,7 +863,7 @@ pbook_pci_save(void) } } -static inline void __openfirmware +static inline void pbook_pci_restore(void) { u16 cmd; @@ -902,7 +902,7 @@ pbook_pci_restore(void) #define IRQ_ENABLE ((unsigned int *)0xf3000024) #define MEM_CTRL ((unsigned int *)0xf8000070) -int __openfirmware powerbook_sleep(void) +int powerbook_sleep(void) { int ret, i, x; static int save_backlight; @@ -1001,25 +1001,24 @@ int __openfirmware powerbook_sleep(void) /* * Support for /dev/pmu device */ -static int __openfirmware pmu_open(struct inode *inode, struct file *file) +static int pmu_open(struct inode *inode, struct file *file) { return 0; } -static ssize_t __openfirmware pmu_read(struct file *file, char *buf, +static ssize_t pmu_read(struct file *file, char *buf, size_t count, loff_t *ppos) { return 0; } -static ssize_t __openfirmware pmu_write(struct file *file, const char *buf, +static ssize_t pmu_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { return 0; } -/* Note: removed __openfirmware here since it causes link errors */ -static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp, +static int pmu_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) { int error; From 6c45ab992e4299c869fb26427944a8f8ea177024 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Sat, 17 Sep 2005 10:38:23 -0500 Subject: [PATCH 0068/1940] [PATCH] powerpc: Remove section free() and linker script bits Here is a new patch that removes all notion of the pmac, prep, chrp and openfirmware initialization sections, and then unifies the sections.h files without those __pmac, etc, sections identifiers cluttering things up. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/vmlinux.lds.S | 26 -------------------------- arch/ppc/mm/init.c | 12 ------------ 2 files changed, 38 deletions(-) diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 17d2db7e537d..09c6525cfa61 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -149,32 +149,6 @@ SECTIONS . = ALIGN(4096); _sextratext = .; - __pmac_begin = .; - .pmac.text : { *(.pmac.text) } - .pmac.data : { *(.pmac.data) } - . = ALIGN(4096); - __pmac_end = .; - - . = ALIGN(4096); - __prep_begin = .; - .prep.text : { *(.prep.text) } - .prep.data : { *(.prep.data) } - . = ALIGN(4096); - __prep_end = .; - - . = ALIGN(4096); - __chrp_begin = .; - .chrp.text : { *(.chrp.text) } - .chrp.data : { *(.chrp.data) } - . = ALIGN(4096); - __chrp_end = .; - - . = ALIGN(4096); - __openfirmware_begin = .; - .openfirmware.text : { *(.openfirmware.text) } - .openfirmware.data : { *(.openfirmware.data) } - . = ALIGN(4096); - __openfirmware_end = .; _eextratext = .; __bss_start = .; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index f421a4b337f6..5e9ef23b4671 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -74,10 +74,6 @@ unsigned long agp_special_page; extern char _end[]; extern char etext[], _stext[]; extern char __init_begin, __init_end; -extern char __prep_begin, __prep_end; -extern char __chrp_begin, __chrp_end; -extern char __pmac_begin, __pmac_end; -extern char __openfirmware_begin, __openfirmware_end; #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; @@ -167,14 +163,6 @@ void free_initmem(void) printk ("Freeing unused kernel memory:"); FREESEC(init); - if (_machine != _MACH_Pmac) - FREESEC(pmac); - if (_machine != _MACH_chrp) - FREESEC(chrp); - if (_machine != _MACH_prep) - FREESEC(prep); - if (!have_of) - FREESEC(openfirmware); printk("\n"); ppc_md.progress = NULL; #undef FREESEC From fbcd54b1e67ffa27f2b2ce087ee300138828d730 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Sat, 17 Sep 2005 10:39:46 -0500 Subject: [PATCH 0069/1940] [PATCH] powerpc: Merge simplified sections.h into asm-powerpc Here is a new patch that removes all notion of the pmac, prep, chrp and openfirmware initialization sections, and then unifies the sections.h files without those __pmac, etc, sections identifiers cluttering things up. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/sections.h | 21 ++++-------- include/asm-ppc/sections.h | 33 ------------------- 2 files changed, 6 insertions(+), 48 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/sections.h (51%) delete mode 100644 include/asm-ppc/sections.h diff --git a/include/asm-ppc64/sections.h b/include/asm-powerpc/sections.h similarity index 51% rename from include/asm-ppc64/sections.h rename to include/asm-powerpc/sections.h index 308ca6f5ced2..47be2ac2a925 100644 --- a/include/asm-ppc64/sections.h +++ b/include/asm-powerpc/sections.h @@ -1,22 +1,11 @@ -#ifndef _PPC64_SECTIONS_H -#define _PPC64_SECTIONS_H - -extern char _end[]; +#ifndef _ASM_POWERPC_SECTIONS_H +#define _ASM_POWERPC_SECTIONS_H #include -#define __pmac -#define __pmacdata - -#define __prep -#define __prepdata - -#define __chrp -#define __chrpdata - -#define __openfirmware -#define __openfirmwaredata +#ifdef __powerpc64__ +extern char _end[]; static inline int in_kernel_text(unsigned long addr) { @@ -27,3 +16,5 @@ static inline int in_kernel_text(unsigned long addr) } #endif + +#endif /* _ASM_POWERPC_SECTIONS_H */ diff --git a/include/asm-ppc/sections.h b/include/asm-ppc/sections.h deleted file mode 100644 index ba8f43ac9bf3..000000000000 --- a/include/asm-ppc/sections.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _PPC_SECTIONS_H -#define _PPC_SECTIONS_H - -#include - -#define __pmac __attribute__ ((__section__ (".pmac.text"))) -#define __pmacdata __attribute__ ((__section__ (".pmac.data"))) -#define __pmacfunc(__argpmac) \ - __argpmac __pmac; \ - __argpmac - -#define __prep __attribute__ ((__section__ (".prep.text"))) -#define __prepdata __attribute__ ((__section__ (".prep.data"))) -#define __prepfunc(__argprep) \ - __argprep __prep; \ - __argprep - -#define __chrp __attribute__ ((__section__ (".chrp.text"))) -#define __chrpdata __attribute__ ((__section__ (".chrp.data"))) -#define __chrpfunc(__argchrp) \ - __argchrp __chrp; \ - __argchrp - -/* this is actually just common chrp/pmac code, not OF code -- Cort */ -#define __openfirmware __attribute__ ((__section__ (".openfirmware.text"))) -#define __openfirmwaredata __attribute__ ((__section__ (".openfirmware.data"))) -#define __openfirmwarefunc(__argopenfirmware) \ - __argopenfirmware __openfirmware; \ - __argopenfirmware - -#endif /* _PPC_SECTIONS_H */ -#endif /* __KERNEL__ */ From df0d3cecc4bd03ea911d7c3302510984388c8a76 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sun, 18 Sep 2005 13:02:03 -0500 Subject: [PATCH 0070/1940] [PATCH] ppc32: Allow user to individual select CHRP/PMAC/PREP config Made the CHRP/PMAC/PREP config options selectable by the user. This allows us to build kernels specifically for one of the platforms thus reducing code size. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 776941c75672..96b574c0e44a 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -747,12 +747,13 @@ config CPM2 on it (826x, 827x, 8560). config PPC_CHRP + bool " Common Hardware Reference Platform (CHRP) based machines" bool depends on PPC_MULTIPLATFORM default y config PPC_PMAC - bool + bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM default y @@ -762,6 +763,7 @@ config PPC_PMAC64 default y config PPC_PREP + bool " PowerPC Reference Platform (PREP) based machines" bool depends on PPC_MULTIPLATFORM default y From 3e87d80391c84eefceb4bda94a6363661dba4f71 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 18 Sep 2005 20:49:21 -0700 Subject: [PATCH 0071/1940] [CIFS] Add support for legacy servers part seven. Fix open for write, begin implementation of Win9x style set file size via open then write of zero bytes. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifssmb.c | 10 ++++++---- fs/cifs/inode.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b8830118f09a..575b2281518d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -766,7 +766,7 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, if(create_options & CREATE_OPTION_SPECIAL) pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); else - pSMB->FileAttributes = cpu_to_le16(ATTR_NORMAL); + pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */ /* if ((omode & S_IWUGO) == 0) pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ @@ -777,6 +777,8 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, /* BB FIXME BB */ /* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */ /* BB FIXME END BB */ + + pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); pSMB->OpenFunction = convert_disposition(openDisposition); count += name_len; pSMB->hdr.smb_buf_length += count; @@ -3689,7 +3691,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; - } else { /* BB improve the check for buffer overruns BB */ + } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(fileName, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, fileName, name_len); @@ -3697,7 +3699,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, params = 6 + name_len; data_count = sizeof (struct file_end_of_file_info); pSMB->MaxParameterCount = cpu_to_le16(2); - pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ + pSMB->MaxDataCount = cpu_to_le16(4100); pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; pSMB->Flags = 0; @@ -4079,7 +4081,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; - } else { /* BB improve the check for buffer overruns BB */ + } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(fileName, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, fileName, name_len); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0fbe02ebc033..6e82e1ae03b4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1030,6 +1030,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) /* now that we found one valid file handle no sense continuing to loop trying others, so break here */ + /* if(rc == -EINVAL) { + int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, + nfid, 0, + attrs->ia_size, + &bytes_written, + NULL, NULL, long_op); + } */ break; } } @@ -1048,6 +1056,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); + /* if(rc == -EINVAL) + old_style_set_eof_via_write(xid, pTcon, + full_path, + attrs->ia_size, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR);*/ } /* Server is ok setting allocation size implicitly - no need From be379124c0a5abfbe57dab2823fe8a71ce797aee Mon Sep 17 00:00:00 2001 From: Khalid Aziz Date: Mon, 19 Sep 2005 15:42:36 -0700 Subject: [PATCH 0072/1940] [IA64] include EFI memory information in /proc/iomem User mode kexec tools expect to find information about physical memory in /proc/iomem (as they do on x86) to validate the addresses that the new kernel will use. Signed-off-by: Khalid Aziz Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 87 ++++++++++++++++++++++++++++++++++++++++ arch/ia64/kernel/setup.c | 29 ++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 1291db581721..f72ea6aebcb1 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -923,3 +923,90 @@ efi_memmap_init(unsigned long *s, unsigned long *e) *s = (u64)kern_memmap; *e = (u64)++k; } + +void +efi_initialize_iomem_resources(struct resource *code_resource, + struct resource *data_resource) +{ + struct resource *res; + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; + char *name; + unsigned long flags; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + res = NULL; + + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + + if (md->num_pages == 0) /* should not happen */ + continue; + + flags = IORESOURCE_MEM; + switch (md->type) { + + case EFI_MEMORY_MAPPED_IO: + case EFI_MEMORY_MAPPED_IO_PORT_SPACE: + continue; + + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_CONVENTIONAL_MEMORY: + if (md->attribute & EFI_MEMORY_WP) { + name = "System ROM"; + flags |= IORESOURCE_READONLY; + } else { + name = "System RAM"; + } + break; + + case EFI_ACPI_MEMORY_NVS: + name = "ACPI Non-volatile Storage"; + flags |= IORESOURCE_BUSY; + break; + + case EFI_UNUSABLE_MEMORY: + name = "reserved"; + flags |= IORESOURCE_BUSY | IORESOURCE_DISABLED; + break; + + case EFI_RESERVED_TYPE: + case EFI_RUNTIME_SERVICES_CODE: + case EFI_RUNTIME_SERVICES_DATA: + case EFI_ACPI_RECLAIM_MEMORY: + default: + name = "reserved"; + flags |= IORESOURCE_BUSY; + break; + } + + if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "failed to alocate resource for iomem\n"); + return; + } + + res->name = name; + res->start = md->phys_addr; + res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; + res->flags = flags; + + if (insert_resource(&iomem_resource, res) < 0) + kfree(res); + else { + /* + * We don't know which region contains + * kernel data so we try it repeatedly and + * let the resource manager test it. + */ + insert_resource(res, code_resource); + insert_resource(res, data_resource); + } + } +} diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 1658d687b79c..83b37c410ccd 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -78,6 +78,19 @@ struct screen_info screen_info; unsigned long vga_console_iobase; unsigned long vga_console_membase; +static struct resource data_resource = { + .name = "Kernel data", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource code_resource = { + .name = "Kernel code", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; +extern void efi_initialize_iomem_resources(struct resource *, + struct resource *); +extern char _text[], _edata[], _etext[]; + unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ EXPORT_SYMBOL(ia64_iobase); @@ -171,6 +184,22 @@ sort_regions (struct rsvd_region *rsvd_region, int max) } } +/* + * Request address space for all standard resources + */ +static int __init register_memory(void) +{ + code_resource.start = ia64_tpa(_text); + code_resource.end = ia64_tpa(_etext) - 1; + data_resource.start = ia64_tpa(_etext); + data_resource.end = ia64_tpa(_edata) - 1; + efi_initialize_iomem_resources(&code_resource, &data_resource); + + return 0; +} + +__initcall(register_memory); + /** * reserve_memory - setup reserved memory areas * From 44c451208da397438e7062393aeb3a19ddb76a60 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 16 Sep 2005 11:43:10 -0600 Subject: [PATCH 0073/1940] [IA64] ia64: add ar.k0 usage note Update comment about how ar.k0 is used. Make the initialization the same as in start_secondary() (no functional change, just make it look more similar). Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 1f5c26dbe705..e256b114bf4e 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -244,28 +244,31 @@ find_initrd (void) static void __init io_port_init (void) { - extern unsigned long ia64_iobase; unsigned long phys_iobase; /* - * Set `iobase' to the appropriate address in region 6 (uncached access range). + * Set `iobase' based on the EFI memory map or, failing that, the + * value firmware left in ar.k0. * - * The EFI memory map is the "preferred" location to get the I/O port space base, - * rather the relying on AR.KR0. This should become more clear in future SAL - * specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is - * found in the memory map. + * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute + * the port's virtual address, so ia32_load_state() loads it with a + * user virtual address. But in ia64 mode, glibc uses the + * *physical* address in ar.k0 to mmap the appropriate area from + * /dev/mem, and the inX()/outX() interfaces use MMIO. In both + * cases, user-mode can only use the legacy 0-64K I/O port space. + * + * ar.k0 is not involved in kernel I/O port accesses, which can use + * any of the I/O port spaces and are done via MMIO using the + * virtual mmio_base from the appropriate io_space[]. */ phys_iobase = efi_get_iobase(); - if (phys_iobase) - /* set AR.KR0 since this is all we use it for anyway */ - ia64_set_kr(IA64_KR_IO_BASE, phys_iobase); - else { + if (!phys_iobase) { phys_iobase = ia64_get_kr(IA64_KR_IO_BASE); - printk(KERN_INFO "No I/O port range found in EFI memory map, falling back " - "to AR.KR0\n"); - printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase); + printk(KERN_INFO "No I/O port range found in EFI memory map, " + "falling back to AR.KR0 (0x%lx)\n", phys_iobase); } ia64_iobase = (unsigned long) ioremap(phys_iobase, 0); + ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase)); /* setup legacy IO port space */ io_space[0].mmio_base = ia64_iobase; From 650316f1228c0dc5e45c17765caef30db62468cd Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 16 Sep 2005 11:43:45 -0600 Subject: [PATCH 0074/1940] [IA64] move ACPI IOSAPIC locality domain mapping from pci.c to acpi.c Move acpi_map_iosapics() from pci.c to acpi.c, since it doesn't have anything to do with PCI. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/acpi.c | 13 +++++++++++-- arch/ia64/pci/pci.c | 23 ----------------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 7e926471e4ec..9ad94ddf6687 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -838,7 +838,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ #ifdef CONFIG_ACPI_NUMA -acpi_status __devinit +static acpi_status __devinit acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -890,7 +890,16 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) map_iosapic_to_node(gsi_base, node); return AE_OK; } -#endif /* CONFIG_NUMA */ + +static int __init +acpi_map_iosapics (void) +{ + acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL); + return 0; +} + +fs_initcall(acpi_map_iosapics); +#endif /* CONFIG_ACPI_NUMA */ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 9b5de589b82f..6bf48d7842c6 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -120,29 +120,6 @@ struct pci_ops pci_root_ops = { .write = pci_write, }; -#ifdef CONFIG_NUMA -extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **); -static void acpi_map_iosapics(void) -{ - acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL); -} -#else -static void acpi_map_iosapics(void) -{ - return; -} -#endif /* CONFIG_NUMA */ - -static int __init -pci_acpi_init (void) -{ - acpi_map_iosapics(); - - return 0; -} - -subsys_initcall(pci_acpi_init); - /* Called by ACPI when it finds a new root bus. */ static struct pci_controller * __devinit From b13941f635c3119eb02dc29b5248066f934f76be Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:28 -0500 Subject: [PATCH 0075/1940] [SCSI] iscsi: nodelay fix From: tomof@acm.org I'm not sure about this. I don't think that NODELAY option hurts performance. However, open-iscsi does not use MSG_MORE properly with sendpage, so NODELAY option hurts the open-iscsi performance. I've attached a patch to fix NODELAY and MSG_MORE problems and the write performance results with disktest. I use Opteron boxes connected directly, Chelsio NICs, 1500-byte MTU, 64 KB I/O size, and the iSCSI parameters on open-iscsi web site. With only NODELAY fix, the performance drops, as you said. On the other hand, NODELAY and MSG_MORE fixes improve the performance overall. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 810e5e59658f..584e51024fd6 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1385,7 +1385,7 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, BUG_ON(buf->sent + size > buf->sg.length); if (size > *count) size = *count; - if (buf->sent + size != buf->sg.length) + if (buf->sent + size != buf->sg.length || *count != size) flags |= MSG_MORE; res = iscsi_send(sk, buf, size, flags); From af973481f4a0902ad35726636c290f4794704948 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:32 -0500 Subject: [PATCH 0076/1940] [SCSI] iscsi: preemt fix and cleanup From: zhenyu.z.wang@intel.com Delay the head digest update until xmit time, like data digest update. [To make things cleaner and avoid prempt bug] Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 52 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 584e51024fd6..8751f6015559 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -129,14 +129,11 @@ iscsi_buf_left(struct iscsi_buf *ibuf) } static inline void -iscsi_buf_init_hdr(struct iscsi_conn *conn, struct iscsi_buf *ibuf, - char *vbuf, u8 *crc) +iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf, + u8* crc) { - iscsi_buf_init_virt(ibuf, vbuf, sizeof(struct iscsi_hdr)); - if (conn->hdrdgst_en) { - crypto_digest_digest(conn->tx_tfm, &ibuf->sg, 1, crc); - ibuf->sg.length += sizeof(uint32_t); - } + crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc); + buf->sg.length += sizeof(uint32_t); } static void @@ -427,8 +424,8 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, r2t->sent = 0; - iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr, - (u8 *)dtask->hdrext); + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, + sizeof(struct iscsi_hdr)); r2t->dtask = dtask; @@ -1494,8 +1491,8 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } conn->dataout_pdus_cnt++; - iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr, - (u8 *)dtask->hdrext); + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, + sizeof(struct iscsi_hdr)); r2t->dtask = dtask; @@ -1541,8 +1538,8 @@ iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) hdr->flags = ISCSI_FLAG_CMD_FINAL; } - iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)hdr, - (u8 *)dtask->hdrext); + iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr, + sizeof(struct iscsi_hdr)); list_add(&dtask->item, &ctask->dataqueue); @@ -1662,8 +1659,8 @@ iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, zero_data(ctask->hdr.dlength); } - iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)&ctask->hdr, - (u8 *)ctask->hdrext); + iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, + sizeof(struct iscsi_hdr)); conn->scsicmd_pdus_cnt++; } @@ -1692,6 +1689,11 @@ iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) mtask->xmstate &= ~XMSTATE_IMM_HDR; if (mtask->data_count) mtask->xmstate |= XMSTATE_IMM_DATA; + if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && + conn->stop_stage != STOP_CONN_RECOVER && + conn->hdrdgst_en) + iscsi_hdr_digest(conn, &mtask->headbuf, + (u8*)mtask->hdrext); if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) { mtask->xmstate |= XMSTATE_IMM_HDR; if (mtask->data_count) @@ -1723,6 +1725,8 @@ static inline int handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { ctask->xmstate &= ~XMSTATE_R_HDR; + if (conn->hdrdgst_en) + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { BUG_ON(ctask->xmstate != XMSTATE_IDLE); return 0; /* wait for Data-In */ @@ -1735,6 +1739,8 @@ static inline int handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { ctask->xmstate &= ~XMSTATE_W_HDR; + if (conn->hdrdgst_en) + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { ctask->xmstate |= XMSTATE_W_HDR; return -EAGAIN; @@ -1813,7 +1819,9 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) iscsi_unsolicit_data_init(conn, ctask); BUG_ON(!ctask->dtask); dtask = ctask->dtask; - + if (conn->hdrdgst_en) + iscsi_hdr_digest(conn, &ctask->headbuf, + (u8*)dtask->hdrext); ctask->xmstate &= ~XMSTATE_UNS_INIT; } if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) { @@ -2118,7 +2126,9 @@ iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) sizeof(void*)); solicit_head_again: r2t = ctask->r2t; - + if (conn->hdrdgst_en) + iscsi_hdr_digest(conn, &r2t->headbuf, + (u8*)r2t->dtask->hdrext); if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { ctask->xmstate &= ~XMSTATE_SOL_DATA; ctask->xmstate |= XMSTATE_SOL_HDR; @@ -2889,14 +2899,8 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr)); - if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE || - conn->stop_stage == STOP_CONN_RECOVER) - iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr, + iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr, sizeof(struct iscsi_hdr)); - else - /* this will update header digest */ - iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr, - (u8 *)mtask->hdrext); spin_unlock_bh(&session->lock); From bb052349798f775d4d7ed20ffcf1510287d8abe6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:35 -0500 Subject: [PATCH 0077/1940] [SCSI] iscsi: handle nonlinear skbs From: zhenyu.z.wang@intel.com Fix oops from nonlinear skb usage. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8751f6015559..bb0a5039d334 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1061,7 +1061,6 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, { int rc; struct iscsi_conn *conn = rd_desc->arg.data; - int start = skb_headlen(skb); int processed; char pad[ISCSI_PAD_LEN]; struct scatterlist sg; @@ -1070,7 +1069,7 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, * Save current SKB and its offset in the corresponding * connection context. */ - conn->in.copy = start - offset; + conn->in.copy = skb->len - offset; conn->in.offset = offset; conn->in.skb = skb; conn->in.len = conn->in.copy; From baebc497b43a69d7280af226e08214c527220d45 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:38 -0500 Subject: [PATCH 0078/1940] [SCSI] iscsi: update some iscsi proto defs From: michaelc@cs.wisc.edu Cleanup some iscsi_proto defs, add some missing values, and fix some defs. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 2 +- include/scsi/iscsi_proto.h | 45 ++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index bb0a5039d334..baacf836083e 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -751,7 +751,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) (void*)&mtask, sizeof(void*)); conn->tmabort_state = ((struct iscsi_tm_rsp *)hdr)-> - response == SCSI_TCP_TM_RESP_COMPLETE ? + response == ISCSI_TMF_RSP_COMPLETE ? TMABORT_SUCCESS:TMABORT_FAILED; /* unblock eh_abort() */ wake_up(&conn->ehwait); diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index 6c08551c79f5..8d3190480441 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -56,7 +56,8 @@ struct iscsi_hdr { __be32 ttt; /* Target Task Tag */ __be32 statsn; __be32 exp_statsn; - uint8_t other[16]; + __be32 max_statsn; + uint8_t other[12]; }; /************************* RFC 3720 Begin *****************************/ @@ -78,6 +79,11 @@ struct iscsi_hdr { #define ISCSI_OP_LOGOUT 0x06 #define ISCSI_OP_SNACK 0x10 +#define ISCSI_OP_VENDOR1_CMD 0x1c +#define ISCSI_OP_VENDOR2_CMD 0x1d +#define ISCSI_OP_VENDOR3_CMD 0x1e +#define ISCSI_OP_VENDOR4_CMD 0x1f + /* Target Opcode values */ #define ISCSI_OP_NOOP_IN 0x20 #define ISCSI_OP_SCSI_CMD_RSP 0x21 @@ -90,12 +96,20 @@ struct iscsi_hdr { #define ISCSI_OP_ASYNC_EVENT 0x32 #define ISCSI_OP_REJECT 0x3f +struct iscsi_ahs_hdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t ahspec[5]; +}; + +#define ISCSI_AHSTYPE_CDB 1 +#define ISCSI_AHSTYPE_RLENGTH 2 + /* iSCSI PDU Header */ struct iscsi_cmd { uint8_t opcode; uint8_t flags; - uint8_t rsvd2; - uint8_t cmdrn; + __be16 rsvd2; uint8_t hlength; uint8_t dlength[3]; uint8_t lun[8]; @@ -120,6 +134,13 @@ struct iscsi_cmd { #define ISCSI_ATTR_HEAD_OF_QUEUE 3 #define ISCSI_ATTR_ACA 4 +struct iscsi_rlength_ahdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t reserved; + __be32 read_length; +}; + /* SCSI Response Header */ struct iscsi_cmd_rsp { uint8_t opcode; @@ -227,7 +248,7 @@ struct iscsi_tm { uint8_t rsvd2[8]; }; -#define ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK 0x7F +#define ISCSI_FLAG_TM_FUNC_MASK 0x7F /* Function values */ #define ISCSI_TM_FUNC_ABORT_TASK 1 @@ -257,14 +278,14 @@ struct iscsi_tm_rsp { }; /* Response values */ -#define SCSI_TCP_TM_RESP_COMPLETE 0x00 -#define SCSI_TCP_TM_RESP_NO_TASK 0x01 -#define SCSI_TCP_TM_RESP_NO_LUN 0x02 -#define SCSI_TCP_TM_RESP_TASK_ALLEGIANT 0x03 -#define SCSI_TCP_TM_RESP_NO_FAILOVER 0x04 -#define SCSI_TCP_TM_RESP_NOT_SUPPORTED 0x05 -#define SCSI_TCP_TM_RESP_AUTH_FAILED 0x06 -#define SCSI_TCP_TM_RESP_REJECTED 0xff +#define ISCSI_TMF_RSP_COMPLETE 0x00 +#define ISCSI_TMF_RSP_NO_TASK 0x01 +#define ISCSI_TMF_RSP_NO_LUN 0x02 +#define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03 +#define ISCSI_TMF_RSP_NO_FAILOVER 0x04 +#define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05 +#define ISCSI_TMF_RSP_AUTH_FAILED 0x06 +#define ISCSI_TMF_RSP_REJECTED 0xff /* Ready To Transfer Header */ struct iscsi_r2t_rsp { From 02cf9311ee4690373ebbe62a5986025c932bead0 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:41 -0500 Subject: [PATCH 0079/1940] [SCSI] iscsi: fix ahs len From: tomof@acm.org Fix AHS Length Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index baacf836083e..13411ca3d648 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -557,7 +557,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) conn->data_copied = 0; /* read AHS */ - conn->in.ahslen = hdr->hlength*(4*sizeof(__u16)); + conn->in.ahslen = hdr->hlength * 4; conn->in.offset += conn->in.ahslen; conn->in.copy -= conn->in.ahslen; if (conn->in.copy < 0) { From 762e2bfac7bc5f21b04ff17138aac3c453fb6481 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:46 -0500 Subject: [PATCH 0080/1940] [SCSI] iscsi: add newline to sysfs output From: tomof@acm.org trivial cleanup of show_transport_handle() Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index e4fceca49e56..d010aeda9d62 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -97,7 +97,7 @@ static ssize_t show_transport_handle(struct class_device *cdev, char *buf) { struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); - return sprintf(buf, "%llu", (unsigned long long)iscsi_handle(priv->iscsi_transport)); + return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport)); } static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); From fa0a6957aa7d02addb08a231c8e7c77c2b8fcd20 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:01:57 -0500 Subject: [PATCH 0081/1940] [SCSI] iscsi: rename some proto defs From: hare@suse.de for a proper alignment between open-iscsi and iscsitarget the definitions in include/iscsi_proto.h do not match exactly. With this patch it's possible to have iscsitarget use 'include/iscsi_proto.h' instead of its own iscsi_hdr.h. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/iscsi_proto.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index 8d3190480441..4feda05fdf25 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -548,9 +548,11 @@ struct iscsi_reject { uint8_t flags; uint8_t reason; uint8_t rsvd2; - uint8_t rsvd3; + uint8_t hlength; uint8_t dlength[3]; - uint8_t rsvd4[16]; + uint8_t rsvd3[8]; + __be32 ffffffff; + uint8_t rsvd4[4]; __be32 statsn; __be32 exp_cmdsn; __be32 max_cmdsn; @@ -560,17 +562,17 @@ struct iscsi_reject { }; /* Reason for Reject */ -#define CMD_BEFORE_LOGIN 1 -#define DATA_DIGEST_ERROR 2 -#define DATA_SNACK_REJECT 3 -#define ISCSI_PROTOCOL_ERROR 4 -#define CMD_NOT_SUPPORTED 5 -#define IMM_CMD_REJECT 6 -#define TASK_IN_PROGRESS 7 -#define INVALID_SNACK 8 -#define BOOKMARK_REJECTED 9 -#define BOOKMARK_NO_RESOURCES 10 -#define NEGOTIATION_RESET 11 +#define ISCSI_REASON_CMD_BEFORE_LOGIN 1 +#define ISCSI_REASON_DATA_DIGEST_ERROR 2 +#define ISCSI_REASON_DATA_SNACK_REJECT 3 +#define ISCSI_REASON_PROTOCOL_ERROR 4 +#define ISCSI_REASON_CMD_NOT_SUPPORTED 5 +#define ISCSI_REASON_IMM_CMD_REJECT 6 +#define ISCSI_REASON_TASK_IN_PROGRESS 7 +#define ISCSI_REASON_INVALID_SNACK 8 +#define ISCSI_REASON_BOOKMARK_INVALID 9 +#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10 +#define ISCSI_REASON_NEGOTIATION_RESET 11 /* Max. number of Key=Value pairs in a text message */ #define MAX_KEY_VALUE_PAIRS 8192 From 9974487824570e7ac388390333ef5c4ca3ebc2da Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:02:04 -0500 Subject: [PATCH 0082/1940] [SCSI] iscsi: fix nop-in handling From: zhenyu.z.wang@intel.com This add check to NOOP_IN's ttt, when it's ~0UL we should not send NOOP_OUT by spec (plus some cleanup). Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 82 +++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 13411ca3d648..1d27caf3abe8 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -672,34 +672,6 @@ iscsi_hdr_recv(struct iscsi_conn *conn) else rc = ISCSI_ERR_PROTO; break; - case ISCSI_OP_NOOP_IN: - case ISCSI_OP_TEXT_RSP: - case ISCSI_OP_LOGOUT_RSP: - case ISCSI_OP_ASYNC_EVENT: - case ISCSI_OP_REJECT: - rc = iscsi_check_assign_cmdsn(session, - (struct iscsi_nopin*)hdr); - if (rc) - break; - - /* update ExpStatSN */ - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - if (!conn->in.datalen) { - struct iscsi_mgmt_task *mtask; - - rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, - NULL, 0); - mtask = (struct iscsi_mgmt_task *) - session->mgmt_cmds[conn->in.itt - - ISCSI_MGMT_ITT_OFFSET]; - if (conn->login_mtask != mtask) { - spin_lock(&session->lock); - __kfifo_put(session->mgmtpool.queue, - (void*)&mtask, sizeof(void*)); - spin_unlock(&session->lock); - } - } - break; default: rc = ISCSI_ERR_BAD_OPCODE; break; @@ -718,6 +690,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) switch(conn->in.opcode) { case ISCSI_OP_LOGIN_RSP: case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGOUT_RSP: rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); if (rc) @@ -758,20 +731,59 @@ iscsi_hdr_recv(struct iscsi_conn *conn) } spin_unlock(&session->lock); break; + case ISCSI_OP_NOOP_IN: + if (hdr->ttt != ISCSI_RESERVED_TAG) { + rc = ISCSI_ERR_PROTO; + break; + } + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + + if (!conn->in.datalen) { + struct iscsi_mgmt_task *mtask; + + rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, + NULL, 0); + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; default: rc = ISCSI_ERR_BAD_OPCODE; break; } } else if (conn->in.itt == ISCSI_RESERVED_TAG) { - if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) { - rc = iscsi_check_assign_cmdsn(session, + switch(conn->in.opcode) { + case ISCSI_OP_NOOP_IN: + if (!conn->in.datalen) { + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); - if (!rc) - rc = iscsi_recv_pdu(iscsi_handle(conn), - hdr, NULL, 0); - } - else + if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) + rc = iscsi_recv_pdu(iscsi_handle(conn), + hdr, NULL, 0); + } else + rc = ISCSI_ERR_PROTO; + break; + case ISCSI_OP_REJECT: + /* we need sth like iscsi_reject_rsp()*/ + case ISCSI_OP_ASYNC_EVENT: + /* we need sth like iscsi_async_event_rsp() */ rc = ISCSI_ERR_BAD_OPCODE; + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } } else rc = ISCSI_ERR_BAD_ITT; From beb8abd9a958999e238c31814230368045b942b3 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 12 Sep 2005 21:02:06 -0500 Subject: [PATCH 0083/1940] [SCSI] iscsi: add module version From: michaelc@cs.wisc.edu I have a bad memory. I cannot remember what versions are which, so add a module version to help. Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 1d27caf3abe8..4fea3e4edaa7 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -49,7 +49,7 @@ MODULE_AUTHOR("Dmitry Yusupov , " "Alex Aizman "); MODULE_DESCRIPTION("iSCSI/TCP data-path"); MODULE_LICENSE("GPL"); - +MODULE_VERSION("0:4.409"); /* #define DEBUG_TCP */ /* #define DEBUG_SCSI */ #define DEBUG_ASSERT From fe607aa94f5d25ee84f9a9a4fdf2cce3765e12e4 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 16 Sep 2005 19:28:01 +0200 Subject: [PATCH 0084/1940] [SCSI] dc395x: atomic_kmap for PIO Signed-off-by: Guennadi Liakhovetski Signed-off-by: James Bottomley --- drivers/scsi/dc395x.c | 13 +++++++++++++ drivers/scsi/tmscsim.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 600ba1202864..c44af5795b10 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -976,6 +976,16 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) } } +static inline void pio_trigger(void) +{ + static int feedback_requested; + + if (!feedback_requested) { + feedback_requested = 1; + printk(KERN_WARNING "%s: Please, contact " + "to help improve support for your system.\n", __FILE__); + } +} /* Prepare SRB for being sent to Device DCB w/ command *cmd */ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, @@ -2320,6 +2330,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, CFG2_WIDEFIFO); while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) { u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + pio_trigger(); *(srb->virt_addr)++ = byte; if (debug_enabled(DBG_PIO)) printk(" %02x", byte); @@ -2331,6 +2342,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, /* Read the last byte ... */ if (srb->total_xfer_length > 0) { u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + pio_trigger(); *(srb->virt_addr)++ = byte; srb->total_xfer_length--; if (debug_enabled(DBG_PIO)) @@ -2507,6 +2519,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb, if (debug_enabled(DBG_PIO)) printk(" %02x", (unsigned char) *(srb->virt_addr)); + pio_trigger(); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *(srb->virt_addr)++); diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 9589c67de535..386bd6c67e73 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -988,7 +988,15 @@ dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( residual ) { + static int feedback_requested; bval = DC390_read8 (ScsiFifo); /* get one residual byte */ + + if (!feedback_requested) { + feedback_requested = 1; + printk(KERN_WARNING "%s: Please, contact " + "to help improve support for your system.\n", __FILE__); + } + ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr ); *ptr = bval; pSRB->SGBusAddr++; xferCnt++; From e30dcf3a1905b4d2154f95db5fdfdf69691b4f0e Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 20 Sep 2005 20:49:16 -0700 Subject: [PATCH 0085/1940] [CIFS] Add support for legacy servers part eight. Write fixes for Windows ME, and do not set ctime unless explicitly requested with atime and/or mtime (it gets thrown away by most servers anyway as there is no way to set this via posix). Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 2 ++ fs/cifs/cifsfs.c | 2 +- fs/cifs/cifssmb.c | 15 +++++---- fs/cifs/inode.c | 78 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 66 insertions(+), 31 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 8b55e56cf1fe..47ae68b51847 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -2,6 +2,8 @@ Version 1.37 ------------ Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. +Do not attempt to set ctime unless atime and/or mtime change requested +(most servers throw it away anyway). Version 1.36 ------------ diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 43fb2aafa528..f738c8b19e3b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -256,7 +256,7 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->clientCanCacheAll = FALSE; cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ - + cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; INIT_LIST_HEAD(&cifs_inode->openFileList); return &cifs_inode->vfs_inode; } diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 575b2281518d..f72a61df3c68 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1072,7 +1072,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, if (bytes_sent > count) bytes_sent = count; pSMB->DataOffset = - cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); + cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); if(buf) memcpy(pSMB->Data,buf,bytes_sent); else if(ubuf) { @@ -1080,20 +1080,23 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, cifs_buf_release(pSMB); return -EFAULT; } - } else { + } else if (count != 0) { /* No buffer */ cifs_buf_release(pSMB); return -EINVAL; + } /* else setting file size with write of zero bytes */ + if(wct == 14) + byte_count = bytes_sent + 1; /* pad */ + else /* wct == 12 */ { + byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ } - - byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */ pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); - pSMB->hdr.smb_buf_length += bytes_sent+1; + pSMB->hdr.smb_buf_length += byte_count; if(wct == 14) pSMB->ByteCount = cpu_to_le16(byte_count); - else { /* old style write has byte count 4 bytes earlier */ + else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */ struct smb_com_writex_req * pSMBW = (struct smb_com_writex_req *)pSMB; pSMBW->ByteCount = cpu_to_le16(byte_count); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 6e82e1ae03b4..ca3af4eafcb2 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1030,14 +1030,15 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) /* now that we found one valid file handle no sense continuing to loop trying others, so break here */ - /* if(rc == -EINVAL) { + if(rc == -EINVAL) { int bytes_written; rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, - &bytes_written, - NULL, NULL, long_op); - } */ + &bytes_written, NULL, + NULL, 1 /* 45 sec */); + cFYI(1,("wrt seteof rc %d",rc)); + } break; } } @@ -1055,14 +1056,30 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); - /* if(rc == -EINVAL) - old_style_set_eof_via_write(xid, pTcon, - full_path, - attrs->ia_size, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR);*/ + cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); + if(rc == -EINVAL) { + __u16 netfid; + int oplock = FALSE; + + rc = SMBLegacyOpen(xid, pTcon, full_path, + FILE_OPEN, + SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, + CREATE_NOT_DIR, &netfid, &oplock, + NULL, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc==0) { + int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, + netfid, 0, + attrs->ia_size, + &bytes_written, NULL, + NULL, 1 /* 45 sec */); + cFYI(1,("wrt seteof rc %d",rc)); + CIFSSMBClose(xid, pTcon, netfid); + } + + } } /* Server is ok setting allocation size implicitly - no need @@ -1075,24 +1092,22 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) rc = vmtruncate(direntry->d_inode, attrs->ia_size); cifs_truncate_page(direntry->d_inode->i_mapping, direntry->d_inode->i_size); - } + } else + goto cifs_setattr_exit; } if (attrs->ia_valid & ATTR_UID) { - cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid)); + cFYI(1, ("UID changed to %d", attrs->ia_uid)); uid = attrs->ia_uid; - /* entry->uid = cpu_to_le16(attr->ia_uid); */ } if (attrs->ia_valid & ATTR_GID) { - cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid)); + cFYI(1, ("GID changed to %d", attrs->ia_gid)); gid = attrs->ia_gid; - /* entry->gid = cpu_to_le16(attr->ia_gid); */ } time_buf.Attributes = 0; if (attrs->ia_valid & ATTR_MODE) { - cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode)); + cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); mode = attrs->ia_mode; - /* entry->mode = cpu_to_le16(attr->ia_mode); */ } if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) @@ -1132,18 +1147,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); } else time_buf.LastWriteTime = 0; - - if (attrs->ia_valid & ATTR_CTIME) { + /* Do not set ctime explicitly unless other time + stamps are changed explicitly (i.e. by utime() + since we would then have a mix of client and + server times */ + + if (set_time && (attrs->ia_valid & ATTR_CTIME)) { set_time = TRUE; - cFYI(1, (" CIFS - CTIME changed ")); /* BB probably no need */ + /* Although Samba throws this field away + it may be useful to Windows - but we do + not want to set ctime unless some other + timestamp is changing */ + cFYI(1, ("CIFS - CTIME changed ")); time_buf.ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); } else time_buf.ChangeTime = 0; if (set_time || time_buf.Attributes) { - /* BB what if setting one attribute fails (such as size) but - time setting works? */ time_buf.CreationTime = 0; /* do not change */ /* In the future we should experiment - try setting timestamps via Handle (SetFileInfo) instead of by path */ @@ -1182,12 +1203,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) &time_buf, cifs_sb->local_nls); */ } } + /* Even if error on time set, no sense failing the call if + the server would set the time to a reasonable value anyway, + and this check ensures that we are not being called from + sys_utimes in which case we ought to fail the call back to + the user when the server rejects the call */ + if((rc) && (attrs->ia_valid && + (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) + rc = 0; } /* do not need local check to inode_check_ok since the server does that */ if (!rc) rc = inode_setattr(direntry->d_inode, attrs); +cifs_setattr_exit: kfree(full_path); FreeXid(xid); return rc; From a21ead3239c6a7a1220b45df0a7b537882afff16 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 21 Sep 2005 18:47:00 +1000 Subject: [PATCH 0086/1940] Revert "[PATCH] ppc32: Allow user to individual select CHRP/PMAC/PREP config" This reverts df0d3cecc4bd03ea911d7c3302510984388c8a76 commit. --- arch/ppc/Kconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 96b574c0e44a..776941c75672 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -747,13 +747,12 @@ config CPM2 on it (826x, 827x, 8560). config PPC_CHRP - bool " Common Hardware Reference Platform (CHRP) based machines" bool depends on PPC_MULTIPLATFORM default y config PPC_PMAC - bool " Apple PowerMac based machines" + bool depends on PPC_MULTIPLATFORM default y @@ -763,7 +762,6 @@ config PPC_PMAC64 default y config PPC_PREP - bool " PowerPC Reference Platform (PREP) based machines" bool depends on PPC_MULTIPLATFORM default y From c707ffcf3a44914f30e5f2fd53089ad5586c9e42 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 20 Sep 2005 13:45:41 +1000 Subject: [PATCH 0087/1940] [PATCH] ppc64: Updated Olof iommu updates 1/3 Split out the implementation-specific parts of include/asm-ppc64/iommu.h to separate include files (tce.h and dart.h respectively). The generic iommu code really doesn't care about the underlying implementation, and the TCE and DART stuff is completely different. Signed-off-by: Olof Johansson Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/iSeries_iommu.c | 1 + arch/ppc64/kernel/iSeries_vio.c | 1 + arch/ppc64/kernel/pSeries_iommu.c | 1 + arch/ppc64/kernel/pSeries_vio.c | 1 + arch/ppc64/kernel/u3_iommu.c | 29 +--------------- include/asm-ppc64/dart.h | 55 +++++++++++++++++++++++++++++ include/asm-ppc64/iommu.h | 36 +------------------ include/asm-ppc64/tce.h | 57 +++++++++++++++++++++++++++++++ 8 files changed, 118 insertions(+), 63 deletions(-) create mode 100644 include/asm-ppc64/dart.h create mode 100644 include/asm-ppc64/tce.h diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c index f8ff1bb054dc..287db32d9867 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/ppc64/kernel/iSeries_iommu.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/ppc64/kernel/iSeries_vio.c index 6b754b0c8344..c0f7d2e9153f 100644 --- a/arch/ppc64/kernel/iSeries_vio.c +++ b/arch/ppc64/kernel/iSeries_vio.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index f0fd7fbd6531..7f7947c3e12f 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "pci.h" #define DBG(fmt...) diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/ppc64/kernel/pSeries_vio.c index e0ae06f58f86..866379b80c09 100644 --- a/arch/ppc64/kernel/pSeries_vio.c +++ b/arch/ppc64/kernel/pSeries_vio.c @@ -22,6 +22,7 @@ #include #include #include +#include extern struct subsystem devices_subsys; /* needed for vio_find_name() */ diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index 41ea09cb9ac7..115cbdf3b13b 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c @@ -44,39 +44,12 @@ #include #include #include +#include #include "pci.h" extern int iommu_force_on; -/* physical base of DART registers */ -#define DART_BASE 0xf8033000UL - -/* Offset from base to control register */ -#define DARTCNTL 0 -/* Offset from base to exception register */ -#define DARTEXCP 0x10 -/* Offset from base to TLB tag registers */ -#define DARTTAG 0x1000 - - -/* Control Register fields */ - -/* base address of table (pfn) */ -#define DARTCNTL_BASE_MASK 0xfffff -#define DARTCNTL_BASE_SHIFT 12 - -#define DARTCNTL_FLUSHTLB 0x400 -#define DARTCNTL_ENABLE 0x200 - -/* size of table in pages */ -#define DARTCNTL_SIZE_MASK 0x1ff -#define DARTCNTL_SIZE_SHIFT 0 - -/* DART table fields */ -#define DARTMAP_VALID 0x80000000 -#define DARTMAP_RPNMASK 0x00ffffff - /* Physical base address and size of the DART table */ unsigned long dart_tablebase; /* exported to htab_initialize */ static unsigned long dart_tablesize; diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h new file mode 100644 index 000000000000..306799a31a5d --- /dev/null +++ b/include/asm-ppc64/dart.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_DART_H +#define _ASM_DART_H + + +/* physical base of DART registers */ +#define DART_BASE 0xf8033000UL + +/* Offset from base to control register */ +#define DARTCNTL 0 +/* Offset from base to exception register */ +#define DARTEXCP 0x10 +/* Offset from base to TLB tag registers */ +#define DARTTAG 0x1000 + + +/* Control Register fields */ + +/* base address of table (pfn) */ +#define DARTCNTL_BASE_MASK 0xfffff +#define DARTCNTL_BASE_SHIFT 12 + +#define DARTCNTL_FLUSHTLB 0x400 +#define DARTCNTL_ENABLE 0x200 + +/* size of table in pages */ +#define DARTCNTL_SIZE_MASK 0x1ff +#define DARTCNTL_SIZE_SHIFT 0 + + +/* DART table fields */ + +#define DARTMAP_VALID 0x80000000 +#define DARTMAP_RPNMASK 0x00ffffff + + + +#endif diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index 72dcf8116b04..a6a173d49506 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -1,5 +1,4 @@ /* - * iommu.h * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * Rewrite, cleanup: * Copyright (C) 2004 Olof Johansson , IBM Corporation @@ -29,44 +28,11 @@ /* * IOMAP_MAX_ORDER defines the largest contiguous block - * of dma (tce) space we can get. IOMAP_MAX_ORDER = 13 + * of dma space we can get. IOMAP_MAX_ORDER = 13 * allows up to 2**12 pages (4096 * 4096) = 16 MB */ #define IOMAP_MAX_ORDER 13 -/* - * Tces come in two formats, one for the virtual bus and a different - * format for PCI - */ -#define TCE_VB 0 -#define TCE_PCI 1 - -/* tce_entry - * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's - * abstracted so layout is irrelevant. - */ -union tce_entry { - unsigned long te_word; - struct { - unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ - unsigned int tb_rsvd :6; - unsigned long tb_rpn :40; /* Real page number */ - unsigned int tb_valid :1; /* Tce is valid (vb only) */ - unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ - unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ - unsigned int tb_pciwr :1; /* Write allowed (pci only) */ - unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ - } te_bits; -#define te_cacheBits te_bits.tb_cacheBits -#define te_rpn te_bits.tb_rpn -#define te_valid te_bits.tb_valid -#define te_allio te_bits.tb_allio -#define te_lpindex te_bits.tb_lpindex -#define te_pciwr te_bits.tb_pciwr -#define te_rdwr te_bits.tb_rdwr -}; - - struct iommu_table { unsigned long it_busno; /* Bus number this table belongs to */ unsigned long it_size; /* Size of iommu table in entries */ diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h new file mode 100644 index 000000000000..636504c62c88 --- /dev/null +++ b/include/asm-ppc64/tce.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation + * Rewrite, cleanup: + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_TCE_H +#define _ASM_TCE_H + +/* + * Tces come in two formats, one for the virtual bus and a different + * format for PCI + */ +#define TCE_VB 0 +#define TCE_PCI 1 + +/* tce_entry + * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's + * abstracted so layout is irrelevant. + */ +union tce_entry { + unsigned long te_word; + struct { + unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ + unsigned int tb_rsvd :6; + unsigned long tb_rpn :40; /* Real page number */ + unsigned int tb_valid :1; /* Tce is valid (vb only) */ + unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ + unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ + unsigned int tb_pciwr :1; /* Write allowed (pci only) */ + unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ + } te_bits; +#define te_cacheBits te_bits.tb_cacheBits +#define te_rpn te_bits.tb_rpn +#define te_valid te_bits.tb_valid +#define te_allio te_bits.tb_allio +#define te_lpindex te_bits.tb_lpindex +#define te_pciwr te_bits.tb_pciwr +#define te_rdwr te_bits.tb_rdwr +}; + + +#endif From d0035c62d9145a2ce3057c8182a7ff0b4921a41c Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 20 Sep 2005 13:46:44 +1000 Subject: [PATCH 0088/1940] [PATCH] ppc64: Updated Olof iommu updates 2/3 There are potential cases in the future where the IOMMU might be mapping smaller pages than the regular MMU is using. Keep the allocator working on MMU pagesizes, but the low-level mapping functions need to map more than one TCE entry per page to deal with this. Signed-off-by: Olof Johansson Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/pSeries_iommu.c | 25 ++++++++++++++++++++----- arch/ppc64/kernel/u3_iommu.c | 18 ++++++++++++------ include/asm-ppc64/dart.h | 4 ++++ include/asm-ppc64/tce.h | 7 +++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 7f7947c3e12f..2b5e622732f4 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -60,6 +60,9 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index, union tce_entry t; union tce_entry *tp; + index <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + t.te_word = 0; t.te_rdwr = 1; // Read allowed @@ -70,11 +73,11 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index, while (npages--) { /* can't move this out since we might cross LMB boundary */ - t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tp->te_word = t.te_word; - uaddr += PAGE_SIZE; + uaddr += TCE_PAGE_SIZE; tp++; } } @@ -85,6 +88,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) union tce_entry t; union tce_entry *tp; + npages <<= TCE_PAGE_FACTOR; + index <<= TCE_PAGE_FACTOR; + t.te_word = 0; tp = ((union tce_entry *)tbl->it_base) + index; @@ -104,7 +110,7 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, union tce_entry tce; tce.te_word = 0; - tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) tce.te_pciwr = 1; @@ -137,6 +143,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, union tce_entry tce, *tcep; long l, limit; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + if (npages == 1) return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction); @@ -156,7 +165,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, } tce.te_word = 0; - tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) tce.te_pciwr = 1; @@ -167,7 +176,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, * Set up the page with TCE data, looping through and setting * the values. */ - limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry)); + limit = min_t(long, npages, 4096/sizeof(union tce_entry)); for (l = 0; l < limit; l++) { tcep[l] = tce; @@ -197,6 +206,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages u64 rc; union tce_entry tce; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + tce.te_word = 0; while (npages--) { @@ -222,6 +234,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n u64 rc; union tce_entry tce; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + tce.te_word = 0; rc = plpar_tce_stuff((u64)tbl->it_index, diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index 115cbdf3b13b..df9c775f4955 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c @@ -125,18 +125,21 @@ static void dart_build(struct iommu_table *tbl, long index, DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int*)tbl->it_base) + index; /* On U3, all memory is contigous, so we can move this * out of the loop. */ while (npages--) { - rpn = virt_to_abs(uaddr) >> PAGE_SHIFT; + rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); rpn++; - uaddr += PAGE_SIZE; + uaddr += DART_PAGE_SIZE; } dart_dirty = 1; @@ -154,6 +157,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) DBG("dart: free at: %lx, %lx\n", index, npages); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int *)tbl->it_base) + index; while (npages--) @@ -182,10 +188,10 @@ static int dart_init(struct device_node *dart_node) * that to work around what looks like a problem with the HT bridge * prefetching into invalid pages and corrupting data */ - tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE); + tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); if (!tmp) panic("U3-DART: Cannot allocate spare page!"); - dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK); + dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK); /* Map in DART registers. FIXME: Use device node to get base address */ dart = ioremap(DART_BASE, 0x7000); @@ -196,8 +202,8 @@ static int dart_init(struct device_node *dart_node) * table size and enable bit */ regword = DARTCNTL_ENABLE | - ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | - (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK) + ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | + (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK) << DARTCNTL_SIZE_SHIFT); dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h index 306799a31a5d..a9000de8a2e3 100644 --- a/include/asm-ppc64/dart.h +++ b/include/asm-ppc64/dart.h @@ -51,5 +51,9 @@ #define DARTMAP_RPNMASK 0x00ffffff +#define DART_SHIFT 12 +#define DART_PAGE_SIZE (1 << DART_SHIFT) +#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_SHIFT) + #endif diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h index 636504c62c88..d40b6b42ab35 100644 --- a/include/asm-ppc64/tce.h +++ b/include/asm-ppc64/tce.h @@ -28,6 +28,13 @@ #define TCE_VB 0 #define TCE_PCI 1 +/* TCE page size is 4096 bytes (1 << 12) */ + +#define TCE_SHIFT 12 +#define TCE_PAGE_SIZE (1 << TCE_SHIFT) +#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) + + /* tce_entry * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's * abstracted so layout is irrelevant. From 637a6ff6ce525d8495df944550efea0f023dd521 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 20 Sep 2005 13:47:41 +1000 Subject: [PATCH 0089/1940] [PATCH] ppc64: Updated Olof misc updates 3/3 Replace some of the hard-coded constants with PAGE_SIZE/SHIFT/ORDER where appropriate. Likewise, in a couple of places it doesn't make sense to base some allocations on page size when all that's required is a constant 4K, etc. Signed-off-by: Olof Johansson Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/head.S | 2 +- arch/ppc64/kernel/misc.S | 2 +- arch/ppc64/kernel/vmlinux.lds.S | 16 ++++++++++------ include/asm-ppc64/elf.h | 3 ++- include/asm-ppc64/mmu.h | 2 +- include/asm-ppc64/thread_info.h | 6 +++--- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 72c61041151a..22a5ee07e1ea 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1992,7 +1992,7 @@ _GLOBAL(smp_release_cpus) */ .section ".bss" - .align 12 + .align PAGE_SHIFT .globl empty_zero_page empty_zero_page: diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index e7241ad80a08..a25b59759ddb 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -329,7 +329,7 @@ _GLOBAL(__flush_dcache_icache) /* Flush the dcache */ ld r7,PPC64_CACHES@toc(r2) - clrrdi r3,r3,12 /* Page align */ + clrrdi r3,r3,PAGE_SHIFT /* Page align */ lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */ lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */ mr r6,r3 diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S index 0306510bc4ff..f34d514432ac 100644 --- a/arch/ppc64/kernel/vmlinux.lds.S +++ b/arch/ppc64/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +#include #include OUTPUT_ARCH(powerpc:common64) @@ -17,7 +18,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT *(.fixup) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _etext = .; } @@ -43,7 +44,7 @@ SECTIONS /* will be freed after init */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __init_begin = .; .init.text : { @@ -83,7 +84,7 @@ SECTIONS SECURITY_INIT - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .init.ramfs : { __initramfs_start = .; *(.init.ramfs) @@ -96,18 +97,21 @@ SECTIONS __per_cpu_end = .; } + . = ALIGN(PAGE_SIZE); . = ALIGN(16384); __init_end = .; /* freed after init ends here */ /* Read/write sections */ + . = ALIGN(PAGE_SIZE); . = ALIGN(16384); /* The initial task and kernel stack */ .data.init_task : { *(.data.init_task) } + . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.page_aligned) } @@ -129,18 +133,18 @@ SECTIONS __toc_start = .; *(.got) *(.toc) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _edata = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .bss : { __bss_start = .; *(.bss) __bss_stop = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _end = . ; } diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h index c919a89343db..e27c2942953c 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-ppc64/elf.h @@ -5,6 +5,7 @@ #include #include #include +#include /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 @@ -146,7 +147,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) #define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE /* This is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 737e85a5ce3c..d2b0b796d35e 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h @@ -30,7 +30,7 @@ /* Location of cpu0's segment table */ #define STAB0_PAGE 0x6 -#define STAB0_PHYS_ADDR (STAB0_PAGE< Date: Tue, 20 Sep 2005 13:52:50 +1000 Subject: [PATCH 0090/1940] [PATCH] ppc64: Store virtual address in TLB flush batches This patch slightly change the TLB flush batch mecanism so that we store the full vaddr (including vsid) when adding an entry to the batch so that the flush part doesn't have to get to the context. This cleans it a bit, and paves the way to future updates like dynamic vsids. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/pSeries_lpar.c | 5 ++--- arch/ppc64/mm/hash_native.c | 13 +++---------- arch/ppc64/mm/hash_utils.c | 21 +++++++-------------- arch/ppc64/mm/tlb.c | 25 ++++++++++++------------- include/asm-ppc64/machdep.h | 5 ++--- include/asm-ppc64/tlbflush.h | 7 ++----- 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index a6de83f2078f..268d8362dde7 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c @@ -486,8 +486,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie * lock. */ -void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number, - int local) +void pSeries_lpar_flush_hash_range(unsigned long number, int local) { int i; unsigned long flags = 0; @@ -498,7 +497,7 @@ void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number, spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); for (i = 0; i < number; i++) - flush_hash_page(context, batch->addr[i], batch->pte[i], local); + flush_hash_page(batch->vaddr[i], batch->pte[i], local); if (lock_tlbie) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 7626bb59954d..29b074505d3e 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c @@ -335,10 +335,9 @@ static void native_hpte_clear(void) local_irq_restore(flags); } -static void native_flush_hash_range(unsigned long context, - unsigned long number, int local) +static void native_flush_hash_range(unsigned long number, int local) { - unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn; + unsigned long va, vpn, hash, secondary, slot, flags, avpn; int i, j; hpte_t *hptep; unsigned long hpte_v; @@ -351,13 +350,7 @@ static void native_flush_hash_range(unsigned long context, j = 0; for (i = 0; i < number; i++) { - if (batch->addr[i] < KERNELBASE) - vsid = get_vsid(context, batch->addr[i]); - else - vsid = get_kernel_vsid(batch->addr[i]); - - va = (vsid << 28) | (batch->addr[i] & 0x0fffffff); - batch->vaddr[j] = va; + va = batch->vaddr[j]; if (large) vpn = va >> HPAGE_SHIFT; else diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 09475c8edf7c..36cf474b3d36 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -355,18 +355,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) return ret; } -void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, - int local) +void flush_hash_page(unsigned long va, pte_t pte, int local) { - unsigned long vsid, vpn, va, hash, secondary, slot; + unsigned long vpn, hash, secondary, slot; unsigned long huge = pte_huge(pte); - if (ea < KERNELBASE) - vsid = get_vsid(context, ea); - else - vsid = get_kernel_vsid(ea); - - va = (vsid << 28) | (ea & 0x0fffffff); if (huge) vpn = va >> HPAGE_SHIFT; else @@ -381,17 +374,17 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, ppc_md.hpte_invalidate(slot, va, huge, local); } -void flush_hash_range(unsigned long context, unsigned long number, int local) +void flush_hash_range(unsigned long number, int local) { if (ppc_md.flush_hash_range) { - ppc_md.flush_hash_range(context, number, local); + ppc_md.flush_hash_range(number, local); } else { int i; - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = + &__get_cpu_var(ppc64_tlb_batch); for (i = 0; i < number; i++) - flush_hash_page(context, batch->addr[i], batch->pte[i], - local); + flush_hash_page(batch->vaddr[i], batch->pte[i], local); } } diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index d8a6593a13f0..31afd95bf870 100644 --- a/arch/ppc64/mm/tlb.c +++ b/arch/ppc64/mm/tlb.c @@ -128,12 +128,10 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) void hpte_update(struct mm_struct *mm, unsigned long addr, unsigned long pte, int wrprot) { - int i; - unsigned long context = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + unsigned long vsid; + int i; - if (REGION_ID(addr) == USER_REGION_ID) - context = mm->context.id; i = batch->index; /* @@ -143,17 +141,19 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, * up scanning and resetting referenced bits then our batch context * will change mid stream. */ - if (unlikely(i != 0 && context != batch->context)) { + if (unlikely(i != 0 && mm != batch->mm)) { flush_tlb_pending(); i = 0; } - - if (i == 0) { - batch->context = context; + if (i == 0) batch->mm = mm; - } + if (addr < KERNELBASE) { + vsid = get_vsid(mm->context.id, addr); + WARN_ON(vsid == 0); + } else + vsid = get_kernel_vsid(addr); + batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff); batch->pte[i] = __pte(pte); - batch->addr[i] = addr; batch->index = ++i; if (i >= PPC64_TLB_BATCH_NR) flush_tlb_pending(); @@ -175,10 +175,9 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) local = 1; if (i == 1) - flush_hash_page(batch->context, batch->addr[0], batch->pte[0], - local); + flush_hash_page(batch->vaddr[0], batch->pte[0], local); else - flush_hash_range(batch->context, i, local); + flush_hash_range(i, local); batch->index = 0; put_cpu(); } diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index 8027160ec96d..d35d9d3e44cf 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -56,9 +56,8 @@ struct machdep_calls { unsigned long vflags, unsigned long rflags); long (*hpte_remove)(unsigned long hpte_group); - void (*flush_hash_range)(unsigned long context, - unsigned long number, - int local); + void (*flush_hash_range)(unsigned long number, int local); + /* special for kexec, to be called in real mode, linar mapping is * destroyed as well */ void (*hpte_clear_all)(void); diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h index 45411a67e082..800bc0010cfb 100644 --- a/include/asm-ppc64/tlbflush.h +++ b/include/asm-ppc64/tlbflush.h @@ -20,10 +20,8 @@ struct mm_struct; struct ppc64_tlb_batch { unsigned long index; - unsigned long context; struct mm_struct *mm; pte_t pte[PPC64_TLB_BATCH_NR]; - unsigned long addr[PPC64_TLB_BATCH_NR]; unsigned long vaddr[PPC64_TLB_BATCH_NR]; }; DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); @@ -47,8 +45,7 @@ static inline void flush_tlb_pending(void) #define flush_tlb_kernel_range(start, end) flush_tlb_pending() #define flush_tlb_pgtables(mm, start, end) do { } while (0) -extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, - int local); -void flush_hash_range(unsigned long context, unsigned long number, int local); +extern void flush_hash_page(unsigned long va, pte_t pte, int local); +void flush_hash_range(unsigned long number, int local); #endif /* _PPC64_TLBFLUSH_H */ From da0825fd201a03294dbf7f8f030676d608da122c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sun, 18 Sep 2005 21:33:18 -0500 Subject: [PATCH 0091/1940] [PATCH] ppc32: Allow user to individual select CHRP/PMAC/PREP config Made the CHRP/PMAC/PREP config options selectable by the user. This allows us to build kernels specifically for one of the platforms thus reducing code size. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 776941c75672..f9285210475f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -747,12 +747,12 @@ config CPM2 on it (826x, 827x, 8560). config PPC_CHRP - bool + bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM default y config PPC_PMAC - bool + bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM default y @@ -762,7 +762,7 @@ config PPC_PMAC64 default y config PPC_PREP - bool + bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM default y From 17b1dc07aebdef9ee43c06525bee702d5f0e9db1 Mon Sep 17 00:00:00 2001 From: "jdl@freescale.com" Date: Fri, 9 Sep 2005 16:43:52 -0500 Subject: [PATCH 0092/1940] [PATCH] powerpc: Merge asm-ppc*/posix_types.h Merge asm-ppc/posix_types.h and asm-ppc64/posix_types.h. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- .../{asm-ppc64 => asm-powerpc}/posix_types.h | 40 ++++--- include/asm-ppc/posix_types.h | 111 ------------------ 2 files changed, 25 insertions(+), 126 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/posix_types.h (88%) delete mode 100644 include/asm-ppc/posix_types.h diff --git a/include/asm-ppc64/posix_types.h b/include/asm-powerpc/posix_types.h similarity index 88% rename from include/asm-ppc64/posix_types.h rename to include/asm-powerpc/posix_types.h index 516de7201b5d..c6391077224f 100644 --- a/include/asm-ppc64/posix_types.h +++ b/include/asm-powerpc/posix_types.h @@ -1,44 +1,54 @@ -#ifndef _PPC64_POSIX_TYPES_H -#define _PPC64_POSIX_TYPES_H +#ifndef _ASM_POWERPC_POSIX_TYPES_H +#define _ASM_POWERPC_POSIX_TYPES_H /* * This file is generally used by user-level software, so you need to * be a little careful about namespace pollution etc. Also, we cannot * assume GCC is being used. - * - * 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. */ typedef unsigned long __kernel_ino_t; -typedef unsigned long __kernel_nlink_t; typedef unsigned int __kernel_mode_t; typedef long __kernel_off_t; -typedef long long __kernel_loff_t; typedef int __kernel_pid_t; -typedef int __kernel_ipc_pid_t; typedef unsigned int __kernel_uid_t; typedef unsigned int __kernel_gid_t; -typedef unsigned long __kernel_size_t; -typedef long __kernel_ssize_t; typedef long __kernel_ptrdiff_t; typedef long __kernel_time_t; +typedef long __kernel_clock_t; typedef int __kernel_timer_t; typedef int __kernel_clockid_t; typedef long __kernel_suseconds_t; -typedef long __kernel_clock_t; typedef int __kernel_daddr_t; typedef char * __kernel_caddr_t; typedef unsigned short __kernel_uid16_t; typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; - typedef unsigned int __kernel_old_uid_t; typedef unsigned int __kernel_old_gid_t; + +#ifdef __powerpc64__ +typedef unsigned long __kernel_nlink_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; typedef unsigned long __kernel_old_dev_t; +#else +typedef unsigned short __kernel_nlink_t; +typedef short __kernel_ipc_pid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef unsigned int __kernel_old_dev_t; +#endif + +#ifdef __powerpc64__ +typedef long long __kernel_loff_t; +#else +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif +#endif typedef struct { int val[2]; @@ -116,4 +126,4 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p) #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ #endif /* __GNUC__ */ -#endif /* _PPC64_POSIX_TYPES_H */ +#endif /* _ASM_POWERPC_POSIX_TYPES_H */ diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h deleted file mode 100644 index a14a82abe8d2..000000000000 --- a/include/asm-ppc/posix_types.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _PPC_POSIX_TYPES_H -#define _PPC_POSIX_TYPES_H - -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -typedef unsigned long __kernel_ino_t; -typedef unsigned int __kernel_mode_t; -typedef unsigned short __kernel_nlink_t; -typedef long __kernel_off_t; -typedef int __kernel_pid_t; -typedef unsigned int __kernel_uid_t; -typedef unsigned int __kernel_gid_t; -typedef unsigned int __kernel_size_t; -typedef int __kernel_ssize_t; -typedef long __kernel_ptrdiff_t; -typedef long __kernel_time_t; -typedef long __kernel_suseconds_t; -typedef long __kernel_clock_t; -typedef int __kernel_timer_t; -typedef int __kernel_clockid_t; -typedef int __kernel_daddr_t; -typedef char * __kernel_caddr_t; -typedef short __kernel_ipc_pid_t; -typedef unsigned short __kernel_uid16_t; -typedef unsigned short __kernel_gid16_t; -typedef unsigned int __kernel_uid32_t; -typedef unsigned int __kernel_gid32_t; - -typedef unsigned int __kernel_old_uid_t; -typedef unsigned int __kernel_old_gid_t; -typedef unsigned int __kernel_old_dev_t; - -#ifdef __GNUC__ -typedef long long __kernel_loff_t; -#endif - -typedef struct { - int val[2]; -} __kernel_fsid_t; - -#ifndef __GNUC__ - -#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) -#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) -#define __FD_ZERO(set) \ - ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) - -#else /* __GNUC__ */ - -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \ - || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -/* With GNU C, use inline functions instead so args are evaluated only once: */ - -#undef __FD_SET -static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - fdsetp->fds_bits[_tmp] |= (1UL<<_rem); -} - -#undef __FD_CLR -static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); -} - -#undef __FD_ISSET -static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; -} - -/* - * This will unroll the loop for the normal constant case (8 ints, - * for a 256-bit fd_set) - */ -#undef __FD_ZERO -static __inline__ void __FD_ZERO(__kernel_fd_set *p) -{ - unsigned int *tmp = (unsigned int *)p->fds_bits; - int i; - - if (__builtin_constant_p(__FDSET_LONGS)) { - switch (__FDSET_LONGS) { - case 8: - tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; - tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; - return; - } - } - i = __FDSET_LONGS; - while (i) { - i--; - *tmp = 0; - tmp++; - } -} - -#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ -#endif /* __GNUC__ */ -#endif /* _PPC_POSIX_TYPES_H */ From 564ee7a5668e8b6d3b369fd807c75c77285c88d4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 17:33:25 +1000 Subject: [PATCH 0093/1940] [PATCH] powerpc: Move arch/ppc*/kernel/vecemu.c to arch/powerpc This file is the same in both architectures so create arch/powerpc/kernel and move it there. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/{ppc => powerpc}/kernel/vecemu.c | 0 arch/ppc/kernel/Makefile | 2 + arch/ppc64/kernel/Makefile | 3 + arch/ppc64/kernel/vecemu.c | 346 -------------------------- 4 files changed, 5 insertions(+), 346 deletions(-) rename arch/{ppc => powerpc}/kernel/vecemu.c (100%) delete mode 100644 arch/ppc64/kernel/vecemu.c diff --git a/arch/ppc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c similarity index 100% rename from arch/ppc/kernel/vecemu.c rename to arch/powerpc/kernel/vecemu.c diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 1fb92f16acd6..abf10dcb787b 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -36,3 +36,5 @@ ifndef CONFIG_MATH_EMULATION obj-$(CONFIG_8xx) += softemu8xx.o endif +# These are here while we do the architecture merge +vecemu-y += ../../powerpc/kernel/vecemu.o diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index ae60eb1193c6..813718df4f82 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -83,3 +83,6 @@ ifeq ($(CONFIG_PPC_ISERIES),y) arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s AFLAGS_head.o += -Iarch/ppc64/kernel endif + +# These are here while we do the architecture merge +vecemu-y += ../../powerpc/kernel/vecemu.o diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c deleted file mode 100644 index cb207629f21f..000000000000 --- a/arch/ppc64/kernel/vecemu.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Routines to emulate some Altivec/VMX instructions, specifically - * those that can trap when given denormalized operands in Java mode. - */ -#include -#include -#include -#include -#include -#include - -/* Functions in vector.S */ -extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b); -extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b); -extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); -extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); -extern void vrefp(vector128 *dst, vector128 *src); -extern void vrsqrtefp(vector128 *dst, vector128 *src); -extern void vexptep(vector128 *dst, vector128 *src); - -static unsigned int exp2s[8] = { - 0x800000, - 0x8b95c2, - 0x9837f0, - 0xa5fed7, - 0xb504f3, - 0xc5672a, - 0xd744fd, - 0xeac0c7 -}; - -/* - * Computes an estimate of 2^x. The `s' argument is the 32-bit - * single-precision floating-point representation of x. - */ -static unsigned int eexp2(unsigned int s) -{ - int exp, pwr; - unsigned int mant, frac; - - /* extract exponent field from input */ - exp = ((s >> 23) & 0xff) - 127; - if (exp > 7) { - /* check for NaN input */ - if (exp == 128 && (s & 0x7fffff) != 0) - return s | 0x400000; /* return QNaN */ - /* 2^-big = 0, 2^+big = +Inf */ - return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */ - } - if (exp < -23) - return 0x3f800000; /* 1.0 */ - - /* convert to fixed point integer in 9.23 representation */ - pwr = (s & 0x7fffff) | 0x800000; - if (exp > 0) - pwr <<= exp; - else - pwr >>= -exp; - if (s & 0x80000000) - pwr = -pwr; - - /* extract integer part, which becomes exponent part of result */ - exp = (pwr >> 23) + 126; - if (exp >= 254) - return 0x7f800000; - if (exp < -23) - return 0; - - /* table lookup on top 3 bits of fraction to get mantissa */ - mant = exp2s[(pwr >> 20) & 7]; - - /* linear interpolation using remaining 20 bits of fraction */ - asm("mulhwu %0,%1,%2" : "=r" (frac) - : "r" (pwr << 12), "r" (0x172b83ff)); - asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant)); - mant += frac; - - if (exp >= 0) - return mant + (exp << 23); - - /* denormalized result */ - exp = -exp; - mant += 1 << (exp - 1); - return mant >> exp; -} - -/* - * Computes an estimate of log_2(x). The `s' argument is the 32-bit - * single-precision floating-point representation of x. - */ -static unsigned int elog2(unsigned int s) -{ - int exp, mant, lz, frac; - - exp = s & 0x7f800000; - mant = s & 0x7fffff; - if (exp == 0x7f800000) { /* Inf or NaN */ - if (mant != 0) - s |= 0x400000; /* turn NaN into QNaN */ - return s; - } - if ((exp | mant) == 0) /* +0 or -0 */ - return 0xff800000; /* return -Inf */ - - if (exp == 0) { - /* denormalized */ - asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant)); - mant <<= lz - 8; - exp = (-118 - lz) << 23; - } else { - mant |= 0x800000; - exp -= 127 << 23; - } - - if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */ - exp |= 0x400000; /* 0.5 * 2^23 */ - asm("mulhwu %0,%1,%2" : "=r" (mant) - : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */ - } - if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */ - exp |= 0x200000; /* 0.25 * 2^23 */ - asm("mulhwu %0,%1,%2" : "=r" (mant) - : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */ - } - if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */ - exp |= 0x100000; /* 0.125 * 2^23 */ - asm("mulhwu %0,%1,%2" : "=r" (mant) - : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */ - } - if (mant > 0x800000) { /* 1.0 * 2^23 */ - /* calculate (mant - 1) * 1.381097463 */ - /* 1.381097463 == 0.125 / (2^0.125 - 1) */ - asm("mulhwu %0,%1,%2" : "=r" (frac) - : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a)); - exp += frac; - } - s = exp & 0x80000000; - if (exp != 0) { - if (s) - exp = -exp; - asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp)); - lz = 8 - lz; - if (lz > 0) - exp >>= lz; - else if (lz < 0) - exp <<= -lz; - s += ((lz + 126) << 23) + exp; - } - return s; -} - -#define VSCR_SAT 1 - -static int ctsxs(unsigned int x, int scale, unsigned int *vscrp) -{ - int exp, mant; - - exp = (x >> 23) & 0xff; - mant = x & 0x7fffff; - if (exp == 255 && mant != 0) - return 0; /* NaN -> 0 */ - exp = exp - 127 + scale; - if (exp < 0) - return 0; /* round towards zero */ - if (exp >= 31) { - /* saturate, unless the result would be -2^31 */ - if (x + (scale << 23) != 0xcf000000) - *vscrp |= VSCR_SAT; - return (x & 0x80000000)? 0x80000000: 0x7fffffff; - } - mant |= 0x800000; - mant = (mant << 7) >> (30 - exp); - return (x & 0x80000000)? -mant: mant; -} - -static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp) -{ - int exp; - unsigned int mant; - - exp = (x >> 23) & 0xff; - mant = x & 0x7fffff; - if (exp == 255 && mant != 0) - return 0; /* NaN -> 0 */ - exp = exp - 127 + scale; - if (exp < 0) - return 0; /* round towards zero */ - if (x & 0x80000000) { - /* negative => saturate to 0 */ - *vscrp |= VSCR_SAT; - return 0; - } - if (exp >= 32) { - /* saturate */ - *vscrp |= VSCR_SAT; - return 0xffffffff; - } - mant |= 0x800000; - mant = (mant << 8) >> (31 - exp); - return mant; -} - -/* Round to floating integer, towards 0 */ -static unsigned int rfiz(unsigned int x) -{ - int exp; - - exp = ((x >> 23) & 0xff) - 127; - if (exp == 128 && (x & 0x7fffff) != 0) - return x | 0x400000; /* NaN -> make it a QNaN */ - if (exp >= 23) - return x; /* it's an integer already (or Inf) */ - if (exp < 0) - return x & 0x80000000; /* |x| < 1.0 rounds to 0 */ - return x & ~(0x7fffff >> exp); -} - -/* Round to floating integer, towards +/- Inf */ -static unsigned int rfii(unsigned int x) -{ - int exp, mask; - - exp = ((x >> 23) & 0xff) - 127; - if (exp == 128 && (x & 0x7fffff) != 0) - return x | 0x400000; /* NaN -> make it a QNaN */ - if (exp >= 23) - return x; /* it's an integer already (or Inf) */ - if ((x & 0x7fffffff) == 0) - return x; /* +/-0 -> +/-0 */ - if (exp < 0) - /* 0 < |x| < 1.0 rounds to +/- 1.0 */ - return (x & 0x80000000) | 0x3f800000; - mask = 0x7fffff >> exp; - /* mantissa overflows into exponent - that's OK, - it can't overflow into the sign bit */ - return (x + mask) & ~mask; -} - -/* Round to floating integer, to nearest */ -static unsigned int rfin(unsigned int x) -{ - int exp, half; - - exp = ((x >> 23) & 0xff) - 127; - if (exp == 128 && (x & 0x7fffff) != 0) - return x | 0x400000; /* NaN -> make it a QNaN */ - if (exp >= 23) - return x; /* it's an integer already (or Inf) */ - if (exp < -1) - return x & 0x80000000; /* |x| < 0.5 -> +/-0 */ - if (exp == -1) - /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */ - return (x & 0x80000000) | 0x3f800000; - half = 0x400000 >> exp; - /* add 0.5 to the magnitude and chop off the fraction bits */ - return (x + half) & ~(0x7fffff >> exp); -} - -int -emulate_altivec(struct pt_regs *regs) -{ - unsigned int instr, i; - unsigned int va, vb, vc, vd; - vector128 *vrs; - - if (get_user(instr, (unsigned int __user *) regs->nip)) - return -EFAULT; - if ((instr >> 26) != 4) - return -EINVAL; /* not an altivec instruction */ - vd = (instr >> 21) & 0x1f; - va = (instr >> 16) & 0x1f; - vb = (instr >> 11) & 0x1f; - vc = (instr >> 6) & 0x1f; - - vrs = current->thread.vr; - switch (instr & 0x3f) { - case 10: - switch (vc) { - case 0: /* vaddfp */ - vaddfp(&vrs[vd], &vrs[va], &vrs[vb]); - break; - case 1: /* vsubfp */ - vsubfp(&vrs[vd], &vrs[va], &vrs[vb]); - break; - case 4: /* vrefp */ - vrefp(&vrs[vd], &vrs[vb]); - break; - case 5: /* vrsqrtefp */ - vrsqrtefp(&vrs[vd], &vrs[vb]); - break; - case 6: /* vexptefp */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = eexp2(vrs[vb].u[i]); - break; - case 7: /* vlogefp */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = elog2(vrs[vb].u[i]); - break; - case 8: /* vrfin */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = rfin(vrs[vb].u[i]); - break; - case 9: /* vrfiz */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = rfiz(vrs[vb].u[i]); - break; - case 10: /* vrfip */ - for (i = 0; i < 4; ++i) { - u32 x = vrs[vb].u[i]; - x = (x & 0x80000000)? rfiz(x): rfii(x); - vrs[vd].u[i] = x; - } - break; - case 11: /* vrfim */ - for (i = 0; i < 4; ++i) { - u32 x = vrs[vb].u[i]; - x = (x & 0x80000000)? rfii(x): rfiz(x); - vrs[vd].u[i] = x; - } - break; - case 14: /* vctuxs */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, - ¤t->thread.vscr.u[3]); - break; - case 15: /* vctsxs */ - for (i = 0; i < 4; ++i) - vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, - ¤t->thread.vscr.u[3]); - break; - default: - return -EINVAL; - } - break; - case 46: /* vmaddfp */ - vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); - break; - case 47: /* vnmsubfp */ - vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); - break; - default: - return -EINVAL; - } - - return 0; -} From 5bfc82652ab913606c91d74f7337cbd94627a797 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 17:50:21 +1000 Subject: [PATCH 0094/1940] [PATCH] powerpc: Merge include/asm-ppc*/a.out.h into include/asm-powerpc Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/a.out.h | 21 ++++++++--------- include/asm-ppc/a.out.h | 26 ---------------------- 2 files changed, 9 insertions(+), 38 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/a.out.h (69%) delete mode 100644 include/asm-ppc/a.out.h diff --git a/include/asm-ppc64/a.out.h b/include/asm-powerpc/a.out.h similarity index 69% rename from include/asm-ppc64/a.out.h rename to include/asm-powerpc/a.out.h index 3871e252a6f1..c7393a977364 100644 --- a/include/asm-ppc64/a.out.h +++ b/include/asm-powerpc/a.out.h @@ -1,14 +1,5 @@ -#ifndef __PPC64_A_OUT_H__ -#define __PPC64_A_OUT_H__ - -/* - * c 2001 PPC 64 Team, IBM Corp - * - * 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. - */ +#ifndef _ASM_POWERPC_A_OUT_H +#define _ASM_POWERPC_A_OUT_H struct exec { @@ -27,6 +18,7 @@ struct exec #define N_SYMSIZE(a) ((a).a_syms) #ifdef __KERNEL__ +#ifdef __powerpc64__ #define STACK_TOP_USER64 TASK_SIZE_USER64 #define STACK_TOP_USER32 TASK_SIZE_USER32 @@ -34,6 +26,11 @@ struct exec #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ STACK_TOP_USER32 : STACK_TOP_USER64) +#else /* __powerpc64__ */ + +#define STACK_TOP TASK_SIZE + +#endif /* __powerpc64__ */ #endif /* __KERNEL__ */ -#endif /* __PPC64_A_OUT_H__ */ +#endif /* _ASM_POWERPC_A_OUT_H */ diff --git a/include/asm-ppc/a.out.h b/include/asm-ppc/a.out.h deleted file mode 100644 index 8979a94c4a81..000000000000 --- a/include/asm-ppc/a.out.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __PPC_A_OUT_H__ -#define __PPC_A_OUT_H__ - -/* grabbed from the intel stuff */ -#define STACK_TOP TASK_SIZE - - -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ -}; - - -#define N_TRSIZE(a) ((a).a_trsize) -#define N_DRSIZE(a) ((a).a_drsize) -#define N_SYMSIZE(a) ((a).a_syms) - - -#endif From bcdd1ea350feb7ee28d4f425c312e9fdf681acfb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:13:24 +1000 Subject: [PATCH 0095/1940] [PATCH] powerpc: Move arch/ppc*/oprofile/Kconfig to arch/powerpc These files are identical. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/{ppc => powerpc}/oprofile/Kconfig | 0 arch/ppc/Kconfig | 2 +- arch/ppc64/Kconfig | 2 +- arch/ppc64/oprofile/Kconfig | 23 ----------------------- 4 files changed, 2 insertions(+), 25 deletions(-) rename arch/{ppc => powerpc}/oprofile/Kconfig (100%) delete mode 100644 arch/ppc64/oprofile/Kconfig diff --git a/arch/ppc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig similarity index 100% rename from arch/ppc/oprofile/Kconfig rename to arch/powerpc/oprofile/Kconfig diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index f9285210475f..ed9c9727d75f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -1368,7 +1368,7 @@ endmenu source "lib/Kconfig" -source "arch/ppc/oprofile/Kconfig" +source "arch/powerpc/oprofile/Kconfig" source "arch/ppc/Kconfig.debug" diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index c658650af429..32951bfc7f65 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -461,7 +461,7 @@ config VIOPATH depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH default y -source "arch/ppc64/oprofile/Kconfig" +source "arch/powerpc/oprofile/Kconfig" source "arch/ppc64/Kconfig.debug" diff --git a/arch/ppc64/oprofile/Kconfig b/arch/ppc64/oprofile/Kconfig deleted file mode 100644 index 5ade19801b97..000000000000 --- a/arch/ppc64/oprofile/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ - -menu "Profiling support" - depends on EXPERIMENTAL - -config PROFILING - bool "Profiling support (EXPERIMENTAL)" - help - Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. - - -config OPROFILE - tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -endmenu - From d9e5b83b120dea9f306de06f7dead55103ab2d46 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:15:51 +1000 Subject: [PATCH 0096/1940] [PATCH] Merge arch/ppc*/oprofile/Makefile into arch/powerpc/oprofile Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/oprofile/Makefile | 11 +++++++++++ arch/ppc/oprofile/Makefile | 15 +-------------- arch/ppc64/oprofile/Makefile | 10 +--------- 3 files changed, 13 insertions(+), 23 deletions(-) create mode 100644 arch/powerpc/oprofile/Makefile diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile new file mode 100644 index 000000000000..0782d0cca89c --- /dev/null +++ b/arch/powerpc/oprofile/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) common.o +oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o +oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o diff --git a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile index e2218d32a4eb..4bf75b776c5b 100644 --- a/arch/ppc/oprofile/Makefile +++ b/arch/ppc/oprofile/Makefile @@ -1,14 +1 @@ -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o - -ifeq ($(CONFIG_FSL_BOOKE),y) - oprofile-y += op_model_fsl_booke.o -endif - +include arch/powerpc/oprofile/Makefile diff --git a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile index 162dbf06c142..4bf75b776c5b 100644 --- a/arch/ppc64/oprofile/Makefile +++ b/arch/ppc64/oprofile/Makefile @@ -1,9 +1 @@ -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o op_model_rs64.o op_model_power4.o +include arch/powerpc/oprofile/Makefile From a3e48c10cca3287a845435dd8ca58ecbde72d847 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:18:31 +1000 Subject: [PATCH 0097/1940] [PATCH] powerpc: rename op_ppc{32,64}_model to op_powerpc_model Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc/oprofile/common.c | 2 +- arch/ppc/oprofile/op_impl.h | 2 +- arch/ppc/oprofile/op_model_fsl_booke.c | 2 +- arch/ppc64/oprofile/common.c | 2 +- arch/ppc64/oprofile/op_model_power4.c | 2 +- arch/ppc64/oprofile/op_model_rs64.c | 2 +- include/asm-ppc/perfmon.h | 2 +- include/asm-ppc64/cputable.h | 4 ++-- include/asm-ppc64/oprofile_impl.h | 6 +++--- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c index 3169c67abea7..a67d438a7144 100644 --- a/arch/ppc/oprofile/common.c +++ b/arch/ppc/oprofile/common.c @@ -25,7 +25,7 @@ #include "op_impl.h" -static struct op_ppc32_model *model; +static struct op_powerpc_model *model; static struct op_counter_config ctr[OP_MAX_COUNTER]; static struct op_system_config sys; diff --git a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h index bc336dc971e3..297f3097d2d9 100644 --- a/arch/ppc/oprofile/op_impl.h +++ b/arch/ppc/oprofile/op_impl.h @@ -31,7 +31,7 @@ struct op_system_config { }; /* Per-arch configuration */ -struct op_ppc32_model { +struct op_powerpc_model { void (*reg_setup) (struct op_counter_config *, struct op_system_config *, int num_counters); diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/ppc/oprofile/op_model_fsl_booke.c index fc9c859358c6..8fc60f6055ab 100644 --- a/arch/ppc/oprofile/op_model_fsl_booke.c +++ b/arch/ppc/oprofile/op_model_fsl_booke.c @@ -176,7 +176,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, pmc_start_ctrs(1); } -struct op_ppc32_model op_model_fsl_booke = { +struct op_powerpc_model op_model_fsl_booke = { .reg_setup = fsl_booke_reg_setup, .start = fsl_booke_start, .stop = fsl_booke_stop, diff --git a/arch/ppc64/oprofile/common.c b/arch/ppc64/oprofile/common.c index e5f572710aa0..ff9361a07d39 100644 --- a/arch/ppc64/oprofile/common.c +++ b/arch/ppc64/oprofile/common.c @@ -19,7 +19,7 @@ #include #include -static struct op_ppc64_model *model; +static struct op_powerpc_model *model; static struct op_counter_config ctr[OP_MAX_COUNTER]; static struct op_system_config sys; diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/ppc64/oprofile/op_model_power4.c index 32b2bb5625fe..886449315847 100644 --- a/arch/ppc64/oprofile/op_model_power4.c +++ b/arch/ppc64/oprofile/op_model_power4.c @@ -300,7 +300,7 @@ static void power4_handle_interrupt(struct pt_regs *regs, mtspr(SPRN_MMCR0, mmcr0); } -struct op_ppc64_model op_model_power4 = { +struct op_powerpc_model op_model_power4 = { .reg_setup = power4_reg_setup, .cpu_setup = power4_cpu_setup, .start = power4_start, diff --git a/arch/ppc64/oprofile/op_model_rs64.c b/arch/ppc64/oprofile/op_model_rs64.c index 08c5b333f5c4..e010b85996e8 100644 --- a/arch/ppc64/oprofile/op_model_rs64.c +++ b/arch/ppc64/oprofile/op_model_rs64.c @@ -209,7 +209,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs, mtspr(SPRN_MMCR0, mmcr0); } -struct op_ppc64_model op_model_rs64 = { +struct op_powerpc_model op_model_rs64 = { .reg_setup = rs64_reg_setup, .cpu_setup = rs64_cpu_setup, .start = rs64_start, diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h index 5e7a89c47b5b..e9692a603cff 100644 --- a/include/asm-ppc/perfmon.h +++ b/include/asm-ppc/perfmon.h @@ -16,7 +16,7 @@ void pmc_start_ctrs(int enable); void pmc_stop_ctrs(void); void dump_pmcs(void); -extern struct op_ppc32_model op_model_fsl_booke; +extern struct op_powerpc_model op_model_fsl_booke; #endif #endif /* __PERFMON_H */ diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h index 35121408ed1c..3eef40efd082 100644 --- a/include/asm-ppc64/cputable.h +++ b/include/asm-ppc64/cputable.h @@ -36,7 +36,7 @@ * via the mkdefs mechanism. */ struct cpu_spec; -struct op_ppc64_model; +struct op_powerpc_model; typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); @@ -65,7 +65,7 @@ struct cpu_spec { char *oprofile_cpu_type; /* Processor specific oprofile operations */ - struct op_ppc64_model *oprofile_model; + struct op_powerpc_model *oprofile_model; }; extern struct cpu_spec cpu_specs[]; diff --git a/include/asm-ppc64/oprofile_impl.h b/include/asm-ppc64/oprofile_impl.h index b04f1dfb1421..50420e715f05 100644 --- a/include/asm-ppc64/oprofile_impl.h +++ b/include/asm-ppc64/oprofile_impl.h @@ -37,7 +37,7 @@ struct op_system_config { }; /* Per-arch configuration */ -struct op_ppc64_model { +struct op_powerpc_model { void (*reg_setup) (struct op_counter_config *, struct op_system_config *, int num_counters); @@ -49,8 +49,8 @@ struct op_ppc64_model { int num_counters; }; -extern struct op_ppc64_model op_model_rs64; -extern struct op_ppc64_model op_model_power4; +extern struct op_powerpc_model op_model_rs64; +extern struct op_powerpc_model op_model_power4; static inline unsigned int ctr_read(unsigned int i) { From 654810ec899ea5f2fc2138fca1793b603d481ff4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:21:15 +1000 Subject: [PATCH 0098/1940] [PATCH] powerpc: merge oprofile headers Merge include/asm-ppc64/oprofile_ipml.h and arch/ppc/oprofile/op_impl.h into include/asm-powerpc/oprofile_ipml.h Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc/oprofile/common.c | 3 +- arch/ppc/oprofile/op_impl.h | 45 ------------------- arch/ppc/oprofile/op_model_fsl_booke.c | 3 +- .../oprofile_impl.h | 18 ++++++-- 4 files changed, 17 insertions(+), 52 deletions(-) delete mode 100644 arch/ppc/oprofile/op_impl.h rename include/{asm-ppc64 => asm-powerpc}/oprofile_impl.h (88%) diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c index a67d438a7144..f63bee23f20c 100644 --- a/arch/ppc/oprofile/common.c +++ b/arch/ppc/oprofile/common.c @@ -22,8 +22,7 @@ #include #include #include - -#include "op_impl.h" +#include static struct op_powerpc_model *model; diff --git a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h deleted file mode 100644 index 297f3097d2d9..000000000000 --- a/arch/ppc/oprofile/op_impl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2004 Anton Blanchard , IBM - * - * Based on alpha version. - * - * 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. - */ - -#ifndef OP_IMPL_H -#define OP_IMPL_H 1 - -#define OP_MAX_COUNTER 8 - -/* Per-counter configuration as set via oprofilefs. */ -struct op_counter_config { - unsigned long enabled; - unsigned long event; - unsigned long count; - unsigned long kernel; - unsigned long user; - unsigned long unit_mask; -}; - -/* System-wide configuration as set via oprofilefs. */ -struct op_system_config { - unsigned long enable_kernel; - unsigned long enable_user; -}; - -/* Per-arch configuration */ -struct op_powerpc_model { - void (*reg_setup) (struct op_counter_config *, - struct op_system_config *, - int num_counters); - void (*start) (struct op_counter_config *); - void (*stop) (void); - void (*handle_interrupt) (struct pt_regs *, - struct op_counter_config *); - int num_counters; -}; - -#endif /* OP_IMPL_H */ diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/ppc/oprofile/op_model_fsl_booke.c index 8fc60f6055ab..1917f8df8a8b 100644 --- a/arch/ppc/oprofile/op_model_fsl_booke.c +++ b/arch/ppc/oprofile/op_model_fsl_booke.c @@ -25,8 +25,7 @@ #include #include #include - -#include "op_impl.h" +#include static unsigned long reset_value[OP_MAX_COUNTER]; diff --git a/include/asm-ppc64/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h similarity index 88% rename from include/asm-ppc64/oprofile_impl.h rename to include/asm-powerpc/oprofile_impl.h index 50420e715f05..8013cd273ced 100644 --- a/include/asm-ppc64/oprofile_impl.h +++ b/include/asm-powerpc/oprofile_impl.h @@ -9,31 +9,39 @@ * 2 of the License, or (at your option) any later version. */ -#ifndef OP_IMPL_H -#define OP_IMPL_H 1 +#ifndef _ASM_POWERPC_OPROFILE_IMPL_H +#define _ASM_POWERPC_OPROFILE_IMPL_H #define OP_MAX_COUNTER 8 /* Per-counter configuration as set via oprofilefs. */ struct op_counter_config { +#ifdef __powerpc64__ unsigned long valid; +#endif unsigned long enabled; unsigned long event; unsigned long count; unsigned long kernel; +#ifdef __powerpc64__ /* We dont support per counter user/kernel selection */ +#endif unsigned long user; unsigned long unit_mask; }; /* System-wide configuration as set via oprofilefs. */ struct op_system_config { +#ifdef __powerpc64__ unsigned long mmcr0; unsigned long mmcr1; unsigned long mmcra; +#endif unsigned long enable_kernel; unsigned long enable_user; +#ifdef __powerpc64__ unsigned long backtrace_spinlocks; +#endif }; /* Per-arch configuration */ @@ -41,7 +49,9 @@ struct op_powerpc_model { void (*reg_setup) (struct op_counter_config *, struct op_system_config *, int num_counters); +#ifdef __powerpc64__ void (*cpu_setup) (void *); +#endif void (*start) (struct op_counter_config *); void (*stop) (void); void (*handle_interrupt) (struct pt_regs *, @@ -49,6 +59,7 @@ struct op_powerpc_model { int num_counters; }; +#ifdef __powerpc64__ extern struct op_powerpc_model op_model_rs64; extern struct op_powerpc_model op_model_power4; @@ -107,5 +118,6 @@ static inline void ctr_write(unsigned int i, unsigned int val) break; } } +#endif /* __powerpc64__ */ -#endif +#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */ From 86a5cddbd9676b129cfa2ed7a1a11759d3b2b512 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:24:08 +1000 Subject: [PATCH 0099/1940] [PATCH] powerpc: merge the rest of arch/ppc*/oprofile - merge common.c - move model specific files - remove stub Makefiles - clean up arch/ppc*/Makefile Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/{ppc64 => powerpc}/oprofile/common.c | 101 +++++++++-- .../oprofile/op_model_fsl_booke.c | 0 .../oprofile/op_model_power4.c | 0 .../oprofile/op_model_rs64.c | 0 arch/ppc/Makefile | 2 +- arch/ppc/oprofile/Makefile | 1 - arch/ppc/oprofile/common.c | 160 ------------------ arch/ppc64/Makefile | 2 +- arch/ppc64/oprofile/Makefile | 1 - 9 files changed, 87 insertions(+), 180 deletions(-) rename arch/{ppc64 => powerpc}/oprofile/common.c (56%) rename arch/{ppc => powerpc}/oprofile/op_model_fsl_booke.c (100%) rename arch/{ppc64 => powerpc}/oprofile/op_model_power4.c (100%) rename arch/{ppc64 => powerpc}/oprofile/op_model_rs64.c (100%) delete mode 100644 arch/ppc/oprofile/Makefile delete mode 100644 arch/ppc/oprofile/common.c delete mode 100644 arch/ppc64/oprofile/Makefile diff --git a/arch/ppc64/oprofile/common.c b/arch/powerpc/oprofile/common.c similarity index 56% rename from arch/ppc64/oprofile/common.c rename to arch/powerpc/oprofile/common.c index ff9361a07d39..486314a0defd 100644 --- a/arch/ppc64/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -1,5 +1,9 @@ /* + * PPC 64 oprofile support: * Copyright (C) 2004 Anton Blanchard , IBM + * PPC 32 oprofile support: (based on PPC 64 support) + * Copyright (C) Freescale Semiconductor, Inc 2004 + * Author: Andy Fleming * * Based on alpha version. * @@ -10,12 +14,19 @@ */ #include +#ifndef __powerpc64__ +#include +#endif /* ! __powerpc64__ */ #include #include #include #include #include +#ifdef __powerpc64__ #include +#else /* __powerpc64__ */ +#include +#endif /* __powerpc64__ */ #include #include @@ -24,59 +35,84 @@ static struct op_powerpc_model *model; static struct op_counter_config ctr[OP_MAX_COUNTER]; static struct op_system_config sys; +#ifndef __powerpc64__ +static char *cpu_type; +#endif /* ! __powerpc64__ */ + static void op_handle_interrupt(struct pt_regs *regs) { model->handle_interrupt(regs, ctr); } -static int op_ppc64_setup(void) +static int op_powerpc_setup(void) { +#ifdef __powerpc64__ int err; /* Grab the hardware */ err = reserve_pmc_hardware(op_handle_interrupt); if (err) return err; +#else /* __powerpc64__ */ + /* Install our interrupt handler into the existing hook. */ + if (request_perfmon_irq(&op_handle_interrupt)) + return -EBUSY; + mb(); +#endif /* __powerpc64__ */ /* Pre-compute the values to stuff in the hardware registers. */ model->reg_setup(ctr, &sys, model->num_counters); /* Configure the registers on all cpus. */ +#ifdef __powerpc64__ on_each_cpu(model->cpu_setup, NULL, 0, 1); +#else /* __powerpc64__ */ +#if 0 + /* FIXME: Make multi-cpu work */ + on_each_cpu(model->reg_setup, NULL, 0, 1); +#endif +#endif /* __powerpc64__ */ return 0; } -static void op_ppc64_shutdown(void) +static void op_powerpc_shutdown(void) { +#ifdef __powerpc64__ release_pmc_hardware(); +#else /* __powerpc64__ */ + mb(); + /* Remove our interrupt handler. We may be removing this module. */ + free_perfmon_irq(); +#endif /* __powerpc64__ */ } -static void op_ppc64_cpu_start(void *dummy) +static void op_powerpc_cpu_start(void *dummy) { model->start(ctr); } -static int op_ppc64_start(void) +static int op_powerpc_start(void) { - on_each_cpu(op_ppc64_cpu_start, NULL, 0, 1); + on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); return 0; } -static inline void op_ppc64_cpu_stop(void *dummy) +static inline void op_powerpc_cpu_stop(void *dummy) { model->stop(); } -static void op_ppc64_stop(void) +static void op_powerpc_stop(void) { - on_each_cpu(op_ppc64_cpu_stop, NULL, 0, 1); + on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1); } -static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) +static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) { int i; +#ifdef __powerpc64__ /* * There is one mmcr0, mmcr1 and mmcra for setting the events for * all of the counters. @@ -84,6 +120,7 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); +#endif /* __powerpc64__ */ for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; @@ -95,44 +132,72 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); +#ifdef __powerpc64__ /* * We dont support per counter user/kernel selection, but * we leave the entries because userspace expects them */ +#endif /* __powerpc64__ */ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); + +#ifndef __powerpc64__ + /* FIXME: Not sure if this is used */ +#endif /* ! __powerpc64__ */ oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); } oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); +#ifdef __powerpc64__ oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", &sys.backtrace_spinlocks); +#endif /* __powerpc64__ */ /* Default to tracing both kernel and user */ sys.enable_kernel = 1; sys.enable_user = 1; - +#ifdef __powerpc64__ /* Turn on backtracing through spinlocks by default */ sys.backtrace_spinlocks = 1; +#endif /* __powerpc64__ */ return 0; } int __init oprofile_arch_init(struct oprofile_operations *ops) { +#ifndef __powerpc64__ + int cpu_id = smp_processor_id(); + +#ifdef CONFIG_FSL_BOOKE + model = &op_model_fsl_booke; +#else + return -ENODEV; +#endif + + cpu_type = kmalloc(32, GFP_KERNEL); + if (NULL == cpu_type) + return -ENOMEM; + + sprintf(cpu_type, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name); + + model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs; + + ops->cpu_type = cpu_type; +#else /* __powerpc64__ */ if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type) return -ENODEV; - model = cur_cpu_spec->oprofile_model; model->num_counters = cur_cpu_spec->num_pmcs; ops->cpu_type = cur_cpu_spec->oprofile_cpu_type; - ops->create_files = op_ppc64_create_files; - ops->setup = op_ppc64_setup; - ops->shutdown = op_ppc64_shutdown; - ops->start = op_ppc64_start; - ops->stop = op_ppc64_stop; +#endif /* __powerpc64__ */ + ops->create_files = op_powerpc_create_files; + ops->setup = op_powerpc_setup; + ops->shutdown = op_powerpc_shutdown; + ops->start = op_powerpc_start; + ops->stop = op_powerpc_stop; printk(KERN_INFO "oprofile: using %s performance monitoring.\n", ops->cpu_type); @@ -142,4 +207,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) void oprofile_arch_exit(void) { +#ifndef __powerpc64__ + kfree(cpu_type); + cpu_type = NULL; +#endif /* ! __powerpc64__ */ } diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c similarity index 100% rename from arch/ppc/oprofile/op_model_fsl_booke.c rename to arch/powerpc/oprofile/op_model_fsl_booke.c diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c similarity index 100% rename from arch/ppc64/oprofile/op_model_power4.c rename to arch/powerpc/oprofile/op_model_power4.c diff --git a/arch/ppc64/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c similarity index 100% rename from arch/ppc64/oprofile/op_model_rs64.c rename to arch/powerpc/oprofile/op_model_rs64.c diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 16e2675f3270..90c750227ed9 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -71,7 +71,7 @@ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ -drivers-$(CONFIG_OPROFILE) += arch/ppc/oprofile/ +drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm diff --git a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile deleted file mode 100644 index 4bf75b776c5b..000000000000 --- a/arch/ppc/oprofile/Makefile +++ /dev/null @@ -1 +0,0 @@ -include arch/powerpc/oprofile/Makefile diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c deleted file mode 100644 index f63bee23f20c..000000000000 --- a/arch/ppc/oprofile/common.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * PPC 32 oprofile support - * Based on PPC64 oprofile support - * Copyright (C) 2004 Anton Blanchard , IBM - * - * Copyright (C) Freescale Semiconductor, Inc 2004 - * - * Author: Andy Fleming - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct op_powerpc_model *model; - -static struct op_counter_config ctr[OP_MAX_COUNTER]; -static struct op_system_config sys; - -static void op_handle_interrupt(struct pt_regs *regs) -{ - model->handle_interrupt(regs, ctr); -} - -static int op_ppc32_setup(void) -{ - /* Install our interrupt handler into the existing hook. */ - if(request_perfmon_irq(&op_handle_interrupt)) - return -EBUSY; - - mb(); - - /* Pre-compute the values to stuff in the hardware registers. */ - model->reg_setup(ctr, &sys, model->num_counters); - -#if 0 - /* FIXME: Make multi-cpu work */ - /* Configure the registers on all cpus. */ - on_each_cpu(model->reg_setup, NULL, 0, 1); -#endif - - return 0; -} - -static void op_ppc32_shutdown(void) -{ - mb(); - - /* Remove our interrupt handler. We may be removing this module. */ - free_perfmon_irq(); -} - -static void op_ppc32_cpu_start(void *dummy) -{ - model->start(ctr); -} - -static int op_ppc32_start(void) -{ - on_each_cpu(op_ppc32_cpu_start, NULL, 0, 1); - return 0; -} - -static inline void op_ppc32_cpu_stop(void *dummy) -{ - model->stop(); -} - -static void op_ppc32_stop(void) -{ - on_each_cpu(op_ppc32_cpu_stop, NULL, 0, 1); -} - -static int op_ppc32_create_files(struct super_block *sb, struct dentry *root) -{ - int i; - - for (i = 0; i < model->num_counters; ++i) { - struct dentry *dir; - char buf[3]; - - snprintf(buf, sizeof buf, "%d", i); - dir = oprofilefs_mkdir(sb, root, buf); - - oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); - oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); - oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); - oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); - oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); - - /* FIXME: Not sure if this is used */ - oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); - } - - oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); - oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); - - /* Default to tracing both kernel and user */ - sys.enable_kernel = 1; - sys.enable_user = 1; - - return 0; -} - -static struct oprofile_operations oprof_ppc32_ops = { - .create_files = op_ppc32_create_files, - .setup = op_ppc32_setup, - .shutdown = op_ppc32_shutdown, - .start = op_ppc32_start, - .stop = op_ppc32_stop, - .cpu_type = NULL /* To be filled in below. */ -}; - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - char *name; - int cpu_id = smp_processor_id(); - -#ifdef CONFIG_FSL_BOOKE - model = &op_model_fsl_booke; -#else - return -ENODEV; -#endif - - name = kmalloc(32, GFP_KERNEL); - - if (NULL == name) - return -ENOMEM; - - sprintf(name, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name); - - oprof_ppc32_ops.cpu_type = name; - - model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs; - - *ops = oprof_ppc32_ops; - - printk(KERN_INFO "oprofile: using %s performance monitoring.\n", - oprof_ppc32_ops.cpu_type); - - return 0; -} - -void oprofile_arch_exit(void) -{ - kfree(oprof_ppc32_ops.cpu_type); - oprof_ppc32_ops.cpu_type = NULL; -} diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 17d2c1eac3b8..a8877881bb48 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -85,7 +85,7 @@ libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ core-y += arch/ppc64/mm/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ -drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/ +drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ boot := arch/ppc64/boot diff --git a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile deleted file mode 100644 index 4bf75b776c5b..000000000000 --- a/arch/ppc64/oprofile/Makefile +++ /dev/null @@ -1 +0,0 @@ -include arch/powerpc/oprofile/Makefile From 82cd02c16be99cba6a97d38488aee8807580a202 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 Sep 2005 23:28:21 +1000 Subject: [PATCH 0100/1940] [PATCH] powerpc: reduce oprofile/common.c differences Rename and slightly modify {request,free}_perfmon_irq in the ppc code. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/oprofile/common.c | 13 ------------- arch/ppc/kernel/perfmon.c | 10 +++++----- include/asm-ppc/perfmon.h | 4 ++-- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 486314a0defd..88b4118fd0c5 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -46,19 +46,12 @@ static void op_handle_interrupt(struct pt_regs *regs) static int op_powerpc_setup(void) { -#ifdef __powerpc64__ int err; /* Grab the hardware */ err = reserve_pmc_hardware(op_handle_interrupt); if (err) return err; -#else /* __powerpc64__ */ - /* Install our interrupt handler into the existing hook. */ - if (request_perfmon_irq(&op_handle_interrupt)) - return -EBUSY; - mb(); -#endif /* __powerpc64__ */ /* Pre-compute the values to stuff in the hardware registers. */ model->reg_setup(ctr, &sys, model->num_counters); @@ -78,13 +71,7 @@ static int op_powerpc_setup(void) static void op_powerpc_shutdown(void) { -#ifdef __powerpc64__ release_pmc_hardware(); -#else /* __powerpc64__ */ - mb(); - /* Remove our interrupt handler. We may be removing this module. */ - free_perfmon_irq(); -#endif /* __powerpc64__ */ } static void op_powerpc_cpu_start(void *dummy) diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c index fa1dad96b830..91e2786ea097 100644 --- a/arch/ppc/kernel/perfmon.c +++ b/arch/ppc/kernel/perfmon.c @@ -61,7 +61,7 @@ void (*perf_irq)(struct pt_regs *) = dummy_perf; /* Grab the interrupt, if it's free. * Returns 0 on success, -1 if the interrupt is taken already */ -int request_perfmon_irq(void (*handler)(struct pt_regs *)) +int reserve_pmc_hardware(void (*handler)(struct pt_regs *)) { int err = 0; @@ -71,7 +71,7 @@ int request_perfmon_irq(void (*handler)(struct pt_regs *)) perf_irq = handler; else { pr_info("perfmon irq already handled by %p\n", perf_irq); - err = -1; + err = -EBUSY; } spin_unlock(&perfmon_lock); @@ -79,7 +79,7 @@ int request_perfmon_irq(void (*handler)(struct pt_regs *)) return err; } -void free_perfmon_irq(void) +void release_pmc_hardware(void) { spin_lock(&perfmon_lock); @@ -89,5 +89,5 @@ void free_perfmon_irq(void) } EXPORT_SYMBOL(perf_irq); -EXPORT_SYMBOL(request_perfmon_irq); -EXPORT_SYMBOL(free_perfmon_irq); +EXPORT_SYMBOL(reserve_pmc_hardware); +EXPORT_SYMBOL(release_pmc_hardware); diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h index e9692a603cff..2ae031594a4e 100644 --- a/include/asm-ppc/perfmon.h +++ b/include/asm-ppc/perfmon.h @@ -3,8 +3,8 @@ extern void (*perf_irq)(struct pt_regs *); -int request_perfmon_irq(void (*handler)(struct pt_regs *)); -void free_perfmon_irq(void); +int reserve_pmc_hardware(void (*handler)(struct pt_regs *)); +void release_pmc_hardware(void); #ifdef CONFIG_FSL_BOOKE void init_pmc_stop(int ctr); From c7aeffc4d38f0573b05bf5ebd2f037997ec9d075 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 19 Sep 2005 09:30:27 -0500 Subject: [PATCH 0101/1940] [PATCH] powerpc: unified signature of timer_interrupt() between ppc32/ppc64 On ppc64 timer_interrupt() returned a value that was never used. Changed the ppc64 version of timer_interrupt() to no longer return a value so that the signatures between ppc32 & ppc64 match. This will simplify future merging of arch/powerpc. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/time.c | 4 +--- include/asm-ppc64/hw_irq.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 9939c206afa4..fb4bf0ad8f32 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -319,7 +319,7 @@ unsigned long tb_last_stamp __cacheline_aligned_in_smp; * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. */ -int timer_interrupt(struct pt_regs * regs) +void timer_interrupt(struct pt_regs * regs) { int next_dec; unsigned long cur_tb; @@ -377,8 +377,6 @@ int timer_interrupt(struct pt_regs * regs) } irq_exit(); - - return 1; } /* diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-ppc64/hw_irq.h index baea40e695ec..c483897b8757 100644 --- a/include/asm-ppc64/hw_irq.h +++ b/include/asm-ppc64/hw_irq.h @@ -16,7 +16,7 @@ #include #include -int timer_interrupt(struct pt_regs *); +extern void timer_interrupt(struct pt_regs *); extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); #ifdef CONFIG_PPC_ISERIES From 3e57615bb5a8b6208627049884ee441f6d05905e Mon Sep 17 00:00:00 2001 From: "linuxppc@jdl.com" Date: Mon, 19 Sep 2005 09:32:07 -0500 Subject: [PATCH 0102/1940] [PATCH] powerpc: Revised merge asm-ppc*/hardirq.h This is a revised patch to merge asm-ppc*/hardirq.h. It removes some unnecessary #includes, but then requires the addition of #include in PPC32's hw_irq.h much like ppc64 already does. Furthermore, several unnecessary #includes were removed from some ppc32 boards in order to break resulting bad #include cycles. Builds pSeries_defconfig and all ppc32 platforms except the already b0rken bseip. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/platforms/83xx/mpc834x_sys.h | 1 - arch/ppc/platforms/85xx/mpc85xx_ads_common.h | 1 - arch/ppc/platforms/85xx/stx_gp3.h | 1 - include/{asm-ppc => asm-powerpc}/hardirq.h | 15 +++-------- include/asm-ppc/hw_irq.h | 1 + include/asm-ppc64/hardirq.h | 27 -------------------- 6 files changed, 5 insertions(+), 41 deletions(-) rename include/{asm-ppc => asm-powerpc}/hardirq.h (67%) delete mode 100644 include/asm-ppc64/hardirq.h diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h index 1584cd77a9ef..58e44c042535 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.h +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h index 3875e839cff7..84acf6e8d45e 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h +++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h @@ -19,7 +19,6 @@ #include #include -#include #include #define BOARD_CCSRBAR ((uint)0xe0000000) diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h index 7bcc6c35a417..95fdf4b0680b 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.h +++ b/arch/ppc/platforms/85xx/stx_gp3.h @@ -21,7 +21,6 @@ #include #include -#include #include #define BOARD_CCSRBAR ((uint)0xe0000000) diff --git a/include/asm-ppc/hardirq.h b/include/asm-powerpc/hardirq.h similarity index 67% rename from include/asm-ppc/hardirq.h rename to include/asm-powerpc/hardirq.h index 94f1411b1a93..2c0a31b1008d 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-powerpc/hardirq.h @@ -1,11 +1,5 @@ -#ifdef __KERNEL__ -#ifndef __ASM_HARDIRQ_H -#define __ASM_HARDIRQ_H - -#include -#include -#include -#include +#ifndef _ASM_POWERPC_HARDIRQ_H +#define _ASM_POWERPC_HARDIRQ_H /* The __last_jiffy_stamp field is needed to ensure that no decrementer * interrupt is lost on SMP machines. Since on most CPUs it is in the same @@ -13,7 +7,7 @@ * for uniformity. */ typedef struct { - unsigned long __softirq_pending; /* set_bit is used on this */ + unsigned int __softirq_pending; /* set_bit is used on this */ unsigned int __last_jiffy_stamp; } ____cacheline_aligned irq_cpustat_t; @@ -27,5 +21,4 @@ static inline void ack_bad_irq(int irq) BUG(); } -#endif /* __ASM_HARDIRQ_H */ -#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_HARDIRQ_H */ diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 51a1d7ef5253..da0fa940adb3 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -7,6 +7,7 @@ #include #include +#include extern void timer_interrupt(struct pt_regs *); diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h deleted file mode 100644 index 4ee72bb1fd48..000000000000 --- a/include/asm-ppc64/hardirq.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __ASM_HARDIRQ_H -#define __ASM_HARDIRQ_H - -/* - * 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. - */ - -#include -#include -#include - -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include /* Standard mappings for irq_cpustat_t above */ - -static inline void ack_bad_irq(int irq) -{ - printk(KERN_CRIT "illegal vector %d received!\n", irq); - BUG(); -} - -#endif /* __ASM_HARDIRQ_H */ From 25433b123ce1a3da78ddd9b848484bca91cbb7a1 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Mon, 19 Sep 2005 17:01:54 -0500 Subject: [PATCH 0103/1940] [PATCH] powerpc: Merge bug.h ppc32/ppc64: Merge bug.h into include/asm-powerpc This patch merges bug.h into include/asm-powerpc. Changed the data structure for bug_entry such that line is always an int on both 32 and 64-bit platforms; removed casts to int from the 64-bit trap code to reflect this. Signed-off-by: Kumar Gala Signed-off-by: Becky Bruce Signed-off-by: Paul Mackerras --- arch/ppc/kernel/traps.c | 2 +- arch/ppc64/kernel/traps.c | 4 +- include/{asm-ppc64 => asm-powerpc}/bug.h | 38 ++++++++++------ include/asm-ppc/bug.h | 58 ------------------------ 4 files changed, 28 insertions(+), 74 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/bug.h (62%) delete mode 100644 include/asm-ppc/bug.h diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 961ede87be72..82e4d70e6dbb 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -575,7 +575,7 @@ extern struct bug_entry __start___bug_table[], __stop___bug_table[]; #define module_find_bug(x) NULL #endif -static struct bug_entry *find_bug(unsigned long bugaddr) +struct bug_entry *find_bug(unsigned long bugaddr) { struct bug_entry *bug; diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index 7467ae508e6e..5c4647b2c5f3 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c @@ -390,12 +390,12 @@ check_bug_trap(struct pt_regs *regs) /* this is a WARN_ON rather than BUG/BUG_ON */ printk(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, - (unsigned int)bug->line & ~BUG_WARNING_TRAP); + bug->line & ~BUG_WARNING_TRAP); show_stack(current, (void *)regs->gpr[1]); return 1; } printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", - bug->function, bug->file, (unsigned int)bug->line); + bug->function, bug->file, bug->line); return 0; } diff --git a/include/asm-ppc64/bug.h b/include/asm-powerpc/bug.h similarity index 62% rename from include/asm-ppc64/bug.h rename to include/asm-powerpc/bug.h index 160178278861..e4d028e87020 100644 --- a/include/asm-ppc64/bug.h +++ b/include/asm-powerpc/bug.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_BUG_H -#define _PPC64_BUG_H +#ifndef _ASM_POWERPC_BUG_H +#define _ASM_POWERPC_BUG_H /* * Define an illegal instr to trap on the bug. @@ -11,9 +11,21 @@ #ifndef __ASSEMBLY__ +#ifdef __powerpc64__ +#define BUG_TABLE_ENTRY(label, line, file, func) \ + ".llong " #label "\n .long " #line "\n .llong " #file ", " #func "\n" +#define TRAP_OP(ra, rb) "1: tdnei " #ra ", " #rb "\n" +#define DATA_TYPE long long +#else +#define BUG_TABLE_ENTRY(label, line, file, func) \ + ".long " #label ", " #line ", " #file ", " #func "\n" +#define TRAP_OP(ra, rb) "1: twnei " #ra ", " #rb "\n" +#define DATA_TYPE int +#endif /* __powerpc64__ */ + struct bug_entry { unsigned long bug_addr; - long line; + int line; const char *file; const char *function; }; @@ -32,28 +44,28 @@ struct bug_entry *find_bug(unsigned long bugaddr); __asm__ __volatile__( \ "1: twi 31,0,0\n" \ ".section __bug_table,\"a\"\n\t" \ - " .llong 1b,%0,%1,%2\n" \ + BUG_TABLE_ENTRY(1b,%0,%1,%2) \ ".previous" \ : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define BUG_ON(x) do { \ __asm__ __volatile__( \ - "1: tdnei %0,0\n" \ + TRAP_OP(%0,0) \ ".section __bug_table,\"a\"\n\t" \ - " .llong 1b,%1,%2,%3\n" \ + BUG_TABLE_ENTRY(1b,%1,%2,%3) \ ".previous" \ - : : "r" ((long long)(x)), "i" (__LINE__), \ + : : "r" ((DATA_TYPE)(x)), "i" (__LINE__), \ "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define WARN_ON(x) do { \ __asm__ __volatile__( \ - "1: tdnei %0,0\n" \ + TRAP_OP(%0,0) \ ".section __bug_table,\"a\"\n\t" \ - " .llong 1b,%1,%2,%3\n" \ + BUG_TABLE_ENTRY(1b,%1,%2,%3) \ ".previous" \ - : : "r" ((long long)(x)), \ + : : "r" ((DATA_TYPE)(x)), \ "i" (__LINE__ + BUG_WARNING_TRAP), \ "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) @@ -61,9 +73,9 @@ struct bug_entry *find_bug(unsigned long bugaddr); #define HAVE_ARCH_BUG #define HAVE_ARCH_BUG_ON #define HAVE_ARCH_WARN_ON -#endif -#endif +#endif /* CONFIG_BUG */ +#endif /* __ASSEMBLY __ */ #include -#endif +#endif /* _ASM_POWERPC_BUG_H */ diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h deleted file mode 100644 index 8b34fd682b0d..000000000000 --- a/include/asm-ppc/bug.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _PPC_BUG_H -#define _PPC_BUG_H - -struct bug_entry { - unsigned long bug_addr; - int line; - const char *file; - const char *function; -}; - -/* - * If this bit is set in the line number it means that the trap - * is for WARN_ON rather than BUG or BUG_ON. - */ -#define BUG_WARNING_TRAP 0x1000000 - -#ifdef CONFIG_BUG -#define BUG() do { \ - __asm__ __volatile__( \ - "1: twi 31,0,0\n" \ - ".section __bug_table,\"a\"\n\t" \ - " .long 1b,%0,%1,%2\n" \ - ".previous" \ - : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ -} while (0) - -#define BUG_ON(x) do { \ - if (!__builtin_constant_p(x) || (x)) { \ - __asm__ __volatile__( \ - "1: twnei %0,0\n" \ - ".section __bug_table,\"a\"\n\t" \ - " .long 1b,%1,%2,%3\n" \ - ".previous" \ - : : "r" (x), "i" (__LINE__), "i" (__FILE__), \ - "i" (__FUNCTION__)); \ - } \ -} while (0) - -#define WARN_ON(x) do { \ - if (!__builtin_constant_p(x) || (x)) { \ - __asm__ __volatile__( \ - "1: twnei %0,0\n" \ - ".section __bug_table,\"a\"\n\t" \ - " .long 1b,%1,%2,%3\n" \ - ".previous" \ - : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \ - "i" (__FILE__), "i" (__FUNCTION__)); \ - } \ -} while (0) - -#define HAVE_ARCH_BUG -#define HAVE_ARCH_BUG_ON -#define HAVE_ARCH_WARN_ON -#endif - -#include - -#endif From a99eb2ef452ce685e40a433ceb187276ba0871f4 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Mon, 19 Sep 2005 19:17:27 -0500 Subject: [PATCH 0104/1940] [PATCH] powerpc: Merge elf.h ppc/ppc64: Merge elf.h into include/asm-powerpc Merge elf.h into a single include file for 32 and 64-bit ppc platforms. This patch has been tested on 32-bit and built on 64-bit platforms. Signed-off-by: Kumar Gala Signed-off-by: Becky Bruce Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/elf.h | 97 +++++++++------ include/asm-ppc/elf.h | 151 ----------------------- 2 files changed, 62 insertions(+), 186 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/elf.h (87%) delete mode 100644 include/asm-ppc/elf.h diff --git a/include/asm-ppc64/elf.h b/include/asm-powerpc/elf.h similarity index 87% rename from include/asm-ppc64/elf.h rename to include/asm-powerpc/elf.h index e27c2942953c..36b9d5cec50c 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-powerpc/elf.h @@ -1,5 +1,5 @@ -#ifndef __PPC64_ELF_H -#define __PPC64_ELF_H +#ifndef _ASM_POWERPC_ELF_H +#define _ASM_POWERPC_ELF_H #include #include @@ -76,7 +76,7 @@ #define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ #define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -/* Keep this the last entry. */ +/* keep this the last entry. */ #define R_PPC_NUM 95 /* @@ -91,8 +91,6 @@ #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ #define ELF_NFPREG 33 /* includes fpscr */ -#define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */ -#define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */ typedef unsigned long elf_greg_t64; typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; @@ -101,8 +99,21 @@ typedef unsigned int elf_greg_t32; typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG]; /* - * These are used to set parameters in the core dumps. + * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps. */ +#ifdef __powerpc64__ +# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */ +# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */ +# define ELF_GREG_TYPE elf_greg_t64 +#else +# define ELF_NEVRREG 34 /* includes acc (as 2) */ +# define ELF_NVRREG 33 /* includes vscr */ +# define ELF_GREG_TYPE elf_greg_t32 +# define ELF_ARCH EM_PPC +# define ELF_CLASS ELFCLASS32 +# define ELF_DATA ELFDATA2MSB +#endif /* __powerpc64__ */ + #ifndef ELF_ARCH # define ELF_ARCH EM_PPC64 # define ELF_CLASS ELFCLASS64 @@ -115,8 +126,9 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG]; typedef elf_greg_t32 elf_greg_t; typedef elf_gregset_t32 elf_gregset_t; # define elf_addr_t u32 -#endif +#endif /* ELF_ARCH */ +/* Floating point registers */ typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; @@ -126,7 +138,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; * The entry with index 32 contains the vscr as the last word (offset 12) * within the quadword. This allows the vscr to be stored as either a * quadword (since it must be copied via a vector register to/from storage) - * or as a word. The entry with index 33 contains the vrsave as the first + * or as a word. + * + * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first * word (offset 0) within the quadword. * * This definition of the VMX state is compatible with the current PPC32 @@ -139,7 +153,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; */ typedef __vector128 elf_vrreg_t; typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; +#ifdef __powerpc64__ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; +#endif /* * This is used to ensure we don't load something for the wrong architecture. @@ -159,26 +175,30 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; #ifdef __KERNEL__ /* Common routine for both 32-bit and 64-bit processes */ -static inline void ppc64_elf_core_copy_regs(elf_gregset_t elf_regs, +static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs, struct pt_regs *regs) { int i; - int gprs = sizeof(struct pt_regs)/sizeof(elf_greg_t64); + int gprs = sizeof(struct pt_regs)/sizeof(ELF_GREG_TYPE); if (gprs > ELF_NGREG) gprs = ELF_NGREG; for (i=0; i < gprs; i++) - elf_regs[i] = (elf_greg_t)((elf_greg_t64 *)regs)[i]; + elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i]; + + memset((char *)(elf_regs) + sizeof(struct pt_regs), 0, \ + sizeof(elf_gregset_t) - sizeof(struct pt_regs)); + } -#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs); +#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs); static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *elf_regs) { struct pt_regs *regs = tsk->thread.regs; if (regs) - ppc64_elf_core_copy_regs(*elf_regs, regs); + ppc_elf_core_copy_regs(*elf_regs, regs); return 1; } @@ -187,15 +207,21 @@ static inline int dump_task_regs(struct task_struct *tsk, extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) -/* XXX Should we define the XFPREGS using altivec ??? */ +#endif /* __KERNEL__ */ -#endif - -/* This yields a mask that user programs can use to figure out what +/* ELF_HWCAP yields a mask that user programs can use to figure out what instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ - -#define ELF_HWCAP (cur_cpu_spec->cpu_user_features) +#ifdef __powerpc64__ +# define ELF_HWCAP (cur_cpu_spec->cpu_user_features) +# define ELF_PLAT_INIT(_r, load_addr) do { \ + memset(_r->gpr, 0, sizeof(_r->gpr)); \ + _r->ctr = _r->link = _r->xer = _r->ccr = 0; \ + _r->gpr[2] = load_addr; \ +} while (0) +#else +# define ELF_HWCAP (cur_cpu_spec[0]->cpu_user_features) +#endif /* __powerpc64__ */ /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in @@ -206,14 +232,10 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); #define ELF_PLATFORM (NULL) -#define ELF_PLAT_INIT(_r, load_addr) do { \ - memset(_r->gpr, 0, sizeof(_r->gpr)); \ - _r->ctr = _r->link = _r->xer = _r->ccr = 0; \ - _r->gpr[2] = load_addr; \ -} while (0) - #ifdef __KERNEL__ -#define SET_PERSONALITY(ex, ibcs2) \ + +#ifdef __powerpc64__ +# define SET_PERSONALITY(ex, ibcs2) \ do { \ unsigned long new_flags = 0; \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ @@ -226,7 +248,6 @@ do { \ if (personality(current->personality) != PER_LINUX32) \ set_personality(PER_LINUX); \ } while (0) - /* * An executable for which elf_read_implies_exec() returns TRUE will * have the READ_IMPLIES_EXEC personality flag set automatically. This @@ -234,19 +255,26 @@ do { \ * the 64bit ABI has never had these issues dont enable the workaround * even if we have an executable stack. */ -#define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ +# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ (exec_stk != EXSTACK_DISABLE_X) : 0) +#else +# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#endif /* __powerpc64__ */ -#endif +#endif /* __KERNEL__ */ extern int dcache_bsize; extern int icache_bsize; extern int ucache_bsize; -/* We do have an arch_setup_additional_pages for vDSO matters */ -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES +#ifdef __powerpc64__ struct linux_binprm; +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES /* vDSO has arch_setup_additional_pages */ extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); +#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b); +#else +#define VDSO_AUX_ENT(a,b) +#endif /* __powerpc64__ */ /* * The requirements here are: @@ -266,9 +294,8 @@ do { \ NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \ NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \ NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \ - /* vDSO base */ \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base); \ - } while (0) + VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base) \ +} while (0) /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE @@ -385,4 +412,4 @@ do { \ /* Keep this the last entry. */ #define R_PPC64_NUM 107 -#endif /* __PPC64_ELF_H */ +#endif /* _ASM_POWERPC_ELF_H */ diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h deleted file mode 100644 index c25cc35e6ab5..000000000000 --- a/include/asm-ppc/elf.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __PPC_ELF_H -#define __PPC_ELF_H - -/* - * ELF register definitions.. - */ -#include -#include -#include -#include - -/* PowerPC relocations defined by the ABIs */ -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 /* 32bit absolute address */ -#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define R_PPC_ADDR16 3 /* 16bit absolute address */ -#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 /* PC relative 26 bit */ -#define R_PPC_REL14 11 /* PC relative 16 bit */ -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 -/* Keep this the last entry. */ -#define R_PPC_NUM 37 - -#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ -#define ELF_NFPREG 33 /* includes fpscr */ -#define ELF_NVRREG 33 /* includes vscr */ -#define ELF_NEVRREG 34 /* includes acc (as 2) */ - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_ARCH EM_PPC -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2MSB - -/* General registers */ -typedef unsigned long elf_greg_t; -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -/* Floating point registers */ -typedef double elf_fpreg_t; -typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; - -/* Altivec registers */ -typedef __vector128 elf_vrreg_t; -typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; - -#ifdef __KERNEL__ - -struct task_struct; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ - -#define elf_check_arch(x) ((x)->e_machine == EM_PPC) - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (0x08000000) - -#define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_CORE_COPY_REGS(gregs, regs) \ - memcpy((gregs), (regs), sizeof(struct pt_regs)); \ - memset((char *)(gregs) + sizeof(struct pt_regs), 0, \ - sizeof(elf_gregset_t) - sizeof(struct pt_regs)); - -#define ELF_CORE_COPY_TASK_REGS(t, elfregs) \ - ((t)->thread.regs? \ - ({ ELF_CORE_COPY_REGS((elfregs), (t)->thread.regs); 1; }): 0) - -extern int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpu); -#define ELF_CORE_COPY_FPREGS(t, fpu) dump_task_fpu((t), (fpu)) - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. This could be done in userspace, - but it's not easy, and we've already done it here. */ - -#define ELF_HWCAP (cur_cpu_spec[0]->cpu_user_features) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. - - For the moment, we have only optimizations for the Intel generations, - but that could change... */ - -#define ELF_PLATFORM (NULL) - -#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) - -extern int dcache_bsize; -extern int icache_bsize; -extern int ucache_bsize; - -/* - * The requirements here are: - * - keep the final alignment of sp (sp & 0xf) - * - make sure the 32-bit value at the first 16 byte aligned position of - * AUXV is greater than 16 for glibc compatibility. - * AT_IGNOREPPC is used for that. - * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, - * even if DLINFO_ARCH_ITEMS goes to zero or is undefined. - */ -#define ARCH_DLINFO \ -do { \ - /* Handle glibc compatibility. */ \ - NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ - NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ - /* Cache size items */ \ - NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \ - NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \ - NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \ - } while (0) - -#endif /* __KERNEL__ */ -#endif From 8b22cc010599075806b84cfe2955ab87ab07172c Mon Sep 17 00:00:00 2001 From: "linuxppc@jdl.com" Date: Tue, 20 Sep 2005 14:32:37 -0500 Subject: [PATCH 0105/1940] [PATCH] powerpc: Merge asm-ppc*/vga.h Merge asm-ppc*/vga.h Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/vga.h | 20 ++++++----- include/asm-ppc/vga.h | 46 ------------------------ 2 files changed, 12 insertions(+), 54 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/vga.h (74%) delete mode 100644 include/asm-ppc/vga.h diff --git a/include/asm-ppc64/vga.h b/include/asm-powerpc/vga.h similarity index 74% rename from include/asm-ppc64/vga.h rename to include/asm-powerpc/vga.h index c09849743f45..f8d350aabf1a 100644 --- a/include/asm-ppc64/vga.h +++ b/include/asm-powerpc/vga.h @@ -1,16 +1,14 @@ +#ifndef _ASM_POWERPC_VGA_H_ +#define _ASM_POWERPC_VGA_H_ + +#ifdef __KERNEL__ + /* * Access to VGA videoram * * (c) 1998 Martin Mares - * - * 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. */ -#ifndef _LINUX_ASM_VGA_H_ -#define _LINUX_ASM_VGA_H_ #include @@ -42,9 +40,15 @@ static inline u16 scr_readw(volatile const u16 *addr) #endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ extern unsigned long vgacon_remap_base; + +#ifdef __powerpc64__ #define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0)) +#else +#define VGA_MAP_MEM(x) (x + vgacon_remap_base) +#endif #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) -#endif +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_VGA_H_ */ diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h deleted file mode 100644 index c5864734e3e1..000000000000 --- a/include/asm-ppc/vga.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Access to VGA videoram - * - * (c) 1998 Martin Mares - */ - -#ifdef __KERNEL__ -#ifndef _LINUX_ASM_VGA_H_ -#define _LINUX_ASM_VGA_H_ - -#include - -#include - -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) - -#define VT_BUF_HAVE_RW -/* - * These are only needed for supporting VGA or MDA text mode, which use little - * endian byte ordering. - * In other cases, we can optimize by using native byte ordering and - * has already done the right job for us. - */ - -extern inline void scr_writew(u16 val, volatile u16 *addr) -{ - st_le16(addr, val); -} - -extern inline u16 scr_readw(volatile const u16 *addr) -{ - return ld_le16(addr); -} - -#define VT_BUF_HAVE_MEMCPYW -#define scr_memcpyw memcpy - -#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ - -extern unsigned long vgacon_remap_base; -#define VGA_MAP_MEM(x) (x + vgacon_remap_base) -#define vga_readb(x) (*(x)) -#define vga_writeb(x,y) (*(y) = (x)) - -#endif -#endif /* __KERNEL__ */ From 3f58542f476f9a77d5c59b62165e67290d7f55ed Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 20 Sep 2005 15:45:26 -0500 Subject: [PATCH 0106/1940] [PATCH] powerpc: merge include/asm-ppc*/auxvec.h into include/asm-powerpc/auxvec.h Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/auxvec.h | 6 +++--- include/asm-ppc/auxvec.h | 14 -------------- 2 files changed, 3 insertions(+), 17 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/auxvec.h (84%) delete mode 100644 include/asm-ppc/auxvec.h diff --git a/include/asm-ppc64/auxvec.h b/include/asm-powerpc/auxvec.h similarity index 84% rename from include/asm-ppc64/auxvec.h rename to include/asm-powerpc/auxvec.h index ac6381a106e1..19a099b62cd6 100644 --- a/include/asm-ppc64/auxvec.h +++ b/include/asm-powerpc/auxvec.h @@ -1,5 +1,5 @@ -#ifndef __PPC64_AUXVEC_H -#define __PPC64_AUXVEC_H +#ifndef _ASM_POWERPC_AUXVEC_H +#define _ASM_POWERPC_AUXVEC_H /* * We need to put in some extra aux table entries to tell glibc what @@ -16,4 +16,4 @@ */ #define AT_SYSINFO_EHDR 33 -#endif /* __PPC64_AUXVEC_H */ +#endif diff --git a/include/asm-ppc/auxvec.h b/include/asm-ppc/auxvec.h deleted file mode 100644 index 172358df29c8..000000000000 --- a/include/asm-ppc/auxvec.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __PPC_AUXVEC_H -#define __PPC_AUXVEC_H - -/* - * We need to put in some extra aux table entries to tell glibc what - * the cache block size is, so it can use the dcbz instruction safely. - */ -#define AT_DCACHEBSIZE 19 -#define AT_ICACHEBSIZE 20 -#define AT_UCACHEBSIZE 21 -/* A special ignored type value for PPC, for glibc compatibility. */ -#define AT_IGNOREPPC 22 - -#endif From 8a4a10ae996b67c622b9f3f6a4dfea5de4500a11 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 20 Sep 2005 16:33:54 -0500 Subject: [PATCH 0107/1940] [PATCH] powerpc: merge include/asm-ppc*/spinlock_types.h into include/asm-powerpc/spinlock_types.h Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- .../spinlock_types.h | 4 ++-- include/asm-ppc/spinlock_types.h | 20 ------------------- 2 files changed, 2 insertions(+), 22 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/spinlock_types.h (80%) delete mode 100644 include/asm-ppc/spinlock_types.h diff --git a/include/asm-ppc64/spinlock_types.h b/include/asm-powerpc/spinlock_types.h similarity index 80% rename from include/asm-ppc64/spinlock_types.h rename to include/asm-powerpc/spinlock_types.h index a37c8eabb9f2..74236c9f05b1 100644 --- a/include/asm-ppc64/spinlock_types.h +++ b/include/asm-powerpc/spinlock_types.h @@ -1,5 +1,5 @@ -#ifndef __ASM_SPINLOCK_TYPES_H -#define __ASM_SPINLOCK_TYPES_H +#ifndef _ASM_POWERPC_SPINLOCK_TYPES_H +#define _ASM_POWERPC_SPINLOCK_TYPES_H #ifndef __LINUX_SPINLOCK_TYPES_H # error "please don't include this file directly" diff --git a/include/asm-ppc/spinlock_types.h b/include/asm-ppc/spinlock_types.h deleted file mode 100644 index 7919ccc75b8a..000000000000 --- a/include/asm-ppc/spinlock_types.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __ASM_SPINLOCK_TYPES_H -#define __ASM_SPINLOCK_TYPES_H - -#ifndef __LINUX_SPINLOCK_TYPES_H -# error "please don't include this file directly" -#endif - -typedef struct { - volatile unsigned long lock; -} raw_spinlock_t; - -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } - -typedef struct { - volatile signed int lock; -} raw_rwlock_t; - -#define __RAW_RW_LOCK_UNLOCKED { 0 } - -#endif From e903c5b536895fdf69970df62c5bf49ad17e6533 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 20 Sep 2005 16:49:51 -0500 Subject: [PATCH 0108/1940] [PATCH] powerpc: merge include/asm-ppc*/statfs.h into include/asm-powerpc/statfs.h Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/statfs.h | 19 +++++++++---------- include/asm-ppc/statfs.h | 8 -------- 2 files changed, 9 insertions(+), 18 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/statfs.h (69%) delete mode 100644 include/asm-ppc/statfs.h diff --git a/include/asm-ppc64/statfs.h b/include/asm-powerpc/statfs.h similarity index 69% rename from include/asm-ppc64/statfs.h rename to include/asm-powerpc/statfs.h index 3c985e5246a7..67024026c10d 100644 --- a/include/asm-ppc64/statfs.h +++ b/include/asm-powerpc/statfs.h @@ -1,12 +1,11 @@ -#ifndef _PPC64_STATFS_H -#define _PPC64_STATFS_H +#ifndef _ASM_POWERPC_STATFS_H +#define _ASM_POWERPC_STATFS_H -/* - * 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. - */ +/* For ppc32 we just use the generic definitions, not so simple on ppc64 */ + +#ifndef __powerpc64__ +#include +#else #ifndef __KERNEL_STRICT_NAMES #include @@ -57,5 +56,5 @@ struct compat_statfs64 { __u32 f_frsize; __u32 f_spare[5]; }; - -#endif /* _PPC64_STATFS_H */ +#endif /* ! __powerpc64__ */ +#endif diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h deleted file mode 100644 index 807c69954a1b..000000000000 --- a/include/asm-ppc/statfs.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _PPC_STATFS_H -#define _PPC_STATFS_H - -#include -#endif - - - From 2096243885ee34b78cb57ce835e07c8536a67d2a Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 21 Sep 2005 22:05:57 -0700 Subject: [PATCH 0109/1940] [CIFS] Add support for legacy servers part nine. statfs (df and du) is now functional, and the length check is fixed so readdir does not throw a warning message when windows me messes up the response to FindFirst of an empty dir (with only . and ..). Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 3 +- fs/cifs/cifsfs.c | 4 ++ fs/cifs/cifspdu.h | 8 ++++ fs/cifs/cifsproto.h | 2 + fs/cifs/cifssmb.c | 95 ++++++++++++++++++++++++++++++++++++++++++--- fs/cifs/misc.c | 3 +- fs/cifs/netmisc.c | 2 +- 7 files changed, 107 insertions(+), 10 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 47ae68b51847..661b45906d09 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -3,7 +3,8 @@ Version 1.37 Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. Do not attempt to set ctime unless atime and/or mtime change requested -(most servers throw it away anyway). +(most servers throw it away anyway). Fix length check of received smbs +to be more accurate. Version 1.36 ------------ diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f738c8b19e3b..1f97d39100ee 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -205,6 +205,10 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) #endif /* CIFS_EXPERIMENTAL */ rc = CIFSSMBQFSInfo(xid, pTcon, buf); + /* Old Windows servers do not support level 103, retry with level + one if old server failed the previous call */ + if(rc) + rc = SMBOldQFSInfo(xid, pTcon, buf); /* int f_type; __fsid_t f_fsid; diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index cf466595b0d4..3fa37790bea2 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1683,6 +1683,14 @@ typedef struct { __le32 BytesPerSector; } FILE_SYSTEM_INFO; /* size info, level 0x103 */ +typedef struct { + __le32 fsid; + __le32 SectorsPerAllocationUnit; + __le32 TotalAllocationUnits; + __le32 FreeAllocationUnits; + __le16 BytesPerSector; +} FILE_SYSTEM_ALLOC_INFO; + typedef struct { __le16 MajorVersionNumber; __le16 MinorVersionNumber; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 6943f7c6de08..0bace385e97a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -133,6 +133,8 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, int remap); extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData); +extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, + struct kstatfs *FSData); extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f72a61df3c68..daf717e6b6eb 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3215,6 +3215,92 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, return rc; } +/* Query File System Info such as free space to old servers such as Win 9x */ +int +SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) +{ +/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ + TRANSACTION2_QFSI_REQ *pSMB = NULL; + TRANSACTION2_QFSI_RSP *pSMBr = NULL; + FILE_SYSTEM_ALLOC_INFO *response_data; + int rc = 0; + int bytes_returned = 0; + __u16 params, byte_count; + + cFYI(1, ("OldQFSInfo")); +oldQFSInfoRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + params = 2; /* level */ + pSMB->TotalDataCount = 0; + pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxDataCount = cpu_to_le16(1000); + pSMB->MaxSetupCount = 0; + pSMB->Reserved = 0; + pSMB->Flags = 0; + pSMB->Timeout = 0; + pSMB->Reserved2 = 0; + byte_count = params + 1 /* pad */ ; + pSMB->TotalParameterCount = cpu_to_le16(params); + pSMB->ParameterCount = pSMB->TotalParameterCount; + pSMB->ParameterOffset = cpu_to_le16(offsetof( + struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); + pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); + pSMB->hdr.smb_buf_length += byte_count; + pSMB->ByteCount = cpu_to_le16(byte_count); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QFSInfo = %d", rc)); + } else { /* decode response */ + rc = validate_t2((struct smb_t2_rsp *)pSMBr); + + if (rc || (pSMBr->ByteCount < 18)) + rc = -EIO; /* bad smb */ + else { + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); + cFYI(1,("qfsinf resp BCC: %d Offset %d", + pSMBr->ByteCount, data_offset)); + + response_data = + (FILE_SYSTEM_ALLOC_INFO *) + (((char *) &pSMBr->hdr.Protocol) + data_offset); + FSData->f_bsize = + le16_to_cpu(response_data->BytesPerSector) * + le32_to_cpu(response_data-> + SectorsPerAllocationUnit); + FSData->f_blocks = + le32_to_cpu(response_data->TotalAllocationUnits); + FSData->f_bfree = FSData->f_bavail = + le32_to_cpu(response_data->FreeAllocationUnits); + cFYI(1, + ("Blocks: %lld Free: %lld Block size %ld", + (unsigned long long)FSData->f_blocks, + (unsigned long long)FSData->f_bfree, + FSData->f_bsize)); + } + } + cifs_buf_release(pSMB); + + if (rc == -EAGAIN) + goto oldQFSInfoRetry; + + return rc; +} + int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) { @@ -3236,7 +3322,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) params = 2; /* level */ pSMB->TotalDataCount = 0; pSMB->MaxParameterCount = cpu_to_le16(2); - pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ + pSMB->MaxDataCount = cpu_to_le16(1000); pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; pSMB->Flags = 0; @@ -3259,17 +3345,14 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("Send error in QFSInfo = %d", rc)); + cFYI(1, ("Send error in QFSInfo = %d", rc)); } else { /* decode response */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); - if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */ + if (rc || (pSMBr->ByteCount < 24)) rc = -EIO; /* bad smb */ else { __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); - cFYI(1, - ("Decoding qfsinfo response. BCC: %d Offset %d", - pSMBr->ByteCount, data_offset)); response_data = (FILE_SYSTEM_INFO diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index fafbdbfa63a1..26b35b55f31b 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -450,13 +450,12 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) if ((4 + len != smbCalcSize(smb)) || (4 + len != (unsigned int)length)) { - return 0; - } else { cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb))); cERROR(1, ("bad smb size detected. The Mid=%d", smb->Mid)); return 1; } + return 0; } int is_valid_oplock_break(struct smb_hdr *buf) diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 873b812c0f40..32efa32774d2 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -868,7 +868,7 @@ unsigned int smbCalcSize(struct smb_hdr *ptr) { return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + - BCC(ptr)); + 2 /* size of the bcc field itself */ + BCC(ptr)); } /* The following are taken from fs/ntfs/util.c */ From b8f114db84dac709080198e08a5564976afd6579 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Wed, 21 Sep 2005 14:54:51 -0500 Subject: [PATCH 0110/1940] [PATCH] powerpc: Merge asm-ppc*/dma.h This merges the asm-ppc*/dma.h files. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/setup.c | 3 +- include/{asm-ppc => asm-powerpc}/dma.h | 91 ++++--- include/asm-ppc64/dma.h | 329 ------------------------- 3 files changed, 57 insertions(+), 366 deletions(-) rename include/{asm-ppc => asm-powerpc}/dma.h (86%) delete mode 100644 include/asm-ppc64/dma.h diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 8b06b8e00332..77fecfbabe88 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -71,7 +71,8 @@ struct ide_machdep_calls ppc_ide_md; unsigned long boot_mem_size; unsigned long ISA_DMA_THRESHOLD; -unsigned long DMA_MODE_READ, DMA_MODE_WRITE; +unsigned int DMA_MODE_READ; +unsigned int DMA_MODE_WRITE; #ifdef CONFIG_PPC_MULTIPLATFORM int _machine = 0; diff --git a/include/asm-ppc/dma.h b/include/asm-powerpc/dma.h similarity index 86% rename from include/asm-ppc/dma.h rename to include/asm-powerpc/dma.h index cc8e5cd8c9d2..926378d2cd94 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-powerpc/dma.h @@ -1,18 +1,14 @@ +#ifndef _ASM_POWERPC_DMA_H +#define _ASM_POWERPC_DMA_H + /* - * include/asm-ppc/dma.h: Defines for using and allocating dma channels. + * Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen * and John Boyd, Nov. 1992. * Changes for ppc sound by Christoph Nadig */ -#ifdef __KERNEL__ - -#include -#include -#include -#include - /* * Note: Adapted for PowerPC by Gary Thomas * Modified by Cort Dougan @@ -25,8 +21,10 @@ * with a grain of salt. */ -#ifndef _ASM_DMA_H -#define _ASM_DMA_H +#include +#include +#include +#include #ifndef MAX_DMA_CHANNELS #define MAX_DMA_CHANNELS 8 @@ -34,11 +32,9 @@ /* The maximum address that we can perform a DMA transfer to on this platform */ /* Doesn't really apply... */ -#define MAX_DMA_ADDRESS 0xFFFFFFFF +#define MAX_DMA_ADDRESS (~0UL) -/* in arch/ppc/kernel/setup.c -- Cort */ -extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ; -extern unsigned long ISA_DMA_THRESHOLD; +#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER #define dma_outb outb_p @@ -171,7 +167,18 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2; #define DMA1_EXT_REG 0x40B #define DMA2_EXT_REG 0x4D6 +#ifndef __powerpc64__ + /* in arch/ppc/kernel/setup.c -- Cort */ + extern unsigned int DMA_MODE_WRITE; + extern unsigned int DMA_MODE_READ; + extern unsigned long ISA_DMA_THRESHOLD; +#else + #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ + #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#endif + #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + #define DMA_AUTOINIT 0x10 extern spinlock_t dma_spin_lock; @@ -200,8 +207,9 @@ static __inline__ void enable_dma(unsigned int dmanr) if (dmanr <= 3) { dma_outb(dmanr, DMA1_MASK_REG); dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */ - } else + } else { dma_outb(dmanr & 3, DMA2_MASK_REG); + } } static __inline__ void disable_dma(unsigned int dmanr) @@ -290,19 +298,26 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) { if (dmanr <= 3) { - dma_outb(phys & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE); - dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE); + dma_outb(phys & 0xff, + ((dmanr & 3) << 1) + IO_DMA1_BASE); + dma_outb((phys >> 8) & 0xff, + ((dmanr & 3) << 1) + IO_DMA1_BASE); } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { - dma_outb(phys & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); - dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb(phys & 0xff, + ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb((phys >> 8) & 0xff, + ((dmanr & 3) << 2) + IO_DMA2_BASE); dma_outb((dmanr & 3), DMA2_EXT_REG); } else { - dma_outb((phys >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); - dma_outb((phys >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb((phys >> 1) & 0xff, + ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb((phys >> 9) & 0xff, + ((dmanr & 3) << 2) + IO_DMA2_BASE); } set_dma_page(dmanr, phys >> 16); } + /* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for * a specific DMA channel. * You must ensure the parameters are valid. @@ -315,21 +330,24 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) { count--; if (dmanr <= 3) { - dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); - dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 1) + 1 + - IO_DMA1_BASE); + dma_outb(count & 0xff, + ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); + dma_outb((count >> 8) & 0xff, + ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { - dma_outb(count & 0xff, ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); - dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 2) + 2 + - IO_DMA2_BASE); + dma_outb(count & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); + dma_outb((count >> 8) & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); } else { - dma_outb((count >> 1) & 0xff, ((dmanr & 3) << 2) + 2 + - IO_DMA2_BASE); - dma_outb((count >> 9) & 0xff, ((dmanr & 3) << 2) + 2 + - IO_DMA2_BASE); + dma_outb((count >> 1) & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); + dma_outb((count >> 9) & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); } } + /* Get DMA residue count. After a DMA transfer, this * should return zero. Reading this while a DMA transfer is * still in progress will return unpredictable results. @@ -340,8 +358,8 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) */ static __inline__ int get_dma_residue(unsigned int dmanr) { - unsigned int io_port = (dmanr <= 3) ? - ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE + unsigned int io_port = (dmanr <= 3) + ? ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE : ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE; /* using short to get 16-bit wrap around */ @@ -352,7 +370,6 @@ static __inline__ int get_dma_residue(unsigned int dmanr) return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2) ? count : (count << 1); - } /* These are in kernel/dma.c: */ @@ -367,5 +384,7 @@ extern int isa_dma_bridge_buggy; #else #define isa_dma_bridge_buggy (0) #endif -#endif /* _ASM_DMA_H */ -#endif /* __KERNEL__ */ + +#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */ + +#endif /* _ASM_POWERPC_DMA_H */ diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h deleted file mode 100644 index dfd1f69059ba..000000000000 --- a/include/asm-ppc64/dma.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen - * and John Boyd, Nov. 1992. - * Changes for ppc sound by Christoph Nadig - * - * 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. - */ - -#ifndef _ASM_DMA_H -#define _ASM_DMA_H - -#include -#include -#include -#include - -#ifndef MAX_DMA_CHANNELS -#define MAX_DMA_CHANNELS 8 -#endif - -/* The maximum address that we can perform a DMA transfer to on this platform */ -/* Doesn't really apply... */ -#define MAX_DMA_ADDRESS (~0UL) - -#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) - -#define dma_outb outb -#define dma_inb inb - -/* - * NOTES about DMA transfers: - * - * controller 1: channels 0-3, byte operations, ports 00-1F - * controller 2: channels 4-7, word operations, ports C0-DF - * - * - ALL registers are 8 bits only, regardless of transfer size - * - channel 4 is not used - cascades 1 into 2. - * - channels 0-3 are byte - addresses/counts are for physical bytes - * - channels 5-7 are word - addresses/counts are for physical words - * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries - * - transfer count loaded to registers is 1 less than actual count - * - controller 2 offsets are all even (2x offsets for controller 1) - * - page registers for 5-7 don't use data bit 0, represent 128K pages - * - page registers for 0-3 use bit 0, represent 64K pages - * - * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory. - * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing. - * Note that addresses loaded into registers must be _physical_ addresses, - * not logical addresses (which may differ if paging is active). - * - * Address mapping for channels 0-3: - * - * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Address mapping for channels 5-7: - * - * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) - * | ... | \ \ ... \ \ \ ... \ \ - * | ... | \ \ ... \ \ \ ... \ (not used) - * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses - * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at - * the hardware level, so odd-byte transfers aren't possible). - * - * Transfer count (_not # bytes_) is limited to 64K, represented as actual - * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. - * - */ - -/* 8237 DMA controllers */ -#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ -#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ - -/* DMA controller registers */ -#define DMA1_CMD_REG 0x08 /* command register (w) */ -#define DMA1_STAT_REG 0x08 /* status register (r) */ -#define DMA1_REQ_REG 0x09 /* request register (w) */ -#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ -#define DMA1_MODE_REG 0x0B /* mode register (w) */ -#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ -#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ - -#define DMA2_CMD_REG 0xD0 /* command register (w) */ -#define DMA2_STAT_REG 0xD0 /* status register (r) */ -#define DMA2_REQ_REG 0xD2 /* request register (w) */ -#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ -#define DMA2_MODE_REG 0xD6 /* mode register (w) */ -#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ -#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ - -#define DMA_ADDR_0 0x00 /* DMA address registers */ -#define DMA_ADDR_1 0x02 -#define DMA_ADDR_2 0x04 -#define DMA_ADDR_3 0x06 -#define DMA_ADDR_4 0xC0 -#define DMA_ADDR_5 0xC4 -#define DMA_ADDR_6 0xC8 -#define DMA_ADDR_7 0xCC - -#define DMA_CNT_0 0x01 /* DMA count registers */ -#define DMA_CNT_1 0x03 -#define DMA_CNT_2 0x05 -#define DMA_CNT_3 0x07 -#define DMA_CNT_4 0xC2 -#define DMA_CNT_5 0xC6 -#define DMA_CNT_6 0xCA -#define DMA_CNT_7 0xCE - -#define DMA_LO_PAGE_0 0x87 /* DMA page registers */ -#define DMA_LO_PAGE_1 0x83 -#define DMA_LO_PAGE_2 0x81 -#define DMA_LO_PAGE_3 0x82 -#define DMA_LO_PAGE_5 0x8B -#define DMA_LO_PAGE_6 0x89 -#define DMA_LO_PAGE_7 0x8A - -#define DMA_HI_PAGE_0 0x487 /* DMA page registers */ -#define DMA_HI_PAGE_1 0x483 -#define DMA_HI_PAGE_2 0x481 -#define DMA_HI_PAGE_3 0x482 -#define DMA_HI_PAGE_5 0x48B -#define DMA_HI_PAGE_6 0x489 -#define DMA_HI_PAGE_7 0x48A - -#define DMA1_EXT_REG 0x40B -#define DMA2_EXT_REG 0x4D6 - -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ - -#define DMA_AUTOINIT 0x10 - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - unsigned char ucDmaCmd=0x00; - - if (dmanr != 4) - { - dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ - dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */ - } - if (dmanr<=3) - { - dma_outb(dmanr, DMA1_MASK_REG); - dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */ - } else - { - dma_outb(dmanr & 3, DMA2_MASK_REG); - } -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); - else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); -} - -/* Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); - else - dma_outb(0, DMA2_CLEAR_FF_REG); -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); - else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); -} - -/* Set only the page register bits of the transfer address. - * This is used for successive transfers when we know the contents of - * the lower 16 bits of the DMA current address register, but a 64k boundary - * may have been crossed. - */ -static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) -{ - switch(dmanr) { - case 0: - dma_outb(pagenr, DMA_LO_PAGE_0); - dma_outb(pagenr>>8, DMA_HI_PAGE_0); - break; - case 1: - dma_outb(pagenr, DMA_LO_PAGE_1); - dma_outb(pagenr>>8, DMA_HI_PAGE_1); - break; - case 2: - dma_outb(pagenr, DMA_LO_PAGE_2); - dma_outb(pagenr>>8, DMA_HI_PAGE_2); - break; - case 3: - dma_outb(pagenr, DMA_LO_PAGE_3); - dma_outb(pagenr>>8, DMA_HI_PAGE_3); - break; - case 5: - dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5); - dma_outb(pagenr>>8, DMA_HI_PAGE_5); - break; - case 6: - dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6); - dma_outb(pagenr>>8, DMA_HI_PAGE_6); - break; - case 7: - dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7); - dma_outb(pagenr>>8, DMA_HI_PAGE_7); - break; - } -} - - -/* Set transfer address & page bits for specific DMA channel. - * Assumes dma flipflop is clear. - */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) -{ - if (dmanr <= 3) { - dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } - set_dma_page(dmanr, phys>>16); -} - - -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for - * a specific DMA channel. - * You must ensure the parameters are valid. - * NOTE: from a manual: "the number of transfers is one more - * than the initial word count"! This is taken into account. - * Assumes dma flip-flop is clear. - * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } -} - - -/* Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * If called before the channel has been used, it may return 1. - * Otherwise, it returns the number of _bytes_ left to transfer. - * - * Assumes DMA flip-flop is clear. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; - - /* using short to get 16-bit wrap around */ - unsigned short count; - - count = 1 + dma_inb(io_port); - count += dma_inb(io_port) << 8; - - return (dmanr <= 3)? count : (count<<1); -} - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif -#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */ -#endif /* _ASM_DMA_H */ From fa2ac7a25f1b11c4a695c9288339d0476ecfaf38 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 21 Sep 2005 15:44:11 -0500 Subject: [PATCH 0111/1940] [PATCH] powerpc: Fix compiling of ppc32 The merging of auxvec.h into asm-powerpc introduced the AT_SYSINFO_EHDR into the ppc32 build that is used for VDSO. However, we dont have VDSO support in the ppc32 tree at this time. Introducing this define causes a number of other things to get built with the assumption of VDSO, thus causing the compile errors for ppc32. Until we have VDSO on ppc32 we will leave AT_SYSINFO_EHDR a ppc64 only define. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- include/asm-powerpc/auxvec.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-powerpc/auxvec.h b/include/asm-powerpc/auxvec.h index 19a099b62cd6..79d8c4732309 100644 --- a/include/asm-powerpc/auxvec.h +++ b/include/asm-powerpc/auxvec.h @@ -14,6 +14,8 @@ /* The vDSO location. We have to use the same value as x86 for glibc's * sake :-) */ +#ifdef __powerpc64__ #define AT_SYSINFO_EHDR 33 +#endif #endif From b671ad2befe37131af380183760862d5cbad858d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 21 Sep 2005 16:52:55 -0500 Subject: [PATCH 0112/1940] [PATCH] powerpc: merged hw_irq.h Merged hw_irq.h between ppc32 & ppc64. Added support to use the Book-E wrtee[i] instructions that allow modifying MSR[EE] atomically. Additionally, added get_irq_desc() macros to ppc32 to allow mask_irq(), unmask_irq(), and ack_irq() to be common between ppc32 & ppc64. Note: because 64-bit Book-E implementations only have a 32-bit MSR the macro's for Book-E need to come before the PPC64 macro's to ensure the right thing happends for 64-bit Book-E processors. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/hw_irq.h | 63 ++++++++++++--------- include/asm-ppc/hw_irq.h | 59 ------------------- include/asm-ppc/irq.h | 6 ++ 3 files changed, 43 insertions(+), 85 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/hw_irq.h (66%) delete mode 100644 include/asm-ppc/hw_irq.h diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-powerpc/hw_irq.h similarity index 66% rename from include/asm-ppc64/hw_irq.h rename to include/asm-powerpc/hw_irq.h index c483897b8757..605a65e42063 100644 --- a/include/asm-ppc64/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h @@ -1,19 +1,15 @@ /* * Copyright (C) 1999 Cort Dougan - * - * Use inline IRQs where possible - Anton Blanchard - * - * 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. */ +#ifndef _ASM_POWERPC_HW_IRQ_H +#define _ASM_POWERPC_HW_IRQ_H + #ifdef __KERNEL__ -#ifndef _PPC64_HW_IRQ_H -#define _PPC64_HW_IRQ_H #include #include +#include +#include #include extern void timer_interrupt(struct pt_regs *); @@ -33,45 +29,60 @@ extern void local_irq_restore(unsigned long); #else -#define local_save_flags(flags) ((flags) = mfmsr()) +#if defined(CONFIG_BOOKE) +#define SET_MSR_EE(x) mtmsr(x) +#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") +#elif defined(__powerpc64__) +#define SET_MSR_EE(x) __mtmsrd(x, 1) #define local_irq_restore(flags) do { \ __asm__ __volatile__("": : :"memory"); \ __mtmsrd((flags), 1); \ } while(0) +#else +#define SET_MSR_EE(x) mtmsr(x) +#define local_irq_restore(flags) mtmsr(flags) +#endif static inline void local_irq_disable(void) { +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 0": : :"memory"); +#else unsigned long msr; - msr = mfmsr(); - __mtmsrd(msr & ~MSR_EE, 1); __asm__ __volatile__("": : :"memory"); + msr = mfmsr(); + SET_MSR_EE(msr & ~MSR_EE); +#endif } static inline void local_irq_enable(void) { +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 1": : :"memory"); +#else unsigned long msr; __asm__ __volatile__("": : :"memory"); msr = mfmsr(); - __mtmsrd(msr | MSR_EE, 1); + SET_MSR_EE(msr | MSR_EE); +#endif } -static inline void __do_save_and_cli(unsigned long *flags) +static inline void local_irq_save_ptr(unsigned long *flags) { unsigned long msr; msr = mfmsr(); *flags = msr; - __mtmsrd(msr & ~MSR_EE, 1); +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 0": : :"memory"); +#else + SET_MSR_EE(msr & ~MSR_EE); +#endif __asm__ __volatile__("": : :"memory"); } -#define local_irq_save(flags) __do_save_and_cli(&flags) - -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - !(flags & MSR_EE); \ -}) +#define local_save_flags(flags) ((flags) = mfmsr()) +#define local_irq_save(flags) local_irq_save_ptr(&flags) +#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) #endif /* CONFIG_PPC_ISERIES */ @@ -99,6 +110,6 @@ static inline void __do_save_and_cli(unsigned long *flags) */ struct hw_interrupt_type; static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} - -#endif /* _PPC64_HW_IRQ_H */ -#endif /* __KERNEL__ */ + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h deleted file mode 100644 index da0fa940adb3..000000000000 --- a/include/asm-ppc/hw_irq.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1999 Cort Dougan - */ -#ifdef __KERNEL__ -#ifndef _PPC_HW_IRQ_H -#define _PPC_HW_IRQ_H - -#include -#include -#include - -extern void timer_interrupt(struct pt_regs *); - -#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) - -static inline void local_irq_disable(void) -{ - unsigned long msr; - msr = mfmsr(); - mtmsr(msr & ~MSR_EE); - __asm__ __volatile__("": : :"memory"); -} - -static inline void local_irq_enable(void) -{ - unsigned long msr; - __asm__ __volatile__("": : :"memory"); - msr = mfmsr(); - mtmsr(msr | MSR_EE); -} - -static inline void local_irq_save_ptr(unsigned long *flags) -{ - unsigned long msr; - msr = mfmsr(); - *flags = msr; - mtmsr(msr & ~MSR_EE); - __asm__ __volatile__("": : :"memory"); -} - -#define local_save_flags(flags) ((flags) = mfmsr()) -#define local_irq_save(flags) local_irq_save_ptr(&flags) -#define local_irq_restore(flags) mtmsr(flags) - -extern void do_lost_interrupts(unsigned long); - -#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);}) -#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);}) -#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);}) - -/* Should we handle this via lost interrupts and IPIs or should we don't care like - * we do now ? --BenH. - */ -struct hw_interrupt_type; -static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} - - -#endif /* _PPC_HW_IRQ_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index bd9674807f05..137ea0cf34d3 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -24,6 +24,12 @@ */ #define ARCH_HAS_IRQ_PER_CPU +#define get_irq_desc(irq) (&irq_desc[(irq)]) + +/* Define a way to iterate across irqs. */ +#define for_each_irq(i) \ + for ((i) = 0; (i) < NR_IRQS; ++(i)) + #if defined(CONFIG_40x) #include From 70ca734a14366b634224a1e4586d43b36b65ab67 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 22 Sep 2005 16:32:06 -0700 Subject: [PATCH 0113/1940] [CIFS] Various minor bigendian fixes and sparse level 2 warning message fixes Most important of these fixes mapchars on bigendian and a few statfs fields Signed-off-by: Shaggy (shaggy@austin.ibm.com) Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/CHANGES | 3 ++- fs/cifs/cifspdu.h | 2 +- fs/cifs/cifsproto.h | 1 + fs/cifs/cifssmb.c | 24 ++++++++++++++---------- fs/cifs/connect.c | 38 +++++++++++++++++++++++++------------- fs/cifs/misc.c | 12 +++++++----- fs/cifs/netmisc.c | 9 ++++++++- fs/cifs/transport.c | 4 ++-- 8 files changed, 60 insertions(+), 33 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 661b45906d09..535177238020 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -4,7 +4,8 @@ Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. Do not attempt to set ctime unless atime and/or mtime change requested (most servers throw it away anyway). Fix length check of received smbs -to be more accurate. +to be more accurate. Fix big endian problem with mapchars mount option, +and with a field returned by statfs. Version 1.36 ------------ diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 3fa37790bea2..193f06eb43f9 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -697,7 +697,7 @@ typedef struct smb_com_openx_req { __le32 EndOfFile; __le32 Timeout; __le32 Reserved; - __u16 ByteCount; /* file name follows */ + __le16 ByteCount; /* file name follows */ char fileName[1]; } OPENX_REQ; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 0bace385e97a..dc5a6a6ff2f9 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -56,6 +56,7 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern unsigned int smbCalcSize(struct smb_hdr *ptr); +extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, enum securityEnum *secType); extern int cifs_inet_pton(int, char * source, void *dst); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index daf717e6b6eb..52caac063a77 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -779,7 +779,7 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, /* BB FIXME END BB */ pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); - pSMB->OpenFunction = convert_disposition(openDisposition); + pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); count += name_len; pSMB->hdr.smb_buf_length += count; @@ -808,10 +808,12 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, pfile_info->LastAccessTime = 0; /* BB fixme */ pfile_info->LastWriteTime = 0; /* BB fixme */ pfile_info->ChangeTime = 0; /* BB fixme */ - pfile_info->Attributes = pSMBr->FileAttributes; + pfile_info->Attributes = + cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); /* the file_info buf is endian converted by caller */ - pfile_info->AllocationSize = pSMBr->EndOfFile; - pfile_info->EndOfFile = pSMBr->EndOfFile; + pfile_info->AllocationSize = + cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); + pfile_info->EndOfFile = pfile_info->AllocationSize; pfile_info->NumberOfLinks = cpu_to_le32(1); } } @@ -2390,9 +2392,11 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, cFYI(1, ("Send error in QueryInfo = %d", rc)); } else if (pFinfo) { /* decode response */ memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); - pFinfo->AllocationSize = (__le64) pSMBr->size; - pFinfo->EndOfFile = (__le64) pSMBr->size; - pFinfo->Attributes = (__le32) pSMBr->attr; + pFinfo->AllocationSize = + cpu_to_le64(le32_to_cpu(pSMBr->size)); + pFinfo->EndOfFile = pFinfo->AllocationSize; + pFinfo->Attributes = + cpu_to_le32(le16_to_cpu(pSMBr->attr)); } else rc = -EIO; /* bad buffer passed in */ @@ -3722,16 +3726,16 @@ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, le64_to_cpu(response_data->TotalBlocks); FSData->f_bfree = le64_to_cpu(response_data->BlocksAvail); - if(response_data->UserBlocksAvail == -1) { + if(response_data->UserBlocksAvail == cpu_to_le64(-1)) { FSData->f_bavail = FSData->f_bfree; } else { FSData->f_bavail = le64_to_cpu(response_data->UserBlocksAvail); } - if(response_data->TotalFileNodes != -1) + if(response_data->TotalFileNodes != cpu_to_le64(-1)) FSData->f_files = le64_to_cpu(response_data->TotalFileNodes); - if(response_data->FreeFileNodes != -1) + if(response_data->FreeFileNodes != cpu_to_le64(-1)) FSData->f_ffree = le64_to_cpu(response_data->FreeFileNodes); } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 196976049c00..e27e5ad8b591 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -303,12 +303,12 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB) byte_count += total_in_buf2; BCC_LE(pTargetSMB) = cpu_to_le16(byte_count); - byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); + byte_count = pTargetSMB->smb_buf_length; byte_count += total_in_buf2; /* BB also add check that we are not beyond maximum buffer size */ - pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); + pTargetSMB->smb_buf_length = byte_count; if(remaining == total_in_buf2) { cFYI(1,("found the last secondary response")); @@ -333,7 +333,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) struct cifsSesInfo *ses; struct task_struct *task_to_wake = NULL; struct mid_q_entry *mid_entry; - char *temp; + char temp; int isLargeBuf = FALSE; int isMultiRsp; int reconnect; @@ -435,22 +435,32 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) continue; } - /* the right amount was read from socket - 4 bytes */ + /* The right amount was read from socket - 4 bytes */ + /* so we can now interpret the length field */ + /* the first byte big endian of the length field, + is actually not part of the length but the type + with the most common, zero, as regular data */ + temp = *((char *) smb_buffer); + + /* Note that FC 1001 length is big endian on the wire, + but we convert it here so it is always manipulated + as host byte order */ pdu_length = ntohl(smb_buffer->smb_buf_length); - cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); + smb_buffer->smb_buf_length = pdu_length; - temp = (char *) smb_buffer; - if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) { + cFYI(1,("rfc1002 length 0x%x)", pdu_length+4)); + + if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { continue; - } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { + } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { cFYI(1,("Good RFC 1002 session rsp")); continue; - } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { + } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { /* we get this from Windows 98 instead of an error on SMB negprot response */ cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", - temp[4])); + pdu_length)); if(server->tcpStatus == CifsNew) { /* if nack on negprot (rather than ret of smb negprot error) reconnecting @@ -472,9 +482,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) wake_up(&server->response_q); continue; } - } else if (temp[0] != (char) 0) { + } else if (temp != (char) 0) { cERROR(1,("Unknown RFC 1002 frame")); - cifs_dump_mem(" Received Data: ", temp, length); + cifs_dump_mem(" Received Data: ", (char *)smb_buffer, + length); cifs_reconnect(server); csocket = server->ssocket; continue; @@ -609,7 +620,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } else if ((is_valid_oplock_break(smb_buffer) == FALSE) && (isMultiRsp == FALSE)) { cERROR(1, ("No task to wake, unknown frame rcvd!")); - cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)); + cifs_dump_mem("Received Data is: ",(char *)smb_buffer, + sizeof(struct smb_hdr)); } } /* end while !EXITING */ diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 26b35b55f31b..8a0edd695f84 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -419,7 +419,7 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) int checkSMB(struct smb_hdr *smb, __u16 mid, int length) { - __u32 len = be32_to_cpu(smb->smb_buf_length); + __u32 len = smb->smb_buf_length; cFYI(0, ("Entering checkSMB with Length: %x, smb_buf_length: %x ", length, len)); @@ -448,9 +448,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) if (checkSMBhdr(smb, mid)) return 1; - if ((4 + len != smbCalcSize(smb)) + if ((4 + len != smbCalcSize_LE(smb)) || (4 + len != (unsigned int)length)) { - cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb))); + cERROR(1, ("smbCalcSize %x ", smbCalcSize_LE(smb))); cERROR(1, ("bad smb size detected. The Mid=%d", smb->Mid)); return 1; @@ -672,6 +672,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, int i,j,charlen; int len_remaining = maxlen; char src_char; + __u16 temp; if(!mapChars) return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); @@ -708,13 +709,14 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, break;*/ default: charlen = cp->char2uni(source+i, - len_remaining, target+j); + len_remaining, &temp); /* if no match, use question mark, which at least in some cases servers as wild card */ if(charlen < 1) { target[j] = cpu_to_le16(0x003f); charlen = 1; - } + } else + target[j] = cpu_to_le16(temp); len_remaining -= charlen; /* character may take more than one byte in the the source string, but will take exactly two diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 32efa32774d2..29e6efc5597c 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -868,7 +868,14 @@ unsigned int smbCalcSize(struct smb_hdr *ptr) { return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + - 2 /* size of the bcc field itself */ + BCC(ptr)); + 2 /* size of the bcc field */ + BCC(ptr)); +} + +unsigned int +smbCalcSize_LE(struct smb_hdr *ptr) +{ + return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + + 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); } /* The following are taken from fs/ntfs/util.c */ diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index d5e0c4018f92..9e8e85a8d186 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -414,7 +414,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { spin_unlock(&GlobalMid_Lock); - receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); + receive_len = midQ->resp_buf->smb_buf_length; } else { cERROR(1,("No response buffer")); if(midQ->midState == MID_REQUEST_SUBMITTED) { @@ -665,7 +665,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { spin_unlock(&GlobalMid_Lock); - receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); + receive_len = midQ->resp_buf->smb_buf_length; } else { cERROR(1,("No response buffer")); if(midQ->midState == MID_REQUEST_SUBMITTED) { From 9f497581fda5fd804e9ebd7d8f6d80c3a0e9f883 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:10:59 +1000 Subject: [PATCH 0114/1940] ppc64 iSeries: Move iSeries ppc_md functions into a machdep_calls struct Move the iSeries machine specific calls into a machdep_calls struct like other platforms, rather than setting members of ppc_md explicitly. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 57 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 3ffefbbc6623..b5dcb08547bd 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -76,6 +76,8 @@ extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); static void setup_iSeries_cache_sizes(void); static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); +static int iseries_shared_idle(void); +static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI extern void iSeries_pci_final_fixup(void); #else @@ -695,6 +697,14 @@ static void __init iSeries_setup_arch(void) { unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; + if (get_paca()->lppaca.shared_proc) { + ppc_md.idle_loop = iseries_shared_idle; + printk(KERN_INFO "Using shared processor idle loop\n"); + } else { + ppc_md.idle_loop = iseries_dedicated_idle; + printk(KERN_INFO "Using dedicated idle loop\n"); + } + /* Add an eye catcher and the systemcfg layout version number */ strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); systemcfg->version.major = SYSTEMCFG_MAJOR; @@ -942,36 +952,25 @@ static int iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif +struct machdep_calls __initdata iseries_md = { + .setup_arch = iSeries_setup_arch, + .get_cpuinfo = iSeries_get_cpuinfo, + .init_IRQ = iSeries_init_IRQ, + .get_irq = iSeries_get_irq, + .init_early = iSeries_init_early, + .pcibios_fixup = iSeries_pci_final_fixup, + .restart = iSeries_restart, + .power_off = iSeries_power_off, + .halt = iSeries_halt, + .get_boot_time = iSeries_get_boot_time, + .set_rtc_time = iSeries_set_rtc_time, + .get_rtc_time = iSeries_get_rtc_time, + .calibrate_decr = iSeries_calibrate_decr, + .progress = iSeries_progress, + /* XXX Implement enable_pmcs for iSeries */ +}; + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); - - ppc_md.setup_arch = iSeries_setup_arch; - ppc_md.get_cpuinfo = iSeries_get_cpuinfo; - ppc_md.init_IRQ = iSeries_init_IRQ; - ppc_md.get_irq = iSeries_get_irq; - ppc_md.init_early = iSeries_init_early, - - ppc_md.pcibios_fixup = iSeries_pci_final_fixup; - - ppc_md.restart = iSeries_restart; - ppc_md.power_off = iSeries_power_off; - ppc_md.halt = iSeries_halt; - - ppc_md.get_boot_time = iSeries_get_boot_time; - ppc_md.set_rtc_time = iSeries_set_rtc_time; - ppc_md.get_rtc_time = iSeries_get_rtc_time; - ppc_md.calibrate_decr = iSeries_calibrate_decr; - ppc_md.progress = iSeries_progress; - - /* XXX Implement enable_pmcs for iSeries */ - - if (get_paca()->lppaca.shared_proc) { - ppc_md.idle_loop = iseries_shared_idle; - printk(KERN_INFO "Using shared processor idle loop\n"); - } else { - ppc_md.idle_loop = iseries_dedicated_idle; - printk(KERN_INFO "Using dedicated idle loop\n"); - } } - From ba293fff085fde5b9f1b5a57c8abb1a8098d0c59 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:43:22 +1000 Subject: [PATCH 0115/1940] ppc46 iSeries: Make some generic irq code compile for iSeries In order to call finish_device_tree() on iSeries we need to define virt_irq_create_mapping(). We also need to set ppc64_interrupt_controller to something other than zero. If we want to do interrupt setup via the device tree on iSeries this code will need some serious work, but it's harmless to have it there as long as the nodes in the iSeries device tree don't cause it to be invoked. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_irq.c | 13 +++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 2 ++ include/asm-ppc64/processor.h | 1 + 3 files changed, 16 insertions(+) diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c index 77376c1bd611..0170682a8ca5 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/ppc64/kernel/iSeries_irq.c @@ -351,3 +351,16 @@ int __init iSeries_allocate_IRQ(HvBusNumber busNumber, irq_desc[virtirq].handler = &iSeries_IRQ_handler; return virtirq; } + +int virt_irq_create_mapping(unsigned int real_irq) +{ + BUG(); /* Don't call this on iSeries, yet */ + + return 0; +} + +void virt_irq_init(void) +{ + return; +} + diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index b5dcb08547bd..75d8db4eaac6 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -321,6 +321,8 @@ static void __init iSeries_init_early(void) ppcdbg_initialize(); + ppc64_interrupt_controller = IC_ISERIES; + #if defined(CONFIG_BLK_DEV_INITRD) /* * If the init RAM disk has been configured and there is diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 4146189006e3..fe5cd2f5868a 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -291,6 +291,7 @@ #define IC_OPEN_PIC 1 #define IC_PPC_XIC 2 #define IC_BPA_IIC 3 +#define IC_ISERIES 4 #define XGLUE(a,b) a##b #define GLUE(a,b) XGLUE(a,b) From 4c55130b2aa93370f1bf52d2304394e91cf8ee39 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:47:58 +1000 Subject: [PATCH 0116/1940] ppc64 iSeries: Update create_pte_mapping to replace iSeries_bolt_kernel() early_setup() calls htab_initialize() which is similar, but not identical to iSeries_bolt_kernel(). On iSeries the Hypervisor has already inserted some ptes for us, and we simply have to detect that and bolt them. iSeries_hpte_bolt_or_insert() implements that logic. For the case of a non-existing pte we just call iSeries_hpte_insert(). This appears to work, although it's not entirely equivalent to the old code in iSeries_make_pte() which panicked if we got a secondary slot. Not sure if that's important. Finally we call iSeries_hpte_bolt_or_insert() from create_pte_mapping(), which is called from htab_initialize() for each lmb region. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_htab.c | 19 ++++++++++ arch/ppc64/kernel/iSeries_setup.c | 60 ------------------------------- arch/ppc64/mm/hash_utils.c | 15 +++++--- include/asm-ppc64/mmu.h | 4 +++ 4 files changed, 34 insertions(+), 64 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c index 2192055a90a0..9a2be3abf349 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/ppc64/kernel/iSeries_htab.c @@ -84,6 +84,25 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, return (secondary << 3) | (slot & 7); } +long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, + unsigned long va, unsigned long prpn, unsigned long vflags, + unsigned long rflags) +{ + long slot; + hpte_t lhpte; + + slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); + + if (lhpte.v & HPTE_V_VALID) { + /* Bolt the existing HPTE */ + HvCallHpt_setSwBits(slot, 0x10, 0); + HvCallHpt_setPp(slot, PP_RWXX); + return 0; + } + + return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags); +} + static unsigned long iSeries_hpte_getword0(unsigned long slot) { hpte_t hpte; diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 75d8db4eaac6..49d0f9999682 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -75,7 +75,6 @@ extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); static void setup_iSeries_cache_sizes(void); -static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); static int iseries_shared_idle(void); static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI @@ -383,9 +382,6 @@ static void __init iSeries_init_early(void) } } - /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */ - iSeries_bolt_kernel(0, systemcfg->physicalMemorySize); - lmb_init(); lmb_add(0, systemcfg->physicalMemorySize); lmb_analyze(); @@ -636,62 +632,6 @@ static void __init setup_iSeries_cache_sizes(void) (unsigned int)ppc64_caches.iline_size); } -/* - * Create a pte. Used during initialization only. - */ -static void iSeries_make_pte(unsigned long va, unsigned long pa, - int mode) -{ - hpte_t local_hpte, rhpte; - unsigned long hash, vpn; - long slot; - - vpn = va >> PAGE_SHIFT; - hash = hpt_hash(vpn, 0); - - local_hpte.r = pa | mode; - local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) - | HPTE_V_BOLTED | HPTE_V_VALID; - - slot = HvCallHpt_findValid(&rhpte, vpn); - if (slot < 0) { - /* Must find space in primary group */ - panic("hash_page: hpte already exists\n"); - } - HvCallHpt_addValidate(slot, 0, &local_hpte); -} - -/* - * Bolt the kernel addr space into the HPT - */ -static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) -{ - unsigned long pa; - unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; - hpte_t hpte; - - for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { - unsigned long ea = (unsigned long)__va(pa); - unsigned long vsid = get_kernel_vsid(ea); - unsigned long va = (vsid << 28) | (pa & 0xfffffff); - unsigned long vpn = va >> PAGE_SHIFT; - unsigned long slot = HvCallHpt_findValid(&hpte, vpn); - - /* Make non-kernel text non-executable */ - if (!in_kernel_text(ea)) - mode_rw |= HW_NO_EXEC; - - if (hpte.v & HPTE_V_VALID) { - /* HPTE exists, so just bolt it */ - HvCallHpt_setSwBits(slot, 0x10, 0); - /* And make sure the pp bits are correct */ - HvCallHpt_setPp(slot, PP_RWXX); - } else - /* No HPTE exists, so create a new bolted one */ - iSeries_make_pte(va, phys_to_abs(pa), mode_rw); - } -} - /* * Document me. */ diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 36cf474b3d36..83507438d6a0 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -90,7 +90,6 @@ static inline void loop_forever(void) ; } -#ifdef CONFIG_PPC_MULTIPLATFORM static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long mode, int large) { @@ -111,7 +110,7 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long vpn, hash, hpteg; unsigned long vsid = get_kernel_vsid(addr); unsigned long va = (vsid << 28) | (addr & 0xfffffff); - int ret; + int ret = -1; if (large) vpn = va >> HPAGE_SHIFT; @@ -129,16 +128,25 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); +#ifdef CONFIG_PPC_ISERIES + if (systemcfg->platform & PLATFORM_ISERIES_LPAR) + ret = iSeries_hpte_bolt_or_insert(hpteg, va, + virt_to_abs(addr) >> PAGE_SHIFT, + vflags, tmp_mode); + else +#endif #ifdef CONFIG_PPC_PSERIES if (systemcfg->platform & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); else -#endif /* CONFIG_PPC_PSERIES */ +#endif +#ifdef CONFIG_PPC_MULTIPLATFORM ret = native_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); +#endif if (ret == -1) { ppc64_terminate_msg(0x20, "create_pte_mapping"); @@ -261,7 +269,6 @@ void __init htab_initialize(void) } #undef KB #undef MB -#endif /* CONFIG_PPC_MULTIPLATFORM */ /* * Called by asm hashtable.S for doing lazy icache flush diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index d2b0b796d35e..e0505acb77d9 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h @@ -206,6 +206,10 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long prpn, unsigned long vflags, unsigned long rflags); +extern long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, + unsigned long va, unsigned long prpn, + unsigned long vflags, unsigned long rflags); + extern void stabs_alloc(void); #endif /* __ASSEMBLY__ */ From 7c6f947f2477f7c0017be1af458eb5e0b96b7f40 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:50:25 +1000 Subject: [PATCH 0117/1940] ppc64 iSeries: Make stab_initialize() work on iSeries We don't need to call stab_initialize() for the boot cpu on iSeries, so we hack around it so that early_setup() can be called on iSeries. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 5ac48bd64891..ca8acf671e46 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -401,7 +402,8 @@ void __init early_setup(unsigned long dt_ptr) /* * Initialize stab / SLB management */ - stab_initialize(lpaca->stab_real); + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + stab_initialize(lpaca->stab_real); /* * Initialize the MMU Hash table and create the linear mapping From f6ab9c68406dfcd1fcd0a5352244fcb932b113b1 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:54:37 +1000 Subject: [PATCH 0118/1940] ppc64 iSeries: Make smp_release_cpus() callable on iSeries We don't need to call smp_release_cpus() on iSeries but it's harmless if we do and it removes another #ifdef ISERIES. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/head.S | 6 ++++-- arch/ppc64/kernel/setup.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 22a5ee07e1ea..b1d0edff0c04 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1970,20 +1970,22 @@ _GLOBAL(hmt_start_secondary) blr #endif -#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) +#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP) _GLOBAL(smp_release_cpus) /* All secondary cpus are spinning on a common * spinloop, release them all now so they can start * to spin on their individual paca spinloops. * For non SMP kernels, the secondary cpus never * get out of the common spinloop. + * XXX This does nothing useful on iSeries, secondaries are + * already waiting on their paca. */ li r3,1 LOADADDR(r5,__secondary_hold_spinloop) std r3,0(r5) sync blr -#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */ +#endif /* CONFIG_SMP */ /* diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index ca8acf671e46..acf826043e39 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -154,7 +154,7 @@ struct screen_info screen_info = { .orig_video_points = 16 }; -#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) +#ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -307,7 +307,7 @@ static void __init setup_cpu_maps(void) systemcfg->processorCount = num_present_cpus(); } -#endif /* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */ +#endif /* CONFIG_SMP */ #ifdef CONFIG_PPC_MULTIPLATFORM @@ -611,7 +611,7 @@ void __init setup_system(void) parse_early_param(); #endif /* !CONFIG_PPC_ISERIES */ -#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) +#ifdef CONFIG_SMP /* * iSeries has already initialized the cpu maps at this point. */ @@ -621,7 +621,7 @@ void __init setup_system(void) * we can map physical -> logical CPU ids */ smp_release_cpus(); -#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */ +#endif printk("Starting Linux PPC64 %s\n", system_utsname.version); From c0a59491daca7db11d49edad1a1cefaaa7120a9e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:56:09 +1000 Subject: [PATCH 0119/1940] ppc64 iSeries: Create a fake flat device tree on iSeries This patch adds infrastructure for creating a fake flattened device tree on iSeries. We also need to build prom.o for iSeries which means we'll always need it. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 137 ++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 49d0f9999682..99e4307affd6 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -912,7 +912,144 @@ struct machdep_calls __initdata iseries_md = { /* XXX Implement enable_pmcs for iSeries */ }; +struct blob { + unsigned char data[PAGE_SIZE]; + unsigned long next; +}; + +struct iseries_flat_dt { + struct boot_param_header header; + u64 reserve_map[2]; + struct blob dt; + struct blob strings; +}; + +struct iseries_flat_dt iseries_dt; + +void dt_init(struct iseries_flat_dt *dt) +{ + dt->header.off_mem_rsvmap = + offsetof(struct iseries_flat_dt, reserve_map); + dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt); + dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings); + dt->header.totalsize = sizeof(struct iseries_flat_dt); + dt->header.dt_strings_size = sizeof(struct blob); + + /* There is no notion of hardware cpu id on iSeries */ + dt->header.boot_cpuid_phys = smp_processor_id(); + + dt->dt.next = (unsigned long)&dt->dt.data; + dt->strings.next = (unsigned long)&dt->strings.data; + + dt->header.magic = OF_DT_HEADER; + dt->header.version = 0x10; + dt->header.last_comp_version = 0x10; + + dt->reserve_map[0] = 0; + dt->reserve_map[1] = 0; +} + +void dt_check_blob(struct blob *b) +{ + if (b->next >= (unsigned long)&b->next) { + DBG("Ran out of space in flat device tree blob!\n"); + BUG(); + } +} + +void dt_push_u32(struct iseries_flat_dt *dt, u32 value) +{ + *((u32*)dt->dt.next) = value; + dt->dt.next += sizeof(u32); + + dt_check_blob(&dt->dt); +} + +void dt_push_u64(struct iseries_flat_dt *dt, u64 value) +{ + *((u64*)dt->dt.next) = value; + dt->dt.next += sizeof(u64); + + dt_check_blob(&dt->dt); +} + +unsigned long dt_push_bytes(struct blob *blob, char *data, int len) +{ + unsigned long start = blob->next - (unsigned long)blob->data; + + memcpy((char *)blob->next, data, len); + blob->next = _ALIGN(blob->next + len, 4); + + dt_check_blob(blob); + + return start; +} + +void dt_start_node(struct iseries_flat_dt *dt, char *name) +{ + dt_push_u32(dt, OF_DT_BEGIN_NODE); + dt_push_bytes(&dt->dt, name, strlen(name) + 1); +} + +#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) + +void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len) +{ + unsigned long offset; + + dt_push_u32(dt, OF_DT_PROP); + + /* Length of the data */ + dt_push_u32(dt, len); + + /* Put the property name in the string blob. */ + offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1); + + /* The offset of the properties name in the string blob. */ + dt_push_u32(dt, (u32)offset); + + /* The actual data. */ + dt_push_bytes(&dt->dt, data, len); +} + +void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data) +{ + dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ +} + +void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u32)); +} + +void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u64)); +} + +void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n) +{ + dt_prop(dt, name, (char *)data, sizeof(u64) * n); +} + +void dt_prop_empty(struct iseries_flat_dt *dt, char *name) +{ + dt_prop(dt, name, NULL, 0); +} + +void build_flat_dt(struct iseries_flat_dt *dt) +{ + dt_init(dt); + + dt_start_node(dt, ""); + dt_end_node(dt); + + dt_push_u32(dt, OF_DT_END); +} + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); + + build_flat_dt(&iseries_dt); } From 4762713a93fa8706c31b0897c1340e7dc282d8fb Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 14:59:04 +1000 Subject: [PATCH 0120/1940] ppc64 iSeries: Call early_setup() on iSeries Misc steps to incorporate the flat device tree on iSeries. - define iseries_probe() - call build_iSeries_Memory_Map() earlier - return __pa() of the flat device tree from iSeries_early_setup() - actually call early_setup() for iSeries - add iseries_md to machdep_calls - build prom.o for iSeries - enable /proc/device-tree for iSeries Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/Kconfig | 1 - arch/ppc64/kernel/Makefile | 4 ++-- arch/ppc64/kernel/head.S | 1 + arch/ppc64/kernel/iSeries_setup.c | 22 +++++++++++++++------- arch/ppc64/kernel/setup.c | 9 ++++----- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 32951bfc7f65..246212115a48 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -357,7 +357,6 @@ config HOTPLUG_CPU config PROC_DEVICETREE bool "Support for Open Firmware device tree in /proc" - depends on !PPC_ISERIES help This option adds a device-tree directory under /proc which contains an image of the device tree that the kernel copies from Open diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 813718df4f82..afadb6e4a6dc 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -11,7 +11,7 @@ obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ - iommu.o sysfs.o vdso.o pmc.o firmware.o + iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o @@ -27,7 +27,7 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o -obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o +obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index b1d0edff0c04..eb526c480b6c 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1364,6 +1364,7 @@ _STATIC(__start_initialization_iSeries) addi r2,r2,0x4000 bl .iSeries_early_setup + bl .early_setup /* relocation is on at this point */ diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 99e4307affd6..27faf4f0967a 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -359,12 +359,6 @@ static void __init iSeries_init_early(void) */ iommu_init_early_iSeries(); - /* - * Initialize the table which translate Linux physical addresses to - * AS/400 absolute addresses - */ - build_iSeries_Memory_Map(); - iSeries_get_cmdline(); /* Save unparsed command line copy for /proc/cmdline */ @@ -894,6 +888,11 @@ static int iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif +static int __init iseries_probe(int platform) +{ + return PLATFORM_ISERIES_LPAR == platform; +} + struct machdep_calls __initdata iseries_md = { .setup_arch = iSeries_setup_arch, .get_cpuinfo = iSeries_get_cpuinfo, @@ -909,6 +908,7 @@ struct machdep_calls __initdata iseries_md = { .get_rtc_time = iSeries_get_rtc_time, .calibrate_decr = iSeries_calibrate_decr, .progress = iSeries_progress, + .probe = iseries_probe, /* XXX Implement enable_pmcs for iSeries */ }; @@ -1047,9 +1047,17 @@ void build_flat_dt(struct iseries_flat_dt *dt) dt_push_u32(dt, OF_DT_END); } -void __init iSeries_early_setup(void) +void * __init iSeries_early_setup(void) { iSeries_fixup_klimit(); + /* + * Initialize the table which translate Linux physical addresses to + * AS/400 absolute addresses + */ + build_iSeries_Memory_Map(); + build_flat_dt(&iseries_dt); + + return (void *) __pa(&iseries_dt); } diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index acf826043e39..6c1cd3bab28e 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -309,13 +309,11 @@ static void __init setup_cpu_maps(void) } #endif /* CONFIG_SMP */ - -#ifdef CONFIG_PPC_MULTIPLATFORM - extern struct machdep_calls pSeries_md; extern struct machdep_calls pmac_md; extern struct machdep_calls maple_md; extern struct machdep_calls bpa_md; +extern struct machdep_calls iseries_md; /* Ultimately, stuff them in an elf section like initcalls... */ static struct machdep_calls __initdata *machines[] = { @@ -330,6 +328,9 @@ static struct machdep_calls __initdata *machines[] = { #endif /* CONFIG_PPC_MAPLE */ #ifdef CONFIG_PPC_BPA &bpa_md, +#endif +#ifdef CONFIG_PPC_ISERIES + &iseries_md, #endif NULL }; @@ -534,8 +535,6 @@ static void __init check_for_initrd(void) #endif /* CONFIG_BLK_DEV_INITRD */ } -#endif /* CONFIG_PPC_MULTIPLATFORM */ - /* * Do some initial setup of the system. The parameters are those which * were passed in from the bootloader. From 3ab42407fe0628c7880b21eff057566390865319 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 15:00:20 +1000 Subject: [PATCH 0121/1940] ppc64 iSeries: Move memory setup into iSeries device tree This patch adds the required nodes to the iSeries device tree to allow early_init_devtree() to do the lmb setup for us. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 27faf4f0967a..639f400d6b0c 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -376,11 +376,6 @@ static void __init iSeries_init_early(void) } } - lmb_init(); - lmb_add(0, systemcfg->physicalMemorySize); - lmb_analyze(); - lmb_reserve(0, __pa(klimit)); - /* Initialize machine-dependency vectors */ #ifdef CONFIG_SMP smp_init_iSeries(); @@ -1039,9 +1034,24 @@ void dt_prop_empty(struct iseries_flat_dt *dt, char *name) void build_flat_dt(struct iseries_flat_dt *dt) { + u64 tmp[2]; + dt_init(dt); dt_start_node(dt, ""); + + dt_prop_u32(dt, "#address-cells", 2); + dt_prop_u32(dt, "#size-cells", 2); + + /* /memory */ + dt_start_node(dt, "memory@0"); + dt_prop_str(dt, "name", "memory"); + dt_prop_str(dt, "device_type", "memory"); + tmp[0] = 0; + tmp[1] = systemcfg->physicalMemorySize; + dt_prop_u64_list(dt, "reg", tmp, 2); + dt_end_node(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); From 47db360328582000a7a46390cfa385b8df07b44f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 15:01:49 +1000 Subject: [PATCH 0122/1940] ppc64 iSeries: Move setup of systemcfg->platform into iSeries device tree Add /chosen/linux,platform to the device tree so we can remove iSeries specific code in setup_system() to set systemcfg->platform. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 5 +++++ arch/ppc64/kernel/setup.c | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 639f400d6b0c..4895f674a4ba 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -1052,6 +1052,11 @@ void build_flat_dt(struct iseries_flat_dt *dt) dt_prop_u64_list(dt, "reg", tmp, 2); dt_end_node(dt); + /* /chosen */ + dt_start_node(dt, "chosen"); + dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); + dt_end_node(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 6c1cd3bab28e..776b55b45e1b 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -543,14 +543,6 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); -#ifdef CONFIG_PPC_ISERIES - /* pSeries systems are identified in prom.c via OF. */ - if (itLpNaca.xLparInstalled == 1) - systemcfg->platform = PLATFORM_ISERIES_LPAR; - - ppc_md.init_early(); -#else /* CONFIG_PPC_ISERIES */ - /* * Unflatten the device-tree passed by prom_init or kexec */ @@ -608,7 +600,6 @@ void __init setup_system(void) strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); parse_early_param(); -#endif /* !CONFIG_PPC_ISERIES */ #ifdef CONFIG_SMP /* From 95b293800859886b602e31c8926a840530a82971 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 Sep 2005 15:03:10 +1000 Subject: [PATCH 0123/1940] ppc64 iSeries: Define /cpus in iSeries device tree Add the /cpus node and nodes for each cpu, as well as cache size properties, reg propery, "linux,boot-cpu", and timebase/clock frequency. With those properties in place we can remove: - setup_iSeries_cache_sizes() - code in iSeries_setup_arch() to calculate timebase etc. - iSeries_calibrate_decr() - smp_iSeries_numProcs() and simplify smp_iSeries_probe() Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 178 +++++++++--------------------- arch/ppc64/kernel/iSeries_smp.c | 30 +---- arch/ppc64/kernel/time.c | 2 +- 3 files changed, 57 insertions(+), 153 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 4895f674a4ba..cadfc623a838 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -74,7 +74,6 @@ extern void hvlog(char *fmt, ...); extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); -static void setup_iSeries_cache_sizes(void); static int iseries_shared_idle(void); static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI @@ -84,14 +83,6 @@ static void iSeries_pci_final_fixup(void) { } #endif /* Global Variables */ -static unsigned long procFreqHz; -static unsigned long procFreqMhz; -static unsigned long procFreqMhzHundreths; - -static unsigned long tbFreqHz; -static unsigned long tbFreqMhz; -static unsigned long tbFreqMhzHundreths; - int piranha_simulator; extern int rd_size; /* Defined in drivers/block/rd.c */ @@ -343,12 +334,6 @@ static void __init iSeries_init_early(void) iSeries_recal_tb = get_tb(); iSeries_recal_titan = HvCallXm_loadTod(); - /* - * Cache sizes must be initialized before hpte_init_iSeries is called - * as the later need them for flush_icache_range() - */ - setup_iSeries_cache_sizes(); - /* * Initialize the hash table management pointers */ @@ -580,47 +565,6 @@ static void __init build_iSeries_Memory_Map(void) systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk); } -/* - * Set up the variables that describe the cache line sizes - * for this machine. - */ -static void __init setup_iSeries_cache_sizes(void) -{ - unsigned int i, n; - unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; - - systemcfg->icache_size = - ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024; - systemcfg->icache_line_size = - ppc64_caches.iline_size = - xIoHriProcessorVpd[procIx].xInstCacheOperandSize; - systemcfg->dcache_size = - ppc64_caches.dsize = - xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024; - systemcfg->dcache_line_size = - ppc64_caches.dline_size = - xIoHriProcessorVpd[procIx].xDataCacheOperandSize; - ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size; - ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size; - - i = ppc64_caches.iline_size; - n = 0; - while ((i = (i / 2))) - ++n; - ppc64_caches.log_iline_size = n; - - i = ppc64_caches.dline_size; - n = 0; - while ((i = (i / 2))) - ++n; - ppc64_caches.log_dline_size = n; - - printk("D-cache line size = %d\n", - (unsigned int)ppc64_caches.dline_size); - printk("I-cache line size = %d\n", - (unsigned int)ppc64_caches.iline_size); -} - /* * Document me. */ @@ -636,36 +580,14 @@ static void __init iSeries_setup_arch(void) printk(KERN_INFO "Using dedicated idle loop\n"); } - /* Add an eye catcher and the systemcfg layout version number */ - strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); - systemcfg->version.major = SYSTEMCFG_MAJOR; - systemcfg->version.minor = SYSTEMCFG_MINOR; - /* Setup the Lp Event Queue */ setup_hvlpevent_queue(); - /* Compute processor frequency */ - procFreqHz = ((1UL << 34) * 1000000) / - xIoHriProcessorVpd[procIx].xProcFreq; - procFreqMhz = procFreqHz / 1000000; - procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100); - ppc_proc_freq = procFreqHz; - - /* Compute time base frequency */ - tbFreqHz = ((1UL << 32) * 1000000) / - xIoHriProcessorVpd[procIx].xTimeBaseFreq; - tbFreqMhz = tbFreqHz / 1000000; - tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100); - ppc_tb_freq = tbFreqHz; - printk("Max logical processors = %d\n", itVpdAreas.xSlicMaxLogicalProcs); printk("Max physical processors = %d\n", itVpdAreas.xSlicMaxPhysicalProcs); - printk("Processor frequency = %lu.%02lu\n", procFreqMhz, - procFreqMhzHundreths); - printk("Time base frequency = %lu.%02lu\n", tbFreqMhz, - tbFreqMhzHundreths); + systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; printk("Processor version = %x\n", systemcfg->processor); } @@ -709,49 +631,6 @@ static void iSeries_halt(void) mf_power_off(); } -/* - * void __init iSeries_calibrate_decr() - * - * Description: - * This routine retrieves the internal processor frequency from the VPD, - * and sets up the kernel timer decrementer based on that value. - * - */ -static void __init iSeries_calibrate_decr(void) -{ - unsigned long cyclesPerUsec; - struct div_result divres; - - /* Compute decrementer (and TB) frequency in cycles/sec */ - cyclesPerUsec = ppc_tb_freq / 1000000; - - /* - * Set the amount to refresh the decrementer by. This - * is the number of decrementer ticks it takes for - * 1/HZ seconds. - */ - tb_ticks_per_jiffy = ppc_tb_freq / HZ; - -#if 0 - /* TEST CODE FOR ADJTIME */ - tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000; - /* END OF TEST CODE */ -#endif - - /* - * tb_ticks_per_sec = freq; would give better accuracy - * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures - * that jiffies (and xtime) will match the time returned - * by do_gettimeofday. - */ - tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; - tb_ticks_per_usec = cyclesPerUsec; - tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); - div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres); - tb_to_xs = divres.result_low; - setup_default_decr(); -} - static void __init iSeries_progress(char * st, unsigned short code) { printk("Progress: [%04x] - %s\n", (unsigned)code, st); @@ -901,7 +780,7 @@ struct machdep_calls __initdata iseries_md = { .get_boot_time = iSeries_get_boot_time, .set_rtc_time = iSeries_set_rtc_time, .get_rtc_time = iSeries_get_rtc_time, - .calibrate_decr = iSeries_calibrate_decr, + .calibrate_decr = generic_calibrate_decr, .progress = iSeries_progress, .probe = iseries_probe, /* XXX Implement enable_pmcs for iSeries */ @@ -1032,6 +911,57 @@ void dt_prop_empty(struct iseries_flat_dt *dt, char *name) dt_prop(dt, name, NULL, 0); } +void dt_cpus(struct iseries_flat_dt *dt) +{ + unsigned char buf[32]; + unsigned char *p; + unsigned int i, index; + struct IoHriProcessorVpd *d; + + /* yuck */ + snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); + p = strchr(buf, ' '); + if (!p) p = buf + strlen(buf); + + dt_start_node(dt, "cpus"); + dt_prop_u32(dt, "#address-cells", 1); + dt_prop_u32(dt, "#size-cells", 0); + + for (i = 0; i < NR_CPUS; i++) { + if (paca[i].lppaca.dyn_proc_status >= 2) + continue; + + snprintf(p, 32 - (p - buf), "@%d", i); + dt_start_node(dt, buf); + + dt_prop_str(dt, "device_type", "cpu"); + + index = paca[i].lppaca.dyn_hv_phys_proc_index; + d = &xIoHriProcessorVpd[index]; + + dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); + dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); + + dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); + dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); + + /* magic conversions to Hz copied from old code */ + dt_prop_u32(dt, "clock-frequency", + ((1UL << 34) * 1000000) / d->xProcFreq); + dt_prop_u32(dt, "timebase-frequency", + ((1UL << 32) * 1000000) / d->xTimeBaseFreq); + + dt_prop_u32(dt, "reg", i); + + if (dt->header.boot_cpuid_phys == i) + dt_prop_empty(dt, "linux,boot-cpu"); + + dt_end_node(dt); + } + + dt_end_node(dt); +} + void build_flat_dt(struct iseries_flat_dt *dt) { u64 tmp[2]; @@ -1057,6 +987,8 @@ void build_flat_dt(struct iseries_flat_dt *dt) dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); dt_end_node(dt); + dt_cpus(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c index f74386e31638..f982e5b805f4 100644 --- a/arch/ppc64/kernel/iSeries_smp.c +++ b/arch/ppc64/kernel/iSeries_smp.c @@ -82,35 +82,9 @@ static void smp_iSeries_message_pass(int target, int msg) } } -static int smp_iSeries_numProcs(void) -{ - unsigned np, i; - - np = 0; - for (i=0; i < NR_CPUS; ++i) { - if (paca[i].lppaca.dyn_proc_status < 2) { - cpu_set(i, cpu_possible_map); - cpu_set(i, cpu_present_map); - cpu_set(i, cpu_sibling_map[i]); - ++np; - } - } - return np; -} - static int smp_iSeries_probe(void) { - unsigned i; - unsigned np = 0; - - for (i=0; i < NR_CPUS; ++i) { - if (paca[i].lppaca.dyn_proc_status < 2) { - /*paca[i].active = 1;*/ - ++np; - } - } - - return np; + return cpus_weight(cpu_possible_map); } static void smp_iSeries_kick_cpu(int nr) @@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops = { void __init smp_init_iSeries(void) { smp_ops = &iSeries_smp_ops; - systemcfg->processorCount = smp_iSeries_numProcs(); } - diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index fb4bf0ad8f32..7f63755eddfd 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -465,7 +465,7 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) || defined(CONFIG_PPC_ISERIES) void __init generic_calibrate_decr(void) { struct device_node *cpu; From 3d8a66cc9ec475baaf22de139deff67ffe8e7cf2 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 Sep 2005 15:17:30 +1000 Subject: [PATCH 0124/1940] ppc64 iSeries: Don't create linux,boot-cpu This is obsolete. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index cadfc623a838..9daf734adbd5 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -953,9 +953,6 @@ void dt_cpus(struct iseries_flat_dt *dt) dt_prop_u32(dt, "reg", i); - if (dt->header.boot_cpuid_phys == i) - dt_prop_empty(dt, "linux,boot-cpu"); - dt_end_node(dt); } From 463eb297401eeb174db3fdf37a87911b576b3993 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 23 Sep 2005 11:39:07 -0600 Subject: [PATCH 0125/1940] [IA64] respect ACPI producer/consumer flag for PCI root bridges Address space resources for ACPI devices have a producer/consumer flag. All devices "consume" the indicated address space. If the resource is marked as a "producer", the range is also passed on to child devices. We currently ignore this flag when setting up MMIO and I/O port windows for PCI root bridges, so we could mistakenly interpret a "consumed-only" range, like CSR space for the device itself, as a window that is routed to children. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/pci/pci.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 9b5de589b82f..564319e29bd5 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -191,6 +191,29 @@ add_io_space (struct acpi_resource_address64 *addr) return IO_SPACE_BASE(i); } +static acpi_status __devinit resource_to_window(struct acpi_resource *resource, + struct acpi_resource_address64 *addr) +{ + acpi_status status; + + /* + * We're only interested in _CRS descriptors that are + * - address space descriptors for memory or I/O space + * - non-zero size + * - producers, i.e., the address space is routed downstream, + * not consumed by the bridge itself + */ + status = acpi_resource_to_address64(resource, addr); + if (ACPI_SUCCESS(status) && + (addr->resource_type == ACPI_MEMORY_RANGE || + addr->resource_type == ACPI_IO_RANGE) && + addr->address_length && + addr->producer_consumer == ACPI_PRODUCER) + return AE_OK; + + return AE_ERROR; +} + static acpi_status __devinit count_window (struct acpi_resource *resource, void *data) { @@ -198,11 +221,9 @@ count_window (struct acpi_resource *resource, void *data) struct acpi_resource_address64 addr; acpi_status status; - status = acpi_resource_to_address64(resource, &addr); + status = resource_to_window(resource, &addr); if (ACPI_SUCCESS(status)) - if (addr.resource_type == ACPI_MEMORY_RANGE || - addr.resource_type == ACPI_IO_RANGE) - (*windows)++; + (*windows)++; return AE_OK; } @@ -221,13 +242,11 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) unsigned long flags, offset = 0; struct resource *root; - status = acpi_resource_to_address64(res, &addr); + /* Return AE_OK for non-window resources to keep scanning for more */ + status = resource_to_window(res, &addr); if (!ACPI_SUCCESS(status)) return AE_OK; - if (!addr.address_length) - return AE_OK; - if (addr.resource_type == ACPI_MEMORY_RANGE) { flags = IORESOURCE_MEM; root = &iomem_resource; From 61b9cf7c6cf5077c40ad37480fa56f6574af3db5 Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Fri, 23 Sep 2005 12:31:53 -0500 Subject: [PATCH 0126/1940] [IA64-SGI] fix sn_pci_legacy_read/fix sn_pci_legacy_write This patch adds a #define for SN_SAL_IOIF_PCI_SAFE and makes that the preferred method of implementing sn_pci_legacy_read() and sn_pci_legacy_write(). This SAL call has been present in SGI proms since version 4.10. If the SN_SAL_IOIF_PCI_SAFE call fails, revert to the previous code for compatability with older proms. Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/sn/pci/pci_dma.c | 46 ++++++++++++++++++++++++++++++++++++ include/asm-ia64/sn/sn_sal.h | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 0e4b9ad9ef02..abdf6eea6ac8 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -326,6 +326,29 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) { unsigned long addr; int ret; + struct ia64_sal_retval isrv; + + /* + * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work + * around hw issues at the pci bus level. SGI proms older than + * 4.10 don't implment this. + */ + + SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, + pci_domain_nr(bus), bus->number, + 0, /* io */ + 0, /* read */ + port, size, __pa(val)); + + if (isrv.status == 0) + return size; + + /* + * If the above failed, retry using the SAL_PROBE call which should + * be present in all proms (but which cannot work round PCI chipset + * bugs). This code is retained for compatability with old + * pre-4.10 proms, and should be removed at some point in the future. + */ if (!SN_PCIBUS_BUSSOFT(bus)) return -ENODEV; @@ -349,6 +372,29 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) int ret = size; unsigned long paddr; unsigned long *addr; + struct ia64_sal_retval isrv; + + /* + * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work + * around hw issues at the pci bus level. SGI proms older than + * 4.10 don't implment this. + */ + + SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, + pci_domain_nr(bus), bus->number, + 0, /* io */ + 1, /* write */ + port, size, __pa(&val)); + + if (isrv.status == 0) + return size; + + /* + * If the above failed, retry using the SAL_PROBE call which should + * be present in all proms (but which cannot work round PCI chipset + * bugs). This code is retained for compatability with old + * pre-4.10 proms, and should be removed at some point in the future. + */ if (!SN_PCIBUS_BUSSOFT(bus)) { ret = -ENODEV; diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index fea35b33d4e4..b2d32837723f 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -67,7 +67,7 @@ #define SN_SAL_IOIF_INTERRUPT 0x0200004a #define SN_SAL_HWPERF_OP 0x02000050 // lock #define SN_SAL_IOIF_ERROR_INTERRUPT 0x02000051 - +#define SN_SAL_IOIF_PCI_SAFE 0x02000052 #define SN_SAL_IOIF_SLOT_ENABLE 0x02000053 #define SN_SAL_IOIF_SLOT_DISABLE 0x02000054 #define SN_SAL_IOIF_GET_HUBDEV_INFO 0x02000055 From 99a2657a29e2d623c3568cd86b27cac13fb63140 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 25 Sep 2005 13:25:41 +1000 Subject: [PATCH 0127/1940] drm: use kernel macros Make some of the DRM_ macros use the real kernel macros. Signed-off-by: Dave Airlie --- drivers/char/drm/drmP.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index cf58a526a030..79221783a14c 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -228,9 +228,9 @@ /** \name Internal types and structures */ /*@{*/ -#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) -#define DRM_MIN(a,b) ((a)<(b)?(a):(b)) -#define DRM_MAX(a,b) ((a)>(b)?(a):(b)) +#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) +#define DRM_MIN(a,b) min(a,b) +#define DRM_MAX(a,b) max(a,b) #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) From b5e89ed53ed8d24f83ba1941c07382af00ed238e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 25 Sep 2005 14:28:13 +1000 Subject: [PATCH 0128/1940] drm: lindent the drm directory. I've been threatening this for a while, so no point hanging around. This lindents the DRM code which was always really bad in tabbing department. I've also fixed some misnamed files in comments and removed some trailing whitespace. Signed-off-by: Dave Airlie --- drivers/char/drm/ati_pcigart.c | 123 +- drivers/char/drm/drm.h | 293 +- drivers/char/drm/drmP.h | 845 +- drivers/char/drm/drm_agpsupport.c | 150 +- drivers/char/drm/drm_auth.c | 68 +- drivers/char/drm/drm_bufs.c | 883 +- drivers/char/drm/drm_context.c | 304 +- drivers/char/drm/drm_dma.c | 87 +- drivers/char/drm/drm_drawable.c | 8 +- drivers/char/drm/drm_drv.c | 343 +- drivers/char/drm/drm_fops.c | 293 +- drivers/char/drm/drm_init.c | 7 +- drivers/char/drm/drm_ioc32.c | 223 +- drivers/char/drm/drm_ioctl.c | 168 +- drivers/char/drm/drm_irq.c | 169 +- drivers/char/drm/drm_lock.c | 181 +- drivers/char/drm/drm_memory.c | 54 +- drivers/char/drm/drm_memory.h | 73 +- drivers/char/drm/drm_memory_debug.h | 224 +- drivers/char/drm/drm_os_linux.h | 17 +- drivers/char/drm/drm_pci.c | 10 +- drivers/char/drm/drm_pciids.h | 1 - drivers/char/drm/drm_proc.c | 272 +- drivers/char/drm/drm_sarea.h | 30 +- drivers/char/drm/drm_scatter.c | 179 +- drivers/char/drm/drm_stub.c | 112 +- drivers/char/drm/drm_vm.c | 365 +- drivers/char/drm/ffb_context.c | 230 +- drivers/char/drm/ffb_drv.c | 143 +- drivers/char/drm/ffb_drv.h | 439 +- drivers/char/drm/i810_dma.c | 1147 +- drivers/char/drm/i810_drm.h | 75 +- drivers/char/drm/i810_drv.c | 60 +- drivers/char/drm/i810_drv.h | 38 +- drivers/char/drm/i830_dma.c | 1312 ++- drivers/char/drm/i830_drm.h | 90 +- drivers/char/drm/i830_drv.c | 59 +- drivers/char/drm/i830_drv.h | 65 +- drivers/char/drm/i830_irq.c | 137 +- drivers/char/drm/i915_dma.c | 65 +- drivers/char/drm/i915_drv.c | 61 +- drivers/char/drm/i915_drv.h | 13 +- drivers/char/drm/i915_ioc32.c | 64 +- drivers/char/drm/i915_mem.c | 8 +- drivers/char/drm/mga_dma.c | 507 +- drivers/char/drm/mga_drm.h | 142 +- drivers/char/drm/mga_drv.c | 75 +- drivers/char/drm/mga_drv.h | 42 +- drivers/char/drm/mga_ioc32.c | 62 +- drivers/char/drm/mga_irq.c | 42 +- drivers/char/drm/mga_state.c | 890 +- drivers/char/drm/mga_ucode.h | 16070 +++++++++++++------------- drivers/char/drm/mga_warp.c | 116 +- drivers/char/drm/r128_cce.c | 590 +- drivers/char/drm/r128_drm.h | 32 +- drivers/char/drm/r128_drv.c | 60 +- drivers/char/drm/r128_drv.h | 67 +- drivers/char/drm/r128_ioc32.c | 35 +- drivers/char/drm/r128_irq.c | 53 +- drivers/char/drm/r128_state.c | 1378 ++- drivers/char/drm/r300_cmdbuf.c | 502 +- drivers/char/drm/r300_reg.h | 192 +- drivers/char/drm/radeon_cp.c | 2462 ++-- drivers/char/drm/radeon_drm.h | 276 +- drivers/char/drm/radeon_drv.c | 61 +- drivers/char/drm/radeon_drv.h | 145 +- drivers/char/drm/radeon_ioc32.c | 51 +- drivers/char/drm/radeon_irq.c | 127 +- drivers/char/drm/radeon_mem.c | 148 +- drivers/char/drm/radeon_state.c | 2467 ++-- drivers/char/drm/savage_bci.c | 201 +- drivers/char/drm/savage_drm.h | 53 +- drivers/char/drm/savage_drv.c | 56 +- drivers/char/drm/savage_drv.h | 58 +- drivers/char/drm/savage_state.c | 483 +- drivers/char/drm/sis_drm.h | 2 +- drivers/char/drm/sis_drv.c | 58 +- drivers/char/drm/sis_drv.h | 10 +- drivers/char/drm/sis_ds.c | 82 +- drivers/char/drm/sis_ds.h | 40 +- drivers/char/drm/sis_mm.c | 132 +- drivers/char/drm/tdfx_drv.c | 52 +- drivers/char/drm/via_3d_reg.h | 1 - drivers/char/drm/via_dma.c | 261 +- drivers/char/drm/via_drm.h | 4 +- drivers/char/drm/via_drv.c | 22 +- drivers/char/drm/via_drv.h | 21 +- drivers/char/drm/via_irq.c | 102 +- drivers/char/drm/via_map.c | 4 +- drivers/char/drm/via_mm.c | 17 +- drivers/char/drm/via_verifier.c | 481 +- drivers/char/drm/via_verifier.h | 22 +- drivers/char/drm/via_video.c | 30 +- 93 files changed, 19159 insertions(+), 19113 deletions(-) diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 957596c63934..d07ce96e9f4b 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c @@ -1,5 +1,5 @@ /** - * \file ati_pcigart.h + * \file ati_pcigart.c * ATI PCI GART support * * \author Gareth Hughes @@ -52,87 +52,91 @@ # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ -static unsigned long drm_ati_alloc_pcigart_table( void ) +static unsigned long drm_ati_alloc_pcigart_table(void) { unsigned long address; struct page *page; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER ); - if ( address == 0UL ) { + address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER); + if (address == 0UL) { return 0; } - page = virt_to_page( address ); + page = virt_to_page(address); - for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { get_page(page); - SetPageReserved( page ); + SetPageReserved(page); } - DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address ); + DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); return address; } -static void drm_ati_free_pcigart_table( unsigned long address ) +static void drm_ati_free_pcigart_table(unsigned long address) { struct page *page; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - page = virt_to_page( address ); + page = virt_to_page(address); - for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { __put_page(page); - ClearPageReserved( page ); + ClearPageReserved(page); } - free_pages( address, ATI_PCIGART_TABLE_ORDER ); + free_pages(address, ATI_PCIGART_TABLE_ORDER); } -int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_cleanup(drm_device_t * dev, + drm_ati_pcigart_info * gart_info) { drm_sg_mem_t *entry = dev->sg; unsigned long pages; int i; /* we need to support large memory configurations */ - if ( !entry ) { - DRM_ERROR( "no scatter/gather memory!\n" ); + if (!entry) { + DRM_ERROR("no scatter/gather memory!\n"); return 0; } if (gart_info->bus_addr) { - if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) { + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { pci_unmap_single(dev->pdev, gart_info->bus_addr, ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, PCI_DMA_TODEVICE); } - pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) - ? entry->pages : ATI_MAX_PCIGART_PAGES; + pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) + ? entry->pages : ATI_MAX_PCIGART_PAGES; - for ( i = 0 ; i < pages ; i++ ) { - if ( !entry->busaddr[i] ) break; + for (i = 0; i < pages; i++) { + if (!entry->busaddr[i]) + break; pci_unmap_single(dev->pdev, entry->busaddr[i], PAGE_SIZE, PCI_DMA_TODEVICE); } - - if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) - gart_info->bus_addr=0; + + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) + gart_info->bus_addr = 0; } - if (gart_info->gart_table_location==DRM_ATI_GART_MAIN && gart_info->addr) { + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN + && gart_info->addr) { drm_ati_free_pcigart_table(gart_info->addr); - gart_info->addr=0; + gart_info->addr = 0; } return 1; } + EXPORT_SYMBOL(drm_ati_pcigart_cleanup); -int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) { drm_sg_mem_t *entry = dev->sg; unsigned long address = 0; @@ -140,58 +144,56 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) u32 *pci_gart, page_base, bus_address = 0; int i, j, ret = 0; - if ( !entry ) { - DRM_ERROR( "no scatter/gather memory!\n" ); + if (!entry) { + DRM_ERROR("no scatter/gather memory!\n"); goto done; } - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) - { + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); - + address = drm_ati_alloc_pcigart_table(); - if ( !address ) { - DRM_ERROR( "cannot allocate PCI GART page!\n" ); + if (!address) { + DRM_ERROR("cannot allocate PCI GART page!\n"); goto done; } - - if ( !dev->pdev ) { - DRM_ERROR( "PCI device unknown!\n" ); + + if (!dev->pdev) { + DRM_ERROR("PCI device unknown!\n"); goto done; } bus_address = pci_map_single(dev->pdev, (void *)address, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); + ATI_PCIGART_TABLE_PAGES * + PAGE_SIZE, PCI_DMA_TODEVICE); if (bus_address == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - drm_ati_free_pcigart_table( address ); + DRM_ERROR("unable to map PCIGART pages!\n"); + drm_ati_free_pcigart_table(address); address = 0; goto done; } - } - else - { + } else { address = gart_info->addr; bus_address = gart_info->bus_addr; - DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", bus_address, address); + DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", + bus_address, address); } - pci_gart = (u32 *)address; + pci_gart = (u32 *) address; - pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) - ? entry->pages : ATI_MAX_PCIGART_PAGES; + pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) + ? entry->pages : ATI_MAX_PCIGART_PAGES; - memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); + memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32)); - for ( i = 0 ; i < pages ; i++ ) { + for (i = 0; i < pages; i++) { /* we need to support large memory configurations */ entry->busaddr[i] = pci_map_single(dev->pdev, - page_address( entry->pagelist[i] ), - PAGE_SIZE, - PCI_DMA_TODEVICE); + page_address(entry-> + pagelist[i]), + PAGE_SIZE, PCI_DMA_TODEVICE); if (entry->busaddr[i] == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); + DRM_ERROR("unable to map PCIGART pages!\n"); drm_ati_pcigart_cleanup(dev, gart_info); address = 0; bus_address = 0; @@ -201,9 +203,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { if (gart_info->is_pcie) - *pci_gart = (cpu_to_le32(page_base)>>8) | 0xc; + *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; else - *pci_gart++ = cpu_to_le32( page_base ); + *pci_gart++ = cpu_to_le32(page_base); page_base += ATI_PCIGART_PAGE_SIZE; } } @@ -216,9 +218,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) mb(); #endif -done: + done: gart_info->addr = address; - gart_info->bus_addr = bus_address; + gart_info->bus_addr = bus_address; return ret; } + EXPORT_SYMBOL(drm_ati_pcigart_init); diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index fc6598a81acd..64d6237fdd0b 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h @@ -1,7 +1,7 @@ /** - * \file drm.h + * \file drm.h * Header for the Direct Rendering Manager - * + * * \author Rickard E. (Rik) Faith * * \par Acknowledgments: @@ -33,7 +33,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ - #ifndef _DRM_H_ #define _DRM_H_ @@ -56,7 +55,7 @@ #define ioctl(a,b,c) xf86ioctl(a,b,c) #else #include -#endif /* __FreeBSD__ && xf86ioctl */ +#endif /* __FreeBSD__ && xf86ioctl */ #define DRM_IOCTL_NR(n) ((n) & 0xff) #define DRM_IOC_VOID IOC_VOID #define DRM_IOC_READ IOC_OUT @@ -97,16 +96,14 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) - -typedef unsigned int drm_handle_t; -typedef unsigned int drm_context_t; -typedef unsigned int drm_drawable_t; -typedef unsigned int drm_magic_t; - +typedef unsigned int drm_handle_t; +typedef unsigned int drm_context_t; +typedef unsigned int drm_drawable_t; +typedef unsigned int drm_magic_t; /** * Cliprect. - * + * * \warning: If you change this structure, make sure you change * XF86DRIClipRectRec in the server as well * @@ -114,22 +111,21 @@ typedef unsigned int drm_magic_t; * backwards-compatibility reasons. */ typedef struct drm_clip_rect { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; } drm_clip_rect_t; - /** * Texture region, */ typedef struct drm_tex_region { - unsigned char next; - unsigned char prev; - unsigned char in_use; - unsigned char padding; - unsigned int age; + unsigned char next; + unsigned char prev; + unsigned char in_use; + unsigned char padding; + unsigned int age; } drm_tex_region_t; /** @@ -141,28 +137,26 @@ typedef struct drm_tex_region { */ typedef struct drm_hw_lock { __volatile__ unsigned int lock; /**< lock variable */ - char padding[60]; /**< Pad to cache line */ + char padding[60]; /**< Pad to cache line */ } drm_hw_lock_t; - /** * DRM_IOCTL_VERSION ioctl argument type. - * + * * \sa drmGetVersion(). */ typedef struct drm_version { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel;/**< Patch level */ + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ size_t name_len; /**< Length of name buffer */ - char __user *name; /**< Name of driver */ + char __user *name; /**< Name of driver */ size_t date_len; /**< Length of date buffer */ - char __user *date; /**< User-space buffer to hold date */ + char __user *date; /**< User-space buffer to hold date */ size_t desc_len; /**< Length of desc buffer */ - char __user *desc; /**< User-space buffer to hold desc */ + char __user *desc; /**< User-space buffer to hold desc */ } drm_version_t; - /** * DRM_IOCTL_GET_UNIQUE ioctl argument type. * @@ -170,21 +164,18 @@ typedef struct drm_version { */ typedef struct drm_unique { size_t unique_len; /**< Length of unique */ - char __user *unique; /**< Unique name for driver instantiation */ + char __user *unique; /**< Unique name for driver instantiation */ } drm_unique_t; - typedef struct drm_list { - int count; /**< Length of user-space structures */ - drm_version_t __user *version; + int count; /**< Length of user-space structures */ + drm_version_t __user *version; } drm_list_t; - typedef struct drm_block { - int unused; + int unused; } drm_block_t; - /** * DRM_IOCTL_CONTROL ioctl argument type. * @@ -196,44 +187,40 @@ typedef struct drm_control { DRM_RM_COMMAND, DRM_INST_HANDLER, DRM_UNINST_HANDLER - } func; - int irq; + } func; + int irq; } drm_control_t; - /** * Type of memory to map. */ typedef enum drm_map_type { - _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ - _DRM_REGISTERS = 1, /**< no caching, no core dump */ - _DRM_SHM = 2, /**< shared, cached */ - _DRM_AGP = 3, /**< AGP/GART */ + _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ + _DRM_REGISTERS = 1, /**< no caching, no core dump */ + _DRM_SHM = 2, /**< shared, cached */ + _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ - _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ + _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ } drm_map_type_t; - /** * Memory mapping flags. */ typedef enum drm_map_flags { - _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ - _DRM_READ_ONLY = 0x02, - _DRM_LOCKED = 0x04, /**< shared, cached, locked */ - _DRM_KERNEL = 0x08, /**< kernel requires access */ + _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ + _DRM_READ_ONLY = 0x02, + _DRM_LOCKED = 0x04, /**< shared, cached, locked */ + _DRM_KERNEL = 0x08, /**< kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ - _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40 /**< Removable mapping */ + _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ + _DRM_REMOVABLE = 0x40 /**< Removable mapping */ } drm_map_flags_t; - typedef struct drm_ctx_priv_map { - unsigned int ctx_id; /**< Context requesting private mapping */ - void *handle; /**< Handle of map */ + unsigned int ctx_id; /**< Context requesting private mapping */ + void *handle; /**< Handle of map */ } drm_ctx_priv_map_t; - /** * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls * argument type. @@ -241,30 +228,28 @@ typedef struct drm_ctx_priv_map { * \sa drmAddMap(). */ typedef struct drm_map { - unsigned long offset; /**< Requested physical address (0 for SAREA)*/ - unsigned long size; /**< Requested physical size (bytes) */ - drm_map_type_t type; /**< Type of memory to map */ + unsigned long offset; /**< Requested physical address (0 for SAREA)*/ + unsigned long size; /**< Requested physical size (bytes) */ + drm_map_type_t type; /**< Type of memory to map */ drm_map_flags_t flags; /**< Flags */ - void *handle; /**< User-space: "Handle" to pass to mmap() */ + void *handle; /**< User-space: "Handle" to pass to mmap() */ /**< Kernel-space: kernel-virtual address */ - int mtrr; /**< MTRR slot used */ - /* Private data */ + int mtrr; /**< MTRR slot used */ + /* Private data */ } drm_map_t; - /** * DRM_IOCTL_GET_CLIENT ioctl argument type. */ typedef struct drm_client { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - unsigned long pid; /**< Process ID */ - unsigned long uid; /**< User ID */ - unsigned long magic; /**< Magic */ - unsigned long iocs; /**< Ioctl count */ + int idx; /**< Which client desired? */ + int auth; /**< Is client authenticated? */ + unsigned long pid; /**< Process ID */ + unsigned long uid; /**< User ID */ + unsigned long magic; /**< Magic */ + unsigned long iocs; /**< Ioctl count */ } drm_client_t; - typedef enum { _DRM_STAT_LOCK, _DRM_STAT_OPENS, @@ -282,63 +267,58 @@ typedef enum { _DRM_STAT_DMA, /**< DMA */ _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ _DRM_STAT_MISSED /**< Missed DMA opportunity */ - - /* Add to the *END* of the list */ + /* Add to the *END* of the list */ } drm_stat_type_t; - /** * DRM_IOCTL_GET_STATS ioctl argument type. */ typedef struct drm_stats { unsigned long count; struct { - unsigned long value; + unsigned long value; drm_stat_type_t type; } data[15]; } drm_stats_t; - /** * Hardware locking flags. */ typedef enum drm_lock_flags { - _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ - _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ - _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ - _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ - /* These *HALT* flags aren't supported yet - -- they will be used to support the - full-screen DGA-like mode. */ + _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ + _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ + _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ + _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ + /* These *HALT* flags aren't supported yet + -- they will be used to support the + full-screen DGA-like mode. */ _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ } drm_lock_flags_t; - /** * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. - * + * * \sa drmGetLock() and drmUnlock(). */ typedef struct drm_lock { - int context; + int context; drm_lock_flags_t flags; } drm_lock_t; - /** * DMA flags * - * \warning + * \warning * These values \e must match xf86drm.h. * * \sa drm_dma. */ -typedef enum drm_dma_flags { - /* Flags for DMA buffer dispatch */ - _DRM_DMA_BLOCK = 0x01, /**< +typedef enum drm_dma_flags { + /* Flags for DMA buffer dispatch */ + _DRM_DMA_BLOCK = 0x01, /**< * Block until buffer dispatched. - * + * * \note The buffer may not yet have * been processed by the hardware -- * getting a hardware lock with the @@ -347,79 +327,73 @@ typedef enum drm_dma_flags { * processed. */ _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ - _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ + _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ - /* Flags for DMA buffer request */ - _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ - _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ - _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ + /* Flags for DMA buffer request */ + _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ + _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ + _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ } drm_dma_flags_t; - /** * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. * * \sa drmAddBufs(). */ typedef struct drm_buf_desc { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ + int count; /**< Number of buffers of this size */ + int size; /**< Size in bytes */ + int low_mark; /**< Low water mark */ + int high_mark; /**< High water mark */ enum { - _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ - _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ - _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ - _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */ - } flags; - unsigned long agp_start; /**< + _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ + _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ + _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */ + } flags; + unsigned long agp_start; /**< * Start address of where the AGP buffers are * in the AGP aperture */ } drm_buf_desc_t; - /** * DRM_IOCTL_INFO_BUFS ioctl argument type. */ typedef struct drm_buf_info { - int count; /**< Entries in list */ + int count; /**< Entries in list */ drm_buf_desc_t __user *list; } drm_buf_info_t; - /** * DRM_IOCTL_FREE_BUFS ioctl argument type. */ typedef struct drm_buf_free { - int count; - int __user *list; + int count; + int __user *list; } drm_buf_free_t; - /** * Buffer information * * \sa drm_buf_map. */ typedef struct drm_buf_pub { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - void __user *address; /**< Address of buffer */ + int idx; /**< Index into the master buffer list */ + int total; /**< Buffer size */ + int used; /**< Amount of buffer in use (for DMA) */ + void __user *address; /**< Address of buffer */ } drm_buf_pub_t; - /** * DRM_IOCTL_MAP_BUFS ioctl argument type. */ typedef struct drm_buf_map { - int count; /**< Length of the buffer list */ - void __user *virtual; /**< Mmap'd area in user-virtual */ + int count; /**< Length of the buffer list */ + void __user *virtual; /**< Mmap'd area in user-virtual */ drm_buf_pub_t __user *list; /**< Buffer information */ } drm_buf_map_t; - /** * DRM_IOCTL_DMA ioctl argument type. * @@ -428,61 +402,55 @@ typedef struct drm_buf_map { * \sa drmDMA(). */ typedef struct drm_dma { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - int __user *send_indices; /**< List of handles to buffers */ - int __user *send_sizes; /**< Lengths of data to send */ + int context; /**< Context handle */ + int send_count; /**< Number of buffers to send */ + int __user *send_indices; /**< List of handles to buffers */ + int __user *send_sizes; /**< Lengths of data to send */ drm_dma_flags_t flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - int __user *request_indices; /**< Buffer information */ - int __user *request_sizes; - int granted_count; /**< Number of buffers granted */ + int request_count; /**< Number of buffers requested */ + int request_size; /**< Desired size for buffers */ + int __user *request_indices; /**< Buffer information */ + int __user *request_sizes; + int granted_count; /**< Number of buffers granted */ } drm_dma_t; - typedef enum { _DRM_CONTEXT_PRESERVED = 0x01, - _DRM_CONTEXT_2DONLY = 0x02 + _DRM_CONTEXT_2DONLY = 0x02 } drm_ctx_flags_t; - /** * DRM_IOCTL_ADD_CTX ioctl argument type. * * \sa drmCreateContext() and drmDestroyContext(). */ typedef struct drm_ctx { - drm_context_t handle; + drm_context_t handle; drm_ctx_flags_t flags; } drm_ctx_t; - /** * DRM_IOCTL_RES_CTX ioctl argument type. */ typedef struct drm_ctx_res { - int count; - drm_ctx_t __user *contexts; + int count; + drm_ctx_t __user *contexts; } drm_ctx_res_t; - /** * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. */ typedef struct drm_draw { - drm_drawable_t handle; + drm_drawable_t handle; } drm_draw_t; - /** * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. */ typedef struct drm_auth { - drm_magic_t magic; + drm_magic_t magic; } drm_auth_t; - /** * DRM_IOCTL_IRQ_BUSID ioctl argument type. * @@ -495,24 +463,20 @@ typedef struct drm_irq_busid { int funcnum; /**< function number */ } drm_irq_busid_t; - typedef enum { - _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ - _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ - _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ + _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ } drm_vblank_seq_type_t; - #define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL - struct drm_wait_vblank_request { drm_vblank_seq_type_t type; unsigned int sequence; unsigned long signal; }; - struct drm_wait_vblank_reply { drm_vblank_seq_type_t type; unsigned int sequence; @@ -520,7 +484,6 @@ struct drm_wait_vblank_reply { long tval_usec; }; - /** * DRM_IOCTL_WAIT_VBLANK ioctl argument type. * @@ -531,7 +494,6 @@ typedef union drm_wait_vblank { struct drm_wait_vblank_reply reply; } drm_wait_vblank_t; - /** * DRM_IOCTL_AGP_ENABLE ioctl argument type. * @@ -541,7 +503,6 @@ typedef struct drm_agp_mode { unsigned long mode; /**< AGP mode */ } drm_agp_mode_t; - /** * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. * @@ -550,22 +511,20 @@ typedef struct drm_agp_mode { typedef struct drm_agp_buffer { unsigned long size; /**< In bytes -- will round to page boundary */ unsigned long handle; /**< Used for binding / unbinding */ - unsigned long type; /**< Type of memory to allocate */ - unsigned long physical; /**< Physical used by i810 */ + unsigned long type; /**< Type of memory to allocate */ + unsigned long physical; /**< Physical used by i810 */ } drm_agp_buffer_t; - /** * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. * * \sa drmAgpBind() and drmAgpUnbind(). */ typedef struct drm_agp_binding { - unsigned long handle; /**< From drm_agp_buffer */ + unsigned long handle; /**< From drm_agp_buffer */ unsigned long offset; /**< In bytes -- will round to page boundary */ } drm_agp_binding_t; - /** * DRM_IOCTL_AGP_INFO ioctl argument type. * @@ -574,20 +533,19 @@ typedef struct drm_agp_binding { * drmAgpVendorId() and drmAgpDeviceId(). */ typedef struct drm_agp_info { - int agp_version_major; - int agp_version_minor; - unsigned long mode; - unsigned long aperture_base; /* physical address */ - unsigned long aperture_size; /* bytes */ - unsigned long memory_allowed; /* bytes */ - unsigned long memory_used; + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /* physical address */ + unsigned long aperture_size; /* bytes */ + unsigned long memory_allowed; /* bytes */ + unsigned long memory_used; - /* PCI information */ + /* PCI information */ unsigned short id_vendor; unsigned short id_device; } drm_agp_info_t; - /** * DRM_IOCTL_SG_ALLOC ioctl argument type. */ @@ -606,7 +564,6 @@ typedef struct drm_set_version { int drm_dd_minor; } drm_set_version_t; - #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 79221783a14c..255a21783d10 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -1,7 +1,7 @@ /** - * \file drmP.h + * \file drmP.h * Private header for Direct Rendering Manager - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -43,7 +43,7 @@ * before static inline funcs in wait.h. Doing this so we * can build the DRM (part of PI DRI). 4/21/2000 S + B */ #include -#endif /* __alpha__ */ +#endif /* __alpha__ */ #include #include #include @@ -58,7 +58,7 @@ #include #include #if defined(__alpha__) || defined(__powerpc__) -#include /* For pte_wrprotect */ +#include /* For pte_wrprotect */ #endif #include #include @@ -138,16 +138,15 @@ #define DRM_MEM_CTXLIST 21 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) - -/*@}*/ +/*@}*/ /***********************************************************************/ /** \name Backward compatibility section */ /*@{*/ #ifndef MODULE_LICENSE -#define MODULE_LICENSE(x) +#define MODULE_LICENSE(x) #endif #ifndef preempt_disable @@ -155,7 +154,7 @@ #define preempt_enable() #endif -#ifndef pte_offset_map +#ifndef pte_offset_map #define pte_offset_map pte_offset #define pte_unmap(pte) #endif @@ -166,7 +165,6 @@ /*@}*/ - /***********************************************************************/ /** \name Macros to make printk easier */ /*@{*/ @@ -195,7 +193,7 @@ /** * Debug output. - * + * * \param fmt printf() like format string. * \param arg arguments */ @@ -223,7 +221,6 @@ /*@}*/ - /***********************************************************************/ /** \name Internal types and structures */ /*@{*/ @@ -275,7 +272,7 @@ do { \ if ( copy_to_user( name, value, len ) ) \ return -EFAULT; \ } - + /** * Ioctl function type. * @@ -284,25 +281,25 @@ do { \ * \param cmd command. * \param arg argument. */ -typedef int drm_ioctl_t( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +typedef int drm_ioctl_t(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg); typedef struct drm_ioctl_desc { - drm_ioctl_t *func; - int auth_needed; - int root_only; + drm_ioctl_t *func; + int auth_needed; + int root_only; } drm_ioctl_desc_t; typedef struct drm_devstate { - pid_t owner; /**< X server pid holding x_lock */ + pid_t owner; /**< X server pid holding x_lock */ } drm_devstate_t; typedef struct drm_magic_entry { - drm_magic_t magic; - struct drm_file *priv; + drm_magic_t magic; + struct drm_file *priv; struct drm_magic_entry *next; } drm_magic_entry_t; @@ -313,111 +310,110 @@ typedef struct drm_magic_head { typedef struct drm_vma_entry { struct vm_area_struct *vma; - struct drm_vma_entry *next; - pid_t pid; + struct drm_vma_entry *next; + pid_t pid; } drm_vma_entry_t; /** * DMA buffer. */ typedef struct drm_buf { - int idx; /**< Index into master buflist */ - int total; /**< Buffer size */ - int order; /**< log-base-2(total) */ - int used; /**< Amount of buffer in use (for DMA) */ - unsigned long offset; /**< Byte offset (used internally) */ - void *address; /**< Address of buffer */ - unsigned long bus_address; /**< Bus address of buffer */ - struct drm_buf *next; /**< Kernel-only: used for free list */ - __volatile__ int waiting; /**< On kernel DMA queue */ - __volatile__ int pending; /**< On hardware DMA queue */ + int idx; /**< Index into master buflist */ + int total; /**< Buffer size */ + int order; /**< log-base-2(total) */ + int used; /**< Amount of buffer in use (for DMA) */ + unsigned long offset; /**< Byte offset (used internally) */ + void *address; /**< Address of buffer */ + unsigned long bus_address; /**< Bus address of buffer */ + struct drm_buf *next; /**< Kernel-only: used for free list */ + __volatile__ int waiting; /**< On kernel DMA queue */ + __volatile__ int pending; /**< On hardware DMA queue */ wait_queue_head_t dma_wait; /**< Processes waiting */ - struct file *filp; /**< Pointer to holding file descr */ - int context; /**< Kernel queue for this buffer */ - int while_locked;/**< Dispatch this buffer while locked */ + struct file *filp; /**< Pointer to holding file descr */ + int context; /**< Kernel queue for this buffer */ + int while_locked; /**< Dispatch this buffer while locked */ enum { - DRM_LIST_NONE = 0, - DRM_LIST_FREE = 1, - DRM_LIST_WAIT = 2, - DRM_LIST_PEND = 3, - DRM_LIST_PRIO = 4, + DRM_LIST_NONE = 0, + DRM_LIST_FREE = 1, + DRM_LIST_WAIT = 2, + DRM_LIST_PEND = 3, + DRM_LIST_PRIO = 4, DRM_LIST_RECLAIM = 5 - } list; /**< Which list we're on */ + } list; /**< Which list we're on */ - int dev_priv_size; /**< Size of buffer private storage */ - void *dev_private; /**< Per-buffer private storage */ + int dev_priv_size; /**< Size of buffer private storage */ + void *dev_private; /**< Per-buffer private storage */ } drm_buf_t; - /** bufs is one longer than it has to be */ typedef struct drm_waitlist { - int count; /**< Number of possible buffers */ - drm_buf_t **bufs; /**< List of pointers to buffers */ - drm_buf_t **rp; /**< Read pointer */ - drm_buf_t **wp; /**< Write pointer */ - drm_buf_t **end; /**< End pointer */ - spinlock_t read_lock; - spinlock_t write_lock; + int count; /**< Number of possible buffers */ + drm_buf_t **bufs; /**< List of pointers to buffers */ + drm_buf_t **rp; /**< Read pointer */ + drm_buf_t **wp; /**< Write pointer */ + drm_buf_t **end; /**< End pointer */ + spinlock_t read_lock; + spinlock_t write_lock; } drm_waitlist_t; typedef struct drm_freelist { - int initialized; /**< Freelist in use */ - atomic_t count; /**< Number of free buffers */ - drm_buf_t *next; /**< End pointer */ + int initialized; /**< Freelist in use */ + atomic_t count; /**< Number of free buffers */ + drm_buf_t *next; /**< End pointer */ wait_queue_head_t waiting; /**< Processes waiting on free bufs */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - atomic_t wfh; /**< If waiting for high mark */ - spinlock_t lock; + int low_mark; /**< Low water mark */ + int high_mark; /**< High water mark */ + atomic_t wfh; /**< If waiting for high mark */ + spinlock_t lock; } drm_freelist_t; /** * Buffer entry. There is one of this for each buffer size order. */ typedef struct drm_buf_entry { - int buf_size; /**< size */ - int buf_count; /**< number of buffers */ - drm_buf_t *buflist; /**< buffer list */ - int seg_count; - int page_order; - unsigned long *seglist; + int buf_size; /**< size */ + int buf_count; /**< number of buffers */ + drm_buf_t *buflist; /**< buffer list */ + int seg_count; + int page_order; + unsigned long *seglist; - drm_freelist_t freelist; + drm_freelist_t freelist; } drm_buf_entry_t; /** File private data */ typedef struct drm_file { - int authenticated; - int minor; - pid_t pid; - uid_t uid; - drm_magic_t magic; - unsigned long ioctl_count; - struct drm_file *next; - struct drm_file *prev; - struct drm_head *head; - int remove_auth_on_close; - unsigned long lock_count; - void *driver_priv; + int authenticated; + int minor; + pid_t pid; + uid_t uid; + drm_magic_t magic; + unsigned long ioctl_count; + struct drm_file *next; + struct drm_file *prev; + struct drm_head *head; + int remove_auth_on_close; + unsigned long lock_count; + void *driver_priv; } drm_file_t; /** Wait queue */ typedef struct drm_queue { - atomic_t use_count; /**< Outstanding uses (+1) */ - atomic_t finalization; /**< Finalization in progress */ - atomic_t block_count; /**< Count of processes waiting */ - atomic_t block_read; /**< Queue blocked for reads */ + atomic_t use_count; /**< Outstanding uses (+1) */ + atomic_t finalization; /**< Finalization in progress */ + atomic_t block_count; /**< Count of processes waiting */ + atomic_t block_read; /**< Queue blocked for reads */ wait_queue_head_t read_queue; /**< Processes waiting on block_read */ - atomic_t block_write; /**< Queue blocked for writes */ + atomic_t block_write; /**< Queue blocked for writes */ wait_queue_head_t write_queue; /**< Processes waiting on block_write */ #if 1 - atomic_t total_queued; /**< Total queued statistic */ - atomic_t total_flushed;/**< Total flushes statistic */ - atomic_t total_locks; /**< Total locks statistics */ + atomic_t total_queued; /**< Total queued statistic */ + atomic_t total_flushed; /**< Total flushes statistic */ + atomic_t total_locks; /**< Total locks statistics */ #endif - drm_ctx_flags_t flags; /**< Context preserving and 2D-only */ - drm_waitlist_t waitlist; /**< Pending buffers */ + drm_ctx_flags_t flags; /**< Context preserving and 2D-only */ + drm_waitlist_t waitlist; /**< Pending buffers */ wait_queue_head_t flush_queue; /**< Processes waiting until flush */ } drm_queue_t; @@ -425,10 +421,10 @@ typedef struct drm_queue { * Lock data. */ typedef struct drm_lock_data { - drm_hw_lock_t *hw_lock; /**< Hardware lock */ - struct file *filp; /**< File descr of lock holder (0=kernel) */ + drm_hw_lock_t *hw_lock; /**< Hardware lock */ + struct file *filp; /**< File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /**< Queue of blocked processes */ - unsigned long lock_time; /**< Time of last lock in jiffies */ + unsigned long lock_time; /**< Time of last lock in jiffies */ } drm_lock_data_t; /** @@ -436,29 +432,29 @@ typedef struct drm_lock_data { */ typedef struct drm_device_dma { - drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; /**< buffers, grouped by their size order */ - int buf_count; /**< total number of buffers */ - drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */ - int seg_count; - int page_count; /**< number of pages */ - unsigned long *pagelist; /**< page list */ - unsigned long byte_count; + drm_buf_entry_t bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */ + int buf_count; /**< total number of buffers */ + drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */ + int seg_count; + int page_count; /**< number of pages */ + unsigned long *pagelist; /**< page list */ + unsigned long byte_count; enum { _DRM_DMA_USE_AGP = 0x01, - _DRM_DMA_USE_SG = 0x02, - _DRM_DMA_USE_FB = 0x04 + _DRM_DMA_USE_SG = 0x02, + _DRM_DMA_USE_FB = 0x04 } flags; } drm_device_dma_t; -/** +/** * AGP memory entry. Stored as a doubly linked list. */ typedef struct drm_agp_mem { - unsigned long handle; /**< handle */ - DRM_AGP_MEM *memory; - unsigned long bound; /**< address */ - int pages; + unsigned long handle; /**< handle */ + DRM_AGP_MEM *memory; + unsigned long bound; /**< address */ + int pages; struct drm_agp_mem *prev; /**< previous entry */ struct drm_agp_mem *next; /**< next entry */ } drm_agp_mem_t; @@ -469,31 +465,31 @@ typedef struct drm_agp_mem { * \sa drm_agp_init() and drm_device::agp. */ typedef struct drm_agp_head { - DRM_AGP_KERN agp_info; /**< AGP device information */ - drm_agp_mem_t *memory; /**< memory entries */ - unsigned long mode; /**< AGP mode */ - struct agp_bridge_data *bridge; - int enabled; /**< whether the AGP bus as been enabled */ - int acquired; /**< whether the AGP device has been acquired */ - unsigned long base; - int agp_mtrr; - int cant_use_aperture; - unsigned long page_mask; + DRM_AGP_KERN agp_info; /**< AGP device information */ + drm_agp_mem_t *memory; /**< memory entries */ + unsigned long mode; /**< AGP mode */ + struct agp_bridge_data *bridge; + int enabled; /**< whether the AGP bus as been enabled */ + int acquired; /**< whether the AGP device has been acquired */ + unsigned long base; + int agp_mtrr; + int cant_use_aperture; + unsigned long page_mask; } drm_agp_head_t; /** * Scatter-gather memory. */ typedef struct drm_sg_mem { - unsigned long handle; - void *virtual; - int pages; - struct page **pagelist; - dma_addr_t *busaddr; + unsigned long handle; + void *virtual; + int pages; + struct page **pagelist; + dma_addr_t *busaddr; } drm_sg_mem_t; typedef struct drm_sigdata { - int context; + int context; drm_hw_lock_t *lock; } drm_sigdata_t; @@ -507,8 +503,8 @@ typedef struct drm_dma_handle { * Mappings list */ typedef struct drm_map_list { - struct list_head head; /**< list head */ - drm_map_t *map; /**< mapping */ + struct list_head head; /**< list head */ + drm_map_t *map; /**< mapping */ unsigned int user_token; } drm_map_list_t; @@ -518,20 +514,18 @@ typedef drm_map_t drm_local_map_t; * Context handle list */ typedef struct drm_ctx_list { - struct list_head head; /**< list head */ - drm_context_t handle; /**< context handle */ - drm_file_t *tag; /**< associated fd private data */ + struct list_head head; /**< list head */ + drm_context_t handle; /**< context handle */ + drm_file_t *tag; /**< associated fd private data */ } drm_ctx_list_t; - typedef struct drm_vbl_sig { - struct list_head head; - unsigned int sequence; - struct siginfo info; - struct task_struct *task; + struct list_head head; + unsigned int sequence; + struct siginfo info; + struct task_struct *task; } drm_vbl_sig_t; - /* location of GART table */ #define DRM_ATI_GART_MAIN 1 #define DRM_ATI_GART_FB 2 @@ -551,24 +545,26 @@ typedef struct ati_pcigart_info { struct drm_device; struct drm_driver { - int (*preinit)(struct drm_device *, unsigned long flags); - void (*prerelease)(struct drm_device *, struct file *filp); - void (*pretakedown)(struct drm_device *); - int (*postcleanup)(struct drm_device *); - int (*presetup)(struct drm_device *); - int (*postsetup)(struct drm_device *); - int (*dma_ioctl)( DRM_IOCTL_ARGS ); - int (*open_helper)(struct drm_device *, drm_file_t *); - void (*free_filp_priv)(struct drm_device *, drm_file_t *); - void (*release)(struct drm_device *, struct file *filp); - void (*dma_ready)(struct drm_device *); - int (*dma_quiescent)(struct drm_device *); - int (*context_ctor)(struct drm_device *dev, int context); - int (*context_dtor)(struct drm_device *dev, int context); - int (*kernel_context_switch)(struct drm_device *dev, int old, int new); - void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock); - int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence); - + int (*preinit) (struct drm_device *, unsigned long flags); + void (*prerelease) (struct drm_device *, struct file * filp); + void (*pretakedown) (struct drm_device *); + int (*postcleanup) (struct drm_device *); + int (*presetup) (struct drm_device *); + int (*postsetup) (struct drm_device *); + int (*dma_ioctl) (DRM_IOCTL_ARGS); + int (*open_helper) (struct drm_device *, drm_file_t *); + void (*free_filp_priv) (struct drm_device *, drm_file_t *); + void (*release) (struct drm_device *, struct file * filp); + void (*dma_ready) (struct drm_device *); + int (*dma_quiescent) (struct drm_device *); + int (*context_ctor) (struct drm_device * dev, int context); + int (*context_dtor) (struct drm_device * dev, int context); + int (*kernel_context_switch) (struct drm_device * dev, int old, + int new); + void (*kernel_context_switch_unlock) (struct drm_device * dev, + drm_lock_t * lock); + int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); + /** * Called by \c drm_device_is_agp. Typically used to determine if a * card is really attached to AGP or not. @@ -583,17 +579,17 @@ struct drm_driver { int (*device_is_agp) (struct drm_device * dev); /* these have to be filled in */ - - int (*postinit)(struct drm_device *, unsigned long flags); - irqreturn_t (*irq_handler)( DRM_IRQ_ARGS ); - void (*irq_preinstall)(struct drm_device *dev); - void (*irq_postinstall)(struct drm_device *dev); - void (*irq_uninstall)(struct drm_device *dev); - void (*reclaim_buffers)(struct drm_device *dev, struct file *filp); - unsigned long (*get_map_ofs)(drm_map_t *map); - unsigned long (*get_reg_ofs)(struct drm_device *dev); - void (*set_version)(struct drm_device *dev, drm_set_version_t *sv); - int (*version)(drm_version_t *version); + + int (*postinit) (struct drm_device *, unsigned long flags); + irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); + void (*irq_preinstall) (struct drm_device * dev); + void (*irq_postinstall) (struct drm_device * dev); + void (*irq_uninstall) (struct drm_device * dev); + void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); + unsigned long (*get_map_ofs) (drm_map_t * map); + unsigned long (*get_reg_ofs) (struct drm_device * dev); + void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); + int (*version) (drm_version_t * version); u32 driver_features; int dev_priv_size; drm_ioctl_desc_t *ioctls; @@ -620,128 +616,129 @@ typedef struct drm_head { * may contain multiple heads. */ typedef struct drm_device { - char *unique; /**< Unique identifier: e.g., busid */ - int unique_len; /**< Length of unique field */ - char *devname; /**< For /proc/interrupts */ - int if_version; /**< Highest interface version set */ + char *unique; /**< Unique identifier: e.g., busid */ + int unique_len; /**< Length of unique field */ + char *devname; /**< For /proc/interrupts */ + int if_version; /**< Highest interface version set */ - int blocked; /**< Blocked due to VC switch? */ + int blocked; /**< Blocked due to VC switch? */ /** \name Locks */ - /*@{*/ - spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ - struct semaphore struct_sem; /**< For others */ - /*@}*/ + /*@{ */ + spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ + struct semaphore struct_sem; /**< For others */ + /*@} */ /** \name Usage Counters */ - /*@{*/ - int open_count; /**< Outstanding files open */ - atomic_t ioctl_count; /**< Outstanding IOCTLs pending */ - atomic_t vma_count; /**< Outstanding vma areas open */ - int buf_use; /**< Buffers in use -- cannot alloc */ - atomic_t buf_alloc; /**< Buffer allocation in progress */ - /*@}*/ + /*@{ */ + int open_count; /**< Outstanding files open */ + atomic_t ioctl_count; /**< Outstanding IOCTLs pending */ + atomic_t vma_count; /**< Outstanding vma areas open */ + int buf_use; /**< Buffers in use -- cannot alloc */ + atomic_t buf_alloc; /**< Buffer allocation in progress */ + /*@} */ /** \name Performance counters */ - /*@{*/ - unsigned long counters; - drm_stat_type_t types[15]; - atomic_t counts[15]; - /*@}*/ + /*@{ */ + unsigned long counters; + drm_stat_type_t types[15]; + atomic_t counts[15]; + /*@} */ /** \name Authentication */ - /*@{*/ - drm_file_t *file_first; /**< file list head */ - drm_file_t *file_last; /**< file list tail */ - drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ - /*@}*/ + /*@{ */ + drm_file_t *file_first; /**< file list head */ + drm_file_t *file_last; /**< file list tail */ + drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ + /*@} */ /** \name Memory management */ - /*@{*/ - drm_map_list_t *maplist; /**< Linked list of regions */ - int map_count; /**< Number of mappable regions */ + /*@{ */ + drm_map_list_t *maplist; /**< Linked list of regions */ + int map_count; /**< Number of mappable regions */ /** \name Context handle management */ - /*@{*/ - drm_ctx_list_t *ctxlist; /**< Linked list of context handles */ - int ctx_count; /**< Number of context handles */ - struct semaphore ctxlist_sem; /**< For ctxlist */ + /*@{ */ + drm_ctx_list_t *ctxlist; /**< Linked list of context handles */ + int ctx_count; /**< Number of context handles */ + struct semaphore ctxlist_sem; /**< For ctxlist */ - drm_map_t **context_sareas; /**< per-context SAREA's */ - int max_context; + drm_map_t **context_sareas; /**< per-context SAREA's */ + int max_context; - drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */ - drm_lock_data_t lock; /**< Information on hardware lock */ - /*@}*/ + drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */ + drm_lock_data_t lock; /**< Information on hardware lock */ + /*@} */ /** \name DMA queues (contexts) */ - /*@{*/ - int queue_count; /**< Number of active DMA queues */ - int queue_reserved; /**< Number of reserved DMA queues */ - int queue_slots; /**< Actual length of queuelist */ - drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */ - drm_device_dma_t *dma; /**< Optional pointer for DMA support */ - /*@}*/ + /*@{ */ + int queue_count; /**< Number of active DMA queues */ + int queue_reserved; /**< Number of reserved DMA queues */ + int queue_slots; /**< Actual length of queuelist */ + drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */ + drm_device_dma_t *dma; /**< Optional pointer for DMA support */ + /*@} */ /** \name Context support */ - /*@{*/ - int irq; /**< Interrupt used by board */ - int irq_enabled; /**< True if irq handler is enabled */ + /*@{ */ + int irq; /**< Interrupt used by board */ + int irq_enabled; /**< True if irq handler is enabled */ __volatile__ long context_flag; /**< Context swapping flag */ __volatile__ long interrupt_flag; /**< Interruption handler flag */ __volatile__ long dma_flag; /**< DMA dispatch flag */ struct timer_list timer; /**< Timer for delaying ctx switch */ - wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */ - int last_checked; /**< Last context checked for DMA */ - int last_context; /**< Last current context */ - unsigned long last_switch; /**< jiffies at last context switch */ - /*@}*/ - - struct work_struct work; + wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */ + int last_checked; /**< Last context checked for DMA */ + int last_context; /**< Last current context */ + unsigned long last_switch; /**< jiffies at last context switch */ + /*@} */ + + struct work_struct work; /** \name VBLANK IRQ support */ - /*@{*/ + /*@{ */ - wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ - atomic_t vbl_received; - spinlock_t vbl_lock; - drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */ - unsigned int vbl_pending; + wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ + atomic_t vbl_received; + spinlock_t vbl_lock; + drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */ + unsigned int vbl_pending; - /*@}*/ - cycles_t ctx_start; - cycles_t lck_start; + /*@} */ + cycles_t ctx_start; + cycles_t lck_start; - char buf[DRM_BSZ]; /**< Output buffer */ - char *buf_rp; /**< Read pointer */ - char *buf_wp; /**< Write pointer */ - char *buf_end; /**< End pointer */ + char buf[DRM_BSZ]; /**< Output buffer */ + char *buf_rp; /**< Read pointer */ + char *buf_wp; /**< Write pointer */ + char *buf_end; /**< End pointer */ struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /**< Processes waiting to read */ wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */ - drm_agp_head_t *agp; /**< AGP data */ + drm_agp_head_t *agp; /**< AGP data */ - struct pci_dev *pdev; /**< PCI device structure */ - int pci_domain; /**< PCI bus domain number */ - int pci_bus; /**< PCI bus number */ - int pci_slot; /**< PCI slot number */ - int pci_func; /**< PCI function number */ + struct pci_dev *pdev; /**< PCI device structure */ + int pci_domain; /**< PCI bus domain number */ + int pci_bus; /**< PCI bus number */ + int pci_slot; /**< PCI slot number */ + int pci_func; /**< PCI function number */ #ifdef __alpha__ struct pci_controller *hose; #endif - drm_sg_mem_t *sg; /**< Scatter gather memory */ - unsigned long *ctx_bitmap; /**< context bitmap */ - void *dev_private; /**< device private data */ - drm_sigdata_t sigdata; /**< For block_all_signals */ - sigset_t sigmask; + drm_sg_mem_t *sg; /**< Scatter gather memory */ + unsigned long *ctx_bitmap; /**< context bitmap */ + void *dev_private; /**< device private data */ + drm_sigdata_t sigdata; /**< For block_all_signals */ + sigset_t sigmask; - struct drm_driver *driver; - drm_local_map_t *agp_buffer_map; + struct drm_driver *driver; + drm_local_map_t *agp_buffer_map; unsigned int agp_buffer_token; drm_head_t primary; /**< primary screen head */ } drm_device_t; -static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature) +static __inline__ int drm_core_check_feature(struct drm_device *dev, + int feature) { return ((dev->driver->driver_features & feature) ? 1 : 0); } @@ -749,7 +746,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature #if __OS_HAS_AGP static inline int drm_core_has_AGP(struct drm_device *dev) { - return drm_core_check_feature(dev, DRIVER_USE_AGP); + return drm_core_check_feature(dev, DRIVER_USE_AGP); } #else #define drm_core_has_AGP(dev) (0) @@ -758,7 +755,7 @@ static inline int drm_core_has_AGP(struct drm_device *dev) #if __OS_HAS_MTRR static inline int drm_core_has_MTRR(struct drm_device *dev) { - return drm_core_check_feature(dev, DRIVER_USE_MTRR); + return drm_core_check_feature(dev, DRIVER_USE_MTRR); } #else #define drm_core_has_MTRR(dev) (0) @@ -769,230 +766,229 @@ static inline int drm_core_has_MTRR(struct drm_device *dev) /*@{*/ /* Misc. support (drm_init.h) */ -extern int drm_flags; -extern void drm_parse_options( char *s ); -extern int drm_cpu_valid( void ); +extern int drm_flags; +extern void drm_parse_options(char *s); +extern int drm_cpu_valid(void); /* Driver support (drm_drv.h) */ -extern int drm_init(struct drm_driver *driver); -extern void drm_exit(struct drm_driver *driver); -extern int drm_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern long drm_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_takedown(drm_device_t * dev); +extern int drm_init(struct drm_driver *driver); +extern void drm_exit(struct drm_driver *driver); +extern int drm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern long drm_compat_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_takedown(drm_device_t * dev); /* Device support (drm_fops.h) */ -extern int drm_open(struct inode *inode, struct file *filp); -extern int drm_stub_open(struct inode *inode, struct file *filp); -extern int drm_flush(struct file *filp); -extern int drm_fasync(int fd, struct file *filp, int on); -extern int drm_release(struct inode *inode, struct file *filp); +extern int drm_open(struct inode *inode, struct file *filp); +extern int drm_stub_open(struct inode *inode, struct file *filp); +extern int drm_flush(struct file *filp); +extern int drm_fasync(int fd, struct file *filp, int on); +extern int drm_release(struct inode *inode, struct file *filp); /* Mapping support (drm_vm.h) */ -extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); -extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); +extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); +extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); /* Memory management support (drm_memory.h) */ #include "drm_memory.h" -extern void drm_mem_init(void); -extern int drm_mem_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, - int area); +extern void drm_mem_init(void); +extern int drm_mem_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); +extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); extern unsigned long drm_alloc_pages(int order, int area); -extern void drm_free_pages(unsigned long address, int order, - int area); -extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev); -extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, - drm_device_t *dev); -extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); +extern void drm_free_pages(unsigned long address, int order, int area); +extern void *drm_ioremap(unsigned long offset, unsigned long size, + drm_device_t * dev); +extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, + drm_device_t * dev); +extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); -extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type); -extern int drm_free_agp(DRM_AGP_MEM *handle, int pages); -extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start); -extern int drm_unbind_agp(DRM_AGP_MEM *handle); +extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); +extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); +extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); +extern int drm_unbind_agp(DRM_AGP_MEM * handle); /* Misc. IOCTL support (drm_ioctl.h) */ -extern int drm_irq_by_busid(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_getunique(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_setunique(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_getmap(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_getclient(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_getstats(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_setversion(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +extern int drm_irq_by_busid(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getunique(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_setunique(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getmap(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getclient(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getstats(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_setversion(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Context IOCTL support (drm_context.h) */ -extern int drm_resctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_addctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_modctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_getctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_switchctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_newctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_rmctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int drm_resctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_addctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_modctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_switchctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_newctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_rmctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); -extern int drm_ctxbitmap_init( drm_device_t *dev ); -extern void drm_ctxbitmap_cleanup( drm_device_t *dev ); -extern void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle ); +extern int drm_ctxbitmap_init(drm_device_t * dev); +extern void drm_ctxbitmap_cleanup(drm_device_t * dev); +extern void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle); -extern int drm_setsareactx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_getsareactx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int drm_setsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_getsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Drawable IOCTL support (drm_drawable.h) */ -extern int drm_adddraw(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_rmdraw(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); - +extern int drm_adddraw(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_rmdraw(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Authentication IOCTL support (drm_auth.h) */ -extern int drm_getmagic(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_authmagic(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +extern int drm_getmagic(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_authmagic(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); - /* Placeholder for ioctls past */ -extern int drm_noop(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); + /* Placeholder for ioctls past */ +extern int drm_noop(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Locking IOCTL support (drm_lock.h) */ -extern int drm_lock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_unlock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_lock_take(__volatile__ unsigned int *lock, - unsigned int context); -extern int drm_lock_free(drm_device_t *dev, - __volatile__ unsigned int *lock, - unsigned int context); +extern int drm_lock(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_unlock(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); +extern int drm_lock_free(drm_device_t * dev, + __volatile__ unsigned int *lock, unsigned int context); /* Buffer management support (drm_bufs.h) */ -extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request); -extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request); -extern int drm_addmap(drm_device_t *dev, unsigned int offset, +extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); +extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); +extern int drm_addmap(drm_device_t * dev, unsigned int offset, unsigned int size, drm_map_type_t type, - drm_map_flags_t flags, drm_local_map_t **map_ptr); + drm_map_flags_t flags, drm_local_map_t ** map_ptr); extern int drm_addmap_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map); -extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map); +extern int drm_rmmap(drm_device_t * dev, drm_local_map_t * map); +extern int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map); extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_order( unsigned long size ); -extern int drm_addbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_infobufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_markbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_freebufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_mapbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern unsigned long drm_get_resource_start(drm_device_t *dev, +extern int drm_order(unsigned long size); +extern int drm_addbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_infobufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_markbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_freebufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_mapbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource); -extern unsigned long drm_get_resource_len(drm_device_t *dev, +extern unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource); /* DMA support (drm_dma.h) */ -extern int drm_dma_setup(drm_device_t *dev); -extern void drm_dma_takedown(drm_device_t *dev); -extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf); -extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp); +extern int drm_dma_setup(drm_device_t * dev); +extern void drm_dma_takedown(drm_device_t * dev); +extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf); +extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp); /* IRQ support (drm_irq.h) */ -extern int drm_control( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_irq_uninstall( drm_device_t *dev ); -extern irqreturn_t drm_irq_handler( DRM_IRQ_ARGS ); -extern void drm_driver_irq_preinstall( drm_device_t *dev ); -extern void drm_driver_irq_postinstall( drm_device_t *dev ); -extern void drm_driver_irq_uninstall( drm_device_t *dev ); +extern int drm_control(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_irq_uninstall(drm_device_t * dev); +extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); +extern void drm_driver_irq_preinstall(drm_device_t * dev); +extern void drm_driver_irq_postinstall(drm_device_t * dev); +extern void drm_driver_irq_uninstall(drm_device_t * dev); -extern int drm_wait_vblank(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq); -extern void drm_vbl_send_signals( drm_device_t *dev ); +extern int drm_wait_vblank(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq); +extern void drm_vbl_send_signals(drm_device_t * dev); /* AGP/GART support (drm_agpsupport.h) */ -extern drm_agp_head_t *drm_agp_init(drm_device_t *dev); +extern drm_agp_head_t *drm_agp_init(drm_device_t * dev); extern int drm_agp_acquire(drm_device_t * dev); extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_release(drm_device_t *dev); + unsigned int cmd, unsigned long arg); +extern int drm_agp_release(drm_device_t * dev); extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode); + unsigned int cmd, unsigned long arg); +extern int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode); extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info); + unsigned int cmd, unsigned long arg); +extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_alloc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_agp_alloc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_free(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_unbind(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_bind(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type); -extern int drm_agp_free_memory(DRM_AGP_MEM *handle); -extern int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start); -extern int drm_agp_unbind_memory(DRM_AGP_MEM *handle); +extern int drm_agp_unbind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_bind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, + size_t pages, u32 type); +extern int drm_agp_free_memory(DRM_AGP_MEM * handle); +extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); +extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); /* Stub support (drm_stub.h) */ extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver); + struct drm_driver *driver); extern int drm_put_dev(drm_device_t * dev); extern int drm_put_head(drm_head_t * head); -extern unsigned int drm_debug; -extern unsigned int drm_cards_limit; +extern unsigned int drm_debug; +extern unsigned int drm_cards_limit; extern drm_head_t **drm_heads; extern struct drm_sysfs_class *drm_class; extern struct proc_dir_entry *drm_proc_root; /* Proc support (drm_proc.h) */ -extern int drm_proc_init(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int drm_proc_cleanup(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); +extern int drm_proc_init(drm_device_t * dev, + int minor, + struct proc_dir_entry *root, + struct proc_dir_entry **dev_root); +extern int drm_proc_cleanup(int minor, + struct proc_dir_entry *root, + struct proc_dir_entry *dev_root); /* Scatter Gather Support (drm_scatter.h) */ -extern void drm_sg_cleanup(drm_sg_mem_t *entry); -extern int drm_sg_alloc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_sg_free(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +extern void drm_sg_cleanup(drm_sg_mem_t * entry); +extern int drm_sg_alloc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_sg_free(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); - /* ATI PCIGART support (ati_pcigart.h) */ -extern int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info); -extern int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info); + /* ATI PCIGART support (ati_pcigart.h) */ +extern int drm_ati_pcigart_init(drm_device_t * dev, + drm_ati_pcigart_info * gart_info); +extern int drm_ati_pcigart_cleanup(drm_device_t * dev, + drm_ati_pcigart_info * gart_info); -extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, +extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, dma_addr_t maxaddr); -extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah); -extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah); +extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); +extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); /* sysfs support (drm_sysfs.c) */ struct drm_sysfs_class; @@ -1005,38 +1001,41 @@ extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, const char *fmt, ...); extern void drm_sysfs_device_remove(dev_t dev); - /* Inline replacements for DRM_IOREMAP macros */ -static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) +static __inline__ void drm_core_ioremap(struct drm_map *map, + struct drm_device *dev) { - map->handle = drm_ioremap( map->offset, map->size, dev ); + map->handle = drm_ioremap(map->offset, map->size, dev); } -static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev) +static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, + struct drm_device *dev) { map->handle = drm_ioremap_nocache(map->offset, map->size, dev); } -static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) +static __inline__ void drm_core_ioremapfree(struct drm_map *map, + struct drm_device *dev) { - if ( map->handle && map->size ) - drm_ioremapfree( map->handle, map->size, dev ); + if (map->handle && map->size) + drm_ioremapfree(map->handle, map->size, dev); } -static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token) +static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, + unsigned int token) { drm_map_list_t *_entry; list_for_each_entry(_entry, &dev->maplist->head, head) - if (_entry->user_token == token) - return _entry->map; + if (_entry->user_token == token) + return _entry->map; return NULL; } -static __inline__ int drm_device_is_agp(drm_device_t *dev) +static __inline__ int drm_device_is_agp(drm_device_t * dev) { - if ( dev->driver->device_is_agp != NULL ) { - int err = (*dev->driver->device_is_agp)( dev ); - + if (dev->driver->device_is_agp != NULL) { + int err = (*dev->driver->device_is_agp) (dev); + if (err != 2) { return err; } @@ -1045,7 +1044,7 @@ static __inline__ int drm_device_is_agp(drm_device_t *dev) return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP); } -static __inline__ int drm_device_is_pcie(drm_device_t *dev) +static __inline__ int drm_device_is_pcie(drm_device_t * dev) { return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); } @@ -1080,12 +1079,12 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area); /*@}*/ -extern unsigned long drm_core_get_map_ofs(drm_map_t *map); +extern unsigned long drm_core_get_map_ofs(drm_map_t * map); extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); #ifndef pci_pretty_name #define pci_pretty_name(dev) "" #endif -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ #endif diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 8c215adcb4b2..2b6453a9ffce 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c @@ -1,7 +1,7 @@ /** - * \file drm_agpsupport.h + * \file drm_agpsupport.h * DRM support for AGP/GART backend - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -48,30 +48,31 @@ * Verifies the AGP device has been initialized and acquired and fills in the * drm_agp_info structure with the information in drm_agp_head::agp_info. */ -int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info) +int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info) { - DRM_AGP_KERN *kern; + DRM_AGP_KERN *kern; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - kern = &dev->agp->agp_info; + kern = &dev->agp->agp_info; info->agp_version_major = kern->version.major; info->agp_version_minor = kern->version.minor; - info->mode = kern->mode; - info->aperture_base = kern->aper_base; - info->aperture_size = kern->aper_size * 1024 * 1024; - info->memory_allowed = kern->max_memory << PAGE_SHIFT; - info->memory_used = kern->current_memory << PAGE_SHIFT; - info->id_vendor = kern->device->vendor; - info->id_device = kern->device->device; + info->mode = kern->mode; + info->aperture_base = kern->aper_base; + info->aperture_size = kern->aper_size * 1024 * 1024; + info->memory_allowed = kern->max_memory << PAGE_SHIFT; + info->memory_used = kern->current_memory << PAGE_SHIFT; + info->id_vendor = kern->device->vendor; + info->id_device = kern->device->device; return 0; } + EXPORT_SYMBOL(drm_agp_info); int drm_agp_info_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -81,7 +82,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp, err = drm_agp_info(dev, &info); if (err) return err; - + if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info))) return -EFAULT; return 0; @@ -91,12 +92,12 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp, * Acquire the AGP device. * * \param dev DRM device that is to acquire AGP - * \return zero on success or a negative number on failure. + * \return zero on success or a negative number on failure. * * Verifies the AGP device hasn't been acquired before and calls * \c agp_backend_acquire. */ -int drm_agp_acquire(drm_device_t *dev) +int drm_agp_acquire(drm_device_t * dev) { if (!dev->agp) return -ENODEV; @@ -107,6 +108,7 @@ int drm_agp_acquire(drm_device_t *dev) dev->agp->acquired = 1; return 0; } + EXPORT_SYMBOL(drm_agp_acquire); /** @@ -125,8 +127,8 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; - - return drm_agp_acquire( (drm_device_t *) priv->head->dev ); + + return drm_agp_acquire((drm_device_t *) priv->head->dev); } /** @@ -137,7 +139,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, * * Verifies the AGP device has been acquired and calls \c agp_backend_release. */ -int drm_agp_release(drm_device_t *dev) +int drm_agp_release(drm_device_t * dev) { if (!dev->agp || !dev->agp->acquired) return -EINVAL; @@ -145,6 +147,7 @@ int drm_agp_release(drm_device_t *dev) dev->agp->acquired = 0; return 0; } + EXPORT_SYMBOL(drm_agp_release); int drm_agp_release_ioctl(struct inode *inode, struct file *filp, @@ -152,13 +155,13 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - + return drm_agp_release(dev); } /** * Enable the AGP bus. - * + * * \param dev DRM device that has previously acquired AGP. * \param mode Requested AGP mode. * \return zero on success or a negative number on failure. @@ -166,27 +169,27 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp, * Verifies the AGP device has been acquired but not enabled, and calls * \c agp_enable. */ -int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode) +int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode) { if (!dev->agp || !dev->agp->acquired) return -EINVAL; - dev->agp->mode = mode.mode; + dev->agp->mode = mode.mode; agp_enable(dev->agp->bridge, mode.mode); - dev->agp->base = dev->agp->agp_info.aper_base; + dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; } + EXPORT_SYMBOL(drm_agp_enable); int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_agp_mode_t mode; - if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode))) return -EFAULT; @@ -201,20 +204,20 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, * \param cmd command. * \param arg pointer to a drm_agp_buffer structure. * \return zero on success or a negative number on failure. - * + * * Verifies the AGP device is present and has been acquired, allocates the * memory via alloc_agp() and creates a drm_agp_mem entry for it. */ int drm_agp_alloc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_agp_buffer_t request; - drm_agp_mem_t *entry; - DRM_AGP_MEM *memory; - unsigned long pages; - u32 type; + drm_agp_mem_t *entry; + DRM_AGP_MEM *memory; + unsigned long pages; + u32 type; drm_agp_buffer_t __user *argp = (void __user *)arg; if (!dev->agp || !dev->agp->acquired) @@ -224,7 +227,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; - memset(entry, 0, sizeof(*entry)); + memset(entry, 0, sizeof(*entry)); pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request.type; @@ -234,21 +237,21 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, return -ENOMEM; } - entry->handle = (unsigned long)memory->key + 1; - entry->memory = memory; - entry->bound = 0; - entry->pages = pages; - entry->prev = NULL; - entry->next = dev->agp->memory; + entry->handle = (unsigned long)memory->key + 1; + entry->memory = memory; + entry->bound = 0; + entry->pages = pages; + entry->prev = NULL; + entry->next = dev->agp->memory; if (dev->agp->memory) dev->agp->memory->prev = entry; dev->agp->memory = entry; - request.handle = entry->handle; + request.handle = entry->handle; request.physical = memory->physical; if (copy_to_user(argp, &request, sizeof(request))) { - dev->agp->memory = entry->next; + dev->agp->memory = entry->next; dev->agp->memory->prev = NULL; drm_free_agp(memory, pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); @@ -263,11 +266,11 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, * \param dev DRM device structure. * \param handle AGP memory handle. * \return pointer to the drm_agp_mem structure associated with \p handle. - * + * * Walks through drm_agp_head::memory until finding a matching handle. */ -static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev, - unsigned long handle) +static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev, + unsigned long handle) { drm_agp_mem_t *entry; @@ -291,17 +294,18 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev, * entry and passes it to the unbind_agp() function. */ int drm_agp_unbind(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_agp_binding_t request; - drm_agp_mem_t *entry; + drm_agp_mem_t *entry; int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request))) + if (copy_from_user + (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; @@ -309,7 +313,7 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, return -EINVAL; ret = drm_unbind_agp(entry->memory); if (ret == 0) - entry->bound = 0; + entry->bound = 0; return ret; } @@ -327,18 +331,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, * it to bind_agp() function. */ int drm_agp_bind(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_agp_binding_t request; - drm_agp_mem_t *entry; - int retcode; - int page; + drm_agp_mem_t *entry; + int retcode; + int page; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request))) + if (copy_from_user + (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; @@ -368,16 +373,17 @@ int drm_agp_bind(struct inode *inode, struct file *filp, * and unlinks from the doubly linked list it's inserted in. */ int drm_agp_free(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_agp_buffer_t request; - drm_agp_mem_t *entry; + drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request))) + if (copy_from_user + (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; @@ -403,9 +409,9 @@ int drm_agp_free(struct inode *inode, struct file *filp, * \return pointer to a drm_agp_head structure. * */ -drm_agp_head_t *drm_agp_init(drm_device_t *dev) +drm_agp_head_t *drm_agp_init(drm_device_t * dev) { - drm_agp_head_t *head = NULL; + drm_agp_head_t *head = NULL; if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) return NULL; @@ -433,13 +439,14 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev) } /** Calls agp_allocate_memory() */ -DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type) +DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge, + size_t pages, u32 type) { return agp_allocate_memory(bridge, pages, type); } /** Calls agp_free_memory() */ -int drm_agp_free_memory(DRM_AGP_MEM *handle) +int drm_agp_free_memory(DRM_AGP_MEM * handle) { if (!handle) return 0; @@ -448,20 +455,21 @@ int drm_agp_free_memory(DRM_AGP_MEM *handle) } /** Calls agp_bind_memory() */ -int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start) +int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start) { if (!handle) return -EINVAL; return agp_bind_memory(handle, start); } + EXPORT_SYMBOL(drm_agp_bind_memory); /** Calls agp_unbind_memory() */ -int drm_agp_unbind_memory(DRM_AGP_MEM *handle) +int drm_agp_unbind_memory(DRM_AGP_MEM * handle) { if (!handle) return -EINVAL; return agp_unbind_memory(handle); } -#endif /* __OS_HAS_AGP */ +#endif /* __OS_HAS_AGP */ diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c index dd140bca8f71..a47b502bc7cc 100644 --- a/drivers/char/drm/drm_auth.c +++ b/drivers/char/drm/drm_auth.c @@ -1,5 +1,5 @@ /** - * \file drm_auth.h + * \file drm_auth.c * IOCTLs for authentication * * \author Rickard E. (Rik) Faith @@ -46,7 +46,7 @@ */ static int drm_hash_magic(drm_magic_t magic) { - return magic & (DRM_HASH_SIZE-1); + return magic & (DRM_HASH_SIZE - 1); } /** @@ -59,11 +59,11 @@ static int drm_hash_magic(drm_magic_t magic) * the one with matching magic number, while holding the drm_device::struct_sem * lock. */ -static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic) +static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) { - drm_file_t *retval = NULL; + drm_file_t *retval = NULL; drm_magic_entry_t *pt; - int hash = drm_hash_magic(magic); + int hash = drm_hash_magic(magic); down(&dev->struct_sem); for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { @@ -78,7 +78,7 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic) /** * Adds a magic number. - * + * * \param dev DRM device. * \param priv file private data. * \param magic magic number. @@ -87,28 +87,30 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic) * associated the magic number hash key in drm_device::magiclist, while holding * the drm_device::struct_sem lock. */ -static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) +static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, + drm_magic_t magic) { - int hash; + int hash; drm_magic_entry_t *entry; DRM_DEBUG("%d\n", magic); - hash = drm_hash_magic(magic); - entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); - if (!entry) return -ENOMEM; + hash = drm_hash_magic(magic); + entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); + if (!entry) + return -ENOMEM; memset(entry, 0, sizeof(*entry)); entry->magic = magic; - entry->priv = priv; - entry->next = NULL; + entry->priv = priv; + entry->next = NULL; down(&dev->struct_sem); if (dev->magiclist[hash].tail) { dev->magiclist[hash].tail->next = entry; - dev->magiclist[hash].tail = entry; + dev->magiclist[hash].tail = entry; } else { - dev->magiclist[hash].head = entry; - dev->magiclist[hash].tail = entry; + dev->magiclist[hash].head = entry; + dev->magiclist[hash].tail = entry; } up(&dev->struct_sem); @@ -117,19 +119,18 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) /** * Remove a magic number. - * + * * \param dev DRM device. * \param magic magic number. * * Searches and unlinks the entry in drm_device::magiclist with the magic * number hash key, while holding the drm_device::struct_sem lock. */ -static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic) +static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) { drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; - int hash; - + int hash; DRM_DEBUG("%d\n", magic); hash = drm_hash_magic(magic); @@ -171,21 +172,22 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic) * filp. */ int drm_getmagic(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { static drm_magic_t sequence = 0; static DEFINE_SPINLOCK(lock); - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_auth_t auth; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_auth_t auth; - /* Find unique magic */ + /* Find unique magic */ if (priv->magic) { auth.magic = priv->magic; } else { do { spin_lock(&lock); - if (!sequence) ++sequence; /* reserve 0 */ + if (!sequence) + ++sequence; /* reserve 0 */ auth.magic = sequence++; spin_unlock(&lock); } while (drm_find_file(dev, auth.magic)); @@ -194,7 +196,7 @@ int drm_getmagic(struct inode *inode, struct file *filp, } DRM_DEBUG("%u\n", auth.magic); - if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth))) + if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth))) return -EFAULT; return 0; } @@ -211,14 +213,14 @@ int drm_getmagic(struct inode *inode, struct file *filp, * Checks if \p filp is associated with the magic number passed in \arg. */ int drm_authmagic(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_auth_t auth; - drm_file_t *file; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_auth_t auth; + drm_file_t *file; - if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth))) + if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth))) return -EFAULT; DRM_DEBUG("%u\n", auth.magic); if ((file = drm_find_file(dev, auth.magic))) { diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index f28e70ae6606..bb989ccea5a0 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -1,7 +1,7 @@ /** - * \file drm_bufs.h + * \file drm_bufs.c * Generic buffer template - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -36,20 +36,22 @@ #include #include "drmP.h" -unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource) { return pci_resource_start(dev->pdev, resource); } + EXPORT_SYMBOL(drm_get_resource_start); -unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) +unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource) { return pci_resource_len(dev->pdev, resource); } + EXPORT_SYMBOL(drm_get_resource_len); -static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, - drm_local_map_t *map) +static drm_map_list_t *drm_find_matching_map(drm_device_t * dev, + drm_local_map_t * map) { struct list_head *list; @@ -71,7 +73,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, #define END_RANGE 0x40000000 #ifdef _LP64 -static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev) +static __inline__ unsigned int HandleID(unsigned long lhandle, + drm_device_t * dev) { static unsigned int map32_handle = START_RANGE; unsigned int hash; @@ -81,12 +84,12 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev map32_handle += PAGE_SIZE; if (map32_handle > END_RANGE) map32_handle = START_RANGE; - } else + } else hash = lhandle; while (1) { drm_map_list_t *_entry; - list_for_each_entry(_entry, &dev->maplist->head,head) { + list_for_each_entry(_entry, &dev->maplist->head, head) { if (_entry->user_token == hash) break; } @@ -116,14 +119,14 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev */ int drm_addmap_core(drm_device_t * dev, unsigned int offset, unsigned int size, drm_map_type_t type, - drm_map_flags_t flags, drm_map_list_t **maplist) + drm_map_flags_t flags, drm_map_list_t ** maplist) { drm_map_t *map; drm_map_list_t *list; drm_dma_handle_t *dmah; - map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); - if ( !map ) + map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); + if (!map) return -ENOMEM; map->offset = offset; @@ -135,26 +138,26 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, * book keeping information about shared memory to allow for removal * when processes fork. */ - if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) { - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } - DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n", - map->offset, map->size, map->type ); - if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) { - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", + map->offset, map->size, map->type); + if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } - map->mtrr = -1; + map->mtrr = -1; map->handle = NULL; - switch ( map->type ) { + switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) - if ( map->offset + map->size < map->offset || - map->offset < virt_to_phys(high_memory) ) { - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + if (map->offset + map->size < map->offset || + map->offset < virt_to_phys(high_memory)) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } #endif @@ -169,8 +172,9 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, if (list != NULL) { if (list->map->size != map->size) { DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, list->map->size); + "mismatched sizes, (%ld vs %ld)\n", + map->type, map->size, + list->map->size); list->map->size = map->size; } @@ -180,35 +184,33 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, } if (drm_core_has_MTRR(dev)) { - if ( map->type == _DRM_FRAME_BUFFER || - (map->flags & _DRM_WRITE_COMBINING) ) { - map->mtrr = mtrr_add( map->offset, map->size, - MTRR_TYPE_WRCOMB, 1 ); + if (map->type == _DRM_FRAME_BUFFER || + (map->flags & _DRM_WRITE_COMBINING)) { + map->mtrr = mtrr_add(map->offset, map->size, + MTRR_TYPE_WRCOMB, 1); } } if (map->type == _DRM_REGISTERS) - map->handle = drm_ioremap( map->offset, map->size, - dev ); + map->handle = drm_ioremap(map->offset, map->size, dev); break; case _DRM_SHM: map->handle = vmalloc_32(map->size); - DRM_DEBUG( "%lu %d %p\n", - map->size, drm_order( map->size ), map->handle ); - if ( !map->handle ) { - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + DRM_DEBUG("%lu %d %p\n", + map->size, drm_order(map->size), map->handle); + if (!map->handle) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -ENOMEM; } map->offset = (unsigned long)map->handle; - if ( map->flags & _DRM_CONTAINS_LOCK ) { + if (map->flags & _DRM_CONTAINS_LOCK) { /* Prevent a 2nd X Server from creating a 2nd lock */ if (dev->lock.hw_lock != NULL) { - vfree( map->handle ); - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + vfree(map->handle); + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EBUSY; } - dev->sigdata.lock = - dev->lock.hw_lock = map->handle; /* Pointer to lock */ + dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; case _DRM_AGP: @@ -217,7 +219,7 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, map->offset += dev->hose->mem_space->start; #endif map->offset += dev->agp->base; - map->mtrr = dev->agp->agp_mtrr; /* for getmap */ + map->mtrr = dev->agp->agp_mtrr; /* for getmap */ } break; case _DRM_SCATTER_GATHER: @@ -227,7 +229,7 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, } map->offset += (unsigned long)dev->sg->virtual; break; - case _DRM_CONSISTENT: + case _DRM_CONSISTENT: /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, * As we're limiting the address to 2^32-1 (or less), * casting it down to 32 bits is no problem, but we @@ -242,12 +244,12 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, kfree(dmah); break; default: - drm_free( map, sizeof(*map), DRM_MEM_MAPS ); + drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); - if(!list) { + if (!list) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -258,18 +260,18 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset, list_add(&list->head, &dev->maplist->head); /* Assign a 32-bit handle */ /* We do it here so that dev->struct_sem protects the increment */ - list->user_token = HandleID(map->type==_DRM_SHM + list->user_token = HandleID(map->type == _DRM_SHM ? (unsigned long)map->handle : map->offset, dev); - up(&dev->struct_sem); + up(&dev->struct_sem); *maplist = list; return 0; } -int drm_addmap(drm_device_t *dev, unsigned int offset, +int drm_addmap(drm_device_t * dev, unsigned int offset, unsigned int size, drm_map_type_t type, - drm_map_flags_t flags, drm_local_map_t **map_ptr) + drm_map_flags_t flags, drm_local_map_t ** map_ptr) { drm_map_list_t *list; int rc; @@ -279,6 +281,7 @@ int drm_addmap(drm_device_t *dev, unsigned int offset, *map_ptr = list->map; return rc; } + EXPORT_SYMBOL(drm_addmap); int drm_addmap_ioctl(struct inode *inode, struct file *filp, @@ -294,14 +297,14 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, if (!(filp->f_mode & 3)) return -EACCES; /* Require read/write */ - if (copy_from_user(& map, argp, sizeof(map))) { + if (copy_from_user(&map, argp, sizeof(map))) { return -EFAULT; } err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, &maplist); - if (err) + if (err) return err; if (copy_to_user(argp, maplist->map, sizeof(drm_map_t))) @@ -311,7 +314,6 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, return 0; } - /** * Remove a map private from list and deallocate resources if the mapping * isn't in use. @@ -328,7 +330,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, * * \sa drm_addmap */ -int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) +int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map) { struct list_head *list; drm_map_list_t *r_list = NULL; @@ -359,9 +361,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) case _DRM_FRAME_BUFFER: if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { int retcode; - retcode = mtrr_del(map->mtrr, map->offset, - map->size); - DRM_DEBUG ("mtrr_del=%d\n", retcode); + retcode = mtrr_del(map->mtrr, map->offset, map->size); + DRM_DEBUG("mtrr_del=%d\n", retcode); } break; case _DRM_SHM: @@ -381,9 +382,10 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) return 0; } + EXPORT_SYMBOL(drm_rmmap_locked); -int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) +int drm_rmmap(drm_device_t * dev, drm_local_map_t * map) { int ret; @@ -393,6 +395,7 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) return ret; } + EXPORT_SYMBOL(drm_rmmap); /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on @@ -414,7 +417,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, struct list_head *list; int ret; - if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) { + if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) { return -EFAULT; } @@ -423,7 +426,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if (r_list->map && - r_list->user_token == (unsigned long) request.handle && + r_list->user_token == (unsigned long)request.handle && r_list->map->flags & _DRM_REMOVABLE) { map = r_list->map; break; @@ -462,7 +465,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, * * Frees any pages and buffers associated with the given entry. */ -static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry) +static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry) { int i; @@ -470,30 +473,27 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry) for (i = 0; i < entry->seg_count; i++) { if (entry->seglist[i]) { drm_free_pages(entry->seglist[i], - entry->page_order, - DRM_MEM_DMA); + entry->page_order, DRM_MEM_DMA); } } drm_free(entry->seglist, - entry->seg_count * - sizeof(*entry->seglist), - DRM_MEM_SEGS); + entry->seg_count * + sizeof(*entry->seglist), DRM_MEM_SEGS); entry->seg_count = 0; } - if (entry->buf_count) { - for (i = 0; i < entry->buf_count; i++) { + if (entry->buf_count) { + for (i = 0; i < entry->buf_count; i++) { if (entry->buflist[i].dev_private) { drm_free(entry->buflist[i].dev_private, - entry->buflist[i].dev_priv_size, - DRM_MEM_BUFS); + entry->buflist[i].dev_priv_size, + DRM_MEM_BUFS); } } drm_free(entry->buflist, - entry->buf_count * - sizeof(*entry->buflist), - DRM_MEM_BUFS); + entry->buf_count * + sizeof(*entry->buflist), DRM_MEM_BUFS); entry->buf_count = 0; } @@ -506,12 +506,12 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry) * \param dev drm_device_t to which the buffers are to be added. * \param request pointer to a drm_buf_desc_t describing the request. * \return zero on success or a negative number on failure. - * + * * After some sanity checks creates a drm_buf structure for each buffer and * reallocates the buffer list of the same size order to accommodate the new * buffers. */ -int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) +int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -528,144 +528,145 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) int i; drm_buf_t **temp_buflist; - if ( !dma ) return -EINVAL; + if (!dma) + return -EINVAL; count = request->count; order = drm_order(request->size); size = 1 << order; - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; + alignment = (request->flags & _DRM_PAGE_ALIGN) + ? PAGE_ALIGN(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; byte_count = 0; agp_offset = dev->agp->base + request->agp_start; - DRM_DEBUG( "count: %d\n", count ); - DRM_DEBUG( "order: %d\n", order ); - DRM_DEBUG( "size: %d\n", size ); - DRM_DEBUG( "agp_offset: %lu\n", agp_offset ); - DRM_DEBUG( "alignment: %d\n", alignment ); - DRM_DEBUG( "page_order: %d\n", page_order ); - DRM_DEBUG( "total: %d\n", total ); + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %lu\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; - if ( dev->queue_count ) return -EBUSY; /* Not while in use */ + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) + return -EINVAL; + if (dev->queue_count) + return -EBUSY; /* Not while in use */ - spin_lock( &dev->count_lock ); - if ( dev->buf_use ) { - spin_unlock( &dev->count_lock ); + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); return -EBUSY; } - atomic_inc( &dev->buf_alloc ); - spin_unlock( &dev->count_lock ); + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down( &dev->struct_sem ); + down(&dev->struct_sem); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); - return -ENOMEM; /* May only call once for each order */ + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ } if (count < 0 || count > 4096) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -EINVAL; } - entry->buflist = drm_alloc( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); entry->buf_size = size; entry->page_order = page_order; offset = 0; - while ( entry->buf_count < count ) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; + while (entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; - buf->offset = (dma->byte_count + offset); + buf->offset = (dma->byte_count + offset); buf->bus_address = agp_offset + offset; buf->address = (void *)(agp_offset + offset); - buf->next = NULL; + buf->next = NULL; buf->waiting = 0; buf->pending = 0; - init_waitqueue_head( &buf->dma_wait ); - buf->filp = NULL; + init_waitqueue_head(&buf->dma_wait); + buf->filp = NULL; buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc( buf->dev_priv_size, - DRM_MEM_BUFS ); - if(!buf->dev_private) { + buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); + if (!buf->dev_private) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; - drm_cleanup_buf_error(dev,entry); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( buf->dev_private, 0, buf->dev_priv_size ); + memset(buf->dev_private, 0, buf->dev_priv_size); - DRM_DEBUG( "buffer %d @ %p\n", - entry->buf_count, buf->address ); + DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); offset += alignment; entry->buf_count++; byte_count += PAGE_SIZE << page_order; } - DRM_DEBUG( "byte_count: %d\n", byte_count ); + DRM_DEBUG("byte_count: %d\n", byte_count); - temp_buflist = drm_realloc( dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS ); - if(!temp_buflist) { + temp_buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), DRM_MEM_BUFS); + if (!temp_buflist) { /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev,entry); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } dma->buflist = temp_buflist; - for ( i = 0 ; i < entry->buf_count ; i++ ) { + for (i = 0; i < entry->buf_count; i++) { dma->buflist[i + dma->buf_count] = &entry->buflist[i]; } dma->buf_count += entry->buf_count; dma->byte_count += byte_count; - DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); - DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); + DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); + DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - up( &dev->struct_sem ); + up(&dev->struct_sem); request->count = entry->buf_count; request->size = size; dma->flags = _DRM_DMA_USE_AGP; - atomic_dec( &dev->buf_alloc ); + atomic_dec(&dev->buf_alloc); return 0; } -EXPORT_SYMBOL(drm_addbufs_agp); -#endif /* __OS_HAS_AGP */ -int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) +EXPORT_SYMBOL(drm_addbufs_agp); +#endif /* __OS_HAS_AGP */ + +int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; int count; @@ -684,178 +685,174 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) unsigned long *temp_pagelist; drm_buf_t **temp_buflist; - if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL; - if ( !dma ) return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) + return -EINVAL; + if (!dma) + return -EINVAL; count = request->count; order = drm_order(request->size); size = 1 << order; - DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n", - request->count, request->size, size, - order, dev->queue_count ); + DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n", + request->count, request->size, size, order, dev->queue_count); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; - if ( dev->queue_count ) return -EBUSY; /* Not while in use */ + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) + return -EINVAL; + if (dev->queue_count) + return -EBUSY; /* Not while in use */ alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; + ? PAGE_ALIGN(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - spin_lock( &dev->count_lock ); - if ( dev->buf_use ) { - spin_unlock( &dev->count_lock ); + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); return -EBUSY; } - atomic_inc( &dev->buf_alloc ); - spin_unlock( &dev->count_lock ); + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down( &dev->struct_sem ); + down(&dev->struct_sem); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; /* May only call once for each order */ } if (count < 0 || count > 4096) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -EINVAL; } - entry->buflist = drm_alloc( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - entry->seglist = drm_alloc( count * sizeof(*entry->seglist), - DRM_MEM_SEGS ); - if ( !entry->seglist ) { - drm_free( entry->buflist, - count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + entry->seglist = drm_alloc(count * sizeof(*entry->seglist), + DRM_MEM_SEGS); + if (!entry->seglist) { + drm_free(entry->buflist, + count * sizeof(*entry->buflist), DRM_MEM_BUFS); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( entry->seglist, 0, count * sizeof(*entry->seglist) ); + memset(entry->seglist, 0, count * sizeof(*entry->seglist)); /* Keep the original pagelist until we know all the allocations * have succeeded */ - temp_pagelist = drm_alloc( (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES ); + temp_pagelist = drm_alloc((dma->page_count + (count << page_order)) + * sizeof(*dma->pagelist), DRM_MEM_PAGES); if (!temp_pagelist) { - drm_free( entry->buflist, - count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - drm_free( entry->seglist, - count * sizeof(*entry->seglist), - DRM_MEM_SEGS ); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_free(entry->buflist, + count * sizeof(*entry->buflist), DRM_MEM_BUFS); + drm_free(entry->seglist, + count * sizeof(*entry->seglist), DRM_MEM_SEGS); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } memcpy(temp_pagelist, - dma->pagelist, - dma->page_count * sizeof(*dma->pagelist)); - DRM_DEBUG( "pagelist: %d entries\n", - dma->page_count + (count << page_order) ); + dma->pagelist, dma->page_count * sizeof(*dma->pagelist)); + DRM_DEBUG("pagelist: %d entries\n", + dma->page_count + (count << page_order)); - entry->buf_size = size; + entry->buf_size = size; entry->page_order = page_order; byte_count = 0; page_count = 0; - while ( entry->buf_count < count ) { - page = drm_alloc_pages( page_order, DRM_MEM_DMA ); - if ( !page ) { + while (entry->buf_count < count) { + page = drm_alloc_pages(page_order, DRM_MEM_DMA); + if (!page) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; drm_cleanup_buf_error(dev, entry); - drm_free( temp_pagelist, - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES ); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_free(temp_pagelist, + (dma->page_count + (count << page_order)) + * sizeof(*dma->pagelist), DRM_MEM_PAGES); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } entry->seglist[entry->seg_count++] = page; - for ( i = 0 ; i < (1 << page_order) ; i++ ) { - DRM_DEBUG( "page %d @ 0x%08lx\n", - dma->page_count + page_count, - page + PAGE_SIZE * i ); + for (i = 0; i < (1 << page_order); i++) { + DRM_DEBUG("page %d @ 0x%08lx\n", + dma->page_count + page_count, + page + PAGE_SIZE * i); temp_pagelist[dma->page_count + page_count++] - = page + PAGE_SIZE * i; + = page + PAGE_SIZE * i; } - for ( offset = 0 ; - offset + size <= total && entry->buf_count < count ; - offset += alignment, ++entry->buf_count ) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = (dma->byte_count + byte_count + offset); + for (offset = 0; + offset + size <= total && entry->buf_count < count; + offset += alignment, ++entry->buf_count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + buf->offset = (dma->byte_count + byte_count + offset); buf->address = (void *)(page + offset); - buf->next = NULL; + buf->next = NULL; buf->waiting = 0; buf->pending = 0; - init_waitqueue_head( &buf->dma_wait ); - buf->filp = NULL; + init_waitqueue_head(&buf->dma_wait); + buf->filp = NULL; buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc( buf->dev_priv_size, - DRM_MEM_BUFS ); - if(!buf->dev_private) { + buf->dev_private = drm_alloc(buf->dev_priv_size, + DRM_MEM_BUFS); + if (!buf->dev_private) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; - drm_cleanup_buf_error(dev,entry); - drm_free( temp_pagelist, - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES ); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + drm_free(temp_pagelist, + (dma->page_count + + (count << page_order)) + * sizeof(*dma->pagelist), + DRM_MEM_PAGES); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( buf->dev_private, 0, buf->dev_priv_size ); + memset(buf->dev_private, 0, buf->dev_priv_size); - DRM_DEBUG( "buffer %d @ %p\n", - entry->buf_count, buf->address ); + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); } byte_count += PAGE_SIZE << page_order; } - temp_buflist = drm_realloc( dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS ); + temp_buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), DRM_MEM_BUFS); if (!temp_buflist) { /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev,entry); - drm_free( temp_pagelist, - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES ); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + drm_free(temp_pagelist, + (dma->page_count + (count << page_order)) + * sizeof(*dma->pagelist), DRM_MEM_PAGES); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } dma->buflist = temp_buflist; - for ( i = 0 ; i < entry->buf_count ; i++ ) { + for (i = 0; i < entry->buf_count; i++) { dma->buflist[i + dma->buf_count] = &entry->buflist[i]; } @@ -864,8 +861,8 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) */ if (dma->page_count) { drm_free(dma->pagelist, - dma->page_count * sizeof(*dma->pagelist), - DRM_MEM_PAGES); + dma->page_count * sizeof(*dma->pagelist), + DRM_MEM_PAGES); } dma->pagelist = temp_pagelist; @@ -874,18 +871,19 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - up( &dev->struct_sem ); + up(&dev->struct_sem); request->count = entry->buf_count; request->size = size; - atomic_dec( &dev->buf_alloc ); + atomic_dec(&dev->buf_alloc); return 0; } + EXPORT_SYMBOL(drm_addbufs_pci); -static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) +static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -902,146 +900,147 @@ static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) int i; drm_buf_t **temp_buflist; - if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL; - - if ( !dma ) return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_SG)) + return -EINVAL; + + if (!dma) + return -EINVAL; count = request->count; order = drm_order(request->size); size = 1 << order; - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; + alignment = (request->flags & _DRM_PAGE_ALIGN) + ? PAGE_ALIGN(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; byte_count = 0; agp_offset = request->agp_start; - DRM_DEBUG( "count: %d\n", count ); - DRM_DEBUG( "order: %d\n", order ); - DRM_DEBUG( "size: %d\n", size ); - DRM_DEBUG( "agp_offset: %lu\n", agp_offset ); - DRM_DEBUG( "alignment: %d\n", alignment ); - DRM_DEBUG( "page_order: %d\n", page_order ); - DRM_DEBUG( "total: %d\n", total ); + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %lu\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; - if ( dev->queue_count ) return -EBUSY; /* Not while in use */ + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) + return -EINVAL; + if (dev->queue_count) + return -EBUSY; /* Not while in use */ - spin_lock( &dev->count_lock ); - if ( dev->buf_use ) { - spin_unlock( &dev->count_lock ); + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); return -EBUSY; } - atomic_inc( &dev->buf_alloc ); - spin_unlock( &dev->count_lock ); + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down( &dev->struct_sem ); + down(&dev->struct_sem); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); - return -ENOMEM; /* May only call once for each order */ + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ } if (count < 0 || count > 4096) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -EINVAL; } - entry->buflist = drm_alloc( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); entry->buf_size = size; entry->page_order = page_order; offset = 0; - while ( entry->buf_count < count ) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; + while (entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; - buf->offset = (dma->byte_count + offset); + buf->offset = (dma->byte_count + offset); buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset + buf->address = (void *)(agp_offset + offset + (unsigned long)dev->sg->virtual); - buf->next = NULL; + buf->next = NULL; buf->waiting = 0; buf->pending = 0; - init_waitqueue_head( &buf->dma_wait ); - buf->filp = NULL; + init_waitqueue_head(&buf->dma_wait); + buf->filp = NULL; buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc( buf->dev_priv_size, - DRM_MEM_BUFS ); - if(!buf->dev_private) { + buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); + if (!buf->dev_private) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; - drm_cleanup_buf_error(dev,entry); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } - memset( buf->dev_private, 0, buf->dev_priv_size ); + memset(buf->dev_private, 0, buf->dev_priv_size); - DRM_DEBUG( "buffer %d @ %p\n", - entry->buf_count, buf->address ); + DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); offset += alignment; entry->buf_count++; byte_count += PAGE_SIZE << page_order; } - DRM_DEBUG( "byte_count: %d\n", byte_count ); + DRM_DEBUG("byte_count: %d\n", byte_count); - temp_buflist = drm_realloc( dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS ); - if(!temp_buflist) { + temp_buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), DRM_MEM_BUFS); + if (!temp_buflist) { /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev,entry); - up( &dev->struct_sem ); - atomic_dec( &dev->buf_alloc ); + drm_cleanup_buf_error(dev, entry); + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); return -ENOMEM; } dma->buflist = temp_buflist; - for ( i = 0 ; i < entry->buf_count ; i++ ) { + for (i = 0; i < entry->buf_count; i++) { dma->buflist[i + dma->buf_count] = &entry->buflist[i]; } dma->buf_count += entry->buf_count; dma->byte_count += byte_count; - DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); - DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); + DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); + DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - up( &dev->struct_sem ); + up(&dev->struct_sem); request->count = entry->buf_count; request->size = size; dma->flags = _DRM_DMA_USE_SG; - atomic_dec( &dev->buf_alloc ); + atomic_dec(&dev->buf_alloc); return 0; } -static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request) +static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -1060,7 +1059,7 @@ static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request) if (!drm_core_check_feature(dev, DRIVER_FB_DMA)) return -EINVAL; - + if (!dma) return -EINVAL; @@ -1210,43 +1209,41 @@ static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request) * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent * PCI memory respectively. */ -int drm_addbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_addbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_buf_desc_t request; drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; int ret; - + if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) return -EINVAL; - if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg, - sizeof(request) ) ) + if (copy_from_user(&request, (drm_buf_desc_t __user *) arg, + sizeof(request))) return -EFAULT; #if __OS_HAS_AGP - if ( request.flags & _DRM_AGP_BUFFER ) - ret=drm_addbufs_agp(dev, &request); + if (request.flags & _DRM_AGP_BUFFER) + ret = drm_addbufs_agp(dev, &request); else #endif - if ( request.flags & _DRM_SG_BUFFER ) - ret=drm_addbufs_sg(dev, &request); - else if ( request.flags & _DRM_FB_BUFFER) - ret=drm_addbufs_fb(dev, &request); + if (request.flags & _DRM_SG_BUFFER) + ret = drm_addbufs_sg(dev, &request); + else if (request.flags & _DRM_FB_BUFFER) + ret = drm_addbufs_fb(dev, &request); else - ret=drm_addbufs_pci(dev, &request); + ret = drm_addbufs_pci(dev, &request); - if (ret==0) { - if (copy_to_user((void __user *)arg, &request, - sizeof(request))) { + if (ret == 0) { + if (copy_to_user((void __user *)arg, &request, sizeof(request))) { ret = -EFAULT; } } return ret; } - /** * Get information about the buffer mappings. * @@ -1264,8 +1261,8 @@ int drm_addbufs( struct inode *inode, struct file *filp, * lock, preventing of allocating more buffers after this call. Information * about each requested buffer is then copied into user space. */ -int drm_infobufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_infobufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1278,58 +1275,61 @@ int drm_infobufs( struct inode *inode, struct file *filp, if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) return -EINVAL; - if ( !dma ) return -EINVAL; + if (!dma) + return -EINVAL; - spin_lock( &dev->count_lock ); - if ( atomic_read( &dev->buf_alloc ) ) { - spin_unlock( &dev->count_lock ); + spin_lock(&dev->count_lock); + if (atomic_read(&dev->buf_alloc)) { + spin_unlock(&dev->count_lock); return -EBUSY; } ++dev->buf_use; /* Can't allocate more after this call */ - spin_unlock( &dev->count_lock ); + spin_unlock(&dev->count_lock); - if ( copy_from_user( &request, argp, sizeof(request) ) ) + if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; - for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { - if ( dma->bufs[i].buf_count ) ++count; + for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { + if (dma->bufs[i].buf_count) + ++count; } - DRM_DEBUG( "count = %d\n", count ); + DRM_DEBUG("count = %d\n", count); - if ( request.count >= count ) { - for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { - if ( dma->bufs[i].buf_count ) { - drm_buf_desc_t __user *to = &request.list[count]; + if (request.count >= count) { + for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { + if (dma->bufs[i].buf_count) { + drm_buf_desc_t __user *to = + &request.list[count]; drm_buf_entry_t *from = &dma->bufs[i]; drm_freelist_t *list = &dma->bufs[i].freelist; - if ( copy_to_user( &to->count, - &from->buf_count, - sizeof(from->buf_count) ) || - copy_to_user( &to->size, - &from->buf_size, - sizeof(from->buf_size) ) || - copy_to_user( &to->low_mark, - &list->low_mark, - sizeof(list->low_mark) ) || - copy_to_user( &to->high_mark, - &list->high_mark, - sizeof(list->high_mark) ) ) + if (copy_to_user(&to->count, + &from->buf_count, + sizeof(from->buf_count)) || + copy_to_user(&to->size, + &from->buf_size, + sizeof(from->buf_size)) || + copy_to_user(&to->low_mark, + &list->low_mark, + sizeof(list->low_mark)) || + copy_to_user(&to->high_mark, + &list->high_mark, + sizeof(list->high_mark))) return -EFAULT; - DRM_DEBUG( "%d %d %d %d %d\n", - i, - dma->bufs[i].buf_count, - dma->bufs[i].buf_size, - dma->bufs[i].freelist.low_mark, - dma->bufs[i].freelist.high_mark ); + DRM_DEBUG("%d %d %d %d %d\n", + i, + dma->bufs[i].buf_count, + dma->bufs[i].buf_size, + dma->bufs[i].freelist.low_mark, + dma->bufs[i].freelist.high_mark); ++count; } } } request.count = count; - if ( copy_to_user( argp, &request, sizeof(request) ) ) + if (copy_to_user(argp, &request, sizeof(request))) return -EFAULT; return 0; @@ -1349,8 +1349,8 @@ int drm_infobufs( struct inode *inode, struct file *filp, * * \note This ioctl is deprecated and mostly never used. */ -int drm_markbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_markbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1362,44 +1362,45 @@ int drm_markbufs( struct inode *inode, struct file *filp, if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) return -EINVAL; - if ( !dma ) return -EINVAL; + if (!dma) + return -EINVAL; - if ( copy_from_user( &request, - (drm_buf_desc_t __user *)arg, - sizeof(request) ) ) + if (copy_from_user(&request, + (drm_buf_desc_t __user *) arg, sizeof(request))) return -EFAULT; - DRM_DEBUG( "%d, %d, %d\n", - request.size, request.low_mark, request.high_mark ); - order = drm_order( request.size ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; + DRM_DEBUG("%d, %d, %d\n", + request.size, request.low_mark, request.high_mark); + order = drm_order(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) + return -EINVAL; entry = &dma->bufs[order]; - if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) + if (request.low_mark < 0 || request.low_mark > entry->buf_count) return -EINVAL; - if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) + if (request.high_mark < 0 || request.high_mark > entry->buf_count) return -EINVAL; - entry->freelist.low_mark = request.low_mark; + entry->freelist.low_mark = request.low_mark; entry->freelist.high_mark = request.high_mark; return 0; } /** - * Unreserve the buffers in list, previously reserved using drmDMA. + * Unreserve the buffers in list, previously reserved using drmDMA. * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_buf_free structure. * \return zero on success or a negative number on failure. - * + * * Calls free_buffer() for each used buffer. * This function is primarily used for debugging. */ -int drm_freebufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_freebufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1412,31 +1413,29 @@ int drm_freebufs( struct inode *inode, struct file *filp, if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) return -EINVAL; - if ( !dma ) return -EINVAL; + if (!dma) + return -EINVAL; - if ( copy_from_user( &request, - (drm_buf_free_t __user *)arg, - sizeof(request) ) ) + if (copy_from_user(&request, + (drm_buf_free_t __user *) arg, sizeof(request))) return -EFAULT; - DRM_DEBUG( "%d\n", request.count ); - for ( i = 0 ; i < request.count ; i++ ) { - if ( copy_from_user( &idx, - &request.list[i], - sizeof(idx) ) ) + DRM_DEBUG("%d\n", request.count); + for (i = 0; i < request.count; i++) { + if (copy_from_user(&idx, &request.list[i], sizeof(idx))) return -EFAULT; - if ( idx < 0 || idx >= dma->buf_count ) { - DRM_ERROR( "Index %d (of %d max)\n", - idx, dma->buf_count - 1 ); + if (idx < 0 || idx >= dma->buf_count) { + DRM_ERROR("Index %d (of %d max)\n", + idx, dma->buf_count - 1); return -EINVAL; } buf = dma->buflist[idx]; - if ( buf->filp != filp ) { - DRM_ERROR( "Process %d freeing buffer not owned\n", - current->pid ); + if (buf->filp != filp) { + DRM_ERROR("Process %d freeing buffer not owned\n", + current->pid); return -EINVAL; } - drm_free_buffer( dev, buf ); + drm_free_buffer(dev, buf); } return 0; @@ -1455,8 +1454,8 @@ int drm_freebufs( struct inode *inode, struct file *filp, * about each buffer into user space. The PCI buffers are already mapped on the * addbufs_pci() call. */ -int drm_mapbufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_mapbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1472,86 +1471,84 @@ int drm_mapbufs( struct inode *inode, struct file *filp, if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) return -EINVAL; - if ( !dma ) return -EINVAL; + if (!dma) + return -EINVAL; - spin_lock( &dev->count_lock ); - if ( atomic_read( &dev->buf_alloc ) ) { - spin_unlock( &dev->count_lock ); + spin_lock(&dev->count_lock); + if (atomic_read(&dev->buf_alloc)) { + spin_unlock(&dev->count_lock); return -EBUSY; } dev->buf_use++; /* Can't allocate more after this call */ - spin_unlock( &dev->count_lock ); + spin_unlock(&dev->count_lock); - if ( copy_from_user( &request, argp, sizeof(request) ) ) + if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; - if ( request.count >= dma->buf_count ) { + if (request.count >= dma->buf_count) { if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) - || (drm_core_check_feature(dev, DRIVER_SG) + || (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) || (drm_core_check_feature(dev, DRIVER_FB_DMA) && (dma->flags & _DRM_DMA_USE_FB))) { drm_map_t *map = dev->agp_buffer_map; unsigned long token = dev->agp_buffer_token; - if ( !map ) { + if (!map) { retcode = -EINVAL; goto done; } - down_write( ¤t->mm->mmap_sem ); - virtual = do_mmap( filp, 0, map->size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - token ); - up_write( ¤t->mm->mmap_sem ); + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ | PROT_WRITE, + MAP_SHARED, token); + up_write(¤t->mm->mmap_sem); } else { - down_write( ¤t->mm->mmap_sem ); - virtual = do_mmap( filp, 0, dma->byte_count, - PROT_READ | PROT_WRITE, - MAP_SHARED, 0 ); - up_write( ¤t->mm->mmap_sem ); + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ | PROT_WRITE, + MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); } - if ( virtual > -1024UL ) { + if (virtual > -1024UL) { /* Real error */ retcode = (signed long)virtual; goto done; } request.virtual = (void __user *)virtual; - for ( i = 0 ; i < dma->buf_count ; i++ ) { - if ( copy_to_user( &request.list[i].idx, - &dma->buflist[i]->idx, - sizeof(request.list[0].idx) ) ) { + for (i = 0; i < dma->buf_count; i++) { + if (copy_to_user(&request.list[i].idx, + &dma->buflist[i]->idx, + sizeof(request.list[0].idx))) { retcode = -EFAULT; goto done; } - if ( copy_to_user( &request.list[i].total, - &dma->buflist[i]->total, - sizeof(request.list[0].total) ) ) { + if (copy_to_user(&request.list[i].total, + &dma->buflist[i]->total, + sizeof(request.list[0].total))) { retcode = -EFAULT; goto done; } - if ( copy_to_user( &request.list[i].used, - &zero, - sizeof(zero) ) ) { + if (copy_to_user(&request.list[i].used, + &zero, sizeof(zero))) { retcode = -EFAULT; goto done; } - address = virtual + dma->buflist[i]->offset; /* *** */ - if ( copy_to_user( &request.list[i].address, - &address, - sizeof(address) ) ) { + address = virtual + dma->buflist[i]->offset; /* *** */ + if (copy_to_user(&request.list[i].address, + &address, sizeof(address))) { retcode = -EFAULT; goto done; } } } - done: + done: request.count = dma->buf_count; - DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode ); + DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - if ( copy_to_user( argp, &request, sizeof(request) ) ) + if (copy_to_user(argp, &request, sizeof(request))) return -EFAULT; return retcode; @@ -1560,23 +1557,23 @@ int drm_mapbufs( struct inode *inode, struct file *filp, /** * Compute size order. Returns the exponent of the smaller power of two which * is greater or equal to given number. - * + * * \param size size. * \return order. * * \todo Can be made faster. */ -int drm_order( unsigned long size ) +int drm_order(unsigned long size) { int order; unsigned long tmp; - for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) - ; + for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ; if (size & (size - 1)) ++order; return order; } + EXPORT_SYMBOL(drm_order); diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c index 502892794c16..6380127be281 100644 --- a/drivers/char/drm/drm_context.c +++ b/drivers/char/drm/drm_context.c @@ -1,7 +1,7 @@ /** - * \file drm_context.h + * \file drm_context.c * IOCTLs for generic contexts - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -56,25 +56,26 @@ * in drm_device::context_sareas, while holding the drm_device::struct_sem * lock. */ -void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle ) +void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) { - if ( ctx_handle < 0 ) goto failed; - if ( !dev->ctx_bitmap ) goto failed; + if (ctx_handle < 0) + goto failed; + if (!dev->ctx_bitmap) + goto failed; - if ( ctx_handle < DRM_MAX_CTXBITMAP ) { + if (ctx_handle < DRM_MAX_CTXBITMAP) { down(&dev->struct_sem); - clear_bit( ctx_handle, dev->ctx_bitmap ); + clear_bit(ctx_handle, dev->ctx_bitmap); dev->context_sareas[ctx_handle] = NULL; up(&dev->struct_sem); return; } -failed: - DRM_ERROR( "Attempt to free invalid context handle: %d\n", - ctx_handle ); - return; + failed: + DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle); + return; } -/** +/** * Context bitmap allocation. * * \param dev DRM device. @@ -84,29 +85,33 @@ void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle ) * drm_device::context_sareas to accommodate the new entry while holding the * drm_device::struct_sem lock. */ -static int drm_ctxbitmap_next( drm_device_t *dev ) +static int drm_ctxbitmap_next(drm_device_t * dev) { int bit; - if(!dev->ctx_bitmap) return -1; + if (!dev->ctx_bitmap) + return -1; down(&dev->struct_sem); - bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP ); - if ( bit < DRM_MAX_CTXBITMAP ) { - set_bit( bit, dev->ctx_bitmap ); - DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit ); - if((bit+1) > dev->max_context) { - dev->max_context = (bit+1); - if(dev->context_sareas) { + bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); + if (bit < DRM_MAX_CTXBITMAP) { + set_bit(bit, dev->ctx_bitmap); + DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit); + if ((bit + 1) > dev->max_context) { + dev->max_context = (bit + 1); + if (dev->context_sareas) { drm_map_t **ctx_sareas; ctx_sareas = drm_realloc(dev->context_sareas, - (dev->max_context - 1) * - sizeof(*dev->context_sareas), - dev->max_context * - sizeof(*dev->context_sareas), - DRM_MEM_MAPS); - if(!ctx_sareas) { + (dev->max_context - + 1) * + sizeof(*dev-> + context_sareas), + dev->max_context * + sizeof(*dev-> + context_sareas), + DRM_MEM_MAPS); + if (!ctx_sareas) { clear_bit(bit, dev->ctx_bitmap); up(&dev->struct_sem); return -1; @@ -115,11 +120,11 @@ static int drm_ctxbitmap_next( drm_device_t *dev ) dev->context_sareas[bit] = NULL; } else { /* max_context == 1 at this point */ - dev->context_sareas = drm_alloc( - dev->max_context * - sizeof(*dev->context_sareas), - DRM_MEM_MAPS); - if(!dev->context_sareas) { + dev->context_sareas = + drm_alloc(dev->max_context * + sizeof(*dev->context_sareas), + DRM_MEM_MAPS); + if (!dev->context_sareas) { clear_bit(bit, dev->ctx_bitmap); up(&dev->struct_sem); return -1; @@ -142,26 +147,26 @@ static int drm_ctxbitmap_next( drm_device_t *dev ) * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding * the drm_device::struct_sem lock. */ -int drm_ctxbitmap_init( drm_device_t *dev ) +int drm_ctxbitmap_init(drm_device_t * dev) { int i; - int temp; + int temp; down(&dev->struct_sem); - dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE, - DRM_MEM_CTXBITMAP ); - if ( dev->ctx_bitmap == NULL ) { + dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE, + DRM_MEM_CTXBITMAP); + if (dev->ctx_bitmap == NULL) { up(&dev->struct_sem); return -ENOMEM; } - memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE ); + memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE); dev->context_sareas = NULL; dev->max_context = -1; up(&dev->struct_sem); - for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { - temp = drm_ctxbitmap_next( dev ); - DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp ); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { + temp = drm_ctxbitmap_next(dev); + DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp); } return 0; @@ -175,14 +180,14 @@ int drm_ctxbitmap_init( drm_device_t *dev ) * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding * the drm_device::struct_sem lock. */ -void drm_ctxbitmap_cleanup( drm_device_t *dev ) +void drm_ctxbitmap_cleanup(drm_device_t * dev) { down(&dev->struct_sem); - if( dev->context_sareas ) drm_free( dev->context_sareas, - sizeof(*dev->context_sareas) * - dev->max_context, - DRM_MEM_MAPS ); - drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP ); + if (dev->context_sareas) + drm_free(dev->context_sareas, + sizeof(*dev->context_sareas) * + dev->max_context, DRM_MEM_MAPS); + drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); up(&dev->struct_sem); } @@ -194,7 +199,7 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev ) /** * Get per-context SAREA. - * + * * \param inode device inode. * \param filp file pointer. * \param cmd command. @@ -205,10 +210,10 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev ) * returns its handle. */ int drm_getsareactx(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_ctx_priv_map_t __user *argp = (void __user *)arg; drm_ctx_priv_map_t request; drm_map_t *map; @@ -218,7 +223,8 @@ int drm_getsareactx(struct inode *inode, struct file *filp, return -EFAULT; down(&dev->struct_sem); - if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) { + if (dev->max_context < 0 + || request.ctx_id >= (unsigned)dev->max_context) { up(&dev->struct_sem); return -EINVAL; } @@ -227,16 +233,16 @@ int drm_getsareactx(struct inode *inode, struct file *filp, up(&dev->struct_sem); request.handle = 0; - list_for_each_entry(_entry, &dev->maplist->head,head) { + list_for_each_entry(_entry, &dev->maplist->head, head) { if (_entry->map == map) { - request.handle = (void *)(unsigned long)_entry->user_token; + request.handle = + (void *)(unsigned long)_entry->user_token; break; } } if (request.handle == 0) return -EINVAL; - if (copy_to_user(argp, &request, sizeof(request))) return -EFAULT; return 0; @@ -244,7 +250,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp, /** * Set per-context SAREA. - * + * * \param inode device inode. * \param filp file pointer. * \param cmd command. @@ -255,37 +261,37 @@ int drm_getsareactx(struct inode *inode, struct file *filp, * drm_device::context_sareas with it. */ int drm_setsareactx(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_ctx_priv_map_t request; drm_map_t *map = NULL; drm_map_list_t *r_list = NULL; struct list_head *list; if (copy_from_user(&request, - (drm_ctx_priv_map_t __user *)arg, - sizeof(request))) + (drm_ctx_priv_map_t __user *) arg, sizeof(request))) return -EFAULT; down(&dev->struct_sem); list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); if (r_list->map - && r_list->user_token == (unsigned long) request.handle) + && r_list->user_token == (unsigned long)request.handle) goto found; } -bad: + bad: up(&dev->struct_sem); return -EINVAL; -found: + found: map = r_list->map; - if (!map) goto bad; + if (!map) + goto bad; if (dev->max_context < 0) goto bad; - if (request.ctx_id >= (unsigned) dev->max_context) + if (request.ctx_id >= (unsigned)dev->max_context) goto bad; dev->context_sareas[request.ctx_id] = map; up(&dev->struct_sem); @@ -308,22 +314,21 @@ int drm_setsareactx(struct inode *inode, struct file *filp, * * Attempt to set drm_device::context_flag. */ -static int drm_context_switch( drm_device_t *dev, int old, int new ) +static int drm_context_switch(drm_device_t * dev, int old, int new) { - if ( test_and_set_bit( 0, &dev->context_flag ) ) { - DRM_ERROR( "Reentering -- FIXME\n" ); - return -EBUSY; - } + if (test_and_set_bit(0, &dev->context_flag)) { + DRM_ERROR("Reentering -- FIXME\n"); + return -EBUSY; + } + DRM_DEBUG("Context switch from %d to %d\n", old, new); - DRM_DEBUG( "Context switch from %d to %d\n", old, new ); + if (new == dev->last_context) { + clear_bit(0, &dev->context_flag); + return 0; + } - if ( new == dev->last_context ) { - clear_bit( 0, &dev->context_flag ); - return 0; - } - - return 0; + return 0; } /** @@ -337,22 +342,22 @@ static int drm_context_switch( drm_device_t *dev, int old, int new ) * hardware lock is held, clears the drm_device::context_flag and wakes up * drm_device::context_wait. */ -static int drm_context_switch_complete( drm_device_t *dev, int new ) +static int drm_context_switch_complete(drm_device_t * dev, int new) { - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ + dev->last_switch = jiffies; - if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) { - DRM_ERROR( "Lock isn't held after context switch\n" ); - } + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); + } - /* If a context switch is ever initiated - when the kernel holds the lock, release - that lock here. */ - clear_bit( 0, &dev->context_flag ); - wake_up( &dev->context_wait ); + /* If a context switch is ever initiated + when the kernel holds the lock, release + that lock here. */ + clear_bit(0, &dev->context_flag); + wake_up(&dev->context_wait); - return 0; + return 0; } /** @@ -364,29 +369,28 @@ static int drm_context_switch_complete( drm_device_t *dev, int new ) * \param arg user argument pointing to a drm_ctx_res structure. * \return zero on success or a negative number on failure. */ -int drm_resctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_resctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_ctx_res_t res; drm_ctx_t __user *argp = (void __user *)arg; drm_ctx_t ctx; int i; - if ( copy_from_user( &res, argp, sizeof(res) ) ) + if (copy_from_user(&res, argp, sizeof(res))) return -EFAULT; - if ( res.count >= DRM_RESERVED_CONTEXTS ) { - memset( &ctx, 0, sizeof(ctx) ); - for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { + if (res.count >= DRM_RESERVED_CONTEXTS) { + memset(&ctx, 0, sizeof(ctx)); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if ( copy_to_user( &res.contexts[i], - &ctx, sizeof(ctx) ) ) + if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx))) return -EFAULT; } } res.count = DRM_RESERVED_CONTEXTS; - if ( copy_to_user( argp, &res, sizeof(res) ) ) + if (copy_to_user(argp, &res, sizeof(res))) return -EFAULT; return 0; } @@ -402,58 +406,57 @@ int drm_resctx( struct inode *inode, struct file *filp, * * Get a new handle for the context and copy to userspace. */ -int drm_addctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_addctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_ctx_list_t * ctx_entry; + drm_ctx_list_t *ctx_entry; drm_ctx_t __user *argp = (void __user *)arg; drm_ctx_t ctx; - if ( copy_from_user( &ctx, argp, sizeof(ctx) ) ) + if (copy_from_user(&ctx, argp, sizeof(ctx))) return -EFAULT; - ctx.handle = drm_ctxbitmap_next( dev ); - if ( ctx.handle == DRM_KERNEL_CONTEXT ) { - /* Skip kernel's context and get a new one. */ - ctx.handle = drm_ctxbitmap_next( dev ); + ctx.handle = drm_ctxbitmap_next(dev); + if (ctx.handle == DRM_KERNEL_CONTEXT) { + /* Skip kernel's context and get a new one. */ + ctx.handle = drm_ctxbitmap_next(dev); } - DRM_DEBUG( "%d\n", ctx.handle ); - if ( ctx.handle == -1 ) { - DRM_DEBUG( "Not enough free contexts.\n" ); - /* Should this return -EBUSY instead? */ + DRM_DEBUG("%d\n", ctx.handle); + if (ctx.handle == -1) { + DRM_DEBUG("Not enough free contexts.\n"); + /* Should this return -EBUSY instead? */ return -ENOMEM; } - if ( ctx.handle != DRM_KERNEL_CONTEXT ) - { + if (ctx.handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_ctor) dev->driver->context_ctor(dev, ctx.handle); } - ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST ); - if ( !ctx_entry ) { + ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST); + if (!ctx_entry) { DRM_DEBUG("out of memory\n"); return -ENOMEM; } - INIT_LIST_HEAD( &ctx_entry->head ); + INIT_LIST_HEAD(&ctx_entry->head); ctx_entry->handle = ctx.handle; ctx_entry->tag = priv; - down( &dev->ctxlist_sem ); - list_add( &ctx_entry->head, &dev->ctxlist->head ); + down(&dev->ctxlist_sem); + list_add(&ctx_entry->head, &dev->ctxlist->head); ++dev->ctx_count; - up( &dev->ctxlist_sem ); + up(&dev->ctxlist_sem); - if ( copy_to_user( argp, &ctx, sizeof(ctx) ) ) + if (copy_to_user(argp, &ctx, sizeof(ctx))) return -EFAULT; return 0; } -int drm_modctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_modctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { /* This does nothing */ return 0; @@ -468,19 +471,19 @@ int drm_modctx( struct inode *inode, struct file *filp, * \param arg user argument pointing to a drm_ctx structure. * \return zero on success or a negative number on failure. */ -int drm_getctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_getctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_ctx_t __user *argp = (void __user *)arg; drm_ctx_t ctx; - if ( copy_from_user( &ctx, argp, sizeof(ctx) ) ) + if (copy_from_user(&ctx, argp, sizeof(ctx))) return -EFAULT; /* This is 0, because we don't handle any context flags */ ctx.flags = 0; - if ( copy_to_user( argp, &ctx, sizeof(ctx) ) ) + if (copy_to_user(argp, &ctx, sizeof(ctx))) return -EFAULT; return 0; } @@ -496,18 +499,18 @@ int drm_getctx( struct inode *inode, struct file *filp, * * Calls context_switch(). */ -int drm_switchctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_switchctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_ctx_t ctx; - if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) ) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; - DRM_DEBUG( "%d\n", ctx.handle ); - return drm_context_switch( dev, dev->last_context, ctx.handle ); + DRM_DEBUG("%d\n", ctx.handle); + return drm_context_switch(dev, dev->last_context, ctx.handle); } /** @@ -521,18 +524,18 @@ int drm_switchctx( struct inode *inode, struct file *filp, * * Calls context_switch_complete(). */ -int drm_newctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_newctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_ctx_t ctx; - if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) ) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; - DRM_DEBUG( "%d\n", ctx.handle ); - drm_context_switch_complete( dev, ctx.handle ); + DRM_DEBUG("%d\n", ctx.handle); + drm_context_switch_complete(dev, ctx.handle); return 0; } @@ -548,42 +551,41 @@ int drm_newctx( struct inode *inode, struct file *filp, * * If not the special kernel context, calls ctxbitmap_free() to free the specified context. */ -int drm_rmctx( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_rmctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_ctx_t ctx; - if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) ) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; - DRM_DEBUG( "%d\n", ctx.handle ); - if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) { + DRM_DEBUG("%d\n", ctx.handle); + if (ctx.handle == DRM_KERNEL_CONTEXT + 1) { priv->remove_auth_on_close = 1; } - if ( ctx.handle != DRM_KERNEL_CONTEXT ) { + if (ctx.handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_dtor) dev->driver->context_dtor(dev, ctx.handle); - drm_ctxbitmap_free( dev, ctx.handle ); + drm_ctxbitmap_free(dev, ctx.handle); } - down( &dev->ctxlist_sem ); - if ( !list_empty( &dev->ctxlist->head ) ) { + down(&dev->ctxlist_sem); + if (!list_empty(&dev->ctxlist->head)) { drm_ctx_list_t *pos, *n; - list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) { - if ( pos->handle == ctx.handle ) { - list_del( &pos->head ); - drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST ); + list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) { + if (pos->handle == ctx.handle) { + list_del(&pos->head); + drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); --dev->ctx_count; } } } - up( &dev->ctxlist_sem ); + up(&dev->ctxlist_sem); return 0; } /*@}*/ - diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c index 4a28c053c98b..2afab95ca036 100644 --- a/drivers/char/drm/drm_dma.c +++ b/drivers/char/drm/drm_dma.c @@ -1,5 +1,5 @@ /** - * \file drm_dma.h + * \file drm_dma.c * DMA IOCTL and function support * * \author Rickard E. (Rik) Faith @@ -37,23 +37,23 @@ /** * Initialize the DMA data. - * + * * \param dev DRM device. * \return zero on success or a negative value on failure. * * Allocate and initialize a drm_device_dma structure. */ -int drm_dma_setup( drm_device_t *dev ) +int drm_dma_setup(drm_device_t * dev) { int i; - dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER ); - if ( !dev->dma ) + dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER); + if (!dev->dma) return -ENOMEM; - memset( dev->dma, 0, sizeof(*dev->dma) ); + memset(dev->dma, 0, sizeof(*dev->dma)); - for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ ) + for (i = 0; i <= DRM_MAX_ORDER; i++) memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); return 0; @@ -67,14 +67,15 @@ int drm_dma_setup( drm_device_t *dev ) * Free all pages associated with DMA buffers, the buffers and pages lists, and * finally the the drm_device::dma structure itself. */ -void drm_dma_takedown(drm_device_t *dev) +void drm_dma_takedown(drm_device_t * dev) { - drm_device_dma_t *dma = dev->dma; - int i, j; + drm_device_dma_t *dma = dev->dma; + int i, j; - if (!dma) return; + if (!dma) + return; - /* Clear dma buffers */ + /* Clear dma buffers */ for (i = 0; i <= DRM_MAX_ORDER; i++) { if (dma->bufs[i].seg_count) { DRM_DEBUG("order %d: buf_count = %d," @@ -85,64 +86,63 @@ void drm_dma_takedown(drm_device_t *dev) for (j = 0; j < dma->bufs[i].seg_count; j++) { if (dma->bufs[i].seglist[j]) { drm_free_pages(dma->bufs[i].seglist[j], - dma->bufs[i].page_order, - DRM_MEM_DMA); + dma->bufs[i].page_order, + DRM_MEM_DMA); } } drm_free(dma->bufs[i].seglist, - dma->bufs[i].seg_count - * sizeof(*dma->bufs[0].seglist), - DRM_MEM_SEGS); + dma->bufs[i].seg_count + * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS); } - if (dma->bufs[i].buf_count) { - for (j = 0; j < dma->bufs[i].buf_count; j++) { + if (dma->bufs[i].buf_count) { + for (j = 0; j < dma->bufs[i].buf_count; j++) { if (dma->bufs[i].buflist[j].dev_private) { - drm_free(dma->bufs[i].buflist[j].dev_private, - dma->bufs[i].buflist[j].dev_priv_size, - DRM_MEM_BUFS); + drm_free(dma->bufs[i].buflist[j]. + dev_private, + dma->bufs[i].buflist[j]. + dev_priv_size, DRM_MEM_BUFS); } } - drm_free(dma->bufs[i].buflist, - dma->bufs[i].buf_count * - sizeof(*dma->bufs[0].buflist), - DRM_MEM_BUFS); + drm_free(dma->bufs[i].buflist, + dma->bufs[i].buf_count * + sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS); } } if (dma->buflist) { drm_free(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - DRM_MEM_BUFS); + dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS); } if (dma->pagelist) { drm_free(dma->pagelist, - dma->page_count * sizeof(*dma->pagelist), - DRM_MEM_PAGES); + dma->page_count * sizeof(*dma->pagelist), + DRM_MEM_PAGES); } drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); dev->dma = NULL; } - /** * Free a buffer. * * \param dev DRM device. * \param buf buffer to free. - * + * * Resets the fields of \p buf. */ -void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf) +void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf) { - if (!buf) return; + if (!buf) + return; - buf->waiting = 0; - buf->pending = 0; - buf->filp = NULL; - buf->used = 0; + buf->waiting = 0; + buf->pending = 0; + buf->filp = NULL; + buf->used = 0; - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) { + if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) + && waitqueue_active(&buf->dma_wait)) { wake_up_interruptible(&buf->dma_wait); } } @@ -154,12 +154,13 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf) * * Frees each buffer associated with \p filp not already on the hardware. */ -void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp) +void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp) { drm_device_dma_t *dma = dev->dma; - int i; + int i; - if (!dma) return; + if (!dma) + return; for (i = 0; i < dma->buf_count; i++) { if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { @@ -176,5 +177,5 @@ void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp) } } } -EXPORT_SYMBOL(drm_core_reclaim_buffers); +EXPORT_SYMBOL(drm_core_reclaim_buffers); diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c index e8e8e42be4c7..7857453c4f48 100644 --- a/drivers/char/drm/drm_drawable.c +++ b/drivers/char/drm/drm_drawable.c @@ -1,5 +1,5 @@ /** - * \file drm_drawable.h + * \file drm_drawable.c * IOCTLs for drawables * * \author Rickard E. (Rik) Faith @@ -37,20 +37,20 @@ /** No-op. */ int drm_adddraw(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_draw_t draw; draw.handle = 0; /* NOOP */ DRM_DEBUG("%d\n", draw.handle); - if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw))) + if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw))) return -EFAULT; return 0; } /** No-op. */ int drm_rmdraw(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return 0; /* NOOP */ } diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 6ba48f346fcf..26733248ff4a 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c @@ -1,5 +1,5 @@ /** - * \file drm_drv.h + * \file drm_drv.c * Generic driver template * * \author Rickard E. (Rik) Faith @@ -55,67 +55,67 @@ static int drm_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); /** Ioctl table */ -static drm_ioctl_desc_t drm_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, 0, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, 0, 1 }, +static drm_ioctl_desc_t drm_ioctls[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1}, - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1}, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1}, - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0}, /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1}, #if __OS_HAS_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, #endif - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1}, - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0}, }; #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) @@ -129,17 +129,17 @@ static drm_ioctl_desc_t drm_ioctls[] = { * * \sa drm_device */ -int drm_takedown( drm_device_t *dev ) +int drm_takedown(drm_device_t * dev) { drm_magic_entry_t *pt, *next; drm_map_list_t *r_list; drm_vma_entry_t *vma, *vma_next; int i; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); if (dev->driver->pretakedown) - dev->driver->pretakedown(dev); + dev->driver->pretakedown(dev); DRM_DEBUG("driver pretakedown completed\n"); if (dev->unique) { @@ -148,95 +148,95 @@ int drm_takedown( drm_device_t *dev ) dev->unique_len = 0; } - if ( dev->irq_enabled ) drm_irq_uninstall( dev ); + if (dev->irq_enabled) + drm_irq_uninstall(dev); - down( &dev->struct_sem ); - del_timer( &dev->timer ); + down(&dev->struct_sem); + del_timer(&dev->timer); - /* Clear pid list */ - for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { - for ( pt = dev->magiclist[i].head ; pt ; pt = next ) { + /* Clear pid list */ + for (i = 0; i < DRM_HASH_SIZE; i++) { + for (pt = dev->magiclist[i].head; pt; pt = next) { next = pt->next; - drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC ); + drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } - /* Clear AGP information */ + /* Clear AGP information */ if (drm_core_has_AGP(dev) && dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ - for ( entry = dev->agp->memory ; entry ; entry = nexte ) { + /* Remove AGP resources, but leave dev->agp + intact until drv_cleanup is called. */ + for (entry = dev->agp->memory; entry; entry = nexte) { nexte = entry->next; - if ( entry->bound ) drm_unbind_agp( entry->memory ); - drm_free_agp( entry->memory, entry->pages ); - drm_free( entry, sizeof(*entry), DRM_MEM_AGPLISTS ); + if (entry->bound) + drm_unbind_agp(entry->memory); + drm_free_agp(entry->memory, entry->pages); + drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; if (dev->agp->acquired) - drm_agp_release(dev); + drm_agp_release(dev); dev->agp->acquired = 0; - dev->agp->enabled = 0; + dev->agp->enabled = 0; } if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { drm_sg_cleanup(dev->sg); dev->sg = NULL; } - /* Clear vma list (only built for debugging) */ - if ( dev->vmalist ) { - for ( vma = dev->vmalist ; vma ; vma = vma_next ) { + /* Clear vma list (only built for debugging) */ + if (dev->vmalist) { + for (vma = dev->vmalist; vma; vma = vma_next) { vma_next = vma->next; - drm_free( vma, sizeof(*vma), DRM_MEM_VMAS ); + drm_free(vma, sizeof(*vma), DRM_MEM_VMAS); } dev->vmalist = NULL; } - if( dev->maplist ) { + if (dev->maplist) { while (!list_empty(&dev->maplist->head)) { struct list_head *list = dev->maplist->head.next; r_list = list_entry(list, drm_map_list_t, head); drm_rmmap_locked(dev, r_list->map); } - } + } - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { - for ( i = 0 ; i < dev->queue_count ; i++ ) { - if ( dev->queuelist[i] ) { - drm_free( dev->queuelist[i], - sizeof(*dev->queuelist[0]), - DRM_MEM_QUEUES ); + if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { + for (i = 0; i < dev->queue_count; i++) { + if (dev->queuelist[i]) { + drm_free(dev->queuelist[i], + sizeof(*dev->queuelist[0]), + DRM_MEM_QUEUES); dev->queuelist[i] = NULL; } } - drm_free( dev->queuelist, - dev->queue_slots * sizeof(*dev->queuelist), - DRM_MEM_QUEUES ); + drm_free(dev->queuelist, + dev->queue_slots * sizeof(*dev->queuelist), + DRM_MEM_QUEUES); dev->queuelist = NULL; } dev->queue_count = 0; if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - drm_dma_takedown( dev ); + drm_dma_takedown(dev); - if ( dev->lock.hw_lock ) { - dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ + if (dev->lock.hw_lock) { + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.filp = NULL; - wake_up_interruptible( &dev->lock.lock_queue ); + wake_up_interruptible(&dev->lock.lock_queue); } - up( &dev->struct_sem ); + up(&dev->struct_sem); DRM_DEBUG("takedown completed\n"); return 0; } - - /** * Module initialization. Called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). @@ -246,26 +246,28 @@ int drm_takedown( drm_device_t *dev ) * Initializes an array of drm_device structures, and attempts to * initialize all available devices, using consecutive minors, registering the * stubs and initializing the AGP device. - * + * * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and * after the initialization for driver customization. */ -int drm_init( struct drm_driver *driver ) +int drm_init(struct drm_driver *driver) { struct pci_dev *pdev = NULL; struct pci_device_id *pid; int i; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); drm_mem_init(); - for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) { + for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; - - pdev=NULL; - /* pass back in pdev to account for multiple identical cards */ - while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) { + + pdev = NULL; + /* pass back in pdev to account for multiple identical cards */ + while ((pdev = + pci_get_subsys(pid->vendor, pid->device, pid->subvendor, + pid->subdevice, pdev)) != NULL) { /* stealth mode requires a manual probe */ pci_dev_get(pdev); drm_get_dev(pdev, pid, driver); @@ -273,62 +275,63 @@ int drm_init( struct drm_driver *driver ) } return 0; } + EXPORT_SYMBOL(drm_init); /** * Called via cleanup_module() at module unload time. * * Cleans up all DRM device, calling takedown(). - * + * * \sa drm_init */ -static void drm_cleanup( drm_device_t *dev ) +static void drm_cleanup(drm_device_t * dev) { - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); if (!dev) { DRM_ERROR("cleanup called no dev\n"); return; } - drm_takedown( dev ); + drm_takedown(dev); if (dev->maplist) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; } - drm_ctxbitmap_cleanup( dev ); - + drm_ctxbitmap_cleanup(dev); + if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp && dev->agp->agp_mtrr >= 0) { int retval; - retval = mtrr_del( dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024 ); - DRM_DEBUG( "mtrr_del=%d\n", retval ); + retval = mtrr_del(dev->agp->agp_mtrr, + dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * 1024 * 1024); + DRM_DEBUG("mtrr_del=%d\n", retval); } - - if (drm_core_has_AGP(dev) && dev->agp ) { - drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); + + if (drm_core_has_AGP(dev) && dev->agp) { + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } if (dev->driver->postcleanup) dev->driver->postcleanup(dev); - + drm_put_head(&dev->primary); - if ( drm_put_dev(dev) ) - DRM_ERROR( "Cannot unload module\n" ); + if (drm_put_dev(dev)) + DRM_ERROR("Cannot unload module\n"); } -void drm_exit (struct drm_driver *driver) +void drm_exit(struct drm_driver *driver) { int i; drm_device_t *dev = NULL; drm_head_t *head; - - DRM_DEBUG( "\n" ); + + DRM_DEBUG("\n"); for (i = 0; i < drm_cards_limit; i++) { head = drm_heads[i]; @@ -336,9 +339,9 @@ void drm_exit (struct drm_driver *driver) continue; if (!head->dev) continue; - if (head->dev->driver!=driver) + if (head->dev->driver != driver) continue; - dev=head->dev; + dev = head->dev; } if (dev) { /* release the pci driver */ @@ -346,32 +349,35 @@ void drm_exit (struct drm_driver *driver) pci_dev_put(dev->pdev); drm_cleanup(dev); } - DRM_INFO( "Module unloaded\n" ); + DRM_INFO("Module unloaded\n"); } + EXPORT_SYMBOL(drm_exit); /** File operations structure */ static struct file_operations drm_stub_fops = { .owner = THIS_MODULE, - .open = drm_stub_open + .open = drm_stub_open }; static int __init drm_core_init(void) { int ret = -ENOMEM; - - drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); - drm_heads = drm_calloc(drm_cards_limit, - sizeof(*drm_heads), DRM_MEM_STUB); - if(!drm_heads) + + drm_cards_limit = + (drm_cards_limit < + DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); + drm_heads = + drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); + if (!drm_heads) goto err_p1; - + if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) goto err_p1; - + drm_class = drm_sysfs_create(THIS_MODULE, "drm"); if (IS_ERR(drm_class)) { - printk (KERN_ERR "DRM: Error creating drm class.\n"); + printk(KERN_ERR "DRM: Error creating drm class.\n"); ret = PTR_ERR(drm_class); goto err_p2; } @@ -382,35 +388,31 @@ static int __init drm_core_init(void) ret = -1; goto err_p3; } - - DRM_INFO( "Initialized %s %d.%d.%d %s\n", - CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, - CORE_DATE); + + DRM_INFO("Initialized %s %d.%d.%d %s\n", + CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); return 0; -err_p3: + err_p3: drm_sysfs_destroy(drm_class); -err_p2: + err_p2: unregister_chrdev(DRM_MAJOR, "drm"); drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); -err_p1: + err_p1: return ret; } -static void __exit drm_core_exit (void) +static void __exit drm_core_exit(void) { remove_proc_entry("dri", NULL); drm_sysfs_destroy(drm_class); unregister_chrdev(DRM_MAJOR, "drm"); - drm_free(drm_heads, sizeof(*drm_heads) * - drm_cards_limit, DRM_MEM_STUB); + drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); } - -module_init( drm_core_init ); -module_exit( drm_core_exit ); - +module_init(drm_core_init); +module_exit(drm_core_exit); /** * Get version information @@ -423,8 +425,8 @@ module_exit( drm_core_exit ); * * Fills in the version information in \p arg. */ -static int drm_version( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +static int drm_version(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -432,21 +434,19 @@ static int drm_version( struct inode *inode, struct file *filp, drm_version_t version; int ret; - if ( copy_from_user( &version, argp, sizeof(version) ) ) + if (copy_from_user(&version, argp, sizeof(version))) return -EFAULT; /* version is a required function to return the personality module version */ if ((ret = dev->driver->version(&version))) return ret; - - if ( copy_to_user( argp, &version, sizeof(version) ) ) + + if (copy_to_user(argp, &version, sizeof(version))) return -EFAULT; return 0; } - - -/** +/** * Called whenever a process performs an ioctl on /dev/drm. * * \param inode device inode. @@ -458,8 +458,8 @@ static int drm_version( struct inode *inode, struct file *filp, * Looks up the ioctl function in the ::ioctls table, checking for root * previleges if so required, and dispatches to the respective function. */ -int drm_ioctl( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -468,40 +468,43 @@ int drm_ioctl( struct inode *inode, struct file *filp, unsigned int nr = DRM_IOCTL_NR(cmd); int retcode = -EINVAL; - atomic_inc( &dev->ioctl_count ); - atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); + atomic_inc(&dev->ioctl_count); + atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); ++priv->ioctl_count; - DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - current->pid, cmd, nr, (long)old_encode_dev(priv->head->device), - priv->authenticated ); - + DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + current->pid, cmd, nr, + (long)old_encode_dev(priv->head->device), + priv->authenticated); + if (nr < DRIVER_IOCTL_COUNT) ioctl = &drm_ioctls[nr]; - else if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) + else if ((nr >= DRM_COMMAND_BASE) + && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; else goto err_i1; - + func = ioctl->func; /* is there a local override? */ if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl) func = dev->driver->dma_ioctl; - - if ( !func ) { - DRM_DEBUG( "no function\n" ); + + if (!func) { + DRM_DEBUG("no function\n"); retcode = -EINVAL; - } else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )|| - ( ioctl->auth_needed && !priv->authenticated ) ) { + } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) || + (ioctl->auth_needed && !priv->authenticated)) { retcode = -EACCES; } else { - retcode = func( inode, filp, cmd, arg ); + retcode = func(inode, filp, cmd, arg); } - -err_i1: - atomic_dec( &dev->ioctl_count ); - if (retcode) DRM_DEBUG( "ret = %x\n", retcode); + + err_i1: + atomic_dec(&dev->ioctl_count); + if (retcode) + DRM_DEBUG("ret = %x\n", retcode); return retcode; } -EXPORT_SYMBOL(drm_ioctl); +EXPORT_SYMBOL(drm_ioctl); diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index a1f4e9cd64ed..e0124a9ba14a 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c @@ -1,7 +1,7 @@ /** - * \file drm_fops.h + * \file drm_fops.c * File operations for DRM - * + * * \author Rickard E. (Rik) Faith * \author Daryll Strauss * \author Gareth Hughes @@ -37,49 +37,48 @@ #include "drmP.h" #include -static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev); +static int drm_open_helper(struct inode *inode, struct file *filp, + drm_device_t * dev); -static int drm_setup( drm_device_t *dev ) +static int drm_setup(drm_device_t * dev) { int i; int ret; - if (dev->driver->presetup) - { - ret=dev->driver->presetup(dev); - if (ret!=0) + if (dev->driver->presetup) { + ret = dev->driver->presetup(dev); + if (ret != 0) return ret; } - atomic_set( &dev->ioctl_count, 0 ); - atomic_set( &dev->vma_count, 0 ); + atomic_set(&dev->ioctl_count, 0); + atomic_set(&dev->vma_count, 0); dev->buf_use = 0; - atomic_set( &dev->buf_alloc, 0 ); + atomic_set(&dev->buf_alloc, 0); - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - { - i = drm_dma_setup( dev ); - if ( i < 0 ) + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { + i = drm_dma_setup(dev); + if (i < 0) return i; } - for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ ) - atomic_set( &dev->counts[i], 0 ); + for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) + atomic_set(&dev->counts[i], 0); - for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { + for (i = 0; i < DRM_HASH_SIZE; i++) { dev->magiclist[i].head = NULL; dev->magiclist[i].tail = NULL; } - dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), - DRM_MEM_CTXLIST); - if(dev->ctxlist == NULL) return -ENOMEM; + dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); + if (dev->ctxlist == NULL) + return -ENOMEM; memset(dev->ctxlist, 0, sizeof(*dev->ctxlist)); INIT_LIST_HEAD(&dev->ctxlist->head); dev->vmalist = NULL; dev->sigdata.lock = dev->lock.hw_lock = NULL; - init_waitqueue_head( &dev->lock.lock_queue ); + init_waitqueue_head(&dev->lock.lock_queue); dev->queue_count = 0; dev->queue_reserved = 0; dev->queue_slots = 0; @@ -91,7 +90,7 @@ static int drm_setup( drm_device_t *dev ) dev->last_context = 0; dev->last_switch = 0; dev->last_checked = 0; - init_waitqueue_head( &dev->context_wait ); + init_waitqueue_head(&dev->context_wait); dev->if_version = 0; dev->ctx_start = 0; @@ -101,14 +100,14 @@ static int drm_setup( drm_device_t *dev ) dev->buf_wp = dev->buf; dev->buf_end = dev->buf + DRM_BSZ; dev->buf_async = NULL; - init_waitqueue_head( &dev->buf_readers ); - init_waitqueue_head( &dev->buf_writers ); + init_waitqueue_head(&dev->buf_readers); + init_waitqueue_head(&dev->buf_writers); - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* * The kernel's context could be created here, but is now created - * in drm_dma_enqueue. This is more resource-efficient for + * in drm_dma_enqueue. This is more resource-efficient for * hardware that does not do DMA, but may mean that * drm_select_queue fails between the time the interrupt is * initialized and the time the queues are initialized. @@ -121,7 +120,7 @@ static int drm_setup( drm_device_t *dev ) /** * Open file. - * + * * \param inode device inode * \param filp file pointer. * \return zero on success or a negative number on failure. @@ -130,7 +129,7 @@ static int drm_setup( drm_device_t *dev ) * increments the device open count. If the open count was previous at zero, * i.e., it's the first that the device is open, then calls setup(). */ -int drm_open( struct inode *inode, struct file *filp ) +int drm_open(struct inode *inode, struct file *filp) { drm_device_t *dev = NULL; int minor = iminor(inode); @@ -138,26 +137,27 @@ int drm_open( struct inode *inode, struct file *filp ) if (!((minor >= 0) && (minor < drm_cards_limit))) return -ENODEV; - + if (!drm_heads[minor]) return -ENODEV; if (!(dev = drm_heads[minor]->dev)) return -ENODEV; - - retcode = drm_open_helper( inode, filp, dev ); - if ( !retcode ) { - atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - spin_lock( &dev->count_lock ); - if ( !dev->open_count++ ) { - spin_unlock( &dev->count_lock ); - return drm_setup( dev ); + + retcode = drm_open_helper(inode, filp, dev); + if (!retcode) { + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); + spin_lock(&dev->count_lock); + if (!dev->open_count++) { + spin_unlock(&dev->count_lock); + return drm_setup(dev); } - spin_unlock( &dev->count_lock ); + spin_unlock(&dev->count_lock); } return retcode; } + EXPORT_SYMBOL(drm_open); /** @@ -172,7 +172,7 @@ EXPORT_SYMBOL(drm_open); * data from its list and free it. Decreases the open count and if it reaches * zero calls takedown(). */ -int drm_release( struct inode *inode, struct file *filp ) +int drm_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; drm_device_t *dev; @@ -181,7 +181,7 @@ int drm_release( struct inode *inode, struct file *filp ) lock_kernel(); dev = priv->head->dev; - DRM_DEBUG( "open_count = %d\n", dev->open_count ); + DRM_DEBUG("open_count = %d\n", dev->open_count); if (dev->driver->prerelease) dev->driver->prerelease(dev, filp); @@ -190,194 +190,199 @@ int drm_release( struct inode *inode, struct file *filp ) * Begin inline drm_release */ - DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", - current->pid, (long)old_encode_dev(priv->head->device), dev->open_count ); + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)old_encode_dev(priv->head->device), + dev->open_count); + + if (priv->lock_count && dev->lock.hw_lock && + _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && + dev->lock.filp == filp) { + DRM_DEBUG("File %p released, freeing lock for context %d\n", + filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - if ( priv->lock_count && dev->lock.hw_lock && - _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.filp == filp ) { - DRM_DEBUG( "File %p released, freeing lock for context %d\n", - filp, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); - if (dev->driver->release) dev->driver->release(dev, filp); - drm_lock_free( dev, &dev->lock.hw_lock->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } - else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) { + /* FIXME: may require heavy-handed reset of + hardware at this point, possibly + processed via a callback to the X + server. */ + } else if (dev->driver->release && priv->lock_count + && dev->lock.hw_lock) { /* The lock is required to reclaim buffers */ - DECLARE_WAITQUEUE( entry, current ); + DECLARE_WAITQUEUE(entry, current); - add_wait_queue( &dev->lock.lock_queue, &entry ); + add_wait_queue(&dev->lock.lock_queue, &entry); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); - if ( !dev->lock.hw_lock ) { + if (!dev->lock.hw_lock) { /* Device has been unregistered */ retcode = -EINTR; break; } - if ( drm_lock_take( &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT ) ) { - dev->lock.filp = filp; + if (drm_lock_take(&dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + dev->lock.filp = filp; dev->lock.lock_time = jiffies; - atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); + atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); break; /* Got lock */ } - /* Contention */ + /* Contention */ schedule(); - if ( signal_pending( current ) ) { + if (signal_pending(current)) { retcode = -ERESTARTSYS; break; } } __set_current_state(TASK_RUNNING); - remove_wait_queue( &dev->lock.lock_queue, &entry ); - if( !retcode ) { + remove_wait_queue(&dev->lock.lock_queue, &entry); + if (!retcode) { if (dev->driver->release) dev->driver->release(dev, filp); - drm_lock_free( dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT ); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); } } - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release) - { + + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) + && !dev->driver->release) { dev->driver->reclaim_buffers(dev, filp); } - drm_fasync( -1, filp, 0 ); + drm_fasync(-1, filp, 0); - down( &dev->ctxlist_sem ); - if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { + down(&dev->ctxlist_sem); + if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { drm_ctx_list_t *pos, *n; - list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) { - if ( pos->tag == priv && - pos->handle != DRM_KERNEL_CONTEXT ) { + list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) { + if (pos->tag == priv && + pos->handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, pos->handle); + dev->driver->context_dtor(dev, + pos->handle); - drm_ctxbitmap_free( dev, pos->handle ); + drm_ctxbitmap_free(dev, pos->handle); - list_del( &pos->head ); - drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST ); + list_del(&pos->head); + drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); --dev->ctx_count; } } } - up( &dev->ctxlist_sem ); + up(&dev->ctxlist_sem); - down( &dev->struct_sem ); - if ( priv->remove_auth_on_close == 1 ) { + down(&dev->struct_sem); + if (priv->remove_auth_on_close == 1) { drm_file_t *temp = dev->file_first; - while ( temp ) { + while (temp) { temp->authenticated = 0; temp = temp->next; } } - if ( priv->prev ) { + if (priv->prev) { priv->prev->next = priv->next; } else { - dev->file_first = priv->next; + dev->file_first = priv->next; } - if ( priv->next ) { + if (priv->next) { priv->next->prev = priv->prev; } else { - dev->file_last = priv->prev; + dev->file_last = priv->prev; } - up( &dev->struct_sem ); - + up(&dev->struct_sem); + if (dev->driver->free_filp_priv) dev->driver->free_filp_priv(dev, priv); - drm_free( priv, sizeof(*priv), DRM_MEM_FILES ); + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); /* ======================================================== * End inline drm_release */ - atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - spin_lock( &dev->count_lock ); - if ( !--dev->open_count ) { - if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) { - DRM_ERROR( "Device busy: %d %d\n", - atomic_read( &dev->ioctl_count ), - dev->blocked ); - spin_unlock( &dev->count_lock ); + atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); + spin_lock(&dev->count_lock); + if (!--dev->open_count) { + if (atomic_read(&dev->ioctl_count) || dev->blocked) { + DRM_ERROR("Device busy: %d %d\n", + atomic_read(&dev->ioctl_count), dev->blocked); + spin_unlock(&dev->count_lock); unlock_kernel(); return -EBUSY; } - spin_unlock( &dev->count_lock ); + spin_unlock(&dev->count_lock); unlock_kernel(); - return drm_takedown( dev ); + return drm_takedown(dev); } - spin_unlock( &dev->count_lock ); + spin_unlock(&dev->count_lock); unlock_kernel(); return retcode; } + EXPORT_SYMBOL(drm_release); /** - * Called whenever a process opens /dev/drm. + * Called whenever a process opens /dev/drm. * * \param inode device inode. * \param filp file pointer. * \param dev device. * \return zero on success or a negative number on failure. - * + * * Creates and initializes a drm_file structure for the file private data in \p * filp and add it into the double linked list in \p dev. */ -static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev) +static int drm_open_helper(struct inode *inode, struct file *filp, + drm_device_t * dev) { - int minor = iminor(inode); - drm_file_t *priv; + int minor = iminor(inode); + drm_file_t *priv; int ret; - if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ - if (!drm_cpu_valid()) return -EINVAL; + if (filp->f_flags & O_EXCL) + return -EBUSY; /* No exclusive opens */ + if (!drm_cpu_valid()) + return -EINVAL; DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); - priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); - if(!priv) return -ENOMEM; + priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); + if (!priv) + return -ENOMEM; memset(priv, 0, sizeof(*priv)); - filp->private_data = priv; - priv->uid = current->euid; - priv->pid = current->pid; - priv->minor = minor; - priv->head = drm_heads[minor]; - priv->ioctl_count = 0; + filp->private_data = priv; + priv->uid = current->euid; + priv->pid = current->pid; + priv->minor = minor; + priv->head = drm_heads[minor]; + priv->ioctl_count = 0; priv->authenticated = capable(CAP_SYS_ADMIN); - priv->lock_count = 0; + priv->lock_count = 0; if (dev->driver->open_helper) { - ret=dev->driver->open_helper(dev, priv); + ret = dev->driver->open_helper(dev, priv); if (ret < 0) goto out_free; } down(&dev->struct_sem); if (!dev->file_last) { - priv->next = NULL; - priv->prev = NULL; + priv->next = NULL; + priv->prev = NULL; dev->file_first = priv; - dev->file_last = priv; + dev->file_last = priv; } else { - priv->next = NULL; - priv->prev = dev->file_last; + priv->next = NULL; + priv->prev = dev->file_last; dev->file_last->next = priv; - dev->file_last = priv; + dev->file_last = priv; } up(&dev->struct_sem); @@ -394,42 +399,48 @@ static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t } if (!dev->hose) { struct pci_bus *b = pci_bus_b(pci_root_buses.next); - if (b) dev->hose = b->sysdata; + if (b) + dev->hose = b->sysdata; } } #endif return 0; -out_free: + out_free: drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - filp->private_data=NULL; + filp->private_data = NULL; return ret; } /** No-op. */ int drm_flush(struct file *filp) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - current->pid, (long)old_encode_dev(priv->head->device), dev->open_count); + current->pid, (long)old_encode_dev(priv->head->device), + dev->open_count); return 0; } + EXPORT_SYMBOL(drm_flush); /** No-op. */ int drm_fasync(int fd, struct file *filp, int on) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - int retcode; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + int retcode; - DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(priv->head->device)); + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, + (long)old_encode_dev(priv->head->device)); retcode = fasync_helper(fd, filp, on, &dev->buf_async); - if (retcode < 0) return retcode; + if (retcode < 0) + return retcode; return 0; } + EXPORT_SYMBOL(drm_fasync); /** No-op. */ @@ -437,5 +448,5 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) { return 0; } -EXPORT_SYMBOL(drm_poll); +EXPORT_SYMBOL(drm_poll); diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c index 62883b749e97..754b934715c4 100644 --- a/drivers/char/drm/drm_init.c +++ b/drivers/char/drm/drm_init.c @@ -1,5 +1,5 @@ /** - * \file drm_init.h + * \file drm_init.c * Setup/Cleanup for DRM * * \author Rickard E. (Rik) Faith @@ -43,10 +43,11 @@ int drm_cpu_valid(void) { #if defined(__i386__) - if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */ + if (boot_cpu_data.x86 == 3) + return 0; /* No cmpxchg on a 386 */ #endif #if defined(__sparc__) && !defined(__sparc_v9__) - return 0; /* No cmpxchg before v9 sparc. */ + return 0; /* No cmpxchg before v9 sparc. */ #endif return 1; } diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c index 8087a9636399..dd91ff6b474c 100644 --- a/drivers/char/drm/drm_ioc32.c +++ b/drivers/char/drm/drm_ioc32.c @@ -68,15 +68,15 @@ #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) typedef struct drm_version_32 { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel;/**< Patch level */ - u32 name_len; /**< Length of name buffer */ - u32 name; /**< Name of driver */ - u32 date_len; /**< Length of date buffer */ - u32 date; /**< User-space buffer to hold date */ - u32 desc_len; /**< Length of desc buffer */ - u32 desc; /**< User-space buffer to hold desc */ + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ + u32 name_len; /**< Length of name buffer */ + u32 name; /**< Name of driver */ + u32 date_len; /**< Length of date buffer */ + u32 date; /**< User-space buffer to hold date */ + u32 desc_len; /**< Length of desc buffer */ + u32 desc; /**< User-space buffer to hold desc */ } drm_version32_t; static int compat_drm_version(struct file *file, unsigned int cmd, @@ -86,7 +86,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, drm_version_t __user *version; int err; - if (copy_from_user(&v32, (void __user *) arg, sizeof(v32))) + if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) return -EFAULT; version = compat_alloc_user_space(sizeof(*version)); @@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_VERSION, (unsigned long) version); + DRM_IOCTL_VERSION, (unsigned long)version); if (err) return err; @@ -116,7 +116,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, || __get_user(v32.desc_len, &version->desc_len)) return -EFAULT; - if (copy_to_user((void __user *) arg, &v32, sizeof(v32))) + if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) return -EFAULT; return 0; } @@ -133,25 +133,25 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, drm_unique_t __user *u; int err; - if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32))) + if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; u = compat_alloc_user_space(sizeof(*u)); if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) return -EFAULT; if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long) uq32.unique, + || __put_user((void __user *)(unsigned long)uq32.unique, &u->unique)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_GET_UNIQUE, (unsigned long) u); + DRM_IOCTL_GET_UNIQUE, (unsigned long)u); if (err) return err; if (__get_user(uq32.unique_len, &u->unique_len)) return -EFAULT; - if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32))) + if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) return -EFAULT; return 0; } @@ -162,28 +162,28 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, drm_unique32_t uq32; drm_unique_t __user *u; - if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32))) + if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; u = compat_alloc_user_space(sizeof(*u)); if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) return -EFAULT; if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long) uq32.unique, + || __put_user((void __user *)(unsigned long)uq32.unique, &u->unique)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_SET_UNIQUE, (unsigned long) u); + DRM_IOCTL_SET_UNIQUE, (unsigned long)u); } typedef struct drm_map32 { - u32 offset; /**< Requested physical address (0 for SAREA)*/ - u32 size; /**< Requested physical size (bytes) */ - drm_map_type_t type; /**< Type of memory to map */ + u32 offset; /**< Requested physical address (0 for SAREA)*/ + u32 size; /**< Requested physical size (bytes) */ + drm_map_type_t type; /**< Type of memory to map */ drm_map_flags_t flags; /**< Flags */ - u32 handle; /**< User-space: "Handle" to pass to mmap() */ - int mtrr; /**< MTRR slot used */ + u32 handle; /**< User-space: "Handle" to pass to mmap() */ + int mtrr; /**< MTRR slot used */ } drm_map32_t; static int compat_drm_getmap(struct file *file, unsigned int cmd, @@ -205,7 +205,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_GET_MAP, (unsigned long) map); + DRM_IOCTL_GET_MAP, (unsigned long)map); if (err) return err; @@ -217,7 +217,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, || __get_user(m32.mtrr, &map->mtrr)) return -EFAULT; - m32.handle = (unsigned long) handle; + m32.handle = (unsigned long)handle; if (copy_to_user(argp, &m32, sizeof(m32))) return -EFAULT; return 0; @@ -246,7 +246,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_ADD_MAP, (unsigned long) map); + DRM_IOCTL_ADD_MAP, (unsigned long)map); if (err) return err; @@ -255,8 +255,8 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, || __get_user(handle, &map->handle)) return -EFAULT; - m32.handle = (unsigned long) handle; - if (m32.handle != (unsigned long) handle && printk_ratelimit()) + m32.handle = (unsigned long)handle; + if (m32.handle != (unsigned long)handle && printk_ratelimit()) printk(KERN_ERR "compat_drm_addmap truncated handle" " %p for type %d offset %x\n", handle, m32.type, m32.offset); @@ -280,20 +280,20 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, map = compat_alloc_user_space(sizeof(*map)); if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) return -EFAULT; - if (__put_user((void *)(unsigned long) handle, &map->handle)) + if (__put_user((void *)(unsigned long)handle, &map->handle)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RM_MAP, (unsigned long) map); + DRM_IOCTL_RM_MAP, (unsigned long)map); } typedef struct drm_client32 { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - u32 pid; /**< Process ID */ - u32 uid; /**< User ID */ - u32 magic; /**< Magic */ - u32 iocs; /**< Ioctl count */ + int idx; /**< Which client desired? */ + int auth; /**< Is client authenticated? */ + u32 pid; /**< Process ID */ + u32 uid; /**< User ID */ + u32 magic; /**< Magic */ + u32 iocs; /**< Ioctl count */ } drm_client32_t; static int compat_drm_getclient(struct file *file, unsigned int cmd, @@ -314,7 +314,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_GET_CLIENT, (unsigned long) client); + DRM_IOCTL_GET_CLIENT, (unsigned long)client); if (err) return err; @@ -351,7 +351,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_GET_STATS, (unsigned long) stats); + DRM_IOCTL_GET_STATS, (unsigned long)stats); if (err) return err; @@ -368,12 +368,12 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, } typedef struct drm_buf_desc32 { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - int flags; - u32 agp_start; /**< Start address in the AGP aperture */ + int count; /**< Number of buffers of this size */ + int size; /**< Size in bytes */ + int low_mark; /**< Low water mark */ + int high_mark; /**< High water mark */ + int flags; + u32 agp_start; /**< Start address in the AGP aperture */ } drm_buf_desc32_t; static int compat_drm_addbufs(struct file *file, unsigned int cmd, @@ -395,7 +395,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_ADD_BUFS, (unsigned long) buf); + DRM_IOCTL_ADD_BUFS, (unsigned long)buf); if (err) return err; @@ -427,12 +427,12 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_MARK_BUFS, (unsigned long) buf); + DRM_IOCTL_MARK_BUFS, (unsigned long)buf); } typedef struct drm_buf_info32 { - int count; /**< Entries in list */ - u32 list; + int count; /**< Entries in list */ + u32 list; } drm_buf_info32_t; static int compat_drm_infobufs(struct file *file, unsigned int cmd, @@ -451,7 +451,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, return -EFAULT; count = req32.count; - to = (drm_buf_desc32_t __user *)(unsigned long) req32.list; + to = (drm_buf_desc32_t __user *) (unsigned long)req32.list; if (count < 0) count = 0; if (count > 0 @@ -469,7 +469,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_INFO_BUFS, (unsigned long) request); + DRM_IOCTL_INFO_BUFS, (unsigned long)request); if (err) return err; @@ -488,16 +488,16 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, } typedef struct drm_buf_pub32 { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - u32 address; /**< Address of buffer */ + int idx; /**< Index into the master buffer list */ + int total; /**< Buffer size */ + int used; /**< Amount of buffer in use (for DMA) */ + u32 address; /**< Address of buffer */ } drm_buf_pub32_t; typedef struct drm_buf_map32 { - int count; /**< Length of the buffer list */ - u32 virtual; /**< Mmap'd area in user-virtual */ - u32 list; /**< Buffer information */ + int count; /**< Length of the buffer list */ + u32 virtual; /**< Mmap'd area in user-virtual */ + u32 list; /**< Buffer information */ } drm_buf_map32_t; static int compat_drm_mapbufs(struct file *file, unsigned int cmd, @@ -531,7 +531,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_MAP_BUFS, (unsigned long) request); + DRM_IOCTL_MAP_BUFS, (unsigned long)request); if (err) return err; @@ -542,21 +542,21 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd, if (__copy_in_user(&list32[i], &list[i], offsetof(drm_buf_pub_t, address)) || __get_user(addr, &list[i].address) - || __put_user((unsigned long) addr, + || __put_user((unsigned long)addr, &list32[i].address)) return -EFAULT; if (__put_user(actual, &argp->count) || __get_user(addr, &request->virtual) - || __put_user((unsigned long) addr, &argp->virtual)) + || __put_user((unsigned long)addr, &argp->virtual)) return -EFAULT; return 0; } typedef struct drm_buf_free32 { - int count; - u32 list; + int count; + u32 list; } drm_buf_free32_t; static int compat_drm_freebufs(struct file *file, unsigned int cmd, @@ -573,17 +573,17 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd, if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) return -EFAULT; if (__put_user(req32.count, &request->count) - || __put_user((int __user *)(unsigned long) req32.list, + || __put_user((int __user *)(unsigned long)req32.list, &request->list)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_FREE_BUFS, (unsigned long) request); + DRM_IOCTL_FREE_BUFS, (unsigned long)request); } typedef struct drm_ctx_priv_map32 { - unsigned int ctx_id; /**< Context requesting private mapping */ - u32 handle; /**< Handle of map */ + unsigned int ctx_id; /**< Context requesting private mapping */ + u32 handle; /**< Handle of map */ } drm_ctx_priv_map32_t; static int compat_drm_setsareactx(struct file *file, unsigned int cmd, @@ -600,12 +600,12 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd, if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) return -EFAULT; if (__put_user(req32.ctx_id, &request->ctx_id) - || __put_user((void *)(unsigned long) req32.handle, + || __put_user((void *)(unsigned long)req32.handle, &request->handle)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request); + DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); } static int compat_drm_getsareactx(struct file *file, unsigned int cmd, @@ -628,20 +628,20 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request); + DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); if (err) return err; if (__get_user(handle, &request->handle) - || __put_user((unsigned long) handle, &argp->handle)) + || __put_user((unsigned long)handle, &argp->handle)) return -EFAULT; return 0; } typedef struct drm_ctx_res32 { - int count; - u32 contexts; + int count; + u32 contexts; } drm_ctx_res32_t; static int compat_drm_resctx(struct file *file, unsigned int cmd, @@ -659,12 +659,12 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, if (!access_ok(VERIFY_WRITE, res, sizeof(*res))) return -EFAULT; if (__put_user(res32.count, &res->count) - || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts, + || __put_user((drm_ctx_t __user *) (unsigned long)res32.contexts, &res->contexts)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RES_CTX, (unsigned long) res); + DRM_IOCTL_RES_CTX, (unsigned long)res); if (err) return err; @@ -676,23 +676,23 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, } typedef struct drm_dma32 { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - u32 send_indices; /**< List of handles to buffers */ - u32 send_sizes; /**< Lengths of data to send */ + int context; /**< Context handle */ + int send_count; /**< Number of buffers to send */ + u32 send_indices; /**< List of handles to buffers */ + u32 send_sizes; /**< Lengths of data to send */ drm_dma_flags_t flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - u32 request_indices; /**< Buffer information */ - u32 request_sizes; - int granted_count; /**< Number of buffers granted */ + int request_count; /**< Number of buffers requested */ + int request_size; /**< Desired size for buffers */ + u32 request_indices; /**< Buffer information */ + u32 request_sizes; + int granted_count; /**< Number of buffers granted */ } drm_dma32_t; static int compat_drm_dma(struct file *file, unsigned int cmd, unsigned long arg) { drm_dma32_t d32; - drm_dma32_t __user *argp = (void __user *) arg; + drm_dma32_t __user *argp = (void __user *)arg; drm_dma_t __user *d; int err; @@ -705,20 +705,20 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, if (__put_user(d32.context, &d->context) || __put_user(d32.send_count, &d->send_count) - || __put_user((int __user *)(unsigned long) d32.send_indices, + || __put_user((int __user *)(unsigned long)d32.send_indices, &d->send_indices) - || __put_user((int __user *)(unsigned long) d32.send_sizes, + || __put_user((int __user *)(unsigned long)d32.send_sizes, &d->send_sizes) || __put_user(d32.flags, &d->flags) || __put_user(d32.request_count, &d->request_count) - || __put_user((int __user *)(unsigned long) d32.request_indices, + || __put_user((int __user *)(unsigned long)d32.request_indices, &d->request_indices) - || __put_user((int __user *)(unsigned long) d32.request_sizes, + || __put_user((int __user *)(unsigned long)d32.request_sizes, &d->request_sizes)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_DMA, (unsigned long) d); + DRM_IOCTL_DMA, (unsigned long)d); if (err) return err; @@ -751,19 +751,19 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_ENABLE, (unsigned long) mode); + DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); } typedef struct drm_agp_info32 { - int agp_version_major; - int agp_version_minor; - u32 mode; - u32 aperture_base; /* physical address */ - u32 aperture_size; /* bytes */ - u32 memory_allowed; /* bytes */ - u32 memory_used; + int agp_version_major; + int agp_version_minor; + u32 mode; + u32 aperture_base; /* physical address */ + u32 aperture_size; /* bytes */ + u32 memory_allowed; /* bytes */ + u32 memory_used; - /* PCI information */ + /* PCI information */ unsigned short id_vendor; unsigned short id_device; } drm_agp_info32_t; @@ -781,7 +781,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_INFO, (unsigned long) info); + DRM_IOCTL_AGP_INFO, (unsigned long)info); if (err) return err; @@ -806,7 +806,7 @@ typedef struct drm_agp_buffer32 { u32 size; /**< In bytes -- will round to page boundary */ u32 handle; /**< Used for binding / unbinding */ u32 type; /**< Type of memory to allocate */ - u32 physical; /**< Physical used by i810 */ + u32 physical; /**< Physical used by i810 */ } drm_agp_buffer32_t; static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, @@ -827,7 +827,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_ALLOC, (unsigned long) request); + DRM_IOCTL_AGP_ALLOC, (unsigned long)request); if (err) return err; @@ -835,7 +835,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, || __get_user(req32.physical, &request->physical) || copy_to_user(argp, &req32, sizeof(req32))) { drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long) request); + DRM_IOCTL_AGP_FREE, (unsigned long)request); return -EFAULT; } @@ -856,7 +856,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long) request); + DRM_IOCTL_AGP_FREE, (unsigned long)request); } typedef struct drm_agp_binding32 { @@ -881,7 +881,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_BIND, (unsigned long) request); + DRM_IOCTL_AGP_BIND, (unsigned long)request); } static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, @@ -898,9 +898,9 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_AGP_UNBIND, (unsigned long) request); + DRM_IOCTL_AGP_UNBIND, (unsigned long)request); } -#endif /* __OS_HAS_AGP */ +#endif /* __OS_HAS_AGP */ typedef struct drm_scatter_gather32 { u32 size; /**< In bytes -- will round to page boundary */ @@ -923,7 +923,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_SG_ALLOC, (unsigned long) request); + DRM_IOCTL_SG_ALLOC, (unsigned long)request); if (err) return err; @@ -950,7 +950,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_SG_FREE, (unsigned long) request); + DRM_IOCTL_SG_FREE, (unsigned long)request); } struct drm_wait_vblank_request32 { @@ -990,7 +990,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_WAIT_VBLANK, (unsigned long) request); + DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); if (err) return err; @@ -1059,11 +1059,12 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) lock_kernel(); /* XXX for now */ if (fn != NULL) - ret = (*fn)(filp, cmd, arg); + ret = (*fn) (filp, cmd, arg); else ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; } + EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c index d2ed3ba5aca9..9b0feba6b063 100644 --- a/drivers/char/drm/drm_ioctl.c +++ b/drivers/char/drm/drm_ioctl.c @@ -1,5 +1,5 @@ /** - * \file drm_ioctl.h + * \file drm_ioctl.c * IOCTL processing for DRM * * \author Rickard E. (Rik) Faith @@ -40,7 +40,7 @@ /** * Get the bus id. - * + * * \param inode device inode. * \param filp file pointer. * \param cmd command. @@ -50,12 +50,12 @@ * Copies the bus id from drm_device::unique into user space. */ int drm_getunique(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_unique_t __user *argp = (void __user *)arg; - drm_unique_t u; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_unique_t __user *argp = (void __user *)arg; + drm_unique_t u; if (copy_from_user(&u, argp, sizeof(u))) return -EFAULT; @@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, struct file *filp, /** * Set the bus id. - * + * * \param inode device inode. * \param filp file pointer. * \param cmd command. @@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, struct file *filp, * version 1.1 or greater. */ int drm_setunique(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_unique_t u; - int domain, bus, slot, func, ret; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_unique_t u; + int domain, bus, slot, func, ret; - if (dev->unique_len || dev->unique) return -EBUSY; + if (dev->unique_len || dev->unique) + return -EBUSY; - if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u))) + if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u))) return -EFAULT; - if (!u.unique_len || u.unique_len > 1024) return -EINVAL; + if (!u.unique_len || u.unique_len > 1024) + return -EINVAL; dev->unique_len = u.unique_len; - dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); - if(!dev->unique) return -ENOMEM; + dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); + if (!dev->unique) + return -ENOMEM; if (copy_from_user(dev->unique, u.unique, dev->unique_len)) return -EFAULT; dev->unique[dev->unique_len] = '\0'; - dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2, - DRM_MEM_DRIVER); + dev->devname = + drm_alloc(strlen(dev->driver->pci_driver.name) + + strlen(dev->unique) + 2, DRM_MEM_DRIVER); if (!dev->devname) return -ENOMEM; - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); + sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, + dev->unique); /* Return error if the busid submitted doesn't match the device's actual * busid. @@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, struct file *filp, return DRM_ERR(EINVAL); domain = bus >> 8; bus &= 0xff; - + if ((domain != dev->pci_domain) || (bus != dev->pci_bus) || - (slot != dev->pci_slot) || - (func != dev->pci_func)) + (slot != dev->pci_slot) || (func != dev->pci_func)) return -EINVAL; return 0; } -static int -drm_set_busid(drm_device_t *dev) +static int drm_set_busid(drm_device_t * dev) { if (dev->unique != NULL) return EBUSY; @@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev) return ENOMEM; snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", - dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); + dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); - dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, - DRM_MEM_DRIVER); + dev->devname = + drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + + 2, DRM_MEM_DRIVER); if (dev->devname == NULL) return ENOMEM; - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); + sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, + dev->unique); return 0; } - /** * Get a mapping information. * @@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev) * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_map structure. - * + * * \return zero on success or a negative number on failure. * * Searches for the mapping with the specified offset and copies its information * into userspace */ -int drm_getmap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_getmap(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_map_t __user *argp = (void __user *)arg; - drm_map_t map; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_map_t __user *argp = (void __user *)arg; + drm_map_t map; drm_map_list_t *r_list = NULL; struct list_head *list; - int idx; - int i; + int idx; + int i; if (copy_from_user(&map, argp, sizeof(map))) return -EFAULT; @@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, struct file *filp, i = 0; list_for_each(list, &dev->maplist->head) { - if(i == idx) { + if (i == idx) { r_list = list_entry(list, drm_map_list_t, head); break; } i++; } - if(!r_list || !r_list->map) { + if (!r_list || !r_list->map) { up(&dev->struct_sem); return -EINVAL; } map.offset = r_list->map->offset; - map.size = r_list->map->size; - map.type = r_list->map->type; - map.flags = r_list->map->flags; - map.handle = (void *)(unsigned long) r_list->user_token; - map.mtrr = r_list->map->mtrr; + map.size = r_list->map->size; + map.type = r_list->map->type; + map.flags = r_list->map->flags; + map.handle = (void *)(unsigned long)r_list->user_token; + map.mtrr = r_list->map->mtrr; up(&dev->struct_sem); - if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT; + if (copy_to_user(argp, &map, sizeof(map))) + return -EFAULT; return 0; } @@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, struct file *filp, * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_client structure. - * + * * \return zero on success or a negative number on failure. * * Searches for the client with the specified index and copies its information * into userspace */ -int drm_getclient( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_getclient(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_client_t __user *argp = (void __user *)arg; drm_client_t client; - drm_file_t *pt; - int idx; - int i; + drm_file_t *pt; + int idx; + int i; if (copy_from_user(&client, argp, sizeof(client))) return -EFAULT; idx = client.idx; down(&dev->struct_sem); - for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) - ; + for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ; if (!pt) { up(&dev->struct_sem); return -EINVAL; } - client.auth = pt->authenticated; - client.pid = pt->pid; - client.uid = pt->uid; + client.auth = pt->authenticated; + client.pid = pt->pid; + client.uid = pt->uid; client.magic = pt->magic; - client.iocs = pt->ioctl_count; + client.iocs = pt->ioctl_count; up(&dev->struct_sem); - if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client))) + if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client))) return -EFAULT; return 0; } -/** - * Get statistics information. - * +/** + * Get statistics information. + * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_stats structure. - * + * * \return zero on success or a negative number on failure. */ -int drm_getstats( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_getstats(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_stats_t stats; - int i; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_stats_t stats; + int i; memset(&stats, 0, sizeof(stats)); - + down(&dev->struct_sem); for (i = 0; i < dev->counters; i++) { if (dev->types[i] == _DRM_STAT_LOCK) stats.data[i].value - = (dev->lock.hw_lock - ? dev->lock.hw_lock->lock : 0); - else + = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); + else stats.data[i].value = atomic_read(&dev->counts[i]); - stats.data[i].type = dev->types[i]; + stats.data[i].type = dev->types[i]; } - + stats.count = dev->counters; up(&dev->struct_sem); - if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats))) + if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats))) return -EFAULT; return 0; } @@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS) if (sv.drm_dd_major != -1) { if (sv.drm_dd_major != version.version_major || - sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor) + sv.drm_dd_minor < 0 + || sv.drm_dd_minor > version.version_minor) return EINVAL; if (dev->driver->set_version) @@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS) /** No-op ioctl. */ int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { DRM_DEBUG("\n"); return 0; diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index cdd4aecd25e2..b0d4b236e837 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c @@ -1,5 +1,5 @@ /** - * \file drm_irq.h + * \file drm_irq.c * IRQ support * * \author Rickard E. (Rik) Faith @@ -39,19 +39,19 @@ /** * Get interrupt from bus id. - * + * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_irq_busid structure. * \return zero on success or a negative number on failure. - * + * * Finds the PCI device with the specified bus id and gets its IRQ number. * This IOCTL is deprecated, and will now return EINVAL for any busid not equal * to that of the device that this DRM instance attached to. */ int drm_irq_by_busid(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -66,14 +66,12 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, if ((p.busnum >> 8) != dev->pci_domain || (p.busnum & 0xff) != dev->pci_bus || - p.devnum != dev->pci_slot || - p.funcnum != dev->pci_func) + p.devnum != dev->pci_slot || p.funcnum != dev->pci_func) return -EINVAL; p.irq = dev->irq; - DRM_DEBUG("%d:%d:%d => IRQ %d\n", - p.busnum, p.devnum, p.funcnum, p.irq); + DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq); if (copy_to_user(argp, &p, sizeof(p))) return -EFAULT; return 0; @@ -89,61 +87,61 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions * before and after the installation. */ -static int drm_irq_install( drm_device_t *dev ) +static int drm_irq_install(drm_device_t * dev) { int ret; - unsigned long sh_flags=0; + unsigned long sh_flags = 0; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; - if ( dev->irq == 0 ) + if (dev->irq == 0) return -EINVAL; - down( &dev->struct_sem ); + down(&dev->struct_sem); /* Driver must have been initialized */ - if ( !dev->dev_private ) { - up( &dev->struct_sem ); + if (!dev->dev_private) { + up(&dev->struct_sem); return -EINVAL; } - if ( dev->irq_enabled ) { - up( &dev->struct_sem ); + if (dev->irq_enabled) { + up(&dev->struct_sem); return -EBUSY; } dev->irq_enabled = 1; - up( &dev->struct_sem ); + up(&dev->struct_sem); - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq ); + DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq); if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { init_waitqueue_head(&dev->vbl_queue); - - spin_lock_init( &dev->vbl_lock ); - - INIT_LIST_HEAD( &dev->vbl_sigs.head ); - + + spin_lock_init(&dev->vbl_lock); + + INIT_LIST_HEAD(&dev->vbl_sigs.head); + dev->vbl_pending = 0; } - /* Before installing handler */ + /* Before installing handler */ dev->driver->irq_preinstall(dev); - /* Install handler */ + /* Install handler */ if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) sh_flags = SA_SHIRQ; - - ret = request_irq( dev->irq, dev->driver->irq_handler, - sh_flags, dev->devname, dev ); - if ( ret < 0 ) { - down( &dev->struct_sem ); + + ret = request_irq(dev->irq, dev->driver->irq_handler, + sh_flags, dev->devname, dev); + if (ret < 0) { + down(&dev->struct_sem); dev->irq_enabled = 0; - up( &dev->struct_sem ); + up(&dev->struct_sem); return ret; } - /* After installing handler */ + /* After installing handler */ dev->driver->irq_postinstall(dev); return 0; @@ -156,29 +154,30 @@ static int drm_irq_install( drm_device_t *dev ) * * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq. */ -int drm_irq_uninstall( drm_device_t *dev ) +int drm_irq_uninstall(drm_device_t * dev) { int irq_enabled; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; - down( &dev->struct_sem ); + down(&dev->struct_sem); irq_enabled = dev->irq_enabled; dev->irq_enabled = 0; - up( &dev->struct_sem ); + up(&dev->struct_sem); - if ( !irq_enabled ) + if (!irq_enabled) return -EINVAL; - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq ); + DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq); dev->driver->irq_uninstall(dev); - free_irq( dev->irq, dev ); + free_irq(dev->irq, dev); return 0; } + EXPORT_SYMBOL(drm_irq_uninstall); /** @@ -192,30 +191,30 @@ EXPORT_SYMBOL(drm_irq_uninstall); * * Calls irq_install() or irq_uninstall() according to \p arg. */ -int drm_control( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_control(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_control_t ctl; - + /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */ - if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) ) + if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl))) return -EFAULT; - switch ( ctl.func ) { + switch (ctl.func) { case DRM_INST_HANDLER: if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return 0; if (dev->if_version < DRM_IF_VERSION(1, 2) && ctl.irq != dev->irq) return -EINVAL; - return drm_irq_install( dev ); + return drm_irq_install(dev); case DRM_UNINST_HANDLER: if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return 0; - return drm_irq_uninstall( dev ); + return drm_irq_uninstall(dev); default: return -EINVAL; } @@ -230,7 +229,7 @@ int drm_control( struct inode *inode, struct file *filp, * \param data user argument, pointing to a drm_wait_vblank structure. * \return zero on success or a negative number on failure. * - * Verifies the IRQ is installed. + * Verifies the IRQ is installed. * * If a signal is requested checks if this task has already scheduled the same signal * for the same vblank sequence number - nothing to be done in @@ -240,7 +239,7 @@ int drm_control( struct inode *inode, struct file *filp, * * If a signal is not requested, then calls vblank_wait(). */ -int drm_wait_vblank( DRM_IOCTL_ARGS ) +int drm_wait_vblank(DRM_IOCTL_ARGS) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -256,11 +255,11 @@ int drm_wait_vblank( DRM_IOCTL_ARGS ) if (!dev->irq) return -EINVAL; - DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) ); + DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait)); - switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) { + switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) { case _DRM_VBLANK_RELATIVE: - vblwait.request.sequence += atomic_read( &dev->vbl_received ); + vblwait.request.sequence += atomic_read(&dev->vbl_received); vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; case _DRM_VBLANK_ABSOLUTE: break; @@ -269,64 +268,68 @@ int drm_wait_vblank( DRM_IOCTL_ARGS ) } flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; - - if ( flags & _DRM_VBLANK_SIGNAL ) { + + if (flags & _DRM_VBLANK_SIGNAL) { unsigned long irqflags; drm_vbl_sig_t *vbl_sig; - - vblwait.reply.sequence = atomic_read( &dev->vbl_received ); - spin_lock_irqsave( &dev->vbl_lock, irqflags ); + vblwait.reply.sequence = atomic_read(&dev->vbl_received); + + spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Check if this task has already scheduled the same signal * for the same vblank sequence number; nothing to be done in * that case */ - list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) { + list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) { if (vbl_sig->sequence == vblwait.request.sequence && vbl_sig->info.si_signo == vblwait.request.signal - && vbl_sig->task == current) - { - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + && vbl_sig->task == current) { + spin_unlock_irqrestore(&dev->vbl_lock, + irqflags); goto done; } } - if ( dev->vbl_pending >= 100 ) { - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + if (dev->vbl_pending >= 100) { + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); return -EBUSY; } dev->vbl_pending++; - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) { + if (! + (vbl_sig = + drm_alloc(sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER))) { return -ENOMEM; } - memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) ); + memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); vbl_sig->sequence = vblwait.request.sequence; vbl_sig->info.si_signo = vblwait.request.signal; vbl_sig->task = current; - spin_lock_irqsave( &dev->vbl_lock, irqflags ); + spin_lock_irqsave(&dev->vbl_lock, irqflags); - list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head ); + list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head); - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } else { if (dev->driver->vblank_wait) - ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence ); + ret = + dev->driver->vblank_wait(dev, + &vblwait.request.sequence); - do_gettimeofday( &now ); + do_gettimeofday(&now); vblwait.reply.tval_sec = now.tv_sec; vblwait.reply.tval_usec = now.tv_usec; } -done: - DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) ); + done: + DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait)); return ret; } @@ -340,31 +343,31 @@ int drm_wait_vblank( DRM_IOCTL_ARGS ) * * If a signal is not requested, then calls vblank_wait(). */ -void drm_vbl_send_signals( drm_device_t *dev ) +void drm_vbl_send_signals(drm_device_t * dev) { struct list_head *list, *tmp; drm_vbl_sig_t *vbl_sig; - unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + unsigned int vbl_seq = atomic_read(&dev->vbl_received); unsigned long flags; - spin_lock_irqsave( &dev->vbl_lock, flags ); + spin_lock_irqsave(&dev->vbl_lock, flags); - list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) { - vbl_sig = list_entry( list, drm_vbl_sig_t, head ); - if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + list_for_each_safe(list, tmp, &dev->vbl_sigs.head) { + vbl_sig = list_entry(list, drm_vbl_sig_t, head); + if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { vbl_sig->info.si_code = vbl_seq; - send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); + send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info, + vbl_sig->task); - list_del( list ); + list_del(list); - drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER ); + drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER); dev->vbl_pending--; } } - spin_unlock_irqrestore( &dev->vbl_lock, flags ); + spin_unlock_irqrestore(&dev->vbl_lock, flags); } + EXPORT_SYMBOL(drm_vbl_send_signals); - - diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index 4702d863bcc6..b276ae8a6633 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c @@ -1,7 +1,7 @@ /** - * \file drm_lock.h + * \file drm_lock.c * IOCTLs for locking - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -35,12 +35,12 @@ #include "drmP.h" -static int drm_lock_transfer(drm_device_t *dev, +static int drm_lock_transfer(drm_device_t * dev, __volatile__ unsigned int *lock, unsigned int context); static int drm_notifier(void *priv); -/** +/** * Lock ioctl. * * \param inode device inode. @@ -51,91 +51,89 @@ static int drm_notifier(void *priv); * * Add the current task to the lock wait queue, and attempt to take to lock. */ -int drm_lock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_lock(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - DECLARE_WAITQUEUE( entry, current ); - drm_lock_t lock; - int ret = 0; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + DECLARE_WAITQUEUE(entry, current); + drm_lock_t lock; + int ret = 0; ++priv->lock_count; - if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) ) + if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock))) return -EFAULT; - if ( lock.context == DRM_KERNEL_CONTEXT ) { - DRM_ERROR( "Process %d using kernel context %d\n", - current->pid, lock.context ); - return -EINVAL; - } + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + current->pid, lock.context); + return -EINVAL; + } - DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock.context, current->pid, - dev->lock.hw_lock->lock, lock.flags ); + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", + lock.context, current->pid, + dev->lock.hw_lock->lock, lock.flags); if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) - if ( lock.context < 0 ) + if (lock.context < 0) return -EINVAL; - add_wait_queue( &dev->lock.lock_queue, &entry ); + add_wait_queue(&dev->lock.lock_queue, &entry); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); - if ( !dev->lock.hw_lock ) { + if (!dev->lock.hw_lock) { /* Device has been unregistered */ ret = -EINTR; break; } - if ( drm_lock_take( &dev->lock.hw_lock->lock, - lock.context ) ) { - dev->lock.filp = filp; + if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { + dev->lock.filp = filp; dev->lock.lock_time = jiffies; - atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); - break; /* Got lock */ + atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); + break; /* Got lock */ } - + /* Contention */ schedule(); - if ( signal_pending( current ) ) { + if (signal_pending(current)) { ret = -ERESTARTSYS; break; } } __set_current_state(TASK_RUNNING); - remove_wait_queue( &dev->lock.lock_queue, &entry ); + remove_wait_queue(&dev->lock.lock_queue, &entry); - sigemptyset( &dev->sigmask ); - sigaddset( &dev->sigmask, SIGSTOP ); - sigaddset( &dev->sigmask, SIGTSTP ); - sigaddset( &dev->sigmask, SIGTTIN ); - sigaddset( &dev->sigmask, SIGTTOU ); + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); dev->sigdata.context = lock.context; - dev->sigdata.lock = dev->lock.hw_lock; - block_all_signals( drm_notifier, - &dev->sigdata, &dev->sigmask ); - + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); + if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY)) dev->driver->dma_ready(dev); - - if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT )) + + if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) return dev->driver->dma_quiescent(dev); - - /* dev->driver->kernel_context_switch isn't used by any of the x86 + + /* dev->driver->kernel_context_switch isn't used by any of the x86 * drivers but is used by the Sparc driver. */ - - if (dev->driver->kernel_context_switch && - dev->last_context != lock.context) { - dev->driver->kernel_context_switch(dev, dev->last_context, - lock.context); - } - DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); - return ret; + if (dev->driver->kernel_context_switch && + dev->last_context != lock.context) { + dev->driver->kernel_context_switch(dev, dev->last_context, + lock.context); + } + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + + return ret; } -/** +/** * Unlock ioctl. * * \param inode device inode. @@ -146,23 +144,23 @@ int drm_lock( struct inode *inode, struct file *filp, * * Transfer and free the lock. */ -int drm_unlock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_unlock(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_lock_t lock; - if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) ) + if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock))) return -EFAULT; - if ( lock.context == DRM_KERNEL_CONTEXT ) { - DRM_ERROR( "Process %d using kernel context %d\n", - current->pid, lock.context ); + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + current->pid, lock.context); return -EINVAL; } - atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); + atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); /* kernel_context_switch isn't used by any of the x86 drm * modules but is required by the Sparc driver. @@ -170,12 +168,12 @@ int drm_unlock( struct inode *inode, struct file *filp, if (dev->driver->kernel_context_switch_unlock) dev->driver->kernel_context_switch_unlock(dev, &lock); else { - drm_lock_transfer( dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT ); - - if ( drm_lock_free( dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT ) ) { - DRM_ERROR( "\n" ); + drm_lock_transfer(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + + if (drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + DRM_ERROR("\n"); } } @@ -198,8 +196,10 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) do { old = *lock; - if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; - else new = context | _DRM_LOCK_HELD; + if (old & _DRM_LOCK_HELD) + new = old | _DRM_LOCK_CONT; + else + new = context | _DRM_LOCK_HELD; prev = cmpxchg(lock, old, new); } while (prev != old); if (_DRM_LOCKING_CONTEXT(old) == context) { @@ -212,7 +212,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) } } if (new == (context | _DRM_LOCK_HELD)) { - /* Have lock */ + /* Have lock */ return 1; } return 0; @@ -220,8 +220,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) /** * This takes a lock forcibly and hands it to context. Should ONLY be used - * inside *_unlock to give lock to kernel before calling *_dma_schedule. - * + * inside *_unlock to give lock to kernel before calling *_dma_schedule. + * * \param dev DRM device. * \param lock lock pointer. * \param context locking context. @@ -230,7 +230,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) * Resets the lock file pointer. * Marks the lock as held by the given context, via the \p cmpxchg instruction. */ -static int drm_lock_transfer(drm_device_t *dev, +static int drm_lock_transfer(drm_device_t * dev, __volatile__ unsigned int *lock, unsigned int context) { @@ -238,8 +238,8 @@ static int drm_lock_transfer(drm_device_t *dev, dev->lock.filp = NULL; do { - old = *lock; - new = context | _DRM_LOCK_HELD; + old = *lock; + new = context | _DRM_LOCK_HELD; prev = cmpxchg(lock, old, new); } while (prev != old); return 1; @@ -247,30 +247,29 @@ static int drm_lock_transfer(drm_device_t *dev, /** * Free lock. - * + * * \param dev DRM device. * \param lock lock. * \param context context. - * + * * Resets the lock file pointer. * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task * waiting on the lock queue. */ -int drm_lock_free(drm_device_t *dev, - __volatile__ unsigned int *lock, unsigned int context) +int drm_lock_free(drm_device_t * dev, + __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; dev->lock.filp = NULL; do { - old = *lock; - new = 0; + old = *lock; + new = 0; prev = cmpxchg(lock, old, new); } while (prev != old); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { DRM_ERROR("%d freed heavyweight lock held by %d\n", - context, - _DRM_LOCKING_CONTEXT(old)); + context, _DRM_LOCKING_CONTEXT(old)); return 1; } wake_up_interruptible(&dev->lock.lock_queue); @@ -290,19 +289,19 @@ int drm_lock_free(drm_device_t *dev, */ static int drm_notifier(void *priv) { - drm_sigdata_t *s = (drm_sigdata_t *)priv; - unsigned int old, new, prev; + drm_sigdata_t *s = (drm_sigdata_t *) priv; + unsigned int old, new, prev; - - /* Allow signal delivery if lock isn't held */ + /* Allow signal delivery if lock isn't held */ if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock) - || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1; + || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) + return 1; - /* Otherwise, set flag to force call to - drmUnlock */ + /* Otherwise, set flag to force call to + drmUnlock */ do { - old = s->lock->lock; - new = old | _DRM_LOCK_CONT; + old = s->lock->lock; + new = old | _DRM_LOCK_CONT; prev = cmpxchg(&s->lock->lock, old, new); } while (prev != old); return 0; diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c index ff483fb418aa..2c74155aa84f 100644 --- a/drivers/char/drm/drm_memory.c +++ b/drivers/char/drm/drm_memory.c @@ -1,12 +1,12 @@ -/** - * \file drm_memory.h +/** + * \file drm_memory.c * Memory management wrappers for DRM * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ -/* +/* * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -48,7 +48,7 @@ void drm_mem_init(void) /** * Called when "/proc/dri/%dev%/mem" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -57,10 +57,10 @@ void drm_mem_init(void) * \param data private data. * \return number of written bytes. * - * No-op. + * No-op. */ int drm_mem_info(char *buf, char **start, off_t offset, - int len, int *eof, void *data) + int len, int *eof, void *data) { return 0; } @@ -70,7 +70,8 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) { void *pt; - if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL; + if (!(pt = kmalloc(size, GFP_KERNEL))) + return NULL; if (oldpt && oldsize) { memcpy(pt, oldpt, oldsize); kfree(oldpt); @@ -90,21 +91,20 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) unsigned long drm_alloc_pages(int order, int area) { unsigned long address; - unsigned long bytes = PAGE_SIZE << order; + unsigned long bytes = PAGE_SIZE << order; unsigned long addr; - unsigned int sz; + unsigned int sz; address = __get_free_pages(GFP_KERNEL, order); - if (!address) + if (!address) return 0; - /* Zero */ + /* Zero */ memset((void *)address, 0, bytes); - /* Reserve */ + /* Reserve */ for (addr = address, sz = bytes; - sz > 0; - addr += PAGE_SIZE, sz -= PAGE_SIZE) { + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { SetPageReserved(virt_to_page(addr)); } @@ -113,7 +113,7 @@ unsigned long drm_alloc_pages(int order, int area) /** * Free pages. - * + * * \param address address of the pages to free. * \param order size order. * \param area memory area. (Not used.) @@ -124,49 +124,51 @@ void drm_free_pages(unsigned long address, int order, int area) { unsigned long bytes = PAGE_SIZE << order; unsigned long addr; - unsigned int sz; + unsigned int sz; - if (!address) + if (!address) return; /* Unreserve */ for (addr = address, sz = bytes; - sz > 0; - addr += PAGE_SIZE, sz -= PAGE_SIZE) { + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); } free_pages(address, order); } - #if __OS_HAS_AGP /** Wrapper around agp_allocate_memory() */ -DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type) +DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) { return drm_agp_allocate_memory(dev->agp->bridge, pages, type); } + EXPORT_SYMBOL(drm_alloc_agp); /** Wrapper around agp_free_memory() */ -int drm_free_agp(DRM_AGP_MEM *handle, int pages) +int drm_free_agp(DRM_AGP_MEM * handle, int pages) { return drm_agp_free_memory(handle) ? 0 : -EINVAL; } + EXPORT_SYMBOL(drm_free_agp); /** Wrapper around agp_bind_memory() */ -int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start) +int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) { return drm_agp_bind_memory(handle, start); } + EXPORT_SYMBOL(drm_bind_agp); /** Wrapper around agp_unbind_memory() */ -int drm_unbind_agp(DRM_AGP_MEM *handle) +int drm_unbind_agp(DRM_AGP_MEM * handle) { return drm_agp_unbind_memory(handle); } + EXPORT_SYMBOL(drm_unbind_agp); -#endif /* agp */ -#endif /* debug_memory */ +#endif /* agp */ +#endif /* debug_memory */ diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h index 422b94268709..3732a61c3762 100644 --- a/drivers/char/drm/drm_memory.h +++ b/drivers/char/drm/drm_memory.h @@ -1,12 +1,12 @@ -/** - * \file drm_memory.h +/** + * \file drm_memory.h * Memory management wrappers for DRM * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ -/* +/* * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -40,7 +40,7 @@ /** * Cut down version of drm_memory_debug.h, which used to be called - * drm_memory.h. + * drm_memory.h. */ #if __OS_HAS_AGP @@ -60,8 +60,8 @@ /* * Find the drm_map that covers the range [offset, offset+size). */ -static inline drm_map_t * -drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev) +static inline drm_map_t *drm_lookup_map(unsigned long offset, + unsigned long size, drm_device_t * dev) { struct list_head *list; drm_map_list_t *r_list; @@ -72,16 +72,18 @@ drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev) map = r_list->map; if (!map) continue; - if (map->offset <= offset && (offset + size) <= (map->offset + map->size)) + if (map->offset <= offset + && (offset + size) <= (map->offset + map->size)) return map; } return NULL; } -static inline void * -agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev) +static inline void *agp_remap(unsigned long offset, unsigned long size, + drm_device_t * dev) { - unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE; + unsigned long *phys_addr_map, i, num_pages = + PAGE_ALIGN(size) / PAGE_SIZE; struct drm_agp_mem *agpmem; struct page **page_map; void *addr; @@ -94,7 +96,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev) for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) if (agpmem->bound <= offset - && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size)) + && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= + (offset + size)) break; if (!agpmem) return NULL; @@ -109,7 +112,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev) if (!page_map) return NULL; - phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; + phys_addr_map = + agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; for (i = 0; i < num_pages; ++i) page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); @@ -118,36 +122,38 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev) return addr; } -static inline unsigned long -drm_follow_page (void *vaddr) +static inline unsigned long drm_follow_page(void *vaddr) { - pgd_t *pgd = pgd_offset_k((unsigned long) vaddr); - pud_t *pud = pud_offset(pgd, (unsigned long) vaddr); - pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr); - pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr); + pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); + pud_t *pud = pud_offset(pgd, (unsigned long)vaddr); + pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr); + pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr); return pte_pfn(*ptep) << PAGE_SHIFT; } -#else /* __OS_HAS_AGP */ +#else /* __OS_HAS_AGP */ -static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev) +static inline drm_map_t *drm_lookup_map(unsigned long offset, + unsigned long size, drm_device_t * dev) { - return NULL; + return NULL; } -static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev) +static inline void *agp_remap(unsigned long offset, unsigned long size, + drm_device_t * dev) { - return NULL; + return NULL; } -static inline unsigned long drm_follow_page (void *vaddr) +static inline unsigned long drm_follow_page(void *vaddr) { - return 0; + return 0; } #endif -static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev) +static inline void *drm_ioremap(unsigned long offset, unsigned long size, + drm_device_t * dev) { if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { drm_map_t *map = drm_lookup_map(offset, size, dev); @@ -158,8 +164,8 @@ static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_de return ioremap(offset, size); } -static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size, - drm_device_t *dev) +static inline void *drm_ioremap_nocache(unsigned long offset, + unsigned long size, drm_device_t * dev) { if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { drm_map_t *map = drm_lookup_map(offset, size, dev); @@ -170,7 +176,8 @@ static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size return ioremap_nocache(offset, size); } -static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev) +static inline void drm_ioremapfree(void *pt, unsigned long size, + drm_device_t * dev) { /* * This is a bit ugly. It would be much cleaner if the DRM API would use separate @@ -178,12 +185,12 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d * a future revision of the interface... */ if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture - && ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END)) - { + && ((unsigned long)pt >= VMALLOC_START + && (unsigned long)pt < VMALLOC_END)) { unsigned long offset; drm_map_t *map; - offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK); + offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK); map = drm_lookup_map(offset, size, dev); if (map && map->type == _DRM_AGP) { vunmap(pt); @@ -193,5 +200,3 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d iounmap(pt); } - - diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index 2c82e69a7fd2..4542353195bd 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h @@ -1,5 +1,5 @@ /** - * \file drm_memory.h + * \file drm_memory.h * Memory management wrappers for DRM. * * \author Rickard E. (Rik) Faith @@ -35,75 +35,75 @@ #include "drmP.h" typedef struct drm_mem_stats { - const char *name; - int succeed_count; - int free_count; - int fail_count; - unsigned long bytes_allocated; - unsigned long bytes_freed; + const char *name; + int succeed_count; + int free_count; + int fail_count; + unsigned long bytes_allocated; + unsigned long bytes_freed; } drm_mem_stats_t; static DEFINE_SPINLOCK(DRM(mem_lock)); -static unsigned long DRM(ram_available) = 0; /* In pages */ -static unsigned long DRM(ram_used) = 0; -static drm_mem_stats_t DRM(mem_stats)[] = { - [DRM_MEM_DMA] = { "dmabufs" }, - [DRM_MEM_SAREA] = { "sareas" }, - [DRM_MEM_DRIVER] = { "driver" }, - [DRM_MEM_MAGIC] = { "magic" }, - [DRM_MEM_IOCTLS] = { "ioctltab" }, - [DRM_MEM_MAPS] = { "maplist" }, - [DRM_MEM_VMAS] = { "vmalist" }, - [DRM_MEM_BUFS] = { "buflist" }, - [DRM_MEM_SEGS] = { "seglist" }, - [DRM_MEM_PAGES] = { "pagelist" }, - [DRM_MEM_FILES] = { "files" }, - [DRM_MEM_QUEUES] = { "queues" }, - [DRM_MEM_CMDS] = { "commands" }, - [DRM_MEM_MAPPINGS] = { "mappings" }, - [DRM_MEM_BUFLISTS] = { "buflists" }, - [DRM_MEM_AGPLISTS] = { "agplist" }, - [DRM_MEM_SGLISTS] = { "sglist" }, - [DRM_MEM_TOTALAGP] = { "totalagp" }, - [DRM_MEM_BOUNDAGP] = { "boundagp" }, - [DRM_MEM_CTXBITMAP] = { "ctxbitmap"}, - [DRM_MEM_CTXLIST] = { "ctxlist" }, - [DRM_MEM_STUB] = { "stub" }, - { NULL, 0, } /* Last entry must be null */ +static unsigned long DRM(ram_available) = 0; /* In pages */ +static unsigned long DRM(ram_used) = 0; +static drm_mem_stats_t DRM(mem_stats)[] = +{ + [DRM_MEM_DMA] = { + "dmabufs"},[DRM_MEM_SAREA] = { + "sareas"},[DRM_MEM_DRIVER] = { + "driver"},[DRM_MEM_MAGIC] = { + "magic"},[DRM_MEM_IOCTLS] = { + "ioctltab"},[DRM_MEM_MAPS] = { + "maplist"},[DRM_MEM_VMAS] = { + "vmalist"},[DRM_MEM_BUFS] = { + "buflist"},[DRM_MEM_SEGS] = { + "seglist"},[DRM_MEM_PAGES] = { + "pagelist"},[DRM_MEM_FILES] = { + "files"},[DRM_MEM_QUEUES] = { + "queues"},[DRM_MEM_CMDS] = { + "commands"},[DRM_MEM_MAPPINGS] = { + "mappings"},[DRM_MEM_BUFLISTS] = { + "buflists"},[DRM_MEM_AGPLISTS] = { + "agplist"},[DRM_MEM_SGLISTS] = { + "sglist"},[DRM_MEM_TOTALAGP] = { + "totalagp"},[DRM_MEM_BOUNDAGP] = { + "boundagp"},[DRM_MEM_CTXBITMAP] = { + "ctxbitmap"},[DRM_MEM_CTXLIST] = { + "ctxlist"},[DRM_MEM_STUB] = { + "stub"}, { + NULL, 0,} /* Last entry must be null */ }; -void DRM(mem_init)(void) -{ +void DRM(mem_init) (void) { drm_mem_stats_t *mem; - struct sysinfo si; + struct sysinfo si; for (mem = DRM(mem_stats); mem->name; ++mem) { - mem->succeed_count = 0; - mem->free_count = 0; - mem->fail_count = 0; + mem->succeed_count = 0; + mem->free_count = 0; + mem->fail_count = 0; mem->bytes_allocated = 0; - mem->bytes_freed = 0; + mem->bytes_freed = 0; } si_meminfo(&si); DRM(ram_available) = si.totalram; - DRM(ram_used) = 0; + DRM(ram_used) = 0; } /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ -static int DRM(_mem_info)(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ +static int DRM(_mem_info) (char *buf, char **start, off_t offset, + int request, int *eof, void *data) { drm_mem_stats_t *pt; - int len = 0; + int len = 0; if (offset > DRM_PROC_LIMIT) { *eof = 1; return 0; } - *eof = 0; + *eof = 0; *start = &buf[offset]; DRM_PROC_PRINT(" total counts " @@ -129,24 +129,23 @@ static int DRM(_mem_info)(char *buf, char **start, off_t offset, - (long)pt->bytes_freed); } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } -int DRM(mem_info)(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ +int DRM(mem_info) (char *buf, char **start, off_t offset, + int len, int *eof, void *data) { int ret; spin_lock(&DRM(mem_lock)); - ret = DRM(_mem_info)(buf, start, offset, len, eof, data); + ret = DRM(_mem_info) (buf, start, offset, len, eof, data); spin_unlock(&DRM(mem_lock)); return ret; } -void *DRM(alloc)(size_t size, int area) -{ +void *DRM(alloc) (size_t size, int area) { void *pt; if (!size) { @@ -167,40 +166,40 @@ void *DRM(alloc)(size_t size, int area) return pt; } -void *DRM(calloc)(size_t nmemb, size_t size, int area) -{ +void *DRM(calloc) (size_t nmemb, size_t size, int area) { void *addr; - addr = DRM(alloc)(nmemb * size, area); + addr = DRM(alloc) (nmemb * size, area); if (addr != NULL) memset((void *)addr, 0, size * nmemb); return addr; } -void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area) -{ +void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) { void *pt; - if (!(pt = DRM(alloc)(size, area))) return NULL; + if (!(pt = DRM(alloc) (size, area))) + return NULL; if (oldpt && oldsize) { memcpy(pt, oldpt, oldsize); - DRM(free)(oldpt, oldsize, area); + DRM(free) (oldpt, oldsize, area); } return pt; } -void DRM(free)(void *pt, size_t size, int area) -{ +void DRM(free) (void *pt, size_t size, int area) { int alloc_count; int free_count; - if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); - else kfree(pt); + if (!pt) + DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); + else + kfree(pt); spin_lock(&DRM(mem_lock)); DRM(mem_stats)[area].bytes_freed += size; - free_count = ++DRM(mem_stats)[area].free_count; - alloc_count = DRM(mem_stats)[area].succeed_count; + free_count = ++DRM(mem_stats)[area].free_count; + alloc_count = DRM(mem_stats)[area].succeed_count; spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", @@ -208,12 +207,11 @@ void DRM(free)(void *pt, size_t size, int area) } } -unsigned long DRM(alloc_pages)(int order, int area) -{ +unsigned long DRM(alloc_pages) (int order, int area) { unsigned long address; - unsigned long bytes = PAGE_SIZE << order; + unsigned long bytes = PAGE_SIZE << order; unsigned long addr; - unsigned int sz; + unsigned int sz; spin_lock(&DRM(mem_lock)); if ((DRM(ram_used) >> PAGE_SHIFT) @@ -233,48 +231,44 @@ unsigned long DRM(alloc_pages)(int order, int area) spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[area].succeed_count; DRM(mem_stats)[area].bytes_allocated += bytes; - DRM(ram_used) += bytes; + DRM(ram_used) += bytes; spin_unlock(&DRM(mem_lock)); - - /* Zero outside the lock */ + /* Zero outside the lock */ memset((void *)address, 0, bytes); - /* Reserve */ + /* Reserve */ for (addr = address, sz = bytes; - sz > 0; - addr += PAGE_SIZE, sz -= PAGE_SIZE) { + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { SetPageReserved(virt_to_page(addr)); } return address; } -void DRM(free_pages)(unsigned long address, int order, int area) -{ +void DRM(free_pages) (unsigned long address, int order, int area) { unsigned long bytes = PAGE_SIZE << order; - int alloc_count; - int free_count; + int alloc_count; + int free_count; unsigned long addr; - unsigned int sz; + unsigned int sz; if (!address) { DRM_MEM_ERROR(area, "Attempt to free address 0\n"); } else { - /* Unreserve */ + /* Unreserve */ for (addr = address, sz = bytes; - sz > 0; - addr += PAGE_SIZE, sz -= PAGE_SIZE) { + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); } free_pages(address, order); } spin_lock(&DRM(mem_lock)); - free_count = ++DRM(mem_stats)[area].free_count; - alloc_count = DRM(mem_stats)[area].succeed_count; + free_count = ++DRM(mem_stats)[area].free_count; + alloc_count = DRM(mem_stats)[area].succeed_count; DRM(mem_stats)[area].bytes_freed += bytes; - DRM(ram_used) -= bytes; + DRM(ram_used) -= bytes; spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, @@ -283,8 +277,8 @@ void DRM(free_pages)(unsigned long address, int order, int area) } } -void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) -{ +void *DRM(ioremap) (unsigned long offset, unsigned long size, + drm_device_t * dev) { void *pt; if (!size) { @@ -306,8 +300,8 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) return pt; } -void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) -{ +void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size, + drm_device_t * dev) { void *pt; if (!size) { @@ -329,8 +323,7 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_ return pt; } -void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) -{ +void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { int alloc_count; int free_count; @@ -342,8 +335,8 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) spin_lock(&DRM(mem_lock)); DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; - free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; - alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; + alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, @@ -354,8 +347,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) #if __OS_HAS_AGP -DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type) -{ +DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) { DRM_AGP_MEM *handle; if (!pages) { @@ -363,11 +355,11 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type) return NULL; } - if ((handle = DRM(agp_allocate_memory)(pages, type))) { + if ((handle = DRM(agp_allocate_memory) (pages, type))) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated - += pages << PAGE_SHIFT; + += pages << PAGE_SHIFT; spin_unlock(&DRM(mem_lock)); return handle; } @@ -377,11 +369,10 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type) return NULL; } -int DRM(free_agp)(DRM_AGP_MEM *handle, int pages) -{ - int alloc_count; - int free_count; - int retval = -EINVAL; +int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { + int alloc_count; + int free_count; + int retval = -EINVAL; if (!handle) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, @@ -389,12 +380,12 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages) return retval; } - if (DRM(agp_free_memory)(handle)) { + if (DRM(agp_free_memory) (handle)) { spin_lock(&DRM(mem_lock)); - free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; - alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; + free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; + alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed - += pages << PAGE_SHIFT; + += pages << PAGE_SHIFT; spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, @@ -406,8 +397,7 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages) return retval; } -int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start) -{ +int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) { int retcode = -EINVAL; if (!handle) { @@ -416,11 +406,11 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start) return retcode; } - if (!(retcode = DRM(agp_bind_memory)(handle, start))) { + if (!(retcode = DRM(agp_bind_memory) (handle, start))) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated - += handle->page_count << PAGE_SHIFT; + += handle->page_count << PAGE_SHIFT; spin_unlock(&DRM(mem_lock)); return retcode; } @@ -430,8 +420,7 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start) return retcode; } -int DRM(unbind_agp)(DRM_AGP_MEM *handle) -{ +int DRM(unbind_agp) (DRM_AGP_MEM * handle) { int alloc_count; int free_count; int retcode = -EINVAL; @@ -442,12 +431,13 @@ int DRM(unbind_agp)(DRM_AGP_MEM *handle) return retcode; } - if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode; + if ((retcode = DRM(agp_unbind_memory) (handle))) + return retcode; spin_lock(&DRM(mem_lock)); - free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; + free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed - += handle->page_count << PAGE_SHIFT; + += handle->page_count << PAGE_SHIFT; spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h index b14cd370dea5..d51aeb4966f4 100644 --- a/drivers/char/drm/drm_os_linux.h +++ b/drivers/char/drm/drm_os_linux.h @@ -3,7 +3,6 @@ * OS abstraction macros. */ - #include /* For task queue support */ #include @@ -47,25 +46,25 @@ #else /* define some dummy types for non AGP supporting kernels */ struct no_agp_kern { - unsigned long aper_base; - unsigned long aper_size; + unsigned long aper_base; + unsigned long aper_size; }; #define DRM_AGP_MEM int #define DRM_AGP_KERN struct no_agp_kern #endif #if !(__OS_HAS_MTRR) -static __inline__ int mtrr_add (unsigned long base, unsigned long size, - unsigned int type, char increment) +static __inline__ int mtrr_add(unsigned long base, unsigned long size, + unsigned int type, char increment) { return -ENODEV; } -static __inline__ int mtrr_del (int reg, unsigned long base, - unsigned long size) +static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) { return -ENODEV; } + #define MTRR_TYPE_WRCOMB 1 #endif @@ -99,7 +98,7 @@ static __inline__ int mtrr_del (int reg, unsigned long base, #define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data -/** +/** * Get the pointer to the SAREA. * * Searches the SAREA on the mapping lists and points drm_device::sarea to it. @@ -143,7 +142,5 @@ do { \ remove_wait_queue(&(queue), &entry); \ } while (0) - #define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) - diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c index 09ed712c1a7f..1fd7ff164817 100644 --- a/drivers/char/drm/drm_pci.c +++ b/drivers/char/drm/drm_pci.c @@ -77,7 +77,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); if (!dmah) return NULL; - + dmah->size = size; dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); @@ -106,6 +106,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, return dmah; } + EXPORT_SYMBOL(drm_pci_alloc); /** @@ -113,8 +114,7 @@ EXPORT_SYMBOL(drm_pci_alloc); * * This function is for internal use in the Linux-specific DRM core code. */ -void -__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) +void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) { #ifdef DRM_DEBUG_MEMORY int area = DRM_MEM_DMA; @@ -150,12 +150,12 @@ __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) /** * \brief Free a PCI consistent memory block */ -void -drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah) +void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) { __drm_pci_free(dev, dmah); kfree(dmah); } + EXPORT_SYMBOL(drm_pci_free); /*@}*/ diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 58b1747cd440..d66dc55e29a0 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -234,4 +234,3 @@ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} - diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index 32d2bb99462c..8ec2156b97a9 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c @@ -1,5 +1,5 @@ /** - * \file drm_proc.h + * \file drm_proc.c * /proc support for DRM * * \author Rickard E. (Rik) Faith @@ -39,19 +39,19 @@ #include "drmP.h" -static int drm_name_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_vm_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_queues_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_bufs_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); +static int drm_name_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); +static int drm_vm_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); +static int drm_clients_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); +static int drm_queues_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); +static int drm_bufs_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); #if DRM_DEBUG_CODE -static int drm_vma_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); +static int drm_vma_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data); #endif /** @@ -59,18 +59,21 @@ static int drm_vma_info(char *buf, char **start, off_t offset, */ static struct drm_proc_list { const char *name; /**< file name */ - int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/ + int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ } drm_proc_list[] = { - { "name", drm_name_info }, - { "mem", drm_mem_info }, - { "vm", drm_vm_info }, - { "clients", drm_clients_info }, - { "queues", drm_queues_info }, - { "bufs", drm_bufs_info }, + { + "name", drm_name_info}, { + "mem", drm_mem_info}, { + "vm", drm_vm_info}, { + "clients", drm_clients_info}, { + "queues", drm_queues_info}, { + "bufs", drm_bufs_info}, #if DRM_DEBUG_CODE - { "vma", drm_vma_info }, + { + "vma", drm_vma_info}, #endif }; + #define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0])) /** @@ -81,18 +84,17 @@ static struct drm_proc_list { * \param root DRI proc dir entry. * \param dev_root resulting DRI device proc dir entry. * \return root entry pointer on success, or NULL on failure. - * + * * Create the DRI proc root entry "/proc/dri", the device proc root entry * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -int drm_proc_init(drm_device_t *dev, int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root) +int drm_proc_init(drm_device_t * dev, int minor, + struct proc_dir_entry *root, struct proc_dir_entry **dev_root) { struct proc_dir_entry *ent; - int i, j; - char name[64]; + int i, j; + char name[64]; sprintf(name, "%d", minor); *dev_root = create_proc_entry(name, S_IFDIR, root); @@ -103,7 +105,7 @@ int drm_proc_init(drm_device_t *dev, int minor, for (i = 0; i < DRM_PROC_ENTRIES; i++) { ent = create_proc_entry(drm_proc_list[i].name, - S_IFREG|S_IRUGO, *dev_root); + S_IFREG | S_IRUGO, *dev_root); if (!ent) { DRM_ERROR("Cannot create /proc/dri/%s/%s\n", name, drm_proc_list[i].name); @@ -114,13 +116,12 @@ int drm_proc_init(drm_device_t *dev, int minor, return -1; } ent->read_proc = drm_proc_list[i].f; - ent->data = dev; + ent->data = dev; } return 0; } - /** * Cleanup the proc filesystem resources. * @@ -132,12 +133,13 @@ int drm_proc_init(drm_device_t *dev, int minor, * Remove all proc entries created by proc_init(). */ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, - struct proc_dir_entry *dev_root) + struct proc_dir_entry *dev_root) { - int i; + int i; char name[64]; - if (!root || !dev_root) return 0; + if (!root || !dev_root) + return 0; for (i = 0; i < DRM_PROC_ENTRIES; i++) remove_proc_entry(drm_proc_list[i].name, dev_root); @@ -149,7 +151,7 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, /** * Called when "/proc/dri/.../name" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -157,14 +159,14 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, * \param eof whether there is no more data to return. * \param data private data. * \return number of written bytes. - * + * * Prints the device name together with the bus id if available. */ static int drm_name_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; if (offset > DRM_PROC_LIMIT) { *eof = 1; @@ -172,23 +174,26 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, } *start = &buf[offset]; - *eof = 0; + *eof = 0; if (dev->unique) { DRM_PROC_PRINT("%s %s %s\n", - dev->driver->pci_driver.name, pci_name(dev->pdev), dev->unique); + dev->driver->pci_driver.name, + pci_name(dev->pdev), dev->unique); } else { - DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, pci_name(dev->pdev)); + DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, + pci_name(dev->pdev)); } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } /** * Called when "/proc/dri/.../vm" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -196,24 +201,24 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, * \param eof whether there is no more data to return. * \param data private data. * \return number of written bytes. - * + * * Prints information about all mappings in drm_device::maplist. */ static int drm__vm_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - drm_map_t *map; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; + drm_map_t *map; drm_map_list_t *r_list; struct list_head *list; - /* Hardcoded from _DRM_FRAME_BUFFER, - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and - _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; - const char *type; - int i; + /* Hardcoded from _DRM_FRAME_BUFFER, + _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and + _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ + const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; + const char *type; + int i; if (offset > DRM_PROC_LIMIT) { *eof = 1; @@ -221,36 +226,35 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, } *start = &buf[offset]; - *eof = 0; + *eof = 0; DRM_PROC_PRINT("slot offset size type flags " "address mtrr\n\n"); i = 0; - if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) { + if (dev->maplist != NULL) + list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; - if(!map) + if (!map) continue; if (map->type < 0 || map->type > 5) type = "??"; - else + else type = types[map->type]; DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08x ", i, map->offset, - map->size, - type, - map->flags, - r_list->user_token); + map->size, type, map->flags, r_list->user_token); if (map->mtrr < 0) { DRM_PROC_PRINT("none\n"); } else { DRM_PROC_PRINT("%4d\n", map->mtrr); } i++; - } + } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } @@ -259,10 +263,10 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, * Simply calls _vm_info() while holding the drm_device::struct_sem lock. */ static int drm_vm_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int ret; + drm_device_t *dev = (drm_device_t *) data; + int ret; down(&dev->struct_sem); ret = drm__vm_info(buf, start, offset, request, eof, data); @@ -272,7 +276,7 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, /** * Called when "/proc/dri/.../queues" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -282,12 +286,12 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, * \return number of written bytes. */ static int drm__queues_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) + int request, int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - int i; - drm_queue_t *q; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; + int i; + drm_queue_t *q; if (offset > DRM_PROC_LIMIT) { *eof = 1; @@ -295,7 +299,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset, } *start = &buf[offset]; - *eof = 0; + *eof = 0; DRM_PROC_PRINT(" ctx/flags use fin" " blk/rw/rwf wait flushed queued" @@ -313,14 +317,17 @@ static int drm__queues_info(char *buf, char **start, off_t offset, atomic_read(&q->block_count), atomic_read(&q->block_read) ? 'r' : '-', atomic_read(&q->block_write) ? 'w' : '-', - waitqueue_active(&q->read_queue) ? 'r':'-', - waitqueue_active(&q->write_queue) ? 'w':'-', - waitqueue_active(&q->flush_queue) ? 'f':'-', + waitqueue_active(&q->read_queue) ? 'r' : '-', + waitqueue_active(&q-> + write_queue) ? 'w' : '-', + waitqueue_active(&q-> + flush_queue) ? 'f' : '-', DRM_BUFCOUNT(&q->waitlist)); atomic_dec(&q->use_count); } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } @@ -329,10 +336,10 @@ static int drm__queues_info(char *buf, char **start, off_t offset, * Simply calls _queues_info() while holding the drm_device::struct_sem lock. */ static int drm_queues_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int ret; + drm_device_t *dev = (drm_device_t *) data; + int ret; down(&dev->struct_sem); ret = drm__queues_info(buf, start, offset, request, eof, data); @@ -342,7 +349,7 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, /** * Called when "/proc/dri/.../bufs" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -352,12 +359,12 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, * \return number of written bytes. */ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; drm_device_dma_t *dma = dev->dma; - int i; + int i; if (!dma || offset > DRM_PROC_LIMIT) { *eof = 1; @@ -365,7 +372,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, } *start = &buf[offset]; - *eof = 0; + *eof = 0; DRM_PROC_PRINT(" o size count free segs pages kB\n\n"); for (i = 0; i <= DRM_MAX_ORDER; i++) { @@ -378,19 +385,21 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, .freelist.count), dma->bufs[i].seg_count, dma->bufs[i].seg_count - *(1 << dma->bufs[i].page_order), + * (1 << dma->bufs[i].page_order), (dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order)) * PAGE_SIZE / 1024); } DRM_PROC_PRINT("\n"); for (i = 0; i < dma->buf_count; i++) { - if (i && !(i%32)) DRM_PROC_PRINT("\n"); + if (i && !(i % 32)) + DRM_PROC_PRINT("\n"); DRM_PROC_PRINT(" %d", dma->buflist[i]->list); } DRM_PROC_PRINT("\n"); - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } @@ -399,10 +408,10 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, * Simply calls _bufs_info() while holding the drm_device::struct_sem lock. */ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int ret; + drm_device_t *dev = (drm_device_t *) data; + int ret; down(&dev->struct_sem); ret = drm__bufs_info(buf, start, offset, request, eof, data); @@ -412,7 +421,7 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, /** * Called when "/proc/dri/.../clients" is read. - * + * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. @@ -422,11 +431,11 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, * \return number of written bytes. */ static int drm__clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) + int request, int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - drm_file_t *priv; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; + drm_file_t *priv; if (offset > DRM_PROC_LIMIT) { *eof = 1; @@ -434,7 +443,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, } *start = &buf[offset]; - *eof = 0; + *eof = 0; DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n"); for (priv = dev->file_first; priv; priv = priv->next) { @@ -442,12 +451,11 @@ static int drm__clients_info(char *buf, char **start, off_t offset, priv->authenticated ? 'y' : 'n', priv->minor, priv->pid, - priv->uid, - priv->magic, - priv->ioctl_count); + priv->uid, priv->magic, priv->ioctl_count); } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } @@ -456,10 +464,10 @@ static int drm__clients_info(char *buf, char **start, off_t offset, * Simply calls _clients_info() while holding the drm_device::struct_sem lock. */ static int drm_clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) + int request, int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int ret; + drm_device_t *dev = (drm_device_t *) data; + int ret; down(&dev->struct_sem); ret = drm__clients_info(buf, start, offset, request, eof, data); @@ -470,14 +478,14 @@ static int drm_clients_info(char *buf, char **start, off_t offset, #if DRM_DEBUG_CODE static int drm__vma_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - drm_vma_entry_t *pt; + drm_device_t *dev = (drm_device_t *) data; + int len = 0; + drm_vma_entry_t *pt; struct vm_area_struct *vma; #if defined(__i386__) - unsigned int pgprot; + unsigned int pgprot; #endif if (offset > DRM_PROC_LIMIT) { @@ -486,51 +494,53 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, } *start = &buf[offset]; - *eof = 0; + *eof = 0; DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", atomic_read(&dev->vma_count), high_memory, virt_to_phys(high_memory)); for (pt = dev->vmalist; pt; pt = pt->next) { - if (!(vma = pt->vma)) continue; + if (!(vma = pt->vma)) + continue; DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", pt->pid, vma->vm_start, vma->vm_end, - vma->vm_flags & VM_READ ? 'r' : '-', - vma->vm_flags & VM_WRITE ? 'w' : '-', - vma->vm_flags & VM_EXEC ? 'x' : '-', + vma->vm_flags & VM_READ ? 'r' : '-', + vma->vm_flags & VM_WRITE ? 'w' : '-', + vma->vm_flags & VM_EXEC ? 'x' : '-', vma->vm_flags & VM_MAYSHARE ? 's' : 'p', - vma->vm_flags & VM_LOCKED ? 'l' : '-', - vma->vm_flags & VM_IO ? 'i' : '-', + vma->vm_flags & VM_LOCKED ? 'l' : '-', + vma->vm_flags & VM_IO ? 'i' : '-', VM_OFFSET(vma)); #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c", - pgprot & _PAGE_PRESENT ? 'p' : '-', - pgprot & _PAGE_RW ? 'w' : 'r', - pgprot & _PAGE_USER ? 'u' : 's', - pgprot & _PAGE_PWT ? 't' : 'b', - pgprot & _PAGE_PCD ? 'u' : 'c', + pgprot & _PAGE_PRESENT ? 'p' : '-', + pgprot & _PAGE_RW ? 'w' : 'r', + pgprot & _PAGE_USER ? 'u' : 's', + pgprot & _PAGE_PWT ? 't' : 'b', + pgprot & _PAGE_PCD ? 'u' : 'c', pgprot & _PAGE_ACCESSED ? 'a' : '-', - pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_PSE ? 'm' : 'k', - pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); + pgprot & _PAGE_DIRTY ? 'd' : '-', + pgprot & _PAGE_PSE ? 'm' : 'k', + pgprot & _PAGE_GLOBAL ? 'g' : 'l'); #endif DRM_PROC_PRINT("\n"); } - if (len > request + offset) return request; + if (len > request + offset) + return request; *eof = 1; return len - offset; } static int drm_vma_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) + int *eof, void *data) { - drm_device_t *dev = (drm_device_t *)data; - int ret; + drm_device_t *dev = (drm_device_t *) data; + int ret; down(&dev->struct_sem); ret = drm__vma_info(buf, start, offset, request, eof, data); @@ -538,5 +548,3 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int request, return ret; } #endif - - diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h index de782ed2f03a..e94297b751b8 100644 --- a/drivers/char/drm/drm_sarea.h +++ b/drivers/char/drm/drm_sarea.h @@ -1,5 +1,5 @@ /** - * \file drm_sarea.h + * \file drm_sarea.h * \brief SAREA definitions * * \author Michel Dänzer @@ -38,7 +38,7 @@ #if defined(__alpha__) #define SAREA_MAX 0x2000 #elif defined(__ia64__) -#define SAREA_MAX 0x10000 /* 64kB */ +#define SAREA_MAX 0x10000 /* 64kB */ #else /* Intel 830M driver needs at least 8k SAREA */ #define SAREA_MAX 0x2000 @@ -51,28 +51,28 @@ /** SAREA drawable */ typedef struct drm_sarea_drawable { - unsigned int stamp; - unsigned int flags; + unsigned int stamp; + unsigned int flags; } drm_sarea_drawable_t; /** SAREA frame */ typedef struct drm_sarea_frame { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - unsigned int fullscreen; + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + unsigned int fullscreen; } drm_sarea_frame_t; /** SAREA */ typedef struct drm_sarea { /** first thing is always the DRM locking structure */ - drm_hw_lock_t lock; + drm_hw_lock_t lock; /** \todo Use readers/writer lock for drm_sarea::drawable_lock */ - drm_hw_lock_t drawable_lock; - drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ - drm_sarea_frame_t frame; /**< frame */ - drm_context_t dummy_context; + drm_hw_lock_t drawable_lock; + drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ + drm_sarea_frame_t frame; /**< frame */ + drm_context_t dummy_context; } drm_sarea_t; -#endif /* _DRM_SAREA_H_ */ +#endif /* _DRM_SAREA_H_ */ diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c index ed267d49bc6a..ce81bf248200 100644 --- a/drivers/char/drm/drm_scatter.c +++ b/drivers/char/drm/drm_scatter.c @@ -1,5 +1,5 @@ /** - * \file drm_scatter.h + * \file drm_scatter.c * IOCTLs to manage scatter/gather memory * * \author Gareth Hughes @@ -37,28 +37,24 @@ #define DEBUG_SCATTER 0 -void drm_sg_cleanup( drm_sg_mem_t *entry ) +void drm_sg_cleanup(drm_sg_mem_t * entry) { struct page *page; int i; - for ( i = 0 ; i < entry->pages ; i++ ) { + for (i = 0; i < entry->pages; i++) { page = entry->pagelist[i]; - if ( page ) - ClearPageReserved( page ); + if (page) + ClearPageReserved(page); } - vfree( entry->virtual ); + vfree(entry->virtual); - drm_free( entry->busaddr, - entry->pages * sizeof(*entry->busaddr), - DRM_MEM_PAGES ); - drm_free( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - drm_free( entry, - sizeof(*entry), - DRM_MEM_SGLISTS ); + drm_free(entry->busaddr, + entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); + drm_free(entry->pagelist, + entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES); + drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); } #ifdef _LP64 @@ -67,8 +63,8 @@ void drm_sg_cleanup( drm_sg_mem_t *entry ) # define ScatterHandle(x) (unsigned int)(x) #endif -int drm_sg_alloc( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_sg_alloc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -77,75 +73,70 @@ int drm_sg_alloc( struct inode *inode, struct file *filp, drm_sg_mem_t *entry; unsigned long pages, i, j; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL; - if ( dev->sg ) + if (dev->sg) return -EINVAL; - if ( copy_from_user( &request, argp, sizeof(request) ) ) + if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; - entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS ); - if ( !entry ) + entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); + if (!entry) return -ENOMEM; - memset( entry, 0, sizeof(*entry) ); + memset(entry, 0, sizeof(*entry)); pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages ); + DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages); entry->pages = pages; - entry->pagelist = drm_alloc( pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - if ( !entry->pagelist ) { - drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS ); + entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), + DRM_MEM_PAGES); + if (!entry->pagelist) { + drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); return -ENOMEM; } memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); - entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr), - DRM_MEM_PAGES ); - if ( !entry->busaddr ) { - drm_free( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - drm_free( entry, - sizeof(*entry), - DRM_MEM_SGLISTS ); + entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr), + DRM_MEM_PAGES); + if (!entry->busaddr) { + drm_free(entry->pagelist, + entry->pages * sizeof(*entry->pagelist), + DRM_MEM_PAGES); + drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); return -ENOMEM; } - memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) ); + memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); - entry->virtual = vmalloc_32( pages << PAGE_SHIFT ); - if ( !entry->virtual ) { - drm_free( entry->busaddr, - entry->pages * sizeof(*entry->busaddr), - DRM_MEM_PAGES ); - drm_free( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - drm_free( entry, - sizeof(*entry), - DRM_MEM_SGLISTS ); + entry->virtual = vmalloc_32(pages << PAGE_SHIFT); + if (!entry->virtual) { + drm_free(entry->busaddr, + entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); + drm_free(entry->pagelist, + entry->pages * sizeof(*entry->pagelist), + DRM_MEM_PAGES); + drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); return -ENOMEM; } /* This also forces the mapping of COW pages, so our page list * will be valid. Please don't remove it... */ - memset( entry->virtual, 0, pages << PAGE_SHIFT ); + memset(entry->virtual, 0, pages << PAGE_SHIFT); entry->handle = ScatterHandle((unsigned long)entry->virtual); - DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); - DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); + DRM_DEBUG("sg alloc handle = %08lx\n", entry->handle); + DRM_DEBUG("sg alloc virtual = %p\n", entry->virtual); - for (i = (unsigned long)entry->virtual, j = 0; j < pages; - i += PAGE_SIZE, j++) { + for (i = (unsigned long)entry->virtual, j = 0; j < pages; + i += PAGE_SIZE, j++) { entry->pagelist[j] = vmalloc_to_page((void *)i); if (!entry->pagelist[j]) goto failed; @@ -154,8 +145,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp, request.handle = entry->handle; - if ( copy_to_user( argp, &request, sizeof(request) ) ) { - drm_sg_cleanup( entry ); + if (copy_to_user(argp, &request, sizeof(request))) { + drm_sg_cleanup(entry); return -EFAULT; } @@ -166,50 +157,50 @@ int drm_sg_alloc( struct inode *inode, struct file *filp, * versa. */ { - int error = 0; + int error = 0; - for ( i = 0 ; i < pages ; i++ ) { - unsigned long *tmp; + for (i = 0; i < pages; i++) { + unsigned long *tmp; - tmp = page_address( entry->pagelist[i] ); - for ( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - *tmp = 0xcafebabe; - } - tmp = (unsigned long *)((u8 *)entry->virtual + - (PAGE_SIZE * i)); - for( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - if ( *tmp != 0xcafebabe && error == 0 ) { - error = 1; - DRM_ERROR( "Scatter allocation error, " - "pagelist does not match " - "virtual mapping\n" ); + tmp = page_address(entry->pagelist[i]); + for (j = 0; + j < PAGE_SIZE / sizeof(unsigned long); + j++, tmp++) { + *tmp = 0xcafebabe; + } + tmp = (unsigned long *)((u8 *) entry->virtual + + (PAGE_SIZE * i)); + for (j = 0; + j < PAGE_SIZE / sizeof(unsigned long); + j++, tmp++) { + if (*tmp != 0xcafebabe && error == 0) { + error = 1; + DRM_ERROR("Scatter allocation error, " + "pagelist does not match " + "virtual mapping\n"); + } + } + tmp = page_address(entry->pagelist[i]); + for (j = 0; + j < PAGE_SIZE / sizeof(unsigned long); + j++, tmp++) { + *tmp = 0; } } - tmp = page_address( entry->pagelist[i] ); - for(j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++) { - *tmp = 0; - } - } - if (error == 0) - DRM_ERROR( "Scatter allocation matches pagelist\n" ); + if (error == 0) + DRM_ERROR("Scatter allocation matches pagelist\n"); } #endif return 0; - failed: - drm_sg_cleanup( entry ); + failed: + drm_sg_cleanup(entry); return -ENOMEM; } -int drm_sg_free( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int drm_sg_free(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -219,20 +210,20 @@ int drm_sg_free( struct inode *inode, struct file *filp, if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL; - if ( copy_from_user( &request, - (drm_scatter_gather_t __user *)arg, - sizeof(request) ) ) + if (copy_from_user(&request, + (drm_scatter_gather_t __user *) arg, + sizeof(request))) return -EFAULT; entry = dev->sg; dev->sg = NULL; - if ( !entry || entry->handle != request.handle ) + if (!entry || entry->handle != request.handle) return -EINVAL; - DRM_DEBUG( "sg free virtual = %p\n", entry->virtual ); + DRM_DEBUG("sg free virtual = %p\n", entry->virtual); - drm_sg_cleanup( entry ); + drm_sg_cleanup(entry); return 0; } diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 95a976c96eb8..7cb7234d6288 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c @@ -37,11 +37,11 @@ #include "drm_core.h" unsigned int drm_cards_limit = 16; /* Enough for one machine */ -unsigned int drm_debug = 0; /* 1 to enable debug output */ +unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); -MODULE_AUTHOR( CORE_AUTHOR ); -MODULE_DESCRIPTION( CORE_DESC ); +MODULE_AUTHOR(CORE_AUTHOR); +MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); @@ -53,19 +53,21 @@ drm_head_t **drm_heads; struct drm_sysfs_class *drm_class; struct proc_dir_entry *drm_proc_root; -static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) +static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver) { int retcode; spin_lock_init(&dev->count_lock); - init_timer( &dev->timer ); - sema_init( &dev->struct_sem, 1 ); - sema_init( &dev->ctxlist_sem, 1 ); + init_timer(&dev->timer); + sema_init(&dev->struct_sem, 1); + sema_init(&dev->ctxlist_sem, 1); - dev->pdev = pdev; + dev->pdev = pdev; #ifdef __alpha__ - dev->hose = pdev->sysdata; + dev->hose = pdev->sysdata; dev->pci_domain = dev->hose->bus->number; #else dev->pci_domain = 0; @@ -82,15 +84,15 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct /* the DRM has 6 basic counters */ dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; + dev->types[0] = _DRM_STAT_LOCK; + dev->types[1] = _DRM_STAT_OPENS; + dev->types[2] = _DRM_STAT_CLOSES; + dev->types[3] = _DRM_STAT_IOCTLS; + dev->types[4] = _DRM_STAT_LOCKS; + dev->types[5] = _DRM_STAT_UNLOCKS; dev->driver = driver; - + if (dev->driver->preinit) if ((retcode = dev->driver->preinit(dev, ent->driver_data))) goto error_out_unreg; @@ -98,29 +100,30 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct if (drm_core_has_AGP(dev)) { if (drm_device_is_agp(dev)) dev->agp = drm_agp_init(dev); - if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) + && (dev->agp == NULL)) { + DRM_ERROR("Cannot initialize the agpgart module.\n"); retcode = -EINVAL; goto error_out_unreg; } if (drm_core_has_MTRR(dev)) { if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024, - MTRR_TYPE_WRCOMB, - 1 ); + dev->agp->agp_mtrr = + mtrr_add(dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * + 1024 * 1024, MTRR_TYPE_WRCOMB, 1); } } - retcode = drm_ctxbitmap_init( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + retcode = drm_ctxbitmap_init(dev); + if (retcode) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); goto error_out_unreg; } return 0; - -error_out_unreg: + + error_out_unreg: drm_takedown(dev); return retcode; } @@ -140,7 +143,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) int minor = iminor(inode); int err = -ENODEV; struct file_operations *old_fops; - + DRM_DEBUG("\n"); if (!((minor >= 0) && (minor < drm_cards_limit))) @@ -148,7 +151,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) if (!drm_heads[minor]) return -ENODEV; - + if (!(dev = drm_heads[minor]->dev)) return -ENODEV; @@ -174,7 +177,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(drm_device_t *dev, drm_head_t *head) +static int drm_get_head(drm_device_t * dev, drm_head_t * head) { drm_head_t **heads = drm_heads; int ret; @@ -184,26 +187,27 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head) for (minor = 0; minor < drm_cards_limit; minor++, heads++) { if (!*heads) { - + *head = (drm_head_t) { - .dev = dev, - .device = MKDEV(DRM_MAJOR, minor), - .minor = minor, - }; - - if ((ret = drm_proc_init(dev, minor, drm_proc_root, &head->dev_root))) { - printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n"); + .dev = dev,.device = + MKDEV(DRM_MAJOR, minor),.minor = minor,}; + + if ((ret = + drm_proc_init(dev, minor, drm_proc_root, + &head->dev_root))) { + printk(KERN_ERR + "DRM: Failed to initialize /proc/dri.\n"); goto err_g1; } - head->dev_class = drm_sysfs_device_add(drm_class, MKDEV(DRM_MAJOR, minor), &dev->pdev->dev, "card%d", minor); if (IS_ERR(head->dev_class)) { - printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); + printk(KERN_ERR + "DRM: Error sysfs_device_add.\n"); ret = PTR_ERR(head->dev_class); goto err_g2; } @@ -215,13 +219,14 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head) } DRM_ERROR("out of minors\n"); return -ENOMEM; -err_g2: + err_g2: drm_proc_cleanup(minor, drm_proc_root, head->dev_root); -err_g1: - *head = (drm_head_t) {.dev = NULL}; + err_g1: + *head = (drm_head_t) { + .dev = NULL}; return ret; } - + /** * Register. * @@ -234,7 +239,7 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head) * Try and register, if we fail to register, backout previous work. */ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) + struct drm_driver *driver) { drm_device_t *dev; int ret; @@ -261,10 +266,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, return 0; -err_g1: + err_g1: drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } + EXPORT_SYMBOL(drm_get_dev); /** @@ -305,19 +311,19 @@ int drm_put_dev(drm_device_t * dev) * last minor released. * */ -int drm_put_head(drm_head_t *head) +int drm_put_head(drm_head_t * head) { int minor = head->minor; - + DRM_DEBUG("release secondary minor %d\n", minor); - + drm_proc_cleanup(minor, drm_proc_root, head->dev_root); drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); - - *head = (drm_head_t){.dev = NULL}; + + *head = (drm_head_t) { + .dev = NULL}; drm_heads[minor] = NULL; - + return 0; } - diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index a13d07f44202..e84a7876a1b3 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c @@ -1,7 +1,7 @@ /** - * \file drm_vm.h + * \file drm_vm.c * Memory mapping for DRM - * + * * \author Rickard E. (Rik) Faith * \author Gareth Hughes */ @@ -47,32 +47,34 @@ static void drm_vm_close(struct vm_area_struct *vma); * \param vma virtual memory area. * \param address access address. * \return pointer to the page structure. - * + * * Find the right map and if it's AGP memory find the real physical page to * map, get the page, increment the use count and return it. */ #if __OS_HAS_AGP static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, - unsigned long address) + unsigned long address) { - drm_file_t *priv = vma->vm_file->private_data; + drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->head->dev; - drm_map_t *map = NULL; - drm_map_list_t *r_list; + drm_map_t *map = NULL; + drm_map_list_t *r_list; struct list_head *list; /* - * Find the right map - */ + * Find the right map + */ if (!drm_core_has_AGP(dev)) goto vm_nopage_error; - if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; + if (!dev->agp || !dev->agp->cant_use_aperture) + goto vm_nopage_error; list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; - if (!map) continue; + if (!map) + continue; if (r_list->user_token == VM_OFFSET(vma)) break; } @@ -85,45 +87,47 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, #ifdef __alpha__ /* - * Adjust to a bus-relative address - */ + * Adjust to a bus-relative address + */ baddr -= dev->hose->mem_space->start; #endif /* - * It's AGP memory - find the real physical page to map - */ - for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { + * It's AGP memory - find the real physical page to map + */ + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { if (agpmem->bound <= baddr && - agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) + agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) break; } - if (!agpmem) goto vm_nopage_error; + if (!agpmem) + goto vm_nopage_error; /* - * Get the page, inc the use count, and return it - */ + * Get the page, inc the use count, and return it + */ offset = (baddr - agpmem->bound) >> PAGE_SHIFT; page = virt_to_page(__va(agpmem->memory->memory[offset])); get_page(page); - DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", - baddr, __va(agpmem->memory->memory[offset]), offset, - page_count(page)); + DRM_DEBUG + ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", + baddr, __va(agpmem->memory->memory[offset]), offset, + page_count(page)); return page; - } -vm_nopage_error: - return NOPAGE_SIGBUS; /* Disallow mremap */ + } + vm_nopage_error: + return NOPAGE_SIGBUS; /* Disallow mremap */ } -#else /* __OS_HAS_AGP */ +#else /* __OS_HAS_AGP */ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, - unsigned long address) + unsigned long address) { return NOPAGE_SIGBUS; } -#endif /* __OS_HAS_AGP */ +#endif /* __OS_HAS_AGP */ /** * \c nopage method for shared virtual memory. @@ -131,25 +135,27 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, * \param vma virtual memory area. * \param address access address. * \return pointer to the page structure. - * + * * Get the the mapping, find the real physical page to map, get the page, and * return it. */ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address) + unsigned long address) { - drm_map_t *map = (drm_map_t *)vma->vm_private_data; - unsigned long offset; - unsigned long i; - struct page *page; + drm_map_t *map = (drm_map_t *) vma->vm_private_data; + unsigned long offset; + unsigned long i; + struct page *page; - if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ - if (!map) return NOPAGE_OOM; /* Nothing allocated */ + if (address > vma->vm_end) + return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!map) + return NOPAGE_OOM; /* Nothing allocated */ - offset = address - vma->vm_start; + offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; - page = (map->type == _DRM_CONSISTENT) ? - virt_to_page((void *)i) : vmalloc_to_page((void *)i); + page = (map->type == _DRM_CONSISTENT) ? + virt_to_page((void *)i) : vmalloc_to_page((void *)i); if (!page) return NOPAGE_OOM; get_page(page); @@ -158,19 +164,18 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, return page; } - /** * \c close method for shared virtual memory. - * + * * \param vma virtual memory area. - * + * * Deletes map information if we are the last * person to close a mapping and it's not in the global maplist. */ static void drm_vm_shm_close(struct vm_area_struct *vma) { - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = vma->vm_file->private_data; + drm_device_t *dev = priv->head->dev; drm_vma_entry_t *pt, *prev, *next; drm_map_t *map; drm_map_list_t *r_list; @@ -186,7 +191,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) down(&dev->struct_sem); for (pt = dev->vmalist, prev = NULL; pt; pt = next) { next = pt->next; - if (pt->vma->vm_private_data == map) found_maps++; + if (pt->vma->vm_private_data == map) + found_maps++; if (pt->vma == vma) { if (prev) { prev->next = pt->next; @@ -199,8 +205,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) } } /* We were the only map that was found */ - if(found_maps == 1 && - map->flags & _DRM_REMOVABLE) { + if (found_maps == 1 && map->flags & _DRM_REMOVABLE) { /* Check to see if we are in the maplist, if we are not, then * we delete this mappings information. */ @@ -208,10 +213,11 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) list = &dev->maplist->head; list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); - if (r_list->map == map) found_maps++; + if (r_list->map == map) + found_maps++; } - if(!found_maps) { + if (!found_maps) { drm_dma_handle_t dmah; switch (map->type) { @@ -251,27 +257,29 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) * \param vma virtual memory area. * \param address access address. * \return pointer to the page structure. - * + * * Determine the page number from the page offset and get it from drm_device_dma::pagelist. */ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address) + unsigned long address) { - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->head->dev; - drm_device_dma_t *dma = dev->dma; - unsigned long offset; - unsigned long page_nr; - struct page *page; + drm_file_t *priv = vma->vm_file->private_data; + drm_device_t *dev = priv->head->dev; + drm_device_dma_t *dma = dev->dma; + unsigned long offset; + unsigned long page_nr; + struct page *page; - if (!dma) return NOPAGE_SIGBUS; /* Error */ - if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ - if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */ + if (!dma) + return NOPAGE_SIGBUS; /* Error */ + if (address > vma->vm_end) + return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!dma->pagelist) + return NOPAGE_OOM; /* Nothing allocated */ - offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ - page_nr = offset >> PAGE_SHIFT; - page = virt_to_page((dma->pagelist[page_nr] + - (offset & (~PAGE_MASK)))); + offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ + page_nr = offset >> PAGE_SHIFT; + page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); get_page(page); @@ -285,13 +293,13 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, * \param vma virtual memory area. * \param address access address. * \return pointer to the page structure. - * + * * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. */ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address) + unsigned long address) { - drm_map_t *map = (drm_map_t *)vma->vm_private_data; + drm_map_t *map = (drm_map_t *) vma->vm_private_data; drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->head->dev; drm_sg_mem_t *entry = dev->sg; @@ -300,10 +308,12 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, unsigned long page_offset; struct page *page; - if (!entry) return NOPAGE_SIGBUS; /* Error */ - if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ - if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */ - + if (!entry) + return NOPAGE_SIGBUS; /* Error */ + if (address > vma->vm_end) + return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!entry->pagelist) + return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; map_offset = map->offset - (unsigned long)dev->sg->virtual; @@ -314,76 +324,78 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, return page; } - static struct page *drm_vm_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) { - if (type) *type = VM_FAULT_MINOR; + unsigned long address, int *type) +{ + if (type) + *type = VM_FAULT_MINOR; return drm_do_vm_nopage(vma, address); } static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) { - if (type) *type = VM_FAULT_MINOR; + unsigned long address, int *type) +{ + if (type) + *type = VM_FAULT_MINOR; return drm_do_vm_shm_nopage(vma, address); } static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) { - if (type) *type = VM_FAULT_MINOR; + unsigned long address, int *type) +{ + if (type) + *type = VM_FAULT_MINOR; return drm_do_vm_dma_nopage(vma, address); } static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) { - if (type) *type = VM_FAULT_MINOR; + unsigned long address, int *type) +{ + if (type) + *type = VM_FAULT_MINOR; return drm_do_vm_sg_nopage(vma, address); } /** AGP virtual memory operations */ -static struct vm_operations_struct drm_vm_ops = { +static struct vm_operations_struct drm_vm_ops = { .nopage = drm_vm_nopage, - .open = drm_vm_open, - .close = drm_vm_close, + .open = drm_vm_open, + .close = drm_vm_close, }; /** Shared virtual memory operations */ -static struct vm_operations_struct drm_vm_shm_ops = { +static struct vm_operations_struct drm_vm_shm_ops = { .nopage = drm_vm_shm_nopage, - .open = drm_vm_open, - .close = drm_vm_shm_close, + .open = drm_vm_open, + .close = drm_vm_shm_close, }; /** DMA virtual memory operations */ -static struct vm_operations_struct drm_vm_dma_ops = { +static struct vm_operations_struct drm_vm_dma_ops = { .nopage = drm_vm_dma_nopage, - .open = drm_vm_open, - .close = drm_vm_close, + .open = drm_vm_open, + .close = drm_vm_close, }; /** Scatter-gather virtual memory operations */ -static struct vm_operations_struct drm_vm_sg_ops = { +static struct vm_operations_struct drm_vm_sg_ops = { .nopage = drm_vm_sg_nopage, - .open = drm_vm_open, - .close = drm_vm_close, + .open = drm_vm_open, + .close = drm_vm_close, }; - /** * \c open method for shared virtual memory. - * + * * \param vma virtual memory area. - * + * * Create a new drm_vma_entry structure as the \p vma private data entry and * add it to drm_device::vmalist. */ static void drm_vm_open(struct vm_area_struct *vma) { - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = vma->vm_file->private_data; + drm_device_t *dev = priv->head->dev; drm_vma_entry_t *vma_entry; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -393,26 +405,26 @@ static void drm_vm_open(struct vm_area_struct *vma) vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); if (vma_entry) { down(&dev->struct_sem); - vma_entry->vma = vma; + vma_entry->vma = vma; vma_entry->next = dev->vmalist; - vma_entry->pid = current->pid; - dev->vmalist = vma_entry; + vma_entry->pid = current->pid; + dev->vmalist = vma_entry; up(&dev->struct_sem); } } /** * \c close method for all virtual memory types. - * + * * \param vma virtual memory area. - * + * * Search the \p vma private data entry in drm_device::vmalist, unlink it, and * free it. */ static void drm_vm_close(struct vm_area_struct *vma) { - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = vma->vm_file->private_data; + drm_device_t *dev = priv->head->dev; drm_vma_entry_t *pt, *prev; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -440,43 +452,44 @@ static void drm_vm_close(struct vm_area_struct *vma) * \param filp file pointer. * \param vma virtual memory area. * \return zero on success or a negative number on failure. - * + * * Sets the virtual memory area operations structure to vm_dma_ops, the file * pointer, and calls vm_open(). */ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; drm_device_dma_t *dma; - unsigned long length = vma->vm_end - vma->vm_start; + unsigned long length = vma->vm_end - vma->vm_start; lock_kernel(); - dev = priv->head->dev; - dma = dev->dma; + dev = priv->head->dev; + dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); - /* Length must match exact page count */ + /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { unlock_kernel(); return -EINVAL; } unlock_kernel(); - vma->vm_ops = &drm_vm_dma_ops; + vma->vm_ops = &drm_vm_dma_ops; - vma->vm_flags |= VM_RESERVED; /* Don't swap */ + vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_file = filp; /* Needed for drm_vm_open() */ + vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); return 0; } -unsigned long drm_core_get_map_ofs(drm_map_t *map) +unsigned long drm_core_get_map_ofs(drm_map_t * map) { return map->offset; } + EXPORT_SYMBOL(drm_core_get_map_ofs); unsigned long drm_core_get_reg_ofs(struct drm_device *dev) @@ -487,6 +500,7 @@ unsigned long drm_core_get_reg_ofs(struct drm_device *dev) return 0; #endif } + EXPORT_SYMBOL(drm_core_get_reg_ofs); /** @@ -495,7 +509,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); * \param filp file pointer. * \param vma virtual memory area. * \return zero on success or a negative number on failure. - * + * * If the virtual memory area has no offset associated with it then it's a DMA * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist, * checks that the restricted flag is not set, sets the virtual memory operations @@ -504,17 +518,18 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); */ int drm_mmap(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_map_t *map = NULL; - drm_map_list_t *r_list; - unsigned long offset = 0; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_map_t *map = NULL; + drm_map_list_t *r_list; + unsigned long offset = 0; struct list_head *list; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); - if ( !priv->authenticated ) return -EACCES; + if (!priv->authenticated) + return -EACCES; /* We check for "dma". On Apple's UniNorth, it's valid to have * the AGP mapped at physical address 0 @@ -522,61 +537,66 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) */ if (!VM_OFFSET(vma) #if __OS_HAS_AGP - && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) + && (!dev->agp + || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) #endif ) return drm_mmap_dma(filp, vma); - /* A sequential search of a linked list is - fine here because: 1) there will only be - about 5-10 entries in the list and, 2) a - DRI client only has to do this mapping - once, so it doesn't have to be optimized - for performance, even if the list was a - bit longer. */ + /* A sequential search of a linked list is + fine here because: 1) there will only be + about 5-10 entries in the list and, 2) a + DRI client only has to do this mapping + once, so it doesn't have to be optimized + for performance, even if the list was a + bit longer. */ list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; - if (!map) continue; + if (!map) + continue; if (r_list->user_token == VM_OFFSET(vma)) break; } - if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) + if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; - /* Check for valid size. */ - if (map->size != vma->vm_end - vma->vm_start) return -EINVAL; + /* Check for valid size. */ + if (map->size != vma->vm_end - vma->vm_start) + return -EINVAL; if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); #if defined(__i386__) || defined(__x86_64__) pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; #else - /* Ye gads this is ugly. With more thought - we could move this up higher and use - `protection_map' instead. */ - vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect( - __pte(pgprot_val(vma->vm_page_prot))))); + /* Ye gads this is ugly. With more thought + we could move this up higher and use + `protection_map' instead. */ + vma->vm_page_prot = + __pgprot(pte_val + (pte_wrprotect + (__pte(pgprot_val(vma->vm_page_prot))))); #endif } switch (map->type) { - case _DRM_AGP: - if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { - /* - * On some platforms we can't talk to bus dma address from the CPU, so for - * memory of type DRM_AGP, we'll deal with sorting out the real physical - * pages and mappings in nopage() - */ + case _DRM_AGP: + if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { + /* + * On some platforms we can't talk to bus dma address from the CPU, so for + * memory of type DRM_AGP, we'll deal with sorting out the real physical + * pages and mappings in nopage() + */ #if defined(__powerpc__) - pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; #endif - vma->vm_ops = &drm_vm_ops; - break; - } - /* fall through to _DRM_FRAME_BUFFER... */ + vma->vm_ops = &drm_vm_ops; + break; + } + /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: #if defined(__i386__) || defined(__x86_64__) @@ -591,27 +611,25 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) #endif vma->vm_flags |= VM_IO; /* not in core dump */ #if defined(__ia64__) - if (efi_range_is_wc(vma->vm_start, vma->vm_end - - vma->vm_start)) + if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) vma->vm_page_prot = - pgprot_writecombine(vma->vm_page_prot); + pgprot_writecombine(vma->vm_page_prot); else - vma->vm_page_prot = - pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif offset = dev->driver->get_reg_ofs(dev); #ifdef __sparc__ if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) + (map->offset + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) #else if (io_remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) + (map->offset + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) #endif - return -EAGAIN; + return -EAGAIN; DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," " offset = 0x%lx\n", map->type, @@ -624,22 +642,23 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) * allocate in a different way */ vma->vm_ops = &drm_vm_shm_ops; vma->vm_private_data = (void *)map; - /* Don't let this area swap. Change when - DRM_KERNEL advisory is supported. */ + /* Don't let this area swap. Change when + DRM_KERNEL advisory is supported. */ vma->vm_flags |= VM_RESERVED; break; case _DRM_SCATTER_GATHER: vma->vm_ops = &drm_vm_sg_ops; vma->vm_private_data = (void *)map; vma->vm_flags |= VM_RESERVED; - break; + break; default: return -EINVAL; /* This should never happen. */ } - vma->vm_flags |= VM_RESERVED; /* Don't swap */ + vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_file = filp; /* Needed for drm_vm_open() */ + vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); return 0; } + EXPORT_SYMBOL(drm_mmap); diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c index f51812078010..8a6cc2751bc9 100644 --- a/drivers/char/drm/ffb_context.c +++ b/drivers/char/drm/ffb_context.c @@ -15,8 +15,7 @@ #include "ffb_drv.h" -static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only) -{ +static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) { ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; int i; @@ -37,7 +36,7 @@ static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only) return i + 1; } -static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) +static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx) { ffb_fbcPtr ffb = fpriv->regs; struct ffb_hw_context *ctx; @@ -94,36 +93,36 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) /* Capture rendering attributes. */ - ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */ - ctx->wid = upa_readl(&ffb->wid); /* Current WID */ - ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */ - ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */ - ctx->consty = upa_readl(&ffb->consty); /* Constant Y */ - ctx->constz = upa_readl(&ffb->constz); /* Constant Z */ - ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */ - ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */ + ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */ + ctx->wid = upa_readl(&ffb->wid); /* Current WID */ + ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */ + ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */ + ctx->consty = upa_readl(&ffb->consty); /* Constant Y */ + ctx->constz = upa_readl(&ffb->constz); /* Constant Z */ + ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */ + ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */ ctx->vclipmin = upa_readl(&ffb->vclipmin); /* Primary XY clip, minimum */ ctx->vclipmax = upa_readl(&ffb->vclipmax); /* Primary XY clip, maximum */ ctx->vclipzmin = upa_readl(&ffb->vclipzmin); /* Primary Z clip, minimum */ ctx->vclipzmax = upa_readl(&ffb->vclipzmax); /* Primary Z clip, maximum */ - ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */ - ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */ - ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */ - ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */ - ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */ + ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */ + ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */ + ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */ + ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */ + ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */ ctx->blendc1 = upa_readl(&ffb->blendc1); /* Alpha Blend Color 1 */ ctx->blendc2 = upa_readl(&ffb->blendc2); /* Alpha Blend Color 2 */ - ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */ - ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */ - ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */ + ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */ + ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */ + ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */ ctx->matchab = upa_readl(&ffb->matchab); /* Buffer A/B Match Ops */ - ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */ - ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */ - ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */ - ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */ - ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */ - ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */ - ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */ + ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */ + ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */ + ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */ + ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */ + ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */ + ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */ + ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */ /* Auxiliary Clips. */ ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min); @@ -135,9 +134,9 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min); ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max); - ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */ - ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */ - ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */ + ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */ + ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */ + ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */ ctx->fontinc = upa_readl(&ffb->fontinc); /* Font X/Y Increment */ /* These registers/features only exist on FFB2 and later chips. */ @@ -145,12 +144,12 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) ctx->dcss1 = upa_readl(&ffb->dcss1); /* Depth Cue Scale Slope 1 */ ctx->dcss2 = upa_readl(&ffb->dcss2); /* Depth Cue Scale Slope 2 */ ctx->dcss2 = upa_readl(&ffb->dcss3); /* Depth Cue Scale Slope 3 */ - ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */ - ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */ - ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */ - ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */ - ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */ - ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */ + ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */ + ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */ + ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */ + ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */ + ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */ + ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */ /* And stencil/stencilctl only exists on FFB2+ and later * due to the introduction of 3DRAM-III. @@ -170,7 +169,7 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) ctx->ucsr = upa_readl(&ffb->ucsr); } -static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx) +static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx) { ffb_fbcPtr ffb = fpriv->regs; struct ffb_hw_context *ctx; @@ -193,7 +192,7 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx) upa_writel(ctx->ppc, &ffb->ppc); upa_writel(ctx->wid, &ffb->wid); - upa_writel(ctx->fg, &ffb->fg); + upa_writel(ctx->fg, &ffb->fg); upa_writel(ctx->bg, &ffb->bg); upa_writel(ctx->xclip, &ffb->xclip); upa_writel(ctx->fbc, &ffb->fbc); @@ -237,36 +236,36 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx) /* Restore rendering attributes. */ - upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */ - upa_writel(ctx->wid, &ffb->wid); /* Current WID */ - upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */ - upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */ - upa_writel(ctx->consty, &ffb->consty); /* Constant Y */ - upa_writel(ctx->constz, &ffb->constz); /* Constant Z */ - upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */ - upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */ + upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */ + upa_writel(ctx->wid, &ffb->wid); /* Current WID */ + upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */ + upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */ + upa_writel(ctx->consty, &ffb->consty); /* Constant Y */ + upa_writel(ctx->constz, &ffb->constz); /* Constant Z */ + upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */ + upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */ upa_writel(ctx->vclipmin, &ffb->vclipmin); /* Primary XY clip, minimum */ upa_writel(ctx->vclipmax, &ffb->vclipmax); /* Primary XY clip, maximum */ upa_writel(ctx->vclipzmin, &ffb->vclipzmin); /* Primary Z clip, minimum */ upa_writel(ctx->vclipzmax, &ffb->vclipzmax); /* Primary Z clip, maximum */ - upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */ - upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */ - upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */ - upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */ - upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */ + upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */ + upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */ + upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */ + upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */ + upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */ upa_writel(ctx->blendc1, &ffb->blendc1); /* Alpha Blend Color 1 */ upa_writel(ctx->blendc2, &ffb->blendc2); /* Alpha Blend Color 2 */ - upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */ - upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */ - upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */ + upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */ + upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */ + upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */ upa_writel(ctx->matchab, &ffb->matchab); /* Buffer A/B Match Ops */ - upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */ - upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */ - upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */ - upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */ - upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */ - upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */ - upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */ + upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */ + upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */ + upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */ + upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */ + upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */ + upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */ + upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */ /* Auxiliary Clips. */ upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min); @@ -278,9 +277,9 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx) upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min); upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max); - upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */ - upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */ - upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */ + upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */ + upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */ + upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */ upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */ /* These registers/features only exist on FFB2 and later chips. */ @@ -354,91 +353,87 @@ static void FFBWait(ffb_fbcPtr ffb) } while (--limit); } -int ffb_driver_context_switch(drm_device_t *dev, int old, int new) +int ffb_driver_context_switch(drm_device_t * dev, int old, int new) { ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; #ifdef DRM_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); + dev->ctx_start = get_cycles(); #endif - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - if (new == dev->last_context || - dev->last_context == 0) { + DRM_DEBUG("Context switch from %d to %d\n", old, new); + + if (new == dev->last_context || dev->last_context == 0) { dev->last_context = new; - return 0; + return 0; } - + FFBWait(fpriv->regs); ffb_save_context(fpriv, old); ffb_restore_context(fpriv, old, new); FFBWait(fpriv->regs); - + dev->last_context = new; - return 0; + return 0; } int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; + drm_ctx_res_t res; + drm_ctx_t ctx; + int i; DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res))) + if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res))) return -EFAULT; if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) + if (copy_to_user(&res.contexts[i], &i, sizeof(i))) return -EFAULT; } } res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res))) + if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res))) return -EFAULT; return 0; } - int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; int idx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; - idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY)); + idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY)); if (idx < 0) return -ENFILE; DRM_DEBUG("%d\n", ctx.handle); ctx.handle = idx; - if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx))) + if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx))) return -EFAULT; return 0; } int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; struct ffb_hw_context *hwctx; drm_ctx_t ctx; int idx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; idx = ctx.handle; @@ -458,16 +453,16 @@ int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd, } int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; struct ffb_hw_context *hwctx; drm_ctx_t ctx; int idx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; idx = ctx.handle; @@ -483,31 +478,31 @@ int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd, else ctx.flags = 0; - if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx))) + if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx))) return -EFAULT; return 0; } -int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int ffb_driver_switchctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); return ffb_driver_context_switch(dev, dev->last_context, ctx.handle); } int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_ctx_t ctx; + drm_ctx_t ctx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); @@ -515,15 +510,15 @@ int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd, } int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_ctx_t ctx; - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; + drm_ctx_t ctx; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; int idx; - if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) + if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx))) return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); @@ -544,7 +539,8 @@ void ffb_set_context_ioctls(void) DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx; - DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx; + DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = + ffb_driver_switchctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx; DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx; diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c index 1bd0d55ee0f0..5c121d6df9f2 100644 --- a/drivers/char/drm/ffb_drv.c +++ b/drivers/char/drm/ffb_drv.c @@ -33,13 +33,13 @@ typedef struct _ffb_position_t { static ffb_position_t *ffb_position; -static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance) +static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance) { volatile unsigned char *strap_bits; unsigned char val; strap_bits = (volatile unsigned char *) - (ffb_priv->card_phys_base + 0x00200000UL); + (ffb_priv->card_phys_base + 0x00200000UL); /* Don't ask, you have to read the value twice for whatever * reason to get correct contents. @@ -61,7 +61,8 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance) break; case (0x1 << 5) | (0x0 << 3): ffb_priv->ffb_type = ffb2_prototype; - printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", instance); + printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", + instance); break; case (0x1 << 5) | (0x1 << 3): ffb_priv->ffb_type = ffb2_vertical; @@ -81,12 +82,13 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance) break; default: ffb_priv->ffb_type = ffb2_vertical; - printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", instance, val); + printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", + instance, val); break; }; } -static void ffb_apply_upa_parent_ranges(int parent, +static void ffb_apply_upa_parent_ranges(int parent, struct linux_prom64_registers *regs) { struct linux_prom64_ranges ranges[PROMREG_MAX]; @@ -97,7 +99,8 @@ static void ffb_apply_upa_parent_ranges(int parent, if (strcmp(name, "upa") != 0) return; - len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges)); + len = + prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges)); if (len <= 0) return; @@ -117,11 +120,11 @@ static void ffb_apply_upa_parent_ranges(int parent, return; } -static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node, +static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node, int instance) { - struct linux_prom64_registers regs[2*PROMREG_MAX]; - ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private; + struct linux_prom64_registers regs[2 * PROMREG_MAX]; + ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private; int i; ffb_priv->prom_node = prom_node; @@ -132,27 +135,27 @@ static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node, ffb_apply_upa_parent_ranges(parent_node, ®s[0]); ffb_priv->card_phys_base = regs[0].phys_addr; ffb_priv->regs = (ffb_fbcPtr) - (regs[0].phys_addr + 0x00600000UL); + (regs[0].phys_addr + 0x00600000UL); get_ffb_type(ffb_priv, instance); for (i = 0; i < FFB_MAX_CTXS; i++) ffb_priv->hw_state[i] = NULL; - + return 0; } static drm_map_t *ffb_find_map(struct file *filp, unsigned long off) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev; - drm_map_list_t *r_list; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_map_list_t *r_list; struct list_head *list; - drm_map_t *map; + drm_map_t *map; if (!priv || (dev = priv->dev) == NULL) return NULL; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = (drm_map_list_t *) list; map = r_list->map; if (!map) continue; @@ -166,8 +169,7 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off) unsigned long ffb_get_unmapped_area(struct file *filp, unsigned long hint, unsigned long len, - unsigned long pgoff, - unsigned long flags) + unsigned long pgoff, unsigned long flags) { drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT); unsigned long addr = -ENOMEM; @@ -175,8 +177,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp, if (!map) return get_unmapped_area(NULL, hint, len, pgoff, flags); - if (map->type == _DRM_FRAME_BUFFER || - map->type == _DRM_REGISTERS) { + if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) { #ifdef HAVE_ARCH_FB_UNMAPPED_AREA addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags); #else @@ -187,7 +188,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp, addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags); if (!(addr & ~PAGE_MASK)) { - unsigned long kvirt = (unsigned long) map->handle; + unsigned long kvirt = (unsigned long)map->handle; if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { unsigned long koff, aoff; @@ -207,9 +208,9 @@ unsigned long ffb_get_unmapped_area(struct file *filp, return addr; } -static int ffb_presetup(drm_device_t *dev) +static int ffb_presetup(drm_device_t * dev) { - ffb_dev_priv_t *ffb_priv; + ffb_dev_priv_t *ffb_priv; int ret = 0; int i = 0; @@ -224,14 +225,11 @@ static int ffb_presetup(drm_device_t *dev) memset(ffb_priv, 0, sizeof(*ffb_priv)); dev->dev_private = ffb_priv; - ret = ffb_init_one(dev, - ffb_position[i].node, - ffb_position[i].root, - i); + ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i); return ret; } -static void ffb_driver_release(drm_device_t *dev, struct file *filp) +static void ffb_driver_release(drm_device_t * dev, struct file *filp) { ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock); @@ -239,84 +237,82 @@ static void ffb_driver_release(drm_device_t *dev, struct file *filp) idx = context - 1; if (fpriv && - context != DRM_KERNEL_CONTEXT && - fpriv->hw_state[idx] != NULL) { + context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) { kfree(fpriv->hw_state[idx]); fpriv->hw_state[idx] = NULL; - } + } } -static void ffb_driver_pretakedown(drm_device_t *dev) +static void ffb_driver_pretakedown(drm_device_t * dev) { - if (dev->dev_private) kfree(dev->dev_private); + if (dev->dev_private) + kfree(dev->dev_private); } -static int ffb_driver_postcleanup(drm_device_t *dev) +static int ffb_driver_postcleanup(drm_device_t * dev) { - if (ffb_position != NULL) kfree(ffb_position); + if (ffb_position != NULL) + kfree(ffb_position); return 0; } -static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, drm_lock_t *lock) +static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, + drm_lock_t * lock) { dev->lock.filp = 0; { __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; unsigned int old, new, prev, ctx; - + ctx = lock->context; do { - old = *plock; - new = ctx; + old = *plock; + new = ctx; prev = cmpxchg(plock, old, new); } while (prev != old); } wake_up_interruptible(&dev->lock.lock_queue); } -static unsigned long ffb_driver_get_map_ofs(drm_map_t *map) +static unsigned long ffb_driver_get_map_ofs(drm_map_t * map) { return (map->offset & 0xffffffff); } -static unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev) +static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev) { - ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private; - - if (ffb_priv) - return ffb_priv->card_phys_base; - - return 0; -} + ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private; + + if (ffb_priv) + return ffb_priv->card_phys_base; -static int postinit( struct drm_device *dev, unsigned long flags ) -{ - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->minor - ); return 0; } -static int version( drm_version_t *version ) +static int postinit(struct drm_device *dev, unsigned long flags) +{ + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor); + return 0; +} + +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } static drm_ioctl_desc_t ioctls[] = { - + }; static struct drm_driver driver = { @@ -335,14 +331,15 @@ static struct drm_driver driver = { .ioctls = ioctls, .num_ioctls = DRM_ARRAY_SIZE(ioctls), .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + } + , }; static int __init ffb_init(void) @@ -357,6 +354,6 @@ static void __exit ffb_exit(void) module_init(ffb_init); module_exit(ffb_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h index 8bf7f1e143f1..582afa6dd2b4 100644 --- a/drivers/char/drm/ffb_drv.h +++ b/drivers/char/drm/ffb_drv.h @@ -5,7 +5,7 @@ */ /* Auxilliary clips. */ -typedef struct { +typedef struct { volatile unsigned int min; volatile unsigned int max; } ffb_auxclip, *ffb_auxclipPtr; @@ -15,172 +15,265 @@ typedef struct _ffb_fbc { /* Next vertex registers, on the right we list which drawops * use said register and the logical name the register has in * that context. - */ /* DESCRIPTION DRAWOP(NAME) */ -/*0x00*/unsigned int pad1[3]; /* Reserved */ -/*0x0c*/volatile unsigned int alpha; /* ALPHA Transparency */ -/*0x10*/volatile unsigned int red; /* RED */ -/*0x14*/volatile unsigned int green; /* GREEN */ -/*0x18*/volatile unsigned int blue; /* BLUE */ -/*0x1c*/volatile unsigned int z; /* DEPTH */ -/*0x20*/volatile unsigned int y; /* Y triangle(DOYF) */ - /* aadot(DYF) */ - /* ddline(DYF) */ - /* aaline(DYF) */ -/*0x24*/volatile unsigned int x; /* X triangle(DOXF) */ - /* aadot(DXF) */ - /* ddline(DXF) */ - /* aaline(DXF) */ -/*0x28*/unsigned int pad2[2]; /* Reserved */ -/*0x30*/volatile unsigned int ryf; /* Y (alias to DOYF) ddline(RYF) */ - /* aaline(RYF) */ - /* triangle(RYF) */ -/*0x34*/volatile unsigned int rxf; /* X ddline(RXF) */ - /* aaline(RXF) */ - /* triangle(RXF) */ -/*0x38*/unsigned int pad3[2]; /* Reserved */ -/*0x40*/volatile unsigned int dmyf; /* Y (alias to DOYF) triangle(DMYF) */ -/*0x44*/volatile unsigned int dmxf; /* X triangle(DMXF) */ -/*0x48*/unsigned int pad4[2]; /* Reserved */ -/*0x50*/volatile unsigned int ebyi; /* Y (alias to RYI) polygon(EBYI) */ -/*0x54*/volatile unsigned int ebxi; /* X polygon(EBXI) */ -/*0x58*/unsigned int pad5[2]; /* Reserved */ -/*0x60*/volatile unsigned int by; /* Y brline(RYI) */ - /* fastfill(OP) */ - /* polygon(YI) */ - /* rectangle(YI) */ - /* bcopy(SRCY) */ - /* vscroll(SRCY) */ -/*0x64*/volatile unsigned int bx; /* X brline(RXI) */ - /* polygon(XI) */ - /* rectangle(XI) */ - /* bcopy(SRCX) */ - /* vscroll(SRCX) */ - /* fastfill(GO) */ -/*0x68*/volatile unsigned int dy; /* destination Y fastfill(DSTY) */ - /* bcopy(DSRY) */ - /* vscroll(DSRY) */ -/*0x6c*/volatile unsigned int dx; /* destination X fastfill(DSTX) */ - /* bcopy(DSTX) */ - /* vscroll(DSTX) */ -/*0x70*/volatile unsigned int bh; /* Y (alias to RYI) brline(DYI) */ - /* dot(DYI) */ - /* polygon(ETYI) */ - /* Height fastfill(H) */ - /* bcopy(H) */ - /* vscroll(H) */ - /* Y count fastfill(NY) */ -/*0x74*/volatile unsigned int bw; /* X dot(DXI) */ - /* brline(DXI) */ - /* polygon(ETXI) */ - /* fastfill(W) */ - /* bcopy(W) */ - /* vscroll(W) */ - /* fastfill(NX) */ -/*0x78*/unsigned int pad6[2]; /* Reserved */ -/*0x80*/unsigned int pad7[32]; /* Reserved */ - - /* Setup Unit's vertex state register */ -/*100*/ volatile unsigned int suvtx; -/*104*/ unsigned int pad8[63]; /* Reserved */ - - /* Frame Buffer Control Registers */ -/*200*/ volatile unsigned int ppc; /* Pixel Processor Control */ -/*204*/ volatile unsigned int wid; /* Current WID */ -/*208*/ volatile unsigned int fg; /* FG data */ -/*20c*/ volatile unsigned int bg; /* BG data */ -/*210*/ volatile unsigned int consty; /* Constant Y */ -/*214*/ volatile unsigned int constz; /* Constant Z */ -/*218*/ volatile unsigned int xclip; /* X Clip */ -/*21c*/ volatile unsigned int dcss; /* Depth Cue Scale Slope */ -/*220*/ volatile unsigned int vclipmin; /* Viewclip XY Min Bounds */ -/*224*/ volatile unsigned int vclipmax; /* Viewclip XY Max Bounds */ -/*228*/ volatile unsigned int vclipzmin; /* Viewclip Z Min Bounds */ -/*22c*/ volatile unsigned int vclipzmax; /* Viewclip Z Max Bounds */ -/*230*/ volatile unsigned int dcsf; /* Depth Cue Scale Front Bound */ -/*234*/ volatile unsigned int dcsb; /* Depth Cue Scale Back Bound */ -/*238*/ volatile unsigned int dczf; /* Depth Cue Z Front */ -/*23c*/ volatile unsigned int dczb; /* Depth Cue Z Back */ -/*240*/ unsigned int pad9; /* Reserved */ -/*244*/ volatile unsigned int blendc; /* Alpha Blend Control */ -/*248*/ volatile unsigned int blendc1; /* Alpha Blend Color 1 */ -/*24c*/ volatile unsigned int blendc2; /* Alpha Blend Color 2 */ -/*250*/ volatile unsigned int fbramitc; /* FB RAM Interleave Test Control */ -/*254*/ volatile unsigned int fbc; /* Frame Buffer Control */ -/*258*/ volatile unsigned int rop; /* Raster OPeration */ -/*25c*/ volatile unsigned int cmp; /* Frame Buffer Compare */ -/*260*/ volatile unsigned int matchab; /* Buffer AB Match Mask */ -/*264*/ volatile unsigned int matchc; /* Buffer C(YZ) Match Mask */ -/*268*/ volatile unsigned int magnab; /* Buffer AB Magnitude Mask */ -/*26c*/ volatile unsigned int magnc; /* Buffer C(YZ) Magnitude Mask */ -/*270*/ volatile unsigned int fbcfg0; /* Frame Buffer Config 0 */ -/*274*/ volatile unsigned int fbcfg1; /* Frame Buffer Config 1 */ -/*278*/ volatile unsigned int fbcfg2; /* Frame Buffer Config 2 */ -/*27c*/ volatile unsigned int fbcfg3; /* Frame Buffer Config 3 */ -/*280*/ volatile unsigned int ppcfg; /* Pixel Processor Config */ -/*284*/ volatile unsigned int pick; /* Picking Control */ -/*288*/ volatile unsigned int fillmode; /* FillMode */ -/*28c*/ volatile unsigned int fbramwac; /* FB RAM Write Address Control */ -/*290*/ volatile unsigned int pmask; /* RGB PlaneMask */ -/*294*/ volatile unsigned int xpmask; /* X PlaneMask */ -/*298*/ volatile unsigned int ypmask; /* Y PlaneMask */ -/*29c*/ volatile unsigned int zpmask; /* Z PlaneMask */ -/*2a0*/ ffb_auxclip auxclip[4]; /* Auxilliary Viewport Clip */ - - /* New 3dRAM III support regs */ -/*2c0*/ volatile unsigned int rawblend2; -/*2c4*/ volatile unsigned int rawpreblend; -/*2c8*/ volatile unsigned int rawstencil; -/*2cc*/ volatile unsigned int rawstencilctl; -/*2d0*/ volatile unsigned int threedram1; -/*2d4*/ volatile unsigned int threedram2; -/*2d8*/ volatile unsigned int passin; -/*2dc*/ volatile unsigned int rawclrdepth; -/*2e0*/ volatile unsigned int rawpmask; -/*2e4*/ volatile unsigned int rawcsrc; -/*2e8*/ volatile unsigned int rawmatch; -/*2ec*/ volatile unsigned int rawmagn; -/*2f0*/ volatile unsigned int rawropblend; -/*2f4*/ volatile unsigned int rawcmp; -/*2f8*/ volatile unsigned int rawwac; -/*2fc*/ volatile unsigned int fbramid; - -/*300*/ volatile unsigned int drawop; /* Draw OPeration */ -/*304*/ unsigned int pad10[2]; /* Reserved */ -/*30c*/ volatile unsigned int lpat; /* Line Pattern control */ -/*310*/ unsigned int pad11; /* Reserved */ -/*314*/ volatile unsigned int fontxy; /* XY Font coordinate */ -/*318*/ volatile unsigned int fontw; /* Font Width */ -/*31c*/ volatile unsigned int fontinc; /* Font Increment */ -/*320*/ volatile unsigned int font; /* Font bits */ -/*324*/ unsigned int pad12[3]; /* Reserved */ -/*330*/ volatile unsigned int blend2; -/*334*/ volatile unsigned int preblend; -/*338*/ volatile unsigned int stencil; -/*33c*/ volatile unsigned int stencilctl; + *//* DESCRIPTION DRAWOP(NAME) */ + /*0x00*/ unsigned int pad1[3]; + /* Reserved */ + /*0x0c*/ volatile unsigned int alpha; + /* ALPHA Transparency */ + /*0x10*/ volatile unsigned int red; + /* RED */ + /*0x14*/ volatile unsigned int green; + /* GREEN */ + /*0x18*/ volatile unsigned int blue; + /* BLUE */ + /*0x1c*/ volatile unsigned int z; + /* DEPTH */ + /*0x20*/ volatile unsigned int y; + /* Y triangle(DOYF) */ + /* aadot(DYF) */ + /* ddline(DYF) */ + /* aaline(DYF) */ + /*0x24*/ volatile unsigned int x; + /* X triangle(DOXF) */ + /* aadot(DXF) */ + /* ddline(DXF) */ + /* aaline(DXF) */ + /*0x28*/ unsigned int pad2[2]; + /* Reserved */ + /*0x30*/ volatile unsigned int ryf; + /* Y (alias to DOYF) ddline(RYF) */ + /* aaline(RYF) */ + /* triangle(RYF) */ + /*0x34*/ volatile unsigned int rxf; + /* X ddline(RXF) */ + /* aaline(RXF) */ + /* triangle(RXF) */ + /*0x38*/ unsigned int pad3[2]; + /* Reserved */ + /*0x40*/ volatile unsigned int dmyf; + /* Y (alias to DOYF) triangle(DMYF) */ + /*0x44*/ volatile unsigned int dmxf; + /* X triangle(DMXF) */ + /*0x48*/ unsigned int pad4[2]; + /* Reserved */ + /*0x50*/ volatile unsigned int ebyi; + /* Y (alias to RYI) polygon(EBYI) */ + /*0x54*/ volatile unsigned int ebxi; + /* X polygon(EBXI) */ + /*0x58*/ unsigned int pad5[2]; + /* Reserved */ + /*0x60*/ volatile unsigned int by; + /* Y brline(RYI) */ + /* fastfill(OP) */ + /* polygon(YI) */ + /* rectangle(YI) */ + /* bcopy(SRCY) */ + /* vscroll(SRCY) */ + /*0x64*/ volatile unsigned int bx; + /* X brline(RXI) */ + /* polygon(XI) */ + /* rectangle(XI) */ + /* bcopy(SRCX) */ + /* vscroll(SRCX) */ + /* fastfill(GO) */ + /*0x68*/ volatile unsigned int dy; + /* destination Y fastfill(DSTY) */ + /* bcopy(DSRY) */ + /* vscroll(DSRY) */ + /*0x6c*/ volatile unsigned int dx; + /* destination X fastfill(DSTX) */ + /* bcopy(DSTX) */ + /* vscroll(DSTX) */ + /*0x70*/ volatile unsigned int bh; + /* Y (alias to RYI) brline(DYI) */ + /* dot(DYI) */ + /* polygon(ETYI) */ + /* Height fastfill(H) */ + /* bcopy(H) */ + /* vscroll(H) */ + /* Y count fastfill(NY) */ + /*0x74*/ volatile unsigned int bw; + /* X dot(DXI) */ + /* brline(DXI) */ + /* polygon(ETXI) */ + /* fastfill(W) */ + /* bcopy(W) */ + /* vscroll(W) */ + /* fastfill(NX) */ + /*0x78*/ unsigned int pad6[2]; + /* Reserved */ + /*0x80*/ unsigned int pad7[32]; + /* Reserved */ -/*340*/ unsigned int pad13[4]; /* Reserved */ -/*350*/ volatile unsigned int dcss1; /* Depth Cue Scale Slope 1 */ -/*354*/ volatile unsigned int dcss2; /* Depth Cue Scale Slope 2 */ -/*358*/ volatile unsigned int dcss3; /* Depth Cue Scale Slope 3 */ -/*35c*/ volatile unsigned int widpmask; -/*360*/ volatile unsigned int dcs2; -/*364*/ volatile unsigned int dcs3; -/*368*/ volatile unsigned int dcs4; -/*36c*/ unsigned int pad14; /* Reserved */ -/*370*/ volatile unsigned int dcd2; -/*374*/ volatile unsigned int dcd3; -/*378*/ volatile unsigned int dcd4; -/*37c*/ unsigned int pad15; /* Reserved */ -/*380*/ volatile unsigned int pattern[32]; /* area Pattern */ -/*400*/ unsigned int pad16[8]; /* Reserved */ -/*420*/ volatile unsigned int reset; /* chip RESET */ -/*424*/ unsigned int pad17[247]; /* Reserved */ -/*800*/ volatile unsigned int devid; /* Device ID */ -/*804*/ unsigned int pad18[63]; /* Reserved */ -/*900*/ volatile unsigned int ucsr; /* User Control & Status Register */ -/*904*/ unsigned int pad19[31]; /* Reserved */ -/*980*/ volatile unsigned int mer; /* Mode Enable Register */ -/*984*/ unsigned int pad20[1439]; /* Reserved */ + /* Setup Unit's vertex state register */ +/*100*/ volatile unsigned int suvtx; + /*104*/ unsigned int pad8[63]; + /* Reserved */ + + /* Frame Buffer Control Registers */ + /*200*/ volatile unsigned int ppc; + /* Pixel Processor Control */ + /*204*/ volatile unsigned int wid; + /* Current WID */ + /*208*/ volatile unsigned int fg; + /* FG data */ + /*20c*/ volatile unsigned int bg; + /* BG data */ + /*210*/ volatile unsigned int consty; + /* Constant Y */ + /*214*/ volatile unsigned int constz; + /* Constant Z */ + /*218*/ volatile unsigned int xclip; + /* X Clip */ + /*21c*/ volatile unsigned int dcss; + /* Depth Cue Scale Slope */ + /*220*/ volatile unsigned int vclipmin; + /* Viewclip XY Min Bounds */ + /*224*/ volatile unsigned int vclipmax; + /* Viewclip XY Max Bounds */ + /*228*/ volatile unsigned int vclipzmin; + /* Viewclip Z Min Bounds */ + /*22c*/ volatile unsigned int vclipzmax; + /* Viewclip Z Max Bounds */ + /*230*/ volatile unsigned int dcsf; + /* Depth Cue Scale Front Bound */ + /*234*/ volatile unsigned int dcsb; + /* Depth Cue Scale Back Bound */ + /*238*/ volatile unsigned int dczf; + /* Depth Cue Z Front */ + /*23c*/ volatile unsigned int dczb; + /* Depth Cue Z Back */ + /*240*/ unsigned int pad9; + /* Reserved */ + /*244*/ volatile unsigned int blendc; + /* Alpha Blend Control */ + /*248*/ volatile unsigned int blendc1; + /* Alpha Blend Color 1 */ + /*24c*/ volatile unsigned int blendc2; + /* Alpha Blend Color 2 */ + /*250*/ volatile unsigned int fbramitc; + /* FB RAM Interleave Test Control */ + /*254*/ volatile unsigned int fbc; + /* Frame Buffer Control */ + /*258*/ volatile unsigned int rop; + /* Raster OPeration */ + /*25c*/ volatile unsigned int cmp; + /* Frame Buffer Compare */ + /*260*/ volatile unsigned int matchab; + /* Buffer AB Match Mask */ + /*264*/ volatile unsigned int matchc; + /* Buffer C(YZ) Match Mask */ + /*268*/ volatile unsigned int magnab; + /* Buffer AB Magnitude Mask */ + /*26c*/ volatile unsigned int magnc; + /* Buffer C(YZ) Magnitude Mask */ + /*270*/ volatile unsigned int fbcfg0; + /* Frame Buffer Config 0 */ + /*274*/ volatile unsigned int fbcfg1; + /* Frame Buffer Config 1 */ + /*278*/ volatile unsigned int fbcfg2; + /* Frame Buffer Config 2 */ + /*27c*/ volatile unsigned int fbcfg3; + /* Frame Buffer Config 3 */ + /*280*/ volatile unsigned int ppcfg; + /* Pixel Processor Config */ + /*284*/ volatile unsigned int pick; + /* Picking Control */ + /*288*/ volatile unsigned int fillmode; + /* FillMode */ + /*28c*/ volatile unsigned int fbramwac; + /* FB RAM Write Address Control */ + /*290*/ volatile unsigned int pmask; + /* RGB PlaneMask */ + /*294*/ volatile unsigned int xpmask; + /* X PlaneMask */ + /*298*/ volatile unsigned int ypmask; + /* Y PlaneMask */ + /*29c*/ volatile unsigned int zpmask; + /* Z PlaneMask */ + /*2a0*/ ffb_auxclip auxclip[4]; + /* Auxilliary Viewport Clip */ + + /* New 3dRAM III support regs */ +/*2c0*/ volatile unsigned int rawblend2; +/*2c4*/ volatile unsigned int rawpreblend; +/*2c8*/ volatile unsigned int rawstencil; +/*2cc*/ volatile unsigned int rawstencilctl; +/*2d0*/ volatile unsigned int threedram1; +/*2d4*/ volatile unsigned int threedram2; +/*2d8*/ volatile unsigned int passin; +/*2dc*/ volatile unsigned int rawclrdepth; +/*2e0*/ volatile unsigned int rawpmask; +/*2e4*/ volatile unsigned int rawcsrc; +/*2e8*/ volatile unsigned int rawmatch; +/*2ec*/ volatile unsigned int rawmagn; +/*2f0*/ volatile unsigned int rawropblend; +/*2f4*/ volatile unsigned int rawcmp; +/*2f8*/ volatile unsigned int rawwac; +/*2fc*/ volatile unsigned int fbramid; + + /*300*/ volatile unsigned int drawop; + /* Draw OPeration */ + /*304*/ unsigned int pad10[2]; + /* Reserved */ + /*30c*/ volatile unsigned int lpat; + /* Line Pattern control */ + /*310*/ unsigned int pad11; + /* Reserved */ + /*314*/ volatile unsigned int fontxy; + /* XY Font coordinate */ + /*318*/ volatile unsigned int fontw; + /* Font Width */ + /*31c*/ volatile unsigned int fontinc; + /* Font Increment */ + /*320*/ volatile unsigned int font; + /* Font bits */ + /*324*/ unsigned int pad12[3]; + /* Reserved */ +/*330*/ volatile unsigned int blend2; +/*334*/ volatile unsigned int preblend; +/*338*/ volatile unsigned int stencil; +/*33c*/ volatile unsigned int stencilctl; + + /*340*/ unsigned int pad13[4]; + /* Reserved */ + /*350*/ volatile unsigned int dcss1; + /* Depth Cue Scale Slope 1 */ + /*354*/ volatile unsigned int dcss2; + /* Depth Cue Scale Slope 2 */ + /*358*/ volatile unsigned int dcss3; + /* Depth Cue Scale Slope 3 */ +/*35c*/ volatile unsigned int widpmask; +/*360*/ volatile unsigned int dcs2; +/*364*/ volatile unsigned int dcs3; +/*368*/ volatile unsigned int dcs4; + /*36c*/ unsigned int pad14; + /* Reserved */ +/*370*/ volatile unsigned int dcd2; +/*374*/ volatile unsigned int dcd3; +/*378*/ volatile unsigned int dcd4; + /*37c*/ unsigned int pad15; + /* Reserved */ + /*380*/ volatile unsigned int pattern[32]; + /* area Pattern */ + /*400*/ unsigned int pad16[8]; + /* Reserved */ + /*420*/ volatile unsigned int reset; + /* chip RESET */ + /*424*/ unsigned int pad17[247]; + /* Reserved */ + /*800*/ volatile unsigned int devid; + /* Device ID */ + /*804*/ unsigned int pad18[63]; + /* Reserved */ + /*900*/ volatile unsigned int ucsr; + /* User Control & Status Register */ + /*904*/ unsigned int pad19[31]; + /* Reserved */ + /*980*/ volatile unsigned int mer; + /* Mode Enable Register */ + /*984*/ unsigned int pad20[1439]; + /* Reserved */ } ffb_fbc, *ffb_fbcPtr; struct ffb_hw_context { @@ -263,16 +356,16 @@ enum ffb_chip_type { typedef struct ffb_dev_priv { /* Misc software state. */ - int prom_node; - enum ffb_chip_type ffb_type; - u64 card_phys_base; - struct miscdevice miscdev; + int prom_node; + enum ffb_chip_type ffb_type; + u64 card_phys_base; + struct miscdevice miscdev; /* Controller registers. */ - ffb_fbcPtr regs; + ffb_fbcPtr regs; /* Context table. */ - struct ffb_hw_context *hw_state[FFB_MAX_CTXS]; + struct ffb_hw_context *hw_state[FFB_MAX_CTXS]; } ffb_dev_priv_t; extern unsigned long ffb_get_unmapped_area(struct file *filp, @@ -283,4 +376,4 @@ extern unsigned long ffb_get_unmapped_area(struct file *filp, extern void ffb_set_context_ioctls(void); extern drm_ioctl_desc_t DRM(ioctls)[]; -extern int ffb_driver_context_switch(drm_device_t *dev, int old, int new); +extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new); diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index 2f1659b96fd1..810625093c06 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c @@ -45,102 +45,101 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -static drm_buf_t *i810_freelist_get(drm_device_t *dev) +static drm_buf_t *i810_freelist_get(drm_device_t * dev) { - drm_device_dma_t *dma = dev->dma; - int i; - int used; + drm_device_dma_t *dma = dev->dma; + int i; + int used; /* Linear search might not be the best solution */ - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, + used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT); if (used == I810_BUF_FREE) { return buf; } } - return NULL; + return NULL; } /* This should only be called if the buffer is not sent to the hardware * yet, the hardware updates in use for us once its on the ring buffer. */ -static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) +static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf) { - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - int used; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + int used; - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); if (used != I810_BUF_CLIENT) { - DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); - return -EINVAL; + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return -EINVAL; } - return 0; + return 0; } static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev; - drm_i810_private_t *dev_priv; - drm_buf_t *buf; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i810_private_t *dev_priv; + drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; lock_kernel(); - dev = priv->head->dev; + dev = priv->head->dev; dev_priv = dev->dev_private; - buf = dev_priv->mmap_buffer; + buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; - buf_priv->currently_mapped = I810_BUF_MAPPED; + buf_priv->currently_mapped = I810_BUF_MAPPED; unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - VM_OFFSET(vma) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) return -EAGAIN; + VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; return 0; } static struct file_operations i810_buffer_fops = { - .open = drm_open, - .flush = drm_flush, + .open = drm_open, + .flush = drm_flush, .release = drm_release, - .ioctl = drm_ioctl, - .mmap = i810_mmap_buffers, - .fasync = drm_fasync, + .ioctl = drm_ioctl, + .mmap = i810_mmap_buffers, + .fasync = drm_fasync, }; -static int i810_map_buffer(drm_buf_t *buf, struct file *filp) +static int i810_map_buffer(drm_buf_t * buf, struct file *filp) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_private_t *dev_priv = dev->dev_private; - struct file_operations *old_fops; + drm_i810_private_t *dev_priv = dev->dev_private; + struct file_operations *old_fops; int retcode = 0; - if (buf_priv->currently_mapped == I810_BUF_MAPPED) + if (buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - down_write( ¤t->mm->mmap_sem ); + down_write(¤t->mm->mmap_sem); old_fops = filp->f_op; filp->f_op = &i810_buffer_fops; dev_priv->mmap_buffer = buf; buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, - PROT_READ|PROT_WRITE, - MAP_SHARED, - buf->bus_address); + PROT_READ | PROT_WRITE, + MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; if ((unsigned long)buf_priv->virtual > -1024UL) { @@ -149,12 +148,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) retcode = (signed int)buf_priv->virtual; buf_priv->virtual = NULL; } - up_write( ¤t->mm->mmap_sem ); + up_write(¤t->mm->mmap_sem); return retcode; } -static int i810_unmap_buffer(drm_buf_t *buf) +static int i810_unmap_buffer(drm_buf_t * buf) { drm_i810_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; @@ -168,43 +167,43 @@ static int i810_unmap_buffer(drm_buf_t *buf) (size_t) buf->total); up_write(¤t->mm->mmap_sem); - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - buf_priv->virtual = NULL; + buf_priv->currently_mapped = I810_BUF_UNMAPPED; + buf_priv->virtual = NULL; return retcode; } -static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, +static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d, struct file *filp) { - drm_buf_t *buf; + drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; int retcode = 0; buf = i810_freelist_get(dev); if (!buf) { retcode = -ENOMEM; - DRM_DEBUG("retcode=%d\n", retcode); + DRM_DEBUG("retcode=%d\n", retcode); return retcode; } retcode = i810_map_buffer(buf, filp); if (retcode) { i810_freelist_put(dev, buf); - DRM_ERROR("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; - d->request_idx = buf->idx; - d->request_size = buf->total; - d->virtual = buf_priv->virtual; + d->request_idx = buf->idx; + d->request_size = buf->total; + d->virtual = buf_priv->virtual; return retcode; } -static int i810_dma_cleanup(drm_device_t *dev) +static int i810_dma_cleanup(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; @@ -217,165 +216,167 @@ static int i810_dma_cleanup(drm_device_t *dev) if (dev->dev_private) { int i; - drm_i810_private_t *dev_priv = - (drm_i810_private_t *) dev->dev_private; + drm_i810_private_t *dev_priv = + (drm_i810_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start) { - drm_ioremapfree((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size, dev); + drm_ioremapfree((void *)dev_priv->ring.virtual_start, + dev_priv->ring.Size, dev); } - if (dev_priv->hw_status_page) { - pci_free_consistent(dev->pdev, PAGE_SIZE, + if (dev_priv->hw_status_page) { + pci_free_consistent(dev->pdev, PAGE_SIZE, dev_priv->hw_status_page, dev_priv->dma_status_page); - /* Need to rewrite hardware status page */ - I810_WRITE(0x02080, 0x1ffff000); + /* Need to rewrite hardware status page */ + I810_WRITE(0x02080, 0x1ffff000); } - drm_free(dev->dev_private, sizeof(drm_i810_private_t), + drm_free(dev->dev_private, sizeof(drm_i810_private_t), DRM_MEM_DRIVER); - dev->dev_private = NULL; + dev->dev_private = NULL; for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; + drm_buf_t *buf = dma->buflist[i]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - if ( buf_priv->kernel_virtual && buf->total ) - drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev); + if (buf_priv->kernel_virtual && buf->total) + drm_ioremapfree(buf_priv->kernel_virtual, + buf->total, dev); } } - return 0; -} - -static int i810_wait_ring(drm_device_t *dev, int n) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - int iters = 0; - unsigned long end; - unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - - end = jiffies + (HZ*3); - while (ring->space < n) { - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail+8); - if (ring->space < 0) ring->space += ring->Size; - - if (ring->head != last_head) { - end = jiffies + (HZ*3); - last_head = ring->head; - } - - iters++; - if (time_before(end, jiffies)) { - DRM_ERROR("space: %d wanted %d\n", ring->space, n); - DRM_ERROR("lockup\n"); - goto out_wait_ring; - } - udelay(1); - } - -out_wait_ring: - return iters; -} - -static void i810_kernel_lost_context(drm_device_t *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I810_READ(LP_RING + RING_TAIL); - ring->space = ring->head - (ring->tail+8); - if (ring->space < 0) ring->space += ring->Size; -} - -static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv) -{ - drm_device_dma_t *dma = dev->dma; - int my_idx = 24; - u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); - int i; - - if (dma->buf_count > 1019) { - /* Not enough space in the status page for the freelist */ - return -EINVAL; - } - - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - buf_priv->in_use = hw_status++; - buf_priv->my_use_idx = my_idx; - my_idx += 4; - - *buf_priv->in_use = I810_BUF_FREE; - - buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, - buf->total, dev); - } return 0; } -static int i810_dma_initialize(drm_device_t *dev, - drm_i810_private_t *dev_priv, - drm_i810_init_t *init) +static int i810_wait_ring(drm_device_t * dev, int n) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; + unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + + end = jiffies + (HZ * 3); + while (ring->space < n) { + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; + + if (ring->head != last_head) { + end = jiffies + (HZ * 3); + last_head = ring->head; + } + + iters++; + if (time_before(end, jiffies)) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; + } + udelay(1); + } + + out_wait_ring: + return iters; +} + +static void i810_kernel_lost_context(drm_device_t * dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I810_READ(LP_RING + RING_TAIL); + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; +} + +static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv) +{ + drm_device_dma_t *dma = dev->dma; + int my_idx = 24; + u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); + int i; + + if (dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return -EINVAL; + } + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + buf_priv->in_use = hw_status++; + buf_priv->my_use_idx = my_idx; + my_idx += 4; + + *buf_priv->in_use = I810_BUF_FREE; + + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total, dev); + } + return 0; +} + +static int i810_dma_initialize(drm_device_t * dev, + drm_i810_private_t * dev_priv, + drm_i810_init_t * init) { struct list_head *list; - memset(dev_priv, 0, sizeof(drm_i810_private_t)); + memset(dev_priv, 0, sizeof(drm_i810_private_t)); list_for_each(list, &dev->maplist->head) { drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if (r_list->map && r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { + r_list->map->flags & _DRM_CONTAINS_LOCK) { dev_priv->sarea_map = r_list->map; - break; - } - } + break; + } + } if (!dev_priv->sarea_map) { dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find sarea!\n"); - return -EINVAL; + i810_dma_cleanup(dev); + DRM_ERROR("can not find sarea!\n"); + return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; + i810_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find dma buffer map!\n"); - return -EINVAL; + i810_dma_cleanup(dev); + DRM_ERROR("can not find dma buffer map!\n"); + return -EINVAL; } dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *)dev_priv->sarea_map->handle + - init->sarea_priv_offset); + ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; - dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + - init->ring_start, - init->ring_size, dev); + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, + init->ring_size, dev); - if (dev_priv->ring.virtual_start == NULL) { - dev->dev_private = (void *) dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" + if (dev_priv->ring.virtual_start == NULL) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return -ENOMEM; + return -ENOMEM; } - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; dev_priv->w = init->w; dev_priv->h = init->h; @@ -391,33 +392,33 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; - /* Program Hardware Status Page */ - dev_priv->hw_status_page = - pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); - if (!dev_priv->hw_status_page) { + /* Program Hardware Status Page */ + dev_priv->hw_status_page = + pci_alloc_consistent(dev->pdev, PAGE_SIZE, + &dev_priv->dma_status_page); + if (!dev_priv->hw_status_page) { dev->dev_private = (void *)dev_priv; i810_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); I810_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); + DRM_DEBUG("Enabled hardware status page\n"); - /* Now we need to init our freelist */ + /* Now we need to init our freelist */ if (i810_freelist_init(dev, dev_priv) != 0) { dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("Not enough space in the status page for" + i810_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" " the freelist\n"); - return -ENOMEM; + return -ENOMEM; } dev->dev_private = (void *)dev_priv; - return 0; + return 0; } /* i810 DRM version 1.1 used a smaller init structure with different @@ -431,12 +432,12 @@ static int i810_dma_initialize(drm_device_t *dev, * If it isn't then we have a v1.1 client. Fix up params. * If it is, then we have a 1.2 client... get the rest of the data. */ -static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg) +static int i810_dma_init_compat(drm_i810_init_t * init, unsigned long arg) { /* Get v1.1 init data */ - if (copy_from_user(init, (drm_i810_pre12_init_t __user *)arg, - sizeof(drm_i810_pre12_init_t))) { + if (copy_from_user(init, (drm_i810_pre12_init_t __user *) arg, + sizeof(drm_i810_pre12_init_t))) { return -EFAULT; } @@ -444,7 +445,7 @@ static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg) /* This is a v1.2 client, just get the v1.2 init data */ DRM_INFO("Using POST v1.2 init.\n"); - if (copy_from_user(init, (drm_i810_init_t __user *)arg, + if (copy_from_user(init, (drm_i810_init_t __user *) arg, sizeof(drm_i810_init_t))) { return -EFAULT; } @@ -452,246 +453,239 @@ static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg) /* This is a v1.1 client, fix the params */ DRM_INFO("Using PRE v1.2 init.\n"); - init->pitch_bits = init->h; - init->pitch = init->w; - init->h = init->overlay_physical; - init->w = init->overlay_offset; - init->overlay_physical = 0; - init->overlay_offset = 0; + init->pitch_bits = init->h; + init->pitch = init->w; + init->h = init->overlay_physical; + init->w = init->overlay_offset; + init->overlay_physical = 0; + init->overlay_offset = 0; } return 0; } static int i810_dma_init(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv; - drm_i810_init_t init; - int retcode = 0; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_i810_private_t *dev_priv; + drm_i810_init_t init; + int retcode = 0; /* Get only the init func */ - if (copy_from_user(&init, (void __user *)arg, sizeof(drm_i810_init_func_t))) + if (copy_from_user + (&init, (void __user *)arg, sizeof(drm_i810_init_func_t))) return -EFAULT; - switch(init.func) { - case I810_INIT_DMA: - /* This case is for backward compatibility. It - * handles XFree 4.1.0 and 4.2.0, and has to - * do some parameter checking as described below. - * It will someday go away. - */ - retcode = i810_dma_init_compat(&init, arg); - if (retcode) - return retcode; + switch (init.func) { + case I810_INIT_DMA: + /* This case is for backward compatibility. It + * handles XFree 4.1.0 and 4.2.0, and has to + * do some parameter checking as described below. + * It will someday go away. + */ + retcode = i810_dma_init_compat(&init, arg); + if (retcode) + return retcode; - dev_priv = drm_alloc(sizeof(drm_i810_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i810_dma_initialize(dev, dev_priv, &init); - break; + dev_priv = drm_alloc(sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + retcode = i810_dma_initialize(dev, dev_priv, &init); + break; - default: - case I810_INIT_DMA_1_4: - DRM_INFO("Using v1.4 init.\n"); - if (copy_from_user(&init, (drm_i810_init_t __user *)arg, - sizeof(drm_i810_init_t))) { - return -EFAULT; - } - dev_priv = drm_alloc(sizeof(drm_i810_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i810_dma_initialize(dev, dev_priv, &init); - break; + default: + case I810_INIT_DMA_1_4: + DRM_INFO("Using v1.4 init.\n"); + if (copy_from_user(&init, (drm_i810_init_t __user *) arg, + sizeof(drm_i810_init_t))) { + return -EFAULT; + } + dev_priv = drm_alloc(sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + retcode = i810_dma_initialize(dev, dev_priv, &init); + break; - case I810_CLEANUP_DMA: - DRM_INFO("DMA Cleanup\n"); - retcode = i810_dma_cleanup(dev); - break; + case I810_CLEANUP_DMA: + DRM_INFO("DMA Cleanup\n"); + retcode = i810_dma_cleanup(dev); + break; } - return retcode; + return retcode; } - - /* Most efficient way to verify state for the i810 is as it is * emitted. Non-conformant state is silently dropped. * * Use 'volatile' & local var tmp to force the emitted values to be * identical to the verified ones. */ -static void i810EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i810EmitContextVerified(drm_device_t * dev, + volatile unsigned int *code) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); + BEGIN_LP_RING(I810_CTX_SETUP_SIZE); - OUT_RING( GFX_OP_COLOR_FACTOR ); - OUT_RING( code[I810_CTXREG_CF1] ); + OUT_RING(GFX_OP_COLOR_FACTOR); + OUT_RING(code[I810_CTXREG_CF1]); - OUT_RING( GFX_OP_STIPPLE ); - OUT_RING( code[I810_CTXREG_ST1] ); + OUT_RING(GFX_OP_STIPPLE); + OUT_RING(code[I810_CTXREG_ST1]); - for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { + for (i = 4; i < I810_CTX_SETUP_SIZE; i++) { tmp = code[i]; - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) - { - OUT_RING( tmp ); + if ((tmp & (7 << 29)) == (3 << 29) && + (tmp & (0x1f << 24)) < (0x1d << 24)) { + OUT_RING(tmp); j++; - } - else printk("constext state dropped!!!\n"); + } else + printk("constext state dropped!!!\n"); } if (j & 1) - OUT_RING( 0 ); + OUT_RING(0); ADVANCE_LP_RING(); } -static void i810EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); + BEGIN_LP_RING(I810_TEX_SETUP_SIZE); - OUT_RING( GFX_OP_MAP_INFO ); - OUT_RING( code[I810_TEXREG_MI1] ); - OUT_RING( code[I810_TEXREG_MI2] ); - OUT_RING( code[I810_TEXREG_MI3] ); + OUT_RING(GFX_OP_MAP_INFO); + OUT_RING(code[I810_TEXREG_MI1]); + OUT_RING(code[I810_TEXREG_MI2]); + OUT_RING(code[I810_TEXREG_MI3]); - for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { + for (i = 4; i < I810_TEX_SETUP_SIZE; i++) { tmp = code[i]; - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) - { - OUT_RING( tmp ); + if ((tmp & (7 << 29)) == (3 << 29) && + (tmp & (0x1f << 24)) < (0x1d << 24)) { + OUT_RING(tmp); j++; - } - else printk("texture state dropped!!!\n"); + } else + printk("texture state dropped!!!\n"); } if (j & 1) - OUT_RING( 0 ); + OUT_RING(0); ADVANCE_LP_RING(); } - /* Need to do some additional checking when setting the dest buffer. */ -static void i810EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i810EmitDestVerified(drm_device_t * dev, + volatile unsigned int *code) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 ); + BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); tmp = code[I810_DESTREG_DI1]; if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( tmp ); + OUT_RING(CMD_OP_DESTBUFFER_INFO); + OUT_RING(tmp); } else - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); /* invarient: */ - OUT_RING( CMD_OP_Z_BUFFER_INFO ); - OUT_RING( dev_priv->zi1 ); + OUT_RING(CMD_OP_Z_BUFFER_INFO); + OUT_RING(dev_priv->zi1); - OUT_RING( GFX_OP_DESTBUFFER_VARS ); - OUT_RING( code[I810_DESTREG_DV1] ); + OUT_RING(GFX_OP_DESTBUFFER_VARS); + OUT_RING(code[I810_DESTREG_DV1]); - OUT_RING( GFX_OP_DRAWRECT_INFO ); - OUT_RING( code[I810_DESTREG_DR1] ); - OUT_RING( code[I810_DESTREG_DR2] ); - OUT_RING( code[I810_DESTREG_DR3] ); - OUT_RING( code[I810_DESTREG_DR4] ); - OUT_RING( 0 ); + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(code[I810_DESTREG_DR1]); + OUT_RING(code[I810_DESTREG_DR2]); + OUT_RING(code[I810_DESTREG_DR3]); + OUT_RING(code[I810_DESTREG_DR4]); + OUT_RING(0); ADVANCE_LP_RING(); } - - -static void i810EmitState( drm_device_t *dev ) +static void i810EmitState(drm_device_t * dev) { - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; - + DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); if (dirty & I810_UPLOAD_BUFFERS) { - i810EmitDestVerified( dev, sarea_priv->BufferState ); + i810EmitDestVerified(dev, sarea_priv->BufferState); sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; } if (dirty & I810_UPLOAD_CTX) { - i810EmitContextVerified( dev, sarea_priv->ContextState ); + i810EmitContextVerified(dev, sarea_priv->ContextState); sarea_priv->dirty &= ~I810_UPLOAD_CTX; } if (dirty & I810_UPLOAD_TEX0) { - i810EmitTexVerified( dev, sarea_priv->TexState[0] ); + i810EmitTexVerified(dev, sarea_priv->TexState[0]); sarea_priv->dirty &= ~I810_UPLOAD_TEX0; } if (dirty & I810_UPLOAD_TEX1) { - i810EmitTexVerified( dev, sarea_priv->TexState[1] ); + i810EmitTexVerified(dev, sarea_priv->TexState[1]); sarea_priv->dirty &= ~I810_UPLOAD_TEX1; } } - - /* need to verify */ -static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, - unsigned int clear_color, - unsigned int clear_zval ) +static void i810_dma_dispatch_clear(drm_device_t * dev, int flags, + unsigned int clear_color, + unsigned int clear_zval) { - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; int cpp = 2; int i; RING_LOCALS; - - if ( dev_priv->current_page == 1 ) { - unsigned int tmp = flags; - + + if (dev_priv->current_page == 1) { + unsigned int tmp = flags; + flags &= ~(I810_FRONT | I810_BACK); - if (tmp & I810_FRONT) flags |= I810_BACK; - if (tmp & I810_BACK) flags |= I810_FRONT; + if (tmp & I810_FRONT) + flags |= I810_BACK; + if (tmp & I810_BACK) + flags |= I810_FRONT; } - i810_kernel_lost_context(dev); + i810_kernel_lost_context(dev); - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; - for (i = 0 ; i < nbox ; i++, pbox++) { + for (i = 0; i < nbox; i++, pbox++) { unsigned int x = pbox->x1; unsigned int y = pbox->y1; unsigned int width = (pbox->x2 - x) * cpp; @@ -700,52 +694,48 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || - pbox->y2 > dev_priv->h) + pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - if ( flags & I810_FRONT ) { - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | - BR00_OP_COLOR_BLT | 0x3 ); - OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); - OUT_RING( (height << 16) | width ); - OUT_RING( start ); - OUT_RING( clear_color ); - OUT_RING( 0 ); + if (flags & I810_FRONT) { + BEGIN_LP_RING(6); + OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); + OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); + OUT_RING((height << 16) | width); + OUT_RING(start); + OUT_RING(clear_color); + OUT_RING(0); ADVANCE_LP_RING(); } - if ( flags & I810_BACK ) { - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | - BR00_OP_COLOR_BLT | 0x3 ); - OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); - OUT_RING( (height << 16) | width ); - OUT_RING( dev_priv->back_offset + start ); - OUT_RING( clear_color ); - OUT_RING( 0 ); + if (flags & I810_BACK) { + BEGIN_LP_RING(6); + OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); + OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); + OUT_RING((height << 16) | width); + OUT_RING(dev_priv->back_offset + start); + OUT_RING(clear_color); + OUT_RING(0); ADVANCE_LP_RING(); } - if ( flags & I810_DEPTH ) { - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | - BR00_OP_COLOR_BLT | 0x3 ); - OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); - OUT_RING( (height << 16) | width ); - OUT_RING( dev_priv->depth_offset + start ); - OUT_RING( clear_zval ); - OUT_RING( 0 ); + if (flags & I810_DEPTH) { + BEGIN_LP_RING(6); + OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); + OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); + OUT_RING((height << 16) | width); + OUT_RING(dev_priv->depth_offset + start); + OUT_RING(clear_zval); + OUT_RING(0); ADVANCE_LP_RING(); } } } -static void i810_dma_dispatch_swap( drm_device_t *dev ) +static void i810_dma_dispatch_swap(drm_device_t * dev) { - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; @@ -755,75 +745,71 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) DRM_DEBUG("swapbuffers\n"); - i810_kernel_lost_context(dev); + i810_kernel_lost_context(dev); - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; - for (i = 0 ; i < nbox; i++, pbox++) - { + for (i = 0; i < nbox; i++, pbox++) { unsigned int w = pbox->x2 - pbox->x1; unsigned int h = pbox->y2 - pbox->y1; - unsigned int dst = pbox->x1*cpp + pbox->y1*pitch; + unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch; unsigned int start = dst; if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || - pbox->y2 > dev_priv->h) + pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); - OUT_RING( pitch | (0xCC << 16)); - OUT_RING( (h << 16) | (w * cpp)); + BEGIN_LP_RING(6); + OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); + OUT_RING(pitch | (0xCC << 16)); + OUT_RING((h << 16) | (w * cpp)); if (dev_priv->current_page == 0) - OUT_RING(dev_priv->front_offset + start); + OUT_RING(dev_priv->front_offset + start); else - OUT_RING(dev_priv->back_offset + start); - OUT_RING( pitch ); + OUT_RING(dev_priv->back_offset + start); + OUT_RING(pitch); if (dev_priv->current_page == 0) - OUT_RING(dev_priv->back_offset + start); + OUT_RING(dev_priv->back_offset + start); else - OUT_RING(dev_priv->front_offset + start); + OUT_RING(dev_priv->front_offset + start); ADVANCE_LP_RING(); } } - -static void i810_dma_dispatch_vertex(drm_device_t *dev, - drm_buf_t *buf, - int discard, - int used) +static void i810_dma_dispatch_vertex(drm_device_t * dev, + drm_buf_t * buf, int discard, int used) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_clip_rect_t *box = sarea_priv->boxes; - int nbox = sarea_priv->nbox; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; int i = 0; - RING_LOCALS; + RING_LOCALS; - i810_kernel_lost_context(dev); + i810_kernel_lost_context(dev); - if (nbox > I810_NR_SAREA_CLIPRECTS) + if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - if (used > 4*1024) + if (used > 4 * 1024) used = 0; if (sarea_priv->dirty) - i810EmitState( dev ); + i810EmitState(dev); if (buf_priv->currently_mapped == I810_BUF_MAPPED) { unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); - *(u32 *)buf_priv->kernel_virtual = ((GFX_OP_PRIMITIVE | prim | ((used/4)-2))); + *(u32 *) buf_priv->kernel_virtual = + ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); if (used & 4) { - *(u32 *)((u32)buf_priv->kernel_virtual + used) = 0; + *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0; used += 4; } @@ -834,19 +820,20 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, do { if (i < nbox) { BEGIN_LP_RING(4); - OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | - SC_ENABLE ); - OUT_RING( GFX_OP_SCISSOR_INFO ); - OUT_RING( box[i].x1 | (box[i].y1<<16) ); - OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); + OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + SC_ENABLE); + OUT_RING(GFX_OP_SCISSOR_INFO); + OUT_RING(box[i].x1 | (box[i].y1 << 16)); + OUT_RING((box[i].x2 - + 1) | ((box[i].y2 - 1) << 16)); ADVANCE_LP_RING(); } BEGIN_LP_RING(4); - OUT_RING( CMD_OP_BATCH_BUFFER ); - OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + used - 4 ); - OUT_RING( 0 ); + OUT_RING(CMD_OP_BATCH_BUFFER); + OUT_RING(start | BB1_PROTECTED); + OUT_RING(start + used - 4); + OUT_RING(0); ADVANCE_LP_RING(); } while (++i < nbox); @@ -855,59 +842,59 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, if (discard) { dev_priv->counter++; - (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); + (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); BEGIN_LP_RING(8); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( buf_priv->my_use_idx ); - OUT_RING( I810_BUF_FREE ); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); + OUT_RING(dev_priv->counter); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(buf_priv->my_use_idx); + OUT_RING(I810_BUF_FREE); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); ADVANCE_LP_RING(); } } -static void i810_dma_dispatch_flip( drm_device_t *dev ) +static void i810_dma_dispatch_flip(drm_device_t * dev) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; int pitch = dev_priv->pitch; RING_LOCALS; - DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", - __FUNCTION__, - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); - - i810_kernel_lost_context(dev); + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); - BEGIN_LP_RING( 2 ); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); - OUT_RING( 0 ); + i810_kernel_lost_context(dev); + + BEGIN_LP_RING(2); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING(0); ADVANCE_LP_RING(); - BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 ); + BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); /* On i815 at least ASYNC is buggy */ /* pitch<<5 is from 11.2.8 p158, its the pitch / 8 then left shifted 8, so (pitch >> 3) << 8 */ - OUT_RING( CMD_OP_FRONTBUFFER_INFO | (pitch<<5) /*| ASYNC_FLIP */ ); - if ( dev_priv->current_page == 0 ) { - OUT_RING( dev_priv->back_offset ); + OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ ); + if (dev_priv->current_page == 0) { + OUT_RING(dev_priv->back_offset); dev_priv->current_page = 1; } else { - OUT_RING( dev_priv->front_offset ); + OUT_RING(dev_priv->front_offset); dev_priv->current_page = 0; } OUT_RING(0); ADVANCE_LP_RING(); BEGIN_LP_RING(2); - OUT_RING( CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP ); - OUT_RING( 0 ); + OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP); + OUT_RING(0); ADVANCE_LP_RING(); /* Increment the frame counter. The client-side 3D driver must @@ -918,46 +905,46 @@ static void i810_dma_dispatch_flip( drm_device_t *dev ) } -static void i810_dma_quiescent(drm_device_t *dev) +static void i810_dma_quiescent(drm_device_t * dev) { - drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS; + drm_i810_private_t *dev_priv = dev->dev_private; + RING_LOCALS; /* printk("%s\n", __FUNCTION__); */ - i810_kernel_lost_context(dev); + i810_kernel_lost_context(dev); - BEGIN_LP_RING(4); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); + BEGIN_LP_RING(4); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); + OUT_RING(0); + ADVANCE_LP_RING(); - i810_wait_ring( dev, dev_priv->ring.Size - 8 ); + i810_wait_ring(dev, dev_priv->ring.Size - 8); } -static int i810_flush_queue(drm_device_t *dev) +static int i810_flush_queue(drm_device_t * dev) { - drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - int i, ret = 0; - RING_LOCALS; - + int i, ret = 0; + RING_LOCALS; + /* printk("%s\n", __FUNCTION__); */ - i810_kernel_lost_context(dev); + i810_kernel_lost_context(dev); - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); + BEGIN_LP_RING(2); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); + ADVANCE_LP_RING(); - i810_wait_ring( dev, dev_priv->ring.Size - 8 ); + i810_wait_ring(dev, dev_priv->ring.Size - 8); - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, I810_BUF_FREE); @@ -968,24 +955,27 @@ static int i810_flush_queue(drm_device_t *dev) DRM_DEBUG("still on client\n"); } - return ret; + return ret; } /* Must be called with the lock held */ -void i810_reclaim_buffers(drm_device_t *dev, struct file *filp) +void i810_reclaim_buffers(drm_device_t * dev, struct file *filp) { drm_device_dma_t *dma = dev->dma; - int i; + int i; - if (!dma) return; - if (!dev->dev_private) return; - if (!dma->buflist) return; + if (!dma) + return; + if (!dev->dev_private) + return; + if (!dma->buflist) + return; - i810_flush_queue(dev); + i810_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_buf_t *buf = dma->buflist[i]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, @@ -994,7 +984,7 @@ void i810_reclaim_buffers(drm_device_t *dev, struct file *filp) if (used == I810_BUF_CLIENT) DRM_DEBUG("reclaimed from client\n"); if (buf_priv->currently_mapped == I810_BUF_MAPPED) - buf_priv->currently_mapped = I810_BUF_UNMAPPED; + buf_priv->currently_mapped = I810_BUF_UNMAPPED; } } } @@ -1002,29 +992,29 @@ void i810_reclaim_buffers(drm_device_t *dev, struct file *filp) static int i810_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; LOCK_TEST_WITH_RETURN(dev, filp); - i810_flush_queue(dev); - return 0; + i810_flush_queue(dev); + return 0; } - static int i810_dma_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_device_dma_t *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; drm_i810_vertex_t vertex; - if (copy_from_user(&vertex, (drm_i810_vertex_t __user *)arg, sizeof(vertex))) + if (copy_from_user + (&vertex, (drm_i810_vertex_t __user *) arg, sizeof(vertex))) return -EFAULT; LOCK_TEST_WITH_RETURN(dev, filp); @@ -1032,48 +1022,46 @@ static int i810_dma_vertex(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); - if (vertex.idx < 0 || vertex.idx > dma->buf_count) + if (vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; - i810_dma_dispatch_vertex( dev, - dma->buflist[ vertex.idx ], - vertex.discard, vertex.used ); + i810_dma_dispatch_vertex(dev, + dma->buflist[vertex.idx], + vertex.discard, vertex.used); - atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]); + atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]); atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter-1; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_enqueue = dev_priv->counter - 1; + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } - - static int i810_clear_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_i810_clear_t clear; - if (copy_from_user(&clear, (drm_i810_clear_t __user *)arg, sizeof(clear))) + if (copy_from_user + (&clear, (drm_i810_clear_t __user *) arg, sizeof(clear))) return -EFAULT; LOCK_TEST_WITH_RETURN(dev, filp); - /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { - return -EINVAL; - } + /* GH: Someone's doing nasty things... */ + if (!dev->dev_private) { + return -EINVAL; + } - i810_dma_dispatch_clear( dev, clear.flags, - clear.clear_color, - clear.clear_depth ); - return 0; + i810_dma_dispatch_clear(dev, clear.flags, + clear.clear_color, clear.clear_depth); + return 0; } static int i810_swap_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1082,37 +1070,37 @@ static int i810_swap_bufs(struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN(dev, filp); - i810_dma_dispatch_swap( dev ); - return 0; + i810_dma_dispatch_swap(dev); + return 0; } static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - int retcode = 0; - drm_i810_dma_t d; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + int retcode = 0; + drm_i810_dma_t d; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; - if (copy_from_user(&d, (drm_i810_dma_t __user *)arg, sizeof(d))) + if (copy_from_user(&d, (drm_i810_dma_t __user *) arg, sizeof(d))) return -EFAULT; LOCK_TEST_WITH_RETURN(dev, filp); @@ -1124,29 +1112,29 @@ static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", current->pid, retcode, d.granted); - if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d))) + if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d))) return -EFAULT; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return retcode; } static int i810_copybuf(struct inode *inode, - struct file *filp, unsigned int cmd, unsigned long arg) + struct file *filp, unsigned int cmd, unsigned long arg) { /* Never copy - 2.4.x doesn't need it */ return 0; } static int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { /* Never copy - 2.4.x doesn't need it */ return 0; } -static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used, - unsigned int last_render) +static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used, + unsigned int last_render) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; @@ -1158,19 +1146,17 @@ static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used, i810_kernel_lost_context(dev); - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); if (u != I810_BUF_CLIENT) { DRM_DEBUG("MC found buffer that isn't mine!\n"); } - if (used > 4*1024) + if (used > 4 * 1024) used = 0; sarea_priv->dirty = 0x7f; - DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", - address, used); + DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", address, used); dev_priv->counter++; DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); @@ -1181,46 +1167,45 @@ static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used, if (buf_priv->currently_mapped == I810_BUF_MAPPED) { if (used & 4) { - *(u32 *)((u32)buf_priv->virtual + used) = 0; + *(u32 *) ((u32) buf_priv->virtual + used) = 0; used += 4; } i810_unmap_buffer(buf); } BEGIN_LP_RING(4); - OUT_RING( CMD_OP_BATCH_BUFFER ); - OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + used - 4 ); - OUT_RING( 0 ); + OUT_RING(CMD_OP_BATCH_BUFFER); + OUT_RING(start | BB1_PROTECTED); + OUT_RING(start + used - 4); + OUT_RING(0); ADVANCE_LP_RING(); - BEGIN_LP_RING(8); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( buf_priv->my_use_idx ); - OUT_RING( I810_BUF_FREE ); - OUT_RING( 0 ); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(buf_priv->my_use_idx); + OUT_RING(I810_BUF_FREE); + OUT_RING(0); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 16 ); - OUT_RING( last_render ); - OUT_RING( 0 ); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(16); + OUT_RING(last_render); + OUT_RING(0); ADVANCE_LP_RING(); } static int i810_dma_mc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_device_dma_t *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; u32 *hw_status = dev_priv->hw_status_page; drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + dev_priv->sarea_priv; drm_i810_mc_t mc; - if (copy_from_user(&mc, (drm_i810_mc_t __user *)arg, sizeof(mc))) + if (copy_from_user(&mc, (drm_i810_mc_t __user *) arg, sizeof(mc))) return -EFAULT; LOCK_TEST_WITH_RETURN(dev, filp); @@ -1229,12 +1214,12 @@ static int i810_dma_mc(struct inode *inode, struct file *filp, return -EINVAL; i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used, - mc.last_render ); + mc.last_render); atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]); atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter-1; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_enqueue = dev_priv->counter - 1; + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } @@ -1244,22 +1229,23 @@ static int i810_rstatus(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - return (int)(((u32 *)(dev_priv->hw_status_page))[4]); + return (int)(((u32 *) (dev_priv->hw_status_page))[4]); } static int i810_ov0_info(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; drm_i810_overlay_t data; data.offset = dev_priv->overlay_offset; data.physical = dev_priv->overlay_physical; - if (copy_to_user((drm_i810_overlay_t __user *)arg,&data,sizeof(data))) + if (copy_to_user + ((drm_i810_overlay_t __user *) arg, &data, sizeof(data))) return -EFAULT; return 0; } @@ -1269,7 +1255,7 @@ static int i810_fstatus(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; LOCK_TEST_WITH_RETURN(dev, filp); @@ -1277,47 +1263,46 @@ static int i810_fstatus(struct inode *inode, struct file *filp, } static int i810_ov0_flip(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; LOCK_TEST_WITH_RETURN(dev, filp); //Tell the overlay to update - I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000); + I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); return 0; } - /* Not sure why this isn't set all the time: - */ -static void i810_do_init_pageflip( drm_device_t *dev ) + */ +static void i810_do_init_pageflip(drm_device_t * dev) { drm_i810_private_t *dev_priv = dev->dev_private; - + DRM_DEBUG("%s\n", __FUNCTION__); dev_priv->page_flipping = 1; dev_priv->current_page = 0; dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static int i810_do_cleanup_pageflip( drm_device_t *dev ) +static int i810_do_cleanup_pageflip(drm_device_t * dev) { drm_i810_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); if (dev_priv->current_page != 0) - i810_dma_dispatch_flip( dev ); + i810_dma_dispatch_flip(dev); dev_priv->page_flipping = 0; return 0; } static int i810_flip_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1327,19 +1312,19 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN(dev, filp); - if (!dev_priv->page_flipping) - i810_do_init_pageflip( dev ); + if (!dev_priv->page_flipping) + i810_do_init_pageflip(dev); - i810_dma_dispatch_flip( dev ); - return 0; + i810_dma_dispatch_flip(dev); + return 0; } -void i810_driver_pretakedown(drm_device_t *dev) +void i810_driver_pretakedown(drm_device_t * dev) { - i810_dma_cleanup( dev ); + i810_dma_cleanup(dev); } -void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp) +void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -1349,33 +1334,47 @@ void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp) } } -void i810_driver_release(drm_device_t *dev, struct file *filp) +void i810_driver_release(drm_device_t * dev, struct file *filp) { i810_reclaim_buffers(dev, filp); } -int i810_driver_dma_quiescent(drm_device_t *dev) +int i810_driver_dma_quiescent(drm_device_t * dev) { - i810_dma_quiescent( dev ); + i810_dma_quiescent(dev); return 0; } drm_ioctl_desc_t i810_ioctls[] = { - [DRM_IOCTL_NR(DRM_I810_INIT)] = { i810_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_GETAGE)] = { i810_getage, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_GETBUF)] = { i810_getbuf, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_COPY)] = { i810_copybuf, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = { i810_docopy, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_MC)] = { i810_dma_mc, 1, 1 }, - [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus, 1, 0 }, - [DRM_IOCTL_NR(DRM_I810_FLIP)] = { i810_flip_bufs, 1, 0 } + [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1} + , + [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0} + , + [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0} }; int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); diff --git a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h index 73ac40563b1d..2deb925a94f3 100644 --- a/drivers/char/drm/i810_drm.h +++ b/drivers/char/drm/i810_drm.h @@ -19,21 +19,20 @@ #define I810_LOG_MIN_TEX_REGION_SIZE 16 #endif -#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ -#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ +#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ +#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ #define I810_UPLOAD_CTX 0x4 #define I810_UPLOAD_BUFFERS 0x8 #define I810_UPLOAD_TEX0 0x10 #define I810_UPLOAD_TEX1 0x20 #define I810_UPLOAD_CLIPRECTS 0x40 - /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, * or in a piecewise fashion as required. */ -/* Destbuffer state +/* Destbuffer state * - backbuffer linear offset and pitch -- invarient in the current dri * - zbuffer linear offset and pitch -- also invarient * - drawing origin in back and depth buffers. @@ -55,13 +54,13 @@ /* Context state */ #define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */ -#define I810_CTXREG_CF1 1 -#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */ +#define I810_CTXREG_CF1 1 +#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */ #define I810_CTXREG_ST1 3 #define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */ #define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */ #define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */ -#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ +#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ #define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */ #define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */ #define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */ @@ -74,14 +73,14 @@ #define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */ #define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */ #define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ -#define I810_CTX_SETUP_SIZE 20 +#define I810_CTX_SETUP_SIZE 20 /* Texture state (per tex unit) */ #define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */ -#define I810_TEXREG_MI1 1 -#define I810_TEXREG_MI2 2 -#define I810_TEXREG_MI3 3 +#define I810_TEXREG_MI1 1 +#define I810_TEXREG_MI2 2 +#define I810_TEXREG_MI3 3 #define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */ #define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */ #define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */ @@ -98,7 +97,7 @@ typedef enum _drm_i810_init_func { I810_INIT_DMA = 0x01, I810_CLEANUP_DMA = 0x02, I810_INIT_DMA_1_4 = 0x03 - } drm_i810_init_func_t; +} drm_i810_init_func_t; /* This is the init structure after v1.2 */ typedef struct _drm_i810_init { @@ -122,7 +121,7 @@ typedef struct _drm_i810_init { unsigned int w; unsigned int h; unsigned int pitch; - unsigned int pitch_bits; + unsigned int pitch_bits; } drm_i810_init_t; /* This is the init structure prior to v1.2 */ @@ -140,23 +139,23 @@ typedef struct _drm_i810_pre12_init { unsigned int w; unsigned int h; unsigned int pitch; - unsigned int pitch_bits; + unsigned int pitch_bits; } drm_i810_pre12_init_t; /* Warning: If you change the SAREA structure you must change the Xserver * structure as well */ typedef struct _drm_i810_tex_region { - unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char next, prev; /* indices to form a circular LRU */ unsigned char in_use; /* owned by a client, or free? */ int age; /* tracked by clients to update local LRU's */ } drm_i810_tex_region_t; typedef struct _drm_i810_sarea { - unsigned int ContextState[I810_CTX_SETUP_SIZE]; - unsigned int BufferState[I810_DEST_SETUP_SIZE]; - unsigned int TexState[2][I810_TEX_SETUP_SIZE]; - unsigned int dirty; + unsigned int ContextState[I810_CTX_SETUP_SIZE]; + unsigned int BufferState[I810_DEST_SETUP_SIZE]; + unsigned int TexState[2][I810_TEX_SETUP_SIZE]; + unsigned int dirty; unsigned int nbox; drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; @@ -174,22 +173,22 @@ typedef struct _drm_i810_sarea { * texture space, and can make informed decisions as to which * areas to kick out. There is no need to choose whether to * kick out your own texture or someone else's - simply eject - * them all in LRU order. + * them all in LRU order. */ - - drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1]; - /* Last elt is sentinal */ - int texAge; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ + + drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ - int last_quiescent; /* */ + int last_quiescent; /* */ int ctxOwner; /* last context to upload state */ int vertex_prim; - int pf_enabled; /* is pageflipping allowed? */ + int pf_enabled; /* is pageflipping allowed? */ int pf_active; - int pf_current_page; /* which buffer is being displayed? */ + int pf_current_page; /* which buffer is being displayed? */ } drm_i810_sarea_t; /* WARNING: If you change any of these defines, make sure to change the @@ -243,13 +242,13 @@ typedef struct _drm_i810_clear { * new set of cliprects. */ typedef struct _drm_i810_vertex { - int idx; /* buffer index */ + int idx; /* buffer index */ int used; /* nr bytes in use */ int discard; /* client is finished with the buffer? */ } drm_i810_vertex_t; typedef struct _drm_i810_copy_t { - int idx; /* buffer index */ + int idx; /* buffer index */ int used; /* nr bytes in use */ void *address; /* Address to copy from */ } drm_i810_copy_t; @@ -264,7 +263,6 @@ typedef struct _drm_i810_copy_t { #define PR_RECTS (0x7<<18) #define PR_MASK (0x7<<18) - typedef struct drm_i810_dma { void *virtual; int request_idx; @@ -273,17 +271,16 @@ typedef struct drm_i810_dma { } drm_i810_dma_t; typedef struct _drm_i810_overlay_t { - unsigned int offset; /* Address of the Overlay Regs */ + unsigned int offset; /* Address of the Overlay Regs */ unsigned int physical; } drm_i810_overlay_t; typedef struct _drm_i810_mc { - int idx; /* buffer index */ - int used; /* nr bytes in use */ - int num_blocks; /* number of GFXBlocks */ - int *length; /* List of lengths for GFXBlocks (FUTURE)*/ - unsigned int last_render; /* Last Render Request */ + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int num_blocks; /* number of GFXBlocks */ + int *length; /* List of lengths for GFXBlocks (FUTURE) */ + unsigned int last_render; /* Last Render Request */ } drm_i810_mc_t; - -#endif /* _I810_DRM_H_ */ +#endif /* _I810_DRM_H_ */ diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c index 00609329d578..327e2f1cc997 100644 --- a/drivers/char/drm/i810_drv.c +++ b/drivers/char/drm/i810_drv.c @@ -38,7 +38,7 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { /* i810 has 4 more counters */ dev->counters += 4; @@ -46,29 +46,27 @@ static int postinit( struct drm_device *dev, unsigned long flags ) dev->types[7] = _DRM_STAT_PRIMARY; dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; - - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -80,7 +78,9 @@ extern drm_ioctl_desc_t i810_ioctls[]; extern int i810_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, + .driver_features = + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | + DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, .dev_priv_size = sizeof(drm_i810_buf_priv_t), .pretakedown = i810_driver_pretakedown, .prerelease = i810_driver_prerelease, @@ -94,18 +94,20 @@ static struct drm_driver driver = { .version = version, .ioctls = i810_ioctls, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, + .name = DRIVER_NAME, + .id_table = pciidlist, + } + , }; static int __init i810_init(void) @@ -122,6 +124,6 @@ static void __exit i810_exit(void) module_init(i810_init); module_exit(i810_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h index 62ee4f58c59a..2d6b594afa0d 100644 --- a/drivers/char/drm/i810_drv.h +++ b/drivers/char/drm/i810_drv.h @@ -56,14 +56,14 @@ #define DRIVER_PATCHLEVEL 0 typedef struct drm_i810_buf_priv { - u32 *in_use; - int my_use_idx; + u32 *in_use; + int my_use_idx; int currently_mapped; void *virtual; void *kernel_virtual; } drm_i810_buf_priv_t; -typedef struct _drm_i810_ring_buffer{ +typedef struct _drm_i810_ring_buffer { int tail_mask; unsigned long Start; unsigned long End; @@ -79,16 +79,15 @@ typedef struct drm_i810_private { drm_map_t *mmio_map; drm_i810_sarea_t *sarea_priv; - drm_i810_ring_buffer_t ring; + drm_i810_ring_buffer_t ring; - void *hw_status_page; - unsigned long counter; + void *hw_status_page; + unsigned long counter; dma_addr_t dma_status_page; drm_buf_t *mmap_buffer; - u32 front_di1, back_di1, zi1; int back_offset; @@ -97,7 +96,7 @@ typedef struct drm_i810_private { int overlay_physical; int w, h; int pitch; - int back_pitch; + int back_pitch; int depth_pitch; int do_boxes; @@ -107,19 +106,19 @@ typedef struct drm_i810_private { int page_flipping; wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; - - int front_offset; + atomic_t irq_received; + atomic_t irq_emitted; + + int front_offset; } drm_i810_private_t; /* i810_dma.c */ -extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp); +extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); -extern int i810_driver_dma_quiescent(drm_device_t *dev); -extern void i810_driver_release(drm_device_t *dev, struct file *filp); -extern void i810_driver_pretakedown(drm_device_t *dev); -extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp); +extern int i810_driver_dma_quiescent(drm_device_t * dev); +extern void i810_driver_release(drm_device_t * dev, struct file *filp); +extern void i810_driver_pretakedown(drm_device_t * dev); +extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i810_driver_device_is_agp(drm_device_t * dev); #define I810_BASE(reg) ((unsigned long) \ @@ -170,7 +169,6 @@ extern int i810_driver_device_is_agp(drm_device_t * dev); #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 - #define BB1_START_ADDR_MASK (~0x7) #define BB1_PROTECTED (1<<0) #define BB1_UNPROTECTED (0<<0) @@ -229,8 +227,8 @@ extern int i810_driver_device_is_agp(drm_device_t * dev); #define BR00_OP_SRC_COPY_BLT 0x10C00000 #define BR13_SOLID_PATTERN 0x80000000 -#define WAIT_FOR_PLANE_A_SCANLINES (1<<1) -#define WAIT_FOR_PLANE_A_FLIP (1<<2) +#define WAIT_FOR_PLANE_A_SCANLINES (1<<1) +#define WAIT_FOR_PLANE_A_FLIP (1<<2) #define WAIT_FOR_VBLANK (1<<3) #endif diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 6f89d5796ef3..e1107ecb16e3 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -47,103 +47,104 @@ #define I830_BUF_UNMAPPED 0 #define I830_BUF_MAPPED 1 -static drm_buf_t *i830_freelist_get(drm_device_t *dev) +static drm_buf_t *i830_freelist_get(drm_device_t * dev) { - drm_device_dma_t *dma = dev->dma; - int i; - int used; - + drm_device_dma_t *dma = dev->dma; + int i; + int used; + /* Linear search might not be the best solution */ - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, + used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, I830_BUF_CLIENT); - if(used == I830_BUF_FREE) { + if (used == I830_BUF_FREE) { return buf; } } - return NULL; + return NULL; } /* This should only be called if the buffer is not sent to the hardware * yet, the hardware updates in use for us once its on the ring buffer. */ -static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf) +static int i830_freelist_put(drm_device_t * dev, drm_buf_t * buf) { - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - int used; - - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); - if(used != I830_BUF_CLIENT) { - DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); - return -EINVAL; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + int used; + + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); + if (used != I830_BUF_CLIENT) { + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return -EINVAL; } - - return 0; + + return 0; } static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev; - drm_i830_private_t *dev_priv; - drm_buf_t *buf; + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i830_private_t *dev_priv; + drm_buf_t *buf; drm_i830_buf_priv_t *buf_priv; lock_kernel(); - dev = priv->head->dev; + dev = priv->head->dev; dev_priv = dev->dev_private; - buf = dev_priv->mmap_buffer; + buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; - + vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; - - buf_priv->currently_mapped = I830_BUF_MAPPED; + + buf_priv->currently_mapped = I830_BUF_MAPPED; unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - VM_OFFSET(vma) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) return -EAGAIN; + VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; return 0; } static struct file_operations i830_buffer_fops = { - .open = drm_open, - .flush = drm_flush, + .open = drm_open, + .flush = drm_flush, .release = drm_release, - .ioctl = drm_ioctl, - .mmap = i830_mmap_buffers, - .fasync = drm_fasync, + .ioctl = drm_ioctl, + .mmap = i830_mmap_buffers, + .fasync = drm_fasync, }; -static int i830_map_buffer(drm_buf_t *buf, struct file *filp) +static int i830_map_buffer(drm_buf_t * buf, struct file *filp) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - drm_i830_private_t *dev_priv = dev->dev_private; - struct file_operations *old_fops; + drm_i830_private_t *dev_priv = dev->dev_private; + struct file_operations *old_fops; unsigned long virtual; int retcode = 0; - if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL; + if (buf_priv->currently_mapped == I830_BUF_MAPPED) + return -EINVAL; - down_write( ¤t->mm->mmap_sem ); + down_write(¤t->mm->mmap_sem); old_fops = filp->f_op; filp->f_op = &i830_buffer_fops; dev_priv->mmap_buffer = buf; - virtual = do_mmap(filp, 0, buf->total, PROT_READ|PROT_WRITE, - MAP_SHARED, buf->bus_address); + virtual = do_mmap(filp, 0, buf->total, PROT_READ | PROT_WRITE, + MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; - if (IS_ERR((void *)virtual)) { /* ugh */ + if (IS_ERR((void *)virtual)) { /* ugh */ /* Real error */ DRM_ERROR("mmap error\n"); retcode = virtual; @@ -151,17 +152,17 @@ static int i830_map_buffer(drm_buf_t *buf, struct file *filp) } else { buf_priv->virtual = (void __user *)virtual; } - up_write( ¤t->mm->mmap_sem ); + up_write(¤t->mm->mmap_sem); return retcode; } -static int i830_unmap_buffer(drm_buf_t *buf) +static int i830_unmap_buffer(drm_buf_t * buf) { drm_i830_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; - if(buf_priv->currently_mapped != I830_BUF_MAPPED) + if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EINVAL; down_write(¤t->mm->mmap_sem); @@ -170,43 +171,43 @@ static int i830_unmap_buffer(drm_buf_t *buf) (size_t) buf->total); up_write(¤t->mm->mmap_sem); - buf_priv->currently_mapped = I830_BUF_UNMAPPED; - buf_priv->virtual = NULL; + buf_priv->currently_mapped = I830_BUF_UNMAPPED; + buf_priv->virtual = NULL; return retcode; } -static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, +static int i830_dma_get_buffer(drm_device_t * dev, drm_i830_dma_t * d, struct file *filp) { - drm_buf_t *buf; + drm_buf_t *buf; drm_i830_buf_priv_t *buf_priv; int retcode = 0; buf = i830_freelist_get(dev); if (!buf) { retcode = -ENOMEM; - DRM_DEBUG("retcode=%d\n", retcode); + DRM_DEBUG("retcode=%d\n", retcode); return retcode; } - + retcode = i830_map_buffer(buf, filp); - if(retcode) { + if (retcode) { i830_freelist_put(dev, buf); - DRM_ERROR("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } buf->filp = filp; - buf_priv = buf->dev_private; + buf_priv = buf->dev_private; d->granted = 1; - d->request_idx = buf->idx; - d->request_size = buf->total; - d->virtual = buf_priv->virtual; + d->request_idx = buf->idx; + d->request_size = buf->total; + d->virtual = buf_priv->virtual; return retcode; } -static int i830_dma_cleanup(drm_device_t *dev) +static int i830_dma_cleanup(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; @@ -214,140 +215,144 @@ static int i830_dma_cleanup(drm_device_t *dev) * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq_enabled ) drm_irq_uninstall(dev); + if (dev->irq_enabled) + drm_irq_uninstall(dev); if (dev->dev_private) { int i; - drm_i830_private_t *dev_priv = - (drm_i830_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_ioremapfree((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size, dev); + drm_i830_private_t *dev_priv = + (drm_i830_private_t *) dev->dev_private; + + if (dev_priv->ring.virtual_start) { + drm_ioremapfree((void *)dev_priv->ring.virtual_start, + dev_priv->ring.Size, dev); } - if (dev_priv->hw_status_page) { + if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, dev_priv->hw_status_page, dev_priv->dma_status_page); - /* Need to rewrite hardware status page */ - I830_WRITE(0x02080, 0x1ffff000); + /* Need to rewrite hardware status page */ + I830_WRITE(0x02080, 0x1ffff000); } - drm_free(dev->dev_private, sizeof(drm_i830_private_t), + drm_free(dev->dev_private, sizeof(drm_i830_private_t), DRM_MEM_DRIVER); - dev->dev_private = NULL; + dev->dev_private = NULL; for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; + drm_buf_t *buf = dma->buflist[i]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - if ( buf_priv->kernel_virtual && buf->total ) - drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev); + if (buf_priv->kernel_virtual && buf->total) + drm_ioremapfree(buf_priv->kernel_virtual, + buf->total, dev); } } - return 0; + return 0; } -int i830_wait_ring(drm_device_t *dev, int n, const char *caller) +int i830_wait_ring(drm_device_t * dev, int n, const char *caller) { - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_ring_buffer_t *ring = &(dev_priv->ring); - int iters = 0; - unsigned long end; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - end = jiffies + (HZ*3); - while (ring->space < n) { - ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail+8); - if (ring->space < 0) ring->space += ring->Size; - + end = jiffies + (HZ * 3); + while (ring->space < n) { + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; + if (ring->head != last_head) { - end = jiffies + (HZ*3); + end = jiffies + (HZ * 3); last_head = ring->head; } - - iters++; - if(time_before(end, jiffies)) { - DRM_ERROR("space: %d wanted %d\n", ring->space, n); - DRM_ERROR("lockup\n"); - goto out_wait_ring; + + iters++; + if (time_before(end, jiffies)) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; } udelay(1); dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } -out_wait_ring: - return iters; + out_wait_ring: + return iters; } -static void i830_kernel_lost_context(drm_device_t *dev) +static void i830_kernel_lost_context(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; - ring->space = ring->head - (ring->tail+8); - if (ring->space < 0) ring->space += ring->Size; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; if (ring->head == ring->tail) dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } -static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) +static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv) { - drm_device_dma_t *dma = dev->dma; - int my_idx = 36; - u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); - int i; + drm_device_dma_t *dma = dev->dma; + int my_idx = 36; + u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); + int i; - if(dma->buf_count > 1019) { - /* Not enough space in the status page for the freelist */ - return -EINVAL; + if (dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return -EINVAL; } - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->in_use = hw_status++; - buf_priv->my_use_idx = my_idx; - my_idx += 4; + buf_priv->in_use = hw_status++; + buf_priv->my_use_idx = my_idx; + my_idx += 4; - *buf_priv->in_use = I830_BUF_FREE; + *buf_priv->in_use = I830_BUF_FREE; - buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, - buf->total, dev); + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total, dev); } return 0; } -static int i830_dma_initialize(drm_device_t *dev, - drm_i830_private_t *dev_priv, - drm_i830_init_t *init) +static int i830_dma_initialize(drm_device_t * dev, + drm_i830_private_t * dev_priv, + drm_i830_init_t * init) { struct list_head *list; - memset(dev_priv, 0, sizeof(drm_i830_private_t)); + memset(dev_priv, 0, sizeof(drm_i830_private_t)); list_for_each(list, &dev->maplist->head) { drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); - if( r_list->map && + if (r_list->map && r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { + r_list->map->flags & _DRM_CONTAINS_LOCK) { dev_priv->sarea_map = r_list->map; - break; - } - } + break; + } + } - if(!dev_priv->sarea_map) { + if (!dev_priv->sarea_map) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("can not find sarea!\n"); return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if(!dev_priv->mmio_map) { + if (!dev_priv->mmio_map) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("can not find mmio map!\n"); @@ -355,7 +360,7 @@ static int i830_dma_initialize(drm_device_t *dev, } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if(!dev->agp_buffer_map) { + if (!dev->agp_buffer_map) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("can not find dma buffer map!\n"); @@ -363,27 +368,26 @@ static int i830_dma_initialize(drm_device_t *dev, } dev_priv->sarea_priv = (drm_i830_sarea_t *) - ((u8 *)dev_priv->sarea_map->handle + - init->sarea_priv_offset); + ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; - dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + - init->ring_start, - init->ring_size, dev); + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, + init->ring_size, dev); - if (dev_priv->ring.virtual_start == NULL) { - dev->dev_private = (void *) dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" + if (dev_priv->ring.virtual_start == NULL) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return -ENOMEM; + return -ENOMEM; } - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + dev_priv->w = init->w; dev_priv->h = init->h; dev_priv->pitch = init->pitch; @@ -395,10 +399,10 @@ static int i830_dma_initialize(drm_device_t *dev, dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; - DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1); + DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1); DRM_DEBUG("back_offset %x\n", dev_priv->back_offset); - DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1); - DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); + DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1); + DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); dev_priv->cpp = init->cpp; /* We are using separate values as placeholders for mechanisms for @@ -410,63 +414,64 @@ static int i830_dma_initialize(drm_device_t *dev, dev_priv->do_boxes = 0; dev_priv->use_mi_batchbuffer_start = 0; - /* Program Hardware Status Page */ - dev_priv->hw_status_page = - pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); - if (!dev_priv->hw_status_page) { + /* Program Hardware Status Page */ + dev_priv->hw_status_page = + pci_alloc_consistent(dev->pdev, PAGE_SIZE, + &dev_priv->dma_status_page); + if (!dev_priv->hw_status_page) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I830_WRITE(0x02080, dev_priv->dma_status_page); + + I830_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - - /* Now we need to init our freelist */ - if(i830_freelist_init(dev, dev_priv) != 0) { + + /* Now we need to init our freelist */ + if (i830_freelist_init(dev, dev_priv) != 0) { dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("Not enough space in the status page for" + i830_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" " the freelist\n"); - return -ENOMEM; + return -ENOMEM; } dev->dev_private = (void *)dev_priv; - return 0; + return 0; } static int i830_dma_init(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_i830_private_t *dev_priv; - drm_i830_init_t init; - int retcode = 0; - - if (copy_from_user(&init, (void * __user) arg, sizeof(init))) + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_i830_private_t *dev_priv; + drm_i830_init_t init; + int retcode = 0; + + if (copy_from_user(&init, (void *__user)arg, sizeof(init))) return -EFAULT; - - switch(init.func) { - case I830_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i830_private_t), - DRM_MEM_DRIVER); - if(dev_priv == NULL) return -ENOMEM; - retcode = i830_dma_initialize(dev, dev_priv, &init); - break; - case I830_CLEANUP_DMA: - retcode = i830_dma_cleanup(dev); - break; - default: - retcode = -EINVAL; - break; + + switch (init.func) { + case I830_INIT_DMA: + dev_priv = drm_alloc(sizeof(drm_i830_private_t), + DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + retcode = i830_dma_initialize(dev, dev_priv, &init); + break; + case I830_CLEANUP_DMA: + retcode = i830_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; } - - return retcode; + + return retcode; } #define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) @@ -476,92 +481,89 @@ static int i830_dma_init(struct inode *inode, struct file *filp, /* Most efficient way to verify state for the i830 is as it is * emitted. Non-conformant state is silently dropped. */ -static void i830EmitContextVerified( drm_device_t *dev, - unsigned int *code ) +static void i830EmitContextVerified(drm_device_t * dev, unsigned int *code) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 ); + BEGIN_LP_RING(I830_CTX_SETUP_SIZE + 4); - for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { + for (i = 0; i < I830_CTXREG_BLENDCOLR0; i++) { tmp = code[i]; - if ((tmp & (7<<29)) == CMD_3D && - (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + if ((tmp & (7 << 29)) == CMD_3D && + (tmp & (0x1f << 24)) < (0x1d << 24)) { + OUT_RING(tmp); j++; } else { DRM_ERROR("Skipping %d\n", i); } } - OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); - OUT_RING( code[I830_CTXREG_BLENDCOLR] ); + OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD); + OUT_RING(code[I830_CTXREG_BLENDCOLR]); j += 2; - for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) { + for (i = I830_CTXREG_VF; i < I830_CTXREG_MCSB0; i++) { tmp = code[i]; - if ((tmp & (7<<29)) == CMD_3D && - (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + if ((tmp & (7 << 29)) == CMD_3D && + (tmp & (0x1f << 24)) < (0x1d << 24)) { + OUT_RING(tmp); j++; } else { DRM_ERROR("Skipping %d\n", i); } } - OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); - OUT_RING( code[I830_CTXREG_MCSB1] ); + OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD); + OUT_RING(code[I830_CTXREG_MCSB1]); j += 2; - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING(0); ADVANCE_LP_RING(); } -static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) +static void i830EmitTexVerified(drm_device_t * dev, unsigned int *code) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || - (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == - (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { + (code[I830_TEXREG_MI0] & ~(0xf * LOAD_TEXTURE_MAP0)) == + (STATE3D_LOAD_STATE_IMMEDIATE_2 | 4)) { - BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + BEGIN_LP_RING(I830_TEX_SETUP_SIZE); - OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ - OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ - OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ - OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ - OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ - OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ - - for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + OUT_RING(code[I830_TEXREG_MI0]); /* TM0LI */ + OUT_RING(code[I830_TEXREG_MI1]); /* TM0S0 */ + OUT_RING(code[I830_TEXREG_MI2]); /* TM0S1 */ + OUT_RING(code[I830_TEXREG_MI3]); /* TM0S2 */ + OUT_RING(code[I830_TEXREG_MI4]); /* TM0S3 */ + OUT_RING(code[I830_TEXREG_MI5]); /* TM0S4 */ + + for (i = 6; i < I830_TEX_SETUP_SIZE; i++) { tmp = code[i]; - OUT_RING( tmp ); + OUT_RING(tmp); j++; - } + } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING(0); ADVANCE_LP_RING(); - } - else + } else printk("rejected packet %x\n", code[0]); } -static void i830EmitTexBlendVerified( drm_device_t *dev, - unsigned int *code, - unsigned int num) +static void i830EmitTexBlendVerified(drm_device_t * dev, + unsigned int *code, unsigned int num) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; @@ -569,59 +571,54 @@ static void i830EmitTexBlendVerified( drm_device_t *dev, if (!num) return; - BEGIN_LP_RING( num + 1 ); + BEGIN_LP_RING(num + 1); - for ( i = 0 ; i < num ; i++ ) { + for (i = 0; i < num; i++) { tmp = code[i]; - OUT_RING( tmp ); + OUT_RING(tmp); j++; } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING(0); ADVANCE_LP_RING(); } -static void i830EmitTexPalette( drm_device_t *dev, - unsigned int *palette, - int number, - int is_shared ) +static void i830EmitTexPalette(drm_device_t * dev, + unsigned int *palette, int number, int is_shared) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; return; - BEGIN_LP_RING( 258 ); + BEGIN_LP_RING(258); - if(is_shared == 1) { + if (is_shared == 1) { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | - MAP_PALETTE_NUM(0) | - MAP_PALETTE_BOTH); + MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH); } else { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); } - for(i = 0; i < 256; i++) { + for (i = 0; i < 256; i++) { OUT_RING(palette[i]); } OUT_RING(0); - /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! + /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! */ } /* Need to do some additional checking when setting the dest buffer. */ -static void i830EmitDestVerified( drm_device_t *dev, - unsigned int *code ) -{ - drm_i830_private_t *dev_priv = dev->dev_private; +static void i830EmitDestVerified(drm_device_t * dev, unsigned int *code) +{ + drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); - + BEGIN_LP_RING(I830_DEST_SETUP_SIZE + 10); tmp = code[I830_DESTREG_CBUFADDR]; if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { @@ -630,18 +627,18 @@ static void i830EmitDestVerified( drm_device_t *dev, OUT_RING(0); } - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | - BUF_3D_USE_FENCE); - OUT_RING( tmp ); - OUT_RING( 0 ); + OUT_RING(CMD_OP_DESTBUFFER_INFO); + OUT_RING(BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | + BUF_3D_USE_FENCE); + OUT_RING(tmp); + OUT_RING(0); - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING( dev_priv->zi1 ); - OUT_RING( 0 ); + OUT_RING(CMD_OP_DESTBUFFER_INFO); + OUT_RING(BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | + BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); + OUT_RING(dev_priv->zi1); + OUT_RING(0); } else { DRM_ERROR("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); @@ -650,83 +647,80 @@ static void i830EmitDestVerified( drm_device_t *dev, /* invarient: */ + OUT_RING(GFX_OP_DESTBUFFER_VARS); + OUT_RING(code[I830_DESTREG_DV1]); - OUT_RING( GFX_OP_DESTBUFFER_VARS ); - OUT_RING( code[I830_DESTREG_DV1] ); - - OUT_RING( GFX_OP_DRAWRECT_INFO ); - OUT_RING( code[I830_DESTREG_DR1] ); - OUT_RING( code[I830_DESTREG_DR2] ); - OUT_RING( code[I830_DESTREG_DR3] ); - OUT_RING( code[I830_DESTREG_DR4] ); + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(code[I830_DESTREG_DR1]); + OUT_RING(code[I830_DESTREG_DR2]); + OUT_RING(code[I830_DESTREG_DR3]); + OUT_RING(code[I830_DESTREG_DR4]); /* Need to verify this */ tmp = code[I830_DESTREG_SENABLE]; - if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { - OUT_RING( tmp ); + if ((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { + OUT_RING(tmp); } else { DRM_ERROR("bad scissor enable\n"); - OUT_RING( 0 ); + OUT_RING(0); } - OUT_RING( GFX_OP_SCISSOR_RECT ); - OUT_RING( code[I830_DESTREG_SR1] ); - OUT_RING( code[I830_DESTREG_SR2] ); - OUT_RING( 0 ); + OUT_RING(GFX_OP_SCISSOR_RECT); + OUT_RING(code[I830_DESTREG_SR1]); + OUT_RING(code[I830_DESTREG_SR2]); + OUT_RING(0); ADVANCE_LP_RING(); } -static void i830EmitStippleVerified( drm_device_t *dev, - unsigned int *code ) +static void i830EmitStippleVerified(drm_device_t * dev, unsigned int *code) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; - BEGIN_LP_RING( 2 ); - OUT_RING( GFX_OP_STIPPLE ); - OUT_RING( code[1] ); - ADVANCE_LP_RING(); + BEGIN_LP_RING(2); + OUT_RING(GFX_OP_STIPPLE); + OUT_RING(code[1]); + ADVANCE_LP_RING(); } - -static void i830EmitState( drm_device_t *dev ) +static void i830EmitState(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); if (dirty & I830_UPLOAD_BUFFERS) { - i830EmitDestVerified( dev, sarea_priv->BufferState ); + i830EmitDestVerified(dev, sarea_priv->BufferState); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; } if (dirty & I830_UPLOAD_CTX) { - i830EmitContextVerified( dev, sarea_priv->ContextState ); + i830EmitContextVerified(dev, sarea_priv->ContextState); sarea_priv->dirty &= ~I830_UPLOAD_CTX; } if (dirty & I830_UPLOAD_TEX0) { - i830EmitTexVerified( dev, sarea_priv->TexState[0] ); + i830EmitTexVerified(dev, sarea_priv->TexState[0]); sarea_priv->dirty &= ~I830_UPLOAD_TEX0; } if (dirty & I830_UPLOAD_TEX1) { - i830EmitTexVerified( dev, sarea_priv->TexState[1] ); + i830EmitTexVerified(dev, sarea_priv->TexState[1]); sarea_priv->dirty &= ~I830_UPLOAD_TEX1; } if (dirty & I830_UPLOAD_TEXBLEND0) { - i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0], - sarea_priv->TexBlendStateWordsUsed[0]); + i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[0], + sarea_priv->TexBlendStateWordsUsed[0]); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0; } if (dirty & I830_UPLOAD_TEXBLEND1) { - i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1], - sarea_priv->TexBlendStateWordsUsed[1]); + i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[1], + sarea_priv->TexBlendStateWordsUsed[1]); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1; } @@ -759,36 +753,32 @@ static void i830EmitState( drm_device_t *dev ) /* 1.3: */ if (dirty & I830_UPLOAD_STIPPLE) { - i830EmitStippleVerified( dev, - sarea_priv->StippleState); + i830EmitStippleVerified(dev, sarea_priv->StippleState); sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; } if (dirty & I830_UPLOAD_TEX2) { - i830EmitTexVerified( dev, sarea_priv->TexState2 ); + i830EmitTexVerified(dev, sarea_priv->TexState2); sarea_priv->dirty &= ~I830_UPLOAD_TEX2; } if (dirty & I830_UPLOAD_TEX3) { - i830EmitTexVerified( dev, sarea_priv->TexState3 ); + i830EmitTexVerified(dev, sarea_priv->TexState3); sarea_priv->dirty &= ~I830_UPLOAD_TEX3; } - if (dirty & I830_UPLOAD_TEXBLEND2) { - i830EmitTexBlendVerified( - dev, - sarea_priv->TexBlendState2, - sarea_priv->TexBlendStateWordsUsed2); + i830EmitTexBlendVerified(dev, + sarea_priv->TexBlendState2, + sarea_priv->TexBlendStateWordsUsed2); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; } if (dirty & I830_UPLOAD_TEXBLEND3) { - i830EmitTexBlendVerified( - dev, - sarea_priv->TexBlendState3, - sarea_priv->TexBlendStateWordsUsed3); + i830EmitTexBlendVerified(dev, + sarea_priv->TexBlendState3, + sarea_priv->TexBlendStateWordsUsed3); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; } } @@ -797,97 +787,96 @@ static void i830EmitState( drm_device_t *dev ) * Performance monitoring functions */ -static void i830_fill_box( drm_device_t *dev, - int x, int y, int w, int h, - int r, int g, int b ) +static void i830_fill_box(drm_device_t * dev, + int x, int y, int w, int h, int r, int g, int b) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; u32 color; unsigned int BR13, CMD; RING_LOCALS; - BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); + BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1 << 24); CMD = XY_COLOR_BLT_CMD; x += dev_priv->sarea_priv->boxes[0].x1; y += dev_priv->sarea_priv->boxes[0].y1; if (dev_priv->cpp == 4) { - BR13 |= (1<<25); + BR13 |= (1 << 25); CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); } else { color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | - ((b & 0xf8) >> 3)); + ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); } - BEGIN_LP_RING( 6 ); - OUT_RING( CMD ); - OUT_RING( BR13 ); - OUT_RING( (y << 16) | x ); - OUT_RING( ((y+h) << 16) | (x+w) ); + BEGIN_LP_RING(6); + OUT_RING(CMD); + OUT_RING(BR13); + OUT_RING((y << 16) | x); + OUT_RING(((y + h) << 16) | (x + w)); - if ( dev_priv->current_page == 1 ) { - OUT_RING( dev_priv->front_offset ); - } else { - OUT_RING( dev_priv->back_offset ); - } + if (dev_priv->current_page == 1) { + OUT_RING(dev_priv->front_offset); + } else { + OUT_RING(dev_priv->back_offset); + } - OUT_RING( color ); + OUT_RING(color); ADVANCE_LP_RING(); } -static void i830_cp_performance_boxes( drm_device_t *dev ) +static void i830_cp_performance_boxes(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; /* Purple box for page flipping */ - if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) - i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); + if (dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP) + i830_fill_box(dev, 4, 4, 8, 8, 255, 0, 255); /* Red box if we have to wait for idle at any point */ - if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) - i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); + if (dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT) + i830_fill_box(dev, 16, 4, 8, 8, 255, 0, 0); /* Blue box: lost context? */ - if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) - i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); + if (dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT) + i830_fill_box(dev, 28, 4, 8, 8, 0, 0, 255); /* Yellow box for texture swaps */ - if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) - i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); + if (dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD) + i830_fill_box(dev, 40, 4, 8, 8, 255, 255, 0); /* Green box if hardware never idles (as far as we can tell) */ - if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) - i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); + if (!(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY)) + i830_fill_box(dev, 64, 4, 8, 8, 0, 255, 0); - - /* Draw bars indicating number of buffers allocated + /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) */ if (dev_priv->dma_used) { int bar = dev_priv->dma_used / 10240; - if (bar > 100) bar = 100; - if (bar < 1) bar = 1; - i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); + if (bar > 100) + bar = 100; + if (bar < 1) + bar = 1; + i830_fill_box(dev, 4, 16, bar, 4, 196, 128, 128); dev_priv->dma_used = 0; } dev_priv->sarea_priv->perf_boxes = 0; } -static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, +static void i830_dma_dispatch_clear(drm_device_t * dev, int flags, unsigned int clear_color, unsigned int clear_zval, unsigned int clear_depthmask) { - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; @@ -896,90 +885,90 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int BR13, CMD, D_CMD; RING_LOCALS; - - if ( dev_priv->current_page == 1 ) { + if (dev_priv->current_page == 1) { unsigned int tmp = flags; flags &= ~(I830_FRONT | I830_BACK); - if ( tmp & I830_FRONT ) flags |= I830_BACK; - if ( tmp & I830_BACK ) flags |= I830_FRONT; + if (tmp & I830_FRONT) + flags |= I830_BACK; + if (tmp & I830_BACK) + flags |= I830_FRONT; } - i830_kernel_lost_context(dev); + i830_kernel_lost_context(dev); - switch(cpp) { - case 2: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + switch (cpp) { + case 2: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); D_CMD = CMD = XY_COLOR_BLT_CMD; break; case 4: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); - CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); D_CMD = XY_COLOR_BLT_CMD; - if(clear_depthmask & 0x00ffffff) + if (clear_depthmask & 0x00ffffff) D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if(clear_depthmask & 0xff000000) + if (clear_depthmask & 0xff000000) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; break; default: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); D_CMD = CMD = XY_COLOR_BLT_CMD; break; } - if (nbox > I830_NR_SAREA_CLIPRECTS) - nbox = I830_NR_SAREA_CLIPRECTS; + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; - for (i = 0 ; i < nbox ; i++, pbox++) { + for (i = 0; i < nbox; i++, pbox++) { if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || - pbox->y2 > dev_priv->h) + pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - if ( flags & I830_FRONT ) { - DRM_DEBUG("clear front\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( CMD ); - OUT_RING( BR13 ); - OUT_RING( (pbox->y1 << 16) | pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( dev_priv->front_offset ); - OUT_RING( clear_color ); + if (flags & I830_FRONT) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING(6); + OUT_RING(CMD); + OUT_RING(BR13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); + OUT_RING(dev_priv->front_offset); + OUT_RING(clear_color); ADVANCE_LP_RING(); } - if ( flags & I830_BACK ) { + if (flags & I830_BACK) { DRM_DEBUG("clear back\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( CMD ); - OUT_RING( BR13 ); - OUT_RING( (pbox->y1 << 16) | pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( dev_priv->back_offset ); - OUT_RING( clear_color ); + BEGIN_LP_RING(6); + OUT_RING(CMD); + OUT_RING(BR13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); + OUT_RING(dev_priv->back_offset); + OUT_RING(clear_color); ADVANCE_LP_RING(); } - if ( flags & I830_DEPTH ) { + if (flags & I830_DEPTH) { DRM_DEBUG("clear depth\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( D_CMD ); - OUT_RING( BR13 ); - OUT_RING( (pbox->y1 << 16) | pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( dev_priv->depth_offset ); - OUT_RING( clear_zval ); + BEGIN_LP_RING(6); + OUT_RING(D_CMD); + OUT_RING(BR13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); + OUT_RING(dev_priv->depth_offset); + OUT_RING(clear_zval); ADVANCE_LP_RING(); } } } -static void i830_dma_dispatch_swap( drm_device_t *dev ) +static void i830_dma_dispatch_swap(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; @@ -990,202 +979,192 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) DRM_DEBUG("swapbuffers\n"); - i830_kernel_lost_context(dev); + i830_kernel_lost_context(dev); if (dev_priv->do_boxes) - i830_cp_performance_boxes( dev ); + i830_cp_performance_boxes(dev); - switch(cpp) { - case 2: - BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + switch (cpp) { + case 2: + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); CMD = XY_SRC_COPY_BLT_CMD; break; case 4: - BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25); + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); break; default: - BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); CMD = XY_SRC_COPY_BLT_CMD; break; } + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; - if (nbox > I830_NR_SAREA_CLIPRECTS) - nbox = I830_NR_SAREA_CLIPRECTS; - - for (i = 0 ; i < nbox; i++, pbox++) - { + for (i = 0; i < nbox; i++, pbox++) { if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || - pbox->y2 > dev_priv->h) + pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", - pbox->x1, pbox->y1, - pbox->x2, pbox->y2); + pbox->x1, pbox->y1, pbox->x2, pbox->y2); - BEGIN_LP_RING( 8 ); - OUT_RING( CMD ); - OUT_RING( BR13 ); - OUT_RING( (pbox->y1 << 16) | pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + BEGIN_LP_RING(8); + OUT_RING(CMD); + OUT_RING(BR13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); - if (dev_priv->current_page == 0) - OUT_RING( dev_priv->front_offset ); + if (dev_priv->current_page == 0) + OUT_RING(dev_priv->front_offset); else - OUT_RING( dev_priv->back_offset ); + OUT_RING(dev_priv->back_offset); - OUT_RING( (pbox->y1 << 16) | pbox->x1 ); - OUT_RING( BR13 & 0xffff ); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING(BR13 & 0xffff); - if (dev_priv->current_page == 0) - OUT_RING( dev_priv->back_offset ); + if (dev_priv->current_page == 0) + OUT_RING(dev_priv->back_offset); else - OUT_RING( dev_priv->front_offset ); + OUT_RING(dev_priv->front_offset); ADVANCE_LP_RING(); } } -static void i830_dma_dispatch_flip( drm_device_t *dev ) +static void i830_dma_dispatch_flip(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", - __FUNCTION__, - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); - i830_kernel_lost_context(dev); + i830_kernel_lost_context(dev); if (dev_priv->do_boxes) { dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; - i830_cp_performance_boxes( dev ); + i830_cp_performance_boxes(dev); } - - BEGIN_LP_RING( 2 ); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); - OUT_RING( 0 ); + BEGIN_LP_RING(2); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING(0); ADVANCE_LP_RING(); - BEGIN_LP_RING( 6 ); - OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP ); - OUT_RING( 0 ); - if ( dev_priv->current_page == 0 ) { - OUT_RING( dev_priv->back_offset ); + BEGIN_LP_RING(6); + OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); + OUT_RING(0); + if (dev_priv->current_page == 0) { + OUT_RING(dev_priv->back_offset); dev_priv->current_page = 1; } else { - OUT_RING( dev_priv->front_offset ); + OUT_RING(dev_priv->front_offset); dev_priv->current_page = 0; } OUT_RING(0); ADVANCE_LP_RING(); - - BEGIN_LP_RING( 2 ); - OUT_RING( MI_WAIT_FOR_EVENT | - MI_WAIT_FOR_PLANE_A_FLIP ); - OUT_RING( 0 ); + BEGIN_LP_RING(2); + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); + OUT_RING(0); ADVANCE_LP_RING(); - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static void i830_dma_dispatch_vertex(drm_device_t *dev, - drm_buf_t *buf, - int discard, - int used) +static void i830_dma_dispatch_vertex(drm_device_t * dev, + drm_buf_t * buf, int discard, int used) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_clip_rect_t *box = sarea_priv->boxes; - int nbox = sarea_priv->nbox; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; + unsigned long start = address - dev->agp->base; int i = 0, u; - RING_LOCALS; + RING_LOCALS; - i830_kernel_lost_context(dev); + i830_kernel_lost_context(dev); - if (nbox > I830_NR_SAREA_CLIPRECTS) + if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; if (discard) { - u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_HARDWARE); - if(u != I830_BUF_CLIENT) { + if (u != I830_BUF_CLIENT) { DRM_DEBUG("xxxx 2\n"); } } - if (used > 4*1023) + if (used > 4 * 1023) used = 0; if (sarea_priv->dirty) - i830EmitState( dev ); + i830EmitState(dev); - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", address, used, nbox); - dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG( "i830_dma_dispatch\n"); - DRM_DEBUG( "start : %lx\n", start); - DRM_DEBUG( "used : %d\n", used); - DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); + dev_priv->counter++; + DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG("i830_dma_dispatch\n"); + DRM_DEBUG("start : %lx\n", start); + DRM_DEBUG("used : %d\n", used); + DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); if (buf_priv->currently_mapped == I830_BUF_MAPPED) { u32 *vp = buf_priv->kernel_virtual; vp[0] = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | - ((used/4)-2)); + sarea_priv->vertex_prim | ((used / 4) - 2)); if (dev_priv->use_mi_batchbuffer_start) { - vp[used/4] = MI_BATCH_BUFFER_END; - used += 4; + vp[used / 4] = MI_BATCH_BUFFER_END; + used += 4; } - + if (used & 4) { - vp[used/4] = 0; + vp[used / 4] = 0; used += 4; } i830_unmap_buffer(buf); } - + if (used) { do { if (i < nbox) { BEGIN_LP_RING(6); - OUT_RING( GFX_OP_DRAWRECT_INFO ); - OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] ); - OUT_RING( box[i].x1 | (box[i].y1<<16) ); - OUT_RING( box[i].x2 | (box[i].y2<<16) ); - OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] ); - OUT_RING( 0 ); + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(sarea_priv-> + BufferState[I830_DESTREG_DR1]); + OUT_RING(box[i].x1 | (box[i].y1 << 16)); + OUT_RING(box[i].x2 | (box[i].y2 << 16)); + OUT_RING(sarea_priv-> + BufferState[I830_DESTREG_DR4]); + OUT_RING(0); ADVANCE_LP_RING(); } if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); - OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); - OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); + OUT_RING(start | MI_BATCH_NON_SECURE); ADVANCE_LP_RING(); - } - else { + } else { BEGIN_LP_RING(4); - OUT_RING( MI_BATCH_BUFFER ); - OUT_RING( start | MI_BATCH_NON_SECURE ); - OUT_RING( start + used - 4 ); - OUT_RING( 0 ); + OUT_RING(MI_BATCH_BUFFER); + OUT_RING(start | MI_BATCH_NON_SECURE); + OUT_RING(start + used - 4); + OUT_RING(0); ADVANCE_LP_RING(); } @@ -1195,61 +1174,60 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev, if (discard) { dev_priv->counter++; - (void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, - I830_BUF_HARDWARE); + (void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_HARDWARE); BEGIN_LP_RING(8); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( buf_priv->my_use_idx ); - OUT_RING( I830_BUF_FREE ); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); + OUT_RING(dev_priv->counter); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(buf_priv->my_use_idx); + OUT_RING(I830_BUF_FREE); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); ADVANCE_LP_RING(); } } - -static void i830_dma_quiescent(drm_device_t *dev) +static void i830_dma_quiescent(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; - i830_kernel_lost_context(dev); + i830_kernel_lost_context(dev); - BEGIN_LP_RING(4); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); + BEGIN_LP_RING(4); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); + OUT_RING(0); + ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); + i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); } -static int i830_flush_queue(drm_device_t *dev) +static int i830_flush_queue(drm_device_t * dev) { - drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - int i, ret = 0; - RING_LOCALS; - - i830_kernel_lost_context(dev); + int i, ret = 0; + RING_LOCALS; - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); + i830_kernel_lost_context(dev); - i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); + BEGIN_LP_RING(2); + OUT_RING(CMD_REPORT_HEAD); + OUT_RING(0); + ADVANCE_LP_RING(); - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - - int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, + i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[i]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, I830_BUF_FREE); if (used == I830_BUF_HARDWARE) @@ -1258,62 +1236,66 @@ static int i830_flush_queue(drm_device_t *dev) DRM_DEBUG("still on client\n"); } - return ret; + return ret; } /* Must be called with the lock held */ -void i830_reclaim_buffers(drm_device_t *dev, struct file *filp) +void i830_reclaim_buffers(drm_device_t * dev, struct file *filp) { drm_device_dma_t *dma = dev->dma; - int i; + int i; - if (!dma) return; - if (!dev->dev_private) return; - if (!dma->buflist) return; + if (!dma) + return; + if (!dev->dev_private) + return; + if (!dma->buflist) + return; - i830_flush_queue(dev); + i830_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - + drm_buf_t *buf = dma->buflist[i]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + if (buf->filp == filp && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); if (used == I830_BUF_CLIENT) DRM_DEBUG("reclaimed from client\n"); - if(buf_priv->currently_mapped == I830_BUF_MAPPED) - buf_priv->currently_mapped = I830_BUF_UNMAPPED; + if (buf_priv->currently_mapped == I830_BUF_MAPPED) + buf_priv->currently_mapped = I830_BUF_UNMAPPED; } } } -static int i830_flush_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static int i830_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; LOCK_TEST_WITH_RETURN(dev, filp); - i830_flush_queue(dev); - return 0; + i830_flush_queue(dev); + return 0; } static int i830_dma_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_device_dma_t *dma = dev->dma; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; drm_i830_vertex_t vertex; - if (copy_from_user(&vertex, (drm_i830_vertex_t __user *)arg, sizeof(vertex))) + if (copy_from_user + (&vertex, (drm_i830_vertex_t __user *) arg, sizeof(vertex))) return -EFAULT; LOCK_TEST_WITH_RETURN(dev, filp); @@ -1321,15 +1303,16 @@ static int i830_dma_vertex(struct inode *inode, struct file *filp, DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); - if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; + if (vertex.idx < 0 || vertex.idx > dma->buf_count) + return -EINVAL; - i830_dma_dispatch_vertex( dev, - dma->buflist[ vertex.idx ], - vertex.discard, vertex.used ); + i830_dma_dispatch_vertex(dev, + dma->buflist[vertex.idx], + vertex.discard, vertex.used); + + sarea_priv->last_enqueue = dev_priv->counter - 1; + sarea_priv->last_dispatch = (int)hw_status[5]; - sarea_priv->last_enqueue = dev_priv->counter-1; - sarea_priv->last_dispatch = (int) hw_status[5]; - return 0; } @@ -1340,9 +1323,10 @@ static int i830_clear_bufs(struct inode *inode, struct file *filp, drm_device_t *dev = priv->head->dev; drm_i830_clear_t clear; - if (copy_from_user(&clear, (drm_i830_clear_t __user *)arg, sizeof(clear))) + if (copy_from_user + (&clear, (drm_i830_clear_t __user *) arg, sizeof(clear))) return -EFAULT; - + LOCK_TEST_WITH_RETURN(dev, filp); /* GH: Someone's doing nasty things... */ @@ -1350,11 +1334,10 @@ static int i830_clear_bufs(struct inode *inode, struct file *filp, return -EINVAL; } - i830_dma_dispatch_clear( dev, clear.flags, - clear.clear_color, - clear.clear_depth, - clear.clear_depthmask); - return 0; + i830_dma_dispatch_clear(dev, clear.flags, + clear.clear_color, + clear.clear_depth, clear.clear_depthmask); + return 0; } static int i830_swap_bufs(struct inode *inode, struct file *filp, @@ -1362,20 +1345,18 @@ static int i830_swap_bufs(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - + DRM_DEBUG("i830_swap_bufs\n"); LOCK_TEST_WITH_RETURN(dev, filp); - i830_dma_dispatch_swap( dev ); - return 0; + i830_dma_dispatch_swap(dev); + return 0; } - - /* Not sure why this isn't set all the time: - */ -static void i830_do_init_pageflip( drm_device_t *dev ) + */ +static void i830_do_init_pageflip(drm_device_t * dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1385,20 +1366,20 @@ static void i830_do_init_pageflip( drm_device_t *dev ) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static int i830_do_cleanup_pageflip( drm_device_t *dev ) +static int i830_do_cleanup_pageflip(drm_device_t * dev) { drm_i830_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); if (dev_priv->current_page != 0) - i830_dma_dispatch_flip( dev ); + i830_dma_dispatch_flip(dev); dev_priv->page_flipping = 0; return 0; } static int i830_flip_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1408,45 +1389,45 @@ static int i830_flip_bufs(struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN(dev, filp); - if (!dev_priv->page_flipping) - i830_do_init_pageflip( dev ); + if (!dev_priv->page_flipping) + i830_do_init_pageflip(dev); - i830_dma_dispatch_flip( dev ); - return 0; + i830_dma_dispatch_flip(dev); + return 0; } static int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - int retcode = 0; - drm_i830_dma_t d; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + int retcode = 0; + drm_i830_dma_t d; + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; DRM_DEBUG("getbuf\n"); - if (copy_from_user(&d, (drm_i830_dma_t __user *)arg, sizeof(d))) + if (copy_from_user(&d, (drm_i830_dma_t __user *) arg, sizeof(d))) return -EFAULT; - + LOCK_TEST_WITH_RETURN(dev, filp); - + d.granted = 0; retcode = i830_dma_get_buffer(dev, &d, filp); @@ -1454,46 +1435,45 @@ static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n", current->pid, retcode, d.granted); - if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d))) + if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d))) return -EFAULT; - sarea_priv->last_dispatch = (int) hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return retcode; } static int i830_copybuf(struct inode *inode, - struct file *filp, unsigned int cmd, unsigned long arg) + struct file *filp, unsigned int cmd, unsigned long arg) { /* Never copy - 2.4.x doesn't need it */ return 0; } static int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { return 0; } - - -static int i830_getparam( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +static int i830_getparam(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_getparam_t param; int value; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - if (copy_from_user(¶m, (drm_i830_getparam_t __user *)arg, sizeof(param) )) + if (copy_from_user + (¶m, (drm_i830_getparam_t __user *) arg, sizeof(param))) return -EFAULT; - switch( param.param ) { + switch (param.param) { case I830_PARAM_IRQ_ACTIVE: value = dev->irq_enabled; break; @@ -1501,32 +1481,32 @@ static int i830_getparam( struct inode *inode, struct file *filp, return -EINVAL; } - if ( copy_to_user( param.value, &value, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (copy_to_user(param.value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return -EFAULT; } - + return 0; } - -static int i830_setparam( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +static int i830_setparam(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_setparam_t param; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - if (copy_from_user(¶m, (drm_i830_setparam_t __user *)arg, sizeof(param) )) + if (copy_from_user + (¶m, (drm_i830_setparam_t __user *) arg, sizeof(param))) return -EFAULT; - switch( param.param ) { + switch (param.param) { case I830_SETPARAM_USE_MI_BATCHBUFFER_START: dev_priv->use_mi_batchbuffer_start = param.value; break; @@ -1537,13 +1517,12 @@ static int i830_setparam( struct inode *inode, struct file *filp, return 0; } - -void i830_driver_pretakedown(drm_device_t *dev) +void i830_driver_pretakedown(drm_device_t * dev) { - i830_dma_cleanup( dev ); + i830_dma_cleanup(dev); } -void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp) +void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1553,32 +1532,45 @@ void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp) } } -void i830_driver_release(drm_device_t *dev, struct file *filp) +void i830_driver_release(drm_device_t * dev, struct file *filp) { i830_reclaim_buffers(dev, filp); } -int i830_driver_dma_quiescent(drm_device_t *dev) +int i830_driver_dma_quiescent(drm_device_t * dev) { - i830_dma_quiescent( dev ); + i830_dma_quiescent(dev); return 0; } drm_ioctl_desc_t i830_ioctls[] = { - [DRM_IOCTL_NR(DRM_I830_INIT)] = { i830_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_GETAGE)] = { i830_getage, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_GETBUF)] = { i830_getbuf, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_COPY)] = { i830_copybuf, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = { i830_docopy, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam, 1, 0 }, - [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam, 1, 0 } + [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0} + , + [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0} }; int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); diff --git a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h index 03382c0beee3..66dd75027967 100644 --- a/drivers/char/drm/i830_drm.h +++ b/drivers/char/drm/i830_drm.h @@ -33,14 +33,14 @@ #define I830_UPLOAD_CTX 0x1 #define I830_UPLOAD_BUFFERS 0x2 #define I830_UPLOAD_CLIPRECTS 0x4 -#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */ -#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */ -#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */ -#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */ -#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */ -#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */ -#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */ -#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */ +#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */ +#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */ +#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */ +#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */ +#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */ +#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */ +#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */ +#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */ #define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2)) #define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2)) #define I830_UPLOAD_TEXIMAGE_MASK 0xff00 @@ -65,7 +65,7 @@ * or in a piecewise fashion as required. */ -/* Destbuffer state +/* Destbuffer state * - backbuffer linear offset and pitch -- invarient in the current dri * - zbuffer linear offset and pitch -- also invarient * - drawing origin in back and depth buffers. @@ -103,7 +103,7 @@ #define I830_CTXREG_AA 9 #define I830_CTXREG_FOGCOLOR 10 #define I830_CTXREG_BLENDCOLR0 11 -#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */ +#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */ #define I830_CTXREG_VF 13 #define I830_CTXREG_VF2 14 #define I830_CTXREG_MCSB0 15 @@ -111,12 +111,11 @@ #define I830_CTX_SETUP_SIZE 17 /* 1.3: Stipple state - */ + */ #define I830_STPREG_ST0 0 #define I830_STPREG_ST1 1 #define I830_STP_SETUP_SIZE 2 - /* Texture state (per tex unit) */ @@ -132,23 +131,23 @@ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 -#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ #define I830_TEXREG_TM0S0 1 #define I830_TEXREG_TM0S1 2 #define I830_TEXREG_TM0S2 3 #define I830_TEXREG_TM0S3 4 #define I830_TEXREG_TM0S4 5 -#define I830_TEXREG_NOP0 6 /* noop */ -#define I830_TEXREG_NOP1 7 /* noop */ -#define I830_TEXREG_NOP2 8 /* noop */ -#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ #define __I830_TEX_SETUP_SIZE 10 #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 -#endif /* _I830_DEFINES_ */ +#endif /* _I830_DEFINES_ */ typedef struct _drm_i830_init { enum { @@ -177,19 +176,19 @@ typedef struct _drm_i830_init { * structure as well */ typedef struct _drm_i830_tex_region { - unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char next, prev; /* indices to form a circular LRU */ unsigned char in_use; /* owned by a client, or free? */ int age; /* tracked by clients to update local LRU's */ } drm_i830_tex_region_t; typedef struct _drm_i830_sarea { unsigned int ContextState[I830_CTX_SETUP_SIZE]; - unsigned int BufferState[I830_DEST_SETUP_SIZE]; + unsigned int BufferState[I830_DEST_SETUP_SIZE]; unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE]; unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT]; unsigned int Palette[2][256]; - unsigned int dirty; + unsigned int dirty; unsigned int nbox; drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS]; @@ -207,26 +206,26 @@ typedef struct _drm_i830_sarea { * texture space, and can make informed decisions as to which * areas to kick out. There is no need to choose whether to * kick out your own texture or someone else's - simply eject - * them all in LRU order. + * them all in LRU order. */ - drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS+1]; - /* Last elt is sentinal */ - int texAge; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ + drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS + 1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ - int last_quiescent; /* */ + int last_quiescent; /* */ int ctxOwner; /* last context to upload state */ int vertex_prim; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - - /* Here's the state for texunits 2,3: + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: */ unsigned int TexState2[I830_TEX_SETUP_SIZE]; unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; @@ -241,12 +240,11 @@ typedef struct _drm_i830_sarea { /* Flags for perf_boxes */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ /* I830 specific ioctls * The device specific ioctl range is 0x40 to 0x79. @@ -289,23 +287,21 @@ typedef struct _drm_i830_clear { unsigned int clear_depthmask; } drm_i830_clear_t; - - /* These may be placeholders if we have more cliprects than * I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to * false, indicating that the buffer will be dispatched again with a * new set of cliprects. */ typedef struct _drm_i830_vertex { - int idx; /* buffer index */ + int idx; /* buffer index */ int used; /* nr bytes in use */ int discard; /* client is finished with the buffer? */ } drm_i830_vertex_t; typedef struct _drm_i830_copy_t { - int idx; /* buffer index */ + int idx; /* buffer index */ int used; /* nr bytes in use */ - void __user *address; /* Address to copy from */ + void __user *address; /* Address to copy from */ } drm_i830_copy_t; typedef struct drm_i830_dma { @@ -315,7 +311,6 @@ typedef struct drm_i830_dma { int granted; } drm_i830_dma_t; - /* 1.3: Userspace can request & wait on irq's: */ typedef struct drm_i830_irq_emit { @@ -326,7 +321,6 @@ typedef struct drm_i830_irq_wait { int irq_seq; } drm_i830_irq_wait_t; - /* 1.3: New ioctl to query kernel params: */ #define I830_PARAM_IRQ_ACTIVE 1 @@ -336,7 +330,6 @@ typedef struct drm_i830_getparam { int __user *value; } drm_i830_getparam_t; - /* 1.3: New ioctl to set kernel params: */ #define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 @@ -346,5 +339,4 @@ typedef struct drm_i830_setparam { int value; } drm_i830_setparam_t; - -#endif /* _I830_DRM_H_ */ +#endif /* _I830_DRM_H_ */ diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c index 0da9cd19919e..6dad356450bc 100644 --- a/drivers/char/drm/i830_drv.c +++ b/drivers/char/drm/i830_drv.c @@ -40,36 +40,34 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; dev->types[7] = _DRM_STAT_PRIMARY; dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; - - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -81,7 +79,9 @@ extern drm_ioctl_desc_t i830_ioctls[]; extern int i830_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, + .driver_features = + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | + DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, #if USE_IRQS .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, #endif @@ -104,18 +104,19 @@ static struct drm_driver driver = { .version = version, .ioctls = i830_ioctls, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; @@ -133,6 +134,6 @@ static void __exit i830_exit(void) module_init(i830_init); module_exit(i830_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index 63f96a8b6a4a..99835465c44b 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -63,14 +63,14 @@ #define USE_IRQS 0 typedef struct drm_i830_buf_priv { - u32 *in_use; - int my_use_idx; + u32 *in_use; + int my_use_idx; int currently_mapped; void __user *virtual; void *kernel_virtual; } drm_i830_buf_priv_t; -typedef struct _drm_i830_ring_buffer{ +typedef struct _drm_i830_ring_buffer { int tail_mask; unsigned long Start; unsigned long End; @@ -86,17 +86,17 @@ typedef struct drm_i830_private { drm_map_t *mmio_map; drm_i830_sarea_t *sarea_priv; - drm_i830_ring_buffer_t ring; + drm_i830_ring_buffer_t ring; - void * hw_status_page; - unsigned long counter; + void *hw_status_page; + unsigned long counter; dma_addr_t dma_status_page; drm_buf_t *mmap_buffer; - + u32 front_di1, back_di1, zi1; - + int back_offset; int depth_offset; int front_offset; @@ -113,30 +113,30 @@ typedef struct drm_i830_private { int page_flipping; wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; + atomic_t irq_received; + atomic_t irq_emitted; int use_mi_batchbuffer_start; } drm_i830_private_t; /* i830_dma.c */ -extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp); +extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp); /* i830_irq.c */ -extern int i830_irq_emit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int i830_irq_wait( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int i830_irq_emit(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i830_irq_wait(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); -extern irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS ); -extern void i830_driver_irq_preinstall( drm_device_t *dev ); -extern void i830_driver_irq_postinstall( drm_device_t *dev ); -extern void i830_driver_irq_uninstall( drm_device_t *dev ); -extern void i830_driver_pretakedown(drm_device_t *dev); -extern void i830_driver_release(drm_device_t *dev, struct file *filp); -extern int i830_driver_dma_quiescent(drm_device_t *dev); -extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp); +extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); +extern void i830_driver_irq_preinstall(drm_device_t * dev); +extern void i830_driver_irq_postinstall(drm_device_t * dev); +extern void i830_driver_irq_uninstall(drm_device_t * dev); +extern void i830_driver_pretakedown(drm_device_t * dev); +extern void i830_driver_release(drm_device_t * dev, struct file *filp); +extern int i830_driver_dma_quiescent(drm_device_t * dev); +extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i830_driver_device_is_agp(drm_device_t * dev); #define I830_BASE(reg) ((unsigned long) \ @@ -149,8 +149,6 @@ extern int i830_driver_device_is_agp(drm_device_t * dev); #define I830_READ16(reg) I830_DEREF16(reg) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) - - #define I830_VERBOSE 0 #define RING_LOCALS unsigned int outring, ringmask, outcount; \ @@ -168,7 +166,6 @@ extern int i830_driver_device_is_agp(drm_device_t * dev); virt = dev_priv->ring.virtual_start; \ } while (0) - #define OUT_RING(n) do { \ if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ *(volatile unsigned int *)(virt + outring) = n; \ @@ -184,8 +181,7 @@ extern int i830_driver_device_is_agp(drm_device_t * dev); I830_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); - +extern int i830_wait_ring(drm_device_t * dev, int n, const char *caller); #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -200,7 +196,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 - #define BB1_START_ADDR_MASK (~0x7) #define BB1_PROTECTED (1<<0) #define BB1_UNPROTECTED (0<<0) @@ -213,7 +208,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); #define I830_IRQ_RESERVED ((1<<13)|(3<<2)) - #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 @@ -225,7 +219,7 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); #define RING_START 0x08 #define START_ADDR 0x0xFFFFF000 #define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 +#define RING_NR_PAGES 0x001FF000 #define RING_REPORT_MASK 0x00000006 #define RING_REPORT_64K 0x00000002 #define RING_REPORT_128K 0x00000004 @@ -291,10 +285,9 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); #define MI_BATCH_NON_SECURE (1) #define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) #define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) #endif - diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c index a5923e5d0a77..5841f7674956 100644 --- a/drivers/char/drm/i830_irq.c +++ b/drivers/char/drm/i830_irq.c @@ -9,11 +9,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -33,28 +33,27 @@ #include /* For task queue support */ #include - -irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS ) +irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *)arg; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u16 temp; + drm_device_t *dev = (drm_device_t *) arg; + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; + u16 temp; - temp = I830_READ16(I830REG_INT_IDENTITY_R); + temp = I830_READ16(I830REG_INT_IDENTITY_R); DRM_DEBUG("%x\n", temp); - if ( !( temp & 2 ) ) + if (!(temp & 2)) return IRQ_NONE; - I830_WRITE16(I830REG_INT_IDENTITY_R, temp); + I830_WRITE16(I830REG_INT_IDENTITY_R, temp); atomic_inc(&dev_priv->irq_received); - wake_up_interruptible(&dev_priv->irq_queue); + wake_up_interruptible(&dev_priv->irq_queue); return IRQ_HANDLED; } -static int i830_emit_irq(drm_device_t *dev) +static int i830_emit_irq(drm_device_t * dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -63,27 +62,25 @@ static int i830_emit_irq(drm_device_t *dev) atomic_inc(&dev_priv->irq_emitted); - BEGIN_LP_RING(2); - OUT_RING( 0 ); - OUT_RING( GFX_OP_USER_INTERRUPT ); - ADVANCE_LP_RING(); + BEGIN_LP_RING(2); + OUT_RING(0); + OUT_RING(GFX_OP_USER_INTERRUPT); + ADVANCE_LP_RING(); return atomic_read(&dev_priv->irq_emitted); } - -static int i830_wait_irq(drm_device_t *dev, int irq_nr) +static int i830_wait_irq(drm_device_t * dev, int irq_nr) { - drm_i830_private_t *dev_priv = - (drm_i830_private_t *)dev->dev_private; + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; DECLARE_WAITQUEUE(entry, current); - unsigned long end = jiffies + HZ*3; + unsigned long end = jiffies + HZ * 3; int ret = 0; DRM_DEBUG("%s\n", __FUNCTION__); - if (atomic_read(&dev_priv->irq_received) >= irq_nr) - return 0; + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + return 0; dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; @@ -91,21 +88,21 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr) for (;;) { __set_current_state(TASK_INTERRUPTIBLE); - if (atomic_read(&dev_priv->irq_received) >= irq_nr) - break; - if((signed)(end - jiffies) <= 0) { + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + break; + if ((signed)(end - jiffies) <= 0) { DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", - I830_READ16( I830REG_INT_IDENTITY_R ), - I830_READ16( I830REG_INT_MASK_R ), - I830_READ16( I830REG_INT_ENABLE_R ), - I830_READ16( I830REG_HWSTAM )); + I830_READ16(I830REG_INT_IDENTITY_R), + I830_READ16(I830REG_INT_MASK_R), + I830_READ16(I830REG_INT_ENABLE_R), + I830_READ16(I830REG_HWSTAM)); - ret = -EBUSY; /* Lockup? Missed irq? */ + ret = -EBUSY; /* Lockup? Missed irq? */ break; } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - ret = -EINTR; + schedule_timeout(HZ * 3); + if (signal_pending(current)) { + ret = -EINTR; break; } } @@ -115,89 +112,87 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr) return ret; } - /* Needs the lock as it touches the ring. */ -int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg ) +int i830_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_irq_emit_t emit; int result; LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - if (copy_from_user( &emit, (drm_i830_irq_emit_t __user *)arg, sizeof(emit) )) + if (copy_from_user + (&emit, (drm_i830_irq_emit_t __user *) arg, sizeof(emit))) return -EFAULT; - result = i830_emit_irq( dev ); + result = i830_emit_irq(dev); - if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (copy_to_user(emit.irq_seq, &result, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return -EFAULT; } return 0; } - /* Doesn't need the hardware lock. */ -int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg ) +int i830_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_irq_wait_t irqwait; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - if (copy_from_user( &irqwait, (drm_i830_irq_wait_t __user *)arg, - sizeof(irqwait) )) + if (copy_from_user(&irqwait, (drm_i830_irq_wait_t __user *) arg, + sizeof(irqwait))) return -EFAULT; - return i830_wait_irq( dev, irqwait.irq_seq ); + return i830_wait_irq(dev, irqwait.irq_seq); } - /* drm_dma.h hooks */ -void i830_driver_irq_preinstall( drm_device_t *dev ) { - drm_i830_private_t *dev_priv = - (drm_i830_private_t *)dev->dev_private; +void i830_driver_irq_preinstall(drm_device_t * dev) +{ + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - I830_WRITE16( I830REG_HWSTAM, 0xffff ); - I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); - I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + I830_WRITE16(I830REG_HWSTAM, 0xffff); + I830_WRITE16(I830REG_INT_MASK_R, 0x0); + I830_WRITE16(I830REG_INT_ENABLE_R, 0x0); atomic_set(&dev_priv->irq_received, 0); atomic_set(&dev_priv->irq_emitted, 0); init_waitqueue_head(&dev_priv->irq_queue); } -void i830_driver_irq_postinstall( drm_device_t *dev ) { - drm_i830_private_t *dev_priv = - (drm_i830_private_t *)dev->dev_private; +void i830_driver_irq_postinstall(drm_device_t * dev) +{ + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); + I830_WRITE16(I830REG_INT_ENABLE_R, 0x2); } -void i830_driver_irq_uninstall( drm_device_t *dev ) { - drm_i830_private_t *dev_priv = - (drm_i830_private_t *)dev->dev_private; +void i830_driver_irq_uninstall(drm_device_t * dev) +{ + drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; if (!dev_priv) return; - I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); - I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + I830_WRITE16(I830REG_INT_MASK_R, 0xffff); + I830_WRITE16(I830REG_INT_ENABLE_R, 0x0); } diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 34f552f90c4a..f0bb0bdbb6e2 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -85,14 +85,14 @@ static int i915_dma_cleanup(drm_device_t * dev) * is freed, it's too late. */ if (dev->irq) - drm_irq_uninstall (dev); + drm_irq_uninstall(dev); if (dev->dev_private) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree( &dev_priv->ring.map, dev); + drm_core_ioremapfree(&dev_priv->ring.map, dev); } if (dev_priv->status_page_dmah) { @@ -101,8 +101,8 @@ static int i915_dma_cleanup(drm_device_t * dev) I915_WRITE(0x02080, 0x1ffff000); } - drm_free (dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + drm_free(dev->dev_private, sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); dev->dev_private = NULL; } @@ -146,7 +146,7 @@ static int i915_initialize(drm_device_t * dev, dev_priv->ring.map.flags = 0; dev_priv->ring.map.mtrr = 0; - drm_core_ioremap( &dev_priv->ring.map, dev ); + drm_core_ioremap(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { dev->dev_private = (void *)dev_priv; @@ -243,8 +243,8 @@ static int i915_dma_init(DRM_IOCTL_ARGS) switch (init.func) { case I915_INIT_DMA: - dev_priv = drm_alloc (sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + dev_priv = drm_alloc(sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); if (dev_priv == NULL) return DRM_ERR(ENOMEM); retcode = i915_initialize(dev, dev_priv, &init); @@ -297,7 +297,7 @@ static int do_validate_cmd(int cmd) case 0x1c: return 1; case 0x1d: - switch ((cmd>>16)&0xff) { + switch ((cmd >> 16) & 0xff) { case 0x3: return (cmd & 0x1f) + 2; case 0x4: @@ -699,35 +699,46 @@ static int i915_setparam(DRM_IOCTL_ARGS) return 0; } -void i915_driver_pretakedown(drm_device_t *dev) +void i915_driver_pretakedown(drm_device_t * dev) { - if ( dev->dev_private ) { + if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_takedown( &(dev_priv->agp_heap) ); - } - i915_dma_cleanup( dev ); + i915_mem_takedown(&(dev_priv->agp_heap)); + } + i915_dma_cleanup(dev); } -void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp) +void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) { - if ( dev->dev_private ) { + if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release( dev, filp, dev_priv->agp_heap ); + i915_mem_release(dev, filp, dev_priv->agp_heap); } } drm_ioctl_desc_t i915_ioctls[] = { - [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1}, - [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1}, - [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0}, - [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1} + , + [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0} + , + [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1} + , [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0} }; diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 106b9ec02213..665da6ac11c6 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -34,36 +34,34 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; dev->types[7] = _DRM_STAT_PRIMARY; dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; - - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -75,8 +73,9 @@ extern drm_ioctl_desc_t i915_ioctls[]; extern int i915_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .driver_features = + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, .pretakedown = i915_driver_pretakedown, .prerelease = i915_driver_prerelease, .device_is_agp = i915_driver_device_is_agp, @@ -91,21 +90,21 @@ static struct drm_driver driver = { .version = version, .ioctls = i915_ioctls, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = i915_compat_ioctl, + .compat_ioctl = i915_compat_ioctl, #endif - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init i915_init(void) @@ -122,6 +121,6 @@ static void __exit i915_exit(void) module_init(i915_init); module_exit(i915_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 70ed4e68eac8..511ef1d87637 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -101,18 +101,18 @@ typedef struct drm_i915_private { /* i915_dma.c */ extern void i915_kernel_lost_context(drm_device_t * dev); -extern void i915_driver_pretakedown(drm_device_t *dev); -extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp); -extern int i915_driver_device_is_agp(drm_device_t *dev); +extern void i915_driver_pretakedown(drm_device_t * dev); +extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp); +extern int i915_driver_device_is_agp(drm_device_t * dev); /* i915_irq.c */ extern int i915_irq_emit(DRM_IOCTL_ARGS); extern int i915_irq_wait(DRM_IOCTL_ARGS); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); -extern void i915_driver_irq_preinstall(drm_device_t *dev); -extern void i915_driver_irq_postinstall(drm_device_t *dev); -extern void i915_driver_irq_uninstall(drm_device_t *dev); +extern void i915_driver_irq_preinstall(drm_device_t * dev); +extern void i915_driver_irq_postinstall(drm_device_t * dev); +extern void i915_driver_irq_uninstall(drm_device_t * dev); /* i915_mem.c */ extern int i915_mem_alloc(DRM_IOCTL_ARGS); @@ -125,7 +125,6 @@ extern void i915_mem_release(drm_device_t * dev, extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); - #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c index fe009e1b3a3f..2218a946ec87 100644 --- a/drivers/char/drm/i915_ioc32.c +++ b/drivers/char/drm/i915_ioc32.c @@ -3,7 +3,7 @@ * * 32-bit ioctl compatibility routines for the i915 DRM. * - * \author Alan Hourihane + * \author Alan Hourihane * * * Copyright (C) Paul Mackerras 2005 @@ -42,51 +42,55 @@ typedef struct _drm_i915_batchbuffer32 { int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ + u32 cliprects; /* pointer to userspace cliprects */ } drm_i915_batchbuffer32_t; static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_i915_batchbuffer32_t batchbuffer32; drm_i915_batchbuffer_t __user *batchbuffer; - - if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32))) + + if (copy_from_user + (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32))) return -EFAULT; - + batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer)); if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer)) || __put_user(batchbuffer32.start, &batchbuffer->start) || __put_user(batchbuffer32.used, &batchbuffer->used) || __put_user(batchbuffer32.DR1, &batchbuffer->DR1) || __put_user(batchbuffer32.DR4, &batchbuffer->DR4) - || __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects) + || __put_user(batchbuffer32.num_cliprects, + &batchbuffer->num_cliprects) || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects, &batchbuffer->cliprects)) return -EFAULT; - + return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer); + DRM_IOCTL_I915_BATCHBUFFER, + (unsigned long)batchbuffer); } typedef struct _drm_i915_cmdbuffer32 { - u32 buf; /* pointer to userspace command buffer */ + u32 buf; /* pointer to userspace command buffer */ int sz; /* nr bytes in buf */ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ + u32 cliprects; /* pointer to userspace cliprects */ } drm_i915_cmdbuffer32_t; static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_i915_cmdbuffer32_t cmdbuffer32; drm_i915_cmdbuffer_t __user *cmdbuffer; - - if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32))) + + if (copy_from_user + (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32))) return -EFAULT; - + cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer)); if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer)) || __put_user((int __user *)(unsigned long)cmdbuffer32.buf, @@ -98,9 +102,9 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects, &cmdbuffer->cliprects)) return -EFAULT; - + return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer); + DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); } typedef struct drm_i915_irq_emit32 { @@ -108,12 +112,12 @@ typedef struct drm_i915_irq_emit32 { } drm_i915_irq_emit32_t; static int compat_i915_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_i915_irq_emit32_t req32; drm_i915_irq_emit_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -123,7 +127,7 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request); + DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); } typedef struct drm_i915_getparam32 { int param; @@ -131,12 +135,12 @@ typedef struct drm_i915_getparam32 { } drm_i915_getparam32_t; static int compat_i915_getparam(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_i915_getparam32_t req32; drm_i915_getparam_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -147,7 +151,7 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_GETPARAM, (unsigned long) request); + DRM_IOCTL_I915_GETPARAM, (unsigned long)request); } typedef struct drm_i915_mem_alloc32 { @@ -158,12 +162,12 @@ typedef struct drm_i915_mem_alloc32 { } drm_i915_mem_alloc32_t; static int compat_i915_alloc(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_i915_mem_alloc32_t req32; drm_i915_mem_alloc_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -176,10 +180,9 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_ALLOC, (unsigned long) request); + DRM_IOCTL_I915_ALLOC, (unsigned long)request); } - drm_ioctl_compat_t *i915_compat_ioctls[] = { [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, @@ -197,8 +200,7 @@ drm_ioctl_compat_t *i915_compat_ioctls[] = { * \param arg user argument. * \return zero on success or negative number on failure. */ -long i915_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) +long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int nr = DRM_IOCTL_NR(cmd); drm_ioctl_compat_t *fn = NULL; @@ -206,13 +208,13 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); - + if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; lock_kernel(); /* XXX for now */ if (fn != NULL) - ret = (*fn)(filp, cmd, arg); + ret = (*fn) (filp, cmd, arg); else ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c index 9b1698f521be..13176d136a99 100644 --- a/drivers/char/drm/i915_mem.c +++ b/drivers/char/drm/i915_mem.c @@ -86,7 +86,7 @@ static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use) } /* Very simple allocator for agp memory, working on a static range - * already mapped into each client's address space. + * already mapped into each client's address space. */ static struct mem_block *split_block(struct mem_block *p, int start, int size, @@ -94,7 +94,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, { /* Maybe cut off the start of an existing block */ if (start > p->start) { - struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); if (!newblock) goto out; newblock->start = start; @@ -110,7 +111,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, /* Maybe cut off the end of an existing block */ if (size < p->size) { - struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); if (!newblock) goto out; newblock->start = start + size; diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c index fc7d4a594bca..cfbe35d5d862 100644 --- a/drivers/char/drm/mga_dma.c +++ b/drivers/char/drm/mga_dma.c @@ -28,7 +28,7 @@ /** * \file mga_dma.c * DMA support for MGA G200 / G400. - * + * * \author Rickard E. (Rik) Faith * \author Jeff Hartmann * \author Keith Whitwell @@ -44,40 +44,40 @@ #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 -static int mga_do_cleanup_dma( drm_device_t *dev ); +static int mga_do_cleanup_dma(drm_device_t * dev); /* ================================================================ * Engine control */ -int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) +int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) { u32 status = 0; int i; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; - if ( status == MGA_ENDPRDMASTS ) { - MGA_WRITE8( MGA_CRTC_INDEX, 0 ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; + if (status == MGA_ENDPRDMASTS) { + MGA_WRITE8(MGA_CRTC_INDEX, 0); return 0; } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if MGA_DMA_DEBUG - DRM_ERROR( "failed!\n" ); - DRM_INFO( " status=0x%08x\n", status ); + DRM_ERROR("failed!\n"); + DRM_INFO(" status=0x%08x\n", status); #endif return DRM_ERR(EBUSY); } -static int mga_do_dma_reset( drm_mga_private_t *dev_priv ) +static int mga_do_dma_reset(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* The primary DMA stream should look like new right about now. */ @@ -100,24 +100,25 @@ static int mga_do_dma_reset( drm_mga_private_t *dev_priv ) * Primary DMA stream */ -void mga_do_dma_flush( drm_mga_private_t *dev_priv ) +void mga_do_dma_flush(drm_mga_private_t * dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; u32 status = 0; int i; - DMA_LOCALS; - DRM_DEBUG( "\n" ); + DMA_LOCALS; + DRM_DEBUG("\n"); - /* We need to wait so that we can do an safe flush */ - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; - if ( status == MGA_ENDPRDMASTS ) break; - DRM_UDELAY( 1 ); + /* We need to wait so that we can do an safe flush */ + for (i = 0; i < dev_priv->usec_timeout; i++) { + status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; + if (status == MGA_ENDPRDMASTS) + break; + DRM_UDELAY(1); } - if ( primary->tail == primary->last_flush ) { - DRM_DEBUG( " bailing out...\n" ); + if (primary->tail == primary->last_flush) { + DRM_DEBUG(" bailing out...\n"); return; } @@ -127,48 +128,46 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) * actually (partially?) reads the first of these commands. * See page 4-16 in the G400 manual, middle of the page or so. */ - BEGIN_DMA( 1 ); + BEGIN_DMA(1); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); ADVANCE_DMA(); primary->last_flush = primary->tail; - head = MGA_READ( MGA_PRIMADDRESS ); + head = MGA_READ(MGA_PRIMADDRESS); - if ( head <= tail ) { + if (head <= tail) { primary->space = primary->size - primary->tail; } else { primary->space = head - tail; } - DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset ); - DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset ); - DRM_DEBUG( " space = 0x%06x\n", primary->space ); + DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); + DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset); + DRM_DEBUG(" space = 0x%06x\n", primary->space); mga_flush_write_combine(); MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - DRM_DEBUG( "done.\n" ); + DRM_DEBUG("done.\n"); } -void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) +void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); BEGIN_DMA_WRAP(); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); ADVANCE_DMA(); @@ -178,45 +177,43 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) primary->last_flush = 0; primary->last_wrap++; - head = MGA_READ( MGA_PRIMADDRESS ); + head = MGA_READ(MGA_PRIMADDRESS); - if ( head == dev_priv->primary->offset ) { + if (head == dev_priv->primary->offset) { primary->space = primary->size; } else { primary->space = head - dev_priv->primary->offset; } - DRM_DEBUG( " head = 0x%06lx\n", - head - dev_priv->primary->offset ); - DRM_DEBUG( " tail = 0x%06x\n", primary->tail ); - DRM_DEBUG( " wrap = %d\n", primary->last_wrap ); - DRM_DEBUG( " space = 0x%06x\n", primary->space ); + DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); + DRM_DEBUG(" tail = 0x%06x\n", primary->tail); + DRM_DEBUG(" wrap = %d\n", primary->last_wrap); + DRM_DEBUG(" space = 0x%06x\n", primary->space); mga_flush_write_combine(); MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - set_bit( 0, &primary->wrapped ); - DRM_DEBUG( "done.\n" ); + set_bit(0, &primary->wrapped); + DRM_DEBUG("done.\n"); } -void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) +void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); sarea_priv->last_wrap++; - DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); + DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap); mga_flush_write_combine(); - MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); + MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL); - clear_bit( 0, &primary->wrapped ); - DRM_DEBUG( "done.\n" ); + clear_bit(0, &primary->wrapped); + DRM_DEBUG("done.\n"); } - /* ================================================================ * Freelist management */ @@ -225,63 +222,61 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) #define MGA_BUFFER_FREE 0 #if MGA_FREELIST_DEBUG -static void mga_freelist_print( drm_device_t *dev ) +static void mga_freelist_print(drm_device_t * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; - DRM_INFO( "\n" ); - DRM_INFO( "current dispatch: last=0x%x done=0x%x\n", - dev_priv->sarea_priv->last_dispatch, - (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) - - dev_priv->primary->offset) ); - DRM_INFO( "current freelist:\n" ); + DRM_INFO("\n"); + DRM_INFO("current dispatch: last=0x%x done=0x%x\n", + dev_priv->sarea_priv->last_dispatch, + (unsigned int)(MGA_READ(MGA_PRIMADDRESS) - + dev_priv->primary->offset)); + DRM_INFO("current freelist:\n"); - for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) { - DRM_INFO( " %p idx=%2d age=0x%x 0x%06lx\n", - entry, entry->buf->idx, entry->age.head, - entry->age.head - dev_priv->primary->offset ); + for (entry = dev_priv->head->next; entry; entry = entry->next) { + DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", + entry, entry->buf->idx, entry->age.head, + entry->age.head - dev_priv->primary->offset); } - DRM_INFO( "\n" ); + DRM_INFO("\n"); } #endif -static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) +static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv) { drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; - DRM_DEBUG( "count=%d\n", dma->buf_count ); + DRM_DEBUG("count=%d\n", dma->buf_count); - dev_priv->head = drm_alloc( sizeof(drm_mga_freelist_t), - DRM_MEM_DRIVER ); - if ( dev_priv->head == NULL ) + dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); + if (dev_priv->head == NULL) return DRM_ERR(ENOMEM); - memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) ); - SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 ); + memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); + SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; - buf_priv = buf->dev_private; + buf_priv = buf->dev_private; - entry = drm_alloc( sizeof(drm_mga_freelist_t), - DRM_MEM_DRIVER ); - if ( entry == NULL ) + entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); + if (entry == NULL) return DRM_ERR(ENOMEM); - memset( entry, 0, sizeof(drm_mga_freelist_t) ); + memset(entry, 0, sizeof(drm_mga_freelist_t)); entry->next = dev_priv->head->next; entry->prev = dev_priv->head; - SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 ); + SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); entry->buf = buf; - if ( dev_priv->head->next != NULL ) + if (dev_priv->head->next != NULL) dev_priv->head->next->prev = entry; - if ( entry->next == NULL ) + if (entry->next == NULL) dev_priv->tail = entry; buf_priv->list_entry = entry; @@ -294,17 +289,17 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) return 0; } -static void mga_freelist_cleanup( drm_device_t *dev ) +static void mga_freelist_cleanup(drm_device_t * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; drm_mga_freelist_t *next; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); entry = dev_priv->head; - while ( entry ) { + while (entry) { next = entry->next; - drm_free( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); + drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); entry = next; } @@ -314,71 +309,69 @@ static void mga_freelist_cleanup( drm_device_t *dev ) #if 0 /* FIXME: Still needed? */ -static void mga_freelist_reset( drm_device_t *dev ) +static void mga_freelist_reset(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; int i; - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; - buf_priv = buf->dev_private; - SET_AGE( &buf_priv->list_entry->age, - MGA_BUFFER_FREE, 0 ); + buf_priv = buf->dev_private; + SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0); } } #endif -static drm_buf_t *mga_freelist_get( drm_device_t *dev ) +static drm_buf_t *mga_freelist_get(drm_device_t * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *next; drm_mga_freelist_t *prev; drm_mga_freelist_t *tail = dev_priv->tail; u32 head, wrap; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - head = MGA_READ( MGA_PRIMADDRESS ); + head = MGA_READ(MGA_PRIMADDRESS); wrap = dev_priv->sarea_priv->last_wrap; - DRM_DEBUG( " tail=0x%06lx %d\n", - tail->age.head ? - tail->age.head - dev_priv->primary->offset : 0, - tail->age.wrap ); - DRM_DEBUG( " head=0x%06lx %d\n", - head - dev_priv->primary->offset, wrap ); + DRM_DEBUG(" tail=0x%06lx %d\n", + tail->age.head ? + tail->age.head - dev_priv->primary->offset : 0, + tail->age.wrap); + DRM_DEBUG(" head=0x%06lx %d\n", + head - dev_priv->primary->offset, wrap); - if ( TEST_AGE( &tail->age, head, wrap ) ) { + if (TEST_AGE(&tail->age, head, wrap)) { prev = dev_priv->tail->prev; next = dev_priv->tail; prev->next = NULL; next->prev = next->next = NULL; dev_priv->tail = prev; - SET_AGE( &next->age, MGA_BUFFER_USED, 0 ); + SET_AGE(&next->age, MGA_BUFFER_USED, 0); return next->buf; } - DRM_DEBUG( "returning NULL!\n" ); + DRM_DEBUG("returning NULL!\n"); return NULL; } -int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) +int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *head, *entry, *prev; - DRM_DEBUG( "age=0x%06lx wrap=%d\n", - buf_priv->list_entry->age.head - - dev_priv->primary->offset, - buf_priv->list_entry->age.wrap ); + DRM_DEBUG("age=0x%06lx wrap=%d\n", + buf_priv->list_entry->age.head - + dev_priv->primary->offset, buf_priv->list_entry->age.wrap); entry = buf_priv->list_entry; head = dev_priv->head; - if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { - SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 ); + if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) { + SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); prev = dev_priv->tail; prev->next = entry; entry->prev = prev; @@ -394,15 +387,13 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) return 0; } - /* ================================================================ * DMA initialization, cleanup */ - -int mga_driver_preinit(drm_device_t *dev, unsigned long flags) +int mga_driver_preinit(drm_device_t * dev, unsigned long flags) { - drm_mga_private_t * dev_priv; + drm_mga_private_t *dev_priv; dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); if (!dev_priv) @@ -420,7 +411,7 @@ int mga_driver_preinit(drm_device_t *dev, unsigned long flags) #if __OS_HAS_AGP /** * Bootstrap the driver for AGP DMA. - * + * * \todo * Investigate whether there is any benifit to storing the WARP microcode in * AGP memory. If not, the microcode may as well always be put in PCI @@ -436,18 +427,18 @@ int mga_driver_preinit(drm_device_t *dev, unsigned long flags) static int mga_do_agp_dma_bootstrap(drm_device_t * dev, drm_mga_dma_bootstrap_t * dma_bs) { - drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; const unsigned int warp_size = mga_warp_microcode_size(dev_priv); int err; - unsigned offset; + unsigned offset; const unsigned secondary_size = dma_bs->secondary_bin_count - * dma_bs->secondary_bin_size; + * dma_bs->secondary_bin_size; const unsigned agp_size = (dma_bs->agp_size << 20); drm_buf_desc_t req; drm_agp_mode_t mode; drm_agp_info_t info; - /* Acquire AGP. */ err = drm_agp_acquire(dev); if (err) { @@ -468,7 +459,6 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, return err; } - /* In addition to the usual AGP mode configuration, the G200 AGP cards * need to have the AGP mode "manually" set. */ @@ -476,68 +466,66 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, if (dev_priv->chipset == MGA_CARD_TYPE_G200) { if (mode.mode & 0x02) { MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); - } - else { + } else { MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); } } - /* Allocate and bind AGP memory. */ dev_priv->agp_pages = agp_size / PAGE_SIZE; - dev_priv->agp_mem = drm_alloc_agp( dev, dev_priv->agp_pages, 0 ); + dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0); if (dev_priv->agp_mem == NULL) { dev_priv->agp_pages = 0; DRM_ERROR("Unable to allocate %uMB AGP memory\n", dma_bs->agp_size); return DRM_ERR(ENOMEM); } - - err = drm_bind_agp( dev_priv->agp_mem, 0 ); + + err = drm_bind_agp(dev_priv->agp_mem, 0); if (err) { DRM_ERROR("Unable to bind AGP memory\n"); return err; } offset = 0; - err = drm_addmap( dev, offset, warp_size, - _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp ); + err = drm_addmap(dev, offset, warp_size, + _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); if (err) { DRM_ERROR("Unable to map WARP microcode\n"); return err; } offset += warp_size; - err = drm_addmap( dev, offset, dma_bs->primary_size, - _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary ); + err = drm_addmap(dev, offset, dma_bs->primary_size, + _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); if (err) { DRM_ERROR("Unable to map primary DMA region\n"); return err; } offset += dma_bs->primary_size; - err = drm_addmap( dev, offset, secondary_size, - _DRM_AGP, 0, & dev->agp_buffer_map ); + err = drm_addmap(dev, offset, secondary_size, + _DRM_AGP, 0, &dev->agp_buffer_map); if (err) { DRM_ERROR("Unable to map secondary DMA region\n"); return err; } - (void) memset( &req, 0, sizeof(req) ); + (void)memset(&req, 0, sizeof(req)); req.count = dma_bs->secondary_bin_count; req.size = dma_bs->secondary_bin_size; req.flags = _DRM_AGP_BUFFER; req.agp_start = offset; - err = drm_addbufs_agp( dev, & req ); + err = drm_addbufs_agp(dev, &req); if (err) { DRM_ERROR("Unable to add secondary DMA buffers\n"); return err; } offset += secondary_size; - err = drm_addmap( dev, offset, agp_size - offset, - _DRM_AGP, 0, & dev_priv->agp_textures ); + err = drm_addmap(dev, offset, agp_size - offset, + _DRM_AGP, 0, &dev_priv->agp_textures); if (err) { DRM_ERROR("Unable to map AGP texture region\n"); return err; @@ -571,7 +559,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, /** * Bootstrap the driver for PCI DMA. - * + * * \todo * The algorithm for decreasing the size of the primary DMA buffer could be * better. The size should be rounded up to the nearest page size, then @@ -580,20 +568,20 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, * \todo * Determine whether the maximum address passed to drm_pci_alloc is correct. * The same goes for drm_addbufs_pci. - * + * * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap */ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, drm_mga_dma_bootstrap_t * dma_bs) { - drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; const unsigned int warp_size = mga_warp_microcode_size(dev_priv); unsigned int primary_size; unsigned int bin_count; int err; drm_buf_desc_t req; - if (dev->dma == NULL) { DRM_ERROR("dev->dma is NULL\n"); return DRM_ERR(EFAULT); @@ -612,9 +600,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, * alignment of the primary or secondary DMA buffers. */ - for ( primary_size = dma_bs->primary_size - ; primary_size != 0 - ; primary_size >>= 1 ) { + for (primary_size = dma_bs->primary_size; primary_size != 0; + primary_size >>= 1) { /* The proper alignment for this mapping is 0x04 */ err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT, _DRM_READ_ONLY, &dev_priv->primary); @@ -629,24 +616,23 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, if (dev_priv->primary->size != dma_bs->primary_size) { DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n", - dma_bs->primary_size, - (unsigned) dev_priv->primary->size); + dma_bs->primary_size, + (unsigned)dev_priv->primary->size); dma_bs->primary_size = dev_priv->primary->size; } - for ( bin_count = dma_bs->secondary_bin_count - ; bin_count > 0 - ; bin_count-- ) { - (void) memset( &req, 0, sizeof(req) ); + for (bin_count = dma_bs->secondary_bin_count; bin_count > 0; + bin_count--) { + (void)memset(&req, 0, sizeof(req)); req.count = bin_count; req.size = dma_bs->secondary_bin_size; - err = drm_addbufs_pci( dev, & req ); + err = drm_addbufs_pci(dev, &req); if (!err) { break; } } - + if (bin_count == 0) { DRM_ERROR("Unable to add secondary DMA buffers\n"); return err; @@ -668,38 +654,34 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, return 0; } - static int mga_do_dma_bootstrap(drm_device_t * dev, drm_mga_dma_bootstrap_t * dma_bs) { const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); int err; - drm_mga_private_t * const dev_priv = - (drm_mga_private_t *) dev->dev_private; - + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; dev_priv->used_new_dma_init = 1; /* The first steps are the same for both PCI and AGP based DMA. Map * the cards MMIO registers and map a status page. */ - err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size, - _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio ); + err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); if (err) { DRM_ERROR("Unable to map MMIO region\n"); return err; } - - err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM, - _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, - & dev_priv->status ); + err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, + _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, + &dev_priv->status); if (err) { DRM_ERROR("Unable to map status region\n"); return err; } - /* The DMA initialization procedure is slightly different for PCI and * AGP cards. AGP cards just allocate a large block of AGP memory and * carve off portions of it for internal uses. The remaining memory @@ -708,7 +690,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, if (is_agp) { err = mga_do_agp_dma_bootstrap(dev, dma_bs); } - + /* If we attempted to initialize the card for AGP DMA but failed, * clean-up any mess that may have been created. */ @@ -717,7 +699,6 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, mga_do_cleanup_dma(dev); } - /* Not only do we want to try and initialized PCI cards for PCI DMA, * but we also try to initialized AGP cards that could not be * initialized for AGP DMA. This covers the case where we have an AGP @@ -730,7 +711,6 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, err = mga_do_pci_dma_bootstrap(dev, dma_bs); } - return err; } @@ -740,45 +720,42 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS) drm_mga_dma_bootstrap_t bootstrap; int err; - DRM_COPY_FROM_USER_IOCTL(bootstrap, (drm_mga_dma_bootstrap_t __user *) data, sizeof(bootstrap)); - err = mga_do_dma_bootstrap(dev, & bootstrap); - if (! err) { + err = mga_do_dma_bootstrap(dev, &bootstrap); + if (!err) { static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; - const drm_mga_private_t * const dev_priv = - (drm_mga_private_t *) dev->dev_private; + const drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; if (dev_priv->agp_textures != NULL) { - bootstrap.texture_handle = dev_priv->agp_textures->offset; + bootstrap.texture_handle = + dev_priv->agp_textures->offset; bootstrap.texture_size = dev_priv->agp_textures->size; - } - else { + } else { bootstrap.texture_handle = 0; bootstrap.texture_size = 0; } - bootstrap.agp_mode = modes[ bootstrap.agp_mode & 0x07 ]; - if (DRM_COPY_TO_USER( (void __user *) data, & bootstrap, + bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; + if (DRM_COPY_TO_USER((void __user *)data, &bootstrap, sizeof(bootstrap))) { err = DRM_ERR(EFAULT); } - } - else { + } else { mga_do_cleanup_dma(dev); } return err; } -static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) +static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) { drm_mga_private_t *dev_priv; int ret; - DRM_DEBUG( "\n" ); - + DRM_DEBUG("\n"); dev_priv = dev->dev_private; @@ -787,17 +764,17 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) } else { dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; } - dev_priv->maccess = init->maccess; + dev_priv->maccess = init->maccess; - dev_priv->fb_cpp = init->fb_cpp; - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; + dev_priv->fb_cpp = init->fb_cpp; + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_cpp = init->depth_cpp; - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; + dev_priv->depth_cpp = init->depth_cpp; + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; /* FIXME: Need to support AGP textures... */ @@ -811,7 +788,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) return DRM_ERR(EINVAL); } - if (! dev_priv->used_new_dma_init) { + if (!dev_priv->used_new_dma_init) { dev_priv->status = drm_core_findmap(dev, init->status_offset); if (!dev_priv->status) { DRM_ERROR("failed to find status page!\n"); @@ -833,7 +810,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) return DRM_ERR(EINVAL); } dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); + dev->agp_buffer_map = + drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("failed to find dma buffer region!\n"); return DRM_ERR(EINVAL); @@ -845,8 +823,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) } dev_priv->sarea_priv = - (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + - init->sarea_priv_offset); + (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle + + init->sarea_priv_offset); if (!dev_priv->warp->handle || !dev_priv->primary->handle || @@ -869,23 +847,20 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) return ret; } - dev_priv->prim.status = (u32 *)dev_priv->status->handle; + dev_priv->prim.status = (u32 *) dev_priv->status->handle; - mga_do_wait_for_idle( dev_priv ); + mga_do_wait_for_idle(dev_priv); /* Init the primary DMA registers. */ - MGA_WRITE( MGA_PRIMADDRESS, - dev_priv->primary->offset | MGA_DMA_GENERAL ); + MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL); #if 0 - MGA_WRITE( MGA_PRIMPTR, - virt_to_bus((void *)dev_priv->prim.status) | - MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ - MGA_PRIMPTREN1 ); /* DWGSYNC */ + MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ + MGA_PRIMPTREN1); /* DWGSYNC */ #endif - dev_priv->prim.start = (u8 *)dev_priv->primary->handle; - dev_priv->prim.end = ((u8 *)dev_priv->primary->handle + dev_priv->prim.start = (u8 *) dev_priv->primary->handle; + dev_priv->prim.end = ((u8 *) dev_priv->primary->handle + dev_priv->primary->size); dev_priv->prim.size = dev_priv->primary->size; @@ -913,7 +888,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) return 0; } -static int mga_do_cleanup_dma( drm_device_t *dev ) +static int mga_do_cleanup_dma(drm_device_t * dev) { int err = 0; DRM_DEBUG("\n"); @@ -922,16 +897,17 @@ static int mga_do_cleanup_dma( drm_device_t *dev ) * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq_enabled ) drm_irq_uninstall(dev); + if (dev->irq_enabled) + drm_irq_uninstall(dev); - if ( dev->dev_private ) { + if (dev->dev_private) { drm_mga_private_t *dev_priv = dev->dev_private; - if ((dev_priv->warp != NULL) + if ((dev_priv->warp != NULL) && (dev_priv->mmio->type != _DRM_CONSISTENT)) drm_core_ioremapfree(dev_priv->warp, dev); - if ((dev_priv->primary != NULL) + if ((dev_priv->primary != NULL) && (dev_priv->primary->type != _DRM_CONSISTENT)) drm_core_ioremapfree(dev_priv->primary, dev); @@ -944,7 +920,8 @@ static int mga_do_cleanup_dma( drm_device_t *dev ) dev_priv->agp_textures = NULL; drm_unbind_agp(dev_priv->agp_mem); - drm_free_agp(dev_priv->agp_mem, dev_priv->agp_pages); + drm_free_agp(dev_priv->agp_mem, + dev_priv->agp_pages); dev_priv->agp_pages = 0; dev_priv->agp_mem = NULL; } @@ -966,7 +943,8 @@ static int mga_do_cleanup_dma( drm_device_t *dev ) memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); dev_priv->warp_pipe = 0; - memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); + memset(dev_priv->warp_pipe_phys, 0, + sizeof(dev_priv->warp_pipe_phys)); if (dev_priv->head != NULL) { mga_freelist_cleanup(dev); @@ -976,103 +954,102 @@ static int mga_do_cleanup_dma( drm_device_t *dev ) return err; } -int mga_dma_init( DRM_IOCTL_ARGS ) +int mga_dma_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_init_t init; int err; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); DRM_COPY_FROM_USER_IOCTL(init, (drm_mga_init_t __user *) data, sizeof(init)); - switch ( init.func ) { + switch (init.func) { case MGA_INIT_DMA: err = mga_do_init_dma(dev, &init); if (err) { - (void) mga_do_cleanup_dma(dev); + (void)mga_do_cleanup_dma(dev); } return err; case MGA_CLEANUP_DMA: - return mga_do_cleanup_dma( dev ); + return mga_do_cleanup_dma(dev); } return DRM_ERR(EINVAL); } - /* ================================================================ * Primary DMA stream management */ -int mga_dma_flush( DRM_IOCTL_ARGS ) +int mga_dma_flush(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_lock_t lock; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t __user *)data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t __user *) data, + sizeof(lock)); - DRM_DEBUG( "%s%s%s\n", - (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", - (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", - (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" ); + DRM_DEBUG("%s%s%s\n", + (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", + (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", + (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); - WRAP_WAIT_WITH_RETURN( dev_priv ); + WRAP_WAIT_WITH_RETURN(dev_priv); - if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) { - mga_do_dma_flush( dev_priv ); + if (lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { + mga_do_dma_flush(dev_priv); } - if ( lock.flags & _DRM_LOCK_QUIESCENT ) { + if (lock.flags & _DRM_LOCK_QUIESCENT) { #if MGA_DMA_DEBUG - int ret = mga_do_wait_for_idle( dev_priv ); - if ( ret < 0 ) - DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); + int ret = mga_do_wait_for_idle(dev_priv); + if (ret < 0) + DRM_INFO("%s: -EBUSY\n", __FUNCTION__); return ret; #else - return mga_do_wait_for_idle( dev_priv ); + return mga_do_wait_for_idle(dev_priv); #endif } else { return 0; } } -int mga_dma_reset( DRM_IOCTL_ARGS ) +int mga_dma_reset(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - return mga_do_dma_reset( dev_priv ); + return mga_do_dma_reset(dev_priv); } - /* ================================================================ * DMA buffer management */ -static int mga_dma_get_buffers( DRMFILE filp, - drm_device_t *dev, drm_dma_t *d ) +static int mga_dma_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d) { drm_buf_t *buf; int i; - for ( i = d->granted_count ; i < d->request_count ; i++ ) { - buf = mga_freelist_get( dev ); - if ( !buf ) return DRM_ERR(EAGAIN); + for (i = d->granted_count; i < d->request_count; i++) { + buf = mga_freelist_get(dev); + if (!buf) + return DRM_ERR(EAGAIN); buf->filp = filp; - if ( DRM_COPY_TO_USER( &d->request_indices[i], - &buf->idx, sizeof(buf->idx) ) ) + if (DRM_COPY_TO_USER(&d->request_indices[i], + &buf->idx, sizeof(buf->idx))) return DRM_ERR(EFAULT); - if ( DRM_COPY_TO_USER( &d->request_sizes[i], - &buf->total, sizeof(buf->total) ) ) + if (DRM_COPY_TO_USER(&d->request_sizes[i], + &buf->total, sizeof(buf->total))) return DRM_ERR(EFAULT); d->granted_count++; @@ -1080,44 +1057,44 @@ static int mga_dma_get_buffers( DRMFILE filp, return 0; } -int mga_dma_buffers( DRM_IOCTL_ARGS ) +int mga_dma_buffers(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_dma_t __user *argp = (void __user *)data; drm_dma_t d; int ret = 0; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) ); + DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); /* Please don't send us buffers. */ - if ( d.send_count != 0 ) { - DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count ); + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count); return DRM_ERR(EINVAL); } /* We'll send you buffers. */ - if ( d.request_count < 0 || d.request_count > dma->buf_count ) { - DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count ); + if (d.request_count < 0 || d.request_count > dma->buf_count) { + DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", + DRM_CURRENTPID, d.request_count, dma->buf_count); return DRM_ERR(EINVAL); } - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); d.granted_count = 0; - if ( d.request_count ) { - ret = mga_dma_get_buffers( filp, dev, &d ); + if (d.request_count) { + ret = mga_dma_get_buffers(filp, dev, &d); } - DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) ); + DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); return ret; } @@ -1138,11 +1115,11 @@ int mga_driver_postcleanup(drm_device_t * dev) */ void mga_driver_pretakedown(drm_device_t * dev) { - mga_do_cleanup_dma( dev ); + mga_do_cleanup_dma(dev); } -int mga_driver_dma_quiescent(drm_device_t *dev) +int mga_driver_dma_quiescent(drm_device_t * dev) { drm_mga_private_t *dev_priv = dev->dev_private; - return mga_do_wait_for_idle( dev_priv ); + return mga_do_wait_for_idle(dev_priv); } diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h index d20aab3bd57b..44d1293e2947 100644 --- a/drivers/char/drm/mga_drm.h +++ b/drivers/char/drm/mga_drm.h @@ -44,10 +44,10 @@ /* WARP pipe flags */ -#define MGA_F 0x1 /* fog */ -#define MGA_A 0x2 /* alpha */ -#define MGA_S 0x4 /* specular */ -#define MGA_T2 0x8 /* multitexture */ +#define MGA_F 0x1 /* fog */ +#define MGA_A 0x2 /* alpha */ +#define MGA_S 0x4 /* specular */ +#define MGA_T2 0x8 /* multitexture */ #define MGA_WARP_TGZ 0 #define MGA_WARP_TGZF (MGA_F) @@ -66,14 +66,14 @@ #define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) #define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) -#define MGA_MAX_G200_PIPES 8 /* no multitex */ +#define MGA_MAX_G200_PIPES 8 /* no multitex */ #define MGA_MAX_G400_PIPES 16 #define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES -#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ +#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 -#define MGA_CARD_TYPE_G450 3 /* not currently used */ +#define MGA_CARD_TYPE_G450 3 /* not currently used */ #define MGA_CARD_TYPE_G550 4 #define MGA_FRONT 0x1 @@ -86,14 +86,14 @@ #define MGA_UPLOAD_TEX0 0x2 #define MGA_UPLOAD_TEX1 0x4 #define MGA_UPLOAD_PIPE 0x8 -#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ -#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ +#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ +#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ #define MGA_UPLOAD_2D 0x40 -#define MGA_WAIT_AGE 0x80 /* handled client-side */ -#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ +#define MGA_WAIT_AGE 0x80 /* handled client-side */ +#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ #if 0 -#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock - quiescent */ +#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock + quiescent */ #endif /* 32 buffers of 64k each, total 2 meg. @@ -120,8 +120,7 @@ #define DRM_MGA_IDLE_RETRY 2048 -#endif /* __MGA_SAREA_DEFINES__ */ - +#endif /* __MGA_SAREA_DEFINES__ */ /* Setup registers for 3D context */ @@ -165,25 +164,25 @@ typedef struct { /* General aging mechanism */ typedef struct { - unsigned int head; /* Position of head pointer */ - unsigned int wrap; /* Primary DMA wrap count */ + unsigned int head; /* Position of head pointer */ + unsigned int wrap; /* Primary DMA wrap count */ } drm_mga_age_t; typedef struct _drm_mga_sarea { /* The channel for communication of state information to the kernel * on firing a vertex dma buffer. */ - drm_mga_context_regs_t context_state; - drm_mga_server_regs_t server_state; - drm_mga_texture_regs_t tex_state[2]; - unsigned int warp_pipe; - unsigned int dirty; - unsigned int vertsize; + drm_mga_context_regs_t context_state; + drm_mga_server_regs_t server_state; + drm_mga_texture_regs_t tex_state[2]; + unsigned int warp_pipe; + unsigned int dirty; + unsigned int vertsize; /* The current cliprects, or a subset thereof. */ - drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; - unsigned int nbox; + drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; + unsigned int nbox; /* Information about the most recently used 3d drawable. The * client fills in the req_* fields, the server fills in the @@ -192,18 +191,18 @@ typedef struct _drm_mga_sarea { * The client clears the exported_drawable field before * clobbering the boxes data. */ - unsigned int req_drawable; /* the X drawable id */ - unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ + unsigned int req_drawable; /* the X drawable id */ + unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ - unsigned int exported_drawable; + unsigned int exported_drawable; unsigned int exported_index; - unsigned int exported_stamp; - unsigned int exported_buffers; - unsigned int exported_nfront; - unsigned int exported_nback; + unsigned int exported_stamp; + unsigned int exported_buffers; + unsigned int exported_nfront; + unsigned int exported_nback; int exported_back_x, exported_front_x, exported_w; int exported_back_y, exported_front_y, exported_h; - drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; /* Counters for aging textures and for client-side throttling. */ @@ -211,21 +210,20 @@ typedef struct _drm_mga_sarea { unsigned int last_wrap; drm_mga_age_t last_frame; - unsigned int last_enqueue; /* last time a buffer was enqueued */ + unsigned int last_enqueue; /* last time a buffer was enqueued */ unsigned int last_dispatch; /* age of the most recently dispatched buffer */ - unsigned int last_quiescent; /* */ + unsigned int last_quiescent; /* */ /* LRU lists for texture memory in agp space and on the card. */ - drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; + drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1]; unsigned int texAge[MGA_NR_TEX_HEAPS]; /* Mechanism to validate card state. */ - int ctxOwner; + int ctxOwner; } drm_mga_sarea_t; - /* MGA specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ @@ -247,7 +245,6 @@ typedef struct _drm_mga_sarea { #define DRM_MGA_WAIT_FENCE 0x0b #define DRM_MGA_DMA_BOOTSTRAP 0x0c - #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) @@ -263,33 +260,33 @@ typedef struct _drm_mga_sarea { #define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t) typedef struct _drm_mga_warp_index { - int installed; - unsigned long phys_addr; - int size; + int installed; + unsigned long phys_addr; + int size; } drm_mga_warp_index_t; typedef struct drm_mga_init { - enum { - MGA_INIT_DMA = 0x01, - MGA_CLEANUP_DMA = 0x02 + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 } func; - unsigned long sarea_priv_offset; + unsigned long sarea_priv_offset; int chipset; - int sgram; + int sgram; unsigned int maccess; - unsigned int fb_cpp; + unsigned int fb_cpp; unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; + unsigned int back_offset, back_pitch; - unsigned int depth_cpp; - unsigned int depth_offset, depth_pitch; + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; - unsigned int texture_offset[MGA_NR_TEX_HEAPS]; - unsigned int texture_size[MGA_NR_TEX_HEAPS]; + unsigned int texture_offset[MGA_NR_TEX_HEAPS]; + unsigned int texture_size[MGA_NR_TEX_HEAPS]; unsigned long fb_offset; unsigned long mmio_offset; @@ -302,64 +299,59 @@ typedef struct drm_mga_init { typedef struct drm_mga_dma_bootstrap { /** * \name AGP texture region - * + * * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will * be filled in with the actual AGP texture settings. - * + * * \warning * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode * is zero, it means that PCI memory (most likely through the use of * an IOMMU) is being used for "AGP" textures. */ - /*@{*/ + /*@{ */ unsigned long texture_handle; /**< Handle used to map AGP textures. */ - uint32_t texture_size; /**< Size of the AGP texture region. */ - /*@}*/ - + uint32_t texture_size; /**< Size of the AGP texture region. */ + /*@} */ /** * Requested size of the primary DMA region. - * + * * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be * filled in with the actual AGP mode. If AGP was not available */ uint32_t primary_size; - /** * Requested number of secondary DMA buffers. - * + * * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be * filled in with the actual number of secondary DMA buffers * allocated. Particularly when PCI DMA is used, this may be * (subtantially) less than the number requested. */ uint32_t secondary_bin_count; - - + /** * Requested size of each secondary DMA buffer. - * + * * While the kernel \b is free to reduce * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed * to reduce dma_mga_dma_bootstrap::secondary_bin_size. */ uint32_t secondary_bin_size; - /** * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X, * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is * zero, it means that PCI DMA should be used, even if AGP is * possible. - * + * * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be * filled in with the actual AGP mode. If AGP was not available * (i.e., PCI DMA was used), this value will be zero. */ uint32_t agp_mode; - /** * Desired AGP GART size, measured in megabytes. */ @@ -375,16 +367,16 @@ typedef struct drm_mga_clear { } drm_mga_clear_t; typedef struct drm_mga_vertex { - int idx; /* buffer to queue */ - int used; /* bytes in use */ - int discard; /* client finished with buffer? */ + int idx; /* buffer to queue */ + int used; /* bytes in use */ + int discard; /* client finished with buffer? */ } drm_mga_vertex_t; typedef struct drm_mga_indices { - int idx; /* buffer to queue */ + int idx; /* buffer to queue */ unsigned int start; unsigned int end; - int discard; /* client finished with buffer? */ + int discard; /* client finished with buffer? */ } drm_mga_indices_t; typedef struct drm_mga_iload { @@ -400,12 +392,12 @@ typedef struct _drm_mga_blit { int src_pitch, dst_pitch; int delta_sx, delta_sy; int delta_dx, delta_dy; - int height, ydir; /* flip image vertically */ + int height, ydir; /* flip image vertically */ int source_pitch, dest_pitch; } drm_mga_blit_t; /* 3.1: An ioctl to get parameters that aren't available to the 3d - * client any other way. + * client any other way. */ #define MGA_PARAM_IRQ_NR 1 diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index daabbba3b297..220037a91c09 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -35,14 +35,13 @@ #include "mga_drm.h" #include "mga_drv.h" - #include "drm_pciids.h" static int mga_driver_device_is_agp(drm_device_t * dev); -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { - drm_mga_private_t * const dev_priv = - (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); @@ -52,28 +51,26 @@ static int postinit( struct drm_device *dev, unsigned long flags ) dev->types[7] = _DRM_STAT_PRIMARY; dev->types[8] = _DRM_STAT_SECONDARY; - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -85,7 +82,10 @@ extern drm_ioctl_desc_t mga_ioctls[]; extern int mga_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + .driver_features = + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .preinit = mga_driver_preinit, .postcleanup = mga_driver_postcleanup, .pretakedown = mga_driver_pretakedown, @@ -104,21 +104,21 @@ static struct drm_driver driver = { .ioctls = mga_ioctls, .dma_ioctl = mga_dma_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = mga_compat_ioctl, + .compat_ioctl = mga_compat_ioctl, #endif - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init mga_init(void) @@ -135,8 +135,8 @@ static void __exit mga_exit(void) module_init(mga_init); module_exit(mga_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); /** @@ -153,8 +153,7 @@ MODULE_LICENSE("GPL and additional rights"); */ int mga_driver_device_is_agp(drm_device_t * dev) { - const struct pci_dev * const pdev = dev->pdev; - + const struct pci_dev *const pdev = dev->pdev; /* There are PCI versions of the G450. These cards have the * same PCI ID as the AGP G450, but have an additional PCI-to-PCI @@ -164,10 +163,10 @@ int mga_driver_device_is_agp(drm_device_t * dev) * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the * device. */ - - if ( (pdev->device == 0x0525) - && (pdev->bus->self->vendor == 0x3388) - && (pdev->bus->self->device == 0x0021) ) { + + if ((pdev->device == 0x0525) + && (pdev->bus->self->vendor == 0x3388) + && (pdev->bus->self->device == 0x0021)) { return 0; } diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index b22fdbd4f830..05f0f913dedd 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h @@ -62,14 +62,14 @@ typedef struct drm_mga_primary_buffer { } drm_mga_primary_buffer_t; typedef struct drm_mga_freelist { - struct drm_mga_freelist *next; - struct drm_mga_freelist *prev; + struct drm_mga_freelist *next; + struct drm_mga_freelist *prev; drm_mga_age_t age; - drm_buf_t *buf; + drm_buf_t *buf; } drm_mga_freelist_t; typedef struct { - drm_mga_freelist_t *list_entry; + drm_mga_freelist_t *list_entry; int discard; int dispatched; } drm_mga_buf_priv_t; @@ -78,8 +78,8 @@ typedef struct drm_mga_private { drm_mga_primary_buffer_t prim; drm_mga_sarea_t *sarea_priv; - drm_mga_freelist_t *head; - drm_mga_freelist_t *tail; + drm_mga_freelist_t *head; + drm_mga_freelist_t *tail; unsigned int warp_pipe; unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES]; @@ -109,13 +109,13 @@ typedef struct drm_mga_private { /** * \name MMIO region parameters. - * + * * \sa drm_mga_private_t::mmio */ - /*@{*/ - u32 mmio_base; /**< Bus address of base of MMIO. */ - u32 mmio_size; /**< Size of the MMIO region. */ - /*@}*/ + /*@{ */ + u32 mmio_base; /**< Bus address of base of MMIO. */ + u32 mmio_size; /**< Size of the MMIO region. */ + /*@} */ u32 clear_cmd; u32 maccess; @@ -143,7 +143,7 @@ typedef struct drm_mga_private { drm_local_map_t *warp; drm_local_map_t *primary; drm_local_map_t *agp_textures; - + DRM_AGP_MEM *agp_mem; unsigned int agp_pages; } drm_mga_private_t; @@ -165,7 +165,7 @@ extern void mga_do_dma_flush(drm_mga_private_t * dev_priv); extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv); extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); -extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); +extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf); /* mga_warp.c */ extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); @@ -196,7 +196,7 @@ extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, #define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) #define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) -static inline u32 _MGA_READ(u32 *addr) +static inline u32 _MGA_READ(u32 * addr) { DRM_MEMORYBARRIER(); return *(volatile u32 *)addr; @@ -218,8 +218,6 @@ static inline u32 _MGA_READ(u32 *addr) #define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) #define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) - - /* ================================================================ * Helper macross... */ @@ -261,7 +259,6 @@ do { \ } \ } while (0) - /* ================================================================ * Primary DMA command stream */ @@ -346,7 +343,6 @@ do { \ write += DMA_BLOCK_SIZE; \ } while (0) - /* Buffer aging via primary DMA stream head pointer. */ @@ -373,7 +369,6 @@ do { \ } \ } while (0) - #define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \ MGA_DWGENGSTS | \ MGA_ENDPRDMASTS) @@ -382,8 +377,6 @@ do { \ #define MGA_DMA_DEBUG 0 - - /* A reduced set of the mga registers. */ #define MGA_CRTC_INDEX 0x1fd4 @@ -644,7 +637,6 @@ do { \ # define MGA_G400_WR_MAGIC (1 << 6) # define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */ - #define MGA_ILOAD_ALIGN 64 #define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1) @@ -679,10 +671,10 @@ do { \ /* Simple idle test. */ -static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv ) +static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv) { - u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; - return ( status == MGA_ENDPRDMASTS ); + u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; + return (status == MGA_ENDPRDMASTS); } #endif diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c index 77d738e75a4d..24a9d4e86af0 100644 --- a/drivers/char/drm/mga_ioc32.c +++ b/drivers/char/drm/mga_ioc32.c @@ -39,17 +39,17 @@ typedef struct drm32_mga_init { int func; - u32 sarea_priv_offset; + u32 sarea_priv_offset; int chipset; - int sgram; + int sgram; unsigned int maccess; - unsigned int fb_cpp; + unsigned int fb_cpp; unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_cpp; - unsigned int depth_offset, depth_pitch; - unsigned int texture_offset[MGA_NR_TEX_HEAPS]; - unsigned int texture_size[MGA_NR_TEX_HEAPS]; + unsigned int back_offset, back_pitch; + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; + unsigned int texture_offset[MGA_NR_TEX_HEAPS]; + unsigned int texture_size[MGA_NR_TEX_HEAPS]; u32 fb_offset; u32 mmio_offset; u32 status_offset; @@ -64,10 +64,10 @@ static int compat_mga_init(struct file *file, unsigned int cmd, drm_mga_init32_t init32; drm_mga_init_t __user *init; int err = 0, i; - + if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) return -EFAULT; - + init = compat_alloc_user_space(sizeof(*init)); if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) || __put_user(init32.func, &init->func) @@ -90,42 +90,43 @@ static int compat_mga_init(struct file *file, unsigned int cmd, || __put_user(init32.primary_offset, &init->primary_offset) || __put_user(init32.buffers_offset, &init->buffers_offset)) return -EFAULT; - - for (i=0; itexture_offset[i]); - err |= __put_user(init32.texture_size[i], &init->texture_size[i]); + + for (i = 0; i < MGA_NR_TEX_HEAPS; i++) { + err |= + __put_user(init32.texture_offset[i], + &init->texture_offset[i]); + err |= + __put_user(init32.texture_size[i], &init->texture_size[i]); } if (err) return -EFAULT; - - return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_MGA_INIT, (unsigned long) init); -} + return drm_ioctl(file->f_dentry->d_inode, file, + DRM_IOCTL_MGA_INIT, (unsigned long)init); +} typedef struct drm_mga_getparam32 { int param; u32 value; } drm_mga_getparam32_t; - static int compat_mga_getparam(struct file *file, unsigned int cmd, unsigned long arg) { drm_mga_getparam32_t getparam32; drm_mga_getparam_t __user *getparam; - + if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) return -EFAULT; getparam = compat_alloc_user_space(sizeof(*getparam)); if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value)) + || __put_user((void __user *)(unsigned long)getparam32.value, + &getparam->value)) return -EFAULT; - return drm_ioctl(file->f_dentry->d_inode, file, + return drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); } @@ -182,14 +183,12 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, &dma_bootstrap->secondary_bin_count) || __get_user(dma_bootstrap32.secondary_bin_size, &dma_bootstrap->secondary_bin_size) - || __get_user(dma_bootstrap32.agp_mode, - &dma_bootstrap->agp_mode) - || __get_user(dma_bootstrap32.agp_size, - &dma_bootstrap->agp_size)) + || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) + || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) return -EFAULT; if (copy_to_user((void __user *)arg, &dma_bootstrap32, - sizeof(dma_bootstrap32))) + sizeof(dma_bootstrap32))) return -EFAULT; return 0; @@ -210,8 +209,7 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = { * \param arg user argument. * \return zero on success or negative number on failure. */ -long mga_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) +long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int nr = DRM_IOCTL_NR(cmd); drm_ioctl_compat_t *fn = NULL; @@ -219,13 +217,13 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); - + if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; lock_kernel(); /* XXX for now */ if (fn != NULL) - ret = (*fn)(filp, cmd, arg); + ret = (*fn) (filp, cmd, arg); else ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c index 52eaa4e788f9..eb9644024172 100644 --- a/drivers/char/drm/mga_irq.c +++ b/drivers/char/drm/mga_irq.c @@ -1,7 +1,7 @@ /* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * + * * The Weather Channel (TM) funded Tungsten Graphics to develop the * initial release of the Radeon 8500 driver under the XFree86 license. * This notice must be preserved. @@ -35,19 +35,18 @@ #include "mga_drm.h" #include "mga_drv.h" -irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS ) +irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; int status; int handled = 0; status = MGA_READ(MGA_STATUS); /* VBLANK interrupt */ - if ( status & MGA_VLINEPEN ) { - MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR ); + if (status & MGA_VLINEPEN) { + MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); @@ -57,15 +56,14 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS ) /* SOFTRAP interrupt */ if (status & MGA_SOFTRAPEN) { const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); - const u32 prim_end = MGA_READ(MGA_PRIMEND); - + const u32 prim_end = MGA_READ(MGA_PRIMEND); MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); /* In addition to clearing the interrupt-pending bit, we * have to write to MGA_PRIMEND to re-start the DMA operation. */ - if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) { + if ((prim_start & ~0x03) != (prim_end & ~0x03)) { MGA_WRITE(MGA_PRIMEND, prim_end); } @@ -74,24 +72,24 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS ) handled = 1; } - if ( handled ) { + if (handled) { return IRQ_HANDLED; } return IRQ_NONE; } -int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) { unsigned int cur_vblank; int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years - * using vertical blanks... + * using vertical blanks... */ - DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, - ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) - - *sequence ) <= (1<<23) ) ); + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); *sequence = cur_vblank; @@ -122,29 +120,29 @@ void mga_driver_irq_preinstall(drm_device_t * dev) drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; /* Disable *all* interrupts */ - MGA_WRITE( MGA_IEN, 0 ); + MGA_WRITE(MGA_IEN, 0); /* Clear bits if they're already high */ - MGA_WRITE( MGA_ICLEAR, ~0 ); + MGA_WRITE(MGA_ICLEAR, ~0); } void mga_driver_irq_postinstall(drm_device_t * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - DRM_INIT_WAITQUEUE( &dev_priv->fence_queue ); + DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); /* Turn on vertical blank interrupt and soft trap interrupt. */ MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); } -void mga_driver_irq_uninstall( drm_device_t *dev ) { - drm_mga_private_t *dev_priv = - (drm_mga_private_t *)dev->dev_private; +void mga_driver_irq_uninstall(drm_device_t * dev) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; if (!dev_priv) return; /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); - + dev->irq_enabled = 0; } diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c index 05bbb4719376..15114f8aa467 100644 --- a/drivers/char/drm/mga_state.c +++ b/drivers/char/drm/mga_state.c @@ -41,15 +41,15 @@ * DMA hardware state programming functions */ -static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, - drm_clip_rect_t *box ) +static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, + drm_clip_rect_t * box) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; unsigned int pitch = dev_priv->front_pitch; DMA_LOCALS; - BEGIN_DMA( 2 ); + BEGIN_DMA(2); /* Force reset of DWGCTL on G400 (eliminates clip disable bit). */ @@ -61,101 +61,90 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, } DMA_BLOCK(MGA_DMAPAD, 0x00000000, MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YTOP, box->y1 * pitch, - MGA_YBOT, (box->y2 - 1) * pitch); + MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch); ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; DMA_LOCALS; - BEGIN_DMA( 3 ); + BEGIN_DMA(3); - DMA_BLOCK( MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, - MGA_DWGCTL, ctx->dwgctl ); + DMA_BLOCK(MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, - MGA_ZORG, dev_priv->depth_offset ); + DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - DMA_BLOCK( MGA_FCOL, ctx->fcol, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_FCOL, ctx->fcol, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; DMA_LOCALS; - BEGIN_DMA( 4 ); + BEGIN_DMA(4); - DMA_BLOCK( MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, - MGA_DWGCTL, ctx->dwgctl ); + DMA_BLOCK(MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, - MGA_ZORG, dev_priv->depth_offset ); + DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - DMA_BLOCK( MGA_WFLAG1, ctx->wflag, - MGA_TDUALSTAGE0, ctx->tdualstage0, - MGA_TDUALSTAGE1, ctx->tdualstage1, - MGA_FCOL, ctx->fcol ); + DMA_BLOCK(MGA_WFLAG1, ctx->wflag, + MGA_TDUALSTAGE0, ctx->tdualstage0, + MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol); - DMA_BLOCK( MGA_STENCIL, ctx->stencil, - MGA_STENCILCTL, ctx->stencilctl, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_STENCIL, ctx->stencil, + MGA_STENCILCTL, ctx->stencilctl, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; DMA_LOCALS; - BEGIN_DMA( 4 ); + BEGIN_DMA(4); - DMA_BLOCK( MGA_TEXCTL2, tex->texctl2, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol ); + DMA_BLOCK(MGA_TEXCTL2, tex->texctl2, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol); - DMA_BLOCK( MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, - MGA_TEXORG3, tex->texorg3 ); + DMA_BLOCK(MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - DMA_BLOCK( MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, - MGA_WR24, tex->texwidth ); + DMA_BLOCK(MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth); - DMA_BLOCK( MGA_WR34, tex->texheight, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_WR34, tex->texheight, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000); ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; @@ -164,42 +153,38 @@ static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) /* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */ /* tex->texctl, tex->texctl2); */ - BEGIN_DMA( 6 ); + BEGIN_DMA(6); - DMA_BLOCK( MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol ); + DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol); - DMA_BLOCK( MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, - MGA_TEXORG3, tex->texorg3 ); + DMA_BLOCK(MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - DMA_BLOCK( MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, - MGA_WR49, 0x00000000 ); + DMA_BLOCK(MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - DMA_BLOCK( MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, - MGA_WR52, MGA_G400_WR_MAGIC ); + DMA_BLOCK(MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC); - DMA_BLOCK( MGA_WR60, MGA_G400_WR_MAGIC, - MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, - MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC, + MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, + MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, + MGA_DMAPAD, 0x00000000); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff); ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; @@ -208,55 +193,51 @@ static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) /* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */ /* tex->texctl, tex->texctl2); */ - BEGIN_DMA( 5 ); + BEGIN_DMA(5); - DMA_BLOCK( MGA_TEXCTL2, (tex->texctl2 | - MGA_MAP1_ENABLE | - MGA_G400_TC2_MAGIC), - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol ); + DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 | + MGA_MAP1_ENABLE | + MGA_G400_TC2_MAGIC), + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol); - DMA_BLOCK( MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, - MGA_TEXORG3, tex->texorg3 ); + DMA_BLOCK(MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - DMA_BLOCK( MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, - MGA_WR49, 0x00000000 ); + DMA_BLOCK(MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - DMA_BLOCK( MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, - MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC ); + DMA_BLOCK(MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, + MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC); - DMA_BLOCK( MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, - MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC ); + DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, + MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC); ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; DMA_LOCALS; - BEGIN_DMA( 3 ); + BEGIN_DMA(3); - DMA_BLOCK( MGA_WIADDR, MGA_WMODE_SUSPEND, - MGA_WVRTXSZ, 0x00000007, - MGA_WFLAG, 0x00000000, - MGA_WR24, 0x00000000 ); + DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND, + MGA_WVRTXSZ, 0x00000007, + MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000); - DMA_BLOCK( MGA_WR25, 0x00000100, - MGA_WR34, 0x00000000, - MGA_WR42, 0x0000ffff, - MGA_WR60, 0x0000ffff ); + DMA_BLOCK(MGA_WR25, 0x00000100, + MGA_WR34, 0x00000000, + MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff); /* Padding required to to hardware bug. */ @@ -269,7 +250,7 @@ static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; @@ -277,68 +258,64 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) /* printk("mga_g400_emit_pipe %x\n", pipe); */ - BEGIN_DMA( 10 ); + BEGIN_DMA(10); - DMA_BLOCK( MGA_WIADDR2, MGA_WMODE_SUSPEND, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - if ( pipe & MGA_T2 ) { - DMA_BLOCK( MGA_WVRTXSZ, 0x00001e09, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + if (pipe & MGA_T2) { + DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x1e000000 ); + DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x1e000000); } else { - if ( dev_priv->warp_pipe & MGA_T2 ) { + if (dev_priv->warp_pipe & MGA_T2) { /* Flush the WARP pipe */ - DMA_BLOCK( MGA_YDST, 0x00000000, - MGA_FXLEFT, 0x00000000, - MGA_FXRIGHT, 0x00000001, - MGA_DWGCTL, MGA_DWGCTL_FLUSH ); + DMA_BLOCK(MGA_YDST, 0x00000000, + MGA_FXLEFT, 0x00000000, + MGA_FXRIGHT, 0x00000001, + MGA_DWGCTL, MGA_DWGCTL_FLUSH); - DMA_BLOCK( MGA_LEN + MGA_EXEC, 0x00000001, - MGA_DWGSYNC, 0x00007000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_LEN + MGA_EXEC, 0x00000000 ); + DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001, + MGA_DWGSYNC, 0x00007000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_LEN + MGA_EXEC, 0x00000000); - DMA_BLOCK( MGA_TEXCTL2, (MGA_DUALTEX | - MGA_G400_TC2_MAGIC), - MGA_LEN + MGA_EXEC, 0x00000000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX | + MGA_G400_TC2_MAGIC), + MGA_LEN + MGA_EXEC, 0x00000000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_DMAPAD, 0x00000000); } - DMA_BLOCK( MGA_WVRTXSZ, 0x00001807, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_WVRTXSZ, 0x00001807, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x18000000 ); + DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x18000000); } - DMA_BLOCK( MGA_WFLAG, 0x00000000, - MGA_WFLAG1, 0x00000000, - MGA_WR56, MGA_G400_WR56_MAGIC, - MGA_DMAPAD, 0x00000000 ); + DMA_BLOCK(MGA_WFLAG, 0x00000000, + MGA_WFLAG1, 0x00000000, + MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000); - DMA_BLOCK( MGA_WR49, 0x00000000, /* tex0 */ - MGA_WR57, 0x00000000, /* tex0 */ - MGA_WR53, 0x00000000, /* tex1 */ - MGA_WR61, 0x00000000 ); /* tex1 */ + DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */ + MGA_WR57, 0x00000000, /* tex0 */ + MGA_WR53, 0x00000000, /* tex1 */ + MGA_WR61, 0x00000000); /* tex1 */ - DMA_BLOCK( MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ - MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ - MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ - MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ + DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ + MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ + MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ + MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */ /* Padding required to to hardware bug */ DMA_BLOCK(MGA_DMAPAD, 0xffffffff, @@ -350,71 +327,70 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static void mga_g200_emit_state( drm_mga_private_t *dev_priv ) +static void mga_g200_emit_state(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; - if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { - mga_g200_emit_pipe( dev_priv ); + if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { + mga_g200_emit_pipe(dev_priv); dev_priv->warp_pipe = sarea_priv->warp_pipe; } - if ( dirty & MGA_UPLOAD_CONTEXT ) { - mga_g200_emit_context( dev_priv ); + if (dirty & MGA_UPLOAD_CONTEXT) { + mga_g200_emit_context(dev_priv); sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; } - if ( dirty & MGA_UPLOAD_TEX0 ) { - mga_g200_emit_tex0( dev_priv ); + if (dirty & MGA_UPLOAD_TEX0) { + mga_g200_emit_tex0(dev_priv); sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; } } -static void mga_g400_emit_state( drm_mga_private_t *dev_priv ) +static void mga_g400_emit_state(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; int multitex = sarea_priv->warp_pipe & MGA_T2; - if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { - mga_g400_emit_pipe( dev_priv ); + if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { + mga_g400_emit_pipe(dev_priv); dev_priv->warp_pipe = sarea_priv->warp_pipe; } - if ( dirty & MGA_UPLOAD_CONTEXT ) { - mga_g400_emit_context( dev_priv ); + if (dirty & MGA_UPLOAD_CONTEXT) { + mga_g400_emit_context(dev_priv); sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; } - if ( dirty & MGA_UPLOAD_TEX0 ) { - mga_g400_emit_tex0( dev_priv ); + if (dirty & MGA_UPLOAD_TEX0) { + mga_g400_emit_tex0(dev_priv); sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; } - if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) { - mga_g400_emit_tex1( dev_priv ); + if ((dirty & MGA_UPLOAD_TEX1) && multitex) { + mga_g400_emit_tex1(dev_priv); sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; } } - /* ================================================================ * SAREA state verification */ /* Disallow all write destinations except the front and backbuffer. */ -static int mga_verify_context( drm_mga_private_t *dev_priv ) +static int mga_verify_context(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - if ( ctx->dstorg != dev_priv->front_offset && - ctx->dstorg != dev_priv->back_offset ) { - DRM_ERROR( "*** bad DSTORG: %x (front %x, back %x)\n\n", - ctx->dstorg, dev_priv->front_offset, - dev_priv->back_offset ); + if (ctx->dstorg != dev_priv->front_offset && + ctx->dstorg != dev_priv->back_offset) { + DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n", + ctx->dstorg, dev_priv->front_offset, + dev_priv->back_offset); ctx->dstorg = 0; return DRM_ERR(EINVAL); } @@ -424,7 +400,7 @@ static int mga_verify_context( drm_mga_private_t *dev_priv ) /* Disallow texture reads from PCI space. */ -static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) +static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; @@ -432,9 +408,8 @@ static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); - if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) { - DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n", - tex->texorg, unit ); + if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) { + DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit); tex->texorg = 0; return DRM_ERR(EINVAL); } @@ -442,73 +417,70 @@ static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) return 0; } -static int mga_verify_state( drm_mga_private_t *dev_priv ) +static int mga_verify_state(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; int ret = 0; - if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - if ( dirty & MGA_UPLOAD_CONTEXT ) - ret |= mga_verify_context( dev_priv ); + if (dirty & MGA_UPLOAD_CONTEXT) + ret |= mga_verify_context(dev_priv); - if ( dirty & MGA_UPLOAD_TEX0 ) - ret |= mga_verify_tex( dev_priv, 0 ); + if (dirty & MGA_UPLOAD_TEX0) + ret |= mga_verify_tex(dev_priv, 0); if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { if (dirty & MGA_UPLOAD_TEX1) ret |= mga_verify_tex(dev_priv, 1); - if ( dirty & MGA_UPLOAD_PIPE ) - ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); + if (dirty & MGA_UPLOAD_PIPE) + ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES); } else { - if ( dirty & MGA_UPLOAD_PIPE ) - ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES ); + if (dirty & MGA_UPLOAD_PIPE) + ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES); } - return ( ret == 0 ); + return (ret == 0); } -static int mga_verify_iload( drm_mga_private_t *dev_priv, - unsigned int dstorg, unsigned int length ) +static int mga_verify_iload(drm_mga_private_t * dev_priv, + unsigned int dstorg, unsigned int length) { - if ( dstorg < dev_priv->texture_offset || - dstorg + length > (dev_priv->texture_offset + - dev_priv->texture_size) ) { - DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg ); + if (dstorg < dev_priv->texture_offset || + dstorg + length > (dev_priv->texture_offset + + dev_priv->texture_size)) { + DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg); return DRM_ERR(EINVAL); } - if ( length & MGA_ILOAD_MASK ) { - DRM_ERROR( "*** bad iload length: 0x%x\n", - length & MGA_ILOAD_MASK ); + if (length & MGA_ILOAD_MASK) { + DRM_ERROR("*** bad iload length: 0x%x\n", + length & MGA_ILOAD_MASK); return DRM_ERR(EINVAL); } return 0; } -static int mga_verify_blit( drm_mga_private_t *dev_priv, - unsigned int srcorg, unsigned int dstorg ) +static int mga_verify_blit(drm_mga_private_t * dev_priv, + unsigned int srcorg, unsigned int dstorg) { - if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || - (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) { - DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n", - srcorg, dstorg ); + if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || + (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) { + DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg); return DRM_ERR(EINVAL); } return 0; } - /* ================================================================ * */ -static void mga_dma_dispatch_clear( drm_device_t *dev, - drm_mga_clear_t *clear ) +static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -517,92 +489,86 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - BEGIN_DMA( 1 ); + BEGIN_DMA(1); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, - MGA_DWGSYNC, 0x00007000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); ADVANCE_DMA(); - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { drm_clip_rect_t *box = &pbox[i]; u32 height = box->y2 - box->y1; - DRM_DEBUG( " from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2 ); + DRM_DEBUG(" from=%d,%d to=%d,%d\n", + box->x1, box->y1, box->x2, box->y2); - if ( clear->flags & MGA_FRONT ) { - BEGIN_DMA( 2 ); + if (clear->flags & MGA_FRONT) { + BEGIN_DMA(2); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->front_offset, - MGA_DWGCTL + MGA_EXEC, - dev_priv->clear_cmd ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->front_offset, + MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); ADVANCE_DMA(); } + if (clear->flags & MGA_BACK) { + BEGIN_DMA(2); - if ( clear->flags & MGA_BACK ) { - BEGIN_DMA( 2 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); - - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->back_offset, - MGA_DWGCTL + MGA_EXEC, - dev_priv->clear_cmd ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->back_offset, + MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); ADVANCE_DMA(); } - if ( clear->flags & MGA_DEPTH ) { - BEGIN_DMA( 2 ); + if (clear->flags & MGA_DEPTH) { + BEGIN_DMA(2); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->depth_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->depth_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_depth, - MGA_DSTORG, dev_priv->depth_offset, - MGA_DWGCTL + MGA_EXEC, - dev_priv->clear_cmd ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_depth, + MGA_DSTORG, dev_priv->depth_offset, + MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); ADVANCE_DMA(); } } - BEGIN_DMA( 1 ); + BEGIN_DMA(1); /* Force reset of DWGCTL */ - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_DWGCTL, ctx->dwgctl ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); ADVANCE_DMA(); FLUSH_DMA(); } -static void mga_dma_dispatch_swap( drm_device_t *dev ) +static void mga_dma_dispatch_swap(drm_device_t * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -611,56 +577,52 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); sarea_priv->last_frame.head = dev_priv->prim.tail; sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; - BEGIN_DMA( 4 + nbox ); + BEGIN_DMA(4 + nbox); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, - MGA_DWGSYNC, 0x00007000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset, - MGA_MACCESS, dev_priv->maccess, - MGA_SRCORG, dev_priv->back_offset, - MGA_AR5, dev_priv->front_pitch ); + DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset, + MGA_MACCESS, dev_priv->maccess, + MGA_SRCORG, dev_priv->back_offset, + MGA_AR5, dev_priv->front_pitch); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, 0xffffffff, - MGA_DWGCTL, MGA_DWGCTL_COPY ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY); - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { drm_clip_rect_t *box = &pbox[i]; u32 height = box->y2 - box->y1; u32 start = box->y1 * dev_priv->front_pitch; - DRM_DEBUG( " from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2 ); + DRM_DEBUG(" from=%d,%d to=%d,%d\n", + box->x1, box->y1, box->x2, box->y2); - DMA_BLOCK( MGA_AR0, start + box->x2 - 1, - MGA_AR3, start + box->x1, - MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YDSTLEN + MGA_EXEC, - (box->y1 << 16) | height ); + DMA_BLOCK(MGA_AR0, start + box->x2 - 1, + MGA_AR3, start + box->x1, + MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, + MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height); } - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, - MGA_DWGCTL, ctx->dwgctl ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl); ADVANCE_DMA(); FLUSH_DMA(); - DRM_DEBUG( "%s... done.\n", __FUNCTION__ ); + DRM_DEBUG("%s... done.\n", __FUNCTION__); } -static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) +static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -669,20 +631,20 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) u32 length = (u32) buf->used; int i = 0; DMA_LOCALS; - DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used ); + DRM_DEBUG("vertex: buf=%d used=%d\n", buf->idx, buf->used); - if ( buf->used ) { + if (buf->used) { buf_priv->dispatched = 1; - MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); + MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); do { - if ( i < sarea_priv->nbox ) { - mga_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + if (i < sarea_priv->nbox) { + mga_emit_clip_rect(dev_priv, + &sarea_priv->boxes[i]); } - BEGIN_DMA( 1 ); + BEGIN_DMA(1); DMA_BLOCK(MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, @@ -692,23 +654,23 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) dev_priv->dma_access)); ADVANCE_DMA(); - } while ( ++i < sarea_priv->nbox ); + } while (++i < sarea_priv->nbox); } - if ( buf_priv->discard ) { - AGE_BUFFER( buf_priv ); + if (buf_priv->discard) { + AGE_BUFFER(buf_priv); buf->pending = 0; buf->used = 0; buf_priv->dispatched = 0; - mga_freelist_put( dev, buf ); + mga_freelist_put(dev, buf); } FLUSH_DMA(); } -static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, - unsigned int start, unsigned int end ) +static void mga_dma_dispatch_indices(drm_device_t * dev, drm_buf_t * buf, + unsigned int start, unsigned int end) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -716,20 +678,20 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, u32 address = (u32) buf->bus_address; int i = 0; DMA_LOCALS; - DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end ); + DRM_DEBUG("indices: buf=%d start=%d end=%d\n", buf->idx, start, end); - if ( start != end ) { + if (start != end) { buf_priv->dispatched = 1; - MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); + MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); do { - if ( i < sarea_priv->nbox ) { - mga_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + if (i < sarea_priv->nbox) { + mga_emit_clip_rect(dev_priv, + &sarea_priv->boxes[i]); } - BEGIN_DMA( 1 ); + BEGIN_DMA(1); DMA_BLOCK(MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, @@ -738,16 +700,16 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, dev_priv->dma_access)); ADVANCE_DMA(); - } while ( ++i < sarea_priv->nbox ); + } while (++i < sarea_priv->nbox); } - if ( buf_priv->discard ) { - AGE_BUFFER( buf_priv ); + if (buf_priv->discard) { + AGE_BUFFER(buf_priv); buf->pending = 0; buf->used = 0; buf_priv->dispatched = 0; - mga_freelist_put( dev, buf ); + mga_freelist_put(dev, buf); } FLUSH_DMA(); @@ -756,61 +718,55 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, /* This copies a 64 byte aligned agp region to the frambuffer with a * standard blit, the ioctl needs to do checking. */ -static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, - unsigned int dstorg, unsigned int length ) +static void mga_dma_dispatch_iload(drm_device_t * dev, drm_buf_t * buf, + unsigned int dstorg, unsigned int length) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; - u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; + u32 srcorg = + buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; u32 y2; DMA_LOCALS; - DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); + DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); y2 = length / 64; - BEGIN_DMA( 5 ); + BEGIN_DMA(5); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, - MGA_DWGSYNC, 0x00007000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - DMA_BLOCK( MGA_DSTORG, dstorg, - MGA_MACCESS, 0x00000000, - MGA_SRCORG, srcorg, - MGA_AR5, 64 ); + DMA_BLOCK(MGA_DSTORG, dstorg, + MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64); - DMA_BLOCK( MGA_PITCH, 64, - MGA_PLNWT, 0xffffffff, - MGA_DMAPAD, 0x00000000, - MGA_DWGCTL, MGA_DWGCTL_COPY ); + DMA_BLOCK(MGA_PITCH, 64, + MGA_PLNWT, 0xffffffff, + MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY); - DMA_BLOCK( MGA_AR0, 63, - MGA_AR3, 0, - MGA_FXBNDRY, (63 << 16) | 0, - MGA_YDSTLEN + MGA_EXEC, y2 ); + DMA_BLOCK(MGA_AR0, 63, + MGA_AR3, 0, + MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2); - DMA_BLOCK( MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, - MGA_PITCH, dev_priv->front_pitch, - MGA_DWGSYNC, 0x00007000 ); + DMA_BLOCK(MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, + MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000); ADVANCE_DMA(); - AGE_BUFFER( buf_priv ); + AGE_BUFFER(buf_priv); buf->pending = 0; buf->used = 0; buf_priv->dispatched = 0; - mga_freelist_put( dev, buf ); + mga_freelist_put(dev, buf); FLUSH_DMA(); } -static void mga_dma_dispatch_blit( drm_device_t *dev, - drm_mga_blit_t *blit ) +static void mga_dma_dispatch_blit(drm_device_t * dev, drm_mga_blit_t * blit) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -819,26 +775,24 @@ static void mga_dma_dispatch_blit( drm_device_t *dev, int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - BEGIN_DMA( 4 + nbox ); + BEGIN_DMA(4 + nbox); - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, - MGA_DWGSYNC, 0x00007000 ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - DMA_BLOCK( MGA_DWGCTL, MGA_DWGCTL_COPY, - MGA_PLNWT, blit->planemask, - MGA_SRCORG, blit->srcorg, - MGA_DSTORG, blit->dstorg ); + DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY, + MGA_PLNWT, blit->planemask, + MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg); - DMA_BLOCK( MGA_SGN, scandir, - MGA_MACCESS, dev_priv->maccess, - MGA_AR5, blit->ydir * blit->src_pitch, - MGA_PITCH, blit->dst_pitch ); + DMA_BLOCK(MGA_SGN, scandir, + MGA_MACCESS, dev_priv->maccess, + MGA_AR5, blit->ydir * blit->src_pitch, + MGA_PITCH, blit->dst_pitch); - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { int srcx = pbox[i].x1 + blit->delta_sx; int srcy = pbox[i].y1 + blit->delta_sy; int dstx = pbox[i].x1 + blit->delta_dx; @@ -847,52 +801,51 @@ static void mga_dma_dispatch_blit( drm_device_t *dev, int w = pbox[i].x2 - pbox[i].x1 - 1; int start; - if ( blit->ydir == -1 ) { + if (blit->ydir == -1) { srcy = blit->height - srcy - 1; } start = srcy * blit->src_pitch + srcx; - DMA_BLOCK( MGA_AR0, start + w, - MGA_AR3, start, - MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), - MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h ); + DMA_BLOCK(MGA_AR0, start + w, + MGA_AR3, start, + MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), + MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h); } /* Do something to flush AGP? */ /* Force reset of DWGCTL */ - DMA_BLOCK( MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_PITCH, dev_priv->front_pitch, - MGA_DWGCTL, ctx->dwgctl ); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl); ADVANCE_DMA(); } - /* ================================================================ * */ -static int mga_dma_clear( DRM_IOCTL_ARGS ) +static int mga_dma_clear(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t __user *)data, sizeof(clear) ); + DRM_COPY_FROM_USER_IOCTL(clear, (drm_mga_clear_t __user *) data, + sizeof(clear)); - if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_clear( dev, &clear ); + mga_dma_dispatch_clear(dev, &clear); /* Make sure we restore the 3D state next time. */ @@ -901,20 +854,20 @@ static int mga_dma_clear( DRM_IOCTL_ARGS ) return 0; } -static int mga_dma_swap( DRM_IOCTL_ARGS ) +static int mga_dma_swap(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_swap( dev ); + mga_dma_dispatch_swap(dev); /* Make sure we restore the 3D state next time. */ @@ -923,7 +876,7 @@ static int mga_dma_swap( DRM_IOCTL_ARGS ) return 0; } -static int mga_dma_vertex( DRM_IOCTL_ARGS ) +static int mga_dma_vertex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; @@ -932,37 +885,38 @@ static int mga_dma_vertex( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( vertex, - (drm_mga_vertex_t __user *)data, - sizeof(vertex) ); + DRM_COPY_FROM_USER_IOCTL(vertex, + (drm_mga_vertex_t __user *) data, + sizeof(vertex)); - if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL); + if (vertex.idx < 0 || vertex.idx > dma->buf_count) + return DRM_ERR(EINVAL); buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; buf->used = vertex.used; buf_priv->discard = vertex.discard; - if ( !mga_verify_state( dev_priv ) ) { - if ( vertex.discard ) { - if ( buf_priv->dispatched == 1 ) - AGE_BUFFER( buf_priv ); + if (!mga_verify_state(dev_priv)) { + if (vertex.discard) { + if (buf_priv->dispatched == 1) + AGE_BUFFER(buf_priv); buf_priv->dispatched = 0; - mga_freelist_put( dev, buf ); + mga_freelist_put(dev, buf); } return DRM_ERR(EINVAL); } - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_vertex( dev, buf ); + mga_dma_dispatch_vertex(dev, buf); return 0; } -static int mga_dma_indices( DRM_IOCTL_ARGS ) +static int mga_dma_indices(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; @@ -971,37 +925,38 @@ static int mga_dma_indices( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_indices_t indices; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( indices, - (drm_mga_indices_t __user *)data, - sizeof(indices) ); + DRM_COPY_FROM_USER_IOCTL(indices, + (drm_mga_indices_t __user *) data, + sizeof(indices)); - if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL); + if (indices.idx < 0 || indices.idx > dma->buf_count) + return DRM_ERR(EINVAL); buf = dma->buflist[indices.idx]; buf_priv = buf->dev_private; buf_priv->discard = indices.discard; - if ( !mga_verify_state( dev_priv ) ) { - if ( indices.discard ) { - if ( buf_priv->dispatched == 1 ) - AGE_BUFFER( buf_priv ); + if (!mga_verify_state(dev_priv)) { + if (indices.discard) { + if (buf_priv->dispatched == 1) + AGE_BUFFER(buf_priv); buf_priv->dispatched = 0; - mga_freelist_put( dev, buf ); + mga_freelist_put(dev, buf); } return DRM_ERR(EINVAL); } - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_indices( dev, buf, indices.start, indices.end ); + mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); return 0; } -static int mga_dma_iload( DRM_IOCTL_ARGS ) +static int mga_dma_iload(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_device_dma_t *dma = dev->dma; @@ -1009,32 +964,34 @@ static int mga_dma_iload( DRM_IOCTL_ARGS ) drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_iload_t iload; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t __user *)data, sizeof(iload) ); + DRM_COPY_FROM_USER_IOCTL(iload, (drm_mga_iload_t __user *) data, + sizeof(iload)); #if 0 - if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { - if ( MGA_DMA_DEBUG ) - DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); + if (mga_do_wait_for_idle(dev_priv) < 0) { + if (MGA_DMA_DEBUG) + DRM_INFO("%s: -EBUSY\n", __FUNCTION__); return DRM_ERR(EBUSY); } #endif - if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL); + if (iload.idx < 0 || iload.idx > dma->buf_count) + return DRM_ERR(EINVAL); buf = dma->buflist[iload.idx]; buf_priv = buf->dev_private; - if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) { - mga_freelist_put( dev, buf ); + if (mga_verify_iload(dev_priv, iload.dstorg, iload.length)) { + mga_freelist_put(dev, buf); return DRM_ERR(EINVAL); } - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length ); + mga_dma_dispatch_iload(dev, buf, iload.dstorg, iload.length); /* Make sure we restore the 3D state next time. */ @@ -1043,27 +1000,28 @@ static int mga_dma_iload( DRM_IOCTL_ARGS ) return 0; } -static int mga_dma_blit( DRM_IOCTL_ARGS ) +static int mga_dma_blit(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_blit_t blit; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t __user *)data, sizeof(blit) ); + DRM_COPY_FROM_USER_IOCTL(blit, (drm_mga_blit_t __user *) data, + sizeof(blit)); - if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) ) + if (mga_verify_blit(dev_priv, blit.srcorg, blit.dstorg)) return DRM_ERR(EINVAL); - WRAP_TEST_WITH_RETURN( dev_priv ); + WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_blit( dev, &blit ); + mga_dma_dispatch_blit(dev, &blit); /* Make sure we restore the 3D state next time. */ @@ -1072,24 +1030,24 @@ static int mga_dma_blit( DRM_IOCTL_ARGS ) return 0; } -static int mga_getparam( DRM_IOCTL_ARGS ) +static int mga_getparam(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_getparam_t param; int value; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t __user *)data, - sizeof(param) ); + DRM_COPY_FROM_USER_IOCTL(param, (drm_mga_getparam_t __user *) data, + sizeof(param)); - DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch( param.param ) { + switch (param.param) { case MGA_PARAM_IRQ_NR: value = dev->irq; break; @@ -1100,11 +1058,11 @@ static int mga_getparam( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } - if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } - + return 0; } @@ -1132,11 +1090,10 @@ static int mga_set_fence(DRM_IOCTL_ARGS) BEGIN_DMA(1); DMA_BLOCK(MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_SOFTRAP, 0x00000000); + MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000); ADVANCE_DMA(); - if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) { + if (DRM_COPY_TO_USER((u32 __user *) data, &temp, sizeof(u32))) { DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } @@ -1159,9 +1116,9 @@ static int mga_wait_fence(DRM_IOCTL_ARGS) DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - mga_driver_fence_wait(dev, & fence); + mga_driver_fence_wait(dev, &fence); - if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) { + if (DRM_COPY_TO_USER((u32 __user *) data, &fence, sizeof(u32))) { DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } @@ -1170,19 +1127,32 @@ static int mga_wait_fence(DRM_IOCTL_ARGS) } drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, - [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, - [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, + [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0} + , + [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1} + , }; diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h index fa0f82ec9fa0..b611e27470e1 100644 --- a/drivers/char/drm/mga_ucode.h +++ b/drivers/char/drm/mga_ucode.h @@ -40,11606 +40,11606 @@ static unsigned char warp_g200_tgz[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x72, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x72, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x60, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x60, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x03, 0x80, 0x0A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x0A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x3C, 0x27, 0x4F, 0xE9, + 0x33, 0xC0, 0x33, 0xAF, + 0x3C, 0x27, 0x4F, 0xE9, -0x57, 0x39, 0x20, 0xE9, -0x28, 0x19, 0x60, 0xEC, + 0x57, 0x39, 0x20, 0xE9, + 0x28, 0x19, 0x60, 0xEC, -0x2B, 0x32, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0xB3, 0x05, -0x00, 0xE0, -0x16, 0x28, 0x20, 0xE9, + 0xB3, 0x05, + 0x00, 0xE0, + 0x16, 0x28, 0x20, 0xE9, -0x23, 0x3B, 0x33, 0xAD, -0x1E, 0x2B, 0x20, 0xE9, + 0x23, 0x3B, 0x33, 0xAD, + 0x1E, 0x2B, 0x20, 0xE9, -0x1C, 0x80, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x80, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x85, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x85, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x84, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x84, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x82, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x82, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x7F, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x7F, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgza[] = { -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x7D, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x7D, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x6B, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x6B, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x2D, 0x44, 0x4C, 0xB6, -0x25, 0x44, 0x54, 0xB6, + 0x2D, 0x44, 0x4C, 0xB6, + 0x25, 0x44, 0x54, 0xB6, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x2D, 0x20, -0x25, 0x20, -0x07, 0xC0, 0x44, 0xC6, + 0x2D, 0x20, + 0x25, 0x20, + 0x07, 0xC0, 0x44, 0xC6, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x3C, 0x27, 0x4F, 0xE9, + 0x33, 0xC0, 0x33, 0xAF, + 0x3C, 0x27, 0x4F, 0xE9, -0x1F, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x3F, 0x3D, 0x5D, 0x9F, -0x00, 0xE0, -0x07, 0x20, + 0x3F, 0x3D, 0x5D, 0x9F, + 0x00, 0xE0, + 0x07, 0x20, -0x00, 0x80, 0x00, 0xE8, -0x28, 0x19, 0x60, 0xEC, + 0x00, 0x80, 0x00, 0xE8, + 0x28, 0x19, 0x60, 0xEC, -0xB3, 0x05, -0x00, 0xE0, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x05, + 0x00, 0xE0, + 0x00, 0x80, 0x00, 0xE8, -0x23, 0x3B, 0x33, 0xAD, -0x00, 0x80, 0x00, 0xE8, + 0x23, 0x3B, 0x33, 0xAD, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0x26, 0x1F, 0xDF, -0x9D, 0x1F, 0x4F, 0xE9, + 0x1F, 0x26, 0x1F, 0xDF, + 0x9D, 0x1F, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x9E, 0x3F, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x9E, 0x3F, 0x4F, 0xE9, -0x07, 0x07, 0x1F, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x07, 0x07, 0x1F, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x9C, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x7A, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x7A, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x79, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x79, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x77, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x77, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x74, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x74, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzaf[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x83, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x83, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x6F, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x6F, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0D, 0x21, 0x1A, 0xB6, -0x05, 0x21, 0x31, 0xB6, + 0x0D, 0x21, 0x1A, 0xB6, + 0x05, 0x21, 0x31, 0xB6, -0x2D, 0x44, 0x4C, 0xB6, -0x25, 0x44, 0x54, 0xB6, + 0x2D, 0x44, 0x4C, 0xB6, + 0x25, 0x44, 0x54, 0xB6, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x0D, 0x20, -0x05, 0x20, -0x2F, 0xC0, 0x21, 0xC6, + 0x0D, 0x20, + 0x05, 0x20, + 0x2F, 0xC0, 0x21, 0xC6, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x3C, 0x27, 0x4F, 0xE9, + 0x33, 0xC0, 0x33, 0xAF, + 0x3C, 0x27, 0x4F, 0xE9, -0x00, 0xE0, -0x25, 0x20, -0x07, 0xC0, 0x44, 0xC6, + 0x00, 0xE0, + 0x25, 0x20, + 0x07, 0xC0, 0x44, 0xC6, -0x17, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x2D, 0x20, + 0x17, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x2D, 0x20, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x1F, 0x62, 0x57, 0x9F, -0x00, 0xE0, -0x07, 0x20, + 0x1F, 0x62, 0x57, 0x9F, + 0x00, 0xE0, + 0x07, 0x20, -0x3F, 0x3D, 0x5D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0x3D, 0x5D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x28, 0x19, 0x60, 0xEC, + 0x00, 0x80, 0x00, 0xE8, + 0x28, 0x19, 0x60, 0xEC, -0xB3, 0x05, -0x00, 0xE0, -0x17, 0x26, 0x17, 0xDF, + 0xB3, 0x05, + 0x00, 0xE0, + 0x17, 0x26, 0x17, 0xDF, -0x23, 0x3B, 0x33, 0xAD, -0x35, 0x17, 0x4F, 0xE9, + 0x23, 0x3B, 0x33, 0xAD, + 0x35, 0x17, 0x4F, 0xE9, -0x1F, 0x26, 0x1F, 0xDF, -0x9D, 0x1F, 0x4F, 0xE9, + 0x1F, 0x26, 0x1F, 0xDF, + 0x9D, 0x1F, 0x4F, 0xE9, -0x9E, 0x3F, 0x4F, 0xE9, -0x39, 0x37, 0x4F, 0xE9, + 0x9E, 0x3F, 0x4F, 0xE9, + 0x39, 0x37, 0x4F, 0xE9, -0x2F, 0x2F, 0x17, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x2F, 0x2F, 0x17, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0x07, 0x07, 0x1F, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x07, 0x07, 0x1F, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0x31, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x9C, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x74, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x74, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x73, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x73, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x71, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x71, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x6E, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x6E, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzf[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x7F, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x7F, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x6B, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x6B, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0D, 0x21, 0x1A, 0xB6, -0x05, 0x21, 0x31, 0xB6, + 0x0D, 0x21, 0x1A, 0xB6, + 0x05, 0x21, 0x31, 0xB6, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x0D, 0x20, -0x05, 0x20, -0x2F, 0xC0, 0x21, 0xC6, + 0x0D, 0x20, + 0x05, 0x20, + 0x2F, 0xC0, 0x21, 0xC6, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x3C, 0x27, 0x4F, 0xE9, + 0x33, 0xC0, 0x33, 0xAF, + 0x3C, 0x27, 0x4F, 0xE9, -0x17, 0x50, 0x56, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x17, 0x50, 0x56, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x00, 0x80, 0x00, 0xE8, -0x28, 0x19, 0x60, 0xEC, + 0x00, 0x80, 0x00, 0xE8, + 0x28, 0x19, 0x60, 0xEC, -0xB3, 0x05, -0x00, 0xE0, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x05, + 0x00, 0xE0, + 0x00, 0x80, 0x00, 0xE8, -0x23, 0x3B, 0x33, 0xAD, -0x00, 0x80, 0x00, 0xE8, + 0x23, 0x3B, 0x33, 0xAD, + 0x00, 0x80, 0x00, 0xE8, -0x17, 0x26, 0x17, 0xDF, -0x35, 0x17, 0x4F, 0xE9, + 0x17, 0x26, 0x17, 0xDF, + 0x35, 0x17, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x39, 0x37, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x39, 0x37, 0x4F, 0xE9, -0x2F, 0x2F, 0x17, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x2F, 0x2F, 0x17, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x31, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x78, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x78, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x77, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x77, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x75, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x75, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x72, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x72, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzs[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x8B, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x8B, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x77, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x77, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x2D, 0x21, 0x1A, 0xB0, -0x25, 0x21, 0x31, 0xB0, + 0x2D, 0x21, 0x1A, 0xB0, + 0x25, 0x21, 0x31, 0xB0, -0x0D, 0x21, 0x1A, 0xB2, -0x05, 0x21, 0x31, 0xB2, + 0x0D, 0x21, 0x1A, 0xB2, + 0x05, 0x21, 0x31, 0xB2, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x2D, 0x20, -0x25, 0x20, -0x05, 0x20, -0x0D, 0x20, + 0x2D, 0x20, + 0x25, 0x20, + 0x05, 0x20, + 0x0D, 0x20, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x2F, 0xC0, 0x21, 0xC0, + 0x33, 0xC0, 0x33, 0xAF, + 0x2F, 0xC0, 0x21, 0xC0, -0x16, 0x42, 0x56, 0x9F, -0x3C, 0x27, 0x4F, 0xE9, + 0x16, 0x42, 0x56, 0x9F, + 0x3C, 0x27, 0x4F, 0xE9, -0x1E, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x21, 0x31, 0xB4, -0x2D, 0x21, 0x1A, 0xB4, + 0x25, 0x21, 0x31, 0xB4, + 0x2D, 0x21, 0x1A, 0xB4, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0x05, -0x00, 0xE0, -0x28, 0x19, 0x60, 0xEC, + 0x33, 0x05, + 0x00, 0xE0, + 0x28, 0x19, 0x60, 0xEC, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x23, 0x3B, 0x33, 0xAD, -0x1E, 0x26, 0x1E, 0xDF, + 0x23, 0x3B, 0x33, 0xAD, + 0x1E, 0x26, 0x1E, 0xDF, -0xA7, 0x1E, 0x4F, 0xE9, -0x17, 0x26, 0x16, 0xDF, + 0xA7, 0x1E, 0x4F, 0xE9, + 0x17, 0x26, 0x16, 0xDF, -0x2D, 0x20, -0x00, 0xE0, -0xA8, 0x3F, 0x4F, 0xE9, + 0x2D, 0x20, + 0x00, 0xE0, + 0xA8, 0x3F, 0x4F, 0xE9, -0x2F, 0x2F, 0x1E, 0xAF, -0x25, 0x20, -0x00, 0xE0, + 0x2F, 0x2F, 0x1E, 0xAF, + 0x25, 0x20, + 0x00, 0xE0, -0xA4, 0x16, 0x4F, 0xE9, -0x0F, 0xC0, 0x21, 0xC2, + 0xA4, 0x16, 0x4F, 0xE9, + 0x0F, 0xC0, 0x21, 0xC2, -0xA6, 0x80, 0x4F, 0xE9, -0x1F, 0x62, 0x57, 0x9F, + 0xA6, 0x80, 0x4F, 0xE9, + 0x1F, 0x62, 0x57, 0x9F, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0xE0, -0x8F, 0x20, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0xE0, + 0x8F, 0x20, -0xA5, 0x37, 0x4F, 0xE9, -0x0F, 0x17, 0x0F, 0xAF, + 0xA5, 0x37, 0x4F, 0xE9, + 0x0F, 0x17, 0x0F, 0xAF, -0x06, 0xC0, 0x21, 0xC4, -0x00, 0x80, 0x00, 0xE8, + 0x06, 0xC0, 0x21, 0xC4, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0xA3, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0xA3, 0x80, 0x4F, 0xE9, -0x06, 0x20, -0x00, 0xE0, -0x1F, 0x26, 0x1F, 0xDF, + 0x06, 0x20, + 0x00, 0xE0, + 0x1F, 0x26, 0x1F, 0xDF, -0xA1, 0x1F, 0x4F, 0xE9, -0xA2, 0x3F, 0x4F, 0xE9, + 0xA1, 0x1F, 0x4F, 0xE9, + 0xA2, 0x3F, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x06, 0x06, 0x1F, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x06, 0x06, 0x1F, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x6C, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x6C, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x6B, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x6B, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x69, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x69, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x66, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzsa[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x8F, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x8F, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x7B, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x7B, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x2D, 0x21, 0x1A, 0xB0, -0x25, 0x21, 0x31, 0xB0, + 0x2D, 0x21, 0x1A, 0xB0, + 0x25, 0x21, 0x31, 0xB0, -0x0D, 0x21, 0x1A, 0xB2, -0x05, 0x21, 0x31, 0xB2, + 0x0D, 0x21, 0x1A, 0xB2, + 0x05, 0x21, 0x31, 0xB2, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x2D, 0x20, -0x25, 0x20, -0x05, 0x20, -0x0D, 0x20, + 0x2D, 0x20, + 0x25, 0x20, + 0x05, 0x20, + 0x0D, 0x20, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x2F, 0xC0, 0x21, 0xC0, + 0x33, 0xC0, 0x33, 0xAF, + 0x2F, 0xC0, 0x21, 0xC0, -0x16, 0x42, 0x56, 0x9F, -0x3C, 0x27, 0x4F, 0xE9, + 0x16, 0x42, 0x56, 0x9F, + 0x3C, 0x27, 0x4F, 0xE9, -0x1E, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x21, 0x31, 0xB4, -0x2D, 0x21, 0x1A, 0xB4, + 0x25, 0x21, 0x31, 0xB4, + 0x2D, 0x21, 0x1A, 0xB4, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0x05, -0x00, 0xE0, -0x28, 0x19, 0x60, 0xEC, + 0x33, 0x05, + 0x00, 0xE0, + 0x28, 0x19, 0x60, 0xEC, -0x0D, 0x44, 0x4C, 0xB6, -0x05, 0x44, 0x54, 0xB6, + 0x0D, 0x44, 0x4C, 0xB6, + 0x05, 0x44, 0x54, 0xB6, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x23, 0x3B, 0x33, 0xAD, -0x1E, 0x26, 0x1E, 0xDF, + 0x23, 0x3B, 0x33, 0xAD, + 0x1E, 0x26, 0x1E, 0xDF, -0xA7, 0x1E, 0x4F, 0xE9, -0x17, 0x26, 0x16, 0xDF, + 0xA7, 0x1E, 0x4F, 0xE9, + 0x17, 0x26, 0x16, 0xDF, -0x2D, 0x20, -0x00, 0xE0, -0xA8, 0x3F, 0x4F, 0xE9, + 0x2D, 0x20, + 0x00, 0xE0, + 0xA8, 0x3F, 0x4F, 0xE9, -0x2F, 0x2F, 0x1E, 0xAF, -0x25, 0x20, -0x00, 0xE0, + 0x2F, 0x2F, 0x1E, 0xAF, + 0x25, 0x20, + 0x00, 0xE0, -0xA4, 0x16, 0x4F, 0xE9, -0x0F, 0xC0, 0x21, 0xC2, + 0xA4, 0x16, 0x4F, 0xE9, + 0x0F, 0xC0, 0x21, 0xC2, -0xA6, 0x80, 0x4F, 0xE9, -0x1F, 0x62, 0x57, 0x9F, + 0xA6, 0x80, 0x4F, 0xE9, + 0x1F, 0x62, 0x57, 0x9F, -0x0D, 0x20, -0x05, 0x20, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x20, + 0x05, 0x20, + 0x00, 0x80, 0x00, 0xE8, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0xE0, -0x0F, 0x20, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0xE0, + 0x0F, 0x20, -0x17, 0x50, 0x56, 0x9F, -0xA5, 0x37, 0x4F, 0xE9, + 0x17, 0x50, 0x56, 0x9F, + 0xA5, 0x37, 0x4F, 0xE9, -0x06, 0xC0, 0x21, 0xC4, -0x0F, 0x17, 0x0F, 0xAF, + 0x06, 0xC0, 0x21, 0xC4, + 0x0F, 0x17, 0x0F, 0xAF, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x2F, 0xC0, 0x44, 0xC6, -0xA3, 0x80, 0x4F, 0xE9, + 0x2F, 0xC0, 0x44, 0xC6, + 0xA3, 0x80, 0x4F, 0xE9, -0x06, 0x20, -0x00, 0xE0, -0x1F, 0x26, 0x1F, 0xDF, + 0x06, 0x20, + 0x00, 0xE0, + 0x1F, 0x26, 0x1F, 0xDF, -0x17, 0x26, 0x17, 0xDF, -0x9D, 0x17, 0x4F, 0xE9, + 0x17, 0x26, 0x17, 0xDF, + 0x9D, 0x17, 0x4F, 0xE9, -0xA1, 0x1F, 0x4F, 0xE9, -0xA2, 0x3F, 0x4F, 0xE9, + 0xA1, 0x1F, 0x4F, 0xE9, + 0xA2, 0x3F, 0x4F, 0xE9, -0x06, 0x06, 0x1F, 0xAF, -0x00, 0xE0, -0xAF, 0x20, + 0x06, 0x06, 0x1F, 0xAF, + 0x00, 0xE0, + 0xAF, 0x20, -0x9E, 0x37, 0x4F, 0xE9, -0x2F, 0x17, 0x2F, 0xAF, + 0x9E, 0x37, 0x4F, 0xE9, + 0x2F, 0x17, 0x2F, 0xAF, -0xA0, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x9C, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x68, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x68, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x67, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x67, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x65, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x65, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x62, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x62, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzsaf[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x94, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x94, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x80, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x80, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x2D, 0x21, 0x1A, 0xB0, -0x25, 0x21, 0x31, 0xB0, + 0x2D, 0x21, 0x1A, 0xB0, + 0x25, 0x21, 0x31, 0xB0, -0x0D, 0x21, 0x1A, 0xB2, -0x05, 0x21, 0x31, 0xB2, + 0x0D, 0x21, 0x1A, 0xB2, + 0x05, 0x21, 0x31, 0xB2, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x2D, 0x20, -0x25, 0x20, -0x05, 0x20, -0x0D, 0x20, + 0x2D, 0x20, + 0x25, 0x20, + 0x05, 0x20, + 0x0D, 0x20, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x2F, 0xC0, 0x21, 0xC0, + 0x33, 0xC0, 0x33, 0xAF, + 0x2F, 0xC0, 0x21, 0xC0, -0x16, 0x42, 0x56, 0x9F, -0x3C, 0x27, 0x4F, 0xE9, + 0x16, 0x42, 0x56, 0x9F, + 0x3C, 0x27, 0x4F, 0xE9, -0x1E, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x21, 0x31, 0xB4, -0x2D, 0x21, 0x1A, 0xB4, + 0x25, 0x21, 0x31, 0xB4, + 0x2D, 0x21, 0x1A, 0xB4, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0x05, -0x00, 0xE0, -0x28, 0x19, 0x60, 0xEC, + 0x33, 0x05, + 0x00, 0xE0, + 0x28, 0x19, 0x60, 0xEC, -0x0D, 0x21, 0x1A, 0xB6, -0x05, 0x21, 0x31, 0xB6, + 0x0D, 0x21, 0x1A, 0xB6, + 0x05, 0x21, 0x31, 0xB6, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x23, 0x3B, 0x33, 0xAD, -0x1E, 0x26, 0x1E, 0xDF, + 0x23, 0x3B, 0x33, 0xAD, + 0x1E, 0x26, 0x1E, 0xDF, -0xA7, 0x1E, 0x4F, 0xE9, -0x17, 0x26, 0x16, 0xDF, + 0xA7, 0x1E, 0x4F, 0xE9, + 0x17, 0x26, 0x16, 0xDF, -0x2D, 0x20, -0x00, 0xE0, -0xA8, 0x3F, 0x4F, 0xE9, + 0x2D, 0x20, + 0x00, 0xE0, + 0xA8, 0x3F, 0x4F, 0xE9, -0x2F, 0x2F, 0x1E, 0xAF, -0x25, 0x20, -0x00, 0xE0, + 0x2F, 0x2F, 0x1E, 0xAF, + 0x25, 0x20, + 0x00, 0xE0, -0xA4, 0x16, 0x4F, 0xE9, -0x0F, 0xC0, 0x21, 0xC2, + 0xA4, 0x16, 0x4F, 0xE9, + 0x0F, 0xC0, 0x21, 0xC2, -0xA6, 0x80, 0x4F, 0xE9, -0x1F, 0x62, 0x57, 0x9F, + 0xA6, 0x80, 0x4F, 0xE9, + 0x1F, 0x62, 0x57, 0x9F, -0x0D, 0x20, -0x05, 0x20, -0x2F, 0xC0, 0x21, 0xC6, + 0x0D, 0x20, + 0x05, 0x20, + 0x2F, 0xC0, 0x21, 0xC6, -0x2D, 0x44, 0x4C, 0xB6, -0x25, 0x44, 0x54, 0xB6, + 0x2D, 0x44, 0x4C, 0xB6, + 0x25, 0x44, 0x54, 0xB6, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0xE0, -0x0F, 0x20, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0xE0, + 0x0F, 0x20, -0x2D, 0x20, -0x25, 0x20, -0x07, 0xC0, 0x44, 0xC6, + 0x2D, 0x20, + 0x25, 0x20, + 0x07, 0xC0, 0x44, 0xC6, -0x17, 0x50, 0x56, 0x9F, -0xA5, 0x37, 0x4F, 0xE9, + 0x17, 0x50, 0x56, 0x9F, + 0xA5, 0x37, 0x4F, 0xE9, -0x06, 0xC0, 0x21, 0xC4, -0x0F, 0x17, 0x0F, 0xAF, + 0x06, 0xC0, 0x21, 0xC4, + 0x0F, 0x17, 0x0F, 0xAF, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x1E, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x3E, 0x3D, 0x5D, 0x9F, -0x00, 0xE0, -0x07, 0x20, + 0x3E, 0x3D, 0x5D, 0x9F, + 0x00, 0xE0, + 0x07, 0x20, -0x2F, 0x20, -0x00, 0xE0, -0xA3, 0x0F, 0x4F, 0xE9, + 0x2F, 0x20, + 0x00, 0xE0, + 0xA3, 0x0F, 0x4F, 0xE9, -0x06, 0x20, -0x00, 0xE0, -0x1F, 0x26, 0x1F, 0xDF, + 0x06, 0x20, + 0x00, 0xE0, + 0x1F, 0x26, 0x1F, 0xDF, -0x17, 0x26, 0x17, 0xDF, -0xA1, 0x1F, 0x4F, 0xE9, + 0x17, 0x26, 0x17, 0xDF, + 0xA1, 0x1F, 0x4F, 0xE9, -0x1E, 0x26, 0x1E, 0xDF, -0x9D, 0x1E, 0x4F, 0xE9, + 0x1E, 0x26, 0x1E, 0xDF, + 0x9D, 0x1E, 0x4F, 0xE9, -0x35, 0x17, 0x4F, 0xE9, -0xA2, 0x3F, 0x4F, 0xE9, + 0x35, 0x17, 0x4F, 0xE9, + 0xA2, 0x3F, 0x4F, 0xE9, -0x06, 0x06, 0x1F, 0xAF, -0x39, 0x37, 0x4F, 0xE9, + 0x06, 0x06, 0x1F, 0xAF, + 0x39, 0x37, 0x4F, 0xE9, -0x2F, 0x2F, 0x17, 0xAF, -0x07, 0x07, 0x1E, 0xAF, + 0x2F, 0x2F, 0x17, 0xAF, + 0x07, 0x07, 0x1E, 0xAF, -0xA0, 0x80, 0x4F, 0xE9, -0x9E, 0x3E, 0x4F, 0xE9, + 0xA0, 0x80, 0x4F, 0xE9, + 0x9E, 0x3E, 0x4F, 0xE9, -0x31, 0x80, 0x4F, 0xE9, -0x9C, 0x80, 0x4F, 0xE9, + 0x31, 0x80, 0x4F, 0xE9, + 0x9C, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x63, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x63, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x62, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x62, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x60, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x60, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x5D, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x5D, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g200_tgzsf[] = { -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x98, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x98, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x81, 0x04, -0x89, 0x04, -0x01, 0x04, -0x09, 0x04, + 0x81, 0x04, + 0x89, 0x04, + 0x01, 0x04, + 0x09, 0x04, -0xC9, 0x41, 0xC0, 0xEC, -0x11, 0x04, -0x00, 0xE0, + 0xC9, 0x41, 0xC0, 0xEC, + 0x11, 0x04, + 0x00, 0xE0, -0x41, 0xCC, 0x41, 0xCD, -0x49, 0xCC, 0x49, 0xCD, + 0x41, 0xCC, 0x41, 0xCD, + 0x49, 0xCC, 0x49, 0xCD, -0xD1, 0x41, 0xC0, 0xEC, -0x51, 0xCC, 0x51, 0xCD, + 0xD1, 0x41, 0xC0, 0xEC, + 0x51, 0xCC, 0x51, 0xCD, -0x80, 0x04, -0x10, 0x04, -0x08, 0x04, -0x00, 0xE0, + 0x80, 0x04, + 0x10, 0x04, + 0x08, 0x04, + 0x00, 0xE0, -0x00, 0xCC, 0xC0, 0xCD, -0xD1, 0x49, 0xC0, 0xEC, + 0x00, 0xCC, 0xC0, 0xCD, + 0xD1, 0x49, 0xC0, 0xEC, -0x8A, 0x1F, 0x20, 0xE9, -0x8B, 0x3F, 0x20, 0xE9, + 0x8A, 0x1F, 0x20, 0xE9, + 0x8B, 0x3F, 0x20, 0xE9, -0x41, 0x3C, 0x41, 0xAD, -0x49, 0x3C, 0x49, 0xAD, + 0x41, 0x3C, 0x41, 0xAD, + 0x49, 0x3C, 0x49, 0xAD, -0x10, 0xCC, 0x10, 0xCD, -0x08, 0xCC, 0x08, 0xCD, + 0x10, 0xCC, 0x10, 0xCD, + 0x08, 0xCC, 0x08, 0xCD, -0xB9, 0x41, 0x49, 0xBB, -0x1F, 0xF0, 0x41, 0xCD, + 0xB9, 0x41, 0x49, 0xBB, + 0x1F, 0xF0, 0x41, 0xCD, -0x51, 0x3C, 0x51, 0xAD, -0x00, 0x98, 0x80, 0xE9, + 0x51, 0x3C, 0x51, 0xAD, + 0x00, 0x98, 0x80, 0xE9, -0x8F, 0x80, 0x07, 0xEA, -0x24, 0x1F, 0x20, 0xE9, + 0x8F, 0x80, 0x07, 0xEA, + 0x24, 0x1F, 0x20, 0xE9, -0x21, 0x45, 0x80, 0xE8, -0x1A, 0x4D, 0x80, 0xE8, + 0x21, 0x45, 0x80, 0xE8, + 0x1A, 0x4D, 0x80, 0xE8, -0x31, 0x55, 0x80, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x55, 0x80, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0x41, 0x49, 0xBD, -0x1D, 0x41, 0x51, 0xBD, + 0x15, 0x41, 0x49, 0xBD, + 0x1D, 0x41, 0x51, 0xBD, -0x2E, 0x41, 0x2A, 0xB8, -0x34, 0x53, 0xA0, 0xE8, + 0x2E, 0x41, 0x2A, 0xB8, + 0x34, 0x53, 0xA0, 0xE8, -0x15, 0x30, -0x1D, 0x30, -0x58, 0xE3, -0x00, 0xE0, + 0x15, 0x30, + 0x1D, 0x30, + 0x58, 0xE3, + 0x00, 0xE0, -0xB5, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0xB5, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x24, 0x43, 0xA0, 0xE8, -0x2C, 0x4B, 0xA0, 0xE8, + 0x24, 0x43, 0xA0, 0xE8, + 0x2C, 0x4B, 0xA0, 0xE8, -0x15, 0x72, -0x09, 0xE3, -0x00, 0xE0, -0x1D, 0x72, + 0x15, 0x72, + 0x09, 0xE3, + 0x00, 0xE0, + 0x1D, 0x72, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0x97, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0x97, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x6C, 0x64, 0xC8, 0xEC, -0x98, 0xE1, -0xB5, 0x05, + 0x6C, 0x64, 0xC8, 0xEC, + 0x98, 0xE1, + 0xB5, 0x05, -0xBD, 0x05, -0x2E, 0x30, -0x32, 0xC0, 0xA0, 0xE8, + 0xBD, 0x05, + 0x2E, 0x30, + 0x32, 0xC0, 0xA0, 0xE8, -0x33, 0xC0, 0xA0, 0xE8, -0x74, 0x64, 0xC8, 0xEC, + 0x33, 0xC0, 0xA0, 0xE8, + 0x74, 0x64, 0xC8, 0xEC, -0x40, 0x3C, 0x40, 0xAD, -0x32, 0x6A, -0x2A, 0x30, + 0x40, 0x3C, 0x40, 0xAD, + 0x32, 0x6A, + 0x2A, 0x30, -0x20, 0x73, -0x33, 0x6A, -0x00, 0xE0, -0x28, 0x73, + 0x20, 0x73, + 0x33, 0x6A, + 0x00, 0xE0, + 0x28, 0x73, -0x1C, 0x72, -0x83, 0xE2, -0x7B, 0x80, 0x15, 0xEA, + 0x1C, 0x72, + 0x83, 0xE2, + 0x7B, 0x80, 0x15, 0xEA, -0xB8, 0x3D, 0x28, 0xDF, -0x30, 0x35, 0x20, 0xDF, + 0xB8, 0x3D, 0x28, 0xDF, + 0x30, 0x35, 0x20, 0xDF, -0x40, 0x30, -0x00, 0xE0, -0xCC, 0xE2, -0x64, 0x72, + 0x40, 0x30, + 0x00, 0xE0, + 0xCC, 0xE2, + 0x64, 0x72, -0x25, 0x42, 0x52, 0xBF, -0x2D, 0x42, 0x4A, 0xBF, + 0x25, 0x42, 0x52, 0xBF, + 0x2D, 0x42, 0x4A, 0xBF, -0x30, 0x2E, 0x30, 0xDF, -0x38, 0x2E, 0x38, 0xDF, + 0x30, 0x2E, 0x30, 0xDF, + 0x38, 0x2E, 0x38, 0xDF, -0x18, 0x1D, 0x45, 0xE9, -0x1E, 0x15, 0x45, 0xE9, + 0x18, 0x1D, 0x45, 0xE9, + 0x1E, 0x15, 0x45, 0xE9, -0x2B, 0x49, 0x51, 0xBD, -0x00, 0xE0, -0x1F, 0x73, + 0x2B, 0x49, 0x51, 0xBD, + 0x00, 0xE0, + 0x1F, 0x73, -0x38, 0x38, 0x40, 0xAF, -0x30, 0x30, 0x40, 0xAF, + 0x38, 0x38, 0x40, 0xAF, + 0x30, 0x30, 0x40, 0xAF, -0x24, 0x1F, 0x24, 0xDF, -0x1D, 0x32, 0x20, 0xE9, + 0x24, 0x1F, 0x24, 0xDF, + 0x1D, 0x32, 0x20, 0xE9, -0x2C, 0x1F, 0x2C, 0xDF, -0x1A, 0x33, 0x20, 0xE9, + 0x2C, 0x1F, 0x2C, 0xDF, + 0x1A, 0x33, 0x20, 0xE9, -0xB0, 0x10, -0x08, 0xE3, -0x40, 0x10, -0xB8, 0x10, + 0xB0, 0x10, + 0x08, 0xE3, + 0x40, 0x10, + 0xB8, 0x10, -0x26, 0xF0, 0x30, 0xCD, -0x2F, 0xF0, 0x38, 0xCD, + 0x26, 0xF0, 0x30, 0xCD, + 0x2F, 0xF0, 0x38, 0xCD, -0x2B, 0x80, 0x20, 0xE9, -0x2A, 0x80, 0x20, 0xE9, + 0x2B, 0x80, 0x20, 0xE9, + 0x2A, 0x80, 0x20, 0xE9, -0xA6, 0x20, -0x88, 0xE2, -0x00, 0xE0, -0xAF, 0x20, + 0xA6, 0x20, + 0x88, 0xE2, + 0x00, 0xE0, + 0xAF, 0x20, -0x28, 0x2A, 0x26, 0xAF, -0x20, 0x2A, 0xC0, 0xAF, + 0x28, 0x2A, 0x26, 0xAF, + 0x20, 0x2A, 0xC0, 0xAF, -0x34, 0x1F, 0x34, 0xDF, -0x46, 0x24, 0x46, 0xDF, + 0x34, 0x1F, 0x34, 0xDF, + 0x46, 0x24, 0x46, 0xDF, -0x28, 0x30, 0x80, 0xBF, -0x20, 0x38, 0x80, 0xBF, + 0x28, 0x30, 0x80, 0xBF, + 0x20, 0x38, 0x80, 0xBF, -0x47, 0x24, 0x47, 0xDF, -0x4E, 0x2C, 0x4E, 0xDF, + 0x47, 0x24, 0x47, 0xDF, + 0x4E, 0x2C, 0x4E, 0xDF, -0x4F, 0x2C, 0x4F, 0xDF, -0x56, 0x34, 0x56, 0xDF, + 0x4F, 0x2C, 0x4F, 0xDF, + 0x56, 0x34, 0x56, 0xDF, -0x28, 0x15, 0x28, 0xDF, -0x20, 0x1D, 0x20, 0xDF, + 0x28, 0x15, 0x28, 0xDF, + 0x20, 0x1D, 0x20, 0xDF, -0x57, 0x34, 0x57, 0xDF, -0x00, 0xE0, -0x1D, 0x05, + 0x57, 0x34, 0x57, 0xDF, + 0x00, 0xE0, + 0x1D, 0x05, -0x04, 0x80, 0x10, 0xEA, -0x89, 0xE2, -0x2B, 0x30, + 0x04, 0x80, 0x10, 0xEA, + 0x89, 0xE2, + 0x2B, 0x30, -0x3F, 0xC1, 0x1D, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0xC1, 0x1D, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x68, -0xBF, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x68, + 0xBF, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x20, 0xC0, 0x20, 0xAF, -0x28, 0x05, -0x97, 0x74, + 0x20, 0xC0, 0x20, 0xAF, + 0x28, 0x05, + 0x97, 0x74, -0x00, 0xE0, -0x2A, 0x10, -0x16, 0xC0, 0x20, 0xE9, + 0x00, 0xE0, + 0x2A, 0x10, + 0x16, 0xC0, 0x20, 0xE9, -0x04, 0x80, 0x10, 0xEA, -0x8C, 0xE2, -0x95, 0x05, + 0x04, 0x80, 0x10, 0xEA, + 0x8C, 0xE2, + 0x95, 0x05, -0x28, 0xC1, 0x28, 0xAD, -0x1F, 0xC1, 0x15, 0xBD, + 0x28, 0xC1, 0x28, 0xAD, + 0x1F, 0xC1, 0x15, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xA8, 0x67, -0x9F, 0x6B, -0x00, 0x80, 0x00, 0xE8, + 0xA8, 0x67, + 0x9F, 0x6B, + 0x00, 0x80, 0x00, 0xE8, -0x28, 0xC0, 0x28, 0xAD, -0x1D, 0x25, -0x20, 0x05, + 0x28, 0xC0, 0x28, 0xAD, + 0x1D, 0x25, + 0x20, 0x05, -0x28, 0x32, 0x80, 0xAD, -0x40, 0x2A, 0x40, 0xBD, + 0x28, 0x32, 0x80, 0xAD, + 0x40, 0x2A, 0x40, 0xBD, -0x1C, 0x80, 0x20, 0xE9, -0x20, 0x33, 0x20, 0xAD, + 0x1C, 0x80, 0x20, 0xE9, + 0x20, 0x33, 0x20, 0xAD, -0x20, 0x73, -0x00, 0xE0, -0xB6, 0x49, 0x51, 0xBB, + 0x20, 0x73, + 0x00, 0xE0, + 0xB6, 0x49, 0x51, 0xBB, -0x26, 0x2F, 0xB0, 0xE8, -0x19, 0x20, 0x20, 0xE9, + 0x26, 0x2F, 0xB0, 0xE8, + 0x19, 0x20, 0x20, 0xE9, -0x35, 0x20, 0x35, 0xDF, -0x3D, 0x20, 0x3D, 0xDF, + 0x35, 0x20, 0x35, 0xDF, + 0x3D, 0x20, 0x3D, 0xDF, -0x15, 0x20, 0x15, 0xDF, -0x1D, 0x20, 0x1D, 0xDF, + 0x15, 0x20, 0x15, 0xDF, + 0x1D, 0x20, 0x1D, 0xDF, -0x26, 0xD0, 0x26, 0xCD, -0x29, 0x49, 0x2A, 0xB8, + 0x26, 0xD0, 0x26, 0xCD, + 0x29, 0x49, 0x2A, 0xB8, -0x26, 0x40, 0x80, 0xBD, -0x3B, 0x48, 0x50, 0xBD, + 0x26, 0x40, 0x80, 0xBD, + 0x3B, 0x48, 0x50, 0xBD, -0x3E, 0x54, 0x57, 0x9F, -0x00, 0xE0, -0x82, 0xE1, + 0x3E, 0x54, 0x57, 0x9F, + 0x00, 0xE0, + 0x82, 0xE1, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x26, 0x30, -0x29, 0x30, -0x48, 0x3C, 0x48, 0xAD, + 0x26, 0x30, + 0x29, 0x30, + 0x48, 0x3C, 0x48, 0xAD, -0x2B, 0x72, -0xC2, 0xE1, -0x2C, 0xC0, 0x44, 0xC2, + 0x2B, 0x72, + 0xC2, 0xE1, + 0x2C, 0xC0, 0x44, 0xC2, -0x05, 0x24, 0x34, 0xBF, -0x0D, 0x24, 0x2C, 0xBF, + 0x05, 0x24, 0x34, 0xBF, + 0x0D, 0x24, 0x2C, 0xBF, -0x2D, 0x46, 0x4E, 0xBF, -0x25, 0x46, 0x56, 0xBF, + 0x2D, 0x46, 0x4E, 0xBF, + 0x25, 0x46, 0x56, 0xBF, -0x20, 0x1D, 0x6F, 0x8F, -0x32, 0x3E, 0x5F, 0xE9, + 0x20, 0x1D, 0x6F, 0x8F, + 0x32, 0x3E, 0x5F, 0xE9, -0x3E, 0x50, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x30, + 0x3E, 0x50, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x30, -0x1E, 0x8F, 0x51, 0x9F, -0x33, 0x1E, 0x5F, 0xE9, + 0x1E, 0x8F, 0x51, 0x9F, + 0x33, 0x1E, 0x5F, 0xE9, -0x05, 0x44, 0x54, 0xB2, -0x0D, 0x44, 0x4C, 0xB2, + 0x05, 0x44, 0x54, 0xB2, + 0x0D, 0x44, 0x4C, 0xB2, -0x19, 0xC0, 0xB0, 0xE8, -0x34, 0xC0, 0x44, 0xC4, + 0x19, 0xC0, 0xB0, 0xE8, + 0x34, 0xC0, 0x44, 0xC4, -0x33, 0x73, -0x00, 0xE0, -0x3E, 0x62, 0x57, 0x9F, + 0x33, 0x73, + 0x00, 0xE0, + 0x3E, 0x62, 0x57, 0x9F, -0x1E, 0xAF, 0x59, 0x9F, -0x00, 0xE0, -0x0D, 0x20, + 0x1E, 0xAF, 0x59, 0x9F, + 0x00, 0xE0, + 0x0D, 0x20, -0x84, 0x3E, 0x58, 0xE9, -0x28, 0x1D, 0x6F, 0x8F, + 0x84, 0x3E, 0x58, 0xE9, + 0x28, 0x1D, 0x6F, 0x8F, -0x05, 0x20, -0x00, 0xE0, -0x85, 0x1E, 0x58, 0xE9, + 0x05, 0x20, + 0x00, 0xE0, + 0x85, 0x1E, 0x58, 0xE9, -0x9B, 0x3B, 0x33, 0xDF, -0x20, 0x20, 0x42, 0xAF, + 0x9B, 0x3B, 0x33, 0xDF, + 0x20, 0x20, 0x42, 0xAF, -0x30, 0x42, 0x56, 0x9F, -0x80, 0x3E, 0x57, 0xE9, + 0x30, 0x42, 0x56, 0x9F, + 0x80, 0x3E, 0x57, 0xE9, -0x3F, 0x8F, 0x51, 0x9F, -0x30, 0x80, 0x5F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x30, 0x80, 0x5F, 0xE9, -0x28, 0x28, 0x24, 0xAF, -0x81, 0x1E, 0x57, 0xE9, + 0x28, 0x28, 0x24, 0xAF, + 0x81, 0x1E, 0x57, 0xE9, -0x05, 0x47, 0x57, 0xBF, -0x0D, 0x47, 0x4F, 0xBF, + 0x05, 0x47, 0x57, 0xBF, + 0x0D, 0x47, 0x4F, 0xBF, -0x88, 0x80, 0x58, 0xE9, -0x1B, 0x29, 0x1B, 0xDF, + 0x88, 0x80, 0x58, 0xE9, + 0x1B, 0x29, 0x1B, 0xDF, -0x30, 0x1D, 0x6F, 0x8F, -0x3A, 0x30, 0x4F, 0xE9, + 0x30, 0x1D, 0x6F, 0x8F, + 0x3A, 0x30, 0x4F, 0xE9, -0x1C, 0x30, 0x26, 0xDF, -0x09, 0xE3, -0x3B, 0x05, + 0x1C, 0x30, 0x26, 0xDF, + 0x09, 0xE3, + 0x3B, 0x05, -0x3E, 0x50, 0x56, 0x9F, -0x3B, 0x3F, 0x4F, 0xE9, + 0x3E, 0x50, 0x56, 0x9F, + 0x3B, 0x3F, 0x4F, 0xE9, -0x1E, 0x8F, 0x51, 0x9F, -0x00, 0xE0, -0xAC, 0x20, + 0x1E, 0x8F, 0x51, 0x9F, + 0x00, 0xE0, + 0xAC, 0x20, -0x2D, 0x44, 0x4C, 0xB4, -0x2C, 0x1C, 0xC0, 0xAF, + 0x2D, 0x44, 0x4C, 0xB4, + 0x2C, 0x1C, 0xC0, 0xAF, -0x25, 0x44, 0x54, 0xB4, -0x00, 0xE0, -0xC8, 0x30, + 0x25, 0x44, 0x54, 0xB4, + 0x00, 0xE0, + 0xC8, 0x30, -0x30, 0x46, 0x30, 0xAF, -0x1B, 0x1B, 0x48, 0xAF, + 0x30, 0x46, 0x30, 0xAF, + 0x1B, 0x1B, 0x48, 0xAF, -0x00, 0xE0, -0x25, 0x20, -0x38, 0x2C, 0x4F, 0xE9, + 0x00, 0xE0, + 0x25, 0x20, + 0x38, 0x2C, 0x4F, 0xE9, -0x86, 0x80, 0x57, 0xE9, -0x38, 0x1D, 0x6F, 0x8F, + 0x86, 0x80, 0x57, 0xE9, + 0x38, 0x1D, 0x6F, 0x8F, -0x28, 0x74, -0x00, 0xE0, -0x0D, 0x44, 0x4C, 0xB0, + 0x28, 0x74, + 0x00, 0xE0, + 0x0D, 0x44, 0x4C, 0xB0, -0x05, 0x44, 0x54, 0xB0, -0x2D, 0x20, -0x9B, 0x10, + 0x05, 0x44, 0x54, 0xB0, + 0x2D, 0x20, + 0x9B, 0x10, -0x82, 0x3E, 0x57, 0xE9, -0x32, 0xF0, 0x1B, 0xCD, + 0x82, 0x3E, 0x57, 0xE9, + 0x32, 0xF0, 0x1B, 0xCD, -0x1E, 0xBD, 0x59, 0x9F, -0x83, 0x1E, 0x57, 0xE9, + 0x1E, 0xBD, 0x59, 0x9F, + 0x83, 0x1E, 0x57, 0xE9, -0x38, 0x47, 0x38, 0xAF, -0x34, 0x20, -0x2A, 0x30, + 0x38, 0x47, 0x38, 0xAF, + 0x34, 0x20, + 0x2A, 0x30, -0x00, 0xE0, -0x0D, 0x20, -0x32, 0x20, -0x05, 0x20, + 0x00, 0xE0, + 0x0D, 0x20, + 0x32, 0x20, + 0x05, 0x20, -0x87, 0x80, 0x57, 0xE9, -0x1F, 0x54, 0x57, 0x9F, + 0x87, 0x80, 0x57, 0xE9, + 0x1F, 0x54, 0x57, 0x9F, -0x17, 0x42, 0x56, 0x9F, -0x00, 0xE0, -0x3B, 0x6A, + 0x17, 0x42, 0x56, 0x9F, + 0x00, 0xE0, + 0x3B, 0x6A, -0x3F, 0x8F, 0x51, 0x9F, -0x37, 0x1E, 0x4F, 0xE9, + 0x3F, 0x8F, 0x51, 0x9F, + 0x37, 0x1E, 0x4F, 0xE9, -0x37, 0x32, 0x2A, 0xAF, -0x00, 0xE0, -0x32, 0x00, + 0x37, 0x32, 0x2A, 0xAF, + 0x00, 0xE0, + 0x32, 0x00, -0x00, 0x80, 0x00, 0xE8, -0x27, 0xC0, 0x44, 0xC0, + 0x00, 0x80, 0x00, 0xE8, + 0x27, 0xC0, 0x44, 0xC0, -0x36, 0x1F, 0x4F, 0xE9, -0x1F, 0x1F, 0x26, 0xDF, + 0x36, 0x1F, 0x4F, 0xE9, + 0x1F, 0x1F, 0x26, 0xDF, -0x37, 0x1B, 0x37, 0xBF, -0x17, 0x26, 0x17, 0xDF, + 0x37, 0x1B, 0x37, 0xBF, + 0x17, 0x26, 0x17, 0xDF, -0x3E, 0x17, 0x4F, 0xE9, -0x3F, 0x3F, 0x4F, 0xE9, + 0x3E, 0x17, 0x4F, 0xE9, + 0x3F, 0x3F, 0x4F, 0xE9, -0x34, 0x1F, 0x34, 0xAF, -0x2B, 0x05, -0xA7, 0x20, + 0x34, 0x1F, 0x34, 0xAF, + 0x2B, 0x05, + 0xA7, 0x20, -0x33, 0x2B, 0x37, 0xDF, -0x27, 0x17, 0xC0, 0xAF, + 0x33, 0x2B, 0x37, 0xDF, + 0x27, 0x17, 0xC0, 0xAF, -0x34, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x34, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x2D, 0x21, 0x1A, 0xB0, -0x25, 0x21, 0x31, 0xB0, + 0x2D, 0x21, 0x1A, 0xB0, + 0x25, 0x21, 0x31, 0xB0, -0x0D, 0x21, 0x1A, 0xB2, -0x05, 0x21, 0x31, 0xB2, + 0x0D, 0x21, 0x1A, 0xB2, + 0x05, 0x21, 0x31, 0xB2, -0x03, 0x80, 0x2A, 0xEA, -0x17, 0xC1, 0x2B, 0xBD, + 0x03, 0x80, 0x2A, 0xEA, + 0x17, 0xC1, 0x2B, 0xBD, -0x2D, 0x20, -0x25, 0x20, -0x05, 0x20, -0x0D, 0x20, + 0x2D, 0x20, + 0x25, 0x20, + 0x05, 0x20, + 0x0D, 0x20, -0xB3, 0x68, -0x97, 0x25, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0x68, + 0x97, 0x25, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0xC0, 0x33, 0xAF, -0x2F, 0xC0, 0x21, 0xC0, + 0x33, 0xC0, 0x33, 0xAF, + 0x2F, 0xC0, 0x21, 0xC0, -0x16, 0x42, 0x56, 0x9F, -0x3C, 0x27, 0x4F, 0xE9, + 0x16, 0x42, 0x56, 0x9F, + 0x3C, 0x27, 0x4F, 0xE9, -0x1E, 0x62, 0x57, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x1E, 0x62, 0x57, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x21, 0x31, 0xB4, -0x2D, 0x21, 0x1A, 0xB4, + 0x25, 0x21, 0x31, 0xB4, + 0x2D, 0x21, 0x1A, 0xB4, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x33, 0x05, -0x00, 0xE0, -0x28, 0x19, 0x60, 0xEC, + 0x33, 0x05, + 0x00, 0xE0, + 0x28, 0x19, 0x60, 0xEC, -0x0D, 0x21, 0x1A, 0xB6, -0x05, 0x21, 0x31, 0xB6, + 0x0D, 0x21, 0x1A, 0xB6, + 0x05, 0x21, 0x31, 0xB6, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0xE0, -0x2F, 0x20, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0xE0, + 0x2F, 0x20, -0x23, 0x3B, 0x33, 0xAD, -0x1E, 0x26, 0x1E, 0xDF, + 0x23, 0x3B, 0x33, 0xAD, + 0x1E, 0x26, 0x1E, 0xDF, -0xA7, 0x1E, 0x4F, 0xE9, -0x17, 0x26, 0x16, 0xDF, + 0xA7, 0x1E, 0x4F, 0xE9, + 0x17, 0x26, 0x16, 0xDF, -0x2D, 0x20, -0x00, 0xE0, -0xA8, 0x3F, 0x4F, 0xE9, + 0x2D, 0x20, + 0x00, 0xE0, + 0xA8, 0x3F, 0x4F, 0xE9, -0x2F, 0x2F, 0x1E, 0xAF, -0x25, 0x20, -0x00, 0xE0, + 0x2F, 0x2F, 0x1E, 0xAF, + 0x25, 0x20, + 0x00, 0xE0, -0xA4, 0x16, 0x4F, 0xE9, -0x0F, 0xC0, 0x21, 0xC2, + 0xA4, 0x16, 0x4F, 0xE9, + 0x0F, 0xC0, 0x21, 0xC2, -0xA6, 0x80, 0x4F, 0xE9, -0x1F, 0x62, 0x57, 0x9F, + 0xA6, 0x80, 0x4F, 0xE9, + 0x1F, 0x62, 0x57, 0x9F, -0x0D, 0x20, -0x05, 0x20, -0x2F, 0xC0, 0x21, 0xC6, + 0x0D, 0x20, + 0x05, 0x20, + 0x2F, 0xC0, 0x21, 0xC6, -0x3F, 0x2F, 0x5D, 0x9F, -0x00, 0xE0, -0x0F, 0x20, + 0x3F, 0x2F, 0x5D, 0x9F, + 0x00, 0xE0, + 0x0F, 0x20, -0x17, 0x50, 0x56, 0x9F, -0xA5, 0x37, 0x4F, 0xE9, + 0x17, 0x50, 0x56, 0x9F, + 0xA5, 0x37, 0x4F, 0xE9, -0x06, 0xC0, 0x21, 0xC4, -0x0F, 0x17, 0x0F, 0xAF, + 0x06, 0xC0, 0x21, 0xC4, + 0x0F, 0x17, 0x0F, 0xAF, -0x37, 0x0F, 0x5C, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x37, 0x0F, 0x5C, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x2F, 0x20, -0x00, 0xE0, -0xA3, 0x80, 0x4F, 0xE9, + 0x2F, 0x20, + 0x00, 0xE0, + 0xA3, 0x80, 0x4F, 0xE9, -0x06, 0x20, -0x00, 0xE0, -0x1F, 0x26, 0x1F, 0xDF, + 0x06, 0x20, + 0x00, 0xE0, + 0x1F, 0x26, 0x1F, 0xDF, -0x17, 0x26, 0x17, 0xDF, -0x35, 0x17, 0x4F, 0xE9, + 0x17, 0x26, 0x17, 0xDF, + 0x35, 0x17, 0x4F, 0xE9, -0xA1, 0x1F, 0x4F, 0xE9, -0xA2, 0x3F, 0x4F, 0xE9, + 0xA1, 0x1F, 0x4F, 0xE9, + 0xA2, 0x3F, 0x4F, 0xE9, -0x06, 0x06, 0x1F, 0xAF, -0x39, 0x37, 0x4F, 0xE9, + 0x06, 0x06, 0x1F, 0xAF, + 0x39, 0x37, 0x4F, 0xE9, -0x2F, 0x2F, 0x17, 0xAF, -0x00, 0x80, 0x00, 0xE8, + 0x2F, 0x2F, 0x17, 0xAF, + 0x00, 0x80, 0x00, 0xE8, -0xA0, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xA0, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x31, 0x80, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x80, 0x4F, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x57, 0x39, 0x20, 0xE9, + 0x00, 0x80, 0x00, 0xE8, + 0x57, 0x39, 0x20, 0xE9, -0x16, 0x28, 0x20, 0xE9, -0x1D, 0x3B, 0x20, 0xE9, + 0x16, 0x28, 0x20, 0xE9, + 0x1D, 0x3B, 0x20, 0xE9, -0x1E, 0x2B, 0x20, 0xE9, -0x2B, 0x32, 0x20, 0xE9, + 0x1E, 0x2B, 0x20, 0xE9, + 0x2B, 0x32, 0x20, 0xE9, -0x1C, 0x23, 0x20, 0xE9, -0x57, 0x36, 0x20, 0xE9, + 0x1C, 0x23, 0x20, 0xE9, + 0x57, 0x36, 0x20, 0xE9, -0x00, 0x80, 0xA0, 0xE9, -0x40, 0x40, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x40, 0x40, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x90, 0xE2, -0x00, 0xE0, + 0xFF, 0x80, 0xC0, 0xE9, + 0x90, 0xE2, + 0x00, 0xE0, -0x68, 0xFF, 0x20, 0xEA, -0x19, 0xC8, 0xC1, 0xCD, + 0x68, 0xFF, 0x20, 0xEA, + 0x19, 0xC8, 0xC1, 0xCD, -0x1F, 0xD7, 0x18, 0xBD, -0x3F, 0xD7, 0x22, 0xBD, + 0x1F, 0xD7, 0x18, 0xBD, + 0x3F, 0xD7, 0x22, 0xBD, -0x9F, 0x41, 0x49, 0xBD, -0x00, 0x80, 0x00, 0xE8, + 0x9F, 0x41, 0x49, 0xBD, + 0x00, 0x80, 0x00, 0xE8, -0x25, 0x41, 0x49, 0xBD, -0x2D, 0x41, 0x51, 0xBD, + 0x25, 0x41, 0x49, 0xBD, + 0x2D, 0x41, 0x51, 0xBD, -0x0D, 0x80, 0x07, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x0D, 0x80, 0x07, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x35, 0x40, 0x48, 0xBD, -0x3D, 0x40, 0x50, 0xBD, + 0x35, 0x40, 0x48, 0xBD, + 0x3D, 0x40, 0x50, 0xBD, -0x00, 0x80, 0x00, 0xE8, -0x25, 0x30, -0x2D, 0x30, + 0x00, 0x80, 0x00, 0xE8, + 0x25, 0x30, + 0x2D, 0x30, -0x35, 0x30, -0xB5, 0x30, -0xBD, 0x30, -0x3D, 0x30, + 0x35, 0x30, + 0xB5, 0x30, + 0xBD, 0x30, + 0x3D, 0x30, -0x9C, 0xA7, 0x5B, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x9C, 0xA7, 0x5B, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x67, 0xFF, 0x0A, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x67, 0xFF, 0x0A, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0xC9, 0x41, 0xC8, 0xEC, -0x42, 0xE1, -0x00, 0xE0, + 0xC9, 0x41, 0xC8, 0xEC, + 0x42, 0xE1, + 0x00, 0xE0, -0x65, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x65, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0xC8, 0x40, 0xC0, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0xC8, 0x40, 0xC0, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x62, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0x62, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, }; static unsigned char warp_g400_t2gz[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x78, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x78, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x69, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x69, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x25, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x25, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x74, 0xC2, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x53, 0x2F, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x2A, 0x44, 0x54, 0xB4, -0x1A, 0x44, 0x64, 0xB4, + 0x2A, 0x44, 0x54, 0xB4, + 0x1A, 0x44, 0x64, 0xB4, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x9F, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x9F, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xBE, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xBE, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x7D, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x7D, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gza[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x7C, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x7C, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x6D, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x6D, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x29, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x29, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x0F, 0xCF, 0x74, 0xC6, -0x3D, 0xCF, 0x74, 0xC2, + 0x0F, 0xCF, 0x74, 0xC6, + 0x3D, 0xCF, 0x74, 0xC2, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x0F, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB4, -0x02, 0x44, 0x64, 0xB4, + 0x0A, 0x44, 0x54, 0xB4, + 0x02, 0x44, 0x64, 0xB4, -0x2A, 0x44, 0x54, 0xB6, -0x1A, 0x44, 0x64, 0xB6, + 0x2A, 0x44, 0x54, 0xB6, + 0x1A, 0x44, 0x64, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x9B, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x9B, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xBA, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xBA, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x79, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x79, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzaf[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x81, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x81, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x72, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x72, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x37, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x37, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x2E, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x2E, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x0F, 0xCF, 0x74, 0xC6, + 0x3D, 0xCF, 0x74, 0xC2, + 0x0F, 0xCF, 0x74, 0xC6, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x0F, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB4, -0x02, 0x44, 0x64, 0xB4, + 0x0A, 0x44, 0x54, 0xB4, + 0x02, 0x44, 0x64, 0xB4, -0x2A, 0x44, 0x54, 0xB6, -0x1A, 0x44, 0x64, 0xB6, + 0x2A, 0x44, 0x54, 0xB6, + 0x1A, 0x44, 0x64, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x3D, 0xCF, 0x75, 0xC6, -0x00, 0x80, 0x00, 0xE8, + 0x3D, 0xCF, 0x75, 0xC6, + 0x00, 0x80, 0x00, 0xE8, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x0A, 0x45, 0x55, 0xB6, -0x02, 0x45, 0x65, 0xB6, + 0x0A, 0x45, 0x55, 0xB6, + 0x02, 0x45, 0x65, 0xB6, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0x31, 0x3D, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x38, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x96, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x96, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xB5, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xB5, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x74, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x74, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzf[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x7D, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x7D, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x6E, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x6E, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x39, 0xE5, 0x2C, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x53, 0x2F, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x88, 0x73, 0x5E, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x88, 0x73, 0x5E, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0F, 0xCF, 0x75, 0xC6, -0x3C, 0x3D, 0x20, 0xE9, + 0x0F, 0xCF, 0x75, 0xC6, + 0x3C, 0x3D, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x28, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x28, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x74, 0xC2, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x31, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x31, 0x0F, 0x20, 0xE9, -0x0A, 0x44, 0x54, 0xB4, -0x02, 0x44, 0x64, 0xB4, + 0x0A, 0x44, 0x54, 0xB4, + 0x02, 0x44, 0x64, 0xB4, -0x2A, 0x45, 0x55, 0xB6, -0x1A, 0x45, 0x65, 0xB6, + 0x2A, 0x45, 0x55, 0xB6, + 0x1A, 0x45, 0x65, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x39, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x9A, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x9A, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xBB, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xBB, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x78, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x78, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzs[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x85, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x85, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x76, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x76, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x0F, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x0F, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x31, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x31, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x0F, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB4, -0x1A, 0x44, 0x64, 0xB4, + 0x2A, 0x44, 0x54, 0xB4, + 0x1A, 0x44, 0x64, 0xB4, -0x0A, 0x45, 0x55, 0xB0, -0x02, 0x45, 0x65, 0xB0, + 0x0A, 0x45, 0x55, 0xB0, + 0x02, 0x45, 0x65, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x2A, 0x45, 0x55, 0xB2, -0x1A, 0x45, 0x65, 0xB2, + 0x2A, 0x45, 0x55, 0xB2, + 0x1A, 0x45, 0x65, 0xB2, -0x0A, 0x45, 0x55, 0xB4, -0x02, 0x45, 0x65, 0xB4, + 0x0A, 0x45, 0x55, 0xB4, + 0x02, 0x45, 0x65, 0xB4, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x20, -0x1A, 0x20, -0x0A, 0x20, -0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0xA7, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA7, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x92, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x92, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xB2, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xB2, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x70, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x70, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzsa[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x8A, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x8A, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x7B, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x7B, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x0F, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x0F, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x36, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x36, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x0F, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB4, -0x1A, 0x44, 0x64, 0xB4, + 0x2A, 0x44, 0x54, 0xB4, + 0x1A, 0x44, 0x64, 0xB4, -0x0A, 0x45, 0x55, 0xB0, -0x02, 0x45, 0x65, 0xB0, + 0x0A, 0x45, 0x55, 0xB0, + 0x02, 0x45, 0x65, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x55, 0xB2, -0x1A, 0x45, 0x65, 0xB2, + 0x2A, 0x45, 0x55, 0xB2, + 0x1A, 0x45, 0x65, 0xB2, -0x0A, 0x45, 0x55, 0xB4, -0x02, 0x45, 0x65, 0xB4, + 0x0A, 0x45, 0x55, 0xB4, + 0x02, 0x45, 0x65, 0xB4, -0x0F, 0xCF, 0x74, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x74, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x44, 0x54, 0xB6, -0x1A, 0x44, 0x64, 0xB6, + 0x2A, 0x44, 0x54, 0xB6, + 0x1A, 0x44, 0x64, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x2A, 0x20, -0x1A, 0x20, + 0x00, 0x80, 0x00, 0xE8, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x8D, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x8D, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xAD, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xAD, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x6B, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x6B, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzsaf[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x8E, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x8E, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x7F, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x7F, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x0F, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x0F, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x3A, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x3A, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x0F, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB4, -0x1A, 0x44, 0x64, 0xB4, + 0x2A, 0x44, 0x54, 0xB4, + 0x1A, 0x44, 0x64, 0xB4, -0x0A, 0x45, 0x55, 0xB0, -0x02, 0x45, 0x65, 0xB0, + 0x0A, 0x45, 0x55, 0xB0, + 0x02, 0x45, 0x65, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x55, 0xB2, -0x1A, 0x45, 0x65, 0xB2, + 0x2A, 0x45, 0x55, 0xB2, + 0x1A, 0x45, 0x65, 0xB2, -0x0A, 0x45, 0x55, 0xB4, -0x02, 0x45, 0x65, 0xB4, + 0x0A, 0x45, 0x55, 0xB4, + 0x02, 0x45, 0x65, 0xB4, -0x0F, 0xCF, 0x74, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x74, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x44, 0x54, 0xB6, -0x1A, 0x44, 0x64, 0xB6, + 0x2A, 0x44, 0x54, 0xB6, + 0x1A, 0x44, 0x64, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x0A, 0x45, 0x55, 0xB6, -0x02, 0x45, 0x65, 0xB6, + 0x0A, 0x45, 0x55, 0xB6, + 0x02, 0x45, 0x65, 0xB6, -0x3D, 0xCF, 0x75, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x75, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x31, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0x31, 0x3D, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x38, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x89, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x89, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xA9, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xA9, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x67, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x67, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_t2gzsf[] = { -0x00, 0x8A, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x8A, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x0A, 0x40, 0x50, 0xBF, -0x2A, 0x40, 0x60, 0xBF, + 0x0A, 0x40, 0x50, 0xBF, + 0x2A, 0x40, 0x60, 0xBF, -0x32, 0x41, 0x51, 0xBF, -0x3A, 0x41, 0x61, 0xBF, + 0x32, 0x41, 0x51, 0xBF, + 0x3A, 0x41, 0x61, 0xBF, -0xC3, 0x6B, -0xD3, 0x6B, -0x00, 0x8A, 0x98, 0xE9, + 0xC3, 0x6B, + 0xD3, 0x6B, + 0x00, 0x8A, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x53, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x53, 0xA0, 0xE8, -0xAD, 0xEE, 0x23, 0x9F, -0x00, 0xE0, -0x51, 0x04, + 0xAD, 0xEE, 0x23, 0x9F, + 0x00, 0xE0, + 0x51, 0x04, -0x90, 0xE2, -0x61, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x61, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x51, 0x41, 0xE0, 0xEC, -0x39, 0x67, 0xB1, 0xE8, + 0x51, 0x41, 0xE0, 0xEC, + 0x39, 0x67, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x63, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x63, 0xA0, 0xE8, -0x61, 0x41, 0xE0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x61, 0x41, 0xE0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x8A, 0x80, 0x15, 0xEA, -0x10, 0x04, -0x20, 0x04, + 0x8A, 0x80, 0x15, 0xEA, + 0x10, 0x04, + 0x20, 0x04, -0x61, 0x51, 0xE0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x61, 0x51, 0xE0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x52, 0xBF, -0x0F, 0x52, 0xA0, 0xE8, + 0x2A, 0x42, 0x52, 0xBF, + 0x0F, 0x52, 0xA0, 0xE8, -0x1A, 0x42, 0x62, 0xBF, -0x1E, 0x51, 0x60, 0xEA, + 0x1A, 0x42, 0x62, 0xBF, + 0x1E, 0x51, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x0E, 0x61, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x0E, 0x61, 0x60, 0xEA, -0x32, 0x40, 0x50, 0xBD, -0x22, 0x40, 0x60, 0xBD, + 0x32, 0x40, 0x50, 0xBD, + 0x22, 0x40, 0x60, 0xBD, -0x12, 0x41, 0x51, 0xBD, -0x3A, 0x41, 0x61, 0xBD, + 0x12, 0x41, 0x51, 0xBD, + 0x3A, 0x41, 0x61, 0xBD, -0xBF, 0x2F, 0x0E, 0xBD, -0x97, 0xE2, -0x7B, 0x72, + 0xBF, 0x2F, 0x0E, 0xBD, + 0x97, 0xE2, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x35, 0x48, 0xB1, 0xE8, -0x3D, 0x59, 0xB1, 0xE8, + 0x35, 0x48, 0xB1, 0xE8, + 0x3D, 0x59, 0xB1, 0xE8, -0x46, 0x31, 0x46, 0xBF, -0x56, 0x31, 0x56, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x56, 0x31, 0x56, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x66, 0x31, 0x66, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x66, 0x31, 0x66, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x57, 0x39, 0x57, 0xBF, -0x67, 0x39, 0x67, 0xBF, + 0x57, 0x39, 0x57, 0xBF, + 0x67, 0x39, 0x67, 0xBF, -0x7B, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x7B, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x35, 0x00, -0x3D, 0x00, -0x00, 0xE0, -0x2D, 0x73, + 0x35, 0x00, + 0x3D, 0x00, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0x8D, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0x8D, 0x2F, 0x1E, 0xBD, -0x43, 0x75, 0xF8, 0xEC, -0x35, 0x20, -0x3D, 0x20, + 0x43, 0x75, 0xF8, 0xEC, + 0x35, 0x20, + 0x3D, 0x20, -0x43, 0x43, 0x2D, 0xDF, -0x53, 0x53, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x53, 0x53, 0x2D, 0xDF, -0xAE, 0x1E, 0x0E, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x0E, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x48, 0x35, 0x48, 0xBF, -0x58, 0x35, 0x58, 0xBF, + 0x48, 0x35, 0x48, 0xBF, + 0x58, 0x35, 0x58, 0xBF, -0x68, 0x35, 0x68, 0xBF, -0x49, 0x3D, 0x49, 0xBF, + 0x68, 0x35, 0x68, 0xBF, + 0x49, 0x3D, 0x49, 0xBF, -0x59, 0x3D, 0x59, 0xBF, -0x69, 0x3D, 0x69, 0xBF, + 0x59, 0x3D, 0x59, 0xBF, + 0x69, 0x3D, 0x69, 0xBF, -0x63, 0x63, 0x2D, 0xDF, -0x4D, 0x7D, 0xF8, 0xEC, + 0x63, 0x63, 0x2D, 0xDF, + 0x4D, 0x7D, 0xF8, 0xEC, -0x59, 0xE3, -0x00, 0xE0, -0xB8, 0x38, 0x33, 0xBF, + 0x59, 0xE3, + 0x00, 0xE0, + 0xB8, 0x38, 0x33, 0xBF, -0x2D, 0x73, -0x30, 0x76, -0x18, 0x3A, 0x41, 0xE9, + 0x2D, 0x73, + 0x30, 0x76, + 0x18, 0x3A, 0x41, 0xE9, -0x3F, 0x53, 0xA0, 0xE8, -0x05, 0x80, 0x3D, 0xEA, + 0x3F, 0x53, 0xA0, 0xE8, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x63, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x63, 0xA0, 0xE8, -0x50, 0x70, 0xF8, 0xEC, -0x2B, 0x50, 0x3C, 0xE9, + 0x50, 0x70, 0xF8, 0xEC, + 0x2B, 0x50, 0x3C, 0xE9, -0x1F, 0x0F, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x0F, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x59, 0x78, 0xF8, 0xEC, -0x00, 0x80, 0x00, 0xE8, + 0x59, 0x78, 0xF8, 0xEC, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x46, 0x37, 0x46, 0xDF, -0x56, 0x3F, 0x56, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x56, 0x3F, 0x56, 0xDF, -0x2B, 0x40, 0x3D, 0xE9, -0x66, 0x3D, 0x66, 0xDF, + 0x2B, 0x40, 0x3D, 0xE9, + 0x66, 0x3D, 0x66, 0xDF, -0x1D, 0x32, 0x41, 0xE9, -0x67, 0x3D, 0x67, 0xDF, + 0x1D, 0x32, 0x41, 0xE9, + 0x67, 0x3D, 0x67, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3F, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3F, 0x57, 0xDF, -0x2A, 0x40, 0x20, 0xE9, -0x59, 0x3F, 0x59, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x59, 0x3F, 0x59, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x69, 0x3D, 0x69, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x69, 0x3D, 0x69, 0xDF, -0x48, 0x37, 0x48, 0xDF, -0x58, 0x3F, 0x58, 0xDF, + 0x48, 0x37, 0x48, 0xDF, + 0x58, 0x3F, 0x58, 0xDF, -0x68, 0x3D, 0x68, 0xDF, -0x49, 0x37, 0x49, 0xDF, + 0x68, 0x3D, 0x68, 0xDF, + 0x49, 0x37, 0x49, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x0F, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x0F, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x54, 0xB0, -0x02, 0x44, 0x64, 0xB0, + 0x0A, 0x44, 0x54, 0xB0, + 0x02, 0x44, 0x64, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB2, -0x1A, 0x44, 0x64, 0xB2, + 0x2A, 0x44, 0x54, 0xB2, + 0x1A, 0x44, 0x64, 0xB2, -0x36, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x36, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x0F, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x54, 0xB4, -0x1A, 0x44, 0x64, 0xB4, + 0x2A, 0x44, 0x54, 0xB4, + 0x1A, 0x44, 0x64, 0xB4, -0x0A, 0x45, 0x55, 0xB0, -0x02, 0x45, 0x65, 0xB0, + 0x0A, 0x45, 0x55, 0xB0, + 0x02, 0x45, 0x65, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x55, 0xB2, -0x1A, 0x45, 0x65, 0xB2, + 0x2A, 0x45, 0x55, 0xB2, + 0x1A, 0x45, 0x65, 0xB2, -0x0A, 0x45, 0x55, 0xB4, -0x02, 0x45, 0x65, 0xB4, + 0x0A, 0x45, 0x55, 0xB4, + 0x02, 0x45, 0x65, 0xB4, -0x0F, 0xCF, 0x75, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x0F, 0xCF, 0x75, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x31, 0x0F, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x31, 0x0F, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x45, 0x55, 0xB6, -0x1A, 0x45, 0x65, 0xB6, + 0x2A, 0x45, 0x55, 0xB6, + 0x1A, 0x45, 0x65, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x2A, 0x20, -0x1A, 0x20, + 0x00, 0x80, 0x00, 0xE8, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x56, 0xBF, -0x1A, 0x46, 0x66, 0xBF, + 0x2A, 0x46, 0x56, 0xBF, + 0x1A, 0x46, 0x66, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x0A, 0x47, 0x57, 0xBF, -0x02, 0x47, 0x67, 0xBF, + 0x0A, 0x47, 0x57, 0xBF, + 0x02, 0x47, 0x67, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x53, 0xBF, -0x1A, 0x43, 0x63, 0xBF, + 0x2A, 0x43, 0x53, 0xBF, + 0x1A, 0x43, 0x63, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x39, 0x4F, 0xE9, -0x0A, 0x48, 0x58, 0xBF, -0x02, 0x48, 0x68, 0xBF, + 0x0A, 0x48, 0x58, 0xBF, + 0x02, 0x48, 0x68, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x2A, 0x49, 0x59, 0xBF, -0x1A, 0x49, 0x69, 0xBF, + 0x2A, 0x49, 0x59, 0xBF, + 0x1A, 0x49, 0x69, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x82, 0x30, 0x57, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x82, 0x30, 0x57, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x83, 0x38, 0x57, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x83, 0x38, 0x57, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x84, 0x31, 0x5E, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x84, 0x31, 0x5E, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x85, 0x39, 0x5E, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x85, 0x39, 0x5E, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8A, 0x36, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8A, 0x36, 0x20, 0xE9, -0x87, 0x77, 0x57, 0xE9, -0x8B, 0x3E, 0xBF, 0xEA, + 0x87, 0x77, 0x57, 0xE9, + 0x8B, 0x3E, 0xBF, 0xEA, -0x80, 0x30, 0x57, 0xE9, -0x81, 0x38, 0x57, 0xE9, + 0x80, 0x30, 0x57, 0xE9, + 0x81, 0x38, 0x57, 0xE9, -0x82, 0x31, 0x57, 0xE9, -0x86, 0x78, 0x57, 0xE9, + 0x82, 0x31, 0x57, 0xE9, + 0x86, 0x78, 0x57, 0xE9, -0x83, 0x39, 0x57, 0xE9, -0x87, 0x79, 0x57, 0xE9, + 0x83, 0x39, 0x57, 0xE9, + 0x87, 0x79, 0x57, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, -0x8A, 0x34, 0x20, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, + 0x8A, 0x34, 0x20, 0xE9, -0x8B, 0x3C, 0x20, 0xE9, -0x37, 0x50, 0x60, 0xBD, + 0x8B, 0x3C, 0x20, 0xE9, + 0x37, 0x50, 0x60, 0xBD, -0x57, 0x0D, 0x20, 0xE9, -0x35, 0x51, 0x61, 0xBD, + 0x57, 0x0D, 0x20, 0xE9, + 0x35, 0x51, 0x61, 0xBD, -0x2B, 0x50, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x50, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x0E, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x0E, 0x77, -0x24, 0x51, 0x20, 0xE9, -0x8D, 0xFF, 0x20, 0xEA, + 0x24, 0x51, 0x20, 0xE9, + 0x8D, 0xFF, 0x20, 0xEA, -0x16, 0x0E, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x0E, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x0B, 0x46, 0xA0, 0xE8, -0x1B, 0x56, 0xA0, 0xE8, + 0x0B, 0x46, 0xA0, 0xE8, + 0x1B, 0x56, 0xA0, 0xE8, -0x2B, 0x66, 0xA0, 0xE8, -0x0C, 0x47, 0xA0, 0xE8, + 0x2B, 0x66, 0xA0, 0xE8, + 0x0C, 0x47, 0xA0, 0xE8, -0x1C, 0x57, 0xA0, 0xE8, -0x2C, 0x67, 0xA0, 0xE8, + 0x1C, 0x57, 0xA0, 0xE8, + 0x2C, 0x67, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x57, 0x80, 0x57, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x57, 0x80, 0x57, 0xCF, -0x66, 0x33, 0x66, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x66, 0x33, 0x66, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x67, 0x3B, 0x67, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x67, 0x3B, 0x67, 0xCF, -0x0B, 0x48, 0xA0, 0xE8, -0x1B, 0x58, 0xA0, 0xE8, + 0x0B, 0x48, 0xA0, 0xE8, + 0x1B, 0x58, 0xA0, 0xE8, -0x2B, 0x68, 0xA0, 0xE8, -0x0C, 0x49, 0xA0, 0xE8, + 0x2B, 0x68, 0xA0, 0xE8, + 0x0C, 0x49, 0xA0, 0xE8, -0x1C, 0x59, 0xA0, 0xE8, -0x2C, 0x69, 0xA0, 0xE8, + 0x1C, 0x59, 0xA0, 0xE8, + 0x2C, 0x69, 0xA0, 0xE8, -0x0B, 0x00, -0x1B, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x0B, 0x00, + 0x1B, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x0C, 0x00, -0x1C, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x0C, 0x00, + 0x1C, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x0B, 0x65, -0x1B, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x0B, 0x65, + 0x1B, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x0C, 0x65, -0x1C, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x0C, 0x65, + 0x1C, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x0B, 0x1B, 0x60, 0xEC, -0x34, 0xD7, 0x34, 0xAD, + 0x0B, 0x1B, 0x60, 0xEC, + 0x34, 0xD7, 0x34, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x0C, 0x1C, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x0C, 0x1C, 0x60, 0xEC, -0x3C, 0xD7, 0x3C, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3C, 0xD7, 0x3C, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x0B, 0x2B, 0xDE, 0xE8, -0x1B, 0x80, 0xDE, 0xE8, + 0x0B, 0x2B, 0xDE, 0xE8, + 0x1B, 0x80, 0xDE, 0xE8, -0x34, 0x80, 0x34, 0xBD, -0x3C, 0x80, 0x3C, 0xBD, + 0x34, 0x80, 0x34, 0xBD, + 0x3C, 0x80, 0x3C, 0xBD, -0x33, 0xD7, 0x0B, 0xBD, -0x3B, 0xD7, 0x1B, 0xBD, + 0x33, 0xD7, 0x0B, 0xBD, + 0x3B, 0xD7, 0x1B, 0xBD, -0x48, 0x80, 0x48, 0xCF, -0x59, 0x80, 0x59, 0xCF, + 0x48, 0x80, 0x48, 0xCF, + 0x59, 0x80, 0x59, 0xCF, -0x68, 0x33, 0x68, 0xCF, -0x49, 0x3B, 0x49, 0xCF, + 0x68, 0x33, 0x68, 0xCF, + 0x49, 0x3B, 0x49, 0xCF, -0xAD, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xAD, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x58, 0x33, 0x58, 0xCF, -0x69, 0x3B, 0x69, 0xCF, + 0x58, 0x33, 0x58, 0xCF, + 0x69, 0x3B, 0x69, 0xCF, -0x6B, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x6B, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgz[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x58, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x58, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x4A, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x4A, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x1D, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x1D, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x74, 0xC2, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x53, 0x2F, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x2A, 0x44, 0x4C, 0xB4, -0x1A, 0x44, 0x54, 0xB4, + 0x2A, 0x44, 0x4C, 0xB4, + 0x1A, 0x44, 0x54, 0xB4, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0xAF, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0xAF, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xD6, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xD6, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x9D, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x9D, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgza[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x5C, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x5C, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x4E, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x4E, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x27, 0xCF, 0x74, 0xC6, -0x3D, 0xCF, 0x74, 0xC2, + 0x27, 0xCF, 0x74, 0xC6, + 0x3D, 0xCF, 0x74, 0xC2, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x20, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x20, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x27, 0x20, 0xE9, -0x0A, 0x44, 0x4C, 0xB4, -0x02, 0x44, 0x54, 0xB4, + 0x0A, 0x44, 0x4C, 0xB4, + 0x02, 0x44, 0x54, 0xB4, -0x2A, 0x44, 0x4C, 0xB6, -0x1A, 0x44, 0x54, 0xB6, + 0x2A, 0x44, 0x4C, 0xB6, + 0x1A, 0x44, 0x54, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0xAB, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0xAB, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xD3, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xD3, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x99, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x99, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzaf[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x61, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x61, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x53, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x53, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x31, 0x53, 0x2F, 0x9F, -0x34, 0x37, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x34, 0x37, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x26, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x26, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x27, 0xCF, 0x74, 0xC6, + 0x3D, 0xCF, 0x74, 0xC2, + 0x27, 0xCF, 0x74, 0xC6, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x27, 0x20, 0xE9, -0x0A, 0x44, 0x4C, 0xB4, -0x02, 0x44, 0x54, 0xB4, + 0x0A, 0x44, 0x4C, 0xB4, + 0x02, 0x44, 0x54, 0xB4, -0x2A, 0x44, 0x4C, 0xB6, -0x1A, 0x44, 0x54, 0xB6, + 0x2A, 0x44, 0x4C, 0xB6, + 0x1A, 0x44, 0x54, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x3D, 0xCF, 0x75, 0xC6, -0x00, 0x80, 0x00, 0xE8, + 0x3D, 0xCF, 0x75, 0xC6, + 0x00, 0x80, 0x00, 0xE8, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x0A, 0x45, 0x4D, 0xB6, -0x02, 0x45, 0x55, 0xB6, + 0x0A, 0x45, 0x4D, 0xB6, + 0x02, 0x45, 0x55, 0xB6, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0x31, 0x3D, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0xA6, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0xA6, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xCD, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xCD, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x94, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x94, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzf[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x5D, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x5D, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x4F, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x4F, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x3D, 0xCF, 0x74, 0xC0, -0x37, 0xCF, 0x74, 0xC4, + 0x3D, 0xCF, 0x74, 0xC0, + 0x37, 0xCF, 0x74, 0xC4, -0x39, 0xE5, 0x2C, 0x9F, -0x34, 0x80, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x34, 0x80, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0x31, 0x53, 0x2F, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x88, 0x73, 0x5E, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x88, 0x73, 0x5E, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x27, 0xCF, 0x75, 0xC6, -0x3C, 0x3D, 0x20, 0xE9, + 0x27, 0xCF, 0x75, 0xC6, + 0x3C, 0x3D, 0x20, 0xE9, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x20, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x20, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x3D, 0xCF, 0x74, 0xC2, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x74, 0xC2, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x31, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x31, 0x27, 0x20, 0xE9, -0x0A, 0x44, 0x4C, 0xB4, -0x02, 0x44, 0x54, 0xB4, + 0x0A, 0x44, 0x4C, 0xB4, + 0x02, 0x44, 0x54, 0xB4, -0x2A, 0x45, 0x4D, 0xB6, -0x1A, 0x45, 0x55, 0xB6, + 0x2A, 0x45, 0x4D, 0xB6, + 0x1A, 0x45, 0x55, 0xB6, -0x39, 0xE5, 0x2C, 0x9F, -0x38, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x38, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0xAA, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0xAA, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xD3, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xD3, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x98, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x98, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzs[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x65, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x65, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x57, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x57, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x27, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x27, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x29, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x29, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x27, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB4, -0x1A, 0x44, 0x54, 0xB4, + 0x2A, 0x44, 0x4C, 0xB4, + 0x1A, 0x44, 0x54, 0xB4, -0x0A, 0x45, 0x4D, 0xB0, -0x02, 0x45, 0x55, 0xB0, + 0x0A, 0x45, 0x4D, 0xB0, + 0x02, 0x45, 0x55, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x2A, 0x45, 0x4D, 0xB2, -0x1A, 0x45, 0x55, 0xB2, + 0x2A, 0x45, 0x4D, 0xB2, + 0x1A, 0x45, 0x55, 0xB2, -0x0A, 0x45, 0x4D, 0xB4, -0x02, 0x45, 0x55, 0xB4, + 0x0A, 0x45, 0x4D, 0xB4, + 0x02, 0x45, 0x55, 0xB4, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, -0x2A, 0x20, -0x1A, 0x20, + 0x0A, 0x20, + 0x02, 0x20, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0xA7, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA7, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0xA2, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0xA2, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xCA, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xCA, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x90, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x90, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzsa[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x6A, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x6A, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x5C, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x5C, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x27, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x27, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x2E, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x2E, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x27, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB4, -0x1A, 0x44, 0x54, 0xB4, + 0x2A, 0x44, 0x4C, 0xB4, + 0x1A, 0x44, 0x54, 0xB4, -0x0A, 0x45, 0x4D, 0xB0, -0x02, 0x45, 0x55, 0xB0, + 0x0A, 0x45, 0x4D, 0xB0, + 0x02, 0x45, 0x55, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x4D, 0xB2, -0x1A, 0x45, 0x55, 0xB2, + 0x2A, 0x45, 0x4D, 0xB2, + 0x1A, 0x45, 0x55, 0xB2, -0x0A, 0x45, 0x4D, 0xB4, -0x02, 0x45, 0x55, 0xB4, + 0x0A, 0x45, 0x4D, 0xB4, + 0x02, 0x45, 0x55, 0xB4, -0x27, 0xCF, 0x74, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x74, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x44, 0x4C, 0xB6, -0x1A, 0x44, 0x54, 0xB6, + 0x2A, 0x44, 0x4C, 0xB6, + 0x1A, 0x44, 0x54, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x2A, 0x20, -0x1A, 0x20, + 0x00, 0x80, 0x00, 0xE8, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0x9D, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0x9D, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xC5, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xC5, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x8B, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x8B, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzsaf[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x6E, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x6E, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x60, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x60, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x27, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x27, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x32, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x32, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x27, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB4, -0x1A, 0x44, 0x54, 0xB4, + 0x2A, 0x44, 0x4C, 0xB4, + 0x1A, 0x44, 0x54, 0xB4, -0x0A, 0x45, 0x4D, 0xB0, -0x02, 0x45, 0x55, 0xB0, + 0x0A, 0x45, 0x4D, 0xB0, + 0x02, 0x45, 0x55, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x4D, 0xB2, -0x1A, 0x45, 0x55, 0xB2, + 0x2A, 0x45, 0x4D, 0xB2, + 0x1A, 0x45, 0x55, 0xB2, -0x0A, 0x45, 0x4D, 0xB4, -0x02, 0x45, 0x55, 0xB4, + 0x0A, 0x45, 0x4D, 0xB4, + 0x02, 0x45, 0x55, 0xB4, -0x27, 0xCF, 0x74, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x74, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x9C, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9C, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x44, 0x4C, 0xB6, -0x1A, 0x44, 0x54, 0xB6, + 0x2A, 0x44, 0x4C, 0xB6, + 0x1A, 0x44, 0x54, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x0A, 0x45, 0x4D, 0xB6, -0x02, 0x45, 0x55, 0xB6, + 0x0A, 0x45, 0x4D, 0xB6, + 0x02, 0x45, 0x55, 0xB6, -0x3D, 0xCF, 0x75, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x3D, 0xCF, 0x75, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x31, 0x3D, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0x31, 0x3D, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x9D, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x9D, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x9E, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x9E, 0x39, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x30, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x30, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x38, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x38, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0x99, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0x99, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xC1, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xC1, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x87, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x87, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; static unsigned char warp_g400_tgzsf[] = { -0x00, 0x88, 0x98, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x88, 0x98, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, -0xFF, 0x80, 0xC0, 0xE9, -0x00, 0x80, 0x00, 0xE8, + 0xFF, 0x80, 0xC0, 0xE9, + 0x00, 0x80, 0x00, 0xE8, -0x22, 0x40, 0x48, 0xBF, -0x2A, 0x40, 0x50, 0xBF, + 0x22, 0x40, 0x48, 0xBF, + 0x2A, 0x40, 0x50, 0xBF, -0x32, 0x41, 0x49, 0xBF, -0x3A, 0x41, 0x51, 0xBF, + 0x32, 0x41, 0x49, 0xBF, + 0x3A, 0x41, 0x51, 0xBF, -0xC3, 0x6B, -0xCB, 0x6B, -0x00, 0x88, 0x98, 0xE9, + 0xC3, 0x6B, + 0xCB, 0x6B, + 0x00, 0x88, 0x98, 0xE9, -0x73, 0x7B, 0xC8, 0xEC, -0x96, 0xE2, -0x41, 0x04, + 0x73, 0x7B, 0xC8, 0xEC, + 0x96, 0xE2, + 0x41, 0x04, -0x7B, 0x43, 0xA0, 0xE8, -0x73, 0x4B, 0xA0, 0xE8, + 0x7B, 0x43, 0xA0, 0xE8, + 0x73, 0x4B, 0xA0, 0xE8, -0xAD, 0xEE, 0x29, 0x9F, -0x00, 0xE0, -0x49, 0x04, + 0xAD, 0xEE, 0x29, 0x9F, + 0x00, 0xE0, + 0x49, 0x04, -0x90, 0xE2, -0x51, 0x04, -0x31, 0x46, 0xB1, 0xE8, + 0x90, 0xE2, + 0x51, 0x04, + 0x31, 0x46, 0xB1, 0xE8, -0x49, 0x41, 0xC0, 0xEC, -0x39, 0x57, 0xB1, 0xE8, + 0x49, 0x41, 0xC0, 0xEC, + 0x39, 0x57, 0xB1, 0xE8, -0x00, 0x04, -0x46, 0xE2, -0x73, 0x53, 0xA0, 0xE8, + 0x00, 0x04, + 0x46, 0xE2, + 0x73, 0x53, 0xA0, 0xE8, -0x51, 0x41, 0xC0, 0xEC, -0x31, 0x00, -0x39, 0x00, + 0x51, 0x41, 0xC0, 0xEC, + 0x31, 0x00, + 0x39, 0x00, -0x6A, 0x80, 0x15, 0xEA, -0x08, 0x04, -0x10, 0x04, + 0x6A, 0x80, 0x15, 0xEA, + 0x08, 0x04, + 0x10, 0x04, -0x51, 0x49, 0xC0, 0xEC, -0x2F, 0x41, 0x60, 0xEA, + 0x51, 0x49, 0xC0, 0xEC, + 0x2F, 0x41, 0x60, 0xEA, -0x31, 0x20, -0x39, 0x20, -0x1F, 0x42, 0xA0, 0xE8, + 0x31, 0x20, + 0x39, 0x20, + 0x1F, 0x42, 0xA0, 0xE8, -0x2A, 0x42, 0x4A, 0xBF, -0x27, 0x4A, 0xA0, 0xE8, + 0x2A, 0x42, 0x4A, 0xBF, + 0x27, 0x4A, 0xA0, 0xE8, -0x1A, 0x42, 0x52, 0xBF, -0x1E, 0x49, 0x60, 0xEA, + 0x1A, 0x42, 0x52, 0xBF, + 0x1E, 0x49, 0x60, 0xEA, -0x73, 0x7B, 0xC8, 0xEC, -0x26, 0x51, 0x60, 0xEA, + 0x73, 0x7B, 0xC8, 0xEC, + 0x26, 0x51, 0x60, 0xEA, -0x32, 0x40, 0x48, 0xBD, -0x22, 0x40, 0x50, 0xBD, + 0x32, 0x40, 0x48, 0xBD, + 0x22, 0x40, 0x50, 0xBD, -0x12, 0x41, 0x49, 0xBD, -0x3A, 0x41, 0x51, 0xBD, + 0x12, 0x41, 0x49, 0xBD, + 0x3A, 0x41, 0x51, 0xBD, -0xBF, 0x2F, 0x26, 0xBD, -0x00, 0xE0, -0x7B, 0x72, + 0xBF, 0x2F, 0x26, 0xBD, + 0x00, 0xE0, + 0x7B, 0x72, -0x32, 0x20, -0x22, 0x20, -0x12, 0x20, -0x3A, 0x20, + 0x32, 0x20, + 0x22, 0x20, + 0x12, 0x20, + 0x3A, 0x20, -0x46, 0x31, 0x46, 0xBF, -0x4E, 0x31, 0x4E, 0xBF, + 0x46, 0x31, 0x46, 0xBF, + 0x4E, 0x31, 0x4E, 0xBF, -0xB3, 0xE2, 0x2D, 0x9F, -0x00, 0x80, 0x00, 0xE8, + 0xB3, 0xE2, 0x2D, 0x9F, + 0x00, 0x80, 0x00, 0xE8, -0x56, 0x31, 0x56, 0xBF, -0x47, 0x39, 0x47, 0xBF, + 0x56, 0x31, 0x56, 0xBF, + 0x47, 0x39, 0x47, 0xBF, -0x4F, 0x39, 0x4F, 0xBF, -0x57, 0x39, 0x57, 0xBF, + 0x4F, 0x39, 0x4F, 0xBF, + 0x57, 0x39, 0x57, 0xBF, -0x5C, 0x80, 0x07, 0xEA, -0x24, 0x41, 0x20, 0xE9, + 0x5C, 0x80, 0x07, 0xEA, + 0x24, 0x41, 0x20, 0xE9, -0x42, 0x73, 0xF8, 0xEC, -0x00, 0xE0, -0x2D, 0x73, + 0x42, 0x73, 0xF8, 0xEC, + 0x00, 0xE0, + 0x2D, 0x73, -0x33, 0x72, -0x0C, 0xE3, -0xA5, 0x2F, 0x1E, 0xBD, + 0x33, 0x72, + 0x0C, 0xE3, + 0xA5, 0x2F, 0x1E, 0xBD, -0x43, 0x43, 0x2D, 0xDF, -0x4B, 0x4B, 0x2D, 0xDF, + 0x43, 0x43, 0x2D, 0xDF, + 0x4B, 0x4B, 0x2D, 0xDF, -0xAE, 0x1E, 0x26, 0xBD, -0x58, 0xE3, -0x33, 0x66, + 0xAE, 0x1E, 0x26, 0xBD, + 0x58, 0xE3, + 0x33, 0x66, -0x53, 0x53, 0x2D, 0xDF, -0x00, 0x80, 0x00, 0xE8, + 0x53, 0x53, 0x2D, 0xDF, + 0x00, 0x80, 0x00, 0xE8, -0xB8, 0x38, 0x33, 0xBF, -0x00, 0xE0, -0x59, 0xE3, + 0xB8, 0x38, 0x33, 0xBF, + 0x00, 0xE0, + 0x59, 0xE3, -0x1E, 0x12, 0x41, 0xE9, -0x1A, 0x22, 0x41, 0xE9, + 0x1E, 0x12, 0x41, 0xE9, + 0x1A, 0x22, 0x41, 0xE9, -0x2B, 0x40, 0x3D, 0xE9, -0x3F, 0x4B, 0xA0, 0xE8, + 0x2B, 0x40, 0x3D, 0xE9, + 0x3F, 0x4B, 0xA0, 0xE8, -0x2D, 0x73, -0x30, 0x76, -0x05, 0x80, 0x3D, 0xEA, + 0x2D, 0x73, + 0x30, 0x76, + 0x05, 0x80, 0x3D, 0xEA, -0x37, 0x43, 0xA0, 0xE8, -0x3D, 0x53, 0xA0, 0xE8, + 0x37, 0x43, 0xA0, 0xE8, + 0x3D, 0x53, 0xA0, 0xE8, -0x48, 0x70, 0xF8, 0xEC, -0x2B, 0x48, 0x3C, 0xE9, + 0x48, 0x70, 0xF8, 0xEC, + 0x2B, 0x48, 0x3C, 0xE9, -0x1F, 0x27, 0xBC, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x1F, 0x27, 0xBC, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, -0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, + 0x00, 0x80, 0x00, 0xE8, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, -0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, + 0x15, 0xC0, 0x20, 0xE9, -0x18, 0x3A, 0x41, 0xE9, -0x1D, 0x32, 0x41, 0xE9, + 0x18, 0x3A, 0x41, 0xE9, + 0x1D, 0x32, 0x41, 0xE9, -0x2A, 0x40, 0x20, 0xE9, -0x56, 0x3D, 0x56, 0xDF, + 0x2A, 0x40, 0x20, 0xE9, + 0x56, 0x3D, 0x56, 0xDF, -0x46, 0x37, 0x46, 0xDF, -0x4E, 0x3F, 0x4E, 0xDF, + 0x46, 0x37, 0x46, 0xDF, + 0x4E, 0x3F, 0x4E, 0xDF, -0x16, 0x30, 0x20, 0xE9, -0x4F, 0x3F, 0x4F, 0xDF, + 0x16, 0x30, 0x20, 0xE9, + 0x4F, 0x3F, 0x4F, 0xDF, -0x47, 0x37, 0x47, 0xDF, -0x57, 0x3D, 0x57, 0xDF, + 0x47, 0x37, 0x47, 0xDF, + 0x57, 0x3D, 0x57, 0xDF, -0x32, 0x32, 0x2D, 0xDF, -0x22, 0x22, 0x2D, 0xDF, + 0x32, 0x32, 0x2D, 0xDF, + 0x22, 0x22, 0x2D, 0xDF, -0x12, 0x12, 0x2D, 0xDF, -0x3A, 0x3A, 0x2D, 0xDF, + 0x12, 0x12, 0x2D, 0xDF, + 0x3A, 0x3A, 0x2D, 0xDF, -0x27, 0xCF, 0x74, 0xC2, -0x37, 0xCF, 0x74, 0xC4, + 0x27, 0xCF, 0x74, 0xC2, + 0x37, 0xCF, 0x74, 0xC4, -0x0A, 0x44, 0x4C, 0xB0, -0x02, 0x44, 0x54, 0xB0, + 0x0A, 0x44, 0x4C, 0xB0, + 0x02, 0x44, 0x54, 0xB0, -0x3D, 0xCF, 0x74, 0xC0, -0x34, 0x37, 0x20, 0xE9, + 0x3D, 0xCF, 0x74, 0xC0, + 0x34, 0x37, 0x20, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x38, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x38, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3C, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3C, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB2, -0x1A, 0x44, 0x54, 0xB2, + 0x2A, 0x44, 0x4C, 0xB2, + 0x1A, 0x44, 0x54, 0xB2, -0x2E, 0x80, 0x3A, 0xEA, -0x0A, 0x20, -0x02, 0x20, + 0x2E, 0x80, 0x3A, 0xEA, + 0x0A, 0x20, + 0x02, 0x20, -0x27, 0xCF, 0x75, 0xC0, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x75, 0xC0, + 0x2A, 0x20, + 0x1A, 0x20, -0x30, 0x50, 0x2E, 0x9F, -0x32, 0x31, 0x5F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x32, 0x31, 0x5F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x33, 0x39, 0x5F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x33, 0x39, 0x5F, 0xE9, -0x3D, 0xCF, 0x75, 0xC2, -0x37, 0xCF, 0x75, 0xC4, + 0x3D, 0xCF, 0x75, 0xC2, + 0x37, 0xCF, 0x75, 0xC4, -0x31, 0x53, 0x2F, 0x9F, -0xA6, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA6, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA3, 0x3D, 0x20, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA3, 0x3D, 0x20, 0xE9, -0x2A, 0x44, 0x4C, 0xB4, -0x1A, 0x44, 0x54, 0xB4, + 0x2A, 0x44, 0x4C, 0xB4, + 0x1A, 0x44, 0x54, 0xB4, -0x0A, 0x45, 0x4D, 0xB0, -0x02, 0x45, 0x55, 0xB0, + 0x0A, 0x45, 0x4D, 0xB0, + 0x02, 0x45, 0x55, 0xB0, -0x88, 0x73, 0x5E, 0xE9, -0x2A, 0x20, -0x1A, 0x20, + 0x88, 0x73, 0x5E, 0xE9, + 0x2A, 0x20, + 0x1A, 0x20, -0xA0, 0x37, 0x20, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA0, 0x37, 0x20, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x3E, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x3E, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x3F, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x3F, 0x38, 0x4F, 0xE9, -0x30, 0x50, 0x2E, 0x9F, -0x3A, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x3A, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x3B, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x3B, 0x39, 0x4F, 0xE9, -0x2A, 0x45, 0x4D, 0xB2, -0x1A, 0x45, 0x55, 0xB2, + 0x2A, 0x45, 0x4D, 0xB2, + 0x1A, 0x45, 0x55, 0xB2, -0x0A, 0x45, 0x4D, 0xB4, -0x02, 0x45, 0x55, 0xB4, + 0x0A, 0x45, 0x4D, 0xB4, + 0x02, 0x45, 0x55, 0xB4, -0x27, 0xCF, 0x75, 0xC6, -0x2A, 0x20, -0x1A, 0x20, + 0x27, 0xCF, 0x75, 0xC6, + 0x2A, 0x20, + 0x1A, 0x20, -0xA7, 0x30, 0x4F, 0xE9, -0x0A, 0x20, -0x02, 0x20, + 0xA7, 0x30, 0x4F, 0xE9, + 0x0A, 0x20, + 0x02, 0x20, -0x31, 0x53, 0x2F, 0x9F, -0x31, 0x27, 0x20, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x31, 0x27, 0x20, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA8, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA8, 0x38, 0x4F, 0xE9, -0x2A, 0x45, 0x4D, 0xB6, -0x1A, 0x45, 0x55, 0xB6, + 0x2A, 0x45, 0x4D, 0xB6, + 0x1A, 0x45, 0x55, 0xB6, -0x30, 0x50, 0x2E, 0x9F, -0x36, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x36, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x37, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x37, 0x39, 0x4F, 0xE9, -0x00, 0x80, 0x00, 0xE8, -0x2A, 0x20, -0x1A, 0x20, + 0x00, 0x80, 0x00, 0xE8, + 0x2A, 0x20, + 0x1A, 0x20, -0x2A, 0x46, 0x4E, 0xBF, -0x1A, 0x46, 0x56, 0xBF, + 0x2A, 0x46, 0x4E, 0xBF, + 0x1A, 0x46, 0x56, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA4, 0x31, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA4, 0x31, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA5, 0x39, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA5, 0x39, 0x4F, 0xE9, -0x0A, 0x47, 0x4F, 0xBF, -0x02, 0x47, 0x57, 0xBF, + 0x0A, 0x47, 0x4F, 0xBF, + 0x02, 0x47, 0x57, 0xBF, -0x31, 0x53, 0x2F, 0x9F, -0xA1, 0x30, 0x4F, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0xA1, 0x30, 0x4F, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0xA2, 0x38, 0x4F, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0xA2, 0x38, 0x4F, 0xE9, -0x2A, 0x43, 0x4B, 0xBF, -0x1A, 0x43, 0x53, 0xBF, + 0x2A, 0x43, 0x4B, 0xBF, + 0x1A, 0x43, 0x53, 0xBF, -0x30, 0x50, 0x2E, 0x9F, -0x35, 0x31, 0x4F, 0xE9, + 0x30, 0x50, 0x2E, 0x9F, + 0x35, 0x31, 0x4F, 0xE9, -0x38, 0x21, 0x2C, 0x9F, -0x39, 0x39, 0x4F, 0xE9, + 0x38, 0x21, 0x2C, 0x9F, + 0x39, 0x39, 0x4F, 0xE9, -0x31, 0x53, 0x2F, 0x9F, -0x80, 0x31, 0x57, 0xE9, + 0x31, 0x53, 0x2F, 0x9F, + 0x80, 0x31, 0x57, 0xE9, -0x39, 0xE5, 0x2C, 0x9F, -0x81, 0x39, 0x57, 0xE9, + 0x39, 0xE5, 0x2C, 0x9F, + 0x81, 0x39, 0x57, 0xE9, -0x37, 0x48, 0x50, 0xBD, -0x8A, 0x36, 0x20, 0xE9, + 0x37, 0x48, 0x50, 0xBD, + 0x8A, 0x36, 0x20, 0xE9, -0x86, 0x76, 0x57, 0xE9, -0x8B, 0x3E, 0x20, 0xE9, + 0x86, 0x76, 0x57, 0xE9, + 0x8B, 0x3E, 0x20, 0xE9, -0x82, 0x30, 0x57, 0xE9, -0x87, 0x77, 0x57, 0xE9, + 0x82, 0x30, 0x57, 0xE9, + 0x87, 0x77, 0x57, 0xE9, -0x83, 0x38, 0x57, 0xE9, -0x35, 0x49, 0x51, 0xBD, + 0x83, 0x38, 0x57, 0xE9, + 0x35, 0x49, 0x51, 0xBD, -0x84, 0x31, 0x5E, 0xE9, -0x30, 0x1F, 0x5F, 0xE9, + 0x84, 0x31, 0x5E, 0xE9, + 0x30, 0x1F, 0x5F, 0xE9, -0x85, 0x39, 0x5E, 0xE9, -0x57, 0x25, 0x20, 0xE9, + 0x85, 0x39, 0x5E, 0xE9, + 0x57, 0x25, 0x20, 0xE9, -0x2B, 0x48, 0x20, 0xE9, -0x1D, 0x37, 0xE1, 0xEA, + 0x2B, 0x48, 0x20, 0xE9, + 0x1D, 0x37, 0xE1, 0xEA, -0x1E, 0x35, 0xE1, 0xEA, -0x00, 0xE0, -0x26, 0x77, + 0x1E, 0x35, 0xE1, 0xEA, + 0x00, 0xE0, + 0x26, 0x77, -0x24, 0x49, 0x20, 0xE9, -0x9D, 0xFF, 0x20, 0xEA, + 0x24, 0x49, 0x20, 0xE9, + 0x9D, 0xFF, 0x20, 0xEA, -0x16, 0x26, 0x20, 0xE9, -0x57, 0x2E, 0xBF, 0xEA, + 0x16, 0x26, 0x20, 0xE9, + 0x57, 0x2E, 0xBF, 0xEA, -0x1C, 0x46, 0xA0, 0xE8, -0x23, 0x4E, 0xA0, 0xE8, + 0x1C, 0x46, 0xA0, 0xE8, + 0x23, 0x4E, 0xA0, 0xE8, -0x2B, 0x56, 0xA0, 0xE8, -0x1D, 0x47, 0xA0, 0xE8, + 0x2B, 0x56, 0xA0, 0xE8, + 0x1D, 0x47, 0xA0, 0xE8, -0x24, 0x4F, 0xA0, 0xE8, -0x2C, 0x57, 0xA0, 0xE8, + 0x24, 0x4F, 0xA0, 0xE8, + 0x2C, 0x57, 0xA0, 0xE8, -0x1C, 0x00, -0x23, 0x00, -0x2B, 0x00, -0x00, 0xE0, + 0x1C, 0x00, + 0x23, 0x00, + 0x2B, 0x00, + 0x00, 0xE0, -0x1D, 0x00, -0x24, 0x00, -0x2C, 0x00, -0x00, 0xE0, + 0x1D, 0x00, + 0x24, 0x00, + 0x2C, 0x00, + 0x00, 0xE0, -0x1C, 0x65, -0x23, 0x65, -0x2B, 0x65, -0x00, 0xE0, + 0x1C, 0x65, + 0x23, 0x65, + 0x2B, 0x65, + 0x00, 0xE0, -0x1D, 0x65, -0x24, 0x65, -0x2C, 0x65, -0x00, 0xE0, + 0x1D, 0x65, + 0x24, 0x65, + 0x2C, 0x65, + 0x00, 0xE0, -0x1C, 0x23, 0x60, 0xEC, -0x36, 0xD7, 0x36, 0xAD, + 0x1C, 0x23, 0x60, 0xEC, + 0x36, 0xD7, 0x36, 0xAD, -0x2B, 0x80, 0x60, 0xEC, -0x1D, 0x24, 0x60, 0xEC, + 0x2B, 0x80, 0x60, 0xEC, + 0x1D, 0x24, 0x60, 0xEC, -0x3E, 0xD7, 0x3E, 0xAD, -0x2C, 0x80, 0x60, 0xEC, + 0x3E, 0xD7, 0x3E, 0xAD, + 0x2C, 0x80, 0x60, 0xEC, -0x1C, 0x2B, 0xDE, 0xE8, -0x23, 0x80, 0xDE, 0xE8, + 0x1C, 0x2B, 0xDE, 0xE8, + 0x23, 0x80, 0xDE, 0xE8, -0x36, 0x80, 0x36, 0xBD, -0x3E, 0x80, 0x3E, 0xBD, + 0x36, 0x80, 0x36, 0xBD, + 0x3E, 0x80, 0x3E, 0xBD, -0x33, 0xD7, 0x1C, 0xBD, -0x3B, 0xD7, 0x23, 0xBD, + 0x33, 0xD7, 0x1C, 0xBD, + 0x3B, 0xD7, 0x23, 0xBD, -0x46, 0x80, 0x46, 0xCF, -0x4F, 0x80, 0x4F, 0xCF, + 0x46, 0x80, 0x46, 0xCF, + 0x4F, 0x80, 0x4F, 0xCF, -0x56, 0x33, 0x56, 0xCF, -0x47, 0x3B, 0x47, 0xCF, + 0x56, 0x33, 0x56, 0xCF, + 0x47, 0x3B, 0x47, 0xCF, -0xC5, 0xFF, 0x20, 0xEA, -0x00, 0x80, 0x00, 0xE8, + 0xC5, 0xFF, 0x20, 0xEA, + 0x00, 0x80, 0x00, 0xE8, -0x4E, 0x33, 0x4E, 0xCF, -0x57, 0x3B, 0x57, 0xCF, + 0x4E, 0x33, 0x4E, 0xCF, + 0x57, 0x3B, 0x57, 0xCF, -0x8B, 0xFF, 0x20, 0xEA, -0x57, 0xC0, 0xBF, 0xEA, + 0x8B, 0xFF, 0x20, 0xEA, + 0x57, 0xC0, 0xBF, 0xEA, -0x00, 0x80, 0xA0, 0xE9, -0x00, 0x00, 0xD8, 0xEC, + 0x00, 0x80, 0xA0, 0xE9, + 0x00, 0x00, 0xD8, 0xEC, }; diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c index 55ccc8a0ac29..d67f4925fbac 100644 --- a/drivers/char/drm/mga_warp.c +++ b/drivers/char/drm/mga_warp.c @@ -33,8 +33,7 @@ #include "mga_drv.h" #include "mga_ucode.h" - -#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ +#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ #define WARP_UCODE_SIZE( which ) \ ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) @@ -49,33 +48,30 @@ do { \ } while (0) static const unsigned int mga_warp_g400_microcode_size = - (WARP_UCODE_SIZE(warp_g400_tgz) + - WARP_UCODE_SIZE(warp_g400_tgza) + - WARP_UCODE_SIZE(warp_g400_tgzaf) + - WARP_UCODE_SIZE(warp_g400_tgzf) + - WARP_UCODE_SIZE(warp_g400_tgzs) + - WARP_UCODE_SIZE(warp_g400_tgzsa) + - WARP_UCODE_SIZE(warp_g400_tgzsaf) + - WARP_UCODE_SIZE(warp_g400_tgzsf) + - WARP_UCODE_SIZE(warp_g400_t2gz) + - WARP_UCODE_SIZE(warp_g400_t2gza) + - WARP_UCODE_SIZE(warp_g400_t2gzaf) + - WARP_UCODE_SIZE(warp_g400_t2gzf) + - WARP_UCODE_SIZE(warp_g400_t2gzs) + - WARP_UCODE_SIZE(warp_g400_t2gzsa) + - WARP_UCODE_SIZE(warp_g400_t2gzsaf) + - WARP_UCODE_SIZE(warp_g400_t2gzsf)); + (WARP_UCODE_SIZE(warp_g400_tgz) + + WARP_UCODE_SIZE(warp_g400_tgza) + + WARP_UCODE_SIZE(warp_g400_tgzaf) + + WARP_UCODE_SIZE(warp_g400_tgzf) + + WARP_UCODE_SIZE(warp_g400_tgzs) + + WARP_UCODE_SIZE(warp_g400_tgzsa) + + WARP_UCODE_SIZE(warp_g400_tgzsaf) + + WARP_UCODE_SIZE(warp_g400_tgzsf) + + WARP_UCODE_SIZE(warp_g400_t2gz) + + WARP_UCODE_SIZE(warp_g400_t2gza) + + WARP_UCODE_SIZE(warp_g400_t2gzaf) + + WARP_UCODE_SIZE(warp_g400_t2gzf) + + WARP_UCODE_SIZE(warp_g400_t2gzs) + + WARP_UCODE_SIZE(warp_g400_t2gzsa) + + WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf)); static const unsigned int mga_warp_g200_microcode_size = - (WARP_UCODE_SIZE(warp_g200_tgz) + - WARP_UCODE_SIZE(warp_g200_tgza) + - WARP_UCODE_SIZE(warp_g200_tgzaf) + - WARP_UCODE_SIZE(warp_g200_tgzf) + - WARP_UCODE_SIZE(warp_g200_tgzs) + - WARP_UCODE_SIZE(warp_g200_tgzsa) + - WARP_UCODE_SIZE(warp_g200_tgzsaf) + - WARP_UCODE_SIZE(warp_g200_tgzsf)); - + (WARP_UCODE_SIZE(warp_g200_tgz) + + WARP_UCODE_SIZE(warp_g200_tgza) + + WARP_UCODE_SIZE(warp_g200_tgzaf) + + WARP_UCODE_SIZE(warp_g200_tgzf) + + WARP_UCODE_SIZE(warp_g200_tgzs) + + WARP_UCODE_SIZE(warp_g200_tgzsa) + + WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf)); unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) { @@ -90,36 +86,35 @@ unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) } } -static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) +static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv) { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; - memset( dev_priv->warp_pipe_phys, 0, - sizeof(dev_priv->warp_pipe_phys) ); + memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); - WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ ); - WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF ); - WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA ); - WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF ); - WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS ); - WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF ); - WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA ); - WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF ); + WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ); + WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF); + WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA); + WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF); + WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS); + WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF); + WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA); + WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF); - WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ ); - WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF ); - WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA ); - WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF ); - WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS ); - WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF ); - WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA ); - WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF ); + WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ); + WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF); + WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA); + WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF); + WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS); + WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF); + WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA); + WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF); return 0; } -static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) +static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv) { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; @@ -138,7 +133,7 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) return 0; } -int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) +int mga_warp_install_microcode(drm_mga_private_t * dev_priv) { const unsigned int size = mga_warp_microcode_size(dev_priv); @@ -154,7 +149,7 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) case MGA_CARD_TYPE_G550: return mga_warp_install_g400_microcode(dev_priv); case MGA_CARD_TYPE_G200: - return mga_warp_install_g200_microcode( dev_priv ); + return mga_warp_install_g200_microcode(dev_priv); default: return DRM_ERR(EINVAL); } @@ -162,13 +157,13 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) -int mga_warp_init( drm_mga_private_t *dev_priv ) +int mga_warp_init(drm_mga_private_t * dev_priv) { u32 wmisc; /* FIXME: Get rid of these damned magic numbers... */ - switch ( dev_priv->chipset ) { + switch (dev_priv->chipset) { case MGA_CARD_TYPE_G400: case MGA_CARD_TYPE_G550: MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND); @@ -177,21 +172,20 @@ int mga_warp_init( drm_mga_private_t *dev_priv ) MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000); break; case MGA_CARD_TYPE_G200: - MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND ); - MGA_WRITE( MGA_WGETMSB, 0x1606 ); - MGA_WRITE( MGA_WVRTXSZ, 7 ); + MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND); + MGA_WRITE(MGA_WGETMSB, 0x1606); + MGA_WRITE(MGA_WVRTXSZ, 7); break; default: return DRM_ERR(EINVAL); } - MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE | - MGA_WMASTER_ENABLE | - MGA_WCACHEFLUSH_ENABLE) ); - wmisc = MGA_READ( MGA_WMISC ); - if ( wmisc != WMISC_EXPECTED ) { - DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n", - wmisc, WMISC_EXPECTED ); + MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE | + MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE)); + wmisc = MGA_READ(MGA_WMISC); + if (wmisc != WMISC_EXPECTED) { + DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n", + wmisc, WMISC_EXPECTED); return DRM_ERR(EINVAL); } diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index ac3ea2bc9b28..7452753d4d01 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c @@ -80,7 +80,7 @@ static u32 r128_cce_microcode[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static int R128_READ_PLL(drm_device_t *dev, int addr) +static int R128_READ_PLL(drm_device_t * dev, int addr) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -89,106 +89,105 @@ static int R128_READ_PLL(drm_device_t *dev, int addr) } #if R128_FIFO_DEBUG -static void r128_status( drm_r128_private_t *dev_priv ) +static void r128_status(drm_r128_private_t * dev_priv) { - printk( "GUI_STAT = 0x%08x\n", - (unsigned int)R128_READ( R128_GUI_STAT ) ); - printk( "PM4_STAT = 0x%08x\n", - (unsigned int)R128_READ( R128_PM4_STAT ) ); - printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n", - (unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) ); - printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n", - (unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) ); - printk( "PM4_MICRO_CNTL = 0x%08x\n", - (unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) ); - printk( "PM4_BUFFER_CNTL = 0x%08x\n", - (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) ); + printk("GUI_STAT = 0x%08x\n", + (unsigned int)R128_READ(R128_GUI_STAT)); + printk("PM4_STAT = 0x%08x\n", + (unsigned int)R128_READ(R128_PM4_STAT)); + printk("PM4_BUFFER_DL_WPTR = 0x%08x\n", + (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR)); + printk("PM4_BUFFER_DL_RPTR = 0x%08x\n", + (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR)); + printk("PM4_MICRO_CNTL = 0x%08x\n", + (unsigned int)R128_READ(R128_PM4_MICRO_CNTL)); + printk("PM4_BUFFER_CNTL = 0x%08x\n", + (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL)); } #endif - /* ================================================================ * Engine, FIFO control */ -static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv ) +static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) { u32 tmp; int i; - tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL; - R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp ); + tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL; + R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) { + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) { return 0; } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if R128_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); + DRM_ERROR("failed!\n"); #endif return DRM_ERR(EBUSY); } -static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries ) +static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) { int i; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK; - if ( slots >= entries ) return 0; - DRM_UDELAY( 1 ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (slots >= entries) + return 0; + DRM_UDELAY(1); } #if R128_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); + DRM_ERROR("failed!\n"); #endif return DRM_ERR(EBUSY); } -static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) +static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) { int i, ret; - ret = r128_do_wait_for_fifo( dev_priv, 64 ); - if ( ret ) return ret; + ret = r128_do_wait_for_fifo(dev_priv, 64); + if (ret) + return ret; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { - r128_do_pixcache_flush( dev_priv ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + r128_do_pixcache_flush(dev_priv); return 0; } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if R128_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); + DRM_ERROR("failed!\n"); #endif return DRM_ERR(EBUSY); } - /* ================================================================ * CCE control, initialization */ /* Load the microcode for the CCE */ -static void r128_cce_load_microcode( drm_r128_private_t *dev_priv ) +static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) { int i; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - r128_do_wait_for_idle( dev_priv ); + r128_do_wait_for_idle(dev_priv); - R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 ); - for ( i = 0 ; i < 256 ; i++ ) { - R128_WRITE( R128_PM4_MICROCODE_DATAH, - r128_cce_microcode[i * 2] ); - R128_WRITE( R128_PM4_MICROCODE_DATAL, - r128_cce_microcode[i * 2 + 1] ); + R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); + for (i = 0; i < 256; i++) { + R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); + R128_WRITE(R128_PM4_MICROCODE_DATAL, + r128_cce_microcode[i * 2 + 1]); } } @@ -196,51 +195,51 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv ) * prior to a wait for idle, as it informs the engine that the command * stream is ending. */ -static void r128_do_cce_flush( drm_r128_private_t *dev_priv ) +static void r128_do_cce_flush(drm_r128_private_t * dev_priv) { u32 tmp; - tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE; - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp ); + tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE; + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp); } /* Wait for the CCE to go idle. */ -int r128_do_cce_idle( drm_r128_private_t *dev_priv ) +int r128_do_cce_idle(drm_r128_private_t * dev_priv) { int i; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) { - int pm4stat = R128_READ( R128_PM4_STAT ); - if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= - dev_priv->cce_fifo_size ) && - !(pm4stat & (R128_PM4_BUSY | - R128_PM4_GUI_ACTIVE)) ) { - return r128_do_pixcache_flush( dev_priv ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) { + int pm4stat = R128_READ(R128_PM4_STAT); + if (((pm4stat & R128_PM4_FIFOCNT_MASK) >= + dev_priv->cce_fifo_size) && + !(pm4stat & (R128_PM4_BUSY | + R128_PM4_GUI_ACTIVE))) { + return r128_do_pixcache_flush(dev_priv); } } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if R128_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); - r128_status( dev_priv ); + DRM_ERROR("failed!\n"); + r128_status(dev_priv); #endif return DRM_ERR(EBUSY); } /* Start the Concurrent Command Engine. */ -static void r128_do_cce_start( drm_r128_private_t *dev_priv ) +static void r128_do_cce_start(drm_r128_private_t * dev_priv) { - r128_do_wait_for_idle( dev_priv ); + r128_do_wait_for_idle(dev_priv); - R128_WRITE( R128_PM4_BUFFER_CNTL, - dev_priv->cce_mode | dev_priv->ring.size_l2qw - | R128_PM4_BUFFER_CNTL_NOUPDATE ); - R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */ - R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN ); + R128_WRITE(R128_PM4_BUFFER_CNTL, + dev_priv->cce_mode | dev_priv->ring.size_l2qw + | R128_PM4_BUFFER_CNTL_NOUPDATE); + R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */ + R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); dev_priv->cce_running = 1; } @@ -249,10 +248,10 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv ) * commands, so you must wait for the CCE command stream to complete * before calling this routine. */ -static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) +static void r128_do_cce_reset(drm_r128_private_t * dev_priv) { - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); - R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); + R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); dev_priv->ring.tail = 0; } @@ -260,122 +259,120 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) * commands, so you must flush the command stream and wait for the CCE * to go idle before calling this routine. */ -static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) +static void r128_do_cce_stop(drm_r128_private_t * dev_priv) { - R128_WRITE( R128_PM4_MICRO_CNTL, 0 ); - R128_WRITE( R128_PM4_BUFFER_CNTL, - R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE ); + R128_WRITE(R128_PM4_MICRO_CNTL, 0); + R128_WRITE(R128_PM4_BUFFER_CNTL, + R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE); dev_priv->cce_running = 0; } /* Reset the engine. This will stop the CCE if it is running. */ -static int r128_do_engine_reset( drm_device_t *dev ) +static int r128_do_engine_reset(drm_device_t * dev) { drm_r128_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; - r128_do_pixcache_flush( dev_priv ); + r128_do_pixcache_flush(dev_priv); - clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX ); - mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL ); + clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); + mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); - R128_WRITE_PLL( R128_MCLK_CNTL, - mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP ); + R128_WRITE_PLL(R128_MCLK_CNTL, + mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); - gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL ); + gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL); /* Taken from the sample code - do not change */ - R128_WRITE( R128_GEN_RESET_CNTL, - gen_reset_cntl | R128_SOFT_RESET_GUI ); - R128_READ( R128_GEN_RESET_CNTL ); - R128_WRITE( R128_GEN_RESET_CNTL, - gen_reset_cntl & ~R128_SOFT_RESET_GUI ); - R128_READ( R128_GEN_RESET_CNTL ); + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + R128_READ(R128_GEN_RESET_CNTL); + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + R128_READ(R128_GEN_RESET_CNTL); - R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl ); - R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index ); - R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl ); + R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl); + R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl); /* Reset the CCE ring */ - r128_do_cce_reset( dev_priv ); + r128_do_cce_reset(dev_priv); /* The CCE is no longer running after an engine reset */ dev_priv->cce_running = 0; /* Reset any pending vertex, indirect buffers */ - r128_freelist_reset( dev ); + r128_freelist_reset(dev); return 0; } -static void r128_cce_init_ring_buffer( drm_device_t *dev, - drm_r128_private_t *dev_priv ) +static void r128_cce_init_ring_buffer(drm_device_t * dev, + drm_r128_private_t * dev_priv) { u32 ring_start; u32 tmp; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* The manual (p. 2) says this address is in "VM space". This * means it's an offset from the start of AGP space. */ #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) + if (!dev_priv->is_pci) ring_start = dev_priv->cce_ring->offset - dev->agp->base; else #endif - ring_start = dev_priv->cce_ring->offset - - (unsigned long)dev->sg->virtual; + ring_start = dev_priv->cce_ring->offset - + (unsigned long)dev->sg->virtual; - R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET ); + R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET); - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); - R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); + R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); /* Set watermark control */ - R128_WRITE( R128_PM4_BUFFER_WM_CNTL, - ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) - | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT) - | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT) - | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) ); + R128_WRITE(R128_PM4_BUFFER_WM_CNTL, + ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT) + | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT) + | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT) + | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT)); /* Force read. Why? Because it's in the examples... */ - R128_READ( R128_PM4_BUFFER_ADDR ); + R128_READ(R128_PM4_BUFFER_ADDR); /* Turn on bus mastering */ - tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS; - R128_WRITE( R128_BUS_CNTL, tmp ); + tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS; + R128_WRITE(R128_BUS_CNTL, tmp); } -static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) +static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) { drm_r128_private_t *dev_priv; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); - if ( dev_priv == NULL ) + dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) return DRM_ERR(ENOMEM); - memset( dev_priv, 0, sizeof(drm_r128_private_t) ); + memset(dev_priv, 0, sizeof(drm_r128_private_t)); dev_priv->is_pci = init->is_pci; - if ( dev_priv->is_pci && !dev->sg ) { - DRM_ERROR( "PCI GART memory not allocated!\n" ); + if (dev_priv->is_pci && !dev->sg) { + DRM_ERROR("PCI GART memory not allocated!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } dev_priv->usec_timeout = init->usec_timeout; - if ( dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) { - DRM_DEBUG( "TIMEOUT problem!\n" ); + if (dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) { + DRM_DEBUG("TIMEOUT problem!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } @@ -383,23 +380,23 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) /* GH: Simple idle check. */ - atomic_set( &dev_priv->idle_count, 0 ); + atomic_set(&dev_priv->idle_count, 0); /* We don't support anything other than bus-mastering ring mode, * but the ring can be in either AGP or PCI space for the ring * read pointer. */ - if ( ( init->cce_mode != R128_PM4_192BM ) && - ( init->cce_mode != R128_PM4_128BM_64INDBM ) && - ( init->cce_mode != R128_PM4_64BM_128INDBM ) && - ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) { - DRM_DEBUG( "Bad cce_mode!\n" ); + if ((init->cce_mode != R128_PM4_192BM) && + (init->cce_mode != R128_PM4_128BM_64INDBM) && + (init->cce_mode != R128_PM4_64BM_128INDBM) && + (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) { + DRM_DEBUG("Bad cce_mode!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } - switch ( init->cce_mode ) { + switch (init->cce_mode) { case R128_PM4_NONPM4: dev_priv->cce_fifo_size = 0; break; @@ -420,7 +417,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) break; } - switch ( init->fb_bpp ) { + switch (init->fb_bpp) { case 16: dev_priv->color_fmt = R128_DATATYPE_RGB565; break; @@ -429,12 +426,12 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->color_fmt = R128_DATATYPE_ARGB8888; break; } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; - switch ( init->depth_bpp ) { + switch (init->depth_bpp) { case 16: dev_priv->depth_fmt = R128_DATATYPE_RGB565; break; @@ -444,131 +441,130 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; break; } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - dev_priv->span_offset = init->span_offset; + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + dev_priv->span_offset = init->span_offset; - dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) | + dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) | (dev_priv->front_offset >> 5)); - dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) | + dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) | (dev_priv->back_offset >> 5)); - dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | (dev_priv->depth_offset >> 5) | R128_DST_TILE); - dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | (dev_priv->span_offset >> 5)); DRM_GETSAREA(); - - if(!dev_priv->sarea) { + + if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if(!dev_priv->mmio) { + if (!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset); - if(!dev_priv->cce_ring) { + if (!dev_priv->cce_ring) { DRM_ERROR("could not find cce ring region!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if(!dev_priv->ring_rptr) { + if (!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if(!dev->agp_buffer_map) { + if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } - if ( !dev_priv->is_pci ) { - dev_priv->agp_textures = drm_core_findmap(dev, init->agp_textures_offset); - if(!dev_priv->agp_textures) { + if (!dev_priv->is_pci) { + dev_priv->agp_textures = + drm_core_findmap(dev, init->agp_textures_offset); + if (!dev_priv->agp_textures) { DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } } dev_priv->sarea_priv = - (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + - init->sarea_priv_offset); + (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle + + init->sarea_priv_offset); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { - drm_core_ioremap( dev_priv->cce_ring, dev ); - drm_core_ioremap( dev_priv->ring_rptr, dev ); - drm_core_ioremap( dev->agp_buffer_map, dev ); - if(!dev_priv->cce_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { + if (!dev_priv->is_pci) { + drm_core_ioremap(dev_priv->cce_ring, dev); + drm_core_ioremap(dev_priv->ring_rptr, dev); + drm_core_ioremap(dev->agp_buffer_map, dev); + if (!dev_priv->cce_ring->handle || + !dev_priv->ring_rptr->handle || + !dev->agp_buffer_map->handle) { DRM_ERROR("Could not ioremap agp regions!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(ENOMEM); } } else #endif { - dev_priv->cce_ring->handle = - (void *)dev_priv->cce_ring->offset; + dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset; dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset; + (void *)dev_priv->ring_rptr->offset; + dev->agp_buffer_map->handle = + (void *)dev->agp_buffer_map->offset; } #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) + if (!dev_priv->is_pci) dev_priv->cce_buffers_offset = dev->agp->base; else #endif dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual; - dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; - dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle + dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle; + dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle + init->ring_size / sizeof(u32)); dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 ); + dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - dev_priv->ring.tail_mask = - (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = 128; dev_priv->sarea_priv->last_frame = 0; - R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); + R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); dev_priv->sarea_priv->last_dispatch = 0; - R128_WRITE( R128_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch ); + R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch); #if __OS_HAS_AGP - if ( dev_priv->is_pci ) { + if (dev_priv->is_pci) { #endif dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; - dev_priv->gart_info.is_pcie = 0; + dev_priv->gart_info.is_pcie = 0; if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { - DRM_ERROR( "failed to init PCI GART!\n" ); + DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); return DRM_ERR(ENOMEM); } R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); @@ -576,88 +572,92 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) } #endif - r128_cce_init_ring_buffer( dev, dev_priv ); - r128_cce_load_microcode( dev_priv ); + r128_cce_init_ring_buffer(dev, dev_priv); + r128_cce_load_microcode(dev_priv); dev->dev_private = (void *)dev_priv; - r128_do_engine_reset( dev ); + r128_do_engine_reset(dev); return 0; } -int r128_do_cleanup_cce( drm_device_t *dev ) +int r128_do_cleanup_cce(drm_device_t * dev) { /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq_enabled ) drm_irq_uninstall(dev); + if (dev->irq_enabled) + drm_irq_uninstall(dev); - if ( dev->dev_private ) { + if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { - if ( dev_priv->cce_ring != NULL ) - drm_core_ioremapfree( dev_priv->cce_ring, dev ); - if ( dev_priv->ring_rptr != NULL ) - drm_core_ioremapfree( dev_priv->ring_rptr, dev ); - if ( dev->agp_buffer_map != NULL ) - drm_core_ioremapfree( dev->agp_buffer_map, dev ); + if (!dev_priv->is_pci) { + if (dev_priv->cce_ring != NULL) + drm_core_ioremapfree(dev_priv->cce_ring, dev); + if (dev_priv->ring_rptr != NULL) + drm_core_ioremapfree(dev_priv->ring_rptr, dev); + if (dev->agp_buffer_map != NULL) + drm_core_ioremapfree(dev->agp_buffer_map, dev); } else #endif { - if (dev_priv->gart_info.bus_addr) - if (!drm_ati_pcigart_cleanup( dev, - &dev_priv->gart_info)) - DRM_ERROR( "failed to cleanup PCI GART!\n" ); + if (dev_priv->gart_info.bus_addr) + if (!drm_ati_pcigart_cleanup(dev, + &dev_priv-> + gart_info)) + DRM_ERROR + ("failed to cleanup PCI GART!\n"); } - drm_free( dev->dev_private, sizeof(drm_r128_private_t), - DRM_MEM_DRIVER ); + drm_free(dev->dev_private, sizeof(drm_r128_private_t), + DRM_MEM_DRIVER); dev->dev_private = NULL; } return 0; } -int r128_cce_init( DRM_IOCTL_ARGS ) +int r128_cce_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_init_t init; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t __user *)data, sizeof(init) ); + DRM_COPY_FROM_USER_IOCTL(init, (drm_r128_init_t __user *) data, + sizeof(init)); - switch ( init.func ) { + switch (init.func) { case R128_INIT_CCE: - return r128_do_init_cce( dev, &init ); + return r128_do_init_cce(dev, &init); case R128_CLEANUP_CCE: - return r128_do_cleanup_cce( dev ); + return r128_do_cleanup_cce(dev); } return DRM_ERR(EINVAL); } -int r128_cce_start( DRM_IOCTL_ARGS ) +int r128_cce_start(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { - DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); + if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { + DRM_DEBUG("%s while CCE running\n", __FUNCTION__); return 0; } - r128_do_cce_start( dev_priv ); + r128_do_cce_start(dev_priv); return 0; } @@ -665,61 +665,63 @@ int r128_cce_start( DRM_IOCTL_ARGS ) /* Stop the CCE. The engine must have been idled before calling this * routine. */ -int r128_cce_stop( DRM_IOCTL_ARGS ) +int r128_cce_stop(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_cce_stop_t stop; int ret; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *)data, sizeof(stop) ); + DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *) data, + sizeof(stop)); /* Flush any pending CCE commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. */ - if ( stop.flush ) { - r128_do_cce_flush( dev_priv ); + if (stop.flush) { + r128_do_cce_flush(dev_priv); } /* If we fail to make the engine go idle, we return an error * code so that the DRM ioctl wrapper can try again. */ - if ( stop.idle ) { - ret = r128_do_cce_idle( dev_priv ); - if ( ret ) return ret; + if (stop.idle) { + ret = r128_do_cce_idle(dev_priv); + if (ret) + return ret; } /* Finally, we can turn off the CCE. If the engine isn't idle, * we will get some dropped triangles as they won't be fully * rendered before the CCE is shut down. */ - r128_do_cce_stop( dev_priv ); + r128_do_cce_stop(dev_priv); /* Reset the engine */ - r128_do_engine_reset( dev ); + r128_do_engine_reset(dev); return 0; } /* Just reset the CCE ring. Called as part of an X Server engine reset. */ -int r128_cce_reset( DRM_IOCTL_ARGS ) +int r128_cce_reset(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_DEBUG("%s called before init done\n", __FUNCTION__); return DRM_ERR(EINVAL); } - r128_do_cce_reset( dev_priv ); + r128_do_cce_reset(dev_priv); /* The CCE is no longer running after an engine reset */ dev_priv->cce_running = 0; @@ -727,37 +729,36 @@ int r128_cce_reset( DRM_IOCTL_ARGS ) return 0; } -int r128_cce_idle( DRM_IOCTL_ARGS ) +int r128_cce_idle(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( dev_priv->cce_running ) { - r128_do_cce_flush( dev_priv ); + if (dev_priv->cce_running) { + r128_do_cce_flush(dev_priv); } - return r128_do_cce_idle( dev_priv ); + return r128_do_cce_idle(dev_priv); } -int r128_engine_reset( DRM_IOCTL_ARGS ) +int r128_engine_reset(DRM_IOCTL_ARGS) { DRM_DEVICE; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - return r128_do_engine_reset( dev ); + return r128_do_engine_reset(dev); } -int r128_fullscreen( DRM_IOCTL_ARGS ) +int r128_fullscreen(DRM_IOCTL_ARGS) { return DRM_ERR(EINVAL); } - /* ================================================================ * Freelist management */ @@ -765,7 +766,7 @@ int r128_fullscreen( DRM_IOCTL_ARGS ) #define R128_BUFFER_FREE 0 #if 0 -static int r128_freelist_init( drm_device_t *dev ) +static int r128_freelist_init(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; @@ -774,27 +775,26 @@ static int r128_freelist_init( drm_device_t *dev ) drm_r128_freelist_t *entry; int i; - dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t), - DRM_MEM_DRIVER ); - if ( dev_priv->head == NULL ) + dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); + if (dev_priv->head == NULL) return DRM_ERR(ENOMEM); - memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) ); + memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t)); dev_priv->head->age = R128_BUFFER_USED; - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - entry = drm_alloc( sizeof(drm_r128_freelist_t), - DRM_MEM_DRIVER ); - if ( !entry ) return DRM_ERR(ENOMEM); + entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); + if (!entry) + return DRM_ERR(ENOMEM); entry->age = R128_BUFFER_FREE; entry->buf = buf; entry->prev = dev_priv->head; entry->next = dev_priv->head->next; - if ( !entry->next ) + if (!entry->next) dev_priv->tail = entry; buf_priv->discard = 0; @@ -803,7 +803,7 @@ static int r128_freelist_init( drm_device_t *dev ) dev_priv->head->next = entry; - if ( dev_priv->head->next ) + if (dev_priv->head->next) dev_priv->head->next->prev = entry; } @@ -812,7 +812,7 @@ static int r128_freelist_init( drm_device_t *dev ) } #endif -static drm_buf_t *r128_freelist_get( drm_device_t *dev ) +static drm_buf_t *r128_freelist_get(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; @@ -822,20 +822,20 @@ static drm_buf_t *r128_freelist_get( drm_device_t *dev ) /* FIXME: Optimize -- use freelist code */ - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->filp == 0 ) + if (buf->filp == 0) return buf; } - for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { - u32 done_age = R128_READ( R128_LAST_DISPATCH_REG ); + for (t = 0; t < dev_priv->usec_timeout; t++) { + u32 done_age = R128_READ(R128_LAST_DISPATCH_REG); - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pending && buf_priv->age <= done_age ) { + if (buf->pending && buf_priv->age <= done_age) { /* The buffer has been processed, so it * can now be used. */ @@ -843,63 +843,63 @@ static drm_buf_t *r128_freelist_get( drm_device_t *dev ) return buf; } } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } - DRM_DEBUG( "returning NULL!\n" ); + DRM_DEBUG("returning NULL!\n"); return NULL; } -void r128_freelist_reset( drm_device_t *dev ) +void r128_freelist_reset(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; int i; - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[i]; drm_r128_buf_priv_t *buf_priv = buf->dev_private; buf_priv->age = 0; } } - /* ================================================================ * CCE command submission */ -int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) +int r128_wait_ring(drm_r128_private_t * dev_priv, int n) { drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - r128_update_ring_snapshot( dev_priv ); - if ( ring->space >= n ) + for (i = 0; i < dev_priv->usec_timeout; i++) { + r128_update_ring_snapshot(dev_priv); + if (ring->space >= n) return 0; - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } /* FIXME: This is being ignored... */ - DRM_ERROR( "failed!\n" ); + DRM_ERROR("failed!\n"); return DRM_ERR(EBUSY); } -static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) +static int r128_cce_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d) { int i; drm_buf_t *buf; - for ( i = d->granted_count ; i < d->request_count ; i++ ) { - buf = r128_freelist_get( dev ); - if ( !buf ) return DRM_ERR(EAGAIN); + for (i = d->granted_count; i < d->request_count; i++) { + buf = r128_freelist_get(dev); + if (!buf) + return DRM_ERR(EAGAIN); buf->filp = filp; - if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, - sizeof(buf->idx) ) ) + if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, + sizeof(buf->idx))) return DRM_ERR(EFAULT); - if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, - sizeof(buf->total) ) ) + if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, + sizeof(buf->total))) return DRM_ERR(EFAULT); d->granted_count++; @@ -907,7 +907,7 @@ static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) return 0; } -int r128_cce_buffers( DRM_IOCTL_ARGS ) +int r128_cce_buffers(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_device_dma_t *dma = dev->dma; @@ -915,33 +915,33 @@ int r128_cce_buffers( DRM_IOCTL_ARGS ) drm_dma_t __user *argp = (void __user *)data; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) ); + DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); /* Please don't send us buffers. */ - if ( d.send_count != 0 ) { - DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count ); + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count); return DRM_ERR(EINVAL); } /* We'll send you buffers. */ - if ( d.request_count < 0 || d.request_count > dma->buf_count ) { - DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count ); + if (d.request_count < 0 || d.request_count > dma->buf_count) { + DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", + DRM_CURRENTPID, d.request_count, dma->buf_count); return DRM_ERR(EINVAL); } d.granted_count = 0; - if ( d.request_count ) { - ret = r128_cce_get_buffers( filp, dev, &d ); + if (d.request_count) { + ret = r128_cce_get_buffers(filp, dev, &d); } - DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d) ); + DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); return ret; } diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h index b616cd3ed2cd..5ddc03202411 100644 --- a/drivers/char/drm/r128_drm.h +++ b/drivers/char/drm/r128_drm.h @@ -93,7 +93,7 @@ #define R128_MAX_TEXTURE_LEVELS 11 #define R128_MAX_TEXTURE_UNITS 2 -#endif /* __R128_SAREA_DEFINES__ */ +#endif /* __R128_SAREA_DEFINES__ */ typedef struct { /* Context state - can be written in one large chunk */ @@ -140,7 +140,6 @@ typedef struct { unsigned int tex_border_color; } drm_r128_texture_regs_t; - typedef struct drm_r128_sarea { /* The channel for communication of state information to the kernel * on firing a vertex buffer. @@ -161,14 +160,13 @@ typedef struct drm_r128_sarea { unsigned int last_frame; unsigned int last_dispatch; - drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1]; unsigned int tex_age[R128_NR_TEX_HEAPS]; int ctx_owner; - int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */ - int pfCurrentPage; /* which buffer is being displayed? */ + int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */ + int pfCurrentPage; /* which buffer is being displayed? */ } drm_r128_sarea_t; - /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmR128.h) */ @@ -220,7 +218,7 @@ typedef struct drm_r128_sarea { typedef struct drm_r128_init { enum { - R128_INIT_CCE = 0x01, + R128_INIT_CCE = 0x01, R128_CLEANUP_CCE = 0x02 } func; #if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) @@ -278,9 +276,9 @@ typedef struct drm_r128_clear { typedef struct drm_r128_vertex { int prim; - int idx; /* Index of vertex buffer */ - int count; /* Number of vertices in buffer */ - int discard; /* Client finished with buffer? */ + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ } drm_r128_vertex_t; typedef struct drm_r128_indices { @@ -288,7 +286,7 @@ typedef struct drm_r128_indices { int idx; int start; int end; - int discard; /* Client finished with buffer? */ + int discard; /* Client finished with buffer? */ } drm_r128_indices_t; typedef struct drm_r128_blit { @@ -302,10 +300,10 @@ typedef struct drm_r128_blit { typedef struct drm_r128_depth { enum { - R128_WRITE_SPAN = 0x01, - R128_WRITE_PIXELS = 0x02, - R128_READ_SPAN = 0x03, - R128_READ_PIXELS = 0x04 + R128_WRITE_SPAN = 0x01, + R128_WRITE_PIXELS = 0x02, + R128_READ_SPAN = 0x03, + R128_READ_PIXELS = 0x04 } func; int n; int __user *x; @@ -327,13 +325,13 @@ typedef struct drm_r128_indirect { typedef struct drm_r128_fullscreen { enum { - R128_INIT_FULLSCREEN = 0x01, + R128_INIT_FULLSCREEN = 0x01, R128_CLEANUP_FULLSCREEN = 0x02 } func; } drm_r128_fullscreen_t; /* 2.3: An ioctl to get parameters that aren't available to the 3d - * client any other way. + * client any other way. */ #define R128_PARAM_IRQ_NR 1 diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index bc446da1b210..4d9224645f04 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -37,30 +37,28 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -72,7 +70,10 @@ extern drm_ioctl_desc_t r128_ioctls[]; extern int r128_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_r128_buf_priv_t), .prerelease = r128_driver_prerelease, .pretakedown = r128_driver_pretakedown, @@ -89,21 +90,22 @@ static struct drm_driver driver = { .ioctls = r128_ioctls, .dma_ioctl = r128_cce_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = r128_compat_ioctl, + .compat_ioctl = r128_compat_ioctl, #endif - }, + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init r128_init(void) @@ -120,6 +122,6 @@ static void __exit r128_exit(void) module_init(r128_init); module_exit(r128_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 938dfaea553a..87c5e1381ba2 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h @@ -52,14 +52,13 @@ #define DRIVER_MINOR 5 #define DRIVER_PATCHLEVEL 0 - #define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) typedef struct drm_r128_freelist { - unsigned int age; - drm_buf_t *buf; - struct drm_r128_freelist *next; - struct drm_r128_freelist *prev; + unsigned int age; + drm_buf_t *buf; + struct drm_r128_freelist *next; + struct drm_r128_freelist *prev; } drm_r128_freelist_t; typedef struct drm_r128_ring_buffer { @@ -83,8 +82,8 @@ typedef struct drm_r128_private { int cce_fifo_size; int cce_running; - drm_r128_freelist_t *head; - drm_r128_freelist_t *tail; + drm_r128_freelist_t *head; + drm_r128_freelist_t *tail; int usec_timeout; int is_pci; @@ -126,34 +125,34 @@ typedef struct drm_r128_buf_priv { int prim; int discard; int dispatched; - drm_r128_freelist_t *list_entry; + drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; /* r128_cce.c */ -extern int r128_cce_init( DRM_IOCTL_ARGS ); -extern int r128_cce_start( DRM_IOCTL_ARGS ); -extern int r128_cce_stop( DRM_IOCTL_ARGS ); -extern int r128_cce_reset( DRM_IOCTL_ARGS ); -extern int r128_cce_idle( DRM_IOCTL_ARGS ); -extern int r128_engine_reset( DRM_IOCTL_ARGS ); -extern int r128_fullscreen( DRM_IOCTL_ARGS ); -extern int r128_cce_buffers( DRM_IOCTL_ARGS ); +extern int r128_cce_init(DRM_IOCTL_ARGS); +extern int r128_cce_start(DRM_IOCTL_ARGS); +extern int r128_cce_stop(DRM_IOCTL_ARGS); +extern int r128_cce_reset(DRM_IOCTL_ARGS); +extern int r128_cce_idle(DRM_IOCTL_ARGS); +extern int r128_engine_reset(DRM_IOCTL_ARGS); +extern int r128_fullscreen(DRM_IOCTL_ARGS); +extern int r128_cce_buffers(DRM_IOCTL_ARGS); -extern void r128_freelist_reset( drm_device_t *dev ); +extern void r128_freelist_reset(drm_device_t * dev); -extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n ); +extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); -extern int r128_do_cce_idle( drm_r128_private_t *dev_priv ); -extern int r128_do_cleanup_cce( drm_device_t *dev ); +extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); +extern int r128_do_cleanup_cce(drm_device_t * dev); -extern int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); +extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); -extern irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS ); -extern void r128_driver_irq_preinstall( drm_device_t *dev ); -extern void r128_driver_irq_postinstall( drm_device_t *dev ); -extern void r128_driver_irq_uninstall( drm_device_t *dev ); -extern void r128_driver_pretakedown(drm_device_t *dev); -extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp); +extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); +extern void r128_driver_irq_preinstall(drm_device_t * dev); +extern void r128_driver_irq_postinstall(drm_device_t * dev); +extern void r128_driver_irq_uninstall(drm_device_t * dev); +extern void r128_driver_pretakedown(drm_device_t * dev); +extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -265,7 +264,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, # define R128_EVENT_CRTC_OFFSET (1 << 0) #define R128_WINDOW_XY_OFFSET 0x1bcc - /* CCE registers */ #define R128_PM4_BUFFER_OFFSET 0x0700 @@ -316,7 +314,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, #define R128_PM4_FIFO_DATA_EVEN 0x1000 #define R128_PM4_FIFO_DATA_ODD 0x1004 - /* CCE command packets */ #define R128_CCE_PACKET0 0x00000000 @@ -394,7 +391,6 @@ do { \ R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ } while (0) - #define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \ ((n) << 16) | ((reg) >> 2)) #define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \ @@ -403,13 +399,11 @@ do { \ #define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \ (pkt) | ((n) << 16)) - -static __inline__ void -r128_update_ring_snapshot( drm_r128_private_t *dev_priv ) +static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv) { drm_r128_ring_buffer_t *ring = &dev_priv->ring; - ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) + ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); + if (ring->space <= 0) ring->space += ring->size; } @@ -450,7 +444,6 @@ do { \ OUT_RING( R128_EVENT_CRTC_OFFSET ); \ } while (0) - /* ================================================================ * Ring control */ @@ -520,4 +513,4 @@ do { \ write &= tail_mask; \ } while (0) -#endif /* __R128_DRV_H__ */ +#endif /* __R128_DRV_H__ */ diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c index 60598ef9475a..1e2e367b8b82 100644 --- a/drivers/char/drm/r128_ioc32.c +++ b/drivers/char/drm/r128_ioc32.c @@ -65,10 +65,10 @@ static int compat_r128_init(struct file *file, unsigned int cmd, { drm_r128_init32_t init32; drm_r128_init_t __user *init; - + if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) return -EFAULT; - + init = compat_alloc_user_space(sizeof(*init)); if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) || __put_user(init32.func, &init->func) @@ -92,14 +92,14 @@ static int compat_r128_init(struct file *file, unsigned int cmd, || __put_user(init32.ring_offset, &init->ring_offset) || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.agp_textures_offset, &init->agp_textures_offset)) + || __put_user(init32.agp_textures_offset, + &init->agp_textures_offset)) return -EFAULT; - + return drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_R128_INIT, (unsigned long)init); } - typedef struct drm_r128_depth32 { int func; int n; @@ -124,13 +124,15 @@ static int compat_r128_depth(struct file *file, unsigned int cmd, || __put_user(depth32.n, &depth->n) || __put_user((int __user *)(unsigned long)depth32.x, &depth->x) || __put_user((int __user *)(unsigned long)depth32.y, &depth->y) - || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer) - || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask)) + || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, + &depth->buffer) + || __put_user((unsigned char __user *)(unsigned long)depth32.mask, + &depth->mask)) return -EFAULT; - + return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_R128_DEPTH, (unsigned long)depth); - + DRM_IOCTL_R128_DEPTH, (unsigned long)depth); + } typedef struct drm_r128_stipple32 { @@ -148,7 +150,8 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd, stipple = compat_alloc_user_space(sizeof(*stipple)); if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple)) - || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask)) + || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, + &stipple->mask)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, @@ -172,9 +175,10 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd, getparam = compat_alloc_user_space(sizeof(*getparam)); if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value)) + || __put_user((void __user *)(unsigned long)getparam32.value, + &getparam->value)) return -EFAULT; - + return drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); } @@ -195,8 +199,7 @@ drm_ioctl_compat_t *r128_compat_ioctls[] = { * \param arg user argument. * \return zero on success or negative number on failure. */ -long r128_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) +long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int nr = DRM_IOCTL_NR(cmd); drm_ioctl_compat_t *fn = NULL; @@ -210,7 +213,7 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd, lock_kernel(); /* XXX for now */ if (fn != NULL) - ret = (*fn)(filp, cmd, arg); + ret = (*fn) (filp, cmd, arg); else ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c index 643a30785fe5..27eb0e31bd3b 100644 --- a/drivers/char/drm/r128_irq.c +++ b/drivers/char/drm/r128_irq.c @@ -1,7 +1,7 @@ /* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * + * * The Weather Channel (TM) funded Tungsten Graphics to develop the * initial release of the Radeon 8500 driver under the XFree86 license. * This notice must be preserved. @@ -35,68 +35,67 @@ #include "r128_drm.h" #include "r128_drv.h" -irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS ) +irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; - drm_r128_private_t *dev_priv = - (drm_r128_private_t *)dev->dev_private; + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; int status; - status = R128_READ( R128_GEN_INT_STATUS ); - + status = R128_READ(R128_GEN_INT_STATUS); + /* VBLANK interrupt */ - if ( status & R128_CRTC_VBLANK_INT ) { - R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK ); + if (status & R128_CRTC_VBLANK_INT) { + R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals( dev ); + drm_vbl_send_signals(dev); return IRQ_HANDLED; } return IRQ_NONE; } -int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) { unsigned int cur_vblank; int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years - * using vertical blanks... + * using vertical blanks... */ - DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, - ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) - - *sequence ) <= (1<<23) ) ); + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; } -void r128_driver_irq_preinstall( drm_device_t *dev ) { - drm_r128_private_t *dev_priv = - (drm_r128_private_t *)dev->dev_private; +void r128_driver_irq_preinstall(drm_device_t * dev) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; /* Disable *all* interrupts */ - R128_WRITE( R128_GEN_INT_CNTL, 0 ); + R128_WRITE(R128_GEN_INT_CNTL, 0); /* Clear vblank bit if it's already high */ - R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK ); + R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); } -void r128_driver_irq_postinstall( drm_device_t *dev ) { - drm_r128_private_t *dev_priv = - (drm_r128_private_t *)dev->dev_private; +void r128_driver_irq_postinstall(drm_device_t * dev) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; /* Turn on VBL interrupt */ - R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN ); + R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); } -void r128_driver_irq_uninstall( drm_device_t *dev ) { - drm_r128_private_t *dev_priv = - (drm_r128_private_t *)dev->dev_private; +void r128_driver_irq_uninstall(drm_device_t * dev) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; if (!dev_priv) return; /* Disable *all* interrupts */ - R128_WRITE( R128_GEN_INT_CNTL, 0 ); + R128_WRITE(R128_GEN_INT_CNTL, 0); } diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c index 426a71c049d9..14479cc08a57 100644 --- a/drivers/char/drm/r128_state.c +++ b/drivers/char/drm/r128_state.c @@ -32,235 +32,233 @@ #include "r128_drm.h" #include "r128_drv.h" - /* ================================================================ * CCE hardware state programming functions */ -static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, - drm_clip_rect_t *boxes, int count ) +static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, + drm_clip_rect_t * boxes, int count) { u32 aux_sc_cntl = 0x00000000; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( (count < 3? count: 3) * 5 + 2 ); + BEGIN_RING((count < 3 ? count : 3) * 5 + 2); - if ( count >= 1 ) { - OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) ); - OUT_RING( boxes[0].x1 ); - OUT_RING( boxes[0].x2 - 1 ); - OUT_RING( boxes[0].y1 ); - OUT_RING( boxes[0].y2 - 1 ); + if (count >= 1) { + OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3)); + OUT_RING(boxes[0].x1); + OUT_RING(boxes[0].x2 - 1); + OUT_RING(boxes[0].y1); + OUT_RING(boxes[0].y2 - 1); aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); } - if ( count >= 2 ) { - OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) ); - OUT_RING( boxes[1].x1 ); - OUT_RING( boxes[1].x2 - 1 ); - OUT_RING( boxes[1].y1 ); - OUT_RING( boxes[1].y2 - 1 ); + if (count >= 2) { + OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3)); + OUT_RING(boxes[1].x1); + OUT_RING(boxes[1].x2 - 1); + OUT_RING(boxes[1].y1); + OUT_RING(boxes[1].y2 - 1); aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); } - if ( count >= 3 ) { - OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) ); - OUT_RING( boxes[2].x1 ); - OUT_RING( boxes[2].x2 - 1 ); - OUT_RING( boxes[2].y1 ); - OUT_RING( boxes[2].y2 - 1 ); + if (count >= 3) { + OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3)); + OUT_RING(boxes[2].x1); + OUT_RING(boxes[2].x2 - 1); + OUT_RING(boxes[2].y1); + OUT_RING(boxes[2].y2 - 1); aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); } - OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) ); - OUT_RING( aux_sc_cntl ); + OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0)); + OUT_RING(aux_sc_cntl); ADVANCE_RING(); } -static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) ); - OUT_RING( ctx->scale_3d_cntl ); + OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0)); + OUT_RING(ctx->scale_3d_cntl); ADVANCE_RING(); } -static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 13 ); + BEGIN_RING(13); - OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) ); - OUT_RING( ctx->dst_pitch_offset_c ); - OUT_RING( ctx->dp_gui_master_cntl_c ); - OUT_RING( ctx->sc_top_left_c ); - OUT_RING( ctx->sc_bottom_right_c ); - OUT_RING( ctx->z_offset_c ); - OUT_RING( ctx->z_pitch_c ); - OUT_RING( ctx->z_sten_cntl_c ); - OUT_RING( ctx->tex_cntl_c ); - OUT_RING( ctx->misc_3d_state_cntl_reg ); - OUT_RING( ctx->texture_clr_cmp_clr_c ); - OUT_RING( ctx->texture_clr_cmp_msk_c ); - OUT_RING( ctx->fog_color_c ); + OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11)); + OUT_RING(ctx->dst_pitch_offset_c); + OUT_RING(ctx->dp_gui_master_cntl_c); + OUT_RING(ctx->sc_top_left_c); + OUT_RING(ctx->sc_bottom_right_c); + OUT_RING(ctx->z_offset_c); + OUT_RING(ctx->z_pitch_c); + OUT_RING(ctx->z_sten_cntl_c); + OUT_RING(ctx->tex_cntl_c); + OUT_RING(ctx->misc_3d_state_cntl_reg); + OUT_RING(ctx->texture_clr_cmp_clr_c); + OUT_RING(ctx->texture_clr_cmp_msk_c); + OUT_RING(ctx->fog_color_c); ADVANCE_RING(); } -static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 3 ); + BEGIN_RING(3); - OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) ); - OUT_RING( ctx->setup_cntl ); - OUT_RING( ctx->pm4_vc_fpu_setup ); + OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP)); + OUT_RING(ctx->setup_cntl); + OUT_RING(ctx->pm4_vc_fpu_setup); ADVANCE_RING(); } -static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 5 ); + BEGIN_RING(5); - OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( ctx->dp_write_mask ); + OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); + OUT_RING(ctx->dp_write_mask); - OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) ); - OUT_RING( ctx->sten_ref_mask_c ); - OUT_RING( ctx->plane_3d_mask_c ); + OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1)); + OUT_RING(ctx->sten_ref_mask_c); + OUT_RING(ctx->plane_3d_mask_c); ADVANCE_RING(); } -static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) ); - OUT_RING( ctx->window_xy_offset ); + OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0)); + OUT_RING(ctx->window_xy_offset); ADVANCE_RING(); } -static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; int i; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS ); + BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS); - OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C, - 2 + R128_MAX_TEXTURE_LEVELS ) ); - OUT_RING( tex->tex_cntl ); - OUT_RING( tex->tex_combine_cntl ); - OUT_RING( ctx->tex_size_pitch_c ); - for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { - OUT_RING( tex->tex_offset[i] ); + OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, + 2 + R128_MAX_TEXTURE_LEVELS)); + OUT_RING(tex->tex_cntl); + OUT_RING(tex->tex_combine_cntl); + OUT_RING(ctx->tex_size_pitch_c); + for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { + OUT_RING(tex->tex_offset[i]); } - OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) ); - OUT_RING( ctx->constant_color_c ); - OUT_RING( tex->tex_border_color ); + OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); + OUT_RING(ctx->constant_color_c); + OUT_RING(tex->tex_border_color); ADVANCE_RING(); } -static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; int i; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG(" %s\n", __FUNCTION__); - BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS ); + BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS); - OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C, - 1 + R128_MAX_TEXTURE_LEVELS ) ); - OUT_RING( tex->tex_cntl ); - OUT_RING( tex->tex_combine_cntl ); - for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { - OUT_RING( tex->tex_offset[i] ); + OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); + OUT_RING(tex->tex_cntl); + OUT_RING(tex->tex_combine_cntl); + for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { + OUT_RING(tex->tex_offset[i]); } - OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) ); - OUT_RING( tex->tex_border_color ); + OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); + OUT_RING(tex->tex_border_color); ADVANCE_RING(); } -static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; - DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty); - if ( dirty & R128_UPLOAD_CORE ) { - r128_emit_core( dev_priv ); + if (dirty & R128_UPLOAD_CORE) { + r128_emit_core(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_CORE; } - if ( dirty & R128_UPLOAD_CONTEXT ) { - r128_emit_context( dev_priv ); + if (dirty & R128_UPLOAD_CONTEXT) { + r128_emit_context(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; } - if ( dirty & R128_UPLOAD_SETUP ) { - r128_emit_setup( dev_priv ); + if (dirty & R128_UPLOAD_SETUP) { + r128_emit_setup(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_SETUP; } - if ( dirty & R128_UPLOAD_MASKS ) { - r128_emit_masks( dev_priv ); + if (dirty & R128_UPLOAD_MASKS) { + r128_emit_masks(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_MASKS; } - if ( dirty & R128_UPLOAD_WINDOW ) { - r128_emit_window( dev_priv ); + if (dirty & R128_UPLOAD_WINDOW) { + r128_emit_window(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; } - if ( dirty & R128_UPLOAD_TEX0 ) { - r128_emit_tex0( dev_priv ); + if (dirty & R128_UPLOAD_TEX0) { + r128_emit_tex0(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_TEX0; } - if ( dirty & R128_UPLOAD_TEX1 ) { - r128_emit_tex1( dev_priv ); + if (dirty & R128_UPLOAD_TEX1) { + r128_emit_tex1(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_TEX1; } @@ -270,26 +268,23 @@ static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv ) sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; } - #if R128_PERFORMANCE_BOXES /* ================================================================ * Performance monitoring functions */ -static void r128_clear_box( drm_r128_private_t *dev_priv, - int x, int y, int w, int h, - int r, int g, int b ) +static void r128_clear_box(drm_r128_private_t * dev_priv, + int x, int y, int w, int h, int r, int g, int b) { u32 pitch, offset; u32 fb_bpp, color; RING_LOCALS; - switch ( dev_priv->fb_bpp ) { + switch (dev_priv->fb_bpp) { case 16: fb_bpp = R128_GMC_DST_16BPP; color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | - ((b & 0xf8) >> 3)); + ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; case 24: fb_bpp = R128_GMC_DST_24BPP; @@ -297,7 +292,7 @@ static void r128_clear_box( drm_r128_private_t *dev_priv, break; case 32: fb_bpp = R128_GMC_DST_32BPP; - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; default: return; @@ -306,60 +301,58 @@ static void r128_clear_box( drm_r128_private_t *dev_priv, offset = dev_priv->back_offset; pitch = dev_priv->back_pitch >> 3; - BEGIN_RING( 6 ); + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - fb_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); - OUT_RING( (pitch << 21) | (offset >> 5) ); - OUT_RING( color ); + OUT_RING((pitch << 21) | (offset >> 5)); + OUT_RING(color); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } -static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv ) +static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv) { - if ( atomic_read( &dev_priv->idle_count ) == 0 ) { - r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + if (atomic_read(&dev_priv->idle_count) == 0) { + r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); } else { - atomic_set( &dev_priv->idle_count, 0 ); + atomic_set(&dev_priv->idle_count, 0); } } #endif - /* ================================================================ * CCE command dispatch functions */ -static void r128_print_dirty( const char *msg, unsigned int flags ) +static void r128_print_dirty(const char *msg, unsigned int flags) { - DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & R128_UPLOAD_CORE) ? "core, " : "", - (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", - (flags & R128_UPLOAD_SETUP) ? "setup, " : "", - (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", - (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", - (flags & R128_UPLOAD_MASKS) ? "masks, " : "", - (flags & R128_UPLOAD_WINDOW) ? "window, " : "", - (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); + DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & R128_UPLOAD_CORE) ? "core, " : "", + (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", + (flags & R128_UPLOAD_SETUP) ? "setup, " : "", + (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", + (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", + (flags & R128_UPLOAD_MASKS) ? "masks, " : "", + (flags & R128_UPLOAD_WINDOW) ? "window, " : "", + (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); } -static void r128_cce_dispatch_clear( drm_device_t *dev, - drm_r128_clear_t *clear ) +static void r128_cce_dispatch_clear(drm_device_t * dev, + drm_r128_clear_t * clear) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -368,102 +361,103 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, unsigned int flags = clear->flags; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + if (dev_priv->page_flipping && dev_priv->current_page == 1) { unsigned int tmp = flags; flags &= ~(R128_FRONT | R128_BACK); - if ( tmp & R128_FRONT ) flags |= R128_BACK; - if ( tmp & R128_BACK ) flags |= R128_FRONT; + if (tmp & R128_FRONT) + flags |= R128_BACK; + if (tmp & R128_BACK) + flags |= R128_FRONT; } - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; - DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", - pbox[i].x1, pbox[i].y1, pbox[i].x2, - pbox[i].y2, flags ); + DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", + pbox[i].x1, pbox[i].y1, pbox[i].x2, + pbox[i].y2, flags); - if ( flags & (R128_FRONT | R128_BACK) ) { - BEGIN_RING( 2 ); + if (flags & (R128_FRONT | R128_BACK)) { + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( clear->color_mask ); + OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); + OUT_RING(clear->color_mask); ADVANCE_RING(); } - if ( flags & R128_FRONT ) { - BEGIN_RING( 6 ); + if (flags & R128_FRONT) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS); - OUT_RING( dev_priv->front_pitch_offset_c ); - OUT_RING( clear->clear_color ); + OUT_RING(dev_priv->front_pitch_offset_c); + OUT_RING(clear->clear_color); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } - if ( flags & R128_BACK ) { - BEGIN_RING( 6 ); + if (flags & R128_BACK) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS); - OUT_RING( dev_priv->back_pitch_offset_c ); - OUT_RING( clear->clear_color ); + OUT_RING(dev_priv->back_pitch_offset_c); + OUT_RING(clear->clear_color); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } - if ( flags & R128_DEPTH ) { - BEGIN_RING( 6 ); + if (flags & R128_DEPTH) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( clear->clear_depth ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(clear->clear_depth); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } } } -static void r128_cce_dispatch_swap( drm_device_t *dev ) +static void r128_cce_dispatch_swap(drm_device_t * dev) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -471,48 +465,46 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - r128_cce_performance_boxes( dev_priv ); + r128_cce_performance_boxes(dev_priv); #endif - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; - BEGIN_RING( 7 ); + BEGIN_RING(7); - OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); + OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); /* Make this work even if front & back are flipped: */ if (dev_priv->current_page == 0) { - OUT_RING( dev_priv->back_pitch_offset_c ); - OUT_RING( dev_priv->front_pitch_offset_c ); - } - else { - OUT_RING( dev_priv->front_pitch_offset_c ); - OUT_RING( dev_priv->back_pitch_offset_c ); + OUT_RING(dev_priv->back_pitch_offset_c); + OUT_RING(dev_priv->front_pitch_offset_c); + } else { + OUT_RING(dev_priv->front_pitch_offset_c); + OUT_RING(dev_priv->back_pitch_offset_c); } - OUT_RING( (x << 16) | y ); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } @@ -523,38 +515,37 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) */ dev_priv->sarea_priv->last_frame++; - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); - OUT_RING( dev_priv->sarea_priv->last_frame ); + OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); + OUT_RING(dev_priv->sarea_priv->last_frame); ADVANCE_RING(); } -static void r128_cce_dispatch_flip( drm_device_t *dev ) +static void r128_cce_dispatch_flip(drm_device_t * dev) { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", - __FUNCTION__, - dev_priv->current_page, - dev_priv->sarea_priv->pfCurrentPage); + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - r128_cce_performance_boxes( dev_priv ); + r128_cce_performance_boxes(dev_priv); #endif - BEGIN_RING( 4 ); + BEGIN_RING(4); R128_WAIT_UNTIL_PAGE_FLIPPED(); - OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) ); + OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); - if ( dev_priv->current_page == 0 ) { - OUT_RING( dev_priv->back_offset ); + if (dev_priv->current_page == 0) { + OUT_RING(dev_priv->back_offset); } else { - OUT_RING( dev_priv->front_offset ); + OUT_RING(dev_priv->front_offset); } ADVANCE_RING(); @@ -565,18 +556,17 @@ static void r128_cce_dispatch_flip( drm_device_t *dev ) */ dev_priv->sarea_priv->last_frame++; dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = - 1 - dev_priv->current_page; + 1 - dev_priv->current_page; - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); - OUT_RING( dev_priv->sarea_priv->last_frame ); + OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); + OUT_RING(dev_priv->sarea_priv->last_frame); ADVANCE_RING(); } -static void r128_cce_dispatch_vertex( drm_device_t *dev, - drm_buf_t *buf ) +static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -587,50 +577,50 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, int prim = buf_priv->prim; int i = 0; RING_LOCALS; - DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); + DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox); - if ( 0 ) - r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); + if (0) + r128_print_dirty("dispatch_vertex", sarea_priv->dirty); - if ( buf->used ) { + if (buf->used) { buf_priv->dispatched = 1; - if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128_emit_state( dev_priv ); + if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { + r128_emit_state(dev_priv); } do { /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - r128_emit_clip_rects( dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i ); + if (i < sarea_priv->nbox) { + r128_emit_clip_rects(dev_priv, + &sarea_priv->boxes[i], + sarea_priv->nbox - i); } /* Emit the vertex buffer rendering commands */ - BEGIN_RING( 5 ); + BEGIN_RING(5); - OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) ); - OUT_RING( offset ); - OUT_RING( size ); - OUT_RING( format ); - OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | - (size << R128_CCE_VC_CNTL_NUM_SHIFT) ); + OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3)); + OUT_RING(offset); + OUT_RING(size); + OUT_RING(format); + OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | + (size << R128_CCE_VC_CNTL_NUM_SHIFT)); ADVANCE_RING(); i += 3; - } while ( i < sarea_priv->nbox ); + } while (i < sarea_priv->nbox); } - if ( buf_priv->discard ) { + if (buf_priv->discard) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); - OUT_RING( buf_priv->age ); + OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); + OUT_RING(buf_priv->age); ADVANCE_RING(); @@ -646,17 +636,15 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, sarea_priv->nbox = 0; } -static void r128_cce_dispatch_indirect( drm_device_t *dev, - drm_buf_t *buf, - int start, int end ) +static void r128_cce_dispatch_indirect(drm_device_t * dev, + drm_buf_t * buf, int start, int end) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; - DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", - buf->idx, start, end ); + DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - if ( start != end ) { + if (start != end) { int offset = buf->bus_address + start; int dwords = (end - start + 3) / sizeof(u32); @@ -664,33 +652,33 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, * dwords, so if we've been given an odd number we must * pad the data with a Type-2 CCE packet. */ - if ( dwords & 1 ) { + if (dwords & 1) { u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 ); + ((char *)dev->agp_buffer_map->handle + + buf->offset + start); + data[dwords++] = cpu_to_le32(R128_CCE_PACKET2); } buf_priv->dispatched = 1; /* Fire off the indirect buffer */ - BEGIN_RING( 3 ); + BEGIN_RING(3); - OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) ); - OUT_RING( offset ); - OUT_RING( dwords ); + OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1)); + OUT_RING(offset); + OUT_RING(dwords); ADVANCE_RING(); } - if ( buf_priv->discard ) { + if (buf_priv->discard) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the indirect buffer age */ - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); - OUT_RING( buf_priv->age ); + OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); + OUT_RING(buf_priv->age); ADVANCE_RING(); @@ -703,10 +691,9 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, dev_priv->sarea_priv->last_dispatch++; } -static void r128_cce_dispatch_indices( drm_device_t *dev, - drm_buf_t *buf, - int start, int end, - int count ) +static void r128_cce_dispatch_indices(drm_device_t * dev, + drm_buf_t * buf, + int start, int end, int count) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -718,62 +705,62 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, int dwords; int i = 0; RING_LOCALS; - DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); + DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count); - if ( 0 ) - r128_print_dirty( "dispatch_indices", sarea_priv->dirty ); + if (0) + r128_print_dirty("dispatch_indices", sarea_priv->dirty); - if ( start != end ) { + if (start != end) { buf_priv->dispatched = 1; - if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128_emit_state( dev_priv ); + if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { + r128_emit_state(dev_priv); } dwords = (end - start + 3) / sizeof(u32); - data = (u32 *)((char *)dev->agp_buffer_map->handle - + buf->offset + start); + data = (u32 *) ((char *)dev->agp_buffer_map->handle + + buf->offset + start); - data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, - dwords-2 ) ); + data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, + dwords - 2)); - data[1] = cpu_to_le32( offset ); - data[2] = cpu_to_le32( R128_MAX_VB_VERTS ); - data[3] = cpu_to_le32( format ); - data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | - (count << 16)) ); + data[1] = cpu_to_le32(offset); + data[2] = cpu_to_le32(R128_MAX_VB_VERTS); + data[3] = cpu_to_le32(format); + data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | + (count << 16))); - if ( count & 0x1 ) { + if (count & 0x1) { #ifdef __LITTLE_ENDIAN - data[dwords-1] &= 0x0000ffff; + data[dwords - 1] &= 0x0000ffff; #else - data[dwords-1] &= 0xffff0000; + data[dwords - 1] &= 0xffff0000; #endif } do { /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - r128_emit_clip_rects( dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i ); + if (i < sarea_priv->nbox) { + r128_emit_clip_rects(dev_priv, + &sarea_priv->boxes[i], + sarea_priv->nbox - i); } - r128_cce_dispatch_indirect( dev, buf, start, end ); + r128_cce_dispatch_indirect(dev, buf, start, end); i += 3; - } while ( i < sarea_priv->nbox ); + } while (i < sarea_priv->nbox); } - if ( buf_priv->discard ) { + if (buf_priv->discard) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); - OUT_RING( buf_priv->age ); + OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); + OUT_RING(buf_priv->age); ADVANCE_RING(); @@ -788,9 +775,8 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, sarea_priv->nbox = 0; } -static int r128_cce_dispatch_blit( DRMFILE filp, - drm_device_t *dev, - drm_r128_blit_t *blit ) +static int r128_cce_dispatch_blit(DRMFILE filp, + drm_device_t * dev, drm_r128_blit_t * blit) { drm_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; @@ -799,13 +785,13 @@ static int r128_cce_dispatch_blit( DRMFILE filp, u32 *data; int dword_shift, dwords; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll * use a shift instead. */ - switch ( blit->format ) { + switch (blit->format) { case R128_DATATYPE_ARGB8888: dword_shift = 0; break; @@ -821,7 +807,7 @@ static int r128_cce_dispatch_blit( DRMFILE filp, dword_shift = 2; break; default: - DRM_ERROR( "invalid blit format %d\n", blit->format ); + DRM_ERROR("invalid blit format %d\n", blit->format); return DRM_ERR(EINVAL); } @@ -830,10 +816,10 @@ static int r128_cce_dispatch_blit( DRMFILE filp, * data from the host data blit, otherwise part of the texture * image may be corrupted. */ - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); - OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI ); + OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); + OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI); ADVANCE_RING(); @@ -842,13 +828,13 @@ static int r128_cce_dispatch_blit( DRMFILE filp, buf = dma->buflist[blit->idx]; buf_priv = buf->dev_private; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", blit->idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", blit->idx); return DRM_ERR(EINVAL); } @@ -856,45 +842,43 @@ static int r128_cce_dispatch_blit( DRMFILE filp, dwords = (blit->width * blit->height) >> dword_shift; - data = (u32 *)((char *)dev->agp_buffer_map->handle + buf->offset); + data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) ); - data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (blit->format << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_HOST_DATA | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS) ); + data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6)); + data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (blit->format << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_HOST_DATA | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS)); - data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) ); - data[3] = cpu_to_le32( 0xffffffff ); - data[4] = cpu_to_le32( 0xffffffff ); - data[5] = cpu_to_le32( (blit->y << 16) | blit->x ); - data[6] = cpu_to_le32( (blit->height << 16) | blit->width ); - data[7] = cpu_to_le32( dwords ); + data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5)); + data[3] = cpu_to_le32(0xffffffff); + data[4] = cpu_to_le32(0xffffffff); + data[5] = cpu_to_le32((blit->y << 16) | blit->x); + data[6] = cpu_to_le32((blit->height << 16) | blit->width); + data[7] = cpu_to_le32(dwords); buf->used = (dwords + 8) * sizeof(u32); - r128_cce_dispatch_indirect( dev, buf, 0, buf->used ); + r128_cce_dispatch_indirect(dev, buf, 0, buf->used); /* Flush the pixel cache after the blit completes. This ensures * the texture data is written out to memory before rendering * continues. */ - BEGIN_RING( 2 ); + BEGIN_RING(2); - OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); - OUT_RING( R128_PC_FLUSH_GUI ); + OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); + OUT_RING(R128_PC_FLUSH_GUI); ADVANCE_RING(); return 0; } - /* ================================================================ * Tiled depth buffer management * @@ -902,8 +886,8 @@ static int r128_cce_dispatch_blit( DRMFILE filp, * have hardware stencil support. */ -static int r128_cce_dispatch_write_span( drm_device_t *dev, - drm_r128_depth_t *depth ) +static int r128_cce_dispatch_write_span(drm_device_t * dev, + drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; @@ -911,95 +895,95 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, u8 *mask; int i, buffer_size, mask_size; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); count = depth->n; if (count > 4096 || count <= 0) return DRM_ERR(EMSGSIZE); - if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { return DRM_ERR(EFAULT); } buffer_size = depth->n * sizeof(u32); - buffer = drm_alloc( buffer_size, DRM_MEM_BUFS ); - if ( buffer == NULL ) + buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); + if (buffer == NULL) return DRM_ERR(ENOMEM); - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { - drm_free( buffer, buffer_size, DRM_MEM_BUFS); + if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } mask_size = depth->n * sizeof(u8); - if ( depth->mask ) { - mask = drm_alloc( mask_size, DRM_MEM_BUFS ); - if ( mask == NULL ) { - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); + if (depth->mask) { + mask = drm_alloc(mask_size, DRM_MEM_BUFS); + if (mask == NULL) { + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); - drm_free( mask, mask_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { + drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(mask, mask_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - for ( i = 0 ; i < count ; i++, x++ ) { - if ( mask[i] ) { - BEGIN_RING( 6 ); + for (i = 0; i < count; i++, x++) { + if (mask[i]) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( buffer[i] ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(buffer[i]); - OUT_RING( (x << 16) | y ); - OUT_RING( (1 << 16) | 1 ); + OUT_RING((x << 16) | y); + OUT_RING((1 << 16) | 1); ADVANCE_RING(); } } - drm_free( mask, mask_size, DRM_MEM_BUFS ); + drm_free(mask, mask_size, DRM_MEM_BUFS); } else { - for ( i = 0 ; i < count ; i++, x++ ) { - BEGIN_RING( 6 ); + for (i = 0; i < count; i++, x++) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( buffer[i] ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(buffer[i]); - OUT_RING( (x << 16) | y ); - OUT_RING( (1 << 16) | 1 ); + OUT_RING((x << 16) | y); + OUT_RING((1 << 16) | 1); ADVANCE_RING(); } } - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return 0; } -static int r128_cce_dispatch_write_pixels( drm_device_t *dev, - drm_r128_depth_t *depth ) +static int r128_cce_dispatch_write_pixels(drm_device_t * dev, + drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; @@ -1007,7 +991,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, u8 *mask; int i, xbuf_size, ybuf_size, buffer_size, mask_size; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); count = depth->n; if (count > 4096 || count <= 0) @@ -1015,270 +999,266 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, xbuf_size = count * sizeof(*x); ybuf_size = count * sizeof(*y); - x = drm_alloc( xbuf_size, DRM_MEM_BUFS ); - if ( x == NULL ) { + x = drm_alloc(xbuf_size, DRM_MEM_BUFS); + if (x == NULL) { return DRM_ERR(ENOMEM); } - y = drm_alloc( ybuf_size, DRM_MEM_BUFS ); - if ( y == NULL ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); + y = drm_alloc(ybuf_size, DRM_MEM_BUFS); + if (y == NULL) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } buffer_size = depth->n * sizeof(u32); - buffer = drm_alloc( buffer_size, DRM_MEM_BUFS ); - if ( buffer == NULL ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); + if (buffer == NULL) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - if ( depth->mask ) { + if (depth->mask) { mask_size = depth->n * sizeof(u8); - mask = drm_alloc( mask_size, DRM_MEM_BUFS ); - if ( mask == NULL ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); + mask = drm_alloc(mask_size, DRM_MEM_BUFS); + if (mask == NULL) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); - drm_free( mask, mask_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(mask, mask_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - for ( i = 0 ; i < count ; i++ ) { - if ( mask[i] ) { - BEGIN_RING( 6 ); + for (i = 0; i < count; i++) { + if (mask[i]) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( buffer[i] ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(buffer[i]); - OUT_RING( (x[i] << 16) | y[i] ); - OUT_RING( (1 << 16) | 1 ); + OUT_RING((x[i] << 16) | y[i]); + OUT_RING((1 << 16) | 1); ADVANCE_RING(); } } - drm_free( mask, mask_size, DRM_MEM_BUFS ); + drm_free(mask, mask_size, DRM_MEM_BUFS); } else { - for ( i = 0 ; i < count ; i++ ) { - BEGIN_RING( 6 ); + for (i = 0; i < count; i++) { + BEGIN_RING(6); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); + OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( buffer[i] ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(buffer[i]); - OUT_RING( (x[i] << 16) | y[i] ); - OUT_RING( (1 << 16) | 1 ); + OUT_RING((x[i] << 16) | y[i]); + OUT_RING((1 << 16) | 1); ADVANCE_RING(); } } - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); - drm_free( buffer, buffer_size, DRM_MEM_BUFS ); + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(buffer, buffer_size, DRM_MEM_BUFS); return 0; } -static int r128_cce_dispatch_read_span( drm_device_t *dev, - drm_r128_depth_t *depth ) +static int r128_cce_dispatch_read_span(drm_device_t * dev, + drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); count = depth->n; if (count > 4096 || count <= 0) return DRM_ERR(EMSGSIZE); - if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { return DRM_ERR(EFAULT); } - BEGIN_RING( 7 ); + BEGIN_RING(7); - OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); + OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( dev_priv->span_pitch_offset_c ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(dev_priv->span_pitch_offset_c); - OUT_RING( (x << 16) | y ); - OUT_RING( (0 << 16) | 0 ); - OUT_RING( (count << 16) | 1 ); + OUT_RING((x << 16) | y); + OUT_RING((0 << 16) | 0); + OUT_RING((count << 16) | 1); ADVANCE_RING(); return 0; } -static int r128_cce_dispatch_read_pixels( drm_device_t *dev, - drm_r128_depth_t *depth ) +static int r128_cce_dispatch_read_pixels(drm_device_t * dev, + drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; int i, xbuf_size, ybuf_size; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); count = depth->n; if (count > 4096 || count <= 0) return DRM_ERR(EMSGSIZE); - if ( count > dev_priv->depth_pitch ) { + if (count > dev_priv->depth_pitch) { count = dev_priv->depth_pitch; } xbuf_size = count * sizeof(*x); ybuf_size = count * sizeof(*y); - x = drm_alloc( xbuf_size, DRM_MEM_BUFS ); - if ( x == NULL ) { + x = drm_alloc(xbuf_size, DRM_MEM_BUFS); + if (x == NULL) { return DRM_ERR(ENOMEM); } - y = drm_alloc( ybuf_size, DRM_MEM_BUFS ); - if ( y == NULL ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); + y = drm_alloc(ybuf_size, DRM_MEM_BUFS); + if (y == NULL) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) { - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return DRM_ERR(EFAULT); } - for ( i = 0 ; i < count ; i++ ) { - BEGIN_RING( 7 ); + for (i = 0; i < count; i++) { + BEGIN_RING(7); - OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS ); + OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); + OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( dev_priv->span_pitch_offset_c ); + OUT_RING(dev_priv->depth_pitch_offset_c); + OUT_RING(dev_priv->span_pitch_offset_c); - OUT_RING( (x[i] << 16) | y[i] ); - OUT_RING( (i << 16) | 0 ); - OUT_RING( (1 << 16) | 1 ); + OUT_RING((x[i] << 16) | y[i]); + OUT_RING((i << 16) | 0); + OUT_RING((1 << 16) | 1); ADVANCE_RING(); } - drm_free( x, xbuf_size, DRM_MEM_BUFS ); - drm_free( y, ybuf_size, DRM_MEM_BUFS ); + drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(y, ybuf_size, DRM_MEM_BUFS); return 0; } - /* ================================================================ * Polygon stipple */ -static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +static void r128_cce_dispatch_stipple(drm_device_t * dev, u32 * stipple) { drm_r128_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - BEGIN_RING( 33 ); + BEGIN_RING(33); - OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); - for ( i = 0 ; i < 32 ; i++ ) { - OUT_RING( stipple[i] ); + OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); + for (i = 0; i < 32; i++) { + OUT_RING(stipple[i]); } ADVANCE_RING(); } - /* ================================================================ * IOCTL functions */ -static int r128_cce_clear( DRM_IOCTL_ARGS ) +static int r128_cce_clear(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_clear_t clear; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t __user *) data, - sizeof(clear) ); + DRM_COPY_FROM_USER_IOCTL(clear, (drm_r128_clear_t __user *) data, + sizeof(clear)); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - r128_cce_dispatch_clear( dev, &clear ); + r128_cce_dispatch_clear(dev, &clear); COMMIT_RING(); /* Make sure we restore the 3D state next time. @@ -1288,17 +1268,17 @@ static int r128_cce_clear( DRM_IOCTL_ARGS ) return 0; } -static int r128_do_init_pageflip( drm_device_t *dev ) +static int r128_do_init_pageflip(drm_device_t * dev) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); - dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); + dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET); + dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL); - R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); - R128_WRITE( R128_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); + R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset); + R128_WRITE(R128_CRTC_OFFSET_CNTL, + dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL); dev_priv->page_flipping = 1; dev_priv->current_page = 0; @@ -1307,16 +1287,16 @@ static int r128_do_init_pageflip( drm_device_t *dev ) return 0; } -static int r128_do_cleanup_pageflip( drm_device_t *dev ) +static int r128_do_cleanup_pageflip(drm_device_t * dev) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); - R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); + R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset); + R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl); if (dev_priv->current_page != 0) { - r128_cce_dispatch_flip( dev ); + r128_cce_dispatch_flip(dev); COMMIT_RING(); } @@ -1325,43 +1305,43 @@ static int r128_do_cleanup_pageflip( drm_device_t *dev ) } /* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. + * They can & should be intermixed to support multiple 3d windows. */ -static int r128_cce_flip( DRM_IOCTL_ARGS ) +static int r128_cce_flip(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if (!dev_priv->page_flipping) - r128_do_init_pageflip( dev ); + if (!dev_priv->page_flipping) + r128_do_init_pageflip(dev); - r128_cce_dispatch_flip( dev ); + r128_cce_dispatch_flip(dev); COMMIT_RING(); return 0; } -static int r128_cce_swap( DRM_IOCTL_ARGS ) +static int r128_cce_swap(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - r128_cce_dispatch_swap( dev ); + r128_cce_dispatch_swap(dev); dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS); @@ -1369,7 +1349,7 @@ static int r128_cce_swap( DRM_IOCTL_ARGS ) return 0; } -static int r128_cce_vertex( DRM_IOCTL_ARGS ) +static int r128_cce_vertex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; @@ -1378,44 +1358,43 @@ static int r128_cce_vertex( DRM_IOCTL_ARGS ) drm_r128_buf_priv_t *buf_priv; drm_r128_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t __user *) data, - sizeof(vertex) ); + DRM_COPY_FROM_USER_IOCTL(vertex, (drm_r128_vertex_t __user *) data, + sizeof(vertex)); - DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, - vertex.idx, vertex.count, vertex.discard ); + DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard); - if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1 ); + if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - if ( vertex.prim < 0 || - vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { - DRM_ERROR( "buffer prim %d\n", vertex.prim ); + if (vertex.prim < 0 || + vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { + DRM_ERROR("buffer prim %d\n", vertex.prim); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", vertex.idx); return DRM_ERR(EINVAL); } @@ -1423,13 +1402,13 @@ static int r128_cce_vertex( DRM_IOCTL_ARGS ) buf_priv->prim = vertex.prim; buf_priv->discard = vertex.discard; - r128_cce_dispatch_vertex( dev, buf ); + r128_cce_dispatch_vertex(dev, buf); COMMIT_RING(); return 0; } -static int r128_cce_indices( DRM_IOCTL_ARGS ) +static int r128_cce_indices(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; @@ -1439,55 +1418,54 @@ static int r128_cce_indices( DRM_IOCTL_ARGS ) drm_r128_indices_t elts; int count; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t __user *) data, - sizeof(elts) ); + DRM_COPY_FROM_USER_IOCTL(elts, (drm_r128_indices_t __user *) data, + sizeof(elts)); - DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, - elts.idx, elts.start, elts.end, elts.discard ); + DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, + elts.idx, elts.start, elts.end, elts.discard); - if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - elts.idx, dma->buf_count - 1 ); + if (elts.idx < 0 || elts.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + elts.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - if ( elts.prim < 0 || - elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { - DRM_ERROR( "buffer prim %d\n", elts.prim ); + if (elts.prim < 0 || elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { + DRM_ERROR("buffer prim %d\n", elts.prim); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", elts.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", elts.idx); return DRM_ERR(EINVAL); } count = (elts.end - elts.start) / sizeof(u16); elts.start -= R128_INDEX_PRIM_OFFSET; - if ( elts.start & 0x7 ) { - DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + if (elts.start & 0x7) { + DRM_ERROR("misaligned buffer 0x%x\n", elts.start); return DRM_ERR(EINVAL); } - if ( elts.start < buf->used ) { - DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); + if (elts.start < buf->used) { + DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used); return DRM_ERR(EINVAL); } @@ -1495,13 +1473,13 @@ static int r128_cce_indices( DRM_IOCTL_ARGS ) buf_priv->prim = elts.prim; buf_priv->discard = elts.discard; - r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); + r128_cce_dispatch_indices(dev, buf, elts.start, elts.end, count); COMMIT_RING(); return 0; } -static int r128_cce_blit( DRM_IOCTL_ARGS ) +static int r128_cce_blit(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_device_dma_t *dma = dev->dma; @@ -1509,55 +1487,55 @@ static int r128_cce_blit( DRM_IOCTL_ARGS ) drm_r128_blit_t blit; int ret; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t __user *) data, - sizeof(blit) ); + DRM_COPY_FROM_USER_IOCTL(blit, (drm_r128_blit_t __user *) data, + sizeof(blit)); - DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx ); + DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit.idx); - if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - blit.idx, dma->buf_count - 1 ); + if (blit.idx < 0 || blit.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + blit.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); - ret = r128_cce_dispatch_blit( filp, dev, &blit ); + ret = r128_cce_dispatch_blit(filp, dev, &blit); COMMIT_RING(); return ret; } -static int r128_cce_depth( DRM_IOCTL_ARGS ) +static int r128_cce_depth(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; int ret; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t __user *) data, - sizeof(depth) ); + DRM_COPY_FROM_USER_IOCTL(depth, (drm_r128_depth_t __user *) data, + sizeof(depth)); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); ret = DRM_ERR(EINVAL); - switch ( depth.func ) { + switch (depth.func) { case R128_WRITE_SPAN: - ret = r128_cce_dispatch_write_span( dev, &depth ); + ret = r128_cce_dispatch_write_span(dev, &depth); break; case R128_WRITE_PIXELS: - ret = r128_cce_dispatch_write_pixels( dev, &depth ); + ret = r128_cce_dispatch_write_pixels(dev, &depth); break; case R128_READ_SPAN: - ret = r128_cce_dispatch_read_span( dev, &depth ); + ret = r128_cce_dispatch_read_span(dev, &depth); break; case R128_READ_PIXELS: - ret = r128_cce_dispatch_read_pixels( dev, &depth ); + ret = r128_cce_dispatch_read_pixels(dev, &depth); break; } @@ -1565,31 +1543,30 @@ static int r128_cce_depth( DRM_IOCTL_ARGS ) return ret; } -static int r128_cce_stipple( DRM_IOCTL_ARGS ) +static int r128_cce_stipple(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t __user *) data, - sizeof(stipple) ); + DRM_COPY_FROM_USER_IOCTL(stipple, (drm_r128_stipple_t __user *) data, + sizeof(stipple)); - if ( DRM_COPY_FROM_USER( &mask, stipple.mask, - 32 * sizeof(u32) ) ) - return DRM_ERR( EFAULT ); + if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32))) + return DRM_ERR(EFAULT); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - r128_cce_dispatch_stipple( dev, mask ); + r128_cce_dispatch_stipple(dev, mask); COMMIT_RING(); return 0; } -static int r128_cce_indirect( DRM_IOCTL_ARGS ) +static int r128_cce_indirect(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; @@ -1601,47 +1578,46 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS ) RING_LOCALS; #endif - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t __user *) data, - sizeof(indirect) ); + DRM_COPY_FROM_USER_IOCTL(indirect, (drm_r128_indirect_t __user *) data, + sizeof(indirect)); - DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", - indirect.idx, indirect.start, - indirect.end, indirect.discard ); + DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, indirect.end, indirect.discard); - if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - indirect.idx, dma->buf_count - 1 ); + if (indirect.idx < 0 || indirect.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } buf = dma->buflist[indirect.idx]; buf_priv = buf->dev_private; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", indirect.idx); return DRM_ERR(EINVAL); } - if ( indirect.start < buf->used ) { - DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", - indirect.start, buf->used ); + if (indirect.start < buf->used) { + DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf->used = indirect.end; buf_priv->discard = indirect.discard; @@ -1650,7 +1626,7 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS ) /* Wait for the 3D stream to idle before the indirect buffer * containing 2D acceleration commands is processed. */ - BEGIN_RING( 2 ); + BEGIN_RING(2); RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); #endif @@ -1659,30 +1635,30 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS ) * X server. This is insecure and is thus only available to * privileged clients. */ - r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + r128_cce_dispatch_indirect(dev, buf, indirect.start, indirect.end); COMMIT_RING(); return 0; } -static int r128_getparam( DRM_IOCTL_ARGS ) +static int r128_getparam(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_getparam_t param; int value; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t __user *)data, - sizeof(param) ); + DRM_COPY_FROM_USER_IOCTL(param, (drm_r128_getparam_t __user *) data, + sizeof(param)); - DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch( param.param ) { + switch (param.param) { case R128_PARAM_IRQ_NR: value = dev->irq; break; @@ -1690,47 +1666,47 @@ static int r128_getparam( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } - if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } - + return 0; } -void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp) +void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) { - if ( dev->dev_private ) { + if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; - if ( dev_priv->page_flipping ) { - r128_do_cleanup_pageflip( dev ); + if (dev_priv->page_flipping) { + r128_do_cleanup_pageflip(dev); } - } + } } -void r128_driver_pretakedown(drm_device_t *dev) +void r128_driver_pretakedown(drm_device_t * dev) { - r128_do_cleanup_cce( dev ); + r128_do_cleanup_cce(dev); } drm_ioctl_desc_t r128_ioctls[] = { - [DRM_IOCTL_NR(DRM_R128_INIT)] = { r128_cce_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_R128_CCE_START)] = { r128_cce_start, 1, 1 }, - [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, - [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, - [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_RESET)] = { r128_engine_reset, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_SWAP)] = { r128_cce_swap, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_FLIP)] = { r128_cce_flip, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_INDICES)] = { r128_cce_indices, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_BLIT)] = { r128_cce_blit, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, - [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, - [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = { r128_getparam, 1, 0 }, + [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0}, }; int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 623f1f460cb5..aa66f46279e7 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c @@ -37,7 +37,6 @@ #include "radeon_drv.h" #include "r300_reg.h" - #define R300_SIMULTANEOUS_CLIPRECTS 4 /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects @@ -49,14 +48,12 @@ static const int r300_cliprect_cntl[4] = { 0xFFFE }; - /** * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command * buffer, starting with index n. */ -static int r300_emit_cliprects(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, - int n) +static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf, int n) { drm_clip_rect_t box; int nr; @@ -70,38 +67,47 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv, DRM_DEBUG("%i cliprects\n", nr); if (nr) { - BEGIN_RING(6 + nr*2); - OUT_RING( CP_PACKET0( R300_RE_CLIPRECT_TL_0, nr*2 - 1 ) ); + BEGIN_RING(6 + nr * 2); + OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); - for(i = 0; i < nr; ++i) { - if (DRM_COPY_FROM_USER_UNCHECKED(&box, &cmdbuf->boxes[n+i], sizeof(box))) { + for (i = 0; i < nr; ++i) { + if (DRM_COPY_FROM_USER_UNCHECKED + (&box, &cmdbuf->boxes[n + i], sizeof(box))) { DRM_ERROR("copy cliprect faulted\n"); return DRM_ERR(EFAULT); } - box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; - box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; - box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; - box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; + box.x1 = + (box.x1 + + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; + box.y1 = + (box.y1 + + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; + box.x2 = + (box.x2 + + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; + box.y2 = + (box.y2 + + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK; OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) | - (box.y1 << R300_CLIPRECT_Y_SHIFT)); + (box.y1 << R300_CLIPRECT_Y_SHIFT)); OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) | - (box.y2 << R300_CLIPRECT_Y_SHIFT)); + (box.y2 << R300_CLIPRECT_Y_SHIFT)); } - OUT_RING_REG( R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr-1] ); + OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]); /* TODO/SECURITY: Force scissors to a safe value, otherwise the - * client might be able to trample over memory. - * The impact should be very limited, but I'd rather be safe than - * sorry. - */ - OUT_RING( CP_PACKET0( R300_RE_SCISSORS_TL, 1 ) ); - OUT_RING( 0 ); - OUT_RING( R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK ); + * client might be able to trample over memory. + * The impact should be very limited, but I'd rather be safe than + * sorry. + */ + OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1)); + OUT_RING(0); + OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK); ADVANCE_RING(); - } else { + } else { /* Why we allow zero cliprect rendering: * There are some commands in a command buffer that must be submitted * even when there are no cliprects, e.g. DMA buffer discard @@ -118,28 +124,27 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv, * can't produce any fragments. */ BEGIN_RING(2); - OUT_RING_REG( R300_RE_CLIPRECT_CNTL, 0 ); + OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0); ADVANCE_RING(); - } + } return 0; } -u8 r300_reg_flags[0x10000>>2]; - +u8 r300_reg_flags[0x10000 >> 2]; void r300_init_reg_flags(void) { int i; - memset(r300_reg_flags, 0, 0x10000>>2); - #define ADD_RANGE_MARK(reg, count,mark) \ + memset(r300_reg_flags, 0, 0x10000 >> 2); +#define ADD_RANGE_MARK(reg, count,mark) \ for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ r300_reg_flags[i]|=(mark); - - #define MARK_SAFE 1 - #define MARK_CHECK_OFFSET 2 - - #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) + +#define MARK_SAFE 1 +#define MARK_CHECK_OFFSET 2 + +#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */ ADD_RANGE(R300_SE_VPORT_XSCALE, 6); @@ -193,15 +198,15 @@ void r300_init_reg_flags(void) ADD_RANGE(R300_RB3D_CBLEND, 2); ADD_RANGE(R300_RB3D_COLORMASK, 1); ADD_RANGE(0x4E10, 3); - ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */ + ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */ ADD_RANGE(R300_RB3D_COLORPITCH0, 1); ADD_RANGE(0x4E50, 9); ADD_RANGE(0x4E88, 1); ADD_RANGE(0x4EA0, 2); ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3); ADD_RANGE(0x4F10, 4); - ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ - ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); + ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ + ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); ADD_RANGE(0x4F28, 1); ADD_RANGE(0x4F30, 2); ADD_RANGE(0x4F44, 1); @@ -211,7 +216,7 @@ void r300_init_reg_flags(void) ADD_RANGE(R300_TX_UNK1_0, 16); ADD_RANGE(R300_TX_SIZE_0, 16); ADD_RANGE(R300_TX_FORMAT_0, 16); - /* Texture offset is dangerous and needs more checking */ + /* Texture offset is dangerous and needs more checking */ ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); ADD_RANGE(R300_TX_UNK4_0, 16); ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); @@ -224,33 +229,41 @@ void r300_init_reg_flags(void) } -static __inline__ int r300_check_range(unsigned reg, int count) +static __inline__ int r300_check_range(unsigned reg, int count) { int i; - if(reg & ~0xffff)return -1; - for(i=(reg>>2);i<(reg>>2)+count;i++) - if(r300_reg_flags[i]!=MARK_SAFE)return 1; + if (reg & ~0xffff) + return -1; + for (i = (reg >> 2); i < (reg >> 2) + count; i++) + if (r300_reg_flags[i] != MARK_SAFE) + return 1; return 0; } /* we expect offsets passed to the framebuffer to be either within video memory or - within AGP space */ -static __inline__ int r300_check_offset(drm_radeon_private_t* dev_priv, u32 offset) + within AGP space */ +static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv, + u32 offset) { /* we realy want to check against end of video aperture - but this value is not being kept. - This code is correct for now (does the same thing as the - code that sets MC_FB_LOCATION) in radeon_cp.c */ - if((offset>=dev_priv->fb_location) && - (offsetgart_vm_start))return 0; - if((offset>=dev_priv->gart_vm_start) && - (offsetgart_vm_start+dev_priv->gart_size))return 0; + but this value is not being kept. + This code is correct for now (does the same thing as the + code that sets MC_FB_LOCATION) in radeon_cp.c */ + if ((offset >= dev_priv->fb_location) && + (offset < dev_priv->gart_vm_start)) + return 0; + if ((offset >= dev_priv->gart_vm_start) && + (offset < dev_priv->gart_vm_start + dev_priv->gart_size)) + return 0; return 1; } -static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, - drm_r300_cmd_header_t header) +static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * + dev_priv, + drm_radeon_cmd_buffer_t + * cmdbuf, + drm_r300_cmd_header_t + header) { int reg; int sz; @@ -260,35 +273,40 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* sz = header.packet0.count; reg = (header.packet0.reghi << 8) | header.packet0.reglo; - - if((sz>64)||(sz<0)){ - DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz); + + if ((sz > 64) || (sz < 0)) { + DRM_ERROR + ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", + reg, sz); return DRM_ERR(EINVAL); - } - for(i=0;ibuf)[i]; - switch(r300_reg_flags[(reg>>2)+i]){ + } + for (i = 0; i < sz; i++) { + values[i] = ((int __user *)cmdbuf->buf)[i]; + switch (r300_reg_flags[(reg >> 2) + i]) { case MARK_SAFE: break; case MARK_CHECK_OFFSET: - if(r300_check_offset(dev_priv, (u32)values[i])){ - DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", reg, sz); + if (r300_check_offset(dev_priv, (u32) values[i])) { + DRM_ERROR + ("Offset failed range check (reg=%04x sz=%d)\n", + reg, sz); return DRM_ERR(EINVAL); - } + } break; default: - DRM_ERROR("Register %04x failed check as flag=%02x\n", reg+i*4, r300_reg_flags[(reg>>2)+i]); + DRM_ERROR("Register %04x failed check as flag=%02x\n", + reg + i * 4, r300_reg_flags[(reg >> 2) + i]); return DRM_ERR(EINVAL); - } } - - BEGIN_RING(1+sz); - OUT_RING( CP_PACKET0( reg, sz-1 ) ); - OUT_RING_TABLE( values, sz ); + } + + BEGIN_RING(1 + sz); + OUT_RING(CP_PACKET0(reg, sz - 1)); + OUT_RING_TABLE(values, sz); ADVANCE_RING(); - cmdbuf->buf += sz*4; - cmdbuf->bufsz -= sz*4; + cmdbuf->buf += sz * 4; + cmdbuf->bufsz -= sz * 4; return 0; } @@ -299,9 +317,9 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* * * Note that checks are performed on contents and addresses of the registers */ -static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, - drm_r300_cmd_header_t header) +static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf, + drm_r300_cmd_header_t header) { int reg; int sz; @@ -313,39 +331,40 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv, if (!sz) return 0; - if (sz*4 > cmdbuf->bufsz) + if (sz * 4 > cmdbuf->bufsz) return DRM_ERR(EINVAL); - - if (reg+sz*4 >= 0x10000){ - DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz); - return DRM_ERR(EINVAL); - } - if(r300_check_range(reg, sz)){ + if (reg + sz * 4 >= 0x10000) { + DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, + sz); + return DRM_ERR(EINVAL); + } + + if (r300_check_range(reg, sz)) { /* go and check everything */ - return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, header); - } + return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, + header); + } /* the rest of the data is safe to emit, whatever the values the user passed */ - BEGIN_RING(1+sz); - OUT_RING( CP_PACKET0( reg, sz-1 ) ); - OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz ); + BEGIN_RING(1 + sz); + OUT_RING(CP_PACKET0(reg, sz - 1)); + OUT_RING_TABLE((int __user *)cmdbuf->buf, sz); ADVANCE_RING(); - cmdbuf->buf += sz*4; - cmdbuf->bufsz -= sz*4; + cmdbuf->buf += sz * 4; + cmdbuf->bufsz -= sz * 4; return 0; } - /** * Uploads user-supplied vertex program instructions or parameters onto * the graphics card. * Called by r300_do_cp_cmdbuf. */ -static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, +static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int sz; @@ -357,114 +376,121 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv, if (!sz) return 0; - if (sz*16 > cmdbuf->bufsz) + if (sz * 16 > cmdbuf->bufsz) return DRM_ERR(EINVAL); - BEGIN_RING(5+sz*4); + BEGIN_RING(5 + sz * 4); /* Wait for VAP to come to senses.. */ /* there is no need to emit it multiple times, (only once before VAP is programmed, but this optimization is for later */ - OUT_RING_REG( R300_VAP_PVS_WAITIDLE, 0 ); - OUT_RING_REG( R300_VAP_PVS_UPLOAD_ADDRESS, addr ); - OUT_RING( CP_PACKET0_TABLE( R300_VAP_PVS_UPLOAD_DATA, sz*4 - 1 ) ); - OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz*4 ); + OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0); + OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); + OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); + OUT_RING_TABLE((int __user *)cmdbuf->buf, sz * 4); ADVANCE_RING(); - cmdbuf->buf += sz*16; - cmdbuf->bufsz -= sz*16; + cmdbuf->buf += sz * 16; + cmdbuf->bufsz -= sz * 16; return 0; } - /** * Emit a clear packet from userspace. * Called by r300_emit_packet3. */ -static __inline__ int r300_emit_clear(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf) +static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf) { RING_LOCALS; - if (8*4 > cmdbuf->bufsz) + if (8 * 4 > cmdbuf->bufsz) return DRM_ERR(EINVAL); BEGIN_RING(10); - OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 8 ) ); - OUT_RING( R300_PRIM_TYPE_POINT|R300_PRIM_WALK_RING| - (1<buf, 8 ); + OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); + OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | + (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + OUT_RING_TABLE((int __user *)cmdbuf->buf, 8); ADVANCE_RING(); - cmdbuf->buf += 8*4; - cmdbuf->bufsz -= 8*4; + cmdbuf->buf += 8 * 4; + cmdbuf->bufsz -= 8 * 4; return 0; } -static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, - u32 header) +static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf, + u32 header) { - int count, i,k; - #define MAX_ARRAY_PACKET 64 + int count, i, k; +#define MAX_ARRAY_PACKET 64 u32 payload[MAX_ARRAY_PACKET]; u32 narrays; RING_LOCALS; - count=(header>>16) & 0x3fff; - - if((count+1)>MAX_ARRAY_PACKET){ - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count); + count = (header >> 16) & 0x3fff; + + if ((count + 1) > MAX_ARRAY_PACKET) { + DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", + count); return DRM_ERR(EINVAL); - } - memset(payload, 0, MAX_ARRAY_PACKET*4); - memcpy(payload, cmdbuf->buf+4, (count+1)*4); - + } + memset(payload, 0, MAX_ARRAY_PACKET * 4); + memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4); + /* carefully check packet contents */ - - narrays=payload[0]; - k=0; - i=1; - while((kbuf += (count+2)*4; - cmdbuf->bufsz -= (count+2)*4; + cmdbuf->buf += (count + 2) * 4; + cmdbuf->bufsz -= (count + 2) * 4; return 0; } -static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf) +static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf) { u32 header; int count; @@ -473,36 +499,37 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv, if (4 > cmdbuf->bufsz) return DRM_ERR(EINVAL); - /* Fixme !! This simply emits a packet without much checking. + /* Fixme !! This simply emits a packet without much checking. We need to be smarter. */ /* obtain first word - actual packet3 header */ - header = *(u32 __user*)cmdbuf->buf; + header = *(u32 __user *) cmdbuf->buf; /* Is it packet 3 ? */ - if( (header>>30)!=0x3 ) { + if ((header >> 30) != 0x3) { DRM_ERROR("Not a packet3 header (0x%08x)\n", header); return DRM_ERR(EINVAL); - } + } - count=(header>>16) & 0x3fff; + count = (header >> 16) & 0x3fff; /* Check again now that we know how much data to expect */ - if ((count+2)*4 > cmdbuf->bufsz){ - DRM_ERROR("Expected packet3 of length %d but have only %d bytes left\n", - (count+2)*4, cmdbuf->bufsz); + if ((count + 2) * 4 > cmdbuf->bufsz) { + DRM_ERROR + ("Expected packet3 of length %d but have only %d bytes left\n", + (count + 2) * 4, cmdbuf->bufsz); return DRM_ERR(EINVAL); - } + } /* Is it a packet type we know about ? */ - switch(header & 0xff00){ - case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ + switch (header & 0xff00) { + case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); - case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ - case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ - case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ - case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ + case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ + case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ + case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ + case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ case RADEON_WAIT_FOR_IDLE: case RADEON_CP_NOP: /* these packets are safe */ @@ -510,32 +537,30 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv, default: DRM_ERROR("Unknown packet3 header (0x%08x)\n", header); return DRM_ERR(EINVAL); - } + } - - BEGIN_RING(count+2); + BEGIN_RING(count + 2); OUT_RING(header); - OUT_RING_TABLE( (int __user*)(cmdbuf->buf+4), count+1); + OUT_RING_TABLE((int __user *)(cmdbuf->buf + 4), count + 1); ADVANCE_RING(); - cmdbuf->buf += (count+2)*4; - cmdbuf->bufsz -= (count+2)*4; + cmdbuf->buf += (count + 2) * 4; + cmdbuf->bufsz -= (count + 2) * 4; return 0; } - /** * Emit a rendering packet3 from userspace. * Called by r300_do_cp_cmdbuf. */ -static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv, - drm_radeon_cmd_buffer_t* cmdbuf, +static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int n; int ret; - char __user* orig_buf = cmdbuf->buf; + char __user *orig_buf = cmdbuf->buf; int orig_bufsz = cmdbuf->bufsz; /* This is a do-while-loop so that we run the interior at least once, @@ -550,16 +575,16 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv, cmdbuf->buf = orig_buf; cmdbuf->bufsz = orig_bufsz; - } + } - switch(header.packet3.packet) { + switch (header.packet3.packet) { case R300_CMD_PACKET3_CLEAR: DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n"); ret = r300_emit_clear(dev_priv, cmdbuf); if (ret) { DRM_ERROR("r300_emit_clear failed\n"); return ret; - } + } break; case R300_CMD_PACKET3_RAW: @@ -568,18 +593,18 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv, if (ret) { DRM_ERROR("r300_emit_raw_packet3 failed\n"); return ret; - } + } break; default: DRM_ERROR("bad packet3 type %i at %p\n", - header.packet3.packet, - cmdbuf->buf - sizeof(header)); + header.packet3.packet, + cmdbuf->buf - sizeof(header)); return DRM_ERR(EINVAL); - } + } n += R300_SIMULTANEOUS_CLIPRECTS; - } while(n < cmdbuf->nbox); + } while (n < cmdbuf->nbox); return 0; } @@ -598,21 +623,20 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv, /** * Emit the sequence to pacify R300. */ -static __inline__ void r300_pacify(drm_radeon_private_t* dev_priv) +static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv) { RING_LOCALS; BEGIN_RING(6); - OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); - OUT_RING( 0xa ); - OUT_RING( CP_PACKET0( 0x4f18, 0 ) ); - OUT_RING( 0x3 ); - OUT_RING( CP_PACKET3( RADEON_CP_NOP, 0 ) ); - OUT_RING( 0x0 ); + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + OUT_RING(0xa); + OUT_RING(CP_PACKET0(0x4f18, 0)); + OUT_RING(0x3); + OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); + OUT_RING(0x0); ADVANCE_RING(); } - /** * Called by r300_do_cp_cmdbuf to update the internal buffer age and state. * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must @@ -628,20 +652,18 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) buf->used = 0; } - /** * Parses and validates a user-supplied command buffer and emits appropriate * commands on the DMA ring buffer. * Called by the ioctl handler function radeon_cp_cmdbuf. */ -int r300_do_cp_cmdbuf(drm_device_t* dev, - DRMFILE filp, - drm_file_t* filp_priv, - drm_radeon_cmd_buffer_t* cmdbuf) +int r300_do_cp_cmdbuf(drm_device_t * dev, + DRMFILE filp, + drm_file_t * filp_priv, drm_radeon_cmd_buffer_t * cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = NULL; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = NULL; int emit_dispatch_age = 0; int ret = 0; @@ -655,9 +677,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, ret = r300_emit_cliprects(dev_priv, cmdbuf, 0); if (ret) goto cleanup; - } + } - while(cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) { + while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) { int idx; drm_r300_cmd_header_t header; @@ -666,14 +688,14 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, cmdbuf->buf += sizeof(header); cmdbuf->bufsz -= sizeof(header); - switch(header.header.cmd_type) { - case R300_CMD_PACKET0: + switch (header.header.cmd_type) { + case R300_CMD_PACKET0: DRM_DEBUG("R300_CMD_PACKET0\n"); ret = r300_emit_packet0(dev_priv, cmdbuf, header); if (ret) { DRM_ERROR("r300_emit_packet0 failed\n"); goto cleanup; - } + } break; case R300_CMD_VPU: @@ -682,7 +704,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, if (ret) { DRM_ERROR("r300_emit_vpu failed\n"); goto cleanup; - } + } break; case R300_CMD_PACKET3: @@ -691,26 +713,26 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, if (ret) { DRM_ERROR("r300_emit_packet3 failed\n"); goto cleanup; - } + } break; case R300_CMD_END3D: DRM_DEBUG("R300_CMD_END3D\n"); - /* TODO: - Ideally userspace driver should not need to issue this call, - i.e. the drm driver should issue it automatically and prevent - lockups. - - In practice, we do not understand why this call is needed and what - it does (except for some vague guesses that it has to do with cache - coherence) and so the user space driver does it. - - Once we are sure which uses prevent lockups the code could be moved - into the kernel and the userspace driver will not - need to use this command. + /* TODO: + Ideally userspace driver should not need to issue this call, + i.e. the drm driver should issue it automatically and prevent + lockups. - Note that issuing this command does not hurt anything - except, possibly, performance */ + In practice, we do not understand why this call is needed and what + it does (except for some vague guesses that it has to do with cache + coherence) and so the user space driver does it. + + Once we are sure which uses prevent lockups the code could be moved + into the kernel and the userspace driver will not + need to use this command. + + Note that issuing this command does not hurt anything + except, possibly, performance */ r300_pacify(dev_priv); break; @@ -722,7 +744,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, RING_LOCALS; BEGIN_RING(header.delay.count); - for(i=0;i= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - idx, dma->buf_count - 1); + idx = header.dma.buf_idx; + if (idx < 0 || idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + idx, dma->buf_count - 1); ret = DRM_ERR(EINVAL); - goto cleanup; - } - - buf = dma->buflist[idx]; - if (buf->filp != filp || buf->pending) { - DRM_ERROR("bad buffer %p %p %d\n", - buf->filp, filp, buf->pending); - ret = DRM_ERR(EINVAL); goto cleanup; - } + } + + buf = dma->buflist[idx]; + if (buf->filp != filp || buf->pending) { + DRM_ERROR("bad buffer %p %p %d\n", + buf->filp, filp, buf->pending); + ret = DRM_ERR(EINVAL); + goto cleanup; + } emit_dispatch_age = 1; r300_discard_buffer(dev, buf); - break; + break; case R300_CMD_WAIT: /* simple enough, we can do it here */ DRM_DEBUG("R300_CMD_WAIT\n"); - if(header.wait.flags==0)break; /* nothing to do */ + if (header.wait.flags == 0) + break; /* nothing to do */ { RING_LOCALS; BEGIN_RING(2); - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); - OUT_RING( (header.wait.flags & 0xf)<<14 ); + OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); + OUT_RING((header.wait.flags & 0xf) << 14); ADVANCE_RING(); } break; default: DRM_ERROR("bad cmd_type %i at %p\n", - header.header.cmd_type, + header.header.cmd_type, cmdbuf->buf - sizeof(header)); ret = DRM_ERR(EINVAL); goto cleanup; - } + } } DRM_DEBUG("END\n"); -cleanup: + cleanup: r300_pacify(dev_priv); /* We emit the vertex buffer age here, outside the pacifier "brackets" @@ -792,10 +815,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev, BEGIN_RING(2); RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch); ADVANCE_RING(); - } + } COMMIT_RING(); return ret; } - diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h index c3e7ca3dbe3d..e5b73c002394 100644 --- a/drivers/char/drm/r300_reg.h +++ b/drivers/char/drm/r300_reg.h @@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24 # define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28 - #define R300_MC_INIT_GFX_LAT_TIMER 0x154 # define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0 # define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4 @@ -62,7 +61,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_SE_VPORT_ZSCALE 0x1DA8 #define R300_SE_VPORT_ZOFFSET 0x1DAC - /* This register is written directly and also starts data section in many 3d CP_PACKET3's */ #define R300_VAP_VF_CNTL 0x2084 @@ -93,17 +91,17 @@ I am fairly certain that they are correct unless stated otherwise in comments. /* index size - when not set the indices are assumed to be 16 bit */ # define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11) - /* number of vertices */ + /* number of vertices */ # define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 /* BEGIN: Wild guesses */ #define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 # define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) # define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1) -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ #define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 @@ -159,14 +157,14 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0) # define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0) # define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ +# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ # define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8 -# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ +# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ # define R300_VAP_INPUT_ROUTE_END (1 << 13) -# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ #define R300_VAP_INPUT_ROUTE_0_1 0x2154 #define R300_VAP_INPUT_ROUTE_0_2 0x2158 #define R300_VAP_INPUT_ROUTE_0_3 0x215C @@ -188,12 +186,12 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_INPUT_CNTL_COLOR 0x00000004 # define R300_INPUT_CNTL_TC0 0x00000400 # define R300_INPUT_CNTL_TC1 0x00000800 -# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ -# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ -# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ -# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ -# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ -# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ +# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ +# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ +# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ +# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ +# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ +# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ /* gap */ /* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0 @@ -270,12 +268,12 @@ I am fairly certain that they are correct unless stated otherwise in comments. // rendering commands and overwriting vertex program parameters. // Therefore, I suspect writing zero to 0x2284 synchronizes the engine and // avoids bugs caused by still running shaders reading bad data from memory. */ -#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */ +#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */ /* Absolutely no clue what this register is about. */ #define R300_VAP_UNKNOWN_2288 0x2288 -# define R300_2288_R300 0x00750000 /* -- nh */ -# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ +# define R300_2288_R300 0x00750000 /* -- nh */ +# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ /* gap */ /* Addresses are relative to the vertex program instruction area of the @@ -286,10 +284,10 @@ I am fairly certain that they are correct unless stated otherwise in comments. // experiments so far have shown that both *must* point to an instruction // inside the vertex program, otherwise the GPU locks up. // fglrx usually sets CNTL_3_UNKNOWN to the end of the program and -// CNTL_1_UNKNOWN points to instruction where last write to position takes place. +// CNTL_1_UNKNOWN points to instruction where last write to position takes place. // Most likely this is used to ignore rest of the program in cases where group of verts arent visible. // For some reason this "section" is sometimes accepted other instruction that have -// no relationship with position calculations. +// no relationship with position calculations. */ #define R300_VAP_PVS_CNTL_1 0x22D0 # define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 @@ -308,13 +306,13 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_VAP_VTX_COLOR_R 0x2464 #define R300_VAP_VTX_COLOR_G 0x2468 #define R300_VAP_VTX_COLOR_B 0x246C -#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ +#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ #define R300_VAP_VTX_POS_0_Y_1 0x2494 -#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ -#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ +#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ +#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ #define R300_VAP_VTX_POS_0_Y_2 0x24A4 #define R300_VAP_VTX_POS_0_Z_2 0x24A8 -#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */ +#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */ /* gap */ @@ -385,7 +383,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_GB_MSPOS1__MS_Y5_SHIFT 20 # define R300_GB_MSPOS1__MSBD1 24 - #define R300_GB_TILE_CONFIG 0x4018 # define R300_GB_TILE_ENABLE (1<<0) # define R300_GB_TILE_PIPE_COUNT_RV300 0 @@ -478,9 +475,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. // framebuffer. */ #define R300_RE_POINTSIZE 0x421C # define R300_POINTSIZE_Y_SHIFT 0 -# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */ +# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */ # define R300_POINTSIZE_X_SHIFT 16 -# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */ +# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */ # define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) /* The line width is given in multiples of 6. @@ -491,7 +488,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. */ #define R300_RE_LINE_CNT 0x4234 # define R300_LINESIZE_SHIFT 0 -# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ +# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ # define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6) # define R300_LINE_CNT_HO (1 << 16) # define R300_LINE_CNT_VE (1 << 17) @@ -513,8 +510,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_PM_BACK_LINE (1 << 7) # define R300_PM_BACK_FILL (1 << 8) -/* Not sure why there are duplicate of factor and constant values. - My best guess so far is that there are seperate zbiases for test and write. +/* Not sure why there are duplicate of factor and constant values. + My best guess so far is that there are seperate zbiases for test and write. Ordering might be wrong. Some of the tests indicate that fgl has a fallback implementation of zbias via pixel shaders. */ @@ -540,7 +537,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FRONT_FACE_CCW (0 << 2) # define R300_FRONT_FACE_CW (1 << 2) - /* BEGIN: Rasterization / Interpolators - many guesses // 0_UNKNOWN_18 has always been set except for clear operations. // TC_CNT is the number of incoming texture coordinate sets (i.e. it depends @@ -548,7 +544,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_RS_CNTL_0 0x4300 # define R300_RS_CNTL_TC_CNT_SHIFT 2 # define R300_RS_CNTL_TC_CNT_MASK (7 << 2) -# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */ +# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */ # define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18) /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */ #define R300_RS_CNTL_1 0x4304 @@ -585,29 +581,29 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_RS_ROUTE_0 0x4330 #define R300_RS_ROUTE_1 0x4334 #define R300_RS_ROUTE_2 0x4338 -#define R300_RS_ROUTE_3 0x433C /* GUESS */ -#define R300_RS_ROUTE_4 0x4340 /* GUESS */ -#define R300_RS_ROUTE_5 0x4344 /* GUESS */ -#define R300_RS_ROUTE_6 0x4348 /* GUESS */ -#define R300_RS_ROUTE_7 0x434C /* GUESS */ +#define R300_RS_ROUTE_3 0x433C /* GUESS */ +#define R300_RS_ROUTE_4 0x4340 /* GUESS */ +#define R300_RS_ROUTE_5 0x4344 /* GUESS */ +#define R300_RS_ROUTE_6 0x4348 /* GUESS */ +#define R300_RS_ROUTE_7 0x434C /* GUESS */ # define R300_RS_ROUTE_SOURCE_INTERP_0 0 # define R300_RS_ROUTE_SOURCE_INTERP_1 1 # define R300_RS_ROUTE_SOURCE_INTERP_2 2 # define R300_RS_ROUTE_SOURCE_INTERP_3 3 # define R300_RS_ROUTE_SOURCE_INTERP_4 4 -# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ -# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ +# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ # define R300_RS_ROUTE_DEST_SHIFT 6 -# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ +# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ /* Special handling for color: When the fragment program uses color, // the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the // color register index. */ # define R300_RS_ROUTE_0_COLOR (1 << 14) # define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 -# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ +# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ /* As above, but for secondary color */ # define R300_RS_ROUTE_1_COLOR1 (1 << 14) # define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 @@ -721,7 +717,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_HEIGHTMASK_SHIFT 11 # define R300_TX_HEIGHTMASK_MASK (2047 << 11) # define R300_TX_UNK23 (1 << 23) -# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ +# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ # define R300_TX_SIZE_MASK (15 << 26) #define R300_TX_FORMAT_0 0x44C0 /* The interpretation of the format word by Wladimir van der Laan */ @@ -746,12 +742,12 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_DXT1 0xF # define R300_TX_FORMAT_DXT3 0x10 # define R300_TX_FORMAT_DXT5 0x11 -# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ -# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ -# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ -# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ +# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ +# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ +# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ +# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ /* 0x16 - some 16 bit green format.. ?? */ -# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ +# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ /* gap */ /* Floating point formats */ @@ -777,8 +773,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_W 3 # define R300_TX_FORMAT_ZERO 4 # define R300_TX_FORMAT_ONE 5 -# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */ -# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */ # define R300_TX_FORMAT_B_SHIFT 18 # define R300_TX_FORMAT_G_SHIFT 15 @@ -811,7 +807,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TXO_OFFSET_SHIFT 5 /* END */ #define R300_TX_UNK4_0 0x4580 -#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } +#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } /* END */ @@ -844,9 +840,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_PFS_CNTL_ALU_END_SHIFT 6 # define R300_PFS_CNTL_ALU_END_MASK (63 << 0) # define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12 -# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */ +# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */ # define R300_PFS_CNTL_TEX_END_SHIFT 18 -# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */ +# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */ /* gap */ /* Nodes are stored backwards. The last active node is always stored in @@ -877,11 +873,11 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_PFS_TEXI_0 0x4620 # define R300_FPITX_SRC_SHIFT 0 # define R300_FPITX_SRC_MASK (31 << 0) -# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */ +# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */ # define R300_FPITX_DST_SHIFT 6 # define R300_FPITX_DST_MASK (31 << 6) # define R300_FPITX_IMAGE_SHIFT 11 -# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */ +# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */ /* Unsure if these are opcodes, or some kind of bitfield, but this is how * they were set when I checked */ @@ -1003,7 +999,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FPI0_ARGC_SRC1C_LRP 15 # define R300_FPI0_ARGC_ZERO 20 # define R300_FPI0_ARGC_ONE 21 -# define R300_FPI0_ARGC_HALF 22 /* GUESS */ +# define R300_FPI0_ARGC_HALF 22 /* GUESS */ # define R300_FPI0_ARGC_SRC0C_YZX 23 # define R300_FPI0_ARGC_SRC1C_YZX 24 # define R300_FPI0_ARGC_SRC2C_YZX 25 @@ -1054,20 +1050,20 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FPI2_ARGA_SRC1A_LRP 15 # define R300_FPI2_ARGA_ZERO 16 # define R300_FPI2_ARGA_ONE 17 -# define R300_FPI2_ARGA_HALF 18 /* GUESS */ +# define R300_FPI2_ARGA_HALF 18 /* GUESS */ # define R300_FPI2_ARG0A_SHIFT 0 # define R300_FPI2_ARG0A_MASK (31 << 0) # define R300_FPI2_ARG0A_NEG (1 << 5) -# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */ +# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */ # define R300_FPI2_ARG1A_SHIFT 7 # define R300_FPI2_ARG1A_MASK (31 << 7) # define R300_FPI2_ARG1A_NEG (1 << 12) -# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */ +# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */ # define R300_FPI2_ARG2A_SHIFT 14 # define R300_FPI2_ARG2A_MASK (31 << 14) # define R300_FPI2_ARG2A_NEG (1 << 19) -# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */ +# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */ # define R300_FPI2_SPECIAL_LRP (1 << 21) # define R300_FPI2_OUTA_MAD (0 << 23) # define R300_FPI2_OUTA_DP4 (1 << 23) @@ -1157,26 +1153,26 @@ I am fairly certain that they are correct unless stated otherwise in comments. /* gap */ #define R300_RB3D_COLOROFFSET0 0x4E28 -# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ -#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ -#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ -#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ +# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ +#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ +#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ +#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ /* gap */ /* Bit 16: Larger tiles // Bit 17: 4x2 tiles // Bit 18: Extremely weird tile like, but some pixels duplicated? */ #define R300_RB3D_COLORPITCH0 0x4E38 -# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ -# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ -# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ -# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ +# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ +# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ +# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ +# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ +# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ +# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ # define R300_COLOR_FORMAT_RGB565 (2 << 22) # define R300_COLOR_FORMAT_ARGB8888 (3 << 22) -#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ -#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ -#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ +#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ +#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ +#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ /* gap */ /* Guess by Vladimir. @@ -1189,8 +1185,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. /* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */ /* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */ #define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00 -# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */ -# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */ +# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */ +# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */ # define R300_RB3D_Z_TEST 0x00000012 # define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 # define R300_RB3D_Z_WRITE_ONLY 0x00000006 @@ -1233,8 +1229,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21 # define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24 - - #define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08 # define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0 # define R300_RB3D_ZS2_STENCIL_MASK 0xFF @@ -1250,12 +1244,12 @@ I am fairly certain that they are correct unless stated otherwise in comments. /* gap */ #define R300_RB3D_DEPTHOFFSET 0x4F20 #define R300_RB3D_DEPTHPITCH 0x4F24 -# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ -# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */ -# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */ -# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ -# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ -# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ +# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ +# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */ +# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */ +# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ +# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ +# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ /* BEGIN: Vertex program instruction set // Every instruction is four dwords long: @@ -1295,26 +1289,26 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_VPI_OUT_OP_MIN (8 << 0) #define R300_VPI_OUT_OP_SGE (9 << 0) #define R300_VPI_OUT_OP_SLT (10 << 0) -#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ +#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ #define R300_VPI_OUT_OP_EXP (65 << 0) #define R300_VPI_OUT_OP_LOG (66 << 0) -#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */ +#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */ #define R300_VPI_OUT_OP_LIT (68 << 0) #define R300_VPI_OUT_OP_POW (69 << 0) #define R300_VPI_OUT_OP_RCP (70 << 0) #define R300_VPI_OUT_OP_RSQ (72 << 0) -#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ +#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ #define R300_VPI_OUT_OP_EX2 (75 << 0) #define R300_VPI_OUT_OP_LG2 (76 << 0) #define R300_VPI_OUT_OP_MAD_2 (128 << 0) -#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */ +#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */ #define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8) #define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8) #define R300_VPI_OUT_REG_CLASS_MASK (31 << 8) #define R300_VPI_OUT_REG_INDEX_SHIFT 13 -#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */ +#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */ #define R300_VPI_OUT_WRITE_X (1 << 20) #define R300_VPI_OUT_WRITE_Y (1 << 21) @@ -1325,10 +1319,10 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0) #define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0) #define R300_VPI_IN_REG_CLASS_NONE (9 << 0) -#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */ +#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */ #define R300_VPI_IN_REG_INDEX_SHIFT 5 -#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */ +#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */ /* The R300 can select components from the input register arbitrarily. // Use the following constants, shifted by the component shift you @@ -1366,7 +1360,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_PRIM_TYPE_RECT_LIST (8 << 0) #define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) #define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) -#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200) +#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200) #define R300_PRIM_TYPE_LINE_LOOP (12 << 0) #define R300_PRIM_TYPE_QUADS (13 << 0) #define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) @@ -1376,8 +1370,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. #define R300_PRIM_WALK_LIST (2 << 4) #define R300_PRIM_WALK_RING (3 << 4) #define R300_PRIM_WALK_MASK (3 << 4) -#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200) -#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS +#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200) +#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS #define R300_PRIM_NUM_VERTICES_SHIFT 16 // Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. @@ -1409,4 +1403,4 @@ I am fairly certain that they are correct unless stated otherwise in comments. //END -#endif /* _R300_REG_H */ +#endif /* _R300_REG_H */ diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 6dff5e43f713..447bfbe0da8a 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -36,788 +36,787 @@ #define RADEON_FIFO_DEBUG 0 -static int radeon_do_cleanup_cp( drm_device_t *dev ); +static int radeon_do_cleanup_cp(drm_device_t * dev); /* CP microcode (from ATI) */ static u32 R200_cp_microcode[][2] = { - { 0x21007000, 0000000000 }, - { 0x20007000, 0000000000 }, - { 0x000000ab, 0x00000004 }, - { 0x000000af, 0x00000004 }, - { 0x66544a49, 0000000000 }, - { 0x49494174, 0000000000 }, - { 0x54517d83, 0000000000 }, - { 0x498d8b64, 0000000000 }, - { 0x49494949, 0000000000 }, - { 0x49da493c, 0000000000 }, - { 0x49989898, 0000000000 }, - { 0xd34949d5, 0000000000 }, - { 0x9dc90e11, 0000000000 }, - { 0xce9b9b9b, 0000000000 }, - { 0x000f0000, 0x00000016 }, - { 0x352e232c, 0000000000 }, - { 0x00000013, 0x00000004 }, - { 0x000f0000, 0x00000016 }, - { 0x352e272c, 0000000000 }, - { 0x000f0001, 0x00000016 }, - { 0x3239362f, 0000000000 }, - { 0x000077ef, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00000016, 0x00000004 }, - { 0x0003802a, 0x00000002 }, - { 0x040067e0, 0x00000002 }, - { 0x00000016, 0x00000004 }, - { 0x000077e0, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x000037e1, 0x00000002 }, - { 0x040067e1, 0x00000006 }, - { 0x000077e0, 0x00000002 }, - { 0x000077e1, 0x00000002 }, - { 0x000077e1, 0x00000006 }, - { 0xffffffff, 0000000000 }, - { 0x10000000, 0000000000 }, - { 0x0003802a, 0x00000002 }, - { 0x040067e0, 0x00000006 }, - { 0x00007675, 0x00000002 }, - { 0x00007676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802b, 0x00000002 }, - { 0x04002676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0000002e, 0x00000018 }, - { 0x0000002e, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x0000002f, 0x00000018 }, - { 0x0000002f, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x01605000, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00098000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x64c0603d, 0x00000004 }, - { 0x00080000, 0x00000016 }, - { 0000000000, 0000000000 }, - { 0x0400251d, 0x00000002 }, - { 0x00007580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x04002580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x00000046, 0x00000004 }, - { 0x00005000, 0000000000 }, - { 0x00061000, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x00019000, 0x00000002 }, - { 0x00011055, 0x00000014 }, - { 0x00000055, 0x00000012 }, - { 0x0400250f, 0x00000002 }, - { 0x0000504a, 0x00000004 }, - { 0x00007565, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000051, 0x00000004 }, - { 0x01e655b4, 0x00000002 }, - { 0x4401b0dc, 0x00000002 }, - { 0x01c110dc, 0x00000002 }, - { 0x2666705d, 0x00000018 }, - { 0x040c2565, 0x00000002 }, - { 0x0000005d, 0x00000018 }, - { 0x04002564, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000054, 0x00000004 }, - { 0x00401060, 0x00000008 }, - { 0x00101000, 0x00000002 }, - { 0x000d80ff, 0x00000002 }, - { 0x00800063, 0x00000008 }, - { 0x000f9000, 0x00000002 }, - { 0x000e00ff, 0x00000002 }, - { 0000000000, 0x00000006 }, - { 0x00000080, 0x00000018 }, - { 0x00000054, 0x00000004 }, - { 0x00007576, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00009000, 0x00000002 }, - { 0x00041000, 0x00000002 }, - { 0x0c00350e, 0x00000002 }, - { 0x00049000, 0x00000002 }, - { 0x00051000, 0x00000002 }, - { 0x01e785f8, 0x00000002 }, - { 0x00200000, 0x00000002 }, - { 0x00600073, 0x0000000c }, - { 0x00007563, 0x00000002 }, - { 0x006075f0, 0x00000021 }, - { 0x20007068, 0x00000004 }, - { 0x00005068, 0x00000004 }, - { 0x00007576, 0x00000002 }, - { 0x00007577, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x0000750f, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00600076, 0x0000000c }, - { 0x006075f0, 0x00000021 }, - { 0x000075f8, 0x00000002 }, - { 0x00000076, 0x00000004 }, - { 0x000a750e, 0x00000002 }, - { 0x0020750f, 0x00000002 }, - { 0x00600079, 0x00000004 }, - { 0x00007570, 0x00000002 }, - { 0x00007571, 0x00000002 }, - { 0x00007572, 0x00000006 }, - { 0x00005000, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00007568, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000084, 0x0000000c }, - { 0x00058000, 0x00000002 }, - { 0x0c607562, 0x00000002 }, - { 0x00000086, 0x00000004 }, - { 0x00600085, 0x00000004 }, - { 0x400070dd, 0000000000 }, - { 0x000380dd, 0x00000002 }, - { 0x00000093, 0x0000001c }, - { 0x00065095, 0x00000018 }, - { 0x040025bb, 0x00000002 }, - { 0x00061096, 0x00000018 }, - { 0x040075bc, 0000000000 }, - { 0x000075bb, 0x00000002 }, - { 0x000075bc, 0000000000 }, - { 0x00090000, 0x00000006 }, - { 0x00090000, 0x00000002 }, - { 0x000d8002, 0x00000006 }, - { 0x00005000, 0x00000002 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x01665000, 0x00000002 }, - { 0x000a0000, 0x00000002 }, - { 0x000671cc, 0x00000002 }, - { 0x0286f1cd, 0x00000002 }, - { 0x000000a3, 0x00000010 }, - { 0x21007000, 0000000000 }, - { 0x000000aa, 0x0000001c }, - { 0x00065000, 0x00000002 }, - { 0x000a0000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x000b0000, 0x00000002 }, - { 0x38067000, 0x00000002 }, - { 0x000a00a6, 0x00000004 }, - { 0x20007000, 0000000000 }, - { 0x01200000, 0x00000002 }, - { 0x20077000, 0x00000002 }, - { 0x01200000, 0x00000002 }, - { 0x20007000, 0000000000 }, - { 0x00061000, 0x00000002 }, - { 0x0120751b, 0x00000002 }, - { 0x8040750a, 0x00000002 }, - { 0x8040750b, 0x00000002 }, - { 0x00110000, 0x00000002 }, - { 0x000380dd, 0x00000002 }, - { 0x000000bd, 0x0000001c }, - { 0x00061096, 0x00000018 }, - { 0x844075bd, 0x00000002 }, - { 0x00061095, 0x00000018 }, - { 0x840075bb, 0x00000002 }, - { 0x00061096, 0x00000018 }, - { 0x844075bc, 0x00000002 }, - { 0x000000c0, 0x00000004 }, - { 0x804075bd, 0x00000002 }, - { 0x800075bb, 0x00000002 }, - { 0x804075bc, 0x00000002 }, - { 0x00108000, 0x00000002 }, - { 0x01400000, 0x00000002 }, - { 0x006000c4, 0x0000000c }, - { 0x20c07000, 0x00000020 }, - { 0x000000c6, 0x00000012 }, - { 0x00800000, 0x00000006 }, - { 0x0080751d, 0x00000006 }, - { 0x000025bb, 0x00000002 }, - { 0x000040c0, 0x00000004 }, - { 0x0000775c, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460275d, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x00007999, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460299b, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x01e00830, 0x00000002 }, - { 0x21007000, 0000000000 }, - { 0x00005000, 0x00000002 }, - { 0x00038042, 0x00000002 }, - { 0x040025e0, 0x00000002 }, - { 0x000075e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000380d9, 0x00000002 }, - { 0x04007394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, + {0x21007000, 0000000000}, + {0x20007000, 0000000000}, + {0x000000ab, 0x00000004}, + {0x000000af, 0x00000004}, + {0x66544a49, 0000000000}, + {0x49494174, 0000000000}, + {0x54517d83, 0000000000}, + {0x498d8b64, 0000000000}, + {0x49494949, 0000000000}, + {0x49da493c, 0000000000}, + {0x49989898, 0000000000}, + {0xd34949d5, 0000000000}, + {0x9dc90e11, 0000000000}, + {0xce9b9b9b, 0000000000}, + {0x000f0000, 0x00000016}, + {0x352e232c, 0000000000}, + {0x00000013, 0x00000004}, + {0x000f0000, 0x00000016}, + {0x352e272c, 0000000000}, + {0x000f0001, 0x00000016}, + {0x3239362f, 0000000000}, + {0x000077ef, 0x00000002}, + {0x00061000, 0x00000002}, + {0x00000020, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00061000, 0x00000002}, + {0x00000020, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00061000, 0x00000002}, + {0x00000020, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00000016, 0x00000004}, + {0x0003802a, 0x00000002}, + {0x040067e0, 0x00000002}, + {0x00000016, 0x00000004}, + {0x000077e0, 0x00000002}, + {0x00065000, 0x00000002}, + {0x000037e1, 0x00000002}, + {0x040067e1, 0x00000006}, + {0x000077e0, 0x00000002}, + {0x000077e1, 0x00000002}, + {0x000077e1, 0x00000006}, + {0xffffffff, 0000000000}, + {0x10000000, 0000000000}, + {0x0003802a, 0x00000002}, + {0x040067e0, 0x00000006}, + {0x00007675, 0x00000002}, + {0x00007676, 0x00000002}, + {0x00007677, 0x00000002}, + {0x00007678, 0x00000006}, + {0x0003802b, 0x00000002}, + {0x04002676, 0x00000002}, + {0x00007677, 0x00000002}, + {0x00007678, 0x00000006}, + {0x0000002e, 0x00000018}, + {0x0000002e, 0x00000018}, + {0000000000, 0x00000006}, + {0x0000002f, 0x00000018}, + {0x0000002f, 0x00000018}, + {0000000000, 0x00000006}, + {0x01605000, 0x00000002}, + {0x00065000, 0x00000002}, + {0x00098000, 0x00000002}, + {0x00061000, 0x00000002}, + {0x64c0603d, 0x00000004}, + {0x00080000, 0x00000016}, + {0000000000, 0000000000}, + {0x0400251d, 0x00000002}, + {0x00007580, 0x00000002}, + {0x00067581, 0x00000002}, + {0x04002580, 0x00000002}, + {0x00067581, 0x00000002}, + {0x00000046, 0x00000004}, + {0x00005000, 0000000000}, + {0x00061000, 0x00000002}, + {0x0000750e, 0x00000002}, + {0x00019000, 0x00000002}, + {0x00011055, 0x00000014}, + {0x00000055, 0x00000012}, + {0x0400250f, 0x00000002}, + {0x0000504a, 0x00000004}, + {0x00007565, 0x00000002}, + {0x00007566, 0x00000002}, + {0x00000051, 0x00000004}, + {0x01e655b4, 0x00000002}, + {0x4401b0dc, 0x00000002}, + {0x01c110dc, 0x00000002}, + {0x2666705d, 0x00000018}, + {0x040c2565, 0x00000002}, + {0x0000005d, 0x00000018}, + {0x04002564, 0x00000002}, + {0x00007566, 0x00000002}, + {0x00000054, 0x00000004}, + {0x00401060, 0x00000008}, + {0x00101000, 0x00000002}, + {0x000d80ff, 0x00000002}, + {0x00800063, 0x00000008}, + {0x000f9000, 0x00000002}, + {0x000e00ff, 0x00000002}, + {0000000000, 0x00000006}, + {0x00000080, 0x00000018}, + {0x00000054, 0x00000004}, + {0x00007576, 0x00000002}, + {0x00065000, 0x00000002}, + {0x00009000, 0x00000002}, + {0x00041000, 0x00000002}, + {0x0c00350e, 0x00000002}, + {0x00049000, 0x00000002}, + {0x00051000, 0x00000002}, + {0x01e785f8, 0x00000002}, + {0x00200000, 0x00000002}, + {0x00600073, 0x0000000c}, + {0x00007563, 0x00000002}, + {0x006075f0, 0x00000021}, + {0x20007068, 0x00000004}, + {0x00005068, 0x00000004}, + {0x00007576, 0x00000002}, + {0x00007577, 0x00000002}, + {0x0000750e, 0x00000002}, + {0x0000750f, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00600076, 0x0000000c}, + {0x006075f0, 0x00000021}, + {0x000075f8, 0x00000002}, + {0x00000076, 0x00000004}, + {0x000a750e, 0x00000002}, + {0x0020750f, 0x00000002}, + {0x00600079, 0x00000004}, + {0x00007570, 0x00000002}, + {0x00007571, 0x00000002}, + {0x00007572, 0x00000006}, + {0x00005000, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00007568, 0x00000002}, + {0x00061000, 0x00000002}, + {0x00000084, 0x0000000c}, + {0x00058000, 0x00000002}, + {0x0c607562, 0x00000002}, + {0x00000086, 0x00000004}, + {0x00600085, 0x00000004}, + {0x400070dd, 0000000000}, + {0x000380dd, 0x00000002}, + {0x00000093, 0x0000001c}, + {0x00065095, 0x00000018}, + {0x040025bb, 0x00000002}, + {0x00061096, 0x00000018}, + {0x040075bc, 0000000000}, + {0x000075bb, 0x00000002}, + {0x000075bc, 0000000000}, + {0x00090000, 0x00000006}, + {0x00090000, 0x00000002}, + {0x000d8002, 0x00000006}, + {0x00005000, 0x00000002}, + {0x00007821, 0x00000002}, + {0x00007800, 0000000000}, + {0x00007821, 0x00000002}, + {0x00007800, 0000000000}, + {0x01665000, 0x00000002}, + {0x000a0000, 0x00000002}, + {0x000671cc, 0x00000002}, + {0x0286f1cd, 0x00000002}, + {0x000000a3, 0x00000010}, + {0x21007000, 0000000000}, + {0x000000aa, 0x0000001c}, + {0x00065000, 0x00000002}, + {0x000a0000, 0x00000002}, + {0x00061000, 0x00000002}, + {0x000b0000, 0x00000002}, + {0x38067000, 0x00000002}, + {0x000a00a6, 0x00000004}, + {0x20007000, 0000000000}, + {0x01200000, 0x00000002}, + {0x20077000, 0x00000002}, + {0x01200000, 0x00000002}, + {0x20007000, 0000000000}, + {0x00061000, 0x00000002}, + {0x0120751b, 0x00000002}, + {0x8040750a, 0x00000002}, + {0x8040750b, 0x00000002}, + {0x00110000, 0x00000002}, + {0x000380dd, 0x00000002}, + {0x000000bd, 0x0000001c}, + {0x00061096, 0x00000018}, + {0x844075bd, 0x00000002}, + {0x00061095, 0x00000018}, + {0x840075bb, 0x00000002}, + {0x00061096, 0x00000018}, + {0x844075bc, 0x00000002}, + {0x000000c0, 0x00000004}, + {0x804075bd, 0x00000002}, + {0x800075bb, 0x00000002}, + {0x804075bc, 0x00000002}, + {0x00108000, 0x00000002}, + {0x01400000, 0x00000002}, + {0x006000c4, 0x0000000c}, + {0x20c07000, 0x00000020}, + {0x000000c6, 0x00000012}, + {0x00800000, 0x00000006}, + {0x0080751d, 0x00000006}, + {0x000025bb, 0x00000002}, + {0x000040c0, 0x00000004}, + {0x0000775c, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00661000, 0x00000002}, + {0x0460275d, 0x00000020}, + {0x00004000, 0000000000}, + {0x00007999, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00661000, 0x00000002}, + {0x0460299b, 0x00000020}, + {0x00004000, 0000000000}, + {0x01e00830, 0x00000002}, + {0x21007000, 0000000000}, + {0x00005000, 0x00000002}, + {0x00038042, 0x00000002}, + {0x040025e0, 0x00000002}, + {0x000075e1, 0000000000}, + {0x00000001, 0000000000}, + {0x000380d9, 0x00000002}, + {0x04007394, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, }; - static u32 radeon_cp_microcode[][2] = { - { 0x21007000, 0000000000 }, - { 0x20007000, 0000000000 }, - { 0x000000b4, 0x00000004 }, - { 0x000000b8, 0x00000004 }, - { 0x6f5b4d4c, 0000000000 }, - { 0x4c4c427f, 0000000000 }, - { 0x5b568a92, 0000000000 }, - { 0x4ca09c6d, 0000000000 }, - { 0xad4c4c4c, 0000000000 }, - { 0x4ce1af3d, 0000000000 }, - { 0xd8afafaf, 0000000000 }, - { 0xd64c4cdc, 0000000000 }, - { 0x4cd10d10, 0000000000 }, - { 0x000f0000, 0x00000016 }, - { 0x362f242d, 0000000000 }, - { 0x00000012, 0x00000004 }, - { 0x000f0000, 0x00000016 }, - { 0x362f282d, 0000000000 }, - { 0x000380e7, 0x00000002 }, - { 0x04002c97, 0x00000002 }, - { 0x000f0001, 0x00000016 }, - { 0x333a3730, 0000000000 }, - { 0x000077ef, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00000017, 0x00000004 }, - { 0x0003802b, 0x00000002 }, - { 0x040067e0, 0x00000002 }, - { 0x00000017, 0x00000004 }, - { 0x000077e0, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x000037e1, 0x00000002 }, - { 0x040067e1, 0x00000006 }, - { 0x000077e0, 0x00000002 }, - { 0x000077e1, 0x00000002 }, - { 0x000077e1, 0x00000006 }, - { 0xffffffff, 0000000000 }, - { 0x10000000, 0000000000 }, - { 0x0003802b, 0x00000002 }, - { 0x040067e0, 0x00000006 }, - { 0x00007675, 0x00000002 }, - { 0x00007676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802c, 0x00000002 }, - { 0x04002676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0000002f, 0x00000018 }, - { 0x0000002f, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x00000030, 0x00000018 }, - { 0x00000030, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x01605000, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00098000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x64c0603e, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00080000, 0x00000016 }, - { 0000000000, 0000000000 }, - { 0x0400251d, 0x00000002 }, - { 0x00007580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x04002580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x00000049, 0x00000004 }, - { 0x00005000, 0000000000 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x00019000, 0x00000002 }, - { 0x00011055, 0x00000014 }, - { 0x00000055, 0x00000012 }, - { 0x0400250f, 0x00000002 }, - { 0x0000504f, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007565, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000058, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x01e655b4, 0x00000002 }, - { 0x4401b0e4, 0x00000002 }, - { 0x01c110e4, 0x00000002 }, - { 0x26667066, 0x00000018 }, - { 0x040c2565, 0x00000002 }, - { 0x00000066, 0x00000018 }, - { 0x04002564, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x0000005d, 0x00000004 }, - { 0x00401069, 0x00000008 }, - { 0x00101000, 0x00000002 }, - { 0x000d80ff, 0x00000002 }, - { 0x0080006c, 0x00000008 }, - { 0x000f9000, 0x00000002 }, - { 0x000e00ff, 0x00000002 }, - { 0000000000, 0x00000006 }, - { 0x0000008f, 0x00000018 }, - { 0x0000005b, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007576, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00009000, 0x00000002 }, - { 0x00041000, 0x00000002 }, - { 0x0c00350e, 0x00000002 }, - { 0x00049000, 0x00000002 }, - { 0x00051000, 0x00000002 }, - { 0x01e785f8, 0x00000002 }, - { 0x00200000, 0x00000002 }, - { 0x0060007e, 0x0000000c }, - { 0x00007563, 0x00000002 }, - { 0x006075f0, 0x00000021 }, - { 0x20007073, 0x00000004 }, - { 0x00005073, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007576, 0x00000002 }, - { 0x00007577, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x0000750f, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00600083, 0x0000000c }, - { 0x006075f0, 0x00000021 }, - { 0x000075f8, 0x00000002 }, - { 0x00000083, 0x00000004 }, - { 0x000a750e, 0x00000002 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x0020750f, 0x00000002 }, - { 0x00600086, 0x00000004 }, - { 0x00007570, 0x00000002 }, - { 0x00007571, 0x00000002 }, - { 0x00007572, 0x00000006 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00005000, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00007568, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000095, 0x0000000c }, - { 0x00058000, 0x00000002 }, - { 0x0c607562, 0x00000002 }, - { 0x00000097, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00600096, 0x00000004 }, - { 0x400070e5, 0000000000 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x000380e5, 0x00000002 }, - { 0x000000a8, 0x0000001c }, - { 0x000650aa, 0x00000018 }, - { 0x040025bb, 0x00000002 }, - { 0x000610ab, 0x00000018 }, - { 0x040075bc, 0000000000 }, - { 0x000075bb, 0x00000002 }, - { 0x000075bc, 0000000000 }, - { 0x00090000, 0x00000006 }, - { 0x00090000, 0x00000002 }, - { 0x000d8002, 0x00000006 }, - { 0x00007832, 0x00000002 }, - { 0x00005000, 0x00000002 }, - { 0x000380e7, 0x00000002 }, - { 0x04002c97, 0x00000002 }, - { 0x00007820, 0x00000002 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x01200000, 0x00000002 }, - { 0x20077000, 0x00000002 }, - { 0x01200000, 0x00000002 }, - { 0x20007000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x0120751b, 0x00000002 }, - { 0x8040750a, 0x00000002 }, - { 0x8040750b, 0x00000002 }, - { 0x00110000, 0x00000002 }, - { 0x000380e5, 0x00000002 }, - { 0x000000c6, 0x0000001c }, - { 0x000610ab, 0x00000018 }, - { 0x844075bd, 0x00000002 }, - { 0x000610aa, 0x00000018 }, - { 0x840075bb, 0x00000002 }, - { 0x000610ab, 0x00000018 }, - { 0x844075bc, 0x00000002 }, - { 0x000000c9, 0x00000004 }, - { 0x804075bd, 0x00000002 }, - { 0x800075bb, 0x00000002 }, - { 0x804075bc, 0x00000002 }, - { 0x00108000, 0x00000002 }, - { 0x01400000, 0x00000002 }, - { 0x006000cd, 0x0000000c }, - { 0x20c07000, 0x00000020 }, - { 0x000000cf, 0x00000012 }, - { 0x00800000, 0x00000006 }, - { 0x0080751d, 0x00000006 }, - { 0000000000, 0000000000 }, - { 0x0000775c, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460275d, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x01e00830, 0x00000002 }, - { 0x21007000, 0000000000 }, - { 0x6464614d, 0000000000 }, - { 0x69687420, 0000000000 }, - { 0x00000073, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x00005000, 0x00000002 }, - { 0x000380d0, 0x00000002 }, - { 0x040025e0, 0x00000002 }, - { 0x000075e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000380e0, 0x00000002 }, - { 0x04002394, 0x00000002 }, - { 0x00005000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x00000008, 0000000000 }, - { 0x00000004, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, + {0x21007000, 0000000000}, + {0x20007000, 0000000000}, + {0x000000b4, 0x00000004}, + {0x000000b8, 0x00000004}, + {0x6f5b4d4c, 0000000000}, + {0x4c4c427f, 0000000000}, + {0x5b568a92, 0000000000}, + {0x4ca09c6d, 0000000000}, + {0xad4c4c4c, 0000000000}, + {0x4ce1af3d, 0000000000}, + {0xd8afafaf, 0000000000}, + {0xd64c4cdc, 0000000000}, + {0x4cd10d10, 0000000000}, + {0x000f0000, 0x00000016}, + {0x362f242d, 0000000000}, + {0x00000012, 0x00000004}, + {0x000f0000, 0x00000016}, + {0x362f282d, 0000000000}, + {0x000380e7, 0x00000002}, + {0x04002c97, 0x00000002}, + {0x000f0001, 0x00000016}, + {0x333a3730, 0000000000}, + {0x000077ef, 0x00000002}, + {0x00061000, 0x00000002}, + {0x00000021, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00061000, 0x00000002}, + {0x00000021, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00061000, 0x00000002}, + {0x00000021, 0x0000001a}, + {0x00004000, 0x0000001e}, + {0x00000017, 0x00000004}, + {0x0003802b, 0x00000002}, + {0x040067e0, 0x00000002}, + {0x00000017, 0x00000004}, + {0x000077e0, 0x00000002}, + {0x00065000, 0x00000002}, + {0x000037e1, 0x00000002}, + {0x040067e1, 0x00000006}, + {0x000077e0, 0x00000002}, + {0x000077e1, 0x00000002}, + {0x000077e1, 0x00000006}, + {0xffffffff, 0000000000}, + {0x10000000, 0000000000}, + {0x0003802b, 0x00000002}, + {0x040067e0, 0x00000006}, + {0x00007675, 0x00000002}, + {0x00007676, 0x00000002}, + {0x00007677, 0x00000002}, + {0x00007678, 0x00000006}, + {0x0003802c, 0x00000002}, + {0x04002676, 0x00000002}, + {0x00007677, 0x00000002}, + {0x00007678, 0x00000006}, + {0x0000002f, 0x00000018}, + {0x0000002f, 0x00000018}, + {0000000000, 0x00000006}, + {0x00000030, 0x00000018}, + {0x00000030, 0x00000018}, + {0000000000, 0x00000006}, + {0x01605000, 0x00000002}, + {0x00065000, 0x00000002}, + {0x00098000, 0x00000002}, + {0x00061000, 0x00000002}, + {0x64c0603e, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00080000, 0x00000016}, + {0000000000, 0000000000}, + {0x0400251d, 0x00000002}, + {0x00007580, 0x00000002}, + {0x00067581, 0x00000002}, + {0x04002580, 0x00000002}, + {0x00067581, 0x00000002}, + {0x00000049, 0x00000004}, + {0x00005000, 0000000000}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00061000, 0x00000002}, + {0x0000750e, 0x00000002}, + {0x00019000, 0x00000002}, + {0x00011055, 0x00000014}, + {0x00000055, 0x00000012}, + {0x0400250f, 0x00000002}, + {0x0000504f, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00007565, 0x00000002}, + {0x00007566, 0x00000002}, + {0x00000058, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x01e655b4, 0x00000002}, + {0x4401b0e4, 0x00000002}, + {0x01c110e4, 0x00000002}, + {0x26667066, 0x00000018}, + {0x040c2565, 0x00000002}, + {0x00000066, 0x00000018}, + {0x04002564, 0x00000002}, + {0x00007566, 0x00000002}, + {0x0000005d, 0x00000004}, + {0x00401069, 0x00000008}, + {0x00101000, 0x00000002}, + {0x000d80ff, 0x00000002}, + {0x0080006c, 0x00000008}, + {0x000f9000, 0x00000002}, + {0x000e00ff, 0x00000002}, + {0000000000, 0x00000006}, + {0x0000008f, 0x00000018}, + {0x0000005b, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00007576, 0x00000002}, + {0x00065000, 0x00000002}, + {0x00009000, 0x00000002}, + {0x00041000, 0x00000002}, + {0x0c00350e, 0x00000002}, + {0x00049000, 0x00000002}, + {0x00051000, 0x00000002}, + {0x01e785f8, 0x00000002}, + {0x00200000, 0x00000002}, + {0x0060007e, 0x0000000c}, + {0x00007563, 0x00000002}, + {0x006075f0, 0x00000021}, + {0x20007073, 0x00000004}, + {0x00005073, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00007576, 0x00000002}, + {0x00007577, 0x00000002}, + {0x0000750e, 0x00000002}, + {0x0000750f, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00600083, 0x0000000c}, + {0x006075f0, 0x00000021}, + {0x000075f8, 0x00000002}, + {0x00000083, 0x00000004}, + {0x000a750e, 0x00000002}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x0020750f, 0x00000002}, + {0x00600086, 0x00000004}, + {0x00007570, 0x00000002}, + {0x00007571, 0x00000002}, + {0x00007572, 0x00000006}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00005000, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00007568, 0x00000002}, + {0x00061000, 0x00000002}, + {0x00000095, 0x0000000c}, + {0x00058000, 0x00000002}, + {0x0c607562, 0x00000002}, + {0x00000097, 0x00000004}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x00600096, 0x00000004}, + {0x400070e5, 0000000000}, + {0x000380e6, 0x00000002}, + {0x040025c5, 0x00000002}, + {0x000380e5, 0x00000002}, + {0x000000a8, 0x0000001c}, + {0x000650aa, 0x00000018}, + {0x040025bb, 0x00000002}, + {0x000610ab, 0x00000018}, + {0x040075bc, 0000000000}, + {0x000075bb, 0x00000002}, + {0x000075bc, 0000000000}, + {0x00090000, 0x00000006}, + {0x00090000, 0x00000002}, + {0x000d8002, 0x00000006}, + {0x00007832, 0x00000002}, + {0x00005000, 0x00000002}, + {0x000380e7, 0x00000002}, + {0x04002c97, 0x00000002}, + {0x00007820, 0x00000002}, + {0x00007821, 0x00000002}, + {0x00007800, 0000000000}, + {0x01200000, 0x00000002}, + {0x20077000, 0x00000002}, + {0x01200000, 0x00000002}, + {0x20007000, 0x00000002}, + {0x00061000, 0x00000002}, + {0x0120751b, 0x00000002}, + {0x8040750a, 0x00000002}, + {0x8040750b, 0x00000002}, + {0x00110000, 0x00000002}, + {0x000380e5, 0x00000002}, + {0x000000c6, 0x0000001c}, + {0x000610ab, 0x00000018}, + {0x844075bd, 0x00000002}, + {0x000610aa, 0x00000018}, + {0x840075bb, 0x00000002}, + {0x000610ab, 0x00000018}, + {0x844075bc, 0x00000002}, + {0x000000c9, 0x00000004}, + {0x804075bd, 0x00000002}, + {0x800075bb, 0x00000002}, + {0x804075bc, 0x00000002}, + {0x00108000, 0x00000002}, + {0x01400000, 0x00000002}, + {0x006000cd, 0x0000000c}, + {0x20c07000, 0x00000020}, + {0x000000cf, 0x00000012}, + {0x00800000, 0x00000006}, + {0x0080751d, 0x00000006}, + {0000000000, 0000000000}, + {0x0000775c, 0x00000002}, + {0x00a05000, 0x00000002}, + {0x00661000, 0x00000002}, + {0x0460275d, 0x00000020}, + {0x00004000, 0000000000}, + {0x01e00830, 0x00000002}, + {0x21007000, 0000000000}, + {0x6464614d, 0000000000}, + {0x69687420, 0000000000}, + {0x00000073, 0000000000}, + {0000000000, 0000000000}, + {0x00005000, 0x00000002}, + {0x000380d0, 0x00000002}, + {0x040025e0, 0x00000002}, + {0x000075e1, 0000000000}, + {0x00000001, 0000000000}, + {0x000380e0, 0x00000002}, + {0x04002394, 0x00000002}, + {0x00005000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0x00000008, 0000000000}, + {0x00000004, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, }; static u32 R300_cp_microcode[][2] = { - { 0x4200e000, 0000000000 }, - { 0x4000e000, 0000000000 }, - { 0x000000af, 0x00000008 }, - { 0x000000b3, 0x00000008 }, - { 0x6c5a504f, 0000000000 }, - { 0x4f4f497a, 0000000000 }, - { 0x5a578288, 0000000000 }, - { 0x4f91906a, 0000000000 }, - { 0x4f4f4f4f, 0000000000 }, - { 0x4fe24f44, 0000000000 }, - { 0x4f9c9c9c, 0000000000 }, - { 0xdc4f4fde, 0000000000 }, - { 0xa1cd4f4f, 0000000000 }, - { 0xd29d9d9d, 0000000000 }, - { 0x4f0f9fd7, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000f041, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000f184, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000f185, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000f186, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000f187, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x02c0a000, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x00130000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0xc980c045, 0x00000008 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x0000004c, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022056, 0x00000028 }, - { 0x00000056, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a050, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000057, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce063, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x00000063, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x0000005a, 0x00000008 }, - { 0x00802066, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000069, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000085, 0x00000030 }, - { 0x0000005a, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x00012000, 0x00000004 }, - { 0x00082000, 0x00000004 }, - { 0x1800650e, 0x00000004 }, - { 0x00092000, 0x00000004 }, - { 0x000a2000, 0x00000004 }, - { 0x000f0000, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x00000079, 0x00000018 }, - { 0x0000e563, 0x00000004 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x0000006e, 0x00000008 }, - { 0x0000a06e, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000007c, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x0000007c, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0007f, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000089, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x0000008b, 0x00000008 }, - { 0x00c0008a, 0x00000008 }, - { 0x000700e4, 0x00000004 }, - { 0x00000097, 0x00000038 }, - { 0x000ca099, 0x00000030 }, - { 0x080045bb, 0x00000004 }, - { 0x000c209a, 0x00000030 }, - { 0x0800e5bc, 0000000000 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x00120000, 0x0000000c }, - { 0x00120000, 0x00000004 }, - { 0x001b0002, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x000000a7, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x000000ae, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x001400aa, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700e4, 0x00000004 }, - { 0x000000c1, 0x00000038 }, - { 0x000c209a, 0x00000030 }, - { 0x0880e5bd, 0x00000005 }, - { 0x000c2099, 0x00000030 }, - { 0x0800e5bb, 0x00000005 }, - { 0x000c209a, 0x00000030 }, - { 0x0880e5bc, 0x00000005 }, - { 0x000000c4, 0x00000008 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000c8, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000ca, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080c4, 0x00000008 }, - { 0x0000f3ce, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053cf, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f3d2, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053d3, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f39d, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c0539e, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700e1, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, + {0x4200e000, 0000000000}, + {0x4000e000, 0000000000}, + {0x000000af, 0x00000008}, + {0x000000b3, 0x00000008}, + {0x6c5a504f, 0000000000}, + {0x4f4f497a, 0000000000}, + {0x5a578288, 0000000000}, + {0x4f91906a, 0000000000}, + {0x4f4f4f4f, 0000000000}, + {0x4fe24f44, 0000000000}, + {0x4f9c9c9c, 0000000000}, + {0xdc4f4fde, 0000000000}, + {0xa1cd4f4f, 0000000000}, + {0xd29d9d9d, 0000000000}, + {0x4f0f9fd7, 0000000000}, + {0x000ca000, 0x00000004}, + {0x000d0012, 0x00000038}, + {0x0000e8b4, 0x00000004}, + {0x000d0014, 0x00000038}, + {0x0000e8b6, 0x00000004}, + {0x000d0016, 0x00000038}, + {0x0000e854, 0x00000004}, + {0x000d0018, 0x00000038}, + {0x0000e855, 0x00000004}, + {0x000d001a, 0x00000038}, + {0x0000e856, 0x00000004}, + {0x000d001c, 0x00000038}, + {0x0000e857, 0x00000004}, + {0x000d001e, 0x00000038}, + {0x0000e824, 0x00000004}, + {0x000d0020, 0x00000038}, + {0x0000e825, 0x00000004}, + {0x000d0022, 0x00000038}, + {0x0000e830, 0x00000004}, + {0x000d0024, 0x00000038}, + {0x0000f0c0, 0x00000004}, + {0x000d0026, 0x00000038}, + {0x0000f0c1, 0x00000004}, + {0x000d0028, 0x00000038}, + {0x0000f041, 0x00000004}, + {0x000d002a, 0x00000038}, + {0x0000f184, 0x00000004}, + {0x000d002c, 0x00000038}, + {0x0000f185, 0x00000004}, + {0x000d002e, 0x00000038}, + {0x0000f186, 0x00000004}, + {0x000d0030, 0x00000038}, + {0x0000f187, 0x00000004}, + {0x000d0032, 0x00000038}, + {0x0000f180, 0x00000004}, + {0x000d0034, 0x00000038}, + {0x0000f393, 0x00000004}, + {0x000d0036, 0x00000038}, + {0x0000f38a, 0x00000004}, + {0x000d0038, 0x00000038}, + {0x0000f38e, 0x00000004}, + {0x0000e821, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x00000043, 0x00000018}, + {0x00cce800, 0x00000004}, + {0x001b0001, 0x00000004}, + {0x08004800, 0x00000004}, + {0x001b0001, 0x00000004}, + {0x08004800, 0x00000004}, + {0x001b0001, 0x00000004}, + {0x08004800, 0x00000004}, + {0x0000003a, 0x00000008}, + {0x0000a000, 0000000000}, + {0x02c0a000, 0x00000004}, + {0x000ca000, 0x00000004}, + {0x00130000, 0x00000004}, + {0x000c2000, 0x00000004}, + {0xc980c045, 0x00000008}, + {0x2000451d, 0x00000004}, + {0x0000e580, 0x00000004}, + {0x000ce581, 0x00000004}, + {0x08004580, 0x00000004}, + {0x000ce581, 0x00000004}, + {0x0000004c, 0x00000008}, + {0x0000a000, 0000000000}, + {0x000c2000, 0x00000004}, + {0x0000e50e, 0x00000004}, + {0x00032000, 0x00000004}, + {0x00022056, 0x00000028}, + {0x00000056, 0x00000024}, + {0x0800450f, 0x00000004}, + {0x0000a050, 0x00000008}, + {0x0000e565, 0x00000004}, + {0x0000e566, 0x00000004}, + {0x00000057, 0x00000008}, + {0x03cca5b4, 0x00000004}, + {0x05432000, 0x00000004}, + {0x00022000, 0x00000004}, + {0x4ccce063, 0x00000030}, + {0x08274565, 0x00000004}, + {0x00000063, 0x00000030}, + {0x08004564, 0x00000004}, + {0x0000e566, 0x00000004}, + {0x0000005a, 0x00000008}, + {0x00802066, 0x00000010}, + {0x00202000, 0x00000004}, + {0x001b00ff, 0x00000004}, + {0x01000069, 0x00000010}, + {0x001f2000, 0x00000004}, + {0x001c00ff, 0x00000004}, + {0000000000, 0x0000000c}, + {0x00000085, 0x00000030}, + {0x0000005a, 0x00000008}, + {0x0000e576, 0x00000004}, + {0x000ca000, 0x00000004}, + {0x00012000, 0x00000004}, + {0x00082000, 0x00000004}, + {0x1800650e, 0x00000004}, + {0x00092000, 0x00000004}, + {0x000a2000, 0x00000004}, + {0x000f0000, 0x00000004}, + {0x00400000, 0x00000004}, + {0x00000079, 0x00000018}, + {0x0000e563, 0x00000004}, + {0x00c0e5f9, 0x000000c2}, + {0x0000006e, 0x00000008}, + {0x0000a06e, 0x00000008}, + {0x0000e576, 0x00000004}, + {0x0000e577, 0x00000004}, + {0x0000e50e, 0x00000004}, + {0x0000e50f, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x0000007c, 0x00000018}, + {0x00c0e5f9, 0x000000c2}, + {0x0000007c, 0x00000008}, + {0x0014e50e, 0x00000004}, + {0x0040e50f, 0x00000004}, + {0x00c0007f, 0x00000008}, + {0x0000e570, 0x00000004}, + {0x0000e571, 0x00000004}, + {0x0000e572, 0x0000000c}, + {0x0000a000, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x0000e568, 0x00000004}, + {0x000c2000, 0x00000004}, + {0x00000089, 0x00000018}, + {0x000b0000, 0x00000004}, + {0x18c0e562, 0x00000004}, + {0x0000008b, 0x00000008}, + {0x00c0008a, 0x00000008}, + {0x000700e4, 0x00000004}, + {0x00000097, 0x00000038}, + {0x000ca099, 0x00000030}, + {0x080045bb, 0x00000004}, + {0x000c209a, 0x00000030}, + {0x0800e5bc, 0000000000}, + {0x0000e5bb, 0x00000004}, + {0x0000e5bc, 0000000000}, + {0x00120000, 0x0000000c}, + {0x00120000, 0x00000004}, + {0x001b0002, 0x0000000c}, + {0x0000a000, 0x00000004}, + {0x0000e821, 0x00000004}, + {0x0000e800, 0000000000}, + {0x0000e821, 0x00000004}, + {0x0000e82e, 0000000000}, + {0x02cca000, 0x00000004}, + {0x00140000, 0x00000004}, + {0x000ce1cc, 0x00000004}, + {0x050de1cd, 0x00000004}, + {0x000000a7, 0x00000020}, + {0x4200e000, 0000000000}, + {0x000000ae, 0x00000038}, + {0x000ca000, 0x00000004}, + {0x00140000, 0x00000004}, + {0x000c2000, 0x00000004}, + {0x00160000, 0x00000004}, + {0x700ce000, 0x00000004}, + {0x001400aa, 0x00000008}, + {0x4000e000, 0000000000}, + {0x02400000, 0x00000004}, + {0x400ee000, 0x00000004}, + {0x02400000, 0x00000004}, + {0x4000e000, 0000000000}, + {0x000c2000, 0x00000004}, + {0x0240e51b, 0x00000004}, + {0x0080e50a, 0x00000005}, + {0x0080e50b, 0x00000005}, + {0x00220000, 0x00000004}, + {0x000700e4, 0x00000004}, + {0x000000c1, 0x00000038}, + {0x000c209a, 0x00000030}, + {0x0880e5bd, 0x00000005}, + {0x000c2099, 0x00000030}, + {0x0800e5bb, 0x00000005}, + {0x000c209a, 0x00000030}, + {0x0880e5bc, 0x00000005}, + {0x000000c4, 0x00000008}, + {0x0080e5bd, 0x00000005}, + {0x0000e5bb, 0x00000005}, + {0x0080e5bc, 0x00000005}, + {0x00210000, 0x00000004}, + {0x02800000, 0x00000004}, + {0x00c000c8, 0x00000018}, + {0x4180e000, 0x00000040}, + {0x000000ca, 0x00000024}, + {0x01000000, 0x0000000c}, + {0x0100e51d, 0x0000000c}, + {0x000045bb, 0x00000004}, + {0x000080c4, 0x00000008}, + {0x0000f3ce, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x00cc2000, 0x00000004}, + {0x08c053cf, 0x00000040}, + {0x00008000, 0000000000}, + {0x0000f3d2, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x00cc2000, 0x00000004}, + {0x08c053d3, 0x00000040}, + {0x00008000, 0000000000}, + {0x0000f39d, 0x00000004}, + {0x0140a000, 0x00000004}, + {0x00cc2000, 0x00000004}, + {0x08c0539e, 0x00000040}, + {0x00008000, 0000000000}, + {0x03c00830, 0x00000004}, + {0x4200e000, 0000000000}, + {0x0000a000, 0x00000004}, + {0x200045e0, 0x00000004}, + {0x0000e5e1, 0000000000}, + {0x00000001, 0000000000}, + {0x000700e1, 0x00000004}, + {0x0800e394, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, + {0000000000, 0000000000}, }; -static int RADEON_READ_PLL(drm_device_t *dev, int addr) +static int RADEON_READ_PLL(drm_device_t * dev, int addr) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -825,151 +824,148 @@ static int RADEON_READ_PLL(drm_device_t *dev, int addr) return RADEON_READ(RADEON_CLOCK_CNTL_DATA); } -static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr) { RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); return RADEON_READ(RADEON_PCIE_DATA); } #if RADEON_FIFO_DEBUG -static void radeon_status( drm_radeon_private_t *dev_priv ) +static void radeon_status(drm_radeon_private_t * dev_priv) { - printk( "%s:\n", __FUNCTION__ ); - printk( "RBBM_STATUS = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) ); - printk( "CP_RB_RTPR = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) ); - printk( "CP_RB_WTPR = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) ); - printk( "AIC_CNTL = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) ); - printk( "AIC_STAT = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_AIC_STAT ) ); - printk( "AIC_PT_BASE = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) ); - printk( "TLB_ADDR = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) ); - printk( "TLB_DATA = 0x%08x\n", - (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) ); + printk("%s:\n", __FUNCTION__); + printk("RBBM_STATUS = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); + printk("CP_RB_RTPR = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR)); + printk("CP_RB_WTPR = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR)); + printk("AIC_CNTL = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_AIC_CNTL)); + printk("AIC_STAT = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_AIC_STAT)); + printk("AIC_PT_BASE = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE)); + printk("TLB_ADDR = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR)); + printk("TLB_DATA = 0x%08x\n", + (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA)); } #endif - /* ================================================================ * Engine, FIFO control */ -static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) +static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) { u32 tmp; int i; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); + tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT); tmp |= RADEON_RB2D_DC_FLUSH_ALL; - RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); + RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp); - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ) - & RADEON_RB2D_DC_BUSY) ) { + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT) + & RADEON_RB2D_DC_BUSY)) { return 0; } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if RADEON_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); - radeon_status( dev_priv ); + DRM_ERROR("failed!\n"); + radeon_status(dev_priv); #endif return DRM_ERR(EBUSY); } -static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, - int entries ) +static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) { int i; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) - & RADEON_RBBM_FIFOCNT_MASK ); - if ( slots >= entries ) return 0; - DRM_UDELAY( 1 ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + int slots = (RADEON_READ(RADEON_RBBM_STATUS) + & RADEON_RBBM_FIFOCNT_MASK); + if (slots >= entries) + return 0; + DRM_UDELAY(1); } #if RADEON_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); - radeon_status( dev_priv ); + DRM_ERROR("failed!\n"); + radeon_status(dev_priv); #endif return DRM_ERR(EBUSY); } -static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) +static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) { int i, ret; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - ret = radeon_do_wait_for_fifo( dev_priv, 64 ); - if ( ret ) return ret; + ret = radeon_do_wait_for_fifo(dev_priv, 64); + if (ret) + return ret; - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( !(RADEON_READ( RADEON_RBBM_STATUS ) - & RADEON_RBBM_ACTIVE) ) { - radeon_do_pixcache_flush( dev_priv ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (!(RADEON_READ(RADEON_RBBM_STATUS) + & RADEON_RBBM_ACTIVE)) { + radeon_do_pixcache_flush(dev_priv); return 0; } - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } #if RADEON_FIFO_DEBUG - DRM_ERROR( "failed!\n" ); - radeon_status( dev_priv ); + DRM_ERROR("failed!\n"); + radeon_status(dev_priv); #endif return DRM_ERR(EBUSY); } - /* ================================================================ * CP control, initialization */ /* Load the microcode for the CP */ -static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) +static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) { int i; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - radeon_do_wait_for_idle( dev_priv ); + radeon_do_wait_for_idle(dev_priv); - RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); + RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); - if (dev_priv->microcode_version==UCODE_R200) { + if (dev_priv->microcode_version == UCODE_R200) { DRM_INFO("Loading R200 Microcode\n"); - for ( i = 0 ; i < 256 ; i++ ) - { - RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, - R200_cp_microcode[i][1] ); - RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, - R200_cp_microcode[i][0] ); + for (i = 0; i < 256; i++) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, + R200_cp_microcode[i][1]); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + R200_cp_microcode[i][0]); } - } else if (dev_priv->microcode_version==UCODE_R300) { + } else if (dev_priv->microcode_version == UCODE_R300) { DRM_INFO("Loading R300 Microcode\n"); - for ( i = 0 ; i < 256 ; i++ ) - { - RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, - R300_cp_microcode[i][1] ); - RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, - R300_cp_microcode[i][0] ); + for (i = 0; i < 256; i++) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, + R300_cp_microcode[i][1]); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + R300_cp_microcode[i][0]); } } else { - for ( i = 0 ; i < 256 ; i++ ) { - RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, - radeon_cp_microcode[i][1] ); - RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, - radeon_cp_microcode[i][0] ); + for (i = 0; i < 256; i++) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, + radeon_cp_microcode[i][1]); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + radeon_cp_microcode[i][0]); } } } @@ -978,25 +974,25 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) * prior to a wait for idle, as it informs the engine that the command * stream is ending. */ -static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) +static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) { - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); #if 0 u32 tmp; - tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31); - RADEON_WRITE( RADEON_CP_RB_WPTR, tmp ); + tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); + RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); #endif } /* Wait for the CP to go idle. */ -int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) +int radeon_do_cp_idle(drm_radeon_private_t * dev_priv) { RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - BEGIN_RING( 6 ); + BEGIN_RING(6); RADEON_PURGE_CACHE(); RADEON_PURGE_ZCACHE(); @@ -1005,23 +1001,23 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) ADVANCE_RING(); COMMIT_RING(); - return radeon_do_wait_for_idle( dev_priv ); + return radeon_do_wait_for_idle(dev_priv); } /* Start the Command Processor. */ -static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) +static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) { RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - radeon_do_wait_for_idle( dev_priv ); + radeon_do_wait_for_idle(dev_priv); - RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode ); + RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode); dev_priv->cp_running = 1; - BEGIN_RING( 6 ); + BEGIN_RING(6); RADEON_PURGE_CACHE(); RADEON_PURGE_ZCACHE(); @@ -1035,14 +1031,14 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) * commands, so you must wait for the CP command stream to complete * before calling this routine. */ -static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) +static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv) { u32 cur_read_ptr; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); - RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - SET_RING_HEAD( dev_priv, cur_read_ptr ); + cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); + RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); + SET_RING_HEAD(dev_priv, cur_read_ptr); dev_priv->ring.tail = cur_read_ptr; } @@ -1050,120 +1046,116 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) * commands, so you must flush the command stream and wait for the CP * to go idle before calling this routine. */ -static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) +static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) { - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); + RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); dev_priv->cp_running = 0; } /* Reset the engine. This will stop the CP if it is running. */ -static int radeon_do_engine_reset( drm_device_t *dev ) +static int radeon_do_engine_reset(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - radeon_do_pixcache_flush( dev_priv ); + radeon_do_pixcache_flush(dev_priv); - clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX ); - mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL ); + clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); + mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); - RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC ) ); + RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | + RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB | + RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC | + RADEON_FORCEON_AIC)); - rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET ); + rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); - RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset | - RADEON_SOFT_RESET_CP | + RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB)); + RADEON_READ(RADEON_RBBM_SOFT_RESET); + RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & + ~(RADEON_SOFT_RESET_CP | RADEON_SOFT_RESET_HI | RADEON_SOFT_RESET_SE | RADEON_SOFT_RESET_RE | RADEON_SOFT_RESET_PP | RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB ) ); - RADEON_READ( RADEON_RBBM_SOFT_RESET ); - RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset & - ~( RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB ) ) ); - RADEON_READ( RADEON_RBBM_SOFT_RESET ); + RADEON_SOFT_RESET_RB))); + RADEON_READ(RADEON_RBBM_SOFT_RESET); - - RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl ); - RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index ); - RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset ); + RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); + RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); /* Reset the CP ring */ - radeon_do_cp_reset( dev_priv ); + radeon_do_cp_reset(dev_priv); /* The CP is no longer running after an engine reset */ dev_priv->cp_running = 0; /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset( dev ); + radeon_freelist_reset(dev); return 0; } -static void radeon_cp_init_ring_buffer( drm_device_t *dev, - drm_radeon_private_t *dev_priv ) +static void radeon_cp_init_ring_buffer(drm_device_t * dev, + drm_radeon_private_t * dev_priv) { u32 ring_start, cur_read_ptr; u32 tmp; /* Initialize the memory controller */ - RADEON_WRITE( RADEON_MC_FB_LOCATION, - ( ( dev_priv->gart_vm_start - 1 ) & 0xffff0000 ) - | ( dev_priv->fb_location >> 16 ) ); + RADEON_WRITE(RADEON_MC_FB_LOCATION, + ((dev_priv->gart_vm_start - 1) & 0xffff0000) + | (dev_priv->fb_location >> 16)); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { - RADEON_WRITE( RADEON_MC_AGP_LOCATION, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16)) ); + if (!dev_priv->is_pci) { + RADEON_WRITE(RADEON_MC_AGP_LOCATION, + (((dev_priv->gart_vm_start - 1 + + dev_priv->gart_size) & 0xffff0000) | + (dev_priv->gart_vm_start >> 16))); ring_start = (dev_priv->cp_ring->offset - - dev->agp->base - + dev_priv->gart_vm_start); - } else + - dev->agp->base + dev_priv->gart_vm_start); + } else #endif ring_start = (dev_priv->cp_ring->offset - - dev->sg->handle - + dev_priv->gart_vm_start); + - dev->sg->handle + dev_priv->gart_vm_start); - RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); + RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); /* Set the write pointer delay */ - RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); + RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); /* Initialize the ring buffer's read and write pointers */ - cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); - RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - SET_RING_HEAD( dev_priv, cur_read_ptr ); + cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); + RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); + SET_RING_HEAD(dev_priv, cur_read_ptr); dev_priv->ring.tail = cur_read_ptr; #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { + if (!dev_priv->is_pci) { /* set RADEON_AGP_BASE here instead of relying on X from user space */ RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset - - dev->agp->base - + dev_priv->gart_vm_start); + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, + dev_priv->ring_rptr->offset + - dev->agp->base + dev_priv->gart_vm_start); } else #endif { @@ -1173,11 +1165,10 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; page_ofs = tmp_ofs >> PAGE_SHIFT; - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long) entry->busaddr[page_ofs], - entry->handle + tmp_ofs ); + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); + DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", + (unsigned long)entry->busaddr[page_ofs], + entry->handle + tmp_ofs); } /* Initialize the scratch register pointer. This will cause @@ -1187,64 +1178,64 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, * We simply put this behind the ring read pointer, this works * with PCI GART as well as (whatever kind of) AGP GART */ - RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) - + RADEON_SCRATCH_REG_OFFSET ); + RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + + RADEON_SCRATCH_REG_OFFSET); dev_priv->scratch = ((__volatile__ u32 *) dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); /* Writeback doesn't seem to work everywhere, test it first */ - DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); - RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); + DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); + RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); - for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { - if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) + for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { + if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == + 0xdeadbeef) break; - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } - if ( tmp < dev_priv->usec_timeout ) { + if (tmp < dev_priv->usec_timeout) { dev_priv->writeback_works = 1; - DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); + DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp); } else { dev_priv->writeback_works = 0; - DRM_DEBUG( "writeback test failed\n" ); + DRM_DEBUG("writeback test failed\n"); } dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; - RADEON_WRITE( RADEON_LAST_FRAME_REG, - dev_priv->sarea_priv->last_frame ); + RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; - RADEON_WRITE( RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch ); + RADEON_WRITE(RADEON_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch); dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; - RADEON_WRITE( RADEON_LAST_CLEAR_REG, - dev_priv->sarea_priv->last_clear ); + RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); /* Set ring buffer size */ #ifdef __BIG_ENDIAN - RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); + RADEON_WRITE(RADEON_CP_RB_CNTL, + dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); #else - RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); + RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); #endif - radeon_do_wait_for_idle( dev_priv ); + radeon_do_wait_for_idle(dev_priv); /* Turn on bus mastering */ - tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE( RADEON_BUS_CNTL, tmp ); + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); /* Sync everything up */ - RADEON_WRITE( RADEON_ISYNC_CNTL, - (RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); + RADEON_WRITE(RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + RADEON_ISYNC_CPSCRATCH_IDLEGUI)); } /* Enable or disable PCI-E GART on the chip */ @@ -1254,35 +1245,42 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) if (on) { DRM_DEBUG("programming pcie %08X %08lX %08X\n", - dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, dev_priv->gart_size); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start - + dev_priv->gart_size - 1); - + RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, + dev_priv->gart_vm_start); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, + dev_priv->gart_info.bus_addr); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, + dev_priv->gart_vm_start); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, + dev_priv->gart_vm_start + + dev_priv->gart_size - 1); + RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ - - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); + + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, + RADEON_PCIE_TX_GART_EN); } else { - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, + tmp & ~RADEON_PCIE_TX_GART_EN); } } /* Enable or disable PCI GART on the chip */ -static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) +static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { - u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); + u32 tmp = RADEON_READ(RADEON_AIC_CNTL); - if (dev_priv->flags & CHIP_IS_PCIE) - { + if (dev_priv->flags & CHIP_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; } - if ( on ) { - RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); + if (on) { + RADEON_WRITE(RADEON_AIC_CNTL, + tmp | RADEON_PCIGART_TRANSLATE_EN); /* set PCI GART page-table base address */ @@ -1290,53 +1288,54 @@ static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) /* set address range for PCI address translate */ - RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start ); - RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start - + dev_priv->gart_size - 1); + RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); + RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start + + dev_priv->gart_size - 1); /* Turn off AGP aperture -- is this required for PCI GART? */ - RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ - RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ + RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ } else { - RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN ); + RADEON_WRITE(RADEON_AIC_CNTL, + tmp & ~RADEON_PCIGART_TRANSLATE_EN); } } -static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) +static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private;; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); dev_priv->is_pci = init->is_pci; - if ( dev_priv->is_pci && !dev->sg ) { - DRM_ERROR( "PCI GART memory not allocated!\n" ); + if (dev_priv->is_pci && !dev->sg) { + DRM_ERROR("PCI GART memory not allocated!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } dev_priv->usec_timeout = init->usec_timeout; - if ( dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { - DRM_DEBUG( "TIMEOUT problem!\n" ); + if (dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { + DRM_DEBUG("TIMEOUT problem!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - switch(init->func) { + switch (init->func) { case RADEON_INIT_R200_CP: - dev_priv->microcode_version=UCODE_R200; + dev_priv->microcode_version = UCODE_R200; break; case RADEON_INIT_R300_CP: - dev_priv->microcode_version=UCODE_R300; + dev_priv->microcode_version = UCODE_R300; break; default: - dev_priv->microcode_version=UCODE_R100; + dev_priv->microcode_version = UCODE_R100; } - + dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; @@ -1344,15 +1343,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) * but the ring can be in either AGP or PCI space for the ring * read pointer. */ - if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && - ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { - DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); + if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && + (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { + DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - switch ( init->fb_bpp ) { + switch (init->fb_bpp) { case 16: dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; break; @@ -1361,12 +1360,12 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; break; } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; - switch ( init->depth_bpp ) { + switch (init->depth_bpp) { case 16: dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; break; @@ -1375,8 +1374,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; break; } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; /* Hardware state for depth clears. Remove this if/when we no * longer clear the depth buffer with a 3D rectangle. Hard-code @@ -1385,16 +1384,16 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | (dev_priv->color_fmt << 10) | - (dev_priv->microcode_version == UCODE_R100 ? RADEON_ZBLOCK16 : 0)); + (dev_priv->microcode_version == + UCODE_R100 ? RADEON_ZBLOCK16 : 0)); - dev_priv->depth_clear.rb3d_zstencilcntl = - (dev_priv->depth_fmt | - RADEON_Z_TEST_ALWAYS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_S_FAIL_REPLACE | - RADEON_STENCIL_ZPASS_REPLACE | - RADEON_STENCIL_ZFAIL_REPLACE | - RADEON_Z_WRITE_ENABLE); + dev_priv->depth_clear.rb3d_zstencilcntl = + (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_REPLACE | + RADEON_STENCIL_ZPASS_REPLACE | + RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | RADEON_BFACE_SOLID | @@ -1416,8 +1415,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->ring_rptr_offset = init->ring_rptr_offset; dev_priv->buffers_offset = init->buffers_offset; dev_priv->gart_textures_offset = init->gart_textures_offset; - - if(!dev_priv->sarea) { + + if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); @@ -1425,21 +1424,21 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if(!dev_priv->mmio) { + if (!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); - if(!dev_priv->cp_ring) { + if (!dev_priv->cp_ring) { DRM_ERROR("could not find cp ring region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if(!dev_priv->ring_rptr) { + if (!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); @@ -1447,16 +1446,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if(!dev->agp_buffer_map) { + if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - if ( init->gart_textures_offset ) { - dev_priv->gart_textures = drm_core_findmap(dev, init->gart_textures_offset); - if ( !dev_priv->gart_textures ) { + if (init->gart_textures_offset) { + dev_priv->gart_textures = + drm_core_findmap(dev, init->gart_textures_offset); + if (!dev_priv->gart_textures) { DRM_ERROR("could not find GART texture region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); @@ -1465,17 +1465,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } dev_priv->sarea_priv = - (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + - init->sarea_priv_offset); + (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + + init->sarea_priv_offset); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { - drm_core_ioremap( dev_priv->cp_ring, dev ); - drm_core_ioremap( dev_priv->ring_rptr, dev ); - drm_core_ioremap( dev->agp_buffer_map, dev ); - if(!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { + if (!dev_priv->is_pci) { + drm_core_ioremap(dev_priv->cp_ring, dev); + drm_core_ioremap(dev_priv->ring_rptr, dev); + drm_core_ioremap(dev->agp_buffer_map, dev); + if (!dev_priv->cp_ring->handle || + !dev_priv->ring_rptr->handle || + !dev->agp_buffer_map->handle) { DRM_ERROR("could not find ioremap agp regions!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); @@ -1484,140 +1484,146 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } else #endif { - dev_priv->cp_ring->handle = - (void *)dev_priv->cp_ring->offset; + dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset; + (void *)dev_priv->ring_rptr->offset; + dev->agp_buffer_map->handle = + (void *)dev->agp_buffer_map->offset; - DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle ); - DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle ); - DRM_DEBUG( "dev->agp_buffer_map->handle %p\n", - dev->agp_buffer_map->handle ); + DRM_DEBUG("dev_priv->cp_ring->handle %p\n", + dev_priv->cp_ring->handle); + DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", + dev_priv->ring_rptr->handle); + DRM_DEBUG("dev->agp_buffer_map->handle %p\n", + dev->agp_buffer_map->handle); } - dev_priv->fb_location = ( RADEON_READ( RADEON_MC_FB_LOCATION ) - & 0xffff ) << 16; + dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) + & 0xffff) << 16; - dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | - ( ( dev_priv->front_offset - + dev_priv->fb_location ) >> 10 ) ); + dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | + ((dev_priv->front_offset + + dev_priv->fb_location) >> 10)); - dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | - ( ( dev_priv->back_offset - + dev_priv->fb_location ) >> 10 ) ); - - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | - ( ( dev_priv->depth_offset - + dev_priv->fb_location ) >> 10 ) ); + dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | + ((dev_priv->back_offset + + dev_priv->fb_location) >> 10)); + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | + ((dev_priv->depth_offset + + dev_priv->fb_location) >> 10)); dev_priv->gart_size = init->gart_size; dev_priv->gart_vm_start = dev_priv->fb_location - + RADEON_READ( RADEON_CONFIG_APER_SIZE ); + + RADEON_READ(RADEON_CONFIG_APER_SIZE); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) + if (!dev_priv->is_pci) dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->agp->base - + dev_priv->gart_vm_start); + - dev->agp->base + + dev_priv->gart_vm_start); else #endif dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->sg->handle - + dev_priv->gart_vm_start); + - dev->sg->handle + + dev_priv->gart_vm_start); - DRM_DEBUG( "dev_priv->gart_size %d\n", - dev_priv->gart_size ); - DRM_DEBUG( "dev_priv->gart_vm_start 0x%x\n", - dev_priv->gart_vm_start ); - DRM_DEBUG( "dev_priv->gart_buffers_offset 0x%lx\n", - dev_priv->gart_buffers_offset ); + DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); + DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); + DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", + dev_priv->gart_buffers_offset); - dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; - dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle + dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; + dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle + init->ring_size / sizeof(u32)); dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 ); + dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - dev_priv->ring.tail_mask = - (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { + if (!dev_priv->is_pci) { /* Turn off PCI GART */ - radeon_set_pcigart( dev_priv, 0 ); + radeon_set_pcigart(dev_priv, 0); } else #endif { /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset) { - dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.addr = (unsigned long)drm_ioremap(dev_priv->gart_info.bus_addr, RADEON_PCIGART_TABLE_SIZE, dev); + dev_priv->gart_info.bus_addr = + dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.addr = + (unsigned long)drm_ioremap(dev_priv->gart_info. + bus_addr, + RADEON_PCIGART_TABLE_SIZE, + dev); - dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); - dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; - - DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); - } - else { - dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr= 0; - if (dev_priv->flags & CHIP_IS_PCIE) - { - DRM_ERROR("Cannot use PCI Express without GART in FB memory\n"); + dev_priv->gart_info.is_pcie = + !!(dev_priv->flags & CHIP_IS_PCIE); + dev_priv->gart_info.gart_table_location = + DRM_ATI_GART_FB; + + DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", + dev_priv->gart_info.addr, + dev_priv->pcigart_offset); + } else { + dev_priv->gart_info.gart_table_location = + DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = + dev_priv->gart_info.bus_addr = 0; + if (dev_priv->flags & CHIP_IS_PCIE) { + DRM_ERROR + ("Cannot use PCI Express without GART in FB memory\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } } if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { - DRM_ERROR( "failed to init PCI GART!\n" ); + DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(ENOMEM); } /* Turn on PCI GART */ - radeon_set_pcigart( dev_priv, 1 ); + radeon_set_pcigart(dev_priv, 1); } - radeon_cp_load_microcode( dev_priv ); - radeon_cp_init_ring_buffer( dev, dev_priv ); + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); dev_priv->last_buf = 0; dev->dev_private = (void *)dev_priv; - radeon_do_engine_reset( dev ); + radeon_do_engine_reset(dev); return 0; } -static int radeon_do_cleanup_cp( drm_device_t *dev ) +static int radeon_do_cleanup_cp(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq_enabled ) drm_irq_uninstall(dev); + if (dev->irq_enabled) + drm_irq_uninstall(dev); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { - if ( dev_priv->cp_ring != NULL ) - drm_core_ioremapfree( dev_priv->cp_ring, dev ); - if ( dev_priv->ring_rptr != NULL ) - drm_core_ioremapfree( dev_priv->ring_rptr, dev ); - if ( dev->agp_buffer_map != NULL ) - { - drm_core_ioremapfree( dev->agp_buffer_map, dev ); + if (!dev_priv->is_pci) { + if (dev_priv->cp_ring != NULL) + drm_core_ioremapfree(dev_priv->cp_ring, dev); + if (dev_priv->ring_rptr != NULL) + drm_core_ioremapfree(dev_priv->ring_rptr, dev); + if (dev->agp_buffer_map != NULL) { + drm_core_ioremapfree(dev->agp_buffer_map, dev); dev->agp_buffer_map = NULL; } } else @@ -1626,103 +1632,103 @@ static int radeon_do_cleanup_cp( drm_device_t *dev ) if (dev_priv->gart_info.bus_addr) if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) DRM_ERROR("failed to cleanup PCI GART!\n"); - - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) - { - drm_ioremapfree((void *)dev_priv->gart_info.addr, RADEON_PCIGART_TABLE_SIZE, dev); + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { + drm_ioremapfree((void *)dev_priv->gart_info.addr, + RADEON_PCIGART_TABLE_SIZE, dev); dev_priv->gart_info.addr = 0; } } - + /* only clear to the start of flags */ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); return 0; } -/* This code will reinit the Radeon CP hardware after a resume from disc. - * AFAIK, it would be very difficult to pickle the state at suspend time, so +/* This code will reinit the Radeon CP hardware after a resume from disc. + * AFAIK, it would be very difficult to pickle the state at suspend time, so * here we make sure that all Radeon hardware initialisation is re-done without * affecting running applications. * * Charl P. Botha */ -static int radeon_do_resume_cp( drm_device_t *dev ) +static int radeon_do_resume_cp(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - if ( !dev_priv ) { - DRM_ERROR( "Called with no initialization\n" ); - return DRM_ERR( EINVAL ); + if (!dev_priv) { + DRM_ERROR("Called with no initialization\n"); + return DRM_ERR(EINVAL); } DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __OS_HAS_AGP - if ( !dev_priv->is_pci ) { + if (!dev_priv->is_pci) { /* Turn off PCI GART */ - radeon_set_pcigart( dev_priv, 0 ); + radeon_set_pcigart(dev_priv, 0); } else #endif { /* Turn on PCI GART */ - radeon_set_pcigart( dev_priv, 1 ); + radeon_set_pcigart(dev_priv, 1); } - radeon_cp_load_microcode( dev_priv ); - radeon_cp_init_ring_buffer( dev, dev_priv ); + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); - radeon_do_engine_reset( dev ); + radeon_do_engine_reset(dev); DRM_DEBUG("radeon_do_resume_cp() complete\n"); return 0; } - -int radeon_cp_init( DRM_IOCTL_ARGS ) +int radeon_cp_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_init_t init; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t __user *)data, sizeof(init) ); + DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data, + sizeof(init)); - if(init.func == RADEON_INIT_R300_CP) + if (init.func == RADEON_INIT_R300_CP) r300_init_reg_flags(); - switch ( init.func ) { + switch (init.func) { case RADEON_INIT_CP: case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: - return radeon_do_init_cp( dev, &init ); + return radeon_do_init_cp(dev, &init); case RADEON_CLEANUP_CP: - return radeon_do_cleanup_cp( dev ); + return radeon_do_cleanup_cp(dev); } return DRM_ERR(EINVAL); } -int radeon_cp_start( DRM_IOCTL_ARGS ) +int radeon_cp_start(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( dev_priv->cp_running ) { - DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); + if (dev_priv->cp_running) { + DRM_DEBUG("%s while CP running\n", __FUNCTION__); return 0; } - if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { - DRM_DEBUG( "%s called with bogus CP mode (%d)\n", - __FUNCTION__, dev_priv->cp_mode ); + if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { + DRM_DEBUG("%s called with bogus CP mode (%d)\n", + __FUNCTION__, dev_priv->cp_mode); return 0; } - radeon_do_cp_start( dev_priv ); + radeon_do_cp_start(dev_priv); return 0; } @@ -1730,17 +1736,18 @@ int radeon_cp_start( DRM_IOCTL_ARGS ) /* Stop the CP. The engine must have been idled before calling this * routine. */ -int radeon_cp_stop( DRM_IOCTL_ARGS ) +int radeon_cp_stop(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_cp_stop_t stop; int ret; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t __user *)data, sizeof(stop) ); + DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data, + sizeof(stop)); if (!dev_priv->cp_running) return 0; @@ -1748,32 +1755,32 @@ int radeon_cp_stop( DRM_IOCTL_ARGS ) /* Flush any pending CP commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. */ - if ( stop.flush ) { - radeon_do_cp_flush( dev_priv ); + if (stop.flush) { + radeon_do_cp_flush(dev_priv); } /* If we fail to make the engine go idle, we return an error * code so that the DRM ioctl wrapper can try again. */ - if ( stop.idle ) { - ret = radeon_do_cp_idle( dev_priv ); - if ( ret ) return ret; + if (stop.idle) { + ret = radeon_do_cp_idle(dev_priv); + if (ret) + return ret; } /* Finally, we can turn off the CP. If the engine isn't idle, * we will get some dropped triangles as they won't be fully * rendered before the CP is shut down. */ - radeon_do_cp_stop( dev_priv ); + radeon_do_cp_stop(dev_priv); /* Reset the engine */ - radeon_do_engine_reset( dev ); + radeon_do_engine_reset(dev); return 0; } - -void radeon_do_release( drm_device_t *dev ) +void radeon_do_release(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; int i, ret; @@ -1781,7 +1788,7 @@ void radeon_do_release( drm_device_t *dev ) if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ - while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { + while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { DRM_DEBUG("radeon_do_cp_idle %d\n", ret); #ifdef __linux__ schedule(); @@ -1789,47 +1796,49 @@ void radeon_do_release( drm_device_t *dev ) tsleep(&ret, PZERO, "rdnrel", 1); #endif } - radeon_do_cp_stop( dev_priv ); - radeon_do_engine_reset( dev ); + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); } /* Disable *all* interrupts */ if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - if (dev_priv->mmio) {/* remove all surfaces */ + if (dev_priv->mmio) { /* remove all surfaces */ for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0); + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + + 16 * i, 0); } } /* Free memory heap structures */ - radeon_mem_takedown( &(dev_priv->gart_heap) ); - radeon_mem_takedown( &(dev_priv->fb_heap) ); + radeon_mem_takedown(&(dev_priv->gart_heap)); + radeon_mem_takedown(&(dev_priv->fb_heap)); /* deallocate kernel resources */ - radeon_do_cleanup_cp( dev ); + radeon_do_cleanup_cp(dev); } } /* Just reset the CP ring. Called as part of an X Server engine reset. */ -int radeon_cp_reset( DRM_IOCTL_ARGS ) +int radeon_cp_reset(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_DEBUG("%s called before init done\n", __FUNCTION__); return DRM_ERR(EINVAL); } - radeon_do_cp_reset( dev_priv ); + radeon_do_cp_reset(dev_priv); /* The CP is no longer running after an engine reset */ dev_priv->cp_running = 0; @@ -1837,50 +1846,47 @@ int radeon_cp_reset( DRM_IOCTL_ARGS ) return 0; } -int radeon_cp_idle( DRM_IOCTL_ARGS ) +int radeon_cp_idle(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - return radeon_do_cp_idle( dev_priv ); + return radeon_do_cp_idle(dev_priv); } /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ -int radeon_cp_resume( DRM_IOCTL_ARGS ) +int radeon_cp_resume(DRM_IOCTL_ARGS) { DRM_DEVICE; return radeon_do_resume_cp(dev); } - -int radeon_engine_reset( DRM_IOCTL_ARGS ) +int radeon_engine_reset(DRM_IOCTL_ARGS) { DRM_DEVICE; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - return radeon_do_engine_reset( dev ); + return radeon_do_engine_reset(dev); } - /* ================================================================ * Fullscreen mode */ /* KW: Deprecated to say the least: */ -int radeon_fullscreen( DRM_IOCTL_ARGS ) +int radeon_fullscreen(DRM_IOCTL_ARGS) { return 0; } - /* ================================================================ * Freelist management */ @@ -1889,20 +1895,20 @@ int radeon_fullscreen( DRM_IOCTL_ARGS ) * bufs until freelist code is used. Note this hides a problem with * the scratch register * (used to keep track of last buffer * completed) being written to before * the last buffer has actually - * completed rendering. + * completed rendering. * * KW: It's also a good way to find free buffers quickly. * * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't * sleep. However, bugs in older versions of radeon_accel.c mean that * we essentially have to do this, else old clients will break. - * + * * However, it does leave open a potential deadlock where all the * buffers are held by other clients, which can't release them because - * they can't get the lock. + * they can't get the lock. */ -drm_buf_t *radeon_freelist_get( drm_device_t *dev ) +drm_buf_t *radeon_freelist_get(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1911,19 +1917,19 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) int i, t; int start; - if ( ++dev_priv->last_buf >= dma->buf_count ) + if (++dev_priv->last_buf >= dma->buf_count) dev_priv->last_buf = 0; start = dev_priv->last_buf; - for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { - u32 done_age = GET_SCRATCH( 1 ); - DRM_DEBUG("done_age = %d\n",done_age); - for ( i = start ; i < dma->buf_count ; i++ ) { + for (t = 0; t < dev_priv->usec_timeout; t++) { + u32 done_age = GET_SCRATCH(1); + DRM_DEBUG("done_age = %d\n", done_age); + for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->filp == 0 || (buf->pending && - buf_priv->age <= done_age) ) { + if (buf->filp == 0 || (buf->pending && + buf_priv->age <= done_age)) { dev_priv->stats.requested_bufs++; buf->pending = 0; return buf; @@ -1932,16 +1938,17 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) } if (t) { - DRM_UDELAY( 1 ); + DRM_UDELAY(1); dev_priv->stats.freelist_loops++; } } - DRM_DEBUG( "returning NULL!\n" ); + DRM_DEBUG("returning NULL!\n"); return NULL; } + #if 0 -drm_buf_t *radeon_freelist_get( drm_device_t *dev ) +drm_buf_t *radeon_freelist_get(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1951,18 +1958,18 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) int start; u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); - if ( ++dev_priv->last_buf >= dma->buf_count ) + if (++dev_priv->last_buf >= dma->buf_count) dev_priv->last_buf = 0; start = dev_priv->last_buf; dev_priv->stats.freelist_loops++; - - for ( t = 0 ; t < 2 ; t++ ) { - for ( i = start ; i < dma->buf_count ; i++ ) { + + for (t = 0; t < 2; t++) { + for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->filp == 0 || (buf->pending && - buf_priv->age <= done_age) ) { + if (buf->filp == 0 || (buf->pending && + buf_priv->age <= done_age)) { dev_priv->stats.requested_bufs++; buf->pending = 0; return buf; @@ -1975,73 +1982,74 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) } #endif -void radeon_freelist_reset( drm_device_t *dev ) +void radeon_freelist_reset(drm_device_t * dev) { drm_device_dma_t *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; int i; dev_priv->last_buf = 0; - for ( i = 0 ; i < dma->buf_count ; i++ ) { + for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[i]; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; buf_priv->age = 0; } } - /* ================================================================ * CP command submission */ -int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) +int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; - u32 last_head = GET_RING_HEAD( dev_priv ); + u32 last_head = GET_RING_HEAD(dev_priv); - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - u32 head = GET_RING_HEAD( dev_priv ); + for (i = 0; i < dev_priv->usec_timeout; i++) { + u32 head = GET_RING_HEAD(dev_priv); ring->space = (head - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) + if (ring->space <= 0) ring->space += ring->size; - if ( ring->space > n ) + if (ring->space > n) return 0; - + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; if (head != last_head) i = 0; last_head = head; - DRM_UDELAY( 1 ); + DRM_UDELAY(1); } /* FIXME: This return value is ignored in the BEGIN_RING macro! */ #if RADEON_FIFO_DEBUG - radeon_status( dev_priv ); - DRM_ERROR( "failed!\n" ); + radeon_status(dev_priv); + DRM_ERROR("failed!\n"); #endif return DRM_ERR(EBUSY); } -static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) +static int radeon_cp_get_buffers(DRMFILE filp, drm_device_t * dev, + drm_dma_t * d) { int i; drm_buf_t *buf; - for ( i = d->granted_count ; i < d->request_count ; i++ ) { - buf = radeon_freelist_get( dev ); - if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ + for (i = d->granted_count; i < d->request_count; i++) { + buf = radeon_freelist_get(dev); + if (!buf) + return DRM_ERR(EBUSY); /* NOTE: broken client */ buf->filp = filp; - if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, - sizeof(buf->idx) ) ) + if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, + sizeof(buf->idx))) return DRM_ERR(EFAULT); - if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, - sizeof(buf->total) ) ) + if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, + sizeof(buf->total))) return DRM_ERR(EFAULT); d->granted_count++; @@ -2049,7 +2057,7 @@ static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d return 0; } -int radeon_cp_buffers( DRM_IOCTL_ARGS ) +int radeon_cp_buffers(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_device_dma_t *dma = dev->dma; @@ -2057,33 +2065,33 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) drm_dma_t __user *argp = (void __user *)data; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) ); + DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); /* Please don't send us buffers. */ - if ( d.send_count != 0 ) { - DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count ); + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count); return DRM_ERR(EINVAL); } /* We'll send you buffers. */ - if ( d.request_count < 0 || d.request_count > dma->buf_count ) { - DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count ); + if (d.request_count < 0 || d.request_count > dma->buf_count) { + DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", + DRM_CURRENTPID, d.request_count, dma->buf_count); return DRM_ERR(EINVAL); } d.granted_count = 0; - if ( d.request_count ) { - ret = radeon_cp_get_buffers( filp, dev, &d ); + if (d.request_count) { + ret = radeon_cp_get_buffers(filp, dev, &d); } - DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) ); + DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); return ret; } @@ -2110,13 +2118,13 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) dev_priv->flags |= CHIP_HAS_HIERZ; break; default: - /* all other chips have no hierarchical z buffer */ + /* all other chips have no hierarchical z buffer */ break; } if (drm_device_is_agp(dev)) dev_priv->flags |= CHIP_IS_AGP; - + if (drm_device_is_pcie(dev)) dev_priv->flags |= CHIP_IS_PCIE; diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index dd526617faec..1cd81a671a36 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h @@ -57,78 +57,77 @@ #define RADEON_UPLOAD_TEX0IMAGES 0x00001000 #define RADEON_UPLOAD_TEX1IMAGES 0x00002000 #define RADEON_UPLOAD_TEX2IMAGES 0x00004000 -#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ #define RADEON_REQUIRE_QUIESCENCE 0x00010000 -#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ +#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ #define RADEON_UPLOAD_ALL 0x003effff #define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff - /* New style per-packet identifiers for use in cmd_buffer ioctl with * the RADEON_EMIT_PACKET command. Comments relate new packets to old * state bits and the packet size: */ -#define RADEON_EMIT_PP_MISC 0 /* context/7 */ -#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ -#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ -#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ -#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ -#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ -#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ -#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ -#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ -#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ -#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ -#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ -#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ -#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ -#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ -#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ -#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ -#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ -#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ -#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ -#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ -#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ -#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ -#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ -#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ -#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ -#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */ -#define R200_EMIT_TFACTOR_0 30 /* tf/7 */ -#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */ -#define R200_EMIT_VAP_CTL 32 /* vap/1 */ -#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ -#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ -#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ -#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ -#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ -#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ -#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ -#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ -#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ -#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ -#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ -#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ -#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ -#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ -#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ -#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ -#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ -#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ -#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ -#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ -#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ -#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ -#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ -#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ -#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ -#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ -#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ -#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ +#define RADEON_EMIT_PP_MISC 0 /* context/7 */ +#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ +#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ +#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ +#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ +#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ +#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ +#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ +#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ +#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ +#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ +#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ +#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ +#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ +#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ +#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ +#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ +#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ +#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ +#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ +#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ +#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ +#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ +#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ +#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ +#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ +#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */ +#define R200_EMIT_TFACTOR_0 30 /* tf/7 */ +#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */ +#define R200_EMIT_VAP_CTL 32 /* vap/1 */ +#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ +#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ +#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ +#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ +#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ +#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ +#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ +#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ +#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ +#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ +#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ +#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ +#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ +#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ +#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ +#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ +#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ +#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ +#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ +#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ +#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ +#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ +#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ +#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ +#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ +#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ #define R200_EMIT_PP_CUBIC_FACES_0 61 #define R200_EMIT_PP_CUBIC_OFFSETS_0 62 #define R200_EMIT_PP_CUBIC_FACES_1 63 @@ -167,37 +166,36 @@ /* Commands understood by cmd_buffer ioctl. More can be added but * obviously these can't be removed or changed: */ -#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ -#define RADEON_CMD_SCALARS 2 /* emit scalar data */ -#define RADEON_CMD_VECTORS 3 /* emit vector data */ -#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ -#define RADEON_CMD_PACKET3 5 /* emit hw packet */ -#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ -#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */ -#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: - * doesn't make the cpu wait, just - * the graphics hardware */ - +#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ +#define RADEON_CMD_SCALARS 2 /* emit scalar data */ +#define RADEON_CMD_VECTORS 3 /* emit vector data */ +#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ +#define RADEON_CMD_PACKET3 5 /* emit hw packet */ +#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ +#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */ +#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: + * doesn't make the cpu wait, just + * the graphics hardware */ typedef union { int i; - struct { + struct { unsigned char cmd_type, pad0, pad1, pad2; } header; - struct { + struct { unsigned char cmd_type, packet_id, pad0, pad1; } packet; - struct { - unsigned char cmd_type, offset, stride, count; + struct { + unsigned char cmd_type, offset, stride, count; } scalars; - struct { - unsigned char cmd_type, offset, stride, count; + struct { + unsigned char cmd_type, offset, stride, count; } vectors; - struct { - unsigned char cmd_type, buf_idx, pad0, pad1; + struct { + unsigned char cmd_type, buf_idx, pad0, pad1; } dma; - struct { - unsigned char cmd_type, flags, pad0, pad1; + struct { + unsigned char cmd_type, flags, pad0, pad1; } wait; } drm_radeon_cmd_header_t; @@ -213,10 +211,10 @@ typedef union { * The interface has not been stabilized, so some of these may be removed * and eventually reordered before stabilization. */ -#define R300_CMD_PACKET0 1 -#define R300_CMD_VPU 2 /* emit vertex program upload */ -#define R300_CMD_PACKET3 3 /* emit a packet3 */ -#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */ +#define R300_CMD_PACKET0 1 +#define R300_CMD_VPU 2 /* emit vertex program upload */ +#define R300_CMD_PACKET3 3 /* emit a packet3 */ +#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */ #define R300_CMD_CP_DELAY 5 #define R300_CMD_DMA_DISCARD 6 #define R300_CMD_WAIT 7 @@ -241,13 +239,13 @@ typedef union { } packet3; struct { unsigned char cmd_type, packet; - unsigned short count; /* amount of packet2 to emit */ + unsigned short count; /* amount of packet2 to emit */ } delay; struct { unsigned char cmd_type, buf_idx, pad0, pad1; } dma; struct { - unsigned char cmd_type, flags, pad0, pad1; + unsigned char cmd_type, flags, pad0, pad1; } wait; } drm_r300_cmd_header_t; @@ -301,7 +299,7 @@ typedef union { #define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT) #define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1) -#endif /* __RADEON_SAREA_DEFINES__ */ +#endif /* __RADEON_SAREA_DEFINES__ */ typedef struct { unsigned int red; @@ -312,7 +310,7 @@ typedef struct { typedef struct { /* Context state */ - unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_misc; /* 0x1c14 */ unsigned int pp_fog_color; unsigned int re_solid_color; unsigned int rb3d_blendcntl; @@ -320,7 +318,7 @@ typedef struct { unsigned int rb3d_depthpitch; unsigned int rb3d_zstencilcntl; - unsigned int pp_cntl; /* 0x1c38 */ + unsigned int pp_cntl; /* 0x1c38 */ unsigned int rb3d_cntl; unsigned int rb3d_coloroffset; unsigned int re_width_height; @@ -328,27 +326,27 @@ typedef struct { unsigned int se_cntl; /* Vertex format state */ - unsigned int se_coord_fmt; /* 0x1c50 */ + unsigned int se_coord_fmt; /* 0x1c50 */ /* Line state */ - unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_pattern; /* 0x1cd0 */ unsigned int re_line_state; - unsigned int se_line_width; /* 0x1db8 */ + unsigned int se_line_width; /* 0x1db8 */ /* Bumpmap state */ - unsigned int pp_lum_matrix; /* 0x1d00 */ + unsigned int pp_lum_matrix; /* 0x1d00 */ - unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_0; /* 0x1d58 */ unsigned int pp_rot_matrix_1; /* Mask state */ - unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ unsigned int rb3d_ropcntl; unsigned int rb3d_planemask; /* Viewport state */ - unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xscale; /* 0x1d98 */ unsigned int se_vport_xoffset; unsigned int se_vport_yscale; unsigned int se_vport_yoffset; @@ -356,20 +354,19 @@ typedef struct { unsigned int se_vport_zoffset; /* Setup state */ - unsigned int se_cntl_status; /* 0x2140 */ + unsigned int se_cntl_status; /* 0x2140 */ /* Misc state */ - unsigned int re_top_left; /* 0x26c0 */ + unsigned int re_top_left; /* 0x26c0 */ unsigned int re_misc; } drm_radeon_context_regs_t; typedef struct { /* Zbias state */ - unsigned int se_zbias_factor; /* 0x1dac */ + unsigned int se_zbias_factor; /* 0x1dac */ unsigned int se_zbias_constant; } drm_radeon_context2_regs_t; - /* Setup registers for each texture unit */ typedef struct { @@ -387,11 +384,10 @@ typedef struct { unsigned int finish; unsigned int prim:8; unsigned int stateidx:8; - unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ - unsigned int vc_format; /* vertex format */ + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; /* vertex format */ } drm_radeon_prim_t; - typedef struct { drm_radeon_context_regs_t context; drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; @@ -399,7 +395,6 @@ typedef struct { unsigned int dirty; } drm_radeon_state_t; - typedef struct { /* The channel for communication of state information to the * kernel on firing a vertex buffer with either of the @@ -422,16 +417,16 @@ typedef struct { unsigned int last_dispatch; unsigned int last_clear; - drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; + drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS + + 1]; unsigned int tex_age[RADEON_NR_TEX_HEAPS]; int ctx_owner; - int pfState; /* number of 3d windows (0,1,2ormore) */ - int pfCurrentPage; /* which buffer is being displayed? */ - int crtc2_base; /* CRTC2 frame offset */ + int pfState; /* number of 3d windows (0,1,2ormore) */ + int pfCurrentPage; /* which buffer is being displayed? */ + int crtc2_base; /* CRTC2 frame offset */ int tiling_enabled; /* set by drm, read by 2d + 3d clients */ } drm_radeon_sarea_t; - /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmRadeon.h) * @@ -441,15 +436,15 @@ typedef struct { /* Radeon specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ -#define DRM_RADEON_CP_INIT 0x00 -#define DRM_RADEON_CP_START 0x01 +#define DRM_RADEON_CP_INIT 0x00 +#define DRM_RADEON_CP_START 0x01 #define DRM_RADEON_CP_STOP 0x02 #define DRM_RADEON_CP_RESET 0x03 #define DRM_RADEON_CP_IDLE 0x04 -#define DRM_RADEON_RESET 0x05 +#define DRM_RADEON_RESET 0x05 #define DRM_RADEON_FULLSCREEN 0x06 -#define DRM_RADEON_SWAP 0x07 -#define DRM_RADEON_CLEAR 0x08 +#define DRM_RADEON_SWAP 0x07 +#define DRM_RADEON_CLEAR 0x08 #define DRM_RADEON_VERTEX 0x09 #define DRM_RADEON_INDICES 0x0A #define DRM_RADEON_NOT_USED @@ -500,7 +495,7 @@ typedef struct { typedef struct drm_radeon_init { enum { - RADEON_INIT_CP = 0x01, + RADEON_INIT_CP = 0x01, RADEON_CLEANUP_CP = 0x02, RADEON_INIT_R200_CP = 0x03, RADEON_INIT_R300_CP = 0x04 @@ -533,7 +528,7 @@ typedef struct drm_radeon_cp_stop { typedef struct drm_radeon_fullscreen { enum { - RADEON_INIT_FULLSCREEN = 0x01, + RADEON_INIT_FULLSCREEN = 0x01, RADEON_CLEANUP_FULLSCREEN = 0x02 } func; } drm_radeon_fullscreen_t; @@ -554,15 +549,15 @@ typedef struct drm_radeon_clear { unsigned int clear_color; unsigned int clear_depth; unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ + unsigned int depth_mask; /* misnamed field: should be stencil */ drm_radeon_clear_rect_t __user *depth_boxes; } drm_radeon_clear_t; typedef struct drm_radeon_vertex { int prim; - int idx; /* Index of vertex buffer */ - int count; /* Number of vertices in buffer */ - int discard; /* Client finished with buffer? */ + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ } drm_radeon_vertex_t; typedef struct drm_radeon_indices { @@ -570,7 +565,7 @@ typedef struct drm_radeon_indices { int idx; int start; int end; - int discard; /* Client finished with buffer? */ + int discard; /* Client finished with buffer? */ } drm_radeon_indices_t; /* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices @@ -578,8 +573,8 @@ typedef struct drm_radeon_indices { * - supports driver change to emit native primitives */ typedef struct drm_radeon_vertex2 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ int nr_states; drm_radeon_state_t __user *state; int nr_prims; @@ -587,10 +582,10 @@ typedef struct drm_radeon_vertex2 { } drm_radeon_vertex2_t; /* v1.3 - obsoletes drm_radeon_vertex2 - * - allows arbitarily large cliprect list + * - allows arbitarily large cliprect list * - allows updating of tcl packet, vector and scalar state * - allows memory-efficient description of state updates - * - allows state to be emitted without a primitive + * - allows state to be emitted without a primitive * (for clears, ctx switches) * - allows more than one dma buffer to be referenced per ioctl * - supports tcl driver @@ -604,7 +599,7 @@ typedef struct drm_radeon_cmd_buffer { } drm_radeon_cmd_buffer_t; typedef struct drm_radeon_tex_image { - unsigned int x, y; /* Blit coordinates */ + unsigned int x, y; /* Blit coordinates */ unsigned int width, height; const void __user *data; } drm_radeon_tex_image_t; @@ -613,7 +608,7 @@ typedef struct drm_radeon_texture { unsigned int offset; int pitch; int format; - int width; /* Texture image coordinates */ + int width; /* Texture image coordinates */ int height; drm_radeon_tex_image_t __user *image; } drm_radeon_texture_t; @@ -629,19 +624,18 @@ typedef struct drm_radeon_indirect { int discard; } drm_radeon_indirect_t; - /* 1.3: An ioctl to get parameters that aren't available to the 3d - * client any other way. + * client any other way. */ -#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */ +#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */ #define RADEON_PARAM_LAST_FRAME 2 #define RADEON_PARAM_LAST_DISPATCH 3 #define RADEON_PARAM_LAST_CLEAR 4 /* Added with DRM version 1.6. */ #define RADEON_PARAM_IRQ_NR 5 -#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */ +#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */ /* Added with DRM version 1.8. */ -#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ +#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ #define RADEON_PARAM_STATUS_HANDLE 8 #define RADEON_PARAM_SAREA_HANDLE 9 #define RADEON_PARAM_GART_TEX_HANDLE 10 @@ -672,10 +666,9 @@ typedef struct drm_radeon_mem_free { typedef struct drm_radeon_mem_init_heap { int region; int size; - int start; + int start; } drm_radeon_mem_init_heap_t; - /* 1.6: Userspace can request & wait on irq's: */ typedef struct drm_radeon_irq_emit { @@ -686,19 +679,18 @@ typedef struct drm_radeon_irq_wait { int irq_seq; } drm_radeon_irq_wait_t; - /* 1.10: Clients tell the DRM where they think the framebuffer is located in * the card's address space, via a new generic ioctl to set parameters */ typedef struct drm_radeon_setparam { unsigned int param; - int64_t value; + int64_t value; } drm_radeon_setparam_t; #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ -#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ +#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ /* 1.14: Clients can allocate/free a surface */ diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index e0682f64b400..6c1766120c10 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c @@ -29,7 +29,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ - #include #include "drmP.h" #include "drm.h" @@ -38,30 +37,28 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -73,7 +70,10 @@ extern drm_ioctl_desc_t radeon_ioctls[]; extern int radeon_max_ioctl; static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .preinit = radeon_driver_preinit, .presetup = radeon_presetup, @@ -95,21 +95,22 @@ static struct drm_driver driver = { .ioctls = radeon_ioctls, .dma_ioctl = radeon_cp_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = radeon_compat_ioctl, + .compat_ioctl = radeon_compat_ioctl, #endif - }, + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init radeon_init(void) @@ -126,6 +127,6 @@ static void __exit radeon_exit(void) module_init(radeon_init); module_exit(radeon_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 9c10141845e7..e36076981d1a 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -68,7 +68,7 @@ * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl. * Add texture rectangle support for r100. * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which - * clients use to tell the DRM where they think the framebuffer is + * clients use to tell the DRM where they think the framebuffer is * located in the card's address space * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color * and GL_EXT_blend_[func|equation]_separate on r200 @@ -134,15 +134,15 @@ enum radeon_chip_flags { CHIP_IS_IGP = 0x00020000UL, CHIP_SINGLE_CRTC = 0x00040000UL, CHIP_IS_AGP = 0x00080000UL, - CHIP_HAS_HIERZ = 0x00100000UL, + CHIP_HAS_HIERZ = 0x00100000UL, CHIP_IS_PCIE = 0x00200000UL, }; typedef struct drm_radeon_freelist { - unsigned int age; - drm_buf_t *buf; - struct drm_radeon_freelist *next; - struct drm_radeon_freelist *prev; + unsigned int age; + drm_buf_t *buf; + struct drm_radeon_freelist *next; + struct drm_radeon_freelist *prev; } drm_radeon_freelist_t; typedef struct drm_radeon_ring_buffer { @@ -204,8 +204,8 @@ typedef struct drm_radeon_private { int cp_mode; int cp_running; - drm_radeon_freelist_t *head; - drm_radeon_freelist_t *tail; + drm_radeon_freelist_t *head; + drm_radeon_freelist_t *tail; int last_buf; volatile u32 *scratch; int writeback_works; @@ -246,7 +246,7 @@ typedef struct drm_radeon_private { u32 depth_pitch_offset; drm_radeon_depth_clear_t depth_clear; - + unsigned long fb_offset; unsigned long mmio_offset; unsigned long ring_offset; @@ -264,14 +264,14 @@ typedef struct drm_radeon_private { struct mem_block *fb_heap; /* SW interrupt */ - wait_queue_head_t swi_queue; - atomic_t swi_emitted; + wait_queue_head_t swi_queue; + atomic_t swi_emitted; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; - struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; + struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; - unsigned long pcigart_offset; - drm_ati_pcigart_info gart_info; + unsigned long pcigart_offset; + drm_ati_pcigart_info gart_info; /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ @@ -282,62 +282,64 @@ typedef struct drm_radeon_buf_priv { } drm_radeon_buf_priv_t; /* radeon_cp.c */ -extern int radeon_cp_init( DRM_IOCTL_ARGS ); -extern int radeon_cp_start( DRM_IOCTL_ARGS ); -extern int radeon_cp_stop( DRM_IOCTL_ARGS ); -extern int radeon_cp_reset( DRM_IOCTL_ARGS ); -extern int radeon_cp_idle( DRM_IOCTL_ARGS ); -extern int radeon_cp_resume( DRM_IOCTL_ARGS ); -extern int radeon_engine_reset( DRM_IOCTL_ARGS ); -extern int radeon_fullscreen( DRM_IOCTL_ARGS ); -extern int radeon_cp_buffers( DRM_IOCTL_ARGS ); +extern int radeon_cp_init(DRM_IOCTL_ARGS); +extern int radeon_cp_start(DRM_IOCTL_ARGS); +extern int radeon_cp_stop(DRM_IOCTL_ARGS); +extern int radeon_cp_reset(DRM_IOCTL_ARGS); +extern int radeon_cp_idle(DRM_IOCTL_ARGS); +extern int radeon_cp_resume(DRM_IOCTL_ARGS); +extern int radeon_engine_reset(DRM_IOCTL_ARGS); +extern int radeon_fullscreen(DRM_IOCTL_ARGS); +extern int radeon_cp_buffers(DRM_IOCTL_ARGS); -extern void radeon_freelist_reset( drm_device_t *dev ); -extern drm_buf_t *radeon_freelist_get( drm_device_t *dev ); +extern void radeon_freelist_reset(drm_device_t * dev); +extern drm_buf_t *radeon_freelist_get(drm_device_t * dev); -extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); +extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); -extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); +extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); extern int radeon_presetup(struct drm_device *dev); extern int radeon_driver_postcleanup(struct drm_device *dev); -extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); -extern int radeon_mem_free( DRM_IOCTL_ARGS ); -extern int radeon_mem_init_heap( DRM_IOCTL_ARGS ); -extern void radeon_mem_takedown( struct mem_block **heap ); -extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap ); +extern int radeon_mem_alloc(DRM_IOCTL_ARGS); +extern int radeon_mem_free(DRM_IOCTL_ARGS); +extern int radeon_mem_init_heap(DRM_IOCTL_ARGS); +extern void radeon_mem_takedown(struct mem_block **heap); +extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap); /* radeon_irq.c */ -extern int radeon_irq_emit( DRM_IOCTL_ARGS ); -extern int radeon_irq_wait( DRM_IOCTL_ARGS ); +extern int radeon_irq_emit(DRM_IOCTL_ARGS); +extern int radeon_irq_wait(DRM_IOCTL_ARGS); -extern void radeon_do_release(drm_device_t *dev); -extern int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); -extern irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS ); -extern void radeon_driver_irq_preinstall( drm_device_t *dev ); -extern void radeon_driver_irq_postinstall( drm_device_t *dev ); -extern void radeon_driver_irq_uninstall( drm_device_t *dev ); -extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp); -extern void radeon_driver_pretakedown(drm_device_t *dev); -extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv); -extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv); +extern void radeon_do_release(drm_device_t * dev); +extern int radeon_driver_vblank_wait(drm_device_t * dev, + unsigned int *sequence); +extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); +extern void radeon_driver_irq_preinstall(drm_device_t * dev); +extern void radeon_driver_irq_postinstall(drm_device_t * dev); +extern void radeon_driver_irq_uninstall(drm_device_t * dev); +extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp); +extern void radeon_driver_pretakedown(drm_device_t * dev); +extern int radeon_driver_open_helper(drm_device_t * dev, + drm_file_t * filp_priv); +extern void radeon_driver_free_filp_priv(drm_device_t * dev, + drm_file_t * filp_priv); -extern int radeon_preinit( struct drm_device *dev, unsigned long flags ); -extern int radeon_postinit( struct drm_device *dev, unsigned long flags ); -extern int radeon_postcleanup( struct drm_device *dev ); +extern int radeon_preinit(struct drm_device *dev, unsigned long flags); +extern int radeon_postinit(struct drm_device *dev, unsigned long flags); +extern int radeon_postcleanup(struct drm_device *dev); extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); - /* r300_cmdbuf.c */ extern void r300_init_reg_flags(void); -extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, - drm_file_t* filp_priv, - drm_radeon_cmd_buffer_t* cmdbuf); +extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, + drm_file_t * filp_priv, + drm_radeon_cmd_buffer_t * cmdbuf); /* Flags for stats.boxes */ @@ -347,8 +349,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define RADEON_BOX_WAIT_IDLE 0x8 #define RADEON_BOX_TEXTURE_LOAD 0x10 - - /* Register definitions, register access macros and drmAddMap constants * for Radeon kernel driver. */ @@ -442,7 +442,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) - #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) @@ -650,7 +649,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, # define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) # define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) - /* CP registers */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 #define RADEON_CP_ME_RAM_RADDR 0x07d8 @@ -698,7 +696,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, # define RADEON_CP_NEXT_CHAR 0x00001900 # define RADEON_CP_PLY_NEXTSCAN 0x00001D00 # define RADEON_CP_SET_SCISSORS 0x00001E00 - /* GEN_INDX_PRIM is unsupported starting with R300 */ + /* GEN_INDX_PRIM is unsupported starting with R300 */ # define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 # define RADEON_WAIT_FOR_IDLE 0x00002600 # define RADEON_3D_DRAW_VBUF 0x00002800 @@ -782,19 +780,19 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define R200_PP_TXCBLEND_5 0x2f50 #define R200_PP_TXCBLEND_6 0x2f60 #define R200_PP_TXCBLEND_7 0x2f70 -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 +#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 #define R200_PP_TFACTOR_0 0x2ee0 #define R200_SE_VTX_FMT_0 0x2088 #define R200_SE_VAP_CNTL 0x2080 #define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFILTER_0 0x2c00 +#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 +#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 +#define R200_PP_TXFILTER_5 0x2ca0 +#define R200_PP_TXFILTER_4 0x2c80 +#define R200_PP_TXFILTER_3 0x2c60 +#define R200_PP_TXFILTER_2 0x2c40 +#define R200_PP_TXFILTER_1 0x2c20 +#define R200_PP_TXFILTER_0 0x2c00 #define R200_PP_TXOFFSET_5 0x2d78 #define R200_PP_TXOFFSET_4 0x2d60 #define R200_PP_TXOFFSET_3 0x2d48 @@ -848,13 +846,13 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define R200_RE_SCISSOR_TL_0 0x1cd8 #define R200_RE_SCISSOR_TL_1 0x1ce0 #define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 +#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 #define R200_RE_AUX_SCISSOR_CNTL 0x26f0 #define R200_SE_VTX_STATE_CNTL 0x2180 #define R200_RE_POINTSIZE 0x2648 #define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 -#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ +#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ #define RADEON_PP_TEX_SIZE_1 0x1d0c #define RADEON_PP_TEX_SIZE_2 0x1d14 @@ -875,7 +873,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b #define R200_3D_DRAW_IMMD_2 0xC0003500 #define R200_SE_VTX_FMT_1 0x208c -#define R200_RE_CNTL 0x1c50 +#define R200_RE_CNTL 0x1c50 #define R200_RB3D_BLENDCOLOR 0x3218 @@ -884,7 +882,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, #define R200_PP_TRI_PERF 0x2cf8 #define R200_PP_AFS_0 0x2f80 -#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ +#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -932,7 +930,6 @@ do { \ #define CP_PACKET3( pkt, n ) \ (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) - /* ================================================================ * Engine control helper macros */ @@ -981,12 +978,11 @@ do { \ OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ } while (0) - /* ================================================================ * Misc helper macros */ -/* Perfbox functionality only. +/* Perfbox functionality only. */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ @@ -1023,7 +1019,6 @@ do { \ OUT_RING( age ); \ } while (0) - /* ================================================================ * Ring control */ @@ -1084,7 +1079,6 @@ do { \ OUT_RING( val ); \ } while (0) - #define OUT_RING_TABLE( tab, sz ) do { \ int _size = (sz); \ int *_tab = (int *)(tab); \ @@ -1109,5 +1103,4 @@ do { \ write &= mask; \ } while (0) - -#endif /* __RADEON_DRV_H__ */ +#endif /* __RADEON_DRV_H__ */ diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c index bfe612215fb3..fef4a2b84c1e 100644 --- a/drivers/char/drm/radeon_ioc32.c +++ b/drivers/char/drm/radeon_ioc32.c @@ -94,7 +94,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init); + DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); } typedef struct drm_radeon_clear32 { @@ -102,8 +102,8 @@ typedef struct drm_radeon_clear32 { unsigned int clear_color; unsigned int clear_depth; unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ - u32 depth_boxes; + unsigned int depth_mask; /* misnamed field: should be stencil */ + u32 depth_boxes; } drm_radeon_clear32_t; static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, @@ -127,7 +127,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr); + DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); } typedef struct drm_radeon_stipple32 { @@ -137,7 +137,7 @@ typedef struct drm_radeon_stipple32 { static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, unsigned long arg) { - drm_radeon_stipple32_t __user *argp = (void __user *) arg; + drm_radeon_stipple32_t __user *argp = (void __user *)arg; drm_radeon_stipple_t __user *request; u32 mask; @@ -146,16 +146,16 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, request = compat_alloc_user_space(sizeof(*request)); if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((unsigned int __user *)(unsigned long) mask, + || __put_user((unsigned int __user *)(unsigned long)mask, &request->mask)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request); + DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); } typedef struct drm_radeon_tex_image32 { - unsigned int x, y; /* Blit coordinates */ + unsigned int x, y; /* Blit coordinates */ unsigned int width, height; u32 data; } drm_radeon_tex_image32_t; @@ -164,7 +164,7 @@ typedef struct drm_radeon_texture32 { unsigned int offset; int pitch; int format; - int width; /* Texture image coordinates */ + int width; /* Texture image coordinates */ int height; u32 image; } drm_radeon_texture32_t; @@ -177,7 +177,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, drm_radeon_tex_image32_t img32; drm_radeon_tex_image_t __user *image; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; if (req32.image == 0) return -EINVAL; @@ -206,12 +206,12 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request); + DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); } typedef struct drm_radeon_vertex2_32 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ int nr_states; u32 state; int nr_prims; @@ -224,7 +224,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, drm_radeon_vertex2_32_t req32; drm_radeon_vertex2_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -240,7 +240,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request); + DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); } typedef struct drm_radeon_cmd_buffer32 { @@ -256,7 +256,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, drm_radeon_cmd_buffer32_t req32; drm_radeon_cmd_buffer_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -270,7 +270,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request); + DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); } typedef struct drm_radeon_getparam32 { @@ -284,7 +284,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, drm_radeon_getparam32_t req32; drm_radeon_getparam_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -295,7 +295,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request); + DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); } typedef struct drm_radeon_mem_alloc32 { @@ -311,7 +311,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, drm_radeon_mem_alloc32_t req32; drm_radeon_mem_alloc_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -324,7 +324,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_ALLOC, (unsigned long) request); + DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); } typedef struct drm_radeon_irq_emit32 { @@ -337,7 +337,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, drm_radeon_irq_emit32_t req32; drm_radeon_irq_emit_t __user *request; - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) + if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; request = compat_alloc_user_space(sizeof(*request)); @@ -347,7 +347,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request); + DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); } drm_ioctl_compat_t *radeon_compat_ioctls[] = { @@ -371,8 +371,7 @@ drm_ioctl_compat_t *radeon_compat_ioctls[] = { * \param arg user argument. * \return zero on success or negative number on failure. */ -long radeon_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) +long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int nr = DRM_IOCTL_NR(cmd); drm_ioctl_compat_t *fn = NULL; @@ -386,7 +385,7 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, lock_kernel(); /* XXX for now */ if (fn != NULL) - ret = (*fn)(filp, cmd, arg); + ret = (*fn) (filp, cmd, arg); else ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 40474a65f56d..d60519de887b 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c @@ -1,7 +1,7 @@ /* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * + * * The Weather Channel (TM) funded Tungsten Graphics to develop the * initial release of the Radeon 8500 driver under the XFree86 license. * This notice must be preserved. @@ -35,7 +35,8 @@ #include "radeon_drm.h" #include "radeon_drv.h" -static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask) +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, + u32 mask) { u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; if (irqs) @@ -61,37 +62,37 @@ static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u3 * tied to dma at all, this is just a hangover from dri prehistory. */ -irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS ) +irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; - u32 stat; + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; + u32 stat; /* Only consider the bits we're interested in - others could be used * outside the DRM */ - stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); if (!stat) return IRQ_NONE; /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) { - DRM_WAKEUP( &dev_priv->swi_queue ); + DRM_WAKEUP(&dev_priv->swi_queue); } /* VBLANK interrupt */ if (stat & RADEON_CRTC_VBLANK_STAT) { atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals( dev ); + drm_vbl_send_signals(dev); } return IRQ_HANDLED; } -static int radeon_emit_irq(drm_device_t *dev) +static int radeon_emit_irq(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int ret; @@ -100,42 +101,41 @@ static int radeon_emit_irq(drm_device_t *dev) atomic_inc(&dev_priv->swi_emitted); ret = atomic_read(&dev_priv->swi_emitted); - BEGIN_RING( 4 ); - OUT_RING_REG( RADEON_LAST_SWI_REG, ret ); - OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE ); - ADVANCE_RING(); - COMMIT_RING(); + BEGIN_RING(4); + OUT_RING_REG(RADEON_LAST_SWI_REG, ret); + OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); + ADVANCE_RING(); + COMMIT_RING(); return ret; } - -static int radeon_wait_irq(drm_device_t *dev, int swi_nr) +static int radeon_wait_irq(drm_device_t * dev, int swi_nr) { - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; int ret = 0; - if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr) - return 0; + if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) + return 0; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, - RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); + DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, + RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); return ret; } -int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) { - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; unsigned int cur_vblank; int ret = 0; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } @@ -145,101 +145,100 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years - * using vertical blanks... + * using vertical blanks... */ - DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, - ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) - - *sequence ) <= (1<<23) ) ); + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; } - /* Needs the lock as it touches the ring. */ -int radeon_irq_emit( DRM_IOCTL_ARGS ) +int radeon_irq_emit(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_irq_emit_t emit; int result; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t __user *)data, - sizeof(emit) ); + DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data, + sizeof(emit)); - result = radeon_emit_irq( dev ); + result = radeon_emit_irq(dev); - if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } return 0; } - /* Doesn't need the hardware lock. */ -int radeon_irq_wait( DRM_IOCTL_ARGS ) +int radeon_irq_wait(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_irq_wait_t irqwait; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t __user*)data, - sizeof(irqwait) ); + DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data, + sizeof(irqwait)); - return radeon_wait_irq( dev, irqwait.irq_seq ); + return radeon_wait_irq(dev, irqwait.irq_seq); } - /* drm_dma.h hooks */ -void radeon_driver_irq_preinstall( drm_device_t *dev ) { +void radeon_driver_irq_preinstall(drm_device_t * dev) +{ drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; + (drm_radeon_private_t *) dev->dev_private; - /* Disable *all* interrupts */ - RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + /* Disable *all* interrupts */ + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); /* Clear bits if they're already high */ radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); } -void radeon_driver_irq_postinstall( drm_device_t *dev ) { +void radeon_driver_irq_postinstall(drm_device_t * dev) +{ drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; + (drm_radeon_private_t *) dev->dev_private; - atomic_set(&dev_priv->swi_emitted, 0); - DRM_INIT_WAITQUEUE( &dev_priv->swi_queue ); + atomic_set(&dev_priv->swi_emitted, 0); + DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); /* Turn on SW and VBL ints */ - RADEON_WRITE( RADEON_GEN_INT_CNTL, - RADEON_CRTC_VBLANK_MASK | - RADEON_SW_INT_ENABLE ); + RADEON_WRITE(RADEON_GEN_INT_CNTL, + RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE); } -void radeon_driver_irq_uninstall( drm_device_t *dev ) { +void radeon_driver_irq_uninstall(drm_device_t * dev) +{ drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *)dev->dev_private; + (drm_radeon_private_t *) dev->dev_private; if (!dev_priv) return; /* Disable *all* interrupts */ - RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); } diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c index 134f894e6e4b..030a6fad0d86 100644 --- a/drivers/char/drm/radeon_mem.c +++ b/drivers/char/drm/radeon_mem.c @@ -1,7 +1,7 @@ /* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * + * * The Weather Channel (TM) funded Tungsten Graphics to develop the * initial release of the Radeon 8500 driver under the XFree86 license. * This notice must be preserved. @@ -35,16 +35,17 @@ #include "radeon_drv.h" /* Very simple allocator for GART memory, working on a static range - * already mapped into each client's address space. + * already mapped into each client's address space. */ static struct mem_block *split_block(struct mem_block *p, int start, int size, - DRMFILE filp ) + DRMFILE filp) { /* Maybe cut off the start of an existing block */ if (start > p->start) { - struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS ); - if (!newblock) + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); + if (!newblock) goto out; newblock->start = start; newblock->size = p->size - (start - p->start); @@ -56,10 +57,11 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, p->size -= newblock->size; p = newblock; } - + /* Maybe cut off the end of an existing block */ if (size < p->size) { - struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS ); + struct mem_block *newblock = + drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); if (!newblock) goto out; newblock->start = start + size; @@ -72,40 +74,39 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, p->size = size; } - out: + out: /* Our block is in the middle */ p->filp = filp; return p; } -static struct mem_block *alloc_block( struct mem_block *heap, int size, - int align2, DRMFILE filp ) +static struct mem_block *alloc_block(struct mem_block *heap, int size, + int align2, DRMFILE filp) { struct mem_block *p; - int mask = (1 << align2)-1; + int mask = (1 << align2) - 1; list_for_each(p, heap) { int start = (p->start + mask) & ~mask; if (p->filp == 0 && start + size <= p->start + p->size) - return split_block( p, start, size, filp ); + return split_block(p, start, size, filp); } return NULL; } -static struct mem_block *find_block( struct mem_block *heap, int start ) +static struct mem_block *find_block(struct mem_block *heap, int start) { struct mem_block *p; list_for_each(p, heap) - if (p->start == start) - return p; + if (p->start == start) + return p; return NULL; } - -static void free_block( struct mem_block *p ) +static void free_block(struct mem_block *p) { p->filp = NULL; @@ -117,7 +118,7 @@ static void free_block( struct mem_block *p ) p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFS ); + drm_free(q, sizeof(*q), DRM_MEM_BUFS); } if (p->prev->filp == 0) { @@ -125,7 +126,7 @@ static void free_block( struct mem_block *p ) q->size += p->size; q->next = p->next; q->next->prev = q; - drm_free(p, sizeof(*q), DRM_MEM_BUFS ); + drm_free(p, sizeof(*q), DRM_MEM_BUFS); } } @@ -133,14 +134,14 @@ static void free_block( struct mem_block *p ) */ static int init_heap(struct mem_block **heap, int start, int size) { - struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS ); + struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); - if (!blocks) + if (!blocks) return DRM_ERR(ENOMEM); - - *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS ); + + *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); if (!*heap) { - drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS ); + drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); return DRM_ERR(ENOMEM); } @@ -149,16 +150,15 @@ static int init_heap(struct mem_block **heap, int start, int size) blocks->filp = NULL; blocks->next = blocks->prev = *heap; - memset( *heap, 0, sizeof(**heap) ); - (*heap)->filp = (DRMFILE) -1; + memset(*heap, 0, sizeof(**heap)); + (*heap)->filp = (DRMFILE) - 1; (*heap)->next = (*heap)->prev = blocks; return 0; } - /* Free all blocks associated with the releasing file. */ -void radeon_mem_release( DRMFILE filp, struct mem_block *heap ) +void radeon_mem_release(DRMFILE filp, struct mem_block *heap) { struct mem_block *p; @@ -166,7 +166,7 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap ) return; list_for_each(p, heap) { - if (p->filp == filp) + if (p->filp == filp) p->filp = NULL; } @@ -179,40 +179,37 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap ) p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q),DRM_MEM_DRIVER); + drm_free(q, sizeof(*q), DRM_MEM_DRIVER); } } } /* Shutdown. */ -void radeon_mem_takedown( struct mem_block **heap ) +void radeon_mem_takedown(struct mem_block **heap) { struct mem_block *p; - + if (!*heap) return; - for (p = (*heap)->next ; p != *heap ; ) { + for (p = (*heap)->next; p != *heap;) { struct mem_block *q = p; p = p->next; - drm_free(q, sizeof(*q),DRM_MEM_DRIVER); + drm_free(q, sizeof(*q), DRM_MEM_DRIVER); } - drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER ); + drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); *heap = NULL; } - - /* IOCTL HANDLERS */ -static struct mem_block **get_heap( drm_radeon_private_t *dev_priv, - int region ) +static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region) { - switch( region ) { + switch (region) { case RADEON_MEM_REGION_GART: - return &dev_priv->gart_heap; + return &dev_priv->gart_heap; case RADEON_MEM_REGION_FB: return &dev_priv->fb_heap; default: @@ -220,103 +217,98 @@ static struct mem_block **get_heap( drm_radeon_private_t *dev_priv, } } -int radeon_mem_alloc( DRM_IOCTL_ARGS ) +int radeon_mem_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_mem_alloc_t alloc; struct mem_block *block, **heap; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t __user *)data, - sizeof(alloc) ); + DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_mem_alloc_t __user *) data, + sizeof(alloc)); - heap = get_heap( dev_priv, alloc.region ); + heap = get_heap(dev_priv, alloc.region); if (!heap || !*heap) return DRM_ERR(EFAULT); - + /* Make things easier on ourselves: all allocations at least * 4k aligned. */ if (alloc.alignment < 12) alloc.alignment = 12; - block = alloc_block( *heap, alloc.size, alloc.alignment, - filp ); + block = alloc_block(*heap, alloc.size, alloc.alignment, filp); - if (!block) + if (!block) return DRM_ERR(ENOMEM); - if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start, - sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } - + return 0; } - - -int radeon_mem_free( DRM_IOCTL_ARGS ) +int radeon_mem_free(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_mem_free_t memfree; struct mem_block *block, **heap; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t __user *)data, - sizeof(memfree) ); + DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, + sizeof(memfree)); - heap = get_heap( dev_priv, memfree.region ); + heap = get_heap(dev_priv, memfree.region); if (!heap || !*heap) return DRM_ERR(EFAULT); - - block = find_block( *heap, memfree.region_offset ); + + block = find_block(*heap, memfree.region_offset); if (!block) return DRM_ERR(EFAULT); if (block->filp != filp) return DRM_ERR(EPERM); - free_block( block ); + free_block(block); return 0; } -int radeon_mem_init_heap( DRM_IOCTL_ARGS ) +int radeon_mem_init_heap(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_mem_init_heap_t initheap; struct mem_block **heap; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t __user *)data, - sizeof(initheap) ); + DRM_COPY_FROM_USER_IOCTL(initheap, + (drm_radeon_mem_init_heap_t __user *) data, + sizeof(initheap)); - heap = get_heap( dev_priv, initheap.region ); - if (!heap) + heap = get_heap(dev_priv, initheap.region); + if (!heap) return DRM_ERR(EFAULT); - + if (*heap) { DRM_ERROR("heap already initialized?"); return DRM_ERR(EFAULT); } - - return init_heap( heap, initheap.start, initheap.size ); + + return init_heap(heap, initheap.start, initheap.size); } - - diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 74c2fe8033c2..42e8ce4dbe99 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -37,51 +37,58 @@ * Helper functions for client state checking and fixup */ -static __inline__ int radeon_check_and_fixup_offset( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - u32 *offset ) { +static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * + dev_priv, + drm_file_t * filp_priv, + u32 * offset) +{ u32 off = *offset; struct drm_radeon_driver_file_fields *radeon_priv; - if ( off >= dev_priv->fb_location && - off < ( dev_priv->gart_vm_start + dev_priv->gart_size ) ) + if (off >= dev_priv->fb_location && + off < (dev_priv->gart_vm_start + dev_priv->gart_size)) return 0; radeon_priv = filp_priv->driver_priv; off += radeon_priv->radeon_fb_delta; - DRM_DEBUG( "offset fixed up to 0x%x\n", off ); + DRM_DEBUG("offset fixed up to 0x%x\n", off); - if ( off < dev_priv->fb_location || - off >= ( dev_priv->gart_vm_start + dev_priv->gart_size ) ) - return DRM_ERR( EINVAL ); + if (off < dev_priv->fb_location || + off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) + return DRM_ERR(EINVAL); *offset = off; return 0; } -static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - int id, - u32 __user *data ) { - switch ( id ) { +static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * + dev_priv, + drm_file_t * filp_priv, + int id, u32 __user * data) +{ + switch (id) { case RADEON_EMIT_PP_MISC: - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &data[( RADEON_RB3D_DEPTHOFFSET - - RADEON_PP_MISC ) / 4] ) ) { - DRM_ERROR( "Invalid depth buffer offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &data[(RADEON_RB3D_DEPTHOFFSET + - + RADEON_PP_MISC) / + 4])) { + DRM_ERROR("Invalid depth buffer offset\n"); + return DRM_ERR(EINVAL); } break; case RADEON_EMIT_PP_CNTL: - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &data[( RADEON_RB3D_COLOROFFSET - - RADEON_PP_CNTL ) / 4] ) ) { - DRM_ERROR( "Invalid colour buffer offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &data[(RADEON_RB3D_COLOROFFSET + - + RADEON_PP_CNTL) / + 4])) { + DRM_ERROR("Invalid colour buffer offset\n"); + return DRM_ERR(EINVAL); } break; @@ -91,21 +98,23 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case R200_EMIT_PP_TXOFFSET_3: case R200_EMIT_PP_TXOFFSET_4: case R200_EMIT_PP_TXOFFSET_5: - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &data[0] ) ) { - DRM_ERROR( "Invalid R200 texture offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &data[0])) { + DRM_ERROR("Invalid R200 texture offset\n"); + return DRM_ERR(EINVAL); } break; case RADEON_EMIT_PP_TXFILTER_0: case RADEON_EMIT_PP_TXFILTER_1: case RADEON_EMIT_PP_TXFILTER_2: - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &data[( RADEON_PP_TXOFFSET_0 - - RADEON_PP_TXFILTER_0 ) / 4] ) ) { - DRM_ERROR( "Invalid R100 texture offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &data[(RADEON_PP_TXOFFSET_0 + - + RADEON_PP_TXFILTER_0) / + 4])) { + DRM_ERROR("Invalid R100 texture offset\n"); + return DRM_ERR(EINVAL); } break; @@ -114,17 +123,18 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case R200_EMIT_PP_CUBIC_OFFSETS_2: case R200_EMIT_PP_CUBIC_OFFSETS_3: case R200_EMIT_PP_CUBIC_OFFSETS_4: - case R200_EMIT_PP_CUBIC_OFFSETS_5: { - int i; - for ( i = 0; i < 5; i++ ) { - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &data[i] ) ) { - DRM_ERROR( "Invalid R200 cubic texture offset\n" ); - return DRM_ERR( EINVAL ); + case R200_EMIT_PP_CUBIC_OFFSETS_5:{ + int i; + for (i = 0; i < 5; i++) { + if (radeon_check_and_fixup_offset + (dev_priv, filp_priv, &data[i])) { + DRM_ERROR + ("Invalid R200 cubic texture offset\n"); + return DRM_ERR(EINVAL); + } } + break; } - break; - } case RADEON_EMIT_PP_CUBIC_OFFSETS_T0: case RADEON_EMIT_PP_CUBIC_OFFSETS_T1: @@ -220,243 +230,247 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ break; default: - DRM_ERROR( "Unknown state packet ID %d\n", id ); - return DRM_ERR( EINVAL ); + DRM_ERROR("Unknown state packet ID %d\n", id); + return DRM_ERR(EINVAL); } return 0; } -static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - drm_radeon_cmd_buffer_t *cmdbuf, - unsigned int *cmdsz ) { +static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * + dev_priv, + drm_file_t * filp_priv, + drm_radeon_cmd_buffer_t * + cmdbuf, + unsigned int *cmdsz) +{ u32 *cmd = (u32 *) cmdbuf->buf; - *cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); + *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); - if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { - DRM_ERROR( "Not a type 3 packet\n" ); - return DRM_ERR( EINVAL ); + if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) { + DRM_ERROR("Not a type 3 packet\n"); + return DRM_ERR(EINVAL); } - if ( 4 * *cmdsz > cmdbuf->bufsz ) { - DRM_ERROR( "Packet size larger than size of data provided\n" ); - return DRM_ERR( EINVAL ); + if (4 * *cmdsz > cmdbuf->bufsz) { + DRM_ERROR("Packet size larger than size of data provided\n"); + return DRM_ERR(EINVAL); } /* Check client state and fix it up if necessary */ - if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ + if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */ u32 offset; - if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL - | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { + if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL + | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { - DRM_ERROR( "Invalid first packet offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset + (dev_priv, filp_priv, &offset)) { + DRM_ERROR("Invalid first packet offset\n"); + return DRM_ERR(EINVAL); } - cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10; + cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10; } - if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && - ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { + if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && + (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[3] << 10; - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { - DRM_ERROR( "Invalid second packet offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset + (dev_priv, filp_priv, &offset)) { + DRM_ERROR("Invalid second packet offset\n"); + return DRM_ERR(EINVAL); } - cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10; + cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; } } return 0; } - /* ================================================================ * CP hardware state programming functions */ -static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, - drm_clip_rect_t *box ) +static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, + drm_clip_rect_t * box) { RING_LOCALS; - DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", - box->x1, box->y1, box->x2, box->y2 ); + DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n", + box->x1, box->y1, box->x2, box->y2); - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); - OUT_RING( (box->y1 << 16) | box->x1 ); - OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); - OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0)); + OUT_RING((box->y1 << 16) | box->x1); + OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0)); + OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1)); ADVANCE_RING(); } /* Emit 1.1 state */ -static int radeon_emit_state( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - drm_radeon_context_regs_t *ctx, - drm_radeon_texture_regs_t *tex, - unsigned int dirty ) +static int radeon_emit_state(drm_radeon_private_t * dev_priv, + drm_file_t * filp_priv, + drm_radeon_context_regs_t * ctx, + drm_radeon_texture_regs_t * tex, + unsigned int dirty) { RING_LOCALS; - DRM_DEBUG( "dirty=0x%08x\n", dirty ); + DRM_DEBUG("dirty=0x%08x\n", dirty); - if ( dirty & RADEON_UPLOAD_CONTEXT ) { - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &ctx->rb3d_depthoffset ) ) { - DRM_ERROR( "Invalid depth buffer offset\n" ); - return DRM_ERR( EINVAL ); + if (dirty & RADEON_UPLOAD_CONTEXT) { + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &ctx->rb3d_depthoffset)) { + DRM_ERROR("Invalid depth buffer offset\n"); + return DRM_ERR(EINVAL); } - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &ctx->rb3d_coloroffset ) ) { - DRM_ERROR( "Invalid depth buffer offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &ctx->rb3d_coloroffset)) { + DRM_ERROR("Invalid depth buffer offset\n"); + return DRM_ERR(EINVAL); } - BEGIN_RING( 14 ); - OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); - OUT_RING( ctx->pp_misc ); - OUT_RING( ctx->pp_fog_color ); - OUT_RING( ctx->re_solid_color ); - OUT_RING( ctx->rb3d_blendcntl ); - OUT_RING( ctx->rb3d_depthoffset ); - OUT_RING( ctx->rb3d_depthpitch ); - OUT_RING( ctx->rb3d_zstencilcntl ); - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); - OUT_RING( ctx->pp_cntl ); - OUT_RING( ctx->rb3d_cntl ); - OUT_RING( ctx->rb3d_coloroffset ); - OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); - OUT_RING( ctx->rb3d_colorpitch ); + BEGIN_RING(14); + OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6)); + OUT_RING(ctx->pp_misc); + OUT_RING(ctx->pp_fog_color); + OUT_RING(ctx->re_solid_color); + OUT_RING(ctx->rb3d_blendcntl); + OUT_RING(ctx->rb3d_depthoffset); + OUT_RING(ctx->rb3d_depthpitch); + OUT_RING(ctx->rb3d_zstencilcntl); + OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2)); + OUT_RING(ctx->pp_cntl); + OUT_RING(ctx->rb3d_cntl); + OUT_RING(ctx->rb3d_coloroffset); + OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); + OUT_RING(ctx->rb3d_colorpitch); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_VERTFMT ) { - BEGIN_RING( 2 ); - OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); - OUT_RING( ctx->se_coord_fmt ); + if (dirty & RADEON_UPLOAD_VERTFMT) { + BEGIN_RING(2); + OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0)); + OUT_RING(ctx->se_coord_fmt); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_LINE ) { - BEGIN_RING( 5 ); - OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); - OUT_RING( ctx->re_line_pattern ); - OUT_RING( ctx->re_line_state ); - OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); - OUT_RING( ctx->se_line_width ); + if (dirty & RADEON_UPLOAD_LINE) { + BEGIN_RING(5); + OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1)); + OUT_RING(ctx->re_line_pattern); + OUT_RING(ctx->re_line_state); + OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0)); + OUT_RING(ctx->se_line_width); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_BUMPMAP ) { - BEGIN_RING( 5 ); - OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); - OUT_RING( ctx->pp_lum_matrix ); - OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); - OUT_RING( ctx->pp_rot_matrix_0 ); - OUT_RING( ctx->pp_rot_matrix_1 ); + if (dirty & RADEON_UPLOAD_BUMPMAP) { + BEGIN_RING(5); + OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0)); + OUT_RING(ctx->pp_lum_matrix); + OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1)); + OUT_RING(ctx->pp_rot_matrix_0); + OUT_RING(ctx->pp_rot_matrix_1); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_MASKS ) { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); - OUT_RING( ctx->rb3d_stencilrefmask ); - OUT_RING( ctx->rb3d_ropcntl ); - OUT_RING( ctx->rb3d_planemask ); + if (dirty & RADEON_UPLOAD_MASKS) { + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2)); + OUT_RING(ctx->rb3d_stencilrefmask); + OUT_RING(ctx->rb3d_ropcntl); + OUT_RING(ctx->rb3d_planemask); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_VIEWPORT ) { - BEGIN_RING( 7 ); - OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); - OUT_RING( ctx->se_vport_xscale ); - OUT_RING( ctx->se_vport_xoffset ); - OUT_RING( ctx->se_vport_yscale ); - OUT_RING( ctx->se_vport_yoffset ); - OUT_RING( ctx->se_vport_zscale ); - OUT_RING( ctx->se_vport_zoffset ); + if (dirty & RADEON_UPLOAD_VIEWPORT) { + BEGIN_RING(7); + OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5)); + OUT_RING(ctx->se_vport_xscale); + OUT_RING(ctx->se_vport_xoffset); + OUT_RING(ctx->se_vport_yscale); + OUT_RING(ctx->se_vport_yoffset); + OUT_RING(ctx->se_vport_zscale); + OUT_RING(ctx->se_vport_zoffset); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_SETUP ) { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); - OUT_RING( ctx->se_cntl ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); - OUT_RING( ctx->se_cntl_status ); + if (dirty & RADEON_UPLOAD_SETUP) { + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0)); + OUT_RING(ctx->se_cntl); + OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0)); + OUT_RING(ctx->se_cntl_status); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_MISC ) { - BEGIN_RING( 2 ); - OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); - OUT_RING( ctx->re_misc ); + if (dirty & RADEON_UPLOAD_MISC) { + BEGIN_RING(2); + OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0)); + OUT_RING(ctx->re_misc); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_TEX0 ) { - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &tex[0].pp_txoffset ) ) { - DRM_ERROR( "Invalid texture offset for unit 0\n" ); - return DRM_ERR( EINVAL ); + if (dirty & RADEON_UPLOAD_TEX0) { + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &tex[0].pp_txoffset)) { + DRM_ERROR("Invalid texture offset for unit 0\n"); + return DRM_ERR(EINVAL); } - BEGIN_RING( 9 ); - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); - OUT_RING( tex[0].pp_txfilter ); - OUT_RING( tex[0].pp_txformat ); - OUT_RING( tex[0].pp_txoffset ); - OUT_RING( tex[0].pp_txcblend ); - OUT_RING( tex[0].pp_txablend ); - OUT_RING( tex[0].pp_tfactor ); - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); - OUT_RING( tex[0].pp_border_color ); + BEGIN_RING(9); + OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5)); + OUT_RING(tex[0].pp_txfilter); + OUT_RING(tex[0].pp_txformat); + OUT_RING(tex[0].pp_txoffset); + OUT_RING(tex[0].pp_txcblend); + OUT_RING(tex[0].pp_txablend); + OUT_RING(tex[0].pp_tfactor); + OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0)); + OUT_RING(tex[0].pp_border_color); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_TEX1 ) { - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &tex[1].pp_txoffset ) ) { - DRM_ERROR( "Invalid texture offset for unit 1\n" ); - return DRM_ERR( EINVAL ); + if (dirty & RADEON_UPLOAD_TEX1) { + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &tex[1].pp_txoffset)) { + DRM_ERROR("Invalid texture offset for unit 1\n"); + return DRM_ERR(EINVAL); } - BEGIN_RING( 9 ); - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); - OUT_RING( tex[1].pp_txfilter ); - OUT_RING( tex[1].pp_txformat ); - OUT_RING( tex[1].pp_txoffset ); - OUT_RING( tex[1].pp_txcblend ); - OUT_RING( tex[1].pp_txablend ); - OUT_RING( tex[1].pp_tfactor ); - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); - OUT_RING( tex[1].pp_border_color ); + BEGIN_RING(9); + OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5)); + OUT_RING(tex[1].pp_txfilter); + OUT_RING(tex[1].pp_txformat); + OUT_RING(tex[1].pp_txoffset); + OUT_RING(tex[1].pp_txcblend); + OUT_RING(tex[1].pp_txablend); + OUT_RING(tex[1].pp_tfactor); + OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0)); + OUT_RING(tex[1].pp_border_color); ADVANCE_RING(); } - if ( dirty & RADEON_UPLOAD_TEX2 ) { - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, - &tex[2].pp_txoffset ) ) { - DRM_ERROR( "Invalid texture offset for unit 2\n" ); - return DRM_ERR( EINVAL ); + if (dirty & RADEON_UPLOAD_TEX2) { + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + &tex[2].pp_txoffset)) { + DRM_ERROR("Invalid texture offset for unit 2\n"); + return DRM_ERR(EINVAL); } - BEGIN_RING( 9 ); - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); - OUT_RING( tex[2].pp_txfilter ); - OUT_RING( tex[2].pp_txformat ); - OUT_RING( tex[2].pp_txoffset ); - OUT_RING( tex[2].pp_txcblend ); - OUT_RING( tex[2].pp_txablend ); - OUT_RING( tex[2].pp_tfactor ); - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); - OUT_RING( tex[2].pp_border_color ); + BEGIN_RING(9); + OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5)); + OUT_RING(tex[2].pp_txfilter); + OUT_RING(tex[2].pp_txformat); + OUT_RING(tex[2].pp_txoffset); + OUT_RING(tex[2].pp_txcblend); + OUT_RING(tex[2].pp_txablend); + OUT_RING(tex[2].pp_tfactor); + OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0)); + OUT_RING(tex[2].pp_border_color); ADVANCE_RING(); } @@ -465,138 +479,137 @@ static int radeon_emit_state( drm_radeon_private_t *dev_priv, /* Emit 1.2 state */ -static int radeon_emit_state2( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - drm_radeon_state_t *state ) +static int radeon_emit_state2(drm_radeon_private_t * dev_priv, + drm_file_t * filp_priv, + drm_radeon_state_t * state) { RING_LOCALS; if (state->dirty & RADEON_UPLOAD_ZBIAS) { - BEGIN_RING( 3 ); - OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); - OUT_RING( state->context2.se_zbias_factor ); - OUT_RING( state->context2.se_zbias_constant ); + BEGIN_RING(3); + OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1)); + OUT_RING(state->context2.se_zbias_factor); + OUT_RING(state->context2.se_zbias_constant); ADVANCE_RING(); } - return radeon_emit_state( dev_priv, filp_priv, &state->context, - state->tex, state->dirty ); + return radeon_emit_state(dev_priv, filp_priv, &state->context, + state->tex, state->dirty); } /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in * 1.3 cmdbuffers allow all previous state to be updated as well as - * the tcl scalar and vector areas. + * the tcl scalar and vector areas. */ -static struct { - int start; - int len; +static struct { + int start; + int len; const char *name; } packet[RADEON_MAX_STATE_PACKETS] = { - { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, - { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, - { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, - { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, - { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, - { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, - { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, - { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, - { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, - { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, - { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, - { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, - { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, - { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, - { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, - { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, - { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, - { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, - { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, - { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, - { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, - { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, - { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, - { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, - { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, - { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, - { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, - { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, - { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, - { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, - { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, - { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, - { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, - { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, - { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, - { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, - { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, - { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, - { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, - { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, - { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, - { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, - { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, - { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, - { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, - { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, - { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, - { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, - { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, - { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, - { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, - { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, - { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, - { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, - { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, - { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, - { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, - { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, - { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, - { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, - { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, - { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ - { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ - { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, - { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, - { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, - { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, - { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, - { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, - { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, - { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, - { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, - { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, - { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" }, - { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, - { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" }, - { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" }, - { R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" }, - { RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, - { RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, - { RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, - { RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, - { RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, - { RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, - { R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, - { R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ - { R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, - { R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, - { R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, - { R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, - { R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, - { R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, - { R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, - { R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, + {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, + {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, + {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, + {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, + {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, + {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, + {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, + {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, + {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, + {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, + {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, + {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, + {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, + {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, + {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, + {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, + {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, + {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, + {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, + {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, + {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, + "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, + {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, + {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, + {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, + {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, + {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, + {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, + {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, + {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, + {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, + {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, + {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, + {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, + {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, + {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, + {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, + {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, + {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, + {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, + {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, + {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, + {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, + {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, + {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, + {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, + {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, + {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, + {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, + {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, + {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, + {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, + {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, + {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, + {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, + {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, + {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, + {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, + {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, + {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, + {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, + {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, + "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, + {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ + {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ + {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, + {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, + {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, + {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, + {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, + {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, + {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, + {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, + {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, + {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, + {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, + {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, + {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, + {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, + {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, + {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, + {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, + {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, + {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, + {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, + {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, + {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, + {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ + {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, + {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, + {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, + {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, + {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, + {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, + {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, + {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, }; - - /* ================================================================ * Performance monitoring functions */ -static void radeon_clear_box( drm_radeon_private_t *dev_priv, - int x, int y, int w, int h, - int r, int g, int b ) +static void radeon_clear_box(drm_radeon_private_t * dev_priv, + int x, int y, int w, int h, int r, int g, int b) { u32 color; RING_LOCALS; @@ -604,49 +617,47 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, x += dev_priv->sarea_priv->boxes[0].x1; y += dev_priv->sarea_priv->boxes[0].y1; - switch ( dev_priv->color_fmt ) { + switch (dev_priv->color_fmt) { case RADEON_COLOR_FORMAT_RGB565: color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | - ((b & 0xf8) >> 3)); + ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; case RADEON_COLOR_FORMAT_ARGB8888: default: - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; } - BEGIN_RING( 4 ); - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( 0xffffffff ); + BEGIN_RING(4); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); + OUT_RING(0xffffffff); ADVANCE_RING(); - BEGIN_RING( 6 ); + BEGIN_RING(6); - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4)); + OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { - OUT_RING( dev_priv->front_pitch_offset ); - } else { - OUT_RING( dev_priv->back_pitch_offset ); - } + if (dev_priv->page_flipping && dev_priv->current_page == 1) { + OUT_RING(dev_priv->front_pitch_offset); + } else { + OUT_RING(dev_priv->back_pitch_offset); + } - OUT_RING( color ); + OUT_RING(color); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } -static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) +static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) { /* Collapse various things into a wait flag -- trying to * guess if userspase slept -- better just to have them tell us. @@ -662,50 +673,50 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) /* Purple box for page flipping */ - if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) - radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); + if (dev_priv->stats.boxes & RADEON_BOX_FLIP) + radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255); /* Red box if we have to wait for idle at any point */ - if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) - radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); + if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE) + radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0); /* Blue box: lost context? */ /* Yellow box for texture swaps */ - if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) - radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); + if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD) + radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0); /* Green box if hardware never idles (as far as we can tell) */ - if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) - radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) + radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); - - /* Draw bars indicating number of buffers allocated + /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) */ if (dev_priv->stats.requested_bufs) { if (dev_priv->stats.requested_bufs > 100) dev_priv->stats.requested_bufs = 100; - radeon_clear_box( dev_priv, 4, 16, - dev_priv->stats.requested_bufs, 4, - 196, 128, 128 ); + radeon_clear_box(dev_priv, 4, 16, + dev_priv->stats.requested_bufs, 4, + 196, 128, 128); } - memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) ); + memset(&dev_priv->stats, 0, sizeof(dev_priv->stats)); } + /* ================================================================ * CP command dispatch functions */ -static void radeon_cp_dispatch_clear( drm_device_t *dev, - drm_radeon_clear_t *clear, - drm_radeon_clear_rect_t *depth_boxes ) +static void radeon_cp_dispatch_clear(drm_device_t * dev, + drm_radeon_clear_t * clear, + drm_radeon_clear_rect_t * depth_boxes) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -713,32 +724,34 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; - u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; + u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0; int i; RING_LOCALS; - DRM_DEBUG( "flags = 0x%x\n", flags ); + DRM_DEBUG("flags = 0x%x\n", flags); dev_priv->stats.clears++; - if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + if (dev_priv->page_flipping && dev_priv->current_page == 1) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); - if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; - if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; + if (tmp & RADEON_FRONT) + flags |= RADEON_BACK; + if (tmp & RADEON_BACK) + flags |= RADEON_FRONT; } - if ( flags & (RADEON_FRONT | RADEON_BACK) ) { + if (flags & (RADEON_FRONT | RADEON_BACK)) { - BEGIN_RING( 4 ); + BEGIN_RING(4); /* Ensure the 3D stream is idle before doing a * 2D fill to clear the front or back buffer. */ RADEON_WAIT_UNTIL_3D_IDLE(); - - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( clear->color_mask ); + + OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); + OUT_RING(clear->color_mask); ADVANCE_RING(); @@ -746,121 +759,130 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, */ dev_priv->sarea_priv->ctx_owner = 0; - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; - DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", - x, y, w, h, flags ); + DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", + x, y, w, h, flags); - if ( flags & RADEON_FRONT ) { - BEGIN_RING( 6 ); - - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + if (flags & RADEON_FRONT) { + BEGIN_RING(6); + + OUT_RING(CP_PACKET3 + (RADEON_CNTL_PAINT_MULTI, 4)); + OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv-> + color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS); + + OUT_RING(dev_priv->front_pitch_offset); + OUT_RING(clear->clear_color); + + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); - OUT_RING( dev_priv->front_pitch_offset ); - OUT_RING( clear->clear_color ); - - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); - ADVANCE_RING(); } - - if ( flags & RADEON_BACK ) { - BEGIN_RING( 6 ); - - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); - - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( clear->clear_color ); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + if (flags & RADEON_BACK) { + BEGIN_RING(6); + + OUT_RING(CP_PACKET3 + (RADEON_CNTL_PAINT_MULTI, 4)); + OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv-> + color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS); + + OUT_RING(dev_priv->back_pitch_offset); + OUT_RING(clear->clear_color); + + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } } } - + /* hyper z clear */ /* no docs available, based on reverse engeneering by Stephane Marchesin */ - if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) { + if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) + && (flags & RADEON_CLEAR_FASTZ)) { int i; - int depthpixperline = dev_priv->depth_fmt==RADEON_DEPTH_FORMAT_16BIT_INT_Z? - (dev_priv->depth_pitch / 2): (dev_priv->depth_pitch / 4); - + int depthpixperline = + dev_priv->depth_fmt == + RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch / + 2) : (dev_priv-> + depth_pitch / 4); + u32 clearmask; u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth | - ((clear->depth_mask & 0xff) << 24); - - + ((clear->depth_mask & 0xff) << 24); + /* Make sure we restore the 3D state next time. * we haven't touched any "normal" state - still need this? */ dev_priv->sarea_priv->ctx_owner = 0; - if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { - /* FIXME : reverse engineer that for Rx00 cards */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ - /* pattern seems to work for r100, though get slight - rendering errors with glxgears. If hierz is not enabled for r100, - only 4 bits which indicate clear (15,16,31,32, all zero) matter, the - other ones are ignored, and the same clear mask can be used. That's - very different behaviour than R200 which needs different clear mask - and different number of tiles to clear if hierz is enabled or not !?! - */ - clearmask = (0xff<<22)|(0xff<<6)| 0x003f003f; - } - else { - /* clear mask : chooses the clearing pattern. - rv250: could be used to clear only parts of macrotiles - (but that would get really complicated...)? - bit 0 and 1 (either or both of them ?!?!) are used to - not clear tile (or maybe one of the bits indicates if the tile is - compressed or not), bit 2 and 3 to not clear tile 1,...,. - Pattern is as follows: - | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29| - bits ------------------------------------------------- - | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31| - rv100: clearmask covers 2x8 4x1 tiles, but one clear still - covers 256 pixels ?!? - */ + if ((dev_priv->flags & CHIP_HAS_HIERZ) + && (flags & RADEON_USE_HIERZ)) { + /* FIXME : reverse engineer that for Rx00 cards */ + /* FIXME : the mask supposedly contains low-res z values. So can't set + just to the max (0xff? or actually 0x3fff?), need to take z clear + value into account? */ + /* pattern seems to work for r100, though get slight + rendering errors with glxgears. If hierz is not enabled for r100, + only 4 bits which indicate clear (15,16,31,32, all zero) matter, the + other ones are ignored, and the same clear mask can be used. That's + very different behaviour than R200 which needs different clear mask + and different number of tiles to clear if hierz is enabled or not !?! + */ + clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f; + } else { + /* clear mask : chooses the clearing pattern. + rv250: could be used to clear only parts of macrotiles + (but that would get really complicated...)? + bit 0 and 1 (either or both of them ?!?!) are used to + not clear tile (or maybe one of the bits indicates if the tile is + compressed or not), bit 2 and 3 to not clear tile 1,...,. + Pattern is as follows: + | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29| + bits ------------------------------------------------- + | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31| + rv100: clearmask covers 2x8 4x1 tiles, but one clear still + covers 256 pixels ?!? + */ clearmask = 0x0; } - BEGIN_RING( 8 ); + BEGIN_RING(8); RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING_REG( RADEON_RB3D_DEPTHCLEARVALUE, - tempRB3D_DEPTHCLEARVALUE); + OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE, + tempRB3D_DEPTHCLEARVALUE); /* what offset is this exactly ? */ - OUT_RING_REG( RADEON_RB3D_ZMASKOFFSET, 0 ); + OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0); /* need ctlstat, otherwise get some strange black flickering */ - OUT_RING_REG( RADEON_RB3D_ZCACHE_CTLSTAT, RADEON_RB3D_ZC_FLUSH_ALL ); + OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT, + RADEON_RB3D_ZC_FLUSH_ALL); ADVANCE_RING(); for (i = 0; i < nbox; i++) { int tileoffset, nrtilesx, nrtilesy, j; /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ - if ((dev_priv->flags&CHIP_HAS_HIERZ) && !(dev_priv->microcode_version==UCODE_R200)) { + if ((dev_priv->flags & CHIP_HAS_HIERZ) + && !(dev_priv->microcode_version == UCODE_R200)) { /* FIXME : figure this out for r200 (when hierz is enabled). Or maybe r200 actually doesn't need to put the low-res z value into the tile cache like r100, but just needs to clear the hi-level z-buffer? @@ -868,59 +890,74 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, R100 seems to operate on 2x1 8x8 tiles, but... odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially problematic with resolutions which are not 64 pix aligned? */ - tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 6; - nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); + tileoffset = + ((pbox[i].y1 >> 3) * depthpixperline + + pbox[i].x1) >> 6; + nrtilesx = + ((pbox[i].x2 & ~63) - + (pbox[i].x1 & ~63)) >> 4; + nrtilesy = + (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) ); + BEGIN_RING(4); + OUT_RING(CP_PACKET3 + (RADEON_3D_CLEAR_ZMASK, 2)); /* first tile */ - OUT_RING( tileoffset * 8 ); + OUT_RING(tileoffset * 8); /* the number of tiles to clear */ - OUT_RING( nrtilesx + 4 ); + OUT_RING(nrtilesx + 4); /* clear mask : chooses the clearing pattern. */ - OUT_RING( clearmask ); + OUT_RING(clearmask); ADVANCE_RING(); tileoffset += depthpixperline >> 6; } - } - else if (dev_priv->microcode_version==UCODE_R200) { + } else if (dev_priv->microcode_version == UCODE_R200) { /* works for rv250. */ /* find first macro tile (8x2 4x4 z-pixels on rv250) */ - tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 5; - nrtilesx = (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5); - nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); + tileoffset = + ((pbox[i].y1 >> 3) * depthpixperline + + pbox[i].x1) >> 5; + nrtilesx = + (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5); + nrtilesy = + (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) ); + BEGIN_RING(4); + OUT_RING(CP_PACKET3 + (RADEON_3D_CLEAR_ZMASK, 2)); /* first tile */ /* judging by the first tile offset needed, could possibly directly address/clear 4x4 tiles instead of 8x2 * 4x4 macro tiles, though would still need clear mask for right/bottom if truely 4x4 granularity is desired ? */ - OUT_RING( tileoffset * 16 ); + OUT_RING(tileoffset * 16); /* the number of tiles to clear */ - OUT_RING( nrtilesx + 1 ); + OUT_RING(nrtilesx + 1); /* clear mask : chooses the clearing pattern. */ - OUT_RING( clearmask ); + OUT_RING(clearmask); ADVANCE_RING(); tileoffset += depthpixperline >> 5; } - } - else { /* rv 100 */ + } else { /* rv 100 */ /* rv100 might not need 64 pix alignment, who knows */ /* offsets are, hmm, weird */ - tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6; - nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4); + tileoffset = + ((pbox[i].y1 >> 4) * depthpixperline + + pbox[i].x1) >> 6; + nrtilesx = + ((pbox[i].x2 & ~63) - + (pbox[i].x1 & ~63)) >> 4; + nrtilesy = + (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4); for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) ); - OUT_RING( tileoffset * 128 ); + BEGIN_RING(4); + OUT_RING(CP_PACKET3 + (RADEON_3D_CLEAR_ZMASK, 2)); + OUT_RING(tileoffset * 128); /* the number of tiles to clear */ - OUT_RING( nrtilesx + 4 ); + OUT_RING(nrtilesx + 4); /* clear mask : chooses the clearing pattern. */ - OUT_RING( clearmask ); + OUT_RING(clearmask); ADVANCE_RING(); tileoffset += depthpixperline >> 6; } @@ -928,18 +965,19 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, } /* TODO don't always clear all hi-level z tiles */ - if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200) - && (flags & RADEON_USE_HIERZ)) - /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ + if ((dev_priv->flags & CHIP_HAS_HIERZ) + && (dev_priv->microcode_version == UCODE_R200) + && (flags & RADEON_USE_HIERZ)) + /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ + /* FIXME : the mask supposedly contains low-res z values. So can't set + just to the max (0xff? or actually 0x3fff?), need to take z clear + value into account? */ { - BEGIN_RING( 4 ); - OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) ); - OUT_RING( 0x0 ); /* First tile */ - OUT_RING( 0x3cc0 ); - OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f); + BEGIN_RING(4); + OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2)); + OUT_RING(0x0); /* First tile */ + OUT_RING(0x3cc0); + OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f); ADVANCE_RING(); } } @@ -974,30 +1012,27 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, tempSE_CNTL = depth_clear->se_cntl; - - /* Disable TCL */ - tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ - (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); + tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ + (0x9 << + SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); tempRB3D_PLANEMASK = 0x0; tempRE_AUX_SCISSOR_CNTL = 0x0; tempSE_VTE_CNTL = - SE_VTE_CNTL__VTX_XY_FMT_MASK | - SE_VTE_CNTL__VTX_Z_FMT_MASK; + SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK; - /* Vertex format (X, Y, Z, W)*/ + /* Vertex format (X, Y, Z, W) */ tempSE_VTX_FMT_0 = - SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | - SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; + SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | + SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; tempSE_VTX_FMT_1 = 0x0; - - /* - * Depth buffer specific enables + /* + * Depth buffer specific enables */ if (flags & RADEON_DEPTH) { /* Enable depth buffer */ @@ -1007,12 +1042,12 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, tempRB3D_CNTL &= ~RADEON_Z_ENABLE; } - /* + /* * Stencil buffer specific enables */ - if ( flags & RADEON_STENCIL ) { - tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; - tempRB3D_STENCILREFMASK = clear->depth_mask; + if (flags & RADEON_STENCIL) { + tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; + tempRB3D_STENCILREFMASK = clear->depth_mask; } else { tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; tempRB3D_STENCILREFMASK = 0x00000000; @@ -1020,79 +1055,75 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, if (flags & RADEON_USE_COMP_ZBUF) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; + RADEON_Z_DECOMPRESSION_ENABLE; } if (flags & RADEON_USE_HIERZ) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; } - BEGIN_RING( 26 ); + BEGIN_RING(26); RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); - OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); - OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); - OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, - tempRB3D_ZSTENCILCNTL ); - OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, - tempRB3D_STENCILREFMASK ); - OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); - OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); - OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); - OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); - OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); - OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); - OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, - tempRE_AUX_SCISSOR_CNTL ); + OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL); + OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL); + OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL); + OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); + OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, + tempRB3D_STENCILREFMASK); + OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK); + OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL); + OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL); + OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0); + OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1); + OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL); + OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->ctx_owner = 0; - for ( i = 0 ; i < nbox ; i++ ) { - - /* Funny that this should be required -- + for (i = 0; i < nbox; i++) { + + /* Funny that this should be required -- * sets top-left? */ - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - BEGIN_RING( 14 ); - OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); - OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - (3 << RADEON_NUM_VERTICES_SHIFT)) ); - OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x3f800000 ); - OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x3f800000 ); - OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x3f800000 ); + BEGIN_RING(14); + OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12)); + OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + (3 << RADEON_NUM_VERTICES_SHIFT))); + OUT_RING(depth_boxes[i].ui[CLEAR_X1]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x3f800000); + OUT_RING(depth_boxes[i].ui[CLEAR_X1]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x3f800000); + OUT_RING(depth_boxes[i].ui[CLEAR_X2]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x3f800000); ADVANCE_RING(); } - } - else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { + } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) { int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; rb3d_cntl = depth_clear->rb3d_cntl; - if ( flags & RADEON_DEPTH ) { - rb3d_cntl |= RADEON_Z_ENABLE; + if (flags & RADEON_DEPTH) { + rb3d_cntl |= RADEON_Z_ENABLE; } else { rb3d_cntl &= ~RADEON_Z_ENABLE; } - if ( flags & RADEON_STENCIL ) { - rb3d_cntl |= RADEON_STENCIL_ENABLE; - rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ + if (flags & RADEON_STENCIL) { + rb3d_cntl |= RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ } else { rb3d_cntl &= ~RADEON_STENCIL_ENABLE; rb3d_stencilrefmask = 0x00000000; @@ -1100,66 +1131,61 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, if (flags & RADEON_USE_COMP_ZBUF) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; + RADEON_Z_DECOMPRESSION_ENABLE; } if (flags & RADEON_USE_HIERZ) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; } - BEGIN_RING( 13 ); + BEGIN_RING(13); RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); - OUT_RING( 0x00000000 ); - OUT_RING( rb3d_cntl ); - - OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL ); - OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, - rb3d_stencilrefmask ); - OUT_RING_REG( RADEON_RB3D_PLANEMASK, - 0x00000000 ); - OUT_RING_REG( RADEON_SE_CNTL, - depth_clear->se_cntl ); + OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1)); + OUT_RING(0x00000000); + OUT_RING(rb3d_cntl); + + OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); + OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask); + OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000); + OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->ctx_owner = 0; - for ( i = 0 ; i < nbox ; i++ ) { - - /* Funny that this should be required -- + for (i = 0; i < nbox; i++) { + + /* Funny that this should be required -- * sets top-left? */ - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - BEGIN_RING( 15 ); + BEGIN_RING(15); - OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); - OUT_RING( RADEON_VTX_Z_PRESENT | - RADEON_VTX_PKCOLOR_PRESENT); - OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - RADEON_MAOS_ENABLE | - RADEON_VTX_FMT_RADEON_MODE | - (3 << RADEON_NUM_VERTICES_SHIFT)) ); + OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13)); + OUT_RING(RADEON_VTX_Z_PRESENT | + RADEON_VTX_PKCOLOR_PRESENT); + OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + RADEON_MAOS_ENABLE | + RADEON_VTX_FMT_RADEON_MODE | + (3 << RADEON_NUM_VERTICES_SHIFT))); + OUT_RING(depth_boxes[i].ui[CLEAR_X1]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x0); - OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x0 ); + OUT_RING(depth_boxes[i].ui[CLEAR_X1]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x0); - OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x0 ); - - OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); - OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); - OUT_RING( 0x0 ); + OUT_RING(depth_boxes[i].ui[CLEAR_X2]); + OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); + OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); + OUT_RING(0x0); ADVANCE_RING(); } @@ -1171,15 +1197,15 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, */ dev_priv->sarea_priv->last_clear++; - BEGIN_RING( 4 ); + BEGIN_RING(4); - RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); + RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_swap( drm_device_t *dev ) +static void radeon_cp_dispatch_swap(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1187,59 +1213,55 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) - radeon_cp_performance_boxes( dev_priv ); - + radeon_cp_performance_boxes(dev_priv); /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. */ - BEGIN_RING( 2 ); + BEGIN_RING(2); RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); - for ( i = 0 ; i < nbox ; i++ ) { + for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; - DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n", - x, y, w, h ); + DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h); - BEGIN_RING( 7 ); + BEGIN_RING(7); + + OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); + OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | - RADEON_GMC_WR_MSK_DIS ); - /* Make this work even if front & back are flipped: */ if (dev_priv->current_page == 0) { - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( dev_priv->front_pitch_offset ); - } - else { - OUT_RING( dev_priv->front_pitch_offset ); - OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING(dev_priv->back_pitch_offset); + OUT_RING(dev_priv->front_pitch_offset); + } else { + OUT_RING(dev_priv->front_pitch_offset); + OUT_RING(dev_priv->back_pitch_offset); } - OUT_RING( (x << 16) | y ); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + OUT_RING((x << 16) | y); + OUT_RING((x << 16) | y); + OUT_RING((w << 16) | h); ADVANCE_RING(); } @@ -1250,44 +1272,43 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) */ dev_priv->sarea_priv->last_frame++; - BEGIN_RING( 4 ); + BEGIN_RING(4); - RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_flip( drm_device_t *dev ) +static void radeon_cp_dispatch_flip(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; + drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle; int offset = (dev_priv->current_page == 1) - ? dev_priv->front_offset : dev_priv->back_offset; + ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; - DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", - __FUNCTION__, - dev_priv->current_page, - dev_priv->sarea_priv->pfCurrentPage); + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) { dev_priv->stats.boxes |= RADEON_BOX_FLIP; - radeon_cp_performance_boxes( dev_priv ); + radeon_cp_performance_boxes(dev_priv); } /* Update the frame offsets for both CRTCs */ - BEGIN_RING( 6 ); + BEGIN_RING(6); RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch - + sarea->frame.x - * ( dev_priv->color_fmt - 2 ) ) & ~7 ) - + offset ); - OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base - + offset ); + OUT_RING_REG(RADEON_CRTC_OFFSET, + ((sarea->frame.y * dev_priv->front_pitch + + sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7) + + offset); + OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + + offset); ADVANCE_RING(); @@ -1297,16 +1318,16 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) */ dev_priv->sarea_priv->last_frame++; dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = - 1 - dev_priv->current_page; + 1 - dev_priv->current_page; - BEGIN_RING( 2 ); + BEGIN_RING(2); - RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); ADVANCE_RING(); } -static int bad_prim_vertex_nr( int primitive, int nr ) +static int bad_prim_vertex_nr(int primitive, int nr) { switch (primitive & RADEON_PRIM_TYPE_MASK) { case RADEON_PRIM_TYPE_NONE: @@ -1326,24 +1347,21 @@ static int bad_prim_vertex_nr( int primitive, int nr ) return nr < 3; default: return 1; - } + } } - - typedef struct { unsigned int start; unsigned int finish; unsigned int prim; unsigned int numverts; - unsigned int offset; - unsigned int vc_format; + unsigned int offset; + unsigned int vc_format; } drm_radeon_tcl_prim_t; -static void radeon_cp_dispatch_vertex( drm_device_t *dev, - drm_buf_t *buf, - drm_radeon_tcl_prim_t *prim ) - +static void radeon_cp_dispatch_vertex(drm_device_t * dev, + drm_buf_t * buf, + drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1355,45 +1373,39 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", prim->prim, - prim->vc_format, - prim->start, - prim->finish, - prim->numverts); + prim->vc_format, prim->start, prim->finish, prim->numverts); - if (bad_prim_vertex_nr( prim->prim, prim->numverts )) { - DRM_ERROR( "bad prim %x numverts %d\n", - prim->prim, prim->numverts ); + if (bad_prim_vertex_nr(prim->prim, prim->numverts)) { + DRM_ERROR("bad prim %x numverts %d\n", + prim->prim, prim->numverts); return; } do { /* Emit the next cliprect */ - if ( i < nbox ) { - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + if (i < nbox) { + radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); } /* Emit the vertex buffer rendering commands */ - BEGIN_RING( 5 ); + BEGIN_RING(5); - OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); - OUT_RING( offset ); - OUT_RING( numverts ); - OUT_RING( prim->vc_format ); - OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (numverts << RADEON_NUM_VERTICES_SHIFT) ); + OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3)); + OUT_RING(offset); + OUT_RING(numverts); + OUT_RING(prim->vc_format); + OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (numverts << RADEON_NUM_VERTICES_SHIFT)); ADVANCE_RING(); i++; - } while ( i < nbox ); + } while (i < nbox); } - - -static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ) +static void radeon_cp_discard_buffer(drm_device_t * dev, drm_buf_t * buf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -1402,24 +1414,22 @@ static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ) buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); + BEGIN_RING(2); + RADEON_DISPATCH_AGE(buf_priv->age); ADVANCE_RING(); buf->pending = 1; buf->used = 0; } -static void radeon_cp_dispatch_indirect( drm_device_t *dev, - drm_buf_t *buf, - int start, int end ) +static void radeon_cp_dispatch_indirect(drm_device_t * dev, + drm_buf_t * buf, int start, int end) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", - buf->idx, start, end ); + DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - if ( start != end ) { + if (start != end) { int offset = (dev_priv->gart_buffers_offset + buf->offset + start); int dwords = (end - start + 3) / sizeof(u32); @@ -1428,28 +1438,27 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, * dwords, so if we've been given an odd number we must * pad the data with a Type-2 CP packet. */ - if ( dwords & 1 ) { + if (dwords & 1) { u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); + ((char *)dev->agp_buffer_map->handle + + buf->offset + start); data[dwords++] = RADEON_CP_PACKET2; } /* Fire off the indirect buffer */ - BEGIN_RING( 3 ); + BEGIN_RING(3); - OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) ); - OUT_RING( offset ); - OUT_RING( dwords ); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(offset); + OUT_RING(dwords); ADVANCE_RING(); } } - -static void radeon_cp_dispatch_indices( drm_device_t *dev, - drm_buf_t *elt_buf, - drm_radeon_tcl_prim_t *prim ) +static void radeon_cp_dispatch_indices(drm_device_t * dev, + drm_buf_t * elt_buf, + drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1464,30 +1473,24 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", prim->prim, prim->vc_format, - prim->start, - prim->finish, - prim->offset, - prim->numverts); + prim->start, prim->finish, prim->offset, prim->numverts); - if (bad_prim_vertex_nr( prim->prim, count )) { - DRM_ERROR( "bad prim %x count %d\n", - prim->prim, count ); + if (bad_prim_vertex_nr(prim->prim, count)) { + DRM_ERROR("bad prim %x count %d\n", prim->prim, count); return; } - - if ( start >= prim->finish || - (prim->start & 0x7) ) { - DRM_ERROR( "buffer prim %d\n", prim->prim ); + if (start >= prim->finish || (prim->start & 0x7)) { + DRM_ERROR("buffer prim %d\n", prim->prim); return; } dwords = (prim->finish - prim->start + 3) / sizeof(u32); - data = (u32 *)((char *)dev->agp_buffer_map->handle + - elt_buf->offset + prim->start); + data = (u32 *) ((char *)dev->agp_buffer_map->handle + + elt_buf->offset + prim->start); - data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); + data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2); data[1] = offset; data[2] = prim->numverts; data[3] = prim->vc_format; @@ -1495,28 +1498,26 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, RADEON_PRIM_WALK_IND | RADEON_COLOR_ORDER_RGBA | RADEON_VTX_FMT_RADEON_MODE | - (count << RADEON_NUM_VERTICES_SHIFT) ); + (count << RADEON_NUM_VERTICES_SHIFT)); do { - if ( i < nbox ) - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); + if (i < nbox) + radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - radeon_cp_dispatch_indirect( dev, elt_buf, - prim->start, - prim->finish ); + radeon_cp_dispatch_indirect(dev, elt_buf, + prim->start, prim->finish); i++; - } while ( i < nbox ); + } while (i < nbox); } #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE -static int radeon_cp_dispatch_texture( DRMFILE filp, - drm_device_t *dev, - drm_radeon_texture_t *tex, - drm_radeon_tex_image_t *image ) +static int radeon_cp_dispatch_texture(DRMFILE filp, + drm_device_t * dev, + drm_radeon_texture_t * tex, + drm_radeon_tex_image_t * image) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; @@ -1531,11 +1532,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, u32 offset; RING_LOCALS; - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &tex->offset ) ) { - DRM_ERROR( "Invalid destination offset\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &tex->offset)) { + DRM_ERROR("Invalid destination offset\n"); + return DRM_ERR(EINVAL); } dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; @@ -1544,7 +1545,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, * up with the texture data from the host data blit, otherwise * part of the texture image may be corrupted. */ - BEGIN_RING( 4 ); + BEGIN_RING(4); RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); @@ -1553,7 +1554,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, * even if the only legal values are powers of two. Thus, we'll * use a shift instead. */ - switch ( tex->format ) { + switch (tex->format) { case RADEON_TXFORMAT_ARGB8888: case RADEON_TXFORMAT_RGBA8888: format = RADEON_COLOR_FORMAT_ARGB8888; @@ -1577,7 +1578,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, blit_width = image->width * 1; break; default: - DRM_ERROR( "invalid texture format %d\n", tex->format ); + DRM_ERROR("invalid texture format %d\n", tex->format); return DRM_ERR(EINVAL); } spitch = blit_width >> 6; @@ -1592,49 +1593,49 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, /* we got tiled coordinates, untile them */ image->x *= 2; } - } - else microtile = 0; + } else + microtile = 0; - DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); + DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width); do { - DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - tex->offset >> 10, tex->pitch, tex->format, - image->x, image->y, image->width, image->height ); + DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + tex->offset >> 10, tex->pitch, tex->format, + image->x, image->y, image->width, image->height); /* Make a copy of some parameters in case we have to * update them for a multi-pass texture blit. */ height = image->height; data = (const u8 __user *)image->data; - + size = height * blit_width; - if ( size > RADEON_MAX_TEXTURE_SIZE ) { + if (size > RADEON_MAX_TEXTURE_SIZE) { height = RADEON_MAX_TEXTURE_SIZE / blit_width; size = height * blit_width; - } else if ( size < 4 && size > 0 ) { + } else if (size < 4 && size > 0) { size = 4; - } else if ( size == 0 ) { + } else if (size == 0) { return 0; } - buf = radeon_freelist_get( dev ); - if ( 0 && !buf ) { - radeon_do_cp_idle( dev_priv ); - buf = radeon_freelist_get( dev ); + buf = radeon_freelist_get(dev); + if (0 && !buf) { + radeon_do_cp_idle(dev_priv); + buf = radeon_freelist_get(dev); } - if ( !buf ) { + if (!buf) { DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); - if (DRM_COPY_TO_USER( tex->image, image, sizeof(*image) )) + if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) return DRM_ERR(EFAULT); return DRM_ERR(EAGAIN); } - /* Dispatch the indirect buffer. */ - buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset); + buffer = + (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); dwords = size / 4; if (microtile) { @@ -1649,20 +1650,26 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, if (tex->height == 1) { if (tex_width >= 64 || tex_width <= 16) { if (DRM_COPY_FROM_USER(buffer, data, - tex_width * sizeof(u32))) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + tex_width * + sizeof(u32))) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } } else if (tex_width == 32) { - if (DRM_COPY_FROM_USER(buffer, data, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } - if (DRM_COPY_FROM_USER(buffer + 8, data + 16, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer + 8, data + 16, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } } @@ -1675,9 +1682,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, } } else if (tex_width < 16) { for (i = 0; i < tex->height; i++) { - if (DRM_COPY_FROM_USER(buffer, data, tex_width)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer, data, tex_width)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } buffer += 4; @@ -1687,35 +1696,42 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, /* TODO: make sure this works when not fitting in one buffer (i.e. 32bytes x 2048...) */ for (i = 0; i < tex->height; i += 2) { - if (DRM_COPY_FROM_USER(buffer, data, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } data += 16; - if (DRM_COPY_FROM_USER(buffer + 8, data, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer + 8, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } data += 16; - if (DRM_COPY_FROM_USER(buffer + 4, data, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer + 4, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } data += 16; - if (DRM_COPY_FROM_USER(buffer + 12, data, 16)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", - tex_width); + if (DRM_COPY_FROM_USER + (buffer + 12, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } data += 16; buffer += 16; } } - } - else { + } else { if (tex_width >= 32) { /* Texture image width is larger than the minimum, so we * can upload it directly. @@ -1731,9 +1747,12 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, * need to pad out each image scanline to the minimum * width. */ - for (i = 0 ; i < tex->height ; i++) { - if (DRM_COPY_FROM_USER(buffer, data, tex_width )) { - DRM_ERROR("EFAULT on pad, %d bytes\n", tex_width); + for (i = 0; i < tex->height; i++) { + if (DRM_COPY_FROM_USER + (buffer, data, tex_width)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); return DRM_ERR(EFAULT); } buffer += 8; @@ -1754,8 +1773,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | - RADEON_GMC_WR_MSK_DIS ); + RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); OUT_RING((spitch << 22) | (offset >> 10)); OUT_RING((texpitch << 22) | (tex->offset >> 10)); OUT_RING(0); @@ -1776,62 +1794,62 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, * the texture data is written out to memory before rendering * continues. */ - BEGIN_RING( 4 ); + BEGIN_RING(4); RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); return 0; } - -static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple) { drm_radeon_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - BEGIN_RING( 35 ); + BEGIN_RING(35); - OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) ); - OUT_RING( 0x00000000 ); + OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0)); + OUT_RING(0x00000000); - OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) ); - for ( i = 0 ; i < 32 ; i++ ) { - OUT_RING( stipple[i] ); + OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31)); + for (i = 0; i < 32; i++) { + OUT_RING(stipple[i]); } ADVANCE_RING(); } -static void radeon_apply_surface_regs(int surf_index, drm_radeon_private_t *dev_priv) +static void radeon_apply_surface_regs(int surf_index, + drm_radeon_private_t * dev_priv) { if (!dev_priv->mmio) return; radeon_do_cp_idle(dev_priv); - RADEON_WRITE(RADEON_SURFACE0_INFO + 16*surf_index, - dev_priv->surfaces[surf_index].flags); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*surf_index, - dev_priv->surfaces[surf_index].lower); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*surf_index, - dev_priv->surfaces[surf_index].upper); + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index, + dev_priv->surfaces[surf_index].flags); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index, + dev_priv->surfaces[surf_index].lower); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index, + dev_priv->surfaces[surf_index].upper); } - /* Allocates a virtual surface - * doesn't always allocate a real surface, will stretch an existing + * doesn't always allocate a real surface, will stretch an existing * surface when possible. * * Note that refcount can be at most 2, since during a free refcount=3 * might mean we have to allocate a new surface which might not always * be available. - * For example : we allocate three contigous surfaces ABC. If B is + * For example : we allocate three contigous surfaces ABC. If B is * freed, we suddenly need two surfaces to store A and C, which might * not always be available. */ -static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *dev_priv, DRMFILE filp) +static int alloc_surface(drm_radeon_surface_alloc_t * new, + drm_radeon_private_t * dev_priv, DRMFILE filp) { struct radeon_virt_surface *s; int i; @@ -1843,34 +1861,37 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t * /* sanity check */ if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) || - ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != RADEON_SURF_ADDRESS_FIXED_MASK) || - ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0)) + ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != + RADEON_SURF_ADDRESS_FIXED_MASK) + || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0)) return -1; /* make sure there is no overlap with existing surfaces */ for (i = 0; i < RADEON_MAX_SURFACES; i++) { if ((dev_priv->surfaces[i].refcount != 0) && - (( (new_lower >= dev_priv->surfaces[i].lower) && - (new_lower < dev_priv->surfaces[i].upper) ) || - ( (new_lower < dev_priv->surfaces[i].lower) && - (new_upper > dev_priv->surfaces[i].lower) )) ){ - return -1;} + (((new_lower >= dev_priv->surfaces[i].lower) && + (new_lower < dev_priv->surfaces[i].upper)) || + ((new_lower < dev_priv->surfaces[i].lower) && + (new_upper > dev_priv->surfaces[i].lower)))) { + return -1; + } } /* find a virtual surface */ - for (i = 0; i < 2*RADEON_MAX_SURFACES; i++) + for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) if (dev_priv->virt_surfaces[i].filp == 0) break; - if (i == 2*RADEON_MAX_SURFACES) { - return -1;} + if (i == 2 * RADEON_MAX_SURFACES) { + return -1; + } virt_surface_index = i; /* try to reuse an existing surface */ for (i = 0; i < RADEON_MAX_SURFACES; i++) { /* extend before */ if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_upper + 1 == dev_priv->surfaces[i].lower)) { + (new->flags == dev_priv->surfaces[i].flags) && + (new_upper + 1 == dev_priv->surfaces[i].lower)) { s = &(dev_priv->virt_surfaces[virt_surface_index]); s->surface_index = i; s->lower = new_lower; @@ -1885,8 +1906,8 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t * /* extend after */ if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_lower == dev_priv->surfaces[i].upper + 1)) { + (new->flags == dev_priv->surfaces[i].flags) && + (new_lower == dev_priv->surfaces[i].upper + 1)) { s = &(dev_priv->virt_surfaces[virt_surface_index]); s->surface_index = i; s->lower = new_lower; @@ -1922,26 +1943,34 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t * return -1; } -static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower) +static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv, + int lower) { struct radeon_virt_surface *s; int i; /* find the virtual surface */ - for(i = 0; i < 2*RADEON_MAX_SURFACES; i++) { + for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { s = &(dev_priv->virt_surfaces[i]); if (s->filp) { if ((lower == s->lower) && (filp == s->filp)) { - if (dev_priv->surfaces[s->surface_index].lower == s->lower) - dev_priv->surfaces[s->surface_index].lower = s->upper; + if (dev_priv->surfaces[s->surface_index]. + lower == s->lower) + dev_priv->surfaces[s->surface_index]. + lower = s->upper; - if (dev_priv->surfaces[s->surface_index].upper == s->upper) - dev_priv->surfaces[s->surface_index].upper = s->lower; + if (dev_priv->surfaces[s->surface_index]. + upper == s->upper) + dev_priv->surfaces[s->surface_index]. + upper = s->lower; dev_priv->surfaces[s->surface_index].refcount--; - if (dev_priv->surfaces[s->surface_index].refcount == 0) - dev_priv->surfaces[s->surface_index].flags = 0; + if (dev_priv->surfaces[s->surface_index]. + refcount == 0) + dev_priv->surfaces[s->surface_index]. + flags = 0; s->filp = NULL; - radeon_apply_surface_regs(s->surface_index, dev_priv); + radeon_apply_surface_regs(s->surface_index, + dev_priv); return 0; } } @@ -1949,13 +1978,14 @@ static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower) return 1; } -static void radeon_surfaces_release(DRMFILE filp, drm_radeon_private_t *dev_priv) +static void radeon_surfaces_release(DRMFILE filp, + drm_radeon_private_t * dev_priv) { int i; - for( i = 0; i < 2*RADEON_MAX_SURFACES; i++) - { + for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { if (dev_priv->virt_surfaces[i].filp == filp) - free_surface(filp, dev_priv, dev_priv->virt_surfaces[i].lower); + free_surface(filp, dev_priv, + dev_priv->virt_surfaces[i].lower); } } @@ -1969,12 +1999,13 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS) drm_radeon_surface_alloc_t alloc; if (!dev_priv) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *)data, - sizeof(alloc)); + DRM_COPY_FROM_USER_IOCTL(alloc, + (drm_radeon_surface_alloc_t __user *) data, + sizeof(alloc)); if (alloc_surface(&alloc, dev_priv, filp) == -1) return DRM_ERR(EINVAL); @@ -1989,12 +2020,12 @@ static int radeon_surface_free(DRM_IOCTL_ARGS) drm_radeon_surface_free_t memfree; if (!dev_priv) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *)data, - sizeof(memfree) ); + DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, + sizeof(memfree)); if (free_surface(filp, dev_priv, memfree.address)) return DRM_ERR(EINVAL); @@ -2002,51 +2033,52 @@ static int radeon_surface_free(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_clear( DRM_IOCTL_ARGS ) +static int radeon_cp_clear(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_clear_t clear; drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t __user *)data, - sizeof(clear) ); + DRM_COPY_FROM_USER_IOCTL(clear, (drm_radeon_clear_t __user *) data, + sizeof(clear)); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes, - sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) + if (DRM_COPY_FROM_USER(&depth_boxes, clear.depth_boxes, + sarea_priv->nbox * sizeof(depth_boxes[0]))) return DRM_ERR(EFAULT); - radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + radeon_cp_dispatch_clear(dev, &clear, depth_boxes); COMMIT_RING(); return 0; } - /* Not sure why this isn't set all the time: - */ -static int radeon_do_init_pageflip( drm_device_t *dev ) + */ +static int radeon_do_init_pageflip(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - BEGIN_RING( 6 ); + BEGIN_RING(6); RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); - OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); - OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); - OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0)); + OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) | + RADEON_CRTC_OFFSET_FLIP_CNTL); + OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0)); + OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) | + RADEON_CRTC_OFFSET_FLIP_CNTL); ADVANCE_RING(); dev_priv->page_flipping = 1; @@ -2059,62 +2091,62 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) /* Called whenever a client dies, from drm_release. * NOTE: Lock isn't necessarily held when this is called! */ -static int radeon_do_cleanup_pageflip( drm_device_t *dev ) +static int radeon_do_cleanup_pageflip(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); if (dev_priv->current_page != 0) - radeon_cp_dispatch_flip( dev ); + radeon_cp_dispatch_flip(dev); dev_priv->page_flipping = 0; return 0; } /* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. + * They can & should be intermixed to support multiple 3d windows. */ -static int radeon_cp_flip( DRM_IOCTL_ARGS ) +static int radeon_cp_flip(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if (!dev_priv->page_flipping) - radeon_do_init_pageflip( dev ); - - radeon_cp_dispatch_flip( dev ); + if (!dev_priv->page_flipping) + radeon_do_init_pageflip(dev); + + radeon_cp_dispatch_flip(dev); COMMIT_RING(); return 0; } -static int radeon_cp_swap( DRM_IOCTL_ARGS ) +static int radeon_cp_swap(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "\n" ); + DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - radeon_cp_dispatch_swap( dev ); + radeon_cp_dispatch_swap(dev); dev_priv->sarea_priv->ctx_owner = 0; COMMIT_RING(); return 0; } -static int radeon_cp_vertex( DRM_IOCTL_ARGS ) +static int radeon_cp_vertex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2125,55 +2157,53 @@ static int radeon_cp_vertex( DRM_IOCTL_ARGS ) drm_radeon_vertex_t vertex; drm_radeon_tcl_prim_t prim; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t __user *)data, - sizeof(vertex) ); + DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, + sizeof(vertex)); - DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, - vertex.idx, vertex.count, vertex.discard ); + DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard); - if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1 ); + if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - if ( vertex.prim < 0 || - vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { - DRM_ERROR( "buffer prim %d\n", vertex.prim ); + if (vertex.prim < 0 || vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { + DRM_ERROR("buffer prim %d\n", vertex.prim); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf = dma->buflist[vertex.idx]; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", vertex.idx); return DRM_ERR(EINVAL); } /* Build up a prim_t record: */ if (vertex.count) { - buf->used = vertex.count; /* not used? */ + buf->used = vertex.count; /* not used? */ - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - if ( radeon_emit_state( dev_priv, filp_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty ) ) { - DRM_ERROR( "radeon_emit_state failed\n" ); - return DRM_ERR( EINVAL ); + if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { + if (radeon_emit_state(dev_priv, filp_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty)) { + DRM_ERROR("radeon_emit_state failed\n"); + return DRM_ERR(EINVAL); } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | @@ -2183,23 +2213,23 @@ static int radeon_cp_vertex( DRM_IOCTL_ARGS ) } prim.start = 0; - prim.finish = vertex.count; /* unused */ + prim.finish = vertex.count; /* unused */ prim.prim = vertex.prim; prim.numverts = vertex.count; prim.vc_format = dev_priv->sarea_priv->vc_format; - - radeon_cp_dispatch_vertex( dev, buf, &prim ); + + radeon_cp_dispatch_vertex(dev, buf, &prim); } if (vertex.discard) { - radeon_cp_discard_buffer( dev, buf ); + radeon_cp_discard_buffer(dev, buf); } COMMIT_RING(); return 0; } -static int radeon_cp_indices( DRM_IOCTL_ARGS ) +static int radeon_cp_indices(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2211,69 +2241,67 @@ static int radeon_cp_indices( DRM_IOCTL_ARGS ) drm_radeon_tcl_prim_t prim; int count; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t __user *)data, - sizeof(elts) ); + DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, + sizeof(elts)); - DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n", - DRM_CURRENTPID, - elts.idx, elts.start, elts.end, elts.discard ); + DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", + DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard); - if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - elts.idx, dma->buf_count - 1 ); + if (elts.idx < 0 || elts.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + elts.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - if ( elts.prim < 0 || - elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { - DRM_ERROR( "buffer prim %d\n", elts.prim ); + if (elts.prim < 0 || elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { + DRM_ERROR("buffer prim %d\n", elts.prim); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf = dma->buflist[elts.idx]; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", elts.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", elts.idx); return DRM_ERR(EINVAL); } count = (elts.end - elts.start) / sizeof(u16); elts.start -= RADEON_INDEX_PRIM_OFFSET; - if ( elts.start & 0x7 ) { - DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + if (elts.start & 0x7) { + DRM_ERROR("misaligned buffer 0x%x\n", elts.start); return DRM_ERR(EINVAL); } - if ( elts.start < buf->used ) { - DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); + if (elts.start < buf->used) { + DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used); return DRM_ERR(EINVAL); } buf->used = elts.end; - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - if ( radeon_emit_state( dev_priv, filp_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty ) ) { - DRM_ERROR( "radeon_emit_state failed\n" ); - return DRM_ERR( EINVAL ); + if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { + if (radeon_emit_state(dev_priv, filp_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty)) { + DRM_ERROR("radeon_emit_state failed\n"); + return DRM_ERR(EINVAL); } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | @@ -2282,26 +2310,25 @@ static int radeon_cp_indices( DRM_IOCTL_ARGS ) RADEON_REQUIRE_QUIESCENCE); } - /* Build up a prim_t record: */ prim.start = elts.start; - prim.finish = elts.end; + prim.finish = elts.end; prim.prim = elts.prim; prim.offset = 0; /* offset from start of dma buffers */ - prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ prim.vc_format = dev_priv->sarea_priv->vc_format; - - radeon_cp_dispatch_indices( dev, buf, &prim ); + + radeon_cp_dispatch_indices(dev, buf, &prim); if (elts.discard) { - radeon_cp_discard_buffer( dev, buf ); + radeon_cp_discard_buffer(dev, buf); } COMMIT_RING(); return 0; } -static int radeon_cp_texture( DRM_IOCTL_ARGS ) +static int radeon_cp_texture(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2309,53 +2336,54 @@ static int radeon_cp_texture( DRM_IOCTL_ARGS ) drm_radeon_tex_image_t image; int ret; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t __user *)data, sizeof(tex) ); + DRM_COPY_FROM_USER_IOCTL(tex, (drm_radeon_texture_t __user *) data, + sizeof(tex)); - if ( tex.image == NULL ) { - DRM_ERROR( "null texture image!\n" ); + if (tex.image == NULL) { + DRM_ERROR("null texture image!\n"); return DRM_ERR(EINVAL); } - if ( DRM_COPY_FROM_USER( &image, - (drm_radeon_tex_image_t __user *)tex.image, - sizeof(image) ) ) + if (DRM_COPY_FROM_USER(&image, + (drm_radeon_tex_image_t __user *) tex.image, + sizeof(image))) return DRM_ERR(EFAULT); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); - ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image ); + ret = radeon_cp_dispatch_texture(filp, dev, &tex, &image); COMMIT_RING(); return ret; } -static int radeon_cp_stipple( DRM_IOCTL_ARGS ) +static int radeon_cp_stipple(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t __user *)data, - sizeof(stipple) ); + DRM_COPY_FROM_USER_IOCTL(stipple, (drm_radeon_stipple_t __user *) data, + sizeof(stipple)); - if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) + if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32))) return DRM_ERR(EFAULT); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); - radeon_cp_dispatch_stipple( dev, mask ); + radeon_cp_dispatch_stipple(dev, mask); COMMIT_RING(); return 0; } -static int radeon_cp_indirect( DRM_IOCTL_ARGS ) +static int radeon_cp_indirect(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2364,53 +2392,53 @@ static int radeon_cp_indirect( DRM_IOCTL_ARGS ) drm_radeon_indirect_t indirect; RING_LOCALS; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t __user *)data, - sizeof(indirect) ); + DRM_COPY_FROM_USER_IOCTL(indirect, + (drm_radeon_indirect_t __user *) data, + sizeof(indirect)); - DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", - indirect.idx, indirect.start, - indirect.end, indirect.discard ); + DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, indirect.end, indirect.discard); - if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - indirect.idx, dma->buf_count - 1 ); + if (indirect.idx < 0 || indirect.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } buf = dma->buflist[indirect.idx]; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", indirect.idx); return DRM_ERR(EINVAL); } - if ( indirect.start < buf->used ) { - DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", - indirect.start, buf->used ); + if (indirect.start < buf->used) { + DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf->used = indirect.end; /* Wait for the 3D stream to idle before the indirect buffer * containing 2D acceleration commands is processed. */ - BEGIN_RING( 2 ); + BEGIN_RING(2); RADEON_WAIT_UNTIL_3D_IDLE(); @@ -2420,17 +2448,16 @@ static int radeon_cp_indirect( DRM_IOCTL_ARGS ) * X server. This is insecure and is thus only available to * privileged clients. */ - radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + radeon_cp_dispatch_indirect(dev, buf, indirect.start, indirect.end); if (indirect.discard) { - radeon_cp_discard_buffer( dev, buf ); + radeon_cp_discard_buffer(dev, buf); } - COMMIT_RING(); return 0; } -static int radeon_cp_vertex2( DRM_IOCTL_ARGS ) +static int radeon_cp_vertex2(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2442,65 +2469,64 @@ static int radeon_cp_vertex2( DRM_IOCTL_ARGS ) int i; unsigned char laststate; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t __user *)data, - sizeof(vertex) ); + DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, + sizeof(vertex)); - DRM_DEBUG( "pid=%d index=%d discard=%d\n", - DRM_CURRENTPID, - vertex.idx, vertex.discard ); + DRM_DEBUG("pid=%d index=%d discard=%d\n", + DRM_CURRENTPID, vertex.idx, vertex.discard); - if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1 ); + if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); buf = dma->buflist[vertex.idx]; - if ( buf->filp != filp ) { - DRM_ERROR( "process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp ); + if (buf->filp != filp) { + DRM_ERROR("process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp); return DRM_ERR(EINVAL); } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", vertex.idx); return DRM_ERR(EINVAL); } - + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) return DRM_ERR(EINVAL); - for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { + for (laststate = 0xff, i = 0; i < vertex.nr_prims; i++) { drm_radeon_prim_t prim; drm_radeon_tcl_prim_t tclprim; - - if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) ) + + if (DRM_COPY_FROM_USER(&prim, &vertex.prim[i], sizeof(prim))) return DRM_ERR(EFAULT); - - if ( prim.stateidx != laststate ) { - drm_radeon_state_t state; - - if ( DRM_COPY_FROM_USER( &state, - &vertex.state[prim.stateidx], - sizeof(state) ) ) + + if (prim.stateidx != laststate) { + drm_radeon_state_t state; + + if (DRM_COPY_FROM_USER(&state, + &vertex.state[prim.stateidx], + sizeof(state))) return DRM_ERR(EFAULT); - if ( radeon_emit_state2( dev_priv, filp_priv, &state ) ) { - DRM_ERROR( "radeon_emit_state2 failed\n" ); - return DRM_ERR( EINVAL ); + if (radeon_emit_state2(dev_priv, filp_priv, &state)) { + DRM_ERROR("radeon_emit_state2 failed\n"); + return DRM_ERR(EINVAL); } laststate = prim.stateidx; @@ -2511,42 +2537,40 @@ static int radeon_cp_vertex2( DRM_IOCTL_ARGS ) tclprim.prim = prim.prim; tclprim.vc_format = prim.vc_format; - if ( prim.prim & RADEON_PRIM_WALK_IND ) { + if (prim.prim & RADEON_PRIM_WALK_IND) { tclprim.offset = prim.numverts * 64; - tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - radeon_cp_dispatch_indices( dev, buf, &tclprim ); + radeon_cp_dispatch_indices(dev, buf, &tclprim); } else { tclprim.numverts = prim.numverts; - tclprim.offset = 0; /* not used */ + tclprim.offset = 0; /* not used */ - radeon_cp_dispatch_vertex( dev, buf, &tclprim ); + radeon_cp_dispatch_vertex(dev, buf, &tclprim); } - + if (sarea_priv->nbox == 1) sarea_priv->nbox = 0; } - if ( vertex.discard ) { - radeon_cp_discard_buffer( dev, buf ); + if (vertex.discard) { + radeon_cp_discard_buffer(dev, buf); } COMMIT_RING(); return 0; } - -static int radeon_emit_packets( - drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t *cmdbuf ) +static int radeon_emit_packets(drm_radeon_private_t * dev_priv, + drm_file_t * filp_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t * cmdbuf) { int id = (int)header.packet.packet_id; int sz, reg; int *data = (int *)cmdbuf->buf; RING_LOCALS; - + if (id >= RADEON_MAX_STATE_PACKETS) return DRM_ERR(EINVAL); @@ -2554,18 +2578,18 @@ static int radeon_emit_packets( reg = packet[id].start; if (sz * sizeof(int) > cmdbuf->bufsz) { - DRM_ERROR( "Packet size provided larger than data provided\n" ); + DRM_ERROR("Packet size provided larger than data provided\n"); return DRM_ERR(EINVAL); } - if ( radeon_check_and_fixup_packets( dev_priv, filp_priv, id, data ) ) { - DRM_ERROR( "Packet verification failed\n" ); - return DRM_ERR( EINVAL ); + if (radeon_check_and_fixup_packets(dev_priv, filp_priv, id, data)) { + DRM_ERROR("Packet verification failed\n"); + return DRM_ERR(EINVAL); } - BEGIN_RING(sz+1); - OUT_RING( CP_PACKET0( reg, (sz-1) ) ); - OUT_RING_TABLE( data, sz ); + BEGIN_RING(sz + 1); + OUT_RING(CP_PACKET0(reg, (sz - 1))); + OUT_RING_TABLE(data, sz); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); @@ -2573,21 +2597,20 @@ static int radeon_emit_packets( return 0; } -static __inline__ int radeon_emit_scalars( - drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t *cmdbuf ) +static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = header.scalars.offset; int stride = header.scalars.stride; RING_LOCALS; - BEGIN_RING( 3+sz ); - OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); - OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); - OUT_RING_TABLE( cmdbuf->buf, sz ); + BEGIN_RING(3 + sz); + OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); + OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); + OUT_RING_TABLE(cmdbuf->buf, sz); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); cmdbuf->bufsz -= sz * sizeof(int); @@ -2596,42 +2619,40 @@ static __inline__ int radeon_emit_scalars( /* God this is ugly */ -static __inline__ int radeon_emit_scalars2( - drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t *cmdbuf ) +static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = ((unsigned int)header.scalars.offset) + 0x100; int stride = header.scalars.stride; RING_LOCALS; - BEGIN_RING( 3+sz ); - OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); - OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); - OUT_RING_TABLE( cmdbuf->buf, sz ); + BEGIN_RING(3 + sz); + OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); + OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); + OUT_RING_TABLE(cmdbuf->buf, sz); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); cmdbuf->bufsz -= sz * sizeof(int); return 0; } -static __inline__ int radeon_emit_vectors( - drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t *cmdbuf ) +static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t * cmdbuf) { int sz = header.vectors.count; int start = header.vectors.offset; int stride = header.vectors.stride; RING_LOCALS; - BEGIN_RING( 3+sz ); - OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); - OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); - OUT_RING_TABLE( cmdbuf->buf, sz ); + BEGIN_RING(3 + sz); + OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); + OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); + OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); + OUT_RING_TABLE(cmdbuf->buf, sz); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); @@ -2639,10 +2660,9 @@ static __inline__ int radeon_emit_vectors( return 0; } - -static int radeon_emit_packet3( drm_device_t *dev, - drm_file_t *filp_priv, - drm_radeon_cmd_buffer_t *cmdbuf ) +static int radeon_emit_packet3(drm_device_t * dev, + drm_file_t * filp_priv, + drm_radeon_cmd_buffer_t * cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int cmdsz; @@ -2651,14 +2671,14 @@ static int radeon_emit_packet3( drm_device_t *dev, DRM_DEBUG("\n"); - if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv, - cmdbuf, &cmdsz ) ) ) { - DRM_ERROR( "Packet verification failed\n" ); + if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv, + cmdbuf, &cmdsz))) { + DRM_ERROR("Packet verification failed\n"); return ret; } - BEGIN_RING( cmdsz ); - OUT_RING_TABLE( cmdbuf->buf, cmdsz ); + BEGIN_RING(cmdsz); + OUT_RING_TABLE(cmdbuf->buf, cmdsz); ADVANCE_RING(); cmdbuf->buf += cmdsz * 4; @@ -2666,11 +2686,10 @@ static int radeon_emit_packet3( drm_device_t *dev, return 0; } - -static int radeon_emit_packet3_cliprect( drm_device_t *dev, - drm_file_t *filp_priv, - drm_radeon_cmd_buffer_t *cmdbuf, - int orig_nbox ) +static int radeon_emit_packet3_cliprect(drm_device_t * dev, + drm_file_t * filp_priv, + drm_radeon_cmd_buffer_t * cmdbuf, + int orig_nbox) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_clip_rect_t box; @@ -2682,9 +2701,9 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, DRM_DEBUG("\n"); - if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv, - cmdbuf, &cmdsz ) ) ) { - DRM_ERROR( "Packet verification failed\n" ); + if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv, + cmdbuf, &cmdsz))) { + DRM_ERROR("Packet verification failed\n"); return ret; } @@ -2692,8 +2711,8 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, goto out; do { - if ( i < cmdbuf->nbox ) { - if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) )) + if (i < cmdbuf->nbox) { + if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box))) return DRM_ERR(EFAULT); /* FIXME The second and subsequent times round * this loop, send a WAIT_UNTIL_3D_IDLE before @@ -2707,30 +2726,29 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, * the correct place to fix it but this works * around it until I can figure that out - Tim * Smith */ - if ( i ) { - BEGIN_RING( 2 ); + if (i) { + BEGIN_RING(2); RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); } - radeon_emit_clip_rect( dev_priv, &box ); + radeon_emit_clip_rect(dev_priv, &box); } - - BEGIN_RING( cmdsz ); - OUT_RING_TABLE( cmdbuf->buf, cmdsz ); + + BEGIN_RING(cmdsz); + OUT_RING_TABLE(cmdbuf->buf, cmdsz); ADVANCE_RING(); - } while ( ++i < cmdbuf->nbox ); - if (cmdbuf->nbox == 1) + } while (++i < cmdbuf->nbox); + if (cmdbuf->nbox == 1) cmdbuf->nbox = 0; - out: + out: cmdbuf->buf += cmdsz * 4; cmdbuf->bufsz -= cmdsz * 4; return 0; } - -static int radeon_emit_wait( drm_device_t *dev, int flags ) +static int radeon_emit_wait(drm_device_t * dev, int flags) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -2738,18 +2756,18 @@ static int radeon_emit_wait( drm_device_t *dev, int flags ) DRM_DEBUG("%s: %x\n", __FUNCTION__, flags); switch (flags) { case RADEON_WAIT_2D: - BEGIN_RING( 2 ); - RADEON_WAIT_UNTIL_2D_IDLE(); + BEGIN_RING(2); + RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); break; case RADEON_WAIT_3D: - BEGIN_RING( 2 ); - RADEON_WAIT_UNTIL_3D_IDLE(); + BEGIN_RING(2); + RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); break; - case RADEON_WAIT_2D|RADEON_WAIT_3D: - BEGIN_RING( 2 ); - RADEON_WAIT_UNTIL_IDLE(); + case RADEON_WAIT_2D | RADEON_WAIT_3D: + BEGIN_RING(2); + RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); break; default: @@ -2759,7 +2777,7 @@ static int radeon_emit_wait( drm_device_t *dev, int flags ) return 0; } -static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) +static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2770,24 +2788,25 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) drm_radeon_cmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; int orig_nbox, orig_bufsz; - char *kbuf=NULL; + char *kbuf = NULL; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t __user *)data, - sizeof(cmdbuf) ); + DRM_COPY_FROM_USER_IOCTL(cmdbuf, + (drm_radeon_cmd_buffer_t __user *) data, + sizeof(cmdbuf)); - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - VB_AGE_TEST_WITH_RETURN( dev_priv ); + RING_SPACE_TEST_WITH_RETURN(dev_priv); + VB_AGE_TEST_WITH_RETURN(dev_priv); - if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) { + if (cmdbuf.bufsz > 64 * 1024 || cmdbuf.bufsz < 0) { return DRM_ERR(EINVAL); } @@ -2809,27 +2828,28 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) orig_nbox = cmdbuf.nbox; - if(dev_priv->microcode_version == UCODE_R300) { + if (dev_priv->microcode_version == UCODE_R300) { int temp; - temp=r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf); - + temp = r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf); + if (orig_bufsz != 0) drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - + return temp; } /* microcode_version != r300 */ - while ( cmdbuf.bufsz >= sizeof(header) ) { + while (cmdbuf.bufsz >= sizeof(header)) { header.i = *(int *)cmdbuf.buf; cmdbuf.buf += sizeof(header); cmdbuf.bufsz -= sizeof(header); switch (header.header.cmd_type) { - case RADEON_CMD_PACKET: + case RADEON_CMD_PACKET: DRM_DEBUG("RADEON_CMD_PACKET\n"); - if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) { + if (radeon_emit_packets + (dev_priv, filp_priv, header, &cmdbuf)) { DRM_ERROR("radeon_emit_packets failed\n"); goto err; } @@ -2837,7 +2857,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_SCALARS: DRM_DEBUG("RADEON_CMD_SCALARS\n"); - if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { + if (radeon_emit_scalars(dev_priv, header, &cmdbuf)) { DRM_ERROR("radeon_emit_scalars failed\n"); goto err; } @@ -2845,7 +2865,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_VECTORS: DRM_DEBUG("RADEON_CMD_VECTORS\n"); - if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { + if (radeon_emit_vectors(dev_priv, header, &cmdbuf)) { DRM_ERROR("radeon_emit_vectors failed\n"); goto err; } @@ -2854,25 +2874,25 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_DMA_DISCARD: DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); idx = header.dma.buf_idx; - if ( idx < 0 || idx >= dma->buf_count ) { - DRM_ERROR( "buffer index %d (of %d max)\n", - idx, dma->buf_count - 1 ); + if (idx < 0 || idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + idx, dma->buf_count - 1); goto err; } buf = dma->buflist[idx]; - if ( buf->filp != filp || buf->pending ) { - DRM_ERROR( "bad buffer %p %p %d\n", - buf->filp, filp, buf->pending); + if (buf->filp != filp || buf->pending) { + DRM_ERROR("bad buffer %p %p %d\n", + buf->filp, filp, buf->pending); goto err; } - radeon_cp_discard_buffer( dev, buf ); + radeon_cp_discard_buffer(dev, buf); break; case RADEON_CMD_PACKET3: DRM_DEBUG("RADEON_CMD_PACKET3\n"); - if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) { + if (radeon_emit_packet3(dev, filp_priv, &cmdbuf)) { DRM_ERROR("radeon_emit_packet3 failed\n"); goto err; } @@ -2880,7 +2900,8 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_PACKET3_CLIP: DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); - if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) { + if (radeon_emit_packet3_cliprect + (dev, filp_priv, &cmdbuf, orig_nbox)) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); goto err; } @@ -2888,7 +2909,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_SCALARS2: DRM_DEBUG("RADEON_CMD_SCALARS2\n"); - if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { + if (radeon_emit_scalars2(dev_priv, header, &cmdbuf)) { DRM_ERROR("radeon_emit_scalars2 failed\n"); goto err; } @@ -2896,13 +2917,13 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) case RADEON_CMD_WAIT: DRM_DEBUG("RADEON_CMD_WAIT\n"); - if (radeon_emit_wait( dev, header.wait.flags )) { + if (radeon_emit_wait(dev, header.wait.flags)) { DRM_ERROR("radeon_emit_wait failed\n"); goto err; } break; default: - DRM_ERROR("bad cmd_type %d at %p\n", + DRM_ERROR("bad cmd_type %d at %p\n", header.header.cmd_type, cmdbuf.buf - sizeof(header)); goto err; @@ -2916,45 +2937,43 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) COMMIT_RING(); return 0; -err: + err: if (orig_bufsz != 0) drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); return DRM_ERR(EINVAL); } - - -static int radeon_cp_getparam( DRM_IOCTL_ARGS ) +static int radeon_cp_getparam(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_getparam_t param; int value; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t __user *)data, - sizeof(param) ); + DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, + sizeof(param)); - DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch( param.param ) { + switch (param.param) { case RADEON_PARAM_GART_BUFFER_OFFSET: value = dev_priv->gart_buffers_offset; break; case RADEON_PARAM_LAST_FRAME: dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH( 0 ); + value = GET_SCRATCH(0); break; case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH( 1 ); + value = GET_SCRATCH(1); break; case RADEON_PARAM_LAST_CLEAR: dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH( 2 ); + value = GET_SCRATCH(2); break; case RADEON_PARAM_IRQ_NR: value = dev->irq; @@ -2969,15 +2988,15 @@ static int radeon_cp_getparam( DRM_IOCTL_ARGS ) value = dev_priv->ring_rptr_offset; break; #if BITS_PER_LONG == 32 - /* - * This ioctl() doesn't work on 64-bit platforms because hw_lock is a - * pointer which can't fit into an int-sized variable. According to - * Michel Dänzer, the ioctl() is only used on embedded platforms, so - * not supporting it shouldn't be a problem. If the same functionality - * is needed on 64-bit platforms, a new ioctl() would have to be added, - * so backwards-compatibility for the embedded platforms can be - * maintained. --davidm 4-Feb-2004. - */ + /* + * This ioctl() doesn't work on 64-bit platforms because hw_lock is a + * pointer which can't fit into an int-sized variable. According to + * Michel Dänzer, the ioctl() is only used on embedded platforms, so + * not supporting it shouldn't be a problem. If the same functionality + * is needed on 64-bit platforms, a new ioctl() would have to be added, + * so backwards-compatibility for the embedded platforms can be + * maintained. --davidm 4-Feb-2004. + */ case RADEON_PARAM_SAREA_HANDLE: /* The lock is the first dword in the sarea. */ value = (long)dev->lock.hw_lock; @@ -2990,56 +3009,56 @@ static int radeon_cp_getparam( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } - if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { - DRM_ERROR( "copy_to_user\n" ); + if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); return DRM_ERR(EFAULT); } - + return 0; } -static int radeon_cp_setparam( DRM_IOCTL_ARGS ) { +static int radeon_cp_setparam(DRM_IOCTL_ARGS) +{ DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; drm_radeon_setparam_t sp; struct drm_radeon_driver_file_fields *radeon_priv; - if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return DRM_ERR( EINVAL ); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); } - DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - DRM_COPY_FROM_USER_IOCTL( sp, ( drm_radeon_setparam_t __user * )data, - sizeof( sp ) ); + DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, + sizeof(sp)); - switch( sp.param ) { + switch (sp.param) { case RADEON_SETPARAM_FB_LOCATION: radeon_priv = filp_priv->driver_priv; radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value; break; case RADEON_SETPARAM_SWITCH_TILING: if (sp.value == 0) { - DRM_DEBUG( "color tiling disabled\n" ); + DRM_DEBUG("color tiling disabled\n"); dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->sarea_priv->tiling_enabled = 0; - } - else if (sp.value == 1) { - DRM_DEBUG( "color tiling enabled\n" ); + } else if (sp.value == 1) { + DRM_DEBUG("color tiling enabled\n"); dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; dev_priv->sarea_priv->tiling_enabled = 1; } - break; + break; case RADEON_SETPARAM_PCIGART_LOCATION: dev_priv->pcigart_offset = sp.value; break; default: - DRM_DEBUG( "Invalid parameter %d\n", sp.param ); - return DRM_ERR( EINVAL ); + DRM_DEBUG("Invalid parameter %d\n", sp.param); + return DRM_ERR(EINVAL); } return 0; @@ -3051,78 +3070,106 @@ static int radeon_cp_setparam( DRM_IOCTL_ARGS ) { * * DRM infrastructure takes care of reclaiming dma buffers. */ -void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp) +void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) { - if ( dev->dev_private ) { - drm_radeon_private_t *dev_priv = dev->dev_private; - if ( dev_priv->page_flipping ) { - radeon_do_cleanup_pageflip( dev ); - } - radeon_mem_release( filp, dev_priv->gart_heap ); - radeon_mem_release( filp, dev_priv->fb_heap ); + if (dev->dev_private) { + drm_radeon_private_t *dev_priv = dev->dev_private; + if (dev_priv->page_flipping) { + radeon_do_cleanup_pageflip(dev); + } + radeon_mem_release(filp, dev_priv->gart_heap); + radeon_mem_release(filp, dev_priv->fb_heap); radeon_surfaces_release(filp, dev_priv); - } + } } -void radeon_driver_pretakedown(drm_device_t *dev) +void radeon_driver_pretakedown(drm_device_t * dev) { radeon_do_release(dev); } -int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv) +int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_radeon_driver_file_fields *radeon_priv; - - radeon_priv = (struct drm_radeon_driver_file_fields *)drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); - + + radeon_priv = + (struct drm_radeon_driver_file_fields *) + drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); + if (!radeon_priv) return -ENOMEM; filp_priv->driver_priv = radeon_priv; - if ( dev_priv ) + if (dev_priv) radeon_priv->radeon_fb_delta = dev_priv->fb_location; else radeon_priv->radeon_fb_delta = 0; return 0; } - -void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv) +void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) { - struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv; - - drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); + struct drm_radeon_driver_file_fields *radeon_priv = + filp_priv->driver_priv; + + drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); } drm_ioctl_desc_t radeon_ioctls[] = { - [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = { radeon_mem_init_heap,1, 1 }, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 }, - [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = { radeon_surface_free, 1, 0 } + [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1} + , + [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0} + , + [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0} }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 2fd40bac7c97..0ad9201af8bd 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c @@ -28,12 +28,12 @@ /* Need a long timeout for shadow status updates can take a while * and so can waiting for events when the queue is full. */ -#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */ -#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ +#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */ +#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ #define SAVAGE_FREELIST_DEBUG 0 static int -savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n) +savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) { uint32_t mask = dev_priv->status_used_mask; uint32_t threshold = dev_priv->bci_threshold_hi; @@ -62,7 +62,7 @@ savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n) } static int -savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n) +savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n) { uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; uint32_t status; @@ -83,7 +83,7 @@ savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n) } static int -savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n) +savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n) { uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; uint32_t status; @@ -115,7 +115,7 @@ savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n) * rule. Otherwise there may be glitches every 2^16 events. */ static int -savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e) +savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e) { uint32_t status; int i; @@ -138,7 +138,7 @@ savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e) } static int -savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e) +savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e) { uint32_t status; int i; @@ -159,7 +159,7 @@ savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e) return DRM_ERR(EBUSY); } -uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, +uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, unsigned int flags) { uint16_t count; @@ -175,12 +175,12 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, } count = (count + 1) & 0xffff; if (count == 0) { - count++; /* See the comment above savage_wait_event_*. */ + count++; /* See the comment above savage_wait_event_*. */ dev_priv->event_wrap++; } dev_priv->event_counter = count; if (dev_priv->status_ptr) - dev_priv->status_ptr[1023] = (uint32_t)count; + dev_priv->status_ptr[1023] = (uint32_t) count; if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) { unsigned int wait_cmd = BCI_CMD_WAIT; @@ -193,7 +193,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, } else { BEGIN_BCI(1); } - BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t)count); + BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count); return count; } @@ -201,7 +201,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, /* * Freelist management */ -static int savage_freelist_init(drm_device_t *dev) +static int savage_freelist_init(drm_device_t * dev) { drm_savage_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; @@ -234,7 +234,7 @@ static int savage_freelist_init(drm_device_t *dev) return 0; } -static drm_buf_t *savage_freelist_get(drm_device_t *dev) +static drm_buf_t *savage_freelist_get(drm_device_t * dev) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_buf_priv_t *tail = dev_priv->tail.prev; @@ -249,7 +249,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev) event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; wrap = dev_priv->event_wrap; if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ + wrap--; /* hardware hasn't passed the last wrap yet */ DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap); DRM_DEBUG(" head=0x%04x %d\n", event, wrap); @@ -267,7 +267,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev) return NULL; } -void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf) +void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next; @@ -290,15 +290,14 @@ void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf) /* * Command DMA */ -static int savage_dma_init(drm_savage_private_t *dev_priv) +static int savage_dma_init(drm_savage_private_t * dev_priv) { unsigned int i; dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / - (SAVAGE_DMA_PAGE_SIZE*4); + (SAVAGE_DMA_PAGE_SIZE * 4); dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) * - dev_priv->nr_dma_pages, - DRM_MEM_DRIVER); + dev_priv->nr_dma_pages, DRM_MEM_DRIVER); if (dev_priv->dma_pages == NULL) return DRM_ERR(ENOMEM); @@ -315,7 +314,7 @@ static int savage_dma_init(drm_savage_private_t *dev_priv) return 0; } -void savage_dma_reset(drm_savage_private_t *dev_priv) +void savage_dma_reset(drm_savage_private_t * dev_priv) { uint16_t event; unsigned int wrap, i; @@ -330,7 +329,7 @@ void savage_dma_reset(drm_savage_private_t *dev_priv) dev_priv->first_dma_page = dev_priv->current_dma_page = 0; } -void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page) +void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page) { uint16_t event; unsigned int wrap; @@ -346,7 +345,7 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page) event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; wrap = dev_priv->event_wrap; if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ + wrap--; /* hardware hasn't passed the last wrap yet */ if (dev_priv->dma_pages[page].age.wrap > wrap || (dev_priv->dma_pages[page].age.wrap == wrap && @@ -358,13 +357,13 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page) } } -uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n) +uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n) { unsigned int cur = dev_priv->current_dma_page; unsigned int rest = SAVAGE_DMA_PAGE_SIZE - - dev_priv->dma_pages[cur].used; - unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) / - SAVAGE_DMA_PAGE_SIZE; + dev_priv->dma_pages[cur].used; + unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) / + SAVAGE_DMA_PAGE_SIZE; uint32_t *dma_ptr; unsigned int i; @@ -372,9 +371,8 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n) cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages); if (cur + nr_pages < dev_priv->nr_dma_pages) { - dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + - cur*SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[cur].used; + dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + + cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; if (n < rest) rest = n; dev_priv->dma_pages[cur].used += rest; @@ -382,13 +380,14 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n) cur++; } else { dev_priv->dma_flush(dev_priv); - nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE; + nr_pages = + (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE; for (i = cur; i < dev_priv->nr_dma_pages; ++i) { dev_priv->dma_pages[i].age = dev_priv->last_dma_age; dev_priv->dma_pages[i].used = 0; dev_priv->dma_pages[i].flushed = 0; } - dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle; + dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle; dev_priv->first_dma_page = cur = 0; } for (i = cur; nr_pages > 0; ++i, --nr_pages) { @@ -414,7 +413,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n) return dma_ptr; } -static void savage_dma_flush(drm_savage_private_t *dev_priv) +static void savage_dma_flush(drm_savage_private_t * dev_priv) { unsigned int first = dev_priv->first_dma_page; unsigned int cur = dev_priv->current_dma_page; @@ -439,11 +438,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) /* pad with noops */ if (pad) { - uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + - cur * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[cur].used; + uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + + cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; dev_priv->dma_pages[cur].used += pad; - while(pad != 0) { + while (pad != 0) { *dma_ptr++ = BCI_CMD_WAIT; pad--; } @@ -453,11 +451,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) /* do flush ... */ phys_addr = dev_priv->cmd_dma->offset + - (first * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[first].flushed) * 4; + (first * SAVAGE_DMA_PAGE_SIZE + + dev_priv->dma_pages[first].flushed) * 4; len = (cur - first) * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[cur].used - - dev_priv->dma_pages[first].flushed; + dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed; DRM_DEBUG("phys_addr=%lx, len=%u\n", phys_addr | dev_priv->dma_type, len); @@ -499,7 +496,7 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) dev_priv->dma_pages[cur].flushed); } -static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) +static void savage_fake_dma_flush(drm_savage_private_t * dev_priv) { unsigned int i, j; BCI_LOCALS; @@ -515,8 +512,8 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) for (i = dev_priv->first_dma_page; i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used; ++i) { - uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + - i * SAVAGE_DMA_PAGE_SIZE; + uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + + i * SAVAGE_DMA_PAGE_SIZE; #if SAVAGE_DMA_DEBUG /* Sanity check: all pages except the last one must be full. */ if (i < dev_priv->current_dma_page && @@ -543,7 +540,7 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) * initialized. We also need to take care of deleting the MTRRs in * postcleanup. */ -int savage_preinit(drm_device_t *dev, unsigned long chipset) +int savage_preinit(drm_device_t * dev, unsigned long chipset) { drm_savage_private_t *dev_priv; unsigned long mmio_base, fb_base, fb_size, aperture_base; @@ -578,19 +575,22 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) * MTRRs. */ dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x01000000; - dev_priv->mtrr[0].handle = mtrr_add( - dev_priv->mtrr[0].base, dev_priv->mtrr[0].size, - MTRR_TYPE_WRCOMB, 1); - dev_priv->mtrr[1].base = fb_base+0x02000000; + dev_priv->mtrr[0].handle = + mtrr_add(dev_priv->mtrr[0].base, + dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, + 1); + dev_priv->mtrr[1].base = fb_base + 0x02000000; dev_priv->mtrr[1].size = 0x02000000; - dev_priv->mtrr[1].handle = mtrr_add( - dev_priv->mtrr[1].base, dev_priv->mtrr[1].size, - MTRR_TYPE_WRCOMB, 1); - dev_priv->mtrr[2].base = fb_base+0x04000000; + dev_priv->mtrr[1].handle = + mtrr_add(dev_priv->mtrr[1].base, + dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB, + 1); + dev_priv->mtrr[2].base = fb_base + 0x04000000; dev_priv->mtrr[2].size = 0x04000000; - dev_priv->mtrr[2].handle = mtrr_add( - dev_priv->mtrr[2].base, dev_priv->mtrr[2].size, - MTRR_TYPE_WRCOMB, 1); + dev_priv->mtrr[2].handle = + mtrr_add(dev_priv->mtrr[2].base, + dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB, + 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 0)); @@ -608,9 +608,10 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) * aperture. */ dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x08000000; - dev_priv->mtrr[0].handle = mtrr_add( - dev_priv->mtrr[0].base, dev_priv->mtrr[0].size, - MTRR_TYPE_WRCOMB, 1); + dev_priv->mtrr[0].handle = + mtrr_add(dev_priv->mtrr[0].base, + dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, + 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 1)); @@ -647,7 +648,7 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) /* * Delete MTRRs and free device-private data. */ -int savage_postcleanup(drm_device_t *dev) +int savage_postcleanup(drm_device_t * dev) { drm_savage_private_t *dev_priv = dev->dev_private; int i; @@ -663,7 +664,7 @@ int savage_postcleanup(drm_device_t *dev) return 0; } -static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) +static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init) { drm_savage_private_t *dev_priv = dev->dev_private; @@ -731,7 +732,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) } if (init->agp_textures_offset) { dev_priv->agp_textures = - drm_core_findmap(dev, init->agp_textures_offset); + drm_core_findmap(dev, init->agp_textures_offset); if (!dev_priv->agp_textures) { DRM_ERROR("could not find agp texture region!\n"); savage_do_cleanup_bci(dev); @@ -802,8 +803,8 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) } dev_priv->sarea_priv = - (drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle + - init->sarea_priv_offset); + (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle + + init->sarea_priv_offset); /* setup bitmap descriptors */ { @@ -812,35 +813,36 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) unsigned int front_stride, back_stride, depth_stride; if (dev_priv->chipset <= S3_SAVAGE4) { color_tile_format = dev_priv->fb_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; + SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; depth_tile_format = dev_priv->depth_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; + SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; } else { color_tile_format = SAVAGE_BD_TILE_DEST; depth_tile_format = SAVAGE_BD_TILE_DEST; } - front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp/8); - back_stride = dev_priv-> back_pitch / (dev_priv->fb_bpp/8); - depth_stride = dev_priv->depth_pitch / (dev_priv->depth_bpp/8); + front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8); + back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8); + depth_stride = + dev_priv->depth_pitch / (dev_priv->depth_bpp / 8); dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); + (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | + (color_tile_format << SAVAGE_BD_TILE_SHIFT); - dev_priv-> back_bd = back_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); + dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE | + (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | + (color_tile_format << SAVAGE_BD_TILE_SHIFT); dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) | - (depth_tile_format << SAVAGE_BD_TILE_SHIFT); + (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) | + (depth_tile_format << SAVAGE_BD_TILE_SHIFT); } /* setup status and bci ptr */ dev_priv->event_counter = 0; dev_priv->event_wrap = 0; dev_priv->bci_ptr = (volatile uint32_t *) - ((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET); + ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET); if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D; } else { @@ -848,7 +850,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) } if (dev_priv->status != NULL) { dev_priv->status_ptr = - (volatile uint32_t *)dev_priv->status->handle; + (volatile uint32_t *)dev_priv->status->handle; dev_priv->wait_fifo = savage_bci_wait_fifo_shadow; dev_priv->wait_evnt = savage_bci_wait_event_shadow; dev_priv->status_ptr[1023] = dev_priv->event_counter; @@ -874,7 +876,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) return DRM_ERR(ENOMEM); } - if (savage_dma_init(dev_priv) < 0) { + if (savage_dma_init(dev_priv) < 0) { DRM_ERROR("could not initialize command DMA\n"); savage_do_cleanup_bci(dev); return DRM_ERR(ENOMEM); @@ -883,7 +885,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) return 0; } -int savage_do_cleanup_bci(drm_device_t *dev) +int savage_do_cleanup_bci(drm_device_t * dev) { drm_savage_private_t *dev_priv = dev->dev_private; @@ -907,7 +909,7 @@ int savage_do_cleanup_bci(drm_device_t *dev) if (dev_priv->dma_pages) drm_free(dev_priv->dma_pages, - sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages, + sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages, DRM_MEM_DRIVER); return 0; @@ -920,7 +922,7 @@ static int savage_bci_init(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data, + DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *) data, sizeof(init)); switch (init.func) { @@ -943,13 +945,13 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data, + DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *) data, sizeof(event)); event.count = savage_bci_emit_event(dev_priv, event.flags); event.count |= dev_priv->event_wrap << 16; - DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count, - event.count, sizeof(event.count)); + DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)-> + count, event.count, sizeof(event.count)); return 0; } @@ -963,7 +965,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) DRM_DEBUG("\n"); - DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data, + DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *) data, sizeof(event)); UPDATE_EVENT_COUNTER(); @@ -973,7 +975,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; hw_w = dev_priv->event_wrap; if (hw_e > dev_priv->event_counter) - hw_w--; /* hardware hasn't passed the last wrap yet */ + hw_w--; /* hardware hasn't passed the last wrap yet */ event_e = event.count & 0xffff; event_w = event.count >> 16; @@ -982,7 +984,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) * - event counter wrapped since the event was emitted or * - the hardware has advanced up to or over the event to wait for. */ - if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) ) + if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e)) return 0; else return dev_priv->wait_evnt(dev_priv, event_e); @@ -992,7 +994,8 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) * DMA buffer management */ -static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d) +static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev, + drm_dma_t * d) { drm_buf_t *buf; int i; @@ -1025,7 +1028,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d)); + DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *) data, sizeof(d)); /* Please don't send us buffers. */ @@ -1049,12 +1052,13 @@ int savage_bci_buffers(DRM_IOCTL_ARGS) ret = savage_bci_get_buffers(filp, dev, &d); } - DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d)); + DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *) data, d, sizeof(d)); return ret; } -void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) { +void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) +{ drm_device_dma_t *dma = dev->dma; drm_savage_private_t *dev_priv = dev->dev_private; int i; @@ -1066,7 +1070,7 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) { if (!dma->buflist) return; - /*i830_flush_queue(dev);*/ + /*i830_flush_queue(dev); */ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[i]; @@ -1085,12 +1089,15 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) { drm_core_reclaim_buffers(dev, filp); } - drm_ioctl_desc_t savage_ioctls[] = { - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1} + , + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0} + , + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0} + , + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0} + , }; int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h index 6526c9aa7589..e1148e8e7994 100644 --- a/drivers/char/drm/savage_drm.h +++ b/drivers/char/drm/savage_drm.h @@ -42,12 +42,13 @@ #define SAVAGE_NR_TEX_REGIONS 16 #define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16 -#endif /* __SAVAGE_SAREA_DEFINES__ */ +#endif /* __SAVAGE_SAREA_DEFINES__ */ typedef struct _drm_savage_sarea { /* LRU lists for texture memory in agp space and on the card. */ - drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1]; + drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS + + 1]; unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; /* Mechanism to validate card state. @@ -101,24 +102,24 @@ typedef struct drm_savage_init { typedef union drm_savage_cmd_header drm_savage_cmd_header_t; typedef struct drm_savage_cmdbuf { - /* command buffer in client's address space */ + /* command buffer in client's address space */ drm_savage_cmd_header_t __user *cmd_addr; unsigned int size; /* size of the command buffer in 64bit units */ unsigned int dma_idx; /* DMA buffer index to use */ int discard; /* discard DMA buffer when done */ - /* vertex buffer in client's address space */ + /* vertex buffer in client's address space */ unsigned int __user *vb_addr; unsigned int vb_size; /* size of client vertex buffer in bytes */ unsigned int vb_stride; /* stride of vertices in 32bit words */ - /* boxes in client's address space */ + /* boxes in client's address space */ drm_clip_rect_t __user *box_addr; unsigned int nbox; /* number of clipping boxes */ } drm_savage_cmdbuf_t; -#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */ -#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */ -#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */ +#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */ +#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */ +#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */ typedef struct drm_savage_event { unsigned int count; unsigned int flags; @@ -126,21 +127,21 @@ typedef struct drm_savage_event { /* Commands for the cmdbuf ioctl */ -#define SAVAGE_CMD_STATE 0 /* a range of state registers */ -#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */ -#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */ -#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */ -#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */ -#define SAVAGE_CMD_CLEAR 5 /* clear buffers */ -#define SAVAGE_CMD_SWAP 6 /* swap buffers */ +#define SAVAGE_CMD_STATE 0 /* a range of state registers */ +#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */ +#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */ +#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */ +#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */ +#define SAVAGE_CMD_CLEAR 5 /* clear buffers */ +#define SAVAGE_CMD_SWAP 6 /* swap buffers */ /* Primitive types */ -#define SAVAGE_PRIM_TRILIST 0 /* triangle list */ -#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */ -#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */ -#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat - * shading on s3d */ +#define SAVAGE_PRIM_TRILIST 0 /* triangle list */ +#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */ +#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */ +#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat + * shading on s3d */ /* Skip flags (vertex format) */ @@ -172,38 +173,38 @@ union drm_savage_cmd_header { unsigned short pad1; unsigned short pad2; unsigned short pad3; - } cmd; /* generic */ + } cmd; /* generic */ struct { unsigned char cmd; unsigned char global; /* need idle engine? */ unsigned short count; /* number of consecutive registers */ unsigned short start; /* first register */ unsigned short pad3; - } state; /* SAVAGE_CMD_STATE */ + } state; /* SAVAGE_CMD_STATE */ struct { unsigned char cmd; unsigned char prim; /* primitive type */ unsigned short skip; /* vertex format (skip flags) */ unsigned short count; /* number of vertices */ unsigned short start; /* first vertex in DMA/vertex buffer */ - } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */ + } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */ struct { unsigned char cmd; unsigned char prim; unsigned short skip; unsigned short count; /* number of indices that follow */ unsigned short pad3; - } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */ + } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */ struct { unsigned char cmd; unsigned char pad0; unsigned short pad1; unsigned int flags; - } clear0; /* SAVAGE_CMD_CLEAR */ + } clear0; /* SAVAGE_CMD_CLEAR */ struct { unsigned int mask; unsigned int value; - } clear1; /* SAVAGE_CMD_CLEAR data */ + } clear1; /* SAVAGE_CMD_CLEAR data */ }; #endif diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c index ac8d270427ca..0906f9a5d8f9 100644 --- a/drivers/char/drm/savage_drv.c +++ b/drivers/char/drm/savage_drv.c @@ -30,30 +30,28 @@ #include "drm_pciids.h" -static int postinit( struct drm_device *dev, unsigned long flags ) +static int postinit(struct drm_device *dev, unsigned long flags) { - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -66,8 +64,7 @@ extern int savage_max_ioctl; static struct drm_driver driver = { .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | - DRIVER_HAVE_DMA | DRIVER_PCI_DMA, + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, .dev_priv_size = sizeof(drm_savage_buf_priv_t), .preinit = savage_preinit, .postinit = postinit, @@ -79,18 +76,19 @@ static struct drm_driver driver = { .ioctls = savage_ioctls, .dma_ioctl = savage_bci_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init savage_init(void) @@ -107,6 +105,6 @@ static void __exit savage_exit(void) module_init(savage_init); module_exit(savage_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h index a45434944658..358f4fb2712a 100644 --- a/drivers/char/drm/savage_drv.h +++ b/drivers/char/drm/savage_drv.h @@ -65,7 +65,7 @@ typedef struct drm_savage_dma_page { drm_savage_age_t age; unsigned int used, flushed; } drm_savage_dma_page_t; -#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */ +#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */ /* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command * size of 16kbytes or 4k entries. Minimum requirement would be * 10kbytes for 255 40-byte vertices in one drawing command. */ @@ -184,13 +184,13 @@ typedef struct drm_savage_private { unsigned int waiting; /* config/hardware-dependent function pointers */ - int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n); - int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e); + int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n); + int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e); /* Err, there is a macro wait_event in include/linux/wait.h. * Avoid unwanted macro expansion. */ - void (*emit_clip_rect)(struct drm_savage_private *dev_priv, - drm_clip_rect_t *pbox); - void (*dma_flush)(struct drm_savage_private *dev_priv); + void (*emit_clip_rect) (struct drm_savage_private * dev_priv, + drm_clip_rect_t * pbox); + void (*dma_flush) (struct drm_savage_private * dev_priv); } drm_savage_private_t; /* ioctls */ @@ -198,23 +198,23 @@ extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS); extern int savage_bci_buffers(DRM_IOCTL_ARGS); /* BCI functions */ -extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, +extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, unsigned int flags); -extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf); -extern void savage_dma_reset(drm_savage_private_t *dev_priv); -extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page); -extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, +extern void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf); +extern void savage_dma_reset(drm_savage_private_t * dev_priv); +extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); +extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n); -extern int savage_preinit(drm_device_t *dev, unsigned long chipset); -extern int savage_postcleanup(drm_device_t *dev); -extern int savage_do_cleanup_bci(drm_device_t *dev); -extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp); +extern int savage_preinit(drm_device_t * dev, unsigned long chipset); +extern int savage_postcleanup(drm_device_t * dev); +extern int savage_do_cleanup_bci(drm_device_t * dev); +extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); /* state functions */ -extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox); -extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox); +extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, + drm_clip_rect_t * pbox); +extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, + drm_clip_rect_t * pbox); #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ @@ -222,10 +222,10 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */ #define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */ -#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region +#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region * inside the MMIO region */ -#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip - * BCI FIFO */ +#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip + * BCI FIFO */ /* * MMIO registers @@ -278,7 +278,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define SAVAGE_TEXADDR1_S4 0x23 #define SAVAGE_TEXBLEND0_S4 0x24 #define SAVAGE_TEXBLEND1_S4 0x25 -#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */ +#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */ #define SAVAGE_TEXDESCR_S4 0x27 #define SAVAGE_FOGTABLE_S4 0x28 #define SAVAGE_FOGCTRL_S4 0x30 @@ -293,7 +293,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define SAVAGE_TEXBLENDCOLOR_S4 0x39 /* Savage3D/MX/IX 3D registers */ #define SAVAGE_TEXPALADDR_S3D 0x18 -#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */ +#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */ #define SAVAGE_TEXADDR_S3D 0x1A #define SAVAGE_TEXDESCR_S3D 0x1B #define SAVAGE_TEXCTRL_S3D 0x1C @@ -305,7 +305,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define SAVAGE_DESTCTRL_S3D 0x34 #define SAVAGE_SCSTART_S3D 0x35 #define SAVAGE_SCEND_S3D 0x36 -#define SAVAGE_ZWATERMARK_S3D 0x37 +#define SAVAGE_ZWATERMARK_S3D 0x37 #define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38 /* common stuff */ #define SAVAGE_VERTBUFADDR 0x3e @@ -313,9 +313,9 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define SAVAGE_DMABUFADDR 0x51 /* texture enable bits (needed for tex addr checking) */ -#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */ -#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */ -#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */ +#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */ +#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */ +#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */ /* Global fields in Savage4/Twister/ProSavage 3D registers: * @@ -576,4 +576,4 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, #define TEST_AGE( age, e, w ) \ ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) ) -#endif /* __SAVAGE_DRV_H__ */ +#endif /* __SAVAGE_DRV_H__ */ diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c index 475695a00083..39654cb5d570 100644 --- a/drivers/char/drm/savage_state.c +++ b/drivers/char/drm/savage_state.c @@ -26,48 +26,48 @@ #include "savage_drm.h" #include "savage_drv.h" -void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox) +void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, + drm_clip_rect_t * pbox) { uint32_t scstart = dev_priv->state.s3d.new_scstart; - uint32_t scend = dev_priv->state.s3d.new_scend; + uint32_t scend = dev_priv->state.s3d.new_scend; scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) | - ((uint32_t)pbox->x1 & 0x000007ff) | - (((uint32_t)pbox->y1 << 16) & 0x07ff0000); - scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) | - (((uint32_t)pbox->x2-1) & 0x000007ff) | - ((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000); + ((uint32_t) pbox->x1 & 0x000007ff) | + (((uint32_t) pbox->y1 << 16) & 0x07ff0000); + scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) | + (((uint32_t) pbox->x2 - 1) & 0x000007ff) | + ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000); if (scstart != dev_priv->state.s3d.scstart || - scend != dev_priv->state.s3d.scend) { + scend != dev_priv->state.s3d.scend) { DMA_LOCALS; BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D); + DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2); DMA_WRITE(scstart); DMA_WRITE(scend); dev_priv->state.s3d.scstart = scstart; - dev_priv->state.s3d.scend = scend; + dev_priv->state.s3d.scend = scend; dev_priv->waiting = 1; DMA_COMMIT(); } } -void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox) +void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, + drm_clip_rect_t * pbox) { uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) | - ((uint32_t)pbox->x1 & 0x000007ff) | - (((uint32_t)pbox->y1 << 12) & 0x00fff000); + ((uint32_t) pbox->x1 & 0x000007ff) | + (((uint32_t) pbox->y1 << 12) & 0x00fff000); drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) | - (((uint32_t)pbox->x2-1) & 0x000007ff) | - ((((uint32_t)pbox->y2-1) << 12) & 0x00fff000); + (((uint32_t) pbox->x2 - 1) & 0x000007ff) | + ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000); if (drawctrl0 != dev_priv->state.s4.drawctrl0 || drawctrl1 != dev_priv->state.s4.drawctrl1) { DMA_LOCALS; BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D); + DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2); DMA_WRITE(drawctrl0); DMA_WRITE(drawctrl1); @@ -78,22 +78,23 @@ void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, } } -static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, +static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit, uint32_t addr) { - if ((addr & 6) != 2) { /* reserved bits */ + if ((addr & 6) != 2) { /* reserved bits */ DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr); return DRM_ERR(EINVAL); } - if (!(addr & 1)) { /* local */ + if (!(addr & 1)) { /* local */ addr &= ~7; - if (addr < dev_priv->texture_offset || - addr >= dev_priv->texture_offset+dev_priv->texture_size) { - DRM_ERROR("bad texAddr%d %08x (local addr out of range)\n", - unit, addr); + if (addr < dev_priv->texture_offset || + addr >= dev_priv->texture_offset + dev_priv->texture_size) { + DRM_ERROR + ("bad texAddr%d %08x (local addr out of range)\n", + unit, addr); return DRM_ERR(EINVAL); } - } else { /* AGP */ + } else { /* AGP */ if (!dev_priv->agp_textures) { DRM_ERROR("bad texAddr%d %08x (AGP not available)\n", unit, addr); @@ -103,8 +104,9 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, if (addr < dev_priv->agp_textures->offset || addr >= (dev_priv->agp_textures->offset + dev_priv->agp_textures->size)) { - DRM_ERROR("bad texAddr%d %08x (AGP addr out of range)\n", - unit, addr); + DRM_ERROR + ("bad texAddr%d %08x (AGP addr out of range)\n", + unit, addr); return DRM_ERR(EINVAL); } } @@ -122,14 +124,14 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, (dev_priv->state.where & ~(mask)); \ } \ } while (0) -static int savage_verify_state_s3d(drm_savage_private_t *dev_priv, +static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, unsigned int start, unsigned int count, - const uint32_t __user *regs) + const uint32_t __user * regs) { if (start < SAVAGE_TEXPALADDR_S3D || - start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { + start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start+count-1); + start, start + count - 1); return DRM_ERR(EINVAL); } @@ -140,28 +142,29 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv, /* if any texture regs were changed ... */ if (start <= SAVAGE_TEXCTRL_S3D && - start+count > SAVAGE_TEXPALADDR_S3D) { + start + count > SAVAGE_TEXPALADDR_S3D) { /* ... check texture state */ SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl); SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) - return savage_verify_texaddr( - dev_priv, 0, dev_priv->state.s3d.texaddr); + return savage_verify_texaddr(dev_priv, 0, + dev_priv->state.s3d. + texaddr); } return 0; } -static int savage_verify_state_s4(drm_savage_private_t *dev_priv, +static int savage_verify_state_s4(drm_savage_private_t * dev_priv, unsigned int start, unsigned int count, - const uint32_t __user *regs) + const uint32_t __user * regs) { int ret = 0; if (start < SAVAGE_DRAWLOCALCTRL_S4 || - start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) { + start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) { DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start+count-1); + start, start + count - 1); return DRM_ERR(EINVAL); } @@ -171,28 +174,30 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv, ~SAVAGE_SCISSOR_MASK_S4); /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXDESCR_S4 && - start+count > SAVAGE_TEXPALADDR_S4) { + if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) { /* ... check texture state */ SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) - ret |= savage_verify_texaddr( - dev_priv, 0, dev_priv->state.s4.texaddr0); + ret |= + savage_verify_texaddr(dev_priv, 0, + dev_priv->state.s4.texaddr0); if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) - ret |= savage_verify_texaddr( - dev_priv, 1, dev_priv->state.s4.texaddr1); + ret |= + savage_verify_texaddr(dev_priv, 1, + dev_priv->state.s4.texaddr1); } return ret; } + #undef SAVE_STATE #undef SAVE_STATE_MASK -static int savage_dispatch_state(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const uint32_t __user *regs) +static int savage_dispatch_state(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const uint32_t __user * regs) { unsigned int count = cmd_header->state.count; unsigned int start = cmd_header->state.start; @@ -204,7 +209,7 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, if (!count) return 0; - if (DRM_VERIFYAREA_READ(regs, count*4)) + if (DRM_VERIFYAREA_READ(regs, count * 4)) return DRM_ERR(EFAULT); if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { @@ -213,14 +218,14 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, return ret; /* scissor regs are emitted in savage_dispatch_draw */ if (start < SAVAGE_SCSTART_S3D) { - if (start+count > SAVAGE_SCEND_S3D+1) - count2 = count - (SAVAGE_SCEND_S3D+1 - start); - if (start+count > SAVAGE_SCSTART_S3D) + if (start + count > SAVAGE_SCEND_S3D + 1) + count2 = count - (SAVAGE_SCEND_S3D + 1 - start); + if (start + count > SAVAGE_SCSTART_S3D) count = SAVAGE_SCSTART_S3D - start; } else if (start <= SAVAGE_SCEND_S3D) { - if (start+count > SAVAGE_SCEND_S3D+1) { - count -= SAVAGE_SCEND_S3D+1 - start; - start = SAVAGE_SCEND_S3D+1; + if (start + count > SAVAGE_SCEND_S3D + 1) { + count -= SAVAGE_SCEND_S3D + 1 - start; + start = SAVAGE_SCEND_S3D + 1; } else return 0; } @@ -230,23 +235,24 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, return ret; /* scissor regs are emitted in savage_dispatch_draw */ if (start < SAVAGE_DRAWCTRL0_S4) { - if (start+count > SAVAGE_DRAWCTRL1_S4+1) - count2 = count - (SAVAGE_DRAWCTRL1_S4+1 - start); - if (start+count > SAVAGE_DRAWCTRL0_S4) + if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) + count2 = + count - (SAVAGE_DRAWCTRL1_S4 + 1 - start); + if (start + count > SAVAGE_DRAWCTRL0_S4) count = SAVAGE_DRAWCTRL0_S4 - start; } else if (start <= SAVAGE_DRAWCTRL1_S4) { - if (start+count > SAVAGE_DRAWCTRL1_S4+1) { - count -= SAVAGE_DRAWCTRL1_S4+1 - start; - start = SAVAGE_DRAWCTRL1_S4+1; + if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) { + count -= SAVAGE_DRAWCTRL1_S4 + 1 - start; + start = SAVAGE_DRAWCTRL1_S4 + 1; } else return 0; } } - bci_size = count + (count+254)/255 + count2 + (count2+254)/255; + bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255; if (cmd_header->state.global) { - BEGIN_DMA(bci_size+1); + BEGIN_DMA(bci_size + 1); DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); dev_priv->waiting = 1; } else { @@ -273,9 +279,9 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const drm_buf_t *dmabuf) +static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const drm_buf_t * dmabuf) { unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; @@ -286,8 +292,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, BCI_LOCALS; if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return DRM_ERR(EINVAL); + DRM_ERROR("called without dma buffers!\n"); + return DRM_ERR(EINVAL); } if (!n) @@ -307,8 +313,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, case SAVAGE_PRIM_TRISTRIP: case SAVAGE_PRIM_TRIFAN: if (n < 3) { - DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n", - n); + DRM_ERROR + ("wrong number of vertices %u in TRIFAN/STRIP\n", + n); return DRM_ERR(EINVAL); } break; @@ -319,17 +326,15 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", - skip); + DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); return DRM_ERR(EINVAL); } } else { unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); + (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - + (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", - skip); + DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); return DRM_ERR(EINVAL); } if (reorder) { @@ -338,9 +343,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, } } - if (start + n > dmabuf->total/32) { + if (start + n > dmabuf->total / 32) { DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, dmabuf->total/32); + start, start + n - 1, dmabuf->total / 32); return DRM_ERR(EINVAL); } @@ -375,32 +380,33 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, /* Need to reorder indices for correct flat * shading while preserving the clock sense * for correct culling. Only on Savage3D. */ - int reorder[3] = {-1, -1, -1}; - reorder[start%3] = 2; + int reorder[3] = { -1, -1, -1 }; + reorder[start % 3] = 2; - BEGIN_BCI((count+1+1)/2); - BCI_DRAW_INDICES_S3D(count, prim, start+2); + BEGIN_BCI((count + 1 + 1) / 2); + BCI_DRAW_INDICES_S3D(count, prim, start + 2); - for (i = start+1; i+1 < start+count; i += 2) + for (i = start + 1; i + 1 < start + count; i += 2) BCI_WRITE((i + reorder[i % 3]) | - ((i+1 + reorder[(i+1) % 3]) << 16)); - if (i < start+count) - BCI_WRITE(i + reorder[i%3]); + ((i + 1 + + reorder[(i + 1) % 3]) << 16)); + if (i < start + count) + BCI_WRITE(i + reorder[i % 3]); } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count+1+1)/2); + BEGIN_BCI((count + 1 + 1) / 2); BCI_DRAW_INDICES_S3D(count, prim, start); - for (i = start+1; i+1 < start+count; i += 2) - BCI_WRITE(i | ((i+1) << 16)); - if (i < start+count) + for (i = start + 1; i + 1 < start + count; i += 2) + BCI_WRITE(i | ((i + 1) << 16)); + if (i < start + count) BCI_WRITE(i); } else { - BEGIN_BCI((count+2+1)/2); + BEGIN_BCI((count + 2 + 1) / 2); BCI_DRAW_INDICES_S4(count, prim, skip); - for (i = start; i+1 < start+count; i += 2) - BCI_WRITE(i | ((i+1) << 16)); - if (i < start+count) + for (i = start; i + 1 < start + count; i += 2) + BCI_WRITE(i | ((i + 1) << 16)); + if (i < start + count) BCI_WRITE(i); } @@ -413,11 +419,10 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const uint32_t __user *vtxbuf, - unsigned int vb_size, - unsigned int vb_stride) +static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const uint32_t __user * vtxbuf, + unsigned int vb_size, unsigned int vb_stride) { unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; @@ -445,8 +450,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, case SAVAGE_PRIM_TRISTRIP: case SAVAGE_PRIM_TRIFAN: if (n < 3) { - DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n", - n); + DRM_ERROR + ("wrong number of vertices %u in TRIFAN/STRIP\n", + n); return DRM_ERR(EINVAL); } break; @@ -460,18 +466,18 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, DRM_ERROR("invalid skip flags 0x%04x\n", skip); return DRM_ERR(EINVAL); } - vtx_size = 8; /* full vertex */ + vtx_size = 8; /* full vertex */ } else { if (skip > SAVAGE_SKIP_ALL_S4) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); return DRM_ERR(EINVAL); } - vtx_size = 10; /* full vertex */ + vtx_size = 10; /* full vertex */ } vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); + (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + + (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); if (vtx_size > vb_stride) { DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", @@ -479,9 +485,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, return DRM_ERR(EINVAL); } - if (start + n > vb_size / (vb_stride*4)) { + if (start + n > vb_size / (vb_stride * 4)) { DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, vb_size / (vb_stride*4)); + start, start + n - 1, vb_size / (vb_stride * 4)); return DRM_ERR(EINVAL); } @@ -493,31 +499,31 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, /* Need to reorder vertices for correct flat * shading while preserving the clock sense * for correct culling. Only on Savage3D. */ - int reorder[3] = {-1, -1, -1}; - reorder[start%3] = 2; + int reorder[3] = { -1, -1, -1 }; + reorder[start % 3] = 2; - BEGIN_DMA(count*vtx_size+1); + BEGIN_DMA(count * vtx_size + 1); DMA_DRAW_PRIMITIVE(count, prim, skip); - for (i = start; i < start+count; ++i) { + for (i = start; i < start + count; ++i) { unsigned int j = i + reorder[i % 3]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], vtx_size); } DMA_COMMIT(); } else { - BEGIN_DMA(count*vtx_size+1); + BEGIN_DMA(count * vtx_size + 1); DMA_DRAW_PRIMITIVE(count, prim, skip); if (vb_stride == vtx_size) { - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start], - vtx_size*count); + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start], + vtx_size * count); } else { - for (i = start; i < start+count; ++i) { - DMA_COPY_FROM_USER( - &vtxbuf[vb_stride*i], - vtx_size); + for (i = start; i < start + count; ++i) { + DMA_COPY_FROM_USER(&vtxbuf + [vb_stride * i], + vtx_size); } } @@ -533,10 +539,10 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const uint16_t __user *usr_idx, - const drm_buf_t *dmabuf) +static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const uint16_t __user * usr_idx, + const drm_buf_t * dmabuf) { unsigned char reorder = 0; unsigned int prim = cmd_header->idx.prim; @@ -546,8 +552,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, BCI_LOCALS; if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return DRM_ERR(EINVAL); + DRM_ERROR("called without dma buffers!\n"); + return DRM_ERR(EINVAL); } if (!n) @@ -559,16 +565,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, prim = SAVAGE_PRIM_TRILIST; case SAVAGE_PRIM_TRILIST: if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", - n); + DRM_ERROR("wrong number of indices %u in TRILIST\n", n); return DRM_ERR(EINVAL); } break; case SAVAGE_PRIM_TRISTRIP: case SAVAGE_PRIM_TRIFAN: if (n < 3) { - DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n", - n); + DRM_ERROR + ("wrong number of indices %u in TRIFAN/STRIP\n", n); return DRM_ERR(EINVAL); } break; @@ -579,17 +584,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", - skip); + DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); return DRM_ERR(EINVAL); } } else { unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); + (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - + (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", - skip); + DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); return DRM_ERR(EINVAL); } if (reorder) { @@ -629,11 +632,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, uint16_t idx[255]; /* Copy and check indices */ - DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2); + DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); for (i = 0; i < count; ++i) { - if (idx[i] > dmabuf->total/32) { + if (idx[i] > dmabuf->total / 32) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], dmabuf->total/32); + i, idx[i], dmabuf->total / 32); return DRM_ERR(EINVAL); } } @@ -642,30 +645,31 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, /* Need to reorder indices for correct flat * shading while preserving the clock sense * for correct culling. Only on Savage3D. */ - int reorder[3] = {2, -1, -1}; + int reorder[3] = { 2, -1, -1 }; - BEGIN_BCI((count+1+1)/2); + BEGIN_BCI((count + 1 + 1) / 2); BCI_DRAW_INDICES_S3D(count, prim, idx[2]); - for (i = 1; i+1 < count; i += 2) + for (i = 1; i + 1 < count; i += 2) BCI_WRITE(idx[i + reorder[i % 3]] | - (idx[i+1 + reorder[(i+1) % 3]] << 16)); + (idx[i + 1 + reorder[(i + 1) % 3]] << + 16)); if (i < count) - BCI_WRITE(idx[i + reorder[i%3]]); + BCI_WRITE(idx[i + reorder[i % 3]]); } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count+1+1)/2); + BEGIN_BCI((count + 1 + 1) / 2); BCI_DRAW_INDICES_S3D(count, prim, idx[0]); - for (i = 1; i+1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i+1] << 16)); + for (i = 1; i + 1 < count; i += 2) + BCI_WRITE(idx[i] | (idx[i + 1] << 16)); if (i < count) BCI_WRITE(idx[i]); } else { - BEGIN_BCI((count+2+1)/2); + BEGIN_BCI((count + 2 + 1) / 2); BCI_DRAW_INDICES_S4(count, prim, skip); - for (i = 0; i+1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i+1] << 16)); + for (i = 0; i + 1 < count; i += 2) + BCI_WRITE(idx[i] | (idx[i + 1] << 16)); if (i < count) BCI_WRITE(idx[i]); } @@ -679,12 +683,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const uint16_t __user *usr_idx, - const uint32_t __user *vtxbuf, - unsigned int vb_size, - unsigned int vb_stride) +static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const uint16_t __user * usr_idx, + const uint32_t __user * vtxbuf, + unsigned int vb_size, unsigned int vb_stride) { unsigned char reorder = 0; unsigned int prim = cmd_header->idx.prim; @@ -703,16 +706,15 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, prim = SAVAGE_PRIM_TRILIST; case SAVAGE_PRIM_TRILIST: if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", - n); + DRM_ERROR("wrong number of indices %u in TRILIST\n", n); return DRM_ERR(EINVAL); } break; case SAVAGE_PRIM_TRISTRIP: case SAVAGE_PRIM_TRIFAN: if (n < 3) { - DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n", - n); + DRM_ERROR + ("wrong number of indices %u in TRIFAN/STRIP\n", n); return DRM_ERR(EINVAL); } break; @@ -726,18 +728,18 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, DRM_ERROR("invalid skip flags 0x%04x\n", skip); return DRM_ERR(EINVAL); } - vtx_size = 8; /* full vertex */ + vtx_size = 8; /* full vertex */ } else { if (skip > SAVAGE_SKIP_ALL_S4) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); return DRM_ERR(EINVAL); } - vtx_size = 10; /* full vertex */ + vtx_size = 10; /* full vertex */ } vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); + (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + + (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); if (vtx_size > vb_stride) { DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", @@ -753,11 +755,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, uint16_t idx[255]; /* Copy and check indices */ - DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2); + DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); for (i = 0; i < count; ++i) { - if (idx[i] > vb_size / (vb_stride*4)) { + if (idx[i] > vb_size / (vb_stride * 4)) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], vb_size / (vb_stride*4)); + i, idx[i], vb_size / (vb_stride * 4)); return DRM_ERR(EINVAL); } } @@ -766,25 +768,25 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, /* Need to reorder vertices for correct flat * shading while preserving the clock sense * for correct culling. Only on Savage3D. */ - int reorder[3] = {2, -1, -1}; + int reorder[3] = { 2, -1, -1 }; - BEGIN_DMA(count*vtx_size+1); + BEGIN_DMA(count * vtx_size + 1); DMA_DRAW_PRIMITIVE(count, prim, skip); for (i = 0; i < count; ++i) { unsigned int j = idx[i + reorder[i % 3]]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], vtx_size); } DMA_COMMIT(); } else { - BEGIN_DMA(count*vtx_size+1); + BEGIN_DMA(count * vtx_size + 1); DMA_DRAW_PRIMITIVE(count, prim, skip); for (i = 0; i < count; ++i) { unsigned int j = idx[i]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], vtx_size); } @@ -800,11 +802,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_clear(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t *cmd_header, - const drm_savage_cmd_header_t __user *data, +static int savage_dispatch_clear(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t * cmd_header, + const drm_savage_cmd_header_t __user * data, unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + const drm_clip_rect_t __user * usr_boxes) { unsigned int flags = cmd_header->clear0.flags, mask, value; unsigned int clear_cmd; @@ -814,18 +816,17 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, if (nbox == 0) return 0; - DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t*)data) + DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t *)data) ->clear1.mask); - DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t*)data) + DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t *)data) ->clear1.value); clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; - BCI_CMD_SET_ROP(clear_cmd,0xCC); + BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; + BCI_CMD_SET_ROP(clear_cmd, 0xCC); nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) + - ((flags & SAVAGE_BACK) ? 1 : 0) + - ((flags & SAVAGE_DEPTH) ? 1 : 0); + ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0); if (nbufs == 0) return 0; @@ -844,12 +845,12 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, x = box.x1, y = box.y1; w = box.x2 - box.x1; h = box.y2 - box.y1; - BEGIN_DMA(nbufs*6); + BEGIN_DMA(nbufs * 6); for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { if (!(flags & buf)) continue; DMA_WRITE(clear_cmd); - switch(buf) { + switch (buf) { case SAVAGE_FRONT: DMA_WRITE(dev_priv->front_offset); DMA_WRITE(dev_priv->front_bd); @@ -880,9 +881,9 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, return 0; } -static int savage_dispatch_swap(drm_savage_private_t *dev_priv, +static int savage_dispatch_swap(drm_savage_private_t * dev_priv, unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + const drm_clip_rect_t __user * usr_boxes) { unsigned int swap_cmd; unsigned int i; @@ -892,8 +893,8 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv, return 0; swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD; - BCI_CMD_SET_ROP(swap_cmd,0xCC); + BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD; + BCI_CMD_SET_ROP(swap_cmd, 0xCC); for (i = 0; i < nbox; ++i) { drm_clip_rect_t box; @@ -905,21 +906,21 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv, DMA_WRITE(dev_priv->back_bd); DMA_WRITE(BCI_X_Y(box.x1, box.y1)); DMA_WRITE(BCI_X_Y(box.x1, box.y1)); - DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1)); + DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1)); DMA_COMMIT(); } return 0; } -static int savage_dispatch_draw(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t __user *start, - const drm_savage_cmd_header_t __user *end, - const drm_buf_t *dmabuf, - const unsigned int __user *usr_vtxbuf, +static int savage_dispatch_draw(drm_savage_private_t * dev_priv, + const drm_savage_cmd_header_t __user * start, + const drm_savage_cmd_header_t __user * end, + const drm_buf_t * dmabuf, + const unsigned int __user * usr_vtxbuf, unsigned int vb_size, unsigned int vb_stride, unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + const drm_clip_rect_t __user * usr_boxes) { unsigned int i, j; int ret; @@ -938,32 +939,42 @@ static int savage_dispatch_draw(drm_savage_private_t *dev_priv, usr_cmdbuf++; switch (cmd_header.cmd.cmd) { case SAVAGE_CMD_DMA_PRIM: - ret = savage_dispatch_dma_prim( - dev_priv, &cmd_header, dmabuf); + ret = + savage_dispatch_dma_prim(dev_priv, + &cmd_header, + dmabuf); break; case SAVAGE_CMD_VB_PRIM: - ret = savage_dispatch_vb_prim( - dev_priv, &cmd_header, - (const uint32_t __user *)usr_vtxbuf, - vb_size, vb_stride); + ret = + savage_dispatch_vb_prim(dev_priv, + &cmd_header, + (const uint32_t + __user *) + usr_vtxbuf, vb_size, + vb_stride); break; case SAVAGE_CMD_DMA_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_dma_idx( - dev_priv, &cmd_header, - (const uint16_t __user *)usr_cmdbuf, - dmabuf); + ret = + savage_dispatch_dma_idx(dev_priv, + &cmd_header, + (const uint16_t + __user *) + usr_cmdbuf, dmabuf); usr_cmdbuf += j; break; case SAVAGE_CMD_VB_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_vb_idx( - dev_priv, &cmd_header, - (const uint16_t __user *)usr_cmdbuf, - (const uint32_t __user *)usr_vtxbuf, - vb_size, vb_stride); + ret = + savage_dispatch_vb_idx(dev_priv, + &cmd_header, + (const uint16_t + __user *)usr_cmdbuf, + (const uint32_t + __user *)usr_vtxbuf, + vb_size, vb_stride); usr_cmdbuf += j; break; default: @@ -997,16 +1008,17 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) int ret = 0; DRM_DEBUG("\n"); - + LOCK_TEST_WITH_RETURN(dev, filp); - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data, + DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *) data, sizeof(cmdbuf)); if (dma && dma->buflist) { if (cmdbuf.dma_idx > dma->buf_count) { - DRM_ERROR("vertex buffer index %u out of range (0-%u)\n", - cmdbuf.dma_idx, dma->buf_count-1); + DRM_ERROR + ("vertex buffer index %u out of range (0-%u)\n", + cmdbuf.dma_idx, dma->buf_count - 1); return DRM_ERR(EINVAL); } dmabuf = dma->buflist[cmdbuf.dma_idx]; @@ -1014,14 +1026,14 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) dmabuf = NULL; } - usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr; + usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr; usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr; - usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr; - if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) || - (cmdbuf.vb_size && DRM_VERIFYAREA_READ( - usr_vtxbuf, cmdbuf.vb_size)) || - (cmdbuf.nbox && DRM_VERIFYAREA_READ( - usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t)))) + usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr; + if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) || + (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size)) + || (cmdbuf.nbox + && DRM_VERIFYAREA_READ(usr_boxes, + cmdbuf.nbox * sizeof(drm_clip_rect_t)))) return DRM_ERR(EFAULT); /* Make sure writes to DMA buffers are finished before sending @@ -1058,17 +1070,21 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) case SAVAGE_CMD_DMA_PRIM: case SAVAGE_CMD_VB_PRIM: if (!first_draw_cmd) - first_draw_cmd = usr_cmdbuf-1; + first_draw_cmd = usr_cmdbuf - 1; usr_cmdbuf += j; i += j; break; default: if (first_draw_cmd) { - ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, usr_cmdbuf-1, - dmabuf, usr_vtxbuf, cmdbuf.vb_size, - cmdbuf.vb_stride, - cmdbuf.nbox, usr_boxes); + ret = + savage_dispatch_draw(dev_priv, + first_draw_cmd, + usr_cmdbuf - 1, dmabuf, + usr_vtxbuf, + cmdbuf.vb_size, + cmdbuf.vb_stride, + cmdbuf.nbox, + usr_boxes); if (ret != 0) return ret; first_draw_cmd = NULL; @@ -1086,9 +1102,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) DMA_FLUSH(); return DRM_ERR(EINVAL); } - ret = savage_dispatch_state( - dev_priv, &cmd_header, - (uint32_t __user *)usr_cmdbuf); + ret = savage_dispatch_state(dev_priv, &cmd_header, + (uint32_t __user *) + usr_cmdbuf); usr_cmdbuf += j; i += j; break; @@ -1122,10 +1138,11 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) } if (first_draw_cmd) { - ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf, - usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride, - cmdbuf.nbox, usr_boxes); + ret = + savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf, + dmabuf, usr_vtxbuf, cmdbuf.vb_size, + cmdbuf.vb_stride, cmdbuf.nbox, + usr_boxes); if (ret != 0) { DMA_FLUSH(); return ret; diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h index e99c3a43abbc..8f273da76ddb 100644 --- a/drivers/char/drm/sis_drm.h +++ b/drivers/char/drm/sis_drm.h @@ -39,4 +39,4 @@ typedef struct { unsigned int offset, size; } drm_sis_fb_t; -#endif /* __SIS_DRM_H__ */ +#endif /* __SIS_DRM_H__ */ diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c index f441714faae3..6d0cb2226005 100644 --- a/drivers/char/drm/sis_drv.c +++ b/drivers/char/drm/sis_drv.c @@ -10,11 +10,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -31,31 +31,29 @@ #include "sis_drv.h" #include "drm_pciids.h" - -static int postinit( struct drm_device *dev, unsigned long flags ) + +static int postinit(struct drm_device *dev, unsigned long flags) { - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - dev->primary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -77,18 +75,18 @@ static struct drm_driver driver = { .version = version, .ioctls = sis_ioctls, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init sis_init(void) @@ -105,6 +103,6 @@ static void __exit sis_exit(void) module_init(sis_init); module_exit(sis_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h index 5be36b5caec9..4ef3d6226418 100644 --- a/drivers/char/drm/sis_drv.h +++ b/drivers/char/drm/sis_drv.h @@ -10,11 +10,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -22,7 +22,7 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * */ #ifndef _SIS_DRV_H_ @@ -46,7 +46,7 @@ typedef struct drm_sis_private { memHeap_t *FBHeap; } drm_sis_private_t; -extern int sis_init_context(drm_device_t *dev, int context); -extern int sis_final_context(drm_device_t *dev, int context); +extern int sis_init_context(drm_device_t * dev, int context); +extern int sis_final_context(drm_device_t * dev, int context); #endif diff --git a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c index e37ed8ce48df..2e485d482943 100644 --- a/drivers/char/drm/sis_ds.c +++ b/drivers/char/drm/sis_ds.c @@ -10,11 +10,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -22,10 +22,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Sung-Ching Lin - * + * */ #include "drmP.h" @@ -41,13 +41,13 @@ set_t *setInit(void) int i; set_t *set; - set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER); + set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER); if (set != NULL) { for (i = 0; i < SET_SIZE; i++) { - set->list[i].free_next = i + 1; + set->list[i].free_next = i + 1; set->list[i].alloc_next = -1; } - set->list[SET_SIZE-1].free_next = -1; + set->list[SET_SIZE - 1].free_next = -1; set->free = 0; set->alloc = -1; set->trace = -1; @@ -55,10 +55,10 @@ set_t *setInit(void) return set; } -int setAdd(set_t *set, ITEM_TYPE item) +int setAdd(set_t * set, ITEM_TYPE item) { int free = set->free; - + if (free != -1) { set->list[free].val = item; set->free = set->list[free].free_next; @@ -67,16 +67,16 @@ int setAdd(set_t *set, ITEM_TYPE item) } set->list[free].alloc_next = set->alloc; - set->alloc = free; - set->list[free].free_next = -1; + set->alloc = free; + set->list[free].free_next = -1; return 1; } -int setDel(set_t *set, ITEM_TYPE item) +int setDel(set_t * set, ITEM_TYPE item) { int alloc = set->alloc; - int prev = -1; + int prev = -1; while (alloc != -1) { if (set->list[alloc].val == item) { @@ -103,7 +103,7 @@ int setDel(set_t *set, ITEM_TYPE item) /* setFirst -> setAdd -> setNext is wrong */ -int setFirst(set_t *set, ITEM_TYPE *item) +int setFirst(set_t * set, ITEM_TYPE * item) { if (set->alloc == -1) return 0; @@ -114,7 +114,7 @@ int setFirst(set_t *set, ITEM_TYPE *item) return 1; } -int setNext(set_t *set, ITEM_TYPE *item) +int setNext(set_t * set, ITEM_TYPE * item) { if (set->trace == -1) return 0; @@ -125,7 +125,7 @@ int setNext(set_t *set, ITEM_TYPE *item) return 1; } -int setDestroy(set_t *set) +int setDestroy(set_t * set) { drm_free(set, sizeof(set_t), DRM_MEM_DRIVER); @@ -149,35 +149,34 @@ int setDestroy(set_t *set) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #define ISFREE(bptr) ((bptr)->free) -memHeap_t *mmInit(int ofs, - int size) +memHeap_t *mmInit(int ofs, int size) { PMemBlock blocks; if (size <= 0) return NULL; - blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); + blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); if (blocks != NULL) { blocks->ofs = ofs; blocks->size = size; blocks->free = 1; - return (memHeap_t *)blocks; + return (memHeap_t *) blocks; } else return NULL; } /* Checks if a pointer 'b' is part of the heap 'heap' */ -int mmBlockInHeap(memHeap_t *heap, PMemBlock b) +int mmBlockInHeap(memHeap_t * heap, PMemBlock b) { TMemBlock *p; @@ -194,16 +193,16 @@ int mmBlockInHeap(memHeap_t *heap, PMemBlock b) return 0; } -static TMemBlock* SliceBlock(TMemBlock *p, - int startofs, int size, +static TMemBlock *SliceBlock(TMemBlock * p, + int startofs, int size, int reserved, int alignment) { TMemBlock *newblock; /* break left */ if (startofs > p->ofs) { - newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock), - DRM_MEM_DRIVER); + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); newblock->ofs = startofs; newblock->size = p->size - (startofs - p->ofs); newblock->free = 1; @@ -215,8 +214,8 @@ static TMemBlock* SliceBlock(TMemBlock *p, /* break right */ if (size < p->size) { - newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock), - DRM_MEM_DRIVER); + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); newblock->ofs = startofs + size; newblock->size = p->size - size; newblock->free = 1; @@ -232,37 +231,37 @@ static TMemBlock* SliceBlock(TMemBlock *p, return p; } -PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch) +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch) { - int mask,startofs, endofs; + int mask, startofs, endofs; TMemBlock *p; - + if (heap == NULL || align2 < 0 || size <= 0) return NULL; - mask = (1 << align2)-1; + mask = (1 << align2) - 1; startofs = 0; - p = (TMemBlock *)heap; + p = (TMemBlock *) heap; while (p != NULL) { if (ISFREE(p)) { startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { + if (startofs < startSearch) { startofs = startSearch; } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) + endofs = startofs + size; + if (endofs <= (p->ofs + p->size)) break; } p = p->next; } if (p == NULL) return NULL; - p = SliceBlock(p,startofs,size,0,mask+1); + p = SliceBlock(p, startofs, size, 0, mask + 1); p->heap = heap; return p; } -static __inline__ int Join2Blocks(TMemBlock *p) +static __inline__ int Join2Blocks(TMemBlock * p) { if (p->free && p->next && p->next->free) { TMemBlock *q = p->next; @@ -295,7 +294,6 @@ int mmFreeMem(PMemBlock b) p->free = 1; Join2Blocks(p); if (prev) - Join2Blocks(prev); + Join2Blocks(prev); return 0; } - diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h index 171ee75afa57..da850b4f5440 100644 --- a/drivers/char/drm/sis_ds.h +++ b/drivers/char/drm/sis_ds.h @@ -10,11 +10,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -22,10 +22,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Sung-Ching Lin - * + * */ #ifndef __SIS_DS_H__ @@ -50,11 +50,11 @@ typedef struct { } set_t; set_t *setInit(void); -int setAdd(set_t *set, ITEM_TYPE item); -int setDel(set_t *set, ITEM_TYPE item); -int setFirst(set_t *set, ITEM_TYPE *item); -int setNext(set_t *set, ITEM_TYPE *item); -int setDestroy(set_t *set); +int setAdd(set_t * set, ITEM_TYPE item); +int setDel(set_t * set, ITEM_TYPE item); +int setFirst(set_t * set, ITEM_TYPE * item); +int setNext(set_t * set, ITEM_TYPE * item); +int setDestroy(set_t * set); /* * GLX Hardware Device Driver common code @@ -73,9 +73,9 @@ int setDestroy(set_t *set); * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ @@ -83,7 +83,7 @@ int setDestroy(set_t *set); struct mem_block_t { struct mem_block_t *next; struct mem_block_t *heap; - int ofs,size; + int ofs, size; int align; unsigned int free:1; unsigned int reserved:1; @@ -109,11 +109,11 @@ static __inline__ void mmMarkReserved(PMemBlock b) b->reserved = 1; } -/* +/* * input: total size in bytes * return: a heap pointer if OK, NULL if error */ -memHeap_t *mmInit( int ofs, int size ); +memHeap_t *mmInit(int ofs, int size); /* * Allocate 'size' bytes with 2^align2 bytes alignment, @@ -125,21 +125,21 @@ memHeap_t *mmInit( int ofs, int size ); * startSearch = linear offset from start of heap to begin search * return: pointer to the allocated block, 0 if error */ -PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch ); +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch); /* * Returns 1 if the block 'b' is part of the heap 'heap' */ -int mmBlockInHeap( PMemBlock heap, PMemBlock b ); +int mmBlockInHeap(PMemBlock heap, PMemBlock b); /* * Free block starts at offset * input: pointer to a block * return: 0 if OK, -1 if error */ -int mmFreeMem( PMemBlock b ); +int mmFreeMem(PMemBlock b); /* For debuging purpose. */ -void mmDumpMemInfo( memHeap_t *mmInit ); +void mmDumpMemInfo(memHeap_t * mmInit); -#endif /* __SIS_DS_H__ */ +#endif /* __SIS_DS_H__ */ diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c index 6610c5576d22..50e32384ad93 100644 --- a/drivers/char/drm/sis_mm.c +++ b/drivers/char/drm/sis_mm.c @@ -10,11 +10,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -22,10 +22,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Sung-Ching Lin - * + * */ #include "drmP.h" @@ -37,25 +37,23 @@ #endif #define MAX_CONTEXT 100 -#define VIDEO_TYPE 0 +#define VIDEO_TYPE 0 #define AGP_TYPE 1 typedef struct { int used; int context; - set_t *sets[2]; /* 0 for video, 1 for AGP */ + set_t *sets[2]; /* 0 for video, 1 for AGP */ } sis_context_t; static sis_context_t global_ppriv[MAX_CONTEXT]; - static int add_alloc_set(int context, int type, unsigned int val) { int i, retval = 0; - + for (i = 0; i < MAX_CONTEXT; i++) { - if (global_ppriv[i].used && global_ppriv[i].context == context) - { + if (global_ppriv[i].used && global_ppriv[i].context == context) { retval = setAdd(global_ppriv[i].sets[type], val); break; } @@ -64,12 +62,11 @@ static int add_alloc_set(int context, int type, unsigned int val) } static int del_alloc_set(int context, int type, unsigned int val) -{ +{ int i, retval = 0; for (i = 0; i < MAX_CONTEXT; i++) { - if (global_ppriv[i].used && global_ppriv[i].context == context) - { + if (global_ppriv[i].used && global_ppriv[i].context == context) { retval = setDel(global_ppriv[i].sets[type], val); break; } @@ -77,15 +74,15 @@ static int del_alloc_set(int context, int type, unsigned int val) return retval; } -/* fb management via fb device */ +/* fb management via fb device */ #if defined(__linux__) && defined(CONFIG_FB_SIS) -static int sis_fb_init( DRM_IOCTL_ARGS ) +static int sis_fb_init(DRM_IOCTL_ARGS) { return 0; } -static int sis_fb_alloc( DRM_IOCTL_ARGS ) +static int sis_fb_alloc(DRM_IOCTL_ARGS) { drm_sis_mem_t fb; struct sis_memreq req; @@ -105,7 +102,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS ) sis_free(req.offset); retval = DRM_ERR(EINVAL); } - } else { + } else { fb.offset = 0; fb.size = 0; fb.free = 0; @@ -118,19 +115,19 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS ) return retval; } -static int sis_fb_free( DRM_IOCTL_ARGS ) +static int sis_fb_free(DRM_IOCTL_ARGS) { drm_sis_mem_t fb; int retval = 0; - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb)); + DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb)); if (!fb.free) return DRM_ERR(EINVAL); if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) retval = DRM_ERR(EINVAL); - sis_free((u32)fb.free); + sis_free((u32) fb.free); DRM_DEBUG("free fb, offset = %lu\n", fb.free); @@ -149,17 +146,17 @@ static int sis_fb_free( DRM_IOCTL_ARGS ) * X driver/sisfb HW- Command- * framebuffer memory DRI heap Cursor queue */ -static int sis_fb_init( DRM_IOCTL_ARGS ) +static int sis_fb_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; drm_sis_fb_t fb; - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb)); + DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb)); if (dev_priv == NULL) { dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t), - DRM_MEM_DRIVER); + DRM_MEM_DRIVER); dev_priv = dev->dev_private; if (dev_priv == NULL) return ENOMEM; @@ -175,7 +172,7 @@ static int sis_fb_init( DRM_IOCTL_ARGS ) return 0; } -static int sis_fb_alloc( DRM_IOCTL_ARGS ) +static int sis_fb_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; @@ -186,9 +183,9 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS ) if (dev_priv == NULL || dev_priv->FBHeap == NULL) return DRM_ERR(EINVAL); - + DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); - + block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0); if (block) { /* TODO */ @@ -196,7 +193,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS ) fb.free = (unsigned long)block; if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) { DRM_DEBUG("adding to allocation set fails\n"); - mmFreeMem((PMemBlock)fb.free); + mmFreeMem((PMemBlock) fb.free); retval = DRM_ERR(EINVAL); } } else { @@ -212,7 +209,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS ) return retval; } -static int sis_fb_free( DRM_IOCTL_ARGS ) +static int sis_fb_free(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; @@ -221,14 +218,14 @@ static int sis_fb_free( DRM_IOCTL_ARGS ) if (dev_priv == NULL || dev_priv->FBHeap == NULL) return DRM_ERR(EINVAL); - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb)); + DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb)); - if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free)) + if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free)) return DRM_ERR(EINVAL); if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) return DRM_ERR(EINVAL); - mmFreeMem((PMemBlock)fb.free); + mmFreeMem((PMemBlock) fb.free); DRM_DEBUG("free fb, free = 0x%lx\n", fb.free); @@ -237,9 +234,9 @@ static int sis_fb_free( DRM_IOCTL_ARGS ) #endif -/* agp memory management */ +/* agp memory management */ -static int sis_ioctl_agp_init( DRM_IOCTL_ARGS ) +static int sis_ioctl_agp_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; @@ -247,7 +244,7 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS ) if (dev_priv == NULL) { dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t), - DRM_MEM_DRIVER); + DRM_MEM_DRIVER); dev_priv = dev->dev_private; if (dev_priv == NULL) return ENOMEM; @@ -256,16 +253,17 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS ) if (dev_priv->AGPHeap != NULL) return DRM_ERR(EINVAL); - DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *)data, sizeof(agp)); + DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data, + sizeof(agp)); dev_priv->AGPHeap = mmInit(agp.offset, agp.size); DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size); - + return 0; } -static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS ) +static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; @@ -273,12 +271,12 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS ) drm_sis_mem_t agp; PMemBlock block; int retval = 0; - + if (dev_priv == NULL || dev_priv->AGPHeap == NULL) return DRM_ERR(EINVAL); - + DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp)); - + block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0); if (block) { /* TODO */ @@ -286,10 +284,10 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS ) agp.free = (unsigned long)block; if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) { DRM_DEBUG("adding to allocation set fails\n"); - mmFreeMem((PMemBlock)agp.free); + mmFreeMem((PMemBlock) agp.free); retval = -1; } - } else { + } else { agp.offset = 0; agp.size = 0; agp.free = 0; @@ -302,7 +300,7 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS ) return retval; } -static int sis_ioctl_agp_free( DRM_IOCTL_ARGS ) +static int sis_ioctl_agp_free(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; @@ -311,12 +309,13 @@ static int sis_ioctl_agp_free( DRM_IOCTL_ARGS ) if (dev_priv == NULL || dev_priv->AGPHeap == NULL) return DRM_ERR(EINVAL); - DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *)data, sizeof(agp)); + DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data, + sizeof(agp)); - if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free)) + if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free)) return DRM_ERR(EINVAL); - mmFreeMem((PMemBlock)agp.free); + mmFreeMem((PMemBlock) agp.free); if (!del_alloc_set(agp.context, AGP_TYPE, agp.free)) return DRM_ERR(EINVAL); @@ -329,31 +328,30 @@ int sis_init_context(struct drm_device *dev, int context) { int i; - for (i = 0; i < MAX_CONTEXT ; i++) { + for (i = 0; i < MAX_CONTEXT; i++) { if (global_ppriv[i].used && (global_ppriv[i].context == context)) break; } if (i >= MAX_CONTEXT) { - for (i = 0; i < MAX_CONTEXT ; i++) { + for (i = 0; i < MAX_CONTEXT; i++) { if (!global_ppriv[i].used) { global_ppriv[i].context = context; global_ppriv[i].used = 1; global_ppriv[i].sets[0] = setInit(); global_ppriv[i].sets[1] = setInit(); DRM_DEBUG("init allocation set, socket=%d, " - "context = %d\n", i, context); + "context = %d\n", i, context); break; } } if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) || - (global_ppriv[i].sets[1] == NULL)) - { + (global_ppriv[i].sets[1] == NULL)) { return 0; } } - + return 1; } @@ -361,7 +359,7 @@ int sis_final_context(struct drm_device *dev, int context) { int i; - for (i=0; iprimary.minor, - pci_pretty_name(dev->pdev) - ); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); return 0; } -static int version( drm_version_t *version ) +static int version(drm_version_t * version) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; - DRM_COPY( version->name, DRIVER_NAME ); - DRM_COPY( version->date, DRIVER_DATE ); - DRM_COPY( version->desc, DRIVER_DESC ); + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); return 0; } @@ -75,18 +73,18 @@ static struct drm_driver driver = { .postinit = postinit, .version = version, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init tdfx_init(void) @@ -102,6 +100,6 @@ static void __exit tdfx_exit(void) module_init(tdfx_init); module_exit(tdfx_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h index cf61bb514db1..462375d543b9 100644 --- a/drivers/char/drm/via_3d_reg.h +++ b/drivers/char/drm/via_3d_reg.h @@ -1643,7 +1643,6 @@ #define HC_HAGPBpID_STOP 0x00000002 #define HC_HAGPBpH_MASK 0x00ffffff - #define VIA_VIDEO_HEADER5 0xFE040000 #define VIA_VIDEO_HEADER6 0xFE050000 #define VIA_VIDEO_HEADER7 0xFE060000 diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index 4f60f7f4193d..d4b1766608b0 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c @@ -1,11 +1,11 @@ /* via_dma.c -- DMA support for the VIA Unichrome/Pro - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A. * All Rights Reserved. - * + * * Copyright 2004 The Unichrome project. * All Rights Reserved. * @@ -23,14 +23,14 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * - * Authors: - * Tungsten Graphics, - * Erdi Chen, + * Authors: + * Tungsten Graphics, + * Erdi Chen, * Thomas Hellstrom. */ @@ -61,34 +61,31 @@ dev_priv->dma_low +=8; \ } -#define via_flush_write_combine() DRM_MEMORYBARRIER() +#define via_flush_write_combine() DRM_MEMORYBARRIER() #define VIA_OUT_RING_QW(w1,w2) \ *vb++ = (w1); \ *vb++ = (w2); \ - dev_priv->dma_low += 8; + dev_priv->dma_low += 8; static void via_cmdbuf_start(drm_via_private_t * dev_priv); static void via_cmdbuf_pause(drm_via_private_t * dev_priv); static void via_cmdbuf_reset(drm_via_private_t * dev_priv); static void via_cmdbuf_rewind(drm_via_private_t * dev_priv); static int via_wait_idle(drm_via_private_t * dev_priv); -static void via_pad_cache(drm_via_private_t *dev_priv, int qwords); - +static void via_pad_cache(drm_via_private_t * dev_priv, int qwords); /* * Free space in command buffer. */ -static uint32_t -via_cmdbuf_space(drm_via_private_t *dev_priv) +static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) { - uint32_t agp_base = dev_priv->dma_offset + - (uint32_t) dev_priv->agpAddr; + uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; - - return ((hw_addr <= dev_priv->dma_low) ? - (dev_priv->dma_high + hw_addr - dev_priv->dma_low) : + + return ((hw_addr <= dev_priv->dma_low) ? + (dev_priv->dma_high + hw_addr - dev_priv->dma_low) : (hw_addr - dev_priv->dma_low)); } @@ -96,15 +93,13 @@ via_cmdbuf_space(drm_via_private_t *dev_priv) * How much does the command regulator lag behind? */ -static uint32_t -via_cmdbuf_lag(drm_via_private_t *dev_priv) +static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) { - uint32_t agp_base = dev_priv->dma_offset + - (uint32_t) dev_priv->agpAddr; + uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; - - return ((hw_addr <= dev_priv->dma_low) ? - (dev_priv->dma_low - hw_addr) : + + return ((hw_addr <= dev_priv->dma_low) ? + (dev_priv->dma_low - hw_addr) : (dev_priv->dma_wrap + dev_priv->dma_low - hw_addr)); } @@ -121,20 +116,20 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) uint32_t count; hw_addr_ptr = dev_priv->hw_addr_ptr; cur_addr = dev_priv->dma_low; - next_addr = cur_addr + size + 512*1024; + next_addr = cur_addr + size + 512 * 1024; count = 1000000; do { - hw_addr = *hw_addr_ptr - agp_base; + hw_addr = *hw_addr_ptr - agp_base; if (count-- == 0) { - DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", - hw_addr, cur_addr, next_addr); + DRM_ERROR + ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", + hw_addr, cur_addr, next_addr); return -1; } } while ((cur_addr < hw_addr) && (next_addr >= hw_addr)); return 0; } - /* * Checks whether buffer head has reach the end. Rewind the ring buffer * when necessary. @@ -145,7 +140,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv, unsigned int size) { - if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) { + if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) > + dev_priv->dma_high) { via_cmdbuf_rewind(dev_priv); } if (via_cmdbuf_wait(dev_priv, size) != 0) { @@ -159,7 +155,7 @@ int via_dma_cleanup(drm_device_t * dev) { if (dev->dev_private) { drm_via_private_t *dev_priv = - (drm_via_private_t *) dev->dev_private; + (drm_via_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start) { via_cmdbuf_reset(dev_priv); @@ -189,7 +185,7 @@ static int via_initialize(drm_device_t * dev, } if (!dev->agp || !dev->agp->base) { - DRM_ERROR("%s called with no agp memory available\n", + DRM_ERROR("%s called with no agp memory available\n", __FUNCTION__); return DRM_ERR(EFAULT); } @@ -247,10 +243,10 @@ int via_dma_init(DRM_IOCTL_ARGS) else retcode = via_dma_cleanup(dev); break; - case VIA_DMA_INITIALIZED: - retcode = (dev_priv->ring.virtual_start != NULL) ? - 0: DRM_ERR( EFAULT ); - break; + case VIA_DMA_INITIALIZED: + retcode = (dev_priv->ring.virtual_start != NULL) ? + 0 : DRM_ERR(EFAULT); + break; default: retcode = DRM_ERR(EINVAL); break; @@ -259,8 +255,6 @@ int via_dma_init(DRM_IOCTL_ARGS) return retcode; } - - static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) { drm_via_private_t *dev_priv; @@ -277,8 +271,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) if (cmd->size > VIA_PCI_BUF_SIZE) { return DRM_ERR(ENOMEM); - } - + } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) return DRM_ERR(EFAULT); @@ -289,19 +282,19 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) * copy it to AGP memory when ready. */ - - if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) { + if ((ret = + via_verify_command_stream((uint32_t *) dev_priv->pci_buf, + cmd->size, dev, 1))) { return ret; } - - + vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); if (vb == NULL) { return DRM_ERR(EAGAIN); } memcpy(vb, dev_priv->pci_buf, cmd->size); - + dev_priv->dma_low += cmd->size; /* @@ -310,7 +303,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) */ if (cmd->size < 0x100) - via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3); + via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3); via_cmdbuf_pause(dev_priv); return 0; @@ -330,7 +323,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); return via_driver_dma_quiescent(dev); } @@ -341,7 +334,7 @@ int via_cmdbuffer(DRM_IOCTL_ARGS) drm_via_cmdbuffer_t cmdbuf; int ret; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, sizeof(cmdbuf)); @@ -356,8 +349,9 @@ int via_cmdbuffer(DRM_IOCTL_ARGS) return 0; } -extern int -via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size); +extern int +via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, + unsigned int size); static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) { @@ -366,15 +360,19 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, if (cmd->size > VIA_PCI_BUF_SIZE) { return DRM_ERR(ENOMEM); - } + } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) return DRM_ERR(EFAULT); - - if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) { + + if ((ret = + via_verify_command_stream((uint32_t *) dev_priv->pci_buf, + cmd->size, dev, 0))) { return ret; } - - ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size); + + ret = + via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, + cmd->size); return ret; } @@ -384,7 +382,7 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS) drm_via_cmdbuffer_t cmdbuf; int ret; - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, sizeof(cmdbuf)); @@ -400,17 +398,15 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS) return 0; } - static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, uint32_t * vb, int qw_count) { - for (; qw_count > 0; --qw_count) { + for (; qw_count > 0; --qw_count) { VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); } return vb; } - /* * This function is used internally by ring buffer mangement code. * @@ -426,7 +422,7 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) * modifying the pause address stored in the buffer itself. If * the regulator has already paused, restart it. */ -static int via_hook_segment(drm_via_private_t *dev_priv, +static int via_hook_segment(drm_via_private_t * dev_priv, uint32_t pause_addr_hi, uint32_t pause_addr_lo, int no_pci_fire) { @@ -434,7 +430,7 @@ static int via_hook_segment(drm_via_private_t *dev_priv, volatile uint32_t *paused_at = dev_priv->last_pause_ptr; via_flush_write_combine(); - while(! *(via_get_dma(dev_priv)-1)); + while (!*(via_get_dma(dev_priv) - 1)) ; *dev_priv->last_pause_ptr = pause_addr_lo; via_flush_write_combine(); @@ -443,55 +439,53 @@ static int via_hook_segment(drm_via_private_t *dev_priv, * Not sure it is needed. */ - while(! *dev_priv->last_pause_ptr); + while (!*dev_priv->last_pause_ptr) ; dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; - while(! *dev_priv->last_pause_ptr); - + while (!*dev_priv->last_pause_ptr) ; paused = 0; - count = 20; + count = 20; - while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--); + while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ; if ((count <= 8) && (count >= 0)) { uint32_t rgtr, ptr; rgtr = *(dev_priv->hw_addr_ptr); - ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + - dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - - CMDBUF_ALIGNMENT_SIZE; + ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - + CMDBUF_ALIGNMENT_SIZE; if (rgtr <= ptr) { - DRM_ERROR("Command regulator\npaused at count %d, address %x, " - "while current pause address is %x.\n" - "Please mail this message to " - "\n", - count, rgtr, ptr); + DRM_ERROR + ("Command regulator\npaused at count %d, address %x, " + "while current pause address is %x.\n" + "Please mail this message to " + "\n", count, + rgtr, ptr); } } - + if (paused && !no_pci_fire) { - uint32_t rgtr,ptr; + uint32_t rgtr, ptr; uint32_t ptr_low; count = 1000000; - while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--); - - rgtr = *(dev_priv->hw_addr_ptr); - ptr = ((char *)paused_at - dev_priv->dma_ptr) + - dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; - + while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) + && count--) ; - ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ? - ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0; + rgtr = *(dev_priv->hw_addr_ptr); + ptr = ((char *)paused_at - dev_priv->dma_ptr) + + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; + + ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? + ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0; if (rgtr <= ptr && rgtr >= ptr_low) { VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); - } + } } return paused; } - - static int via_wait_idle(drm_via_private_t * dev_priv) { int count = 10000000; @@ -502,9 +496,8 @@ static int via_wait_idle(drm_via_private_t * dev_priv) } static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, - uint32_t addr, uint32_t *cmd_addr_hi, - uint32_t *cmd_addr_lo, - int skip_wait) + uint32_t addr, uint32_t * cmd_addr_hi, + uint32_t * cmd_addr_lo, int skip_wait) { uint32_t agp_base; uint32_t cmd_addr, addr_lo, addr_hi; @@ -512,31 +505,26 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, uint32_t qw_pad_count; if (!skip_wait) - via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE); + via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE); vb = via_get_dma(dev_priv); - VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) | - (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16); + VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) | + (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16); agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) - - ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3); + ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3); - - cmd_addr = (addr) ? addr : - agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3); + cmd_addr = (addr) ? addr : + agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3); addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) | (cmd_addr & HC_HAGPBpL_MASK)); addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24)); vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1); - VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, - *cmd_addr_lo = addr_lo); + VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo); return vb; } - - - static void via_cmdbuf_start(drm_via_private_t * dev_priv) { uint32_t pause_addr_lo, pause_addr_hi; @@ -545,7 +533,6 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) uint32_t command; uint32_t agp_base; - dev_priv->dma_low = 0; agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; @@ -557,12 +544,12 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) | ((end_addr & 0xff000000) >> 16)); - dev_priv->last_pause_ptr = - via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, - &pause_addr_hi, & pause_addr_lo, 1) - 1; + dev_priv->last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, + &pause_addr_hi, &pause_addr_lo, 1) - 1; via_flush_write_combine(); - while(! *dev_priv->last_pause_ptr); + while (!*dev_priv->last_pause_ptr) ; VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, command); @@ -575,14 +562,14 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); } -static void via_pad_cache(drm_via_private_t *dev_priv, int qwords) +static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) { uint32_t *vb; via_cmdbuf_wait(dev_priv, qwords + 2); vb = via_get_dma(dev_priv); - VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16); - via_align_buffer(dev_priv,vb,qwords); + VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16); + via_align_buffer(dev_priv, vb, qwords); } static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) @@ -590,10 +577,9 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) uint32_t *vb = via_get_dma(dev_priv); SetReg2DAGP(0x0C, (0 | (0 << 16))); SetReg2DAGP(0x10, 0 | (0 << 16)); - SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); } - static void via_cmdbuf_jump(drm_via_private_t * dev_priv) { uint32_t agp_base; @@ -603,11 +589,10 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) uint32_t dma_low_save1, dma_low_save2; agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; - via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, + via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, &jump_addr_lo, 0); - - dev_priv->dma_wrap = dev_priv->dma_low; + dev_priv->dma_wrap = dev_priv->dma_low; /* * Wrap command buffer to the beginning. @@ -619,11 +604,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) } via_dummy_bitblt(dev_priv); - via_dummy_bitblt(dev_priv); + via_dummy_bitblt(dev_priv); - last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, - &pause_addr_lo, 0) -1; - via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0) - 1; + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, &pause_addr_lo, 0); *last_pause_ptr = pause_addr_lo; @@ -638,23 +624,23 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) * does not seem to get updated immediately when a jump occurs. */ - last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, - &pause_addr_lo, 0) -1; - via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0) - 1; + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, &pause_addr_lo, 0); *last_pause_ptr = pause_addr_lo; dma_low_save2 = dev_priv->dma_low; - dev_priv->dma_low = dma_low_save1; - via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0); + dev_priv->dma_low = dma_low_save1; + via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0); dev_priv->dma_low = dma_low_save2; - via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0); + via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); } - static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) { - via_cmdbuf_jump(dev_priv); + via_cmdbuf_jump(dev_priv); } static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) @@ -662,10 +648,9 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) uint32_t pause_addr_lo, pause_addr_hi; via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0); - via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0); + via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); } - static void via_cmdbuf_pause(drm_via_private_t * dev_priv) { via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE); @@ -681,8 +666,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv) * User interface to the space and lag functions. */ -int -via_cmdbuf_size(DRM_IOCTL_ARGS) +int via_cmdbuf_size(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_via_cmdbuf_size_t d_siz; @@ -691,7 +675,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS) drm_via_private_t *dev_priv; DRM_DEBUG("via cmdbuf_size\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, filp); dev_priv = (drm_via_private_t *) dev->dev_private; @@ -704,12 +688,12 @@ via_cmdbuf_size(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data, sizeof(d_siz)); - count = 1000000; tmp_size = d_siz.size; - switch(d_siz.func) { + switch (d_siz.func) { case VIA_CMDBUF_SPACE: - while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) { + while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) + && count--) { if (!d_siz.wait) { break; } @@ -720,7 +704,8 @@ via_cmdbuf_size(DRM_IOCTL_ARGS) } break; case VIA_CMDBUF_LAG: - while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) { + while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) + && count--) { if (!d_siz.wait) { break; } diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h index be346bb0a26a..ebde9206115e 100644 --- a/drivers/char/drm/via_drm.h +++ b/drivers/char/drm/via_drm.h @@ -149,7 +149,7 @@ typedef struct _drm_via_dma_init { enum { VIA_INIT_DMA = 0x01, VIA_CLEANUP_DMA = 0x02, - VIA_DMA_INITIALIZED = 0x03 + VIA_DMA_INITIALIZED = 0x03 } func; unsigned long offset; @@ -212,7 +212,7 @@ typedef enum { #define VIA_IRQ_FLAGS_MASK 0xF0000000 -struct drm_via_wait_irq_request{ +struct drm_via_wait_irq_request { unsigned irq; via_irq_seq_type_t type; uint32_t sequence; diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index 275eefc79221..016665e0c69f 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c @@ -93,18 +93,18 @@ static struct drm_driver driver = { .ioctls = ioctls, .num_ioctls = DRM_ARRAY_SIZE(ioctls), .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - } + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init via_init(void) diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index 4eaa8b7c4c96..d902dc2f4fae 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h @@ -40,8 +40,6 @@ #define VIA_FIRE_BUF_SIZE 1024 #define VIA_NUM_IRQS 2 - - typedef struct drm_via_ring_buffer { drm_map_t map; char *virtual_start; @@ -55,7 +53,7 @@ typedef struct drm_via_irq { uint32_t enable_mask; wait_queue_head_t irq_queue; } drm_via_irq_t; - + typedef struct drm_via_private { drm_via_sarea_t *sarea_priv; drm_map_t *sarea; @@ -71,9 +69,9 @@ typedef struct drm_via_private { volatile uint32_t *last_pause_ptr; volatile uint32_t *hw_addr_ptr; drm_via_ring_buffer_t ring; - struct timeval last_vblank; - int last_vblank_valid; - unsigned usec_per_vblank; + struct timeval last_vblank; + int last_vblank_valid; + unsigned usec_per_vblank; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; @@ -82,8 +80,8 @@ typedef struct drm_via_private { drm_via_irq_t via_irqs[VIA_NUM_IRQS]; unsigned num_irqs; maskarray_t *irq_masks; - uint32_t irq_enable_mask; - uint32_t irq_pending_mask; + uint32_t irq_enable_mask; + uint32_t irq_pending_mask; } drm_via_private_t; /* VIA MMIO register access */ @@ -110,9 +108,8 @@ extern void via_driver_irq_uninstall(drm_device_t * dev); extern int via_dma_cleanup(drm_device_t * dev); extern void via_init_command_verifier(void); extern int via_driver_dma_quiescent(drm_device_t * dev); -extern void via_init_futex(drm_via_private_t *dev_priv); -extern void via_cleanup_futex(drm_via_private_t *dev_priv); -extern void via_release_futex(drm_via_private_t *dev_priv, int context); - +extern void via_init_futex(drm_via_private_t * dev_priv); +extern void via_cleanup_futex(drm_via_private_t * dev_priv); +extern void via_release_futex(drm_via_private_t * dev_priv, int context); #endif diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index e8027f3a93b0..d023add1929b 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c @@ -54,23 +54,26 @@ /* * Device-specific IRQs go here. This type might need to be extended with * the register if there are multiple IRQ control registers. - * Currently we activate the HQV interrupts of Unichrome Pro group A. + * Currently we activate the HQV interrupts of Unichrome Pro group A. */ static maskarray_t via_pro_group_a_irqs[] = { - {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 }, - {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }}; -static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t); + {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, + 0x00000000}, + {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, + 0x00000000} +}; +static int via_num_pro_group_a = + sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); -static maskarray_t via_unichrome_irqs[] = {}; -static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t); +static maskarray_t via_unichrome_irqs[] = { }; +static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); - -static unsigned time_diff(struct timeval *now,struct timeval *then) +static unsigned time_diff(struct timeval *now, struct timeval *then) { - return (now->tv_usec >= then->tv_usec) ? - now->tv_usec - then->tv_usec : - 1000000 - (then->tv_usec - now->tv_usec); + return (now->tv_usec >= then->tv_usec) ? + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); } irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) @@ -86,38 +89,37 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBLANK_PENDING) { atomic_inc(&dev->vbl_received); - if (!(atomic_read(&dev->vbl_received) & 0x0F)) { + if (!(atomic_read(&dev->vbl_received) & 0x0F)) { do_gettimeofday(&cur_vblank); - if (dev_priv->last_vblank_valid) { - dev_priv->usec_per_vblank = - time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4; + if (dev_priv->last_vblank_valid) { + dev_priv->usec_per_vblank = + time_diff(&cur_vblank, + &dev_priv->last_vblank) >> 4; } dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; - } - if (!(atomic_read(&dev->vbl_received) & 0xFF)) { + } + if (!(atomic_read(&dev->vbl_received) & 0xFF)) { DRM_DEBUG("US per vblank is: %u\n", - dev_priv->usec_per_vblank); + dev_priv->usec_per_vblank); } DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); handled = 1; } - - for (i=0; inum_irqs; ++i) { + for (i = 0; i < dev_priv->num_irqs; ++i) { if (status & cur_irq->pending_mask) { - atomic_inc( &cur_irq->irq_received ); - DRM_WAKEUP( &cur_irq->irq_queue ); + atomic_inc(&cur_irq->irq_received); + DRM_WAKEUP(&cur_irq->irq_queue); handled = 1; } cur_irq++; } - + /* Acknowlege interrupts */ VIA_WRITE(VIA_REG_INTERRUPT, status); - if (handled) return IRQ_HANDLED; else @@ -131,7 +133,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) if (dev_priv) { /* Acknowlege interrupts */ status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status | + VIA_WRITE(VIA_REG_INTERRUPT, status | dev_priv->irq_pending_mask); } } @@ -158,12 +160,12 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) - *sequence) <= (1 << 23))); - + *sequence = cur_vblank; return ret; } -static int +static int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, unsigned int *sequence) { @@ -180,27 +182,29 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, return DRM_ERR(EINVAL); } - if (irq >= dev_priv->num_irqs ) { - DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq); + if (irq >= dev_priv->num_irqs) { + DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, + irq); return DRM_ERR(EINVAL); } - + cur_irq += irq; if (masks[irq][2] && !force_sequence) { DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, - ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4])); + ((VIA_READ(masks[irq][2]) & masks[irq][3]) == + masks[irq][4])); cur_irq_sequence = atomic_read(&cur_irq->irq_received); } else { DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, - (((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) - - *sequence) <= (1 << 23))); + (((cur_irq_sequence = + atomic_read(&cur_irq->irq_received)) - + *sequence) <= (1 << 23))); } *sequence = cur_irq_sequence; return ret; } - /* * drm_dma.h hooks */ @@ -219,29 +223,29 @@ void via_driver_irq_preinstall(drm_device_t * dev) dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; dev_priv->irq_masks = (dev_priv->pro_group_a) ? - via_pro_group_a_irqs : via_unichrome_irqs; + via_pro_group_a_irqs : via_unichrome_irqs; dev_priv->num_irqs = (dev_priv->pro_group_a) ? - via_num_pro_group_a : via_num_unichrome; - - for(i=0; i < dev_priv->num_irqs; ++i) { + via_num_pro_group_a : via_num_unichrome; + + for (i = 0; i < dev_priv->num_irqs; ++i) { atomic_set(&cur_irq->irq_received, 0); - cur_irq->enable_mask = dev_priv->irq_masks[i][0]; + cur_irq->enable_mask = dev_priv->irq_masks[i][0]; cur_irq->pending_mask = dev_priv->irq_masks[i][1]; - DRM_INIT_WAITQUEUE( &cur_irq->irq_queue ); + DRM_INIT_WAITQUEUE(&cur_irq->irq_queue); dev_priv->irq_enable_mask |= cur_irq->enable_mask; dev_priv->irq_pending_mask |= cur_irq->pending_mask; cur_irq++; - + DRM_DEBUG("Initializing IRQ %d\n", i); } - - dev_priv->last_vblank_valid = 0; + + dev_priv->last_vblank_valid = 0; // Clear VSync interrupt regs status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status & + VIA_WRITE(VIA_REG_INTERRUPT, status & ~(dev_priv->irq_enable_mask)); - + /* Clear bits if they're already high */ viadrv_acknowledge_irqs(dev_priv); } @@ -262,7 +266,7 @@ void via_driver_irq_postinstall(drm_device_t * dev) VIA_WRITE8(0x83d4, 0x11); VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); - + } } @@ -280,7 +284,7 @@ void via_driver_irq_uninstall(drm_device_t * dev) VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status & + VIA_WRITE(VIA_REG_INTERRUPT, status & ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask)); } } @@ -302,7 +306,7 @@ int via_wait_irq(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait)); if (irqwait.request.irq >= dev_priv->num_irqs) { - DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, + DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irqwait.request.irq); return DRM_ERR(EINVAL); } @@ -320,7 +324,7 @@ int via_wait_irq(DRM_IOCTL_ARGS) } if (irqwait.request.type & VIA_IRQ_SIGNAL) { - DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n", + DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n", __FUNCTION__); return DRM_ERR(EINVAL); } diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c index bb171139e737..6bd6ac52ad1b 100644 --- a/drivers/char/drm/via_map.c +++ b/drivers/char/drm/via_map.c @@ -66,7 +66,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) dev_priv->agpAddr = init->agpAddr; - via_init_futex( dev_priv ); + via_init_futex(dev_priv); dev_priv->pro_group_a = (dev->pdev->device == 0x3118); dev->dev_private = (void *)dev_priv; @@ -107,5 +107,3 @@ int via_map_init(DRM_IOCTL_ARGS) return -EINVAL; } - - diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c index 13921f3c0ec2..3baddacdff26 100644 --- a/drivers/char/drm/via_mm.c +++ b/drivers/char/drm/via_mm.c @@ -81,7 +81,8 @@ int via_agp_init(DRM_IOCTL_ARGS) AgpHeap = via_mmInit(agp.offset, agp.size); - DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size); + DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, + (unsigned long)agp.size); return 0; } @@ -97,7 +98,8 @@ int via_fb_init(DRM_IOCTL_ARGS) FBHeap = via_mmInit(fb.offset, fb.size); - DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size); + DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, + (unsigned long)fb.size); return 0; } @@ -134,8 +136,8 @@ int via_init_context(struct drm_device *dev, int context) } int via_final_context(struct drm_device *dev, int context) -{ - int i; +{ + int i; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; for (i = 0; i < MAX_CONTEXT; i++) @@ -171,14 +173,13 @@ int via_final_context(struct drm_device *dev, int context) via_setDestroy(set); global_ppriv[i].used = 0; } - via_release_futex(dev_priv, context); - - + via_release_futex(dev_priv, context); + #if defined(__linux__) /* Linux specific until context tracking code gets ported to BSD */ /* Last context, perform cleanup */ if (dev->ctx_count == 1 && dev->dev_private) { - DRM_DEBUG("Last Context\n"); + DRM_DEBUG("Last Context\n"); if (dev->irq) drm_irq_uninstall(dev); diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c index 07923b0c7a97..4ac495f297f7 100644 --- a/drivers/char/drm/via_verifier.c +++ b/drivers/char/drm/via_verifier.c @@ -28,7 +28,6 @@ * be very slow. */ - #include "via_3d_reg.h" #include "drmP.h" #include "drm.h" @@ -36,7 +35,7 @@ #include "via_verifier.h" #include "via_drv.h" -typedef enum{ +typedef enum { state_command, state_header2, state_header1, @@ -45,8 +44,7 @@ typedef enum{ state_error } verifier_state_t; - -typedef enum{ +typedef enum { no_check = 0, check_for_header2, check_for_header1, @@ -74,16 +72,16 @@ typedef enum{ check_for_vertex_count, check_number_texunits, forbidden_command -}hazard_t; +} hazard_t; /* * Associates each hazard above with a possible multi-command * sequence. For example an address that is split over multiple - * commands and that needs to be checked at the first command + * commands and that needs to be checked at the first command * that does not include any part of the address. */ -static drm_via_sequence_t seqs[] = { +static drm_via_sequence_t seqs[] = { no_sequence, no_sequence, no_sequence, @@ -110,14 +108,12 @@ static drm_via_sequence_t seqs[] = { tex_address, no_sequence }; - -typedef struct{ + +typedef struct { unsigned int code; hazard_t hz; } hz_init_t; - - static hz_init_t init_table1[] = { {0xf2, check_for_header2_err}, {0xf0, check_for_header1_err}, @@ -169,8 +165,6 @@ static hz_init_t init_table1[] = { {0x7D, check_for_vertex_count} }; - - static hz_init_t init_table2[] = { {0xf2, check_for_header2_err}, {0xf0, check_for_header1_err}, @@ -235,49 +229,49 @@ static hz_init_t init_table3[] = { {0xcc, check_for_dummy}, {0x00, check_number_texunits} }; - - -static hazard_t table1[256]; -static hazard_t table2[256]; -static hazard_t table3[256]; - +static hazard_t table1[256]; +static hazard_t table2[256]; +static hazard_t table3[256]; static __inline__ int -eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words) +eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) { if ((*buf - buf_end) >= num_words) { *buf += num_words; return 0; - } + } DRM_ERROR("Illegal termination of DMA command buffer\n"); return 1; } - /* * Partially stolen from drm_memory.h */ -static __inline__ drm_map_t * -via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size, - drm_device_t *dev) +static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq, + unsigned long offset, + unsigned long size, + drm_device_t * dev) { struct list_head *list; drm_map_list_t *r_list; drm_map_t *map = seq->map_cache; - if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) { + if (map && map->offset <= offset + && (offset + size) <= (map->offset + map->size)) { return map; } - + list_for_each(list, &dev->maplist->head) { r_list = (drm_map_list_t *) list; map = r_list->map; if (!map) continue; - if (map->offset <= offset && (offset + size) <= (map->offset + map->size) && - !(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) { + if (map->offset <= offset + && (offset + size) <= (map->offset + map->size) + && !(map->flags & _DRM_RESTRICTED) + && (map->type == _DRM_AGP)) { seq->map_cache = map; return map; } @@ -285,54 +279,60 @@ via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned lon return NULL; } - /* - * Require that all AGP texture levels reside in the same AGP map which should + * Require that all AGP texture levels reside in the same AGP map which should * be mappable by the client. This is not a big restriction. - * FIXME: To actually enforce this security policy strictly, drm_rmmap - * would have to wait for dma quiescent before removing an AGP map. + * FIXME: To actually enforce this security policy strictly, drm_rmmap + * would have to wait for dma quiescent before removing an AGP map. * The via_drm_lookup_agp_map call in reality seems to take * very little CPU time. */ - -static __inline__ int -finish_current_sequence(drm_via_state_t *cur_seq) +static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) { - switch(cur_seq->unfinished) { + switch (cur_seq->unfinished) { case z_address: DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr); break; case dest_address: - DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr); + DRM_DEBUG("Destination start address is 0x%x\n", + cur_seq->d_addr); break; case tex_address: - if (cur_seq->agp_texture) { - unsigned start = cur_seq->tex_level_lo[cur_seq->texture]; + if (cur_seq->agp_texture) { + unsigned start = + cur_seq->tex_level_lo[cur_seq->texture]; unsigned end = cur_seq->tex_level_hi[cur_seq->texture]; - unsigned long lo=~0, hi=0, tmp; + unsigned long lo = ~0, hi = 0, tmp; uint32_t *addr, *pitch, *height, tex; unsigned i; - if (end > 9) end = 9; - if (start > 9) start = 9; + if (end > 9) + end = 9; + if (start > 9) + start = 9; - addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]); + addr = + &(cur_seq->t_addr[tex = cur_seq->texture][start]); pitch = &(cur_seq->pitch[tex][start]); height = &(cur_seq->height[tex][start]); - for (i=start; i<= end; ++i) { + for (i = start; i <= end; ++i) { tmp = *addr++; - if (tmp < lo) lo = tmp; + if (tmp < lo) + lo = tmp; tmp += (*height++ << *pitch++); - if (tmp > hi) hi = tmp; + if (tmp > hi) + hi = tmp; } - if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) { - DRM_ERROR("AGP texture is not in allowed map\n"); + if (!via_drm_lookup_agp_map + (cur_seq, lo, hi - lo, cur_seq->dev)) { + DRM_ERROR + ("AGP texture is not in allowed map\n"); return 2; } - } + } break; default: break; @@ -341,73 +341,84 @@ finish_current_sequence(drm_via_state_t *cur_seq) return 0; } -static __inline__ int -investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) +static __inline__ int +investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) { register uint32_t tmp, *tmp_addr; if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) { int ret; - if ((ret = finish_current_sequence(cur_seq))) return ret; + if ((ret = finish_current_sequence(cur_seq))) + return ret; } - switch(hz) { + switch (hz) { case check_for_header2: - if (cmd == HALCYON_HEADER2) return 1; + if (cmd == HALCYON_HEADER2) + return 1; return 0; case check_for_header1: - if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1; + if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + return 1; return 0; case check_for_header2_err: - if (cmd == HALCYON_HEADER2) return 1; + if (cmd == HALCYON_HEADER2) + return 1; DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n"); break; case check_for_header1_err: - if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1; + if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + return 1; DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n"); break; case check_for_fire: - if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1; + if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) + return 1; DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n"); break; case check_for_dummy: - if (HC_DUMMY == cmd) return 0; + if (HC_DUMMY == cmd) + return 0; DRM_ERROR("Illegal DMA HC_DUMMY command\n"); break; case check_for_dd: - if (0xdddddddd == cmd) return 0; + if (0xdddddddd == cmd) + return 0; DRM_ERROR("Illegal DMA 0xdddddddd command\n"); break; case check_z_buffer_addr0: cur_seq->unfinished = z_address; cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) | - (cmd & 0x00FFFFFF); + (cmd & 0x00FFFFFF); return 0; case check_z_buffer_addr1: cur_seq->unfinished = z_address; cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) | - ((cmd & 0xFF) << 24); + ((cmd & 0xFF) << 24); return 0; case check_z_buffer_addr_mode: cur_seq->unfinished = z_address; - if ((cmd & 0x0000C000) == 0) return 0; + if ((cmd & 0x0000C000) == 0) + return 0; DRM_ERROR("Attempt to place Z buffer in system memory\n"); return 2; case check_destination_addr0: cur_seq->unfinished = dest_address; cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) | - (cmd & 0x00FFFFFF); + (cmd & 0x00FFFFFF); return 0; case check_destination_addr1: cur_seq->unfinished = dest_address; cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) | - ((cmd & 0xFF) << 24); + ((cmd & 0xFF) << 24); return 0; case check_destination_addr_mode: cur_seq->unfinished = dest_address; - if ((cmd & 0x0000C000) == 0) return 0; - DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n"); - return 2; + if ((cmd & 0x0000C000) == 0) + return 0; + DRM_ERROR + ("Attempt to place 3D drawing buffer in system memory\n"); + return 2; case check_texture_addr0: cur_seq->unfinished = tex_address; tmp = (cmd >> 24); @@ -433,9 +444,11 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) case check_texture_addr3: cur_seq->unfinished = tex_address; tmp = ((cmd >> 24) - 0x2B); - cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20; + cur_seq->pitch[cur_seq->texture][tmp] = + (cmd & 0x00F00000) >> 20; if (!tmp && (cmd & 0x000FFFFF)) { - DRM_ERROR("Unimplemented texture level 0 pitch mode.\n"); + DRM_ERROR + ("Unimplemented texture level 0 pitch mode.\n"); return 2; } return 0; @@ -449,7 +462,7 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) cur_seq->unfinished = tex_address; /* * Texture width. We don't care since we have the pitch. - */ + */ return 0; case check_texture_addr7: cur_seq->unfinished = tex_address; @@ -465,25 +478,26 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) cur_seq->unfinished = tex_address; tmp_addr = &(cur_seq->height[cur_seq->texture][0]); tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12); - tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8); + tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8); tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4); tmp_addr[6] = 1 << (cmd & 0x0000000F); return 0; case check_texture_addr_mode: cur_seq->unfinished = tex_address; - if ( 2 == (tmp = cmd & 0x00000003)) { - DRM_ERROR("Attempt to fetch texture from system memory.\n"); + if (2 == (tmp = cmd & 0x00000003)) { + DRM_ERROR + ("Attempt to fetch texture from system memory.\n"); return 2; } cur_seq->agp_texture = (tmp == 3); - cur_seq->tex_palette_size[cur_seq->texture] = - (cmd >> 16) & 0x000000007; + cur_seq->tex_palette_size[cur_seq->texture] = + (cmd >> 16) & 0x000000007; return 0; case check_for_vertex_count: cur_seq->vertex_count = cmd & 0x0000FFFF; return 0; case check_number_texunits: - cur_seq->multitex = (cmd >> 3) & 1; + cur_seq->multitex = (cmd >> 3) & 1; return 0; default: DRM_ERROR("Illegal DMA data: 0x%x\n", cmd); @@ -492,25 +506,27 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) return 2; } - static __inline__ int -via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end, - drm_via_state_t *cur_seq) +via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, + drm_via_state_t * cur_seq) { - drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private; - uint32_t a_fire, bcmd , dw_count; + drm_via_private_t *dev_priv = + (drm_via_private_t *) cur_seq->dev->dev_private; + uint32_t a_fire, bcmd, dw_count; int ret = 0; int have_fire; const uint32_t *buf = *buffer; - while(buf < buf_end) { - have_fire = 0; + while (buf < buf_end) { + have_fire = 0; if ((buf_end - buf) < 2) { - DRM_ERROR("Unexpected termination of primitive list.\n"); + DRM_ERROR + ("Unexpected termination of primitive list.\n"); ret = 1; break; } - if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break; + if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) + break; bcmd = *buf++; if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) { DRM_ERROR("Expected Vertex List A command, got 0x%x\n", @@ -518,43 +534,56 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end, ret = 1; break; } - a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK; - + a_fire = + *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | + HC_HE3Fire_MASK; + /* * How many dwords per vertex ? - */ - + */ + if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) { DRM_ERROR("Illegal B command vertex data for AGP.\n"); ret = 1; break; - } + } dw_count = 0; - if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1; - if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1; - if (bcmd & (1 << 9)) dw_count++; - if (bcmd & (1 << 10)) dw_count++; - if (bcmd & (1 << 11)) dw_count++; - if (bcmd & (1 << 12)) dw_count++; - if (bcmd & (1 << 13)) dw_count++; - if (bcmd & (1 << 14)) dw_count++; + if (bcmd & (1 << 7)) + dw_count += (cur_seq->multitex) ? 2 : 1; + if (bcmd & (1 << 8)) + dw_count += (cur_seq->multitex) ? 2 : 1; + if (bcmd & (1 << 9)) + dw_count++; + if (bcmd & (1 << 10)) + dw_count++; + if (bcmd & (1 << 11)) + dw_count++; + if (bcmd & (1 << 12)) + dw_count++; + if (bcmd & (1 << 13)) + dw_count++; + if (bcmd & (1 << 14)) + dw_count++; - while(buf < buf_end) { + while (buf < buf_end) { if (*buf == a_fire) { - if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) { + if (dev_priv->num_fire_offsets >= + VIA_FIRE_BUF_SIZE) { DRM_ERROR("Fire offset buffer full.\n"); ret = 1; break; } - dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf; - have_fire = 1; + dev_priv->fire_offsets[dev_priv-> + num_fire_offsets++] = + buf; + have_fire = 1; buf++; - if (buf < buf_end && *buf == a_fire) + if (buf < buf_end && *buf == a_fire) buf++; break; } - if ((*buf == HALCYON_HEADER2) || + if ((*buf == HALCYON_HEADER2) || ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) { DRM_ERROR("Missing Vertex Fire command, " "Stray Vertex Fire command or verifier " @@ -576,18 +605,14 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end, ret = 1; break; } - } + } *buffer = buf; return ret; } - - - - static __inline__ verifier_state_t -via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, - drm_via_state_t *hc_state) +via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, + drm_via_state_t * hc_state) { uint32_t cmd; int hz_mode; @@ -595,17 +620,17 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, const uint32_t *buf = *buffer; const hazard_t *hz_table; - if ((buf_end - buf) < 2) { - DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n"); + DRM_ERROR + ("Illegal termination of DMA HALCYON_HEADER2 sequence.\n"); return state_error; } buf++; cmd = (*buf++ & 0xFFFF0000) >> 16; - switch(cmd) { + switch (cmd) { case HC_ParaType_CmdVdata: - if (via_check_prim_list(&buf, buf_end, hc_state )) + if (via_check_prim_list(&buf, buf_end, hc_state)) return state_error; *buffer = buf; return state_command; @@ -650,13 +675,13 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, */ DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 " - "DMA subcommand: 0x%x. Previous dword: 0x%x\n", - cmd, *(buf -2)); + "DMA subcommand: 0x%x. Previous dword: 0x%x\n", + cmd, *(buf - 2)); *buffer = buf; return state_error; } - while(buf < buf_end) { + while (buf < buf_end) { cmd = *buf++; if ((hz = hz_table[cmd >> 24])) { if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) { @@ -666,7 +691,7 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, } return state_error; } - } else if (hc_state->unfinished && + } else if (hc_state->unfinished && finish_current_sequence(hc_state)) { return state_error; } @@ -679,64 +704,65 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, } static __inline__ verifier_state_t -via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end, - int *fire_count) +via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer, + const uint32_t * buf_end, int *fire_count) { uint32_t cmd; const uint32_t *buf = *buffer; - const uint32_t *next_fire; + const uint32_t *next_fire; int burst = 0; next_fire = dev_priv->fire_offsets[*fire_count]; buf++; cmd = (*buf & 0xFFFF0000) >> 16; VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++); - switch(cmd) { + switch (cmd) { case HC_ParaType_CmdVdata: while ((buf < buf_end) && - (*fire_count < dev_priv->num_fire_offsets) && - (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) { - while(buf <= next_fire) { - VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++); + (*fire_count < dev_priv->num_fire_offsets) && + (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) { + while (buf <= next_fire) { + VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + + (burst & 63), *buf++); burst += 4; } - if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) + if ((buf < buf_end) + && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) buf++; - if (++(*fire_count) < dev_priv->num_fire_offsets) + if (++(*fire_count) < dev_priv->num_fire_offsets) next_fire = dev_priv->fire_offsets[*fire_count]; } break; default: - while(buf < buf_end) { - - if ( *buf == HC_HEADER2 || - (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 || - (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 || - (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break; - - VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++); - burst +=4; + while (buf < buf_end) { + + if (*buf == HC_HEADER2 || + (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 || + (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 || + (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) + break; + + VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + + (burst & 63), *buf++); + burst += 4; } } *buffer = buf; return state_command; } - - -static __inline__ int -verify_mmio_address( uint32_t address) +static __inline__ int verify_mmio_address(uint32_t address) { - if ((address > 0x3FF) && (address < 0xC00 )) { + if ((address > 0x3FF) && (address < 0xC00)) { DRM_ERROR("Invalid VIDEO DMA command. " "Attempt to access 3D- or command burst area.\n"); return 1; } else if ((address > 0xCFF) && (address < 0x1300)) { DRM_ERROR("Invalid VIDEO DMA command. " "Attempt to access PCI DMA area.\n"); - return 1; - } else if (address > 0x13FF ) { + return 1; + } else if (address > 0x13FF) { DRM_ERROR("Invalid VIDEO DMA command. " "Attempt to access VGA registers.\n"); return 1; @@ -745,7 +771,8 @@ verify_mmio_address( uint32_t address) } static __inline__ int -verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords) +verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end, + uint32_t dwords) { const uint32_t *buf = *buffer; @@ -762,10 +789,9 @@ verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dw *buffer = buf; return 0; } - static __inline__ verifier_state_t -via_check_header1( uint32_t const **buffer, const uint32_t *buf_end ) +via_check_header1(uint32_t const **buffer, const uint32_t * buf_end) { uint32_t cmd; const uint32_t *buf = *buffer; @@ -774,21 +800,21 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end ) while (buf < buf_end) { cmd = *buf; if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) && - (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) { - if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) + (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) { + if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break; DRM_ERROR("Invalid HALCYON_HEADER1 command. " "Attempt to access 3D- or command burst area.\n"); ret = state_error; break; } else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) { - if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) + if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break; DRM_ERROR("Invalid HALCYON_HEADER1 command. " "Attempt to access VGA registers.\n"); ret = state_error; - break; - } else { + break; + } else { buf += 2; } } @@ -797,15 +823,17 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end ) } static __inline__ verifier_state_t -via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end ) +via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, + const uint32_t * buf_end) { register uint32_t cmd; const uint32_t *buf = *buffer; while (buf < buf_end) { cmd = *buf; - if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break; - VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf); + if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) + break; + VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf); buf++; } *buffer = buf; @@ -813,7 +841,7 @@ via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const u } static __inline__ verifier_state_t -via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end ) +via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) { uint32_t data; const uint32_t *buf = *buffer; @@ -836,41 +864,41 @@ via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end ) DRM_ERROR("Illegal header5 header data\n"); return state_error; } - if (eat_words(&buf, buf_end, data)) + if (eat_words(&buf, buf_end, data)) return state_error; - if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) + if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) return state_error; *buffer = buf; return state_command; - -} + +} static __inline__ verifier_state_t -via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end ) +via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, + const uint32_t * buf_end) { - uint32_t addr, count, i; + uint32_t addr, count, i; const uint32_t *buf = *buffer; - + addr = *buf++ & ~VIA_VIDEOMASK; i = count = *buf; buf += 3; - while(i--) { + while (i--) { VIA_WRITE(addr, *buf++); } - if (count & 3) buf += 4 - (count & 3); + if (count & 3) + buf += 4 - (count & 3); *buffer = buf; - return state_command; -} - + return state_command; +} static __inline__ verifier_state_t -via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end ) +via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end) { uint32_t data; const uint32_t *buf = *buffer; uint32_t i; - if (buf_end - buf < 4) { DRM_ERROR("Illegal termination of video header6 command\n"); return state_error; @@ -889,7 +917,7 @@ via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end ) DRM_ERROR("Illegal termination of video header6 command\n"); return state_error; } - for (i=0; idev_private; drm_via_state_t *hc_state = &dev_priv->hc_state; drm_via_state_t saved_state = *hc_state; uint32_t cmd; - const uint32_t *buf_end = buf + ( size >> 2 ); + const uint32_t *buf_end = buf + (size >> 2); verifier_state_t state = state_command; int pro_group_a = dev_priv->pro_group_a; - + hc_state->dev = dev; hc_state->unfinished = no_sequence; hc_state->map_cache = NULL; @@ -946,38 +974,41 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t switch (state) { case state_header2: - state = via_check_header2( &buf, buf_end, hc_state ); + state = via_check_header2(&buf, buf_end, hc_state); break; case state_header1: - state = via_check_header1( &buf, buf_end ); + state = via_check_header1(&buf, buf_end); break; case state_vheader5: - state = via_check_vheader5( &buf, buf_end ); + state = via_check_vheader5(&buf, buf_end); break; case state_vheader6: - state = via_check_vheader6( &buf, buf_end ); + state = via_check_vheader6(&buf, buf_end); break; case state_command: - if (HALCYON_HEADER2 == (cmd = *buf)) + if (HALCYON_HEADER2 == (cmd = *buf)) state = state_header2; - else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) state = state_header1; - else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) + else if (pro_group_a + && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) state = state_vheader5; - else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) + else if (pro_group_a + && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) state = state_vheader6; else { - DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n", - cmd); + DRM_ERROR + ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", + cmd); state = state_error; } break; case state_error: default: *hc_state = saved_state; - return DRM_ERR(EINVAL); + return DRM_ERR(EINVAL); } - } + } if (state == state_error) { *hc_state = saved_state; return DRM_ERR(EINVAL); @@ -985,77 +1016,81 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t return 0; } -int -via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size) +int +via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, + unsigned int size) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; uint32_t cmd; - const uint32_t *buf_end = buf + ( size >> 2 ); + const uint32_t *buf_end = buf + (size >> 2); verifier_state_t state = state_command; int fire_count = 0; - + while (buf < buf_end) { switch (state) { case state_header2: - state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count ); + state = + via_parse_header2(dev_priv, &buf, buf_end, + &fire_count); break; case state_header1: - state = via_parse_header1( dev_priv, &buf, buf_end ); + state = via_parse_header1(dev_priv, &buf, buf_end); break; case state_vheader5: - state = via_parse_vheader5( dev_priv, &buf, buf_end ); + state = via_parse_vheader5(dev_priv, &buf, buf_end); break; case state_vheader6: - state = via_parse_vheader6( dev_priv, &buf, buf_end ); + state = via_parse_vheader6(dev_priv, &buf, buf_end); break; case state_command: - if (HALCYON_HEADER2 == (cmd = *buf)) + if (HALCYON_HEADER2 == (cmd = *buf)) state = state_header2; - else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) state = state_header1; else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) state = state_vheader5; else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) state = state_vheader6; else { - DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n", - cmd); + DRM_ERROR + ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", + cmd); state = state_error; } break; case state_error: default: - return DRM_ERR(EINVAL); + return DRM_ERR(EINVAL); } - } + } if (state == state_error) { return DRM_ERR(EINVAL); } return 0; } - - -static void +static void setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) { int i; - for(i=0; i<256; ++i) { + for (i = 0; i < 256; ++i) { table[i] = forbidden_command; } - for(i=0; isarea_priv, i); - if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) { - if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) { - DRM_WAKEUP( &(dev_priv->decoder_queue[i])); + for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) { + lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); + if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { + if (_DRM_LOCK_IS_HELD(*lock) + && (*lock & _DRM_LOCK_CONT)) { + DRM_WAKEUP(&(dev_priv->decoder_queue[i])); } *lock = 0; } - } -} + } +} -int -via_decoder_futex(DRM_IOCTL_ARGS) +int via_decoder_futex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_via_futex_t fx; @@ -95,4 +92,3 @@ via_decoder_futex(DRM_IOCTL_ARGS) } return 0; } - From 13e4a9c85152a49ec10e682308581ab13b437470 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 25 Sep 2005 14:30:09 +1000 Subject: [PATCH 0129/1940] drm: cast handle to a pointer to avoid warning Andrew reported a warning on this line, just case to void *. Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index bb989ccea5a0..e3d372ad0076 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -309,7 +309,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, if (copy_to_user(argp, maplist->map, sizeof(drm_map_t))) return -EFAULT; - if (put_user(maplist->user_token, &argp->handle)) + if (put_user((void *)maplist->user_token, &argp->handle)) return -EFAULT; return 0; } From b6ce156c415544f900e031890c78eba8bc92f9b3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 25 Sep 2005 15:07:24 +1000 Subject: [PATCH 0130/1940] drm: fix some lindent damage Signed-off-by: Dave Airlie --- drivers/char/drm/i810_dma.c | 42 ++++++------------ drivers/char/drm/i830_dma.c | 39 ++++++----------- drivers/char/drm/i915_dma.c | 33 +++++--------- drivers/char/drm/mga_state.c | 40 ++++++----------- drivers/char/drm/radeon_state.c | 78 +++++++++++---------------------- drivers/char/drm/savage_bci.c | 12 ++--- drivers/char/drm/sis_mm.c | 15 +++---- 7 files changed, 86 insertions(+), 173 deletions(-) diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index 810625093c06..dba502373da1 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c @@ -1346,34 +1346,20 @@ int i810_driver_dma_quiescent(drm_device_t * dev) } drm_ioctl_desc_t i810_ioctls[] = { - [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0} - , - [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1} - , - [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0} - , + [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1}, + [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0}, [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0} }; diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index e1107ecb16e3..dc94f1914425 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c @@ -1544,32 +1544,19 @@ int i830_driver_dma_quiescent(drm_device_t * dev) } drm_ioctl_desc_t i830_ioctls[] = { - [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0} - , - [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0} - , + [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0}, [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0} }; diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index f0bb0bdbb6e2..f3aa0c370127 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -717,28 +717,17 @@ void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) } drm_ioctl_desc_t i915_ioctls[] = { - [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1} - , - [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0} - , - [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1} - , + [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1}, [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0} }; diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c index 15114f8aa467..ee77685069d0 100644 --- a/drivers/char/drm/mga_state.c +++ b/drivers/char/drm/mga_state.c @@ -1127,33 +1127,19 @@ static int mga_wait_fence(DRM_IOCTL_ARGS) } drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0} - , - [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1} - , - + [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, }; int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 42e8ce4dbe99..2eae60bd340f 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -3117,58 +3117,32 @@ void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) } drm_ioctl_desc_t radeon_ioctls[] = { - [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1} - , - [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0} - , - [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0} - , + [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0}, [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0} }; diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 0ad9201af8bd..6d10515795cc 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c @@ -1090,14 +1090,10 @@ void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) } drm_ioctl_desc_t savage_ioctls[] = { - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0} - , - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0} - , - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0} - , + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0}, }; int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c index 50e32384ad93..a8529728fa63 100644 --- a/drivers/char/drm/sis_mm.c +++ b/drivers/char/drm/sis_mm.c @@ -403,16 +403,11 @@ int sis_final_context(struct drm_device *dev, int context) } drm_ioctl_desc_t sis_ioctls[] = { - [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0} - , - [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0} - , - [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1} - , - [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0} - , - [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0} - , + [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1}, + [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0}, [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1} }; From 3efc333e7fdb6fab9d4eae129e2b249c6483b250 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 22 Sep 2005 10:13:31 -0500 Subject: [PATCH 0131/1940] [PATCH] powerpc: Fix building of power3 config on ppc32 The spinlock_types.h merge renamed the structure for raw_spinlock_t to match ppc64. In doing so some of the spinlock macros/functions needed to be updated to match. Apparently, this seems to only be caught when building power3. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-ppc/spinlock.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index 20edcf2a6e0c..5c64b75f0295 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -9,7 +9,7 @@ * (the type definitions are in asm/raw_spinlock_types.h) */ -#define __raw_spin_is_locked(x) ((x)->lock != 0) +#define __raw_spin_is_locked(x) ((x)->slock != 0) #define __raw_spin_unlock_wait(lock) \ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) @@ -31,17 +31,17 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) bne- 2b\n\ isync" : "=&r"(tmp) - : "r"(&lock->lock), "r"(1) + : "r"(&lock->slock), "r"(1) : "cr0", "memory"); } static inline void __raw_spin_unlock(raw_spinlock_t *lock) { __asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory"); - lock->lock = 0; + lock->slock = 0; } -#define __raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock)) +#define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock))) /* * Read-write spinlocks, allowing multiple readers From 2bfadee32f1501faa3184d574f6a769f17236c87 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Fri, 23 Sep 2005 08:05:03 -0500 Subject: [PATCH 0132/1940] [PATCH] powerpc: Merge asm-ppc*/seccomp.h, drop TIF_32BIT check Merge asm-ppc*/seccomp.h. Drop TIF_32BIT check. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/seccomp.h | 11 +++-------- include/asm-ppc/seccomp.h | 10 ---------- 2 files changed, 3 insertions(+), 18 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/seccomp.h (66%) delete mode 100644 include/asm-ppc/seccomp.h diff --git a/include/asm-ppc64/seccomp.h b/include/asm-powerpc/seccomp.h similarity index 66% rename from include/asm-ppc64/seccomp.h rename to include/asm-powerpc/seccomp.h index c130c334bda1..1e1cfe12882b 100644 --- a/include/asm-ppc64/seccomp.h +++ b/include/asm-powerpc/seccomp.h @@ -1,11 +1,6 @@ -#ifndef _ASM_SECCOMP_H - -#include /* already defines TIF_32BIT */ - -#ifndef TIF_32BIT -#error "unexpected TIF_32BIT on ppc64" -#endif +#ifndef _ASM_POWERPC_SECCOMP_H +#include #include #define __NR_seccomp_read __NR_read @@ -18,4 +13,4 @@ #define __NR_seccomp_exit_32 __NR_exit #define __NR_seccomp_sigreturn_32 __NR_sigreturn -#endif /* _ASM_SECCOMP_H */ +#endif /* _ASM_POWERPC_SECCOMP_H */ diff --git a/include/asm-ppc/seccomp.h b/include/asm-ppc/seccomp.h deleted file mode 100644 index 666c4da96d87..000000000000 --- a/include/asm-ppc/seccomp.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ASM_SECCOMP_H - -#include - -#define __NR_seccomp_read __NR_read -#define __NR_seccomp_write __NR_write -#define __NR_seccomp_exit __NR_exit -#define __NR_seccomp_sigreturn __NR_rt_sigreturn - -#endif /* _ASM_SECCOMP_H */ From feaf7cf153335fe7100b65ed6f4585c3574fe69a Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Thu, 22 Sep 2005 14:20:04 -0500 Subject: [PATCH 0133/1940] [PATCH] powerpc: merge atomic.h, memory.h powerpc: Merge atomic.h and memory.h into powerpc Merged atomic.h into include/powerpc. Moved asm-style HMT_ defines from memory.h into ppc_asm.h, where there were already HMT_defines; moved c-style HMT_ defines to processor.h. Renamed memory.h to synch.h to better reflect its contents. Signed-off-by: Kumar Gala Signed-off-by: Becky Bruce Signed-off-by: Jon Loeliger Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/atomic.h | 45 +++-- include/asm-powerpc/ppc_asm.h | 3 + include/asm-powerpc/synch.h | 51 ++++++ include/asm-ppc/io.h | 11 +- include/asm-ppc64/atomic.h | 197 ---------------------- include/asm-ppc64/bitops.h | 2 +- include/asm-ppc64/futex.h | 2 +- include/asm-ppc64/io.h | 2 +- include/asm-ppc64/memory.h | 61 ------- include/asm-ppc64/processor.h | 8 + include/asm-ppc64/system.h | 4 +- 11 files changed, 88 insertions(+), 298 deletions(-) rename include/{asm-ppc => asm-powerpc}/atomic.h (85%) create mode 100644 include/asm-powerpc/synch.h delete mode 100644 include/asm-ppc64/atomic.h delete mode 100644 include/asm-ppc64/memory.h diff --git a/include/asm-ppc/atomic.h b/include/asm-powerpc/atomic.h similarity index 85% rename from include/asm-ppc/atomic.h rename to include/asm-powerpc/atomic.h index eeafd505836e..ed4b345ed75d 100644 --- a/include/asm-ppc/atomic.h +++ b/include/asm-powerpc/atomic.h @@ -1,29 +1,20 @@ +#ifndef _ASM_POWERPC_ATOMIC_H_ +#define _ASM_POWERPC_ATOMIC_H_ + /* * PowerPC atomic operations */ -#ifndef _ASM_PPC_ATOMIC_H_ -#define _ASM_PPC_ATOMIC_H_ - typedef struct { volatile int counter; } atomic_t; #ifdef __KERNEL__ +#include -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) -extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); - -#ifdef CONFIG_SMP -#define SMP_SYNC "sync" -#define SMP_ISYNC "\n\tisync" -#else -#define SMP_SYNC "" -#define SMP_ISYNC -#endif - /* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. * The old ATOMIC_SYNC_FIX covered some but not all of this. */ @@ -53,12 +44,13 @@ static __inline__ int atomic_add_return(int a, atomic_t *v) int t; __asm__ __volatile__( + EIEIO_ON_SMP "1: lwarx %0,0,%2 # atomic_add_return\n\ add %0,%1,%0\n" PPC405_ERR77(0,%2) " stwcx. %0,0,%2 \n\ bne- 1b" - SMP_ISYNC + ISYNC_ON_SMP : "=&r" (t) : "r" (a), "r" (&v->counter) : "cc", "memory"); @@ -88,12 +80,13 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v) int t; __asm__ __volatile__( + EIEIO_ON_SMP "1: lwarx %0,0,%2 # atomic_sub_return\n\ subf %0,%1,%0\n" PPC405_ERR77(0,%2) " stwcx. %0,0,%2 \n\ bne- 1b" - SMP_ISYNC + ISYNC_ON_SMP : "=&r" (t) : "r" (a), "r" (&v->counter) : "cc", "memory"); @@ -121,12 +114,13 @@ static __inline__ int atomic_inc_return(atomic_t *v) int t; __asm__ __volatile__( + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_inc_return\n\ addic %0,%0,1\n" PPC405_ERR77(0,%1) " stwcx. %0,0,%1 \n\ bne- 1b" - SMP_ISYNC + ISYNC_ON_SMP : "=&r" (t) : "r" (&v->counter) : "cc", "memory"); @@ -164,12 +158,13 @@ static __inline__ int atomic_dec_return(atomic_t *v) int t; __asm__ __volatile__( + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_dec_return\n\ addic %0,%0,-1\n" PPC405_ERR77(0,%1) " stwcx. %0,0,%1\n\ bne- 1b" - SMP_ISYNC + ISYNC_ON_SMP : "=&r" (t) : "r" (&v->counter) : "cc", "memory"); @@ -189,13 +184,14 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) int t; __asm__ __volatile__( + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ addic. %0,%0,-1\n\ blt- 2f\n" PPC405_ERR77(0,%1) " stwcx. %0,0,%1\n\ bne- 1b" - SMP_ISYNC + ISYNC_ON_SMP "\n\ 2:" : "=&r" (t) : "r" (&v->counter) @@ -204,11 +200,10 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) return t; } -#define __MB __asm__ __volatile__ (SMP_SYNC : : : "memory") -#define smp_mb__before_atomic_dec() __MB -#define smp_mb__after_atomic_dec() __MB -#define smp_mb__before_atomic_inc() __MB -#define smp_mb__after_atomic_inc() __MB +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() #endif /* __KERNEL__ */ -#endif /* _ASM_PPC_ATOMIC_H_ */ +#endif /* _ASM_POWERPC_ATOMIC_H_ */ diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 553035cda00e..4efa71878fa9 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -75,8 +75,11 @@ #define REST_32EVRS(n,s,base) REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base) /* Macros to adjust thread priority for Iseries hardware multithreading */ +#define HMT_VERY_LOW or 31,31,31 # very low priority\n" #define HMT_LOW or 1,1,1 +#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority\n" #define HMT_MEDIUM or 2,2,2 +#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority\n" #define HMT_HIGH or 3,3,3 /* handle instructions that older assemblers may not know */ diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h new file mode 100644 index 000000000000..4660c0394a77 --- /dev/null +++ b/include/asm-powerpc/synch.h @@ -0,0 +1,51 @@ +#ifndef _ASM_POWERPC_SYNCH_H +#define _ASM_POWERPC_SYNCH_H + +#include + +#ifdef __powerpc64__ +#define __SUBARCH_HAS_LWSYNC +#endif + +#ifdef __SUBARCH_HAS_LWSYNC +# define LWSYNC lwsync +#else +# define LWSYNC sync +#endif + + +/* + * Arguably the bitops and *xchg operations don't imply any memory barrier + * or SMP ordering, but in fact a lot of drivers expect them to imply + * both, since they do on x86 cpus. + */ +#ifdef CONFIG_SMP +#define EIEIO_ON_SMP "eieio\n" +#define ISYNC_ON_SMP "\n\tisync" +#define SYNC_ON_SMP __stringify(LWSYNC) "\n" +#else +#define EIEIO_ON_SMP +#define ISYNC_ON_SMP +#define SYNC_ON_SMP +#endif + +static inline void eieio(void) +{ + __asm__ __volatile__ ("eieio" : : : "memory"); +} + +static inline void isync(void) +{ + __asm__ __volatile__ ("isync" : : : "memory"); +} + +#ifdef CONFIG_SMP +#define eieio_on_smp() eieio() +#define isync_on_smp() isync() +#else +#define eieio_on_smp() __asm__ __volatile__("": : :"memory") +#define isync_on_smp() __asm__ __volatile__("": : :"memory") +#endif + +#endif /* _ASM_POWERPC_SYNCH_H */ + diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 7eb7cf6360bd..39caf067a31b 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -8,6 +8,7 @@ #include #include +#include #include #define SIO_CONFIG_RA 0x398 @@ -440,16 +441,6 @@ extern inline void * phys_to_virt(unsigned long address) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET) -/* - * Enforce In-order Execution of I/O: - * Acts as a barrier to ensure all previous I/O accesses have - * completed before any further ones are issued. - */ -extern inline void eieio(void) -{ - __asm__ __volatile__ ("eieio" : : : "memory"); -} - /* Enforce in-order execution of data I/O. * No distinction between read/write on PPC; use eieio for all three. */ diff --git a/include/asm-ppc64/atomic.h b/include/asm-ppc64/atomic.h deleted file mode 100644 index 0e5f25e83bc0..000000000000 --- a/include/asm-ppc64/atomic.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * PowerPC64 atomic operations - * - * Copyright (C) 2001 Paul Mackerras , IBM - * Copyright (C) 2001 Anton Blanchard , IBM - * - * 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. - */ - -#ifndef _ASM_PPC64_ATOMIC_H_ -#define _ASM_PPC64_ATOMIC_H_ - -#include - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -static __inline__ void atomic_add(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_add_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static __inline__ void atomic_sub(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_sub_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_inc(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_inc\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_inc_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) - -static __inline__ void atomic_dec(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_dec\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_dec_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) - -/* - * Atomically test *v and decrement if it is greater than 0. - * The function returns the old value of *v minus 1. - */ -static __inline__ int atomic_dec_if_positive(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ - addic. %0,%0,-1\n\ - blt- 2f\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - "\n\ -2:" : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define smp_mb__before_atomic_dec() smp_mb() -#define smp_mb__after_atomic_dec() smp_mb() -#define smp_mb__before_atomic_inc() smp_mb() -#define smp_mb__after_atomic_inc() smp_mb() - -#endif /* _ASM_PPC64_ATOMIC_H_ */ diff --git a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h index a0f831224f96..dbfa42ef4a99 100644 --- a/include/asm-ppc64/bitops.h +++ b/include/asm-ppc64/bitops.h @@ -42,7 +42,7 @@ #ifdef __KERNEL__ -#include +#include /* * clear_bit doesn't imply a memory barrier diff --git a/include/asm-ppc64/futex.h b/include/asm-ppc64/futex.h index cb2640b3a408..266b460de44e 100644 --- a/include/asm-ppc64/futex.h +++ b/include/asm-ppc64/futex.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h index 59c958aea4db..bd7c9532d77b 100644 --- a/include/asm-ppc64/io.h +++ b/include/asm-ppc64/io.h @@ -15,7 +15,7 @@ #ifdef CONFIG_PPC_ISERIES #include #endif -#include +#include #include #include diff --git a/include/asm-ppc64/memory.h b/include/asm-ppc64/memory.h deleted file mode 100644 index af53ffb55726..000000000000 --- a/include/asm-ppc64/memory.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _ASM_PPC64_MEMORY_H_ -#define _ASM_PPC64_MEMORY_H_ - -/* - * 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. - */ - -#include - -/* - * Arguably the bitops and *xchg operations don't imply any memory barrier - * or SMP ordering, but in fact a lot of drivers expect them to imply - * both, since they do on x86 cpus. - */ -#ifdef CONFIG_SMP -#define EIEIO_ON_SMP "eieio\n" -#define ISYNC_ON_SMP "\n\tisync" -#define SYNC_ON_SMP "lwsync\n\t" -#else -#define EIEIO_ON_SMP -#define ISYNC_ON_SMP -#define SYNC_ON_SMP -#endif - -static inline void eieio(void) -{ - __asm__ __volatile__ ("eieio" : : : "memory"); -} - -static inline void isync(void) -{ - __asm__ __volatile__ ("isync" : : : "memory"); -} - -#ifdef CONFIG_SMP -#define eieio_on_smp() eieio() -#define isync_on_smp() isync() -#else -#define eieio_on_smp() __asm__ __volatile__("": : :"memory") -#define isync_on_smp() __asm__ __volatile__("": : :"memory") -#endif - -/* Macros for adjusting thread priority (hardware multi-threading) */ -#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") -#define HMT_low() asm volatile("or 1,1,1 # low priority") -#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") -#define HMT_medium() asm volatile("or 2,2,2 # medium priority") -#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") -#define HMT_high() asm volatile("or 3,3,3 # high priority") - -#define HMT_VERY_LOW "\tor 31,31,31 # very low priority\n" -#define HMT_LOW "\tor 1,1,1 # low priority\n" -#define HMT_MEDIUM_LOW "\tor 6,6,6 # medium low priority\n" -#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n" -#define HMT_MEDIUM_HIGH "\tor 5,5,5 # medium high priority\n" -#define HMT_HIGH "\tor 3,3,3 # high priority\n" - -#endif diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 4146189006e3..e5fc18531ec1 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -368,6 +368,14 @@ GLUE(.,name): #define mfasr() ({unsigned long rval; \ asm volatile("mfasr %0" : "=r" (rval)); rval;}) +/* Macros for adjusting thread priority (hardware multi-threading) */ +#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") +#define HMT_low() asm volatile("or 1,1,1 # low priority") +#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") +#define HMT_medium() asm volatile("or 2,2,2 # medium priority") +#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") +#define HMT_high() asm volatile("or 3,3,3 # high priority") + static inline void set_tb(unsigned int upper, unsigned int lower) { mttbl(0); diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 375015c62f20..1fbdc9f0590c 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include /* * Memory barrier. @@ -48,7 +48,7 @@ #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() rmb() -#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory") +#define smp_wmb() eieio() #define smp_read_barrier_depends() read_barrier_depends() #else #define smp_mb() __asm__ __volatile__("": : :"memory") From 342e73b3d6fd1321d1eaaa6a935f267a300ceebd Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 22 Sep 2005 14:55:30 -0500 Subject: [PATCH 0134/1940] [PATCH] powerpc: Merge asm-ppc*/rwsem.h Merge asm-ppc*/rwsem.h into include/asm-powerpc. Removed smp_*mb() memory barriers from the ppc32 code as they are now burried in the atomic_*() functions as suggested by Paul, implemented by Arnd, and pushed out by Becky. I am not the droid you are looking for. This patch depends on Becky's atomic.h merge patch. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/rwsem.h | 18 +-- include/asm-ppc/rwsem.h | 172 --------------------- 2 files changed, 7 insertions(+), 183 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/rwsem.h (91%) delete mode 100644 include/asm-ppc/rwsem.h diff --git a/include/asm-ppc64/rwsem.h b/include/asm-powerpc/rwsem.h similarity index 91% rename from include/asm-ppc64/rwsem.h rename to include/asm-powerpc/rwsem.h index bd5c2f093575..0a5b83a3c949 100644 --- a/include/asm-ppc64/rwsem.h +++ b/include/asm-powerpc/rwsem.h @@ -1,18 +1,14 @@ +#ifndef _ASM_POWERPC_RWSEM_H +#define _ASM_POWERPC_RWSEM_H + +#ifdef __KERNEL__ + /* * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h * by Paul Mackerras . - * - * 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. */ -#ifndef _PPC64_RWSEM_H -#define _PPC64_RWSEM_H - -#ifdef __KERNEL__ #include #include #include @@ -163,5 +159,5 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) return atomic_add_return(delta, (atomic_t *)(&sem->count)); } -#endif /* __KERNEL__ */ -#endif /* _PPC_RWSEM_XADD_H */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_RWSEM_H */ diff --git a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h deleted file mode 100644 index 3e738f483c11..000000000000 --- a/include/asm-ppc/rwsem.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff - * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h - * by Paul Mackerras . - */ - -#ifndef _PPC_RWSEM_H -#define _PPC_RWSEM_H - -#ifdef __KERNEL__ -#include -#include -#include -#include - -/* - * the semaphore definition - */ -struct rw_semaphore { - /* XXX this should be able to be an atomic_t -- paulus */ - signed long count; -#define RWSEM_UNLOCKED_VALUE 0x00000000 -#define RWSEM_ACTIVE_BIAS 0x00000001 -#define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS (-0x00010000) -#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS -#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) - spinlock_t wait_lock; - struct list_head wait_list; -#if RWSEM_DEBUG - int debug; -#endif -}; - -/* - * initialisation - */ -#if RWSEM_DEBUG -#define __RWSEM_DEBUG_INIT , 0 -#else -#define __RWSEM_DEBUG_INIT /* */ -#endif - -#define __RWSEM_INITIALIZER(name) \ - { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ - LIST_HEAD_INIT((name).wait_list) \ - __RWSEM_DEBUG_INIT } - -#define DECLARE_RWSEM(name) \ - struct rw_semaphore name = __RWSEM_INITIALIZER(name) - -extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); -extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); -extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); -extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); - -static inline void init_rwsem(struct rw_semaphore *sem) -{ - sem->count = RWSEM_UNLOCKED_VALUE; - spin_lock_init(&sem->wait_lock); - INIT_LIST_HEAD(&sem->wait_list); -#if RWSEM_DEBUG - sem->debug = 0; -#endif -} - -/* - * lock for reading - */ -static inline void __down_read(struct rw_semaphore *sem) -{ - if (atomic_inc_return((atomic_t *)(&sem->count)) > 0) - smp_wmb(); - else - rwsem_down_read_failed(sem); -} - -static inline int __down_read_trylock(struct rw_semaphore *sem) -{ - int tmp; - - while ((tmp = sem->count) >= 0) { - if (tmp == cmpxchg(&sem->count, tmp, - tmp + RWSEM_ACTIVE_READ_BIAS)) { - smp_wmb(); - return 1; - } - } - return 0; -} - -/* - * lock for writing - */ -static inline void __down_write(struct rw_semaphore *sem) -{ - int tmp; - - tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, - (atomic_t *)(&sem->count)); - if (tmp == RWSEM_ACTIVE_WRITE_BIAS) - smp_wmb(); - else - rwsem_down_write_failed(sem); -} - -static inline int __down_write_trylock(struct rw_semaphore *sem) -{ - int tmp; - - tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, - RWSEM_ACTIVE_WRITE_BIAS); - smp_wmb(); - return tmp == RWSEM_UNLOCKED_VALUE; -} - -/* - * unlock after reading - */ -static inline void __up_read(struct rw_semaphore *sem) -{ - int tmp; - - smp_wmb(); - tmp = atomic_dec_return((atomic_t *)(&sem->count)); - if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0) - rwsem_wake(sem); -} - -/* - * unlock after writing - */ -static inline void __up_write(struct rw_semaphore *sem) -{ - smp_wmb(); - if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, - (atomic_t *)(&sem->count)) < 0) - rwsem_wake(sem); -} - -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) -{ - atomic_add(delta, (atomic_t *)(&sem->count)); -} - -/* - * downgrade write lock to read lock - */ -static inline void __downgrade_write(struct rw_semaphore *sem) -{ - int tmp; - - smp_wmb(); - tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count)); - if (tmp < 0) - rwsem_downgrade_wake(sem); -} - -/* - * implement exchange and add functionality - */ -static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) -{ - smp_mb(); - return atomic_add_return(delta, (atomic_t *)(&sem->count)); -} - -#endif /* __KERNEL__ */ -#endif /* _PPC_RWSEM_XADD_H */ From d6a4c847e43c851cc0ddf73087a730227223f989 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Fri, 23 Sep 2005 11:07:36 -0500 Subject: [PATCH 0135/1940] [PATCH] powerpc: merge semaphore.h powerpc: Merge semaphore.h Adopted the ppc64 version of semaphore.h. The 32-bit version used smp_wmb(), but recent updates to atomic.h mean this is no longer required. The 64-bit version made use of unlikely(), which has been retained in the combined version. This patch requires the recent atomic.h patch. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- .../{asm-ppc64 => asm-powerpc}/semaphore.h | 6 +- include/asm-ppc/semaphore.h | 111 ------------------ 2 files changed, 3 insertions(+), 114 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/semaphore.h (95%) delete mode 100644 include/asm-ppc/semaphore.h diff --git a/include/asm-ppc64/semaphore.h b/include/asm-powerpc/semaphore.h similarity index 95% rename from include/asm-ppc64/semaphore.h rename to include/asm-powerpc/semaphore.h index aefe7753ea41..fd42fe97158f 100644 --- a/include/asm-ppc64/semaphore.h +++ b/include/asm-powerpc/semaphore.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_SEMAPHORE_H -#define _PPC64_SEMAPHORE_H +#ifndef _ASM_POWERPC_SEMAPHORE_H +#define _ASM_POWERPC_SEMAPHORE_H /* * Remove spinlock-based RW semaphores; RW semaphore definitions are @@ -95,4 +95,4 @@ static inline void up(struct semaphore * sem) #endif /* __KERNEL__ */ -#endif /* !(_PPC64_SEMAPHORE_H) */ +#endif /* _ASM_POWERPC_SEMAPHORE_H */ diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h deleted file mode 100644 index 89e6e73be08c..000000000000 --- a/include/asm-ppc/semaphore.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _PPC_SEMAPHORE_H -#define _PPC_SEMAPHORE_H - -/* - * Swiped from asm-sparc/semaphore.h and modified - * -- Cort (cort@cs.nmt.edu) - * - * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h - * -- Ani Joshi (ajoshi@unixbox.com) - * - * Remove spinlock-based RW semaphores; RW semaphore definitions are - * now in rwsem.h and we use the generic lib/rwsem.c implementation. - * Rework semaphores to use atomic_dec_if_positive. - * -- Paul Mackerras (paulus@samba.org) - */ - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -struct semaphore { - /* - * Note that any negative value of count is equivalent to 0, - * but additionally indicates that some process(es) might be - * sleeping on `wait'. - */ - atomic_t count; - wait_queue_head_t wait; -}; - -#define __SEMAPHORE_INITIALIZER(name, n) \ -{ \ - .count = ATOMIC_INIT(n), \ - .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ -} - -#define __MUTEX_INITIALIZER(name) \ - __SEMAPHORE_INITIALIZER(name, 1) - -#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ - struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) - -#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) - -static inline void sema_init (struct semaphore *sem, int val) -{ - atomic_set(&sem->count, val); - init_waitqueue_head(&sem->wait); -} - -static inline void init_MUTEX (struct semaphore *sem) -{ - sema_init(sem, 1); -} - -static inline void init_MUTEX_LOCKED (struct semaphore *sem) -{ - sema_init(sem, 0); -} - -extern void __down(struct semaphore * sem); -extern int __down_interruptible(struct semaphore * sem); -extern void __up(struct semaphore * sem); - -extern inline void down(struct semaphore * sem) -{ - might_sleep(); - - /* - * Try to get the semaphore, take the slow path if we fail. - */ - if (atomic_dec_return(&sem->count) < 0) - __down(sem); - smp_wmb(); -} - -extern inline int down_interruptible(struct semaphore * sem) -{ - int ret = 0; - - might_sleep(); - - if (atomic_dec_return(&sem->count) < 0) - ret = __down_interruptible(sem); - smp_wmb(); - return ret; -} - -extern inline int down_trylock(struct semaphore * sem) -{ - int ret; - - ret = atomic_dec_if_positive(&sem->count) < 0; - smp_wmb(); - return ret; -} - -extern inline void up(struct semaphore * sem) -{ - smp_wmb(); - if (atomic_inc_return(&sem->count) <= 0) - __up(sem); -} - -#endif /* __KERNEL__ */ - -#endif /* !(_PPC_SEMAPHORE_H) */ From 14cf11af6cf608eb8c23e989ddb17a715ddce109 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 26 Sep 2005 16:04:21 +1000 Subject: [PATCH 0136/1940] powerpc: Merge enough to start building in arch/powerpc. This creates the directory structure under arch/powerpc and a bunch of Kconfig files. It does a first-cut merge of arch/powerpc/mm, arch/powerpc/lib and arch/powerpc/platforms/powermac. This is enough to build a 32-bit powermac kernel with ARCH=powerpc. For now we are getting some unmerged files from arch/ppc/kernel and arch/ppc/syslib, or arch/ppc64/kernel. This makes some minor changes to files in those directories and files outside arch/powerpc. The boot directory is still not merged. That's going to be interesting. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 861 +++++ arch/powerpc/Kconfig.debug | 73 + arch/powerpc/Makefile | 222 ++ arch/powerpc/kernel/Makefile | 18 + arch/powerpc/kernel/asm-offsets.c | 262 ++ arch/powerpc/kernel/fpu.S | 133 + arch/powerpc/kernel/head.S | 1545 +++++++++ arch/powerpc/kernel/head_44x.S | 778 +++++ arch/powerpc/kernel/head_4xx.S | 1016 ++++++ arch/powerpc/kernel/head_64.S | 2011 +++++++++++ arch/powerpc/kernel/head_8xx.S | 860 +++++ arch/powerpc/kernel/head_fsl_booke.S | 1058 ++++++ arch/powerpc/kernel/idle_6xx.S | 233 ++ arch/powerpc/kernel/process.c | 724 ++++ arch/powerpc/kernel/semaphore.c | 135 + arch/powerpc/kernel/traps.c | 1047 ++++++ arch/powerpc/kernel/vector.S | 197 ++ arch/powerpc/kernel/vmlinux.lds | 174 + arch/powerpc/kernel/vmlinux.lds.S | 172 + arch/powerpc/lib/Makefile | 9 + arch/powerpc/lib/checksum.S | 225 ++ arch/powerpc/lib/checksum64.S | 229 ++ arch/powerpc/lib/copy32.S | 543 +++ arch/powerpc/lib/copypage.S | 121 + arch/powerpc/lib/copyuser.S | 576 ++++ arch/powerpc/lib/div64.S | 58 + arch/powerpc/lib/e2a.c | 108 + arch/powerpc/lib/memcpy.S | 172 + arch/powerpc/lib/rheap.c | 693 ++++ arch/powerpc/lib/sstep.c | 141 + arch/powerpc/lib/strcase.c | 23 + arch/powerpc/lib/string.S | 203 ++ arch/powerpc/lib/usercopy.c | 41 + arch/powerpc/mm/44x_mmu.c | 120 + arch/powerpc/mm/4xx_mmu.c | 141 + arch/powerpc/mm/Makefile | 12 + arch/powerpc/mm/fault.c | 391 +++ arch/powerpc/mm/fsl_booke_mmu.c | 237 ++ arch/powerpc/mm/hash_32.S | 618 ++++ arch/powerpc/mm/init.c | 581 ++++ arch/powerpc/mm/init64.c | 385 +++ arch/powerpc/mm/mem.c | 299 ++ arch/powerpc/mm/mem64.c | 259 ++ arch/powerpc/mm/mem_pieces.c | 163 + arch/powerpc/mm/mem_pieces.h | 48 + arch/powerpc/mm/mmu_context.c | 86 + arch/powerpc/mm/mmu_context64.c | 63 + arch/powerpc/mm/mmu_decl.h | 85 + arch/powerpc/mm/pgtable.c | 470 +++ arch/powerpc/mm/pgtable64.c | 357 ++ arch/powerpc/mm/ppc_mmu.c | 296 ++ arch/powerpc/mm/tlb.c | 183 + arch/powerpc/platforms/4xx/Kconfig | 280 ++ arch/powerpc/platforms/85xx/Kconfig | 86 + arch/powerpc/platforms/8xx/Kconfig | 352 ++ arch/powerpc/platforms/apus/Kconfig | 130 + arch/powerpc/platforms/embedded6xx/Kconfig | 313 ++ arch/powerpc/platforms/iseries/Kconfig | 31 + arch/powerpc/platforms/powermac/Makefile | 9 + arch/powerpc/platforms/powermac/pmac.h | 31 + .../platforms/powermac/pmac_backlight.c | 202 ++ arch/powerpc/platforms/powermac/pmac_cache.S | 359 ++ .../powerpc/platforms/powermac/pmac_cpufreq.c | 728 ++++ .../powerpc/platforms/powermac/pmac_feature.c | 3062 +++++++++++++++++ .../powerpc/platforms/powermac/pmac_low_i2c.c | 523 +++ arch/powerpc/platforms/powermac/pmac_nvram.c | 584 ++++ arch/powerpc/platforms/powermac/pmac_pci.c | 1341 ++++++++ arch/powerpc/platforms/powermac/pmac_pic.c | 655 ++++ arch/powerpc/platforms/powermac/pmac_pic.h | 11 + arch/powerpc/platforms/powermac/pmac_setup.c | 662 ++++ arch/powerpc/platforms/powermac/pmac_sleep.S | 396 +++ arch/powerpc/platforms/powermac/pmac_smp.c | 716 ++++ arch/powerpc/platforms/powermac/pmac_time.c | 291 ++ arch/powerpc/platforms/prep/Kconfig | 22 + arch/powerpc/platforms/pseries/Kconfig | 47 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/mpic.c | 904 +++++ arch/ppc/kernel/Makefile | 21 + arch/ppc/kernel/setup.c | 8 + arch/ppc/platforms/prep_setup.c | 3 - arch/ppc/syslib/Makefile | 14 + drivers/macintosh/via-pmu.c | 2 +- fs/proc/proc_misc.c | 8 - include/asm-powerpc/kdebug.h | 42 + include/asm-powerpc/kprobes.h | 67 + include/asm-powerpc/mpic.h | 279 ++ include/asm-powerpc/reg.h | 446 +++ include/asm-powerpc/system.h | 350 ++ include/asm-ppc/smp.h | 17 +- 89 files changed, 32423 insertions(+), 25 deletions(-) create mode 100644 arch/powerpc/Kconfig create mode 100644 arch/powerpc/Kconfig.debug create mode 100644 arch/powerpc/Makefile create mode 100644 arch/powerpc/kernel/Makefile create mode 100644 arch/powerpc/kernel/asm-offsets.c create mode 100644 arch/powerpc/kernel/fpu.S create mode 100644 arch/powerpc/kernel/head.S create mode 100644 arch/powerpc/kernel/head_44x.S create mode 100644 arch/powerpc/kernel/head_4xx.S create mode 100644 arch/powerpc/kernel/head_64.S create mode 100644 arch/powerpc/kernel/head_8xx.S create mode 100644 arch/powerpc/kernel/head_fsl_booke.S create mode 100644 arch/powerpc/kernel/idle_6xx.S create mode 100644 arch/powerpc/kernel/process.c create mode 100644 arch/powerpc/kernel/semaphore.c create mode 100644 arch/powerpc/kernel/traps.c create mode 100644 arch/powerpc/kernel/vector.S create mode 100644 arch/powerpc/kernel/vmlinux.lds create mode 100644 arch/powerpc/kernel/vmlinux.lds.S create mode 100644 arch/powerpc/lib/Makefile create mode 100644 arch/powerpc/lib/checksum.S create mode 100644 arch/powerpc/lib/checksum64.S create mode 100644 arch/powerpc/lib/copy32.S create mode 100644 arch/powerpc/lib/copypage.S create mode 100644 arch/powerpc/lib/copyuser.S create mode 100644 arch/powerpc/lib/div64.S create mode 100644 arch/powerpc/lib/e2a.c create mode 100644 arch/powerpc/lib/memcpy.S create mode 100644 arch/powerpc/lib/rheap.c create mode 100644 arch/powerpc/lib/sstep.c create mode 100644 arch/powerpc/lib/strcase.c create mode 100644 arch/powerpc/lib/string.S create mode 100644 arch/powerpc/lib/usercopy.c create mode 100644 arch/powerpc/mm/44x_mmu.c create mode 100644 arch/powerpc/mm/4xx_mmu.c create mode 100644 arch/powerpc/mm/Makefile create mode 100644 arch/powerpc/mm/fault.c create mode 100644 arch/powerpc/mm/fsl_booke_mmu.c create mode 100644 arch/powerpc/mm/hash_32.S create mode 100644 arch/powerpc/mm/init.c create mode 100644 arch/powerpc/mm/init64.c create mode 100644 arch/powerpc/mm/mem.c create mode 100644 arch/powerpc/mm/mem64.c create mode 100644 arch/powerpc/mm/mem_pieces.c create mode 100644 arch/powerpc/mm/mem_pieces.h create mode 100644 arch/powerpc/mm/mmu_context.c create mode 100644 arch/powerpc/mm/mmu_context64.c create mode 100644 arch/powerpc/mm/mmu_decl.h create mode 100644 arch/powerpc/mm/pgtable.c create mode 100644 arch/powerpc/mm/pgtable64.c create mode 100644 arch/powerpc/mm/ppc_mmu.c create mode 100644 arch/powerpc/mm/tlb.c create mode 100644 arch/powerpc/platforms/4xx/Kconfig create mode 100644 arch/powerpc/platforms/85xx/Kconfig create mode 100644 arch/powerpc/platforms/8xx/Kconfig create mode 100644 arch/powerpc/platforms/apus/Kconfig create mode 100644 arch/powerpc/platforms/embedded6xx/Kconfig create mode 100644 arch/powerpc/platforms/iseries/Kconfig create mode 100644 arch/powerpc/platforms/powermac/Makefile create mode 100644 arch/powerpc/platforms/powermac/pmac.h create mode 100644 arch/powerpc/platforms/powermac/pmac_backlight.c create mode 100644 arch/powerpc/platforms/powermac/pmac_cache.S create mode 100644 arch/powerpc/platforms/powermac/pmac_cpufreq.c create mode 100644 arch/powerpc/platforms/powermac/pmac_feature.c create mode 100644 arch/powerpc/platforms/powermac/pmac_low_i2c.c create mode 100644 arch/powerpc/platforms/powermac/pmac_nvram.c create mode 100644 arch/powerpc/platforms/powermac/pmac_pci.c create mode 100644 arch/powerpc/platforms/powermac/pmac_pic.c create mode 100644 arch/powerpc/platforms/powermac/pmac_pic.h create mode 100644 arch/powerpc/platforms/powermac/pmac_setup.c create mode 100644 arch/powerpc/platforms/powermac/pmac_sleep.S create mode 100644 arch/powerpc/platforms/powermac/pmac_smp.c create mode 100644 arch/powerpc/platforms/powermac/pmac_time.c create mode 100644 arch/powerpc/platforms/prep/Kconfig create mode 100644 arch/powerpc/platforms/pseries/Kconfig create mode 100644 arch/powerpc/sysdev/Makefile create mode 100644 arch/powerpc/sysdev/mpic.c create mode 100644 include/asm-powerpc/kdebug.h create mode 100644 include/asm-powerpc/kprobes.h create mode 100644 include/asm-powerpc/mpic.h create mode 100644 include/asm-powerpc/reg.h create mode 100644 include/asm-powerpc/system.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig new file mode 100644 index 000000000000..edfac467b9e0 --- /dev/null +++ b/arch/powerpc/Kconfig @@ -0,0 +1,861 @@ +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# + +mainmenu "Linux/PowerPC Kernel Configuration" + +config PPC64 + bool "64-bit kernel" + default n + help + This option selects whether a 32-bit or a 64-bit kernel + will be built. + +config PPC32 + bool + default y if !PPC64 + +config 64BIT + bool + default y if PPC64 + +config PPC_MERGE + def_bool y + +config MMU + bool + default y + +config UID16 + bool + +config GENERIC_HARDIRQS + bool + default y + +config RWSEM_GENERIC_SPINLOCK + bool + +config RWSEM_XCHGADD_ALGORITHM + bool + default y + +config GENERIC_CALIBRATE_DELAY + bool + default y + +config PPC + bool + default y + +config EARLY_PRINTK + bool + default y if PPC64 + +config COMPAT + bool + default y if PPC64 + +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y + +# All PPC32s use generic nvram driver through ppc_md +config GENERIC_NVRAM + bool + default y if PPC32 + +config SCHED_NO_NO_OMIT_FRAME_POINTER + bool + default y + +config ARCH_MAY_HAVE_PC_FDC + bool + default y + +menu "Processor support" +choice + prompt "Processor Type" + depends on PPC32 + default 6xx + +config 6xx + bool "6xx/7xx/74xx" + select PPC_FPU + help + There are four families of PowerPC chips supported. The more common + types (601, 603, 604, 740, 750, 7400), the Motorola embedded + versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC + embedded versions (403 and 405) and the high end 64 bit Power + processors (POWER 3, POWER4, and IBM PPC970 also known as G5). + + Unless you are building a kernel for one of the embedded processor + systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx. + Note that the kernel runs in 32-bit mode even on 64-bit chips. + +config PPC_52xx + bool "Freescale 52xx" + +config PPC_82xx + bool "Freescale 82xx" + +config PPC_83xx + bool "Freescale 83xx" + +config 40x + bool "AMCC 40x" + +config 44x + bool "AMCC 44x" + +config PPC64BRIDGE + select PPC_FPU + bool "POWER3, POWER4 and PPC970 (G5)" + +config 8xx + bool "Freescale 8xx" + +config E200 + bool "Freescale e200" + +config E500 + bool "Freescale e500" +endchoice + +config POWER4_ONLY + bool "Optimize for POWER4" + depends on PPC64 || PPC64BRIDGE + default n + ---help--- + Cause the compiler to optimize for POWER4/POWER5/PPC970 processors. + The resulting binary will not work on POWER3 or RS64 processors + when compiled with binutils 2.15 or later. + +config POWER3 + bool + depends on PPC64 || PPC64BRIDGE + default y if !POWER4_ONLY + +config POWER4 + depends on PPC64 || PPC64BRIDGE + def_bool y + +config PPC_FPU + bool + default y if PPC64 + +config BOOKE + bool + depends on E200 || E500 + default y + +config FSL_BOOKE + bool + depends on E200 || E500 + default y + +config PTE_64BIT + bool + depends on 44x || E500 + default y if 44x + default y if E500 && PHYS_64BIT + +config PHYS_64BIT + bool 'Large physical address support' if E500 + depends on 44x || E500 + default y if 44x + ---help--- + This option enables kernel support for larger than 32-bit physical + addresses. This features is not be available on all e500 cores. + + If in doubt, say N here. + +config ALTIVEC + bool "AltiVec Support" + depends on 6xx || POWER4 + ---help--- + This option enables kernel support for the Altivec extensions to the + PowerPC processor. The kernel currently supports saving and restoring + altivec registers, and turning on the 'altivec enable' bit so user + processes can execute altivec instructions. + + This option is only usefully if you have a processor that supports + altivec (G4, otherwise known as 74xx series), but does not have + any affect on a non-altivec cpu (it does, however add code to the + kernel). + + If in doubt, say Y here. + +config SPE + bool "SPE Support" + depends on E200 || E500 + ---help--- + This option enables kernel support for the Signal Processing + Extensions (SPE) to the PowerPC processor. The kernel currently + supports saving and restoring SPE registers, and turning on the + 'spe enable' bit so user processes can execute SPE instructions. + + This option is only useful if you have a processor that supports + SPE (e500, otherwise known as 85xx series), but does not have any + effect on a non-spe cpu (it does, however add code to the kernel). + + If in doubt, say Y here. + +config PPC_STD_MMU + bool + depends on 6xx || POWER3 || POWER4 || PPC64 + default y + +config PPC_STD_MMU_32 + def_bool y + depends on PPC_STD_MMU && PPC32 + +config SMP + depends on PPC_STD_MMU + bool "Symmetric multi-processing support" + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, say N. If you have a system with more + than one CPU, say Y. Note that the kernel does not currently + support SMP machines with 603/603e/603ev or PPC750 ("G3") processors + since they have inadequate hardware support for multiprocessor + operation. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on single-processor machines. + On a single-processor machine, the kernel will run faster if you say + N here. + + If you don't know what to do here, say N. + +config NR_CPUS + int "Maximum number of CPUs (2-32)" + range 2 128 + depends on SMP + default "32" if PPC64 + default "4" + +config NOT_COHERENT_CACHE + bool + depends on 4xx || 8xx || E200 + default y +endmenu + +source "init/Kconfig" + +menu "Platform support" + depends on PPC64 || 6xx + +choice + prompt "Machine type" + default PPC_MULTIPLATFORM + +config PPC_MULTIPLATFORM + bool "Generic desktop/server/laptop" + help + Select this option if configuring for an IBM pSeries or + RS/6000 machine, an Apple machine, or a PReP, CHRP, + Maple or Cell-based machine. + +config PPC_ISERIES + bool "IBM Legacy iSeries" + depends on PPC64 + +config EMBEDDED6xx + bool "Embedded 6xx/7xx/7xxx-based board" + depends on PPC32 + +config APUS + bool "Amiga-APUS" + depends on PPC32 && BROKEN + help + Select APUS if configuring for a PowerUP Amiga. + More information is available at: + . +endchoice + +config PPC_PSERIES + depends on PPC_MULTIPLATFORM && PPC64 + bool " IBM pSeries & new (POWER5-based) iSeries" + default y + +config PPC_CHRP + bool " Common Hardware Reference Platform (CHRP) based machines" + depends on PPC_MULTIPLATFORM && PPC32 + default y + +config PPC_PMAC + bool " Apple PowerMac based machines" + depends on PPC_MULTIPLATFORM + default y + +config PPC_PMAC64 + bool + depends on PPC_PMAC && POWER4 + default y + +config PPC_PREP + bool " PowerPC Reference Platform (PReP) based machines" + depends on PPC_MULTIPLATFORM && PPC32 + default y + +config PPC_MAPLE + depends on PPC_MULTIPLATFORM && PPC64 + bool " Maple 970FX Evaluation Board" + select U3_DART + select MPIC_BROKEN_U3 + default n + help + This option enables support for the Maple 970FX Evaluation Board. + For more informations, refer to + +config PPC_BPA + bool " Broadband Processor Architecture" + depends on PPC_MULTIPLATFORM && PPC64 + +config PPC_OF + bool + depends on PPC_MULTIPLATFORM # for now + default y + +config XICS + depends on PPC_PSERIES + bool + default y + +config U3_DART + bool + depends on PPC_MULTIPLATFORM && PPC64 + default n + +config MPIC + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE + bool + default y + +config MPIC_BROKEN_U3 + bool + depends on PPC_MAPLE + default y + +config BPA_IIC + depends on PPC_BPA + bool + default y + +config IBMVIO + depends on PPC_PSERIES || PPC_ISERIES + bool + default y + +source "drivers/cpufreq/Kconfig" + +config CPU_FREQ_PMAC + bool "Support for Apple PowerBooks" + depends on CPU_FREQ && ADB_PMU && PPC32 + select CPU_FREQ_TABLE + help + This adds support for frequency switching on Apple PowerBooks, + this currently includes some models of iBook & Titanium + PowerBook. + +config PPC601_SYNC_FIX + bool "Workarounds for PPC601 bugs" + depends on 6xx && (PPC_PREP || PPC_PMAC) + help + Some versions of the PPC601 (the first PowerPC chip) have bugs which + mean that extra synchronization instructions are required near + certain instructions, typically those that make major changes to the + CPU state. These extra instructions reduce performance slightly. + If you say N here, these extra instructions will not be included, + resulting in a kernel which will run faster but may not run at all + on some systems with the PPC601 chip. + + If in doubt, say Y here. + +config TAU + bool "Thermal Management Support" + depends on 6xx + help + G3 and G4 processors have an on-chip temperature sensor called the + 'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die + temperature within 2-4 degrees Celsius. This option shows the current + on-die temperature in /proc/cpuinfo if the cpu supports it. + + Unfortunately, on some chip revisions, this sensor is very inaccurate + and in some cases, does not work at all, so don't assume the cpu + temp is actually what /proc/cpuinfo says it is. + +config TAU_INT + bool "Interrupt driven TAU driver (DANGEROUS)" + depends on TAU + ---help--- + The TAU supports an interrupt driven mode which causes an interrupt + whenever the temperature goes out of range. This is the fastest way + to get notified the temp has exceeded a range. With this option off, + a timer is used to re-check the temperature periodically. + + However, on some cpus it appears that the TAU interrupt hardware + is buggy and can cause a situation which would lead unexplained hard + lockups. + + Unless you are extending the TAU driver, or enjoy kernel/hardware + debugging, leave this option off. + +config TAU_AVERAGE + bool "Average high and low temp" + depends on TAU + ---help--- + The TAU hardware can compare the temperature to an upper and lower + bound. The default behavior is to show both the upper and lower + bound in /proc/cpuinfo. If the range is large, the temperature is + either changing a lot, or the TAU hardware is broken (likely on some + G4's). If the range is small (around 4 degrees), the temperature is + relatively stable. If you say Y here, a single temperature value, + halfway between the upper and lower bounds, will be reported in + /proc/cpuinfo. + + If in doubt, say N here. +endmenu + +source arch/powerpc/platforms/embedded6xx/Kconfig +source arch/powerpc/platforms/4xx/Kconfig +source arch/powerpc/platforms/85xx/Kconfig +source arch/powerpc/platforms/8xx/Kconfig + +menu "Kernel options" + +config HIGHMEM + bool "High memory support" + depends on PPC32 + +source kernel/Kconfig.hz +source kernel/Kconfig.preempt +source "fs/Kconfig.binfmt" + +# We optimistically allocate largepages from the VM, so make the limit +# large enough (16MB). This badly named config option is actually +# max order + 1 +config FORCE_MAX_ZONEORDER + int + depends on PPC64 + default "13" + +config MATH_EMULATION + bool "Math emulation" + depends on 4xx || 8xx || E200 || E500 + ---help--- + Some PowerPC chips designed for embedded applications do not have + a floating-point unit and therefore do not implement the + floating-point instructions in the PowerPC instruction set. If you + say Y here, the kernel will include code to emulate a floating-point + unit, which will allow programs that use floating-point + instructions to run. + +config IOMMU_VMERGE + bool "Enable IOMMU virtual merging (EXPERIMENTAL)" + depends on EXPERIMENTAL && PPC64 + default n + help + Cause IO segments sent to a device for DMA to be merged virtually + by the IOMMU when they happen to have been allocated contiguously. + This doesn't add pressure to the IOMMU allocator. However, some + drivers don't support getting large merged segments coming back + from *_map_sg(). Say Y if you know the drivers you are using are + properly handling this case. + +config HOTPLUG_CPU + bool "Support for enabling/disabling CPUs" + depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) + ---help--- + Say Y here to be able to disable and re-enable individual + CPUs at runtime on SMP machines. + + Say N if you are unsure. + +config KEXEC + bool "kexec system call (EXPERIMENTAL)" + depends on PPC_MULTIPLATFORM && EXPERIMENTAL + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is indepedent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similiarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + +config EMBEDDEDBOOT + bool + depends on 8xx || 8260 + default y + +config PC_KEYBOARD + bool "PC PS/2 style Keyboard" + depends on 4xx || CPM2 + +config PPCBUG_NVRAM + bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC + default y if PPC_PREP + +config IRQ_ALL_CPUS + bool "Distribute interrupts on all CPUs by default" + depends on SMP && !MV64360 + help + This option gives the kernel permission to distribute IRQs across + multiple CPUs. Saying N here will route all IRQs to the first + CPU. Generally saying Y is safe, although some problems have been + reported with SMP Power Macintoshes with this option enabled. + +source "arch/powerpc/platforms/pseries/Kconfig" + +config ARCH_SELECT_MEMORY_MODEL + def_bool y + depends on PPC64 + +config ARCH_FLATMEM_ENABLE + def_bool y + depends on PPC64 && !NUMA + +config ARCH_DISCONTIGMEM_ENABLE + def_bool y + depends on SMP && PPC_PSERIES + +config ARCH_DISCONTIGMEM_DEFAULT + def_bool y + depends on ARCH_DISCONTIGMEM_ENABLE + +config ARCH_FLATMEM_ENABLE + def_bool y + depends on PPC64 + +config ARCH_SPARSEMEM_ENABLE + def_bool y + depends on ARCH_DISCONTIGMEM_ENABLE + +source "mm/Kconfig" + +config HAVE_ARCH_EARLY_PFN_TO_NID + def_bool y + depends on NEED_MULTIPLE_NODES + +# Some NUMA nodes have memory ranges that span +# other nodes. Even though a pfn is valid and +# between a node's start and end pfns, it may not +# reside on that node. +# +# This is a relatively temporary hack that should +# be able to go away when sparsemem is fully in +# place + +config NODES_SPAN_OTHER_NODES + def_bool y + depends on NEED_MULTIPLE_NODES + +config NUMA + bool "NUMA support" + default y if DISCONTIGMEM || SPARSEMEM + +config SCHED_SMT + bool "SMT (Hyperthreading) scheduler support" + depends on PPC64 && SMP + default off + help + SMT scheduler support improves the CPU scheduler's decision making + when dealing with POWER5 cpus at a cost of slightly increased + overhead in some places. If unsure say N here. + +config PROC_DEVICETREE + bool "Support for Open Firmware device tree in /proc" + depends on PPC_OF && PROC_FS + help + This option adds a device-tree directory under /proc which contains + an image of the device tree that the kernel copies from Open + Firmware. If unsure, say Y here. + +source "arch/powerpc/platforms/prep/Kconfig" + +config CMDLINE_BOOL + bool "Default bootloader kernel arguments" + depends on !PPC_ISERIES + +config CMDLINE + string "Initial kernel command string" + depends on CMDLINE_BOOL + default "console=ttyS0,9600 console=tty0 root=/dev/sda2" + help + On some platforms, there is currently no way for the boot loader to + pass arguments to the kernel. For these platforms, you can supply + some command-line options at build time by entering them here. In + most cases you will need to specify the root device here. + +if !44x || BROKEN +source kernel/power/Kconfig +endif + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc//seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + +endmenu + +config ISA_DMA_API + bool + default y + +menu "Bus options" + +config ISA + bool "Support for ISA-bus hardware" + depends on PPC_PREP || PPC_CHRP + help + Find out whether you have ISA slots on your motherboard. ISA is the + name of a bus system, i.e. the way the CPU talks to the other stuff + inside your box. If you have an Apple machine, say N here; if you + have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If + you have an embedded board, consult your board documentation. + +config GENERIC_ISA_DMA + bool + depends on PPC64 || POWER4 || 6xx && !CPM2 + default y + +config EISA + bool + +config SBUS + bool + +# Yes MCA RS/6000s exist but Linux-PPC does not currently support any +config MCA + bool + +config PCI + bool "PCI support" if 40x || CPM2 || 83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) + default y if !40x && !CPM2 && !8xx && !APUS && !83xx && !85xx + default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS + default PCI_QSPAN if !4xx && !CPM2 && 8xx + help + Find out whether your system includes a PCI bus. PCI is the name of + a bus system, i.e. the way the CPU talks to the other stuff inside + your box. If you say Y here, the kernel will include drivers and + infrastructure code to support PCI bus devices. + +config PCI_DOMAINS + bool + default PCI + +config MPC83xx_PCI2 + bool " Supprt for 2nd PCI host controller" + depends on PCI && MPC834x + default y if MPC834x_SYS + +config PCI_QSPAN + bool "QSpan PCI" + depends on !4xx && !CPM2 && 8xx + help + Say Y here if you have a system based on a Motorola 8xx-series + embedded processor with a QSPAN PCI interface, otherwise say N. + +config PCI_8260 + bool + depends on PCI && 8260 + default y + +config 8260_PCI9 + bool " Enable workaround for MPC826x erratum PCI 9" + depends on PCI_8260 && !ADS8272 + default y + +choice + prompt " IDMA channel for PCI 9 workaround" + depends on 8260_PCI9 + +config 8260_PCI9_IDMA1 + bool "IDMA1" + +config 8260_PCI9_IDMA2 + bool "IDMA2" + +config 8260_PCI9_IDMA3 + bool "IDMA3" + +config 8260_PCI9_IDMA4 + bool "IDMA4" + +endchoice + +source "drivers/pci/Kconfig" + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +endmenu + +menu "Advanced setup" + depends on PPC32 + +config ADVANCED_OPTIONS + bool "Prompt for advanced kernel configuration options" + help + This option will enable prompting for a variety of advanced kernel + configuration options. These options can cause the kernel to not + work if they are set incorrectly, but can be used to optimize certain + aspects of kernel memory management. + + Unless you know what you are doing, say N here. + +comment "Default settings for advanced configuration options are used" + depends on !ADVANCED_OPTIONS + +config HIGHMEM_START_BOOL + bool "Set high memory pool address" + depends on ADVANCED_OPTIONS && HIGHMEM + help + This option allows you to set the base address of the kernel virtual + area used to map high memory pages. This can be useful in + optimizing the layout of kernel virtual memory. + + Say N here unless you know what you are doing. + +config HIGHMEM_START + hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL + default "0xfe000000" + +config LOWMEM_SIZE_BOOL + bool "Set maximum low memory" + depends on ADVANCED_OPTIONS + help + This option allows you to set the maximum amount of memory which + will be used as "low memory", that is, memory which the kernel can + access directly, without having to set up a kernel virtual mapping. + This can be useful in optimizing the layout of kernel virtual + memory. + + Say N here unless you know what you are doing. + +config LOWMEM_SIZE + hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL + default "0x30000000" + +config KERNEL_START_BOOL + bool "Set custom kernel base address" + depends on ADVANCED_OPTIONS + help + This option allows you to set the kernel virtual address at which + the kernel will map low memory (the kernel image will be linked at + this address). This can be useful in optimizing the virtual memory + layout of the system. + + Say N here unless you know what you are doing. + +config KERNEL_START + hex "Virtual address of kernel base" if KERNEL_START_BOOL + default "0xc0000000" + +config TASK_SIZE_BOOL + bool "Set custom user task size" + depends on ADVANCED_OPTIONS + help + This option allows you to set the amount of virtual address space + allocated to user tasks. This can be useful in optimizing the + virtual memory layout of the system. + + Say N here unless you know what you are doing. + +config TASK_SIZE + hex "Size of user task space" if TASK_SIZE_BOOL + default "0x80000000" + +config CONSISTENT_START_BOOL + bool "Set custom consistent memory pool address" + depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE + help + This option allows you to set the base virtual address + of the the consistent memory pool. This pool of virtual + memory is used to make consistent memory allocations. + +config CONSISTENT_START + hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL + default "0xff100000" if NOT_COHERENT_CACHE + +config CONSISTENT_SIZE_BOOL + bool "Set custom consistent memory pool size" + depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE + help + This option allows you to set the size of the the + consistent memory pool. This pool of virtual memory + is used to make consistent memory allocations. + +config CONSISTENT_SIZE + hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL + default "0x00200000" if NOT_COHERENT_CACHE + +config BOOT_LOAD_BOOL + bool "Set the boot link/load address" + depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM + help + This option allows you to set the initial load address of the zImage + or zImage.initrd file. This can be useful if you are on a board + which has a small amount of memory. + + Say N here unless you know what you are doing. + +config BOOT_LOAD + hex "Link/load address for booting" if BOOT_LOAD_BOOL + default "0x00400000" if 40x || 8xx || 8260 + default "0x01000000" if 44x + default "0x00800000" + +config PIN_TLB + bool "Pinned Kernel TLBs (860 ONLY)" + depends on ADVANCED_OPTIONS && 8xx +endmenu + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +# XXX source "arch/ppc/8xx_io/Kconfig" + +# XXX source "arch/ppc/8260_io/Kconfig" + +source "arch/powerpc/platforms/iseries/Kconfig" + +source "lib/Kconfig" + +source "arch/powerpc/oprofile/Kconfig" + +source "arch/powerpc/Kconfig.debug" + +source "security/Kconfig" + +config KEYS_COMPAT + bool + depends on COMPAT && KEYS + default y + +source "crypto/Kconfig" diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug new file mode 100644 index 000000000000..61653cb60c4e --- /dev/null +++ b/arch/powerpc/Kconfig.debug @@ -0,0 +1,73 @@ +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config KGDB + bool "Include kgdb kernel debugger" + depends on DEBUG_KERNEL && (BROKEN || PPC_GEN550 || 4xx) + select DEBUG_INFO + help + Include in-kernel hooks for kgdb, the Linux kernel source level + debugger. See for more information. + Unless you are intending to debug the kernel, say N here. + +choice + prompt "Serial Port" + depends on KGDB + default KGDB_TTYS1 + +config KGDB_TTYS0 + bool "ttyS0" + +config KGDB_TTYS1 + bool "ttyS1" + +config KGDB_TTYS2 + bool "ttyS2" + +config KGDB_TTYS3 + bool "ttyS3" + +endchoice + +config KGDB_CONSOLE + bool "Enable serial console thru kgdb port" + depends on KGDB && 8xx || CPM2 + help + If you enable this, all serial console messages will be sent + over the gdb stub. + If unsure, say N. + +config XMON + bool "Include xmon kernel debugger" + depends on DEBUG_KERNEL + help + Include in-kernel hooks for the xmon kernel monitor/debugger. + Unless you are intending to debug the kernel, say N here. + +config BDI_SWITCH + bool "Include BDI-2000 user context switcher" + depends on DEBUG_KERNEL + help + Include in-kernel support for the Abatron BDI2000 debugger. + Unless you are intending to debug the kernel with one of these + machines, say N here. + +config BOOTX_TEXT + bool "Support for early boot text console (BootX or OpenFirmware only)" + depends PPC_OF + help + Say Y here to see progress messages from the boot firmware in text + mode. Requires either BootX or Open Firmware. + +config SERIAL_TEXT_DEBUG + bool "Support for early boot texts over serial port" + depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ + PPC_GEN550 || PPC_MPC52xx + +config PPC_OCP + bool + depends on IBM_OCP || XILINX_OCP + default y + +endmenu diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile new file mode 100644 index 000000000000..8a65e112211b --- /dev/null +++ b/arch/powerpc/Makefile @@ -0,0 +1,222 @@ +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. Remember to do have actions +# for "archclean" and "archdep" for cleaning up and making dependencies for +# this architecture. +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1994 by Linus Torvalds +# Changes for PPC by Gary Thomas +# Rewritten by Cort Dougan and Paul Mackerras +# + +# This must match PAGE_OFFSET in include/asm-powerpc/page.h. +KERNELLOAD := $(CONFIG_KERNEL_START) + +HAS_BIARCH := $(call cc-option-yn, -m32) + +ifeq ($(CONFIG_PPC64),y) +SZ := 64 + +# Set default 32 bits cross compilers for vdso and boot wrapper +CROSS32_COMPILE ?= + +CROSS32CC := $(CROSS32_COMPILE)gcc +CROSS32AS := $(CROSS32_COMPILE)as +CROSS32LD := $(CROSS32_COMPILE)ld +CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy + +ifeq ($(HAS_BIARCH),y) +ifeq ($(CROSS32_COMPILE),) +CROSS32CC := $(CC) -m32 +CROSS32AS := $(AS) -a32 +CROSS32LD := $(LD) -m elf32ppc +CROSS32OBJCOPY := $(OBJCOPY) +endif +endif + +export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY + +new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) + +ifeq ($(new_nm),y) +NM := $(NM) --synthetic +endif + +else +SZ := 32 +endif + +ifeq ($(HAS_BIARCH),y) +override AS += -a$(SZ) +override LD += -m elf$(SZ)ppc +override CC += -m$(SZ) +endif + +LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD) + +# The -Iarch/$(ARCH)/include is temporary while we are merging +CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include +AFLAGS += -Iarch/$(ARCH) +CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe +ifeq ($(CONFIG_PPC64),y) +CFLAGS += -mminimal-toc -mtraceback=none -mcall-aixdesc +else +CFLAGS += -ffixed-r2 -mmultiple +endif +CPP = $(CC) -E $(CFLAGS) +# Temporary hack until we have migrated to asm-powerpc +LINUXINCLUDE += -Iarch/$(ARCH)/include + +CHECKFLAGS += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__ + +ifeq ($(CONFIG_PPC64),y) +GCC_VERSION := $(call cc-version) +GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi) + +ifeq ($(CONFIG_POWER4_ONLY),y) +ifeq ($(CONFIG_ALTIVEC),y) +ifeq ($(GCC_BROKEN_VEC),y) + CFLAGS += $(call cc-option,-mcpu=970) +else + CFLAGS += $(call cc-option,-mcpu=power4) +endif +else + CFLAGS += $(call cc-option,-mcpu=power4) +endif +else + CFLAGS += $(call cc-option,-mtune=power4) +endif +endif + +# Enable unit-at-a-time mode when possible. It shrinks the +# kernel considerably. +CFLAGS += $(call cc-option,-funit-at-a-time) + +ifndef CONFIG_FSL_BOOKE +CFLAGS += -mstring +endif + +cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge +cpu-as-$(CONFIG_4xx) += -Wa,-m405 +cpu-as-$(CONFIG_6xx) += -Wa,-maltivec +cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec +cpu-as-$(CONFIG_E500) += -Wa,-me500 +cpu-as-$(CONFIG_E200) += -Wa,-me200 + +AFLAGS += $(cpu-as-y) +CFLAGS += $(cpu-as-y) + +# Default to the common case. +KBUILD_DEFCONFIG := common_defconfig + +head-y := arch/powerpc/kernel/head.o +head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o +head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o +head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o +head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o +head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o + +ifeq ($(CONFIG_PPC32),y) +head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o +head-$(CONFIG_POWER4) += arch/powerpc/kernel/idle_power4.o +head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o +endif + +core-y += arch/powerpc/kernel/ \ + arch/powerpc/mm/ \ + arch/powerpc/lib/ \ + arch/powerpc/sysdev/ +core-$(CONFIG_PPC32) += arch/ppc/kernel/ \ + arch/ppc/syslib/ +core-$(CONFIG_PPC64) += arch/ppc64/kernel/ +core-$(CONFIG_PPC_PMAC) += arch/powerpc/platforms/powermac/ +core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ +core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ +core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ +core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ +core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_APUS) += arch/ppc/amiga/ +drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ +drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ +drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ + +drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ + +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm + +.PHONY: $(BOOT_TARGETS) + +all: uImage zImage + +CPPFLAGS_vmlinux.lds := -Upowerpc + +# All the instructions talk about "make bzImage". +bzImage: zImage + +boot := arch/$(ARCH)/boot + +$(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $@ + +uImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot)/images $(boot)/images/$@ + +define archhelp + @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)' + @echo ' uImage - Create a bootable image for U-Boot / PPCBoot' + @echo ' install - Install kernel using' + @echo ' (your) ~/bin/installkernel or' + @echo ' (distribution) /sbin/installkernel or' + @echo ' install to $$(INSTALL_PATH) and run lilo' + @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs' +endef + +archclean: + $(Q)$(MAKE) $(clean)=arch/ppc/boot + # Temporary hack until we have migrated to asm-powerpc + $(Q)rm -rf arch/$(ARCH)/include + +archprepare: checkbin + +# Temporary hack until we have migrated to asm-powerpc +ifeq ($(CONFIG_PPC64),y) +include/asm: arch/$(ARCH)/include/asm +arch/$(ARCH)/include/asm: + $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi + $(Q)ln -fsn $(srctree)/include/asm-ppc64 arch/$(ARCH)/include/asm +else +include/asm: arch/$(ARCH)/include/asm +arch/$(ARCH)/include/asm: + $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi + $(Q)ln -fsn $(srctree)/include/asm-ppc arch/$(ARCH)/include/asm +endif + +# Use the file '.tmp_gas_check' for binutils tests, as gas won't output +# to stdout and these checks are run even on install targets. +TOUT := .tmp_gas_check +# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec +# instructions. +# gcc-3.4 and binutils-2.14 are a fatal combination. +GCC_VERSION := $(call cc-version) + +checkbin: + @if test "$(GCC_VERSION)" = "0304" ; then \ + if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \ + echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \ + echo 'correctly with gcc-3.4 and your version of binutils.'; \ + echo '*** Please upgrade your binutils or downgrade your gcc'; \ + false; \ + fi ; \ + fi + @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \ + echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \ + echo 'correctly with old versions of binutils.' ; \ + echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \ + false ; \ + fi + +CLEAN_FILES += $(TOUT) + diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile new file mode 100644 index 000000000000..62c4a51a23d7 --- /dev/null +++ b/arch/powerpc/kernel/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the linux kernel. +# + +extra-$(CONFIG_PPC_STD_MMU) := head.o +extra_$(CONFIG_PPC64) := head_64.o +extra-$(CONFIG_40x) := head_4xx.o +extra-$(CONFIG_44x) := head_44x.o +extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o +extra-$(CONFIG_8xx) := head_8xx.o +extra-$(CONFIG_6xx) += idle_6xx.o +extra-$(CONFIG_POWER4) += idle_power4.o +extra-$(CONFIG_PPC_FPU) += fpu.o +extra-y += vmlinux.lds + +obj-y := semaphore.o traps.o process.o + +obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c new file mode 100644 index 000000000000..16cf0b7ee2b7 --- /dev/null +++ b/arch/powerpc/kernel/asm-offsets.c @@ -0,0 +1,262 @@ +/* + * This program is used to generate definitions needed by + * assembly language modules. + * + * We use the technique used in the OSF Mach kernel code: + * generate asm statements containing #defines, + * compile this file to assembler, and then extract the + * #defines from the assembly-language output. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef CONFIG_PPC64 +#include +#include +#include +#include +#include +#include +#include +#endif + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define BLANK() asm volatile("\n->" : : ) + +int main(void) +{ + /* thread struct on stack */ + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); +#ifdef CONFIG_PPC32 + DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); +#endif +#ifdef CONFIG_PPC64 + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); + DEFINE(THREAD_SHIFT, THREAD_SHIFT); +#endif + DEFINE(THREAD_SIZE, THREAD_SIZE); + + /* task_struct->thread */ + DEFINE(THREAD, offsetof(struct task_struct, thread)); + DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); + DEFINE(MM, offsetof(struct task_struct, mm)); + DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); + DEFINE(KSP, offsetof(struct thread_struct, ksp)); + DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); + DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall)); + DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); + DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); + DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); + DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); + DEFINE(PT_PTRACED, PT_PTRACED); +#endif +#ifdef CONFIG_PPC64 + DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); +#endif + +#ifdef CONFIG_ALTIVEC + DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); + DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); + DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); + DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0])); + DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc)); + DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr)); + DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe)); +#endif /* CONFIG_SPE */ + /* Interrupt register frame */ + DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); +#ifndef CONFIG_PPC64 + DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); +#else + DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); + + /* 288 = # of volatile regs, int & fp, for leaf routines */ + /* which do not stack a frame. See the PPC64 ABI. */ + DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288); +#endif + /* in fact we only use gpr0 - gpr9 and gpr20 - gpr23 */ + DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0])); + DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1])); + DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2])); + DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3])); + DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4])); + DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5])); + DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6])); + DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7])); + DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8])); + DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9])); + DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10])); + DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11])); + DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12])); + DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13])); + DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14])); + DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15])); + DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16])); + DEFINE(GPR17, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[17])); + DEFINE(GPR18, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[18])); + DEFINE(GPR19, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[19])); + DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20])); + DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21])); + DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22])); + DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23])); + DEFINE(GPR24, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[24])); + DEFINE(GPR25, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[25])); + DEFINE(GPR26, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[26])); + DEFINE(GPR27, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[27])); + DEFINE(GPR28, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[28])); + DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29])); + DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30])); + DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31])); + /* + * Note: these symbols include _ because they overlap with special + * register names + */ + DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip)); + DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr)); + DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr)); + DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link)); + DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr)); + DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq)); + DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer)); + DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); + DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); + /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR + * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs + * for such processors. For critical interrupts we use them to + * hold SRR0 and SRR1. + */ + DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); + DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); + DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); + DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); + DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); + DEFINE(CLONE_VM, CLONE_VM); + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); + DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); + + /* About the CPU features table */ + DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); + DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask)); + DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); + DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); + DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + +#ifdef CONFIG_PPC64 + DEFINE(MM, offsetof(struct task_struct, mm)); + DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); + + DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); + DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size)); + DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page)); + DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); + DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); + DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); + DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); + + /* paca */ + DEFINE(PACA_SIZE, sizeof(struct paca_struct)); + DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); + DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start)); + DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack)); + DEFINE(PACACURRENT, offsetof(struct paca_struct, __current)); + DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr)); + DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real)); + DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr)); + DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); + DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); + DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); + DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); + DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); + DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); + DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); +#ifdef CONFIG_HUGETLB_PAGE + DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); + DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); +#endif /* CONFIG_HUGETLB_PAGE */ + DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr)); + DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); + DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); + DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); + DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi)); + DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); + DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); + DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); + DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); + DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); + DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); + DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); + + /* RTAS */ + DEFINE(RTASBASE, offsetof(struct rtas_t, base)); + DEFINE(RTASENTRY, offsetof(struct rtas_t, entry)); + + DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); + DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe)); + + /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ + DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); + DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); + + /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */ + DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)); + DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8); + + /* systemcfg offsets for use by vdso */ + DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp)); + DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec)); + DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs)); + DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec)); + DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count)); + DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest)); + DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime)); + DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32)); + DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64)); + + /* timeval/timezone offsets for use by vdso */ + DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec)); + DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); + DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); + DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); + DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); + DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); +#endif + + DEFINE(pbe_address, offsetof(struct pbe, address)); + DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); + DEFINE(pbe_next, offsetof(struct pbe, next)); + + DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); + return 0; +} diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S new file mode 100644 index 000000000000..665d7d34304c --- /dev/null +++ b/arch/powerpc/kernel/fpu.S @@ -0,0 +1,133 @@ +/* + * FPU support code, moved here from head.S so that it can be used + * by chips which use other head-whatever.S files. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This task wants to use the FPU now. + * On UP, disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Load up this task's FP registers from its thread_struct, + * enable the FPU for the current task and return to the task. + */ + .globl load_up_fpu +load_up_fpu: + mfmsr r5 + ori r5,r5,MSR_FP +#ifdef CONFIG_PPC64BRIDGE + clrldi r5,r5,1 /* turn off 64-bit mode */ +#endif /* CONFIG_PPC64BRIDGE */ + SYNC + MTMSRD(r5) /* enable use of fpu now */ + isync +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + */ +#ifndef CONFIG_SMP + tophys(r6,0) /* get __pa constant */ + addis r3,r6,last_task_used_math@ha + lwz r4,last_task_used_math@l(r3) + cmpwi 0,r4,0 + beq 1f + add r4,r4,r6 + addi r4,r4,THREAD /* want last_task_used_math->thread */ + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r4) + lwz r5,PT_REGS(r4) + add r5,r5,r6 + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r10,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r10 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ + lwz r4,THREAD_FPEXC_MODE(r5) + ori r9,r9,MSR_FP /* enable FP for current */ + or r9,r9,r4 + lfd fr0,THREAD_FPSCR-4(r5) + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) +#ifndef CONFIG_SMP + subi r4,r5,THREAD + sub r4,r4,r6 + stw r4,last_task_used_math@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + /* we haven't used ctr or xer or lr */ + b fast_exception_return + +/* + * FP unavailable trap from kernel - print a message, but let + * the task use FP in the kernel until it returns to user mode. + */ + .globl KernelFP +KernelFP: + lwz r3,_MSR(r1) + ori r3,r3,MSR_FP + stw r3,_MSR(r1) /* enable use of FP after return */ + lis r3,86f@h + ori r3,r3,86f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +86: .string "floating point used in kernel (task=%p, pc=%x)\n" + .align 4,0 + +/* + * giveup_fpu(tsk) + * Disable FP for the task given as the argument, + * and save the floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + */ + .globl giveup_fpu +giveup_fpu: + mfmsr r5 + ori r5,r5,MSR_FP + SYNC_601 + ISYNC_601 + MTMSRD(r5) /* enable use of fpu now */ + SYNC_601 + isync + cmpwi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpwi 0,r5,0 + SAVE_32FPRS(0, r3) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r3) + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r3 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_math@ha + stw r5,last_task_used_math@l(r4) +#endif /* CONFIG_SMP */ + blr diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S new file mode 100644 index 000000000000..d05509f197d0 --- /dev/null +++ b/arch/powerpc/kernel/head.S @@ -0,0 +1,1545 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * This file contains the low-level support and setup for the + * PowerPC platform, including trap and interrupt dispatch. + * (The PPC 8xx embedded CPUs use head_8xx.S instead.) + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_APUS +#include +#endif + +#ifdef CONFIG_PPC64BRIDGE +#define LOAD_BAT(n, reg, RA, RB) \ + ld RA,(n*32)+0(reg); \ + ld RB,(n*32)+8(reg); \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_IBAT##n##L,RB; \ + ld RA,(n*32)+16(reg); \ + ld RB,(n*32)+24(reg); \ + mtspr SPRN_DBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##L,RB; \ + +#else /* CONFIG_PPC64BRIDGE */ + +/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ +#define LOAD_BAT(n, reg, RA, RB) \ + /* see the comment for clear_bats() -- Cort */ \ + li RA,0; \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##U,RA; \ + lwz RA,(n*16)+0(reg); \ + lwz RB,(n*16)+4(reg); \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_IBAT##n##L,RB; \ + beq 1f; \ + lwz RA,(n*16)+8(reg); \ + lwz RB,(n*16)+12(reg); \ + mtspr SPRN_DBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##L,RB; \ +1: +#endif /* CONFIG_PPC64BRIDGE */ + + .text + .stabs "arch/ppc/kernel/",N_SO,0,0,0f + .stabs "head.S",N_SO,0,0,0f +0: + .globl _stext +_stext: + +/* + * _start is defined this way because the XCOFF loader in the OpenFirmware + * on the powermac expects the entry point to be a procedure descriptor. + */ + .text + .globl _start +_start: + /* + * These are here for legacy reasons, the kernel used to + * need to look like a coff function entry for the pmac + * but we're always started by some kind of bootloader now. + * -- Cort + */ + nop /* used by __secondary_hold on prep (mtx) and chrp smp */ + nop /* used by __secondary_hold on prep (mtx) and chrp smp */ + nop + +/* PMAC + * Enter here with the kernel text, data and bss loaded starting at + * 0, running with virtual == physical mapping. + * r5 points to the prom entry point (the client interface handler + * address). Address translation is turned on, with the prom + * managing the hash table. Interrupts are disabled. The stack + * pointer (r1) points to just below the end of the half-meg region + * from 0x380000 - 0x400000, which is mapped in already. + * + * If we are booted from MacOS via BootX, we enter with the kernel + * image loaded somewhere, and the following values in registers: + * r3: 'BooX' (0x426f6f58) + * r4: virtual address of boot_infos_t + * r5: 0 + * + * APUS + * r3: 'APUS' + * r4: physical address of memory base + * Linux/m68k style BootInfo structure at &_end. + * + * PREP + * This is jumped to on prep systems right after the kernel is relocated + * to its proper place in memory by the boot loader. The expected layout + * of the regs is: + * r3: ptr to residual data + * r4: initrd_start or if no initrd then 0 + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + * + * This just gets a minimal mmu environment setup so we can call + * start_here() to do the real work. + * -- Cort + */ + + .globl __start +__start: +/* + * We have to do any OF calls before we map ourselves to KERNELBASE, + * because OF may have I/O devices mapped into that area + * (particularly on CHRP). + */ + mr r31,r3 /* save parameters */ + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* cpu # */ + +/* + * early_init() does the early machine identification and does + * the necessary low-level setup and clears the BSS + * -- Cort + */ + bl early_init + +/* + * On POWER4, we first need to tweak some CPU configuration registers + * like real mode cache inhibit or exception base + */ +#ifdef CONFIG_POWER4 + bl __970_cpu_preinit +#endif /* CONFIG_POWER4 */ + +#ifdef CONFIG_APUS +/* On APUS the __va/__pa constants need to be set to the correct + * values before continuing. + */ + mr r4,r30 + bl fix_mem_constants +#endif /* CONFIG_APUS */ + +/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains + * the physical address we are running at, returned by early_init() + */ + bl mmu_off +__after_mmu_off: +#ifndef CONFIG_POWER4 + bl clear_bats + bl flush_tlbs + + bl initial_bats +#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) + bl setup_disp_bat +#endif +#else /* CONFIG_POWER4 */ + bl reloc_offset + bl initial_mm_power4 +#endif /* CONFIG_POWER4 */ + +/* + * Call setup_cpu for CPU 0 and initialize 6xx Idle + */ + bl reloc_offset + li r24,0 /* cpu# */ + bl call_setup_cpu /* Call setup_cpu for this CPU */ +#ifdef CONFIG_6xx + bl reloc_offset + bl init_idle_6xx +#endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + bl reloc_offset + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ + + +#ifndef CONFIG_APUS +/* + * We need to run with _start at physical address 0. + * On CHRP, we are loaded at 0x10000 since OF on CHRP uses + * the exception vectors at 0 (and therefore this copy + * overwrites OF's exception vectors with our own). + * If the MMU is already turned on, we copy stuff to KERNELBASE, + * otherwise we copy it to 0. + */ + bl reloc_offset + mr r26,r3 + addis r4,r3,KERNELBASE@h /* current address of _start */ + cmpwi 0,r4,0 /* are we already running at 0? */ + bne relocate_kernel +#endif /* CONFIG_APUS */ +/* + * we now have the 1st 16M of ram mapped with the bats. + * prep needs the mmu to be turned on here, but pmac already has it on. + * this shouldn't bother the pmac since it just gets turned on again + * as we jump to our code at KERNELBASE. -- Cort + * Actually no, pmac doesn't have it on any more. BootX enters with MMU + * off, and in other cases, we now turn it off before changing BATs above. + */ +turn_on_mmu: + mfmsr r0 + ori r0,r0,MSR_DR|MSR_IR + mtspr SPRN_SRR1,r0 + lis r0,start_here@h + ori r0,r0,start_here@l + mtspr SPRN_SRR0,r0 + SYNC + RFI /* enables MMU */ + +/* + * We need __secondary_hold as a place to hold the other cpus on + * an SMP machine, even when we are running a UP kernel. + */ + . = 0xc0 /* for prep bootloader */ + li r3,1 /* MTX only has 1 cpu */ + .globl __secondary_hold +__secondary_hold: + /* tell the master we're here */ + stw r3,4(0) +#ifdef CONFIG_SMP +100: lwz r4,0(0) + /* wait until we're told to start */ + cmpw 0,r4,r3 + bne 100b + /* our cpu # was at addr 0 - go */ + mr r24,r3 /* cpu # */ + b __secondary_start +#else + b . +#endif /* CONFIG_SMP */ + +/* + * Exception entry code. This code runs with address translation + * turned off, i.e. using physical addresses. + * We assume sprg3 has the physical address of the current + * task's thread_struct. + */ +#define EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; \ + mtspr SPRN_SPRG1,r11; \ + mfcr r10; \ + EXCEPTION_PROLOG_1; \ + EXCEPTION_PROLOG_2 + +#define EXCEPTION_PROLOG_1 \ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ + andi. r11,r11,MSR_PR; \ + tophys(r11,r1); /* use tophys(r1) if kernel */ \ + beq 1f; \ + mfspr r11,SPRN_SPRG3; \ + lwz r11,THREAD_INFO-THREAD(r11); \ + addi r11,r11,THREAD_SIZE; \ + tophys(r11,r11); \ +1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */ + + +#define EXCEPTION_PROLOG_2 \ + CLR_TOP32(r11); \ + stw r10,_CCR(r11); /* save registers */ \ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRN_SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRN_SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_SRR0; \ + mfspr r9,SPRN_SRR1; \ + stw r1,GPR1(r11); \ + stw r1,0(r11); \ + tovirt(r1,r11); /* set new kernel sp */ \ + li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ + MTMSRD(r10); /* (except for mach check in rtas) */ \ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Note: code which follows this uses cr0.eq (set if from kernel), + * r11, r12 (SRR0), and r9 (SRR1). + * + * Note2: once we have set r1 we are in a position to take exceptions + * again, and we could thus set MSR:RI at that point. + */ + +/* + * Exception vectors. + */ +#define EXCEPTION(n, label, hdlr, xfer) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + li r10,MSR_KERNEL; \ + copyee(r10, r9); \ + bl tfer; \ +i##n: \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \ + ret_from_except) + +/* System reset */ +/* core99 pmac starts the seconary here by changing the vector, and + putting it back to what it was (UnknownException) when done. */ +#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) + . = 0x100 + b __secondary_start_gemini +#else + EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) +#endif + +/* Machine check */ +/* + * On CHRP, this is complicated by the fact that we could get a + * machine check inside RTAS, and we have no guarantee that certain + * critical registers will have the values we expect. The set of + * registers that might have bad values includes all the GPRs + * and all the BATs. We indicate that we are in RTAS by putting + * a non-zero value, the address of the exception frame to use, + * in SPRG2. The machine check handler checks SPRG2 and uses its + * value if it is non-zero. If we ever needed to free up SPRG2, + * we could use a field in the thread_info or thread_struct instead. + * (Other exception handlers assume that r1 is a valid kernel stack + * pointer when we take an exception from supervisor mode.) + * -- paulus. + */ + . = 0x200 + mtspr SPRN_SPRG0,r10 + mtspr SPRN_SPRG1,r11 + mfcr r10 +#ifdef CONFIG_PPC_CHRP + mfspr r11,SPRN_SPRG2 + cmpwi 0,r11,0 + bne 7f +#endif /* CONFIG_PPC_CHRP */ + EXCEPTION_PROLOG_1 +7: EXCEPTION_PROLOG_2 + addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_PPC_CHRP + mfspr r4,SPRN_SPRG2 + cmpwi cr1,r4,0 + bne cr1,1f +#endif + EXC_XFER_STD(0x200, MachineCheckException) +#ifdef CONFIG_PPC_CHRP +1: b machine_check_in_rtas +#endif + +/* Data access exception. */ + . = 0x300 +#ifdef CONFIG_PPC64BRIDGE + b DataAccess +DataAccessCont: +#else +DataAccess: + EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ + mfspr r10,SPRN_DSISR + andis. r0,r10,0xa470 /* weird error? */ + bne 1f /* if not, try to put a PTE */ + mfspr r4,SPRN_DAR /* into the hash table */ + rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ + bl hash_page +1: stw r10,_DSISR(r11) + mr r5,r10 + mfspr r4,SPRN_DAR + EXC_XFER_EE_LITE(0x300, handle_page_fault) + +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on data access. */ + . = 0x380 + b DataSegment +#endif /* CONFIG_PPC64BRIDGE */ + +/* Instruction access exception. */ + . = 0x400 +#ifdef CONFIG_PPC64BRIDGE + b InstructionAccess +InstructionAccessCont: +#else +InstructionAccess: + EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ + andis. r0,r9,0x4000 /* no pte found? */ + beq 1f /* if so, try to put a PTE */ + li r3,0 /* into the hash table */ + mr r4,r12 /* SRR0 is fault address */ + bl hash_page +1: mr r4,r12 + mr r5,r9 + EXC_XFER_EE_LITE(0x400, handle_page_fault) + +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on instruction access. */ + . = 0x480 + b InstructionSegment +#endif /* CONFIG_PPC64BRIDGE */ + +/* External interrupt */ + EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) + +/* Alignment exception */ + . = 0x600 +Alignment: + EXCEPTION_PROLOG + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x600, AlignmentException) + +/* Program check exception */ + EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + +/* Floating-point unavailable */ + . = 0x800 +FPUnavailable: + EXCEPTION_PROLOG + bne load_up_fpu /* if from user, just load it up */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x800, KernelFP) + +/* Decrementer */ + EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) + + EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + +/* System call */ + . = 0xc00 +SystemCall: + EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0xc00, DoSyscall) + +/* Single step - not used on 601 */ + EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) + +/* + * The Altivec unavailable trap is at 0x0f20. Foo. + * We effectively remap it to 0x3000. + * We include an altivec unavailable exception vector even if + * not configured for Altivec, so that you can't panic a + * non-altivec kernel running on a machine with altivec just + * by executing an altivec instruction. + */ + . = 0xf00 + b Trap_0f + + . = 0xf20 + b AltiVecUnavailable + +Trap_0f: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0xf00, UnknownException) + +/* + * Handle TLB miss for instruction on 603/603e. + * Note: we get an alternate set of r0 - r3 to use automatically. + */ + . = 0x1000 +InstructionTLBMiss: +/* + * r0: stored ctr + * r1: linux style pte ( later becomes ppc hardware pte ) + * r2: ptr to linux-style pte + * r3: scratch + */ + mfctr r0 + /* Get PTE (linux-style) and check access */ + mfspr r3,SPRN_IMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 + mfspr r2,SPRN_SPRG3 + li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */ + lwz r2,PGDIR(r2) + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ +112: tophys(r2,r2) + rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ + lwz r2,0(r2) /* get pmd entry */ + rlwinm. r2,r2,0,0,19 /* extract address of pte page */ + beq- InstructionAddressInvalid /* return if no mapping */ + rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ + bne- InstructionAddressInvalid /* return if access not permitted */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed bit) */ + /* Convert linux-style PTE to low word of PPC-style PTE */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_IMISS + tlbli r3 + mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r3 + rfi +InstructionAddressInvalid: + mfspr r3,SPRN_SRR1 + rlwinm r1,r3,9,6,6 /* Get load/store bit */ + + addis r1,r1,0x2000 + mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */ + mtctr r0 /* Restore CTR */ + andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ + or r2,r2,r1 + mtspr SPRN_SRR1,r2 + mfspr r1,SPRN_IMISS /* Get failing address */ + rlwinm. r2,r2,0,31,31 /* Check for little endian access */ + rlwimi r2,r2,1,30,30 /* change 1 -> 3 */ + xor r1,r1,r2 + mtspr SPRN_DAR,r1 /* Set fault address */ + mfmsr r0 /* Restore "normal" registers */ + xoris r0,r0,MSR_TGPR>>16 + mtcrf 0x80,r3 /* Restore CR0 */ + mtmsr r0 + b InstructionAccess + +/* + * Handle TLB miss for DATA Load operation on 603/603e + */ + . = 0x1100 +DataLoadTLBMiss: +/* + * r0: stored ctr + * r1: linux style pte ( later becomes ppc hardware pte ) + * r2: ptr to linux-style pte + * r3: scratch + */ + mfctr r0 + /* Get PTE (linux-style) and check access */ + mfspr r3,SPRN_DMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 + mfspr r2,SPRN_SPRG3 + li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */ + lwz r2,PGDIR(r2) + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ +112: tophys(r2,r2) + rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ + lwz r2,0(r2) /* get pmd entry */ + rlwinm. r2,r2,0,0,19 /* extract address of pte page */ + beq- DataAddressInvalid /* return if no mapping */ + rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ + bne- DataAddressInvalid /* return if access not permitted */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed bit) */ + /* Convert linux-style PTE to low word of PPC-style PTE */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_DMISS + tlbld r3 + mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r3 + rfi +DataAddressInvalid: + mfspr r3,SPRN_SRR1 + rlwinm r1,r3,9,6,6 /* Get load/store bit */ + addis r1,r1,0x2000 + mtspr SPRN_DSISR,r1 + mtctr r0 /* Restore CTR */ + andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ + mtspr SPRN_SRR1,r2 + mfspr r1,SPRN_DMISS /* Get failing address */ + rlwinm. r2,r2,0,31,31 /* Check for little endian access */ + beq 20f /* Jump if big endian */ + xori r1,r1,3 +20: mtspr SPRN_DAR,r1 /* Set fault address */ + mfmsr r0 /* Restore "normal" registers */ + xoris r0,r0,MSR_TGPR>>16 + mtcrf 0x80,r3 /* Restore CR0 */ + mtmsr r0 + b DataAccess + +/* + * Handle TLB miss for DATA Store on 603/603e + */ + . = 0x1200 +DataStoreTLBMiss: +/* + * r0: stored ctr + * r1: linux style pte ( later becomes ppc hardware pte ) + * r2: ptr to linux-style pte + * r3: scratch + */ + mfctr r0 + /* Get PTE (linux-style) and check access */ + mfspr r3,SPRN_DMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 + mfspr r2,SPRN_SPRG3 + li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */ + lwz r2,PGDIR(r2) + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ +112: tophys(r2,r2) + rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ + lwz r2,0(r2) /* get pmd entry */ + rlwinm. r2,r2,0,0,19 /* extract address of pte page */ + beq- DataAddressInvalid /* return if no mapping */ + rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ + bne- DataAddressInvalid /* return if access not permitted */ + ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed/dirty bits) */ + /* Convert linux-style PTE to low word of PPC-style PTE */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + li r1,0xe15 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? 2: 0 */ + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_DMISS + tlbld r3 + mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r3 + rfi + +#ifndef CONFIG_ALTIVEC +#define AltivecAssistException UnknownException +#endif + + EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE) + EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) +#ifdef CONFIG_POWER4 + EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) +#else /* !CONFIG_POWER4 */ + EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) + EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) +#endif /* CONFIG_POWER4 */ + EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE) + EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE) + + .globl mol_trampoline + .set mol_trampoline, i0x2f00 + + . = 0x3000 + +AltiVecUnavailable: + EXCEPTION_PROLOG +#ifdef CONFIG_ALTIVEC + bne load_up_altivec /* if from user, just load it up */ +#endif /* CONFIG_ALTIVEC */ + EXC_XFER_EE_LITE(0xf20, AltivecUnavailException) + +#ifdef CONFIG_PPC64BRIDGE +DataAccess: + EXCEPTION_PROLOG + b DataAccessCont + +InstructionAccess: + EXCEPTION_PROLOG + b InstructionAccessCont + +DataSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + EXC_XFER_STD(0x380, UnknownException) + +InstructionSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x480, UnknownException) +#endif /* CONFIG_PPC64BRIDGE */ + +#ifdef CONFIG_ALTIVEC +/* Note that the AltiVec support is closely modeled after the FP + * support. Changes to one are likely to be applicable to the + * other! */ +load_up_altivec: +/* + * Disable AltiVec for the task which had AltiVec previously, + * and save its AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + * On SMP we know the AltiVec units are free, since we give it up every + * switch. -- Kumar + */ + mfmsr r5 + oris r5,r5,MSR_VEC@h + MTMSRD(r5) /* enable use of AltiVec now */ + isync +/* + * For SMP, we don't do lazy AltiVec switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altivec in switch_to. + */ +#ifndef CONFIG_SMP + tophys(r6,0) + addis r3,r6,last_task_used_altivec@ha + lwz r4,last_task_used_altivec@l(r3) + cmpwi 0,r4,0 + beq 1f + add r4,r4,r6 + addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */ + SAVE_32VRS(0,r10,r4) + mfvscr vr0 + li r10,THREAD_VSCR + stvx vr0,r10,r4 + lwz r5,PT_REGS(r4) + add r5,r5,r6 + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r10,MSR_VEC@h + andc r4,r4,r10 /* disable altivec for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of AltiVec after return */ + oris r9,r9,MSR_VEC@h + mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ + li r4,1 + li r10,THREAD_VSCR + stw r4,THREAD_USED_VR(r5) + lvx vr0,r10,r5 + mtvscr vr0 + REST_32VRS(0,r10,r5) +#ifndef CONFIG_SMP + subi r4,r5,THREAD + sub r4,r4,r6 + stw r4,last_task_used_altivec@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + /* we haven't used ctr or xer or lr */ + b fast_exception_return + +/* + * AltiVec unavailable trap from kernel - print a message, but let + * the task use AltiVec in the kernel until it returns to user mode. + */ +KernelAltiVec: + lwz r3,_MSR(r1) + oris r3,r3,MSR_VEC@h + stw r3,_MSR(r1) /* enable use of AltiVec after return */ + lis r3,87f@h + ori r3,r3,87f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +87: .string "AltiVec used in kernel (task=%p, pc=%x) \n" + .align 4,0 + +/* + * giveup_altivec(tsk) + * Disable AltiVec for the task given as the argument, + * and save the AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + */ + + .globl giveup_altivec +giveup_altivec: + mfmsr r5 + oris r5,r5,MSR_VEC@h + SYNC + MTMSRD(r5) /* enable use of AltiVec now */ + isync + cmpwi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpwi 0,r5,0 + SAVE_32VRS(0, r4, r3) + mfvscr vr0 + li r4,THREAD_VSCR + stvx vr0,r4,r3 + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC@h + andc r4,r4,r3 /* disable AltiVec for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_altivec@ha + stw r5,last_task_used_altivec@l(r4) +#endif /* CONFIG_SMP */ + blr +#endif /* CONFIG_ALTIVEC */ + +/* + * This code is jumped to from the startup code to copy + * the kernel image to physical address 0. + */ +relocate_kernel: + addis r9,r26,klimit@ha /* fetch klimit */ + lwz r25,klimit@l(r9) + addis r25,r25,-KERNELBASE@h + li r3,0 /* Destination base address */ + li r6,0 /* Destination offset */ + li r5,0x4000 /* # bytes of memory to copy */ + bl copy_and_flush /* copy the first 0x4000 bytes */ + addi r0,r3,4f@l /* jump to the address of 4f */ + mtctr r0 /* in copy and do the rest. */ + bctr /* jump to the copy */ +4: mr r5,r25 + bl copy_and_flush /* copy the rest */ + b turn_on_mmu + +/* + * Copy routine used to copy the kernel to start at physical address 0 + * and flush and invalidate the caches as needed. + * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset + * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. + */ +copy_and_flush: + addi r5,r5,-4 + addi r6,r6,-4 +4: li r0,L1_CACHE_LINE_SIZE/4 + mtctr r0 +3: addi r6,r6,4 /* copy a cache line */ + lwzx r0,r6,r4 + stwx r0,r6,r3 + bdnz 3b + dcbst r6,r3 /* write it to memory */ + sync + icbi r6,r3 /* flush the icache line */ + cmplw 0,r6,r5 + blt 4b + sync /* additional sync needed on g4 */ + isync + addi r5,r5,4 + addi r6,r6,4 + blr + +#ifdef CONFIG_APUS +/* + * On APUS the physical base address of the kernel is not known at compile + * time, which means the __pa/__va constants used are incorrect. In the + * __init section is recorded the virtual addresses of instructions using + * these constants, so all that has to be done is fix these before + * continuing the kernel boot. + * + * r4 = The physical address of the kernel base. + */ +fix_mem_constants: + mr r10,r4 + addis r10,r10,-KERNELBASE@h /* virt_to_phys constant */ + neg r11,r10 /* phys_to_virt constant */ + + lis r12,__vtop_table_begin@h + ori r12,r12,__vtop_table_begin@l + add r12,r12,r10 /* table begin phys address */ + lis r13,__vtop_table_end@h + ori r13,r13,__vtop_table_end@l + add r13,r13,r10 /* table end phys address */ + subi r12,r12,4 + subi r13,r13,4 +1: lwzu r14,4(r12) /* virt address of instruction */ + add r14,r14,r10 /* phys address of instruction */ + lwz r15,0(r14) /* instruction, now insert top */ + rlwimi r15,r10,16,16,31 /* half of vp const in low half */ + stw r15,0(r14) /* of instruction and restore. */ + dcbst r0,r14 /* write it to memory */ + sync + icbi r0,r14 /* flush the icache line */ + cmpw r12,r13 + bne 1b + sync /* additional sync needed on g4 */ + isync + +/* + * Map the memory where the exception handlers will + * be copied to when hash constants have been patched. + */ +#ifdef CONFIG_APUS_FAST_EXCEPT + lis r8,0xfff0 +#else + lis r8,0 +#endif + ori r8,r8,0x2 /* 128KB, supervisor */ + mtspr SPRN_DBAT3U,r8 + mtspr SPRN_DBAT3L,r8 + + lis r12,__ptov_table_begin@h + ori r12,r12,__ptov_table_begin@l + add r12,r12,r10 /* table begin phys address */ + lis r13,__ptov_table_end@h + ori r13,r13,__ptov_table_end@l + add r13,r13,r10 /* table end phys address */ + subi r12,r12,4 + subi r13,r13,4 +1: lwzu r14,4(r12) /* virt address of instruction */ + add r14,r14,r10 /* phys address of instruction */ + lwz r15,0(r14) /* instruction, now insert top */ + rlwimi r15,r11,16,16,31 /* half of pv const in low half*/ + stw r15,0(r14) /* of instruction and restore. */ + dcbst r0,r14 /* write it to memory */ + sync + icbi r0,r14 /* flush the icache line */ + cmpw r12,r13 + bne 1b + + sync /* additional sync needed on g4 */ + isync /* No speculative loading until now */ + blr + +/*********************************************************************** + * Please note that on APUS the exception handlers are located at the + * physical address 0xfff0000. For this reason, the exception handlers + * cannot use relative branches to access the code below. + ***********************************************************************/ +#endif /* CONFIG_APUS */ + +#ifdef CONFIG_SMP +#ifdef CONFIG_GEMINI + .globl __secondary_start_gemini +__secondary_start_gemini: + mfspr r4,SPRN_HID0 + ori r4,r4,HID0_ICFI + li r3,0 + ori r3,r3,HID0_ICE + andc r4,r4,r3 + mtspr SPRN_HID0,r4 + sync + b __secondary_start +#endif /* CONFIG_GEMINI */ + + .globl __secondary_start_pmac_0 +__secondary_start_pmac_0: + /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ + li r24,0 + b 1f + li r24,1 + b 1f + li r24,2 + b 1f + li r24,3 +1: + /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0 + set to map the 0xf0000000 - 0xffffffff region */ + mfmsr r0 + rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ + SYNC + mtmsr r0 + isync + + .globl __secondary_start +__secondary_start: +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + SYNC + MTMSRD(r0) + isync +#endif + /* Copy some CPU settings from CPU 0 */ + bl __restore_cpu_setup + + lis r3,-KERNELBASE@h + mr r4,r24 + bl identify_cpu + bl call_setup_cpu /* Call setup_cpu for this CPU */ +#ifdef CONFIG_6xx + lis r3,-KERNELBASE@h + bl init_idle_6xx +#endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + lis r3,-KERNELBASE@h + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ + + /* get current_thread_info and current */ + lis r1,secondary_ti@ha + tophys(r1,r1) + lwz r1,secondary_ti@l(r1) + tophys(r2,r1) + lwz r2,TI_TASK(r2) + + /* stack */ + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + li r0,0 + tophys(r3,r1) + stw r0,0(r3) + + /* load up the MMU */ + bl load_up_mmu + + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* phys address of our thread_struct */ + CLR_TOP32(r4) + mtspr SPRN_SPRG3,r4 + li r3,0 + mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */ + + /* enable MMU and jump to start_secondary */ + li r4,MSR_KERNEL + FIX_SRR1(r4,r5) + lis r3,start_secondary@h + ori r3,r3,start_secondary@l + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 + SYNC + RFI +#endif /* CONFIG_SMP */ + +/* + * Those generic dummy functions are kept for CPUs not + * included in CONFIG_6xx + */ +_GLOBAL(__setup_cpu_power3) + blr +_GLOBAL(__setup_cpu_generic) + blr + +#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) +_GLOBAL(__save_cpu_setup) + blr +_GLOBAL(__restore_cpu_setup) + blr +#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */ + + +/* + * Load stuff into the MMU. Intended to be called with + * IR=0 and DR=0. + */ +load_up_mmu: + sync /* Force all PTE updates to finish */ + isync + tlbia /* Clear all TLB entries */ + sync /* wait for tlbia/tlbie to finish */ + TLBSYNC /* ... on all CPUs */ + /* Load the SDR1 register (hash table base & size) */ + lis r6,_SDR1@ha + tophys(r6,r6) + lwz r6,_SDR1@l(r6) + mtspr SPRN_SDR1,r6 +#ifdef CONFIG_PPC64BRIDGE + /* clear the ASR so we only use the pseudo-segment registers. */ + li r6,0 + mtasr r6 +#endif /* CONFIG_PPC64BRIDGE */ + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b +#ifndef CONFIG_POWER4 +/* Load the BAT registers with the values set up by MMU_init. + MMU_init takes care of whether we're on a 601 or not. */ + mfpvr r3 + srwi r3,r3,16 + cmpwi r3,1 + lis r3,BATS@ha + addi r3,r3,BATS@l + tophys(r3,r3) + LOAD_BAT(0,r3,r4,r5) + LOAD_BAT(1,r3,r4,r5) + LOAD_BAT(2,r3,r4,r5) + LOAD_BAT(3,r3,r4,r5) +#endif /* CONFIG_POWER4 */ + blr + +/* + * This is where the main kernel code starts. + */ +start_here: + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + /* Set up for using our exception vectors */ + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* init task's THREAD */ + CLR_TOP32(r4) + mtspr SPRN_SPRG3,r4 + li r3,0 + mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */ + + /* stack */ + lis r1,init_thread_union@ha + addi r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) +/* + * Do early bootinfo parsing, platform-specific initialization, + * and set up the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + +#ifdef CONFIG_APUS + /* Copy exception code to exception vector base on APUS. */ + lis r4,KERNELBASE@h +#ifdef CONFIG_APUS_FAST_EXCEPT + lis r3,0xfff0 /* Copy to 0xfff00000 */ +#else + lis r3,0 /* Copy to 0x00000000 */ +#endif + li r5,0x4000 /* # bytes of memory to copy */ + li r6,0 + bl copy_and_flush /* copy the first 0x4000 bytes */ +#endif /* CONFIG_APUS */ + +/* + * Go back to running unmapped so we can load up new values + * for SDR1 (hash table pointer) and the segment registers + * and change to using our exception vectors. + */ + lis r4,2f@h + ori r4,r4,2f@l + tophys(r4,r4) + li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) + FIX_SRR1(r3,r5) + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + SYNC + RFI +/* Load up the kernel context */ +2: bl load_up_mmu + +#ifdef CONFIG_BDI_SWITCH + /* Add helper information for the Abatron bdiGDB debugger. + * We do this here because we know the mmu is disabled, and + * will be enabled for real in just a few instructions. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* This much match your Abatron config */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + tophys(r5, r5) + stw r6, 0(r5) +#endif /* CONFIG_BDI_SWITCH */ + +/* Now turn on the MMU for real! */ + li r4,MSR_KERNEL + FIX_SRR1(r4,r5) + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 + SYNC + RFI + +/* + * Set up the segment registers for a new context. + */ +_GLOBAL(set_context) + mulli r3,r3,897 /* multiply context by skew factor */ + rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ + addis r3,r3,0x6000 /* Set Ks, Ku bits */ + li r0,NUM_USER_SEGMENTS + mtctr r0 + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is passed as second argument. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif + li r4,0 + isync +3: +#ifdef CONFIG_PPC64BRIDGE + slbie r4 +#endif /* CONFIG_PPC64BRIDGE */ + mtsrin r3,r4 + addi r3,r3,0x111 /* next VSID */ + rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + sync + isync + blr + +/* + * An undocumented "feature" of 604e requires that the v bit + * be cleared before changing BAT values. + * + * Also, newer IBM firmware does not clear bat3 and 4 so + * this makes sure it's done. + * -- Cort + */ +clear_bats: + li r10,0 + mfspr r9,SPRN_PVR + rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ + cmpwi r9, 1 + beq 1f + + mtspr SPRN_DBAT0U,r10 + mtspr SPRN_DBAT0L,r10 + mtspr SPRN_DBAT1U,r10 + mtspr SPRN_DBAT1L,r10 + mtspr SPRN_DBAT2U,r10 + mtspr SPRN_DBAT2L,r10 + mtspr SPRN_DBAT3U,r10 + mtspr SPRN_DBAT3L,r10 +1: + mtspr SPRN_IBAT0U,r10 + mtspr SPRN_IBAT0L,r10 + mtspr SPRN_IBAT1U,r10 + mtspr SPRN_IBAT1L,r10 + mtspr SPRN_IBAT2U,r10 + mtspr SPRN_IBAT2L,r10 + mtspr SPRN_IBAT3U,r10 + mtspr SPRN_IBAT3L,r10 +BEGIN_FTR_SECTION + /* Here's a tweak: at this point, CPU setup have + * not been called yet, so HIGH_BAT_EN may not be + * set in HID0 for the 745x processors. However, it + * seems that doesn't affect our ability to actually + * write to these SPRs. + */ + mtspr SPRN_DBAT4U,r10 + mtspr SPRN_DBAT4L,r10 + mtspr SPRN_DBAT5U,r10 + mtspr SPRN_DBAT5L,r10 + mtspr SPRN_DBAT6U,r10 + mtspr SPRN_DBAT6L,r10 + mtspr SPRN_DBAT7U,r10 + mtspr SPRN_DBAT7L,r10 + mtspr SPRN_IBAT4U,r10 + mtspr SPRN_IBAT4L,r10 + mtspr SPRN_IBAT5U,r10 + mtspr SPRN_IBAT5L,r10 + mtspr SPRN_IBAT6U,r10 + mtspr SPRN_IBAT6L,r10 + mtspr SPRN_IBAT7U,r10 + mtspr SPRN_IBAT7L,r10 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) + blr + +flush_tlbs: + lis r10, 0x40 +1: addic. r10, r10, -0x1000 + tlbie r10 + blt 1b + sync + blr + +mmu_off: + addi r4, r3, __after_mmu_off - _start + mfmsr r3 + andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */ + beqlr + andc r3,r3,r0 + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + sync + RFI + +#ifndef CONFIG_POWER4 +/* + * Use the first pair of BAT registers to map the 1st 16MB + * of RAM to KERNELBASE. From this point on we can't safely + * call OF any more. + */ +initial_bats: + lis r11,KERNELBASE@h +#ifndef CONFIG_PPC64BRIDGE + mfspr r9,SPRN_PVR + rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ + cmpwi 0,r9,1 + bne 4f + ori r11,r11,4 /* set up BAT registers for 601 */ + li r8,0x7f /* valid, block length = 8MB */ + oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */ + oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */ + mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ + mtspr SPRN_IBAT0L,r8 /* lower BAT register */ + mtspr SPRN_IBAT1U,r9 + mtspr SPRN_IBAT1L,r10 + isync + blr +#endif /* CONFIG_PPC64BRIDGE */ + +4: tophys(r8,r11) +#ifdef CONFIG_SMP + ori r8,r8,0x12 /* R/W access, M=1 */ +#else + ori r8,r8,2 /* R/W access */ +#endif /* CONFIG_SMP */ +#ifdef CONFIG_APUS + ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */ +#else + ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ +#endif /* CONFIG_APUS */ + +#ifdef CONFIG_PPC64BRIDGE + /* clear out the high 32 bits in the BAT */ + clrldi r11,r11,32 + clrldi r8,r8,32 +#endif /* CONFIG_PPC64BRIDGE */ + mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ + mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ + mtspr SPRN_IBAT0L,r8 + mtspr SPRN_IBAT0U,r11 + isync + blr + +#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) +setup_disp_bat: + /* + * setup the display bat prepared for us in prom.c + */ + mflr r8 + bl reloc_offset + mtlr r8 + addis r8,r3,disp_BAT@ha + addi r8,r8,disp_BAT@l + lwz r11,0(r8) + lwz r8,4(r8) + mfspr r9,SPRN_PVR + rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ + cmpwi 0,r9,1 + beq 1f + mtspr SPRN_DBAT3L,r8 + mtspr SPRN_DBAT3U,r11 + blr +1: mtspr SPRN_IBAT3L,r8 + mtspr SPRN_IBAT3U,r11 + blr + +#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ + +#else /* CONFIG_POWER4 */ +/* + * Load up the SDR1 and segment register values now + * since we don't have the BATs. + * Also make sure we are running in 32-bit mode. + */ + +initial_mm_power4: + addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ + lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ + mtspr SPRN_SDR1,r14 + slbia + lis r4,0x2000 /* set pseudo-segment reg 12 */ + ori r5,r4,0x0ccc + mtsr 12,r5 +#if 0 + ori r5,r4,0x0888 /* set pseudo-segment reg 8 */ + mtsr 8,r5 /* (for access to serial port) */ +#endif +#ifdef CONFIG_BOOTX_TEXT + ori r5,r4,0x0999 /* set pseudo-segment reg 9 */ + mtsr 9,r5 /* (for access to screen) */ +#endif + mfmsr r0 + clrldi r0,r0,1 + sync + mtmsr r0 + isync + blr + +#endif /* CONFIG_POWER4 */ + +#ifdef CONFIG_8260 +/* Jump into the system reset for the rom. + * We first disable the MMU, and then jump to the ROM reset address. + * + * r3 is the board info structure, r4 is the location for starting. + * I use this for building a small kernel that can load other kernels, + * rather than trying to write or rely on a rom monitor that can tftp load. + */ + .globl m8260_gorom +m8260_gorom: + mfmsr r0 + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync + mtmsr r0 + sync + mfspr r11, SPRN_HID0 + lis r10, 0 + ori r10,r10,HID0_ICE|HID0_DCE + andc r11, r11, r10 + mtspr SPRN_HID0, r11 + isync + li r5, MSR_ME|MSR_RI + lis r6,2f@h + addis r6,r6,-KERNELBASE@h + ori r6,r6,2f@l + mtspr SPRN_SRR0,r6 + mtspr SPRN_SRR1,r5 + isync + sync + rfi +2: + mtlr r4 + blr +#endif + + +/* + * We put a few things here that have to be page-aligned. + * This stuff goes at the beginning of the data segment, + * which is page-aligned. + */ + .data + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: + .space 4096 + + .globl swapper_pg_dir +swapper_pg_dir: + .space 4096 + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * Used to pass parameters into the kernel like root=/dev/sda1, etc. + */ + .globl cmd_line +cmd_line: + .space 512 + + .globl intercept_table +intercept_table: + .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700 + .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0 + .long 0, 0, 0, i0x1300, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + +/* Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S new file mode 100644 index 000000000000..599245b0407e --- /dev/null +++ b/arch/powerpc/kernel/head_44x.S @@ -0,0 +1,778 @@ +/* + * arch/ppc/kernel/head_44x.S + * + * Kernel execution entry point code. + * + * Copyright (c) 1995-1996 Gary Thomas + * Initial PowerPC version. + * Copyright (c) 1996 Cort Dougan + * Rewritten for PReP + * Copyright (c) 1996 Paul Mackerras + * Low-level exception handers, MMU support, and rewrite. + * Copyright (c) 1997 Dan Malek + * PowerPC 8xx modifications. + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson + * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * Copyright 2002-2005 MontaVista Software, Inc. + * PowerPC 44x support, Matt Porter + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "head_booke.h" + + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=128") + * r7 - End of kernel command line string + * + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + /* + * Reserve a word at a fixed location to store the address + * of abatron_pteptrs + */ + nop +/* + * Save parameters we are passed + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* CPU number */ + +/* + * Set up the initial MMU state + * + * We are still executing code at the virtual address + * mappings set by the firmware for the base of RAM. + * + * We first invalidate all TLB entries but the one + * we are running from. We then load the KERNELBASE + * mappings so we can begin to use kernel addresses + * natively and so the interrupt vector locations are + * permanently pinned (necessary since Book E + * implementations always have translation enabled). + * + * TODO: Use the known TLB entry we are running from to + * determine which physical region we are located + * in. This can be used to determine where in RAM + * (on a shared CPU system) or PCI memory space + * (on a DRAMless system) we are located. + * For now, we assume a perfect world which means + * we are located at the base of DRAM (physical 0). + */ + +/* + * Search TLB for entry that we are currently using. + * Invalidate all entries but the one we are using. + */ + /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ + mfspr r3,SPRN_PID /* Get PID */ + mfmsr r4 /* Get MSR */ + andi. r4,r4,MSR_IS@l /* TS=1? */ + beq wmmucr /* If not, leave STS=0 */ + oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ +wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ + sync + + bl invstr /* Find our address */ +invstr: mflr r5 /* Make it accessible */ + tlbsx r23,0,r5 /* Find entry we are in */ + li r4,0 /* Start at TLB entry 0 */ + li r3,0 /* Set PAGEID inval value */ +1: cmpw r23,r4 /* Is this our entry? */ + beq skpinv /* If so, skip the inval */ + tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ +skpinv: addi r4,r4,1 /* Increment */ + cmpwi r4,64 /* Are we done? */ + bne 1b /* If not, repeat */ + isync /* If so, context change */ + +/* + * Configure and load pinned entry into TLB slot 63. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + + /* Kernel is at the base of RAM */ + li r4, 0 /* Load the kernel physical address */ + + /* Load the kernel PID = 0 */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Initialize MMUCR */ + li r5,0 + mtspr SPRN_MMUCR,r5 + sync + + /* pageid fields */ + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M + + /* xlat fields */ + clrrwi r4,r4,10 /* Mask off the real page number */ + /* ERPN is 0 for first 4GB page */ + + /* attrib fields */ + /* Added guarded bit to protect against speculative loads/stores */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) + + li r0,63 /* TLB slot 63 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + /* Force context change */ + mfmsr r0 + mtspr SPRN_SRR1, r0 + lis r0,3f@h + ori r0,r0,3f@l + mtspr SPRN_SRR0,r0 + sync + rfi + + /* If necessary, invalidate original entry we used */ +3: cmpwi r23,63 + beq 4f + li r6,0 + tlbwe r6,r23,PPC44x_TLB_PAGEID + isync + +4: +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* + * Add temporary UART mapping for early debug. + * We can map UART registers wherever we want as long as they don't + * interfere with other system mappings (e.g. with pinned entries). + * For an example of how we handle this - see ocotea.h. --ebs + */ + /* pageid fields */ + lis r3,UART0_IO_BASE@h + ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K + + /* xlat fields */ + lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ +#ifndef CONFIG_440EP + ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ +#endif + + /* attrib fields */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) + + li r0,0 /* TLB slot 0 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + /* Force context change */ + isync +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, Debug); + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + +#ifdef CONFIG_440EP + /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */ + mfspr r2,SPRN_CCR0 + lis r3,0xffef + ori r3,r3,0xffff + and r2,r2,r3 + mtspr SPRN_CCR0,r2 + isync +#endif + + /* + * This is where the main kernel code starts. + */ + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to current thread */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRN_SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@h + ori r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + + /* Setup PTE pointers for the Abatron bdiGDB */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + lis r4, KERNELBASE@h + ori r4, r4, KERNELBASE@l + stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ + stw r6, 0(r5) + + /* Let's move on */ + lis r4,start_kernel@h + ori r4,r4,start_kernel@l + lis r3,MSR_KERNEL@h + ori r3,r3,MSR_KERNEL@l + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + rfi /* change context and jump to start_kernel */ + +/* + * Interrupt vector entry code + * + * The Book E MMUs are always on so we don't need to handle + * interrupts in real mode as with previous PPC processors. In + * this case we handle interrupts in the kernel virtual address + * space. + * + * Interrupt vectors are dynamically placed relative to the + * interrupt prefix as determined by the address of interrupt_base. + * The interrupt vectors offsets are programmed using the labels + * for each interrupt vector entry. + * + * Interrupt vectors must be aligned on a 16 byte boundary. + * We align on a 32 byte cache line boundary for good measure. + */ + +interrupt_base: + /* Critical Input Interrupt */ + CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + + /* Machine Check Interrupt */ +#ifdef CONFIG_440A + MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +#else + CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +#endif + + /* Data Storage Interrupt */ + START_EXCEPTION(DataStorage) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + + /* + * Check if it was a store fault, if not then bail + * because a user tried to access a kernel or + * read-protected page. Otherwise, get the + * offending address and handle it. + */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_ST@h + beq 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR + rlwinm r12,r12,0,0,23 /* Clear TID */ + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + mfspr r12,SPRN_MMUCR /* Get MMUCR */ + mfspr r13,SPRN_PID /* Get PID */ + rlwimi r12,r13,0,24,31 /* Set TID */ + +4: + mtspr SPRN_MMUCR,r12 + + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + + andi. r13, r11, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, 4(r12) /* Update Linux page table */ + + li r13, PPC44x_TLB_SR@l /* Set SR */ + rlwimi r13, r11, 29, 29, 29 /* SX = _PAGE_HWEXEC */ + rlwimi r13, r11, 0, 30, 30 /* SW = _PAGE_RW */ + rlwimi r13, r11, 29, 28, 28 /* UR = _PAGE_USER */ + rlwimi r12, r11, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */ + rlwimi r12, r11, 29, 30, 30 /* (_PAGE_USER>>3)->r12 */ + and r12, r12, r11 /* HWEXEC/RW & USER */ + rlwimi r13, r12, 0, 26, 26 /* UX = HWEXEC & USER */ + rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */ + + rlwimi r11,r13,0,26,31 /* Insert static perms */ + + rlwinm r11,r11,0,20,15 /* Clear U0-U3 */ + + /* find the TLB index that caused the fault. It has to be here. */ + tlbsx r10, 0, r10 + + tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + rfi /* Force context change */ + +2: + /* + * The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b data_access + + /* Instruction Storage Interrupt */ + INSTRUCTION_STORAGE_EXCEPTION + + /* External Input Interrupt */ + EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) + + /* Alignment Interrupt */ + ALIGNMENT_EXCEPTION + + /* Program Interrupt */ + PROGRAM_EXCEPTION + + /* Floating Point Unavailable Interrupt */ +#ifdef CONFIG_PPC_FPU + FP_UNAVAILABLE_EXCEPTION +#else + EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) +#endif + + /* System Call Interrupt */ + START_EXCEPTION(SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0x0c00, DoSyscall) + + /* Auxillary Processor Unavailable Interrupt */ + EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + + /* Decrementer Interrupt */ + DECREMENTER_EXCEPTION + + /* Fixed Internal Timer Interrupt */ + /* TODO: Add FIT support */ + EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + + /* Watchdog Timer Interrupt */ + /* TODO: Add watchdog support */ +#ifdef CONFIG_BOOKE_WDT + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) +#else + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) +#endif + + /* Data TLB Error Interrupt */ + START_EXCEPTION(DataTLBError) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR + rlwinm r12,r12,0,0,23 /* Clear TID */ + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + mfspr r12,SPRN_MMUCR + mfspr r13,SPRN_PID /* Get PID */ + rlwimi r12,r13,0,24,31 /* Set TID */ + +4: + mtspr SPRN_MMUCR,r12 + + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common tlb load */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b data_access + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + mfspr r10, SPRN_SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR + rlwinm r12,r12,0,0,23 /* Clear TID */ + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + mfspr r12,SPRN_MMUCR + mfspr r13,SPRN_PID /* Get PID */ + rlwimi r12,r13,0,24,31 /* Set TID */ + +4: + mtspr SPRN_MMUCR,r12 + + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common TLB load point */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b InstructionStorage + + /* Debug Interrupt */ + DEBUG_EXCEPTION + +/* + * Local functions + */ + /* + * Data TLB exceptions will bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +data_access: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + EXC_XFER_EE_LITE(0x0300, handle_page_fault) + +/* + + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - EA of fault + * r11 - available to use + * r12 - Pointer to the 64-bit PTE + * r13 - available to use + * MMUCR - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load: + /* + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + + /* Load the next available TLB index */ + lis r13, tlb_44x_index@ha + lwz r13, tlb_44x_index@l(r13) + /* Load the TLB high watermark */ + lis r11, tlb_44x_hwater@ha + lwz r11, tlb_44x_hwater@l(r11) + + /* Increment, rollover, and store TLB index */ + addi r13, r13, 1 + cmpw 0, r13, r11 /* reserve entries */ + ble 7f + li r13, 0 +7: + /* Store the next available TLB index */ + lis r11, tlb_44x_index@ha + stw r13, tlb_44x_index@l(r11) + + lwz r11, 0(r12) /* Get MS word of PTE */ + lwz r12, 4(r12) /* Get LS word of PTE */ + rlwimi r11, r12, 0, 0 , 19 /* Insert RPN */ + tlbwe r11, r13, PPC44x_TLB_XLAT /* Write XLAT */ + + /* + * Create PAGEID. This is the faulting address, + * page size, and valid flag. + */ + li r11, PPC44x_TLB_VALID | PPC44x_TLB_4K + rlwimi r10, r11, 0, 20, 31 /* Insert valid and page size */ + tlbwe r10, r13, PPC44x_TLB_PAGEID /* Write PAGEID */ + + li r10, PPC44x_TLB_SR@l /* Set SR */ + rlwimi r10, r12, 0, 30, 30 /* Set SW = _PAGE_RW */ + rlwimi r10, r12, 29, 29, 29 /* SX = _PAGE_HWEXEC */ + rlwimi r10, r12, 29, 28, 28 /* UR = _PAGE_USER */ + rlwimi r11, r12, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */ + and r11, r12, r11 /* HWEXEC & USER */ + rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */ + + rlwimi r12, r10, 0, 26, 31 /* Insert static perms */ + rlwinm r12, r12, 0, 20, 15 /* Clear U0-U3 */ + tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + rfi /* Force context change */ + +/* + * Global functions + */ + +/* + * extern void giveup_altivec(struct task_struct *prev) + * + * The 44x core does not have an AltiVec unit. + */ +_GLOBAL(giveup_altivec) + blr + +/* + * extern void giveup_fpu(struct task_struct *prev) + * + * The 44x core does not have an FPU. + */ +#ifndef CONFIG_PPC_FPU +_GLOBAL(giveup_fpu) + blr +#endif + +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR0_RST_SYSTEM@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r4, 0x4(r5) +#endif + mtspr SPRN_PID,r3 + isync /* Force context change */ + blr + +/* + * We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 + +/* + * To support >32-bit physical addresses, we use an 8KB pgdir. + */ +_GLOBAL(swapper_pg_dir) + .space 8192 + +/* Reserved 4k for the critical exception stack & 4k for the machine + * check stack per CPU for kernel mode exceptions */ + .section .bss + .align 12 +exception_stack_bottom: + .space BOOKE_EXCEPTION_STACK_SIZE +_GLOBAL(exception_stack_top) + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* + * Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 + + diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S new file mode 100644 index 000000000000..8562b807b37c --- /dev/null +++ b/arch/powerpc/kernel/head_4xx.S @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 1995-1996 Gary Thomas + * Initial PowerPC version. + * Copyright (c) 1996 Cort Dougan + * Rewritten for PReP + * Copyright (c) 1996 Paul Mackerras + * Low-level exception handers, MMU support, and rewrite. + * Copyright (c) 1997 Dan Malek + * PowerPC 8xx modifications. + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson + * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * + * Module name: head_4xx.S + * + * Description: + * Kernel execution entry point code. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=96m") + * r7 - End of kernel command line string + * + * This is all going to change RSN when we add bi_recs....... -- Dan + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + + /* Save parameters we are passed. + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + + /* We have to turn on the MMU right away so we get cache modes + * set correctly. + */ + bl initial_mmu + +/* We now have the lower 16 Meg mapped into TLB entries, and the caches + * ready to work. + */ +turn_on_mmu: + lis r0,MSR_KERNEL@h + ori r0,r0,MSR_KERNEL@l + mtspr SPRN_SRR1,r0 + lis r0,start_here@h + ori r0,r0,start_here@l + mtspr SPRN_SRR0,r0 + SYNC + rfi /* enables MMU */ + b . /* prevent prefetch past rfi */ + +/* + * This area is used for temporarily saving registers during the + * critical exception prolog. + */ + . = 0xc0 +crit_save: +_GLOBAL(crit_r10) + .space 4 +_GLOBAL(crit_r11) + .space 4 + +/* + * Exception vector entry code. This code runs with address translation + * turned off (i.e. using physical addresses). We assume SPRG3 has the + * physical address of the current task thread_struct. + * Note that we have to have decremented r1 before we write to any fields + * of the exception frame, since a critical interrupt could occur at any + * time, and it will write to the area immediately below the current r1. + */ +#define NORMAL_EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ + mtspr SPRN_SPRG1,r11; \ + mtspr SPRN_SPRG2,r1; \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + beq 1f; \ + mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\ + lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ + addi r1,r1,THREAD_SIZE; \ +1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r1); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRN_SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRN_SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r10,SPRN_SPRG2; \ + mfspr r12,SPRN_SRR0; \ + stw r10,GPR1(r11); \ + mfspr r9,SPRN_SRR1; \ + stw r10,0(r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception prolog for critical exceptions. This is a little different + * from the normal exception prolog above since a critical exception + * can potentially occur at any point during normal exception processing. + * Thus we cannot use the same SPRG registers as the normal prolog above. + * Instead we use a couple of words of memory at low physical addresses. + * This is OK since we don't support SMP on these processors. + */ +#define CRITICAL_EXCEPTION_PROLOG \ + stw r10,crit_r10@l(0); /* save two registers to work with */\ + stw r11,crit_r11@l(0); \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_SRR3; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + lis r11,critical_stack_top@h; \ + ori r11,r11,critical_stack_top@l; \ + beq 1f; \ + /* COMING FROM USER MODE */ \ + mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ + lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ + addi r11,r11,THREAD_SIZE; \ +1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r11); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ + stw r12,_DEAR(r11); /* since they may have had stuff */\ + mfspr r9,SPRN_ESR; /* in them at the point where the */\ + stw r9,_ESR(r11); /* exception was taken */\ + mfspr r12,SPRN_SRR2; \ + stw r1,GPR1(r11); \ + mfspr r9,SPRN_SRR3; \ + stw r1,0(r11); \ + tovirt(r1,r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + + /* + * State at this point: + * r9 saved in stack frame, now saved SRR3 & ~MSR_WE + * r10 saved in crit_r10 and in stack frame, trashed + * r11 saved in crit_r11 and in stack frame, + * now phys stack/exception frame pointer + * r12 saved in stack frame, now saved SRR2 + * CR saved in stack frame, CR0.EQ = !SRR3.PR + * LR, DEAR, ESR in stack frame + * r1 saved in stack frame, now virt stack/excframe pointer + * r0, r3-r8 saved in stack frame + */ + +/* + * Exception vectors. + */ +#define START_EXCEPTION(n, label) \ + . = n; \ +label: + +#define EXCEPTION(n, label, hdlr, xfer) \ + START_EXCEPTION(n, label); \ + NORMAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define CRITICAL_EXCEPTION(n, label, hdlr) \ + START_EXCEPTION(n, label); \ + CRITICAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, crit_transfer_to_handler, \ + ret_from_crit_exc) + +#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + lis r10,msr@h; \ + ori r10,r10,msr@l; \ + copyee(r10, r9); \ + bl tfer; \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ + ret_from_except) + + +/* + * 0x0100 - Critical Interrupt Exception + */ + CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) + +/* + * 0x0200 - Machine Check Exception + */ + CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + +/* + * 0x0300 - Data Storage Exception + * This happens for just a few reasons. U0 set (but we don't do that), + * or zone protection fault (user violation, write to protected page). + * If this is just an update of modified status, we do that quickly + * and exit. Otherwise, we call heavywight functions to do the work. + */ + START_EXCEPTION(0x0300, DataStorage) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 +#ifdef CONFIG_403GCX + stw r12, 0(r0) + stw r9, 4(r0) + mfcr r11 + mfspr r12, SPRN_PID + stw r11, 8(r0) + stw r12, 12(r0) +#else + mtspr SPRN_SPRG4, r12 + mtspr SPRN_SPRG5, r9 + mfcr r11 + mfspr r12, SPRN_PID + mtspr SPRN_SPRG7, r11 + mtspr SPRN_SPRG6, r12 +#endif + + /* First, check if it was a zone fault (which means a user + * tried to access a kernel or read-protected page - always + * a SEGV). All other faults here must be stores, so no + * need to check ESR_DST as well. */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_DIZ@h + bne 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + li r9, 0 + mtspr SPRN_PID, r9 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) +4: + tophys(r11, r11) + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r11, 0(r11) /* Get L1 entry */ + rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + + andi. r9, r11, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, 0(r12) /* Update Linux page table */ + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r12, 0x0ce2 + andc r11, r11, r12 /* Make sure 20, 21 are zero */ + + /* find the TLB index that caused the fault. It has to be here. + */ + tlbsx r9, 0, r10 + + tlbwe r11, r9, TLB_DATA /* Load TLB LO */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r12, 12(r0) + lwz r11, 8(r0) + mtspr SPRN_PID, r12 + mtcr r11 + lwz r9, 4(r0) + lwz r12, 0(r0) +#else + mfspr r12, SPRN_SPRG6 + mfspr r11, SPRN_SPRG7 + mtspr SPRN_PID, r12 + mtcr r11 + mfspr r9, SPRN_SPRG5 + mfspr r12, SPRN_SPRG4 +#endif + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + b . /* prevent prefetch past rfi */ + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r12, 12(r0) + lwz r11, 8(r0) + mtspr SPRN_PID, r12 + mtcr r11 + lwz r9, 4(r0) + lwz r12, 0(r0) +#else + mfspr r12, SPRN_SPRG6 + mfspr r11, SPRN_SPRG7 + mtspr SPRN_PID, r12 + mtcr r11 + mfspr r9, SPRN_SPRG5 + mfspr r12, SPRN_SPRG4 +#endif + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b DataAccess + +/* + * 0x0400 - Instruction Storage Exception + * This is caused by a fetch from non-execute or guarded pages. + */ + START_EXCEPTION(0x0400, InstructionAccess) + NORMAL_EXCEPTION_PROLOG + mr r4,r12 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ + EXC_XFER_EE_LITE(0x400, handle_page_fault) + +/* 0x0500 - External Interrupt Exception */ + EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) + +/* 0x0600 - Alignment Exception */ + START_EXCEPTION(0x0600, Alignment) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x600, AlignmentException) + +/* 0x0700 - Program Exception */ + START_EXCEPTION(0x0700, ProgramCheck) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_ESR /* Grab the ESR and save it */ + stw r4,_ESR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x700, ProgramCheckException) + + EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE) + +/* 0x0C00 - System Call Exception */ + START_EXCEPTION(0x0C00, SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0xc00, DoSyscall) + + EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE) + +/* 0x1000 - Programmable Interval Timer (PIT) Exception */ + START_EXCEPTION(0x1000, Decrementer) + NORMAL_EXCEPTION_PROLOG + lis r0,TSR_PIS@h + mtspr SPRN_TSR,r0 /* Clear the PIT exception */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_LITE(0x1000, timer_interrupt) + +#if 0 +/* NOTE: + * FIT and WDT handlers are not implemented yet. + */ + +/* 0x1010 - Fixed Interval Timer (FIT) Exception +*/ + STND_EXCEPTION(0x1010, FITException, UnknownException) + +/* 0x1020 - Watchdog Timer (WDT) Exception +*/ +#ifdef CONFIG_BOOKE_WDT + CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException) +#else + CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException) +#endif +#endif + +/* 0x1100 - Data TLB Miss Exception + * As the name implies, translation is not in the MMU, so search the + * page tables and fix it. The only purpose of this function is to + * load TLB entries from the page table if they exist. + */ + START_EXCEPTION(0x1100, DTLBMiss) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 +#ifdef CONFIG_403GCX + stw r12, 0(r0) + stw r9, 4(r0) + mfcr r11 + mfspr r12, SPRN_PID + stw r11, 8(r0) + stw r12, 12(r0) +#else + mtspr SPRN_SPRG4, r12 + mtspr SPRN_SPRG5, r9 + mfcr r11 + mfspr r12, SPRN_PID + mtspr SPRN_SPRG7, r11 + mtspr SPRN_SPRG6, r12 +#endif + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + li r9, 0 + mtspr SPRN_PID, r9 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) +4: + tophys(r11, r11) + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r12, 0(r11) /* Get L1 entry */ + andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + andi. r9, r11, _PAGE_PRESENT + beq 5f + + ori r11, r11, _PAGE_ACCESSED + stw r11, 0(r12) + + /* Create TLB tag. This is the faulting address plus a static + * set of bits. These are size, valid, E, U0. + */ + li r12, 0x00c0 + rlwimi r10, r12, 0, 20, 31 + + b finish_tlb_load + +2: /* Check for possible large-page pmd entry */ + rlwinm. r9, r12, 2, 22, 24 + beq 5f + + /* Create TLB tag. This is the faulting address, plus a static + * set of bits (valid, E, U0) plus the size from the PMD. + */ + ori r9, r9, 0x40 + rlwimi r10, r9, 0, 20, 31 + mr r11, r12 + + b finish_tlb_load + +5: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r12, 12(r0) + lwz r11, 8(r0) + mtspr SPRN_PID, r12 + mtcr r11 + lwz r9, 4(r0) + lwz r12, 0(r0) +#else + mfspr r12, SPRN_SPRG6 + mfspr r11, SPRN_SPRG7 + mtspr SPRN_PID, r12 + mtcr r11 + mfspr r9, SPRN_SPRG5 + mfspr r12, SPRN_SPRG4 +#endif + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b DataAccess + +/* 0x1200 - Instruction TLB Miss Exception + * Nearly the same as above, except we get our information from different + * registers and bailout to a different point. + */ + START_EXCEPTION(0x1200, ITLBMiss) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 +#ifdef CONFIG_403GCX + stw r12, 0(r0) + stw r9, 4(r0) + mfcr r11 + mfspr r12, SPRN_PID + stw r11, 8(r0) + stw r12, 12(r0) +#else + mtspr SPRN_SPRG4, r12 + mtspr SPRN_SPRG5, r9 + mfcr r11 + mfspr r12, SPRN_PID + mtspr SPRN_SPRG7, r11 + mtspr SPRN_SPRG6, r12 +#endif + mfspr r10, SPRN_SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + li r9, 0 + mtspr SPRN_PID, r9 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) +4: + tophys(r11, r11) + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r12, 0(r11) /* Get L1 entry */ + andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + andi. r9, r11, _PAGE_PRESENT + beq 5f + + ori r11, r11, _PAGE_ACCESSED + stw r11, 0(r12) + + /* Create TLB tag. This is the faulting address plus a static + * set of bits. These are size, valid, E, U0. + */ + li r12, 0x00c0 + rlwimi r10, r12, 0, 20, 31 + + b finish_tlb_load + +2: /* Check for possible large-page pmd entry */ + rlwinm. r9, r12, 2, 22, 24 + beq 5f + + /* Create TLB tag. This is the faulting address, plus a static + * set of bits (valid, E, U0) plus the size from the PMD. + */ + ori r9, r9, 0x40 + rlwimi r10, r9, 0, 20, 31 + mr r11, r12 + + b finish_tlb_load + +5: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r12, 12(r0) + lwz r11, 8(r0) + mtspr SPRN_PID, r12 + mtcr r11 + lwz r9, 4(r0) + lwz r12, 0(r0) +#else + mfspr r12, SPRN_SPRG6 + mfspr r11, SPRN_SPRG7 + mtspr SPRN_PID, r12 + mtcr r11 + mfspr r9, SPRN_SPRG5 + mfspr r12, SPRN_SPRG4 +#endif + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b InstructionAccess + + EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) +#ifdef CONFIG_IBM405_ERR51 + /* 405GP errata 51 */ + START_EXCEPTION(0x1700, Trap_17) + b DTLBMiss +#else + EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) +#endif + EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE) + +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB/DTLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is + * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ + /* 0x2000 - Debug Exception */ + START_EXCEPTION(0x2000, DebugTrap) + CRITICAL_EXCEPTION_PROLOG + + /* + * If this is a single step or branch-taken exception in an + * exception entry sequence, it was probably meant to apply to + * the code where the exception occurred (since exception entry + * doesn't turn off DE automatically). We simulate the effect + * of turning off DE on entry to an exception handler by turning + * off DE in the SRR3 value and clearing the debug status. + */ + mfspr r10,SPRN_DBSR /* check single-step/branch taken */ + andis. r10,r10,DBSR_IC@h + beq+ 2f + + andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */ + beq 1f /* branch and fix it up */ + + mfspr r10,SPRN_SRR2 /* Faulting instruction address */ + cmplwi r10,0x2100 + bgt+ 2f /* address above exception vectors */ + + /* here it looks like we got an inappropriate debug exception. */ +1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */ + lis r10,DBSR_IC@h /* clear the IC event */ + mtspr SPRN_DBSR,r10 + /* restore state and get out */ + lwz r10,_CCR(r11) + lwz r0,GPR0(r11) + lwz r1,GPR1(r11) + mtcrf 0x80,r10 + mtspr SPRN_SRR2,r12 + mtspr SPRN_SRR3,r9 + lwz r9,GPR9(r11) + lwz r12,GPR12(r11) + lwz r10,crit_r10@l(0) + lwz r11,crit_r11@l(0) + PPC405_ERR77_SYNC + rfci + b . + + /* continue normal handling for a critical exception... */ +2: mfspr r4,SPRN_DBSR + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_TEMPLATE(DebugException, 0x2002, \ + (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) + +/* + * The other Data TLB exceptions bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +DataAccess: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + EXC_XFER_EE_LITE(0x300, handle_page_fault) + +/* Other PowerPC processors, namely those derived from the 6xx-series + * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. + * However, for the 4xx-series processors these are neither defined nor + * reserved. + */ + + /* Damn, I came up one instruction too many to fit into the + * exception space :-). Both the instruction and data TLB + * miss get to this point to load the TLB. + * r10 - TLB_TAG value + * r11 - Linux PTE + * r12, r9 - avilable to use + * PID - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + * Actually, it will fit now, but oh well.....a common place + * to load the TLB. + */ +tlb_4xx_index: + .long 0 +finish_tlb_load: + /* load the next available TLB index. + */ + lwz r9, tlb_4xx_index@l(0) + addi r9, r9, 1 + andi. r9, r9, (PPC4XX_TLB_SIZE-1) + stw r9, tlb_4xx_index@l(0) + +6: + /* + * Clear out the software-only bits in the PTE to generate the + * TLB_DATA value. These are the bottom 2 bits of the RPM, the + * top 3 bits of the zone field, and M. + */ + li r12, 0x0ce2 + andc r11, r11, r12 + + tlbwe r11, r9, TLB_DATA /* Load TLB LO */ + tlbwe r10, r9, TLB_TAG /* Load TLB HI */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r12, 12(r0) + lwz r11, 8(r0) + mtspr SPRN_PID, r12 + mtcr r11 + lwz r9, 4(r0) + lwz r12, 0(r0) +#else + mfspr r12, SPRN_SPRG6 + mfspr r11, SPRN_SPRG7 + mtspr SPRN_PID, r12 + mtcr r11 + mfspr r9, SPRN_SPRG5 + mfspr r12, SPRN_SPRG4 +#endif + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + b . /* prevent prefetch past rfi */ + +/* extern void giveup_fpu(struct task_struct *prev) + * + * The PowerPC 4xx family of processors do not have an FPU, so this just + * returns. + */ +_GLOBAL(giveup_fpu) + blr + +/* This is where the main kernel code starts. + */ +start_here: + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* init task's THREAD */ + mtspr SPRN_SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@ha + addi r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init /* We have to do this with MMU on */ + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + +/* Go back to running unmapped so we can load up new values + * and change to using our exception vectors. + * On the 4xx, all we have to do is invalidate the TLB to clear + * the old 16M byte TLB mappings. + */ + lis r4,2f@h + ori r4,r4,2f@l + tophys(r4,r4) + lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h + ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + rfi + b . /* prevent prefetch past rfi */ + +/* Load up the kernel context */ +2: + sync /* Flush to memory before changing TLB */ + tlbia + isync /* Flush shadow TLBs */ + + /* set up the PTE pointers for the Abatron bdiGDB. + */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* Must match your Abatron config file */ + tophys(r5,r5) + stw r6, 0(r5) + +/* Now turn on the MMU for real! */ + lis r4,MSR_KERNEL@h + ori r4,r4,MSR_KERNEL@l + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 + rfi /* enable MMU and jump to start_kernel */ + b . /* prevent prefetch past rfi */ + +/* Set up the initial MMU state so we can do the first level of + * kernel initialization. This maps the first 16 MBytes of memory 1:1 + * virtual to physical and more importantly sets the cache mode. + */ +initial_mmu: + tlbia /* Invalidate all TLB entries */ + isync + + /* We should still be executing code at physical address 0x0000xxxx + * at this point. However, start_here is at virtual address + * 0xC000xxxx. So, set up a TLB mapping to cover this once + * translation is enabled. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + tophys(r4,r3) /* Load the kernel physical address */ + + iccci r0,r3 /* Invalidate the i-cache before use */ + + /* Load the kernel PID. + */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Configure and load two entries into TLB slots 62 and 63. + * In case we are pinning TLBs, these are reserved in by the + * other TLB functions. If not reserving, then it doesn't + * matter where they are loaded. + */ + clrrwi r4,r4,10 /* Mask off the real page number */ + ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ + + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) + + li r0,63 /* TLB slot 63 */ + + tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ + tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE) + + /* Load a TLB entry for the UART, so that ppc4xx_progress() can use + * the UARTs nice and early. We use a 4k real==virtual mapping. */ + + lis r3,SERIAL_DEBUG_IO_BASE@h + ori r3,r3,SERIAL_DEBUG_IO_BASE@l + mr r4,r3 + clrrwi r4,r4,12 + ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G) + + clrrwi r3,r3,12 + ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K)) + + li r0,0 /* TLB slot 0 */ + tlbwe r4,r0,TLB_DATA + tlbwe r3,r0,TLB_TAG +#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */ + + isync + + /* Establish the exception vector base + */ + lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */ + tophys(r0,r4) /* Use the physical address */ + mtspr SPRN_EVPR,r0 + + blr + +_GLOBAL(abort) + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR0_RST_SYSTEM@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif + sync + mtspr SPRN_PID,r3 + isync /* Need an isync to flush shadow */ + /* TLBs after changing PID */ + blr + +/* We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 +_GLOBAL(swapper_pg_dir) + .space 4096 + + +/* Stack for handling critical exceptions from kernel mode */ + .section .bss + .align 12 +exception_stack_bottom: + .space 4096 +critical_stack_top: +_GLOBAL(exception_stack_top) + +/* This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S new file mode 100644 index 000000000000..22a5ee07e1ea --- /dev/null +++ b/arch/powerpc/kernel/head_64.S @@ -0,0 +1,2011 @@ +/* + * arch/ppc64/kernel/head.S + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and + * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com + * + * This file contains the low-level support and setup for the + * PowerPC-64 platform, including trap and interrupt dispatch. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PPC_ISERIES +#define DO_SOFT_DISABLE +#endif + +/* + * We layout physical memory as follows: + * 0x0000 - 0x00ff : Secondary processor spin code + * 0x0100 - 0x2fff : pSeries Interrupt prologs + * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs + * 0x6000 - 0x6fff : Initial (CPU0) segment table + * 0x7000 - 0x7fff : FWNMI data area + * 0x8000 - : Early init and support code + */ + +/* + * SPRG Usage + * + * Register Definition + * + * SPRG0 reserved for hypervisor + * SPRG1 temp - used to save gpr + * SPRG2 temp - used to save gpr + * SPRG3 virt addr of paca + */ + +/* + * Entering into this code we make the following assumptions: + * For pSeries: + * 1. The MMU is off & open firmware is running in real mode. + * 2. The kernel is entered at __start + * + * For iSeries: + * 1. The MMU is on (as it always is for iSeries) + * 2. The kernel is entered at system_reset_iSeries + */ + + .text + .globl _stext +_stext: +#ifdef CONFIG_PPC_MULTIPLATFORM +_GLOBAL(__start) + /* NOP this out unconditionally */ +BEGIN_FTR_SECTION + b .__start_initialization_multiplatform +END_FTR_SECTION(0, 1) +#endif /* CONFIG_PPC_MULTIPLATFORM */ + + /* Catch branch to 0 in real mode */ + trap + +#ifdef CONFIG_PPC_ISERIES + /* + * At offset 0x20, there is a pointer to iSeries LPAR data. + * This is required by the hypervisor + */ + . = 0x20 + .llong hvReleaseData-KERNELBASE + + /* + * At offset 0x28 and 0x30 are offsets to the mschunks_map + * array (used by the iSeries LPAR debugger to do translation + * between physical addresses and absolute addresses) and + * to the pidhash table (also used by the debugger) + */ + .llong mschunks_map-KERNELBASE + .llong 0 /* pidhash-KERNELBASE SFRXXX */ + + /* Offset 0x38 - Pointer to start of embedded System.map */ + .globl embedded_sysmap_start +embedded_sysmap_start: + .llong 0 + /* Offset 0x40 - Pointer to end of embedded System.map */ + .globl embedded_sysmap_end +embedded_sysmap_end: + .llong 0 + +#endif /* CONFIG_PPC_ISERIES */ + + /* Secondary processors spin on this value until it goes to 1. */ + .globl __secondary_hold_spinloop +__secondary_hold_spinloop: + .llong 0x0 + + /* Secondary processors write this value with their cpu # */ + /* after they enter the spin loop immediately below. */ + .globl __secondary_hold_acknowledge +__secondary_hold_acknowledge: + .llong 0x0 + + . = 0x60 +/* + * The following code is used on pSeries to hold secondary processors + * in a spin loop after they have been freed from OpenFirmware, but + * before the bulk of the kernel has been relocated. This code + * is relocated to physical address 0x60 before prom_init is run. + * All of it must fit below the first exception vector at 0x100. + */ +_GLOBAL(__secondary_hold) + mfmsr r24 + ori r24,r24,MSR_RI + mtmsrd r24 /* RI on */ + + /* Grab our linux cpu number */ + mr r24,r3 + + /* Tell the master cpu we're here */ + /* Relocation is off & we are located at an address less */ + /* than 0x100, so only need to grab low order offset. */ + std r24,__secondary_hold_acknowledge@l(0) + sync + + /* All secondary cpus wait here until told to start. */ +100: ld r4,__secondary_hold_spinloop@l(0) + cmpdi 0,r4,1 + bne 100b + +#ifdef CONFIG_HMT + b .hmt_init +#else +#ifdef CONFIG_SMP + mr r3,r24 + b .pSeries_secondary_smp_init +#else + BUG_OPCODE +#endif +#endif + +/* This value is used to mark exception frames on the stack. */ + .section ".toc","aw" +exception_marker: + .tc ID_72656773_68657265[TC],0x7265677368657265 + .text + +/* + * The following macros define the code that appears as + * the prologue to each of the exception handlers. They + * are split into two parts to allow a single kernel binary + * to be used for pSeries and iSeries. + * LOL. One day... - paulus + */ + +/* + * We make as much of the exception code common between native + * exception handlers (including pSeries LPAR) and iSeries LPAR + * implementations as possible. + */ + +/* + * This is the start of the interrupt handlers for pSeries + * This code runs with relocation off. + */ +#define EX_R9 0 +#define EX_R10 8 +#define EX_R11 16 +#define EX_R12 24 +#define EX_R13 32 +#define EX_SRR0 40 +#define EX_R3 40 /* SLB miss saves R3, but not SRR0 */ +#define EX_DAR 48 +#define EX_LR 48 /* SLB miss saves LR, but not DAR */ +#define EX_DSISR 56 +#define EX_CCR 60 + +#define EXCEPTION_PROLOG_PSERIES(area, label) \ + mfspr r13,SPRG3; /* get paca address into r13 */ \ + std r9,area+EX_R9(r13); /* save r9 - r12 */ \ + std r10,area+EX_R10(r13); \ + std r11,area+EX_R11(r13); \ + std r12,area+EX_R12(r13); \ + mfspr r9,SPRG1; \ + std r9,area+EX_R13(r13); \ + mfcr r9; \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ + mfspr r11,SRR0; /* save SRR0 */ \ + ori r12,r12,(label)@l; /* virt addr of handler */ \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ + mtspr SRR0,r12; \ + mfspr r12,SRR1; /* and SRR1 */ \ + mtspr SRR1,r10; \ + rfid; \ + b . /* prevent speculative execution */ + +/* + * This is the start of the interrupt handlers for iSeries + * This code runs with relocation on. + */ +#define EXCEPTION_PROLOG_ISERIES_1(area) \ + mfspr r13,SPRG3; /* get paca address into r13 */ \ + std r9,area+EX_R9(r13); /* save r9 - r12 */ \ + std r10,area+EX_R10(r13); \ + std r11,area+EX_R11(r13); \ + std r12,area+EX_R12(r13); \ + mfspr r9,SPRG1; \ + std r9,area+EX_R13(r13); \ + mfcr r9 + +#define EXCEPTION_PROLOG_ISERIES_2 \ + mfmsr r10; \ + ld r11,PACALPPACA+LPPACASRR0(r13); \ + ld r12,PACALPPACA+LPPACASRR1(r13); \ + ori r10,r10,MSR_RI; \ + mtmsrd r10,1 + +/* + * The common exception prolog is used for all except a few exceptions + * such as a segment miss on a kernel address. We have to be prepared + * to take another exception from the point where we first touch the + * kernel stack onwards. + * + * On entry r13 points to the paca, r9-r13 are saved in the paca, + * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and + * SRR1, and relocation is on. + */ +#define EXCEPTION_PROLOG_COMMON(n, area) \ + andi. r10,r12,MSR_PR; /* See if coming from user */ \ + mr r10,r1; /* Save r1 */ \ + subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ + beq- 1f; \ + ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ +1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ + bge- cr1,bad_stack; /* abort if it is */ \ + std r9,_CCR(r1); /* save CR in stackframe */ \ + std r11,_NIP(r1); /* save SRR0 in stackframe */ \ + std r12,_MSR(r1); /* save SRR1 in stackframe */ \ + std r10,0(r1); /* make stack chain pointer */ \ + std r0,GPR0(r1); /* save r0 in stackframe */ \ + std r10,GPR1(r1); /* save r1 in stackframe */ \ + std r2,GPR2(r1); /* save r2 in stackframe */ \ + SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ + SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ + ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ + ld r10,area+EX_R10(r13); \ + std r9,GPR9(r1); \ + std r10,GPR10(r1); \ + ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ + ld r10,area+EX_R12(r13); \ + ld r11,area+EX_R13(r13); \ + std r9,GPR11(r1); \ + std r10,GPR12(r1); \ + std r11,GPR13(r1); \ + ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ + mflr r9; /* save LR in stackframe */ \ + std r9,_LINK(r1); \ + mfctr r10; /* save CTR in stackframe */ \ + std r10,_CTR(r1); \ + mfspr r11,XER; /* save XER in stackframe */ \ + std r11,_XER(r1); \ + li r9,(n)+1; \ + std r9,_TRAP(r1); /* set trap number */ \ + li r10,0; \ + ld r11,exception_marker@toc(r2); \ + std r10,RESULT(r1); /* clear regs->result */ \ + std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ + +/* + * Exception vectors. + */ +#define STD_EXCEPTION_PSERIES(n, label) \ + . = n; \ + .globl label##_pSeries; \ +label##_pSeries: \ + HMT_MEDIUM; \ + mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + +#define STD_EXCEPTION_ISERIES(n, label, area) \ + .globl label##_iSeries; \ +label##_iSeries: \ + HMT_MEDIUM; \ + mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ + EXCEPTION_PROLOG_ISERIES_1(area); \ + EXCEPTION_PROLOG_ISERIES_2; \ + b label##_common + +#define MASKABLE_EXCEPTION_ISERIES(n, label) \ + .globl label##_iSeries; \ +label##_iSeries: \ + HMT_MEDIUM; \ + mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ + EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ + lbz r10,PACAPROCENABLED(r13); \ + cmpwi 0,r10,0; \ + beq- label##_iSeries_masked; \ + EXCEPTION_PROLOG_ISERIES_2; \ + b label##_common; \ + +#ifdef DO_SOFT_DISABLE +#define DISABLE_INTS \ + lbz r10,PACAPROCENABLED(r13); \ + li r11,0; \ + std r10,SOFTE(r1); \ + mfmsr r10; \ + stb r11,PACAPROCENABLED(r13); \ + ori r10,r10,MSR_EE; \ + mtmsrd r10,1 + +#define ENABLE_INTS \ + lbz r10,PACAPROCENABLED(r13); \ + mfmsr r11; \ + std r10,SOFTE(r1); \ + ori r11,r11,MSR_EE; \ + mtmsrd r11,1 + +#else /* hard enable/disable interrupts */ +#define DISABLE_INTS + +#define ENABLE_INTS \ + ld r12,_MSR(r1); \ + mfmsr r11; \ + rlwimi r11,r12,0,MSR_EE; \ + mtmsrd r11,1 + +#endif + +#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ + .align 7; \ + .globl label##_common; \ +label##_common: \ + EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ + DISABLE_INTS; \ + bl .save_nvgprs; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b .ret_from_except + +#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ + .align 7; \ + .globl label##_common; \ +label##_common: \ + EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ + DISABLE_INTS; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b .ret_from_except_lite + +/* + * Start of pSeries system interrupt routines + */ + . = 0x100 + .globl __start_interrupts +__start_interrupts: + + STD_EXCEPTION_PSERIES(0x100, system_reset) + + . = 0x200 +_machine_check_pSeries: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + + . = 0x300 + .globl data_access_pSeries +data_access_pSeries: + HMT_MEDIUM + mtspr SPRG1,r13 +BEGIN_FTR_SECTION + mtspr SPRG2,r12 + mfspr r13,DAR + mfspr r12,DSISR + srdi r13,r13,60 + rlwimi r13,r12,16,0x20 + mfcr r12 + cmpwi r13,0x2c + beq .do_stab_bolted_pSeries + mtcrf 0x80,r12 + mfspr r12,SPRG2 +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) + + . = 0x380 + .globl data_access_slb_pSeries +data_access_slb_pSeries: + HMT_MEDIUM + mtspr SPRG1,r13 + RUNLATCH_ON(r13) + mfspr r13,SPRG3 /* get paca address into r13 */ + std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ + std r10,PACA_EXSLB+EX_R10(r13) + std r11,PACA_EXSLB+EX_R11(r13) + std r12,PACA_EXSLB+EX_R12(r13) + std r3,PACA_EXSLB+EX_R3(r13) + mfspr r9,SPRG1 + std r9,PACA_EXSLB+EX_R13(r13) + mfcr r9 + mfspr r12,SRR1 /* and SRR1 */ + mfspr r3,DAR + b .do_slb_miss /* Rel. branch works in real mode */ + + STD_EXCEPTION_PSERIES(0x400, instruction_access) + + . = 0x480 + .globl instruction_access_slb_pSeries +instruction_access_slb_pSeries: + HMT_MEDIUM + mtspr SPRG1,r13 + RUNLATCH_ON(r13) + mfspr r13,SPRG3 /* get paca address into r13 */ + std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ + std r10,PACA_EXSLB+EX_R10(r13) + std r11,PACA_EXSLB+EX_R11(r13) + std r12,PACA_EXSLB+EX_R12(r13) + std r3,PACA_EXSLB+EX_R3(r13) + mfspr r9,SPRG1 + std r9,PACA_EXSLB+EX_R13(r13) + mfcr r9 + mfspr r12,SRR1 /* and SRR1 */ + mfspr r3,SRR0 /* SRR0 is faulting address */ + b .do_slb_miss /* Rel. branch works in real mode */ + + STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) + STD_EXCEPTION_PSERIES(0x600, alignment) + STD_EXCEPTION_PSERIES(0x700, program_check) + STD_EXCEPTION_PSERIES(0x800, fp_unavailable) + STD_EXCEPTION_PSERIES(0x900, decrementer) + STD_EXCEPTION_PSERIES(0xa00, trap_0a) + STD_EXCEPTION_PSERIES(0xb00, trap_0b) + + . = 0xc00 + .globl system_call_pSeries +system_call_pSeries: + HMT_MEDIUM + RUNLATCH_ON(r9) + mr r9,r13 + mfmsr r10 + mfspr r13,SPRG3 + mfspr r11,SRR0 + clrrdi r12,r13,32 + oris r12,r12,system_call_common@h + ori r12,r12,system_call_common@l + mtspr SRR0,r12 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI + mfspr r12,SRR1 + mtspr SRR1,r10 + rfid + b . /* prevent speculative execution */ + + STD_EXCEPTION_PSERIES(0xd00, single_step) + STD_EXCEPTION_PSERIES(0xe00, trap_0e) + + /* We need to deal with the Altivec unavailable exception + * here which is at 0xf20, thus in the middle of the + * prolog code of the PerformanceMonitor one. A little + * trickery is thus necessary + */ + . = 0xf00 + b performance_monitor_pSeries + + STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable) + + STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) + STD_EXCEPTION_PSERIES(0x1700, altivec_assist) + + . = 0x3000 + +/*** pSeries interrupt support ***/ + + /* moved from 0xf00 */ + STD_EXCEPTION_PSERIES(., performance_monitor) + + .align 7 +_GLOBAL(do_stab_bolted_pSeries) + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) + +/* + * Vectors for the FWNMI option. Share common code. + */ + .globl system_reset_fwnmi +system_reset_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) + + .globl machine_check_fwnmi +machine_check_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + +#ifdef CONFIG_PPC_ISERIES +/*** ISeries-LPAR interrupt handlers ***/ + + STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC) + + .globl data_access_iSeries +data_access_iSeries: + mtspr SPRG1,r13 +BEGIN_FTR_SECTION + mtspr SPRG2,r12 + mfspr r13,DAR + mfspr r12,DSISR + srdi r13,r13,60 + rlwimi r13,r12,16,0x20 + mfcr r12 + cmpwi r13,0x2c + beq .do_stab_bolted_iSeries + mtcrf 0x80,r12 + mfspr r12,SPRG2 +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) + EXCEPTION_PROLOG_ISERIES_2 + b data_access_common + +.do_stab_bolted_iSeries: + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) + EXCEPTION_PROLOG_ISERIES_2 + b .do_stab_bolted + + .globl data_access_slb_iSeries +data_access_slb_iSeries: + mtspr SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) + std r3,PACA_EXSLB+EX_R3(r13) + ld r12,PACALPPACA+LPPACASRR1(r13) + mfspr r3,DAR + b .do_slb_miss + + STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) + + .globl instruction_access_slb_iSeries +instruction_access_slb_iSeries: + mtspr SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) + std r3,PACA_EXSLB+EX_R3(r13) + ld r12,PACALPPACA+LPPACASRR1(r13) + ld r3,PACALPPACA+LPPACASRR0(r13) + b .do_slb_miss + + MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt) + STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN) + MASKABLE_EXCEPTION_ISERIES(0x900, decrementer) + STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN) + + .globl system_call_iSeries +system_call_iSeries: + mr r9,r13 + mfspr r13,SPRG3 + EXCEPTION_PROLOG_ISERIES_2 + b system_call_common + + STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN) + STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN) + STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN) + + .globl system_reset_iSeries +system_reset_iSeries: + mfspr r13,SPRG3 /* Get paca address */ + mfmsr r24 + ori r24,r24,MSR_RI + mtmsrd r24 /* RI on */ + lhz r24,PACAPACAINDEX(r13) /* Get processor # */ + cmpwi 0,r24,0 /* Are we processor 0? */ + beq .__start_initialization_iSeries /* Start up the first processor */ + mfspr r4,SPRN_CTRLF + li r5,CTRL_RUNLATCH /* Turn off the run light */ + andc r4,r4,r5 + mtspr SPRN_CTRLT,r4 + +1: + HMT_LOW +#ifdef CONFIG_SMP + lbz r23,PACAPROCSTART(r13) /* Test if this processor + * should start */ + sync + LOADADDR(r3,current_set) + sldi r28,r24,3 /* get current_set[cpu#] */ + ldx r3,r3,r28 + addi r1,r3,THREAD_SIZE + subi r1,r1,STACK_FRAME_OVERHEAD + + cmpwi 0,r23,0 + beq iSeries_secondary_smp_loop /* Loop until told to go */ + bne .__secondary_start /* Loop until told to go */ +iSeries_secondary_smp_loop: + /* Let the Hypervisor know we are alive */ + /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ + lis r3,0x8002 + rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ +#else /* CONFIG_SMP */ + /* Yield the processor. This is required for non-SMP kernels + which are running on multi-threaded machines. */ + lis r3,0x8000 + rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ + addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ + li r4,0 /* "yield timed" */ + li r5,-1 /* "yield forever" */ +#endif /* CONFIG_SMP */ + li r0,-1 /* r0=-1 indicates a Hypervisor call */ + sc /* Invoke the hypervisor via a system call */ + mfspr r13,SPRG3 /* Put r13 back ???? */ + b 1b /* If SMP not configured, secondaries + * loop forever */ + + .globl decrementer_iSeries_masked +decrementer_iSeries_masked: + li r11,1 + stb r11,PACALPPACA+LPPACADECRINT(r13) + lwz r12,PACADEFAULTDECR(r13) + mtspr SPRN_DEC,r12 + /* fall through */ + + .globl hardware_interrupt_iSeries_masked +hardware_interrupt_iSeries_masked: + mtcrf 0x80,r9 /* Restore regs */ + ld r11,PACALPPACA+LPPACASRR0(r13) + ld r12,PACALPPACA+LPPACASRR1(r13) + mtspr SRR0,r11 + mtspr SRR1,r12 + ld r9,PACA_EXGEN+EX_R9(r13) + ld r10,PACA_EXGEN+EX_R10(r13) + ld r11,PACA_EXGEN+EX_R11(r13) + ld r12,PACA_EXGEN+EX_R12(r13) + ld r13,PACA_EXGEN+EX_R13(r13) + rfid + b . /* prevent speculative execution */ +#endif /* CONFIG_PPC_ISERIES */ + +/*** Common interrupt handlers ***/ + + STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception) + + /* + * Machine check is different because we use a different + * save area: PACA_EXMC instead of PACA_EXGEN. + */ + .align 7 + .globl machine_check_common +machine_check_common: + EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) + DISABLE_INTS + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + bl .machine_check_exception + b .ret_from_except + + STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt) + STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception) + STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) + STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) + STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) + STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) + STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) +#ifdef CONFIG_ALTIVEC + STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) +#else + STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception) +#endif + +/* + * Here we have detected that the kernel stack pointer is bad. + * R9 contains the saved CR, r13 points to the paca, + * r10 contains the (bad) kernel stack pointer, + * r11 and r12 contain the saved SRR0 and SRR1. + * We switch to using an emergency stack, save the registers there, + * and call kernel_bad_stack(), which panics. + */ +bad_stack: + ld r1,PACAEMERGSP(r13) + subi r1,r1,64+INT_FRAME_SIZE + std r9,_CCR(r1) + std r10,GPR1(r1) + std r11,_NIP(r1) + std r12,_MSR(r1) + mfspr r11,DAR + mfspr r12,DSISR + std r11,_DAR(r1) + std r12,_DSISR(r1) + mflr r10 + mfctr r11 + mfxer r12 + std r10,_LINK(r1) + std r11,_CTR(r1) + std r12,_XER(r1) + SAVE_GPR(0,r1) + SAVE_GPR(2,r1) + SAVE_4GPRS(3,r1) + SAVE_2GPRS(7,r1) + SAVE_10GPRS(12,r1) + SAVE_10GPRS(22,r1) + addi r11,r1,INT_FRAME_SIZE + std r11,0(r1) + li r12,0 + std r12,0(r11) + ld r2,PACATOC(r13) +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .kernel_bad_stack + b 1b + +/* + * Return from an exception with minimal checks. + * The caller is assumed to have done EXCEPTION_PROLOG_COMMON. + * If interrupts have been enabled, or anything has been + * done that might have changed the scheduling status of + * any task or sent any task a signal, you should use + * ret_from_except or ret_from_except_lite instead of this. + */ +fast_exception_return: + ld r12,_MSR(r1) + ld r11,_NIP(r1) + andi. r3,r12,MSR_RI /* check if RI is set */ + beq- unrecov_fer + ld r3,_CCR(r1) + ld r4,_LINK(r1) + ld r5,_CTR(r1) + ld r6,_XER(r1) + mtcr r3 + mtlr r4 + mtctr r5 + mtxer r6 + REST_GPR(0, r1) + REST_8GPRS(2, r1) + + mfmsr r10 + clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ + mtmsrd r10,1 + + mtspr SRR1,r12 + mtspr SRR0,r11 + REST_4GPRS(10, r1) + ld r1,GPR1(r1) + rfid + b . /* prevent speculative execution */ + +unrecov_fer: + bl .save_nvgprs +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b 1b + +/* + * Here r13 points to the paca, r9 contains the saved CR, + * SRR0 and SRR1 are saved in r11 and r12, + * r9 - r13 are saved in paca->exgen. + */ + .align 7 + .globl data_access_common +data_access_common: + RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */ + mfspr r10,DAR + std r10,PACA_EXGEN+EX_DAR(r13) + mfspr r10,DSISR + stw r10,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) + ld r3,PACA_EXGEN+EX_DAR(r13) + lwz r4,PACA_EXGEN+EX_DSISR(r13) + li r5,0x300 + b .do_hash_page /* Try to handle as hpte fault */ + + .align 7 + .globl instruction_access_common +instruction_access_common: + EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) + ld r3,_NIP(r1) + andis. r4,r12,0x5820 + li r5,0x400 + b .do_hash_page /* Try to handle as hpte fault */ + + .align 7 + .globl hardware_interrupt_common + .globl hardware_interrupt_entry +hardware_interrupt_common: + EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) +hardware_interrupt_entry: + DISABLE_INTS + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_IRQ + b .ret_from_except_lite + + .align 7 + .globl alignment_common +alignment_common: + mfspr r10,DAR + std r10,PACA_EXGEN+EX_DAR(r13) + mfspr r10,DSISR + stw r10,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) + ld r3,PACA_EXGEN+EX_DAR(r13) + lwz r4,PACA_EXGEN+EX_DSISR(r13) + std r3,_DAR(r1) + std r4,_DSISR(r1) + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS + bl .alignment_exception + b .ret_from_except + + .align 7 + .globl program_check_common +program_check_common: + EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS + bl .program_check_exception + b .ret_from_except + + .align 7 + .globl fp_unavailable_common +fp_unavailable_common: + EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) + bne .load_up_fpu /* if from user, just load it up */ + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS + bl .kernel_fp_unavailable_exception + BUG_OPCODE + +/* + * load_up_fpu(unused, unused, tsk) + * Disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch (ie, no lazy save of the FP registers). + * On entry: r13 == 'current' && last_task_used_math != 'current' + */ +_STATIC(load_up_fpu) + mfmsr r5 /* grab the current MSR */ + ori r5,r5,MSR_FP + mtmsrd r5 /* enable use of fpu now */ + isync +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + * + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_math@got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save FP state to last_task_used_math's THREAD struct */ + addi r4,r4,THREAD + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR(r4) + /* Disable FP for last_task_used_math */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r6,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r4,THREAD_FPEXC_MODE(r5) + ori r12,r12,MSR_FP + or r12,r12,r4 + std r12,_MSR(r1) + lfd fr0,THREAD_FPSCR(r5) + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return + + .align 7 + .globl altivec_unavailable_common +altivec_unavailable_common: + EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + bne .load_up_altivec /* if from user, just load it up */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS + bl .altivec_unavailable_exception + b .ret_from_except + +#ifdef CONFIG_ALTIVEC +/* + * load_up_altivec(unused, unused, tsk) + * Disable VMX for the task which had it previously, + * and save its vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + * On SMP we know the VMX is free, since we give it up every + * switch (ie, no lazy save of the vector registers). + * On entry: r13 == 'current' && last_task_used_altivec != 'current' + */ +_STATIC(load_up_altivec) + mfmsr r5 /* grab the current MSR */ + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of VMX now */ + isync + +/* + * For SMP, we don't do lazy VMX switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altvec in switch_to. + * VRSAVE isn't dealt with here, that is done in the normal context + * switch code. Note that we could rely on vrsave value to eventually + * avoid saving all of the VREGs here... + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_altivec@got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save VMX state to last_task_used_altivec's THREAD struct */ + addi r4,r4,THREAD + SAVE_32VRS(0,r5,r4) + mfvscr vr0 + li r10,THREAD_VSCR + stvx vr0,r10,r4 + /* Disable VMX for last_task_used_altivec */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r6,MSR_VEC@h + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* Hack: if we get an altivec unavailable trap with VRSAVE + * set to all zeros, we assume this is a broken application + * that fails to set it properly, and thus we switch it to + * all 1's + */ + mfspr r4,SPRN_VRSAVE + cmpdi 0,r4,0 + bne+ 1f + li r4,-1 + mtspr SPRN_VRSAVE,r4 +1: + /* enable use of VMX after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + oris r12,r12,MSR_VEC@h + std r12,_MSR(r1) + li r4,1 + li r10,THREAD_VSCR + stw r4,THREAD_USED_VR(r5) + lvx vr0,r10,r5 + mtvscr vr0 + REST_32VRS(0,r4,r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return +#endif /* CONFIG_ALTIVEC */ + +/* + * Hash table stuff + */ + .align 7 +_GLOBAL(do_hash_page) + std r3,_DAR(r1) + std r4,_DSISR(r1) + + andis. r0,r4,0xa450 /* weird error? */ + bne- .handle_page_fault /* if not, try to insert a HPTE */ +BEGIN_FTR_SECTION + andis. r0,r4,0x0020 /* Is it a segment table fault? */ + bne- .do_ste_alloc /* If so handle it */ +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + + /* + * We need to set the _PAGE_USER bit if MSR_PR is set or if we are + * accessing a userspace segment (even from the kernel). We assume + * kernel addresses always have the high bit set. + */ + rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */ + rotldi r0,r3,15 /* Move high bit into MSR_PR posn */ + orc r0,r12,r0 /* MSR_PR | ~high_bit */ + rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */ + ori r4,r4,1 /* add _PAGE_PRESENT */ + rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */ + + /* + * On iSeries, we soft-disable interrupts here, then + * hard-enable interrupts so that the hash_page code can spin on + * the hash_table_lock without problems on a shared processor. + */ + DISABLE_INTS + + /* + * r3 contains the faulting address + * r4 contains the required access permissions + * r5 contains the trap number + * + * at return r3 = 0 for success + */ + bl .hash_page /* build HPTE if possible */ + cmpdi r3,0 /* see if hash_page succeeded */ + +#ifdef DO_SOFT_DISABLE + /* + * If we had interrupts soft-enabled at the point where the + * DSI/ISI occurred, and an interrupt came in during hash_page, + * handle it now. + * We jump to ret_from_except_lite rather than fast_exception_return + * because ret_from_except_lite will check for and handle pending + * interrupts if necessary. + */ + beq .ret_from_except_lite + /* For a hash failure, we don't bother re-enabling interrupts */ + ble- 12f + + /* + * hash_page couldn't handle it, set soft interrupt enable back + * to what it was before the trap. Note that .local_irq_restore + * handles any interrupts pending at this point. + */ + ld r3,SOFTE(r1) + bl .local_irq_restore + b 11f +#else + beq fast_exception_return /* Return from exception on success */ + ble- 12f /* Failure return from hash_page */ + + /* fall through */ +#endif + +/* Here we have a page fault that hash_page can't handle. */ +_GLOBAL(handle_page_fault) + ENABLE_INTS +11: ld r4,_DAR(r1) + ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_page_fault + cmpdi r3,0 + beq+ .ret_from_except_lite + bl .save_nvgprs + mr r5,r3 + addi r3,r1,STACK_FRAME_OVERHEAD + lwz r4,_DAR(r1) + bl .bad_page_fault + b .ret_from_except + +/* We have a page fault that hash_page could handle but HV refused + * the PTE insertion + */ +12: bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + lwz r4,_DAR(r1) + bl .low_hash_fault + b .ret_from_except + + /* here we have a segment miss */ +_GLOBAL(do_ste_alloc) + bl .ste_allocate /* try to insert stab entry */ + cmpdi r3,0 + beq+ fast_exception_return + b .handle_page_fault + +/* + * r13 points to the PACA, r9 contains the saved CR, + * r11 and r12 contain the saved SRR0 and SRR1. + * r9 - r13 are saved in paca->exslb. + * We assume we aren't going to take any exceptions during this procedure. + * We assume (DAR >> 60) == 0xc. + */ + .align 7 +_GLOBAL(do_stab_bolted) + stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ + std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ + + /* Hash to the primary group */ + ld r10,PACASTABVIRT(r13) + mfspr r11,DAR + srdi r11,r11,28 + rldimi r10,r11,7,52 /* r10 = first ste of the group */ + + /* Calculate VSID */ + /* This is a kernel address, so protovsid = ESID */ + ASM_VSID_SCRAMBLE(r11, r9) + rldic r9,r11,12,16 /* r9 = vsid << 12 */ + + /* Search the primary group for a free entry */ +1: ld r11,0(r10) /* Test valid bit of the current ste */ + andi. r11,r11,0x80 + beq 2f + addi r10,r10,16 + andi. r11,r10,0x70 + bne 1b + + /* Stick for only searching the primary group for now. */ + /* At least for now, we use a very simple random castout scheme */ + /* Use the TB as a random number ; OR in 1 to avoid entry 0 */ + mftb r11 + rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */ + ori r11,r11,0x10 + + /* r10 currently points to an ste one past the group of interest */ + /* make it point to the randomly selected entry */ + subi r10,r10,128 + or r10,r10,r11 /* r10 is the entry to invalidate */ + + isync /* mark the entry invalid */ + ld r11,0(r10) + rldicl r11,r11,56,1 /* clear the valid bit */ + rotldi r11,r11,8 + std r11,0(r10) + sync + + clrrdi r11,r11,28 /* Get the esid part of the ste */ + slbie r11 + +2: std r9,8(r10) /* Store the vsid part of the ste */ + eieio + + mfspr r11,DAR /* Get the new esid */ + clrrdi r11,r11,28 /* Permits a full 32b of ESID */ + ori r11,r11,0x90 /* Turn on valid and kp */ + std r11,0(r10) /* Put new entry back into the stab */ + + sync + + /* All done -- return from exception. */ + lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ + ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */ + + andi. r10,r12,MSR_RI + beq- unrecov_slb + + mtcrf 0x80,r9 /* restore CR */ + + mfmsr r10 + clrrdi r10,r10,2 + mtmsrd r10,1 + + mtspr SRR0,r11 + mtspr SRR1,r12 + ld r9,PACA_EXSLB+EX_R9(r13) + ld r10,PACA_EXSLB+EX_R10(r13) + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) + rfid + b . /* prevent speculative execution */ + +/* + * r13 points to the PACA, r9 contains the saved CR, + * r11 and r12 contain the saved SRR0 and SRR1. + * r3 has the faulting address + * r9 - r13 are saved in paca->exslb. + * r3 is saved in paca->slb_r3 + * We assume we aren't going to take any exceptions during this procedure. + */ +_GLOBAL(do_slb_miss) + mflr r10 + + stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ + std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ + + bl .slb_allocate /* handle it */ + + /* All done -- return from exception. */ + + ld r10,PACA_EXSLB+EX_LR(r13) + ld r3,PACA_EXSLB+EX_R3(r13) + lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ +#ifdef CONFIG_PPC_ISERIES + ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ +#endif /* CONFIG_PPC_ISERIES */ + + mtlr r10 + + andi. r10,r12,MSR_RI /* check for unrecoverable exception */ + beq- unrecov_slb + +.machine push +.machine "power4" + mtcrf 0x80,r9 + mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ +.machine pop + +#ifdef CONFIG_PPC_ISERIES + mtspr SRR0,r11 + mtspr SRR1,r12 +#endif /* CONFIG_PPC_ISERIES */ + ld r9,PACA_EXSLB+EX_R9(r13) + ld r10,PACA_EXSLB+EX_R10(r13) + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) + rfid + b . /* prevent speculative execution */ + +unrecov_slb: + EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) + DISABLE_INTS + bl .save_nvgprs +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b 1b + +/* + * Space for CPU0's segment table. + * + * On iSeries, the hypervisor must fill in at least one entry before + * we get control (with relocate on). The address is give to the hv + * as a page number (see xLparMap in LparData.c), so this must be at a + * fixed address (the linker can't compute (u64)&initial_stab >> + * PAGE_SHIFT). + */ + . = STAB0_PHYS_ADDR /* 0x6000 */ + .globl initial_stab +initial_stab: + .space 4096 + +/* + * Data area reserved for FWNMI option. + * This address (0x7000) is fixed by the RPA. + */ + .= 0x7000 + .globl fwnmi_data_area +fwnmi_data_area: + + /* iSeries does not use the FWNMI stuff, so it is safe to put + * this here, even if we later allow kernels that will boot on + * both pSeries and iSeries */ +#ifdef CONFIG_PPC_ISERIES + . = LPARMAP_PHYS +#include "lparmap.s" +/* + * This ".text" is here for old compilers that generate a trailing + * .note section when compiling .c files to .s + */ + .text +#endif /* CONFIG_PPC_ISERIES */ + + . = 0x8000 + +/* + * On pSeries, secondary processors spin in the following code. + * At entry, r3 = this processor's number (physical cpu id) + */ +_GLOBAL(pSeries_secondary_smp_init) + mr r24,r3 + + /* turn on 64-bit mode */ + bl .enable_64b_mode + isync + + /* Copy some CPU settings from CPU 0 */ + bl .__restore_cpu_setup + + /* Set up a paca value for this processor. Since we have the + * physical cpu id in r24, we need to search the pacas to find + * which logical id maps to our physical one. + */ + LOADADDR(r13, paca) /* Get base vaddr of paca array */ + li r5,0 /* logical cpu id */ +1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ + cmpw r6,r24 /* Compare to our id */ + beq 2f + addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */ + addi r5,r5,1 + cmpwi r5,NR_CPUS + blt 1b + + mr r3,r24 /* not found, copy phys to r3 */ + b .kexec_wait /* next kernel might do better */ + +2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + /* From now on, r24 is expected to be logical cpuid */ + mr r24,r5 +3: HMT_LOW + lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ + /* start. */ + sync + + /* Create a temp kernel stack for use before relocation is on. */ + ld r1,PACAEMERGSP(r13) + subi r1,r1,STACK_FRAME_OVERHEAD + + cmpwi 0,r23,0 +#ifdef CONFIG_SMP + bne .__secondary_start +#endif + b 3b /* Loop until told to go */ + +#ifdef CONFIG_PPC_ISERIES +_STATIC(__start_initialization_iSeries) + /* Clear out the BSS */ + LOADADDR(r11,__bss_stop) + LOADADDR(r8,__bss_start) + sub r11,r11,r8 /* bss size */ + addi r11,r11,7 /* round up to an even double word */ + rldicl. r11,r11,61,3 /* shift right by 3 */ + beq 4f + addi r8,r8,-8 + li r0,0 + mtctr r11 /* zero this many doublewords */ +3: stdu r0,8(r8) + bdnz 3b +4: + LOADADDR(r1,init_thread_union) + addi r1,r1,THREAD_SIZE + li r0,0 + stdu r0,-STACK_FRAME_OVERHEAD(r1) + + LOADADDR(r3,cpu_specs) + LOADADDR(r4,cur_cpu_spec) + li r5,0 + bl .identify_cpu + + LOADADDR(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + + bl .iSeries_early_setup + + /* relocation is on at this point */ + + b .start_here_common +#endif /* CONFIG_PPC_ISERIES */ + +#ifdef CONFIG_PPC_MULTIPLATFORM + +_STATIC(__mmu_off) + mfmsr r3 + andi. r0,r3,MSR_IR|MSR_DR + beqlr + andc r3,r3,r0 + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + sync + rfid + b . /* prevent speculative execution */ + + +/* + * Here is our main kernel entry point. We support currently 2 kind of entries + * depending on the value of r5. + * + * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content + * in r3...r7 + * + * r5 == NULL -> kexec style entry. r3 is a physical pointer to the + * DT block, r4 is a physical pointer to the kernel itself + * + */ +_GLOBAL(__start_initialization_multiplatform) + /* + * Are we booted from a PROM Of-type client-interface ? + */ + cmpldi cr0,r5,0 + bne .__boot_from_prom /* yes -> prom */ + + /* Save parameters */ + mr r31,r3 + mr r30,r4 + + /* Make sure we are running in 64 bits mode */ + bl .enable_64b_mode + + /* Setup some critical 970 SPRs before switching MMU off */ + bl .__970_cpu_preinit + + /* cpu # */ + li r24,0 + + /* Switch off MMU if not already */ + LOADADDR(r4, .__after_prom_start - KERNELBASE) + add r4,r4,r30 + bl .__mmu_off + b .__after_prom_start + +_STATIC(__boot_from_prom) + /* Save parameters */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + + /* Make sure we are running in 64 bits mode */ + bl .enable_64b_mode + + /* put a relocation offset into r3 */ + bl .reloc_offset + + LOADADDR(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + + /* Relocate the TOC from a virt addr to a real addr */ + sub r2,r2,r3 + + /* Restore parameters */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + + /* Do all of the interaction with OF client interface */ + bl .prom_init + /* We never return */ + trap + +/* + * At this point, r3 contains the physical address we are running at, + * returned by prom_init() + */ +_STATIC(__after_prom_start) + +/* + * We need to run with __start at physical address 0. + * This will leave some code in the first 256B of + * real memory, which are reserved for software use. + * The remainder of the first page is loaded with the fixed + * interrupt vectors. The next two pages are filled with + * unknown exception placeholders. + * + * Note: This process overwrites the OF exception vectors. + * r26 == relocation offset + * r27 == KERNELBASE + */ + bl .reloc_offset + mr r26,r3 + SET_REG_TO_CONST(r27,KERNELBASE) + + li r3,0 /* target addr */ + + // XXX FIXME: Use phys returned by OF (r30) + sub r4,r27,r26 /* source addr */ + /* current address of _start */ + /* i.e. where we are running */ + /* the source addr */ + + LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ + sub r5,r5,r27 + + li r6,0x100 /* Start offset, the first 0x100 */ + /* bytes were copied earlier. */ + + bl .copy_and_flush /* copy the first n bytes */ + /* this includes the code being */ + /* executed here. */ + + LOADADDR(r0, 4f) /* Jump to the copy of this code */ + mtctr r0 /* that we just made/relocated */ + bctr + +4: LOADADDR(r5,klimit) + sub r5,r5,r26 + ld r5,0(r5) /* get the value of klimit */ + sub r5,r5,r27 + bl .copy_and_flush /* copy the rest */ + b .start_here_multiplatform + +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +/* + * Copy routine used to copy the kernel to start at physical address 0 + * and flush and invalidate the caches as needed. + * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset + * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. + * + * Note: this routine *only* clobbers r0, r6 and lr + */ +_GLOBAL(copy_and_flush) + addi r5,r5,-8 + addi r6,r6,-8 +4: li r0,16 /* Use the least common */ + /* denominator cache line */ + /* size. This results in */ + /* extra cache line flushes */ + /* but operation is correct. */ + /* Can't get cache line size */ + /* from NACA as it is being */ + /* moved too. */ + + mtctr r0 /* put # words/line in ctr */ +3: addi r6,r6,8 /* copy a cache line */ + ldx r0,r6,r4 + stdx r0,r6,r3 + bdnz 3b + dcbst r6,r3 /* write it to memory */ + sync + icbi r6,r3 /* flush the icache line */ + cmpld 0,r6,r5 + blt 4b + sync + addi r5,r5,8 + addi r6,r6,8 + blr + +.align 8 +copy_to_here: + +#ifdef CONFIG_SMP +#ifdef CONFIG_PPC_PMAC +/* + * On PowerMac, secondary processors starts from the reset vector, which + * is temporarily turned into a call to one of the functions below. + */ + .section ".text"; + .align 2 ; + + .globl pmac_secondary_start_1 +pmac_secondary_start_1: + li r24, 1 + b .pmac_secondary_start + + .globl pmac_secondary_start_2 +pmac_secondary_start_2: + li r24, 2 + b .pmac_secondary_start + + .globl pmac_secondary_start_3 +pmac_secondary_start_3: + li r24, 3 + b .pmac_secondary_start + +_GLOBAL(pmac_secondary_start) + /* turn on 64-bit mode */ + bl .enable_64b_mode + isync + + /* Copy some CPU settings from CPU 0 */ + bl .__restore_cpu_setup + + /* pSeries do that early though I don't think we really need it */ + mfmsr r3 + ori r3,r3,MSR_RI + mtmsrd r3 /* RI on */ + + /* Set up a paca value for this processor. */ + LOADADDR(r4, paca) /* Get base vaddr of paca array */ + mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r4 /* for this processor. */ + mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + + /* Create a temp kernel stack for use before relocation is on. */ + ld r1,PACAEMERGSP(r13) + subi r1,r1,STACK_FRAME_OVERHEAD + + b .__secondary_start + +#endif /* CONFIG_PPC_PMAC */ + +/* + * This function is called after the master CPU has released the + * secondary processors. The execution environment is relocation off. + * The paca for this processor has the following fields initialized at + * this point: + * 1. Processor number + * 2. Segment table pointer (virtual address) + * On entry the following are set: + * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries + * r24 = cpu# (in Linux terms) + * r13 = paca virtual address + * SPRG3 = paca virtual address + */ +_GLOBAL(__secondary_start) + + HMT_MEDIUM /* Set thread priority to MEDIUM */ + + ld r2,PACATOC(r13) + li r6,0 + stb r6,PACAPROCENABLED(r13) + +#ifndef CONFIG_PPC_ISERIES + /* Initialize the page table pointer register. */ + LOADADDR(r6,_SDR1) + ld r6,0(r6) /* get the value of _SDR1 */ + mtspr SDR1,r6 /* set the htab location */ +#endif + /* Initialize the first segment table (or SLB) entry */ + ld r3,PACASTABVIRT(r13) /* get addr of segment table */ + bl .stab_initialize + + /* Initialize the kernel stack. Just a repeat for iSeries. */ + LOADADDR(r3,current_set) + sldi r28,r24,3 /* get current_set[cpu#] */ + ldx r1,r3,r28 + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + std r1,PACAKSAVE(r13) + + ld r3,PACASTABREAL(r13) /* get raddr of segment table */ + ori r4,r3,1 /* turn on valid bit */ + +#ifdef CONFIG_PPC_ISERIES + li r0,-1 /* hypervisor call */ + li r3,1 + sldi r3,r3,63 /* 0x8000000000000000 */ + ori r3,r3,4 /* 0x8000000000000004 */ + sc /* HvCall_setASR */ +#else + /* set the ASR */ + ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ + ld r3,0(r3) + lwz r3,PLATFORM(r3) /* r3 = platform flags */ + andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ + beq 98f /* branch if result is 0 */ + mfspr r3,PVR + srwi r3,r3,16 + cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ + bne 98f +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ + HVSC /* Invoking hcall */ + b 99f +98: /* !(rpa hypervisor) || !(star) */ + mtasr r4 /* set the stab location */ +99: +#endif + li r7,0 + mtlr r7 + + /* enable MMU and jump to start_secondary */ + LOADADDR(r3,.start_secondary_prolog) + SET_REG_TO_CONST(r4, MSR_KERNEL) +#ifdef DO_SOFT_DISABLE + ori r4,r4,MSR_EE +#endif + mtspr SRR0,r3 + mtspr SRR1,r4 + rfid + b . /* prevent speculative execution */ + +/* + * Running with relocation on at this point. All we want to do is + * zero the stack back-chain pointer before going into C code. + */ +_GLOBAL(start_secondary_prolog) + li r3,0 + std r3,0(r1) /* Zero the stack frame pointer */ + bl .start_secondary +#endif + +/* + * This subroutine clobbers r11 and r12 + */ +_GLOBAL(enable_64b_mode) + mfmsr r11 /* grab the current MSR */ + li r12,1 + rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) + or r11,r11,r12 + li r12,1 + rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) + or r11,r11,r12 + mtmsrd r11 + isync + blr + +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * This is where the main kernel code starts. + */ +_STATIC(start_here_multiplatform) + /* get a new offset, now that the kernel has moved. */ + bl .reloc_offset + mr r26,r3 + + /* Clear out the BSS. It may have been done in prom_init, + * already but that's irrelevant since prom_init will soon + * be detached from the kernel completely. Besides, we need + * to clear it now for kexec-style entry. + */ + LOADADDR(r11,__bss_stop) + LOADADDR(r8,__bss_start) + sub r11,r11,r8 /* bss size */ + addi r11,r11,7 /* round up to an even double word */ + rldicl. r11,r11,61,3 /* shift right by 3 */ + beq 4f + addi r8,r8,-8 + li r0,0 + mtctr r11 /* zero this many doublewords */ +3: stdu r0,8(r8) + bdnz 3b +4: + + mfmsr r6 + ori r6,r6,MSR_RI + mtmsrd r6 /* RI on */ + +#ifdef CONFIG_HMT + /* Start up the second thread on cpu 0 */ + mfspr r3,PVR + srwi r3,r3,16 + cmpwi r3,0x34 /* Pulsar */ + beq 90f + cmpwi r3,0x36 /* Icestar */ + beq 90f + cmpwi r3,0x37 /* SStar */ + beq 90f + b 91f /* HMT not supported */ +90: li r3,0 + bl .hmt_start_secondary +91: +#endif + + /* The following gets the stack and TOC set up with the regs */ + /* pointing to the real addr of the kernel stack. This is */ + /* all done to support the C function call below which sets */ + /* up the htab. This is done because we have relocated the */ + /* kernel but are still running in real mode. */ + + LOADADDR(r3,init_thread_union) + sub r3,r3,r26 + + /* set up a stack pointer (physical address) */ + addi r1,r3,THREAD_SIZE + li r0,0 + stdu r0,-STACK_FRAME_OVERHEAD(r1) + + /* set up the TOC (physical address) */ + LOADADDR(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + sub r2,r2,r26 + + LOADADDR(r3,cpu_specs) + sub r3,r3,r26 + LOADADDR(r4,cur_cpu_spec) + sub r4,r4,r26 + mr r5,r26 + bl .identify_cpu + + /* Save some low level config HIDs of CPU0 to be copied to + * other CPUs later on, or used for suspend/resume + */ + bl .__save_cpu_setup + sync + + /* Setup a valid physical PACA pointer in SPRG3 for early_setup + * note that boot_cpuid can always be 0 nowadays since there is + * nowhere it can be initialized differently before we reach this + * code + */ + LOADADDR(r27, boot_cpuid) + sub r27,r27,r26 + lwz r27,0(r27) + + LOADADDR(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ + sub r13,r13,r26 /* convert to physical addr */ + mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ + + /* Do very early kernel initializations, including initial hash table, + * stab and slb setup before we turn on relocation. */ + + /* Restore parameters passed from prom_init/kexec */ + mr r3,r31 + bl .early_setup + + /* set the ASR */ + ld r3,PACASTABREAL(r13) + ori r4,r3,1 /* turn on valid bit */ + ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ + ld r3,0(r3) + lwz r3,PLATFORM(r3) /* r3 = platform flags */ + andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ + beq 98f /* branch if result is 0 */ + mfspr r3,PVR + srwi r3,r3,16 + cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ + bne 98f +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ + HVSC /* Invoking hcall */ + b 99f +98: /* !(rpa hypervisor) || !(star) */ + mtasr r4 /* set the stab location */ +99: + /* Set SDR1 (hash table pointer) */ + ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */ + ld r3,0(r3) + lwz r3,PLATFORM(r3) /* r3 = platform flags */ + /* Test if bit 0 is set (LPAR bit) */ + andi. r3,r3,PLATFORM_LPAR + bne 98f /* branch if result is !0 */ + LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ + sub r6,r6,r26 + ld r6,0(r6) /* get the value of _SDR1 */ + mtspr SDR1,r6 /* set the htab location */ +98: + LOADADDR(r3,.start_here_common) + SET_REG_TO_CONST(r4, MSR_KERNEL) + mtspr SRR0,r3 + mtspr SRR1,r4 + rfid + b . /* prevent speculative execution */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ + + /* This is where all platforms converge execution */ +_STATIC(start_here_common) + /* relocation is on at this point */ + + /* The following code sets up the SP and TOC now that we are */ + /* running with translation enabled. */ + + LOADADDR(r3,init_thread_union) + + /* set up the stack */ + addi r1,r3,THREAD_SIZE + li r0,0 + stdu r0,-STACK_FRAME_OVERHEAD(r1) + + /* Apply the CPUs-specific fixups (nop out sections not relevant + * to this CPU + */ + li r3,0 + bl .do_cpu_ftr_fixups + + LOADADDR(r26, boot_cpuid) + lwz r26,0(r26) + + LOADADDR(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ + mtspr SPRG3,r13 + + /* ptr to current */ + LOADADDR(r4,init_task) + std r4,PACACURRENT(r13) + + /* Load the TOC */ + ld r2,PACATOC(r13) + std r1,PACAKSAVE(r13) + + bl .setup_system + + /* Load up the kernel context */ +5: +#ifdef DO_SOFT_DISABLE + li r5,0 + stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ + mfmsr r5 + ori r5,r5,MSR_EE /* Hard Enabled */ + mtmsrd r5 +#endif + + bl .start_kernel + +_GLOBAL(hmt_init) +#ifdef CONFIG_HMT + LOADADDR(r5, hmt_thread_data) + mfspr r7,PVR + srwi r7,r7,16 + cmpwi r7,0x34 /* Pulsar */ + beq 90f + cmpwi r7,0x36 /* Icestar */ + beq 91f + cmpwi r7,0x37 /* SStar */ + beq 91f + b 101f +90: mfspr r6,PIR + andi. r6,r6,0x1f + b 92f +91: mfspr r6,PIR + andi. r6,r6,0x3ff +92: sldi r4,r24,3 + stwx r6,r5,r4 + bl .hmt_start_secondary + b 101f + +__hmt_secondary_hold: + LOADADDR(r5, hmt_thread_data) + clrldi r5,r5,4 + li r7,0 + mfspr r6,PIR + mfspr r8,PVR + srwi r8,r8,16 + cmpwi r8,0x34 + bne 93f + andi. r6,r6,0x1f + b 103f +93: andi. r6,r6,0x3f + +103: lwzx r8,r5,r7 + cmpw r8,r6 + beq 104f + addi r7,r7,8 + b 103b + +104: addi r7,r7,4 + lwzx r9,r5,r7 + mr r24,r9 +101: +#endif + mr r3,r24 + b .pSeries_secondary_smp_init + +#ifdef CONFIG_HMT +_GLOBAL(hmt_start_secondary) + LOADADDR(r4,__hmt_secondary_hold) + clrldi r4,r4,4 + mtspr NIADORM, r4 + mfspr r4, MSRDORM + li r5, -65 + and r4, r4, r5 + mtspr MSRDORM, r4 + lis r4,0xffef + ori r4,r4,0x7403 + mtspr TSC, r4 + li r4,0x1f4 + mtspr TST, r4 + mfspr r4, HID0 + ori r4, r4, 0x1 + mtspr HID0, r4 + mfspr r4, SPRN_CTRLF + oris r4, r4, 0x40 + mtspr SPRN_CTRLT, r4 + blr +#endif + +#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) +_GLOBAL(smp_release_cpus) + /* All secondary cpus are spinning on a common + * spinloop, release them all now so they can start + * to spin on their individual paca spinloops. + * For non SMP kernels, the secondary cpus never + * get out of the common spinloop. + */ + li r3,1 + LOADADDR(r5,__secondary_hold_spinloop) + std r3,0(r5) + sync + blr +#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */ + + +/* + * We put a few things here that have to be page-aligned. + * This stuff goes at the beginning of the bss, which is page-aligned. + */ + .section ".bss" + + .align PAGE_SHIFT + + .globl empty_zero_page +empty_zero_page: + .space PAGE_SIZE + + .globl swapper_pg_dir +swapper_pg_dir: + .space PAGE_SIZE + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * Used to pass parameters into the kernel like root=/dev/sda1, etc. + */ + .globl cmd_line +cmd_line: + .space COMMAND_LINE_SIZE diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S new file mode 100644 index 000000000000..cb1a3a54a026 --- /dev/null +++ b/arch/powerpc/kernel/head_8xx.S @@ -0,0 +1,860 @@ +/* + * arch/ppc/kernel/except_8xx.S + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * MPC8xx modifications by Dan Malek + * Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * + * This file contains low-level support and setup for PowerPC 8xx + * embedded processors, including trap and interrupt dispatch. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Macro to make the code more readable. */ +#ifdef CONFIG_8xx_CPU6 +#define DO_8xx_CPU6(val, reg) \ + li reg, val; \ + stw reg, 12(r0); \ + lwz reg, 12(r0); +#else +#define DO_8xx_CPU6(val, reg) +#endif + .text + .globl _stext +_stext: + .text + .globl _start +_start: + +/* MPC8xx + * This port was done on an MBX board with an 860. Right now I only + * support an ELF compressed (zImage) boot from EPPC-Bug because the + * code there loads up some registers before calling us: + * r3: ptr to board info data + * r4: initrd_start or if no initrd then 0 + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + * + * I decided to use conditional compilation instead of checking PVR and + * adding more processor specific branches around code I don't need. + * Since this is an embedded processor, I also appreciate any memory + * savings I can get. + * + * The MPC8xx does not have any BATs, but it supports large page sizes. + * We first initialize the MMU to support 8M byte pages, then load one + * entry into each of the instruction and data TLBs to map the first + * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to + * the "internal" processor registers before MMU_init is called. + * + * The TLB code currently contains a major hack. Since I use the condition + * code register, I have to save and restore it. I am out of registers, so + * I just store it in memory location 0 (the TLB handlers are not reentrant). + * To avoid making any decisions, I need to use the "segment" valid bit + * in the first level table, but that would require many changes to the + * Linux page directory/table functions that I don't want to do right now. + * + * I used to use SPRG2 for a temporary register in the TLB handler, but it + * has since been put to other uses. I now use a hack to save a register + * and the CCR at memory location 0.....Someday I'll fix this..... + * -- Dan + */ + .globl __start +__start: + mr r31,r3 /* save parameters */ + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + + /* We have to turn on the MMU right away so we get cache modes + * set correctly. + */ + bl initial_mmu + +/* We now have the lower 8 Meg mapped into TLB entries, and the caches + * ready to work. + */ + +turn_on_mmu: + mfmsr r0 + ori r0,r0,MSR_DR|MSR_IR + mtspr SPRN_SRR1,r0 + lis r0,start_here@h + ori r0,r0,start_here@l + mtspr SPRN_SRR0,r0 + SYNC + rfi /* enables MMU */ + +/* + * Exception entry code. This code runs with address translation + * turned off, i.e. using physical addresses. + * We assume sprg3 has the physical address of the current + * task's thread_struct. + */ +#define EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; \ + mtspr SPRN_SPRG1,r11; \ + mfcr r10; \ + EXCEPTION_PROLOG_1; \ + EXCEPTION_PROLOG_2 + +#define EXCEPTION_PROLOG_1 \ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ + andi. r11,r11,MSR_PR; \ + tophys(r11,r1); /* use tophys(r1) if kernel */ \ + beq 1f; \ + mfspr r11,SPRN_SPRG3; \ + lwz r11,THREAD_INFO-THREAD(r11); \ + addi r11,r11,THREAD_SIZE; \ + tophys(r11,r11); \ +1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */ + + +#define EXCEPTION_PROLOG_2 \ + CLR_TOP32(r11); \ + stw r10,_CCR(r11); /* save registers */ \ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRN_SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRN_SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_SRR0; \ + mfspr r9,SPRN_SRR1; \ + stw r1,GPR1(r11); \ + stw r1,0(r11); \ + tovirt(r1,r11); /* set new kernel sp */ \ + li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ + MTMSRD(r10); /* (except for mach check in rtas) */ \ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Note: code which follows this uses cr0.eq (set if from kernel), + * r11, r12 (SRR0), and r9 (SRR1). + * + * Note2: once we have set r1 we are in a position to take exceptions + * again, and we could thus set MSR:RI at that point. + */ + +/* + * Exception vectors. + */ +#define EXCEPTION(n, label, hdlr, xfer) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + li r10,MSR_KERNEL; \ + copyee(r10, r9); \ + bl tfer; \ +i##n: \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \ + ret_from_except) + +/* System reset */ + EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) + +/* Machine check */ + . = 0x200 +MachineCheck: + EXCEPTION_PROLOG + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x200, MachineCheckException) + +/* Data access exception. + * This is "never generated" by the MPC8xx. We jump to it for other + * translation errors. + */ + . = 0x300 +DataAccess: + EXCEPTION_PROLOG + mfspr r10,SPRN_DSISR + stw r10,_DSISR(r11) + mr r5,r10 + mfspr r4,SPRN_DAR + EXC_XFER_EE_LITE(0x300, handle_page_fault) + +/* Instruction access exception. + * This is "never generated" by the MPC8xx. We jump to it for other + * translation errors. + */ + . = 0x400 +InstructionAccess: + EXCEPTION_PROLOG + mr r4,r12 + mr r5,r9 + EXC_XFER_EE_LITE(0x400, handle_page_fault) + +/* External interrupt */ + EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) + +/* Alignment exception */ + . = 0x600 +Alignment: + EXCEPTION_PROLOG + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x600, AlignmentException) + +/* Program check exception */ + EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + +/* No FPU on MPC8xx. This exception is not supposed to happen. +*/ + EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD) + +/* Decrementer */ + EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) + + EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + +/* System call */ + . = 0xc00 +SystemCall: + EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0xc00, DoSyscall) + +/* Single step - not used on 601 */ + EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) + EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE) + +/* On the MPC8xx, this is a software emulation interrupt. It occurs + * for all unimplemented and illegal instructions. + */ + EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD) + + . = 0x1100 +/* + * For the MPC8xx, this is a software tablewalk to load the instruction + * TLB. It is modelled after the example in the Motorola manual. The task + * switch loads the M_TWB register with the pointer to the first level table. + * If we discover there is no second level table (value is zero) or if there + * is an invalid pte, we load that into the TLB, which causes another fault + * into the TLB Error interrupt where we can handle such problems. + * We have to use the MD_xxx registers for the tablewalk because the + * equivalent MI_xxx registers only perform the attribute functions. + */ +InstructionTLBMiss: +#ifdef CONFIG_8xx_CPU6 + stw r3, 8(r0) +#endif + DO_8xx_CPU6(0x3f80, r3) + mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ + mfcr r10 + stw r10, 0(r0) + stw r11, 4(r0) + mfspr r10, SPRN_SRR0 /* Get effective address of fault */ + DO_8xx_CPU6(0x3780, r3) + mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */ + mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andi. r11, r10, 0x0800 /* Address >= 0x80000000 */ + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + rlwimi r10, r11, 0, 2, 19 +3: + lwz r11, 0(r10) /* Get the level 1 entry */ + rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ + beq 2f /* If zero, don't try to find a pte */ + + /* We have a pte table, so load the MI_TWC with the attributes + * for this "segment." + */ + ori r11,r11,1 /* Set valid bit */ + DO_8xx_CPU6(0x2b80, r3) + mtspr SPRN_MI_TWC, r11 /* Set segment attributes */ + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ + mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ + lwz r10, 0(r11) /* Get the pte */ + + ori r10, r10, _PAGE_ACCESSED + stw r10, 0(r11) + + /* The Linux PTE won't go exactly into the MMU TLB. + * Software indicator bits 21, 22 and 28 must be clear. + * Software indicator bits 24, 25, 26, and 27 must be + * set. All other Linux PTE bits control the behavior + * of the MMU. + */ +2: li r11, 0x00f0 + rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ + DO_8xx_CPU6(0x2d80, r3) + mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ + + mfspr r10, SPRN_M_TW /* Restore registers */ + lwz r11, 0(r0) + mtcr r11 + lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) +#endif + rfi + + . = 0x1200 +DataStoreTLBMiss: +#ifdef CONFIG_8xx_CPU6 + stw r3, 8(r0) +#endif + DO_8xx_CPU6(0x3f80, r3) + mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ + mfcr r10 + stw r10, 0(r0) + stw r11, 4(r0) + mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andi. r11, r10, 0x0800 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + rlwimi r10, r11, 0, 2, 19 +3: + lwz r11, 0(r10) /* Get the level 1 entry */ + rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ + beq 2f /* If zero, don't try to find a pte */ + + /* We have a pte table, so load fetch the pte from the table. + */ + ori r11, r11, 1 /* Set valid bit in physical L2 page */ + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ + mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ + lwz r10, 0(r10) /* Get the pte */ + + /* Insert the Guarded flag into the TWC from the Linux PTE. + * It is bit 27 of both the Linux PTE and the TWC (at least + * I got that right :-). It will be better when we can put + * this into the Linux pgd/pmd and load it in the operation + * above. + */ + rlwimi r11, r10, 0, 27, 27 + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 + + mfspr r11, SPRN_MD_TWC /* get the pte address again */ + ori r10, r10, _PAGE_ACCESSED + stw r10, 0(r11) + + /* The Linux PTE won't go exactly into the MMU TLB. + * Software indicator bits 21, 22 and 28 must be clear. + * Software indicator bits 24, 25, 26, and 27 must be + * set. All other Linux PTE bits control the behavior + * of the MMU. + */ +2: li r11, 0x00f0 + rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ + DO_8xx_CPU6(0x3d80, r3) + mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ + + mfspr r10, SPRN_M_TW /* Restore registers */ + lwz r11, 0(r0) + mtcr r11 + lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) +#endif + rfi + +/* This is an instruction TLB error on the MPC8xx. This could be due + * to many reasons, such as executing guarded memory or illegal instruction + * addresses. There is nothing to do but handle a big time error fault. + */ + . = 0x1300 +InstructionTLBError: + b InstructionAccess + +/* This is the data TLB error on the MPC8xx. This could be due to + * many reasons, including a dirty update to a pte. We can catch that + * one here, but anything else is an error. First, we track down the + * Linux pte. If it is valid, write access is allowed, but the + * page dirty bit is not set, we will set it and reload the TLB. For + * any other case, we bail out to a higher level function that can + * handle it. + */ + . = 0x1400 +DataTLBError: +#ifdef CONFIG_8xx_CPU6 + stw r3, 8(r0) +#endif + DO_8xx_CPU6(0x3f80, r3) + mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ + mfcr r10 + stw r10, 0(r0) + stw r11, 4(r0) + + /* First, make sure this was a store operation. + */ + mfspr r10, SPRN_DSISR + andis. r11, r10, 0x0200 /* If set, indicates store op */ + beq 2f + + /* The EA of a data TLB miss is automatically stored in the MD_EPN + * register. The EA of a data TLB error is automatically stored in + * the DAR, but not the MD_EPN register. We must copy the 20 most + * significant bits of the EA from the DAR to MD_EPN before we + * start walking the page tables. We also need to copy the CASID + * value from the M_CASID register. + * Addendum: The EA of a data TLB error is _supposed_ to be stored + * in DAR, but it seems that this doesn't happen in some cases, such + * as when the error is due to a dcbi instruction to a page with a + * TLB that doesn't have the changed bit set. In such cases, there + * does not appear to be any way to recover the EA of the error + * since it is neither in DAR nor MD_EPN. As a workaround, the + * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs + * are initialized in mapin_ram(). This will avoid the problem, + * assuming we only use the dcbi instruction on kernel addresses. + */ + mfspr r10, SPRN_DAR + rlwinm r11, r10, 0, 0, 19 + ori r11, r11, MD_EVALID + mfspr r10, SPRN_M_CASID + rlwimi r11, r10, 0, 28, 31 + DO_8xx_CPU6(0x3780, r3) + mtspr SPRN_MD_EPN, r11 + + mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andi. r11, r10, 0x0800 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + rlwimi r10, r11, 0, 2, 19 +3: + lwz r11, 0(r10) /* Get the level 1 entry */ + rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ + beq 2f /* If zero, bail */ + + /* We have a pte table, so fetch the pte from the table. + */ + ori r11, r11, 1 /* Set valid bit in physical L2 page */ + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ + mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ + lwz r10, 0(r11) /* Get the pte */ + + andi. r11, r10, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail out if not */ + + /* Update 'changed', among others. + */ + ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + mfspr r11, SPRN_MD_TWC /* Get pte address again */ + stw r10, 0(r11) /* and update pte in table */ + + /* The Linux PTE won't go exactly into the MMU TLB. + * Software indicator bits 21, 22 and 28 must be clear. + * Software indicator bits 24, 25, 26, and 27 must be + * set. All other Linux PTE bits control the behavior + * of the MMU. + */ + li r11, 0x00f0 + rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ + DO_8xx_CPU6(0x3d80, r3) + mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ + + mfspr r10, SPRN_M_TW /* Restore registers */ + lwz r11, 0(r0) + mtcr r11 + lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) +#endif + rfi +2: + mfspr r10, SPRN_M_TW /* Restore registers */ + lwz r11, 0(r0) + mtcr r11 + lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) +#endif + b DataAccess + + EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) + +/* On the MPC8xx, these next four traps are used for development + * support of breakpoints and such. Someday I will get around to + * using them. + */ + EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + + . = 0x2000 + + .globl giveup_fpu +giveup_fpu: + blr + +/* + * This is where the main kernel code starts. + */ +start_here: + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* init task's THREAD */ + mtspr SPRN_SPRG3,r4 + li r3,0 + mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */ + + /* stack */ + lis r1,init_thread_union@ha + addi r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init /* We have to do this with MMU on */ + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + +/* + * Go back to running unmapped so we can load up new values + * and change to using our exception vectors. + * On the 8xx, all we have to do is invalidate the TLB to clear + * the old 8M byte TLB mappings and load the page table base register. + */ + /* The right way to do this would be to track it down through + * init's THREAD like the context switch code does, but this is + * easier......until someone changes init's static structures. + */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + tophys(r6,r6) +#ifdef CONFIG_8xx_CPU6 + lis r4, cpu6_errata_word@h + ori r4, r4, cpu6_errata_word@l + li r3, 0x3980 + stw r3, 12(r4) + lwz r3, 12(r4) +#endif + mtspr SPRN_M_TWB, r6 + lis r4,2f@h + ori r4,r4,2f@l + tophys(r4,r4) + li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + rfi +/* Load up the kernel context */ +2: + SYNC /* Force all PTE updates to finish */ + tlbia /* Clear all TLB entries */ + sync /* wait for tlbia/tlbie to finish */ + TLBSYNC /* ... on all CPUs */ + + /* set up the PTE pointers for the Abatron bdiGDB. + */ + tovirt(r6,r6) + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* Must match your Abatron config file */ + tophys(r5,r5) + stw r6, 0(r5) + +/* Now turn on the MMU for real! */ + li r4,MSR_KERNEL + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 + rfi /* enable MMU and jump to start_kernel */ + +/* Set up the initial MMU state so we can do the first level of + * kernel initialization. This maps the first 8 MBytes of memory 1:1 + * virtual to physical. Also, set the cache mode since that is defined + * by TLB entries and perform any additional mapping (like of the IMMR). + * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel, + * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by + * these mappings is mapped by page tables. + */ +initial_mmu: + tlbia /* Invalidate all TLB entries */ +#ifdef CONFIG_PIN_TLB + lis r8, MI_RSV4I@h + ori r8, r8, 0x1c00 +#else + li r8, 0 +#endif + mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ + +#ifdef CONFIG_PIN_TLB + lis r10, (MD_RSV4I | MD_RESETVAL)@h + ori r10, r10, 0x1c00 + mr r8, r10 +#else + lis r10, MD_RESETVAL@h +#endif +#ifndef CONFIG_8xx_COPYBACK + oris r10, r10, MD_WTDEF@h +#endif + mtspr SPRN_MD_CTR, r10 /* Set data TLB control */ + + /* Now map the lower 8 Meg into the TLBs. For this quick hack, + * we can load the instruction and data TLB registers with the + * same values. + */ + lis r8, KERNELBASE@h /* Create vaddr for TLB */ + ori r8, r8, MI_EVALID /* Mark it valid */ + mtspr SPRN_MI_EPN, r8 + mtspr SPRN_MD_EPN, r8 + li r8, MI_PS8MEG /* Set 8M byte page */ + ori r8, r8, MI_SVALID /* Make it valid */ + mtspr SPRN_MI_TWC, r8 + mtspr SPRN_MD_TWC, r8 + li r8, MI_BOOTINIT /* Create RPN for address 0 */ + mtspr SPRN_MI_RPN, r8 /* Store TLB entry */ + mtspr SPRN_MD_RPN, r8 + lis r8, MI_Kp@h /* Set the protection mode */ + mtspr SPRN_MI_AP, r8 + mtspr SPRN_MD_AP, r8 + + /* Map another 8 MByte at the IMMR to get the processor + * internal registers (among other things). + */ +#ifdef CONFIG_PIN_TLB + addi r10, r10, 0x0100 + mtspr SPRN_MD_CTR, r10 +#endif + mfspr r9, 638 /* Get current IMMR */ + andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */ + + mr r8, r9 /* Create vaddr for TLB */ + ori r8, r8, MD_EVALID /* Mark it valid */ + mtspr SPRN_MD_EPN, r8 + li r8, MD_PS8MEG /* Set 8M byte page */ + ori r8, r8, MD_SVALID /* Make it valid */ + mtspr SPRN_MD_TWC, r8 + mr r8, r9 /* Create paddr for TLB */ + ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */ + mtspr SPRN_MD_RPN, r8 + +#ifdef CONFIG_PIN_TLB + /* Map two more 8M kernel data pages. + */ + addi r10, r10, 0x0100 + mtspr SPRN_MD_CTR, r10 + + lis r8, KERNELBASE@h /* Create vaddr for TLB */ + addis r8, r8, 0x0080 /* Add 8M */ + ori r8, r8, MI_EVALID /* Mark it valid */ + mtspr SPRN_MD_EPN, r8 + li r9, MI_PS8MEG /* Set 8M byte page */ + ori r9, r9, MI_SVALID /* Make it valid */ + mtspr SPRN_MD_TWC, r9 + li r11, MI_BOOTINIT /* Create RPN for address 0 */ + addis r11, r11, 0x0080 /* Add 8M */ + mtspr SPRN_MD_RPN, r8 + + addis r8, r8, 0x0080 /* Add 8M */ + mtspr SPRN_MD_EPN, r8 + mtspr SPRN_MD_TWC, r9 + addis r11, r11, 0x0080 /* Add 8M */ + mtspr SPRN_MD_RPN, r8 +#endif + + /* Since the cache is enabled according to the information we + * just loaded into the TLB, invalidate and enable the caches here. + * We should probably check/set other modes....later. + */ + lis r8, IDC_INVALL@h + mtspr SPRN_IC_CST, r8 + mtspr SPRN_DC_CST, r8 + lis r8, IDC_ENABLE@h + mtspr SPRN_IC_CST, r8 +#ifdef CONFIG_8xx_COPYBACK + mtspr SPRN_DC_CST, r8 +#else + /* For a debug option, I left this here to easily enable + * the write through cache mode + */ + lis r8, DC_SFWT@h + mtspr SPRN_DC_CST, r8 + lis r8, IDC_ENABLE@h + mtspr SPRN_DC_CST, r8 +#endif + blr + + +/* + * Set up to use a given MMU context. + * r3 is context number, r4 is PGD pointer. + * + * We place the physical address of the new task page directory loaded + * into the MMU base register, and set the ASID compare register with + * the new "context." + */ +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is passed as second argument. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif + +#ifdef CONFIG_8xx_CPU6 + lis r6, cpu6_errata_word@h + ori r6, r6, cpu6_errata_word@l + tophys (r4, r4) + li r7, 0x3980 + stw r7, 12(r6) + lwz r7, 12(r6) + mtspr SPRN_M_TWB, r4 /* Update MMU base address */ + li r7, 0x3380 + stw r7, 12(r6) + lwz r7, 12(r6) + mtspr SPRN_M_CASID, r3 /* Update context */ +#else + mtspr SPRN_M_CASID,r3 /* Update context */ + tophys (r4, r4) + mtspr SPRN_M_TWB, r4 /* and pgd */ +#endif + SYNC + blr + +#ifdef CONFIG_8xx_CPU6 +/* It's here because it is unique to the 8xx. + * It is important we get called with interrupts disabled. I used to + * do that, but it appears that all code that calls this already had + * interrupt disabled. + */ + .globl set_dec_cpu6 +set_dec_cpu6: + lis r7, cpu6_errata_word@h + ori r7, r7, cpu6_errata_word@l + li r4, 0x2c00 + stw r4, 8(r7) + lwz r4, 8(r7) + mtspr 22, r3 /* Update Decrementer */ + SYNC + blr +#endif + +/* + * We put a few things here that have to be page-aligned. + * This stuff goes at the beginning of the data segment, + * which is page-aligned. + */ + .data + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: + .space 4096 + + .globl swapper_pg_dir +swapper_pg_dir: + .space 4096 + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * Used to pass parameters into the kernel like root=/dev/sda1, etc. + */ + .globl cmd_line +cmd_line: + .space 512 + +/* Room for two PTE table poiners, usually the kernel and current user + * pointer to their respective root page table (pgdir). + */ +abatron_pteptrs: + .space 8 + +#ifdef CONFIG_8xx_CPU6 + .globl cpu6_errata_word +cpu6_errata_word: + .space 16 +#endif + diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S new file mode 100644 index 000000000000..eba5a5f8ff08 --- /dev/null +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -0,0 +1,1058 @@ +/* + * arch/ppc/kernel/head_fsl_booke.S + * + * Kernel execution entry point code. + * + * Copyright (c) 1995-1996 Gary Thomas + * Initial PowerPC version. + * Copyright (c) 1996 Cort Dougan + * Rewritten for PReP + * Copyright (c) 1996 Paul Mackerras + * Low-level exception handers, MMU support, and rewrite. + * Copyright (c) 1997 Dan Malek + * PowerPC 8xx modifications. + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson + * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * Copyright 2002-2004 MontaVista Software, Inc. + * PowerPC 44x support, Matt Porter + * Copyright 2004 Freescale Semiconductor, Inc + * PowerPC e500 modifications, Kumar Gala + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "head_booke.h" + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=128") + * r7 - End of kernel command line string + * + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + /* + * Reserve a word at a fixed location to store the address + * of abatron_pteptrs + */ + nop +/* + * Save parameters we are passed + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* CPU number */ + +/* We try to not make any assumptions about how the boot loader + * setup or used the TLBs. We invalidate all mappings from the + * boot loader and load a single entry in TLB1[0] to map the + * first 16M of kernel memory. Any boot info passed from the + * bootloader needs to live in this first 16M. + * + * Requirement on bootloader: + * - The page we're executing in needs to reside in TLB1 and + * have IPROT=1. If not an invalidate broadcast could + * evict the entry we're currently executing in. + * + * r3 = Index of TLB1 were executing in + * r4 = Current MSR[IS] + * r5 = Index of TLB1 temp mapping + * + * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0] + * if needed + */ + +/* 1. Find the index of the entry we're executing in */ + bl invstr /* Find our address */ +invstr: mflr r6 /* Make it accessible */ + mfmsr r7 + rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ + mfspr r7, SPRN_PID0 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ +#ifndef CONFIG_E200 + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + mfspr r7,SPRN_PID1 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + mfspr r7, SPRN_PID2 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* Fall through, we had to match */ +#endif +match_TLB: + mfspr r7,SPRN_MAS0 + rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ + + mfspr r7,SPRN_MAS1 /* Insure IPROT set */ + oris r7,r7,MAS1_IPROT@h + mtspr SPRN_MAS1,r7 + tlbwe + +/* 2. Invalidate all entries except the entry we're executing in */ + mfspr r9,SPRN_TLB1CFG + andi. r9,r9,0xfff + li r6,0 /* Set Entry counter to 0 */ +1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ + mtspr SPRN_MAS0,r7 + tlbre + mfspr r7,SPRN_MAS1 + rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ + cmpw r3,r6 + beq skpinv /* Dont update the current execution TLB */ + mtspr SPRN_MAS1,r7 + tlbwe + isync +skpinv: addi r6,r6,1 /* Increment */ + cmpw r6,r9 /* Are we done? */ + bne 1b /* If not, repeat */ + + /* Invalidate TLB0 */ + li r6,0x04 + tlbivax 0,r6 +#ifdef CONFIG_SMP + tlbsync +#endif + /* Invalidate TLB1 */ + li r6,0x0c + tlbivax 0,r6 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + +/* 3. Setup a temp mapping and jump to it */ + andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ + addi r5, r5, 0x1 + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + + /* Just modify the entry ID and EPN for the temp mapping */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + xori r6,r4,1 /* Setup TMP mapping in the other Address space */ + slwi r6,r6,12 + oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l + mtspr SPRN_MAS1,r6 + mfspr r6,SPRN_MAS2 + li r7,0 /* temp EPN = 0 */ + rlwimi r7,r6,0,20,31 + mtspr SPRN_MAS2,r7 + tlbwe + + xori r6,r4,1 + slwi r6,r6,5 /* setup new context with other address space */ + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r7,r9,0,20,31 + addi r7,r7,24 + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r6 + rfi + +/* 4. Clear out PIDs & Search info */ + li r6,0 + mtspr SPRN_PID0,r6 +#ifndef CONFIG_E200 + mtspr SPRN_PID1,r6 + mtspr SPRN_PID2,r6 +#endif + mtspr SPRN_MAS6,r6 + +/* 5. Invalidate mapping we started in */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + li r6,0 + mtspr SPRN_MAS1,r6 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + +/* 6. Setup KERNELBASE mapping in TLB1[0] */ + lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ + mtspr SPRN_MAS0,r6 + lis r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l + mtspr SPRN_MAS1,r6 + li r7,0 + lis r6,KERNELBASE@h + ori r6,r6,KERNELBASE@l + rlwimi r6,r7,0,20,31 + mtspr SPRN_MAS2,r6 + li r7,(MAS3_SX|MAS3_SW|MAS3_SR) + mtspr SPRN_MAS3,r7 + tlbwe + +/* 7. Jump to KERNELBASE mapping */ + lis r7,MSR_KERNEL@h + ori r7,r7,MSR_KERNEL@l + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r6,r9,0,20,31 + addi r6,r6,24 + mtspr SPRN_SRR0,r6 + mtspr SPRN_SRR1,r7 + rfi /* start execution out of TLB1[0] entry */ + +/* 8. Clear out the temp mapping */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + tlbre + mtspr SPRN_MAS1,r8 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, Debug); + SET_IVOR(32, SPEUnavailable); + SET_IVOR(33, SPEFloatingPointData); + SET_IVOR(34, SPEFloatingPointRound); +#ifndef CONFIG_E200 + SET_IVOR(35, PerformanceMonitor); +#endif + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + + /* Setup the defaults for TLB entries */ + li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l +#ifdef CONFIG_E200 + oris r2,r2,MAS4_TLBSELD(1)@h +#endif + mtspr SPRN_MAS4, r2 + +#if 0 + /* Enable DOZE */ + mfspr r2,SPRN_HID0 + oris r2,r2,HID0_DOZE@h + mtspr SPRN_HID0, r2 +#endif +#ifdef CONFIG_E200 + /* enable dedicated debug exception handling resources (Debug APU) */ + mfspr r2,SPRN_HID0 + ori r2,r2,HID0_DAPUEN@l + mtspr SPRN_HID0,r2 +#endif + +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + lis r2,DBCR0_IDM@h + mtspr SPRN_DBCR0,r2 + /* clear any residual debug events */ + li r2,-1 + mtspr SPRN_DBSR,r2 +#endif + + /* + * This is where the main kernel code starts. + */ + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to current thread */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRN_SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@h + ori r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init + + mfspr r3,SPRN_TLB1CFG + andi. r3,r3,0xfff + lis r4,num_tlbcam_entries@ha + stw r3,num_tlbcam_entries@l(r4) +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + + /* Setup PTE pointers for the Abatron bdiGDB */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + lis r4, KERNELBASE@h + ori r4, r4, KERNELBASE@l + stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ + stw r6, 0(r5) + + /* Let's move on */ + lis r4,start_kernel@h + ori r4,r4,start_kernel@l + lis r3,MSR_KERNEL@h + ori r3,r3,MSR_KERNEL@l + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r3 + rfi /* change context and jump to start_kernel */ + +/* Macros to hide the PTE size differences + * + * FIND_PTE -- walks the page tables given EA & pgdir pointer + * r10 -- EA of fault + * r11 -- PGDIR pointer + * r12 -- free + * label 2: is the bailout case + * + * if we find the pte (fall through): + * r11 is low pte word + * r12 is pointer to the pte + */ +#ifdef CONFIG_PTE_64BIT +#define PTE_FLAGS_OFFSET 4 +#define FIND_PTE \ + rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ + lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ + rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \ + beq 2f; /* Bail if no table */ \ + rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ + lwz r11, 4(r12); /* Get pte entry */ +#else +#define PTE_FLAGS_OFFSET 0 +#define FIND_PTE \ + rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ + lwz r11, 0(r11); /* Get L1 entry */ \ + rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \ + beq 2f; /* Bail if no table */ \ + rlwimi r12, r10, 22, 20, 29; /* Compute PTE address */ \ + lwz r11, 0(r12); /* Get Linux PTE */ +#endif + +/* + * Interrupt vector entry code + * + * The Book E MMUs are always on so we don't need to handle + * interrupts in real mode as with previous PPC processors. In + * this case we handle interrupts in the kernel virtual address + * space. + * + * Interrupt vectors are dynamically placed relative to the + * interrupt prefix as determined by the address of interrupt_base. + * The interrupt vectors offsets are programmed using the labels + * for each interrupt vector entry. + * + * Interrupt vectors must be aligned on a 16 byte boundary. + * We align on a 32 byte cache line boundary for good measure. + */ + +interrupt_base: + /* Critical Input Interrupt */ + CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + + /* Machine Check Interrupt */ +#ifdef CONFIG_E200 + /* no RFMCI, MCSRRs on E200 */ + CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +#else + MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +#endif + + /* Data Storage Interrupt */ + START_EXCEPTION(DataStorage) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + + /* + * Check if it was a store fault, if not then bail + * because a user tried to access a kernel or + * read-protected page. Otherwise, get the + * offending address and handle it. + */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_ST@h + beq 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 0, r10, r11 + bge 2f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) +4: + FIND_PTE + + /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */ + andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE + cmpwi 0, r13, _PAGE_RW|_PAGE_USER + bne 2f /* Bail if not */ + + /* Update 'changed'. */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */ + + /* MAS2 not updated as the entry does exist in the tlb, this + fault taken to detect state transition (eg: COW -> DIRTY) + */ + andi. r11, r11, _PAGE_HWEXEC + rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */ + ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */ + + /* update search PID in MAS6, AS = 0 */ + mfspr r12, SPRN_PID0 + slwi r12, r12, 16 + mtspr SPRN_MAS6, r12 + + /* find the TLB index that caused the fault. It has to be here. */ + tlbsx 0, r10 + + /* only update the perm bits, assume the RPN is fine */ + mfspr r12, SPRN_MAS3 + rlwimi r12, r11, 0, 20, 31 + mtspr SPRN_MAS3,r12 + tlbwe + + /* Done...restore registers and get out of here. */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + rfi /* Force context change */ + +2: + /* + * The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b data_access + + /* Instruction Storage Interrupt */ + INSTRUCTION_STORAGE_EXCEPTION + + /* External Input Interrupt */ + EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) + + /* Alignment Interrupt */ + ALIGNMENT_EXCEPTION + + /* Program Interrupt */ + PROGRAM_EXCEPTION + + /* Floating Point Unavailable Interrupt */ +#ifdef CONFIG_PPC_FPU + FP_UNAVAILABLE_EXCEPTION +#else +#ifdef CONFIG_E200 + /* E200 treats 'normal' floating point instructions as FP Unavail exception */ + EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE) +#else + EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) +#endif +#endif + + /* System Call Interrupt */ + START_EXCEPTION(SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0x0c00, DoSyscall) + + /* Auxillary Processor Unavailable Interrupt */ + EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + + /* Decrementer Interrupt */ + DECREMENTER_EXCEPTION + + /* Fixed Internal Timer Interrupt */ + /* TODO: Add FIT support */ + EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + + /* Watchdog Timer Interrupt */ +#ifdef CONFIG_BOOKE_WDT + CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException) +#else + CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) +#endif + + /* Data TLB Error Interrupt */ + START_EXCEPTION(DataTLBError) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 5, r10, r11 + blt 5, 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MAS1 /* Set TID to 0 */ + rlwinm r12,r12,0,16,1 + mtspr SPRN_MAS1,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + +4: + FIND_PTE + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + +#ifdef CONFIG_PTE_64BIT + lwz r13, 0(r12) +#endif + ori r11, r11, _PAGE_ACCESSED + stw r11, PTE_FLAGS_OFFSET(r12) + + /* Jump to common tlb load */ + b finish_tlb_load +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b data_access + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError) + mtspr SPRN_SPRG0, r10 /* Save some working registers */ + mtspr SPRN_SPRG1, r11 + mtspr SPRN_SPRG4W, r12 + mtspr SPRN_SPRG5W, r13 + mfcr r11 + mtspr SPRN_SPRG7W, r11 + mfspr r10, SPRN_SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 5, r10, r11 + blt 5, 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MAS1 /* Set TID to 0 */ + rlwinm r12,r12,0,16,1 + mtspr SPRN_MAS1,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + +4: + FIND_PTE + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + +#ifdef CONFIG_PTE_64BIT + lwz r13, 0(r12) +#endif + ori r11, r11, _PAGE_ACCESSED + stw r11, PTE_FLAGS_OFFSET(r12) + + /* Jump to common TLB load point */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + b InstructionStorage + +#ifdef CONFIG_SPE + /* SPE Unavailable */ + START_EXCEPTION(SPEUnavailable) + NORMAL_EXCEPTION_PROLOG + bne load_up_spe + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x2010, KernelSPE) +#else + EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE) +#endif /* CONFIG_SPE */ + + /* SPE Floating Point Data */ +#ifdef CONFIG_SPE + EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); +#else + EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE) +#endif /* CONFIG_SPE */ + + /* SPE Floating Point Round */ + EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE) + + /* Performance Monitor */ + EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD) + + + /* Debug Interrupt */ + DEBUG_EXCEPTION + +/* + * Local functions + */ + + /* + * Data TLB exceptions will bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +data_access: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + andis. r10,r5,(ESR_ILK|ESR_DLK)@h + bne 1f + EXC_XFER_EE_LITE(0x0300, handle_page_fault) +1: + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0300, CacheLockingException) + +/* + + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - EA of fault + * r11 - TLB (info from Linux PTE) + * r12, r13 - available to use + * CR5 - results of addr < TASK_SIZE + * MAS0, MAS1 - loaded with proper value when we get here + * MAS2, MAS3 - will need additional info from Linux PTE + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load: + /* + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + + mfspr r12, SPRN_MAS2 +#ifdef CONFIG_PTE_64BIT + rlwimi r12, r11, 26, 24, 31 /* extract ...WIMGE from pte */ +#else + rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ +#endif + mtspr SPRN_MAS2, r12 + + bge 5, 1f + + /* is user addr */ + andi. r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC) + andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */ + srwi r10, r12, 1 + or r12, r12, r10 /* Copy user perms into supervisor */ + iseleq r12, 0, r12 + b 2f + + /* is kernel addr */ +1: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */ + ori r12, r12, (MAS3_SX | MAS3_SR) + +#ifdef CONFIG_PTE_64BIT +2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */ + rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */ + mtspr SPRN_MAS3, r12 +BEGIN_FTR_SECTION + srwi r10, r13, 8 /* grab RPN[8:31] */ + mtspr SPRN_MAS7, r10 +END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS) +#else +2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ + mtspr SPRN_MAS3, r11 +#endif +#ifdef CONFIG_E200 + /* Round robin TLB1 entries assignment */ + mfspr r12, SPRN_MAS0 + + /* Extract TLB1CFG(NENTRY) */ + mfspr r11, SPRN_TLB1CFG + andi. r11, r11, 0xfff + + /* Extract MAS0(NV) */ + andi. r13, r12, 0xfff + addi r13, r13, 1 + cmpw 0, r13, r11 + addi r12, r12, 1 + + /* check if we need to wrap */ + blt 7f + + /* wrap back to first free tlbcam entry */ + lis r13, tlbcam_index@ha + lwz r13, tlbcam_index@l(r13) + rlwimi r12, r13, 0, 20, 31 +7: + mtspr SPRN_MAS0,r12 +#endif /* CONFIG_E200 */ + + tlbwe + + /* Done...restore registers and get out of here. */ + mfspr r11, SPRN_SPRG7R + mtcr r11 + mfspr r13, SPRN_SPRG5R + mfspr r12, SPRN_SPRG4R + mfspr r11, SPRN_SPRG1 + mfspr r10, SPRN_SPRG0 + rfi /* Force context change */ + +#ifdef CONFIG_SPE +/* Note that the SPE support is closely modeled after the AltiVec + * support. Changes to one are likely to be applicable to the + * other! */ +load_up_spe: +/* + * Disable SPE for the task which had SPE previously, + * and save its SPE registers in its thread_struct. + * Enables SPE for use in the kernel on return. + * On SMP we know the SPE units are free, since we give it up every + * switch. -- Kumar + */ + mfmsr r5 + oris r5,r5,MSR_SPE@h + mtmsr r5 /* enable use of SPE now */ + isync +/* + * For SMP, we don't do lazy SPE switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_spe in switch_to. + */ +#ifndef CONFIG_SMP + lis r3,last_task_used_spe@ha + lwz r4,last_task_used_spe@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want THREAD of last_task_used_spe */ + SAVE_32EVRS(0,r10,r4) + evxor evr10, evr10, evr10 /* clear out evr10 */ + evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */ + li r5,THREAD_ACC + evstddx evr10, r4, r5 /* save off accumulator */ + lwz r5,PT_REGS(r4) + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r10,MSR_SPE@h + andc r4,r4,r10 /* disable SPE for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of SPE after return */ + oris r9,r9,MSR_SPE@h + mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ + li r4,1 + li r10,THREAD_ACC + stw r4,THREAD_USED_SPE(r5) + evlddx evr4,r10,r5 + evmra evr4,evr4 + REST_32EVRS(0,r10,r5) +#ifndef CONFIG_SMP + subi r4,r5,THREAD + stw r4,last_task_used_spe@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ +2: REST_4GPRS(3, r11) + lwz r10,_CCR(r11) + REST_GPR(1, r11) + mtcr r10 + lwz r10,_LINK(r11) + mtlr r10 + REST_GPR(10, r11) + mtspr SPRN_SRR1,r9 + mtspr SPRN_SRR0,r12 + REST_GPR(9, r11) + REST_GPR(12, r11) + lwz r11,GPR11(r11) + SYNC + rfi + +/* + * SPE unavailable trap from kernel - print a message, but let + * the task use SPE in the kernel until it returns to user mode. + */ +KernelSPE: + lwz r3,_MSR(r1) + oris r3,r3,MSR_SPE@h + stw r3,_MSR(r1) /* enable use of SPE after return */ + lis r3,87f@h + ori r3,r3,87f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +87: .string "SPE used in kernel (task=%p, pc=%x) \n" + .align 4,0 + +#endif /* CONFIG_SPE */ + +/* + * Global functions + */ + +/* + * extern void loadcam_entry(unsigned int index) + * + * Load TLBCAM[index] entry in to the L2 CAM MMU + */ +_GLOBAL(loadcam_entry) + lis r4,TLBCAM@ha + addi r4,r4,TLBCAM@l + mulli r5,r3,20 + add r3,r5,r4 + lwz r4,0(r3) + mtspr SPRN_MAS0,r4 + lwz r4,4(r3) + mtspr SPRN_MAS1,r4 + lwz r4,8(r3) + mtspr SPRN_MAS2,r4 + lwz r4,12(r3) + mtspr SPRN_MAS3,r4 + tlbwe + isync + blr + +/* + * extern void giveup_altivec(struct task_struct *prev) + * + * The e500 core does not have an AltiVec unit. + */ +_GLOBAL(giveup_altivec) + blr + +#ifdef CONFIG_SPE +/* + * extern void giveup_spe(struct task_struct *prev) + * + */ +_GLOBAL(giveup_spe) + mfmsr r5 + oris r5,r5,MSR_SPE@h + SYNC + mtmsr r5 /* enable use of SPE now */ + isync + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32EVRS(0, r4, r3) + evxor evr6, evr6, evr6 /* clear out evr6 */ + evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */ + li r4,THREAD_ACC + evstddx evr6, r4, r3 /* save off accumulator */ + mfspr r6,SPRN_SPEFSCR + stw r6,THREAD_SPEFSCR(r3) /* save spefscr register value */ + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_SPE@h + andc r4,r4,r3 /* disable SPE for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_spe@ha + stw r5,last_task_used_spe@l(r4) +#endif /* CONFIG_SMP */ + blr +#endif /* CONFIG_SPE */ + +/* + * extern void giveup_fpu(struct task_struct *prev) + * + * Not all FSL Book-E cores have an FPU + */ +#ifndef CONFIG_PPC_FPU +_GLOBAL(giveup_fpu) + blr +#endif + +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + li r13,0 + mtspr SPRN_DBCR0,r13 /* disable all debug events */ + mfmsr r13 + ori r13,r13,MSR_DE@l /* Enable Debug Events */ + mtmsr r13 + mfspr r13,SPRN_DBCR0 + lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r4, 0x4(r5) +#endif + mtspr SPRN_PID,r3 + isync /* Force context change */ + blr + +/* + * We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 +_GLOBAL(swapper_pg_dir) + .space 4096 + +/* Reserved 4k for the critical exception stack & 4k for the machine + * check stack per CPU for kernel mode exceptions */ + .section .bss + .align 12 +exception_stack_bottom: + .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS +_GLOBAL(exception_stack_top) + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* + * Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 + diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S new file mode 100644 index 000000000000..1a2194cf6828 --- /dev/null +++ b/arch/powerpc/kernel/idle_6xx.S @@ -0,0 +1,233 @@ +/* + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + + .text + +/* + * Init idle, called at early CPU setup time from head.S for each CPU + * Make sure no rest of NAP mode remains in HID0, save default + * values for some CPU specific registers. Called with r24 + * containing CPU number and r3 reloc offset + */ +_GLOBAL(init_idle_6xx) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID0 + rlwinm r4,r4,0,10,8 /* Clear NAP */ + mtspr SPRN_HID0, r4 + b 1f +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + blr +1: + slwi r5,r24,2 + add r5,r5,r3 +BEGIN_FTR_SECTION + mfspr r4,SPRN_MSSCR0 + addis r6,r5, nap_save_msscr0@ha + stw r4,nap_save_msscr0@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID1 + addis r6,r5,nap_save_hid1@ha + stw r4,nap_save_hid1@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + blr + +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ +_GLOBAL(ppc6xx_idle) + /* Check if we can nap or doze, put HID0 mask in r3 + */ + lis r3, 0 +BEGIN_FTR_SECTION + lis r3,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) +BEGIN_FTR_SECTION + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + lis r4,cur_cpu_spec@ha + lwz r4,cur_cpu_spec@l(r4) + lwz r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beq 1f + /* Now check if user or arch enabled NAP mode */ + lis r4,powersave_nap@ha + lwz r4,powersave_nap@l(r4) + cmpwi 0,r4,0 + beq 1f + lis r3,HID0_NAP@h +1: +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + cmpwi 0,r3,0 + beqlr + + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: + /* Some pre-nap cleanups needed on some CPUs */ + andis. r0,r3,HID0_NAP@h + beq 2f +BEGIN_FTR_SECTION + /* Disable L2 prefetch on some 745x and try to ensure + * L2 prefetch engines are idle. As explained by errata + * text, we can't be sure they are, we just hope very hard + * that well be enough (sic !). At least I noticed Apple + * doesn't even bother doing the dcbf's here... + */ + mfspr r4,SPRN_MSSCR0 + rlwinm r4,r4,0,0,29 + sync + mtspr SPRN_MSSCR0,r4 + sync + isync + lis r4,KERNELBASE@h + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +#ifdef DEBUG + lis r6,nap_enter_count@ha + lwz r4,nap_enter_count@l(r6) + addi r4,r4,1 + stw r4,nap_enter_count@l(r6) +#endif +2: +BEGIN_FTR_SECTION + /* Go to low speed mode on some 750FX */ + lis r4,powersave_lowspeed@ha + lwz r4,powersave_lowspeed@l(r4) + cmpwi 0,r4,0 + beq 1f + mfspr r4,SPRN_HID1 + oris r4,r4,0x0001 + mtspr SPRN_HID1,r4 +1: +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + + /* Go to NAP or DOZE now */ + mfspr r4,SPRN_HID0 + lis r5,(HID0_NAP|HID0_SLEEP)@h +BEGIN_FTR_SECTION + oris r5,r5,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + andc r4,r4,r5 + or r4,r4,r3 +BEGIN_FTR_SECTION + oris r4,r4,HID0_DPM@h /* that should be done once for all */ +END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + mtspr SPRN_HID0,r4 +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + ori r7,r7,MSR_EE /* Could be ommited (already set) */ + oris r7,r7,MSR_POW@h + sync + isync + mtmsr r7 + isync + sync + blr + +/* + * Return from NAP/DOZE mode, restore some CPU specific registers, + * we are called with DR/IR still off and r2 containing physical + * address of current. + */ +_GLOBAL(power_save_6xx_restore) + mfspr r11,SPRN_HID0 + rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ + cror 4*cr1+eq,4*cr0+eq,4*cr0+eq +BEGIN_FTR_SECTION + rlwinm r11,r11,0,9,7 /* Clear DOZE */ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + mtspr SPRN_HID0, r11 + +#ifdef DEBUG + beq cr1,1f + lis r11,(nap_return_count-KERNELBASE)@ha + lwz r9,nap_return_count@l(r11) + addi r9,r9,1 + stw r9,nap_return_count@l(r11) +1: +#endif + + rlwinm r9,r1,0,0,18 + tophys(r9,r9) + lwz r11,TI_CPU(r9) + slwi r11,r11,2 + /* Todo make sure all these are in the same page + * and load r22 (@ha part + CPU offset) only once + */ +BEGIN_FTR_SECTION + beq cr1,1f + addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha + lwz r9,nap_save_msscr0@l(r9) + mtspr SPRN_MSSCR0, r9 + sync + isync +1: +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + addis r9,r11,(nap_save_hid1-KERNELBASE)@ha + lwz r9,nap_save_hid1@l(r9) + mtspr SPRN_HID1, r9 +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + b transfer_to_handler_cont + + .data + +_GLOBAL(nap_save_msscr0) + .space 4*NR_CPUS + +_GLOBAL(nap_save_hid1) + .space 4*NR_CPUS + +_GLOBAL(powersave_nap) + .long 0 +_GLOBAL(powersave_lowspeed) + .long 0 + +#ifdef DEBUG +_GLOBAL(nap_enter_count) + .space 4 +_GLOBAL(nap_return_count) + .space 4 +#endif diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c new file mode 100644 index 000000000000..f5a9d2a84fa1 --- /dev/null +++ b/arch/powerpc/kernel/process.c @@ -0,0 +1,724 @@ +/* + * arch/ppc/kernel/process.c + * + * Derived from "arch/i386/kernel/process.c" + * Copyright (C) 1995 Linus Torvalds + * + * Updated and modified by Cort Dougan (cort@cs.nmt.edu) and + * Paul Mackerras (paulus@cs.anu.edu.au) + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern unsigned long _get_SP(void); + +#ifndef CONFIG_SMP +struct task_struct *last_task_used_math = NULL; +struct task_struct *last_task_used_altivec = NULL; +struct task_struct *last_task_used_spe = NULL; +#endif + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_SYMBOL(init_mm); + +/* this is 8kB-aligned so we can get to the thread_info struct + at the base of it from the stack pointer with 1 integer instruction. */ +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = +{ INIT_THREAD_INFO(init_task) }; + +/* initial task structure */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* only used to get secondary processor up */ +struct task_struct *current_set[NR_CPUS] = {&init_task, }; + +/* + * Make sure the floating-point register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_fp_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + /* + * We need to disable preemption here because if we didn't, + * another process could get scheduled after the regs->msr + * test but before we have finished saving the FP registers + * to the thread_struct. That process could take over the + * FPU, and then when we get scheduled again we would store + * bogus values for the remaining FP registers. + */ + preempt_disable(); + if (tsk->thread.regs->msr & MSR_FP) { +#ifdef CONFIG_SMP + /* + * This should only ever be called for current or + * for a stopped child process. Since we save away + * the FP register state on context switch on SMP, + * there is something wrong if a stopped child appears + * to still have its FP state in the CPU registers. + */ + BUG_ON(tsk != current); +#endif + giveup_fpu(current); + } + preempt_enable(); + } +} + +void enable_kernel_fp(void) +{ + WARN_ON(preemptible()); + +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) + giveup_fpu(current); + else + giveup_fpu(NULL); /* just enables FP for kernel */ +#else + giveup_fpu(last_task_used_math); +#endif /* CONFIG_SMP */ +} +EXPORT_SYMBOL(enable_kernel_fp); + +int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) +{ + if (!tsk->thread.regs) + return 0; + flush_fp_to_thread(current); + + memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); + + return 1; +} + +#ifdef CONFIG_ALTIVEC +void enable_kernel_altivec(void) +{ + WARN_ON(preemptible()); + +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) + giveup_altivec(current); + else + giveup_altivec(NULL); /* just enable AltiVec for kernel - force */ +#else + giveup_altivec(last_task_used_altivec); +#endif /* CONFIG_SMP */ +} +EXPORT_SYMBOL(enable_kernel_altivec); + +/* + * Make sure the VMX/Altivec register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_altivec_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + preempt_disable(); + if (tsk->thread.regs->msr & MSR_VEC) { +#ifdef CONFIG_SMP + BUG_ON(tsk != current); +#endif + giveup_altivec(current); + } + preempt_enable(); + } +} + +int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) +{ + flush_altivec_to_thread(current); + memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); + return 1; +} +#endif /* CONFIG_ALTIVEC */ + +#ifdef CONFIG_SPE + +void enable_kernel_spe(void) +{ + WARN_ON(preemptible()); + +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) + giveup_spe(current); + else + giveup_spe(NULL); /* just enable SPE for kernel - force */ +#else + giveup_spe(last_task_used_spe); +#endif /* __SMP __ */ +} +EXPORT_SYMBOL(enable_kernel_spe); + +void flush_spe_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + preempt_disable(); + if (tsk->thread.regs->msr & MSR_SPE) { +#ifdef CONFIG_SMP + BUG_ON(tsk != current); +#endif + giveup_spe(current); + } + preempt_enable(); + } +} + +int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) +{ + flush_spe_to_thread(current); + /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */ + memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35); + return 1; +} +#endif /* CONFIG_SPE */ + +static void set_dabr_spr(unsigned long val) +{ + mtspr(SPRN_DABR, val); +} + +int set_dabr(unsigned long dabr) +{ + int ret = 0; + +#ifdef CONFIG_PPC64 + if (firmware_has_feature(FW_FEATURE_XDABR)) { + /* We want to catch accesses from kernel and userspace */ + unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER; + ret = plpar_set_xdabr(dabr, flags); + } else if (firmware_has_feature(FW_FEATURE_DABR)) { + ret = plpar_set_dabr(dabr); + } else +#endif + set_dabr_spr(dabr); + + return ret; +} + +static DEFINE_PER_CPU(unsigned long, current_dabr); + +struct task_struct *__switch_to(struct task_struct *prev, + struct task_struct *new) +{ + struct thread_struct *new_thread, *old_thread; + unsigned long flags; + struct task_struct *last; + +#ifdef CONFIG_SMP + /* avoid complexity of lazy save/restore of fpu + * by just saving it every time we switch out if + * this task used the fpu during the last quantum. + * + * If it tries to use the fpu again, it'll trap and + * reload its fp regs. So we don't have to do a restore + * every switch, just a save. + * -- Cort + */ + if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP)) + giveup_fpu(prev); +#ifdef CONFIG_ALTIVEC + /* + * If the previous thread used altivec in the last quantum + * (thus changing altivec regs) then save them. + * We used to check the VRSAVE register but not all apps + * set it, so we don't rely on it now (and in fact we need + * to save & restore VSCR even if VRSAVE == 0). -- paulus + * + * On SMP we always save/restore altivec regs just to avoid the + * complexity of changing processors. + * -- Cort + */ + if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) + giveup_altivec(prev); + /* Avoid the trap. On smp this this never happens since + * we don't set last_task_used_altivec -- Cort + */ + if (new->thread.regs && last_task_used_altivec == new) + new->thread.regs->msr |= MSR_VEC; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + /* + * If the previous thread used spe in the last quantum + * (thus changing spe regs) then save them. + * + * On SMP we always save/restore spe regs just to avoid the + * complexity of changing processors. + */ + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) + giveup_spe(prev); + /* Avoid the trap. On smp this this never happens since + * we don't set last_task_used_spe + */ + if (new->thread.regs && last_task_used_spe == new) + new->thread.regs->msr |= MSR_SPE; +#endif /* CONFIG_SPE */ +#endif /* CONFIG_SMP */ + +#ifdef CONFIG_PPC64 /* for now */ + if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) { + set_dabr(new->thread.dabr); + __get_cpu_var(current_dabr) = new->thread.dabr; + } +#endif + + new_thread = &new->thread; + old_thread = ¤t->thread; + local_irq_save(flags); + last = _switch(old_thread, new_thread); + + local_irq_restore(flags); + + return last; +} + +void show_regs(struct pt_regs * regs) +{ + int i, trap; + + printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n", + regs->nip, regs->link, regs->gpr[1], regs, regs->trap, + print_tainted()); + printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", + regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, + regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, + regs->msr&MSR_IR ? 1 : 0, + regs->msr&MSR_DR ? 1 : 0); + trap = TRAP(regs); + if (trap == 0x300 || trap == 0x600) + printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); + printk("TASK = %p[%d] '%s' THREAD: %p\n", + current, current->pid, current->comm, current->thread_info); + printk("Last syscall: %ld ", current->thread.last_syscall); + +#ifdef CONFIG_SMP + printk(" CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 32; i++) { + long r; + if ((i % 8) == 0) + printk("\n" KERN_INFO "GPR%02d: ", i); + if (__get_user(r, ®s->gpr[i])) + break; + printk("%08lX ", r); + if (i == 12 && !FULL_REGS(regs)) + break; + } + printk("\n"); +#ifdef CONFIG_KALLSYMS + /* + * Lookup NIP late so we have the best change of getting the + * above info out without failing + */ + printk("NIP [%08lx] ", regs->nip); + print_symbol("%s\n", regs->nip); + printk("LR [%08lx] ", regs->link); + print_symbol("%s\n", regs->link); +#endif + show_stack(current, (unsigned long *) regs->gpr[1]); +} + +void exit_thread(void) +{ +#ifndef CONFIG_SMP + if (last_task_used_math == current) + last_task_used_math = NULL; +#ifdef CONFIG_ALTIVEC + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (last_task_used_spe == current) + last_task_used_spe = NULL; +#endif +#endif /* CONFIG_SMP */ +} + +void flush_thread(void) +{ +#ifndef CONFIG_SMP + if (last_task_used_math == current) + last_task_used_math = NULL; +#ifdef CONFIG_ALTIVEC + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (last_task_used_spe == current) + last_task_used_spe = NULL; +#endif +#endif /* CONFIG_SMP */ + +#ifdef CONFIG_PPC64 /* for now */ + if (current->thread.dabr) { + current->thread.dabr = 0; + set_dabr(0); + } +#endif +} + +void +release_thread(struct task_struct *t) +{ +} + +/* + * This gets called before we allocate a new thread and copy + * the current task into it. + */ +void prepare_to_copy(struct task_struct *tsk) +{ + flush_fp_to_thread(current); + flush_altivec_to_thread(current); + flush_spe_to_thread(current); +} + +/* + * Copy a thread.. + */ +int +copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct *p, struct pt_regs *regs) +{ + struct pt_regs *childregs, *kregs; + extern void ret_from_fork(void); + unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE; + unsigned long childframe; + + CHECK_FULL_REGS(regs); + /* Copy registers */ + sp -= sizeof(struct pt_regs); + childregs = (struct pt_regs *) sp; + *childregs = *regs; + if ((childregs->msr & MSR_PR) == 0) { + /* for kernel thread, set `current' and stackptr in new task */ + childregs->gpr[1] = sp + sizeof(struct pt_regs); + childregs->gpr[2] = (unsigned long) p; + p->thread.regs = NULL; /* no user register state */ + } else { + childregs->gpr[1] = usp; + p->thread.regs = childregs; + if (clone_flags & CLONE_SETTLS) + childregs->gpr[2] = childregs->gpr[6]; + } + childregs->gpr[3] = 0; /* Result from fork() */ + sp -= STACK_FRAME_OVERHEAD; + childframe = sp; + + /* + * The way this works is that at some point in the future + * some task will call _switch to switch to the new task. + * That will pop off the stack frame created below and start + * the new task running at ret_from_fork. The new task will + * do some house keeping and then return from the fork or clone + * system call, using the stack frame created above. + */ + sp -= sizeof(struct pt_regs); + kregs = (struct pt_regs *) sp; + sp -= STACK_FRAME_OVERHEAD; + p->thread.ksp = sp; + kregs->nip = (unsigned long)ret_from_fork; + + p->thread.last_syscall = -1; + + return 0; +} + +/* + * Set up a thread for executing a new program + */ +void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) +{ + set_fs(USER_DS); + memset(regs->gpr, 0, sizeof(regs->gpr)); + regs->ctr = 0; + regs->link = 0; + regs->xer = 0; + regs->ccr = 0; + regs->mq = 0; + regs->nip = nip; + regs->gpr[1] = sp; + regs->msr = MSR_USER; +#ifndef CONFIG_SMP + if (last_task_used_math == current) + last_task_used_math = NULL; +#ifdef CONFIG_ALTIVEC + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif +#ifdef CONFIG_SPE + if (last_task_used_spe == current) + last_task_used_spe = NULL; +#endif +#endif /* CONFIG_SMP */ + memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); + current->thread.fpscr = 0; +#ifdef CONFIG_ALTIVEC + memset(current->thread.vr, 0, sizeof(current->thread.vr)); + memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); + current->thread.vrsave = 0; + current->thread.used_vr = 0; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + memset(current->thread.evr, 0, sizeof(current->thread.evr)); + current->thread.acc = 0; + current->thread.spefscr = 0; + current->thread.used_spe = 0; +#endif /* CONFIG_SPE */ +} + +#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \ + | PR_FP_EXC_RES | PR_FP_EXC_INV) + +int set_fpexc_mode(struct task_struct *tsk, unsigned int val) +{ + struct pt_regs *regs = tsk->thread.regs; + + /* This is a bit hairy. If we are an SPE enabled processor + * (have embedded fp) we store the IEEE exception enable flags in + * fpexc_mode. fpexc_mode is also used for setting FP exception + * mode (asyn, precise, disabled) for 'Classic' FP. */ + if (val & PR_FP_EXC_SW_ENABLE) { +#ifdef CONFIG_SPE + tsk->thread.fpexc_mode = val & + (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); +#else + return -EINVAL; +#endif + } else { + /* on a CONFIG_SPE this does not hurt us. The bits that + * __pack_fe01 use do not overlap with bits used for + * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits + * on CONFIG_SPE implementations are reserved so writing to + * them does not change anything */ + if (val > PR_FP_EXC_PRECISE) + return -EINVAL; + tsk->thread.fpexc_mode = __pack_fe01(val); + if (regs != NULL && (regs->msr & MSR_FP) != 0) + regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) + | tsk->thread.fpexc_mode; + } + return 0; +} + +int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) +{ + unsigned int val; + + if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) +#ifdef CONFIG_SPE + val = tsk->thread.fpexc_mode; +#else + return -EINVAL; +#endif + else + val = __unpack_fe01(tsk->thread.fpexc_mode); + return put_user(val, (unsigned int __user *) adr); +} + +int sys_clone(unsigned long clone_flags, unsigned long usp, + int __user *parent_tidp, void __user *child_threadptr, + int __user *child_tidp, int p6, + struct pt_regs *regs) +{ + CHECK_FULL_REGS(regs); + if (usp == 0) + usp = regs->gpr[1]; /* stack pointer for child */ + return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp); +} + +int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, + struct pt_regs *regs) +{ + CHECK_FULL_REGS(regs); + return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL); +} + +int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, + struct pt_regs *regs) +{ + CHECK_FULL_REGS(regs); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], + regs, 0, NULL, NULL); +} + +int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs *regs) +{ + int error; + char * filename; + + filename = getname((char __user *) a0); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + flush_fp_to_thread(current); + flush_altivec_to_thread(current); + flush_spe_to_thread(current); + if (error == 0) { + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + } + putname(filename); +out: + return error; +} + +static int validate_sp(unsigned long sp, struct task_struct *p, + unsigned long nbytes) +{ + unsigned long stack_page = (unsigned long)p->thread_info; + + if (sp >= stack_page + sizeof(struct thread_struct) + && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; + +#ifdef CONFIG_IRQSTACKS + stack_page = (unsigned long) hardirq_ctx[task_cpu(p)]; + if (sp >= stack_page + sizeof(struct thread_struct) + && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; + + stack_page = (unsigned long) softirq_ctx[task_cpu(p)]; + if (sp >= stack_page + sizeof(struct thread_struct) + && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; +#endif + + return 0; +} + +void dump_stack(void) +{ + show_stack(current, NULL); +} + +EXPORT_SYMBOL(dump_stack); + +void show_stack(struct task_struct *tsk, unsigned long *stack) +{ + unsigned long sp, stack_top, prev_sp, ret; + int count = 0; + unsigned long next_exc = 0; + struct pt_regs *regs; + extern char ret_from_except, ret_from_except_full, ret_from_syscall; + + sp = (unsigned long) stack; + if (tsk == NULL) + tsk = current; + if (sp == 0) { + if (tsk == current) + asm("mr %0,1" : "=r" (sp)); + else + sp = tsk->thread.ksp; + } + + prev_sp = (unsigned long) (tsk->thread_info + 1); + stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE; + while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) { + if (count == 0) { + printk("Call trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + } else { + if (next_exc) { + ret = next_exc; + next_exc = 0; + } else + ret = *(unsigned long *)(sp + 4); + printk(" [%08lx] ", ret); +#ifdef CONFIG_KALLSYMS + print_symbol("%s", ret); + printk("\n"); +#endif + if (ret == (unsigned long) &ret_from_except + || ret == (unsigned long) &ret_from_except_full + || ret == (unsigned long) &ret_from_syscall) { + /* sp + 16 points to an exception frame */ + regs = (struct pt_regs *) (sp + 16); + if (sp + 16 + sizeof(*regs) <= stack_top) + next_exc = regs->nip; + } + } + ++count; + sp = *(unsigned long *)sp; + } +#ifndef CONFIG_KALLSYMS + if (count > 0) + printk("\n"); +#endif +} + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ip, sp; + int count = 0; + + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + sp = p->thread.ksp; + if (!validate_sp(sp, p, 16)) + return 0; + + do { + sp = *(unsigned long *)sp; + if (!validate_sp(sp, p, 16)) + return 0; + if (count > 0) { + ip = *(unsigned long *)(sp + 4); + if (!in_sched_functions(ip)) + return ip; + } + } while (count++ < 16); + return 0; +} +EXPORT_SYMBOL(get_wchan); diff --git a/arch/powerpc/kernel/semaphore.c b/arch/powerpc/kernel/semaphore.c new file mode 100644 index 000000000000..2f8c3c951394 --- /dev/null +++ b/arch/powerpc/kernel/semaphore.c @@ -0,0 +1,135 @@ +/* + * PowerPC-specific semaphore code. + * + * Copyright (C) 1999 Cort Dougan + * + * 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. + * + * April 2001 - Reworked by Paul Mackerras + * to eliminate the SMP races in the old version between the updates + * of `count' and `waking'. Now we use negative `count' values to + * indicate that some process(es) are waiting for the semaphore. + */ + +#include +#include +#include + +#include +#include +#include + +/* + * Atomically update sem->count. + * This does the equivalent of the following: + * + * old_count = sem->count; + * tmp = MAX(old_count, 0) + incr; + * sem->count = tmp; + * return old_count; + */ +static inline int __sem_update_count(struct semaphore *sem, int incr) +{ + int old_count, tmp; + + __asm__ __volatile__("\n" +"1: lwarx %0,0,%3\n" +" srawi %1,%0,31\n" +" andc %1,%0,%1\n" +" add %1,%1,%4\n" + PPC405_ERR77(0,%3) +" stwcx. %1,0,%3\n" +" bne 1b" + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (&sem->count), "r" (incr), "m" (sem->count) + : "cc"); + + return old_count; +} + +void __up(struct semaphore *sem) +{ + /* + * Note that we incremented count in up() before we came here, + * but that was ineffective since the result was <= 0, and + * any negative value of count is equivalent to 0. + * This ends up setting count to 1, unless count is now > 0 + * (i.e. because some other cpu has called up() in the meantime), + * in which case we just increment count. + */ + __sem_update_count(sem, 1); + wake_up(&sem->wait); +} +EXPORT_SYMBOL(__up); + +/* + * Note that when we come in to __down or __down_interruptible, + * we have already decremented count, but that decrement was + * ineffective since the result was < 0, and any negative value + * of count is equivalent to 0. + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. + */ +void __sched __down(struct semaphore *sem) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); + + /* + * Try to get the semaphore. If the count is > 0, then we've + * got the semaphore; we decrement count and exit the loop. + * If the count is 0 or negative, we set it to -1, indicating + * that we are asleep, and then sleep. + */ + while (__sem_update_count(sem, -1) <= 0) { + schedule(); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + } + remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); + + /* + * If there are any more sleepers, wake one of them up so + * that it can either get the semaphore, or set count to -1 + * indicating that there are still processes sleeping. + */ + wake_up(&sem->wait); +} +EXPORT_SYMBOL(__down); + +int __sched __down_interruptible(struct semaphore * sem) +{ + int retval = 0; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + __set_task_state(tsk, TASK_INTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); + + while (__sem_update_count(sem, -1) <= 0) { + if (signal_pending(current)) { + /* + * A signal is pending - give up trying. + * Set sem->count to 0 if it is negative, + * since we are no longer sleeping. + */ + __sem_update_count(sem, 0); + retval = -EINTR; + break; + } + schedule(); + set_task_state(tsk, TASK_INTERRUPTIBLE); + } + remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); + + wake_up(&sem->wait); + return retval; +} +EXPORT_SYMBOL(__down_interruptible); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c new file mode 100644 index 000000000000..c7afbbba0f36 --- /dev/null +++ b/arch/powerpc/kernel/traps.c @@ -0,0 +1,1047 @@ +/* + * arch/powerpc/kernel/traps.c + * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * 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. + * + * Modified by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras (paulus@samba.org) + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif +#include + +#ifdef CONFIG_DEBUGGER +int (*__debugger)(struct pt_regs *regs); +int (*__debugger_ipi)(struct pt_regs *regs); +int (*__debugger_bpt)(struct pt_regs *regs); +int (*__debugger_sstep)(struct pt_regs *regs); +int (*__debugger_iabr_match)(struct pt_regs *regs); +int (*__debugger_dabr_match)(struct pt_regs *regs); +int (*__debugger_fault_handler)(struct pt_regs *regs); + +EXPORT_SYMBOL(__debugger); +EXPORT_SYMBOL(__debugger_ipi); +EXPORT_SYMBOL(__debugger_bpt); +EXPORT_SYMBOL(__debugger_sstep); +EXPORT_SYMBOL(__debugger_iabr_match); +EXPORT_SYMBOL(__debugger_dabr_match); +EXPORT_SYMBOL(__debugger_fault_handler); +#endif + +struct notifier_block *powerpc_die_chain; +static DEFINE_SPINLOCK(die_notifier_lock); + +int register_die_notifier(struct notifier_block *nb) +{ + int err = 0; + unsigned long flags; + + spin_lock_irqsave(&die_notifier_lock, flags); + err = notifier_chain_register(&powerpc_die_chain, nb); + spin_unlock_irqrestore(&die_notifier_lock, flags); + return err; +} + +/* + * Trap & Exception support + */ + +static DEFINE_SPINLOCK(die_lock); + +int die(const char *str, struct pt_regs *regs, long err) +{ + static int die_counter; + int nl = 0; + + if (debugger(regs)) + return 1; + + console_verbose(); + spin_lock_irq(&die_lock); + bust_spinlocks(1); +#ifdef CONFIG_PMAC_BACKLIGHT + if (_machine == _MACH_Pmac) { + set_backlight_enable(1); + set_backlight_level(BACKLIGHT_MAX); + } +#endif + printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); + nl = 1; +#endif +#ifdef CONFIG_SMP + printk("SMP NR_CPUS=%d ", NR_CPUS); + nl = 1; +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC "); + nl = 1; +#endif +#ifdef CONFIG_NUMA + printk("NUMA "); + nl = 1; +#endif +#ifdef CONFIG_PPC64 + switch (systemcfg->platform) { + case PLATFORM_PSERIES: + printk("PSERIES "); + nl = 1; + break; + case PLATFORM_PSERIES_LPAR: + printk("PSERIES LPAR "); + nl = 1; + break; + case PLATFORM_ISERIES_LPAR: + printk("ISERIES LPAR "); + nl = 1; + break; + case PLATFORM_POWERMAC: + printk("POWERMAC "); + nl = 1; + break; + case PLATFORM_BPA: + printk("BPA "); + nl = 1; + break; + } +#endif + if (nl) + printk("\n"); + print_modules(); + show_regs(regs); + bust_spinlocks(0); + spin_unlock_irq(&die_lock); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + + if (panic_on_oops) { + panic("Fatal exception"); + } + do_exit(err); + + return 0; +} + +void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) +{ + siginfo_t info; + + if (!user_mode(regs)) { + if (die("Exception in kernel mode", regs, signr)) + return; + } + + memset(&info, 0, sizeof(info)); + info.si_signo = signr; + info.si_code = code; + info.si_addr = (void __user *) addr; + force_sig_info(signr, &info, current); + + /* + * Init gets no signals that it doesn't have a handler for. + * That's all very well, but if it has caused a synchronous + * exception and we ignore the resulting signal, it will just + * generate the same exception over and over again and we get + * nowhere. Better to kill it and let the kernel panic. + */ + if (current->pid == 1) { + __sighandler_t handler; + + spin_lock_irq(¤t->sighand->siglock); + handler = current->sighand->action[signr-1].sa.sa_handler; + spin_unlock_irq(¤t->sighand->siglock); + if (handler == SIG_DFL) { + /* init has generated a synchronous exception + and it doesn't have a handler for the signal */ + printk(KERN_CRIT "init has generated signal %d " + "but has no handler for it\n", signr); + do_exit(signr); + } + } +} + +#ifdef CONFIG_PPC64 +void system_reset_exception(struct pt_regs *regs) +{ + /* See if any machine dependent calls */ + if (ppc_md.system_reset_exception) + ppc_md.system_reset_exception(regs); + + die("System Reset", regs, SIGABRT); + + /* Must die if the interrupt is not recoverable */ + if (!(regs->msr & MSR_RI)) + panic("Unrecoverable System Reset"); + + /* What should we do here? We could issue a shutdown or hard reset. */ +} +#endif + +/* + * I/O accesses can cause machine checks on powermacs. + * Check if the NIP corresponds to the address of a sync + * instruction for which there is an entry in the exception + * table. + * Note that the 601 only takes a machine check on TEA + * (transfer error ack) signal assertion, and does not + * set any of the top 16 bits of SRR1. + * -- paulus. + */ +static inline int check_io_access(struct pt_regs *regs) +{ +#ifdef CONFIG_PPC_PMAC + unsigned long msr = regs->msr; + const struct exception_table_entry *entry; + unsigned int *nip = (unsigned int *)regs->nip; + + if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000))) + && (entry = search_exception_tables(regs->nip)) != NULL) { + /* + * Check that it's a sync instruction, or somewhere + * in the twi; isync; nop sequence that inb/inw/inl uses. + * As the address is in the exception table + * we should be able to read the instr there. + * For the debug message, we look at the preceding + * load or store. + */ + if (*nip == 0x60000000) /* nop */ + nip -= 2; + else if (*nip == 0x4c00012c) /* isync */ + --nip; + if (*nip == 0x7c0004ac || (*nip >> 26) == 3) { + /* sync or twi */ + unsigned int rb; + + --nip; + rb = (*nip >> 11) & 0x1f; + printk(KERN_DEBUG "%s bad port %lx at %p\n", + (*nip & 0x100)? "OUT to": "IN from", + regs->gpr[rb] - _IO_BASE, nip); + regs->msr |= MSR_RI; + regs->nip = entry->fixup; + return 1; + } + } +#endif /* CONFIG_PPC_PMAC */ + return 0; +} + +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) +/* On 4xx, the reason for the machine check or program exception + is in the ESR. */ +#define get_reason(regs) ((regs)->dsisr) +#ifndef CONFIG_FSL_BOOKE +#define get_mc_reason(regs) ((regs)->dsisr) +#else +#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) +#endif +#define REASON_FP ESR_FP +#define REASON_ILLEGAL (ESR_PIL | ESR_PUO) +#define REASON_PRIVILEGED ESR_PPR +#define REASON_TRAP ESR_PTR + +/* single-step stuff */ +#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC) +#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) + +#else +/* On non-4xx, the reason for the machine check or program + exception is in the MSR. */ +#define get_reason(regs) ((regs)->msr) +#define get_mc_reason(regs) ((regs)->msr) +#define REASON_FP 0x100000 +#define REASON_ILLEGAL 0x80000 +#define REASON_PRIVILEGED 0x40000 +#define REASON_TRAP 0x20000 + +#define single_stepping(regs) ((regs)->msr & MSR_SE) +#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) +#endif + +/* + * This is "fall-back" implementation for configurations + * which don't provide platform-specific machine check info + */ +void __attribute__ ((weak)) +platform_machine_check(struct pt_regs *regs) +{ +} + +void MachineCheckException(struct pt_regs *regs) +{ +#ifdef CONFIG_PPC64 + int recover = 0; + + /* See if any machine dependent calls */ + if (ppc_md.machine_check_exception) + recover = ppc_md.machine_check_exception(regs); + + if (recover) + return; +#else + unsigned long reason = get_mc_reason(regs); + + if (user_mode(regs)) { + regs->msr |= MSR_RI; + _exception(SIGBUS, regs, BUS_ADRERR, regs->nip); + return; + } + +#if defined(CONFIG_8xx) && defined(CONFIG_PCI) + /* the qspan pci read routines can cause machine checks -- Cort */ + bad_page_fault(regs, regs->dar, SIGBUS); + return; +#endif + + if (debugger_fault_handler(regs)) { + regs->msr |= MSR_RI; + return; + } + + if (check_io_access(regs)) + return; + +#if defined(CONFIG_4xx) && !defined(CONFIG_440A) + if (reason & ESR_IMCP) { + printk("Instruction"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } else + printk("Data"); + printk(" machine check in kernel mode.\n"); +#elif defined(CONFIG_440A) + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & MCSR_DCFP) + printk("D-Cache Flush Parity Error\n"); + if (mcsr & MCSR_IMPE) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } +#elif defined (CONFIG_E500) + printk("Machine check in kernel mode.\n"); + printk("Caused by (from MCSR=%lx): ", reason); + + if (reason & MCSR_MCP) + printk("Machine Check Signal\n"); + if (reason & MCSR_ICPERR) + printk("Instruction Cache Parity Error\n"); + if (reason & MCSR_DCP_PERR) + printk("Data Cache Push Parity Error\n"); + if (reason & MCSR_DCPERR) + printk("Data Cache Parity Error\n"); + if (reason & MCSR_GL_CI) + printk("Guarded Load or Cache-Inhibited stwcx.\n"); + if (reason & MCSR_BUS_IAERR) + printk("Bus - Instruction Address Error\n"); + if (reason & MCSR_BUS_RAERR) + printk("Bus - Read Address Error\n"); + if (reason & MCSR_BUS_WAERR) + printk("Bus - Write Address Error\n"); + if (reason & MCSR_BUS_IBERR) + printk("Bus - Instruction Data Error\n"); + if (reason & MCSR_BUS_RBERR) + printk("Bus - Read Data Bus Error\n"); + if (reason & MCSR_BUS_WBERR) + printk("Bus - Read Data Bus Error\n"); + if (reason & MCSR_BUS_IPERR) + printk("Bus - Instruction Parity Error\n"); + if (reason & MCSR_BUS_RPERR) + printk("Bus - Read Parity Error\n"); +#elif defined (CONFIG_E200) + printk("Machine check in kernel mode.\n"); + printk("Caused by (from MCSR=%lx): ", reason); + + if (reason & MCSR_MCP) + printk("Machine Check Signal\n"); + if (reason & MCSR_CP_PERR) + printk("Cache Push Parity Error\n"); + if (reason & MCSR_CPERR) + printk("Cache Parity Error\n"); + if (reason & MCSR_EXCP_ERR) + printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n"); + if (reason & MCSR_BUS_IRERR) + printk("Bus - Read Bus Error on instruction fetch\n"); + if (reason & MCSR_BUS_DRERR) + printk("Bus - Read Bus Error on data load\n"); + if (reason & MCSR_BUS_WRERR) + printk("Bus - Write Bus Error on buffered store or cache line push\n"); +#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ + printk("Machine check in kernel mode.\n"); + printk("Caused by (from SRR1=%lx): ", reason); + switch (reason & 0x601F0000) { + case 0x80000: + printk("Machine check signal\n"); + break; + case 0: /* for 601 */ + case 0x40000: + case 0x140000: /* 7450 MSS error and TEA */ + printk("Transfer error ack signal\n"); + break; + case 0x20000: + printk("Data parity error signal\n"); + break; + case 0x10000: + printk("Address parity error signal\n"); + break; + case 0x20000000: + printk("L1 Data Cache error\n"); + break; + case 0x40000000: + printk("L1 Instruction Cache error\n"); + break; + case 0x00100000: + printk("L2 data cache parity error\n"); + break; + default: + printk("Unknown values in msr\n"); + } +#endif /* CONFIG_4xx */ + + /* + * Optional platform-provided routine to print out + * additional info, e.g. bus error registers. + */ + platform_machine_check(regs); +#endif /* CONFIG_PPC64 */ + + if (debugger_fault_handler(regs)) + return; + die("Machine check", regs, SIGBUS); + + /* Must die if the interrupt is not recoverable */ + if (!(regs->msr & MSR_RI)) + panic("Unrecoverable Machine check"); +} + +void SMIException(struct pt_regs *regs) +{ + die("System Management Interrupt", regs, SIGABRT); +} + +void UnknownException(struct pt_regs *regs) +{ + printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", + regs->nip, regs->msr, regs->trap); + + _exception(SIGTRAP, regs, 0, 0); +} + +void InstructionBreakpoint(struct pt_regs *regs) +{ + if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, + 5, SIGTRAP) == NOTIFY_STOP) + return; + if (debugger_iabr_match(regs)) + return; + _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); +} + +void RunModeException(struct pt_regs *regs) +{ + _exception(SIGTRAP, regs, 0, 0); +} + +void SingleStepException(struct pt_regs *regs) +{ + regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ + + if (notify_die(DIE_SSTEP, "single_step", regs, 5, + 5, SIGTRAP) == NOTIFY_STOP) + return; + if (debugger_sstep(regs)) + return; + + _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); +} + +/* + * After we have successfully emulated an instruction, we have to + * check if the instruction was being single-stepped, and if so, + * pretend we got a single-step exception. This was pointed out + * by Kumar Gala. -- paulus + */ +static void emulate_single_step(struct pt_regs *regs) +{ + if (single_stepping(regs)) { + clear_single_step(regs); + _exception(SIGTRAP, regs, TRAP_TRACE, 0); + } +} + +/* Illegal instruction emulation support. Originally written to + * provide the PVR to user applications using the mfspr rd, PVR. + * Return non-zero if we can't emulate, or -EFAULT if the associated + * memory access caused an access fault. Return zero on success. + * + * There are a couple of ways to do this, either "decode" the instruction + * or directly match lots of bits. In this case, matching lots of + * bits is faster and easier. + * + */ +#define INST_MFSPR_PVR 0x7c1f42a6 +#define INST_MFSPR_PVR_MASK 0xfc1fffff + +#define INST_DCBA 0x7c0005ec +#define INST_DCBA_MASK 0x7c0007fe + +#define INST_MCRXR 0x7c000400 +#define INST_MCRXR_MASK 0x7c0007fe + +#define INST_STRING 0x7c00042a +#define INST_STRING_MASK 0x7c0007fe +#define INST_STRING_GEN_MASK 0x7c00067e +#define INST_LSWI 0x7c0004aa +#define INST_LSWX 0x7c00042a +#define INST_STSWI 0x7c0005aa +#define INST_STSWX 0x7c00052a + +static int emulate_string_inst(struct pt_regs *regs, u32 instword) +{ + u8 rT = (instword >> 21) & 0x1f; + u8 rA = (instword >> 16) & 0x1f; + u8 NB_RB = (instword >> 11) & 0x1f; + u32 num_bytes; + unsigned long EA; + int pos = 0; + + /* Early out if we are an invalid form of lswx */ + if ((instword & INST_STRING_MASK) == INST_LSWX) + if ((rT == rA) || (rT == NB_RB)) + return -EINVAL; + + EA = (rA == 0) ? 0 : regs->gpr[rA]; + + switch (instword & INST_STRING_MASK) { + case INST_LSWX: + case INST_STSWX: + EA += NB_RB; + num_bytes = regs->xer & 0x7f; + break; + case INST_LSWI: + case INST_STSWI: + num_bytes = (NB_RB == 0) ? 32 : NB_RB; + break; + default: + return -EINVAL; + } + + while (num_bytes != 0) + { + u8 val; + u32 shift = 8 * (3 - (pos & 0x3)); + + switch ((instword & INST_STRING_MASK)) { + case INST_LSWX: + case INST_LSWI: + if (get_user(val, (u8 __user *)EA)) + return -EFAULT; + /* first time updating this reg, + * zero it out */ + if (pos == 0) + regs->gpr[rT] = 0; + regs->gpr[rT] |= val << shift; + break; + case INST_STSWI: + case INST_STSWX: + val = regs->gpr[rT] >> shift; + if (put_user(val, (u8 __user *)EA)) + return -EFAULT; + break; + } + /* move EA to next address */ + EA += 1; + num_bytes--; + + /* manage our position within the register */ + if (++pos == 4) { + pos = 0; + if (++rT == 32) + rT = 0; + } + } + + return 0; +} + +static int emulate_instruction(struct pt_regs *regs) +{ + u32 instword; + u32 rd; + + if (!user_mode(regs)) + return -EINVAL; + CHECK_FULL_REGS(regs); + + if (get_user(instword, (u32 __user *)(regs->nip))) + return -EFAULT; + + /* Emulate the mfspr rD, PVR. */ + if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { + rd = (instword >> 21) & 0x1f; + regs->gpr[rd] = mfspr(SPRN_PVR); + return 0; + } + + /* Emulating the dcba insn is just a no-op. */ + if ((instword & INST_DCBA_MASK) == INST_DCBA) + return 0; + + /* Emulate the mcrxr insn. */ + if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { + int shift = (instword >> 21) & 0x1c; + unsigned long msk = 0xf0000000UL >> shift; + + regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); + regs->xer &= ~0xf0000000UL; + return 0; + } + + /* Emulate load/store string insn. */ + if ((instword & INST_STRING_GEN_MASK) == INST_STRING) + return emulate_string_inst(regs, instword); + + return -EINVAL; +} + +/* + * Look through the list of trap instructions that are used for BUG(), + * BUG_ON() and WARN_ON() and see if we hit one. At this point we know + * that the exception was caused by a trap instruction of some kind. + * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 + * otherwise. + */ +extern struct bug_entry __start___bug_table[], __stop___bug_table[]; + +#ifndef CONFIG_MODULES +#define module_find_bug(x) NULL +#endif + +struct bug_entry *find_bug(unsigned long bugaddr) +{ + struct bug_entry *bug; + + for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) + if (bugaddr == bug->bug_addr) + return bug; + return module_find_bug(bugaddr); +} + +int check_bug_trap(struct pt_regs *regs) +{ + struct bug_entry *bug; + unsigned long addr; + + if (regs->msr & MSR_PR) + return 0; /* not in kernel */ + addr = regs->nip; /* address of trap instruction */ + if (addr < PAGE_OFFSET) + return 0; + bug = find_bug(regs->nip); + if (bug == NULL) + return 0; + if (bug->line & BUG_WARNING_TRAP) { + /* this is a WARN_ON rather than BUG/BUG_ON */ +#ifdef CONFIG_XMON + xmon_printf(KERN_ERR "Badness in %s at %s:%d\n", + bug->function, bug->file, + bug->line & ~BUG_WARNING_TRAP); +#endif /* CONFIG_XMON */ + printk(KERN_ERR "Badness in %s at %s:%d\n", + bug->function, bug->file, + bug->line & ~BUG_WARNING_TRAP); + dump_stack(); + return 1; + } +#ifdef CONFIG_XMON + xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n", + bug->function, bug->file, bug->line); + xmon(regs); +#endif /* CONFIG_XMON */ + printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", + bug->function, bug->file, bug->line); + + return 0; +} + +void ProgramCheckException(struct pt_regs *regs) +{ + unsigned int reason = get_reason(regs); + extern int do_mathemu(struct pt_regs *regs); + +#ifdef CONFIG_MATH_EMULATION + /* (reason & REASON_ILLEGAL) would be the obvious thing here, + * but there seems to be a hardware bug on the 405GP (RevD) + * that means ESR is sometimes set incorrectly - either to + * ESR_DST (!?) or 0. In the process of chasing this with the + * hardware people - not sure if it can happen on any illegal + * instruction or only on FP instructions, whether there is a + * pattern to occurences etc. -dgibson 31/Mar/2003 */ + if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) { + emulate_single_step(regs); + return; + } +#endif /* CONFIG_MATH_EMULATION */ + + if (reason & REASON_FP) { + /* IEEE FP exception */ + int code = 0; + u32 fpscr; + + /* We must make sure the FP state is consistent with + * our MSR_FP in regs + */ + preempt_disable(); + if (regs->msr & MSR_FP) + giveup_fpu(current); + preempt_enable(); + + fpscr = current->thread.fpscr; + fpscr &= fpscr << 22; /* mask summary bits with enables */ + if (fpscr & FPSCR_VX) + code = FPE_FLTINV; + else if (fpscr & FPSCR_OX) + code = FPE_FLTOVF; + else if (fpscr & FPSCR_UX) + code = FPE_FLTUND; + else if (fpscr & FPSCR_ZX) + code = FPE_FLTDIV; + else if (fpscr & FPSCR_XX) + code = FPE_FLTRES; + _exception(SIGFPE, regs, code, regs->nip); + return; + } + + if (reason & REASON_TRAP) { + /* trap exception */ + if (debugger_bpt(regs)) + return; + if (check_bug_trap(regs)) { + regs->nip += 4; + return; + } + _exception(SIGTRAP, regs, TRAP_BRKPT, 0); + return; + } + + /* Try to emulate it if we should. */ + if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { + switch (emulate_instruction(regs)) { + case 0: + regs->nip += 4; + emulate_single_step(regs); + return; + case -EFAULT: + _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); + return; + } + } + + if (reason & REASON_PRIVILEGED) + _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); + else + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); +} + +void AlignmentException(struct pt_regs *regs) +{ + int fixed; + + fixed = fix_alignment(regs); + + if (fixed == 1) { + regs->nip += 4; /* skip over emulated instruction */ + emulate_single_step(regs); + return; + } + + /* Operand address was bad */ + if (fixed == -EFAULT) { + if (user_mode(regs)) + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); + else + /* Search exception table */ + bad_page_fault(regs, regs->dar, SIGSEGV); + return; + } + _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); +} + +void StackOverflow(struct pt_regs *regs) +{ + printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", + current, regs->gpr[1]); + debugger(regs); + show_regs(regs); + panic("kernel stack overflow"); +} + +void nonrecoverable_exception(struct pt_regs *regs) +{ + printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n", + regs->nip, regs->msr); + debugger(regs); + die("nonrecoverable exception", regs, SIGKILL); +} + +void trace_syscall(struct pt_regs *regs) +{ + printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", + current, current->pid, regs->nip, regs->link, regs->gpr[0], + regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); +} + +#ifdef CONFIG_8xx +void SoftwareEmulation(struct pt_regs *regs) +{ + extern int do_mathemu(struct pt_regs *); + extern int Soft_emulate_8xx(struct pt_regs *); + int errcode; + + CHECK_FULL_REGS(regs); + + if (!user_mode(regs)) { + debugger(regs); + die("Kernel Mode Software FPU Emulation", regs, SIGFPE); + } + +#ifdef CONFIG_MATH_EMULATION + errcode = do_mathemu(regs); +#else + errcode = Soft_emulate_8xx(regs); +#endif + if (errcode) { + if (errcode > 0) + _exception(SIGFPE, regs, 0, 0); + else if (errcode == -EFAULT) + _exception(SIGSEGV, regs, 0, 0); + else + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + } else + emulate_single_step(regs); +} +#endif /* CONFIG_8xx */ + +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) + +void DebugException(struct pt_regs *regs, unsigned long debug_status) +{ + if (debug_status & DBSR_IC) { /* instruction completion */ + regs->msr &= ~MSR_DE; + if (user_mode(regs)) { + current->thread.dbcr0 &= ~DBCR0_IC; + } else { + /* Disable instruction completion */ + mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC); + /* Clear the instruction completion event */ + mtspr(SPRN_DBSR, DBSR_IC); + if (debugger_sstep(regs)) + return; + } + _exception(SIGTRAP, regs, TRAP_TRACE, 0); + } +} +#endif /* CONFIG_4xx || CONFIG_BOOKE */ + +#if !defined(CONFIG_TAU_INT) +void TAUException(struct pt_regs *regs) +{ + printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n", + regs->nip, regs->msr, regs->trap, print_tainted()); +} +#endif /* CONFIG_INT_TAU */ + +void AltivecUnavailException(struct pt_regs *regs) +{ + static int kernel_altivec_count; + +#ifndef CONFIG_ALTIVEC + if (user_mode(regs)) { + /* A user program has executed an altivec instruction, + but this kernel doesn't support altivec. */ + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + return; + } +#endif + /* The kernel has executed an altivec instruction without + first enabling altivec. Whinge but let it do it. */ + if (++kernel_altivec_count < 10) + printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", + current, regs->nip); + regs->msr |= MSR_VEC; +} + +#ifdef CONFIG_ALTIVEC +void AltivecAssistException(struct pt_regs *regs) +{ + int err; + + preempt_disable(); + if (regs->msr & MSR_VEC) + giveup_altivec(current); + preempt_enable(); + if (!user_mode(regs)) { + printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" + " at %lx\n", regs->nip); + die("Kernel Altivec assist exception", regs, SIGILL); + } + + err = emulate_altivec(regs); + if (err == 0) { + regs->nip += 4; /* skip emulated instruction */ + emulate_single_step(regs); + return; + } + + if (err == -EFAULT) { + /* got an error reading the instruction */ + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip); + } else { + /* didn't recognize the instruction */ + /* XXX quick hack for now: set the non-Java bit in the VSCR */ + if (printk_ratelimit()) + printk(KERN_ERR "Unrecognized altivec instruction " + "in %s at %lx\n", current->comm, regs->nip); + current->thread.vscr.u[3] |= 0x10000; + } +} +#endif /* CONFIG_ALTIVEC */ + +#ifdef CONFIG_E500 +void PerformanceMonitorException(struct pt_regs *regs) +{ + perf_irq(regs); +} +#endif + +#ifdef CONFIG_FSL_BOOKE +void CacheLockingException(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + /* We treat cache locking instructions from the user + * as priv ops, in the future we could try to do + * something smarter + */ + if (error_code & (ESR_DLK|ESR_ILK)) + _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); + return; +} +#endif /* CONFIG_FSL_BOOKE */ + +#ifdef CONFIG_SPE +void SPEFloatingPointException(struct pt_regs *regs) +{ + unsigned long spefscr; + int fpexc_mode; + int code = 0; + + spefscr = current->thread.spefscr; + fpexc_mode = current->thread.fpexc_mode; + + /* Hardware does not neccessarily set sticky + * underflow/overflow/invalid flags */ + if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) { + code = FPE_FLTOVF; + spefscr |= SPEFSCR_FOVFS; + } + else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) { + code = FPE_FLTUND; + spefscr |= SPEFSCR_FUNFS; + } + else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV)) + code = FPE_FLTDIV; + else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) { + code = FPE_FLTINV; + spefscr |= SPEFSCR_FINVS; + } + else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES)) + code = FPE_FLTRES; + + current->thread.spefscr = spefscr; + + _exception(SIGFPE, regs, code, regs->nip); + return; +} +#endif + +#ifdef CONFIG_BOOKE_WDT +/* + * Default handler for a Watchdog exception, + * spins until a reboot occurs + */ +void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs) +{ + /* Generic WatchdogHandler, implement your own */ + mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE)); + return; +} + +void WatchdogException(struct pt_regs *regs) +{ + printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n"); + WatchdogHandler(regs); +} +#endif + +void __init trap_init(void) +{ +} diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S new file mode 100644 index 000000000000..12cb90bc209c --- /dev/null +++ b/arch/powerpc/kernel/vector.S @@ -0,0 +1,197 @@ +#include +#include +#include + +/* + * The routines below are in assembler so we can closely control the + * usage of floating-point registers. These routines must be called + * with preempt disabled. + */ +#ifdef CONFIG_PPC32 + .data +fpzero: + .long 0 +fpone: + .long 0x3f800000 /* 1.0 in single-precision FP */ +fphalf: + .long 0x3f000000 /* 0.5 in single-precision FP */ + +#define LDCONST(fr, name) \ + lis r11,name@ha; \ + lfs fr,name@l(r11) +#else + + .section ".toc","aw" +fpzero: + .tc FD_0_0[TC],0 +fpone: + .tc FD_3ff00000_0[TC],0x3ff0000000000000 /* 1.0 */ +fphalf: + .tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */ + +#define LDCONST(fr, name) \ + lfd fr,name@toc(r2) +#endif + + .text +/* + * Internal routine to enable floating point and set FPSCR to 0. + * Don't call it from C; it doesn't use the normal calling convention. + */ +fpenable: +#ifdef CONFIG_PPC32 + stwu r1,-64(r1) +#else + stdu r1,-64(r1) +#endif + mfmsr r10 + ori r11,r10,MSR_FP + mtmsr r11 + isync + stfd fr0,24(r1) + stfd fr1,16(r1) + stfd fr31,8(r1) + LDCONST(fr1, fpzero) + mffs fr31 + mtfsf 0xff,fr1 + blr + +fpdisable: + mtlr r12 + mtfsf 0xff,fr31 + lfd fr31,8(r1) + lfd fr1,16(r1) + lfd fr0,24(r1) + mtmsr r10 + isync + addi r1,r1,64 + blr + +/* + * Vector add, floating point. + */ +_GLOBAL(vaddfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fadds fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector subtract, floating point. + */ +_GLOBAL(vsubfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fsubs fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector multiply and add, floating point. + */ +_GLOBAL(vmaddfp) + mflr r12 + bl fpenable + stfd fr2,32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fmadds fr0,fr0,fr2,fr1 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,32(r1) + b fpdisable + +/* + * Vector negative multiply and subtract, floating point. + */ +_GLOBAL(vnmsubfp) + mflr r12 + bl fpenable + stfd fr2,32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fnmsubs fr0,fr0,fr2,fr1 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,32(r1) + b fpdisable + +/* + * Vector reciprocal estimate. We just compute 1.0/x. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrefp) + mflr r12 + bl fpenable + li r0,4 + LDCONST(fr1, fpone) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + fdivs fr0,fr1,fr0 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector reciprocal square-root estimate, floating point. + * We use the frsqrte instruction for the initial estimate followed + * by 2 iterations of Newton-Raphson to get sufficient accuracy. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrsqrtefp) + mflr r12 + bl fpenable + stfd fr2,32(r1) + stfd fr3,40(r1) + stfd fr4,48(r1) + stfd fr5,56(r1) + li r0,4 + LDCONST(fr4, fpone) + LDCONST(fr5, fphalf) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + frsqrte fr1,fr0 /* r = frsqrte(s) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + stfsx fr1,r3,r6 + addi r6,r6,4 + bdnz 1b + lfd fr5,56(r1) + lfd fr4,48(r1) + lfd fr3,40(r1) + lfd fr2,32(r1) + b fpdisable diff --git a/arch/powerpc/kernel/vmlinux.lds b/arch/powerpc/kernel/vmlinux.lds new file mode 100644 index 000000000000..d62c288a81d0 --- /dev/null +++ b/arch/powerpc/kernel/vmlinux.lds @@ -0,0 +1,174 @@ +/* Align . to a 8 byte boundary equals to maximum function alignment. */ +/* sched.text is aling to function alignment to secure we have same + * address even at second ld pass when generating System.map */ +/* spinlock.text is aling to function alignment to secure we have same + * address even at second ld pass when generating System.map */ + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to + the beginning of the section so we begin them at 0. */ + /* Stabs debugging sections. */ +OUTPUT_ARCH(powerpc:common) +jiffies = jiffies_64 + 4; +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } +/* .init : { *(.init) } =0*/ + .plt : { *(.plt) } + .text : + { + *(.text) + . = ALIGN(8); __sched_text_start = .; *(.sched.text) __sched_text_end = .; + . = ALIGN(8); __lock_text_start = .; *(.spinlock.text) __lock_text_end = .; + *(.fixup) + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; + } + _etext = .; + PROVIDE (etext = .); + .rodata : AT(ADDR(.rodata) - 0) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1 : AT(ADDR(.rodata1) - 0) { *(.rodata1) } .pci_fixup : AT(ADDR(.pci_fixup) - 0) { __start_pci_fixups_early = .; *(.pci_fixup_early) __end_pci_fixups_early = .; __start_pci_fixups_header = .; *(.pci_fixup_header) __end_pci_fixups_header = .; __start_pci_fixups_final = .; *(.pci_fixup_final) __end_pci_fixups_final = .; __start_pci_fixups_enable = .; *(.pci_fixup_enable) __end_pci_fixups_enable = .; } __ksymtab : AT(ADDR(__ksymtab) - 0) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - 0) { __start___ksymtab_gpl = .; *(__ksymtab_gpl) __stop___ksymtab_gpl = .; } __kcrctab : AT(ADDR(__kcrctab) - 0) { __start___kcrctab = .; *(__kcrctab) __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - 0) { __start___kcrctab_gpl = .; *(__kcrctab_gpl) __stop___kcrctab_gpl = .; } __ksymtab_strings : AT(ADDR(__ksymtab_strings) - 0) { *(__ksymtab_strings) } __param : AT(ADDR(__param) - 0) { __start___param = .; *(__param) __stop___param = .; } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .fixup : { *(.fixup) } + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + __bug_table : { + __start___bug_table = .; + *(__bug_table) + __stop___bug_table = .; + } + /* Read-write section, merged into data segment: */ + . = ALIGN(4096); + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; + PROVIDE (edata = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + /* .exit.text is discarded at runtime, not link time, + to deal with references from __bug_table */ + .exit.text : { *(.exit.text) } + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + + .security_initcall.init : AT(ADDR(.security_initcall.init) - 0) { __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .; } + + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; + + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + _sextratext = .; + _eextratext = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + __bss_stop = .; + + _end = . ; + PROVIDE (end = .); + + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + *(.exit.data) + } +} diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..09c6525cfa61 --- /dev/null +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -0,0 +1,172 @@ +#include + +OUTPUT_ARCH(powerpc:common) +jiffies = jiffies_64 + 4; +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } +/* .init : { *(.init) } =0*/ + .plt : { *(.plt) } + .text : + { + *(.text) + SCHED_TEXT + LOCK_TEXT + *(.fixup) + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; + } + _etext = .; + PROVIDE (etext = .); + + RODATA + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + .fixup : { *(.fixup) } + + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + __bug_table : { + __start___bug_table = .; + *(__bug_table) + __stop___bug_table = .; + } + + /* Read-write section, merged into data segment: */ + . = ALIGN(4096); + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; + PROVIDE (edata = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + /* .exit.text is discarded at runtime, not link time, + to deal with references from __bug_table */ + .exit.text : { *(.exit.text) } + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + + SECURITY_INIT + + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; + + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + _sextratext = .; + _eextratext = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + __bss_stop = .; + + _end = . ; + PROVIDE (end = .); + + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + *(.exit.data) + } +} diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile new file mode 100644 index 000000000000..347f9798e433 --- /dev/null +++ b/arch/powerpc/lib/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for ppc-specific library files.. +# + +obj-y := strcase.o string.o +obj-$(CONFIG_PPC32) += div64.o copy32.o checksum.o +obj-$(CONFIG_PPC64) += copypage.o copyuser.o memcpy.o usercopy.o \ + sstep.o checksum64.o +obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/powerpc/lib/checksum.S b/arch/powerpc/lib/checksum.S new file mode 100644 index 000000000000..7874e8a80455 --- /dev/null +++ b/arch/powerpc/lib/checksum.S @@ -0,0 +1,225 @@ +/* + * This file contains assembly-language implementations + * of IP-style 1's complement checksum routines. + * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * 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. + * + * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au). + */ + +#include +#include +#include +#include + + .text + +/* + * ip_fast_csum(buf, len) -- Optimized for IP header + * len is in words and is always >= 5. + */ +_GLOBAL(ip_fast_csum) + lwz r0,0(r3) + lwzu r5,4(r3) + addic. r4,r4,-2 + addc r0,r0,r5 + mtctr r4 + blelr- +1: lwzu r4,4(r3) + adde r0,r0,r4 + bdnz 1b + addze r0,r0 /* add in final carry */ + rlwinm r3,r0,16,0,31 /* fold two halves together */ + add r3,r0,r3 + not r3,r3 + srwi r3,r3,16 + blr + +/* + * Compute checksum of TCP or UDP pseudo-header: + * csum_tcpudp_magic(saddr, daddr, len, proto, sum) + */ +_GLOBAL(csum_tcpudp_magic) + rlwimi r5,r6,16,0,15 /* put proto in upper half of len */ + addc r0,r3,r4 /* add 4 32-bit words together */ + adde r0,r0,r5 + adde r0,r0,r7 + addze r0,r0 /* add in final carry */ + rlwinm r3,r0,16,0,31 /* fold two halves together */ + add r3,r0,r3 + not r3,r3 + srwi r3,r3,16 + blr + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * csum_partial(buff, len, sum) + */ +_GLOBAL(csum_partial) + addic r0,r5,0 + subi r3,r3,4 + srwi. r6,r4,2 + beq 3f /* if we're doing < 4 bytes */ + andi. r5,r3,2 /* Align buffer to longword boundary */ + beq+ 1f + lhz r5,4(r3) /* do 2 bytes to get aligned */ + addi r3,r3,2 + subi r4,r4,2 + addc r0,r0,r5 + srwi. r6,r4,2 /* # words to do */ + beq 3f +1: mtctr r6 +2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */ + adde r0,r0,r5 /* be unnecessary to unroll this loop */ + bdnz 2b + andi. r4,r4,3 +3: cmpwi 0,r4,2 + blt+ 4f + lhz r5,4(r3) + addi r3,r3,2 + subi r4,r4,2 + adde r0,r0,r5 +4: cmpwi 0,r4,1 + bne+ 5f + lbz r5,4(r3) + slwi r5,r5,8 /* Upper byte of word */ + adde r0,r0,r5 +5: addze r3,r0 /* add in final carry */ + blr + +/* + * Computes the checksum of a memory block at src, length len, + * and adds in "sum" (32-bit), while copying the block to dst. + * If an access exception occurs on src or dst, it stores -EFAULT + * to *src_err or *dst_err respectively, and (for an error on + * src) zeroes the rest of dst. + * + * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) + */ +_GLOBAL(csum_partial_copy_generic) + addic r0,r6,0 + subi r3,r3,4 + subi r4,r4,4 + srwi. r6,r5,2 + beq 3f /* if we're doing < 4 bytes */ + andi. r9,r4,2 /* Align dst to longword boundary */ + beq+ 1f +81: lhz r6,4(r3) /* do 2 bytes to get aligned */ + addi r3,r3,2 + subi r5,r5,2 +91: sth r6,4(r4) + addi r4,r4,2 + addc r0,r0,r6 + srwi. r6,r5,2 /* # words to do */ + beq 3f +1: srwi. r6,r5,4 /* # groups of 4 words to do */ + beq 10f + mtctr r6 +71: lwz r6,4(r3) +72: lwz r9,8(r3) +73: lwz r10,12(r3) +74: lwzu r11,16(r3) + adde r0,r0,r6 +75: stw r6,4(r4) + adde r0,r0,r9 +76: stw r9,8(r4) + adde r0,r0,r10 +77: stw r10,12(r4) + adde r0,r0,r11 +78: stwu r11,16(r4) + bdnz 71b +10: rlwinm. r6,r5,30,30,31 /* # words left to do */ + beq 13f + mtctr r6 +82: lwzu r9,4(r3) +92: stwu r9,4(r4) + adde r0,r0,r9 + bdnz 82b +13: andi. r5,r5,3 +3: cmpwi 0,r5,2 + blt+ 4f +83: lhz r6,4(r3) + addi r3,r3,2 + subi r5,r5,2 +93: sth r6,4(r4) + addi r4,r4,2 + adde r0,r0,r6 +4: cmpwi 0,r5,1 + bne+ 5f +84: lbz r6,4(r3) +94: stb r6,4(r4) + slwi r6,r6,8 /* Upper byte of word */ + adde r0,r0,r6 +5: addze r3,r0 /* add in final carry */ + blr + +/* These shouldn't go in the fixup section, since that would + cause the ex_table addresses to get out of order. */ + +src_error_4: + mfctr r6 /* update # bytes remaining from ctr */ + rlwimi r5,r6,4,0,27 + b 79f +src_error_1: + li r6,0 + subi r5,r5,2 +95: sth r6,4(r4) + addi r4,r4,2 +79: srwi. r6,r5,2 + beq 3f + mtctr r6 +src_error_2: + li r6,0 +96: stwu r6,4(r4) + bdnz 96b +3: andi. r5,r5,3 + beq src_error +src_error_3: + li r6,0 + mtctr r5 + addi r4,r4,3 +97: stbu r6,1(r4) + bdnz 97b +src_error: + cmpwi 0,r7,0 + beq 1f + li r6,-EFAULT + stw r6,0(r7) +1: addze r3,r0 + blr + +dst_error: + cmpwi 0,r8,0 + beq 1f + li r6,-EFAULT + stw r6,0(r8) +1: addze r3,r0 + blr + +.section __ex_table,"a" + .long 81b,src_error_1 + .long 91b,dst_error + .long 71b,src_error_4 + .long 72b,src_error_4 + .long 73b,src_error_4 + .long 74b,src_error_4 + .long 75b,dst_error + .long 76b,dst_error + .long 77b,dst_error + .long 78b,dst_error + .long 82b,src_error_2 + .long 92b,dst_error + .long 83b,src_error_3 + .long 93b,dst_error + .long 84b,src_error_3 + .long 94b,dst_error + .long 95b,dst_error + .long 96b,dst_error + .long 97b,dst_error diff --git a/arch/powerpc/lib/checksum64.S b/arch/powerpc/lib/checksum64.S new file mode 100644 index 000000000000..ef96c6c58efc --- /dev/null +++ b/arch/powerpc/lib/checksum64.S @@ -0,0 +1,229 @@ +/* + * This file contains assembly-language implementations + * of IP-style 1's complement checksum routines. + * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * 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. + * + * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au). + */ + +#include +#include +#include +#include + +/* + * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header + * len is in words and is always >= 5. + * + * In practice len == 5, but this is not guaranteed. So this code does not + * attempt to use doubleword instructions. + */ +_GLOBAL(ip_fast_csum) + lwz r0,0(r3) + lwzu r5,4(r3) + addic. r4,r4,-2 + addc r0,r0,r5 + mtctr r4 + blelr- +1: lwzu r4,4(r3) + adde r0,r0,r4 + bdnz 1b + addze r0,r0 /* add in final carry */ + rldicl r4,r0,32,0 /* fold two 32-bit halves together */ + add r0,r0,r4 + srdi r0,r0,32 + rlwinm r3,r0,16,0,31 /* fold two halves together */ + add r3,r0,r3 + not r3,r3 + srwi r3,r3,16 + blr + +/* + * Compute checksum of TCP or UDP pseudo-header: + * csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum) + * No real gain trying to do this specially for 64 bit, but + * the 32 bit addition may spill into the upper bits of + * the doubleword so we still must fold it down from 64. + */ +_GLOBAL(csum_tcpudp_magic) + rlwimi r5,r6,16,0,15 /* put proto in upper half of len */ + addc r0,r3,r4 /* add 4 32-bit words together */ + adde r0,r0,r5 + adde r0,r0,r7 + rldicl r4,r0,32,0 /* fold 64 bit value */ + add r0,r4,r0 + srdi r0,r0,32 + rlwinm r3,r0,16,0,31 /* fold two halves together */ + add r3,r0,r3 + not r3,r3 + srwi r3,r3,16 + blr + +/* + * Computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit). + * + * This code assumes at least halfword alignment, though the length + * can be any number of bytes. The sum is accumulated in r5. + * + * csum_partial(r3=buff, r4=len, r5=sum) + */ +_GLOBAL(csum_partial) + subi r3,r3,8 /* we'll offset by 8 for the loads */ + srdi. r6,r4,3 /* divide by 8 for doubleword count */ + addic r5,r5,0 /* clear carry */ + beq 3f /* if we're doing < 8 bytes */ + andi. r0,r3,2 /* aligned on a word boundary already? */ + beq+ 1f + lhz r6,8(r3) /* do 2 bytes to get aligned */ + addi r3,r3,2 + subi r4,r4,2 + addc r5,r5,r6 + srdi. r6,r4,3 /* recompute number of doublewords */ + beq 3f /* any left? */ +1: mtctr r6 +2: ldu r6,8(r3) /* main sum loop */ + adde r5,r5,r6 + bdnz 2b + andi. r4,r4,7 /* compute bytes left to sum after doublewords */ +3: cmpwi 0,r4,4 /* is at least a full word left? */ + blt 4f + lwz r6,8(r3) /* sum this word */ + addi r3,r3,4 + subi r4,r4,4 + adde r5,r5,r6 +4: cmpwi 0,r4,2 /* is at least a halfword left? */ + blt+ 5f + lhz r6,8(r3) /* sum this halfword */ + addi r3,r3,2 + subi r4,r4,2 + adde r5,r5,r6 +5: cmpwi 0,r4,1 /* is at least a byte left? */ + bne+ 6f + lbz r6,8(r3) /* sum this byte */ + slwi r6,r6,8 /* this byte is assumed to be the upper byte of a halfword */ + adde r5,r5,r6 +6: addze r5,r5 /* add in final carry */ + rldicl r4,r5,32,0 /* fold two 32-bit halves together */ + add r3,r4,r5 + srdi r3,r3,32 + blr + +/* + * Computes the checksum of a memory block at src, length len, + * and adds in "sum" (32-bit), while copying the block to dst. + * If an access exception occurs on src or dst, it stores -EFAULT + * to *src_err or *dst_err respectively, and (for an error on + * src) zeroes the rest of dst. + * + * This code needs to be reworked to take advantage of 64 bit sum+copy. + * However, due to tokenring halfword alignment problems this will be very + * tricky. For now we'll leave it until we instrument it somehow. + * + * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err) + */ +_GLOBAL(csum_partial_copy_generic) + addic r0,r6,0 + subi r3,r3,4 + subi r4,r4,4 + srwi. r6,r5,2 + beq 3f /* if we're doing < 4 bytes */ + andi. r9,r4,2 /* Align dst to longword boundary */ + beq+ 1f +81: lhz r6,4(r3) /* do 2 bytes to get aligned */ + addi r3,r3,2 + subi r5,r5,2 +91: sth r6,4(r4) + addi r4,r4,2 + addc r0,r0,r6 + srwi. r6,r5,2 /* # words to do */ + beq 3f +1: mtctr r6 +82: lwzu r6,4(r3) /* the bdnz has zero overhead, so it should */ +92: stwu r6,4(r4) /* be unnecessary to unroll this loop */ + adde r0,r0,r6 + bdnz 82b + andi. r5,r5,3 +3: cmpwi 0,r5,2 + blt+ 4f +83: lhz r6,4(r3) + addi r3,r3,2 + subi r5,r5,2 +93: sth r6,4(r4) + addi r4,r4,2 + adde r0,r0,r6 +4: cmpwi 0,r5,1 + bne+ 5f +84: lbz r6,4(r3) +94: stb r6,4(r4) + slwi r6,r6,8 /* Upper byte of word */ + adde r0,r0,r6 +5: addze r3,r0 /* add in final carry (unlikely with 64-bit regs) */ + rldicl r4,r3,32,0 /* fold 64 bit value */ + add r3,r4,r3 + srdi r3,r3,32 + blr + +/* These shouldn't go in the fixup section, since that would + cause the ex_table addresses to get out of order. */ + + .globl src_error_1 +src_error_1: + li r6,0 + subi r5,r5,2 +95: sth r6,4(r4) + addi r4,r4,2 + srwi. r6,r5,2 + beq 3f + mtctr r6 + .globl src_error_2 +src_error_2: + li r6,0 +96: stwu r6,4(r4) + bdnz 96b +3: andi. r5,r5,3 + beq src_error + .globl src_error_3 +src_error_3: + li r6,0 + mtctr r5 + addi r4,r4,3 +97: stbu r6,1(r4) + bdnz 97b + .globl src_error +src_error: + cmpdi 0,r7,0 + beq 1f + li r6,-EFAULT + stw r6,0(r7) +1: addze r3,r0 + blr + + .globl dst_error +dst_error: + cmpdi 0,r8,0 + beq 1f + li r6,-EFAULT + stw r6,0(r8) +1: addze r3,r0 + blr + +.section __ex_table,"a" + .align 3 + .llong 81b,src_error_1 + .llong 91b,dst_error + .llong 82b,src_error_2 + .llong 92b,dst_error + .llong 83b,src_error_3 + .llong 93b,dst_error + .llong 84b,src_error_3 + .llong 94b,dst_error + .llong 95b,dst_error + .llong 96b,dst_error + .llong 97b,dst_error diff --git a/arch/powerpc/lib/copy32.S b/arch/powerpc/lib/copy32.S new file mode 100644 index 000000000000..420a912198a2 --- /dev/null +++ b/arch/powerpc/lib/copy32.S @@ -0,0 +1,543 @@ +/* + * Memory copy functions for 32-bit PowerPC. + * + * Copyright (C) 1996-2005 Paul Mackerras. + * + * 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. + */ +#include +#include +#include +#include +#include + +#define COPY_16_BYTES \ + lwz r7,4(r4); \ + lwz r8,8(r4); \ + lwz r9,12(r4); \ + lwzu r10,16(r4); \ + stw r7,4(r6); \ + stw r8,8(r6); \ + stw r9,12(r6); \ + stwu r10,16(r6) + +#define COPY_16_BYTES_WITHEX(n) \ +8 ## n ## 0: \ + lwz r7,4(r4); \ +8 ## n ## 1: \ + lwz r8,8(r4); \ +8 ## n ## 2: \ + lwz r9,12(r4); \ +8 ## n ## 3: \ + lwzu r10,16(r4); \ +8 ## n ## 4: \ + stw r7,4(r6); \ +8 ## n ## 5: \ + stw r8,8(r6); \ +8 ## n ## 6: \ + stw r9,12(r6); \ +8 ## n ## 7: \ + stwu r10,16(r6) + +#define COPY_16_BYTES_EXCODE(n) \ +9 ## n ## 0: \ + addi r5,r5,-(16 * n); \ + b 104f; \ +9 ## n ## 1: \ + addi r5,r5,-(16 * n); \ + b 105f; \ +.section __ex_table,"a"; \ + .align 2; \ + .long 8 ## n ## 0b,9 ## n ## 0b; \ + .long 8 ## n ## 1b,9 ## n ## 0b; \ + .long 8 ## n ## 2b,9 ## n ## 0b; \ + .long 8 ## n ## 3b,9 ## n ## 0b; \ + .long 8 ## n ## 4b,9 ## n ## 1b; \ + .long 8 ## n ## 5b,9 ## n ## 1b; \ + .long 8 ## n ## 6b,9 ## n ## 1b; \ + .long 8 ## n ## 7b,9 ## n ## 1b; \ + .text + + .text + .stabs "arch/powerpc/lib/",N_SO,0,0,0f + .stabs "copy32.S",N_SO,0,0,0f +0: + +CACHELINE_BYTES = L1_CACHE_LINE_SIZE +LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE +CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1) + +/* + * Use dcbz on the complete cache lines in the destination + * to set them to zero. This requires that the destination + * area is cacheable. -- paulus + */ +_GLOBAL(cacheable_memzero) + mr r5,r4 + li r4,0 + addi r6,r3,-4 + cmplwi 0,r5,4 + blt 7f + stwu r4,4(r6) + beqlr + andi. r0,r6,3 + add r5,r0,r5 + subf r6,r0,r6 + clrlwi r7,r6,32-LG_CACHELINE_BYTES + add r8,r7,r5 + srwi r9,r8,LG_CACHELINE_BYTES + addic. r9,r9,-1 /* total number of complete cachelines */ + ble 2f + xori r0,r7,CACHELINE_MASK & ~3 + srwi. r0,r0,2 + beq 3f + mtctr r0 +4: stwu r4,4(r6) + bdnz 4b +3: mtctr r9 + li r7,4 +#if !defined(CONFIG_8xx) +10: dcbz r7,r6 +#else +10: stw r4, 4(r6) + stw r4, 8(r6) + stw r4, 12(r6) + stw r4, 16(r6) +#if CACHE_LINE_SIZE >= 32 + stw r4, 20(r6) + stw r4, 24(r6) + stw r4, 28(r6) + stw r4, 32(r6) +#endif /* CACHE_LINE_SIZE */ +#endif + addi r6,r6,CACHELINE_BYTES + bdnz 10b + clrlwi r5,r8,32-LG_CACHELINE_BYTES + addi r5,r5,4 +2: srwi r0,r5,2 + mtctr r0 + bdz 6f +1: stwu r4,4(r6) + bdnz 1b +6: andi. r5,r5,3 +7: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r6,3 +8: stbu r4,1(r6) + bdnz 8b + blr + +_GLOBAL(memset) + rlwimi r4,r4,8,16,23 + rlwimi r4,r4,16,0,15 + addi r6,r3,-4 + cmplwi 0,r5,4 + blt 7f + stwu r4,4(r6) + beqlr + andi. r0,r6,3 + add r5,r0,r5 + subf r6,r0,r6 + srwi r0,r5,2 + mtctr r0 + bdz 6f +1: stwu r4,4(r6) + bdnz 1b +6: andi. r5,r5,3 +7: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r6,3 +8: stbu r4,1(r6) + bdnz 8b + blr + +/* + * This version uses dcbz on the complete cache lines in the + * destination area to reduce memory traffic. This requires that + * the destination area is cacheable. + * We only use this version if the source and dest don't overlap. + * -- paulus. + */ +_GLOBAL(cacheable_memcpy) + add r7,r3,r5 /* test if the src & dst overlap */ + add r8,r4,r5 + cmplw 0,r4,r7 + cmplw 1,r3,r8 + crand 0,0,4 /* cr0.lt &= cr1.lt */ + blt memcpy /* if regions overlap */ + + addi r4,r4,-4 + addi r6,r3,-4 + neg r0,r3 + andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ + beq 58f + + cmplw 0,r5,r0 /* is this more than total to do? */ + blt 63f /* if not much to do */ + andi. r8,r0,3 /* get it word-aligned first */ + subf r5,r0,r5 + mtctr r8 + beq+ 61f +70: lbz r9,4(r4) /* do some bytes */ + stb r9,4(r6) + addi r4,r4,1 + addi r6,r6,1 + bdnz 70b +61: srwi. r0,r0,2 + mtctr r0 + beq 58f +72: lwzu r9,4(r4) /* do some words */ + stwu r9,4(r6) + bdnz 72b + +58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ + clrlwi r5,r5,32-LG_CACHELINE_BYTES + li r11,4 + mtctr r0 + beq 63f +53: +#if !defined(CONFIG_8xx) + dcbz r11,r6 +#endif + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 32 + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 64 + COPY_16_BYTES + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 128 + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES +#endif +#endif +#endif + bdnz 53b + +63: srwi. r0,r5,2 + mtctr r0 + beq 64f +30: lwzu r0,4(r4) + stwu r0,4(r6) + bdnz 30b + +64: andi. r0,r5,3 + mtctr r0 + beq+ 65f +40: lbz r0,4(r4) + stb r0,4(r6) + addi r4,r4,1 + addi r6,r6,1 + bdnz 40b +65: blr + +_GLOBAL(memmove) + cmplw 0,r3,r4 + bgt backwards_memcpy + /* fall through */ + +_GLOBAL(memcpy) + srwi. r7,r5,3 + addi r6,r3,-4 + addi r4,r4,-4 + beq 2f /* if less than 8 bytes to do */ + andi. r0,r6,3 /* get dest word aligned */ + mtctr r7 + bne 5f +1: lwz r7,4(r4) + lwzu r8,8(r4) + stw r7,4(r6) + stwu r8,8(r6) + bdnz 1b + andi. r5,r5,7 +2: cmplwi 0,r5,4 + blt 3f + lwzu r0,4(r4) + addi r5,r5,-4 + stwu r0,4(r6) +3: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r4,r4,3 + addi r6,r6,3 +4: lbzu r0,1(r4) + stbu r0,1(r6) + bdnz 4b + blr +5: subfic r0,r0,4 + mtctr r0 +6: lbz r7,4(r4) + addi r4,r4,1 + stb r7,4(r6) + addi r6,r6,1 + bdnz 6b + subf r5,r0,r5 + rlwinm. r7,r5,32-3,3,31 + beq 2b + mtctr r7 + b 1b + +_GLOBAL(backwards_memcpy) + rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + add r6,r3,r5 + add r4,r4,r5 + beq 2f + andi. r0,r6,3 + mtctr r7 + bne 5f +1: lwz r7,-4(r4) + lwzu r8,-8(r4) + stw r7,-4(r6) + stwu r8,-8(r6) + bdnz 1b + andi. r5,r5,7 +2: cmplwi 0,r5,4 + blt 3f + lwzu r0,-4(r4) + subi r5,r5,4 + stwu r0,-4(r6) +3: cmpwi 0,r5,0 + beqlr + mtctr r5 +4: lbzu r0,-1(r4) + stbu r0,-1(r6) + bdnz 4b + blr +5: mtctr r0 +6: lbzu r7,-1(r4) + stbu r7,-1(r6) + bdnz 6b + subf r5,r0,r5 + rlwinm. r7,r5,32-3,3,31 + beq 2b + mtctr r7 + b 1b + +_GLOBAL(__copy_tofrom_user) + addi r4,r4,-4 + addi r6,r3,-4 + neg r0,r3 + andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ + beq 58f + + cmplw 0,r5,r0 /* is this more than total to do? */ + blt 63f /* if not much to do */ + andi. r8,r0,3 /* get it word-aligned first */ + mtctr r8 + beq+ 61f +70: lbz r9,4(r4) /* do some bytes */ +71: stb r9,4(r6) + addi r4,r4,1 + addi r6,r6,1 + bdnz 70b +61: subf r5,r0,r5 + srwi. r0,r0,2 + mtctr r0 + beq 58f +72: lwzu r9,4(r4) /* do some words */ +73: stwu r9,4(r6) + bdnz 72b + + .section __ex_table,"a" + .align 2 + .long 70b,100f + .long 71b,101f + .long 72b,102f + .long 73b,103f + .text + +58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ + clrlwi r5,r5,32-LG_CACHELINE_BYTES + li r11,4 + beq 63f + +#ifdef CONFIG_8xx + /* Don't use prefetch on 8xx */ + mtctr r0 + li r0,0 +53: COPY_16_BYTES_WITHEX(0) + bdnz 53b + +#else /* not CONFIG_8xx */ + /* Here we decide how far ahead to prefetch the source */ + li r3,4 + cmpwi r0,1 + li r7,0 + ble 114f + li r7,1 +#if MAX_COPY_PREFETCH > 1 + /* Heuristically, for large transfers we prefetch + MAX_COPY_PREFETCH cachelines ahead. For small transfers + we prefetch 1 cacheline ahead. */ + cmpwi r0,MAX_COPY_PREFETCH + ble 112f + li r7,MAX_COPY_PREFETCH +112: mtctr r7 +111: dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES + bdnz 111b +#else + dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES +#endif /* MAX_COPY_PREFETCH > 1 */ + +114: subf r8,r7,r0 + mr r0,r7 + mtctr r8 + +53: dcbt r3,r4 +54: dcbz r11,r6 + .section __ex_table,"a" + .align 2 + .long 54b,105f + .text +/* the main body of the cacheline loop */ + COPY_16_BYTES_WITHEX(0) +#if L1_CACHE_LINE_SIZE >= 32 + COPY_16_BYTES_WITHEX(1) +#if L1_CACHE_LINE_SIZE >= 64 + COPY_16_BYTES_WITHEX(2) + COPY_16_BYTES_WITHEX(3) +#if L1_CACHE_LINE_SIZE >= 128 + COPY_16_BYTES_WITHEX(4) + COPY_16_BYTES_WITHEX(5) + COPY_16_BYTES_WITHEX(6) + COPY_16_BYTES_WITHEX(7) +#endif +#endif +#endif + bdnz 53b + cmpwi r0,0 + li r3,4 + li r7,0 + bne 114b +#endif /* CONFIG_8xx */ + +63: srwi. r0,r5,2 + mtctr r0 + beq 64f +30: lwzu r0,4(r4) +31: stwu r0,4(r6) + bdnz 30b + +64: andi. r0,r5,3 + mtctr r0 + beq+ 65f +40: lbz r0,4(r4) +41: stb r0,4(r6) + addi r4,r4,1 + addi r6,r6,1 + bdnz 40b +65: li r3,0 + blr + +/* read fault, initial single-byte copy */ +100: li r9,0 + b 90f +/* write fault, initial single-byte copy */ +101: li r9,1 +90: subf r5,r8,r5 + li r3,0 + b 99f +/* read fault, initial word copy */ +102: li r9,0 + b 91f +/* write fault, initial word copy */ +103: li r9,1 +91: li r3,2 + b 99f + +/* + * this stuff handles faults in the cacheline loop and branches to either + * 104f (if in read part) or 105f (if in write part), after updating r5 + */ + COPY_16_BYTES_EXCODE(0) +#if L1_CACHE_LINE_SIZE >= 32 + COPY_16_BYTES_EXCODE(1) +#if L1_CACHE_LINE_SIZE >= 64 + COPY_16_BYTES_EXCODE(2) + COPY_16_BYTES_EXCODE(3) +#if L1_CACHE_LINE_SIZE >= 128 + COPY_16_BYTES_EXCODE(4) + COPY_16_BYTES_EXCODE(5) + COPY_16_BYTES_EXCODE(6) + COPY_16_BYTES_EXCODE(7) +#endif +#endif +#endif + +/* read fault in cacheline loop */ +104: li r9,0 + b 92f +/* fault on dcbz (effectively a write fault) */ +/* or write fault in cacheline loop */ +105: li r9,1 +92: li r3,LG_CACHELINE_BYTES + mfctr r8 + add r0,r0,r8 + b 106f +/* read fault in final word loop */ +108: li r9,0 + b 93f +/* write fault in final word loop */ +109: li r9,1 +93: andi. r5,r5,3 + li r3,2 + b 99f +/* read fault in final byte loop */ +110: li r9,0 + b 94f +/* write fault in final byte loop */ +111: li r9,1 +94: li r5,0 + li r3,0 +/* + * At this stage the number of bytes not copied is + * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. + */ +99: mfctr r0 +106: slw r3,r0,r3 + add. r3,r3,r5 + beq 120f /* shouldn't happen */ + cmpwi 0,r9,0 + bne 120f +/* for a read fault, first try to continue the copy one byte at a time */ + mtctr r3 +130: lbz r0,4(r4) +131: stb r0,4(r6) + addi r4,r4,1 + addi r6,r6,1 + bdnz 130b +/* then clear out the destination: r3 bytes starting at 4(r6) */ +132: mfctr r3 + srwi. r0,r3,2 + li r9,0 + mtctr r0 + beq 113f +112: stwu r9,4(r6) + bdnz 112b +113: andi. r0,r3,3 + mtctr r0 + beq 120f +114: stb r9,4(r6) + addi r6,r6,1 + bdnz 114b +120: blr + + .section __ex_table,"a" + .align 2 + .long 30b,108b + .long 31b,109b + .long 40b,110b + .long 41b,111b + .long 130b,132b + .long 131b,120b + .long 112b,120b + .long 114b,120b + .text diff --git a/arch/powerpc/lib/copypage.S b/arch/powerpc/lib/copypage.S new file mode 100644 index 000000000000..733d61618bbf --- /dev/null +++ b/arch/powerpc/lib/copypage.S @@ -0,0 +1,121 @@ +/* + * arch/ppc64/lib/copypage.S + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * 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. + */ +#include +#include + +_GLOBAL(copy_page) + std r31,-8(1) + std r30,-16(1) + std r29,-24(1) + std r28,-32(1) + std r27,-40(1) + std r26,-48(1) + std r25,-56(1) + std r24,-64(1) + std r23,-72(1) + std r22,-80(1) + std r21,-88(1) + std r20,-96(1) + li r5,4096/32 - 1 + addi r3,r3,-8 + li r12,5 +0: addi r5,r5,-24 + mtctr r12 + ld r22,640(4) + ld r21,512(4) + ld r20,384(4) + ld r11,256(4) + ld r9,128(4) + ld r7,0(4) + ld r25,648(4) + ld r24,520(4) + ld r23,392(4) + ld r10,264(4) + ld r8,136(4) + ldu r6,8(4) + cmpwi r5,24 +1: std r22,648(3) + std r21,520(3) + std r20,392(3) + std r11,264(3) + std r9,136(3) + std r7,8(3) + ld r28,648(4) + ld r27,520(4) + ld r26,392(4) + ld r31,264(4) + ld r30,136(4) + ld r29,8(4) + std r25,656(3) + std r24,528(3) + std r23,400(3) + std r10,272(3) + std r8,144(3) + std r6,16(3) + ld r22,656(4) + ld r21,528(4) + ld r20,400(4) + ld r11,272(4) + ld r9,144(4) + ld r7,16(4) + std r28,664(3) + std r27,536(3) + std r26,408(3) + std r31,280(3) + std r30,152(3) + stdu r29,24(3) + ld r25,664(4) + ld r24,536(4) + ld r23,408(4) + ld r10,280(4) + ld r8,152(4) + ldu r6,24(4) + bdnz 1b + std r22,648(3) + std r21,520(3) + std r20,392(3) + std r11,264(3) + std r9,136(3) + std r7,8(3) + addi r4,r4,640 + addi r3,r3,648 + bge 0b + mtctr r5 + ld r7,0(4) + ld r8,8(4) + ldu r9,16(4) +3: ld r10,8(4) + std r7,8(3) + ld r7,16(4) + std r8,16(3) + ld r8,24(4) + std r9,24(3) + ldu r9,32(4) + stdu r10,32(3) + bdnz 3b +4: ld r10,8(4) + std r7,8(3) + std r8,16(3) + std r9,24(3) + std r10,32(3) +9: ld r20,-96(1) + ld r21,-88(1) + ld r22,-80(1) + ld r23,-72(1) + ld r24,-64(1) + ld r25,-56(1) + ld r26,-48(1) + ld r27,-40(1) + ld r28,-32(1) + ld r29,-24(1) + ld r30,-16(1) + ld r31,-8(1) + blr diff --git a/arch/powerpc/lib/copyuser.S b/arch/powerpc/lib/copyuser.S new file mode 100644 index 000000000000..a0b3fbbd6fb1 --- /dev/null +++ b/arch/powerpc/lib/copyuser.S @@ -0,0 +1,576 @@ +/* + * arch/ppc64/lib/copyuser.S + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * 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. + */ +#include +#include + + .align 7 +_GLOBAL(__copy_tofrom_user) + /* first check for a whole page copy on a page boundary */ + cmpldi cr1,r5,16 + cmpdi cr6,r5,4096 + or r0,r3,r4 + neg r6,r3 /* LS 3 bits = # bytes to 8-byte dest bdry */ + andi. r0,r0,4095 + std r3,-24(r1) + crand cr0*4+2,cr0*4+2,cr6*4+2 + std r4,-16(r1) + std r5,-8(r1) + dcbt 0,r4 + beq .Lcopy_page + andi. r6,r6,7 + mtcrf 0x01,r5 + blt cr1,.Lshort_copy + bne .Ldst_unaligned +.Ldst_aligned: + andi. r0,r4,7 + addi r3,r3,-16 + bne .Lsrc_unaligned + srdi r7,r5,4 +20: ld r9,0(r4) + addi r4,r4,-8 + mtctr r7 + andi. r5,r5,7 + bf cr7*4+0,22f + addi r3,r3,8 + addi r4,r4,8 + mr r8,r9 + blt cr1,72f +21: ld r9,8(r4) +70: std r8,8(r3) +22: ldu r8,16(r4) +71: stdu r9,16(r3) + bdnz 21b +72: std r8,8(r3) + beq+ 3f + addi r3,r3,16 +23: ld r9,8(r4) +.Ldo_tail: + bf cr7*4+1,1f + rotldi r9,r9,32 +73: stw r9,0(r3) + addi r3,r3,4 +1: bf cr7*4+2,2f + rotldi r9,r9,16 +74: sth r9,0(r3) + addi r3,r3,2 +2: bf cr7*4+3,3f + rotldi r9,r9,8 +75: stb r9,0(r3) +3: li r3,0 + blr + +.Lsrc_unaligned: + srdi r6,r5,3 + addi r5,r5,-16 + subf r4,r0,r4 + srdi r7,r5,4 + sldi r10,r0,3 + cmpldi cr6,r6,3 + andi. r5,r5,7 + mtctr r7 + subfic r11,r10,64 + add r5,r5,r0 + bt cr7*4+0,28f + +24: ld r9,0(r4) /* 3+2n loads, 2+2n stores */ +25: ld r0,8(r4) + sld r6,r9,r10 +26: ldu r9,16(r4) + srd r7,r0,r11 + sld r8,r0,r10 + or r7,r7,r6 + blt cr6,79f +27: ld r0,8(r4) + b 2f + +28: ld r0,0(r4) /* 4+2n loads, 3+2n stores */ +29: ldu r9,8(r4) + sld r8,r0,r10 + addi r3,r3,-8 + blt cr6,5f +30: ld r0,8(r4) + srd r12,r9,r11 + sld r6,r9,r10 +31: ldu r9,16(r4) + or r12,r8,r12 + srd r7,r0,r11 + sld r8,r0,r10 + addi r3,r3,16 + beq cr6,78f + +1: or r7,r7,r6 +32: ld r0,8(r4) +76: std r12,8(r3) +2: srd r12,r9,r11 + sld r6,r9,r10 +33: ldu r9,16(r4) + or r12,r8,r12 +77: stdu r7,16(r3) + srd r7,r0,r11 + sld r8,r0,r10 + bdnz 1b + +78: std r12,8(r3) + or r7,r7,r6 +79: std r7,16(r3) +5: srd r12,r9,r11 + or r12,r8,r12 +80: std r12,24(r3) + bne 6f + li r3,0 + blr +6: cmpwi cr1,r5,8 + addi r3,r3,32 + sld r9,r9,r10 + ble cr1,.Ldo_tail +34: ld r0,8(r4) + srd r7,r0,r11 + or r9,r7,r9 + b .Ldo_tail + +.Ldst_unaligned: + mtcrf 0x01,r6 /* put #bytes to 8B bdry into cr7 */ + subf r5,r6,r5 + li r7,0 + cmpldi r1,r5,16 + bf cr7*4+3,1f +35: lbz r0,0(r4) +81: stb r0,0(r3) + addi r7,r7,1 +1: bf cr7*4+2,2f +36: lhzx r0,r7,r4 +82: sthx r0,r7,r3 + addi r7,r7,2 +2: bf cr7*4+1,3f +37: lwzx r0,r7,r4 +83: stwx r0,r7,r3 +3: mtcrf 0x01,r5 + add r4,r6,r4 + add r3,r6,r3 + b .Ldst_aligned + +.Lshort_copy: + bf cr7*4+0,1f +38: lwz r0,0(r4) +39: lwz r9,4(r4) + addi r4,r4,8 +84: stw r0,0(r3) +85: stw r9,4(r3) + addi r3,r3,8 +1: bf cr7*4+1,2f +40: lwz r0,0(r4) + addi r4,r4,4 +86: stw r0,0(r3) + addi r3,r3,4 +2: bf cr7*4+2,3f +41: lhz r0,0(r4) + addi r4,r4,2 +87: sth r0,0(r3) + addi r3,r3,2 +3: bf cr7*4+3,4f +42: lbz r0,0(r4) +88: stb r0,0(r3) +4: li r3,0 + blr + +/* + * exception handlers follow + * we have to return the number of bytes not copied + * for an exception on a load, we set the rest of the destination to 0 + */ + +136: +137: + add r3,r3,r7 + b 1f +130: +131: + addi r3,r3,8 +120: +122: +124: +125: +126: +127: +128: +129: +133: + addi r3,r3,8 +121: +132: + addi r3,r3,8 +123: +134: +135: +138: +139: +140: +141: +142: + +/* + * here we have had a fault on a load and r3 points to the first + * unmodified byte of the destination + */ +1: ld r6,-24(r1) + ld r4,-16(r1) + ld r5,-8(r1) + subf r6,r6,r3 + add r4,r4,r6 + subf r5,r6,r5 /* #bytes left to go */ + +/* + * first see if we can copy any more bytes before hitting another exception + */ + mtctr r5 +43: lbz r0,0(r4) + addi r4,r4,1 +89: stb r0,0(r3) + addi r3,r3,1 + bdnz 43b + li r3,0 /* huh? all copied successfully this time? */ + blr + +/* + * here we have trapped again, need to clear ctr bytes starting at r3 + */ +143: mfctr r5 + li r0,0 + mr r4,r3 + mr r3,r5 /* return the number of bytes not copied */ +1: andi. r9,r4,7 + beq 3f +90: stb r0,0(r4) + addic. r5,r5,-1 + addi r4,r4,1 + bne 1b + blr +3: cmpldi cr1,r5,8 + srdi r9,r5,3 + andi. r5,r5,7 + blt cr1,93f + mtctr r9 +91: std r0,0(r4) + addi r4,r4,8 + bdnz 91b +93: beqlr + mtctr r5 +92: stb r0,0(r4) + addi r4,r4,1 + bdnz 92b + blr + +/* + * exception handlers for stores: we just need to work + * out how many bytes weren't copied + */ +182: +183: + add r3,r3,r7 + b 1f +180: + addi r3,r3,8 +171: +177: + addi r3,r3,8 +170: +172: +176: +178: + addi r3,r3,4 +185: + addi r3,r3,4 +173: +174: +175: +179: +181: +184: +186: +187: +188: +189: +1: + ld r6,-24(r1) + ld r5,-8(r1) + add r6,r6,r5 + subf r3,r3,r6 /* #bytes not copied */ +190: +191: +192: + blr /* #bytes not copied in r3 */ + + .section __ex_table,"a" + .align 3 + .llong 20b,120b + .llong 21b,121b + .llong 70b,170b + .llong 22b,122b + .llong 71b,171b + .llong 72b,172b + .llong 23b,123b + .llong 73b,173b + .llong 74b,174b + .llong 75b,175b + .llong 24b,124b + .llong 25b,125b + .llong 26b,126b + .llong 27b,127b + .llong 28b,128b + .llong 29b,129b + .llong 30b,130b + .llong 31b,131b + .llong 32b,132b + .llong 76b,176b + .llong 33b,133b + .llong 77b,177b + .llong 78b,178b + .llong 79b,179b + .llong 80b,180b + .llong 34b,134b + .llong 35b,135b + .llong 81b,181b + .llong 36b,136b + .llong 82b,182b + .llong 37b,137b + .llong 83b,183b + .llong 38b,138b + .llong 39b,139b + .llong 84b,184b + .llong 85b,185b + .llong 40b,140b + .llong 86b,186b + .llong 41b,141b + .llong 87b,187b + .llong 42b,142b + .llong 88b,188b + .llong 43b,143b + .llong 89b,189b + .llong 90b,190b + .llong 91b,191b + .llong 92b,192b + + .text + +/* + * Routine to copy a whole page of data, optimized for POWER4. + * On POWER4 it is more than 50% faster than the simple loop + * above (following the .Ldst_aligned label) but it runs slightly + * slower on POWER3. + */ +.Lcopy_page: + std r31,-32(1) + std r30,-40(1) + std r29,-48(1) + std r28,-56(1) + std r27,-64(1) + std r26,-72(1) + std r25,-80(1) + std r24,-88(1) + std r23,-96(1) + std r22,-104(1) + std r21,-112(1) + std r20,-120(1) + li r5,4096/32 - 1 + addi r3,r3,-8 + li r0,5 +0: addi r5,r5,-24 + mtctr r0 +20: ld r22,640(4) +21: ld r21,512(4) +22: ld r20,384(4) +23: ld r11,256(4) +24: ld r9,128(4) +25: ld r7,0(4) +26: ld r25,648(4) +27: ld r24,520(4) +28: ld r23,392(4) +29: ld r10,264(4) +30: ld r8,136(4) +31: ldu r6,8(4) + cmpwi r5,24 +1: +32: std r22,648(3) +33: std r21,520(3) +34: std r20,392(3) +35: std r11,264(3) +36: std r9,136(3) +37: std r7,8(3) +38: ld r28,648(4) +39: ld r27,520(4) +40: ld r26,392(4) +41: ld r31,264(4) +42: ld r30,136(4) +43: ld r29,8(4) +44: std r25,656(3) +45: std r24,528(3) +46: std r23,400(3) +47: std r10,272(3) +48: std r8,144(3) +49: std r6,16(3) +50: ld r22,656(4) +51: ld r21,528(4) +52: ld r20,400(4) +53: ld r11,272(4) +54: ld r9,144(4) +55: ld r7,16(4) +56: std r28,664(3) +57: std r27,536(3) +58: std r26,408(3) +59: std r31,280(3) +60: std r30,152(3) +61: stdu r29,24(3) +62: ld r25,664(4) +63: ld r24,536(4) +64: ld r23,408(4) +65: ld r10,280(4) +66: ld r8,152(4) +67: ldu r6,24(4) + bdnz 1b +68: std r22,648(3) +69: std r21,520(3) +70: std r20,392(3) +71: std r11,264(3) +72: std r9,136(3) +73: std r7,8(3) +74: addi r4,r4,640 +75: addi r3,r3,648 + bge 0b + mtctr r5 +76: ld r7,0(4) +77: ld r8,8(4) +78: ldu r9,16(4) +3: +79: ld r10,8(4) +80: std r7,8(3) +81: ld r7,16(4) +82: std r8,16(3) +83: ld r8,24(4) +84: std r9,24(3) +85: ldu r9,32(4) +86: stdu r10,32(3) + bdnz 3b +4: +87: ld r10,8(4) +88: std r7,8(3) +89: std r8,16(3) +90: std r9,24(3) +91: std r10,32(3) +9: ld r20,-120(1) + ld r21,-112(1) + ld r22,-104(1) + ld r23,-96(1) + ld r24,-88(1) + ld r25,-80(1) + ld r26,-72(1) + ld r27,-64(1) + ld r28,-56(1) + ld r29,-48(1) + ld r30,-40(1) + ld r31,-32(1) + li r3,0 + blr + +/* + * on an exception, reset to the beginning and jump back into the + * standard __copy_tofrom_user + */ +100: ld r20,-120(1) + ld r21,-112(1) + ld r22,-104(1) + ld r23,-96(1) + ld r24,-88(1) + ld r25,-80(1) + ld r26,-72(1) + ld r27,-64(1) + ld r28,-56(1) + ld r29,-48(1) + ld r30,-40(1) + ld r31,-32(1) + ld r3,-24(r1) + ld r4,-16(r1) + li r5,4096 + b .Ldst_aligned + + .section __ex_table,"a" + .align 3 + .llong 20b,100b + .llong 21b,100b + .llong 22b,100b + .llong 23b,100b + .llong 24b,100b + .llong 25b,100b + .llong 26b,100b + .llong 27b,100b + .llong 28b,100b + .llong 29b,100b + .llong 30b,100b + .llong 31b,100b + .llong 32b,100b + .llong 33b,100b + .llong 34b,100b + .llong 35b,100b + .llong 36b,100b + .llong 37b,100b + .llong 38b,100b + .llong 39b,100b + .llong 40b,100b + .llong 41b,100b + .llong 42b,100b + .llong 43b,100b + .llong 44b,100b + .llong 45b,100b + .llong 46b,100b + .llong 47b,100b + .llong 48b,100b + .llong 49b,100b + .llong 50b,100b + .llong 51b,100b + .llong 52b,100b + .llong 53b,100b + .llong 54b,100b + .llong 55b,100b + .llong 56b,100b + .llong 57b,100b + .llong 58b,100b + .llong 59b,100b + .llong 60b,100b + .llong 61b,100b + .llong 62b,100b + .llong 63b,100b + .llong 64b,100b + .llong 65b,100b + .llong 66b,100b + .llong 67b,100b + .llong 68b,100b + .llong 69b,100b + .llong 70b,100b + .llong 71b,100b + .llong 72b,100b + .llong 73b,100b + .llong 74b,100b + .llong 75b,100b + .llong 76b,100b + .llong 77b,100b + .llong 78b,100b + .llong 79b,100b + .llong 80b,100b + .llong 81b,100b + .llong 82b,100b + .llong 83b,100b + .llong 84b,100b + .llong 85b,100b + .llong 86b,100b + .llong 87b,100b + .llong 88b,100b + .llong 89b,100b + .llong 90b,100b + .llong 91b,100b diff --git a/arch/powerpc/lib/div64.S b/arch/powerpc/lib/div64.S new file mode 100644 index 000000000000..3527569e9926 --- /dev/null +++ b/arch/powerpc/lib/div64.S @@ -0,0 +1,58 @@ +/* + * Divide a 64-bit unsigned number by a 32-bit unsigned number. + * This routine assumes that the top 32 bits of the dividend are + * non-zero to start with. + * On entry, r3 points to the dividend, which get overwritten with + * the 64-bit quotient, and r4 contains the divisor. + * On exit, r3 contains the remainder. + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * 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. + */ +#include +#include + +_GLOBAL(__div64_32) + lwz r5,0(r3) # get the dividend into r5/r6 + lwz r6,4(r3) + cmplw r5,r4 + li r7,0 + li r8,0 + blt 1f + divwu r7,r5,r4 # if dividend.hi >= divisor, + mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor + subf. r5,r0,r5 # dividend.hi %= divisor + beq 3f +1: mr r11,r5 # here dividend.hi != 0 + andis. r0,r5,0xc000 + bne 2f + cntlzw r0,r5 # we are shifting the dividend right + li r10,-1 # to make it < 2^32, and shifting + srw r10,r10,r0 # the divisor right the same amount, + add r9,r4,r10 # rounding up (so the estimate cannot + andc r11,r6,r10 # ever be too large, only too small) + andc r9,r9,r10 + or r11,r5,r11 + rotlw r9,r9,r0 + rotlw r11,r11,r0 + divwu r11,r11,r9 # then we divide the shifted quantities +2: mullw r10,r11,r4 # to get an estimate of the quotient, + mulhwu r9,r11,r4 # multiply the estimate by the divisor, + subfc r6,r10,r6 # take the product from the divisor, + add r8,r8,r11 # and add the estimate to the accumulated + subfe. r5,r9,r5 # quotient + bne 1b +3: cmplw r6,r4 + blt 4f + divwu r0,r6,r4 # perform the remaining 32-bit division + mullw r10,r0,r4 # and get the remainder + add r8,r8,r0 + subf r6,r10,r6 +4: stw r7,0(r3) # return the quotient in *r3 + stw r8,4(r3) + mr r3,r6 # return the remainder in r3 + blr diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c new file mode 100644 index 000000000000..d2b834887920 --- /dev/null +++ b/arch/powerpc/lib/e2a.c @@ -0,0 +1,108 @@ +/* + * arch/ppc64/lib/e2a.c + * + * EBCDIC to ASCII conversion + * + * This function moved here from arch/ppc64/kernel/viopath.c + * + * (C) Copyright 2000-2004 IBM Corporation + * + * 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) anyu 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; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +unsigned char e2a(unsigned char x) +{ + switch (x) { + case 0xF0: + return '0'; + case 0xF1: + return '1'; + case 0xF2: + return '2'; + case 0xF3: + return '3'; + case 0xF4: + return '4'; + case 0xF5: + return '5'; + case 0xF6: + return '6'; + case 0xF7: + return '7'; + case 0xF8: + return '8'; + case 0xF9: + return '9'; + case 0xC1: + return 'A'; + case 0xC2: + return 'B'; + case 0xC3: + return 'C'; + case 0xC4: + return 'D'; + case 0xC5: + return 'E'; + case 0xC6: + return 'F'; + case 0xC7: + return 'G'; + case 0xC8: + return 'H'; + case 0xC9: + return 'I'; + case 0xD1: + return 'J'; + case 0xD2: + return 'K'; + case 0xD3: + return 'L'; + case 0xD4: + return 'M'; + case 0xD5: + return 'N'; + case 0xD6: + return 'O'; + case 0xD7: + return 'P'; + case 0xD8: + return 'Q'; + case 0xD9: + return 'R'; + case 0xE2: + return 'S'; + case 0xE3: + return 'T'; + case 0xE4: + return 'U'; + case 0xE5: + return 'V'; + case 0xE6: + return 'W'; + case 0xE7: + return 'X'; + case 0xE8: + return 'Y'; + case 0xE9: + return 'Z'; + } + return ' '; +} +EXPORT_SYMBOL(e2a); + + diff --git a/arch/powerpc/lib/memcpy.S b/arch/powerpc/lib/memcpy.S new file mode 100644 index 000000000000..9ccacdf5bcb9 --- /dev/null +++ b/arch/powerpc/lib/memcpy.S @@ -0,0 +1,172 @@ +/* + * arch/ppc64/lib/memcpy.S + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * 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. + */ +#include +#include + + .align 7 +_GLOBAL(memcpy) + mtcrf 0x01,r5 + cmpldi cr1,r5,16 + neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry + andi. r6,r6,7 + dcbt 0,r4 + blt cr1,.Lshort_copy + bne .Ldst_unaligned +.Ldst_aligned: + andi. r0,r4,7 + addi r3,r3,-16 + bne .Lsrc_unaligned + srdi r7,r5,4 + ld r9,0(r4) + addi r4,r4,-8 + mtctr r7 + andi. r5,r5,7 + bf cr7*4+0,2f + addi r3,r3,8 + addi r4,r4,8 + mr r8,r9 + blt cr1,3f +1: ld r9,8(r4) + std r8,8(r3) +2: ldu r8,16(r4) + stdu r9,16(r3) + bdnz 1b +3: std r8,8(r3) + beqlr + addi r3,r3,16 + ld r9,8(r4) +.Ldo_tail: + bf cr7*4+1,1f + rotldi r9,r9,32 + stw r9,0(r3) + addi r3,r3,4 +1: bf cr7*4+2,2f + rotldi r9,r9,16 + sth r9,0(r3) + addi r3,r3,2 +2: bf cr7*4+3,3f + rotldi r9,r9,8 + stb r9,0(r3) +3: blr + +.Lsrc_unaligned: + srdi r6,r5,3 + addi r5,r5,-16 + subf r4,r0,r4 + srdi r7,r5,4 + sldi r10,r0,3 + cmpdi cr6,r6,3 + andi. r5,r5,7 + mtctr r7 + subfic r11,r10,64 + add r5,r5,r0 + + bt cr7*4+0,0f + + ld r9,0(r4) # 3+2n loads, 2+2n stores + ld r0,8(r4) + sld r6,r9,r10 + ldu r9,16(r4) + srd r7,r0,r11 + sld r8,r0,r10 + or r7,r7,r6 + blt cr6,4f + ld r0,8(r4) + # s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12 + b 2f + +0: ld r0,0(r4) # 4+2n loads, 3+2n stores + ldu r9,8(r4) + sld r8,r0,r10 + addi r3,r3,-8 + blt cr6,5f + ld r0,8(r4) + srd r12,r9,r11 + sld r6,r9,r10 + ldu r9,16(r4) + or r12,r8,r12 + srd r7,r0,r11 + sld r8,r0,r10 + addi r3,r3,16 + beq cr6,3f + + # d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9 +1: or r7,r7,r6 + ld r0,8(r4) + std r12,8(r3) +2: srd r12,r9,r11 + sld r6,r9,r10 + ldu r9,16(r4) + or r12,r8,r12 + stdu r7,16(r3) + srd r7,r0,r11 + sld r8,r0,r10 + bdnz 1b + +3: std r12,8(r3) + or r7,r7,r6 +4: std r7,16(r3) +5: srd r12,r9,r11 + or r12,r8,r12 + std r12,24(r3) + beqlr + cmpwi cr1,r5,8 + addi r3,r3,32 + sld r9,r9,r10 + ble cr1,.Ldo_tail + ld r0,8(r4) + srd r7,r0,r11 + or r9,r7,r9 + b .Ldo_tail + +.Ldst_unaligned: + mtcrf 0x01,r6 # put #bytes to 8B bdry into cr7 + subf r5,r6,r5 + li r7,0 + cmpldi r1,r5,16 + bf cr7*4+3,1f + lbz r0,0(r4) + stb r0,0(r3) + addi r7,r7,1 +1: bf cr7*4+2,2f + lhzx r0,r7,r4 + sthx r0,r7,r3 + addi r7,r7,2 +2: bf cr7*4+1,3f + lwzx r0,r7,r4 + stwx r0,r7,r3 +3: mtcrf 0x01,r5 + add r4,r6,r4 + add r3,r6,r3 + b .Ldst_aligned + +.Lshort_copy: + bf cr7*4+0,1f + lwz r0,0(r4) + lwz r9,4(r4) + addi r4,r4,8 + stw r0,0(r3) + stw r9,4(r3) + addi r3,r3,8 +1: bf cr7*4+1,2f + lwz r0,0(r4) + addi r4,r4,4 + stw r0,0(r3) + addi r3,r3,4 +2: bf cr7*4+2,3f + lhz r0,0(r4) + addi r4,r4,2 + sth r0,0(r3) + addi r3,r3,2 +3: bf cr7*4+3,4f + lbz r0,0(r4) + stb r0,0(r3) +4: blr diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c new file mode 100644 index 000000000000..42c5de2c898f --- /dev/null +++ b/arch/powerpc/lib/rheap.c @@ -0,0 +1,693 @@ +/* + * arch/ppc/syslib/rheap.c + * + * A Remote Heap. Remote means that we don't touch the memory that the + * heap points to. Normal heap implementations use the memory they manage + * to place their list. We cannot do that because the memory we manage may + * have special properties, for example it is uncachable or of different + * endianess. + * + * Author: Pantelis Antoniou + * + * 2004 (c) INTRACOM S.A. Greece. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include +#include + +#include + +/* + * Fixup a list_head, needed when copying lists. If the pointers fall + * between s and e, apply the delta. This assumes that + * sizeof(struct list_head *) == sizeof(unsigned long *). + */ +static inline void fixup(unsigned long s, unsigned long e, int d, + struct list_head *l) +{ + unsigned long *pp; + + pp = (unsigned long *)&l->next; + if (*pp >= s && *pp < e) + *pp += d; + + pp = (unsigned long *)&l->prev; + if (*pp >= s && *pp < e) + *pp += d; +} + +/* Grow the allocated blocks */ +static int grow(rh_info_t * info, int max_blocks) +{ + rh_block_t *block, *blk; + int i, new_blocks; + int delta; + unsigned long blks, blke; + + if (max_blocks <= info->max_blocks) + return -EINVAL; + + new_blocks = max_blocks - info->max_blocks; + + block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL); + if (block == NULL) + return -ENOMEM; + + if (info->max_blocks > 0) { + + /* copy old block area */ + memcpy(block, info->block, + sizeof(rh_block_t) * info->max_blocks); + + delta = (char *)block - (char *)info->block; + + /* and fixup list pointers */ + blks = (unsigned long)info->block; + blke = (unsigned long)(info->block + info->max_blocks); + + for (i = 0, blk = block; i < info->max_blocks; i++, blk++) + fixup(blks, blke, delta, &blk->list); + + fixup(blks, blke, delta, &info->empty_list); + fixup(blks, blke, delta, &info->free_list); + fixup(blks, blke, delta, &info->taken_list); + + /* free the old allocated memory */ + if ((info->flags & RHIF_STATIC_BLOCK) == 0) + kfree(info->block); + } + + info->block = block; + info->empty_slots += new_blocks; + info->max_blocks = max_blocks; + info->flags &= ~RHIF_STATIC_BLOCK; + + /* add all new blocks to the free list */ + for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++) + list_add(&blk->list, &info->empty_list); + + return 0; +} + +/* + * Assure at least the required amount of empty slots. If this function + * causes a grow in the block area then all pointers kept to the block + * area are invalid! + */ +static int assure_empty(rh_info_t * info, int slots) +{ + int max_blocks; + + /* This function is not meant to be used to grow uncontrollably */ + if (slots >= 4) + return -EINVAL; + + /* Enough space */ + if (info->empty_slots >= slots) + return 0; + + /* Next 16 sized block */ + max_blocks = ((info->max_blocks + slots) + 15) & ~15; + + return grow(info, max_blocks); +} + +static rh_block_t *get_slot(rh_info_t * info) +{ + rh_block_t *blk; + + /* If no more free slots, and failure to extend. */ + /* XXX: You should have called assure_empty before */ + if (info->empty_slots == 0) { + printk(KERN_ERR "rh: out of slots; crash is imminent.\n"); + return NULL; + } + + /* Get empty slot to use */ + blk = list_entry(info->empty_list.next, rh_block_t, list); + list_del_init(&blk->list); + info->empty_slots--; + + /* Initialize */ + blk->start = NULL; + blk->size = 0; + blk->owner = NULL; + + return blk; +} + +static inline void release_slot(rh_info_t * info, rh_block_t * blk) +{ + list_add(&blk->list, &info->empty_list); + info->empty_slots++; +} + +static void attach_free_block(rh_info_t * info, rh_block_t * blkn) +{ + rh_block_t *blk; + rh_block_t *before; + rh_block_t *after; + rh_block_t *next; + int size; + unsigned long s, e, bs, be; + struct list_head *l; + + /* We assume that they are aligned properly */ + size = blkn->size; + s = (unsigned long)blkn->start; + e = s + size; + + /* Find the blocks immediately before and after the given one + * (if any) */ + before = NULL; + after = NULL; + next = NULL; + + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + + bs = (unsigned long)blk->start; + be = bs + blk->size; + + if (next == NULL && s >= bs) + next = blk; + + if (be == s) + before = blk; + + if (e == bs) + after = blk; + + /* If both are not null, break now */ + if (before != NULL && after != NULL) + break; + } + + /* Now check if they are really adjacent */ + if (before != NULL && s != (unsigned long)before->start + before->size) + before = NULL; + + if (after != NULL && e != (unsigned long)after->start) + after = NULL; + + /* No coalescing; list insert and return */ + if (before == NULL && after == NULL) { + + if (next != NULL) + list_add(&blkn->list, &next->list); + else + list_add(&blkn->list, &info->free_list); + + return; + } + + /* We don't need it anymore */ + release_slot(info, blkn); + + /* Grow the before block */ + if (before != NULL && after == NULL) { + before->size += size; + return; + } + + /* Grow the after block backwards */ + if (before == NULL && after != NULL) { + after->start = (int8_t *)after->start - size; + after->size += size; + return; + } + + /* Grow the before block, and release the after block */ + before->size += size + after->size; + list_del(&after->list); + release_slot(info, after); +} + +static void attach_taken_block(rh_info_t * info, rh_block_t * blkn) +{ + rh_block_t *blk; + struct list_head *l; + + /* Find the block immediately before the given one (if any) */ + list_for_each(l, &info->taken_list) { + blk = list_entry(l, rh_block_t, list); + if (blk->start > blkn->start) { + list_add_tail(&blkn->list, &blk->list); + return; + } + } + + list_add_tail(&blkn->list, &info->taken_list); +} + +/* + * Create a remote heap dynamically. Note that no memory for the blocks + * are allocated. It will upon the first allocation + */ +rh_info_t *rh_create(unsigned int alignment) +{ + rh_info_t *info; + + /* Alignment must be a power of two */ + if ((alignment & (alignment - 1)) != 0) + return ERR_PTR(-EINVAL); + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) + return ERR_PTR(-ENOMEM); + + info->alignment = alignment; + + /* Initially everything as empty */ + info->block = NULL; + info->max_blocks = 0; + info->empty_slots = 0; + info->flags = 0; + + INIT_LIST_HEAD(&info->empty_list); + INIT_LIST_HEAD(&info->free_list); + INIT_LIST_HEAD(&info->taken_list); + + return info; +} + +/* + * Destroy a dynamically created remote heap. Deallocate only if the areas + * are not static + */ +void rh_destroy(rh_info_t * info) +{ + if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL) + kfree(info->block); + + if ((info->flags & RHIF_STATIC_INFO) == 0) + kfree(info); +} + +/* + * Initialize in place a remote heap info block. This is needed to support + * operation very early in the startup of the kernel, when it is not yet safe + * to call kmalloc. + */ +void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks, + rh_block_t * block) +{ + int i; + rh_block_t *blk; + + /* Alignment must be a power of two */ + if ((alignment & (alignment - 1)) != 0) + return; + + info->alignment = alignment; + + /* Initially everything as empty */ + info->block = block; + info->max_blocks = max_blocks; + info->empty_slots = max_blocks; + info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK; + + INIT_LIST_HEAD(&info->empty_list); + INIT_LIST_HEAD(&info->free_list); + INIT_LIST_HEAD(&info->taken_list); + + /* Add all new blocks to the free list */ + for (i = 0, blk = block; i < max_blocks; i++, blk++) + list_add(&blk->list, &info->empty_list); +} + +/* Attach a free memory region, coalesces regions if adjuscent */ +int rh_attach_region(rh_info_t * info, void *start, int size) +{ + rh_block_t *blk; + unsigned long s, e, m; + int r; + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + /* Take final values */ + start = (void *)s; + size = (int)(e - s); + + /* Grow the blocks, if needed */ + r = assure_empty(info, 1); + if (r < 0) + return r; + + blk = get_slot(info); + blk->start = start; + blk->size = size; + blk->owner = NULL; + + attach_free_block(info, blk); + + return 0; +} + +/* Detatch given address range, splits free block if needed. */ +void *rh_detach_region(rh_info_t * info, void *start, int size) +{ + struct list_head *l; + rh_block_t *blk, *newblk; + unsigned long s, e, m, bs, be; + + /* Validate size */ + if (size <= 0) + return ERR_PTR(-EINVAL); + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + if (assure_empty(info, 1) < 0) + return ERR_PTR(-ENOMEM); + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + /* The range must lie entirely inside one free block */ + bs = (unsigned long)blk->start; + be = (unsigned long)blk->start + blk->size; + if (s >= bs && e <= be) + break; + blk = NULL; + } + + if (blk == NULL) + return ERR_PTR(-ENOMEM); + + /* Perfect fit */ + if (bs == s && be == e) { + /* Delete from free list, release slot */ + list_del(&blk->list); + release_slot(info, blk); + return (void *)s; + } + + /* blk still in free list, with updated start and/or size */ + if (bs == s || be == e) { + if (bs == s) + blk->start = (int8_t *)blk->start + size; + blk->size -= size; + + } else { + /* The front free fragment */ + blk->size = s - bs; + + /* the back free fragment */ + newblk = get_slot(info); + newblk->start = (void *)e; + newblk->size = be - e; + + list_add(&newblk->list, &blk->list); + } + + return (void *)s; +} + +void *rh_alloc(rh_info_t * info, int size, const char *owner) +{ + struct list_head *l; + rh_block_t *blk; + rh_block_t *newblk; + void *start; + + /* Validate size */ + if (size <= 0) + return ERR_PTR(-EINVAL); + + /* Align to configured alignment */ + size = (size + (info->alignment - 1)) & ~(info->alignment - 1); + + if (assure_empty(info, 1) < 0) + return ERR_PTR(-ENOMEM); + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + if (size <= blk->size) + break; + blk = NULL; + } + + if (blk == NULL) + return ERR_PTR(-ENOMEM); + + /* Just fits */ + if (blk->size == size) { + /* Move from free list to taken list */ + list_del(&blk->list); + blk->owner = owner; + start = blk->start; + + attach_taken_block(info, blk); + + return start; + } + + newblk = get_slot(info); + newblk->start = blk->start; + newblk->size = size; + newblk->owner = owner; + + /* blk still in free list, with updated start, size */ + blk->start = (int8_t *)blk->start + size; + blk->size -= size; + + start = newblk->start; + + attach_taken_block(info, newblk); + + return start; +} + +/* allocate at precisely the given address */ +void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) +{ + struct list_head *l; + rh_block_t *blk, *newblk1, *newblk2; + unsigned long s, e, m, bs, be; + + /* Validate size */ + if (size <= 0) + return ERR_PTR(-EINVAL); + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + if (assure_empty(info, 2) < 0) + return ERR_PTR(-ENOMEM); + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + /* The range must lie entirely inside one free block */ + bs = (unsigned long)blk->start; + be = (unsigned long)blk->start + blk->size; + if (s >= bs && e <= be) + break; + } + + if (blk == NULL) + return ERR_PTR(-ENOMEM); + + /* Perfect fit */ + if (bs == s && be == e) { + /* Move from free list to taken list */ + list_del(&blk->list); + blk->owner = owner; + + start = blk->start; + attach_taken_block(info, blk); + + return start; + + } + + /* blk still in free list, with updated start and/or size */ + if (bs == s || be == e) { + if (bs == s) + blk->start = (int8_t *)blk->start + size; + blk->size -= size; + + } else { + /* The front free fragment */ + blk->size = s - bs; + + /* The back free fragment */ + newblk2 = get_slot(info); + newblk2->start = (void *)e; + newblk2->size = be - e; + + list_add(&newblk2->list, &blk->list); + } + + newblk1 = get_slot(info); + newblk1->start = (void *)s; + newblk1->size = e - s; + newblk1->owner = owner; + + start = newblk1->start; + attach_taken_block(info, newblk1); + + return start; +} + +int rh_free(rh_info_t * info, void *start) +{ + rh_block_t *blk, *blk2; + struct list_head *l; + int size; + + /* Linear search for block */ + blk = NULL; + list_for_each(l, &info->taken_list) { + blk2 = list_entry(l, rh_block_t, list); + if (start < blk2->start) + break; + blk = blk2; + } + + if (blk == NULL || start > (blk->start + blk->size)) + return -EINVAL; + + /* Remove from taken list */ + list_del(&blk->list); + + /* Get size of freed block */ + size = blk->size; + attach_free_block(info, blk); + + return size; +} + +int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats) +{ + rh_block_t *blk; + struct list_head *l; + struct list_head *h; + int nr; + + switch (what) { + + case RHGS_FREE: + h = &info->free_list; + break; + + case RHGS_TAKEN: + h = &info->taken_list; + break; + + default: + return -EINVAL; + } + + /* Linear search for block */ + nr = 0; + list_for_each(l, h) { + blk = list_entry(l, rh_block_t, list); + if (stats != NULL && nr < max_stats) { + stats->start = blk->start; + stats->size = blk->size; + stats->owner = blk->owner; + stats++; + } + nr++; + } + + return nr; +} + +int rh_set_owner(rh_info_t * info, void *start, const char *owner) +{ + rh_block_t *blk, *blk2; + struct list_head *l; + int size; + + /* Linear search for block */ + blk = NULL; + list_for_each(l, &info->taken_list) { + blk2 = list_entry(l, rh_block_t, list); + if (start < blk2->start) + break; + blk = blk2; + } + + if (blk == NULL || start > (blk->start + blk->size)) + return -EINVAL; + + blk->owner = owner; + size = blk->size; + + return size; +} + +void rh_dump(rh_info_t * info) +{ + static rh_stats_t st[32]; /* XXX maximum 32 blocks */ + int maxnr; + int i, nr; + + maxnr = sizeof(st) / sizeof(st[0]); + + printk(KERN_INFO + "info @0x%p (%d slots empty / %d max)\n", + info, info->empty_slots, info->max_blocks); + + printk(KERN_INFO " Free:\n"); + nr = rh_get_stats(info, RHGS_FREE, maxnr, st); + if (nr > maxnr) + nr = maxnr; + for (i = 0; i < nr; i++) + printk(KERN_INFO + " 0x%p-0x%p (%u)\n", + st[i].start, (int8_t *) st[i].start + st[i].size, + st[i].size); + printk(KERN_INFO "\n"); + + printk(KERN_INFO " Taken:\n"); + nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st); + if (nr > maxnr) + nr = maxnr; + for (i = 0; i < nr; i++) + printk(KERN_INFO + " 0x%p-0x%p (%u) %s\n", + st[i].start, (int8_t *) st[i].start + st[i].size, + st[i].size, st[i].owner != NULL ? st[i].owner : ""); + printk(KERN_INFO "\n"); +} + +void rh_dump_blk(rh_info_t * info, rh_block_t * blk) +{ + printk(KERN_INFO + "blk @0x%p: 0x%p-0x%p (%u)\n", + blk, blk->start, (int8_t *) blk->start + blk->size, blk->size); +} diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c new file mode 100644 index 000000000000..e79123d1485c --- /dev/null +++ b/arch/powerpc/lib/sstep.c @@ -0,0 +1,141 @@ +/* + * Single-step support. + * + * Copyright (C) 2004 Paul Mackerras , IBM + * + * 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. + */ +#include +#include +#include +#include + +extern char system_call_common[]; + +/* Bits in SRR1 that are copied from MSR */ +#define MSR_MASK 0xffffffff87c0ffff + +/* + * Determine whether a conditional branch instruction would branch. + */ +static int branch_taken(unsigned int instr, struct pt_regs *regs) +{ + unsigned int bo = (instr >> 21) & 0x1f; + unsigned int bi; + + if ((bo & 4) == 0) { + /* decrement counter */ + --regs->ctr; + if (((bo >> 1) & 1) ^ (regs->ctr == 0)) + return 0; + } + if ((bo & 0x10) == 0) { + /* check bit from CR */ + bi = (instr >> 16) & 0x1f; + if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1)) + return 0; + } + return 1; +} + +/* + * Emulate instructions that cause a transfer of control. + * Returns 1 if the step was emulated, 0 if not, + * or -1 if the instruction is one that should not be stepped, + * such as an rfid, or a mtmsrd that would clear MSR_RI. + */ +int emulate_step(struct pt_regs *regs, unsigned int instr) +{ + unsigned int opcode, rd; + unsigned long int imm; + + opcode = instr >> 26; + switch (opcode) { + case 16: /* bc */ + imm = (signed short)(instr & 0xfffc); + if ((instr & 2) == 0) + imm += regs->nip; + regs->nip += 4; + if ((regs->msr & MSR_SF) == 0) + regs->nip &= 0xffffffffUL; + if (instr & 1) + regs->link = regs->nip; + if (branch_taken(instr, regs)) + regs->nip = imm; + return 1; + case 17: /* sc */ + /* + * N.B. this uses knowledge about how the syscall + * entry code works. If that is changed, this will + * need to be changed also. + */ + regs->gpr[9] = regs->gpr[13]; + regs->gpr[11] = regs->nip + 4; + regs->gpr[12] = regs->msr & MSR_MASK; + regs->gpr[13] = (unsigned long) get_paca(); + regs->nip = (unsigned long) &system_call_common; + regs->msr = MSR_KERNEL; + return 1; + case 18: /* b */ + imm = instr & 0x03fffffc; + if (imm & 0x02000000) + imm -= 0x04000000; + if ((instr & 2) == 0) + imm += regs->nip; + if (instr & 1) { + regs->link = regs->nip + 4; + if ((regs->msr & MSR_SF) == 0) + regs->link &= 0xffffffffUL; + } + if ((regs->msr & MSR_SF) == 0) + imm &= 0xffffffffUL; + regs->nip = imm; + return 1; + case 19: + switch (instr & 0x7fe) { + case 0x20: /* bclr */ + case 0x420: /* bcctr */ + imm = (instr & 0x400)? regs->ctr: regs->link; + regs->nip += 4; + if ((regs->msr & MSR_SF) == 0) { + regs->nip &= 0xffffffffUL; + imm &= 0xffffffffUL; + } + if (instr & 1) + regs->link = regs->nip; + if (branch_taken(instr, regs)) + regs->nip = imm; + return 1; + case 0x24: /* rfid, scary */ + return -1; + } + case 31: + rd = (instr >> 21) & 0x1f; + switch (instr & 0x7fe) { + case 0xa6: /* mfmsr */ + regs->gpr[rd] = regs->msr & MSR_MASK; + regs->nip += 4; + if ((regs->msr & MSR_SF) == 0) + regs->nip &= 0xffffffffUL; + return 1; + case 0x164: /* mtmsrd */ + /* only MSR_EE and MSR_RI get changed if bit 15 set */ + /* mtmsrd doesn't change MSR_HV and MSR_ME */ + imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; + imm = (regs->msr & MSR_MASK & ~imm) + | (regs->gpr[rd] & imm); + if ((imm & MSR_RI) == 0) + /* can't step mtmsrd that would clear MSR_RI */ + return -1; + regs->msr = imm; + regs->nip += 4; + if ((imm & MSR_SF) == 0) + regs->nip &= 0xffffffffUL; + return 1; + } + } + return 0; +} diff --git a/arch/powerpc/lib/strcase.c b/arch/powerpc/lib/strcase.c new file mode 100644 index 000000000000..36b521091bbc --- /dev/null +++ b/arch/powerpc/lib/strcase.c @@ -0,0 +1,23 @@ +#include + +int strcasecmp(const char *s1, const char *s2) +{ + int c1, c2; + + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } while (c1 == c2 && c1 != 0); + return c1 - c2; +} + +int strncasecmp(const char *s1, const char *s2, int n) +{ + int c1, c2; + + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } while ((--n > 0) && c1 == c2 && c1 != 0); + return c1 - c2; +} diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S new file mode 100644 index 000000000000..15d40e9ef8b1 --- /dev/null +++ b/arch/powerpc/lib/string.S @@ -0,0 +1,203 @@ +/* + * String handling functions for PowerPC. + * + * Copyright (C) 1996 Paul Mackerras. + * + * 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. + */ +#include +#include +#include +#include + + .text + .stabs "arch/powerpc/lib/",N_SO,0,0,0f + .stabs "string.S",N_SO,0,0,0f +0: + + .section __ex_table,"a" +#ifdef CONFIG_PPC64 + .align 3 +#define EXTBL .llong +#else + .align 2 +#define EXTBL .long +#endif + .text + +_GLOBAL(strcpy) + addi r5,r3,-1 + addi r4,r4,-1 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + stbu r0,1(r5) + bne 1b + blr + +/* This clears out any unused part of the destination buffer, + just as the libc version does. -- paulus */ +_GLOBAL(strncpy) + cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r3,-1 + addi r4,r4,-1 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + stbu r0,1(r6) + bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ + bnelr /* if we didn't hit a null char, we're done */ + mfctr r5 + cmpwi 0,r5,0 /* any space left in destination buffer? */ + beqlr /* we know r0 == 0 here */ +2: stbu r0,1(r6) /* clear it out if so */ + bdnz 2b + blr + +_GLOBAL(strcat) + addi r5,r3,-1 + addi r4,r4,-1 +1: lbzu r0,1(r5) + cmpwi 0,r0,0 + bne 1b + addi r5,r5,-1 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + stbu r0,1(r5) + bne 1b + blr + +_GLOBAL(strcmp) + addi r5,r3,-1 + addi r4,r4,-1 +1: lbzu r3,1(r5) + cmpwi 1,r3,0 + lbzu r0,1(r4) + subf. r3,r0,r3 + beqlr 1 + beq 1b + blr + +_GLOBAL(strlen) + addi r4,r3,-1 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + bne 1b + subf r3,r3,r4 + blr + +_GLOBAL(memcmp) + cmpwi 0,r5,0 + ble- 2f + mtctr r5 + addi r6,r3,-1 + addi r4,r4,-1 +1: lbzu r3,1(r6) + lbzu r0,1(r4) + subf. r3,r0,r3 + bdnzt 2,1b + blr +2: li r3,0 + blr + +_GLOBAL(memchr) + cmpwi 0,r5,0 + ble- 2f + mtctr r5 + addi r3,r3,-1 +1: lbzu r0,1(r3) + cmpw 0,r0,r4 + bdnzf 2,1b + beqlr +2: li r3,0 + blr + +_GLOBAL(__clear_user) + addi r6,r3,-4 + li r3,0 + li r5,0 + cmplwi 0,r4,4 + blt 7f + /* clear a single word */ +11: stwu r5,4(r6) + beqlr + /* clear word sized chunks */ + andi. r0,r6,3 + add r4,r0,r4 + subf r6,r0,r6 + srwi r0,r4,2 + andi. r4,r4,3 + mtctr r0 + bdz 7f +1: stwu r5,4(r6) + bdnz 1b + /* clear byte sized chunks */ +7: cmpwi 0,r4,0 + beqlr + mtctr r4 + addi r6,r6,3 +8: stbu r5,1(r6) + bdnz 8b + blr +90: mr r3,r4 + blr +91: mfctr r3 + slwi r3,r3,2 + add r3,r3,r4 + blr +92: mfctr r3 + blr + + .section __ex_table,"a" + EXTBL 11b,90b + EXTBL 1b,91b + EXTBL 8b,92b + .text + +_GLOBAL(__strncpy_from_user) + addi r6,r3,-1 + addi r4,r4,-1 + cmpwi 0,r5,0 + beq 2f + mtctr r5 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + stbu r0,1(r6) + bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ + beq 3f +2: addi r6,r6,1 +3: subf r3,r3,r6 + blr +99: li r3,-EFAULT + blr + + .section __ex_table,"a" + EXTBL 1b,99b + .text + +/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ +_GLOBAL(__strnlen_user) + addi r7,r3,-1 + subf r6,r7,r5 /* top+1 - str */ + cmplw 0,r4,r6 + bge 0f + mr r6,r4 +0: mtctr r6 /* ctr = min(len, top - str) */ +1: lbzu r0,1(r7) /* get next byte */ + cmpwi 0,r0,0 + bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ + addi r7,r7,1 + subf r3,r3,r7 /* number of bytes we have looked at */ + beqlr /* return if we found a 0 byte */ + cmpw 0,r3,r4 /* did we look at all len bytes? */ + blt 99f /* if not, must have hit top */ + addi r3,r4,1 /* return len + 1 to indicate no null found */ + blr +99: li r3,0 /* bad address, return 0 */ + blr + + .section __ex_table,"a" + EXTBL 1b,99b diff --git a/arch/powerpc/lib/usercopy.c b/arch/powerpc/lib/usercopy.c new file mode 100644 index 000000000000..5eea6f3c1e03 --- /dev/null +++ b/arch/powerpc/lib/usercopy.c @@ -0,0 +1,41 @@ +/* + * Functions which are too large to be inlined. + * + * 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. + */ +#include +#include + +unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (likely(access_ok(VERIFY_READ, from, n))) + n = __copy_from_user(to, from, n); + else + memset(to, 0, n); + return n; +} + +unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (likely(access_ok(VERIFY_WRITE, to, n))) + n = __copy_to_user(to, from, n); + return n; +} + +unsigned long copy_in_user(void __user *to, const void __user *from, + unsigned long n) +{ + might_sleep(); + if (likely(access_ok(VERIFY_READ, from, n) && + access_ok(VERIFY_WRITE, to, n))) + n =__copy_tofrom_user(to, from, n); + return n; +} + +EXPORT_SYMBOL(copy_from_user); +EXPORT_SYMBOL(copy_to_user); +EXPORT_SYMBOL(copy_in_user); + diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c new file mode 100644 index 000000000000..3d79ce281b67 --- /dev/null +++ b/arch/powerpc/mm/44x_mmu.c @@ -0,0 +1,120 @@ +/* + * Modifications by Matt Porter (mporter@mvista.com) to support + * PPC44x Book E processors. + * + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mmu_decl.h" + +extern char etext[], _stext[]; + +/* Used by the 44x TLB replacement exception handler. + * Just needed it declared someplace. + */ +unsigned int tlb_44x_index = 0; +unsigned int tlb_44x_hwater = 62; + +/* + * "Pins" a 256MB TLB entry in AS0 for kernel lowmem + */ +static void __init +ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) +{ + unsigned long attrib = 0; + + __asm__ __volatile__("\ + clrrwi %2,%2,10\n\ + ori %2,%2,%4\n\ + clrrwi %1,%1,10\n\ + li %0,0\n\ + ori %0,%0,%5\n\ + tlbwe %2,%3,%6\n\ + tlbwe %1,%3,%7\n\ + tlbwe %0,%3,%8" + : + : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), + "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M), + "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), + "i" (PPC44x_TLB_PAGEID), + "i" (PPC44x_TLB_XLAT), + "i" (PPC44x_TLB_ATTRIB)); +} + +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + flush_instruction_cache(); +} + +unsigned long __init mmu_mapin_ram(void) +{ + unsigned int pinned_tlbs = 1; + int i; + + /* Determine number of entries necessary to cover lowmem */ + pinned_tlbs = (unsigned int) + (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); + + /* Write upper watermark to save location */ + tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; + + /* If necessary, set additional pinned TLBs */ + if (pinned_tlbs > 1) + for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; + ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); + } + + return total_lowmem; +} diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c new file mode 100644 index 000000000000..b7bcbc232f39 --- /dev/null +++ b/arch/powerpc/mm/4xx_mmu.c @@ -0,0 +1,141 @@ +/* + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mmu_decl.h" + +extern int __map_without_ltlbs; +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + /* + * The Zone Protection Register (ZPR) defines how protection will + * be applied to every page which is a member of a given zone. At + * present, we utilize only two of the 4xx's zones. + * The zone index bits (of ZSEL) in the PTE are used for software + * indicators, except the LSB. For user access, zone 1 is used, + * for kernel access, zone 0 is used. We set all but zone 1 + * to zero, allowing only kernel access as indicated in the PTE. + * For zone 1, we set a 01 binary (a value of 10 will not work) + * to allow user access as indicated in the PTE. This also allows + * kernel access as indicated in the PTE. + */ + + mtspr(SPRN_ZPR, 0x10000000); + + flush_instruction_cache(); + + /* + * Set up the real-mode cache parameters for the exception vector + * handlers (which are run in real-mode). + */ + + mtspr(SPRN_DCWR, 0x00000000); /* All caching is write-back */ + + /* + * Cache instruction and data space where the exception + * vectors and the kernel live in real-mode. + */ + + mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */ + mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */ +} + +#define LARGE_PAGE_SIZE_16M (1<<24) +#define LARGE_PAGE_SIZE_4M (1<<22) + +unsigned long __init mmu_mapin_ram(void) +{ + unsigned long v, s; + phys_addr_t p; + + v = KERNELBASE; + p = PPC_MEMSTART; + s = 0; + + if (__map_without_ltlbs) { + return s; + } + + while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) { + pmd_t *pmdp; + unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE; + + spin_lock(&init_mm.page_table_lock); + pmdp = pmd_offset(pgd_offset_k(v), v); + pmd_val(*pmdp++) = val; + pmd_val(*pmdp++) = val; + pmd_val(*pmdp++) = val; + pmd_val(*pmdp++) = val; + spin_unlock(&init_mm.page_table_lock); + + v += LARGE_PAGE_SIZE_16M; + p += LARGE_PAGE_SIZE_16M; + s += LARGE_PAGE_SIZE_16M; + } + + while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) { + pmd_t *pmdp; + unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE; + + spin_lock(&init_mm.page_table_lock); + pmdp = pmd_offset(pgd_offset_k(v), v); + pmd_val(*pmdp) = val; + spin_unlock(&init_mm.page_table_lock); + + v += LARGE_PAGE_SIZE_4M; + p += LARGE_PAGE_SIZE_4M; + s += LARGE_PAGE_SIZE_4M; + } + + return s; +} diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile new file mode 100644 index 000000000000..9f52c26acd86 --- /dev/null +++ b/arch/powerpc/mm/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux ppc-specific parts of the memory manager. +# + +obj-y := fault.o mem.o +obj-$(CONFIG_PPC32) += init.o pgtable.o mmu_context.o \ + mem_pieces.o tlb.o +obj-$(CONFIG_PPC64) += init64.o pgtable64.o mmu_context64.o +obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu.o hash_32.o +obj-$(CONFIG_40x) += 4xx_mmu.o +obj-$(CONFIG_44x) += 44x_mmu.o +obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c new file mode 100644 index 000000000000..3df641fa789d --- /dev/null +++ b/arch/powerpc/mm/fault.c @@ -0,0 +1,391 @@ +/* + * arch/ppc/mm/fault.c + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Derived from "arch/i386/mm/fault.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * Modified by Cort Dougan and Paul Mackerras. + * + * Modified for PPC64 by Dave Engebretsen (engebret@ibm.com) + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Check whether the instruction at regs->nip is a store using + * an update addressing form which will update r1. + */ +static int store_updates_sp(struct pt_regs *regs) +{ + unsigned int inst; + + if (get_user(inst, (unsigned int __user *)regs->nip)) + return 0; + /* check for 1 in the rA field */ + if (((inst >> 16) & 0x1f) != 1) + return 0; + /* check major opcode */ + switch (inst >> 26) { + case 37: /* stwu */ + case 39: /* stbu */ + case 45: /* sthu */ + case 53: /* stfsu */ + case 55: /* stfdu */ + return 1; + case 62: /* std or stdu */ + return (inst & 3) == 1; + case 31: + /* check minor opcode */ + switch ((inst >> 1) & 0x3ff) { + case 181: /* stdux */ + case 183: /* stwux */ + case 247: /* stbux */ + case 439: /* sthux */ + case 695: /* stfsux */ + case 759: /* stfdux */ + return 1; + } + } + return 0; +} + +static void do_dabr(struct pt_regs *regs, unsigned long error_code) +{ + siginfo_t info; + + if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, + 11, SIGSEGV) == NOTIFY_STOP) + return; + + if (debugger_dabr_match(regs)) + return; + + /* Clear the DABR */ + set_dabr(0); + + /* Deliver the signal to userspace */ + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_HWBKPT; + info.si_addr = (void __user *)regs->nip; + force_sig_info(SIGTRAP, &info, current); +} + +/* + * For 600- and 800-family processors, the error_code parameter is DSISR + * for a data fault, SRR1 for an instruction fault. For 400-family processors + * the error_code parameter is ESR for a data fault, 0 for an instruction + * fault. + * For 64-bit processors, the error_code parameter is + * - DSISR for a non-SLB data access fault, + * - SRR1 & 0x08000000 for a non-SLB instruction access fault + * - 0 any SLB fault. + * + * The return value is 0 if the fault was handled, or the signal + * number if this is a kernel fault that can't be handled here. + */ +int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + struct vm_area_struct * vma; + struct mm_struct *mm = current->mm; + siginfo_t info; + int code = SEGV_MAPERR; + int is_write = 0; + int trap = TRAP(regs); + int is_exec = trap == 0x400; + +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + /* + * Fortunately the bit assignments in SRR1 for an instruction + * fault and DSISR for a data fault are mostly the same for the + * bits we are interested in. But there are some bits which + * indicate errors in DSISR but can validly be set in SRR1. + */ + if (trap == 0x400) + error_code &= 0x48200000; + else + is_write = error_code & DSISR_ISSTORE; +#else + is_write = error_code & ESR_DST; +#endif /* CONFIG_4xx || CONFIG_BOOKE */ + + if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code, + 11, SIGSEGV) == NOTIFY_STOP) + return 0; + + if (trap == 0x300) { + if (debugger_fault_handler(regs)) + return 0; + } + + /* On a kernel SLB miss we can only check for a valid exception entry */ + if (!user_mode(regs) && (address >= TASK_SIZE)) + return SIGSEGV; + +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + if (error_code & DSISR_DABRMATCH) { + /* DABR match */ + do_dabr(regs, error_code); + return 0; + } +#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ + + if (in_atomic() || mm == NULL) { + if (!user_mode(regs)) + return SIGSEGV; + /* in_atomic() in user mode is really bad, + as is current->mm == NULL. */ + printk(KERN_EMERG "Page fault in user mode with" + "in_atomic() = %d mm = %p\n", in_atomic(), mm); + printk(KERN_EMERG "NIP = %lx MSR = %lx\n", + regs->nip, regs->msr); + die("Weird page fault", regs, SIGSEGV); + } + + /* When running in the kernel we expect faults to occur only to + * addresses in user space. All other faults represent errors in the + * kernel and should generate an OOPS. Unfortunatly, in the case of an + * erroneous fault occuring in a code path which already holds mmap_sem + * we will deadlock attempting to validate the fault against the + * address space. Luckily the kernel only validly references user + * space from well defined areas of code, which are listed in the + * exceptions table. + * + * As the vast majority of faults will be valid we will only perform + * the source reference check when there is a possibilty of a deadlock. + * Attempt to lock the address space, if we cannot we then validate the + * source. If this is invalid we can skip the address space check, + * thus avoiding the deadlock. + */ + if (!down_read_trylock(&mm->mmap_sem)) { + if (!user_mode(regs) && !search_exception_tables(regs->nip)) + goto bad_area_nosemaphore; + + down_read(&mm->mmap_sem); + } + + vma = find_vma(mm, address); + if (!vma) + goto bad_area; + if (vma->vm_start <= address) + goto good_area; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto bad_area; + + /* + * N.B. The POWER/Open ABI allows programs to access up to + * 288 bytes below the stack pointer. + * The kernel signal delivery code writes up to about 1.5kB + * below the stack pointer (r1) before decrementing it. + * The exec code can write slightly over 640kB to the stack + * before setting the user r1. Thus we allow the stack to + * expand to 1MB without further checks. + */ + if (address + 0x100000 < vma->vm_end) { + /* get user regs even if this fault is in kernel mode */ + struct pt_regs *uregs = current->thread.regs; + if (uregs == NULL) + goto bad_area; + + /* + * A user-mode access to an address a long way below + * the stack pointer is only valid if the instruction + * is one which would update the stack pointer to the + * address accessed if the instruction completed, + * i.e. either stwu rs,n(r1) or stwux rs,r1,rb + * (or the byte, halfword, float or double forms). + * + * If we don't check this then any write to the area + * between the last mapped region and the stack will + * expand the stack rather than segfaulting. + */ + if (address + 2048 < uregs->gpr[1] + && (!user_mode(regs) || !store_updates_sp(regs))) + goto bad_area; + } + if (expand_stack(vma, address)) + goto bad_area; + +good_area: + code = SEGV_ACCERR; +#if defined(CONFIG_6xx) + if (error_code & 0x95700000) + /* an error such as lwarx to I/O controller space, + address matching DABR, eciwx, etc. */ + goto bad_area; +#endif /* CONFIG_6xx */ +#if defined(CONFIG_8xx) + /* The MPC8xx seems to always set 0x80000000, which is + * "undefined". Of those that can be set, this is the only + * one which seems bad. + */ + if (error_code & 0x10000000) + /* Guarded storage error. */ + goto bad_area; +#endif /* CONFIG_8xx */ + + if (is_exec) { +#ifdef CONFIG_PPC64 + /* protection fault */ + if (error_code & DSISR_PROTFAULT) + goto bad_area; + if (!(vma->vm_flags & VM_EXEC)) + goto bad_area; +#endif +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + pte_t *ptep; + + /* Since 4xx/Book-E supports per-page execute permission, + * we lazily flush dcache to icache. */ + ptep = NULL; + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); + } + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + pte_unmap(ptep); + up_read(&mm->mmap_sem); + return 0; + } + if (ptep != NULL) + pte_unmap(ptep); +#endif + /* a write */ + } else if (is_write) { + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area; + /* a read */ + } else { + /* protection fault */ + if (error_code & 0x08000000) + goto bad_area; + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto bad_area; + } + + /* + * If for any reason at all we couldn't handle the fault, + * make sure we exit gracefully rather than endlessly redo + * the fault. + */ + survive: + switch (handle_mm_fault(mm, vma, address, is_write)) { + + case VM_FAULT_MINOR: + current->min_flt++; + break; + case VM_FAULT_MAJOR: + current->maj_flt++; + break; + case VM_FAULT_SIGBUS: + goto do_sigbus; + case VM_FAULT_OOM: + goto out_of_memory; + default: + BUG(); + } + + up_read(&mm->mmap_sem); + return 0; + +bad_area: + up_read(&mm->mmap_sem); + +bad_area_nosemaphore: + /* User mode accesses cause a SIGSEGV */ + if (user_mode(regs)) { + _exception(SIGSEGV, regs, code, address); + return 0; + } + + if (is_exec && (error_code & DSISR_PROTFAULT) + && printk_ratelimit()) + printk(KERN_CRIT "kernel tried to execute NX-protected" + " page (%lx) - exploit attempt? (uid: %d)\n", + address, current->uid); + + return SIGSEGV; + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +out_of_memory: + up_read(&mm->mmap_sem); + if (current->pid == 1) { + yield(); + down_read(&mm->mmap_sem); + goto survive; + } + printk("VM: killing process %s\n", current->comm); + if (user_mode(regs)) + do_exit(SIGKILL); + return SIGKILL; + +do_sigbus: + up_read(&mm->mmap_sem); + if (user_mode(regs)) { + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void __user *)address; + force_sig_info(SIGBUS, &info, current); + return 0; + } + return SIGBUS; +} + +/* + * bad_page_fault is called when we have a bad access from the kernel. + * It is called from the DSI and ISI handlers in head.S and from some + * of the procedures in traps.c. + */ +void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +{ + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault? */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + regs->nip = entry->fixup; + return; + } + + /* kernel has accessed a bad area */ + die("Kernel access of bad area", regs, sig); +} diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c new file mode 100644 index 000000000000..af9ca0eb6d55 --- /dev/null +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -0,0 +1,237 @@ +/* + * Modifications by Kumar Gala (kumar.gala@freescale.com) to support + * E500 Book E processors. + * + * Copyright 2004 Freescale Semiconductor, Inc + * + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void loadcam_entry(unsigned int index); +unsigned int tlbcam_index; +unsigned int num_tlbcam_entries; +static unsigned long __cam0, __cam1, __cam2; +extern unsigned long total_lowmem; +extern unsigned long __max_low_memory; +#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +#define NUM_TLBCAMS (16) + +struct tlbcam { + u32 MAS0; + u32 MAS1; + u32 MAS2; + u32 MAS3; + u32 MAS7; +} TLBCAM[NUM_TLBCAMS]; + +struct tlbcamrange { + unsigned long start; + unsigned long limit; + phys_addr_t phys; +} tlbcam_addrs[NUM_TLBCAMS]; + +extern unsigned int tlbcam_index; + +/* + * Return PA for this VA if it is mapped by a CAM, or 0 + */ +unsigned long v_mapped_by_tlbcam(unsigned long va) +{ + int b; + for (b = 0; b < tlbcam_index; ++b) + if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit) + return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start); + return 0; +} + +/* + * Return VA for a given PA or 0 if not mapped + */ +unsigned long p_mapped_by_tlbcam(unsigned long pa) +{ + int b; + for (b = 0; b < tlbcam_index; ++b) + if (pa >= tlbcam_addrs[b].phys + && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start) + +tlbcam_addrs[b].phys) + return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); + return 0; +} + +/* + * Set up one of the I/D BAT (block address translation) register pairs. + * The parameters are not checked; in particular size must be a power + * of 4 between 4k and 256M. + */ +void settlbcam(int index, unsigned long virt, phys_addr_t phys, + unsigned int size, int flags, unsigned int pid) +{ + unsigned int tsize, lz; + + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size)); + tsize = (21 - lz) / 2; + +#ifdef CONFIG_SMP + if ((flags & _PAGE_NO_CACHE) == 0) + flags |= _PAGE_COHERENT; +#endif + + TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1); + TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid); + TLBCAM[index].MAS2 = virt & PAGE_MASK; + + TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0; + + TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0); + +#ifndef CONFIG_KGDB /* want user access for breakpoints */ + if (flags & _PAGE_USER) { + TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); + } +#else + TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); +#endif + + tlbcam_addrs[index].start = virt; + tlbcam_addrs[index].limit = virt + size - 1; + tlbcam_addrs[index].phys = phys; + + loadcam_entry(index); +} + +void invalidate_tlbcam_entry(int index) +{ + TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index); + TLBCAM[index].MAS1 = ~MAS1_VALID; + + loadcam_entry(index); +} + +void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1, + unsigned long cam2) +{ + settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0); + tlbcam_index++; + if (cam1) { + tlbcam_index++; + settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0); + } + if (cam2) { + tlbcam_index++; + settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0); + } +} + +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + flush_instruction_cache(); +} + +unsigned long __init mmu_mapin_ram(void) +{ + cam_mapin_ram(__cam0, __cam1, __cam2); + + return __cam0 + __cam1 + __cam2; +} + + +void __init +adjust_total_lowmem(void) +{ + unsigned long max_low_mem = MAX_LOW_MEM; + unsigned long cam_max = 0x10000000; + unsigned long ram; + + /* adjust CAM size to max_low_mem */ + if (max_low_mem < cam_max) + cam_max = max_low_mem; + + /* adjust lowmem size to max_low_mem */ + if (max_low_mem < total_lowmem) + ram = max_low_mem; + else + ram = total_lowmem; + + /* Calculate CAM values */ + __cam0 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam0 > cam_max) + __cam0 = cam_max; + ram -= __cam0; + if (ram) { + __cam1 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam1 > cam_max) + __cam1 = cam_max; + ram -= __cam1; + } + if (ram) { + __cam2 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam2 > cam_max) + __cam2 = cam_max; + ram -= __cam2; + } + + printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb," + " CAM2=%ldMb residual: %ldMb\n", + __cam0 >> 20, __cam1 >> 20, __cam2 >> 20, + (total_lowmem - __cam0 - __cam1 - __cam2) >> 20); + __max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2; +} diff --git a/arch/powerpc/mm/hash_32.S b/arch/powerpc/mm/hash_32.S new file mode 100644 index 000000000000..57278a8dd132 --- /dev/null +++ b/arch/powerpc/mm/hash_32.S @@ -0,0 +1,618 @@ +/* + * arch/ppc/kernel/hashtable.S + * + * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $ + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * + * This file contains low-level assembler routines for managing + * the PowerPC MMU hash table. (PPC 8xx processors don't use a + * hash table, so this file is not used on them.) + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SMP + .comm mmu_hash_lock,4 +#endif /* CONFIG_SMP */ + +/* + * Sync CPUs with hash_page taking & releasing the hash + * table lock + */ +#ifdef CONFIG_SMP + .text +_GLOBAL(hash_page_sync) + lis r8,mmu_hash_lock@h + ori r8,r8,mmu_hash_lock@l + lis r0,0x0fff + b 10f +11: lwz r6,0(r8) + cmpwi 0,r6,0 + bne 11b +10: lwarx r6,0,r8 + cmpwi 0,r6,0 + bne- 11b + stwcx. r0,0,r8 + bne- 10b + isync + eieio + li r0,0 + stw r0,0(r8) + blr +#endif + +/* + * Load a PTE into the hash table, if possible. + * The address is in r4, and r3 contains an access flag: + * _PAGE_RW (0x400) if a write. + * r9 contains the SRR1 value, from which we use the MSR_PR bit. + * SPRG3 contains the physical address of the current task's thread. + * + * Returns to the caller if the access is illegal or there is no + * mapping for the address. Otherwise it places an appropriate PTE + * in the hash table and returns from the exception. + * Uses r0, r3 - r8, ctr, lr. + */ + .text +_GLOBAL(hash_page) +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + MTMSRD(r0) + isync +#endif + tophys(r7,0) /* gets -KERNELBASE into r7 */ +#ifdef CONFIG_SMP + addis r8,r7,mmu_hash_lock@h + ori r8,r8,mmu_hash_lock@l + lis r0,0x0fff + b 10f +11: lwz r6,0(r8) + cmpwi 0,r6,0 + bne 11b +10: lwarx r6,0,r8 + cmpwi 0,r6,0 + bne- 11b + stwcx. r0,0,r8 + bne- 10b + isync +#endif + /* Get PTE (linux-style) and check access */ + lis r0,KERNELBASE@h /* check if kernel address */ + cmplw 0,r4,r0 + mfspr r8,SPRN_SPRG3 /* current task's THREAD (phys) */ + ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */ + lwz r5,PGDIR(r8) /* virt page-table root */ + blt+ 112f /* assume user more likely */ + lis r5,swapper_pg_dir@ha /* if kernel address, use */ + addi r5,r5,swapper_pg_dir@l /* kernel page table */ + rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ +112: add r5,r5,r7 /* convert to phys addr */ + rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ + lwz r8,0(r5) /* get pmd entry */ + rlwinm. r8,r8,0,0,19 /* extract address of pte page */ +#ifdef CONFIG_SMP + beq- hash_page_out /* return if no mapping */ +#else + /* XXX it seems like the 601 will give a machine fault on the + rfi if its alignment is wrong (bottom 4 bits of address are + 8 or 0xc) and we have had a not-taken conditional branch + to the address following the rfi. */ + beqlr- +#endif + rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */ + rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE + + /* + * Update the linux PTE atomically. We do the lwarx up-front + * because almost always, there won't be a permission violation + * and there won't already be an HPTE, and thus we will have + * to update the PTE to set _PAGE_HASHPTE. -- paulus. + */ +retry: + lwarx r6,0,r8 /* get linux-style pte */ + andc. r5,r3,r6 /* check access & ~permission */ +#ifdef CONFIG_SMP + bne- hash_page_out /* return if access not permitted */ +#else + bnelr- +#endif + or r5,r0,r6 /* set accessed/dirty bits */ + stwcx. r5,0,r8 /* attempt to update PTE */ + bne- retry /* retry if someone got there first */ + + mfsrin r3,r4 /* get segment reg for segment */ + mfctr r0 + stw r0,_CTR(r11) + bl create_hpte /* add the hash table entry */ + +#ifdef CONFIG_SMP + eieio + addis r8,r7,mmu_hash_lock@ha + li r0,0 + stw r0,mmu_hash_lock@l(r8) +#endif + + /* Return from the exception */ + lwz r5,_CTR(r11) + mtctr r5 + lwz r0,GPR0(r11) + lwz r7,GPR7(r11) + lwz r8,GPR8(r11) + b fast_exception_return + +#ifdef CONFIG_SMP +hash_page_out: + eieio + addis r8,r7,mmu_hash_lock@ha + li r0,0 + stw r0,mmu_hash_lock@l(r8) + blr +#endif /* CONFIG_SMP */ + +/* + * Add an entry for a particular page to the hash table. + * + * add_hash_page(unsigned context, unsigned long va, unsigned long pmdval) + * + * We assume any necessary modifications to the pte (e.g. setting + * the accessed bit) have already been done and that there is actually + * a hash table in use (i.e. we're not on a 603). + */ +_GLOBAL(add_hash_page) + mflr r0 + stw r0,4(r1) + + /* Convert context and va to VSID */ + mulli r3,r3,897*16 /* multiply context by context skew */ + rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ + mulli r0,r0,0x111 /* multiply by ESID skew */ + add r3,r3,r0 /* note create_hpte trims to 24 bits */ + +#ifdef CONFIG_SMP + rlwinm r8,r1,0,0,18 /* use cpu number to make tag */ + lwz r8,TI_CPU(r8) /* to go in mmu_hash_lock */ + oris r8,r8,12 +#endif /* CONFIG_SMP */ + + /* + * We disable interrupts here, even on UP, because we don't + * want to race with hash_page, and because we want the + * _PAGE_HASHPTE bit to be a reliable indication of whether + * the HPTE exists (or at least whether one did once). + * We also turn off the MMU for data accesses so that we + * we can't take a hash table miss (assuming the code is + * covered by a BAT). -- paulus + */ + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear MSR_DR */ + mtmsr r0 + SYNC_601 + isync + + tophys(r7,0) + +#ifdef CONFIG_SMP + addis r9,r7,mmu_hash_lock@ha + addi r9,r9,mmu_hash_lock@l +10: lwarx r0,0,r9 /* take the mmu_hash_lock */ + cmpi 0,r0,0 + bne- 11f + stwcx. r8,0,r9 + beq+ 12f +11: lwz r0,0(r9) + cmpi 0,r0,0 + beq 10b + b 11b +12: isync +#endif + + /* + * Fetch the linux pte and test and set _PAGE_HASHPTE atomically. + * If _PAGE_HASHPTE was already set, we don't replace the existing + * HPTE, so we just unlock and return. + */ + mr r8,r5 + rlwimi r8,r4,22,20,29 +1: lwarx r6,0,r8 + andi. r0,r6,_PAGE_HASHPTE + bne 9f /* if HASHPTE already set, done */ + ori r5,r6,_PAGE_HASHPTE + stwcx. r5,0,r8 + bne- 1b + + bl create_hpte + +9: +#ifdef CONFIG_SMP + eieio + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ +#endif + + /* reenable interrupts and DR */ + mtmsr r10 + SYNC_601 + isync + + lwz r0,4(r1) + mtlr r0 + blr + +/* + * This routine adds a hardware PTE to the hash table. + * It is designed to be called with the MMU either on or off. + * r3 contains the VSID, r4 contains the virtual address, + * r5 contains the linux PTE, r6 contains the old value of the + * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the + * offset to be added to addresses (0 if the MMU is on, + * -KERNELBASE if it is off). + * On SMP, the caller should have the mmu_hash_lock held. + * We assume that the caller has (or will) set the _PAGE_HASHPTE + * bit in the linux PTE in memory. The value passed in r6 should + * be the old linux PTE value; if it doesn't have _PAGE_HASHPTE set + * this routine will skip the search for an existing HPTE. + * This procedure modifies r0, r3 - r6, r8, cr0. + * -- paulus. + * + * For speed, 4 of the instructions get patched once the size and + * physical address of the hash table are known. These definitions + * of Hash_base and Hash_bits below are just an example. + */ +Hash_base = 0xc0180000 +Hash_bits = 12 /* e.g. 256kB hash table */ +Hash_msk = (((1 << Hash_bits) - 1) * 64) + +#ifndef CONFIG_PPC64BRIDGE +/* defines for the PTE format for 32-bit PPCs */ +#define PTE_SIZE 8 +#define PTEG_SIZE 64 +#define LG_PTEG_SIZE 6 +#define LDPTEu lwzu +#define STPTE stw +#define CMPPTE cmpw +#define PTE_H 0x40 +#define PTE_V 0x80000000 +#define TST_V(r) rlwinm. r,r,0,0,0 +#define SET_V(r) oris r,r,PTE_V@h +#define CLR_V(r,t) rlwinm r,r,0,1,31 + +#else +/* defines for the PTE format for 64-bit PPCs */ +#define PTE_SIZE 16 +#define PTEG_SIZE 128 +#define LG_PTEG_SIZE 7 +#define LDPTEu ldu +#define STPTE std +#define CMPPTE cmpd +#define PTE_H 2 +#define PTE_V 1 +#define TST_V(r) andi. r,r,PTE_V +#define SET_V(r) ori r,r,PTE_V +#define CLR_V(r,t) li t,PTE_V; andc r,r,t +#endif /* CONFIG_PPC64BRIDGE */ + +#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) +#define HASH_RIGHT 31-LG_PTEG_SIZE + +_GLOBAL(create_hpte) + /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */ + rlwinm r8,r5,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r0,r5,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r8,r8,r0 /* writable if _RW & _DIRTY */ + rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ + ori r8,r8,0xe14 /* clear out reserved bits and M */ + andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */ +BEGIN_FTR_SECTION + ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */ +END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) + + /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE + rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ + rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ + SET_V(r5) /* set V (valid) bit */ + + /* Get the address of the primary PTE group in the hash table (r3) */ +_GLOBAL(hash_page_patch_A) + addis r0,r7,Hash_base@h /* base address of hash table */ + rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ + rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */ + xor r3,r3,r0 /* make primary hash */ + li r0,8 /* PTEs/group */ + + /* + * Test the _PAGE_HASHPTE bit in the old linux PTE, and skip the search + * if it is clear, meaning that the HPTE isn't there already... + */ + andi. r6,r6,_PAGE_HASHPTE + beq+ 10f /* no PTE: go look for an empty slot */ + tlbie r4 + + addis r4,r7,htab_hash_searches@ha + lwz r6,htab_hash_searches@l(r4) + addi r6,r6,1 /* count how many searches we do */ + stw r6,htab_hash_searches@l(r4) + + /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ + mtctr r0 + addi r4,r3,-PTE_SIZE +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ + CMPPTE 0,r6,r5 + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ found_slot + + /* Search the secondary PTEG for a matching PTE */ + ori r5,r5,PTE_H /* set H (secondary hash) bit */ +_GLOBAL(hash_page_patch_B) + xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ + xori r4,r4,(-PTEG_SIZE & 0xffff) + addi r4,r4,-PTE_SIZE + mtctr r0 +2: LDPTEu r6,PTE_SIZE(r4) + CMPPTE 0,r6,r5 + bdnzf 2,2b + beq+ found_slot + xori r5,r5,PTE_H /* clear H bit again */ + + /* Search the primary PTEG for an empty slot */ +10: mtctr r0 + addi r4,r3,-PTE_SIZE /* search primary PTEG */ +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ + TST_V(r6) /* test valid bit */ + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ found_empty + + /* update counter of times that the primary PTEG is full */ + addis r4,r7,primary_pteg_full@ha + lwz r6,primary_pteg_full@l(r4) + addi r6,r6,1 + stw r6,primary_pteg_full@l(r4) + + /* Search the secondary PTEG for an empty slot */ + ori r5,r5,PTE_H /* set H (secondary hash) bit */ +_GLOBAL(hash_page_patch_C) + xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ + xori r4,r4,(-PTEG_SIZE & 0xffff) + addi r4,r4,-PTE_SIZE + mtctr r0 +2: LDPTEu r6,PTE_SIZE(r4) + TST_V(r6) + bdnzf 2,2b + beq+ found_empty + xori r5,r5,PTE_H /* clear H bit again */ + + /* + * Choose an arbitrary slot in the primary PTEG to overwrite. + * Since both the primary and secondary PTEGs are full, and we + * have no information that the PTEs in the primary PTEG are + * more important or useful than those in the secondary PTEG, + * and we know there is a definite (although small) speed + * advantage to putting the PTE in the primary PTEG, we always + * put the PTE in the primary PTEG. + */ + addis r4,r7,next_slot@ha + lwz r6,next_slot@l(r4) + addi r6,r6,PTE_SIZE + andi. r6,r6,7*PTE_SIZE + stw r6,next_slot@l(r4) + add r4,r3,r6 + +#ifndef CONFIG_SMP + /* Store PTE in PTEG */ +found_empty: + STPTE r5,0(r4) +found_slot: + STPTE r8,PTE_SIZE/2(r4) + +#else /* CONFIG_SMP */ +/* + * Between the tlbie above and updating the hash table entry below, + * another CPU could read the hash table entry and put it in its TLB. + * There are 3 cases: + * 1. using an empty slot + * 2. updating an earlier entry to change permissions (i.e. enable write) + * 3. taking over the PTE for an unrelated address + * + * In each case it doesn't really matter if the other CPUs have the old + * PTE in their TLB. So we don't need to bother with another tlbie here, + * which is convenient as we've overwritten the register that had the + * address. :-) The tlbie above is mainly to make sure that this CPU comes + * and gets the new PTE from the hash table. + * + * We do however have to make sure that the PTE is never in an invalid + * state with the V bit set. + */ +found_empty: +found_slot: + CLR_V(r5,r0) /* clear V (valid) bit in PTE */ + STPTE r5,0(r4) + sync + TLBSYNC + STPTE r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */ + sync + SET_V(r5) + STPTE r5,0(r4) /* finally set V bit in PTE */ +#endif /* CONFIG_SMP */ + + sync /* make sure pte updates get to memory */ + blr + + .comm next_slot,4 + .comm primary_pteg_full,4 + .comm htab_hash_searches,4 + +/* + * Flush the entry for a particular page from the hash table. + * + * flush_hash_pages(unsigned context, unsigned long va, unsigned long pmdval, + * int count) + * + * We assume that there is a hash table in use (Hash != 0). + */ +_GLOBAL(flush_hash_pages) + tophys(r7,0) + + /* + * We disable interrupts here, even on UP, because we want + * the _PAGE_HASHPTE bit to be a reliable indication of + * whether the HPTE exists (or at least whether one did once). + * We also turn off the MMU for data accesses so that we + * we can't take a hash table miss (assuming the code is + * covered by a BAT). -- paulus + */ + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear MSR_DR */ + mtmsr r0 + SYNC_601 + isync + + /* First find a PTE in the range that has _PAGE_HASHPTE set */ + rlwimi r5,r4,22,20,29 +1: lwz r0,0(r5) + cmpwi cr1,r6,1 + andi. r0,r0,_PAGE_HASHPTE + bne 2f + ble cr1,19f + addi r4,r4,0x1000 + addi r5,r5,4 + addi r6,r6,-1 + b 1b + + /* Convert context and va to VSID */ +2: mulli r3,r3,897*16 /* multiply context by context skew */ + rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ + mulli r0,r0,0x111 /* multiply by ESID skew */ + add r3,r3,r0 /* note code below trims to 24 bits */ + + /* Construct the high word of the PPC-style PTE (r11) */ +#ifndef CONFIG_PPC64BRIDGE + rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ + rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r11,r3,12 /* shift vsid into position */ + rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ + SET_V(r11) /* set V (valid) bit */ + +#ifdef CONFIG_SMP + addis r9,r7,mmu_hash_lock@ha + addi r9,r9,mmu_hash_lock@l + rlwinm r8,r1,0,0,18 + add r8,r8,r7 + lwz r8,TI_CPU(r8) + oris r8,r8,9 +10: lwarx r0,0,r9 + cmpi 0,r0,0 + bne- 11f + stwcx. r8,0,r9 + beq+ 12f +11: lwz r0,0(r9) + cmpi 0,r0,0 + beq 10b + b 11b +12: isync +#endif + + /* + * Check the _PAGE_HASHPTE bit in the linux PTE. If it is + * already clear, we're done (for this pte). If not, + * clear it (atomically) and proceed. -- paulus. + */ +33: lwarx r8,0,r5 /* fetch the pte */ + andi. r0,r8,_PAGE_HASHPTE + beq 8f /* done if HASHPTE is already clear */ + rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ + stwcx. r8,0,r5 /* update the pte */ + bne- 33b + + /* Get the address of the primary PTE group in the hash table (r3) */ +_GLOBAL(flush_hash_patch_A) + addis r8,r7,Hash_base@h /* base address of hash table */ + rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ + rlwinm r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */ + xor r8,r0,r8 /* make primary hash */ + + /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ + li r0,8 /* PTEs/group */ + mtctr r0 + addi r12,r8,-PTE_SIZE +1: LDPTEu r0,PTE_SIZE(r12) /* get next PTE */ + CMPPTE 0,r0,r11 + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ 3f + + /* Search the secondary PTEG for a matching PTE */ + ori r11,r11,PTE_H /* set H (secondary hash) bit */ + li r0,8 /* PTEs/group */ +_GLOBAL(flush_hash_patch_B) + xoris r12,r8,Hash_msk>>16 /* compute secondary hash */ + xori r12,r12,(-PTEG_SIZE & 0xffff) + addi r12,r12,-PTE_SIZE + mtctr r0 +2: LDPTEu r0,PTE_SIZE(r12) + CMPPTE 0,r0,r11 + bdnzf 2,2b + xori r11,r11,PTE_H /* clear H again */ + bne- 4f /* should rarely fail to find it */ + +3: li r0,0 + STPTE r0,0(r12) /* invalidate entry */ +4: sync + tlbie r4 /* in hw tlb too */ + sync + +8: ble cr1,9f /* if all ptes checked */ +81: addi r6,r6,-1 + addi r5,r5,4 /* advance to next pte */ + addi r4,r4,0x1000 + lwz r0,0(r5) /* check next pte */ + cmpwi cr1,r6,1 + andi. r0,r0,_PAGE_HASHPTE + bne 33b + bgt cr1,81b + +9: +#ifdef CONFIG_SMP + TLBSYNC + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ +#endif + +19: mtmsr r10 + SYNC_601 + isync + blr diff --git a/arch/powerpc/mm/init.c b/arch/powerpc/mm/init.c new file mode 100644 index 000000000000..f4d983a6e521 --- /dev/null +++ b/arch/powerpc/mm/init.c @@ -0,0 +1,581 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mem_pieces.h" +#include "mmu_decl.h" + +#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL) +/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */ +#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE)) +#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL" +#endif +#endif +#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + +unsigned long total_memory; +unsigned long total_lowmem; + +unsigned long ppc_memstart; +unsigned long ppc_memoffset = PAGE_OFFSET; + +int mem_init_done; +int init_bootmem_done; +int boot_mapsize; +#ifdef CONFIG_PPC_PMAC +unsigned long agp_special_page; +#endif + +extern char _end[]; +extern char etext[], _stext[]; +extern char __init_begin, __init_end; + +#ifdef CONFIG_HIGHMEM +pte_t *kmap_pte; +pgprot_t kmap_prot; + +EXPORT_SYMBOL(kmap_prot); +EXPORT_SYMBOL(kmap_pte); +#endif + +void MMU_init(void); +void set_phys_avail(unsigned long total_ram); + +/* XXX should be in current.h -- paulus */ +extern struct task_struct *current_set[NR_CPUS]; + +char *klimit = _end; +struct mem_pieces phys_avail; +struct device_node *memory_node; + +/* + * this tells the system to map all of ram with the segregs + * (i.e. page tables) instead of the bats. + * -- Cort + */ +int __map_without_bats; +int __map_without_ltlbs; + +/* max amount of RAM to use */ +unsigned long __max_memory; +/* max amount of low RAM to map in */ +unsigned long __max_low_memory = MAX_LOW_MEM; + +/* + * Read in a property describing some pieces of memory. + */ +static int __init get_mem_prop(char *name, struct mem_pieces *mp) +{ + struct reg_property *rp; + int i, s; + unsigned int *ip; + int nac = prom_n_addr_cells(memory_node); + int nsc = prom_n_size_cells(memory_node); + + ip = (unsigned int *) get_property(memory_node, name, &s); + if (ip == NULL) { + printk(KERN_ERR "error: couldn't get %s property on /memory\n", + name); + return 0; + } + s /= (nsc + nac) * 4; + rp = mp->regions; + for (i = 0; i < s; ++i, ip += nac+nsc) { + if (nac >= 2 && ip[nac-2] != 0) + continue; + rp->address = ip[nac-1]; + if (nsc >= 2 && ip[nac+nsc-2] != 0) + rp->size = ~0U; + else + rp->size = ip[nac+nsc-1]; + ++rp; + } + mp->n_regions = rp - mp->regions; + + /* Make sure the pieces are sorted. */ + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); + return 1; +} + +/* + * Collect information about physical RAM and which pieces are + * already in use from the device tree. + */ +unsigned long __init find_end_of_memory(void) +{ + unsigned long a, total; + struct mem_pieces phys_mem; + + /* + * Find out where physical memory is, and check that it + * starts at 0 and is contiguous. It seems that RAM is + * always physically contiguous on Power Macintoshes. + * + * Supporting discontiguous physical memory isn't hard, + * it just makes the virtual <-> physical mapping functions + * more complicated (or else you end up wasting space + * in mem_map). + */ + memory_node = find_devices("memory"); + if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) + || phys_mem.n_regions == 0) + panic("No RAM??"); + a = phys_mem.regions[0].address; + if (a != 0) + panic("RAM doesn't start at physical address 0"); + total = phys_mem.regions[0].size; + + if (phys_mem.n_regions > 1) { + printk("RAM starting at 0x%x is not contiguous\n", + phys_mem.regions[1].address); + printk("Using RAM from 0 to 0x%lx\n", total-1); + } + + return total; +} + +/* + * Check for command-line options that affect what MMU_init will do. + */ +void MMU_setup(void) +{ + /* Check for nobats option (used in mapin_ram). */ + if (strstr(cmd_line, "nobats")) { + __map_without_bats = 1; + } + + if (strstr(cmd_line, "noltlbs")) { + __map_without_ltlbs = 1; + } + + /* Look for mem= option on command line */ + if (strstr(cmd_line, "mem=")) { + char *p, *q; + unsigned long maxmem = 0; + + for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { + q = p + 4; + if (p > cmd_line && p[-1] != ' ') + continue; + maxmem = simple_strtoul(q, &q, 0); + if (*q == 'k' || *q == 'K') { + maxmem <<= 10; + ++q; + } else if (*q == 'm' || *q == 'M') { + maxmem <<= 20; + ++q; + } + } + __max_memory = maxmem; + } +} + +/* + * MMU_init sets up the basic memory mappings for the kernel, + * including both RAM and possibly some I/O regions, + * and sets up the page tables and the MMU hardware ready to go. + */ +void __init MMU_init(void) +{ + if (ppc_md.progress) + ppc_md.progress("MMU:enter", 0x111); + + /* parse args from command line */ + MMU_setup(); + + /* + * Figure out how much memory we have, how much + * is lowmem, and how much is highmem. If we were + * passed the total memory size from the bootloader, + * just use it. + */ + if (boot_mem_size) + total_memory = boot_mem_size; + else + total_memory = ppc_md.find_end_of_memory(); + + if (__max_memory && total_memory > __max_memory) + total_memory = __max_memory; + total_lowmem = total_memory; +#ifdef CONFIG_FSL_BOOKE + /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB + * entries, so we need to adjust lowmem to match the amount we can map + * in the fixed entries */ + adjust_total_lowmem(); +#endif /* CONFIG_FSL_BOOKE */ + if (total_lowmem > __max_low_memory) { + total_lowmem = __max_low_memory; +#ifndef CONFIG_HIGHMEM + total_memory = total_lowmem; +#endif /* CONFIG_HIGHMEM */ + } + set_phys_avail(total_lowmem); + + /* Initialize the MMU hardware */ + if (ppc_md.progress) + ppc_md.progress("MMU:hw init", 0x300); + MMU_init_hw(); + + /* Map in all of RAM starting at KERNELBASE */ + if (ppc_md.progress) + ppc_md.progress("MMU:mapin", 0x301); + mapin_ram(); + +#ifdef CONFIG_HIGHMEM + ioremap_base = PKMAP_BASE; +#else + ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */ +#endif /* CONFIG_HIGHMEM */ + ioremap_bot = ioremap_base; + + /* Map in I/O resources */ + if (ppc_md.progress) + ppc_md.progress("MMU:setio", 0x302); + if (ppc_md.setup_io_mappings) + ppc_md.setup_io_mappings(); + + /* Initialize the context management stuff */ + mmu_context_init(); + + if (ppc_md.progress) + ppc_md.progress("MMU:exit", 0x211); + +#ifdef CONFIG_BOOTX_TEXT + /* By default, we are no longer mapped */ + boot_text_mapped = 0; + /* Must be done last, or ppc_md.progress will die. */ + map_boot_text(); +#endif +} + +/* This is only called until mem_init is done. */ +void __init *early_get_page(void) +{ + void *p; + + if (init_bootmem_done) { + p = alloc_bootmem_pages(PAGE_SIZE); + } else { + p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE); + } + return p; +} + +/* Free up now-unused memory */ +static void free_sec(unsigned long start, unsigned long end, const char *name) +{ + unsigned long cnt = 0; + + while (start < end) { + ClearPageReserved(virt_to_page(start)); + set_page_count(virt_to_page(start), 1); + free_page(start); + cnt++; + start += PAGE_SIZE; + } + if (cnt) { + printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name); + totalram_pages += cnt; + } +} + +void free_initmem(void) +{ +#define FREESEC(TYPE) \ + free_sec((unsigned long)(&__ ## TYPE ## _begin), \ + (unsigned long)(&__ ## TYPE ## _end), \ + #TYPE); + + printk ("Freeing unused kernel memory:"); + FREESEC(init); + printk("\n"); + ppc_md.progress = NULL; +#undef FREESEC +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + set_page_count(virt_to_page(start), 1); + free_page(start); + totalram_pages++; + } +} +#endif + +/* + * Initialize the bootmem system and give it all the memory we + * have available. + */ +void __init do_init_bootmem(void) +{ + unsigned long start, size; + int i; + + /* + * Find an area to use for the bootmem bitmap. + * We look for the first area which is at least + * 128kB in length (128kB is enough for a bitmap + * for 4GB of memory, using 4kB pages), plus 1 page + * (in case the address isn't page-aligned). + */ + start = 0; + size = 0; + for (i = 0; i < phys_avail.n_regions; ++i) { + unsigned long a = phys_avail.regions[i].address; + unsigned long s = phys_avail.regions[i].size; + if (s <= size) + continue; + start = a; + size = s; + if (s >= 33 * PAGE_SIZE) + break; + } + start = PAGE_ALIGN(start); + + min_low_pfn = start >> PAGE_SHIFT; + max_low_pfn = (PPC_MEMSTART + total_lowmem) >> PAGE_SHIFT; + max_pfn = (PPC_MEMSTART + total_memory) >> PAGE_SHIFT; + boot_mapsize = init_bootmem_node(&contig_page_data, min_low_pfn, + PPC_MEMSTART >> PAGE_SHIFT, + max_low_pfn); + + /* remove the bootmem bitmap from the available memory */ + mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); + + /* add everything in phys_avail into the bootmem map */ + for (i = 0; i < phys_avail.n_regions; ++i) + free_bootmem(phys_avail.regions[i].address, + phys_avail.regions[i].size); + + init_bootmem_done = 1; +} + +/* + * paging_init() sets up the page tables - in fact we've already done this. + */ +void __init paging_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES], i; + +#ifdef CONFIG_HIGHMEM + map_page(PKMAP_BASE, 0, 0); /* XXX gross */ + pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k + (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); + map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ + kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k + (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); + kmap_prot = PAGE_KERNEL; +#endif /* CONFIG_HIGHMEM */ + + /* + * All pages are DMA-able so we put them all in the DMA zone. + */ + zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; + for (i = 1; i < MAX_NR_ZONES; i++) + zones_size[i] = 0; + +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; +#endif /* CONFIG_HIGHMEM */ + + free_area_init(zones_size); +} + +void __init mem_init(void) +{ + unsigned long addr; + int codepages = 0; + int datapages = 0; + int initpages = 0; +#ifdef CONFIG_HIGHMEM + unsigned long highmem_mapnr; + + highmem_mapnr = total_lowmem >> PAGE_SHIFT; +#endif /* CONFIG_HIGHMEM */ + max_mapnr = total_memory >> PAGE_SHIFT; + + high_memory = (void *) __va(PPC_MEMSTART + total_lowmem); + num_physpages = max_mapnr; /* RAM is assumed contiguous */ + + totalram_pages += free_all_bootmem(); + +#ifdef CONFIG_BLK_DEV_INITRD + /* if we are booted from BootX with an initial ramdisk, + make sure the ramdisk pages aren't reserved. */ + if (initrd_start) { + for (addr = initrd_start; addr < initrd_end; addr += PAGE_SIZE) + ClearPageReserved(virt_to_page(addr)); + } +#endif /* CONFIG_BLK_DEV_INITRD */ + +#ifdef CONFIG_PPC_OF + /* mark the RTAS pages as reserved */ + if ( rtas_data ) + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; + addr += PAGE_SIZE) + SetPageReserved(virt_to_page(addr)); +#endif +#ifdef CONFIG_PPC_PMAC + if (agp_special_page) + SetPageReserved(virt_to_page(agp_special_page)); +#endif + for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; + addr += PAGE_SIZE) { + if (!PageReserved(virt_to_page(addr))) + continue; + if (addr < (ulong) etext) + codepages++; + else if (addr >= (unsigned long)&__init_begin + && addr < (unsigned long)&__init_end) + initpages++; + else if (addr < (ulong) klimit) + datapages++; + } + +#ifdef CONFIG_HIGHMEM + { + unsigned long pfn; + + for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { + struct page *page = mem_map + pfn; + + ClearPageReserved(page); + set_page_count(page, 1); + __free_page(page); + totalhigh_pages++; + } + totalram_pages += totalhigh_pages; + } +#endif /* CONFIG_HIGHMEM */ + + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", + (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10), + codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), + initpages<< (PAGE_SHIFT-10), + (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + +#ifdef CONFIG_PPC_PMAC + if (agp_special_page) + printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); +#endif + + mem_init_done = 1; +} + +/* + * Set phys_avail to the amount of physical memory, + * less the kernel text/data/bss. + */ +void __init +set_phys_avail(unsigned long total_memory) +{ + unsigned long kstart, ksize; + + /* + * Initially, available physical memory is equivalent to all + * physical memory. + */ + + phys_avail.regions[0].address = PPC_MEMSTART; + phys_avail.regions[0].size = total_memory; + phys_avail.n_regions = 1; + + /* + * Map out the kernel text/data/bss from the available physical + * memory. + */ + + kstart = __pa(_stext); /* should be 0 */ + ksize = PAGE_ALIGN(klimit - _stext); + + mem_pieces_remove(&phys_avail, kstart, ksize, 0); + mem_pieces_remove(&phys_avail, 0, 0x4000, 0); + +#if defined(CONFIG_BLK_DEV_INITRD) + /* Remove the init RAM disk from the available memory. */ + if (initrd_start) { + mem_pieces_remove(&phys_avail, __pa(initrd_start), + initrd_end - initrd_start, 1); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_OF + /* remove the RTAS pages from the available memory */ + if (rtas_data) + mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); +#endif +#ifdef CONFIG_PPC_PMAC + /* Because of some uninorth weirdness, we need a page of + * memory as high as possible (it must be outside of the + * bus address seen as the AGP aperture). It will be used + * by the r128 DRM driver + * + * FIXME: We need to make sure that page doesn't overlap any of the\ + * above. This could be done by improving mem_pieces_find to be able + * to do a backward search from the end of the list. + */ + if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) { + agp_special_page = (total_memory - PAGE_SIZE); + mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); + agp_special_page = (unsigned long)__va(agp_special_page); + } +#endif /* CONFIG_PPC_PMAC */ +} + +/* Mark some memory as reserved by removing it from phys_avail. */ +void __init reserve_phys_mem(unsigned long start, unsigned long size) +{ + mem_pieces_remove(&phys_avail, start, size, 1); +} diff --git a/arch/powerpc/mm/init64.c b/arch/powerpc/mm/init64.c new file mode 100644 index 000000000000..81f6745b31ef --- /dev/null +++ b/arch/powerpc/mm/init64.c @@ -0,0 +1,385 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * Dave Engebretsen + * Rework for PPC64 port. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if PGTABLE_RANGE > USER_VSID_RANGE +#warning Limited user VSID range means pagetable space is wasted +#endif + +#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) +#warning TASK_SIZE is smaller than it needs to be. +#endif + +int mem_init_done; +unsigned long ioremap_bot = IMALLOC_BASE; +static unsigned long phbs_io_bot = PHBS_IO_BASE; + +extern pgd_t swapper_pg_dir[]; +extern struct task_struct *current_set[NR_CPUS]; + +unsigned long klimit = (unsigned long)_end; + +unsigned long _SDR1=0; +unsigned long _ASR=0; + +/* max amount of RAM to use */ +unsigned long __max_memory; + +/* info on what we think the IO hole is */ +unsigned long io_hole_start; +unsigned long io_hole_size; + +/* + * Do very early mm setup. + */ +void __init mm_init_ppc64(void) +{ +#ifndef CONFIG_PPC_ISERIES + unsigned long i; +#endif + + ppc64_boot_msg(0x100, "MM Init"); + + /* This is the story of the IO hole... please, keep seated, + * unfortunately, we are out of oxygen masks at the moment. + * So we need some rough way to tell where your big IO hole + * is. On pmac, it's between 2G and 4G, on POWER3, it's around + * that area as well, on POWER4 we don't have one, etc... + * We need that as a "hint" when sizing the TCE table on POWER3 + * So far, the simplest way that seem work well enough for us it + * to just assume that the first discontinuity in our physical + * RAM layout is the IO hole. That may not be correct in the future + * (and isn't on iSeries but then we don't care ;) + */ + +#ifndef CONFIG_PPC_ISERIES + for (i = 1; i < lmb.memory.cnt; i++) { + unsigned long base, prevbase, prevsize; + + prevbase = lmb.memory.region[i-1].base; + prevsize = lmb.memory.region[i-1].size; + base = lmb.memory.region[i].base; + if (base > (prevbase + prevsize)) { + io_hole_start = prevbase + prevsize; + io_hole_size = base - (prevbase + prevsize); + break; + } + } +#endif /* CONFIG_PPC_ISERIES */ + if (io_hole_start) + printk("IO Hole assumed to be %lx -> %lx\n", + io_hole_start, io_hole_start + io_hole_size - 1); + + ppc64_boot_msg(0x100, "MM Init Done"); +} + +void free_initmem(void) +{ + unsigned long addr; + + addr = (unsigned long)__init_begin; + for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { + memset((void *)addr, 0xcc, PAGE_SIZE); + ClearPageReserved(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); + free_page(addr); + totalram_pages++; + } + printk ("Freeing unused kernel memory: %luk freed\n", + ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + set_page_count(virt_to_page(start), 1); + free_page(start); + totalram_pages++; + } +} +#endif + +/* + * Initialize the bootmem system and give it all the memory we + * have available. + */ +#ifndef CONFIG_NEED_MULTIPLE_NODES +void __init do_init_bootmem(void) +{ + unsigned long i; + unsigned long start, bootmap_pages; + unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; + int boot_mapsize; + + /* + * Find an area to use for the bootmem bitmap. Calculate the size of + * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. + * Add 1 additional page in case the address isn't page-aligned. + */ + bootmap_pages = bootmem_bootmap_pages(total_pages); + + start = lmb_alloc(bootmap_pages<> PAGE_SHIFT, total_pages); + + max_pfn = max_low_pfn; + + /* Add all physical memory to the bootmem map, mark each area + * present. + */ + for (i=0; i < lmb.memory.cnt; i++) + free_bootmem(lmb.memory.region[i].base, + lmb_size_bytes(&lmb.memory, i)); + + /* reserve the sections we're already using */ + for (i=0; i < lmb.reserved.cnt; i++) + reserve_bootmem(lmb.reserved.region[i].base, + lmb_size_bytes(&lmb.reserved, i)); + + for (i=0; i < lmb.memory.cnt; i++) + memory_present(0, lmb_start_pfn(&lmb.memory, i), + lmb_end_pfn(&lmb.memory, i)); +} + +/* + * paging_init() sets up the page tables - in fact we've already done this. + */ +void __init paging_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long total_ram = lmb_phys_mem_size(); + unsigned long top_of_ram = lmb_end_of_DRAM(); + + printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", + top_of_ram, total_ram); + printk(KERN_INFO "Memory hole size: %ldMB\n", + (top_of_ram - total_ram) >> 20); + /* + * All pages are DMA-able so we put them all in the DMA zone. + */ + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + + zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; + + free_area_init_node(0, NODE_DATA(0), zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); +} +#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ + +static struct kcore_list kcore_vmem; + +static int __init setup_kcore(void) +{ + int i; + + for (i=0; i < lmb.memory.cnt; i++) { + unsigned long base, size; + struct kcore_list *kcore_mem; + + base = lmb.memory.region[i].base; + size = lmb.memory.region[i].size; + + /* GFP_ATOMIC to avoid might_sleep warnings during boot */ + kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); + if (!kcore_mem) + panic("mem_init: kmalloc failed\n"); + + kclist_add(kcore_mem, __va(base), size); + } + + kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); + + return 0; +} +module_init(setup_kcore); + +void __init mem_init(void) +{ +#ifdef CONFIG_NEED_MULTIPLE_NODES + int nid; +#endif + pg_data_t *pgdat; + unsigned long i; + struct page *page; + unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; + + num_physpages = max_low_pfn; /* RAM is assumed contiguous */ + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); + +#ifdef CONFIG_NEED_MULTIPLE_NODES + for_each_online_node(nid) { + if (NODE_DATA(nid)->node_spanned_pages != 0) { + printk("freeing bootmem node %x\n", nid); + totalram_pages += + free_all_bootmem_node(NODE_DATA(nid)); + } + } +#else + max_mapnr = num_physpages; + totalram_pages += free_all_bootmem(); +#endif + + for_each_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + page = pgdat_page_nr(pgdat, i); + if (PageReserved(page)) + reservedpages++; + } + } + + codesize = (unsigned long)&_etext - (unsigned long)&_stext; + initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin; + datasize = (unsigned long)&_edata - (unsigned long)&__init_end; + bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start; + + printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, " + "%luk reserved, %luk data, %luk bss, %luk init)\n", + (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10), + codesize >> 10, + reservedpages << (PAGE_SHIFT-10), + datasize >> 10, + bsssize >> 10, + initsize >> 10); + + mem_init_done = 1; + + /* Initialize the vDSO */ + vdso_init(); +} + +void __iomem * reserve_phb_iospace(unsigned long size) +{ + void __iomem *virt_addr; + + if (phbs_io_bot >= IMALLOC_BASE) + panic("reserve_phb_iospace(): phb io space overflow\n"); + + virt_addr = (void __iomem *) phbs_io_bot; + phbs_io_bot += size; + + return virt_addr; +} + +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) +{ + memset(addr, 0, kmem_cache_size(cache)); +} + +static const int pgtable_cache_size[2] = { + PTE_TABLE_SIZE, PMD_TABLE_SIZE +}; +static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { + "pgd_pte_cache", "pud_pmd_cache", +}; + +kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; + +void pgtable_cache_init(void) +{ + int i; + + BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]); + BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]); + BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]); + BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]); + + for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { + int size = pgtable_cache_size[i]; + const char *name = pgtable_cache_name[i]; + + pgtable_cache[i] = kmem_cache_create(name, + size, size, + SLAB_HWCACHE_ALIGN + | SLAB_MUST_HWCACHE_ALIGN, + zero_ctor, + NULL); + if (! pgtable_cache[i]) + panic("pgtable_cache_init(): could not create %s!\n", + name); + } +} + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, + unsigned long size, pgprot_t vma_prot) +{ + if (ppc_md.phys_mem_access_prot) + return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); + + if (!page_is_ram(addr >> PAGE_SHIFT)) + vma_prot = __pgprot(pgprot_val(vma_prot) + | _PAGE_GUARDED | _PAGE_NO_CACHE); + return vma_prot; +} +EXPORT_SYMBOL(phys_mem_access_prot); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c new file mode 100644 index 000000000000..345db08e5d20 --- /dev/null +++ b/arch/powerpc/mm/mem.c @@ -0,0 +1,299 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mem_pieces.h" +#include "mmu_decl.h" + +#ifndef CPU_FTR_COHERENT_ICACHE +#define CPU_FTR_COHERENT_ICACHE 0 /* XXX for now */ +#define CPU_FTR_NOEXECUTE 0 +#endif + +/* + * This is called by /dev/mem to know if a given address has to + * be mapped non-cacheable or not + */ +int page_is_ram(unsigned long pfn) +{ + unsigned long paddr = (pfn << PAGE_SHIFT); + +#ifndef CONFIG_PPC64 /* XXX for now */ + return paddr < __pa(high_memory); +#else + int i; + for (i=0; i < lmb.memory.cnt; i++) { + unsigned long base; + + base = lmb.memory.region[i].base; + + if ((paddr >= base) && + (paddr < (base + lmb.memory.region[i].size))) { + return 1; + } + } + + return 0; +#endif +} +EXPORT_SYMBOL(page_is_ram); + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, + unsigned long size, pgprot_t vma_prot) +{ + if (ppc_md.phys_mem_access_prot) + return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); + + if (!page_is_ram(addr >> PAGE_SHIFT)) + vma_prot = __pgprot(pgprot_val(vma_prot) + | _PAGE_GUARDED | _PAGE_NO_CACHE); + return vma_prot; +} +EXPORT_SYMBOL(phys_mem_access_prot); + +void show_mem(void) +{ + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + unsigned long highmem = 0; + struct page *page; + pg_data_t *pgdat; + unsigned long i; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + for_each_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + page = pgdat_page_nr(pgdat, i); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + } + printk("%ld pages of RAM\n", total); +#ifdef CONFIG_HIGHMEM + printk("%ld pages of HIGHMEM\n", highmem); +#endif + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); +} + +/* + * This is called when a page has been modified by the kernel. + * It just marks the page as not i-cache clean. We do the i-cache + * flush later when the page is given to a user process, if necessary. + */ +void flush_dcache_page(struct page *page) +{ + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &page->flags)) + clear_bit(PG_arch_1, &page->flags); +} +EXPORT_SYMBOL(flush_dcache_page); + +void flush_dcache_icache_page(struct page *page) +{ +#ifdef CONFIG_BOOKE + void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE); + __flush_dcache_icache(start); + kunmap_atomic(start, KM_PPC_SYNC_ICACHE); +#elif defined(CONFIG_8xx) + /* On 8xx there is no need to kmap since highmem is not supported */ + __flush_dcache_icache(page_address(page)); +#else + __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); +#endif + +} +void clear_user_page(void *page, unsigned long vaddr, struct page *pg) +{ + clear_page(page); + + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + /* + * We shouldnt have to do this, but some versions of glibc + * require it (ld.so assumes zero filled pages are icache clean) + * - Anton + */ + + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &pg->flags)) + clear_bit(PG_arch_1, &pg->flags); +} +EXPORT_SYMBOL(clear_user_page); + +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *pg) +{ + copy_page(vto, vfrom); + + /* + * We should be able to use the following optimisation, however + * there are two problems. + * Firstly a bug in some versions of binutils meant PLT sections + * were not marked executable. + * Secondly the first word in the GOT section is blrl, used + * to establish the GOT address. Until recently the GOT was + * not marked executable. + * - Anton + */ +#if 0 + if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0)) + return; +#endif + + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &pg->flags)) + clear_bit(PG_arch_1, &pg->flags); +} + +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) +{ + unsigned long maddr; + + maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + flush_icache_range(maddr, maddr + len); + kunmap(page); +} +EXPORT_SYMBOL(flush_icache_user_range); + +/* + * This is called at the end of handling a user page fault, when the + * fault has been handled by updating a PTE in the linux page tables. + * We use it to preload an HPTE into the hash table corresponding to + * the updated linux PTE. + * + * This must always be called with the mm->page_table_lock held + */ +void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + /* handle i-cache coherency */ + unsigned long pfn = pte_pfn(pte); +#ifdef CONFIG_PPC32 + pmd_t *pmd; +#else + unsigned long vsid; + void *pgdir; + pte_t *ptep; + int local = 0; + cpumask_t tmp; + unsigned long flags; +#endif + + /* handle i-cache coherency */ + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && + !cpu_has_feature(CPU_FTR_NOEXECUTE) && + pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + if (!PageReserved(page) + && !test_bit(PG_arch_1, &page->flags)) { + if (vma->vm_mm == current->active_mm) { +#ifdef CONFIG_8xx + /* On 8xx, cache control instructions (particularly + * "dcbst" from flush_dcache_icache) fault as write + * operation if there is an unpopulated TLB entry + * for the address in question. To workaround that, + * we invalidate the TLB here, thus avoiding dcbst + * misbehaviour. + */ + _tlbie(address); +#endif + __flush_dcache_icache((void *) address); + } else + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); + } + } + +#ifdef CONFIG_PPC_STD_MMU + /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ + if (!pte_young(pte) || address >= TASK_SIZE) + return; +#ifdef CONFIG_PPC32 + if (Hash == 0) + return; + pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address); + if (!pmd_none(*pmd)) + add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd)); +#else + pgdir = vma->vm_mm->pgd; + if (pgdir == NULL) + return; + + ptep = find_linux_pte(pgdir, ea); + if (!ptep) + return; + + vsid = get_vsid(vma->vm_mm->context.id, ea); + + local_irq_save(flags); + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) + local = 1; + + __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, + 0x300, local); + local_irq_restore(flags); +#endif +#endif +} diff --git a/arch/powerpc/mm/mem64.c b/arch/powerpc/mm/mem64.c new file mode 100644 index 000000000000..ef765a84433f --- /dev/null +++ b/arch/powerpc/mm/mem64.c @@ -0,0 +1,259 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * Dave Engebretsen + * Rework for PPC64 port. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This is called by /dev/mem to know if a given address has to + * be mapped non-cacheable or not + */ +int page_is_ram(unsigned long pfn) +{ + int i; + unsigned long paddr = (pfn << PAGE_SHIFT); + + for (i=0; i < lmb.memory.cnt; i++) { + unsigned long base; + + base = lmb.memory.region[i].base; + + if ((paddr >= base) && + (paddr < (base + lmb.memory.region[i].size))) { + return 1; + } + } + + return 0; +} +EXPORT_SYMBOL(page_is_ram); + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, + unsigned long size, pgprot_t vma_prot) +{ + if (ppc_md.phys_mem_access_prot) + return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); + + if (!page_is_ram(addr >> PAGE_SHIFT)) + vma_prot = __pgprot(pgprot_val(vma_prot) + | _PAGE_GUARDED | _PAGE_NO_CACHE); + return vma_prot; +} +EXPORT_SYMBOL(phys_mem_access_prot); + +void show_mem(void) +{ + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + struct page *page; + pg_data_t *pgdat; + unsigned long i; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + for_each_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + page = pgdat_page_nr(pgdat, i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + } + printk("%ld pages of RAM\n", total); + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); +} + +/* + * This is called when a page has been modified by the kernel. + * It just marks the page as not i-cache clean. We do the i-cache + * flush later when the page is given to a user process, if necessary. + */ +void flush_dcache_page(struct page *page) +{ + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &page->flags)) + clear_bit(PG_arch_1, &page->flags); +} +EXPORT_SYMBOL(flush_dcache_page); + +void clear_user_page(void *page, unsigned long vaddr, struct page *pg) +{ + clear_page(page); + + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + /* + * We shouldnt have to do this, but some versions of glibc + * require it (ld.so assumes zero filled pages are icache clean) + * - Anton + */ + + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &pg->flags)) + clear_bit(PG_arch_1, &pg->flags); +} +EXPORT_SYMBOL(clear_user_page); + +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *pg) +{ + copy_page(vto, vfrom); + + /* + * We should be able to use the following optimisation, however + * there are two problems. + * Firstly a bug in some versions of binutils meant PLT sections + * were not marked executable. + * Secondly the first word in the GOT section is blrl, used + * to establish the GOT address. Until recently the GOT was + * not marked executable. + * - Anton + */ +#if 0 + if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0)) + return; +#endif + + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + return; + + /* avoid an atomic op if possible */ + if (test_bit(PG_arch_1, &pg->flags)) + clear_bit(PG_arch_1, &pg->flags); +} + +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) +{ + unsigned long maddr; + + maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK); + flush_icache_range(maddr, maddr + len); +} +EXPORT_SYMBOL(flush_icache_user_range); + +/* + * This is called at the end of handling a user page fault, when the + * fault has been handled by updating a PTE in the linux page tables. + * We use it to preload an HPTE into the hash table corresponding to + * the updated linux PTE. + * + * This must always be called with the mm->page_table_lock held + */ +void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea, + pte_t pte) +{ + unsigned long vsid; + void *pgdir; + pte_t *ptep; + int local = 0; + cpumask_t tmp; + unsigned long flags; + + /* handle i-cache coherency */ + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && + !cpu_has_feature(CPU_FTR_NOEXECUTE)) { + unsigned long pfn = pte_pfn(pte); + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + if (!PageReserved(page) + && !test_bit(PG_arch_1, &page->flags)) { + __flush_dcache_icache(page_address(page)); + set_bit(PG_arch_1, &page->flags); + } + } + } + + /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ + if (!pte_young(pte)) + return; + + pgdir = vma->vm_mm->pgd; + if (pgdir == NULL) + return; + + ptep = find_linux_pte(pgdir, ea); + if (!ptep) + return; + + vsid = get_vsid(vma->vm_mm->context.id, ea); + + local_irq_save(flags); + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) + local = 1; + + __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, + 0x300, local); + local_irq_restore(flags); +} diff --git a/arch/powerpc/mm/mem_pieces.c b/arch/powerpc/mm/mem_pieces.c new file mode 100644 index 000000000000..3d639052017e --- /dev/null +++ b/arch/powerpc/mm/mem_pieces.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1996 Paul Mackerras + * Changes to accommodate Power Macintoshes. + * Cort Dougan + * Rewrites. + * Grant Erickson + * General rework and split from mm/init.c. + * + * Module name: mem_pieces.c + * + * Description: + * Routines and data structures for manipulating and representing + * phyiscal memory extents (i.e. address/length pairs). + * + */ + +#include +#include +#include +#include +#include + +#include "mem_pieces.h" + +extern struct mem_pieces phys_avail; + +static void mem_pieces_print(struct mem_pieces *); + +/* + * Scan a region for a piece of a given size with the required alignment. + */ +void __init * +mem_pieces_find(unsigned int size, unsigned int align) +{ + int i; + unsigned a, e; + struct mem_pieces *mp = &phys_avail; + + for (i = 0; i < mp->n_regions; ++i) { + a = mp->regions[i].address; + e = a + mp->regions[i].size; + a = (a + align - 1) & -align; + if (a + size <= e) { + mem_pieces_remove(mp, a, size, 1); + return (void *) __va(a); + } + } + panic("Couldn't find %u bytes at %u alignment\n", size, align); + + return NULL; +} + +/* + * Remove some memory from an array of pieces + */ +void __init +mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size, + int must_exist) +{ + int i, j; + unsigned int end, rs, re; + struct reg_property *rp; + + end = start + size; + for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) { + if (end > rp->address && start < rp->address + rp->size) + break; + } + if (i >= mp->n_regions) { + if (must_exist) + printk("mem_pieces_remove: [%x,%x) not in any region\n", + start, end); + return; + } + for (; i < mp->n_regions && end > rp->address; ++i, ++rp) { + rs = rp->address; + re = rs + rp->size; + if (must_exist && (start < rs || end > re)) { + printk("mem_pieces_remove: bad overlap [%x,%x) with", + start, end); + mem_pieces_print(mp); + must_exist = 0; + } + if (start > rs) { + rp->size = start - rs; + if (end < re) { + /* need to split this entry */ + if (mp->n_regions >= MEM_PIECES_MAX) + panic("eek... mem_pieces overflow"); + for (j = mp->n_regions; j > i + 1; --j) + mp->regions[j] = mp->regions[j-1]; + ++mp->n_regions; + rp[1].address = end; + rp[1].size = re - end; + } + } else { + if (end < re) { + rp->address = end; + rp->size = re - end; + } else { + /* need to delete this entry */ + for (j = i; j < mp->n_regions - 1; ++j) + mp->regions[j] = mp->regions[j+1]; + --mp->n_regions; + --i; + --rp; + } + } + } +} + +static void __init +mem_pieces_print(struct mem_pieces *mp) +{ + int i; + + for (i = 0; i < mp->n_regions; ++i) + printk(" [%x, %x)", mp->regions[i].address, + mp->regions[i].address + mp->regions[i].size); + printk("\n"); +} + +void __init +mem_pieces_sort(struct mem_pieces *mp) +{ + unsigned long a, s; + int i, j; + + for (i = 1; i < mp->n_regions; ++i) { + a = mp->regions[i].address; + s = mp->regions[i].size; + for (j = i - 1; j >= 0; --j) { + if (a >= mp->regions[j].address) + break; + mp->regions[j+1] = mp->regions[j]; + } + mp->regions[j+1].address = a; + mp->regions[j+1].size = s; + } +} + +void __init +mem_pieces_coalesce(struct mem_pieces *mp) +{ + unsigned long a, s, ns; + int i, j, d; + + d = 0; + for (i = 0; i < mp->n_regions; i = j) { + a = mp->regions[i].address; + s = mp->regions[i].size; + for (j = i + 1; j < mp->n_regions + && mp->regions[j].address - a <= s; ++j) { + ns = mp->regions[j].address + mp->regions[j].size - a; + if (ns > s) + s = ns; + } + mp->regions[d].address = a; + mp->regions[d].size = s; + ++d; + } + mp->n_regions = d; +} diff --git a/arch/powerpc/mm/mem_pieces.h b/arch/powerpc/mm/mem_pieces.h new file mode 100644 index 000000000000..e2b700dc7f18 --- /dev/null +++ b/arch/powerpc/mm/mem_pieces.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1996 Paul Mackerras + * Changes to accommodate Power Macintoshes. + * Cort Dougan + * Rewrites. + * Grant Erickson + * General rework and split from mm/init.c. + * + * Module name: mem_pieces.h + * + * Description: + * Routines and data structures for manipulating and representing + * phyiscal memory extents (i.e. address/length pairs). + * + */ + +#ifndef __MEM_PIECES_H__ +#define __MEM_PIECES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Type Definitions */ + +#define MEM_PIECES_MAX 32 + +struct mem_pieces { + int n_regions; + struct reg_property regions[MEM_PIECES_MAX]; +}; + +/* Function Prototypes */ + +extern void *mem_pieces_find(unsigned int size, unsigned int align); +extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start, + unsigned int size, int must_exist); +extern void mem_pieces_coalesce(struct mem_pieces *mp); +extern void mem_pieces_sort(struct mem_pieces *mp); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEM_PIECES_H__ */ diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c new file mode 100644 index 000000000000..a8816e0f6a86 --- /dev/null +++ b/arch/powerpc/mm/mmu_context.c @@ -0,0 +1,86 @@ +/* + * This file contains the routines for handling the MMU on those + * PowerPC implementations where the MMU substantially follows the + * architecture specification. This includes the 6xx, 7xx, 7xxx, + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include + +#include +#include + +mm_context_t next_mmu_context; +unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; +#ifdef FEW_CONTEXTS +atomic_t nr_free_contexts; +struct mm_struct *context_mm[LAST_CONTEXT+1]; +void steal_context(void); +#endif /* FEW_CONTEXTS */ + +/* + * Initialize the context management stuff. + */ +void __init +mmu_context_init(void) +{ + /* + * Some processors have too few contexts to reserve one for + * init_mm, and require using context 0 for a normal task. + * Other processors reserve the use of context zero for the kernel. + * This code assumes FIRST_CONTEXT < 32. + */ + context_map[0] = (1 << FIRST_CONTEXT) - 1; + next_mmu_context = FIRST_CONTEXT; +#ifdef FEW_CONTEXTS + atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1); +#endif /* FEW_CONTEXTS */ +} + +#ifdef FEW_CONTEXTS +/* + * Steal a context from a task that has one at the moment. + * This is only used on 8xx and 4xx and we presently assume that + * they don't do SMP. If they do then this will have to check + * whether the MM we steal is in use. + * We also assume that this is only used on systems that don't + * use an MMU hash table - this is true for 8xx and 4xx. + * This isn't an LRU system, it just frees up each context in + * turn (sort-of pseudo-random replacement :). This would be the + * place to implement an LRU scheme if anyone was motivated to do it. + * -- paulus + */ +void +steal_context(void) +{ + struct mm_struct *mm; + + /* free up context `next_mmu_context' */ + /* if we shouldn't free context 0, don't... */ + if (next_mmu_context < FIRST_CONTEXT) + next_mmu_context = FIRST_CONTEXT; + mm = context_mm[next_mmu_context]; + flush_tlb_mm(mm); + destroy_context(mm); +} +#endif /* FEW_CONTEXTS */ diff --git a/arch/powerpc/mm/mmu_context64.c b/arch/powerpc/mm/mmu_context64.c new file mode 100644 index 000000000000..714a84dd8d5d --- /dev/null +++ b/arch/powerpc/mm/mmu_context64.c @@ -0,0 +1,63 @@ +/* + * MMU context allocation for 64-bit kernels. + * + * Copyright (C) 2004 Anton Blanchard, IBM Corp. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static DEFINE_SPINLOCK(mmu_context_lock); +static DEFINE_IDR(mmu_context_idr); + +int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + int index; + int err; + +again: + if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL)) + return -ENOMEM; + + spin_lock(&mmu_context_lock); + err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index); + spin_unlock(&mmu_context_lock); + + if (err == -EAGAIN) + goto again; + else if (err) + return err; + + if (index > MAX_CONTEXT) { + idr_remove(&mmu_context_idr, index); + return -ENOMEM; + } + + mm->context.id = index; + + return 0; +} + +void destroy_context(struct mm_struct *mm) +{ + spin_lock(&mmu_context_lock); + idr_remove(&mmu_context_idr, mm->context.id); + spin_unlock(&mmu_context_lock); + + mm->context.id = NO_CONTEXT; +} diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h new file mode 100644 index 000000000000..540f3292b229 --- /dev/null +++ b/arch/powerpc/mm/mmu_decl.h @@ -0,0 +1,85 @@ +/* + * Declarations of procedures and variables shared between files + * in arch/ppc/mm/. + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ +#include +#include + +extern void mapin_ram(void); +extern int map_page(unsigned long va, phys_addr_t pa, int flags); +extern void setbat(int index, unsigned long virt, unsigned long phys, + unsigned int size, int flags); +extern void reserve_phys_mem(unsigned long start, unsigned long size); +extern void settlbcam(int index, unsigned long virt, phys_addr_t phys, + unsigned int size, int flags, unsigned int pid); +extern void invalidate_tlbcam_entry(int index); + +extern int __map_without_bats; +extern unsigned long ioremap_base; +extern unsigned long ioremap_bot; +extern unsigned int rtas_data, rtas_size; + +extern unsigned long total_memory; +extern unsigned long total_lowmem; +extern int mem_init_done; + +extern PTE *Hash, *Hash_end; +extern unsigned long Hash_size, Hash_mask; + +extern unsigned int num_tlbcam_entries; + +/* ...and now those things that may be slightly different between processor + * architectures. -- Dan + */ +#if defined(CONFIG_8xx) +#define flush_HPTE(X, va, pg) _tlbie(va) +#define MMU_init_hw() do { } while(0) +#define mmu_mapin_ram() (0UL) + +#elif defined(CONFIG_4xx) +#define flush_HPTE(X, va, pg) _tlbie(va) +extern void MMU_init_hw(void); +extern unsigned long mmu_mapin_ram(void); + +#elif defined(CONFIG_FSL_BOOKE) +#define flush_HPTE(X, va, pg) _tlbie(va) +extern void MMU_init_hw(void); +extern unsigned long mmu_mapin_ram(void); +extern void adjust_total_lowmem(void); + +#else +/* anything except 4xx or 8xx */ +extern void MMU_init_hw(void); +extern unsigned long mmu_mapin_ram(void); + +/* Be careful....this needs to be updated if we ever encounter 603 SMPs, + * which includes all new 82xx processors. We need tlbie/tlbsync here + * in that case (I think). -- Dan. + */ +static inline void flush_HPTE(unsigned context, unsigned long va, + unsigned long pdval) +{ + if ((Hash != 0) && + cpu_has_feature(CPU_FTR_HPTE_TABLE)) + flush_hash_pages(0, va, pdval, 1); + else + _tlbie(va); +} +#endif diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c new file mode 100644 index 000000000000..81a3d7446d37 --- /dev/null +++ b/arch/powerpc/mm/pgtable.c @@ -0,0 +1,470 @@ +/* + * This file contains the routines setting up the linux page tables. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mmu_decl.h" + +unsigned long ioremap_base; +unsigned long ioremap_bot; +int io_bat_index; + +#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) +#define HAVE_BATS 1 +#endif + +#if defined(CONFIG_FSL_BOOKE) +#define HAVE_TLBCAM 1 +#endif + +extern char etext[], _stext[]; + +#ifdef CONFIG_SMP +extern void hash_page_sync(void); +#endif + +#ifdef HAVE_BATS +extern unsigned long v_mapped_by_bats(unsigned long va); +extern unsigned long p_mapped_by_bats(unsigned long pa); +void setbat(int index, unsigned long virt, unsigned long phys, + unsigned int size, int flags); + +#else /* !HAVE_BATS */ +#define v_mapped_by_bats(x) (0UL) +#define p_mapped_by_bats(x) (0UL) +#endif /* HAVE_BATS */ + +#ifdef HAVE_TLBCAM +extern unsigned int tlbcam_index; +extern unsigned long v_mapped_by_tlbcam(unsigned long va); +extern unsigned long p_mapped_by_tlbcam(unsigned long pa); +#else /* !HAVE_TLBCAM */ +#define v_mapped_by_tlbcam(x) (0UL) +#define p_mapped_by_tlbcam(x) (0UL) +#endif /* HAVE_TLBCAM */ + +#ifdef CONFIG_PTE_64BIT +/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ +#define PGDIR_ORDER 1 +#else +#define PGDIR_ORDER 0 +#endif + +pgd_t *pgd_alloc(struct mm_struct *mm) +{ + pgd_t *ret; + + ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER); + return ret; +} + +void pgd_free(pgd_t *pgd) +{ + free_pages((unsigned long)pgd, PGDIR_ORDER); +} + +pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + extern int mem_init_done; + extern void *early_get_page(void); + + if (mem_init_done) { + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + } else { + pte = (pte_t *)early_get_page(); + if (pte) + clear_page(pte); + } + return pte; +} + +struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *ptepage; + +#ifdef CONFIG_HIGHPTE + int flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT; +#else + int flags = GFP_KERNEL | __GFP_REPEAT; +#endif + + ptepage = alloc_pages(flags, 0); + if (ptepage) + clear_highpage(ptepage); + return ptepage; +} + +void pte_free_kernel(pte_t *pte) +{ +#ifdef CONFIG_SMP + hash_page_sync(); +#endif + free_page((unsigned long)pte); +} + +void pte_free(struct page *ptepage) +{ +#ifdef CONFIG_SMP + hash_page_sync(); +#endif + __free_page(ptepage); +} + +#ifndef CONFIG_PHYS_64BIT +void __iomem * +ioremap(phys_addr_t addr, unsigned long size) +{ + return __ioremap(addr, size, _PAGE_NO_CACHE); +} +#else /* CONFIG_PHYS_64BIT */ +void __iomem * +ioremap64(unsigned long long addr, unsigned long size) +{ + return __ioremap(addr, size, _PAGE_NO_CACHE); +} + +void __iomem * +ioremap(phys_addr_t addr, unsigned long size) +{ + phys_addr_t addr64 = fixup_bigphys_addr(addr, size); + + return ioremap64(addr64, size); +} +#endif /* CONFIG_PHYS_64BIT */ + +void __iomem * +__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) +{ + unsigned long v, i; + phys_addr_t p; + int err; + + /* + * Choose an address to map it to. + * Once the vmalloc system is running, we use it. + * Before then, we use space going down from ioremap_base + * (ioremap_bot records where we're up to). + */ + p = addr & PAGE_MASK; + size = PAGE_ALIGN(addr + size) - p; + + /* + * If the address lies within the first 16 MB, assume it's in ISA + * memory space + */ + if (p < 16*1024*1024) + p += _ISA_MEM_BASE; + + /* + * Don't allow anybody to remap normal RAM that we're using. + * mem_init() sets high_memory so only do the check after that. + */ + if ( mem_init_done && (p < virt_to_phys(high_memory)) ) + { + printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p, + __builtin_return_address(0)); + return NULL; + } + + if (size == 0) + return NULL; + + /* + * Is it already mapped? Perhaps overlapped by a previous + * BAT mapping. If the whole area is mapped then we're done, + * otherwise remap it since we want to keep the virt addrs for + * each request contiguous. + * + * We make the assumption here that if the bottom and top + * of the range we want are mapped then it's mapped to the + * same virt address (and this is contiguous). + * -- Cort + */ + if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) + goto out; + + if ((v = p_mapped_by_tlbcam(p))) + goto out; + + if (mem_init_done) { + struct vm_struct *area; + area = get_vm_area(size, VM_IOREMAP); + if (area == 0) + return NULL; + v = (unsigned long) area->addr; + } else { + v = (ioremap_bot -= size); + } + + if ((flags & _PAGE_PRESENT) == 0) + flags |= _PAGE_KERNEL; + if (flags & _PAGE_NO_CACHE) + flags |= _PAGE_GUARDED; + + /* + * Should check if it is a candidate for a BAT mapping + */ + + err = 0; + for (i = 0; i < size && err == 0; i += PAGE_SIZE) + err = map_page(v+i, p+i, flags); + if (err) { + if (mem_init_done) + vunmap((void *)v); + return NULL; + } + +out: + return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK)); +} + +void iounmap(volatile void __iomem *addr) +{ + /* + * If mapped by BATs then there is nothing to do. + * Calling vfree() generates a benign warning. + */ + if (v_mapped_by_bats((unsigned long)addr)) return; + + if (addr > high_memory && (unsigned long) addr < ioremap_bot) + vunmap((void *) (PAGE_MASK & (unsigned long)addr)); +} + +void __iomem *ioport_map(unsigned long port, unsigned int len) +{ + return (void __iomem *) (port + _IO_BASE); +} + +void ioport_unmap(void __iomem *addr) +{ + /* Nothing to do */ +} +EXPORT_SYMBOL(ioport_map); +EXPORT_SYMBOL(ioport_unmap); + +int +map_page(unsigned long va, phys_addr_t pa, int flags) +{ + pmd_t *pd; + pte_t *pg; + int err = -ENOMEM; + + spin_lock(&init_mm.page_table_lock); + /* Use upper 10 bits of VA to index the first level map */ + pd = pmd_offset(pgd_offset_k(va), va); + /* Use middle 10 bits of VA to index the second-level map */ + pg = pte_alloc_kernel(&init_mm, pd, va); + if (pg != 0) { + err = 0; + set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags))); + if (mem_init_done) + flush_HPTE(0, va, pmd_val(*pd)); + } + spin_unlock(&init_mm.page_table_lock); + return err; +} + +/* + * Map in all of physical memory starting at KERNELBASE. + */ +void __init mapin_ram(void) +{ + unsigned long v, p, s, f; + + s = mmu_mapin_ram(); + v = KERNELBASE + s; + p = PPC_MEMSTART + s; + for (; s < total_lowmem; s += PAGE_SIZE) { + if ((char *) v >= _stext && (char *) v < etext) + f = _PAGE_RAM_TEXT; + else + f = _PAGE_RAM; + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; + } +} + +/* is x a power of 2? */ +#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) + +/* is x a power of 4? */ +#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1)) + +/* + * Set up a mapping for a block of I/O. + * virt, phys, size must all be page-aligned. + * This should only be called before ioremap is called. + */ +void __init io_block_mapping(unsigned long virt, phys_addr_t phys, + unsigned int size, int flags) +{ + int i; + + if (virt > KERNELBASE && virt < ioremap_bot) + ioremap_bot = ioremap_base = virt; + +#ifdef HAVE_BATS + /* + * Use a BAT for this if possible... + */ + if (io_bat_index < 2 && is_power_of_2(size) + && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) { + setbat(io_bat_index, virt, phys, size, flags); + ++io_bat_index; + return; + } +#endif /* HAVE_BATS */ + +#ifdef HAVE_TLBCAM + /* + * Use a CAM for this if possible... + */ + if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size) + && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) { + settlbcam(tlbcam_index, virt, phys, size, flags, 0); + ++tlbcam_index; + return; + } +#endif /* HAVE_TLBCAM */ + + /* No BATs available, put it in the page tables. */ + for (i = 0; i < size; i += PAGE_SIZE) + map_page(virt + i, phys + i, flags); +} + +/* Scan the real Linux page tables and return a PTE pointer for + * a virtual address in a context. + * Returns true (1) if PTE was found, zero otherwise. The pointer to + * the PTE pointer is unmodified if PTE is not found. + */ +int +get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int retval = 0; + + pgd = pgd_offset(mm, addr & PAGE_MASK); + if (pgd) { + pmd = pmd_offset(pgd, addr & PAGE_MASK); + if (pmd_present(*pmd)) { + pte = pte_offset_map(pmd, addr & PAGE_MASK); + if (pte) { + retval = 1; + *ptep = pte; + /* XXX caller needs to do pte_unmap, yuck */ + } + } + } + return(retval); +} + +/* Find physical address for this virtual address. Normally used by + * I/O functions, but anyone can call it. + */ +unsigned long iopa(unsigned long addr) +{ + unsigned long pa; + + /* I don't know why this won't work on PMacs or CHRP. It + * appears there is some bug, or there is some implicit + * mapping done not properly represented by BATs or in page + * tables.......I am actively working on resolving this, but + * can't hold up other stuff. -- Dan + */ + pte_t *pte; + struct mm_struct *mm; + + /* Check the BATs */ + pa = v_mapped_by_bats(addr); + if (pa) + return pa; + + /* Allow mapping of user addresses (within the thread) + * for DMA if necessary. + */ + if (addr < TASK_SIZE) + mm = current->mm; + else + mm = &init_mm; + + pa = 0; + if (get_pteptr(mm, addr, &pte)) { + pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); + pte_unmap(pte); + } + + return(pa); +} + +/* This is will find the virtual address for a physical one.... + * Swiped from APUS, could be dangerous :-). + * This is only a placeholder until I really find a way to make this + * work. -- Dan + */ +unsigned long +mm_ptov (unsigned long paddr) +{ + unsigned long ret; +#if 0 + if (paddr < 16*1024*1024) + ret = ZTWO_VADDR(paddr); + else { + int i; + + for (i = 0; i < kmap_chunk_count;){ + unsigned long phys = kmap_chunks[i++]; + unsigned long size = kmap_chunks[i++]; + unsigned long virt = kmap_chunks[i++]; + if (paddr >= phys + && paddr < (phys + size)){ + ret = virt + paddr - phys; + goto exit; + } + } + + ret = (unsigned long) __va(paddr); + } +exit: +#ifdef DEBUGPV + printk ("PTOV(%lx)=%lx\n", paddr, ret); +#endif +#else + ret = (unsigned long)paddr + KERNELBASE; +#endif + return ret; +} + diff --git a/arch/powerpc/mm/pgtable64.c b/arch/powerpc/mm/pgtable64.c new file mode 100644 index 000000000000..724f97e5dee5 --- /dev/null +++ b/arch/powerpc/mm/pgtable64.c @@ -0,0 +1,357 @@ +/* + * This file contains ioremap and related functions for 64-bit machines. + * + * Derived from arch/ppc64/mm/init.c + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * Dave Engebretsen + * Rework for PPC64 port. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if PGTABLE_RANGE > USER_VSID_RANGE +#warning Limited user VSID range means pagetable space is wasted +#endif + +#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) +#warning TASK_SIZE is smaller than it needs to be. +#endif + +int mem_init_done; +unsigned long ioremap_bot = IMALLOC_BASE; +static unsigned long phbs_io_bot = PHBS_IO_BASE; + +extern pgd_t swapper_pg_dir[]; +extern struct task_struct *current_set[NR_CPUS]; + +unsigned long klimit = (unsigned long)_end; + +/* max amount of RAM to use */ +unsigned long __max_memory; + +/* info on what we think the IO hole is */ +unsigned long io_hole_start; +unsigned long io_hole_size; + +#ifdef CONFIG_PPC_ISERIES + +void __iomem *ioremap(unsigned long addr, unsigned long size) +{ + return (void __iomem *)addr; +} + +extern void __iomem *__ioremap(unsigned long addr, unsigned long size, + unsigned long flags) +{ + return (void __iomem *)addr; +} + +void iounmap(volatile void __iomem *addr) +{ + return; +} + +#else + +/* + * map_io_page currently only called by __ioremap + * map_io_page adds an entry to the ioremap page table + * and adds an entry to the HPT, possibly bolting it + */ +static int map_io_page(unsigned long ea, unsigned long pa, int flags) +{ + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + unsigned long vsid; + + if (mem_init_done) { + spin_lock(&init_mm.page_table_lock); + pgdp = pgd_offset_k(ea); + pudp = pud_alloc(&init_mm, pgdp, ea); + if (!pudp) + return -ENOMEM; + pmdp = pmd_alloc(&init_mm, pudp, ea); + if (!pmdp) + return -ENOMEM; + ptep = pte_alloc_kernel(&init_mm, pmdp, ea); + if (!ptep) + return -ENOMEM; + set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, + __pgprot(flags))); + spin_unlock(&init_mm.page_table_lock); + } else { + unsigned long va, vpn, hash, hpteg; + + /* + * If the mm subsystem is not fully up, we cannot create a + * linux page table entry for this mapping. Simply bolt an + * entry in the hardware page table. + */ + vsid = get_kernel_vsid(ea); + va = (vsid << 28) | (ea & 0xFFFFFFF); + vpn = va >> PAGE_SHIFT; + + hash = hpt_hash(vpn, 0); + + hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); + + /* Panic if a pte grpup is full */ + if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, + HPTE_V_BOLTED, + _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX) + == -1) { + panic("map_io_page: could not insert mapping"); + } + } + return 0; +} + + +static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, + unsigned long ea, unsigned long size, + unsigned long flags) +{ + unsigned long i; + + if ((flags & _PAGE_PRESENT) == 0) + flags |= pgprot_val(PAGE_KERNEL); + + for (i = 0; i < size; i += PAGE_SIZE) + if (map_io_page(ea+i, pa+i, flags)) + return NULL; + + return (void __iomem *) (ea + (addr & ~PAGE_MASK)); +} + + +void __iomem * +ioremap(unsigned long addr, unsigned long size) +{ + return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); +} + +void __iomem * __ioremap(unsigned long addr, unsigned long size, + unsigned long flags) +{ + unsigned long pa, ea; + void __iomem *ret; + + /* + * Choose an address to map it to. + * Once the imalloc system is running, we use it. + * Before that, we map using addresses going + * up from ioremap_bot. imalloc will use + * the addresses from ioremap_bot through + * IMALLOC_END + * + */ + pa = addr & PAGE_MASK; + size = PAGE_ALIGN(addr + size) - pa; + + if (size == 0) + return NULL; + + if (mem_init_done) { + struct vm_struct *area; + area = im_get_free_area(size); + if (area == NULL) + return NULL; + ea = (unsigned long)(area->addr); + ret = __ioremap_com(addr, pa, ea, size, flags); + if (!ret) + im_free(area->addr); + } else { + ea = ioremap_bot; + ret = __ioremap_com(addr, pa, ea, size, flags); + if (ret) + ioremap_bot += size; + } + return ret; +} + +#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) + +int __ioremap_explicit(unsigned long pa, unsigned long ea, + unsigned long size, unsigned long flags) +{ + struct vm_struct *area; + void __iomem *ret; + + /* For now, require page-aligned values for pa, ea, and size */ + if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || + !IS_PAGE_ALIGNED(size)) { + printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__); + return 1; + } + + if (!mem_init_done) { + /* Two things to consider in this case: + * 1) No records will be kept (imalloc, etc) that the region + * has been remapped + * 2) It won't be easy to iounmap() the region later (because + * of 1) + */ + ; + } else { + area = im_get_area(ea, size, + IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS); + if (area == NULL) { + /* Expected when PHB-dlpar is in play */ + return 1; + } + if (ea != (unsigned long) area->addr) { + printk(KERN_ERR "unexpected addr return from " + "im_get_area\n"); + return 1; + } + } + + ret = __ioremap_com(pa, pa, ea, size, flags); + if (ret == NULL) { + printk(KERN_ERR "ioremap_explicit() allocation failure !\n"); + return 1; + } + if (ret != (void *) ea) { + printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); + return 1; + } + + return 0; +} + +/* + * Unmap an IO region and remove it from imalloc'd list. + * Access to IO memory should be serialized by driver. + * This code is modeled after vmalloc code - unmap_vm_area() + * + * XXX what about calls before mem_init_done (ie python_countermeasures()) + */ +void iounmap(volatile void __iomem *token) +{ + void *addr; + + if (!mem_init_done) + return; + + addr = (void *) ((unsigned long __force) token & PAGE_MASK); + + im_free(addr); +} + +static int iounmap_subset_regions(unsigned long addr, unsigned long size) +{ + struct vm_struct *area; + + /* Check whether subsets of this region exist */ + area = im_get_area(addr, size, IM_REGION_SUPERSET); + if (area == NULL) + return 1; + + while (area) { + iounmap((void __iomem *) area->addr); + area = im_get_area(addr, size, + IM_REGION_SUPERSET); + } + + return 0; +} + +int iounmap_explicit(volatile void __iomem *start, unsigned long size) +{ + struct vm_struct *area; + unsigned long addr; + int rc; + + addr = (unsigned long __force) start & PAGE_MASK; + + /* Verify that the region either exists or is a subset of an existing + * region. In the latter case, split the parent region to create + * the exact region + */ + area = im_get_area(addr, size, + IM_REGION_EXISTS | IM_REGION_SUBSET); + if (area == NULL) { + /* Determine whether subset regions exist. If so, unmap */ + rc = iounmap_subset_regions(addr, size); + if (rc) { + printk(KERN_ERR + "%s() cannot unmap nonexistent range 0x%lx\n", + __FUNCTION__, addr); + return 1; + } + } else { + iounmap((void __iomem *) area->addr); + } + /* + * FIXME! This can't be right: + iounmap(area->addr); + * Maybe it should be "iounmap(area);" + */ + return 0; +} + +#endif + +EXPORT_SYMBOL(ioremap); +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(iounmap); diff --git a/arch/powerpc/mm/ppc_mmu.c b/arch/powerpc/mm/ppc_mmu.c new file mode 100644 index 000000000000..9a381ed5eb21 --- /dev/null +++ b/arch/powerpc/mm/ppc_mmu.c @@ -0,0 +1,296 @@ +/* + * This file contains the routines for handling the MMU on those + * PowerPC implementations where the MMU substantially follows the + * architecture specification. This includes the 6xx, 7xx, 7xxx, + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mmu_decl.h" +#include "mem_pieces.h" + +PTE *Hash, *Hash_end; +unsigned long Hash_size, Hash_mask; +unsigned long _SDR1; + +union ubat { /* BAT register values to be loaded */ + BAT bat; +#ifdef CONFIG_PPC64BRIDGE + u64 word[2]; +#else + u32 word[2]; +#endif +} BATS[4][2]; /* 4 pairs of IBAT, DBAT */ + +struct batrange { /* stores address ranges mapped by BATs */ + unsigned long start; + unsigned long limit; + unsigned long phys; +} bat_addrs[4]; + +/* + * Return PA for this VA if it is mapped by a BAT, or 0 + */ +unsigned long v_mapped_by_bats(unsigned long va) +{ + int b; + for (b = 0; b < 4; ++b) + if (va >= bat_addrs[b].start && va < bat_addrs[b].limit) + return bat_addrs[b].phys + (va - bat_addrs[b].start); + return 0; +} + +/* + * Return VA for a given PA or 0 if not mapped + */ +unsigned long p_mapped_by_bats(unsigned long pa) +{ + int b; + for (b = 0; b < 4; ++b) + if (pa >= bat_addrs[b].phys + && pa < (bat_addrs[b].limit-bat_addrs[b].start) + +bat_addrs[b].phys) + return bat_addrs[b].start+(pa-bat_addrs[b].phys); + return 0; +} + +unsigned long __init mmu_mapin_ram(void) +{ +#ifdef CONFIG_POWER4 + return 0; +#else + unsigned long tot, bl, done; + unsigned long max_size = (256<<20); + unsigned long align; + + if (__map_without_bats) + return 0; + + /* Set up BAT2 and if necessary BAT3 to cover RAM. */ + + /* Make sure we don't map a block larger than the + smallest alignment of the physical address. */ + /* alignment of PPC_MEMSTART */ + align = ~(PPC_MEMSTART-1) & PPC_MEMSTART; + /* set BAT block size to MIN(max_size, align) */ + if (align && align < max_size) + max_size = align; + + tot = total_lowmem; + for (bl = 128<<10; bl < max_size; bl <<= 1) { + if (bl * 2 > tot) + break; + } + + setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM); + done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; + if ((done < tot) && !bat_addrs[3].limit) { + /* use BAT3 to cover a bit more */ + tot -= done; + for (bl = 128<<10; bl < max_size; bl <<= 1) + if (bl * 2 > tot) + break; + setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM); + done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1; + } + + return done; +#endif +} + +/* + * Set up one of the I/D BAT (block address translation) register pairs. + * The parameters are not checked; in particular size must be a power + * of 2 between 128k and 256M. + */ +void __init setbat(int index, unsigned long virt, unsigned long phys, + unsigned int size, int flags) +{ + unsigned int bl; + int wimgxpp; + union ubat *bat = BATS[index]; + + if (((flags & _PAGE_NO_CACHE) == 0) && + cpu_has_feature(CPU_FTR_NEED_COHERENT)) + flags |= _PAGE_COHERENT; + + bl = (size >> 17) - 1; + if (PVR_VER(mfspr(SPRN_PVR)) != 1) { + /* 603, 604, etc. */ + /* Do DBAT first */ + wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE + | _PAGE_COHERENT | _PAGE_GUARDED); + wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; + bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ + bat[1].word[1] = phys | wimgxpp; +#ifndef CONFIG_KGDB /* want user access for breakpoints */ + if (flags & _PAGE_USER) +#endif + bat[1].bat.batu.vp = 1; + if (flags & _PAGE_GUARDED) { + /* G bit must be zero in IBATs */ + bat[0].word[0] = bat[0].word[1] = 0; + } else { + /* make IBAT same as DBAT */ + bat[0] = bat[1]; + } + } else { + /* 601 cpu */ + if (bl > BL_8M) + bl = BL_8M; + wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE + | _PAGE_COHERENT); + wimgxpp |= (flags & _PAGE_RW)? + ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX; + bat->word[0] = virt | wimgxpp | 4; /* Ks=0, Ku=1 */ + bat->word[1] = phys | bl | 0x40; /* V=1 */ + } + + bat_addrs[index].start = virt; + bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1; + bat_addrs[index].phys = phys; +} + +/* + * Initialize the hash table and patch the instructions in hashtable.S. + */ +void __init MMU_init_hw(void) +{ + unsigned int hmask, mb, mb2; + unsigned int n_hpteg, lg_n_hpteg; + + extern unsigned int hash_page_patch_A[]; + extern unsigned int hash_page_patch_B[], hash_page_patch_C[]; + extern unsigned int hash_page[]; + extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; + + if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) { + /* + * Put a blr (procedure return) instruction at the + * start of hash_page, since we can still get DSI + * exceptions on a 603. + */ + hash_page[0] = 0x4e800020; + flush_icache_range((unsigned long) &hash_page[0], + (unsigned long) &hash_page[1]); + return; + } + + if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); + +#ifdef CONFIG_PPC64BRIDGE +#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ +#define SDR1_LOW_BITS (lg_n_hpteg - 11) +#define MIN_N_HPTEG 2048 /* min 256kB hash table */ +#else +#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ +#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) +#define MIN_N_HPTEG 1024 /* min 64kB hash table */ +#endif + +#ifdef CONFIG_POWER4 + /* The hash table has already been allocated and initialized + in prom.c */ + n_hpteg = Hash_size >> LG_HPTEG_SIZE; + lg_n_hpteg = __ilog2(n_hpteg); + + /* Remove the hash table from the available memory */ + if (Hash) + reserve_phys_mem(__pa(Hash), Hash_size); + +#else /* CONFIG_POWER4 */ + /* + * Allow 1 HPTE (1/8 HPTEG) for each page of memory. + * This is less than the recommended amount, but then + * Linux ain't AIX. + */ + n_hpteg = total_memory / (PAGE_SIZE * 8); + if (n_hpteg < MIN_N_HPTEG) + n_hpteg = MIN_N_HPTEG; + lg_n_hpteg = __ilog2(n_hpteg); + if (n_hpteg & (n_hpteg - 1)) { + ++lg_n_hpteg; /* round up if not power of 2 */ + n_hpteg = 1 << lg_n_hpteg; + } + Hash_size = n_hpteg << LG_HPTEG_SIZE; + + /* + * Find some memory for the hash table. + */ + if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322); + Hash = mem_pieces_find(Hash_size, Hash_size); + cacheable_memzero(Hash, Hash_size); + _SDR1 = __pa(Hash) | SDR1_LOW_BITS; +#endif /* CONFIG_POWER4 */ + + Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); + + printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", + total_memory >> 20, Hash_size >> 10, Hash); + + + /* + * Patch up the instructions in hashtable.S:create_hpte + */ + if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); + Hash_mask = n_hpteg - 1; + hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); + mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; + if (lg_n_hpteg > 16) + mb2 = 16 - LG_HPTEG_SIZE; + + hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) + | ((unsigned int)(Hash) >> 16); + hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6); + hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6); + hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask; + hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask; + + /* + * Ensure that the locations we've patched have been written + * out from the data cache and invalidated in the instruction + * cache, on those machines with split caches. + */ + flush_icache_range((unsigned long) &hash_page_patch_A[0], + (unsigned long) &hash_page_patch_C[1]); + + /* + * Patch up the instructions in hashtable.S:flush_hash_page + */ + flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff) + | ((unsigned int)(Hash) >> 16); + flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6); + flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6); + flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask; + flush_icache_range((unsigned long) &flush_hash_patch_A[0], + (unsigned long) &flush_hash_patch_B[1]); + + if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); +} diff --git a/arch/powerpc/mm/tlb.c b/arch/powerpc/mm/tlb.c new file mode 100644 index 000000000000..6c3dc3c44c86 --- /dev/null +++ b/arch/powerpc/mm/tlb.c @@ -0,0 +1,183 @@ +/* + * This file contains the routines for TLB flushing. + * On machines where the MMU uses a hash table to store virtual to + * physical translations, these routines flush entries from the + * hash table also. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mmu_decl.h" + +/* + * Called when unmapping pages to flush entries from the TLB/hash table. + */ +void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) +{ + unsigned long ptephys; + + if (Hash != 0) { + ptephys = __pa(ptep) & PAGE_MASK; + flush_hash_pages(mm->context, addr, ptephys, 1); + } +} + +/* + * Called by ptep_set_access_flags, must flush on CPUs for which the + * DSI handler can't just "fixup" the TLB on a write fault + */ +void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr) +{ + if (Hash != 0) + return; + _tlbie(addr); +} + +/* + * Called at the end of a mmu_gather operation to make sure the + * TLB flush is completely done. + */ +void tlb_flush(struct mmu_gather *tlb) +{ + if (Hash == 0) { + /* + * 603 needs to flush the whole TLB here since + * it doesn't use a hash table. + */ + _tlbia(); + } +} + +/* + * TLB flushing: + * + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes kernel pages + * + * since the hardware hash table functions as an extension of the + * tlb as far as the linux tables are concerned, flush it too. + * -- Cort + */ + +/* + * 750 SMP is a Bad Idea because the 750 doesn't broadcast all + * the cache operations on the bus. Hence we need to use an IPI + * to get the other CPU(s) to invalidate their TLBs. + */ +#ifdef CONFIG_SMP_750 +#define FINISH_FLUSH smp_send_tlb_invalidate(0) +#else +#define FINISH_FLUSH do { } while (0) +#endif + +static void flush_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + pmd_t *pmd; + unsigned long pmd_end; + int count; + unsigned int ctx = mm->context; + + if (Hash == 0) { + _tlbia(); + return; + } + start &= PAGE_MASK; + if (start >= end) + return; + end = (end - 1) | ~PAGE_MASK; + pmd = pmd_offset(pgd_offset(mm, start), start); + for (;;) { + pmd_end = ((start + PGDIR_SIZE) & PGDIR_MASK) - 1; + if (pmd_end > end) + pmd_end = end; + if (!pmd_none(*pmd)) { + count = ((pmd_end - start) >> PAGE_SHIFT) + 1; + flush_hash_pages(ctx, start, pmd_val(*pmd), count); + } + if (pmd_end == end) + break; + start = pmd_end + 1; + ++pmd; + } +} + +/* + * Flush kernel TLB entries in the given range + */ +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_range(&init_mm, start, end); + FINISH_FLUSH; +} + +/* + * Flush all the (user) entries for the address space described by mm. + */ +void flush_tlb_mm(struct mm_struct *mm) +{ + struct vm_area_struct *mp; + + if (Hash == 0) { + _tlbia(); + return; + } + + for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) + flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); + FINISH_FLUSH; +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) +{ + struct mm_struct *mm; + pmd_t *pmd; + + if (Hash == 0) { + _tlbie(vmaddr); + return; + } + mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; + pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr); + if (!pmd_none(*pmd)) + flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1); + FINISH_FLUSH; +} + +/* + * For each address in the range, find the pte for the address + * and check _PAGE_HASHPTE bit; if it is set, find and destroy + * the corresponding HPTE. + */ +void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + flush_range(vma->vm_mm, start, end); + FINISH_FLUSH; +} diff --git a/arch/powerpc/platforms/4xx/Kconfig b/arch/powerpc/platforms/4xx/Kconfig new file mode 100644 index 000000000000..ed39d6a3d22a --- /dev/null +++ b/arch/powerpc/platforms/4xx/Kconfig @@ -0,0 +1,280 @@ +config 4xx + bool + depends on 40x || 44x + default y + +config WANT_EARLY_SERIAL + bool + select SERIAL_8250 + default n + +menu "AMCC 4xx options" + depends on 4xx + +choice + prompt "Machine Type" + depends on 40x + default WALNUT + +config BUBINGA + bool "Bubinga" + select WANT_EARLY_SERIAL + help + This option enables support for the IBM 405EP evaluation board. + +config CPCI405 + bool "CPCI405" + help + This option enables support for the CPCI405 board. + +config EP405 + bool "EP405/EP405PC" + help + This option enables support for the EP405/EP405PC boards. + +config REDWOOD_5 + bool "Redwood-5" + help + This option enables support for the IBM STB04 evaluation board. + +config REDWOOD_6 + bool "Redwood-6" + help + This option enables support for the IBM STBx25xx evaluation board. + +config SYCAMORE + bool "Sycamore" + help + This option enables support for the IBM PPC405GPr evaluation board. + +config WALNUT + bool "Walnut" + help + This option enables support for the IBM PPC405GP evaluation board. + +config XILINX_ML300 + bool "Xilinx-ML300" + help + This option enables support for the Xilinx ML300 evaluation board. + +endchoice + +choice + prompt "Machine Type" + depends on 44x + default EBONY + +config BAMBOO + bool "Bamboo" + select WANT_EARLY_SERIAL + help + This option enables support for the IBM PPC440EP evaluation board. + +config EBONY + bool "Ebony" + select WANT_EARLY_SERIAL + help + This option enables support for the IBM PPC440GP evaluation board. + +config LUAN + bool "Luan" + select WANT_EARLY_SERIAL + help + This option enables support for the IBM PPC440SP evaluation board. + +config OCOTEA + bool "Ocotea" + select WANT_EARLY_SERIAL + help + This option enables support for the IBM PPC440GX evaluation board. + +endchoice + +config EP405PC + bool "EP405PC Support" + depends on EP405 + + +# It's often necessary to know the specific 4xx processor type. +# Fortunately, it is impled (so far) from the board type, so we +# don't need to ask more redundant questions. +config NP405H + bool + depends on ASH + default y + +config 440EP + bool + depends on BAMBOO + select PPC_FPU + default y + +config 440GP + bool + depends on EBONY + default y + +config 440GX + bool + depends on OCOTEA + default y + +config 440SP + bool + depends on LUAN + default y + +config 440 + bool + depends on 440GP || 440SP || 440EP + default y + +config 440A + bool + depends on 440GX + default y + +config IBM440EP_ERR42 + bool + depends on 440EP + default y + +# All 405-based cores up until the 405GPR and 405EP have this errata. +config IBM405_ERR77 + bool + depends on 40x && !403GCX && !405GPR && !405EP + default y + +# All 40x-based cores, up until the 405GPR and 405EP have this errata. +config IBM405_ERR51 + bool + depends on 40x && !405GPR && !405EP + default y + +config BOOKE + bool + depends on 44x + default y + +config IBM_OCP + bool + depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + default y + +config XILINX_OCP + bool + depends on XILINX_ML300 + default y + +config IBM_EMAC4 + bool + depends on 440GX || 440SP + default y + +config BIOS_FIXUP + bool + depends on BUBINGA || EP405 || SYCAMORE || WALNUT + default y + +# OAK doesn't exist but wanted to keep this around for any future 403GCX boards +config 403GCX + bool + depends OAK + default y + +config 405EP + bool + depends on BUBINGA + default y + +config 405GP + bool + depends on CPCI405 || EP405 || WALNUT + default y + +config 405GPR + bool + depends on SYCAMORE + default y + +config VIRTEX_II_PRO + bool + depends on XILINX_ML300 + default y + +config STB03xxx + bool + depends on REDWOOD_5 || REDWOOD_6 + default y + +config EMBEDDEDBOOT + bool + depends on EP405 || XILINX_ML300 + default y + +config IBM_OPENBIOS + bool + depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + default y + +config PPC4xx_DMA + bool "PPC4xx DMA controller support" + depends on 4xx + +config PPC4xx_EDMA + bool + depends on !STB03xxx && PPC4xx_DMA + default y + +config PPC_GEN550 + bool + depends on 4xx + default y + +choice + prompt "TTYS0 device and default console" + depends on 40x + default UART0_TTYS0 + +config UART0_TTYS0 + bool "UART0" + +config UART0_TTYS1 + bool "UART1" + +endchoice + +config SERIAL_SICC + bool "SICC Serial port support" + depends on STB03xxx + +config UART1_DFLT_CONSOLE + bool + depends on SERIAL_SICC && UART0_TTYS1 + default y + +config SERIAL_SICC_CONSOLE + bool + depends on SERIAL_SICC && UART0_TTYS1 + default y +endmenu + + +menu "IBM 40x options" + depends on 40x + +config SERIAL_SICC + bool "SICC Serial port" + depends on STB03xxx + +config UART1_DFLT_CONSOLE + bool + depends on SERIAL_SICC && UART0_TTYS1 + default y + +config SERIAL_SICC_CONSOLE + bool + depends on SERIAL_SICC && UART0_TTYS1 + default y + +endmenu diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig new file mode 100644 index 000000000000..c5bc2821d991 --- /dev/null +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -0,0 +1,86 @@ +config 85xx + bool + depends on E500 + default y + +config PPC_INDIRECT_PCI_BE + bool + depends on 85xx + default y + +menu "Freescale 85xx options" + depends on E500 + +choice + prompt "Machine Type" + depends on 85xx + default MPC8540_ADS + +config MPC8540_ADS + bool "Freescale MPC8540 ADS" + help + This option enables support for the MPC 8540 ADS evaluation board. + +config MPC8548_CDS + bool "Freescale MPC8548 CDS" + help + This option enablese support for the MPC8548 CDS evaluation board. + +config MPC8555_CDS + bool "Freescale MPC8555 CDS" + help + This option enablese support for the MPC8555 CDS evaluation board. + +config MPC8560_ADS + bool "Freescale MPC8560 ADS" + help + This option enables support for the MPC 8560 ADS evaluation board. + +config SBC8560 + bool "WindRiver PowerQUICC III SBC8560" + help + This option enables support for the WindRiver PowerQUICC III + SBC8560 board. + +config STX_GP3 + bool "Silicon Turnkey Express GP3" + help + This option enables support for the Silicon Turnkey Express GP3 + board. + +endchoice + +# It's often necessary to know the specific 85xx processor type. +# Fortunately, it is implied (so far) from the board type, so we +# don't need to ask more redundant questions. +config MPC8540 + bool + depends on MPC8540_ADS + default y + +config MPC8548 + bool + depends on MPC8548_CDS + default y + +config MPC8555 + bool + depends on MPC8555_CDS + default y + +config MPC8560 + bool + depends on SBC8560 || MPC8560_ADS || STX_GP3 + default y + +config 85xx_PCI2 + bool "Supprt for 2nd PCI host controller" + depends on MPC8555_CDS + default y + +config PPC_GEN550 + bool + depends on MPC8540 || SBC8560 || MPC8555 + default y + +endmenu diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig new file mode 100644 index 000000000000..c8c0ba3cf8e8 --- /dev/null +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -0,0 +1,352 @@ +config FADS + bool + +choice + prompt "8xx Machine Type" + depends on 8xx + default RPXLITE + +config RPXLITE + bool "RPX-Lite" + ---help--- + Single-board computers based around the PowerPC MPC8xx chips and + intended for embedded applications. The following types are + supported: + + RPX-Lite: + Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823. + + RPX-Classic: + Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on + the MPC 860 + + BSE-IP: + Bright Star Engineering ip-Engine. + + TQM823L: + TQM850L: + TQM855L: + TQM860L: + MPC8xx based family of mini modules, half credit card size, + up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports, + 2 x CAN bus interface, ... + Manufacturer: TQ Components, www.tq-group.de + Date of Release: October (?) 1999 + End of Life: not yet :-) + URL: + - module: + - starter kit: + - images: + + FPS850L: + FingerPrint Sensor System (based on TQM850L) + Manufacturer: IKENDI AG, + Date of Release: November 1999 + End of life: end 2000 ? + URL: see TQM850L + + IVMS8: + MPC860 based board used in the "Integrated Voice Mail System", + Small Version (8 voice channels) + Manufacturer: Speech Design, + Date of Release: December 2000 (?) + End of life: - + URL: + + IVML24: + MPC860 based board used in the "Integrated Voice Mail System", + Large Version (24 voice channels) + Manufacturer: Speech Design, + Date of Release: March 2001 (?) + End of life: - + URL: + + HERMES: + Hermes-Pro ISDN/LAN router with integrated 8 x hub + Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik + + Date of Release: 2000 (?) + End of life: - + URL: + + IP860: + VMEBus IP (Industry Pack) carrier board with MPC860 + Manufacturer: MicroSys GmbH, + Date of Release: ? + End of life: - + URL: + + PCU_E: + PCU = Peripheral Controller Unit, Extended + Manufacturer: Siemens AG, ICN (Information and Communication Networks) + + Date of Release: April 2001 + End of life: August 2001 + URL: n. a. + +config RPXCLASSIC + bool "RPX-Classic" + help + The RPX-Classic is a single-board computer based on the Motorola + MPC860. It features 16MB of DRAM and a variable amount of flash, + I2C EEPROM, thermal monitoring, a PCMCIA slot, a DIP switch and two + LEDs. Variants with Ethernet ports exist. Say Y here to support it + directly. + +config BSEIP + bool "BSE-IP" + help + Say Y here to support the Bright Star Engineering ipEngine SBC. + This is a credit-card-sized device featuring a MPC823 processor, + 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video + controller, and two RS232 ports. + +config MPC8XXFADS + bool "FADS" + select FADS + +config MPC86XADS + bool "MPC86XADS" + help + MPC86x Application Development System by Freescale Semiconductor. + The MPC86xADS is meant to serve as a platform for s/w and h/w + development around the MPC86X processor families. + select FADS + +config MPC885ADS + bool "MPC885ADS" + help + Freescale Semiconductor MPC885 Application Development System (ADS). + Also known as DUET. + The MPC885ADS is meant to serve as a platform for s/w and h/w + development around the MPC885 processor family. + +config TQM823L + bool "TQM823L" + help + Say Y here to support the TQM823L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . + +config TQM850L + bool "TQM850L" + help + Say Y here to support the TQM850L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . + +config TQM855L + bool "TQM855L" + help + Say Y here to support the TQM855L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . + +config TQM860L + bool "TQM860L" + help + Say Y here to support the TQM860L, one of an MPC8xx-based family of + mini SBCs (half credit-card size) from TQ Components first released + in late 1999. Technical references are at + , and + , and an image at + . + +config FPS850L + bool "FPS850L" + +config IVMS8 + bool "IVMS8" + help + Say Y here to support the Integrated Voice-Mail Small 8-channel SBC + from Speech Design, released March 2001. The manufacturer's website + is at . + +config IVML24 + bool "IVML24" + help + Say Y here to support the Integrated Voice-Mail Large 24-channel SBC + from Speech Design, released March 2001. The manufacturer's website + is at . + +config HERMES_PRO + bool "HERMES" + +config IP860 + bool "IP860" + +config LWMON + bool "LWMON" + +config PCU_E + bool "PCU_E" + +config CCM + bool "CCM" + +config LANTEC + bool "LANTEC" + +config MBX + bool "MBX" + help + MBX is a line of Motorola single-board computer based around the + MPC821 and MPC860 processors, and intended for embedded-controller + applications. Say Y here to support these boards directly. + +config WINCEPT + bool "WinCept" + help + The Wincept 100/110 is a Motorola single-board computer based on the + MPC821 PowerPC, introduced in 1998 and designed to be used in + thin-client machines. Say Y to support it directly. + +endchoice + +# +# MPC8xx Communication options +# + +menu "MPC8xx CPM Options" + depends on 8xx + +config SCC_ENET + bool "CPM SCC Ethernet" + depends on NET_ETHERNET + help + Enable Ethernet support via the Motorola MPC8xx serial + communications controller. + +choice + prompt "SCC used for Ethernet" + depends on SCC_ENET + default SCC1_ENET + +config SCC1_ENET + bool "SCC1" + help + Use MPC8xx serial communications controller 1 to drive Ethernet + (default). + +config SCC2_ENET + bool "SCC2" + help + Use MPC8xx serial communications controller 2 to drive Ethernet. + +config SCC3_ENET + bool "SCC3" + help + Use MPC8xx serial communications controller 3 to drive Ethernet. + +endchoice + +config FEC_ENET + bool "860T FEC Ethernet" + depends on NET_ETHERNET + help + Enable Ethernet support via the Fast Ethernet Controller (FCC) on + the Motorola MPC8260. + +config USE_MDIO + bool "Use MDIO for PHY configuration" + depends on FEC_ENET + help + On some boards the hardware configuration of the ethernet PHY can be + used without any software interaction over the MDIO interface, so + all MII code can be omitted. Say N here if unsure or if you don't + need link status reports. + +config FEC_AM79C874 + bool "Support AMD79C874 PHY" + depends on USE_MDIO + +config FEC_LXT970 + bool "Support LXT970 PHY" + depends on USE_MDIO + +config FEC_LXT971 + bool "Support LXT971 PHY" + depends on USE_MDIO + +config FEC_QS6612 + bool "Support QS6612 PHY" + depends on USE_MDIO + +config ENET_BIG_BUFFERS + bool "Use Big CPM Ethernet Buffers" + depends on SCC_ENET || FEC_ENET + help + Allocate large buffers for MPC8xx Ethernet. Increases throughput + and decreases the likelihood of dropped packets, but costs memory. + +config HTDMSOUND + bool "Embedded Planet HIOX Audio" + depends on SOUND=y + +# This doesn't really belong here, but it is convenient to ask +# 8xx specific questions. +comment "Generic MPC8xx Options" + +config 8xx_COPYBACK + bool "Copy-Back Data Cache (else Writethrough)" + help + Saying Y here will cause the cache on an MPC8xx processor to be used + in Copy-Back mode. If you say N here, it is used in Writethrough + mode. + + If in doubt, say Y here. + +config 8xx_CPU6 + bool "CPU6 Silicon Errata (860 Pre Rev. C)" + help + MPC860 CPUs, prior to Rev C have some bugs in the silicon, which + require workarounds for Linux (and most other OSes to work). If you + get a BUG() very early in boot, this might fix the problem. For + more details read the document entitled "MPC860 Family Device Errata + Reference" on Motorola's website. This option also incurs a + performance hit. + + If in doubt, say N here. + +choice + prompt "Microcode patch selection" + default NO_UCODE_PATCH + help + Help not implemented yet, coming soon. + +config NO_UCODE_PATCH + bool "None" + +config USB_SOF_UCODE_PATCH + bool "USB SOF patch" + help + Help not implemented yet, coming soon. + +config I2C_SPI_UCODE_PATCH + bool "I2C/SPI relocation patch" + help + Help not implemented yet, coming soon. + +config I2C_SPI_SMC1_UCODE_PATCH + bool "I2C/SPI/SMC1 relocation patch" + help + Help not implemented yet, coming soon. + +endchoice + +config UCODE_PATCH + bool + default y + depends on !NO_UCODE_PATCH + +endmenu + diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig new file mode 100644 index 000000000000..6bde3bffed86 --- /dev/null +++ b/arch/powerpc/platforms/apus/Kconfig @@ -0,0 +1,130 @@ + +config AMIGA + bool + depends on APUS + default y + help + This option enables support for the Amiga series of computers. + +config ZORRO + bool + depends on APUS + default y + help + This enables support for the Zorro bus in the Amiga. If you have + expansion cards in your Amiga that conform to the Amiga + AutoConfig(tm) specification, say Y, otherwise N. Note that even + expansion cards that do not fit in the Zorro slots but fit in e.g. + the CPU slot may fall in this category, so you have to say Y to let + Linux use these. + +config ABSTRACT_CONSOLE + bool + depends on APUS + default y + +config APUS_FAST_EXCEPT + bool + depends on APUS + default y + +config AMIGA_PCMCIA + bool "Amiga 1200/600 PCMCIA support" + depends on APUS && EXPERIMENTAL + help + Include support in the kernel for pcmcia on Amiga 1200 and Amiga + 600. If you intend to use pcmcia cards say Y; otherwise say N. + +config AMIGA_BUILTIN_SERIAL + tristate "Amiga builtin serial support" + depends on APUS + help + If you want to use your Amiga's built-in serial port in Linux, + answer Y. + + To compile this driver as a module, choose M here. + +config GVPIOEXT + tristate "GVP IO-Extender support" + depends on APUS + help + If you want to use a GVP IO-Extender serial card in Linux, say Y. + Otherwise, say N. + +config GVPIOEXT_LP + tristate "GVP IO-Extender parallel printer support" + depends on GVPIOEXT + help + Say Y to enable driving a printer from the parallel port on your + GVP IO-Extender card, N otherwise. + +config GVPIOEXT_PLIP + tristate "GVP IO-Extender PLIP support" + depends on GVPIOEXT + help + Say Y to enable doing IP over the parallel port on your GVP + IO-Extender card, N otherwise. + +config MULTIFACE_III_TTY + tristate "Multiface Card III serial support" + depends on APUS + help + If you want to use a Multiface III card's serial port in Linux, + answer Y. + + To compile this driver as a module, choose M here. + +config A2232 + tristate "Commodore A2232 serial support (EXPERIMENTAL)" + depends on EXPERIMENTAL && APUS + ---help--- + This option supports the 2232 7-port serial card shipped with the + Amiga 2000 and other Zorro-bus machines, dating from 1989. At + a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip + each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The + ports were connected with 8 pin DIN connectors on the card bracket, + for which 8 pin to DB25 adapters were supplied. The card also had + jumpers internally to toggle various pinning configurations. + + This driver can be built as a module; but then "generic_serial" + will also be built as a module. This has to be loaded before + "ser_a2232". If you want to do this, answer M here. + +config WHIPPET_SERIAL + tristate "Hisoft Whippet PCMCIA serial support" + depends on AMIGA_PCMCIA + help + HiSoft has a web page at , but there + is no listing for the Whippet in their Amiga section. + +config APNE + tristate "PCMCIA NE2000 support" + depends on AMIGA_PCMCIA + help + If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise, + say N. + + To compile this driver as a module, choose M here: the + module will be called apne. + +config SERIAL_CONSOLE + bool "Support for serial port console" + depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y) + +config HEARTBEAT + bool "Use power LED as a heartbeat" + depends on APUS + help + Use the power-on LED on your machine as a load meter. The exact + behavior is platform-dependent, but normally the flash frequency is + a hyperbolic function of the 5-minute load average. + +config PROC_HARDWARE + bool "/proc/hardware support" + depends on APUS + +source "drivers/zorro/Kconfig" + +config PCI_PERMEDIA + bool "PCI for Permedia2" + depends on !4xx && !8xx && APUS diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig new file mode 100644 index 000000000000..4f3551430596 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -0,0 +1,313 @@ +choice + prompt "Machine Type" + depends on EMBEDDED6xx + +config APUS + bool "Amiga-APUS" + depends on BROKEN + help + Select APUS if configuring for a PowerUP Amiga. + More information is available at: + . + +config KATANA + bool "Artesyn-Katana" + help + Select KATANA if configuring an Artesyn KATANA 750i or 3750 + cPCI board. + +config WILLOW + bool "Cogent-Willow" + +config CPCI690 + bool "Force-CPCI690" + help + Select CPCI690 if configuring a Force CPCI690 cPCI board. + +config POWERPMC250 + bool "Force-PowerPMC250" + +config CHESTNUT + bool "IBM 750FX Eval board or 750GX Eval board" + help + Select CHESTNUT if configuring an IBM 750FX Eval Board or a + IBM 750GX Eval board. + +config SPRUCE + bool "IBM-Spruce" + +config HDPU + bool "Sky-HDPU" + help + Select HDPU if configuring a Sky Computers Compute Blade. + +config HDPU_FEATURES + depends HDPU + tristate "HDPU-Features" + help + Select to enable HDPU enhanced features. + +config EV64260 + bool "Marvell-EV64260BP" + help + Select EV64260 if configuring a Marvell (formerly Galileo) + EV64260BP Evaluation platform. + +config LOPEC + bool "Motorola-LoPEC" + +config MVME5100 + bool "Motorola-MVME5100" + +config PPLUS + bool "Motorola-PowerPlus" + +config PRPMC750 + bool "Motorola-PrPMC750" + +config PRPMC800 + bool "Motorola-PrPMC800" + +config SANDPOINT + bool "Motorola-Sandpoint" + help + Select SANDPOINT if configuring for a Motorola Sandpoint X3 + (any flavor). + +config RADSTONE_PPC7D + bool "Radstone Technology PPC7D board" + +config PAL4 + bool "SBS-Palomar4" + +config GEMINI + bool "Synergy-Gemini" + depends on BROKEN + help + Select Gemini if configuring for a Synergy Microsystems' Gemini + series Single Board Computer. More information is available at: + . + +config EST8260 + bool "EST8260" + ---help--- + The EST8260 is a single-board computer manufactured by Wind River + Systems, Inc. (formerly Embedded Support Tools Corp.) and based on + the MPC8260. Wind River Systems has a website at + , but the EST8260 cannot be found on it + and has probably been discontinued or rebadged. + +config SBC82xx + bool "SBC82xx" + ---help--- + SBC PowerQUICC II, single-board computer with MPC82xx CPU + Manufacturer: Wind River Systems, Inc. + Date of Release: May 2003 + End of Life: - + URL: + +config SBS8260 + bool "SBS8260" + +config RPX8260 + bool "RPXSUPER" + +config TQM8260 + bool "TQM8260" + ---help--- + MPC8260 based module, little larger than credit card, + up to 128 MB global + 64 MB local RAM, 32 MB Flash, + 32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet, + 2 x serial ports, ... + Manufacturer: TQ Components, www.tq-group.de + Date of Release: June 2001 + End of Life: not yet :-) + URL: + +config ADS8272 + bool "ADS8272" + +config PQ2FADS + bool "Freescale-PQ2FADS" + help + Select PQ2FADS if you wish to configure for a Freescale + PQ2FADS board (-VR or -ZU). + +config LITE5200 + bool "Freescale LITE5200 / (IceCube)" + select PPC_MPC52xx + help + Support for the LITE5200 dev board for the MPC5200 from Freescale. + This is for the LITE5200 version 2.0 board. Don't know if it changes + much but it's only been tested on this board version. I think this + board is also known as IceCube. + +config MPC834x_SYS + bool "Freescale MPC834x SYS" + help + This option enables support for the MPC 834x SYS evaluation board. + + Be aware that PCI buses can only function when SYS board is plugged + into the PIB (Platform IO Board) board from Freescale which provide + 3 PCI slots. The PIBs PCI initialization is the bootloader's + responsiblilty. + +config EV64360 + bool "Marvell-EV64360BP" + help + Select EV64360 if configuring a Marvell EV64360BP Evaluation + platform. +endchoice + +config PQ2ADS + bool + depends on ADS8272 + default y + +config TQM8xxL + bool + depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L) + default y + +config PPC_MPC52xx + bool + +config 8260 + bool "CPM2 Support" if WILLOW + depends on 6xx + default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS + help + The MPC8260 is a typical embedded CPU made by Motorola. Selecting + this option means that you wish to build a kernel for a machine with + an 8260 class CPU. + +config 8272 + bool + depends on 6xx + default y if ADS8272 + select 8260 + help + The MPC8272 CPM has a different internal dpram setup than other CPM2 + devices + +config 83xx + bool + default y if MPC834x_SYS + +config MPC834x + bool + default y if MPC834x_SYS + +config CPM2 + bool + depends on 8260 || MPC8560 || MPC8555 + default y + help + The CPM2 (Communications Processor Module) is a coprocessor on + embedded CPUs made by Motorola. Selecting this option means that + you wish to build a kernel for a machine with a CPM2 coprocessor + on it (826x, 827x, 8560). + +config PPC_GEN550 + bool + depends on SANDPOINT || SPRUCE || PPLUS || \ + PRPMC750 || PRPMC800 || LOPEC || \ + (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \ + 83xx + default y + +config FORCE + bool + depends on 6xx && POWERPMC250 + default y + +config GT64260 + bool + depends on EV64260 || CPCI690 + default y + +config MV64360 # Really MV64360 & MV64460 + bool + depends on CHESTNUT || KATANA || RADSTONE_PPC7D || HDPU || EV64360 + default y + +config MV64X60 + bool + depends on (GT64260 || MV64360) + default y + +menu "Set bridge options" + depends on MV64X60 + +config NOT_COHERENT_CACHE + bool "Turn off Cache Coherency" + default n + help + Some 64x60 bridges lock up when trying to enforce cache coherency. + When this option is selected, cache coherency will be turned off. + Note that this can cause other problems (e.g., stale data being + speculatively loaded via a cached mapping). Use at your own risk. + +config MV64X60_BASE + hex "Set bridge base used by firmware" + default "0xf1000000" + help + A firmware can leave the base address of the bridge's registers at + a non-standard location. If so, set this value to reflect the + address of that non-standard location. + +config MV64X60_NEW_BASE + hex "Set bridge base used by kernel" + default "0xf1000000" + help + If the current base address of the bridge's registers is not where + you want it, set this value to the address that you want it moved to. + +endmenu + +config NONMONARCH_SUPPORT + bool "Enable Non-Monarch Support" + depends on PRPMC800 + +config HARRIER + bool + depends on PRPMC800 + default y + +config EPIC_SERIAL_MODE + bool + depends on 6xx && (LOPEC || SANDPOINT) + default y + +config MPC10X_BRIDGE + bool + depends on POWERPMC250 || LOPEC || SANDPOINT + default y + +config MPC10X_OPENPIC + bool + depends on POWERPMC250 || LOPEC || SANDPOINT + default y + +config MPC10X_STORE_GATHERING + bool "Enable MPC10x store gathering" + depends on MPC10X_BRIDGE + +config SANDPOINT_ENABLE_UART1 + bool "Enable DUART mode on Sandpoint" + depends on SANDPOINT + help + If this option is enabled then the MPC824x processor will run + in DUART mode instead of UART mode. + +config HARRIER_STORE_GATHERING + bool "Enable Harrier store gathering" + depends on HARRIER + +config MVME5100_IPMC761_PRESENT + bool "MVME5100 configured with an IPMC761" + depends on MVME5100 + +config SPRUCE_BAUD_33M + bool "Spruce baud clock support" + depends on SPRUCE diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig new file mode 100644 index 000000000000..3d957a30c8c2 --- /dev/null +++ b/arch/powerpc/platforms/iseries/Kconfig @@ -0,0 +1,31 @@ + +menu "iSeries device drivers" + depends on PPC_ISERIES + +config VIOCONS + tristate "iSeries Virtual Console Support" + +config VIODASD + tristate "iSeries Virtual I/O disk support" + help + If you are running on an iSeries system and you want to use + virtual disks created and managed by OS/400, say Y. + +config VIOCD + tristate "iSeries Virtual I/O CD support" + help + If you are running Linux on an IBM iSeries system and you want to + read a CD drive owned by OS/400, say Y here. + +config VIOTAPE + tristate "iSeries Virtual Tape Support" + help + If you are running Linux on an iSeries system and you want Linux + to read and/or write a tape drive owned by OS/400, say Y here. + +endmenu + +config VIOPATH + bool + depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH + default y diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile new file mode 100644 index 000000000000..37b7341396e4 --- /dev/null +++ b/arch/powerpc/platforms/powermac/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \ + pmac_feature.o pmac_pci.o pmac_sleep.o \ + pmac_low_i2c.o pmac_cache.o +obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o +obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o +ifeq ($(CONFIG_PPC_PMAC),y) +obj-$(CONFIG_NVRAM) += pmac_nvram.o +obj-$(CONFIG_SMP) += pmac_smp.o +endif diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h new file mode 100644 index 000000000000..40e1c5030f74 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -0,0 +1,31 @@ +#ifndef __PMAC_H__ +#define __PMAC_H__ + +#include +#include + +/* + * Declaration for the various functions exported by the + * pmac_* files. Mostly for use by pmac_setup + */ + +extern void pmac_get_boot_time(struct rtc_time *tm); +extern void pmac_get_rtc_time(struct rtc_time *tm); +extern int pmac_set_rtc_time(struct rtc_time *tm); +extern void pmac_read_rtc_time(void); +extern void pmac_calibrate_decr(void); + +extern void pmac_pcibios_fixup(void); +extern void pmac_pci_init(void); +extern void pmac_setup_pci_dma(void); +extern void pmac_check_ht_link(void); + +extern void pmac_setup_smp(void); + +extern unsigned long pmac_ide_get_base(int index); +extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, + unsigned long data_port, unsigned long ctrl_port, int *irq); + +extern void pmac_nvram_init(void); + +#endif /* __PMAC_H__ */ diff --git a/arch/powerpc/platforms/powermac/pmac_backlight.c b/arch/powerpc/platforms/powermac/pmac_backlight.c new file mode 100644 index 000000000000..8be2f7d071f0 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_backlight.c @@ -0,0 +1,202 @@ +/* + * Miscellaneous procedures for dealing with the PowerMac hardware. + * Contains support for the backlight. + * + * Copyright (C) 2000 Benjamin Herrenschmidt + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct backlight_controller *backlighter; +static void* backlighter_data; +static int backlight_autosave; +static int backlight_level = BACKLIGHT_MAX; +static int backlight_enabled = 1; +static int backlight_req_level = -1; +static int backlight_req_enable = -1; + +static void backlight_callback(void *); +static DECLARE_WORK(backlight_work, backlight_callback, NULL); + +void register_backlight_controller(struct backlight_controller *ctrler, + void *data, char *type) +{ + struct device_node* bk_node; + char *prop; + int valid = 0; + + /* There's already a matching controller, bail out */ + if (backlighter != NULL) + return; + + bk_node = find_devices("backlight"); + +#ifdef CONFIG_ADB_PMU + /* Special case for the old PowerBook since I can't test on it */ + backlight_autosave = machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500"); + if ((backlight_autosave + || machine_is_compatible("AAPL,PowerBook1998") + || machine_is_compatible("PowerBook1,1")) + && !strcmp(type, "pmu")) + valid = 1; +#endif + if (bk_node) { + prop = get_property(bk_node, "backlight-control", NULL); + if (prop && !strncmp(prop, type, strlen(type))) + valid = 1; + } + if (!valid) + return; + backlighter = ctrler; + backlighter_data = data; + + if (bk_node && !backlight_autosave) + prop = get_property(bk_node, "bklt", NULL); + else + prop = NULL; + if (prop) { + backlight_level = ((*prop)+1) >> 1; + if (backlight_level > BACKLIGHT_MAX) + backlight_level = BACKLIGHT_MAX; + } + +#ifdef CONFIG_ADB_PMU + if (backlight_autosave) { + struct adb_request req; + pmu_request(&req, NULL, 2, 0xd9, 0); + while (!req.complete) + pmu_poll(); + backlight_level = req.reply[0] >> 4; + } +#endif + acquire_console_sem(); + if (!backlighter->set_enable(1, backlight_level, data)) + backlight_enabled = 1; + release_console_sem(); + + printk(KERN_INFO "Registered \"%s\" backlight controller," + "level: %d/15\n", type, backlight_level); +} +EXPORT_SYMBOL(register_backlight_controller); + +void unregister_backlight_controller(struct backlight_controller + *ctrler, void *data) +{ + /* We keep the current backlight level (for now) */ + if (ctrler == backlighter && data == backlighter_data) + backlighter = NULL; +} +EXPORT_SYMBOL(unregister_backlight_controller); + +static int __set_backlight_enable(int enable) +{ + int rc; + + if (!backlighter) + return -ENODEV; + acquire_console_sem(); + rc = backlighter->set_enable(enable, backlight_level, + backlighter_data); + if (!rc) + backlight_enabled = enable; + release_console_sem(); + return rc; +} +int set_backlight_enable(int enable) +{ + if (!backlighter) + return -ENODEV; + backlight_req_enable = enable; + schedule_work(&backlight_work); + return 0; +} + +EXPORT_SYMBOL(set_backlight_enable); + +int get_backlight_enable(void) +{ + if (!backlighter) + return -ENODEV; + return backlight_enabled; +} +EXPORT_SYMBOL(get_backlight_enable); + +static int __set_backlight_level(int level) +{ + int rc = 0; + + if (!backlighter) + return -ENODEV; + if (level < BACKLIGHT_MIN) + level = BACKLIGHT_OFF; + if (level > BACKLIGHT_MAX) + level = BACKLIGHT_MAX; + acquire_console_sem(); + if (backlight_enabled) + rc = backlighter->set_level(level, backlighter_data); + if (!rc) + backlight_level = level; + release_console_sem(); + if (!rc && !backlight_autosave) { + level <<=1; + if (level & 0x10) + level |= 0x01; + // -- todo: save to property "bklt" + } + return rc; +} +int set_backlight_level(int level) +{ + if (!backlighter) + return -ENODEV; + backlight_req_level = level; + schedule_work(&backlight_work); + return 0; +} + +EXPORT_SYMBOL(set_backlight_level); + +int get_backlight_level(void) +{ + if (!backlighter) + return -ENODEV; + return backlight_level; +} +EXPORT_SYMBOL(get_backlight_level); + +static void backlight_callback(void *dummy) +{ + int level, enable; + + do { + level = backlight_req_level; + enable = backlight_req_enable; + mb(); + + if (level >= 0) + __set_backlight_level(level); + if (enable >= 0) + __set_backlight_enable(enable); + } while(cmpxchg(&backlight_req_level, level, -1) != level || + cmpxchg(&backlight_req_enable, enable, -1) != enable); +} diff --git a/arch/powerpc/platforms/powermac/pmac_cache.S b/arch/powerpc/platforms/powermac/pmac_cache.S new file mode 100644 index 000000000000..fb977de6b704 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_cache.S @@ -0,0 +1,359 @@ +/* + * This file contains low-level cache management functions + * used for sleep and CPU speed changes on Apple machines. + * (In fact the only thing that is Apple-specific is that we assume + * that we can read from ROM at physical address 0xfff00000.) + * + * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and + * Benjamin Herrenschmidt (benh@kernel.crashing.org) + * + * 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. + * + */ + +#include +#include +#include +#include + +/* + * Flush and disable all data caches (dL1, L2, L3). This is used + * when going to sleep, when doing a PMU based cpufreq transition, + * or when "offlining" a CPU on SMP machines. This code is over + * paranoid, but I've had enough issues with various CPU revs and + * bugs that I decided it was worth beeing over cautious + */ + +_GLOBAL(flush_disable_caches) +#ifndef CONFIG_6xx + blr +#else +BEGIN_FTR_SECTION + b flush_disable_745x +END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) +BEGIN_FTR_SECTION + b flush_disable_75x +END_FTR_SECTION_IFSET(CPU_FTR_L2CR) + b __flush_disable_L1 + +/* This is the code for G3 and 74[01]0 */ +flush_disable_75x: + mflr r10 + + /* Turn off EE and DR in MSR */ + mfmsr r11 + rlwinm r0,r11,0,~MSR_EE + rlwinm r0,r0,0,~MSR_DR + sync + mtmsr r0 + isync + + /* Stop DST streams */ +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + + /* Stop DPM */ + mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */ + rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ + sync + mtspr SPRN_HID0,r4 /* Disable DPM */ + sync + + /* Disp-flush L1. We have a weird problem here that I never + * totally figured out. On 750FX, using the ROM for the flush + * results in a non-working flush. We use that workaround for + * now until I finally understand what's going on. --BenH + */ + + /* ROM base by default */ + lis r4,0xfff0 + mfpvr r3 + srwi r3,r3,16 + cmplwi cr0,r3,0x7000 + bne+ 1f + /* RAM base on 750FX */ + li r4,0 +1: li r4,0x4000 + mtctr r4 +1: lwz r0,0(r4) + addi r4,r4,32 + bdnz 1b + sync + isync + + /* Disable / invalidate / enable L1 data */ + mfspr r3,SPRN_HID0 + rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE) + mtspr SPRN_HID0,r3 + sync + isync + ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI) + sync + isync + mtspr SPRN_HID0,r3 + xori r3,r3,(HID0_DCI|HID0_ICFI) + mtspr SPRN_HID0,r3 + sync + + /* Get the current enable bit of the L2CR into r4 */ + mfspr r5,SPRN_L2CR + /* Set to data-only (pre-745x bit) */ + oris r3,r5,L2CR_L2DO@h + b 2f + /* When disabling L2, code must be in L1 */ + .balign 32 +1: mtspr SPRN_L2CR,r3 +3: sync + isync + b 1f +2: b 3f +3: sync + isync + b 1b +1: /* disp-flush L2. The interesting thing here is that the L2 can be + * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory + * but that is probbaly fine. We disp-flush over 4Mb to be safe + */ + lis r4,2 + mtctr r4 + lis r4,0xfff0 +1: lwz r0,0(r4) + addi r4,r4,32 + bdnz 1b + sync + isync + lis r4,2 + mtctr r4 + lis r4,0xfff0 +1: dcbf 0,r4 + addi r4,r4,32 + bdnz 1b + sync + isync + + /* now disable L2 */ + rlwinm r5,r5,0,~L2CR_L2E + b 2f + /* When disabling L2, code must be in L1 */ + .balign 32 +1: mtspr SPRN_L2CR,r5 +3: sync + isync + b 1f +2: b 3f +3: sync + isync + b 1b +1: sync + isync + /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */ + oris r4,r5,L2CR_L2I@h + mtspr SPRN_L2CR,r4 + sync + isync + + /* Wait for the invalidation to complete */ +1: mfspr r3,SPRN_L2CR + rlwinm. r0,r3,0,31,31 + bne 1b + + /* Clear L2I */ + xoris r4,r4,L2CR_L2I@h + sync + mtspr SPRN_L2CR,r4 + sync + + /* now disable the L1 data cache */ + mfspr r0,SPRN_HID0 + rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE) + mtspr SPRN_HID0,r0 + sync + isync + + /* Restore HID0[DPM] to whatever it was before */ + sync + mfspr r0,SPRN_HID0 + rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */ + mtspr SPRN_HID0,r0 + sync + + /* restore DR and EE */ + sync + mtmsr r11 + isync + + mtlr r10 + blr + +/* This code is for 745x processors */ +flush_disable_745x: + /* Turn off EE and DR in MSR */ + mfmsr r11 + rlwinm r0,r11,0,~MSR_EE + rlwinm r0,r0,0,~MSR_DR + sync + mtmsr r0 + isync + + /* Stop prefetch streams */ + DSSALL + sync + + /* Disable L2 prefetching */ + mfspr r0,SPRN_MSSCR0 + rlwinm r0,r0,0,0,29 + mtspr SPRN_MSSCR0,r0 + sync + isync + lis r4,0 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + + /* Due to a bug with the HW flush on some CPU revs, we occasionally + * experience data corruption. I'm adding a displacement flush along + * with a dcbf loop over a few Mb to "help". The problem isn't totally + * fixed by this in theory, but at least, in practice, I couldn't reproduce + * it even with a big hammer... + */ + + lis r4,0x0002 + mtctr r4 + li r4,0 +1: + lwz r0,0(r4) + addi r4,r4,32 /* Go to start of next cache line */ + bdnz 1b + isync + + /* Now, flush the first 4MB of memory */ + lis r4,0x0002 + mtctr r4 + li r4,0 + sync +1: + dcbf 0,r4 + addi r4,r4,32 /* Go to start of next cache line */ + bdnz 1b + + /* Flush and disable the L1 data cache */ + mfspr r6,SPRN_LDSTCR + lis r3,0xfff0 /* read from ROM for displacement flush */ + li r4,0xfe /* start with only way 0 unlocked */ + li r5,128 /* 128 lines in each way */ +1: mtctr r5 + rlwimi r6,r4,0,24,31 + mtspr SPRN_LDSTCR,r6 + sync + isync +2: lwz r0,0(r3) /* touch each cache line */ + addi r3,r3,32 + bdnz 2b + rlwinm r4,r4,1,24,30 /* move on to the next way */ + ori r4,r4,1 + cmpwi r4,0xff /* all done? */ + bne 1b + /* now unlock the L1 data cache */ + li r4,0 + rlwimi r6,r4,0,24,31 + sync + mtspr SPRN_LDSTCR,r6 + sync + isync + + /* Flush the L2 cache using the hardware assist */ + mfspr r3,SPRN_L2CR + cmpwi r3,0 /* check if it is enabled first */ + bge 4f + oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h + b 2f + /* When disabling/locking L2, code must be in L1 */ + .balign 32 +1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */ +3: sync + isync + b 1f +2: b 3f +3: sync + isync + b 1b +1: sync + isync + ori r0,r3,L2CR_L2HWF_745x + sync + mtspr SPRN_L2CR,r0 /* set the hardware flush bit */ +3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */ + andi. r0,r0,L2CR_L2HWF_745x + bne 3b + sync + rlwinm r3,r3,0,~L2CR_L2E + b 2f + /* When disabling L2, code must be in L1 */ + .balign 32 +1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */ +3: sync + isync + b 1f +2: b 3f +3: sync + isync + b 1b +1: sync + isync + oris r4,r3,L2CR_L2I@h + mtspr SPRN_L2CR,r4 + sync + isync +1: mfspr r4,SPRN_L2CR + andis. r0,r4,L2CR_L2I@h + bne 1b + sync + +BEGIN_FTR_SECTION + /* Flush the L3 cache using the hardware assist */ +4: mfspr r3,SPRN_L3CR + cmpwi r3,0 /* check if it is enabled */ + bge 6f + oris r0,r3,L3CR_L3IO@h + ori r0,r0,L3CR_L3DO + sync + mtspr SPRN_L3CR,r0 /* lock the L3 cache */ + sync + isync + ori r0,r0,L3CR_L3HWF + sync + mtspr SPRN_L3CR,r0 /* set the hardware flush bit */ +5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */ + andi. r0,r0,L3CR_L3HWF + bne 5b + rlwinm r3,r3,0,~L3CR_L3E + sync + mtspr SPRN_L3CR,r3 /* disable the L3 cache */ + sync + ori r4,r3,L3CR_L3I + mtspr SPRN_L3CR,r4 +1: mfspr r4,SPRN_L3CR + andi. r0,r4,L3CR_L3I + bne 1b + sync +END_FTR_SECTION_IFSET(CPU_FTR_L3CR) + +6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */ + rlwinm r0,r0,0,~HID0_DCE + mtspr SPRN_HID0,r0 + sync + isync + mtmsr r11 /* restore DR and EE */ + isync + blr +#endif /* CONFIG_6xx */ diff --git a/arch/powerpc/platforms/powermac/pmac_cpufreq.c b/arch/powerpc/platforms/powermac/pmac_cpufreq.c new file mode 100644 index 000000000000..6d32d99402be --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_cpufreq.c @@ -0,0 +1,728 @@ +/* + * arch/ppc/platforms/pmac_cpufreq.c + * + * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt + * Copyright (C) 2004 John Steele Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * TODO: Need a big cleanup here. Basically, we need to have different + * cpufreq_driver structures for the different type of HW instead of the + * current mess. We also need to better deal with the detection of the + * type of machine. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* WARNING !!! This will cause calibrate_delay() to be called, + * but this is an __init function ! So you MUST go edit + * init/main.c to make it non-init before enabling DEBUG_FREQ + */ +#undef DEBUG_FREQ + +/* + * There is a problem with the core cpufreq code on SMP kernels, + * it won't recalculate the Bogomips properly + */ +#ifdef CONFIG_SMP +#warning "WARNING, CPUFREQ not recommended on SMP kernels" +#endif + +extern void low_choose_7447a_dfs(int dfs); +extern void low_choose_750fx_pll(int pll); +extern void low_sleep_handler(void); + +/* + * Currently, PowerMac cpufreq supports only high & low frequencies + * that are set by the firmware + */ +static unsigned int low_freq; +static unsigned int hi_freq; +static unsigned int cur_freq; +static unsigned int sleep_freq; + +/* + * Different models uses different mecanisms to switch the frequency + */ +static int (*set_speed_proc)(int low_speed); +static unsigned int (*get_speed_proc)(void); + +/* + * Some definitions used by the various speedprocs + */ +static u32 voltage_gpio; +static u32 frequency_gpio; +static u32 slew_done_gpio; +static int no_schedule; +static int has_cpu_l2lve; +static int is_pmu_based; + +/* There are only two frequency states for each processor. Values + * are in kHz for the time being. + */ +#define CPUFREQ_HIGH 0 +#define CPUFREQ_LOW 1 + +static struct cpufreq_frequency_table pmac_cpu_freqs[] = { + {CPUFREQ_HIGH, 0}, + {CPUFREQ_LOW, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +static struct freq_attr* pmac_cpu_freqs_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static inline void local_delay(unsigned long ms) +{ + if (no_schedule) + mdelay(ms); + else + msleep(ms); +} + +static inline void wakeup_decrementer(void) +{ + set_dec(tb_ticks_per_jiffy); + /* No currently-supported powerbook has a 601, + * so use get_tbl, not native + */ + last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); +} + +#ifdef DEBUG_FREQ +static inline void debug_calc_bogomips(void) +{ + /* This will cause a recalc of bogomips and display the + * result. We backup/restore the value to avoid affecting the + * core cpufreq framework's own calculation. + */ + extern void calibrate_delay(void); + + unsigned long save_lpj = loops_per_jiffy; + calibrate_delay(); + loops_per_jiffy = save_lpj; +} +#endif /* DEBUG_FREQ */ + +/* Switch CPU speed under 750FX CPU control + */ +static int cpu_750fx_cpu_speed(int low_speed) +{ + u32 hid2; + + if (low_speed == 0) { + /* ramping up, set voltage first */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); + /* Make sure we sleep for at least 1ms */ + local_delay(10); + + /* tweak L2 for high voltage */ + if (has_cpu_l2lve) { + hid2 = mfspr(SPRN_HID2); + hid2 &= ~0x2000; + mtspr(SPRN_HID2, hid2); + } + } +#ifdef CONFIG_6xx + low_choose_750fx_pll(low_speed); +#endif + if (low_speed == 1) { + /* tweak L2 for low voltage */ + if (has_cpu_l2lve) { + hid2 = mfspr(SPRN_HID2); + hid2 |= 0x2000; + mtspr(SPRN_HID2, hid2); + } + + /* ramping down, set voltage last */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); + local_delay(10); + } + + return 0; +} + +static unsigned int cpu_750fx_get_cpu_speed(void) +{ + if (mfspr(SPRN_HID1) & HID1_PS) + return low_freq; + else + return hi_freq; +} + +/* Switch CPU speed using DFS */ +static int dfs_set_cpu_speed(int low_speed) +{ + if (low_speed == 0) { + /* ramping up, set voltage first */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); + /* Make sure we sleep for at least 1ms */ + local_delay(1); + } + + /* set frequency */ +#ifdef CONFIG_6xx + low_choose_7447a_dfs(low_speed); +#endif + udelay(100); + + if (low_speed == 1) { + /* ramping down, set voltage last */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); + local_delay(1); + } + + return 0; +} + +static unsigned int dfs_get_cpu_speed(void) +{ + if (mfspr(SPRN_HID1) & HID1_DFS) + return low_freq; + else + return hi_freq; +} + + +/* Switch CPU speed using slewing GPIOs + */ +static int gpios_set_cpu_speed(int low_speed) +{ + int gpio, timeout = 0; + + /* If ramping up, set voltage first */ + if (low_speed == 0) { + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); + /* Delay is way too big but it's ok, we schedule */ + local_delay(10); + } + + /* Set frequency */ + gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); + if (low_speed == ((gpio & 0x01) == 0)) + goto skip; + + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, + low_speed ? 0x04 : 0x05); + udelay(200); + do { + if (++timeout > 100) + break; + local_delay(1); + gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0); + } while((gpio & 0x02) == 0); + skip: + /* If ramping down, set voltage last */ + if (low_speed == 1) { + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); + /* Delay is way too big but it's ok, we schedule */ + local_delay(10); + } + +#ifdef DEBUG_FREQ + debug_calc_bogomips(); +#endif + + return 0; +} + +/* Switch CPU speed under PMU control + */ +static int pmu_set_cpu_speed(int low_speed) +{ + struct adb_request req; + unsigned long save_l2cr; + unsigned long save_l3cr; + unsigned int pic_prio; + unsigned long flags; + + preempt_disable(); + +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); +#endif + pmu_suspend(); + + /* Disable all interrupt sources on openpic */ + pic_prio = mpic_cpu_get_priority(); + mpic_cpu_set_priority(0xf); + + /* Make sure the decrementer won't interrupt us */ + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + /* Make sure any pending DEC interrupt occuring while we did + * the above didn't re-enable the DEC */ + mb(); + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + + /* We can now disable MSR_EE */ + local_irq_save(flags); + + /* Giveup the FPU & vec */ + enable_kernel_fp(); + +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + enable_kernel_altivec(); +#endif /* CONFIG_ALTIVEC */ + + /* Save & disable L2 and L3 caches */ + save_l3cr = _get_L3CR(); /* (returns -1 if not available) */ + save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ + + /* Send the new speed command. My assumption is that this command + * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep + */ + pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed); + while (!req.complete) + pmu_poll(); + + /* Prepare the northbridge for the speed transition */ + pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1); + + /* Call low level code to backup CPU state and recover from + * hardware reset + */ + low_sleep_handler(); + + /* Restore the northbridge */ + pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0); + + /* Restore L2 cache */ + if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) + _set_L2CR(save_l2cr); + /* Restore L3 cache */ + if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0) + _set_L3CR(save_l3cr); + + /* Restore userland MMU context */ + set_context(current->active_mm->context, current->active_mm->pgd); + +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); +#endif + + /* Restore low level PMU operations */ + pmu_unlock(); + + /* Restore decrementer */ + wakeup_decrementer(); + + /* Restore interrupts */ + mpic_cpu_set_priority(pic_prio); + + /* Let interrupts flow again ... */ + local_irq_restore(flags); + +#ifdef DEBUG_FREQ + debug_calc_bogomips(); +#endif + + pmu_resume(); + + preempt_enable(); + + return 0; +} + +static int do_set_cpu_speed(int speed_mode, int notify) +{ + struct cpufreq_freqs freqs; + unsigned long l3cr; + static unsigned long prev_l3cr; + + freqs.old = cur_freq; + freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; + freqs.cpu = smp_processor_id(); + + if (freqs.old == freqs.new) + return 0; + + if (notify) + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + if (speed_mode == CPUFREQ_LOW && + cpu_has_feature(CPU_FTR_L3CR)) { + l3cr = _get_L3CR(); + if (l3cr & L3CR_L3E) { + prev_l3cr = l3cr; + _set_L3CR(0); + } + } + set_speed_proc(speed_mode == CPUFREQ_LOW); + if (speed_mode == CPUFREQ_HIGH && + cpu_has_feature(CPU_FTR_L3CR)) { + l3cr = _get_L3CR(); + if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) + _set_L3CR(prev_l3cr); + } + if (notify) + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; + + return 0; +} + +static unsigned int pmac_cpufreq_get_speed(unsigned int cpu) +{ + return cur_freq; +} + +static int pmac_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); +} + +static int pmac_cpufreq_target( struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int newstate = 0; + + if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, + target_freq, relation, &newstate)) + return -EINVAL; + + return do_set_cpu_speed(newstate, 1); +} + +unsigned int pmac_get_one_cpufreq(int i) +{ + /* Supports only one CPU for now */ + return (i == 0) ? cur_freq : 0; +} + +static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + if (policy->cpu != 0) + return -ENODEV; + + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + policy->cur = cur_freq; + + cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); + return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); +} + +static u32 read_gpio(struct device_node *np) +{ + u32 *reg = (u32 *)get_property(np, "reg", NULL); + u32 offset; + + if (reg == NULL) + return 0; + /* That works for all keylargos but shall be fixed properly + * some day... The problem is that it seems we can't rely + * on the "reg" property of the GPIO nodes, they are either + * relative to the base of KeyLargo or to the base of the + * GPIO space, and the device-tree doesn't help. + */ + offset = *reg; + if (offset < KEYLARGO_GPIO_LEVELS0) + offset += KEYLARGO_GPIO_LEVELS0; + return offset; +} + +static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) +{ + /* Ok, this could be made a bit smarter, but let's be robust for now. We + * always force a speed change to high speed before sleep, to make sure + * we have appropriate voltage and/or bus speed for the wakeup process, + * and to make sure our loops_per_jiffies are "good enough", that is will + * not cause too short delays if we sleep in low speed and wake in high + * speed.. + */ + no_schedule = 1; + sleep_freq = cur_freq; + if (cur_freq == low_freq && !is_pmu_based) + do_set_cpu_speed(CPUFREQ_HIGH, 0); + return 0; +} + +static int pmac_cpufreq_resume(struct cpufreq_policy *policy) +{ + /* If we resume, first check if we have a get() function */ + if (get_speed_proc) + cur_freq = get_speed_proc(); + else + cur_freq = 0; + + /* We don't, hrm... we don't really know our speed here, best + * is that we force a switch to whatever it was, which is + * probably high speed due to our suspend() routine + */ + do_set_cpu_speed(sleep_freq == low_freq ? + CPUFREQ_LOW : CPUFREQ_HIGH, 0); + + no_schedule = 0; + return 0; +} + +static struct cpufreq_driver pmac_cpufreq_driver = { + .verify = pmac_cpufreq_verify, + .target = pmac_cpufreq_target, + .get = pmac_cpufreq_get_speed, + .init = pmac_cpufreq_cpu_init, + .suspend = pmac_cpufreq_suspend, + .resume = pmac_cpufreq_resume, + .flags = CPUFREQ_PM_NO_WARN, + .attr = pmac_cpu_freqs_attr, + .name = "powermac", + .owner = THIS_MODULE, +}; + + +static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np = of_find_node_by_name(NULL, + "voltage-gpio"); + struct device_node *freq_gpio_np = of_find_node_by_name(NULL, + "frequency-gpio"); + struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, + "slewing-done"); + u32 *value; + + /* + * Check to see if it's GPIO driven or PMU only + * + * The way we extract the GPIO address is slightly hackish, but it + * works well enough for now. We need to abstract the whole GPIO + * stuff sooner or later anyway + */ + + if (volt_gpio_np) + voltage_gpio = read_gpio(volt_gpio_np); + if (freq_gpio_np) + frequency_gpio = read_gpio(freq_gpio_np); + if (slew_done_gpio_np) + slew_done_gpio = read_gpio(slew_done_gpio_np); + + /* If we use the frequency GPIOs, calculate the min/max speeds based + * on the bus frequencies + */ + if (frequency_gpio && slew_done_gpio) { + int lenp, rc; + u32 *freqs, *ratio; + + freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); + lenp /= sizeof(u32); + if (freqs == NULL || lenp != 2) { + printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); + return 1; + } + ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); + if (ratio == NULL) { + printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); + return 1; + } + + /* Get the min/max bus frequencies */ + low_freq = min(freqs[0], freqs[1]); + hi_freq = max(freqs[0], freqs[1]); + + /* Grrrr.. It _seems_ that the device-tree is lying on the low bus + * frequency, it claims it to be around 84Mhz on some models while + * it appears to be approx. 101Mhz on all. Let's hack around here... + * fortunately, we don't need to be too precise + */ + if (low_freq < 98000000) + low_freq = 101000000; + + /* Convert those to CPU core clocks */ + low_freq = (low_freq * (*ratio)) / 2000; + hi_freq = (hi_freq * (*ratio)) / 2000; + + /* Now we get the frequencies, we read the GPIO to see what is out current + * speed + */ + rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); + cur_freq = (rc & 0x01) ? hi_freq : low_freq; + + set_speed_proc = gpios_set_cpu_speed; + return 1; + } + + /* If we use the PMU, look for the min & max frequencies in the + * device-tree + */ + value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); + if (!value) + return 1; + low_freq = (*value) / 1000; + /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree + * here */ + if (low_freq < 100000) + low_freq *= 10; + + value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); + if (!value) + return 1; + hi_freq = (*value) / 1000; + set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; + + return 0; +} + +static int pmac_cpufreq_init_7447A(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np; + + if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) + return 1; + + volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); + if (volt_gpio_np) + voltage_gpio = read_gpio(volt_gpio_np); + if (!voltage_gpio){ + printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); + return 1; + } + + /* OF only reports the high frequency */ + hi_freq = cur_freq; + low_freq = cur_freq/2; + + /* Read actual frequency from CPU */ + cur_freq = dfs_get_cpu_speed(); + set_speed_proc = dfs_set_cpu_speed; + get_speed_proc = dfs_get_cpu_speed; + + return 0; +} + +static int pmac_cpufreq_init_750FX(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np; + u32 pvr, *value; + + if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) + return 1; + + hi_freq = cur_freq; + value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); + if (!value) + return 1; + low_freq = (*value) / 1000; + + volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); + if (volt_gpio_np) + voltage_gpio = read_gpio(volt_gpio_np); + + pvr = mfspr(SPRN_PVR); + has_cpu_l2lve = !((pvr & 0xf00) == 0x100); + + set_speed_proc = cpu_750fx_cpu_speed; + get_speed_proc = cpu_750fx_get_cpu_speed; + cur_freq = cpu_750fx_get_cpu_speed(); + + return 0; +} + +/* Currently, we support the following machines: + * + * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz) + * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz) + * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz) + * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) + * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz) + * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) + * - Recent MacRISC3 laptops + * - All new machines with 7447A CPUs + */ +static int __init pmac_cpufreq_setup(void) +{ + struct device_node *cpunode; + u32 *value; + + if (strstr(cmd_line, "nocpufreq")) + return 0; + + /* Assume only one CPU */ + cpunode = find_type_devices("cpu"); + if (!cpunode) + goto out; + + /* Get current cpu clock freq */ + value = (u32 *)get_property(cpunode, "clock-frequency", NULL); + if (!value) + goto out; + cur_freq = (*value) / 1000; + + /* Check for 7447A based MacRISC3 */ + if (machine_is_compatible("MacRISC3") && + get_property(cpunode, "dynamic-power-step", NULL) && + PVR_VER(mfspr(SPRN_PVR)) == 0x8003) { + pmac_cpufreq_init_7447A(cpunode); + /* Check for other MacRISC3 machines */ + } else if (machine_is_compatible("PowerBook3,4") || + machine_is_compatible("PowerBook3,5") || + machine_is_compatible("MacRISC3")) { + pmac_cpufreq_init_MacRISC3(cpunode); + /* Else check for iBook2 500/600 */ + } else if (machine_is_compatible("PowerBook4,1")) { + hi_freq = cur_freq; + low_freq = 400000; + set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; + } + /* Else check for TiPb 400 & 500 */ + else if (machine_is_compatible("PowerBook3,2")) { + /* We only know about the 400 MHz and the 500Mhz model + * they both have 300 MHz as low frequency + */ + if (cur_freq < 350000 || cur_freq > 550000) + goto out; + hi_freq = cur_freq; + low_freq = 300000; + set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; + } + /* Else check for 750FX */ + else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) + pmac_cpufreq_init_750FX(cpunode); +out: + if (set_speed_proc == NULL) + return -ENODEV; + + pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq; + pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq; + + printk(KERN_INFO "Registering PowerMac CPU frequency driver\n"); + printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n", + low_freq/1000, hi_freq/1000, cur_freq/1000); + + return cpufreq_register_driver(&pmac_cpufreq_driver); +} + +module_init(pmac_cpufreq_setup); + diff --git a/arch/powerpc/platforms/powermac/pmac_feature.c b/arch/powerpc/platforms/powermac/pmac_feature.c new file mode 100644 index 000000000000..2cba670c71b7 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_feature.c @@ -0,0 +1,3062 @@ +/* + * arch/ppc/platforms/pmac_feature.c + * + * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au) + * Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * 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. + * + * TODO: + * + * - Replace mdelay with some schedule loop if possible + * - Shorten some obfuscated delays on some routines (like modem + * power) + * - Refcount some clocks (see darwin) + * - Split split split... + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG_FEATURE + +#ifdef DEBUG_FEATURE +#define DBG(fmt...) printk(KERN_DEBUG fmt) +#else +#define DBG(fmt...) +#endif + +#ifdef CONFIG_6xx +extern int powersave_lowspeed; +#endif + +extern int powersave_nap; +extern struct device_node *k2_skiplist[2]; + + +/* + * We use a single global lock to protect accesses. Each driver has + * to take care of its own locking + */ +static DEFINE_SPINLOCK(feature_lock); + +#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); +#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); + + +/* + * Instance of some macio stuffs + */ +struct macio_chip macio_chips[MAX_MACIO_CHIPS]; + +struct macio_chip *macio_find(struct device_node *child, int type) +{ + while(child) { + int i; + + for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++) + if (child == macio_chips[i].of_node && + (!type || macio_chips[i].type == type)) + return &macio_chips[i]; + child = child->parent; + } + return NULL; +} +EXPORT_SYMBOL_GPL(macio_find); + +static const char *macio_names[] = +{ + "Unknown", + "Grand Central", + "OHare", + "OHareII", + "Heathrow", + "Gatwick", + "Paddington", + "Keylargo", + "Pangea", + "Intrepid", + "K2" +}; + + + +/* + * Uninorth reg. access. Note that Uni-N regs are big endian + */ + +#define UN_REG(r) (uninorth_base + ((r) >> 2)) +#define UN_IN(r) (in_be32(UN_REG(r))) +#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) +#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) +#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) + +static struct device_node *uninorth_node; +static u32 __iomem *uninorth_base; +static u32 uninorth_rev; +static int uninorth_u3; +static void __iomem *u3_ht; + +/* + * For each motherboard family, we have a table of functions pointers + * that handle the various features. + */ + +typedef long (*feature_call)(struct device_node *node, long param, long value); + +struct feature_table_entry { + unsigned int selector; + feature_call function; +}; + +struct pmac_mb_def +{ + const char* model_string; + const char* model_name; + int model_id; + struct feature_table_entry* features; + unsigned long board_flags; +}; +static struct pmac_mb_def pmac_mb; + +/* + * Here are the chip specific feature functions + */ + +static inline int simple_feature_tweak(struct device_node *node, int type, + int reg, u32 mask, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, type); + if (!macio) + return -ENODEV; + LOCK(flags); + if (value) + MACIO_BIS(reg, mask); + else + MACIO_BIC(reg, mask); + (void)MACIO_IN32(reg); + UNLOCK(flags); + + return 0; +} + +#ifndef CONFIG_POWER4 + +static long ohare_htw_scc_enable(struct device_node *node, long param, + long value) +{ + struct macio_chip* macio; + unsigned long chan_mask; + unsigned long fcr; + unsigned long flags; + int htw, trans; + unsigned long rmask; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (!strcmp(node->name, "ch-a")) + chan_mask = MACIO_FLAG_SCCA_ON; + else if (!strcmp(node->name, "ch-b")) + chan_mask = MACIO_FLAG_SCCB_ON; + else + return -ENODEV; + + htw = (macio->type == macio_heathrow || macio->type == macio_paddington + || macio->type == macio_gatwick); + /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */ + trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && + pmac_mb.model_id != PMAC_TYPE_YIKES); + if (value) { +#ifdef CONFIG_ADB_PMU + if ((param & 0xfff) == PMAC_SCC_IRDA) + pmu_enable_irled(1); +#endif /* CONFIG_ADB_PMU */ + LOCK(flags); + fcr = MACIO_IN32(OHARE_FCR); + /* Check if scc cell need enabling */ + if (!(fcr & OH_SCC_ENABLE)) { + fcr |= OH_SCC_ENABLE; + if (htw) { + /* Side effect: this will also power up the + * modem, but it's too messy to figure out on which + * ports this controls the tranceiver and on which + * it controls the modem + */ + if (trans) + fcr &= ~HRW_SCC_TRANS_EN_N; + MACIO_OUT32(OHARE_FCR, fcr); + fcr |= (rmask = HRW_RESET_SCC); + MACIO_OUT32(OHARE_FCR, fcr); + } else { + fcr |= (rmask = OH_SCC_RESET); + MACIO_OUT32(OHARE_FCR, fcr); + } + UNLOCK(flags); + (void)MACIO_IN32(OHARE_FCR); + mdelay(15); + LOCK(flags); + fcr &= ~rmask; + MACIO_OUT32(OHARE_FCR, fcr); + } + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr |= OH_SCCA_IO; + if (chan_mask & MACIO_FLAG_SCCB_ON) + fcr |= OH_SCCB_IO; + MACIO_OUT32(OHARE_FCR, fcr); + macio->flags |= chan_mask; + UNLOCK(flags); + if (param & PMAC_SCC_FLAG_XMON) + macio->flags |= MACIO_FLAG_SCC_LOCKED; + } else { + if (macio->flags & MACIO_FLAG_SCC_LOCKED) + return -EPERM; + LOCK(flags); + fcr = MACIO_IN32(OHARE_FCR); + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr &= ~OH_SCCA_IO; + if (chan_mask & MACIO_FLAG_SCCB_ON) + fcr &= ~OH_SCCB_IO; + MACIO_OUT32(OHARE_FCR, fcr); + if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) { + fcr &= ~OH_SCC_ENABLE; + if (htw && trans) + fcr |= HRW_SCC_TRANS_EN_N; + MACIO_OUT32(OHARE_FCR, fcr); + } + macio->flags &= ~(chan_mask); + UNLOCK(flags); + mdelay(10); +#ifdef CONFIG_ADB_PMU + if ((param & 0xfff) == PMAC_SCC_IRDA) + pmu_enable_irled(0); +#endif /* CONFIG_ADB_PMU */ + } + return 0; +} + +static long ohare_floppy_enable(struct device_node *node, long param, + long value) +{ + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_FLOPPY_ENABLE, value); +} + +static long ohare_mesh_enable(struct device_node *node, long param, long value) +{ + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_MESH_ENABLE, value); +} + +static long ohare_ide_enable(struct device_node *node, long param, long value) +{ + switch(param) { + case 0: + /* For some reason, setting the bit in set_initial_features() + * doesn't stick. I'm still investigating... --BenH. + */ + if (value) + simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IOBUS_ENABLE, 1); + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_BAY_IDE_ENABLE, value); + default: + return -ENODEV; + } +} + +static long ohare_ide_reset(struct device_node *node, long param, long value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE1_RESET_N, !value); + default: + return -ENODEV; + } +} + +static long ohare_sleep_state(struct device_node *node, long param, long value) +{ + struct macio_chip* macio = &macio_chips[0]; + + if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) + return -EPERM; + if (value == 1) { + MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE); + } else if (value == 0) { + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } + + return 0; +} + +static long heathrow_modem_enable(struct device_node *node, long param, + long value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + macio = macio_find(node, macio_unknown); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1; + if (!value) { + LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + mdelay(250); + } + if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && + pmac_mb.model_id != PMAC_TYPE_YIKES) { + LOCK(flags); + if (value) + MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); + else + MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(250); + } + if (value) { + LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); + } + return 0; +} + +static long heathrow_floppy_enable(struct device_node *node, long param, + long value) +{ + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, + HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE, + value); +} + +static long heathrow_mesh_enable(struct device_node *node, long param, + long value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, macio_unknown); + if (!macio) + return -ENODEV; + LOCK(flags); + /* Set clear mesh cell enable */ + if (value) + MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE); + else + MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE); + (void)MACIO_IN32(HEATHROW_FCR); + udelay(10); + /* Set/Clear termination power */ + if (value) + MACIO_BIC(HEATHROW_MBCR, 0x04000000); + else + MACIO_BIS(HEATHROW_MBCR, 0x04000000); + (void)MACIO_IN32(HEATHROW_MBCR); + udelay(10); + UNLOCK(flags); + + return 0; +} + +static long heathrow_ide_enable(struct device_node *node, long param, + long value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value); + default: + return -ENODEV; + } +} + +static long heathrow_ide_reset(struct device_node *node, long param, + long value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE1_RESET_N, !value); + default: + return -ENODEV; + } +} + +static long heathrow_bmac_enable(struct device_node *node, long param, + long value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (value) { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); + MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(10); + LOCK(flags); + MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(10); + } else { + LOCK(flags); + MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); + UNLOCK(flags); + } + return 0; +} + +static long heathrow_sound_enable(struct device_node *node, long param, + long value) +{ + struct macio_chip* macio; + unsigned long flags; + + /* B&W G3 and Yikes don't support that properly (the + * sound appear to never come back after beeing shut down). + */ + if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || + pmac_mb.model_id == PMAC_TYPE_YIKES) + return 0; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (value) { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + } else { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + UNLOCK(flags); + } + return 0; +} + +static u32 save_fcr[6]; +static u32 save_mbcr; +static u32 save_gpio_levels[2]; +static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; +static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; +static u32 save_unin_clock_ctl; +static struct dbdma_regs save_dbdma[13]; +static struct dbdma_regs save_alt_dbdma[13]; + +static void dbdma_save(struct macio_chip *macio, struct dbdma_regs *save) +{ + int i; + + /* Save state & config of DBDMA channels */ + for (i = 0; i < 13; i++) { + volatile struct dbdma_regs __iomem * chan = (void __iomem *) + (macio->base + ((0x8000+i*0x100)>>2)); + save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); + save[i].cmdptr = in_le32(&chan->cmdptr); + save[i].intr_sel = in_le32(&chan->intr_sel); + save[i].br_sel = in_le32(&chan->br_sel); + save[i].wait_sel = in_le32(&chan->wait_sel); + } +} + +static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save) +{ + int i; + + /* Save state & config of DBDMA channels */ + for (i = 0; i < 13; i++) { + volatile struct dbdma_regs __iomem * chan = (void __iomem *) + (macio->base + ((0x8000+i*0x100)>>2)); + out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); + while (in_le32(&chan->status) & ACTIVE) + mb(); + out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi); + out_le32(&chan->cmdptr, save[i].cmdptr); + out_le32(&chan->intr_sel, save[i].intr_sel); + out_le32(&chan->br_sel, save[i].br_sel); + out_le32(&chan->wait_sel, save[i].wait_sel); + } +} + +static void heathrow_sleep(struct macio_chip *macio, int secondary) +{ + if (secondary) { + dbdma_save(macio, save_alt_dbdma); + save_fcr[2] = MACIO_IN32(0x38); + save_fcr[3] = MACIO_IN32(0x3c); + } else { + dbdma_save(macio, save_dbdma); + save_fcr[0] = MACIO_IN32(0x38); + save_fcr[1] = MACIO_IN32(0x3c); + save_mbcr = MACIO_IN32(0x34); + /* Make sure sound is shut down */ + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + /* This seems to be necessary as well or the fan + * keeps coming up and battery drains fast */ + MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE); + MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N); + /* Make sure eth is down even if module or sleep + * won't work properly */ + MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET); + } + /* Make sure modem is shut down */ + MACIO_OUT8(HRW_GPIO_MODEM_RESET, + MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1); + MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); + MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE); + + /* Let things settle */ + (void)MACIO_IN32(HEATHROW_FCR); +} + +static void heathrow_wakeup(struct macio_chip *macio, int secondary) +{ + if (secondary) { + MACIO_OUT32(0x38, save_fcr[2]); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x3c, save_fcr[3]); + (void)MACIO_IN32(0x38); + mdelay(10); + dbdma_restore(macio, save_alt_dbdma); + } else { + MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x3c, save_fcr[1]); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x34, save_mbcr); + (void)MACIO_IN32(0x38); + mdelay(10); + dbdma_restore(macio, save_dbdma); + } +} + +static long heathrow_sleep_state(struct device_node *node, long param, + long value) +{ + if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) + return -EPERM; + if (value == 1) { + if (macio_chips[1].type == macio_gatwick) + heathrow_sleep(&macio_chips[0], 1); + heathrow_sleep(&macio_chips[0], 0); + } else if (value == 0) { + heathrow_wakeup(&macio_chips[0], 0); + if (macio_chips[1].type == macio_gatwick) + heathrow_wakeup(&macio_chips[0], 1); + } + return 0; +} + +static long core99_scc_enable(struct device_node *node, long param, long value) +{ + struct macio_chip* macio; + unsigned long flags; + unsigned long chan_mask; + u32 fcr; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (!strcmp(node->name, "ch-a")) + chan_mask = MACIO_FLAG_SCCA_ON; + else if (!strcmp(node->name, "ch-b")) + chan_mask = MACIO_FLAG_SCCB_ON; + else + return -ENODEV; + + if (value) { + int need_reset_scc = 0; + int need_reset_irda = 0; + + LOCK(flags); + fcr = MACIO_IN32(KEYLARGO_FCR0); + /* Check if scc cell need enabling */ + if (!(fcr & KL0_SCC_CELL_ENABLE)) { + fcr |= KL0_SCC_CELL_ENABLE; + need_reset_scc = 1; + } + if (chan_mask & MACIO_FLAG_SCCA_ON) { + fcr |= KL0_SCCA_ENABLE; + /* Don't enable line drivers for I2S modem */ + if ((param & 0xfff) == PMAC_SCC_I2S1) + fcr &= ~KL0_SCC_A_INTF_ENABLE; + else + fcr |= KL0_SCC_A_INTF_ENABLE; + } + if (chan_mask & MACIO_FLAG_SCCB_ON) { + fcr |= KL0_SCCB_ENABLE; + /* Perform irda specific inits */ + if ((param & 0xfff) == PMAC_SCC_IRDA) { + fcr &= ~KL0_SCC_B_INTF_ENABLE; + fcr |= KL0_IRDA_ENABLE; + fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE; + fcr |= KL0_IRDA_SOURCE1_SEL; + fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); + fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); + need_reset_irda = 1; + } else + fcr |= KL0_SCC_B_INTF_ENABLE; + } + MACIO_OUT32(KEYLARGO_FCR0, fcr); + macio->flags |= chan_mask; + if (need_reset_scc) { + MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(15); + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET); + } + if (need_reset_irda) { + MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(15); + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET); + } + UNLOCK(flags); + if (param & PMAC_SCC_FLAG_XMON) + macio->flags |= MACIO_FLAG_SCC_LOCKED; + } else { + if (macio->flags & MACIO_FLAG_SCC_LOCKED) + return -EPERM; + LOCK(flags); + fcr = MACIO_IN32(KEYLARGO_FCR0); + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr &= ~KL0_SCCA_ENABLE; + if (chan_mask & MACIO_FLAG_SCCB_ON) { + fcr &= ~KL0_SCCB_ENABLE; + /* Perform irda specific clears */ + if ((param & 0xfff) == PMAC_SCC_IRDA) { + fcr &= ~KL0_IRDA_ENABLE; + fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); + fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); + fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); + } + } + MACIO_OUT32(KEYLARGO_FCR0, fcr); + if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) { + fcr &= ~KL0_SCC_CELL_ENABLE; + MACIO_OUT32(KEYLARGO_FCR0, fcr); + } + macio->flags &= ~(chan_mask); + UNLOCK(flags); + mdelay(10); + } + return 0; +} + +static long +core99_modem_enable(struct device_node *node, long param, long value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + /* Hack for internal USB modem */ + if (node == NULL) { + if (macio_chips[0].type != macio_keylargo) + return -ENODEV; + node = macio_chips[0].of_node; + } + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); + gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; + gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; + + if (!value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + mdelay(250); + } + LOCK(flags); + if (value) { + MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR2); + mdelay(250); + } else { + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + UNLOCK(flags); + } + if (value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); + } + return 0; +} + +static long +pangea_modem_enable(struct device_node *node, long param, long value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + /* Hack for internal USB modem */ + if (node == NULL) { + if (macio_chips[0].type != macio_pangea && + macio_chips[0].type != macio_intrepid) + return -ENODEV; + node = macio_chips[0].of_node; + } + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); + gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; + gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; + + if (!value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + mdelay(250); + } + LOCK(flags); + if (value) { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR2); + mdelay(250); + } else { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + UNLOCK(flags); + } + if (value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); + } + return 0; +} + +static long +core99_ata100_enable(struct device_node *node, long value) +{ + unsigned long flags; + struct pci_dev *pdev = NULL; + u8 pbus, pid; + + if (uninorth_rev < 0x24) + return -ENODEV; + + LOCK(flags); + if (value) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); + (void)UN_IN(UNI_N_CLOCK_CNTL); + UNLOCK(flags); + udelay(20); + + if (value) { + if (pci_device_from_OF_node(node, &pbus, &pid) == 0) + pdev = pci_find_slot(pbus, pid); + if (pdev == NULL) + return 0; + pci_enable_device(pdev); + pci_set_master(pdev); + } + return 0; +} + +static long +core99_ide_enable(struct device_node *node, long param, long value) +{ + /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2 + * based ata-100 + */ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value); + case 2: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_UIDE_ENABLE, value); + case 3: + return core99_ata100_enable(node, value); + default: + return -ENODEV; + } +} + +static long +core99_ide_reset(struct device_node *node, long param, long value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value); + case 2: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value); + default: + return -ENODEV; + } +} + +static long +core99_gmac_enable(struct device_node *node, long param, long value) +{ + unsigned long flags; + + LOCK(flags); + if (value) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); + (void)UN_IN(UNI_N_CLOCK_CNTL); + UNLOCK(flags); + udelay(20); + + return 0; +} + +static long +core99_gmac_phy_reset(struct device_node *node, long param, long value) +{ + unsigned long flags; + struct macio_chip *macio; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + + LOCK(flags); + MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET); + UNLOCK(flags); + mdelay(10); + LOCK(flags); + MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */ + KEYLARGO_GPIO_OUTOUT_DATA); + UNLOCK(flags); + mdelay(10); + + return 0; +} + +static long +core99_sound_chip_enable(struct device_node *node, long param, long value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + + /* Do a better probe code, screamer G4 desktops & + * iMacs can do that too, add a recalibrate in + * the driver as well + */ + if (pmac_mb.model_id == PMAC_TYPE_PISMO || + pmac_mb.model_id == PMAC_TYPE_TITANIUM) { + LOCK(flags); + if (value) + MACIO_OUT8(KL_GPIO_SOUND_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE | + KEYLARGO_GPIO_OUTOUT_DATA); + else + MACIO_OUT8(KL_GPIO_SOUND_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(KL_GPIO_SOUND_POWER); + UNLOCK(flags); + } + return 0; +} + +static long +core99_airport_enable(struct device_node *node, long param, long value) +{ + struct macio_chip* macio; + unsigned long flags; + int state; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + + /* Hint: we allow passing of macio itself for the sake of the + * sleep code + */ + if (node != macio->of_node && + (!node->parent || node->parent != macio->of_node)) + return -ENODEV; + state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0; + if (value == state) + return 0; + if (value) { + /* This code is a reproduction of OF enable-cardslot + * and init-wireless methods, slightly hacked until + * I got it working. + */ + LOCK(flags); + MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); + UNLOCK(flags); + mdelay(10); + LOCK(flags); + MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); + UNLOCK(flags); + + mdelay(10); + + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe); + UNLOCK(flags); + udelay(10); + MACIO_OUT32(0x1c000, 0); + mdelay(1); + MACIO_OUT8(0x1a3e0, 0x41); + (void)MACIO_IN8(0x1a3e0); + udelay(10); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + UNLOCK(flags); + mdelay(100); + + macio->flags |= MACIO_FLAG_AIRPORT_ON; + } else { + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + MACIO_OUT8(KL_GPIO_AIRPORT_0, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_1, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_2, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_3, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_4, 0); + (void)MACIO_IN8(KL_GPIO_AIRPORT_4); + UNLOCK(flags); + + macio->flags &= ~MACIO_FLAG_AIRPORT_ON; + } + return 0; +} + +#ifdef CONFIG_SMP +static long +core99_reset_cpu(struct device_node *node, long param, long value) +{ + unsigned int reset_io = 0; + unsigned long flags; + struct macio_chip *macio; + struct device_node *np; + const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0, + KL_GPIO_RESET_CPU1, + KL_GPIO_RESET_CPU2, + KL_GPIO_RESET_CPU3 }; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo) + return -ENODEV; + + np = find_path_device("/cpus"); + if (np == NULL) + return -ENODEV; + for (np = np->child; np != NULL; np = np->sibling) { + u32 *num = (u32 *)get_property(np, "reg", NULL); + u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); + if (num == NULL || rst == NULL) + continue; + if (param == *num) { + reset_io = *rst; + break; + } + } + if (np == NULL || reset_io == 0) + reset_io = dflt_reset_lines[param]; + + LOCK(flags); + MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(reset_io); + udelay(1); + MACIO_OUT8(reset_io, 0); + (void)MACIO_IN8(reset_io); + UNLOCK(flags); + + return 0; +} +#endif /* CONFIG_SMP */ + +static long +core99_usb_enable(struct device_node *node, long param, long value) +{ + struct macio_chip *macio; + unsigned long flags; + char *prop; + int number; + u32 reg; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + + prop = (char *)get_property(node, "AAPL,clock-id", NULL); + if (!prop) + return -ENODEV; + if (strncmp(prop, "usb0u048", 8) == 0) + number = 0; + else if (strncmp(prop, "usb1u148", 8) == 0) + number = 2; + else if (strncmp(prop, "usb2u248", 8) == 0) + number = 4; + else + return -ENODEV; + + /* Sorry for the brute-force locking, but this is only used during + * sleep and the timing seem to be critical + */ + LOCK(flags); + if (value) { + /* Turn ON */ + if (number == 0) { + MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + } else if (number == 2) { + MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + } else if (number == 4) { + MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR1); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE); + } + if (number < 4) { + reg = MACIO_IN32(KEYLARGO_FCR4); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(10); + } else { + reg = MACIO_IN32(KEYLARGO_FCR3); + reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | + KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0)); + reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | + KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1)); + MACIO_OUT32(KEYLARGO_FCR3, reg); + (void)MACIO_IN32(KEYLARGO_FCR3); + udelay(10); + } + if (macio->type == macio_intrepid) { + /* wait for clock stopped bits to clear */ + u32 test0 = 0, test1 = 0; + u32 status0, status1; + int timeout = 1000; + + UNLOCK(flags); + switch (number) { + case 0: + test0 = UNI_N_CLOCK_STOPPED_USB0; + test1 = UNI_N_CLOCK_STOPPED_USB0PCI; + break; + case 2: + test0 = UNI_N_CLOCK_STOPPED_USB1; + test1 = UNI_N_CLOCK_STOPPED_USB1PCI; + break; + case 4: + test0 = UNI_N_CLOCK_STOPPED_USB2; + test1 = UNI_N_CLOCK_STOPPED_USB2PCI; + break; + } + do { + if (--timeout <= 0) { + printk(KERN_ERR "core99_usb_enable: " + "Timeout waiting for clocks\n"); + break; + } + mdelay(1); + status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0); + status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1); + } while ((status0 & test0) | (status1 & test1)); + LOCK(flags); + } + } else { + /* Turn OFF */ + if (number < 4) { + reg = MACIO_IN32(KEYLARGO_FCR4); + reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); + reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(1); + } else { + reg = MACIO_IN32(KEYLARGO_FCR3); + reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | + KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0); + reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | + KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1); + MACIO_OUT32(KEYLARGO_FCR3, reg); + (void)MACIO_IN32(KEYLARGO_FCR3); + udelay(1); + } + if (number == 0) { + if (macio->type != macio_intrepid) + MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR0); + udelay(1); + MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + } else if (number == 2) { + if (macio->type != macio_intrepid) + MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR0); + udelay(1); + MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + } else if (number == 4) { + udelay(1); + MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR1); + } + udelay(1); + } + UNLOCK(flags); + + return 0; +} + +static long +core99_firewire_enable(struct device_node *node, long param, long value) +{ + unsigned long flags; + struct macio_chip *macio; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) + return -ENODEV; + + LOCK(flags); + if (value) { + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + (void)UN_IN(UNI_N_CLOCK_CNTL); + } else { + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + (void)UN_IN(UNI_N_CLOCK_CNTL); + } + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static long +core99_firewire_cable_power(struct device_node *node, long param, long value) +{ + unsigned long flags; + struct macio_chip *macio; + + /* Trick: we allow NULL node */ + if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0) + return -ENODEV; + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) + return -ENODEV; + + LOCK(flags); + if (value) { + MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0); + MACIO_IN8(KL_GPIO_FW_CABLE_POWER); + udelay(10); + } else { + MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4); + MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10); + } + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static long +intrepid_aack_delay_enable(struct device_node *node, long param, long value) +{ + unsigned long flags; + + if (uninorth_rev < 0xd2) + return -ENODEV; + + LOCK(flags); + if (param) + UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + else + UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + UNLOCK(flags); + + return 0; +} + + +#endif /* CONFIG_POWER4 */ + +static long +core99_read_gpio(struct device_node *node, long param, long value) +{ + struct macio_chip *macio = &macio_chips[0]; + + return MACIO_IN8(param); +} + + +static long +core99_write_gpio(struct device_node *node, long param, long value) +{ + struct macio_chip *macio = &macio_chips[0]; + + MACIO_OUT8(param, (u8)(value & 0xff)); + return 0; +} + +#ifdef CONFIG_POWER4 +static long g5_gmac_enable(struct device_node *node, long param, long value) +{ + struct macio_chip *macio = &macio_chips[0]; + unsigned long flags; + + if (node == NULL) + return -ENODEV; + + LOCK(flags); + if (value) { + MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); + mb(); + k2_skiplist[0] = NULL; + } else { + k2_skiplist[0] = node; + mb(); + MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); + } + + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static long g5_fw_enable(struct device_node *node, long param, long value) +{ + struct macio_chip *macio = &macio_chips[0]; + unsigned long flags; + + if (node == NULL) + return -ENODEV; + + LOCK(flags); + if (value) { + MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); + mb(); + k2_skiplist[1] = NULL; + } else { + k2_skiplist[1] = node; + mb(); + MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); + } + + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static long g5_mpic_enable(struct device_node *node, long param, long value) +{ + unsigned long flags; + + if (node->parent == NULL || strcmp(node->parent->name, "u3")) + return 0; + + LOCK(flags); + UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE); + UNLOCK(flags); + + return 0; +} + +static long g5_eth_phy_reset(struct device_node *node, long param, long value) +{ + struct macio_chip *macio = &macio_chips[0]; + struct device_node *phy; + int need_reset; + + /* + * We must not reset the combo PHYs, only the BCM5221 found in + * the iMac G5. + */ + phy = of_get_next_child(node, NULL); + if (!phy) + return -ENODEV; + need_reset = device_is_compatible(phy, "B5221"); + of_node_put(phy); + if (!need_reset) + return 0; + + /* PHY reset is GPIO 29, not in device-tree unfortunately */ + MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, + KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + /* Thankfully, this is now always called at a time when we can + * schedule by sungem. + */ + msleep(10); + MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0); + + return 0; +} + +static long g5_i2s_enable(struct device_node *node, long param, long value) +{ + /* Very crude implementation for now */ + struct macio_chip *macio = &macio_chips[0]; + unsigned long flags; + + if (value == 0) + return 0; /* don't disable yet */ + + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE | + KL3_I2S0_CLK18_ENABLE); + udelay(10); + MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE | + K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE); + udelay(10); + MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET); + UNLOCK(flags); + udelay(10); + + return 0; +} + + +#ifdef CONFIG_SMP +static long g5_reset_cpu(struct device_node *node, long param, long value) +{ + unsigned int reset_io = 0; + unsigned long flags; + struct macio_chip *macio; + struct device_node *np; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo2) + return -ENODEV; + + np = find_path_device("/cpus"); + if (np == NULL) + return -ENODEV; + for (np = np->child; np != NULL; np = np->sibling) { + u32 *num = (u32 *)get_property(np, "reg", NULL); + u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); + if (num == NULL || rst == NULL) + continue; + if (param == *num) { + reset_io = *rst; + break; + } + } + if (np == NULL || reset_io == 0) + return -ENODEV; + + LOCK(flags); + MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(reset_io); + udelay(1); + MACIO_OUT8(reset_io, 0); + (void)MACIO_IN8(reset_io); + UNLOCK(flags); + + return 0; +} +#endif /* CONFIG_SMP */ + +/* + * This can be called from pmac_smp so isn't static + * + * This takes the second CPU off the bus on dual CPU machines + * running UP + */ +void g5_phy_disable_cpu1(void) +{ + UN_OUT(U3_API_PHY_CONFIG_1, 0); +} +#endif /* CONFIG_POWER4 */ + +#ifndef CONFIG_POWER4 + +static void +keylargo_shutdown(struct macio_chip *macio, int sleep_mode) +{ + u32 temp; + + if (sleep_mode) { + mdelay(1); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(1); + } + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | + KL0_IRDA_CLK19_ENABLE); + + MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); + MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE); + + MACIO_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | + KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | + KL1_UIDE_ENABLE); + + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); + + temp = MACIO_IN32(KEYLARGO_FCR3); + if (macio->rev >= 2) { + temp |= KL3_SHUTDOWN_PLL2X; + if (sleep_mode) + temp |= KL3_SHUTDOWN_PLL_TOTAL; + } + + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35; + if (sleep_mode) + temp |= KL3_SHUTDOWN_PLLKW12; + temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE + | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); +} + +static void +pangea_shutdown(struct macio_chip *macio, int sleep_mode) +{ + u32 temp; + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); + + MACIO_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_UIDE_ENABLE); + if (pmac_mb.board_flags & PMAC_MB_MOBILE) + MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); + + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + + temp = MACIO_IN32(KEYLARGO_FCR3); + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35; + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); +} + +static void +intrepid_shutdown(struct macio_chip *macio, int sleep_mode) +{ + u32 temp; + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE); + + MACIO_BIC(KEYLARGO_FCR1, + /*KL1_USB2_CELL_ENABLE |*/ + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE); + if (pmac_mb.board_flags & PMAC_MB_MOBILE) + MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); + + temp = MACIO_IN32(KEYLARGO_FCR3); + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | + KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(10); +} + + +void pmac_tweak_clock_spreading(int enable) +{ + struct macio_chip *macio = &macio_chips[0]; + + /* Hack for doing clock spreading on some machines PowerBooks and + * iBooks. This implements the "platform-do-clockspreading" OF + * property as decoded manually on various models. For safety, we also + * check the product ID in the device-tree in cases we'll whack the i2c + * chip to make reasonably sure we won't set wrong values in there + * + * Of course, ultimately, we have to implement a real parser for + * the platform-do-* stuff... + */ + + if (macio->type == macio_intrepid) { + if (enable) + UN_OUT(UNI_N_CLOCK_SPREADING, 2); + else + UN_OUT(UNI_N_CLOCK_SPREADING, 0); + mdelay(40); + } + + while (machine_is_compatible("PowerBook5,2") || + machine_is_compatible("PowerBook5,3") || + machine_is_compatible("PowerBook6,2") || + machine_is_compatible("PowerBook6,3")) { + struct device_node *ui2c = of_find_node_by_type(NULL, "i2c"); + struct device_node *dt = of_find_node_by_name(NULL, "device-tree"); + u8 buffer[9]; + u32 *productID; + int i, rc, changed = 0; + + if (dt == NULL) + break; + productID = (u32 *)get_property(dt, "pid#", NULL); + if (productID == NULL) + break; + while(ui2c) { + struct device_node *p = of_get_parent(ui2c); + if (p && !strcmp(p->name, "uni-n")) + break; + ui2c = of_find_node_by_type(ui2c, "i2c"); + } + if (ui2c == NULL) + break; + DBG("Trying to bump clock speed for PID: %08x...\n", *productID); + rc = pmac_low_i2c_open(ui2c, 1); + if (rc != 0) + break; + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); + DBG("read result: %d,", rc); + if (rc != 0) { + pmac_low_i2c_close(ui2c); + break; + } + for (i=0; i<9; i++) + DBG(" %02x", buffer[i]); + DBG("\n"); + + switch(*productID) { + case 0x1182: /* AlBook 12" rev 2 */ + case 0x1183: /* iBook G4 12" */ + buffer[0] = (buffer[0] & 0x8f) | 0x70; + buffer[2] = (buffer[2] & 0x7f) | 0x00; + buffer[5] = (buffer[5] & 0x80) | 0x31; + buffer[6] = (buffer[6] & 0x40) | 0xb0; + buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba); + buffer[8] = (buffer[8] & 0x00) | 0x30; + changed = 1; + break; + case 0x3142: /* AlBook 15" (ATI M10) */ + case 0x3143: /* AlBook 17" (ATI M10) */ + buffer[0] = (buffer[0] & 0xaf) | 0x50; + buffer[2] = (buffer[2] & 0x7f) | 0x00; + buffer[5] = (buffer[5] & 0x80) | 0x31; + buffer[6] = (buffer[6] & 0x40) | 0xb0; + buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0); + buffer[8] = (buffer[8] & 0x00) | 0x30; + changed = 1; + break; + default: + DBG("i2c-hwclock: Machine model not handled\n"); + break; + } + if (!changed) { + pmac_low_i2c_close(ui2c); + break; + } + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9); + DBG("write result: %d,", rc); + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); + DBG("read result: %d,", rc); + if (rc != 0) { + pmac_low_i2c_close(ui2c); + break; + } + for (i=0; i<9; i++) + DBG(" %02x", buffer[i]); + pmac_low_i2c_close(ui2c); + break; + } +} + + +static int +core99_sleep(void) +{ + struct macio_chip *macio; + int i; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + + /* We power off the wireless slot in case it was not done + * by the driver. We don't power it on automatically however + */ + if (macio->flags & MACIO_FLAG_AIRPORT_ON) + core99_airport_enable(macio->of_node, 0, 0); + + /* We power off the FW cable. Should be done by the driver... */ + if (macio->flags & MACIO_FLAG_FW_SUPPORTED) { + core99_firewire_enable(NULL, 0, 0); + core99_firewire_cable_power(NULL, 0, 0); + } + + /* We make sure int. modem is off (in case driver lost it) */ + if (macio->type == macio_keylargo) + core99_modem_enable(macio->of_node, 0, 0); + else + pangea_modem_enable(macio->of_node, 0, 0); + + /* We make sure the sound is off as well */ + core99_sound_chip_enable(macio->of_node, 0, 0); + + /* + * Save various bits of KeyLargo + */ + + /* Save the state of the various GPIOs */ + save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0); + save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1); + for (i=0; itype == macio_keylargo) + save_mbcr = MACIO_IN32(KEYLARGO_MBCR); + save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0); + save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1); + save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2); + save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3); + save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4); + if (macio->type == macio_pangea || macio->type == macio_intrepid) + save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5); + + /* Save state & config of DBDMA channels */ + dbdma_save(macio, save_dbdma); + + /* + * Turn off as much as we can + */ + if (macio->type == macio_pangea) + pangea_shutdown(macio, 1); + else if (macio->type == macio_intrepid) + intrepid_shutdown(macio, 1); + else if (macio->type == macio_keylargo) + keylargo_shutdown(macio, 1); + + /* + * Put the host bridge to sleep + */ + + save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL); + /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it + * enabled ! + */ + UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl & + ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/)); + udelay(100); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP); + mdelay(10); + + /* + * FIXME: A bit of black magic with OpenPIC (don't ask me why) + */ + if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) { + MACIO_BIS(0x506e0, 0x00400000); + MACIO_BIS(0x506e0, 0x80000000); + } + return 0; +} + +static int +core99_wake_up(void) +{ + struct macio_chip *macio; + int i; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) + return -ENODEV; + + /* + * Wakeup the host bridge + */ + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); + udelay(10); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); + udelay(10); + + /* + * Restore KeyLargo + */ + + if (macio->type == macio_keylargo) { + MACIO_OUT32(KEYLARGO_MBCR, save_mbcr); + (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + } + MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]); + (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); + MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]); + (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); + MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]); + (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10); + MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]); + (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); + MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]); + (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10); + if (macio->type == macio_pangea || macio->type == macio_intrepid) { + MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]); + (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10); + } + + dbdma_restore(macio, save_dbdma); + + MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]); + MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]); + for (i=0; itype) { +#ifndef CONFIG_POWER4 + case macio_grand_central: + pmac_mb.model_id = PMAC_TYPE_PSURGE; + pmac_mb.model_name = "Unknown PowerSurge"; + break; + case macio_ohare: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE; + pmac_mb.model_name = "Unknown OHare-based"; + break; + case macio_heathrow: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW; + pmac_mb.model_name = "Unknown Heathrow-based"; + pmac_mb.features = heathrow_desktop_features; + break; + case macio_paddington: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON; + pmac_mb.model_name = "Unknown Paddington-based"; + pmac_mb.features = paddington_features; + break; + case macio_keylargo: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99; + pmac_mb.model_name = "Unknown Keylargo-based"; + pmac_mb.features = core99_features; + break; + case macio_pangea: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA; + pmac_mb.model_name = "Unknown Pangea-based"; + pmac_mb.features = pangea_features; + break; + case macio_intrepid: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID; + pmac_mb.model_name = "Unknown Intrepid-based"; + pmac_mb.features = intrepid_features; + break; +#else /* CONFIG_POWER4 */ + case macio_keylargo2: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2; + pmac_mb.model_name = "Unknown K2-based"; + pmac_mb.features = g5_features; + break; +#endif /* CONFIG_POWER4 */ + default: + return -ENODEV; + } +found: +#ifndef CONFIG_POWER4 + /* Fixup Hooper vs. Comet */ + if (pmac_mb.model_id == PMAC_TYPE_HOOPER) { + u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4); + if (!mach_id_ptr) + return -ENODEV; + /* Here, I used to disable the media-bay on comet. It + * appears this is wrong, the floppy connector is actually + * a kind of media-bay and works with the current driver. + */ + if (__raw_readl(mach_id_ptr) & 0x20000000UL) + pmac_mb.model_id = PMAC_TYPE_COMET; + iounmap(mach_id_ptr); + } +#endif /* CONFIG_POWER4 */ + +#ifdef CONFIG_6xx + /* Set default value of powersave_nap on machines that support it. + * It appears that uninorth rev 3 has a problem with it, we don't + * enable it on those. In theory, the flush-on-lock property is + * supposed to be set when not supported, but I'm not very confident + * that all Apple OF revs did it properly, I do it the paranoid way. + */ + while (uninorth_base && uninorth_rev > 3) { + struct device_node *np = find_path_device("/cpus"); + if (!np || !np->child) { + printk(KERN_WARNING "Can't find CPU(s) in device tree !\n"); + break; + } + np = np->child; + /* Nap mode not supported on SMP */ + if (np->sibling) + break; + /* Nap mode not supported if flush-on-lock property is present */ + if (get_property(np, "flush-on-lock", NULL)) + break; + powersave_nap = 1; + printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); + break; + } + + /* On CPUs that support it (750FX), lowspeed by default during + * NAP mode + */ + powersave_lowspeed = 1; +#endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + powersave_nap = 1; +#endif + /* Check for "mobile" machine */ + if (model && (strncmp(model, "PowerBook", 9) == 0 + || strncmp(model, "iBook", 5) == 0)) + pmac_mb.board_flags |= PMAC_MB_MOBILE; + + + printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); + return 0; +} + +/* Initialize the Core99 UniNorth host bridge and memory controller + */ +static void __init probe_uninorth(void) +{ + unsigned long actrl; + + /* Locate core99 Uni-N */ + uninorth_node = of_find_node_by_name(NULL, "uni-n"); + /* Locate G5 u3 */ + if (uninorth_node == NULL) { + uninorth_node = of_find_node_by_name(NULL, "u3"); + uninorth_u3 = 1; + } + if (uninorth_node && uninorth_node->n_addrs > 0) { + unsigned long address = uninorth_node->addrs[0].address; + uninorth_base = ioremap(address, 0x40000); + uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); + if (uninorth_u3) + u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); + } else + uninorth_node = NULL; + + if (!uninorth_node) + return; + + printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n", + uninorth_u3 ? "U3" : "UniNorth", uninorth_rev); + printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); + + /* Set the arbitrer QAck delay according to what Apple does + */ + if (uninorth_rev < 0x11) { + actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; + actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : + UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; + UN_OUT(UNI_N_ARB_CTRL, actrl); + } + + /* Some more magic as done by them in recent MacOS X on UniNorth + * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI + * memory timeout + */ + if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) + UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); +} + +static void __init probe_one_macio(const char *name, const char *compat, int type) +{ + struct device_node* node; + int i; + volatile u32 __iomem * base; + u32* revp; + + node = find_devices(name); + if (!node || !node->n_addrs) + return; + if (compat) + do { + if (device_is_compatible(node, compat)) + break; + node = node->next; + } while (node); + if (!node) + return; + for(i=0; i= MAX_MACIO_CHIPS) { + printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); + printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); + return; + } + base = ioremap(node->addrs[0].address, node->addrs[0].size); + if (!base) { + printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); + return; + } + if (type == macio_keylargo) { + u32 *did = (u32 *)get_property(node, "device-id", NULL); + if (*did == 0x00000025) + type = macio_pangea; + if (*did == 0x0000003e) + type = macio_intrepid; + } + macio_chips[i].of_node = node; + macio_chips[i].type = type; + macio_chips[i].base = base; + macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; + macio_chips[i].name = macio_names[type]; + revp = (u32 *)get_property(node, "revision-id", NULL); + if (revp) + macio_chips[i].rev = *revp; + printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", + macio_names[type], macio_chips[i].rev, macio_chips[i].base); +} + +static int __init +probe_macios(void) +{ + /* Warning, ordering is important */ + probe_one_macio("gc", NULL, macio_grand_central); + probe_one_macio("ohare", NULL, macio_ohare); + probe_one_macio("pci106b,7", NULL, macio_ohareII); + probe_one_macio("mac-io", "keylargo", macio_keylargo); + probe_one_macio("mac-io", "paddington", macio_paddington); + probe_one_macio("mac-io", "gatwick", macio_gatwick); + probe_one_macio("mac-io", "heathrow", macio_heathrow); + probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2); + + /* Make sure the "main" macio chip appear first */ + if (macio_chips[0].type == macio_gatwick + && macio_chips[1].type == macio_heathrow) { + struct macio_chip temp = macio_chips[0]; + macio_chips[0] = macio_chips[1]; + macio_chips[1] = temp; + } + if (macio_chips[0].type == macio_ohareII + && macio_chips[1].type == macio_ohare) { + struct macio_chip temp = macio_chips[0]; + macio_chips[0] = macio_chips[1]; + macio_chips[1] = temp; + } + macio_chips[0].lbus.index = 0; + macio_chips[1].lbus.index = 1; + + return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; +} + +static void __init +initial_serial_shutdown(struct device_node *np) +{ + int len; + struct slot_names_prop { + int count; + char name[1]; + } *slots; + char *conn; + int port_type = PMAC_SCC_ASYNC; + int modem = 0; + + slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); + conn = get_property(np, "AAPL,connector", &len); + if (conn && (strcmp(conn, "infrared") == 0)) + port_type = PMAC_SCC_IRDA; + else if (device_is_compatible(np, "cobalt")) + modem = 1; + else if (slots && slots->count > 0) { + if (strcmp(slots->name, "IrDA") == 0) + port_type = PMAC_SCC_IRDA; + else if (strcmp(slots->name, "Modem") == 0) + modem = 1; + } + if (modem) + pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0); + pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0); +} + +static void __init +set_initial_features(void) +{ + struct device_node *np; + + /* That hack appears to be necessary for some StarMax motherboards + * but I'm not too sure it was audited for side-effects on other + * ohare based machines... + * Since I still have difficulties figuring the right way to + * differenciate them all and since that hack was there for a long + * time, I'll keep it around + */ + if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) { + struct macio_chip *macio = &macio_chips[0]; + MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES); + } else if (macio_chips[0].type == macio_ohare) { + struct macio_chip *macio = &macio_chips[0]; + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } else if (macio_chips[1].type == macio_ohare) { + struct macio_chip *macio = &macio_chips[1]; + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } + +#ifdef CONFIG_POWER4 + if (macio_chips[0].type == macio_keylargo2) { +#ifndef CONFIG_SMP + /* On SMP machines running UP, we have the second CPU eating + * bus cycles. We need to take it off the bus. This is done + * from pmac_smp for SMP kernels running on one CPU + */ + np = of_find_node_by_type(NULL, "cpu"); + if (np != NULL) + np = of_find_node_by_type(np, "cpu"); + if (np != NULL) { + g5_phy_disable_cpu1(); + of_node_put(np); + } +#endif /* CONFIG_SMP */ + /* Enable GMAC for now for PCI probing. It will be disabled + * later on after PCI probe + */ + np = of_find_node_by_name(NULL, "ethernet"); + while(np) { + if (device_is_compatible(np, "K2-GMAC")) + g5_gmac_enable(np, 0, 1); + np = of_find_node_by_name(np, "ethernet"); + } + + /* Enable FW before PCI probe. Will be disabled later on + * Note: We should have a batter way to check that we are + * dealing with uninorth internal cell and not a PCI cell + * on the external PCI. The code below works though. + */ + np = of_find_node_by_name(NULL, "firewire"); + while(np) { + if (device_is_compatible(np, "pci106b,5811")) { + macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; + g5_fw_enable(np, 0, 1); + } + np = of_find_node_by_name(np, "firewire"); + } + } +#else /* CONFIG_POWER4 */ + + if (macio_chips[0].type == macio_keylargo || + macio_chips[0].type == macio_pangea || + macio_chips[0].type == macio_intrepid) { + /* Enable GMAC for now for PCI probing. It will be disabled + * later on after PCI probe + */ + np = of_find_node_by_name(NULL, "ethernet"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "gmac")) + core99_gmac_enable(np, 0, 1); + np = of_find_node_by_name(np, "ethernet"); + } + + /* Enable FW before PCI probe. Will be disabled later on + * Note: We should have a batter way to check that we are + * dealing with uninorth internal cell and not a PCI cell + * on the external PCI. The code below works though. + */ + np = of_find_node_by_name(NULL, "firewire"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && (device_is_compatible(np, "pci106b,18") || + device_is_compatible(np, "pci106b,30") || + device_is_compatible(np, "pci11c1,5811"))) { + macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; + core99_firewire_enable(np, 0, 1); + } + np = of_find_node_by_name(np, "firewire"); + } + + /* Enable ATA-100 before PCI probe. */ + np = of_find_node_by_name(NULL, "ata-6"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "kauai-ata")) { + core99_ata100_enable(np, 1); + } + np = of_find_node_by_name(np, "ata-6"); + } + + /* Switch airport off */ + np = find_devices("radio"); + while(np) { + if (np && np->parent == macio_chips[0].of_node) { + macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; + core99_airport_enable(np, 0, 0); + } + np = np->next; + } + } + + /* On all machines that support sound PM, switch sound off */ + if (macio_chips[0].of_node) + pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, + macio_chips[0].of_node, 0, 0); + + /* While on some desktop G3s, we turn it back on */ + if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow + && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER || + pmac_mb.model_id == PMAC_TYPE_SILK)) { + struct macio_chip *macio = &macio_chips[0]; + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); + } + + /* Some machine models need the clock chip to be properly setup for + * clock spreading now. This should be a platform function but we + * don't do these at the moment + */ + pmac_tweak_clock_spreading(1); + +#endif /* CONFIG_POWER4 */ + + /* On all machines, switch modem & serial ports off */ + np = find_devices("ch-a"); + while(np) { + initial_serial_shutdown(np); + np = np->next; + } + np = find_devices("ch-b"); + while(np) { + initial_serial_shutdown(np); + np = np->next; + } +} + +void __init +pmac_feature_init(void) +{ + /* Detect the UniNorth memory controller */ + probe_uninorth(); + + /* Probe mac-io controllers */ + if (probe_macios()) { + printk(KERN_WARNING "No mac-io chip found\n"); + return; + } + + /* Setup low-level i2c stuffs */ + pmac_init_low_i2c(); + + /* Probe machine type */ + if (probe_motherboard()) + printk(KERN_WARNING "Unknown PowerMac !\n"); + + /* Set some initial features (turn off some chips that will + * be later turned on) + */ + set_initial_features(); +} + +int __init pmac_feature_late_init(void) +{ +#if 0 + struct device_node *np; + + /* Request some resources late */ + if (uninorth_node) + request_OF_resource(uninorth_node, 0, NULL); + np = find_devices("hammerhead"); + if (np) + request_OF_resource(np, 0, NULL); + np = find_devices("interrupt-controller"); + if (np) + request_OF_resource(np, 0, NULL); +#endif + return 0; +} + +device_initcall(pmac_feature_late_init); + +#if 0 +static void dump_HT_speeds(char *name, u32 cfg, u32 frq) +{ + int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 }; + int bits[8] = { 8,16,0,32,2,4,0,0 }; + int freq = (frq >> 8) & 0xf; + + if (freqs[freq] == 0) + printk("%s: Unknown HT link frequency %x\n", name, freq); + else + printk("%s: %d MHz on main link, (%d in / %d out) bits width\n", + name, freqs[freq], + bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]); +} + +void __init pmac_check_ht_link(void) +{ +#if 0 /* Disabled for now */ + u32 ufreq, freq, ucfg, cfg; + struct device_node *pcix_node; + u8 px_bus, px_devfn; + struct pci_controller *px_hose; + + (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); + ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); + ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); + dump_HT_speeds("U3 HyperTransport", cfg, freq); + + pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); + if (pcix_node == NULL) { + printk("No PCI-X bridge found\n"); + return; + } + if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) { + printk("PCI-X bridge found but not matched to pci\n"); + return; + } + px_hose = pci_find_hose_for_OF_device(pcix_node); + if (px_hose == NULL) { + printk("PCI-X bridge found but not matched to host\n"); + return; + } + early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); + early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); + dump_HT_speeds("PCI-X HT Uplink", cfg, freq); + early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg); + early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq); + dump_HT_speeds("PCI-X HT Downlink", cfg, freq); +#endif +} + +#endif /* CONFIG_POWER4 */ + +/* + * Early video resume hook + */ + +static void (*pmac_early_vresume_proc)(void *data); +static void *pmac_early_vresume_data; + +void pmac_set_early_video_resume(void (*proc)(void *data), void *data) +{ + if (_machine != _MACH_Pmac) + return; + preempt_disable(); + pmac_early_vresume_proc = proc; + pmac_early_vresume_data = data; + preempt_enable(); +} +EXPORT_SYMBOL(pmac_set_early_video_resume); + +void pmac_call_early_video_resume(void) +{ + if (pmac_early_vresume_proc) + pmac_early_vresume_proc(pmac_early_vresume_data); +} + +/* + * AGP related suspend/resume code + */ + +static struct pci_dev *pmac_agp_bridge; +static int (*pmac_agp_suspend)(struct pci_dev *bridge); +static int (*pmac_agp_resume)(struct pci_dev *bridge); + +void pmac_register_agp_pm(struct pci_dev *bridge, + int (*suspend)(struct pci_dev *bridge), + int (*resume)(struct pci_dev *bridge)) +{ + if (suspend || resume) { + pmac_agp_bridge = bridge; + pmac_agp_suspend = suspend; + pmac_agp_resume = resume; + return; + } + if (bridge != pmac_agp_bridge) + return; + pmac_agp_suspend = pmac_agp_resume = NULL; + return; +} +EXPORT_SYMBOL(pmac_register_agp_pm); + +void pmac_suspend_agp_for_card(struct pci_dev *dev) +{ + if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL) + return; + if (pmac_agp_bridge->bus != dev->bus) + return; + pmac_agp_suspend(pmac_agp_bridge); +} +EXPORT_SYMBOL(pmac_suspend_agp_for_card); + +void pmac_resume_agp_for_card(struct pci_dev *dev) +{ + if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL) + return; + if (pmac_agp_bridge->bus != dev->bus) + return; + pmac_agp_resume(pmac_agp_bridge); +} +EXPORT_SYMBOL(pmac_resume_agp_for_card); diff --git a/arch/powerpc/platforms/powermac/pmac_low_i2c.c b/arch/powerpc/platforms/powermac/pmac_low_i2c.c new file mode 100644 index 000000000000..f3f39e8e337a --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_low_i2c.c @@ -0,0 +1,523 @@ +/* + * arch/ppc/platforms/pmac_low_i2c.c + * + * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * 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 file contains some low-level i2c access routines that + * need to be used by various bits of the PowerMac platform code + * at times where the real asynchronous & interrupt driven driver + * cannot be used. The API borrows some semantics from the darwin + * driver in order to ease the implementation of the platform + * properties parser + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_LOW_I2C_HOST 4 + +#ifdef DEBUG +#define DBG(x...) do {\ + printk(KERN_DEBUG "KW:" x); \ + } while(0) +#else +#define DBG(x...) +#endif + +struct low_i2c_host; + +typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len); + +struct low_i2c_host +{ + struct device_node *np; /* OF device node */ + struct semaphore mutex; /* Access mutex for use by i2c-keywest */ + low_i2c_func_t func; /* Access function */ + unsigned int is_open : 1; /* Poor man's access control */ + int mode; /* Current mode */ + int channel; /* Current channel */ + int num_channels; /* Number of channels */ + void __iomem *base; /* For keywest-i2c, base address */ + int bsteps; /* And register stepping */ + int speed; /* And speed */ +}; + +static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST]; + +/* No locking is necessary on allocation, we are running way before + * anything can race with us + */ +static struct low_i2c_host *find_low_i2c_host(struct device_node *np) +{ + int i; + + for (i = 0; i < MAX_LOW_I2C_HOST; i++) + if (low_i2c_hosts[i].np == np) + return &low_i2c_hosts[i]; + return NULL; +} + +/* + * + * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's) + * + */ + +/* + * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h, + * should be moved somewhere in include/asm-ppc/ + */ +/* Register indices */ +typedef enum { + reg_mode = 0, + reg_control, + reg_status, + reg_isr, + reg_ier, + reg_addr, + reg_subaddr, + reg_data +} reg_t; + + +/* Mode register */ +#define KW_I2C_MODE_100KHZ 0x00 +#define KW_I2C_MODE_50KHZ 0x01 +#define KW_I2C_MODE_25KHZ 0x02 +#define KW_I2C_MODE_DUMB 0x00 +#define KW_I2C_MODE_STANDARD 0x04 +#define KW_I2C_MODE_STANDARDSUB 0x08 +#define KW_I2C_MODE_COMBINED 0x0C +#define KW_I2C_MODE_MODE_MASK 0x0C +#define KW_I2C_MODE_CHAN_MASK 0xF0 + +/* Control register */ +#define KW_I2C_CTL_AAK 0x01 +#define KW_I2C_CTL_XADDR 0x02 +#define KW_I2C_CTL_STOP 0x04 +#define KW_I2C_CTL_START 0x08 + +/* Status register */ +#define KW_I2C_STAT_BUSY 0x01 +#define KW_I2C_STAT_LAST_AAK 0x02 +#define KW_I2C_STAT_LAST_RW 0x04 +#define KW_I2C_STAT_SDA 0x08 +#define KW_I2C_STAT_SCL 0x10 + +/* IER & ISR registers */ +#define KW_I2C_IRQ_DATA 0x01 +#define KW_I2C_IRQ_ADDR 0x02 +#define KW_I2C_IRQ_STOP 0x04 +#define KW_I2C_IRQ_START 0x08 +#define KW_I2C_IRQ_MASK 0x0F + +/* State machine states */ +enum { + state_idle, + state_addr, + state_read, + state_write, + state_stop, + state_dead +}; + +#define WRONG_STATE(name) do {\ + printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ + name, __kw_state_names[state], isr); \ + } while(0) + +static const char *__kw_state_names[] = { + "state_idle", + "state_addr", + "state_read", + "state_write", + "state_stop", + "state_dead" +}; + +static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg) +{ + return readb(host->base + (((unsigned int)reg) << host->bsteps)); +} + +static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val) +{ + writeb(val, host->base + (((unsigned)reg) << host->bsteps)); + (void)__kw_read_reg(host, reg_subaddr); +} + +#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) +#define kw_read_reg(reg) __kw_read_reg(host, reg) + + +/* Don't schedule, the g5 fan controller is too + * timing sensitive + */ +static u8 kw_wait_interrupt(struct low_i2c_host* host) +{ + int i, j; + u8 isr; + + for (i = 0; i < 100000; i++) { + isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; + if (isr != 0) + return isr; + + /* This code is used with the timebase frozen, we cannot rely + * on udelay ! For now, just use a bogus loop + */ + for (j = 1; j < 10000; j++) + mb(); + } + return isr; +} + +static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr) +{ + u8 ack; + + DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr); + + if (isr == 0) { + if (state != state_stop) { + DBG("KW: Timeout !\n"); + *rc = -EIO; + goto stop; + } + if (state == state_stop) { + ack = kw_read_reg(reg_status); + if (!(ack & KW_I2C_STAT_BUSY)) { + state = state_idle; + kw_write_reg(reg_ier, 0x00); + } + } + return state; + } + + if (isr & KW_I2C_IRQ_ADDR) { + ack = kw_read_reg(reg_status); + if (state != state_addr) { + kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); + WRONG_STATE("KW_I2C_IRQ_ADDR"); + *rc = -EIO; + goto stop; + } + if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { + *rc = -ENODEV; + DBG("KW: NAK on address\n"); + return state_stop; + } else { + if (rw) { + state = state_read; + if (*len > 1) + kw_write_reg(reg_control, KW_I2C_CTL_AAK); + } else { + state = state_write; + kw_write_reg(reg_data, **data); + (*data)++; (*len)--; + } + } + kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); + } + + if (isr & KW_I2C_IRQ_DATA) { + if (state == state_read) { + **data = kw_read_reg(reg_data); + (*data)++; (*len)--; + kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); + if ((*len) == 0) + state = state_stop; + else if ((*len) == 1) + kw_write_reg(reg_control, 0); + } else if (state == state_write) { + ack = kw_read_reg(reg_status); + if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { + DBG("KW: nack on data write\n"); + *rc = -EIO; + goto stop; + } else if (*len) { + kw_write_reg(reg_data, **data); + (*data)++; (*len)--; + } else { + kw_write_reg(reg_control, KW_I2C_CTL_STOP); + state = state_stop; + *rc = 0; + } + kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); + } else { + kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); + WRONG_STATE("KW_I2C_IRQ_DATA"); + if (state != state_stop) { + *rc = -EIO; + goto stop; + } + } + } + + if (isr & KW_I2C_IRQ_STOP) { + kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); + if (state != state_stop) { + WRONG_STATE("KW_I2C_IRQ_STOP"); + *rc = -EIO; + } + return state_idle; + } + + if (isr & KW_I2C_IRQ_START) + kw_write_reg(reg_isr, KW_I2C_IRQ_START); + + return state; + + stop: + kw_write_reg(reg_control, KW_I2C_CTL_STOP); + return state_stop; +} + +static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len) +{ + u8 mode_reg = host->speed; + int state = state_addr; + int rc = 0; + + /* Setup mode & subaddress if any */ + switch(host->mode) { + case pmac_low_i2c_mode_dumb: + printk(KERN_ERR "low_i2c: Dumb mode not supported !\n"); + return -EINVAL; + case pmac_low_i2c_mode_std: + mode_reg |= KW_I2C_MODE_STANDARD; + break; + case pmac_low_i2c_mode_stdsub: + mode_reg |= KW_I2C_MODE_STANDARDSUB; + break; + case pmac_low_i2c_mode_combined: + mode_reg |= KW_I2C_MODE_COMBINED; + break; + } + + /* Setup channel & clear pending irqs */ + kw_write_reg(reg_isr, kw_read_reg(reg_isr)); + kw_write_reg(reg_mode, mode_reg | (host->channel << 4)); + kw_write_reg(reg_status, 0); + + /* Set up address and r/w bit */ + kw_write_reg(reg_addr, addr); + + /* Set up the sub address */ + if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB + || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) + kw_write_reg(reg_subaddr, subaddr); + + /* Start sending address & disable interrupt*/ + kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); + kw_write_reg(reg_control, KW_I2C_CTL_XADDR); + + /* State machine, to turn into an interrupt handler */ + while(state != state_idle) { + u8 isr = kw_wait_interrupt(host); + state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr); + } + + return rc; +} + +static void keywest_low_i2c_add(struct device_node *np) +{ + struct low_i2c_host *host = find_low_i2c_host(NULL); + u32 *psteps, *prate, steps, aoffset = 0; + struct device_node *parent; + + if (host == NULL) { + printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", + np->full_name); + return; + } + memset(host, 0, sizeof(*host)); + + init_MUTEX(&host->mutex); + host->np = of_node_get(np); + psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); + steps = psteps ? (*psteps) : 0x10; + for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) + steps >>= 1; + parent = of_get_parent(np); + host->num_channels = 1; + if (parent && parent->name[0] == 'u') { + host->num_channels = 2; + aoffset = 3; + } + /* Select interface rate */ + host->speed = KW_I2C_MODE_100KHZ; + prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); + if (prate) switch(*prate) { + case 100: + host->speed = KW_I2C_MODE_100KHZ; + break; + case 50: + host->speed = KW_I2C_MODE_50KHZ; + break; + case 25: + host->speed = KW_I2C_MODE_25KHZ; + break; + } + + host->mode = pmac_low_i2c_mode_std; + host->base = ioremap(np->addrs[0].address + aoffset, + np->addrs[0].size); + host->func = keywest_low_i2c_func; +} + +/* + * + * PMU implementation + * + */ + + +#ifdef CONFIG_ADB_PMU + +static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len) +{ + // TODO + return -ENODEV; +} + +static void pmu_low_i2c_add(struct device_node *np) +{ + struct low_i2c_host *host = find_low_i2c_host(NULL); + + if (host == NULL) { + printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", + np->full_name); + return; + } + memset(host, 0, sizeof(*host)); + + init_MUTEX(&host->mutex); + host->np = of_node_get(np); + host->num_channels = 3; + host->mode = pmac_low_i2c_mode_std; + host->func = pmu_low_i2c_func; +} + +#endif /* CONFIG_ADB_PMU */ + +void __init pmac_init_low_i2c(void) +{ + struct device_node *np; + + /* Probe keywest-i2c busses */ + np = of_find_compatible_node(NULL, "i2c", "keywest-i2c"); + while(np) { + keywest_low_i2c_add(np); + np = of_find_compatible_node(np, "i2c", "keywest-i2c"); + } + +#ifdef CONFIG_ADB_PMU + /* Probe PMU busses */ + np = of_find_node_by_name(NULL, "via-pmu"); + if (np) + pmu_low_i2c_add(np); +#endif /* CONFIG_ADB_PMU */ + + /* TODO: Add CUDA support as well */ +} + +int pmac_low_i2c_lock(struct device_node *np) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + down(&host->mutex); + return 0; +} +EXPORT_SYMBOL(pmac_low_i2c_lock); + +int pmac_low_i2c_unlock(struct device_node *np) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + up(&host->mutex); + return 0; +} +EXPORT_SYMBOL(pmac_low_i2c_unlock); + + +int pmac_low_i2c_open(struct device_node *np, int channel) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + + if (channel >= host->num_channels) + return -EINVAL; + + down(&host->mutex); + host->is_open = 1; + host->channel = channel; + + return 0; +} +EXPORT_SYMBOL(pmac_low_i2c_open); + +int pmac_low_i2c_close(struct device_node *np) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + + host->is_open = 0; + up(&host->mutex); + + return 0; +} +EXPORT_SYMBOL(pmac_low_i2c_close); + +int pmac_low_i2c_setmode(struct device_node *np, int mode) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + WARN_ON(!host->is_open); + host->mode = mode; + + return 0; +} +EXPORT_SYMBOL(pmac_low_i2c_setmode); + +int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len) +{ + struct low_i2c_host *host = find_low_i2c_host(np); + + if (!host) + return -ENODEV; + WARN_ON(!host->is_open); + + return host->func(host, addrdir, subaddr, data, len); +} +EXPORT_SYMBOL(pmac_low_i2c_xfer); + diff --git a/arch/powerpc/platforms/powermac/pmac_nvram.c b/arch/powerpc/platforms/powermac/pmac_nvram.c new file mode 100644 index 000000000000..8c9b008c7226 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_nvram.c @@ -0,0 +1,584 @@ +/* + * arch/ppc/platforms/pmac_nvram.c + * + * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * + * 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. + * + * Todo: - add support for the OF persistent properties + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ + +#define CORE99_SIGNATURE 0x5a +#define CORE99_ADLER_START 0x14 + +/* On Core99, nvram is either a sharp, a micron or an AMD flash */ +#define SM_FLASH_STATUS_DONE 0x80 +#define SM_FLASH_STATUS_ERR 0x38 +#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 +#define SM_FLASH_CMD_ERASE_SETUP 0x20 +#define SM_FLASH_CMD_RESET 0xff +#define SM_FLASH_CMD_WRITE_SETUP 0x40 +#define SM_FLASH_CMD_CLEAR_STATUS 0x50 +#define SM_FLASH_CMD_READ_STATUS 0x70 + +/* CHRP NVRAM header */ +struct chrp_header { + u8 signature; + u8 cksum; + u16 len; + char name[12]; + u8 data[0]; +}; + +struct core99_header { + struct chrp_header hdr; + u32 adler; + u32 generation; + u32 reserved[2]; +}; + +/* + * Read and write the non-volatile RAM on PowerMacs and CHRP machines. + */ +static int nvram_naddrs; +static volatile unsigned char *nvram_addr; +static volatile unsigned char *nvram_data; +static int nvram_mult, is_core_99; +static int core99_bank = 0; +static int nvram_partitions[3]; +static DEFINE_SPINLOCK(nv_lock); + +extern int pmac_newworld; +extern int system_running; + +static int (*core99_write_bank)(int bank, u8* datas); +static int (*core99_erase_bank)(int bank); + +static char *nvram_image; + + +static unsigned char core99_nvram_read_byte(int addr) +{ + if (nvram_image == NULL) + return 0xff; + return nvram_image[addr]; +} + +static void core99_nvram_write_byte(int addr, unsigned char val) +{ + if (nvram_image == NULL) + return; + nvram_image[addr] = val; +} + + +static unsigned char direct_nvram_read_byte(int addr) +{ + return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]); +} + +static void direct_nvram_write_byte(int addr, unsigned char val) +{ + out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val); +} + + +static unsigned char indirect_nvram_read_byte(int addr) +{ + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&nv_lock, flags); + out_8(nvram_addr, addr >> 5); + val = in_8(&nvram_data[(addr & 0x1f) << 4]); + spin_unlock_irqrestore(&nv_lock, flags); + + return val; +} + +static void indirect_nvram_write_byte(int addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&nv_lock, flags); + out_8(nvram_addr, addr >> 5); + out_8(&nvram_data[(addr & 0x1f) << 4], val); + spin_unlock_irqrestore(&nv_lock, flags); +} + + +#ifdef CONFIG_ADB_PMU + +static void pmu_nvram_complete(struct adb_request *req) +{ + if (req->arg) + complete((struct completion *)req->arg); +} + +static unsigned char pmu_nvram_read_byte(int addr) +{ + struct adb_request req; + DECLARE_COMPLETION(req_complete); + + req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; + if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM, + (addr >> 8) & 0xff, addr & 0xff)) + return 0xff; + if (system_state == SYSTEM_RUNNING) + wait_for_completion(&req_complete); + while (!req.complete) + pmu_poll(); + return req.reply[0]; +} + +static void pmu_nvram_write_byte(int addr, unsigned char val) +{ + struct adb_request req; + DECLARE_COMPLETION(req_complete); + + req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; + if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM, + (addr >> 8) & 0xff, addr & 0xff, val)) + return; + if (system_state == SYSTEM_RUNNING) + wait_for_completion(&req_complete); + while (!req.complete) + pmu_poll(); +} + +#endif /* CONFIG_ADB_PMU */ + + +static u8 chrp_checksum(struct chrp_header* hdr) +{ + u8 *ptr; + u16 sum = hdr->signature; + for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++) + sum += *ptr; + while (sum > 0xFF) + sum = (sum & 0xFF) + (sum>>8); + return sum; +} + +static u32 core99_calc_adler(u8 *buffer) +{ + int cnt; + u32 low, high; + + buffer += CORE99_ADLER_START; + low = 1; + high = 0; + for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) { + if ((cnt % 5000) == 0) { + high %= 65521UL; + high %= 65521UL; + } + low += buffer[cnt]; + high += low; + } + low %= 65521UL; + high %= 65521UL; + + return (high << 16) | low; +} + +static u32 core99_check(u8* datas) +{ + struct core99_header* hdr99 = (struct core99_header*)datas; + + if (hdr99->hdr.signature != CORE99_SIGNATURE) { + DBG("Invalid signature\n"); + return 0; + } + if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) { + DBG("Invalid checksum\n"); + return 0; + } + if (hdr99->adler != core99_calc_adler(datas)) { + DBG("Invalid adler\n"); + return 0; + } + return hdr99->generation; +} + +static int sm_erase_bank(int bank) +{ + int stat, i; + unsigned long timeout; + + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; + + DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); + + out_8(base, SM_FLASH_CMD_ERASE_SETUP); + out_8(base, SM_FLASH_CMD_ERASE_CONFIRM); + timeout = 0; + do { + if (++timeout > 1000000) { + printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n"); + break; + } + out_8(base, SM_FLASH_CMD_READ_STATUS); + stat = in_8(base); + } while (!(stat & SM_FLASH_STATUS_DONE)); + + out_8(base, SM_FLASH_CMD_CLEAR_STATUS); + out_8(base, SM_FLASH_CMD_RESET); + + for (i=0; i 1000000) { + printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n"); + break; + } + out_8(base, SM_FLASH_CMD_READ_STATUS); + stat = in_8(base); + } while (!(stat & SM_FLASH_STATUS_DONE)); + if (!(stat & SM_FLASH_STATUS_DONE)) + break; + } + out_8(base, SM_FLASH_CMD_CLEAR_STATUS); + out_8(base, SM_FLASH_CMD_RESET); + for (i=0; i 1000000) { + printk(KERN_ERR "nvram: AMD flash erase timeout !\n"); + break; + } + stat = in_8(base) ^ in_8(base); + } while (stat != 0); + + /* Reset */ + out_8(base, 0xf0); + udelay(1); + + for (i=0; i 1000000) { + printk(KERN_ERR "nvram: AMD flash write timeout !\n"); + break; + } + stat = in_8(base) ^ in_8(base); + } while (stat != 0); + if (stat != 0) + break; + } + + /* Reset */ + out_8(base, 0xf0); + udelay(1); + + for (i=0; iname, "common")) + nvram_partitions[pmac_nvram_OF] = offset + 0x10; + if (!strcmp(hdr->name, "APL,MacOS75")) { + nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10; + nvram_partitions[pmac_nvram_NR] = offset + 0x110; + } + offset += (hdr->len * 0x10); + } while(offset < NVRAM_SIZE); + } else { + nvram_partitions[pmac_nvram_OF] = 0x1800; + nvram_partitions[pmac_nvram_XPRAM] = 0x1300; + nvram_partitions[pmac_nvram_NR] = 0x1400; + } + DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]); + DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]); + DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]); +} + +static void core99_nvram_sync(void) +{ + struct core99_header* hdr99; + unsigned long flags; + + if (!is_core_99 || !nvram_data || !nvram_image) + return; + + spin_lock_irqsave(&nv_lock, flags); + if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE, + NVRAM_SIZE)) + goto bail; + + DBG("Updating nvram...\n"); + + hdr99 = (struct core99_header*)nvram_image; + hdr99->generation++; + hdr99->hdr.signature = CORE99_SIGNATURE; + hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr); + hdr99->adler = core99_calc_adler(nvram_image); + core99_bank = core99_bank ? 0 : 1; + if (core99_erase_bank) + if (core99_erase_bank(core99_bank)) { + printk("nvram: Error erasing bank %d\n", core99_bank); + goto bail; + } + if (core99_write_bank) + if (core99_write_bank(core99_bank, nvram_image)) + printk("nvram: Error writing bank %d\n", core99_bank); + bail: + spin_unlock_irqrestore(&nv_lock, flags); + +#ifdef DEBUG + mdelay(2000); +#endif +} + +void __init pmac_nvram_init(void) +{ + struct device_node *dp; + + nvram_naddrs = 0; + + dp = find_devices("nvram"); + if (dp == NULL) { + printk(KERN_ERR "Can't find NVRAM device\n"); + return; + } + nvram_naddrs = dp->n_addrs; + is_core_99 = device_is_compatible(dp, "nvram,flash"); + if (is_core_99) { + int i; + u32 gen_bank0, gen_bank1; + + if (nvram_naddrs < 1) { + printk(KERN_ERR "nvram: no address\n"); + return; + } + nvram_image = alloc_bootmem(NVRAM_SIZE); + if (nvram_image == NULL) { + printk(KERN_ERR "nvram: can't allocate ram image\n"); + return; + } + nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); + nvram_naddrs = 1; /* Make sure we get the correct case */ + + DBG("nvram: Checking bank 0...\n"); + + gen_bank0 = core99_check((u8 *)nvram_data); + gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); + core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; + + DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); + DBG("nvram: Active bank is: %d\n", core99_bank); + + for (i=0; iaddrs[0].address + isa_mem_base, + dp->addrs[0].size); + nvram_mult = 1; + ppc_md.nvram_read_val = direct_nvram_read_byte; + ppc_md.nvram_write_val = direct_nvram_write_byte; + } else if (nvram_naddrs == 1) { + nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size); + nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE; + ppc_md.nvram_read_val = direct_nvram_read_byte; + ppc_md.nvram_write_val = direct_nvram_write_byte; + } else if (nvram_naddrs == 2) { + nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size); + nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size); + ppc_md.nvram_read_val = indirect_nvram_read_byte; + ppc_md.nvram_write_val = indirect_nvram_write_byte; + } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { +#ifdef CONFIG_ADB_PMU + nvram_naddrs = -1; + ppc_md.nvram_read_val = pmu_nvram_read_byte; + ppc_md.nvram_write_val = pmu_nvram_write_byte; +#endif /* CONFIG_ADB_PMU */ + } else { + printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n", + nvram_naddrs); + } + lookup_partitions(); +} + +int pmac_get_partition(int partition) +{ + return nvram_partitions[partition]; +} + +u8 pmac_xpram_read(int xpaddr) +{ + int offset = nvram_partitions[pmac_nvram_XPRAM]; + + if (offset < 0) + return 0xff; + + return ppc_md.nvram_read_val(xpaddr + offset); +} + +void pmac_xpram_write(int xpaddr, u8 data) +{ + int offset = nvram_partitions[pmac_nvram_XPRAM]; + + if (offset < 0) + return; + + ppc_md.nvram_write_val(xpaddr + offset, data); +} + +EXPORT_SYMBOL(pmac_get_partition); +EXPORT_SYMBOL(pmac_xpram_read); +EXPORT_SYMBOL(pmac_xpram_write); diff --git a/arch/powerpc/platforms/powermac/pmac_pci.c b/arch/powerpc/platforms/powermac/pmac_pci.c new file mode 100644 index 000000000000..40bcd3e55afb --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_pci.c @@ -0,0 +1,1341 @@ +/* + * Support for PCI bridges found on Power Macintoshes. + * At present the "bandit" and "chaos" bridges are supported. + * Fortunately you access configuration space in the same + * way with either bridge. + * + * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) + * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static int add_bridge(struct device_node *dev); +extern void pmac_check_ht_link(void); + +/* XXX Could be per-controller, but I don't think we risk anything by + * assuming we won't have both UniNorth and Bandit */ +static int has_uninorth; +#ifdef CONFIG_POWER4 +static struct pci_controller *u3_agp; +#endif /* CONFIG_POWER4 */ + +extern u8 pci_cache_line_size; +extern int pcibios_assign_bus_offset; + +struct device_node *k2_skiplist[2]; + +/* + * Magic constants for enabling cache coherency in the bandit/PSX bridge. + */ +#define BANDIT_DEVID_2 8 +#define BANDIT_REVID 3 + +#define BANDIT_DEVNUM 11 +#define BANDIT_MAGIC 0x50 +#define BANDIT_COHERENT 0x40 + +static int __init fixup_one_level_bus_range(struct device_node *node, int higher) +{ + for (; node != 0;node = node->sibling) { + int * bus_range; + unsigned int *class_code; + int len; + + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", NULL); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range != NULL && len > 2 * sizeof(int)) { + if (bus_range[1] > higher) + higher = bus_range[1]; + } + higher = fixup_one_level_bus_range(node->child, higher); + } + return higher; +} + +/* This routine fixes the "bus-range" property of all bridges in the + * system since they tend to have their "last" member wrong on macs + * + * Note that the bus numbers manipulated here are OF bus numbers, they + * are not Linux bus numbers. + */ +static void __init fixup_bus_range(struct device_node *bridge) +{ + int * bus_range; + int len; + + /* Lookup the "bus-range" property for the hose */ + bus_range = (int *) get_property(bridge, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + bridge->full_name); + return; + } + bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); +} + +/* + * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers. + * + * The "Bandit" version is present in all early PCI PowerMacs, + * and up to the first ones using Grackle. Some machines may + * have 2 bandit controllers (2 PCI busses). + * + * "Chaos" is used in some "Bandit"-type machines as a bridge + * for the separate display bus. It is accessed the same + * way as bandit, but cannot be probed for devices. It therefore + * has its own config access functions. + * + * The "UniNorth" version is present in all Core99 machines + * (iBook, G4, new IMacs, and all the recent Apple machines). + * It contains 3 controllers in one ASIC. + * + * The U3 is the bridge used on G5 machines. It contains an + * AGP bus which is dealt with the old UniNorth access routines + * and a HyperTransport bus which uses its own set of access + * functions. + */ + +#define MACRISC_CFA0(devfn, off) \ + ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ + | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ + | (((unsigned long)(off)) & 0xFCUL)) + +#define MACRISC_CFA1(bus, devfn, off) \ + ((((unsigned long)(bus)) << 16) \ + |(((unsigned long)(devfn)) << 8) \ + |(((unsigned long)(off)) & 0xFCUL) \ + |1UL) + +static unsigned long macrisc_cfg_access(struct pci_controller* hose, + u8 bus, u8 dev_fn, u8 offset) +{ + unsigned int caddr; + + if (bus == hose->first_busno) { + if (dev_fn < (11 << 3)) + return 0; + caddr = MACRISC_CFA0(dev_fn, offset); + } else + caddr = MACRISC_CFA1(bus, dev_fn, offset); + + /* Uninorth will return garbage if we don't read back the value ! */ + do { + out_le32(hose->cfg_addr, caddr); + } while (in_le32(hose->cfg_addr) != caddr); + + offset &= has_uninorth ? 0x07 : 0x03; + return ((unsigned long)hose->cfg_data) + offset; +} + +static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr; + + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + *val = in_8((u8 *)addr); + break; + case 2: + *val = in_le16((u16 *)addr); + break; + default: + *val = in_le32((u32 *)addr); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr; + + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + out_8((u8 *)addr, val); + (void) in_8((u8 *)addr); + break; + case 2: + out_le16((u16 *)addr, val); + (void) in_le16((u16 *)addr); + break; + default: + out_le32((u32 *)addr, val); + (void) in_le32((u32 *)addr); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops macrisc_pci_ops = +{ + macrisc_read_config, + macrisc_write_config +}; + +/* + * Verifiy that a specific (bus, dev_fn) exists on chaos + */ +static int +chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) +{ + struct device_node *np; + u32 *vendor, *device; + + np = pci_busdev_to_OF_node(bus, devfn); + if (np == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + vendor = (u32 *)get_property(np, "vendor-id", NULL); + device = (u32 *)get_property(np, "device-id", NULL); + if (vendor == NULL || device == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) + && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + return PCIBIOS_SUCCESSFUL; +} + +static int +chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + int result = chaos_validate_dev(bus, devfn, offset); + if (result == PCIBIOS_BAD_REGISTER_NUMBER) + *val = ~0U; + if (result != PCIBIOS_SUCCESSFUL) + return result; + return macrisc_read_config(bus, devfn, offset, len, val); +} + +static int +chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + int result = chaos_validate_dev(bus, devfn, offset); + if (result != PCIBIOS_SUCCESSFUL) + return result; + return macrisc_write_config(bus, devfn, offset, len, val); +} + +static struct pci_ops chaos_pci_ops = +{ + chaos_read_config, + chaos_write_config +}; + +#ifdef CONFIG_POWER4 + +/* + * These versions of U3 HyperTransport config space access ops do not + * implement self-view of the HT host yet + */ + +/* + * This function deals with some "special cases" devices. + * + * 0 -> No special case + * 1 -> Skip the device but act as if the access was successfull + * (return 0xff's on reads, eventually, cache config space + * accesses in a later version) + * -1 -> Hide the device (unsuccessful acess) + */ +static int u3_ht_skip_device(struct pci_controller *hose, + struct pci_bus *bus, unsigned int devfn) +{ + struct device_node *busdn, *dn; + int i; + + /* We only allow config cycles to devices that are in OF device-tree + * as we are apparently having some weird things going on with some + * revs of K2 on recent G5s + */ + if (bus->self) + busdn = pci_device_to_OF_node(bus->self); + else + busdn = hose->arch_data; + for (dn = busdn->child; dn; dn = dn->sibling) + if (dn->data && PCI_DN(dn)->devfn == devfn) + break; + if (dn == NULL) + return -1; + + /* + * When a device in K2 is powered down, we die on config + * cycle accesses. Fix that here. + */ + for (i=0; i<2; i++) + if (k2_skiplist[i] == dn) + return 1; + + return 0; +} + +#define U3_HT_CFA0(devfn, off) \ + ((((unsigned long)devfn) << 8) | offset) +#define U3_HT_CFA1(bus, devfn, off) \ + (U3_HT_CFA0(devfn, off) \ + + (((unsigned long)bus) << 16) \ + + 0x01000000UL) + +static unsigned long u3_ht_cfg_access(struct pci_controller* hose, + u8 bus, u8 devfn, u8 offset) +{ + if (bus == hose->first_busno) { + /* For now, we don't self probe U3 HT bridge */ + if (PCI_SLOT(devfn) == 0) + return 0; + return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); + } else + return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); +} + +static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr; + + struct device_node *np = pci_busdev_to_OF_node(bus, devfn); + if (np == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch (u3_ht_skip_device(hose, bus, devfn)) { + case 0: + break; + case 1: + switch (len) { + case 1: + *val = 0xff; break; + case 2: + *val = 0xffff; break; + default: + *val = 0xfffffffful; break; + } + return PCIBIOS_SUCCESSFUL; + default: + return PCIBIOS_DEVICE_NOT_FOUND; + } + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + *val = in_8((u8 *)addr); + break; + case 2: + *val = in_le16((u16 *)addr); + break; + default: + *val = in_le32((u32 *)addr); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr; + + struct device_node *np = pci_busdev_to_OF_node(bus, devfn); + if (np == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch (u3_ht_skip_device(hose, bus, devfn)) { + case 0: + break; + case 1: + return PCIBIOS_SUCCESSFUL; + default: + return PCIBIOS_DEVICE_NOT_FOUND; + } + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + out_8((u8 *)addr, val); + (void) in_8((u8 *)addr); + break; + case 2: + out_le16((u16 *)addr, val); + (void) in_le16((u16 *)addr); + break; + default: + out_le32((u32 *)addr, val); + (void) in_le32((u32 *)addr); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops u3_ht_pci_ops = +{ + u3_ht_read_config, + u3_ht_write_config +}; + +#endif /* CONFIG_POWER4 */ + +/* + * For a bandit bridge, turn on cache coherency if necessary. + * N.B. we could clean this up using the hose ops directly. + */ +static void __init +init_bandit(struct pci_controller *bp) +{ + unsigned int vendev, magic; + int rev; + + /* read the word at offset 0 in config space for device 11 */ + out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID); + udelay(2); + vendev = in_le32(bp->cfg_data); + if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + + PCI_VENDOR_ID_APPLE) { + /* read the revision id */ + out_le32(bp->cfg_addr, + (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID); + udelay(2); + rev = in_8(bp->cfg_data); + if (rev != BANDIT_REVID) + printk(KERN_WARNING + "Unknown revision %d for bandit\n", rev); + } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) { + printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); + return; + } + + /* read the word at offset 0x50 */ + out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); + udelay(2); + magic = in_le32(bp->cfg_data); + if ((magic & BANDIT_COHERENT) != 0) + return; + magic |= BANDIT_COHERENT; + udelay(2); + out_le32(bp->cfg_data, magic); + printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n"); +} + + +/* + * Tweak the PCI-PCI bridge chip on the blue & white G3s. + */ +static void __init +init_p2pbridge(void) +{ + struct device_node *p2pbridge; + struct pci_controller* hose; + u8 bus, devfn; + u16 val; + + /* XXX it would be better here to identify the specific + PCI-PCI bridge chip we have. */ + if ((p2pbridge = find_devices("pci-bridge")) == 0 + || p2pbridge->parent == NULL + || strcmp(p2pbridge->parent->name, "pci") != 0) + return; + if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { + DBG("Can't find PCI infos for PCI<->PCI bridge\n"); + return; + } + /* Warning: At this point, we have not yet renumbered all busses. + * So we must use OF walking to find out hose + */ + hose = pci_find_hose_for_OF_device(p2pbridge); + if (!hose) { + DBG("Can't find hose for PCI<->PCI bridge\n"); + return; + } + if (early_read_config_word(hose, bus, devfn, + PCI_BRIDGE_CONTROL, &val) < 0) { + printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); + return; + } + val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; + early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); +} + +/* + * Some Apple desktop machines have a NEC PD720100A USB2 controller + * on the motherboard. Open Firmware, on these, will disable the + * EHCI part of it so it behaves like a pair of OHCI's. This fixup + * code re-enables it ;) + */ +static void __init +fixup_nec_usb2(void) +{ + struct device_node *nec; + + for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { + struct pci_controller *hose; + u32 data, *prop; + u8 bus, devfn; + + prop = (u32 *)get_property(nec, "vendor-id", NULL); + if (prop == NULL) + continue; + if (0x1033 != *prop) + continue; + prop = (u32 *)get_property(nec, "device-id", NULL); + if (prop == NULL) + continue; + if (0x0035 != *prop) + continue; + prop = (u32 *)get_property(nec, "reg", NULL); + if (prop == NULL) + continue; + devfn = (prop[0] >> 8) & 0xff; + bus = (prop[0] >> 16) & 0xff; + if (PCI_FUNC(devfn) != 0) + continue; + hose = pci_find_hose_for_OF_device(nec); + if (!hose) + continue; + early_read_config_dword(hose, bus, devfn, 0xe4, &data); + if (data & 1UL) { + printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n"); + data &= ~1UL; + early_write_config_dword(hose, bus, devfn, 0xe4, data); + early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, + nec->intrs[0].line); + } + } +} + +void __init +pmac_find_bridges(void) +{ + struct device_node *np, *root; + struct device_node *ht = NULL; + + root = of_find_node_by_path("/"); + if (root == NULL) { + printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); + return; + } + for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { + if (np->name == NULL) + continue; + if (strcmp(np->name, "bandit") == 0 + || strcmp(np->name, "chaos") == 0 + || strcmp(np->name, "pci") == 0) { + if (add_bridge(np) == 0) + of_node_get(np); + } + if (strcmp(np->name, "ht") == 0) { + of_node_get(np); + ht = np; + } + } + of_node_put(root); + + /* Probe HT last as it relies on the agp resources to be already + * setup + */ + if (ht && add_bridge(ht) != 0) + of_node_put(ht); + + init_p2pbridge(); + fixup_nec_usb2(); + + /* We are still having some issues with the Xserve G4, enabling + * some offset between bus number and domains for now when we + * assign all busses should help for now + */ + if (pci_assign_all_busses) + pcibios_assign_bus_offset = 0x10; + +#ifdef CONFIG_POWER4 + /* There is something wrong with DMA on U3/HT. I haven't figured out + * the details yet, but if I set the cache line size to 128 bytes like + * it should, I'm getting memory corruption caused by devices like + * sungem (even without the MWI bit set, but maybe sungem doesn't + * care). Right now, it appears that setting up a 64 bytes line size + * works properly, 64 bytes beeing the max transfer size of HT, I + * suppose this is related the way HT/PCI are hooked together. I still + * need to dive into more specs though to be really sure of what's + * going on. --BenH. + * + * Ok, apparently, it's just that HT can't do more than 64 bytes + * transactions. MWI seem to be meaningless there as well, it may + * be worth nop'ing out pci_set_mwi too though I haven't done that + * yet. + * + * Note that it's a bit different for whatever is in the AGP slot. + * For now, I don't care, but this can become a real issue, we + * should probably hook pci_set_mwi anyway to make sure it sets + * the real cache line size in there. + */ + if (machine_is_compatible("MacRISC4")) + pci_cache_line_size = 16; /* 64 bytes */ + + pmac_check_ht_link(); +#endif /* CONFIG_POWER4 */ +} + +#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ + | (((o) & ~3) << 24)) + +#define GRACKLE_PICR1_STG 0x00000040 +#define GRACKLE_PICR1_LOOPSNOOP 0x00000010 + +/* N.B. this is called before bridges is initialized, so we can't + use grackle_pcibios_{read,write}_config_dword. */ +static inline void grackle_set_stg(struct pci_controller* bp, int enable) +{ + unsigned int val; + + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + val = in_le32(bp->cfg_data); + val = enable? (val | GRACKLE_PICR1_STG) : + (val & ~GRACKLE_PICR1_STG); + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + out_le32(bp->cfg_data, val); + (void)in_le32(bp->cfg_data); +} + +static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) +{ + unsigned int val; + + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + val = in_le32(bp->cfg_data); + val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) : + (val & ~GRACKLE_PICR1_LOOPSNOOP); + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + out_le32(bp->cfg_data, val); + (void)in_le32(bp->cfg_data); +} + +static int __init +setup_uninorth(struct pci_controller* hose, struct reg_property* addr) +{ + pci_assign_all_busses = 1; + has_uninorth = 1; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + /* We "know" that the bridge at f2000000 has the PCI slots. */ + return addr->address == 0xf2000000; +} + +static void __init +setup_bandit(struct pci_controller* hose, struct reg_property* addr) +{ + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + init_bandit(hose); +} + +static void __init +setup_chaos(struct pci_controller* hose, struct reg_property* addr) +{ + /* assume a `chaos' bridge */ + hose->ops = &chaos_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); +} + +#ifdef CONFIG_POWER4 + +static void __init setup_u3_agp(struct pci_controller* hose) +{ + /* On G5, we move AGP up to high bus number so we don't need + * to reassign bus numbers for HT. If we ever have P2P bridges + * on AGP, we'll have to move pci_assign_all_busses to the + * pci_controller structure so we enable it for AGP and not for + * HT childs. + * We hard code the address because of the different size of + * the reg address cell, we shall fix that by killing struct + * reg_property and using some accessor functions instead + */ + hose->first_busno = 0xf0; + hose->last_busno = 0xff; + has_uninorth = 1; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); + hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); + + u3_agp = hose; +} + +static void __init setup_u3_ht(struct pci_controller* hose) +{ + struct device_node *np = (struct device_node *)hose->arch_data; + int i, cur; + + hose->ops = &u3_ht_pci_ops; + + /* We hard code the address because of the different size of + * the reg address cell, we shall fix that by killing struct + * reg_property and using some accessor functions instead + */ + hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); + + /* + * /ht node doesn't expose a "ranges" property, so we "remove" regions that + * have been allocated to AGP. So far, this version of the code doesn't assign + * any of the 0xfxxxxxxx "fine" memory regions to /ht. + * We need to fix that sooner or later by either parsing all child "ranges" + * properties or figuring out the U3 address space decoding logic and + * then read its configuration register (if any). + */ + hose->io_base_phys = 0xf4000000; + hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); + isa_io_base = (unsigned long) hose->io_base_virt; + hose->io_resource.name = np->full_name; + hose->io_resource.start = 0; + hose->io_resource.end = 0x003fffff; + hose->io_resource.flags = IORESOURCE_IO; + hose->pci_mem_offset = 0; + hose->first_busno = 0; + hose->last_busno = 0xef; + hose->mem_resources[0].name = np->full_name; + hose->mem_resources[0].start = 0x80000000; + hose->mem_resources[0].end = 0xefffffff; + hose->mem_resources[0].flags = IORESOURCE_MEM; + + if (u3_agp == NULL) { + DBG("U3 has no AGP, using full resource range\n"); + return; + } + + /* We "remove" the AGP resources from the resources allocated to HT, that + * is we create "holes". However, that code does assumptions that so far + * happen to be true (cross fingers...), typically that resources in the + * AGP node are properly ordered + */ + cur = 0; + for (i=0; i<3; i++) { + struct resource *res = &u3_agp->mem_resources[i]; + if (res->flags != IORESOURCE_MEM) + continue; + /* We don't care about "fine" resources */ + if (res->start >= 0xf0000000) + continue; + /* Check if it's just a matter of "shrinking" us in one direction */ + if (hose->mem_resources[cur].start == res->start) { + DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", + cur, hose->mem_resources[cur].start, res->end + 1); + hose->mem_resources[cur].start = res->end + 1; + continue; + } + if (hose->mem_resources[cur].end == res->end) { + DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", + cur, hose->mem_resources[cur].end, res->start - 1); + hose->mem_resources[cur].end = res->start - 1; + continue; + } + /* No, it's not the case, we need a hole */ + if (cur == 2) { + /* not enough resources to make a hole, we drop part of the range */ + printk(KERN_WARNING "Running out of resources for /ht host !\n"); + hose->mem_resources[cur].end = res->start - 1; + continue; + } + cur++; + DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", + cur-1, res->start - 1, cur, res->end + 1); + hose->mem_resources[cur].name = np->full_name; + hose->mem_resources[cur].flags = IORESOURCE_MEM; + hose->mem_resources[cur].start = res->end + 1; + hose->mem_resources[cur].end = hose->mem_resources[cur-1].end; + hose->mem_resources[cur-1].end = res->start - 1; + } +} + +#endif /* CONFIG_POWER4 */ + +void __init +setup_grackle(struct pci_controller *hose) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif +} + +static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary) +{ + static unsigned int static_lc_ranges[2024]; + unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; + unsigned int size; + int rlen = 0, orig_rlen; + int memno = 0; + struct resource *res; + int np, na = prom_n_addr_cells(dev); + + np = na + 5; + + /* First we try to merge ranges to fix a problem with some pmacs + * that can have more than 3 ranges, fortunately using contiguous + * addresses -- BenH + */ + dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + if (!dt_ranges) + return; + /* lc_ranges = alloc_bootmem(rlen);*/ + lc_ranges = static_lc_ranges; + if (!lc_ranges) + return; /* what can we do here ? */ + memcpy(lc_ranges, dt_ranges, rlen); + orig_rlen = rlen; + + /* Let's work on a copy of the "ranges" property instead of damaging + * the device-tree image in memory + */ + ranges = lc_ranges; + prev = NULL; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if (prev) { + if (prev[0] == ranges[0] && prev[1] == ranges[1] && + (prev[2] + prev[na+4]) == ranges[2] && + (prev[na+2] + prev[na+4]) == ranges[na+2]) { + prev[na+4] += ranges[na+4]; + ranges[0] = 0; + ranges += np; + continue; + } + } + prev = ranges; + ranges += np; + } + + /* + * The ranges property is laid out as an array of elements, + * each of which comprises: + * cells 0 - 2: a PCI address + * cells 3 or 3+4: a CPU physical address + * (size depending on dev->n_addr_cells) + * cells 4+5 or 5+6: the size of the range + */ + ranges = lc_ranges; + rlen = orig_rlen; + while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { + res = NULL; + size = ranges[na+4]; + switch (ranges[0] >> 24) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[na+2]; + /* limit I/O space to 16MB */ + if (size > 0x01000000) + size = 0x01000000; + hose->io_base_virt = ioremap(ranges[na+2], size); + if (primary) + isa_io_base = (unsigned long) hose->io_base_virt; + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + res->start = ranges[2]; + break; + case 2: /* memory space */ + memno = 0; + if (ranges[1] == 0 && ranges[2] == 0 + && ranges[na+4] <= (16 << 20)) { + /* 1st 16MB, i.e. ISA memory area */ +#if 0 + if (primary) + isa_mem_base = ranges[na+2]; +#endif + memno = 1; + } + while (memno < 3 && hose->mem_resources[memno].flags) + ++memno; + if (memno == 0) + hose->pci_mem_offset = ranges[na+2] - ranges[2]; + if (memno < 3) { + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + res->start = ranges[na+2]; + } + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->end = res->start + size - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += np; + } +} + +/* + * We assume that if we have a G3 powermac, we have one bridge called + * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, + * if we have one or more bandit or chaos bridges, we don't have a MPC106. + */ +static int __init add_bridge(struct device_node *dev) +{ + int len; + struct pci_controller *hose; + struct reg_property *addr; + char* disp_name; + int *bus_range; + int primary = 1; + + DBG("Adding PCI host bridge %s\n", dev->full_name); + + addr = (struct reg_property *) get_property(dev, "reg", &len); + if (addr == NULL || len < sizeof(*addr)) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + return -ENODEV; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", + dev->full_name); + } + + hose = pcibios_alloc_controller(); + if (!hose) + return -ENOMEM; + hose->arch_data = dev; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + disp_name = NULL; +#ifdef CONFIG_POWER4 + if (device_is_compatible(dev, "u3-agp")) { + setup_u3_agp(hose, addr); + disp_name = "U3-AGP"; + primary = 0; + } else if (device_is_compatible(dev, "u3-ht")) { + setup_u3_ht(hose, addr); + disp_name = "U3-HT"; + primary = 1; + } else +#endif /* CONFIG_POWER4 */ + if (device_is_compatible(dev, "uni-north")) { + primary = setup_uninorth(hose, addr); + disp_name = "UniNorth"; + } else if (strcmp(dev->name, "pci") == 0) { + /* XXX assume this is a mpc106 (grackle) */ + setup_grackle(hose); + disp_name = "Grackle (MPC106)"; + } else if (strcmp(dev->name, "bandit") == 0) { + setup_bandit(hose, addr); + disp_name = "Bandit"; + } else if (strcmp(dev->name, "chaos") == 0) { + setup_chaos(hose, addr); + disp_name = "Chaos"; + primary = 0; + } + printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); + DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", + hose, hose->cfg_addr, hose->cfg_data); + + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, primary); + + /* Fixup "bus-range" OF property */ + fixup_bus_range(dev); + + return 0; +} + +static void __init +pcibios_fixup_OF_interrupts(void) +{ + struct pci_dev* dev = NULL; + + /* + * Open Firmware often doesn't initialize the + * PCI_INTERRUPT_LINE config register properly, so we + * should find the device node and apply the interrupt + * obtained from the OF device-tree + */ + for_each_pci_dev(dev) { + struct device_node *node; + node = pci_device_to_OF_node(dev); + /* this is the node, see if it has interrupts */ + if (node && node->n_intrs > 0) + dev->irq = node->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +void __init +pmac_pcibios_fixup(void) +{ + /* Fixup interrupts according to OF tree */ + pcibios_fixup_OF_interrupts(); +} + +int +pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) +{ + struct device_node* node; + int updatecfg = 0; + int uninorth_child; + + node = pci_device_to_OF_node(dev); + + /* We don't want to enable USB controllers absent from the OF tree + * (iBook second controller) + */ + if (dev->vendor == PCI_VENDOR_ID_APPLE + && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) + && !node) { + printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n", + pci_name(dev)); + return -EINVAL; + } + + if (!node) + return 0; + + uninorth_child = node->parent && + device_is_compatible(node->parent, "uni-north"); + + /* Firewire & GMAC were disabled after PCI probe, the driver is + * claiming them, we must re-enable them now. + */ + if (uninorth_child && !strcmp(node->name, "firewire") && + (device_is_compatible(node, "pci106b,18") || + device_is_compatible(node, "pci106b,30") || + device_is_compatible(node, "pci11c1,5811"))) { + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); + pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); + updatecfg = 1; + } + if (uninorth_child && !strcmp(node->name, "ethernet") && + device_is_compatible(node, "gmac")) { + pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); + updatecfg = 1; + } + + if (updatecfg) { + u16 cmd; + + /* + * Make sure PCI is correctly configured + * + * We use old pci_bios versions of the function since, by + * default, gmac is not powered up, and so will be absent + * from the kernel initial PCI lookup. + * + * Should be replaced by 2.4 new PCI mechanisms and really + * register the device. + */ + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size); + } + + return 0; +} + +/* We power down some devices after they have been probed. They'll + * be powered back on later on + */ +void __init +pmac_pcibios_after_init(void) +{ + struct device_node* nd; + +#ifdef CONFIG_BLK_DEV_IDE + struct pci_dev *dev = NULL; + + /* OF fails to initialize IDE controllers on macs + * (and maybe other machines) + * + * Ideally, this should be moved to the IDE layer, but we need + * to check specifically with Andre Hedrick how to do it cleanly + * since the common IDE code seem to care about the fact that the + * BIOS may have disabled a controller. + * + * -- BenH + */ + for_each_pci_dev(dev) { + if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) + pci_enable_device(dev); + } +#endif /* CONFIG_BLK_DEV_IDE */ + + nd = find_devices("firewire"); + while (nd) { + if (nd->parent && (device_is_compatible(nd, "pci106b,18") || + device_is_compatible(nd, "pci106b,30") || + device_is_compatible(nd, "pci11c1,5811")) + && device_is_compatible(nd->parent, "uni-north")) { + pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0); + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); + } + nd = nd->next; + } + nd = find_devices("ethernet"); + while (nd) { + if (nd->parent && device_is_compatible(nd, "gmac") + && device_is_compatible(nd->parent, "uni-north")) + pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); + nd = nd->next; + } +} + +#ifdef CONFIG_PPC64 +static void __init pmac_fixup_phb_resources(void) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; + hose->io_resource.start += offset; + hose->io_resource.end += offset; + printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + hose->global_number, + hose->io_resource.start, hose->io_resource.end); + } +} + +void __init pmac_pci_init(void) +{ + struct device_node *np, *root; + struct device_node *ht = NULL; + + /* Probe root PCI hosts, that is on U3 the AGP host and the + * HyperTransport host. That one is actually "kept" around + * and actually added last as it's resource management relies + * on the AGP resources to have been setup first + */ + root = of_find_node_by_path("/"); + if (root == NULL) { + printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); + return; + } + for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { + if (np->name == NULL) + continue; + if (strcmp(np->name, "pci") == 0) { + if (add_bridge(np) == 0) + of_node_get(np); + } + if (strcmp(np->name, "ht") == 0) { + of_node_get(np); + ht = np; + } + } + of_node_put(root); + + /* Now setup the HyperTransport host if we found any + */ + if (ht && add_bridge(ht) != 0) + of_node_put(ht); + + /* Fixup the IO resources on our host bridges as the common code + * does it only for childs of the host bridges + */ + pmac_fixup_phb_resources(); + + /* Setup the linkage between OF nodes and PHBs */ + pci_devs_phb_init(); + + /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We + * assume there is no P2P bridge on the AGP bus, which should be a + * safe assumptions hopefully. + */ + if (u3_agp) { + struct device_node *np = u3_agp->arch_data; + PCI_DN(np)->busno = 0xf0; + for (np = np->child; np; np = np->sibling) + PCI_DN(np)->busno = 0xf0; + } + + pmac_check_ht_link(); + + /* Tell pci.c to not use the common resource allocation mecanism */ + pci_probe_only = 1; + + /* Allow all IO */ + io_page_mask = -1; +} +#endif + +#ifdef CONFIG_PPC32 +void pmac_pci_fixup_cardbus(struct pci_dev* dev) +{ + if (_machine != _MACH_Pmac) + return; + /* + * Fix the interrupt routing on the various cardbus bridges + * used on powerbooks + */ + if (dev->vendor != PCI_VENDOR_ID_TI) + return; + if (dev->device == PCI_DEVICE_ID_TI_1130 || + dev->device == PCI_DEVICE_ID_TI_1131) { + u8 val; + /* Enable PCI interrupt */ + if (pci_read_config_byte(dev, 0x91, &val) == 0) + pci_write_config_byte(dev, 0x91, val | 0x30); + /* Disable ISA interrupt mode */ + if (pci_read_config_byte(dev, 0x92, &val) == 0) + pci_write_config_byte(dev, 0x92, val & ~0x06); + } + if (dev->device == PCI_DEVICE_ID_TI_1210 || + dev->device == PCI_DEVICE_ID_TI_1211 || + dev->device == PCI_DEVICE_ID_TI_1410 || + dev->device == PCI_DEVICE_ID_TI_1510) { + u8 val; + /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA + signal out the MFUNC0 pin */ + if (pci_read_config_byte(dev, 0x8c, &val) == 0) + pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2); + /* Disable ISA interrupt mode */ + if (pci_read_config_byte(dev, 0x92, &val) == 0) + pci_write_config_byte(dev, 0x92, val & ~0x06); + } +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus); + +void pmac_pci_fixup_pciata(struct pci_dev* dev) +{ + u8 progif = 0; + + /* + * On PowerMacs, we try to switch any PCI ATA controller to + * fully native mode + */ + if (_machine != _MACH_Pmac) + return; + /* Some controllers don't have the class IDE */ + if (dev->vendor == PCI_VENDOR_ID_PROMISE) + switch(dev->device) { + case PCI_DEVICE_ID_PROMISE_20246: + case PCI_DEVICE_ID_PROMISE_20262: + case PCI_DEVICE_ID_PROMISE_20263: + case PCI_DEVICE_ID_PROMISE_20265: + case PCI_DEVICE_ID_PROMISE_20267: + case PCI_DEVICE_ID_PROMISE_20268: + case PCI_DEVICE_ID_PROMISE_20269: + case PCI_DEVICE_ID_PROMISE_20270: + case PCI_DEVICE_ID_PROMISE_20271: + case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20276: + case PCI_DEVICE_ID_PROMISE_20277: + goto good; + } + /* Others, check PCI class */ + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + good: + pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); + if ((progif & 5) != 5) { + printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev)); + (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); + if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || + (progif & 5) != 5) + printk(KERN_ERR "Rewrite of PROGIF failed !\n"); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); +#endif + +/* + * Disable second function on K2-SATA, it's broken + * and disable IO BARs on first one + */ +static void fixup_k2_sata(struct pci_dev* dev) +{ + int i; + u16 cmd; + + if (PCI_FUNC(dev->devfn) > 0) { + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, cmd); + for (i = 0; i < 6; i++) { + dev->resource[i].start = dev->resource[i].end = 0; + dev->resource[i].flags = 0; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); + } + } else { + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~PCI_COMMAND_IO; + pci_write_config_word(dev, PCI_COMMAND, cmd); + for (i = 0; i < 5; i++) { + dev->resource[i].start = dev->resource[i].end = 0; + dev->resource[i].flags = 0; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata); + diff --git a/arch/powerpc/platforms/powermac/pmac_pic.c b/arch/powerpc/platforms/powermac/pmac_pic.c new file mode 100644 index 000000000000..bf3e1899a4cc --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_pic.c @@ -0,0 +1,655 @@ +/* + * Support for the interrupt controllers found on Power Macintosh, + * currently Apple's "Grand Central" interrupt controller in all + * it's incarnations. OpenPIC support used on newer machines is + * in a separate file + * + * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) + * + * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pmac_pic.h" + +/* + * XXX this should be in xmon.h, but putting it there means xmon.h + * has to include (to get irqreturn_t), which + * causes all sorts of problems. -- paulus + */ +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); + +struct pmac_irq_hw { + unsigned int event; + unsigned int enable; + unsigned int ack; + unsigned int level; +}; + +/* Default addresses */ +static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { + (struct pmac_irq_hw *) 0xf3000020, + (struct pmac_irq_hw *) 0xf3000010, + (struct pmac_irq_hw *) 0xf4000020, + (struct pmac_irq_hw *) 0xf4000010, +}; + +#define GC_LEVEL_MASK 0x3ff00000 +#define OHARE_LEVEL_MASK 0x1ff00000 +#define HEATHROW_LEVEL_MASK 0x1ff00000 + +static int max_irqs; +static int max_real_irqs; +static u32 level_mask[4]; + +static DEFINE_SPINLOCK(pmac_pic_lock); + + +#define GATWICK_IRQ_POOL_SIZE 10 +static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; + +/* + * Mark an irq as "lost". This is only used on the pmac + * since it can lose interrupts (see pmac_set_irq_mask). + * -- Cort + */ +void +__set_lost(unsigned long irq_nr, int nokick) +{ + if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { + atomic_inc(&ppc_n_lost_interrupts); + if (!nokick) + set_dec(1); + } +} + +static void +pmac_mask_and_ack_irq(unsigned int irq_nr) +{ + unsigned long bit = 1UL << (irq_nr & 0x1f); + int i = irq_nr >> 5; + unsigned long flags; + + if ((unsigned)irq_nr >= max_irqs) + return; + + clear_bit(irq_nr, ppc_cached_irq_mask); + if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) + atomic_dec(&ppc_n_lost_interrupts); + spin_lock_irqsave(&pmac_pic_lock, flags); + out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); + out_le32(&pmac_irq_hw[i]->ack, bit); + do { + /* make sure ack gets to controller before we enable + interrupts */ + mb(); + } while((in_le32(&pmac_irq_hw[i]->enable) & bit) + != (ppc_cached_irq_mask[i] & bit)); + spin_unlock_irqrestore(&pmac_pic_lock, flags); +} + +static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) +{ + unsigned long bit = 1UL << (irq_nr & 0x1f); + int i = irq_nr >> 5; + unsigned long flags; + + if ((unsigned)irq_nr >= max_irqs) + return; + + spin_lock_irqsave(&pmac_pic_lock, flags); + /* enable unmasked interrupts */ + out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); + + do { + /* make sure mask gets to controller before we + return to user */ + mb(); + } while((in_le32(&pmac_irq_hw[i]->enable) & bit) + != (ppc_cached_irq_mask[i] & bit)); + + /* + * Unfortunately, setting the bit in the enable register + * when the device interrupt is already on *doesn't* set + * the bit in the flag register or request another interrupt. + */ + if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level)) + __set_lost((ulong)irq_nr, nokicklost); + spin_unlock_irqrestore(&pmac_pic_lock, flags); +} + +/* When an irq gets requested for the first client, if it's an + * edge interrupt, we clear any previous one on the controller + */ +static unsigned int pmac_startup_irq(unsigned int irq_nr) +{ + unsigned long bit = 1UL << (irq_nr & 0x1f); + int i = irq_nr >> 5; + + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + out_le32(&pmac_irq_hw[i]->ack, bit); + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr, 0); + + return 0; +} + +static void pmac_mask_irq(unsigned int irq_nr) +{ + clear_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr, 0); + mb(); +} + +static void pmac_unmask_irq(unsigned int irq_nr) +{ + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr, 0); +} + +static void pmac_end_irq(unsigned int irq_nr) +{ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) + && irq_desc[irq_nr].action) { + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr, 1); + } +} + + +struct hw_interrupt_type pmac_pic = { + .typename = " PMAC-PIC ", + .startup = pmac_startup_irq, + .enable = pmac_unmask_irq, + .disable = pmac_mask_irq, + .ack = pmac_mask_and_ack_irq, + .end = pmac_end_irq, +}; + +struct hw_interrupt_type gatwick_pic = { + .typename = " GATWICK ", + .startup = pmac_startup_irq, + .enable = pmac_unmask_irq, + .disable = pmac_mask_irq, + .ack = pmac_mask_and_ack_irq, + .end = pmac_end_irq, +}; + +static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + int irq, bits; + + for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { + int i = irq >> 5; + bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; + /* We must read level interrupts from the level register */ + bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits &= ppc_cached_irq_mask[i]; + if (bits == 0) + continue; + irq += __ilog2(bits); + __do_IRQ(irq, regs); + return IRQ_HANDLED; + } + printk("gatwick irq not from gatwick pic\n"); + return IRQ_NONE; +} + +int +pmac_get_irq(struct pt_regs *regs) +{ + int irq; + unsigned long bits = 0; + +#ifdef CONFIG_SMP + void psurge_smp_message_recv(struct pt_regs *); + + /* IPI's are a hack on the powersurge -- Cort */ + if ( smp_processor_id() != 0 ) { + psurge_smp_message_recv(regs); + return -2; /* ignore, already handled */ + } +#endif /* CONFIG_SMP */ + for (irq = max_real_irqs; (irq -= 32) >= 0; ) { + int i = irq >> 5; + bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; + /* We must read level interrupts from the level register */ + bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits &= ppc_cached_irq_mask[i]; + if (bits == 0) + continue; + irq += __ilog2(bits); + break; + } + + return irq; +} + +/* This routine will fix some missing interrupt values in the device tree + * on the gatwick mac-io controller used by some PowerBooks + */ +static void __init +pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) +{ + struct device_node *node; + int count; + + memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); + node = gw->child; + count = 0; + while(node) + { + /* Fix SCC */ + if (strcasecmp(node->name, "escc") == 0) + if (node->child) { + if (node->child->n_intrs < 3) { + node->child->intrs = &gatwick_int_pool[count]; + count += 3; + } + node->child->n_intrs = 3; + node->child->intrs[0].line = 15+irq_base; + node->child->intrs[1].line = 4+irq_base; + node->child->intrs[2].line = 5+irq_base; + printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n", + node->child->intrs[0].line, + node->child->intrs[1].line, + node->child->intrs[2].line); + } + /* Fix media-bay & left SWIM */ + if (strcasecmp(node->name, "media-bay") == 0) { + struct device_node* ya_node; + + if (node->n_intrs == 0) + node->intrs = &gatwick_int_pool[count++]; + node->n_intrs = 1; + node->intrs[0].line = 29+irq_base; + printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", + node->intrs[0].line); + + ya_node = node->child; + while(ya_node) + { + if (strcasecmp(ya_node->name, "floppy") == 0) { + if (ya_node->n_intrs < 2) { + ya_node->intrs = &gatwick_int_pool[count]; + count += 2; + } + ya_node->n_intrs = 2; + ya_node->intrs[0].line = 19+irq_base; + ya_node->intrs[1].line = 1+irq_base; + printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n", + ya_node->intrs[0].line, ya_node->intrs[1].line); + } + if (strcasecmp(ya_node->name, "ata4") == 0) { + if (ya_node->n_intrs < 2) { + ya_node->intrs = &gatwick_int_pool[count]; + count += 2; + } + ya_node->n_intrs = 2; + ya_node->intrs[0].line = 14+irq_base; + ya_node->intrs[1].line = 3+irq_base; + printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n", + ya_node->intrs[0].line, ya_node->intrs[1].line); + } + ya_node = ya_node->sibling; + } + } + node = node->sibling; + } + if (count > 10) { + printk("WARNING !! Gatwick interrupt pool overflow\n"); + printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE); + printk(" requested = %d\n", count); + } +} + +/* + * The PowerBook 3400/2400/3500 can have a combo ethernet/modem + * card which includes an ohare chip that acts as a second interrupt + * controller. If we find this second ohare, set it up and fix the + * interrupt value in the device tree for the ethernet chip. + */ +static int __init enable_second_ohare(void) +{ + unsigned char bus, devfn; + unsigned short cmd; + unsigned long addr; + struct device_node *irqctrler = find_devices("pci106b,7"); + struct device_node *ether; + + if (irqctrler == NULL || irqctrler->n_addrs <= 0) + return -1; + addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); + pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); + max_irqs = 64; + if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { + struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); + if (!hose) + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + else { + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); + } + } + + /* Fix interrupt for the modem/ethernet combo controller. The number + in the device tree (27) is bogus (correct for the ethernet-only + board but not the combo ethernet/modem board). + The real interrupt is 28 on the second controller -> 28+32 = 60. + */ + ether = find_devices("pci1011,14"); + if (ether && ether->n_intrs > 0) { + ether->intrs[0].line = 60; + printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", + ether->intrs[0].line); + } + + /* Return the interrupt number of the cascade */ + return irqctrler->intrs[0].line; +} + +static int pmac_u3_cascade(struct pt_regs *regs, void *data) +{ + return mpic_get_one_irq((struct mpic *)data, regs); +} + +#ifdef CONFIG_XMON +static struct irqaction xmon_action = { + .handler = xmon_irq, + .flags = 0, + .mask = CPU_MASK_NONE, + .name = "NMI - XMON" +}; +#endif + +static struct irqaction gatwick_cascade_action = { + .handler = gatwick_action, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, + .name = "cascade", +}; + +void __init pmac_pic_init(void) +{ + int i; + struct device_node *irqctrler = NULL; + struct device_node *irqctrler2 = NULL; + struct device_node *np; + unsigned long addr; + int irq_cascade = -1; + struct mpic *mpic1, *mpic2; + + /* We first try to detect Apple's new Core99 chipset, since mac-io + * is quite different on those machines and contains an IBM MPIC2. + */ + np = find_type_devices("open-pic"); + while (np) { + if (np->parent && !strcmp(np->parent->name, "u3")) + irqctrler2 = np; + else + irqctrler = np; + np = np->next; + } + if (irqctrler != NULL && irqctrler->n_addrs > 0) { + unsigned char senses[128]; + + printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", + (unsigned int)irqctrler->addrs[0].address); + + prom_get_irq_senses(senses, 0, 128); + mpic1 = mpic_alloc(irqctrler->addrs[0].address, + MPIC_PRIMARY | MPIC_WANTS_RESET, + 0, 0, 128, 256, senses, 128, " K2-MPIC "); + BUG_ON(mpic1 == NULL); + mpic_init(mpic1); + + if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && + irqctrler2->n_addrs > 0) { + printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", + (u32)irqctrler2->addrs[0].address, + irqctrler2->intrs[0].line); + + pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); + prom_get_irq_senses(senses, 128, 128 + 128); + + /* We don't need to set MPIC_BROKEN_U3 here since we don't have + * hypertransport interrupts routed to it + */ + mpic2 = mpic_alloc(irqctrler2->addrs[0].address, + MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, + 0, 128, 128, 0, senses, 128, " U3-MPIC "); + BUG_ON(mpic2 == NULL); + mpic_init(mpic2); + mpic_setup_cascade(irqctrler2->intrs[0].line, + pmac_u3_cascade, mpic2); + } + } + + /* Get the level/edge settings, assume if it's not + * a Grand Central nor an OHare, then it's an Heathrow + * (or Paddington). + */ + if (find_devices("gc")) + level_mask[0] = GC_LEVEL_MASK; + else if (find_devices("ohare")) { + level_mask[0] = OHARE_LEVEL_MASK; + /* We might have a second cascaded ohare */ + level_mask[1] = OHARE_LEVEL_MASK; + } else { + level_mask[0] = HEATHROW_LEVEL_MASK; + level_mask[1] = 0; + /* We might have a second cascaded heathrow */ + level_mask[2] = HEATHROW_LEVEL_MASK; + level_mask[3] = 0; + } + + /* + * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, + * 1998 G3 Series PowerBooks have 128, + * other powermacs have 32. + * The combo ethernet/modem card for the Powerstar powerbooks + * (2400/3400/3500, ohare based) has a second ohare chip + * effectively making a total of 64. + */ + max_irqs = max_real_irqs = 32; + irqctrler = find_devices("mac-io"); + if (irqctrler) + { + max_real_irqs = 64; + if (irqctrler->next) + max_irqs = 128; + else + max_irqs = 64; + } + for ( i = 0; i < max_real_irqs ; i++ ) + irq_desc[i].handler = &pmac_pic; + + /* get addresses of first controller */ + if (irqctrler) { + if (irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 0; i < 2; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (2 - i) * 0x10); + } + + /* get addresses of second controller */ + irqctrler = irqctrler->next; + if (irqctrler && irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 2; i < 4; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (4 - i) * 0x10); + irq_cascade = irqctrler->intrs[0].line; + if (device_is_compatible(irqctrler, "gatwick")) + pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); + } + } else { + /* older powermacs have a GC (grand central) or ohare at + f3000000, with interrupt control registers at f3000020. */ + addr = (unsigned long) ioremap(0xf3000000, 0x40); + pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); + } + + /* PowerBooks 3400 and 3500 can have a second controller in a second + ohare chip, on the combo ethernet/modem card */ + if (machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500")) + irq_cascade = enable_second_ohare(); + + /* disable all interrupts in all controllers */ + for (i = 0; i * 32 < max_irqs; ++i) + out_le32(&pmac_irq_hw[i]->enable, 0); + /* mark level interrupts */ + for (i = 0; i < max_irqs; i++) + if (level_mask[i >> 5] & (1UL << (i & 0x1f))) + irq_desc[i].status = IRQ_LEVEL; + + /* get interrupt line of secondary interrupt controller */ + if (irq_cascade >= 0) { + printk(KERN_INFO "irq: secondary controller on irq %d\n", + (int)irq_cascade); + for ( i = max_real_irqs ; i < max_irqs ; i++ ) + irq_desc[i].handler = &gatwick_pic; + setup_irq(irq_cascade, &gatwick_cascade_action); + } + printk("System has %d possible interrupts\n", max_irqs); + if (max_irqs != max_real_irqs) + printk(KERN_DEBUG "%d interrupts on main controller\n", + max_real_irqs); + +#ifdef CONFIG_XMON + setup_irq(20, &xmon_action); +#endif /* CONFIG_XMON */ +} + +#ifdef CONFIG_PM +/* + * These procedures are used in implementing sleep on the powerbooks. + * sleep_save_intrs() saves the states of all interrupt enables + * and disables all interrupts except for the nominated one. + * sleep_restore_intrs() restores the states of all interrupt enables. + */ +unsigned long sleep_save_mask[2]; + +/* This used to be passed by the PMU driver but that link got + * broken with the new driver model. We use this tweak for now... + */ +static int pmacpic_find_viaint(void) +{ + int viaint = -1; + +#ifdef CONFIG_ADB_PMU + struct device_node *np; + + if (pmu_get_model() != PMU_OHARE_BASED) + goto not_found; + np = of_find_node_by_name(NULL, "via-pmu"); + if (np == NULL) + goto not_found; + viaint = np->intrs[0].line; +#endif /* CONFIG_ADB_PMU */ + +not_found: + return viaint; +} + +static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state) +{ + int viaint = pmacpic_find_viaint(); + + sleep_save_mask[0] = ppc_cached_irq_mask[0]; + sleep_save_mask[1] = ppc_cached_irq_mask[1]; + ppc_cached_irq_mask[0] = 0; + ppc_cached_irq_mask[1] = 0; + if (viaint > 0) + set_bit(viaint, ppc_cached_irq_mask); + out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]); + if (max_real_irqs > 32) + out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]); + (void)in_le32(&pmac_irq_hw[0]->event); + /* make sure mask gets to controller before we return to caller */ + mb(); + (void)in_le32(&pmac_irq_hw[0]->enable); + + return 0; +} + +static int pmacpic_resume(struct sys_device *sysdev) +{ + int i; + + out_le32(&pmac_irq_hw[0]->enable, 0); + if (max_real_irqs > 32) + out_le32(&pmac_irq_hw[1]->enable, 0); + mb(); + for (i = 0; i < max_real_irqs; ++i) + if (test_bit(i, sleep_save_mask)) + pmac_unmask_irq(i); + + return 0; +} + +#endif /* CONFIG_PM */ + +static struct sysdev_class pmacpic_sysclass = { + set_kset_name("pmac_pic"), +}; + +static struct sys_device device_pmacpic = { + .id = 0, + .cls = &pmacpic_sysclass, +}; + +static struct sysdev_driver driver_pmacpic = { +#ifdef CONFIG_PM + .suspend = &pmacpic_suspend, + .resume = &pmacpic_resume, +#endif /* CONFIG_PM */ +}; + +static int __init init_pmacpic_sysfs(void) +{ + if (max_irqs == 0) + return -ENODEV; + + printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); + sysdev_class_register(&pmacpic_sysclass); + sysdev_register(&device_pmacpic); + sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic); + return 0; +} + +subsys_initcall(init_pmacpic_sysfs); + diff --git a/arch/powerpc/platforms/powermac/pmac_pic.h b/arch/powerpc/platforms/powermac/pmac_pic.h new file mode 100644 index 000000000000..664103dfeef9 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_pic.h @@ -0,0 +1,11 @@ +#ifndef __PPC_PLATFORMS_PMAC_PIC_H +#define __PPC_PLATFORMS_PMAC_PIC_H + +#include + +extern struct hw_interrupt_type pmac_pic; + +void pmac_pic_init(void); +int pmac_get_irq(struct pt_regs *regs); + +#endif /* __PPC_PLATFORMS_PMAC_PIC_H */ diff --git a/arch/powerpc/platforms/powermac/pmac_setup.c b/arch/powerpc/platforms/powermac/pmac_setup.c new file mode 100644 index 000000000000..dbc921a084cd --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_setup.c @@ -0,0 +1,662 @@ +/* + * arch/ppc/platforms/setup.c + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Adapted for Power Macintosh by Paul Mackerras + * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * + * Derived from "arch/alpha/kernel/setup.c" + * Copyright (C) 1995 Linus Torvalds + * + * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) + * + * 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. + * + */ + +/* + * bootup setup stuff.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pmac_pic.h" + +#undef SHOW_GATWICK_IRQS + +extern long pmac_time_init(void); +extern unsigned long pmac_get_rtc_time(void); +extern int pmac_set_rtc_time(unsigned long nowtime); +extern void pmac_read_rtc_time(void); +extern void pmac_calibrate_decr(void); +extern void pmac_pcibios_fixup(void); +extern void pmac_find_bridges(void); +extern unsigned long pmac_ide_get_base(int index); +extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, + unsigned long data_port, unsigned long ctrl_port, int *irq); + +extern void pmac_nvram_update(void); +extern unsigned char pmac_nvram_read_byte(int addr); +extern void pmac_nvram_write_byte(int addr, unsigned char val); +extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); +extern void pmac_pcibios_after_init(void); +extern int of_show_percpuinfo(struct seq_file *m, int i); + +unsigned char drive_info; + +int ppc_override_l2cr = 0; +int ppc_override_l2cr_value; +int has_l2cache = 0; + +static int current_root_goodness = -1; + +extern int pmac_newworld; + +#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ + +extern void zs_kgdb_hook(int tty_num); +static void ohare_init(void); +#ifdef CONFIG_BOOTX_TEXT +static void pmac_progress(char *s, unsigned short hex); +#endif + +sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; + +#ifdef CONFIG_SMP +extern struct smp_ops_t psurge_smp_ops; +extern struct smp_ops_t core99_smp_ops; +#endif /* CONFIG_SMP */ + +static int +pmac_show_cpuinfo(struct seq_file *m) +{ + struct device_node *np; + char *pp; + int plen; + int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, + NULL, PMAC_MB_INFO_MODEL, 0); + unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO, + NULL, PMAC_MB_INFO_FLAGS, 0); + char* mbname; + + if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) + mbname = "Unknown"; + + /* find motherboard type */ + seq_printf(m, "machine\t\t: "); + np = find_devices("device-tree"); + if (np != NULL) { + pp = (char *) get_property(np, "model", NULL); + if (pp != NULL) + seq_printf(m, "%s\n", pp); + else + seq_printf(m, "PowerMac\n"); + pp = (char *) get_property(np, "compatible", &plen); + if (pp != NULL) { + seq_printf(m, "motherboard\t:"); + while (plen > 0) { + int l = strlen(pp) + 1; + seq_printf(m, " %s", pp); + plen -= l; + pp += l; + } + seq_printf(m, "\n"); + } + } else + seq_printf(m, "PowerMac\n"); + + /* print parsed model */ + seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); + seq_printf(m, "pmac flags\t: %08x\n", mbflags); + + /* find l2 cache info */ + np = find_devices("l2-cache"); + if (np == 0) + np = find_type_devices("cache"); + if (np != 0) { + unsigned int *ic = (unsigned int *) + get_property(np, "i-cache-size", NULL); + unsigned int *dc = (unsigned int *) + get_property(np, "d-cache-size", NULL); + seq_printf(m, "L2 cache\t:"); + has_l2cache = 1; + if (get_property(np, "cache-unified", NULL) != 0 && dc) { + seq_printf(m, " %dK unified", *dc / 1024); + } else { + if (ic) + seq_printf(m, " %dK instruction", *ic / 1024); + if (dc) + seq_printf(m, "%s %dK data", + (ic? " +": ""), *dc / 1024); + } + pp = get_property(np, "ram-type", NULL); + if (pp) + seq_printf(m, " %s", pp); + seq_printf(m, "\n"); + } + + /* find ram info */ + np = find_devices("memory"); + if (np != 0) { + int n; + struct reg_property *reg = (struct reg_property *) + get_property(np, "reg", &n); + + if (reg != 0) { + unsigned long total = 0; + + for (n /= sizeof(struct reg_property); n > 0; --n) + total += (reg++)->size; + seq_printf(m, "memory\t\t: %luMB\n", total >> 20); + } + } + + /* Checks "l2cr-value" property in the registry */ + np = find_devices("cpus"); + if (np == 0) + np = find_type_devices("cpu"); + if (np != 0) { + unsigned int *l2cr = (unsigned int *) + get_property(np, "l2cr-value", NULL); + if (l2cr != 0) { + seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr); + } + } + + /* Indicate newworld/oldworld */ + seq_printf(m, "pmac-generation\t: %s\n", + pmac_newworld ? "NewWorld" : "OldWorld"); + + + return 0; +} + +static int +pmac_show_percpuinfo(struct seq_file *m, int i) +{ +#ifdef CONFIG_CPU_FREQ_PMAC + extern unsigned int pmac_get_one_cpufreq(int i); + unsigned int freq = pmac_get_one_cpufreq(i); + if (freq != 0) { + seq_printf(m, "clock\t\t: %dMHz\n", freq/1000); + return 0; + } +#endif /* CONFIG_CPU_FREQ_PMAC */ + return of_show_percpuinfo(m, i); +} + +static volatile u32 *sysctrl_regs; + +void __init +pmac_setup_arch(void) +{ + struct device_node *cpu; + int *fp; + unsigned long pvr; + + pvr = PVR_VER(mfspr(SPRN_PVR)); + + /* Set loops_per_jiffy to a half-way reasonable value, + for use until calibrate_delay gets called. */ + cpu = find_type_devices("cpu"); + if (cpu != 0) { + fp = (int *) get_property(cpu, "clock-frequency", NULL); + if (fp != 0) { + if (pvr == 4 || pvr >= 8) + /* 604, G3, G4 etc. */ + loops_per_jiffy = *fp / HZ; + else + /* 601, 603, etc. */ + loops_per_jiffy = *fp / (2*HZ); + } else + loops_per_jiffy = 50000000 / HZ; + } + + /* this area has the CPU identification register + and some registers used by smp boards */ + sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); + ohare_init(); + + /* Lookup PCI hosts */ + pmac_find_bridges(); + + /* Checks "l2cr-value" property in the registry */ + if (cpu_has_feature(CPU_FTR_L2CR)) { + struct device_node *np = find_devices("cpus"); + if (np == 0) + np = find_type_devices("cpu"); + if (np != 0) { + unsigned int *l2cr = (unsigned int *) + get_property(np, "l2cr-value", NULL); + if (l2cr != 0) { + ppc_override_l2cr = 1; + ppc_override_l2cr_value = *l2cr; + _set_L2CR(0); + _set_L2CR(ppc_override_l2cr_value); + } + } + } + + if (ppc_override_l2cr) + printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", + ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) + ? "enabled" : "disabled"); + +#ifdef CONFIG_KGDB + zs_kgdb_hook(0); +#endif + +#ifdef CONFIG_ADB_CUDA + find_via_cuda(); +#else + if (find_devices("via-cuda")) { + printk("WARNING ! Your machine is Cuda based but your kernel\n"); + printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); + } +#endif +#ifdef CONFIG_ADB_PMU + find_via_pmu(); +#else + if (find_devices("via-pmu")) { + printk("WARNING ! Your machine is PMU based but your kernel\n"); + printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); + } +#endif +#ifdef CONFIG_NVRAM + pmac_nvram_init(); +#endif +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = DEFAULT_ROOT_DEVICE; + +#ifdef CONFIG_SMP + /* Check for Core99 */ + if (find_devices("uni-n") || find_devices("u3")) + ppc_md.smp_ops = &core99_smp_ops; + else + ppc_md.smp_ops = &psurge_smp_ops; +#endif /* CONFIG_SMP */ + + pci_create_OF_bus_map(); +} + +static void __init ohare_init(void) +{ + /* + * Turn on the L2 cache. + * We assume that we have a PSX memory controller iff + * we have an ohare I/O controller. + */ + if (find_devices("ohare") != NULL) { + if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { + if (sysctrl_regs[4] & 0x10) + sysctrl_regs[4] |= 0x04000020; + else + sysctrl_regs[4] |= 0x04000000; + if(has_l2cache) + printk(KERN_INFO "Level 2 cache enabled\n"); + } + } +} + +extern char *bootpath; +extern char *bootdevice; +void *boot_host; +int boot_target; +int boot_part; +extern dev_t boot_dev; + +#ifdef CONFIG_SCSI +void __init +note_scsi_host(struct device_node *node, void *host) +{ + int l; + char *p; + + l = strlen(node->full_name); + if (bootpath != NULL && bootdevice != NULL + && strncmp(node->full_name, bootdevice, l) == 0 + && (bootdevice[l] == '/' || bootdevice[l] == 0)) { + boot_host = host; + /* + * There's a bug in OF 1.0.5. (Why am I not surprised.) + * If you pass a path like scsi/sd@1:0 to canon, it returns + * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 + * That is, the scsi target number doesn't get preserved. + * So we pick the target number out of bootpath and use that. + */ + p = strstr(bootpath, "/sd@"); + if (p != NULL) { + p += 4; + boot_target = simple_strtoul(p, NULL, 10); + p = strchr(p, ':'); + if (p != NULL) + boot_part = simple_strtoul(p + 1, NULL, 10); + } + } +} +#endif + +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) +static dev_t __init +find_ide_boot(void) +{ + char *p; + int n; + dev_t __init pmac_find_ide_boot(char *bootdevice, int n); + + if (bootdevice == NULL) + return 0; + p = strrchr(bootdevice, '/'); + if (p == NULL) + return 0; + n = p - bootdevice; + + return pmac_find_ide_boot(bootdevice, n); +} +#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ + +static void __init +find_boot_device(void) +{ +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) + boot_dev = find_ide_boot(); +#endif +} + +static int initializing = 1; +/* TODO: Merge the suspend-to-ram with the common code !!! + * currently, this is a stub implementation for suspend-to-disk + * only + */ + +#ifdef CONFIG_SOFTWARE_SUSPEND + +static int pmac_pm_prepare(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + return 0; +} + +static int pmac_pm_enter(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + /* Giveup the lazy FPU & vec so we don't have to back them + * up from the low level code + */ + enable_kernel_fp(); + +#ifdef CONFIG_ALTIVEC + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + enable_kernel_altivec(); +#endif /* CONFIG_ALTIVEC */ + + return 0; +} + +static int pmac_pm_finish(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + /* Restore userland MMU context */ + set_context(current->active_mm->context, current->active_mm->pgd); + + return 0; +} + +static struct pm_ops pmac_pm_ops = { + .pm_disk_mode = PM_DISK_SHUTDOWN, + .prepare = pmac_pm_prepare, + .enter = pmac_pm_enter, + .finish = pmac_pm_finish, +}; + +#endif /* CONFIG_SOFTWARE_SUSPEND */ + +static int pmac_late_init(void) +{ + initializing = 0; +#ifdef CONFIG_SOFTWARE_SUSPEND + pm_set_ops(&pmac_pm_ops); +#endif /* CONFIG_SOFTWARE_SUSPEND */ + return 0; +} + +late_initcall(pmac_late_init); + +/* can't be __init - can be called whenever a disk is first accessed */ +void +note_bootable_part(dev_t dev, int part, int goodness) +{ + static int found_boot = 0; + char *p; + + if (!initializing) + return; + if ((goodness <= current_root_goodness) && + ROOT_DEV != DEFAULT_ROOT_DEVICE) + return; + p = strstr(saved_command_line, "root="); + if (p != NULL && (p == saved_command_line || p[-1] == ' ')) + return; + + if (!found_boot) { + find_boot_device(); + found_boot = 1; + } + if (!boot_dev || dev == boot_dev) { + ROOT_DEV = dev + part; + boot_dev = 0; + current_root_goodness = goodness; + } +} + +static void +pmac_restart(char *cmd) +{ +#ifdef CONFIG_ADB_CUDA + struct adb_request req; +#endif /* CONFIG_ADB_CUDA */ + + switch (sys_ctrler) { +#ifdef CONFIG_ADB_CUDA + case SYS_CTRLER_CUDA: + cuda_request(&req, NULL, 2, CUDA_PACKET, + CUDA_RESET_SYSTEM); + for (;;) + cuda_poll(); + break; +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_ADB_PMU + case SYS_CTRLER_PMU: + pmu_restart(); + break; +#endif /* CONFIG_ADB_PMU */ + default: ; + } +} + +static void +pmac_power_off(void) +{ +#ifdef CONFIG_ADB_CUDA + struct adb_request req; +#endif /* CONFIG_ADB_CUDA */ + + switch (sys_ctrler) { +#ifdef CONFIG_ADB_CUDA + case SYS_CTRLER_CUDA: + cuda_request(&req, NULL, 2, CUDA_PACKET, + CUDA_POWERDOWN); + for (;;) + cuda_poll(); + break; +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_ADB_PMU + case SYS_CTRLER_PMU: + pmu_shutdown(); + break; +#endif /* CONFIG_ADB_PMU */ + default: ; + } +} + +static void +pmac_halt(void) +{ + pmac_power_off(); +} + +void __init +pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* isa_io_base gets set in pmac_find_bridges */ + isa_mem_base = PMAC_ISA_MEM_BASE; + pci_dram_offset = PMAC_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 1; + DMA_MODE_WRITE = 2; + + ppc_md.setup_arch = pmac_setup_arch; + ppc_md.show_cpuinfo = pmac_show_cpuinfo; + ppc_md.show_percpuinfo = pmac_show_percpuinfo; + ppc_md.irq_canonicalize = NULL; + ppc_md.init_IRQ = pmac_pic_init; + ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ + + ppc_md.pcibios_fixup = pmac_pcibios_fixup; + ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; + ppc_md.pcibios_after_init = pmac_pcibios_after_init; + ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; + + ppc_md.restart = pmac_restart; + ppc_md.power_off = pmac_power_off; + ppc_md.halt = pmac_halt; + + ppc_md.time_init = pmac_time_init; + ppc_md.set_rtc_time = pmac_set_rtc_time; + ppc_md.get_rtc_time = pmac_get_rtc_time; + ppc_md.calibrate_decr = pmac_calibrate_decr; + + ppc_md.feature_call = pmac_do_feature_call; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +#ifdef CONFIG_BLK_DEV_IDE_PMAC + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; + ppc_ide_md.default_io_base = pmac_ide_get_base; +#endif /* CONFIG_BLK_DEV_IDE_PMAC */ +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ + +#ifdef CONFIG_BOOTX_TEXT + ppc_md.progress = pmac_progress; +#endif /* CONFIG_BOOTX_TEXT */ + + if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); + +} + +#ifdef CONFIG_BOOTX_TEXT +static void __init +pmac_progress(char *s, unsigned short hex) +{ + if (boot_text_mapped) { + btext_drawstring(s); + btext_drawchar('\n'); + } +} +#endif /* CONFIG_BOOTX_TEXT */ + +static int __init +pmac_declare_of_platform_devices(void) +{ + struct device_node *np; + + np = find_devices("uni-n"); + if (np) { + for (np = np->child; np != NULL; np = np->sibling) + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "uni-n-i2c", + NULL); + break; + } + } + np = find_devices("u3"); + if (np) { + for (np = np->child; np != NULL; np = np->sibling) + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "u3-i2c", + NULL); + break; + } + } + + np = find_devices("valkyrie"); + if (np) + of_platform_device_create(np, "valkyrie", NULL); + np = find_devices("platinum"); + if (np) + of_platform_device_create(np, "platinum", NULL); + + return 0; +} + +device_initcall(pmac_declare_of_platform_devices); diff --git a/arch/powerpc/platforms/powermac/pmac_sleep.S b/arch/powerpc/platforms/powermac/pmac_sleep.S new file mode 100644 index 000000000000..88419c77ac43 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_sleep.S @@ -0,0 +1,396 @@ +/* + * This file contains sleep low-level functions for PowerBook G3. + * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * and Paul Mackerras (paulus@samba.org). + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAGIC 0x4c617273 /* 'Lars' */ + +/* + * Structure for storing CPU registers on the stack. + */ +#define SL_SP 0 +#define SL_PC 4 +#define SL_MSR 8 +#define SL_SDR1 0xc +#define SL_SPRG0 0x10 /* 4 sprg's */ +#define SL_DBAT0 0x20 +#define SL_IBAT0 0x28 +#define SL_DBAT1 0x30 +#define SL_IBAT1 0x38 +#define SL_DBAT2 0x40 +#define SL_IBAT2 0x48 +#define SL_DBAT3 0x50 +#define SL_IBAT3 0x58 +#define SL_TB 0x60 +#define SL_R2 0x68 +#define SL_CR 0x6c +#define SL_R12 0x70 /* r12 to r31 */ +#define SL_SIZE (SL_R12 + 80) + + .section .text + .align 5 + +#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) + +/* This gets called by via-pmu.c late during the sleep process. + * The PMU was already send the sleep command and will shut us down + * soon. We need to save all that is needed and setup the wakeup + * vector that will be called by the ROM on wakeup + */ +_GLOBAL(low_sleep_handler) +#ifndef CONFIG_6xx + blr +#else + mflr r0 + stw r0,4(r1) + stwu r1,-SL_SIZE(r1) + mfcr r0 + stw r0,SL_CR(r1) + stw r2,SL_R2(r1) + stmw r12,SL_R12(r1) + + /* Save MSR & SDR1 */ + mfmsr r4 + stw r4,SL_MSR(r1) + mfsdr1 r4 + stw r4,SL_SDR1(r1) + + /* Get a stable timebase and save it */ +1: mftbu r4 + stw r4,SL_TB(r1) + mftb r5 + stw r5,SL_TB+4(r1) + mftbu r3 + cmpw r3,r4 + bne 1b + + /* Save SPRGs */ + mfsprg r4,0 + stw r4,SL_SPRG0(r1) + mfsprg r4,1 + stw r4,SL_SPRG0+4(r1) + mfsprg r4,2 + stw r4,SL_SPRG0+8(r1) + mfsprg r4,3 + stw r4,SL_SPRG0+12(r1) + + /* Save BATs */ + mfdbatu r4,0 + stw r4,SL_DBAT0(r1) + mfdbatl r4,0 + stw r4,SL_DBAT0+4(r1) + mfdbatu r4,1 + stw r4,SL_DBAT1(r1) + mfdbatl r4,1 + stw r4,SL_DBAT1+4(r1) + mfdbatu r4,2 + stw r4,SL_DBAT2(r1) + mfdbatl r4,2 + stw r4,SL_DBAT2+4(r1) + mfdbatu r4,3 + stw r4,SL_DBAT3(r1) + mfdbatl r4,3 + stw r4,SL_DBAT3+4(r1) + mfibatu r4,0 + stw r4,SL_IBAT0(r1) + mfibatl r4,0 + stw r4,SL_IBAT0+4(r1) + mfibatu r4,1 + stw r4,SL_IBAT1(r1) + mfibatl r4,1 + stw r4,SL_IBAT1+4(r1) + mfibatu r4,2 + stw r4,SL_IBAT2(r1) + mfibatl r4,2 + stw r4,SL_IBAT2+4(r1) + mfibatu r4,3 + stw r4,SL_IBAT3(r1) + mfibatl r4,3 + stw r4,SL_IBAT3+4(r1) + + /* Backup various CPU config stuffs */ + bl __save_cpu_setup + + /* The ROM can wake us up via 2 different vectors: + * - On wallstreet & lombard, we must write a magic + * value 'Lars' at address 4 and a pointer to a + * memory location containing the PC to resume from + * at address 0. + * - On Core99, we must store the wakeup vector at + * address 0x80 and eventually it's parameters + * at address 0x84. I've have some trouble with those + * parameters however and I no longer use them. + */ + lis r5,grackle_wake_up@ha + addi r5,r5,grackle_wake_up@l + tophys(r5,r5) + stw r5,SL_PC(r1) + lis r4,KERNELBASE@h + tophys(r5,r1) + addi r5,r5,SL_PC + lis r6,MAGIC@ha + addi r6,r6,MAGIC@l + stw r5,0(r4) + stw r6,4(r4) + /* Setup stuffs at 0x80-0x84 for Core99 */ + lis r3,core99_wake_up@ha + addi r3,r3,core99_wake_up@l + tophys(r3,r3) + stw r3,0x80(r4) + stw r5,0x84(r4) + /* Store a pointer to our backup storage into + * a kernel global + */ + lis r3,sleep_storage@ha + addi r3,r3,sleep_storage@l + stw r5,0(r3) + + .globl low_cpu_die +low_cpu_die: + /* Flush & disable all caches */ + bl flush_disable_caches + + /* Turn off data relocation. */ + mfmsr r3 /* Save MSR in r7 */ + rlwinm r3,r3,0,28,26 /* Turn off DR bit */ + sync + mtmsr r3 + isync + +BEGIN_FTR_SECTION + /* Flush any pending L2 data prefetches to work around HW bug */ + sync + lis r3,0xfff0 + lwz r0,0(r3) /* perform cache-inhibited load to ROM */ + sync /* (caches are disabled at this point) */ +END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) + +/* + * Set the HID0 and MSR for sleep. + */ + mfspr r2,SPRN_HID0 + rlwinm r2,r2,0,10,7 /* clear doze, nap */ + oris r2,r2,HID0_SLEEP@h + sync + isync + mtspr SPRN_HID0,r2 + sync + +/* This loop puts us back to sleep in case we have a spurrious + * wakeup so that the host bridge properly stays asleep. The + * CPU will be turned off, either after a known time (about 1 + * second) on wallstreet & lombard, or as soon as the CPU enters + * SLEEP mode on core99 + */ + mfmsr r2 + oris r2,r2,MSR_POW@h +1: sync + mtmsr r2 + isync + b 1b + +/* + * Here is the resume code. + */ + + +/* + * Core99 machines resume here + * r4 has the physical address of SL_PC(sp) (unused) + */ +_GLOBAL(core99_wake_up) + /* Make sure HID0 no longer contains any sleep bit and that data cache + * is disabled + */ + mfspr r3,SPRN_HID0 + rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */ + rlwinm 3,r3,0,18,15 /* clear DCE, ICE */ + mtspr SPRN_HID0,r3 + sync + isync + + /* sanitize MSR */ + mfmsr r3 + ori r3,r3,MSR_EE|MSR_IP + xori r3,r3,MSR_EE|MSR_IP + sync + isync + mtmsr r3 + sync + isync + + /* Recover sleep storage */ + lis r3,sleep_storage@ha + addi r3,r3,sleep_storage@l + tophys(r3,r3) + lwz r1,0(r3) + + /* Pass thru to older resume code ... */ +/* + * Here is the resume code for older machines. + * r1 has the physical address of SL_PC(sp). + */ + +grackle_wake_up: + + /* Restore the kernel's segment registers before + * we do any r1 memory access as we are not sure they + * are in a sane state above the first 256Mb region + */ + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + sync + isync + + subi r1,r1,SL_PC + + /* Restore various CPU config stuffs */ + bl __restore_cpu_setup + + /* Make sure all FPRs have been initialized */ + bl reloc_offset + bl __init_fpu_registers + + /* Invalidate & enable L1 cache, we don't care about + * whatever the ROM may have tried to write to memory + */ + bl __inval_enable_L1 + + /* Restore the BATs, and SDR1. Then we can turn on the MMU. */ + lwz r4,SL_SDR1(r1) + mtsdr1 r4 + lwz r4,SL_SPRG0(r1) + mtsprg 0,r4 + lwz r4,SL_SPRG0+4(r1) + mtsprg 1,r4 + lwz r4,SL_SPRG0+8(r1) + mtsprg 2,r4 + lwz r4,SL_SPRG0+12(r1) + mtsprg 3,r4 + + lwz r4,SL_DBAT0(r1) + mtdbatu 0,r4 + lwz r4,SL_DBAT0+4(r1) + mtdbatl 0,r4 + lwz r4,SL_DBAT1(r1) + mtdbatu 1,r4 + lwz r4,SL_DBAT1+4(r1) + mtdbatl 1,r4 + lwz r4,SL_DBAT2(r1) + mtdbatu 2,r4 + lwz r4,SL_DBAT2+4(r1) + mtdbatl 2,r4 + lwz r4,SL_DBAT3(r1) + mtdbatu 3,r4 + lwz r4,SL_DBAT3+4(r1) + mtdbatl 3,r4 + lwz r4,SL_IBAT0(r1) + mtibatu 0,r4 + lwz r4,SL_IBAT0+4(r1) + mtibatl 0,r4 + lwz r4,SL_IBAT1(r1) + mtibatu 1,r4 + lwz r4,SL_IBAT1+4(r1) + mtibatl 1,r4 + lwz r4,SL_IBAT2(r1) + mtibatu 2,r4 + lwz r4,SL_IBAT2+4(r1) + mtibatl 2,r4 + lwz r4,SL_IBAT3(r1) + mtibatu 3,r4 + lwz r4,SL_IBAT3+4(r1) + mtibatl 3,r4 + +BEGIN_FTR_SECTION + li r4,0 + mtspr SPRN_DBAT4U,r4 + mtspr SPRN_DBAT4L,r4 + mtspr SPRN_DBAT5U,r4 + mtspr SPRN_DBAT5L,r4 + mtspr SPRN_DBAT6U,r4 + mtspr SPRN_DBAT6L,r4 + mtspr SPRN_DBAT7U,r4 + mtspr SPRN_DBAT7L,r4 + mtspr SPRN_IBAT4U,r4 + mtspr SPRN_IBAT4L,r4 + mtspr SPRN_IBAT5U,r4 + mtspr SPRN_IBAT5L,r4 + mtspr SPRN_IBAT6U,r4 + mtspr SPRN_IBAT6L,r4 + mtspr SPRN_IBAT7U,r4 + mtspr SPRN_IBAT7L,r4 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) + + /* Flush all TLBs */ + lis r4,0x1000 +1: addic. r4,r4,-0x1000 + tlbie r4 + blt 1b + sync + + /* restore the MSR and turn on the MMU */ + lwz r3,SL_MSR(r1) + bl turn_on_mmu + + /* get back the stack pointer */ + tovirt(r1,r1) + + /* Restore TB */ + li r3,0 + mttbl r3 + lwz r3,SL_TB(r1) + lwz r4,SL_TB+4(r1) + mttbu r3 + mttbl r4 + + /* Restore the callee-saved registers and return */ + lwz r0,SL_CR(r1) + mtcr r0 + lwz r2,SL_R2(r1) + lmw r12,SL_R12(r1) + addi r1,r1,SL_SIZE + lwz r0,4(r1) + mtlr r0 + blr + +turn_on_mmu: + mflr r4 + tovirt(r4,r4) + mtsrr0 r4 + mtsrr1 r3 + sync + isync + rfi + +#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ + + .section .data + .balign L1_CACHE_LINE_SIZE +sleep_storage: + .long 0 + .balign L1_CACHE_LINE_SIZE, 0 + +#endif /* CONFIG_6xx */ + .section .text diff --git a/arch/powerpc/platforms/powermac/pmac_smp.c b/arch/powerpc/platforms/powermac/pmac_smp.c new file mode 100644 index 000000000000..995e9095d865 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_smp.c @@ -0,0 +1,716 @@ +/* + * SMP support for power macintosh. + * + * We support both the old "powersurge" SMP architecture + * and the current Core99 (G4 PowerMac) machines. + * + * Note that we don't support the very first rev. of + * Apple/DayStar 2 CPUs board, the one with the funky + * watchdog. Hopefully, none of these should be there except + * maybe internally to Apple. I should probably still add some + * code to detect this card though and disable SMP. --BenH. + * + * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net) + * and Ben Herrenschmidt . + * + * Support for DayStar quad CPU cards + * Copyright (C) XLR8, Inc. 1994-2000 + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Powersurge (old powermac SMP) support. + */ + +extern void __secondary_start_pmac_0(void); + +/* Addresses for powersurge registers */ +#define HAMMERHEAD_BASE 0xf8000000 +#define HHEAD_CONFIG 0x90 +#define HHEAD_SEC_INTR 0xc0 + +/* register for interrupting the primary processor on the powersurge */ +/* N.B. this is actually the ethernet ROM! */ +#define PSURGE_PRI_INTR 0xf3019000 + +/* register for storing the start address for the secondary processor */ +/* N.B. this is the PCI config space address register for the 1st bridge */ +#define PSURGE_START 0xf2800000 + +/* Daystar/XLR8 4-CPU card */ +#define PSURGE_QUAD_REG_ADDR 0xf8800000 + +#define PSURGE_QUAD_IRQ_SET 0 +#define PSURGE_QUAD_IRQ_CLR 1 +#define PSURGE_QUAD_IRQ_PRIMARY 2 +#define PSURGE_QUAD_CKSTOP_CTL 3 +#define PSURGE_QUAD_PRIMARY_ARB 4 +#define PSURGE_QUAD_BOARD_ID 6 +#define PSURGE_QUAD_WHICH_CPU 7 +#define PSURGE_QUAD_CKSTOP_RDBK 8 +#define PSURGE_QUAD_RESET_CTL 11 + +#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v))) +#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f) +#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v))) +#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v))) + +/* virtual addresses for the above */ +static volatile u8 __iomem *hhead_base; +static volatile u8 __iomem *quad_base; +static volatile u32 __iomem *psurge_pri_intr; +static volatile u8 __iomem *psurge_sec_intr; +static volatile u32 __iomem *psurge_start; + +/* values for psurge_type */ +#define PSURGE_NONE -1 +#define PSURGE_DUAL 0 +#define PSURGE_QUAD_OKEE 1 +#define PSURGE_QUAD_COTTON 2 +#define PSURGE_QUAD_ICEGRASS 3 + +/* what sort of powersurge board we have */ +static int psurge_type = PSURGE_NONE; + +/* L2 and L3 cache settings to pass from CPU0 to CPU1 */ +volatile static long int core99_l2_cache; +volatile static long int core99_l3_cache; + +/* Timebase freeze GPIO */ +static unsigned int core99_tb_gpio; + +/* Sync flag for HW tb sync */ +static volatile int sec_tb_reset = 0; +static unsigned int pri_tb_hi, pri_tb_lo; +static unsigned int pri_tb_stamp; + +static void __devinit core99_init_caches(int cpu) +{ + if (!cpu_has_feature(CPU_FTR_L2CR)) + return; + + if (cpu == 0) { + core99_l2_cache = _get_L2CR(); + printk("CPU0: L2CR is %lx\n", core99_l2_cache); + } else { + printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); + _set_L2CR(0); + _set_L2CR(core99_l2_cache); + printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); + } + + if (!cpu_has_feature(CPU_FTR_L3CR)) + return; + + if (cpu == 0){ + core99_l3_cache = _get_L3CR(); + printk("CPU0: L3CR is %lx\n", core99_l3_cache); + } else { + printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR()); + _set_L3CR(0); + _set_L3CR(core99_l3_cache); + printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); + } +} + +/* + * Set and clear IPIs for powersurge. + */ +static inline void psurge_set_ipi(int cpu) +{ + if (psurge_type == PSURGE_NONE) + return; + if (cpu == 0) + in_be32(psurge_pri_intr); + else if (psurge_type == PSURGE_DUAL) + out_8(psurge_sec_intr, 0); + else + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu); +} + +static inline void psurge_clr_ipi(int cpu) +{ + if (cpu > 0) { + switch(psurge_type) { + case PSURGE_DUAL: + out_8(psurge_sec_intr, ~0); + case PSURGE_NONE: + break; + default: + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu); + } + } +} + +/* + * On powersurge (old SMP powermac architecture) we don't have + * separate IPIs for separate messages like openpic does. Instead + * we have a bitmap for each processor, where a 1 bit means that + * the corresponding message is pending for that processor. + * Ideally each cpu's entry would be in a different cache line. + * -- paulus. + */ +static unsigned long psurge_smp_message[NR_CPUS]; + +void psurge_smp_message_recv(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int msg; + + /* clear interrupt */ + psurge_clr_ipi(cpu); + + if (num_online_cpus() < 2) + return; + + /* make sure there is a message there */ + for (msg = 0; msg < 4; msg++) + if (test_and_clear_bit(msg, &psurge_smp_message[cpu])) + smp_message_recv(msg, regs); +} + +irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) +{ + psurge_smp_message_recv(regs); + return IRQ_HANDLED; +} + +static void smp_psurge_message_pass(int target, int msg, unsigned long data, + int wait) +{ + int i; + + if (num_online_cpus() < 2) + return; + + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; + if (target == MSG_ALL + || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) + || target == i) { + set_bit(msg, &psurge_smp_message[i]); + psurge_set_ipi(i); + } + } +} + +/* + * Determine a quad card presence. We read the board ID register, we + * force the data bus to change to something else, and we read it again. + * It it's stable, then the register probably exist (ugh !) + */ +static int __init psurge_quad_probe(void) +{ + int type; + unsigned int i; + + type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID); + if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS + || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + + /* looks OK, try a slightly more rigorous test */ + /* bogus is not necessarily cacheline-aligned, + though I don't suppose that really matters. -- paulus */ + for (i = 0; i < 100; i++) { + volatile u32 bogus[8]; + bogus[(0+i)%8] = 0x00000000; + bogus[(1+i)%8] = 0x55555555; + bogus[(2+i)%8] = 0xFFFFFFFF; + bogus[(3+i)%8] = 0xAAAAAAAA; + bogus[(4+i)%8] = 0x33333333; + bogus[(5+i)%8] = 0xCCCCCCCC; + bogus[(6+i)%8] = 0xCCCCCCCC; + bogus[(7+i)%8] = 0x33333333; + wmb(); + asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory"); + mb(); + if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + } + return type; +} + +static void __init psurge_quad_init(void) +{ + int procbits; + + if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351); + procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU); + if (psurge_type == PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + else + PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits); + mdelay(33); + out_8(psurge_sec_intr, ~0); + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits); + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + if (psurge_type != PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits); + PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); + PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits); + mdelay(33); + PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); +} + +static int __init smp_psurge_probe(void) +{ + int i, ncpus; + + /* We don't do SMP on the PPC601 -- paulus */ + if (PVR_VER(mfspr(SPRN_PVR)) == 1) + return 1; + + /* + * The powersurge cpu board can be used in the generation + * of powermacs that have a socket for an upgradeable cpu card, + * including the 7500, 8500, 9500, 9600. + * The device tree doesn't tell you if you have 2 cpus because + * OF doesn't know anything about the 2nd processor. + * Instead we look for magic bits in magic registers, + * in the hammerhead memory controller in the case of the + * dual-cpu powersurge board. -- paulus. + */ + if (find_devices("hammerhead") == NULL) + return 1; + + hhead_base = ioremap(HAMMERHEAD_BASE, 0x800); + quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024); + psurge_sec_intr = hhead_base + HHEAD_SEC_INTR; + + psurge_type = psurge_quad_probe(); + if (psurge_type != PSURGE_DUAL) { + psurge_quad_init(); + /* All released cards using this HW design have 4 CPUs */ + ncpus = 4; + } else { + iounmap(quad_base); + if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { + /* not a dual-cpu card */ + iounmap(hhead_base); + psurge_type = PSURGE_NONE; + return 1; + } + ncpus = 2; + } + + psurge_start = ioremap(PSURGE_START, 4); + psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); + + /* this is not actually strictly necessary -- paulus. */ + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + + if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); + + return ncpus; +} + +static void __init smp_psurge_kick_cpu(int nr) +{ + unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; + unsigned long a; + + /* may need to flush here if secondary bats aren't setup */ + for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) + asm volatile("dcbf 0,%0" : : "r" (a) : "memory"); + asm volatile("sync"); + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); + + out_be32(psurge_start, start); + mb(); + + psurge_set_ipi(nr); + udelay(10); + psurge_clr_ipi(nr); + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); +} + +/* + * With the dual-cpu powersurge board, the decrementers and timebases + * of both cpus are frozen after the secondary cpu is started up, + * until we give the secondary cpu another interrupt. This routine + * uses this to get the timebases synchronized. + * -- paulus. + */ +static void __init psurge_dual_sync_tb(int cpu_nr) +{ + int t; + + set_dec(tb_ticks_per_jiffy); + set_tb(0, 0); + last_jiffy_stamp(cpu_nr) = 0; + + if (cpu_nr > 0) { + mb(); + sec_tb_reset = 1; + return; + } + + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + + /* now interrupt the secondary, starting both TBs */ + psurge_set_ipi(1); + + smp_tb_synchronized = 1; +} + +static struct irqaction psurge_irqaction = { + .handler = psurge_primary_intr, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, + .name = "primary IPI", +}; + +static void __init smp_psurge_setup_cpu(int cpu_nr) +{ + + if (cpu_nr == 0) { + /* If we failed to start the second CPU, we should still + * send it an IPI to start the timebase & DEC or we might + * have them stuck. + */ + if (num_online_cpus() < 2) { + if (psurge_type == PSURGE_DUAL) + psurge_set_ipi(1); + return; + } + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (setup_irq(30, &psurge_irqaction)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + } + + if (psurge_type == PSURGE_DUAL) + psurge_dual_sync_tb(cpu_nr); +} + +void __init smp_psurge_take_timebase(void) +{ + /* Dummy implementation */ +} + +void __init smp_psurge_give_timebase(void) +{ + /* Dummy implementation */ +} + +static int __init smp_core99_probe(void) +{ +#ifdef CONFIG_6xx + extern int powersave_nap; +#endif + struct device_node *cpus, *firstcpu; + int i, ncpus = 0, boot_cpu = -1; + u32 *tbprop = NULL; + + if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); + cpus = firstcpu = find_type_devices("cpu"); + while(cpus != NULL) { + u32 *regprop = (u32 *)get_property(cpus, "reg", NULL); + char *stateprop = (char *)get_property(cpus, "state", NULL); + if (regprop != NULL && stateprop != NULL && + !strncmp(stateprop, "running", 7)) + boot_cpu = *regprop; + ++ncpus; + cpus = cpus->next; + } + if (boot_cpu == -1) + printk(KERN_WARNING "Couldn't detect boot CPU !\n"); + if (boot_cpu != 0) + printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu); + + if (machine_is_compatible("MacRISC4")) { + extern struct smp_ops_t core99_smp_ops; + + core99_smp_ops.take_timebase = smp_generic_take_timebase; + core99_smp_ops.give_timebase = smp_generic_give_timebase; + } else { + if (firstcpu != NULL) + tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL); + if (tbprop) + core99_tb_gpio = *tbprop; + else + core99_tb_gpio = KL_GPIO_TB_ENABLE; + } + + if (ncpus > 1) { + mpic_request_ipis(); + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; +#ifdef CONFIG_6xx + powersave_nap = 0; +#endif + core99_init_caches(0); + } + + return ncpus; +} + +static void __devinit smp_core99_kick_cpu(int nr) +{ + unsigned long save_vector, new_vector; + unsigned long flags; + + volatile unsigned long *vector + = ((volatile unsigned long *)(KERNELBASE+0x100)); + if (nr < 0 || nr > 3) + return; + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); + + local_irq_save(flags); + local_irq_disable(); + + /* Save reset vector */ + save_vector = *vector; + + /* Setup fake reset vector that does + * b __secondary_start_pmac_0 + nr*8 - KERNELBASE + */ + new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; + *vector = 0x48000002 + new_vector - KERNELBASE; + + /* flush data cache and inval instruction cache */ + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + /* Put some life in our friend */ + pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); + + /* FIXME: We wait a bit for the CPU to take the exception, I should + * instead wait for the entry code to set something for me. Well, + * ideally, all that crap will be done in prom.c and the CPU left + * in a RAM-based wait loop like CHRP. + */ + mdelay(1); + + /* Restore our exception vector */ + *vector = save_vector; + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + local_irq_restore(flags); + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); +} + +static void __devinit smp_core99_setup_cpu(int cpu_nr) +{ + /* Setup L2/L3 */ + if (cpu_nr != 0) + core99_init_caches(cpu_nr); + + /* Setup openpic */ + mpic_setup_this_cpu(); + + if (cpu_nr == 0) { +#ifdef CONFIG_POWER4 + extern void g5_phy_disable_cpu1(void); + + /* If we didn't start the second CPU, we must take + * it off the bus + */ + if (machine_is_compatible("MacRISC4") && + num_online_cpus() < 2) + g5_phy_disable_cpu1(); +#endif /* CONFIG_POWER4 */ + if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); + } +} + +/* not __init, called in sleep/wakeup code */ +void smp_core99_take_timebase(void) +{ + unsigned long flags; + + /* tell the primary we're here */ + sec_tb_reset = 1; + mb(); + + /* wait for the primary to set pri_tb_hi/lo */ + while (sec_tb_reset < 2) + mb(); + + /* set our stuff the same as the primary */ + local_irq_save(flags); + set_dec(1); + set_tb(pri_tb_hi, pri_tb_lo); + last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp; + mb(); + + /* tell the primary we're done */ + sec_tb_reset = 0; + mb(); + local_irq_restore(flags); +} + +/* not __init, called in sleep/wakeup code */ +void smp_core99_give_timebase(void) +{ + unsigned long flags; + unsigned int t; + + /* wait for the secondary to be in take_timebase */ + for (t = 100000; t > 0 && !sec_tb_reset; --t) + udelay(10); + if (!sec_tb_reset) { + printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); + return; + } + + /* freeze the timebase and read it */ + /* disable interrupts so the timebase is disabled for the + shortest possible time */ + local_irq_save(flags); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + mb(); + pri_tb_hi = get_tbu(); + pri_tb_lo = get_tbl(); + pri_tb_stamp = last_jiffy_stamp(smp_processor_id()); + mb(); + + /* tell the secondary we're ready */ + sec_tb_reset = 2; + mb(); + + /* wait for the secondary to have taken it */ + for (t = 100000; t > 0 && sec_tb_reset; --t) + udelay(10); + if (sec_tb_reset) + printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); + else + smp_tb_synchronized = 1; + + /* Now, restart the timebase by leaving the GPIO to an open collector */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + local_irq_restore(flags); +} + +void smp_core99_message_pass(int target, int msg, unsigned long data, int wait) +{ + cpumask_t mask = CPU_MASK_ALL; + /* make sure we're sending something that translates to an IPI */ + if (msg > 0x3) { + printk("SMP %d: smp_message_pass: unknown msg %d\n", + smp_processor_id(), msg); + return; + } + switch (target) { + case MSG_ALL: + mpic_send_ipi(msg, mask); + break; + case MSG_ALL_BUT_SELF: + cpu_clear(smp_processor_id(), mask); + mpic_send_ipi(msg, mask); + break; + default: + mpic_send_ipi(msg, cpumask_of_cpu(target)); + break; + } +} + + +/* PowerSurge-style Macs */ +struct smp_ops_t psurge_smp_ops = { + .message_pass = smp_psurge_message_pass, + .probe = smp_psurge_probe, + .kick_cpu = smp_psurge_kick_cpu, + .setup_cpu = smp_psurge_setup_cpu, + .give_timebase = smp_psurge_give_timebase, + .take_timebase = smp_psurge_take_timebase, +}; + +/* Core99 Macs (dual G4s) */ +struct smp_ops_t core99_smp_ops = { + .message_pass = smp_core99_message_pass, + .probe = smp_core99_probe, + .kick_cpu = smp_core99_kick_cpu, + .setup_cpu = smp_core99_setup_cpu, + .give_timebase = smp_core99_give_timebase, + .take_timebase = smp_core99_take_timebase, +}; + +#ifdef CONFIG_HOTPLUG_CPU + +int __cpu_disable(void) +{ + cpu_clear(smp_processor_id(), cpu_online_map); + + /* XXX reset cpu affinity here */ + openpic_set_priority(0xf); + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + mb(); + udelay(20); + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + return 0; +} + +extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */ +static int cpu_dead[NR_CPUS]; + +void cpu_die(void) +{ + local_irq_disable(); + cpu_dead[smp_processor_id()] = 1; + mb(); + low_cpu_die(); +} + +void __cpu_die(unsigned int cpu) +{ + int timeout; + + timeout = 1000; + while (!cpu_dead[cpu]) { + if (--timeout == 0) { + printk("CPU %u refused to die!\n", cpu); + break; + } + msleep(1); + } + cpu_callin_map[cpu] = 0; + cpu_dead[cpu] = 0; +} + +#endif diff --git a/arch/powerpc/platforms/powermac/pmac_time.c b/arch/powerpc/platforms/powermac/pmac_time.c new file mode 100644 index 000000000000..ff6adff36cb8 --- /dev/null +++ b/arch/powerpc/platforms/powermac/pmac_time.c @@ -0,0 +1,291 @@ +/* + * Support for periodic interrupts (100 per second) and for getting + * the current time from the RTC on Power Macintoshes. + * + * We use the decrementer register for our periodic interrupts. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996 Paul Mackerras. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Apparently the RTC stores seconds since 1 Jan 1904 */ +#define RTC_OFFSET 2082844800 + +/* + * Calibrate the decrementer frequency with the VIA timer 1. + */ +#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ + +/* VIA registers */ +#define RS 0x200 /* skip between registers */ +#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ +#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ +#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ +#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ +#define ACR (11*RS) /* Auxiliary control register */ +#define IFR (13*RS) /* Interrupt flag register */ + +/* Bits in ACR */ +#define T1MODE 0xc0 /* Timer 1 mode */ +#define T1MODE_CONT 0x40 /* continuous interrupts */ + +/* Bits in IFR and IER */ +#define T1_INT 0x40 /* Timer 1 interrupt */ + +extern struct timezone sys_tz; + +long __init +pmac_time_init(void) +{ +#ifdef CONFIG_NVRAM + s32 delta = 0; + int dst; + + delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; + delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; + delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); + if (delta & 0x00800000UL) + delta |= 0xFF000000UL; + dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); + printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, + dst ? "on" : "off"); + return delta; +#else + return 0; +#endif +} + +unsigned long +pmac_get_rtc_time(void) +{ +#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) + struct adb_request req; + unsigned long now; +#endif + + /* Get the time from the RTC */ + switch (sys_ctrler) { +#ifdef CONFIG_ADB_CUDA + case SYS_CTRLER_CUDA: + if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) + return 0; + while (!req.complete) + cuda_poll(); + if (req.reply_len != 7) + printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", + req.reply_len); + now = (req.reply[3] << 24) + (req.reply[4] << 16) + + (req.reply[5] << 8) + req.reply[6]; + return now - RTC_OFFSET; +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_ADB_PMU + case SYS_CTRLER_PMU: + if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) + return 0; + while (!req.complete) + pmu_poll(); + if (req.reply_len != 4) + printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", + req.reply_len); + now = (req.reply[0] << 24) + (req.reply[1] << 16) + + (req.reply[2] << 8) + req.reply[3]; + return now - RTC_OFFSET; +#endif /* CONFIG_ADB_PMU */ + default: ; + } + return 0; +} + +int +pmac_set_rtc_time(unsigned long nowtime) +{ +#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) + struct adb_request req; +#endif + + nowtime += RTC_OFFSET; + + switch (sys_ctrler) { +#ifdef CONFIG_ADB_CUDA + case SYS_CTRLER_CUDA: + if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, + nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + return 0; + while (!req.complete) + cuda_poll(); + if ((req.reply_len != 3) && (req.reply_len != 7)) + printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", + req.reply_len); + return 1; +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_ADB_PMU + case SYS_CTRLER_PMU: + if (pmu_request(&req, NULL, 5, PMU_SET_RTC, + nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + return 0; + while (!req.complete) + pmu_poll(); + if (req.reply_len != 0) + printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", + req.reply_len); + return 1; +#endif /* CONFIG_ADB_PMU */ + default: + return 0; + } +} + +/* + * Calibrate the decrementer register using VIA timer 1. + * This is used both on powermacs and CHRP machines. + */ +int __init +via_calibrate_decr(void) +{ + struct device_node *vias; + volatile unsigned char __iomem *via; + int count = VIA_TIMER_FREQ_6 / 100; + unsigned int dstart, dend; + + vias = find_devices("via-cuda"); + if (vias == 0) + vias = find_devices("via-pmu"); + if (vias == 0) + vias = find_devices("via"); + if (vias == 0 || vias->n_addrs == 0) + return 0; + via = ioremap(vias->addrs[0].address, vias->addrs[0].size); + + /* set timer 1 for continuous interrupts */ + out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); + /* set the counter to a small value */ + out_8(&via[T1CH], 2); + /* set the latch to `count' */ + out_8(&via[T1LL], count); + out_8(&via[T1LH], count >> 8); + /* wait until it hits 0 */ + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dstart = get_dec(); + /* clear the interrupt & wait until it hits 0 again */ + in_8(&via[T1CL]); + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dend = get_dec(); + + tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100)); + tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); + + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + tb_ticks_per_jiffy, dstart - dend); + + iounmap(via); + + return 1; +} + +#ifdef CONFIG_PM +/* + * Reset the time after a sleep. + */ +static int +time_sleep_notify(struct pmu_sleep_notifier *self, int when) +{ + static unsigned long time_diff; + unsigned long flags; + unsigned long seq; + + switch (when) { + case PBOOK_SLEEP_NOW: + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + time_diff = xtime.tv_sec - pmac_get_rtc_time(); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + break; + case PBOOK_WAKE: + write_seqlock_irqsave(&xtime_lock, flags); + xtime.tv_sec = pmac_get_rtc_time() + time_diff; + xtime.tv_nsec = 0; + last_rtc_update = xtime.tv_sec; + write_sequnlock_irqrestore(&xtime_lock, flags); + break; + } + return PBOOK_SLEEP_OK; +} + +static struct pmu_sleep_notifier time_sleep_notifier = { + time_sleep_notify, SLEEP_LEVEL_MISC, +}; +#endif /* CONFIG_PM */ + +/* + * Query the OF and get the decr frequency. + * This was taken from the pmac time_init() when merging the prep/pmac + * time functions. + */ +void __init +pmac_calibrate_decr(void) +{ + struct device_node *cpu; + unsigned int freq, *fp; + +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&time_sleep_notifier); +#endif /* CONFIG_PM */ + + /* We assume MacRISC2 machines have correct device-tree + * calibration. That's better since the VIA itself seems + * to be slightly off. --BenH + */ + if (!machine_is_compatible("MacRISC2") && + !machine_is_compatible("MacRISC3") && + !machine_is_compatible("MacRISC4")) + if (via_calibrate_decr()) + return; + + /* Special case: QuickSilver G4s seem to have a badly calibrated + * timebase-frequency in OF, VIA is much better on these. We should + * probably implement calibration based on the KL timer on these + * machines anyway... -BenH + */ + if (machine_is_compatible("PowerMac3,5")) + if (via_calibrate_decr()) + return; + /* + * The cpu node should have a timebase-frequency property + * to tell us the rate at which the decrementer counts. + */ + cpu = find_type_devices("cpu"); + if (cpu == 0) + panic("can't find cpu node in time_init"); + fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); + if (fp == 0) + panic("can't get cpu timebase frequency"); + freq = *fp; + printk("time_init: decrementer frequency = %u.%.6u MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); +} diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig new file mode 100644 index 000000000000..673ac47a1626 --- /dev/null +++ b/arch/powerpc/platforms/prep/Kconfig @@ -0,0 +1,22 @@ + +config PREP_RESIDUAL + bool "Support for PReP Residual Data" + depends on PPC_PREP + help + Some PReP systems have residual data passed to the kernel by the + firmware. This allows detection of memory size, devices present and + other useful pieces of information. Sometimes this information is + not present or incorrect, in which case it could lead to the machine + behaving incorrectly. If this happens, either disable PREP_RESIDUAL + or pass the 'noresidual' option to the kernel. + + If you are running a PReP system, say Y here, otherwise say N. + +config PROC_PREPRESIDUAL + bool "Support for reading of PReP Residual Data in /proc" + depends on PREP_RESIDUAL && PROC_FS + help + Enabling this option will create a /proc/residual file which allows + you to get at the residual data on PReP systems. You will need a tool + (lsresidual) to parse it. If you aren't on a PReP system, you don't + want this. diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig new file mode 100644 index 000000000000..7a3b6fc4d976 --- /dev/null +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -0,0 +1,47 @@ + +config PPC_SPLPAR + depends on PPC_PSERIES + bool "Support for shared-processor logical partitions" + default n + help + Enabling this option will make the kernel run more efficiently + on logically-partitioned pSeries systems which use shared + processors, that is, which share physical processors between + two or more partitions. + +config HMT + bool "Hardware multithreading" + depends on SMP && PPC_PSERIES && BROKEN + help + This option enables hardware multithreading on RS64 cpus. + pSeries systems p620 and p660 have such a cpu type. + +config EEH + bool "PCI Extended Error Handling (EEH)" if EMBEDDED + depends on PPC_PSERIES + default y if !EMBEDDED + +config PPC_RTAS + bool + depends on PPC_PSERIES || PPC_BPA + default y + +config RTAS_PROC + bool "Proc interface to RTAS" + depends on PPC_RTAS + default y + +config RTAS_FLASH + tristate "Firmware flash interface" + depends on PPC64 && RTAS_PROC + +config SCANLOG + tristate "Scanlog dump interface" + depends on RTAS_PROC && PPC_PSERIES + +config LPARCFG + tristate "LPAR Configuration Data" + depends on PPC_PSERIES || PPC_ISERIES + help + Provide system capacity information via human readable + = pairs through a /proc/ppc64/lparcfg interface. diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile new file mode 100644 index 000000000000..26bdcd9a2a43 --- /dev/null +++ b/arch/powerpc/sysdev/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MPIC) += mpic.o diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c new file mode 100644 index 000000000000..c660e7d7c643 --- /dev/null +++ b/arch/powerpc/sysdev/mpic.c @@ -0,0 +1,904 @@ +/* + * arch/powerpc/kernel/mpic.c + * + * Driver for interrupt controllers following the OpenPIC standard, the + * common implementation beeing IBM's MPIC. This driver also can deal + * with various broken implementations of this HW. + * + * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif + +static struct mpic *mpics; +static struct mpic *mpic_primary; +static DEFINE_SPINLOCK(mpic_lock); + + +/* + * Register accessor functions + */ + + +static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, + unsigned int reg) +{ + if (be) + return in_be32(base + (reg >> 2)); + else + return in_le32(base + (reg >> 2)); +} + +static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, + unsigned int reg, u32 value) +{ + if (be) + out_be32(base + (reg >> 2), value); + else + out_le32(base + (reg >> 2), value); +} + +static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) +{ + unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; + unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); + + if (mpic->flags & MPIC_BROKEN_IPI) + be = !be; + return _mpic_read(be, mpic->gregs, offset); +} + +static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) +{ + unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); + + _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); +} + +static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) +{ + unsigned int cpu = 0; + + if (mpic->flags & MPIC_PRIMARY) + cpu = hard_smp_processor_id(); + + return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg); +} + +static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) +{ + unsigned int cpu = 0; + + if (mpic->flags & MPIC_PRIMARY) + cpu = hard_smp_processor_id(); + + _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value); +} + +static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) +{ + unsigned int isu = src_no >> mpic->isu_shift; + unsigned int idx = src_no & mpic->isu_mask; + + return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], + reg + (idx * MPIC_IRQ_STRIDE)); +} + +static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, + unsigned int reg, u32 value) +{ + unsigned int isu = src_no >> mpic->isu_shift; + unsigned int idx = src_no & mpic->isu_mask; + + _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], + reg + (idx * MPIC_IRQ_STRIDE), value); +} + +#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) +#define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v)) +#define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) +#define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) +#define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) +#define mpic_cpu_write(i,v) _mpic_cpu_write(mpic,(i),(v)) +#define mpic_irq_read(s,r) _mpic_irq_read(mpic,(s),(r)) +#define mpic_irq_write(s,r,v) _mpic_irq_write(mpic,(s),(r),(v)) + + +/* + * Low level utility functions + */ + + + +/* Check if we have one of those nice broken MPICs with a flipped endian on + * reads from IPI registers + */ +static void __init mpic_test_broken_ipi(struct mpic *mpic) +{ + u32 r; + + mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK); + r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0); + + if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { + printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); + mpic->flags |= MPIC_BROKEN_IPI; + } +} + +#ifdef CONFIG_MPIC_BROKEN_U3 + +/* Test if an interrupt is sourced from HyperTransport (used on broken U3s) + * to force the edge setting on the MPIC and do the ack workaround. + */ +static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no) +{ + if (source_no >= 128 || !mpic->fixups) + return 0; + return mpic->fixups[source_no].base != NULL; +} + +static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no) +{ + struct mpic_irq_fixup *fixup = &mpic->fixups[source_no]; + u32 tmp; + + spin_lock(&mpic->fixup_lock); + writeb(0x11 + 2 * fixup->irq, fixup->base); + tmp = readl(fixup->base + 2); + writel(tmp | 0x80000000ul, fixup->base + 2); + /* config writes shouldn't be posted but let's be safe ... */ + (void)readl(fixup->base + 2); + spin_unlock(&mpic->fixup_lock); +} + + +static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase) +{ + int i, irq; + u32 tmp; + + printk(KERN_INFO "mpic: - Workarounds on AMD 8111 @ %p\n", devbase); + + for (i=0; i < 24; i++) { + writeb(0x10 + 2*i, devbase + 0xf2); + tmp = readl(devbase + 0xf4); + if ((tmp & 0x1) || !(tmp & 0x20)) + continue; + irq = (tmp >> 16) & 0xff; + mpic->fixups[irq].irq = i; + mpic->fixups[irq].base = devbase + 0xf2; + } +} + +static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase) +{ + int i, irq; + u32 tmp; + + printk(KERN_INFO "mpic: - Workarounds on AMD 8131 @ %p\n", devbase); + + for (i=0; i < 4; i++) { + writeb(0x10 + 2*i, devbase + 0xba); + tmp = readl(devbase + 0xbc); + if ((tmp & 0x1) || !(tmp & 0x20)) + continue; + irq = (tmp >> 16) & 0xff; + mpic->fixups[irq].irq = i; + mpic->fixups[irq].base = devbase + 0xba; + } +} + +static void __init mpic_scan_ioapics(struct mpic *mpic) +{ + unsigned int devfn; + u8 __iomem *cfgspace; + + printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n"); + + /* Allocate fixups array */ + mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup)); + BUG_ON(mpic->fixups == NULL); + memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup)); + + /* Init spinlock */ + spin_lock_init(&mpic->fixup_lock); + + /* Map u3 config space. We assume all IO-APICs are on the primary bus + * and slot will never be above "0xf" so we only need to map 32k + */ + cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000); + BUG_ON(cfgspace == NULL); + + /* Now we scan all slots. We do a very quick scan, we read the header type, + * vendor ID and device ID only, that's plenty enough + */ + for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) { + u8 __iomem *devbase = cfgspace + (devfn << 8); + u8 hdr_type = readb(devbase + PCI_HEADER_TYPE); + u32 l = readl(devbase + PCI_VENDOR_ID); + u16 vendor_id, device_id; + int multifunc = 0; + + DBG("devfn %x, l: %x\n", devfn, l); + + /* If no device, skip */ + if (l == 0xffffffff || l == 0x00000000 || + l == 0x0000ffff || l == 0xffff0000) + goto next; + + /* Check if it's a multifunction device (only really used + * to function 0 though + */ + multifunc = !!(hdr_type & 0x80); + vendor_id = l & 0xffff; + device_id = (l >> 16) & 0xffff; + + /* If a known device, go to fixup setup code */ + if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460) + mpic_amd8111_read_irq(mpic, devbase); + if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450) + mpic_amd8131_read_irq(mpic, devbase); + next: + /* next device, if function 0 */ + if ((PCI_FUNC(devfn) == 0) && !multifunc) + devfn += 7; + } +} + +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + +/* Find an mpic associated with a given linux interrupt */ +static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi) +{ + struct mpic *mpic = mpics; + + while(mpic) { + /* search IPIs first since they may override the main interrupts */ + if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) { + if (is_ipi) + *is_ipi = 1; + return mpic; + } + if (irq >= mpic->irq_offset && + irq < (mpic->irq_offset + mpic->irq_count)) { + if (is_ipi) + *is_ipi = 0; + return mpic; + } + mpic = mpic -> next; + } + return NULL; +} + +/* Convert a cpu mask from logical to physical cpu numbers. */ +static inline u32 mpic_physmask(u32 cpumask) +{ + int i; + u32 mask = 0; + + for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1) + mask |= (cpumask & 1) << get_hard_smp_processor_id(i); + return mask; +} + +#ifdef CONFIG_SMP +/* Get the mpic structure from the IPI number */ +static inline struct mpic * mpic_from_ipi(unsigned int ipi) +{ + return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); +} +#endif + +/* Get the mpic structure from the irq number */ +static inline struct mpic * mpic_from_irq(unsigned int irq) +{ + return container_of(irq_desc[irq].handler, struct mpic, hc_irq); +} + +/* Send an EOI */ +static inline void mpic_eoi(struct mpic *mpic) +{ + mpic_cpu_write(MPIC_CPU_EOI, 0); + (void)mpic_cpu_read(MPIC_CPU_WHOAMI); +} + +#ifdef CONFIG_SMP +static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) +{ + struct mpic *mpic = dev_id; + + smp_message_recv(irq - mpic->ipi_offset, regs); + return IRQ_HANDLED; +} +#endif /* CONFIG_SMP */ + +/* + * Linux descriptor level callbacks + */ + + +static void mpic_enable_irq(unsigned int irq) +{ + unsigned int loops = 100000; + struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = irq - mpic->irq_offset; + + DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src); + + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, + mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); + + /* make sure mask gets to controller before we return to user */ + do { + if (!loops--) { + printk(KERN_ERR "mpic_enable_irq timeout\n"); + break; + } + } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); +} + +static void mpic_disable_irq(unsigned int irq) +{ + unsigned int loops = 100000; + struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = irq - mpic->irq_offset; + + DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); + + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, + mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK); + + /* make sure mask gets to controller before we return to user */ + do { + if (!loops--) { + printk(KERN_ERR "mpic_enable_irq timeout\n"); + break; + } + } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); +} + +static void mpic_end_irq(unsigned int irq) +{ + struct mpic *mpic = mpic_from_irq(irq); + + DBG("%s: end_irq: %d\n", mpic->name, irq); + + /* We always EOI on end_irq() even for edge interrupts since that + * should only lower the priority, the MPIC should have properly + * latched another edge interrupt coming in anyway + */ + +#ifdef CONFIG_MPIC_BROKEN_U3 + if (mpic->flags & MPIC_BROKEN_U3) { + unsigned int src = irq - mpic->irq_offset; + if (mpic_is_ht_interrupt(mpic, src)) + mpic_apic_end_irq(mpic, src); + } +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + mpic_eoi(mpic); +} + +#ifdef CONFIG_SMP + +static void mpic_enable_ipi(unsigned int irq) +{ + struct mpic *mpic = mpic_from_ipi(irq); + unsigned int src = irq - mpic->ipi_offset; + + DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src); + mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK); +} + +static void mpic_disable_ipi(unsigned int irq) +{ + /* NEVER disable an IPI... that's just plain wrong! */ +} + +static void mpic_end_ipi(unsigned int irq) +{ + struct mpic *mpic = mpic_from_ipi(irq); + + /* + * IPIs are marked IRQ_PER_CPU. This has the side effect of + * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from + * applying to them. We EOI them late to avoid re-entering. + * We mark IPI's with SA_INTERRUPT as they must run with + * irqs disabled. + */ + mpic_eoi(mpic); +} + +#endif /* CONFIG_SMP */ + +static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) +{ + struct mpic *mpic = mpic_from_irq(irq); + + cpumask_t tmp; + + cpus_and(tmp, cpumask, cpu_online_map); + + mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION, + mpic_physmask(cpus_addr(tmp)[0])); +} + + +/* + * Exported functions + */ + + +struct mpic * __init mpic_alloc(unsigned long phys_addr, + unsigned int flags, + unsigned int isu_size, + unsigned int irq_offset, + unsigned int irq_count, + unsigned int ipi_offset, + unsigned char *senses, + unsigned int senses_count, + const char *name) +{ + struct mpic *mpic; + u32 reg; + const char *vers; + int i; + + mpic = alloc_bootmem(sizeof(struct mpic)); + if (mpic == NULL) + return NULL; + + + memset(mpic, 0, sizeof(struct mpic)); + mpic->name = name; + + mpic->hc_irq.typename = name; + mpic->hc_irq.enable = mpic_enable_irq; + mpic->hc_irq.disable = mpic_disable_irq; + mpic->hc_irq.end = mpic_end_irq; + if (flags & MPIC_PRIMARY) + mpic->hc_irq.set_affinity = mpic_set_affinity; +#ifdef CONFIG_SMP + mpic->hc_ipi.typename = name; + mpic->hc_ipi.enable = mpic_enable_ipi; + mpic->hc_ipi.disable = mpic_disable_ipi; + mpic->hc_ipi.end = mpic_end_ipi; +#endif /* CONFIG_SMP */ + + mpic->flags = flags; + mpic->isu_size = isu_size; + mpic->irq_offset = irq_offset; + mpic->irq_count = irq_count; + mpic->ipi_offset = ipi_offset; + mpic->num_sources = 0; /* so far */ + mpic->senses = senses; + mpic->senses_count = senses_count; + + /* Map the global registers */ + mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); + mpic->tmregs = mpic->gregs + (MPIC_TIMER_BASE >> 2); + BUG_ON(mpic->gregs == NULL); + + /* Reset */ + if (flags & MPIC_WANTS_RESET) { + mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, + mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + | MPIC_GREG_GCONF_RESET); + while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + & MPIC_GREG_GCONF_RESET) + mb(); + } + + /* Read feature register, calculate num CPUs and, for non-ISU + * MPICs, num sources as well. On ISU MPICs, sources are counted + * as ISUs are added + */ + reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0); + mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) + >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; + if (isu_size == 0) + mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK) + >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; + + /* Map the per-CPU registers */ + for (i = 0; i < mpic->num_cpus; i++) { + mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE + + i * MPIC_CPU_STRIDE, 0x1000); + BUG_ON(mpic->cpuregs[i] == NULL); + } + + /* Initialize main ISU if none provided */ + if (mpic->isu_size == 0) { + mpic->isu_size = mpic->num_sources; + mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE, + MPIC_IRQ_STRIDE * mpic->isu_size); + BUG_ON(mpic->isus[0] == NULL); + } + mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); + mpic->isu_mask = (1 << mpic->isu_shift) - 1; + + /* Display version */ + switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) { + case 1: + vers = "1.0"; + break; + case 2: + vers = "1.2"; + break; + case 3: + vers = "1.3"; + break; + default: + vers = ""; + break; + } + printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n", + name, vers, phys_addr, mpic->num_cpus); + printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size, + mpic->isu_shift, mpic->isu_mask); + + mpic->next = mpics; + mpics = mpic; + + if (flags & MPIC_PRIMARY) + mpic_primary = mpic; + + return mpic; +} + +void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, + unsigned long phys_addr) +{ + unsigned int isu_first = isu_num * mpic->isu_size; + + BUG_ON(isu_num >= MPIC_MAX_ISU); + + mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size); + if ((isu_first + mpic->isu_size) > mpic->num_sources) + mpic->num_sources = isu_first + mpic->isu_size; +} + +void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler, + void *data) +{ + struct mpic *mpic = mpic_find(irq, NULL); + unsigned long flags; + + /* Synchronization here is a bit dodgy, so don't try to replace cascade + * interrupts on the fly too often ... but normally it's set up at boot. + */ + spin_lock_irqsave(&mpic_lock, flags); + if (mpic->cascade) + mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset); + mpic->cascade = NULL; + wmb(); + mpic->cascade_vec = irq - mpic->irq_offset; + mpic->cascade_data = data; + wmb(); + mpic->cascade = handler; + mpic_enable_irq(irq); + spin_unlock_irqrestore(&mpic_lock, flags); +} + +void __init mpic_init(struct mpic *mpic) +{ + int i; + + BUG_ON(mpic->num_sources == 0); + + printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); + + /* Set current processor priority to max */ + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); + + /* Initialize timers: just disable them all */ + for (i = 0; i < 4; i++) { + mpic_write(mpic->tmregs, + i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0); + mpic_write(mpic->tmregs, + i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI, + MPIC_VECPRI_MASK | + (MPIC_VEC_TIMER_0 + i)); + } + + /* Initialize IPIs to our reserved vectors and mark them disabled for now */ + mpic_test_broken_ipi(mpic); + for (i = 0; i < 4; i++) { + mpic_ipi_write(i, + MPIC_VECPRI_MASK | + (10 << MPIC_VECPRI_PRIORITY_SHIFT) | + (MPIC_VEC_IPI_0 + i)); +#ifdef CONFIG_SMP + if (!(mpic->flags & MPIC_PRIMARY)) + continue; + irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; + irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; + +#endif /* CONFIG_SMP */ + } + + /* Initialize interrupt sources */ + if (mpic->irq_count == 0) + mpic->irq_count = mpic->num_sources; + +#ifdef CONFIG_MPIC_BROKEN_U3 + /* Do the ioapic fixups on U3 broken mpic */ + DBG("MPIC flags: %x\n", mpic->flags); + if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) + mpic_scan_ioapics(mpic); +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + for (i = 0; i < mpic->num_sources; i++) { + /* start with vector = source number, and masked */ + u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT); + int level = 0; + + /* if it's an IPI, we skip it */ + if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) && + (mpic->irq_offset + i) < (mpic->ipi_offset + i + 4)) + continue; + + /* do senses munging */ + if (mpic->senses && i < mpic->senses_count) { + if (mpic->senses[i] & IRQ_SENSE_LEVEL) + vecpri |= MPIC_VECPRI_SENSE_LEVEL; + if (mpic->senses[i] & IRQ_POLARITY_POSITIVE) + vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; + } else + vecpri |= MPIC_VECPRI_SENSE_LEVEL; + + /* remember if it was a level interrupts */ + level = (vecpri & MPIC_VECPRI_SENSE_LEVEL); + + /* deal with broken U3 */ + if (mpic->flags & MPIC_BROKEN_U3) { +#ifdef CONFIG_MPIC_BROKEN_U3 + if (mpic_is_ht_interrupt(mpic, i)) { + vecpri &= ~(MPIC_VECPRI_SENSE_MASK | + MPIC_VECPRI_POLARITY_MASK); + vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; + } +#else + printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n"); +#endif + } + + DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri, + (level != 0)); + + /* init hw */ + mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri); + mpic_irq_write(i, MPIC_IRQ_DESTINATION, + 1 << hard_smp_processor_id()); + + /* init linux descriptors */ + if (i < mpic->irq_count) { + irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; + irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; + } + } + + /* Init spurrious vector */ + mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS); + + /* Disable 8259 passthrough */ + mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, + mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + | MPIC_GREG_GCONF_8259_PTHROU_DIS); + + /* Set current processor priority to 0 */ + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); +} + + + +void mpic_irq_set_priority(unsigned int irq, unsigned int pri) +{ + int is_ipi; + struct mpic *mpic = mpic_find(irq, &is_ipi); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&mpic_lock, flags); + if (is_ipi) { + reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK; + mpic_ipi_write(irq - mpic->ipi_offset, + reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); + } else { + reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI) + & MPIC_VECPRI_PRIORITY_MASK; + mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI, + reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); + } + spin_unlock_irqrestore(&mpic_lock, flags); +} + +unsigned int mpic_irq_get_priority(unsigned int irq) +{ + int is_ipi; + struct mpic *mpic = mpic_find(irq, &is_ipi); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&mpic_lock, flags); + if (is_ipi) + reg = mpic_ipi_read(irq - mpic->ipi_offset); + else + reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI); + spin_unlock_irqrestore(&mpic_lock, flags); + return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; +} + +void mpic_setup_this_cpu(void) +{ +#ifdef CONFIG_SMP + struct mpic *mpic = mpic_primary; + unsigned long flags; + u32 msk = 1 << hard_smp_processor_id(); + unsigned int i; + + BUG_ON(mpic == NULL); + + DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); + + spin_lock_irqsave(&mpic_lock, flags); + + /* let the mpic know we want intrs. default affinity is 0xffffffff + * until changed via /proc. That's how it's done on x86. If we want + * it differently, then we should make sure we also change the default + * values of irq_affinity in irq.c. + */ + if (distribute_irqs) { + for (i = 0; i < mpic->num_sources ; i++) + mpic_irq_write(i, MPIC_IRQ_DESTINATION, + mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk); + } + + /* Set current processor priority to 0 */ + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); + + spin_unlock_irqrestore(&mpic_lock, flags); +#endif /* CONFIG_SMP */ +} + +int mpic_cpu_get_priority(void) +{ + struct mpic *mpic = mpic_primary; + + return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI); +} + +void mpic_cpu_set_priority(int prio) +{ + struct mpic *mpic = mpic_primary; + + prio &= MPIC_CPU_TASKPRI_MASK; + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio); +} + +/* + * XXX: someone who knows mpic should check this. + * do we need to eoi the ipi including for kexec cpu here (see xics comments)? + * or can we reset the mpic in the new kernel? + */ +void mpic_teardown_this_cpu(int secondary) +{ + struct mpic *mpic = mpic_primary; + unsigned long flags; + u32 msk = 1 << hard_smp_processor_id(); + unsigned int i; + + BUG_ON(mpic == NULL); + + DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); + spin_lock_irqsave(&mpic_lock, flags); + + /* let the mpic know we don't want intrs. */ + for (i = 0; i < mpic->num_sources ; i++) + mpic_irq_write(i, MPIC_IRQ_DESTINATION, + mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); + + /* Set current processor priority to max */ + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); + + spin_unlock_irqrestore(&mpic_lock, flags); +} + + +void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) +{ + struct mpic *mpic = mpic_primary; + + BUG_ON(mpic == NULL); + + DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); + + mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, + mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); +} + +int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) +{ + u32 irq; + + irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; + DBG("%s: get_one_irq(): %d\n", mpic->name, irq); + + if (mpic->cascade && irq == mpic->cascade_vec) { + DBG("%s: cascading ...\n", mpic->name); + irq = mpic->cascade(regs, mpic->cascade_data); + mpic_eoi(mpic); + return irq; + } + if (unlikely(irq == MPIC_VEC_SPURRIOUS)) + return -1; + if (irq < MPIC_VEC_IPI_0) + return irq + mpic->irq_offset; + DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0); + return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset; +} + +int mpic_get_irq(struct pt_regs *regs) +{ + struct mpic *mpic = mpic_primary; + + BUG_ON(mpic == NULL); + + return mpic_get_one_irq(mpic, regs); +} + + +#ifdef CONFIG_SMP +void mpic_request_ipis(void) +{ + struct mpic *mpic = mpic_primary; + + BUG_ON(mpic == NULL); + + printk("requesting IPIs ... \n"); + + /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */ + request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT, + "IPI0 (call function)", mpic); + request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT, + "IPI1 (reschedule)", mpic); + request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT, + "IPI2 (unused)", mpic); + request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT, + "IPI3 (debugger break)", mpic); + + printk("IPIs requested... \n"); +} +#endif /* CONFIG_SMP */ diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index ce166e3de53b..0649540bc7d9 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -1,6 +1,7 @@ # # Makefile for the linux kernel. # +ifneq ($(CONFIG_PPC_MERGE),y) extra-$(CONFIG_PPC_STD_MMU) := head.o extra-$(CONFIG_40x) := head_4xx.o @@ -37,3 +38,23 @@ endif # These are here while we do the architecture merge vecemu-y += ../../powerpc/kernel/vecemu.o + +else +obj-y := entry.o irq.o idle.o time.o misc.o \ + signal.o ptrace.o align.o \ + syscalls.o setup.o \ + cputable.o perfmon.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_POWER4) += cpu_setup_power4.o +obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_KGDB) += ppc-stub.o +obj-$(CONFIG_SMP) += smp.o smp-tbsync.o +obj-$(CONFIG_TAU) += temp.o +ifndef CONFIG_E200 +obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o +endif +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o +endif diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 77fecfbabe88..1b891b806f3d 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -83,6 +83,8 @@ extern void pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); extern void chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); + +dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ #ifdef CONFIG_MAGIC_SYSRQ @@ -405,11 +407,13 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, _machine = _MACH_prep; } +#ifdef CONFIG_PPC_PREP /* not much more to do here, if prep */ if (_machine == _MACH_prep) { prep_init(r3, r4, r5, r6, r7); return; } +#endif /* prom_init has already been called from __start */ if (boot_infos) @@ -480,12 +484,16 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif /* CONFIG_ADB */ switch (_machine) { +#ifdef CONFIG_PPC_PMAC case _MACH_Pmac: pmac_init(r3, r4, r5, r6, r7); break; +#endif +#ifdef CONFIG_PPC_CHRP case _MACH_chrp: chrp_init(r3, r4, r5, r6, r7); break; +#endif } } diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index fccafbcd4b58..8bc734fe6682 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -89,9 +89,6 @@ extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi #define cached_21 (((char *)(ppc_cached_irq_mask))[3]) #define cached_A1 (((char *)(ppc_cached_irq_mask))[2]) -/* for the mac fs */ -dev_t boot_dev; - #ifdef CONFIG_SOUND_CS4232 long ppc_cs4232_dma, ppc_cs4232_dma2; #endif diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index b8d08f33f7ee..1b0a84931afc 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -5,6 +5,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC +ifneq ($(CONFIG_PPC_MERGE),y) wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o @@ -109,3 +110,16 @@ obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \ ifeq ($(CONFIG_PPC_MPC52xx),y) obj-$(CONFIG_PCI) += mpc52xx_pci.o endif + +else +# Stuff still needed by the merged powerpc sources + +obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o +obj-$(CONFIG_PPC_PMAC) += indirect_pci.o +obj-$(CONFIG_PPC_CHRP) += indirect_pci.o i8259.o +obj-$(CONFIG_PPC_PREP) += indirect_pci.o i8259.o todc_time.o +obj-$(CONFIG_BOOTX_TEXT) += btext.o +obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o + +endif diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 76719451e384..503461884528 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -405,7 +405,7 @@ static int __init via_pmu_start(void) bright_req_2.complete = 1; batt_req.complete = 1; -#ifdef CONFIG_PPC32 +#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE) if (pmu_kind == PMU_KEYLARGO_BASED) openpic_set_irq_priority(vias->intrs[0].line, OPENPIC_PRIORITY_DEFAULT + 1); diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index a3453555a94e..5b6b0b6038a7 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -629,12 +629,4 @@ void __init proc_misc_init(void) if (entry) entry->proc_fops = &proc_sysrq_trigger_operations; #endif -#ifdef CONFIG_PPC32 - { - extern struct file_operations ppc_htab_operations; - entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL); - if (entry) - entry->proc_fops = &ppc_htab_operations; - } -#endif } diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h new file mode 100644 index 000000000000..7c55abf597f6 --- /dev/null +++ b/include/asm-powerpc/kdebug.h @@ -0,0 +1,42 @@ +#ifndef _POWERPC_KDEBUG_H +#define _POWERPC_KDEBUG_H 1 + +/* nearly identical to x86_64/i386 code */ + +#include + +struct pt_regs; + +struct die_args { + struct pt_regs *regs; + const char *str; + long err; + int trapnr; + int signr; +}; + +/* + Note - you should never unregister because that can race with NMIs. + If you really want to do it first unregister - then synchronize_sched - + then free. + */ +int register_die_notifier(struct notifier_block *nb); +extern struct notifier_block *powerpc_die_chain; + +/* Grossly misnamed. */ +enum die_val { + DIE_OOPS = 1, + DIE_IABR_MATCH, + DIE_DABR_MATCH, + DIE_BPT, + DIE_SSTEP, + DIE_PAGE_FAULT, +}; + +static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) +{ + struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; + return notifier_call_chain(&powerpc_die_chain, val, &args); +} + +#endif diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h new file mode 100644 index 000000000000..d9129d2b038e --- /dev/null +++ b/include/asm-powerpc/kprobes.h @@ -0,0 +1,67 @@ +#ifndef _ASM_KPROBES_H +#define _ASM_KPROBES_H +/* + * Kernel Probes (KProbes) + * include/asm-ppc64/kprobes.h + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2002, 2004 + * + * 2002-Oct Created by Vamsi Krishna S Kernel + * Probes initial implementation ( includes suggestions from + * Rusty Russell). + * 2004-Nov Modified for PPC64 by Ananth N Mavinakayanahalli + * + */ +#include +#include + +struct pt_regs; + +typedef unsigned int kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ +#define MAX_INSN_SIZE 1 + +#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008) +#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088) +#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) +#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) + +#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) + +#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ + IS_TWI(instr) || IS_TDI(instr)) + +#define ARCH_SUPPORTS_KRETPROBES +void kretprobe_trampoline(void); + +/* Architecture specific copy of original instruction */ +struct arch_specific_insn { + /* copy of original instruction */ + kprobe_opcode_t *insn; +}; + +#ifdef CONFIG_KPROBES +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); +#else /* !CONFIG_KPROBES */ +static inline int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data) +{ + return 0; +} +#endif +#endif /* _ASM_KPROBES_H */ diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h new file mode 100644 index 000000000000..f1e24f4b2d1c --- /dev/null +++ b/include/asm-powerpc/mpic.h @@ -0,0 +1,279 @@ +#include + +/* + * Global registers + */ + +#define MPIC_GREG_BASE 0x01000 + +#define MPIC_GREG_FEATURE_0 0x00000 +#define MPIC_GREG_FEATURE_LAST_SRC_MASK 0x07ff0000 +#define MPIC_GREG_FEATURE_LAST_SRC_SHIFT 16 +#define MPIC_GREG_FEATURE_LAST_CPU_MASK 0x00001f00 +#define MPIC_GREG_FEATURE_LAST_CPU_SHIFT 8 +#define MPIC_GREG_FEATURE_VERSION_MASK 0xff +#define MPIC_GREG_FEATURE_1 0x00010 +#define MPIC_GREG_GLOBAL_CONF_0 0x00020 +#define MPIC_GREG_GCONF_RESET 0x80000000 +#define MPIC_GREG_GCONF_8259_PTHROU_DIS 0x20000000 +#define MPIC_GREG_GCONF_BASE_MASK 0x000fffff +#define MPIC_GREG_GLOBAL_CONF_1 0x00030 +#define MPIC_GREG_VENDOR_0 0x00040 +#define MPIC_GREG_VENDOR_1 0x00050 +#define MPIC_GREG_VENDOR_2 0x00060 +#define MPIC_GREG_VENDOR_3 0x00070 +#define MPIC_GREG_VENDOR_ID 0x00080 +#define MPIC_GREG_VENDOR_ID_STEPPING_MASK 0x00ff0000 +#define MPIC_GREG_VENDOR_ID_STEPPING_SHIFT 16 +#define MPIC_GREG_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00 +#define MPIC_GREG_VENDOR_ID_DEVICE_ID_SHIFT 8 +#define MPIC_GREG_VENDOR_ID_VENDOR_ID_MASK 0x000000ff +#define MPIC_GREG_PROCESSOR_INIT 0x00090 +#define MPIC_GREG_IPI_VECTOR_PRI_0 0x000a0 +#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0 +#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0 +#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0 +#define MPIC_GREG_SPURIOUS 0x000e0 +#define MPIC_GREG_TIMER_FREQ 0x000f0 + +/* + * + * Timer registers + */ +#define MPIC_TIMER_BASE 0x01100 +#define MPIC_TIMER_STRIDE 0x40 + +#define MPIC_TIMER_CURRENT_CNT 0x00000 +#define MPIC_TIMER_BASE_CNT 0x00010 +#define MPIC_TIMER_VECTOR_PRI 0x00020 +#define MPIC_TIMER_DESTINATION 0x00030 + +/* + * Per-Processor registers + */ + +#define MPIC_CPU_THISBASE 0x00000 +#define MPIC_CPU_BASE 0x20000 +#define MPIC_CPU_STRIDE 0x01000 + +#define MPIC_CPU_IPI_DISPATCH_0 0x00040 +#define MPIC_CPU_IPI_DISPATCH_1 0x00050 +#define MPIC_CPU_IPI_DISPATCH_2 0x00060 +#define MPIC_CPU_IPI_DISPATCH_3 0x00070 +#define MPIC_CPU_CURRENT_TASK_PRI 0x00080 +#define MPIC_CPU_TASKPRI_MASK 0x0000000f +#define MPIC_CPU_WHOAMI 0x00090 +#define MPIC_CPU_WHOAMI_MASK 0x0000001f +#define MPIC_CPU_INTACK 0x000a0 +#define MPIC_CPU_EOI 0x000b0 + +/* + * Per-source registers + */ + +#define MPIC_IRQ_BASE 0x10000 +#define MPIC_IRQ_STRIDE 0x00020 +#define MPIC_IRQ_VECTOR_PRI 0x00000 +#define MPIC_VECPRI_MASK 0x80000000 +#define MPIC_VECPRI_ACTIVITY 0x40000000 /* Read Only */ +#define MPIC_VECPRI_PRIORITY_MASK 0x000f0000 +#define MPIC_VECPRI_PRIORITY_SHIFT 16 +#define MPIC_VECPRI_VECTOR_MASK 0x000007ff +#define MPIC_VECPRI_POLARITY_POSITIVE 0x00800000 +#define MPIC_VECPRI_POLARITY_NEGATIVE 0x00000000 +#define MPIC_VECPRI_POLARITY_MASK 0x00800000 +#define MPIC_VECPRI_SENSE_LEVEL 0x00400000 +#define MPIC_VECPRI_SENSE_EDGE 0x00000000 +#define MPIC_VECPRI_SENSE_MASK 0x00400000 +#define MPIC_IRQ_DESTINATION 0x00010 + +#define MPIC_MAX_IRQ_SOURCES 2048 +#define MPIC_MAX_CPUS 32 +#define MPIC_MAX_ISU 32 + +/* + * Special vector numbers (internal use only) + */ +#define MPIC_VEC_SPURRIOUS 255 +#define MPIC_VEC_IPI_3 254 +#define MPIC_VEC_IPI_2 253 +#define MPIC_VEC_IPI_1 252 +#define MPIC_VEC_IPI_0 251 + +/* unused */ +#define MPIC_VEC_TIMER_3 250 +#define MPIC_VEC_TIMER_2 249 +#define MPIC_VEC_TIMER_1 248 +#define MPIC_VEC_TIMER_0 247 + +/* Type definition of the cascade handler */ +typedef int (*mpic_cascade_t)(struct pt_regs *regs, void *data); + +#ifdef CONFIG_MPIC_BROKEN_U3 +/* Fixup table entry */ +struct mpic_irq_fixup +{ + u8 __iomem *base; + unsigned int irq; +}; +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + +/* The instance data of a given MPIC */ +struct mpic +{ + /* The "linux" controller struct */ + hw_irq_controller hc_irq; +#ifdef CONFIG_SMP + hw_irq_controller hc_ipi; +#endif + const char *name; + /* Flags */ + unsigned int flags; + /* How many irq sources in a given ISU */ + unsigned int isu_size; + unsigned int isu_shift; + unsigned int isu_mask; + /* Offset of irq vector numbers */ + unsigned int irq_offset; + unsigned int irq_count; + /* Offset of ipi vector numbers */ + unsigned int ipi_offset; + /* Number of sources */ + unsigned int num_sources; + /* Number of CPUs */ + unsigned int num_cpus; + /* cascade handler */ + mpic_cascade_t cascade; + void *cascade_data; + unsigned int cascade_vec; + /* senses array */ + unsigned char *senses; + unsigned int senses_count; + +#ifdef CONFIG_MPIC_BROKEN_U3 + /* The fixup table */ + struct mpic_irq_fixup *fixups; + spinlock_t fixup_lock; +#endif + + /* The various ioremap'ed bases */ + volatile u32 __iomem *gregs; + volatile u32 __iomem *tmregs; + volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; + volatile u32 __iomem *isus[MPIC_MAX_ISU]; + + /* link */ + struct mpic *next; +}; + +/* This is the primary controller, only that one has IPIs and + * has afinity control. A non-primary MPIC always uses CPU0 + * registers only + */ +#define MPIC_PRIMARY 0x00000001 +/* Set this for a big-endian MPIC */ +#define MPIC_BIG_ENDIAN 0x00000002 +/* Broken U3 MPIC */ +#define MPIC_BROKEN_U3 0x00000004 +/* Broken IPI registers (autodetected) */ +#define MPIC_BROKEN_IPI 0x00000008 +/* MPIC wants a reset */ +#define MPIC_WANTS_RESET 0x00000010 + +/* Allocate the controller structure and setup the linux irq descs + * for the range if interrupts passed in. No HW initialization is + * actually performed. + * + * @phys_addr: physial base address of the MPIC + * @flags: flags, see constants above + * @isu_size: number of interrupts in an ISU. Use 0 to use a + * standard ISU-less setup (aka powermac) + * @irq_offset: first irq number to assign to this mpic + * @irq_count: number of irqs to use with this mpic IRQ sources. Pass 0 + * to match the number of sources + * @ipi_offset: first irq number to assign to this mpic IPI sources, + * used only on primary mpic + * @senses: array of sense values + * @senses_num: number of entries in the array + * + * Note about the sense array. If none is passed, all interrupts are + * setup to be level negative unless MPIC_BROKEN_U3 is set in which + * case they are edge positive (and the array is ignored anyway). + * The values in the array start at the first source of the MPIC, + * that is senses[0] correspond to linux irq "irq_offset". + */ +extern struct mpic *mpic_alloc(unsigned long phys_addr, + unsigned int flags, + unsigned int isu_size, + unsigned int irq_offset, + unsigned int irq_count, + unsigned int ipi_offset, + unsigned char *senses, + unsigned int senses_num, + const char *name); + +/* Assign ISUs, to call before mpic_init() + * + * @mpic: controller structure as returned by mpic_alloc() + * @isu_num: ISU number + * @phys_addr: physical address of the ISU + */ +extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, + unsigned long phys_addr); + +/* Initialize the controller. After this has been called, none of the above + * should be called again for this mpic + */ +extern void mpic_init(struct mpic *mpic); + +/* Setup a cascade. Currently, only one cascade is supported this + * way, though you can always do a normal request_irq() and add + * other cascades this way. You should call this _after_ having + * added all the ISUs + * + * @irq_no: "linux" irq number of the cascade (that is offset'ed vector) + * @handler: cascade handler function + */ +extern void mpic_setup_cascade(unsigned int irq_no, mpic_cascade_t hanlder, + void *data); + +/* + * All of the following functions must only be used after the + * ISUs have been assigned and the controller fully initialized + * with mpic_init() + */ + + +/* Change/Read the priority of an interrupt. Default is 8 for irqs and + * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the + * IPI number is then the offset'ed (linux irq number mapped to the IPI) + */ +extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri); +extern unsigned int mpic_irq_get_priority(unsigned int irq); + +/* Setup a non-boot CPU */ +extern void mpic_setup_this_cpu(void); + +/* Clean up for kexec (or cpu offline or ...) */ +extern void mpic_teardown_this_cpu(int secondary); + +/* Get the current cpu priority for this cpu (0..15) */ +extern int mpic_cpu_get_priority(void); + +/* Set the current cpu priority for this cpu */ +extern void mpic_cpu_set_priority(int prio); + +/* Request IPIs on primary mpic */ +extern void mpic_request_ipis(void); + +/* Send an IPI (non offseted number 0..3) */ +extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask); + +/* Fetch interrupt from a given mpic */ +extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); +/* This one gets to the primary mpic */ +extern int mpic_get_irq(struct pt_regs *regs); + +/* global mpic for pSeries */ +extern struct mpic *pSeries_mpic; diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h new file mode 100644 index 000000000000..f97a5f1761b4 --- /dev/null +++ b/include/asm-powerpc/reg.h @@ -0,0 +1,446 @@ +/* + * Contains the definition of registers common to all PowerPC variants. + * If a register definition has been changed in a different PowerPC + * variant, we will case it in #ifndef XXX ... #endif, and have the + * number used in the Programming Environments Manual For 32-Bit + * Implementations of the PowerPC Architecture (a.k.a. Green Book) here. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_PPC_REGS_H__ +#define __ASM_PPC_REGS_H__ + +#include + +/* Pickup Book E specific registers. */ +#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) +#include +#endif + +/* Machine State Register (MSR) Fields */ +#define MSR_SF (1<<63) +#define MSR_ISF (1<<61) +#define MSR_VEC (1<<25) /* Enable AltiVec */ +#define MSR_POW (1<<18) /* Enable Power Management */ +#define MSR_WE (1<<18) /* Wait State Enable */ +#define MSR_TGPR (1<<17) /* TLB Update registers in use */ +#define MSR_CE (1<<17) /* Critical Interrupt Enable */ +#define MSR_ILE (1<<16) /* Interrupt Little Endian */ +#define MSR_EE (1<<15) /* External Interrupt Enable */ +#define MSR_PR (1<<14) /* Problem State / Privilege Level */ +#define MSR_FP (1<<13) /* Floating Point enable */ +#define MSR_ME (1<<12) /* Machine Check Enable */ +#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ +#define MSR_SE (1<<10) /* Single Step */ +#define MSR_BE (1<<9) /* Branch Trace */ +#define MSR_DE (1<<9) /* Debug Exception Enable */ +#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ +#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ +#define MSR_IR (1<<5) /* Instruction Relocate */ +#define MSR_DR (1<<4) /* Data Relocate */ +#define MSR_PE (1<<3) /* Protection Enable */ +#define MSR_PX (1<<2) /* Protection Exclusive Mode */ +#define MSR_RI (1<<1) /* Recoverable Exception */ +#define MSR_LE (1<<0) /* Little Endian */ + +/* Default MSR for kernel mode. */ +#ifdef CONFIG_APUS_FAST_EXCEPT +#define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR) +#endif + +#ifndef MSR_KERNEL +#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) +#endif + +#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) + +/* Floating Point Status and Control Register (FPSCR) Fields */ +#define FPSCR_FX 0x80000000 /* FPU exception summary */ +#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */ +#define FPSCR_VX 0x20000000 /* Invalid operation summary */ +#define FPSCR_OX 0x10000000 /* Overflow exception summary */ +#define FPSCR_UX 0x08000000 /* Underflow exception summary */ +#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */ +#define FPSCR_XX 0x02000000 /* Inexact exception summary */ +#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */ +#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */ +#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */ +#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */ +#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */ +#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */ +#define FPSCR_FR 0x00040000 /* Fraction rounded */ +#define FPSCR_FI 0x00020000 /* Fraction inexact */ +#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */ +#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */ +#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */ +#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */ +#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */ +#define FPSCR_VE 0x00000080 /* Invalid op exception enable */ +#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */ +#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */ +#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */ +#define FPSCR_XE 0x00000008 /* FP inexact exception enable */ +#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */ +#define FPSCR_RN 0x00000003 /* FPU rounding control */ + +/* Special Purpose Registers (SPRNs)*/ +#define SPRN_CTR 0x009 /* Count Register */ +#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ +#define DABR_TRANSLATION (1UL << 2) +#define SPRN_DAR 0x013 /* Data Address Register */ +#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ +#define DSISR_NOHPTE 0x40000000 /* no translation found */ +#define DSISR_PROTFAULT 0x08000000 /* protection fault */ +#define DSISR_ISSTORE 0x02000000 /* access was a store */ +#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ +#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ +#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ +#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ +#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ +#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ +#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ +#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ +#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ +#define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */ +#define SPRN_DBAT1U 0x21A /* Data BAT 1 Upper Register */ +#define SPRN_DBAT2L 0x21D /* Data BAT 2 Lower Register */ +#define SPRN_DBAT2U 0x21C /* Data BAT 2 Upper Register */ +#define SPRN_DBAT3L 0x21F /* Data BAT 3 Lower Register */ +#define SPRN_DBAT3U 0x21E /* Data BAT 3 Upper Register */ +#define SPRN_DBAT4L 0x239 /* Data BAT 4 Lower Register */ +#define SPRN_DBAT4U 0x238 /* Data BAT 4 Upper Register */ +#define SPRN_DBAT5L 0x23B /* Data BAT 5 Lower Register */ +#define SPRN_DBAT5U 0x23A /* Data BAT 5 Upper Register */ +#define SPRN_DBAT6L 0x23D /* Data BAT 6 Lower Register */ +#define SPRN_DBAT6U 0x23C /* Data BAT 6 Upper Register */ +#define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */ +#define SPRN_DBAT7U 0x23E /* Data BAT 7 Upper Register */ + +#define SPRN_DEC 0x016 /* Decrement Register */ +#define SPRN_DER 0x095 /* Debug Enable Regsiter */ +#define DER_RSTE 0x40000000 /* Reset Interrupt */ +#define DER_CHSTPE 0x20000000 /* Check Stop */ +#define DER_MCIE 0x10000000 /* Machine Check Interrupt */ +#define DER_EXTIE 0x02000000 /* External Interrupt */ +#define DER_ALIE 0x01000000 /* Alignment Interrupt */ +#define DER_PRIE 0x00800000 /* Program Interrupt */ +#define DER_FPUVIE 0x00400000 /* FP Unavailable Interrupt */ +#define DER_DECIE 0x00200000 /* Decrementer Interrupt */ +#define DER_SYSIE 0x00040000 /* System Call Interrupt */ +#define DER_TRE 0x00020000 /* Trace Interrupt */ +#define DER_SEIE 0x00004000 /* FP SW Emulation Interrupt */ +#define DER_ITLBMSE 0x00002000 /* Imp. Spec. Instruction TLB Miss */ +#define DER_ITLBERE 0x00001000 /* Imp. Spec. Instruction TLB Error */ +#define DER_DTLBMSE 0x00000800 /* Imp. Spec. Data TLB Miss */ +#define DER_DTLBERE 0x00000400 /* Imp. Spec. Data TLB Error */ +#define DER_LBRKE 0x00000008 /* Load/Store Breakpoint Interrupt */ +#define DER_IBRKE 0x00000004 /* Instruction Breakpoint Interrupt */ +#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */ +#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */ +#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ +#define SPRN_EAR 0x11A /* External Address Register */ +#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ +#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ +#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ +#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ +#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ +#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ +#define HID0_SBCLK (1<<27) +#define HID0_EICE (1<<26) +#define HID0_TBEN (1<<26) /* Timebase enable - 745x */ +#define HID0_ECLK (1<<25) +#define HID0_PAR (1<<24) +#define HID0_STEN (1<<24) /* Software table search enable - 745x */ +#define HID0_HIGH_BAT (1<<23) /* Enable high BATs - 7455 */ +#define HID0_DOZE (1<<23) +#define HID0_NAP (1<<22) +#define HID0_SLEEP (1<<21) +#define HID0_DPM (1<<20) +#define HID0_BHTCLR (1<<18) /* Clear branch history table - 7450 */ +#define HID0_XAEN (1<<17) /* Extended addressing enable - 7450 */ +#define HID0_NHR (1<<16) /* Not hard reset (software bit-7450)*/ +#define HID0_ICE (1<<15) /* Instruction Cache Enable */ +#define HID0_DCE (1<<14) /* Data Cache Enable */ +#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ +#define HID0_DLOCK (1<<12) /* Data Cache Lock */ +#define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ +#define HID0_DCI (1<<10) /* Data Cache Invalidate */ +#define HID0_SPD (1<<9) /* Speculative disable */ +#define HID0_DAPUEN (1<<8) /* Debug APU enable */ +#define HID0_SGE (1<<7) /* Store Gathering Enable */ +#define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ +#define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ +#define HID0_LRSTK (1<<4) /* Link register stack - 745x */ +#define HID0_BTIC (1<<5) /* Branch Target Instr Cache Enable */ +#define HID0_ABE (1<<3) /* Address Broadcast Enable */ +#define HID0_FOLD (1<<3) /* Branch Folding enable - 745x */ +#define HID0_BHTE (1<<2) /* Branch History Table Enable */ +#define HID0_BTCD (1<<1) /* Branch target cache disable */ +#define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */ +#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ + +#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ +#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */ +#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */ +#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */ +#define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */ +#define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */ +#define HID1_PC3 (1<<13) /* 7450 PLL_CFG[3] */ +#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ +#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ +#define HID1_PS (1<<16) /* 750FX PLL selection */ +#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ +#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ +#define SPRN_HID4 0x3F4 /* 970 HID4 */ +#define SPRN_HID5 0x3F6 /* 970 HID5 */ +#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2) +#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ +#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ +#endif +#define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */ +#define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */ +#define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */ +#define SPRN_IBAT1U 0x212 /* Instruction BAT 1 Upper Register */ +#define SPRN_IBAT2L 0x215 /* Instruction BAT 2 Lower Register */ +#define SPRN_IBAT2U 0x214 /* Instruction BAT 2 Upper Register */ +#define SPRN_IBAT3L 0x217 /* Instruction BAT 3 Lower Register */ +#define SPRN_IBAT3U 0x216 /* Instruction BAT 3 Upper Register */ +#define SPRN_IBAT4L 0x231 /* Instruction BAT 4 Lower Register */ +#define SPRN_IBAT4U 0x230 /* Instruction BAT 4 Upper Register */ +#define SPRN_IBAT5L 0x233 /* Instruction BAT 5 Lower Register */ +#define SPRN_IBAT5U 0x232 /* Instruction BAT 5 Upper Register */ +#define SPRN_IBAT6L 0x235 /* Instruction BAT 6 Lower Register */ +#define SPRN_IBAT6U 0x234 /* Instruction BAT 6 Upper Register */ +#define SPRN_IBAT7L 0x237 /* Instruction BAT 7 Lower Register */ +#define SPRN_IBAT7U 0x236 /* Instruction BAT 7 Upper Register */ +#define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ +#define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ +#define SPRN_ICTRL 0x3F3 /* 1011 7450 icache and interrupt ctrl */ +#define ICTRL_EICE 0x08000000 /* enable icache parity errs */ +#define ICTRL_EDC 0x04000000 /* enable dcache parity errs */ +#define ICTRL_EICP 0x00000100 /* enable icache par. check */ +#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ +#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ +#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ +#define SPRN_L2CR2 0x3f8 +#define L2CR_L2E 0x80000000 /* L2 enable */ +#define L2CR_L2PE 0x40000000 /* L2 parity enable */ +#define L2CR_L2SIZ_MASK 0x30000000 /* L2 size mask */ +#define L2CR_L2SIZ_256KB 0x10000000 /* L2 size 256KB */ +#define L2CR_L2SIZ_512KB 0x20000000 /* L2 size 512KB */ +#define L2CR_L2SIZ_1MB 0x30000000 /* L2 size 1MB */ +#define L2CR_L2CLK_MASK 0x0e000000 /* L2 clock mask */ +#define L2CR_L2CLK_DISABLED 0x00000000 /* L2 clock disabled */ +#define L2CR_L2CLK_DIV1 0x02000000 /* L2 clock / 1 */ +#define L2CR_L2CLK_DIV1_5 0x04000000 /* L2 clock / 1.5 */ +#define L2CR_L2CLK_DIV2 0x08000000 /* L2 clock / 2 */ +#define L2CR_L2CLK_DIV2_5 0x0a000000 /* L2 clock / 2.5 */ +#define L2CR_L2CLK_DIV3 0x0c000000 /* L2 clock / 3 */ +#define L2CR_L2RAM_MASK 0x01800000 /* L2 RAM type mask */ +#define L2CR_L2RAM_FLOW 0x00000000 /* L2 RAM flow through */ +#define L2CR_L2RAM_PIPE 0x01000000 /* L2 RAM pipelined */ +#define L2CR_L2RAM_PIPE_LW 0x01800000 /* L2 RAM pipelined latewr */ +#define L2CR_L2DO 0x00400000 /* L2 data only */ +#define L2CR_L2I 0x00200000 /* L2 global invalidate */ +#define L2CR_L2CTL 0x00100000 /* L2 RAM control */ +#define L2CR_L2WT 0x00080000 /* L2 write-through */ +#define L2CR_L2TS 0x00040000 /* L2 test support */ +#define L2CR_L2OH_MASK 0x00030000 /* L2 output hold mask */ +#define L2CR_L2OH_0_5 0x00000000 /* L2 output hold 0.5 ns */ +#define L2CR_L2OH_1_0 0x00010000 /* L2 output hold 1.0 ns */ +#define L2CR_L2SL 0x00008000 /* L2 DLL slow */ +#define L2CR_L2DF 0x00004000 /* L2 differential clock */ +#define L2CR_L2BYP 0x00002000 /* L2 DLL bypass */ +#define L2CR_L2IP 0x00000001 /* L2 GI in progress */ +#define L2CR_L2IO_745x 0x00100000 /* L2 instr. only (745x) */ +#define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ +#define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ +#define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ +#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */ +#define L3CR_L3E 0x80000000 /* L3 enable */ +#define L3CR_L3PE 0x40000000 /* L3 data parity enable */ +#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ +#define L3CR_L3SIZ 0x10000000 /* L3 size */ +#define L3CR_L3CLKEN 0x08000000 /* L3 clock enable */ +#define L3CR_L3RES 0x04000000 /* L3 special reserved bit */ +#define L3CR_L3CLKDIV 0x03800000 /* L3 clock divisor */ +#define L3CR_L3IO 0x00400000 /* L3 instruction only */ +#define L3CR_L3SPO 0x00040000 /* L3 sample point override */ +#define L3CR_L3CKSP 0x00030000 /* L3 clock sample point */ +#define L3CR_L3PSP 0x0000e000 /* L3 P-clock sample point */ +#define L3CR_L3REP 0x00001000 /* L3 replacement algorithm */ +#define L3CR_L3HWF 0x00000800 /* L3 hardware flush */ +#define L3CR_L3I 0x00000400 /* L3 global invalidate */ +#define L3CR_L3RT 0x00000300 /* L3 SRAM type */ +#define L3CR_L3NIRCA 0x00000080 /* L3 non-integer ratio clock adj. */ +#define L3CR_L3DO 0x00000040 /* L3 data only mode */ +#define L3CR_PMEN 0x00000004 /* L3 private memory enable */ +#define L3CR_PMSIZ 0x00000001 /* L3 private memory size */ +#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */ +#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */ +#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */ +#define SPRN_LDSTDB 0x3f4 /* */ +#define SPRN_LR 0x008 /* Link Register */ +#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ +#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ +#ifndef SPRN_PIR +#define SPRN_PIR 0x3FF /* Processor Identification Register */ +#endif +#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ +#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ +#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ +#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ +#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ +#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ +#define SPRN_PVR 0x11F /* Processor Version Register */ +#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ +#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ +#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ +#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ +#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ +#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ +#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ +#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ +#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ +#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ +#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ +#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ +#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ +#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ +#ifndef SPRN_SVR +#define SPRN_SVR 0x11E /* System Version Register */ +#endif +#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ +/* these bits were defined in inverted endian sense originally, ugh, confusing */ +#define THRM1_TIN (1 << 31) +#define THRM1_TIV (1 << 30) +#define THRM1_THRES(x) ((x&0x7f)<<23) +#define THRM3_SITV(x) ((x&0x3fff)<<1) +#define THRM1_TID (1<<2) +#define THRM1_TIE (1<<1) +#define THRM1_V (1<<0) +#define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ +#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ +#define THRM3_E (1<<0) +#define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ +#define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */ +#define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */ +#define SPRN_UPMC1 0x3A9 /* User Performance Counter Register 1 */ +#define SPRN_UPMC2 0x3AA /* User Performance Counter Register 2 */ +#define SPRN_UPMC3 0x3AD /* User Performance Counter Register 3 */ +#define SPRN_UPMC4 0x3AE /* User Performance Counter Register 4 */ +#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ +#define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ +#define SPRN_XER 0x001 /* Fixed Point Exception Register */ + +/* Bit definitions for MMCR0 and PMC1 / PMC2. */ +#define MMCR0_PMC1_CYCLES (1 << 7) +#define MMCR0_PMC1_ICACHEMISS (5 << 7) +#define MMCR0_PMC1_DTLB (6 << 7) +#define MMCR0_PMC2_DCACHEMISS 0x6 +#define MMCR0_PMC2_CYCLES 0x1 +#define MMCR0_PMC2_ITLB 0x7 +#define MMCR0_PMC2_LOADMISSTIME 0x5 +#define MMCR0_PMXE (1 << 26) + +/* Processor Version Register */ + +/* Processor Version Register (PVR) field extraction */ + +#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ +#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ + +/* + * IBM has further subdivided the standard PowerPC 16-bit version and + * revision subfields of the PVR for the PowerPC 403s into the following: + */ + +#define PVR_FAM(pvr) (((pvr) >> 20) & 0xFFF) /* Family field */ +#define PVR_MEM(pvr) (((pvr) >> 16) & 0xF) /* Member field */ +#define PVR_CORE(pvr) (((pvr) >> 12) & 0xF) /* Core field */ +#define PVR_CFG(pvr) (((pvr) >> 8) & 0xF) /* Configuration field */ +#define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ +#define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ + +/* Processor Version Numbers */ + +#define PVR_403GA 0x00200000 +#define PVR_403GB 0x00200100 +#define PVR_403GC 0x00200200 +#define PVR_403GCX 0x00201400 +#define PVR_405GP 0x40110000 +#define PVR_STB03XXX 0x40310000 +#define PVR_NP405H 0x41410000 +#define PVR_NP405L 0x41610000 +#define PVR_601 0x00010000 +#define PVR_602 0x00050000 +#define PVR_603 0x00030000 +#define PVR_603e 0x00060000 +#define PVR_603ev 0x00070000 +#define PVR_603r 0x00071000 +#define PVR_604 0x00040000 +#define PVR_604e 0x00090000 +#define PVR_604r 0x000A0000 +#define PVR_620 0x00140000 +#define PVR_740 0x00080000 +#define PVR_750 PVR_740 +#define PVR_740P 0x10080000 +#define PVR_750P PVR_740P +#define PVR_7400 0x000C0000 +#define PVR_7410 0x800C0000 +#define PVR_7450 0x80000000 +#define PVR_8540 0x80200000 +#define PVR_8560 0x80200000 +/* + * For the 8xx processors, all of them report the same PVR family for + * the PowerPC core. The various versions of these processors must be + * differentiated by the version number in the Communication Processor + * Module (CPM). + */ +#define PVR_821 0x00500000 +#define PVR_823 PVR_821 +#define PVR_850 PVR_821 +#define PVR_860 PVR_821 +#define PVR_8240 0x00810100 +#define PVR_8245 0x80811014 +#define PVR_8260 PVR_8240 + +#if 0 +/* Segment Registers */ +#define SR0 0 +#define SR1 1 +#define SR2 2 +#define SR3 3 +#define SR4 4 +#define SR5 5 +#define SR6 6 +#define SR7 7 +#define SR8 8 +#define SR9 9 +#define SR10 10 +#define SR11 11 +#define SR12 12 +#define SR13 13 +#define SR14 14 +#define SR15 15 +#endif + +/* Macros for setting and retrieving special purpose registers */ +#ifndef __ASSEMBLY__ +#define mfmsr() ({unsigned int rval; \ + asm volatile("mfmsr %0" : "=r" (rval)); rval;}) +#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) + +#define mfspr(rn) ({unsigned int rval; \ + asm volatile("mfspr %0," __stringify(rn) \ + : "=r" (rval)); rval;}) +#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) + +#define mfsrin(v) ({unsigned int rval; \ + asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ + rval;}) + +#define proc_trap() asm volatile("trap") +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_PPC_REGS_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h new file mode 100644 index 000000000000..be542efb32d3 --- /dev/null +++ b/include/asm-powerpc/system.h @@ -0,0 +1,350 @@ +/* + * Copyright (C) 1999 Cort Dougan + */ +#ifndef __PPC_SYSTEM_H +#define __PPC_SYSTEM_H + +#include +#include + +#include +#include + +/* + * Memory barrier. + * The sync instruction guarantees that all memory accesses initiated + * by this processor have been performed (with respect to all other + * mechanisms that access memory). The eieio instruction is a barrier + * providing an ordering (separately) for (a) cacheable stores and (b) + * loads and stores to non-cacheable memory (e.g. I/O devices). + * + * mb() prevents loads and stores being reordered across this point. + * rmb() prevents loads being reordered across this point. + * wmb() prevents stores being reordered across this point. + * read_barrier_depends() prevents data-dependent loads being reordered + * across this point (nop on PPC). + * + * We have to use the sync instructions for mb(), since lwsync doesn't + * order loads with respect to previous stores. Lwsync is fine for + * rmb(), though. Note that lwsync is interpreted as sync by + * 32-bit and older 64-bit CPUs. + * + * For wmb(), we use sync since wmb is used in drivers to order + * stores to system memory with respect to writes to the device. + * However, smp_wmb() can be a lighter-weight eieio barrier on + * SMP since it is only used to order updates to system memory. + */ +#define mb() __asm__ __volatile__ ("sync" : : : "memory") +#define rmb() __asm__ __volatile__ ("lwsync" : : : "memory") +#define wmb() __asm__ __volatile__ ("sync" : : : "memory") +#define read_barrier_depends() do { } while(0) + +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory") +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) +#endif /* CONFIG_SMP */ + +#ifdef __KERNEL__ +struct task_struct; +struct pt_regs; + +#ifdef CONFIG_DEBUGGER + +extern int (*__debugger)(struct pt_regs *regs); +extern int (*__debugger_ipi)(struct pt_regs *regs); +extern int (*__debugger_bpt)(struct pt_regs *regs); +extern int (*__debugger_sstep)(struct pt_regs *regs); +extern int (*__debugger_iabr_match)(struct pt_regs *regs); +extern int (*__debugger_dabr_match)(struct pt_regs *regs); +extern int (*__debugger_fault_handler)(struct pt_regs *regs); + +#define DEBUGGER_BOILERPLATE(__NAME) \ +static inline int __NAME(struct pt_regs *regs) \ +{ \ + if (unlikely(__ ## __NAME)) \ + return __ ## __NAME(regs); \ + return 0; \ +} + +DEBUGGER_BOILERPLATE(debugger) +DEBUGGER_BOILERPLATE(debugger_ipi) +DEBUGGER_BOILERPLATE(debugger_bpt) +DEBUGGER_BOILERPLATE(debugger_sstep) +DEBUGGER_BOILERPLATE(debugger_iabr_match) +DEBUGGER_BOILERPLATE(debugger_dabr_match) +DEBUGGER_BOILERPLATE(debugger_fault_handler) + +#ifdef CONFIG_XMON +extern void xmon_init(int enable); +#endif + +#else +static inline int debugger(struct pt_regs *regs) { return 0; } +static inline int debugger_ipi(struct pt_regs *regs) { return 0; } +static inline int debugger_bpt(struct pt_regs *regs) { return 0; } +static inline int debugger_sstep(struct pt_regs *regs) { return 0; } +static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; } +static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; } +static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; } +#endif + +extern int set_dabr(unsigned long dabr); +extern void print_backtrace(unsigned long *); +extern void show_regs(struct pt_regs * regs); +extern void flush_instruction_cache(void); +extern void hard_reset_now(void); +extern void poweroff_now(void); + +#ifdef CONFIG_6xx +extern long _get_L2CR(void); +extern long _get_L3CR(void); +extern void _set_L2CR(unsigned long); +extern void _set_L3CR(unsigned long); +#else +#define _get_L2CR() 0L +#define _get_L3CR() 0L +#define _set_L2CR(val) do { } while(0) +#define _set_L3CR(val) do { } while(0) +#endif + +extern void via_cuda_init(void); +extern void pmac_nvram_init(void); +extern void read_rtc_time(void); +extern void pmac_find_display(void); +extern void giveup_fpu(struct task_struct *); +extern void enable_kernel_fp(void); +extern void flush_fp_to_thread(struct task_struct *); +extern void enable_kernel_altivec(void); +extern void giveup_altivec(struct task_struct *); +extern void load_up_altivec(struct task_struct *); +extern void giveup_spe(struct task_struct *); +extern void load_up_spe(struct task_struct *); +extern int fix_alignment(struct pt_regs *); +extern void cvt_fd(float *from, double *to, unsigned long *fpscr); +extern void cvt_df(double *from, float *to, unsigned long *fpscr); + +#ifdef CONFIG_ALTIVEC +extern void flush_altivec_to_thread(struct task_struct *); +#else +static inline void flush_altivec_to_thread(struct task_struct *t) +{ +} +#endif + +#ifdef CONFIG_SPE +extern void flush_spe_to_thread(struct task_struct *); +#else +static inline void flush_spe_to_thread(struct task_struct *t) +{ +} +#endif + +extern int call_rtas(const char *, int, int, unsigned long *, ...); +extern void cacheable_memzero(void *p, unsigned int nb); +extern void *cacheable_memcpy(void *, const void *, unsigned int); +extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); +extern void bad_page_fault(struct pt_regs *, unsigned long, int); +extern int die(const char *, struct pt_regs *, long); +extern void _exception(int, struct pt_regs *, int, unsigned long); +#ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; +#endif /* CONFIG_BOOKE_WDT */ + +/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */ +extern unsigned char e2a(unsigned char); + +struct device_node; +extern void note_scsi_host(struct device_node *, void *); + +extern struct task_struct *__switch_to(struct task_struct *, + struct task_struct *); +#define switch_to(prev, next, last) ((last) = __switch_to((prev), (next))) + +struct thread_struct; +extern struct task_struct *_switch(struct thread_struct *prev, + struct thread_struct *next); + +extern unsigned int rtas_data; + +/* + * Atomic exchange + * + * Changes the memory location '*ptr' to be val and returns + * the previous value stored there. + */ +static __inline__ unsigned long +__xchg_u32(volatile void *p, unsigned long val) +{ + unsigned long prev; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%2 \n" + PPC405_ERR77(0,%2) +" stwcx. %3,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (prev), "=m" (*(volatile unsigned int *)p) + : "r" (p), "r" (val), "m" (*(volatile unsigned int *)p) + : "cc", "memory"); + + return prev; +} + +#ifdef CONFIG_PPC64 +static __inline__ unsigned long +__xchg_u64(volatile void *p, unsigned long val) +{ + unsigned long prev; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%2 \n" + PPC405_ERR77(0,%2) +" stdcx. %3,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (prev), "=m" (*(volatile unsigned long *)p) + : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p) + : "cc", "memory"); + + return prev; +} +#endif + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + */ +extern void __xchg_called_with_bad_pointer(void); + +static __inline__ unsigned long +__xchg(volatile void *ptr, unsigned long x, unsigned int size) +{ + switch (size) { + case 4: + return __xchg_u32(ptr, x); +#ifdef CONFIG_PPC64 + case 8: + return __xchg_u64(ptr, x); +#endif + } + __xchg_called_with_bad_pointer(); + return x; +} + +#define xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ + }) + +#define tas(ptr) (xchg((ptr),1)) + +/* + * Compare and exchange - if *p == old, set it to new, + * and return the old value of *p. + */ +#define __HAVE_ARCH_CMPXCHG 1 + +static __inline__ unsigned long +__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new) +{ + unsigned int prev; + + __asm__ __volatile__ ( + EIEIO_ON_SMP +"1: lwarx %0,0,%2 # __cmpxchg_u32\n\ + cmpw 0,%0,%3\n\ + bne- 2f\n" + PPC405_ERR77(0,%2) +" stwcx. %4,0,%2\n\ + bne- 1b" + ISYNC_ON_SMP + "\n\ +2:" + : "=&r" (prev), "=m" (*p) + : "r" (p), "r" (old), "r" (new), "m" (*p) + : "cc", "memory"); + + return prev; +} + +#ifdef CONFIG_PPC64 +static __inline__ unsigned long +__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new) +{ + unsigned long prev; + + __asm__ __volatile__ ( + EIEIO_ON_SMP +"1: ldarx %0,0,%2 # __cmpxchg_u64\n\ + cmpd 0,%0,%3\n\ + bne- 2f\n\ + stdcx. %4,0,%2\n\ + bne- 1b" + ISYNC_ON_SMP + "\n\ +2:" + : "=&r" (prev), "=m" (*p) + : "r" (p), "r" (old), "r" (new), "m" (*p) + : "cc", "memory"); + + return prev; +} +#endif + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, + unsigned int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); +#ifdef CONFIG_PPC64 + case 8: + return __cmpxchg_u64(ptr, old, new); +#endif + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#ifdef CONFIG_PPC64 +/* + * We handle most unaligned accesses in hardware. On the other hand + * unaligned DMA can be very expensive on some ppc64 IO chips (it does + * powers of 2 writes until it reaches sufficient alignment). + * + * Based on this we disable the IP header alignment in network drivers. + */ +#define NET_IP_ALIGN 0 +#endif + +#define arch_align_stack(x) (x) + +#endif /* __KERNEL__ */ +#endif /* __PPC_SYSTEM_H */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 829481c0a9dc..79c1be3dfe61 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -45,30 +45,21 @@ extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); extern void cpu_die(void) __attribute__((noreturn)); -#define NO_PROC_ID 0xFF /* No processor magic marker */ -#define PROC_CHANGE_PENALTY 20 - #define raw_smp_processor_id() (current_thread_info()->cpu) extern int __cpu_up(unsigned int cpu); extern int smp_hw_index[]; -#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) - -struct klock_info_struct { - unsigned long kernel_flag; - unsigned char akp; -}; - -extern struct klock_info_struct klock_info; -#define KLOCK_HELD 0xffffffff -#define KLOCK_CLEAR 0x0 +#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) +#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)]) #endif /* __ASSEMBLY__ */ #else /* !(CONFIG_SMP) */ static inline void cpu_die(void) { } +#define get_hard_smp_processor_id(cpu) 0 +#define hard_smp_processor_id() 0 #endif /* !(CONFIG_SMP) */ From bbeb3f4c55f666df7bcd2655b303dfb8c4d1a119 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 27 Sep 2005 13:51:59 +1000 Subject: [PATCH 0137/1940] powerpc: clean up after powermac build merge Complete moving arch/ppc64/kernel/mpic.h, include/asm-ppc/reg.h, include/asm-ppc64/kdebug.h and include/asm-ppc64/kprobes.h Add arch/powerpc/platforms/Makefile and use it from arch/powerpc/Makefile Introduce OLDARCH temporarily so we can point back to the originating architecture Signed-off-by: Stephen Rothwell --- arch/powerpc/Makefile | 31 +- arch/powerpc/platforms/Makefile | 4 + arch/powerpc/platforms/embedded6xx/Kconfig | 8 - arch/ppc64/kernel/kprobes.c | 1 - arch/ppc64/kernel/maple_setup.c | 3 +- arch/ppc64/kernel/mpic.c | 3 +- arch/ppc64/kernel/mpic.h | 273 ------------- arch/ppc64/kernel/pSeries_setup.c | 2 +- arch/ppc64/kernel/pSeries_smp.c | 2 +- arch/ppc64/kernel/pmac_setup.c | 2 +- arch/ppc64/kernel/pmac_smp.c | 3 +- arch/ppc64/kernel/rtas_pci.c | 2 +- arch/ppc64/kernel/smp.c | 3 +- arch/ppc64/kernel/traps.c | 4 +- include/asm-powerpc/kdebug.h | 6 +- include/asm-powerpc/kprobes.h | 7 +- include/asm-powerpc/mpic.h | 5 + include/asm-powerpc/reg.h | 6 +- include/asm-powerpc/system.h | 6 +- include/asm-ppc/reg.h | 440 --------------------- include/asm-ppc64/kdebug.h | 43 -- include/asm-ppc64/kprobes.h | 67 ---- 22 files changed, 41 insertions(+), 880 deletions(-) create mode 100644 arch/powerpc/platforms/Makefile delete mode 100644 arch/ppc64/kernel/mpic.h delete mode 100644 include/asm-ppc/reg.h delete mode 100644 include/asm-ppc64/kdebug.h delete mode 100644 include/asm-ppc64/kprobes.h diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 8a65e112211b..d94878193cd9 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -18,6 +18,7 @@ KERNELLOAD := $(CONFIG_KERNEL_START) HAS_BIARCH := $(call cc-option-yn, -m32) ifeq ($(CONFIG_PPC64),y) +OLDARCH := ppc64 SZ := 64 # Set default 32 bits cross compilers for vdso and boot wrapper @@ -46,6 +47,7 @@ NM := $(NM) --synthetic endif else +OLDARCH := ppc SZ := 32 endif @@ -61,11 +63,9 @@ LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD) CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include AFLAGS += -Iarch/$(ARCH) CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe -ifeq ($(CONFIG_PPC64),y) -CFLAGS += -mminimal-toc -mtraceback=none -mcall-aixdesc -else -CFLAGS += -ffixed-r2 -mmultiple -endif +CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc +CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple +CFLAGS += $(CFLAGS-y) CPP = $(CC) -E $(CFLAGS) # Temporary hack until we have migrated to asm-powerpc LINUXINCLUDE += -Iarch/$(ARCH)/include @@ -126,16 +126,12 @@ head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o endif core-y += arch/powerpc/kernel/ \ + arch/$(OLDARCH)/kernel/ \ arch/powerpc/mm/ \ arch/powerpc/lib/ \ - arch/powerpc/sysdev/ -core-$(CONFIG_PPC32) += arch/ppc/kernel/ \ - arch/ppc/syslib/ -core-$(CONFIG_PPC64) += arch/ppc64/kernel/ -core-$(CONFIG_PPC_PMAC) += arch/powerpc/platforms/powermac/ -core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ -core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ -core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ + arch/powerpc/sysdev/ \ + arch/powerpc/platforms/ +core-$(CONFIG_PPC32) += arch/ppc/syslib/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ @@ -182,17 +178,10 @@ archclean: archprepare: checkbin # Temporary hack until we have migrated to asm-powerpc -ifeq ($(CONFIG_PPC64),y) include/asm: arch/$(ARCH)/include/asm arch/$(ARCH)/include/asm: $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi - $(Q)ln -fsn $(srctree)/include/asm-ppc64 arch/$(ARCH)/include/asm -else -include/asm: arch/$(ARCH)/include/asm -arch/$(ARCH)/include/asm: - $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi - $(Q)ln -fsn $(srctree)/include/asm-ppc arch/$(ARCH)/include/asm -endif + $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm # Use the file '.tmp_gas_check' for binutils tests, as gas won't output # to stdout and these checks are run even on install targets. diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile new file mode 100644 index 000000000000..dbc093759a89 --- /dev/null +++ b/arch/powerpc/platforms/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PPC_PMAC) += powermac/ +obj-$(CONFIG_4xx) += 4xx/ +obj-$(CONFIG_83xx) += 83xx/ +obj-$(CONFIG_85xx) += 85xx/ diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 4f3551430596..2d755b79d51f 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -2,14 +2,6 @@ choice prompt "Machine Type" depends on EMBEDDED6xx -config APUS - bool "Amiga-APUS" - depends on BROKEN - help - Select APUS if configuring for a PowerUP Amiga. - More information is available at: - . - config KATANA bool "Artesyn-Katana" help diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 7e80d49c589a..abb90e67534a 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -395,7 +395,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, if (post_kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; - case DIE_GPF: case DIE_PAGE_FAULT: if (kprobe_running() && kprobe_fault_handler(args->regs, args->trapnr)) diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index fc0567498a3a..2a7fae01eee1 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c @@ -59,8 +59,7 @@ #include #include #include - -#include "mpic.h" +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c index cc262a05ddb4..ec22321342ad 100644 --- a/arch/ppc64/kernel/mpic.c +++ b/arch/ppc64/kernel/mpic.c @@ -31,8 +31,7 @@ #include #include #include - -#include "mpic.h" +#include #ifdef DEBUG #define DBG(fmt...) printk(fmt) diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h deleted file mode 100644 index ca78a7f10528..000000000000 --- a/arch/ppc64/kernel/mpic.h +++ /dev/null @@ -1,273 +0,0 @@ -#include - -/* - * Global registers - */ - -#define MPIC_GREG_BASE 0x01000 - -#define MPIC_GREG_FEATURE_0 0x00000 -#define MPIC_GREG_FEATURE_LAST_SRC_MASK 0x07ff0000 -#define MPIC_GREG_FEATURE_LAST_SRC_SHIFT 16 -#define MPIC_GREG_FEATURE_LAST_CPU_MASK 0x00001f00 -#define MPIC_GREG_FEATURE_LAST_CPU_SHIFT 8 -#define MPIC_GREG_FEATURE_VERSION_MASK 0xff -#define MPIC_GREG_FEATURE_1 0x00010 -#define MPIC_GREG_GLOBAL_CONF_0 0x00020 -#define MPIC_GREG_GCONF_RESET 0x80000000 -#define MPIC_GREG_GCONF_8259_PTHROU_DIS 0x20000000 -#define MPIC_GREG_GCONF_BASE_MASK 0x000fffff -#define MPIC_GREG_GLOBAL_CONF_1 0x00030 -#define MPIC_GREG_VENDOR_0 0x00040 -#define MPIC_GREG_VENDOR_1 0x00050 -#define MPIC_GREG_VENDOR_2 0x00060 -#define MPIC_GREG_VENDOR_3 0x00070 -#define MPIC_GREG_VENDOR_ID 0x00080 -#define MPIC_GREG_VENDOR_ID_STEPPING_MASK 0x00ff0000 -#define MPIC_GREG_VENDOR_ID_STEPPING_SHIFT 16 -#define MPIC_GREG_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00 -#define MPIC_GREG_VENDOR_ID_DEVICE_ID_SHIFT 8 -#define MPIC_GREG_VENDOR_ID_VENDOR_ID_MASK 0x000000ff -#define MPIC_GREG_PROCESSOR_INIT 0x00090 -#define MPIC_GREG_IPI_VECTOR_PRI_0 0x000a0 -#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0 -#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0 -#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0 -#define MPIC_GREG_SPURIOUS 0x000e0 -#define MPIC_GREG_TIMER_FREQ 0x000f0 - -/* - * - * Timer registers - */ -#define MPIC_TIMER_BASE 0x01100 -#define MPIC_TIMER_STRIDE 0x40 - -#define MPIC_TIMER_CURRENT_CNT 0x00000 -#define MPIC_TIMER_BASE_CNT 0x00010 -#define MPIC_TIMER_VECTOR_PRI 0x00020 -#define MPIC_TIMER_DESTINATION 0x00030 - -/* - * Per-Processor registers - */ - -#define MPIC_CPU_THISBASE 0x00000 -#define MPIC_CPU_BASE 0x20000 -#define MPIC_CPU_STRIDE 0x01000 - -#define MPIC_CPU_IPI_DISPATCH_0 0x00040 -#define MPIC_CPU_IPI_DISPATCH_1 0x00050 -#define MPIC_CPU_IPI_DISPATCH_2 0x00060 -#define MPIC_CPU_IPI_DISPATCH_3 0x00070 -#define MPIC_CPU_CURRENT_TASK_PRI 0x00080 -#define MPIC_CPU_TASKPRI_MASK 0x0000000f -#define MPIC_CPU_WHOAMI 0x00090 -#define MPIC_CPU_WHOAMI_MASK 0x0000001f -#define MPIC_CPU_INTACK 0x000a0 -#define MPIC_CPU_EOI 0x000b0 - -/* - * Per-source registers - */ - -#define MPIC_IRQ_BASE 0x10000 -#define MPIC_IRQ_STRIDE 0x00020 -#define MPIC_IRQ_VECTOR_PRI 0x00000 -#define MPIC_VECPRI_MASK 0x80000000 -#define MPIC_VECPRI_ACTIVITY 0x40000000 /* Read Only */ -#define MPIC_VECPRI_PRIORITY_MASK 0x000f0000 -#define MPIC_VECPRI_PRIORITY_SHIFT 16 -#define MPIC_VECPRI_VECTOR_MASK 0x000007ff -#define MPIC_VECPRI_POLARITY_POSITIVE 0x00800000 -#define MPIC_VECPRI_POLARITY_NEGATIVE 0x00000000 -#define MPIC_VECPRI_POLARITY_MASK 0x00800000 -#define MPIC_VECPRI_SENSE_LEVEL 0x00400000 -#define MPIC_VECPRI_SENSE_EDGE 0x00000000 -#define MPIC_VECPRI_SENSE_MASK 0x00400000 -#define MPIC_IRQ_DESTINATION 0x00010 - -#define MPIC_MAX_IRQ_SOURCES 2048 -#define MPIC_MAX_CPUS 32 -#define MPIC_MAX_ISU 32 - -/* - * Special vector numbers (internal use only) - */ -#define MPIC_VEC_SPURRIOUS 255 -#define MPIC_VEC_IPI_3 254 -#define MPIC_VEC_IPI_2 253 -#define MPIC_VEC_IPI_1 252 -#define MPIC_VEC_IPI_0 251 - -/* unused */ -#define MPIC_VEC_TIMER_3 250 -#define MPIC_VEC_TIMER_2 249 -#define MPIC_VEC_TIMER_1 248 -#define MPIC_VEC_TIMER_0 247 - -/* Type definition of the cascade handler */ -typedef int (*mpic_cascade_t)(struct pt_regs *regs, void *data); - -#ifdef CONFIG_MPIC_BROKEN_U3 -/* Fixup table entry */ -struct mpic_irq_fixup -{ - u8 __iomem *base; - unsigned int irq; -}; -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - -/* The instance data of a given MPIC */ -struct mpic -{ - /* The "linux" controller struct */ - hw_irq_controller hc_irq; -#ifdef CONFIG_SMP - hw_irq_controller hc_ipi; -#endif - const char *name; - /* Flags */ - unsigned int flags; - /* How many irq sources in a given ISU */ - unsigned int isu_size; - unsigned int isu_shift; - unsigned int isu_mask; - /* Offset of irq vector numbers */ - unsigned int irq_offset; - unsigned int irq_count; - /* Offset of ipi vector numbers */ - unsigned int ipi_offset; - /* Number of sources */ - unsigned int num_sources; - /* Number of CPUs */ - unsigned int num_cpus; - /* cascade handler */ - mpic_cascade_t cascade; - void *cascade_data; - unsigned int cascade_vec; - /* senses array */ - unsigned char *senses; - unsigned int senses_count; - -#ifdef CONFIG_MPIC_BROKEN_U3 - /* The fixup table */ - struct mpic_irq_fixup *fixups; - spinlock_t fixup_lock; -#endif - - /* The various ioremap'ed bases */ - volatile u32 __iomem *gregs; - volatile u32 __iomem *tmregs; - volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; - volatile u32 __iomem *isus[MPIC_MAX_ISU]; - - /* link */ - struct mpic *next; -}; - -/* This is the primary controller, only that one has IPIs and - * has afinity control. A non-primary MPIC always uses CPU0 - * registers only - */ -#define MPIC_PRIMARY 0x00000001 -/* Set this for a big-endian MPIC */ -#define MPIC_BIG_ENDIAN 0x00000002 -/* Broken U3 MPIC */ -#define MPIC_BROKEN_U3 0x00000004 -/* Broken IPI registers (autodetected) */ -#define MPIC_BROKEN_IPI 0x00000008 -/* MPIC wants a reset */ -#define MPIC_WANTS_RESET 0x00000010 - -/* Allocate the controller structure and setup the linux irq descs - * for the range if interrupts passed in. No HW initialization is - * actually performed. - * - * @phys_addr: physial base address of the MPIC - * @flags: flags, see constants above - * @isu_size: number of interrupts in an ISU. Use 0 to use a - * standard ISU-less setup (aka powermac) - * @irq_offset: first irq number to assign to this mpic - * @irq_count: number of irqs to use with this mpic IRQ sources. Pass 0 - * to match the number of sources - * @ipi_offset: first irq number to assign to this mpic IPI sources, - * used only on primary mpic - * @senses: array of sense values - * @senses_num: number of entries in the array - * - * Note about the sense array. If none is passed, all interrupts are - * setup to be level negative unless MPIC_BROKEN_U3 is set in which - * case they are edge positive (and the array is ignored anyway). - * The values in the array start at the first source of the MPIC, - * that is senses[0] correspond to linux irq "irq_offset". - */ -extern struct mpic *mpic_alloc(unsigned long phys_addr, - unsigned int flags, - unsigned int isu_size, - unsigned int irq_offset, - unsigned int irq_count, - unsigned int ipi_offset, - unsigned char *senses, - unsigned int senses_num, - const char *name); - -/* Assign ISUs, to call before mpic_init() - * - * @mpic: controller structure as returned by mpic_alloc() - * @isu_num: ISU number - * @phys_addr: physical address of the ISU - */ -extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, - unsigned long phys_addr); - -/* Initialize the controller. After this has been called, none of the above - * should be called again for this mpic - */ -extern void mpic_init(struct mpic *mpic); - -/* Setup a cascade. Currently, only one cascade is supported this - * way, though you can always do a normal request_irq() and add - * other cascades this way. You should call this _after_ having - * added all the ISUs - * - * @irq_no: "linux" irq number of the cascade (that is offset'ed vector) - * @handler: cascade handler function - */ -extern void mpic_setup_cascade(unsigned int irq_no, mpic_cascade_t hanlder, - void *data); - -/* - * All of the following functions must only be used after the - * ISUs have been assigned and the controller fully initialized - * with mpic_init() - */ - - -/* Change/Read the priority of an interrupt. Default is 8 for irqs and - * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the - * IPI number is then the offset'ed (linux irq number mapped to the IPI) - */ -extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri); -extern unsigned int mpic_irq_get_priority(unsigned int irq); - -/* Setup a non-boot CPU */ -extern void mpic_setup_this_cpu(void); - -/* Clean up for kexec (or cpu offline or ...) */ -extern void mpic_teardown_this_cpu(int secondary); - -/* Request IPIs on primary mpic */ -extern void mpic_request_ipis(void); - -/* Send an IPI (non offseted number 0..3) */ -extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask); - -/* Fetch interrupt from a given mpic */ -extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); -/* This one gets to the primary mpic */ -extern int mpic_get_irq(struct pt_regs *regs); - -/* global mpic for pSeries */ -extern struct mpic *pSeries_mpic; diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index 3009701eb90d..b9bcff21b463 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c @@ -62,9 +62,9 @@ #include #include #include +#include #include "i8259.h" -#include "mpic.h" #include "pci.h" #ifdef DEBUG diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index d2c7e2c4733b..5d1ed850f47b 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c @@ -46,8 +46,8 @@ #include #include #include +#include -#include "mpic.h" #include "bpa_iic.h" #ifdef DEBUG diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index bb0c3bfbb7e2..497c3cd95bc3 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -72,9 +72,9 @@ #include #include #include +#include #include "pmac.h" -#include "mpic.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c index 9fd23ea55bc9..3a1683f5b07f 100644 --- a/arch/ppc64/kernel/pmac_smp.c +++ b/arch/ppc64/kernel/pmac_smp.c @@ -51,8 +51,7 @@ #include #include #include - -#include "mpic.h" +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c index 4a9719b48abe..4d920dd41dc6 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/ppc64/kernel/rtas_pci.c @@ -38,8 +38,8 @@ #include #include #include +#include -#include "mpic.h" #include "pci.h" /* RTAS tokens */ diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 793b562da653..6f4f3da12a63 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -45,8 +45,7 @@ #include #include #include - -#include "mpic.h" +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index 5c4647b2c5f3..a728c9f0b53f 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c @@ -62,7 +62,7 @@ EXPORT_SYMBOL(__debugger_dabr_match); EXPORT_SYMBOL(__debugger_fault_handler); #endif -struct notifier_block *ppc64_die_chain; +struct notifier_block *powerpc_die_chain; static DEFINE_SPINLOCK(die_notifier_lock); int register_die_notifier(struct notifier_block *nb) @@ -71,7 +71,7 @@ int register_die_notifier(struct notifier_block *nb) unsigned long flags; spin_lock_irqsave(&die_notifier_lock, flags); - err = notifier_chain_register(&ppc64_die_chain, nb); + err = notifier_chain_register(&powerpc_die_chain, nb); spin_unlock_irqrestore(&die_notifier_lock, flags); return err; } diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h index 7c55abf597f6..9dcbac674811 100644 --- a/include/asm-powerpc/kdebug.h +++ b/include/asm-powerpc/kdebug.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_KDEBUG_H -#define _POWERPC_KDEBUG_H 1 +#ifndef _ASM_POWERPC_KDEBUG_H +#define _ASM_POWERPC_KDEBUG_H /* nearly identical to x86_64/i386 code */ @@ -39,4 +39,4 @@ static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,lon return notifier_call_chain(&powerpc_die_chain, val, &args); } -#endif +#endif /* _ASM_POWERPC_KDEBUG_H */ diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h index d9129d2b038e..b2f09f17fbe0 100644 --- a/include/asm-powerpc/kprobes.h +++ b/include/asm-powerpc/kprobes.h @@ -1,8 +1,7 @@ -#ifndef _ASM_KPROBES_H -#define _ASM_KPROBES_H +#ifndef _ASM_POWERPC_KPROBES_H +#define _ASM_POWERPC_KPROBES_H /* * Kernel Probes (KProbes) - * include/asm-ppc64/kprobes.h * * 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 @@ -64,4 +63,4 @@ static inline int kprobe_exceptions_notify(struct notifier_block *self, return 0; } #endif -#endif /* _ASM_KPROBES_H */ +#endif /* _ASM_POWERPC_KPROBES_H */ diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index f1e24f4b2d1c..6b558aeb9cb9 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h @@ -1,3 +1,6 @@ +#ifndef _ASM_POWERPC_MPIC_H +#define _ASM_POWERPC_MPIC_H + #include /* @@ -277,3 +280,5 @@ extern int mpic_get_irq(struct pt_regs *regs); /* global mpic for pSeries */ extern struct mpic *pSeries_mpic; + +#endif /* _ASM_POWERPC_MPIC_H */ diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index f97a5f1761b4..1402a2dedffb 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -6,9 +6,9 @@ * Implementations of the PowerPC Architecture (a.k.a. Green Book) here. */ +#ifndef _ASM_POWERPC_REGS_H +#define _ASM_POWERPC_REGS_H #ifdef __KERNEL__ -#ifndef __ASM_PPC_REGS_H__ -#define __ASM_PPC_REGS_H__ #include @@ -442,5 +442,5 @@ #define proc_trap() asm volatile("trap") #endif /* __ASSEMBLY__ */ -#endif /* __ASM_PPC_REGS_H__ */ #endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_REGS_H */ diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index be542efb32d3..1b64879a02c3 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -1,8 +1,8 @@ /* * Copyright (C) 1999 Cort Dougan */ -#ifndef __PPC_SYSTEM_H -#define __PPC_SYSTEM_H +#ifndef _ASM_POWERPC_SYSTEM_H +#define _ASM_POWERPC_SYSTEM_H #include #include @@ -347,4 +347,4 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, #define arch_align_stack(x) (x) #endif /* __KERNEL__ */ -#endif /* __PPC_SYSTEM_H */ +#endif /* _ASM_POWERPC_SYSTEM_H */ diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h deleted file mode 100644 index 73c33e3ef9c6..000000000000 --- a/include/asm-ppc/reg.h +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Contains the definition of registers common to all PowerPC variants. - * If a register definition has been changed in a different PowerPC - * variant, we will case it in #ifndef XXX ... #endif, and have the - * number used in the Programming Environments Manual For 32-Bit - * Implementations of the PowerPC Architecture (a.k.a. Green Book) here. - */ - -#ifdef __KERNEL__ -#ifndef __ASM_PPC_REGS_H__ -#define __ASM_PPC_REGS_H__ - -#include - -/* Pickup Book E specific registers. */ -#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) -#include -#endif - -/* Machine State Register (MSR) Fields */ -#define MSR_SF (1<<63) -#define MSR_ISF (1<<61) -#define MSR_VEC (1<<25) /* Enable AltiVec */ -#define MSR_POW (1<<18) /* Enable Power Management */ -#define MSR_WE (1<<18) /* Wait State Enable */ -#define MSR_TGPR (1<<17) /* TLB Update registers in use */ -#define MSR_CE (1<<17) /* Critical Interrupt Enable */ -#define MSR_ILE (1<<16) /* Interrupt Little Endian */ -#define MSR_EE (1<<15) /* External Interrupt Enable */ -#define MSR_PR (1<<14) /* Problem State / Privilege Level */ -#define MSR_FP (1<<13) /* Floating Point enable */ -#define MSR_ME (1<<12) /* Machine Check Enable */ -#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ -#define MSR_SE (1<<10) /* Single Step */ -#define MSR_BE (1<<9) /* Branch Trace */ -#define MSR_DE (1<<9) /* Debug Exception Enable */ -#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ -#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ -#define MSR_IR (1<<5) /* Instruction Relocate */ -#define MSR_DR (1<<4) /* Data Relocate */ -#define MSR_PE (1<<3) /* Protection Enable */ -#define MSR_PX (1<<2) /* Protection Exclusive Mode */ -#define MSR_RI (1<<1) /* Recoverable Exception */ -#define MSR_LE (1<<0) /* Little Endian */ - -/* Default MSR for kernel mode. */ -#ifdef CONFIG_APUS_FAST_EXCEPT -#define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR) -#endif - -#ifndef MSR_KERNEL -#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) -#endif - -#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) - -/* Floating Point Status and Control Register (FPSCR) Fields */ -#define FPSCR_FX 0x80000000 /* FPU exception summary */ -#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */ -#define FPSCR_VX 0x20000000 /* Invalid operation summary */ -#define FPSCR_OX 0x10000000 /* Overflow exception summary */ -#define FPSCR_UX 0x08000000 /* Underflow exception summary */ -#define FPSCR_ZX 0x04000000 /* Zero-devide exception summary */ -#define FPSCR_XX 0x02000000 /* Inexact exception summary */ -#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */ -#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */ -#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */ -#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */ -#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */ -#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */ -#define FPSCR_FR 0x00040000 /* Fraction rounded */ -#define FPSCR_FI 0x00020000 /* Fraction inexact */ -#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */ -#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */ -#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */ -#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */ -#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */ -#define FPSCR_VE 0x00000080 /* Invalid op exception enable */ -#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */ -#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */ -#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */ -#define FPSCR_XE 0x00000008 /* FP inexact exception enable */ -#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */ -#define FPSCR_RN 0x00000003 /* FPU rounding control */ - -/* Special Purpose Registers (SPRNs)*/ -#define SPRN_CTR 0x009 /* Count Register */ -#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ -#define SPRN_DAR 0x013 /* Data Address Register */ -#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ -#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ -#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ -#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ -#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ -#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ -#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ -#define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */ -#define SPRN_DBAT1U 0x21A /* Data BAT 1 Upper Register */ -#define SPRN_DBAT2L 0x21D /* Data BAT 2 Lower Register */ -#define SPRN_DBAT2U 0x21C /* Data BAT 2 Upper Register */ -#define SPRN_DBAT3L 0x21F /* Data BAT 3 Lower Register */ -#define SPRN_DBAT3U 0x21E /* Data BAT 3 Upper Register */ -#define SPRN_DBAT4L 0x239 /* Data BAT 4 Lower Register */ -#define SPRN_DBAT4U 0x238 /* Data BAT 4 Upper Register */ -#define SPRN_DBAT5L 0x23B /* Data BAT 5 Lower Register */ -#define SPRN_DBAT5U 0x23A /* Data BAT 5 Upper Register */ -#define SPRN_DBAT6L 0x23D /* Data BAT 6 Lower Register */ -#define SPRN_DBAT6U 0x23C /* Data BAT 6 Upper Register */ -#define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */ -#define SPRN_DBAT7U 0x23E /* Data BAT 7 Upper Register */ - -#define SPRN_DEC 0x016 /* Decrement Register */ -#define SPRN_DER 0x095 /* Debug Enable Regsiter */ -#define DER_RSTE 0x40000000 /* Reset Interrupt */ -#define DER_CHSTPE 0x20000000 /* Check Stop */ -#define DER_MCIE 0x10000000 /* Machine Check Interrupt */ -#define DER_EXTIE 0x02000000 /* External Interrupt */ -#define DER_ALIE 0x01000000 /* Alignment Interrupt */ -#define DER_PRIE 0x00800000 /* Program Interrupt */ -#define DER_FPUVIE 0x00400000 /* FP Unavailable Interrupt */ -#define DER_DECIE 0x00200000 /* Decrementer Interrupt */ -#define DER_SYSIE 0x00040000 /* System Call Interrupt */ -#define DER_TRE 0x00020000 /* Trace Interrupt */ -#define DER_SEIE 0x00004000 /* FP SW Emulation Interrupt */ -#define DER_ITLBMSE 0x00002000 /* Imp. Spec. Instruction TLB Miss */ -#define DER_ITLBERE 0x00001000 /* Imp. Spec. Instruction TLB Error */ -#define DER_DTLBMSE 0x00000800 /* Imp. Spec. Data TLB Miss */ -#define DER_DTLBERE 0x00000400 /* Imp. Spec. Data TLB Error */ -#define DER_LBRKE 0x00000008 /* Load/Store Breakpoint Interrupt */ -#define DER_IBRKE 0x00000004 /* Instruction Breakpoint Interrupt */ -#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */ -#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */ -#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ -#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ -#define SPRN_EAR 0x11A /* External Address Register */ -#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ -#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ -#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ -#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ -#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ -#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ -#define HID0_SBCLK (1<<27) -#define HID0_EICE (1<<26) -#define HID0_TBEN (1<<26) /* Timebase enable - 745x */ -#define HID0_ECLK (1<<25) -#define HID0_PAR (1<<24) -#define HID0_STEN (1<<24) /* Software table search enable - 745x */ -#define HID0_HIGH_BAT (1<<23) /* Enable high BATs - 7455 */ -#define HID0_DOZE (1<<23) -#define HID0_NAP (1<<22) -#define HID0_SLEEP (1<<21) -#define HID0_DPM (1<<20) -#define HID0_BHTCLR (1<<18) /* Clear branch history table - 7450 */ -#define HID0_XAEN (1<<17) /* Extended addressing enable - 7450 */ -#define HID0_NHR (1<<16) /* Not hard reset (software bit-7450)*/ -#define HID0_ICE (1<<15) /* Instruction Cache Enable */ -#define HID0_DCE (1<<14) /* Data Cache Enable */ -#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ -#define HID0_DLOCK (1<<12) /* Data Cache Lock */ -#define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ -#define HID0_DCI (1<<10) /* Data Cache Invalidate */ -#define HID0_SPD (1<<9) /* Speculative disable */ -#define HID0_DAPUEN (1<<8) /* Debug APU enable */ -#define HID0_SGE (1<<7) /* Store Gathering Enable */ -#define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ -#define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ -#define HID0_LRSTK (1<<4) /* Link register stack - 745x */ -#define HID0_BTIC (1<<5) /* Branch Target Instr Cache Enable */ -#define HID0_ABE (1<<3) /* Address Broadcast Enable */ -#define HID0_FOLD (1<<3) /* Branch Folding enable - 745x */ -#define HID0_BHTE (1<<2) /* Branch History Table Enable */ -#define HID0_BTCD (1<<1) /* Branch target cache disable */ -#define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */ -#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ - -#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ -#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */ -#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */ -#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */ -#define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */ -#define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */ -#define HID1_PC3 (1<<13) /* 7450 PLL_CFG[3] */ -#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ -#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ -#define HID1_PS (1<<16) /* 750FX PLL selection */ -#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ -#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ -#define SPRN_HID4 0x3F4 /* 970 HID4 */ -#define SPRN_HID5 0x3F6 /* 970 HID5 */ -#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2) -#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ -#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ -#endif -#define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */ -#define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */ -#define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */ -#define SPRN_IBAT1U 0x212 /* Instruction BAT 1 Upper Register */ -#define SPRN_IBAT2L 0x215 /* Instruction BAT 2 Lower Register */ -#define SPRN_IBAT2U 0x214 /* Instruction BAT 2 Upper Register */ -#define SPRN_IBAT3L 0x217 /* Instruction BAT 3 Lower Register */ -#define SPRN_IBAT3U 0x216 /* Instruction BAT 3 Upper Register */ -#define SPRN_IBAT4L 0x231 /* Instruction BAT 4 Lower Register */ -#define SPRN_IBAT4U 0x230 /* Instruction BAT 4 Upper Register */ -#define SPRN_IBAT5L 0x233 /* Instruction BAT 5 Lower Register */ -#define SPRN_IBAT5U 0x232 /* Instruction BAT 5 Upper Register */ -#define SPRN_IBAT6L 0x235 /* Instruction BAT 6 Lower Register */ -#define SPRN_IBAT6U 0x234 /* Instruction BAT 6 Upper Register */ -#define SPRN_IBAT7L 0x237 /* Instruction BAT 7 Lower Register */ -#define SPRN_IBAT7U 0x236 /* Instruction BAT 7 Upper Register */ -#define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ -#define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ -#define SPRN_ICTRL 0x3F3 /* 1011 7450 icache and interrupt ctrl */ -#define ICTRL_EICE 0x08000000 /* enable icache parity errs */ -#define ICTRL_EDC 0x04000000 /* enable dcache parity errs */ -#define ICTRL_EICP 0x00000100 /* enable icache par. check */ -#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ -#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ -#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ -#define SPRN_L2CR2 0x3f8 -#define L2CR_L2E 0x80000000 /* L2 enable */ -#define L2CR_L2PE 0x40000000 /* L2 parity enable */ -#define L2CR_L2SIZ_MASK 0x30000000 /* L2 size mask */ -#define L2CR_L2SIZ_256KB 0x10000000 /* L2 size 256KB */ -#define L2CR_L2SIZ_512KB 0x20000000 /* L2 size 512KB */ -#define L2CR_L2SIZ_1MB 0x30000000 /* L2 size 1MB */ -#define L2CR_L2CLK_MASK 0x0e000000 /* L2 clock mask */ -#define L2CR_L2CLK_DISABLED 0x00000000 /* L2 clock disabled */ -#define L2CR_L2CLK_DIV1 0x02000000 /* L2 clock / 1 */ -#define L2CR_L2CLK_DIV1_5 0x04000000 /* L2 clock / 1.5 */ -#define L2CR_L2CLK_DIV2 0x08000000 /* L2 clock / 2 */ -#define L2CR_L2CLK_DIV2_5 0x0a000000 /* L2 clock / 2.5 */ -#define L2CR_L2CLK_DIV3 0x0c000000 /* L2 clock / 3 */ -#define L2CR_L2RAM_MASK 0x01800000 /* L2 RAM type mask */ -#define L2CR_L2RAM_FLOW 0x00000000 /* L2 RAM flow through */ -#define L2CR_L2RAM_PIPE 0x01000000 /* L2 RAM pipelined */ -#define L2CR_L2RAM_PIPE_LW 0x01800000 /* L2 RAM pipelined latewr */ -#define L2CR_L2DO 0x00400000 /* L2 data only */ -#define L2CR_L2I 0x00200000 /* L2 global invalidate */ -#define L2CR_L2CTL 0x00100000 /* L2 RAM control */ -#define L2CR_L2WT 0x00080000 /* L2 write-through */ -#define L2CR_L2TS 0x00040000 /* L2 test support */ -#define L2CR_L2OH_MASK 0x00030000 /* L2 output hold mask */ -#define L2CR_L2OH_0_5 0x00000000 /* L2 output hold 0.5 ns */ -#define L2CR_L2OH_1_0 0x00010000 /* L2 output hold 1.0 ns */ -#define L2CR_L2SL 0x00008000 /* L2 DLL slow */ -#define L2CR_L2DF 0x00004000 /* L2 differential clock */ -#define L2CR_L2BYP 0x00002000 /* L2 DLL bypass */ -#define L2CR_L2IP 0x00000001 /* L2 GI in progress */ -#define L2CR_L2IO_745x 0x00100000 /* L2 instr. only (745x) */ -#define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ -#define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ -#define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ -#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */ -#define L3CR_L3E 0x80000000 /* L3 enable */ -#define L3CR_L3PE 0x40000000 /* L3 data parity enable */ -#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ -#define L3CR_L3SIZ 0x10000000 /* L3 size */ -#define L3CR_L3CLKEN 0x08000000 /* L3 clock enable */ -#define L3CR_L3RES 0x04000000 /* L3 special reserved bit */ -#define L3CR_L3CLKDIV 0x03800000 /* L3 clock divisor */ -#define L3CR_L3IO 0x00400000 /* L3 instruction only */ -#define L3CR_L3SPO 0x00040000 /* L3 sample point override */ -#define L3CR_L3CKSP 0x00030000 /* L3 clock sample point */ -#define L3CR_L3PSP 0x0000e000 /* L3 P-clock sample point */ -#define L3CR_L3REP 0x00001000 /* L3 replacement algorithm */ -#define L3CR_L3HWF 0x00000800 /* L3 hardware flush */ -#define L3CR_L3I 0x00000400 /* L3 global invalidate */ -#define L3CR_L3RT 0x00000300 /* L3 SRAM type */ -#define L3CR_L3NIRCA 0x00000080 /* L3 non-integer ratio clock adj. */ -#define L3CR_L3DO 0x00000040 /* L3 data only mode */ -#define L3CR_PMEN 0x00000004 /* L3 private memory enable */ -#define L3CR_PMSIZ 0x00000001 /* L3 private memory size */ -#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */ -#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */ -#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */ -#define SPRN_LDSTDB 0x3f4 /* */ -#define SPRN_LR 0x008 /* Link Register */ -#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ -#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ -#ifndef SPRN_PIR -#define SPRN_PIR 0x3FF /* Processor Identification Register */ -#endif -#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ -#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ -#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ -#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ -#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ -#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ -#define SPRN_PVR 0x11F /* Processor Version Register */ -#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ -#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ -#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ -#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ -#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ -#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ -#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ -#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ -#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ -#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ -#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ -#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ -#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ -#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ -#ifndef SPRN_SVR -#define SPRN_SVR 0x11E /* System Version Register */ -#endif -#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ -/* these bits were defined in inverted endian sense originally, ugh, confusing */ -#define THRM1_TIN (1 << 31) -#define THRM1_TIV (1 << 30) -#define THRM1_THRES(x) ((x&0x7f)<<23) -#define THRM3_SITV(x) ((x&0x3fff)<<1) -#define THRM1_TID (1<<2) -#define THRM1_TIE (1<<1) -#define THRM1_V (1<<0) -#define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ -#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ -#define THRM3_E (1<<0) -#define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ -#define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */ -#define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */ -#define SPRN_UPMC1 0x3A9 /* User Performance Counter Register 1 */ -#define SPRN_UPMC2 0x3AA /* User Performance Counter Register 2 */ -#define SPRN_UPMC3 0x3AD /* User Performance Counter Register 3 */ -#define SPRN_UPMC4 0x3AE /* User Performance Counter Register 4 */ -#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ -#define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ -#define SPRN_XER 0x001 /* Fixed Point Exception Register */ - -/* Bit definitions for MMCR0 and PMC1 / PMC2. */ -#define MMCR0_PMC1_CYCLES (1 << 7) -#define MMCR0_PMC1_ICACHEMISS (5 << 7) -#define MMCR0_PMC1_DTLB (6 << 7) -#define MMCR0_PMC2_DCACHEMISS 0x6 -#define MMCR0_PMC2_CYCLES 0x1 -#define MMCR0_PMC2_ITLB 0x7 -#define MMCR0_PMC2_LOADMISSTIME 0x5 -#define MMCR0_PMXE (1 << 26) - -/* Processor Version Register */ - -/* Processor Version Register (PVR) field extraction */ - -#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ -#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ - -/* - * IBM has further subdivided the standard PowerPC 16-bit version and - * revision subfields of the PVR for the PowerPC 403s into the following: - */ - -#define PVR_FAM(pvr) (((pvr) >> 20) & 0xFFF) /* Family field */ -#define PVR_MEM(pvr) (((pvr) >> 16) & 0xF) /* Member field */ -#define PVR_CORE(pvr) (((pvr) >> 12) & 0xF) /* Core field */ -#define PVR_CFG(pvr) (((pvr) >> 8) & 0xF) /* Configuration field */ -#define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ -#define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ - -/* Processor Version Numbers */ - -#define PVR_403GA 0x00200000 -#define PVR_403GB 0x00200100 -#define PVR_403GC 0x00200200 -#define PVR_403GCX 0x00201400 -#define PVR_405GP 0x40110000 -#define PVR_STB03XXX 0x40310000 -#define PVR_NP405H 0x41410000 -#define PVR_NP405L 0x41610000 -#define PVR_601 0x00010000 -#define PVR_602 0x00050000 -#define PVR_603 0x00030000 -#define PVR_603e 0x00060000 -#define PVR_603ev 0x00070000 -#define PVR_603r 0x00071000 -#define PVR_604 0x00040000 -#define PVR_604e 0x00090000 -#define PVR_604r 0x000A0000 -#define PVR_620 0x00140000 -#define PVR_740 0x00080000 -#define PVR_750 PVR_740 -#define PVR_740P 0x10080000 -#define PVR_750P PVR_740P -#define PVR_7400 0x000C0000 -#define PVR_7410 0x800C0000 -#define PVR_7450 0x80000000 -#define PVR_8540 0x80200000 -#define PVR_8560 0x80200000 -/* - * For the 8xx processors, all of them report the same PVR family for - * the PowerPC core. The various versions of these processors must be - * differentiated by the version number in the Communication Processor - * Module (CPM). - */ -#define PVR_821 0x00500000 -#define PVR_823 PVR_821 -#define PVR_850 PVR_821 -#define PVR_860 PVR_821 -#define PVR_8240 0x00810100 -#define PVR_8245 0x80811014 -#define PVR_8260 PVR_8240 - -#if 0 -/* Segment Registers */ -#define SR0 0 -#define SR1 1 -#define SR2 2 -#define SR3 3 -#define SR4 4 -#define SR5 5 -#define SR6 6 -#define SR7 7 -#define SR8 8 -#define SR9 9 -#define SR10 10 -#define SR11 11 -#define SR12 12 -#define SR13 13 -#define SR14 14 -#define SR15 15 -#endif - -/* Macros for setting and retrieving special purpose registers */ -#ifndef __ASSEMBLY__ -#define mfmsr() ({unsigned int rval; \ - asm volatile("mfmsr %0" : "=r" (rval)); rval;}) -#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) - -#define mfspr(rn) ({unsigned int rval; \ - asm volatile("mfspr %0," __stringify(rn) \ - : "=r" (rval)); rval;}) -#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) - -#define mfsrin(v) ({unsigned int rval; \ - asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ - rval;}) - -#define proc_trap() asm volatile("trap") -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_PPC_REGS_H__ */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/kdebug.h b/include/asm-ppc64/kdebug.h deleted file mode 100644 index d383d161cf8d..000000000000 --- a/include/asm-ppc64/kdebug.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _PPC64_KDEBUG_H -#define _PPC64_KDEBUG_H 1 - -/* nearly identical to x86_64/i386 code */ - -#include - -struct pt_regs; - -struct die_args { - struct pt_regs *regs; - const char *str; - long err; - int trapnr; - int signr; -}; - -/* - Note - you should never unregister because that can race with NMIs. - If you really want to do it first unregister - then synchronize_sched - - then free. - */ -int register_die_notifier(struct notifier_block *nb); -extern struct notifier_block *ppc64_die_chain; - -/* Grossly misnamed. */ -enum die_val { - DIE_OOPS = 1, - DIE_IABR_MATCH, - DIE_DABR_MATCH, - DIE_BPT, - DIE_SSTEP, - DIE_GPF, - DIE_PAGE_FAULT, -}; - -static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) -{ - struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; - return notifier_call_chain(&ppc64_die_chain, val, &args); -} - -#endif diff --git a/include/asm-ppc64/kprobes.h b/include/asm-ppc64/kprobes.h deleted file mode 100644 index d9129d2b038e..000000000000 --- a/include/asm-ppc64/kprobes.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _ASM_KPROBES_H -#define _ASM_KPROBES_H -/* - * Kernel Probes (KProbes) - * include/asm-ppc64/kprobes.h - * - * 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) IBM Corporation, 2002, 2004 - * - * 2002-Oct Created by Vamsi Krishna S Kernel - * Probes initial implementation ( includes suggestions from - * Rusty Russell). - * 2004-Nov Modified for PPC64 by Ananth N Mavinakayanahalli - * - */ -#include -#include - -struct pt_regs; - -typedef unsigned int kprobe_opcode_t; -#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ -#define MAX_INSN_SIZE 1 - -#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008) -#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088) -#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) -#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) - -#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) - -#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ - IS_TWI(instr) || IS_TDI(instr)) - -#define ARCH_SUPPORTS_KRETPROBES -void kretprobe_trampoline(void); - -/* Architecture specific copy of original instruction */ -struct arch_specific_insn { - /* copy of original instruction */ - kprobe_opcode_t *insn; -}; - -#ifdef CONFIG_KPROBES -extern int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data); -#else /* !CONFIG_KPROBES */ -static inline int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - return 0; -} -#endif -#endif /* _ASM_KPROBES_H */ From e607d98369dbd8e7b33b19664d1729a8a81fe7cd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 27 Sep 2005 14:24:18 +1000 Subject: [PATCH 0138/1940] ppc64: Fix typo in iommu cleanups that broke pmac build. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- include/asm-ppc64/dart.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h index a9000de8a2e3..cdf8a2dec05f 100644 --- a/include/asm-ppc64/dart.h +++ b/include/asm-ppc64/dart.h @@ -51,9 +51,9 @@ #define DARTMAP_RPNMASK 0x00ffffff -#define DART_SHIFT 12 -#define DART_PAGE_SIZE (1 << DART_SHIFT) -#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_SHIFT) +#define DART_PAGE_SHIFT 12 +#define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT) +#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT) #endif From 6b67f62cf655c80147435544a2f8f6f57e07ec87 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 27 Sep 2005 14:09:39 +1000 Subject: [PATCH 0139/1940] [PATCH] ppc64 g5: merge tree build fix We removed __pmacdata in the merge. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- drivers/macintosh/smu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index a85ac18dd21d..5f283529620b 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -1092,7 +1092,7 @@ static int smu_release(struct inode *inode, struct file *file) } -static struct file_operations smu_device_fops __pmacdata = { +static struct file_operations smu_device_fops = { .llseek = no_llseek, .read = smu_read, .write = smu_write, @@ -1101,7 +1101,7 @@ static struct file_operations smu_device_fops __pmacdata = { .release = smu_release, }; -static struct miscdevice pmu_device __pmacdata = { +static struct miscdevice pmu_device = { MISC_DYNAMIC_MINOR, "smu", &smu_device_fops }; From ba0dd617a3e23321a14cb38ff7ad6f796ba32c34 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 Sep 2005 13:15:51 +1000 Subject: [PATCH 0140/1940] powerpc: Create arch/powerpc/platforms/iseries I also move arch/ppc64/kernel/HvCall.c to arch/powerpc/platforms/iseries/hvcall.c. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/Makefile | 9 +++++---- arch/powerpc/platforms/iseries/Makefile | 1 + .../HvCall.c => powerpc/platforms/iseries/hvcall.c} | 1 - arch/ppc64/Makefile | 1 + arch/ppc64/kernel/Makefile | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 arch/powerpc/platforms/iseries/Makefile rename arch/{ppc64/kernel/HvCall.c => powerpc/platforms/iseries/hvcall.c} (98%) diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index dbc093759a89..697addea192f 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -1,4 +1,5 @@ -obj-$(CONFIG_PPC_PMAC) += powermac/ -obj-$(CONFIG_4xx) += 4xx/ -obj-$(CONFIG_83xx) += 83xx/ -obj-$(CONFIG_85xx) += 85xx/ +obj-$(CONFIG_PPC_PMAC) += powermac/ +obj-$(CONFIG_4xx) += 4xx/ +obj-$(CONFIG_83xx) += 83xx/ +obj-$(CONFIG_85xx) += 85xx/ +obj-$(CONFIG_PPC_ISERIES) += iseries/ diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile new file mode 100644 index 000000000000..af0c7d97121d --- /dev/null +++ b/arch/powerpc/platforms/iseries/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PPC_ISERIES) += hvcall.o diff --git a/arch/ppc64/kernel/HvCall.c b/arch/powerpc/platforms/iseries/hvcall.c similarity index 98% rename from arch/ppc64/kernel/HvCall.c rename to arch/powerpc/platforms/iseries/hvcall.c index b772e65b57a2..f61e2e9ac9ec 100644 --- a/arch/ppc64/kernel/HvCall.c +++ b/arch/powerpc/platforms/iseries/hvcall.c @@ -1,5 +1,4 @@ /* - * HvCall.c * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 40675b3f924d..d4eb55f82f03 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -84,6 +84,7 @@ head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ core-y += arch/ppc64/mm/ +core-y += arch/powerpc/platforms/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index afadb6e4a6dc..aba3895b74d4 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,7 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \ +obj-$(CONFIG_PPC_ISERIES) += HvLpConfig.o LparData.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o From acdbec1b8974f61b0cb69ebe57916f8721b2f3d7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 Sep 2005 13:23:58 +1000 Subject: [PATCH 0141/1940] powerpc: Move HvLpConfig.c to powerpc arch Also rename it to hvlpconfig.c Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../HvLpConfig.c => powerpc/platforms/iseries/hvlpconfig.c} | 1 - arch/ppc64/kernel/Makefile | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) rename arch/{ppc64/kernel/HvLpConfig.c => powerpc/platforms/iseries/hvlpconfig.c} (98%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index af0c7d97121d..3b7a31d4acda 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1 @@ -obj-$(CONFIG_PPC_ISERIES) += hvcall.o +obj-$(CONFIG_PPC_ISERIES) += hvcall.o hvlpconfig.o diff --git a/arch/ppc64/kernel/HvLpConfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c similarity index 98% rename from arch/ppc64/kernel/HvLpConfig.c rename to arch/powerpc/platforms/iseries/hvlpconfig.c index cb1d6473203c..dc28621aea0d 100644 --- a/arch/ppc64/kernel/HvLpConfig.c +++ b/arch/powerpc/platforms/iseries/hvlpconfig.c @@ -1,5 +1,4 @@ /* - * HvLpConfig.c * Copyright (C) 2001 Kyle A. Lucke, IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index aba3895b74d4..c80b6174231e 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,7 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += HvLpConfig.o LparData.o \ +obj-$(CONFIG_PPC_ISERIES) += LparData.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o From 2960eb661a82131b9492cdd1b6500a5f74ccc394 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 Sep 2005 13:42:26 +1000 Subject: [PATCH 0142/1940] powerpc: Move LparData.c to powerpc platforms Also rename it to lpardata.c Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../platforms/iseries/lpardata.c} | 18 +++++++++--------- arch/ppc64/kernel/Makefile | 3 +-- arch/ppc64/kernel/head.S | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) rename arch/{ppc64/kernel/LparData.c => powerpc/platforms/iseries/lpardata.c} (98%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 3b7a31d4acda..095471d50d9f 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1 @@ -obj-$(CONFIG_PPC_ISERIES) += hvcall.o hvlpconfig.o +obj-$(CONFIG_PPC_ISERIES) += hvcall.o hvlpconfig.o lpardata.o diff --git a/arch/ppc64/kernel/LparData.c b/arch/powerpc/platforms/iseries/lpardata.c similarity index 98% rename from arch/ppc64/kernel/LparData.c rename to arch/powerpc/platforms/iseries/lpardata.c index 0a9c23ca2f0c..87b7ad8ca465 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/powerpc/platforms/iseries/lpardata.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Mike Corrigan, IBM Corp * * This program is free software; you can redistribute it and/or @@ -29,8 +29,8 @@ #include -/* The HvReleaseData is the root of the information shared between - * the hypervisor and Linux. +/* The HvReleaseData is the root of the information shared between + * the hypervisor and Linux. */ struct HvReleaseData hvReleaseData = { .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ @@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void); extern void performance_monitor_iSeries(void); extern void data_access_slb_iSeries(void); extern void instruction_access_slb_iSeries(void); - + struct ItLpNaca itLpNaca = { .xDesc = 0xd397d581, /* "LpNa" ebcdic */ .xSize = 0x0400, /* size of ItLpNaca */ @@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = { .xLoadAreaChunks = 0, /* chunks for load area */ .xPaseSysCallCRMask = 0, /* PASE mask */ .xSlicSegmentTablePtr = 0, /* seg table */ - .xOldLpQueue = { 0 }, /* Old LP Queue */ + .xOldLpQueue = { 0 }, /* Old LP Queue */ .xInterruptHdlr = { (u64)system_reset_iSeries, /* 0x100 System Reset */ (u64)machine_check_iSeries, /* 0x200 Machine Check */ @@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = { EXPORT_SYMBOL(itLpNaca); /* May be filled in by the hypervisor so cannot end up in the BSS */ -struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); +struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); /* May be filled in by the hypervisor so cannot end up in the BSS */ struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); @@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = { .xPVR = 0x3600 } }; - + /* Space for Main Store Vpd 27,200 bytes */ /* May be filled in by the hypervisor so cannot end up in the BSS */ u64 xMsVpd[3400] __attribute__((__section__(".data"))); @@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = { 26992, /* 7 length of MS VPD */ 0, /* 8 */ sizeof(struct ItLpNaca),/* 9 length of LP Naca */ - 0, /* 10 */ + 0, /* 10 */ 256, /* 11 length of Recovery Log Buf */ sizeof(struct SpCommArea), /* 12 length of SP Comm Area */ 0,0,0, /* 13 - 15 */ @@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = { 0,0 /* 24 - 25 */ }, .xSlicVpdAdrs = { /* VPD addresses */ - 0,0,0, /* 0 - 2 */ + 0,0,0, /* 0 - 2 */ &xItExtVpdPanel, /* 3 Extended VPD */ &paca[0], /* 4 first Paca */ 0, /* 5 */ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index c80b6174231e..4d95f0d0137a 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,8 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += LparData.o \ - iSeries_setup.o ItLpQueue.o hvCall.o \ +obj-$(CONFIG_PPC_ISERIES) += iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index eb526c480b6c..db0cd3587627 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1253,7 +1253,7 @@ unrecov_slb: * * On iSeries, the hypervisor must fill in at least one entry before * we get control (with relocate on). The address is give to the hv - * as a page number (see xLparMap in LparData.c), so this must be at a + * as a page number (see xLparMap in lpardata.c), so this must be at a * fixed address (the linker can't compute (u64)&initial_stab >> * PAGE_SHIFT). */ From c8b84976f86adcd10c221d398e1d0be2b778f3c8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 27 Sep 2005 18:44:42 +1000 Subject: [PATCH 0143/1940] powerpc: move iSeries_setup.[ch] and mf.c into platforms/iseries iSeries_setup.c becomes setup.c iSeries_setup.h becomes setup.h mf.c retains its name Also moved iSeries_[gs]et_rtc_time and iSeries_get_boot_time into mf.c since they are just small wrappers around mf_ functions. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../kernel => powerpc/platforms/iseries}/mf.c | 85 +++++++++++++------ .../platforms/iseries/setup.c} | 5 +- .../platforms/iseries/setup.h} | 2 - arch/ppc64/kernel/Makefile | 4 +- arch/ppc64/kernel/rtc.c | 37 -------- 6 files changed, 65 insertions(+), 70 deletions(-) rename arch/{ppc64/kernel => powerpc/platforms/iseries}/mf.c (94%) rename arch/{ppc64/kernel/iSeries_setup.c => powerpc/platforms/iseries/setup.c} (99%) rename arch/{ppc64/kernel/iSeries_setup.h => powerpc/platforms/iseries/setup.h} (96%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 095471d50d9f..f5e11907cab1 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1 @@ -obj-$(CONFIG_PPC_ISERIES) += hvcall.o hvlpconfig.o lpardata.o +obj-y += hvcall.o hvlpconfig.o lpardata.o setup.o mf.o diff --git a/arch/ppc64/kernel/mf.c b/arch/powerpc/platforms/iseries/mf.c similarity index 94% rename from arch/ppc64/kernel/mf.c rename to arch/powerpc/platforms/iseries/mf.c index ef4a338ebd01..82f5abab9afa 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -1,29 +1,28 @@ /* - * mf.c - * Copyright (C) 2001 Troy D. Armstrong IBM Corporation - * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation - * - * This modules exists as an interface between a Linux secondary partition - * running on an iSeries and the primary partition's Virtual Service - * Processor (VSP) object. The VSP has final authority over powering on/off - * all partitions in the iSeries. It also provides miscellaneous low-level - * machine facility type operations. - * - * - * 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Copyright (C) 2001 Troy D. Armstrong IBM Corporation + * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation + * + * This modules exists as an interface between a Linux secondary partition + * running on an iSeries and the primary partition's Virtual Service + * Processor (VSP) object. The VSP has final authority over powering on/off + * all partitions in the iSeries. It also provides miscellaneous low-level + * machine facility type operations. + * + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include #include @@ -42,6 +41,10 @@ #include #include +#include "setup.h" + +extern int piranha_simulator; + /* * This is the structure layout for the Machine Facilites LPAR event * flows. @@ -1279,3 +1282,35 @@ static int __init mf_proc_init(void) __initcall(mf_proc_init); #endif /* CONFIG_PROC_FS */ + +/* + * Get the RTC from the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +void iSeries_get_rtc_time(struct rtc_time *rtc_tm) +{ + if (piranha_simulator) + return; + + mf_get_rtc(rtc_tm); + rtc_tm->tm_mon--; +} + +/* + * Set the RTC in the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +int iSeries_set_rtc_time(struct rtc_time *tm) +{ + mf_set_rtc(tm); + return 0; +} + +void iSeries_get_boot_time(struct rtc_time *tm) +{ + if (piranha_simulator) + return; + + mf_get_boot_rtc(tm); + tm->tm_mon -= 1; +} diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/powerpc/platforms/iseries/setup.c similarity index 99% rename from arch/ppc64/kernel/iSeries_setup.c rename to arch/powerpc/platforms/iseries/setup.c index 9daf734adbd5..ad78c8581a5a 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -2,8 +2,6 @@ * Copyright (c) 2000 Mike Corrigan * Copyright (c) 1999-2000 Grant Erickson * - * Module name: iSeries_setup.c - * * Description: * Architecture- / platform-specific boot-time initialization code for * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and @@ -42,7 +40,6 @@ #include #include -#include "iSeries_setup.h" #include #include #include @@ -62,6 +59,8 @@ #include #include +#include "setup.h" + extern void hvlog(char *fmt, ...); #ifdef DEBUG diff --git a/arch/ppc64/kernel/iSeries_setup.h b/arch/powerpc/platforms/iseries/setup.h similarity index 96% rename from arch/ppc64/kernel/iSeries_setup.h rename to arch/powerpc/platforms/iseries/setup.h index c6eb29a245ac..6da89ae991ce 100644 --- a/arch/ppc64/kernel/iSeries_setup.h +++ b/arch/powerpc/platforms/iseries/setup.h @@ -2,8 +2,6 @@ * Copyright (c) 2000 Mike Corrigan * Copyright (c) 1999-2000 Grant Erickson * - * Module name: as400_setup.h - * * Description: * Architecture- / platform-specific boot-time initialization code for * the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 4d95f0d0137a..b558cc0f4d9e 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,8 +22,8 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_setup.o ItLpQueue.o hvCall.o \ - mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ +obj-$(CONFIG_PPC_ISERIES) += ItLpQueue.o hvCall.o \ + HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 6ff52bc61325..88ae13f81c46 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -43,11 +43,8 @@ #include #include -#include #include -extern int piranha_simulator; - /* * We sponge a minor off of the misc major. No need slurping * up another valuable major dev number for this. If you add @@ -265,40 +262,6 @@ static int rtc_read_proc(char *page, char **start, off_t off, return len; } -#ifdef CONFIG_PPC_ISERIES -/* - * Get the RTC from the virtual service processor - * This requires flowing LpEvents to the primary partition - */ -void iSeries_get_rtc_time(struct rtc_time *rtc_tm) -{ - if (piranha_simulator) - return; - - mf_get_rtc(rtc_tm); - rtc_tm->tm_mon--; -} - -/* - * Set the RTC in the virtual service processor - * This requires flowing LpEvents to the primary partition - */ -int iSeries_set_rtc_time(struct rtc_time *tm) -{ - mf_set_rtc(tm); - return 0; -} - -void iSeries_get_boot_time(struct rtc_time *tm) -{ - if ( piranha_simulator ) - return; - - mf_get_boot_rtc(tm); - tm->tm_mon -= 1; -} -#endif - #ifdef CONFIG_PPC_RTAS #define MAX_RTC_WAIT 5000 /* 5 sec */ #define RTAS_CLOCK_BUSY (-2) From 2952bc7c896ec76a20e18321e2be40a694a73a78 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 00:03:46 +1000 Subject: [PATCH 0144/1940] powerpc: move ItLpQueue.c to powerpc/platforms/iseries Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../kernel/ItLpQueue.c => powerpc/platforms/iseries/lpevents.c} | 1 - arch/ppc64/kernel/Makefile | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) rename arch/{ppc64/kernel/ItLpQueue.c => powerpc/platforms/iseries/lpevents.c} (99%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index f5e11907cab1..a5e91c9db5c7 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1 @@ -obj-y += hvcall.o hvlpconfig.o lpardata.o setup.o mf.o +obj-y += hvcall.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/powerpc/platforms/iseries/lpevents.c similarity index 99% rename from arch/ppc64/kernel/ItLpQueue.c rename to arch/powerpc/platforms/iseries/lpevents.c index 4231861288a3..819298a8a4db 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -1,5 +1,4 @@ /* - * ItLpQueue.c * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index b558cc0f4d9e..e3bce4dda502 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,7 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += ItLpQueue.o hvCall.o \ +obj-$(CONFIG_PPC_ISERIES) += hvCall.o \ HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o From 99a2379cdddcc4e8579e70deb80479450ed65d49 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 00:17:40 +1000 Subject: [PATCH 0145/1940] powerpc: move hvCall.s to powerpc/platforms/iseries Rename it to hvcall.S and (so I can do that) rename hvcall.c to hvlog.c - a more appropriate name. Do some white space cleanups. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../platforms/iseries/hvcall.S} | 21 +++++++------------ .../platforms/iseries/{hvcall.c => hvlog.c} | 0 arch/ppc64/kernel/Makefile | 3 +-- 4 files changed, 10 insertions(+), 16 deletions(-) rename arch/{ppc64/kernel/hvCall.S => powerpc/platforms/iseries/hvcall.S} (96%) rename arch/powerpc/platforms/iseries/{hvcall.c => hvlog.c} (100%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index a5e91c9db5c7..3a9981a35e2a 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1 @@ -obj-y += hvcall.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o +obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o hvcall.o diff --git a/arch/ppc64/kernel/hvCall.S b/arch/powerpc/platforms/iseries/hvcall.S similarity index 96% rename from arch/ppc64/kernel/hvCall.S rename to arch/powerpc/platforms/iseries/hvcall.S index 4c699eab1b95..9901c0ec1415 100644 --- a/arch/ppc64/kernel/hvCall.S +++ b/arch/powerpc/platforms/iseries/hvcall.S @@ -1,7 +1,4 @@ /* - * arch/ppc64/kernel/hvCall.S - * - * * This file contains the code to perform calls to the * iSeries LPAR hypervisor * @@ -16,12 +13,12 @@ .text -/* +/* * Hypervisor call - * + * * Invoke the iSeries hypervisor via the System Call instruction * Parameters are passed to this routine in registers r3 - r10 - * + * * r3 contains the HV function to be called * r4-r10 contain the operands to the hypervisor function * @@ -41,11 +38,11 @@ _GLOBAL(HvCall7) mfcr r0 std r0,-8(r1) stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1) - + /* r0 = 0xffffffffffffffff indicates a hypervisor call */ - + li r0,-1 - + /* Invoke the hypervisor */ sc @@ -55,7 +52,7 @@ _GLOBAL(HvCall7) mtcrf 0xff,r0 /* return to caller, return value in r3 */ - + blr _GLOBAL(HvCall0Ret16) @@ -92,7 +89,5 @@ _GLOBAL(HvCall7Ret16) ld r0,-8(r1) mtcrf 0xff,r0 ld r31,-16(r1) - + blr - - diff --git a/arch/powerpc/platforms/iseries/hvcall.c b/arch/powerpc/platforms/iseries/hvlog.c similarity index 100% rename from arch/powerpc/platforms/iseries/hvcall.c rename to arch/powerpc/platforms/iseries/hvlog.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index e3bce4dda502..f84ae358db0a 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,8 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += hvCall.o \ - HvLpEvent.o iSeries_proc.o iSeries_htab.o \ +obj-$(CONFIG_PPC_ISERIES) += HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o From 544cbbaed4de962fb0e831e8799ab01c448ff37d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:18:47 +1000 Subject: [PATCH 0146/1940] powerpc: Merge HvLpEvent.c into lpevents.c These two files were intimately connected, so just merge them. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/lpevents.c | 68 +++++++++++++++++- arch/ppc64/kernel/HvLpEvent.c | 88 ----------------------- arch/ppc64/kernel/Makefile | 2 +- 3 files changed, 68 insertions(+), 90 deletions(-) delete mode 100644 arch/ppc64/kernel/HvLpEvent.c diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 819298a8a4db..883603027ccf 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * The LpQueue is used to pass event data from the hypervisor to @@ -42,7 +43,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = { }; /* Array of LpEvent handler functions */ -extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; static struct HvLpEvent * get_next_hvlpevent(void) { @@ -198,6 +200,70 @@ void setup_hvlpevent_queue(void) hvlpevent_queue.xIndex = 0; } +/* Register a handler for an LpEvent type */ +int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler) +{ + if (eventType < HvLpEvent_Type_NumTypes) { + lpEventHandler[eventType] = handler; + return 0; + } + return 1; +} +EXPORT_SYMBOL(HvLpEvent_registerHandler); + +int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType) +{ + might_sleep(); + + if (eventType < HvLpEvent_Type_NumTypes) { + if (!lpEventHandlerPaths[eventType]) { + lpEventHandler[eventType] = NULL; + /* + * We now sleep until all other CPUs have scheduled. + * This ensures that the deletion is seen by all + * other CPUs, and that the deleted handler isn't + * still running on another CPU when we return. + */ + synchronize_rcu(); + return 0; + } + } + return 1; +} +EXPORT_SYMBOL(HvLpEvent_unregisterHandler); + +/* + * lpIndex is the partition index of the target partition. + * needed only for VirtualIo, VirtualLan and SessionMgr. Zero + * indicates to use our partition index - for the other types. + */ +int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex) +{ + if ((eventType < HvLpEvent_Type_NumTypes) && + lpEventHandler[eventType]) { + if (lpIndex == 0) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_openLpEventPath(lpIndex, eventType); + ++lpEventHandlerPaths[eventType]; + return 0; + } + return 1; +} + +int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex) +{ + if ((eventType < HvLpEvent_Type_NumTypes) && + lpEventHandler[eventType] && + lpEventHandlerPaths[eventType]) { + if (lpIndex == 0) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_closeLpEventPath(lpIndex, eventType); + --lpEventHandlerPaths[eventType]; + return 0; + } + return 1; +} + static int proc_lpevents_show(struct seq_file *m, void *v) { int cpu, i; diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c deleted file mode 100644 index 90032b138902..000000000000 --- a/arch/ppc64/kernel/HvLpEvent.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2001 Mike Corrigan IBM Corp - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include - -/* Array of LpEvent handler functions */ -LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; - -/* Register a handler for an LpEvent type */ - -int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler ) -{ - int rc = 1; - if ( eventType < HvLpEvent_Type_NumTypes ) { - lpEventHandler[eventType] = handler; - rc = 0; - } - return rc; - -} - -int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ) -{ - int rc = 1; - - might_sleep(); - - if ( eventType < HvLpEvent_Type_NumTypes ) { - if ( !lpEventHandlerPaths[eventType] ) { - lpEventHandler[eventType] = NULL; - rc = 0; - - /* We now sleep until all other CPUs have scheduled. This ensures that - * the deletion is seen by all other CPUs, and that the deleted handler - * isn't still running on another CPU when we return. */ - synchronize_rcu(); - } - } - return rc; -} -EXPORT_SYMBOL(HvLpEvent_registerHandler); -EXPORT_SYMBOL(HvLpEvent_unregisterHandler); - -/* (lpIndex is the partition index of the target partition. - * needed only for VirtualIo, VirtualLan and SessionMgr. Zero - * indicates to use our partition index - for the other types) - */ -int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) -{ - int rc = 1; - if ( eventType < HvLpEvent_Type_NumTypes && - lpEventHandler[eventType] ) { - if ( lpIndex == 0 ) - lpIndex = itLpNaca.xLpIndex; - HvCallEvent_openLpEventPath( lpIndex, eventType ); - ++lpEventHandlerPaths[eventType]; - rc = 0; - } - return rc; -} - -int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) -{ - int rc = 1; - if ( eventType < HvLpEvent_Type_NumTypes && - lpEventHandler[eventType] && - lpEventHandlerPaths[eventType] ) { - if ( lpIndex == 0 ) - lpIndex = itLpNaca.xLpIndex; - HvCallEvent_closeLpEventPath( lpIndex, eventType ); - --lpEventHandlerPaths[eventType]; - rc = 0; - } - return rc; -} - diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index f84ae358db0a..a4e5c5b86c74 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,7 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += HvLpEvent.o iSeries_proc.o iSeries_htab.o \ +obj-$(CONFIG_PPC_ISERIES) += iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o From cb5c7980ab16c461a883ec7899675be57798d285 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:24:05 +1000 Subject: [PATCH 0147/1940] powerpc: move iSeries_proc.c to powerpc/platforms/iseries And renamed it to proc.c Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 3 ++- .../platforms/iseries/proc.c} | 10 ++++++---- arch/ppc64/kernel/Makefile | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) rename arch/{ppc64/kernel/iSeries_proc.c => powerpc/platforms/iseries/proc.c} (93%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 3a9981a35e2a..0bd671573c87 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1 +1,2 @@ -obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o hvcall.o +obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ + hvcall.o proc.o diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/powerpc/platforms/iseries/proc.c similarity index 93% rename from arch/ppc64/kernel/iSeries_proc.c rename to arch/powerpc/platforms/iseries/proc.c index 0fe3116eba29..d46b473ce4dd 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/powerpc/platforms/iseries/proc.c @@ -1,5 +1,4 @@ /* - * iSeries_proc.c * Copyright (C) 2001 Kyle A. Lucke IBM Corporation * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation * @@ -68,12 +67,15 @@ static int proc_titantod_show(struct seq_file *m, void *v) unsigned long tb_ticks = (tb0 - startTb); unsigned long titan_jiffies = titan_usec / (1000000/HZ); unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ); - unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec; + unsigned long titan_jiff_rem_usec = + titan_usec - titan_jiff_usec; unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy; unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy; unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks; - unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec; - unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec; + unsigned long tb_jiff_rem_usec = + tb_jiff_rem_ticks / tb_ticks_per_usec; + unsigned long new_tb_ticks_per_jiffy = + (tb_ticks * (1000000/HZ))/titan_usec; seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec); seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks); diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index a4e5c5b86c74..271b71d20d15 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,7 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_proc.o iSeries_htab.o \ +obj-$(CONFIG_PPC_ISERIES) += iSeries_htab.o \ iSeries_iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o From e508f438e0c152dcd1fbec5104e9c0ee28f352d4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:28:45 +1000 Subject: [PATCH 0148/1940] powerpc: Move iSeries_htab.c to powerpc/platforms/iseries And rename it to htab.c Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../platforms/iseries/htab.c} | 25 ++++++++++--------- arch/ppc64/kernel/Makefile | 3 +-- 3 files changed, 15 insertions(+), 15 deletions(-) rename arch/{ppc64/kernel/iSeries_htab.c => powerpc/platforms/iseries/htab.c} (94%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 0bd671573c87..4ef588c1b606 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,2 +1,2 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ - hvcall.o proc.o + hvcall.o proc.o htab.o diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/powerpc/platforms/iseries/htab.c similarity index 94% rename from arch/ppc64/kernel/iSeries_htab.c rename to arch/powerpc/platforms/iseries/htab.c index 9a2be3abf349..431b22767d06 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/powerpc/platforms/iseries/htab.c @@ -1,10 +1,10 @@ /* * iSeries hashtable management. - * Derived from pSeries_htab.c + * Derived from pSeries_htab.c * * SMP scalability work: * Copyright (C) 2001 Anton Blanchard , IBM - * + * * 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 @@ -18,7 +18,8 @@ #include #include -static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED}; +static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = + { [0 ... 63] = SPIN_LOCK_UNLOCKED}; /* * Very primitive algorithm for picking up a lock @@ -126,7 +127,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group) hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset); if (! (hpte_v & HPTE_V_BOLTED)) { - HvCallHpt_invalidateSetSwBitsGet(hpte_group + + HvCallHpt_invalidateSetSwBitsGet(hpte_group + slot_offset, 0, 0); iSeries_hunlock(hpte_group); return i; @@ -143,9 +144,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group) /* * The HyperVisor expects the "flags" argument in this form: - * bits 0..59 : reserved - * bit 60 : N - * bits 61..63 : PP2,PP1,PP0 + * bits 0..59 : reserved + * bit 60 : N + * bits 61..63 : PP2,PP1,PP0 */ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) @@ -171,7 +172,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, } /* - * Functions used to find the PTE for a particular virtual address. + * Functions used to find the PTE for a particular virtual address. * Only used during boot when bolting pages. * * Input : vpn : virtual page number @@ -189,7 +190,7 @@ static long iSeries_hpte_find(unsigned long vpn) * 0x00000000xxxxxxxx : Entry found in primary group, slot x * 0x80000000xxxxxxxx : Entry found in secondary group, slot x */ - slot = HvCallHpt_findValid(&hpte, vpn); + slot = HvCallHpt_findValid(&hpte, vpn); if (hpte.v & HPTE_V_VALID) { if (slot < 0) { slot &= 0x7fffffffffffffff; @@ -216,7 +217,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) vsid = get_kernel_vsid(ea); va = (vsid << 28) | (ea & 0x0fffffff); vpn = va >> PAGE_SHIFT; - slot = iSeries_hpte_find(vpn); + slot = iSeries_hpte_find(vpn); if (slot == -1) panic("updateboltedpp: Could not find page to bolt\n"); HvCallHpt_setPp(slot, newpp); @@ -234,7 +235,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, iSeries_hlock(slot); hpte_v = iSeries_hpte_getword0(slot); - + if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID)) HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0); @@ -249,7 +250,7 @@ void hpte_init_iSeries(void) ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_insert = iSeries_hpte_insert; - ppc_md.hpte_remove = iSeries_hpte_remove; + ppc_md.hpte_remove = iSeries_hpte_remove; htab_finish_init(); } diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 271b71d20d15..9225a6704e8a 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,8 +22,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_htab.o \ - iSeries_iommu.o +obj-$(CONFIG_PPC_ISERIES) += iSeries_iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o From cc14d430837e8854bd160275ad71d887a8a98488 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:32:16 +1000 Subject: [PATCH 0149/1940] powerpc: Move iSeries_iommu.c to powerpc/platforms/iseries And rename it to iommu.c Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../iSeries_iommu.c => powerpc/platforms/iseries/iommu.c} | 2 -- arch/ppc64/kernel/Makefile | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) rename arch/{ppc64/kernel/iSeries_iommu.c => powerpc/platforms/iseries/iommu.c} (99%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 4ef588c1b606..bf3992bf7ff8 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,2 +1,2 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ - hvcall.o proc.o htab.o + hvcall.o proc.o htab.o iommu.o diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/powerpc/platforms/iseries/iommu.c similarity index 99% rename from arch/ppc64/kernel/iSeries_iommu.c rename to arch/powerpc/platforms/iseries/iommu.c index 287db32d9867..65c76dd1d3de 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -1,6 +1,4 @@ /* - * arch/ppc64/kernel/iSeries_iommu.c - * * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * * Rewrite, cleanup: diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 9225a6704e8a..5988d555d36d 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -22,8 +22,6 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_iommu.o - obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ From d387899f3f7092edbafe16d69ea9737846473e99 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:50:25 +1000 Subject: [PATCH 0150/1940] powerpc: Move iSeries_pci.c to powerpc/platform/iseries and rename it to pci.c. This also required moving arch/ppc64/kernel/pci.h into include/asm-powerpc (called ppc-pci.h. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 1 + .../platforms/iseries/pci.c} | 66 +++++++++---------- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/bpa_iommu.c | 2 +- arch/ppc64/kernel/bpa_setup.c | 2 +- arch/ppc64/kernel/eeh.c | 2 +- arch/ppc64/kernel/maple_pci.c | 3 +- arch/ppc64/kernel/pSeries_iommu.c | 2 +- arch/ppc64/kernel/pSeries_pci.c | 3 +- arch/ppc64/kernel/pSeries_setup.c | 2 +- arch/ppc64/kernel/pci.c | 3 +- arch/ppc64/kernel/pci_direct_iommu.c | 3 +- arch/ppc64/kernel/pci_dn.c | 3 +- arch/ppc64/kernel/pci_iommu.c | 2 +- arch/ppc64/kernel/pmac_pci.c | 2 +- arch/ppc64/kernel/rtas_pci.c | 3 +- arch/ppc64/kernel/sys_ppc32.c | 3 +- arch/ppc64/kernel/u3_iommu.c | 3 +- .../pci.h => include/asm-powerpc/ppc-pci.h | 6 +- 19 files changed, 52 insertions(+), 61 deletions(-) rename arch/{ppc64/kernel/iSeries_pci.c => powerpc/platforms/iseries/pci.c} (95%) rename arch/ppc64/kernel/pci.h => include/asm-powerpc/ppc-pci.h (94%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index bf3992bf7ff8..7ee4592f83d3 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,2 +1,3 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/powerpc/platforms/iseries/pci.c similarity index 95% rename from arch/ppc64/kernel/iSeries_pci.c rename to arch/powerpc/platforms/iseries/pci.c index fbc273c32bcc..61a857218bc8 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -1,28 +1,26 @@ /* - * iSeries_pci.c - * * Copyright (C) 2001 Allan Trautman, IBM Corporation * * iSeries specific routines for PCI. - * + * * Based on code from pci.c and iSeries_pci.c 32bit * * 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include #include #include @@ -43,12 +41,12 @@ #include #include -#include "pci.h" +#include extern unsigned long io_page_mask; /* - * Forward declares of prototypes. + * Forward declares of prototypes. */ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn); static void scan_PHB_slots(struct pci_controller *Phb); @@ -68,7 +66,7 @@ static long Pci_Cfg_Write_Count; #endif static long Pci_Error_Count; -static int Pci_Retry_Max = 3; /* Only retry 3 times */ +static int Pci_Retry_Max = 3; /* Only retry 3 times */ static int Pci_Error_Flag = 1; /* Set Retry Error on. */ static struct pci_ops iSeries_pci_ops; @@ -179,7 +177,7 @@ static void allocate_device_bars(struct pci_dev *dev) for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) { bar_res = &dev->resource[bar_num]; iomm_table_allocate_entry(dev, bar_num); - } + } } /* @@ -278,28 +276,28 @@ unsigned long __init find_and_init_phbs(void) /* * iSeries_pcibios_init - * + * * Chance to initialize and structures or variable before PCI Bus walk. */ void iSeries_pcibios_init(void) { - PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); + PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); iomm_table_initialize(); find_and_init_phbs(); io_page_mask = -1; - PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); + PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); } /* - * iSeries_pci_final_fixup(void) + * iSeries_pci_final_fixup(void) */ void __init iSeries_pci_final_fixup(void) { struct pci_dev *pdev = NULL; struct iSeries_Device_Node *node; - int DeviceCount = 0; + int DeviceCount = 0; - PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); + PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); /* Fix up at the device node and pci_dev relationship */ mf_display_src(0xC9000100); @@ -332,24 +330,24 @@ void __init iSeries_pci_final_fixup(void) void pcibios_fixup_bus(struct pci_bus *PciBus) { PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n", - PciBus->number); + PciBus->number); } void pcibios_fixup_resources(struct pci_dev *pdev) { PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev); -} +} /* - * Loop through each node function to find usable EADs bridges. + * Loop through each node function to find usable EADs bridges. */ static void scan_PHB_slots(struct pci_controller *Phb) { struct HvCallPci_DeviceInfo *DevInfo; - HvBusNumber bus = Phb->local_number; /* System Bus */ + HvBusNumber bus = Phb->local_number; /* System Bus */ const HvSubBusNumber SubBus = 0; /* EADs is always 0. */ int HvRc = 0; - int IdSel; + int IdSel; const int MaxAgents = 8; DevInfo = (struct HvCallPci_DeviceInfo*) @@ -358,10 +356,10 @@ static void scan_PHB_slots(struct pci_controller *Phb) return; /* - * Probe for EADs Bridges + * Probe for EADs Bridges */ for (IdSel = 1; IdSel < MaxAgents; ++IdSel) { - HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, + HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, ISERIES_HV_ADDR(DevInfo), sizeof(struct HvCallPci_DeviceInfo)); if (HvRc == 0) { @@ -393,19 +391,19 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, /* Note: hvSubBus and irq is always be 0 at this level! */ for (Function = 0; Function < 8; ++Function) { - AgentId = ISERIES_PCI_AGENTID(IdSel, Function); + AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0); - if (HvRc == 0) { + if (HvRc == 0) { printk("found device at bus %d idsel %d func %d (AgentId %x)\n", bus, IdSel, Function, AgentId); - /* Connect EADs: 0x18.00.12 = 0x00 */ + /* Connect EADs: 0x18.00.12 = 0x00 */ PPCDBG(PPCDBG_BUSWALK, "PCI:Connect EADs: 0x%02X.%02X.%02X\n", bus, SubBus, AgentId); - HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, + HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, ISERIES_HV_ADDR(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo)); - if (HvRc == 0) { + if (HvRc == 0) { printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n", BridgeInfo->busUnitInfo.deviceType, BridgeInfo->subBusNumber, @@ -428,7 +426,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, printk("PCI: Invalid Bridge Configuration(0x%02X)", BridgeInfo->busUnitInfo.deviceType); } - } else if (HvRc != 0x000B) + } else if (HvRc != 0x000B) pci_Log_Error("EADs Connect", bus, SubBus, AgentId, HvRc); } @@ -451,16 +449,16 @@ static int scan_bridge_slot(HvBusNumber Bus, HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function); /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */ - Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel); + Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel); PPCDBG(PPCDBG_BUSWALK, "PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n", Bus, 0, EADsIdSel, Irq); /* - * Connect all functions of any device found. + * Connect all functions of any device found. */ - for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { - for (Function = 0; Function < 8; ++Function) { + for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { + for (Function = 0; Function < 8; ++Function) { HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq); @@ -484,7 +482,7 @@ static int scan_bridge_slot(HvBusNumber Bus, "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n", Bus, SubBus, AgentId, VendorId, Irq); HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, - PCI_INTERRUPT_LINE, Irq); + PCI_INTERRUPT_LINE, Irq); if (HvRc != 0) pci_Log_Error("PciCfgStore Irq Failed!", Bus, SubBus, AgentId, HvRc); diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 5988d555d36d..8473a8784567 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,7 +16,7 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \ +pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ iSeries_VpdInfo.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c index f33a7bccb0d7..0cc463f24539 100644 --- a/arch/ppc64/kernel/bpa_iommu.c +++ b/arch/ppc64/kernel/bpa_iommu.c @@ -39,8 +39,8 @@ #include #include #include +#include -#include "pci.h" #include "bpa_iommu.h" static inline unsigned long diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c index 57b3db66f458..9f915f4222b1 100644 --- a/arch/ppc64/kernel/bpa_setup.c +++ b/arch/ppc64/kernel/bpa_setup.c @@ -43,8 +43,8 @@ #include #include #include +#include -#include "pci.h" #include "bpa_iic.h" #include "bpa_iommu.h" diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index ba93fd731222..035d1b14a207 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -33,7 +33,7 @@ #include #include #include -#include "pci.h" +#include #undef DEBUG diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c index 1d297e0edfc0..0937649f4961 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/ppc64/kernel/maple_pci.c @@ -23,8 +23,7 @@ #include #include #include - -#include "pci.h" +#include #ifdef DEBUG #define DBG(x...) printk(x) diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 5914f61a152e..9e90d41131d8 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -47,7 +47,7 @@ #include #include #include -#include "pci.h" +#include #define DBG(fmt...) diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c index 1f5f141fb7a1..2dd477eb1c53 100644 --- a/arch/ppc64/kernel/pSeries_pci.c +++ b/arch/ppc64/kernel/pSeries_pci.c @@ -29,8 +29,7 @@ #include #include - -#include "pci.h" +#include static int __initdata s7a_workaround = -1; diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index b9bcff21b463..5a9fe96f9f67 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c @@ -63,9 +63,9 @@ #include #include #include +#include #include "i8259.h" -#include "pci.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index ff4be1da69d5..feec06bbafc3 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -31,8 +31,7 @@ #include #include #include - -#include "pci.h" +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c index b8f7f58824f4..57980a5674d7 100644 --- a/arch/ppc64/kernel/pci_direct_iommu.c +++ b/arch/ppc64/kernel/pci_direct_iommu.c @@ -27,8 +27,7 @@ #include #include #include - -#include "pci.h" +#include static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, unsigned int __nocast flag) diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c index a86389d07d57..493bbe43f5b4 100644 --- a/arch/ppc64/kernel/pci_dn.c +++ b/arch/ppc64/kernel/pci_dn.c @@ -30,8 +30,7 @@ #include #include #include - -#include "pci.h" +#include /* * Traverse_func that inits the PCI fields of the device node. diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index 14647e09c9cd..19362ea11572 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c @@ -37,7 +37,7 @@ #include #include #include -#include "pci.h" +#include #ifdef CONFIG_PPC_ISERIES #include diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index 1f61aa4746ec..f139fc034199 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -27,8 +27,8 @@ #include #include #include +#include -#include "pci.h" #include "pmac.h" #define DEBUG diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c index 4d920dd41dc6..20361bcd8cfb 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/ppc64/kernel/rtas_pci.c @@ -39,8 +39,7 @@ #include #include #include - -#include "pci.h" +#include /* RTAS tokens */ static int read_pci_config; diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index e93c13458910..1cacf61f9c91 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -53,8 +53,7 @@ #include #include #include - -#include "pci.h" +#include /* readdir & getdents */ #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index df9c775f4955..fba871a1bda5 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c @@ -45,8 +45,7 @@ #include #include #include - -#include "pci.h" +#include extern int iommu_force_on; diff --git a/arch/ppc64/kernel/pci.h b/include/asm-powerpc/ppc-pci.h similarity index 94% rename from arch/ppc64/kernel/pci.h rename to include/asm-powerpc/ppc-pci.h index 5eb2cc320566..a88728fba8f6 100644 --- a/arch/ppc64/kernel/pci.h +++ b/include/asm-powerpc/ppc-pci.h @@ -6,8 +6,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#ifndef __PPC_KERNEL_PCI_H__ -#define __PPC_KERNEL_PCI_H__ +#ifndef _ASM_POWERPC_PPC_PCI_H +#define _ASM_POWERPC_PPC_PCI_H #include #include @@ -51,4 +51,4 @@ extern unsigned long pci_probe_only; extern unsigned long pci_assign_all_buses; extern int pci_read_irq_line(struct pci_dev *pci_dev); -#endif /* __PPC_KERNEL_PCI_H__ */ +#endif /* _ASM_POWERPC_PPC_PCI_H */ From cb4cf8056ead24ef0595859952319e2a608d5e07 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:54:39 +1000 Subject: [PATCH 0151/1940] powerpc: Move iSeries_irq.c to powerpc/platorms/iseries And rename it to irq.c. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../kernel/iSeries_irq.c => powerpc/platforms/iseries/irq.c} | 1 - arch/ppc64/kernel/Makefile | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) rename arch/{ppc64/kernel/iSeries_irq.c => powerpc/platforms/iseries/irq.c} (99%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 7ee4592f83d3..e5d6ab9e30bb 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,3 +1,3 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o -obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PCI) += pci.o irq.o diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/powerpc/platforms/iseries/irq.c similarity index 99% rename from arch/ppc64/kernel/iSeries_irq.c rename to arch/powerpc/platforms/iseries/irq.c index 0170682a8ca5..5a8a0056b31f 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -363,4 +363,3 @@ void virt_irq_init(void) { return; } - diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 8473a8784567..2ff5d490e725 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,8 +16,7 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ - iSeries_VpdInfo.o +pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_VpdInfo.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) From da3420fcd62a8967c14a586355e322253a1504a8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 02:59:19 +1000 Subject: [PATCH 0152/1940] powerpc: Move iSeries_VpdInfo.c to powerpc/platforms/iseries And rename it to vpdinfo.c. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 2 +- .../iSeries_VpdInfo.c => powerpc/platforms/iseries/vpdinfo.c} | 2 -- arch/ppc64/kernel/Makefile | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) rename arch/{ppc64/kernel/iSeries_VpdInfo.c => powerpc/platforms/iseries/vpdinfo.c} (98%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index e5d6ab9e30bb..d10305d7ad2f 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,3 +1,3 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o -obj-$(CONFIG_PCI) += pci.o irq.o +obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c similarity index 98% rename from arch/ppc64/kernel/iSeries_VpdInfo.c rename to arch/powerpc/platforms/iseries/vpdinfo.c index 5d921792571f..8b62f3bf1d26 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -1,6 +1,4 @@ /* - * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. - * * This code gets the card location of the hardware * Copyright (C) 2001 * Copyright (C) 2005 Stephen Rothwel, IBM Corp diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 2ff5d490e725..8b2743697c38 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,7 +16,6 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_VpdInfo.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) From ed7f2c05de956da72baf066701ac642f7215dbf5 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 03:03:00 +1000 Subject: [PATCH 0153/1940] powerpc: Move iSeries_vio.c to powerpc/platforms/iseries And rename it to vio.c. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 1 + .../kernel/iSeries_vio.c => powerpc/platforms/iseries/vio.c} | 0 arch/ppc64/kernel/Makefile | 1 - 3 files changed, 1 insertion(+), 1 deletion(-) rename arch/{ppc64/kernel/iSeries_vio.c => powerpc/platforms/iseries/vio.c} (100%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index d10305d7ad2f..3a1ed16963a4 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,3 +1,4 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o +obj-$(CONFIG_IBMVIO) += vio.o diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/powerpc/platforms/iseries/vio.c similarity index 100% rename from arch/ppc64/kernel/iSeries_vio.c rename to arch/powerpc/platforms/iseries/vio.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 8b2743697c38..7354c1dbe9f0 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_HVCS) += hvcserver.o vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o -vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y) obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_MPIC) += mpic.o From b6b8681843f9eaee12f8c30ffac399f7b2601ab3 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 03:07:14 +1000 Subject: [PATCH 0154/1940] powerpc: Move iSeries_smp.c to powerpc/platforms/iseries And rename it to smp.c. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 1 + .../platforms/iseries/smp.c} | 16 ++++++++-------- arch/ppc64/kernel/Makefile | 1 - 3 files changed, 9 insertions(+), 9 deletions(-) rename arch/{ppc64/kernel/iSeries_smp.c => powerpc/platforms/iseries/smp.c} (88%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 3a1ed16963a4..202f17419df5 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -2,3 +2,4 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o obj-$(CONFIG_IBMVIO) += vio.o +obj-$(CONFIG_SMP) += smp.o diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/powerpc/platforms/iseries/smp.c similarity index 88% rename from arch/ppc64/kernel/iSeries_smp.c rename to arch/powerpc/platforms/iseries/smp.c index f982e5b805f4..f720916682f6 100644 --- a/arch/ppc64/kernel/iSeries_smp.c +++ b/arch/powerpc/platforms/iseries/smp.c @@ -47,17 +47,17 @@ static unsigned long iSeries_smp_message[NR_CPUS]; -void iSeries_smp_message_recv( struct pt_regs * regs ) +void iSeries_smp_message_recv(struct pt_regs *regs) { int cpu = smp_processor_id(); int msg; - if ( num_online_cpus() < 2 ) + if (num_online_cpus() < 2) return; - for ( msg = 0; msg < 4; ++msg ) - if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) ) - smp_message_recv( msg, regs ); + for (msg = 0; msg < 4; msg++) + if (test_and_clear_bit(msg, &iSeries_smp_message[cpu])) + smp_message_recv(msg, regs); } static inline void smp_iSeries_do_message(int cpu, int msg) @@ -74,8 +74,8 @@ static void smp_iSeries_message_pass(int target, int msg) smp_iSeries_do_message(target, msg); else { for_each_online_cpu(i) { - if (target == MSG_ALL_BUT_SELF - && i == smp_processor_id()) + if ((target == MSG_ALL_BUT_SELF) && + (i == smp_processor_id())) continue; smp_iSeries_do_message(i, msg); } @@ -89,7 +89,7 @@ static int smp_iSeries_probe(void) static void smp_iSeries_kick_cpu(int nr) { - BUG_ON(nr < 0 || nr >= NR_CPUS); + BUG_ON((nr < 0) || (nr >= NR_CPUS)); /* Verify that our partition has a processor nr */ if (paca[nr].lppaca.dyn_proc_status >= 2) diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 7354c1dbe9f0..ee88fca0c886 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_U3_DART) += u3_iommu.o ifdef CONFIG_SMP obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o -obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o obj-$(CONFIG_PPC_BPA) += pSeries_smp.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o From d223e721b743787fad71f6aef5e860176214c8f9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 03:12:35 +1000 Subject: [PATCH 0155/1940] powerpc: Move viopath.c to powerpc/platforms/iseries Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 1 + arch/{ppc64/kernel => powerpc/platforms/iseries}/viopath.c | 3 +-- arch/ppc64/kernel/Makefile | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) rename arch/{ppc64/kernel => powerpc/platforms/iseries}/viopath.c (99%) diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 202f17419df5..5a27b888103c 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -3,3 +3,4 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_VIOPATH) += viopath.o diff --git a/arch/ppc64/kernel/viopath.c b/arch/powerpc/platforms/iseries/viopath.c similarity index 99% rename from arch/ppc64/kernel/viopath.c rename to arch/powerpc/platforms/iseries/viopath.c index 2a6c4f01c45e..c0c767bd37f1 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -1,5 +1,4 @@ /* -*- linux-c -*- - * arch/ppc64/kernel/viopath.c * * iSeries Virtual I/O Message Path code * @@ -7,7 +6,7 @@ * Ryan Arnold * Colin Devilbiss * - * (C) Copyright 2000-2003 IBM Corporation + * (C) Copyright 2000-2005 IBM Corporation * * This code is used by the iSeries virtual disk, cd, * tape, and console to communicate with OS/400 in another diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index ee88fca0c886..bb5946b88b8b 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_SCANLOG) += scanlog.o -obj-$(CONFIG_VIOPATH) += viopath.o obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_BOOTX_TEXT) += btext.o From 7b875f4dc345dc5f6a2c3bd0e1f90bfee46b2258 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 09:40:24 +1000 Subject: [PATCH 0156/1940] powerpc: Make powerpc pmac 32 bit build again Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 697addea192f..7637ff3642c3 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -1,4 +1,6 @@ +ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_PPC_PMAC) += powermac/ +endif obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_83xx) += 83xx/ obj-$(CONFIG_85xx) += 85xx/ From c111d0bda8437d146ccf5101970801fe4ff23ed8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 13:28:01 +1000 Subject: [PATCH 0157/1940] powerpc: move more iSeries code Move the iSeries specific parts of misc.S and ppc_ksyms.c into powerpc/platforms/iseries. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/Makefile | 3 +- arch/powerpc/platforms/iseries/ksyms.c | 27 ++++++++++++ arch/powerpc/platforms/iseries/misc.S | 55 +++++++++++++++++++++++++ arch/ppc64/kernel/misc.S | 38 ----------------- arch/ppc64/kernel/ppc_ksyms.c | 20 --------- 5 files changed, 84 insertions(+), 59 deletions(-) create mode 100644 arch/powerpc/platforms/iseries/ksyms.c create mode 100644 arch/powerpc/platforms/iseries/misc.S diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 5a27b888103c..18bf40077561 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,6 +1,7 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ - hvcall.o proc.o htab.o iommu.o + hvcall.o proc.o htab.o iommu.o misc.o obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_VIOPATH) += viopath.o +obj-$(CONFIG_MODULES) += ksyms.o diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c new file mode 100644 index 000000000000..f271b3539721 --- /dev/null +++ b/arch/powerpc/platforms/iseries/ksyms.c @@ -0,0 +1,27 @@ +/* + * (C) 2001-2005 PPC 64 Team, IBM Corp + * + * 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. + */ +#include + +#include +#include + +EXPORT_SYMBOL(HvCall0); +EXPORT_SYMBOL(HvCall1); +EXPORT_SYMBOL(HvCall2); +EXPORT_SYMBOL(HvCall3); +EXPORT_SYMBOL(HvCall4); +EXPORT_SYMBOL(HvCall5); +EXPORT_SYMBOL(HvCall6); +EXPORT_SYMBOL(HvCall7); + +#ifdef CONFIG_SMP +EXPORT_SYMBOL(local_get_flags); +EXPORT_SYMBOL(local_irq_disable); +EXPORT_SYMBOL(local_irq_restore); +#endif diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S new file mode 100644 index 000000000000..09f14522e176 --- /dev/null +++ b/arch/powerpc/platforms/iseries/misc.S @@ -0,0 +1,55 @@ +/* + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-2005 IBM Corp + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * 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. + */ + +#include +#include + + .text + +/* unsigned long local_save_flags(void) */ +_GLOBAL(local_get_flags) + lbz r3,PACAPROCENABLED(r13) + blr + +/* unsigned long local_irq_disable(void) */ +_GLOBAL(local_irq_disable) + lbz r3,PACAPROCENABLED(r13) + li r4,0 + stb r4,PACAPROCENABLED(r13) + blr /* Done */ + +/* void local_irq_restore(unsigned long flags) */ +_GLOBAL(local_irq_restore) + lbz r5,PACAPROCENABLED(r13) + /* Check if things are setup the way we want _already_. */ + cmpw 0,r3,r5 + beqlr + /* are we enabling interrupts? */ + cmpdi 0,r3,0 + stb r3,PACAPROCENABLED(r13) + beqlr + /* Check pending interrupts */ + /* A decrementer, IPI or PMC interrupt may have occurred + * while we were in the hypervisor (which enables) */ + ld r4,PACALPPACA+LPPACAANYINT(r13) + cmpdi r4,0 + beqlr + + /* + * Handle pending interrupts in interrupt context + */ + li r0,0x5555 + sc + blr diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index a25b59759ddb..d069bbd7f81f 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -64,44 +64,6 @@ _GLOBAL(get_srr1) _GLOBAL(get_sp) mr r3,r1 blr - -#ifdef CONFIG_PPC_ISERIES -/* unsigned long local_save_flags(void) */ -_GLOBAL(local_get_flags) - lbz r3,PACAPROCENABLED(r13) - blr - -/* unsigned long local_irq_disable(void) */ -_GLOBAL(local_irq_disable) - lbz r3,PACAPROCENABLED(r13) - li r4,0 - stb r4,PACAPROCENABLED(r13) - blr /* Done */ - -/* void local_irq_restore(unsigned long flags) */ -_GLOBAL(local_irq_restore) - lbz r5,PACAPROCENABLED(r13) - /* Check if things are setup the way we want _already_. */ - cmpw 0,r3,r5 - beqlr - /* are we enabling interrupts? */ - cmpdi 0,r3,0 - stb r3,PACAPROCENABLED(r13) - beqlr - /* Check pending interrupts */ - /* A decrementer, IPI or PMC interrupt may have occurred - * while we were in the hypervisor (which enables) */ - ld r4,PACALPPACA+LPPACAANYINT(r13) - cmpdi r4,0 - beqlr - - /* - * Handle pending interrupts in interrupt context - */ - li r0,0x5555 - sc - blr -#endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index 705742f4eec6..84006e26342c 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -19,7 +19,6 @@ #include #include #include -#include EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strncpy); @@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(reloc_offset); -#ifdef CONFIG_PPC_ISERIES -EXPORT_SYMBOL(HvCall0); -EXPORT_SYMBOL(HvCall1); -EXPORT_SYMBOL(HvCall2); -EXPORT_SYMBOL(HvCall3); -EXPORT_SYMBOL(HvCall4); -EXPORT_SYMBOL(HvCall5); -EXPORT_SYMBOL(HvCall6); -EXPORT_SYMBOL(HvCall7); -#endif - EXPORT_SYMBOL(_insb); EXPORT_SYMBOL(_outsb); EXPORT_SYMBOL(_insw); @@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec); EXPORT_SYMBOL(__flush_icache_range); EXPORT_SYMBOL(flush_dcache_range); -#ifdef CONFIG_SMP -#ifdef CONFIG_PPC_ISERIES -EXPORT_SYMBOL(local_get_flags); -EXPORT_SYMBOL(local_irq_disable); -EXPORT_SYMBOL(local_irq_restore); -#endif -#endif - EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); From 252e75a51d40757928d692b3d339e66838294b4b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 14:40:40 +1000 Subject: [PATCH 0158/1940] ppc64 iSeries: use device_node instead of iSeries_Device_node There needs to be more cleanup after this. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/iommu.c | 29 ++++---- arch/powerpc/platforms/iseries/pci.c | 91 +++++++++++++----------- arch/powerpc/platforms/iseries/vpdinfo.c | 2 +- arch/ppc64/kernel/pci_iommu.c | 6 -- include/asm-ppc64/iSeries/iSeries_pci.h | 30 ++------ include/asm-ppc64/iommu.h | 4 +- include/asm-ppc64/pci-bridge.h | 10 +++ include/asm-ppc64/prom.h | 3 + 8 files changed, 88 insertions(+), 87 deletions(-) diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 65c76dd1d3de..9ac735d5b817 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -89,15 +89,17 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) */ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { - struct iSeries_Device_Node *dp; + struct device_node *dp; list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { - if ((dp->iommu_table != NULL) && - (dp->iommu_table->it_type == TCE_PCI) && - (dp->iommu_table->it_offset == tbl->it_offset) && - (dp->iommu_table->it_index == tbl->it_index) && - (dp->iommu_table->it_size == tbl->it_size)) - return dp->iommu_table; + struct iommu_table *it = PCI_DN(dp)->iommu_table; + + if ((it != NULL) && + (it->it_type == TCE_PCI) && + (it->it_offset == tbl->it_offset) && + (it->it_index == tbl->it_index) && + (it->it_size == tbl->it_size)) + return it; } return NULL; } @@ -111,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) * 2. TCE table per Bus. * 3. TCE Table per IOA. */ -static void iommu_table_getparms(struct iSeries_Device_Node* dn, +static void iommu_table_getparms(struct device_node *dn, struct iommu_table* tbl) { struct iommu_table_cb *parms; @@ -123,7 +125,7 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, memset(parms, 0, sizeof(*parms)); parms->itc_busno = ISERIES_BUS(dn); - parms->itc_slotno = dn->LogicalSlot; + parms->itc_slotno = PCI_DN(dn)->LogicalSlot; parms->itc_virtbus = 0; HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); @@ -143,18 +145,19 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, } -void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) +void iommu_devnode_init_iSeries(struct device_node *dn) { struct iommu_table *tbl; + struct pci_dn *pdn = PCI_DN(dn); tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_getparms(dn, tbl); /* Look for existing tce table */ - dn->iommu_table = iommu_table_find(tbl); - if (dn->iommu_table == NULL) - dn->iommu_table = iommu_init_table(tbl); + pdn->iommu_table = iommu_table_find(tbl); + if (pdn->iommu_table == NULL) + pdn->iommu_table = iommu_init_table(tbl); else kfree(tbl); } diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 61a857218bc8..501b1dcbfac5 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -48,7 +48,7 @@ extern unsigned long io_page_mask; /* * Forward declares of prototypes. */ -static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn); +static struct device_node *find_Device_Node(int bus, int devfn); static void scan_PHB_slots(struct pci_controller *Phb); static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel); static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info); @@ -85,7 +85,7 @@ static long current_iomm_table_entry; /* * Lookup Tables. */ -static struct iSeries_Device_Node **iomm_table; +static struct device_node **iomm_table; static u8 *iobar_table; /* @@ -199,29 +199,35 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, /* * build_device_node(u16 Bus, int SubBus, u8 DevFn) */ -static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, +static struct device_node *build_device_node(HvBusNumber Bus, HvSubBusNumber SubBus, int AgentId, int Function) { - struct iSeries_Device_Node *node; + struct device_node *node; + struct pci_dn *pdn; PPCDBG(PPCDBG_BUSWALK, "-build_device_node 0x%02X.%02X.%02X Function: %02X\n", Bus, SubBus, AgentId, Function); - node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL); + node = kmalloc(sizeof(struct device_node), GFP_KERNEL); if (node == NULL) return NULL; - - memset(node, 0, sizeof(struct iSeries_Device_Node)); + memset(node, 0, sizeof(struct device_node)); + pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + if (pdn == NULL) { + kfree(node); + return NULL; + } + node->data = pdn; list_add_tail(&node->Device_List, &iSeries_Global_Device_List); #if 0 - node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); + pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); #endif - node->DsaAddr.DsaAddr = 0; - node->DsaAddr.Dsa.busNumber = Bus; - node->DsaAddr.Dsa.subBusNumber = SubBus; - node->DsaAddr.Dsa.deviceId = 0x10; - node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); + pdn->DsaAddr.DsaAddr = 0; + pdn->DsaAddr.Dsa.busNumber = Bus; + pdn->DsaAddr.Dsa.subBusNumber = SubBus; + pdn->DsaAddr.Dsa.deviceId = 0x10; + pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); return node; } @@ -294,7 +300,7 @@ void iSeries_pcibios_init(void) void __init iSeries_pci_final_fixup(void) { struct pci_dev *pdev = NULL; - struct iSeries_Device_Node *node; + struct device_node *node; int DeviceCount = 0; PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); @@ -311,7 +317,7 @@ void __init iSeries_pci_final_fixup(void) if (node != NULL) { ++DeviceCount; pdev->sysdata = (void *)node; - node->PciDev = pdev; + PCI_DN(node)->pcidev = pdev; PPCDBG(PPCDBG_BUSWALK, "pdev 0x%p <==> DevNode 0x%p\n", pdev, node); @@ -321,7 +327,7 @@ void __init iSeries_pci_final_fixup(void) } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); - pdev->irq = node->Irq; + pdev->irq = PCI_DN(node)->Irq; } iSeries_activate_IRQs(); mf_display_src(0xC9000200); @@ -439,7 +445,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *BridgeInfo) { - struct iSeries_Device_Node *node; + struct device_node *node; HvSubBusNumber SubBus = BridgeInfo->subBusNumber; u16 VendorId = 0; int HvRc = 0; @@ -489,8 +495,8 @@ static int scan_bridge_slot(HvBusNumber Bus, ++DeviceCount; node = build_device_node(Bus, SubBus, EADsIdSel, Function); - node->Irq = Irq; - node->LogicalSlot = BridgeInfo->logicalSlotNumber; + PCI_DN(node)->Irq = Irq; + PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber; } /* for (Function = 0; Function < 8; ++Function) */ } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ @@ -540,15 +546,16 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio); /* * Look down the chain to find the matching Device Device */ -static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn) +static struct device_node *find_Device_Node(int bus, int devfn) { struct list_head *pos; list_for_each(pos, &iSeries_Global_Device_List) { - struct iSeries_Device_Node *node = - list_entry(pos, struct iSeries_Device_Node, Device_List); + struct device_node *node = + list_entry(pos, struct device_node, Device_List); - if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn)) + if ((bus == ISERIES_BUS(node)) && + (devfn == PCI_DN(node)->devfn)) return node; } return NULL; @@ -560,12 +567,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn) * Sanity Check Node PciDev to passed pci_dev * If none is found, returns a NULL which the client must handle. */ -static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev) +static struct device_node *get_Device_Node(struct pci_dev *pdev) { - struct iSeries_Device_Node *node; + struct device_node *node; node = pdev->sysdata; - if (node == NULL || node->PciDev != pdev) + if (node == NULL || PCI_DN(node)->pcidev != pdev) node = find_Device_Node(pdev->bus->number, pdev->devfn); return node; } @@ -593,7 +600,7 @@ static u64 hv_cfg_write_func[4] = { static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int size, u32 *val) { - struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); + struct device_node *node = find_Device_Node(bus->number, devfn); u64 fn; struct HvCallPci_LoadReturn ret; @@ -605,7 +612,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, } fn = hv_cfg_read_func[(size - 1) & 3]; - HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0); + HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0); if (ret.rc != 0) { *val = ~0; @@ -623,7 +630,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int size, u32 val) { - struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); + struct device_node *node = find_Device_Node(bus->number, devfn); u64 fn; u64 ret; @@ -633,7 +640,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_BAD_REGISTER_NUMBER; fn = hv_cfg_write_func[(size - 1) & 3]; - ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0); + ret = HvCall4(fn, PCI_DN(node)->DsaAddr.DsaAddr, offset, val, 0); if (ret != 0) return PCIBIOS_DEVICE_NOT_FOUND; @@ -655,14 +662,16 @@ static struct pci_ops iSeries_pci_ops = { * PCI: Device 23.90 ReadL Retry( 1) * PCI: Device 23.90 ReadL Retry Successful(1) */ -static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, +static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, int *retry, u64 ret) { if (ret != 0) { + struct pci_dn *pdn = PCI_DN(DevNode); + ++Pci_Error_Count; (*retry)++; printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", - TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, + TextHdr, pdn->DsaAddr.Dsa.busNumber, pdn->devfn, *retry, (int)ret); /* * Bump the retry and check for retry count exceeded. @@ -685,14 +694,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, * Note: Make sure the passed variable end up on the stack to avoid * the exposure of being device global. */ -static inline struct iSeries_Device_Node *xlate_iomm_address( +static inline struct device_node *xlate_iomm_address( const volatile void __iomem *IoAddress, u64 *dsaptr, u64 *BarOffsetPtr) { unsigned long OrigIoAddr; unsigned long BaseIoAddr; unsigned long TableIndex; - struct iSeries_Device_Node *DevNode; + struct device_node *DevNode; OrigIoAddr = (unsigned long __force)IoAddress; if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) @@ -703,7 +712,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address( if (DevNode != NULL) { int barnum = iobar_table[TableIndex]; - *dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24); + *dsaptr = PCI_DN(DevNode)->DsaAddr.DsaAddr | (barnum << 24); *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; } else panic("PCI: Invalid PCI IoAddress detected!\n"); @@ -725,7 +734,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -755,7 +764,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -786,7 +795,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -824,7 +833,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -852,7 +861,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -880,7 +889,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index 8b62f3bf1d26..d8a6796924e2 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -240,7 +240,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, */ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) { - struct iSeries_Device_Node *DevNode = PciDev->sysdata; + struct device_node *DevNode = PciDev->sysdata; u16 bus; u8 frame; char card[4]; diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index 19362ea11572..6c9dc67f59d8 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c @@ -61,13 +61,7 @@ static inline struct iommu_table *devnode_table(struct device *dev) } else pdev = to_pci_dev(dev); -#ifdef CONFIG_PPC_ISERIES - return ISERIES_DEVNODE(pdev)->iommu_table; -#endif /* CONFIG_PPC_ISERIES */ - -#ifdef CONFIG_PPC_MULTIPLATFORM return PCI_DN(PCI_GET_DN(pdev))->iommu_table; -#endif /* CONFIG_PPC_MULTIPLATFORM */ } diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 575f611f8b33..a4d88b49fd9f 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -30,21 +30,19 @@ * End Change Activity */ -#include #include +#include +#include struct pci_dev; /* For Forward Reference */ -struct iSeries_Device_Node; /* - * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure + * Gets iSeries Bus, SubBus, DevFn using device_node structure */ -#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber -#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber -#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId -#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr -#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata) +#define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber +#define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber +#define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata) #define EADsMaxAgents 7 @@ -67,22 +65,6 @@ struct iSeries_Device_Node; #define ISERIES_HV_ADDR(virtaddr) \ (0x8000000000000000 | virt_to_abs(virtaddr)) -/* - * iSeries Device Information - */ -struct iSeries_Device_Node { - struct list_head Device_List; - struct pci_dev *PciDev; - union HvDsaMap DsaAddr; /* Direct Select Address */ - /* busNumber, subBusNumber, */ - /* deviceId, barNumber */ - int DevFn; /* Linux devfn */ - int Irq; /* Assigned IRQ */ - int Flags; /* Possible flags(disable/bist)*/ - u8 LogicalSlot; /* Hv Slot Index for Tces */ - struct iommu_table *iommu_table;/* Device TCE Table */ -}; - extern void iSeries_Device_Information(struct pci_dev*, int); #endif /* _ISERIES_64_PCI_H */ diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index a6a173d49506..d096faf4191e 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -49,6 +49,7 @@ struct iommu_table { }; struct scatterlist; +struct device_node; #ifdef CONFIG_PPC_MULTIPLATFORM @@ -70,9 +71,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn); #ifdef CONFIG_PPC_ISERIES -struct iSeries_Device_Node; /* Creates table for an individual device node */ -extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn); +extern void iommu_devnode_init_iSeries(struct device_node *dn); #endif /* CONFIG_PPC_ISERIES */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index d8991389ab39..8ca5fce626bb 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -4,6 +4,8 @@ #include +#include + /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -71,6 +73,14 @@ struct pci_dn { struct iommu_table *iommu_table; /* for phb's or bridges */ struct pci_dev *pcidev; /* back-pointer to the pci device */ struct device_node *node; /* back-pointer to the device_node */ +#ifdef CONFIG_PPC_ISERIES + union HvDsaMap DsaAddr; /* Direct Select Address */ + /* busNumber, subBusNumber, */ + /* deviceId, barNumber */ + int Irq; /* Assigned IRQ */ + int Flags; /* Possible flags(disable/bist)*/ + u8 LogicalSlot; /* Hv Slot Index for Tces */ +#endif u32 config_space[16]; /* saved PCI config space */ }; diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index c02ec1d6b909..cf0284e081ea 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h @@ -137,6 +137,9 @@ struct device_node { struct kref kref; unsigned long _flags; void *data; +#ifdef CONFIG_PPC_ISERIES + struct list_head Device_List; +#endif }; extern struct device_node *of_chosen; From a559c91d77c3220be521453bd23815e1e1980a82 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Tue, 27 Sep 2005 14:28:56 -0500 Subject: [PATCH 0159/1940] [PATCH] powerpc: merge byteorder.h powerpc: Merge byteorder.h Essentially adopts the 64-bit version of this file. The 32-bit version had been using unsigned ints for arguments/return values that were actually only 16 bits - the new file uses __u16 for these items as in the 64-bit version of the header. The order of some of the asm constraints in the 64-bit version was slightly different than the 32-bit version, but they produce identical code. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- .../{asm-ppc64 => asm-powerpc}/byteorder.h | 11 ++- include/asm-ppc/byteorder.h | 76 ------------------- 2 files changed, 7 insertions(+), 80 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/byteorder.h (90%) delete mode 100644 include/asm-ppc/byteorder.h diff --git a/include/asm-ppc64/byteorder.h b/include/asm-powerpc/byteorder.h similarity index 90% rename from include/asm-ppc64/byteorder.h rename to include/asm-powerpc/byteorder.h index 8b57da62b674..b37752214a16 100644 --- a/include/asm-ppc64/byteorder.h +++ b/include/asm-powerpc/byteorder.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_BYTEORDER_H -#define _PPC64_BYTEORDER_H +#ifndef _ASM_POWERPC_BYTEORDER_H +#define _ASM_POWERPC_BYTEORDER_H /* * This program is free software; you can redistribute it and/or @@ -77,10 +77,13 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) #ifndef __STRICT_ANSI__ #define __BYTEORDER_HAS_U64__ -#endif +#ifndef __powerpc64__ +#define __SWAB_64_THRU_32__ +#endif /* __powerpc64__ */ +#endif /* __STRICT_ANSI__ */ #endif /* __GNUC__ */ #include -#endif /* _PPC64_BYTEORDER_H */ +#endif /* _ASM_POWERPC_BYTEORDER_H */ diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h deleted file mode 100644 index c63c81ec7968..000000000000 --- a/include/asm-ppc/byteorder.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _PPC_BYTEORDER_H -#define _PPC_BYTEORDER_H - -#include -#include - -#ifdef __GNUC__ -#ifdef __KERNEL__ - -extern __inline__ unsigned ld_le16(const volatile unsigned short *addr) -{ - unsigned val; - - __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); - return val; -} - -extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val) -{ - __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); -} - -extern __inline__ unsigned ld_le32(const volatile unsigned *addr) -{ - unsigned val; - - __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); - return val; -} - -extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val) -{ - __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); -} - -static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) -{ - __u16 result; - - __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value)); - return result; -} - -static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) -{ - __u32 result; - - __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value)); - __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (value)); - __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (value)); - - return result; -} -#define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab16(x) ___arch__swab16(x) - -/* The same, but returns converted value from the location pointer by addr. */ -#define __arch__swab16p(addr) ld_le16(addr) -#define __arch__swab32p(addr) ld_le32(addr) - -/* The same, but do the conversion in situ, ie. put the value back to addr. */ -#define __arch__swab16s(addr) st_le16(addr,*addr) -#define __arch__swab32s(addr) st_le32(addr,*addr) - -#endif /* __KERNEL__ */ - -#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) -# define __BYTEORDER_HAS_U64__ -# define __SWAB_64_THRU_32__ -#endif - -#endif /* __GNUC__ */ - -#include - -#endif /* _PPC_BYTEORDER_H */ From 10b35d9978ac35556aec0d2642055742d8941488 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 23 Sep 2005 14:08:58 -0500 Subject: [PATCH 0160/1940] [PATCH] powerpc: merged asm/cputable.h Merged cputable.h between ppc32 and ppc64. In doing this removed support for the BEGIN_FTR_SECTION/END_FTR_SECTION macros in C code since they dont compile correctly. C code should use cpu_has_feature(). This is based on Arnd Bergmann's initial patch. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/cputable.c | 399 +++++++---------------------- arch/ppc64/kernel/cputable.c | 82 ++---- include/asm-powerpc/cputable.h | 442 +++++++++++++++++++++++++++++++++ include/asm-ppc/cputable.h | 128 ---------- include/asm-ppc/mmu_context.h | 6 +- include/asm-ppc64/cputable.h | 167 ------------- 6 files changed, 547 insertions(+), 677 deletions(-) create mode 100644 include/asm-powerpc/cputable.h delete mode 100644 include/asm-ppc/cputable.h delete mode 100644 include/asm-ppc64/cputable.h diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 546e1ea4cafa..97663d5d96ca 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -42,17 +42,6 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spe #define COMMON_PPC (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ PPC_FEATURE_HAS_MMU) -/* We only set the altivec features if the kernel was compiled with altivec - * support - */ -#ifdef CONFIG_ALTIVEC -#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC -#define PPC_FEATURE_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC -#else -#define CPU_FTR_ALTIVEC_COMP 0 -#define PPC_FEATURE_ALTIVEC_COMP 0 -#endif - /* We only set the spe features if the kernel was compiled with * spe support */ @@ -62,34 +51,13 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spe #define PPC_FEATURE_SPE_COMP 0 #endif -/* We need to mark all pages as being coherent if we're SMP or we - * have a 74[45]x and an MPC107 host bridge. - */ -#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) -#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT -#else -#define CPU_FTR_COMMON 0 -#endif - -/* The powersave features NAP & DOZE seems to confuse BDI when - debugging. So if a BDI is used, disable theses - */ -#ifndef CONFIG_BDI_SWITCH -#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE -#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP -#else -#define CPU_FTR_MAYBE_CAN_DOZE 0 -#define CPU_FTR_MAYBE_CAN_NAP 0 -#endif - struct cpu_spec cpu_specs[] = { #if CLASSIC_PPC { /* 601 */ .pvr_mask = 0xffff0000, .pvr_value = 0x00010000, .cpu_name = "601", - .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_PPC601, .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR | PPC_FEATURE_UNIFIED_CACHE, .icache_bsize = 32, @@ -100,9 +68,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00030000, .cpu_name = "603", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_603, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -112,9 +78,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00060000, .cpu_name = "603e", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_603, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -124,9 +88,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00070000, .cpu_name = "603ev", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_603, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -136,9 +98,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00040000, .cpu_name = "604", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_604, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -149,9 +109,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xfffff000, .pvr_value = 0x00090000, .cpu_name = "604e", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_604, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -162,9 +120,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00090000, .cpu_name = "604r", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_604, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -175,9 +131,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x000a0000, .cpu_name = "604ev", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_604, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -188,10 +142,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x00084202, .cpu_name = "740/750", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE | - CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_740_NOTAU, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -202,10 +153,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xfffffff0, .pvr_value = 0x00080100, .cpu_name = "750CX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_750, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -216,10 +164,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xfffffff0, .pvr_value = 0x00082200, .cpu_name = "750CX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_750, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -230,10 +175,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xfffffff0, .pvr_value = 0x00082210, .cpu_name = "750CXe", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_750, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -244,10 +186,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x00083214, .cpu_name = "750CXe", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_750, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -258,10 +197,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xfffff000, .pvr_value = 0x00083000, .cpu_name = "745/755", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_750, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -272,11 +208,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffff00, .pvr_value = 0x70000100, .cpu_name = "750FX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, + .cpu_features = CPU_FTRS_750FX1, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -287,11 +219,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x70000200, .cpu_name = "750FX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | - CPU_FTR_NO_DPM, + .cpu_features = CPU_FTRS_750FX2, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -302,11 +230,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x70000000, .cpu_name = "750FX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + .cpu_features = CPU_FTRS_750FX, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -317,11 +241,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x70020000, .cpu_name = "750GX", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | - CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_DUAL_PLL_750FX | - CPU_FTR_HAS_HIGH_BATS, + .cpu_features = CPU_FTRS_750GX, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -332,10 +252,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00080000, .cpu_name = "740/750", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + .cpu_features = CPU_FTRS_740, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -346,11 +263,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x000c1101, .cpu_name = "7400 (1.1)", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7400_NOTAU, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -360,12 +274,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x000c0000, .cpu_name = "7400", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | - CPU_FTR_MAYBE_CAN_NAP, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7400, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -375,12 +285,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x800c0000, .cpu_name = "7410", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | - CPU_FTR_MAYBE_CAN_NAP, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7400, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -390,12 +296,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x80000200, .cpu_name = "7450", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7450_20, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -405,14 +307,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x80000201, .cpu_name = "7450", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | - CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7450_21, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -422,13 +318,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x80000000, .cpu_name = "7450", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7450_23, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -438,12 +329,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffff00, .pvr_value = 0x80010100, .cpu_name = "7455", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7455_1, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -453,14 +340,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x80010200, .cpu_name = "7455", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | - CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7455_20, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -470,14 +351,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x80010000, .cpu_name = "7455", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | - CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7455, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -487,14 +362,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x80020100, .cpu_name = "7447/7457", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | - CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7447_10, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -504,14 +373,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffffff, .pvr_value = 0x80020101, .cpu_name = "7447/7457", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | - CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7447_10, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -521,14 +384,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x80020000, .cpu_name = "7447/7457", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | - CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7447, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -538,13 +395,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x80030000, .cpu_name = "7447A", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | - CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | - CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7447A, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -554,13 +406,8 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x80040000, .cpu_name = "7448", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | - CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | - CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_7447A, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -570,9 +417,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x7fff0000, .pvr_value = 0x00810000, .cpu_name = "82xx", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_82XX, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -582,9 +427,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x7fff0000, .pvr_value = 0x00820000, .cpu_name = "G2_LE", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + .cpu_features = CPU_FTRS_G2_LE, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -594,9 +437,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x7fff0000, .pvr_value = 0x00830000, .cpu_name = "e300", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + .cpu_features = CPU_FTRS_E300, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -606,9 +447,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x00000000, .pvr_value = 0x00000000, .cpu_name = "(generic PPC)", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_CLASSIC32, .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, @@ -620,9 +459,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00400000, .cpu_name = "Power3 (630)", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_POWER3_32, .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, .icache_bsize = 128, .dcache_bsize = 128, @@ -633,9 +470,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00410000, .cpu_name = "Power3 (630+)", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_POWER3_32, .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, .icache_bsize = 128, .dcache_bsize = 128, @@ -646,9 +481,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00360000, .cpu_name = "I-star", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_POWER3_32, .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, .icache_bsize = 128, .dcache_bsize = 128, @@ -659,9 +492,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00370000, .cpu_name = "S-star", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, + .cpu_features = CPU_FTRS_POWER3_32, .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, .icache_bsize = 128, .dcache_bsize = 128, @@ -670,44 +501,12 @@ struct cpu_spec cpu_specs[] = { }, #endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_POWER4 - { /* Power4 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00350000, - .cpu_name = "Power4", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power4 - }, - { /* PPC970 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00390000, - .cpu_name = "PPC970", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 | - PPC_FEATURE_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970 - }, { /* PPC970FX */ .pvr_mask = 0xffff0000, .pvr_value = 0x003c0000, .cpu_name = "PPC970FX", - .cpu_features = CPU_FTR_COMMON | - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | - CPU_FTR_HPTE_TABLE | - CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 | - PPC_FEATURE_ALTIVEC_COMP, + .cpu_features = CPU_FTRS_970_32, + .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, @@ -721,8 +520,7 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "8xx", /* CPU_FTR_MAYBE_CAN_DOZE is possible, * if the 8xx code is there.... */ - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_8XX, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, @@ -733,8 +531,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffff00, .pvr_value = 0x00200200, .cpu_name = "403GC", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, @@ -743,8 +540,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffffff00, .pvr_value = 0x00201400, .cpu_name = "403GCX", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, @@ -753,8 +549,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00200000, .cpu_name = "403G ??", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, @@ -763,8 +558,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x40110000, .cpu_name = "405GP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -774,8 +568,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x40130000, .cpu_name = "STB03xxx", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -785,8 +578,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x41810000, .cpu_name = "STB04xxx", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -796,8 +588,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x41610000, .cpu_name = "NP405L", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -807,8 +598,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x40B10000, .cpu_name = "NP4GS3", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -818,8 +608,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x41410000, .cpu_name = "NP405H", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -829,8 +618,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x50910000, .cpu_name = "405GPr", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -840,8 +628,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x51510000, .cpu_name = "STBx25xx", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -851,8 +638,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x41F10000, .cpu_name = "405LP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -861,8 +647,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x20010000, .cpu_name = "Virtex-II Pro", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -872,8 +657,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x51210000, .cpu_name = "405EP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, @@ -886,8 +670,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x40000850, .cpu_name = "440EP Rev. A", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, @@ -896,8 +679,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x400008d3, .cpu_name = "440EP Rev. B", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, @@ -906,8 +688,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x40000440, .cpu_name = "440GP Rev. B", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -916,8 +697,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x40000481, .cpu_name = "440GP Rev. C", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -926,8 +706,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x50000850, .cpu_name = "440GX Rev. A", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -936,8 +715,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x50000851, .cpu_name = "440GX Rev. B", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -946,8 +724,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x50000892, .cpu_name = "440GX Rev. C", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -956,8 +733,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xf0000fff, .pvr_value = 0x50000894, .cpu_name = "440GX Rev. F", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -966,8 +742,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xff000fff, .pvr_value = 0x53000891, .cpu_name = "440SP Rev. A", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -979,7 +754,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x81000000, .cpu_name = "e200z5", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_E200, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_UNIFIED_CACHE, @@ -990,7 +765,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x81100000, .cpu_name = "e200z6", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_E200, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | PPC_FEATURE_HAS_EFP_SINGLE | @@ -1002,8 +777,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80200000, .cpu_name = "e500", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_E500, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | PPC_FEATURE_HAS_EFP_SINGLE, @@ -1016,8 +790,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80210000, .cpu_name = "e500v2", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS, + .cpu_features = CPU_FTRS_E500_2, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, @@ -1031,7 +804,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x00000000, .pvr_value = 0x00000000, .cpu_name = "(generic PPC)", - .cpu_features = CPU_FTR_COMMON, + .cpu_features = CPU_FTRS_GENERIC_32, .cpu_user_features = PPC_FEATURE_32, .icache_bsize = 32, .dcache_bsize = 32, diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c index 8831a28c3c4e..5134c53d536d 100644 --- a/arch/ppc64/kernel/cputable.c +++ b/arch/ppc64/kernel/cputable.c @@ -37,26 +37,13 @@ extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); - -/* We only set the altivec features if the kernel was compiled with altivec - * support - */ -#ifdef CONFIG_ALTIVEC -#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC -#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC -#else -#define CPU_FTR_ALTIVEC_COMP 0 -#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 -#endif - struct cpu_spec cpu_specs[] = { { /* Power3 */ .pvr_mask = 0xffff0000, .pvr_value = 0x00400000, .cpu_name = "POWER3 (630)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR, - .cpu_user_features = COMMON_USER_PPC64, + .cpu_features = CPU_FTRS_POWER3, + .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, @@ -70,8 +57,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00410000, .cpu_name = "POWER3 (630+)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR, + .cpu_features = CPU_FTRS_POWER3, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -86,9 +72,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00330000, .cpu_name = "RS64-II (northstar)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | - CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_features = CPU_FTRS_RS64, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -103,9 +87,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00340000, .cpu_name = "RS64-III (pulsar)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | - CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_features = CPU_FTRS_RS64, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -120,9 +102,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00360000, .cpu_name = "RS64-III (icestar)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | - CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_features = CPU_FTRS_RS64, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -137,9 +117,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00370000, .cpu_name = "RS64-IV (sstar)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | - CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_features = CPU_FTRS_RS64, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -154,9 +132,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00350000, .cpu_name = "POWER4 (gp)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA, + .cpu_features = CPU_FTRS_POWER4, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -171,9 +147,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00380000, .cpu_name = "POWER4+ (gq)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA, + .cpu_features = CPU_FTRS_POWER4, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -188,10 +162,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00390000, .cpu_name = "PPC970", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, + .cpu_features = CPU_FTRS_PPC970, .cpu_user_features = COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, @@ -207,10 +178,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x003c0000, .cpu_name = "PPC970FX", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, + .cpu_features = CPU_FTRS_PPC970, .cpu_user_features = COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, @@ -226,10 +194,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x00440000, .cpu_name = "PPC970MP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, + .cpu_features = CPU_FTRS_PPC970, .cpu_user_features = COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, @@ -244,11 +209,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x003a0000, .cpu_name = "POWER5 (gr)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, + .cpu_features = CPU_FTRS_POWER5, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -263,11 +224,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0xffff0000, .pvr_value = 0x003b0000, .cpu_name = "POWER5 (gs)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, + .cpu_features = CPU_FTRS_POWER5, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, @@ -281,11 +238,8 @@ struct cpu_spec cpu_specs[] = { { /* BE DD1.x */ .pvr_mask = 0xffff0000, .pvr_value = 0x00700000, - .cpu_name = "Broadband Engine", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_SMT, + .cpu_name = "Cell Broadband Engine", + .cpu_features = CPU_FTRS_CELL, .cpu_user_features = COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, @@ -296,9 +250,7 @@ struct cpu_spec cpu_specs[] = { .pvr_mask = 0x00000000, .pvr_value = 0x00000000, .cpu_name = "POWER4 (compatible)", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2, + .cpu_features = CPU_FTRS_COMPATIBLE, .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h new file mode 100644 index 000000000000..5f81d44963f1 --- /dev/null +++ b/include/asm-powerpc/cputable.h @@ -0,0 +1,442 @@ +#ifndef __ASM_POWERPC_CPUTABLE_H +#define __ASM_POWERPC_CPUTABLE_H + +#include +#include /* for ASM_CONST */ + +#define PPC_FEATURE_32 0x80000000 +#define PPC_FEATURE_64 0x40000000 +#define PPC_FEATURE_601_INSTR 0x20000000 +#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 +#define PPC_FEATURE_HAS_FPU 0x08000000 +#define PPC_FEATURE_HAS_MMU 0x04000000 +#define PPC_FEATURE_HAS_4xxMAC 0x02000000 +#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 +#define PPC_FEATURE_HAS_SPE 0x00800000 +#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 +#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +/* This structure can grow, it's real size is used by head.S code + * via the mkdefs mechanism. + */ +struct cpu_spec; +struct op_powerpc_model; + +#ifdef __powerpc64__ +typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); +#else /* __powerpc64__ */ +typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec); +#endif /* __powerpc64__ */ + +struct cpu_spec { + /* CPU is matched via (PVR & pvr_mask) == pvr_value */ + unsigned int pvr_mask; + unsigned int pvr_value; + + char *cpu_name; + unsigned long cpu_features; /* Kernel features */ + unsigned int cpu_user_features; /* Userland features */ + + /* cache line sizes */ + unsigned int icache_bsize; + unsigned int dcache_bsize; + + /* number of performance monitor counters */ + unsigned int num_pmcs; + + /* this is called to initialize various CPU bits like L1 cache, + * BHT, SPD, etc... from head.S before branching to identify_machine + */ + cpu_setup_t cpu_setup; +#ifdef __powerpc64__ + + /* Used by oprofile userspace to select the right counters */ + char *oprofile_cpu_type; + + /* Processor specific oprofile operations */ + struct op_powerpc_model *oprofile_model; +#endif /* __powerpc64__ */ +}; + +extern struct cpu_spec cpu_specs[]; + +#ifdef __powerpc64__ +extern struct cpu_spec *cur_cpu_spec; +#else /* __powerpc64__ */ +extern struct cpu_spec *cur_cpu_spec[]; +#endif /* __powerpc64__ */ + +#endif /* __ASSEMBLY__ */ + +/* CPU kernel features */ + +/* Retain the 32b definitions all use bottom half of word */ +#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001) +#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002) +#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004) +#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008) +#define CPU_FTR_TAU ASM_CONST(0x0000000000000010) +#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020) +#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040) +#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080) +#define CPU_FTR_601 ASM_CONST(0x0000000000000100) +#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200) +#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400) +#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800) +#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000) +#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000) +#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000) +#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000) +#define CPU_FTR_HAS_HIGH_BATS ASM_CONST(0x0000000000010000) +#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000) +#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000) +#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000) + +#ifdef __powerpc64__ +/* Add the 64b processor unique features in the top half of the word */ +#define CPU_FTR_SLB ASM_CONST(0x0000000100000000) +#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000) +#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000) +#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000) +#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000) +#define CPU_FTR_IABR ASM_CONST(0x0000002000000000) +#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000) +#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000) +#define CPU_FTR_SMT ASM_CONST(0x0000010000000000) +#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000) +#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000) +#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000) +#else +/* ensure on 32b processors the flags are available for compiling but + * don't do anything */ +#define CPU_FTR_SLB ASM_CONST(0x0) +#define CPU_FTR_16M_PAGE ASM_CONST(0x0) +#define CPU_FTR_TLBIEL ASM_CONST(0x0) +#define CPU_FTR_NOEXECUTE ASM_CONST(0x0) +#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0) +#define CPU_FTR_IABR ASM_CONST(0x0) +#define CPU_FTR_MMCRA ASM_CONST(0x0) +#define CPU_FTR_CTRL ASM_CONST(0x0) +#define CPU_FTR_SMT ASM_CONST(0x0) +#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0) +#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0) +#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0) +#endif + +#ifndef __ASSEMBLY__ + +#define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \ + PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU) + +#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ + CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ + CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL) + +/* iSeries doesn't support large pages */ +#ifdef CONFIG_PPC_ISERIES +#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE) +#else +#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE) +#endif /* CONFIG_PPC_ISERIES */ + +/* We only set the altivec features if the kernel was compiled with altivec + * support + */ +#ifdef CONFIG_ALTIVEC +#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC +#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC +#else +#define CPU_FTR_ALTIVEC_COMP 0 +#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 +#endif + +/* We need to mark all pages as being coherent if we're SMP or we + * have a 74[45]x and an MPC107 host bridge. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) +#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT +#else +#define CPU_FTR_COMMON 0 +#endif + +/* The powersave features NAP & DOZE seems to confuse BDI when + debugging. So if a BDI is used, disable theses + */ +#ifndef CONFIG_BDI_SWITCH +#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE +#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP +#else +#define CPU_FTR_MAYBE_CAN_DOZE 0 +#define CPU_FTR_MAYBE_CAN_NAP 0 +#endif + +#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ + !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ + !defined(CONFIG_BOOKE)) + +enum { + CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE, + CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, + CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_NO_DPM, + CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | + CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT, + CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | + CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC, + CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB, + CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + CPU_FTRS_E200 = CPU_FTR_USE_TB, + CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_BIG_PHYS, + CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON, +#ifdef __powerpc64__ + CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR, + CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_MMCRA | CPU_FTR_CTRL, + CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA, + CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, + CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_MMCRA | CPU_FTR_SMT | + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | + CPU_FTR_MMCRA_SIHV, + CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT, + CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, +#endif + + CPU_FTRS_POSSIBLE = +#if CLASSIC_PPC + CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | + CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | + CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX | + CPU_FTRS_7400_NOTAU | CPU_FTRS_7400 | CPU_FTRS_7450_20 | + CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 | + CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 | + CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX | + CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 | +#else + CPU_FTRS_GENERIC_32 | +#endif +#ifdef CONFIG_PPC64BRIDGE + CPU_FTRS_POWER3_32 | +#endif +#ifdef CONFIG_POWER4 + CPU_FTRS_POWER4_32 | CPU_FTRS_970_32 | +#endif +#ifdef CONFIG_8xx + CPU_FTRS_8XX | +#endif +#ifdef CONFIG_40x + CPU_FTRS_40X | +#endif +#ifdef CONFIG_44x + CPU_FTRS_44X | +#endif +#ifdef CONFIG_E200 + CPU_FTRS_E200 | +#endif +#ifdef CONFIG_E500 + CPU_FTRS_E500 | CPU_FTRS_E500_2 | +#endif +#ifdef __powerpc64__ + CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | + CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | +#endif + 0, + + CPU_FTRS_ALWAYS = +#if CLASSIC_PPC + CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & + CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & + CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX & + CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 & + CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 & + CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 & + CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX & + CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 & +#else + CPU_FTRS_GENERIC_32 & +#endif +#ifdef CONFIG_PPC64BRIDGE + CPU_FTRS_POWER3_32 & +#endif +#ifdef CONFIG_POWER4 + CPU_FTRS_POWER4_32 & CPU_FTRS_970_32 & +#endif +#ifdef CONFIG_8xx + CPU_FTRS_8XX & +#endif +#ifdef CONFIG_40x + CPU_FTRS_40X & +#endif +#ifdef CONFIG_44x + CPU_FTRS_44X & +#endif +#ifdef CONFIG_E200 + CPU_FTRS_E200 & +#endif +#ifdef CONFIG_E500 + CPU_FTRS_E500 & CPU_FTRS_E500_2 & +#endif +#ifdef __powerpc64__ + CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & + CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & +#endif + CPU_FTRS_POSSIBLE, +}; + +static inline int cpu_has_feature(unsigned long feature) +{ + return (CPU_FTRS_ALWAYS & feature) || + (CPU_FTRS_POSSIBLE +#ifndef __powerpc64__ + & cur_cpu_spec[0]->cpu_features +#else + & cur_cpu_spec->cpu_features +#endif + & feature); +} + +#endif /* !__ASSEMBLY__ */ + +#ifdef __ASSEMBLY__ + +#define BEGIN_FTR_SECTION 98: + +#ifndef __powerpc64__ +#define END_FTR_SECTION(msk, val) \ +99: \ + .section __ftr_fixup,"a"; \ + .align 2; \ + .long msk; \ + .long val; \ + .long 98b; \ + .long 99b; \ + .previous +#else /* __powerpc64__ */ +#define END_FTR_SECTION(msk, val) \ +99: \ + .section __ftr_fixup,"a"; \ + .align 3; \ + .llong msk; \ + .llong val; \ + .llong 98b; \ + .llong 99b; \ + .previous +#endif /* __powerpc64__ */ + +#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) +#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ +#endif /* __ASM_POWERPC_CPUTABLE_H */ diff --git a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h deleted file mode 100644 index 41d8f8425c04..000000000000 --- a/include/asm-ppc/cputable.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * include/asm-ppc/cputable.h - * - * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * 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. - */ - -#ifndef __ASM_PPC_CPUTABLE_H -#define __ASM_PPC_CPUTABLE_H - -/* Exposed to userland CPU features */ -#define PPC_FEATURE_32 0x80000000 -#define PPC_FEATURE_64 0x40000000 -#define PPC_FEATURE_601_INSTR 0x20000000 -#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 -#define PPC_FEATURE_HAS_FPU 0x08000000 -#define PPC_FEATURE_HAS_MMU 0x04000000 -#define PPC_FEATURE_HAS_4xxMAC 0x02000000 -#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 -#define PPC_FEATURE_HAS_SPE 0x00800000 -#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 -#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -/* This structure can grow, it's real size is used by head.S code - * via the mkdefs mecanism. - */ -struct cpu_spec; - -typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec); - -struct cpu_spec { - /* CPU is matched via (PVR & pvr_mask) == pvr_value */ - unsigned int pvr_mask; - unsigned int pvr_value; - - char *cpu_name; - unsigned int cpu_features; /* Kernel features */ - unsigned int cpu_user_features; /* Userland features */ - - /* cache line sizes */ - unsigned int icache_bsize; - unsigned int dcache_bsize; - - /* number of performance monitor counters */ - unsigned int num_pmcs; - - /* this is called to initialize various CPU bits like L1 cache, - * BHT, SPD, etc... from head.S before branching to identify_machine - */ - cpu_setup_t cpu_setup; -}; - -extern struct cpu_spec cpu_specs[]; -extern struct cpu_spec *cur_cpu_spec[]; - -static inline unsigned int cpu_has_feature(unsigned int feature) -{ - return cur_cpu_spec[0]->cpu_features & feature; -} - -#endif /* __ASSEMBLY__ */ - -/* CPU kernel features */ -#define CPU_FTR_SPLIT_ID_CACHE 0x00000001 -#define CPU_FTR_L2CR 0x00000002 -#define CPU_FTR_SPEC7450 0x00000004 -#define CPU_FTR_ALTIVEC 0x00000008 -#define CPU_FTR_TAU 0x00000010 -#define CPU_FTR_CAN_DOZE 0x00000020 -#define CPU_FTR_USE_TB 0x00000040 -#define CPU_FTR_604_PERF_MON 0x00000080 -#define CPU_FTR_601 0x00000100 -#define CPU_FTR_HPTE_TABLE 0x00000200 -#define CPU_FTR_CAN_NAP 0x00000400 -#define CPU_FTR_L3CR 0x00000800 -#define CPU_FTR_L3_DISABLE_NAP 0x00001000 -#define CPU_FTR_NAP_DISABLE_L2_PR 0x00002000 -#define CPU_FTR_DUAL_PLL_750FX 0x00004000 -#define CPU_FTR_NO_DPM 0x00008000 -#define CPU_FTR_HAS_HIGH_BATS 0x00010000 -#define CPU_FTR_NEED_COHERENT 0x00020000 -#define CPU_FTR_NO_BTIC 0x00040000 -#define CPU_FTR_BIG_PHYS 0x00080000 - -#ifdef __ASSEMBLY__ - -#define BEGIN_FTR_SECTION 98: - -#define END_FTR_SECTION(msk, val) \ -99: \ - .section __ftr_fixup,"a"; \ - .align 2; \ - .long msk; \ - .long val; \ - .long 98b; \ - .long 99b; \ - .previous - -#else - -#define BEGIN_FTR_SECTION "98:\n" -#define END_FTR_SECTION(msk, val) \ -"99:\n" \ -" .section __ftr_fixup,\"a\";\n" \ -" .align 2;\n" \ -" .long "#msk";\n" \ -" .long "#val";\n" \ -" .long 98b;\n" \ -" .long 99b;\n" \ -" .previous\n" - - -#endif /* __ASSEMBLY__ */ - -#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) -#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) - -#endif /* __ASM_PPC_CPUTABLE_H */ -#endif /* __KERNEL__ */ - diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index afe26ffc2e2d..4f152cca13c1 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -164,13 +164,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { #ifdef CONFIG_ALTIVEC - asm volatile ( - BEGIN_FTR_SECTION - "dssall;\n" + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + asm volatile ("dssall;\n" #ifndef CONFIG_POWER4 "sync;\n" /* G4 needs a sync here, G5 apparently not */ #endif - END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) : : ); #endif /* CONFIG_ALTIVEC */ diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h deleted file mode 100644 index 3eef40efd082..000000000000 --- a/include/asm-ppc64/cputable.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * include/asm-ppc64/cputable.h - * - * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * Modifications for ppc64: - * Copyright (C) 2003 Dave Engebretsen - * - * 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. - */ - -#ifndef __ASM_PPC_CPUTABLE_H -#define __ASM_PPC_CPUTABLE_H - -#include -#include /* for ASM_CONST */ - -/* Exposed to userland CPU features - Must match ppc32 definitions */ -#define PPC_FEATURE_32 0x80000000 -#define PPC_FEATURE_64 0x40000000 -#define PPC_FEATURE_601_INSTR 0x20000000 -#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 -#define PPC_FEATURE_HAS_FPU 0x08000000 -#define PPC_FEATURE_HAS_MMU 0x04000000 -#define PPC_FEATURE_HAS_4xxMAC 0x02000000 -#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -/* This structure can grow, it's real size is used by head.S code - * via the mkdefs mechanism. - */ -struct cpu_spec; -struct op_powerpc_model; - -typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); - -struct cpu_spec { - /* CPU is matched via (PVR & pvr_mask) == pvr_value */ - unsigned int pvr_mask; - unsigned int pvr_value; - - char *cpu_name; - unsigned long cpu_features; /* Kernel features */ - unsigned int cpu_user_features; /* Userland features */ - - /* cache line sizes */ - unsigned int icache_bsize; - unsigned int dcache_bsize; - - /* number of performance monitor counters */ - unsigned int num_pmcs; - - /* this is called to initialize various CPU bits like L1 cache, - * BHT, SPD, etc... from head.S before branching to identify_machine - */ - cpu_setup_t cpu_setup; - - /* Used by oprofile userspace to select the right counters */ - char *oprofile_cpu_type; - - /* Processor specific oprofile operations */ - struct op_powerpc_model *oprofile_model; -}; - -extern struct cpu_spec cpu_specs[]; -extern struct cpu_spec *cur_cpu_spec; - -static inline unsigned long cpu_has_feature(unsigned long feature) -{ - return cur_cpu_spec->cpu_features & feature; -} - -#endif /* __ASSEMBLY__ */ - -/* CPU kernel features */ - -/* Retain the 32b definitions for the time being - use bottom half of word */ -#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001) -#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002) -#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004) -#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008) -#define CPU_FTR_TAU ASM_CONST(0x0000000000000010) -#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020) -#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040) -#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080) -#define CPU_FTR_601 ASM_CONST(0x0000000000000100) -#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200) -#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400) -#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800) -#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000) -#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000) -#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000) - -/* Add the 64b processor unique features in the top half of the word */ -#define CPU_FTR_SLB ASM_CONST(0x0000000100000000) -#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000) -#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000) -#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000) -#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000) -#define CPU_FTR_IABR ASM_CONST(0x0000002000000000) -#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000) -/* unused ASM_CONST(0x0000008000000000) */ -#define CPU_FTR_SMT ASM_CONST(0x0000010000000000) -#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000) -#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000) -#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000) -#define CPU_FTR_CTRL ASM_CONST(0x0000100000000000) - -#ifndef __ASSEMBLY__ - -#define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \ - PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU) - -#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ - CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ - CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL) - -/* iSeries doesn't support large pages */ -#ifdef CONFIG_PPC_ISERIES -#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE) -#else -#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE) -#endif /* CONFIG_PPC_ISERIES */ - -#endif /* __ASSEMBLY */ - -#ifdef __ASSEMBLY__ - -#define BEGIN_FTR_SECTION 98: - -#define END_FTR_SECTION(msk, val) \ -99: \ - .section __ftr_fixup,"a"; \ - .align 3; \ - .llong msk; \ - .llong val; \ - .llong 98b; \ - .llong 99b; \ - .previous - -#else - -#define BEGIN_FTR_SECTION "98:\n" -#define END_FTR_SECTION(msk, val) \ -"99:\n" \ -" .section __ftr_fixup,\"a\";\n" \ -" .align 3;\n" \ -" .llong "#msk";\n" \ -" .llong "#val";\n" \ -" .llong 98b;\n" \ -" .llong 99b;\n" \ -" .previous\n" - -#endif /* __ASSEMBLY__ */ - -#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) -#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) - -#endif /* __ASM_PPC_CPUTABLE_H */ -#endif /* __KERNEL__ */ - From 400d221274426958f1e1c7081a247bea9cede696 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 27 Sep 2005 15:13:12 -0500 Subject: [PATCH 0161/1940] [PATCH] ppc32: make cur_cpu_spec a single pointer instead of an array Changed ppc32 so that cur_cpu_spec is just a single pointer for all CPUs. Additionally, made call_setup_cpu check to see if the cpu_setup pointer is NULL or not before calling the function. This lets remove the dummy cpu_setup calls that just return. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head.S | 6 ---- arch/powerpc/oprofile/common.c | 6 ++-- arch/powerpc/platforms/powermac/pmac_setup.c | 2 +- arch/ppc/kernel/cpu_setup_6xx.S | 2 -- arch/ppc/kernel/cpu_setup_power4.S | 2 -- arch/ppc/kernel/cputable.c | 33 ++++++++------------ arch/ppc/kernel/head.S | 6 ---- arch/ppc/kernel/misc.S | 22 ++++++------- arch/ppc/kernel/setup.c | 14 ++++----- arch/ppc/platforms/4xx/ebony.c | 2 +- arch/ppc/platforms/pmac_setup.c | 2 +- arch/ppc/platforms/radstone_ppc7d.c | 8 ++--- arch/ppc/syslib/ibm440gx_common.c | 6 ++-- include/asm-powerpc/cputable.h | 16 ---------- include/asm-powerpc/elf.h | 4 +-- 15 files changed, 43 insertions(+), 88 deletions(-) diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S index d05509f197d0..8cdac7385e7f 100644 --- a/arch/powerpc/kernel/head.S +++ b/arch/powerpc/kernel/head.S @@ -1059,7 +1059,6 @@ __secondary_start: lis r3,-KERNELBASE@h mr r4,r24 - bl identify_cpu bl call_setup_cpu /* Call setup_cpu for this CPU */ #ifdef CONFIG_6xx lis r3,-KERNELBASE@h @@ -1109,11 +1108,6 @@ __secondary_start: * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */ -_GLOBAL(__setup_cpu_power3) - blr -_GLOBAL(__setup_cpu_generic) - blr - #if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) _GLOBAL(__save_cpu_setup) blr diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 88b4118fd0c5..0ec12c8f2c01 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -155,8 +155,6 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) int __init oprofile_arch_init(struct oprofile_operations *ops) { #ifndef __powerpc64__ - int cpu_id = smp_processor_id(); - #ifdef CONFIG_FSL_BOOKE model = &op_model_fsl_booke; #else @@ -167,9 +165,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) if (NULL == cpu_type) return -ENOMEM; - sprintf(cpu_type, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name); + sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name); - model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs; + model->num_counters = cur_cpu_spec->num_pmcs; ops->cpu_type = cpu_type; #else /* __powerpc64__ */ diff --git a/arch/powerpc/platforms/powermac/pmac_setup.c b/arch/powerpc/platforms/powermac/pmac_setup.c index dbc921a084cd..3667e0b2b8e3 100644 --- a/arch/powerpc/platforms/powermac/pmac_setup.c +++ b/arch/powerpc/platforms/powermac/pmac_setup.c @@ -445,7 +445,7 @@ static int pmac_pm_enter(suspend_state_t state) enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S index ba396438ede3..a5333c07fc3c 100644 --- a/arch/ppc/kernel/cpu_setup_6xx.S +++ b/arch/ppc/kernel/cpu_setup_6xx.S @@ -17,8 +17,6 @@ #include #include -_GLOBAL(__setup_cpu_601) - blr _GLOBAL(__setup_cpu_603) b setup_common_caches _GLOBAL(__setup_cpu_604) diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S index 7e4fbb653724..0abb5f25b2ca 100644 --- a/arch/ppc/kernel/cpu_setup_power4.S +++ b/arch/ppc/kernel/cpu_setup_power4.S @@ -63,8 +63,6 @@ _GLOBAL(__970_cpu_preinit) isync blr -_GLOBAL(__setup_cpu_power4) - blr _GLOBAL(__setup_cpu_ppc970) mfspr r0,SPRN_HID0 li r11,5 /* clear DOZE and SLEEP */ diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 97663d5d96ca..207d4dd059d9 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -14,23 +14,22 @@ #include #include #include +#include + +#include #include -struct cpu_spec* cur_cpu_spec[NR_CPUS]; +struct cpu_spec* cur_cpu_spec = NULL; -extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_750(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_750cx(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_750fx(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec); +extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_750cx(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_750fx(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); #define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ @@ -62,7 +61,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_UNIFIED_CACHE, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_601 }, { /* 603 */ .pvr_mask = 0xffff0000, @@ -451,7 +449,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_PPC, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_generic }, #endif /* CLASSIC_PPC */ #ifdef CONFIG_PPC64BRIDGE @@ -464,7 +461,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3 }, { /* Power3+ */ .pvr_mask = 0xffff0000, @@ -475,7 +471,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3 }, { /* I-star */ .pvr_mask = 0xffff0000, @@ -486,7 +481,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3 }, { /* S-star */ .pvr_mask = 0xffff0000, @@ -497,7 +491,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3 }, #endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_POWER4 diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index d05509f197d0..8cdac7385e7f 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1059,7 +1059,6 @@ __secondary_start: lis r3,-KERNELBASE@h mr r4,r24 - bl identify_cpu bl call_setup_cpu /* Call setup_cpu for this CPU */ #ifdef CONFIG_6xx lis r3,-KERNELBASE@h @@ -1109,11 +1108,6 @@ __secondary_start: * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */ -_GLOBAL(__setup_cpu_power3) - blr -_GLOBAL(__setup_cpu_generic) - blr - #if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) _GLOBAL(__save_cpu_setup) blr diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 9d2cb79475c6..2b9a16274b0b 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -125,9 +125,8 @@ _GLOBAL(identify_cpu) 1: addis r6,r3,cur_cpu_spec@ha addi r6,r6,cur_cpu_spec@l - slwi r4,r4,2 sub r8,r8,r3 - stwx r8,r4,r6 + stw r8,0(r6) blr /* @@ -186,19 +185,18 @@ _GLOBAL(do_cpu_ftr_fixups) * * Setup function is called with: * r3 = data offset - * r4 = CPU number - * r5 = ptr to CPU spec (relocated) + * r4 = ptr to CPU spec (relocated) */ _GLOBAL(call_setup_cpu) - addis r5,r3,cur_cpu_spec@ha - addi r5,r5,cur_cpu_spec@l - slwi r4,r24,2 - lwzx r5,r4,r5 + addis r4,r3,cur_cpu_spec@ha + addi r4,r4,cur_cpu_spec@l + lwz r4,0(r4) + add r4,r4,r3 + lwz r5,CPU_SPEC_SETUP(r4) + cmpi 0,r5,0 add r5,r5,r3 - lwz r6,CPU_SPEC_SETUP(r5) - add r6,r6,r3 - mtctr r6 - mr r4,r24 + beqlr + mtctr r5 bctr #if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx) diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 1b891b806f3d..62022eacf63e 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -188,18 +188,18 @@ int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "processor\t: %d\n", i); seq_printf(m, "cpu\t\t: "); - if (cur_cpu_spec[i]->pvr_mask) - seq_printf(m, "%s", cur_cpu_spec[i]->cpu_name); + if (cur_cpu_spec->pvr_mask) + seq_printf(m, "%s", cur_cpu_spec->cpu_name); else seq_printf(m, "unknown (%08x)", pvr); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC) + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) seq_printf(m, ", altivec supported"); #endif seq_printf(m, "\n"); #ifdef CONFIG_TAU - if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) { + if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { #ifdef CONFIG_TAU_AVERAGE /* more straightforward, but potentially misleading */ seq_printf(m, "temperature \t: %u C (uncalibrated)\n", @@ -754,12 +754,12 @@ void __init setup_arch(char **cmdline_p) * for a possibly more accurate value. */ if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { - dcache_bsize = cur_cpu_spec[0]->dcache_bsize; - icache_bsize = cur_cpu_spec[0]->icache_bsize; + dcache_bsize = cur_cpu_spec->dcache_bsize; + icache_bsize = cur_cpu_spec->icache_bsize; ucache_bsize = 0; } else ucache_bsize = dcache_bsize = icache_bsize - = cur_cpu_spec[0]->dcache_bsize; + = cur_cpu_spec->dcache_bsize; /* reboot on panic */ panic_timeout = 180; diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c index d6b2b1965dcb..9decb72e7aaf 100644 --- a/arch/ppc/platforms/4xx/ebony.c +++ b/arch/ppc/platforms/4xx/ebony.c @@ -91,7 +91,7 @@ ebony_calibrate_decr(void) * on Rev. C silicon then errata forces us to * use the internal clock. */ - if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0) + if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0) freq = EBONY_440GP_RB_SYSCLK; else freq = EBONY_440GP_RC_SYSCLK; diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index 1ad779ecc8fc..e6a12182bfbb 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -448,7 +448,7 @@ static int pmac_pm_enter(suspend_state_t state) enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index c30607a972d8..06ec30f7e2f4 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c @@ -1185,18 +1185,18 @@ static void __init ppc7d_setup_arch(void) ROOT_DEV = Root_HDA1; #endif - if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) || - (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)) + if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) || + (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)) /* 745x is different. We only want to pass along enable. */ _set_L2CR(L2CR_L2E); - else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) + else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR) /* All modules have 1MB of L2. We also assume that an * L2 divisor of 3 will work. */ _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3 | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) + if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR) /* No L3 cache */ _set_L3CR(0); diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c index 0bb919859b8b..c36db279b43d 100644 --- a/arch/ppc/syslib/ibm440gx_common.c +++ b/arch/ppc/syslib/ibm440gx_common.c @@ -236,9 +236,9 @@ void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p) /* Disable L2C on rev.A, rev.B and 800MHz version of rev.C, enable it on all other revisions */ - if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 || - strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0 - || (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C") + if (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. A") == 0 || + strcmp(cur_cpu_spec->cpu_name, "440GX Rev. B") == 0 + || (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C") == 0 && p->cpu > 667000000)) ibm440gx_l2c_disable(); else diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 5f81d44963f1..1e50efab091d 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -25,11 +25,7 @@ struct cpu_spec; struct op_powerpc_model; -#ifdef __powerpc64__ typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); -#else /* __powerpc64__ */ -typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -#endif /* __powerpc64__ */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ @@ -51,23 +47,15 @@ struct cpu_spec { * BHT, SPD, etc... from head.S before branching to identify_machine */ cpu_setup_t cpu_setup; -#ifdef __powerpc64__ /* Used by oprofile userspace to select the right counters */ char *oprofile_cpu_type; /* Processor specific oprofile operations */ struct op_powerpc_model *oprofile_model; -#endif /* __powerpc64__ */ }; -extern struct cpu_spec cpu_specs[]; - -#ifdef __powerpc64__ extern struct cpu_spec *cur_cpu_spec; -#else /* __powerpc64__ */ -extern struct cpu_spec *cur_cpu_spec[]; -#endif /* __powerpc64__ */ #endif /* __ASSEMBLY__ */ @@ -398,11 +386,7 @@ static inline int cpu_has_feature(unsigned long feature) { return (CPU_FTRS_ALWAYS & feature) || (CPU_FTRS_POSSIBLE -#ifndef __powerpc64__ - & cur_cpu_spec[0]->cpu_features -#else & cur_cpu_spec->cpu_features -#endif & feature); } diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index 36b9d5cec50c..f0a6779fbe52 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -212,15 +212,13 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); /* ELF_HWCAP yields a mask that user programs can use to figure out what instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ -#ifdef __powerpc64__ # define ELF_HWCAP (cur_cpu_spec->cpu_user_features) +#ifdef __powerpc64__ # define ELF_PLAT_INIT(_r, load_addr) do { \ memset(_r->gpr, 0, sizeof(_r->gpr)); \ _r->ctr = _r->link = _r->xer = _r->ccr = 0; \ _r->gpr[2] = load_addr; \ } while (0) -#else -# define ELF_HWCAP (cur_cpu_spec[0]->cpu_user_features) #endif /* __powerpc64__ */ /* This yields a string that ld.so will use to load implementation From a3a9e99e36b2897b3e038869e61f363d62434086 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 28 Sep 2005 15:53:36 +1000 Subject: [PATCH 0162/1940] powerpc: Fix building in the old arch's boot directory for now Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index d94878193cd9..92751ca6f8b1 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -152,13 +152,13 @@ CPPFLAGS_vmlinux.lds := -Upowerpc # All the instructions talk about "make bzImage". bzImage: zImage -boot := arch/$(ARCH)/boot +boot := arch/$(OLDARCH)/boot $(BOOT_TARGETS): vmlinux - $(Q)$(MAKE) $(build)=$(boot) $@ + $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot) $@ uImage: vmlinux - $(Q)$(MAKE) $(build)=$(boot)/images $(boot)/images/$@ + $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@ define archhelp @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)' @@ -171,7 +171,7 @@ define archhelp endef archclean: - $(Q)$(MAKE) $(clean)=arch/ppc/boot + $(Q)$(MAKE) $(clean)=$(boot) # Temporary hack until we have migrated to asm-powerpc $(Q)rm -rf arch/$(ARCH)/include From 20c8c2106305729e7d5e06f6c3d390e965a3dd34 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 28 Sep 2005 20:28:14 +1000 Subject: [PATCH 0163/1940] powerpc: Fixes to get the merged kernel to boot on powermac. This merges ppc_ksyms.c, puts back the actual do_execve call in sys_execve, makes init_MMU call find_end_of_memory rather than ppc_md.find_end_of_memory (every platform has a device tree with a /memory node now, right?) and fixes some problems with the mpic initialization on newworld powermacs. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/ppc_ksyms.c | 338 +++++++++++++++++++++ arch/powerpc/kernel/process.c | 2 + arch/powerpc/mm/init.c | 2 +- arch/powerpc/platforms/powermac/pmac_pic.c | 17 ++ arch/ppc/kernel/Makefile | 2 +- 6 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/kernel/ppc_ksyms.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 62c4a51a23d7..58c130b10ec8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -14,5 +14,5 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y := semaphore.o traps.o process.o - +obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c new file mode 100644 index 000000000000..7bfa0f0121ff --- /dev/null +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -0,0 +1,338 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_8xx +#include +#endif + +extern void transfer_to_handler(void); +extern void do_IRQ(struct pt_regs *regs); +extern void MachineCheckException(struct pt_regs *regs); +extern void AlignmentException(struct pt_regs *regs); +extern void ProgramCheckException(struct pt_regs *regs); +extern void SingleStepException(struct pt_regs *regs); +extern int do_signal(sigset_t *, struct pt_regs *); +extern int pmac_newworld; +extern int sys_sigreturn(struct pt_regs *regs); + +long long __ashrdi3(long long, int); +long long __ashldi3(long long, int); +long long __lshrdi3(long long, int); + +extern unsigned long mm_ptov (unsigned long paddr); + +EXPORT_SYMBOL(clear_pages); +EXPORT_SYMBOL(clear_user_page); +EXPORT_SYMBOL(do_signal); +EXPORT_SYMBOL(transfer_to_handler); +EXPORT_SYMBOL(do_IRQ); +EXPORT_SYMBOL(MachineCheckException); +EXPORT_SYMBOL(AlignmentException); +EXPORT_SYMBOL(ProgramCheckException); +EXPORT_SYMBOL(SingleStepException); +EXPORT_SYMBOL(sys_sigreturn); +EXPORT_SYMBOL(ppc_n_lost_interrupts); +EXPORT_SYMBOL(ppc_lost_interrupts); + +EXPORT_SYMBOL(ISA_DMA_THRESHOLD); +EXPORT_SYMBOL(DMA_MODE_READ); +EXPORT_SYMBOL(DMA_MODE_WRITE); +#if defined(CONFIG_PPC_PREP) +EXPORT_SYMBOL(_prep_type); +EXPORT_SYMBOL(ucSystemType); +#endif + +#if !defined(__INLINE_BITOPS) +EXPORT_SYMBOL(set_bit); +EXPORT_SYMBOL(clear_bit); +EXPORT_SYMBOL(change_bit); +EXPORT_SYMBOL(test_and_set_bit); +EXPORT_SYMBOL(test_and_clear_bit); +EXPORT_SYMBOL(test_and_change_bit); +#endif /* __INLINE_BITOPS */ + +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strpbrk); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strcasecmp); +EXPORT_SYMBOL(__div64_32); + +EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(csum_partial_copy_generic); +EXPORT_SYMBOL(ip_fast_csum); +EXPORT_SYMBOL(csum_tcpudp_magic); + +EXPORT_SYMBOL(__copy_tofrom_user); +EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(__strnlen_user); + +EXPORT_SYMBOL(_insb); +EXPORT_SYMBOL(_outsb); +EXPORT_SYMBOL(_insw); +EXPORT_SYMBOL(_outsw); +EXPORT_SYMBOL(_insl); +EXPORT_SYMBOL(_outsl); +EXPORT_SYMBOL(_insw_ns); +EXPORT_SYMBOL(_outsw_ns); +EXPORT_SYMBOL(_insl_ns); +EXPORT_SYMBOL(_outsl_ns); +EXPORT_SYMBOL(iopa); +EXPORT_SYMBOL(mm_ptov); +EXPORT_SYMBOL(ioremap); +#ifdef CONFIG_44x +EXPORT_SYMBOL(ioremap64); +#endif +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +EXPORT_SYMBOL(ppc_ide_md); +#endif + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(isa_io_base); +EXPORT_SYMBOL(isa_mem_base); +EXPORT_SYMBOL(pci_dram_offset); +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_NOT_COHERENT_CACHE +EXPORT_SYMBOL(flush_dcache_all); +#endif + +EXPORT_SYMBOL(start_thread); +EXPORT_SYMBOL(kernel_thread); + +EXPORT_SYMBOL(flush_instruction_cache); +EXPORT_SYMBOL(giveup_fpu); +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(__flush_icache_range); +#else +EXPORT_SYMBOL(flush_icache_range); +#endif +EXPORT_SYMBOL(flush_dcache_range); +EXPORT_SYMBOL(flush_icache_user_range); +EXPORT_SYMBOL(flush_dcache_page); +EXPORT_SYMBOL(flush_tlb_kernel_range); +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(_tlbie); +#ifdef CONFIG_ALTIVEC +EXPORT_SYMBOL(last_task_used_altivec); +EXPORT_SYMBOL(giveup_altivec); +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE +EXPORT_SYMBOL(last_task_used_spe); +EXPORT_SYMBOL(giveup_spe); +#endif /* CONFIG_SPE */ +#ifdef CONFIG_SMP +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(smp_hw_index); +#endif + +EXPORT_SYMBOL(ppc_md); + +#ifdef CONFIG_ADB +EXPORT_SYMBOL(adb_request); +EXPORT_SYMBOL(adb_register); +EXPORT_SYMBOL(adb_unregister); +EXPORT_SYMBOL(adb_poll); +EXPORT_SYMBOL(adb_try_handler_change); +#endif /* CONFIG_ADB */ +#ifdef CONFIG_ADB_CUDA +EXPORT_SYMBOL(cuda_request); +EXPORT_SYMBOL(cuda_poll); +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_PPC_MULTIPLATFORM +EXPORT_SYMBOL(_machine); +#endif +#ifdef CONFIG_PPC_PMAC +EXPORT_SYMBOL(sys_ctrler); +EXPORT_SYMBOL(pmac_newworld); +#endif +#ifdef CONFIG_PPC_OF +EXPORT_SYMBOL(find_devices); +EXPORT_SYMBOL(find_type_devices); +EXPORT_SYMBOL(find_compatible_devices); +EXPORT_SYMBOL(find_path_device); +EXPORT_SYMBOL(device_is_compatible); +EXPORT_SYMBOL(machine_is_compatible); +EXPORT_SYMBOL(find_all_nodes); +EXPORT_SYMBOL(get_property); +EXPORT_SYMBOL(request_OF_resource); +EXPORT_SYMBOL(release_OF_resource); +EXPORT_SYMBOL(pci_busdev_to_OF_node); +EXPORT_SYMBOL(pci_device_to_OF_node); +EXPORT_SYMBOL(pci_device_from_OF_node); +EXPORT_SYMBOL(of_find_node_by_name); +EXPORT_SYMBOL(of_find_node_by_type); +EXPORT_SYMBOL(of_find_compatible_node); +EXPORT_SYMBOL(of_find_node_by_path); +EXPORT_SYMBOL(of_find_all_nodes); +EXPORT_SYMBOL(of_get_parent); +EXPORT_SYMBOL(of_get_next_child); +EXPORT_SYMBOL(of_node_get); +EXPORT_SYMBOL(of_node_put); +#endif /* CONFIG_PPC_OF */ +#if defined(CONFIG_BOOTX_TEXT) +EXPORT_SYMBOL(btext_update_display); +#endif +#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC) +EXPORT_SYMBOL(note_scsi_host); +#endif +#ifdef CONFIG_VT +EXPORT_SYMBOL(kd_mksound); +#endif +EXPORT_SYMBOL(to_tm); + +EXPORT_SYMBOL(pm_power_off); + +EXPORT_SYMBOL(__ashrdi3); +EXPORT_SYMBOL(__ashldi3); +EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(cacheable_memcpy); +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memchr); + +#if defined(CONFIG_FB_VGA16_MODULE) +EXPORT_SYMBOL(screen_info); +#endif + +EXPORT_SYMBOL(__delay); +EXPORT_SYMBOL(timer_interrupt); +EXPORT_SYMBOL(irq_desc); +EXPORT_SYMBOL(tb_ticks_per_jiffy); +EXPORT_SYMBOL(get_wchan); +EXPORT_SYMBOL(console_drivers); + +#ifdef CONFIG_PPC_ISERIES +EXPORT_SYMBOL(local_irq_disable); +EXPORT_SYMBOL(local_irq_enable); +EXPORT_SYMBOL(local_get_flags); +#endif + +#ifdef CONFIG_XMON +EXPORT_SYMBOL(xmon); +EXPORT_SYMBOL(xmon_printf); +#endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); + +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) +extern void (*debugger)(struct pt_regs *regs); +extern int (*debugger_bpt)(struct pt_regs *regs); +extern int (*debugger_sstep)(struct pt_regs *regs); +extern int (*debugger_iabr_match)(struct pt_regs *regs); +extern int (*debugger_dabr_match)(struct pt_regs *regs); +extern void (*debugger_fault_handler)(struct pt_regs *regs); + +EXPORT_SYMBOL(debugger); +EXPORT_SYMBOL(debugger_bpt); +EXPORT_SYMBOL(debugger_sstep); +EXPORT_SYMBOL(debugger_iabr_match); +EXPORT_SYMBOL(debugger_dabr_match); +EXPORT_SYMBOL(debugger_fault_handler); +#endif + +#ifdef CONFIG_8xx +EXPORT_SYMBOL(cpm_install_handler); +EXPORT_SYMBOL(cpm_free_handler); +#endif /* CONFIG_8xx */ +#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\ + defined(CONFIG_83xx) +EXPORT_SYMBOL(__res); +#endif + +EXPORT_SYMBOL(next_mmu_context); +EXPORT_SYMBOL(set_context); +EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */ +EXPORT_SYMBOL(disarm_decr); +#ifdef CONFIG_PPC_STD_MMU +extern long mol_trampoline; +EXPORT_SYMBOL(mol_trampoline); /* For MOL */ +EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ +#ifdef CONFIG_SMP +extern int mmu_hash_lock; +EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ +#endif /* CONFIG_SMP */ +extern long *intercept_table; +EXPORT_SYMBOL(intercept_table); +#endif /* CONFIG_PPC_STD_MMU */ +EXPORT_SYMBOL(cur_cpu_spec); +#ifdef CONFIG_PPC_PMAC +extern unsigned long agp_special_page; +EXPORT_SYMBOL(agp_special_page); +#endif +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) +EXPORT_SYMBOL(__mtdcr); +EXPORT_SYMBOL(__mfdcr); +#endif diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index f5a9d2a84fa1..e3946769dd8e 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -601,6 +601,8 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, flush_fp_to_thread(current); flush_altivec_to_thread(current); flush_spe_to_thread(current); + error = do_execve(filename, (char __user * __user *) a1, + (char __user * __user *) a2, regs); if (error == 0) { task_lock(current); current->ptrace &= ~PT_DTRACE; diff --git a/arch/powerpc/mm/init.c b/arch/powerpc/mm/init.c index f4d983a6e521..3a81ef15c67e 100644 --- a/arch/powerpc/mm/init.c +++ b/arch/powerpc/mm/init.c @@ -239,7 +239,7 @@ void __init MMU_init(void) if (boot_mem_size) total_memory = boot_mem_size; else - total_memory = ppc_md.find_end_of_memory(); + total_memory = find_end_of_memory(); if (__max_memory && total_memory > __max_memory) total_memory = __max_memory; diff --git a/arch/powerpc/platforms/powermac/pmac_pic.c b/arch/powerpc/platforms/powermac/pmac_pic.c index bf3e1899a4cc..a6b1b577e19f 100644 --- a/arch/powerpc/platforms/powermac/pmac_pic.c +++ b/arch/powerpc/platforms/powermac/pmac_pic.c @@ -424,6 +424,8 @@ void __init pmac_pic_init(void) printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", (unsigned int)irqctrler->addrs[0].address); + ppc_md.get_irq = mpic_get_irq; + pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); prom_get_irq_senses(senses, 0, 128); mpic1 = mpic_alloc(irqctrler->addrs[0].address, @@ -452,7 +454,22 @@ void __init pmac_pic_init(void) mpic_setup_cascade(irqctrler2->intrs[0].line, pmac_u3_cascade, mpic2); } +#ifdef CONFIG_XMON + { + struct device_node* pswitch; + int nmi_irq; + + pswitch = find_devices("programmer-switch"); + if (pswitch && pswitch->n_intrs) { + nmi_irq = pswitch->intrs[0].line; + openpic_init_nmi_irq(nmi_irq); + setup_irq(nmi_irq, &xmon_action); + } + } +#endif /* CONFIG_XMON */ + return; } + irqctrler = NULL; /* Get the level/edge settings, assume if it's not * a Grand Central nor an OHare, then it's an Heathrow diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 0649540bc7d9..467f96480355 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -47,7 +47,7 @@ obj-y := entry.o irq.o idle.o time.o misc.o \ obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_POWER4) += cpu_setup_power4.o -obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o +obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_KGDB) += ppc-stub.o From beeca08738c4c4024c81a591812bfe38f8c436c0 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 28 Sep 2005 20:29:44 +1000 Subject: [PATCH 0164/1940] Don't call a NULL ack function in the generic IRQ code. Some IRQ controllers don't need an ack function (e.g. OpenPIC on PPC platforms) and for them we'd rather not have the overhead of doing an indirect call to a function that does nothing. Signed-off-by: Paul Mackerras --- kernel/irq/handle.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 3ff7b925c387..51df337b37db 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -117,14 +117,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) /* * No locking required for CPU-local interrupts: */ - desc->handler->ack(irq); + if (desc->handler->ack) + desc->handler->ack(irq); action_ret = handle_IRQ_event(irq, regs, desc->action); desc->handler->end(irq); return 1; } spin_lock(&desc->lock); - desc->handler->ack(irq); + if (desc->handler->ack) + desc->handler->ack(irq); /* * REPLAY is when Linux resends an IRQ that was dropped earlier * WAITING is used by probe to mark irqs that are being tested From 59c422358d6573716f2bf2e78e5b12c20eff5a31 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 27 Sep 2005 08:25:32 -0500 Subject: [PATCH 0165/1940] [IA64-SGI] Increase max system size of SGI SN systems Increase the maximum system size of SGI SN systems. Note that this is not the maximum SSI size. The maximum system size is the number of nodes in the numalink domain. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- include/asm-ia64/sn/arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h index 8fce5a6db951..1a3831c04af6 100644 --- a/include/asm-ia64/sn/arch.h +++ b/include/asm-ia64/sn/arch.h @@ -41,7 +41,7 @@ * This value is also the value of the maximum number of NASIDs in the numalink * fabric. */ -#define MAX_NUMALINK_NODES 2048 +#define MAX_NUMALINK_NODES 16384 /* * The following defines attributes of the HUB chip. These attributes are From d719948e623622cf9fc8016f7ec63422d929eb3b Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 28 Sep 2005 16:09:46 -0700 Subject: [PATCH 0166/1940] [IA64] end of kernel 'data' is at _end, not _edata /proc/iomem describes a block of memory as "Kernel data", but the end address is derived from "_edata". The kernel actually has many other sections beyond _edata. Get the real end address from _end. Acked-by: Khalid Aziz Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 83b37c410ccd..3e9b797e6588 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -89,7 +89,7 @@ static struct resource code_resource = { }; extern void efi_initialize_iomem_resources(struct resource *, struct resource *); -extern char _text[], _edata[], _etext[]; +extern char _text[], _end[], _etext[]; unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ @@ -192,7 +192,7 @@ static int __init register_memory(void) code_resource.start = ia64_tpa(_text); code_resource.end = ia64_tpa(_etext) - 1; data_resource.start = ia64_tpa(_etext); - data_resource.end = ia64_tpa(_edata) - 1; + data_resource.end = ia64_tpa(_end) - 1; efi_initialize_iomem_resources(&code_resource, &data_resource); return 0; From 6c654b5fdf093cd05f35f7c9c2a00182fa5636dc Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:42:42 -0700 Subject: [PATCH 0167/1940] [PATCH] swiotlb: move from arch/ia64/lib/ to lib/ The swiotlb implementation is shared by both IA-64 and EM64T. However, the source itself lives under arch/ia64. This patch moves swiotlb.c from arch/ia64/lib to lib/ and fixes-up the appropriate Makefile and Kconfig files. No actual changes are made to swiotlb.c. Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 4 ++++ arch/ia64/lib/Makefile | 2 +- arch/x86_64/kernel/Makefile | 2 -- lib/Makefile | 2 ++ {arch/ia64/lib => lib}/swiotlb.c | 0 5 files changed, 7 insertions(+), 3 deletions(-) rename {arch/ia64/lib => lib}/swiotlb.c (100%) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index ed25d66c8d50..ea4a889d8196 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -26,6 +26,10 @@ config MMU bool default y +config SWIOTLB + bool + default y + config RWSEM_XCHGADD_ALGORITHM bool default y diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 799407e7726f..4be1546e1726 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -9,7 +9,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ bitop.o checksum.o clear_page.o csum_partial_copy.o \ clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ flush.o ip_fast_csum.o do_csum.o \ - memset.o strlen.o swiotlb.o + memset.o strlen.o lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index bcdd0a805fe7..14328cab5d3a 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o -obj-$(CONFIG_SWIOTLB) += swiotlb.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o @@ -41,7 +40,6 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0 bootflag-y += ../../i386/kernel/bootflag.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o topology-y += ../../i386/mach-default/topology.o -swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o quirks-y += ../../i386/kernel/quirks.o diff --git a/lib/Makefile b/lib/Makefile index 44a46750690a..8535f4d7d1c3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,6 +44,8 @@ obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o +obj-$(CONFIG_SWIOTLB) += swiotlb.o + hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/arch/ia64/lib/swiotlb.c b/lib/swiotlb.c similarity index 100% rename from arch/ia64/lib/swiotlb.c rename to lib/swiotlb.c From 8270f3f1a605c83b3aa516c1eaed209fe0884e84 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:43:32 -0700 Subject: [PATCH 0168/1940] [PATCH] swiotlb: cleanup some code duplication cruft The implementations of swiotlb_sync_single_for_{cpu,device} are identical. Likewise for swiotlb_syng_sg_for_{cpu,device}. This patch move the guts of those functions to two new inline functions, and calls the appropriate one from the bodies of those functions. Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- lib/swiotlb.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 875b0c16250c..9719a14649e7 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -594,9 +594,9 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, * address back to the card, you must first perform a * swiotlb_dma_sync_for_device, and then the device again owns the buffer */ -void -swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) +static inline void +swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir) { char *dma_addr = phys_to_virt(dev_addr); @@ -608,18 +608,18 @@ swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, mark_clean(dma_addr, size); } +void +swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir) +{ + swiotlb_sync_single(hwdev, dev_addr, size, dir); +} + void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { - char *dma_addr = phys_to_virt(dev_addr); - - if (dir == DMA_NONE) - BUG(); - if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) - sync_single(hwdev, dma_addr, size, dir); - else if (dir == DMA_FROM_DEVICE) - mark_clean(dma_addr, size); + swiotlb_sync_single(hwdev, dev_addr, size, dir); } /* @@ -696,9 +696,9 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules * and usage. */ -void -swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) +static inline void +swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, + int nelems, int dir) { int i; @@ -711,19 +711,18 @@ swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, sg->dma_length, dir); } +void +swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, + int nelems, int dir) +{ + swiotlb_sync_sg(hwdev, sg, nelems, dir); +} + void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int dir) { - int i; - - if (dir == DMA_NONE) - BUG(); - - for (i = 0; i < nelems; i++, sg++) - if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) - sync_single(hwdev, (void *) sg->dma_address, - sg->dma_length, dir); + swiotlb_sync_sg(hwdev, sg, nelems, dir); } int From 878a97cfd7014b01285db09f52f9881ffe4cb608 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:44:23 -0700 Subject: [PATCH 0169/1940] [PATCH] swiotlb: support syncing sub-ranges of mappings This patch implements swiotlb_sync_single_range_for_{cpu,device}. This is intended to support an x86_64 implementation of dma_sync_single_range_for_{cpu,device}. Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- include/asm-x86_64/swiotlb.h | 8 ++++++++ lib/swiotlb.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h index 36293061f4ed..9b011dd8d19d 100644 --- a/include/asm-x86_64/swiotlb.h +++ b/include/asm-x86_64/swiotlb.h @@ -15,6 +15,14 @@ extern void swiotlb_sync_single_for_cpu(struct device *hwdev, extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir); +extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, + dma_addr_t dev_addr, + unsigned long offset, + size_t size, int dir); +extern void swiotlb_sync_single_range_for_device(struct device *hwdev, + dma_addr_t dev_addr, + unsigned long offset, + size_t size, int dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int dir); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 9719a14649e7..566791b3f583 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -622,6 +622,37 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, swiotlb_sync_single(hwdev, dev_addr, size, dir); } +/* + * Same as above, but for a sub-range of the mapping. + */ +static inline void +swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, + unsigned long offset, size_t size, int dir) +{ + char *dma_addr = phys_to_virt(dev_addr) + offset; + + if (dir == DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + sync_single(hwdev, dma_addr, size, dir); + else if (dir == DMA_FROM_DEVICE) + mark_clean(dma_addr, size); +} + +void +swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, + unsigned long offset, size_t size, int dir) +{ + swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir); +} + +void +swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, + unsigned long offset, size_t size, int dir) +{ + swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir); +} + /* * Map a set of buffers described by scatterlist in streaming mode for DMA. * This is the scatter-gather version of the above swiotlb_map_single @@ -750,6 +781,8 @@ EXPORT_SYMBOL(swiotlb_map_sg); EXPORT_SYMBOL(swiotlb_unmap_sg); EXPORT_SYMBOL(swiotlb_sync_single_for_cpu); EXPORT_SYMBOL(swiotlb_sync_single_for_device); +EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu); +EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); EXPORT_SYMBOL(swiotlb_sync_sg_for_device); EXPORT_SYMBOL(swiotlb_dma_mapping_error); From de69e0f0b38a467d881e138a302b005bf31c8400 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:44:57 -0700 Subject: [PATCH 0170/1940] [PATCH] swiotlb: support syncing DMA_BIDIRECTIONAL mappings The current implementation of sync_single in swiotlb.c chokes on DMA_BIDIRECTIONAL mappings. This patch adds the capability to sync those mappings, and optimizes other syncs by accounting for the sync target (i.e. cpu or device) in addition to the DMA direction of the mapping. Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- lib/swiotlb.c | 62 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 566791b3f583..a1a6d6bf87b4 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -58,6 +58,14 @@ */ #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) +/* + * Enumeration for sync targets + */ +enum dma_sync_target { + SYNC_FOR_CPU = 0, + SYNC_FOR_DEVICE = 1, +}; + int swiotlb_force; /* @@ -397,21 +405,28 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) } static void -sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir) +sync_single(struct device *hwdev, char *dma_addr, size_t size, + int dir, int target) { int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; char *buffer = io_tlb_orig_addr[index]; - /* - * bounce... copy the data back into/from the original buffer - * XXX How do you handle DMA_BIDIRECTIONAL here ? - */ - if (dir == DMA_FROM_DEVICE) - memcpy(buffer, dma_addr, size); - else if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, buffer, size); - else + switch (target) { + case SYNC_FOR_CPU: + if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) + memcpy(buffer, dma_addr, size); + else if (dir != DMA_TO_DEVICE) + BUG(); + break; + case SYNC_FOR_DEVICE: + if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) + memcpy(dma_addr, buffer, size); + else if (dir != DMA_FROM_DEVICE) + BUG(); + break; + default: BUG(); + } } void * @@ -596,14 +611,14 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, */ static inline void swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, int dir, int target) { char *dma_addr = phys_to_virt(dev_addr); if (dir == DMA_NONE) BUG(); if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) - sync_single(hwdev, dma_addr, size, dir); + sync_single(hwdev, dma_addr, size, dir, target); else if (dir == DMA_FROM_DEVICE) mark_clean(dma_addr, size); } @@ -612,14 +627,14 @@ void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { - swiotlb_sync_single(hwdev, dev_addr, size, dir); + swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); } void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { - swiotlb_sync_single(hwdev, dev_addr, size, dir); + swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); } /* @@ -627,14 +642,15 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, */ static inline void swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir) + unsigned long offset, size_t size, + int dir, int target) { char *dma_addr = phys_to_virt(dev_addr) + offset; if (dir == DMA_NONE) BUG(); if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) - sync_single(hwdev, dma_addr, size, dir); + sync_single(hwdev, dma_addr, size, dir, target); else if (dir == DMA_FROM_DEVICE) mark_clean(dma_addr, size); } @@ -643,14 +659,16 @@ void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, int dir) { - swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir); + swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, + SYNC_FOR_CPU); } void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, int dir) { - swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir); + swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, + SYNC_FOR_DEVICE); } /* @@ -729,7 +747,7 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, */ static inline void swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) + int nelems, int dir, int target) { int i; @@ -739,21 +757,21 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, for (i = 0; i < nelems; i++, sg++) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) sync_single(hwdev, (void *) sg->dma_address, - sg->dma_length, dir); + sg->dma_length, dir, target); } void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int dir) { - swiotlb_sync_sg(hwdev, sg, nelems, dir); + swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); } void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int dir) { - swiotlb_sync_sg(hwdev, sg, nelems, dir); + swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); } int From 569c8bf5d8eeeeb9f5250d5b7991007874f0fef2 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:45:24 -0700 Subject: [PATCH 0171/1940] [PATCH] swiotlb: file header comments Change comment at top of swiotlb.c to reflect that the code is shared with EM64T (i.e. Intel x86_64). Also add an entry for myself so that if I "broke it", everyone knows who "bought it"... :-) Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- lib/swiotlb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c index a1a6d6bf87b4..cae806d1ef12 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -1,7 +1,7 @@ /* * Dynamic DMA mapping support. * - * This implementation is for IA-64 platforms that do not support + * This implementation is for IA-64 and EM64T platforms that do not support * I/O TLBs (aka DMA address translation hardware). * Copyright (C) 2000 Asit Mallick * Copyright (C) 2000 Goutham Rao @@ -11,7 +11,9 @@ * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API. * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid * unnecessary i-cache flushing. - * 04/07/.. ak Better overflow handling. Assorted fixes. + * 04/07/.. ak Better overflow handling. Assorted fixes. + * 05/09/10 linville Add support for syncing ranges, support syncing for + * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup. */ #include From 8d15d19e44d2e903d00ae4b70da917ac77921239 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Sep 2005 14:45:52 -0700 Subject: [PATCH 0172/1940] [PATCH] x86_64: implement dma_sync_single_range_for_{cpu,device} Re-implement dma_sync_single_range_for_{cpu,device} for x86_64 using swiotlb_sync_single_range_for_{cpu,device}. Signed-off-by: John W. Linville Signed-off-by: Tony Luck --- include/asm-x86_64/dma-mapping.h | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index e784fdc524f1..45ca88c875c0 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h @@ -85,10 +85,33 @@ static inline void dma_sync_single_for_device(struct device *hwdev, flush_write_buffers(); } -#define dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, dir) \ - dma_sync_single_for_cpu(dev, dma_handle, size, dir) -#define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \ - dma_sync_single_for_device(dev, dma_handle, size, dir) +static inline void dma_sync_single_range_for_cpu(struct device *hwdev, + dma_addr_t dma_handle, + unsigned long offset, + size_t size, int direction) +{ + if (direction == DMA_NONE) + out_of_line_bug(); + + if (swiotlb) + return swiotlb_sync_single_range_for_cpu(hwdev,dma_handle,offset,size,direction); + + flush_write_buffers(); +} + +static inline void dma_sync_single_range_for_device(struct device *hwdev, + dma_addr_t dma_handle, + unsigned long offset, + size_t size, int direction) +{ + if (direction == DMA_NONE) + out_of_line_bug(); + + if (swiotlb) + return swiotlb_sync_single_range_for_device(hwdev,dma_handle,offset,size,direction); + + flush_write_buffers(); +} static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, From 17e5ad6c0ce5a970e2830d0de8bdd60a2f077d38 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 29 Sep 2005 15:52:13 -0700 Subject: [PATCH 0173/1940] [PATCH] Removed remaining PCI specific references from swiotlb.c Matthew Wilcox pointed out that swiotlb.c implements a generic interface that is not tied to just PCI. Remove includes of , . Fix comments and printk() messages to no longer refer to PCI. Signed-off-by: Tony Luck --- lib/swiotlb.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c index cae806d1ef12..c2fc470b6ed8 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -17,17 +17,17 @@ */ #include +#include #include #include -#include #include #include #include #include #include -#include #include +#include #include #include @@ -127,7 +127,7 @@ __setup("swiotlb=", setup_io_tlb_npages); /* * Statically reserve bounce buffer space and initialize bounce buffer data - * structures for the software IO TLB used to implement the PCI DMA API. + * structures for the software IO TLB used to implement the DMA API. */ void swiotlb_init_with_default_size (size_t default_size) @@ -502,24 +502,24 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) /* * Ran out of IOMMU space for this operation. This is very bad. * Unfortunately the drivers cannot handle this operation properly. - * unless they check for pci_dma_mapping_error (most don't) + * unless they check for dma_mapping_error (most don't) * When the mapping is small enough return a static buffer to limit * the damage, or panic when the transfer is too big. */ - printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at " + printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at " "device %s\n", size, dev ? dev->bus_id : "?"); if (size > io_tlb_overflow && do_panic) { - if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL) - panic("PCI-DMA: Memory would be corrupted\n"); - if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) - panic("PCI-DMA: Random memory would be DMAed\n"); + if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) + panic("DMA: Memory would be corrupted\n"); + if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) + panic("DMA: Random memory would be DMAed\n"); } } /* * Map a single buffer of the indicated size for DMA in streaming mode. The - * PCI address to use is returned. + * physical address to use is returned. * * Once the device is given the dma address, the device owns this memory until * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. @@ -606,8 +606,8 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, * after a transfer. * * If you perform a swiotlb_map_single() but wish to interrogate the buffer - * using the cpu, yet do not wish to teardown the PCI dma mapping, you must - * call this function before doing so. At the next point you give the PCI dma + * using the cpu, yet do not wish to teardown the dma mapping, you must + * call this function before doing so. At the next point you give the dma * address back to the card, you must first perform a * swiotlb_dma_sync_for_device, and then the device again owns the buffer */ @@ -783,9 +783,9 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr) } /* - * Return whether the given PCI device DMA address mask can be supported + * Return whether the given device DMA address mask can be supported * properly. For example, if your device can only drive the low 24-bits - * during PCI bus mastering, then you would pass 0x00ffffff as the mask to + * during bus mastering, then you would pass 0x00ffffff as the mask to * this function. */ int From 689b9d74b1c00e1316fbb7d1e912fe1227fdb1ab Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 Sep 2005 17:09:07 +1000 Subject: [PATCH 0174/1940] drm: add option to force writeback off. In order to get some better debugging from people about certain hangs/crashes we need to be able to turn AGP writeback off permanently... Signed-off-by: Dave Airlie --- drivers/char/drm/radeon_cp.c | 4 ++++ drivers/char/drm/radeon_drv.c | 5 +++++ drivers/char/drm/radeon_drv.h | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 447bfbe0da8a..e64d680899f5 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -1205,6 +1205,10 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, dev_priv->writeback_works = 0; DRM_DEBUG("writeback test failed\n"); } + if (radeon_no_wb == 1) { + dev_priv->writeback_works = 0; + DRM_DEBUG("writeback forced off\n"); + } dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index 6c1766120c10..7074d01ed1dd 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c @@ -37,6 +37,11 @@ #include "drm_pciids.h" +int radeon_no_wb; + +MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); +module_param_named(no_wb, radeon_no_wb, int, 0444); + static int postinit(struct drm_device *dev, unsigned long flags) { DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index e36076981d1a..3c7473488665 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -281,6 +281,7 @@ typedef struct drm_radeon_buf_priv { u32 age; } drm_radeon_buf_priv_t; +extern int radeon_no_wb; /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); From b08567cb680686cdea9e362c0ccf0a08d77b9f0c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 28 Sep 2005 23:37:01 +1000 Subject: [PATCH 0175/1940] ppc64 iseries: move some iSeries include files These files are only referenced from within arch/powerpc/platforms/iseries, so move them there. Signed-off-by: Stephen Rothwell --- .../powerpc/platforms/iseries/call_sm.h | 7 +++---- .../powerpc/platforms/iseries/ipl_parms.h | 7 +++---- arch/powerpc/platforms/iseries/irq.c | 3 ++- .../powerpc/platforms/iseries/irq.h | 6 +++--- arch/powerpc/platforms/iseries/lpardata.c | 10 +++++----- .../powerpc/platforms/iseries/main_store.h | 7 +++---- arch/powerpc/platforms/iseries/pci.c | 3 ++- arch/powerpc/platforms/iseries/proc.c | 5 +++-- .../powerpc/platforms/iseries/processor_vpd.h | 7 +++---- .../powerpc/platforms/iseries/release_data.h | 7 +++---- arch/powerpc/platforms/iseries/setup.c | 10 +++++----- .../powerpc/platforms/iseries/spcomm_area.h | 7 +++---- .../powerpc/platforms/iseries/vpd_areas.h | 7 +++---- 13 files changed, 41 insertions(+), 45 deletions(-) rename include/asm-ppc64/iSeries/HvCallSm.h => arch/powerpc/platforms/iseries/call_sm.h (93%) rename include/asm-ppc64/iSeries/ItIplParmsReal.h => arch/powerpc/platforms/iseries/ipl_parms.h (96%) rename include/asm-ppc64/iSeries/iSeries_irq.h => arch/powerpc/platforms/iseries/irq.h (64%) rename include/asm-ppc64/iSeries/IoHriMainStore.h => arch/powerpc/platforms/iseries/main_store.h (97%) rename include/asm-ppc64/iSeries/IoHriProcessorVpd.h => arch/powerpc/platforms/iseries/processor_vpd.h (96%) rename include/asm-ppc64/iSeries/HvReleaseData.h => arch/powerpc/platforms/iseries/release_data.h (95%) rename include/asm-ppc64/iSeries/ItSpCommArea.h => arch/powerpc/platforms/iseries/spcomm_area.h (93%) rename include/asm-ppc64/iSeries/ItVpdAreas.h => arch/powerpc/platforms/iseries/vpd_areas.h (97%) diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/arch/powerpc/platforms/iseries/call_sm.h similarity index 93% rename from include/asm-ppc64/iSeries/HvCallSm.h rename to arch/powerpc/platforms/iseries/call_sm.h index 8a3dbb071a43..ef223166cf22 100644 --- a/include/asm-ppc64/iSeries/HvCallSm.h +++ b/arch/powerpc/platforms/iseries/call_sm.h @@ -1,5 +1,4 @@ /* - * HvCallSm.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _HVCALLSM_H -#define _HVCALLSM_H +#ifndef _ISERIES_CALL_SM_H +#define _ISERIES_CALL_SM_H /* * This file contains the "hypervisor call" interface which is used to @@ -35,4 +34,4 @@ static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex, return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap); } -#endif /* _HVCALLSM_H */ +#endif /* _ISERIES_CALL_SM_H */ diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/arch/powerpc/platforms/iseries/ipl_parms.h similarity index 96% rename from include/asm-ppc64/iSeries/ItIplParmsReal.h rename to arch/powerpc/platforms/iseries/ipl_parms.h index ae3417dc599e..77c135ddbf1b 100644 --- a/include/asm-ppc64/iSeries/ItIplParmsReal.h +++ b/arch/powerpc/platforms/iseries/ipl_parms.h @@ -1,5 +1,4 @@ /* - * ItIplParmsReal.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ITIPLPARMSREAL_H -#define _ITIPLPARMSREAL_H +#ifndef _ISERIES_IPL_PARMS_H +#define _ISERIES_IPL_PARMS_H /* * This struct maps the IPL Parameters DMA'd from the SP. @@ -68,4 +67,4 @@ struct ItIplParmsReal { extern struct ItIplParmsReal xItIplParmsReal; -#endif /* _ITIPLPARMSREAL_H */ +#endif /* _ISERIES_IPL_PARMS_H */ diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 5a8a0056b31f..31fb5fa67fa3 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -40,7 +40,8 @@ #include #include #include -#include + +#include "irq.h" /* This maps virtual irq numbers to real irqs */ unsigned int virt_irq_to_real_map[NR_IRQS]; diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/arch/powerpc/platforms/iseries/irq.h similarity index 64% rename from include/asm-ppc64/iSeries/iSeries_irq.h rename to arch/powerpc/platforms/iseries/irq.h index 6c9767ac1302..5f643f16ecc0 100644 --- a/include/asm-ppc64/iSeries/iSeries_irq.h +++ b/arch/powerpc/platforms/iseries/irq.h @@ -1,8 +1,8 @@ -#ifndef __ISERIES_IRQ_H__ -#define __ISERIES_IRQ_H__ +#ifndef _ISERIES_IRQ_H +#define _ISERIES_IRQ_H extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); extern void iSeries_activate_IRQs(void); -#endif /* __ISERIES_IRQ_H__ */ +#endif /* _ISERIES_IRQ_H */ diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c index 87b7ad8ca465..ed2ffee6f731 100644 --- a/arch/powerpc/platforms/iseries/lpardata.c +++ b/arch/powerpc/platforms/iseries/lpardata.c @@ -19,15 +19,15 @@ #include #include #include -#include #include -#include -#include #include #include -#include -#include +#include "vpd_areas.h" +#include "spcomm_area.h" +#include "ipl_parms.h" +#include "processor_vpd.h" +#include "release_data.h" /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/arch/powerpc/platforms/iseries/main_store.h similarity index 97% rename from include/asm-ppc64/iSeries/IoHriMainStore.h rename to arch/powerpc/platforms/iseries/main_store.h index 45ed3ea67d06..74f6889f834f 100644 --- a/include/asm-ppc64/iSeries/IoHriMainStore.h +++ b/arch/powerpc/platforms/iseries/main_store.h @@ -1,5 +1,4 @@ /* - * IoHriMainStore.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -17,8 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _IOHRIMAINSTORE_H -#define _IOHRIMAINSTORE_H +#ifndef _ISERIES_MAIN_STORE_H +#define _ISERIES_MAIN_STORE_H /* Main Store Vpd for Condor,iStar,sStar */ struct IoHriMainStoreSegment4 { @@ -163,4 +162,4 @@ struct IoHriMainStoreSegment5 { extern u64 xMsVpd[]; -#endif /* _IOHRIMAINSTORE_H */ +#endif /* _ISERIES_MAIN_STORE_H */ diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 501b1dcbfac5..70185dec940b 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -37,12 +37,13 @@ #include #include -#include #include #include #include +#include "irq.h" + extern unsigned long io_page_mask; /* diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index d46b473ce4dd..6f1929cac66b 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c @@ -26,8 +26,9 @@ #include #include #include -#include -#include + +#include "processor_vpd.h" +#include "main_store.h" static int __init iseries_proc_create(void) { diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/arch/powerpc/platforms/iseries/processor_vpd.h similarity index 96% rename from include/asm-ppc64/iSeries/IoHriProcessorVpd.h rename to arch/powerpc/platforms/iseries/processor_vpd.h index 73b73d80b8b1..7ac5d0d0dbfa 100644 --- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h +++ b/arch/powerpc/platforms/iseries/processor_vpd.h @@ -1,5 +1,4 @@ /* - * IoHriProcessorVpd.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _IOHRIPROCESSORVPD_H -#define _IOHRIPROCESSORVPD_H +#ifndef _ISERIES_PROCESSOR_VPD_H +#define _ISERIES_PROCESSOR_VPD_H #include @@ -83,4 +82,4 @@ struct IoHriProcessorVpd { extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; -#endif /* _IOHRIPROCESSORVPD_H */ +#endif /* _ISERIES_PROCESSOR_VPD_H */ diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/arch/powerpc/platforms/iseries/release_data.h similarity index 95% rename from include/asm-ppc64/iSeries/HvReleaseData.h rename to arch/powerpc/platforms/iseries/release_data.h index c8162e5ccb21..c68b9c3e5caf 100644 --- a/include/asm-ppc64/iSeries/HvReleaseData.h +++ b/arch/powerpc/platforms/iseries/release_data.h @@ -1,5 +1,4 @@ /* - * HvReleaseData.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _HVRELEASEDATA_H -#define _HVRELEASEDATA_H +#ifndef _ISERIES_RELEASE_DATA_H +#define _ISERIES_RELEASE_DATA_H /* * This control block contains the critical information about the @@ -61,4 +60,4 @@ struct HvReleaseData { extern struct HvReleaseData hvReleaseData; -#endif /* _HVRELEASEDATA_H */ +#endif /* _ISERIES_RELEASE_DATA_H */ diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index ad78c8581a5a..c3e532b766ef 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -48,18 +48,18 @@ #include #include #include -#include #include #include -#include #include #include -#include -#include -#include #include #include "setup.h" +#include "irq.h" +#include "vpd_areas.h" +#include "processor_vpd.h" +#include "main_store.h" +#include "call_sm.h" extern void hvlog(char *fmt, ...); diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/arch/powerpc/platforms/iseries/spcomm_area.h similarity index 93% rename from include/asm-ppc64/iSeries/ItSpCommArea.h rename to arch/powerpc/platforms/iseries/spcomm_area.h index 5535f8271c9f..6e3b685115c9 100644 --- a/include/asm-ppc64/iSeries/ItSpCommArea.h +++ b/arch/powerpc/platforms/iseries/spcomm_area.h @@ -1,5 +1,4 @@ /* - * ItSpCommArea.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -17,8 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ITSPCOMMAREA_H -#define _ITSPCOMMAREA_H +#ifndef _ISERIES_SPCOMM_AREA_H +#define _ISERIES_SPCOMM_AREA_H struct SpCommArea { @@ -34,4 +33,4 @@ struct SpCommArea { extern struct SpCommArea xSpCommArea; -#endif /* _ITSPCOMMAREA_H */ +#endif /* _ISERIES_SPCOMM_AREA_H */ diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/arch/powerpc/platforms/iseries/vpd_areas.h similarity index 97% rename from include/asm-ppc64/iSeries/ItVpdAreas.h rename to arch/powerpc/platforms/iseries/vpd_areas.h index 71b3ad24f95a..601e6dd860ed 100644 --- a/include/asm-ppc64/iSeries/ItVpdAreas.h +++ b/arch/powerpc/platforms/iseries/vpd_areas.h @@ -1,5 +1,4 @@ /* - * ItVpdAreas.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ITVPDAREAS_H -#define _ITVPDAREAS_H +#ifndef _ISERIES_VPD_AREAS_H +#define _ISERIES_VPD_AREAS_H /* * This file defines the address and length of all of the VPD area passed to @@ -86,4 +85,4 @@ struct ItVpdAreas { extern struct ItVpdAreas itVpdAreas; -#endif /* _ITVPDAREAS_H */ +#endif /* _ISERIES_VPD_AREAS_H */ From d1dead5c5f016ebadb4b87c2c9fa13dfc2c99bf0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Sep 2005 00:35:31 +1000 Subject: [PATCH 0176/1940] powerpc: merge asm-offsets.c Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/asm-offsets.c | 224 ++++++++++++++++-------------- 1 file changed, 119 insertions(+), 105 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 16cf0b7ee2b7..3a247c033e8b 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -20,17 +20,20 @@ #include #include #include -#include -#include #include #include +#ifdef CONFIG_PPC64 #include #include +#else +#include +#include +#endif + #include #include #include #include - #include #include #ifdef CONFIG_PPC64 @@ -50,63 +53,117 @@ int main(void) { - /* thread struct on stack */ - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -#ifdef CONFIG_PPC32 - DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); -#endif -#ifdef CONFIG_PPC64 - DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); - DEFINE(THREAD_SHIFT, THREAD_SHIFT); -#endif - DEFINE(THREAD_SIZE, THREAD_SIZE); - - /* task_struct->thread */ DEFINE(THREAD, offsetof(struct task_struct, thread)); - DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); DEFINE(MM, offsetof(struct task_struct, mm)); +#ifdef CONFIG_PPC64 + DEFINE(THREAD_SHIFT, THREAD_SHIFT); + DEFINE(THREAD_SIZE, THREAD_SIZE); + DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); +#else + DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); +#endif /* CONFIG_PPC64 */ + DEFINE(KSP, offsetof(struct thread_struct, ksp)); - DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); - DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall)); DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); - DEFINE(PT_PTRACED, PT_PTRACED); -#endif -#ifdef CONFIG_PPC64 - DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); -#endif - #ifdef CONFIG_ALTIVEC DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_PPC64 + DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); +#else /* CONFIG_PPC64 */ + DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); + DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall)); +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); + DEFINE(PT_PTRACED, PT_PTRACED); +#endif #ifdef CONFIG_SPE DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0])); DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc)); DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr)); DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe)); #endif /* CONFIG_SPE */ +#endif /* CONFIG_PPC64 */ + + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); +#ifdef CONFIG_PPC64 + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); +#else + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); + DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); +#endif /* CONFIG_PPC64 */ + +#ifdef CONFIG_PPC64 + DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); + DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size)); + DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page)); + DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); + DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); + DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); + DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); + + /* paca */ + DEFINE(PACA_SIZE, sizeof(struct paca_struct)); + DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); + DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start)); + DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack)); + DEFINE(PACACURRENT, offsetof(struct paca_struct, __current)); + DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr)); + DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real)); + DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr)); + DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); + DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); + DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); + DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); + DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); + DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); + DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); +#ifdef CONFIG_HUGETLB_PAGE + DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); + DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); +#endif /* CONFIG_HUGETLB_PAGE */ + DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr)); + DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); + DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); + DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); + DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi)); + DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); + DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); + DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); + + DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); + DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); + DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); + DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); + + /* RTAS */ + DEFINE(RTASBASE, offsetof(struct rtas_t, base)); + DEFINE(RTASENTRY, offsetof(struct rtas_t, entry)); +#endif /* CONFIG_PPC64 */ + /* Interrupt register frame */ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); #ifndef CONFIG_PPC64 DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); -#else +#else /* CONFIG_PPC64 */ DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); - /* 288 = # of volatile regs, int & fp, for leaf routines */ /* which do not stack a frame. See the PPC64 ABI. */ DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288); -#endif - /* in fact we only use gpr0 - gpr9 and gpr20 - gpr23 */ + /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ + DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); + DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); +#endif /* CONFIG_PPC64 */ DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0])); DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1])); DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2])); @@ -121,6 +178,7 @@ int main(void) DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11])); DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12])); DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13])); +#ifndef CONFIG_PPC64 DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14])); DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15])); DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16])); @@ -139,6 +197,7 @@ int main(void) DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29])); DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30])); DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31])); +#endif /* CONFIG_PPC64 */ /* * Note: these symbols include _ because they overlap with special * register names @@ -148,23 +207,37 @@ int main(void) DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr)); DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link)); DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr)); - DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq)); DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer)); DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); - /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR - * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs - * for such processors. For critical interrupts we use them to - * hold SRR0 and SRR1. + DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); + DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); +#ifndef CONFIG_PPC64 + DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq)); + /* + * The PowerPC 400-class & Book-E processors have neither the DAR + * nor the DSISR SPRs. Hence, we overload them to hold the similar + * DEAR and ESR SPRs for such processors. For critical interrupts + * we use them to hold SRR0 and SRR1. */ DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); - DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); - DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); +#else /* CONFIG_PPC64 */ + DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); + DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe)); + + /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */ + DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)); + DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8); +#endif /* CONFIG_PPC64 */ + DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); + +#ifndef CONFIG_PPC64 DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); +#endif /* ! CONFIG_PPC64 */ /* About the CPU features table */ DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); @@ -173,66 +246,13 @@ int main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); -#ifdef CONFIG_PPC64 - DEFINE(MM, offsetof(struct task_struct, mm)); - DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); - - DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); - DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size)); - DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page)); - DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); - DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); - DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); - DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); - - /* paca */ - DEFINE(PACA_SIZE, sizeof(struct paca_struct)); - DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); - DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start)); - DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack)); - DEFINE(PACACURRENT, offsetof(struct paca_struct, __current)); - DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr)); - DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real)); - DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr)); - DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); - DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); - DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); - DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); - DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); - DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); - DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); -#ifdef CONFIG_HUGETLB_PAGE - DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); - DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); -#endif /* CONFIG_HUGETLB_PAGE */ - DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr)); - DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); - DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); - DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); - DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi)); - DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); - DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); - DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); - DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); - DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); - DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); - DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); - - /* RTAS */ - DEFINE(RTASBASE, offsetof(struct rtas_t, base)); - DEFINE(RTASENTRY, offsetof(struct rtas_t, entry)); - - DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); - DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe)); - - /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ - DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); - DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); - - /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */ - DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)); - DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8); +#ifndef CONFIG_PPC64 + DEFINE(pbe_address, offsetof(struct pbe, address)); + DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); + DEFINE(pbe_next, offsetof(struct pbe, next)); + DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); +#else /* CONFIG_PPC64 */ /* systemcfg offsets for use by vdso */ DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp)); DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec)); @@ -251,12 +271,6 @@ int main(void) DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); -#endif - - DEFINE(pbe_address, offsetof(struct pbe, address)); - DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); - DEFINE(pbe_next, offsetof(struct pbe, next)); - - DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); +#endif /* CONFIG_PPC64 */ return 0; } From dcff1b170b43d9b8cb83e275cb3451dfd261c23e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Sep 2005 00:59:39 +1000 Subject: [PATCH 0177/1940] powerpc: remove old vector.S files Update old kernel/Makefiles to cope Signed-off-by: Stephen Rothwell --- arch/ppc/kernel/Makefile | 1 + arch/ppc/kernel/vector.S | 217 ------------------------------------- arch/ppc64/kernel/Makefile | 1 + arch/ppc64/kernel/vector.S | 172 ----------------------------- 4 files changed, 2 insertions(+), 389 deletions(-) delete mode 100644 arch/ppc/kernel/vector.S delete mode 100644 arch/ppc64/kernel/vector.S diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 467f96480355..09067fe5772c 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -38,6 +38,7 @@ endif # These are here while we do the architecture merge vecemu-y += ../../powerpc/kernel/vecemu.o +vector-y += ../../powerpc/kernel/vector.o else obj-y := entry.o irq.o idle.o time.o misc.o \ diff --git a/arch/ppc/kernel/vector.S b/arch/ppc/kernel/vector.S deleted file mode 100644 index 82a21346bf80..000000000000 --- a/arch/ppc/kernel/vector.S +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include - -/* - * The routines below are in assembler so we can closely control the - * usage of floating-point registers. These routines must be called - * with preempt disabled. - */ - .data -fpzero: - .long 0 -fpone: - .long 0x3f800000 /* 1.0 in single-precision FP */ -fphalf: - .long 0x3f000000 /* 0.5 in single-precision FP */ - - .text -/* - * Internal routine to enable floating point and set FPSCR to 0. - * Don't call it from C; it doesn't use the normal calling convention. - */ -fpenable: - mfmsr r10 - ori r11,r10,MSR_FP - mtmsr r11 - isync - stfd fr0,24(r1) - stfd fr1,16(r1) - stfd fr31,8(r1) - lis r11,fpzero@ha - mffs fr31 - lfs fr1,fpzero@l(r11) - mtfsf 0xff,fr1 - blr - -fpdisable: - mtfsf 0xff,fr31 - lfd fr31,8(r1) - lfd fr1,16(r1) - lfd fr0,24(r1) - mtmsr r10 - isync - blr - -/* - * Vector add, floating point. - */ - .globl vaddfp -vaddfp: - stwu r1,-32(r1) - mflr r0 - stw r0,36(r1) - bl fpenable - li r0,4 - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - lfsx fr1,r5,r6 - fadds fr0,fr0,fr1 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - bl fpdisable - lwz r0,36(r1) - mtlr r0 - addi r1,r1,32 - blr - -/* - * Vector subtract, floating point. - */ - .globl vsubfp -vsubfp: - stwu r1,-32(r1) - mflr r0 - stw r0,36(r1) - bl fpenable - li r0,4 - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - lfsx fr1,r5,r6 - fsubs fr0,fr0,fr1 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - bl fpdisable - lwz r0,36(r1) - mtlr r0 - addi r1,r1,32 - blr - -/* - * Vector multiply and add, floating point. - */ - .globl vmaddfp -vmaddfp: - stwu r1,-48(r1) - mflr r0 - stw r0,52(r1) - bl fpenable - stfd fr2,32(r1) - li r0,4 - mtctr r0 - li r7,0 -1: lfsx fr0,r4,r7 - lfsx fr1,r5,r7 - lfsx fr2,r6,r7 - fmadds fr0,fr0,fr2,fr1 - stfsx fr0,r3,r7 - addi r7,r7,4 - bdnz 1b - lfd fr2,32(r1) - bl fpdisable - lwz r0,52(r1) - mtlr r0 - addi r1,r1,48 - blr - -/* - * Vector negative multiply and subtract, floating point. - */ - .globl vnmsubfp -vnmsubfp: - stwu r1,-48(r1) - mflr r0 - stw r0,52(r1) - bl fpenable - stfd fr2,32(r1) - li r0,4 - mtctr r0 - li r7,0 -1: lfsx fr0,r4,r7 - lfsx fr1,r5,r7 - lfsx fr2,r6,r7 - fnmsubs fr0,fr0,fr2,fr1 - stfsx fr0,r3,r7 - addi r7,r7,4 - bdnz 1b - lfd fr2,32(r1) - bl fpdisable - lwz r0,52(r1) - mtlr r0 - addi r1,r1,48 - blr - -/* - * Vector reciprocal estimate. We just compute 1.0/x. - * r3 -> destination, r4 -> source. - */ - .globl vrefp -vrefp: - stwu r1,-32(r1) - mflr r0 - stw r0,36(r1) - bl fpenable - lis r9,fpone@ha - li r0,4 - lfs fr1,fpone@l(r9) - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - fdivs fr0,fr1,fr0 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - bl fpdisable - lwz r0,36(r1) - mtlr r0 - addi r1,r1,32 - blr - -/* - * Vector reciprocal square-root estimate, floating point. - * We use the frsqrte instruction for the initial estimate followed - * by 2 iterations of Newton-Raphson to get sufficient accuracy. - * r3 -> destination, r4 -> source. - */ - .globl vrsqrtefp -vrsqrtefp: - stwu r1,-48(r1) - mflr r0 - stw r0,52(r1) - bl fpenable - stfd fr2,32(r1) - stfd fr3,40(r1) - stfd fr4,48(r1) - stfd fr5,56(r1) - lis r9,fpone@ha - lis r8,fphalf@ha - li r0,4 - lfs fr4,fpone@l(r9) - lfs fr5,fphalf@l(r8) - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - frsqrte fr1,fr0 /* r = frsqrte(s) */ - fmuls fr3,fr1,fr0 /* r * s */ - fmuls fr2,fr1,fr5 /* r * 0.5 */ - fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ - fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ - fmuls fr3,fr1,fr0 /* r * s */ - fmuls fr2,fr1,fr5 /* r * 0.5 */ - fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ - fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ - stfsx fr1,r3,r6 - addi r6,r6,4 - bdnz 1b - lfd fr5,56(r1) - lfd fr4,48(r1) - lfd fr3,40(r1) - lfd fr2,32(r1) - bl fpdisable - lwz r0,36(r1) - mtlr r0 - addi r1,r1,32 - blr diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index bb5946b88b8b..9d4836fe3720 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -76,3 +76,4 @@ endif # These are here while we do the architecture merge vecemu-y += ../../powerpc/kernel/vecemu.o +vector-y += ../../powerpc/kernel/vector.o diff --git a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S deleted file mode 100644 index b79d33e4001e..000000000000 --- a/arch/ppc64/kernel/vector.S +++ /dev/null @@ -1,172 +0,0 @@ -#include -#include - -/* - * The routines below are in assembler so we can closely control the - * usage of floating-point registers. These routines must be called - * with preempt disabled. - */ - .section ".toc","aw" -fpzero: - .tc FD_0_0[TC],0 -fpone: - .tc FD_3ff00000_0[TC],0x3ff0000000000000 /* 1.0 */ -fphalf: - .tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */ - - .text -/* - * Internal routine to enable floating point and set FPSCR to 0. - * Don't call it from C; it doesn't use the normal calling convention. - */ -fpenable: - mfmsr r10 - ori r11,r10,MSR_FP - mtmsr r11 - isync - stfd fr31,-8(r1) - stfd fr0,-16(r1) - stfd fr1,-24(r1) - mffs fr31 - lfd fr1,fpzero@toc(r2) - mtfsf 0xff,fr1 - blr - -fpdisable: - mtlr r12 - mtfsf 0xff,fr31 - lfd fr1,-24(r1) - lfd fr0,-16(r1) - lfd fr31,-8(r1) - mtmsr r10 - isync - blr - -/* - * Vector add, floating point. - */ -_GLOBAL(vaddfp) - mflr r12 - bl fpenable - li r0,4 - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - lfsx fr1,r5,r6 - fadds fr0,fr0,fr1 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - b fpdisable - -/* - * Vector subtract, floating point. - */ -_GLOBAL(vsubfp) - mflr r12 - bl fpenable - li r0,4 - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - lfsx fr1,r5,r6 - fsubs fr0,fr0,fr1 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - b fpdisable - -/* - * Vector multiply and add, floating point. - */ -_GLOBAL(vmaddfp) - mflr r12 - bl fpenable - stfd fr2,-32(r1) - li r0,4 - mtctr r0 - li r7,0 -1: lfsx fr0,r4,r7 - lfsx fr1,r5,r7 - lfsx fr2,r6,r7 - fmadds fr0,fr0,fr2,fr1 - stfsx fr0,r3,r7 - addi r7,r7,4 - bdnz 1b - lfd fr2,-32(r1) - b fpdisable - -/* - * Vector negative multiply and subtract, floating point. - */ -_GLOBAL(vnmsubfp) - mflr r12 - bl fpenable - stfd fr2,-32(r1) - li r0,4 - mtctr r0 - li r7,0 -1: lfsx fr0,r4,r7 - lfsx fr1,r5,r7 - lfsx fr2,r6,r7 - fnmsubs fr0,fr0,fr2,fr1 - stfsx fr0,r3,r7 - addi r7,r7,4 - bdnz 1b - lfd fr2,-32(r1) - b fpdisable - -/* - * Vector reciprocal estimate. We just compute 1.0/x. - * r3 -> destination, r4 -> source. - */ -_GLOBAL(vrefp) - mflr r12 - bl fpenable - li r0,4 - lfd fr1,fpone@toc(r2) - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - fdivs fr0,fr1,fr0 - stfsx fr0,r3,r6 - addi r6,r6,4 - bdnz 1b - b fpdisable - -/* - * Vector reciprocal square-root estimate, floating point. - * We use the frsqrte instruction for the initial estimate followed - * by 2 iterations of Newton-Raphson to get sufficient accuracy. - * r3 -> destination, r4 -> source. - */ -_GLOBAL(vrsqrtefp) - mflr r12 - bl fpenable - stfd fr2,-32(r1) - stfd fr3,-40(r1) - stfd fr4,-48(r1) - stfd fr5,-56(r1) - li r0,4 - lfd fr4,fpone@toc(r2) - lfd fr5,fphalf@toc(r2) - mtctr r0 - li r6,0 -1: lfsx fr0,r4,r6 - frsqrte fr1,fr0 /* r = frsqrte(s) */ - fmuls fr3,fr1,fr0 /* r * s */ - fmuls fr2,fr1,fr5 /* r * 0.5 */ - fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ - fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ - fmuls fr3,fr1,fr0 /* r * s */ - fmuls fr2,fr1,fr5 /* r * 0.5 */ - fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ - fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ - stfsx fr1,r3,r6 - addi r6,r6,4 - bdnz 1b - lfd fr5,-56(r1) - lfd fr4,-48(r1) - lfd fr3,-40(r1) - lfd fr2,-32(r1) - b fpdisable From ee400b63f37120987bd12a2fada850c6212d7563 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Sep 2005 11:50:22 +1000 Subject: [PATCH 0178/1940] powerpc: more cleanup of powerpc/kernel Update head_64.S from arch/ppc64 Remove arc/ppc/kernel/fpu.S Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/head_64.S | 9 ++- arch/ppc/kernel/Makefile | 1 + arch/ppc/kernel/fpu.S | 133 ---------------------------------- 3 files changed, 7 insertions(+), 136 deletions(-) delete mode 100644 arch/ppc/kernel/fpu.S diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 22a5ee07e1ea..db0cd3587627 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1253,7 +1253,7 @@ unrecov_slb: * * On iSeries, the hypervisor must fill in at least one entry before * we get control (with relocate on). The address is give to the hv - * as a page number (see xLparMap in LparData.c), so this must be at a + * as a page number (see xLparMap in lpardata.c), so this must be at a * fixed address (the linker can't compute (u64)&initial_stab >> * PAGE_SHIFT). */ @@ -1364,6 +1364,7 @@ _STATIC(__start_initialization_iSeries) addi r2,r2,0x4000 bl .iSeries_early_setup + bl .early_setup /* relocation is on at this point */ @@ -1970,20 +1971,22 @@ _GLOBAL(hmt_start_secondary) blr #endif -#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) +#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP) _GLOBAL(smp_release_cpus) /* All secondary cpus are spinning on a common * spinloop, release them all now so they can start * to spin on their individual paca spinloops. * For non SMP kernels, the secondary cpus never * get out of the common spinloop. + * XXX This does nothing useful on iSeries, secondaries are + * already waiting on their paca. */ li r3,1 LOADADDR(r5,__secondary_hold_spinloop) std r3,0(r5) sync blr -#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */ +#endif /* CONFIG_SMP */ /* diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 09067fe5772c..da2dc08c4c1b 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -39,6 +39,7 @@ endif # These are here while we do the architecture merge vecemu-y += ../../powerpc/kernel/vecemu.o vector-y += ../../powerpc/kernel/vector.o +fpu-y += ../../powerpc/kernel/fpu.o else obj-y := entry.o irq.o idle.o time.o misc.o \ diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S deleted file mode 100644 index 665d7d34304c..000000000000 --- a/arch/ppc/kernel/fpu.S +++ /dev/null @@ -1,133 +0,0 @@ -/* - * FPU support code, moved here from head.S so that it can be used - * by chips which use other head-whatever.S files. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This task wants to use the FPU now. - * On UP, disable FP for the task which had the FPU previously, - * and save its floating-point registers in its thread_struct. - * Load up this task's FP registers from its thread_struct, - * enable the FPU for the current task and return to the task. - */ - .globl load_up_fpu -load_up_fpu: - mfmsr r5 - ori r5,r5,MSR_FP -#ifdef CONFIG_PPC64BRIDGE - clrldi r5,r5,1 /* turn off 64-bit mode */ -#endif /* CONFIG_PPC64BRIDGE */ - SYNC - MTMSRD(r5) /* enable use of fpu now */ - isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - */ -#ifndef CONFIG_SMP - tophys(r6,0) /* get __pa constant */ - addis r3,r6,last_task_used_math@ha - lwz r4,last_task_used_math@l(r3) - cmpwi 0,r4,0 - beq 1f - add r4,r4,r6 - addi r4,r4,THREAD /* want last_task_used_math->thread */ - SAVE_32FPRS(0, r4) - mffs fr0 - stfd fr0,THREAD_FPSCR-4(r4) - lwz r5,PT_REGS(r4) - add r5,r5,r6 - lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r10,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r10 /* disable FP for previous task */ - stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* enable use of FP after return */ - mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ - lwz r4,THREAD_FPEXC_MODE(r5) - ori r9,r9,MSR_FP /* enable FP for current */ - or r9,r9,r4 - lfd fr0,THREAD_FPSCR-4(r5) - mtfsf 0xff,fr0 - REST_32FPRS(0, r5) -#ifndef CONFIG_SMP - subi r4,r5,THREAD - sub r4,r4,r6 - stw r4,last_task_used_math@l(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - /* we haven't used ctr or xer or lr */ - b fast_exception_return - -/* - * FP unavailable trap from kernel - print a message, but let - * the task use FP in the kernel until it returns to user mode. - */ - .globl KernelFP -KernelFP: - lwz r3,_MSR(r1) - ori r3,r3,MSR_FP - stw r3,_MSR(r1) /* enable use of FP after return */ - lis r3,86f@h - ori r3,r3,86f@l - mr r4,r2 /* current */ - lwz r5,_NIP(r1) - bl printk - b ret_from_except -86: .string "floating point used in kernel (task=%p, pc=%x)\n" - .align 4,0 - -/* - * giveup_fpu(tsk) - * Disable FP for the task given as the argument, - * and save the floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - */ - .globl giveup_fpu -giveup_fpu: - mfmsr r5 - ori r5,r5,MSR_FP - SYNC_601 - ISYNC_601 - MTMSRD(r5) /* enable use of fpu now */ - SYNC_601 - isync - cmpwi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - lwz r5,PT_REGS(r3) - cmpwi 0,r5,0 - SAVE_32FPRS(0, r3) - mffs fr0 - stfd fr0,THREAD_FPSCR-4(r3) - beq 1f - lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r3,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r3 /* disable FP for previous task */ - stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - lis r4,last_task_used_math@ha - stw r5,last_task_used_math@l(r4) -#endif /* CONFIG_SMP */ - blr From d96024c688b59d4d1e60dbb0e226964eb758aa01 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Sep 2005 01:46:29 +1000 Subject: [PATCH 0179/1940] powerpc: Move lparmap.c to powerpc/platforms Signed-off-by: Stephen Rothwell --- arch/{ppc64/kernel => powerpc/platforms/iseries}/lparmap.c | 0 arch/ppc64/kernel/Makefile | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename arch/{ppc64/kernel => powerpc/platforms/iseries}/lparmap.c (100%) diff --git a/arch/ppc64/kernel/lparmap.c b/arch/powerpc/platforms/iseries/lparmap.c similarity index 100% rename from arch/ppc64/kernel/lparmap.c rename to arch/powerpc/platforms/iseries/lparmap.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 9d4836fe3720..16e34de34178 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -70,8 +70,8 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ ifeq ($(CONFIG_PPC_ISERIES),y) -arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s -AFLAGS_head.o += -Iarch/ppc64/kernel +arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s +AFLAGS_head.o += -Iarch/powerpc/platforms/iseries endif # These are here while we do the architecture merge From b3a83639895a422b25f72eec0a5d1d88c3ac4e9e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 Sep 2005 18:37:36 +1000 Subject: [PATCH 0180/1940] drm: fix all sparse warning on 32-bit x86 Finally cleaned up the sparse warnings for the drm. Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 6 +++--- drivers/char/drm/drm_context.c | 4 ++-- drivers/char/drm/i810_drv.c | 3 --- drivers/char/drm/i810_drv.h | 3 +++ drivers/char/drm/i830_drv.c | 3 --- drivers/char/drm/i830_drv.h | 16 +++++++--------- drivers/char/drm/i915_drv.c | 3 --- drivers/char/drm/i915_drv.h | 3 +++ drivers/char/drm/mga_drv.c | 5 +---- drivers/char/drm/mga_drv.h | 3 +++ drivers/char/drm/r128_drv.c | 3 --- drivers/char/drm/r128_drv.h | 3 +++ drivers/char/drm/r300_cmdbuf.c | 34 ++++++++++++++++----------------- drivers/char/drm/radeon_drv.c | 3 --- drivers/char/drm/radeon_drv.h | 12 +++++++++++- drivers/char/drm/radeon_state.c | 23 +++++++++++----------- drivers/char/drm/savage_drv.c | 3 --- drivers/char/drm/savage_drv.h | 3 +++ drivers/char/drm/savage_state.c | 6 ++---- drivers/char/drm/sis_drv.c | 3 --- drivers/char/drm/sis_drv.h | 3 +++ drivers/char/drm/via_drv.h | 3 +++ 22 files changed, 75 insertions(+), 73 deletions(-) diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index e3d372ad0076..58e513a44740 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -117,9 +117,9 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where * applicable and if supported by the kernel. */ -int drm_addmap_core(drm_device_t * dev, unsigned int offset, - unsigned int size, drm_map_type_t type, - drm_map_flags_t flags, drm_map_list_t ** maplist) +static int drm_addmap_core(drm_device_t * dev, unsigned int offset, + unsigned int size, drm_map_type_t type, + drm_map_flags_t flags, drm_map_list_t ** maplist) { drm_map_t *map; drm_map_list_t *list; diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c index 6380127be281..bdd168d88f49 100644 --- a/drivers/char/drm/drm_context.c +++ b/drivers/char/drm/drm_context.c @@ -232,7 +232,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp, map = dev->context_sareas[request.ctx_id]; up(&dev->struct_sem); - request.handle = 0; + request.handle = NULL; list_for_each_entry(_entry, &dev->maplist->head, head) { if (_entry->map == map) { request.handle = @@ -240,7 +240,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp, break; } } - if (request.handle == 0) + if (request.handle == NULL) return -EINVAL; if (copy_to_user(argp, &request, sizeof(request))) diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c index 327e2f1cc997..070cef6c2b46 100644 --- a/drivers/char/drm/i810_drv.c +++ b/drivers/char/drm/i810_drv.c @@ -74,9 +74,6 @@ static struct pci_device_id pciidlist[] = { i810_PCI_IDS }; -extern drm_ioctl_desc_t i810_ioctls[]; -extern int i810_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h index 2d6b594afa0d..c78f36aaa2f0 100644 --- a/drivers/char/drm/i810_drv.h +++ b/drivers/char/drm/i810_drv.h @@ -121,6 +121,9 @@ extern void i810_driver_pretakedown(drm_device_t * dev); extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i810_driver_device_is_agp(drm_device_t * dev); +extern drm_ioctl_desc_t i810_ioctls[]; +extern int i810_max_ioctl; + #define I810_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) #define I810_ADDR(reg) (I810_BASE(reg) + reg) diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c index 6dad356450bc..acd821e8fe4d 100644 --- a/drivers/char/drm/i830_drv.c +++ b/drivers/char/drm/i830_drv.c @@ -75,9 +75,6 @@ static struct pci_device_id pciidlist[] = { i830_PCI_IDS }; -extern drm_ioctl_desc_t i830_ioctls[]; -extern int i830_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index 99835465c44b..bc4bd49fb0cc 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h @@ -120,6 +120,9 @@ typedef struct drm_i830_private { } drm_i830_private_t; +extern drm_ioctl_desc_t i830_ioctls[]; +extern int i830_max_ioctl; + /* i830_dma.c */ extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp); @@ -139,15 +142,10 @@ extern int i830_driver_dma_quiescent(drm_device_t * dev); extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i830_driver_device_is_agp(drm_device_t * dev); -#define I830_BASE(reg) ((unsigned long) \ - dev_priv->mmio_map->handle) -#define I830_ADDR(reg) (I830_BASE(reg) + reg) -#define I830_DEREF(reg) *(__volatile__ unsigned int *)I830_ADDR(reg) -#define I830_READ(reg) readl((volatile u32 *)I830_ADDR(reg)) -#define I830_WRITE(reg,val) writel(val, (volatile u32 *)I830_ADDR(reg)) -#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg) -#define I830_READ16(reg) I830_DEREF16(reg) -#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) +#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) +#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) +#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) +#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) #define I830_VERBOSE 0 diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 665da6ac11c6..0508240f4e3b 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -69,9 +69,6 @@ static struct pci_device_id pciidlist[] = { i915_PCI_IDS }; -extern drm_ioctl_desc_t i915_ioctls[]; -extern int i915_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 511ef1d87637..17e457c73dc7 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -99,6 +99,9 @@ typedef struct drm_i915_private { struct mem_block *agp_heap; } drm_i915_private_t; +extern drm_ioctl_desc_t i915_ioctls[]; +extern int i915_max_ioctl; + /* i915_dma.c */ extern void i915_kernel_lost_context(drm_device_t * dev); extern void i915_driver_pretakedown(drm_device_t * dev); diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 220037a91c09..0cc7c305a7f6 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -78,9 +78,6 @@ static struct pci_device_id pciidlist[] = { mga_PCI_IDS }; -extern drm_ioctl_desc_t mga_ioctls[]; -extern int mga_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | @@ -151,7 +148,7 @@ MODULE_LICENSE("GPL and additional rights"); * \returns * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. */ -int mga_driver_device_is_agp(drm_device_t * dev) +static int mga_driver_device_is_agp(drm_device_t * dev) { const struct pci_dev *const pdev = dev->pdev; diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index 05f0f913dedd..474853deecfa 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h @@ -148,6 +148,9 @@ typedef struct drm_mga_private { unsigned int agp_pages; } drm_mga_private_t; +extern drm_ioctl_desc_t mga_ioctls[]; +extern int mga_max_ioctl; + /* mga_dma.c */ extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags); extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 4d9224645f04..1661e7351402 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -66,9 +66,6 @@ static struct pci_device_id pciidlist[] = { r128_PCI_IDS }; -extern drm_ioctl_desc_t r128_ioctls[]; -extern int r128_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 87c5e1381ba2..5c79e40eb88f 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h @@ -128,6 +128,9 @@ typedef struct drm_r128_buf_priv { drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; +extern drm_ioctl_desc_t r128_ioctls[]; +extern int r128_max_ioctl; + /* r128_cce.c */ extern int r128_cce_init(DRM_IOCTL_ARGS); extern int r128_cce_start(DRM_IOCTL_ARGS); diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index aa66f46279e7..3a1ac5f78b43 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c @@ -53,7 +53,7 @@ static const int r300_cliprect_cntl[4] = { * buffer, starting with index n. */ static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf, int n) + drm_radeon_kcmd_buffer_t * cmdbuf, int n) { drm_clip_rect_t box; int nr; @@ -131,7 +131,7 @@ static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, return 0; } -u8 r300_reg_flags[0x10000 >> 2]; +static u8 r300_reg_flags[0x10000 >> 2]; void r300_init_reg_flags(void) { @@ -260,7 +260,7 @@ static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv, static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) @@ -281,7 +281,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * return DRM_ERR(EINVAL); } for (i = 0; i < sz; i++) { - values[i] = ((int __user *)cmdbuf->buf)[i]; + values[i] = ((int *)cmdbuf->buf)[i]; switch (r300_reg_flags[(reg >> 2) + i]) { case MARK_SAFE: break; @@ -318,7 +318,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * * Note that checks are performed on contents and addresses of the registers */ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int reg; @@ -349,7 +349,7 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, BEGIN_RING(1 + sz); OUT_RING(CP_PACKET0(reg, sz - 1)); - OUT_RING_TABLE((int __user *)cmdbuf->buf, sz); + OUT_RING_TABLE((int *)cmdbuf->buf, sz); ADVANCE_RING(); cmdbuf->buf += sz * 4; @@ -364,7 +364,7 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, * Called by r300_do_cp_cmdbuf. */ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int sz; @@ -386,7 +386,7 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0); OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); - OUT_RING_TABLE((int __user *)cmdbuf->buf, sz * 4); + OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4); ADVANCE_RING(); @@ -401,7 +401,7 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, * Called by r300_emit_packet3. */ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { RING_LOCALS; @@ -412,7 +412,7 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | (1 << R300_PRIM_NUM_VERTICES_SHIFT)); - OUT_RING_TABLE((int __user *)cmdbuf->buf, 8); + OUT_RING_TABLE((int *)cmdbuf->buf, 8); ADVANCE_RING(); cmdbuf->buf += 8 * 4; @@ -422,7 +422,7 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, } static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf, + drm_radeon_kcmd_buffer_t * cmdbuf, u32 header) { int count, i, k; @@ -490,7 +490,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, } static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { u32 header; int count; @@ -503,7 +503,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, We need to be smarter. */ /* obtain first word - actual packet3 header */ - header = *(u32 __user *) cmdbuf->buf; + header = *(u32 *) cmdbuf->buf; /* Is it packet 3 ? */ if ((header >> 30) != 0x3) { @@ -541,7 +541,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, BEGIN_RING(count + 2); OUT_RING(header); - OUT_RING_TABLE((int __user *)(cmdbuf->buf + 4), count + 1); + OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); ADVANCE_RING(); cmdbuf->buf += (count + 2) * 4; @@ -555,12 +555,12 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, * Called by r300_do_cp_cmdbuf. */ static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, - drm_radeon_cmd_buffer_t * cmdbuf, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int n; int ret; - char __user *orig_buf = cmdbuf->buf; + char *orig_buf = cmdbuf->buf; int orig_bufsz = cmdbuf->bufsz; /* This is a do-while-loop so that we run the interior at least once, @@ -659,7 +659,7 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) */ int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, - drm_file_t * filp_priv, drm_radeon_cmd_buffer_t * cmdbuf) + drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index 7074d01ed1dd..ee49670d8162 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c @@ -71,9 +71,6 @@ static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -extern drm_ioctl_desc_t radeon_ioctls[]; -extern int radeon_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 3c7473488665..120ee5a8ebcc 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -281,7 +281,17 @@ typedef struct drm_radeon_buf_priv { u32 age; } drm_radeon_buf_priv_t; +typedef struct drm_radeon_kcmd_buffer { + int bufsz; + char *buf; + int nbox; + drm_clip_rect_t __user *boxes; +} drm_radeon_kcmd_buffer_t; + extern int radeon_no_wb; +extern drm_ioctl_desc_t radeon_ioctls[]; +extern int radeon_max_ioctl; + /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); @@ -340,7 +350,7 @@ extern void r300_init_reg_flags(void); extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, drm_file_t * filp_priv, - drm_radeon_cmd_buffer_t * cmdbuf); + drm_radeon_kcmd_buffer_t * cmdbuf); /* Flags for stats.boxes */ diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 2eae60bd340f..231ac1438c69 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -40,7 +40,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * dev_priv, drm_file_t * filp_priv, - u32 * offset) + u32 *offset) { u32 off = *offset; struct drm_radeon_driver_file_fields *radeon_priv; @@ -66,7 +66,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * dev_priv, drm_file_t * filp_priv, - int id, u32 __user * data) + int id, u32 *data) { switch (id) { @@ -240,8 +240,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * dev_priv, drm_file_t * filp_priv, - drm_radeon_cmd_buffer_t * - cmdbuf, + drm_radeon_kcmd_buffer_t *cmdbuf, unsigned int *cmdsz) { u32 *cmd = (u32 *) cmdbuf->buf; @@ -2564,7 +2563,7 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) static int radeon_emit_packets(drm_radeon_private_t * dev_priv, drm_file_t * filp_priv, drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t *cmdbuf) { int id = (int)header.packet.packet_id; int sz, reg; @@ -2599,7 +2598,7 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = header.scalars.offset; @@ -2621,7 +2620,7 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, */ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = ((unsigned int)header.scalars.offset) + 0x100; @@ -2641,7 +2640,7 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.vectors.count; int start = header.vectors.offset; @@ -2662,7 +2661,7 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, static int radeon_emit_packet3(drm_device_t * dev, drm_file_t * filp_priv, - drm_radeon_cmd_buffer_t * cmdbuf) + drm_radeon_kcmd_buffer_t *cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int cmdsz; @@ -2688,7 +2687,7 @@ static int radeon_emit_packet3(drm_device_t * dev, static int radeon_emit_packet3_cliprect(drm_device_t * dev, drm_file_t * filp_priv, - drm_radeon_cmd_buffer_t * cmdbuf, + drm_radeon_kcmd_buffer_t *cmdbuf, int orig_nbox) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2785,7 +2784,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) drm_device_dma_t *dma = dev->dma; drm_buf_t *buf = NULL; int idx; - drm_radeon_cmd_buffer_t cmdbuf; + drm_radeon_kcmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; int orig_nbox, orig_bufsz; char *kbuf = NULL; @@ -2819,7 +2818,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); if (kbuf == NULL) return DRM_ERR(ENOMEM); - if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) { + if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) { drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); return DRM_ERR(EFAULT); } diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c index 0906f9a5d8f9..22d799cde41c 100644 --- a/drivers/char/drm/savage_drv.c +++ b/drivers/char/drm/savage_drv.c @@ -59,9 +59,6 @@ static struct pci_device_id pciidlist[] = { savage_PCI_IDS }; -extern drm_ioctl_desc_t savage_ioctls[]; -extern int savage_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h index 358f4fb2712a..a4b0fa998a95 100644 --- a/drivers/char/drm/savage_drv.h +++ b/drivers/char/drm/savage_drv.h @@ -104,6 +104,9 @@ enum savage_family { S3_LAST }; +extern drm_ioctl_desc_t savage_ioctls[]; +extern int savage_max_ioctl; + #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) #define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \ diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c index 39654cb5d570..e87a5d59b99c 100644 --- a/drivers/char/drm/savage_state.c +++ b/drivers/char/drm/savage_state.c @@ -816,10 +816,8 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, if (nbox == 0) return 0; - DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t *)data) - ->clear1.mask); - DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t *)data) - ->clear1.value); + DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask); + DRM_GET_USER_UNCHECKED(value, &data->clear1.value); clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c index 6d0cb2226005..3cef10643a8f 100644 --- a/drivers/char/drm/sis_drv.c +++ b/drivers/char/drm/sis_drv.c @@ -61,9 +61,6 @@ static struct pci_device_id pciidlist[] = { sisdrv_PCI_IDS }; -extern drm_ioctl_desc_t sis_ioctls[]; -extern int sis_max_ioctl; - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, .context_ctor = sis_init_context, diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h index 4ef3d6226418..b1fddad83a93 100644 --- a/drivers/char/drm/sis_drv.h +++ b/drivers/char/drm/sis_drv.h @@ -49,4 +49,7 @@ typedef struct drm_sis_private { extern int sis_init_context(drm_device_t * dev, int context); extern int sis_final_context(drm_device_t * dev, int context); +extern drm_ioctl_desc_t sis_ioctls[]; +extern int sis_max_ioctl; + #endif diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index d902dc2f4fae..7d5daf43797e 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h @@ -112,4 +112,7 @@ extern void via_init_futex(drm_via_private_t * dev_priv); extern void via_cleanup_futex(drm_via_private_t * dev_priv); extern void via_release_futex(drm_via_private_t * dev_priv, int context); +extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, + unsigned int size); + #endif From 3d5efad953c6d5ba11d5bcb584ef8e906f953a73 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 Sep 2005 19:12:46 +1000 Subject: [PATCH 0181/1940] drm: fix drm PCIGART PCI Express support broke PCIGART Signed-off-by: Dave Airlie --- drivers/char/drm/ati_pcigart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index d07ce96e9f4b..6d3fec160bff 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c @@ -205,7 +205,8 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) if (gart_info->is_pcie) *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; else - *pci_gart++ = cpu_to_le32(page_base); + *pci_gart = cpu_to_le32(page_base); + *pci_gart++; page_base += ATI_PCIGART_PAGE_SIZE; } } From c0c0d996d08e450164adedc249c1bbbca63524ce Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 1 Oct 2005 13:49:08 +1000 Subject: [PATCH 0182/1940] powerpc: Get merged kernel to compile and run on 32-bit SMP powermac. This updates the powermac SMP code to use the mpic driver instead of the openpic driver and fixes the SMP-dependent context switch code. We had a subtle bug where we were using interrupt numbers 256-259 for IPIs, but ppc32 had NR_IRQS = 256. Moved the IPIs down to use interrupt numbers 252-255 instead. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/ppc_ksyms.c | 2 -- arch/powerpc/kernel/process.c | 17 ++++++++++++----- arch/powerpc/platforms/powermac/pmac_pic.c | 7 ++++--- arch/powerpc/platforms/powermac/pmac_smp.c | 10 +++++----- arch/powerpc/sysdev/mpic.c | 3 +++ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 7bfa0f0121ff..e73b0699b5f0 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -182,11 +182,9 @@ EXPORT_SYMBOL(flush_tlb_kernel_range); EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(_tlbie); #ifdef CONFIG_ALTIVEC -EXPORT_SYMBOL(last_task_used_altivec); EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SPE -EXPORT_SYMBOL(last_task_used_spe); EXPORT_SYMBOL(giveup_spe); #endif /* CONFIG_SPE */ #ifdef CONFIG_SMP diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e3946769dd8e..ae316e9ed581 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -272,11 +272,6 @@ struct task_struct *__switch_to(struct task_struct *prev, */ if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) giveup_altivec(prev); - /* Avoid the trap. On smp this this never happens since - * we don't set last_task_used_altivec -- Cort - */ - if (new->thread.regs && last_task_used_altivec == new) - new->thread.regs->msr |= MSR_VEC; #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SPE /* @@ -288,12 +283,24 @@ struct task_struct *__switch_to(struct task_struct *prev, */ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) giveup_spe(prev); +#endif /* CONFIG_SPE */ + +#else /* CONFIG_SMP */ +#ifdef CONFIG_ALTIVEC + /* Avoid the trap. On smp this this never happens since + * we don't set last_task_used_altivec -- Cort + */ + if (new->thread.regs && last_task_used_altivec == new) + new->thread.regs->msr |= MSR_VEC; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE /* Avoid the trap. On smp this this never happens since * we don't set last_task_used_spe */ if (new->thread.regs && last_task_used_spe == new) new->thread.regs->msr |= MSR_SPE; #endif /* CONFIG_SPE */ + #endif /* CONFIG_SMP */ #ifdef CONFIG_PPC64 /* for now */ diff --git a/arch/powerpc/platforms/powermac/pmac_pic.c b/arch/powerpc/platforms/powermac/pmac_pic.c index a6b1b577e19f..7ddd5264cc6e 100644 --- a/arch/powerpc/platforms/powermac/pmac_pic.c +++ b/arch/powerpc/platforms/powermac/pmac_pic.c @@ -430,7 +430,7 @@ void __init pmac_pic_init(void) prom_get_irq_senses(senses, 0, 128); mpic1 = mpic_alloc(irqctrler->addrs[0].address, MPIC_PRIMARY | MPIC_WANTS_RESET, - 0, 0, 128, 256, senses, 128, " K2-MPIC "); + 0, 0, 128, 252, senses, 128, " OpenPIC "); BUG_ON(mpic1 == NULL); mpic_init(mpic1); @@ -441,14 +441,15 @@ void __init pmac_pic_init(void) irqctrler2->intrs[0].line); pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); - prom_get_irq_senses(senses, 128, 128 + 128); + prom_get_irq_senses(senses, 128, 128 + 124); /* We don't need to set MPIC_BROKEN_U3 here since we don't have * hypertransport interrupts routed to it */ mpic2 = mpic_alloc(irqctrler2->addrs[0].address, MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, - 0, 128, 128, 0, senses, 128, " U3-MPIC "); + 0, 128, 124, 0, senses, 124, + " U3-MPIC "); BUG_ON(mpic2 == NULL); mpic_init(mpic2); mpic_setup_cascade(irqctrler2->intrs[0].line, diff --git a/arch/powerpc/platforms/powermac/pmac_smp.c b/arch/powerpc/platforms/powermac/pmac_smp.c index 995e9095d865..fb996336c58b 100644 --- a/arch/powerpc/platforms/powermac/pmac_smp.c +++ b/arch/powerpc/platforms/powermac/pmac_smp.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include @@ -638,14 +638,14 @@ void smp_core99_message_pass(int target, int msg, unsigned long data, int wait) } switch (target) { case MSG_ALL: - mpic_send_ipi(msg, mask); + mpic_send_ipi(msg, cpus_addr(mask)[0]); break; case MSG_ALL_BUT_SELF: cpu_clear(smp_processor_id(), mask); - mpic_send_ipi(msg, mask); + mpic_send_ipi(msg, cpus_addr(mask)[0]); break; default: - mpic_send_ipi(msg, cpumask_of_cpu(target)); + mpic_send_ipi(msg, 1 << target); break; } } @@ -678,7 +678,7 @@ int __cpu_disable(void) cpu_clear(smp_processor_id(), cpu_online_map); /* XXX reset cpu affinity here */ - openpic_set_priority(0xf); + mpic_cpu_set_priority(0xf); asm volatile("mtdec %0" : : "r" (0x7fffffff)); mb(); udelay(20); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index c660e7d7c643..02b4d2488bfd 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -44,6 +44,9 @@ static struct mpic *mpics; static struct mpic *mpic_primary; static DEFINE_SPINLOCK(mpic_lock); +#ifdef CONFIG_PPC32 /* XXX for now */ +#define distribute_irqs CONFIG_IRQ_ALL_CPUS +#endif /* * Register accessor functions From dc1c1ca3dcd94c545c5e01d7c06b46824d43f4d0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Sat, 1 Oct 2005 18:43:42 +1000 Subject: [PATCH 0183/1940] powerpc: merge idle_power4.S and trapc.s Use idle_power4.S from ppc64 as we are not going to support 32 bit power4 in the merged tree. Merge ppc64 traps.c into powerpc traps.c: use ppc64 versions of exception routine names (as they don't have StudlyCaps) make all the versions if die() have the same prototype Signed-off-by: Stephen Rothwell --- arch/powerpc/Kconfig | 4 +- arch/powerpc/kernel/head.S | 84 +-- arch/powerpc/kernel/head_44x.S | 14 +- arch/powerpc/kernel/head_4xx.S | 52 +- arch/powerpc/kernel/head_8xx.S | 42 +- arch/powerpc/kernel/head_fsl_booke.S | 24 +- arch/{ppc64 => powerpc}/kernel/idle_power4.S | 5 +- arch/powerpc/kernel/ppc_ksyms.c | 16 +- arch/powerpc/kernel/traps.c | 407 +++++++++---- arch/ppc/kernel/head.S | 84 +-- arch/ppc/kernel/head_44x.S | 14 +- arch/ppc/kernel/head_4xx.S | 52 +- arch/ppc/kernel/head_8xx.S | 42 +- arch/ppc/kernel/head_booke.h | 4 +- arch/ppc/kernel/head_fsl_booke.S | 24 +- arch/ppc/kernel/ppc_ksyms.c | 16 +- arch/ppc/kernel/traps.c | 20 +- arch/ppc/syslib/ibm44x_common.c | 2 +- arch/ppc/syslib/ppc4xx_setup.c | 2 +- arch/ppc64/kernel/Makefile | 8 + arch/ppc64/kernel/traps.c | 568 ------------------- include/asm-ppc/system.h | 2 +- 22 files changed, 564 insertions(+), 922 deletions(-) rename arch/{ppc64 => powerpc}/kernel/idle_power4.S (98%) delete mode 100644 arch/ppc64/kernel/traps.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index edfac467b9e0..953a74be57b6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -142,8 +142,8 @@ config POWER4 def_bool y config PPC_FPU - bool - default y if PPC64 + depends on PPC32 + def_bool y config BOOKE bool diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S index 8cdac7385e7f..2c3a1d34e3c7 100644 --- a/arch/powerpc/kernel/head.S +++ b/arch/powerpc/kernel/head.S @@ -349,12 +349,12 @@ i##n: \ /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and - putting it back to what it was (UnknownException) when done. */ + putting it back to what it was (unknown_exception) when done. */ #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) . = 0x100 b __secondary_start_gemini #else - EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) + EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) #endif /* Machine check */ @@ -389,7 +389,7 @@ i##n: \ cmpwi cr1,r4,0 bne cr1,1f #endif - EXC_XFER_STD(0x200, MachineCheckException) + EXC_XFER_STD(0x200, machine_check_exception) #ifdef CONFIG_PPC_CHRP 1: b machine_check_in_rtas #endif @@ -456,10 +456,10 @@ Alignment: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* Program check exception */ - EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD) /* Floating-point unavailable */ . = 0x800 @@ -472,8 +472,8 @@ FPUnavailable: /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) - EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) - EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE) /* System call */ . = 0xc00 @@ -482,8 +482,8 @@ SystemCall: EXC_XFER_EE_LITE(0xc00, DoSyscall) /* Single step - not used on 601 */ - EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) - EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) + EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE) /* * The Altivec unavailable trap is at 0x0f20. Foo. @@ -502,7 +502,7 @@ SystemCall: Trap_0f: EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0xf00, UnknownException) + EXC_XFER_EE(0xf00, unknown_exception) /* * Handle TLB miss for instruction on 603/603e. @@ -702,44 +702,44 @@ DataStoreTLBMiss: rfi #ifndef CONFIG_ALTIVEC -#define AltivecAssistException UnknownException +#define altivec_assist_exception unknown_exception #endif - EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE) + EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) #ifdef CONFIG_POWER4 - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) #else /* !CONFIG_POWER4 */ - EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_POWER4 */ - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE) - EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE) + EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE) .globl mol_trampoline .set mol_trampoline, i0x2f00 @@ -751,7 +751,7 @@ AltiVecUnavailable: #ifdef CONFIG_ALTIVEC bne load_up_altivec /* if from user, just load it up */ #endif /* CONFIG_ALTIVEC */ - EXC_XFER_EE_LITE(0xf20, AltivecUnavailException) + EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) #ifdef CONFIG_PPC64BRIDGE DataAccess: @@ -767,12 +767,12 @@ DataSegment: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_DAR stw r4,_DAR(r11) - EXC_XFER_STD(0x380, UnknownException) + EXC_XFER_STD(0x380, unknown_exception) InstructionSegment: EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x480, UnknownException) + EXC_XFER_STD(0x480, unknown_exception) #endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 599245b0407e..b1b9dc08abca 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -309,13 +309,13 @@ skpinv: addi r4,r4,1 /* Increment */ interrupt_base: /* Critical Input Interrupt */ - CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ #ifdef CONFIG_440A - MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #else - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #endif /* Data Storage Interrupt */ @@ -442,7 +442,7 @@ interrupt_base: #ifdef CONFIG_PPC_FPU FP_UNAVAILABLE_EXCEPTION #else - EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) #endif /* System Call Interrupt */ @@ -451,21 +451,21 @@ interrupt_base: EXC_XFER_EE_LITE(0x0c00, DoSyscall) /* Auxillary Processor Unavailable Interrupt */ - EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ DECREMENTER_EXCEPTION /* Fixed Internal Timer Interrupt */ /* TODO: Add FIT support */ - EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ /* TODO: Add watchdog support */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) #else - CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception) #endif /* Data TLB Error Interrupt */ diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S index 8562b807b37c..5772ce97e24e 100644 --- a/arch/powerpc/kernel/head_4xx.S +++ b/arch/powerpc/kernel/head_4xx.S @@ -245,12 +245,12 @@ label: /* * 0x0100 - Critical Interrupt Exception */ - CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception) /* * 0x0200 - Machine Check Exception */ - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) /* * 0x0300 - Data Storage Exception @@ -405,7 +405,7 @@ label: mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ stw r4,_DEAR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* 0x0700 - Program Exception */ START_EXCEPTION(0x0700, ProgramCheck) @@ -413,21 +413,21 @@ label: mfspr r4,SPRN_ESR /* Grab the ESR and save it */ stw r4,_ESR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x700, ProgramCheckException) + EXC_XFER_STD(0x700, program_check_exception) - EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE) /* 0x0C00 - System Call Exception */ START_EXCEPTION(0x0C00, SystemCall) NORMAL_EXCEPTION_PROLOG EXC_XFER_EE_LITE(0xc00, DoSyscall) - EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE) /* 0x1000 - Programmable Interval Timer (PIT) Exception */ START_EXCEPTION(0x1000, Decrementer) @@ -444,14 +444,14 @@ label: /* 0x1010 - Fixed Interval Timer (FIT) Exception */ - STND_EXCEPTION(0x1010, FITException, UnknownException) + STND_EXCEPTION(0x1010, FITException, unknown_exception) /* 0x1020 - Watchdog Timer (WDT) Exception */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException) #else - CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException) + CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception) #endif #endif @@ -656,25 +656,25 @@ label: mfspr r10, SPRN_SPRG0 b InstructionAccess - EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) #ifdef CONFIG_IBM405_ERR51 /* 405GP errata 51 */ START_EXCEPTION(0x1700, Trap_17) b DTLBMiss #else - EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE) #endif - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE) /* Check for a single step debug exception while in an exception * handler before state has been saved. This is to catch the case diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index cb1a3a54a026..de0978742221 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -203,7 +203,7 @@ i##n: \ ret_from_except) /* System reset */ - EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) + EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) /* Machine check */ . = 0x200 @@ -214,7 +214,7 @@ MachineCheck: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x200, MachineCheckException) + EXC_XFER_STD(0x200, machine_check_exception) /* Data access exception. * This is "never generated" by the MPC8xx. We jump to it for other @@ -252,20 +252,20 @@ Alignment: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* Program check exception */ - EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD) /* No FPU on MPC8xx. This exception is not supposed to happen. */ - EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD) + EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD) /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) - EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) - EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE) /* System call */ . = 0xc00 @@ -274,9 +274,9 @@ SystemCall: EXC_XFER_EE_LITE(0xc00, DoSyscall) /* Single step - not used on 601 */ - EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) - EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) - EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE) + EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE) /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. @@ -540,22 +540,22 @@ DataTLBError: #endif b DataAccess - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) /* On the MPC8xx, these next four traps are used for development * support of breakpoints and such. Someday I will get around to * using them. */ - EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE) . = 0x2000 diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index eba5a5f8ff08..53949811efda 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -426,14 +426,14 @@ skpinv: addi r6,r6,1 /* Increment */ interrupt_base: /* Critical Input Interrupt */ - CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ #ifdef CONFIG_E200 /* no RFMCI, MCSRRs on E200 */ - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #else - MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #endif /* Data Storage Interrupt */ @@ -542,9 +542,9 @@ interrupt_base: #else #ifdef CONFIG_E200 /* E200 treats 'normal' floating point instructions as FP Unavail exception */ - EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE) + EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE) #else - EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) #endif #endif @@ -554,20 +554,20 @@ interrupt_base: EXC_XFER_EE_LITE(0x0c00, DoSyscall) /* Auxillary Processor Unavailable Interrupt */ - EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ DECREMENTER_EXCEPTION /* Fixed Internal Timer Interrupt */ /* TODO: Add FIT support */ - EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException) #else - CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) + CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception) #endif /* Data TLB Error Interrupt */ @@ -696,21 +696,21 @@ interrupt_base: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_EE_LITE(0x2010, KernelSPE) #else - EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_SPE */ /* SPE Floating Point Data */ #ifdef CONFIG_SPE EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); #else - EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_SPE */ /* SPE Floating Point Round */ - EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) /* Performance Monitor */ - EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD) + EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) /* Debug Interrupt */ diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S similarity index 98% rename from arch/ppc64/kernel/idle_power4.S rename to arch/powerpc/kernel/idle_power4.S index ca02afe2a795..5596fad6c87c 100644 --- a/arch/ppc64/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S @@ -63,8 +63,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) beq 1f mtmsrd r7 /* out of line this ? */ blr -1: - /* Go to NAP now */ +1: + /* Go to NAP now */ BEGIN_FTR_SECTION DSSALL sync @@ -76,4 +76,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) isync sync blr - diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 7bfa0f0121ff..07c994585c0b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -53,10 +53,10 @@ extern void transfer_to_handler(void); extern void do_IRQ(struct pt_regs *regs); -extern void MachineCheckException(struct pt_regs *regs); -extern void AlignmentException(struct pt_regs *regs); -extern void ProgramCheckException(struct pt_regs *regs); -extern void SingleStepException(struct pt_regs *regs); +extern void machine_check_exception(struct pt_regs *regs); +extern void alignment_exception(struct pt_regs *regs); +extern void program_check_exception(struct pt_regs *regs); +extern void single_step_exception(struct pt_regs *regs); extern int do_signal(sigset_t *, struct pt_regs *); extern int pmac_newworld; extern int sys_sigreturn(struct pt_regs *regs); @@ -72,10 +72,10 @@ EXPORT_SYMBOL(clear_user_page); EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); -EXPORT_SYMBOL(MachineCheckException); -EXPORT_SYMBOL(AlignmentException); -EXPORT_SYMBOL(ProgramCheckException); -EXPORT_SYMBOL(SingleStepException); +EXPORT_SYMBOL(machine_check_exception); +EXPORT_SYMBOL(alignment_exception); +EXPORT_SYMBOL(program_check_exception); +EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); EXPORT_SYMBOL(ppc_n_lost_interrupts); EXPORT_SYMBOL(ppc_lost_interrupts); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index c7afbbba0f36..37b961f1e279 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1,6 +1,4 @@ /* - * arch/powerpc/kernel/traps.c - * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * This program is free software; you can redistribute it and/or @@ -23,29 +21,46 @@ #include #include #include -#include #include #include #include #include -#include #include #include -#include #include #include #include +#ifdef CONFIG_PPC32 +#include +#include +#endif #include #include #include #include +#ifdef CONFIG_PPC32 #include #include #ifdef CONFIG_PMAC_BACKLIGHT #include #endif #include +#endif +#ifdef CONFIG_PPC64 +#include +#include +#include +#include +#include +#include +#endif + +#ifdef CONFIG_PPC64 +#define __KPROBES __kprobes +#else +#define __KPROBES +#endif #ifdef CONFIG_DEBUGGER int (*__debugger)(struct pt_regs *regs); @@ -96,7 +111,7 @@ int die(const char *str, struct pt_regs *regs, long err) console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); -#ifdef CONFIG_PMAC_BACKLIGHT +#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC_BACKLIGHT) if (_machine == _MACH_Pmac) { set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); @@ -154,9 +169,17 @@ int die(const char *str, struct pt_regs *regs, long err) panic("Fatal exception in interrupt"); if (panic_on_oops) { +#ifdef CONFIG_PPC64 + printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); + ssleep(5); +#endif panic("Fatal exception"); } +#ifdef CONFIG_PPC32 do_exit(err); +#else + do_exit(SIGSEGV); +#endif return 0; } @@ -176,6 +199,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) info.si_addr = (void __user *) addr; force_sig_info(signr, &info, current); +#ifdef CONFIG_PPC32 /* * Init gets no signals that it doesn't have a handler for. * That's all very well, but if it has caused a synchronous @@ -197,6 +221,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) do_exit(signr); } } +#endif } #ifdef CONFIG_PPC64 @@ -206,7 +231,7 @@ void system_reset_exception(struct pt_regs *regs) if (ppc_md.system_reset_exception) ppc_md.system_reset_exception(regs); - die("System Reset", regs, SIGABRT); + die("System Reset", regs, 0); /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) @@ -216,6 +241,7 @@ void system_reset_exception(struct pt_regs *regs) } #endif +#ifdef CONFIG_PPC32 /* * I/O accesses can cause machine checks on powermacs. * Check if the NIP corresponds to the address of a sync @@ -264,8 +290,10 @@ static inline int check_io_access(struct pt_regs *regs) #endif /* CONFIG_PPC_PMAC */ return 0; } +#endif /* CONFIG_PPC32 */ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* On 4xx, the reason for the machine check or program exception is in the ESR. */ #define get_reason(regs) ((regs)->dsisr) @@ -284,6 +312,7 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) #else + /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ #define get_reason(regs) ((regs)->msr) @@ -297,6 +326,7 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif +#ifdef CONFIG_PPC32 /* * This is "fall-back" implementation for configurations * which don't provide platform-specific machine check info @@ -305,8 +335,9 @@ void __attribute__ ((weak)) platform_machine_check(struct pt_regs *regs) { } +#endif -void MachineCheckException(struct pt_regs *regs) +void machine_check_exception(struct pt_regs *regs) { #ifdef CONFIG_PPC64 int recover = 0; @@ -462,23 +493,31 @@ void MachineCheckException(struct pt_regs *regs) * additional info, e.g. bus error registers. */ platform_machine_check(regs); -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC32 */ if (debugger_fault_handler(regs)) return; - die("Machine check", regs, SIGBUS); + die("Machine check", regs, +#ifdef CONFIG_PPC32 + SIGBUS +#else + 0 +#endif + ); /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) panic("Unrecoverable Machine check"); } +#ifdef CONFIG_PPC32 void SMIException(struct pt_regs *regs) { die("System Management Interrupt", regs, SIGABRT); } +#endif -void UnknownException(struct pt_regs *regs) +void unknown_exception(struct pt_regs *regs) { printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); @@ -486,7 +525,7 @@ void UnknownException(struct pt_regs *regs) _exception(SIGTRAP, regs, 0, 0); } -void InstructionBreakpoint(struct pt_regs *regs) +void instruction_breakpoint_exception(struct pt_regs *regs) { if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) @@ -496,14 +535,20 @@ void InstructionBreakpoint(struct pt_regs *regs) _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); } +#ifdef CONFIG_PPC32 void RunModeException(struct pt_regs *regs) { _exception(SIGTRAP, regs, 0, 0); } +#endif -void SingleStepException(struct pt_regs *regs) +void __KPROBES single_step_exception(struct pt_regs *regs) { +#ifdef CONFIG_PPC32 regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ +#else + regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ +#endif if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) @@ -520,15 +565,62 @@ void SingleStepException(struct pt_regs *regs) * pretend we got a single-step exception. This was pointed out * by Kumar Gala. -- paulus */ -static void emulate_single_step(struct pt_regs *regs) +static inline void emulate_single_step(struct pt_regs *regs) { if (single_stepping(regs)) { +#ifdef CONFIG_PPC32 clear_single_step(regs); _exception(SIGTRAP, regs, TRAP_TRACE, 0); +#else + single_step_exception(regs); +#endif } } -/* Illegal instruction emulation support. Originally written to +static void parse_fpe(struct pt_regs *regs) +{ + int code = 0; + unsigned long fpscr; + +#ifdef CONFIG_PPC32 + /* We must make sure the FP state is consistent with + * our MSR_FP in regs + */ + preempt_disable(); + if (regs->msr & MSR_FP) + giveup_fpu(current); + preempt_enable(); +#else + flush_fp_to_thread(current); +#endif + + fpscr = current->thread.fpscr; + + /* Invalid operation */ + if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) + code = FPE_FLTINV; + + /* Overflow */ + else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) + code = FPE_FLTOVF; + + /* Underflow */ + else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) + code = FPE_FLTUND; + + /* Divide by zero */ + else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) + code = FPE_FLTDIV; + + /* Inexact result */ + else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) + code = FPE_FLTRES; + + _exception(SIGFPE, regs, code, regs->nip); +} + +/* + * Illegal instruction emulation support. Originally written to * provide the PVR to user applications using the mfspr rd, PVR. * Return non-zero if we can't emulate, or -EFAULT if the associated * memory access caused an access fault. Return zero on success. @@ -536,7 +628,6 @@ static void emulate_single_step(struct pt_regs *regs) * There are a couple of ways to do this, either "decode" the instruction * or directly match lots of bits. In this case, matching lots of * bits is faster and easier. - * */ #define INST_MFSPR_PVR 0x7c1f42a6 #define INST_MFSPR_PVR_MASK 0xfc1fffff @@ -547,6 +638,8 @@ static void emulate_single_step(struct pt_regs *regs) #define INST_MCRXR 0x7c000400 #define INST_MCRXR_MASK 0x7c0007fe +#ifdef CONFIG_PPC32 + #define INST_STRING 0x7c00042a #define INST_STRING_MASK 0x7c0007fe #define INST_STRING_GEN_MASK 0x7c00067e @@ -622,6 +715,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) return 0; } +#endif /* CONFIG_PPC32 */ static int emulate_instruction(struct pt_regs *regs) { @@ -643,22 +737,44 @@ static int emulate_instruction(struct pt_regs *regs) } /* Emulating the dcba insn is just a no-op. */ - if ((instword & INST_DCBA_MASK) == INST_DCBA) + if ((instword & INST_DCBA_MASK) == INST_DCBA) { +#ifdef CONFIG_PPC64 + static int warned; + + if (!warned) { + printk(KERN_WARNING + "process %d (%s) uses obsolete 'dcba' insn\n", + current->pid, current->comm); + warned = 1; + } +#endif /* CONFIG_PPC64 */ return 0; + } /* Emulate the mcrxr insn. */ if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { - int shift = (instword >> 21) & 0x1c; + unsigned int shift = (instword >> 21) & 0x1c; unsigned long msk = 0xf0000000UL >> shift; +#ifdef CONFIG_PPC64 + static int warned; + if (!warned) { + printk(KERN_WARNING + "process %d (%s) uses obsolete 'mcrxr' insn\n", + current->pid, current->comm); + warned = 1; + } +#endif regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); regs->xer &= ~0xf0000000UL; return 0; } +#ifdef CONFIG_PPC32 /* Emulate load/store string insn. */ if ((instword & INST_STRING_GEN_MASK) == INST_STRING) return emulate_string_inst(regs, instword); +#endif return -EINVAL; } @@ -686,7 +802,7 @@ struct bug_entry *find_bug(unsigned long bugaddr) return module_find_bug(bugaddr); } -int check_bug_trap(struct pt_regs *regs) +static int check_bug_trap(struct pt_regs *regs) { struct bug_entry *bug; unsigned long addr; @@ -701,34 +817,38 @@ int check_bug_trap(struct pt_regs *regs) return 0; if (bug->line & BUG_WARNING_TRAP) { /* this is a WARN_ON rather than BUG/BUG_ON */ -#ifdef CONFIG_XMON +#if defined(CONFIG_PPC32) && defined(CONFIG_XMON) xmon_printf(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, bug->line & ~BUG_WARNING_TRAP); -#endif /* CONFIG_XMON */ +#endif printk(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, bug->line & ~BUG_WARNING_TRAP); +#ifdef CONFIG_PPC32 dump_stack(); +#else + show_stack(current, (void *)regs->gpr[1]); +#endif return 1; } -#ifdef CONFIG_XMON +#if defined(CONFIG_PPC32) && defined(CONFIG_XMON) xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n", bug->function, bug->file, bug->line); xmon(regs); -#endif /* CONFIG_XMON */ +#endif printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", bug->function, bug->file, bug->line); return 0; } -void ProgramCheckException(struct pt_regs *regs) +void __KPROBES program_check_exception(struct pt_regs *regs) { unsigned int reason = get_reason(regs); +#if defined(CONFIG_PPC32) && defined(CONFIG_MATH_EMULATION) extern int do_mathemu(struct pt_regs *regs); -#ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD) * that means ESR is sometimes set incorrectly - either to @@ -740,69 +860,61 @@ void ProgramCheckException(struct pt_regs *regs) emulate_single_step(regs); return; } -#endif /* CONFIG_MATH_EMULATION */ +#endif + +#ifdef CONFIG_PPC64 + if (debugger_fault_handler(regs)) + return; +#endif if (reason & REASON_FP) { /* IEEE FP exception */ - int code = 0; - u32 fpscr; - - /* We must make sure the FP state is consistent with - * our MSR_FP in regs - */ - preempt_disable(); - if (regs->msr & MSR_FP) - giveup_fpu(current); - preempt_enable(); - - fpscr = current->thread.fpscr; - fpscr &= fpscr << 22; /* mask summary bits with enables */ - if (fpscr & FPSCR_VX) - code = FPE_FLTINV; - else if (fpscr & FPSCR_OX) - code = FPE_FLTOVF; - else if (fpscr & FPSCR_UX) - code = FPE_FLTUND; - else if (fpscr & FPSCR_ZX) - code = FPE_FLTDIV; - else if (fpscr & FPSCR_XX) - code = FPE_FLTRES; - _exception(SIGFPE, regs, code, regs->nip); - return; - } - - if (reason & REASON_TRAP) { + parse_fpe(regs); + } else if (reason & REASON_TRAP) { /* trap exception */ +#ifdef CONFIG_PPC64 + if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) + == NOTIFY_STOP) + return; +#endif if (debugger_bpt(regs)) return; if (check_bug_trap(regs)) { regs->nip += 4; return; } - _exception(SIGTRAP, regs, TRAP_BRKPT, 0); - return; - } - - /* Try to emulate it if we should. */ - if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { + _exception(SIGTRAP, regs, TRAP_BRKPT, +#ifdef CONFIG_PPC32 + 0 +#else + regs->nip +#endif + ); + } else +#ifdef CONFIG_PPC32 + if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) +#endif + { + /* Privileged or illegal instruction; try to emulate it. */ switch (emulate_instruction(regs)) { case 0: regs->nip += 4; emulate_single_step(regs); - return; + break; case -EFAULT: _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - return; + break; + default: + if (reason & REASON_PRIVILEGED) + _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); + else + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + break; } } - - if (reason & REASON_PRIVILEGED) - _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); - else - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); } -void AlignmentException(struct pt_regs *regs) +void alignment_exception(struct pt_regs *regs) { int fixed; @@ -814,18 +926,31 @@ void AlignmentException(struct pt_regs *regs) return; } - /* Operand address was bad */ + /* Operand address was bad */ if (fixed == -EFAULT) { if (user_mode(regs)) - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); + _exception(SIGSEGV, regs, +#ifdef CONFIG_PPC32 + SEGV_ACCERR, +#else + SEGV_MAPERR, +#endif + regs->dar); else /* Search exception table */ bad_page_fault(regs, regs->dar, SIGSEGV); return; } - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); + _exception(SIGBUS, regs, BUS_ADRALN, +#ifdef CONFIG_PPC32 + regs->dar +#else + regs->nip +#endif + ); } +#ifdef CONFIG_PPC32 void StackOverflow(struct pt_regs *regs) { printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", @@ -849,8 +974,58 @@ void trace_syscall(struct pt_regs *regs) current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); } +#endif /* CONFIG_PPC32 */ -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC64 +void kernel_fp_unavailable_exception(struct pt_regs *regs) +{ + printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " + "%lx at %lx\n", regs->trap, regs->nip); + die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); +} +#endif + +void altivec_unavailable_exception(struct pt_regs *regs) +{ +#if !defined(CONFIG_ALTIVEC) || defined(CONFIG_PPC64) + if (user_mode(regs)) { + /* A user program has executed an altivec instruction, + but this kernel doesn't support altivec. */ + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); + return; + } +#endif +#ifdef CONFIG_PPC32 + { + static int kernel_altivec_count; + + /* The kernel has executed an altivec instruction without + first enabling altivec. Whinge but let it do it. */ + if (++kernel_altivec_count < 10) + printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", + current, regs->nip); + regs->msr |= MSR_VEC; + } +#else + printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " + "%lx at %lx\n", regs->trap, regs->nip); + die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); +#endif +} + +#ifdef CONFIG_PPC64 +extern perf_irq_t perf_irq; +#endif + +#if defined(CONFIG_PPC64) || defined(CONFIG_E500) +void performance_monitor_exception(struct pt_regs *regs) +{ + perf_irq(regs); +} +#endif + + +#if defined(CONFIG_PPC32) && defined(CONFIG_8xx) void SoftwareEmulation(struct pt_regs *regs) { extern int do_mathemu(struct pt_regs *); @@ -879,8 +1054,9 @@ void SoftwareEmulation(struct pt_regs *regs) } else emulate_single_step(regs); } -#endif /* CONFIG_8xx */ +#endif /* defined(CONFIG_PPC32) && defined(CONFIG_8xx) */ +#ifdef CONFIG_PPC32 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) void DebugException(struct pt_regs *regs, unsigned long debug_status) @@ -909,42 +1085,36 @@ void TAUException(struct pt_regs *regs) regs->nip, regs->msr, regs->trap, print_tainted()); } #endif /* CONFIG_INT_TAU */ - -void AltivecUnavailException(struct pt_regs *regs) -{ - static int kernel_altivec_count; - -#ifndef CONFIG_ALTIVEC - if (user_mode(regs)) { - /* A user program has executed an altivec instruction, - but this kernel doesn't support altivec. */ - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - return; - } -#endif - /* The kernel has executed an altivec instruction without - first enabling altivec. Whinge but let it do it. */ - if (++kernel_altivec_count < 10) - printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", - current, regs->nip); - regs->msr |= MSR_VEC; -} +#endif /* CONFIG_PPC32*/ #ifdef CONFIG_ALTIVEC -void AltivecAssistException(struct pt_regs *regs) +void altivec_assist_exception(struct pt_regs *regs) { int err; +#ifdef CONFIG_PPC64 + siginfo_t info; +#endif +#ifdef CONFIG_PPC32 preempt_disable(); if (regs->msr & MSR_VEC) giveup_altivec(current); preempt_enable(); +#endif if (!user_mode(regs)) { printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" " at %lx\n", regs->nip); - die("Kernel Altivec assist exception", regs, SIGILL); + die("Kernel " +#ifdef CONFIG_PPC64 + "VMX/" +#endif + "Altivec assist exception", regs, SIGILL); } +#ifdef CONFIG_PPC64 + flush_altivec_to_thread(current); +#endif /* CONFIG_PPC64 */ + err = emulate_altivec(regs); if (err == 0) { regs->nip += 4; /* skip emulated instruction */ @@ -954,7 +1124,15 @@ void AltivecAssistException(struct pt_regs *regs) if (err == -EFAULT) { /* got an error reading the instruction */ +#ifdef CONFIG_PPC32 _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip); +#else + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void __user *) regs->nip; + force_sig_info(SIGSEGV, &info, current); +#endif } else { /* didn't recognize the instruction */ /* XXX quick hack for now: set the non-Java bit in the VSCR */ @@ -966,13 +1144,7 @@ void AltivecAssistException(struct pt_regs *regs) } #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_E500 -void PerformanceMonitorException(struct pt_regs *regs) -{ - perf_irq(regs); -} -#endif - +#ifdef CONFIG_PPC32 #ifdef CONFIG_FSL_BOOKE void CacheLockingException(struct pt_regs *regs, unsigned long address, unsigned long error_code) @@ -1022,7 +1194,24 @@ void SPEFloatingPointException(struct pt_regs *regs) return; } #endif +#endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 +/* + * We enter here if we get an unrecoverable exception, that is, one + * that happened at a point where the RI (recoverable interrupt) bit + * in the MSR is 0. This indicates that SRR0/1 are live, and that + * we therefore lost state by taking this exception. + */ +void unrecoverable_exception(struct pt_regs *regs) +{ + printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n", + regs->trap, regs->nip); + die("Unrecoverable exception", regs, SIGABRT); +} +#endif /* CONFIG_PPC64 */ + +#ifdef CONFIG_PPC32 #ifdef CONFIG_BOOKE_WDT /* * Default handler for a Watchdog exception, @@ -1041,6 +1230,20 @@ void WatchdogException(struct pt_regs *regs) WatchdogHandler(regs); } #endif +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 +/* + * We enter here if we discover during exception entry that we are + * running in supervisor mode with a userspace value in the stack pointer. + */ +void kernel_bad_stack(struct pt_regs *regs) +{ + printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n", + regs->gpr[1], regs->nip); + die("Bad kernel stack pointer", regs, SIGABRT); +} +#endif void __init trap_init(void) { diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 8cdac7385e7f..2c3a1d34e3c7 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -349,12 +349,12 @@ i##n: \ /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and - putting it back to what it was (UnknownException) when done. */ + putting it back to what it was (unknown_exception) when done. */ #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) . = 0x100 b __secondary_start_gemini #else - EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) + EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) #endif /* Machine check */ @@ -389,7 +389,7 @@ i##n: \ cmpwi cr1,r4,0 bne cr1,1f #endif - EXC_XFER_STD(0x200, MachineCheckException) + EXC_XFER_STD(0x200, machine_check_exception) #ifdef CONFIG_PPC_CHRP 1: b machine_check_in_rtas #endif @@ -456,10 +456,10 @@ Alignment: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* Program check exception */ - EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD) /* Floating-point unavailable */ . = 0x800 @@ -472,8 +472,8 @@ FPUnavailable: /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) - EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) - EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE) /* System call */ . = 0xc00 @@ -482,8 +482,8 @@ SystemCall: EXC_XFER_EE_LITE(0xc00, DoSyscall) /* Single step - not used on 601 */ - EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) - EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) + EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE) /* * The Altivec unavailable trap is at 0x0f20. Foo. @@ -502,7 +502,7 @@ SystemCall: Trap_0f: EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0xf00, UnknownException) + EXC_XFER_EE(0xf00, unknown_exception) /* * Handle TLB miss for instruction on 603/603e. @@ -702,44 +702,44 @@ DataStoreTLBMiss: rfi #ifndef CONFIG_ALTIVEC -#define AltivecAssistException UnknownException +#define altivec_assist_exception unknown_exception #endif - EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE) + EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) #ifdef CONFIG_POWER4 - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) #else /* !CONFIG_POWER4 */ - EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_POWER4 */ - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE) - EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE) + EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE) .globl mol_trampoline .set mol_trampoline, i0x2f00 @@ -751,7 +751,7 @@ AltiVecUnavailable: #ifdef CONFIG_ALTIVEC bne load_up_altivec /* if from user, just load it up */ #endif /* CONFIG_ALTIVEC */ - EXC_XFER_EE_LITE(0xf20, AltivecUnavailException) + EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) #ifdef CONFIG_PPC64BRIDGE DataAccess: @@ -767,12 +767,12 @@ DataSegment: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_DAR stw r4,_DAR(r11) - EXC_XFER_STD(0x380, UnknownException) + EXC_XFER_STD(0x380, unknown_exception) InstructionSegment: EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x480, UnknownException) + EXC_XFER_STD(0x480, unknown_exception) #endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_ALTIVEC diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 599245b0407e..b1b9dc08abca 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S @@ -309,13 +309,13 @@ skpinv: addi r4,r4,1 /* Increment */ interrupt_base: /* Critical Input Interrupt */ - CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ #ifdef CONFIG_440A - MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #else - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #endif /* Data Storage Interrupt */ @@ -442,7 +442,7 @@ interrupt_base: #ifdef CONFIG_PPC_FPU FP_UNAVAILABLE_EXCEPTION #else - EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) #endif /* System Call Interrupt */ @@ -451,21 +451,21 @@ interrupt_base: EXC_XFER_EE_LITE(0x0c00, DoSyscall) /* Auxillary Processor Unavailable Interrupt */ - EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ DECREMENTER_EXCEPTION /* Fixed Internal Timer Interrupt */ /* TODO: Add FIT support */ - EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ /* TODO: Add watchdog support */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) #else - CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception) #endif /* Data TLB Error Interrupt */ diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S index 8562b807b37c..5772ce97e24e 100644 --- a/arch/ppc/kernel/head_4xx.S +++ b/arch/ppc/kernel/head_4xx.S @@ -245,12 +245,12 @@ label: /* * 0x0100 - Critical Interrupt Exception */ - CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception) /* * 0x0200 - Machine Check Exception */ - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) /* * 0x0300 - Data Storage Exception @@ -405,7 +405,7 @@ label: mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ stw r4,_DEAR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* 0x0700 - Program Exception */ START_EXCEPTION(0x0700, ProgramCheck) @@ -413,21 +413,21 @@ label: mfspr r4,SPRN_ESR /* Grab the ESR and save it */ stw r4,_ESR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x700, ProgramCheckException) + EXC_XFER_STD(0x700, program_check_exception) - EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE) /* 0x0C00 - System Call Exception */ START_EXCEPTION(0x0C00, SystemCall) NORMAL_EXCEPTION_PROLOG EXC_XFER_EE_LITE(0xc00, DoSyscall) - EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE) - EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE) /* 0x1000 - Programmable Interval Timer (PIT) Exception */ START_EXCEPTION(0x1000, Decrementer) @@ -444,14 +444,14 @@ label: /* 0x1010 - Fixed Interval Timer (FIT) Exception */ - STND_EXCEPTION(0x1010, FITException, UnknownException) + STND_EXCEPTION(0x1010, FITException, unknown_exception) /* 0x1020 - Watchdog Timer (WDT) Exception */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException) #else - CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException) + CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception) #endif #endif @@ -656,25 +656,25 @@ label: mfspr r10, SPRN_SPRG0 b InstructionAccess - EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) #ifdef CONFIG_IBM405_ERR51 /* 405GP errata 51 */ START_EXCEPTION(0x1700, Trap_17) b DTLBMiss #else - EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE) #endif - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE) /* Check for a single step debug exception while in an exception * handler before state has been saved. This is to catch the case diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index cb1a3a54a026..de0978742221 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -203,7 +203,7 @@ i##n: \ ret_from_except) /* System reset */ - EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) + EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) /* Machine check */ . = 0x200 @@ -214,7 +214,7 @@ MachineCheck: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x200, MachineCheckException) + EXC_XFER_STD(0x200, machine_check_exception) /* Data access exception. * This is "never generated" by the MPC8xx. We jump to it for other @@ -252,20 +252,20 @@ Alignment: mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE(0x600, AlignmentException) + EXC_XFER_EE(0x600, alignment_exception) /* Program check exception */ - EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD) + EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD) /* No FPU on MPC8xx. This exception is not supposed to happen. */ - EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD) + EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD) /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) - EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE) - EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE) + EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE) /* System call */ . = 0xc00 @@ -274,9 +274,9 @@ SystemCall: EXC_XFER_EE_LITE(0xc00, DoSyscall) /* Single step - not used on 601 */ - EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD) - EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE) - EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE) + EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD) + EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE) /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. @@ -540,22 +540,22 @@ DataTLBError: #endif b DataAccess - EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) /* On the MPC8xx, these next four traps are used for development * support of breakpoints and such. Someday I will get around to * using them. */ - EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE) - EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE) + EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE) . = 0x2000 diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index 9342acf12e72..aeb349b47af3 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h @@ -335,7 +335,7 @@ mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \ stw r4,_DEAR(r11); \ addi r3,r1,STACK_FRAME_OVERHEAD; \ - EXC_XFER_EE(0x0600, AlignmentException) + EXC_XFER_EE(0x0600, alignment_exception) #define PROGRAM_EXCEPTION \ START_EXCEPTION(Program) \ @@ -343,7 +343,7 @@ mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \ stw r4,_ESR(r11); \ addi r3,r1,STACK_FRAME_OVERHEAD; \ - EXC_XFER_STD(0x0700, ProgramCheckException) + EXC_XFER_STD(0x0700, program_check_exception) #define DECREMENTER_EXCEPTION \ START_EXCEPTION(Decrementer) \ diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index eba5a5f8ff08..53949811efda 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S @@ -426,14 +426,14 @@ skpinv: addi r6,r6,1 /* Increment */ interrupt_base: /* Critical Input Interrupt */ - CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ #ifdef CONFIG_E200 /* no RFMCI, MCSRRs on E200 */ - CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #else - MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) #endif /* Data Storage Interrupt */ @@ -542,9 +542,9 @@ interrupt_base: #else #ifdef CONFIG_E200 /* E200 treats 'normal' floating point instructions as FP Unavail exception */ - EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE) + EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE) #else - EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) #endif #endif @@ -554,20 +554,20 @@ interrupt_base: EXC_XFER_EE_LITE(0x0c00, DoSyscall) /* Auxillary Processor Unavailable Interrupt */ - EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ DECREMENTER_EXCEPTION /* Fixed Internal Timer Interrupt */ /* TODO: Add FIT support */ - EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ #ifdef CONFIG_BOOKE_WDT CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException) #else - CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) + CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception) #endif /* Data TLB Error Interrupt */ @@ -696,21 +696,21 @@ interrupt_base: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_EE_LITE(0x2010, KernelSPE) #else - EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_SPE */ /* SPE Floating Point Data */ #ifdef CONFIG_SPE EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); #else - EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) #endif /* CONFIG_SPE */ /* SPE Floating Point Round */ - EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE) + EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) /* Performance Monitor */ - EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD) + EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) /* Debug Interrupt */ diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 1545621d44d2..7872c6c45732 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -53,10 +53,10 @@ extern void transfer_to_handler(void); extern void do_IRQ(struct pt_regs *regs); -extern void MachineCheckException(struct pt_regs *regs); -extern void AlignmentException(struct pt_regs *regs); -extern void ProgramCheckException(struct pt_regs *regs); -extern void SingleStepException(struct pt_regs *regs); +extern void machine_check_exception(struct pt_regs *regs); +extern void alignment_exception(struct pt_regs *regs); +extern void program_check_exception(struct pt_regs *regs); +extern void single_step_exception(struct pt_regs *regs); extern int do_signal(sigset_t *, struct pt_regs *); extern int pmac_newworld; extern int sys_sigreturn(struct pt_regs *regs); @@ -72,10 +72,10 @@ EXPORT_SYMBOL(clear_user_page); EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); -EXPORT_SYMBOL(MachineCheckException); -EXPORT_SYMBOL(AlignmentException); -EXPORT_SYMBOL(ProgramCheckException); -EXPORT_SYMBOL(SingleStepException); +EXPORT_SYMBOL(machine_check_exception); +EXPORT_SYMBOL(alignment_exception); +EXPORT_SYMBOL(program_check_exception); +EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); EXPORT_SYMBOL(ppc_n_lost_interrupts); EXPORT_SYMBOL(ppc_lost_interrupts); diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 82e4d70e6dbb..26606aa33de6 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -74,7 +74,7 @@ void (*debugger_fault_handler)(struct pt_regs *regs); DEFINE_SPINLOCK(die_lock); -void die(const char * str, struct pt_regs * fp, long err) +int die(const char * str, struct pt_regs * fp, long err) { static int die_counter; int nl = 0; @@ -232,7 +232,7 @@ platform_machine_check(struct pt_regs *regs) { } -void MachineCheckException(struct pt_regs *regs) +void machine_check_exception(struct pt_regs *regs) { unsigned long reason = get_mc_reason(regs); @@ -393,14 +393,14 @@ void SMIException(struct pt_regs *regs) #endif } -void UnknownException(struct pt_regs *regs) +void unknown_exception(struct pt_regs *regs) { printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); _exception(SIGTRAP, regs, 0, 0); } -void InstructionBreakpoint(struct pt_regs *regs) +void instruction_breakpoint_exception(struct pt_regs *regs) { if (debugger_iabr_match(regs)) return; @@ -622,7 +622,7 @@ int check_bug_trap(struct pt_regs *regs) return 0; } -void ProgramCheckException(struct pt_regs *regs) +void program_check_exception(struct pt_regs *regs) { unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); @@ -701,7 +701,7 @@ void ProgramCheckException(struct pt_regs *regs) _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); } -void SingleStepException(struct pt_regs *regs) +void single_step_exception(struct pt_regs *regs) { regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ if (debugger_sstep(regs)) @@ -709,7 +709,7 @@ void SingleStepException(struct pt_regs *regs) _exception(SIGTRAP, regs, TRAP_TRACE, 0); } -void AlignmentException(struct pt_regs *regs) +void alignment_exception(struct pt_regs *regs) { int fixed; @@ -814,7 +814,7 @@ void TAUException(struct pt_regs *regs) } #endif /* CONFIG_INT_TAU */ -void AltivecUnavailException(struct pt_regs *regs) +void altivec_unavailable_exception(struct pt_regs *regs) { static int kernel_altivec_count; @@ -835,7 +835,7 @@ void AltivecUnavailException(struct pt_regs *regs) } #ifdef CONFIG_ALTIVEC -void AltivecAssistException(struct pt_regs *regs) +void altivec_assist_exception(struct pt_regs *regs) { int err; @@ -872,7 +872,7 @@ void AltivecAssistException(struct pt_regs *regs) #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_E500 -void PerformanceMonitorException(struct pt_regs *regs) +void performance_monitor_exception(struct pt_regs *regs) { perf_irq(regs); } diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c index 7612e0623f99..95e11f93c15d 100644 --- a/arch/ppc/syslib/ibm44x_common.c +++ b/arch/ppc/syslib/ibm44x_common.c @@ -178,7 +178,7 @@ void __init ibm44x_platform_init(void) #endif } -/* Called from MachineCheckException */ +/* Called from machine_check_exception */ void platform_machine_check(struct pt_regs *regs) { printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n", diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c index b843c4fef25e..def724b6e1c9 100644 --- a/arch/ppc/syslib/ppc4xx_setup.c +++ b/arch/ppc/syslib/ppc4xx_setup.c @@ -279,7 +279,7 @@ ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif /* defined(CONFIG_PCI) && defined(CONFIG_IDE) */ } -/* Called from MachineCheckException */ +/* Called from machine_check_exception */ void platform_machine_check(struct pt_regs *regs) { #if defined(DCRN_PLB0_BEAR) diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 16e34de34178..9457fe63d125 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -2,6 +2,8 @@ # Makefile for the linux ppc64 kernel. # +ifneq ($(CONFIG_PPC_MERGE),y) + EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds @@ -77,3 +79,9 @@ endif # These are here while we do the architecture merge vecemu-y += ../../powerpc/kernel/vecemu.o vector-y += ../../powerpc/kernel/vector.o +idle_power4-y += ../../powerpc/kernel/idle_power4.o +traps-y += ../../powerpc/kernel/traps.o + +else + +endif diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c deleted file mode 100644 index a728c9f0b53f..000000000000 --- a/arch/ppc64/kernel/traps.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * linux/arch/ppc64/kernel/traps.c - * - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * 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. - * - * Modified by Cort Dougan (cort@cs.nmt.edu) - * and Paul Mackerras (paulus@cs.anu.edu.au) - */ - -/* - * This file handles the architecture-dependent parts of hardware exceptions - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_DEBUGGER -int (*__debugger)(struct pt_regs *regs); -int (*__debugger_ipi)(struct pt_regs *regs); -int (*__debugger_bpt)(struct pt_regs *regs); -int (*__debugger_sstep)(struct pt_regs *regs); -int (*__debugger_iabr_match)(struct pt_regs *regs); -int (*__debugger_dabr_match)(struct pt_regs *regs); -int (*__debugger_fault_handler)(struct pt_regs *regs); - -EXPORT_SYMBOL(__debugger); -EXPORT_SYMBOL(__debugger_ipi); -EXPORT_SYMBOL(__debugger_bpt); -EXPORT_SYMBOL(__debugger_sstep); -EXPORT_SYMBOL(__debugger_iabr_match); -EXPORT_SYMBOL(__debugger_dabr_match); -EXPORT_SYMBOL(__debugger_fault_handler); -#endif - -struct notifier_block *powerpc_die_chain; -static DEFINE_SPINLOCK(die_notifier_lock); - -int register_die_notifier(struct notifier_block *nb) -{ - int err = 0; - unsigned long flags; - - spin_lock_irqsave(&die_notifier_lock, flags); - err = notifier_chain_register(&powerpc_die_chain, nb); - spin_unlock_irqrestore(&die_notifier_lock, flags); - return err; -} - -/* - * Trap & Exception support - */ - -static DEFINE_SPINLOCK(die_lock); - -int die(const char *str, struct pt_regs *regs, long err) -{ - static int die_counter; - int nl = 0; - - if (debugger(regs)) - return 1; - - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); - nl = 1; -#endif -#ifdef CONFIG_SMP - printk("SMP NR_CPUS=%d ", NR_CPUS); - nl = 1; -#endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC "); - nl = 1; -#endif -#ifdef CONFIG_NUMA - printk("NUMA "); - nl = 1; -#endif - switch(systemcfg->platform) { - case PLATFORM_PSERIES: - printk("PSERIES "); - nl = 1; - break; - case PLATFORM_PSERIES_LPAR: - printk("PSERIES LPAR "); - nl = 1; - break; - case PLATFORM_ISERIES_LPAR: - printk("ISERIES LPAR "); - nl = 1; - break; - case PLATFORM_POWERMAC: - printk("POWERMAC "); - nl = 1; - break; - case PLATFORM_BPA: - printk("BPA "); - nl = 1; - break; - } - if (nl) - printk("\n"); - print_modules(); - show_regs(regs); - bust_spinlocks(0); - spin_unlock_irq(&die_lock); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); - panic("Fatal exception"); - } - do_exit(SIGSEGV); - - return 0; -} - -void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) -{ - siginfo_t info; - - if (!user_mode(regs)) { - if (die("Exception in kernel mode", regs, signr)) - return; - } - - memset(&info, 0, sizeof(info)); - info.si_signo = signr; - info.si_code = code; - info.si_addr = (void __user *) addr; - force_sig_info(signr, &info, current); -} - -void system_reset_exception(struct pt_regs *regs) -{ - /* See if any machine dependent calls */ - if (ppc_md.system_reset_exception) - ppc_md.system_reset_exception(regs); - - die("System Reset", regs, 0); - - /* Must die if the interrupt is not recoverable */ - if (!(regs->msr & MSR_RI)) - panic("Unrecoverable System Reset"); - - /* What should we do here? We could issue a shutdown or hard reset. */ -} - -void machine_check_exception(struct pt_regs *regs) -{ - int recover = 0; - - /* See if any machine dependent calls */ - if (ppc_md.machine_check_exception) - recover = ppc_md.machine_check_exception(regs); - - if (recover) - return; - - if (debugger_fault_handler(regs)) - return; - die("Machine check", regs, 0); - - /* Must die if the interrupt is not recoverable */ - if (!(regs->msr & MSR_RI)) - panic("Unrecoverable Machine check"); -} - -void unknown_exception(struct pt_regs *regs) -{ - printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", - regs->nip, regs->msr, regs->trap); - - _exception(SIGTRAP, regs, 0, 0); -} - -void instruction_breakpoint_exception(struct pt_regs *regs) -{ - if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, - 5, SIGTRAP) == NOTIFY_STOP) - return; - if (debugger_iabr_match(regs)) - return; - _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); -} - -void __kprobes single_step_exception(struct pt_regs *regs) -{ - regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ - - if (notify_die(DIE_SSTEP, "single_step", regs, 5, - 5, SIGTRAP) == NOTIFY_STOP) - return; - if (debugger_sstep(regs)) - return; - - _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); -} - -/* - * After we have successfully emulated an instruction, we have to - * check if the instruction was being single-stepped, and if so, - * pretend we got a single-step exception. This was pointed out - * by Kumar Gala. -- paulus - */ -static inline void emulate_single_step(struct pt_regs *regs) -{ - if (regs->msr & MSR_SE) - single_step_exception(regs); -} - -static void parse_fpe(struct pt_regs *regs) -{ - int code = 0; - unsigned long fpscr; - - flush_fp_to_thread(current); - - fpscr = current->thread.fpscr; - - /* Invalid operation */ - if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) - code = FPE_FLTINV; - - /* Overflow */ - else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) - code = FPE_FLTOVF; - - /* Underflow */ - else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) - code = FPE_FLTUND; - - /* Divide by zero */ - else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) - code = FPE_FLTDIV; - - /* Inexact result */ - else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) - code = FPE_FLTRES; - - _exception(SIGFPE, regs, code, regs->nip); -} - -/* - * Illegal instruction emulation support. Return non-zero if we can't - * emulate, or -EFAULT if the associated memory access caused an access - * fault. Return zero on success. - */ - -#define INST_MFSPR_PVR 0x7c1f42a6 -#define INST_MFSPR_PVR_MASK 0xfc1fffff - -#define INST_DCBA 0x7c0005ec -#define INST_DCBA_MASK 0x7c0007fe - -#define INST_MCRXR 0x7c000400 -#define INST_MCRXR_MASK 0x7c0007fe - -static int emulate_instruction(struct pt_regs *regs) -{ - unsigned int instword; - - if (!user_mode(regs)) - return -EINVAL; - - CHECK_FULL_REGS(regs); - - if (get_user(instword, (unsigned int __user *)(regs->nip))) - return -EFAULT; - - /* Emulate the mfspr rD, PVR. */ - if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { - unsigned int rd; - - rd = (instword >> 21) & 0x1f; - regs->gpr[rd] = mfspr(SPRN_PVR); - return 0; - } - - /* Emulating the dcba insn is just a no-op. */ - if ((instword & INST_DCBA_MASK) == INST_DCBA) { - static int warned; - - if (!warned) { - printk(KERN_WARNING - "process %d (%s) uses obsolete 'dcba' insn\n", - current->pid, current->comm); - warned = 1; - } - return 0; - } - - /* Emulate the mcrxr insn. */ - if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { - static int warned; - unsigned int shift; - - if (!warned) { - printk(KERN_WARNING - "process %d (%s) uses obsolete 'mcrxr' insn\n", - current->pid, current->comm); - warned = 1; - } - - shift = (instword >> 21) & 0x1c; - regs->ccr &= ~(0xf0000000 >> shift); - regs->ccr |= (regs->xer & 0xf0000000) >> shift; - regs->xer &= ~0xf0000000; - return 0; - } - - return -EINVAL; -} - -/* - * Look through the list of trap instructions that are used for BUG(), - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know - * that the exception was caused by a trap instruction of some kind. - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 - * otherwise. - */ -extern struct bug_entry __start___bug_table[], __stop___bug_table[]; - -#ifndef CONFIG_MODULES -#define module_find_bug(x) NULL -#endif - -struct bug_entry *find_bug(unsigned long bugaddr) -{ - struct bug_entry *bug; - - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) - if (bugaddr == bug->bug_addr) - return bug; - return module_find_bug(bugaddr); -} - -static int -check_bug_trap(struct pt_regs *regs) -{ - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ - printk(KERN_ERR "Badness in %s at %s:%d\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - show_stack(current, (void *)regs->gpr[1]); - return 1; - } - printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", - bug->function, bug->file, bug->line); - return 0; -} - -void __kprobes program_check_exception(struct pt_regs *regs) -{ - if (debugger_fault_handler(regs)) - return; - - if (regs->msr & 0x100000) { - /* IEEE FP exception */ - parse_fpe(regs); - } else if (regs->msr & 0x20000) { - /* trap exception */ - - if (notify_die(DIE_BPT, "breakpoint", regs, 5, - 5, SIGTRAP) == NOTIFY_STOP) - return; - if (debugger_bpt(regs)) - return; - - if (check_bug_trap(regs)) { - regs->nip += 4; - return; - } - _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); - - } else { - /* Privileged or illegal instruction; try to emulate it. */ - switch (emulate_instruction(regs)) { - case 0: - regs->nip += 4; - emulate_single_step(regs); - break; - - case -EFAULT: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - break; - - default: - if (regs->msr & 0x40000) - /* priveleged */ - _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); - else - /* illegal */ - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - break; - } - } -} - -void kernel_fp_unavailable_exception(struct pt_regs *regs) -{ - printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " - "%lx at %lx\n", regs->trap, regs->nip); - die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); -} - -void altivec_unavailable_exception(struct pt_regs *regs) -{ - if (user_mode(regs)) { - /* A user program has executed an altivec instruction, - but this kernel doesn't support altivec. */ - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - return; - } - printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " - "%lx at %lx\n", regs->trap, regs->nip); - die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); -} - -extern perf_irq_t perf_irq; - -void performance_monitor_exception(struct pt_regs *regs) -{ - perf_irq(regs); -} - -void alignment_exception(struct pt_regs *regs) -{ - int fixed; - - fixed = fix_alignment(regs); - - if (fixed == 1) { - regs->nip += 4; /* skip over emulated instruction */ - emulate_single_step(regs); - return; - } - - /* Operand address was bad */ - if (fixed == -EFAULT) { - if (user_mode(regs)) { - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar); - } else { - /* Search exception table */ - bad_page_fault(regs, regs->dar, SIGSEGV); - } - - return; - } - - _exception(SIGBUS, regs, BUS_ADRALN, regs->nip); -} - -#ifdef CONFIG_ALTIVEC -void altivec_assist_exception(struct pt_regs *regs) -{ - int err; - siginfo_t info; - - if (!user_mode(regs)) { - printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" - " at %lx\n", regs->nip); - die("Kernel VMX/Altivec assist exception", regs, SIGILL); - } - - flush_altivec_to_thread(current); - - err = emulate_altivec(regs); - if (err == 0) { - regs->nip += 4; /* skip emulated instruction */ - emulate_single_step(regs); - return; - } - - if (err == -EFAULT) { - /* got an error reading the instruction */ - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = SEGV_MAPERR; - info.si_addr = (void __user *) regs->nip; - force_sig_info(SIGSEGV, &info, current); - } else { - /* didn't recognize the instruction */ - /* XXX quick hack for now: set the non-Java bit in the VSCR */ - if (printk_ratelimit()) - printk(KERN_ERR "Unrecognized altivec instruction " - "in %s at %lx\n", current->comm, regs->nip); - current->thread.vscr.u[3] |= 0x10000; - } -} -#endif /* CONFIG_ALTIVEC */ - -/* - * We enter here if we get an unrecoverable exception, that is, one - * that happened at a point where the RI (recoverable interrupt) bit - * in the MSR is 0. This indicates that SRR0/1 are live, and that - * we therefore lost state by taking this exception. - */ -void unrecoverable_exception(struct pt_regs *regs) -{ - printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n", - regs->trap, regs->nip); - die("Unrecoverable exception", regs, SIGABRT); -} - -/* - * We enter here if we discover during exception entry that we are - * running in supervisor mode with a userspace value in the stack pointer. - */ -void kernel_bad_stack(struct pt_regs *regs) -{ - printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n", - regs->gpr[1], regs->nip); - die("Bad kernel stack pointer", regs, SIGABRT); -} - -void __init trap_init(void) -{ -} diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index d754ab570fe0..6a49b138c218 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -87,7 +87,7 @@ extern void cacheable_memzero(void *p, unsigned int nb); extern void *cacheable_memcpy(void *, const void *, unsigned int); extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); -extern void die(const char *, struct pt_regs *, long); +extern int die(const char *, struct pt_regs *, long); extern void _exception(int, struct pt_regs *, int, unsigned long); #ifdef CONFIG_BOOKE_WDT extern u32 booke_wdt_enabled; From bd142b70a6bd5522f7d95f0cec06091b93bb0715 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 30 Sep 2005 13:51:25 +1000 Subject: [PATCH 0184/1940] ppc64: simplify the build a little Signed-off-by: Stephen Rothwell --- arch/powerpc/Makefile | 1 - arch/powerpc/kernel/Makefile | 11 +++++++++-- arch/ppc64/Makefile | 2 +- arch/ppc64/kernel/Makefile | 11 ++--------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 92751ca6f8b1..9f80deb05ecc 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -121,7 +121,6 @@ head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o ifeq ($(CONFIG_PPC32),y) head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o -head-$(CONFIG_POWER4) += arch/powerpc/kernel/idle_power4.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o endif diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 58c130b10ec8..b5eff3ef2f3d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -2,6 +2,10 @@ # Makefile for the linux kernel. # +ifeq ($(CONFIG_PPC64),y) +EXTRA_CFLAGS += -mno-minimal-toc +endif + extra-$(CONFIG_PPC_STD_MMU) := head.o extra_$(CONFIG_PPC64) := head_64.o extra-$(CONFIG_40x) := head_4xx.o @@ -9,10 +13,13 @@ extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o -extra-$(CONFIG_POWER4) += idle_power4.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y := semaphore.o traps.o process.o +obj-y := traps.o +obj-$(CONFIG_PPC32) += semaphore.o process.o +obj-$(CONFIG_PPC64) += idle_power4.o +ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_MODULES) += ppc_ksyms.o +endif obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index d4eb55f82f03..fa889204d6ae 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -82,7 +82,7 @@ CFLAGS += $(call cc-option,-funit-at-a-time) head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ -core-y += arch/ppc64/kernel/ +core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ core-y += arch/ppc64/mm/ core-y += arch/powerpc/platforms/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 9457fe63d125..90a1519342da 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -7,12 +7,12 @@ ifneq ($(CONFIG_PPC_MERGE),y) EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds -obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \ +obj-y := setup.o entry.o irq.o idle.o dma.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ align.o semaphore.o bitops.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ - lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ + lmb.o cputable.o cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o obj-y += vdso32/ vdso64/ @@ -66,7 +66,6 @@ obj-$(CONFIG_PPC_BPA) += pSeries_smp.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o endif -obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ @@ -76,12 +75,6 @@ arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s AFLAGS_head.o += -Iarch/powerpc/platforms/iseries endif -# These are here while we do the architecture merge -vecemu-y += ../../powerpc/kernel/vecemu.o -vector-y += ../../powerpc/kernel/vector.o -idle_power4-y += ../../powerpc/kernel/idle_power4.o -traps-y += ../../powerpc/kernel/traps.o - else endif From cabb558714945e92000f627dda562aa5e86a31af Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 30 Sep 2005 16:16:52 +1000 Subject: [PATCH 0185/1940] powerpc: make iSeries build Merge vmlinux.lds.S. Also remove arch/powerpc/kernel/vmlinux.lds which is a generated file. Signed-off-by: Stephen Rothwell --- arch/powerpc/Kconfig | 6 + arch/powerpc/Makefile | 27 +-- arch/powerpc/kernel/Makefile | 9 +- arch/powerpc/kernel/vmlinux.lds | 174 ------------------- arch/powerpc/kernel/vmlinux.lds.S | 196 ++++++++++++++++++++-- arch/powerpc/platforms/iseries/lpevents.c | 2 + arch/ppc64/kernel/Makefile | 8 +- include/asm-powerpc/system.h | 4 +- 8 files changed, 217 insertions(+), 209 deletions(-) delete mode 100644 arch/powerpc/kernel/vmlinux.lds diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 953a74be57b6..7f891ebfbd85 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -833,6 +833,12 @@ config PIN_TLB depends on ADVANCED_OPTIONS && 8xx endmenu +if PPC64 +config KERNEL_START + hex + default "0xc0000000" +endif + source "net/Kconfig" source "drivers/Kconfig" diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 9f80deb05ecc..eb1224c24e3e 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -124,12 +124,14 @@ head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o endif -core-y += arch/powerpc/kernel/ \ - arch/$(OLDARCH)/kernel/ \ - arch/powerpc/mm/ \ - arch/powerpc/lib/ \ - arch/powerpc/sysdev/ \ - arch/powerpc/platforms/ +core-y += arch/powerpc/kernel/ +core-y += arch/$(OLDARCH)/kernel/ +core-$(CONFIG_PPC32) += arch/powerpc/mm/ +core-$(CONFIG_PPC64) += arch/$(OLDARCH)/mm/ +core-$(CONFIG_PPC32) += arch/powerpc/lib/ +libs-$(CONFIG_PPC64) += arch/$(OLDARCH)/lib/ +core-y += arch/powerpc/sysdev/ +core-y += arch/powerpc/platforms/ core-$(CONFIG_PPC32) += arch/ppc/syslib/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ @@ -140,17 +142,20 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ -BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm - -.PHONY: $(BOOT_TARGETS) - -all: uImage zImage +defaultimage-$(CONFIG_PPC32) := uImage zImage +defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux +KBUILD_IMAGE := $(defaultimage-y) +all: $(KBUILD_IMAGE) CPPFLAGS_vmlinux.lds := -Upowerpc # All the instructions talk about "make bzImage". bzImage: zImage +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm + +.PHONY: $(BOOT_TARGETS) + boot := arch/$(OLDARCH)/boot $(BOOT_TARGETS): vmlinux diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b5eff3ef2f3d..be3f9d123a6d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -6,8 +6,10 @@ ifeq ($(CONFIG_PPC64),y) EXTRA_CFLAGS += -mno-minimal-toc endif +ifeq ($(CONFIG_PPC32),y) extra-$(CONFIG_PPC_STD_MMU) := head.o -extra_$(CONFIG_PPC64) := head_64.o +endif +extra-$(CONFIG_PPC64) := head_64.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o @@ -23,3 +25,8 @@ ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_MODULES) += ppc_ksyms.o endif obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o + +ifeq ($(CONFIG_PPC_ISERIES),y) +arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s +AFLAGS_head_64.o += -Iarch/powerpc/platforms/iseries +endif diff --git a/arch/powerpc/kernel/vmlinux.lds b/arch/powerpc/kernel/vmlinux.lds deleted file mode 100644 index d62c288a81d0..000000000000 --- a/arch/powerpc/kernel/vmlinux.lds +++ /dev/null @@ -1,174 +0,0 @@ -/* Align . to a 8 byte boundary equals to maximum function alignment. */ -/* sched.text is aling to function alignment to secure we have same - * address even at second ld pass when generating System.map */ -/* spinlock.text is aling to function alignment to secure we have same - * address even at second ld pass when generating System.map */ - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to - the beginning of the section so we begin them at 0. */ - /* Stabs debugging sections. */ -OUTPUT_ARCH(powerpc:common) -jiffies = jiffies_64 + 4; -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } -/* .init : { *(.init) } =0*/ - .plt : { *(.plt) } - .text : - { - *(.text) - . = ALIGN(8); __sched_text_start = .; *(.sched.text) __sched_text_end = .; - . = ALIGN(8); __lock_text_start = .; *(.spinlock.text) __lock_text_end = .; - *(.fixup) - *(.got1) - __got2_start = .; - *(.got2) - __got2_end = .; - } - _etext = .; - PROVIDE (etext = .); - .rodata : AT(ADDR(.rodata) - 0) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1 : AT(ADDR(.rodata1) - 0) { *(.rodata1) } .pci_fixup : AT(ADDR(.pci_fixup) - 0) { __start_pci_fixups_early = .; *(.pci_fixup_early) __end_pci_fixups_early = .; __start_pci_fixups_header = .; *(.pci_fixup_header) __end_pci_fixups_header = .; __start_pci_fixups_final = .; *(.pci_fixup_final) __end_pci_fixups_final = .; __start_pci_fixups_enable = .; *(.pci_fixup_enable) __end_pci_fixups_enable = .; } __ksymtab : AT(ADDR(__ksymtab) - 0) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - 0) { __start___ksymtab_gpl = .; *(__ksymtab_gpl) __stop___ksymtab_gpl = .; } __kcrctab : AT(ADDR(__kcrctab) - 0) { __start___kcrctab = .; *(__kcrctab) __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - 0) { __start___kcrctab_gpl = .; *(__kcrctab_gpl) __stop___kcrctab_gpl = .; } __ksymtab_strings : AT(ADDR(__ksymtab_strings) - 0) { *(__ksymtab_strings) } __param : AT(ADDR(__param) - 0) { __start___param = .; *(__param) __stop___param = .; } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - .fixup : { *(.fixup) } - __ex_table : { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - __bug_table : { - __start___bug_table = .; - *(__bug_table) - __stop___bug_table = .; - } - /* Read-write section, merged into data segment: */ - . = ALIGN(4096); - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; - PROVIDE (edata = .); - - . = ALIGN(8192); - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - /* .exit.text is discarded at runtime, not link time, - to deal with references from __bug_table */ - .exit.text : { *(.exit.text) } - .init.data : { - *(.init.data); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - - .security_initcall.init : AT(ADDR(.security_initcall.init) - 0) { __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .; } - - __start___ftr_fixup = .; - __ftr_fixup : { *(__ftr_fixup) } - __stop___ftr_fixup = .; - - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - _sextratext = .; - _eextratext = .; - - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - __bss_stop = .; - - _end = . ; - PROVIDE (end = .); - - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - *(.exit.data) - } -} diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 09c6525cfa61..0587d9c4609d 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -1,10 +1,29 @@ +#include +#ifdef CONFIG_PPC64 +#include +#endif #include +#ifdef CONFIG_PPC64 +OUTPUT_ARCH(powerpc:common64) +jiffies = jiffies_64; +#else OUTPUT_ARCH(powerpc:common) jiffies = jiffies_64 + 4; +#endif SECTIONS { + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) +#ifdef CONFIG_PPC32 + *(.exit.data) +#endif + } + + /* Read-only sections, merged into text segment: */ +#ifdef CONFIG_PPC32 . = + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } @@ -28,17 +47,30 @@ SECTIONS .rela.plt : { *(.rela.plt) } /* .init : { *(.init) } =0*/ .plt : { *(.plt) } - .text : - { +#endif + .text : { +#ifdef CONFIG_PPC64 + *(.text .text.*) +#else *(.text) +#endif SCHED_TEXT LOCK_TEXT +#ifdef CONFIG_PPC64 + KPROBES_TEXT +#endif *(.fixup) +#ifdef CONFIG_PPC32 *(.got1) __got2_start = .; *(.got2) __got2_end = .; +#else + . = ALIGN(PAGE_SIZE); + _etext = .; +#endif } +#ifdef CONFIG_PPC32 _etext = .; PROVIDE (etext = .); @@ -48,6 +80,7 @@ SECTIONS .dtors : { *(.dtors) } .fixup : { *(.fixup) } +#endif __ex_table : { __start___ex_table = .; @@ -61,6 +94,17 @@ SECTIONS __stop___bug_table = .; } +#ifdef CONFIG_PPC64 + __ftr_fixup : { + __start___ftr_fixup = .; + *(__ftr_fixup) + __stop___ftr_fixup = .; + } + + RODATA +#endif + +#ifdef CONFIG_PPC32 /* Read-write section, merged into data segment: */ . = ALIGN(4096); .data : @@ -90,16 +134,25 @@ SECTIONS .data.init_task : { *(.data.init_task) } . = ALIGN(4096); +#else + /* will be freed after init */ + . = ALIGN(PAGE_SIZE); +#endif __init_begin = .; .init.text : { _sinittext = .; *(.init.text) _einittext = .; } +#ifdef CONFIG_PPC32 /* .exit.text is discarded at runtime, not link time, to deal with references from __bug_table */ .exit.text : { *(.exit.text) } +#endif .init.data : { +#ifdef CONFIG_PPC64 + *(.init.data) +#else *(.init.data); __vtop_table_begin = .; *(.vtop_fixup); @@ -107,13 +160,31 @@ SECTIONS __ptov_table_begin = .; *(.ptov_fixup); __ptov_table_end = .; +#endif } + . = ALIGN(16); +#ifdef CONFIG_PPC32 __setup_start = .; - .init.setup : { *(.init.setup) } +#endif + .init.setup : { +#ifdef CONFIG_PPC64 + __setup_start = .; +#endif + *(.init.setup) +#ifdef CONFIG_PPC64 + __setup_end = .; +#endif + } +#ifdef CONFIG_PPC32 __setup_end = .; + __initcall_start = .; +#endif .initcall.init : { +#ifdef CONFIG_PPC64 + __initcall_start = .; +#endif *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) @@ -121,27 +192,109 @@ SECTIONS *(.initcall5.init) *(.initcall6.init) *(.initcall7.init) +#ifdef CONFIG_PPC64 + __initcall_end = .; +#endif } +#ifdef CONFIG_PPC32 __initcall_end = .; __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } +#endif + .con_initcall.init : { +#ifdef CONFIG_PPC64 + __con_initcall_start = .; +#endif + *(.con_initcall.init) +#ifdef CONFIG_PPC64 + __con_initcall_end = .; +#endif + } +#ifdef CONFIG_PPC32 __con_initcall_end = .; +#endif SECURITY_INIT +#ifdef CONFIG_PPC32 __start___ftr_fixup = .; __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; +#else + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } +#endif +#ifdef CONFIG_PPC32 . = ALIGN(32); __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } +#endif + .data.percpu : { +#ifdef CONFIG_PPC64 + __per_cpu_start = .; +#endif + *(.data.percpu) +#ifdef CONFIG_PPC64 + __per_cpu_end = .; +#endif + } +#ifdef CONFIG_PPC32 __per_cpu_end = .; +#endif +#ifdef CONFIG_PPC64 + . = ALIGN(PAGE_SIZE); + . = ALIGN(16384); + __init_end = .; + /* freed after init ends here */ + + + /* Read/write sections */ + . = ALIGN(PAGE_SIZE); + . = ALIGN(16384); + /* The initial task and kernel stack */ + .data.init_task : { + *(.data.init_task) + } + + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.page_aligned) + } + + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + .data : { + *(.data .data.rel* .toc1) + *(.branch_lt) + } + + .opd : { + *(.opd) + } + + .got : { + __toc_start = .; + *(.got) + *(.toc) + . = ALIGN(PAGE_SIZE); + _edata = .; + } + + + . = ALIGN(PAGE_SIZE); +#else . = ALIGN(4096); __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } + .init.ramfs : { + *(.init.ramfs) + } __initramfs_end = .; . = ALIGN(4096); @@ -152,21 +305,30 @@ SECTIONS _eextratext = .; __bss_start = .; - .bss : - { +#endif + .bss : { +#ifdef CONFIG_PPC64 + __bss_start = .; +#else *(.sbss) *(.scommon) *(.dynbss) +#endif *(.bss) +#ifdef CONFIG_PPC32 *(COMMON) - } +#else __bss_stop = .; - - _end = . ; - PROVIDE (end = .); - - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - *(.exit.data) +#endif } +#ifdef CONFIG_PPC32 + __bss_stop = .; +#endif + +#ifdef CONFIG_PPC64 + . = ALIGN(PAGE_SIZE); +#endif + _end = . ; +#ifdef CONFIG_PPC32 + PROVIDE (end = .); +#endif } diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 883603027ccf..f8b4155b0481 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -13,6 +13,8 @@ #include #include #include +#include + #include #include #include diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 90a1519342da..2fdcc4b63d40 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -2,10 +2,10 @@ # Makefile for the linux ppc64 kernel. # -ifneq ($(CONFIG_PPC_MERGE),y) - EXTRA_CFLAGS += -mno-minimal-toc +ifneq ($(CONFIG_PPC_MERGE),y) extra-y := head.o vmlinux.lds +endif obj-y := setup.o entry.o irq.o idle.o dma.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ @@ -70,11 +70,9 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ +ifneq ($(CONFIG_PPC_MERGE),y) ifeq ($(CONFIG_PPC_ISERIES),y) arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s AFLAGS_head.o += -Iarch/powerpc/platforms/iseries endif - -else - endif diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 1b64879a02c3..027479dcbf43 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -118,10 +118,10 @@ extern void _set_L3CR(unsigned long); #endif extern void via_cuda_init(void); -extern void pmac_nvram_init(void); extern void read_rtc_time(void); extern void pmac_find_display(void); extern void giveup_fpu(struct task_struct *); +extern void disable_kernel_fp(void); extern void enable_kernel_fp(void); extern void flush_fp_to_thread(struct task_struct *); extern void enable_kernel_altivec(void); @@ -346,5 +346,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, #define arch_align_stack(x) (x) +extern unsigned long reloc_offset(void); + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_SYSTEM_H */ From eeb2d21806123a67d957783c4a0c8b020a378cf0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 30 Sep 2005 17:24:15 +1000 Subject: [PATCH 0186/1940] powerpc: make iSeries boot Now that we use the device tree, it helps to build it in. It helps to links the kernel at the correct address. Signed-off-by: Stephen Rothwell --- arch/powerpc/Kconfig | 4 ++-- arch/powerpc/Kconfig.debug | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7f891ebfbd85..34be3247fca4 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -317,7 +317,7 @@ config PPC_BPA config PPC_OF bool - depends on PPC_MULTIPLATFORM # for now + depends on PPC_MULTIPLATFORM || PPC_ISERIES default y config XICS @@ -836,7 +836,7 @@ endmenu if PPC64 config KERNEL_START hex - default "0xc0000000" + default "0xc000000000000000" endif source "net/Kconfig" diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 61653cb60c4e..19df881bf67b 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -55,7 +55,7 @@ config BDI_SWITCH config BOOTX_TEXT bool "Support for early boot text console (BootX or OpenFirmware only)" - depends PPC_OF + depends PPC_OF && !PPC_ISERIES help Say Y here to see progress messages from the boot firmware in text mode. Requires either BootX or Open Firmware. From ac17b8b57013a3e38d1958f66a218f15659e5752 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Mon, 3 Oct 2005 15:32:11 -0500 Subject: [PATCH 0187/1940] JFS: make special inodes play nicely with page balancing This patch fixes up a few problems with jfs's reserved inodes. 1. There is no need for the jfs code setting the I_DIRTY bits in i_state. I am ashamed that the code ever did this, and surprised it hasn't been noticed until now. 2. Make sure special inodes are on an inode hash list. If the inodes are unhashed, __mark_inode_dirty will fail to put the inode on the superblock's dirty list, and the data will not be flushed under memory pressure. 3. Force writing journal data to disk when metapage_writepage is unable to write a metadata page due to pending journal I/O. Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_dmap.c | 1 - fs/jfs/jfs_imap.c | 10 ++++++++-- fs/jfs/jfs_metapage.c | 6 ++++++ fs/jfs/jfs_txnmgr.c | 2 -- fs/jfs/super.c | 1 + 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index eadf319bee22..51c02bf07878 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap) filemap_fdatawrite(ipbmap->i_mapping); filemap_fdatawait(ipbmap->i_mapping); - ipbmap->i_state |= I_DIRTY; diWriteSpecial(ipbmap, 0); return (0); diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 4021d46da7e3..28201b194f53 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -56,6 +56,12 @@ #include "jfs_superblock.h" #include "jfs_debug.h" +/* + * __mark_inode_dirty expects inodes to be hashed. Since we don't want + * special inodes in the fileset inode space, we hash them to a dummy head + */ +static HLIST_HEAD(aggregate_hash); + /* * imap locks */ @@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) /* release the page */ release_metapage(mp); + hlist_add_head(&ip->i_hash, &aggregate_hash); + return (ip); } @@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, int secondary) ino_t inum = ip->i_ino; struct metapage *mp; - ip->i_state &= ~I_DIRTY; - if (secondary) address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage; else diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 13d7e3f1feb4..c81c6438fce5 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -395,6 +395,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) { redirty = 1; + /* + * Make sure this page isn't blocked indefinitely. + * If the journal isn't undergoing I/O, push it + */ + if (mp->log && !(mp->log->cflag & logGC_PAGEOUT)) + jfs_flush_journal(mp->log, 0); continue; } diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 9b71ed2674fe..b660c93c92de 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * tblk) */ if (tblk->xflag & COMMIT_CREATE) { diUpdatePMap(ipimap, tblk->ino, FALSE, tblk); - ipimap->i_state |= I_DIRTY; /* update persistent block allocation map * for the allocation of inode extent; */ @@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * tblk) } else if (tblk->xflag & COMMIT_DELETE) { ip = tblk->u.ip; diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); - ipimap->i_state |= I_DIRTY; iput(ip); } } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 71bc34b96b2b..4226af3ea91b 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_nlink = 1; inode->i_size = sb->s_bdev->bd_inode->i_size; inode->i_mapping->a_ops = &jfs_metapage_aops; + insert_inode_hash(inode); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); sbi->direct_inode = inode; From 3e84469d0101456caceffc6b22218a49017fcd3f Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 3 Oct 2005 13:37:24 -0700 Subject: [PATCH 0188/1940] [CIFS] Add writepages support to shrink memory usage on writes, eliminate the double copy, and improve cifs write performance and help the server by upping the typical write size from 4K to 16K (or even larger if wsize set explicitly) for servers which support this. Part 1 of 2 Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 5 +-- fs/cifs/cifssmb.c | 41 ++++++++----------- fs/cifs/connect.c | 4 ++ fs/cifs/file.c | 16 +++++--- fs/cifs/transport.c | 95 ++++++++++++++++++++++++++------------------- 5 files changed, 89 insertions(+), 72 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index dc5a6a6ff2f9..fb3e76043c50 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -48,8 +48,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, struct smb_hdr * /* out */ , int * /* bytes returned */ , const int long_op); extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, - struct smb_hdr * /* input */ , int hdr_len, - const char * /* SMB data to send */ , int data_len, + struct kvec *, int /* nvec */, int * /* bytes returned */ , const int long_op); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); @@ -241,7 +240,7 @@ extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, const int netfid, const unsigned int count, const __u64 offset, unsigned int *nbytes, - const char *buf,const int long_op); + struct kvec *iov, const int nvec, const int long_op); extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, __u64 * inode_number, const struct nls_table *nls_codepage, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 52caac063a77..365949c14646 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon , nls_codepage); up(&tcon->ses->sesSem); + /* BB FIXME add code to check if wsize needs + update due to negotiated smb buffer size + shrinking */ if(rc == 0) atomic_inc(&tconInfoReconnectCount); @@ -220,6 +223,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nls_codepage); up(&tcon->ses->sesSem); + /* BB FIXME add code to check if wsize needs + update due to negotiated smb buffer size + shrinking */ if(rc == 0) atomic_inc(&tconInfoReconnectCount); @@ -1128,15 +1134,13 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, const int netfid, const unsigned int count, - const __u64 offset, unsigned int *nbytes, const char *buf, - const int long_op) + const __u64 offset, unsigned int *nbytes, struct kvec *iov, + int n_vec, const int long_op) { int rc = -EACCES; WRITE_REQ *pSMB = NULL; int bytes_returned; int smb_hdr_len; - __u32 bytes_sent; - __u16 byte_count; cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); @@ -1154,31 +1158,20 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, pSMB->WriteMode = 0; pSMB->Remaining = 0; - /* Can increase buffer size if buffer is big enough in some cases - ie - can send more if LARGE_WRITE_X capability returned by the server and if - our buffer is big enough or if we convert to iovecs on socket writes - and eliminate the copy to the CIFS buffer */ - if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) { - bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); - } else { - bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) - & ~0xFF; - } - - if (bytes_sent > count) - bytes_sent = count; pSMB->DataOffset = cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); - byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */ - pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); - pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); + pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); + pSMB->DataLengthHigh = cpu_to_le16(count >> 16); smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ - pSMB->hdr.smb_buf_length += bytes_sent+1; - pSMB->ByteCount = cpu_to_le16(byte_count); + pSMB->hdr.smb_buf_length += count+1; + pSMB->ByteCount = cpu_to_le16(count + 1); - rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len, - buf, bytes_sent, &bytes_returned, long_op); + iov[0].iov_base = pSMB; + iov[0].iov_len = smb_hdr_len + 4; + + rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned, + long_op); cifs_stats_inc(&tcon->num_writes); if (rc) { cFYI(1, ("Send error in write = %d", rc)); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e27e5ad8b591..f05d9e2016d5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1891,6 +1891,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, } } } + if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) + cifs_sb->wsize = min(cifs_sb->wsize, + (tcon->ses->server->maxBuf - + MAX_CIFS_HDR_SIZE)); } /* volume_info.password is freed above when existing session found diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 3766db2bb7f2..941108352547 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -849,13 +849,19 @@ static ssize_t cifs_write(struct file *file, const char *write_data, /* BB FIXME We can not sign across two buffers yet */ if((experimEnabled) && ((pTcon->ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) { + struct kvec iov[2]; + unsigned int len; + + len = min(cifs_sb->wsize, + write_size - total_written); + /* iov[0] is reserved for smb header */ + iov[1].iov_base = (char *)write_data + + total_written; + iov[1].iov_len = len; rc = CIFSSMBWrite2(xid, pTcon, - open_file->netfid, - min_t(const int, cifs_sb->wsize, - write_size - total_written), + open_file->netfid, len, *poffset, &bytes_written, - write_data + total_written, - long_op); + iov, 1, long_op); } else /* BB FIXME fixup indentation of line below */ #endif diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 9e8e85a8d186..38b3b2463ae4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -147,16 +147,19 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, Flags2 is converted in SendReceive */ smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); - cFYI(1, ("Sending smb of length %d ", smb_buf_length)); + cFYI(1, ("Sending smb of length %d", smb_buf_length)); dump_smb(smb_buffer, len); while (len > 0) { rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; - if(i > 60) { + /* smaller timeout here than send2 since smaller size */ + /* Although it may not be required, this also is smaller + oplock break time */ + if(i > 30) { cERROR(1, - ("sends on sock %p stuck for 30 seconds", + ("sends on sock %p stuck for 15 seconds", ssocket)); rc = -EAGAIN; break; @@ -172,7 +175,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, } if (rc < 0) { - cERROR(1,("Error %d sending data on socket to server.", rc)); + cERROR(1,("Error %d sending data on socket to server", rc)); } else { rc = 0; } @@ -182,22 +185,20 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, #ifdef CONFIG_CIFS_EXPERIMENTAL static int -smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, - unsigned int smb_hdr_length, const char * data, unsigned int datalen, - struct sockaddr *sin) +smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, + struct sockaddr *sin) { int rc = 0; int i = 0; struct msghdr smb_msg; - struct kvec iov[2]; - unsigned len = smb_hdr_length + 4; + struct smb_hdr *smb_buffer = iov[0].iov_base; + unsigned int len = iov[0].iov_len; + unsigned int total_len; + int first_vec = 0; if(ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ - iov[0].iov_base = smb_buffer; - iov[0].iov_len = len; - iov[1].iov_base = data; - iov[1].iov_len = datalen; + smb_msg.msg_name = sin; smb_msg.msg_namelen = sizeof (struct sockaddr); smb_msg.msg_control = NULL; @@ -209,18 +210,23 @@ smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, cifssmb.c and RFC1001 len is converted to bigendian in smb_send Flags2 is converted in SendReceive */ + + total_len = 0; + for (i = 0; i < n_vec; i++) + total_len += iov[i].iov_len; + smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); - cFYI(1, ("Sending smb: hdrlen %d datalen %d", - smb_hdr_length,datalen)); + cFYI(1, ("Sending smb: total_len %d", total_len)); dump_smb(smb_buffer, len); - while (len + datalen > 0) { - rc = kernel_sendmsg(ssocket, &smb_msg, iov, 2, len); + while (total_len) { + rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], + n_vec - first_vec, total_len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; - if(i > 60) { + if(i > 40) { cERROR(1, - ("sends on sock %p stuck for 30 seconds", + ("sends on sock %p stuck for 20 seconds", ssocket)); rc = -EAGAIN; break; @@ -230,43 +236,52 @@ smb_send2(struct socket *ssocket, struct smb_hdr *smb_buffer, } if (rc < 0) break; - if(iov[0].iov_len > 0) { - if(rc >= len) { - iov[0].iov_len = 0; - rc -= len; - len = 0; - } else { /* some of hdr was not sent */ - len -= rc; - iov[0].iov_len -= rc; - iov[0].iov_base += rc; - continue; - } + + if (rc >= total_len) { + WARN_ON(rc > total_len); + break; } - if((iov[0].iov_len == 0) && (rc > 0)){ - iov[1].iov_base += rc; - iov[1].iov_len -= rc; - datalen -= rc; + if(rc == 0) { + /* should never happen, letting socket clear before + retrying is our only obvious option here */ + cERROR(1,("tcp sent no data"); + msleep(500); + continue; + } + total_len -= rc; + for (i = first_vec; i < n_vec; i++) { + if (iov[i].iov_len) { + if (rc > iov[i].iov_len) { + rc -= iov[i].iov_len; + iov[i].iov_len = 0; + } else { + iov[i].iov_base += rc; + iov[i].iov_len -= rc; + first_vec = i; + break; + } + } } } if (rc < 0) { - cERROR(1,("Error %d sending data on socket to server.", rc)); - } else { + cERROR(1,("Error %d sending data on socket to server", rc)); + } else rc = 0; - } return rc; } int SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, - struct smb_hdr *in_buf, int hdrlen, const char * data, - int datalen, int *pbytes_returned, const int long_op) + struct kvec *iov, int n_vec, int *pbytes_returned, + const int long_op) { int rc = 0; unsigned int receive_len; unsigned long timeout; struct mid_q_entry *midQ; + struct smb_hdr *in_buf = iov[0].iov_base; if (ses == NULL) { cERROR(1,("Null smb session")); @@ -364,7 +379,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, /* rc = cifs_sign_smb2(in_buf, data, ses->server, &midQ->sequence_number); */ midQ->midState = MID_REQUEST_SUBMITTED; - rc = smb_send2(ses->server->ssocket, in_buf, hdrlen, data, datalen, + rc = smb_send2(ses->server->ssocket, iov, n_vec, (struct sockaddr *) &(ses->server->addr.sockAddr)); if(rc < 0) { DeleteMidQEntry(midQ); From 8cc64c6ecfef020d40829f3e1152aab006c13899 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 3 Oct 2005 13:49:43 -0700 Subject: [PATCH 0189/1940] [CIFS] Allow SMBWrite2 to work to older servers Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifssmb.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 365949c14646..41996a240149 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1139,11 +1139,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, { int rc = -EACCES; WRITE_REQ *pSMB = NULL; - int bytes_returned; + int bytes_returned, wct; int smb_hdr_len; cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ - rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); + if(tcon->ses->capabilities & CAP_LARGE_FILES) + wct = 14; + else + wct = 12; + rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); if (rc) return rc; /* tcon and ses pointer are checked in smb_init */ @@ -1153,7 +1157,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = netfid; pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); - pSMB->OffsetHigh = cpu_to_le32(offset >> 32); + if(wct == 14) + pSMB->OffsetHigh = cpu_to_le32(offset >> 32); + else if((offset >> 32) > 0) /* can not handle this big offset for old */ + return -EIO; pSMB->Reserved = 0xFFFFFFFF; pSMB->WriteMode = 0; pSMB->Remaining = 0; @@ -1164,9 +1171,17 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); pSMB->DataLengthHigh = cpu_to_le16(count >> 16); smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ - pSMB->hdr.smb_buf_length += count+1; - pSMB->ByteCount = cpu_to_le16(count + 1); - + if(wct == 14) + pSMB->hdr.smb_buf_length += count+1; + else /* wct == 12 */ + pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ + if(wct == 14) + pSMB->ByteCount = cpu_to_le16(count + 1); + else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { + struct smb_com_writex_req * pSMBW = + (struct smb_com_writex_req *)pSMB; + pSMBW->ByteCount = cpu_to_le16(count + 5); + } iov[0].iov_base = pSMB; iov[0].iov_len = smb_hdr_len + 4; @@ -1174,7 +1189,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, long_op); cifs_stats_inc(&tcon->num_writes); if (rc) { - cFYI(1, ("Send error in write = %d", rc)); + cFYI(1, ("Send error Write2 = %d", rc)); *nbytes = 0; } else { WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB; From 04c08816d693f010ce14b8f408c6228600053af0 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 3 Oct 2005 19:33:15 -0700 Subject: [PATCH 0190/1940] [CIFS] Missing parenthesis from error message in previous fix Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 38b3b2463ae4..64c712629f27 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -244,7 +244,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, if(rc == 0) { /* should never happen, letting socket clear before retrying is our only obvious option here */ - cERROR(1,("tcp sent no data"); + cERROR(1,("tcp sent no data")); msleep(500); continue; } From dd8cad6be2822c7df4ecc5eba12903ba43e09f06 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 4 Oct 2005 14:28:29 +1000 Subject: [PATCH 0191/1940] ppc32: export a few more things where they are defined ... and remove the exports from ppc_ksyms.c. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/pci.c | 3 +++ arch/ppc/kernel/ppc_ksyms.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 2d3c557538b5..b5cf52f5909e 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -813,12 +813,14 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) /* Now, lookup childs of the hose */ return scan_OF_childs_for_device(node->child, busnr, devfn); } +EXPORT_SYMBOL(pci_busdev_to_OF_node); struct device_node* pci_device_to_OF_node(struct pci_dev *dev) { return pci_busdev_to_OF_node(dev->bus, dev->devfn); } +EXPORT_SYMBOL(pci_device_to_OF_node); /* This routine is meant to be used early during boot, when the * PCI bus numbers have not yet been assigned, and you need to @@ -890,6 +892,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) } return -ENODEV; } +EXPORT_SYMBOL(pci_device_from_OF_node); void __init pci_process_bridge_OF_ranges(struct pci_controller *hose, diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 7872c6c45732..f4373fb9181f 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -230,9 +230,6 @@ EXPORT_SYMBOL(find_all_nodes); EXPORT_SYMBOL(get_property); EXPORT_SYMBOL(request_OF_resource); EXPORT_SYMBOL(release_OF_resource); -EXPORT_SYMBOL(pci_busdev_to_OF_node); -EXPORT_SYMBOL(pci_device_to_OF_node); -EXPORT_SYMBOL(pci_device_from_OF_node); EXPORT_SYMBOL(of_find_node_by_name); EXPORT_SYMBOL(of_find_node_by_type); EXPORT_SYMBOL(of_find_compatible_node); From 6ce52e6438fd2921891648ceab700d9b867e5ed2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 4 Oct 2005 14:30:07 +1000 Subject: [PATCH 0192/1940] ppc32: remove obsolete klock_info definition klock_info isn't used or referenced anywhere else in the kernel. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/smp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 726fe7ce1747..a8cc96b0d332 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -38,7 +38,6 @@ volatile int smp_commenced; int smp_tb_synchronized; struct cpuinfo_PPC cpu_data[NR_CPUS]; -struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; atomic_t ipi_recv; atomic_t ipi_sent; cpumask_t cpu_online_map; From fd9d63678d42ffd4312815ac720a12920642eb36 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 13:44:48 +0100 Subject: [PATCH 0193/1940] NTFS: Change ntfs_map_runlist_nolock() to also take an optional attribute search context. This allows calling it with the mft record mapped. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 5 + fs/ntfs/Makefile | 2 +- fs/ntfs/attrib.c | 232 +++++++++++++++++++++++++++++++++++++++------- fs/ntfs/attrib.h | 3 +- 4 files changed, 209 insertions(+), 33 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index de58579a1d0e..85f797a2edad 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -22,6 +22,11 @@ ToDo/Notes: - Enable the code for setting the NT4 compatibility flag when we start making NTFS 1.2 specific modifications. +2.1.25-WIP + + - Change ntfs_map_runlist_nolock() to also take an optional attribute + search context. This allows calling it with the mft record mapped. + 2.1.24 - Lots of bug fixes and support more clean journal states. - Support journals ($LogFile) which have been modified by chkdsk. This diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index 894b2b876d35..a3ce2c0e7dd9 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25-WIP\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 3f9a4ff42ee5..b194197b72f7 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -36,9 +36,27 @@ * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode * @ni: ntfs inode for which to map (part of) a runlist * @vcn: map runlist part containing this vcn + * @ctx: active attribute search context if present or NULL if not * * Map the part of a runlist containing the @vcn of the ntfs inode @ni. * + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when ntfs_map_runlist_nolock() encounters unmapped + * runlist fragments and allows their mapping. If you do not have the mft + * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock() + * will perform the necessary mapping and unmapping. + * + * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and + * restores it before returning. Thus, @ctx will be left pointing to the same + * attribute on return as on entry. However, the actual pointers in @ctx may + * point to different memory locations on return, so you must remember to reset + * any cached pointers from the @ctx, i.e. after the call to + * ntfs_map_runlist_nolock(), you will probably want to do: + * m = ctx->mrec; + * a = ctx->attr; + * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that + * you cache ctx->mrec in a variable @m of type MFT_RECORD *. + * * Return 0 on success and -errno on error. There is one special error code * which is not an error as such. This is -ENOENT. It means that @vcn is out * of bounds of the runlist. @@ -46,19 +64,32 @@ * Note the runlist can be NULL after this function returns if @vcn is zero and * the attribute has zero allocated size, i.e. there simply is no runlist. * - * Locking: - The runlist must be locked for writing. - * - This function modifies the runlist. + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * is no longer valid, i.e. you need to either call + * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. + * In that case PTR_ERR(@ctx->mrec) will give you the error code for + * why the mapping of the old inode failed. + * + * Locking: - The runlist described by @ni must be locked for writing on entry + * and is locked on return. Note the runlist will be modified. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. */ -int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) +int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) { VCN end_vcn; + unsigned long flags; ntfs_inode *base_ni; MFT_RECORD *m; ATTR_RECORD *a; - ntfs_attr_search_ctx *ctx; runlist_element *rl; - unsigned long flags; + struct page *put_this_page = NULL; int err = 0; + BOOL ctx_is_temporary, ctx_needs_reset; + ntfs_attr_search_ctx old_ctx; ntfs_debug("Mapping runlist part containing vcn 0x%llx.", (unsigned long long)vcn); @@ -66,20 +97,77 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) base_ni = ni; else base_ni = ni->ext.base_ntfs_ino; - m = map_mft_record(base_ni); - if (IS_ERR(m)) - return PTR_ERR(m); - ctx = ntfs_attr_get_search_ctx(base_ni, m); - if (unlikely(!ctx)) { - err = -ENOMEM; - goto err_out; + if (!ctx) { + ctx_is_temporary = ctx_needs_reset = TRUE; + m = map_mft_record(base_ni); + if (IS_ERR(m)) + return PTR_ERR(m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + } else { + VCN allocated_size_vcn; + + BUG_ON(IS_ERR(ctx->mrec)); + a = ctx->attr; + BUG_ON(!a->non_resident); + ctx_is_temporary = FALSE; + end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); + read_lock_irqsave(&ni->size_lock, flags); + allocated_size_vcn = ni->allocated_size >> + ni->vol->cluster_size_bits; + read_unlock_irqrestore(&ni->size_lock, flags); + if (!a->data.non_resident.lowest_vcn && end_vcn <= 0) + end_vcn = allocated_size_vcn - 1; + /* + * If we already have the attribute extent containing @vcn in + * @ctx, no need to look it up again. We slightly cheat in + * that if vcn exceeds the allocated size, we will refuse to + * map the runlist below, so there is definitely no need to get + * the right attribute extent. + */ + if (vcn >= allocated_size_vcn || (a->type == ni->type && + a->name_length == ni->name_len && + !memcmp((u8*)a + le16_to_cpu(a->name_offset), + ni->name, ni->name_len) && + sle64_to_cpu(a->data.non_resident.lowest_vcn) + <= vcn && end_vcn >= vcn)) + ctx_needs_reset = FALSE; + else { + /* Save the old search context. */ + old_ctx = *ctx; + /* + * If the currently mapped (extent) inode is not the + * base inode we will unmap it when we reinitialize the + * search context which means we need to get a + * reference to the page containing the mapped mft + * record so we do not accidentally drop changes to the + * mft record when it has not been marked dirty yet. + */ + if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino != + old_ctx.base_ntfs_ino) { + put_this_page = old_ctx.ntfs_ino->page; + page_cache_get(put_this_page); + } + /* + * Reinitialize the search context so we can lookup the + * needed attribute extent. + */ + ntfs_attr_reinit_search_ctx(ctx); + ctx_needs_reset = TRUE; + } } - err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, vcn, NULL, 0, ctx); - if (unlikely(err)) { - if (err == -ENOENT) - err = -EIO; - goto err_out; + if (ctx_needs_reset) { + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, vcn, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + BUG_ON(!ctx->attr->non_resident); } a = ctx->attr; /* @@ -89,11 +177,9 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) * ntfs_mapping_pairs_decompress() fails. */ end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1; - if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) { - read_lock_irqsave(&ni->size_lock, flags); - end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits; - read_unlock_irqrestore(&ni->size_lock, flags); - } + if (!a->data.non_resident.lowest_vcn && end_vcn == 1) + end_vcn = sle64_to_cpu(a->data.non_resident.allocated_size) >> + ni->vol->cluster_size_bits; if (unlikely(vcn >= end_vcn)) { err = -ENOENT; goto err_out; @@ -104,9 +190,93 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) else ni->runlist.rl = rl; err_out: - if (likely(ctx)) - ntfs_attr_put_search_ctx(ctx); - unmap_mft_record(base_ni); + if (ctx_is_temporary) { + if (likely(ctx)) + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + } else if (ctx_needs_reset) { + /* + * If there is no attribute list, restoring the search context + * is acomplished simply by copying the saved context back over + * the caller supplied context. If there is an attribute list, + * things are more complicated as we need to deal with mapping + * of mft records and resulting potential changes in pointers. + */ + if (NInoAttrList(base_ni)) { + /* + * If the currently mapped (extent) inode is not the + * one we had before, we need to unmap it and map the + * old one. + */ + if (ctx->ntfs_ino != old_ctx.ntfs_ino) { + /* + * If the currently mapped inode is not the + * base inode, unmap it. + */ + if (ctx->base_ntfs_ino && ctx->ntfs_ino != + ctx->base_ntfs_ino) { + unmap_extent_mft_record(ctx->ntfs_ino); + ctx->mrec = ctx->base_mrec; + BUG_ON(!ctx->mrec); + } + /* + * If the old mapped inode is not the base + * inode, map it. + */ + if (old_ctx.base_ntfs_ino && + old_ctx.ntfs_ino != + old_ctx.base_ntfs_ino) { +retry_map: + ctx->mrec = map_mft_record( + old_ctx.ntfs_ino); + /* + * Something bad has happened. If out + * of memory retry till it succeeds. + * Any other errors are fatal and we + * return the error code in ctx->mrec. + * Let the caller deal with it... We + * just need to fudge things so the + * caller can reinit and/or put the + * search context safely. + */ + if (IS_ERR(ctx->mrec)) { + if (PTR_ERR(ctx->mrec) == + -ENOMEM) { + schedule(); + goto retry_map; + } else + old_ctx.ntfs_ino = + old_ctx. + base_ntfs_ino; + } + } + } + /* Update the changed pointers in the saved context. */ + if (ctx->mrec != old_ctx.mrec) { + if (!IS_ERR(ctx->mrec)) + old_ctx.attr = (ATTR_RECORD*)( + (u8*)ctx->mrec + + ((u8*)old_ctx.attr - + (u8*)old_ctx.mrec)); + old_ctx.mrec = ctx->mrec; + } + } + /* Restore the search context to the saved one. */ + *ctx = old_ctx; + /* + * We drop the reference on the page we took earlier. In the + * case that IS_ERR(ctx->mrec) is true this means we might lose + * some changes to the mft record that had been made between + * the last time it was marked dirty/written out and now. This + * at this stage is not a problem as the mapping error is fatal + * enough that the mft record cannot be written out anyway and + * the caller is very likely to shutdown the whole inode + * immediately and mark the volume dirty for chkdsk to pick up + * the pieces anyway. + */ + if (put_this_page) + page_cache_release(put_this_page); + } return err; } @@ -122,8 +292,8 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) * of bounds of the runlist. * * Locking: - The runlist must be unlocked on entry and is unlocked on return. - * - This function takes the runlist lock for writing and modifies the - * runlist. + * - This function takes the runlist lock for writing and may modify + * the runlist. */ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) { @@ -133,7 +303,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) /* Make sure someone else didn't do the work while we were sleeping. */ if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <= LCN_RL_NOT_MAPPED)) - err = ntfs_map_runlist_nolock(ni, vcn); + err = ntfs_map_runlist_nolock(ni, vcn, NULL); up_write(&ni->runlist.lock); return err; } @@ -212,7 +382,7 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, goto retry_remap; } } - err = ntfs_map_runlist_nolock(ni, vcn); + err = ntfs_map_runlist_nolock(ni, vcn, NULL); if (!write_locked) { up_write(&ni->runlist.lock); down_read(&ni->runlist.lock); @@ -325,7 +495,7 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, goto retry_remap; } } - err = ntfs_map_runlist_nolock(ni, vcn); + err = ntfs_map_runlist_nolock(ni, vcn, NULL); if (!write_locked) { up_write(&ni->runlist.lock); down_read(&ni->runlist.lock); diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index 0618ed6fd7b3..eeca8e500971 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -60,7 +60,8 @@ typedef struct { ATTR_RECORD *base_attr; } ntfs_attr_search_ctx; -extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn); +extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, + ntfs_attr_search_ctx *ctx); extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn); extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, From 69b41e3c0223bd38cf23e3d8f1385963089fbf22 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 14:01:14 +0100 Subject: [PATCH 0194/1940] NTFS: Change ntfs_attr_find_vcn_nolock() to also take an optional attribute search context as argument. This allows calling it with the mft record mapped. Update all callers. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 6 ++-- fs/ntfs/attrib.c | 84 ++++++++++++++++++++++++++-------------------- fs/ntfs/attrib.h | 2 +- fs/ntfs/lcnalloc.c | 4 +-- fs/ntfs/mft.c | 7 ++-- 5 files changed, 59 insertions(+), 44 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 85f797a2edad..0a361ddb3b45 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -24,8 +24,10 @@ ToDo/Notes: 2.1.25-WIP - - Change ntfs_map_runlist_nolock() to also take an optional attribute - search context. This allows calling it with the mft record mapped. + - Change ntfs_map_runlist_nolock() and ntfs_attr_find_vcn_nolock() to + also take an optional attribute search context as argument. This + allows calling these functions with the mft record mapped. Update + all callers. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index b194197b72f7..2aafc87e9601 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -406,9 +406,9 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, /** * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode - * @ni: ntfs inode describing the runlist to search - * @vcn: vcn to find - * @write_locked: true if the runlist is locked for writing + * @ni: ntfs inode describing the runlist to search + * @vcn: vcn to find + * @ctx: active attribute search context if present or NULL if not * * Find the virtual cluster number @vcn in the runlist described by the ntfs * inode @ni and return the address of the runlist element containing the @vcn. @@ -416,9 +416,22 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, * If the @vcn is not mapped yet, the attempt is made to map the attribute * extent containing the @vcn and the vcn to lcn conversion is retried. * - * If @write_locked is true the caller has locked the runlist for writing and - * if false for reading. + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped + * runlist fragments and allows their mapping. If you do not have the mft + * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock() + * will perform the necessary mapping and unmapping. * + * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and + * restores it before returning. Thus, @ctx will be left pointing to the same + * attribute on return as on entry. However, the actual pointers in @ctx may + * point to different memory locations on return, so you must remember to reset + * any cached pointers from the @ctx, i.e. after the call to + * ntfs_attr_find_vcn_nolock(), you will probably want to do: + * m = ctx->mrec; + * a = ctx->attr; + * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that + * you cache ctx->mrec in a variable @m of type MFT_RECORD *. * Note you need to distinguish between the lcn of the returned runlist element * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on * read and allocate clusters on write. @@ -433,22 +446,31 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, * -ENOMEM - Not enough memory to map runlist. * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). * - * Locking: - The runlist must be locked on entry and is left locked on return. - * - If @write_locked is FALSE, i.e. the runlist is locked for reading, - * the lock may be dropped inside the function so you cannot rely on - * the runlist still being the same when this function returns. + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * is no longer valid, i.e. you need to either call + * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. + * In that case PTR_ERR(@ctx->mrec) will give you the error code for + * why the mapping of the old inode failed. + * + * Locking: - The runlist described by @ni must be locked for writing on entry + * and is locked on return. Note the runlist may be modified when + * needed runlist fragments need to be mapped. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. */ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, - const BOOL write_locked) + ntfs_attr_search_ctx *ctx) { unsigned long flags; runlist_element *rl; int err = 0; BOOL is_retry = FALSE; - ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", - ni->mft_no, (unsigned long long)vcn, - write_locked ? "write" : "read"); + ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.", + ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out"); BUG_ON(!ni); BUG_ON(!NInoNonResident(ni)); BUG_ON(vcn < 0); @@ -482,33 +504,22 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, } if (!err && !is_retry) { /* - * The @vcn is in an unmapped region, map the runlist and - * retry. + * If the search context is invalid we cannot map the unmapped + * region. */ - if (!write_locked) { - up_read(&ni->runlist.lock); - down_write(&ni->runlist.lock); - if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) != - LCN_RL_NOT_MAPPED)) { - up_write(&ni->runlist.lock); - down_read(&ni->runlist.lock); + if (IS_ERR(ctx->mrec)) + err = PTR_ERR(ctx->mrec); + else { + /* + * The @vcn is in an unmapped region, map the runlist + * and retry. + */ + err = ntfs_map_runlist_nolock(ni, vcn, ctx); + if (likely(!err)) { + is_retry = TRUE; goto retry_remap; } } - err = ntfs_map_runlist_nolock(ni, vcn, NULL); - if (!write_locked) { - up_write(&ni->runlist.lock); - down_read(&ni->runlist.lock); - } - if (likely(!err)) { - is_retry = TRUE; - goto retry_remap; - } - /* - * -EINVAL coming from a failed mapping attempt is equivalent - * to i/o error for us as it should not happen in our code - * paths. - */ if (err == -EINVAL) err = -EIO; } else if (!err) @@ -1181,6 +1192,7 @@ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name, ntfs_inode *base_ni; ntfs_debug("Entering."); + BUG_ON(IS_ERR(ctx->mrec)); if (ctx->base_ntfs_ino) base_ni = ctx->base_ntfs_ino; else diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index eeca8e500971..62f76258d9c3 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -68,7 +68,7 @@ extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, const BOOL write_locked); extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, - const VCN vcn, const BOOL write_locked); + const VCN vcn, ntfs_attr_search_ctx *ctx); int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 5af3bf0b7eee..8e60c47fafac 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -839,7 +839,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, total_freed = real_freed = 0; - rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE); + rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, NULL); if (IS_ERR(rl)) { if (!is_rollback) ntfs_error(vol->sb, "Failed to find first runlist " @@ -893,7 +893,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, /* Attempt to map runlist. */ vcn = rl->vcn; - rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE); + rl = ntfs_attr_find_vcn_nolock(ni, vcn, NULL); if (IS_ERR(rl)) { err = PTR_ERR(rl); if (!is_rollback) diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index b011369b5956..15df34f62038 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) ntfs_volume *vol = ni->vol; struct inode *mft_vi = vol->mft_ino; struct page *page; - unsigned long index, ofs, end_index; + unsigned long index, end_index; + unsigned ofs; BUG_ON(ni->page); /* @@ -1308,7 +1309,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) ll = mftbmp_ni->allocated_size; read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, - (ll - 1) >> vol->cluster_size_bits, TRUE); + (ll - 1) >> vol->cluster_size_bits, NULL); if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { up_write(&mftbmp_ni->runlist.lock); ntfs_error(vol->sb, "Failed to determine last allocated " @@ -1738,7 +1739,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ll = mft_ni->allocated_size; read_unlock_irqrestore(&mft_ni->size_lock, flags); rl = ntfs_attr_find_vcn_nolock(mft_ni, - (ll - 1) >> vol->cluster_size_bits, TRUE); + (ll - 1) >> vol->cluster_size_bits, NULL); if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { up_write(&mft_ni->runlist.lock); ntfs_error(vol->sb, "Failed to determine last allocated " From 511bea5ea2b2b330e67c9e58ffb5027caebf9052 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 14:24:21 +0100 Subject: [PATCH 0195/1940] NTFS: - Change {__,}ntfs_cluster_free() to also take an optional attribute search context as argument. This allows calling it with the mft record mapped. Update all callers. - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock() error handling by passing in the active search context when calling ntfs_cluster_free(). Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 11 +++++++---- fs/ntfs/lcnalloc.c | 41 +++++++++++++++++++++++++++++++++++------ fs/ntfs/lcnalloc.h | 40 +++++++++++++++++++++++++++++++++++----- fs/ntfs/mft.c | 13 +++++++++---- 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 0a361ddb3b45..6e4f44eed6fa 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -24,10 +24,13 @@ ToDo/Notes: 2.1.25-WIP - - Change ntfs_map_runlist_nolock() and ntfs_attr_find_vcn_nolock() to - also take an optional attribute search context as argument. This - allows calling these functions with the mft record mapped. Update - all callers. + - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and + {__,}ntfs_cluster_free() to also take an optional attribute search + context as argument. This allows calling these functions with the + mft record mapped. Update all callers. + - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock() + error handling by passing in the active search context when calling + ntfs_cluster_free(). 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 8e60c47fafac..75313f4307e3 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -782,6 +782,7 @@ switch_to_data1_zone: search_zone = 2; * @ni: ntfs inode whose runlist describes the clusters to free * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters * @count: number of clusters to free or -1 for all clusters + * @ctx: active attribute search context if present or NULL if not * @is_rollback: true if this is a rollback operation * * Free @count clusters starting at the cluster @start_vcn in the runlist @@ -791,15 +792,39 @@ switch_to_data1_zone: search_zone = 2; * deallocated. Thus, to completely free all clusters in a runlist, use * @start_vcn = 0 and @count = -1. * + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when __ntfs_cluster_free() encounters unmapped + * runlist fragments and allows their mapping. If you do not have the mft + * record mapped, you can specify @ctx as NULL and __ntfs_cluster_free() will + * perform the necessary mapping and unmapping. + * + * Note, __ntfs_cluster_free() saves the state of @ctx on entry and restores it + * before returning. Thus, @ctx will be left pointing to the same attribute on + * return as on entry. However, the actual pointers in @ctx may point to + * different memory locations on return, so you must remember to reset any + * cached pointers from the @ctx, i.e. after the call to __ntfs_cluster_free(), + * you will probably want to do: + * m = ctx->mrec; + * a = ctx->attr; + * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that + * you cache ctx->mrec in a variable @m of type MFT_RECORD *. + * * @is_rollback should always be FALSE, it is for internal use to rollback * errors. You probably want to use ntfs_cluster_free() instead. * - * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller - * has to deal with it later. + * Note, __ntfs_cluster_free() does not modify the runlist, so you have to + * remove from the runlist or mark sparse the freed runs later. * * Return the number of deallocated clusters (not counting sparse ones) on * success and -errno on error. * + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * is no longer valid, i.e. you need to either call + * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. + * In that case PTR_ERR(@ctx->mrec) will give you the error code for + * why the mapping of the old inode failed. + * * Locking: - The runlist described by @ni must be locked for writing on entry * and is locked on return. Note the runlist may be modified when * needed runlist fragments need to be mapped. @@ -807,9 +832,13 @@ switch_to_data1_zone: search_zone = 2; * on return. * - This function takes the volume lcn bitmap lock for writing and * modifies the bitmap contents. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. */ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, - const BOOL is_rollback) + ntfs_attr_search_ctx *ctx, const BOOL is_rollback) { s64 delta, to_free, total_freed, real_freed; ntfs_volume *vol; @@ -839,7 +868,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, total_freed = real_freed = 0; - rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, NULL); + rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, ctx); if (IS_ERR(rl)) { if (!is_rollback) ntfs_error(vol->sb, "Failed to find first runlist " @@ -893,7 +922,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, /* Attempt to map runlist. */ vcn = rl->vcn; - rl = ntfs_attr_find_vcn_nolock(ni, vcn, NULL); + rl = ntfs_attr_find_vcn_nolock(ni, vcn, ctx); if (IS_ERR(rl)) { err = PTR_ERR(rl); if (!is_rollback) @@ -961,7 +990,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, * If rollback fails, set the volume errors flag, emit an error * message, and return the error code. */ - delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE); + delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE); if (delta < 0) { ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " "inconsistent metadata! Unmount and run " diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h index a6a8827882e7..aa0518509cd3 100644 --- a/fs/ntfs/lcnalloc.h +++ b/fs/ntfs/lcnalloc.h @@ -27,6 +27,7 @@ #include +#include "attrib.h" #include "types.h" #include "inode.h" #include "runlist.h" @@ -44,13 +45,14 @@ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const NTFS_CLUSTER_ALLOCATION_ZONES zone); extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, - s64 count, const BOOL is_rollback); + s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); /** * ntfs_cluster_free - free clusters on an ntfs volume * @ni: ntfs inode whose runlist describes the clusters to free * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters * @count: number of clusters to free or -1 for all clusters + * @ctx: active attribute search context if present or NULL if not * * Free @count clusters starting at the cluster @start_vcn in the runlist * described by the ntfs inode @ni. @@ -59,12 +61,36 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, * deallocated. Thus, to completely free all clusters in a runlist, use * @start_vcn = 0 and @count = -1. * - * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller - * has to deal with it later. + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when ntfs_cluster_free() encounters unmapped runlist + * fragments and allows their mapping. If you do not have the mft record + * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform + * the necessary mapping and unmapping. + * + * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it + * before returning. Thus, @ctx will be left pointing to the same attribute on + * return as on entry. However, the actual pointers in @ctx may point to + * different memory locations on return, so you must remember to reset any + * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(), + * you will probably want to do: + * m = ctx->mrec; + * a = ctx->attr; + * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that + * you cache ctx->mrec in a variable @m of type MFT_RECORD *. + * + * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove + * from the runlist or mark sparse the freed runs later. * * Return the number of deallocated clusters (not counting sparse ones) on * success and -errno on error. * + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * is no longer valid, i.e. you need to either call + * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. + * In that case PTR_ERR(@ctx->mrec) will give you the error code for + * why the mapping of the old inode failed. + * * Locking: - The runlist described by @ni must be locked for writing on entry * and is locked on return. Note the runlist may be modified when * needed runlist fragments need to be mapped. @@ -72,11 +98,15 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, * on return. * - This function takes the volume lcn bitmap lock for writing and * modifies the bitmap contents. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. */ static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, - s64 count) + s64 count, ntfs_attr_search_ctx *ctx) { - return __ntfs_cluster_free(ni, start_vcn, count, FALSE); + return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE); } extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 15df34f62038..5577fc6e190f 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -1952,20 +1952,21 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) NVolSetErrors(vol); return ret; } - a = ctx->attr; - a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); + ctx->attr->data.non_resident.highest_vcn = + cpu_to_sle64(old_last_vcn - 1); undo_alloc: - if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) { + if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) { ntfs_error(vol->sb, "Failed to free clusters from mft data " "attribute.%s", es); NVolSetErrors(vol); } + a = ctx->attr; if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) { ntfs_error(vol->sb, "Failed to truncate mft data attribute " "runlist.%s", es); NVolSetErrors(vol); } - if (mp_rebuilt) { + if (mp_rebuilt && !IS_ERR(ctx->mrec)) { if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( a->data.non_resident.mapping_pairs_offset), old_alen - le16_to_cpu( @@ -1982,6 +1983,10 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) } flush_dcache_mft_record_page(ctx->ntfs_ino); mark_mft_record_dirty(ctx->ntfs_ino); + } else if (IS_ERR(ctx->mrec)) { + ntfs_error(vol->sb, "Failed to restore attribute search " + "context.%s", es); + NVolSetErrors(vol); } if (ctx) ntfs_attr_put_search_ctx(ctx); From fc0fa7dc7d243afabdb3fb6a11d59a944a9c91f8 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 14:36:56 +0100 Subject: [PATCH 0196/1940] NTFS: - Change ntfs_cluster_alloc() to take an extra boolean parameter specifying whether the cluster are being allocated to extend an attribute or to fill a hole. - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() with @is_extension set to TRUE and remove the runlist terminator fixup code as this is now done by ntfs_cluster_alloc(). Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 6 ++++++ fs/ntfs/attrib.c | 10 +--------- fs/ntfs/lcnalloc.c | 15 ++++++++++++--- fs/ntfs/lcnalloc.h | 3 ++- fs/ntfs/mft.c | 6 ++++-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 6e4f44eed6fa..aad2a3f2d1f8 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -31,6 +31,12 @@ ToDo/Notes: - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock() error handling by passing in the active search context when calling ntfs_cluster_free(). + - Change ntfs_cluster_alloc() to take an extra boolean parameter + specifying whether the cluster are being allocated to extend an + attribute or to fill a hole. + - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() + with @is_extension set to TRUE and remove the runlist terminator + fixup code as this is now done by ntfs_cluster_alloc(). 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 2aafc87e9601..33e689f82a55 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -1566,8 +1566,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) new_size = (i_size_read(vi) + vol->cluster_size - 1) & ~(vol->cluster_size - 1); if (new_size > 0) { - runlist_element *rl2; - /* * Will need the page later and since the page lock nests * outside all ntfs locks, we need to get the page now. @@ -1578,7 +1576,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) return -ENOMEM; /* Start by allocating clusters to hold the attribute value. */ rl = ntfs_cluster_alloc(vol, 0, new_size >> - vol->cluster_size_bits, -1, DATA_ZONE); + vol->cluster_size_bits, -1, DATA_ZONE, TRUE); if (IS_ERR(rl)) { err = PTR_ERR(rl); ntfs_debug("Failed to allocate cluster%s, error code " @@ -1587,12 +1585,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) err); goto page_err_out; } - /* Change the runlist terminator to LCN_ENOENT. */ - rl2 = rl; - while (rl2->length) - rl2++; - BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED); - rl2->lcn = LCN_ENOENT; } else { rl = NULL; page = NULL; diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 75313f4307e3..29cabf93d2d2 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @count: number of clusters to allocate * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) * @zone: zone from which to allocate the clusters + * @is_extension: if TRUE, this is an attribute extension * * Allocate @count clusters preferably starting at cluster @start_lcn or at the * current allocator position if @start_lcn is -1, on the mounted ntfs volume @@ -86,6 +87,13 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @start_vcn specifies the vcn of the first allocated cluster. This makes * merging the resulting runlist with the old runlist easier. * + * If @is_extension is TRUE, the caller is allocating clusters to extend an + * attribute and if it is FALSE, the caller is allocating clusters to fill a + * hole in an attribute. Practically the difference is that if @is_extension + * is TRUE the returned runlist will be terminated with LCN_ENOENT and if + * @is_extension is FALSE the runlist will be terminated with + * LCN_RL_NOT_MAPPED. + * * You need to check the return value with IS_ERR(). If this is false, the * function was successful and the return value is a runlist describing the * allocated cluster(s). If IS_ERR() is true, the function failed and @@ -137,7 +145,8 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, */ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, - const NTFS_CLUSTER_ALLOCATION_ZONES zone) + const NTFS_CLUSTER_ALLOCATION_ZONES zone, + const BOOL is_extension) { LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; @@ -310,7 +319,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, continue; } bit = 1 << (lcn & 7); - ntfs_debug("bit %i.", bit); + ntfs_debug("bit 0x%x.", bit); /* If the bit is already set, go onto the next one. */ if (*byte & bit) { lcn++; @@ -729,7 +738,7 @@ switch_to_data1_zone: search_zone = 2; /* Add runlist terminator element. */ if (likely(rl)) { rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; - rl[rlpos].lcn = LCN_RL_NOT_MAPPED; + rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED; rl[rlpos].length = 0; } if (likely(page && !IS_ERR(page))) { diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h index aa0518509cd3..72cbca7003b2 100644 --- a/fs/ntfs/lcnalloc.h +++ b/fs/ntfs/lcnalloc.h @@ -42,7 +42,8 @@ typedef enum { extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, - const NTFS_CLUSTER_ALLOCATION_ZONES zone); + const NTFS_CLUSTER_ALLOCATION_ZONES zone, + const BOOL is_extension); extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 5577fc6e190f..0c65cbb8c5cf 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -1355,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) up_write(&vol->lcnbmp_lock); ntfs_unmap_page(page); /* Allocate a cluster from the DATA_ZONE. */ - rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE); + rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE, + TRUE); if (IS_ERR(rl2)) { up_write(&mftbmp_ni->runlist.lock); ntfs_error(vol->sb, "Failed to allocate a cluster for " @@ -1780,7 +1781,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) nr > min_nr ? "default" : "minimal", (long long)nr); old_last_vcn = rl[1].vcn; do { - rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE); + rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE, + TRUE); if (likely(!IS_ERR(rl2))) break; if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { From 8925d4f0d3479b9c5ed7e49acc648beccca95f21 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 14:48:20 +0100 Subject: [PATCH 0197/1940] NTFS: Change ntfs_attr_make_non_resident to take the attribute value size as an extra parameter. This is needed since we need to know the size before we can map the mft record and our callers always know it. The reason we cannot simply read the size from the vfs inode i_size is that this is not necessarily uptodate. This happens when ntfs_attr_make_non_resident() is called in the ->truncate call path. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 6 ++++++ fs/ntfs/attrib.c | 13 ++++++++++--- fs/ntfs/attrib.h | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index aad2a3f2d1f8..60ba3c5cb2ea 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -37,6 +37,12 @@ ToDo/Notes: - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() with @is_extension set to TRUE and remove the runlist terminator fixup code as this is now done by ntfs_cluster_alloc(). + - Change ntfs_attr_make_non_resident to take the attribute value size + as an extra parameter. This is needed since we need to know the size + before we can map the mft record and our callers always know it. The + reason we cannot simply read the size from the vfs inode i_size is + that this is not necessarily uptodate. This happens when + ntfs_attr_make_non_resident() is called in the ->truncate call path. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 33e689f82a55..380f70a5f2e1 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -1501,10 +1501,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, /** * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute * @ni: ntfs inode describing the attribute to convert + * @data_size: size of the resident data to copy to the non-resident attribute * * Convert the resident ntfs attribute described by the ntfs inode @ni to a * non-resident one. * + * @data_size must be equal to the attribute value size. This is needed since + * we need to know the size before we can map the mft record and our callers + * always know it. The reason we cannot simply read the size from the vfs + * inode i_size is that this is not necessarily uptodate. This happens when + * ntfs_attr_make_non_resident() is called in the ->truncate call path(s). + * * Return 0 on success and -errno on error. The following error return codes * are defined: * -EPERM - The attribute is not allowed to be non-resident. @@ -1525,7 +1532,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, * * Locking: - The caller must hold i_sem on the inode. */ -int ntfs_attr_make_non_resident(ntfs_inode *ni) +int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) { s64 new_size; struct inode *vi = VFS_I(ni); @@ -1563,7 +1570,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) * The size needs to be aligned to a cluster boundary for allocation * purposes. */ - new_size = (i_size_read(vi) + vol->cluster_size - 1) & + new_size = (data_size + vol->cluster_size - 1) & ~(vol->cluster_size - 1); if (new_size > 0) { /* @@ -1647,7 +1654,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) * attribute value. */ attr_size = le32_to_cpu(a->data.resident.value_length); - BUG_ON(attr_size != i_size_read(vi)); + BUG_ON(attr_size != data_size); if (page && !PageUptodate(page)) { kaddr = kmap_atomic(page, KM_USER0); memcpy(kaddr, (u8*)a + diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index 62f76258d9c3..a959af9cef12 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -103,7 +103,7 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size); extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, const u32 new_size); -extern int ntfs_attr_make_non_resident(ntfs_inode *ni); +extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size); extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val); From 2a6fc4e1b0f7d2ec3711d5b1782fb30f78cca765 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 14:57:15 +0100 Subject: [PATCH 0198/1940] NTFS: Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks which is zero for a resident attribute but should no longer be zero once the attribute is non-resident as it then has real clusters allocated. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 4 ++++ fs/ntfs/attrib.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 60ba3c5cb2ea..045beda82942 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -43,6 +43,10 @@ ToDo/Notes: reason we cannot simply read the size from the vfs inode i_size is that this is not necessarily uptodate. This happens when ntfs_attr_make_non_resident() is called in the ->truncate call path. + - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks + which is zero for a resident attribute but should no longer be zero + once the attribute is non-resident as it then has real clusters + allocated. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 380f70a5f2e1..8821e2d088b7 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -1719,7 +1719,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) ffs(ni->itype.compressed.block_size) - 1; ni->itype.compressed.block_clusters = 1U << a->data.non_resident.compression_unit; - } + vi->i_blocks = ni->itype.compressed.size >> 9; + } else + vi->i_blocks = ni->allocated_size >> 9; write_unlock_irqrestore(&ni->size_lock, flags); /* * This needs to be last since the address space operations ->readpage From 2d86829b846d1447a6ab5af4060fc9f301521317 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 15:18:56 +0100 Subject: [PATCH 0199/1940] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to extend the allocation of an attributes. Optionally, the data size, but not the initialized size can be extended, too. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 3 + fs/ntfs/attrib.c | 634 ++++++++++++++++++++++++++++++++++++++++++++++ fs/ntfs/attrib.h | 3 + 3 files changed, 640 insertions(+) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 045beda82942..6c5bdfbb7bbf 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -47,6 +47,9 @@ ToDo/Notes: which is zero for a resident attribute but should no longer be zero once the attribute is non-resident as it then has real clusters allocated. + - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to + extend the allocation of an attributes. Optionally, the data size, + but not the initialized size can be extended, too. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 8821e2d088b7..bc25e88ad468 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -1834,6 +1834,640 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) return err; } +/** + * ntfs_attr_extend_allocation - extend the allocated space of an attribute + * @ni: ntfs inode of the attribute whose allocation to extend + * @new_alloc_size: new size in bytes to which to extend the allocation to + * @new_data_size: new size in bytes to which to extend the data to + * @data_start: beginning of region which is required to be non-sparse + * + * Extend the allocated space of an attribute described by the ntfs inode @ni + * to @new_alloc_size bytes. If @data_start is -1, the whole extension may be + * implemented as a hole in the file (as long as both the volume and the ntfs + * inode @ni have sparse support enabled). If @data_start is >= 0, then the + * region between the old allocated size and @data_start - 1 may be made sparse + * but the regions between @data_start and @new_alloc_size must be backed by + * actual clusters. + * + * If @new_data_size is -1, it is ignored. If it is >= 0, then the data size + * of the attribute is extended to @new_data_size. Note that the i_size of the + * vfs inode is not updated. Only the data size in the base attribute record + * is updated. The caller has to update i_size separately if this is required. + * WARNING: It is a BUG() for @new_data_size to be smaller than the old data + * size as well as for @new_data_size to be greater than @new_alloc_size. + * + * For resident attributes this involves resizing the attribute record and if + * necessary moving it and/or other attributes into extent mft records and/or + * converting the attribute to a non-resident attribute which in turn involves + * extending the allocation of a non-resident attribute as described below. + * + * For non-resident attributes this involves allocating clusters in the data + * zone on the volume (except for regions that are being made sparse) and + * extending the run list to describe the allocated clusters as well as + * updating the mapping pairs array of the attribute. This in turn involves + * resizing the attribute record and if necessary moving it and/or other + * attributes into extent mft records and/or splitting the attribute record + * into multiple extent attribute records. + * + * Also, the attribute list attribute is updated if present and in some of the + * above cases (the ones where extent mft records/attributes come into play), + * an attribute list attribute is created if not already present. + * + * Return the new allocated size on success and -errno on error. In the case + * that an error is encountered but a partial extension at least up to + * @data_start (if present) is possible, the allocation is partially extended + * and this is returned. This means the caller must check the returned size to + * determine if the extension was partial. If @data_start is -1 then partial + * allocations are not performed. + * + * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA. + * + * Locking: This function takes the runlist lock of @ni for writing as well as + * locking the mft record of the base ntfs inode. These locks are maintained + * throughout execution of the function. These locks are required so that the + * attribute can be resized safely and so that it can for example be converted + * from resident to non-resident safely. + * + * TODO: At present attribute list attribute handling is not implemented. + * + * TODO: At present it is not safe to call this function for anything other + * than the $DATA attribute(s) of an uncompressed and unencrypted file. + */ +s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size, + const s64 new_data_size, const s64 data_start) +{ + VCN vcn; + s64 ll, allocated_size, start = data_start; + struct inode *vi = VFS_I(ni); + ntfs_volume *vol = ni->vol; + ntfs_inode *base_ni; + MFT_RECORD *m; + ATTR_RECORD *a; + ntfs_attr_search_ctx *ctx; + runlist_element *rl, *rl2; + unsigned long flags; + int err, mp_size; + u32 attr_len = 0; /* Silence stupid gcc warning. */ + BOOL mp_rebuilt; + +#ifdef NTFS_DEBUG + read_lock_irqsave(&ni->size_lock, flags); + allocated_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, " + "old_allocated_size 0x%llx, " + "new_allocated_size 0x%llx, new_data_size 0x%llx, " + "data_start 0x%llx.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), + (unsigned long long)allocated_size, + (unsigned long long)new_alloc_size, + (unsigned long long)new_data_size, + (unsigned long long)start); +#endif +retry_extend: + /* + * For non-resident attributes, @start and @new_size need to be aligned + * to cluster boundaries for allocation purposes. + */ + if (NInoNonResident(ni)) { + if (start > 0) + start &= ~(s64)vol->cluster_size_mask; + new_alloc_size = (new_alloc_size + vol->cluster_size - 1) & + ~(s64)vol->cluster_size_mask; + } + BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size); + /* Check if new size is allowed in $AttrDef. */ + err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size); + if (unlikely(err)) { + /* Only emit errors when the write will fail completely. */ + read_lock_irqsave(&ni->size_lock, flags); + allocated_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (start < 0 || start >= allocated_size) { + if (err == -ERANGE) { + ntfs_error(vol->sb, "Cannot extend allocation " + "of inode 0x%lx, attribute " + "type 0x%x, because the new " + "allocation would exceed the " + "maximum allowed size for " + "this attribute type.", + vi->i_ino, (unsigned) + le32_to_cpu(ni->type)); + } else { + ntfs_error(vol->sb, "Cannot extend allocation " + "of inode 0x%lx, attribute " + "type 0x%x, because this " + "attribute type is not " + "defined on the NTFS volume. " + "Possible corruption! You " + "should run chkdsk!", + vi->i_ino, (unsigned) + le32_to_cpu(ni->type)); + } + } + /* Translate error code to be POSIX conformant for write(2). */ + if (err == -ERANGE) + err = -EFBIG; + else + err = -EIO; + return err; + } + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + /* + * We will be modifying both the runlist (if non-resident) and the mft + * record so lock them both down. + */ + down_write(&ni->runlist.lock); + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + ctx = NULL; + goto err_out; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + read_lock_irqsave(&ni->size_lock, flags); + allocated_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + /* + * If non-resident, seek to the last extent. If resident, there is + * only one extent, so seek to that. + */ + vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits : + 0; + /* + * Abort if someone did the work whilst we waited for the locks. If we + * just converted the attribute from resident to non-resident it is + * likely that exactly this has happened already. We cannot quite + * abort if we need to update the data size. + */ + if (unlikely(new_alloc_size <= allocated_size)) { + ntfs_debug("Allocated size already exceeds requested size."); + new_alloc_size = allocated_size; + if (new_data_size < 0) + goto done; + /* + * We want the first attribute extent so that we can update the + * data size. + */ + vcn = 0; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, vcn, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + m = ctx->mrec; + a = ctx->attr; + /* Use goto to reduce indentation. */ + if (a->non_resident) + goto do_non_resident_extend; + BUG_ON(NInoNonResident(ni)); + /* The total length of the attribute value. */ + attr_len = le32_to_cpu(a->data.resident.value_length); + /* + * Extend the attribute record to be able to store the new attribute + * size. ntfs_attr_record_resize() will not do anything if the size is + * not changing. + */ + if (new_alloc_size < vol->mft_record_size && + !ntfs_attr_record_resize(m, a, + le16_to_cpu(a->data.resident.value_offset) + + new_alloc_size)) { + /* The resize succeeded! */ + write_lock_irqsave(&ni->size_lock, flags); + ni->allocated_size = le32_to_cpu(a->length) - + le16_to_cpu(a->data.resident.value_offset); + write_unlock_irqrestore(&ni->size_lock, flags); + if (new_data_size >= 0) { + BUG_ON(new_data_size < attr_len); + a->data.resident.value_length = + cpu_to_le32((u32)new_data_size); + } + goto flush_done; + } + /* + * We have to drop all the locks so we can call + * ntfs_attr_make_non_resident(). This could be optimised by try- + * locking the first page cache page and only if that fails dropping + * the locks, locking the page, and redoing all the locking and + * lookups. While this would be a huge optimisation, it is not worth + * it as this is definitely a slow code path. + */ + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); + /* + * Not enough space in the mft record, try to make the attribute + * non-resident and if successful restart the extension process. + */ + err = ntfs_attr_make_non_resident(ni, attr_len); + if (likely(!err)) + goto retry_extend; + /* + * Could not make non-resident. If this is due to this not being + * permitted for this attribute type or there not being enough space, + * try to make other attributes non-resident. Otherwise fail. + */ + if (unlikely(err != -EPERM && err != -ENOSPC)) { + /* Only emit errors when the write will fail completely. */ + read_lock_irqsave(&ni->size_lock, flags); + allocated_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation of " + "inode 0x%lx, attribute type 0x%x, " + "because the conversion from resident " + "to non-resident attribute failed " + "with error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + if (err != -ENOMEM) + err = -EIO; + goto conv_err_out; + } + /* TODO: Not implemented from here, abort. */ + read_lock_irqsave(&ni->size_lock, flags); + allocated_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (start < 0 || start >= allocated_size) { + if (err == -ENOSPC) + ntfs_error(vol->sb, "Not enough space in the mft " + "record/on disk for the non-resident " + "attribute value. This case is not " + "implemented yet."); + else /* if (err == -EPERM) */ + ntfs_error(vol->sb, "This attribute type may not be " + "non-resident. This case is not " + "implemented yet."); + } + err = -EOPNOTSUPP; + goto conv_err_out; +#if 0 + // TODO: Attempt to make other attributes non-resident. + if (!err) + goto do_resident_extend; + /* + * Both the attribute list attribute and the standard information + * attribute must remain in the base inode. Thus, if this is one of + * these attributes, we have to try to move other attributes out into + * extent mft records instead. + */ + if (ni->type == AT_ATTRIBUTE_LIST || + ni->type == AT_STANDARD_INFORMATION) { + // TODO: Attempt to move other attributes into extent mft + // records. + err = -EOPNOTSUPP; + if (!err) + goto do_resident_extend; + goto err_out; + } + // TODO: Attempt to move this attribute to an extent mft record, but + // only if it is not already the only attribute in an mft record in + // which case there would be nothing to gain. + err = -EOPNOTSUPP; + if (!err) + goto do_resident_extend; + /* There is nothing we can do to make enough space. )-: */ + goto err_out; +#endif +do_non_resident_extend: + BUG_ON(!NInoNonResident(ni)); + if (new_alloc_size == allocated_size) { + BUG_ON(vcn); + goto alloc_done; + } + /* + * If the data starts after the end of the old allocation, this is a + * $DATA attribute and sparse attributes are enabled on the volume and + * for this inode, then create a sparse region between the old + * allocated size and the start of the data. Otherwise simply proceed + * with filling the whole space between the old allocated size and the + * new allocated size with clusters. + */ + if ((start >= 0 && start <= allocated_size) || ni->type != AT_DATA || + !NVolSparseEnabled(vol) || NInoSparseDisabled(ni)) + goto skip_sparse; + // TODO: This is not implemented yet. We just fill in with real + // clusters for now... + ntfs_debug("Inserting holes is not-implemented yet. Falling back to " + "allocating real clusters instead."); +skip_sparse: + rl = ni->runlist.rl; + if (likely(rl)) { + /* Seek to the end of the runlist. */ + while (rl->length) + rl++; + } + /* If this attribute extent is not mapped, map it now. */ + if (unlikely(!rl || rl->lcn == LCN_RL_NOT_MAPPED || + (rl->lcn == LCN_ENOENT && rl > ni->runlist.rl && + (rl-1)->lcn == LCN_RL_NOT_MAPPED))) { + if (!rl && !allocated_size) + goto first_alloc; + rl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl); + if (IS_ERR(rl)) { + err = PTR_ERR(rl); + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation " + "of inode 0x%lx, attribute " + "type 0x%x, because the " + "mapping of a runlist " + "fragment failed with error " + "code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), + err); + if (err != -ENOMEM) + err = -EIO; + goto err_out; + } + ni->runlist.rl = rl; + /* Seek to the end of the runlist. */ + while (rl->length) + rl++; + } + /* + * We now know the runlist of the last extent is mapped and @rl is at + * the end of the runlist. We want to begin allocating clusters + * starting at the last allocated cluster to reduce fragmentation. If + * there are no valid LCNs in the attribute we let the cluster + * allocator choose the starting cluster. + */ + /* If the last LCN is a hole or simillar seek back to last real LCN. */ + while (rl->lcn < 0 && rl > ni->runlist.rl) + rl--; +first_alloc: + // FIXME: Need to implement partial allocations so at least part of the + // write can be performed when start >= 0. (Needed for POSIX write(2) + // conformance.) + rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits, + (new_alloc_size - allocated_size) >> + vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ? + rl->lcn + rl->length : -1, DATA_ZONE, TRUE); + if (IS_ERR(rl2)) { + err = PTR_ERR(rl2); + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation of " + "inode 0x%lx, attribute type 0x%x, " + "because the allocation of clusters " + "failed with error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + if (err != -ENOMEM && err != -ENOSPC) + err = -EIO; + goto err_out; + } + rl = ntfs_runlists_merge(ni->runlist.rl, rl2); + if (IS_ERR(rl)) { + err = PTR_ERR(rl); + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation of " + "inode 0x%lx, attribute type 0x%x, " + "because the runlist merge failed " + "with error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + if (err != -ENOMEM) + err = -EIO; + if (ntfs_cluster_free_from_rl(vol, rl2)) { + ntfs_error(vol->sb, "Failed to release allocated " + "cluster(s) in error code path. Run " + "chkdsk to recover the lost " + "cluster(s)."); + NVolSetErrors(vol); + } + ntfs_free(rl2); + goto err_out; + } + ni->runlist.rl = rl; + ntfs_debug("Allocated 0x%llx clusters.", (long long)(new_alloc_size - + allocated_size) >> vol->cluster_size_bits); + /* Find the runlist element with which the attribute extent starts. */ + ll = sle64_to_cpu(a->data.non_resident.lowest_vcn); + rl2 = ntfs_rl_find_vcn_nolock(rl, ll); + BUG_ON(!rl2); + BUG_ON(!rl2->length); + BUG_ON(rl2->lcn < LCN_HOLE); + mp_rebuilt = FALSE; + /* Get the size for the new mapping pairs array for this extent. */ + mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); + if (unlikely(mp_size <= 0)) { + err = mp_size; + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation of " + "inode 0x%lx, attribute type 0x%x, " + "because determining the size for the " + "mapping pairs failed with error code " + "%i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + err = -EIO; + goto undo_alloc; + } + /* Extend the attribute record to fit the bigger mapping pairs array. */ + attr_len = le32_to_cpu(a->length); + err = ntfs_attr_record_resize(m, a, mp_size + + le16_to_cpu(a->data.non_resident.mapping_pairs_offset)); + if (unlikely(err)) { + BUG_ON(err != -ENOSPC); + // TODO: Deal with this by moving this extent to a new mft + // record or by starting a new extent in a new mft record, + // possibly by extending this extent partially and filling it + // and creating a new extent for the remainder, or by making + // other attributes non-resident and/or by moving other + // attributes out of this mft record. + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Not enough space in the mft " + "record for the extended attribute " + "record. This case is not " + "implemented yet."); + err = -EOPNOTSUPP; + goto undo_alloc; + } + mp_rebuilt = TRUE; + /* Generate the mapping pairs array directly into the attr record. */ + err = ntfs_mapping_pairs_build(vol, (u8*)a + + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), + mp_size, rl2, ll, -1, NULL); + if (unlikely(err)) { + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot extend allocation of " + "inode 0x%lx, attribute type 0x%x, " + "because building the mapping pairs " + "failed with error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + err = -EIO; + goto undo_alloc; + } + /* Update the highest_vcn. */ + a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >> + vol->cluster_size_bits) - 1); + /* + * We now have extended the allocated size of the attribute. Reflect + * this in the ntfs_inode structure and the attribute record. + */ + if (a->data.non_resident.lowest_vcn) { + /* + * We are not in the first attribute extent, switch to it, but + * first ensure the changes will make it to disk later. + */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) + goto restore_undo_alloc; + /* @m is not used any more so no need to set it. */ + a = ctx->attr; + } + write_lock_irqsave(&ni->size_lock, flags); + ni->allocated_size = new_alloc_size; + a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size); + /* + * FIXME: This would fail if @ni is a directory, $MFT, or an index, + * since those can have sparse/compressed set. For example can be + * set compressed even though it is not compressed itself and in that + * case the bit means that files are to be created compressed in the + * directory... At present this is ok as this code is only called for + * regular files, and only for their $DATA attribute(s). + * FIXME: The calculation is wrong if we created a hole above. For now + * it does not matter as we never create holes. + */ + if (NInoSparse(ni) || NInoCompressed(ni)) { + ni->itype.compressed.size += new_alloc_size - allocated_size; + a->data.non_resident.compressed_size = + cpu_to_sle64(ni->itype.compressed.size); + vi->i_blocks = ni->itype.compressed.size >> 9; + } else + vi->i_blocks = new_alloc_size >> 9; + write_unlock_irqrestore(&ni->size_lock, flags); +alloc_done: + if (new_data_size >= 0) { + BUG_ON(new_data_size < + sle64_to_cpu(a->data.non_resident.data_size)); + a->data.non_resident.data_size = cpu_to_sle64(new_data_size); + } +flush_done: + /* Ensure the changes make it to disk. */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); +done: + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); + ntfs_debug("Done, new_allocated_size 0x%llx.", + (unsigned long long)new_alloc_size); + return new_alloc_size; +restore_undo_alloc: + if (start < 0 || start >= allocated_size) + ntfs_error(vol->sb, "Cannot complete extension of allocation " + "of inode 0x%lx, attribute type 0x%x, because " + "lookup of first attribute extent failed with " + "error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + if (err == -ENOENT) + err = -EIO; + ntfs_attr_reinit_search_ctx(ctx); + if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE, + allocated_size >> vol->cluster_size_bits, NULL, 0, + ctx)) { + ntfs_error(vol->sb, "Failed to find last attribute extent of " + "attribute in error code path. Run chkdsk to " + "recover."); + write_lock_irqsave(&ni->size_lock, flags); + ni->allocated_size = new_alloc_size; + /* + * FIXME: This would fail if @ni is a directory... See above. + * FIXME: The calculation is wrong if we created a hole above. + * For now it does not matter as we never create holes. + */ + if (NInoSparse(ni) || NInoCompressed(ni)) { + ni->itype.compressed.size += new_alloc_size - + allocated_size; + vi->i_blocks = ni->itype.compressed.size >> 9; + } else + vi->i_blocks = new_alloc_size >> 9; + write_unlock_irqrestore(&ni->size_lock, flags); + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); + /* + * The only thing that is now wrong is the allocated size of the + * base attribute extent which chkdsk should be able to fix. + */ + NVolSetErrors(vol); + return err; + } + ctx->attr->data.non_resident.highest_vcn = cpu_to_sle64( + (allocated_size >> vol->cluster_size_bits) - 1); +undo_alloc: + ll = allocated_size >> vol->cluster_size_bits; + if (ntfs_cluster_free(ni, ll, -1, ctx) < 0) { + ntfs_error(vol->sb, "Failed to release allocated cluster(s) " + "in error code path. Run chkdsk to recover " + "the lost cluster(s)."); + NVolSetErrors(vol); + } + m = ctx->mrec; + a = ctx->attr; + /* + * If the runlist truncation fails and/or the search context is no + * longer valid, we cannot resize the attribute record or build the + * mapping pairs array thus we mark the inode bad so that no access to + * the freed clusters can happen. + */ + if (ntfs_rl_truncate_nolock(vol, &ni->runlist, ll) || IS_ERR(m)) { + ntfs_error(vol->sb, "Failed to %s in error code path. Run " + "chkdsk to recover.", IS_ERR(m) ? + "restore attribute search context" : + "truncate attribute runlist"); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } else if (mp_rebuilt) { + if (ntfs_attr_record_resize(m, a, attr_len)) { + ntfs_error(vol->sb, "Failed to restore attribute " + "record in error code path. Run " + "chkdsk to recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } else /* if (success) */ { + if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( + a->data.non_resident. + mapping_pairs_offset), attr_len - + le16_to_cpu(a->data.non_resident. + mapping_pairs_offset), rl2, ll, -1, + NULL)) { + ntfs_error(vol->sb, "Failed to restore " + "mapping pairs array in error " + "code path. Run chkdsk to " + "recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + } + } +err_out: + if (ctx) + ntfs_attr_put_search_ctx(ctx); + if (m) + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); +conv_err_out: + ntfs_debug("Failed. Returning error code %i.", err); + return err; +} + /** * ntfs_attr_set - fill (a part of) an attribute with a byte * @ni: ntfs inode describing the attribute to fill diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index a959af9cef12..9074886b44ba 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -105,6 +105,9 @@ extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size); +extern s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size, + const s64 new_data_size, const s64 data_start); + extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val); From 54dac83c426a1a03bd139c5ac7e938890bd2693e Mon Sep 17 00:00:00 2001 From: Jeff Raubitschek Date: Tue, 4 Oct 2005 10:21:19 -0400 Subject: [PATCH 0200/1940] [libata passthru] fix leak on error --- drivers/scsi/libata-scsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 98057563a3cc..75cb685e320b 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -116,8 +116,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) if (args[3]) { argsize = SECTOR_SIZE * args[3]; argbuf = kmalloc(argsize, GFP_KERNEL); - if (argbuf == NULL) - return -ENOMEM; + if (argbuf == NULL) { + rc = -ENOMEM; + goto error; + } scsi_cmd[1] = (4 << 1); /* PIO Data-in */ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, From dd072330d1a60be11a5c284fa1e645350750a4fc Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 15:39:02 +0100 Subject: [PATCH 0201/1940] NTFS: Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports uncompressed and unencrypted files. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 20 +- fs/ntfs/inode.c | 497 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 471 insertions(+), 46 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 6c5bdfbb7bbf..70ad4be7a7fe 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -3,16 +3,14 @@ ToDo/Notes: - In between ntfs_prepare/commit_write, need exclusion between simultaneous file extensions. This is given to us by holding i_sem on the inode. The only places in the kernel when a file is resized - are prepare/commit write and truncate for both of which i_sem is - held. Just have to be careful in readpage/writepage and all other - helpers not running under i_sem that we play nice... - Also need to be careful with initialized_size extention in - ntfs_prepare_write. Basically, just be _very_ careful in this code... - UPDATE: The only things that need to be checked are read/writepage - which do not hold i_sem. Note writepage cannot change i_size but it - needs to cope with a concurrent i_size change, just like readpage. - Also both need to cope with concurrent changes to the other sizes, - i.e. initialized/allocated/compressed size, as well. + are prepare/commit write and ntfs_truncate() for both of which i_sem + is held. Just have to be careful in read-/writepage and other helpers + not running under i_sem that we play nice... Also need to be careful + with initialized_size extention in ntfs_prepare_write and writepage. + UPDATE: The only things that need to be checked are + prepare/commit_write as well as the compressed write and the other + attribute resize/write cases like index attributes, etc. For now + none of these are implemented so are safe. - Implement mft.c::sync_mft_mirror_umount(). We currently will just leave the volume dirty on umount if the final iput(vol->mft_ino) causes a write of any mirrored mft records due to the mft mirror @@ -50,6 +48,8 @@ ToDo/Notes: - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to extend the allocation of an attributes. Optionally, the data size, but not the initialized size can be extended, too. + - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports + uncompressed and unencrypted files. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 7ec045131808..a1682342baa6 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -30,6 +30,7 @@ #include "debug.h" #include "inode.h" #include "attrib.h" +#include "lcnalloc.h" #include "malloc.h" #include "mft.h" #include "time.h" @@ -2291,11 +2292,16 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt) #ifdef NTFS_RW +static const char *es = " Leaving inconsistent metadata. Unmount and run " + "chkdsk."; + /** * ntfs_truncate - called when the i_size of an ntfs inode is changed * @vi: inode for which the i_size was changed * - * We do not support i_size changes yet. + * We only support i_size changes for normal files at present, i.e. not + * compressed and not encrypted. This is enforced in ntfs_setattr(), see + * below. * * The kernel guarantees that @vi is a regular file (S_ISREG() is true) and * that the change is allowed. @@ -2306,80 +2312,499 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt) * Returns 0 on success or -errno on error. * * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for - * writing. The only case where ->i_alloc_sem is not held is + * writing. The only case in the kernel where ->i_alloc_sem is not held is * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called - * with the current i_size as the offset which means that it is a noop as far - * as ntfs_truncate() is concerned. + * with the current i_size as the offset. The analogous place in NTFS is in + * fs/ntfs/file.c::ntfs_file_buffered_write() where we call vmtruncate() again + * without holding ->i_alloc_sem. */ int ntfs_truncate(struct inode *vi) { - ntfs_inode *ni = NTFS_I(vi); + s64 new_size, old_size, nr_freed, new_alloc_size, old_alloc_size; + VCN highest_vcn; + unsigned long flags; + ntfs_inode *base_ni, *ni = NTFS_I(vi); ntfs_volume *vol = ni->vol; ntfs_attr_search_ctx *ctx; MFT_RECORD *m; ATTR_RECORD *a; const char *te = " Leaving file length out of sync with i_size."; - int err; + int err, mp_size, size_change, alloc_change; + u32 attr_len; ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); BUG_ON(NInoAttr(ni)); + BUG_ON(S_ISDIR(vi->i_mode)); + BUG_ON(NInoMstProtected(ni)); BUG_ON(ni->nr_extents < 0); - m = map_mft_record(ni); +retry_truncate: + /* + * Lock the runlist for writing and map the mft record to ensure it is + * safe to mess with the attribute runlist and sizes. + */ + down_write(&ni->runlist.lock); + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + m = map_mft_record(base_ni); if (IS_ERR(m)) { err = PTR_ERR(m); ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx " "(error code %d).%s", vi->i_ino, err, te); ctx = NULL; m = NULL; - goto err_out; + goto old_bad_out; } - ctx = ntfs_attr_get_search_ctx(ni, m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); if (unlikely(!ctx)) { ntfs_error(vi->i_sb, "Failed to allocate a search context for " "inode 0x%lx (not enough memory).%s", vi->i_ino, te); err = -ENOMEM; - goto err_out; + goto old_bad_out; } err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE, 0, NULL, 0, ctx); if (unlikely(err)) { - if (err == -ENOENT) + if (err == -ENOENT) { ntfs_error(vi->i_sb, "Open attribute is missing from " "mft record. Inode 0x%lx is corrupt. " - "Run chkdsk.", vi->i_ino); - else + "Run chkdsk.%s", vi->i_ino, te); + err = -EIO; + } else ntfs_error(vi->i_sb, "Failed to lookup attribute in " - "inode 0x%lx (error code %d).", - vi->i_ino, err); + "inode 0x%lx (error code %d).%s", + vi->i_ino, err, te); + goto old_bad_out; + } + m = ctx->mrec; + a = ctx->attr; + /* + * The i_size of the vfs inode is the new size for the attribute value. + */ + new_size = i_size_read(vi); + /* The current size of the attribute value is the old size. */ + old_size = ntfs_attr_size(a); + /* Calculate the new allocated size. */ + if (NInoNonResident(ni)) + new_alloc_size = (new_size + vol->cluster_size - 1) & + ~(s64)vol->cluster_size_mask; + else + new_alloc_size = (new_size + 7) & ~7; + /* The current allocated size is the old allocated size. */ + read_lock_irqsave(&ni->size_lock, flags); + old_alloc_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + /* + * The change in the file size. This will be 0 if no change, >0 if the + * size is growing, and <0 if the size is shrinking. + */ + size_change = -1; + if (new_size - old_size >= 0) { + size_change = 1; + if (new_size == old_size) + size_change = 0; + } + /* As above for the allocated size. */ + alloc_change = -1; + if (new_alloc_size - old_alloc_size >= 0) { + alloc_change = 1; + if (new_alloc_size == old_alloc_size) + alloc_change = 0; + } + /* + * If neither the size nor the allocation are being changed there is + * nothing to do. + */ + if (!size_change && !alloc_change) + goto unm_done; + /* If the size is changing, check if new size is allowed in $AttrDef. */ + if (size_change) { + err = ntfs_attr_size_bounds_check(vol, ni->type, new_size); + if (unlikely(err)) { + if (err == -ERANGE) { + ntfs_error(vol->sb, "Truncate would cause the " + "inode 0x%lx to %simum size " + "for its attribute type " + "(0x%x). Aborting truncate.", + vi->i_ino, + new_size > old_size ? "exceed " + "the max" : "go under the min", + le32_to_cpu(ni->type)); + err = -EFBIG; + } else { + ntfs_error(vol->sb, "Inode 0x%lx has unknown " + "attribute type 0x%x. " + "Aborting truncate.", + vi->i_ino, + le32_to_cpu(ni->type)); + err = -EIO; + } + /* Reset the vfs inode size to the old size. */ + i_size_write(vi, old_size); + goto err_out; + } + } + if (NInoCompressed(ni) || NInoEncrypted(ni)) { + ntfs_warning(vi->i_sb, "Changes in inode size are not " + "supported yet for %s files, ignoring.", + NInoCompressed(ni) ? "compressed" : + "encrypted"); + err = -EOPNOTSUPP; + goto bad_out; + } + if (a->non_resident) + goto do_non_resident_truncate; + BUG_ON(NInoNonResident(ni)); + /* Resize the attribute record to best fit the new attribute size. */ + if (new_size < vol->mft_record_size && + !ntfs_resident_attr_value_resize(m, a, new_size)) { + unsigned long flags; + + /* The resize succeeded! */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + write_lock_irqsave(&ni->size_lock, flags); + /* Update the sizes in the ntfs inode and all is done. */ + ni->allocated_size = le32_to_cpu(a->length) - + le16_to_cpu(a->data.resident.value_offset); + /* + * Note ntfs_resident_attr_value_resize() has already done any + * necessary data clearing in the attribute record. When the + * file is being shrunk vmtruncate() will already have cleared + * the top part of the last partial page, i.e. since this is + * the resident case this is the page with index 0. However, + * when the file is being expanded, the page cache page data + * between the old data_size, i.e. old_size, and the new_size + * has not been zeroed. Fortunately, we do not need to zero it + * either since on one hand it will either already be zero due + * to both readpage and writepage clearing partial page data + * beyond i_size in which case there is nothing to do or in the + * case of the file being mmap()ped at the same time, POSIX + * specifies that the behaviour is unspecified thus we do not + * have to do anything. This means that in our implementation + * in the rare case that the file is mmap()ped and a write + * occured into the mmap()ped region just beyond the file size + * and writepage has not yet been called to write out the page + * (which would clear the area beyond the file size) and we now + * extend the file size to incorporate this dirty region + * outside the file size, a write of the page would result in + * this data being written to disk instead of being cleared. + * Given both POSIX and the Linux mmap(2) man page specify that + * this corner case is undefined, we choose to leave it like + * that as this is much simpler for us as we cannot lock the + * relevant page now since we are holding too many ntfs locks + * which would result in a lock reversal deadlock. + */ + ni->initialized_size = new_size; + write_unlock_irqrestore(&ni->size_lock, flags); + goto unm_done; + } + /* If the above resize failed, this must be an attribute extension. */ + BUG_ON(size_change < 0); + /* + * We have to drop all the locks so we can call + * ntfs_attr_make_non_resident(). This could be optimised by try- + * locking the first page cache page and only if that fails dropping + * the locks, locking the page, and redoing all the locking and + * lookups. While this would be a huge optimisation, it is not worth + * it as this is definitely a slow code path as it only ever can happen + * once for any given file. + */ + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); + /* + * Not enough space in the mft record, try to make the attribute + * non-resident and if successful restart the truncation process. + */ + err = ntfs_attr_make_non_resident(ni, old_size); + if (likely(!err)) + goto retry_truncate; + /* + * Could not make non-resident. If this is due to this not being + * permitted for this attribute type or there not being enough space, + * try to make other attributes non-resident. Otherwise fail. + */ + if (unlikely(err != -EPERM && err != -ENOSPC)) { + ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, attribute " + "type 0x%x, because the conversion from " + "resident to non-resident attribute failed " + "with error code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + if (err != -ENOMEM) + err = -EIO; + goto conv_err_out; + } + /* TODO: Not implemented from here, abort. */ + if (err == -ENOSPC) + ntfs_error(vol->sb, "Not enough space in the mft record/on " + "disk for the non-resident attribute value. " + "This case is not implemented yet."); + else /* if (err == -EPERM) */ + ntfs_error(vol->sb, "This attribute type may not be " + "non-resident. This case is not implemented " + "yet."); + err = -EOPNOTSUPP; + goto conv_err_out; +#if 0 + // TODO: Attempt to make other attributes non-resident. + if (!err) + goto do_resident_extend; + /* + * Both the attribute list attribute and the standard information + * attribute must remain in the base inode. Thus, if this is one of + * these attributes, we have to try to move other attributes out into + * extent mft records instead. + */ + if (ni->type == AT_ATTRIBUTE_LIST || + ni->type == AT_STANDARD_INFORMATION) { + // TODO: Attempt to move other attributes into extent mft + // records. + err = -EOPNOTSUPP; + if (!err) + goto do_resident_extend; goto err_out; } - a = ctx->attr; - /* If the size has not changed there is nothing to do. */ - if (ntfs_attr_size(a) == i_size_read(vi)) - goto done; - // TODO: Implement the truncate... - ntfs_error(vi->i_sb, "Inode size has changed but this is not " - "implemented yet. Resetting inode size to old value. " - " This is most likely a bug in the ntfs driver!"); - i_size_write(vi, ntfs_attr_size(a)); -done: - ntfs_attr_put_search_ctx(ctx); - unmap_mft_record(ni); - NInoClearTruncateFailed(ni); - ntfs_debug("Done."); - return 0; -err_out: - if (err != -ENOMEM) { - NVolSetErrors(vol); - make_bad_inode(vi); + // TODO: Attempt to move this attribute to an extent mft record, but + // only if it is not already the only attribute in an mft record in + // which case there would be nothing to gain. + err = -EOPNOTSUPP; + if (!err) + goto do_resident_extend; + /* There is nothing we can do to make enough space. )-: */ + goto err_out; +#endif +do_non_resident_truncate: + BUG_ON(!NInoNonResident(ni)); + if (alloc_change < 0) { + highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); + if (highest_vcn > 0 && + old_alloc_size >> vol->cluster_size_bits > + highest_vcn + 1) { + /* + * This attribute has multiple extents. Not yet + * supported. + */ + ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, " + "attribute type 0x%x, because the " + "attribute is highly fragmented (it " + "consists of multiple extents) and " + "this case is not implemented yet.", + vi->i_ino, + (unsigned)le32_to_cpu(ni->type)); + err = -EOPNOTSUPP; + goto bad_out; + } } + /* + * If the size is shrinking, need to reduce the initialized_size and + * the data_size before reducing the allocation. + */ + if (size_change < 0) { + /* + * Make the valid size smaller (i_size is already up-to-date). + */ + write_lock_irqsave(&ni->size_lock, flags); + if (new_size < ni->initialized_size) { + ni->initialized_size = new_size; + a->data.non_resident.initialized_size = + cpu_to_sle64(new_size); + } + a->data.non_resident.data_size = cpu_to_sle64(new_size); + write_unlock_irqrestore(&ni->size_lock, flags); + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + /* If the allocated size is not changing, we are done. */ + if (!alloc_change) + goto unm_done; + /* + * If the size is shrinking it makes no sense for the + * allocation to be growing. + */ + BUG_ON(alloc_change > 0); + } else /* if (size_change >= 0) */ { + /* + * The file size is growing or staying the same but the + * allocation can be shrinking, growing or staying the same. + */ + if (alloc_change > 0) { + /* + * We need to extend the allocation and possibly update + * the data size. If we are updating the data size, + * since we are not touching the initialized_size we do + * not need to worry about the actual data on disk. + * And as far as the page cache is concerned, there + * will be no pages beyond the old data size and any + * partial region in the last page between the old and + * new data size (or the end of the page if the new + * data size is outside the page) does not need to be + * modified as explained above for the resident + * attribute truncate case. To do this, we simply drop + * the locks we hold and leave all the work to our + * friendly helper ntfs_attr_extend_allocation(). + */ + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); + err = ntfs_attr_extend_allocation(ni, new_size, + size_change > 0 ? new_size : -1, -1); + /* + * ntfs_attr_extend_allocation() will have done error + * output already. + */ + goto done; + } + if (!alloc_change) + goto alloc_done; + } + /* alloc_change < 0 */ + /* Free the clusters. */ + nr_freed = ntfs_cluster_free(ni, new_alloc_size >> + vol->cluster_size_bits, -1, ctx); + m = ctx->mrec; + a = ctx->attr; + if (unlikely(nr_freed < 0)) { + ntfs_error(vol->sb, "Failed to release cluster(s) (error code " + "%lli). Unmount and run chkdsk to recover " + "the lost cluster(s).", (long long)nr_freed); + NVolSetErrors(vol); + nr_freed = 0; + } + /* Truncate the runlist. */ + err = ntfs_rl_truncate_nolock(vol, &ni->runlist, + new_alloc_size >> vol->cluster_size_bits); + /* + * If the runlist truncation failed and/or the search context is no + * longer valid, we cannot resize the attribute record or build the + * mapping pairs array thus we mark the inode bad so that no access to + * the freed clusters can happen. + */ + if (unlikely(err || IS_ERR(m))) { + ntfs_error(vol->sb, "Failed to %s (error code %li).%s", + IS_ERR(m) ? + "restore attribute search context" : + "truncate attribute runlist", + IS_ERR(m) ? PTR_ERR(m) : err, es); + err = -EIO; + goto bad_out; + } + /* Get the size for the shrunk mapping pairs array for the runlist. */ + mp_size = ntfs_get_size_for_mapping_pairs(vol, ni->runlist.rl, 0, -1); + if (unlikely(mp_size <= 0)) { + ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, " + "attribute type 0x%x, because determining the " + "size for the mapping pairs failed with error " + "code %i.%s", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), mp_size, es); + err = -EIO; + goto bad_out; + } + /* + * Shrink the attribute record for the new mapping pairs array. Note, + * this cannot fail since we are making the attribute smaller thus by + * definition there is enough space to do so. + */ + attr_len = le32_to_cpu(a->length); + err = ntfs_attr_record_resize(m, a, mp_size + + le16_to_cpu(a->data.non_resident.mapping_pairs_offset)); + BUG_ON(err); + /* + * Generate the mapping pairs array directly into the attribute record. + */ + err = ntfs_mapping_pairs_build(vol, (u8*)a + + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), + mp_size, ni->runlist.rl, 0, -1, NULL); + if (unlikely(err)) { + ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, " + "attribute type 0x%x, because building the " + "mapping pairs failed with error code %i.%s", + vi->i_ino, (unsigned)le32_to_cpu(ni->type), + err, es); + err = -EIO; + goto bad_out; + } + /* Update the allocated/compressed size as well as the highest vcn. */ + a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >> + vol->cluster_size_bits) - 1); + write_lock_irqsave(&ni->size_lock, flags); + ni->allocated_size = new_alloc_size; + a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size); + if (NInoSparse(ni) || NInoCompressed(ni)) { + if (nr_freed) { + ni->itype.compressed.size -= nr_freed << + vol->cluster_size_bits; + BUG_ON(ni->itype.compressed.size < 0); + a->data.non_resident.compressed_size = cpu_to_sle64( + ni->itype.compressed.size); + vi->i_blocks = ni->itype.compressed.size >> 9; + } + } else + vi->i_blocks = new_alloc_size >> 9; + write_unlock_irqrestore(&ni->size_lock, flags); + /* + * We have shrunk the allocation. If this is a shrinking truncate we + * have already dealt with the initialized_size and the data_size above + * and we are done. If the truncate is only changing the allocation + * and not the data_size, we are also done. If this is an extending + * truncate, need to extend the data_size now which is ensured by the + * fact that @size_change is positive. + */ +alloc_done: + /* + * If the size is growing, need to update it now. If it is shrinking, + * we have already updated it above (before the allocation change). + */ + if (size_change > 0) + a->data.non_resident.data_size = cpu_to_sle64(new_size); + /* Ensure the modified mft record is written out. */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); +unm_done: + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); +done: + /* Update the mtime and ctime on the base inode. */ + inode_update_time(VFS_I(base_ni), 1); + if (likely(!err)) { + NInoClearTruncateFailed(ni); + ntfs_debug("Done."); + } + return err; +old_bad_out: + old_size = -1; +bad_out: + if (err != -ENOMEM && err != -EOPNOTSUPP) { + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } + if (err != -EOPNOTSUPP) + NInoSetTruncateFailed(ni); + else if (old_size >= 0) + i_size_write(vi, old_size); +err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); if (m) - unmap_mft_record(ni); - NInoSetTruncateFailed(ni); + unmap_mft_record(base_ni); + up_write(&ni->runlist.lock); +out: + ntfs_debug("Failed. Returning error code %i.", err); return err; +conv_err_out: + if (err != -ENOMEM && err != -EOPNOTSUPP) { + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } + if (err != -EOPNOTSUPP) + NInoSetTruncateFailed(ni); + else + i_size_write(vi, old_size); + goto out; } /** From e9438250b635f7832e99a8c8d2e394dd1522ce65 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 4 Oct 2005 16:01:06 +0100 Subject: [PATCH 0202/1940] NTFS: Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes the initial implementation of file truncation. Now both open(2)ing a file with the O_TRUNC flag and the {,f}truncate(2) system calls will resize a file appropriately. The limitations are that only uncompressed and unencrypted files are supported. Also, there is only very limited support for highly fragmented files (the ones whose $DATA attribute is split into multiple attribute extents). Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 7 +++++++ fs/ntfs/inode.c | 23 +++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 70ad4be7a7fe..9f4674a026f2 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -50,6 +50,13 @@ ToDo/Notes: but not the initialized size can be extended, too. - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports uncompressed and unencrypted files. + - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes + the initial implementation of file truncation. Now both open(2)ing + a file with the O_TRUNC flag and the {,f}truncate(2) system calls + will resize a file appropriately. The limitations are that only + uncompressed and unencrypted files are supported. Also, there is + only very limited support for highly fragmented files (the ones whose + $DATA attribute is split into multiple attribute extents). 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index a1682342baa6..b24f4c4b2c5c 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2845,8 +2845,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) err = inode_change_ok(vi, attr); if (err) - return err; - + goto out; /* We do not support NTFS ACLs yet. */ if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) { ntfs_warning(vi->i_sb, "Changes in user/group/mode are not " @@ -2854,14 +2853,22 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) err = -EOPNOTSUPP; goto out; } - if (ia_valid & ATTR_SIZE) { if (attr->ia_size != i_size_read(vi)) { - ntfs_warning(vi->i_sb, "Changes in inode size are not " - "supported yet, ignoring."); - err = -EOPNOTSUPP; - // TODO: Implement... - // err = vmtruncate(vi, attr->ia_size); + ntfs_inode *ni = NTFS_I(vi); + /* + * FIXME: For now we do not support resizing of + * compressed or encrypted files yet. + */ + if (NInoCompressed(ni) || NInoEncrypted(ni)) { + ntfs_warning(vi->i_sb, "Changes in inode size " + "are not supported yet for " + "%s files, ignoring.", + NInoCompressed(ni) ? + "compressed" : "encrypted"); + err = -EOPNOTSUPP; + } else + err = vmtruncate(vi, attr->ia_size); if (err || ia_valid == ATTR_SIZE) goto out; } else { From 36735554571ea619e38210a20f429798de90adc1 Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Mon, 3 Oct 2005 11:51:45 -0500 Subject: [PATCH 0203/1940] [IA64-SGI] Remove references to the SN bist_lock Remove all references to the bist_lock in the SN code as it is not used for anything. Signed-off-by: Dean Roe Signed-off-by: Tony Luck --- include/asm-ia64/sn/nodepda.h | 1 - include/asm-ia64/sn/sn_sal.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h index 47bb8100fd00..6f6d69e39ff5 100644 --- a/include/asm-ia64/sn/nodepda.h +++ b/include/asm-ia64/sn/nodepda.h @@ -55,7 +55,6 @@ struct nodepda_s { */ struct phys_cpuid phys_cpuid[NR_CPUS]; spinlock_t ptc_lock ____cacheline_aligned_in_smp; - spinlock_t bist_lock; }; typedef struct nodepda_s nodepda_t; diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index fea35b33d4e4..33aa4043f87d 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -694,12 +694,10 @@ sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array) unsigned long irq_flags; cnodeid = nasid_to_cnodeid(get_node_number(paddr)); - // spin_lock(&NODEPDA(cnodeid)->bist_lock); local_irq_save(irq_flags); ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len, (u64)nasid_array, perms, 0, 0, 0); local_irq_restore(irq_flags); - // spin_unlock(&NODEPDA(cnodeid)->bist_lock); return ret_stuff.status; } #define SN_MEMPROT_ACCESS_CLASS_0 0x14a080 From da9577c531f17f744f3eab40f700e07933d26361 Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 4 Oct 2005 15:13:37 -0400 Subject: [PATCH 0204/1940] [PATCH] V5 ia64 SPARSEMEM - Kconfig and Makefile The patch modifies the Kconfig file to introduce the new memory model options and other related SPARSEMEM changes. There is also a minor change in the Makefile. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 94 ++++++++++++++++++++++++++----------------- arch/ia64/mm/Makefile | 5 +-- 2 files changed, 58 insertions(+), 41 deletions(-) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 945c15a0722b..a86236d6ba5d 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -63,8 +63,6 @@ config IA64_GENERIC select ACPI select NUMA select ACPI_NUMA - select VIRTUAL_MEM_MAP - select DISCONTIGMEM help This selects the system type of your hardware. A "generic" kernel will run on any supported IA-64 system. However, if you configure @@ -176,40 +174,6 @@ config IA64_L1_CACHE_SHIFT default "6" if ITANIUM # align cache-sensitive data to 64 bytes -config NUMA - bool "NUMA support" - depends on !IA64_HP_SIM - default y if IA64_SGI_SN2 - select ACPI_NUMA - help - Say Y to compile the kernel to support NUMA (Non-Uniform Memory - Access). This option is for configuring high-end multiprocessor - server systems. If in doubt, say N. - -config VIRTUAL_MEM_MAP - bool "Virtual mem map" - default y if !IA64_HP_SIM - help - Say Y to compile the kernel with support for a virtual mem map. - This code also only takes effect if a memory hole of greater than - 1 Gb is found during boot. You must turn this option on if you - require the DISCONTIGMEM option for your machine. If you are - unsure, say Y. - -config HOLES_IN_ZONE - bool - default y if VIRTUAL_MEM_MAP - -config ARCH_DISCONTIGMEM_ENABLE - bool "Discontiguous memory support" - depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP - default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA - help - Say Y to support efficient handling of discontiguous physical memory, - for architectures which are either NUMA (Non-Uniform Memory Access) - or have huge holes in the physical address space for other reasons. - See for more. - config IA64_CYCLONE bool "Cyclone (EXA) Time Source support" help @@ -232,8 +196,10 @@ config IA64_SGI_SN_XP based on a network adapter and DMA messaging. config FORCE_MAX_ZONEORDER - int - default "18" + int "MAX_ORDER (11 - 17)" if !HUGETLB_PAGE + range 11 17 if !HUGETLB_PAGE + default "17" if HUGETLB_PAGE + default "11" config SMP bool "Symmetric multi-processing support" @@ -298,6 +264,58 @@ config PREEMPT source "mm/Kconfig" +config ARCH_SELECT_MEMORY_MODEL + def_bool y + +config ARCH_DISCONTIGMEM_ENABLE + def_bool y + help + Say Y to support efficient handling of discontiguous physical memory, + for architectures which are either NUMA (Non-Uniform Memory Access) + or have huge holes in the physical address space for other reasons. + See for more. + +config ARCH_FLATMEM_ENABLE + def_bool y + +config ARCH_SPARSEMEM_ENABLE + def_bool y + depends on ARCH_DISCONTIGMEM_ENABLE + +config ARCH_DISCONTIGMEM_DEFAULT + def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) + depends on ARCH_DISCONTIGMEM_ENABLE + +config NUMA + bool "NUMA support" + depends on !IA64_HP_SIM && !FLATMEM + default y if IA64_SGI_SN2 + help + Say Y to compile the kernel to support NUMA (Non-Uniform Memory + Access). This option is for configuring high-end multiprocessor + server systems. If in doubt, say N. + +# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. +# VIRTUAL_MEM_MAP has been retained for historical reasons. +config VIRTUAL_MEM_MAP + bool "Virtual mem map" + depends on !SPARSEMEM + default y if !IA64_HP_SIM + help + Say Y to compile the kernel with support for a virtual mem map. + This code also only takes effect if a memory hole of greater than + 1 Gb is found during boot. You must turn this option on if you + require the DISCONTIGMEM option for your machine. If you are + unsure, say Y. + +config HOLES_IN_ZONE + bool + default y if VIRTUAL_MEM_MAP + +config HAVE_ARCH_EARLY_PFN_TO_NID + def_bool y + depends on NEED_MULTIPLE_NODES + config IA32_SUPPORT bool "Support for Linux/x86 binaries" help diff --git a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile index 7078f67887ec..d78d20f0a0f0 100644 --- a/arch/ia64/mm/Makefile +++ b/arch/ia64/mm/Makefile @@ -7,6 +7,5 @@ obj-y := init.o fault.o tlb.o extable.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o -ifndef CONFIG_DISCONTIGMEM -obj-y += contig.o -endif +obj-$(CONFIG_SPARSEMEM) += discontig.o +obj-$(CONFIG_FLATMEM) += contig.o From c678796cab4b5288ad578802a54cb1480ae20a08 Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 4 Oct 2005 15:13:44 -0400 Subject: [PATCH 0205/1940] [PATCH] V5 ia64 SPARSEMEM - eliminate contig_page_data For FLATMEM contig_page_data has been made transparent to the arch code. This patch conforms to that change. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/mm/contig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 91a055f5731f..acaaec4e4681 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -269,7 +269,7 @@ paging_init (void) efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; - free_area_init_node(0, &contig_page_data, zones_size, 0, + free_area_init_node(0, NODE_DATA(0), zones_size, 0, zholes_size); } else { unsigned long map_size; @@ -282,7 +282,7 @@ paging_init (void) efi_memmap_walk(create_mem_map_page_table, NULL); NODE_DATA(0)->node_mem_map = vmem_map; - free_area_init_node(0, &contig_page_data, zones_size, + free_area_init_node(0, NODE_DATA(0), zones_size, 0, zholes_size); printk("Virtual mem_map starts at 0x%p\n", mem_map); From 1be7d9935b9c7fb9bd5964bfaf3ac543381277db Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 4 Oct 2005 15:13:50 -0400 Subject: [PATCH 0206/1940] [PATCH] V5 ia64 SPARSEMEM - conditional changes for SPARSEMEM This patch introduces the conditional changes required for the three memory models. With [patch 1/4] there are three memory models; FLATMEM, DISCONTIG and SPARSEMEM. Also a new arch include file sparemem.h is introduced for defining SPARSEMEM parameters. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- include/asm-ia64/meminit.h | 2 +- include/asm-ia64/mmzone.h | 10 +++++++--- include/asm-ia64/nodedata.h | 4 ++-- include/asm-ia64/page.h | 6 +++--- include/asm-ia64/sparsemem.h | 20 ++++++++++++++++++++ 5 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 include/asm-ia64/sparsemem.h diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h index 1590dc65b30b..74477fc31d51 100644 --- a/include/asm-ia64/meminit.h +++ b/include/asm-ia64/meminit.h @@ -41,7 +41,7 @@ extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg #define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1)) #define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE< #include -#ifdef CONFIG_DISCONTIGMEM +#ifdef CONFIG_NUMA static inline int pfn_to_nid(unsigned long pfn) { @@ -31,6 +31,10 @@ static inline int pfn_to_nid(unsigned long pfn) #endif } +#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +extern int early_pfn_to_nid(unsigned long pfn); +#endif + #ifdef CONFIG_IA64_DIG /* DIG systems are small */ # define MAX_PHYSNODE_ID 8 # define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) @@ -39,8 +43,8 @@ static inline int pfn_to_nid(unsigned long pfn) # define NR_NODE_MEMBLKS (MAX_NUMNODES * 4) #endif -#else /* CONFIG_DISCONTIGMEM */ +#else /* CONFIG_NUMA */ # define NR_NODE_MEMBLKS (MAX_NUMNODES * 4) -#endif /* CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_NUMA */ #endif /* _ASM_IA64_MMZONE_H */ diff --git a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h index 6b0f3ed89b7e..9978c7ce7549 100644 --- a/include/asm-ia64/nodedata.h +++ b/include/asm-ia64/nodedata.h @@ -17,7 +17,7 @@ #include #include -#ifdef CONFIG_DISCONTIGMEM +#ifdef CONFIG_NUMA /* * Node Data. One of these structures is located on each node of a NUMA system. @@ -47,6 +47,6 @@ struct ia64_node_data { */ #define NODE_DATA(nid) (local_node_data->pg_data_ptrs[nid]) -#endif /* CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_NUMA */ #endif /* _ASM_IA64_NODEDATA_H */ diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 9edffad8c28b..ef436b9d06ad 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -102,15 +102,15 @@ do { \ #ifdef CONFIG_VIRTUAL_MEM_MAP extern int ia64_pfn_valid (unsigned long pfn); -#else +#elif defined(CONFIG_FLATMEM) # define ia64_pfn_valid(pfn) 1 #endif -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM # define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) # define page_to_pfn(page) ((unsigned long) (page - mem_map)) # define pfn_to_page(pfn) (mem_map + (pfn)) -#else +#elif defined(CONFIG_DISCONTIGMEM) extern struct page *vmem_map; extern unsigned long max_low_pfn; # define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) diff --git a/include/asm-ia64/sparsemem.h b/include/asm-ia64/sparsemem.h new file mode 100644 index 000000000000..67a7c40ec27f --- /dev/null +++ b/include/asm-ia64/sparsemem.h @@ -0,0 +1,20 @@ +#ifndef _ASM_IA64_SPARSEMEM_H +#define _ASM_IA64_SPARSEMEM_H + +#ifdef CONFIG_SPARSEMEM +/* + * SECTION_SIZE_BITS 2^N: how big each section will be + * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space + */ + +#define SECTION_SIZE_BITS (30) +#define MAX_PHYSMEM_BITS (50) +#ifdef CONFIG_FORCE_MAX_ZONEORDER +#if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS) +#undef SECTION_SIZE_BITS +#define SECTION_SIZE_BITS (CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) +#endif +#endif + +#endif /* CONFIG_SPARSEMEM */ +#endif /* _ASM_IA64_SPARSEMEM_H */ From 2d4b1fa234417b902c9d3034442387c1805bfa7b Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 4 Oct 2005 15:13:57 -0400 Subject: [PATCH 0207/1940] [PATCH] V5 ia64 SPARSEMEM - SPARSEMEM code changes This patch is the minimal set of changes required by ia64 to use SPARSEMEM. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/mm/discontig.c | 43 ++++++++++++++++++++++++++++++++++++++-- arch/ia64/mm/init.c | 2 +- arch/ia64/mm/numa.c | 24 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index b5c90e548195..a3788fb84809 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -421,6 +421,37 @@ static void __init memory_less_nodes(void) return; } +#ifdef CONFIG_SPARSEMEM +/** + * register_sparse_mem - notify SPARSEMEM that this memory range exists. + * @start: physical start of range + * @end: physical end of range + * @arg: unused + * + * Simply calls SPARSEMEM to register memory section(s). + */ +static int __init register_sparse_mem(unsigned long start, unsigned long end, + void *arg) +{ + int nid; + + start = __pa(start) >> PAGE_SHIFT; + end = __pa(end) >> PAGE_SHIFT; + nid = early_pfn_to_nid(start); + memory_present(nid, start, end); + + return 0; +} + +static void __init arch_sparse_init(void) +{ + efi_memmap_walk(register_sparse_mem, NULL); + sparse_init(); +} +#else +#define arch_sparse_init() do {} while (0) +#endif + /** * find_memory - walk the EFI memory map and setup the bootmem allocator * @@ -528,8 +559,10 @@ void show_mem(void) int shared = 0, cached = 0, reserved = 0; printk("Node ID: %d\n", pgdat->node_id); for(i = 0; i < pgdat->node_spanned_pages; i++) { - struct page *page = pgdat_page_nr(pgdat, i); - if (!ia64_pfn_valid(pgdat->node_start_pfn+i)) + struct page *page; + if (pfn_valid(pgdat->node_start_pfn + i)) + page = pfn_to_page(pgdat->node_start_pfn + i); + else continue; if (PageReserved(page)) reserved++; @@ -648,12 +681,16 @@ void __init paging_init(void) max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; + arch_sparse_init(); + efi_memmap_walk(filter_rsvd_memory, count_node_pages); +#ifdef CONFIG_VIRTUAL_MEM_MAP vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); printk("Virtual mem_map starts at 0x%p\n", vmem_map); +#endif for_each_online_node(node) { memset(zones_size, 0, sizeof(zones_size)); @@ -690,7 +727,9 @@ void __init paging_init(void) pfn_offset = mem_data[node].min_pfn; +#ifdef CONFIG_VIRTUAL_MEM_MAP NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; +#endif free_area_init_node(node, NODE_DATA(node), zones_size, pfn_offset, zholes_size); } diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 1281c609ee98..98246acd4991 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -593,7 +593,7 @@ mem_init (void) platform_dma_init(); #endif -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM if (!mem_map) BUG(); max_mapnr = max_low_pfn; diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index 77118bbf3d8b..4e5c8b36ad93 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c @@ -47,3 +47,27 @@ paddr_to_nid(unsigned long paddr) return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0); } + +#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA) +/* + * Because of holes evaluate on section limits. + * If the section of memory exists, then return the node where the section + * resides. Otherwise return node 0 as the default. This is used by + * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where + * the section resides. + */ +int early_pfn_to_nid(unsigned long pfn) +{ + int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; + + for (i = 0; i < num_node_memblks; i++) { + ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT; + esec = (node_memblk[i].start_paddr + node_memblk[i].size + + ((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT; + if (section >= ssec && section < esec) + return node_memblk[i].nid; + } + + return 0; +} +#endif From 1e5c936e3cc2ab745f66c0ae296c42f892ffd42a Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 4 Oct 2005 15:14:05 -0400 Subject: [PATCH 0208/1940] [PATCH] V5 ia64 SPARSEMEM - gensparse_defconfig gensparse_defconfig is a config generated file for SPARSEMEM and GENERIC kernel configuration (defconfig). Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/configs/gensparse_defconfig | 1319 +++++++++++++++++++++++++ 1 file changed, 1319 insertions(+) create mode 100644 arch/ia64/configs/gensparse_defconfig diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig new file mode 100644 index 000000000000..80f8663bc6d9 --- /dev/null +++ b/arch/ia64/configs/gensparse_defconfig @@ -0,0 +1,1319 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-rc2 +# Wed Sep 28 08:27:29 2005 +# + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_TIME_INTERPOLATION=y +CONFIG_EFI=y +CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_IA64_GENERIC=y +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set +# CONFIG_IA64_SGI_SN2 is not set +# CONFIG_IA64_HP_SIM is not set +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_IA64_L1_CACHE_SHIFT=7 +CONFIG_IA64_CYCLONE=y +CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set +CONFIG_FORCE_MAX_ZONEORDER=17 +CONFIG_SMP=y +CONFIG_NR_CPUS=512 +CONFIG_HOTPLUG_CPU=y +# CONFIG_SCHED_SMT is not set +# CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_NUMA=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_IA32_SUPPORT=y +CONFIG_COMPAT=y +CONFIG_IA64_MCA_RECOVERY=y +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y + +# +# Firmware Drivers +# +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +# CONFIG_DELL_RBU is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m + +# +# Power management and ACPI +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set + +# +# ACPI (Advanced Configuration and Power Interface) Support +# +CONFIG_ACPI=y +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=m +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_CONTAINER=m + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Bus options (PCI, PCMCIA) +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_DEBUG is not set + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=m +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_ACPI=m +# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI_SGI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SGIIOC4=y +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_MV is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +CONFIG_SCSI_SATA_VITESSE=y +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +CONFIG_SCSI_QLOGIC_1280=y +# CONFIG_SCSI_QLOGIC_1280_1040 is not set +CONFIG_SCSI_QLA2XXX=y +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=m +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_EMC is not set + +# +# Fusion MPT device support +# +CONFIG_FUSION=y +CONFIG_FUSION_SPI=y +CONFIG_FUSION_FC=m +CONFIG_FUSION_MAX_SGE=128 +# CONFIG_FUSION_CTL is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=m +CONFIG_E100=m +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_TIGON3=y +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_STALDRV is not set +CONFIG_SGI_SNSC=y +CONFIG_SGI_TIOCX=y +CONFIG_SGI_MBCS=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_ACPI=y +CONFIG_SERIAL_8250_NR_UARTS=6 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_SGI_L1_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_SGI_IOC4=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +CONFIG_EFI_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=m +CONFIG_AGP_I460=m +CONFIG_AGP_HP_ZX1=m +CONFIG_AGP_SGI_TIOCA=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +CONFIG_RAW_DRIVER=m +CONFIG_HPET=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_MMAP=y +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set +CONFIG_MMTIMER=y + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_VERBOSE_PRINTK=y +# CONFIG_SND_DEBUG is not set +CONFIG_SND_GENERIC_DRIVER=y + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_BUS=m + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_EMU10K1=m +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +CONFIG_SND_FM801=m +# CONFIG_SND_FM801_TEA575X is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +CONFIG_INFINIBAND=m +# CONFIG_INFINIBAND_USER_MAD is not set +# CONFIG_INFINIBAND_USER_ACCESS is not set +CONFIG_INFINIBAND_MTHCA=m +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_DEBUG is not set + +# +# SN Devices +# +CONFIG_SGI_IOC4=y + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_SECURITY is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_EFI_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y + +# +# HP Simulator drivers +# +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +# CONFIG_HP_SIMSCSI is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=20 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_SYSVIPC_COMPAT=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# From cedc9a478d8c6265879dc3839ef3d4849a709184 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 5 Oct 2005 07:13:30 -0400 Subject: [PATCH 0209/1940] libata: fix ATAPI DMA alignment issues ATAPI needs to be padded to next 4 byte boundary, if misaligned. Original work by me, many fixes from Tejun Heo. --- drivers/scsi/ahci.c | 28 ++++++--- drivers/scsi/libata-core.c | 123 ++++++++++++++++++++++++++++++++----- drivers/scsi/libata-scsi.c | 14 ++++- drivers/scsi/sata_qstor.c | 8 ++- drivers/scsi/sata_sx4.c | 13 ++-- include/linux/libata.h | 27 +++++++- 6 files changed, 173 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index c2c8fa828e24..6e4bb36f8d7c 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -314,8 +314,15 @@ static int ahci_port_start(struct ata_port *ap) return -ENOMEM; memset(pp, 0, sizeof(*pp)); + ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); + if (!ap->pad) { + kfree(pp); + return -ENOMEM; + } + mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { + dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); return -ENOMEM; } @@ -391,6 +398,7 @@ static void ahci_port_stop(struct ata_port *ap) ap->private_data = NULL; dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); + dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); } @@ -476,23 +484,23 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) static void ahci_fill_sg(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; - unsigned int i; + struct scatterlist *sg; + struct ahci_sg *ahci_sg; VPRINTK("ENTER\n"); /* * Next, the S/G list. */ - for (i = 0; i < qc->n_elem; i++) { - u32 sg_len; - dma_addr_t addr; + ahci_sg = pp->cmd_tbl_sg; + ata_for_each_sg(sg, qc) { + dma_addr_t addr = sg_dma_address(sg); + u32 sg_len = sg_dma_len(sg); - addr = sg_dma_address(&qc->sg[i]); - sg_len = sg_dma_len(&qc->sg[i]); - - pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff); - pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); - pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1); + ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); + ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); + ahci_sg->flags_size = cpu_to_le32(sg_len - 1); + ahci_sg++; } } diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index e5b01997117a..943b44c3c16f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2156,8 +2156,9 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) static void ata_sg_clean(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; int dir = qc->dma_dir; + void *pad_buf = NULL; assert(qc->flags & ATA_QCFLAG_DMAMAP); assert(sg != NULL); @@ -2167,14 +2168,35 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) DPRINTK("unmapping %u sg elements\n", qc->n_elem); - if (qc->flags & ATA_QCFLAG_SG) + /* if we padded the buffer out to 32-bit bound, and data + * xfer direction is from-device, we must copy from the + * pad buffer back into the supplied buffer + */ + if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) + pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + + if (qc->flags & ATA_QCFLAG_SG) { dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); - else + /* restore last sg */ + sg[qc->orig_n_elem - 1].length += qc->pad_len; + if (pad_buf) { + struct scatterlist *psg = &qc->pad_sgent; + void *addr = kmap_atomic(psg->page, KM_IRQ0); + memcpy(addr + psg->offset, pad_buf, qc->pad_len); + kunmap_atomic(psg->page, KM_IRQ0); + } + } else { dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), dir); + /* restore sg */ + sg->length += qc->pad_len; + if (pad_buf) + memcpy(qc->buf_virt + sg->length - qc->pad_len, + pad_buf, qc->pad_len); + } qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->sg = NULL; + qc->__sg = NULL; } /** @@ -2190,15 +2212,15 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) */ static void ata_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; - unsigned int idx, nelem; + struct scatterlist *sg; + unsigned int idx; - assert(sg != NULL); + assert(qc->__sg != NULL); assert(qc->n_elem > 0); idx = 0; - for (nelem = qc->n_elem; nelem; nelem--,sg++) { + ata_for_each_sg(sg, qc) { u32 addr, offset; u32 sg_len, len; @@ -2289,11 +2311,12 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) qc->flags |= ATA_QCFLAG_SINGLE; memset(&qc->sgent, 0, sizeof(qc->sgent)); - qc->sg = &qc->sgent; + qc->__sg = &qc->sgent; qc->n_elem = 1; + qc->orig_n_elem = 1; qc->buf_virt = buf; - sg = qc->sg; + sg = qc->__sg; sg->page = virt_to_page(buf); sg->offset = (unsigned long) buf & ~PAGE_MASK; sg->length = buflen; @@ -2317,8 +2340,9 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { qc->flags |= ATA_QCFLAG_SG; - qc->sg = sg; + qc->__sg = sg; qc->n_elem = n_elem; + qc->orig_n_elem = n_elem; } /** @@ -2338,9 +2362,32 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; int dir = qc->dma_dir; - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; dma_addr_t dma_address; + /* we must lengthen transfers to end on a 32-bit boundary */ + qc->pad_len = sg->length & 3; + if (qc->pad_len) { + void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + struct scatterlist *psg = &qc->pad_sgent; + + assert(qc->dev->class == ATA_DEV_ATAPI); + + memset(pad_buf, 0, ATA_DMA_PAD_SZ); + + if (qc->tf.flags & ATA_TFLAG_WRITE) + memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len, + qc->pad_len); + + sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + sg_dma_len(psg) = ATA_DMA_PAD_SZ; + /* trim sg */ + sg->length -= qc->pad_len; + + DPRINTK("padding done, sg->length=%u pad_len=%u\n", + sg->length, qc->pad_len); + } + dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, sg->length, dir); if (dma_mapping_error(dma_address)) @@ -2372,12 +2419,47 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) static int ata_sg_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; + struct scatterlist *lsg = &sg[qc->n_elem - 1]; int n_elem, dir; VPRINTK("ENTER, ata%u\n", ap->id); assert(qc->flags & ATA_QCFLAG_SG); + /* we must lengthen transfers to end on a 32-bit boundary */ + qc->pad_len = lsg->length & 3; + if (qc->pad_len) { + void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + struct scatterlist *psg = &qc->pad_sgent; + unsigned int offset; + + assert(qc->dev->class == ATA_DEV_ATAPI); + + memset(pad_buf, 0, ATA_DMA_PAD_SZ); + + /* + * psg->page/offset are used to copy to-be-written + * data in this function or read data in ata_sg_clean. + */ + offset = lsg->offset + lsg->length - qc->pad_len; + psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT); + psg->offset = offset_in_page(offset); + + if (qc->tf.flags & ATA_TFLAG_WRITE) { + void *addr = kmap_atomic(psg->page, KM_IRQ0); + memcpy(pad_buf, addr + psg->offset, qc->pad_len); + kunmap_atomic(psg->page, KM_IRQ0); + } + + sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + sg_dma_len(psg) = ATA_DMA_PAD_SZ; + /* trim last sg */ + lsg->length -= qc->pad_len; + + DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", + qc->n_elem - 1, lsg->length, qc->pad_len); + } + dir = qc->dma_dir; n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir); if (n_elem < 1) @@ -2655,7 +2737,7 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, static void ata_pio_sector(struct ata_queued_cmd *qc) { int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; struct ata_port *ap = qc->ap; struct page *page; unsigned int offset; @@ -2705,7 +2787,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) { int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; struct ata_port *ap = qc->ap; struct page *page; unsigned char *buf; @@ -2738,7 +2820,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) return; } - sg = &qc->sg[qc->cursg]; + sg = &qc->__sg[qc->cursg]; page = sg->page; offset = sg->offset + qc->cursg_ofs; @@ -3145,7 +3227,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, qc = ata_qc_new(ap); if (qc) { - qc->sg = NULL; + qc->__sg = NULL; qc->flags = 0; qc->scsicmd = NULL; qc->ap = ap; @@ -3837,6 +3919,12 @@ int ata_port_start (struct ata_port *ap) if (!ap->prd) return -ENOMEM; + ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); + if (!ap->pad) { + dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); + return -ENOMEM; + } + DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); return 0; @@ -3859,6 +3947,7 @@ void ata_port_stop (struct ata_port *ap) struct device *dev = ap->host_set->dev; dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); + dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); } void ata_host_stop (struct ata_host_set *host_set) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 104fd9a63e73..ee3f1050fb5f 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -150,10 +150,10 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap, qc->scsidone = done; if (cmd->use_sg) { - qc->sg = (struct scatterlist *) cmd->request_buffer; + qc->__sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; } else { - qc->sg = &qc->sgent; + qc->__sg = &qc->sgent; qc->n_elem = 1; } } else { @@ -364,6 +364,16 @@ int ata_scsi_slave_config(struct scsi_device *sdev) */ blk_queue_max_sectors(sdev->request_queue, 2048); } + + /* + * SATA DMA transfers must be multiples of 4 byte, so + * we need to pad ATAPI transfers using an extra sg. + * Decrement max hw segments accordingly. + */ + if (dev->class == ATA_DEV_ATAPI) { + request_queue_t *q = sdev->request_queue; + blk_queue_max_hw_segments(q, q->max_hw_segments - 1); + } } return 0; /* scsi layer doesn't check return value, sigh */ diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index ffcdeb68641c..69a9b1cf6f9c 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -268,16 +268,17 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static void qs_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; + struct scatterlist *sg; struct ata_port *ap = qc->ap; struct qs_port_priv *pp = ap->private_data; unsigned int nelem; u8 *prd = pp->pkt + QS_CPB_BYTES; - assert(sg != NULL); + assert(qc->__sg != NULL); assert(qc->n_elem > 0); - for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { + nelem = 0; + ata_for_each_sg(sg, qc) { u64 addr; u32 len; @@ -291,6 +292,7 @@ static void qs_fill_sg(struct ata_queued_cmd *qc) VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem, (unsigned long long)addr, len); + nelem++; } } diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 540a85191172..79fdbbab513e 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -449,14 +449,14 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, static void pdc20621_dma_prep(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; + struct scatterlist *sg; struct ata_port *ap = qc->ap; struct pdc_port_priv *pp = ap->private_data; void __iomem *mmio = ap->host_set->mmio_base; struct pdc_host_priv *hpriv = ap->host_set->private_data; void __iomem *dimm_mmio = hpriv->dimm_mmio; unsigned int portno = ap->port_no; - unsigned int i, last, idx, total_len = 0, sgt_len; + unsigned int i, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; assert(qc->flags & ATA_QCFLAG_DMAMAP); @@ -469,12 +469,11 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) /* * Build S/G table */ - last = qc->n_elem; idx = 0; - for (i = 0; i < last; i++) { - buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i])); - buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i])); - total_len += sg_dma_len(&sg[i]); + ata_for_each_sg(sg, qc) { + buf[idx++] = cpu_to_le32(sg_dma_address(sg)); + buf[idx++] = cpu_to_le32(sg_dma_len(sg)); + total_len += sg_dma_len(sg); } buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT); sgt_len = idx * 4; diff --git a/include/linux/libata.h b/include/linux/libata.h index ceee1fc42c60..3ab67622ef93 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -154,6 +154,10 @@ enum { ATA_SHIFT_UDMA = 0, ATA_SHIFT_MWDMA = 8, ATA_SHIFT_PIO = 11, + + /* size of buffer to pad xfers ending on unaligned boundaries */ + ATA_DMA_PAD_SZ = 4, + ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, }; enum pio_task_states { @@ -237,9 +241,12 @@ struct ata_queued_cmd { unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned int tag; unsigned int n_elem; + unsigned int orig_n_elem; int dma_dir; + unsigned int pad_len; + unsigned int nsect; unsigned int cursect; @@ -250,9 +257,11 @@ struct ata_queued_cmd { unsigned int cursg_ofs; struct scatterlist sgent; + struct scatterlist pad_sgent; void *buf_virt; - struct scatterlist *sg; + /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ + struct scatterlist *__sg; ata_qc_cb_t complete_fn; @@ -295,6 +304,9 @@ struct ata_port { struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ + void *pad; /* array of DMA pad buffers */ + dma_addr_t pad_dma; + struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ u8 ctl; /* cache of ATA control register */ @@ -458,6 +470,19 @@ extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); #endif /* CONFIG_PCI */ +static inline struct scatterlist * +ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) +{ + if (sg == &qc->pad_sgent) + return NULL; + if (++sg - qc->__sg < qc->n_elem) + return sg; + return qc->pad_len ? &qc->pad_sgent : NULL; +} + +#define ata_for_each_sg(sg, qc) \ + for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) + static inline unsigned int ata_tag_valid(unsigned int tag) { return (tag < ATA_MAX_QUEUE) ? 1 : 0; From 6148a742b2bd76abfe0c1fc50dd747cb9f28cd6b Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 5 Oct 2005 12:23:19 -0700 Subject: [PATCH 0210/1940] CIFS: Create routine find_writable_file to reduce redundant code Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 1 + fs/cifs/file.c | 112 ++++++++++++++------------------------------ fs/cifs/inode.c | 56 ++++++---------------- 3 files changed, 50 insertions(+), 119 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fb3e76043c50..d301149b1bb0 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -54,6 +54,7 @@ extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb); extern int is_size_safe_to_change(struct cifsInodeInfo *); +extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); extern unsigned int smbCalcSize(struct smb_hdr *ptr); extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 941108352547..94875455d7fa 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -904,6 +904,25 @@ static ssize_t cifs_write(struct file *file, const char *write_data, return total_written; } +static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) +{ + struct cifsFileInfo *open_file; + + read_lock(&GlobalSMBSeslock); + list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { + if (open_file->closePend) + continue; + if (open_file->pfile && + ((open_file->pfile->f_flags & O_RDWR) || + (open_file->pfile->f_flags & O_WRONLY))) { + read_unlock(&GlobalSMBSeslock); + return open_file; + } + } + read_unlock(&GlobalSMBSeslock); + return NULL; +} + static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) { struct address_space *mapping = page->mapping; @@ -914,10 +933,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; struct inode *inode; - struct cifsInodeInfo *cifsInode; - struct cifsFileInfo *open_file = NULL; - struct list_head *tmp; - struct list_head *tmp1; + struct cifsFileInfo *open_file; if (!mapping || !mapping->host) return -EFAULT; @@ -945,49 +961,19 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) if (mapping->host->i_size - offset < (loff_t)to) to = (unsigned)(mapping->host->i_size - offset); - cifsInode = CIFS_I(mapping->host); - read_lock(&GlobalSMBSeslock); - /* BB we should start at the end */ - list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { - open_file = list_entry(tmp, struct cifsFileInfo, flist); - if (open_file->closePend) - continue; - /* We check if file is open for writing first */ - if ((open_file->pfile) && - ((open_file->pfile->f_flags & O_RDWR) || - (open_file->pfile->f_flags & O_WRONLY))) { - read_unlock(&GlobalSMBSeslock); - bytes_written = cifs_write(open_file->pfile, - write_data, to-from, - &offset); - read_lock(&GlobalSMBSeslock); + open_file = find_writable_file(CIFS_I(mapping->host)); + if (open_file) { + bytes_written = cifs_write(open_file->pfile, write_data, + to-from, &offset); /* Does mm or vfs already set times? */ - inode->i_atime = - inode->i_mtime = current_fs_time(inode->i_sb); - if ((bytes_written > 0) && (offset)) { - rc = 0; - } else if (bytes_written < 0) { - if (rc == -EBADF) { - /* have seen a case in which kernel seemed to - have closed/freed a file even with writes - active so we might as well see if there are - other file structs to try for the same - inode before giving up */ - continue; - } else - rc = bytes_written; - } - break; /* now that we found a valid file handle and - tried to write to it we are done, no sense - continuing to loop looking for another */ + inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); + if ((bytes_written > 0) && (offset)) { + rc = 0; + } else if (bytes_written < 0) { + if (rc != -EBADF) + rc = bytes_written; } - if (tmp->next == NULL) { - cFYI(1, ("File instance %p removed", tmp)); - break; - } - } - read_unlock(&GlobalSMBSeslock); - if (open_file == NULL) { + } else { cFYI(1, ("No writeable filehandles for inode")); rc = -EIO; } @@ -1604,40 +1590,12 @@ static int cifs_readpage(struct file *file, struct page *page) page caching in the current Linux kernel design */ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode) { - struct list_head *tmp; - struct list_head *tmp1; - struct cifsFileInfo *open_file = NULL; - int rc = TRUE; - - if (cifsInode == NULL) - return rc; - - read_lock(&GlobalSMBSeslock); - list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { - open_file = list_entry(tmp, struct cifsFileInfo, flist); - if (open_file == NULL) - break; - if (open_file->closePend) - continue; - /* We check if file is open for writing, - BB we could supplement this with a check to see if file size - changes have been flushed to server - ie inode metadata dirty */ - if ((open_file->pfile) && - ((open_file->pfile->f_flags & O_RDWR) || - (open_file->pfile->f_flags & O_WRONLY))) { - rc = FALSE; - break; - } - if (tmp->next == NULL) { - cFYI(1, ("File instance %p removed", tmp)); - break; - } - } - read_unlock(&GlobalSMBSeslock); - return rc; + if (cifsInode && find_writable_file(cifsInode)) + return 0; + else + return 1; } - static int cifs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ca3af4eafcb2..49efdefcff7c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -995,7 +995,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) filemap_fdatawait(direntry->d_inode->i_mapping); if (attrs->ia_valid & ATTR_SIZE) { - read_lock(&GlobalSMBSeslock); /* To avoid spurious oplock breaks from server, in the case of inodes that we already have open, avoid doing path based setting of file size if we can do it by handle. @@ -1003,49 +1002,22 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) when the local oplock break takes longer to flush writebehind data than the SMB timeout for the SetPathInfo request would allow */ - list_for_each(tmp, &cifsInode->openFileList) { - open_file = list_entry(tmp, struct cifsFileInfo, - flist); - /* We check if file is open for writing first */ - if ((open_file->pfile) && - ((open_file->pfile->f_flags & O_RDWR) || - (open_file->pfile->f_flags & O_WRONLY))) { - if (open_file->invalidHandle == FALSE) { - /* we found a valid, writeable network - file handle to use to try to set the - file size */ - __u16 nfid = open_file->netfid; - __u32 npid = open_file->pid; - read_unlock(&GlobalSMBSeslock); - found = TRUE; - rc = CIFSSMBSetFileSize(xid, pTcon, - attrs->ia_size, nfid, npid, - FALSE); - cFYI(1, ("SetFileSize by handle " - "(setattrs) rc = %d", rc)); - /* Do not need reopen and retry on - EAGAIN since we will retry by - pathname below */ - - /* now that we found one valid file - handle no sense continuing to loop - trying others, so break here */ - if(rc == -EINVAL) { - int bytes_written; - rc = CIFSSMBWrite(xid, pTcon, - nfid, 0, - attrs->ia_size, - &bytes_written, NULL, - NULL, 1 /* 45 sec */); - cFYI(1,("wrt seteof rc %d",rc)); - } - break; - } + open_file = find_writable_file(cifsInode); + if (open_file) { + __u16 nfid = open_file->netfid; + __u32 npid = open_file->pid; + rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, + nfid, npid, FALSE); + cFYI(1,("SetFSize for attrs rc = %d", rc)); + if(rc == -EINVAL) { + int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, + nfid, 0, attrs->ia_size, + &bytes_written, NULL, NULL, + 1 /* 45 seconds */); + cFYI(1,("Wrt seteof rc %d", rc)); } } - if (found == FALSE) - read_unlock(&GlobalSMBSeslock); - if (rc != 0) { /* Set file size by pathname rather than by handle either because no valid, writeable file handle for From 37c0eb4677f733a773df6287b0f73f00274402e3 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 5 Oct 2005 14:50:29 -0700 Subject: [PATCH 0211/1940] CIFS: implement cifs_writepages to perform multi-page I/O Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/file.c | 191 ++++++++++++++++++++++++++++++++++++++++++-- fs/cifs/transport.c | 10 ++- 2 files changed, 190 insertions(+), 11 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 94875455d7fa..0473b221f643 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -21,11 +21,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include +#include #include #include #include +#include #include #include "cifsfs.h" #include "cifspdu.h" @@ -916,6 +919,16 @@ static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) ((open_file->pfile->f_flags & O_RDWR) || (open_file->pfile->f_flags & O_WRONLY))) { read_unlock(&GlobalSMBSeslock); + if(open_file->invalidHandle) { + rc = cifs_reopen_file(cifs_inode->vfs_inode, + open_file->pfile, FALSE); + /* if it fails, try another handle - might be */ + /* dangerous to hold up writepages with retry */ + if(rc) { + read_lock(&GlobalSMBSeslock); + continue; + } + } return open_file; } } @@ -982,20 +995,181 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) return rc; } -#if 0 +#ifdef CONFIG_CIFS_EXPERIMENTAL static int cifs_writepages(struct address_space *mapping, - struct writeback_control *wbc) + struct writeback_control *wbc) { - int rc = -EFAULT; + struct backing_dev_info *bdi = mapping->backing_dev_info; + unsigned int bytes_to_write; + unsigned int bytes_written; + struct cifs_sb_info *cifs_sb; + int done = 0; + pgoff_t end = -1; + pgoff_t index; + int is_range = 0; + struct kvec iov[32]; + int n_iov = 0; + pgoff_t next; + int nr_pages; + __u64 offset = 0; + struct cifsFileInfo *open_file = NULL; + struct page *page; + struct pagevec pvec; + int rc = 0; + int scanned = 0; int xid; + cifs_sb = CIFS_SB(mapping->host->i_sb); + + /* + * If wsize is smaller that the page cache size, default to writing + * one page at a time via cifs_writepage + */ + if (cifs_sb->wsize < PAGE_CACHE_SIZE) + return generic_writepages(mapping, wbc); + + /* + * BB: Is this meaningful for a non-block-device file system? + * If it is, we should test it again after we do I/O + */ + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + return 0; + } + xid = GetXid(); - /* Find contiguous pages then iterate through repeating - call 16K write then Setpageuptodate or if LARGE_WRITE_X - support then send larger writes via kevec so as to eliminate - a memcpy */ + pagevec_init(&pvec, 0); + if (wbc->sync_mode == WB_SYNC_NONE) + index = mapping->writeback_index; /* Start from prev offset */ + else { + index = 0; + scanned = 1; + } + if (wbc->start || wbc->end) { + index = wbc->start >> PAGE_CACHE_SHIFT; + end = wbc->end >> PAGE_CACHE_SHIFT; + is_range = 1; + scanned = 1; + } +retry: + while (!done && (index <= end) && + (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, + min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) { + int first; + unsigned int i; + + if (!open_file) { + open_file = find_writable_file(CIFS_I(mapping->host)); + if (!open_file) { + pagevec_release(&pvec); + cERROR(1, ("No writable handles for inode")); + return -EIO; + } + } + + first = -1; + next = 0; + n_iov = 0; + bytes_to_write = 0; + + for (i = 0; i < nr_pages; i++) { + page = pvec.pages[i]; + /* + * At this point we hold neither mapping->tree_lock nor + * lock on the page itself: the page may be truncated or + * invalidated (changing page->mapping to NULL), or even + * swizzled back from swapper_space to tmpfs file + * mapping + */ + + if (first < 0) + lock_page(page); + else if (TestSetPageLocked(page)) + break; + + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + break; + } + + if (unlikely(is_range) && (page->index > end)) { + done = 1; + unlock_page(page); + break; + } + + if (next && (page->index != next)) { + /* Not next consecutive page */ + unlock_page(page); + break; + } + + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + + if (PageWriteback(page) || + !test_clear_page_dirty(page)) { + unlock_page(page); + break; + } + /* + * BB can we get rid of this? pages are held by pvec + */ + page_cache_get(page); + + /* reserve iov[0] for the smb header */ + n_iov++; + iov[n_iov].iov_base = kmap(page); + iov[n_iov].iov_len = PAGE_CACHE_SIZE; + bytes_to_write += PAGE_CACHE_SIZE; + + if (first < 0) { + first = i; + offset = page_offset(page); + } + next = page->index + 1; + if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize) + break; + } + if (n_iov) { + rc = CIFSSMBWrite2(xid, cifs_sb->tcon, + open_file->netfid, bytes_to_write, + offset, &bytes_written, iov, n_iov, + 1); + if (rc || bytes_written < bytes_to_write) { + cERROR(1,("CIFSSMBWrite2 returned %d, written = %x", + rc, bytes_written)); + set_bit(AS_EIO, &mapping->flags); + SetPageError(page); + } + for (i = 0; i < n_iov; i++) { + page = pvec.pages[first + i]; + kunmap(page); + unlock_page(page); + page_cache_release(page); + } + if ((wbc->nr_to_write -= n_iov) <= 0) + done = 1; + index = next; + } + pagevec_release(&pvec); + } + if (!scanned && !done) { + /* + * We hit the last page and there is more work to be done: wrap + * back to the start of the file + */ + scanned = 1; + index = 0; + goto retry; + } + if (!is_range) + mapping->writeback_index = index; + FreeXid(xid); + return rc; } #endif @@ -1635,6 +1809,9 @@ struct address_space_operations cifs_addr_ops = { .readpage = cifs_readpage, .readpages = cifs_readpages, .writepage = cifs_writepage, +#ifdef CONFIG_CIFS_EXPERIMENTAL + .writepages = cifs_writepages, +#endif .prepare_write = cifs_prepare_write, .commit_write = cifs_commit_write, .set_page_dirty = __set_page_dirty_nobuffers, diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 64c712629f27..e104c1ad2da3 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -395,7 +395,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, if (long_op == -1) goto cifs_no_response_exit2; else if (long_op == 2) /* writes past end of file can take loong time */ - timeout = 300 * HZ; + timeout = 180 * HZ; else if (long_op == 1) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ @@ -431,7 +431,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, spin_unlock(&GlobalMid_Lock); receive_len = midQ->resp_buf->smb_buf_length; } else { - cERROR(1,("No response buffer")); + cERROR(1,("No response to cmd %d mid %d", + midQ->command, midQ->mid)); if(midQ->midState == MID_REQUEST_SUBMITTED) { if(ses->server->tcpStatus == CifsExiting) rc = -EHOSTDOWN; @@ -646,7 +647,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, if (long_op == -1) goto cifs_no_response_exit; else if (long_op == 2) /* writes past end of file can take loong time */ - timeout = 300 * HZ; + timeout = 180 * HZ; else if (long_op == 1) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ @@ -682,7 +683,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, spin_unlock(&GlobalMid_Lock); receive_len = midQ->resp_buf->smb_buf_length; } else { - cERROR(1,("No response buffer")); + cERROR(1,("No response for cmd %d mid %d", + midQ->command, midQ->mid)); if(midQ->midState == MID_REQUEST_SUBMITTED) { if(ses->server->tcpStatus == CifsExiting) rc = -EHOSTDOWN; From 4a77118cd5018fec11bf86f6f8d659352ad9a92b Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 5 Oct 2005 15:14:33 -0700 Subject: [PATCH 0212/1940] CIFS: Allow wsize to exceed CIFSMaxBufSize This allows cifs_writepages to send data in larger chunks from the page cache, without requiring larger memory allocations in other cases. Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/connect.c | 2 +- fs/cifs/file.c | 8 ++++++++ fs/cifs/transport.c | 16 +--------------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f05d9e2016d5..31eb9a3bf627 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1740,7 +1740,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->rsize = volume_info.rsize; else cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ - if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize)) + if(volume_info.wsize) cifs_sb->wsize = volume_info.wsize; else cifs_sb->wsize = CIFSMaxBufSize; /* default */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0473b221f643..0f66ae5b694b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -925,6 +925,7 @@ static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) /* if it fails, try another handle - might be */ /* dangerous to hold up writepages with retry */ if(rc) { + cFYI(1,("failed on reopen file in wp")); read_lock(&GlobalSMBSeslock); continue; } @@ -1028,6 +1029,13 @@ static int cifs_writepages(struct address_space *mapping, if (cifs_sb->wsize < PAGE_CACHE_SIZE) return generic_writepages(mapping, wbc); + /* BB FIXME we do not have code to sign across multiple buffers yet, + so go to older writepage style write which we can sign if needed */ + if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) + if(cifs_sb->tcon->ses->server->secMode & + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + return generic_writepages(mapping, wbc); + /* * BB: Is this meaningful for a non-block-device file system? * If it is, we should test it again after we do I/O diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index e104c1ad2da3..c86b7077b92f 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -361,22 +361,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, return -ENOMEM; } - if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - up(&ses->server->tcpSem); - cERROR(1, - ("Illegal length, greater than maximum frame, %d ", - in_buf->smb_buf_length)); - DeleteMidQEntry(midQ); - /* If not lock req, update # of requests on wire to server */ - if(long_op < 3) { - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - } - return -EIO; - } - /* BB FIXME */ -/* rc = cifs_sign_smb2(in_buf, data, ses->server, &midQ->sequence_number); */ +/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */ midQ->midState = MID_REQUEST_SUBMITTED; rc = smb_send2(ses->server->ssocket, iov, n_vec, From b85a046af3a260e079505e8023ccd10e01cf4f2b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 10:59:19 +1000 Subject: [PATCH 0213/1940] powerpc: Define 32/64 bit asm macros and use them in fpu.S These macros help in writing assembly code that works for both ppc32 and ppc64. With this we now have a common fpu.S. This takes out load_up_fpu from head_64.S. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/fpu.S | 72 ++++++++++++++--------------------- arch/powerpc/kernel/head_64.S | 58 +--------------------------- include/asm-powerpc/ppc_asm.h | 28 +++++++++++--- 3 files changed, 53 insertions(+), 105 deletions(-) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 665d7d34304c..04e95e810b21 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -27,13 +27,9 @@ * Load up this task's FP registers from its thread_struct, * enable the FPU for the current task and return to the task. */ - .globl load_up_fpu -load_up_fpu: +_GLOBAL(load_up_fpu) mfmsr r5 ori r5,r5,MSR_FP -#ifdef CONFIG_PPC64BRIDGE - clrldi r5,r5,1 /* turn off 64-bit mode */ -#endif /* CONFIG_PPC64BRIDGE */ SYNC MTMSRD(r5) /* enable use of fpu now */ isync @@ -43,67 +39,57 @@ load_up_fpu: * to another. Instead we call giveup_fpu in switch_to. */ #ifndef CONFIG_SMP - tophys(r6,0) /* get __pa constant */ - addis r3,r6,last_task_used_math@ha - lwz r4,last_task_used_math@l(r3) - cmpwi 0,r4,0 + LOADBASE(r3, last_task_used_math) + tophys(r3,r3) + LDL r4,OFF(last_task_used_math)(r3) + CMPI 0,r4,0 beq 1f - add r4,r4,r6 + tophys(r4,r4) addi r4,r4,THREAD /* want last_task_used_math->thread */ SAVE_32FPRS(0, r4) mffs fr0 stfd fr0,THREAD_FPSCR-4(r4) - lwz r5,PT_REGS(r4) - add r5,r5,r6 - lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + LDL r5,PT_REGS(r4) + tophys(r5,r5) + LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r10,MSR_FP|MSR_FE0|MSR_FE1 andc r4,r4,r10 /* disable FP for previous task */ - stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) + STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: #endif /* CONFIG_SMP */ /* enable use of FP after return */ +#ifdef CONFIG_PPC32 mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ lwz r4,THREAD_FPEXC_MODE(r5) ori r9,r9,MSR_FP /* enable FP for current */ or r9,r9,r4 +#else + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r4,THREAD_FPEXC_MODE(r5) + ori r12,r12,MSR_FP + or r12,r12,r4 + std r12,_MSR(r1) +#endif lfd fr0,THREAD_FPSCR-4(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP subi r4,r5,THREAD - sub r4,r4,r6 - stw r4,last_task_used_math@l(r3) + tovirt(r4,r4) + STL r4,OFF(last_task_used_math)(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ /* we haven't used ctr or xer or lr */ b fast_exception_return -/* - * FP unavailable trap from kernel - print a message, but let - * the task use FP in the kernel until it returns to user mode. - */ - .globl KernelFP -KernelFP: - lwz r3,_MSR(r1) - ori r3,r3,MSR_FP - stw r3,_MSR(r1) /* enable use of FP after return */ - lis r3,86f@h - ori r3,r3,86f@l - mr r4,r2 /* current */ - lwz r5,_NIP(r1) - bl printk - b ret_from_except -86: .string "floating point used in kernel (task=%p, pc=%x)\n" - .align 4,0 - /* * giveup_fpu(tsk) * Disable FP for the task given as the argument, * and save the floating-point registers in its thread_struct. * Enables the FPU for use in the kernel on return. */ - .globl giveup_fpu -giveup_fpu: +_GLOBAL(giveup_fpu) mfmsr r5 ori r5,r5,MSR_FP SYNC_601 @@ -111,23 +97,23 @@ giveup_fpu: MTMSRD(r5) /* enable use of fpu now */ SYNC_601 isync - cmpwi 0,r3,0 + CMPI 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ - lwz r5,PT_REGS(r3) - cmpwi 0,r5,0 + LDL r5,PT_REGS(r3) + CMPI 0,r5,0 SAVE_32FPRS(0, r3) mffs fr0 stfd fr0,THREAD_FPSCR-4(r3) beq 1f - lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r3,MSR_FP|MSR_FE0|MSR_FE1 andc r4,r4,r3 /* disable FP for previous task */ - stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) + STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: #ifndef CONFIG_SMP li r5,0 - lis r4,last_task_used_math@ha - stw r5,last_task_used_math@l(r4) + LOADBASE(r4,last_task_used_math) + STL r5,OFF(last_task_used_math)(r4) #endif /* CONFIG_SMP */ blr diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index db0cd3587627..a36ee6ecbaea 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -80,7 +80,7 @@ _stext: _GLOBAL(__start) /* NOP this out unconditionally */ BEGIN_FTR_SECTION - b .__start_initialization_multiplatform + b .__start_initialization_multiplatform END_FTR_SECTION(0, 1) #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -857,62 +857,6 @@ fp_unavailable_common: bl .kernel_fp_unavailable_exception BUG_OPCODE -/* - * load_up_fpu(unused, unused, tsk) - * Disable FP for the task which had the FPU previously, - * and save its floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - * On SMP we know the fpu is free, since we give it up every - * switch (ie, no lazy save of the FP registers). - * On entry: r13 == 'current' && last_task_used_math != 'current' - */ -_STATIC(load_up_fpu) - mfmsr r5 /* grab the current MSR */ - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - * - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_math@got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save FP state to last_task_used_math's THREAD struct */ - addi r4,r4,THREAD - SAVE_32FPRS(0, r4) - mffs fr0 - stfd fr0,THREAD_FPSCR(r4) - /* Disable FP for last_task_used_math */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r6,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* enable use of FP after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - ld r4,THREAD_FPEXC_MODE(r5) - ori r12,r12,MSR_FP - or r12,r12,r4 - std r12,_MSR(r1) - lfd fr0,THREAD_FPSCR(r5) - mtfsf 0xff,fr0 - REST_32FPRS(0, r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - .align 7 .globl altivec_unavailable_common altivec_unavailable_common: diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 4efa71878fa9..6cd52c130332 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -103,12 +103,13 @@ oris rn,rn,name##@h; \ ori rn,rn,name##@l -#define LOADBASE(rn,name) \ - lis rn,name@highest; \ - ori rn,rn,name@higher; \ - rldicr rn,rn,32,31; \ - oris rn,rn,name@ha +#define LOADBASE(rn,name) \ + .section .toc,"aw"; \ +1: .tc name[TC],name; \ + .previous; \ + ld rn,1b@toc(r2) +#define OFF(name) 0 #define SET_REG_TO_CONST(reg, value) \ lis reg,(((value)>>48)&0xFFFF); \ @@ -123,6 +124,23 @@ rldicr reg,reg,32,31; \ oris reg,reg,(label)@h; \ ori reg,reg,(label)@l; + +/* operations for longs and pointers */ +#define LDL ld +#define STL std +#define CMPI cmpdi + +#else /* 32-bit */ +#define LOADBASE(rn,name) \ + lis rn,name@ha + +#define OFF(name) name@l + +/* operations for longs and pointers */ +#define LDL lwz +#define STL stw +#define CMPI cmpwi + #endif /* various errata or part fixups */ From 9b6b563c0d2d25ecc3111916031aa7255543fbfb Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 12:06:20 +1000 Subject: [PATCH 0214/1940] powerpc: Merge in the ppc64 version of the prom code. This brings in the ppc64 version of prom_init.c, prom.c and btext.c and makes them work for ppc32. This also brings in the new calling convention, where the first entry to the kernel (with r5 != 0) goes to the prom_init code, which then restarts from the beginning (with r5 == 0) after it has done its stuff. For now this also brings in the ppc32 version of setup.c. It also merges lmb.h. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 11 +- arch/powerpc/kernel/btext.c | 852 +++++++ arch/powerpc/kernel/head.S | 16 +- arch/powerpc/kernel/ppc_ksyms.c | 30 - arch/powerpc/kernel/prom.c | 2141 ++++++++++++++++++ arch/powerpc/kernel/prom_init.c | 2126 +++++++++++++++++ arch/powerpc/kernel/setup.c | 678 ++++++ arch/powerpc/platforms/powermac/pmac_setup.c | 11 +- include/asm-powerpc/cputable.h | 3 + include/asm-powerpc/iommu.h | 112 + include/asm-powerpc/lmb.h | 81 + include/asm-powerpc/pSeries_reconfig.h | 25 + include/asm-powerpc/prom.h | 215 ++ include/asm-powerpc/rtas.h | 249 ++ include/asm-powerpc/system.h | 5 + 15 files changed, 6507 insertions(+), 48 deletions(-) create mode 100644 arch/powerpc/kernel/btext.c create mode 100644 arch/powerpc/kernel/prom.c create mode 100644 arch/powerpc/kernel/prom_init.c create mode 100644 arch/powerpc/kernel/setup.c create mode 100644 include/asm-powerpc/iommu.h create mode 100644 include/asm-powerpc/lmb.h create mode 100644 include/asm-powerpc/pSeries_reconfig.h create mode 100644 include/asm-powerpc/prom.h create mode 100644 include/asm-powerpc/rtas.h diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index be3f9d123a6d..4842e82dbc2b 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -5,10 +5,11 @@ ifeq ($(CONFIG_PPC64),y) EXTRA_CFLAGS += -mno-minimal-toc endif - ifeq ($(CONFIG_PPC32),y) -extra-$(CONFIG_PPC_STD_MMU) := head.o +CFLAGS_prom_init.o += -fPIC endif + +extra-$(CONFIG_PPC_STD_MMU) := head.o extra-$(CONFIG_PPC64) := head_64.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o @@ -18,13 +19,15 @@ extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y := traps.o -obj-$(CONFIG_PPC32) += semaphore.o process.o +obj-y := traps.o prom.o semaphore.o +obj-$(CONFIG_PPC32) += setup.o process.o obj-$(CONFIG_PPC64) += idle_power4.o ifeq ($(CONFIG_PPC32),y) +obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o endif obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o +obj-$(CONFIG_BOOTX_TEXT) += btext.o ifeq ($(CONFIG_PPC_ISERIES),y) arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c new file mode 100644 index 000000000000..44f5d98e27c0 --- /dev/null +++ b/arch/powerpc/kernel/btext.c @@ -0,0 +1,852 @@ +/* + * Procedures for drawing on the screen early on in the boot process. + * + * Benjamin Herrenschmidt + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NO_SCROLL + +#ifndef NO_SCROLL +static void scrollscreen(void); +#endif + +static void draw_byte(unsigned char c, long locX, long locY); +static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); +static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); +static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); + +static int g_loc_X; +static int g_loc_Y; +static int g_max_loc_X; +static int g_max_loc_Y; + +static int dispDeviceRowBytes; +static int dispDeviceDepth; +static int dispDeviceRect[4]; +static unsigned char *dispDeviceBase, *logicalDisplayBase; + +unsigned long disp_BAT[2] __initdata = {0, 0}; + +#define cmapsz (16*256) + +static unsigned char vga_font[cmapsz]; + +int boot_text_mapped; +int force_printk_to_btext = 0; + + +/* Calc BAT values for mapping the display and store them + * in disp_BAT. Those values are then used from head.S to map + * the display during identify_machine() and MMU_Init() + * + * The display is mapped to virtual address 0xD0000000, rather + * than 1:1, because some some CHRP machines put the frame buffer + * in the region starting at 0xC0000000 (KERNELBASE). + * This mapping is temporary and will disappear as soon as the + * setup done by MMU_Init() is applied. + * + * For now, we align the BAT and then map 8Mb on 601 and 16Mb + * on other PPCs. This may cause trouble if the framebuffer + * is really badly aligned, but I didn't encounter this case + * yet. + */ +void __init +btext_prepare_BAT(void) +{ + unsigned long vaddr = KERNELBASE + 0x10000000; + unsigned long addr; + unsigned long lowbits; + + addr = (unsigned long)dispDeviceBase; + if (!addr) { + boot_text_mapped = 0; + return; + } + if (PVR_VER(mfspr(SPRN_PVR)) != 1) { + /* 603, 604, G3, G4, ... */ + lowbits = addr & ~0xFF000000UL; + addr &= 0xFF000000UL; + disp_BAT[0] = vaddr | (BL_16M<<2) | 2; + disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + } else { + /* 601 */ + lowbits = addr & ~0xFF800000UL; + addr &= 0xFF800000UL; + disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4; + disp_BAT[1] = addr | BL_8M | 0x40; + } + logicalDisplayBase = (void *) (vaddr + lowbits); +} + +/* This function will enable the early boot text when doing OF booting. This + * way, xmon output should work too + */ +void __init +btext_setup_display(int width, int height, int depth, int pitch, + unsigned long address) +{ + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = width / 8; + g_max_loc_Y = height / 16; + logicalDisplayBase = (unsigned char *)address; + dispDeviceBase = (unsigned char *)address; + dispDeviceRowBytes = pitch; + dispDeviceDepth = depth; + dispDeviceRect[0] = dispDeviceRect[1] = 0; + dispDeviceRect[2] = width; + dispDeviceRect[3] = height; + boot_text_mapped = 1; +} + +/* Here's a small text engine to use during early boot + * or for debugging purposes + * + * todo: + * + * - build some kind of vgacon with it to enable early printk + * - move to a separate file + * - add a few video driver hooks to keep in sync with display + * changes. + */ + +void map_boot_text(void) +{ + unsigned long base, offset, size; + unsigned char *vbase; + + /* By default, we are no longer mapped */ + boot_text_mapped = 0; + if (dispDeviceBase == 0) + return; + base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL; + offset = ((unsigned long) dispDeviceBase) - base; + size = dispDeviceRowBytes * dispDeviceRect[3] + offset + + dispDeviceRect[0]; + vbase = __ioremap(base, size, _PAGE_NO_CACHE); + if (vbase == 0) + return; + logicalDisplayBase = vbase + offset; + boot_text_mapped = 1; +} + +int btext_initialize(struct device_node *np) +{ + unsigned int width, height, depth, pitch; + unsigned long address = 0; + u32 *prop; + + prop = (u32 *)get_property(np, "width", NULL); + if (prop == NULL) + return -EINVAL; + width = *prop; + prop = (u32 *)get_property(np, "height", NULL); + if (prop == NULL) + return -EINVAL; + height = *prop; + prop = (u32 *)get_property(np, "depth", NULL); + if (prop == NULL) + return -EINVAL; + depth = *prop; + pitch = width * ((depth + 7) / 8); + prop = (u32 *)get_property(np, "linebytes", NULL); + if (prop) + pitch = *prop; + if (pitch == 1) + pitch = 0x1000; + prop = (u32 *)get_property(np, "address", NULL); + if (prop) + address = *prop; + + /* FIXME: Add support for PCI reg properties */ + + if (address == 0) + return -EINVAL; + + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = width / 8; + g_max_loc_Y = height / 16; + logicalDisplayBase = (unsigned char *)address; + dispDeviceBase = (unsigned char *)address; + dispDeviceRowBytes = pitch; + dispDeviceDepth = depth; + dispDeviceRect[0] = dispDeviceRect[1] = 0; + dispDeviceRect[2] = width; + dispDeviceRect[3] = height; + + map_boot_text(); + + return 0; +} + +void __init init_boot_display(void) +{ + char *name; + struct device_node *np = NULL; + int rc = -ENODEV; + + printk("trying to initialize btext ...\n"); + + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + if (name != NULL) { + np = of_find_node_by_path(name); + if (np != NULL) { + if (strcmp(np->type, "display") != 0) { + printk("boot stdout isn't a display !\n"); + of_node_put(np); + np = NULL; + } + } + } + if (np) + rc = btext_initialize(np); + if (rc == 0) + return; + + for (np = NULL; (np = of_find_node_by_type(np, "display"));) { + if (get_property(np, "linux,opened", NULL)) { + printk("trying %s ...\n", np->full_name); + rc = btext_initialize(np); + printk("result: %d\n", rc); + } + if (rc == 0) + return; + } +} + +/* Calc the base address of a given point (x,y) */ +static unsigned char * calc_base(int x, int y) +{ + unsigned char *base; + + base = logicalDisplayBase; + if (base == 0) + base = dispDeviceBase; + base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3); + base += (y + dispDeviceRect[1]) * dispDeviceRowBytes; + return base; +} + +/* Adjust the display to a new resolution */ +void btext_update_display(unsigned long phys, int width, int height, + int depth, int pitch) +{ + if (dispDeviceBase == 0) + return; + + /* check it's the same frame buffer (within 256MB) */ + if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000) + return; + + dispDeviceBase = (__u8 *) phys; + dispDeviceRect[0] = 0; + dispDeviceRect[1] = 0; + dispDeviceRect[2] = width; + dispDeviceRect[3] = height; + dispDeviceDepth = depth; + dispDeviceRowBytes = pitch; + if (boot_text_mapped) { + iounmap(logicalDisplayBase); + boot_text_mapped = 0; + } + map_boot_text(); + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = width / 8; + g_max_loc_Y = height / 16; +} +EXPORT_SYMBOL(btext_update_display); + +void btext_clearscreen(void) +{ + unsigned long *base = (unsigned long *)calc_base(0, 0); + unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * + (dispDeviceDepth >> 3)) >> 3; + int i,j; + + for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) + { + unsigned long *ptr = base; + for(j=width; j; --j) + *(ptr++) = 0; + base += (dispDeviceRowBytes >> 3); + } +} + +#ifndef NO_SCROLL +static void scrollscreen(void) +{ + unsigned long *src = (unsigned long *)calc_base(0,16); + unsigned long *dst = (unsigned long *)calc_base(0,0); + unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * + (dispDeviceDepth >> 3)) >> 3; + int i,j; + + for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) + { + unsigned long *src_ptr = src; + unsigned long *dst_ptr = dst; + for(j=width; j; --j) + *(dst_ptr++) = *(src_ptr++); + src += (dispDeviceRowBytes >> 3); + dst += (dispDeviceRowBytes >> 3); + } + for (i=0; i<16; i++) + { + unsigned long *dst_ptr = dst; + for(j=width; j; --j) + *(dst_ptr++) = 0; + dst += (dispDeviceRowBytes >> 3); + } +} +#endif /* ndef NO_SCROLL */ + +void btext_drawchar(char c) +{ + int cline = 0; +#ifdef NO_SCROLL + int x; +#endif + if (!boot_text_mapped) + return; + + switch (c) { + case '\b': + if (g_loc_X > 0) + --g_loc_X; + break; + case '\t': + g_loc_X = (g_loc_X & -8) + 8; + break; + case '\r': + g_loc_X = 0; + break; + case '\n': + g_loc_X = 0; + g_loc_Y++; + cline = 1; + break; + default: + draw_byte(c, g_loc_X++, g_loc_Y); + } + if (g_loc_X >= g_max_loc_X) { + g_loc_X = 0; + g_loc_Y++; + cline = 1; + } +#ifndef NO_SCROLL + while (g_loc_Y >= g_max_loc_Y) { + scrollscreen(); + g_loc_Y--; + } +#else + /* wrap around from bottom to top of screen so we don't + waste time scrolling each line. -- paulus. */ + if (g_loc_Y >= g_max_loc_Y) + g_loc_Y = 0; + if (cline) { + for (x = 0; x < g_max_loc_X; ++x) + draw_byte(' ', x, g_loc_Y); + } +#endif +} + +void btext_drawstring(const char *c) +{ + if (!boot_text_mapped) + return; + while (*c) + btext_drawchar(*c++); +} + +void btext_drawhex(unsigned long v) +{ + char *hex_table = "0123456789abcdef"; + + if (!boot_text_mapped) + return; +#ifdef CONFIG_PPC64 + btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]); +#endif + btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]); + btext_drawchar(' '); +} + +static void draw_byte(unsigned char c, long locX, long locY) +{ + unsigned char *base = calc_base(locX << 3, locY << 4); + unsigned char *font = &vga_font[((unsigned int)c) * 16]; + int rb = dispDeviceRowBytes; + + switch(dispDeviceDepth) { + case 24: + case 32: + draw_byte_32(font, (unsigned int *)base, rb); + break; + case 15: + case 16: + draw_byte_16(font, (unsigned int *)base, rb); + break; + case 8: + draw_byte_8(font, (unsigned int *)base, rb); + break; + } +} + +static unsigned int expand_bits_8[16] = { + 0x00000000, + 0x000000ff, + 0x0000ff00, + 0x0000ffff, + 0x00ff0000, + 0x00ff00ff, + 0x00ffff00, + 0x00ffffff, + 0xff000000, + 0xff0000ff, + 0xff00ff00, + 0xff00ffff, + 0xffff0000, + 0xffff00ff, + 0xffffff00, + 0xffffffff +}; + +static unsigned int expand_bits_16[4] = { + 0x00000000, + 0x0000ffff, + 0xffff0000, + 0xffffffff +}; + + +static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) +{ + int l, bits; + int fg = 0xFFFFFFFFUL; + int bg = 0x00000000UL; + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (-(bits >> 7) & fg) ^ bg; + base[1] = (-((bits >> 6) & 1) & fg) ^ bg; + base[2] = (-((bits >> 5) & 1) & fg) ^ bg; + base[3] = (-((bits >> 4) & 1) & fg) ^ bg; + base[4] = (-((bits >> 3) & 1) & fg) ^ bg; + base[5] = (-((bits >> 2) & 1) & fg) ^ bg; + base[6] = (-((bits >> 1) & 1) & fg) ^ bg; + base[7] = (-(bits & 1) & fg) ^ bg; + base = (unsigned int *) ((char *)base + rb); + } +} + +static void draw_byte_16(unsigned char *font, unsigned int *base, int rb) +{ + int l, bits; + int fg = 0xFFFFFFFFUL; + int bg = 0x00000000UL; + unsigned int *eb = (int *)expand_bits_16; + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (eb[bits >> 6] & fg) ^ bg; + base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; + base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; + base[3] = (eb[bits & 3] & fg) ^ bg; + base = (unsigned int *) ((char *)base + rb); + } +} + +static void draw_byte_8(unsigned char *font, unsigned int *base, int rb) +{ + int l, bits; + int fg = 0x0F0F0F0FUL; + int bg = 0x00000000UL; + unsigned int *eb = (int *)expand_bits_8; + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (eb[bits >> 4] & fg) ^ bg; + base[1] = (eb[bits & 0xf] & fg) ^ bg; + base = (unsigned int *) ((char *)base + rb); + } +} + +static unsigned char vga_font[cmapsz] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, +0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, +0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, +0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, +0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, +0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, +0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, +0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, +0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, +0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, +0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, +0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, +0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, +0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, +0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, +0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, +0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, +0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, +0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, +0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, +0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, +0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, +0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, +0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, +0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, +0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, +0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, +0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, +0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, +0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, +0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, +0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, +0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, +0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, +0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, +0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, +0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, +0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, +0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, +0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, +0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, +0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, +0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, +0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, +0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, +0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, +0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, +0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, +0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, +0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, +0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, +0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, +0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, +0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, +0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, +0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, +0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, +0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, +0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, +0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, +0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, +0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, +}; diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S index 2c3a1d34e3c7..d49bff1a7d51 100644 --- a/arch/powerpc/kernel/head.S +++ b/arch/powerpc/kernel/head.S @@ -134,11 +134,13 @@ __start: * because OF may have I/O devices mapped into that area * (particularly on CHRP). */ - mr r31,r3 /* save parameters */ + cmpwi 0,r5,0 + beq 1f + bl prom_init + trap + +1: mr r31,r3 /* save parameters */ mr r30,r4 - mr r29,r5 - mr r28,r6 - mr r27,r7 li r24,0 /* cpu # */ /* @@ -204,8 +206,7 @@ __after_mmu_off: * On CHRP, we are loaded at 0x10000 since OF on CHRP uses * the exception vectors at 0 (and therefore this copy * overwrites OF's exception vectors with our own). - * If the MMU is already turned on, we copy stuff to KERNELBASE, - * otherwise we copy it to 0. + * The MMU is off at this point. */ bl reloc_offset mr r26,r3 @@ -1187,9 +1188,6 @@ start_here: */ mr r3,r31 mr r4,r30 - mr r5,r29 - mr r6,r28 - mr r7,r27 bl machine_init bl MMU_init diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 33f742cf979b..91a562e3257b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -212,36 +212,6 @@ EXPORT_SYMBOL(_machine); EXPORT_SYMBOL(sys_ctrler); EXPORT_SYMBOL(pmac_newworld); #endif -#ifdef CONFIG_PPC_OF -EXPORT_SYMBOL(find_devices); -EXPORT_SYMBOL(find_type_devices); -EXPORT_SYMBOL(find_compatible_devices); -EXPORT_SYMBOL(find_path_device); -EXPORT_SYMBOL(device_is_compatible); -EXPORT_SYMBOL(machine_is_compatible); -EXPORT_SYMBOL(find_all_nodes); -EXPORT_SYMBOL(get_property); -EXPORT_SYMBOL(request_OF_resource); -EXPORT_SYMBOL(release_OF_resource); -EXPORT_SYMBOL(pci_busdev_to_OF_node); -EXPORT_SYMBOL(pci_device_to_OF_node); -EXPORT_SYMBOL(pci_device_from_OF_node); -EXPORT_SYMBOL(of_find_node_by_name); -EXPORT_SYMBOL(of_find_node_by_type); -EXPORT_SYMBOL(of_find_compatible_node); -EXPORT_SYMBOL(of_find_node_by_path); -EXPORT_SYMBOL(of_find_all_nodes); -EXPORT_SYMBOL(of_get_parent); -EXPORT_SYMBOL(of_get_next_child); -EXPORT_SYMBOL(of_node_get); -EXPORT_SYMBOL(of_node_put); -#endif /* CONFIG_PPC_OF */ -#if defined(CONFIG_BOOTX_TEXT) -EXPORT_SYMBOL(btext_update_display); -#endif -#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC) -EXPORT_SYMBOL(note_scsi_host); -#endif #ifdef CONFIG_VT EXPORT_SYMBOL(kd_mksound); #endif diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c new file mode 100644 index 000000000000..dc3d24ea3bff --- /dev/null +++ b/arch/powerpc/kernel/prom.c @@ -0,0 +1,2141 @@ +/* + * Procedures for creating, accessing and interpreting the device tree. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. + * {engebret|bergner}@us.ibm.com + * + * 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. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#define DBG(fmt...) printk(KERN_ERR fmt) +#else +#define DBG(fmt...) +#endif + +struct pci_reg_property { + struct pci_address addr; + u32 size_hi; + u32 size_lo; +}; + +struct isa_reg_property { + u32 space; + u32 address; + u32 size; +}; + + +typedef int interpret_func(struct device_node *, unsigned long *, + int, int, int); + +extern struct rtas_t rtas; +extern struct lmb lmb; +extern unsigned long klimit; + +static unsigned long memory_limit; + +static int __initdata dt_root_addr_cells; +static int __initdata dt_root_size_cells; + +#ifdef CONFIG_PPC64 +static int __initdata iommu_is_off; +int __initdata iommu_force_on; +extern unsigned long tce_alloc_start, tce_alloc_end; +#endif + +typedef u32 cell_t; + +#if 0 +static struct boot_param_header *initial_boot_params __initdata; +#else +struct boot_param_header *initial_boot_params; +#endif + +static struct device_node *allnodes = NULL; + +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); + +/* export that to outside world */ +struct device_node *of_chosen; + +struct device_node *dflt_interrupt_controller; +int num_interrupt_controllers; + +u32 rtas_data; +u32 rtas_entry; + +/* + * Wrapper for allocating memory for various data that needs to be + * attached to device nodes as they are processed at boot or when + * added to the device tree later (e.g. DLPAR). At boot there is + * already a region reserved so we just increment *mem_start by size; + * otherwise we call kmalloc. + */ +static void * prom_alloc(unsigned long size, unsigned long *mem_start) +{ + unsigned long tmp; + + if (!mem_start) + return kmalloc(size, GFP_KERNEL); + + tmp = *mem_start; + *mem_start += size; + return (void *)tmp; +} + +/* + * Find the device_node with a given phandle. + */ +static struct device_node * find_phandle(phandle ph) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->linux_phandle == ph) + return np; + return NULL; +} + +/* + * Find the interrupt parent of a node. + */ +static struct device_node * __devinit intr_parent(struct device_node *p) +{ + phandle *parp; + + parp = (phandle *) get_property(p, "interrupt-parent", NULL); + if (parp == NULL) + return p->parent; + p = find_phandle(*parp); + if (p != NULL) + return p; + /* + * On a powermac booted with BootX, we don't get to know the + * phandles for any nodes, so find_phandle will return NULL. + * Fortunately these machines only have one interrupt controller + * so there isn't in fact any ambiguity. -- paulus + */ + if (num_interrupt_controllers == 1) + p = dflt_interrupt_controller; + return p; +} + +/* + * Find out the size of each entry of the interrupts property + * for a node. + */ +int __devinit prom_n_intr_cells(struct device_node *np) +{ + struct device_node *p; + unsigned int *icp; + + for (p = np; (p = intr_parent(p)) != NULL; ) { + icp = (unsigned int *) + get_property(p, "#interrupt-cells", NULL); + if (icp != NULL) + return *icp; + if (get_property(p, "interrupt-controller", NULL) != NULL + || get_property(p, "interrupt-map", NULL) != NULL) { + printk("oops, node %s doesn't have #interrupt-cells\n", + p->full_name); + return 1; + } + } +#ifdef DEBUG_IRQ + printk("prom_n_intr_cells failed for %s\n", np->full_name); +#endif + return 1; +} + +/* + * Map an interrupt from a device up to the platform interrupt + * descriptor. + */ +static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler, + struct device_node *np, unsigned int *ints, + int nintrc) +{ + struct device_node *p, *ipar; + unsigned int *imap, *imask, *ip; + int i, imaplen, match; + int newintrc = 0, newaddrc = 0; + unsigned int *reg; + int naddrc; + + reg = (unsigned int *) get_property(np, "reg", NULL); + naddrc = prom_n_addr_cells(np); + p = intr_parent(np); + while (p != NULL) { + if (get_property(p, "interrupt-controller", NULL) != NULL) + /* this node is an interrupt controller, stop here */ + break; + imap = (unsigned int *) + get_property(p, "interrupt-map", &imaplen); + if (imap == NULL) { + p = intr_parent(p); + continue; + } + imask = (unsigned int *) + get_property(p, "interrupt-map-mask", NULL); + if (imask == NULL) { + printk("oops, %s has interrupt-map but no mask\n", + p->full_name); + return 0; + } + imaplen /= sizeof(unsigned int); + match = 0; + ipar = NULL; + while (imaplen > 0 && !match) { + /* check the child-interrupt field */ + match = 1; + for (i = 0; i < naddrc && match; ++i) + match = ((reg[i] ^ imap[i]) & imask[i]) == 0; + for (; i < naddrc + nintrc && match; ++i) + match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; + imap += naddrc + nintrc; + imaplen -= naddrc + nintrc; + /* grab the interrupt parent */ + ipar = find_phandle((phandle) *imap++); + --imaplen; + if (ipar == NULL && num_interrupt_controllers == 1) + /* cope with BootX not giving us phandles */ + ipar = dflt_interrupt_controller; + if (ipar == NULL) { + printk("oops, no int parent %x in map of %s\n", + imap[-1], p->full_name); + return 0; + } + /* find the parent's # addr and intr cells */ + ip = (unsigned int *) + get_property(ipar, "#interrupt-cells", NULL); + if (ip == NULL) { + printk("oops, no #interrupt-cells on %s\n", + ipar->full_name); + return 0; + } + newintrc = *ip; + ip = (unsigned int *) + get_property(ipar, "#address-cells", NULL); + newaddrc = (ip == NULL)? 0: *ip; + imap += newaddrc + newintrc; + imaplen -= newaddrc + newintrc; + } + if (imaplen < 0) { + printk("oops, error decoding int-map on %s, len=%d\n", + p->full_name, imaplen); + return 0; + } + if (!match) { +#ifdef DEBUG_IRQ + printk("oops, no match in %s int-map for %s\n", + p->full_name, np->full_name); +#endif + return 0; + } + p = ipar; + naddrc = newaddrc; + nintrc = newintrc; + ints = imap - nintrc; + reg = ints - naddrc; + } + if (p == NULL) { +#ifdef DEBUG_IRQ + printk("hmmm, int tree for %s doesn't have ctrler\n", + np->full_name); +#endif + return 0; + } + *irq = ints; + *ictrler = p; + return nintrc; +} + +static int __devinit finish_node_interrupts(struct device_node *np, + unsigned long *mem_start, + int measure_only) +{ + unsigned int *ints; + int intlen, intrcells, intrcount; + int i, j, n; + unsigned int *irq, virq; + struct device_node *ic; + + ints = (unsigned int *) get_property(np, "interrupts", &intlen); + if (ints == NULL) + return 0; + intrcells = prom_n_intr_cells(np); + intlen /= intrcells * sizeof(unsigned int); + + np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); + if (!np->intrs) + return -ENOMEM; + + if (measure_only) + return 0; + + intrcount = 0; + for (i = 0; i < intlen; ++i, ints += intrcells) { + n = map_interrupt(&irq, &ic, np, ints, intrcells); + if (n <= 0) + continue; + + /* don't map IRQ numbers under a cascaded 8259 controller */ + if (ic && device_is_compatible(ic, "chrp,iic")) { + np->intrs[intrcount].line = irq[0]; + } else { +#ifdef CONFIG_PPC64 + virq = virt_irq_create_mapping(irq[0]); + if (virq == NO_IRQ) { + printk(KERN_CRIT "Could not allocate interrupt" + " number for %s\n", np->full_name); + continue; + } + virq = irq_offset_up(virq); +#else + virq = irq[0]; +#endif + np->intrs[intrcount].line = virq; + } + +#ifdef CONFIG_PPC64 + /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ + if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { + char *name = get_property(ic->parent, "name", NULL); + if (name && !strcmp(name, "u3")) + np->intrs[intrcount].line += 128; + else if (!(name && !strcmp(name, "mac-io"))) + /* ignore other cascaded controllers, such as + the k2-sata-root */ + break; + } +#endif + np->intrs[intrcount].sense = 1; + if (n > 1) + np->intrs[intrcount].sense = irq[1]; + if (n > 2) { + printk("hmmm, got %d intr cells for %s:", n, + np->full_name); + for (j = 0; j < n; ++j) + printk(" %d", irq[j]); + printk("\n"); + } + ++intrcount; + } + np->n_intrs = intrcount; + + return 0; +} + +static int __devinit interpret_pci_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct address_range *adr; + struct pci_reg_property *pci_addrs; + int i, l, n_addrs; + + pci_addrs = (struct pci_reg_property *) + get_property(np, "assigned-addresses", &l); + if (!pci_addrs) + return 0; + + n_addrs = l / sizeof(*pci_addrs); + + adr = prom_alloc(n_addrs * sizeof(*adr), mem_start); + if (!adr) + return -ENOMEM; + + if (measure_only) + return 0; + + np->addrs = adr; + np->n_addrs = n_addrs; + + for (i = 0; i < n_addrs; i++) { + adr[i].space = pci_addrs[i].addr.a_hi; + adr[i].address = pci_addrs[i].addr.a_lo | + ((u64)pci_addrs[i].addr.a_mid << 32); + adr[i].size = pci_addrs[i].size_lo; + } + + return 0; +} + +static int __init interpret_dbdma_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct reg_property32 *rp; + struct address_range *adr; + unsigned long base_address; + int i, l; + struct device_node *db; + + base_address = 0; + if (!measure_only) { + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + } + + rp = (struct reg_property32 *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property32)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct reg_property32)) >= 0) { + if (!measure_only) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_macio_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct reg_property32 *rp; + struct address_range *adr; + unsigned long base_address; + int i, l; + struct device_node *db; + + base_address = 0; + if (!measure_only) { + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + } + + rp = (struct reg_property32 *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property32)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct reg_property32)) >= 0) { + if (!measure_only) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_isa_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct isa_reg_property *rp; + struct address_range *adr; + int i, l; + + rp = (struct isa_reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct isa_reg_property)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct isa_reg_property)) >= 0) { + if (!measure_only) { + adr[i].space = rp[i].space; + adr[i].address = rp[i].address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_root_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct address_range *adr; + int i, l; + unsigned int *rp; + int rpsize = (naddrc + nsizec) * sizeof(unsigned int); + + rp = (unsigned int *) get_property(np, "reg", &l); + if (rp != 0 && l >= rpsize) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= rpsize) >= 0) { + if (!measure_only) { + adr[i].space = 0; + adr[i].address = rp[naddrc - 1]; + adr[i].size = rp[naddrc + nsizec - 1]; + } + ++i; + rp += naddrc + nsizec; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __devinit finish_node(struct device_node *np, + unsigned long *mem_start, + interpret_func *ifunc, + int naddrc, int nsizec, + int measure_only) +{ + struct device_node *child; + int *ip, rc = 0; + + /* get the device addresses and interrupts */ + if (ifunc != NULL) + rc = ifunc(np, mem_start, naddrc, nsizec, measure_only); + if (rc) + goto out; + + rc = finish_node_interrupts(np, mem_start, measure_only); + if (rc) + goto out; + + /* Look for #address-cells and #size-cells properties. */ + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + naddrc = *ip; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + nsizec = *ip; + + if (!strcmp(np->name, "device-tree") || np->parent == NULL) + ifunc = interpret_root_props; + else if (np->type == 0) + ifunc = NULL; + else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) + ifunc = interpret_pci_props; + else if (!strcmp(np->type, "dbdma")) + ifunc = interpret_dbdma_props; + else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props) + ifunc = interpret_macio_props; + else if (!strcmp(np->type, "isa")) + ifunc = interpret_isa_props; + else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) + ifunc = interpret_root_props; + else if (!((ifunc == interpret_dbdma_props + || ifunc == interpret_macio_props) + && (!strcmp(np->type, "escc") + || !strcmp(np->type, "media-bay")))) + ifunc = NULL; + + for (child = np->child; child != NULL; child = child->sibling) { + rc = finish_node(child, mem_start, ifunc, + naddrc, nsizec, measure_only); + if (rc) + goto out; + } +out: + return rc; +} + +static void __init scan_interrupt_controllers(void) +{ + struct device_node *np; + int n = 0; + char *name, *ic; + int iclen; + + for (np = allnodes; np != NULL; np = np->allnext) { + ic = get_property(np, "interrupt-controller", &iclen); + name = get_property(np, "name", NULL); + /* checking iclen makes sure we don't get a false + match on /chosen.interrupt_controller */ + if ((name != NULL + && strcmp(name, "interrupt-controller") == 0) + || (ic != NULL && iclen == 0 + && strcmp(name, "AppleKiwi"))) { + if (n == 0) + dflt_interrupt_controller = np; + ++n; + } + } + num_interrupt_controllers = n; +} + +/** + * finish_device_tree is called once things are running normally + * (i.e. with text and data mapped to the address they were linked at). + * It traverses the device tree and fills in some of the additional, + * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt + * mapping is also initialized at this point. + */ +void __init finish_device_tree(void) +{ + unsigned long start, end, size = 0; + + DBG(" -> finish_device_tree\n"); + +#ifdef CONFIG_PPC64 + /* Initialize virtual IRQ map */ + virt_irq_init(); +#endif + scan_interrupt_controllers(); + + /* + * Finish device-tree (pre-parsing some properties etc...) + * We do this in 2 passes. One with "measure_only" set, which + * will only measure the amount of memory needed, then we can + * allocate that memory, and call finish_node again. However, + * we must be careful as most routines will fail nowadays when + * prom_alloc() returns 0, so we must make sure our first pass + * doesn't start at 0. We pre-initialize size to 16 for that + * reason and then remove those additional 16 bytes + */ + size = 16; + finish_node(allnodes, &size, NULL, 0, 0, 1); + size -= 16; + end = start = (unsigned long) __va(lmb_alloc(size, 128)); + finish_node(allnodes, &end, NULL, 0, 0, 0); + BUG_ON(end != start + size); + + DBG(" <- finish_device_tree\n"); +} + +static inline char *find_flat_dt_string(u32 offset) +{ + return ((char *)initial_boot_params) + + initial_boot_params->off_dt_strings + offset; +} + +/** + * This function is used to scan the flattened device-tree, it is + * used to extract the memory informations at boot before we can + * unflatten the tree + */ +static int __init scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + int rc = 0; + int depth = -1; + + do { + u32 tag = *((u32 *)p); + char *pathp; + + p += 4; + if (tag == OF_DT_END_NODE) { + depth --; + continue; + } + if (tag == OF_DT_NOP) + continue; + if (tag == OF_DT_END) + break; + if (tag == OF_DT_PROP) { + u32 sz = *((u32 *)p); + p += 8; + if (initial_boot_params->version < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + p += sz; + p = _ALIGN(p, 4); + continue; + } + if (tag != OF_DT_BEGIN_NODE) { + printk(KERN_WARNING "Invalid tag %x scanning flattened" + " device tree !\n", tag); + return -EINVAL; + } + depth++; + pathp = (char *)p; + p = _ALIGN(p + strlen(pathp) + 1, 4); + if ((*pathp) == '/') { + char *lp, *np; + for (lp = NULL, np = pathp; *np; np++) + if ((*np) == '/') + lp = np+1; + if (lp != NULL) + pathp = lp; + } + rc = it(p, pathp, depth, data); + if (rc != 0) + break; + } while(1); + + return rc; +} + +/** + * This function can be used within scan_flattened_dt callback to get + * access to properties + */ +static void* __init get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size) +{ + unsigned long p = node; + + do { + u32 tag = *((u32 *)p); + u32 sz, noff; + const char *nstr; + + p += 4; + if (tag == OF_DT_NOP) + continue; + if (tag != OF_DT_PROP) + return NULL; + + sz = *((u32 *)p); + noff = *((u32 *)(p + 4)); + p += 8; + if (initial_boot_params->version < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + + nstr = find_flat_dt_string(noff); + if (nstr == NULL) { + printk(KERN_WARNING "Can't find property index" + " name !\n"); + return NULL; + } + if (strcmp(name, nstr) == 0) { + if (size) + *size = sz; + return (void *)p; + } + p += sz; + p = _ALIGN(p, 4); + } while(1); +} + +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, + unsigned long align) +{ + void *res; + + *mem = _ALIGN(*mem, align); + res = (void *)*mem; + *mem += size; + + return res; +} + +static unsigned long __init unflatten_dt_node(unsigned long mem, + unsigned long *p, + struct device_node *dad, + struct device_node ***allnextpp, + unsigned long fpsize) +{ + struct device_node *np; + struct property *pp, **prev_pp = NULL; + char *pathp; + u32 tag; + unsigned int l, allocl; + int has_name = 0; + int new_format = 0; + + tag = *((u32 *)(*p)); + if (tag != OF_DT_BEGIN_NODE) { + printk("Weird tag at start of node: %x\n", tag); + return mem; + } + *p += 4; + pathp = (char *)*p; + l = allocl = strlen(pathp) + 1; + *p = _ALIGN(*p + l, 4); + + /* version 0x10 has a more compact unit name here instead of the full + * path. we accumulate the full path size using "fpsize", we'll rebuild + * it later. We detect this because the first character of the name is + * not '/'. + */ + if ((*pathp) != '/') { + new_format = 1; + if (fpsize == 0) { + /* root node: special case. fpsize accounts for path + * plus terminating zero. root node only has '/', so + * fpsize should be 2, but we want to avoid the first + * level nodes to have two '/' so we use fpsize 1 here + */ + fpsize = 1; + allocl = 2; + } else { + /* account for '/' and path size minus terminal 0 + * already in 'l' + */ + fpsize += l; + allocl = fpsize; + } + } + + + np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, + __alignof__(struct device_node)); + if (allnextpp) { + memset(np, 0, sizeof(*np)); + np->full_name = ((char*)np) + sizeof(struct device_node); + if (new_format) { + char *p = np->full_name; + /* rebuild full path for new format */ + if (dad && dad->parent) { + strcpy(p, dad->full_name); +#ifdef DEBUG + if ((strlen(p) + l + 1) != allocl) { + DBG("%s: p: %d, l: %d, a: %d\n", + pathp, strlen(p), l, allocl); + } +#endif + p += strlen(p); + } + *(p++) = '/'; + memcpy(p, pathp, l); + } else + memcpy(np->full_name, pathp, l); + prev_pp = &np->properties; + **allnextpp = np; + *allnextpp = &np->allnext; + if (dad != NULL) { + np->parent = dad; + /* we temporarily use the next field as `last_child'*/ + if (dad->next == 0) + dad->child = np; + else + dad->next->sibling = np; + dad->next = np; + } + kref_init(&np->kref); + } + while(1) { + u32 sz, noff; + char *pname; + + tag = *((u32 *)(*p)); + if (tag == OF_DT_NOP) { + *p += 4; + continue; + } + if (tag != OF_DT_PROP) + break; + *p += 4; + sz = *((u32 *)(*p)); + noff = *((u32 *)((*p) + 4)); + *p += 8; + if (initial_boot_params->version < 0x10) + *p = _ALIGN(*p, sz >= 8 ? 8 : 4); + + pname = find_flat_dt_string(noff); + if (pname == NULL) { + printk("Can't find property name in list !\n"); + break; + } + if (strcmp(pname, "name") == 0) + has_name = 1; + l = strlen(pname) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property), + __alignof__(struct property)); + if (allnextpp) { + if (strcmp(pname, "linux,phandle") == 0) { + np->node = *((u32 *)*p); + if (np->linux_phandle == 0) + np->linux_phandle = np->node; + } + if (strcmp(pname, "ibm,phandle") == 0) + np->linux_phandle = *((u32 *)*p); + pp->name = pname; + pp->length = sz; + pp->value = (void *)*p; + *prev_pp = pp; + prev_pp = &pp->next; + } + *p = _ALIGN((*p) + sz, 4); + } + /* with version 0x10 we may not have the name property, recreate + * it here from the unit name if absent + */ + if (!has_name) { + char *p = pathp, *ps = pathp, *pa = NULL; + int sz; + + while (*p) { + if ((*p) == '@') + pa = p; + if ((*p) == '/') + ps = p + 1; + p++; + } + if (pa < ps) + pa = p; + sz = (pa - ps) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, + __alignof__(struct property)); + if (allnextpp) { + pp->name = "name"; + pp->length = sz; + pp->value = (unsigned char *)(pp + 1); + *prev_pp = pp; + prev_pp = &pp->next; + memcpy(pp->value, ps, sz - 1); + ((char *)pp->value)[sz - 1] = 0; + DBG("fixed up name for %s -> %s\n", pathp, pp->value); + } + } + if (allnextpp) { + *prev_pp = NULL; + np->name = get_property(np, "name", NULL); + np->type = get_property(np, "device_type", NULL); + + if (!np->name) + np->name = ""; + if (!np->type) + np->type = ""; + } + while (tag == OF_DT_BEGIN_NODE) { + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); + tag = *((u32 *)(*p)); + } + if (tag != OF_DT_END_NODE) { + printk("Weird tag at end of node: %x\n", tag); + return mem; + } + *p += 4; + return mem; +} + + +/** + * unflattens the device-tree passed by the firmware, creating the + * tree of struct device_node. It also fills the "name" and "type" + * pointers of the nodes so the normal device-tree walking functions + * can be used (this used to be done by finish_device_tree) + */ +void __init unflatten_device_tree(void) +{ + unsigned long start, mem, size; + struct device_node **allnextp = &allnodes; + char *p = NULL; + int l = 0; + + DBG(" -> unflatten_device_tree()\n"); + + /* First pass, scan for size */ + start = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + size = unflatten_dt_node(0, &start, NULL, NULL, 0); + size = (size | 3) + 1; + + DBG(" size is %lx, allocating...\n", size); + + /* Allocate memory for the expanded device tree */ + mem = lmb_alloc(size + 4, __alignof__(struct device_node)); + if (!mem) { + DBG("Couldn't allocate memory with lmb_alloc()!\n"); + panic("Couldn't allocate memory with lmb_alloc()!\n"); + } + mem = (unsigned long) __va(mem); + + ((u32 *)mem)[size / 4] = 0xdeadbeef; + + DBG(" unflattening %lx...\n", mem); + + /* Second pass, do actual unflattening */ + start = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + unflatten_dt_node(mem, &start, NULL, &allnextp, 0); + if (*((u32 *)start) != OF_DT_END) + printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start)); + if (((u32 *)mem)[size / 4] != 0xdeadbeef) + printk(KERN_WARNING "End of tree marker overwritten: %08x\n", + ((u32 *)mem)[size / 4] ); + *allnextp = NULL; + + /* Get pointer to OF "/chosen" node for use everywhere */ + of_chosen = of_find_node_by_path("/chosen"); + + /* Retreive command line */ + if (of_chosen != NULL) { + p = (char *)get_property(of_chosen, "bootargs", &l); + if (p != NULL && l > 0) + strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE)); + } +#ifdef CONFIG_CMDLINE + if (l == 0 || (l == 1 && (*p) == 0)) + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +#endif /* CONFIG_CMDLINE */ + + DBG("Command line is: %s\n", cmd_line); + + DBG(" <- unflatten_device_tree()\n"); +} + + +static int __init early_init_dt_scan_cpus(unsigned long node, + const char *uname, int depth, void *data) +{ + char *type = get_flat_dt_prop(node, "device_type", NULL); + u32 *prop; + unsigned long size = 0; + + /* We are scanning "cpu" nodes only */ + if (type == NULL || strcmp(type, "cpu") != 0) + return 0; + +#ifdef CONFIG_PPC_PSERIES + /* On LPAR, look for the first ibm,pft-size property for the hash table size + */ + if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) { + u32 *pft_size; + pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL); + if (pft_size != NULL) { + /* pft_size[0] is the NUMA CEC cookie */ + ppc64_pft_size = pft_size[1]; + } + } +#endif + +#ifdef CONFIG_PPC64 + if (initial_boot_params && initial_boot_params->version >= 2) { + /* version 2 of the kexec param format adds the phys cpuid + * of booted proc. + */ + boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; + boot_cpuid = 0; + } else { + /* Check if it's the boot-cpu, set it's hw index in paca now */ + if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { + u32 *prop = get_flat_dt_prop(node, "reg", NULL); + set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); + boot_cpuid_phys = get_hard_smp_processor_id(0); + } + } +#endif + +#ifdef CONFIG_ALTIVEC + /* Check if we have a VMX and eventually update CPU features */ + prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size); + if (prop && (*prop) > 0) { + cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; + } + + /* Same goes for Apple's "altivec" property */ + prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL); + if (prop) { + cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; + } +#endif /* CONFIG_ALTIVEC */ + +#ifdef CONFIG_PPC_PSERIES + /* + * Check for an SMT capable CPU and set the CPU feature. We do + * this by looking at the size of the ibm,ppc-interrupt-server#s + * property + */ + prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", + &size); + cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; + if (prop && ((size / sizeof(u32)) > 1)) + cur_cpu_spec->cpu_features |= CPU_FTR_SMT; +#endif + + return 0; +} + +static int __init early_init_dt_scan_chosen(unsigned long node, + const char *uname, int depth, void *data) +{ + u32 *prop; + unsigned long *lprop; + + DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + + if (depth != 1 || strcmp(uname, "chosen") != 0) + return 0; + + /* get platform type */ + prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL); + if (prop == NULL) + return 0; +#ifdef CONFIG_PPC64 + systemcfg->platform = *prop; +#else + _machine = *prop; +#endif + +#ifdef CONFIG_PPC64 + /* check if iommu is forced on or off */ + if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) + iommu_is_off = 1; + if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL) + iommu_force_on = 1; +#endif + + lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL); + if (lprop) + memory_limit = *lprop; + +#ifdef CONFIG_PPC64 + lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL); + if (lprop) + tce_alloc_start = *lprop; + lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL); + if (lprop) + tce_alloc_end = *lprop; +#endif + +#ifdef CONFIG_PPC_RTAS + /* To help early debugging via the front panel, we retreive a minimal + * set of RTAS infos now if available + */ + { + u64 *basep, *entryp; + + basep = get_flat_dt_prop(node, "linux,rtas-base", NULL); + entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL); + prop = get_flat_dt_prop(node, "linux,rtas-size", NULL); + if (basep && entryp && prop) { + rtas.base = *basep; + rtas.entry = *entryp; + rtas.size = *prop; + } + } +#endif /* CONFIG_PPC_RTAS */ + + /* break now */ + return 1; +} + +static int __init early_init_dt_scan_root(unsigned long node, + const char *uname, int depth, void *data) +{ + u32 *prop; + + if (depth != 0) + return 0; + + prop = get_flat_dt_prop(node, "#size-cells", NULL); + dt_root_size_cells = (prop == NULL) ? 1 : *prop; + DBG("dt_root_size_cells = %x\n", dt_root_size_cells); + + prop = get_flat_dt_prop(node, "#address-cells", NULL); + dt_root_addr_cells = (prop == NULL) ? 2 : *prop; + DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells); + + /* break now */ + return 1; +} + +static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) +{ + cell_t *p = *cellp; + unsigned long r; + + /* Ignore more than 2 cells */ + while (s > sizeof(unsigned long) / 4) { + p++; + s--; + } + r = *p++; +#ifdef CONFIG_PPC64 + if (s > 1) { + r <<= 32; + r |= *(p++); + s--; + } +#endif + + *cellp = p; + return r; +} + + +static int __init early_init_dt_scan_memory(unsigned long node, + const char *uname, int depth, void *data) +{ + char *type = get_flat_dt_prop(node, "device_type", NULL); + cell_t *reg, *endp; + unsigned long l; + + /* We are scanning "memory" nodes only */ + if (type == NULL || strcmp(type, "memory") != 0) + return 0; + + reg = (cell_t *)get_flat_dt_prop(node, "reg", &l); + if (reg == NULL) + return 0; + + endp = reg + (l / sizeof(cell_t)); + + DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n", + uname, l, reg[0], reg[1], reg[2], reg[3]); + + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { + unsigned long base, size; + + base = dt_mem_next_cell(dt_root_addr_cells, ®); + size = dt_mem_next_cell(dt_root_size_cells, ®); + + if (size == 0) + continue; + DBG(" - %lx , %lx\n", base, size); +#ifdef CONFIG_PPC64 + if (iommu_is_off) { + if (base >= 0x80000000ul) + continue; + if ((base + size) > 0x80000000ul) + size = 0x80000000ul - base; + } +#endif + lmb_add(base, size); + } + return 0; +} + +static void __init early_reserve_mem(void) +{ + unsigned long base, size; + unsigned long *reserve_map; + + reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) + + initial_boot_params->off_mem_rsvmap); + while (1) { + base = *(reserve_map++); + size = *(reserve_map++); + if (size == 0) + break; + DBG("reserving: %lx -> %lx\n", base, size); + lmb_reserve(base, size); + } + +#if 0 + DBG("memory reserved, lmbs :\n"); + lmb_dump_all(); +#endif +} + +void __init early_init_devtree(void *params) +{ + DBG(" -> early_init_devtree()\n"); + + /* Setup flat device-tree pointer */ + initial_boot_params = params; + + /* Retrieve various informations from the /chosen node of the + * device-tree, including the platform type, initrd location and + * size, TCE reserve, and more ... + */ + scan_flat_dt(early_init_dt_scan_chosen, NULL); + + /* Scan memory nodes and rebuild LMBs */ + lmb_init(); + scan_flat_dt(early_init_dt_scan_root, NULL); + scan_flat_dt(early_init_dt_scan_memory, NULL); + lmb_enforce_memory_limit(memory_limit); + lmb_analyze(); +#ifdef CONFIG_PPC64 + systemcfg->physicalMemorySize = lmb_phys_mem_size(); +#endif + lmb_reserve(0, __pa(klimit)); + + DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); + + /* Reserve LMB regions used by kernel, initrd, dt, etc... */ + early_reserve_mem(); + + DBG("Scanning CPUs ...\n"); + + /* Retreive hash table size from flattened tree plus other + * CPU related informations (altivec support, boot CPU ID, ...) + */ + scan_flat_dt(early_init_dt_scan_cpus, NULL); + +#ifdef CONFIG_PPC_PSERIES + /* If hash size wasn't obtained above, we calculate it now based on + * the total RAM size + */ + if (ppc64_pft_size == 0) { + unsigned long rnd_mem_size, pteg_count; + + /* round mem_size up to next power of 2 */ + rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); + if (rnd_mem_size < systemcfg->physicalMemorySize) + rnd_mem_size <<= 1; + + /* # pages / 2 */ + pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); + + ppc64_pft_size = __ilog2(pteg_count << 7); + } + + DBG("Hash pftSize: %x\n", (int)ppc64_pft_size); +#endif + DBG(" <- early_init_devtree()\n"); +} + +#undef printk + +int +prom_n_addr_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 1 */ + return 1; +} + +int +prom_n_size_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} + +/** + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) + senses[i-off] = np->intrs[j].sense ? + IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE : + IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE; + } + } +} + +/** + * Construct and return a list of the device_nodes with a given name. + */ +struct device_node *find_devices(const char *name) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->name != 0 && strcasecmp(np->name, name) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} +EXPORT_SYMBOL(find_devices); + +/** + * Construct and return a list of the device_nodes with a given type. + */ +struct device_node *find_type_devices(const char *type) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->type != 0 && strcasecmp(np->type, type) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} +EXPORT_SYMBOL(find_type_devices); + +/** + * Returns all nodes linked together + */ +struct device_node *find_all_nodes(void) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + *prevp = np; + prevp = &np->next; + } + *prevp = NULL; + return head; +} +EXPORT_SYMBOL(find_all_nodes); + +/** Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ +int device_is_compatible(struct device_node *device, const char *compat) +{ + const char* cp; + int cplen, l; + + cp = (char *) get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} +EXPORT_SYMBOL(device_is_compatible); + + +/** + * Indicates whether the root node has a given value in its + * compatible property. + */ +int machine_is_compatible(const char *compat) +{ + struct device_node *root; + int rc = 0; + + root = of_find_node_by_path("/"); + if (root) { + rc = device_is_compatible(root, compat); + of_node_put(root); + } + return rc; +} +EXPORT_SYMBOL(machine_is_compatible); + +/** + * Construct and return a list of the device_nodes with a given type + * and compatible property. + */ +struct device_node *find_compatible_devices(const char *type, + const char *compat) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compat)) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} +EXPORT_SYMBOL(find_compatible_devices); + +/** + * Find the device_node with a given full_name. + */ +struct device_node *find_path_device(const char *path) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + return np; + return NULL; +} +EXPORT_SYMBOL(find_path_device); + +/******* + * + * New implementation of the OF "find" APIs, return a refcounted + * object, call of_node_put() when done. The device tree and list + * are protected by a rw_lock. + * + * Note that property management will need some locking as well, + * this isn't dealt with yet. + * + *******/ + +/** + * of_find_node_by_name - Find a node by its "name" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (np->name != 0 && strcasecmp(np->name, name) == 0 + && of_node_get(np)) + break; + if (from) + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_name); + +/** + * of_find_node_by_type - Find a node by its "device_type" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The type string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcasecmp(np->type, type) == 0 + && of_node_get(np)) + break; + if (from) + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_type); + +/** + * of_find_compatible_node - Find a node based on type and one of the + * tokens in its "compatible" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compatible) && of_node_get(np)) + break; + } + if (from) + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_compatible_node); + +/** + * of_find_node_by_path - Find a node matching a full OF path + * @path: The full path to match + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + read_lock(&devtree_lock); + for (; np != 0; np = np->allnext) { + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0 + && of_node_get(np)) + break; + } + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_path); + +/** + * of_find_node_by_phandle - Find a node given a phandle + * @handle: phandle of the node to find + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_phandle(phandle handle) +{ + struct device_node *np; + + read_lock(&devtree_lock); + for (np = allnodes; np != 0; np = np->allnext) + if (np->linux_phandle == handle) + break; + if (np) + of_node_get(np); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_phandle); + +/** + * of_find_all_nodes - Get next node in global list + * @prev: Previous node or NULL to start iteration + * of_node_put() will be called on it + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_all_nodes(struct device_node *prev) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = prev ? prev->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (of_node_get(np)) + break; + if (prev) + of_node_put(prev); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_all_nodes); + +/** + * of_get_parent - Get a node's parent if any + * @node: Node to get parent + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_parent(const struct device_node *node) +{ + struct device_node *np; + + if (!node) + return NULL; + + read_lock(&devtree_lock); + np = of_node_get(node->parent); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_get_parent); + +/** + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next; + + read_lock(&devtree_lock); + next = prev ? prev->sibling : node->child; + for (; next != 0; next = next->sibling) + if (of_node_get(next)) + break; + if (prev) + of_node_put(prev); + read_unlock(&devtree_lock); + return next; +} +EXPORT_SYMBOL(of_get_next_child); + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns node. + */ +struct device_node *of_node_get(struct device_node *node) +{ + if (node) + kref_get(&node->kref); + return node; +} +EXPORT_SYMBOL(of_node_get); + +static inline struct device_node * kref_to_device_node(struct kref *kref) +{ + return container_of(kref, struct device_node, kref); +} + +/** + * of_node_release - release a dynamically allocated node + * @kref: kref element of the node to be released + * + * In of_node_put() this function is passed to kref_put() + * as the destructor. + */ +static void of_node_release(struct kref *kref) +{ + struct device_node *node = kref_to_device_node(kref); + struct property *prop = node->properties; + + if (!OF_IS_DYNAMIC(node)) + return; + while (prop) { + struct property *next = prop->next; + kfree(prop->name); + kfree(prop->value); + kfree(prop); + prop = next; + } + kfree(node->intrs); + kfree(node->addrs); + kfree(node->full_name); + kfree(node->data); + kfree(node); +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + */ +void of_node_put(struct device_node *node) +{ + if (node) + kref_put(&node->kref, of_node_release); +} +EXPORT_SYMBOL(of_node_put); + +/* + * Plug a device node into the tree and global list. + */ +void of_attach_node(struct device_node *np) +{ + write_lock(&devtree_lock); + np->sibling = np->parent->child; + np->allnext = allnodes; + np->parent->child = np; + allnodes = np; + write_unlock(&devtree_lock); +} + +/* + * "Unplug" a node from the device tree. The caller must hold + * a reference to the node. The memory associated with the node + * is not freed until its refcount goes to zero. + */ +void of_detach_node(const struct device_node *np) +{ + struct device_node *parent; + + write_lock(&devtree_lock); + + parent = np->parent; + + if (allnodes == np) + allnodes = np->allnext; + else { + struct device_node *prev; + for (prev = allnodes; + prev->allnext != np; + prev = prev->allnext) + ; + prev->allnext = np->allnext; + } + + if (parent->child == np) + parent->child = np->sibling; + else { + struct device_node *prevsib; + for (prevsib = np->parent->child; + prevsib->sibling != np; + prevsib = prevsib->sibling) + ; + prevsib->sibling = np->sibling; + } + + write_unlock(&devtree_lock); +} + +#ifdef CONFIG_PPC_PSERIES +/* + * Fix up the uninitialized fields in a new device node: + * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields + * + * A lot of boot-time code is duplicated here, because functions such + * as finish_node_interrupts, interpret_pci_props, etc. cannot use the + * slab allocator. + * + * This should probably be split up into smaller chunks. + */ + +static int of_finish_dynamic_node(struct device_node *node, + unsigned long *unused1, int unused2, + int unused3, int unused4) +{ + struct device_node *parent = of_get_parent(node); + int err = 0; + phandle *ibm_phandle; + + node->name = get_property(node, "name", NULL); + node->type = get_property(node, "device_type", NULL); + + if (!parent) { + err = -ENODEV; + goto out; + } + + /* We don't support that function on PowerMac, at least + * not yet + */ + if (systemcfg->platform == PLATFORM_POWERMAC) + return -ENODEV; + + /* fix up new node's linux_phandle field */ + if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) + node->linux_phandle = *ibm_phandle; + +out: + of_node_put(parent); + return err; +} + +static int prom_reconfig_notifier(struct notifier_block *nb, + unsigned long action, void *node) +{ + int err; + + switch (action) { + case PSERIES_RECONFIG_ADD: + err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); + if (err < 0) { + printk(KERN_ERR "finish_node returned %d\n", err); + err = NOTIFY_BAD; + } + break; + default: + err = NOTIFY_DONE; + break; + } + return err; +} + +static struct notifier_block prom_reconfig_nb = { + .notifier_call = prom_reconfig_notifier, + .priority = 10, /* This one needs to run first */ +}; + +static int __init prom_reconfig_setup(void) +{ + return pSeries_reconfig_notifier_register(&prom_reconfig_nb); +} +__initcall(prom_reconfig_setup); +#endif + +/* + * Find a property with a given name for a given node + * and return the value. + */ +unsigned char *get_property(struct device_node *np, const char *name, + int *lenp) +{ + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) + if (strcmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + return pp->value; + } + return NULL; +} +EXPORT_SYMBOL(get_property); + +/* + * Add a property to a node + */ +void prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; +} + +/* I quickly hacked that one, check against spec ! */ +static inline unsigned long +bus_space_to_resource_flags(unsigned int bus_space) +{ + u8 space = (bus_space >> 24) & 0xf; + if (space == 0) + space = 0x02; + if (space == 0x02) + return IORESOURCE_MEM; + else if (space == 0x01) + return IORESOURCE_IO; + else { + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", + bus_space); + return 0; + } +} + +static struct resource *find_parent_pci_resource(struct pci_dev* pdev, + struct address_range *range) +{ + unsigned long mask; + int i; + + /* Check this one */ + mask = bus_space_to_resource_flags(range->space); + for (i=0; iresource[i].flags & mask) == mask && + pdev->resource[i].start <= range->address && + pdev->resource[i].end > range->address) { + if ((range->address + range->size - 1) > pdev->resource[i].end) { + /* Add better message */ + printk(KERN_WARNING "PCI/OF resource overlap !\n"); + return NULL; + } + break; + } + } + if (i == DEVICE_COUNT_RESOURCE) + return NULL; + return &pdev->resource[i]; +} + +/* + * Request an OF device resource. Currently handles child of PCI devices, + * or other nodes attached to the root node. Ultimately, put some + * link to resources in the OF node. + */ +struct resource *request_OF_resource(struct device_node* node, int index, + const char* name_postfix) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + int nlen, plen; + + if (index >= node->n_addrs) + goto fail; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + goto fail; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while (nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + goto fail; + } + + res = __request_region(parent, node->addrs[index].address, + node->addrs[index].size, NULL); + if (!res) + goto fail; + nlen = strlen(node->name); + plen = name_postfix ? strlen(name_postfix) : 0; + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); + if (res->name) { + strcpy((char *)res->name, node->name); + if (plen) + strcpy((char *)res->name+nlen, name_postfix); + } + return res; +fail: + return NULL; +} +EXPORT_SYMBOL(request_OF_resource); + +int release_OF_resource(struct device_node *node, int index) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask, start, end; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + + if (index >= node->n_addrs) + return -EINVAL; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + return -EINVAL; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", + node->name); + return -ENODEV; + } + + /* Find us in the parent and its childs */ + res = parent->child; + start = node->addrs[index].address; + end = start + node->addrs[index].size - 1; + while (res) { + if (res->start == start && res->end == end && + (res->flags & IORESOURCE_BUSY)) + break; + if (res->start <= start && res->end >= end) + res = res->child; + else + res = res->sibling; + } + if (!res) + return -ENODEV; + + if (res->name) { + kfree(res->name); + res->name = NULL; + } + release_resource(res); + kfree(res); + + return 0; +} +EXPORT_SYMBOL(release_OF_resource); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c new file mode 100644 index 000000000000..e01cda1454c9 --- /dev/null +++ b/arch/powerpc/kernel/prom_init.c @@ -0,0 +1,2126 @@ +/* + * Procedures for interfacing to Open Firmware. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. + * {engebret|bergner}@us.ibm.com + * + * 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. + */ + +#undef DEBUG_PROM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_LOGO_LINUX_CLUT224 +#include +extern const struct linux_logo logo_linux_clut224; +#endif + +/* + * Properties whose value is longer than this get excluded from our + * copy of the device tree. This value does need to be big enough to + * ensure that we don't lose things like the interrupt-map property + * on a PCI-PCI bridge. + */ +#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024) + +/* + * Eventually bump that one up + */ +#define DEVTREE_CHUNK_SIZE 0x100000 + +/* + * This is the size of the local memory reserve map that gets copied + * into the boot params passed to the kernel. That size is totally + * flexible as the kernel just reads the list until it encounters an + * entry with size 0, so it can be changed without breaking binary + * compatibility + */ +#define MEM_RESERVE_MAP_SIZE 8 + +/* + * prom_init() is called very early on, before the kernel text + * and data have been mapped to KERNELBASE. At this point the code + * is running at whatever address it has been loaded at. + * On ppc32 we compile with -mrelocatable, which means that references + * to extern and static variables get relocated automatically. + * On ppc64 we have to relocate the references explicitly with + * RELOC. (Note that strings count as static variables.) + * + * Because OF may have mapped I/O devices into the area starting at + * KERNELBASE, particularly on CHRP machines, we can't safely call + * OF once the kernel has been mapped to KERNELBASE. Therefore all + * OF calls must be done within prom_init(). + * + * ADDR is used in calls to call_prom. The 4th and following + * arguments to call_prom should be 32-bit values. + * On ppc64, 64 bit values are truncated to 32 bits (and + * fortunately don't get interpreted as two arguments). + */ +#ifdef CONFIG_PPC64 +#define RELOC(x) (*PTRRELOC(&(x))) +#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) +#else +#define RELOC(x) (x) +#define ADDR(x) (u32) (x) +#endif + +#define PROM_BUG() do { \ + prom_printf("kernel BUG at %s line 0x%x!\n", \ + RELOC(__FILE__), __LINE__); \ + __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ +} while (0) + +#ifdef DEBUG_PROM +#define prom_debug(x...) prom_printf(x) +#else +#define prom_debug(x...) +#endif + +#ifdef CONFIG_PPC32 +#define PLATFORM_POWERMAC _MACH_Pmac +#define PLATFORM_CHRP _MACH_chrp +#endif + + +typedef u32 prom_arg_t; + +struct prom_args { + u32 service; + u32 nargs; + u32 nret; + prom_arg_t args[10]; +}; + +struct prom_t { + ihandle root; + ihandle chosen; + int cpu; + ihandle stdout; +}; + +struct mem_map_entry { + unsigned long base; + unsigned long size; +}; + +typedef u32 cell_t; + +extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); + +#ifdef CONFIG_PPC64 +extern void enter_prom(struct prom_args *args, unsigned long entry); +#else +static inline void enter_prom(struct prom_args *args, unsigned long entry) +{ + ((void (*)(struct prom_args *))entry)(args); +} +#endif + +extern void copy_and_flush(unsigned long dest, unsigned long src, + unsigned long size, unsigned long offset); + +/* prom structure */ +static struct prom_t __initdata prom; + +static unsigned long prom_entry __initdata; + +#define PROM_SCRATCH_SIZE 256 + +static char __initdata of_stdout_device[256]; +static char __initdata prom_scratch[PROM_SCRATCH_SIZE]; + +static unsigned long __initdata dt_header_start; +static unsigned long __initdata dt_struct_start, dt_struct_end; +static unsigned long __initdata dt_string_start, dt_string_end; + +static unsigned long __initdata prom_initrd_start, prom_initrd_end; + +#ifdef CONFIG_PPC64 +static int __initdata iommu_force_on; +static int __initdata ppc64_iommu_off; +static unsigned long __initdata prom_tce_alloc_start; +static unsigned long __initdata prom_tce_alloc_end; +#endif + +static int __initdata of_platform; + +static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; + +static unsigned long __initdata prom_memory_limit; + +static unsigned long __initdata alloc_top; +static unsigned long __initdata alloc_top_high; +static unsigned long __initdata alloc_bottom; +static unsigned long __initdata rmo_top; +static unsigned long __initdata ram_top; + +static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; +static int __initdata mem_reserve_cnt; + +static cell_t __initdata regbuf[1024]; + + +#define MAX_CPU_THREADS 2 + +/* TO GO */ +#ifdef CONFIG_HMT +struct { + unsigned int pir; + unsigned int threadid; +} hmt_thread_data[NR_CPUS]; +#endif /* CONFIG_HMT */ + +/* + * Error results ... some OF calls will return "-1" on error, some + * will return 0, some will return either. To simplify, here are + * macros to use with any ihandle or phandle return value to check if + * it is valid + */ + +#define PROM_ERROR (-1u) +#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) +#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) + + +/* This is the one and *ONLY* place where we actually call open + * firmware. + */ + +static int __init call_prom(const char *service, int nargs, int nret, ...) +{ + int i; + struct prom_args args; + va_list list; + + args.service = ADDR(service); + args.nargs = nargs; + args.nret = nret; + + va_start(list, nret); + for (i = 0; i < nargs; i++) + args.args[i] = va_arg(list, prom_arg_t); + va_end(list); + + for (i = 0; i < nret; i++) + args.args[nargs+i] = 0; + + enter_prom(&args, RELOC(prom_entry)); + + return (nret > 0) ? args.args[nargs] : 0; +} + +static int __init call_prom_ret(const char *service, int nargs, int nret, + prom_arg_t *rets, ...) +{ + int i; + struct prom_args args; + va_list list; + + args.service = ADDR(service); + args.nargs = nargs; + args.nret = nret; + + va_start(list, rets); + for (i = 0; i < nargs; i++) + args.args[i] = va_arg(list, prom_arg_t); + va_end(list); + + for (i = 0; i < nret; i++) + rets[nargs+i] = 0; + + enter_prom(&args, RELOC(prom_entry)); + + if (rets != NULL) + for (i = 1; i < nret; ++i) + rets[i] = args.args[nargs+i]; + + return (nret > 0) ? args.args[nargs] : 0; +} + + +static unsigned int __init prom_claim(unsigned long virt, unsigned long size, + unsigned long align) +{ + return (unsigned int)call_prom("claim", 3, 1, + (prom_arg_t)virt, (prom_arg_t)size, + (prom_arg_t)align); +} + +static void __init prom_print(const char *msg) +{ + const char *p, *q; + struct prom_t *_prom = &RELOC(prom); + + if (_prom->stdout == 0) + return; + + for (p = msg; *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + ++q; + call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2); + } +} + + +static void __init prom_print_hex(unsigned long val) +{ + int i, nibbles = sizeof(val)*2; + char buf[sizeof(val)*2+1]; + struct prom_t *_prom = &RELOC(prom); + + for (i = nibbles-1; i >= 0; i--) { + buf[i] = (val & 0xf) + '0'; + if (buf[i] > '9') + buf[i] += ('a'-'0'-10); + val >>= 4; + } + buf[nibbles] = '\0'; + call_prom("write", 3, 1, _prom->stdout, buf, nibbles); +} + + +static void __init prom_printf(const char *format, ...) +{ + const char *p, *q, *s; + va_list args; + unsigned long v; + struct prom_t *_prom = &RELOC(prom); + + va_start(args, format); +#ifdef CONFIG_PPC64 + format = PTRRELOC(format); +#endif + for (p = format; *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + if (*q == '\n') { + ++q; + call_prom("write", 3, 1, _prom->stdout, + ADDR("\r\n"), 2); + continue; + } + ++q; + if (*q == 0) + break; + switch (*q) { + case 's': + ++q; + s = va_arg(args, const char *); + prom_print(s); + break; + case 'x': + ++q; + v = va_arg(args, unsigned long); + prom_print_hex(v); + break; + } + } +} + + +static void __init __attribute__((noreturn)) prom_panic(const char *reason) +{ +#ifdef CONFIG_PPC64 + reason = PTRRELOC(reason); +#endif + prom_print(reason); + /* ToDo: should put up an SRC here on p/iSeries */ + call_prom("exit", 0, 0); + + for (;;) /* should never get here */ + ; +} + + +static int __init prom_next_node(phandle *nodep) +{ + phandle node; + + if ((node = *nodep) != 0 + && (*nodep = call_prom("child", 1, 1, node)) != 0) + return 1; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + for (;;) { + if ((node = call_prom("parent", 1, 1, node)) == 0) + return 0; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + } +} + +static int __init prom_getprop(phandle node, const char *pname, + void *value, size_t valuelen) +{ + return call_prom("getprop", 4, 1, node, ADDR(pname), + (u32)(unsigned long) value, (u32) valuelen); +} + +static int __init prom_getproplen(phandle node, const char *pname) +{ + return call_prom("getproplen", 2, 1, node, ADDR(pname)); +} + +static int __init prom_setprop(phandle node, const char *pname, + void *value, size_t valuelen) +{ + return call_prom("setprop", 4, 1, node, ADDR(pname), + (u32)(unsigned long) value, (u32) valuelen); +} + +/* We can't use the standard versions because of RELOC headaches. */ +#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ + || ('a' <= (c) && (c) <= 'f') \ + || ('A' <= (c) && (c) <= 'F')) + +#define isdigit(c) ('0' <= (c) && (c) <= '9') +#define islower(c) ('a' <= (c) && (c) <= 'z') +#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) + +unsigned long prom_strtoul(const char *cp, const char **endp) +{ + unsigned long result = 0, base = 10, value; + + if (*cp == '0') { + base = 8; + cp++; + if (toupper(*cp) == 'X') { + cp++; + base = 16; + } + } + + while (isxdigit(*cp) && + (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) { + result = result * base + value; + cp++; + } + + if (endp) + *endp = cp; + + return result; +} + +unsigned long prom_memparse(const char *ptr, const char **retptr) +{ + unsigned long ret = prom_strtoul(ptr, retptr); + int shift = 0; + + /* + * We can't use a switch here because GCC *may* generate a + * jump table which won't work, because we're not running at + * the address we're linked at. + */ + if ('G' == **retptr || 'g' == **retptr) + shift = 30; + + if ('M' == **retptr || 'm' == **retptr) + shift = 20; + + if ('K' == **retptr || 'k' == **retptr) + shift = 10; + + if (shift) { + ret <<= shift; + (*retptr)++; + } + + return ret; +} + +/* + * Early parsing of the command line passed to the kernel, used for + * "mem=x" and the options that affect the iommu + */ +static void __init early_cmdline_parse(void) +{ + struct prom_t *_prom = &RELOC(prom); + char *opt, *p; + int l = 0; + + RELOC(prom_cmd_line[0]) = 0; + p = RELOC(prom_cmd_line); + if ((long)_prom->chosen > 0) + l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1); +#ifdef CONFIG_CMDLINE + if (l == 0) /* dbl check */ + strlcpy(RELOC(prom_cmd_line), + RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line)); +#endif /* CONFIG_CMDLINE */ + prom_printf("command line: %s\n", RELOC(prom_cmd_line)); + +#ifdef CONFIG_PPC64 + opt = strstr(RELOC(prom_cmd_line), RELOC("iommu=")); + if (opt) { + prom_printf("iommu opt is: %s\n", opt); + opt += 6; + while (*opt && *opt == ' ') + opt++; + if (!strncmp(opt, RELOC("off"), 3)) + RELOC(ppc64_iommu_off) = 1; + else if (!strncmp(opt, RELOC("force"), 5)) + RELOC(iommu_force_on) = 1; + } +#endif + + opt = strstr(RELOC(prom_cmd_line), RELOC("mem=")); + if (opt) { + opt += 4; + RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt); +#ifdef CONFIG_PPC64 + /* Align to 16 MB == size of ppc64 large page */ + RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); +#endif + } +} + +#ifdef CONFIG_PPC_PSERIES +/* + * To tell the firmware what our capabilities are, we have to pass + * it a fake 32-bit ELF header containing a couple of PT_NOTE sections + * that contain structures that contain the actual values. + */ +static struct fake_elf { + Elf32_Ehdr elfhdr; + Elf32_Phdr phdr[2]; + struct chrpnote { + u32 namesz; + u32 descsz; + u32 type; + char name[8]; /* "PowerPC" */ + struct chrpdesc { + u32 real_mode; + u32 real_base; + u32 real_size; + u32 virt_base; + u32 virt_size; + u32 load_base; + } chrpdesc; + } chrpnote; + struct rpanote { + u32 namesz; + u32 descsz; + u32 type; + char name[24]; /* "IBM,RPA-Client-Config" */ + struct rpadesc { + u32 lpar_affinity; + u32 min_rmo_size; + u32 min_rmo_percent; + u32 max_pft_size; + u32 splpar; + u32 min_load; + u32 new_mem_def; + u32 ignore_me; + } rpadesc; + } rpanote; +} fake_elf = { + .elfhdr = { + .e_ident = { 0x7f, 'E', 'L', 'F', + ELFCLASS32, ELFDATA2MSB, EV_CURRENT }, + .e_type = ET_EXEC, /* yeah right */ + .e_machine = EM_PPC, + .e_version = EV_CURRENT, + .e_phoff = offsetof(struct fake_elf, phdr), + .e_phentsize = sizeof(Elf32_Phdr), + .e_phnum = 2 + }, + .phdr = { + [0] = { + .p_type = PT_NOTE, + .p_offset = offsetof(struct fake_elf, chrpnote), + .p_filesz = sizeof(struct chrpnote) + }, [1] = { + .p_type = PT_NOTE, + .p_offset = offsetof(struct fake_elf, rpanote), + .p_filesz = sizeof(struct rpanote) + } + }, + .chrpnote = { + .namesz = sizeof("PowerPC"), + .descsz = sizeof(struct chrpdesc), + .type = 0x1275, + .name = "PowerPC", + .chrpdesc = { + .real_mode = ~0U, /* ~0 means "don't care" */ + .real_base = ~0U, + .real_size = ~0U, + .virt_base = ~0U, + .virt_size = ~0U, + .load_base = ~0U + }, + }, + .rpanote = { + .namesz = sizeof("IBM,RPA-Client-Config"), + .descsz = sizeof(struct rpadesc), + .type = 0x12759999, + .name = "IBM,RPA-Client-Config", + .rpadesc = { + .lpar_affinity = 0, + .min_rmo_size = 64, /* in megabytes */ + .min_rmo_percent = 0, + .max_pft_size = 48, /* 2^48 bytes max PFT size */ + .splpar = 1, + .min_load = ~0U, + .new_mem_def = 0 + } + } +}; + +static void __init prom_send_capabilities(void) +{ + ihandle elfloader; + + elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); + if (elfloader == 0) { + prom_printf("couldn't open /packages/elf-loader\n"); + return; + } + call_prom("call-method", 3, 1, ADDR("process-elf-header"), + elfloader, ADDR(&fake_elf)); + call_prom("close", 1, 0, elfloader); +} +#endif + +/* + * Memory allocation strategy... our layout is normally: + * + * at 14Mb or more we have vmlinux, then a gap and initrd. In some + * rare cases, initrd might end up being before the kernel though. + * We assume this won't override the final kernel at 0, we have no + * provision to handle that in this version, but it should hopefully + * never happen. + * + * alloc_top is set to the top of RMO, eventually shrink down if the + * TCEs overlap + * + * alloc_bottom is set to the top of kernel/initrd + * + * from there, allocations are done this way : rtas is allocated + * topmost, and the device-tree is allocated from the bottom. We try + * to grow the device-tree allocation as we progress. If we can't, + * then we fail, we don't currently have a facility to restart + * elsewhere, but that shouldn't be necessary. + * + * Note that calls to reserve_mem have to be done explicitly, memory + * allocated with either alloc_up or alloc_down isn't automatically + * reserved. + */ + + +/* + * Allocates memory in the RMO upward from the kernel/initrd + * + * When align is 0, this is a special case, it means to allocate in place + * at the current location of alloc_bottom or fail (that is basically + * extending the previous allocation). Used for the device-tree flattening + */ +static unsigned long __init alloc_up(unsigned long size, unsigned long align) +{ + unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align); + unsigned long addr = 0; + + prom_debug("alloc_up(%x, %x)\n", size, align); + if (RELOC(ram_top) == 0) + prom_panic("alloc_up() called with mem not initialized\n"); + + if (align) + base = _ALIGN_UP(RELOC(alloc_bottom), align); + else + base = RELOC(alloc_bottom); + + for(; (base + size) <= RELOC(alloc_top); + base = _ALIGN_UP(base + 0x100000, align)) { + prom_debug(" trying: 0x%x\n\r", base); + addr = (unsigned long)prom_claim(base, size, 0); + if (addr != PROM_ERROR) + break; + addr = 0; + if (align == 0) + break; + } + if (addr == 0) + return 0; + RELOC(alloc_bottom) = addr; + + prom_debug(" -> %x\n", addr); + prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); + prom_debug(" alloc_top : %x\n", RELOC(alloc_top)); + prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); + prom_debug(" rmo_top : %x\n", RELOC(rmo_top)); + prom_debug(" ram_top : %x\n", RELOC(ram_top)); + + return addr; +} + +/* + * Allocates memory downward, either from top of RMO, or if highmem + * is set, from the top of RAM. Note that this one doesn't handle + * failures. It does claim memory if highmem is not set. + */ +static unsigned long __init alloc_down(unsigned long size, unsigned long align, + int highmem) +{ + unsigned long base, addr = 0; + + prom_debug("alloc_down(%x, %x, %s)\n", size, align, + highmem ? RELOC("(high)") : RELOC("(low)")); + if (RELOC(ram_top) == 0) + prom_panic("alloc_down() called with mem not initialized\n"); + + if (highmem) { + /* Carve out storage for the TCE table. */ + addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align); + if (addr <= RELOC(alloc_bottom)) + return 0; + /* Will we bump into the RMO ? If yes, check out that we + * didn't overlap existing allocations there, if we did, + * we are dead, we must be the first in town ! + */ + if (addr < RELOC(rmo_top)) { + /* Good, we are first */ + if (RELOC(alloc_top) == RELOC(rmo_top)) + RELOC(alloc_top) = RELOC(rmo_top) = addr; + else + return 0; + } + RELOC(alloc_top_high) = addr; + goto bail; + } + + base = _ALIGN_DOWN(RELOC(alloc_top) - size, align); + for (; base > RELOC(alloc_bottom); + base = _ALIGN_DOWN(base - 0x100000, align)) { + prom_debug(" trying: 0x%x\n\r", base); + addr = (unsigned long)prom_claim(base, size, 0); + if (addr != PROM_ERROR) + break; + addr = 0; + } + if (addr == 0) + return 0; + RELOC(alloc_top) = addr; + + bail: + prom_debug(" -> %x\n", addr); + prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); + prom_debug(" alloc_top : %x\n", RELOC(alloc_top)); + prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); + prom_debug(" rmo_top : %x\n", RELOC(rmo_top)); + prom_debug(" ram_top : %x\n", RELOC(ram_top)); + + return addr; +} + +/* + * Parse a "reg" cell + */ +static unsigned long __init prom_next_cell(int s, cell_t **cellp) +{ + cell_t *p = *cellp; + unsigned long r = 0; + + /* Ignore more than 2 cells */ + while (s > sizeof(unsigned long) / 4) { + p++; + s--; + } + r = *p++; +#ifdef CONFIG_PPC64 + if (s) { + r <<= 32; + r |= *(p++); + } +#endif + *cellp = p; + return r; +} + +/* + * Very dumb function for adding to the memory reserve list, but + * we don't need anything smarter at this point + * + * XXX Eventually check for collisions. They should NEVER happen. + * If problems seem to show up, it would be a good start to track + * them down. + */ +static void reserve_mem(unsigned long base, unsigned long size) +{ + unsigned long top = base + size; + unsigned long cnt = RELOC(mem_reserve_cnt); + + if (size == 0) + return; + + /* We need to always keep one empty entry so that we + * have our terminator with "size" set to 0 since we are + * dumb and just copy this entire array to the boot params + */ + base = _ALIGN_DOWN(base, PAGE_SIZE); + top = _ALIGN_UP(top, PAGE_SIZE); + size = top - base; + + if (cnt >= (MEM_RESERVE_MAP_SIZE - 1)) + prom_panic("Memory reserve map exhausted !\n"); + RELOC(mem_reserve_map)[cnt].base = base; + RELOC(mem_reserve_map)[cnt].size = size; + RELOC(mem_reserve_cnt) = cnt + 1; +} + +/* + * Initialize memory allocation mecanism, parse "memory" nodes and + * obtain that way the top of memory and RMO to setup out local allocator + */ +static void __init prom_init_mem(void) +{ + phandle node; + char *path, type[64]; + unsigned int plen; + cell_t *p, *endp; + struct prom_t *_prom = &RELOC(prom); + u32 rac, rsc; + + /* + * We iterate the memory nodes to find + * 1) top of RMO (first node) + * 2) top of memory + */ + rac = 2; + prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac)); + rsc = 1; + prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc)); + prom_debug("root_addr_cells: %x\n", (unsigned long) rac); + prom_debug("root_size_cells: %x\n", (unsigned long) rsc); + + prom_debug("scanning memory:\n"); + path = RELOC(prom_scratch); + + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + prom_getprop(node, "device_type", type, sizeof(type)); + + if (strcmp(type, RELOC("memory"))) + continue; + + plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf)); + if (plen > sizeof(regbuf)) { + prom_printf("memory node too large for buffer !\n"); + plen = sizeof(regbuf); + } + p = RELOC(regbuf); + endp = p + (plen / sizeof(cell_t)); + +#ifdef DEBUG_PROM + memset(path, 0, PROM_SCRATCH_SIZE); + call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1); + prom_debug(" node %s :\n", path); +#endif /* DEBUG_PROM */ + + while ((endp - p) >= (rac + rsc)) { + unsigned long base, size; + + base = prom_next_cell(rac, &p); + size = prom_next_cell(rsc, &p); + + if (size == 0) + continue; + prom_debug(" %x %x\n", base, size); + if (base == 0) + RELOC(rmo_top) = size; + if ((base + size) > RELOC(ram_top)) + RELOC(ram_top) = base + size; + } + } + + RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000); + + /* Check if we have an initrd after the kernel, if we do move our bottom + * point to after it + */ + if (RELOC(prom_initrd_start)) { + if (RELOC(prom_initrd_end) > RELOC(alloc_bottom)) + RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end)); + } + + /* + * If prom_memory_limit is set we reduce the upper limits *except* for + * alloc_top_high. This must be the real top of RAM so we can put + * TCE's up there. + */ + + RELOC(alloc_top_high) = RELOC(ram_top); + + if (RELOC(prom_memory_limit)) { + if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) { + prom_printf("Ignoring mem=%x <= alloc_bottom.\n", + RELOC(prom_memory_limit)); + RELOC(prom_memory_limit) = 0; + } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) { + prom_printf("Ignoring mem=%x >= ram_top.\n", + RELOC(prom_memory_limit)); + RELOC(prom_memory_limit) = 0; + } else { + RELOC(ram_top) = RELOC(prom_memory_limit); + RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit)); + } + } + + /* + * Setup our top alloc point, that is top of RMO or top of + * segment 0 when running non-LPAR. + * Some RS64 machines have buggy firmware where claims up at + * 1GB fail. Cap at 768MB as a workaround. + * Since 768MB is plenty of room, and we need to cap to something + * reasonable on 32-bit, cap at 768MB on all machines. + */ + if (!RELOC(rmo_top)) + RELOC(rmo_top) = RELOC(ram_top); + RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top)); + RELOC(alloc_top) = RELOC(rmo_top); + + prom_printf("memory layout at init:\n"); + prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); + prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); + prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); + prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); + prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); + prom_printf(" ram_top : %x\n", RELOC(ram_top)); +} + + +/* + * Allocate room for and instantiate RTAS + */ +static void __init prom_instantiate_rtas(void) +{ + phandle rtas_node; + ihandle rtas_inst; + u32 base, entry = 0; + u32 size = 0; + + prom_debug("prom_instantiate_rtas: start...\n"); + + rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); + prom_debug("rtas_node: %x\n", rtas_node); + if (!PHANDLE_VALID(rtas_node)) + return; + + prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); + if (size == 0) + return; + + base = alloc_down(size, PAGE_SIZE, 0); + if (base == 0) { + prom_printf("RTAS allocation failed !\n"); + return; + } + + rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); + if (!IHANDLE_VALID(rtas_inst)) { + prom_printf("opening rtas package failed"); + return; + } + + prom_printf("instantiating rtas at 0x%x ...", base); + + if (call_prom_ret("call-method", 3, 2, &entry, + ADDR("instantiate-rtas"), + rtas_inst, base) == PROM_ERROR + || entry == 0) { + prom_printf(" failed\n"); + return; + } + prom_printf(" done\n"); + + reserve_mem(base, size); + + prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); + prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); + + prom_debug("rtas base = 0x%x\n", base); + prom_debug("rtas entry = 0x%x\n", entry); + prom_debug("rtas size = 0x%x\n", (long)size); + + prom_debug("prom_instantiate_rtas: end...\n"); +} + +#ifdef CONFIG_PPC64 +/* + * Allocate room for and initialize TCE tables + */ +static void __init prom_initialize_tce_table(void) +{ + phandle node; + ihandle phb_node; + char compatible[64], type[64], model[64]; + char *path = RELOC(prom_scratch); + u64 base, align; + u32 minalign, minsize; + u64 tce_entry, *tce_entryp; + u64 local_alloc_top, local_alloc_bottom; + u64 i; + + if (RELOC(ppc64_iommu_off)) + return; + + prom_debug("starting prom_initialize_tce_table\n"); + + /* Cache current top of allocs so we reserve a single block */ + local_alloc_top = RELOC(alloc_top_high); + local_alloc_bottom = local_alloc_top; + + /* Search all nodes looking for PHBs. */ + for (node = 0; prom_next_node(&node); ) { + compatible[0] = 0; + type[0] = 0; + model[0] = 0; + prom_getprop(node, "compatible", + compatible, sizeof(compatible)); + prom_getprop(node, "device_type", type, sizeof(type)); + prom_getprop(node, "model", model, sizeof(model)); + + if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) + continue; + + /* Keep the old logic in tack to avoid regression. */ + if (compatible[0] != 0) { + if ((strstr(compatible, RELOC("python")) == NULL) && + (strstr(compatible, RELOC("Speedwagon")) == NULL) && + (strstr(compatible, RELOC("Winnipeg")) == NULL)) + continue; + } else if (model[0] != 0) { + if ((strstr(model, RELOC("ython")) == NULL) && + (strstr(model, RELOC("peedwagon")) == NULL) && + (strstr(model, RELOC("innipeg")) == NULL)) + continue; + } + + if (prom_getprop(node, "tce-table-minalign", &minalign, + sizeof(minalign)) == PROM_ERROR) + minalign = 0; + if (prom_getprop(node, "tce-table-minsize", &minsize, + sizeof(minsize)) == PROM_ERROR) + minsize = 4UL << 20; + + /* + * Even though we read what OF wants, we just set the table + * size to 4 MB. This is enough to map 2GB of PCI DMA space. + * By doing this, we avoid the pitfalls of trying to DMA to + * MMIO space and the DMA alias hole. + * + * On POWER4, firmware sets the TCE region by assuming + * each TCE table is 8MB. Using this memory for anything + * else will impact performance, so we always allocate 8MB. + * Anton + */ + if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) + minsize = 8UL << 20; + else + minsize = 4UL << 20; + + /* Align to the greater of the align or size */ + align = max(minalign, minsize); + base = alloc_down(minsize, align, 1); + if (base == 0) + prom_panic("ERROR, cannot find space for TCE table.\n"); + if (base < local_alloc_bottom) + local_alloc_bottom = base; + + /* Save away the TCE table attributes for later use. */ + prom_setprop(node, "linux,tce-base", &base, sizeof(base)); + prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize)); + + /* It seems OF doesn't null-terminate the path :-( */ + memset(path, 0, sizeof(path)); + /* Call OF to setup the TCE hardware */ + if (call_prom("package-to-path", 3, 1, node, + path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) { + prom_printf("package-to-path failed\n"); + } + + prom_debug("TCE table: %s\n", path); + prom_debug("\tnode = 0x%x\n", node); + prom_debug("\tbase = 0x%x\n", base); + prom_debug("\tsize = 0x%x\n", minsize); + + /* Initialize the table to have a one-to-one mapping + * over the allocated size. + */ + tce_entryp = (unsigned long *)base; + for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) { + tce_entry = (i << PAGE_SHIFT); + tce_entry |= 0x3; + *tce_entryp = tce_entry; + } + + prom_printf("opening PHB %s", path); + phb_node = call_prom("open", 1, 1, path); + if (phb_node == 0) + prom_printf("... failed\n"); + else + prom_printf("... done\n"); + + call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"), + phb_node, -1, minsize, + (u32) base, (u32) (base >> 32)); + call_prom("close", 1, 0, phb_node); + } + + reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom); + + if (RELOC(prom_memory_limit)) { + /* + * We align the start to a 16MB boundary so we can map + * the TCE area using large pages if possible. + * The end should be the top of RAM so no need to align it. + */ + RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, + 0x1000000); + RELOC(prom_tce_alloc_end) = local_alloc_top; + } + + /* Flag the first invalid entry */ + prom_debug("ending prom_initialize_tce_table\n"); +} +#endif + +/* + * With CHRP SMP we need to use the OF to start the other processors. + * We can't wait until smp_boot_cpus (the OF is trashed by then) + * so we have to put the processors into a holding pattern controlled + * by the kernel (not OF) before we destroy the OF. + * + * This uses a chunk of low memory, puts some holding pattern + * code there and sends the other processors off to there until + * smp_boot_cpus tells them to do something. The holding pattern + * checks that address until its cpu # is there, when it is that + * cpu jumps to __secondary_start(). smp_boot_cpus() takes care + * of setting those values. + * + * We also use physical address 0x4 here to tell when a cpu + * is in its holding pattern code. + * + * -- Cort + */ +static void __init prom_hold_cpus(void) +{ +#ifdef CONFIG_PPC64 + unsigned long i; + unsigned int reg; + phandle node; + char type[64]; + int cpuid = 0; + unsigned int interrupt_server[MAX_CPU_THREADS]; + unsigned int cpu_threads, hw_cpu_num; + int propsize; + extern void __secondary_hold(void); + extern unsigned long __secondary_hold_spinloop; + extern unsigned long __secondary_hold_acknowledge; + unsigned long *spinloop + = (void *) __pa(&__secondary_hold_spinloop); + unsigned long *acknowledge + = (void *) __pa(&__secondary_hold_acknowledge); +#ifdef CONFIG_PPC64 + unsigned long secondary_hold + = __pa(*PTRRELOC((unsigned long *)__secondary_hold)); +#else + unsigned long secondary_hold = __pa(&__secondary_hold); +#endif + struct prom_t *_prom = &RELOC(prom); + + prom_debug("prom_hold_cpus: start...\n"); + prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); + prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); + prom_debug(" 1) acknowledge = 0x%x\n", + (unsigned long)acknowledge); + prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge); + prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold); + + /* Set the common spinloop variable, so all of the secondary cpus + * will block when they are awakened from their OF spinloop. + * This must occur for both SMP and non SMP kernels, since OF will + * be trashed when we move the kernel. + */ + *spinloop = 0; + +#ifdef CONFIG_HMT + for (i = 0; i < NR_CPUS; i++) { + RELOC(hmt_thread_data)[i].pir = 0xdeadbeef; + } +#endif + /* look for cpus */ + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + prom_getprop(node, "device_type", type, sizeof(type)); + if (strcmp(type, RELOC("cpu")) != 0) + continue; + + /* Skip non-configured cpus. */ + if (prom_getprop(node, "status", type, sizeof(type)) > 0) + if (strcmp(type, RELOC("okay")) != 0) + continue; + + reg = -1; + prom_getprop(node, "reg", ®, sizeof(reg)); + + prom_debug("\ncpuid = 0x%x\n", cpuid); + prom_debug("cpu hw idx = 0x%x\n", reg); + + /* Init the acknowledge var which will be reset by + * the secondary cpu when it awakens from its OF + * spinloop. + */ + *acknowledge = (unsigned long)-1; + + propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s", + &interrupt_server, + sizeof(interrupt_server)); + if (propsize < 0) { + /* no property. old hardware has no SMT */ + cpu_threads = 1; + interrupt_server[0] = reg; /* fake it with phys id */ + } else { + /* We have a threaded processor */ + cpu_threads = propsize / sizeof(u32); + if (cpu_threads > MAX_CPU_THREADS) { + prom_printf("SMT: too many threads!\n" + "SMT: found %x, max is %x\n", + cpu_threads, MAX_CPU_THREADS); + cpu_threads = 1; /* ToDo: panic? */ + } + } + + hw_cpu_num = interrupt_server[0]; + if (hw_cpu_num != _prom->cpu) { + /* Primary Thread of non-boot cpu */ + prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg); + call_prom("start-cpu", 3, 0, node, + secondary_hold, reg); + + for ( i = 0 ; (i < 100000000) && + (*acknowledge == ((unsigned long)-1)); i++ ) + mb(); + + if (*acknowledge == reg) { + prom_printf("done\n"); + /* We have to get every CPU out of OF, + * even if we never start it. */ + if (cpuid >= NR_CPUS) + goto next; + } else { + prom_printf("failed: %x\n", *acknowledge); + } + } +#ifdef CONFIG_SMP + else + prom_printf("%x : boot cpu %x\n", cpuid, reg); +#endif +next: +#ifdef CONFIG_SMP + /* Init paca for secondary threads. They start later. */ + for (i=1; i < cpu_threads; i++) { + cpuid++; + if (cpuid >= NR_CPUS) + continue; + } +#endif /* CONFIG_SMP */ + cpuid++; + } +#ifdef CONFIG_HMT + /* Only enable HMT on processors that provide support. */ + if (__is_processor(PV_PULSAR) || + __is_processor(PV_ICESTAR) || + __is_processor(PV_SSTAR)) { + prom_printf(" starting secondary threads\n"); + + for (i = 0; i < NR_CPUS; i += 2) { + if (!cpu_online(i)) + continue; + + if (i == 0) { + unsigned long pir = mfspr(SPRN_PIR); + if (__is_processor(PV_PULSAR)) { + RELOC(hmt_thread_data)[i].pir = + pir & 0x1f; + } else { + RELOC(hmt_thread_data)[i].pir = + pir & 0x3ff; + } + } + } + } else { + prom_printf("Processor is not HMT capable\n"); + } +#endif + + if (cpuid > NR_CPUS) + prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS) + ") exceeded: ignoring extras\n"); + + prom_debug("prom_hold_cpus: end...\n"); +#endif +} + + +static void __init prom_init_client_services(unsigned long pp) +{ + struct prom_t *_prom = &RELOC(prom); + + /* Get a handle to the prom entry point before anything else */ + RELOC(prom_entry) = pp; + + /* get a handle for the stdout device */ + _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); + if (!PHANDLE_VALID(_prom->chosen)) + prom_panic("cannot find chosen"); /* msg won't be printed :( */ + + /* get device tree root */ + _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); + if (!PHANDLE_VALID(_prom->root)) + prom_panic("cannot find device tree root"); /* msg won't be printed :( */ +} + +static void __init prom_init_stdout(void) +{ + struct prom_t *_prom = &RELOC(prom); + char *path = RELOC(of_stdout_device); + char type[16]; + u32 val; + + if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0) + prom_panic("cannot find stdout"); + + _prom->stdout = val; + + /* Get the full OF pathname of the stdout device */ + memset(path, 0, 256); + call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); + val = call_prom("instance-to-package", 1, 1, _prom->stdout); + prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val)); + prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); + prom_setprop(_prom->chosen, "linux,stdout-path", + RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1); + + /* If it's a display, note it */ + memset(type, 0, sizeof(type)); + prom_getprop(val, "device_type", type, sizeof(type)); + if (strcmp(type, RELOC("display")) == 0) + prom_setprop(val, "linux,boot-display", NULL, 0); +} + +static void __init prom_close_stdin(void) +{ + struct prom_t *_prom = &RELOC(prom); + ihandle val; + + if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0) + call_prom("close", 1, 0, val); +} + +static int __init prom_find_machine_type(void) +{ + struct prom_t *_prom = &RELOC(prom); + char compat[256]; + int len, i = 0; + phandle rtas; + + len = prom_getprop(_prom->root, "compatible", + compat, sizeof(compat)-1); + if (len > 0) { + compat[len] = 0; + while (i < len) { + char *p = &compat[i]; + int sl = strlen(p); + if (sl == 0) + break; + if (strstr(p, RELOC("Power Macintosh")) || + strstr(p, RELOC("MacRISC4"))) + return PLATFORM_POWERMAC; +#ifdef CONFIG_PPC64 + if (strstr(p, RELOC("Momentum,Maple"))) + return PLATFORM_MAPLE; +#endif + i += sl + 1; + } + } +#ifdef CONFIG_PPC64 + /* Default to pSeries. We need to know if we are running LPAR */ + rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); + if (PHANDLE_VALID(rtas)) { + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (x != PROM_ERROR) { + prom_printf("Hypertas detected, assuming LPAR !\n"); + return PLATFORM_PSERIES_LPAR; + } + } + return PLATFORM_PSERIES; +#else + return PLATFORM_CHRP; +#endif +} + +static int __init setup_disp(phandle dp) +{ +#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) + int width = 640, height = 480, depth = 8, pitch; + unsigned address; + u32 addrs[8][5]; + int i, naddrs; + char name[32]; + char *getprop = "getprop"; + + prom_printf("Initializing screen: "); + + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); + name[sizeof(name)-1] = 0; + prom_print(name); + prom_print("\n"); + call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); + pitch = width * ((depth + 7) / 8); + call_prom(getprop, 4, 1, dp, "linebytes", + &pitch, sizeof(pitch)); + if (pitch == 1) + pitch = 0x1000; /* for strange IBM display */ + address = 0; + call_prom(getprop, 4, 1, dp, "address", &address, sizeof(address)); + if (address == 0) { + /* look for an assigned address with a size of >= 1MB */ + naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses", + addrs, sizeof(addrs)); + naddrs /= 20; + for (i = 0; i < naddrs; ++i) { + if (addrs[i][4] >= (1 << 20)) { + address = addrs[i][2]; + /* use the BE aperture if possible */ + if (addrs[i][4] >= (16 << 20)) + address += (8 << 20); + break; + } + } + if (address == 0) { + prom_print("Failed to get address\n"); + return 0; + } + } + /* kludge for valkyrie */ + if (strcmp(name, "valkyrie") == 0) + address += 0x1000; + + prom_printf("\n\n\n\naddress = %x\n", address); + btext_setup_display(width, height, depth, pitch, address); +#endif /* CONFIG_BOOTX_TEXT && CONFIG_PPC32 */ + return 1; +} + +static int __init prom_set_color(ihandle ih, int i, int r, int g, int b) +{ + return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r); +} + +/* + * If we have a display that we don't know how to drive, + * we will want to try to execute OF's open method for it + * later. However, OF will probably fall over if we do that + * we've taken over the MMU. + * So we check whether we will need to open the display, + * and if so, open it now. + */ +static void __init prom_check_displays(void) +{ + char type[16], *path; + phandle node; + ihandle ih; + int i; + int got_display = 0; + + static unsigned char default_colors[] = { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaa, + 0x00, 0xaa, 0x00, + 0x00, 0xaa, 0xaa, + 0xaa, 0x00, 0x00, + 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x00, + 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0xff, + 0x55, 0xff, 0x55, + 0x55, 0xff, 0xff, + 0xff, 0x55, 0x55, + 0xff, 0x55, 0xff, + 0xff, 0xff, 0x55, + 0xff, 0xff, 0xff + }; + const unsigned char *clut; + + prom_printf("Looking for displays\n"); + for (node = 0; prom_next_node(&node); ) { + memset(type, 0, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); + if (strcmp(type, RELOC("display")) != 0) + continue; + + /* It seems OF doesn't null-terminate the path :-( */ + path = RELOC(prom_scratch); + memset(path, 0, PROM_SCRATCH_SIZE); + + /* + * leave some room at the end of the path for appending extra + * arguments + */ + if (call_prom("package-to-path", 3, 1, node, path, + PROM_SCRATCH_SIZE-10) == PROM_ERROR) + continue; + prom_printf("found display : %s, opening ... ", path); + + ih = call_prom("open", 1, 1, path); + if (ih == 0) { + prom_printf("failed\n"); + continue; + } + + /* Success */ + prom_printf("done\n"); + prom_setprop(node, "linux,opened", NULL, 0); + + /* Setup a usable color table when the appropriate + * method is available. Should update this to set-colors */ + clut = RELOC(default_colors); + for (i = 0; i < 32; i++, clut += 3) + if (prom_set_color(ih, i, clut[0], clut[1], + clut[2]) != 0) + break; + +#ifdef CONFIG_LOGO_LINUX_CLUT224 + clut = PTRRELOC(RELOC(logo_linux_clut224.clut)); + for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3) + if (prom_set_color(ih, i + 32, clut[0], clut[1], + clut[2]) != 0) + break; +#endif /* CONFIG_LOGO_LINUX_CLUT224 */ + if (!got_display) + got_display = setup_disp(node); + } +} + + +/* Return (relocated) pointer to this much memory: moves initrd if reqd. */ +static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, + unsigned long needed, unsigned long align) +{ + void *ret; + + *mem_start = _ALIGN(*mem_start, align); + while ((*mem_start + needed) > *mem_end) { + unsigned long room, chunk; + + prom_debug("Chunk exhausted, claiming more at %x...\n", + RELOC(alloc_bottom)); + room = RELOC(alloc_top) - RELOC(alloc_bottom); + if (room > DEVTREE_CHUNK_SIZE) + room = DEVTREE_CHUNK_SIZE; + if (room < PAGE_SIZE) + prom_panic("No memory for flatten_device_tree (no room)"); + chunk = alloc_up(room, 0); + if (chunk == 0) + prom_panic("No memory for flatten_device_tree (claim failed)"); + *mem_end = RELOC(alloc_top); + } + + ret = (void *)*mem_start; + *mem_start += needed; + + return ret; +} + +#define dt_push_token(token, mem_start, mem_end) \ + do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0) + +static unsigned long __init dt_find_string(char *str) +{ + char *s, *os; + + s = os = (char *)RELOC(dt_string_start); + s += 4; + while (s < (char *)RELOC(dt_string_end)) { + if (strcmp(s, str) == 0) + return s - os; + s += strlen(s) + 1; + } + return 0; +} + +/* + * The Open Firmware 1275 specification states properties must be 31 bytes or + * less, however not all firmwares obey this. Make it 64 bytes to be safe. + */ +#define MAX_PROPERTY_NAME 64 + +static void __init scan_dt_build_strings(phandle node, + unsigned long *mem_start, + unsigned long *mem_end) +{ + char *prev_name, *namep, *sstart; + unsigned long soff; + phandle child; + + sstart = (char *)RELOC(dt_string_start); + + /* get and store all property names */ + prev_name = RELOC(""); + for (;;) { + /* 64 is max len of name including nul. */ + namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); + if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) { + /* No more nodes: unwind alloc */ + *mem_start = (unsigned long)namep; + break; + } + + /* skip "name" */ + if (strcmp(namep, RELOC("name")) == 0) { + *mem_start = (unsigned long)namep; + prev_name = RELOC("name"); + continue; + } + /* get/create string entry */ + soff = dt_find_string(namep); + if (soff != 0) { + *mem_start = (unsigned long)namep; + namep = sstart + soff; + } else { + /* Trim off some if we can */ + *mem_start = (unsigned long)namep + strlen(namep) + 1; + RELOC(dt_string_end) = *mem_start; + } + prev_name = namep; + } + + /* do all our children */ + child = call_prom("child", 1, 1, node); + while (child != 0) { + scan_dt_build_strings(child, mem_start, mem_end); + child = call_prom("peer", 1, 1, child); + } +} + +static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, + unsigned long *mem_end) +{ + phandle child; + char *namep, *prev_name, *sstart, *p, *ep, *lp, *path; + unsigned long soff; + unsigned char *valp; + static char pname[MAX_PROPERTY_NAME]; + int l; + + dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); + + /* get the node's full name */ + namep = (char *)*mem_start; + l = call_prom("package-to-path", 3, 1, node, + namep, *mem_end - *mem_start); + if (l >= 0) { + /* Didn't fit? Get more room. */ + if ((l+1) > (*mem_end - *mem_start)) { + namep = make_room(mem_start, mem_end, l+1, 1); + call_prom("package-to-path", 3, 1, node, namep, l); + } + namep[l] = '\0'; + + /* Fixup an Apple bug where they have bogus \0 chars in the + * middle of the path in some properties + */ + for (p = namep, ep = namep + l; p < ep; p++) + if (*p == '\0') { + memmove(p, p+1, ep - p); + ep--; l--; p--; + } + + /* now try to extract the unit name in that mess */ + for (p = namep, lp = NULL; *p; p++) + if (*p == '/') + lp = p + 1; + if (lp != NULL) + memmove(namep, lp, strlen(lp) + 1); + *mem_start = _ALIGN(((unsigned long) namep) + + strlen(namep) + 1, 4); + } + + /* get it again for debugging */ + path = RELOC(prom_scratch); + memset(path, 0, PROM_SCRATCH_SIZE); + call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1); + + /* get and store all properties */ + prev_name = RELOC(""); + sstart = (char *)RELOC(dt_string_start); + for (;;) { + if (call_prom("nextprop", 3, 1, node, prev_name, + RELOC(pname)) != 1) + break; + + /* skip "name" */ + if (strcmp(RELOC(pname), RELOC("name")) == 0) { + prev_name = RELOC("name"); + continue; + } + + /* find string offset */ + soff = dt_find_string(RELOC(pname)); + if (soff == 0) { + prom_printf("WARNING: Can't find string index for" + " <%s>, node %s\n", RELOC(pname), path); + break; + } + prev_name = sstart + soff; + + /* get length */ + l = call_prom("getproplen", 2, 1, node, RELOC(pname)); + + /* sanity checks */ + if (l == PROM_ERROR) + continue; + if (l > MAX_PROPERTY_LENGTH) { + prom_printf("WARNING: ignoring large property "); + /* It seems OF doesn't null-terminate the path :-( */ + prom_printf("[%s] ", path); + prom_printf("%s length 0x%x\n", RELOC(pname), l); + continue; + } + + /* push property head */ + dt_push_token(OF_DT_PROP, mem_start, mem_end); + dt_push_token(l, mem_start, mem_end); + dt_push_token(soff, mem_start, mem_end); + + /* push property content */ + valp = make_room(mem_start, mem_end, l, 4); + call_prom("getprop", 4, 1, node, RELOC(pname), valp, l); + *mem_start = _ALIGN(*mem_start, 4); + } + + /* Add a "linux,phandle" property. */ + soff = dt_find_string(RELOC("linux,phandle")); + if (soff == 0) + prom_printf("WARNING: Can't find string index for" + " node %s\n", path); + else { + dt_push_token(OF_DT_PROP, mem_start, mem_end); + dt_push_token(4, mem_start, mem_end); + dt_push_token(soff, mem_start, mem_end); + valp = make_room(mem_start, mem_end, 4, 4); + *(u32 *)valp = node; + } + + /* do all our children */ + child = call_prom("child", 1, 1, node); + while (child != 0) { + scan_dt_build_struct(child, mem_start, mem_end); + child = call_prom("peer", 1, 1, child); + } + + dt_push_token(OF_DT_END_NODE, mem_start, mem_end); +} + +static void __init flatten_device_tree(void) +{ + phandle root; + unsigned long mem_start, mem_end, room; + struct boot_param_header *hdr; + struct prom_t *_prom = &RELOC(prom); + char *namep; + u64 *rsvmap; + + /* + * Check how much room we have between alloc top & bottom (+/- a + * few pages), crop to 4Mb, as this is our "chuck" size + */ + room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000; + if (room > DEVTREE_CHUNK_SIZE) + room = DEVTREE_CHUNK_SIZE; + prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom)); + + /* Now try to claim that */ + mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); + if (mem_start == 0) + prom_panic("Can't allocate initial device-tree chunk\n"); + mem_end = RELOC(alloc_top); + + /* Get root of tree */ + root = call_prom("peer", 1, 1, (phandle)0); + if (root == (phandle)0) + prom_panic ("couldn't get device tree root\n"); + + /* Build header and make room for mem rsv map */ + mem_start = _ALIGN(mem_start, 4); + hdr = make_room(&mem_start, &mem_end, + sizeof(struct boot_param_header), 4); + RELOC(dt_header_start) = (unsigned long)hdr; + rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8); + + /* Start of strings */ + mem_start = PAGE_ALIGN(mem_start); + RELOC(dt_string_start) = mem_start; + mem_start += 4; /* hole */ + + /* Add "linux,phandle" in there, we'll need it */ + namep = make_room(&mem_start, &mem_end, 16, 1); + strcpy(namep, RELOC("linux,phandle")); + mem_start = (unsigned long)namep + strlen(namep) + 1; + + /* Build string array */ + prom_printf("Building dt strings...\n"); + scan_dt_build_strings(root, &mem_start, &mem_end); + RELOC(dt_string_end) = mem_start; + + /* Build structure */ + mem_start = PAGE_ALIGN(mem_start); + RELOC(dt_struct_start) = mem_start; + prom_printf("Building dt structure...\n"); + scan_dt_build_struct(root, &mem_start, &mem_end); + dt_push_token(OF_DT_END, &mem_start, &mem_end); + RELOC(dt_struct_end) = PAGE_ALIGN(mem_start); + + /* Finish header */ + hdr->boot_cpuid_phys = _prom->cpu; + hdr->magic = OF_DT_HEADER; + hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start); + hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start); + hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start); + hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start); + hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start); + hdr->version = OF_DT_VERSION; + /* Version 16 is not backward compatible */ + hdr->last_comp_version = 0x10; + + /* Reserve the whole thing and copy the reserve map in, we + * also bump mem_reserve_cnt to cause further reservations to + * fail since it's too late. + */ + reserve_mem(RELOC(dt_header_start), hdr->totalsize); + memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map)); + +#ifdef DEBUG_PROM + { + int i; + prom_printf("reserved memory map:\n"); + for (i = 0; i < RELOC(mem_reserve_cnt); i++) + prom_printf(" %x - %x\n", + RELOC(mem_reserve_map)[i].base, + RELOC(mem_reserve_map)[i].size); + } +#endif + RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE; + + prom_printf("Device tree strings 0x%x -> 0x%x\n", + RELOC(dt_string_start), RELOC(dt_string_end)); + prom_printf("Device tree struct 0x%x -> 0x%x\n", + RELOC(dt_struct_start), RELOC(dt_struct_end)); + +} + + +static void __init fixup_device_tree(void) +{ +#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) + phandle u3, i2c, mpic; + u32 u3_rev; + u32 interrupts[2]; + u32 parent; + + /* Some G5s have a missing interrupt definition, fix it up here */ + u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); + if (!PHANDLE_VALID(u3)) + return; + i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); + if (!PHANDLE_VALID(i2c)) + return; + mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); + if (!PHANDLE_VALID(mpic)) + return; + + /* check if proper rev of u3 */ + if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) + == PROM_ERROR) + return; + if (u3_rev != 0x35 && u3_rev != 0x37) + return; + /* does it need fixup ? */ + if (prom_getproplen(i2c, "interrupts") > 0) + return; + + prom_printf("fixing up bogus interrupts for u3 i2c...\n"); + + /* interrupt on this revision of u3 is number 0 and level */ + interrupts[0] = 0; + interrupts[1] = 1; + prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); + parent = (u32)mpic; + prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); +#endif +} + + +static void __init prom_find_boot_cpu(void) +{ + struct prom_t *_prom = &RELOC(prom); + u32 getprop_rval; + ihandle prom_cpu; + phandle cpu_pkg; + + if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0) + prom_panic("cannot find boot cpu"); + + cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); + + prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); + _prom->cpu = getprop_rval; + + prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); +} + +static void __init prom_check_initrd(unsigned long r3, unsigned long r4) +{ +#ifdef CONFIG_BLK_DEV_INITRD + struct prom_t *_prom = &RELOC(prom); + + if (r3 && r4 && r4 != 0xdeadbeef) { + unsigned long val; + + RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; + RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; + + val = RELOC(prom_initrd_start); + prom_setprop(_prom->chosen, "linux,initrd-start", &val, + sizeof(val)); + val = RELOC(prom_initrd_end); + prom_setprop(_prom->chosen, "linux,initrd-end", &val, + sizeof(val)); + + reserve_mem(RELOC(prom_initrd_start), + RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); + + prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start)); + prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end)); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +} + +/* + * We enter here early on, when the Open Firmware prom is still + * handling exceptions and the MMU hash table for us. + */ + +unsigned long __init prom_init(unsigned long r3, unsigned long r4, + unsigned long pp, + unsigned long r6, unsigned long r7) +{ + struct prom_t *_prom; + extern char _stext[]; + unsigned long hdr; + u32 getprop_rval; + +#ifdef CONFIG_PPC32 + unsigned long offset = reloc_offset(); + reloc_got2(offset); +#endif + + _prom = &RELOC(prom); + + /* + * First zero the BSS + */ + memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start); + + /* + * Init interface to Open Firmware, get some node references, + * like /chosen + */ + prom_init_client_services(pp); + + /* + * Init prom stdout device + */ + prom_init_stdout(); + + /* + * Check for an initrd + */ + prom_check_initrd(r3, r4); + + /* + * Get default machine type. At this point, we do not differentiate + * between pSeries SMP and pSeries LPAR + */ + RELOC(of_platform) = prom_find_machine_type(); + getprop_rval = RELOC(of_platform); + prom_setprop(_prom->chosen, "linux,platform", + &getprop_rval, sizeof(getprop_rval)); + +#ifdef CONFIG_PPC_PSERIES + /* + * On pSeries, inform the firmware about our capabilities + */ + if (RELOC(of_platform) & PLATFORM_PSERIES) + prom_send_capabilities(); +#endif + +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_BPA) + /* + * On pSeries and BPA, copy the CPU hold code + */ + if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) + copy_and_flush(0, KERNELBASE - offset, 0x100, 0); +#endif + + /* + * Do early parsing of command line + */ + early_cmdline_parse(); + + /* + * Initialize memory management within prom_init + */ + prom_init_mem(); + + /* + * Determine which cpu is actually running right _now_ + */ + prom_find_boot_cpu(); + + /* + * Initialize display devices + */ + prom_check_displays(); + +#ifdef CONFIG_PPC64 + /* + * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else + * that uses the allocator, we need to make sure we get the top of memory + * available for us here... + */ + if (RELOC(of_platform) == PLATFORM_PSERIES) + prom_initialize_tce_table(); +#endif + + /* + * On non-powermacs, try to instantiate RTAS and puts all CPUs + * in spin-loops. PowerMacs don't have a working RTAS and use + * a different way to spin CPUs + */ + if (RELOC(of_platform) != PLATFORM_POWERMAC) { + prom_instantiate_rtas(); + prom_hold_cpus(); + } + + /* + * Fill in some infos for use by the kernel later on + */ + if (RELOC(prom_memory_limit)) + prom_setprop(_prom->chosen, "linux,memory-limit", + &RELOC(prom_memory_limit), + sizeof(prom_memory_limit)); +#ifdef CONFIG_PPC64 + if (RELOC(ppc64_iommu_off)) + prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0); + + if (RELOC(iommu_force_on)) + prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0); + + if (RELOC(prom_tce_alloc_start)) { + prom_setprop(_prom->chosen, "linux,tce-alloc-start", + &RELOC(prom_tce_alloc_start), + sizeof(prom_tce_alloc_start)); + prom_setprop(_prom->chosen, "linux,tce-alloc-end", + &RELOC(prom_tce_alloc_end), + sizeof(prom_tce_alloc_end)); + } +#endif + + /* + * Fixup any known bugs in the device-tree + */ + fixup_device_tree(); + + /* + * Now finally create the flattened device-tree + */ + prom_printf("copying OF device tree ...\n"); + flatten_device_tree(); + + /* in case stdin is USB and still active on IBM machines... */ + prom_close_stdin(); + + /* + * Call OF "quiesce" method to shut down pending DMA's from + * devices etc... + */ + prom_printf("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); + + /* + * And finally, call the kernel passing it the flattened device + * tree and NULL as r5, thus triggering the new entry point which + * is common to us and kexec + */ + hdr = RELOC(dt_header_start); + prom_printf("returning from prom_init\n"); + prom_debug("->dt_header_start=0x%x\n", hdr); + +#ifdef CONFIG_PPC32 + reloc_got2(-offset); +#endif + + __start(hdr, 0, 0); + + return 0; +} diff --git a/arch/powerpc/kernel/setup.c b/arch/powerpc/kernel/setup.c new file mode 100644 index 000000000000..27d7f828212b --- /dev/null +++ b/arch/powerpc/kernel/setup.c @@ -0,0 +1,678 @@ +/* + * Common prep/pmac/chrp boot and setup code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ + defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ + defined(CONFIG_PPC_MPC52xx)) + +#if USES_PPC_SYS +#include +#endif + +#if defined CONFIG_KGDB +#include +#endif + +extern void platform_init(void); +extern void bootx_init(unsigned long r4, unsigned long phys); + +extern void ppc6xx_idle(void); +extern void power4_idle(void); + +boot_infos_t *boot_infos; +struct ide_machdep_calls ppc_ide_md; + +/* Used with the BI_MEMSIZE bootinfo parameter to store the memory + size value reported by the boot loader. */ +unsigned long boot_mem_size; + +unsigned long ISA_DMA_THRESHOLD; +unsigned int DMA_MODE_READ; +unsigned int DMA_MODE_WRITE; + +#ifdef CONFIG_PPC_MULTIPLATFORM +int _machine = 0; + +extern void prep_init(void); +extern void pmac_init(void); +extern void chrp_init(void); + +dev_t boot_dev; +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY = 0x54; +#endif /* CONFIG_MAGIC_SYSRQ */ + +#ifdef CONFIG_VGA_CONSOLE +unsigned long vgacon_remap_base; +#endif + +struct machdep_calls ppc_md; + +/* + * These are used in binfmt_elf.c to put aux entries on the stack + * for each elf executable being started. + */ +int dcache_bsize; +int icache_bsize; +int ucache_bsize; + +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ + defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) +struct screen_info screen_info = { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0,0,0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + 1, /* orig-video-isVGA */ + 16 /* orig-video-points */ +}; +#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ + +void machine_restart(char *cmd) +{ +#ifdef CONFIG_NVRAM + nvram_sync(); +#endif + ppc_md.restart(cmd); +} + +void machine_power_off(void) +{ +#ifdef CONFIG_NVRAM + nvram_sync(); +#endif + ppc_md.power_off(); +} + +void machine_halt(void) +{ +#ifdef CONFIG_NVRAM + nvram_sync(); +#endif + ppc_md.halt(); +} + +void (*pm_power_off)(void) = machine_power_off; + +#ifdef CONFIG_TAU +extern u32 cpu_temp(unsigned long cpu); +extern u32 cpu_temp_both(unsigned long cpu); +#endif /* CONFIG_TAU */ + +int show_cpuinfo(struct seq_file *m, void *v) +{ + int i = (int) v - 1; + int err = 0; + unsigned int pvr; + unsigned short maj, min; + unsigned long lpj; + + if (i >= NR_CPUS) { + /* Show summary information */ +#ifdef CONFIG_SMP + unsigned long bogosum = 0; + for (i = 0; i < NR_CPUS; ++i) + if (cpu_online(i)) + bogosum += cpu_data[i].loops_per_jiffy; + seq_printf(m, "total bogomips\t: %lu.%02lu\n", + bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); +#endif /* CONFIG_SMP */ + + if (ppc_md.show_cpuinfo != NULL) + err = ppc_md.show_cpuinfo(m); + return err; + } + +#ifdef CONFIG_SMP + if (!cpu_online(i)) + return 0; + pvr = cpu_data[i].pvr; + lpj = cpu_data[i].loops_per_jiffy; +#else + pvr = mfspr(SPRN_PVR); + lpj = loops_per_jiffy; +#endif + + seq_printf(m, "processor\t: %d\n", i); + seq_printf(m, "cpu\t\t: "); + + if (cur_cpu_spec->pvr_mask) + seq_printf(m, "%s", cur_cpu_spec->cpu_name); + else + seq_printf(m, "unknown (%08x)", pvr); +#ifdef CONFIG_ALTIVEC + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + seq_printf(m, ", altivec supported"); +#endif + seq_printf(m, "\n"); + +#ifdef CONFIG_TAU + if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { +#ifdef CONFIG_TAU_AVERAGE + /* more straightforward, but potentially misleading */ + seq_printf(m, "temperature \t: %u C (uncalibrated)\n", + cpu_temp(i)); +#else + /* show the actual temp sensor range */ + u32 temp; + temp = cpu_temp_both(i); + seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", + temp & 0xff, temp >> 16); +#endif + } +#endif /* CONFIG_TAU */ + + if (ppc_md.show_percpuinfo != NULL) { + err = ppc_md.show_percpuinfo(m, i); + if (err) + return err; + } + + /* If we are a Freescale core do a simple check so + * we dont have to keep adding cases in the future */ + if ((PVR_VER(pvr) & 0x8000) == 0x8000) { + maj = PVR_MAJ(pvr); + min = PVR_MIN(pvr); + } else { + switch (PVR_VER(pvr)) { + case 0x0020: /* 403 family */ + maj = PVR_MAJ(pvr) + 1; + min = PVR_MIN(pvr); + break; + case 0x1008: /* 740P/750P ?? */ + maj = ((pvr >> 8) & 0xFF) - 1; + min = pvr & 0xFF; + break; + default: + maj = (pvr >> 8) & 0xFF; + min = pvr & 0xFF; + break; + } + } + + seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", + maj, min, PVR_VER(pvr), PVR_REV(pvr)); + + seq_printf(m, "bogomips\t: %lu.%02lu\n", + lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); + +#if USES_PPC_SYS + if (cur_ppc_sys_spec->ppc_sys_name) + seq_printf(m, "chipset\t\t: %s\n", + cur_ppc_sys_spec->ppc_sys_name); +#endif + +#ifdef CONFIG_SMP + seq_printf(m, "\n"); +#endif + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + int i = *pos; + + return i <= NR_CPUS? (void *) (i + 1): NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start =c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; + +/* + * We're called here very early in the boot. We determine the machine + * type and call the appropriate low-level setup functions. + * -- Cort + * + * Note that the kernel may be running at an address which is different + * from the address that it was linked at, so we must use RELOC/PTRRELOC + * to access static data (including strings). -- paulus + */ +unsigned long __init early_init(unsigned long dt_ptr) +{ + unsigned long offset = reloc_offset(); + + reloc_got2(offset); + + /* + * Identify the CPU type and fix up code sections + * that depend on which cpu we have. + */ + identify_cpu(offset, 0); + do_cpu_ftr_fixups(offset); + +#ifdef CONFIG_BOOTX_TEXT + btext_prepare_BAT(); +#endif + + reloc_got2(-offset); + + return KERNELBASE + offset; +} + +#ifdef CONFIG_PPC_OF +/* + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ +int +of_show_percpuinfo(struct seq_file *m, int i) +{ + struct device_node *cpu_node; + u32 *fp; + int s; + + cpu_node = find_type_devices("cpu"); + if (!cpu_node) + return 0; + for (s = 0; s < i && cpu_node->next; s++) + cpu_node = cpu_node->next; + fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); + if (fp) + seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); + return 0; +} + +void __init +intuit_machine_type(void) +{ + char *model; + struct device_node *root; + + /* ask the OF info if we're a chrp or pmac */ + root = find_path_device("/"); + if (root != 0) { + /* assume pmac unless proven to be chrp -- Cort */ + _machine = _MACH_Pmac; + model = get_property(root, "device_type", NULL); + if (model && !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { + model = get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM", 3)) + _machine = _MACH_chrp; + } + } +} +#endif + +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * The PPC_MULTIPLATFORM version of platform_init... + */ +void __init platform_init(void) +{ + /* if we didn't get any bootinfo telling us what we are... */ + if (_machine == 0) { + /* prep boot loader tells us if we're prep or not */ + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + _machine = _MACH_prep; + } + +#ifdef CONFIG_PPC_PREP + /* not much more to do here, if prep */ + if (_machine == _MACH_prep) { + prep_init(); + return; + } +#endif + +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ + + switch (_machine) { +#ifdef CONFIG_PPC_PMAC + case _MACH_Pmac: + pmac_init(); + break; +#endif +#ifdef CONFIG_PPC_CHRP + case _MACH_chrp: + chrp_init(); + break; +#endif + } +} + +#ifdef CONFIG_SERIAL_CORE_CONSOLE +extern char *of_stdout_device; + +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout; + char *name; + int offset = 0; + + if (of_stdout_device == NULL) + return -ENODEV; + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) + return -EBUSY; + + prom_stdout = find_path_device(of_stdout_device); + if (!prom_stdout) + return -ENODEV; + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) + return -ENODEV; + + if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + return -ENODEV; + } + } + } else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; + else + return -ENODEV; + return add_preferred_console("ttyS", offset, NULL); +} +console_initcall(set_preferred_console); +#endif /* CONFIG_SERIAL_CORE_CONSOLE */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +struct bi_record *find_bootinfo(void) +{ + struct bi_record *rec; + + rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20)); + if ( rec->tag != BI_FIRST ) { + /* + * This 0x10000 offset is a terrible hack but it will go away when + * we have the bootloader handle all the relocation and + * prom calls -- Cort + */ + rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); + if ( rec->tag != BI_FIRST ) + return NULL; + } + return rec; +} + +/* + * Find out what kind of machine we're on and save any data we need + * from the early boot process (devtree is copied on pmac by prom_init()). + * This is called very early on the boot process, after a minimal + * MMU environment has been set up but before MMU_init is called. + */ +void __init machine_init(unsigned long dt_ptr, unsigned long phys) +{ + early_init_devtree(__va(dt_ptr)); + +#ifdef CONFIG_CMDLINE + strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); +#endif /* CONFIG_CMDLINE */ + +#ifdef CONFIG_6xx + ppc_md.power_save = ppc6xx_idle; +#endif +#ifdef CONFIG_POWER4 + ppc_md.power_save = power4_idle; +#endif + + platform_init(); + + if (ppc_md.progress) + ppc_md.progress("id mach(): done", 0x200); +} + +#ifdef CONFIG_BOOKE_WDT +/* Checks wdt=x and wdt_period=xx command-line option */ +int __init early_parse_wdt(char *p) +{ + if (p && strncmp(p, "0", 1) != 0) + booke_wdt_enabled = 1; + + return 0; +} +early_param("wdt", early_parse_wdt); + +int __init early_parse_wdt_period (char *p) +{ + if (p) + booke_wdt_period = simple_strtoul(p, NULL, 0); + + return 0; +} +early_param("wdt_period", early_parse_wdt_period); +#endif /* CONFIG_BOOKE_WDT */ + +/* Checks "l2cr=xxxx" command-line option */ +int __init ppc_setup_l2cr(char *str) +{ + if (cpu_has_feature(CPU_FTR_L2CR)) { + unsigned long val = simple_strtoul(str, NULL, 0); + printk(KERN_INFO "l2cr set to %lx\n", val); + _set_L2CR(0); /* force invalidate by disable cache */ + _set_L2CR(val); /* and enable it */ + } + return 1; +} +__setup("l2cr=", ppc_setup_l2cr); + +#ifdef CONFIG_GENERIC_NVRAM + +/* Generic nvram hooks used by drivers/char/gen_nvram.c */ +unsigned char nvram_read_byte(int addr) +{ + if (ppc_md.nvram_read_val) + return ppc_md.nvram_read_val(addr); + return 0xff; +} +EXPORT_SYMBOL(nvram_read_byte); + +void nvram_write_byte(unsigned char val, int addr) +{ + if (ppc_md.nvram_write_val) + ppc_md.nvram_write_val(addr, val); +} +EXPORT_SYMBOL(nvram_write_byte); + +void nvram_sync(void) +{ + if (ppc_md.nvram_sync) + ppc_md.nvram_sync(); +} +EXPORT_SYMBOL(nvram_sync); + +#endif /* CONFIG_NVRAM */ + +static struct cpu cpu_devices[NR_CPUS]; + +int __init ppc_init(void) +{ + int i; + + /* clear the progress line */ + if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); + + /* register CPU devices */ + for (i = 0; i < NR_CPUS; i++) + if (cpu_possible(i)) + register_cpu(&cpu_devices[i], i, NULL); + + /* call platform init */ + if (ppc_md.init != NULL) { + ppc_md.init(); + } + return 0; +} + +arch_initcall(ppc_init); + +/* Warning, IO base is not yet inited */ +void __init setup_arch(char **cmdline_p) +{ + extern char *klimit; + extern void do_init_bootmem(void); + + /* so udelay does something sensible, assume <= 1000 bogomips */ + loops_per_jiffy = 500000000 / HZ; + +#ifdef CONFIG_BOOTX_TEXT + map_boot_text(); +#endif + + unflatten_device_tree(); + finish_device_tree(); + +#ifdef CONFIG_PPC_MULTIPLATFORM + /* This could be called "early setup arch", it must be done + * now because xmon need it + */ + if (_machine == _MACH_Pmac) + pmac_feature_init(); /* New cool way */ +#endif + +#ifdef CONFIG_XMON + xmon_map_scc(); + if (strstr(cmd_line, "xmon")) + xmon(NULL); +#endif /* CONFIG_XMON */ + if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); + +#if defined(CONFIG_KGDB) + if (ppc_md.kgdb_map_scc) + ppc_md.kgdb_map_scc(); + set_debug_traps(); + if (strstr(cmd_line, "gdb")) { + if (ppc_md.progress) + ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); + printk("kgdb breakpoint activated\n"); + breakpoint(); + } +#endif + + /* + * Set cache line size based on type of cpu as a default. + * Systems with OF can look in the properties on the cpu node(s) + * for a possibly more accurate value. + */ + if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { + dcache_bsize = cur_cpu_spec->dcache_bsize; + icache_bsize = cur_cpu_spec->icache_bsize; + ucache_bsize = 0; + } else + ucache_bsize = dcache_bsize = icache_bsize + = cur_cpu_spec->dcache_bsize; + + /* reboot on panic */ + panic_timeout = 180; + + init_mm.start_code = PAGE_OFFSET; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = (unsigned long) klimit; + + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); + *cmdline_p = cmd_line; + + parse_early_param(); + + /* set up the bootmem stuff with available memory */ + do_init_bootmem(); + if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); + +#ifdef CONFIG_PPC_OCP + /* Initialize OCP device list */ + ocp_early_init(); + if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + ppc_md.setup_arch(); + if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); + + paging_init(); + + /* this is for modules since _machine can be a define -- Cort */ + ppc_md.ppc_machine = _machine; +} diff --git a/arch/powerpc/platforms/powermac/pmac_setup.c b/arch/powerpc/platforms/powermac/pmac_setup.c index 3667e0b2b8e3..1b12bf9956cb 100644 --- a/arch/powerpc/platforms/powermac/pmac_setup.c +++ b/arch/powerpc/platforms/powermac/pmac_setup.c @@ -101,6 +101,8 @@ int ppc_override_l2cr = 0; int ppc_override_l2cr_value; int has_l2cache = 0; +int pmac_newworld = 1; + static int current_root_goodness = -1; extern int pmac_newworld; @@ -355,8 +357,8 @@ static void __init ohare_init(void) } } -extern char *bootpath; -extern char *bootdevice; +char *bootpath; +char *bootdevice; void *boot_host; int boot_target; int boot_part; @@ -391,6 +393,7 @@ note_scsi_host(struct device_node *node, void *host) } } } +EXPORT_SYMBOL(note_scsi_host); #endif #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) @@ -565,9 +568,7 @@ pmac_halt(void) pmac_power_off(); } -void __init -pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) +void __init pmac_init(void) { /* isa_io_base gets set in pmac_find_bridges */ isa_mem_base = PMAC_ISA_MEM_BASE; diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 1e50efab091d..a4a50d08d384 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -57,6 +57,9 @@ struct cpu_spec { extern struct cpu_spec *cur_cpu_spec; +extern void identify_cpu(unsigned long offset, unsigned long cpu); +extern void do_cpu_ftr_fixups(unsigned long offset); + #endif /* __ASSEMBLY__ */ /* CPU kernel features */ diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h new file mode 100644 index 000000000000..d096faf4191e --- /dev/null +++ b/include/asm-powerpc/iommu.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation + * Rewrite, cleanup: + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_IOMMU_H +#define _ASM_IOMMU_H + +#include +#include +#include +#include + +/* + * IOMAP_MAX_ORDER defines the largest contiguous block + * of dma space we can get. IOMAP_MAX_ORDER = 13 + * allows up to 2**12 pages (4096 * 4096) = 16 MB + */ +#define IOMAP_MAX_ORDER 13 + +struct iommu_table { + unsigned long it_busno; /* Bus number this table belongs to */ + unsigned long it_size; /* Size of iommu table in entries */ + unsigned long it_offset; /* Offset into global table */ + unsigned long it_base; /* mapped address of tce table */ + unsigned long it_index; /* which iommu table this is */ + unsigned long it_type; /* type: PCI or Virtual Bus */ + unsigned long it_blocksize; /* Entries in each block (cacheline) */ + unsigned long it_hint; /* Hint for next alloc */ + unsigned long it_largehint; /* Hint for large allocs */ + unsigned long it_halfpoint; /* Breaking point for small/large allocs */ + spinlock_t it_lock; /* Protects it_map */ + unsigned long *it_map; /* A simple allocation bitmap for now */ +}; + +struct scatterlist; +struct device_node; + +#ifdef CONFIG_PPC_MULTIPLATFORM + +/* Walks all buses and creates iommu tables */ +extern void iommu_setup_pSeries(void); +extern void iommu_setup_u3(void); + +/* Frees table for an individual device node */ +extern void iommu_free_table(struct device_node *dn); + +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_PPC_PSERIES + +/* Creates table for an individual device node */ +extern void iommu_devnode_init_pSeries(struct device_node *dn); + +#endif /* CONFIG_PPC_PSERIES */ + +#ifdef CONFIG_PPC_ISERIES + +/* Creates table for an individual device node */ +extern void iommu_devnode_init_iSeries(struct device_node *dn); + +#endif /* CONFIG_PPC_ISERIES */ + +/* Initializes an iommu_table based in values set in the passed-in + * structure + */ +extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); + +extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, + struct scatterlist *sglist, int nelems, + enum dma_data_direction direction); +extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction); + +extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, + dma_addr_t *dma_handle, unsigned int __nocast flag); +extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, + void *vaddr, dma_addr_t dma_handle); +extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, + size_t size, enum dma_data_direction direction); +extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction); + +extern void iommu_init_early_pSeries(void); +extern void iommu_init_early_iSeries(void); +extern void iommu_init_early_u3(void); + +#ifdef CONFIG_PCI +extern void pci_iommu_init(void); +extern void pci_direct_iommu_init(void); +#else +static inline void pci_iommu_init(void) { } +#endif + +extern void alloc_u3_dart_table(void); + +#endif /* _ASM_IOMMU_H */ diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h new file mode 100644 index 000000000000..ea0afe343545 --- /dev/null +++ b/include/asm-powerpc/lmb.h @@ -0,0 +1,81 @@ +#ifndef _PPC64_LMB_H +#define _PPC64_LMB_H + +/* + * Definitions for talking to the Open Firmware PROM on + * Power Macintosh computers. + * + * Copyright (C) 2001 Peter Bergner, IBM Corp. + * + * 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. + */ + +#include +#include + +#define MAX_LMB_REGIONS 128 + +#define LMB_ALLOC_ANYWHERE 0 + +struct lmb_property { + unsigned long base; + unsigned long size; +}; + +struct lmb_region { + unsigned long cnt; + unsigned long size; + struct lmb_property region[MAX_LMB_REGIONS+1]; +}; + +struct lmb { + unsigned long debug; + unsigned long rmo_size; + struct lmb_region memory; + struct lmb_region reserved; +}; + +extern struct lmb lmb; + +extern void __init lmb_init(void); +extern void __init lmb_analyze(void); +extern long __init lmb_add(unsigned long, unsigned long); +extern long __init lmb_reserve(unsigned long, unsigned long); +extern unsigned long __init lmb_alloc(unsigned long, unsigned long); +extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long, + unsigned long); +extern unsigned long __init lmb_phys_mem_size(void); +extern unsigned long __init lmb_end_of_DRAM(void); +extern unsigned long __init lmb_abs_to_phys(unsigned long); +extern void __init lmb_enforce_memory_limit(unsigned long); + +extern void lmb_dump_all(void); + +extern unsigned long io_hole_start; + +static inline unsigned long +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].size; +} +static inline unsigned long +lmb_size_pages(struct lmb_region *type, unsigned long region_nr) +{ + return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT; +} +static inline unsigned long +lmb_start_pfn(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].base >> PAGE_SHIFT; +} +static inline unsigned long +lmb_end_pfn(struct lmb_region *type, unsigned long region_nr) +{ + return lmb_start_pfn(type, region_nr) + + lmb_size_pages(type, region_nr); +} + +#endif /* _PPC64_LMB_H */ diff --git a/include/asm-powerpc/pSeries_reconfig.h b/include/asm-powerpc/pSeries_reconfig.h new file mode 100644 index 000000000000..c0db1ea7f7d1 --- /dev/null +++ b/include/asm-powerpc/pSeries_reconfig.h @@ -0,0 +1,25 @@ +#ifndef _PPC64_PSERIES_RECONFIG_H +#define _PPC64_PSERIES_RECONFIG_H + +#include + +/* + * Use this API if your code needs to know about OF device nodes being + * added or removed on pSeries systems. + */ + +#define PSERIES_RECONFIG_ADD 0x0001 +#define PSERIES_RECONFIG_REMOVE 0x0002 + +#ifdef CONFIG_PPC_PSERIES +extern int pSeries_reconfig_notifier_register(struct notifier_block *); +extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); +#else /* !CONFIG_PPC_PSERIES */ +static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) +{ + return 0; +} +static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } +#endif /* CONFIG_PPC_PSERIES */ + +#endif /* _PPC64_PSERIES_RECONFIG_H */ diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h new file mode 100644 index 000000000000..194b56ee1693 --- /dev/null +++ b/include/asm-powerpc/prom.h @@ -0,0 +1,215 @@ +#ifndef _POWERPC_PROM_H +#define _POWERPC_PROM_H +#ifdef __KERNEL__ + +/* + * Definitions for talking to the Open Firmware PROM on + * Power Macintosh computers. + * + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. + * + * 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. + */ +#include +#include +#include + +/* Definitions used by the flattened device tree */ +#define OF_DT_HEADER 0xd00dfeed /* marker */ +#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ +#define OF_DT_END_NODE 0x2 /* End node */ +#define OF_DT_PROP 0x3 /* Property: name off, size, + * content */ +#define OF_DT_NOP 0x4 /* nop */ +#define OF_DT_END 0x9 + +#define OF_DT_VERSION 0x10 + +/* + * This is what gets passed to the kernel by prom_init or kexec + * + * The dt struct contains the device tree structure, full pathes and + * property contents. The dt strings contain a separate block with just + * the strings for the property names, and is fully page aligned and + * self contained in a page, so that it can be kept around by the kernel, + * each property name appears only once in this page (cheap compression) + * + * the mem_rsvmap contains a map of reserved ranges of physical memory, + * passing it here instead of in the device-tree itself greatly simplifies + * the job of everybody. It's just a list of u64 pairs (base/size) that + * ends when size is 0 + */ +struct boot_param_header +{ + u32 magic; /* magic word OF_DT_HEADER */ + u32 totalsize; /* total size of DT block */ + u32 off_dt_struct; /* offset to structure */ + u32 off_dt_strings; /* offset to strings */ + u32 off_mem_rsvmap; /* offset to memory reserve map */ + u32 version; /* format version */ + u32 last_comp_version; /* last compatible version */ + /* version 2 fields below */ + u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ + /* version 3 fields below */ + u32 dt_strings_size; /* size of the DT strings block */ +}; + + + +typedef u32 phandle; +typedef u32 ihandle; + +struct address_range { + unsigned long space; + unsigned long address; + unsigned long size; +}; + +struct interrupt_info { + int line; + int sense; /* +ve/-ve logic, edge or level, etc. */ +}; + +struct pci_address { + u32 a_hi; + u32 a_mid; + u32 a_lo; +}; + +struct isa_address { + u32 a_hi; + u32 a_lo; +}; + +struct isa_range { + struct isa_address isa_addr; + struct pci_address pci_addr; + unsigned int size; +}; + +struct reg_property { + unsigned long address; + unsigned long size; +}; + +struct reg_property32 { + unsigned int address; + unsigned int size; +}; + +struct reg_property64 { + unsigned long address; + unsigned long size; +}; + +struct property { + char *name; + int length; + unsigned char *value; + struct property *next; +}; + +struct device_node { + char *name; + char *type; + phandle node; + phandle linux_phandle; + int n_addrs; + struct address_range *addrs; + int n_intrs; + struct interrupt_info *intrs; + char *full_name; + + struct property *properties; + struct device_node *parent; + struct device_node *child; + struct device_node *sibling; + struct device_node *next; /* next device of same type */ + struct device_node *allnext; /* next in list of all nodes */ + struct proc_dir_entry *pde; /* this node's proc directory */ + struct kref kref; + unsigned long _flags; + void *data; +}; + +extern struct device_node *of_chosen; + +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ + +#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) +#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) + +#define HAVE_ARCH_DEVTREE_FIXUPS + +static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) +{ + dn->pde = de; +} + + +/* OBSOLETE: Old style node lookup */ +extern struct device_node *find_devices(const char *name); +extern struct device_node *find_type_devices(const char *type); +extern struct device_node *find_path_device(const char *path); +extern struct device_node *find_compatible_devices(const char *type, + const char *compat); +extern struct device_node *find_all_nodes(void); + +/* New style node lookup */ +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_node_by_phandle(phandle handle); +extern struct device_node *of_find_all_nodes(struct device_node *prev); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct device_node *of_node_get(struct device_node *node); +extern void of_node_put(struct device_node *node); + +/* For updating the device tree at runtime */ +extern void of_attach_node(struct device_node *); +extern void of_detach_node(const struct device_node *); + +/* Other Prototypes */ +extern void finish_device_tree(void); +extern void unflatten_device_tree(void); +extern void early_init_devtree(void *); +extern int device_is_compatible(struct device_node *device, const char *); +extern int machine_is_compatible(const char *compat); +extern unsigned char *get_property(struct device_node *node, const char *name, + int *lenp); +extern void print_properties(struct device_node *node); +extern int prom_n_addr_cells(struct device_node* np); +extern int prom_n_size_cells(struct device_node* np); +extern int prom_n_intr_cells(struct device_node* np); +extern void prom_get_irq_senses(unsigned char *senses, int off, int max); +extern void prom_add_property(struct device_node* np, struct property* prop); + +/* + * PCI <-> OF matching functions + * (XXX should these be here?) + */ +struct pci_bus; +struct pci_dev; +extern int pci_device_from_OF_node(struct device_node *node, + u8* bus, u8* devfn); +extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int); +extern struct device_node* pci_device_to_OF_node(struct pci_dev *); +extern void pci_create_OF_bus_map(void); +extern struct resource *request_OF_resource(struct device_node* node, + int index, const char* name_postfix); +extern int release_OF_resource(struct device_node* node, int index); + +#endif /* __KERNEL__ */ +#endif /* _POWERPC_PROM_H */ diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h new file mode 100644 index 000000000000..5c904d371963 --- /dev/null +++ b/include/asm-powerpc/rtas.h @@ -0,0 +1,249 @@ +#ifndef _POWERPC_RTAS_H +#define _POWERPC_RTAS_H + +#include +#include + +/* + * Definitions for talking to the RTAS on CHRP machines. + * + * Copyright (C) 2001 Peter Bergner + * Copyright (C) 2001 PPC 64 Team, IBM Corp + * + * 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. + */ + +#define RTAS_UNKNOWN_SERVICE (-1) +#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ + +/* Buffer size for ppc_rtas system call. */ +#define RTAS_RMOBUF_MAX (64 * 1024) + +/* RTAS return status codes */ +#define RTAS_BUSY -2 /* RTAS Busy */ +#define RTAS_EXTENDED_DELAY_MIN 9900 +#define RTAS_EXTENDED_DELAY_MAX 9905 + +/* + * In general to call RTAS use rtas_token("string") to lookup + * an RTAS token for the given string (e.g. "event-scan"). + * To actually perform the call use + * ret = rtas_call(token, n_in, n_out, ...) + * Where n_in is the number of input parameters and + * n_out is the number of output parameters + * + * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE + * will be returned as a token. rtas_call() does look for this + * token and error out gracefully so rtas_call(rtas_token("str"), ...) + * may be safely used for one-shot calls to RTAS. + * + */ + +typedef u32 rtas_arg_t; + +struct rtas_args { + u32 token; + u32 nargs; + u32 nret; + rtas_arg_t args[16]; + rtas_arg_t *rets; /* Pointer to return values in args[]. */ +}; + +extern struct rtas_args rtas_stop_self_args; + +struct rtas_t { + unsigned long entry; /* physical address pointer */ + unsigned long base; /* physical address pointer */ + unsigned long size; + spinlock_t lock; + struct rtas_args args; + struct device_node *dev; /* virtual address pointer */ +}; + +/* RTAS event classes */ +#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ +#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ +#define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */ +#define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */ +#define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000 + +/* RTAS event severity */ +#define RTAS_SEVERITY_FATAL 0x5 +#define RTAS_SEVERITY_ERROR 0x4 +#define RTAS_SEVERITY_ERROR_SYNC 0x3 +#define RTAS_SEVERITY_WARNING 0x2 +#define RTAS_SEVERITY_EVENT 0x1 +#define RTAS_SEVERITY_NO_ERROR 0x0 + +/* RTAS event disposition */ +#define RTAS_DISP_FULLY_RECOVERED 0x0 +#define RTAS_DISP_LIMITED_RECOVERY 0x1 +#define RTAS_DISP_NOT_RECOVERED 0x2 + +/* RTAS event initiator */ +#define RTAS_INITIATOR_UNKNOWN 0x0 +#define RTAS_INITIATOR_CPU 0x1 +#define RTAS_INITIATOR_PCI 0x2 +#define RTAS_INITIATOR_ISA 0x3 +#define RTAS_INITIATOR_MEMORY 0x4 +#define RTAS_INITIATOR_POWERMGM 0x5 + +/* RTAS event target */ +#define RTAS_TARGET_UNKNOWN 0x0 +#define RTAS_TARGET_CPU 0x1 +#define RTAS_TARGET_PCI 0x2 +#define RTAS_TARGET_ISA 0x3 +#define RTAS_TARGET_MEMORY 0x4 +#define RTAS_TARGET_POWERMGM 0x5 + +/* RTAS event type */ +#define RTAS_TYPE_RETRY 0x01 +#define RTAS_TYPE_TCE_ERR 0x02 +#define RTAS_TYPE_INTERN_DEV_FAIL 0x03 +#define RTAS_TYPE_TIMEOUT 0x04 +#define RTAS_TYPE_DATA_PARITY 0x05 +#define RTAS_TYPE_ADDR_PARITY 0x06 +#define RTAS_TYPE_CACHE_PARITY 0x07 +#define RTAS_TYPE_ADDR_INVALID 0x08 +#define RTAS_TYPE_ECC_UNCORR 0x09 +#define RTAS_TYPE_ECC_CORR 0x0a +#define RTAS_TYPE_EPOW 0x40 +#define RTAS_TYPE_PLATFORM 0xE0 +#define RTAS_TYPE_IO 0xE1 +#define RTAS_TYPE_INFO 0xE2 +#define RTAS_TYPE_DEALLOC 0xE3 +#define RTAS_TYPE_DUMP 0xE4 +/* I don't add PowerMGM events right now, this is a different topic */ +#define RTAS_TYPE_PMGM_POWER_SW_ON 0x60 +#define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61 +#define RTAS_TYPE_PMGM_LID_OPEN 0x62 +#define RTAS_TYPE_PMGM_LID_CLOSE 0x63 +#define RTAS_TYPE_PMGM_SLEEP_BTN 0x64 +#define RTAS_TYPE_PMGM_WAKE_BTN 0x65 +#define RTAS_TYPE_PMGM_BATTERY_WARN 0x66 +#define RTAS_TYPE_PMGM_BATTERY_CRIT 0x67 +#define RTAS_TYPE_PMGM_SWITCH_TO_BAT 0x68 +#define RTAS_TYPE_PMGM_SWITCH_TO_AC 0x69 +#define RTAS_TYPE_PMGM_KBD_OR_MOUSE 0x6a +#define RTAS_TYPE_PMGM_ENCLOS_OPEN 0x6b +#define RTAS_TYPE_PMGM_ENCLOS_CLOSED 0x6c +#define RTAS_TYPE_PMGM_RING_INDICATE 0x6d +#define RTAS_TYPE_PMGM_LAN_ATTENTION 0x6e +#define RTAS_TYPE_PMGM_TIME_ALARM 0x6f +#define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 +#define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 + +struct rtas_error_log { + unsigned long version:8; /* Architectural version */ + unsigned long severity:3; /* Severity level of error */ + unsigned long disposition:2; /* Degree of recovery */ + unsigned long extended:1; /* extended log present? */ + unsigned long /* reserved */ :2; /* Reserved for future use */ + unsigned long initiator:4; /* Initiator of event */ + unsigned long target:4; /* Target of failed operation */ + unsigned long type:8; /* General event or error*/ + unsigned long extended_log_length:32; /* length in bytes */ + unsigned char buffer[1]; +}; + +struct flash_block { + char *data; + unsigned long length; +}; + +/* This struct is very similar but not identical to + * that needed by the rtas flash update. + * All we need to do for rtas is rewrite num_blocks + * into a version/length and translate the pointers + * to absolute. + */ +#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) +struct flash_block_list { + unsigned long num_blocks; + struct flash_block_list *next; + struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; +}; +struct flash_block_list_header { /* just the header of flash_block_list */ + unsigned long num_blocks; + struct flash_block_list *next; +}; +extern struct flash_block_list_header rtas_firmware_flash_list; + +extern struct rtas_t rtas; + +extern void enter_rtas(unsigned long); +extern int rtas_token(const char *service); +extern int rtas_call(int token, int, int, int *, ...); +extern void call_rtas_display_status(unsigned char); +extern void rtas_restart(char *cmd); +extern void rtas_power_off(void); +extern void rtas_halt(void); +extern void rtas_os_term(char *str); +extern int rtas_get_sensor(int sensor, int index, int *state); +extern int rtas_get_power_level(int powerdomain, int *level); +extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); +extern int rtas_set_indicator(int indicator, int index, int new_value); +extern void rtas_progress(char *s, unsigned short hex); +extern void rtas_initialize(void); + +struct rtc_time; +extern void rtas_get_boot_time(struct rtc_time *rtc_time); +extern void rtas_get_rtc_time(struct rtc_time *rtc_time); +extern int rtas_set_rtc_time(struct rtc_time *rtc_time); + +/* Given an RTAS status code of 9900..9905 compute the hinted delay */ +unsigned int rtas_extended_busy_delay_time(int status); +static inline int rtas_is_extended_busy(int status) +{ + return status >= 9900 && status <= 9909; +} + +extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); + +/* Error types logged. */ +#define ERR_FLAG_ALREADY_LOGGED 0x0 +#define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ +#define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ +#define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ + +/* All the types and not flags */ +#define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) + +#define RTAS_DEBUG KERN_DEBUG "RTAS: " + +#define RTAS_ERROR_LOG_MAX 2048 + +/* + * Return the firmware-specified size of the error log buffer + * for all rtas calls that require an error buffer argument. + * This includes 'check-exception' and 'rtas-last-error'. + */ +extern int rtas_get_error_log_max(void); + +/* Event Scan Parameters */ +#define EVENT_SCAN_ALL_EVENTS 0xf0000000 +#define SURVEILLANCE_TOKEN 9000 +#define LOG_NUMBER 64 /* must be a power of two */ +#define LOG_NUMBER_MASK (LOG_NUMBER-1) + +/* Some RTAS ops require a data buffer and that buffer must be < 4G. + * Rather than having a memory allocator, just use this buffer + * (get the lock first), make the RTAS call. Copy the data instead + * of holding the buffer for long. + */ + +#define RTAS_DATA_BUF_SIZE 4096 +extern spinlock_t rtas_data_buf_lock; +extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; + +extern void rtas_stop_self(void); + +/* RMO buffer reserved for user-space RTAS use */ +extern unsigned long rtas_rmo_buf; + +#define GLOBAL_INTERRUPT_QUEUE 9005 + +#endif /* _POWERPC_RTAS_H */ diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 027479dcbf43..66866f7301a9 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -346,7 +346,12 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, #define arch_align_stack(x) (x) +/* Used in very early kernel initialization. */ extern unsigned long reloc_offset(void); +extern unsigned long add_reloc_offset(unsigned long); +extern void reloc_got2(unsigned long); + +#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_SYSTEM_H */ From 7c8c6b9776fb41134d87ef50706a777a45d61cd4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 12:23:33 +1000 Subject: [PATCH 0215/1940] powerpc: Merge lmb.c and make MM initialization use it. This also creates merged versions of do_init_bootmem, paging_init and mem_init and moves them to arch/powerpc/mm/mem.c. It gets rid of the mem_pieces stuff. I made memory_limit a parameter to lmb_enforce_memory_limit rather than a global referenced by that function. This will require some small changes to ppc64 if we want to continue building ARCH=ppc64 using the merged lmb.c. Signed-off-by: Paul Mackerras --- arch/powerpc/mm/Makefile | 4 +- arch/powerpc/mm/init.c | 363 ++--------------------------------- arch/powerpc/mm/init64.c | 126 ------------ arch/powerpc/mm/lmb.c | 296 ++++++++++++++++++++++++++++ arch/powerpc/mm/mem.c | 185 +++++++++++++++++- arch/powerpc/mm/mem_pieces.c | 163 ---------------- arch/powerpc/mm/mem_pieces.h | 48 ----- arch/powerpc/mm/mmu_decl.h | 2 + arch/powerpc/mm/pgtable.c | 3 +- arch/powerpc/mm/ppc_mmu.c | 17 +- include/asm-ppc/page.h | 18 +- 11 files changed, 519 insertions(+), 706 deletions(-) create mode 100644 arch/powerpc/mm/lmb.c delete mode 100644 arch/powerpc/mm/mem_pieces.c delete mode 100644 arch/powerpc/mm/mem_pieces.h diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 9f52c26acd86..afd3be112b79 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -2,9 +2,9 @@ # Makefile for the linux ppc-specific parts of the memory manager. # -obj-y := fault.o mem.o +obj-y := fault.o mem.o lmb.o obj-$(CONFIG_PPC32) += init.o pgtable.o mmu_context.o \ - mem_pieces.o tlb.o + tlb.o obj-$(CONFIG_PPC64) += init64.o pgtable64.o mmu_context64.o obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu.o hash_32.o obj-$(CONFIG_40x) += 4xx_mmu.o diff --git a/arch/powerpc/mm/init.c b/arch/powerpc/mm/init.c index 3a81ef15c67e..bf13c14e66b3 100644 --- a/arch/powerpc/mm/init.c +++ b/arch/powerpc/mm/init.c @@ -45,8 +45,9 @@ #include #include #include +#include +#include -#include "mem_pieces.h" #include "mmu_decl.h" #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL) @@ -65,17 +66,11 @@ unsigned long total_lowmem; unsigned long ppc_memstart; unsigned long ppc_memoffset = PAGE_OFFSET; -int mem_init_done; -int init_bootmem_done; int boot_mapsize; #ifdef CONFIG_PPC_PMAC unsigned long agp_special_page; #endif -extern char _end[]; -extern char etext[], _stext[]; -extern char __init_begin, __init_end; - #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; pgprot_t kmap_prot; @@ -85,15 +80,15 @@ EXPORT_SYMBOL(kmap_pte); #endif void MMU_init(void); -void set_phys_avail(unsigned long total_ram); /* XXX should be in current.h -- paulus */ extern struct task_struct *current_set[NR_CPUS]; char *klimit = _end; -struct mem_pieces phys_avail; struct device_node *memory_node; +extern int init_bootmem_done; + /* * this tells the system to map all of ram with the segregs * (i.e. page tables) instead of the bats. @@ -102,84 +97,14 @@ struct device_node *memory_node; int __map_without_bats; int __map_without_ltlbs; -/* max amount of RAM to use */ -unsigned long __max_memory; /* max amount of low RAM to map in */ unsigned long __max_low_memory = MAX_LOW_MEM; /* - * Read in a property describing some pieces of memory. + * limit of what is accessible with initial MMU setup - + * 256MB usually, but only 16MB on 601. */ -static int __init get_mem_prop(char *name, struct mem_pieces *mp) -{ - struct reg_property *rp; - int i, s; - unsigned int *ip; - int nac = prom_n_addr_cells(memory_node); - int nsc = prom_n_size_cells(memory_node); - - ip = (unsigned int *) get_property(memory_node, name, &s); - if (ip == NULL) { - printk(KERN_ERR "error: couldn't get %s property on /memory\n", - name); - return 0; - } - s /= (nsc + nac) * 4; - rp = mp->regions; - for (i = 0; i < s; ++i, ip += nac+nsc) { - if (nac >= 2 && ip[nac-2] != 0) - continue; - rp->address = ip[nac-1]; - if (nsc >= 2 && ip[nac+nsc-2] != 0) - rp->size = ~0U; - else - rp->size = ip[nac+nsc-1]; - ++rp; - } - mp->n_regions = rp - mp->regions; - - /* Make sure the pieces are sorted. */ - mem_pieces_sort(mp); - mem_pieces_coalesce(mp); - return 1; -} - -/* - * Collect information about physical RAM and which pieces are - * already in use from the device tree. - */ -unsigned long __init find_end_of_memory(void) -{ - unsigned long a, total; - struct mem_pieces phys_mem; - - /* - * Find out where physical memory is, and check that it - * starts at 0 and is contiguous. It seems that RAM is - * always physically contiguous on Power Macintoshes. - * - * Supporting discontiguous physical memory isn't hard, - * it just makes the virtual <-> physical mapping functions - * more complicated (or else you end up wasting space - * in mem_map). - */ - memory_node = find_devices("memory"); - if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) - || phys_mem.n_regions == 0) - panic("No RAM??"); - a = phys_mem.regions[0].address; - if (a != 0) - panic("RAM doesn't start at physical address 0"); - total = phys_mem.regions[0].size; - - if (phys_mem.n_regions > 1) { - printk("RAM starting at 0x%x is not contiguous\n", - phys_mem.regions[1].address); - printk("Using RAM from 0 to 0x%lx\n", total-1); - } - - return total; -} +unsigned long __initial_memory_limit = 0x10000000; /* * Check for command-line options that affect what MMU_init will do. @@ -194,27 +119,6 @@ void MMU_setup(void) if (strstr(cmd_line, "noltlbs")) { __map_without_ltlbs = 1; } - - /* Look for mem= option on command line */ - if (strstr(cmd_line, "mem=")) { - char *p, *q; - unsigned long maxmem = 0; - - for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { - q = p + 4; - if (p > cmd_line && p[-1] != ' ') - continue; - maxmem = simple_strtoul(q, &q, 0); - if (*q == 'k' || *q == 'K') { - maxmem <<= 10; - ++q; - } else if (*q == 'm' || *q == 'M') { - maxmem <<= 20; - ++q; - } - } - __max_memory = maxmem; - } } /* @@ -227,23 +131,22 @@ void __init MMU_init(void) if (ppc_md.progress) ppc_md.progress("MMU:enter", 0x111); + /* 601 can only access 16MB at the moment */ + if (PVR_VER(mfspr(SPRN_PVR)) == 1) + __initial_memory_limit = 0x01000000; + /* parse args from command line */ MMU_setup(); - /* - * Figure out how much memory we have, how much - * is lowmem, and how much is highmem. If we were - * passed the total memory size from the bootloader, - * just use it. - */ - if (boot_mem_size) - total_memory = boot_mem_size; - else - total_memory = find_end_of_memory(); + if (lmb.memory.cnt > 1) { + lmb.memory.cnt = 1; + lmb_analyze(); + printk(KERN_WARNING "Only using first contiguous memory region"); + } - if (__max_memory && total_memory > __max_memory) - total_memory = __max_memory; + total_memory = lmb_end_of_DRAM(); total_lowmem = total_memory; + #ifdef CONFIG_FSL_BOOKE /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB * entries, so we need to adjust lowmem to match the amount we can map @@ -256,7 +159,6 @@ void __init MMU_init(void) total_memory = total_lowmem; #endif /* CONFIG_HIGHMEM */ } - set_phys_avail(total_lowmem); /* Initialize the MMU hardware */ if (ppc_md.progress) @@ -303,7 +205,8 @@ void __init *early_get_page(void) if (init_bootmem_done) { p = alloc_bootmem_pages(PAGE_SIZE); } else { - p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE); + p = __va(lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, + __initial_memory_limit)); } return p; } @@ -353,229 +256,3 @@ void free_initrd_mem(unsigned long start, unsigned long end) } } #endif - -/* - * Initialize the bootmem system and give it all the memory we - * have available. - */ -void __init do_init_bootmem(void) -{ - unsigned long start, size; - int i; - - /* - * Find an area to use for the bootmem bitmap. - * We look for the first area which is at least - * 128kB in length (128kB is enough for a bitmap - * for 4GB of memory, using 4kB pages), plus 1 page - * (in case the address isn't page-aligned). - */ - start = 0; - size = 0; - for (i = 0; i < phys_avail.n_regions; ++i) { - unsigned long a = phys_avail.regions[i].address; - unsigned long s = phys_avail.regions[i].size; - if (s <= size) - continue; - start = a; - size = s; - if (s >= 33 * PAGE_SIZE) - break; - } - start = PAGE_ALIGN(start); - - min_low_pfn = start >> PAGE_SHIFT; - max_low_pfn = (PPC_MEMSTART + total_lowmem) >> PAGE_SHIFT; - max_pfn = (PPC_MEMSTART + total_memory) >> PAGE_SHIFT; - boot_mapsize = init_bootmem_node(&contig_page_data, min_low_pfn, - PPC_MEMSTART >> PAGE_SHIFT, - max_low_pfn); - - /* remove the bootmem bitmap from the available memory */ - mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); - - /* add everything in phys_avail into the bootmem map */ - for (i = 0; i < phys_avail.n_regions; ++i) - free_bootmem(phys_avail.regions[i].address, - phys_avail.regions[i].size); - - init_bootmem_done = 1; -} - -/* - * paging_init() sets up the page tables - in fact we've already done this. - */ -void __init paging_init(void) -{ - unsigned long zones_size[MAX_NR_ZONES], i; - -#ifdef CONFIG_HIGHMEM - map_page(PKMAP_BASE, 0, 0); /* XXX gross */ - pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k - (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); - map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ - kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k - (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); - kmap_prot = PAGE_KERNEL; -#endif /* CONFIG_HIGHMEM */ - - /* - * All pages are DMA-able so we put them all in the DMA zone. - */ - zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; - for (i = 1; i < MAX_NR_ZONES; i++) - zones_size[i] = 0; - -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; -#endif /* CONFIG_HIGHMEM */ - - free_area_init(zones_size); -} - -void __init mem_init(void) -{ - unsigned long addr; - int codepages = 0; - int datapages = 0; - int initpages = 0; -#ifdef CONFIG_HIGHMEM - unsigned long highmem_mapnr; - - highmem_mapnr = total_lowmem >> PAGE_SHIFT; -#endif /* CONFIG_HIGHMEM */ - max_mapnr = total_memory >> PAGE_SHIFT; - - high_memory = (void *) __va(PPC_MEMSTART + total_lowmem); - num_physpages = max_mapnr; /* RAM is assumed contiguous */ - - totalram_pages += free_all_bootmem(); - -#ifdef CONFIG_BLK_DEV_INITRD - /* if we are booted from BootX with an initial ramdisk, - make sure the ramdisk pages aren't reserved. */ - if (initrd_start) { - for (addr = initrd_start; addr < initrd_end; addr += PAGE_SIZE) - ClearPageReserved(virt_to_page(addr)); - } -#endif /* CONFIG_BLK_DEV_INITRD */ - -#ifdef CONFIG_PPC_OF - /* mark the RTAS pages as reserved */ - if ( rtas_data ) - for (addr = (ulong)__va(rtas_data); - addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; - addr += PAGE_SIZE) - SetPageReserved(virt_to_page(addr)); -#endif -#ifdef CONFIG_PPC_PMAC - if (agp_special_page) - SetPageReserved(virt_to_page(agp_special_page)); -#endif - for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; - addr += PAGE_SIZE) { - if (!PageReserved(virt_to_page(addr))) - continue; - if (addr < (ulong) etext) - codepages++; - else if (addr >= (unsigned long)&__init_begin - && addr < (unsigned long)&__init_end) - initpages++; - else if (addr < (ulong) klimit) - datapages++; - } - -#ifdef CONFIG_HIGHMEM - { - unsigned long pfn; - - for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { - struct page *page = mem_map + pfn; - - ClearPageReserved(page); - set_page_count(page, 1); - __free_page(page); - totalhigh_pages++; - } - totalram_pages += totalhigh_pages; - } -#endif /* CONFIG_HIGHMEM */ - - printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", - (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10), - codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), - initpages<< (PAGE_SHIFT-10), - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); - -#ifdef CONFIG_PPC_PMAC - if (agp_special_page) - printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); -#endif - - mem_init_done = 1; -} - -/* - * Set phys_avail to the amount of physical memory, - * less the kernel text/data/bss. - */ -void __init -set_phys_avail(unsigned long total_memory) -{ - unsigned long kstart, ksize; - - /* - * Initially, available physical memory is equivalent to all - * physical memory. - */ - - phys_avail.regions[0].address = PPC_MEMSTART; - phys_avail.regions[0].size = total_memory; - phys_avail.n_regions = 1; - - /* - * Map out the kernel text/data/bss from the available physical - * memory. - */ - - kstart = __pa(_stext); /* should be 0 */ - ksize = PAGE_ALIGN(klimit - _stext); - - mem_pieces_remove(&phys_avail, kstart, ksize, 0); - mem_pieces_remove(&phys_avail, 0, 0x4000, 0); - -#if defined(CONFIG_BLK_DEV_INITRD) - /* Remove the init RAM disk from the available memory. */ - if (initrd_start) { - mem_pieces_remove(&phys_avail, __pa(initrd_start), - initrd_end - initrd_start, 1); - } -#endif /* CONFIG_BLK_DEV_INITRD */ -#ifdef CONFIG_PPC_OF - /* remove the RTAS pages from the available memory */ - if (rtas_data) - mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); -#endif -#ifdef CONFIG_PPC_PMAC - /* Because of some uninorth weirdness, we need a page of - * memory as high as possible (it must be outside of the - * bus address seen as the AGP aperture). It will be used - * by the r128 DRM driver - * - * FIXME: We need to make sure that page doesn't overlap any of the\ - * above. This could be done by improving mem_pieces_find to be able - * to do a backward search from the end of the list. - */ - if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) { - agp_special_page = (total_memory - PAGE_SIZE); - mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); - agp_special_page = (unsigned long)__va(agp_special_page); - } -#endif /* CONFIG_PPC_PMAC */ -} - -/* Mark some memory as reserved by removing it from phys_avail. */ -void __init reserve_phys_mem(unsigned long start, unsigned long size) -{ - mem_pieces_remove(&phys_avail, start, size, 1); -} diff --git a/arch/powerpc/mm/init64.c b/arch/powerpc/mm/init64.c index 81f6745b31ef..c0ce6a7af3c7 100644 --- a/arch/powerpc/mm/init64.c +++ b/arch/powerpc/mm/init64.c @@ -166,77 +166,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -/* - * Initialize the bootmem system and give it all the memory we - * have available. - */ -#ifndef CONFIG_NEED_MULTIPLE_NODES -void __init do_init_bootmem(void) -{ - unsigned long i; - unsigned long start, bootmap_pages; - unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; - int boot_mapsize; - - /* - * Find an area to use for the bootmem bitmap. Calculate the size of - * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. - * Add 1 additional page in case the address isn't page-aligned. - */ - bootmap_pages = bootmem_bootmap_pages(total_pages); - - start = lmb_alloc(bootmap_pages<> PAGE_SHIFT, total_pages); - - max_pfn = max_low_pfn; - - /* Add all physical memory to the bootmem map, mark each area - * present. - */ - for (i=0; i < lmb.memory.cnt; i++) - free_bootmem(lmb.memory.region[i].base, - lmb_size_bytes(&lmb.memory, i)); - - /* reserve the sections we're already using */ - for (i=0; i < lmb.reserved.cnt; i++) - reserve_bootmem(lmb.reserved.region[i].base, - lmb_size_bytes(&lmb.reserved, i)); - - for (i=0; i < lmb.memory.cnt; i++) - memory_present(0, lmb_start_pfn(&lmb.memory, i), - lmb_end_pfn(&lmb.memory, i)); -} - -/* - * paging_init() sets up the page tables - in fact we've already done this. - */ -void __init paging_init(void) -{ - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long total_ram = lmb_phys_mem_size(); - unsigned long top_of_ram = lmb_end_of_DRAM(); - - printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", - top_of_ram, total_ram); - printk(KERN_INFO "Memory hole size: %ldMB\n", - (top_of_ram - total_ram) >> 20); - /* - * All pages are DMA-able so we put them all in the DMA zone. - */ - memset(zones_size, 0, sizeof(zones_size)); - memset(zholes_size, 0, sizeof(zholes_size)); - - zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; - zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; - - free_area_init_node(0, NODE_DATA(0), zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); -} -#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ - static struct kcore_list kcore_vmem; static int __init setup_kcore(void) @@ -264,61 +193,6 @@ static int __init setup_kcore(void) } module_init(setup_kcore); -void __init mem_init(void) -{ -#ifdef CONFIG_NEED_MULTIPLE_NODES - int nid; -#endif - pg_data_t *pgdat; - unsigned long i; - struct page *page; - unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; - - num_physpages = max_low_pfn; /* RAM is assumed contiguous */ - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); - -#ifdef CONFIG_NEED_MULTIPLE_NODES - for_each_online_node(nid) { - if (NODE_DATA(nid)->node_spanned_pages != 0) { - printk("freeing bootmem node %x\n", nid); - totalram_pages += - free_all_bootmem_node(NODE_DATA(nid)); - } - } -#else - max_mapnr = num_physpages; - totalram_pages += free_all_bootmem(); -#endif - - for_each_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; i++) { - page = pgdat_page_nr(pgdat, i); - if (PageReserved(page)) - reservedpages++; - } - } - - codesize = (unsigned long)&_etext - (unsigned long)&_stext; - initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin; - datasize = (unsigned long)&_edata - (unsigned long)&__init_end; - bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start; - - printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, " - "%luk reserved, %luk data, %luk bss, %luk init)\n", - (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), - num_physpages << (PAGE_SHIFT-10), - codesize >> 10, - reservedpages << (PAGE_SHIFT-10), - datasize >> 10, - bsssize >> 10, - initsize >> 10); - - mem_init_done = 1; - - /* Initialize the vDSO */ - vdso_init(); -} - void __iomem * reserve_phb_iospace(unsigned long size) { void __iomem *virt_addr; diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c new file mode 100644 index 000000000000..9b5aa6808eb8 --- /dev/null +++ b/arch/powerpc/mm/lmb.c @@ -0,0 +1,296 @@ +/* + * Procedures for maintaining information about logical memory blocks. + * + * Peter Bergner, IBM Corp. June 2001. + * Copyright (C) 2001 Peter Bergner. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PPC32 +#include "mmu_decl.h" /* for __max_low_memory */ +#endif + +struct lmb lmb; + +#undef DEBUG + +void lmb_dump_all(void) +{ +#ifdef DEBUG + unsigned long i; + + udbg_printf("lmb_dump_all:\n"); + udbg_printf(" memory.cnt = 0x%lx\n", + lmb.memory.cnt); + udbg_printf(" memory.size = 0x%lx\n", + lmb.memory.size); + for (i=0; i < lmb.memory.cnt ;i++) { + udbg_printf(" memory.region[0x%x].base = 0x%lx\n", + i, lmb.memory.region[i].base); + udbg_printf(" .size = 0x%lx\n", + lmb.memory.region[i].size); + } + + udbg_printf("\n reserved.cnt = 0x%lx\n", + lmb.reserved.cnt); + udbg_printf(" reserved.size = 0x%lx\n", + lmb.reserved.size); + for (i=0; i < lmb.reserved.cnt ;i++) { + udbg_printf(" reserved.region[0x%x].base = 0x%lx\n", + i, lmb.reserved.region[i].base); + udbg_printf(" .size = 0x%lx\n", + lmb.reserved.region[i].size); + } +#endif /* DEBUG */ +} + +static unsigned long __init lmb_addrs_overlap(unsigned long base1, + unsigned long size1, unsigned long base2, unsigned long size2) +{ + return ((base1 < (base2+size2)) && (base2 < (base1+size1))); +} + +static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1, + unsigned long base2, unsigned long size2) +{ + if (base2 == base1 + size1) + return 1; + else if (base1 == base2 + size2) + return -1; + + return 0; +} + +static long __init lmb_regions_adjacent(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + unsigned long base1 = rgn->region[r1].base; + unsigned long size1 = rgn->region[r1].size; + unsigned long base2 = rgn->region[r2].base; + unsigned long size2 = rgn->region[r2].size; + + return lmb_addrs_adjacent(base1, size1, base2, size2); +} + +/* Assumption: base addr of region 1 < base addr of region 2 */ +static void __init lmb_coalesce_regions(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + unsigned long i; + + rgn->region[r1].size += rgn->region[r2].size; + for (i=r2; i < rgn->cnt-1; i++) { + rgn->region[i].base = rgn->region[i+1].base; + rgn->region[i].size = rgn->region[i+1].size; + } + rgn->cnt--; +} + +/* This routine called with relocation disabled. */ +void __init lmb_init(void) +{ + /* Create a dummy zero size LMB which will get coalesced away later. + * This simplifies the lmb_add() code below... + */ + lmb.memory.region[0].base = 0; + lmb.memory.region[0].size = 0; + lmb.memory.cnt = 1; + + /* Ditto. */ + lmb.reserved.region[0].base = 0; + lmb.reserved.region[0].size = 0; + lmb.reserved.cnt = 1; +} + +/* This routine may be called with relocation disabled. */ +void __init lmb_analyze(void) +{ + int i; + + lmb.memory.size = 0; + + for (i = 0; i < lmb.memory.cnt; i++) + lmb.memory.size += lmb.memory.region[i].size; +} + +/* This routine called with relocation disabled. */ +static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base, + unsigned long size) +{ + unsigned long i, coalesced = 0; + long adjacent; + + /* First try and coalesce this LMB with another. */ + for (i=0; i < rgn->cnt; i++) { + unsigned long rgnbase = rgn->region[i].base; + unsigned long rgnsize = rgn->region[i].size; + + adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize); + if ( adjacent > 0 ) { + rgn->region[i].base -= size; + rgn->region[i].size += size; + coalesced++; + break; + } + else if ( adjacent < 0 ) { + rgn->region[i].size += size; + coalesced++; + break; + } + } + + if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) { + lmb_coalesce_regions(rgn, i, i+1); + coalesced++; + } + + if (coalesced) + return coalesced; + if (rgn->cnt >= MAX_LMB_REGIONS) + return -1; + + /* Couldn't coalesce the LMB, so add it to the sorted table. */ + for (i = rgn->cnt-1; i >= 0; i--) { + if (base < rgn->region[i].base) { + rgn->region[i+1].base = rgn->region[i].base; + rgn->region[i+1].size = rgn->region[i].size; + } else { + rgn->region[i+1].base = base; + rgn->region[i+1].size = size; + break; + } + } + rgn->cnt++; + + return 0; +} + +/* This routine may be called with relocation disabled. */ +long __init lmb_add(unsigned long base, unsigned long size) +{ + struct lmb_region *_rgn = &(lmb.memory); + + /* On pSeries LPAR systems, the first LMB is our RMO region. */ + if (base == 0) + lmb.rmo_size = size; + + return lmb_add_region(_rgn, base, size); + +} + +long __init lmb_reserve(unsigned long base, unsigned long size) +{ + struct lmb_region *_rgn = &(lmb.reserved); + + return lmb_add_region(_rgn, base, size); +} + +long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, + unsigned long size) +{ + unsigned long i; + + for (i=0; i < rgn->cnt; i++) { + unsigned long rgnbase = rgn->region[i].base; + unsigned long rgnsize = rgn->region[i].size; + if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) { + break; + } + } + + return (i < rgn->cnt) ? i : -1; +} + +unsigned long __init lmb_alloc(unsigned long size, unsigned long align) +{ + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); +} + +unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align, + unsigned long max_addr) +{ + long i, j; + unsigned long base = 0; + +#ifdef CONFIG_PPC32 + /* On 32-bit, make sure we allocate lowmem */ + if (max_addr == LMB_ALLOC_ANYWHERE) + max_addr = __max_low_memory; +#endif + for (i = lmb.memory.cnt-1; i >= 0; i--) { + unsigned long lmbbase = lmb.memory.region[i].base; + unsigned long lmbsize = lmb.memory.region[i].size; + + if (max_addr == LMB_ALLOC_ANYWHERE) + base = _ALIGN_DOWN(lmbbase + lmbsize - size, align); + else if (lmbbase < max_addr) { + base = min(lmbbase + lmbsize, max_addr); + base = _ALIGN_DOWN(base - size, align); + } else + continue; + + while ((lmbbase <= base) && + ((j = lmb_overlaps_region(&lmb.reserved, base, size)) >= 0) ) + base = _ALIGN_DOWN(lmb.reserved.region[j].base - size, + align); + + if ((base != 0) && (lmbbase <= base)) + break; + } + + if (i < 0) + return 0; + + lmb_add_region(&lmb.reserved, base, size); + + return base; +} + +/* You must call lmb_analyze() before this. */ +unsigned long __init lmb_phys_mem_size(void) +{ + return lmb.memory.size; +} + +unsigned long __init lmb_end_of_DRAM(void) +{ + int idx = lmb.memory.cnt - 1; + + return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); +} + +/* + * Truncate the lmb list to memory_limit if it's set + * You must call lmb_analyze() after this. + */ +void __init lmb_enforce_memory_limit(unsigned long memory_limit) +{ + unsigned long i, limit; + + if (! memory_limit) + return; + + limit = memory_limit; + for (i = 0; i < lmb.memory.cnt; i++) { + if (limit > lmb.memory.region[i].size) { + limit -= lmb.memory.region[i].size; + continue; + } + + lmb.memory.region[i].size = limit; + lmb.memory.cnt = i + 1; + break; + } +} diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 345db08e5d20..0650de74d0b3 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -45,8 +45,9 @@ #include #include #include +#include +#include -#include "mem_pieces.h" #include "mmu_decl.h" #ifndef CPU_FTR_COHERENT_ICACHE @@ -54,6 +55,9 @@ #define CPU_FTR_NOEXECUTE 0 #endif +int init_bootmem_done; +int mem_init_done; + /* * This is called by /dev/mem to know if a given address has to * be mapped non-cacheable or not @@ -130,6 +134,185 @@ void show_mem(void) printk("%ld pages swap cached\n", cached); } +/* + * Initialize the bootmem system and give it all the memory we + * have available. If we are using highmem, we only put the + * lowmem into the bootmem system. + */ +#ifndef CONFIG_NEED_MULTIPLE_NODES +void __init do_init_bootmem(void) +{ + unsigned long i; + unsigned long start, bootmap_pages; + unsigned long total_pages; + int boot_mapsize; + + max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; +#ifdef CONFIG_HIGHMEM + total_pages = total_lowmem >> PAGE_SHIFT; +#endif + + /* + * Find an area to use for the bootmem bitmap. Calculate the size of + * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. + * Add 1 additional page in case the address isn't page-aligned. + */ + bootmap_pages = bootmem_bootmap_pages(total_pages); + + start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); + BUG_ON(!start); + + boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); + + /* Add all physical memory to the bootmem map, mark each area + * present. + */ + for (i = 0; i < lmb.memory.cnt; i++) { + unsigned long base = lmb.memory.region[i].base; + unsigned long size = lmb_size_bytes(&lmb.memory, i); +#ifdef CONFIG_HIGHMEM + if (base >= total_lowmem) + continue; + if (base + size > total_lowmem) + size = total_lowmem - base; +#endif + free_bootmem(base, size); + } + + /* reserve the sections we're already using */ + for (i = 0; i < lmb.reserved.cnt; i++) + reserve_bootmem(lmb.reserved.region[i].base, + lmb_size_bytes(&lmb.reserved, i)); + + /* XXX need to clip this if using highmem? */ + for (i = 0; i < lmb.memory.cnt; i++) + memory_present(0, lmb_start_pfn(&lmb.memory, i), + lmb_end_pfn(&lmb.memory, i)); + init_bootmem_done = 1; +} + +/* + * paging_init() sets up the page tables - in fact we've already done this. + */ +void __init paging_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long total_ram = lmb_phys_mem_size(); + unsigned long top_of_ram = lmb_end_of_DRAM(); + +#ifdef CONFIG_HIGHMEM + map_page(PKMAP_BASE, 0, 0); /* XXX gross */ + pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k + (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); + map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ + kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k + (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); + kmap_prot = PAGE_KERNEL; +#endif /* CONFIG_HIGHMEM */ + + printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", + top_of_ram, total_ram); + printk(KERN_INFO "Memory hole size: %ldMB\n", + (top_of_ram - total_ram) >> 20); + /* + * All pages are DMA-able so we put them all in the DMA zone. + */ + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + + zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; + +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; + zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; + zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT; +#else + zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; +#endif /* CONFIG_HIGHMEM */ + + free_area_init_node(0, NODE_DATA(0), zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); +} +#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ + +void __init mem_init(void) +{ +#ifdef CONFIG_NEED_MULTIPLE_NODES + int nid; +#endif + pg_data_t *pgdat; + unsigned long i; + struct page *page; + unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; + + num_physpages = max_pfn; /* RAM is assumed contiguous */ + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); + +#ifdef CONFIG_NEED_MULTIPLE_NODES + for_each_online_node(nid) { + if (NODE_DATA(nid)->node_spanned_pages != 0) { + printk("freeing bootmem node %x\n", nid); + totalram_pages += + free_all_bootmem_node(NODE_DATA(nid)); + } + } +#else + max_mapnr = num_physpages; + totalram_pages += free_all_bootmem(); +#endif + for_each_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + page = pgdat_page_nr(pgdat, i); + if (PageReserved(page)) + reservedpages++; + } + } + + codesize = (unsigned long)&_sdata - (unsigned long)&_stext; + datasize = (unsigned long)&__init_begin - (unsigned long)&_sdata; + initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin; + bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start; + +#ifdef CONFIG_HIGHMEM + { + unsigned long pfn, highmem_mapnr; + + highmem_mapnr = total_lowmem >> PAGE_SHIFT; + for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { + struct page *page = pfn_to_page(pfn); + + ClearPageReserved(page); + set_page_count(page, 1); + __free_page(page); + totalhigh_pages++; + } + totalram_pages += totalhigh_pages; + printk(KERN_INFO "High memory: %luk\n", + totalhigh_pages << (PAGE_SHIFT-10)); + } +#endif /* CONFIG_HIGHMEM */ + + printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, " + "%luk reserved, %luk data, %luk bss, %luk init)\n", + (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10), + codesize >> 10, + reservedpages << (PAGE_SHIFT-10), + datasize >> 10, + bsssize >> 10, + initsize >> 10); + + mem_init_done = 1; + +#ifdef CONFIG_PPC64 + /* Initialize the vDSO */ + vdso_init(); +#endif +} + /* * This is called when a page has been modified by the kernel. * It just marks the page as not i-cache clean. We do the i-cache diff --git a/arch/powerpc/mm/mem_pieces.c b/arch/powerpc/mm/mem_pieces.c deleted file mode 100644 index 3d639052017e..000000000000 --- a/arch/powerpc/mm/mem_pieces.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 1996 Paul Mackerras - * Changes to accommodate Power Macintoshes. - * Cort Dougan - * Rewrites. - * Grant Erickson - * General rework and split from mm/init.c. - * - * Module name: mem_pieces.c - * - * Description: - * Routines and data structures for manipulating and representing - * phyiscal memory extents (i.e. address/length pairs). - * - */ - -#include -#include -#include -#include -#include - -#include "mem_pieces.h" - -extern struct mem_pieces phys_avail; - -static void mem_pieces_print(struct mem_pieces *); - -/* - * Scan a region for a piece of a given size with the required alignment. - */ -void __init * -mem_pieces_find(unsigned int size, unsigned int align) -{ - int i; - unsigned a, e; - struct mem_pieces *mp = &phys_avail; - - for (i = 0; i < mp->n_regions; ++i) { - a = mp->regions[i].address; - e = a + mp->regions[i].size; - a = (a + align - 1) & -align; - if (a + size <= e) { - mem_pieces_remove(mp, a, size, 1); - return (void *) __va(a); - } - } - panic("Couldn't find %u bytes at %u alignment\n", size, align); - - return NULL; -} - -/* - * Remove some memory from an array of pieces - */ -void __init -mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size, - int must_exist) -{ - int i, j; - unsigned int end, rs, re; - struct reg_property *rp; - - end = start + size; - for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) { - if (end > rp->address && start < rp->address + rp->size) - break; - } - if (i >= mp->n_regions) { - if (must_exist) - printk("mem_pieces_remove: [%x,%x) not in any region\n", - start, end); - return; - } - for (; i < mp->n_regions && end > rp->address; ++i, ++rp) { - rs = rp->address; - re = rs + rp->size; - if (must_exist && (start < rs || end > re)) { - printk("mem_pieces_remove: bad overlap [%x,%x) with", - start, end); - mem_pieces_print(mp); - must_exist = 0; - } - if (start > rs) { - rp->size = start - rs; - if (end < re) { - /* need to split this entry */ - if (mp->n_regions >= MEM_PIECES_MAX) - panic("eek... mem_pieces overflow"); - for (j = mp->n_regions; j > i + 1; --j) - mp->regions[j] = mp->regions[j-1]; - ++mp->n_regions; - rp[1].address = end; - rp[1].size = re - end; - } - } else { - if (end < re) { - rp->address = end; - rp->size = re - end; - } else { - /* need to delete this entry */ - for (j = i; j < mp->n_regions - 1; ++j) - mp->regions[j] = mp->regions[j+1]; - --mp->n_regions; - --i; - --rp; - } - } - } -} - -static void __init -mem_pieces_print(struct mem_pieces *mp) -{ - int i; - - for (i = 0; i < mp->n_regions; ++i) - printk(" [%x, %x)", mp->regions[i].address, - mp->regions[i].address + mp->regions[i].size); - printk("\n"); -} - -void __init -mem_pieces_sort(struct mem_pieces *mp) -{ - unsigned long a, s; - int i, j; - - for (i = 1; i < mp->n_regions; ++i) { - a = mp->regions[i].address; - s = mp->regions[i].size; - for (j = i - 1; j >= 0; --j) { - if (a >= mp->regions[j].address) - break; - mp->regions[j+1] = mp->regions[j]; - } - mp->regions[j+1].address = a; - mp->regions[j+1].size = s; - } -} - -void __init -mem_pieces_coalesce(struct mem_pieces *mp) -{ - unsigned long a, s, ns; - int i, j, d; - - d = 0; - for (i = 0; i < mp->n_regions; i = j) { - a = mp->regions[i].address; - s = mp->regions[i].size; - for (j = i + 1; j < mp->n_regions - && mp->regions[j].address - a <= s; ++j) { - ns = mp->regions[j].address + mp->regions[j].size - a; - if (ns > s) - s = ns; - } - mp->regions[d].address = a; - mp->regions[d].size = s; - ++d; - } - mp->n_regions = d; -} diff --git a/arch/powerpc/mm/mem_pieces.h b/arch/powerpc/mm/mem_pieces.h deleted file mode 100644 index e2b700dc7f18..000000000000 --- a/arch/powerpc/mm/mem_pieces.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 1996 Paul Mackerras - * Changes to accommodate Power Macintoshes. - * Cort Dougan - * Rewrites. - * Grant Erickson - * General rework and split from mm/init.c. - * - * Module name: mem_pieces.h - * - * Description: - * Routines and data structures for manipulating and representing - * phyiscal memory extents (i.e. address/length pairs). - * - */ - -#ifndef __MEM_PIECES_H__ -#define __MEM_PIECES_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Type Definitions */ - -#define MEM_PIECES_MAX 32 - -struct mem_pieces { - int n_regions; - struct reg_property regions[MEM_PIECES_MAX]; -}; - -/* Function Prototypes */ - -extern void *mem_pieces_find(unsigned int size, unsigned int align); -extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start, - unsigned int size, int must_exist); -extern void mem_pieces_coalesce(struct mem_pieces *mp); -extern void mem_pieces_sort(struct mem_pieces *mp); - -#ifdef __cplusplus -} -#endif - -#endif /* __MEM_PIECES_H__ */ diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 540f3292b229..06fe8af3af55 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -36,6 +36,8 @@ extern unsigned long ioremap_base; extern unsigned long ioremap_bot; extern unsigned int rtas_data, rtas_size; +extern unsigned long __max_low_memory; +extern unsigned long __initial_memory_limit; extern unsigned long total_memory; extern unsigned long total_lowmem; extern int mem_init_done; diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 81a3d7446d37..5792e533916f 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -190,8 +190,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) * Don't allow anybody to remap normal RAM that we're using. * mem_init() sets high_memory so only do the check after that. */ - if ( mem_init_done && (p < virt_to_phys(high_memory)) ) - { + if (mem_init_done && (p < virt_to_phys(high_memory))) { printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p, __builtin_return_address(0)); return NULL; diff --git a/arch/powerpc/mm/ppc_mmu.c b/arch/powerpc/mm/ppc_mmu.c index 9a381ed5eb21..cef9e83cc7e9 100644 --- a/arch/powerpc/mm/ppc_mmu.c +++ b/arch/powerpc/mm/ppc_mmu.c @@ -32,9 +32,9 @@ #include #include #include +#include #include "mmu_decl.h" -#include "mem_pieces.h" PTE *Hash, *Hash_end; unsigned long Hash_size, Hash_mask; @@ -215,17 +215,6 @@ void __init MMU_init_hw(void) #define MIN_N_HPTEG 1024 /* min 64kB hash table */ #endif -#ifdef CONFIG_POWER4 - /* The hash table has already been allocated and initialized - in prom.c */ - n_hpteg = Hash_size >> LG_HPTEG_SIZE; - lg_n_hpteg = __ilog2(n_hpteg); - - /* Remove the hash table from the available memory */ - if (Hash) - reserve_phys_mem(__pa(Hash), Hash_size); - -#else /* CONFIG_POWER4 */ /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. * This is less than the recommended amount, but then @@ -245,10 +234,10 @@ void __init MMU_init_hw(void) * Find some memory for the hash table. */ if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322); - Hash = mem_pieces_find(Hash_size, Hash_size); + Hash = __va(lmb_alloc_base(Hash_size, Hash_size, + __initial_memory_limit)); cacheable_memzero(Hash, Hash_size); _SDR1 = __pa(Hash) | SDR1_LOW_BITS; -#endif /* CONFIG_POWER4 */ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index 4789dc024240..fc44f7ca62d7 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -34,6 +34,17 @@ typedef unsigned long pte_basic_t; #define PTE_FMT "%.8lx" #endif +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr,size) _ALIGN_UP(addr,size) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) + + #undef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS @@ -76,13 +87,6 @@ typedef unsigned long pgprot_t; #endif - -/* align addr on a size boundary - adjust address up if needed -- Cort */ -#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1))) - -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - struct page; extern void clear_pages(void *page, int order); static inline void clear_page(void *page) { clear_pages(page, 0); } From dd99cd803d460576cf84f012786ff39814b73f7f Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 5 Oct 2005 19:32:49 -0700 Subject: [PATCH 0216/1940] [CIFS] cleanup sparse and compile errors in previous fix Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/file.c | 5 +++-- fs/cifs/inode.c | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0f66ae5b694b..39b23f4fa6c3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -907,9 +907,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data, return total_written; } -static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) +struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) { struct cifsFileInfo *open_file; + int rc; read_lock(&GlobalSMBSeslock); list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { @@ -920,7 +921,7 @@ static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) (open_file->pfile->f_flags & O_WRONLY))) { read_unlock(&GlobalSMBSeslock); if(open_file->invalidHandle) { - rc = cifs_reopen_file(cifs_inode->vfs_inode, + rc = cifs_reopen_file(&cifs_inode->vfs_inode, open_file->pfile, FALSE); /* if it fails, try another handle - might be */ /* dangerous to hold up writepages with retry */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 49efdefcff7c..ff4d1cc7c248 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -962,7 +962,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) struct cifsTconInfo *pTcon; char *full_path = NULL; int rc = -EACCES; - int found = FALSE; struct cifsFileInfo *open_file = NULL; FILE_BASIC_INFO time_buf; int set_time = FALSE; @@ -970,7 +969,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) __u64 uid = 0xFFFFFFFFFFFFFFFFULL; __u64 gid = 0xFFFFFFFFFFFFFFFFULL; struct cifsInodeInfo *cifsInode; - struct list_head *tmp; xid = GetXid(); From 187a00679ad51dfb3d3e74620217417102784218 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 12:49:05 +1000 Subject: [PATCH 0217/1940] powerpc: Remove 64-bit cpu support from ppc32. These days there is no good reason to run a ppc32 kernel on a 64-bit cpu, rather than a ppc64 kernel, so remove the config option and a bunch of code (and ifdefs) from head.S. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 16 ++-- arch/powerpc/kernel/head.S | 148 ++----------------------------------- 2 files changed, 11 insertions(+), 153 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 34be3247fca4..330376b74c87 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -109,10 +109,6 @@ config 40x config 44x bool "AMCC 44x" -config PPC64BRIDGE - select PPC_FPU - bool "POWER3, POWER4 and PPC970 (G5)" - config 8xx bool "Freescale 8xx" @@ -125,7 +121,7 @@ endchoice config POWER4_ONLY bool "Optimize for POWER4" - depends on PPC64 || PPC64BRIDGE + depends on PPC64 default n ---help--- Cause the compiler to optimize for POWER4/POWER5/PPC970 processors. @@ -134,16 +130,16 @@ config POWER4_ONLY config POWER3 bool - depends on PPC64 || PPC64BRIDGE + depends on PPC64 default y if !POWER4_ONLY config POWER4 - depends on PPC64 || PPC64BRIDGE + depends on PPC64 def_bool y config PPC_FPU - depends on PPC32 - def_bool y + bool + default y if PPC64 config BOOKE bool @@ -317,7 +313,7 @@ config PPC_BPA config PPC_OF bool - depends on PPC_MULTIPLATFORM || PPC_ISERIES + depends on PPC_MULTIPLATFORM # for now default y config XICS diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S index d49bff1a7d51..276793e05fd0 100644 --- a/arch/powerpc/kernel/head.S +++ b/arch/powerpc/kernel/head.S @@ -37,19 +37,6 @@ #include #endif -#ifdef CONFIG_PPC64BRIDGE -#define LOAD_BAT(n, reg, RA, RB) \ - ld RA,(n*32)+0(reg); \ - ld RB,(n*32)+8(reg); \ - mtspr SPRN_IBAT##n##U,RA; \ - mtspr SPRN_IBAT##n##L,RB; \ - ld RA,(n*32)+16(reg); \ - ld RB,(n*32)+24(reg); \ - mtspr SPRN_DBAT##n##U,RA; \ - mtspr SPRN_DBAT##n##L,RB; \ - -#else /* CONFIG_PPC64BRIDGE */ - /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ /* see the comment for clear_bats() -- Cort */ \ @@ -66,7 +53,6 @@ mtspr SPRN_DBAT##n##U,RA; \ mtspr SPRN_DBAT##n##L,RB; \ 1: -#endif /* CONFIG_PPC64BRIDGE */ .text .stabs "arch/ppc/kernel/",N_SO,0,0,0f @@ -150,14 +136,6 @@ __start: */ bl early_init -/* - * On POWER4, we first need to tweak some CPU configuration registers - * like real mode cache inhibit or exception base - */ -#ifdef CONFIG_POWER4 - bl __970_cpu_preinit -#endif /* CONFIG_POWER4 */ - #ifdef CONFIG_APUS /* On APUS the __va/__pa constants need to be set to the correct * values before continuing. @@ -171,7 +149,6 @@ __start: */ bl mmu_off __after_mmu_off: -#ifndef CONFIG_POWER4 bl clear_bats bl flush_tlbs @@ -179,10 +156,6 @@ __after_mmu_off: #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif -#else /* CONFIG_POWER4 */ - bl reloc_offset - bl initial_mm_power4 -#endif /* CONFIG_POWER4 */ /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -194,10 +167,6 @@ __after_mmu_off: bl reloc_offset bl init_idle_6xx #endif /* CONFIG_6xx */ -#ifdef CONFIG_POWER4 - bl reloc_offset - bl init_idle_power4 -#endif /* CONFIG_POWER4 */ #ifndef CONFIG_APUS @@ -397,13 +366,8 @@ i##n: \ /* Data access exception. */ . = 0x300 -#ifdef CONFIG_PPC64BRIDGE - b DataAccess -DataAccessCont: -#else DataAccess: EXCEPTION_PROLOG -#endif /* CONFIG_PPC64BRIDGE */ mfspr r10,SPRN_DSISR andis. r0,r10,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -415,21 +379,11 @@ DataAccess: mfspr r4,SPRN_DAR EXC_XFER_EE_LITE(0x300, handle_page_fault) -#ifdef CONFIG_PPC64BRIDGE -/* SLB fault on data access. */ - . = 0x380 - b DataSegment -#endif /* CONFIG_PPC64BRIDGE */ /* Instruction access exception. */ . = 0x400 -#ifdef CONFIG_PPC64BRIDGE - b InstructionAccess -InstructionAccessCont: -#else InstructionAccess: EXCEPTION_PROLOG -#endif /* CONFIG_PPC64BRIDGE */ andis. r0,r9,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ @@ -439,12 +393,6 @@ InstructionAccess: mr r5,r9 EXC_XFER_EE_LITE(0x400, handle_page_fault) -#ifdef CONFIG_PPC64BRIDGE -/* SLB fault on instruction access. */ - . = 0x480 - b InstructionSegment -#endif /* CONFIG_PPC64BRIDGE */ - /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -709,15 +657,9 @@ DataStoreTLBMiss: EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) -#ifdef CONFIG_POWER4 - EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) - EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE) - EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) -#else /* !CONFIG_POWER4 */ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) -#endif /* CONFIG_POWER4 */ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) @@ -754,28 +696,6 @@ AltiVecUnavailable: #endif /* CONFIG_ALTIVEC */ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) -#ifdef CONFIG_PPC64BRIDGE -DataAccess: - EXCEPTION_PROLOG - b DataAccessCont - -InstructionAccess: - EXCEPTION_PROLOG - b InstructionAccessCont - -DataSegment: - EXCEPTION_PROLOG - addi r3,r1,STACK_FRAME_OVERHEAD - mfspr r4,SPRN_DAR - stw r4,_DAR(r11) - EXC_XFER_STD(0x380, unknown_exception) - -InstructionSegment: - EXCEPTION_PROLOG - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0x480, unknown_exception) -#endif /* CONFIG_PPC64BRIDGE */ - #ifdef CONFIG_ALTIVEC /* Note that the AltiVec support is closely modeled after the FP * support. Changes to one are likely to be applicable to the @@ -1048,13 +968,6 @@ __secondary_start_pmac_0: .globl __secondary_start __secondary_start: -#ifdef CONFIG_PPC64BRIDGE - mfmsr r0 - clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - SYNC - MTMSRD(r0) - isync -#endif /* Copy some CPU settings from CPU 0 */ bl __restore_cpu_setup @@ -1065,10 +978,6 @@ __secondary_start: lis r3,-KERNELBASE@h bl init_idle_6xx #endif /* CONFIG_6xx */ -#ifdef CONFIG_POWER4 - lis r3,-KERNELBASE@h - bl init_idle_power4 -#endif /* CONFIG_POWER4 */ /* get current_thread_info and current */ lis r1,secondary_ti@ha @@ -1109,12 +1018,12 @@ __secondary_start: * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */ -#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) +#if !defined(CONFIG_6xx) _GLOBAL(__save_cpu_setup) blr _GLOBAL(__restore_cpu_setup) blr -#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */ +#endif /* !defined(CONFIG_6xx) */ /* @@ -1132,11 +1041,6 @@ load_up_mmu: tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 -#ifdef CONFIG_PPC64BRIDGE - /* clear the ASR so we only use the pseudo-segment registers. */ - li r6,0 - mtasr r6 -#endif /* CONFIG_PPC64BRIDGE */ li r0,16 /* load up segment register values */ mtctr r0 /* for context 0 */ lis r3,0x2000 /* Ku = 1, VSID = 0 */ @@ -1145,7 +1049,7 @@ load_up_mmu: addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b -#ifndef CONFIG_POWER4 + /* Load the BAT registers with the values set up by MMU_init. MMU_init takes care of whether we're on a 601 or not. */ mfpvr r3 @@ -1158,7 +1062,7 @@ load_up_mmu: LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) -#endif /* CONFIG_POWER4 */ + blr /* @@ -1183,7 +1087,7 @@ start_here: li r0,0 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) /* - * Do early bootinfo parsing, platform-specific initialization, + * Do early platform-specific initialization, * and set up the MMU. */ mr r3,r31 @@ -1266,9 +1170,6 @@ _GLOBAL(set_context) li r4,0 isync 3: -#ifdef CONFIG_PPC64BRIDGE - slbie r4 -#endif /* CONFIG_PPC64BRIDGE */ mtsrin r3,r4 addi r3,r3,0x111 /* next VSID */ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ @@ -1355,7 +1256,6 @@ mmu_off: sync RFI -#ifndef CONFIG_POWER4 /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely @@ -1363,7 +1263,6 @@ mmu_off: */ initial_bats: lis r11,KERNELBASE@h -#ifndef CONFIG_PPC64BRIDGE mfspr r9,SPRN_PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi 0,r9,1 @@ -1378,7 +1277,6 @@ initial_bats: mtspr SPRN_IBAT1L,r10 isync blr -#endif /* CONFIG_PPC64BRIDGE */ 4: tophys(r8,r11) #ifdef CONFIG_SMP @@ -1392,11 +1290,6 @@ initial_bats: ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ #endif /* CONFIG_APUS */ -#ifdef CONFIG_PPC64BRIDGE - /* clear out the high 32 bits in the BAT */ - clrldi r11,r11,32 - clrldi r8,r8,32 -#endif /* CONFIG_PPC64BRIDGE */ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 @@ -1429,37 +1322,6 @@ setup_disp_bat: #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ -#else /* CONFIG_POWER4 */ -/* - * Load up the SDR1 and segment register values now - * since we don't have the BATs. - * Also make sure we are running in 32-bit mode. - */ - -initial_mm_power4: - addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ - lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ - mtspr SPRN_SDR1,r14 - slbia - lis r4,0x2000 /* set pseudo-segment reg 12 */ - ori r5,r4,0x0ccc - mtsr 12,r5 -#if 0 - ori r5,r4,0x0888 /* set pseudo-segment reg 8 */ - mtsr 8,r5 /* (for access to serial port) */ -#endif -#ifdef CONFIG_BOOTX_TEXT - ori r5,r4,0x0999 /* set pseudo-segment reg 9 */ - mtsr 9,r5 /* (for access to screen) */ -#endif - mfmsr r0 - clrldi r0,r0,1 - sync - mtmsr r0 - isync - blr - -#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8260 /* Jump into the system reset for the rom. From 2e686bc3bf6268e30eb9584e0bcd43b7bec28f3b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 13:22:17 +1000 Subject: [PATCH 0218/1940] powerpc: Merge of_device.c and of_device.h Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/of_device.c | 274 +++++++++++++++++++ include/{asm-ppc => asm-powerpc}/of_device.h | 7 +- include/asm-ppc64/of_device.h | 2 - 3 files changed, 277 insertions(+), 6 deletions(-) create mode 100644 arch/powerpc/kernel/of_device.c rename include/{asm-ppc => asm-powerpc}/of_device.h (94%) delete mode 100644 include/asm-ppc64/of_device.h diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c new file mode 100644 index 000000000000..766718814515 --- /dev/null +++ b/arch/powerpc/kernel/of_device.c @@ -0,0 +1,274 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_device_id *of_match_device(const struct of_device_id *matches, + const struct of_device *dev) +{ + if (!dev->node) + return NULL; + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + int match = 1; + if (matches->name[0]) + match &= dev->node->name + && !strcmp(matches->name, dev->node->name); + if (matches->type[0]) + match &= dev->node->type + && !strcmp(matches->type, dev->node->type); + if (matches->compatible[0]) + match &= device_is_compatible(dev->node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_device_id * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +struct of_device *of_dev_get(struct of_device *dev) +{ + struct device *tmp; + + if (!dev) + return NULL; + tmp = get_device(&dev->dev); + if (tmp) + return to_of_device(tmp); + else + return NULL; +} + +void of_dev_put(struct of_device *dev) +{ + if (dev) + put_device(&dev->dev); +} + + +static int of_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int of_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int of_device_suspend(struct device *dev, pm_message_t state) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->suspend) + error = drv->suspend(of_dev, state); + return error; +} + +static int of_device_resume(struct device * dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->resume) + error = drv->resume(of_dev); + return error; +} + +struct bus_type of_platform_bus_type = { + .name = "of_platform", + .match = of_platform_bus_match, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; + +static int __init of_bus_driver_init(void) +{ + return bus_register(&of_platform_bus_type); +} + +postcore_initcall(of_bus_driver_init); + +int of_register_driver(struct of_platform_driver *drv) +{ + int count = 0; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &of_platform_bus_type; + drv->driver.probe = of_device_probe; + drv->driver.remove = of_device_remove; + + /* register with core */ + count = driver_register(&drv->driver); + return count ? count : 1; +} + +void of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} + + +static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +/** + * of_release_dev - free an of device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this of device are + * done. + */ +void of_release_dev(struct device *dev) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + of_node_put(ofdev->node); + kfree(ofdev); +} + +int of_device_register(struct of_device *ofdev) +{ + int rc; + struct of_device **odprop; + + BUG_ON(ofdev->node == NULL); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (!odprop) { + struct property *new_prop; + + new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), + GFP_KERNEL); + if (new_prop == NULL) + return -ENOMEM; + new_prop->name = "linux,device"; + new_prop->length = sizeof(sizeof(struct of_device *)); + new_prop->value = (unsigned char *)&new_prop[1]; + odprop = (struct of_device **)new_prop->value; + *odprop = NULL; + prom_add_property(ofdev->node, new_prop); + } + *odprop = ofdev; + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + device_create_file(&ofdev->dev, &dev_attr_devspec); + + return 0; +} + +void of_device_unregister(struct of_device *ofdev) +{ + struct of_device **odprop; + + device_remove_file(&ofdev->dev, &dev_attr_devspec); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (odprop) + *odprop = NULL; + + device_unregister(&ofdev->dev); +} + +struct of_device* of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->node = of_node_get(np); + dev->dma_mask = 0xffffffffUL; + dev->dev.dma_mask = &dev->dma_mask; + dev->dev.parent = parent; + dev->dev.bus = &of_platform_bus_type; + dev->dev.release = of_release_dev; + + strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); + + if (of_device_register(dev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} + +EXPORT_SYMBOL(of_match_device); +EXPORT_SYMBOL(of_platform_bus_type); +EXPORT_SYMBOL(of_register_driver); +EXPORT_SYMBOL(of_unregister_driver); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_dev_get); +EXPORT_SYMBOL(of_dev_put); +EXPORT_SYMBOL(of_platform_device_create); +EXPORT_SYMBOL(of_release_dev); diff --git a/include/asm-ppc/of_device.h b/include/asm-powerpc/of_device.h similarity index 94% rename from include/asm-ppc/of_device.h rename to include/asm-powerpc/of_device.h index 575bce418f80..ddb16aae0bd6 100644 --- a/include/asm-ppc/of_device.h +++ b/include/asm-powerpc/of_device.h @@ -1,5 +1,5 @@ -#ifndef __OF_DEVICE_H__ -#define __OF_DEVICE_H__ +#ifndef _ASM_POWERPC_OF_DEVICE_H +#define _ASM_POWERPC_OF_DEVICE_H #include #include @@ -61,5 +61,4 @@ extern struct of_device *of_platform_device_create(struct device_node *np, struct device *parent); extern void of_release_dev(struct device *dev); -#endif /* __OF_DEVICE_H__ */ - +#endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/include/asm-ppc64/of_device.h b/include/asm-ppc64/of_device.h deleted file mode 100644 index 7bc136e22590..000000000000 --- a/include/asm-ppc64/of_device.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - From b3491269f5604e4265ee2f27b47a76ce1e3678b6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 13:24:50 +1000 Subject: [PATCH 0219/1940] powerpc: Use the merged of_device.c with ARCH=powerpc Also compile btext.c with -fPIC; this was missed before. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 4842e82dbc2b..06d618e52f8e 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -7,6 +7,7 @@ EXTRA_CFLAGS += -mno-minimal-toc endif ifeq ($(CONFIG_PPC32),y) CFLAGS_prom_init.o += -fPIC +CFLAGS_btext.o += -fPIC endif extra-$(CONFIG_PPC_STD_MMU) := head.o @@ -23,7 +24,7 @@ obj-y := traps.o prom.o semaphore.o obj-$(CONFIG_PPC32) += setup.o process.o obj-$(CONFIG_PPC64) += idle_power4.o ifeq ($(CONFIG_PPC32),y) -obj-$(CONFIG_PPC_OF) += prom_init.o +obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o obj-$(CONFIG_MODULES) += ppc_ksyms.o endif obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o From 8dad3f9257414f151cd821bfe01f54d7f52d2507 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 13:27:05 +1000 Subject: [PATCH 0220/1940] powerpc: Merge traps.c a bit more This reduces the differences between ppc32 and ppc64 in arch/powerpc/kernel/traps.c a bit further. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head.S | 2 +- arch/powerpc/kernel/traps.c | 192 +++++++----------------------------- 2 files changed, 35 insertions(+), 159 deletions(-) diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S index 276793e05fd0..d9dbbd426744 100644 --- a/arch/powerpc/kernel/head.S +++ b/arch/powerpc/kernel/head.S @@ -416,7 +416,7 @@ FPUnavailable: EXCEPTION_PROLOG bne load_up_fpu /* if from user, just load it up */ addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE_LITE(0x800, KernelFP) + EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception) /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 37b961f1e279..a2e4ad3f5a75 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -21,19 +21,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include -#ifdef CONFIG_PPC32 -#include -#include -#endif #include #include @@ -56,12 +54,6 @@ #include #endif -#ifdef CONFIG_PPC64 -#define __KPROBES __kprobes -#else -#define __KPROBES -#endif - #ifdef CONFIG_DEBUGGER int (*__debugger)(struct pt_regs *regs); int (*__debugger_ipi)(struct pt_regs *regs); @@ -111,7 +103,7 @@ int die(const char *str, struct pt_regs *regs, long err) console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); -#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC_BACKLIGHT) +#ifdef CONFIG_PMAC_BACKLIGHT if (_machine == _MACH_Pmac) { set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); @@ -175,11 +167,7 @@ int die(const char *str, struct pt_regs *regs, long err) #endif panic("Fatal exception"); } -#ifdef CONFIG_PPC32 do_exit(err); -#else - do_exit(SIGSEGV); -#endif return 0; } @@ -199,7 +187,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) info.si_addr = (void __user *) addr; force_sig_info(signr, &info, current); -#ifdef CONFIG_PPC32 /* * Init gets no signals that it doesn't have a handler for. * That's all very well, but if it has caused a synchronous @@ -221,7 +208,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) do_exit(signr); } } -#endif } #ifdef CONFIG_PPC64 @@ -231,7 +217,7 @@ void system_reset_exception(struct pt_regs *regs) if (ppc_md.system_reset_exception) ppc_md.system_reset_exception(regs); - die("System Reset", regs, 0); + die("System Reset", regs, SIGABRT); /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) @@ -241,7 +227,6 @@ void system_reset_exception(struct pt_regs *regs) } #endif -#ifdef CONFIG_PPC32 /* * I/O accesses can cause machine checks on powermacs. * Check if the NIP corresponds to the address of a sync @@ -290,7 +275,6 @@ static inline int check_io_access(struct pt_regs *regs) #endif /* CONFIG_PPC_PMAC */ return 0; } -#endif /* CONFIG_PPC32 */ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) @@ -326,7 +310,6 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -#ifdef CONFIG_PPC32 /* * This is "fall-back" implementation for configurations * which don't provide platform-specific machine check info @@ -335,7 +318,6 @@ void __attribute__ ((weak)) platform_machine_check(struct pt_regs *regs) { } -#endif void machine_check_exception(struct pt_regs *regs) { @@ -497,13 +479,7 @@ void machine_check_exception(struct pt_regs *regs) if (debugger_fault_handler(regs)) return; - die("Machine check", regs, -#ifdef CONFIG_PPC32 - SIGBUS -#else - 0 -#endif - ); + die("Machine check", regs, SIGBUS); /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) @@ -542,13 +518,9 @@ void RunModeException(struct pt_regs *regs) } #endif -void __KPROBES single_step_exception(struct pt_regs *regs) +void __kprobes single_step_exception(struct pt_regs *regs) { -#ifdef CONFIG_PPC32 regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ -#else - regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ -#endif if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) @@ -565,15 +537,12 @@ void __KPROBES single_step_exception(struct pt_regs *regs) * pretend we got a single-step exception. This was pointed out * by Kumar Gala. -- paulus */ -static inline void emulate_single_step(struct pt_regs *regs) +static void emulate_single_step(struct pt_regs *regs) { if (single_stepping(regs)) { -#ifdef CONFIG_PPC32 clear_single_step(regs); _exception(SIGTRAP, regs, TRAP_TRACE, 0); -#else single_step_exception(regs); -#endif } } @@ -582,17 +551,7 @@ static void parse_fpe(struct pt_regs *regs) int code = 0; unsigned long fpscr; -#ifdef CONFIG_PPC32 - /* We must make sure the FP state is consistent with - * our MSR_FP in regs - */ - preempt_disable(); - if (regs->msr & MSR_FP) - giveup_fpu(current); - preempt_enable(); -#else flush_fp_to_thread(current); -#endif fpscr = current->thread.fpscr; @@ -737,19 +696,8 @@ static int emulate_instruction(struct pt_regs *regs) } /* Emulating the dcba insn is just a no-op. */ - if ((instword & INST_DCBA_MASK) == INST_DCBA) { -#ifdef CONFIG_PPC64 - static int warned; - - if (!warned) { - printk(KERN_WARNING - "process %d (%s) uses obsolete 'dcba' insn\n", - current->pid, current->comm); - warned = 1; - } -#endif /* CONFIG_PPC64 */ + if ((instword & INST_DCBA_MASK) == INST_DCBA) return 0; - } /* Emulate the mcrxr insn. */ if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { @@ -817,7 +765,7 @@ static int check_bug_trap(struct pt_regs *regs) return 0; if (bug->line & BUG_WARNING_TRAP) { /* this is a WARN_ON rather than BUG/BUG_ON */ -#if defined(CONFIG_PPC32) && defined(CONFIG_XMON) +#ifdef CONFIG_XMON xmon_printf(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, bug->line & ~BUG_WARNING_TRAP); @@ -843,12 +791,12 @@ static int check_bug_trap(struct pt_regs *regs) return 0; } -void __KPROBES program_check_exception(struct pt_regs *regs) +void __kprobes program_check_exception(struct pt_regs *regs) { unsigned int reason = get_reason(regs); -#if defined(CONFIG_PPC32) && defined(CONFIG_MATH_EMULATION) extern int do_mathemu(struct pt_regs *regs); +#ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD) * that means ESR is sometimes set incorrectly - either to @@ -860,58 +808,45 @@ void __KPROBES program_check_exception(struct pt_regs *regs) emulate_single_step(regs); return; } -#endif - -#ifdef CONFIG_PPC64 - if (debugger_fault_handler(regs)) - return; -#endif +#endif /* CONFIG_MATH_EMULATION */ if (reason & REASON_FP) { /* IEEE FP exception */ parse_fpe(regs); - } else if (reason & REASON_TRAP) { + return; + } + if (reason & REASON_TRAP) { /* trap exception */ -#ifdef CONFIG_PPC64 if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) return; -#endif if (debugger_bpt(regs)) return; if (check_bug_trap(regs)) { regs->nip += 4; return; } - _exception(SIGTRAP, regs, TRAP_BRKPT, -#ifdef CONFIG_PPC32 - 0 -#else - regs->nip -#endif - ); - } else -#ifdef CONFIG_PPC32 - if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) -#endif - { - /* Privileged or illegal instruction; try to emulate it. */ + _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); + return; + } + + /* Try to emulate it if we should. */ + if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { switch (emulate_instruction(regs)) { case 0: regs->nip += 4; emulate_single_step(regs); - break; + return; case -EFAULT: _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - break; - default: - if (reason & REASON_PRIVILEGED) - _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); - else - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - break; + return; } } + + if (reason & REASON_PRIVILEGED) + _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); + else + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); } void alignment_exception(struct pt_regs *regs) @@ -929,25 +864,13 @@ void alignment_exception(struct pt_regs *regs) /* Operand address was bad */ if (fixed == -EFAULT) { if (user_mode(regs)) - _exception(SIGSEGV, regs, -#ifdef CONFIG_PPC32 - SEGV_ACCERR, -#else - SEGV_MAPERR, -#endif - regs->dar); + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); else /* Search exception table */ bad_page_fault(regs, regs->dar, SIGSEGV); return; } - _exception(SIGBUS, regs, BUS_ADRALN, -#ifdef CONFIG_PPC32 - regs->dar -#else - regs->nip -#endif - ); + _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } #ifdef CONFIG_PPC32 @@ -976,18 +899,16 @@ void trace_syscall(struct pt_regs *regs) } #endif /* CONFIG_PPC32 */ -#ifdef CONFIG_PPC64 void kernel_fp_unavailable_exception(struct pt_regs *regs) { printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); } -#endif void altivec_unavailable_exception(struct pt_regs *regs) { -#if !defined(CONFIG_ALTIVEC) || defined(CONFIG_PPC64) +#if !defined(CONFIG_ALTIVEC) if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ @@ -995,22 +916,9 @@ void altivec_unavailable_exception(struct pt_regs *regs) return; } #endif -#ifdef CONFIG_PPC32 - { - static int kernel_altivec_count; - - /* The kernel has executed an altivec instruction without - first enabling altivec. Whinge but let it do it. */ - if (++kernel_altivec_count < 10) - printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", - current, regs->nip); - regs->msr |= MSR_VEC; - } -#else printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); -#endif } #ifdef CONFIG_PPC64 @@ -1024,8 +932,7 @@ void performance_monitor_exception(struct pt_regs *regs) } #endif - -#if defined(CONFIG_PPC32) && defined(CONFIG_8xx) +#ifdef CONFIG_8xx void SoftwareEmulation(struct pt_regs *regs) { extern int do_mathemu(struct pt_regs *); @@ -1054,7 +961,7 @@ void SoftwareEmulation(struct pt_regs *regs) } else emulate_single_step(regs); } -#endif /* defined(CONFIG_PPC32) && defined(CONFIG_8xx) */ +#endif /* CONFIG_8xx */ #ifdef CONFIG_PPC32 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) @@ -1091,29 +998,14 @@ void TAUException(struct pt_regs *regs) void altivec_assist_exception(struct pt_regs *regs) { int err; -#ifdef CONFIG_PPC64 - siginfo_t info; -#endif -#ifdef CONFIG_PPC32 - preempt_disable(); - if (regs->msr & MSR_VEC) - giveup_altivec(current); - preempt_enable(); -#endif if (!user_mode(regs)) { printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" " at %lx\n", regs->nip); - die("Kernel " -#ifdef CONFIG_PPC64 - "VMX/" -#endif - "Altivec assist exception", regs, SIGILL); + die("Kernel VMX/Altivec assist exception", regs, SIGILL); } -#ifdef CONFIG_PPC64 flush_altivec_to_thread(current); -#endif /* CONFIG_PPC64 */ err = emulate_altivec(regs); if (err == 0) { @@ -1124,15 +1016,7 @@ void altivec_assist_exception(struct pt_regs *regs) if (err == -EFAULT) { /* got an error reading the instruction */ -#ifdef CONFIG_PPC32 _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip); -#else - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = SEGV_MAPERR; - info.si_addr = (void __user *) regs->nip; - force_sig_info(SIGSEGV, &info, current); -#endif } else { /* didn't recognize the instruction */ /* XXX quick hack for now: set the non-Java bit in the VSCR */ @@ -1144,7 +1028,6 @@ void altivec_assist_exception(struct pt_regs *regs) } #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_PPC32 #ifdef CONFIG_FSL_BOOKE void CacheLockingException(struct pt_regs *regs, unsigned long address, unsigned long error_code) @@ -1194,9 +1077,7 @@ void SPEFloatingPointException(struct pt_regs *regs) return; } #endif -#endif /* CONFIG_PPC32 */ -#ifdef CONFIG_PPC64 /* * We enter here if we get an unrecoverable exception, that is, one * that happened at a point where the RI (recoverable interrupt) bit @@ -1209,9 +1090,7 @@ void unrecoverable_exception(struct pt_regs *regs) regs->trap, regs->nip); die("Unrecoverable exception", regs, SIGABRT); } -#endif /* CONFIG_PPC64 */ -#ifdef CONFIG_PPC32 #ifdef CONFIG_BOOKE_WDT /* * Default handler for a Watchdog exception, @@ -1230,9 +1109,7 @@ void WatchdogException(struct pt_regs *regs) WatchdogHandler(regs); } #endif -#endif /* CONFIG_PPC32 */ -#ifdef CONFIG_PPC64 /* * We enter here if we discover during exception entry that we are * running in supervisor mode with a userspace value in the stack pointer. @@ -1243,7 +1120,6 @@ void kernel_bad_stack(struct pt_regs *regs) regs->gpr[1], regs->nip); die("Bad kernel stack pointer", regs, SIGABRT); } -#endif void __init trap_init(void) { From c16ff7e44883afc05cbf6fde0e6913bb10c66885 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 13:28:31 +1000 Subject: [PATCH 0221/1940] powerpc: Define a _sdata symbol This is needed by arch/powerpc/mm/mem.c now. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 0587d9c4609d..d0239bf8d4cc 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -107,6 +107,7 @@ SECTIONS #ifdef CONFIG_PPC32 /* Read-write section, merged into data segment: */ . = ALIGN(4096); + _sdata = .; .data : { *(.data) From 05f62a5c049845eab8dfb3aeda55c18a2d4396e3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Oct 2005 13:29:24 +1000 Subject: [PATCH 0222/1940] powerpc: Fix idle.c compile warning This fixes a compile warning when using arch/ppc/kernel/idle.c in a merged (ARCH=powerpc) kernel. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/idle.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index fba29c876b62..0a12fbef7347 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -32,6 +32,7 @@ #include #include #include +#include void default_idle(void) { From 0e5dec478cfff2c29e68d1108ff828fa321adc59 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 6 Oct 2005 09:40:20 -0400 Subject: [PATCH 0223/1940] [libata passthru] add (DRIVER_SENSE << 24) to all check-conditions --- drivers/scsi/libata-scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 75cb685e320b..1b00bc618e15 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -500,7 +500,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) memset(sb, 0, SCSI_SENSE_BUFFERSIZE); - cmd->result = SAM_STAT_CHECK_CONDITION; + cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; /* * Read the controller registers. @@ -575,7 +575,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) memset(sb, 0, SCSI_SENSE_BUFFERSIZE); - cmd->result = SAM_STAT_CHECK_CONDITION; + cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; /* * Read the controller registers. @@ -1638,7 +1638,7 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf, void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq) { DPRINTK("ENTER\n"); - cmd->result = SAM_STAT_CHECK_CONDITION; + cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; cmd->sense_buffer[0] = 0x70; cmd->sense_buffer[2] = ILLEGAL_REQUEST; From 131afd0b748e382c3a00355d3fa245801f929298 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 7 Oct 2005 09:51:05 -0700 Subject: [PATCH 0224/1940] [CIFS] /proc/fs/cifs debug code cleanup and new stats2 These changes to debug code and new stats are helpful in debugging potential tcp performance/configuration problems under cifs. Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 16 ++++++++++++---- fs/cifs/cifsglob.h | 6 +++++- fs/cifs/transport.c | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index f4c6544468ab..785239618d89 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -81,6 +81,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, buf += length; length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION); buf += length; + length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid); + buf += length; length = sprintf(buf, "Servers:"); buf += length; @@ -97,7 +99,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, } else { length = sprintf(buf, - "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t", + "\n%d) Name: %s Domain: %s Mounts: %d OS: %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t", i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse), ses->serverOS, ses->serverNOS, @@ -105,12 +107,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, buf += length; } if(ses->server) { - buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", + buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d", ses->server->tcpStatus, atomic_read(&ses->server->socketUseCount), ses->server->secMode, atomic_read(&ses->server->inFlight)); - + +#ifdef CONFIG_CIFS_STATS2 + buf += sprintf(buf, "\tIn Send: %d In MaxReq Wait: %d", + atomic_read(&ses->server->inSend), + atomic_read(&ses->server->num_waiters)); +#endif + length = sprintf(buf, "\nMIDs:\n"); buf += length; @@ -149,7 +157,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); length = sprintf(buf, - "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d", + "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d", i, tcon->treeName, atomic_read(&tcon->useCount), tcon->nativeFileSystem, diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cd421c76805e..729717281b40 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -123,13 +123,17 @@ struct TCP_Server_Info { struct list_head pending_mid_q; void *Server_NlsInfo; /* BB - placeholder for future NLS info */ unsigned short server_codepage; /* codepage for the server */ - unsigned long ip_address; /* IP addr for the server if known */ + unsigned long ip_address; /* IP addr for the server if known */ enum protocolEnum protocolType; char versionMajor; char versionMinor; unsigned svlocal:1; /* local server or remote */ atomic_t socketUseCount; /* number of open cifs sessions on socket */ atomic_t inFlight; /* number of requests on the wire to server */ +#ifdef CONFIG_CIFS_STATS2 + atomic_t inSend; /* requests trying to send */ + atomic_t num_waiters; /* blocked waiting to get in sendrecv */ +#endif enum statusEnum tcpStatus; /* what we think the status is */ struct semaphore tcpSem; struct task_struct *tsk; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index c86b7077b92f..893a6fef9853 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -307,9 +307,15 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ spin_unlock(&GlobalMid_Lock); +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->num_waiters); +#endif wait_event(ses->server->request_q, atomic_read(&ses->server->inFlight) < cifs_max_pending); +#ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->num_waiters); +#endif spin_lock(&GlobalMid_Lock); } else { if(ses->server->tcpStatus == CifsExiting) { @@ -365,8 +371,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, /* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */ midQ->midState = MID_REQUEST_SUBMITTED; +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->inSend); +#endif rc = smb_send2(ses->server->ssocket, iov, n_vec, (struct sockaddr *) &(ses->server->addr.sockAddr)); +#ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->inSend); +#endif if(rc < 0) { DeleteMidQEntry(midQ); up(&ses->server->tcpSem); @@ -546,9 +558,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ spin_unlock(&GlobalMid_Lock); +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->num_waiters); +#endif wait_event(ses->server->request_q, atomic_read(&ses->server->inFlight) < cifs_max_pending); +#ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->num_waiters); +#endif spin_lock(&GlobalMid_Lock); } else { if(ses->server->tcpStatus == CifsExiting) { @@ -617,8 +635,14 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); midQ->midState = MID_REQUEST_SUBMITTED; +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->inSend); +#endif rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, (struct sockaddr *) &(ses->server->addr.sockAddr)); +#ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->inSend); +#endif if(rc < 0) { DeleteMidQEntry(midQ); up(&ses->server->tcpSem); From 422fa08e538b649a9b80258950d2f8a202f45f19 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 9 Oct 2005 10:49:34 -0400 Subject: [PATCH 0225/1940] [libata passthru] update ATAPI completion for new error handling --- drivers/scsi/libata-scsi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 698203bf4f69..617534b7a25e 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -1933,7 +1933,12 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) - ata_to_sense_error(qc, drv_stat); + /* FIXME: not quite right; we don't want the + * translation of taskfile registers into + * a sense descriptors, since that's only + * correct for ATA, not ATAPI + */ + ata_gen_ata_desc_sense(qc); else if (unlikely(drv_stat & ATA_ERR)) { DPRINTK("request check condition\n"); From b5bbeb23732196558222a2827092f5b7be8a7945 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 14:01:07 +1000 Subject: [PATCH 0226/1940] powerpc: Use SPRN_xxx rather than xxx for SPR numbers This changes symbols like HID0, SPRG3, SRR0, SRR1 etc. that refer to special purpose registers to SPRN_HID0, SPRN_SPRG3, etc. Using the SPRN_ symbols clutters the namespace less, and the forthcoming merge of asm/processor.h and asm/reg.h is going to remove the non-SPRN_ versions. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head_64.S | 196 +++++++++++++++++----------------- arch/ppc64/kernel/pmc.c | 4 +- 2 files changed, 100 insertions(+), 100 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a36ee6ecbaea..7889ff8473b9 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -201,22 +201,22 @@ exception_marker: #define EX_CCR 60 #define EXCEPTION_PROLOG_PSERIES(area, label) \ - mfspr r13,SPRG3; /* get paca address into r13 */ \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r10,area+EX_R10(r13); \ std r11,area+EX_R11(r13); \ std r12,area+EX_R12(r13); \ - mfspr r9,SPRG1; \ + mfspr r9,SPRN_SPRG1; \ std r9,area+EX_R13(r13); \ mfcr r9; \ clrrdi r12,r13,32; /* get high part of &label */ \ mfmsr r10; \ - mfspr r11,SRR0; /* save SRR0 */ \ + mfspr r11,SPRN_SRR0; /* save SRR0 */ \ ori r12,r12,(label)@l; /* virt addr of handler */ \ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ - mtspr SRR0,r12; \ - mfspr r12,SRR1; /* and SRR1 */ \ - mtspr SRR1,r10; \ + mtspr SPRN_SRR0,r12; \ + mfspr r12,SPRN_SRR1; /* and SRR1 */ \ + mtspr SPRN_SRR1,r10; \ rfid; \ b . /* prevent speculative execution */ @@ -225,12 +225,12 @@ exception_marker: * This code runs with relocation on. */ #define EXCEPTION_PROLOG_ISERIES_1(area) \ - mfspr r13,SPRG3; /* get paca address into r13 */ \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r10,area+EX_R10(r13); \ std r11,area+EX_R11(r13); \ std r12,area+EX_R12(r13); \ - mfspr r9,SPRG1; \ + mfspr r9,SPRN_SPRG1; \ std r9,area+EX_R13(r13); \ mfcr r9 @@ -283,7 +283,7 @@ exception_marker: std r9,_LINK(r1); \ mfctr r10; /* save CTR in stackframe */ \ std r10,_CTR(r1); \ - mfspr r11,XER; /* save XER in stackframe */ \ + mfspr r11,SPRN_XER; /* save XER in stackframe */ \ std r11,_XER(r1); \ li r9,(n)+1; \ std r9,_TRAP(r1); /* set trap number */ \ @@ -300,7 +300,7 @@ exception_marker: .globl label##_pSeries; \ label##_pSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) @@ -308,7 +308,7 @@ label##_pSeries: \ .globl label##_iSeries; \ label##_iSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(area); \ EXCEPTION_PROLOG_ISERIES_2; \ @@ -318,7 +318,7 @@ label##_iSeries: \ .globl label##_iSeries; \ label##_iSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ lbz r10,PACAPROCENABLED(r13); \ @@ -388,7 +388,7 @@ __start_interrupts: . = 0x200 _machine_check_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ RUNLATCH_ON(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) @@ -396,18 +396,18 @@ _machine_check_pSeries: .globl data_access_pSeries data_access_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 BEGIN_FTR_SECTION - mtspr SPRG2,r12 - mfspr r13,DAR - mfspr r12,DSISR + mtspr SPRN_SPRG2,r12 + mfspr r13,SPRN_DAR + mfspr r12,SPRN_DSISR srdi r13,r13,60 rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c beq .do_stab_bolted_pSeries mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) @@ -415,19 +415,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) .globl data_access_slb_pSeries data_access_slb_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 RUNLATCH_ON(r13) - mfspr r13,SPRG3 /* get paca address into r13 */ + mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) std r11,PACA_EXSLB+EX_R11(r13) std r12,PACA_EXSLB+EX_R12(r13) std r3,PACA_EXSLB+EX_R3(r13) - mfspr r9,SPRG1 + mfspr r9,SPRN_SPRG1 std r9,PACA_EXSLB+EX_R13(r13) mfcr r9 - mfspr r12,SRR1 /* and SRR1 */ - mfspr r3,DAR + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mfspr r3,SPRN_DAR b .do_slb_miss /* Rel. branch works in real mode */ STD_EXCEPTION_PSERIES(0x400, instruction_access) @@ -436,19 +436,19 @@ data_access_slb_pSeries: .globl instruction_access_slb_pSeries instruction_access_slb_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 RUNLATCH_ON(r13) - mfspr r13,SPRG3 /* get paca address into r13 */ + mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) std r11,PACA_EXSLB+EX_R11(r13) std r12,PACA_EXSLB+EX_R12(r13) std r3,PACA_EXSLB+EX_R3(r13) - mfspr r9,SPRG1 + mfspr r9,SPRN_SPRG1 std r9,PACA_EXSLB+EX_R13(r13) mfcr r9 - mfspr r12,SRR1 /* and SRR1 */ - mfspr r3,SRR0 /* SRR0 is faulting address */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ b .do_slb_miss /* Rel. branch works in real mode */ STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) @@ -466,15 +466,15 @@ system_call_pSeries: RUNLATCH_ON(r9) mr r9,r13 mfmsr r10 - mfspr r13,SPRG3 - mfspr r11,SRR0 + mfspr r13,SPRN_SPRG3 + mfspr r11,SPRN_SRR0 clrrdi r12,r13,32 oris r12,r12,system_call_common@h ori r12,r12,system_call_common@l - mtspr SRR0,r12 + mtspr SPRN_SRR0,r12 ori r10,r10,MSR_IR|MSR_DR|MSR_RI - mfspr r12,SRR1 - mtspr SRR1,r10 + mfspr r12,SPRN_SRR1 + mtspr SPRN_SRR1,r10 rfid b . /* prevent speculative execution */ @@ -504,25 +504,25 @@ system_call_pSeries: .align 7 _GLOBAL(do_stab_bolted_pSeries) mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) /* * Vectors for the FWNMI option. Share common code. */ - .globl system_reset_fwnmi + .globl system_reset_fwnmi system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - .globl machine_check_fwnmi + .globl machine_check_fwnmi machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ @@ -531,18 +531,18 @@ machine_check_fwnmi: .globl data_access_iSeries data_access_iSeries: - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 BEGIN_FTR_SECTION - mtspr SPRG2,r12 - mfspr r13,DAR - mfspr r12,DSISR + mtspr SPRN_SPRG2,r12 + mfspr r13,SPRN_DAR + mfspr r12,SPRN_DSISR srdi r13,r13,60 rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c beq .do_stab_bolted_iSeries mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) EXCEPTION_PROLOG_ISERIES_2 @@ -550,25 +550,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) .do_stab_bolted_iSeries: mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) EXCEPTION_PROLOG_ISERIES_2 b .do_stab_bolted .globl data_access_slb_iSeries data_access_slb_iSeries: - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) std r3,PACA_EXSLB+EX_R3(r13) ld r12,PACALPPACA+LPPACASRR1(r13) - mfspr r3,DAR + mfspr r3,SPRN_DAR b .do_slb_miss STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) .globl instruction_access_slb_iSeries instruction_access_slb_iSeries: - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) std r3,PACA_EXSLB+EX_R3(r13) ld r12,PACALPPACA+LPPACASRR1(r13) @@ -586,7 +586,7 @@ instruction_access_slb_iSeries: .globl system_call_iSeries system_call_iSeries: mr r9,r13 - mfspr r13,SPRG3 + mfspr r13,SPRN_SPRG3 EXCEPTION_PROLOG_ISERIES_2 b system_call_common @@ -596,7 +596,7 @@ system_call_iSeries: .globl system_reset_iSeries system_reset_iSeries: - mfspr r13,SPRG3 /* Get paca address */ + mfspr r13,SPRN_SPRG3 /* Get paca address */ mfmsr r24 ori r24,r24,MSR_RI mtmsrd r24 /* RI on */ @@ -639,7 +639,7 @@ iSeries_secondary_smp_loop: #endif /* CONFIG_SMP */ li r0,-1 /* r0=-1 indicates a Hypervisor call */ sc /* Invoke the hypervisor via a system call */ - mfspr r13,SPRG3 /* Put r13 back ???? */ + mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */ b 1b /* If SMP not configured, secondaries * loop forever */ @@ -656,8 +656,8 @@ hardware_interrupt_iSeries_masked: mtcrf 0x80,r9 /* Restore regs */ ld r11,PACALPPACA+LPPACASRR0(r13) ld r12,PACALPPACA+LPPACASRR1(r13) - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 ld r9,PACA_EXGEN+EX_R9(r13) ld r10,PACA_EXGEN+EX_R10(r13) ld r11,PACA_EXGEN+EX_R11(r13) @@ -713,8 +713,8 @@ bad_stack: std r10,GPR1(r1) std r11,_NIP(r1) std r12,_MSR(r1) - mfspr r11,DAR - mfspr r12,DSISR + mfspr r11,SPRN_DAR + mfspr r12,SPRN_DSISR std r11,_DAR(r1) std r12,_DSISR(r1) mflr r10 @@ -766,8 +766,8 @@ fast_exception_return: clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ mtmsrd r10,1 - mtspr SRR1,r12 - mtspr SRR0,r11 + mtspr SPRN_SRR1,r12 + mtspr SPRN_SRR0,r11 REST_4GPRS(10, r1) ld r1,GPR1(r1) rfid @@ -788,9 +788,9 @@ unrecov_fer: .globl data_access_common data_access_common: RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */ - mfspr r10,DAR + mfspr r10,SPRN_DAR std r10,PACA_EXGEN+EX_DAR(r13) - mfspr r10,DSISR + mfspr r10,SPRN_DSISR stw r10,PACA_EXGEN+EX_DSISR(r13) EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) ld r3,PACA_EXGEN+EX_DAR(r13) @@ -821,9 +821,9 @@ hardware_interrupt_entry: .align 7 .globl alignment_common alignment_common: - mfspr r10,DAR + mfspr r10,SPRN_DAR std r10,PACA_EXGEN+EX_DAR(r13) - mfspr r10,DSISR + mfspr r10,SPRN_DSISR stw r10,PACA_EXGEN+EX_DSISR(r13) EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) ld r3,PACA_EXGEN+EX_DAR(r13) @@ -1064,7 +1064,7 @@ _GLOBAL(do_stab_bolted) /* Hash to the primary group */ ld r10,PACASTABVIRT(r13) - mfspr r11,DAR + mfspr r11,SPRN_DAR srdi r11,r11,28 rldimi r10,r11,7,52 /* r10 = first ste of the group */ @@ -1106,7 +1106,7 @@ _GLOBAL(do_stab_bolted) 2: std r9,8(r10) /* Store the vsid part of the ste */ eieio - mfspr r11,DAR /* Get the new esid */ + mfspr r11,SPRN_DAR /* Get the new esid */ clrrdi r11,r11,28 /* Permits a full 32b of ESID */ ori r11,r11,0x90 /* Turn on valid and kp */ std r11,0(r10) /* Put new entry back into the stab */ @@ -1126,8 +1126,8 @@ _GLOBAL(do_stab_bolted) clrrdi r10,r10,2 mtmsrd r10,1 - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 ld r9,PACA_EXSLB+EX_R9(r13) ld r10,PACA_EXSLB+EX_R10(r13) ld r11,PACA_EXSLB+EX_R11(r13) @@ -1173,8 +1173,8 @@ _GLOBAL(do_slb_miss) .machine pop #ifdef CONFIG_PPC_ISERIES - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 #endif /* CONFIG_PPC_ISERIES */ ld r9,PACA_EXSLB+EX_R9(r13) ld r10,PACA_EXSLB+EX_R10(r13) @@ -1260,7 +1260,7 @@ _GLOBAL(pSeries_secondary_smp_init) mr r3,r24 /* not found, copy phys to r3 */ b .kexec_wait /* next kernel might do better */ -2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ +2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 3: HMT_LOW @@ -1531,7 +1531,7 @@ _GLOBAL(pmac_secondary_start) LOADADDR(r4, paca) /* Get base vaddr of paca array */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r4 /* for this processor. */ - mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) @@ -1566,7 +1566,7 @@ _GLOBAL(__secondary_start) /* Initialize the page table pointer register. */ LOADADDR(r6,_SDR1) ld r6,0(r6) /* get the value of _SDR1 */ - mtspr SDR1,r6 /* set the htab location */ + mtspr SPRN_SDR1,r6 /* set the htab location */ #endif /* Initialize the first segment table (or SLB) entry */ ld r3,PACASTABVIRT(r13) /* get addr of segment table */ @@ -1595,7 +1595,7 @@ _GLOBAL(__secondary_start) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ beq 98f /* branch if result is 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ beq 97f @@ -1619,8 +1619,8 @@ _GLOBAL(__secondary_start) #ifdef DO_SOFT_DISABLE ori r4,r4,MSR_EE #endif - mtspr SRR0,r3 - mtspr SRR1,r4 + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ @@ -1682,7 +1682,7 @@ _STATIC(start_here_multiplatform) #ifdef CONFIG_HMT /* Start up the second thread on cpu 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x34 /* Pulsar */ beq 90f @@ -1742,7 +1742,7 @@ _STATIC(start_here_multiplatform) mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ sub r13,r13,r26 /* convert to physical addr */ - mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ + mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1759,7 +1759,7 @@ _STATIC(start_here_multiplatform) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ beq 98f /* branch if result is 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ beq 97f @@ -1783,12 +1783,12 @@ _STATIC(start_here_multiplatform) LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ - mtspr SDR1,r6 /* set the htab location */ + mtspr SPRN_SDR1,r6 /* set the htab location */ 98: LOADADDR(r3,.start_here_common) SET_REG_TO_CONST(r4, MSR_KERNEL) - mtspr SRR0,r3 - mtspr SRR1,r4 + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -1819,7 +1819,7 @@ _STATIC(start_here_common) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ - mtspr SPRG3,r13 + mtspr SPRN_SPRG3,r13 /* ptr to current */ LOADADDR(r4,init_task) @@ -1846,7 +1846,7 @@ _STATIC(start_here_common) _GLOBAL(hmt_init) #ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) - mfspr r7,PVR + mfspr r7,SPRN_PVR srwi r7,r7,16 cmpwi r7,0x34 /* Pulsar */ beq 90f @@ -1855,10 +1855,10 @@ _GLOBAL(hmt_init) cmpwi r7,0x37 /* SStar */ beq 91f b 101f -90: mfspr r6,PIR +90: mfspr r6,SPRN_PIR andi. r6,r6,0x1f b 92f -91: mfspr r6,PIR +91: mfspr r6,SPRN_PIR andi. r6,r6,0x3ff 92: sldi r4,r24,3 stwx r6,r5,r4 @@ -1869,8 +1869,8 @@ __hmt_secondary_hold: LOADADDR(r5, hmt_thread_data) clrldi r5,r5,4 li r7,0 - mfspr r6,PIR - mfspr r8,PVR + mfspr r6,SPRN_PIR + mfspr r8,SPRN_PVR srwi r8,r8,16 cmpwi r8,0x34 bne 93f @@ -1896,19 +1896,19 @@ __hmt_secondary_hold: _GLOBAL(hmt_start_secondary) LOADADDR(r4,__hmt_secondary_hold) clrldi r4,r4,4 - mtspr NIADORM, r4 - mfspr r4, MSRDORM + mtspr SPRN_NIADORM, r4 + mfspr r4, SPRN_MSRDORM li r5, -65 and r4, r4, r5 - mtspr MSRDORM, r4 + mtspr SPRN_MSRDORM, r4 lis r4,0xffef ori r4,r4,0x7403 - mtspr TSC, r4 + mtspr SPRN_TSC, r4 li r4,0x1f4 - mtspr TST, r4 - mfspr r4, HID0 + mtspr SPRN_TST, r4 + mfspr r4, SPRN_HID0 ori r4, r4, 0x1 - mtspr HID0, r4 + mtspr SPRN_HID0, r4 mfspr r4, SPRN_CTRLF oris r4, r4, 0x40 mtspr SPRN_CTRLT, r4 diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c index 63d9481c3ec2..944d7df7935f 100644 --- a/arch/ppc64/kernel/pmc.c +++ b/arch/ppc64/kernel/pmc.c @@ -70,7 +70,7 @@ void power4_enable_pmcs(void) { unsigned long hid0; - hid0 = mfspr(HID0); + hid0 = mfspr(SPRN_HID0); hid0 |= 1UL << (63 - 20); /* POWER4 requires the following sequence */ @@ -83,6 +83,6 @@ void power4_enable_pmcs(void) "mfspr %0, %1\n" "mfspr %0, %1\n" "mfspr %0, %1\n" - "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): + "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0): "memory"); } From b60fc8bbd2d0ea2a9b1fc7271d521fcf47f27bfd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 14:14:55 +1000 Subject: [PATCH 0227/1940] powerpc: Make some #includes explicit. In preparation for merging processor.h, this adds some explicit but won't be after the merge. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/irq.c | 1 + arch/ppc/kernel/pci.c | 1 + arch/ppc/kernel/smp.c | 1 + arch/ppc64/kernel/rtas.c | 1 + arch/ppc64/kernel/vdso64/sigtramp.S | 1 + 5 files changed, 5 insertions(+) diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 8843f3af230f..772e428aaa59 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -57,6 +57,7 @@ #include #include #include +#include #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index b5cf52f5909e..6600fd485b50 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -21,6 +21,7 @@ #include #include #include +#include #undef DEBUG diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index a8cc96b0d332..801c793fdec8 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -34,6 +34,7 @@ #include #include #include +#include volatile int smp_commenced; int smp_tb_synchronized; diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c index 5e8eb33b8e54..36adab591bd3 100644 --- a/arch/ppc64/kernel/rtas.c +++ b/arch/ppc64/kernel/rtas.c @@ -30,6 +30,7 @@ #include #include #include +#include struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; diff --git a/arch/ppc64/kernel/vdso64/sigtramp.S b/arch/ppc64/kernel/vdso64/sigtramp.S index 8ae8f205e470..31b604ab56de 100644 --- a/arch/ppc64/kernel/vdso64/sigtramp.S +++ b/arch/ppc64/kernel/vdso64/sigtramp.S @@ -15,6 +15,7 @@ #include #include #include +#include /* XXX for __SIGNAL_FRAMESIZE */ .text From 9f04b9e327c495f8ddbf89c08da6cbe626e1b1b3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 14:19:43 +1000 Subject: [PATCH 0228/1940] powerpc: Merged processor.h. This adds register definitions from the ppc64 processor.h to reg.h, and makes a single merged processor.h. I moved __is_processor from the ppc64 system.h to the merged reg.h along with the PVR register constants. Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/processor.h | 189 +++++-- include/asm-powerpc/reg.h | 281 +++++++-- include/asm-ppc64/processor.h | 567 ------------------- include/asm-ppc64/system.h | 7 - 4 files changed, 355 insertions(+), 689 deletions(-) rename include/{asm-ppc => asm-powerpc}/processor.h (51%) delete mode 100644 include/asm-ppc64/processor.h diff --git a/include/asm-ppc/processor.h b/include/asm-powerpc/processor.h similarity index 51% rename from include/asm-ppc/processor.h rename to include/asm-powerpc/processor.h index b05b5d9cae20..9592f533e058 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-powerpc/processor.h @@ -1,21 +1,28 @@ -#ifdef __KERNEL__ -#ifndef __ASM_PPC_PROCESSOR_H -#define __ASM_PPC_PROCESSOR_H +#ifndef _ASM_POWERPC_PROCESSOR_H +#define _ASM_POWERPC_PROCESSOR_H /* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). + * Copyright (C) 2001 PPC 64 Team, IBM Corp + * + * 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. */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) #include -#include - -#include -#include -#include #include +#ifndef __ASSEMBLY__ +#include +#include +#include +#ifdef CONFIG_PPC64 +#include +#endif + +#ifdef CONFIG_PPC32 +/* 32-bit platform types */ /* We only need to define a new _MACH_xxx for machines which are part of * a configuration which supports more than one type of different machine. * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. @@ -36,20 +43,6 @@ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ #define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ -#define _GLOBAL(n)\ - .stabs __stringify(n:F-1),N_FUN,0,0,n;\ - .globl n;\ -n: - -/* - * this is the minimum allowable io space due to the location - * of the io areas on prep (first one at 0x80000000) but - * as soon as I get around to remapping the io areas with the BATs - * to match the mac we can raise this. -- Cort - */ -#define TASK_SIZE (CONFIG_TASK_SIZE) - -#ifndef __ASSEMBLY__ #ifdef CONFIG_PPC_MULTIPLATFORM extern int _machine; @@ -67,17 +60,49 @@ extern unsigned char ucBoardRevMaj, ucBoardRevMin; #else #define _machine 0 #endif /* CONFIG_PPC_MULTIPLATFORM */ +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 +/* Platforms supported by PPC64 */ +#define PLATFORM_PSERIES 0x0100 +#define PLATFORM_PSERIES_LPAR 0x0101 +#define PLATFORM_ISERIES_LPAR 0x0201 +#define PLATFORM_LPAR 0x0001 +#define PLATFORM_POWERMAC 0x0400 +#define PLATFORM_MAPLE 0x0500 +#define PLATFORM_BPA 0x1000 + +/* Compatibility with drivers coming from PPC32 world */ +#define _machine (systemcfg->platform) +#define _MACH_Pmac PLATFORM_POWERMAC +#endif + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +/* Macros for adjusting thread priority (hardware multi-threading) */ +#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") +#define HMT_low() asm volatile("or 1,1,1 # low priority") +#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") +#define HMT_medium() asm volatile("or 2,2,2 # medium priority") +#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") +#define HMT_high() asm volatile("or 3,3,3 # high priority") + +#ifdef __KERNEL__ + +extern int have_of; struct task_struct; -void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); +void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); void release_thread(struct task_struct *); /* Prepare to copy thread state - unlazy all lazy status */ extern void prepare_to_copy(struct task_struct *tsk); -/* - * Create a new kernel thread. - */ +/* Create a new kernel thread. */ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); /* Lazy FPU handling on uni-processor */ @@ -85,10 +110,37 @@ extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_altivec; extern struct task_struct *last_task_used_spe; +#ifdef CONFIG_PPC32 +#define TASK_SIZE (CONFIG_TASK_SIZE) + /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 8 * 3) +#endif + +#ifdef CONFIG_PPC64 +/* 64-bit user address space is 44-bits (16TB user VM) */ +#define TASK_SIZE_USER64 (0x0000100000000000UL) + +/* + * 32-bit user address space is 4GB - 1 page + * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT + */ +#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE)) + +#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ + TASK_SIZE_USER32 : TASK_SIZE_USER64) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4)) +#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4)) + +#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)) ? \ + TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) +#endif typedef struct { unsigned long seg; @@ -96,18 +148,31 @@ typedef struct { struct thread_struct { unsigned long ksp; /* Kernel stack pointer */ +#ifdef CONFIG_PPC64 + unsigned long ksp_vsid; +#endif struct pt_regs *regs; /* Pointer to saved register state */ mm_segment_t fs; /* for get_fs() validation */ +#ifdef CONFIG_PPC32 void *pgdir; /* root of page-table tree */ - int fpexc_mode; /* floating-point exception mode */ signed long last_syscall; +#endif #if defined(CONFIG_4xx) || defined (CONFIG_BOOKE) unsigned long dbcr0; /* debug control register values */ unsigned long dbcr1; #endif double fpr[32]; /* Complete floating point set */ +#ifdef CONFIG_PPC32 unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ +#endif unsigned long fpscr; /* Floating point status */ + int fpexc_mode; /* floating-point exception mode */ +#ifdef CONFIG_PPC64 + unsigned long start_tb; /* Start purr when proc switched in */ + unsigned long accum_tb; /* Total accumilated purr for process */ + unsigned long vdso_base; /* base of the vDSO library */ +#endif + unsigned long dabr; /* Data address breakpoint register */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ vector128 vr[32] __attribute((aligned(16))); @@ -128,51 +193,58 @@ struct thread_struct { #define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) + +#ifdef CONFIG_PPC32 #define INIT_THREAD { \ .ksp = INIT_SP, \ .fs = KERNEL_DS, \ .pgdir = swapper_pg_dir, \ .fpexc_mode = MSR_FE0 | MSR_FE1, \ } +#else +#define INIT_THREAD { \ + .ksp = INIT_SP, \ + .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ + .fs = KERNEL_DS, \ + .fpr = {0}, \ + .fpscr = 0, \ + .fpexc_mode = MSR_FE0|MSR_FE1, \ +} +#endif /* * Return saved PC of a blocked thread. For now, this is the "user" PC */ -#define thread_saved_pc(tsk) \ - ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) +#define thread_saved_pc(tsk) \ + ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) unsigned long get_wchan(struct task_struct *p); -#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) -#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) +#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) +#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) /* Get/set floating-point exception mode */ -#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr)) -#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val)) +#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr)) +#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val)) extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr); extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val); -static inline unsigned int __unpack_fe01(unsigned int msr_bits) +static inline unsigned int __unpack_fe01(unsigned long msr_bits) { return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); } -static inline unsigned int __pack_fe01(unsigned int fpmode) +static inline unsigned long __pack_fe01(unsigned int fpmode) { return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1); } -/* in process.c - for early bootup debug -- Cort */ -int ll_printk(const char *, ...); -void ll_puts(const char *); - -/* In misc.c */ -void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); - -#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac) - +#ifdef CONFIG_PPC64 +#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0) +#else #define cpu_relax() barrier() +#endif /* * Prefetch macros. @@ -181,21 +253,28 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #define ARCH_HAS_PREFETCHW #define ARCH_HAS_SPINLOCK_PREFETCH -extern inline void prefetch(const void *x) +static inline void prefetch(const void *x) { - __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x)); + if (unlikely(!x)) + return; + + __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x)); } -extern inline void prefetchw(const void *x) +static inline void prefetchw(const void *x) { - __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x)); + if (unlikely(!x)) + return; + + __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x)); } #define spin_lock_prefetch(x) prefetchw(x) -extern int emulate_altivec(struct pt_regs *regs); +#ifdef CONFIG_PPC64 +#define HAVE_ARCH_PICK_MMAP_LAYOUT +#endif -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_PPC_PROCESSOR_H */ #endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_POWERPC_PROCESSOR_H */ diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 1402a2dedffb..ff619630dff9 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -6,53 +6,95 @@ * Implementations of the PowerPC Architecture (a.k.a. Green Book) here. */ -#ifndef _ASM_POWERPC_REGS_H -#define _ASM_POWERPC_REGS_H +#ifndef _ASM_POWERPC_REG_H +#define _ASM_POWERPC_REG_H #ifdef __KERNEL__ #include +#include /* Pickup Book E specific registers. */ #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) #include #endif -/* Machine State Register (MSR) Fields */ -#define MSR_SF (1<<63) -#define MSR_ISF (1<<61) -#define MSR_VEC (1<<25) /* Enable AltiVec */ -#define MSR_POW (1<<18) /* Enable Power Management */ -#define MSR_WE (1<<18) /* Wait State Enable */ -#define MSR_TGPR (1<<17) /* TLB Update registers in use */ -#define MSR_CE (1<<17) /* Critical Interrupt Enable */ -#define MSR_ILE (1<<16) /* Interrupt Little Endian */ -#define MSR_EE (1<<15) /* External Interrupt Enable */ -#define MSR_PR (1<<14) /* Problem State / Privilege Level */ -#define MSR_FP (1<<13) /* Floating Point enable */ -#define MSR_ME (1<<12) /* Machine Check Enable */ -#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ -#define MSR_SE (1<<10) /* Single Step */ -#define MSR_BE (1<<9) /* Branch Trace */ -#define MSR_DE (1<<9) /* Debug Exception Enable */ -#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ -#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ -#define MSR_IR (1<<5) /* Instruction Relocate */ -#define MSR_DR (1<<4) /* Data Relocate */ -#define MSR_PE (1<<3) /* Protection Enable */ -#define MSR_PX (1<<2) /* Protection Exclusive Mode */ -#define MSR_RI (1<<1) /* Recoverable Exception */ -#define MSR_LE (1<<0) /* Little Endian */ +#define MSR_SF_LG 63 /* Enable 64 bit mode */ +#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ +#define MSR_HV_LG 60 /* Hypervisor state */ +#define MSR_VEC_LG 25 /* Enable AltiVec */ +#define MSR_POW_LG 18 /* Enable Power Management */ +#define MSR_WE_LG 18 /* Wait State Enable */ +#define MSR_TGPR_LG 17 /* TLB Update registers in use */ +#define MSR_CE_LG 17 /* Critical Interrupt Enable */ +#define MSR_ILE_LG 16 /* Interrupt Little Endian */ +#define MSR_EE_LG 15 /* External Interrupt Enable */ +#define MSR_PR_LG 14 /* Problem State / Privilege Level */ +#define MSR_FP_LG 13 /* Floating Point enable */ +#define MSR_ME_LG 12 /* Machine Check Enable */ +#define MSR_FE0_LG 11 /* Floating Exception mode 0 */ +#define MSR_SE_LG 10 /* Single Step */ +#define MSR_BE_LG 9 /* Branch Trace */ +#define MSR_DE_LG 9 /* Debug Exception Enable */ +#define MSR_FE1_LG 8 /* Floating Exception mode 1 */ +#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */ +#define MSR_IR_LG 5 /* Instruction Relocate */ +#define MSR_DR_LG 4 /* Data Relocate */ +#define MSR_PE_LG 3 /* Protection Enable */ +#define MSR_PX_LG 2 /* Protection Exclusive Mode */ +#define MSR_PMM_LG 2 /* Performance monitor */ +#define MSR_RI_LG 1 /* Recoverable Exception */ +#define MSR_LE_LG 0 /* Little Endian */ +#ifdef __ASSEMBLY__ +#define __MASK(X) (1<<(X)) +#else +#define __MASK(X) (1UL<<(X)) +#endif + +#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ +#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ +#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ +#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ +#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ +#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ +#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */ +#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */ +#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */ +#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */ +#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */ +#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */ +#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */ +#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */ +#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */ +#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */ +#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */ +#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */ +#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */ +#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */ +#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */ +#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */ +#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */ +#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */ +#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */ +#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */ + +#ifdef CONFIG_PPC64 +#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF +#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV + +#define MSR_USER32 MSR_ | MSR_PR | MSR_EE +#define MSR_USER64 MSR_USER32 | MSR_SF + +#else /* 32-bit */ /* Default MSR for kernel mode. */ #ifdef CONFIG_APUS_FAST_EXCEPT #define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR) -#endif - -#ifndef MSR_KERNEL +#else #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) #endif #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) +#endif /* Floating Point Status and Control Register (FPSCR) Fields */ #define FPSCR_FX 0x80000000 /* FPU exception summary */ @@ -85,6 +127,9 @@ /* Special Purpose Registers (SPRNs)*/ #define SPRN_CTR 0x009 /* Count Register */ +#define SPRN_CTRLF 0x088 +#define SPRN_CTRLT 0x098 +#define CTRL_RUNLATCH 0x1 #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2) #define SPRN_DAR 0x013 /* Data Address Register */ @@ -193,6 +238,16 @@ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #define SPRN_HID4 0x3F4 /* 970 HID4 */ #define SPRN_HID5 0x3F6 /* 970 HID5 */ +#define SPRN_HID6 0x3F9 /* BE HID 6 */ +#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ +#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */ +#define SPRN_TSCR 0x399 /* Thread switch control on BE */ +#define SPRN_TTR 0x39A /* Thread switch timeout on BE */ +#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */ +#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */ +#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */ +#define SPRN_TSC 0x3FD /* Thread switch control on others */ +#define SPRN_TST 0x3FC /* Thread switch timeout on others */ #if !defined(SPRN_IAC1) && !defined(SPRN_IAC2) #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ #define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ @@ -276,22 +331,18 @@ #define L3CR_L3DO 0x00000040 /* L3 data only mode */ #define L3CR_PMEN 0x00000004 /* L3 private memory enable */ #define L3CR_PMSIZ 0x00000001 /* L3 private memory size */ + #define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */ #define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */ #define SPRN_LDSTCR 0x3f8 /* Load/Store control register */ #define SPRN_LDSTDB 0x3f4 /* */ #define SPRN_LR 0x008 /* Link Register */ -#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ -#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ #ifndef SPRN_PIR #define SPRN_PIR 0x3FF /* Processor Identification Register */ #endif -#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ -#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ -#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ -#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ #define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ #define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ +#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */ #define SPRN_PVR 0x11F /* Processor Version Register */ #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ @@ -333,6 +384,52 @@ #define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ +/* Performance monitor SPRs */ +#ifdef CONFIG_PPC64 +#define SPRN_MMCR0 795 +#define MMCR0_FC 0x80000000UL /* freeze counters */ +#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */ +#define MMCR0_KERNEL_DISABLE MMCR0_FCS +#define MMCR0_FCP 0x20000000UL /* freeze in problem state */ +#define MMCR0_PROBLEM_DISABLE MMCR0_FCP +#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */ +#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */ +#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */ +#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */ +#define MMCR0_TBEE 0x00400000UL /* time base exception enable */ +#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/ +#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/ +#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */ +#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */ +#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */ +#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */ +#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */ +#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */ +#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ +#define SPRN_MMCR1 798 +#define SPRN_MMCRA 0x312 +#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */ +#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */ +#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */ +#define SPRN_PMC1 787 +#define SPRN_PMC2 788 +#define SPRN_PMC3 789 +#define SPRN_PMC4 790 +#define SPRN_PMC5 791 +#define SPRN_PMC6 792 +#define SPRN_PMC7 793 +#define SPRN_PMC8 794 +#define SPRN_SIAR 780 +#define SPRN_SDAR 781 + +#else /* 32-bit */ +#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ +#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ +#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ +#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ +#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ +#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ + /* Bit definitions for MMCR0 and PMC1 / PMC2. */ #define MMCR0_PMC1_CYCLES (1 << 7) #define MMCR0_PMC1_ICACHEMISS (5 << 7) @@ -342,14 +439,15 @@ #define MMCR0_PMC2_ITLB 0x7 #define MMCR0_PMC2_LOADMISSTIME 0x5 #define MMCR0_PMXE (1 << 26) - -/* Processor Version Register */ +#endif /* Processor Version Register (PVR) field extraction */ #define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ #define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ +#define __is_processor(pv) (PVR_VER(mfspr(SPRN_PVR)) == (pv)) + /* * IBM has further subdivided the standard PowerPC 16-bit version and * revision subfields of the PVR for the PowerPC 403s into the following: @@ -405,42 +503,105 @@ #define PVR_8245 0x80811014 #define PVR_8260 PVR_8240 -#if 0 -/* Segment Registers */ -#define SR0 0 -#define SR1 1 -#define SR2 2 -#define SR3 3 -#define SR4 4 -#define SR5 5 -#define SR6 6 -#define SR7 7 -#define SR8 8 -#define SR9 9 -#define SR10 10 -#define SR11 11 -#define SR12 12 -#define SR13 13 -#define SR14 14 -#define SR15 15 -#endif +/* 64-bit processors */ +/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */ +#define PV_NORTHSTAR 0x0033 +#define PV_PULSAR 0x0034 +#define PV_POWER4 0x0035 +#define PV_ICESTAR 0x0036 +#define PV_SSTAR 0x0037 +#define PV_POWER4p 0x0038 +#define PV_970 0x0039 +#define PV_POWER5 0x003A +#define PV_POWER5p 0x003B +#define PV_970FX 0x003C +#define PV_630 0x0040 +#define PV_630p 0x0041 +#define PV_970MP 0x0044 +#define PV_BE 0x0070 + +/* + * Number of entries in the SLB. If this ever changes we should handle + * it with a use a cpu feature fixup. + */ +#define SLB_NUM_ENTRIES 64 /* Macros for setting and retrieving special purpose registers */ #ifndef __ASSEMBLY__ -#define mfmsr() ({unsigned int rval; \ +#define mfmsr() ({unsigned long rval; \ asm volatile("mfmsr %0" : "=r" (rval)); rval;}) +#ifdef CONFIG_PPC64 +#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ + : : "r" (v)) +#define mtmsrd(v) __mtmsrd((v), 0) +#else #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) +#endif -#define mfspr(rn) ({unsigned int rval; \ +#define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ : "=r" (rval)); rval;}) #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) +#define mftb() ({unsigned long rval; \ + asm volatile("mftb %0" : "=r" (rval)); rval;}) +#define mftbl() ({unsigned long rval; \ + asm volatile("mftbl %0" : "=r" (rval)); rval;}) + +#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) +#define mttbu(v) asm volatile("mttbu %0":: "r"(v)) + +#ifdef CONFIG_PPC32 #define mfsrin(v) ({unsigned int rval; \ asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ rval;}) +#endif #define proc_trap() asm volatile("trap") + +#ifdef CONFIG_PPC64 +static inline void ppc64_runlatch_on(void) +{ + unsigned long ctrl; + + if (cpu_has_feature(CPU_FTR_CTRL)) { + ctrl = mfspr(SPRN_CTRLF); + ctrl |= CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } +} + +static inline void ppc64_runlatch_off(void) +{ + unsigned long ctrl; + + if (cpu_has_feature(CPU_FTR_CTRL)) { + ctrl = mfspr(SPRN_CTRLF); + ctrl &= ~CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } +} + +static inline void set_tb(unsigned int upper, unsigned int lower) +{ + mttbl(0); + mttbu(upper); + mttbl(lower); +} +#endif + +#define __get_SP() ({unsigned long sp; \ + asm volatile("mr %0,1": "=r" (sp)); sp;}) + +#else /* __ASSEMBLY__ */ + +#define RUNLATCH_ON(REG) \ +BEGIN_FTR_SECTION \ + mfspr (REG),SPRN_CTRLF; \ + ori (REG),(REG),CTRL_RUNLATCH; \ + mtspr SPRN_CTRLT,(REG); \ +END_FTR_SECTION_IFSET(CPU_FTR_CTRL) + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_REGS_H */ +#endif /* _ASM_POWERPC_REG_H */ diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h deleted file mode 100644 index 6447fbee7d69..000000000000 --- a/include/asm-ppc64/processor.h +++ /dev/null @@ -1,567 +0,0 @@ -#ifndef __ASM_PPC64_PROCESSOR_H -#define __ASM_PPC64_PROCESSOR_H - -/* - * Copyright (C) 2001 PPC 64 Team, IBM Corp - * - * 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. - */ - -#include -#ifndef __ASSEMBLY__ -#include -#include -#include -#include -#endif -#include -#include -#include -#include - -/* Machine State Register (MSR) Fields */ -#define MSR_SF_LG 63 /* Enable 64 bit mode */ -#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ -#define MSR_HV_LG 60 /* Hypervisor state */ -#define MSR_VEC_LG 25 /* Enable AltiVec */ -#define MSR_POW_LG 18 /* Enable Power Management */ -#define MSR_WE_LG 18 /* Wait State Enable */ -#define MSR_TGPR_LG 17 /* TLB Update registers in use */ -#define MSR_CE_LG 17 /* Critical Interrupt Enable */ -#define MSR_ILE_LG 16 /* Interrupt Little Endian */ -#define MSR_EE_LG 15 /* External Interrupt Enable */ -#define MSR_PR_LG 14 /* Problem State / Privilege Level */ -#define MSR_FP_LG 13 /* Floating Point enable */ -#define MSR_ME_LG 12 /* Machine Check Enable */ -#define MSR_FE0_LG 11 /* Floating Exception mode 0 */ -#define MSR_SE_LG 10 /* Single Step */ -#define MSR_BE_LG 9 /* Branch Trace */ -#define MSR_DE_LG 9 /* Debug Exception Enable */ -#define MSR_FE1_LG 8 /* Floating Exception mode 1 */ -#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */ -#define MSR_IR_LG 5 /* Instruction Relocate */ -#define MSR_DR_LG 4 /* Data Relocate */ -#define MSR_PE_LG 3 /* Protection Enable */ -#define MSR_PX_LG 2 /* Protection Exclusive Mode */ -#define MSR_PMM_LG 2 /* Performance monitor */ -#define MSR_RI_LG 1 /* Recoverable Exception */ -#define MSR_LE_LG 0 /* Little Endian */ - -#ifdef __ASSEMBLY__ -#define __MASK(X) (1<<(X)) -#else -#define __MASK(X) (1UL<<(X)) -#endif - -#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ -#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ -#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ -#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ -#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ -#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ -#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */ -#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */ -#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */ -#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */ -#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */ -#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */ -#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */ -#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */ -#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */ -#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */ -#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */ -#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */ -#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */ -#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */ -#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */ -#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */ -#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */ -#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */ -#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */ -#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */ - -#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF -#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV - -#define MSR_USER32 MSR_ | MSR_PR | MSR_EE -#define MSR_USER64 MSR_USER32 | MSR_SF - -/* Floating Point Status and Control Register (FPSCR) Fields */ - -#define FPSCR_FX 0x80000000 /* FPU exception summary */ -#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */ -#define FPSCR_VX 0x20000000 /* Invalid operation summary */ -#define FPSCR_OX 0x10000000 /* Overflow exception summary */ -#define FPSCR_UX 0x08000000 /* Underflow exception summary */ -#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */ -#define FPSCR_XX 0x02000000 /* Inexact exception summary */ -#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */ -#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */ -#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */ -#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */ -#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */ -#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */ -#define FPSCR_FR 0x00040000 /* Fraction rounded */ -#define FPSCR_FI 0x00020000 /* Fraction inexact */ -#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */ -#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */ -#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */ -#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */ -#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */ -#define FPSCR_VE 0x00000080 /* Invalid op exception enable */ -#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */ -#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */ -#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */ -#define FPSCR_XE 0x00000008 /* FP inexact exception enable */ -#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */ -#define FPSCR_RN 0x00000003 /* FPU rounding control */ - -/* Special Purpose Registers (SPRNs)*/ - -#define SPRN_CTR 0x009 /* Count Register */ -#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ -#define DABR_TRANSLATION (1UL << 2) -#define SPRN_DAR 0x013 /* Data Address Register */ -#define SPRN_DEC 0x016 /* Decrement Register */ -#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ -#define DSISR_NOHPTE 0x40000000 /* no translation found */ -#define DSISR_PROTFAULT 0x08000000 /* protection fault */ -#define DSISR_ISSTORE 0x02000000 /* access was a store */ -#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ -#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ -#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ -#define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */ -#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ -#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ -#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */ -#define SPRN_HID4 0x3F4 /* 970 HID4 */ -#define SPRN_HID5 0x3F6 /* 970 HID5 */ -#define SPRN_HID6 0x3F9 /* BE HID 6 */ -#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ -#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */ -#define SPRN_TSCR 0x399 /* Thread switch control on BE */ -#define SPRN_TTR 0x39A /* Thread switch timeout on BE */ -#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */ -#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */ -#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */ -#define SPRN_TSC 0x3FD /* Thread switch control on others */ -#define SPRN_TST 0x3FC /* Thread switch timeout on others */ -#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ -#define SPRN_LR 0x008 /* Link Register */ -#define SPRN_PIR 0x3FF /* Processor Identification Register */ -#define SPRN_PIT 0x3DB /* Programmable Interval Timer */ -#define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */ -#define SPRN_PVR 0x11F /* Processor Version Register */ -#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ -#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ -#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ -#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ -#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ -#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ -#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ -#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ -#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ -#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ -#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ -#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ -#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */ -#define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */ -#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ -#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ -#define SPRN_XER 0x001 /* Fixed Point Exception Register */ -#define SPRN_VRSAVE 0x100 /* Vector save */ -#define SPRN_CTRLF 0x088 -#define SPRN_CTRLT 0x098 -#define CTRL_RUNLATCH 0x1 - -/* Performance monitor SPRs */ -#define SPRN_SIAR 780 -#define SPRN_SDAR 781 -#define SPRN_MMCRA 786 -#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */ -#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */ -#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */ -#define SPRN_PMC1 787 -#define SPRN_PMC2 788 -#define SPRN_PMC3 789 -#define SPRN_PMC4 790 -#define SPRN_PMC5 791 -#define SPRN_PMC6 792 -#define SPRN_PMC7 793 -#define SPRN_PMC8 794 -#define SPRN_MMCR0 795 -#define MMCR0_FC 0x80000000UL /* freeze counters. set to 1 on a perfmon exception */ -#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */ -#define MMCR0_KERNEL_DISABLE MMCR0_FCS -#define MMCR0_FCP 0x20000000UL /* freeze in problem state */ -#define MMCR0_PROBLEM_DISABLE MMCR0_FCP -#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */ -#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */ -#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */ -#define MMCR0_FCECE 0x02000000UL /* freeze counters on enabled condition or event */ -/* time base exception enable */ -#define MMCR0_TBEE 0x00400000UL /* time base exception enable */ -#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/ -#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/ -#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */ -#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */ -#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */ -#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */ -#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */ -#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */ -#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ -#define SPRN_MMCR1 798 - -/* Short-hand versions for a number of the above SPRNs */ - -#define CTR SPRN_CTR /* Counter Register */ -#define DAR SPRN_DAR /* Data Address Register */ -#define DABR SPRN_DABR /* Data Address Breakpoint Register */ -#define DEC SPRN_DEC /* Decrement Register */ -#define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ -#define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ -#define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */ -#define NIADORM SPRN_NIADORM /* NIA Dormant Register */ -#define TSC SPRN_TSC /* Thread switch control */ -#define TST SPRN_TST /* Thread switch timeout */ -#define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ -#define L2CR SPRN_L2CR /* PPC 750 L2 control register */ -#define __LR SPRN_LR -#define PVR SPRN_PVR /* Processor Version */ -#define PIR SPRN_PIR /* Processor ID */ -#define PURR SPRN_PURR /* Processor Utilization of Resource Register */ -#define SDR1 SPRN_SDR1 /* MMU hash base register */ -#define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */ -#define SPR1 SPRN_SPRG1 -#define SPR2 SPRN_SPRG2 -#define SPR3 SPRN_SPRG3 -#define SPRG0 SPRN_SPRG0 -#define SPRG1 SPRN_SPRG1 -#define SPRG2 SPRN_SPRG2 -#define SPRG3 SPRN_SPRG3 -#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */ -#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */ -#define TBRL SPRN_TBRL /* Time Base Read Lower Register */ -#define TBRU SPRN_TBRU /* Time Base Read Upper Register */ -#define TBWL SPRN_TBWL /* Time Base Write Lower Register */ -#define TBWU SPRN_TBWU /* Time Base Write Upper Register */ -#define XER SPRN_XER - -/* Processor Version Register (PVR) field extraction */ - -#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ -#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ - -/* Processor Version Numbers */ -#define PV_NORTHSTAR 0x0033 -#define PV_PULSAR 0x0034 -#define PV_POWER4 0x0035 -#define PV_ICESTAR 0x0036 -#define PV_SSTAR 0x0037 -#define PV_POWER4p 0x0038 -#define PV_970 0x0039 -#define PV_POWER5 0x003A -#define PV_POWER5p 0x003B -#define PV_970FX 0x003C -#define PV_630 0x0040 -#define PV_630p 0x0041 -#define PV_970MP 0x0044 -#define PV_BE 0x0070 - -/* Platforms supported by PPC64 */ -#define PLATFORM_PSERIES 0x0100 -#define PLATFORM_PSERIES_LPAR 0x0101 -#define PLATFORM_ISERIES_LPAR 0x0201 -#define PLATFORM_LPAR 0x0001 -#define PLATFORM_POWERMAC 0x0400 -#define PLATFORM_MAPLE 0x0500 -#define PLATFORM_BPA 0x1000 - -/* Compatibility with drivers coming from PPC32 world */ -#define _machine (systemcfg->platform) -#define _MACH_Pmac PLATFORM_POWERMAC - -/* - * List of interrupt controllers. - */ -#define IC_INVALID 0 -#define IC_OPEN_PIC 1 -#define IC_PPC_XIC 2 -#define IC_BPA_IIC 3 -#define IC_ISERIES 4 - -#define XGLUE(a,b) a##b -#define GLUE(a,b) XGLUE(a,b) - -#ifdef __ASSEMBLY__ - -#define _GLOBAL(name) \ - .section ".text"; \ - .align 2 ; \ - .globl name; \ - .globl GLUE(.,name); \ - .section ".opd","aw"; \ -name: \ - .quad GLUE(.,name); \ - .quad .TOC.@tocbase; \ - .quad 0; \ - .previous; \ - .type GLUE(.,name),@function; \ -GLUE(.,name): - -#define _KPROBE(name) \ - .section ".kprobes.text","a"; \ - .align 2 ; \ - .globl name; \ - .globl GLUE(.,name); \ - .section ".opd","aw"; \ -name: \ - .quad GLUE(.,name); \ - .quad .TOC.@tocbase; \ - .quad 0; \ - .previous; \ - .type GLUE(.,name),@function; \ -GLUE(.,name): - -#define _STATIC(name) \ - .section ".text"; \ - .align 2 ; \ - .section ".opd","aw"; \ -name: \ - .quad GLUE(.,name); \ - .quad .TOC.@tocbase; \ - .quad 0; \ - .previous; \ - .type GLUE(.,name),@function; \ -GLUE(.,name): - -#else /* __ASSEMBLY__ */ - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -/* Macros for setting and retrieving special purpose registers */ - -#define mfmsr() ({unsigned long rval; \ - asm volatile("mfmsr %0" : "=r" (rval)); rval;}) - -#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ - : : "r" (v)) -#define mtmsrd(v) __mtmsrd((v), 0) - -#define mfspr(rn) ({unsigned long rval; \ - asm volatile("mfspr %0," __stringify(rn) \ - : "=r" (rval)); rval;}) -#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) - -#define mftb() ({unsigned long rval; \ - asm volatile("mftb %0" : "=r" (rval)); rval;}) - -#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) -#define mttbu(v) asm volatile("mttbu %0":: "r"(v)) - -#define mfasr() ({unsigned long rval; \ - asm volatile("mfasr %0" : "=r" (rval)); rval;}) - -/* Macros for adjusting thread priority (hardware multi-threading) */ -#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") -#define HMT_low() asm volatile("or 1,1,1 # low priority") -#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") -#define HMT_medium() asm volatile("or 2,2,2 # medium priority") -#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") -#define HMT_high() asm volatile("or 3,3,3 # high priority") - -static inline void set_tb(unsigned int upper, unsigned int lower) -{ - mttbl(0); - mttbu(upper); - mttbl(lower); -} - -#define __get_SP() ({unsigned long sp; \ - asm volatile("mr %0,1": "=r" (sp)); sp;}) - -#ifdef __KERNEL__ - -extern int have_of; -extern u64 ppc64_interrupt_controller; - -struct task_struct; -void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); -void release_thread(struct task_struct *); - -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy(struct task_struct *tsk); - -/* Create a new kernel thread. */ -extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; -extern struct task_struct *last_task_used_altivec; - -/* 64-bit user address space is 44-bits (16TB user VM) */ -#define TASK_SIZE_USER64 (0x0000100000000000UL) - -/* - * 32-bit user address space is 4GB - 1 page - * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT - */ -#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE)) - -#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ - TASK_SIZE_USER32 : TASK_SIZE_USER64) - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4)) -#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4)) - -#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \ - TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) - -typedef struct { - unsigned long seg; -} mm_segment_t; - -struct thread_struct { - unsigned long ksp; /* Kernel stack pointer */ - unsigned long ksp_vsid; - struct pt_regs *regs; /* Pointer to saved register state */ - mm_segment_t fs; /* for get_fs() validation */ - double fpr[32]; /* Complete floating point set */ - unsigned long fpscr; /* Floating point status (plus pad) */ - unsigned long fpexc_mode; /* Floating-point exception mode */ - unsigned long start_tb; /* Start purr when proc switched in */ - unsigned long accum_tb; /* Total accumilated purr for process */ - unsigned long vdso_base; /* base of the vDSO library */ - unsigned long dabr; /* Data address breakpoint register */ -#ifdef CONFIG_ALTIVEC - /* Complete AltiVec register set */ - vector128 vr[32] __attribute((aligned(16))); - /* AltiVec status */ - vector128 vscr __attribute((aligned(16))); - unsigned long vrsave; - int used_vr; /* set if process has used altivec */ -#endif /* CONFIG_ALTIVEC */ -}; - -#define ARCH_MIN_TASKALIGN 16 - -#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) - -#define INIT_THREAD { \ - .ksp = INIT_SP, \ - .regs = (struct pt_regs *)INIT_SP - 1, \ - .fs = KERNEL_DS, \ - .fpr = {0}, \ - .fpscr = 0, \ - .fpexc_mode = MSR_FE0|MSR_FE1, \ -} - -/* - * Return saved PC of a blocked thread. For now, this is the "user" PC - */ -#define thread_saved_pc(tsk) \ - ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) - -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) -#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) - -/* Get/set floating-point exception mode */ -#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr)) -#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val)) - -extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr); -extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val); - -static inline unsigned int __unpack_fe01(unsigned long msr_bits) -{ - return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); -} - -static inline unsigned long __pack_fe01(unsigned int fpmode) -{ - return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1); -} - -#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0) - -/* - * Prefetch macros. - */ -#define ARCH_HAS_PREFETCH -#define ARCH_HAS_PREFETCHW -#define ARCH_HAS_SPINLOCK_PREFETCH - -static inline void prefetch(const void *x) -{ - if (unlikely(!x)) - return; - - __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x)); -} - -static inline void prefetchw(const void *x) -{ - if (unlikely(!x)) - return; - - __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x)); -} - -#define spin_lock_prefetch(x) prefetchw(x) - -#define HAVE_ARCH_PICK_MMAP_LAYOUT - -static inline void ppc64_runlatch_on(void) -{ - unsigned long ctrl; - - if (cpu_has_feature(CPU_FTR_CTRL)) { - ctrl = mfspr(SPRN_CTRLF); - ctrl |= CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); - } -} - -static inline void ppc64_runlatch_off(void) -{ - unsigned long ctrl; - - if (cpu_has_feature(CPU_FTR_CTRL)) { - ctrl = mfspr(SPRN_CTRLF); - ctrl &= ~CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); - } -} - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ -#define RUNLATCH_ON(REG) \ -BEGIN_FTR_SECTION \ - mfspr (REG),SPRN_CTRLF; \ - ori (REG),(REG),CTRL_RUNLATCH; \ - mtspr SPRN_CTRLT,(REG); \ -END_FTR_SECTION_IFSET(CPU_FTR_CTRL) -#endif - -/* - * Number of entries in the SLB. If this ever changes we should handle - * it with a use a cpu feature fixup. - */ -#define SLB_NUM_ENTRIES 64 - -#endif /* __ASM_PPC64_PROCESSOR_H */ diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 1fbdc9f0590c..c04d62c592a6 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -144,13 +144,6 @@ struct thread_struct; extern struct task_struct * _switch(struct thread_struct *prev, struct thread_struct *next); -static inline int __is_processor(unsigned long pv) -{ - unsigned long pvr; - asm("mfspr %0, 0x11F" : "=r" (pvr)); - return(PVR_VER(pvr) == pv); -} - /* * Atomic exchange * From a432403a89646614252c3bb6dfbe897c8312ab35 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 20:49:07 +1000 Subject: [PATCH 0229/1940] ppc64: Use the merged lmb routines The only real change here is that lmb_enforce_memory_limit now takes the memory_limit as a parameter instead of as a global variable. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/lmb.c | 299 ------------------------------------- arch/ppc64/kernel/prom.c | 5 +- include/asm-ppc64/lmb.h | 81 ---------- 4 files changed, 4 insertions(+), 383 deletions(-) delete mode 100644 arch/ppc64/kernel/lmb.c delete mode 100644 include/asm-ppc64/lmb.h diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 2fdcc4b63d40..32fd3f1c7935 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := setup.o entry.o irq.o idle.o dma.o \ align.o semaphore.o bitops.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ - lmb.o cputable.o cpu_setup_power4.o \ + cputable.o cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o obj-y += vdso32/ vdso64/ diff --git a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c deleted file mode 100644 index 5adaca2ddc9d..000000000000 --- a/arch/ppc64/kernel/lmb.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Procedures for interfacing to Open Firmware. - * - * Peter Bergner, IBM Corp. June 2001. - * Copyright (C) 2001 Peter Bergner. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct lmb lmb; - -#undef DEBUG - -void lmb_dump_all(void) -{ -#ifdef DEBUG - unsigned long i; - - udbg_printf("lmb_dump_all:\n"); - udbg_printf(" memory.cnt = 0x%lx\n", - lmb.memory.cnt); - udbg_printf(" memory.size = 0x%lx\n", - lmb.memory.size); - for (i=0; i < lmb.memory.cnt ;i++) { - udbg_printf(" memory.region[0x%x].base = 0x%lx\n", - i, lmb.memory.region[i].base); - udbg_printf(" .size = 0x%lx\n", - lmb.memory.region[i].size); - } - - udbg_printf("\n reserved.cnt = 0x%lx\n", - lmb.reserved.cnt); - udbg_printf(" reserved.size = 0x%lx\n", - lmb.reserved.size); - for (i=0; i < lmb.reserved.cnt ;i++) { - udbg_printf(" reserved.region[0x%x].base = 0x%lx\n", - i, lmb.reserved.region[i].base); - udbg_printf(" .size = 0x%lx\n", - lmb.reserved.region[i].size); - } -#endif /* DEBUG */ -} - -static unsigned long __init -lmb_addrs_overlap(unsigned long base1, unsigned long size1, - unsigned long base2, unsigned long size2) -{ - return ((base1 < (base2+size2)) && (base2 < (base1+size1))); -} - -static long __init -lmb_addrs_adjacent(unsigned long base1, unsigned long size1, - unsigned long base2, unsigned long size2) -{ - if (base2 == base1 + size1) - return 1; - else if (base1 == base2 + size2) - return -1; - - return 0; -} - -static long __init -lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2) -{ - unsigned long base1 = rgn->region[r1].base; - unsigned long size1 = rgn->region[r1].size; - unsigned long base2 = rgn->region[r2].base; - unsigned long size2 = rgn->region[r2].size; - - return lmb_addrs_adjacent(base1, size1, base2, size2); -} - -/* Assumption: base addr of region 1 < base addr of region 2 */ -static void __init -lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2) -{ - unsigned long i; - - rgn->region[r1].size += rgn->region[r2].size; - for (i=r2; i < rgn->cnt-1; i++) { - rgn->region[i].base = rgn->region[i+1].base; - rgn->region[i].size = rgn->region[i+1].size; - } - rgn->cnt--; -} - -/* This routine called with relocation disabled. */ -void __init -lmb_init(void) -{ - /* Create a dummy zero size LMB which will get coalesced away later. - * This simplifies the lmb_add() code below... - */ - lmb.memory.region[0].base = 0; - lmb.memory.region[0].size = 0; - lmb.memory.cnt = 1; - - /* Ditto. */ - lmb.reserved.region[0].base = 0; - lmb.reserved.region[0].size = 0; - lmb.reserved.cnt = 1; -} - -/* This routine called with relocation disabled. */ -void __init -lmb_analyze(void) -{ - int i; - - lmb.memory.size = 0; - - for (i = 0; i < lmb.memory.cnt; i++) - lmb.memory.size += lmb.memory.region[i].size; -} - -/* This routine called with relocation disabled. */ -static long __init -lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size) -{ - unsigned long i, coalesced = 0; - long adjacent; - - /* First try and coalesce this LMB with another. */ - for (i=0; i < rgn->cnt; i++) { - unsigned long rgnbase = rgn->region[i].base; - unsigned long rgnsize = rgn->region[i].size; - - adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize); - if ( adjacent > 0 ) { - rgn->region[i].base -= size; - rgn->region[i].size += size; - coalesced++; - break; - } - else if ( adjacent < 0 ) { - rgn->region[i].size += size; - coalesced++; - break; - } - } - - if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) { - lmb_coalesce_regions(rgn, i, i+1); - coalesced++; - } - - if ( coalesced ) { - return coalesced; - } else if ( rgn->cnt >= MAX_LMB_REGIONS ) { - return -1; - } - - /* Couldn't coalesce the LMB, so add it to the sorted table. */ - for (i=rgn->cnt-1; i >= 0; i--) { - if (base < rgn->region[i].base) { - rgn->region[i+1].base = rgn->region[i].base; - rgn->region[i+1].size = rgn->region[i].size; - } else { - rgn->region[i+1].base = base; - rgn->region[i+1].size = size; - break; - } - } - rgn->cnt++; - - return 0; -} - -/* This routine called with relocation disabled. */ -long __init -lmb_add(unsigned long base, unsigned long size) -{ - struct lmb_region *_rgn = &(lmb.memory); - - /* On pSeries LPAR systems, the first LMB is our RMO region. */ - if ( base == 0 ) - lmb.rmo_size = size; - - return lmb_add_region(_rgn, base, size); - -} - -long __init -lmb_reserve(unsigned long base, unsigned long size) -{ - struct lmb_region *_rgn = &(lmb.reserved); - - return lmb_add_region(_rgn, base, size); -} - -long __init -lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size) -{ - unsigned long i; - - for (i=0; i < rgn->cnt; i++) { - unsigned long rgnbase = rgn->region[i].base; - unsigned long rgnsize = rgn->region[i].size; - if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) { - break; - } - } - - return (i < rgn->cnt) ? i : -1; -} - -unsigned long __init -lmb_alloc(unsigned long size, unsigned long align) -{ - return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); -} - -unsigned long __init -lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr) -{ - long i, j; - unsigned long base = 0; - - for (i=lmb.memory.cnt-1; i >= 0; i--) { - unsigned long lmbbase = lmb.memory.region[i].base; - unsigned long lmbsize = lmb.memory.region[i].size; - - if ( max_addr == LMB_ALLOC_ANYWHERE ) - base = _ALIGN_DOWN(lmbbase+lmbsize-size, align); - else if ( lmbbase < max_addr ) - base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align); - else - continue; - - while ( (lmbbase <= base) && - ((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) { - base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align); - } - - if ( (base != 0) && (lmbbase <= base) ) - break; - } - - if ( i < 0 ) - return 0; - - lmb_add_region(&lmb.reserved, base, size); - - return base; -} - -/* You must call lmb_analyze() before this. */ -unsigned long __init -lmb_phys_mem_size(void) -{ - return lmb.memory.size; -} - -unsigned long __init -lmb_end_of_DRAM(void) -{ - int idx = lmb.memory.cnt - 1; - - return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); -} - -/* - * Truncate the lmb list to memory_limit if it's set - * You must call lmb_analyze() after this. - */ -void __init lmb_enforce_memory_limit(void) -{ - extern unsigned long memory_limit; - unsigned long i, limit; - - if (! memory_limit) - return; - - limit = memory_limit; - for (i = 0; i < lmb.memory.cnt; i++) { - if (limit > lmb.memory.region[i].size) { - limit -= lmb.memory.region[i].size; - continue; - } - - lmb.memory.region[i].size = limit; - lmb.memory.cnt = i + 1; - break; - } -} diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 7035deb6de92..a0866f12647f 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -78,6 +78,7 @@ typedef int interpret_func(struct device_node *, unsigned long *, extern struct rtas_t rtas; extern struct lmb lmb; extern unsigned long klimit; +extern unsigned long memory_limit; static int __initdata dt_root_addr_cells; static int __initdata dt_root_size_cells; @@ -1063,7 +1064,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, { u32 *prop; u64 *prop64; - extern unsigned long memory_limit, tce_alloc_start, tce_alloc_end; + extern unsigned long tce_alloc_start, tce_alloc_end; DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname); @@ -1237,7 +1238,7 @@ void __init early_init_devtree(void *params) lmb_init(); scan_flat_dt(early_init_dt_scan_root, NULL); scan_flat_dt(early_init_dt_scan_memory, NULL); - lmb_enforce_memory_limit(); + lmb_enforce_memory_limit(memory_limit); lmb_analyze(); systemcfg->physicalMemorySize = lmb_phys_mem_size(); lmb_reserve(0, __pa(klimit)); diff --git a/include/asm-ppc64/lmb.h b/include/asm-ppc64/lmb.h deleted file mode 100644 index de91e034bd98..000000000000 --- a/include/asm-ppc64/lmb.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _PPC64_LMB_H -#define _PPC64_LMB_H - -/* - * Definitions for talking to the Open Firmware PROM on - * Power Macintosh computers. - * - * Copyright (C) 2001 Peter Bergner, IBM Corp. - * - * 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. - */ - -#include -#include - -#define MAX_LMB_REGIONS 128 - -#define LMB_ALLOC_ANYWHERE 0 - -struct lmb_property { - unsigned long base; - unsigned long size; -}; - -struct lmb_region { - unsigned long cnt; - unsigned long size; - struct lmb_property region[MAX_LMB_REGIONS+1]; -}; - -struct lmb { - unsigned long debug; - unsigned long rmo_size; - struct lmb_region memory; - struct lmb_region reserved; -}; - -extern struct lmb lmb; - -extern void __init lmb_init(void); -extern void __init lmb_analyze(void); -extern long __init lmb_add(unsigned long, unsigned long); -extern long __init lmb_reserve(unsigned long, unsigned long); -extern unsigned long __init lmb_alloc(unsigned long, unsigned long); -extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long, - unsigned long); -extern unsigned long __init lmb_phys_mem_size(void); -extern unsigned long __init lmb_end_of_DRAM(void); -extern unsigned long __init lmb_abs_to_phys(unsigned long); -extern void __init lmb_enforce_memory_limit(void); - -extern void lmb_dump_all(void); - -extern unsigned long io_hole_start; - -static inline unsigned long -lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) -{ - return type->region[region_nr].size; -} -static inline unsigned long -lmb_size_pages(struct lmb_region *type, unsigned long region_nr) -{ - return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT; -} -static inline unsigned long -lmb_start_pfn(struct lmb_region *type, unsigned long region_nr) -{ - return type->region[region_nr].base >> PAGE_SHIFT; -} -static inline unsigned long -lmb_end_pfn(struct lmb_region *type, unsigned long region_nr) -{ - return lmb_start_pfn(type, region_nr) + - lmb_size_pages(type, region_nr); -} - -#endif /* _PPC64_LMB_H */ From 70d64ceaa1a84d2502405422a4dfd3f87786a347 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 21:52:43 +1000 Subject: [PATCH 0230/1940] powerpc: Rename files to have consistent _32/_64 suffixes This doesn't change any code, just renames things so we consistently have foo_32.c and foo_64.c where we have separate 32- and 64-bit versions. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 2 +- arch/powerpc/kernel/Makefile | 4 +- arch/powerpc/kernel/{head.S => head_32.S} | 0 arch/powerpc/kernel/{setup.c => setup_32.c} | 0 arch/powerpc/lib/Makefile | 6 +- .../powerpc/lib/{checksum.S => checksum_32.S} | 0 .../lib/{checksum64.S => checksum_64.S} | 0 arch/powerpc/lib/{copy32.S => copy_32.S} | 0 .../powerpc/lib/{copypage.S => copypage_64.S} | 0 .../powerpc/lib/{copyuser.S => copyuser_64.S} | 0 arch/powerpc/lib/mem_64.S | 119 ++++++++ arch/powerpc/lib/{memcpy.S => memcpy_64.S} | 0 .../powerpc/lib/{usercopy.c => usercopy_64.c} | 0 arch/powerpc/mm/Makefile | 8 +- arch/powerpc/mm/{hash_32.S => hash_low_32.S} | 0 arch/powerpc/mm/{init.c => init_32.c} | 0 arch/powerpc/mm/{init64.c => init_64.c} | 0 arch/powerpc/mm/mem64.c | 259 ------------------ .../mm/{mmu_context.c => mmu_context_32.c} | 0 .../mm/{mmu_context64.c => mmu_context_64.c} | 0 arch/powerpc/mm/{pgtable.c => pgtable_32.c} | 0 arch/powerpc/mm/{pgtable64.c => pgtable_64.c} | 0 arch/powerpc/mm/{ppc_mmu.c => ppc_mmu_32.c} | 0 arch/powerpc/mm/{tlb.c => tlb_32.c} | 0 24 files changed, 129 insertions(+), 269 deletions(-) rename arch/powerpc/kernel/{head.S => head_32.S} (100%) rename arch/powerpc/kernel/{setup.c => setup_32.c} (100%) rename arch/powerpc/lib/{checksum.S => checksum_32.S} (100%) rename arch/powerpc/lib/{checksum64.S => checksum_64.S} (100%) rename arch/powerpc/lib/{copy32.S => copy_32.S} (100%) rename arch/powerpc/lib/{copypage.S => copypage_64.S} (100%) rename arch/powerpc/lib/{copyuser.S => copyuser_64.S} (100%) create mode 100644 arch/powerpc/lib/mem_64.S rename arch/powerpc/lib/{memcpy.S => memcpy_64.S} (100%) rename arch/powerpc/lib/{usercopy.c => usercopy_64.c} (100%) rename arch/powerpc/mm/{hash_32.S => hash_low_32.S} (100%) rename arch/powerpc/mm/{init.c => init_32.c} (100%) rename arch/powerpc/mm/{init64.c => init_64.c} (100%) delete mode 100644 arch/powerpc/mm/mem64.c rename arch/powerpc/mm/{mmu_context.c => mmu_context_32.c} (100%) rename arch/powerpc/mm/{mmu_context64.c => mmu_context_64.c} (100%) rename arch/powerpc/mm/{pgtable.c => pgtable_32.c} (100%) rename arch/powerpc/mm/{pgtable64.c => pgtable_64.c} (100%) rename arch/powerpc/mm/{ppc_mmu.c => ppc_mmu_32.c} (100%) rename arch/powerpc/mm/{tlb.c => tlb_32.c} (100%) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index eb1224c24e3e..064864065753 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -112,7 +112,7 @@ CFLAGS += $(cpu-as-y) # Default to the common case. KBUILD_DEFCONFIG := common_defconfig -head-y := arch/powerpc/kernel/head.o +head-y := arch/powerpc/kernel/head_32.o head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 06d618e52f8e..344cab678c6a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -extra-$(CONFIG_PPC_STD_MMU) := head.o +extra-$(CONFIG_PPC_STD_MMU) := head_32.o extra-$(CONFIG_PPC64) := head_64.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o @@ -21,7 +21,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y := traps.o prom.o semaphore.o -obj-$(CONFIG_PPC32) += setup.o process.o +obj-$(CONFIG_PPC32) += setup_32.o process.o obj-$(CONFIG_PPC64) += idle_power4.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head_32.S similarity index 100% rename from arch/powerpc/kernel/head.S rename to arch/powerpc/kernel/head_32.S diff --git a/arch/powerpc/kernel/setup.c b/arch/powerpc/kernel/setup_32.c similarity index 100% rename from arch/powerpc/kernel/setup.c rename to arch/powerpc/kernel/setup_32.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 347f9798e433..a8cedb96de5f 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -3,7 +3,7 @@ # obj-y := strcase.o string.o -obj-$(CONFIG_PPC32) += div64.o copy32.o checksum.o -obj-$(CONFIG_PPC64) += copypage.o copyuser.o memcpy.o usercopy.o \ - sstep.o checksum64.o +obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o +obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o memcpy_64.o \ + usercopy_64.o sstep.o checksum_64.o mem_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/powerpc/lib/checksum.S b/arch/powerpc/lib/checksum_32.S similarity index 100% rename from arch/powerpc/lib/checksum.S rename to arch/powerpc/lib/checksum_32.S diff --git a/arch/powerpc/lib/checksum64.S b/arch/powerpc/lib/checksum_64.S similarity index 100% rename from arch/powerpc/lib/checksum64.S rename to arch/powerpc/lib/checksum_64.S diff --git a/arch/powerpc/lib/copy32.S b/arch/powerpc/lib/copy_32.S similarity index 100% rename from arch/powerpc/lib/copy32.S rename to arch/powerpc/lib/copy_32.S diff --git a/arch/powerpc/lib/copypage.S b/arch/powerpc/lib/copypage_64.S similarity index 100% rename from arch/powerpc/lib/copypage.S rename to arch/powerpc/lib/copypage_64.S diff --git a/arch/powerpc/lib/copyuser.S b/arch/powerpc/lib/copyuser_64.S similarity index 100% rename from arch/powerpc/lib/copyuser.S rename to arch/powerpc/lib/copyuser_64.S diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S new file mode 100644 index 000000000000..68df20283ff5 --- /dev/null +++ b/arch/powerpc/lib/mem_64.S @@ -0,0 +1,119 @@ +/* + * String handling functions for PowerPC. + * + * Copyright (C) 1996 Paul Mackerras. + * + * 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. + */ +#include +#include +#include + +_GLOBAL(memset) + neg r0,r3 + rlwimi r4,r4,8,16,23 + andi. r0,r0,7 /* # bytes to be 8-byte aligned */ + rlwimi r4,r4,16,0,15 + cmplw cr1,r5,r0 /* do we get that far? */ + rldimi r4,r4,32,0 + mtcrf 1,r0 + mr r6,r3 + blt cr1,8f + beq+ 3f /* if already 8-byte aligned */ + subf r5,r0,r5 + bf 31,1f + stb r4,0(r6) + addi r6,r6,1 +1: bf 30,2f + sth r4,0(r6) + addi r6,r6,2 +2: bf 29,3f + stw r4,0(r6) + addi r6,r6,4 +3: srdi. r0,r5,6 + clrldi r5,r5,58 + mtctr r0 + beq 5f +4: std r4,0(r6) + std r4,8(r6) + std r4,16(r6) + std r4,24(r6) + std r4,32(r6) + std r4,40(r6) + std r4,48(r6) + std r4,56(r6) + addi r6,r6,64 + bdnz 4b +5: srwi. r0,r5,3 + clrlwi r5,r5,29 + mtcrf 1,r0 + beq 8f + bf 29,6f + std r4,0(r6) + std r4,8(r6) + std r4,16(r6) + std r4,24(r6) + addi r6,r6,32 +6: bf 30,7f + std r4,0(r6) + std r4,8(r6) + addi r6,r6,16 +7: bf 31,8f + std r4,0(r6) + addi r6,r6,8 +8: cmpwi r5,0 + mtcrf 1,r5 + beqlr+ + bf 29,9f + stw r4,0(r6) + addi r6,r6,4 +9: bf 30,10f + sth r4,0(r6) + addi r6,r6,2 +10: bflr 31 + stb r4,0(r6) + blr + +_GLOBAL(memmove) + cmplw 0,r3,r4 + bgt .backwards_memcpy + b .memcpy + +_GLOBAL(backwards_memcpy) + rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + add r6,r3,r5 + add r4,r4,r5 + beq 2f + andi. r0,r6,3 + mtctr r7 + bne 5f +1: lwz r7,-4(r4) + lwzu r8,-8(r4) + stw r7,-4(r6) + stwu r8,-8(r6) + bdnz 1b + andi. r5,r5,7 +2: cmplwi 0,r5,4 + blt 3f + lwzu r0,-4(r4) + subi r5,r5,4 + stwu r0,-4(r6) +3: cmpwi 0,r5,0 + beqlr + mtctr r5 +4: lbzu r0,-1(r4) + stbu r0,-1(r6) + bdnz 4b + blr +5: mtctr r0 +6: lbzu r7,-1(r4) + stbu r7,-1(r6) + bdnz 6b + subf r5,r0,r5 + rlwinm. r7,r5,32-3,3,31 + beq 2b + mtctr r7 + b 1b diff --git a/arch/powerpc/lib/memcpy.S b/arch/powerpc/lib/memcpy_64.S similarity index 100% rename from arch/powerpc/lib/memcpy.S rename to arch/powerpc/lib/memcpy_64.S diff --git a/arch/powerpc/lib/usercopy.c b/arch/powerpc/lib/usercopy_64.c similarity index 100% rename from arch/powerpc/lib/usercopy.c rename to arch/powerpc/lib/usercopy_64.c diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index afd3be112b79..35497deeb4b2 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -3,10 +3,10 @@ # obj-y := fault.o mem.o lmb.o -obj-$(CONFIG_PPC32) += init.o pgtable.o mmu_context.o \ - tlb.o -obj-$(CONFIG_PPC64) += init64.o pgtable64.o mmu_context64.o -obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu.o hash_32.o +obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o \ + tlb_32.o +obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o +obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o obj-$(CONFIG_40x) += 4xx_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o diff --git a/arch/powerpc/mm/hash_32.S b/arch/powerpc/mm/hash_low_32.S similarity index 100% rename from arch/powerpc/mm/hash_32.S rename to arch/powerpc/mm/hash_low_32.S diff --git a/arch/powerpc/mm/init.c b/arch/powerpc/mm/init_32.c similarity index 100% rename from arch/powerpc/mm/init.c rename to arch/powerpc/mm/init_32.c diff --git a/arch/powerpc/mm/init64.c b/arch/powerpc/mm/init_64.c similarity index 100% rename from arch/powerpc/mm/init64.c rename to arch/powerpc/mm/init_64.c diff --git a/arch/powerpc/mm/mem64.c b/arch/powerpc/mm/mem64.c deleted file mode 100644 index ef765a84433f..000000000000 --- a/arch/powerpc/mm/mem64.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) - * and Cort Dougan (PReP) (cort@cs.nmt.edu) - * Copyright (C) 1996 Paul Mackerras - * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). - * - * Derived from "arch/i386/mm/init.c" - * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds - * - * Dave Engebretsen - * Rework for PPC64 port. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This is called by /dev/mem to know if a given address has to - * be mapped non-cacheable or not - */ -int page_is_ram(unsigned long pfn) -{ - int i; - unsigned long paddr = (pfn << PAGE_SHIFT); - - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long base; - - base = lmb.memory.region[i].base; - - if ((paddr >= base) && - (paddr < (base + lmb.memory.region[i].size))) { - return 1; - } - } - - return 0; -} -EXPORT_SYMBOL(page_is_ram); - -pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, - unsigned long size, pgprot_t vma_prot) -{ - if (ppc_md.phys_mem_access_prot) - return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); - - if (!page_is_ram(addr >> PAGE_SHIFT)) - vma_prot = __pgprot(pgprot_val(vma_prot) - | _PAGE_GUARDED | _PAGE_NO_CACHE); - return vma_prot; -} -EXPORT_SYMBOL(phys_mem_access_prot); - -void show_mem(void) -{ - unsigned long total = 0, reserved = 0; - unsigned long shared = 0, cached = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - for_each_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; i++) { - page = pgdat_page_nr(pgdat, i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - } - printk("%ld pages of RAM\n", total); - printk("%ld reserved pages\n", reserved); - printk("%ld pages shared\n", shared); - printk("%ld pages swap cached\n", cached); -} - -/* - * This is called when a page has been modified by the kernel. - * It just marks the page as not i-cache clean. We do the i-cache - * flush later when the page is given to a user process, if necessary. - */ -void flush_dcache_page(struct page *page) -{ - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &page->flags)) - clear_bit(PG_arch_1, &page->flags); -} -EXPORT_SYMBOL(flush_dcache_page); - -void clear_user_page(void *page, unsigned long vaddr, struct page *pg) -{ - clear_page(page); - - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - /* - * We shouldnt have to do this, but some versions of glibc - * require it (ld.so assumes zero filled pages are icache clean) - * - Anton - */ - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); -} -EXPORT_SYMBOL(clear_user_page); - -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, - struct page *pg) -{ - copy_page(vto, vfrom); - - /* - * We should be able to use the following optimisation, however - * there are two problems. - * Firstly a bug in some versions of binutils meant PLT sections - * were not marked executable. - * Secondly the first word in the GOT section is blrl, used - * to establish the GOT address. Until recently the GOT was - * not marked executable. - * - Anton - */ -#if 0 - if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0)) - return; -#endif - - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); -} - -void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, - unsigned long addr, int len) -{ - unsigned long maddr; - - maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK); - flush_icache_range(maddr, maddr + len); -} -EXPORT_SYMBOL(flush_icache_user_range); - -/* - * This is called at the end of handling a user page fault, when the - * fault has been handled by updating a PTE in the linux page tables. - * We use it to preload an HPTE into the hash table corresponding to - * the updated linux PTE. - * - * This must always be called with the mm->page_table_lock held - */ -void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea, - pte_t pte) -{ - unsigned long vsid; - void *pgdir; - pte_t *ptep; - int local = 0; - cpumask_t tmp; - unsigned long flags; - - /* handle i-cache coherency */ - if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && - !cpu_has_feature(CPU_FTR_NOEXECUTE)) { - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - if (!PageReserved(page) - && !test_bit(PG_arch_1, &page->flags)) { - __flush_dcache_icache(page_address(page)); - set_bit(PG_arch_1, &page->flags); - } - } - } - - /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ - if (!pte_young(pte)) - return; - - pgdir = vma->vm_mm->pgd; - if (pgdir == NULL) - return; - - ptep = find_linux_pte(pgdir, ea); - if (!ptep) - return; - - vsid = get_vsid(vma->vm_mm->context.id, ea); - - local_irq_save(flags); - tmp = cpumask_of_cpu(smp_processor_id()); - if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) - local = 1; - - __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, - 0x300, local); - local_irq_restore(flags); -} diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context_32.c similarity index 100% rename from arch/powerpc/mm/mmu_context.c rename to arch/powerpc/mm/mmu_context_32.c diff --git a/arch/powerpc/mm/mmu_context64.c b/arch/powerpc/mm/mmu_context_64.c similarity index 100% rename from arch/powerpc/mm/mmu_context64.c rename to arch/powerpc/mm/mmu_context_64.c diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable_32.c similarity index 100% rename from arch/powerpc/mm/pgtable.c rename to arch/powerpc/mm/pgtable_32.c diff --git a/arch/powerpc/mm/pgtable64.c b/arch/powerpc/mm/pgtable_64.c similarity index 100% rename from arch/powerpc/mm/pgtable64.c rename to arch/powerpc/mm/pgtable_64.c diff --git a/arch/powerpc/mm/ppc_mmu.c b/arch/powerpc/mm/ppc_mmu_32.c similarity index 100% rename from arch/powerpc/mm/ppc_mmu.c rename to arch/powerpc/mm/ppc_mmu_32.c diff --git a/arch/powerpc/mm/tlb.c b/arch/powerpc/mm/tlb_32.c similarity index 100% rename from arch/powerpc/mm/tlb.c rename to arch/powerpc/mm/tlb_32.c From ab1f9dac6eea25ee59e4c8e1cf0b7476afbbfe07 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 21:58:35 +1000 Subject: [PATCH 0231/1940] powerpc: Merge arch/ppc64/mm to arch/powerpc/mm This moves the remaining files in arch/ppc64/mm to arch/powerpc/mm, and arranges that we use them when compiling with ARCH=ppc64. Signed-off-by: Paul Mackerras --- arch/powerpc/mm/Makefile | 8 +- .../hash_low.S => powerpc/mm/hash_low_64.S} | 2 +- .../mm/hash_native_64.c} | 0 .../mm/hash_utils_64.c} | 2 +- arch/{ppc64 => powerpc}/mm/hugetlbpage.c | 0 arch/{ppc64 => powerpc}/mm/imalloc.c | 0 arch/powerpc/mm/init_64.c | 36 - arch/powerpc/mm/mem.c | 11 +- arch/{ppc64 => powerpc}/mm/mmap.c | 0 arch/powerpc/mm/mmu_decl.h | 18 +- arch/{ppc64 => powerpc}/mm/numa.c | 0 arch/powerpc/mm/pgtable_64.c | 34 +- arch/{ppc64 => powerpc}/mm/slb.c | 0 arch/{ppc64 => powerpc}/mm/slb_low.S | 0 arch/{ppc64 => powerpc}/mm/stab.c | 0 arch/{ppc64/mm/tlb.c => powerpc/mm/tlb_64.c} | 0 arch/ppc64/Makefile | 2 +- arch/ppc64/mm/Makefile | 11 - arch/ppc64/mm/fault.c | 333 ------- arch/ppc64/mm/init.c | 870 ------------------ 20 files changed, 39 insertions(+), 1288 deletions(-) rename arch/{ppc64/mm/hash_low.S => powerpc/mm/hash_low_64.S} (99%) rename arch/{ppc64/mm/hash_native.c => powerpc/mm/hash_native_64.c} (100%) rename arch/{ppc64/mm/hash_utils.c => powerpc/mm/hash_utils_64.c} (99%) rename arch/{ppc64 => powerpc}/mm/hugetlbpage.c (100%) rename arch/{ppc64 => powerpc}/mm/imalloc.c (100%) rename arch/{ppc64 => powerpc}/mm/mmap.c (100%) rename arch/{ppc64 => powerpc}/mm/numa.c (100%) rename arch/{ppc64 => powerpc}/mm/slb.c (100%) rename arch/{ppc64 => powerpc}/mm/slb_low.S (100%) rename arch/{ppc64 => powerpc}/mm/stab.c (100%) rename arch/{ppc64/mm/tlb.c => powerpc/mm/tlb_64.c} (100%) delete mode 100644 arch/ppc64/mm/Makefile delete mode 100644 arch/ppc64/mm/fault.c delete mode 100644 arch/ppc64/mm/init.c diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 35497deeb4b2..612bc4ec72b1 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -5,8 +5,14 @@ obj-y := fault.o mem.o lmb.o obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o \ tlb_32.o -obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o +hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o +obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \ + hash_utils_64.o hash_low_64.o tlb_64.o \ + slb_low.o slb.o stab.o mmap.o imalloc.o \ + $(hash-y) obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o obj-$(CONFIG_40x) += 4xx_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o +obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/ppc64/mm/hash_low.S b/arch/powerpc/mm/hash_low_64.S similarity index 99% rename from arch/ppc64/mm/hash_low.S rename to arch/powerpc/mm/hash_low_64.S index ee5a5d36bfa8..d6ed9102eeea 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -10,7 +10,7 @@ * described in the kernel's COPYING file. */ -#include +#include #include #include #include diff --git a/arch/ppc64/mm/hash_native.c b/arch/powerpc/mm/hash_native_64.c similarity index 100% rename from arch/ppc64/mm/hash_native.c rename to arch/powerpc/mm/hash_native_64.c diff --git a/arch/ppc64/mm/hash_utils.c b/arch/powerpc/mm/hash_utils_64.c similarity index 99% rename from arch/ppc64/mm/hash_utils.c rename to arch/powerpc/mm/hash_utils_64.c index 83507438d6a0..35dd93eeaf4b 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -78,7 +78,7 @@ extern unsigned long dart_tablebase; hpte_t *htab_address; unsigned long htab_hash_mask; -extern unsigned long _SDR1; +unsigned long _SDR1; #define KB (1024) #define MB (1024*KB) diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c similarity index 100% rename from arch/ppc64/mm/hugetlbpage.c rename to arch/powerpc/mm/hugetlbpage.c diff --git a/arch/ppc64/mm/imalloc.c b/arch/powerpc/mm/imalloc.c similarity index 100% rename from arch/ppc64/mm/imalloc.c rename to arch/powerpc/mm/imalloc.c diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index c0ce6a7af3c7..b0fc822ec29f 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -73,18 +73,8 @@ #warning TASK_SIZE is smaller than it needs to be. #endif -int mem_init_done; -unsigned long ioremap_bot = IMALLOC_BASE; -static unsigned long phbs_io_bot = PHBS_IO_BASE; - -extern pgd_t swapper_pg_dir[]; -extern struct task_struct *current_set[NR_CPUS]; - unsigned long klimit = (unsigned long)_end; -unsigned long _SDR1=0; -unsigned long _ASR=0; - /* max amount of RAM to use */ unsigned long __max_memory; @@ -193,19 +183,6 @@ static int __init setup_kcore(void) } module_init(setup_kcore); -void __iomem * reserve_phb_iospace(unsigned long size) -{ - void __iomem *virt_addr; - - if (phbs_io_bot >= IMALLOC_BASE) - panic("reserve_phb_iospace(): phb io space overflow\n"); - - virt_addr = (void __iomem *) phbs_io_bot; - phbs_io_bot += size; - - return virt_addr; -} - static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { memset(addr, 0, kmem_cache_size(cache)); @@ -244,16 +221,3 @@ void pgtable_cache_init(void) name); } } - -pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, - unsigned long size, pgprot_t vma_prot) -{ - if (ppc_md.phys_mem_access_prot) - return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); - - if (!page_is_ram(addr >> PAGE_SHIFT)) - vma_prot = __pgprot(pgprot_val(vma_prot) - | _PAGE_GUARDED | _PAGE_NO_CACHE); - return vma_prot; -} -EXPORT_SYMBOL(phys_mem_access_prot); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 0650de74d0b3..55b5860ed3c9 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -47,6 +47,9 @@ #include #include #include +#ifdef CONFIG_PPC64 +#include +#endif #include "mmu_decl.h" @@ -334,7 +337,7 @@ void flush_dcache_icache_page(struct page *page) void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE); __flush_dcache_icache(start); kunmap_atomic(start, KM_PPC_SYNC_ICACHE); -#elif defined(CONFIG_8xx) +#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64) /* On 8xx there is no need to kmap since highmem is not supported */ __flush_dcache_icache(page_address(page)); #else @@ -463,18 +466,18 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, if (pgdir == NULL) return; - ptep = find_linux_pte(pgdir, ea); + ptep = find_linux_pte(pgdir, address); if (!ptep) return; - vsid = get_vsid(vma->vm_mm->context.id, ea); + vsid = get_vsid(vma->vm_mm->context.id, address); local_irq_save(flags); tmp = cpumask_of_cpu(smp_processor_id()); if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) local = 1; - __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, + __hash_page(address, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, 0x300, local); local_irq_restore(flags); #endif diff --git a/arch/ppc64/mm/mmap.c b/arch/powerpc/mm/mmap.c similarity index 100% rename from arch/ppc64/mm/mmap.c rename to arch/powerpc/mm/mmap.c diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 06fe8af3af55..a4d7a327c0e5 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -22,11 +22,11 @@ #include #include +#ifdef CONFIG_PPC32 extern void mapin_ram(void); extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, unsigned long phys, unsigned int size, int flags); -extern void reserve_phys_mem(unsigned long start, unsigned long size); extern void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned int size, int flags, unsigned int pid); extern void invalidate_tlbcam_entry(int index); @@ -36,16 +36,16 @@ extern unsigned long ioremap_base; extern unsigned long ioremap_bot; extern unsigned int rtas_data, rtas_size; -extern unsigned long __max_low_memory; -extern unsigned long __initial_memory_limit; -extern unsigned long total_memory; -extern unsigned long total_lowmem; -extern int mem_init_done; - extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern unsigned int num_tlbcam_entries; +#endif + +extern unsigned long __max_low_memory; +extern unsigned long __initial_memory_limit; +extern unsigned long total_memory; +extern unsigned long total_lowmem; /* ...and now those things that may be slightly different between processor * architectures. -- Dan @@ -66,8 +66,8 @@ extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(void); extern void adjust_total_lowmem(void); -#else -/* anything except 4xx or 8xx */ +#elif defined(CONFIG_PPC32) +/* anything 32-bit except 4xx or 8xx */ extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(void); diff --git a/arch/ppc64/mm/numa.c b/arch/powerpc/mm/numa.c similarity index 100% rename from arch/ppc64/mm/numa.c rename to arch/powerpc/mm/numa.c diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 724f97e5dee5..484d24f9208b 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -67,30 +67,9 @@ #include #include -#if PGTABLE_RANGE > USER_VSID_RANGE -#warning Limited user VSID range means pagetable space is wasted -#endif - -#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) -#warning TASK_SIZE is smaller than it needs to be. -#endif - -int mem_init_done; unsigned long ioremap_bot = IMALLOC_BASE; static unsigned long phbs_io_bot = PHBS_IO_BASE; -extern pgd_t swapper_pg_dir[]; -extern struct task_struct *current_set[NR_CPUS]; - -unsigned long klimit = (unsigned long)_end; - -/* max amount of RAM to use */ -unsigned long __max_memory; - -/* info on what we think the IO hole is */ -unsigned long io_hole_start; -unsigned long io_hole_size; - #ifdef CONFIG_PPC_ISERIES void __iomem *ioremap(unsigned long addr, unsigned long size) @@ -355,3 +334,16 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size) EXPORT_SYMBOL(ioremap); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); + +void __iomem * reserve_phb_iospace(unsigned long size) +{ + void __iomem *virt_addr; + + if (phbs_io_bot >= IMALLOC_BASE) + panic("reserve_phb_iospace(): phb io space overflow\n"); + + virt_addr = (void __iomem *) phbs_io_bot; + phbs_io_bot += size; + + return virt_addr; +} diff --git a/arch/ppc64/mm/slb.c b/arch/powerpc/mm/slb.c similarity index 100% rename from arch/ppc64/mm/slb.c rename to arch/powerpc/mm/slb.c diff --git a/arch/ppc64/mm/slb_low.S b/arch/powerpc/mm/slb_low.S similarity index 100% rename from arch/ppc64/mm/slb_low.S rename to arch/powerpc/mm/slb_low.S diff --git a/arch/ppc64/mm/stab.c b/arch/powerpc/mm/stab.c similarity index 100% rename from arch/ppc64/mm/stab.c rename to arch/powerpc/mm/stab.c diff --git a/arch/ppc64/mm/tlb.c b/arch/powerpc/mm/tlb_64.c similarity index 100% rename from arch/ppc64/mm/tlb.c rename to arch/powerpc/mm/tlb_64.c diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index fa889204d6ae..4a9928ef3032 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -83,7 +83,7 @@ head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ -core-y += arch/ppc64/mm/ +core-y += arch/powerpc/mm/ core-y += arch/powerpc/platforms/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile deleted file mode 100644 index 3695d00d347f..000000000000 --- a/arch/ppc64/mm/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the linux ppc-specific parts of the memory manager. -# - -EXTRA_CFLAGS += -mno-minimal-toc - -obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \ - slb_low.o slb.o stab.o mmap.o -obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o -obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c deleted file mode 100644 index be3f25cf3e9f..000000000000 --- a/arch/ppc64/mm/fault.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * arch/ppc/mm/fault.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/i386/mm/fault.c" - * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds - * - * Modified by Cort Dougan and Paul Mackerras. - * - * Modified for PPC64 by Dave Engebretsen (engebret@ibm.com) - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Check whether the instruction at regs->nip is a store using - * an update addressing form which will update r1. - */ -static int store_updates_sp(struct pt_regs *regs) -{ - unsigned int inst; - - if (get_user(inst, (unsigned int __user *)regs->nip)) - return 0; - /* check for 1 in the rA field */ - if (((inst >> 16) & 0x1f) != 1) - return 0; - /* check major opcode */ - switch (inst >> 26) { - case 37: /* stwu */ - case 39: /* stbu */ - case 45: /* sthu */ - case 53: /* stfsu */ - case 55: /* stfdu */ - return 1; - case 62: /* std or stdu */ - return (inst & 3) == 1; - case 31: - /* check minor opcode */ - switch ((inst >> 1) & 0x3ff) { - case 181: /* stdux */ - case 183: /* stwux */ - case 247: /* stbux */ - case 439: /* sthux */ - case 695: /* stfsux */ - case 759: /* stfdux */ - return 1; - } - } - return 0; -} - -static void do_dabr(struct pt_regs *regs, unsigned long error_code) -{ - siginfo_t info; - - if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, - 11, SIGSEGV) == NOTIFY_STOP) - return; - - if (debugger_dabr_match(regs)) - return; - - /* Clear the DABR */ - set_dabr(0); - - /* Deliver the signal to userspace */ - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_HWBKPT; - info.si_addr = (void __user *)regs->nip; - force_sig_info(SIGTRAP, &info, current); -} - -/* - * The error_code parameter is - * - DSISR for a non-SLB data access fault, - * - SRR1 & 0x08000000 for a non-SLB instruction access fault - * - 0 any SLB fault. - * The return value is 0 if the fault was handled, or the signal - * number if this is a kernel fault that can't be handled here. - */ -int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) -{ - struct vm_area_struct * vma; - struct mm_struct *mm = current->mm; - siginfo_t info; - unsigned long code = SEGV_MAPERR; - unsigned long is_write = error_code & DSISR_ISSTORE; - unsigned long trap = TRAP(regs); - unsigned long is_exec = trap == 0x400; - - BUG_ON((trap == 0x380) || (trap == 0x480)); - - if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code, - 11, SIGSEGV) == NOTIFY_STOP) - return 0; - - if (trap == 0x300) { - if (debugger_fault_handler(regs)) - return 0; - } - - /* On a kernel SLB miss we can only check for a valid exception entry */ - if (!user_mode(regs) && (address >= TASK_SIZE)) - return SIGSEGV; - - if (error_code & DSISR_DABRMATCH) { - do_dabr(regs, error_code); - return 0; - } - - if (in_atomic() || mm == NULL) { - if (!user_mode(regs)) - return SIGSEGV; - /* in_atomic() in user mode is really bad, - as is current->mm == NULL. */ - printk(KERN_EMERG "Page fault in user mode with" - "in_atomic() = %d mm = %p\n", in_atomic(), mm); - printk(KERN_EMERG "NIP = %lx MSR = %lx\n", - regs->nip, regs->msr); - die("Weird page fault", regs, SIGSEGV); - } - - /* When running in the kernel we expect faults to occur only to - * addresses in user space. All other faults represent errors in the - * kernel and should generate an OOPS. Unfortunatly, in the case of an - * erroneous fault occuring in a code path which already holds mmap_sem - * we will deadlock attempting to validate the fault against the - * address space. Luckily the kernel only validly references user - * space from well defined areas of code, which are listed in the - * exceptions table. - * - * As the vast majority of faults will be valid we will only perform - * the source reference check when there is a possibilty of a deadlock. - * Attempt to lock the address space, if we cannot we then validate the - * source. If this is invalid we can skip the address space check, - * thus avoiding the deadlock. - */ - if (!down_read_trylock(&mm->mmap_sem)) { - if (!user_mode(regs) && !search_exception_tables(regs->nip)) - goto bad_area_nosemaphore; - - down_read(&mm->mmap_sem); - } - - vma = find_vma(mm, address); - if (!vma) - goto bad_area; - - if (vma->vm_start <= address) { - goto good_area; - } - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - - /* - * N.B. The POWER/Open ABI allows programs to access up to - * 288 bytes below the stack pointer. - * The kernel signal delivery code writes up to about 1.5kB - * below the stack pointer (r1) before decrementing it. - * The exec code can write slightly over 640kB to the stack - * before setting the user r1. Thus we allow the stack to - * expand to 1MB without further checks. - */ - if (address + 0x100000 < vma->vm_end) { - /* get user regs even if this fault is in kernel mode */ - struct pt_regs *uregs = current->thread.regs; - if (uregs == NULL) - goto bad_area; - - /* - * A user-mode access to an address a long way below - * the stack pointer is only valid if the instruction - * is one which would update the stack pointer to the - * address accessed if the instruction completed, - * i.e. either stwu rs,n(r1) or stwux rs,r1,rb - * (or the byte, halfword, float or double forms). - * - * If we don't check this then any write to the area - * between the last mapped region and the stack will - * expand the stack rather than segfaulting. - */ - if (address + 2048 < uregs->gpr[1] - && (!user_mode(regs) || !store_updates_sp(regs))) - goto bad_area; - } - - if (expand_stack(vma, address)) - goto bad_area; - -good_area: - code = SEGV_ACCERR; - - if (is_exec) { - /* protection fault */ - if (error_code & DSISR_PROTFAULT) - goto bad_area; - if (!(vma->vm_flags & VM_EXEC)) - goto bad_area; - /* a write */ - } else if (is_write) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - /* a read */ - } else { - if (!(vma->vm_flags & VM_READ)) - goto bad_area; - } - - survive: - /* - * If for any reason at all we couldn't handle the fault, - * make sure we exit gracefully rather than endlessly redo - * the fault. - */ - switch (handle_mm_fault(mm, vma, address, is_write)) { - - case VM_FAULT_MINOR: - current->min_flt++; - break; - case VM_FAULT_MAJOR: - current->maj_flt++; - break; - case VM_FAULT_SIGBUS: - goto do_sigbus; - case VM_FAULT_OOM: - goto out_of_memory; - default: - BUG(); - } - - up_read(&mm->mmap_sem); - return 0; - -bad_area: - up_read(&mm->mmap_sem); - -bad_area_nosemaphore: - /* User mode accesses cause a SIGSEGV */ - if (user_mode(regs)) { - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = code; - info.si_addr = (void __user *) address; - force_sig_info(SIGSEGV, &info, current); - return 0; - } - - if (trap == 0x400 && (error_code & DSISR_PROTFAULT) - && printk_ratelimit()) - printk(KERN_CRIT "kernel tried to execute NX-protected" - " page (%lx) - exploit attempt? (uid: %d)\n", - address, current->uid); - - return SIGSEGV; - -/* - * We ran out of memory, or some other thing happened to us that made - * us unable to handle the page fault gracefully. - */ -out_of_memory: - up_read(&mm->mmap_sem); - if (current->pid == 1) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", current->comm); - if (user_mode(regs)) - do_exit(SIGKILL); - return SIGKILL; - -do_sigbus: - up_read(&mm->mmap_sem); - if (user_mode(regs)) { - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void __user *)address; - force_sig_info(SIGBUS, &info, current); - return 0; - } - return SIGBUS; -} - -/* - * bad_page_fault is called when we have a bad access from the kernel. - * It is called from do_page_fault above and from some of the procedures - * in traps.c. - */ -void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) -{ - const struct exception_table_entry *entry; - - /* Are we prepared to handle this fault? */ - if ((entry = search_exception_tables(regs->nip)) != NULL) { - regs->nip = entry->fixup; - return; - } - - /* kernel has accessed a bad area */ - die("Kernel access of bad area", regs, sig); -} diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c deleted file mode 100644 index c2157c9c3acb..000000000000 --- a/arch/ppc64/mm/init.c +++ /dev/null @@ -1,870 +0,0 @@ -/* - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) - * and Cort Dougan (PReP) (cort@cs.nmt.edu) - * Copyright (C) 1996 Paul Mackerras - * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). - * - * Derived from "arch/i386/mm/init.c" - * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds - * - * Dave Engebretsen - * Rework for PPC64 port. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if PGTABLE_RANGE > USER_VSID_RANGE -#warning Limited user VSID range means pagetable space is wasted -#endif - -#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) -#warning TASK_SIZE is smaller than it needs to be. -#endif - -int mem_init_done; -unsigned long ioremap_bot = IMALLOC_BASE; -static unsigned long phbs_io_bot = PHBS_IO_BASE; - -extern pgd_t swapper_pg_dir[]; -extern struct task_struct *current_set[NR_CPUS]; - -unsigned long klimit = (unsigned long)_end; - -unsigned long _SDR1=0; -unsigned long _ASR=0; - -/* max amount of RAM to use */ -unsigned long __max_memory; - -/* info on what we think the IO hole is */ -unsigned long io_hole_start; -unsigned long io_hole_size; - -void show_mem(void) -{ - unsigned long total = 0, reserved = 0; - unsigned long shared = 0, cached = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - for_each_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; i++) { - page = pgdat_page_nr(pgdat, i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - } - printk("%ld pages of RAM\n", total); - printk("%ld reserved pages\n", reserved); - printk("%ld pages shared\n", shared); - printk("%ld pages swap cached\n", cached); -} - -#ifdef CONFIG_PPC_ISERIES - -void __iomem *ioremap(unsigned long addr, unsigned long size) -{ - return (void __iomem *)addr; -} - -extern void __iomem *__ioremap(unsigned long addr, unsigned long size, - unsigned long flags) -{ - return (void __iomem *)addr; -} - -void iounmap(volatile void __iomem *addr) -{ - return; -} - -#else - -/* - * map_io_page currently only called by __ioremap - * map_io_page adds an entry to the ioremap page table - * and adds an entry to the HPT, possibly bolting it - */ -static int map_io_page(unsigned long ea, unsigned long pa, int flags) -{ - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - unsigned long vsid; - - if (mem_init_done) { - spin_lock(&init_mm.page_table_lock); - pgdp = pgd_offset_k(ea); - pudp = pud_alloc(&init_mm, pgdp, ea); - if (!pudp) - return -ENOMEM; - pmdp = pmd_alloc(&init_mm, pudp, ea); - if (!pmdp) - return -ENOMEM; - ptep = pte_alloc_kernel(&init_mm, pmdp, ea); - if (!ptep) - return -ENOMEM; - set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, - __pgprot(flags))); - spin_unlock(&init_mm.page_table_lock); - } else { - unsigned long va, vpn, hash, hpteg; - - /* - * If the mm subsystem is not fully up, we cannot create a - * linux page table entry for this mapping. Simply bolt an - * entry in the hardware page table. - */ - vsid = get_kernel_vsid(ea); - va = (vsid << 28) | (ea & 0xFFFFFFF); - vpn = va >> PAGE_SHIFT; - - hash = hpt_hash(vpn, 0); - - hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); - - /* Panic if a pte grpup is full */ - if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, - HPTE_V_BOLTED, - _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX) - == -1) { - panic("map_io_page: could not insert mapping"); - } - } - return 0; -} - - -static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, - unsigned long ea, unsigned long size, - unsigned long flags) -{ - unsigned long i; - - if ((flags & _PAGE_PRESENT) == 0) - flags |= pgprot_val(PAGE_KERNEL); - - for (i = 0; i < size; i += PAGE_SIZE) - if (map_io_page(ea+i, pa+i, flags)) - return NULL; - - return (void __iomem *) (ea + (addr & ~PAGE_MASK)); -} - - -void __iomem * -ioremap(unsigned long addr, unsigned long size) -{ - return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); -} - -void __iomem * __ioremap(unsigned long addr, unsigned long size, - unsigned long flags) -{ - unsigned long pa, ea; - void __iomem *ret; - - /* - * Choose an address to map it to. - * Once the imalloc system is running, we use it. - * Before that, we map using addresses going - * up from ioremap_bot. imalloc will use - * the addresses from ioremap_bot through - * IMALLOC_END - * - */ - pa = addr & PAGE_MASK; - size = PAGE_ALIGN(addr + size) - pa; - - if (size == 0) - return NULL; - - if (mem_init_done) { - struct vm_struct *area; - area = im_get_free_area(size); - if (area == NULL) - return NULL; - ea = (unsigned long)(area->addr); - ret = __ioremap_com(addr, pa, ea, size, flags); - if (!ret) - im_free(area->addr); - } else { - ea = ioremap_bot; - ret = __ioremap_com(addr, pa, ea, size, flags); - if (ret) - ioremap_bot += size; - } - return ret; -} - -#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) - -int __ioremap_explicit(unsigned long pa, unsigned long ea, - unsigned long size, unsigned long flags) -{ - struct vm_struct *area; - void __iomem *ret; - - /* For now, require page-aligned values for pa, ea, and size */ - if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || - !IS_PAGE_ALIGNED(size)) { - printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__); - return 1; - } - - if (!mem_init_done) { - /* Two things to consider in this case: - * 1) No records will be kept (imalloc, etc) that the region - * has been remapped - * 2) It won't be easy to iounmap() the region later (because - * of 1) - */ - ; - } else { - area = im_get_area(ea, size, - IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS); - if (area == NULL) { - /* Expected when PHB-dlpar is in play */ - return 1; - } - if (ea != (unsigned long) area->addr) { - printk(KERN_ERR "unexpected addr return from " - "im_get_area\n"); - return 1; - } - } - - ret = __ioremap_com(pa, pa, ea, size, flags); - if (ret == NULL) { - printk(KERN_ERR "ioremap_explicit() allocation failure !\n"); - return 1; - } - if (ret != (void *) ea) { - printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); - return 1; - } - - return 0; -} - -/* - * Unmap an IO region and remove it from imalloc'd list. - * Access to IO memory should be serialized by driver. - * This code is modeled after vmalloc code - unmap_vm_area() - * - * XXX what about calls before mem_init_done (ie python_countermeasures()) - */ -void iounmap(volatile void __iomem *token) -{ - void *addr; - - if (!mem_init_done) - return; - - addr = (void *) ((unsigned long __force) token & PAGE_MASK); - - im_free(addr); -} - -static int iounmap_subset_regions(unsigned long addr, unsigned long size) -{ - struct vm_struct *area; - - /* Check whether subsets of this region exist */ - area = im_get_area(addr, size, IM_REGION_SUPERSET); - if (area == NULL) - return 1; - - while (area) { - iounmap((void __iomem *) area->addr); - area = im_get_area(addr, size, - IM_REGION_SUPERSET); - } - - return 0; -} - -int iounmap_explicit(volatile void __iomem *start, unsigned long size) -{ - struct vm_struct *area; - unsigned long addr; - int rc; - - addr = (unsigned long __force) start & PAGE_MASK; - - /* Verify that the region either exists or is a subset of an existing - * region. In the latter case, split the parent region to create - * the exact region - */ - area = im_get_area(addr, size, - IM_REGION_EXISTS | IM_REGION_SUBSET); - if (area == NULL) { - /* Determine whether subset regions exist. If so, unmap */ - rc = iounmap_subset_regions(addr, size); - if (rc) { - printk(KERN_ERR - "%s() cannot unmap nonexistent range 0x%lx\n", - __FUNCTION__, addr); - return 1; - } - } else { - iounmap((void __iomem *) area->addr); - } - /* - * FIXME! This can't be right: - iounmap(area->addr); - * Maybe it should be "iounmap(area);" - */ - return 0; -} - -#endif - -EXPORT_SYMBOL(ioremap); -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(iounmap); - -void free_initmem(void) -{ - unsigned long addr; - - addr = (unsigned long)__init_begin; - for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { - memset((void *)addr, 0xcc, PAGE_SIZE); - ClearPageReserved(virt_to_page(addr)); - set_page_count(virt_to_page(addr), 1); - free_page(addr); - totalram_pages++; - } - printk ("Freeing unused kernel memory: %luk freed\n", - ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10); -} - -#ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) -{ - if (start < end) - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(virt_to_page(start)); - set_page_count(virt_to_page(start), 1); - free_page(start); - totalram_pages++; - } -} -#endif - -static DEFINE_SPINLOCK(mmu_context_lock); -static DEFINE_IDR(mmu_context_idr); - -int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - int index; - int err; - -again: - if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(&mmu_context_lock); - err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index); - spin_unlock(&mmu_context_lock); - - if (err == -EAGAIN) - goto again; - else if (err) - return err; - - if (index > MAX_CONTEXT) { - idr_remove(&mmu_context_idr, index); - return -ENOMEM; - } - - mm->context.id = index; - - return 0; -} - -void destroy_context(struct mm_struct *mm) -{ - spin_lock(&mmu_context_lock); - idr_remove(&mmu_context_idr, mm->context.id); - spin_unlock(&mmu_context_lock); - - mm->context.id = NO_CONTEXT; -} - -/* - * Do very early mm setup. - */ -void __init mm_init_ppc64(void) -{ -#ifndef CONFIG_PPC_ISERIES - unsigned long i; -#endif - - ppc64_boot_msg(0x100, "MM Init"); - - /* This is the story of the IO hole... please, keep seated, - * unfortunately, we are out of oxygen masks at the moment. - * So we need some rough way to tell where your big IO hole - * is. On pmac, it's between 2G and 4G, on POWER3, it's around - * that area as well, on POWER4 we don't have one, etc... - * We need that as a "hint" when sizing the TCE table on POWER3 - * So far, the simplest way that seem work well enough for us it - * to just assume that the first discontinuity in our physical - * RAM layout is the IO hole. That may not be correct in the future - * (and isn't on iSeries but then we don't care ;) - */ - -#ifndef CONFIG_PPC_ISERIES - for (i = 1; i < lmb.memory.cnt; i++) { - unsigned long base, prevbase, prevsize; - - prevbase = lmb.memory.region[i-1].base; - prevsize = lmb.memory.region[i-1].size; - base = lmb.memory.region[i].base; - if (base > (prevbase + prevsize)) { - io_hole_start = prevbase + prevsize; - io_hole_size = base - (prevbase + prevsize); - break; - } - } -#endif /* CONFIG_PPC_ISERIES */ - if (io_hole_start) - printk("IO Hole assumed to be %lx -> %lx\n", - io_hole_start, io_hole_start + io_hole_size - 1); - - ppc64_boot_msg(0x100, "MM Init Done"); -} - -/* - * This is called by /dev/mem to know if a given address has to - * be mapped non-cacheable or not - */ -int page_is_ram(unsigned long pfn) -{ - int i; - unsigned long paddr = (pfn << PAGE_SHIFT); - - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long base; - - base = lmb.memory.region[i].base; - - if ((paddr >= base) && - (paddr < (base + lmb.memory.region[i].size))) { - return 1; - } - } - - return 0; -} -EXPORT_SYMBOL(page_is_ram); - -/* - * Initialize the bootmem system and give it all the memory we - * have available. - */ -#ifndef CONFIG_NEED_MULTIPLE_NODES -void __init do_init_bootmem(void) -{ - unsigned long i; - unsigned long start, bootmap_pages; - unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; - int boot_mapsize; - - /* - * Find an area to use for the bootmem bitmap. Calculate the size of - * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. - * Add 1 additional page in case the address isn't page-aligned. - */ - bootmap_pages = bootmem_bootmap_pages(total_pages); - - start = lmb_alloc(bootmap_pages<> PAGE_SHIFT, total_pages); - - max_pfn = max_low_pfn; - - /* Add all physical memory to the bootmem map, mark each area - * present. - */ - for (i=0; i < lmb.memory.cnt; i++) - free_bootmem(lmb.memory.region[i].base, - lmb_size_bytes(&lmb.memory, i)); - - /* reserve the sections we're already using */ - for (i=0; i < lmb.reserved.cnt; i++) - reserve_bootmem(lmb.reserved.region[i].base, - lmb_size_bytes(&lmb.reserved, i)); - - for (i=0; i < lmb.memory.cnt; i++) - memory_present(0, lmb_start_pfn(&lmb.memory, i), - lmb_end_pfn(&lmb.memory, i)); -} - -/* - * paging_init() sets up the page tables - in fact we've already done this. - */ -void __init paging_init(void) -{ - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long total_ram = lmb_phys_mem_size(); - unsigned long top_of_ram = lmb_end_of_DRAM(); - - printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", - top_of_ram, total_ram); - printk(KERN_INFO "Memory hole size: %ldMB\n", - (top_of_ram - total_ram) >> 20); - /* - * All pages are DMA-able so we put them all in the DMA zone. - */ - memset(zones_size, 0, sizeof(zones_size)); - memset(zholes_size, 0, sizeof(zholes_size)); - - zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; - zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; - - free_area_init_node(0, NODE_DATA(0), zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); -} -#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ - -static struct kcore_list kcore_vmem; - -static int __init setup_kcore(void) -{ - int i; - - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long base, size; - struct kcore_list *kcore_mem; - - base = lmb.memory.region[i].base; - size = lmb.memory.region[i].size; - - /* GFP_ATOMIC to avoid might_sleep warnings during boot */ - kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); - if (!kcore_mem) - panic("mem_init: kmalloc failed\n"); - - kclist_add(kcore_mem, __va(base), size); - } - - kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); - - return 0; -} -module_init(setup_kcore); - -void __init mem_init(void) -{ -#ifdef CONFIG_NEED_MULTIPLE_NODES - int nid; -#endif - pg_data_t *pgdat; - unsigned long i; - struct page *page; - unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; - - num_physpages = max_low_pfn; /* RAM is assumed contiguous */ - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); - -#ifdef CONFIG_NEED_MULTIPLE_NODES - for_each_online_node(nid) { - if (NODE_DATA(nid)->node_spanned_pages != 0) { - printk("freeing bootmem node %x\n", nid); - totalram_pages += - free_all_bootmem_node(NODE_DATA(nid)); - } - } -#else - max_mapnr = num_physpages; - totalram_pages += free_all_bootmem(); -#endif - - for_each_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; i++) { - page = pgdat_page_nr(pgdat, i); - if (PageReserved(page)) - reservedpages++; - } - } - - codesize = (unsigned long)&_etext - (unsigned long)&_stext; - initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin; - datasize = (unsigned long)&_edata - (unsigned long)&__init_end; - bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start; - - printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, " - "%luk reserved, %luk data, %luk bss, %luk init)\n", - (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), - num_physpages << (PAGE_SHIFT-10), - codesize >> 10, - reservedpages << (PAGE_SHIFT-10), - datasize >> 10, - bsssize >> 10, - initsize >> 10); - - mem_init_done = 1; - - /* Initialize the vDSO */ - vdso_init(); -} - -/* - * This is called when a page has been modified by the kernel. - * It just marks the page as not i-cache clean. We do the i-cache - * flush later when the page is given to a user process, if necessary. - */ -void flush_dcache_page(struct page *page) -{ - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &page->flags)) - clear_bit(PG_arch_1, &page->flags); -} -EXPORT_SYMBOL(flush_dcache_page); - -void clear_user_page(void *page, unsigned long vaddr, struct page *pg) -{ - clear_page(page); - - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - /* - * We shouldnt have to do this, but some versions of glibc - * require it (ld.so assumes zero filled pages are icache clean) - * - Anton - */ - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); -} -EXPORT_SYMBOL(clear_user_page); - -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, - struct page *pg) -{ - copy_page(vto, vfrom); - - /* - * We should be able to use the following optimisation, however - * there are two problems. - * Firstly a bug in some versions of binutils meant PLT sections - * were not marked executable. - * Secondly the first word in the GOT section is blrl, used - * to establish the GOT address. Until recently the GOT was - * not marked executable. - * - Anton - */ -#if 0 - if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0)) - return; -#endif - - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) - return; - - /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &pg->flags)) - clear_bit(PG_arch_1, &pg->flags); -} - -void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, - unsigned long addr, int len) -{ - unsigned long maddr; - - maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK); - flush_icache_range(maddr, maddr + len); -} -EXPORT_SYMBOL(flush_icache_user_range); - -/* - * This is called at the end of handling a user page fault, when the - * fault has been handled by updating a PTE in the linux page tables. - * We use it to preload an HPTE into the hash table corresponding to - * the updated linux PTE. - * - * This must always be called with the mm->page_table_lock held - */ -void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea, - pte_t pte) -{ - unsigned long vsid; - void *pgdir; - pte_t *ptep; - int local = 0; - cpumask_t tmp; - unsigned long flags; - - /* handle i-cache coherency */ - if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && - !cpu_has_feature(CPU_FTR_NOEXECUTE)) { - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - if (!PageReserved(page) - && !test_bit(PG_arch_1, &page->flags)) { - __flush_dcache_icache(page_address(page)); - set_bit(PG_arch_1, &page->flags); - } - } - } - - /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ - if (!pte_young(pte)) - return; - - pgdir = vma->vm_mm->pgd; - if (pgdir == NULL) - return; - - ptep = find_linux_pte(pgdir, ea); - if (!ptep) - return; - - vsid = get_vsid(vma->vm_mm->context.id, ea); - - local_irq_save(flags); - tmp = cpumask_of_cpu(smp_processor_id()); - if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) - local = 1; - - __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, - 0x300, local); - local_irq_restore(flags); -} - -void __iomem * reserve_phb_iospace(unsigned long size) -{ - void __iomem *virt_addr; - - if (phbs_io_bot >= IMALLOC_BASE) - panic("reserve_phb_iospace(): phb io space overflow\n"); - - virt_addr = (void __iomem *) phbs_io_bot; - phbs_io_bot += size; - - return virt_addr; -} - -static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) -{ - memset(addr, 0, kmem_cache_size(cache)); -} - -static const int pgtable_cache_size[2] = { - PTE_TABLE_SIZE, PMD_TABLE_SIZE -}; -static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { - "pgd_pte_cache", "pud_pmd_cache", -}; - -kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; - -void pgtable_cache_init(void) -{ - int i; - - BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]); - BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]); - BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]); - BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]); - - for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { - int size = pgtable_cache_size[i]; - const char *name = pgtable_cache_name[i]; - - pgtable_cache[i] = kmem_cache_create(name, - size, size, - SLAB_HWCACHE_ALIGN - | SLAB_MUST_HWCACHE_ALIGN, - zero_ctor, - NULL); - if (! pgtable_cache[i]) - panic("pgtable_cache_init(): could not create %s!\n", - name); - } -} - -pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, - unsigned long size, pgprot_t vma_prot) -{ - if (ppc_md.phys_mem_access_prot) - return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); - - if (!page_is_ram(addr >> PAGE_SHIFT)) - vma_prot = __pgprot(pgprot_val(vma_prot) - | _PAGE_GUARDED | _PAGE_NO_CACHE); - return vma_prot; -} -EXPORT_SYMBOL(phys_mem_access_prot); From 69a80d3f69d0b2d7fae5a73c6e034d402d434d8a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:03:41 +1000 Subject: [PATCH 0232/1940] powerpc: move pSeries files to arch/powerpc/platforms/pseries Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/Makefile | 1 + arch/powerpc/platforms/pseries/Makefile | 4 ++ .../platforms/pseries/hvCall.S} | 0 .../platforms/pseries/iommu.c} | 0 .../platforms/pseries/lpar.c} | 0 .../platforms/pseries/nvram.c} | 0 .../platforms/pseries/pci.c} | 0 .../platforms/pseries/reconfig.c} | 0 .../platforms/pseries/setup.c} | 6 +-- .../platforms/pseries/smp.c} | 48 +------------------ .../platforms/pseries/vio.c} | 0 arch/ppc64/kernel/Makefile | 4 +- 12 files changed, 10 insertions(+), 53 deletions(-) create mode 100644 arch/powerpc/platforms/pseries/Makefile rename arch/{ppc64/kernel/pSeries_hvCall.S => powerpc/platforms/pseries/hvCall.S} (100%) rename arch/{ppc64/kernel/pSeries_iommu.c => powerpc/platforms/pseries/iommu.c} (100%) rename arch/{ppc64/kernel/pSeries_lpar.c => powerpc/platforms/pseries/lpar.c} (100%) rename arch/{ppc64/kernel/pSeries_nvram.c => powerpc/platforms/pseries/nvram.c} (100%) rename arch/{ppc64/kernel/pSeries_pci.c => powerpc/platforms/pseries/pci.c} (100%) rename arch/{ppc64/kernel/pSeries_reconfig.c => powerpc/platforms/pseries/reconfig.c} (100%) rename arch/{ppc64/kernel/pSeries_setup.c => powerpc/platforms/pseries/setup.c} (99%) rename arch/{ppc64/kernel/pSeries_smp.c => powerpc/platforms/pseries/smp.c} (92%) rename arch/{ppc64/kernel/pSeries_vio.c => powerpc/platforms/pseries/vio.c} (100%) diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 7637ff3642c3..181ae612b2d3 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -4,4 +4,5 @@ endif obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_83xx) += 83xx/ obj-$(CONFIG_85xx) += 85xx/ +obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile new file mode 100644 index 000000000000..9ebb34180a10 --- /dev/null +++ b/arch/powerpc/platforms/pseries/Makefile @@ -0,0 +1,4 @@ +obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ + setup.o iommu.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_IBMVIO) += vio.o diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S similarity index 100% rename from arch/ppc64/kernel/pSeries_hvCall.S rename to arch/powerpc/platforms/pseries/hvCall.S diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/powerpc/platforms/pseries/iommu.c similarity index 100% rename from arch/ppc64/kernel/pSeries_iommu.c rename to arch/powerpc/platforms/pseries/iommu.c diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/powerpc/platforms/pseries/lpar.c similarity index 100% rename from arch/ppc64/kernel/pSeries_lpar.c rename to arch/powerpc/platforms/pseries/lpar.c diff --git a/arch/ppc64/kernel/pSeries_nvram.c b/arch/powerpc/platforms/pseries/nvram.c similarity index 100% rename from arch/ppc64/kernel/pSeries_nvram.c rename to arch/powerpc/platforms/pseries/nvram.c diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/powerpc/platforms/pseries/pci.c similarity index 100% rename from arch/ppc64/kernel/pSeries_pci.c rename to arch/powerpc/platforms/pseries/pci.c diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c similarity index 100% rename from arch/ppc64/kernel/pSeries_reconfig.c rename to arch/powerpc/platforms/pseries/reconfig.c diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/powerpc/platforms/pseries/setup.c similarity index 99% rename from arch/ppc64/kernel/pSeries_setup.c rename to arch/powerpc/platforms/pseries/setup.c index 5a9fe96f9f67..eb25ee2eead8 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -64,8 +64,8 @@ #include #include #include - -#include "i8259.h" +#include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -124,7 +124,7 @@ static int pSeries_irq_cascade(struct pt_regs *regs, void *data) if (chrp_int_ack_special) return readb(chrp_int_ack_special); else - return i8259_irq(smp_processor_id()); + return i8259_irq(regs); } static void __init pSeries_init_mpic(void) diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/powerpc/platforms/pseries/smp.c similarity index 92% rename from arch/ppc64/kernel/pSeries_smp.c rename to arch/powerpc/platforms/pseries/smp.c index 5d1ed850f47b..ae1bd270f308 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -1,5 +1,5 @@ /* - * SMP support for pSeries and BPA machines. + * SMP support for pSeries machines. * * Dave Engebretsen, Peter Bergner, and * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com @@ -48,8 +48,6 @@ #include #include -#include "bpa_iic.h" - #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else @@ -343,36 +341,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) } #endif /* CONFIG_XICS */ -#ifdef CONFIG_BPA_IIC -static void smp_iic_message_pass(int target, int msg) -{ - unsigned int i; - - if (target < NR_CPUS) { - iic_cause_IPI(target, msg); - } else { - for_each_online_cpu(i) { - if (target == MSG_ALL_BUT_SELF - && i == smp_processor_id()) - continue; - iic_cause_IPI(i, msg); - } - } -} - -static int __init smp_iic_probe(void) -{ - iic_request_IPIs(); - - return cpus_weight(cpu_possible_map); -} - -static void __devinit smp_iic_setup_cpu(int cpu) -{ - if (cpu != boot_cpuid) - iic_setup_cpu(); -} -#endif /* CONFIG_BPA_IIC */ static DEFINE_SPINLOCK(timebase_lock); static unsigned long timebase = 0; @@ -444,15 +412,6 @@ static struct smp_ops_t pSeries_xics_smp_ops = { .cpu_bootable = smp_pSeries_cpu_bootable, }; #endif -#ifdef CONFIG_BPA_IIC -static struct smp_ops_t bpa_iic_smp_ops = { - .message_pass = smp_iic_message_pass, - .probe = smp_iic_probe, - .kick_cpu = smp_pSeries_kick_cpu, - .setup_cpu = smp_iic_setup_cpu, - .cpu_bootable = smp_pSeries_cpu_bootable, -}; -#endif /* This is called very early */ void __init smp_init_pSeries(void) @@ -471,11 +430,6 @@ void __init smp_init_pSeries(void) case IC_PPC_XIC: smp_ops = &pSeries_xics_smp_ops; break; -#endif -#ifdef CONFIG_BPA_IIC - case IC_BPA_IIC: - smp_ops = &bpa_iic_smp_ops; - break; #endif default: panic("Invalid interrupt controller"); diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/powerpc/platforms/pseries/vio.c similarity index 100% rename from arch/ppc64/kernel/pSeries_vio.c rename to arch/powerpc/platforms/pseries/vio.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 32fd3f1c7935..6a0fea272386 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -24,9 +24,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o -obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ - pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ - pSeries_setup.o pSeries_iommu.o udbg_16550.o +obj-$(CONFIG_PPC_PSERIES) += rtasd.o ras.o udbg_16550.o obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ bpa_iic.o spider-pic.o From c17e3325ba603642922219b19623764ba5280ad4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:07:35 +1000 Subject: [PATCH 0233/1940] ppc64: Use SPRN_ prefix for special purpose register names Now that we are using the merged reg.h we have to use the SPRN_xxx names rather than the xxx names. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/entry.S | 30 +++--- arch/ppc64/kernel/head.S | 194 +++++++++++++++++++------------------- 2 files changed, 112 insertions(+), 112 deletions(-) diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index e8c0bbf4d000..ea30af810e0c 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -191,8 +191,8 @@ syscall_exit_trace_cont: ld r1,GPR1(r1) mtlr r4 mtcr r5 - mtspr SRR0,r7 - mtspr SRR1,r8 + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r8 rfid b . /* prevent speculative execution */ @@ -531,7 +531,7 @@ restore: mtctr r3 mtlr r0 ld r3,_XER(r1) - mtspr XER,r3 + mtspr SPRN_XER,r3 REST_8GPRS(5, r1) @@ -543,12 +543,12 @@ restore: mtmsrd r0,1 ld r0,_MSR(r1) - mtspr SRR1,r0 + mtspr SPRN_SRR1,r0 ld r2,_CCR(r1) mtcrf 0xFF,r2 ld r2,_NIP(r1) - mtspr SRR0,r2 + mtspr SPRN_SRR0,r2 ld r0,GPR0(r1) ld r2,GPR2(r1) @@ -643,7 +643,7 @@ _GLOBAL(enter_rtas) std r4,_CCR(r1) mfctr r5 std r5,_CTR(r1) - mfspr r6,XER + mfspr r6,SPRN_XER std r6,_XER(r1) mfdar r7 std r7,_DAR(r1) @@ -697,14 +697,14 @@ _GLOBAL(enter_rtas) ld r5,RTASENTRY(r4) /* get the rtas->entry value */ ld r4,RTASBASE(r4) /* get the rtas->base value */ - mtspr SRR0,r5 - mtspr SRR1,r6 + mtspr SPRN_SRR0,r5 + mtspr SPRN_SRR1,r6 rfid b . /* prevent speculative execution */ _STATIC(rtas_return_loc) /* relocation is off at this point */ - mfspr r4,SPRG3 /* Get PACA */ + mfspr r4,SPRN_SPRG3 /* Get PACA */ SET_REG_TO_CONST(r5, KERNELBASE) sub r4,r4,r5 /* RELOC the PACA base pointer */ @@ -718,8 +718,8 @@ _STATIC(rtas_return_loc) LOADADDR(r3,.rtas_restore_regs) ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ - mtspr SRR0,r3 - mtspr SRR1,r4 + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ @@ -730,14 +730,14 @@ _STATIC(rtas_restore_regs) REST_8GPRS(14, r1) /* Restore the non-volatiles */ REST_10GPRS(22, r1) /* ditto */ - mfspr r13,SPRG3 + mfspr r13,SPRN_SPRG3 ld r4,_CCR(r1) mtcr r4 ld r5,_CTR(r1) mtctr r5 ld r6,_XER(r1) - mtspr XER,r6 + mtspr SPRN_XER,r6 ld r7,_DAR(r1) mtdar r7 ld r8,_DSISR(r1) @@ -774,7 +774,7 @@ _GLOBAL(enter_prom) std r4,_CCR(r1) mfctr r5 std r5,_CTR(r1) - mfspr r6,XER + mfspr r6,SPRN_XER std r6,_XER(r1) mfdar r7 std r7,_DAR(r1) @@ -827,7 +827,7 @@ _GLOBAL(enter_prom) ld r5,_CTR(r1) mtctr r5 ld r6,_XER(r1) - mtspr XER,r6 + mtspr SPRN_XER,r6 ld r7,_DAR(r1) mtdar r7 ld r8,_DSISR(r1) diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index db0cd3587627..d5e6be200764 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -201,22 +201,22 @@ exception_marker: #define EX_CCR 60 #define EXCEPTION_PROLOG_PSERIES(area, label) \ - mfspr r13,SPRG3; /* get paca address into r13 */ \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r10,area+EX_R10(r13); \ std r11,area+EX_R11(r13); \ std r12,area+EX_R12(r13); \ - mfspr r9,SPRG1; \ + mfspr r9,SPRN_SPRG1; \ std r9,area+EX_R13(r13); \ mfcr r9; \ clrrdi r12,r13,32; /* get high part of &label */ \ mfmsr r10; \ - mfspr r11,SRR0; /* save SRR0 */ \ + mfspr r11,SPRN_SRR0; /* save SRR0 */ \ ori r12,r12,(label)@l; /* virt addr of handler */ \ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ - mtspr SRR0,r12; \ - mfspr r12,SRR1; /* and SRR1 */ \ - mtspr SRR1,r10; \ + mtspr SPRN_SRR0,r12; \ + mfspr r12,SPRN_SRR1; /* and SRR1 */ \ + mtspr SPRN_SRR1,r10; \ rfid; \ b . /* prevent speculative execution */ @@ -225,12 +225,12 @@ exception_marker: * This code runs with relocation on. */ #define EXCEPTION_PROLOG_ISERIES_1(area) \ - mfspr r13,SPRG3; /* get paca address into r13 */ \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r10,area+EX_R10(r13); \ std r11,area+EX_R11(r13); \ std r12,area+EX_R12(r13); \ - mfspr r9,SPRG1; \ + mfspr r9,SPRN_SPRG1; \ std r9,area+EX_R13(r13); \ mfcr r9 @@ -283,7 +283,7 @@ exception_marker: std r9,_LINK(r1); \ mfctr r10; /* save CTR in stackframe */ \ std r10,_CTR(r1); \ - mfspr r11,XER; /* save XER in stackframe */ \ + mfspr r11,SPRN_XER; /* save XER in stackframe */ \ std r11,_XER(r1); \ li r9,(n)+1; \ std r9,_TRAP(r1); /* set trap number */ \ @@ -300,7 +300,7 @@ exception_marker: .globl label##_pSeries; \ label##_pSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) @@ -308,7 +308,7 @@ label##_pSeries: \ .globl label##_iSeries; \ label##_iSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(area); \ EXCEPTION_PROLOG_ISERIES_2; \ @@ -318,7 +318,7 @@ label##_iSeries: \ .globl label##_iSeries; \ label##_iSeries: \ HMT_MEDIUM; \ - mtspr SPRG1,r13; /* save r13 */ \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ lbz r10,PACAPROCENABLED(r13); \ @@ -388,7 +388,7 @@ __start_interrupts: . = 0x200 _machine_check_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ RUNLATCH_ON(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) @@ -396,18 +396,18 @@ _machine_check_pSeries: .globl data_access_pSeries data_access_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 BEGIN_FTR_SECTION - mtspr SPRG2,r12 - mfspr r13,DAR - mfspr r12,DSISR + mtspr SPRN_SPRG2,r12 + mfspr r13,SPRN_DAR + mfspr r12,SPRN_DSISR srdi r13,r13,60 rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c beq .do_stab_bolted_pSeries mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) @@ -415,19 +415,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) .globl data_access_slb_pSeries data_access_slb_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 RUNLATCH_ON(r13) - mfspr r13,SPRG3 /* get paca address into r13 */ + mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) std r11,PACA_EXSLB+EX_R11(r13) std r12,PACA_EXSLB+EX_R12(r13) std r3,PACA_EXSLB+EX_R3(r13) - mfspr r9,SPRG1 + mfspr r9,SPRN_SPRG1 std r9,PACA_EXSLB+EX_R13(r13) mfcr r9 - mfspr r12,SRR1 /* and SRR1 */ - mfspr r3,DAR + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mfspr r3,SPRN_DAR b .do_slb_miss /* Rel. branch works in real mode */ STD_EXCEPTION_PSERIES(0x400, instruction_access) @@ -436,19 +436,19 @@ data_access_slb_pSeries: .globl instruction_access_slb_pSeries instruction_access_slb_pSeries: HMT_MEDIUM - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 RUNLATCH_ON(r13) - mfspr r13,SPRG3 /* get paca address into r13 */ + mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) std r11,PACA_EXSLB+EX_R11(r13) std r12,PACA_EXSLB+EX_R12(r13) std r3,PACA_EXSLB+EX_R3(r13) - mfspr r9,SPRG1 + mfspr r9,SPRN_SPRG1 std r9,PACA_EXSLB+EX_R13(r13) mfcr r9 - mfspr r12,SRR1 /* and SRR1 */ - mfspr r3,SRR0 /* SRR0 is faulting address */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ b .do_slb_miss /* Rel. branch works in real mode */ STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) @@ -466,15 +466,15 @@ system_call_pSeries: RUNLATCH_ON(r9) mr r9,r13 mfmsr r10 - mfspr r13,SPRG3 - mfspr r11,SRR0 + mfspr r13,SPRN_SPRG3 + mfspr r11,SPRN_SRR0 clrrdi r12,r13,32 oris r12,r12,system_call_common@h ori r12,r12,system_call_common@l - mtspr SRR0,r12 + mtspr SPRN_SRR0,r12 ori r10,r10,MSR_IR|MSR_DR|MSR_RI - mfspr r12,SRR1 - mtspr SRR1,r10 + mfspr r12,SPRN_SRR1 + mtspr SPRN_SRR1,r10 rfid b . /* prevent speculative execution */ @@ -504,25 +504,25 @@ system_call_pSeries: .align 7 _GLOBAL(do_stab_bolted_pSeries) mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) /* * Vectors for the FWNMI option. Share common code. */ - .globl system_reset_fwnmi + .globl system_reset_fwnmi system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - .globl machine_check_fwnmi + .globl machine_check_fwnmi machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ @@ -531,18 +531,18 @@ machine_check_fwnmi: .globl data_access_iSeries data_access_iSeries: - mtspr SPRG1,r13 + mtspr SPRN_SPRG1,r13 BEGIN_FTR_SECTION - mtspr SPRG2,r12 - mfspr r13,DAR - mfspr r12,DSISR + mtspr SPRN_SPRG2,r12 + mfspr r13,SPRN_DAR + mfspr r12,SPRN_DSISR srdi r13,r13,60 rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c beq .do_stab_bolted_iSeries mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) EXCEPTION_PROLOG_ISERIES_2 @@ -550,25 +550,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) .do_stab_bolted_iSeries: mtcrf 0x80,r12 - mfspr r12,SPRG2 + mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) EXCEPTION_PROLOG_ISERIES_2 b .do_stab_bolted .globl data_access_slb_iSeries data_access_slb_iSeries: - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) std r3,PACA_EXSLB+EX_R3(r13) ld r12,PACALPPACA+LPPACASRR1(r13) - mfspr r3,DAR + mfspr r3,SPRN_DAR b .do_slb_miss STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) .globl instruction_access_slb_iSeries instruction_access_slb_iSeries: - mtspr SPRG1,r13 /* save r13 */ + mtspr SPRN_SPRG1,r13 /* save r13 */ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) std r3,PACA_EXSLB+EX_R3(r13) ld r12,PACALPPACA+LPPACASRR1(r13) @@ -586,7 +586,7 @@ instruction_access_slb_iSeries: .globl system_call_iSeries system_call_iSeries: mr r9,r13 - mfspr r13,SPRG3 + mfspr r13,SPRN_SPRG3 EXCEPTION_PROLOG_ISERIES_2 b system_call_common @@ -596,7 +596,7 @@ system_call_iSeries: .globl system_reset_iSeries system_reset_iSeries: - mfspr r13,SPRG3 /* Get paca address */ + mfspr r13,SPRN_SPRG3 /* Get paca address */ mfmsr r24 ori r24,r24,MSR_RI mtmsrd r24 /* RI on */ @@ -639,7 +639,7 @@ iSeries_secondary_smp_loop: #endif /* CONFIG_SMP */ li r0,-1 /* r0=-1 indicates a Hypervisor call */ sc /* Invoke the hypervisor via a system call */ - mfspr r13,SPRG3 /* Put r13 back ???? */ + mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */ b 1b /* If SMP not configured, secondaries * loop forever */ @@ -656,8 +656,8 @@ hardware_interrupt_iSeries_masked: mtcrf 0x80,r9 /* Restore regs */ ld r11,PACALPPACA+LPPACASRR0(r13) ld r12,PACALPPACA+LPPACASRR1(r13) - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 ld r9,PACA_EXGEN+EX_R9(r13) ld r10,PACA_EXGEN+EX_R10(r13) ld r11,PACA_EXGEN+EX_R11(r13) @@ -713,8 +713,8 @@ bad_stack: std r10,GPR1(r1) std r11,_NIP(r1) std r12,_MSR(r1) - mfspr r11,DAR - mfspr r12,DSISR + mfspr r11,SPRN_DAR + mfspr r12,SPRN_DSISR std r11,_DAR(r1) std r12,_DSISR(r1) mflr r10 @@ -766,8 +766,8 @@ fast_exception_return: clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ mtmsrd r10,1 - mtspr SRR1,r12 - mtspr SRR0,r11 + mtspr SPRN_SRR1,r12 + mtspr SPRN_SRR0,r11 REST_4GPRS(10, r1) ld r1,GPR1(r1) rfid @@ -788,9 +788,9 @@ unrecov_fer: .globl data_access_common data_access_common: RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */ - mfspr r10,DAR + mfspr r10,SPRN_DAR std r10,PACA_EXGEN+EX_DAR(r13) - mfspr r10,DSISR + mfspr r10,SPRN_DSISR stw r10,PACA_EXGEN+EX_DSISR(r13) EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) ld r3,PACA_EXGEN+EX_DAR(r13) @@ -821,9 +821,9 @@ hardware_interrupt_entry: .align 7 .globl alignment_common alignment_common: - mfspr r10,DAR + mfspr r10,SPRN_DAR std r10,PACA_EXGEN+EX_DAR(r13) - mfspr r10,DSISR + mfspr r10,SPRN_DSISR stw r10,PACA_EXGEN+EX_DSISR(r13) EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) ld r3,PACA_EXGEN+EX_DAR(r13) @@ -1120,7 +1120,7 @@ _GLOBAL(do_stab_bolted) /* Hash to the primary group */ ld r10,PACASTABVIRT(r13) - mfspr r11,DAR + mfspr r11,SPRN_DAR srdi r11,r11,28 rldimi r10,r11,7,52 /* r10 = first ste of the group */ @@ -1162,7 +1162,7 @@ _GLOBAL(do_stab_bolted) 2: std r9,8(r10) /* Store the vsid part of the ste */ eieio - mfspr r11,DAR /* Get the new esid */ + mfspr r11,SPRN_DAR /* Get the new esid */ clrrdi r11,r11,28 /* Permits a full 32b of ESID */ ori r11,r11,0x90 /* Turn on valid and kp */ std r11,0(r10) /* Put new entry back into the stab */ @@ -1182,8 +1182,8 @@ _GLOBAL(do_stab_bolted) clrrdi r10,r10,2 mtmsrd r10,1 - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 ld r9,PACA_EXSLB+EX_R9(r13) ld r10,PACA_EXSLB+EX_R10(r13) ld r11,PACA_EXSLB+EX_R11(r13) @@ -1229,8 +1229,8 @@ _GLOBAL(do_slb_miss) .machine pop #ifdef CONFIG_PPC_ISERIES - mtspr SRR0,r11 - mtspr SRR1,r12 + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 #endif /* CONFIG_PPC_ISERIES */ ld r9,PACA_EXSLB+EX_R9(r13) ld r10,PACA_EXSLB+EX_R10(r13) @@ -1316,7 +1316,7 @@ _GLOBAL(pSeries_secondary_smp_init) mr r3,r24 /* not found, copy phys to r3 */ b .kexec_wait /* next kernel might do better */ -2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ +2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 3: HMT_LOW @@ -1587,7 +1587,7 @@ _GLOBAL(pmac_secondary_start) LOADADDR(r4, paca) /* Get base vaddr of paca array */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r4 /* for this processor. */ - mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) @@ -1622,7 +1622,7 @@ _GLOBAL(__secondary_start) /* Initialize the page table pointer register. */ LOADADDR(r6,_SDR1) ld r6,0(r6) /* get the value of _SDR1 */ - mtspr SDR1,r6 /* set the htab location */ + mtspr SPRN_SDR1,r6 /* set the htab location */ #endif /* Initialize the first segment table (or SLB) entry */ ld r3,PACASTABVIRT(r13) /* get addr of segment table */ @@ -1651,7 +1651,7 @@ _GLOBAL(__secondary_start) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ beq 98f /* branch if result is 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ beq 97f @@ -1675,8 +1675,8 @@ _GLOBAL(__secondary_start) #ifdef DO_SOFT_DISABLE ori r4,r4,MSR_EE #endif - mtspr SRR0,r3 - mtspr SRR1,r4 + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ @@ -1738,7 +1738,7 @@ _STATIC(start_here_multiplatform) #ifdef CONFIG_HMT /* Start up the second thread on cpu 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x34 /* Pulsar */ beq 90f @@ -1798,7 +1798,7 @@ _STATIC(start_here_multiplatform) mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ sub r13,r13,r26 /* convert to physical addr */ - mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ + mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1815,7 +1815,7 @@ _STATIC(start_here_multiplatform) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ beq 98f /* branch if result is 0 */ - mfspr r3,PVR + mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ beq 97f @@ -1839,12 +1839,12 @@ _STATIC(start_here_multiplatform) LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ - mtspr SDR1,r6 /* set the htab location */ + mtspr SPRN_SDR1,r6 /* set the htab location */ 98: LOADADDR(r3,.start_here_common) SET_REG_TO_CONST(r4, MSR_KERNEL) - mtspr SRR0,r3 - mtspr SRR1,r4 + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -1875,7 +1875,7 @@ _STATIC(start_here_common) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ - mtspr SPRG3,r13 + mtspr SPRN_SPRG3,r13 /* ptr to current */ LOADADDR(r4,init_task) @@ -1902,7 +1902,7 @@ _STATIC(start_here_common) _GLOBAL(hmt_init) #ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) - mfspr r7,PVR + mfspr r7,SPRN_PVR srwi r7,r7,16 cmpwi r7,0x34 /* Pulsar */ beq 90f @@ -1911,10 +1911,10 @@ _GLOBAL(hmt_init) cmpwi r7,0x37 /* SStar */ beq 91f b 101f -90: mfspr r6,PIR +90: mfspr r6,SPRN_PIR andi. r6,r6,0x1f b 92f -91: mfspr r6,PIR +91: mfspr r6,SPRN_PIR andi. r6,r6,0x3ff 92: sldi r4,r24,3 stwx r6,r5,r4 @@ -1925,8 +1925,8 @@ __hmt_secondary_hold: LOADADDR(r5, hmt_thread_data) clrldi r5,r5,4 li r7,0 - mfspr r6,PIR - mfspr r8,PVR + mfspr r6,SPRN_PIR + mfspr r8,SPRN_PVR srwi r8,r8,16 cmpwi r8,0x34 bne 93f @@ -1952,19 +1952,19 @@ __hmt_secondary_hold: _GLOBAL(hmt_start_secondary) LOADADDR(r4,__hmt_secondary_hold) clrldi r4,r4,4 - mtspr NIADORM, r4 - mfspr r4, MSRDORM + mtspr SPRN_NIADORM, r4 + mfspr r4, SPRN_MSRDORM li r5, -65 and r4, r4, r5 - mtspr MSRDORM, r4 + mtspr SPRN_MSRDORM, r4 lis r4,0xffef ori r4,r4,0x7403 - mtspr TSC, r4 + mtspr SPRN_TSC, r4 li r4,0x1f4 - mtspr TST, r4 - mfspr r4, HID0 + mtspr SPRN_TST, r4 + mfspr r4, SPRN_HID0 ori r4, r4, 0x1 - mtspr HID0, r4 + mtspr SPRN_HID0, r4 mfspr r4, SPRN_CTRLF oris r4, r4, 0x40 mtspr SPRN_CTRLT, r4 From f6d57916db2009bd7e220472200cd131fc010d64 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:13:53 +1000 Subject: [PATCH 0234/1940] powerpc: rename powermac files to remove pmac_ prefix Since the files are now in arch/powerpc/platforms/powermac, the pmac_ prefix that they had is redundant. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/Makefile | 13 ++++++------- .../powermac/{pmac_backlight.c => backlight.c} | 0 .../platforms/powermac/{pmac_cache.S => cache.S} | 0 .../powermac/{pmac_cpufreq.c => cpufreq.c} | 0 .../powermac/{pmac_feature.c => feature.c} | 0 .../powermac/{pmac_low_i2c.c => low_i2c.c} | 0 .../platforms/powermac/{pmac_nvram.c => nvram.c} | 0 .../platforms/powermac/{pmac_pci.c => pci.c} | 0 .../platforms/powermac/{pmac_pic.c => pic.c} | 0 .../platforms/powermac/{pmac_pic.h => pic.h} | 0 .../platforms/powermac/{pmac_setup.c => setup.c} | 0 .../platforms/powermac/{pmac_sleep.S => sleep.S} | 0 .../platforms/powermac/{pmac_smp.c => smp.c} | 0 .../platforms/powermac/{pmac_time.c => time.c} | 0 14 files changed, 6 insertions(+), 7 deletions(-) rename arch/powerpc/platforms/powermac/{pmac_backlight.c => backlight.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_cache.S => cache.S} (100%) rename arch/powerpc/platforms/powermac/{pmac_cpufreq.c => cpufreq.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_feature.c => feature.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_low_i2c.c => low_i2c.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_nvram.c => nvram.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_pci.c => pci.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_pic.c => pic.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_pic.h => pic.h} (100%) rename arch/powerpc/platforms/powermac/{pmac_setup.c => setup.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_sleep.S => sleep.S} (100%) rename arch/powerpc/platforms/powermac/{pmac_smp.c => smp.c} (100%) rename arch/powerpc/platforms/powermac/{pmac_time.c => time.c} (100%) diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 37b7341396e4..74712ede16df 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,9 +1,8 @@ -obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \ - pmac_feature.o pmac_pci.o pmac_sleep.o \ - pmac_low_i2c.o pmac_cache.o -obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o -obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o +obj-$(CONFIG_PPC_PMAC) += pic.o setup.o time.o feature.o pci.o \ + sleep.o low_i2c.o cache.o +obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o +obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o ifeq ($(CONFIG_PPC_PMAC),y) -obj-$(CONFIG_NVRAM) += pmac_nvram.o -obj-$(CONFIG_SMP) += pmac_smp.o +obj-$(CONFIG_NVRAM) += nvram.o +obj-$(CONFIG_SMP) += smp.o endif diff --git a/arch/powerpc/platforms/powermac/pmac_backlight.c b/arch/powerpc/platforms/powermac/backlight.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_backlight.c rename to arch/powerpc/platforms/powermac/backlight.c diff --git a/arch/powerpc/platforms/powermac/pmac_cache.S b/arch/powerpc/platforms/powermac/cache.S similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_cache.S rename to arch/powerpc/platforms/powermac/cache.S diff --git a/arch/powerpc/platforms/powermac/pmac_cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_cpufreq.c rename to arch/powerpc/platforms/powermac/cpufreq.c diff --git a/arch/powerpc/platforms/powermac/pmac_feature.c b/arch/powerpc/platforms/powermac/feature.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_feature.c rename to arch/powerpc/platforms/powermac/feature.c diff --git a/arch/powerpc/platforms/powermac/pmac_low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_low_i2c.c rename to arch/powerpc/platforms/powermac/low_i2c.c diff --git a/arch/powerpc/platforms/powermac/pmac_nvram.c b/arch/powerpc/platforms/powermac/nvram.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_nvram.c rename to arch/powerpc/platforms/powermac/nvram.c diff --git a/arch/powerpc/platforms/powermac/pmac_pci.c b/arch/powerpc/platforms/powermac/pci.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_pci.c rename to arch/powerpc/platforms/powermac/pci.c diff --git a/arch/powerpc/platforms/powermac/pmac_pic.c b/arch/powerpc/platforms/powermac/pic.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_pic.c rename to arch/powerpc/platforms/powermac/pic.c diff --git a/arch/powerpc/platforms/powermac/pmac_pic.h b/arch/powerpc/platforms/powermac/pic.h similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_pic.h rename to arch/powerpc/platforms/powermac/pic.h diff --git a/arch/powerpc/platforms/powermac/pmac_setup.c b/arch/powerpc/platforms/powermac/setup.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_setup.c rename to arch/powerpc/platforms/powermac/setup.c diff --git a/arch/powerpc/platforms/powermac/pmac_sleep.S b/arch/powerpc/platforms/powermac/sleep.S similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_sleep.S rename to arch/powerpc/platforms/powermac/sleep.S diff --git a/arch/powerpc/platforms/powermac/pmac_smp.c b/arch/powerpc/platforms/powermac/smp.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_smp.c rename to arch/powerpc/platforms/powermac/smp.c diff --git a/arch/powerpc/platforms/powermac/pmac_time.c b/arch/powerpc/platforms/powermac/time.c similarity index 100% rename from arch/powerpc/platforms/powermac/pmac_time.c rename to arch/powerpc/platforms/powermac/time.c From ff64208df7eb17c5526197449762ff5e04a95de6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:15:52 +1000 Subject: [PATCH 0235/1940] powerpc: Merge Kconfig.debug This merges in the ppc64 bits into arch/powerpc/Kconfig.debug Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig.debug | 61 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 19df881bf67b..0baf64ec80d0 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -2,9 +2,42 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL && PPC64 + help + This option will cause messages to be printed if free stack space + drops below a certain limit. + +config KPROBES + bool "Kprobes" + depends on DEBUG_KERNEL && PPC64 + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". + +config DEBUG_STACK_USAGE + bool "Stack utilization instrumentation" + depends on DEBUG_KERNEL && PPC64 + help + Enables the display of the minimum amount of free stack which each + task has ever had available in the sysrq-T and sysrq-P debug output. + + This option will slow down process creation somewhat. + +config DEBUGGER + bool "Enable debugger hooks" + depends on DEBUG_KERNEL + help + Include in-kernel hooks for kernel debuggers. Unless you are + intending to debug the kernel, say N here. + config KGDB bool "Include kgdb kernel debugger" - depends on DEBUG_KERNEL && (BROKEN || PPC_GEN550 || 4xx) + depends on DEBUGGER && (BROKEN || PPC_GEN550 || 4xx) select DEBUG_INFO help Include in-kernel hooks for kgdb, the Linux kernel source level @@ -40,14 +73,36 @@ config KGDB_CONSOLE config XMON bool "Include xmon kernel debugger" - depends on DEBUG_KERNEL + depends on DEBUGGER && !PPC_ISERIES help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here. + Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise + nothing will appear on the screen (xmon writes directly to the + framebuffer memory). + The cmdline option 'xmon' or 'xmon=early' will drop into xmon + very early during boot. 'xmon=on' will just enable the xmon + debugger hooks. 'xmon=off' will disable the debugger hooks + if CONFIG_XMON_DEFAULT is set. + +config XMON_DEFAULT + bool "Enable xmon by default" + depends on XMON + help + xmon is normally disabled unless booted with 'xmon=on'. + Use 'xmon=off' to disable xmon init during runtime. + +config IRQSTACKS + bool "Use separate kernel stacks when processing interrupts" + depends on PPC64 + help + If you say Y here the kernel will use separate kernel stacks + for handling hard and soft interrupts. This can help avoid + overflowing the process kernel stacks. config BDI_SWITCH bool "Include BDI-2000 user context switcher" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PPC32 help Include in-kernel support for the Abatron BDI2000 debugger. Unless you are intending to debug the kernel with one of these From b3b8dc6c07cecc1f8d52d03f677206bdf9f794c9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:20:10 +1000 Subject: [PATCH 0236/1940] powerpc: Use reg.h instead of processor.h when we just want reg names Now that the register names and bit definitions are all in reg.h, use that instead of processor.h in assembly code in a few places. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/fpu.S | 2 +- arch/powerpc/kernel/head_32.S | 6 +++--- arch/powerpc/kernel/idle_6xx.S | 2 +- arch/powerpc/kernel/vector.S | 2 +- arch/powerpc/lib/string.S | 5 ----- arch/powerpc/mm/hash_low_32.S | 2 +- 6 files changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 04e95e810b21..563d445ff584 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index d9dbbd426744..108e78ef3878 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -23,7 +23,7 @@ */ #include -#include +#include #include #include #include @@ -55,8 +55,8 @@ 1: .text - .stabs "arch/ppc/kernel/",N_SO,0,0,0f - .stabs "head.S",N_SO,0,0,0f + .stabs "arch/powerpc/kernel/",N_SO,0,0,0f + .stabs "head_32.S",N_SO,0,0,0f 0: .globl _stext _stext: diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 1a2194cf6828..444fdcc769f1 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 12cb90bc209c..66b3d03c5fa5 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -1,6 +1,6 @@ #include #include -#include +#include /* * The routines below are in assembler so we can closely control the diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S index 15d40e9ef8b1..b9ca84ed8927 100644 --- a/arch/powerpc/lib/string.S +++ b/arch/powerpc/lib/string.S @@ -13,11 +13,6 @@ #include #include - .text - .stabs "arch/powerpc/lib/",N_SO,0,0,0f - .stabs "string.S",N_SO,0,0,0f -0: - .section __ex_table,"a" #ifdef CONFIG_PPC64 .align 3 diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S index 57278a8dd132..12ccd7155bac 100644 --- a/arch/powerpc/mm/hash_low_32.S +++ b/arch/powerpc/mm/hash_low_32.S @@ -24,7 +24,7 @@ */ #include -#include +#include #include #include #include From daec962e27490be4fae9ab5a51d0c17f6e638715 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:25:26 +1000 Subject: [PATCH 0237/1940] powerpc: Use arch/powerpc/mm and arch/powerpc/lib for 64-bit This also puts a copy of indirect_pci.c in arch/powerpc/sysdev so that we don't need to build in arch/ppc/syslib. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 15 ++-- arch/powerpc/sysdev/Makefile | 4 +- arch/powerpc/sysdev/indirect_pci.c | 134 +++++++++++++++++++++++++++++ arch/ppc/syslib/Makefile | 14 --- 4 files changed, 143 insertions(+), 24 deletions(-) create mode 100644 arch/powerpc/sysdev/indirect_pci.c diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 064864065753..a4c605f469d4 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -124,15 +124,12 @@ head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o endif -core-y += arch/powerpc/kernel/ -core-y += arch/$(OLDARCH)/kernel/ -core-$(CONFIG_PPC32) += arch/powerpc/mm/ -core-$(CONFIG_PPC64) += arch/$(OLDARCH)/mm/ -core-$(CONFIG_PPC32) += arch/powerpc/lib/ -libs-$(CONFIG_PPC64) += arch/$(OLDARCH)/lib/ -core-y += arch/powerpc/sysdev/ -core-y += arch/powerpc/platforms/ -core-$(CONFIG_PPC32) += arch/ppc/syslib/ +core-y += arch/powerpc/kernel/ \ + arch/$(OLDARCH)/kernel/ \ + arch/powerpc/mm/ \ + arch/powerpc/lib/ \ + arch/powerpc/sysdev/ \ + arch/powerpc/platforms/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 26bdcd9a2a43..c649f03acf68 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1 +1,3 @@ -obj-$(CONFIG_MPIC) += mpic.o +obj-$(CONFIG_MPIC) += mpic.o +indirectpci-$(CONFIG_PPC_PMAC) = indirect_pci.o +obj-$(CONFIG_PPC32) += $(indirectpci-y) diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c new file mode 100644 index 000000000000..e71488469704 --- /dev/null +++ b/arch/powerpc/sysdev/indirect_pci.c @@ -0,0 +1,134 @@ +/* + * Support for indirect PCI bridges. + * + * Copyright (C) 1998 Gabriel Paubert. + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_PPC_INDIRECT_PCI_BE +#define PCI_CFG_OUT out_be32 +#else +#define PCI_CFG_OUT out_le32 +#endif + +static int +indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + volatile void __iomem *cfg_data; + u8 cfg_type = 0; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (hose->set_cfg_type) + if (bus->number != hose->first_busno) + cfg_type = 1; + + PCI_CFG_OUT(hose->cfg_addr, + (0x80000000 | ((bus->number - hose->bus_offset) << 16) + | (devfn << 8) | ((offset & 0xfc) | cfg_type))); + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + (offset & 3); + switch (len) { + case 1: + *val = in_8(cfg_data); + break; + case 2: + *val = in_le16(cfg_data); + break; + default: + *val = in_le32(cfg_data); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + volatile void __iomem *cfg_data; + u8 cfg_type = 0; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (hose->set_cfg_type) + if (bus->number != hose->first_busno) + cfg_type = 1; + + PCI_CFG_OUT(hose->cfg_addr, + (0x80000000 | ((bus->number - hose->bus_offset) << 16) + | (devfn << 8) | ((offset & 0xfc) | cfg_type))); + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + (offset & 3); + switch (len) { + case 1: + out_8(cfg_data, val); + break; + case 2: + out_le16(cfg_data, val); + break; + default: + out_le32(cfg_data, val); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops indirect_pci_ops = +{ + indirect_read_config, + indirect_write_config +}; + +void __init +setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr, + void __iomem * cfg_data) +{ + hose->cfg_addr = cfg_addr; + hose->cfg_data = cfg_data; + hose->ops = &indirect_pci_ops; +} + +void __init +setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) +{ + unsigned long base = cfg_addr & PAGE_MASK; + void __iomem *mbase, *addr, *data; + + mbase = ioremap(base, PAGE_SIZE); + addr = mbase + (cfg_addr & ~PAGE_MASK); + if ((cfg_data & PAGE_MASK) != base) + mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); + data = mbase + (cfg_data & ~PAGE_MASK); + setup_indirect_pci_nomap(hose, addr, data); +} diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 1b0a84931afc..b8d08f33f7ee 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -5,7 +5,6 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC -ifneq ($(CONFIG_PPC_MERGE),y) wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o @@ -110,16 +109,3 @@ obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \ ifeq ($(CONFIG_PPC_MPC52xx),y) obj-$(CONFIG_PCI) += mpc52xx_pci.o endif - -else -# Stuff still needed by the merged powerpc sources - -obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o -obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o -obj-$(CONFIG_PPC_PMAC) += indirect_pci.o -obj-$(CONFIG_PPC_CHRP) += indirect_pci.o i8259.o -obj-$(CONFIG_PPC_PREP) += indirect_pci.o i8259.o todc_time.o -obj-$(CONFIG_BOOTX_TEXT) += btext.o -obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o - -endif From 06d67d54741a5bfefa31945ef195dfa748c29025 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:29:05 +1000 Subject: [PATCH 0238/1940] powerpc: make process.c suitable for both 32-bit and 64-bit Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/init_task.c | 36 +++ arch/powerpc/kernel/process.c | 446 ++++++++++++++++++++++---------- include/asm-powerpc/elf.h | 6 +- 3 files changed, 352 insertions(+), 136 deletions(-) create mode 100644 arch/powerpc/kernel/init_task.c diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c new file mode 100644 index 000000000000..941043ae040f --- /dev/null +++ b/arch/powerpc/kernel/init_task.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); + +EXPORT_SYMBOL(init_mm); + +/* + * Initial thread structure. + * + * We need to make sure that this is 16384-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ae316e9ed581..f09908a0beea 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -44,6 +46,11 @@ #include #include #include +#ifdef CONFIG_PPC64 +#include +#include +#include +#endif extern unsigned long _get_SP(void); @@ -53,26 +60,6 @@ struct task_struct *last_task_used_altivec = NULL; struct task_struct *last_task_used_spe = NULL; #endif -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -struct mm_struct init_mm = INIT_MM(init_mm); -EXPORT_SYMBOL(init_mm); - -/* this is 8kB-aligned so we can get to the thread_info struct - at the base of it from the stack pointer with 1 integer instruction. */ -union thread_union init_thread_union - __attribute__((__section__(".data.init_task"))) = -{ INIT_THREAD_INFO(init_task) }; - -/* initial task structure */ -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); - -/* only used to get secondary processor up */ -struct task_struct *current_set[NR_CPUS] = {&init_task, }; - /* * Make sure the floating-point register state in the * the thread_struct is up to date for task tsk. @@ -237,7 +224,10 @@ int set_dabr(unsigned long dabr) return ret; } +#ifdef CONFIG_PPC64 +DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); static DEFINE_PER_CPU(unsigned long, current_dabr); +#endif struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) @@ -308,10 +298,27 @@ struct task_struct *__switch_to(struct task_struct *prev, set_dabr(new->thread.dabr); __get_cpu_var(current_dabr) = new->thread.dabr; } + + flush_tlb_pending(); #endif new_thread = &new->thread; old_thread = ¤t->thread; + +#ifdef CONFIG_PPC64 + /* + * Collect processor utilization data per process + */ + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); + long unsigned start_tb, current_tb; + start_tb = old_thread->start_tb; + cu->current_tb = current_tb = mfspr(SPRN_PURR); + old_thread->accum_tb += (current_tb - start_tb); + new_thread->start_tb = current_tb; + } +#endif + local_irq_save(flags); last = _switch(old_thread, new_thread); @@ -320,37 +327,106 @@ struct task_struct *__switch_to(struct task_struct *prev, return last; } +static int instructions_to_print = 16; + +#ifdef CONFIG_PPC64 +#define BAD_PC(pc) ((REGION_ID(pc) != KERNEL_REGION_ID) && \ + (REGION_ID(pc) != VMALLOC_REGION_ID)) +#else +#define BAD_PC(pc) ((pc) < KERNELBASE) +#endif + +static void show_instructions(struct pt_regs *regs) +{ + int i; + unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 * + sizeof(int)); + + printk("Instruction dump:"); + + for (i = 0; i < instructions_to_print; i++) { + int instr; + + if (!(i % 8)) + printk("\n"); + + if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) { + printk("XXXXXXXX "); + } else { + if (regs->nip == pc) + printk("<%08x> ", instr); + else + printk("%08x ", instr); + } + + pc += sizeof(int); + } + + printk("\n"); +} + +static struct regbit { + unsigned long bit; + const char *name; +} msr_bits[] = { + {MSR_EE, "EE"}, + {MSR_PR, "PR"}, + {MSR_FP, "FP"}, + {MSR_ME, "ME"}, + {MSR_IR, "IR"}, + {MSR_DR, "DR"}, + {0, NULL} +}; + +static void printbits(unsigned long val, struct regbit *bits) +{ + const char *sep = ""; + + printk("<"); + for (; bits->bit; ++bits) + if (val & bits->bit) { + printk("%s%s", sep, bits->name); + sep = ","; + } + printk(">"); +} + +#ifdef CONFIG_PPC64 +#define REG "%016lX" +#define REGS_PER_LINE 4 +#define LAST_VOLATILE 13 +#else +#define REG "%08lX" +#define REGS_PER_LINE 8 +#define LAST_VOLATILE 12 +#endif + void show_regs(struct pt_regs * regs) { int i, trap; - printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n", - regs->nip, regs->link, regs->gpr[1], regs, regs->trap, - print_tainted()); - printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", - regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, - regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, - regs->msr&MSR_IR ? 1 : 0, - regs->msr&MSR_DR ? 1 : 0); + printk("NIP: "REG" LR: "REG" CTR: "REG"\n", + regs->nip, regs->link, regs->ctr); + printk("REGS: %p TRAP: %04lx %s (%s)\n", + regs, regs->trap, print_tainted(), system_utsname.release); + printk("MSR: "REG" ", regs->msr); + printbits(regs->msr, msr_bits); + printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); trap = TRAP(regs); if (trap == 0x300 || trap == 0x600) - printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); - printk("TASK = %p[%d] '%s' THREAD: %p\n", + printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); + printk("TASK = %p[%d] '%s' THREAD: %p", current, current->pid, current->comm, current->thread_info); - printk("Last syscall: %ld ", current->thread.last_syscall); #ifdef CONFIG_SMP printk(" CPU: %d", smp_processor_id()); #endif /* CONFIG_SMP */ for (i = 0; i < 32; i++) { - long r; - if ((i % 8) == 0) + if ((i % REGS_PER_LINE) == 0) printk("\n" KERN_INFO "GPR%02d: ", i); - if (__get_user(r, ®s->gpr[i])) - break; - printk("%08lX ", r); - if (i == 12 && !FULL_REGS(regs)) + printk(REG " ", regs->gpr[i]); + if (i == LAST_VOLATILE && !FULL_REGS(regs)) break; } printk("\n"); @@ -359,16 +435,20 @@ void show_regs(struct pt_regs * regs) * Lookup NIP late so we have the best change of getting the * above info out without failing */ - printk("NIP [%08lx] ", regs->nip); + printk("NIP ["REG"] ", regs->nip); print_symbol("%s\n", regs->nip); - printk("LR [%08lx] ", regs->link); + printk("LR ["REG"] ", regs->link); print_symbol("%s\n", regs->link); #endif show_stack(current, (unsigned long *) regs->gpr[1]); + if (!user_mode(regs)) + show_instructions(regs); } void exit_thread(void) { + kprobe_flush_task(current); + #ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; @@ -385,6 +465,14 @@ void exit_thread(void) void flush_thread(void) { +#ifdef CONFIG_PPC64 + struct thread_info *t = current_thread_info(); + + if (t->flags & _TIF_ABI_PENDING) + t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); +#endif + kprobe_flush_task(current); + #ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; @@ -425,15 +513,13 @@ void prepare_to_copy(struct task_struct *tsk) /* * Copy a thread.. */ -int -copy_thread(int nr, unsigned long clone_flags, unsigned long usp, - unsigned long unused, - struct task_struct *p, struct pt_regs *regs) +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct *p, + struct pt_regs *regs) { struct pt_regs *childregs, *kregs; extern void ret_from_fork(void); unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE; - unsigned long childframe; CHECK_FULL_REGS(regs); /* Copy registers */ @@ -443,17 +529,26 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, if ((childregs->msr & MSR_PR) == 0) { /* for kernel thread, set `current' and stackptr in new task */ childregs->gpr[1] = sp + sizeof(struct pt_regs); +#ifdef CONFIG_PPC32 childregs->gpr[2] = (unsigned long) p; +#else + clear_ti_thread_flag(p->thread_info, TIF_32BIT); +#endif p->thread.regs = NULL; /* no user register state */ } else { childregs->gpr[1] = usp; p->thread.regs = childregs; - if (clone_flags & CLONE_SETTLS) - childregs->gpr[2] = childregs->gpr[6]; + if (clone_flags & CLONE_SETTLS) { +#ifdef CONFIG_PPC64 + if (!test_thread_flag(TIF_32BIT)) + childregs->gpr[13] = childregs->gpr[6]; + else +#endif + childregs->gpr[2] = childregs->gpr[6]; + } } childregs->gpr[3] = 0; /* Result from fork() */ sp -= STACK_FRAME_OVERHEAD; - childframe = sp; /* * The way this works is that at some point in the future @@ -467,9 +562,30 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, kregs = (struct pt_regs *) sp; sp -= STACK_FRAME_OVERHEAD; p->thread.ksp = sp; - kregs->nip = (unsigned long)ret_from_fork; +#ifdef CONFIG_PPC64 + if (cpu_has_feature(CPU_FTR_SLB)) { + unsigned long sp_vsid = get_kernel_vsid(sp); + + sp_vsid <<= SLB_VSID_SHIFT; + sp_vsid |= SLB_VSID_KERNEL; + if (cpu_has_feature(CPU_FTR_16M_PAGE)) + sp_vsid |= SLB_VSID_L; + + p->thread.ksp_vsid = sp_vsid; + } + + /* + * The PPC64 ABI makes use of a TOC to contain function + * pointers. The function (ret_from_except) is actually a pointer + * to the TOC entry. The first entry is a pointer to the actual + * function. + */ + kregs->nip = *((unsigned long *)ret_from_fork); +#else + kregs->nip = (unsigned long)ret_from_fork; p->thread.last_syscall = -1; +#endif return 0; } @@ -477,18 +593,61 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, /* * Set up a thread for executing a new program */ -void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) +void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) { set_fs(USER_DS); + + /* + * If we exec out of a kernel thread then thread.regs will not be + * set. Do it now. + */ + if (!current->thread.regs) { + unsigned long childregs = (unsigned long)current->thread_info + + THREAD_SIZE; + childregs -= sizeof(struct pt_regs); + current->thread.regs = (struct pt_regs *)childregs; + } + memset(regs->gpr, 0, sizeof(regs->gpr)); regs->ctr = 0; regs->link = 0; regs->xer = 0; regs->ccr = 0; - regs->mq = 0; - regs->nip = nip; regs->gpr[1] = sp; + +#ifdef CONFIG_PPC32 + regs->mq = 0; + regs->nip = start; regs->msr = MSR_USER; +#else + if (test_thread_flag(TIF_32BIT)) { + unsigned long entry, toc, load_addr = regs->gpr[2]; + + /* start is a relocated pointer to the function descriptor for + * the elf _start routine. The first entry in the function + * descriptor is the entry address of _start and the second + * entry is the TOC value we need to use. + */ + __get_user(entry, (unsigned long __user *)start); + __get_user(toc, (unsigned long __user *)start+1); + + /* Check whether the e_entry function descriptor entries + * need to be relocated before we can use them. + */ + if (load_addr != 0) { + entry += load_addr; + toc += load_addr; + } + regs->nip = entry; + regs->gpr[2] = toc; + regs->msr = MSR_USER64; + } else { + regs->nip = start; + regs->gpr[2] = 0; + regs->msr = MSR_USER32; + } +#endif + #ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; @@ -506,6 +665,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) #ifdef CONFIG_ALTIVEC memset(current->thread.vr, 0, sizeof(current->thread.vr)); memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); + current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ current->thread.vrsave = 0; current->thread.used_vr = 0; #endif /* CONFIG_ALTIVEC */ @@ -532,22 +692,23 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) #ifdef CONFIG_SPE tsk->thread.fpexc_mode = val & (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); + return 0; #else return -EINVAL; #endif - } else { - /* on a CONFIG_SPE this does not hurt us. The bits that - * __pack_fe01 use do not overlap with bits used for - * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits - * on CONFIG_SPE implementations are reserved so writing to - * them does not change anything */ - if (val > PR_FP_EXC_PRECISE) - return -EINVAL; - tsk->thread.fpexc_mode = __pack_fe01(val); - if (regs != NULL && (regs->msr & MSR_FP) != 0) - regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) - | tsk->thread.fpexc_mode; } + + /* on a CONFIG_SPE this does not hurt us. The bits that + * __pack_fe01 use do not overlap with bits used for + * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits + * on CONFIG_SPE implementations are reserved so writing to + * them does not change anything */ + if (val > PR_FP_EXC_PRECISE) + return -EINVAL; + tsk->thread.fpexc_mode = __pack_fe01(val); + if (regs != NULL && (regs->msr & MSR_FP) != 0) + regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) + | tsk->thread.fpexc_mode; return 0; } @@ -566,6 +727,8 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) return put_user(val, (unsigned int __user *) adr); } +#define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff)) + int sys_clone(unsigned long clone_flags, unsigned long usp, int __user *parent_tidp, void __user *child_threadptr, int __user *child_tidp, int p6, @@ -574,6 +737,12 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, CHECK_FULL_REGS(regs); if (usp == 0) usp = regs->gpr[1]; /* stack pointer for child */ +#ifdef CONFIG_PPC64 + if (test_thread_flag(TIF_32BIT)) { + parent_tidp = TRUNC_PTR(parent_tidp); + child_tidp = TRUNC_PTR(child_tidp); + } +#endif return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp); } @@ -599,7 +768,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, struct pt_regs *regs) { int error; - char * filename; + char *filename; filename = getname((char __user *) a0); error = PTR_ERR(filename); @@ -644,20 +813,53 @@ static int validate_sp(unsigned long sp, struct task_struct *p, return 0; } -void dump_stack(void) -{ - show_stack(current, NULL); -} +#ifdef CONFIG_PPC64 +#define MIN_STACK_FRAME 112 /* same as STACK_FRAME_OVERHEAD, in fact */ +#define FRAME_LR_SAVE 2 +#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288) +#define REGS_MARKER 0x7265677368657265ul +#define FRAME_MARKER 12 +#else +#define MIN_STACK_FRAME 16 +#define FRAME_LR_SAVE 1 +#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD) +#define REGS_MARKER 0x72656773ul +#define FRAME_MARKER 2 +#endif -EXPORT_SYMBOL(dump_stack); +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ip, sp; + int count = 0; + + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + sp = p->thread.ksp; + if (!validate_sp(sp, p, MIN_STACK_FRAME)) + return 0; + + do { + sp = *(unsigned long *)sp; + if (!validate_sp(sp, p, MIN_STACK_FRAME)) + return 0; + if (count > 0) { + ip = ((unsigned long *)sp)[FRAME_LR_SAVE]; + if (!in_sched_functions(ip)) + return ip; + } + } while (count++ < 16); + return 0; +} +EXPORT_SYMBOL(get_wchan); + +static int kstack_depth_to_print = 64; void show_stack(struct task_struct *tsk, unsigned long *stack) { - unsigned long sp, stack_top, prev_sp, ret; + unsigned long sp, ip, lr, newsp; int count = 0; - unsigned long next_exc = 0; - struct pt_regs *regs; - extern char ret_from_except, ret_from_except_full, ret_from_syscall; + int firstframe = 1; sp = (unsigned long) stack; if (tsk == NULL) @@ -669,65 +871,45 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) sp = tsk->thread.ksp; } - prev_sp = (unsigned long) (tsk->thread_info + 1); - stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE; - while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) { - if (count == 0) { - printk("Call trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif - } else { - if (next_exc) { - ret = next_exc; - next_exc = 0; - } else - ret = *(unsigned long *)(sp + 4); - printk(" [%08lx] ", ret); -#ifdef CONFIG_KALLSYMS - print_symbol("%s", ret); - printk("\n"); -#endif - if (ret == (unsigned long) &ret_from_except - || ret == (unsigned long) &ret_from_except_full - || ret == (unsigned long) &ret_from_syscall) { - /* sp + 16 points to an exception frame */ - regs = (struct pt_regs *) (sp + 16); - if (sp + 16 + sizeof(*regs) <= stack_top) - next_exc = regs->nip; - } - } - ++count; - sp = *(unsigned long *)sp; - } -#ifndef CONFIG_KALLSYMS - if (count > 0) - printk("\n"); -#endif -} - -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long ip, sp; - int count = 0; - - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - sp = p->thread.ksp; - if (!validate_sp(sp, p, 16)) - return 0; - + lr = 0; + printk("Call Trace:\n"); do { - sp = *(unsigned long *)sp; - if (!validate_sp(sp, p, 16)) - return 0; - if (count > 0) { - ip = *(unsigned long *)(sp + 4); - if (!in_sched_functions(ip)) - return ip; + if (!validate_sp(sp, tsk, MIN_STACK_FRAME)) + return; + + stack = (unsigned long *) sp; + newsp = stack[0]; + ip = stack[FRAME_LR_SAVE]; + if (!firstframe || ip != lr) { + printk("["REG"] ["REG"] ", sp, ip); + print_symbol("%s", ip); + if (firstframe) + printk(" (unreliable)"); + printk("\n"); } - } while (count++ < 16); - return 0; + firstframe = 0; + + /* + * See if this is an exception frame. + * We look for the "regshere" marker in the current frame. + */ + if (validate_sp(sp, tsk, INT_FRAME_SIZE) + && stack[FRAME_MARKER] == REGS_MARKER) { + struct pt_regs *regs = (struct pt_regs *) + (sp + STACK_FRAME_OVERHEAD); + printk("--- Exception: %lx", regs->trap); + print_symbol(" at %s\n", regs->nip); + lr = regs->link; + print_symbol(" LR = %s\n", lr); + firstframe = 1; + } + + sp = newsp; + } while (count++ < kstack_depth_to_print); } -EXPORT_SYMBOL(get_wchan); + +void dump_stack(void) +{ + show_stack(current, NULL); +} +EXPORT_SYMBOL(dump_stack); diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index f0a6779fbe52..d22b10021b5d 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -214,10 +214,8 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); but it's not easy, and we've already done it here. */ # define ELF_HWCAP (cur_cpu_spec->cpu_user_features) #ifdef __powerpc64__ -# define ELF_PLAT_INIT(_r, load_addr) do { \ - memset(_r->gpr, 0, sizeof(_r->gpr)); \ - _r->ctr = _r->link = _r->xer = _r->ccr = 0; \ - _r->gpr[2] = load_addr; \ +# define ELF_PLAT_INIT(_r, load_addr) do { \ + _r->gpr[2] = load_addr; \ } while (0) #endif /* __powerpc64__ */ From 9994a33865f4d55c44c9731c01e1f891543278de Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:36:14 +1000 Subject: [PATCH 0239/1940] powerpc: Introduce entry_{32,64}.S, misc_{32,64}.S, systbl.S The system call table has been consolidated into systbl.S. We have separate 32-bit and 64-bit versions of entry.S and misc.S since the code is mostly sufficiently different to be not worth merging. There are some common bits that will be extracted in future. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 3 +- arch/powerpc/kernel/Makefile | 6 +- arch/powerpc/kernel/entry_32.S | 1002 ++++++++++++++++++++++++++++++ arch/powerpc/kernel/entry_64.S | 842 ++++++++++++++++++++++++++ arch/powerpc/kernel/misc_32.S | 1039 ++++++++++++++++++++++++++++++++ arch/powerpc/kernel/misc_64.S | 898 +++++++++++++++++++++++++++ arch/powerpc/kernel/systbl.S | 323 ++++++++++ 7 files changed, 4109 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/kernel/entry_32.S create mode 100644 arch/powerpc/kernel/entry_64.S create mode 100644 arch/powerpc/kernel/misc_32.S create mode 100644 arch/powerpc/kernel/misc_64.S create mode 100644 arch/powerpc/kernel/systbl.S diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index a4c605f469d4..27649cfc2a5d 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -119,10 +119,9 @@ head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o -ifeq ($(CONFIG_PPC32),y) head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o +head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o -endif core-y += arch/powerpc/kernel/ \ arch/$(OLDARCH)/kernel/ \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 344cab678c6a..0625470a6235 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -17,12 +17,14 @@ extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o +extra-$(CONFIG_PPC64) += entry_64.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y := traps.o prom.o semaphore.o -obj-$(CONFIG_PPC32) += setup_32.o process.o +obj-y += traps.o prom.o semaphore.o +obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += idle_power4.o +obj-$(CONFIG_PPC64) += misc_64.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o obj-$(CONFIG_MODULES) += ppc_ksyms.o diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S new file mode 100644 index 000000000000..094eea6fbd69 --- /dev/null +++ b/arch/powerpc/kernel/entry_32.S @@ -0,0 +1,1002 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * + * This file contains the system call entry code, context switch + * code, and exception/interrupt return code for PowerPC. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef SHOW_SYSCALLS +#undef SHOW_SYSCALLS_TASK + +/* + * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE. + */ +#if MSR_KERNEL >= 0x10000 +#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l +#else +#define LOAD_MSR_KERNEL(r, x) li r,(x) +#endif + +#ifdef CONFIG_BOOKE +#include "head_booke.h" +#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \ + mtspr exc_level##_SPRG,r8; \ + BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \ + lwz r0,GPR10-INT_FRAME_SIZE(r8); \ + stw r0,GPR10(r11); \ + lwz r0,GPR11-INT_FRAME_SIZE(r8); \ + stw r0,GPR11(r11); \ + mfspr r8,exc_level##_SPRG + + .globl mcheck_transfer_to_handler +mcheck_transfer_to_handler: + TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) + b transfer_to_handler_full + + .globl debug_transfer_to_handler +debug_transfer_to_handler: + TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG) + b transfer_to_handler_full + + .globl crit_transfer_to_handler +crit_transfer_to_handler: + TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) + /* fall through */ +#endif + +#ifdef CONFIG_40x + .globl crit_transfer_to_handler +crit_transfer_to_handler: + lwz r0,crit_r10@l(0) + stw r0,GPR10(r11) + lwz r0,crit_r11@l(0) + stw r0,GPR11(r11) + /* fall through */ +#endif + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception, turning + * on address translation. + * Note that we rely on the caller having set cr0.eq iff the exception + * occurred in kernel mode (i.e. MSR:PR = 0). + */ + .globl transfer_to_handler_full +transfer_to_handler_full: + SAVE_NVGPRS(r11) + /* fall through */ + + .globl transfer_to_handler +transfer_to_handler: + stw r2,GPR2(r11) + stw r12,_NIP(r11) + stw r9,_MSR(r11) + andi. r2,r9,MSR_PR + mfctr r12 + mfspr r2,SPRN_XER + stw r12,_CTR(r11) + stw r2,_XER(r11) + mfspr r12,SPRN_SPRG3 + addi r2,r12,-THREAD + tovirt(r2,r2) /* set r2 to current */ + beq 2f /* if from user, fix up THREAD.regs */ + addi r11,r1,STACK_FRAME_OVERHEAD + stw r11,PT_REGS(r12) +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) + /* Check to see if the dbcr0 register is set up to debug. Use the + single-step bit to do this. */ + lwz r12,THREAD_DBCR0(r12) + andis. r12,r12,DBCR0_IC@h + beq+ 3f + /* From user and task is ptraced - load up global dbcr0 */ + li r12,-1 /* clear all pending debug events */ + mtspr SPRN_DBSR,r12 + lis r11,global_dbcr0@ha + tophys(r11,r11) + addi r11,r11,global_dbcr0@l + lwz r12,0(r11) + mtspr SPRN_DBCR0,r12 + lwz r12,4(r11) + addi r12,r12,-1 + stw r12,4(r11) +#endif + b 3f +2: /* if from kernel, check interrupted DOZE/NAP mode and + * check for stack overflow + */ +#ifdef CONFIG_6xx + mfspr r11,SPRN_HID0 + mtcr r11 +BEGIN_FTR_SECTION + bt- 8,power_save_6xx_restore /* Check DOZE */ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) +BEGIN_FTR_SECTION + bt- 9,power_save_6xx_restore /* Check NAP */ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) +#endif /* CONFIG_6xx */ + .globl transfer_to_handler_cont +transfer_to_handler_cont: + lwz r11,THREAD_INFO-THREAD(r12) + cmplw r1,r11 /* if r1 <= current->thread_info */ + ble- stack_ovf /* then the kernel stack overflowed */ +3: + mflr r9 + lwz r11,0(r9) /* virtual address of handler */ + lwz r9,4(r9) /* where to go when done */ + FIX_SRR1(r10,r12) + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r10 + mtlr r9 + SYNC + RFI /* jump to handler, enable MMU */ + +/* + * On kernel stack overflow, load up an initial stack pointer + * and call StackOverflow(regs), which should not return. + */ +stack_ovf: + /* sometimes we use a statically-allocated stack, which is OK. */ + lis r11,_end@h + ori r11,r11,_end@l + cmplw r1,r11 + ble 3b /* r1 <= &_end is OK */ + SAVE_NVGPRS(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + lis r1,init_thread_union@ha + addi r1,r1,init_thread_union@l + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + lis r9,StackOverflow@ha + addi r9,r9,StackOverflow@l + LOAD_MSR_KERNEL(r10,MSR_KERNEL) + FIX_SRR1(r10,r12) + mtspr SPRN_SRR0,r9 + mtspr SPRN_SRR1,r10 + SYNC + RFI + +/* + * Handle a system call. + */ + .stabs "arch/powerpc/kernel/",N_SO,0,0,0f + .stabs "entry_32.S",N_SO,0,0,0f +0: + +_GLOBAL(DoSyscall) + stw r0,THREAD+LAST_SYSCALL(r2) + stw r3,ORIG_GPR3(r1) + li r12,0 + stw r12,RESULT(r1) + lwz r11,_CCR(r1) /* Clear SO bit in CR */ + rlwinm r11,r11,0,4,2 + stw r11,_CCR(r1) +#ifdef SHOW_SYSCALLS + bl do_show_syscall +#endif /* SHOW_SYSCALLS */ + rlwinm r10,r1,0,0,18 /* current_thread_info() */ + lwz r11,TI_LOCAL_FLAGS(r10) + rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR + stw r11,TI_LOCAL_FLAGS(r10) + lwz r11,TI_FLAGS(r10) + andi. r11,r11,_TIF_SYSCALL_T_OR_A + bne- syscall_dotrace +syscall_dotrace_cont: + cmplwi 0,r0,NR_syscalls + lis r10,sys_call_table@h + ori r10,r10,sys_call_table@l + slwi r0,r0,2 + bge- 66f + lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ + mtlr r10 + addi r9,r1,STACK_FRAME_OVERHEAD + PPC440EP_ERR42 + blrl /* Call handler */ + .globl ret_from_syscall +ret_from_syscall: +#ifdef SHOW_SYSCALLS + bl do_show_syscall_exit +#endif + mr r6,r3 + li r11,-_LAST_ERRNO + cmplw 0,r3,r11 + rlwinm r12,r1,0,0,18 /* current_thread_info() */ + blt+ 30f + lwz r11,TI_LOCAL_FLAGS(r12) + andi. r11,r11,_TIFL_FORCE_NOERROR + bne 30f + neg r3,r3 + lwz r10,_CCR(r1) /* Set SO bit in CR */ + oris r10,r10,0x1000 + stw r10,_CCR(r1) + + /* disable interrupts so current_thread_info()->flags can't change */ +30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ + SYNC + MTMSRD(r10) + lwz r9,TI_FLAGS(r12) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) + bne- syscall_exit_work +syscall_exit_cont: +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* If the process has its own DBCR0 value, load it up. The single + step bit tells us that dbcr0 should be loaded. */ + lwz r0,THREAD+THREAD_DBCR0(r2) + andis. r10,r0,DBCR0_IC@h + bnel- load_dbcr0 +#endif + stwcx. r0,0,r1 /* to clear the reservation */ + lwz r4,_LINK(r1) + lwz r5,_CCR(r1) + mtlr r4 + mtcr r5 + lwz r7,_NIP(r1) + lwz r8,_MSR(r1) + FIX_SRR1(r8, r0) + lwz r2,GPR2(r1) + lwz r1,GPR1(r1) + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r8 + SYNC + RFI + +66: li r3,-ENOSYS + b ret_from_syscall + + .globl ret_from_fork +ret_from_fork: + REST_NVGPRS(r1) + bl schedule_tail + li r3,0 + b ret_from_syscall + +/* Traced system call support */ +syscall_dotrace: + SAVE_NVGPRS(r1) + li r0,0xc00 + stw r0,TRAP(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_syscall_trace_enter + lwz r0,GPR0(r1) /* Restore original registers */ + lwz r3,GPR3(r1) + lwz r4,GPR4(r1) + lwz r5,GPR5(r1) + lwz r6,GPR6(r1) + lwz r7,GPR7(r1) + lwz r8,GPR8(r1) + REST_NVGPRS(r1) + b syscall_dotrace_cont + +syscall_exit_work: + stw r6,RESULT(r1) /* Save result */ + stw r3,GPR3(r1) /* Update return value */ + andi. r0,r9,_TIF_SYSCALL_T_OR_A + beq 5f + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* re-enable interrupts */ + lwz r4,TRAP(r1) + andi. r4,r4,1 + beq 4f + SAVE_NVGPRS(r1) + li r4,0xc00 + stw r4,TRAP(r1) +4: + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_syscall_trace_leave + REST_NVGPRS(r1) +2: + lwz r3,GPR3(r1) + LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ + SYNC + MTMSRD(r10) /* disable interrupts again */ + rlwinm r12,r1,0,0,18 /* current_thread_info() */ + lwz r9,TI_FLAGS(r12) +5: + andi. r0,r9,_TIF_NEED_RESCHED + bne 1f + lwz r5,_MSR(r1) + andi. r5,r5,MSR_PR + beq syscall_exit_cont + andi. r0,r9,_TIF_SIGPENDING + beq syscall_exit_cont + b do_user_signal +1: + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* re-enable interrupts */ + bl schedule + b 2b + +#ifdef SHOW_SYSCALLS +do_show_syscall: +#ifdef SHOW_SYSCALLS_TASK + lis r11,show_syscalls_task@ha + lwz r11,show_syscalls_task@l(r11) + cmp 0,r2,r11 + bnelr +#endif + stw r31,GPR31(r1) + mflr r31 + lis r3,7f@ha + addi r3,r3,7f@l + lwz r4,GPR0(r1) + lwz r5,GPR3(r1) + lwz r6,GPR4(r1) + lwz r7,GPR5(r1) + lwz r8,GPR6(r1) + lwz r9,GPR7(r1) + bl printk + lis r3,77f@ha + addi r3,r3,77f@l + lwz r4,GPR8(r1) + mr r5,r2 + bl printk + lwz r0,GPR0(r1) + lwz r3,GPR3(r1) + lwz r4,GPR4(r1) + lwz r5,GPR5(r1) + lwz r6,GPR6(r1) + lwz r7,GPR7(r1) + lwz r8,GPR8(r1) + mtlr r31 + lwz r31,GPR31(r1) + blr + +do_show_syscall_exit: +#ifdef SHOW_SYSCALLS_TASK + lis r11,show_syscalls_task@ha + lwz r11,show_syscalls_task@l(r11) + cmp 0,r2,r11 + bnelr +#endif + stw r31,GPR31(r1) + mflr r31 + stw r3,RESULT(r1) /* Save result */ + mr r4,r3 + lis r3,79f@ha + addi r3,r3,79f@l + bl printk + lwz r3,RESULT(r1) + mtlr r31 + lwz r31,GPR31(r1) + blr + +7: .string "syscall %d(%x, %x, %x, %x, %x, " +77: .string "%x), current=%p\n" +79: .string " -> %x\n" + .align 2,0 + +#ifdef SHOW_SYSCALLS_TASK + .data + .globl show_syscalls_task +show_syscalls_task: + .long -1 + .text +#endif +#endif /* SHOW_SYSCALLS */ + +/* + * The sigsuspend and rt_sigsuspend system calls can call do_signal + * and thus put the process into the stopped state where we might + * want to examine its user state with ptrace. Therefore we need + * to save all the nonvolatile registers (r13 - r31) before calling + * the C code. + */ + .globl ppc_sigsuspend +ppc_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_sigsuspend + + .globl ppc_rt_sigsuspend +ppc_rt_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 + stw r0,TRAP(r1) + b sys_rt_sigsuspend + + .globl ppc_fork +ppc_fork: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_fork + + .globl ppc_vfork +ppc_vfork: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_vfork + + .globl ppc_clone +ppc_clone: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_clone + + .globl ppc_swapcontext +ppc_swapcontext: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_swapcontext + +/* + * Top-level page fault handling. + * This is in assembler because if do_page_fault tells us that + * it is a bad kernel page fault, we want to save the non-volatile + * registers before calling bad_page_fault. + */ + .globl handle_page_fault +handle_page_fault: + stw r4,_DAR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_page_fault + cmpwi r3,0 + beq+ ret_from_except + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + clrrwi r0,r0,1 + stw r0,TRAP(r1) + mr r5,r3 + addi r3,r1,STACK_FRAME_OVERHEAD + lwz r4,_DAR(r1) + bl bad_page_fault + b ret_from_except_full + +/* + * This routine switches between two different tasks. The process + * state of one is saved on its kernel stack. Then the state + * of the other is restored from its kernel stack. The memory + * management hardware is updated to the second process's state. + * Finally, we can return to the second process. + * On entry, r3 points to the THREAD for the current task, r4 + * points to the THREAD for the new task. + * + * This routine is always called with interrupts disabled. + * + * Note: there are two ways to get to the "going out" portion + * of this code; either by coming in via the entry (_switch) + * or via "fork" which must set up an environment equivalent + * to the "_switch" path. If you change this , you'll have to + * change the fork code also. + * + * The code which creates the new task context is in 'copy_thread' + * in arch/ppc/kernel/process.c + */ +_GLOBAL(_switch) + stwu r1,-INT_FRAME_SIZE(r1) + mflr r0 + stw r0,INT_FRAME_SIZE+4(r1) + /* r3-r12 are caller saved -- Cort */ + SAVE_NVGPRS(r1) + stw r0,_NIP(r1) /* Return to switch caller */ + mfmsr r11 + li r0,MSR_FP /* Disable floating-point */ +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + oris r0,r0,MSR_VEC@h /* Disable altivec */ + mfspr r12,SPRN_VRSAVE /* save vrsave register value */ + stw r12,THREAD+THREAD_VRSAVE(r2) +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + oris r0,r0,MSR_SPE@h /* Disable SPE */ + mfspr r12,SPRN_SPEFSCR /* save spefscr register value */ + stw r12,THREAD+THREAD_SPEFSCR(r2) +#endif /* CONFIG_SPE */ + and. r0,r0,r11 /* FP or altivec or SPE enabled? */ + beq+ 1f + andc r11,r11,r0 + MTMSRD(r11) + isync +1: stw r11,_MSR(r1) + mfcr r10 + stw r10,_CCR(r1) + stw r1,KSP(r3) /* Set old stack pointer */ + +#ifdef CONFIG_SMP + /* We need a sync somewhere here to make sure that if the + * previous task gets rescheduled on another CPU, it sees all + * stores it has performed on this one. + */ + sync +#endif /* CONFIG_SMP */ + + tophys(r0,r4) + CLR_TOP32(r0) + mtspr SPRN_SPRG3,r0 /* Update current THREAD phys addr */ + lwz r1,KSP(r4) /* Load new stack pointer */ + + /* save the old current 'last' for return value */ + mr r3,r2 + addi r2,r4,-THREAD /* Update current */ + +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + lwz r0,THREAD+THREAD_VRSAVE(r2) + mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + lwz r0,THREAD+THREAD_SPEFSCR(r2) + mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */ +#endif /* CONFIG_SPE */ + + lwz r0,_CCR(r1) + mtcrf 0xFF,r0 + /* r3-r12 are destroyed -- Cort */ + REST_NVGPRS(r1) + + lwz r4,_NIP(r1) /* Return to _switch caller in new task */ + mtlr r4 + addi r1,r1,INT_FRAME_SIZE + blr + + .globl fast_exception_return +fast_exception_return: +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + andi. r10,r9,MSR_RI /* check for recoverable interrupt */ + beq 1f /* if not, we've got problems */ +#endif + +2: REST_4GPRS(3, r11) + lwz r10,_CCR(r11) + REST_GPR(1, r11) + mtcr r10 + lwz r10,_LINK(r11) + mtlr r10 + REST_GPR(10, r11) + mtspr SPRN_SRR1,r9 + mtspr SPRN_SRR0,r12 + REST_GPR(9, r11) + REST_GPR(12, r11) + lwz r11,GPR11(r11) + SYNC + RFI + +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) +/* check if the exception happened in a restartable section */ +1: lis r3,exc_exit_restart_end@ha + addi r3,r3,exc_exit_restart_end@l + cmplw r12,r3 + bge 3f + lis r4,exc_exit_restart@ha + addi r4,r4,exc_exit_restart@l + cmplw r12,r4 + blt 3f + lis r3,fee_restarts@ha + tophys(r3,r3) + lwz r5,fee_restarts@l(r3) + addi r5,r5,1 + stw r5,fee_restarts@l(r3) + mr r12,r4 /* restart at exc_exit_restart */ + b 2b + + .comm fee_restarts,4 + +/* aargh, a nonrecoverable interrupt, panic */ +/* aargh, we don't know which trap this is */ +/* but the 601 doesn't implement the RI bit, so assume it's OK */ +3: +BEGIN_FTR_SECTION + b 2b +END_FTR_SECTION_IFSET(CPU_FTR_601) + li r10,-1 + stw r10,TRAP(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + lis r10,MSR_KERNEL@h + ori r10,r10,MSR_KERNEL@l + bl transfer_to_handler_full + .long nonrecoverable_exception + .long ret_from_except +#endif + + .globl sigreturn_exit +sigreturn_exit: + subi r1,r3,STACK_FRAME_OVERHEAD + rlwinm r12,r1,0,0,18 /* current_thread_info() */ + lwz r9,TI_FLAGS(r12) + andi. r0,r9,_TIF_SYSCALL_T_OR_A + bnel- do_syscall_trace_leave + /* fall through */ + + .globl ret_from_except_full +ret_from_except_full: + REST_NVGPRS(r1) + /* fall through */ + + .globl ret_from_except +ret_from_except: + /* Hard-disable interrupts so that current_thread_info()->flags + * can't change between when we test it and when we return + * from the interrupt. */ + LOAD_MSR_KERNEL(r10,MSR_KERNEL) + SYNC /* Some chip revs have problems here... */ + MTMSRD(r10) /* disable interrupts */ + + lwz r3,_MSR(r1) /* Returning to user mode? */ + andi. r0,r3,MSR_PR + beq resume_kernel + +user_exc_return: /* r10 contains MSR_KERNEL here */ + /* Check current_thread_info()->flags */ + rlwinm r9,r1,0,0,18 + lwz r9,TI_FLAGS(r9) + andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) + bne do_work + +restore_user: +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* Check whether this process has its own DBCR0 value. The single + step bit tells us that dbcr0 should be loaded. */ + lwz r0,THREAD+THREAD_DBCR0(r2) + andis. r10,r0,DBCR0_IC@h + bnel- load_dbcr0 +#endif + +#ifdef CONFIG_PREEMPT + b restore + +/* N.B. the only way to get here is from the beq following ret_from_except. */ +resume_kernel: + /* check current_thread_info->preempt_count */ + rlwinm r9,r1,0,0,18 + lwz r0,TI_PREEMPT(r9) + cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ + bne restore + lwz r0,TI_FLAGS(r9) + andi. r0,r0,_TIF_NEED_RESCHED + beq+ restore + andi. r0,r3,MSR_EE /* interrupts off? */ + beq restore /* don't schedule if so */ +1: bl preempt_schedule_irq + rlwinm r9,r1,0,0,18 + lwz r3,TI_FLAGS(r9) + andi. r0,r3,_TIF_NEED_RESCHED + bne- 1b +#else +resume_kernel: +#endif /* CONFIG_PREEMPT */ + + /* interrupts are hard-disabled at this point */ +restore: + lwz r0,GPR0(r1) + lwz r2,GPR2(r1) + REST_4GPRS(3, r1) + REST_2GPRS(7, r1) + + lwz r10,_XER(r1) + lwz r11,_CTR(r1) + mtspr SPRN_XER,r10 + mtctr r11 + + PPC405_ERR77(0,r1) + stwcx. r0,0,r1 /* to clear the reservation */ + +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + lwz r9,_MSR(r1) + andi. r10,r9,MSR_RI /* check if this exception occurred */ + beql nonrecoverable /* at a bad place (MSR:RI = 0) */ + + lwz r10,_CCR(r1) + lwz r11,_LINK(r1) + mtcrf 0xFF,r10 + mtlr r11 + + /* + * Once we put values in SRR0 and SRR1, we are in a state + * where exceptions are not recoverable, since taking an + * exception will trash SRR0 and SRR1. Therefore we clear the + * MSR:RI bit to indicate this. If we do take an exception, + * we can't return to the point of the exception but we + * can restart the exception exit path at the label + * exc_exit_restart below. -- paulus + */ + LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI) + SYNC + MTMSRD(r10) /* clear the RI bit */ + .globl exc_exit_restart +exc_exit_restart: + lwz r9,_MSR(r1) + lwz r12,_NIP(r1) + FIX_SRR1(r9,r10) + mtspr SPRN_SRR0,r12 + mtspr SPRN_SRR1,r9 + REST_4GPRS(9, r1) + lwz r1,GPR1(r1) + .globl exc_exit_restart_end +exc_exit_restart_end: + SYNC + RFI + +#else /* !(CONFIG_4xx || CONFIG_BOOKE) */ + /* + * This is a bit different on 4xx/Book-E because it doesn't have + * the RI bit in the MSR. + * The TLB miss handler checks if we have interrupted + * the exception exit path and restarts it if so + * (well maybe one day it will... :). + */ + lwz r11,_LINK(r1) + mtlr r11 + lwz r10,_CCR(r1) + mtcrf 0xff,r10 + REST_2GPRS(9, r1) + .globl exc_exit_restart +exc_exit_restart: + lwz r11,_NIP(r1) + lwz r12,_MSR(r1) +exc_exit_start: + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 + REST_2GPRS(11, r1) + lwz r1,GPR1(r1) + .globl exc_exit_restart_end +exc_exit_restart_end: + PPC405_ERR77_SYNC + rfi + b . /* prevent prefetch past rfi */ + +/* + * Returning from a critical interrupt in user mode doesn't need + * to be any different from a normal exception. For a critical + * interrupt in the kernel, we just return (without checking for + * preemption) since the interrupt may have happened at some crucial + * place (e.g. inside the TLB miss handler), and because we will be + * running with r1 pointing into critical_stack, not the current + * process's kernel stack (and therefore current_thread_info() will + * give the wrong answer). + * We have to restore various SPRs that may have been in use at the + * time of the critical interrupt. + * + */ +#ifdef CONFIG_40x +#define PPC_40x_TURN_OFF_MSR_DR \ + /* avoid any possible TLB misses here by turning off MSR.DR, we \ + * assume the instructions here are mapped by a pinned TLB entry */ \ + li r10,MSR_IR; \ + mtmsr r10; \ + isync; \ + tophys(r1, r1); +#else +#define PPC_40x_TURN_OFF_MSR_DR +#endif + +#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \ + REST_NVGPRS(r1); \ + lwz r3,_MSR(r1); \ + andi. r3,r3,MSR_PR; \ + LOAD_MSR_KERNEL(r10,MSR_KERNEL); \ + bne user_exc_return; \ + lwz r0,GPR0(r1); \ + lwz r2,GPR2(r1); \ + REST_4GPRS(3, r1); \ + REST_2GPRS(7, r1); \ + lwz r10,_XER(r1); \ + lwz r11,_CTR(r1); \ + mtspr SPRN_XER,r10; \ + mtctr r11; \ + PPC405_ERR77(0,r1); \ + stwcx. r0,0,r1; /* to clear the reservation */ \ + lwz r11,_LINK(r1); \ + mtlr r11; \ + lwz r10,_CCR(r1); \ + mtcrf 0xff,r10; \ + PPC_40x_TURN_OFF_MSR_DR; \ + lwz r9,_DEAR(r1); \ + lwz r10,_ESR(r1); \ + mtspr SPRN_DEAR,r9; \ + mtspr SPRN_ESR,r10; \ + lwz r11,_NIP(r1); \ + lwz r12,_MSR(r1); \ + mtspr exc_lvl_srr0,r11; \ + mtspr exc_lvl_srr1,r12; \ + lwz r9,GPR9(r1); \ + lwz r12,GPR12(r1); \ + lwz r10,GPR10(r1); \ + lwz r11,GPR11(r1); \ + lwz r1,GPR1(r1); \ + PPC405_ERR77_SYNC; \ + exc_lvl_rfi; \ + b .; /* prevent prefetch past exc_lvl_rfi */ + + .globl ret_from_crit_exc +ret_from_crit_exc: + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) + +#ifdef CONFIG_BOOKE + .globl ret_from_debug_exc +ret_from_debug_exc: + RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) + + .globl ret_from_mcheck_exc +ret_from_mcheck_exc: + RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) +#endif /* CONFIG_BOOKE */ + +/* + * Load the DBCR0 value for a task that is being ptraced, + * having first saved away the global DBCR0. Note that r0 + * has the dbcr0 value to set upon entry to this. + */ +load_dbcr0: + mfmsr r10 /* first disable debug exceptions */ + rlwinm r10,r10,0,~MSR_DE + mtmsr r10 + isync + mfspr r10,SPRN_DBCR0 + lis r11,global_dbcr0@ha + addi r11,r11,global_dbcr0@l + stw r10,0(r11) + mtspr SPRN_DBCR0,r0 + lwz r10,4(r11) + addi r10,r10,1 + stw r10,4(r11) + li r11,-1 + mtspr SPRN_DBSR,r11 /* clear all pending debug events */ + blr + + .comm global_dbcr0,8 +#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ + +do_work: /* r10 contains MSR_KERNEL here */ + andi. r0,r9,_TIF_NEED_RESCHED + beq do_user_signal + +do_resched: /* r10 contains MSR_KERNEL here */ + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* hard-enable interrupts */ + bl schedule +recheck: + LOAD_MSR_KERNEL(r10,MSR_KERNEL) + SYNC + MTMSRD(r10) /* disable interrupts */ + rlwinm r9,r1,0,0,18 + lwz r9,TI_FLAGS(r9) + andi. r0,r9,_TIF_NEED_RESCHED + bne- do_resched + andi. r0,r9,_TIF_SIGPENDING + beq restore_user +do_user_signal: /* r10 contains MSR_KERNEL here */ + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* hard-enable interrupts */ + /* save r13-r31 in the exception frame, if not already done */ + lwz r3,TRAP(r1) + andi. r0,r3,1 + beq 2f + SAVE_NVGPRS(r1) + rlwinm r3,r3,0,0,30 + stw r3,TRAP(r1) +2: li r3,0 + addi r4,r1,STACK_FRAME_OVERHEAD + bl do_signal + REST_NVGPRS(r1) + b recheck + +/* + * We come here when we are at the end of handling an exception + * that occurred at a place where taking an exception will lose + * state information, such as the contents of SRR0 and SRR1. + */ +nonrecoverable: + lis r10,exc_exit_restart_end@ha + addi r10,r10,exc_exit_restart_end@l + cmplw r12,r10 + bge 3f + lis r11,exc_exit_restart@ha + addi r11,r11,exc_exit_restart@l + cmplw r12,r11 + blt 3f + lis r10,ee_restarts@ha + lwz r12,ee_restarts@l(r10) + addi r12,r12,1 + stw r12,ee_restarts@l(r10) + mr r12,r11 /* restart at exc_exit_restart */ + blr +3: /* OK, we can't recover, kill this process */ + /* but the 601 doesn't implement the RI bit, so assume it's OK */ +BEGIN_FTR_SECTION + blr +END_FTR_SECTION_IFSET(CPU_FTR_601) + lwz r3,TRAP(r1) + andi. r0,r3,1 + beq 4f + SAVE_NVGPRS(r1) + rlwinm r3,r3,0,0,30 + stw r3,TRAP(r1) +4: addi r3,r1,STACK_FRAME_OVERHEAD + bl nonrecoverable_exception + /* shouldn't return */ + b 4b + + .comm ee_restarts,4 + +/* + * PROM code for specific machines follows. Put it + * here so it's easy to add arch-specific sections later. + * -- Cort + */ +#ifdef CONFIG_PPC_OF +/* + * On CHRP, the Run-Time Abstraction Services (RTAS) have to be + * called with the MMU off. + */ +_GLOBAL(enter_rtas) + stwu r1,-INT_FRAME_SIZE(r1) + mflr r0 + stw r0,INT_FRAME_SIZE+4(r1) + lis r4,rtas_data@ha + lwz r4,rtas_data@l(r4) + lis r6,1f@ha /* physical return address for rtas */ + addi r6,r6,1f@l + tophys(r6,r6) + tophys(r7,r1) + lis r8,rtas_entry@ha + lwz r8,rtas_entry@l(r8) + mfmsr r9 + stw r9,8(r1) + LOAD_MSR_KERNEL(r0,MSR_KERNEL) + SYNC /* disable interrupts so SRR0/1 */ + MTMSRD(r0) /* don't get trashed */ + li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) + mtlr r6 + CLR_TOP32(r7) + mtspr SPRN_SPRG2,r7 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI +1: tophys(r9,r1) + lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */ + lwz r9,8(r9) /* original msr value */ + FIX_SRR1(r9,r0) + addi r1,r1,INT_FRAME_SIZE + li r0,0 + mtspr SPRN_SPRG2,r0 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI /* return to caller */ + + .globl machine_check_in_rtas +machine_check_in_rtas: + twi 31,0,0 + /* XXX load up BATs and panic */ + +#endif /* CONFIG_PPC_OF */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S new file mode 100644 index 000000000000..22796e28881a --- /dev/null +++ b/arch/powerpc/kernel/entry_64.S @@ -0,0 +1,842 @@ +/* + * arch/ppc64/kernel/entry.S + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * + * This file contains the system call entry code, context switch + * code, and exception/interrupt return code for PowerPC. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PPC_ISERIES +#define DO_SOFT_DISABLE +#endif + +/* + * System calls. + */ + .section ".toc","aw" +.SYS_CALL_TABLE: + .tc .sys_call_table[TC],.sys_call_table + +/* This value is used to mark exception frames on the stack. */ +exception_marker: + .tc ID_72656773_68657265[TC],0x7265677368657265 + + .section ".text" + .align 7 + +#undef SHOW_SYSCALLS + + .globl system_call_common +system_call_common: + andi. r10,r12,MSR_PR + mr r10,r1 + addi r1,r1,-INT_FRAME_SIZE + beq- 1f + ld r1,PACAKSAVE(r13) +1: std r10,0(r1) + std r11,_NIP(r1) + std r12,_MSR(r1) + std r0,GPR0(r1) + std r10,GPR1(r1) + std r2,GPR2(r1) + std r3,GPR3(r1) + std r4,GPR4(r1) + std r5,GPR5(r1) + std r6,GPR6(r1) + std r7,GPR7(r1) + std r8,GPR8(r1) + li r11,0 + std r11,GPR9(r1) + std r11,GPR10(r1) + std r11,GPR11(r1) + std r11,GPR12(r1) + std r9,GPR13(r1) + crclr so + mfcr r9 + mflr r10 + li r11,0xc01 + std r9,_CCR(r1) + std r10,_LINK(r1) + std r11,_TRAP(r1) + mfxer r9 + mfctr r10 + std r9,_XER(r1) + std r10,_CTR(r1) + std r3,ORIG_GPR3(r1) + ld r2,PACATOC(r13) + addi r9,r1,STACK_FRAME_OVERHEAD + ld r11,exception_marker@toc(r2) + std r11,-16(r9) /* "regshere" marker */ +#ifdef CONFIG_PPC_ISERIES + /* Hack for handling interrupts when soft-enabling on iSeries */ + cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ + andi. r10,r12,MSR_PR /* from kernel */ + crand 4*cr0+eq,4*cr1+eq,4*cr0+eq + beq hardware_interrupt_entry + lbz r10,PACAPROCENABLED(r13) + std r10,SOFTE(r1) +#endif + mfmsr r11 + ori r11,r11,MSR_EE + mtmsrd r11,1 + +#ifdef SHOW_SYSCALLS + bl .do_show_syscall + REST_GPR(0,r1) + REST_4GPRS(3,r1) + REST_2GPRS(7,r1) + addi r9,r1,STACK_FRAME_OVERHEAD +#endif + clrrdi r11,r1,THREAD_SHIFT + li r12,0 + ld r10,TI_FLAGS(r11) + stb r12,TI_SC_NOERR(r11) + andi. r11,r10,_TIF_SYSCALL_T_OR_A + bne- syscall_dotrace +syscall_dotrace_cont: + cmpldi 0,r0,NR_syscalls + bge- syscall_enosys + +system_call: /* label this so stack traces look sane */ +/* + * Need to vector to 32 Bit or default sys_call_table here, + * based on caller's run-mode / personality. + */ + ld r11,.SYS_CALL_TABLE@toc(2) + andi. r10,r10,_TIF_32BIT + beq 15f + addi r11,r11,8 /* use 32-bit syscall entries */ + clrldi r3,r3,32 + clrldi r4,r4,32 + clrldi r5,r5,32 + clrldi r6,r6,32 + clrldi r7,r7,32 + clrldi r8,r8,32 +15: + slwi r0,r0,4 + ldx r10,r11,r0 /* Fetch system call handler [ptr] */ + mtctr r10 + bctrl /* Call handler */ + +syscall_exit: +#ifdef SHOW_SYSCALLS + std r3,GPR3(r1) + bl .do_show_syscall_exit + ld r3,GPR3(r1) +#endif + std r3,RESULT(r1) + ld r5,_CCR(r1) + li r10,-_LAST_ERRNO + cmpld r3,r10 + clrrdi r12,r1,THREAD_SHIFT + bge- syscall_error +syscall_error_cont: + + /* check for syscall tracing or audit */ + ld r9,TI_FLAGS(r12) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + bne- syscall_exit_trace +syscall_exit_trace_cont: + + /* disable interrupts so current_thread_info()->flags can't change, + and so that we don't get interrupted after loading SRR0/1. */ + ld r8,_MSR(r1) + andi. r10,r8,MSR_RI + beq- unrecov_restore + mfmsr r10 + rldicl r10,r10,48,1 + rotldi r10,r10,16 + mtmsrd r10,1 + ld r9,TI_FLAGS(r12) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) + bne- syscall_exit_work + ld r7,_NIP(r1) + stdcx. r0,0,r1 /* to clear the reservation */ + andi. r6,r8,MSR_PR + ld r4,_LINK(r1) + beq- 1f /* only restore r13 if */ + ld r13,GPR13(r1) /* returning to usermode */ +1: ld r2,GPR2(r1) + li r12,MSR_RI + andc r10,r10,r12 + mtmsrd r10,1 /* clear MSR.RI */ + ld r1,GPR1(r1) + mtlr r4 + mtcr r5 + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r8 + rfid + b . /* prevent speculative execution */ + +syscall_enosys: + li r3,-ENOSYS + std r3,RESULT(r1) + clrrdi r12,r1,THREAD_SHIFT + ld r5,_CCR(r1) + +syscall_error: + lbz r11,TI_SC_NOERR(r12) + cmpwi 0,r11,0 + bne- syscall_error_cont + neg r3,r3 + oris r5,r5,0x1000 /* Set SO bit in CR */ + std r5,_CCR(r1) + b syscall_error_cont + +/* Traced system call support */ +syscall_dotrace: + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_syscall_trace_enter + ld r0,GPR0(r1) /* Restore original registers */ + ld r3,GPR3(r1) + ld r4,GPR4(r1) + ld r5,GPR5(r1) + ld r6,GPR6(r1) + ld r7,GPR7(r1) + ld r8,GPR8(r1) + addi r9,r1,STACK_FRAME_OVERHEAD + clrrdi r10,r1,THREAD_SHIFT + ld r10,TI_FLAGS(r10) + b syscall_dotrace_cont + +syscall_exit_trace: + std r3,GPR3(r1) + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_syscall_trace_leave + REST_NVGPRS(r1) + ld r3,GPR3(r1) + ld r5,_CCR(r1) + clrrdi r12,r1,THREAD_SHIFT + b syscall_exit_trace_cont + +/* Stuff to do on exit from a system call. */ +syscall_exit_work: + std r3,GPR3(r1) + std r5,_CCR(r1) + b .ret_from_except_lite + +/* Save non-volatile GPRs, if not already saved. */ +_GLOBAL(save_nvgprs) + ld r11,_TRAP(r1) + andi. r0,r11,1 + beqlr- + SAVE_NVGPRS(r1) + clrrdi r0,r11,1 + std r0,_TRAP(r1) + blr + +/* + * The sigsuspend and rt_sigsuspend system calls can call do_signal + * and thus put the process into the stopped state where we might + * want to examine its user state with ptrace. Therefore we need + * to save all the nonvolatile registers (r14 - r31) before calling + * the C code. Similarly, fork, vfork and clone need the full + * register state on the stack so that it can be copied to the child. + */ +_GLOBAL(ppc32_sigsuspend) + bl .save_nvgprs + bl .sys32_sigsuspend + b 70f + +_GLOBAL(ppc64_rt_sigsuspend) + bl .save_nvgprs + bl .sys_rt_sigsuspend + b 70f + +_GLOBAL(ppc32_rt_sigsuspend) + bl .save_nvgprs + bl .sys32_rt_sigsuspend +70: cmpdi 0,r3,0 + /* If it returned an error, we need to return via syscall_exit to set + the SO bit in cr0 and potentially stop for ptrace. */ + bne syscall_exit + /* If sigsuspend() returns zero, we are going into a signal handler. We + may need to call audit_syscall_exit() to mark the exit from sigsuspend() */ +#ifdef CONFIG_AUDIT + ld r3,PACACURRENT(r13) + ld r4,AUDITCONTEXT(r3) + cmpdi 0,r4,0 + beq .ret_from_except /* No audit_context: Leave immediately. */ + li r4, 2 /* AUDITSC_FAILURE */ + li r5,-4 /* It's always -EINTR */ + bl .audit_syscall_exit +#endif + b .ret_from_except + +_GLOBAL(ppc_fork) + bl .save_nvgprs + bl .sys_fork + b syscall_exit + +_GLOBAL(ppc_vfork) + bl .save_nvgprs + bl .sys_vfork + b syscall_exit + +_GLOBAL(ppc_clone) + bl .save_nvgprs + bl .sys_clone + b syscall_exit + +_GLOBAL(ppc32_swapcontext) + bl .save_nvgprs + bl .sys32_swapcontext + b 80f + +_GLOBAL(ppc64_swapcontext) + bl .save_nvgprs + bl .sys_swapcontext + b 80f + +_GLOBAL(ppc32_sigreturn) + bl .sys32_sigreturn + b 80f + +_GLOBAL(ppc32_rt_sigreturn) + bl .sys32_rt_sigreturn + b 80f + +_GLOBAL(ppc64_rt_sigreturn) + bl .sys_rt_sigreturn + +80: cmpdi 0,r3,0 + blt syscall_exit + clrrdi r4,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r4) + andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + beq+ 81f + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_syscall_trace_leave +81: b .ret_from_except + +_GLOBAL(ret_from_fork) + bl .schedule_tail + REST_NVGPRS(r1) + li r3,0 + b syscall_exit + +/* + * This routine switches between two different tasks. The process + * state of one is saved on its kernel stack. Then the state + * of the other is restored from its kernel stack. The memory + * management hardware is updated to the second process's state. + * Finally, we can return to the second process, via ret_from_except. + * On entry, r3 points to the THREAD for the current task, r4 + * points to the THREAD for the new task. + * + * Note: there are two ways to get to the "going out" portion + * of this code; either by coming in via the entry (_switch) + * or via "fork" which must set up an environment equivalent + * to the "_switch" path. If you change this you'll have to change + * the fork code also. + * + * The code which creates the new task context is in 'copy_thread' + * in arch/ppc64/kernel/process.c + */ + .align 7 +_GLOBAL(_switch) + mflr r0 + std r0,16(r1) + stdu r1,-SWITCH_FRAME_SIZE(r1) + /* r3-r13 are caller saved -- Cort */ + SAVE_8GPRS(14, r1) + SAVE_10GPRS(22, r1) + mflr r20 /* Return to switch caller */ + mfmsr r22 + li r0, MSR_FP +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + oris r0,r0,MSR_VEC@h /* Disable altivec */ + mfspr r24,SPRN_VRSAVE /* save vrsave register value */ + std r24,THREAD_VRSAVE(r3) +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ + and. r0,r0,r22 + beq+ 1f + andc r22,r22,r0 + mtmsrd r22 + isync +1: std r20,_NIP(r1) + mfcr r23 + std r23,_CCR(r1) + std r1,KSP(r3) /* Set old stack pointer */ + +#ifdef CONFIG_SMP + /* We need a sync somewhere here to make sure that if the + * previous task gets rescheduled on another CPU, it sees all + * stores it has performed on this one. + */ + sync +#endif /* CONFIG_SMP */ + + addi r6,r4,-THREAD /* Convert THREAD to 'current' */ + std r6,PACACURRENT(r13) /* Set new 'current' */ + + ld r8,KSP(r4) /* new stack pointer */ +BEGIN_FTR_SECTION + clrrdi r6,r8,28 /* get its ESID */ + clrrdi r9,r1,28 /* get current sp ESID */ + clrldi. r0,r6,2 /* is new ESID c00000000? */ + cmpd cr1,r6,r9 /* or is new ESID the same as current ESID? */ + cror eq,4*cr1+eq,eq + beq 2f /* if yes, don't slbie it */ + + /* Bolt in the new stack SLB entry */ + ld r7,KSP_VSID(r4) /* Get new stack's VSID */ + oris r0,r6,(SLB_ESID_V)@h + ori r0,r0,(SLB_NUM_BOLTED-1)@l + slbie r6 + slbie r6 /* Workaround POWER5 < DD2.1 issue */ + slbmte r7,r0 + isync + +2: +END_FTR_SECTION_IFSET(CPU_FTR_SLB) + clrrdi r7,r8,THREAD_SHIFT /* base of new stack */ + /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE + because we don't need to leave the 288-byte ABI gap at the + top of the kernel stack. */ + addi r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE + + mr r1,r8 /* start using new stack pointer */ + std r7,PACAKSAVE(r13) + + ld r6,_CCR(r1) + mtcrf 0xFF,r6 + +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + ld r0,THREAD_VRSAVE(r4) + mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ + + /* r3-r13 are destroyed -- Cort */ + REST_8GPRS(14, r1) + REST_10GPRS(22, r1) + + /* convert old thread to its task_struct for return value */ + addi r3,r3,-THREAD + ld r7,_NIP(r1) /* Return to _switch caller in new task */ + mtlr r7 + addi r1,r1,SWITCH_FRAME_SIZE + blr + + .align 7 +_GLOBAL(ret_from_except) + ld r11,_TRAP(r1) + andi. r0,r11,1 + bne .ret_from_except_lite + REST_NVGPRS(r1) + +_GLOBAL(ret_from_except_lite) + /* + * Disable interrupts so that current_thread_info()->flags + * can't change between when we test it and when we return + * from the interrupt. + */ + mfmsr r10 /* Get current interrupt state */ + rldicl r9,r10,48,1 /* clear MSR_EE */ + rotldi r9,r9,16 + mtmsrd r9,1 /* Update machine state */ + +#ifdef CONFIG_PREEMPT + clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ + li r0,_TIF_NEED_RESCHED /* bits to check */ + ld r3,_MSR(r1) + ld r4,TI_FLAGS(r9) + /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ + rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING + and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ + bne do_work + +#else /* !CONFIG_PREEMPT */ + ld r3,_MSR(r1) /* Returning to user mode? */ + andi. r3,r3,MSR_PR + beq restore /* if not, just restore regs and return */ + + /* Check current_thread_info()->flags */ + clrrdi r9,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r9) + andi. r0,r4,_TIF_USER_WORK_MASK + bne do_work +#endif + +restore: +#ifdef CONFIG_PPC_ISERIES + ld r5,SOFTE(r1) + cmpdi 0,r5,0 + beq 4f + /* Check for pending interrupts (iSeries) */ + ld r3,PACALPPACA+LPPACAANYINT(r13) + cmpdi r3,0 + beq+ 4f /* skip do_IRQ if no interrupts */ + + li r3,0 + stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ + ori r10,r10,MSR_EE + mtmsrd r10 /* hard-enable again */ + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_IRQ + b .ret_from_except_lite /* loop back and handle more */ + +4: stb r5,PACAPROCENABLED(r13) +#endif + + ld r3,_MSR(r1) + andi. r0,r3,MSR_RI + beq- unrecov_restore + + andi. r0,r3,MSR_PR + + /* + * r13 is our per cpu area, only restore it if we are returning to + * userspace + */ + beq 1f + REST_GPR(13, r1) +1: + ld r3,_CTR(r1) + ld r0,_LINK(r1) + mtctr r3 + mtlr r0 + ld r3,_XER(r1) + mtspr SPRN_XER,r3 + + REST_8GPRS(5, r1) + + stdcx. r0,0,r1 /* to clear the reservation */ + + mfmsr r0 + li r2, MSR_RI + andc r0,r0,r2 + mtmsrd r0,1 + + ld r0,_MSR(r1) + mtspr SPRN_SRR1,r0 + + ld r2,_CCR(r1) + mtcrf 0xFF,r2 + ld r2,_NIP(r1) + mtspr SPRN_SRR0,r2 + + ld r0,GPR0(r1) + ld r2,GPR2(r1) + ld r3,GPR3(r1) + ld r4,GPR4(r1) + ld r1,GPR1(r1) + + rfid + b . /* prevent speculative execution */ + +/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */ +do_work: +#ifdef CONFIG_PREEMPT + andi. r0,r3,MSR_PR /* Returning to user mode? */ + bne user_work + /* Check that preempt_count() == 0 and interrupts are enabled */ + lwz r8,TI_PREEMPT(r9) + cmpwi cr1,r8,0 +#ifdef CONFIG_PPC_ISERIES + ld r0,SOFTE(r1) + cmpdi r0,0 +#else + andi. r0,r3,MSR_EE +#endif + crandc eq,cr1*4+eq,eq + bne restore + /* here we are preempting the current task */ +1: +#ifdef CONFIG_PPC_ISERIES + li r0,1 + stb r0,PACAPROCENABLED(r13) +#endif + ori r10,r10,MSR_EE + mtmsrd r10,1 /* reenable interrupts */ + bl .preempt_schedule + mfmsr r10 + clrrdi r9,r1,THREAD_SHIFT + rldicl r10,r10,48,1 /* disable interrupts again */ + rotldi r10,r10,16 + mtmsrd r10,1 + ld r4,TI_FLAGS(r9) + andi. r0,r4,_TIF_NEED_RESCHED + bne 1b + b restore + +user_work: +#endif + /* Enable interrupts */ + ori r10,r10,MSR_EE + mtmsrd r10,1 + + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + bl .schedule + b .ret_from_except_lite + +1: bl .save_nvgprs + li r3,0 + addi r4,r1,STACK_FRAME_OVERHEAD + bl .do_signal + b .ret_from_except + +unrecov_restore: + addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b unrecov_restore + +#ifdef CONFIG_PPC_RTAS +/* + * On CHRP, the Run-Time Abstraction Services (RTAS) have to be + * called with the MMU off. + * + * In addition, we need to be in 32b mode, at least for now. + * + * Note: r3 is an input parameter to rtas, so don't trash it... + */ +_GLOBAL(enter_rtas) + mflr r0 + std r0,16(r1) + stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */ + + /* Because RTAS is running in 32b mode, it clobbers the high order half + * of all registers that it saves. We therefore save those registers + * RTAS might touch to the stack. (r0, r3-r13 are caller saved) + */ + SAVE_GPR(2, r1) /* Save the TOC */ + SAVE_GPR(13, r1) /* Save paca */ + SAVE_8GPRS(14, r1) /* Save the non-volatiles */ + SAVE_10GPRS(22, r1) /* ditto */ + + mfcr r4 + std r4,_CCR(r1) + mfctr r5 + std r5,_CTR(r1) + mfspr r6,SPRN_XER + std r6,_XER(r1) + mfdar r7 + std r7,_DAR(r1) + mfdsisr r8 + std r8,_DSISR(r1) + mfsrr0 r9 + std r9,_SRR0(r1) + mfsrr1 r10 + std r10,_SRR1(r1) + + /* There is no way it is acceptable to get here with interrupts enabled, + * check it with the asm equivalent of WARN_ON + */ + mfmsr r6 + andi. r0,r6,MSR_EE +1: tdnei r0,0 +.section __bug_table,"a" + .llong 1b,__LINE__ + 0x1000000, 1f, 2f +.previous +.section .rodata,"a" +1: .asciz __FILE__ +2: .asciz "enter_rtas" +.previous + + /* Unfortunately, the stack pointer and the MSR are also clobbered, + * so they are saved in the PACA which allows us to restore + * our original state after RTAS returns. + */ + std r1,PACAR1(r13) + std r6,PACASAVEDMSR(r13) + + /* Setup our real return addr */ + SET_REG_TO_LABEL(r4,.rtas_return_loc) + SET_REG_TO_CONST(r9,KERNELBASE) + sub r4,r4,r9 + mtlr r4 + + li r0,0 + ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI + andc r0,r6,r0 + + li r9,1 + rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG) + ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP + andc r6,r0,r9 + ori r6,r6,MSR_RI + sync /* disable interrupts so SRR0/1 */ + mtmsrd r0 /* don't get trashed */ + + SET_REG_TO_LABEL(r4,rtas) + ld r5,RTASENTRY(r4) /* get the rtas->entry value */ + ld r4,RTASBASE(r4) /* get the rtas->base value */ + + mtspr SPRN_SRR0,r5 + mtspr SPRN_SRR1,r6 + rfid + b . /* prevent speculative execution */ + +_STATIC(rtas_return_loc) + /* relocation is off at this point */ + mfspr r4,SPRN_SPRG3 /* Get PACA */ + SET_REG_TO_CONST(r5, KERNELBASE) + sub r4,r4,r5 /* RELOC the PACA base pointer */ + + mfmsr r6 + li r0,MSR_RI + andc r6,r6,r0 + sync + mtmsrd r6 + + ld r1,PACAR1(r4) /* Restore our SP */ + LOADADDR(r3,.rtas_restore_regs) + ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ + + mtspr SPRN_SRR0,r3 + mtspr SPRN_SRR1,r4 + rfid + b . /* prevent speculative execution */ + +_STATIC(rtas_restore_regs) + /* relocation is on at this point */ + REST_GPR(2, r1) /* Restore the TOC */ + REST_GPR(13, r1) /* Restore paca */ + REST_8GPRS(14, r1) /* Restore the non-volatiles */ + REST_10GPRS(22, r1) /* ditto */ + + mfspr r13,SPRN_SPRG3 + + ld r4,_CCR(r1) + mtcr r4 + ld r5,_CTR(r1) + mtctr r5 + ld r6,_XER(r1) + mtspr SPRN_XER,r6 + ld r7,_DAR(r1) + mtdar r7 + ld r8,_DSISR(r1) + mtdsisr r8 + ld r9,_SRR0(r1) + mtsrr0 r9 + ld r10,_SRR1(r1) + mtsrr1 r10 + + addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */ + ld r0,16(r1) /* get return address */ + + mtlr r0 + blr /* return to caller */ + +#endif /* CONFIG_PPC_RTAS */ + +#ifdef CONFIG_PPC_MULTIPLATFORM + +_GLOBAL(enter_prom) + mflr r0 + std r0,16(r1) + stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ + + /* Because PROM is running in 32b mode, it clobbers the high order half + * of all registers that it saves. We therefore save those registers + * PROM might touch to the stack. (r0, r3-r13 are caller saved) + */ + SAVE_8GPRS(2, r1) + SAVE_GPR(13, r1) + SAVE_8GPRS(14, r1) + SAVE_10GPRS(22, r1) + mfcr r4 + std r4,_CCR(r1) + mfctr r5 + std r5,_CTR(r1) + mfspr r6,SPRN_XER + std r6,_XER(r1) + mfdar r7 + std r7,_DAR(r1) + mfdsisr r8 + std r8,_DSISR(r1) + mfsrr0 r9 + std r9,_SRR0(r1) + mfsrr1 r10 + std r10,_SRR1(r1) + mfmsr r11 + std r11,_MSR(r1) + + /* Get the PROM entrypoint */ + ld r0,GPR4(r1) + mtlr r0 + + /* Switch MSR to 32 bits mode + */ + mfmsr r11 + li r12,1 + rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) + andc r11,r11,r12 + li r12,1 + rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) + andc r11,r11,r12 + mtmsrd r11 + isync + + /* Restore arguments & enter PROM here... */ + ld r3,GPR3(r1) + blrl + + /* Just make sure that r1 top 32 bits didn't get + * corrupt by OF + */ + rldicl r1,r1,0,32 + + /* Restore the MSR (back to 64 bits) */ + ld r0,_MSR(r1) + mtmsrd r0 + isync + + /* Restore other registers */ + REST_GPR(2, r1) + REST_GPR(13, r1) + REST_8GPRS(14, r1) + REST_10GPRS(22, r1) + ld r4,_CCR(r1) + mtcr r4 + ld r5,_CTR(r1) + mtctr r5 + ld r6,_XER(r1) + mtspr SPRN_XER,r6 + ld r7,_DAR(r1) + mtdar r7 + ld r8,_DSISR(r1) + mtdsisr r8 + ld r9,_SRR0(r1) + mtsrr0 r9 + ld r10,_SRR1(r1) + mtsrr1 r10 + + addi r1,r1,PROM_FRAME_SIZE + ld r0,16(r1) + mtlr r0 + blr + +#endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S new file mode 100644 index 000000000000..fa8c20ffec78 --- /dev/null +++ b/arch/powerpc/kernel/misc_32.S @@ -0,0 +1,1039 @@ +/* + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + .text + + .align 5 +_GLOBAL(__delay) + cmpwi 0,r3,0 + mtctr r3 + beqlr +1: bdnz 1b + blr + +/* + * Returns (address we're running at) - (address we were linked at) + * for use before the text and data are mapped to KERNELBASE. + */ +_GLOBAL(reloc_offset) + mflr r0 + bl 1f +1: mflr r3 + lis r4,1b@ha + addi r4,r4,1b@l + subf r3,r4,r3 + mtlr r0 + blr + +/* + * add_reloc_offset(x) returns x + reloc_offset(). + */ +_GLOBAL(add_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + lis r4,1b@ha + addi r4,r4,1b@l + subf r5,r4,r5 + add r3,r3,r5 + mtlr r0 + blr + +/* + * sub_reloc_offset(x) returns x - reloc_offset(). + */ +_GLOBAL(sub_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + lis r4,1b@ha + addi r4,r4,1b@l + subf r5,r4,r5 + subf r3,r5,r3 + mtlr r0 + blr + +/* + * reloc_got2 runs through the .got2 section adding an offset + * to each entry. + */ +_GLOBAL(reloc_got2) + mflr r11 + lis r7,__got2_start@ha + addi r7,r7,__got2_start@l + lis r8,__got2_end@ha + addi r8,r8,__got2_end@l + subf r8,r7,r8 + srwi. r8,r8,2 + beqlr + mtctr r8 + bl 1f +1: mflr r0 + lis r4,1b@ha + addi r4,r4,1b@l + subf r0,r4,r0 + add r7,r0,r7 +2: lwz r0,0(r7) + add r0,r0,r3 + stw r0,0(r7) + addi r7,r7,4 + bdnz 2b + mtlr r11 + blr + +/* + * identify_cpu, + * called with r3 = data offset and r4 = CPU number + * doesn't change r3 + */ +_GLOBAL(identify_cpu) + addis r8,r3,cpu_specs@ha + addi r8,r8,cpu_specs@l + mfpvr r7 +1: + lwz r5,CPU_SPEC_PVR_MASK(r8) + and r5,r5,r7 + lwz r6,CPU_SPEC_PVR_VALUE(r8) + cmplw 0,r6,r5 + beq 1f + addi r8,r8,CPU_SPEC_ENTRY_SIZE + b 1b +1: + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + sub r8,r8,r3 + stw r8,0(r6) + blr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + lwz r4,0(r6) + add r4,r4,r3 + lwz r4,CPU_SPEC_FEATURES(r4) + + /* Get the fixup table */ + addis r6,r3,__start___ftr_fixup@ha + addi r6,r6,__start___ftr_fixup@l + addis r7,r3,__stop___ftr_fixup@ha + addi r7,r7,__stop___ftr_fixup@l + + /* Do the fixup */ +1: cmplw 0,r6,r7 + bgelr + addi r6,r6,16 + lwz r8,-16(r6) /* mask */ + and r8,r8,r4 + lwz r9,-12(r6) /* value */ + cmplw 0,r8,r9 + beq 1b + lwz r8,-8(r6) /* section begin */ + lwz r9,-4(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + add r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + +/* + * call_setup_cpu - call the setup_cpu function for this cpu + * r3 = data offset, r24 = cpu number + * + * Setup function is called with: + * r3 = data offset + * r4 = ptr to CPU spec (relocated) + */ +_GLOBAL(call_setup_cpu) + addis r4,r3,cur_cpu_spec@ha + addi r4,r4,cur_cpu_spec@l + lwz r4,0(r4) + add r4,r4,r3 + lwz r5,CPU_SPEC_SETUP(r4) + cmpi 0,r5,0 + add r5,r5,r3 + beqlr + mtctr r5 + bctr + +#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx) + +/* This gets called by via-pmu.c to switch the PLL selection + * on 750fx CPU. This function should really be moved to some + * other place (as most of the cpufreq code in via-pmu + */ +_GLOBAL(low_choose_750fx_pll) + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* If switching to PLL1, disable HID0:BTIC */ + cmplwi cr0,r3,0 + beq 1f + mfspr r5,SPRN_HID0 + rlwinm r5,r5,0,27,25 + sync + mtspr SPRN_HID0,r5 + isync + sync + +1: + /* Calc new HID1 value */ + mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */ + rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */ + rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */ + or r4,r4,r5 + mtspr SPRN_HID1,r4 + + /* Store new HID1 image */ + rlwinm r6,r1,0,0,18 + lwz r6,TI_CPU(r6) + slwi r6,r6,2 + addis r6,r6,nap_save_hid1@ha + stw r4,nap_save_hid1@l(r6) + + /* If switching to PLL0, enable HID0:BTIC */ + cmplwi cr0,r3,0 + bne 1f + mfspr r5,SPRN_HID0 + ori r5,r5,HID0_BTIC + sync + mtspr SPRN_HID0,r5 + isync + sync + +1: + /* Return */ + mtmsr r7 + blr + +_GLOBAL(low_choose_7447a_dfs) + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Calc new HID1 value */ + mfspr r4,SPRN_HID1 + insrwi r4,r3,1,9 /* insert parameter into bit 9 */ + sync + mtspr SPRN_HID1,r4 + sync + isync + + /* Return */ + mtmsr r7 + blr + +#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */ + +/* + * complement mask on the msr then "or" some values on. + * _nmask_and_or_msr(nmask, value_to_or) + */ +_GLOBAL(_nmask_and_or_msr) + mfmsr r0 /* Get current msr */ + andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ + or r0,r0,r4 /* Or on the bits in r4 (second parm) */ + SYNC /* Some chip revs have problems here... */ + mtmsr r0 /* Update machine state */ + isync + blr /* Done */ + + +/* + * Flush MMU TLB + */ +_GLOBAL(_tlbia) +#if defined(CONFIG_40x) + sync /* Flush to memory before changing mapping */ + tlbia + isync /* Flush shadow TLB */ +#elif defined(CONFIG_44x) + li r3,0 + sync + + /* Load high watermark */ + lis r4,tlb_44x_hwater@ha + lwz r5,tlb_44x_hwater@l(r4) + +1: tlbwe r3,r3,PPC44x_TLB_PAGEID + addi r3,r3,1 + cmpw 0,r3,r5 + ble 1b + + isync +#elif defined(CONFIG_FSL_BOOKE) + /* Invalidate all entries in TLB0 */ + li r3, 0x04 + tlbivax 0,3 + /* Invalidate all entries in TLB1 */ + li r3, 0x0c + tlbivax 0,3 + /* Invalidate all entries in TLB2 */ + li r3, 0x14 + tlbivax 0,3 + /* Invalidate all entries in TLB3 */ + li r3, 0x1c + tlbivax 0,3 + msync +#ifdef CONFIG_SMP + tlbsync +#endif /* CONFIG_SMP */ +#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ +#if defined(CONFIG_SMP) + rlwinm r8,r1,0,0,18 + lwz r8,TI_CPU(r8) + oris r8,r8,10 + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear DR */ + mtmsr r0 + SYNC_601 + isync + lis r9,mmu_hash_lock@h + ori r9,r9,mmu_hash_lock@l + tophys(r9,r9) +10: lwarx r7,0,r9 + cmpwi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b + sync + tlbia + sync + TLBSYNC + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ + mtmsr r10 + SYNC_601 + isync +#else /* CONFIG_SMP */ + sync + tlbia + sync +#endif /* CONFIG_SMP */ +#endif /* ! defined(CONFIG_40x) */ + blr + +/* + * Flush MMU TLB for a particular address + */ +_GLOBAL(_tlbie) +#if defined(CONFIG_40x) + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. + * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate + * the TLB entry. */ + tlbwe r3, r3, TLB_TAG + isync +10: +#elif defined(CONFIG_44x) + mfspr r4,SPRN_MMUCR + mfspr r5,SPRN_PID /* Get PID */ + rlwimi r4,r5,0,24,31 /* Set TID */ + mtspr SPRN_MMUCR,r4 + + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, + * which means bit 22, is clear. Since 22 is + * the V bit in the TLB_PAGEID, loading this + * value will invalidate the TLB entry. + */ + tlbwe r3, r3, PPC44x_TLB_PAGEID + isync +10: +#elif defined(CONFIG_FSL_BOOKE) + rlwinm r4, r3, 0, 0, 19 + ori r5, r4, 0x08 /* TLBSEL = 1 */ + ori r6, r4, 0x10 /* TLBSEL = 2 */ + ori r7, r4, 0x18 /* TLBSEL = 3 */ + tlbivax 0, r4 + tlbivax 0, r5 + tlbivax 0, r6 + tlbivax 0, r7 + msync +#if defined(CONFIG_SMP) + tlbsync +#endif /* CONFIG_SMP */ +#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ +#if defined(CONFIG_SMP) + rlwinm r8,r1,0,0,18 + lwz r8,TI_CPU(r8) + oris r8,r8,11 + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear DR */ + mtmsr r0 + SYNC_601 + isync + lis r9,mmu_hash_lock@h + ori r9,r9,mmu_hash_lock@l + tophys(r9,r9) +10: lwarx r7,0,r9 + cmpwi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b + eieio + tlbie r3 + sync + TLBSYNC + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ + mtmsr r10 + SYNC_601 + isync +#else /* CONFIG_SMP */ + tlbie r3 + sync +#endif /* CONFIG_SMP */ +#endif /* ! CONFIG_40x */ + blr + +/* + * Flush instruction cache. + * This is a no-op on the 601. + */ +_GLOBAL(flush_instruction_cache) +#if defined(CONFIG_8xx) + isync + lis r5, IDC_INVALL@h + mtspr SPRN_IC_CST, r5 +#elif defined(CONFIG_4xx) +#ifdef CONFIG_403GCX + li r3, 512 + mtctr r3 + lis r4, KERNELBASE@h +1: iccci 0, r4 + addi r4, r4, 16 + bdnz 1b +#else + lis r3, KERNELBASE@h + iccci 0,r3 +#endif +#elif CONFIG_FSL_BOOKE +BEGIN_FTR_SECTION + mfspr r3,SPRN_L1CSR0 + ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC + /* msync; isync recommended here */ + mtspr SPRN_L1CSR0,r3 + isync + blr +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) + mfspr r3,SPRN_L1CSR1 + ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR + mtspr SPRN_L1CSR1,r3 +#else + mfspr r3,SPRN_PVR + rlwinm r3,r3,16,16,31 + cmpwi 0,r3,1 + beqlr /* for 601, do nothing */ + /* 603/604 processor - use invalidate-all bit in HID0 */ + mfspr r3,SPRN_HID0 + ori r3,r3,HID0_ICFI + mtspr SPRN_HID0,r3 +#endif /* CONFIG_8xx/4xx */ + isync + blr + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * This is a no-op on the 601. + * + * flush_icache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_icache_range) +BEGIN_FTR_SECTION + blr /* for 601, do nothing */ +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) + li r5,L1_CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,L1_CACHE_LINE_SIZE + bdnz 2b + sync /* additional sync needed on g4 */ + isync + blr +/* + * Write any modified data cache blocks out to memory. + * Does not invalidate the corresponding cache lines (especially for + * any corresponding instruction cache). + * + * clean_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(clean_dcache_range) + li r5,L1_CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + beqlr + mtctr r4 + +1: dcbst 0,r3 + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + blr + +/* + * Write any modified data cache blocks out to memory and invalidate them. + * Does not invalidate the corresponding instruction cache blocks. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_dcache_range) + li r5,L1_CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + beqlr + mtctr r4 + +1: dcbf 0,r3 + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + blr + +/* + * Like above, but invalidate the D-cache. This is used by the 8xx + * to invalidate the cache so the PPC core doesn't get stale data + * from the CPM (no cache snooping here :-). + * + * invalidate_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(invalidate_dcache_range) + li r5,L1_CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + beqlr + mtctr r4 + +1: dcbi 0,r3 + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbi's to get to ram */ + blr + +#ifdef CONFIG_NOT_COHERENT_CACHE +/* + * 40x cores have 8K or 16K dcache and 32 byte line size. + * 44x has a 32K dcache and 32 byte line size. + * 8xx has 1, 2, 4, 8K variants. + * For now, cover the worst case of the 44x. + * Must be called with external interrupts disabled. + */ +#define CACHE_NWAYS 64 +#define CACHE_NLINES 16 + +_GLOBAL(flush_dcache_all) + li r4, (2 * CACHE_NWAYS * CACHE_NLINES) + mtctr r4 + lis r5, KERNELBASE@h +1: lwz r3, 0(r5) /* Load one word from every line */ + addi r5, r5, L1_CACHE_LINE_SIZE + bdnz 1b + blr +#endif /* CONFIG_NOT_COHERENT_CACHE */ + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * This is a no-op on the 601 which has a unified cache. + * + * void __flush_dcache_icache(void *page) + */ +_GLOBAL(__flush_dcache_icache) +BEGIN_FTR_SECTION + blr /* for 601, do nothing */ +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) + rlwinm r3,r3,0,0,19 /* Get page base address */ + li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 + mr r6,r3 +0: dcbst 0,r3 /* Write line to ram */ + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 0b + sync + mtctr r4 +1: icbi 0,r6 + addi r6,r6,L1_CACHE_LINE_SIZE + bdnz 1b + sync + isync + blr + +/* + * Flush a particular page from the data cache to RAM, identified + * by its physical address. We turn off the MMU so we can just use + * the physical address (this may be a highmem page without a kernel + * mapping). + * + * void __flush_dcache_icache_phys(unsigned long physaddr) + */ +_GLOBAL(__flush_dcache_icache_phys) +BEGIN_FTR_SECTION + blr /* for 601, do nothing */ +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) + mfmsr r10 + rlwinm r0,r10,0,28,26 /* clear DR */ + mtmsr r0 + isync + rlwinm r3,r3,0,0,19 /* Get page base address */ + li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 + mr r6,r3 +0: dcbst 0,r3 /* Write line to ram */ + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 0b + sync + mtctr r4 +1: icbi 0,r6 + addi r6,r6,L1_CACHE_LINE_SIZE + bdnz 1b + sync + mtmsr r10 /* restore DR */ + isync + blr + +/* + * Clear pages using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced). This only works on cacheable memory. + * + * void clear_pages(void *page, int order) ; + */ +_GLOBAL(clear_pages) + li r0,4096/L1_CACHE_LINE_SIZE + slw r0,r0,r4 + mtctr r0 +#ifdef CONFIG_8xx + li r4, 0 +1: stw r4, 0(r3) + stw r4, 4(r3) + stw r4, 8(r3) + stw r4, 12(r3) +#else +1: dcbz 0,r3 +#endif + addi r3,r3,L1_CACHE_LINE_SIZE + bdnz 1b + blr + +/* + * Copy a whole page. We use the dcbz instruction on the destination + * to reduce memory traffic (it eliminates the unnecessary reads of + * the destination into cache). This requires that the destination + * is cacheable. + */ +#define COPY_16_BYTES \ + lwz r6,4(r4); \ + lwz r7,8(r4); \ + lwz r8,12(r4); \ + lwzu r9,16(r4); \ + stw r6,4(r3); \ + stw r7,8(r3); \ + stw r8,12(r3); \ + stwu r9,16(r3) + +_GLOBAL(copy_page) + addi r3,r3,-4 + addi r4,r4,-4 + +#ifdef CONFIG_8xx + /* don't use prefetch on 8xx */ + li r0,4096/L1_CACHE_LINE_SIZE + mtctr r0 +1: COPY_16_BYTES + bdnz 1b + blr + +#else /* not 8xx, we can prefetch */ + li r5,4 + +#if MAX_COPY_PREFETCH > 1 + li r0,MAX_COPY_PREFETCH + li r11,4 + mtctr r0 +11: dcbt r11,r4 + addi r11,r11,L1_CACHE_LINE_SIZE + bdnz 11b +#else /* MAX_COPY_PREFETCH == 1 */ + dcbt r5,r4 + li r11,L1_CACHE_LINE_SIZE+4 +#endif /* MAX_COPY_PREFETCH */ + li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH + crclr 4*cr0+eq +2: + mtctr r0 +1: + dcbt r11,r4 + dcbz r5,r3 + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 32 + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 64 + COPY_16_BYTES + COPY_16_BYTES +#if L1_CACHE_LINE_SIZE >= 128 + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES +#endif +#endif +#endif + bdnz 1b + beqlr + crnot 4*cr0+eq,4*cr0+eq + li r0,MAX_COPY_PREFETCH + li r11,4 + b 2b +#endif /* CONFIG_8xx */ + +/* + * void atomic_clear_mask(atomic_t mask, atomic_t *addr) + * void atomic_set_mask(atomic_t mask, atomic_t *addr); + */ +_GLOBAL(atomic_clear_mask) +10: lwarx r5,0,r4 + andc r5,r5,r3 + PPC405_ERR77(0,r4) + stwcx. r5,0,r4 + bne- 10b + blr +_GLOBAL(atomic_set_mask) +10: lwarx r5,0,r4 + or r5,r5,r3 + PPC405_ERR77(0,r4) + stwcx. r5,0,r4 + bne- 10b + blr + +/* + * I/O string operations + * + * insb(port, buf, len) + * outsb(port, buf, len) + * insw(port, buf, len) + * outsw(port, buf, len) + * insl(port, buf, len) + * outsl(port, buf, len) + * insw_ns(port, buf, len) + * outsw_ns(port, buf, len) + * insl_ns(port, buf, len) + * outsl_ns(port, buf, len) + * + * The *_ns versions don't do byte-swapping. + */ +_GLOBAL(_insb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbz r5,0(r3) + eieio + stbu r5,1(r4) + bdnz 00b + blr + +_GLOBAL(_outsb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbzu r5,1(r4) + stb r5,0(r3) + eieio + bdnz 00b + blr + +_GLOBAL(_insw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhbrx r5,0,r3 + eieio + sthu r5,2(r4) + bdnz 00b + blr + +_GLOBAL(_outsw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + eieio + sthbrx r5,0,r3 + bdnz 00b + blr + +_GLOBAL(_insl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwbrx r5,0,r3 + eieio + stwu r5,4(r4) + bdnz 00b + blr + +_GLOBAL(_outsl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stwbrx r5,0,r3 + eieio + bdnz 00b + blr + +_GLOBAL(__ide_mm_insw) +_GLOBAL(_insw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhz r5,0(r3) + eieio + sthu r5,2(r4) + bdnz 00b + blr + +_GLOBAL(__ide_mm_outsw) +_GLOBAL(_outsw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + sth r5,0(r3) + eieio + bdnz 00b + blr + +_GLOBAL(__ide_mm_insl) +_GLOBAL(_insl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwz r5,0(r3) + eieio + stwu r5,4(r4) + bdnz 00b + blr + +_GLOBAL(__ide_mm_outsl) +_GLOBAL(_outsl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stw r5,0(r3) + eieio + bdnz 00b + blr + +/* + * Extended precision shifts. + * + * Updated to be valid for shift counts from 0 to 63 inclusive. + * -- Gabriel + * + * R3/R4 has 64 bit value + * R5 has shift count + * result in R3/R4 + * + * ashrdi3: arithmetic right shift (sign propagation) + * lshrdi3: logical right shift + * ashldi3: left shift + */ +_GLOBAL(__ashrdi3) + subfic r6,r5,32 + srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count + addi r7,r5,32 # could be xori, or addi with -32 + slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) + rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0 + sraw r7,r3,r7 # t2 = MSW >> (count-32) + or r4,r4,r6 # LSW |= t1 + slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2 + sraw r3,r3,r5 # MSW = MSW >> count + or r4,r4,r7 # LSW |= t2 + blr + +_GLOBAL(__ashldi3) + subfic r6,r5,32 + slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count + addi r7,r5,32 # could be xori, or addi with -32 + srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count) + slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32) + or r3,r3,r6 # MSW |= t1 + slw r4,r4,r5 # LSW = LSW << count + or r3,r3,r7 # MSW |= t2 + blr + +_GLOBAL(__lshrdi3) + subfic r6,r5,32 + srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count + addi r7,r5,32 # could be xori, or addi with -32 + slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) + srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32) + or r4,r4,r6 # LSW |= t1 + srw r3,r3,r5 # MSW = MSW >> count + or r4,r4,r7 # LSW |= t2 + blr + +_GLOBAL(abs) + srawi r4,r3,31 + xor r3,r3,r4 + sub r3,r3,r4 + blr + +_GLOBAL(_get_SP) + mr r3,r1 /* Close enough */ + blr + +/* + * These are used in the alignment trap handler when emulating + * single-precision loads and stores. + * We restore and save the fpscr so the task gets the same result + * and exceptions as if the cpu had performed the load or store. + */ + +#ifdef CONFIG_PPC_FPU +_GLOBAL(cvt_fd) + lfd 0,-4(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfs 0,0(r3) + stfd 0,0(r4) + mffs 0 /* save new fpscr value */ + stfd 0,-4(r5) + blr + +_GLOBAL(cvt_df) + lfd 0,-4(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfd 0,0(r3) + stfs 0,0(r4) + mffs 0 /* save new fpscr value */ + stfd 0,-4(r5) + blr +#endif + +/* + * Create a kernel thread + * kernel_thread(fn, arg, flags) + */ +_GLOBAL(kernel_thread) + stwu r1,-16(r1) + stw r30,8(r1) + stw r31,12(r1) + mr r30,r3 /* function */ + mr r31,r4 /* argument */ + ori r3,r5,CLONE_VM /* flags */ + oris r3,r3,CLONE_UNTRACED>>16 + li r4,0 /* new sp (unused) */ + li r0,__NR_clone + sc + cmpwi 0,r3,0 /* parent or child? */ + bne 1f /* return if parent */ + li r0,0 /* make top-level stack frame */ + stwu r0,-16(r1) + mtlr r30 /* fn addr in lr */ + mr r3,r31 /* load arg and call fn */ + PPC440EP_ERR42 + blrl + li r0,__NR_exit /* exit if function returns */ + li r3,0 + sc +1: lwz r30,8(r1) + lwz r31,12(r1) + addi r1,r1,16 + blr + +_GLOBAL(execve) + li r0,__NR_execve + sc + bnslr + neg r3,r3 + blr + +/* + * This routine is just here to keep GCC happy - sigh... + */ +_GLOBAL(__main) + blr diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S new file mode 100644 index 000000000000..8fe295693c09 --- /dev/null +++ b/arch/powerpc/kernel/misc_64.S @@ -0,0 +1,898 @@ +/* + * arch/powerpc/kernel/misc64.S + * + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + .text + +/* + * Returns (address we are running at) - (address we were linked at) + * for use before the text and data are mapped to KERNELBASE. + */ + +_GLOBAL(reloc_offset) + mflr r0 + bl 1f +1: mflr r3 + LOADADDR(r4,1b) + subf r3,r4,r3 + mtlr r0 + blr + +/* + * add_reloc_offset(x) returns x + reloc_offset(). + */ +_GLOBAL(add_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + LOADADDR(r4,1b) + subf r5,r4,r5 + add r3,r3,r5 + mtlr r0 + blr + +_GLOBAL(get_msr) + mfmsr r3 + blr + +_GLOBAL(get_dar) + mfdar r3 + blr + +_GLOBAL(get_srr0) + mfsrr0 r3 + blr + +_GLOBAL(get_srr1) + mfsrr1 r3 + blr + +_GLOBAL(get_sp) + mr r3,r1 + blr + +#ifdef CONFIG_IRQSTACKS +_GLOBAL(call_do_softirq) + mflr r0 + std r0,16(r1) + stdu r1,THREAD_SIZE-112(r3) + mr r1,r3 + bl .__do_softirq + ld r1,0(r1) + ld r0,16(r1) + mtlr r0 + blr + +_GLOBAL(call_handle_IRQ_event) + mflr r0 + std r0,16(r1) + stdu r1,THREAD_SIZE-112(r6) + mr r1,r6 + bl .handle_IRQ_event + ld r1,0(r1) + ld r0,16(r1) + mtlr r0 + blr +#endif /* CONFIG_IRQSTACKS */ + + /* + * To be called by C code which needs to do some operations with MMU + * disabled. Note that interrupts have to be disabled by the caller + * prior to calling us. The code called _MUST_ be in the RMO of course + * and part of the linear mapping as we don't attempt to translate the + * stack pointer at all. The function is called with the stack switched + * to this CPU emergency stack + * + * prototype is void *call_with_mmu_off(void *func, void *data); + * + * the called function is expected to be of the form + * + * void *called(void *data); + */ +_GLOBAL(call_with_mmu_off) + mflr r0 /* get link, save it on stackframe */ + std r0,16(r1) + mr r1,r5 /* save old stack ptr */ + ld r1,PACAEMERGSP(r13) /* get emerg. stack */ + subi r1,r1,STACK_FRAME_OVERHEAD + std r0,16(r1) /* save link on emerg. stack */ + std r5,0(r1) /* save old stack ptr in backchain */ + ld r3,0(r3) /* get to real function ptr (assume same TOC) */ + bl 2f /* we need LR to return, continue at label 2 */ + + ld r0,16(r1) /* we return here from the call, get LR and */ + ld r1,0(r1) /* .. old stack ptr */ + mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ + mfmsr r4 + ori r4,r4,MSR_IR|MSR_DR + mtspr SPRN_SRR1,r4 + rfid + +2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ + mr r3,r4 /* get parameter */ + mfmsr r0 + ori r0,r0,MSR_IR|MSR_DR + xori r0,r0,MSR_IR|MSR_DR + mtspr SPRN_SRR1,r0 + rfid + + + .section ".toc","aw" +PPC64_CACHES: + .tc ppc64_caches[TC],ppc64_caches + .section ".text" + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * + * flush_icache_range(unsigned long start, unsigned long stop) + * + * flush all bytes from start through stop-1 inclusive + */ + +_KPROBE(__flush_icache_range) + +/* + * Flush the data cache to memory + * + * Different systems have different cache line sizes + * and in some cases i-cache and d-cache line sizes differ from + * each other. + */ + ld r10,PPC64_CACHES@toc(r2) + lwz r7,DCACHEL1LINESIZE(r10)/* Get cache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of cache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +1: dcbst 0,r6 + add r6,r6,r7 + bdnz 1b + sync + +/* Now invalidate the instruction cache */ + + lwz r7,ICACHEL1LINESIZE(r10) /* Get Icache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 + lwz r9,ICACHEL1LOGLINESIZE(r10) /* Get log-2 of Icache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +2: icbi 0,r6 + add r6,r6,r7 + bdnz 2b + isync + blr + .previous .text +/* + * Like above, but only do the D-cache. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + * + * flush all bytes from start to stop-1 inclusive + */ +_GLOBAL(flush_dcache_range) + +/* + * Flush the data cache to memory + * + * Different systems have different cache line sizes + */ + ld r10,PPC64_CACHES@toc(r2) + lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +0: dcbst 0,r6 + add r6,r6,r7 + bdnz 0b + sync + blr + +/* + * Like above, but works on non-mapped physical addresses. + * Use only for non-LPAR setups ! It also assumes real mode + * is cacheable. Used for flushing out the DART before using + * it as uncacheable memory + * + * flush_dcache_phys_range(unsigned long start, unsigned long stop) + * + * flush all bytes from start to stop-1 inclusive + */ +_GLOBAL(flush_dcache_phys_range) + ld r10,PPC64_CACHES@toc(r2) + lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mfmsr r5 /* Disable MMU Data Relocation */ + ori r0,r5,MSR_DR + xori r0,r0,MSR_DR + sync + mtmsr r0 + sync + isync + mtctr r8 +0: dcbst 0,r6 + add r6,r6,r7 + bdnz 0b + sync + isync + mtmsr r5 /* Re-enable MMU Data Relocation */ + sync + isync + blr + +_GLOBAL(flush_inval_dcache_range) + ld r10,PPC64_CACHES@toc(r2) + lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + sync + isync + mtctr r8 +0: dcbf 0,r6 + add r6,r6,r7 + bdnz 0b + sync + isync + blr + + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * void __flush_dcache_icache(void *page) + */ +_GLOBAL(__flush_dcache_icache) +/* + * Flush the data cache to memory + * + * Different systems have different cache line sizes + */ + +/* Flush the dcache */ + ld r7,PPC64_CACHES@toc(r2) + clrrdi r3,r3,PAGE_SHIFT /* Page align */ + lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */ + lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */ + mr r6,r3 + mtctr r4 +0: dcbst 0,r6 + add r6,r6,r5 + bdnz 0b + sync + +/* Now invalidate the icache */ + + lwz r4,ICACHEL1LINESPERPAGE(r7) /* Get # icache lines per page */ + lwz r5,ICACHEL1LINESIZE(r7) /* Get icache line size */ + mtctr r4 +1: icbi 0,r3 + add r3,r3,r5 + bdnz 1b + isync + blr + +/* + * I/O string operations + * + * insb(port, buf, len) + * outsb(port, buf, len) + * insw(port, buf, len) + * outsw(port, buf, len) + * insl(port, buf, len) + * outsl(port, buf, len) + * insw_ns(port, buf, len) + * outsw_ns(port, buf, len) + * insl_ns(port, buf, len) + * outsl_ns(port, buf, len) + * + * The *_ns versions don't do byte-swapping. + */ +_GLOBAL(_insb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbz r5,0(r3) + eieio + stbu r5,1(r4) + bdnz 00b + twi 0,r5,0 + isync + blr + +_GLOBAL(_outsb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbzu r5,1(r4) + stb r5,0(r3) + bdnz 00b + sync + blr + +_GLOBAL(_insw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhbrx r5,0,r3 + eieio + sthu r5,2(r4) + bdnz 00b + twi 0,r5,0 + isync + blr + +_GLOBAL(_outsw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + sthbrx r5,0,r3 + bdnz 00b + sync + blr + +_GLOBAL(_insl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwbrx r5,0,r3 + eieio + stwu r5,4(r4) + bdnz 00b + twi 0,r5,0 + isync + blr + +_GLOBAL(_outsl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stwbrx r5,0,r3 + bdnz 00b + sync + blr + +/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ +_GLOBAL(_insw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhz r5,0(r3) + eieio + sthu r5,2(r4) + bdnz 00b + twi 0,r5,0 + isync + blr + +/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ +_GLOBAL(_outsw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + sth r5,0(r3) + bdnz 00b + sync + blr + +_GLOBAL(_insl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwz r5,0(r3) + eieio + stwu r5,4(r4) + bdnz 00b + twi 0,r5,0 + isync + blr + +_GLOBAL(_outsl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stw r5,0(r3) + bdnz 00b + sync + blr + + +_GLOBAL(cvt_fd) + lfd 0,0(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfs 0,0(r3) + stfd 0,0(r4) + mffs 0 /* save new fpscr value */ + stfd 0,0(r5) + blr + +_GLOBAL(cvt_df) + lfd 0,0(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfd 0,0(r3) + stfs 0,0(r4) + mffs 0 /* save new fpscr value */ + stfd 0,0(r5) + blr + +/* + * identify_cpu and calls setup_cpu + * In: r3 = base of the cpu_specs array + * r4 = address of cur_cpu_spec + * r5 = relocation offset + */ +_GLOBAL(identify_cpu) + mfpvr r7 +1: + lwz r8,CPU_SPEC_PVR_MASK(r3) + and r8,r8,r7 + lwz r9,CPU_SPEC_PVR_VALUE(r3) + cmplw 0,r9,r8 + beq 1f + addi r3,r3,CPU_SPEC_ENTRY_SIZE + b 1b +1: + sub r0,r3,r5 + std r0,0(r4) + ld r4,CPU_SPEC_SETUP(r3) + add r4,r4,r5 + ld r4,0(r4) + add r4,r4,r5 + mtctr r4 + /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ + mr r4,r3 + mr r3,r5 + bctr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + LOADADDR(r6,cur_cpu_spec) + sub r6,r6,r3 + ld r4,0(r6) + sub r4,r4,r3 + ld r4,CPU_SPEC_FEATURES(r4) + /* Get the fixup table */ + LOADADDR(r6,__start___ftr_fixup) + sub r6,r6,r3 + LOADADDR(r7,__stop___ftr_fixup) + sub r7,r7,r3 + /* Do the fixup */ +1: cmpld r6,r7 + bgelr + addi r6,r6,32 + ld r8,-32(r6) /* mask */ + and r8,r8,r4 + ld r9,-24(r6) /* value */ + cmpld r8,r9 + beq 1b + ld r8,-16(r6) /* section begin */ + ld r9,-8(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + sub r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + +#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) +/* + * Do an IO access in real mode + */ +_GLOBAL(real_readb) + mfmsr r7 + ori r0,r7,MSR_DR + xori r0,r0,MSR_DR + sync + mtmsrd r0 + sync + isync + mfspr r6,SPRN_HID4 + rldicl r5,r6,32,0 + ori r5,r5,0x100 + rldicl r5,r5,32,0 + sync + mtspr SPRN_HID4,r5 + isync + slbia + isync + lbz r3,0(r3) + sync + mtspr SPRN_HID4,r6 + isync + slbia + isync + mtmsrd r7 + sync + isync + blr + + /* + * Do an IO access in real mode + */ +_GLOBAL(real_writeb) + mfmsr r7 + ori r0,r7,MSR_DR + xori r0,r0,MSR_DR + sync + mtmsrd r0 + sync + isync + mfspr r6,SPRN_HID4 + rldicl r5,r6,32,0 + ori r5,r5,0x100 + rldicl r5,r5,32,0 + sync + mtspr SPRN_HID4,r5 + isync + slbia + isync + stb r3,0(r4) + sync + mtspr SPRN_HID4,r6 + isync + slbia + isync + mtmsrd r7 + sync + isync + blr +#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ + +/* + * Create a kernel thread + * kernel_thread(fn, arg, flags) + */ +_GLOBAL(kernel_thread) + std r29,-24(r1) + std r30,-16(r1) + stdu r1,-STACK_FRAME_OVERHEAD(r1) + mr r29,r3 + mr r30,r4 + ori r3,r5,CLONE_VM /* flags */ + oris r3,r3,(CLONE_UNTRACED>>16) + li r4,0 /* new sp (unused) */ + li r0,__NR_clone + sc + cmpdi 0,r3,0 /* parent or child? */ + bne 1f /* return if parent */ + li r0,0 + stdu r0,-STACK_FRAME_OVERHEAD(r1) + ld r2,8(r29) + ld r29,0(r29) + mtlr r29 /* fn addr in lr */ + mr r3,r30 /* load arg and call fn */ + blrl + li r0,__NR_exit /* exit after child exits */ + li r3,0 + sc +1: addi r1,r1,STACK_FRAME_OVERHEAD + ld r29,-24(r1) + ld r30,-16(r1) + blr + +/* + * disable_kernel_fp() + * Disable the FPU. + */ +_GLOBAL(disable_kernel_fp) + mfmsr r3 + rldicl r0,r3,(63-MSR_FP_LG),1 + rldicl r3,r0,(MSR_FP_LG+1),0 + mtmsrd r3 /* disable use of fpu now */ + isync + blr + +#ifdef CONFIG_ALTIVEC + +#if 0 /* this has no callers for now */ +/* + * disable_kernel_altivec() + * Disable the VMX. + */ +_GLOBAL(disable_kernel_altivec) + mfmsr r3 + rldicl r0,r3,(63-MSR_VEC_LG),1 + rldicl r3,r0,(MSR_VEC_LG+1),0 + mtmsrd r3 /* disable use of VMX now */ + isync + blr +#endif /* 0 */ + +/* + * giveup_altivec(tsk) + * Disable VMX for the task given as the argument, + * and save the vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + */ +_GLOBAL(giveup_altivec) + mfmsr r5 + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of VMX now */ + isync + cmpdi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpdi 0,r5,0 + SAVE_32VRS(0,r4,r3) + mfvscr vr0 + li r4,THREAD_VSCR + stvx vr0,r4,r3 + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC@h + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + ld r4,last_task_used_altivec@got(r2) + std r5,0(r4) +#endif /* CONFIG_SMP */ + blr + +#endif /* CONFIG_ALTIVEC */ + +_GLOBAL(__setup_cpu_power3) + blr + +_GLOBAL(execve) + li r0,__NR_execve + sc + bnslr + neg r3,r3 + blr + +/* kexec_wait(phys_cpu) + * + * wait for the flag to change, indicating this kernel is going away but + * the slave code for the next one is at addresses 0 to 100. + * + * This is used by all slaves. + * + * Physical (hardware) cpu id should be in r3. + */ +_GLOBAL(kexec_wait) + bl 1f +1: mflr r5 + addi r5,r5,kexec_flag-1b + +99: HMT_LOW +#ifdef CONFIG_KEXEC /* use no memory without kexec */ + lwz r4,0(r5) + cmpwi 0,r4,0 + bnea 0x60 +#endif + b 99b + +/* this can be in text because we won't change it until we are + * running in real anyways + */ +kexec_flag: + .long 0 + + +#ifdef CONFIG_KEXEC + +/* kexec_smp_wait(void) + * + * call with interrupts off + * note: this is a terminal routine, it does not save lr + * + * get phys id from paca + * set paca id to -1 to say we got here + * switch to real mode + * join other cpus in kexec_wait(phys_id) + */ +_GLOBAL(kexec_smp_wait) + lhz r3,PACAHWCPUID(r13) + li r4,-1 + sth r4,PACAHWCPUID(r13) /* let others know we left */ + bl real_mode + b .kexec_wait + +/* + * switch to real mode (turn mmu off) + * we use the early kernel trick that the hardware ignores bits + * 0 and 1 (big endian) of the effective address in real mode + * + * don't overwrite r3 here, it is live for kexec_wait above. + */ +real_mode: /* assume normal blr return */ +1: li r9,MSR_RI + li r10,MSR_DR|MSR_IR + mflr r11 /* return address to SRR0 */ + mfmsr r12 + andc r9,r12,r9 + andc r10,r12,r10 + + mtmsrd r9,1 + mtspr SPRN_SRR1,r10 + mtspr SPRN_SRR0,r11 + rfid + + +/* + * kexec_sequence(newstack, start, image, control, clear_all()) + * + * does the grungy work with stack switching and real mode switches + * also does simple calls to other code + */ + +_GLOBAL(kexec_sequence) + mflr r0 + std r0,16(r1) + + /* switch stacks to newstack -- &kexec_stack.stack */ + stdu r1,THREAD_SIZE-112(r3) + mr r1,r3 + + li r0,0 + std r0,16(r1) + + /* save regs for local vars on new stack. + * yes, we won't go back, but ... + */ + std r31,-8(r1) + std r30,-16(r1) + std r29,-24(r1) + std r28,-32(r1) + std r27,-40(r1) + std r26,-48(r1) + std r25,-56(r1) + + stdu r1,-112-64(r1) + + /* save args into preserved regs */ + mr r31,r3 /* newstack (both) */ + mr r30,r4 /* start (real) */ + mr r29,r5 /* image (virt) */ + mr r28,r6 /* control, unused */ + mr r27,r7 /* clear_all() fn desc */ + mr r26,r8 /* spare */ + lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ + + /* disable interrupts, we are overwriting kernel data next */ + mfmsr r3 + rlwinm r3,r3,0,17,15 + mtmsrd r3,1 + + /* copy dest pages, flush whole dest image */ + mr r3,r29 + bl .kexec_copy_flush /* (image) */ + + /* turn off mmu */ + bl real_mode + + /* clear out hardware hash page table and tlb */ + ld r5,0(r27) /* deref function descriptor */ + mtctr r5 + bctrl /* ppc_md.hash_clear_all(void); */ + +/* + * kexec image calling is: + * the first 0x100 bytes of the entry point are copied to 0 + * + * all slaves branch to slave = 0x60 (absolute) + * slave(phys_cpu_id); + * + * master goes to start = entry point + * start(phys_cpu_id, start, 0); + * + * + * a wrapper is needed to call existing kernels, here is an approximate + * description of one method: + * + * v2: (2.6.10) + * start will be near the boot_block (maybe 0x100 bytes before it?) + * it will have a 0x60, which will b to boot_block, where it will wait + * and 0 will store phys into struct boot-block and load r3 from there, + * copy kernel 0-0x100 and tell slaves to back down to 0x60 again + * + * v1: (2.6.9) + * boot block will have all cpus scanning device tree to see if they + * are the boot cpu ????? + * other device tree differences (prop sizes, va vs pa, etc)... + */ + + /* copy 0x100 bytes starting at start to 0 */ + li r3,0 + mr r4,r30 + li r5,0x100 + li r6,0 + bl .copy_and_flush /* (dest, src, copy limit, start offset) */ +1: /* assume normal blr return */ + + /* release other cpus to the new kernel secondary start at 0x60 */ + mflr r5 + li r6,1 + stw r6,kexec_flag-1b(5) + mr r3,r25 # my phys cpu + mr r4,r30 # start, aka phys mem offset + mtlr 4 + li r5,0 + blr /* image->start(physid, image->start, 0); */ +#endif /* CONFIG_KEXEC */ diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S new file mode 100644 index 000000000000..82d1fedb441c --- /dev/null +++ b/arch/powerpc/kernel/systbl.S @@ -0,0 +1,323 @@ +/* + * This file contains the table of syscall-handling functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * 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. + */ + +#include +#include + +#ifdef CONFIG_PPC64 +#define SYSCALL(func) .llong .sys_##func,.sys_##func +#define SYSCALL32(func) .llong .sys_##func,.sys32_##func +#define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func +#define PPC_SYS(func) .llong .ppc_##func,.ppc_##func +#define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall +#define SYS32ONLY(func) .llong .sys_ni_syscall,.sys32_##func +#define SYSX(f, f3264, f32) .llong .f,.f3264 +#else +#define SYSCALL(func) .long sys_##func +#define SYSCALL32(func) .long sys_##func +#define COMPAT_SYS(func) .long sys_##func +#define PPC_SYS(func) .long ppc_##func +#define OLDSYS(func) .long sys_##func +#define SYS32ONLY(func) .long sys_##func +#define SYSX(f, f3264, f32) .long f32 +#endif + +#ifdef CONFIG_PPC64 +#define sys_sigpending sys_ni_syscall +#define sys_old_getrlimit sys_ni_syscall +#else +#define ppc_rtas sys_ni_syscall +#endif + +_GLOBAL(sys_call_table) +SYSCALL(restart_syscall) +SYSCALL(exit) +PPC_SYS(fork) +SYSCALL(read) +SYSCALL(write) +COMPAT_SYS(open) +SYSCALL(close) +SYSCALL32(waitpid) +SYSCALL32(creat) +SYSCALL(link) +SYSCALL(unlink) +SYSCALL32(execve) +SYSCALL(chdir) +SYSX(sys64_time,compat_sys_time,sys_time) +SYSCALL(mknod) +SYSCALL(chmod) +SYSCALL(lchown) +SYSCALL(ni_syscall) +OLDSYS(stat) +SYSX(sys_lseek,ppc32_lseek,sys_lseek) +SYSCALL(getpid) +COMPAT_SYS(mount) +SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount) +SYSCALL(setuid) +SYSCALL(getuid) +COMPAT_SYS(stime) +SYSCALL32(ptrace) +SYSCALL(alarm) +OLDSYS(fstat) +SYSCALL32(pause) +COMPAT_SYS(utime) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +SYSCALL32(access) +SYSCALL32(nice) +SYSCALL(ni_syscall) +SYSCALL(sync) +SYSCALL32(kill) +SYSCALL(rename) +SYSCALL32(mkdir) +SYSCALL(rmdir) +SYSCALL(dup) +SYSCALL(pipe) +COMPAT_SYS(times) +SYSCALL(ni_syscall) +SYSCALL(brk) +SYSCALL(setgid) +SYSCALL(getgid) +SYSCALL(signal) +SYSCALL(geteuid) +SYSCALL(getegid) +SYSCALL(acct) +SYSCALL(umount) +SYSCALL(ni_syscall) +COMPAT_SYS(ioctl) +COMPAT_SYS(fcntl) +SYSCALL(ni_syscall) +SYSCALL32(setpgid) +SYSCALL(ni_syscall) +SYS32ONLY(olduname) +SYSCALL32(umask) +SYSCALL(chroot) +SYSCALL(ustat) +SYSCALL(dup2) +SYSCALL(getppid) +SYSCALL(getpgrp) +SYSCALL(setsid) +SYS32ONLY(sigaction) +SYSCALL(sgetmask) +SYSCALL32(ssetmask) +SYSCALL(setreuid) +SYSCALL(setregid) +SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend) +COMPAT_SYS(sigpending) +SYSCALL32(sethostname) +COMPAT_SYS(setrlimit) +COMPAT_SYS(old_getrlimit) +COMPAT_SYS(getrusage) +SYSCALL32(gettimeofday) +SYSCALL32(settimeofday) +SYSCALL32(getgroups) +SYSCALL32(setgroups) +SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select) +SYSCALL(symlink) +OLDSYS(lstat) +SYSCALL32(readlink) +SYSCALL(uselib) +SYSCALL(swapon) +SYSCALL(reboot) +SYSX(sys_ni_syscall,old32_readdir,old_readdir) +SYSCALL(mmap) +SYSCALL(munmap) +SYSCALL(truncate) +SYSCALL(ftruncate) +SYSCALL(fchmod) +SYSCALL(fchown) +SYSCALL32(getpriority) +SYSCALL32(setpriority) +SYSCALL(ni_syscall) +COMPAT_SYS(statfs) +COMPAT_SYS(fstatfs) +SYSCALL(ni_syscall) +COMPAT_SYS(socketcall) +SYSCALL32(syslog) +COMPAT_SYS(setitimer) +COMPAT_SYS(getitimer) +COMPAT_SYS(newstat) +COMPAT_SYS(newlstat) +COMPAT_SYS(newfstat) +SYSX(sys_ni_syscall,sys32_uname,sys_uname) +SYSCALL(ni_syscall) +SYSCALL(vhangup) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +COMPAT_SYS(wait4) +SYSCALL(swapoff) +SYSCALL32(sysinfo) +SYSCALL32(ipc) +SYSCALL(fsync) +SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) +PPC_SYS(clone) +SYSCALL32(setdomainname) +SYSX(ppc64_newuname,ppc64_newuname,sys_newuname) +SYSCALL(ni_syscall) +SYSCALL32(adjtimex) +SYSCALL(mprotect) +SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask) +SYSCALL(ni_syscall) +SYSCALL(init_module) +SYSCALL(delete_module) +SYSCALL(ni_syscall) +SYSCALL(quotactl) +SYSCALL32(getpgid) +SYSCALL(fchdir) +SYSCALL(bdflush) +SYSCALL32(sysfs) +SYSX(ppc64_personality,ppc64_personality,sys_personality) +SYSCALL(ni_syscall) +SYSCALL(setfsuid) +SYSCALL(setfsgid) +SYSCALL(llseek) +SYSCALL32(getdents) +SYSX(sys_select,ppc32_select,ppc_select) +SYSCALL(flock) +SYSCALL(msync) +COMPAT_SYS(readv) +COMPAT_SYS(writev) +SYSCALL32(getsid) +SYSCALL(fdatasync) +SYSCALL32(sysctl) +SYSCALL(mlock) +SYSCALL(munlock) +SYSCALL(mlockall) +SYSCALL(munlockall) +SYSCALL32(sched_setparam) +SYSCALL32(sched_getparam) +SYSCALL32(sched_setscheduler) +SYSCALL32(sched_getscheduler) +SYSCALL(sched_yield) +SYSCALL32(sched_get_priority_max) +SYSCALL32(sched_get_priority_min) +SYSCALL32(sched_rr_get_interval) +COMPAT_SYS(nanosleep) +SYSCALL(mremap) +SYSCALL(setresuid) +SYSCALL(getresuid) +SYSCALL(ni_syscall) +SYSCALL(poll) +COMPAT_SYS(nfsservctl) +SYSCALL(setresgid) +SYSCALL(getresgid) +SYSCALL32(prctl) +SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn) +SYSCALL32(rt_sigaction) +SYSCALL32(rt_sigprocmask) +SYSCALL32(rt_sigpending) +COMPAT_SYS(rt_sigtimedwait) +SYSCALL32(rt_sigqueueinfo) +SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend) +SYSCALL32(pread64) +SYSCALL32(pwrite64) +SYSCALL(chown) +SYSCALL(getcwd) +SYSCALL(capget) +SYSCALL(capset) +SYSCALL32(sigaltstack) +SYSX(sys_sendfile64,sys32_sendfile,sys_sendfile) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +PPC_SYS(vfork) +COMPAT_SYS(getrlimit) +SYSCALL32(readahead) +SYS32ONLY(mmap2) +SYS32ONLY(truncate64) +SYS32ONLY(ftruncate64) +SYSX(sys_ni_syscall,sys_stat64,sys_stat64) +SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64) +SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64) +SYSCALL32(pciconfig_read) +SYSCALL32(pciconfig_write) +SYSCALL32(pciconfig_iobase) +SYSCALL(ni_syscall) +SYSCALL(getdents64) +SYSCALL(pivot_root) +SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64) +SYSCALL(madvise) +SYSCALL(mincore) +SYSCALL(gettid) +SYSCALL(tkill) +SYSCALL(setxattr) +SYSCALL(lsetxattr) +SYSCALL(fsetxattr) +SYSCALL(getxattr) +SYSCALL(lgetxattr) +SYSCALL(fgetxattr) +SYSCALL(listxattr) +SYSCALL(llistxattr) +SYSCALL(flistxattr) +SYSCALL(removexattr) +SYSCALL(lremovexattr) +SYSCALL(fremovexattr) +COMPAT_SYS(futex) +COMPAT_SYS(sched_setaffinity) +COMPAT_SYS(sched_getaffinity) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +SYS32ONLY(sendfile64) +COMPAT_SYS(io_setup) +SYSCALL(io_destroy) +COMPAT_SYS(io_getevents) +COMPAT_SYS(io_submit) +SYSCALL(io_cancel) +SYSCALL(set_tid_address) +SYSX(sys_fadvise64,ppc32_fadvise64,sys_fadvise64) +SYSCALL(exit_group) +SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie) +SYSCALL(epoll_create) +SYSCALL(epoll_ctl) +SYSCALL(epoll_wait) +SYSCALL(remap_file_pages) +SYSX(sys_timer_create,ppc32_timer_create,sys_timer_create) +COMPAT_SYS(timer_settime) +COMPAT_SYS(timer_gettime) +SYSCALL(timer_getoverrun) +SYSCALL(timer_delete) +COMPAT_SYS(clock_settime) +COMPAT_SYS(clock_gettime) +COMPAT_SYS(clock_getres) +COMPAT_SYS(clock_nanosleep) +SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) +SYSCALL32(tgkill) +SYSCALL32(utimes) +COMPAT_SYS(statfs64) +COMPAT_SYS(fstatfs64) +SYSX(sys_ni_syscall, ppc32_fadvise64_64, sys_fadvise64_64) +PPC_SYS(rtas) +OLDSYS(debug_setcontext) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +COMPAT_SYS(mbind) +COMPAT_SYS(get_mempolicy) +COMPAT_SYS(set_mempolicy) +COMPAT_SYS(mq_open) +SYSCALL(mq_unlink) +COMPAT_SYS(mq_timedsend) +COMPAT_SYS(mq_timedreceive) +COMPAT_SYS(mq_notify) +COMPAT_SYS(mq_getsetattr) +COMPAT_SYS(kexec_load) +SYSCALL32(add_key) +SYSCALL32(request_key) +COMPAT_SYS(keyctl) +COMPAT_SYS(waitid) +SYSCALL32(ioprio_set) +SYSCALL32(ioprio_get) +SYSCALL(inotify_init) +SYSCALL(inotify_add_watch) +SYSCALL(inotify_rm_watch) From b42b661745c8d78cd3483752fb22cc7420c67f74 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:37:16 +1000 Subject: [PATCH 0240/1940] powerpc: Make prom_init.c suitable for both 32-bit and 64-bit Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index e01cda1454c9..75b487f107c3 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1968,9 +1968,9 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, extern char _stext[]; unsigned long hdr; u32 getprop_rval; + unsigned long offset = reloc_offset(); #ifdef CONFIG_PPC32 - unsigned long offset = reloc_offset(); reloc_got2(offset); #endif From 8641778049e75c1da66e66441a6d8b7a2069f607 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:37:57 +1000 Subject: [PATCH 0241/1940] powerpc: Reduce the 32/64-bit differences in traps.c Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/traps.c | 58 +++++++++++-------------------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a2e4ad3f5a75..6a881e3ea01d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -31,29 +31,33 @@ #include #include #include -#include +#include #include #include #include #include +#include +#include +#include #ifdef CONFIG_PPC32 #include -#include +#include +#endif #ifdef CONFIG_PMAC_BACKLIGHT #include #endif -#include -#endif #ifdef CONFIG_PPC64 +#include #include -#include -#include #include -#include #include #endif +#ifdef CONFIG_PPC64 /* XXX */ +#define _IO_BASE pci_io_base +#endif + #ifdef CONFIG_DEBUGGER int (*__debugger)(struct pt_regs *regs); int (*__debugger_ipi)(struct pt_regs *regs); @@ -277,7 +281,6 @@ static inline int check_io_access(struct pt_regs *regs) } #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - /* On 4xx, the reason for the machine check or program exception is in the ESR. */ #define get_reason(regs) ((regs)->dsisr) @@ -296,7 +299,6 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) #else - /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ #define get_reason(regs) ((regs)->msr) @@ -475,7 +477,7 @@ void machine_check_exception(struct pt_regs *regs) * additional info, e.g. bus error registers. */ platform_machine_check(regs); -#endif /* CONFIG_PPC32 */ +#endif /* CONFIG_PPC64 */ if (debugger_fault_handler(regs)) return; @@ -486,12 +488,10 @@ void machine_check_exception(struct pt_regs *regs) panic("Unrecoverable Machine check"); } -#ifdef CONFIG_PPC32 void SMIException(struct pt_regs *regs) { die("System Management Interrupt", regs, SIGABRT); } -#endif void unknown_exception(struct pt_regs *regs) { @@ -511,12 +511,10 @@ void instruction_breakpoint_exception(struct pt_regs *regs) _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); } -#ifdef CONFIG_PPC32 void RunModeException(struct pt_regs *regs) { _exception(SIGTRAP, regs, 0, 0); } -#endif void __kprobes single_step_exception(struct pt_regs *regs) { @@ -542,7 +540,6 @@ static void emulate_single_step(struct pt_regs *regs) if (single_stepping(regs)) { clear_single_step(regs); _exception(SIGTRAP, regs, TRAP_TRACE, 0); - single_step_exception(regs); } } @@ -587,6 +584,7 @@ static void parse_fpe(struct pt_regs *regs) * There are a couple of ways to do this, either "decode" the instruction * or directly match lots of bits. In this case, matching lots of * bits is faster and easier. + * */ #define INST_MFSPR_PVR 0x7c1f42a6 #define INST_MFSPR_PVR_MASK 0xfc1fffff @@ -597,8 +595,6 @@ static void parse_fpe(struct pt_regs *regs) #define INST_MCRXR 0x7c000400 #define INST_MCRXR_MASK 0x7c0007fe -#ifdef CONFIG_PPC32 - #define INST_STRING 0x7c00042a #define INST_STRING_MASK 0x7c0007fe #define INST_STRING_GEN_MASK 0x7c00067e @@ -674,7 +670,6 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) return 0; } -#endif /* CONFIG_PPC32 */ static int emulate_instruction(struct pt_regs *regs) { @@ -701,28 +696,17 @@ static int emulate_instruction(struct pt_regs *regs) /* Emulate the mcrxr insn. */ if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { - unsigned int shift = (instword >> 21) & 0x1c; + int shift = (instword >> 21) & 0x1c; unsigned long msk = 0xf0000000UL >> shift; -#ifdef CONFIG_PPC64 - static int warned; - if (!warned) { - printk(KERN_WARNING - "process %d (%s) uses obsolete 'mcrxr' insn\n", - current->pid, current->comm); - warned = 1; - } -#endif regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); regs->xer &= ~0xf0000000UL; return 0; } -#ifdef CONFIG_PPC32 /* Emulate load/store string insn. */ if ((instword & INST_STRING_GEN_MASK) == INST_STRING) return emulate_string_inst(regs, instword); -#endif return -EINVAL; } @@ -769,22 +753,18 @@ static int check_bug_trap(struct pt_regs *regs) xmon_printf(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, bug->line & ~BUG_WARNING_TRAP); -#endif +#endif /* CONFIG_XMON */ printk(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, bug->line & ~BUG_WARNING_TRAP); -#ifdef CONFIG_PPC32 dump_stack(); -#else - show_stack(current, (void *)regs->gpr[1]); -#endif return 1; } -#if defined(CONFIG_PPC32) && defined(CONFIG_XMON) +#ifdef CONFIG_XMON xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n", bug->function, bug->file, bug->line); xmon(regs); -#endif +#endif /* CONFIG_XMON */ printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", bug->function, bug->file, bug->line); @@ -873,7 +853,6 @@ void alignment_exception(struct pt_regs *regs) _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } -#ifdef CONFIG_PPC32 void StackOverflow(struct pt_regs *regs) { printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", @@ -897,7 +876,6 @@ void trace_syscall(struct pt_regs *regs) current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); } -#endif /* CONFIG_PPC32 */ void kernel_fp_unavailable_exception(struct pt_regs *regs) { @@ -963,7 +941,6 @@ void SoftwareEmulation(struct pt_regs *regs) } #endif /* CONFIG_8xx */ -#ifdef CONFIG_PPC32 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) void DebugException(struct pt_regs *regs, unsigned long debug_status) @@ -992,7 +969,6 @@ void TAUException(struct pt_regs *regs) regs->nip, regs->msr, regs->trap, print_tainted()); } #endif /* CONFIG_INT_TAU */ -#endif /* CONFIG_PPC32*/ #ifdef CONFIG_ALTIVEC void altivec_assist_exception(struct pt_regs *regs) From 4a2885630bc0735e573bced7001dae9750cb80d5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:38:46 +1000 Subject: [PATCH 0242/1940] powerpc: Reduce the 32/64-bit diffs in vmlinux.lds.S Also adds the definition of the _sdata symbol to the ppc64 vmlinux.lds.S. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/vmlinux.lds.S | 74 ++++--------------------------- arch/ppc64/kernel/vmlinux.lds.S | 1 + 2 files changed, 10 insertions(+), 65 deletions(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index d0239bf8d4cc..d4dfcfbce272 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -1,6 +1,8 @@ #include #ifdef CONFIG_PPC64 #include +#else +#define PAGE_SIZE 4096 #endif #include @@ -16,9 +18,7 @@ SECTIONS /* Sections to be discarded. */ /DISCARD/ : { *(.exitcall.exit) -#ifdef CONFIG_PPC32 *(.exit.data) -#endif } @@ -49,16 +49,10 @@ SECTIONS .plt : { *(.plt) } #endif .text : { -#ifdef CONFIG_PPC64 *(.text .text.*) -#else - *(.text) -#endif SCHED_TEXT LOCK_TEXT -#ifdef CONFIG_PPC64 KPROBES_TEXT -#endif *(.fixup) #ifdef CONFIG_PPC32 *(.got1) @@ -106,7 +100,7 @@ SECTIONS #ifdef CONFIG_PPC32 /* Read-write section, merged into data segment: */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _sdata = .; .data : { @@ -119,10 +113,10 @@ SECTIONS CONSTRUCTORS } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __nosave_begin = .; .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __nosave_end = .; . = ALIGN(32); @@ -133,12 +127,10 @@ SECTIONS . = ALIGN(8192); .data.init_task : { *(.data.init_task) } +#endif - . = ALIGN(4096); -#else /* will be freed after init */ . = ALIGN(PAGE_SIZE); -#endif __init_begin = .; .init.text : { _sinittext = .; @@ -151,9 +143,6 @@ SECTIONS .exit.text : { *(.exit.text) } #endif .init.data : { -#ifdef CONFIG_PPC64 - *(.init.data) -#else *(.init.data); __vtop_table_begin = .; *(.vtop_fixup); @@ -161,31 +150,17 @@ SECTIONS __ptov_table_begin = .; *(.ptov_fixup); __ptov_table_end = .; -#endif } . = ALIGN(16); -#ifdef CONFIG_PPC32 - __setup_start = .; -#endif .init.setup : { -#ifdef CONFIG_PPC64 __setup_start = .; -#endif *(.init.setup) -#ifdef CONFIG_PPC64 __setup_end = .; -#endif } -#ifdef CONFIG_PPC32 - __setup_end = .; - __initcall_start = .; -#endif .initcall.init : { -#ifdef CONFIG_PPC64 __initcall_start = .; -#endif *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) @@ -193,27 +168,14 @@ SECTIONS *(.initcall5.init) *(.initcall6.init) *(.initcall7.init) -#ifdef CONFIG_PPC64 __initcall_end = .; -#endif } -#ifdef CONFIG_PPC32 - __initcall_end = .; - __con_initcall_start = .; -#endif .con_initcall.init : { -#ifdef CONFIG_PPC64 __con_initcall_start = .; -#endif *(.con_initcall.init) -#ifdef CONFIG_PPC64 __con_initcall_end = .; -#endif } -#ifdef CONFIG_PPC32 - __con_initcall_end = .; -#endif SECURITY_INIT @@ -232,31 +194,23 @@ SECTIONS #ifdef CONFIG_PPC32 . = ALIGN(32); - __per_cpu_start = .; #endif .data.percpu : { -#ifdef CONFIG_PPC64 __per_cpu_start = .; -#endif *(.data.percpu) -#ifdef CONFIG_PPC64 __per_cpu_end = .; -#endif } -#ifdef CONFIG_PPC32 - __per_cpu_end = .; -#endif -#ifdef CONFIG_PPC64 . = ALIGN(PAGE_SIZE); +#ifdef CONFIG_PPC64 . = ALIGN(16384); __init_end = .; /* freed after init ends here */ - /* Read/write sections */ . = ALIGN(PAGE_SIZE); . = ALIGN(16384); + _sdata = .; /* The initial task and kernel stack */ .data.init_task : { *(.data.init_task) @@ -288,10 +242,8 @@ SECTIONS _edata = .; } - . = ALIGN(PAGE_SIZE); #else - . = ALIGN(4096); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) @@ -307,23 +259,15 @@ SECTIONS __bss_start = .; #endif + .bss : { -#ifdef CONFIG_PPC64 __bss_start = .; -#else *(.sbss) *(.scommon) *(.dynbss) -#endif *(.bss) -#ifdef CONFIG_PPC32 *(COMMON) -#else __bss_stop = .; -#endif } -#ifdef CONFIG_PPC32 - __bss_stop = .; -#endif #ifdef CONFIG_PPC64 . = ALIGN(PAGE_SIZE); diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S index f34d514432ac..022f220e772f 100644 --- a/arch/ppc64/kernel/vmlinux.lds.S +++ b/arch/ppc64/kernel/vmlinux.lds.S @@ -106,6 +106,7 @@ SECTIONS /* Read/write sections */ . = ALIGN(PAGE_SIZE); . = ALIGN(16384); + _sdata = .; /* The initial task and kernel stack */ .data.init_task : { *(.data.init_task) From 5a408329ed19cf2a80e831d28cbd93d2e36155a6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:41:25 +1000 Subject: [PATCH 0243/1940] powerpc: Fix bug caused by negation of 64-bit reloc_offset value Although both ppc32 and ppc64 have a reloc_offset function, the ppc64 one produced the opposite sign to the ppc32 one. This standardizes on the ppc32 sign and fixes the merged 64-bit code to account for that. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head_64.S | 20 ++++++++++---------- arch/powerpc/kernel/prom_init.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 7889ff8473b9..3fcac3c37b9b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1385,7 +1385,7 @@ _STATIC(__boot_from_prom) addi r2,r2,0x4000 /* Relocate the TOC from a virt addr to a real addr */ - sub r2,r2,r3 + add r2,r2,r3 /* Restore parameters */ mr r3,r31 @@ -1424,7 +1424,7 @@ _STATIC(__after_prom_start) li r3,0 /* target addr */ // XXX FIXME: Use phys returned by OF (r30) - sub r4,r27,r26 /* source addr */ + add r4,r27,r26 /* source addr */ /* current address of _start */ /* i.e. where we are running */ /* the source addr */ @@ -1444,7 +1444,7 @@ _STATIC(__after_prom_start) bctr 4: LOADADDR(r5,klimit) - sub r5,r5,r26 + add r5,r5,r26 ld r5,0(r5) /* get the value of klimit */ sub r5,r5,r27 bl .copy_and_flush /* copy the rest */ @@ -1703,7 +1703,7 @@ _STATIC(start_here_multiplatform) /* kernel but are still running in real mode. */ LOADADDR(r3,init_thread_union) - sub r3,r3,r26 + add r3,r3,r26 /* set up a stack pointer (physical address) */ addi r1,r3,THREAD_SIZE @@ -1714,12 +1714,12 @@ _STATIC(start_here_multiplatform) LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 - sub r2,r2,r26 + add r2,r2,r26 LOADADDR(r3,cpu_specs) - sub r3,r3,r26 + add r3,r3,r26 LOADADDR(r4,cur_cpu_spec) - sub r4,r4,r26 + add r4,r4,r26 mr r5,r26 bl .identify_cpu @@ -1735,13 +1735,13 @@ _STATIC(start_here_multiplatform) * code */ LOADADDR(r27, boot_cpuid) - sub r27,r27,r26 + add r27,r27,r26 lwz r27,0(r27) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ - sub r13,r13,r26 /* convert to physical addr */ + add r13,r13,r26 /* convert to physical addr */ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, @@ -1781,7 +1781,7 @@ _STATIC(start_here_multiplatform) andi. r3,r3,PLATFORM_LPAR bne 98f /* branch if result is !0 */ LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ - sub r6,r6,r26 + add r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ mtspr SPRN_SDR1,r6 /* set the htab location */ 98: diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 75b487f107c3..75dc7f3714bd 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2019,7 +2019,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, * On pSeries and BPA, copy the CPU hold code */ if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) - copy_and_flush(0, KERNELBASE - offset, 0x100, 0); + copy_and_flush(0, KERNELBASE + offset, 0x100, 0); #endif /* From bc6f8a4b199156897f6eb5b70bf5c1a4773f4e2b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:45:07 +1000 Subject: [PATCH 0244/1940] powerpc: move lparmap.c to arch/powerpc/kernel Since lparmap.s gets included in arch/powerpc/kernel/head_64.S, this avoids depending on a file in another directory. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 5 +++-- arch/powerpc/{platforms/iseries => kernel}/lparmap.c | 0 arch/ppc64/kernel/Makefile | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) rename arch/powerpc/{platforms/iseries => kernel}/lparmap.c (100%) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0625470a6235..bc063edd6de0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_BOOTX_TEXT) += btext.o ifeq ($(CONFIG_PPC_ISERIES),y) -arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s -AFLAGS_head_64.o += -Iarch/powerpc/platforms/iseries +$(obj)/head_64.o: $(obj)/lparmap.s +AFLAGS_head_64.o += -I$(obj) +endif endif diff --git a/arch/powerpc/platforms/iseries/lparmap.c b/arch/powerpc/kernel/lparmap.c similarity index 100% rename from arch/powerpc/platforms/iseries/lparmap.c rename to arch/powerpc/kernel/lparmap.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 6a0fea272386..79366e4a9e5c 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -70,7 +70,7 @@ CFLAGS_ioctl32.o += -Ifs/ ifneq ($(CONFIG_PPC_MERGE),y) ifeq ($(CONFIG_PPC_ISERIES),y) -arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s -AFLAGS_head.o += -Iarch/powerpc/platforms/iseries +arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s +AFLAGS_head.o += -Iarch/powerpc/kernel endif endif From 40ef8cbc6d360e564573eb19582249c35d8ba330 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:50:37 +1000 Subject: [PATCH 0245/1940] powerpc: Get 64-bit configs to compile with ARCH=powerpc This is a bunch of mostly small fixes that are needed to get ARCH=powerpc to compile for 64-bit. This adds setup_64.c from arch/ppc64/kernel/setup.c and locks.c from arch/ppc64/lib/locks.c. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 15 +- arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/btext.c | 3 +- arch/powerpc/kernel/head_64.S | 1 + arch/powerpc/kernel/ppc_ksyms.c | 103 +-- arch/powerpc/kernel/prom.c | 6 +- arch/powerpc/kernel/setup_64.c | 1324 +++++++++++++++++++++++++++++ arch/powerpc/lib/Makefile | 4 + arch/powerpc/lib/locks.c | 95 +++ arch/ppc64/Kconfig | 3 + arch/ppc64/kernel/Makefile | 64 +- arch/ppc64/kernel/asm-offsets.c | 1 + arch/ppc64/kernel/bpa_iommu.c | 2 +- arch/ppc64/kernel/bpa_setup.c | 1 + arch/ppc64/kernel/maple_setup.c | 1 + arch/ppc64/kernel/pmac_setup.c | 1 + include/asm-powerpc/hardirq.h | 3 + include/asm-powerpc/hw_irq.h | 1 - include/asm-powerpc/ppc_asm.h | 92 +- include/asm-powerpc/prom.h | 3 + include/asm-powerpc/system.h | 3 + include/asm-ppc64/pci-bridge.h | 10 + 22 files changed, 1632 insertions(+), 105 deletions(-) create mode 100644 arch/powerpc/kernel/setup_64.c create mode 100644 arch/powerpc/lib/locks.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index bc063edd6de0..47a8eb6e7e39 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,6 +10,12 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif +obj-y := semaphore.o traps.o +obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o +obj-$(CONFIG_POWER4) += idle_power4.o + +ifeq ($(CONFIG_PPC_MERGE),y) + extra-$(CONFIG_PPC_STD_MMU) := head_32.o extra-$(CONFIG_PPC64) := head_64.o extra-$(CONFIG_40x) := head_4xx.o @@ -21,15 +27,12 @@ extra-$(CONFIG_PPC64) += entry_64.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y += traps.o prom.o semaphore.o +obj-y += process.o init_task.o \ + prom.o systbl.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o -obj-$(CONFIG_PPC64) += idle_power4.o -obj-$(CONFIG_PPC64) += misc_64.o -ifeq ($(CONFIG_PPC32),y) +obj-$(CONFIG_PPC64) += setup_64.o misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o obj-$(CONFIG_MODULES) += ppc_ksyms.o -endif -obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_BOOTX_TEXT) += btext.o ifeq ($(CONFIG_PPC_ISERIES),y) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 3a247c033e8b..ddf0c81e1958 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -111,6 +111,7 @@ int main(void) DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); + DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); /* paca */ DEFINE(PACA_SIZE, sizeof(struct paca_struct)); diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 44f5d98e27c0..bdfba92b2b38 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -50,7 +50,7 @@ static unsigned char vga_font[cmapsz]; int boot_text_mapped; int force_printk_to_btext = 0; - +#ifdef CONFIG_PPC32 /* Calc BAT values for mapping the display and store them * in disp_BAT. Those values are then used from head.S to map * the display during identify_machine() and MMU_Init() @@ -93,6 +93,7 @@ btext_prepare_BAT(void) } logicalDisplayBase = (void *) (vaddr + lowbits); } +#endif /* This function will enable the early boot text when doing OF booting. This * way, xmon output should work too diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 3fcac3c37b9b..a4ceb9ae20fc 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -746,6 +746,7 @@ bad_stack: * any task or sent any task a signal, you should use * ret_from_except or ret_from_except_lite instead of this. */ + .globl fast_exception_return fast_exception_return: ld r12,_MSR(r1) ld r11,_NIP(r1) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 91a562e3257b..010554e5fe48 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -51,6 +51,7 @@ #include #endif +#ifdef CONFIG_PPC32 extern void transfer_to_handler(void); extern void do_IRQ(struct pt_regs *regs); extern void machine_check_exception(struct pt_regs *regs); @@ -61,14 +62,12 @@ extern int do_signal(sigset_t *, struct pt_regs *); extern int pmac_newworld; extern int sys_sigreturn(struct pt_regs *regs); -long long __ashrdi3(long long, int); -long long __ashldi3(long long, int); -long long __lshrdi3(long long, int); - -extern unsigned long mm_ptov (unsigned long paddr); - EXPORT_SYMBOL(clear_pages); -EXPORT_SYMBOL(clear_user_page); +EXPORT_SYMBOL(ISA_DMA_THRESHOLD); +EXPORT_SYMBOL(DMA_MODE_READ); +EXPORT_SYMBOL(DMA_MODE_WRITE); +EXPORT_SYMBOL(__div64_32); + EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); @@ -77,12 +76,8 @@ EXPORT_SYMBOL(alignment_exception); EXPORT_SYMBOL(program_check_exception); EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); -EXPORT_SYMBOL(ppc_n_lost_interrupts); -EXPORT_SYMBOL(ppc_lost_interrupts); +#endif -EXPORT_SYMBOL(ISA_DMA_THRESHOLD); -EXPORT_SYMBOL(DMA_MODE_READ); -EXPORT_SYMBOL(DMA_MODE_WRITE); #if defined(CONFIG_PPC_PREP) EXPORT_SYMBOL(_prep_type); EXPORT_SYMBOL(ucSystemType); @@ -110,7 +105,6 @@ EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strcasecmp); -EXPORT_SYMBOL(__div64_32); EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); @@ -132,21 +126,21 @@ EXPORT_SYMBOL(_insw_ns); EXPORT_SYMBOL(_outsw_ns); EXPORT_SYMBOL(_insl_ns); EXPORT_SYMBOL(_outsl_ns); -EXPORT_SYMBOL(iopa); -EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(ioremap); #ifdef CONFIG_44x EXPORT_SYMBOL(ioremap64); #endif EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); +#ifdef CONFIG_PPC32 EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ +#endif -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) EXPORT_SYMBOL(ppc_ide_md); #endif -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_PPC32) EXPORT_SYMBOL(isa_io_base); EXPORT_SYMBOL(isa_mem_base); EXPORT_SYMBOL(pci_dram_offset); @@ -168,31 +162,31 @@ EXPORT_SYMBOL(flush_dcache_all); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(flush_instruction_cache); EXPORT_SYMBOL(giveup_fpu); -#ifdef CONFIG_PPC64 -EXPORT_SYMBOL(__flush_icache_range); -#else -EXPORT_SYMBOL(flush_icache_range); -#endif -EXPORT_SYMBOL(flush_dcache_range); -EXPORT_SYMBOL(flush_icache_user_range); -EXPORT_SYMBOL(flush_dcache_page); -EXPORT_SYMBOL(flush_tlb_kernel_range); -EXPORT_SYMBOL(flush_tlb_page); -EXPORT_SYMBOL(_tlbie); #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SPE EXPORT_SYMBOL(giveup_spe); #endif /* CONFIG_SPE */ + +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(__flush_icache_range); +#else +EXPORT_SYMBOL(flush_instruction_cache); +EXPORT_SYMBOL(flush_icache_range); +EXPORT_SYMBOL(flush_tlb_kernel_range); +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(_tlbie); +#endif +EXPORT_SYMBOL(flush_dcache_range); + #ifdef CONFIG_SMP EXPORT_SYMBOL(smp_call_function); +#ifdef CONFIG_PPC32 EXPORT_SYMBOL(smp_hw_index); #endif - -EXPORT_SYMBOL(ppc_md); +#endif #ifdef CONFIG_ADB EXPORT_SYMBOL(adb_request); @@ -205,25 +199,27 @@ EXPORT_SYMBOL(adb_try_handler_change); EXPORT_SYMBOL(cuda_request); EXPORT_SYMBOL(cuda_poll); #endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_PPC_MULTIPLATFORM +#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32) EXPORT_SYMBOL(_machine); #endif #ifdef CONFIG_PPC_PMAC EXPORT_SYMBOL(sys_ctrler); -EXPORT_SYMBOL(pmac_newworld); #endif #ifdef CONFIG_VT EXPORT_SYMBOL(kd_mksound); #endif EXPORT_SYMBOL(to_tm); -EXPORT_SYMBOL(pm_power_off); - +#ifdef CONFIG_PPC32 +long long __ashrdi3(long long, int); +long long __ashldi3(long long, int); +long long __lshrdi3(long long, int); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); +#endif + EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(cacheable_memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memscan); @@ -234,17 +230,14 @@ EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(screen_info); #endif +#ifdef CONFIG_PPC32 +EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(tb_ticks_per_jiffy); -EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(console_drivers); - -#ifdef CONFIG_PPC_ISERIES -EXPORT_SYMBOL(local_irq_disable); -EXPORT_SYMBOL(local_irq_enable); -EXPORT_SYMBOL(local_get_flags); +EXPORT_SYMBOL(cacheable_memcpy); #endif #ifdef CONFIG_XMON @@ -255,22 +248,6 @@ EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); -#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) -extern void (*debugger)(struct pt_regs *regs); -extern int (*debugger_bpt)(struct pt_regs *regs); -extern int (*debugger_sstep)(struct pt_regs *regs); -extern int (*debugger_iabr_match)(struct pt_regs *regs); -extern int (*debugger_dabr_match)(struct pt_regs *regs); -extern void (*debugger_fault_handler)(struct pt_regs *regs); - -EXPORT_SYMBOL(debugger); -EXPORT_SYMBOL(debugger_bpt); -EXPORT_SYMBOL(debugger_sstep); -EXPORT_SYMBOL(debugger_iabr_match); -EXPORT_SYMBOL(debugger_dabr_match); -EXPORT_SYMBOL(debugger_fault_handler); -#endif - #ifdef CONFIG_8xx EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); @@ -280,22 +257,24 @@ EXPORT_SYMBOL(cpm_free_handler); EXPORT_SYMBOL(__res); #endif +#ifdef CONFIG_PPC32 EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); -EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */ EXPORT_SYMBOL(disarm_decr); -#ifdef CONFIG_PPC_STD_MMU +#endif + +#ifdef CONFIG_PPC_STD_MMU_32 extern long mol_trampoline; EXPORT_SYMBOL(mol_trampoline); /* For MOL */ EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ +EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */ #ifdef CONFIG_SMP extern int mmu_hash_lock; EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ #endif /* CONFIG_SMP */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); -#endif /* CONFIG_PPC_STD_MMU */ -EXPORT_SYMBOL(cur_cpu_spec); +#endif /* CONFIG_PPC_STD_MMU_32 */ #ifdef CONFIG_PPC_PMAC extern unsigned long agp_special_page; EXPORT_SYMBOL(agp_special_page); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index dc3d24ea3bff..ce0dff1caa80 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -47,6 +47,10 @@ #include #include #include +#include +#ifdef CONFIG_PPC64 +#include +#endif #ifdef DEBUG #define DBG(fmt...) printk(KERN_ERR fmt) @@ -1072,7 +1076,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, } else { /* Check if it's the boot-cpu, set it's hw index in paca now */ if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { - u32 *prop = get_flat_dt_prop(node, "reg", NULL); + prop = get_flat_dt_prop(node, "reg", NULL); set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); boot_cpuid_phys = get_hard_smp_processor_id(0); } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c new file mode 100644 index 000000000000..212b00823f82 --- /dev/null +++ b/arch/powerpc/kernel/setup_64.c @@ -0,0 +1,1324 @@ +/* + * + * Common boot and setup code. + * + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) +#endif + +/* + * Here are some early debugging facilities. You can enable one + * but your kernel will not boot on anything else if you do so + */ + +/* This one is for use on LPAR machines that support an HVC console + * on vterm 0 + */ +extern void udbg_init_debug_lpar(void); +/* This one is for use on Apple G5 machines + */ +extern void udbg_init_pmac_realmode(void); +/* That's RTAS panel debug */ +extern void call_rtas_display_status_delay(unsigned char c); +/* Here's maple real mode debug */ +extern void udbg_init_maple_realmode(void); + +#define EARLY_DEBUG_INIT() do {} while(0) + +#if 0 +#define EARLY_DEBUG_INIT() udbg_init_debug_lpar() +#define EARLY_DEBUG_INIT() udbg_init_maple_realmode() +#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode() +#define EARLY_DEBUG_INIT() \ + do { udbg_putc = call_rtas_display_status_delay; } while(0) +#endif + +/* extern void *stab; */ +extern unsigned long klimit; + +extern void mm_init_ppc64(void); +extern void stab_initialize(unsigned long stab); +extern void htab_initialize(void); +extern void early_init_devtree(void *flat_dt); +extern void unflatten_device_tree(void); + +extern void smp_release_cpus(void); + +int have_of = 1; +int boot_cpuid = 0; +int boot_cpuid_phys = 0; +dev_t boot_dev; +u64 ppc64_pft_size; + +struct ppc64_caches ppc64_caches; +EXPORT_SYMBOL_GPL(ppc64_caches); + +/* + * These are used in binfmt_elf.c to put aux entries on the stack + * for each elf executable being started. + */ +int dcache_bsize; +int icache_bsize; +int ucache_bsize; + +/* The main machine-dep calls structure + */ +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY; +#endif /* CONFIG_MAGIC_SYSRQ */ + + +static int ppc64_panic_event(struct notifier_block *, unsigned long, void *); +static struct notifier_block ppc64_panic_block = { + .notifier_call = ppc64_panic_event, + .priority = INT_MIN /* may not return; must be done last */ +}; + +/* + * Perhaps we can put the pmac screen_info[] here + * on pmac as well so we don't need the ifdef's. + * Until we get multiple-console support in here + * that is. -- Cort + * Maybe tie it to serial consoles, since this is really what + * these processors use on existing boards. -- Dan + */ +struct screen_info screen_info = { + .orig_x = 0, + .orig_y = 25, + .orig_video_cols = 80, + .orig_video_lines = 25, + .orig_video_isVGA = 1, + .orig_video_points = 16 +}; + +#ifdef CONFIG_SMP + +static int smt_enabled_cmdline; + +/* Look for ibm,smt-enabled OF option */ +static void check_smt_enabled(void) +{ + struct device_node *dn; + char *smt_option; + + /* Allow the command line to overrule the OF option */ + if (smt_enabled_cmdline) + return; + + dn = of_find_node_by_path("/options"); + + if (dn) { + smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); + + if (smt_option) { + if (!strcmp(smt_option, "on")) + smt_enabled_at_boot = 1; + else if (!strcmp(smt_option, "off")) + smt_enabled_at_boot = 0; + } + } +} + +/* Look for smt-enabled= cmdline option */ +static int __init early_smt_enabled(char *p) +{ + smt_enabled_cmdline = 1; + + if (!p) + return 0; + + if (!strcmp(p, "on") || !strcmp(p, "1")) + smt_enabled_at_boot = 1; + else if (!strcmp(p, "off") || !strcmp(p, "0")) + smt_enabled_at_boot = 0; + + return 0; +} +early_param("smt-enabled", early_smt_enabled); + +/** + * setup_cpu_maps - initialize the following cpu maps: + * cpu_possible_map + * cpu_present_map + * cpu_sibling_map + * + * Having the possible map set up early allows us to restrict allocations + * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. + * + * We do not initialize the online map here; cpus set their own bits in + * cpu_online_map as they come up. + * + * This function is valid only for Open Firmware systems. finish_device_tree + * must be called before using this. + * + * While we're here, we may as well set the "physical" cpu ids in the paca. + */ +static void __init setup_cpu_maps(void) +{ + struct device_node *dn = NULL; + int cpu = 0; + int swap_cpuid = 0; + + check_smt_enabled(); + + while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { + u32 *intserv; + int j, len = sizeof(u32), nthreads; + + intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s", + &len); + if (!intserv) + intserv = (u32 *)get_property(dn, "reg", NULL); + + nthreads = len / sizeof(u32); + + for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { + cpu_set(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, intserv[j]); + + if (intserv[j] == boot_cpuid_phys) + swap_cpuid = cpu; + cpu_set(cpu, cpu_possible_map); + cpu++; + } + } + + /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that + * boot cpu is logical 0. + */ + if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { + u32 tmp; + tmp = get_hard_smp_processor_id(0); + set_hard_smp_processor_id(0, boot_cpuid_phys); + set_hard_smp_processor_id(swap_cpuid, tmp); + } + + /* + * On pSeries LPAR, we need to know how many cpus + * could possibly be added to this partition. + */ + if (systemcfg->platform == PLATFORM_PSERIES_LPAR && + (dn = of_find_node_by_path("/rtas"))) { + int num_addr_cell, num_size_cell, maxcpus; + unsigned int *ireg; + + num_addr_cell = prom_n_addr_cells(dn); + num_size_cell = prom_n_size_cells(dn); + + ireg = (unsigned int *) + get_property(dn, "ibm,lrdr-capacity", NULL); + + if (!ireg) + goto out; + + maxcpus = ireg[num_addr_cell + num_size_cell]; + + /* Double maxcpus for processors which have SMT capability */ + if (cpu_has_feature(CPU_FTR_SMT)) + maxcpus *= 2; + + if (maxcpus > NR_CPUS) { + printk(KERN_WARNING + "Partition configured for %d cpus, " + "operating system maximum is %d.\n", + maxcpus, NR_CPUS); + maxcpus = NR_CPUS; + } else + printk(KERN_INFO "Partition configured for %d cpus.\n", + maxcpus); + + for (cpu = 0; cpu < maxcpus; cpu++) + cpu_set(cpu, cpu_possible_map); + out: + of_node_put(dn); + } + + /* + * Do the sibling map; assume only two threads per processor. + */ + for_each_cpu(cpu) { + cpu_set(cpu, cpu_sibling_map[cpu]); + if (cpu_has_feature(CPU_FTR_SMT)) + cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); + } + + systemcfg->processorCount = num_present_cpus(); +} +#endif /* CONFIG_SMP */ + +extern struct machdep_calls pSeries_md; +extern struct machdep_calls pmac_md; +extern struct machdep_calls maple_md; +extern struct machdep_calls bpa_md; +extern struct machdep_calls iseries_md; + +/* Ultimately, stuff them in an elf section like initcalls... */ +static struct machdep_calls __initdata *machines[] = { +#ifdef CONFIG_PPC_PSERIES + &pSeries_md, +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_PPC_PMAC + &pmac_md, +#endif /* CONFIG_PPC_PMAC */ +#ifdef CONFIG_PPC_MAPLE + &maple_md, +#endif /* CONFIG_PPC_MAPLE */ +#ifdef CONFIG_PPC_BPA + &bpa_md, +#endif +#ifdef CONFIG_PPC_ISERIES + &iseries_md, +#endif + NULL +}; + +/* + * Early initialization entry point. This is called by head.S + * with MMU translation disabled. We rely on the "feature" of + * the CPU that ignores the top 2 bits of the address in real + * mode so we can access kernel globals normally provided we + * only toy with things in the RMO region. From here, we do + * some early parsing of the device-tree to setup out LMB + * data structures, and allocate & initialize the hash table + * and segment tables so we can start running with translation + * enabled. + * + * It is this function which will call the probe() callback of + * the various platform types and copy the matching one to the + * global ppc_md structure. Your platform can eventually do + * some very early initializations from the probe() routine, but + * this is not recommended, be very careful as, for example, the + * device-tree is not accessible via normal means at this point. + */ + +void __init early_setup(unsigned long dt_ptr) +{ + struct paca_struct *lpaca = get_paca(); + static struct machdep_calls **mach; + + /* + * Enable early debugging if any specified (see top of + * this file) + */ + EARLY_DEBUG_INIT(); + + DBG(" -> early_setup()\n"); + + /* + * Fill the default DBG level (do we want to keep + * that old mecanism around forever ?) + */ + ppcdbg_initialize(); + + /* + * Do early initializations using the flattened device + * tree, like retreiving the physical memory map or + * calculating/retreiving the hash table size + */ + early_init_devtree(__va(dt_ptr)); + + /* + * Iterate all ppc_md structures until we find the proper + * one for the current machine type + */ + DBG("Probing machine type for platform %x...\n", + systemcfg->platform); + + for (mach = machines; *mach; mach++) { + if ((*mach)->probe(systemcfg->platform)) + break; + } + /* What can we do if we didn't find ? */ + if (*mach == NULL) { + DBG("No suitable machine found !\n"); + for (;;); + } + ppc_md = **mach; + + DBG("Found, Initializing memory management...\n"); + + /* + * Initialize stab / SLB management + */ + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + stab_initialize(lpaca->stab_real); + + /* + * Initialize the MMU Hash table and create the linear mapping + * of memory + */ + htab_initialize(); + + DBG(" <- early_setup()\n"); +} + + +/* + * Initialize some remaining members of the ppc64_caches and systemcfg structures + * (at least until we get rid of them completely). This is mostly some + * cache informations about the CPU that will be used by cache flush + * routines and/or provided to userland + */ +static void __init initialize_cache_info(void) +{ + struct device_node *np; + unsigned long num_cpus = 0; + + DBG(" -> initialize_cache_info()\n"); + + for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) { + num_cpus += 1; + + /* We're assuming *all* of the CPUs have the same + * d-cache and i-cache sizes... -Peter + */ + + if ( num_cpus == 1 ) { + u32 *sizep, *lsizep; + u32 size, lsize; + const char *dc, *ic; + + /* Then read cache informations */ + if (systemcfg->platform == PLATFORM_POWERMAC) { + dc = "d-cache-block-size"; + ic = "i-cache-block-size"; + } else { + dc = "d-cache-line-size"; + ic = "i-cache-line-size"; + } + + size = 0; + lsize = cur_cpu_spec->dcache_bsize; + sizep = (u32 *)get_property(np, "d-cache-size", NULL); + if (sizep != NULL) + size = *sizep; + lsizep = (u32 *) get_property(np, dc, NULL); + if (lsizep != NULL) + lsize = *lsizep; + if (sizep == 0 || lsizep == 0) + DBG("Argh, can't find dcache properties ! " + "sizep: %p, lsizep: %p\n", sizep, lsizep); + + systemcfg->dcache_size = ppc64_caches.dsize = size; + systemcfg->dcache_line_size = + ppc64_caches.dline_size = lsize; + ppc64_caches.log_dline_size = __ilog2(lsize); + ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; + + size = 0; + lsize = cur_cpu_spec->icache_bsize; + sizep = (u32 *)get_property(np, "i-cache-size", NULL); + if (sizep != NULL) + size = *sizep; + lsizep = (u32 *)get_property(np, ic, NULL); + if (lsizep != NULL) + lsize = *lsizep; + if (sizep == 0 || lsizep == 0) + DBG("Argh, can't find icache properties ! " + "sizep: %p, lsizep: %p\n", sizep, lsizep); + + systemcfg->icache_size = ppc64_caches.isize = size; + systemcfg->icache_line_size = + ppc64_caches.iline_size = lsize; + ppc64_caches.log_iline_size = __ilog2(lsize); + ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; + } + } + + /* Add an eye catcher and the systemcfg layout version number */ + strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); + systemcfg->version.major = SYSTEMCFG_MAJOR; + systemcfg->version.minor = SYSTEMCFG_MINOR; + systemcfg->processor = mfspr(SPRN_PVR); + + DBG(" <- initialize_cache_info()\n"); +} + +static void __init check_for_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + u64 *prop; + + DBG(" -> check_for_initrd()\n"); + + if (of_chosen) { + prop = (u64 *)get_property(of_chosen, + "linux,initrd-start", NULL); + if (prop != NULL) { + initrd_start = (unsigned long)__va(*prop); + prop = (u64 *)get_property(of_chosen, + "linux,initrd-end", NULL); + if (prop != NULL) { + initrd_end = (unsigned long)__va(*prop); + initrd_below_start_ok = 1; + } else + initrd_start = 0; + } + } + + /* If we were passed an initrd, set the ROOT_DEV properly if the values + * look sensible. If not, clear initrd reference. + */ + if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && + initrd_end > initrd_start) + ROOT_DEV = Root_RAM0; + else + initrd_start = initrd_end = 0; + + if (initrd_start) + printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); + + DBG(" <- check_for_initrd()\n"); +#endif /* CONFIG_BLK_DEV_INITRD */ +} + +/* + * Do some initial setup of the system. The parameters are those which + * were passed in from the bootloader. + */ +void __init setup_system(void) +{ + DBG(" -> setup_system()\n"); + + /* + * Unflatten the device-tree passed by prom_init or kexec + */ + unflatten_device_tree(); + + /* + * Fill the ppc64_caches & systemcfg structures with informations + * retreived from the device-tree. Need to be called before + * finish_device_tree() since the later requires some of the + * informations filled up here to properly parse the interrupt + * tree. + * It also sets up the cache line sizes which allows to call + * routines like flush_icache_range (used by the hash init + * later on). + */ + initialize_cache_info(); + +#ifdef CONFIG_PPC_RTAS + /* + * Initialize RTAS if available + */ + rtas_initialize(); +#endif /* CONFIG_PPC_RTAS */ + printk("%s:%d rtas.dev=%p (@ %p)\n", __FILE__, __LINE__, rtas.dev, + &rtas.dev); + + /* + * Check if we have an initrd provided via the device-tree + */ + check_for_initrd(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + /* + * Do some platform specific early initializations, that includes + * setting up the hash table pointers. It also sets up some interrupt-mapping + * related options that will be used by finish_device_tree() + */ + ppc_md.init_early(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + /* + * "Finish" the device-tree, that is do the actual parsing of + * some of the properties like the interrupt map + */ + finish_device_tree(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + /* + * Initialize xmon + */ +#ifdef CONFIG_XMON_DEFAULT + xmon_init(1); +#endif + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + /* + * Register early console + */ + register_early_udbg_console(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); + + parse_early_param(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + +#ifdef CONFIG_SMP + /* + * iSeries has already initialized the cpu maps at this point. + */ + setup_cpu_maps(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + /* Release secondary cpus out of their spinloops at 0x60 now that + * we can map physical -> logical CPU ids + */ + smp_release_cpus(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); +#endif + + printk("Starting Linux PPC64 %s\n", system_utsname.version); + + printk("-----------------------------------------------------\n"); + printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); + printk("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch); + printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); + printk("systemcfg = 0x%p\n", systemcfg); + printk("systemcfg->platform = 0x%x\n", systemcfg->platform); + printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); + printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); + printk("ppc64_caches.dcache_line_size = 0x%x\n", + ppc64_caches.dline_size); + printk("ppc64_caches.icache_line_size = 0x%x\n", + ppc64_caches.iline_size); + printk("htab_address = 0x%p\n", htab_address); + printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); + printk("-----------------------------------------------------\n"); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + mm_init_ppc64(); + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + DBG(" <- setup_system()\n"); +} + +/* also used by kexec */ +void machine_shutdown(void) +{ + if (ppc_md.nvram_sync) + ppc_md.nvram_sync(); +} + +void machine_restart(char *cmd) +{ + machine_shutdown(); + ppc_md.restart(cmd); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} + +void machine_power_off(void) +{ + machine_shutdown(); + ppc_md.power_off(); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} +/* Used by the G5 thermal driver */ +EXPORT_SYMBOL_GPL(machine_power_off); + +void machine_halt(void) +{ + machine_shutdown(); + ppc_md.halt(); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} + +static int ppc64_panic_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + ppc_md.panic((char *)ptr); /* May not return */ + return NOTIFY_DONE; +} + + +#ifdef CONFIG_SMP +DEFINE_PER_CPU(unsigned int, pvr); +#endif + +static int show_cpuinfo(struct seq_file *m, void *v) +{ + unsigned long cpu_id = (unsigned long)v - 1; + unsigned int pvr; + unsigned short maj; + unsigned short min; + + if (cpu_id == NR_CPUS) { + seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); + + if (ppc_md.get_cpuinfo != NULL) + ppc_md.get_cpuinfo(m); + + return 0; + } + + /* We only show online cpus: disable preempt (overzealous, I + * knew) to prevent cpu going down. */ + preempt_disable(); + if (!cpu_online(cpu_id)) { + preempt_enable(); + return 0; + } + +#ifdef CONFIG_SMP + pvr = per_cpu(pvr, cpu_id); +#else + pvr = mfspr(SPRN_PVR); +#endif + maj = (pvr >> 8) & 0xFF; + min = pvr & 0xFF; + + seq_printf(m, "processor\t: %lu\n", cpu_id); + seq_printf(m, "cpu\t\t: "); + + if (cur_cpu_spec->pvr_mask) + seq_printf(m, "%s", cur_cpu_spec->cpu_name); + else + seq_printf(m, "unknown (%08x)", pvr); + +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + seq_printf(m, ", altivec supported"); +#endif /* CONFIG_ALTIVEC */ + + seq_printf(m, "\n"); + + /* + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ + seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, + ppc_proc_freq % 1000000); + + seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min); + + preempt_enable(); + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL; +} +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} +static void c_stop(struct seq_file *m, void *v) +{ +} +struct seq_operations cpuinfo_op = { + .start =c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; + +/* + * These three variables are used to save values passed to us by prom_init() + * via the device tree. The TCE variables are needed because with a memory_limit + * in force we may need to explicitly map the TCE are at the top of RAM. + */ +unsigned long memory_limit; +unsigned long tce_alloc_start; +unsigned long tce_alloc_end; + +#ifdef CONFIG_PPC_ISERIES +/* + * On iSeries we just parse the mem=X option from the command line. + * On pSeries it's a bit more complicated, see prom_init_mem() + */ +static int __init early_parsemem(char *p) +{ + if (!p) + return 0; + + memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE); + + return 0; +} +early_param("mem", early_parsemem); +#endif /* CONFIG_PPC_ISERIES */ + +#ifdef CONFIG_PPC_MULTIPLATFORM +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout = NULL; + char *name; + u32 *spd; + int offset = 0; + + DBG(" -> set_preferred_console()\n"); + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) { + DBG(" console was specified !\n"); + return -EBUSY; + } + + if (!of_chosen) { + DBG(" of_chosen is NULL !\n"); + return -ENODEV; + } + /* We are getting a weird phandle from OF ... */ + /* ... So use the full path instead */ + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + if (name == NULL) { + DBG(" no linux,stdout-path !\n"); + return -ENODEV; + } + prom_stdout = of_find_node_by_path(name); + if (!prom_stdout) { + DBG(" can't find stdout package %s !\n", name); + return -ENODEV; + } + DBG("stdout is %s\n", prom_stdout->full_name); + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) { + DBG(" stdout package has no name !\n"); + goto not_found; + } + spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); + + if (0) + ; +#ifdef CONFIG_SERIAL_8250_CONSOLE + else if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + goto not_found; + } + } + } +#endif /* CONFIG_SERIAL_8250_CONSOLE */ +#ifdef CONFIG_PPC_PSERIES + else if (strcmp(name, "vty") == 0) { + u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); + char *compat = (char *)get_property(prom_stdout, "compatible", NULL); + + if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { + /* Host Virtual Serial Interface */ + int offset; + switch (reg[0]) { + case 0x30000000: + offset = 0; + break; + case 0x30000001: + offset = 1; + break; + default: + goto not_found; + } + of_node_put(prom_stdout); + DBG("Found hvsi console at offset %d\n", offset); + return add_preferred_console("hvsi", offset, NULL); + } else { + /* pSeries LPAR virtual console */ + of_node_put(prom_stdout); + DBG("Found hvc console\n"); + return add_preferred_console("hvc", 0, NULL); + } + } +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE + else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; +#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ + else + goto not_found; + of_node_put(prom_stdout); + + DBG("Found serial console at ttyS%d\n", offset); + + if (spd) { + static char __initdata opt[16]; + sprintf(opt, "%d", *spd); + return add_preferred_console("ttyS", offset, opt); + } else + return add_preferred_console("ttyS", offset, NULL); + + not_found: + DBG("No preferred console found !\n"); + of_node_put(prom_stdout); + return -ENODEV; +} +console_initcall(set_preferred_console); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_IRQSTACKS +static void __init irqstack_early_init(void) +{ + unsigned int i; + + /* + * interrupt stacks must be under 256MB, we cannot afford to take + * SLB misses on them. + */ + for_each_cpu(i) { + softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, + THREAD_SIZE, 0x10000000)); + hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, + THREAD_SIZE, 0x10000000)); + } +} +#else +#define irqstack_early_init() +#endif + +/* + * Stack space used when we detect a bad kernel stack pointer, and + * early in SMP boots before relocation is enabled. + */ +static void __init emergency_stack_init(void) +{ + unsigned long limit; + unsigned int i; + + /* + * Emergency stacks must be under 256MB, we cannot afford to take + * SLB misses on them. The ABI also requires them to be 128-byte + * aligned. + * + * Since we use these as temporary stacks during secondary CPU + * bringup, we need to get at them in real mode. This means they + * must also be within the RMO region. + */ + limit = min(0x10000000UL, lmb.rmo_size); + + for_each_cpu(i) + paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128, + limit)) + PAGE_SIZE; +} + +/* + * Called from setup_arch to initialize the bitmap of available + * syscalls in the systemcfg page + */ +void __init setup_syscall_map(void) +{ + unsigned int i, count64 = 0, count32 = 0; + extern unsigned long *sys_call_table; + extern unsigned long sys_ni_syscall; + + + for (i = 0; i < __NR_syscalls; i++) { + if (sys_call_table[i*2] != sys_ni_syscall) { + count64++; + systemcfg->syscall_map_64[i >> 5] |= + 0x80000000UL >> (i & 0x1f); + } + if (sys_call_table[i*2+1] != sys_ni_syscall) { + count32++; + systemcfg->syscall_map_32[i >> 5] |= + 0x80000000UL >> (i & 0x1f); + } + } + printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n", + count32, count64); +} + +/* + * Called into from start_kernel, after lock_kernel has been called. + * Initializes bootmem, which is unsed to manage page allocation until + * mem_init is called. + */ +void __init setup_arch(char **cmdline_p) +{ + extern void do_init_bootmem(void); + + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + ppc64_boot_msg(0x12, "Setup Arch"); + + *cmdline_p = cmd_line; + + /* + * Set cache line size based on type of cpu as a default. + * Systems with OF can look in the properties on the cpu node(s) + * for a possibly more accurate value. + */ + dcache_bsize = ppc64_caches.dline_size; + icache_bsize = ppc64_caches.iline_size; + + /* reboot on panic */ + panic_timeout = 180; + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + + if (ppc_md.panic) + notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); + + init_mm.start_code = PAGE_OFFSET; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = klimit; + + irqstack_early_init(); + emergency_stack_init(); + + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + stabs_alloc(); + + /* set up the bootmem stuff with available memory */ + do_init_bootmem(); + sparse_init(); + + printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); + /* initialize the syscall map in systemcfg */ + setup_syscall_map(); + + ppc_md.setup_arch(); + + /* Use the default idle loop if the platform hasn't provided one. */ + if (NULL == ppc_md.idle_loop) { + ppc_md.idle_loop = default_idle; + printk(KERN_INFO "Using default idle loop\n"); + } + + paging_init(); + ppc64_boot_msg(0x15, "Setup Done"); +} + + +/* ToDo: do something useful if ppc_md is not yet setup. */ +#define PPC64_LINUX_FUNCTION 0x0f000000 +#define PPC64_IPL_MESSAGE 0xc0000000 +#define PPC64_TERM_MESSAGE 0xb0000000 + +static void ppc64_do_msg(unsigned int src, const char *msg) +{ + if (ppc_md.progress) { + char buf[128]; + + sprintf(buf, "%08X\n", src); + ppc_md.progress(buf, 0); + snprintf(buf, 128, "%s", msg); + ppc_md.progress(buf, 0); + } +} + +/* Print a boot progress message. */ +void ppc64_boot_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); + printk("[boot]%04x %s\n", src, msg); +} + +/* Print a termination message (print only -- does not stop the kernel) */ +void ppc64_terminate_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); + printk("[terminate]%04x %s\n", src, msg); +} + +/* This should only be called on processor 0 during calibrate decr */ +void __init setup_default_decr(void) +{ + struct paca_struct *lpaca = get_paca(); + + lpaca->default_decr = tb_ticks_per_jiffy; + lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; +} + +#ifndef CONFIG_PPC_ISERIES +/* + * This function can be used by platforms to "find" legacy serial ports. + * It works for "serial" nodes under an "isa" node, and will try to + * respect the "ibm,aix-loc" property if any. It works with up to 8 + * ports. + */ + +#define MAX_LEGACY_SERIAL_PORTS 8 +static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1]; +static unsigned int old_serial_count; + +void __init generic_find_legacy_serial_ports(u64 *physport, + unsigned int *default_speed) +{ + struct device_node *np; + u32 *sizeprop; + + struct isa_reg_property { + u32 space; + u32 address; + u32 size; + }; + struct pci_reg_property { + struct pci_address addr; + u32 size_hi; + u32 size_lo; + }; + + DBG(" -> generic_find_legacy_serial_port()\n"); + + *physport = 0; + if (default_speed) + *default_speed = 0; + + np = of_find_node_by_path("/"); + if (!np) + return; + + /* First fill our array */ + for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { + struct device_node *isa, *pci; + struct isa_reg_property *reg; + unsigned long phys_size, addr_size, io_base; + u32 *rangesp; + u32 *interrupts, *clk, *spd; + char *typep; + int index, rlen, rentsize; + + /* Ok, first check if it's under an "isa" parent */ + isa = of_get_parent(np); + if (!isa || strcmp(isa->name, "isa")) { + DBG("%s: no isa parent found\n", np->full_name); + continue; + } + + /* Now look for an "ibm,aix-loc" property that gives us ordering + * if any... + */ + typep = (char *)get_property(np, "ibm,aix-loc", NULL); + + /* Get the ISA port number */ + reg = (struct isa_reg_property *)get_property(np, "reg", NULL); + if (reg == NULL) + goto next_port; + /* We assume the interrupt number isn't translated ... */ + interrupts = (u32 *)get_property(np, "interrupts", NULL); + /* get clock freq. if present */ + clk = (u32 *)get_property(np, "clock-frequency", NULL); + /* get default speed if present */ + spd = (u32 *)get_property(np, "current-speed", NULL); + /* Default to locate at end of array */ + index = old_serial_count; /* end of the array by default */ + + /* If we have a location index, then use it */ + if (typep && *typep == 'S') { + index = simple_strtol(typep+1, NULL, 0) - 1; + /* if index is out of range, use end of array instead */ + if (index >= MAX_LEGACY_SERIAL_PORTS) + index = old_serial_count; + /* if our index is still out of range, that mean that + * array is full, we could scan for a free slot but that + * make little sense to bother, just skip the port + */ + if (index >= MAX_LEGACY_SERIAL_PORTS) + goto next_port; + if (index >= old_serial_count) + old_serial_count = index + 1; + /* Check if there is a port who already claimed our slot */ + if (serial_ports[index].iobase != 0) { + /* if we still have some room, move it, else override */ + if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) { + DBG("Moved legacy port %d -> %d\n", index, + old_serial_count); + serial_ports[old_serial_count++] = + serial_ports[index]; + } else { + DBG("Replacing legacy port %d\n", index); + } + } + } + if (index >= MAX_LEGACY_SERIAL_PORTS) + goto next_port; + if (index >= old_serial_count) + old_serial_count = index + 1; + + /* Now fill the entry */ + memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port)); + serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16; + serial_ports[index].iobase = reg->address; + serial_ports[index].irq = interrupts ? interrupts[0] : 0; + serial_ports[index].flags = ASYNC_BOOT_AUTOCONF; + + DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", + index, + serial_ports[index].iobase, + serial_ports[index].irq, + serial_ports[index].uartclk); + + /* Get phys address of IO reg for port 1 */ + if (index != 0) + goto next_port; + + pci = of_get_parent(isa); + if (!pci) { + DBG("%s: no pci parent found\n", np->full_name); + goto next_port; + } + + rangesp = (u32 *)get_property(pci, "ranges", &rlen); + if (rangesp == NULL) { + of_node_put(pci); + goto next_port; + } + rlen /= 4; + + /* we need the #size-cells of the PCI bridge node itself */ + phys_size = 1; + sizeprop = (u32 *)get_property(pci, "#size-cells", NULL); + if (sizeprop != NULL) + phys_size = *sizeprop; + /* we need the parent #addr-cells */ + addr_size = prom_n_addr_cells(pci); + rentsize = 3 + addr_size + phys_size; + io_base = 0; + for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) { + if (((rangesp[0] >> 24) & 0x3) != 1) + continue; /* not IO space */ + io_base = rangesp[3]; + if (addr_size == 2) + io_base = (io_base << 32) | rangesp[4]; + } + if (io_base != 0) { + *physport = io_base + reg->address; + if (default_speed && spd) + *default_speed = *spd; + } + of_node_put(pci); + next_port: + of_node_put(isa); + } + + DBG(" <- generic_find_legacy_serial_port()\n"); +} + +static struct platform_device serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_ports, + }, +}; + +static int __init serial_dev_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(serial_dev_init); + +#endif /* CONFIG_PPC_ISERIES */ + +int check_legacy_ioport(unsigned long base_port) +{ + if (ppc_md.check_legacy_ioport == NULL) + return 0; + return ppc_md.check_legacy_ioport(base_port); +} +EXPORT_SYMBOL(check_legacy_ioport); + +#ifdef CONFIG_XMON +static int __init early_xmon(char *p) +{ + /* ensure xmon is enabled */ + if (p) { + if (strncmp(p, "on", 2) == 0) + xmon_init(1); + if (strncmp(p, "off", 3) == 0) + xmon_init(0); + if (strncmp(p, "early", 5) != 0) + return 0; + } + xmon_init(1); + debugger(NULL); + + return 0; +} +early_param("xmon", early_xmon); +#endif + +void cpu_die(void) +{ + if (ppc_md.cpu_die) + ppc_md.cpu_die(); +} diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index a8cedb96de5f..30367a0237dd 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -7,3 +7,7 @@ obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o memcpy_64.o \ usercopy_64.o sstep.o checksum_64.o mem_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o +ifeq ($(CONFIG_PPC64),y) +obj-$(CONFIG_SMP) += locks.o +endif + diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c new file mode 100644 index 000000000000..4b8c5ad5e7dc --- /dev/null +++ b/arch/powerpc/lib/locks.c @@ -0,0 +1,95 @@ +/* + * Spin and read/write lock operations. + * + * Copyright (C) 2001-2004 Paul Mackerras , IBM + * Copyright (C) 2001 Anton Blanchard , IBM + * Copyright (C) 2002 Dave Engebretsen , IBM + * Rework to support virtual processors + * + * 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. + */ + +#include +#include +#include +#include +#include + +/* waiting for a spinlock... */ +#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) +#include +#include + +void __spin_yield(raw_spinlock_t *lock) +{ + unsigned int lock_value, holder_cpu, yield_count; + struct paca_struct *holder_paca; + + lock_value = lock->slock; + if (lock_value == 0) + return; + holder_cpu = lock_value & 0xffff; + BUG_ON(holder_cpu >= NR_CPUS); + holder_paca = &paca[holder_cpu]; + yield_count = holder_paca->lppaca.yield_count; + if ((yield_count & 1) == 0) + return; /* virtual cpu is currently running */ + rmb(); + if (lock->slock != lock_value) + return; /* something has changed */ +#ifdef CONFIG_PPC_ISERIES + HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, + ((u64)holder_cpu << 32) | yield_count); +#else + plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), + yield_count); +#endif +} + +/* + * Waiting for a read lock or a write lock on a rwlock... + * This turns out to be the same for read and write locks, since + * we only know the holder if it is write-locked. + */ +void __rw_yield(raw_rwlock_t *rw) +{ + int lock_value; + unsigned int holder_cpu, yield_count; + struct paca_struct *holder_paca; + + lock_value = rw->lock; + if (lock_value >= 0) + return; /* no write lock at present */ + holder_cpu = lock_value & 0xffff; + BUG_ON(holder_cpu >= NR_CPUS); + holder_paca = &paca[holder_cpu]; + yield_count = holder_paca->lppaca.yield_count; + if ((yield_count & 1) == 0) + return; /* virtual cpu is currently running */ + rmb(); + if (rw->lock != lock_value) + return; /* something has changed */ +#ifdef CONFIG_PPC_ISERIES + HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, + ((u64)holder_cpu << 32) | yield_count); +#else + plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), + yield_count); +#endif +} +#endif + +void __raw_spin_unlock_wait(raw_spinlock_t *lock) +{ + while (lock->slock) { + HMT_low(); + if (SHARED_PROCESSOR) + __spin_yield(lock); + } + HMT_medium(); +} + +EXPORT_SYMBOL(__raw_spin_unlock_wait); diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 246212115a48..e656e02d9dd1 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -186,6 +186,9 @@ config BOOTX_TEXT Say Y here to see progress messages from the boot firmware in text mode. Requires an Open Firmware compatible video card. +config POWER4 + def_bool y + config POWER4_ONLY bool "Optimize for POWER4" default n diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 79366e4a9e5c..5c598892f891 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -2,14 +2,14 @@ # Makefile for the linux ppc64 kernel. # -EXTRA_CFLAGS += -mno-minimal-toc ifneq ($(CONFIG_PPC_MERGE),y) + +EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds -endif obj-y := setup.o entry.o irq.o idle.o dma.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ - align.o semaphore.o bitops.o pacaData.o \ + align.o bitops.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ cputable.o cpu_setup_power4.o \ @@ -43,7 +43,6 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_HVCS) += hvcserver.o -vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y) obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_MPIC) += mpic.o @@ -59,8 +58,6 @@ obj-$(CONFIG_U3_DART) += u3_iommu.o ifdef CONFIG_SMP obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o -obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o -obj-$(CONFIG_PPC_BPA) += pSeries_smp.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o endif @@ -68,9 +65,62 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ -ifneq ($(CONFIG_PPC_MERGE),y) ifeq ($(CONFIG_PPC_ISERIES),y) arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s AFLAGS_head.o += -Iarch/powerpc/kernel endif + +else + +# Things still needed from here by the merged ppc code + +obj-y := irq.o idle.o dma.o \ + time.o signal.o syscalls.o ptrace.o \ + align.o bitops.o pacaData.o \ + udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ + ptrace32.o signal32.o rtc.o \ + cputable.o cpu_setup_power4.o \ + iommu.o sysfs.o vdso.o pmc.o firmware.o +obj-y += vdso32/ vdso64/ + +pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o + +obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) + +obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o + +obj-$(CONFIG_PPC_PSERIES) += rtasd.o ras.o udbg_16550.o + +obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ + bpa_iic.o spider-pic.o + +obj-$(CONFIG_KEXEC) += machine_kexec.o +obj-$(CONFIG_EEH) += eeh.o +obj-$(CONFIG_PROC_FS) += proc_ppc64.o +obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o +obj-$(CONFIG_RTAS_PROC) += rtas-proc.o +obj-$(CONFIG_SCANLOG) += scanlog.o +obj-$(CONFIG_LPARCFG) += lparcfg.o +obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o +obj-$(CONFIG_HVCS) += hvcserver.o + +obj-$(CONFIG_IBMVIO) += vio.o +obj-$(CONFIG_XICS) += xics.o + +obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ + udbg_16550.o + +obj-$(CONFIG_U3_DART) += u3_iommu.o + +ifdef CONFIG_SMP +obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o +endif + +obj-$(CONFIG_KPROBES) += kprobes.o + +CFLAGS_ioctl32.o += -Ifs/ + endif diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index 1ff4fa05a973..1378fbbe1e57 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c @@ -77,6 +77,7 @@ int main(void) DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); + DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); /* paca */ DEFINE(PACA_SIZE, sizeof(struct paca_struct)); diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c index 0cc463f24539..45ebe5486c40 100644 --- a/arch/ppc64/kernel/bpa_iommu.c +++ b/arch/ppc64/kernel/bpa_iommu.c @@ -99,7 +99,7 @@ get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_ break; default: /* not a known compile time constant */ - BUILD_BUG_ON(1); + BUG_ON(1); break; } diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c index 9f915f4222b1..017cf23e91fa 100644 --- a/arch/ppc64/kernel/bpa_setup.c +++ b/arch/ppc64/kernel/bpa_setup.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "bpa_iic.h" #include "bpa_iommu.h" diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index 2a7fae01eee1..22987675f544 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c @@ -60,6 +60,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 497c3cd95bc3..be4c1693d149 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -73,6 +73,7 @@ #include #include #include +#include #include "pmac.h" diff --git a/include/asm-powerpc/hardirq.h b/include/asm-powerpc/hardirq.h index 2c0a31b1008d..3b3e3b49ec12 100644 --- a/include/asm-powerpc/hardirq.h +++ b/include/asm-powerpc/hardirq.h @@ -1,6 +1,9 @@ #ifndef _ASM_POWERPC_HARDIRQ_H #define _ASM_POWERPC_HARDIRQ_H +#include +#include + /* The __last_jiffy_stamp field is needed to ensure that no decrementer * interrupt is lost on SMP machines. Since on most CPUs it is in the same * cache line as local_irq_count, it is cheap to access and is also used on UP diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index 605a65e42063..c37b31b96337 100644 --- a/include/asm-powerpc/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h @@ -10,7 +10,6 @@ #include #include #include -#include extern void timer_interrupt(struct pt_regs *); extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 6cd52c130332..e4350e406d2a 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -1,10 +1,12 @@ /* * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. */ - #ifndef _ASM_POWERPC_PPC_ASM_H #define _ASM_POWERPC_PPC_ASM_H +#include +#include + #ifdef __ASSEMBLY__ /* @@ -87,6 +89,66 @@ #define RFDI .long 0x4c00004e /* rfdi instruction */ #define RFMCI .long 0x4c00004c /* rfmci instruction */ +#ifdef CONFIG_PPC64 + +#define XGLUE(a,b) a##b +#define GLUE(a,b) XGLUE(a,b) + +#define _GLOBAL(name) \ + .section ".text"; \ + .align 2 ; \ + .globl name; \ + .globl GLUE(.,name); \ + .section ".opd","aw"; \ +name: \ + .quad GLUE(.,name); \ + .quad .TOC.@tocbase; \ + .quad 0; \ + .previous; \ + .type GLUE(.,name),@function; \ +GLUE(.,name): + +#define _KPROBE(name) \ + .section ".kprobes.text","a"; \ + .align 2 ; \ + .globl name; \ + .globl GLUE(.,name); \ + .section ".opd","aw"; \ +name: \ + .quad GLUE(.,name); \ + .quad .TOC.@tocbase; \ + .quad 0; \ + .previous; \ + .type GLUE(.,name),@function; \ +GLUE(.,name): + +#define _STATIC(name) \ + .section ".text"; \ + .align 2 ; \ + .section ".opd","aw"; \ +name: \ + .quad GLUE(.,name); \ + .quad .TOC.@tocbase; \ + .quad 0; \ + .previous; \ + .type GLUE(.,name),@function; \ +GLUE(.,name): + +#else /* 32-bit */ + +#define _GLOBAL(n) \ + .text; \ + .stabs __stringify(n:F-1),N_FUN,0,0,n;\ + .globl n; \ +n: + +#define _KPROBE(n) \ + .section ".kprobes.text","a"; \ + .globl n; \ +n: + +#endif + /* * LOADADDR( rn, name ) * loads the address of 'name' into 'rn' @@ -251,31 +313,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .previous #endif -/* - * On 64-bit cpus, we use the rfid instruction instead of rfi, but - * we then have to make sure we preserve the top 32 bits except for - * the 64-bit mode bit, which we clear. - */ -#if defined(CONFIG_PPC64BRIDGE) -#define FIX_SRR1(ra, rb) \ - mr rb,ra; \ - mfmsr ra; \ - clrldi ra,ra,1; /* turn off 64-bit mode */ \ - rldimi ra,rb,0,32 -#define RFI .long 0x4c000024 /* rfid instruction */ -#define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */ -#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ -#elif defined(CONFIG_PPC64) -/* Insert the high 32 bits of the MSR into what will be the new - MSR (via SRR1 and rfid) This preserves the MSR.SF and MSR.ISF - bits. */ - -#define FIX_SRR1(ra, rb) \ - mr rb,ra; \ - mfmsr ra; \ - rldimi ra,rb,0,32 - -#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ +#ifdef CONFIG_PPC64 +#define RFI rfid +#define MTMSRD(r) mtmsrd r #else #define FIX_SRR1(ra, rb) diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 194b56ee1693..efc40980cb48 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -196,6 +196,7 @@ extern int prom_n_intr_cells(struct device_node* np); extern void prom_get_irq_senses(unsigned char *senses, int off, int max); extern void prom_add_property(struct device_node* np, struct property* prop); +#ifdef CONFIG_PPC32 /* * PCI <-> OF matching functions * (XXX should these be here?) @@ -207,6 +208,8 @@ extern int pci_device_from_OF_node(struct device_node *node, extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int); extern struct device_node* pci_device_to_OF_node(struct pci_dev *); extern void pci_create_OF_bus_map(void); +#endif + extern struct resource *request_OF_resource(struct device_node* node, int index, const char* name_postfix); extern int release_OF_resource(struct device_node* node, int index); diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 66866f7301a9..6463453b61a3 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -9,6 +9,7 @@ #include #include +#include /* * Memory barrier. @@ -127,6 +128,7 @@ extern void flush_fp_to_thread(struct task_struct *); extern void enable_kernel_altivec(void); extern void giveup_altivec(struct task_struct *); extern void load_up_altivec(struct task_struct *); +extern int emulate_altivec(struct pt_regs *); extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern int fix_alignment(struct pt_regs *); @@ -176,6 +178,7 @@ extern struct task_struct *_switch(struct thread_struct *prev, struct thread_struct *next); extern unsigned int rtas_data; +extern int mem_init_done; /* set on boot once kmalloc can be called */ /* * Atomic exchange diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 8ca5fce626bb..c342c9eb07a4 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -106,6 +106,16 @@ static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) return fetch_dev_dn(dev); } +static inline int pci_device_from_OF_node(struct device_node *np, + u8 *bus, u8 *devfn) +{ + if (!PCI_DN(np)) + return -ENODEV; + *bus = PCI_DN(np)->busno; + *devfn = PCI_DN(np)->devfn; + return 0; +} + static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) { if (bus->self) From 76f9f87fa51c9fb62c17986e2066ed467ac2da05 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:52:26 +1000 Subject: [PATCH 0246/1940] powerpc: Get iseries to compile with ARCH=powerpc This moves the Device_List member from struct device_node to struct pci_dn, which cleans up the device_node and makes the code a little simpler. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/iseries/hvcall.S | 1 + arch/powerpc/platforms/iseries/iommu.c | 7 +++---- arch/powerpc/platforms/iseries/pci.c | 15 ++++++--------- include/asm-ppc64/pci-bridge.h | 2 ++ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/platforms/iseries/hvcall.S b/arch/powerpc/platforms/iseries/hvcall.S index 9901c0ec1415..07ae6ad5f49f 100644 --- a/arch/powerpc/platforms/iseries/hvcall.S +++ b/arch/powerpc/platforms/iseries/hvcall.S @@ -10,6 +10,7 @@ #include #include +#include /* XXX for STACK_FRAME_OVERHEAD */ .text diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 9ac735d5b817..e40c50b7cefc 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -89,11 +89,10 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) */ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { - struct device_node *dp; - - list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { - struct iommu_table *it = PCI_DN(dp)->iommu_table; + struct pci_dn *pdn; + list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { + struct iommu_table *it = pdn->iommu_table; if ((it != NULL) && (it->it_type == TCE_PCI) && (it->it_offset == tbl->it_offset) && diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 70185dec940b..46879d7de925 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -220,7 +220,7 @@ static struct device_node *build_device_node(HvBusNumber Bus, return NULL; } node->data = pdn; - list_add_tail(&node->Device_List, &iSeries_Global_Device_List); + list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List); #if 0 pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); #endif @@ -549,15 +549,12 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio); */ static struct device_node *find_Device_Node(int bus, int devfn) { - struct list_head *pos; + struct pci_dn *pdn; - list_for_each(pos, &iSeries_Global_Device_List) { - struct device_node *node = - list_entry(pos, struct device_node, Device_List); - - if ((bus == ISERIES_BUS(node)) && - (devfn == PCI_DN(node)->devfn)) - return node; + list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { + if ((bus == pdn->DsaAddr.Dsa.busNumber) && + (devfn == pdn->devfn)) + return pdn->node; } return NULL; } diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index c342c9eb07a4..56863df18232 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -3,6 +3,7 @@ #define _ASM_PCI_BRIDGE_H #include +#include #include @@ -74,6 +75,7 @@ struct pci_dn { struct pci_dev *pcidev; /* back-pointer to the pci device */ struct device_node *node; /* back-pointer to the device_node */ #ifdef CONFIG_PPC_ISERIES + struct list_head Device_List; union HvDsaMap DsaAddr; /* Direct Select Address */ /* busNumber, subBusNumber, */ /* deviceId, barNumber */ From 1b92313d5ba993bb6e38a6205ccc64a7595cd0a6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:54:57 +1000 Subject: [PATCH 0247/1940] powerpc: Merge asm/irq.h Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/irq.h | 160 ++++++++++++++++++------- include/asm-ppc64/irq.h | 120 ------------------- 2 files changed, 118 insertions(+), 162 deletions(-) rename include/{asm-ppc => asm-powerpc}/irq.h (84%) delete mode 100644 include/asm-ppc64/irq.h diff --git a/include/asm-ppc/irq.h b/include/asm-powerpc/irq.h similarity index 84% rename from include/asm-ppc/irq.h rename to include/asm-powerpc/irq.h index 137ea0cf34d3..980393a16be2 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-powerpc/irq.h @@ -1,11 +1,23 @@ #ifdef __KERNEL__ -#ifndef _ASM_IRQ_H -#define _ASM_IRQ_H +#ifndef _ASM_POWERPC_IRQ_H +#define _ASM_POWERPC_IRQ_H + +/* + * 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. + */ #include -#include /* ppc_md */ +#include + +#include #include +/* this number is used when no interrupt has been assigned */ +#define NO_IRQ (-1) + /* * These constants are used for passing information about interrupt * signal polarity and level/edge sensing to the low-level PIC chip @@ -30,6 +42,44 @@ #define for_each_irq(i) \ for ((i) = 0; (i) < NR_IRQS; ++(i)) +#ifdef CONFIG_PPC64 + +/* + * Maximum number of interrupt sources that we can handle. + */ +#define NR_IRQS 512 + +/* Interrupt numbers are virtual in case they are sparsely + * distributed by the hardware. + */ +extern unsigned int virt_irq_to_real_map[NR_IRQS]; + +/* Create a mapping for a real_irq if it doesn't already exist. + * Return the virtual irq as a convenience. + */ +int virt_irq_create_mapping(unsigned int real_irq); +void virt_irq_init(void); + +static inline unsigned int virt_irq_to_real(unsigned int virt_irq) +{ + return virt_irq_to_real_map[virt_irq]; +} + +extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq); + +/* + * List of interrupt controllers. + */ +#define IC_INVALID 0 +#define IC_OPEN_PIC 1 +#define IC_PPC_XIC 2 +#define IC_BPA_IIC 3 +#define IC_ISERIES 4 + +extern u64 ppc64_interrupt_controller; + +#else /* 32-bit */ + #if defined(CONFIG_40x) #include @@ -72,11 +122,6 @@ #define NR_UIC_IRQS UIC_WIDTH #define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS) #endif -static __inline__ int -irq_canonicalize(int irq) -{ - return (irq); -} #elif defined(CONFIG_44x) #include @@ -84,12 +129,6 @@ irq_canonicalize(int irq) #define NR_UIC_IRQS 32 #define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS) -static __inline__ int -irq_canonicalize(int irq) -{ - return (irq); -} - #elif defined(CONFIG_8xx) /* Now include the board configuration specific associations. @@ -176,20 +215,9 @@ irq_canonicalize(int irq) */ #define mk_int_int_mask(IL) (1 << (7 - (IL/2))) -/* always the same on 8xx -- Cort */ -static __inline__ int irq_canonicalize(int irq) -{ - return irq; -} - #elif defined(CONFIG_83xx) #include -static __inline__ int irq_canonicalize(int irq) -{ - return irq; -} - #define NR_IRQS (NR_IPIC_INTS) #elif defined(CONFIG_85xx) @@ -313,17 +341,13 @@ static __inline__ int irq_canonicalize(int irq) #define SIU_INT_PC1 ((uint)0x3e+CPM_IRQ_OFFSET) #define SIU_INT_PC0 ((uint)0x3f+CPM_IRQ_OFFSET) -static __inline__ int irq_canonicalize(int irq) -{ - return irq; -} - #else /* CONFIG_40x + CONFIG_8xx */ /* * this is the # irq's for all ppc arch's (pmac/chrp/prep) * so it is the max of them all */ #define NR_IRQS 256 +#define __DO_IRQ_CANON 1 #ifndef CONFIG_8260 @@ -400,18 +424,6 @@ static __inline__ int irq_canonicalize(int irq) #endif /* CONFIG_8260 */ -/* - * This gets called from serial.c, which is now used on - * powermacs as well as prep/chrp boxes. - * Prep and chrp both have cascaded 8259 PICs. - */ -static __inline__ int irq_canonicalize(int irq) -{ - if (ppc_md.irq_canonicalize) - return ppc_md.irq_canonicalize(irq); - return irq; -} - #endif #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) @@ -420,5 +432,69 @@ extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; extern atomic_t ppc_n_lost_interrupts; +#endif + +/* + * Because many systems have two overlapping names spaces for + * interrupts (ISA and XICS for example), and the ISA interrupts + * have historically not been easy to renumber, we allow ISA + * interrupts to take values 0 - 15, and shift up the remaining + * interrupts by 0x10. + */ +#define NUM_ISA_INTERRUPTS 0x10 +extern int __irq_offset_value; + +static inline int irq_offset_up(int irq) +{ + return(irq + __irq_offset_value); +} + +static inline int irq_offset_down(int irq) +{ + return(irq - __irq_offset_value); +} + +static inline int irq_offset_value(void) +{ + return __irq_offset_value; +} + +#ifdef __DO_IRQ_CANON +extern int ppc_do_canonicalize_irqs; +#else +#define ppc_do_canonicalize_irqs 0 +#endif + +static __inline__ int irq_canonicalize(int irq) +{ + if (ppc_do_canonicalize_irqs && irq == 2) + irq = 9; + return irq; +} + +extern int distribute_irqs; + +struct irqaction; +struct pt_regs; + +#ifdef CONFIG_IRQSTACKS +/* + * Per-cpu stacks for handling hard and soft interrupts. + */ +extern struct thread_info *hardirq_ctx[NR_CPUS]; +extern struct thread_info *softirq_ctx[NR_CPUS]; + +extern void irq_ctx_init(void); +extern void call_do_softirq(struct thread_info *tp); +extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, + struct irqaction *action, struct thread_info *tp); + +#define __ARCH_HAS_DO_SOFTIRQ + +#else +#define irq_ctx_init() + +#endif /* CONFIG_IRQSTACKS */ + #endif /* _ASM_IRQ_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/irq.h b/include/asm-ppc64/irq.h deleted file mode 100644 index 99782afb4cde..000000000000 --- a/include/asm-ppc64/irq.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _ASM_IRQ_H -#define _ASM_IRQ_H - -/* - * 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. - */ - -#include -#include - -/* - * Maximum number of interrupt sources that we can handle. - */ -#define NR_IRQS 512 - -/* this number is used when no interrupt has been assigned */ -#define NO_IRQ (-1) - -/* - * These constants are used for passing information about interrupt - * signal polarity and level/edge sensing to the low-level PIC chip - * drivers. - */ -#define IRQ_SENSE_MASK 0x1 -#define IRQ_SENSE_LEVEL 0x1 /* interrupt on active level */ -#define IRQ_SENSE_EDGE 0x0 /* interrupt triggered by edge */ - -#define IRQ_POLARITY_MASK 0x2 -#define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */ -#define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */ - -/* - * IRQ line status macro IRQ_PER_CPU is used - */ -#define ARCH_HAS_IRQ_PER_CPU - -#define get_irq_desc(irq) (&irq_desc[(irq)]) - -/* Define a way to iterate across irqs. */ -#define for_each_irq(i) \ - for ((i) = 0; (i) < NR_IRQS; ++(i)) - -/* Interrupt numbers are virtual in case they are sparsely - * distributed by the hardware. - */ -extern unsigned int virt_irq_to_real_map[NR_IRQS]; - -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. - */ -int virt_irq_create_mapping(unsigned int real_irq); -void virt_irq_init(void); - -static inline unsigned int virt_irq_to_real(unsigned int virt_irq) -{ - return virt_irq_to_real_map[virt_irq]; -} - -extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq); - -/* - * Because many systems have two overlapping names spaces for - * interrupts (ISA and XICS for example), and the ISA interrupts - * have historically not been easy to renumber, we allow ISA - * interrupts to take values 0 - 15, and shift up the remaining - * interrupts by 0x10. - */ -#define NUM_ISA_INTERRUPTS 0x10 -extern int __irq_offset_value; - -static inline int irq_offset_up(int irq) -{ - return(irq + __irq_offset_value); -} - -static inline int irq_offset_down(int irq) -{ - return(irq - __irq_offset_value); -} - -static inline int irq_offset_value(void) -{ - return __irq_offset_value; -} - -static __inline__ int irq_canonicalize(int irq) -{ - return irq; -} - -extern int distribute_irqs; - -struct irqaction; -struct pt_regs; - -#ifdef CONFIG_IRQSTACKS -/* - * Per-cpu stacks for handling hard and soft interrupts. - */ -extern struct thread_info *hardirq_ctx[NR_CPUS]; -extern struct thread_info *softirq_ctx[NR_CPUS]; - -extern void irq_ctx_init(void); -extern void call_do_softirq(struct thread_info *tp); -extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, - struct irqaction *action, struct thread_info *tp); - -#define __ARCH_HAS_DO_SOFTIRQ - -#else -#define irq_ctx_init() - -#endif /* CONFIG_IRQSTACKS */ - -#endif /* _ASM_IRQ_H */ -#endif /* __KERNEL__ */ From eef289f79c03ba5ca197e2ac1e33906175f01c39 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:56:11 +1000 Subject: [PATCH 0248/1940] powerpc: Merge asm/unistd.h Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/unistd.h | 91 ++-- include/asm-ppc64/unistd.h | 487 ---------------------- 2 files changed, 54 insertions(+), 524 deletions(-) rename include/{asm-ppc => asm-powerpc}/unistd.h (90%) delete mode 100644 include/asm-ppc64/unistd.h diff --git a/include/asm-ppc/unistd.h b/include/asm-powerpc/unistd.h similarity index 90% rename from include/asm-ppc/unistd.h rename to include/asm-powerpc/unistd.h index 3173ab3d2eb9..c2d039e338a8 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -3,7 +3,13 @@ /* * This file contains the system call numbers. + * + * 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. */ + #define __NR_restart_syscall 0 #define __NR_exit 1 #define __NR_fork 2 @@ -196,19 +202,23 @@ #define __NR_vfork 189 #define __NR_ugetrlimit 190 /* SuS compliant getrlimit */ #define __NR_readahead 191 +#ifndef __powerpc64__ /* these are 32-bit only */ #define __NR_mmap2 192 #define __NR_truncate64 193 #define __NR_ftruncate64 194 #define __NR_stat64 195 #define __NR_lstat64 196 #define __NR_fstat64 197 +#endif #define __NR_pciconfig_read 198 #define __NR_pciconfig_write 199 #define __NR_pciconfig_iobase 200 #define __NR_multiplexer 201 #define __NR_getdents64 202 #define __NR_pivot_root 203 +#ifndef __powerpc64__ #define __NR_fcntl64 204 +#endif #define __NR_madvise 205 #define __NR_mincore 206 #define __NR_gettid 207 @@ -230,7 +240,9 @@ #define __NR_sched_getaffinity 223 /* 224 currently unused */ #define __NR_tuxcall 225 +#ifndef __powerpc64__ #define __NR_sendfile64 226 +#endif #define __NR_io_setup 227 #define __NR_io_destroy 228 #define __NR_io_getevents 229 @@ -258,14 +270,16 @@ #define __NR_utimes 251 #define __NR_statfs64 252 #define __NR_fstatfs64 253 +#ifndef __powerpc64__ #define __NR_fadvise64_64 254 +#endif #define __NR_rtas 255 #define __NR_sys_debug_setcontext 256 /* Number 257 is reserved for vserver */ /* 258 currently unused */ -/* Number 259 is reserved for new sys_mbind */ -/* Number 260 is reserved for new sys_get_mempolicy */ -/* Number 261 is reserved for new sys_set_mempolicy */ +#define __NR_mbind 259 +#define __NR_get_mempolicy 260 +#define __NR_set_mempolicy 261 #define __NR_mq_open 262 #define __NR_mq_unlink 263 #define __NR_mq_timedsend 264 @@ -285,7 +299,12 @@ #define __NR_syscalls 278 -#define __NR(n) #n +#ifdef __KERNEL__ +#define __NR__exit __NR_exit +#define NR_syscalls __NR_syscalls +#endif + +#ifndef __ASSEMBLY__ /* On powerpc a system call basically clobbers the same registers like a * function call, with the exception of LR (which is needed for the @@ -389,7 +408,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ { \ __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \ } - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ { \ @@ -398,12 +416,13 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 #ifdef __KERNEL__ -#define __NR__exit __NR_exit -#define NR_syscalls __NR_syscalls +#include +#include +#include +#include #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME @@ -423,23 +442,17 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION - -/* - * Forking from kernel space will result in the child getting a new, - * empty kernel stack area. Thus the child cannot access automatic - * variables set in the parent unless they are in registers, and the - * procedure where the fork was done cannot return to its caller in - * the child. - */ - -#ifdef __KERNEL_SYSCALLS__ - -#include -#include +#ifdef CONFIG_PPC32 +#define __ARCH_WANT_OLD_STAT +#endif +#ifdef CONFIG_PPC64 +#define __ARCH_WANT_COMPAT_SYS_TIME +#endif /* * System call prototypes. */ +#ifdef __KERNEL_SYSCALLS__ extern pid_t setsid(void); extern int write(int fd, const char *buf, off_t count); extern int read(int fd, char *buf, off_t count); @@ -449,10 +462,13 @@ extern int execve(const char *file, char **argv, char **envp); extern int open(const char *file, int flag, int mode); extern int close(int fd); extern pid_t waitpid(pid_t pid, int *wait_stat, int options); +#endif /* __KERNEL_SYSCALLS__ */ -unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset); +/* + * Functions that implement syscalls. + */ +unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, + unsigned long flags, unsigned long fd, off_t offset); unsigned long sys_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff); @@ -461,22 +477,19 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs *regs); int sys_clone(unsigned long clone_flags, unsigned long usp, - int __user *parent_tidp, void __user *child_threadptr, - int __user *child_tidp, int p6, - struct pt_regs *regs); -int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, + int __user *parent_tidp, void __user *child_threadptr, + int __user *child_tidp, int p6, struct pt_regs *regs); +int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, struct pt_regs *regs); -int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, +int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, struct pt_regs *regs); int sys_pipe(int __user *fildes); int sys_ptrace(long request, long pid, long addr, long data); struct sigaction; -long sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - size_t sigsetsize); - -#endif /* __KERNEL_SYSCALLS__ */ +long sys_rt_sigaction(int sig, const struct sigaction __user *act, + struct sigaction __user *oact, size_t sigsetsize); /* * "Conditional" syscalls @@ -484,10 +497,14 @@ long sys_rt_sigaction(int sig, * What we want is __attribute__((weak,alias("sys_ni_syscall"))), * but it doesn't work on all toolchains, so we just do it by hand */ -#ifndef cond_syscall +#ifdef CONFIG_PPC32 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#else +#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall") #endif -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_PPC_UNISTD_H_ */ diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h deleted file mode 100644 index 977bc980c1af..000000000000 --- a/include/asm-ppc64/unistd.h +++ /dev/null @@ -1,487 +0,0 @@ -#ifndef _ASM_PPC_UNISTD_H_ -#define _ASM_PPC_UNISTD_H_ - -/* - * This file contains the system call numbers. - * - * 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. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_lchown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl 110 -#define __NR_vhangup 111 -#define __NR_idle 112 -#define __NR_vm86 113 -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_modify_ldt 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_query_module 166 -#define __NR_poll 167 -#define __NR_nfsservctl 168 -#define __NR_setresgid 169 -#define __NR_getresgid 170 -#define __NR_prctl 171 -#define __NR_rt_sigreturn 172 -#define __NR_rt_sigaction 173 -#define __NR_rt_sigprocmask 174 -#define __NR_rt_sigpending 175 -#define __NR_rt_sigtimedwait 176 -#define __NR_rt_sigqueueinfo 177 -#define __NR_rt_sigsuspend 178 -#define __NR_pread64 179 -#define __NR_pwrite64 180 -#define __NR_chown 181 -#define __NR_getcwd 182 -#define __NR_capget 183 -#define __NR_capset 184 -#define __NR_sigaltstack 185 -#define __NR_sendfile 186 -#define __NR_getpmsg 187 /* some people actually want streams */ -#define __NR_putpmsg 188 /* some people actually want streams */ -#define __NR_vfork 189 -#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */ -#define __NR_readahead 191 -/* #define __NR_mmap2 192 32bit only */ -/* #define __NR_truncate64 193 32bit only */ -/* #define __NR_ftruncate64 194 32bit only */ -/* #define __NR_stat64 195 32bit only */ -/* #define __NR_lstat64 196 32bit only */ -/* #define __NR_fstat64 197 32bit only */ -#define __NR_pciconfig_read 198 -#define __NR_pciconfig_write 199 -#define __NR_pciconfig_iobase 200 -#define __NR_multiplexer 201 -#define __NR_getdents64 202 -#define __NR_pivot_root 203 -/* #define __NR_fcntl64 204 32bit only */ -#define __NR_madvise 205 -#define __NR_mincore 206 -#define __NR_gettid 207 -#define __NR_tkill 208 -#define __NR_setxattr 209 -#define __NR_lsetxattr 210 -#define __NR_fsetxattr 211 -#define __NR_getxattr 212 -#define __NR_lgetxattr 213 -#define __NR_fgetxattr 214 -#define __NR_listxattr 215 -#define __NR_llistxattr 216 -#define __NR_flistxattr 217 -#define __NR_removexattr 218 -#define __NR_lremovexattr 219 -#define __NR_fremovexattr 220 -#define __NR_futex 221 -#define __NR_sched_setaffinity 222 -#define __NR_sched_getaffinity 223 -/* 224 currently unused */ -#define __NR_tuxcall 225 -/* #define __NR_sendfile64 226 32bit only */ -#define __NR_io_setup 227 -#define __NR_io_destroy 228 -#define __NR_io_getevents 229 -#define __NR_io_submit 230 -#define __NR_io_cancel 231 -#define __NR_set_tid_address 232 -#define __NR_fadvise64 233 -#define __NR_exit_group 234 -#define __NR_lookup_dcookie 235 -#define __NR_epoll_create 236 -#define __NR_epoll_ctl 237 -#define __NR_epoll_wait 238 -#define __NR_remap_file_pages 239 -#define __NR_timer_create 240 -#define __NR_timer_settime 241 -#define __NR_timer_gettime 242 -#define __NR_timer_getoverrun 243 -#define __NR_timer_delete 244 -#define __NR_clock_settime 245 -#define __NR_clock_gettime 246 -#define __NR_clock_getres 247 -#define __NR_clock_nanosleep 248 -#define __NR_swapcontext 249 -#define __NR_tgkill 250 -#define __NR_utimes 251 -#define __NR_statfs64 252 -#define __NR_fstatfs64 253 -/* #define __NR_fadvise64_64 254 32bit only */ -#define __NR_rtas 255 -/* Number 256 is reserved for sys_debug_setcontext */ -/* Number 257 is reserved for vserver */ -/* 258 currently unused */ -#define __NR_mbind 259 -#define __NR_get_mempolicy 260 -#define __NR_set_mempolicy 261 -#define __NR_mq_open 262 -#define __NR_mq_unlink 263 -#define __NR_mq_timedsend 264 -#define __NR_mq_timedreceive 265 -#define __NR_mq_notify 266 -#define __NR_mq_getsetattr 267 -#define __NR_kexec_load 268 -#define __NR_add_key 269 -#define __NR_request_key 270 -#define __NR_keyctl 271 -#define __NR_waitid 272 -#define __NR_ioprio_set 273 -#define __NR_ioprio_get 274 -#define __NR_inotify_init 275 -#define __NR_inotify_add_watch 276 -#define __NR_inotify_rm_watch 277 - -#define __NR_syscalls 278 -#ifdef __KERNEL__ -#define NR_syscalls __NR_syscalls -#endif - -#ifndef __ASSEMBLY__ - -/* On powerpc a system call basically clobbers the same registers like a - * function call, with the exception of LR (which is needed for the - * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal - * an error return status). - */ - -#define __syscall_nr(nr, type, name, args...) \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_loadargs_##nr(name, args); \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %0 " \ - : "=&r" (__sc_0), \ - "=&r" (__sc_3), "=&r" (__sc_4), \ - "=&r" (__sc_5), "=&r" (__sc_6), \ - "=&r" (__sc_7), "=&r" (__sc_8) \ - : __sc_asm_input_##nr \ - : "cr0", "ctr", "memory", \ - "r9", "r10","r11", "r12"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - if (__sc_err & 0x10000000) \ - { \ - errno = __sc_ret; \ - __sc_ret = -1; \ - } \ - return (type) __sc_ret - -#define __sc_loadargs_0(name, dummy...) \ - __sc_0 = __NR_##name -#define __sc_loadargs_1(name, arg1) \ - __sc_loadargs_0(name); \ - __sc_3 = (unsigned long) (arg1) -#define __sc_loadargs_2(name, arg1, arg2) \ - __sc_loadargs_1(name, arg1); \ - __sc_4 = (unsigned long) (arg2) -#define __sc_loadargs_3(name, arg1, arg2, arg3) \ - __sc_loadargs_2(name, arg1, arg2); \ - __sc_5 = (unsigned long) (arg3) -#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \ - __sc_loadargs_3(name, arg1, arg2, arg3); \ - __sc_6 = (unsigned long) (arg4) -#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \ - __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \ - __sc_7 = (unsigned long) (arg5) -#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ - __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5); \ - __sc_8 = (unsigned long) (arg6) - -#define __sc_asm_input_0 "0" (__sc_0) -#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3) -#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4) -#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5) -#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6) -#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7) -#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8) - -#define _syscall0(type,name) \ -type name(void) \ -{ \ - __syscall_nr(0, type, name); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - __syscall_nr(1, type, name, arg1); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) \ -{ \ - __syscall_nr(2, type, name, arg1, arg2); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1, type2 arg2, type3 arg3) \ -{ \ - __syscall_nr(3, type, name, arg1, arg2, arg3); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \ -} -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ -} - -#ifdef __KERNEL_SYSCALLS__ - -/* - * Forking from kernel space will result in the child getting a new, - * empty kernel stack area. Thus the child cannot access automatic - * variables set in the parent unless they are in registers, and the - * procedure where the fork was done cannot return to its caller in - * the child. - */ - -/* - * System call prototypes. - */ -static inline _syscall3(int, execve, __const__ char *, file, char **, argv, - char **,envp) - -#endif /* __KERNEL_SYSCALLS__ */ - -#ifdef __KERNEL__ - -#include -#include -#include - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_COMPAT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION - -unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, - unsigned long flags, unsigned long fd, off_t offset); -struct pt_regs; -int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs *regs); -int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs); -int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs); -int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs); -int sys_pipe(int __user *fildes); -int sys_ptrace(long request, long pid, long addr, long data); -struct sigaction; -long sys_rt_sigaction(int sig, const struct sigaction __user *act, - struct sigaction __user *oact, size_t sigsetsize); - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall") - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_PPC_UNISTD_H_ */ From c5200c90db3823a6e2f529acf202c4aed04966ae Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:57:03 +1000 Subject: [PATCH 0249/1940] powerpc: Fix off-by-one error in prom_init.c This was preventing us from recognizing that we did actually instantiate RTAS successfully on pSeries. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 75dc7f3714bd..911a803f27da 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -268,7 +268,7 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, if (rets != NULL) for (i = 1; i < nret; ++i) - rets[i] = args.args[nargs+i]; + rets[i-1] = args.args[nargs+i]; return (nret > 0) ? args.args[nargs] : 0; } From e574d238ab907963ae6f97cb6bf12bb8fd48c376 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:58:10 +1000 Subject: [PATCH 0250/1940] powerpc: Fix compilation for 32-bit configs Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 21 +++------------------ arch/ppc/kernel/Makefile | 6 ++---- include/asm-ppc/pci-bridge.h | 5 +++++ 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 27d7f828212b..bfa155c00ea5 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -70,6 +70,8 @@ unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; +int have_of = 1; + #ifdef CONFIG_PPC_MULTIPLATFORM int _machine = 0; @@ -89,6 +91,7 @@ unsigned long vgacon_remap_base; #endif struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); /* * These are used in binfmt_elf.c to put aux entries on the stack @@ -455,24 +458,6 @@ console_initcall(set_preferred_console); #endif /* CONFIG_SERIAL_CORE_CONSOLE */ #endif /* CONFIG_PPC_MULTIPLATFORM */ -struct bi_record *find_bootinfo(void) -{ - struct bi_record *rec; - - rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20)); - if ( rec->tag != BI_FIRST ) { - /* - * This 0x10000 offset is a terrible hack but it will go away when - * we have the bootloader handle all the relocation and - * prom calls -- Cort - */ - rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); - if ( rec->tag != BI_FIRST ) - return NULL; - } - return rec; -} - /* * Find out what kind of machine we're on and save any data we need * from the early boot process (devtree is copied on pmac by prom_init()). diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index da2dc08c4c1b..74b30978619f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -42,13 +42,11 @@ vector-y += ../../powerpc/kernel/vector.o fpu-y += ../../powerpc/kernel/fpu.o else -obj-y := entry.o irq.o idle.o time.o misc.o \ +obj-y := irq.o idle.o time.o \ signal.o ptrace.o align.o \ - syscalls.o setup.o \ - cputable.o perfmon.o + syscalls.o cputable.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o -obj-$(CONFIG_POWER4) += cpu_setup_power4.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h index ffa423456c2b..e58c78f90a5a 100644 --- a/include/asm-ppc/pci-bridge.h +++ b/include/asm-ppc/pci-bridge.h @@ -79,6 +79,11 @@ struct pci_controller { struct resource mem_space; }; +static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus) +{ + return bus->sysdata; +} + /* These are used for config access before all the PCI probing has been done. */ int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, From 3c3f42d63a11f2e22dbff6bb4d170f92dbd39316 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 10 Oct 2005 22:58:41 +1000 Subject: [PATCH 0251/1940] powerpc: Start merging 64-bit support into powermac files Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/pci.c | 194 +++++++++++------------- arch/powerpc/platforms/powermac/pic.c | 32 ++-- arch/powerpc/platforms/powermac/pmac.h | 25 ++- arch/powerpc/platforms/powermac/setup.c | 20 +-- 4 files changed, 128 insertions(+), 143 deletions(-) diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 40bcd3e55afb..afb147e6b89f 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -1,8 +1,5 @@ /* * Support for PCI bridges found on Power Macintoshes. - * At present the "bandit" and "chaos" bridges are supported. - * Fortunately you access configuration space in the same - * way with either bridge. * * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) @@ -26,6 +23,10 @@ #include #include #include +#ifdef CONFIG_PPC64 +#include +#include +#endif #undef DEBUG @@ -160,9 +161,13 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose, static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { - struct pci_controller *hose = bus->sysdata; + struct pci_controller *hose; unsigned long addr; + hose = pci_bus_to_host(bus); + if (hose == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -187,9 +192,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { - struct pci_controller *hose = bus->sysdata; + struct pci_controller *hose; unsigned long addr; + hose = pci_bus_to_host(bus); + if (hose == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -221,7 +230,7 @@ static struct pci_ops macrisc_pci_ops = }; /* - * Verifiy that a specific (bus, dev_fn) exists on chaos + * Verify that a specific (bus, dev_fn) exists on chaos */ static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) @@ -274,7 +283,6 @@ static struct pci_ops chaos_pci_ops = }; #ifdef CONFIG_POWER4 - /* * These versions of U3 HyperTransport config space access ops do not * implement self-view of the HT host yet @@ -342,11 +350,11 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose, static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { - struct pci_controller *hose = bus->sysdata; + struct pci_controller *hose; unsigned long addr; - struct device_node *np = pci_busdev_to_OF_node(bus, devfn); - if (np == NULL) + hose = pci_bus_to_host(bus); + if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); @@ -357,19 +365,19 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, case 0: break; case 1: - switch (len) { - case 1: - *val = 0xff; break; - case 2: - *val = 0xffff; break; - default: - *val = 0xfffffffful; break; - } - return PCIBIOS_SUCCESSFUL; + switch (len) { + case 1: + *val = 0xff; break; + case 2: + *val = 0xffff; break; + default: + *val = 0xfffffffful; break; + } + return PCIBIOS_SUCCESSFUL; default: return PCIBIOS_DEVICE_NOT_FOUND; - } - + } + /* * Note: the caller has already checked that offset is * suitably aligned and that len is 1, 2 or 4. @@ -391,11 +399,11 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { - struct pci_controller *hose = bus->sysdata; + struct pci_controller *hose; unsigned long addr; - struct device_node *np = pci_busdev_to_OF_node(bus, devfn); - if (np == NULL) + hose = pci_bus_to_host(bus); + if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); @@ -437,15 +445,13 @@ static struct pci_ops u3_ht_pci_ops = u3_ht_read_config, u3_ht_write_config }; - #endif /* CONFIG_POWER4 */ /* * For a bandit bridge, turn on cache coherency if necessary. * N.B. we could clean this up using the hose ops directly. */ -static void __init -init_bandit(struct pci_controller *bp) +static void __init init_bandit(struct pci_controller *bp) { unsigned int vendev, magic; int rev; @@ -485,8 +491,7 @@ init_bandit(struct pci_controller *bp) /* * Tweak the PCI-PCI bridge chip on the blue & white G3s. */ -static void __init -init_p2pbridge(void) +static void __init init_p2pbridge(void) { struct device_node *p2pbridge; struct pci_controller* hose; @@ -526,8 +531,7 @@ init_p2pbridge(void) * EHCI part of it so it behaves like a pair of OHCI's. This fixup * code re-enables it ;) */ -static void __init -fixup_nec_usb2(void) +static void __init fixup_nec_usb2(void) { struct device_node *nec; @@ -567,77 +571,6 @@ fixup_nec_usb2(void) } } -void __init -pmac_find_bridges(void) -{ - struct device_node *np, *root; - struct device_node *ht = NULL; - - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); - return; - } - for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { - if (np->name == NULL) - continue; - if (strcmp(np->name, "bandit") == 0 - || strcmp(np->name, "chaos") == 0 - || strcmp(np->name, "pci") == 0) { - if (add_bridge(np) == 0) - of_node_get(np); - } - if (strcmp(np->name, "ht") == 0) { - of_node_get(np); - ht = np; - } - } - of_node_put(root); - - /* Probe HT last as it relies on the agp resources to be already - * setup - */ - if (ht && add_bridge(ht) != 0) - of_node_put(ht); - - init_p2pbridge(); - fixup_nec_usb2(); - - /* We are still having some issues with the Xserve G4, enabling - * some offset between bus number and domains for now when we - * assign all busses should help for now - */ - if (pci_assign_all_busses) - pcibios_assign_bus_offset = 0x10; - -#ifdef CONFIG_POWER4 - /* There is something wrong with DMA on U3/HT. I haven't figured out - * the details yet, but if I set the cache line size to 128 bytes like - * it should, I'm getting memory corruption caused by devices like - * sungem (even without the MWI bit set, but maybe sungem doesn't - * care). Right now, it appears that setting up a 64 bytes line size - * works properly, 64 bytes beeing the max transfer size of HT, I - * suppose this is related the way HT/PCI are hooked together. I still - * need to dive into more specs though to be really sure of what's - * going on. --BenH. - * - * Ok, apparently, it's just that HT can't do more than 64 bytes - * transactions. MWI seem to be meaningless there as well, it may - * be worth nop'ing out pci_set_mwi too though I haven't done that - * yet. - * - * Note that it's a bit different for whatever is in the AGP slot. - * For now, I don't care, but this can become a real issue, we - * should probably hook pci_set_mwi anyway to make sure it sets - * the real cache line size in there. - */ - if (machine_is_compatible("MacRISC4")) - pci_cache_line_size = 16; /* 64 bytes */ - - pmac_check_ht_link(); -#endif /* CONFIG_POWER4 */ -} - #define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | (((o) & ~3) << 24)) @@ -703,7 +636,6 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr) } #ifdef CONFIG_POWER4 - static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need @@ -715,7 +647,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) * the reg address cell, we shall fix that by killing struct * reg_property and using some accessor functions instead */ - hose->first_busno = 0xf0; + hose->first_busno = 0xf0; hose->last_busno = 0xff; has_uninorth = 1; hose->ops = ¯isc_pci_ops; @@ -748,7 +680,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) */ hose->io_base_phys = 0xf4000000; hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); - isa_io_base = (unsigned long) hose->io_base_virt; + isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt; hose->io_resource.name = np->full_name; hose->io_resource.start = 0; hose->io_resource.end = 0x003fffff; @@ -794,13 +726,13 @@ static void __init setup_u3_ht(struct pci_controller* hose) } /* No, it's not the case, we need a hole */ if (cur == 2) { - /* not enough resources to make a hole, we drop part of the range */ + /* not enough resources for a hole, we drop part of the range */ printk(KERN_WARNING "Running out of resources for /ht host !\n"); hose->mem_resources[cur].end = res->start - 1; continue; } cur++; - DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", + DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", cur-1, res->start - 1, cur, res->end + 1); hose->mem_resources[cur].name = np->full_name; hose->mem_resources[cur].flags = IORESOURCE_MEM; @@ -981,7 +913,7 @@ static int __init add_bridge(struct device_node *dev) if (device_is_compatible(dev, "uni-north")) { primary = setup_uninorth(hose, addr); disp_name = "UniNorth"; - } else if (strcmp(dev->name, "pci") == 0) { + } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ setup_grackle(hose); disp_name = "Grackle (MPC106)"; @@ -993,7 +925,7 @@ static int __init add_bridge(struct device_node *dev) disp_name = "Chaos"; primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", + printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", disp_name, addr->address, hose->first_busno, hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); @@ -1036,6 +968,50 @@ pmac_pcibios_fixup(void) pcibios_fixup_OF_interrupts(); } +void __init pmac_find_bridges(void) +{ + struct device_node *np, *root; + struct device_node *ht = NULL; + + root = of_find_node_by_path("/"); + if (root == NULL) { + printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); + return; + } + for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { + if (np->name == NULL) + continue; + if (strcmp(np->name, "bandit") == 0 + || strcmp(np->name, "chaos") == 0 + || strcmp(np->name, "pci") == 0) { + if (add_bridge(np) == 0) + of_node_get(np); + } + if (strcmp(np->name, "ht") == 0) { + of_node_get(np); + ht = np; + } + } + of_node_put(root); + + /* Probe HT last as it relies on the agp resources to be already + * setup + */ + if (ht && add_bridge(ht) != 0) + of_node_put(ht); + + init_p2pbridge(); + fixup_nec_usb2(); + + /* We are still having some issues with the Xserve G4, enabling + * some offset between bus number and domains for now when we + * assign all busses should help for now + */ + if (pci_assign_all_busses) + pcibios_assign_bus_offset = 0x10; + +} + int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) { diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 7ddd5264cc6e..682fe8b6e025 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -32,12 +33,11 @@ #include #include #include -#include #include #include #include -#include "pmac_pic.h" +#include "pmac.h" /* * XXX this should be in xmon.h, but putting it there means xmon.h @@ -46,6 +46,7 @@ */ extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); +#ifdef CONFIG_PPC32 struct pmac_irq_hw { unsigned int event; unsigned int enable; @@ -71,6 +72,9 @@ static u32 level_mask[4]; static DEFINE_SPINLOCK(pmac_pic_lock); +/* XXX here for now, should move to arch/powerpc/kernel/irq.c */ +int ppc_do_canonicalize_irqs; +EXPORT_SYMBOL(ppc_do_canonicalize_irqs); #define GATWICK_IRQ_POOL_SIZE 10 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; @@ -377,11 +381,6 @@ static int __init enable_second_ohare(void) return irqctrler->intrs[0].line; } -static int pmac_u3_cascade(struct pt_regs *regs, void *data) -{ - return mpic_get_one_irq((struct mpic *)data, regs); -} - #ifdef CONFIG_XMON static struct irqaction xmon_action = { .handler = xmon_irq, @@ -397,15 +396,23 @@ static struct irqaction gatwick_cascade_action = { .mask = CPU_MASK_NONE, .name = "cascade", }; +#endif /* CONFIG_PPC32 */ + +static int pmac_u3_cascade(struct pt_regs *regs, void *data) +{ + return mpic_get_one_irq((struct mpic *)data, regs); +} void __init pmac_pic_init(void) { - int i; struct device_node *irqctrler = NULL; struct device_node *irqctrler2 = NULL; struct device_node *np; +#ifdef CONFIG_PPC32 + int i; unsigned long addr; int irq_cascade = -1; +#endif struct mpic *mpic1, *mpic2; /* We first try to detect Apple's new Core99 chipset, since mac-io @@ -455,7 +462,7 @@ void __init pmac_pic_init(void) mpic_setup_cascade(irqctrler2->intrs[0].line, pmac_u3_cascade, mpic2); } -#ifdef CONFIG_XMON +#if defined(CONFIG_XMON) && defined(CONFIG_PPC32) { struct device_node* pswitch; int nmi_irq; @@ -463,7 +470,7 @@ void __init pmac_pic_init(void) pswitch = find_devices("programmer-switch"); if (pswitch && pswitch->n_intrs) { nmi_irq = pswitch->intrs[0].line; - openpic_init_nmi_irq(nmi_irq); + mpic_irq_set_priority(nmi_irq, 9); setup_irq(nmi_irq, &xmon_action); } } @@ -472,6 +479,7 @@ void __init pmac_pic_init(void) } irqctrler = NULL; +#ifdef CONFIG_PPC32 /* Get the level/edge settings, assume if it's not * a Grand Central nor an OHare, then it's an Heathrow * (or Paddington). @@ -570,6 +578,7 @@ void __init pmac_pic_init(void) #ifdef CONFIG_XMON setup_irq(20, &xmon_action); #endif /* CONFIG_XMON */ +#endif /* CONFIG_PPC32 */ } #ifdef CONFIG_PM @@ -659,9 +668,10 @@ static struct sysdev_driver driver_pmacpic = { static int __init init_pmacpic_sysfs(void) { +#ifdef CONFIG_PPC32 if (max_irqs == 0) return -ENODEV; - +#endif printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); sysdev_class_register(&pmacpic_sysclass); sysdev_register(&device_pmacpic); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 40e1c5030f74..81f52512b046 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -3,19 +3,31 @@ #include #include +#include /* * Declaration for the various functions exported by the * pmac_* files. Mostly for use by pmac_setup */ -extern void pmac_get_boot_time(struct rtc_time *tm); -extern void pmac_get_rtc_time(struct rtc_time *tm); -extern int pmac_set_rtc_time(struct rtc_time *tm); +extern long pmac_time_init(void); +extern unsigned long pmac_get_rtc_time(void); +extern int pmac_set_rtc_time(unsigned long nowtime); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); - extern void pmac_pcibios_fixup(void); +extern void pmac_find_bridges(void); +extern unsigned long pmac_ide_get_base(int index); +extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, + unsigned long data_port, unsigned long ctrl_port, int *irq); + +extern void pmac_nvram_update(void); +extern unsigned char pmac_nvram_read_byte(int addr); +extern void pmac_nvram_write_byte(int addr, unsigned char val); +extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); +extern void pmac_pcibios_after_init(void); +extern int of_show_percpuinfo(struct seq_file *m, int i); + extern void pmac_pci_init(void); extern void pmac_setup_pci_dma(void); extern void pmac_check_ht_link(void); @@ -28,4 +40,9 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, extern void pmac_nvram_init(void); +extern struct hw_interrupt_type pmac_pic; + +void pmac_pic_init(void); +int pmac_get_irq(struct pt_regs *regs); + #endif /* __PMAC_H__ */ diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 1b12bf9956cb..9416fcaa6daa 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -73,28 +73,10 @@ #include #include -#include "pmac_pic.h" +#include "pmac.h" #undef SHOW_GATWICK_IRQS -extern long pmac_time_init(void); -extern unsigned long pmac_get_rtc_time(void); -extern int pmac_set_rtc_time(unsigned long nowtime); -extern void pmac_read_rtc_time(void); -extern void pmac_calibrate_decr(void); -extern void pmac_pcibios_fixup(void); -extern void pmac_find_bridges(void); -extern unsigned long pmac_ide_get_base(int index); -extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, - unsigned long data_port, unsigned long ctrl_port, int *irq); - -extern void pmac_nvram_update(void); -extern unsigned char pmac_nvram_read_byte(int addr); -extern void pmac_nvram_write_byte(int addr, unsigned char val); -extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); -extern void pmac_pcibios_after_init(void); -extern int of_show_percpuinfo(struct seq_file *m, int i); - unsigned char drive_info; int ppc_override_l2cr = 0; From 68058e757573d4e81550e74c5a03a29a29069ce7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 10:34:22 -0700 Subject: [PATCH 0252/1940] [CIFS] Reduce CIFS tcp congestion timeout (it was too long) and backoff ever longer amounts (up to 15 seconds). This improves performance especially when using large wsize. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_debug.c | 4 ++-- fs/cifs/cifsfs.c | 16 +++++++++++++--- fs/cifs/transport.c | 13 +++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 785239618d89..b7fb064f6548 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -114,7 +114,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&ses->server->inFlight)); #ifdef CONFIG_CIFS_STATS2 - buf += sprintf(buf, "\tIn Send: %d In MaxReq Wait: %d", + buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", atomic_read(&ses->server->inSend), atomic_read(&ses->server->num_waiters)); #endif @@ -267,7 +267,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&tcon->num_oplock_brks)); buf += item_length; length += item_length; - item_length = sprintf(buf, "\nReads: %d Bytes %lld", + item_length = sprintf(buf, "\nReads: %d Bytes %lld", atomic_read(&tcon->num_reads), (long long)(tcon->bytes_read)); buf += item_length; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 1f97d39100ee..e3177a031edc 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -405,6 +405,16 @@ static struct quotactl_ops cifs_quotactl_ops = { }; #endif +static void cifs_umount_begin(struct super_block * sblock) +{ + cERROR(1,("kill all tasks now - umount begin not implemented yet")); + +/* BB FIXME - finish BB */ + + return; +} + + static int cifs_remount(struct super_block *sb, int *flags, char *data) { *flags |= MS_NODIRATIME; @@ -422,7 +432,7 @@ struct super_operations cifs_super_ops = { unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, -/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */ +/* .umount_begin = cifs_umount_begin, */ /* BB finish in the future */ .remount_fs = cifs_remount, }; @@ -790,9 +800,7 @@ static int cifs_oplock_thread(void * dummyarg) do { if(try_to_freeze()) continue; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1*HZ); spin_lock(&GlobalMid_Lock); if(list_empty(&GlobalOplock_Q)) { spin_unlock(&GlobalMid_Lock); @@ -841,6 +849,8 @@ static int cifs_oplock_thread(void * dummyarg) } } else spin_unlock(&GlobalMid_Lock); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); /* yield in case q were corrupt */ } } while(!signal_pending(current)); oplockThread = NULL; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 893a6fef9853..d9b11690746d 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -157,14 +157,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, /* smaller timeout here than send2 since smaller size */ /* Although it may not be required, this also is smaller oplock break time */ - if(i > 30) { + if(i > 12) { cERROR(1, - ("sends on sock %p stuck for 15 seconds", + ("sends on sock %p stuck for 7 seconds", ssocket)); rc = -EAGAIN; break; } - msleep(500); + msleep(1 << i); continue; } if (rc < 0) @@ -224,14 +224,14 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, n_vec - first_vec, total_len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; - if(i > 40) { + if(i >= 14) { cERROR(1, - ("sends on sock %p stuck for 20 seconds", + ("sends on sock %p stuck for 15 seconds", ssocket)); rc = -EAGAIN; break; } - msleep(500); + msleep(1 << i); continue; } if (rc < 0) @@ -249,6 +249,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, continue; } total_len -= rc; + /* the line below resets i */ for (i = first_vec; i < n_vec; i++) { if (iov[i].iov_len) { if (rc > iov[i].iov_len) { From 0ae0efada36219024e4e3008f16c993d5d091280 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 10:57:19 -0700 Subject: [PATCH 0253/1940] [CIFS] Fix rsize calculation so that large readx flag is checked. Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_debug.c | 2 +- fs/cifs/connect.c | 29 ++++++++++++++++++++++++----- fs/cifs/file.c | 5 +++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index b7fb064f6548..6f7810992db3 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -267,7 +267,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&tcon->num_oplock_brks)); buf += item_length; length += item_length; - item_length = sprintf(buf, "\nReads: %d Bytes %lld", + item_length = sprintf(buf, "\nReads: %d Bytes: %lld", atomic_read(&tcon->num_reads), (long long)(tcon->bytes_read)); buf += item_length; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 31eb9a3bf627..d1c6acee620e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "cifspdu.h" @@ -188,6 +189,7 @@ cifs_reconnect(struct TCP_Server_Info *server) server->server_RFC1001_name); } if(rc) { + cERROR(1,("reconnect error %d",rc)); msleep(3000); } else { atomic_inc(&tcpSesReconnectCount); @@ -469,6 +471,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } else { /* give server a second to clean up before reconnect attempt */ + cERROR(1,("sleep before reconnect")); msleep(1000); /* always try 445 first on reconnect since we get NACK on some if we ever @@ -556,6 +559,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) dump_smb(smb_buffer, length); if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { cERROR(1, ("Bad SMB Received ")); + cifs_dump_mem("smb: ", smb_buffer, 48); continue; } @@ -1383,7 +1387,9 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, the default. sock_setsockopt not used because it expects user space buffer */ (*csocket)->sk->sk_rcvtimeo = 7 * HZ; - + cERROR(1,("sndbuf %d rcvbuf %d reset to 200K each",(*csocket)->sk->sk_sndbuf, (*csocket)->sk->sk_rcvbuf)); + (*csocket)->sk->sk_sndbuf = 300 * 1024; + (*csocket)->sk->sk_rcvbuf = 200 * 1024; /* send RFC1001 sessinit */ if(psin_server->sin_port == htons(RFC1001_PORT)) { @@ -1736,11 +1742,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, /* search for existing tcon to this server share */ if (!rc) { - if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) + if(volume_info.rsize > CIFSMaxBufSize) { + cERROR(1,("rsize %d too large, using MaxBufSize", + volume_info.rsize)); + cifs_sb->rsize = CIFSMaxBufSize; + } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) cifs_sb->rsize = volume_info.rsize; - else - cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ - if(volume_info.wsize) + else /* default */ + cifs_sb->rsize = CIFSMaxBufSize; + + if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { + cERROR(1,("wsize %d too large using 4096 instead", + volume_info.wsize)); + cifs_sb->wsize = 4096; + } else if(volume_info.wsize) cifs_sb->wsize = volume_info.wsize; else cifs_sb->wsize = CIFSMaxBufSize; /* default */ @@ -1895,6 +1910,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->wsize = min(cifs_sb->wsize, (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); + if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) + cifs_sb->rsize = min(cifs_sb->rsize, + (tcon->ses->server->maxBuf - + MAX_CIFS_HDR_SIZE)); } /* volume_info.password is freed above when existing session found diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 39b23f4fa6c3..11806c879c47 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -855,7 +855,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, struct kvec iov[2]; unsigned int len; - len = min(cifs_sb->wsize, + len = min((size_t)cifs_sb->wsize, write_size - total_written); /* iov[0] is reserved for smb header */ iov[1].iov_base = (char *)write_data + @@ -920,7 +920,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) ((open_file->pfile->f_flags & O_RDWR) || (open_file->pfile->f_flags & O_WRONLY))) { read_unlock(&GlobalSMBSeslock); - if(open_file->invalidHandle) { + if((open_file->invalidHandle) && + (!open_file->closePend)) { rc = cifs_reopen_file(&cifs_inode->vfs_inode, open_file->pfile, FALSE); /* if it fails, try another handle - might be */ From 190fdeb84499a2dc046adae2eebfdda49e315e96 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 11:48:26 -0700 Subject: [PATCH 0254/1940] [CIFS] Fix byte range locking to Windows when Windows server returns illegal RFC1001 length (which had caused the lock to block forever until killed). --- fs/cifs/CHANGES | 12 ++++++++++++ fs/cifs/README | 4 ++-- fs/cifs/TODO | 6 +++--- fs/cifs/misc.c | 22 +++++++++++++++------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 535177238020..1c249a2abae3 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,15 @@ +Version 1.38 +------------ +Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket) +to be smaller at first (but increasing) so large write performance performance +over GigE is better. Do not hang thread on illegal byte range lock response +from Windows (Windows can send an RFC1001 size which does not match smb size) by +allowing an SMBs TCP length to be up to a few bytes longer than it should be. +wsize and rsize can now be larger than negotiated buffer size if server +supports large readx/writex, even when directio mount flag not specified. +Write size will in many cases now be 16K instead of 4K which greatly helps +file copy performance on lightly loaded networks. + Version 1.37 ------------ Fix readdir caching when unlink removes file in current search buffer, diff --git a/fs/cifs/README b/fs/cifs/README index 3b610d08dc1e..5d9a953888d9 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -294,8 +294,8 @@ A partial list of the supported mount options follows: during the local client kernel build will be used. If server does not support Unicode, this parameter is unused. - rsize default read size - wsize default write size + rsize default read size (usually 16K) + wsize default write size (usually 16K, 32K is often better over GigE) rw mount the network share read-write (note that the server may still consider the share read-only) ro mount network share read-only diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 0593f6447319..c909298d11ed 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO @@ -1,4 +1,4 @@ -version 1.36 September 6, 2005 +version 1.37 October 9, 2005 A Partial List of Missing Features ================================== @@ -38,8 +38,8 @@ by unlocking all known byte range locks that we locked on the file. i) quota support (needs minor kernel change since quota calls to make it to network filesystems or deviceless filesystems) -j) finish writepages support (multi-page write behind for improved -performance) and syncpage. Started by Shaggy. +j) investigate sync behavior (including syncpage) and check +for proper behavior of intr/nointr k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the extra copy in/out of the socket buffers in some cases. diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 8a0edd695f84..eba1de917f2a 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -420,6 +420,7 @@ int checkSMB(struct smb_hdr *smb, __u16 mid, int length) { __u32 len = smb->smb_buf_length; + __u32 clc_len; /* calculated length */ cFYI(0, ("Entering checkSMB with Length: %x, smb_buf_length: %x ", length, len)); @@ -440,20 +441,27 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) cERROR(1, ("smb_buf_length greater than MaxBufSize")); cERROR(1, - ("bad smb detected. Illegal length. The mid=%d", + ("bad smb detected. Illegal length. mid=%d", smb->Mid)); return 1; } if (checkSMBhdr(smb, mid)) return 1; - - if ((4 + len != smbCalcSize_LE(smb)) + clc_len = smbCalcSize_LE(smb); + if ((4 + len != clc_len) || (4 + len != (unsigned int)length)) { - cERROR(1, ("smbCalcSize %x ", smbCalcSize_LE(smb))); - cERROR(1, - ("bad smb size detected. The Mid=%d", smb->Mid)); - return 1; + cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", + clc_len, 4 + len)); + cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); + /* Windows XP can return a few bytes too much, presumably + an illegal pad, at the end of byte range lock responses + so we allow for up to eight byte pad, as long as actual + received length is as long or longer than calculated length */ + if((4+len > clc_len) && (len <= clc_len + 3)) + return 0; + else + return 1; } return 0; } From 02c37a6df558fb8768c4c8ae792e86e9abf2d733 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 11:49:37 -0700 Subject: [PATCH 0255/1940] [CIFS] Update cifs version to 1.38 Signed-off-by: Steve French --- fs/cifs/cifsfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 0f6d352ab813..4cdb29fdc8c2 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -97,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.37" +#define CIFS_VERSION "1.38" #endif /* _CIFSFS_H */ From 5e1253b50111220f06ee13bc4e555d89ff39176b Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 14:06:37 -0700 Subject: [PATCH 0256/1940] [CIFS] Correct cifs tcp retry when some data sent before getting EAGAIN. Continue implementation of cifs umount begin to allow force unmounts of cifs mounts. Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 19 +++++++++++++++++-- fs/cifs/transport.c | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e3177a031edc..fd5eae37f2a8 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -407,9 +407,24 @@ static struct quotactl_ops cifs_quotactl_ops = { static void cifs_umount_begin(struct super_block * sblock) { - cERROR(1,("kill all tasks now - umount begin not implemented yet")); + struct cifs_sb_info *cifs_sb; -/* BB FIXME - finish BB */ + cifs_sb = CIFS_SB(sb); + if(cifs_sb == NULL) + return -EIO; + if(cifs_sb->tcon == NULL) + return -EIO; + down(&tcon->tconSem); + if (atomic_read(&tcon->useCount) == 1) + tcon->tidStatus = CifsExiting; + up(&tcon->tconSem); + + if((cifs->sb->tcon->ses) && (cifs_sb->tcon->ses->server)) + { + cERROR(1,("wake up tasks now - umount begin not complete")); + wake_up_all(&server->request_q); + } +/* BB FIXME - finish add checks for tidStatus BB */ return; } diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index d9b11690746d..d8865fbd876a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -169,6 +169,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, } if (rc < 0) break; + else + i = 0; /* reset i after each successful send */ iov.iov_base += rc; iov.iov_len -= rc; len -= rc; @@ -263,6 +265,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, } } } + i = 0; /* in case we get ENOSPC on the next send */ } if (rc < 0) { From b387eaeb666f6a5e24990a1f4d6a0447ae14315d Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 14:21:15 -0700 Subject: [PATCH 0257/1940] [CIFS] Do not shrink tcp sndbuf/rcvbuf from their defaults Signed-off-by: Steve French --- fs/cifs/connect.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d1c6acee620e..177289771abe 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -189,7 +189,7 @@ cifs_reconnect(struct TCP_Server_Info *server) server->server_RFC1001_name); } if(rc) { - cERROR(1,("reconnect error %d",rc)); + cFYI(1,("reconnect error %d",rc)); msleep(3000); } else { atomic_inc(&tcpSesReconnectCount); @@ -471,7 +471,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } else { /* give server a second to clean up before reconnect attempt */ - cERROR(1,("sleep before reconnect")); msleep(1000); /* always try 445 first on reconnect since we get NACK on some if we ever @@ -558,8 +557,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) dump_smb(smb_buffer, length); if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { - cERROR(1, ("Bad SMB Received ")); - cifs_dump_mem("smb: ", smb_buffer, 48); + cifs_dump_mem("Bad SMB: ", smb_buffer, 48); continue; } @@ -1386,12 +1384,16 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, /* Eventually check for other socket options to change from the default. sock_setsockopt not used because it expects user space buffer */ + cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf, + (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); (*csocket)->sk->sk_rcvtimeo = 7 * HZ; - cERROR(1,("sndbuf %d rcvbuf %d reset to 200K each",(*csocket)->sk->sk_sndbuf, (*csocket)->sk->sk_rcvbuf)); - (*csocket)->sk->sk_sndbuf = 300 * 1024; - (*csocket)->sk->sk_rcvbuf = 200 * 1024; - /* send RFC1001 sessinit */ + /* make the bufsizes depend on wsize/rsize and max requests */ + if((*csocket)->sk->sk_sndbuf < (200 * 1024)) + (*csocket)->sk->sk_sndbuf = 200 * 1024; + if((*csocket)->sk->sk_rcvbuf < (140 * 1024)) + (*csocket)->sk->sk_rcvbuf = 140 * 1024; + /* send RFC1001 sessinit */ if(psin_server->sin_port == htons(RFC1001_PORT)) { /* some servers require RFC1001 sessinit before sending negprot - BB check reconnection in case where second From 9e2e85f82fa280e937ee42152e7cbaff78be01a2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 14:28:38 -0700 Subject: [PATCH 0258/1940] [CIFS] Fix minor build problem with previous changeset Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index fd5eae37f2a8..99e087d3554f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -408,21 +408,24 @@ static struct quotactl_ops cifs_quotactl_ops = { static void cifs_umount_begin(struct super_block * sblock) { struct cifs_sb_info *cifs_sb; + struct cifsTconInfo * tcon; cifs_sb = CIFS_SB(sb); if(cifs_sb == NULL) - return -EIO; - if(cifs_sb->tcon == NULL) - return -EIO; + return; + + tcon = cifs_sb->tcon; + if(tcon == NULL) + return; down(&tcon->tconSem); if (atomic_read(&tcon->useCount) == 1) tcon->tidStatus = CifsExiting; up(&tcon->tconSem); - if((cifs->sb->tcon->ses) && (cifs_sb->tcon->ses->server)) + if(tcon->ses && tcon->ses->server) { cERROR(1,("wake up tasks now - umount begin not complete")); - wake_up_all(&server->request_q); + wake_up_all(&tcon->ses->server->request_q); } /* BB FIXME - finish add checks for tidStatus BB */ From 34210f33025a3256b9ac3f0a182f02f1879140cb Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 14:31:13 -0700 Subject: [PATCH 0259/1940] [CIFS] Still missing a line from previous fix Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 99e087d3554f..3bc9db522600 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -410,7 +410,7 @@ static void cifs_umount_begin(struct super_block * sblock) struct cifs_sb_info *cifs_sb; struct cifsTconInfo * tcon; - cifs_sb = CIFS_SB(sb); + cifs_sb = CIFS_SB(sblock); if(cifs_sb == NULL) return; From 20f629549b30a1154c8b5e830cb10a0c0faa875f Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:25:40 +1000 Subject: [PATCH 0260/1940] powerpc: Make building the boot image work for both 32-bit and 64-bit At the moment we don't have a merged arch/powerpc/boot, so we build the boot images in arch/ppc/boot and arch/ppc64/boot. Unfortunately the makefile targets are different in those two directories, so this makes a change to accommodate both for the moment. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 27649cfc2a5d..8d1e7bd14c55 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -140,6 +140,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ defaultimage-$(CONFIG_PPC32) := uImage zImage defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux +defaultimage-$(CONFIG_PPC_PSERIES) := zImage KBUILD_IMAGE := $(defaultimage-y) all: $(KBUILD_IMAGE) @@ -154,8 +155,14 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm boot := arch/$(OLDARCH)/boot +# urk +ifeq ($(CONFIG_PPC64),y) $(BOOT_TARGETS): vmlinux - $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot) $@ + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) +else +$(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@ +endif uImage: vmlinux $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@ From 508c40227caee4cef0e963e61a3a5172a108b455 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:26:48 +1000 Subject: [PATCH 0261/1940] powerpc: Merged asm/backlight.h Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/backlight.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename include/{asm-ppc => asm-powerpc}/backlight.h (82%) diff --git a/include/asm-ppc/backlight.h b/include/asm-powerpc/backlight.h similarity index 82% rename from include/asm-ppc/backlight.h rename to include/asm-powerpc/backlight.h index 3a1c3dede2a0..1ba1f27a0b63 100644 --- a/include/asm-ppc/backlight.h +++ b/include/asm-powerpc/backlight.h @@ -1,12 +1,13 @@ /* * Routines for handling backlight control on PowerBooks * - * For now, implementation resides in arch/ppc/kernel/pmac_support.c + * For now, implementation resides in + * arch/powerpc/platforms/powermac/pmac_support.c * */ +#ifndef __ASM_POWERPC_BACKLIGHT_H +#define __ASM_POWERPC_BACKLIGHT_H #ifdef __KERNEL__ -#ifndef __ASM_PPC_BACKLIGHT_H -#define __ASM_PPC_BACKLIGHT_H /* Abstract values */ #define BACKLIGHT_OFF 0 @@ -26,5 +27,5 @@ extern int get_backlight_enable(void); extern int set_backlight_level(int level); extern int get_backlight_level(void); -#endif #endif /* __KERNEL__ */ +#endif From 3b341c1c410078bdc4128e08d4dfeef491697198 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:28:16 +1000 Subject: [PATCH 0262/1940] powerpc: Merged asm/i8259.h Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/i8259.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename include/{asm-ppc => asm-powerpc}/i8259.h (62%) diff --git a/include/asm-ppc/i8259.h b/include/asm-powerpc/i8259.h similarity index 62% rename from include/asm-ppc/i8259.h rename to include/asm-powerpc/i8259.h index 091b71295de4..9521ad47740f 100644 --- a/include/asm-ppc/i8259.h +++ b/include/asm-powerpc/i8259.h @@ -1,5 +1,5 @@ -#ifndef _PPC_KERNEL_i8259_H -#define _PPC_KERNEL_i8259_H +#ifndef _ASM_POWERPC_I8259_H +#define _ASM_POWERPC_I8259_H #include @@ -8,4 +8,4 @@ extern struct hw_interrupt_type i8259_pic; extern void i8259_init(long intack_addr); extern int i8259_irq(struct pt_regs *regs); -#endif /* _PPC_KERNEL_i8259_H */ +#endif /* _ASM_POWERPC_I8259_H */ From 8d66912c3d12df45a59d4e2a66b5ae622e3524b7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:33:08 +1000 Subject: [PATCH 0263/1940] powerpc: Remove 83xx from arch/powerpc/platforms/Makefile for now Since we don't have an 83xx directory or a 83xx/Makefile, having 83xx in causes make clean to fail. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 181ae612b2d3..da744d5e52fd 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -2,7 +2,6 @@ ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif obj-$(CONFIG_4xx) += 4xx/ -obj-$(CONFIG_83xx) += 83xx/ obj-$(CONFIG_85xx) += 85xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ From 60a3d741780a883f4ce10c0fab99e8542ec65e04 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:46:10 +1000 Subject: [PATCH 0264/1940] powerpc: Merged asm/xmon.h Xmon itself isn't merged yet, though. Signed-off-by: Paul Mackerras --- include/asm-powerpc/xmon.h | 12 ++++++++++++ include/asm-ppc/xmon.h | 17 ----------------- 2 files changed, 12 insertions(+), 17 deletions(-) create mode 100644 include/asm-powerpc/xmon.h delete mode 100644 include/asm-ppc/xmon.h diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h new file mode 100644 index 000000000000..ca5f33277e0c --- /dev/null +++ b/include/asm-powerpc/xmon.h @@ -0,0 +1,12 @@ +#ifndef __PPC_XMON_H +#define __PPC_XMON_H +#ifdef __KERNEL__ + +struct pt_regs; + +extern void xmon(struct pt_regs *excp); +extern void xmon_printf(const char *fmt, ...); +extern void xmon_init(int); + +#endif +#endif diff --git a/include/asm-ppc/xmon.h b/include/asm-ppc/xmon.h deleted file mode 100644 index 042b83e6680d..000000000000 --- a/include/asm-ppc/xmon.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __PPC_XMON_H -#define __PPC_XMON_H -#ifdef __KERNEL__ - -struct pt_regs; - -extern void xmon(struct pt_regs *excp); -extern void xmon_printf(const char *fmt, ...); -extern void xmon_map_scc(void); -extern int xmon_bpt(struct pt_regs *regs); -extern int xmon_sstep(struct pt_regs *regs); -extern int xmon_iabr_match(struct pt_regs *regs); -extern int xmon_dabr_match(struct pt_regs *regs); -extern void (*xmon_fault_handler)(struct pt_regs *regs); - -#endif -#endif From abc244dd855a8013db8c850c21811c12a22b608a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 09:47:23 +1000 Subject: [PATCH 0265/1940] powerpc: Remove xmon.h include from arch/powerpc/platforms/powermac/pic.c ... since it isn't needed. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/pic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 682fe8b6e025..58017d18db70 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include From 4ca9c190d902caa7efb899a4c7fc8c6e6d926e95 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 10 Oct 2005 19:52:13 -0700 Subject: [PATCH 0266/1940] [CIFS] Fix oops in experimental notify code (when CONFIG_CIFS_EXPERIMENTAL was turned on). Signed-off-by: Steve French --- fs/cifs/CHANGES | 3 ++- fs/cifs/README | 2 ++ fs/cifs/cifsfs.c | 4 ++++ fs/cifs/fcntl.c | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1c249a2abae3..b2a938378bef 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -8,7 +8,8 @@ allowing an SMBs TCP length to be up to a few bytes longer than it should be. wsize and rsize can now be larger than negotiated buffer size if server supports large readx/writex, even when directio mount flag not specified. Write size will in many cases now be 16K instead of 4K which greatly helps -file copy performance on lightly loaded networks. +file copy performance on lightly loaded networks. Fix oops in dnotify +when experimental config flag enabled. Version 1.37 ------------ diff --git a/fs/cifs/README b/fs/cifs/README index 5d9a953888d9..e7a3ce62d71b 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -296,6 +296,8 @@ A partial list of the supported mount options follows: unused. rsize default read size (usually 16K) wsize default write size (usually 16K, 32K is often better over GigE) + maximum wsize currently allowed by CIFS is 57344 (14 4096 byte + pages) rw mount the network share read-write (note that the server may still consider the share read-only) ro mount network share read-only diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3bc9db522600..d2d16a9c1f05 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -901,6 +901,10 @@ init_cifs(void) INIT_LIST_HEAD(&GlobalSMBSessionList); INIT_LIST_HEAD(&GlobalTreeConnectionList); INIT_LIST_HEAD(&GlobalOplock_Q); +#ifdef CONFIG_CIFS_EXPERIMENTAL + INIT_LIST_HEAD(&GlobalDnotifyReqList); + INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); +#endif /* * Initialize Global counters */ diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index d527e2c76073..a7a47bb36bf3 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -78,6 +78,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg) __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; __u16 netfid; + + if(experimEnabled == 0) + return 0; + xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; From cc5aa206d2c853929ce67d8f5ebb57cd1c7fd413 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 17:35:20 +1000 Subject: [PATCH 0267/1940] powerpc: Remove debug messages from setup_64.c A bunch of printks were left in arch/powerpc/kernel/setup_64.c from when I was chasing a bug. This removes them. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_64.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 212b00823f82..4fcf67575cbb 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -567,14 +567,11 @@ void __init setup_system(void) */ rtas_initialize(); #endif /* CONFIG_PPC_RTAS */ - printk("%s:%d rtas.dev=%p (@ %p)\n", __FILE__, __LINE__, rtas.dev, - &rtas.dev); /* * Check if we have an initrd provided via the device-tree */ check_for_initrd(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* * Do some platform specific early initializations, that includes @@ -582,14 +579,12 @@ void __init setup_system(void) * related options that will be used by finish_device_tree() */ ppc_md.init_early(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* * "Finish" the device-tree, that is do the actual parsing of * some of the properties like the interrupt map */ finish_device_tree(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* * Initialize xmon @@ -597,31 +592,26 @@ void __init setup_system(void) #ifdef CONFIG_XMON_DEFAULT xmon_init(1); #endif - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* * Register early console */ register_early_udbg_console(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* Save unparsed command line copy for /proc/cmdline */ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); parse_early_param(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); #ifdef CONFIG_SMP /* * iSeries has already initialized the cpu maps at this point. */ setup_cpu_maps(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* Release secondary cpus out of their spinloops at 0x60 now that * we can map physical -> logical CPU ids */ smp_release_cpus(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); #endif printk("Starting Linux PPC64 %s\n", system_utsname.version); @@ -641,10 +631,8 @@ void __init setup_system(void) printk("htab_address = 0x%p\n", htab_address); printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); printk("-----------------------------------------------------\n"); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); mm_init_ppc64(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); DBG(" <- setup_system()\n"); } @@ -1016,7 +1004,6 @@ void __init setup_arch(char **cmdline_p) { extern void do_init_bootmem(void); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); ppc64_boot_msg(0x12, "Setup Arch"); *cmdline_p = cmd_line; @@ -1031,7 +1018,6 @@ void __init setup_arch(char **cmdline_p) /* reboot on panic */ panic_timeout = 180; - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); if (ppc_md.panic) notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); @@ -1044,14 +1030,12 @@ void __init setup_arch(char **cmdline_p) irqstack_early_init(); emergency_stack_init(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); stabs_alloc(); /* set up the bootmem stuff with available memory */ do_init_bootmem(); sparse_init(); - printk("%s:%d rtas.dev=%p\n", __FILE__, __LINE__, rtas.dev); /* initialize the syscall map in systemcfg */ setup_syscall_map(); From 35d81a4bfe28a6ea81c9f67c9ce40543124ded0b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 22:03:09 +1000 Subject: [PATCH 0268/1940] ppc: Adapt to asm-powerpc/irq.h irq_canonicalize changes Now instead of having a ppc_md function, we just have a variable which says whether to do the i8259 irq canonicalization or not, and set that variable on the platforms that need that. It looks to me that radstone_ppc7d was trying to use irq canonicalization for something else in a broken kind of way - it will need to be fixed properly. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/setup.c | 5 +++++ arch/ppc/platforms/chestnut.c | 1 - arch/ppc/platforms/chrp_setup.c | 10 +--------- arch/ppc/platforms/gemini_setup.c | 1 - arch/ppc/platforms/lopec.c | 11 +---------- arch/ppc/platforms/pmac_setup.c | 1 - arch/ppc/platforms/pplus.c | 10 +--------- arch/ppc/platforms/prep_setup.c | 15 +-------------- arch/ppc/platforms/radstone_ppc7d.c | 1 + arch/ppc/platforms/sandpoint.c | 11 +---------- arch/ppc/syslib/m8xx_setup.c | 1 - 11 files changed, 11 insertions(+), 56 deletions(-) diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 62022eacf63e..fae6335193ef 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -87,6 +87,11 @@ extern void chrp_init(unsigned long r3, unsigned long r4, dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ +#ifdef __DO_IRQ_CANON +int ppc_do_canonicalize_irqs; +EXPORT_SYMBOL(ppc_do_canonicalize_irqs); +#endif + #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY = 0x54; #endif /* CONFIG_MAGIC_SYSRQ */ diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c index 7786818bd9d0..b3d3bdb3936b 100644 --- a/arch/ppc/platforms/chestnut.c +++ b/arch/ppc/platforms/chestnut.c @@ -542,7 +542,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = chestnut_setup_arch; ppc_md.show_cpuinfo = chestnut_show_cpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = mv64360_init_irq; ppc_md.get_irq = mv64360_get_irq; ppc_md.init = NULL; diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 47b154c27617..a0cf1b6fdbfe 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -337,14 +337,6 @@ chrp_halt(void) chrp_power_off(); } -u_int -chrp_irq_canonicalize(u_int irq) -{ - if (irq == 2) - return 9; - return irq; -} - /* * Finds the open-pic node and sets OpenPIC_Addr based on its reg property. * Then checks if it has an interrupt-ranges property. If it does then @@ -500,6 +492,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; isa_io_base = CHRP_ISA_IO_BASE; /* default value */ + ppc_do_canonicalize_irqs = 1; if (root) machine = get_property(root, "model", NULL); @@ -518,7 +511,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.show_percpuinfo = of_show_percpuinfo; ppc_md.show_cpuinfo = chrp_show_cpuinfo; - ppc_md.irq_canonicalize = chrp_irq_canonicalize; ppc_md.init_IRQ = chrp_init_IRQ; if (_chrp_type == _CHRP_Pegasos) ppc_md.get_irq = i8259_irq; diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c index e391e52383c7..a8ed5c0a2980 100644 --- a/arch/ppc/platforms/gemini_setup.c +++ b/arch/ppc/platforms/gemini_setup.c @@ -556,7 +556,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = gemini_setup_arch; ppc_md.show_cpuinfo = gemini_show_cpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = gemini_init_IRQ; ppc_md.get_irq = openpic_get_irq; ppc_md.init = NULL; diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c index a5569525e0af..800c56a07a97 100644 --- a/arch/ppc/platforms/lopec.c +++ b/arch/ppc/platforms/lopec.c @@ -144,15 +144,6 @@ lopec_show_cpuinfo(struct seq_file *m) return 0; } -static u32 -lopec_irq_canonicalize(u32 irq) -{ - if (irq == 2) - return 9; - else - return irq; -} - static void lopec_restart(char *cmd) { @@ -379,10 +370,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ISA_DMA_THRESHOLD = 0x00ffffff; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + ppc_do_canonicalize_irqs = 1; ppc_md.setup_arch = lopec_setup_arch; ppc_md.show_cpuinfo = lopec_show_cpuinfo; - ppc_md.irq_canonicalize = lopec_irq_canonicalize; ppc_md.init_IRQ = lopec_init_IRQ; ppc_md.get_irq = openpic_get_irq; diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index e6a12182bfbb..8e7b79b110e7 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -662,7 +662,6 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = pmac_setup_arch; ppc_md.show_cpuinfo = pmac_show_cpuinfo; ppc_md.show_percpuinfo = pmac_show_percpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c index 65705c911795..93e9c7b889f7 100644 --- a/arch/ppc/platforms/pplus.c +++ b/arch/ppc/platforms/pplus.c @@ -647,14 +647,6 @@ static void pplus_power_off(void) pplus_halt(); } -static unsigned int pplus_irq_canonicalize(u_int irq) -{ - if (irq == 2) - return 9; - else - return irq; -} - static void __init pplus_init_IRQ(void) { int i; @@ -873,10 +865,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ISA_DMA_THRESHOLD = 0x00ffffff; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + ppc_do_canonicalize_irqs = 1; ppc_md.setup_arch = pplus_setup_arch; ppc_md.show_cpuinfo = pplus_show_cpuinfo; - ppc_md.irq_canonicalize = pplus_irq_canonicalize; ppc_md.init_IRQ = pplus_init_IRQ; /* this gets changed later on if we have an OpenPIC -- Cort */ ppc_md.get_irq = i8259_irq; diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 8bc734fe6682..490ff175c902 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -942,19 +942,6 @@ prep_calibrate_decr(void) todc_calibrate_decr(); } -static unsigned int -prep_irq_canonicalize(u_int irq) -{ - if (irq == 2) - { - return 9; - } - else - { - return irq; - } -} - static void __init prep_init_IRQ(void) { @@ -1110,6 +1097,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ISA_DMA_THRESHOLD = 0x00ffffff; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + ppc_do_canonicalize_irqs = 1; /* figure out what kind of prep workstation we are */ if (have_residual_data) { @@ -1136,7 +1124,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = prep_setup_arch; ppc_md.show_percpuinfo = prep_show_percpuinfo; ppc_md.show_cpuinfo = NULL; /* set in prep_setup_arch() */ - ppc_md.irq_canonicalize = prep_irq_canonicalize; ppc_md.init_IRQ = prep_init_IRQ; /* this gets changed later on if we have an OpenPIC -- Cort */ ppc_md.get_irq = i8259_irq; diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 06ec30f7e2f4..3cf74aa5fed0 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c @@ -1426,6 +1426,7 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = ppc7d_setup_arch; ppc_md.init = ppc7d_init2; ppc_md.show_cpuinfo = ppc7d_show_cpuinfo; + /* XXX this is broken... */ ppc_md.irq_canonicalize = ppc7d_irq_canonicalize; ppc_md.init_IRQ = ppc7d_init_irq; ppc_md.get_irq = ppc7d_get_irq; diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index 21e31346b12b..84c96cb9ac2b 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -509,15 +509,6 @@ sandpoint_init_IRQ(void) i8259_init(0xfef00000); } -static u32 -sandpoint_irq_canonicalize(u32 irq) -{ - if (irq == 2) - return 9; - else - return irq; -} - static unsigned long __init sandpoint_find_end_of_memory(void) { @@ -728,10 +719,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ISA_DMA_THRESHOLD = 0x00ffffff; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + ppc_do_canonicalize_irqs = 1; ppc_md.setup_arch = sandpoint_setup_arch; ppc_md.show_cpuinfo = sandpoint_show_cpuinfo; - ppc_md.irq_canonicalize = sandpoint_irq_canonicalize; ppc_md.init_IRQ = sandpoint_init_IRQ; ppc_md.get_irq = openpic_get_irq; diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index 4c888da89b3c..c88e2d4dceb7 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c @@ -406,7 +406,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = m8xx_setup_arch; ppc_md.show_percpuinfo = m8xx_show_percpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = m8xx_init_IRQ; ppc_md.get_irq = m8xx_get_irq; ppc_md.init = NULL; From fd582ec88eb8d2d907876603e4ecebe6eab330d9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 22:08:12 +1000 Subject: [PATCH 0269/1940] ppc: Various minor compile fixes This fixes up a variety of minor problems in compiling with ARCH=ppc arising from using the merged versions of various header files. A lot of the changes are just adding #include to files that use ppc_md or smp_ops_t. This also arranges for us to use semaphore.c, vecemu.c, vector.S and fpu.S from arch/powerpc/kernel when compiling with ARCH=ppc. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 12 ++++++++++-- arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/platforms/4xx/Makefile | 1 + arch/powerpc/platforms/85xx/Makefile | 1 + arch/ppc/Makefile | 5 +++-- arch/ppc/kernel/Makefile | 7 +------ arch/ppc/kernel/asm-offsets.c | 1 + arch/ppc/kernel/head.S | 2 +- arch/ppc/kernel/pci.c | 4 ++++ arch/ppc/kernel/process.c | 6 ++++-- arch/ppc/kernel/setup.c | 7 ++++++- arch/ppc/kernel/traps.c | 16 ++++++++++++++++ arch/ppc/platforms/chrp_smp.c | 1 + arch/ppc/platforms/ev64360.c | 1 + arch/ppc/platforms/gemini_setup.c | 1 + arch/ppc/platforms/katana.c | 1 + arch/ppc/platforms/lite5200.c | 1 + arch/ppc/platforms/pal4_setup.c | 1 + arch/ppc/platforms/pmac_pic.c | 1 + arch/ppc/syslib/gt64260_pic.c | 1 + arch/ppc/syslib/mpc52xx_pci.c | 1 + arch/ppc/syslib/mpc83xx_devices.c | 1 + arch/ppc/syslib/mv64360_pic.c | 1 + arch/ppc/syslib/mv64x60_dbg.c | 1 + arch/ppc/syslib/open_pic.c | 1 + arch/ppc/syslib/open_pic2.c | 1 + arch/ppc/syslib/ppc403_pic.c | 1 + arch/ppc/syslib/ppc4xx_pic.c | 1 + arch/ppc/syslib/ppc83xx_setup.c | 1 + arch/ppc/syslib/ppc85xx_setup.c | 1 + arch/ppc/syslib/pq2_devices.c | 1 + arch/ppc/syslib/xilinx_pic.c | 1 + arch/ppc/xmon/start.c | 3 ++- include/asm-powerpc/reg.h | 4 ++++ include/asm-ppc/system.h | 3 +++ 35 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 arch/powerpc/platforms/4xx/Makefile create mode 100644 arch/powerpc/platforms/85xx/Makefile diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 47a8eb6e7e39..e1db51e6f23a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -obj-y := semaphore.o traps.o +obj-y := semaphore.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o @@ -28,7 +28,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y += process.o init_task.o \ - prom.o systbl.o + prom.o systbl.o traps.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o @@ -39,4 +39,12 @@ ifeq ($(CONFIG_PPC_ISERIES),y) $(obj)/head_64.o: $(obj)/lparmap.s AFLAGS_head_64.o += -I$(obj) endif + +else +# stuff used from here for ARCH=ppc or ARCH=ppc64 +obj-$(CONFIG_PPC64) += traps.o + +fpux-$(CONFIG_PPC32) += fpu.o +extra-$(CONFIG_PPC_FPU) += $(fpux-y) + endif diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index ddf0c81e1958..b0d6a7cd85e9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -252,6 +252,7 @@ int main(void) DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); + DEFINE(TASK_SIZE, TASK_SIZE); DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); #else /* CONFIG_PPC64 */ /* systemcfg offsets for use by vdso */ diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile new file mode 100644 index 000000000000..79ff6b1e887c --- /dev/null +++ b/arch/powerpc/platforms/4xx/Makefile @@ -0,0 +1 @@ +# empty makefile so make clean works \ No newline at end of file diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile new file mode 100644 index 000000000000..6407197ffd89 --- /dev/null +++ b/arch/powerpc/platforms/85xx/Makefile @@ -0,0 +1 @@ +# empty makefile so make clean works diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 90c750227ed9..aedc9ae13b2a 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -57,9 +57,10 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o -head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o +head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o -core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ +core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ + arch/ppc/platforms/ \ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 74b30978619f..59b6b62d1120 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -10,12 +10,11 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_POWER4) += idle_power4.o -extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ - semaphore.o syscalls.o setup.o \ + syscalls.o setup.o \ cputable.o ppc_htab.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o @@ -26,7 +25,6 @@ obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o smp-tbsync.o obj-$(CONFIG_TAU) += temp.o -obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o ifndef CONFIG_E200 obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o endif @@ -37,9 +35,6 @@ obj-$(CONFIG_8xx) += softemu8xx.o endif # These are here while we do the architecture merge -vecemu-y += ../../powerpc/kernel/vecemu.o -vector-y += ../../powerpc/kernel/vector.o -fpu-y += ../../powerpc/kernel/fpu.o else obj-y := irq.o idle.o time.o \ diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c index d9ad1d776d0e..7972db1f6570 100644 --- a/arch/ppc/kernel/asm-offsets.c +++ b/arch/ppc/kernel/asm-offsets.c @@ -141,6 +141,7 @@ main(void) DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); + DEFINE(TASK_SIZE, TASK_SIZE); DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); return 0; } diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 2c3a1d34e3c7..5b43987a943b 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -467,7 +467,7 @@ FPUnavailable: EXCEPTION_PROLOG bne load_up_fpu /* if from user, just load it up */ addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_EE_LITE(0x800, KernelFP) + EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception) /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6600fd485b50..163276be7cc5 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1034,6 +1034,10 @@ static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *att } static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); +#else /* CONFIG_PPC_OF */ +void pcibios_make_OF_bus_map(void) +{ +} #endif /* CONFIG_PPC_OF */ /* Add sysfs properties */ diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 82de66e4db6d..0870e5553453 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -557,14 +557,16 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp); } -int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, +int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, struct pt_regs *regs) { CHECK_FULL_REGS(regs); return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL); } -int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, +int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, struct pt_regs *regs) { CHECK_FULL_REGS(regs); diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index fae6335193ef..6bcb85d2b7fd 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -87,6 +87,9 @@ extern void chrp_init(unsigned long r3, unsigned long r4, dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ +int have_of; +EXPORT_SYMBOL(have_of); + #ifdef __DO_IRQ_CANON int ppc_do_canonicalize_irqs; EXPORT_SYMBOL(ppc_do_canonicalize_irqs); @@ -420,6 +423,8 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, } #endif + have_of = 1; + /* prom_init has already been called from __start */ if (boot_infos) relocate_nodes(); @@ -735,7 +740,7 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_XMON - xmon_map_scc(); + xmon_init(1); if (strstr(cmd_line, "xmon")) xmon(NULL); #endif /* CONFIG_XMON */ diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 26606aa33de6..3145e9773db9 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -44,6 +44,11 @@ #include #ifdef CONFIG_XMON +extern int xmon_bpt(struct pt_regs *regs); +extern int xmon_sstep(struct pt_regs *regs); +extern int xmon_iabr_match(struct pt_regs *regs); +extern int xmon_dabr_match(struct pt_regs *regs); + void (*debugger)(struct pt_regs *regs) = xmon; int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt; int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep; @@ -814,6 +819,17 @@ void TAUException(struct pt_regs *regs) } #endif /* CONFIG_INT_TAU */ +/* + * FP unavailable trap from kernel - print a message, but let + * the task use FP in the kernel until it returns to user mode. + */ +void kernel_fp_unavailable_exception(struct pt_regs *regs) +{ + regs->msr |= MSR_FP; + printk(KERN_ERR "floating point used in kernel (task=%p, pc=%lx)\n", + current, regs->nip); +} + void altivec_unavailable_exception(struct pt_regs *regs) { static int kernel_altivec_count; diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c index dc62e3209443..97e539557ecb 100644 --- a/arch/ppc/platforms/chrp_smp.c +++ b/arch/ppc/platforms/chrp_smp.c @@ -31,6 +31,7 @@ #include #include #include +#include extern unsigned long smp_chrp_cpu_nr; diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c index 9811a8a52c25..53388a1c334f 100644 --- a/arch/ppc/platforms/ev64360.c +++ b/arch/ppc/platforms/ev64360.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #define BOARD_VENDOR "Marvell" diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c index a8ed5c0a2980..a2a09dc4b5e2 100644 --- a/arch/ppc/platforms/gemini_setup.c +++ b/arch/ppc/platforms/gemini_setup.c @@ -36,6 +36,7 @@ #include #include #include +#include void gemini_find_bridges(void); static int gemini_get_clock_speed(void); diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index 2b53afae0e9c..3eb611e23f69 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c @@ -42,6 +42,7 @@ #include #include #include +#include static struct mv64x60_handle bh; static katana_id_t katana_id; diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c index b604cf8b3cae..d44cc991179f 100644 --- a/arch/ppc/platforms/lite5200.c +++ b/arch/ppc/platforms/lite5200.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c index 12446b93e38c..f93a3f871932 100644 --- a/arch/ppc/platforms/pal4_setup.c +++ b/arch/ppc/platforms/pal4_setup.c @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 3349cfb624a0..9f2d95ea8564 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "pmac_pic.h" diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c index 44aa87385451..f97b3a9abd1e 100644 --- a/arch/ppc/syslib/gt64260_pic.c +++ b/arch/ppc/syslib/gt64260_pic.c @@ -45,6 +45,7 @@ #include #include #include +#include #define CPU_INTR_STR "gt64260 cpu interface error" #define PCI0_INTR_STR "gt64260 pci 0 error" diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c index 59cf3e8bd1a0..02edff8befd0 100644 --- a/arch/ppc/syslib/mpc52xx_pci.c +++ b/arch/ppc/syslib/mpc52xx_pci.c @@ -21,6 +21,7 @@ #include "mpc52xx_pci.h" #include +#include static int diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c index 95b3b8a7f0ba..dbf8acac507f 100644 --- a/arch/ppc/syslib/mpc83xx_devices.c +++ b/arch/ppc/syslib/mpc83xx_devices.c @@ -21,6 +21,7 @@ #include #include #include +#include /* We use offsets for IORESOURCE_MEM since we do not know at compile time * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c index 8356da4678a2..58b0aa813e85 100644 --- a/arch/ppc/syslib/mv64360_pic.c +++ b/arch/ppc/syslib/mv64360_pic.c @@ -48,6 +48,7 @@ #include #include #include +#include #ifdef CONFIG_IRQ_ALL_CPUS #error "The mv64360 does not support distribution of IRQs on all CPUs" diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c index 2927c7adf5e5..fa5b2e45e0ca 100644 --- a/arch/ppc/syslib/mv64x60_dbg.c +++ b/arch/ppc/syslib/mv64x60_dbg.c @@ -24,6 +24,7 @@ #include #include #include +#include #if defined(CONFIG_SERIAL_TEXT_DEBUG) diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 53da58523e39..df0f76dc0ce3 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "open_pic_defs.h" diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c index 9a7e8748e2b2..ef365cc04bd9 100644 --- a/arch/ppc/syslib/open_pic2.c +++ b/arch/ppc/syslib/open_pic2.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "open_pic_defs.h" diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c index ce4d1deb86e9..c46043c47225 100644 --- a/arch/ppc/syslib/ppc403_pic.c +++ b/arch/ppc/syslib/ppc403_pic.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Function Prototypes */ diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index 40086212b9c3..0b435633a0d1 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c @@ -25,6 +25,7 @@ #include #include #include +#include /* See comment in include/arch-ppc/ppc4xx_pic.h * for more info about these two variables diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index 890484e576e7..4da168a6ad03 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #if defined(CONFIG_PCI) diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 832b8bf99ae7..de2f90576577 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c index 1d3869768f96..6f88ba93412b 100644 --- a/arch/ppc/syslib/pq2_devices.c +++ b/arch/ppc/syslib/pq2_devices.c @@ -18,6 +18,7 @@ #include #include #include +#include struct platform_device ppc_sys_platform_devices[] = { [MPC82xx_CPM_FCC1] = { diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c index 2cbcad278cef..47f04c71fe9c 100644 --- a/arch/ppc/syslib/xilinx_pic.c +++ b/arch/ppc/syslib/xilinx_pic.c @@ -17,6 +17,7 @@ #include #include #include +#include /* No one else should require these constants, so define them locally here. */ #define ISR 0 /* Interrupt Status Register */ diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index 507d4eeffe07..98612d420346 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -478,8 +478,9 @@ void *xmon_stdout; void *xmon_stderr; void -xmon_init(void) +xmon_init(int arg) { + xmon_map_scc(); } int diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index ff619630dff9..06a1f0f2db21 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -74,7 +74,9 @@ #define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */ #define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */ #define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */ +#ifndef MSR_PMM #define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */ +#endif #define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */ #define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */ @@ -87,11 +89,13 @@ #else /* 32-bit */ /* Default MSR for kernel mode. */ +#ifndef MSR_KERNEL /* reg_booke.h also defines this */ #ifdef CONFIG_APUS_FAST_EXCEPT #define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR) #else #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) #endif +#endif #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) #endif diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 6a49b138c218..af93ff04c53f 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -77,6 +77,7 @@ extern void enable_kernel_fp(void); extern void enable_kernel_altivec(void); extern void giveup_altivec(struct task_struct *); extern void load_up_altivec(struct task_struct *); +extern int emulate_altivec(struct pt_regs *); extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern int fix_alignment(struct pt_regs *); @@ -89,6 +90,8 @@ extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); extern int die(const char *, struct pt_regs *, long); extern void _exception(int, struct pt_regs *, int, unsigned long); +void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); + #ifdef CONFIG_BOOKE_WDT extern u32 booke_wdt_enabled; extern u32 booke_wdt_period; From 3abec857a0f7491b397a97337cc057b84a1d637a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 22:09:48 +1000 Subject: [PATCH 0270/1940] ppc64: Use merged versions of init_task.c and process.c. These two files are now built in arch/powerpc/kernel instead of arch/ppc64/kernel. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/ppc64/kernel/Makefile | 4 +- arch/ppc64/kernel/init_task.c | 36 -- arch/ppc64/kernel/process.c | 713 ---------------------------------- include/asm-ppc64/system.h | 4 + 5 files changed, 7 insertions(+), 752 deletions(-) delete mode 100644 arch/ppc64/kernel/init_task.c delete mode 100644 arch/ppc64/kernel/process.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index e1db51e6f23a..931795380978 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -42,7 +42,7 @@ endif else # stuff used from here for ARCH=ppc or ARCH=ppc64 -obj-$(CONFIG_PPC64) += traps.o +obj-$(CONFIG_PPC64) += traps.o process.o init_task.o fpux-$(CONFIG_PPC32) += fpu.o extra-$(CONFIG_PPC_FPU) += $(fpux-y) diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 5c598892f891..5569ea7e6830 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -8,10 +8,10 @@ EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds obj-y := setup.o entry.o irq.o idle.o dma.o \ - time.o process.o signal.o syscalls.o misc.o ptrace.o \ + time.o signal.o syscalls.o misc.o ptrace.o \ align.o bitops.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ - ptrace32.o signal32.o rtc.o init_task.o \ + ptrace32.o signal32.o rtc.o \ cputable.o cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o obj-y += vdso32/ vdso64/ diff --git a/arch/ppc64/kernel/init_task.c b/arch/ppc64/kernel/init_task.c deleted file mode 100644 index 941043ae040f..000000000000 --- a/arch/ppc64/kernel/init_task.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -struct mm_struct init_mm = INIT_MM(init_mm); - -EXPORT_SYMBOL(init_mm); - -/* - * Initial thread structure. - * - * We need to make sure that this is 16384-byte aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry.. - */ -union thread_union init_thread_union - __attribute__((__section__(".data.init_task"))) = - { INIT_THREAD_INFO(init_task) }; - -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); - -EXPORT_SYMBOL(init_task); diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c deleted file mode 100644 index 887005358eb1..000000000000 --- a/arch/ppc64/kernel/process.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * linux/arch/ppc64/kernel/process.c - * - * Derived from "arch/i386/kernel/process.c" - * Copyright (C) 1995 Linus Torvalds - * - * Updated and modified by Cort Dougan (cort@cs.nmt.edu) and - * Paul Mackerras (paulus@cs.anu.edu.au) - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SMP -struct task_struct *last_task_used_math = NULL; -struct task_struct *last_task_used_altivec = NULL; -#endif - -/* - * Make sure the floating-point register state in the - * the thread_struct is up to date for task tsk. - */ -void flush_fp_to_thread(struct task_struct *tsk) -{ - if (tsk->thread.regs) { - /* - * We need to disable preemption here because if we didn't, - * another process could get scheduled after the regs->msr - * test but before we have finished saving the FP registers - * to the thread_struct. That process could take over the - * FPU, and then when we get scheduled again we would store - * bogus values for the remaining FP registers. - */ - preempt_disable(); - if (tsk->thread.regs->msr & MSR_FP) { -#ifdef CONFIG_SMP - /* - * This should only ever be called for current or - * for a stopped child process. Since we save away - * the FP register state on context switch on SMP, - * there is something wrong if a stopped child appears - * to still have its FP state in the CPU registers. - */ - BUG_ON(tsk != current); -#endif - giveup_fpu(current); - } - preempt_enable(); - } -} - -void enable_kernel_fp(void) -{ - WARN_ON(preemptible()); - -#ifdef CONFIG_SMP - if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) - giveup_fpu(current); - else - giveup_fpu(NULL); /* just enables FP for kernel */ -#else - giveup_fpu(last_task_used_math); -#endif /* CONFIG_SMP */ -} -EXPORT_SYMBOL(enable_kernel_fp); - -int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) -{ - if (!tsk->thread.regs) - return 0; - flush_fp_to_thread(current); - - memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); - - return 1; -} - -#ifdef CONFIG_ALTIVEC - -void enable_kernel_altivec(void) -{ - WARN_ON(preemptible()); - -#ifdef CONFIG_SMP - if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) - giveup_altivec(current); - else - giveup_altivec(NULL); /* just enables FP for kernel */ -#else - giveup_altivec(last_task_used_altivec); -#endif /* CONFIG_SMP */ -} -EXPORT_SYMBOL(enable_kernel_altivec); - -/* - * Make sure the VMX/Altivec register state in the - * the thread_struct is up to date for task tsk. - */ -void flush_altivec_to_thread(struct task_struct *tsk) -{ - if (tsk->thread.regs) { - preempt_disable(); - if (tsk->thread.regs->msr & MSR_VEC) { -#ifdef CONFIG_SMP - BUG_ON(tsk != current); -#endif - giveup_altivec(current); - } - preempt_enable(); - } -} - -int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) -{ - flush_altivec_to_thread(current); - memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); - return 1; -} - -#endif /* CONFIG_ALTIVEC */ - -static void set_dabr_spr(unsigned long val) -{ - mtspr(SPRN_DABR, val); -} - -int set_dabr(unsigned long dabr) -{ - int ret = 0; - - if (firmware_has_feature(FW_FEATURE_XDABR)) { - /* We want to catch accesses from kernel and userspace */ - unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER; - ret = plpar_set_xdabr(dabr, flags); - } else if (firmware_has_feature(FW_FEATURE_DABR)) { - ret = plpar_set_dabr(dabr); - } else { - set_dabr_spr(dabr); - } - - return ret; -} - -DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); -static DEFINE_PER_CPU(unsigned long, current_dabr); - -struct task_struct *__switch_to(struct task_struct *prev, - struct task_struct *new) -{ - struct thread_struct *new_thread, *old_thread; - unsigned long flags; - struct task_struct *last; - -#ifdef CONFIG_SMP - /* avoid complexity of lazy save/restore of fpu - * by just saving it every time we switch out if - * this task used the fpu during the last quantum. - * - * If it tries to use the fpu again, it'll trap and - * reload its fp regs. So we don't have to do a restore - * every switch, just a save. - * -- Cort - */ - if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP)) - giveup_fpu(prev); -#ifdef CONFIG_ALTIVEC - if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) - giveup_altivec(prev); -#endif /* CONFIG_ALTIVEC */ -#endif /* CONFIG_SMP */ - -#if defined(CONFIG_ALTIVEC) && !defined(CONFIG_SMP) - /* Avoid the trap. On smp this this never happens since - * we don't set last_task_used_altivec -- Cort - */ - if (new->thread.regs && last_task_used_altivec == new) - new->thread.regs->msr |= MSR_VEC; -#endif /* CONFIG_ALTIVEC */ - - if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) { - set_dabr(new->thread.dabr); - __get_cpu_var(current_dabr) = new->thread.dabr; - } - - flush_tlb_pending(); - - new_thread = &new->thread; - old_thread = ¤t->thread; - - /* Collect purr utilization data per process and per processor - * wise purr is nothing but processor time base - */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); - long unsigned start_tb, current_tb; - start_tb = old_thread->start_tb; - cu->current_tb = current_tb = mfspr(SPRN_PURR); - old_thread->accum_tb += (current_tb - start_tb); - new_thread->start_tb = current_tb; - } - - local_irq_save(flags); - last = _switch(old_thread, new_thread); - - local_irq_restore(flags); - - return last; -} - -static int instructions_to_print = 16; - -static void show_instructions(struct pt_regs *regs) -{ - int i; - unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 * - sizeof(int)); - - printk("Instruction dump:"); - - for (i = 0; i < instructions_to_print; i++) { - int instr; - - if (!(i % 8)) - printk("\n"); - - if (((REGION_ID(pc) != KERNEL_REGION_ID) && - (REGION_ID(pc) != VMALLOC_REGION_ID)) || - __get_user(instr, (unsigned int *)pc)) { - printk("XXXXXXXX "); - } else { - if (regs->nip == pc) - printk("<%08x> ", instr); - else - printk("%08x ", instr); - } - - pc += sizeof(int); - } - - printk("\n"); -} - -void show_regs(struct pt_regs * regs) -{ - int i; - unsigned long trap; - - printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n", - regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr); - printk("REGS: %p TRAP: %04lx %s (%s)\n", - regs, regs->trap, print_tainted(), system_utsname.release); - printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x " - "IR/DR: %01x%01x CR: %08X\n", - regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, - regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, - regs->msr&MSR_IR ? 1 : 0, - regs->msr&MSR_DR ? 1 : 0, - (unsigned int)regs->ccr); - trap = TRAP(regs); - printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr); - printk("TASK: %p[%d] '%s' THREAD: %p", - current, current->pid, current->comm, current->thread_info); - -#ifdef CONFIG_SMP - printk(" CPU: %d", smp_processor_id()); -#endif /* CONFIG_SMP */ - - for (i = 0; i < 32; i++) { - if ((i % 4) == 0) { - printk("\n" KERN_INFO "GPR%02d: ", i); - } - - printk("%016lX ", regs->gpr[i]); - if (i == 13 && !FULL_REGS(regs)) - break; - } - printk("\n"); - /* - * Lookup NIP late so we have the best change of getting the - * above info out without failing - */ - printk("NIP [%016lx] ", regs->nip); - print_symbol("%s\n", regs->nip); - printk("LR [%016lx] ", regs->link); - print_symbol("%s\n", regs->link); - show_stack(current, (unsigned long *)regs->gpr[1]); - if (!user_mode(regs)) - show_instructions(regs); -} - -void exit_thread(void) -{ - kprobe_flush_task(current); - -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif /* CONFIG_ALTIVEC */ -#endif /* CONFIG_SMP */ -} - -void flush_thread(void) -{ - struct thread_info *t = current_thread_info(); - - kprobe_flush_task(current); - if (t->flags & _TIF_ABI_PENDING) - t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); - -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif /* CONFIG_ALTIVEC */ -#endif /* CONFIG_SMP */ - - if (current->thread.dabr) { - current->thread.dabr = 0; - set_dabr(0); - } -} - -void -release_thread(struct task_struct *t) -{ -} - - -/* - * This gets called before we allocate a new thread and copy - * the current task into it. - */ -void prepare_to_copy(struct task_struct *tsk) -{ - flush_fp_to_thread(current); - flush_altivec_to_thread(current); -} - -/* - * Copy a thread.. - */ -int -copy_thread(int nr, unsigned long clone_flags, unsigned long usp, - unsigned long unused, struct task_struct *p, struct pt_regs *regs) -{ - struct pt_regs *childregs, *kregs; - extern void ret_from_fork(void); - unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE; - - /* Copy registers */ - sp -= sizeof(struct pt_regs); - childregs = (struct pt_regs *) sp; - *childregs = *regs; - if ((childregs->msr & MSR_PR) == 0) { - /* for kernel thread, set stackptr in new task */ - childregs->gpr[1] = sp + sizeof(struct pt_regs); - p->thread.regs = NULL; /* no user register state */ - clear_ti_thread_flag(p->thread_info, TIF_32BIT); - } else { - childregs->gpr[1] = usp; - p->thread.regs = childregs; - if (clone_flags & CLONE_SETTLS) { - if (test_thread_flag(TIF_32BIT)) - childregs->gpr[2] = childregs->gpr[6]; - else - childregs->gpr[13] = childregs->gpr[6]; - } - } - childregs->gpr[3] = 0; /* Result from fork() */ - sp -= STACK_FRAME_OVERHEAD; - - /* - * The way this works is that at some point in the future - * some task will call _switch to switch to the new task. - * That will pop off the stack frame created below and start - * the new task running at ret_from_fork. The new task will - * do some house keeping and then return from the fork or clone - * system call, using the stack frame created above. - */ - sp -= sizeof(struct pt_regs); - kregs = (struct pt_regs *) sp; - sp -= STACK_FRAME_OVERHEAD; - p->thread.ksp = sp; - if (cpu_has_feature(CPU_FTR_SLB)) { - unsigned long sp_vsid = get_kernel_vsid(sp); - - sp_vsid <<= SLB_VSID_SHIFT; - sp_vsid |= SLB_VSID_KERNEL; - if (cpu_has_feature(CPU_FTR_16M_PAGE)) - sp_vsid |= SLB_VSID_L; - - p->thread.ksp_vsid = sp_vsid; - } - - /* - * The PPC64 ABI makes use of a TOC to contain function - * pointers. The function (ret_from_except) is actually a pointer - * to the TOC entry. The first entry is a pointer to the actual - * function. - */ - kregs->nip = *((unsigned long *)ret_from_fork); - - return 0; -} - -/* - * Set up a thread for executing a new program - */ -void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp) -{ - unsigned long entry, toc, load_addr = regs->gpr[2]; - - /* fdptr is a relocated pointer to the function descriptor for - * the elf _start routine. The first entry in the function - * descriptor is the entry address of _start and the second - * entry is the TOC value we need to use. - */ - set_fs(USER_DS); - __get_user(entry, (unsigned long __user *)fdptr); - __get_user(toc, (unsigned long __user *)fdptr+1); - - /* Check whether the e_entry function descriptor entries - * need to be relocated before we can use them. - */ - if (load_addr != 0) { - entry += load_addr; - toc += load_addr; - } - - /* - * If we exec out of a kernel thread then thread.regs will not be - * set. Do it now. - */ - if (!current->thread.regs) { - unsigned long childregs = (unsigned long)current->thread_info + - THREAD_SIZE; - childregs -= sizeof(struct pt_regs); - current->thread.regs = (struct pt_regs *)childregs; - } - - regs->nip = entry; - regs->gpr[1] = sp; - regs->gpr[2] = toc; - regs->msr = MSR_USER64; -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = 0; -#endif /* CONFIG_SMP */ - memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); - current->thread.fpscr = 0; -#ifdef CONFIG_ALTIVEC -#ifndef CONFIG_SMP - if (last_task_used_altivec == current) - last_task_used_altivec = 0; -#endif /* CONFIG_SMP */ - memset(current->thread.vr, 0, sizeof(current->thread.vr)); - current->thread.vscr.u[0] = 0; - current->thread.vscr.u[1] = 0; - current->thread.vscr.u[2] = 0; - current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ - current->thread.vrsave = 0; - current->thread.used_vr = 0; -#endif /* CONFIG_ALTIVEC */ -} -EXPORT_SYMBOL(start_thread); - -int set_fpexc_mode(struct task_struct *tsk, unsigned int val) -{ - struct pt_regs *regs = tsk->thread.regs; - - if (val > PR_FP_EXC_PRECISE) - return -EINVAL; - tsk->thread.fpexc_mode = __pack_fe01(val); - if (regs != NULL && (regs->msr & MSR_FP) != 0) - regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) - | tsk->thread.fpexc_mode; - return 0; -} - -int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) -{ - unsigned int val; - - val = __unpack_fe01(tsk->thread.fpexc_mode); - return put_user(val, (unsigned int __user *) adr); -} - -int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs) -{ - unsigned long parent_tidptr = 0; - unsigned long child_tidptr = 0; - - if (p2 == 0) - p2 = regs->gpr[1]; /* stack pointer for child */ - - if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | - CLONE_CHILD_CLEARTID)) { - parent_tidptr = p3; - child_tidptr = p5; - if (test_thread_flag(TIF_32BIT)) { - parent_tidptr &= 0xffffffff; - child_tidptr &= 0xffffffff; - } - } - - return do_fork(clone_flags, p2, regs, 0, - (int __user *)parent_tidptr, (int __user *)child_tidptr); -} - -int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs) -{ - return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL); -} - -int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, - unsigned long p4, unsigned long p5, unsigned long p6, - struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0, - NULL, NULL); -} - -int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs *regs) -{ - int error; - char * filename; - - filename = getname((char __user *) a0); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - error = do_execve(filename, (char __user * __user *) a1, - (char __user * __user *) a2, regs); - - if (error == 0) { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - } - putname(filename); - -out: - return error; -} - -static int kstack_depth_to_print = 64; - -static int validate_sp(unsigned long sp, struct task_struct *p, - unsigned long nbytes) -{ - unsigned long stack_page = (unsigned long)p->thread_info; - - if (sp >= stack_page + sizeof(struct thread_struct) - && sp <= stack_page + THREAD_SIZE - nbytes) - return 1; - -#ifdef CONFIG_IRQSTACKS - stack_page = (unsigned long) hardirq_ctx[task_cpu(p)]; - if (sp >= stack_page + sizeof(struct thread_struct) - && sp <= stack_page + THREAD_SIZE - nbytes) - return 1; - - stack_page = (unsigned long) softirq_ctx[task_cpu(p)]; - if (sp >= stack_page + sizeof(struct thread_struct) - && sp <= stack_page + THREAD_SIZE - nbytes) - return 1; -#endif - - return 0; -} - -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long ip, sp; - int count = 0; - - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - sp = p->thread.ksp; - if (!validate_sp(sp, p, 112)) - return 0; - - do { - sp = *(unsigned long *)sp; - if (!validate_sp(sp, p, 112)) - return 0; - if (count > 0) { - ip = *(unsigned long *)(sp + 16); - if (!in_sched_functions(ip)) - return ip; - } - } while (count++ < 16); - return 0; -} -EXPORT_SYMBOL(get_wchan); - -void show_stack(struct task_struct *p, unsigned long *_sp) -{ - unsigned long ip, newsp, lr; - int count = 0; - unsigned long sp = (unsigned long)_sp; - int firstframe = 1; - - if (sp == 0) { - if (p) { - sp = p->thread.ksp; - } else { - sp = __get_SP(); - p = current; - } - } - - lr = 0; - printk("Call Trace:\n"); - do { - if (!validate_sp(sp, p, 112)) - return; - - _sp = (unsigned long *) sp; - newsp = _sp[0]; - ip = _sp[2]; - if (!firstframe || ip != lr) { - printk("[%016lx] [%016lx] ", sp, ip); - print_symbol("%s", ip); - if (firstframe) - printk(" (unreliable)"); - printk("\n"); - } - firstframe = 0; - - /* - * See if this is an exception frame. - * We look for the "regshere" marker in the current frame. - */ - if (validate_sp(sp, p, sizeof(struct pt_regs) + 400) - && _sp[12] == 0x7265677368657265ul) { - struct pt_regs *regs = (struct pt_regs *) - (sp + STACK_FRAME_OVERHEAD); - printk("--- Exception: %lx", regs->trap); - print_symbol(" at %s\n", regs->nip); - lr = regs->link; - print_symbol(" LR = %s\n", lr); - firstframe = 1; - } - - sp = newsp; - } while (count++ < kstack_depth_to_print); -} - -void dump_stack(void) -{ - show_stack(current, (unsigned long *)__get_SP()); -} -EXPORT_SYMBOL(dump_stack); diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index c04d62c592a6..d1e00933354c 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -131,6 +131,10 @@ static inline void flush_altivec_to_thread(struct task_struct *t) } #endif +static inline void flush_spe_to_thread(struct task_struct *t) +{ +} + extern int mem_init_done; /* set on boot once kmalloc can be called */ /* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */ From f696012330a67a60a9822ed48d1e9ecba73b4f18 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Oct 2005 22:10:49 +1000 Subject: [PATCH 0271/1940] ppc64: compile fix - define execve in misc.S This used to be inline in include/asm-ppc64/unistd.h, but isn't inline in the merged include/asm-powerpc/unistd.h, so we need a definition here. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/misc.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index d069bbd7f81f..f9f2131d2fb5 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -740,6 +740,13 @@ _GLOBAL(giveup_altivec) _GLOBAL(__setup_cpu_power3) blr +_GLOBAL(execve) + li r0,__NR_execve + sc + bnslr + neg r3,r3 + blr + /* kexec_wait(phys_cpu) * * wait for the flag to change, indicating this kernel is going away but From 29b8990513b077dc388b0756acd31465e5c21441 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 11 Oct 2005 14:54:42 +0100 Subject: [PATCH 0272/1940] NTFS: In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited() and cond_resched() in the main loop as we could be dirtying a lot of pages and this ensures we play nice with the VM and the system as a whole. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 4 ++++ fs/ntfs/attrib.c | 4 ++++ fs/ntfs/malloc.h | 3 +-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 9f4674a026f2..3b8ff2318085 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -57,6 +57,10 @@ ToDo/Notes: uncompressed and unencrypted files are supported. Also, there is only very limited support for highly fragmented files (the ones whose $DATA attribute is split into multiple attribute extents). + - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited() + and cond_resched() in the main loop as we could be dirtying a lot of + pages and this ensures we play nice with the VM and the system as a + whole. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index bc25e88ad468..338e47144fc9 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -21,7 +21,9 @@ */ #include +#include #include +#include #include "attrib.h" #include "debug.h" @@ -2590,6 +2592,8 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val) /* Finally unlock and release the page. */ unlock_page(page); page_cache_release(page); + balance_dirty_pages_ratelimited(mapping); + cond_resched(); } /* If there is a last partial page, need to do it the slow way. */ if (end_ofs) { diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h index 590887b943f5..e38e402e4103 100644 --- a/fs/ntfs/malloc.h +++ b/fs/ntfs/malloc.h @@ -39,8 +39,7 @@ * If there was insufficient memory to complete the request, return NULL. * Depending on @gfp_mask the allocation may be guaranteed to succeed. */ -static inline void *__ntfs_malloc(unsigned long size, - gfp_t gfp_mask) +static inline void *__ntfs_malloc(unsigned long size, gfp_t gfp_mask) { if (likely(size <= PAGE_SIZE)) { BUG_ON(!size); From 29f5f3c141c58b0a4c0765c77da612271875bcce Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 11 Oct 2005 14:59:40 +0100 Subject: [PATCH 0273/1940] NTFS: Remove address space operations ->prepare_write and ->commit_write in preparation for the big rewrite of write(2) support in ntfs. Signed-off-by: Anton Altaparmakov --- fs/ntfs/aops.c | 827 ------------------------------------------------- 1 file changed, 827 deletions(-) diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 5e80c07c6a4d..8f23c60030c0 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1542,830 +1542,6 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) return err; } -/** - * ntfs_prepare_nonresident_write - - * - */ -static int ntfs_prepare_nonresident_write(struct page *page, - unsigned from, unsigned to) -{ - VCN vcn; - LCN lcn; - s64 initialized_size; - loff_t i_size; - sector_t block, ablock, iblock; - struct inode *vi; - ntfs_inode *ni; - ntfs_volume *vol; - runlist_element *rl; - struct buffer_head *bh, *head, *wait[2], **wait_bh = wait; - unsigned long flags; - unsigned int vcn_ofs, block_start, block_end, blocksize; - int err; - BOOL is_retry; - unsigned char blocksize_bits; - - vi = page->mapping->host; - ni = NTFS_I(vi); - vol = ni->vol; - - ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " - "0x%lx, from = %u, to = %u.", ni->mft_no, ni->type, - page->index, from, to); - - BUG_ON(!NInoNonResident(ni)); - - blocksize_bits = vi->i_blkbits; - blocksize = 1 << blocksize_bits; - - /* - * create_empty_buffers() will create uptodate/dirty buffers if the - * page is uptodate/dirty. - */ - if (!page_has_buffers(page)) - create_empty_buffers(page, blocksize, 0); - bh = head = page_buffers(page); - if (unlikely(!bh)) - return -ENOMEM; - - /* The first block in the page. */ - block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); - - read_lock_irqsave(&ni->size_lock, flags); - /* - * The first out of bounds block for the allocated size. No need to - * round up as allocated_size is in multiples of cluster size and the - * minimum cluster size is 512 bytes, which is equal to the smallest - * blocksize. - */ - ablock = ni->allocated_size >> blocksize_bits; - i_size = i_size_read(vi); - initialized_size = ni->initialized_size; - read_unlock_irqrestore(&ni->size_lock, flags); - - /* The last (fully or partially) initialized block. */ - iblock = initialized_size >> blocksize_bits; - - /* Loop through all the buffers in the page. */ - block_start = 0; - rl = NULL; - err = 0; - do { - block_end = block_start + blocksize; - /* - * If buffer @bh is outside the write, just mark it uptodate - * if the page is uptodate and continue with the next buffer. - */ - if (block_end <= from || block_start >= to) { - if (PageUptodate(page)) { - if (!buffer_uptodate(bh)) - set_buffer_uptodate(bh); - } - continue; - } - /* - * @bh is at least partially being written to. - * Make sure it is not marked as new. - */ - //if (buffer_new(bh)) - // clear_buffer_new(bh); - - if (block >= ablock) { - // TODO: block is above allocated_size, need to - // allocate it. Best done in one go to accommodate not - // only block but all above blocks up to and including: - // ((page->index << PAGE_CACHE_SHIFT) + to + blocksize - // - 1) >> blobksize_bits. Obviously will need to round - // up to next cluster boundary, too. This should be - // done with a helper function, so it can be reused. - ntfs_error(vol->sb, "Writing beyond allocated size " - "is not supported yet. Sorry."); - err = -EOPNOTSUPP; - goto err_out; - // Need to update ablock. - // Need to set_buffer_new() on all block bhs that are - // newly allocated. - } - /* - * Now we have enough allocated size to fulfill the whole - * request, i.e. block < ablock is true. - */ - if (unlikely((block >= iblock) && - (initialized_size < i_size))) { - /* - * If this page is fully outside initialized size, zero - * out all pages between the current initialized size - * and the current page. Just use ntfs_readpage() to do - * the zeroing transparently. - */ - if (block > iblock) { - // TODO: - // For each page do: - // - read_cache_page() - // Again for each page do: - // - wait_on_page_locked() - // - Check (PageUptodate(page) && - // !PageError(page)) - // Update initialized size in the attribute and - // in the inode. - // Again, for each page do: - // __set_page_dirty_buffers(); - // page_cache_release() - // We don't need to wait on the writes. - // Update iblock. - } - /* - * The current page straddles initialized size. Zero - * all non-uptodate buffers and set them uptodate (and - * dirty?). Note, there aren't any non-uptodate buffers - * if the page is uptodate. - * FIXME: For an uptodate page, the buffers may need to - * be written out because they were not initialized on - * disk before. - */ - if (!PageUptodate(page)) { - // TODO: - // Zero any non-uptodate buffers up to i_size. - // Set them uptodate and dirty. - } - // TODO: - // Update initialized size in the attribute and in the - // inode (up to i_size). - // Update iblock. - // FIXME: This is inefficient. Try to batch the two - // size changes to happen in one go. - ntfs_error(vol->sb, "Writing beyond initialized size " - "is not supported yet. Sorry."); - err = -EOPNOTSUPP; - goto err_out; - // Do NOT set_buffer_new() BUT DO clear buffer range - // outside write request range. - // set_buffer_uptodate() on complete buffers as well as - // set_buffer_dirty(). - } - - /* Need to map unmapped buffers. */ - if (!buffer_mapped(bh)) { - /* Unmapped buffer. Need to map it. */ - bh->b_bdev = vol->sb->s_bdev; - - /* Convert block into corresponding vcn and offset. */ - vcn = (VCN)block << blocksize_bits >> - vol->cluster_size_bits; - vcn_ofs = ((VCN)block << blocksize_bits) & - vol->cluster_size_mask; - - is_retry = FALSE; - if (!rl) { -lock_retry_remap: - down_read(&ni->runlist.lock); - rl = ni->runlist.rl; - } - if (likely(rl != NULL)) { - /* Seek to element containing target vcn. */ - while (rl->length && rl[1].vcn <= vcn) - rl++; - lcn = ntfs_rl_vcn_to_lcn(rl, vcn); - } else - lcn = LCN_RL_NOT_MAPPED; - if (unlikely(lcn < 0)) { - /* - * We extended the attribute allocation above. - * If we hit an ENOENT here it means that the - * allocation was insufficient which is a bug. - */ - BUG_ON(lcn == LCN_ENOENT); - - /* It is a hole, need to instantiate it. */ - if (lcn == LCN_HOLE) { - // TODO: Instantiate the hole. - // clear_buffer_new(bh); - // unmap_underlying_metadata(bh->b_bdev, - // bh->b_blocknr); - // For non-uptodate buffers, need to - // zero out the region outside the - // request in this bh or all bhs, - // depending on what we implemented - // above. - // Need to flush_dcache_page(). - // Or could use set_buffer_new() - // instead? - ntfs_error(vol->sb, "Writing into " - "sparse regions is " - "not supported yet. " - "Sorry."); - err = -EOPNOTSUPP; - if (!rl) - up_read(&ni->runlist.lock); - goto err_out; - } else if (!is_retry && - lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; - /* - * Attempt to map runlist, dropping - * lock for the duration. - */ - up_read(&ni->runlist.lock); - err = ntfs_map_runlist(ni, vcn); - if (likely(!err)) - goto lock_retry_remap; - rl = NULL; - } else if (!rl) - up_read(&ni->runlist.lock); - /* - * Failed to map the buffer, even after - * retrying. - */ - if (!err) - err = -EIO; - bh->b_blocknr = -1; - ntfs_error(vol->sb, "Failed to write to inode " - "0x%lx, attribute type 0x%x, " - "vcn 0x%llx, offset 0x%x " - "because its location on disk " - "could not be determined%s " - "(error code %i).", - ni->mft_no, ni->type, - (unsigned long long)vcn, - vcn_ofs, is_retry ? " even " - "after retrying" : "", err); - goto err_out; - } - /* We now have a successful remap, i.e. lcn >= 0. */ - - /* Setup buffer head to correct block. */ - bh->b_blocknr = ((lcn << vol->cluster_size_bits) - + vcn_ofs) >> blocksize_bits; - set_buffer_mapped(bh); - - // FIXME: Something analogous to this is needed for - // each newly allocated block, i.e. BH_New. - // FIXME: Might need to take this out of the - // if (!buffer_mapped(bh)) {}, depending on how we - // implement things during the allocated_size and - // initialized_size extension code above. - if (buffer_new(bh)) { - clear_buffer_new(bh); - unmap_underlying_metadata(bh->b_bdev, - bh->b_blocknr); - if (PageUptodate(page)) { - set_buffer_uptodate(bh); - continue; - } - /* - * Page is _not_ uptodate, zero surrounding - * region. NOTE: This is how we decide if to - * zero or not! - */ - if (block_end > to || block_start < from) { - void *kaddr; - - kaddr = kmap_atomic(page, KM_USER0); - if (block_end > to) - memset(kaddr + to, 0, - block_end - to); - if (block_start < from) - memset(kaddr + block_start, 0, - from - - block_start); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - } - continue; - } - } - /* @bh is mapped, set it uptodate if the page is uptodate. */ - if (PageUptodate(page)) { - if (!buffer_uptodate(bh)) - set_buffer_uptodate(bh); - continue; - } - /* - * The page is not uptodate. The buffer is mapped. If it is not - * uptodate, and it is only partially being written to, we need - * to read the buffer in before the write, i.e. right now. - */ - if (!buffer_uptodate(bh) && - (block_start < from || block_end > to)) { - ll_rw_block(READ, 1, &bh); - *wait_bh++ = bh; - } - } while (block++, block_start = block_end, - (bh = bh->b_this_page) != head); - - /* Release the lock if we took it. */ - if (rl) { - up_read(&ni->runlist.lock); - rl = NULL; - } - - /* If we issued read requests, let them complete. */ - while (wait_bh > wait) { - wait_on_buffer(*--wait_bh); - if (!buffer_uptodate(*wait_bh)) - return -EIO; - } - - ntfs_debug("Done."); - return 0; -err_out: - /* - * Zero out any newly allocated blocks to avoid exposing stale data. - * If BH_New is set, we know that the block was newly allocated in the - * above loop. - * FIXME: What about initialized_size increments? Have we done all the - * required zeroing above? If not this error handling is broken, and - * in particular the if (block_end <= from) check is completely bogus. - */ - bh = head; - block_start = 0; - is_retry = FALSE; - do { - block_end = block_start + blocksize; - if (block_end <= from) - continue; - if (block_start >= to) - break; - if (buffer_new(bh)) { - void *kaddr; - - clear_buffer_new(bh); - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + block_start, 0, bh->b_size); - kunmap_atomic(kaddr, KM_USER0); - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - is_retry = TRUE; - } - } while (block_start = block_end, (bh = bh->b_this_page) != head); - if (is_retry) - flush_dcache_page(page); - if (rl) - up_read(&ni->runlist.lock); - return err; -} - -/** - * ntfs_prepare_write - prepare a page for receiving data - * - * This is called from generic_file_write() with i_sem held on the inode - * (@page->mapping->host). The @page is locked but not kmap()ped. The source - * data has not yet been copied into the @page. - * - * Need to extend the attribute/fill in holes if necessary, create blocks and - * make partially overwritten blocks uptodate, - * - * i_size is not to be modified yet. - * - * Return 0 on success or -errno on error. - * - * Should be using block_prepare_write() [support for sparse files] or - * cont_prepare_write() [no support for sparse files]. Cannot do that due to - * ntfs specifics but can look at them for implementation guidance. - * - * Note: In the range, @from is inclusive and @to is exclusive, i.e. @from is - * the first byte in the page that will be written to and @to is the first byte - * after the last byte that will be written to. - */ -static int ntfs_prepare_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - s64 new_size; - loff_t i_size; - struct inode *vi = page->mapping->host; - ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); - ntfs_volume *vol = ni->vol; - ntfs_attr_search_ctx *ctx = NULL; - MFT_RECORD *m = NULL; - ATTR_RECORD *a; - u8 *kaddr; - u32 attr_len; - int err; - - ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " - "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type, - page->index, from, to); - BUG_ON(!PageLocked(page)); - BUG_ON(from > PAGE_CACHE_SIZE); - BUG_ON(to > PAGE_CACHE_SIZE); - BUG_ON(from > to); - BUG_ON(NInoMstProtected(ni)); - /* - * If a previous ntfs_truncate() failed, repeat it and abort if it - * fails again. - */ - if (unlikely(NInoTruncateFailed(ni))) { - down_write(&vi->i_alloc_sem); - err = ntfs_truncate(vi); - up_write(&vi->i_alloc_sem); - if (err || NInoTruncateFailed(ni)) { - if (!err) - err = -EIO; - goto err_out; - } - } - /* If the attribute is not resident, deal with it elsewhere. */ - if (NInoNonResident(ni)) { - /* - * Only unnamed $DATA attributes can be compressed, encrypted, - * and/or sparse. - */ - if (ni->type == AT_DATA && !ni->name_len) { - /* If file is encrypted, deny access, just like NT4. */ - if (NInoEncrypted(ni)) { - ntfs_debug("Denying write access to encrypted " - "file."); - return -EACCES; - } - /* Compressed data streams are handled in compress.c. */ - if (NInoCompressed(ni)) { - // TODO: Implement and replace this check with - // return ntfs_write_compressed_block(page); - ntfs_error(vi->i_sb, "Writing to compressed " - "files is not supported yet. " - "Sorry."); - return -EOPNOTSUPP; - } - // TODO: Implement and remove this check. - if (NInoSparse(ni)) { - ntfs_error(vi->i_sb, "Writing to sparse files " - "is not supported yet. Sorry."); - return -EOPNOTSUPP; - } - } - /* Normal data stream. */ - return ntfs_prepare_nonresident_write(page, from, to); - } - /* - * Attribute is resident, implying it is not compressed, encrypted, or - * sparse. - */ - BUG_ON(page_has_buffers(page)); - new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to; - /* If we do not need to resize the attribute allocation we are done. */ - if (new_size <= i_size_read(vi)) - goto done; - /* Map, pin, and lock the (base) mft record. */ - if (!NInoAttr(ni)) - base_ni = ni; - else - base_ni = ni->ext.base_ntfs_ino; - m = map_mft_record(base_ni); - if (IS_ERR(m)) { - err = PTR_ERR(m); - m = NULL; - ctx = NULL; - goto err_out; - } - ctx = ntfs_attr_get_search_ctx(base_ni, m); - if (unlikely(!ctx)) { - err = -ENOMEM; - goto err_out; - } - err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx); - if (unlikely(err)) { - if (err == -ENOENT) - err = -EIO; - goto err_out; - } - m = ctx->mrec; - a = ctx->attr; - /* The total length of the attribute value. */ - attr_len = le32_to_cpu(a->data.resident.value_length); - /* Fix an eventual previous failure of ntfs_commit_write(). */ - i_size = i_size_read(vi); - if (unlikely(attr_len > i_size)) { - attr_len = i_size; - a->data.resident.value_length = cpu_to_le32(attr_len); - } - /* If we do not need to resize the attribute allocation we are done. */ - if (new_size <= attr_len) - goto done_unm; - /* Check if new size is allowed in $AttrDef. */ - err = ntfs_attr_size_bounds_check(vol, ni->type, new_size); - if (unlikely(err)) { - if (err == -ERANGE) { - ntfs_error(vol->sb, "Write would cause the inode " - "0x%lx to exceed the maximum size for " - "its attribute type (0x%x). Aborting " - "write.", vi->i_ino, - le32_to_cpu(ni->type)); - } else { - ntfs_error(vol->sb, "Inode 0x%lx has unknown " - "attribute type 0x%x. Aborting " - "write.", vi->i_ino, - le32_to_cpu(ni->type)); - err = -EIO; - } - goto err_out2; - } - /* - * Extend the attribute record to be able to store the new attribute - * size. - */ - if (new_size >= vol->mft_record_size || ntfs_attr_record_resize(m, a, - le16_to_cpu(a->data.resident.value_offset) + - new_size)) { - /* Not enough space in the mft record. */ - ntfs_error(vol->sb, "Not enough space in the mft record for " - "the resized attribute value. This is not " - "supported yet. Aborting write."); - err = -EOPNOTSUPP; - goto err_out2; - } - /* - * We have enough space in the mft record to fit the write. This - * implies the attribute is smaller than the mft record and hence the - * attribute must be in a single page and hence page->index must be 0. - */ - BUG_ON(page->index); - /* - * If the beginning of the write is past the old size, enlarge the - * attribute value up to the beginning of the write and fill it with - * zeroes. - */ - if (from > attr_len) { - memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) + - attr_len, 0, from - attr_len); - a->data.resident.value_length = cpu_to_le32(from); - /* Zero the corresponding area in the page as well. */ - if (PageUptodate(page)) { - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + attr_len, 0, from - attr_len); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page); - } - } - flush_dcache_mft_record_page(ctx->ntfs_ino); - mark_mft_record_dirty(ctx->ntfs_ino); -done_unm: - ntfs_attr_put_search_ctx(ctx); - unmap_mft_record(base_ni); - /* - * Because resident attributes are handled by memcpy() to/from the - * corresponding MFT record, and because this form of i/o is byte - * aligned rather than block aligned, there is no need to bring the - * page uptodate here as in the non-resident case where we need to - * bring the buffers straddled by the write uptodate before - * generic_file_write() does the copying from userspace. - * - * We thus defer the uptodate bringing of the page region outside the - * region written to to ntfs_commit_write(), which makes the code - * simpler and saves one atomic kmap which is good. - */ -done: - ntfs_debug("Done."); - return 0; -err_out: - if (err == -ENOMEM) - ntfs_warning(vi->i_sb, "Error allocating memory required to " - "prepare the write."); - else { - ntfs_error(vi->i_sb, "Resident attribute prepare write failed " - "with error %i.", err); - NVolSetErrors(vol); - make_bad_inode(vi); - } -err_out2: - if (ctx) - ntfs_attr_put_search_ctx(ctx); - if (m) - unmap_mft_record(base_ni); - return err; -} - -/** - * ntfs_commit_nonresident_write - - * - */ -static int ntfs_commit_nonresident_write(struct page *page, - unsigned from, unsigned to) -{ - s64 pos = ((s64)page->index << PAGE_CACHE_SHIFT) + to; - struct inode *vi = page->mapping->host; - struct buffer_head *bh, *head; - unsigned int block_start, block_end, blocksize; - BOOL partial; - - ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " - "0x%lx, from = %u, to = %u.", vi->i_ino, - NTFS_I(vi)->type, page->index, from, to); - blocksize = 1 << vi->i_blkbits; - - // FIXME: We need a whole slew of special cases in here for compressed - // files for example... - // For now, we know ntfs_prepare_write() would have failed so we can't - // get here in any of the cases which we have to special case, so we - // are just a ripped off, unrolled generic_commit_write(). - - bh = head = page_buffers(page); - block_start = 0; - partial = FALSE; - do { - block_end = block_start + blocksize; - if (block_end <= from || block_start >= to) { - if (!buffer_uptodate(bh)) - partial = TRUE; - } else { - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - } - } while (block_start = block_end, (bh = bh->b_this_page) != head); - /* - * If this is a partial write which happened to make all buffers - * uptodate then we can optimize away a bogus ->readpage() for the next - * read(). Here we 'discover' whether the page went uptodate as a - * result of this (potentially partial) write. - */ - if (!partial) - SetPageUptodate(page); - /* - * Not convinced about this at all. See disparity comment above. For - * now we know ntfs_prepare_write() would have failed in the write - * exceeds i_size case, so this will never trigger which is fine. - */ - if (pos > i_size_read(vi)) { - ntfs_error(vi->i_sb, "Writing beyond the existing file size is " - "not supported yet. Sorry."); - return -EOPNOTSUPP; - // vi->i_size = pos; - // mark_inode_dirty(vi); - } - ntfs_debug("Done."); - return 0; -} - -/** - * ntfs_commit_write - commit the received data - * - * This is called from generic_file_write() with i_sem held on the inode - * (@page->mapping->host). The @page is locked but not kmap()ped. The source - * data has already been copied into the @page. ntfs_prepare_write() has been - * called before the data copied and it returned success so we can take the - * results of various BUG checks and some error handling for granted. - * - * Need to mark modified blocks dirty so they get written out later when - * ntfs_writepage() is invoked by the VM. - * - * Return 0 on success or -errno on error. - * - * Should be using generic_commit_write(). This marks buffers uptodate and - * dirty, sets the page uptodate if all buffers in the page are uptodate, and - * updates i_size if the end of io is beyond i_size. In that case, it also - * marks the inode dirty. - * - * Cannot use generic_commit_write() due to ntfs specialities but can look at - * it for implementation guidance. - * - * If things have gone as outlined in ntfs_prepare_write(), then we do not - * need to do any page content modifications here at all, except in the write - * to resident attribute case, where we need to do the uptodate bringing here - * which we combine with the copying into the mft record which means we save - * one atomic kmap. - */ -static int ntfs_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct inode *vi = page->mapping->host; - ntfs_inode *base_ni, *ni = NTFS_I(vi); - char *kaddr, *kattr; - ntfs_attr_search_ctx *ctx; - MFT_RECORD *m; - ATTR_RECORD *a; - u32 attr_len; - int err; - - ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " - "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type, - page->index, from, to); - /* If the attribute is not resident, deal with it elsewhere. */ - if (NInoNonResident(ni)) { - /* Only unnamed $DATA attributes can be compressed/encrypted. */ - if (ni->type == AT_DATA && !ni->name_len) { - /* Encrypted files need separate handling. */ - if (NInoEncrypted(ni)) { - // We never get here at present! - BUG(); - } - /* Compressed data streams are handled in compress.c. */ - if (NInoCompressed(ni)) { - // TODO: Implement this! - // return ntfs_write_compressed_block(page); - // We never get here at present! - BUG(); - } - } - /* Normal data stream. */ - return ntfs_commit_nonresident_write(page, from, to); - } - /* - * Attribute is resident, implying it is not compressed, encrypted, or - * sparse. - */ - if (!NInoAttr(ni)) - base_ni = ni; - else - base_ni = ni->ext.base_ntfs_ino; - /* Map, pin, and lock the mft record. */ - m = map_mft_record(base_ni); - if (IS_ERR(m)) { - err = PTR_ERR(m); - m = NULL; - ctx = NULL; - goto err_out; - } - ctx = ntfs_attr_get_search_ctx(base_ni, m); - if (unlikely(!ctx)) { - err = -ENOMEM; - goto err_out; - } - err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx); - if (unlikely(err)) { - if (err == -ENOENT) - err = -EIO; - goto err_out; - } - a = ctx->attr; - /* The total length of the attribute value. */ - attr_len = le32_to_cpu(a->data.resident.value_length); - BUG_ON(from > attr_len); - kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset); - kaddr = kmap_atomic(page, KM_USER0); - /* Copy the received data from the page to the mft record. */ - memcpy(kattr + from, kaddr + from, to - from); - /* Update the attribute length if necessary. */ - if (to > attr_len) { - attr_len = to; - a->data.resident.value_length = cpu_to_le32(attr_len); - } - /* - * If the page is not uptodate, bring the out of bounds area(s) - * uptodate by copying data from the mft record to the page. - */ - if (!PageUptodate(page)) { - if (from > 0) - memcpy(kaddr, kattr, from); - if (to < attr_len) - memcpy(kaddr + to, kattr + to, attr_len - to); - /* Zero the region outside the end of the attribute value. */ - if (attr_len < PAGE_CACHE_SIZE) - memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len); - /* - * The probability of not having done any of the above is - * extremely small, so we just flush unconditionally. - */ - flush_dcache_page(page); - SetPageUptodate(page); - } - kunmap_atomic(kaddr, KM_USER0); - /* Update i_size if necessary. */ - if (i_size_read(vi) < attr_len) { - unsigned long flags; - - write_lock_irqsave(&ni->size_lock, flags); - ni->allocated_size = ni->initialized_size = attr_len; - i_size_write(vi, attr_len); - write_unlock_irqrestore(&ni->size_lock, flags); - } - /* Mark the mft record dirty, so it gets written back. */ - flush_dcache_mft_record_page(ctx->ntfs_ino); - mark_mft_record_dirty(ctx->ntfs_ino); - ntfs_attr_put_search_ctx(ctx); - unmap_mft_record(base_ni); - ntfs_debug("Done."); - return 0; -err_out: - if (err == -ENOMEM) { - ntfs_warning(vi->i_sb, "Error allocating memory required to " - "commit the write."); - if (PageUptodate(page)) { - ntfs_warning(vi->i_sb, "Page is uptodate, setting " - "dirty so the write will be retried " - "later on by the VM."); - /* - * Put the page on mapping->dirty_pages, but leave its - * buffers' dirty state as-is. - */ - __set_page_dirty_nobuffers(page); - err = 0; - } else - ntfs_error(vi->i_sb, "Page is not uptodate. Written " - "data has been lost."); - } else { - ntfs_error(vi->i_sb, "Resident attribute commit write failed " - "with error %i.", err); - NVolSetErrors(ni->vol); - make_bad_inode(vi); - } - if (ctx) - ntfs_attr_put_search_ctx(ctx); - if (m) - unmap_mft_record(base_ni); - return err; -} - #endif /* NTFS_RW */ /** @@ -2377,9 +1553,6 @@ struct address_space_operations ntfs_aops = { disk request queue. */ #ifdef NTFS_RW .writepage = ntfs_writepage, /* Write dirty page to disk. */ - .prepare_write = ntfs_prepare_write, /* Prepare page and buffers - ready to receive data. */ - .commit_write = ntfs_commit_write, /* Commit received data. */ #endif /* NTFS_RW */ }; From b6a47fd8ff08a9d5cd279cdb8d97a619983575fa Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 11 Oct 2005 09:06:59 -0500 Subject: [PATCH 0274/1940] JFS: Corrupted block map should not cause trap Replace assert statements with better error handling. Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_dmap.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 51c02bf07878..68000a50ceb6 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -74,7 +74,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks); static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); -static void dbBackSplit(dmtree_t * tp, int leafno); +static int dbBackSplit(dmtree_t * tp, int leafno); static int dbJoin(dmtree_t * tp, int leafno, int newval); static void dbAdjTree(dmtree_t * tp, int leafno, int newval); static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, @@ -2466,7 +2466,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) * that it is at the front of a binary buddy system. */ if (oldval == NOFREE) { - dbBackSplit((dmtree_t *) dcp, leafno); + rc = dbBackSplit((dmtree_t *) dcp, leafno); + if (rc) + return rc; oldval = dcp->stree[ti]; } dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); @@ -2626,7 +2628,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ -static void dbBackSplit(dmtree_t * tp, int leafno) +static int dbBackSplit(dmtree_t * tp, int leafno) { int budsz, bud, w, bsz, size; int cursz; @@ -2661,7 +2663,10 @@ static void dbBackSplit(dmtree_t * tp, int leafno) */ for (w = leafno, bsz = budsz;; bsz <<= 1, w = (w < bud) ? w : bud) { - assert(bsz < le32_to_cpu(tp->dmt_nleafs)); + if (bsz >= le32_to_cpu(tp->dmt_nleafs)) { + jfs_err("JFS: block map error in dbBackSplit"); + return -EIO; + } /* determine the buddy. */ @@ -2680,7 +2685,11 @@ static void dbBackSplit(dmtree_t * tp, int leafno) } } - assert(leaf[leafno] == size); + if (leaf[leafno] != size) { + jfs_err("JFS: wrong leaf value in dbBackSplit"); + return -EIO; + } + return 0; } From 98b270362bb9ea6629732e7f5b65b8a6ce4743c7 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 11 Oct 2005 15:40:40 +0100 Subject: [PATCH 0275/1940] NTFS: The big ntfs write(2) rewrite has arrived. We now implement our own file operations ->write(), ->aio_write(), and ->writev() for regular files. This replaces the old use of generic_file_write(), et al and the address space operations ->prepare_write and ->commit_write. This means that both sparse and non-sparse (unencrypted and uncompressed) files can now be extended using the normal write(2) code path. There are two limitations at present and these are that we never create sparse files and that we only have limited support for highly fragmented files, i.e. ones whose data attribute is split across multiple extents. When such a case is encountered, EOPNOTSUPP is returned. Signed-off-by: Anton Altaparmakov --- Documentation/filesystems/ntfs.txt | 42 +- fs/ntfs/ChangeLog | 38 +- fs/ntfs/Makefile | 2 +- fs/ntfs/file.c | 2247 +++++++++++++++++++++++++++- 4 files changed, 2280 insertions(+), 49 deletions(-) diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index a5fbc8e897fa..614de3124901 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -50,9 +50,14 @@ userspace utilities, etc. Features ======== -- This is a complete rewrite of the NTFS driver that used to be in the kernel. - This new driver implements NTFS read support and is functionally equivalent - to the old ntfs driver. +- This is a complete rewrite of the NTFS driver that used to be in the 2.4 and + earlier kernels. This new driver implements NTFS read support and is + functionally equivalent to the old ntfs driver and it also implements limited + write support. The biggest limitation at present is that files/directories + cannot be created or deleted. See below for the list of write features that + are so far supported. Another limitation is that writing to compressed files + is not implemented at all. Also, neither read nor write access to encrypted + files is so far implemented. - The new driver has full support for sparse files on NTFS 3.x volumes which the old driver isn't happy with. - The new driver supports execution of binaries due to mmap() now being @@ -78,7 +83,20 @@ Features - The new driver supports fsync(2), fdatasync(2), and msync(2). - The new driver supports readv(2) and writev(2). - The new driver supports access time updates (including mtime and ctime). - +- The new driver supports truncate(2) and open(2) with O_TRUNC. But at present + only very limited support for highly fragmented files, i.e. ones which have + their data attribute split across multiple extents, is included. Another + limitation is that at present truncate(2) will never create sparse files, + since to mark a file sparse we need to modify the directory entry for the + file and we do not implement directory modifications yet. +- The new driver supports write(2) which can both overwrite existing data and + extend the file size so that you can write beyond the existing data. Also, + writing into sparse regions is supported and the holes are filled in with + clusters. But at present only limited support for highly fragmented files, + i.e. ones which have their data attribute split across multiple extents, is + included. Another limitation is that write(2) will never create sparse + files, since to mark a file sparse we need to modify the directory entry for + the file and we do not implement directory modifications yet. Supported mount options ======================= @@ -439,6 +457,22 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.25: + - Write support is now extended with write(2) being able to both + overwrite existing file data and to extend files. Also, if a write + to a sparse region occurs, write(2) will fill in the hole. Note, + mmap(2) based writes still do not support writing into holes or + writing beyond the initialized size. + - Write support has a new feature and that is that truncate(2) and + open(2) with O_TRUNC are now implemented thus files can be both made + smaller and larger. + - Note: Both write(2) and truncate(2)/open(2) with O_TRUNC still have + limitations in that they + - only provide limited support for highly fragmented files. + - only work on regular, i.e. uncompressed and unencrypted files. + - never create sparse files although this will change once directory + operations are implemented. + - Lots of bug fixes and enhancements across the board. 2.1.24: - Support journals ($LogFile) which have been modified by chkdsk. This means users can boot into Windows after we marked the volume dirty. diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 3b8ff2318085..03015c7b236c 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -1,16 +1,15 @@ ToDo/Notes: - Find and fix bugs. - - In between ntfs_prepare/commit_write, need exclusion between - simultaneous file extensions. This is given to us by holding i_sem - on the inode. The only places in the kernel when a file is resized - are prepare/commit write and ntfs_truncate() for both of which i_sem - is held. Just have to be careful in read-/writepage and other helpers + - The only places in the kernel where a file is resized are + ntfs_file_write*() and ntfs_truncate() for both of which i_sem is + held. Just have to be careful in read-/writepage and other helpers not running under i_sem that we play nice... Also need to be careful - with initialized_size extention in ntfs_prepare_write and writepage. - UPDATE: The only things that need to be checked are - prepare/commit_write as well as the compressed write and the other - attribute resize/write cases like index attributes, etc. For now - none of these are implemented so are safe. + with initialized_size extension in ntfs_file_write*() and writepage. + UPDATE: The only things that need to be checked are the compressed + write and the other attribute resize/write cases like index + attributes, etc. For now none of these are implemented so are safe. + - Implement filling in of holes in aops.c::ntfs_writepage() and its + helpers. - Implement mft.c::sync_mft_mirror_umount(). We currently will just leave the volume dirty on umount if the final iput(vol->mft_ino) causes a write of any mirrored mft records due to the mft mirror @@ -20,7 +19,7 @@ ToDo/Notes: - Enable the code for setting the NT4 compatibility flag when we start making NTFS 1.2 specific modifications. -2.1.25-WIP +2.1.25 - (Almost) fully implement write(2) and truncate(2). - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and {__,}ntfs_cluster_free() to also take an optional attribute search @@ -49,7 +48,12 @@ ToDo/Notes: extend the allocation of an attributes. Optionally, the data size, but not the initialized size can be extended, too. - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports - uncompressed and unencrypted files. + uncompressed and unencrypted files and it never creates sparse files + at least for the moment (making a file sparse requires us to modify + its directory entries and we do not support directory operations at + the moment). Also, support for highly fragmented files, i.e. ones + whose data attribute is split across multiple extents, is severly + limited. When such a case is encountered, EOPNOTSUPP is returned. - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes the initial implementation of file truncation. Now both open(2)ing a file with the O_TRUNC flag and the {,f}truncate(2) system calls @@ -61,6 +65,16 @@ ToDo/Notes: and cond_resched() in the main loop as we could be dirtying a lot of pages and this ensures we play nice with the VM and the system as a whole. + - Implement file operations ->write, ->aio_write, ->writev for regular + files. This replaces the old use of generic_file_write(), et al and + the address space operations ->prepare_write and ->commit_write. + This means that both sparse and non-sparse (unencrypted and + uncompressed) files can now be extended using the normal write(2) + code path. There are two limitations at present and these are that + we never create sparse files and that we only have limited support + for highly fragmented files, i.e. ones whose data attribute is split + across multiple extents. When such a case is encountered, + EOPNOTSUPP is returned. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index a3ce2c0e7dd9..d0d45d1c853a 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25-WIP\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index be9fd1dd423d..cf2a0e2330df 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -19,11 +19,24 @@ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "attrib.h" +#include "bitmap.h" #include "inode.h" #include "debug.h" +#include "lcnalloc.h" +#include "malloc.h" +#include "mft.h" #include "ntfs.h" /** @@ -55,6 +68,2176 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) #ifdef NTFS_RW +/** + * ntfs_attr_extend_initialized - extend the initialized size of an attribute + * @ni: ntfs inode of the attribute to extend + * @new_init_size: requested new initialized size in bytes + * @cached_page: store any allocated but unused page here + * @lru_pvec: lru-buffering pagevec of the caller + * + * Extend the initialized size of an attribute described by the ntfs inode @ni + * to @new_init_size bytes. This involves zeroing any non-sparse space between + * the old initialized size and @new_init_size both in the page cache and on + * disk (if relevant complete pages are zeroed in the page cache then these may + * simply be marked dirty for later writeout). There is one caveat and that is + * that if any uptodate page cache pages between the old initialized size and + * the smaller of @new_init_size and the file size (vfs inode->i_size) are in + * memory, these need to be marked dirty without being zeroed since they could + * be non-zero due to mmap() based writes. + * + * As a side-effect, the file size (vfs inode->i_size) may be incremented as, + * in the resident attribute case, it is tied to the initialized size and, in + * the non-resident attribute case, it may not fall below the initialized size. + * + * Note that if the attribute is resident, we do not need to touch the page + * cache at all. This is because if the page cache page is not uptodate we + * bring it uptodate later, when doing the write to the mft record since we + * then already have the page mapped. And if the page is uptodate, the + * non-initialized region will already have been zeroed when the page was + * brought uptodate and the region may in fact already have been overwritten + * with new data via mmap() based writes, so we cannot just zero it. And since + * POSIX specifies that the behaviour of resizing a file whilst it is mmap()ped + * is unspecified, we choose not to do zeroing and thus we do not need to touch + * the page at all. For a more detailed explanation see ntfs_truncate() which + * is in fs/ntfs/inode.c. + * + * @cached_page and @lru_pvec are just optimisations for dealing with multiple + * pages. + * + * Return 0 on success and -errno on error. In the case that an error is + * encountered it is possible that the initialized size will already have been + * incremented some way towards @new_init_size but it is guaranteed that if + * this is the case, the necessary zeroing will also have happened and that all + * metadata is self-consistent. + * + * Locking: This function locks the mft record of the base ntfs inode and + * maintains the lock throughout execution of the function. This is required + * so that the initialized size of the attribute can be modified safely. + */ +static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size, + struct page **cached_page, struct pagevec *lru_pvec) +{ + s64 old_init_size; + loff_t old_i_size; + pgoff_t index, end_index; + unsigned long flags; + struct inode *vi = VFS_I(ni); + ntfs_inode *base_ni; + MFT_RECORD *m = NULL; + ATTR_RECORD *a; + ntfs_attr_search_ctx *ctx = NULL; + struct address_space *mapping; + struct page *page = NULL; + u8 *kattr; + int err; + u32 attr_len; + + read_lock_irqsave(&ni->size_lock, flags); + old_init_size = ni->initialized_size; + old_i_size = i_size_read(vi); + BUG_ON(new_init_size > ni->allocated_size); + read_unlock_irqrestore(&ni->size_lock, flags); + ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, " + "old_initialized_size 0x%llx, " + "new_initialized_size 0x%llx, i_size 0x%llx.", + vi->i_ino, (unsigned)le32_to_cpu(ni->type), + (unsigned long long)old_init_size, + (unsigned long long)new_init_size, old_i_size); + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + /* Use goto to reduce indentation and we need the label below anyway. */ + if (NInoNonResident(ni)) + goto do_non_resident_extend; + BUG_ON(old_init_size != old_i_size); + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + goto err_out; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + m = ctx->mrec; + a = ctx->attr; + BUG_ON(a->non_resident); + /* The total length of the attribute value. */ + attr_len = le32_to_cpu(a->data.resident.value_length); + BUG_ON(old_i_size != (loff_t)attr_len); + /* + * Do the zeroing in the mft record and update the attribute size in + * the mft record. + */ + kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset); + memset(kattr + attr_len, 0, new_init_size - attr_len); + a->data.resident.value_length = cpu_to_le32((u32)new_init_size); + /* Finally, update the sizes in the vfs and ntfs inodes. */ + write_lock_irqsave(&ni->size_lock, flags); + i_size_write(vi, new_init_size); + ni->initialized_size = new_init_size; + write_unlock_irqrestore(&ni->size_lock, flags); + goto done; +do_non_resident_extend: + /* + * If the new initialized size @new_init_size exceeds the current file + * size (vfs inode->i_size), we need to extend the file size to the + * new initialized size. + */ + if (new_init_size > old_i_size) { + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + goto err_out; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + m = ctx->mrec; + a = ctx->attr; + BUG_ON(!a->non_resident); + BUG_ON(old_i_size != (loff_t) + sle64_to_cpu(a->data.non_resident.data_size)); + a->data.non_resident.data_size = cpu_to_sle64(new_init_size); + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + /* Update the file size in the vfs inode. */ + i_size_write(vi, new_init_size); + ntfs_attr_put_search_ctx(ctx); + ctx = NULL; + unmap_mft_record(base_ni); + m = NULL; + } + mapping = vi->i_mapping; + index = old_init_size >> PAGE_CACHE_SHIFT; + end_index = (new_init_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + do { + /* + * Read the page. If the page is not present, this will zero + * the uninitialized regions for us. + */ + page = read_cache_page(mapping, index, + (filler_t*)mapping->a_ops->readpage, NULL); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto init_err_out; + } + wait_on_page_locked(page); + if (unlikely(!PageUptodate(page) || PageError(page))) { + page_cache_release(page); + err = -EIO; + goto init_err_out; + } + /* + * Update the initialized size in the ntfs inode. This is + * enough to make ntfs_writepage() work. + */ + write_lock_irqsave(&ni->size_lock, flags); + ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT; + if (ni->initialized_size > new_init_size) + ni->initialized_size = new_init_size; + write_unlock_irqrestore(&ni->size_lock, flags); + /* Set the page dirty so it gets written out. */ + set_page_dirty(page); + page_cache_release(page); + /* + * Play nice with the vm and the rest of the system. This is + * very much needed as we can potentially be modifying the + * initialised size from a very small value to a really huge + * value, e.g. + * f = open(somefile, O_TRUNC); + * truncate(f, 10GiB); + * seek(f, 10GiB); + * write(f, 1); + * And this would mean we would be marking dirty hundreds of + * thousands of pages or as in the above example more than + * two and a half million pages! + * + * TODO: For sparse pages could optimize this workload by using + * the FsMisc / MiscFs page bit as a "PageIsSparse" bit. This + * would be set in readpage for sparse pages and here we would + * not need to mark dirty any pages which have this bit set. + * The only caveat is that we have to clear the bit everywhere + * where we allocate any clusters that lie in the page or that + * contain the page. + * + * TODO: An even greater optimization would be for us to only + * call readpage() on pages which are not in sparse regions as + * determined from the runlist. This would greatly reduce the + * number of pages we read and make dirty in the case of sparse + * files. + */ + balance_dirty_pages_ratelimited(mapping); + cond_resched(); + } while (++index < end_index); + read_lock_irqsave(&ni->size_lock, flags); + BUG_ON(ni->initialized_size != new_init_size); + read_unlock_irqrestore(&ni->size_lock, flags); + /* Now bring in sync the initialized_size in the mft record. */ + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + goto init_err_out; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto init_err_out; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto init_err_out; + } + m = ctx->mrec; + a = ctx->attr; + BUG_ON(!a->non_resident); + a->data.non_resident.initialized_size = cpu_to_sle64(new_init_size); +done: + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + if (ctx) + ntfs_attr_put_search_ctx(ctx); + if (m) + unmap_mft_record(base_ni); + ntfs_debug("Done, initialized_size 0x%llx, i_size 0x%llx.", + (unsigned long long)new_init_size, i_size_read(vi)); + return 0; +init_err_out: + write_lock_irqsave(&ni->size_lock, flags); + ni->initialized_size = old_init_size; + write_unlock_irqrestore(&ni->size_lock, flags); +err_out: + if (ctx) + ntfs_attr_put_search_ctx(ctx); + if (m) + unmap_mft_record(base_ni); + ntfs_debug("Failed. Returning error code %i.", err); + return err; +} + +/** + * ntfs_fault_in_pages_readable - + * + * Fault a number of userspace pages into pagetables. + * + * Unlike include/linux/pagemap.h::fault_in_pages_readable(), this one copes + * with more than two userspace pages as well as handling the single page case + * elegantly. + * + * If you find this difficult to understand, then think of the while loop being + * the following code, except that we do without the integer variable ret: + * + * do { + * ret = __get_user(c, uaddr); + * uaddr += PAGE_SIZE; + * } while (!ret && uaddr < end); + * + * Note, the final __get_user() may well run out-of-bounds of the user buffer, + * but _not_ out-of-bounds of the page the user buffer belongs to, and since + * this is only a read and not a write, and since it is still in the same page, + * it should not matter and this makes the code much simpler. + */ +static inline void ntfs_fault_in_pages_readable(const char __user *uaddr, + int bytes) +{ + const char __user *end; + volatile char c; + + /* Set @end to the first byte outside the last page we care about. */ + end = (const char __user*)PAGE_ALIGN((ptrdiff_t __user)uaddr + bytes); + + while (!__get_user(c, uaddr) && (uaddr += PAGE_SIZE, uaddr < end)) + ; +} + +/** + * ntfs_fault_in_pages_readable_iovec - + * + * Same as ntfs_fault_in_pages_readable() but operates on an array of iovecs. + */ +static inline void ntfs_fault_in_pages_readable_iovec(const struct iovec *iov, + size_t iov_ofs, int bytes) +{ + do { + const char __user *buf; + unsigned len; + + buf = iov->iov_base + iov_ofs; + len = iov->iov_len - iov_ofs; + if (len > bytes) + len = bytes; + ntfs_fault_in_pages_readable(buf, len); + bytes -= len; + iov++; + iov_ofs = 0; + } while (bytes); +} + +/** + * __ntfs_grab_cache_pages - obtain a number of locked pages + * @mapping: address space mapping from which to obtain page cache pages + * @index: starting index in @mapping at which to begin obtaining pages + * @nr_pages: number of page cache pages to obtain + * @pages: array of pages in which to return the obtained page cache pages + * @cached_page: allocated but as yet unused page + * @lru_pvec: lru-buffering pagevec of caller + * + * Obtain @nr_pages locked page cache pages from the mapping @maping and + * starting at index @index. + * + * If a page is newly created, increment its refcount and add it to the + * caller's lru-buffering pagevec @lru_pvec. + * + * This is the same as mm/filemap.c::__grab_cache_page(), except that @nr_pages + * are obtained at once instead of just one page and that 0 is returned on + * success and -errno on error. + * + * Note, the page locks are obtained in ascending page index order. + */ +static inline int __ntfs_grab_cache_pages(struct address_space *mapping, + pgoff_t index, const unsigned nr_pages, struct page **pages, + struct page **cached_page, struct pagevec *lru_pvec) +{ + int err, nr; + + BUG_ON(!nr_pages); + err = nr = 0; + do { + pages[nr] = find_lock_page(mapping, index); + if (!pages[nr]) { + if (!*cached_page) { + *cached_page = page_cache_alloc(mapping); + if (unlikely(!*cached_page)) { + err = -ENOMEM; + goto err_out; + } + } + err = add_to_page_cache(*cached_page, mapping, index, + GFP_KERNEL); + if (unlikely(err)) { + if (err == -EEXIST) + continue; + goto err_out; + } + pages[nr] = *cached_page; + page_cache_get(*cached_page); + if (unlikely(!pagevec_add(lru_pvec, *cached_page))) + __pagevec_lru_add(lru_pvec); + *cached_page = NULL; + } + index++; + nr++; + } while (nr < nr_pages); +out: + return err; +err_out: + while (nr > 0) { + unlock_page(pages[--nr]); + page_cache_release(pages[nr]); + } + goto out; +} + +static inline int ntfs_submit_bh_for_read(struct buffer_head *bh) +{ + lock_buffer(bh); + get_bh(bh); + bh->b_end_io = end_buffer_read_sync; + return submit_bh(READ, bh); +} + +/** + * ntfs_prepare_pages_for_non_resident_write - prepare pages for receiving data + * @pages: array of destination pages + * @nr_pages: number of pages in @pages + * @pos: byte position in file at which the write begins + * @bytes: number of bytes to be written + * + * This is called for non-resident attributes from ntfs_file_buffered_write() + * with i_sem held on the inode (@pages[0]->mapping->host). There are + * @nr_pages pages in @pages which are locked but not kmap()ped. The source + * data has not yet been copied into the @pages. + * + * Need to fill any holes with actual clusters, allocate buffers if necessary, + * ensure all the buffers are mapped, and bring uptodate any buffers that are + * only partially being written to. + * + * If @nr_pages is greater than one, we are guaranteed that the cluster size is + * greater than PAGE_CACHE_SIZE, that all pages in @pages are entirely inside + * the same cluster and that they are the entirety of that cluster, and that + * the cluster is sparse, i.e. we need to allocate a cluster to fill the hole. + * + * i_size is not to be modified yet. + * + * Return 0 on success or -errno on error. + */ +static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, + unsigned nr_pages, s64 pos, size_t bytes) +{ + VCN vcn, highest_vcn = 0, cpos, cend, bh_cpos, bh_cend; + LCN lcn; + s64 bh_pos, vcn_len, end, initialized_size; + sector_t lcn_block; + struct page *page; + struct inode *vi; + ntfs_inode *ni, *base_ni = NULL; + ntfs_volume *vol; + runlist_element *rl, *rl2; + struct buffer_head *bh, *head, *wait[2], **wait_bh = wait; + ntfs_attr_search_ctx *ctx = NULL; + MFT_RECORD *m = NULL; + ATTR_RECORD *a = NULL; + unsigned long flags; + u32 attr_rec_len = 0; + unsigned blocksize, u; + int err, mp_size; + BOOL rl_write_locked, was_hole, is_retry; + unsigned char blocksize_bits; + struct { + u8 runlist_merged:1; + u8 mft_attr_mapped:1; + u8 mp_rebuilt:1; + u8 attr_switched:1; + } status = { 0, 0, 0, 0 }; + + BUG_ON(!nr_pages); + BUG_ON(!pages); + BUG_ON(!*pages); + vi = pages[0]->mapping->host; + ni = NTFS_I(vi); + vol = ni->vol; + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page " + "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%x.", + vi->i_ino, ni->type, pages[0]->index, nr_pages, + (long long)pos, bytes); + blocksize_bits = vi->i_blkbits; + blocksize = 1 << blocksize_bits; + u = 0; + do { + struct page *page = pages[u]; + /* + * create_empty_buffers() will create uptodate/dirty buffers if + * the page is uptodate/dirty. + */ + if (!page_has_buffers(page)) { + create_empty_buffers(page, blocksize, 0); + if (unlikely(!page_has_buffers(page))) + return -ENOMEM; + } + } while (++u < nr_pages); + rl_write_locked = FALSE; + rl = NULL; + err = 0; + vcn = lcn = -1; + vcn_len = 0; + lcn_block = -1; + was_hole = FALSE; + cpos = pos >> vol->cluster_size_bits; + end = pos + bytes; + cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits; + /* + * Loop over each page and for each page over each buffer. Use goto to + * reduce indentation. + */ + u = 0; +do_next_page: + page = pages[u]; + bh_pos = (s64)page->index << PAGE_CACHE_SHIFT; + bh = head = page_buffers(page); + do { + VCN cdelta; + s64 bh_end; + unsigned bh_cofs; + + /* Clear buffer_new on all buffers to reinitialise state. */ + if (buffer_new(bh)) + clear_buffer_new(bh); + bh_end = bh_pos + blocksize; + bh_cpos = bh_pos >> vol->cluster_size_bits; + bh_cofs = bh_pos & vol->cluster_size_mask; + if (buffer_mapped(bh)) { + /* + * The buffer is already mapped. If it is uptodate, + * ignore it. + */ + if (buffer_uptodate(bh)) + continue; + /* + * The buffer is not uptodate. If the page is uptodate + * set the buffer uptodate and otherwise ignore it. + */ + if (PageUptodate(page)) { + set_buffer_uptodate(bh); + continue; + } + /* + * Neither the page nor the buffer are uptodate. If + * the buffer is only partially being written to, we + * need to read it in before the write, i.e. now. + */ + if ((bh_pos < pos && bh_end > pos) || + (bh_pos < end && bh_end > end)) { + /* + * If the buffer is fully or partially within + * the initialized size, do an actual read. + * Otherwise, simply zero the buffer. + */ + read_lock_irqsave(&ni->size_lock, flags); + initialized_size = ni->initialized_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (bh_pos < initialized_size) { + ntfs_submit_bh_for_read(bh); + *wait_bh++ = bh; + } else { + u8 *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh), 0, + blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + } + continue; + } + /* Unmapped buffer. Need to map it. */ + bh->b_bdev = vol->sb->s_bdev; + /* + * If the current buffer is in the same clusters as the map + * cache, there is no need to check the runlist again. The + * map cache is made up of @vcn, which is the first cached file + * cluster, @vcn_len which is the number of cached file + * clusters, @lcn is the device cluster corresponding to @vcn, + * and @lcn_block is the block number corresponding to @lcn. + */ + cdelta = bh_cpos - vcn; + if (likely(!cdelta || (cdelta > 0 && cdelta < vcn_len))) { +map_buffer_cached: + BUG_ON(lcn < 0); + bh->b_blocknr = lcn_block + + (cdelta << (vol->cluster_size_bits - + blocksize_bits)) + + (bh_cofs >> blocksize_bits); + set_buffer_mapped(bh); + /* + * If the page is uptodate so is the buffer. If the + * buffer is fully outside the write, we ignore it if + * it was already allocated and we mark it dirty so it + * gets written out if we allocated it. On the other + * hand, if we allocated the buffer but we are not + * marking it dirty we set buffer_new so we can do + * error recovery. + */ + if (PageUptodate(page)) { + if (!buffer_uptodate(bh)) + set_buffer_uptodate(bh); + if (unlikely(was_hole)) { + /* We allocated the buffer. */ + unmap_underlying_metadata(bh->b_bdev, + bh->b_blocknr); + if (bh_end <= pos || bh_pos >= end) + mark_buffer_dirty(bh); + else + set_buffer_new(bh); + } + continue; + } + /* Page is _not_ uptodate. */ + if (likely(!was_hole)) { + /* + * Buffer was already allocated. If it is not + * uptodate and is only partially being written + * to, we need to read it in before the write, + * i.e. now. + */ + if (!buffer_uptodate(bh) && ((bh_pos < pos && + bh_end > pos) || + (bh_end > end && + bh_end > end))) { + /* + * If the buffer is fully or partially + * within the initialized size, do an + * actual read. Otherwise, simply zero + * the buffer. + */ + read_lock_irqsave(&ni->size_lock, + flags); + initialized_size = ni->initialized_size; + read_unlock_irqrestore(&ni->size_lock, + flags); + if (bh_pos < initialized_size) { + ntfs_submit_bh_for_read(bh); + *wait_bh++ = bh; + } else { + u8 *kaddr = kmap_atomic(page, + KM_USER0); + memset(kaddr + bh_offset(bh), + 0, blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + } + continue; + } + /* We allocated the buffer. */ + unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); + /* + * If the buffer is fully outside the write, zero it, + * set it uptodate, and mark it dirty so it gets + * written out. If it is partially being written to, + * zero region surrounding the write but leave it to + * commit write to do anything else. Finally, if the + * buffer is fully being overwritten, do nothing. + */ + if (bh_end <= pos || bh_pos >= end) { + if (!buffer_uptodate(bh)) { + u8 *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh), 0, + blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + mark_buffer_dirty(bh); + continue; + } + set_buffer_new(bh); + if (!buffer_uptodate(bh) && + (bh_pos < pos || bh_end > end)) { + u8 *kaddr; + unsigned pofs; + + kaddr = kmap_atomic(page, KM_USER0); + if (bh_pos < pos) { + pofs = bh_pos & ~PAGE_CACHE_MASK; + memset(kaddr + pofs, 0, pos - bh_pos); + } + if (bh_end > end) { + pofs = end & ~PAGE_CACHE_MASK; + memset(kaddr + pofs, 0, bh_end - end); + } + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + } + continue; + } + /* + * Slow path: this is the first buffer in the cluster. If it + * is outside allocated size and is not uptodate, zero it and + * set it uptodate. + */ + read_lock_irqsave(&ni->size_lock, flags); + initialized_size = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (bh_pos > initialized_size) { + if (PageUptodate(page)) { + if (!buffer_uptodate(bh)) + set_buffer_uptodate(bh); + } else if (!buffer_uptodate(bh)) { + u8 *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh), 0, blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + continue; + } + is_retry = FALSE; + if (!rl) { + down_read(&ni->runlist.lock); +retry_remap: + rl = ni->runlist.rl; + } + if (likely(rl != NULL)) { + /* Seek to element containing target cluster. */ + while (rl->length && rl[1].vcn <= bh_cpos) + rl++; + lcn = ntfs_rl_vcn_to_lcn(rl, bh_cpos); + if (likely(lcn >= 0)) { + /* + * Successful remap, setup the map cache and + * use that to deal with the buffer. + */ + was_hole = FALSE; + vcn = bh_cpos; + vcn_len = rl[1].vcn - vcn; + lcn_block = lcn << (vol->cluster_size_bits - + blocksize_bits); + /* + * If the number of remaining clusters in the + * @pages is smaller or equal to the number of + * cached clusters, unlock the runlist as the + * map cache will be used from now on. + */ + if (likely(vcn + vcn_len >= cend)) { + if (rl_write_locked) { + up_write(&ni->runlist.lock); + rl_write_locked = FALSE; + } else + up_read(&ni->runlist.lock); + rl = NULL; + } + goto map_buffer_cached; + } + } else + lcn = LCN_RL_NOT_MAPPED; + /* + * If it is not a hole and not out of bounds, the runlist is + * probably unmapped so try to map it now. + */ + if (unlikely(lcn != LCN_HOLE && lcn != LCN_ENOENT)) { + if (likely(!is_retry && lcn == LCN_RL_NOT_MAPPED)) { + /* Attempt to map runlist. */ + if (!rl_write_locked) { + /* + * We need the runlist locked for + * writing, so if it is locked for + * reading relock it now and retry in + * case it changed whilst we dropped + * the lock. + */ + up_read(&ni->runlist.lock); + down_write(&ni->runlist.lock); + rl_write_locked = TRUE; + goto retry_remap; + } + err = ntfs_map_runlist_nolock(ni, bh_cpos, + NULL); + if (likely(!err)) { + is_retry = TRUE; + goto retry_remap; + } + /* + * If @vcn is out of bounds, pretend @lcn is + * LCN_ENOENT. As long as the buffer is out + * of bounds this will work fine. + */ + if (err == -ENOENT) { + lcn = LCN_ENOENT; + err = 0; + goto rl_not_mapped_enoent; + } + } else + err = -EIO; + /* Failed to map the buffer, even after retrying. */ + bh->b_blocknr = -1; + ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " + "attribute type 0x%x, vcn 0x%llx, " + "vcn offset 0x%x, because its " + "location on disk could not be " + "determined%s (error code %i).", + ni->mft_no, ni->type, + (unsigned long long)bh_cpos, + (unsigned)bh_pos & + vol->cluster_size_mask, + is_retry ? " even after retrying" : "", + err); + break; + } +rl_not_mapped_enoent: + /* + * The buffer is in a hole or out of bounds. We need to fill + * the hole, unless the buffer is in a cluster which is not + * touched by the write, in which case we just leave the buffer + * unmapped. This can only happen when the cluster size is + * less than the page cache size. + */ + if (unlikely(vol->cluster_size < PAGE_CACHE_SIZE)) { + bh_cend = (bh_end + vol->cluster_size - 1) >> + vol->cluster_size_bits; + if ((bh_cend <= cpos || bh_cpos >= cend)) { + bh->b_blocknr = -1; + /* + * If the buffer is uptodate we skip it. If it + * is not but the page is uptodate, we can set + * the buffer uptodate. If the page is not + * uptodate, we can clear the buffer and set it + * uptodate. Whether this is worthwhile is + * debatable and this could be removed. + */ + if (PageUptodate(page)) { + if (!buffer_uptodate(bh)) + set_buffer_uptodate(bh); + } else if (!buffer_uptodate(bh)) { + u8 *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh), 0, + blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + continue; + } + } + /* + * Out of bounds buffer is invalid if it was not really out of + * bounds. + */ + BUG_ON(lcn != LCN_HOLE); + /* + * We need the runlist locked for writing, so if it is locked + * for reading relock it now and retry in case it changed + * whilst we dropped the lock. + */ + BUG_ON(!rl); + if (!rl_write_locked) { + up_read(&ni->runlist.lock); + down_write(&ni->runlist.lock); + rl_write_locked = TRUE; + goto retry_remap; + } + /* Find the previous last allocated cluster. */ + BUG_ON(rl->lcn != LCN_HOLE); + lcn = -1; + rl2 = rl; + while (--rl2 >= ni->runlist.rl) { + if (rl2->lcn >= 0) { + lcn = rl2->lcn + rl2->length; + break; + } + } + rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE, + FALSE); + if (IS_ERR(rl2)) { + err = PTR_ERR(rl2); + ntfs_debug("Failed to allocate cluster, error code %i.", + err); + break; + } + lcn = rl2->lcn; + rl = ntfs_runlists_merge(ni->runlist.rl, rl2); + if (IS_ERR(rl)) { + err = PTR_ERR(rl); + if (err != -ENOMEM) + err = -EIO; + if (ntfs_cluster_free_from_rl(vol, rl2)) { + ntfs_error(vol->sb, "Failed to release " + "allocated cluster in error " + "code path. Run chkdsk to " + "recover the lost cluster."); + NVolSetErrors(vol); + } + ntfs_free(rl2); + break; + } + ni->runlist.rl = rl; + status.runlist_merged = 1; + ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn); + /* Map and lock the mft record and get the attribute record. */ + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + break; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + unmap_mft_record(base_ni); + break; + } + status.mft_attr_mapped = 1; + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, bh_cpos, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + break; + } + m = ctx->mrec; + a = ctx->attr; + /* + * Find the runlist element with which the attribute extent + * starts. Note, we cannot use the _attr_ version because we + * have mapped the mft record. That is ok because we know the + * runlist fragment must be mapped already to have ever gotten + * here, so we can just use the _rl_ version. + */ + vcn = sle64_to_cpu(a->data.non_resident.lowest_vcn); + rl2 = ntfs_rl_find_vcn_nolock(rl, vcn); + BUG_ON(!rl2); + BUG_ON(!rl2->length); + BUG_ON(rl2->lcn < LCN_HOLE); + highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); + /* + * If @highest_vcn is zero, calculate the real highest_vcn + * (which can really be zero). + */ + if (!highest_vcn) + highest_vcn = (sle64_to_cpu( + a->data.non_resident.allocated_size) >> + vol->cluster_size_bits) - 1; + /* + * Determine the size of the mapping pairs array for the new + * extent, i.e. the old extent with the hole filled. + */ + mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, vcn, + highest_vcn); + if (unlikely(mp_size <= 0)) { + if (!(err = mp_size)) + err = -EIO; + ntfs_debug("Failed to get size for mapping pairs " + "array, error code %i.", err); + break; + } + /* + * Resize the attribute record to fit the new mapping pairs + * array. + */ + attr_rec_len = le32_to_cpu(a->length); + err = ntfs_attr_record_resize(m, a, mp_size + le16_to_cpu( + a->data.non_resident.mapping_pairs_offset)); + if (unlikely(err)) { + BUG_ON(err != -ENOSPC); + // TODO: Deal with this by using the current attribute + // and fill it with as much of the mapping pairs + // array as possible. Then loop over each attribute + // extent rewriting the mapping pairs arrays as we go + // along and if when we reach the end we have not + // enough space, try to resize the last attribute + // extent and if even that fails, add a new attribute + // extent. + // We could also try to resize at each step in the hope + // that we will not need to rewrite every single extent. + // Note, we may need to decompress some extents to fill + // the runlist as we are walking the extents... + ntfs_error(vol->sb, "Not enough space in the mft " + "record for the extended attribute " + "record. This case is not " + "implemented yet."); + err = -EOPNOTSUPP; + break ; + } + status.mp_rebuilt = 1; + /* + * Generate the mapping pairs array directly into the attribute + * record. + */ + err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( + a->data.non_resident.mapping_pairs_offset), + mp_size, rl2, vcn, highest_vcn, NULL); + if (unlikely(err)) { + ntfs_error(vol->sb, "Cannot fill hole in inode 0x%lx, " + "attribute type 0x%x, because building " + "the mapping pairs failed with error " + "code %i.", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + err = -EIO; + break; + } + /* Update the highest_vcn but only if it was not set. */ + if (unlikely(!a->data.non_resident.highest_vcn)) + a->data.non_resident.highest_vcn = + cpu_to_sle64(highest_vcn); + /* + * If the attribute is sparse/compressed, update the compressed + * size in the ntfs_inode structure and the attribute record. + */ + if (likely(NInoSparse(ni) || NInoCompressed(ni))) { + /* + * If we are not in the first attribute extent, switch + * to it, but first ensure the changes will make it to + * disk later. + */ + if (a->data.non_resident.lowest_vcn) { + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(ni->type, ni->name, + ni->name_len, CASE_SENSITIVE, + 0, NULL, 0, ctx); + if (unlikely(err)) { + status.attr_switched = 1; + break; + } + /* @m is not used any more so do not set it. */ + a = ctx->attr; + } + write_lock_irqsave(&ni->size_lock, flags); + ni->itype.compressed.size += vol->cluster_size; + a->data.non_resident.compressed_size = + cpu_to_sle64(ni->itype.compressed.size); + write_unlock_irqrestore(&ni->size_lock, flags); + } + /* Ensure the changes make it to disk. */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + /* Successfully filled the hole. */ + status.runlist_merged = 0; + status.mft_attr_mapped = 0; + status.mp_rebuilt = 0; + /* Setup the map cache and use that to deal with the buffer. */ + was_hole = TRUE; + vcn = bh_cpos; + vcn_len = 1; + lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits); + cdelta = 0; + /* + * If the number of remaining clusters in the @pages is smaller + * or equal to the number of cached clusters, unlock the + * runlist as the map cache will be used from now on. + */ + if (likely(vcn + vcn_len >= cend)) { + up_write(&ni->runlist.lock); + rl_write_locked = FALSE; + rl = NULL; + } + goto map_buffer_cached; + } while (bh_pos += blocksize, (bh = bh->b_this_page) != head); + /* If there are no errors, do the next page. */ + if (likely(!err && ++u < nr_pages)) + goto do_next_page; + /* If there are no errors, release the runlist lock if we took it. */ + if (likely(!err)) { + if (unlikely(rl_write_locked)) { + up_write(&ni->runlist.lock); + rl_write_locked = FALSE; + } else if (unlikely(rl)) + up_read(&ni->runlist.lock); + rl = NULL; + } + /* If we issued read requests, let them complete. */ + read_lock_irqsave(&ni->size_lock, flags); + initialized_size = ni->initialized_size; + read_unlock_irqrestore(&ni->size_lock, flags); + while (wait_bh > wait) { + bh = *--wait_bh; + wait_on_buffer(bh); + if (likely(buffer_uptodate(bh))) { + page = bh->b_page; + bh_pos = ((s64)page->index << PAGE_CACHE_SHIFT) + + bh_offset(bh); + /* + * If the buffer overflows the initialized size, need + * to zero the overflowing region. + */ + if (unlikely(bh_pos + blocksize > initialized_size)) { + u8 *kaddr; + int ofs = 0; + + if (likely(bh_pos < initialized_size)) + ofs = initialized_size - bh_pos; + kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh) + ofs, 0, + blocksize - ofs); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + } + } else /* if (unlikely(!buffer_uptodate(bh))) */ + err = -EIO; + } + if (likely(!err)) { + /* Clear buffer_new on all buffers. */ + u = 0; + do { + bh = head = page_buffers(pages[u]); + do { + if (buffer_new(bh)) + clear_buffer_new(bh); + } while ((bh = bh->b_this_page) != head); + } while (++u < nr_pages); + ntfs_debug("Done."); + return err; + } + if (status.attr_switched) { + /* Get back to the attribute extent we modified. */ + ntfs_attr_reinit_search_ctx(ctx); + if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, bh_cpos, NULL, 0, ctx)) { + ntfs_error(vol->sb, "Failed to find required " + "attribute extent of attribute in " + "error code path. Run chkdsk to " + "recover."); + write_lock_irqsave(&ni->size_lock, flags); + ni->itype.compressed.size += vol->cluster_size; + write_unlock_irqrestore(&ni->size_lock, flags); + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + /* + * The only thing that is now wrong is the compressed + * size of the base attribute extent which chkdsk + * should be able to fix. + */ + NVolSetErrors(vol); + } else { + m = ctx->mrec; + a = ctx->attr; + status.attr_switched = 0; + } + } + /* + * If the runlist has been modified, need to restore it by punching a + * hole into it and we then need to deallocate the on-disk cluster as + * well. Note, we only modify the runlist if we are able to generate a + * new mapping pairs array, i.e. only when the mapped attribute extent + * is not switched. + */ + if (status.runlist_merged && !status.attr_switched) { + BUG_ON(!rl_write_locked); + /* Make the file cluster we allocated sparse in the runlist. */ + if (ntfs_rl_punch_nolock(vol, &ni->runlist, bh_cpos, 1)) { + ntfs_error(vol->sb, "Failed to punch hole into " + "attribute runlist in error code " + "path. Run chkdsk to recover the " + "lost cluster."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } else /* if (success) */ { + status.runlist_merged = 0; + /* + * Deallocate the on-disk cluster we allocated but only + * if we succeeded in punching its vcn out of the + * runlist. + */ + down_write(&vol->lcnbmp_lock); + if (ntfs_bitmap_clear_bit(vol->lcnbmp_ino, lcn)) { + ntfs_error(vol->sb, "Failed to release " + "allocated cluster in error " + "code path. Run chkdsk to " + "recover the lost cluster."); + NVolSetErrors(vol); + } + up_write(&vol->lcnbmp_lock); + } + } + /* + * Resize the attribute record to its old size and rebuild the mapping + * pairs array. Note, we only can do this if the runlist has been + * restored to its old state which also implies that the mapped + * attribute extent is not switched. + */ + if (status.mp_rebuilt && !status.runlist_merged) { + if (ntfs_attr_record_resize(m, a, attr_rec_len)) { + ntfs_error(vol->sb, "Failed to restore attribute " + "record in error code path. Run " + "chkdsk to recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } else /* if (success) */ { + if (ntfs_mapping_pairs_build(vol, (u8*)a + + le16_to_cpu(a->data.non_resident. + mapping_pairs_offset), attr_rec_len - + le16_to_cpu(a->data.non_resident. + mapping_pairs_offset), ni->runlist.rl, + vcn, highest_vcn, NULL)) { + ntfs_error(vol->sb, "Failed to restore " + "mapping pairs array in error " + "code path. Run chkdsk to " + "recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); + NVolSetErrors(vol); + } + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + } + } + /* Release the mft record and the attribute. */ + if (status.mft_attr_mapped) { + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + } + /* Release the runlist lock. */ + if (rl_write_locked) + up_write(&ni->runlist.lock); + else if (rl) + up_read(&ni->runlist.lock); + /* + * Zero out any newly allocated blocks to avoid exposing stale data. + * If BH_New is set, we know that the block was newly allocated above + * and that it has not been fully zeroed and marked dirty yet. + */ + nr_pages = u; + u = 0; + end = bh_cpos << vol->cluster_size_bits; + do { + page = pages[u]; + bh = head = page_buffers(page); + do { + if (u == nr_pages && + ((s64)page->index << PAGE_CACHE_SHIFT) + + bh_offset(bh) >= end) + break; + if (!buffer_new(bh)) + continue; + clear_buffer_new(bh); + if (!buffer_uptodate(bh)) { + if (PageUptodate(page)) + set_buffer_uptodate(bh); + else { + u8 *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + bh_offset(bh), 0, + blocksize); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); + set_buffer_uptodate(bh); + } + } + mark_buffer_dirty(bh); + } while ((bh = bh->b_this_page) != head); + } while (++u <= nr_pages); + ntfs_error(vol->sb, "Failed. Returning error code %i.", err); + return err; +} + +/* + * Copy as much as we can into the pages and return the number of bytes which + * were sucessfully copied. If a fault is encountered then clear the pages + * out to (ofs + bytes) and return the number of bytes which were copied. + */ +static inline size_t ntfs_copy_from_user(struct page **pages, + unsigned nr_pages, unsigned ofs, const char __user *buf, + size_t bytes) +{ + struct page **last_page = pages + nr_pages; + char *kaddr; + size_t total = 0; + unsigned len; + int left; + + do { + len = PAGE_CACHE_SIZE - ofs; + if (len > bytes) + len = bytes; + kaddr = kmap_atomic(*pages, KM_USER0); + left = __copy_from_user_inatomic(kaddr + ofs, buf, len); + kunmap_atomic(kaddr, KM_USER0); + if (unlikely(left)) { + /* Do it the slow way. */ + kaddr = kmap(*pages); + left = __copy_from_user(kaddr + ofs, buf, len); + kunmap(*pages); + if (unlikely(left)) + goto err_out; + } + total += len; + bytes -= len; + if (!bytes) + break; + buf += len; + ofs = 0; + } while (++pages < last_page); +out: + return total; +err_out: + total += len - left; + /* Zero the rest of the target like __copy_from_user(). */ + while (++pages < last_page) { + bytes -= len; + if (!bytes) + break; + len = PAGE_CACHE_SIZE; + if (len > bytes) + len = bytes; + kaddr = kmap_atomic(*pages, KM_USER0); + memset(kaddr, 0, len); + kunmap_atomic(kaddr, KM_USER0); + } + goto out; +} + +static size_t __ntfs_copy_from_user_iovec(char *vaddr, + const struct iovec *iov, size_t iov_ofs, size_t bytes) +{ + size_t total = 0; + + while (1) { + const char __user *buf = iov->iov_base + iov_ofs; + unsigned len; + size_t left; + + len = iov->iov_len - iov_ofs; + if (len > bytes) + len = bytes; + left = __copy_from_user_inatomic(vaddr, buf, len); + total += len; + bytes -= len; + vaddr += len; + if (unlikely(left)) { + /* + * Zero the rest of the target like __copy_from_user(). + */ + memset(vaddr, 0, bytes); + total -= left; + break; + } + if (!bytes) + break; + iov++; + iov_ofs = 0; + } + return total; +} + +static inline void ntfs_set_next_iovec(const struct iovec **iovp, + size_t *iov_ofsp, size_t bytes) +{ + const struct iovec *iov = *iovp; + size_t iov_ofs = *iov_ofsp; + + while (bytes) { + unsigned len; + + len = iov->iov_len - iov_ofs; + if (len > bytes) + len = bytes; + bytes -= len; + iov_ofs += len; + if (iov->iov_len == iov_ofs) { + iov++; + iov_ofs = 0; + } + } + *iovp = iov; + *iov_ofsp = iov_ofs; +} + +/* + * This has the same side-effects and return value as ntfs_copy_from_user(). + * The difference is that on a fault we need to memset the remainder of the + * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s + * single-segment behaviour. + * + * We call the same helper (__ntfs_copy_from_user_iovec()) both when atomic and + * when not atomic. This is ok because __ntfs_copy_from_user_iovec() calls + * __copy_from_user_inatomic() and it is ok to call this when non-atomic. In + * fact, the only difference between __copy_from_user_inatomic() and + * __copy_from_user() is that the latter calls might_sleep(). And on many + * architectures __copy_from_user_inatomic() is just defined to + * __copy_from_user() so it makes no difference at all on those architectures. + */ +static inline size_t ntfs_copy_from_user_iovec(struct page **pages, + unsigned nr_pages, unsigned ofs, const struct iovec **iov, + size_t *iov_ofs, size_t bytes) +{ + struct page **last_page = pages + nr_pages; + char *kaddr; + size_t copied, len, total = 0; + + do { + len = PAGE_CACHE_SIZE - ofs; + if (len > bytes) + len = bytes; + kaddr = kmap_atomic(*pages, KM_USER0); + copied = __ntfs_copy_from_user_iovec(kaddr + ofs, + *iov, *iov_ofs, len); + kunmap_atomic(kaddr, KM_USER0); + if (unlikely(copied != len)) { + /* Do it the slow way. */ + kaddr = kmap(*pages); + copied = __ntfs_copy_from_user_iovec(kaddr + ofs, + *iov, *iov_ofs, len); + kunmap(*pages); + if (unlikely(copied != len)) + goto err_out; + } + total += len; + bytes -= len; + if (!bytes) + break; + ntfs_set_next_iovec(iov, iov_ofs, len); + ofs = 0; + } while (++pages < last_page); +out: + return total; +err_out: + total += copied; + /* Zero the rest of the target like __copy_from_user(). */ + while (++pages < last_page) { + bytes -= len; + if (!bytes) + break; + len = PAGE_CACHE_SIZE; + if (len > bytes) + len = bytes; + kaddr = kmap_atomic(*pages, KM_USER0); + memset(kaddr, 0, len); + kunmap_atomic(kaddr, KM_USER0); + } + goto out; +} + +static inline void ntfs_flush_dcache_pages(struct page **pages, + unsigned nr_pages) +{ + BUG_ON(!nr_pages); + do { + /* + * Warning: Do not do the decrement at the same time as the + * call because flush_dcache_page() is a NULL macro on i386 + * and hence the decrement never happens. + */ + flush_dcache_page(pages[nr_pages]); + } while (--nr_pages > 0); +} + +/** + * ntfs_commit_pages_after_non_resident_write - commit the received data + * @pages: array of destination pages + * @nr_pages: number of pages in @pages + * @pos: byte position in file at which the write begins + * @bytes: number of bytes to be written + * + * See description of ntfs_commit_pages_after_write(), below. + */ +static inline int ntfs_commit_pages_after_non_resident_write( + struct page **pages, const unsigned nr_pages, + s64 pos, size_t bytes) +{ + s64 end, initialized_size; + struct inode *vi; + ntfs_inode *ni, *base_ni; + struct buffer_head *bh, *head; + ntfs_attr_search_ctx *ctx; + MFT_RECORD *m; + ATTR_RECORD *a; + unsigned long flags; + unsigned blocksize, u; + int err; + + vi = pages[0]->mapping->host; + ni = NTFS_I(vi); + blocksize = 1 << vi->i_blkbits; + end = pos + bytes; + u = 0; + do { + s64 bh_pos; + struct page *page; + BOOL partial; + + page = pages[u]; + bh_pos = (s64)page->index << PAGE_CACHE_SHIFT; + bh = head = page_buffers(page); + partial = FALSE; + do { + s64 bh_end; + + bh_end = bh_pos + blocksize; + if (bh_end <= pos || bh_pos >= end) { + if (!buffer_uptodate(bh)) + partial = TRUE; + } else { + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + } + } while (bh_pos += blocksize, (bh = bh->b_this_page) != head); + /* + * If all buffers are now uptodate but the page is not, set the + * page uptodate. + */ + if (!partial && !PageUptodate(page)) + SetPageUptodate(page); + } while (++u < nr_pages); + /* + * Finally, if we do not need to update initialized_size or i_size we + * are finished. + */ + read_lock_irqsave(&ni->size_lock, flags); + initialized_size = ni->initialized_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (end <= initialized_size) { + ntfs_debug("Done."); + return 0; + } + /* + * Update initialized_size/i_size as appropriate, both in the inode and + * the mft record. + */ + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + /* Map, pin, and lock the mft record. */ + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + ctx = NULL; + goto err_out; + } + BUG_ON(!NInoNonResident(ni)); + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + a = ctx->attr; + BUG_ON(!a->non_resident); + write_lock_irqsave(&ni->size_lock, flags); + BUG_ON(end > ni->allocated_size); + ni->initialized_size = end; + a->data.non_resident.initialized_size = cpu_to_sle64(end); + if (end > i_size_read(vi)) { + i_size_write(vi, end); + a->data.non_resident.data_size = + a->data.non_resident.initialized_size; + } + write_unlock_irqrestore(&ni->size_lock, flags); + /* Mark the mft record dirty, so it gets written back. */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + ntfs_debug("Done."); + return 0; +err_out: + if (ctx) + ntfs_attr_put_search_ctx(ctx); + if (m) + unmap_mft_record(base_ni); + ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error " + "code %i).", err); + if (err != -ENOMEM) { + NVolSetErrors(ni->vol); + make_bad_inode(VFS_I(base_ni)); + make_bad_inode(vi); + } + return err; +} + +/** + * ntfs_commit_pages_after_write - commit the received data + * @pages: array of destination pages + * @nr_pages: number of pages in @pages + * @pos: byte position in file at which the write begins + * @bytes: number of bytes to be written + * + * This is called from ntfs_file_buffered_write() with i_sem held on the inode + * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are + * locked but not kmap()ped. The source data has already been copied into the + * @page. ntfs_prepare_pages_for_non_resident_write() has been called before + * the data was copied (for non-resident attributes only) and it returned + * success. + * + * Need to set uptodate and mark dirty all buffers within the boundary of the + * write. If all buffers in a page are uptodate we set the page uptodate, too. + * + * Setting the buffers dirty ensures that they get written out later when + * ntfs_writepage() is invoked by the VM. + * + * Finally, we need to update i_size and initialized_size as appropriate both + * in the inode and the mft record. + * + * This is modelled after fs/buffer.c::generic_commit_write(), which marks + * buffers uptodate and dirty, sets the page uptodate if all buffers in the + * page are uptodate, and updates i_size if the end of io is beyond i_size. In + * that case, it also marks the inode dirty. + * + * If things have gone as outlined in + * ntfs_prepare_pages_for_non_resident_write(), we do not need to do any page + * content modifications here for non-resident attributes. For resident + * attributes we need to do the uptodate bringing here which we combine with + * the copying into the mft record which means we save one atomic kmap. + * + * Return 0 on success or -errno on error. + */ +static int ntfs_commit_pages_after_write(struct page **pages, + const unsigned nr_pages, s64 pos, size_t bytes) +{ + s64 end, initialized_size; + loff_t i_size; + struct inode *vi; + ntfs_inode *ni, *base_ni; + struct page *page; + ntfs_attr_search_ctx *ctx; + MFT_RECORD *m; + ATTR_RECORD *a; + char *kattr, *kaddr; + unsigned long flags; + u32 attr_len; + int err; + + BUG_ON(!nr_pages); + BUG_ON(!pages); + page = pages[0]; + BUG_ON(!page); + vi = page->mapping->host; + ni = NTFS_I(vi); + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page " + "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%x.", + vi->i_ino, ni->type, page->index, nr_pages, + (long long)pos, bytes); + if (NInoNonResident(ni)) + return ntfs_commit_pages_after_non_resident_write(pages, + nr_pages, pos, bytes); + BUG_ON(nr_pages > 1); + /* + * Attribute is resident, implying it is not compressed, encrypted, or + * sparse. + */ + if (!NInoAttr(ni)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + BUG_ON(NInoNonResident(ni)); + /* Map, pin, and lock the mft record. */ + m = map_mft_record(base_ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + m = NULL; + ctx = NULL; + goto err_out; + } + ctx = ntfs_attr_get_search_ctx(base_ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto err_out; + } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + err = -EIO; + goto err_out; + } + a = ctx->attr; + BUG_ON(a->non_resident); + /* The total length of the attribute value. */ + attr_len = le32_to_cpu(a->data.resident.value_length); + i_size = i_size_read(vi); + BUG_ON(attr_len != i_size); + BUG_ON(pos > attr_len); + end = pos + bytes; + BUG_ON(end > le32_to_cpu(a->length) - + le16_to_cpu(a->data.resident.value_offset)); + kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset); + kaddr = kmap_atomic(page, KM_USER0); + /* Copy the received data from the page to the mft record. */ + memcpy(kattr + pos, kaddr + pos, bytes); + /* Update the attribute length if necessary. */ + if (end > attr_len) { + attr_len = end; + a->data.resident.value_length = cpu_to_le32(attr_len); + } + /* + * If the page is not uptodate, bring the out of bounds area(s) + * uptodate by copying data from the mft record to the page. + */ + if (!PageUptodate(page)) { + if (pos > 0) + memcpy(kaddr, kattr, pos); + if (end < attr_len) + memcpy(kaddr + end, kattr + end, attr_len - end); + /* Zero the region outside the end of the attribute value. */ + memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len); + flush_dcache_page(page); + SetPageUptodate(page); + } + kunmap_atomic(kaddr, KM_USER0); + /* Update initialized_size/i_size if necessary. */ + read_lock_irqsave(&ni->size_lock, flags); + initialized_size = ni->initialized_size; + BUG_ON(end > ni->allocated_size); + read_unlock_irqrestore(&ni->size_lock, flags); + BUG_ON(initialized_size != i_size); + if (end > initialized_size) { + unsigned long flags; + + write_lock_irqsave(&ni->size_lock, flags); + ni->initialized_size = end; + i_size_write(vi, end); + write_unlock_irqrestore(&ni->size_lock, flags); + } + /* Mark the mft record dirty, so it gets written back. */ + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + ntfs_attr_put_search_ctx(ctx); + unmap_mft_record(base_ni); + ntfs_debug("Done."); + return 0; +err_out: + if (err == -ENOMEM) { + ntfs_warning(vi->i_sb, "Error allocating memory required to " + "commit the write."); + if (PageUptodate(page)) { + ntfs_warning(vi->i_sb, "Page is uptodate, setting " + "dirty so the write will be retried " + "later on by the VM."); + /* + * Put the page on mapping->dirty_pages, but leave its + * buffers' dirty state as-is. + */ + __set_page_dirty_nobuffers(page); + err = 0; + } else + ntfs_error(vi->i_sb, "Page is not uptodate. Written " + "data has been lost."); + } else { + ntfs_error(vi->i_sb, "Resident attribute commit write failed " + "with error %i.", err); + NVolSetErrors(ni->vol); + make_bad_inode(VFS_I(base_ni)); + make_bad_inode(vi); + } + if (ctx) + ntfs_attr_put_search_ctx(ctx); + if (m) + unmap_mft_record(base_ni); + return err; +} + +/** + * ntfs_file_buffered_write - + * + * Locking: The vfs is holding ->i_sem on the inode. + */ +static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, + const struct iovec *iov, unsigned long nr_segs, + loff_t pos, loff_t *ppos, size_t count) +{ + struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *vi = mapping->host; + ntfs_inode *ni = NTFS_I(vi); + ntfs_volume *vol = ni->vol; + struct page *pages[NTFS_MAX_PAGES_PER_CLUSTER]; + struct page *cached_page = NULL; + char __user *buf = NULL; + s64 end, ll; + VCN last_vcn; + LCN lcn; + unsigned long flags; + size_t bytes, iov_ofs; + ssize_t status, written; + unsigned nr_pages; + int err; + struct pagevec lru_pvec; + + ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, " + "pos 0x%llx, count 0x%lx.", + vi->i_ino, (unsigned)le32_to_cpu(ni->type), + (unsigned long long)pos, (unsigned long)count); + if (unlikely(!count)) + return 0; + BUG_ON(NInoMstProtected(ni)); + /* + * If the attribute is not an index root and it is encrypted or + * compressed, we cannot write to it yet. Note we need to check for + * AT_INDEX_ALLOCATION since this is the type of both directory and + * index inodes. + */ + if (ni->type != AT_INDEX_ALLOCATION) { + /* If file is encrypted, deny access, just like NT4. */ + if (NInoEncrypted(ni)) { + ntfs_debug("Denying write access to encrypted file."); + return -EACCES; + } + if (NInoCompressed(ni)) { + ntfs_error(vi->i_sb, "Writing to compressed files is " + "not implemented yet. Sorry."); + return -EOPNOTSUPP; + } + } + /* + * If a previous ntfs_truncate() failed, repeat it and abort if it + * fails again. + */ + if (unlikely(NInoTruncateFailed(ni))) { + down_write(&vi->i_alloc_sem); + err = ntfs_truncate(vi); + up_write(&vi->i_alloc_sem); + if (err || NInoTruncateFailed(ni)) { + if (!err) + err = -EIO; + ntfs_error(vol->sb, "Cannot perform write to inode " + "0x%lx, attribute type 0x%x, because " + "ntfs_truncate() failed (error code " + "%i).", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + return err; + } + } + /* The first byte after the write. */ + end = pos + count; + /* + * If the write goes beyond the allocated size, extend the allocation + * to cover the whole of the write, rounded up to the nearest cluster. + */ + read_lock_irqsave(&ni->size_lock, flags); + ll = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (end > ll) { + /* Extend the allocation without changing the data size. */ + ll = ntfs_attr_extend_allocation(ni, end, -1, pos); + if (likely(ll >= 0)) { + BUG_ON(pos >= ll); + /* If the extension was partial truncate the write. */ + if (end > ll) { + ntfs_debug("Truncating write to inode 0x%lx, " + "attribute type 0x%x, because " + "the allocation was only " + "partially extended.", + vi->i_ino, (unsigned) + le32_to_cpu(ni->type)); + end = ll; + count = ll - pos; + } + } else { + err = ll; + read_lock_irqsave(&ni->size_lock, flags); + ll = ni->allocated_size; + read_unlock_irqrestore(&ni->size_lock, flags); + /* Perform a partial write if possible or fail. */ + if (pos < ll) { + ntfs_debug("Truncating write to inode 0x%lx, " + "attribute type 0x%x, because " + "extending the allocation " + "failed (error code %i).", + vi->i_ino, (unsigned) + le32_to_cpu(ni->type), err); + end = ll; + count = ll - pos; + } else { + ntfs_error(vol->sb, "Cannot perform write to " + "inode 0x%lx, attribute type " + "0x%x, because extending the " + "allocation failed (error " + "code %i).", vi->i_ino, + (unsigned) + le32_to_cpu(ni->type), err); + return err; + } + } + } + pagevec_init(&lru_pvec, 0); + written = 0; + /* + * If the write starts beyond the initialized size, extend it up to the + * beginning of the write and initialize all non-sparse space between + * the old initialized size and the new one. This automatically also + * increments the vfs inode->i_size to keep it above or equal to the + * initialized_size. + */ + read_lock_irqsave(&ni->size_lock, flags); + ll = ni->initialized_size; + read_unlock_irqrestore(&ni->size_lock, flags); + if (pos > ll) { + err = ntfs_attr_extend_initialized(ni, pos, &cached_page, + &lru_pvec); + if (err < 0) { + ntfs_error(vol->sb, "Cannot perform write to inode " + "0x%lx, attribute type 0x%x, because " + "extending the initialized size " + "failed (error code %i).", vi->i_ino, + (unsigned)le32_to_cpu(ni->type), err); + status = err; + goto err_out; + } + } + /* + * Determine the number of pages per cluster for non-resident + * attributes. + */ + nr_pages = 1; + if (vol->cluster_size > PAGE_CACHE_SIZE && NInoNonResident(ni)) + nr_pages = vol->cluster_size >> PAGE_CACHE_SHIFT; + /* Finally, perform the actual write. */ + last_vcn = -1; + if (likely(nr_segs == 1)) + buf = iov->iov_base; + else + iov_ofs = 0; /* Offset in the current iovec. */ + do { + VCN vcn; + pgoff_t idx, start_idx; + unsigned ofs, do_pages, u; + size_t copied; + + start_idx = idx = pos >> PAGE_CACHE_SHIFT; + ofs = pos & ~PAGE_CACHE_MASK; + bytes = PAGE_CACHE_SIZE - ofs; + do_pages = 1; + if (nr_pages > 1) { + vcn = pos >> vol->cluster_size_bits; + if (vcn != last_vcn) { + last_vcn = vcn; + /* + * Get the lcn of the vcn the write is in. If + * it is a hole, need to lock down all pages in + * the cluster. + */ + down_read(&ni->runlist.lock); + lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >> + vol->cluster_size_bits, FALSE); + up_read(&ni->runlist.lock); + if (unlikely(lcn < LCN_HOLE)) { + status = -EIO; + if (lcn == LCN_ENOMEM) + status = -ENOMEM; + else + ntfs_error(vol->sb, "Cannot " + "perform write to " + "inode 0x%lx, " + "attribute type 0x%x, " + "because the attribute " + "is corrupt.", + vi->i_ino, (unsigned) + le32_to_cpu(ni->type)); + break; + } + if (lcn == LCN_HOLE) { + start_idx = (pos & ~(s64) + vol->cluster_size_mask) + >> PAGE_CACHE_SHIFT; + bytes = vol->cluster_size - (pos & + vol->cluster_size_mask); + do_pages = nr_pages; + } + } + } + if (bytes > count) + bytes = count; + /* + * Bring in the user page(s) that we will copy from _first_. + * Otherwise there is a nasty deadlock on copying from the same + * page(s) as we are writing to, without it/them being marked + * up-to-date. Note, at present there is nothing to stop the + * pages being swapped out between us bringing them into memory + * and doing the actual copying. + */ + if (likely(nr_segs == 1)) + ntfs_fault_in_pages_readable(buf, bytes); + else + ntfs_fault_in_pages_readable_iovec(iov, iov_ofs, bytes); + /* Get and lock @do_pages starting at index @start_idx. */ + status = __ntfs_grab_cache_pages(mapping, start_idx, do_pages, + pages, &cached_page, &lru_pvec); + if (unlikely(status)) + break; + /* + * For non-resident attributes, we need to fill any holes with + * actual clusters and ensure all bufferes are mapped. We also + * need to bring uptodate any buffers that are only partially + * being written to. + */ + if (NInoNonResident(ni)) { + status = ntfs_prepare_pages_for_non_resident_write( + pages, do_pages, pos, bytes); + if (unlikely(status)) { + loff_t i_size; + + do { + unlock_page(pages[--do_pages]); + page_cache_release(pages[do_pages]); + } while (do_pages); + /* + * The write preparation may have instantiated + * allocated space outside i_size. Trim this + * off again. We can ignore any errors in this + * case as we will just be waisting a bit of + * allocated space, which is not a disaster. + */ + i_size = i_size_read(vi); + if (pos + bytes > i_size) + vmtruncate(vi, i_size); + break; + } + } + u = (pos >> PAGE_CACHE_SHIFT) - pages[0]->index; + if (likely(nr_segs == 1)) { + copied = ntfs_copy_from_user(pages + u, do_pages - u, + ofs, buf, bytes); + buf += copied; + } else + copied = ntfs_copy_from_user_iovec(pages + u, + do_pages - u, ofs, &iov, &iov_ofs, + bytes); + ntfs_flush_dcache_pages(pages + u, do_pages - u); + status = ntfs_commit_pages_after_write(pages, do_pages, pos, + bytes); + if (likely(!status)) { + written += copied; + count -= copied; + pos += copied; + if (unlikely(copied != bytes)) + status = -EFAULT; + } + do { + unlock_page(pages[--do_pages]); + mark_page_accessed(pages[do_pages]); + page_cache_release(pages[do_pages]); + } while (do_pages); + if (unlikely(status)) + break; + balance_dirty_pages_ratelimited(mapping); + cond_resched(); + } while (count); +err_out: + *ppos = pos; + if (cached_page) + page_cache_release(cached_page); + /* For now, when the user asks for O_SYNC, we actually give O_DSYNC. */ + if (likely(!status)) { + if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(vi))) { + if (!mapping->a_ops->writepage || !is_sync_kiocb(iocb)) + status = generic_osync_inode(vi, mapping, + OSYNC_METADATA|OSYNC_DATA); + } + } + pagevec_lru_add(&lru_pvec); + ntfs_debug("Done. Returning %s (written 0x%lx, status %li).", + written ? "written" : "status", (unsigned long)written, + (long)status); + return written ? written : status; +} + +/** + * ntfs_file_aio_write_nolock - + */ +static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, + const struct iovec *iov, unsigned long nr_segs, loff_t *ppos) +{ + struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + loff_t pos; + unsigned long seg; + size_t count; /* after file limit checks */ + ssize_t written, err; + + count = 0; + for (seg = 0; seg < nr_segs; seg++) { + const struct iovec *iv = &iov[seg]; + /* + * If any segment has a negative length, or the cumulative + * length ever wraps negative then return -EINVAL. + */ + count += iv->iov_len; + if (unlikely((ssize_t)(count|iv->iov_len) < 0)) + return -EINVAL; + if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len)) + continue; + if (!seg) + return -EFAULT; + nr_segs = seg; + count -= iv->iov_len; /* This segment is no good */ + break; + } + pos = *ppos; + vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); + /* We can write back this queue in page reclaim. */ + current->backing_dev_info = mapping->backing_dev_info; + written = 0; + err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); + if (err) + goto out; + if (!count) + goto out; + err = remove_suid(file->f_dentry); + if (err) + goto out; + inode_update_time(inode, 1); + written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos, + count); +out: + current->backing_dev_info = NULL; + return written ? written : err; +} + +/** + * ntfs_file_aio_write - + */ +static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf, + size_t count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + ssize_t ret; + struct iovec local_iov = { .iov_base = (void __user *)buf, + .iov_len = count }; + + BUG_ON(iocb->ki_pos != pos); + + down(&inode->i_sem); + ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); + up(&inode->i_sem); + if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { + int err = sync_page_range(inode, mapping, pos, ret); + if (err < 0) + ret = err; + } + return ret; +} + +/** + * ntfs_file_writev - + * + * Basically the same as generic_file_writev() except that it ends up calling + * ntfs_file_aio_write_nolock() instead of __generic_file_aio_write_nolock(). + */ +static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov, + unsigned long nr_segs, loff_t *ppos) +{ + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + struct kiocb kiocb; + ssize_t ret; + + down(&inode->i_sem); + init_sync_kiocb(&kiocb, file); + ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); + if (ret == -EIOCBQUEUED) + ret = wait_on_sync_kiocb(&kiocb); + up(&inode->i_sem); + if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { + int err = sync_page_range(inode, mapping, *ppos - ret, ret); + if (err < 0) + ret = err; + } + return ret; +} + +/** + * ntfs_file_write - simple wrapper for ntfs_file_writev() + */ +static ssize_t ntfs_file_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct iovec local_iov = { .iov_base = (void __user *)buf, + .iov_len = count }; + + return ntfs_file_writev(file, &local_iov, 1, ppos); +} + /** * ntfs_file_fsync - sync a file to disk * @filp: file to be synced @@ -113,39 +2296,39 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, #endif /* NTFS_RW */ struct file_operations ntfs_file_ops = { - .llseek = generic_file_llseek, /* Seek inside file. */ - .read = generic_file_read, /* Read from file. */ - .aio_read = generic_file_aio_read, /* Async read from file. */ - .readv = generic_file_readv, /* Read from file. */ + .llseek = generic_file_llseek, /* Seek inside file. */ + .read = generic_file_read, /* Read from file. */ + .aio_read = generic_file_aio_read, /* Async read from file. */ + .readv = generic_file_readv, /* Read from file. */ #ifdef NTFS_RW - .write = generic_file_write, /* Write to file. */ - .aio_write = generic_file_aio_write, /* Async write to file. */ - .writev = generic_file_writev, /* Write to file. */ - /*.release = ,*/ /* Last file is closed. See - fs/ext2/file.c:: - ext2_release_file() for - how to use this to discard - preallocated space for - write opened files. */ - .fsync = ntfs_file_fsync, /* Sync a file to disk. */ - /*.aio_fsync = ,*/ /* Sync all outstanding async - i/o operations on a - kiocb. */ + .write = ntfs_file_write, /* Write to file. */ + .aio_write = ntfs_file_aio_write, /* Async write to file. */ + .writev = ntfs_file_writev, /* Write to file. */ + /*.release = ,*/ /* Last file is closed. See + fs/ext2/file.c:: + ext2_release_file() for + how to use this to discard + preallocated space for + write opened files. */ + .fsync = ntfs_file_fsync, /* Sync a file to disk. */ + /*.aio_fsync = ,*/ /* Sync all outstanding async + i/o operations on a + kiocb. */ #endif /* NTFS_RW */ - /*.ioctl = ,*/ /* Perform function on the - mounted filesystem. */ - .mmap = generic_file_mmap, /* Mmap file. */ - .open = ntfs_file_open, /* Open file. */ - .sendfile = generic_file_sendfile, /* Zero-copy data send with - the data source being on - the ntfs partition. We - do not need to care about - the data destination. */ - /*.sendpage = ,*/ /* Zero-copy data send with - the data destination being - on the ntfs partition. We - do not need to care about - the data source. */ + /*.ioctl = ,*/ /* Perform function on the + mounted filesystem. */ + .mmap = generic_file_mmap, /* Mmap file. */ + .open = ntfs_file_open, /* Open file. */ + .sendfile = generic_file_sendfile, /* Zero-copy data send with + the data source being on + the ntfs partition. We do + not need to care about the + data destination. */ + /*.sendpage = ,*/ /* Zero-copy data send with + the data destination being + on the ntfs partition. We + do not need to care about + the data source. */ }; struct inode_operations ntfs_file_inode_ops = { From f255f0dd1b4ef7af0e48f5603d1f27ee4bad5848 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 10 Oct 2005 17:10:54 +1000 Subject: [PATCH 0276/1940] powerpc: pci_dn's should point to their device_node's Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 46879d7de925..f79c5982446b 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -220,6 +220,7 @@ static struct device_node *build_device_node(HvBusNumber Bus, return NULL; } node->data = pdn; + pdn->node = node; list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List); #if 0 pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); From 3a5f8c5f788d68e325d9fe3c26f4df5a5aee838a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 11 Oct 2005 19:40:20 +1000 Subject: [PATCH 0277/1940] powerpc: make iSeries boot again On ARCH=ppc64 we were getting htab_hash_mask recalculated to the correct value for our particular machine by accident. In the merge tree, that code was commented out, so htab_hash_mask was being corrupted. We now set ppc64_pft_size instead which gets htab_has_mask calculated correctly for us later. We should put an ibm,pft-size property in the device tree at some point. Also set -mno-minimal-toc in some makefiles. Allow iSeries to configure PROC_DEVICETREE. Signed-off-by: Stephen Rothwell --- arch/powerpc/Kconfig | 2 +- arch/powerpc/mm/Makefile | 4 ++++ arch/powerpc/platforms/iseries/Makefile | 2 ++ arch/powerpc/platforms/iseries/setup.c | 6 +----- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 330376b74c87..cd55c9b0f7ea 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -570,7 +570,7 @@ config SCHED_SMT config PROC_DEVICETREE bool "Support for Open Firmware device tree in /proc" - depends on PPC_OF && PROC_FS + depends on (PPC_OF || PPC_ISERIES) && PROC_FS help This option adds a device-tree directory under /proc which contains an image of the device tree that the kernel copies from Open diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 612bc4ec72b1..14b2ffb6c2d8 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -2,6 +2,10 @@ # Makefile for the linux ppc-specific parts of the memory manager. # +ifeq ($(CONFIG_PPC64),y) +EXTRA_CFLAGS += -mno-minimal-toc +endif + obj-y := fault.o mem.o lmb.o obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o \ tlb_32.o diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index 18bf40077561..127b465308be 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,3 +1,5 @@ +EXTRA_CFLAGS += -mno-minimal-toc + obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o misc.o obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index c3e532b766ef..b6cf050a8c27 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -430,7 +430,6 @@ static void __init build_iSeries_Memory_Map(void) u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; u32 nextPhysChunk; u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages; - u32 num_ptegs; u32 totalChunks,moreChunks; u32 currChunk, thisChunk, absChunk; u32 currDword; @@ -493,10 +492,7 @@ static void __init build_iSeries_Memory_Map(void) printk("HPT absolute addr = %016lx, size = %dK\n", chunk_to_addr(hptFirstChunk), hptSizeChunks * 256); - /* Fill in the hashed page table hash mask */ - num_ptegs = hptSizePages * - (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP)); - htab_hash_mask = num_ptegs - 1; + ppc64_pft_size = __ilog2(hptSizePages * PAGE_SIZE); /* * The actual hashed page table is in the hypervisor, From 1047abc159b4eb4ba4a7342a0969e16e9d4b4c69 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 11 Oct 2005 19:58:06 -0700 Subject: [PATCH 0278/1940] [CIFS] CIFS Stats improvements New cifs_writepages routine was not updated bytes written in cifs stats. Also added ability to clear /proc/fs/cifs/Stats by writing (0 or 1) to it. Signed-off-by: Steve French --- fs/cifs/CHANGES | 2 +- fs/cifs/README | 11 ++++++++-- fs/cifs/cifs_debug.c | 49 +++++++++++++++++++++++++++++++++++++++++++- fs/cifs/cifs_debug.h | 5 ++++- fs/cifs/cifsglob.h | 6 +++++- fs/cifs/connect.c | 3 +++ fs/cifs/file.c | 3 +++ fs/cifs/netmisc.c | 2 +- fs/cifs/transport.c | 25 +++++++++++++++++++++- 9 files changed, 98 insertions(+), 8 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index b2a938378bef..f554a70c9cf3 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -9,7 +9,7 @@ wsize and rsize can now be larger than negotiated buffer size if server supports large readx/writex, even when directio mount flag not specified. Write size will in many cases now be 16K instead of 4K which greatly helps file copy performance on lightly loaded networks. Fix oops in dnotify -when experimental config flag enabled. +when experimental config flag enabled. Make cifsFYI more granular. Version 1.37 ------------ diff --git a/fs/cifs/README b/fs/cifs/README index e7a3ce62d71b..bb90941826ad 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -482,9 +482,16 @@ These experimental features and tracing can be enabled by changing flags in kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable tracing to the kernel message log type: - echo 1 > /proc/fs/cifs/cifsFYI + echo 7 > /proc/fs/cifs/cifsFYI -and for more extensive tracing including the start of smb requests and responses +cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel +logging of various informational messages. 2 enables logging of non-zero +SMB return codes while 4 enables logging of requests that take longer +than one second to complete (except for byte range lock requests). +Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the +source code (typically by setting it in the beginning of cifsglob.h), +and setting it to seven enables all three. Finally, tracing +the start of smb requests and responses can be enabled via: echo 1 > /proc/fs/cifs/traceSMB diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 6f7810992db3..f4054d695f81 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -203,6 +203,49 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, } #ifdef CONFIG_CIFS_STATS + +static int +cifs_stats_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + char c; + int rc; + struct list_head *tmp; + struct cifsTconInfo *tcon; + + rc = get_user(c, buffer); + if (rc) + return rc; + + if (c == '1' || c == 'y' || c == 'Y') { + read_lock(&GlobalSMBSeslock); + list_for_each(tmp, &GlobalTreeConnectionList) { + tcon = list_entry(tmp, struct cifsTconInfo, + cifsConnectionList); + atomic_set(&tcon->num_smbs_sent, 0); + atomic_set(&tcon->num_writes, 0); + atomic_set(&tcon->num_reads, 0); + atomic_set(&tcon->num_oplock_brks, 0); + atomic_set(&tcon->num_opens, 0); + atomic_set(&tcon->num_closes, 0); + atomic_set(&tcon->num_deletes, 0); + atomic_set(&tcon->num_mkdirs, 0); + atomic_set(&tcon->num_rmdirs, 0); + atomic_set(&tcon->num_renames, 0); + atomic_set(&tcon->num_t2renames, 0); + atomic_set(&tcon->num_ffirst, 0); + atomic_set(&tcon->num_fnext, 0); + atomic_set(&tcon->num_fclose, 0); + atomic_set(&tcon->num_hardlinks, 0); + atomic_set(&tcon->num_symlinks, 0); + atomic_set(&tcon->num_locks, 0); + } + read_unlock(&GlobalSMBSeslock); + } + + return count; +} + static int cifs_stats_read(char *buf, char **beginBuffer, off_t offset, int count, int *eof, void *data) @@ -365,8 +408,10 @@ cifs_proc_init(void) cifs_debug_data_read, NULL); #ifdef CONFIG_CIFS_STATS - create_proc_read_entry("Stats", 0, proc_fs_cifs, + pde = create_proc_read_entry("Stats", 0, proc_fs_cifs, cifs_stats_read, NULL); + if (pde) + pde->write_proc = cifs_stats_write; #endif pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, cifsFYI_read, NULL); @@ -483,6 +528,8 @@ cifsFYI_write(struct file *file, const char __user *buffer, cifsFYI = 0; else if (c == '1' || c == 'y' || c == 'Y') cifsFYI = 1; + else if((c > '1') && (c <= '9')) + cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ return count; } diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h index bf24d2828f68..4304d9dcfb6c 100644 --- a/fs/cifs/cifs_debug.h +++ b/fs/cifs/cifs_debug.h @@ -26,6 +26,9 @@ void cifs_dump_mem(char *label, void *data, int length); extern int traceSMB; /* flag which enables the function below */ void dump_smb(struct smb_hdr *, int); +#define CIFS_INFO 0x01 +#define CIFS_RC 0x02 +#define CIFS_TIMER 0x04 /* * debug ON @@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int); /* information message: e.g., configuration, major event */ extern int cifsFYI; -#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg) +#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg) #define cFYI(button,prspec) if (button) cifsfyi prspec diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 729717281b40..839a55667c3c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -377,7 +377,11 @@ struct mid_q_entry { __u16 mid; /* multiplex id */ __u16 pid; /* process id */ __u32 sequence_number; /* for CIFS signing */ - struct timeval when_sent; /* time when smb sent */ + unsigned long when_alloc; /* when mid was created */ +#ifdef CONFIG_CIFS_STATS2 + unsigned long when_sent; /* time when smb send finished */ + unsigned long when_received; /* when demux complete (taken off wire) */ +#endif struct cifsSesInfo *ses; /* smb was sent to this server */ struct task_struct *tsk; /* task waiting for response */ struct smb_hdr *resp_buf; /* response buffer */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 177289771abe..a8f0cbada0f0 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -605,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) multi_t2_fnd: task_to_wake = mid_entry->tsk; mid_entry->midState = MID_RESPONSE_RECEIVED; +#ifdef CONFIG_CIFS_STATS2 + mid_entry->when_received = jiffies; +#endif break; } } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 11806c879c47..585a62aebd59 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1153,6 +1153,9 @@ static int cifs_writepages(struct address_space *mapping, rc, bytes_written)); set_bit(AS_EIO, &mapping->flags); SetPageError(page); + } else { + cifs_stats_bytes_written(cifs_sb->tcon, + bytes_written); } for (i = 0; i < n_iov; i++) { page = pvec.pages[first + i]; diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 29e6efc5597c..f7814689844b 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -813,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb) if (smb->Flags2 & SMBFLG2_ERR_STATUS) { /* translate the newer STATUS codes to old style errors and then to POSIX errors */ __u32 err = le32_to_cpu(smb->Status.CifsError); - if(cifsFYI) + if(cifsFYI & CIFS_RC) cifs_print_status(err); ntstatus_to_dos(err, &smberrclass, &smberrcode); } else { diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index d8865fbd876a..981ea0d8b9cd 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -59,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) temp->pid = current->pid; temp->command = smb_buffer->Command; cFYI(1, ("For smb_command %d", temp->command)); - do_gettimeofday(&temp->when_sent); + /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */ + /* when mid allocated can be before when sent */ + temp->when_alloc = jiffies; temp->ses = ses; temp->tsk = current; } @@ -75,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) static void DeleteMidQEntry(struct mid_q_entry *midEntry) { +#ifdef CONFIG_CIFS_STATS2 + unsigned long now; +#endif spin_lock(&GlobalMid_Lock); midEntry->midState = MID_FREE; list_del(&midEntry->qhead); @@ -84,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) cifs_buf_release(midEntry->resp_buf); else cifs_small_buf_release(midEntry->resp_buf); +#ifdef CONFIG_CIFS_STATS2 + now = jiffies; + /* commands taking longer than one second are indications that + something is wrong, unless it is quite a slow link or server */ + if((now - midEntry->when_alloc) > HZ) { + if((cifsFYI & CIFS_TIMER) && + (midEntry->command != SMB_COM_LOCKING_ANDX)) { + printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d", + midEntry->command, midEntry->mid); + printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n", + now - midEntry->when_alloc, + now - midEntry->when_sent, + now - midEntry->when_received); + } + } +#endif mempool_free(midEntry, cifs_mid_poolp); } @@ -382,6 +403,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, (struct sockaddr *) &(ses->server->addr.sockAddr)); #ifdef CONFIG_CIFS_STATS2 atomic_dec(&ses->server->inSend); + midQ->when_sent = jiffies; #endif if(rc < 0) { DeleteMidQEntry(midQ); @@ -646,6 +668,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, (struct sockaddr *) &(ses->server->addr.sockAddr)); #ifdef CONFIG_CIFS_STATS2 atomic_dec(&ses->server->inSend); + midQ->when_sent = jiffies; #endif if(rc < 0) { DeleteMidQEntry(midQ); From 47c786e79b46ef478a1123cb57c711ecb481cbfa Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 11 Oct 2005 20:03:18 -0700 Subject: [PATCH 0279/1940] [CIFS] Add null malloc response check in notify experimental code Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifs_debug.c | 2 +- fs/cifs/cifssmb.c | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index f4054d695f81..22a444a3fe4c 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -217,7 +217,7 @@ cifs_stats_write(struct file *file, const char __user *buffer, if (rc) return rc; - if (c == '1' || c == 'y' || c == 'Y') { + if (c == '1' || c == 'y' || c == 'Y' || c == '0') { read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 41996a240149..9312bfc56682 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -4294,20 +4294,26 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, cFYI(1, ("Error in Notify = %d", rc)); } else { /* Add file to outstanding requests */ + /* BB change to kmem cache alloc */ dnotify_req = (struct dir_notify_req *) kmalloc( - sizeof(struct dir_notify_req), GFP_KERNEL); - dnotify_req->Pid = pSMB->hdr.Pid; - dnotify_req->PidHigh = pSMB->hdr.PidHigh; - dnotify_req->Mid = pSMB->hdr.Mid; - dnotify_req->Tid = pSMB->hdr.Tid; - dnotify_req->Uid = pSMB->hdr.Uid; - dnotify_req->netfid = netfid; - dnotify_req->pfile = pfile; - dnotify_req->filter = filter; - dnotify_req->multishot = multishot; - spin_lock(&GlobalMid_Lock); - list_add_tail(&dnotify_req->lhead, &GlobalDnotifyReqList); - spin_unlock(&GlobalMid_Lock); + sizeof(struct dir_notify_req), + GFP_KERNEL); + if(dnotify_req) { + dnotify_req->Pid = pSMB->hdr.Pid; + dnotify_req->PidHigh = pSMB->hdr.PidHigh; + dnotify_req->Mid = pSMB->hdr.Mid; + dnotify_req->Tid = pSMB->hdr.Tid; + dnotify_req->Uid = pSMB->hdr.Uid; + dnotify_req->netfid = netfid; + dnotify_req->pfile = pfile; + dnotify_req->filter = filter; + dnotify_req->multishot = multishot; + spin_lock(&GlobalMid_Lock); + list_add_tail(&dnotify_req->lhead, + &GlobalDnotifyReqList); + spin_unlock(&GlobalMid_Lock); + } else + rc = -ENOMEM; } cifs_buf_release(pSMB); return rc; From 3eac8c69d1ac1266327f4e29deb23716a12c6d30 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 12 Oct 2005 16:58:53 +1000 Subject: [PATCH 0280/1940] powerpc: Move default hash table size calculation to hash_utils_64.c We weren't computing the size of the hash table correctly on iSeries because the relevant code in prom.c was #ifdef CONFIG_PPC_PSERIES. This moves the code to hash_utils_64.c, makes it unconditional, and cleans it up a bit. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 20 -------------------- arch/powerpc/mm/hash_utils_64.c | 23 ++++++++++++++++++++++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ce0dff1caa80..c8d288457b4c 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1323,26 +1323,6 @@ void __init early_init_devtree(void *params) */ scan_flat_dt(early_init_dt_scan_cpus, NULL); -#ifdef CONFIG_PPC_PSERIES - /* If hash size wasn't obtained above, we calculate it now based on - * the total RAM size - */ - if (ppc64_pft_size == 0) { - unsigned long rnd_mem_size, pteg_count; - - /* round mem_size up to next power of 2 */ - rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); - if (rnd_mem_size < systemcfg->physicalMemorySize) - rnd_mem_size <<= 1; - - /* # pages / 2 */ - pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); - - ppc64_pft_size = __ilog2(pteg_count << 7); - } - - DBG("Hash pftSize: %x\n", (int)ppc64_pft_size); -#endif DBG(" <- early_init_devtree()\n"); } diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 35dd93eeaf4b..6e9e05cce02c 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -155,6 +155,27 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, } } +static unsigned long get_hashtable_size(void) +{ + unsigned long rnd_mem_size, pteg_count; + + /* If hash size wasn't obtained in prom.c, we calculate it now based on + * the total RAM size + */ + if (ppc64_pft_size) + return 1UL << ppc64_pft_size; + + /* round mem_size up to next power of 2 */ + rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); + if (rnd_mem_size < systemcfg->physicalMemorySize) + rnd_mem_size <<= 1; + + /* # pages / 2 */ + pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); + + return pteg_count << 7; +} + void __init htab_initialize(void) { unsigned long table, htab_size_bytes; @@ -170,7 +191,7 @@ void __init htab_initialize(void) * Calculate the required size of the htab. We want the number of * PTEGs to equal one half the number of real pages. */ - htab_size_bytes = 1UL << ppc64_pft_size; + htab_size_bytes = get_hashtable_size(); pteg_count = htab_size_bytes >> 7; /* For debug, make the HTAB 1/8 as big as it normally would be. */ From 5629d41d5ce255802cd3c350fbadfe5f3aa5f279 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 12 Oct 2005 17:01:50 +1000 Subject: [PATCH 0281/1940] powerpc: Bring in some changes made to arch/ppc and include/asm-ppc64 Recent commits upstream have changed files which are currently duplicated in arch/powerpc and include/asm-powerpc. This updates them with the corresponding changes. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/cpufreq.c | 7 +++++++ arch/powerpc/platforms/powermac/feature.c | 4 ++++ arch/powerpc/platforms/powermac/time.c | 2 +- include/asm-powerpc/iommu.h | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powermac/cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq.c index 6d32d99402be..bcd9224f3f90 100644 --- a/arch/powerpc/platforms/powermac/cpufreq.c +++ b/arch/powerpc/platforms/powermac/cpufreq.c @@ -695,6 +695,13 @@ static int __init pmac_cpufreq_setup(void) set_speed_proc = pmu_set_cpu_speed; is_pmu_based = 1; } + /* Else check for TiPb 550 */ + else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) { + hi_freq = cur_freq; + low_freq = 500000; + set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; + } /* Else check for TiPb 400 & 500 */ else if (machine_is_compatible("PowerBook3,2")) { /* We only know about the 400 MHz and the 500Mhz model diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 2cba670c71b7..243a24fd025a 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -2382,6 +2382,10 @@ static struct pmac_mb_def pmac_mb_defs[] = { PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, + { "PowerBook6,7", "iBook G4", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, { "PowerBook6,8", "PowerBook G4 12\"", PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index ff6adff36cb8..edb9fcc64790 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -195,7 +195,7 @@ via_calibrate_decr(void) ; dend = get_dec(); - tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100)); + tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index d096faf4191e..f80ec8daf122 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h @@ -88,7 +88,7 @@ extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, int nelems, enum dma_data_direction direction); extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle, unsigned int __nocast flag); + dma_addr_t *dma_handle, gfp_t flag); extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle); extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, From 7e130edf712ac054aecf643f9d3d0142a9679e6a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 12 Oct 2005 17:03:36 +1000 Subject: [PATCH 0282/1940] ppc64: Remove duplicate versions of some headers This removes three headers from include/asm-ppc64 that are now in include/asm-powerpc and are sufficiently similar that they can be used with ARCH=ppc64. Signed-off-by: Paul Mackerras --- include/asm-ppc64/iommu.h | 112 ------------ include/asm-ppc64/pSeries_reconfig.h | 25 --- include/asm-ppc64/rtas.h | 249 --------------------------- 3 files changed, 386 deletions(-) delete mode 100644 include/asm-ppc64/iommu.h delete mode 100644 include/asm-ppc64/pSeries_reconfig.h delete mode 100644 include/asm-ppc64/rtas.h diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h deleted file mode 100644 index f80ec8daf122..000000000000 --- a/include/asm-ppc64/iommu.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation - * Rewrite, cleanup: - * Copyright (C) 2004 Olof Johansson , IBM Corporation - * - * 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ASM_IOMMU_H -#define _ASM_IOMMU_H - -#include -#include -#include -#include - -/* - * IOMAP_MAX_ORDER defines the largest contiguous block - * of dma space we can get. IOMAP_MAX_ORDER = 13 - * allows up to 2**12 pages (4096 * 4096) = 16 MB - */ -#define IOMAP_MAX_ORDER 13 - -struct iommu_table { - unsigned long it_busno; /* Bus number this table belongs to */ - unsigned long it_size; /* Size of iommu table in entries */ - unsigned long it_offset; /* Offset into global table */ - unsigned long it_base; /* mapped address of tce table */ - unsigned long it_index; /* which iommu table this is */ - unsigned long it_type; /* type: PCI or Virtual Bus */ - unsigned long it_blocksize; /* Entries in each block (cacheline) */ - unsigned long it_hint; /* Hint for next alloc */ - unsigned long it_largehint; /* Hint for large allocs */ - unsigned long it_halfpoint; /* Breaking point for small/large allocs */ - spinlock_t it_lock; /* Protects it_map */ - unsigned long *it_map; /* A simple allocation bitmap for now */ -}; - -struct scatterlist; -struct device_node; - -#ifdef CONFIG_PPC_MULTIPLATFORM - -/* Walks all buses and creates iommu tables */ -extern void iommu_setup_pSeries(void); -extern void iommu_setup_u3(void); - -/* Frees table for an individual device node */ -extern void iommu_free_table(struct device_node *dn); - -#endif /* CONFIG_PPC_MULTIPLATFORM */ - -#ifdef CONFIG_PPC_PSERIES - -/* Creates table for an individual device node */ -extern void iommu_devnode_init_pSeries(struct device_node *dn); - -#endif /* CONFIG_PPC_PSERIES */ - -#ifdef CONFIG_PPC_ISERIES - -/* Creates table for an individual device node */ -extern void iommu_devnode_init_iSeries(struct device_node *dn); - -#endif /* CONFIG_PPC_ISERIES */ - -/* Initializes an iommu_table based in values set in the passed-in - * structure - */ -extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); - -extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, - struct scatterlist *sglist, int nelems, - enum dma_data_direction direction); -extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction); - -extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle, gfp_t flag); -extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, - void *vaddr, dma_addr_t dma_handle); -extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, - size_t size, enum dma_data_direction direction); -extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction); - -extern void iommu_init_early_pSeries(void); -extern void iommu_init_early_iSeries(void); -extern void iommu_init_early_u3(void); - -#ifdef CONFIG_PCI -extern void pci_iommu_init(void); -extern void pci_direct_iommu_init(void); -#else -static inline void pci_iommu_init(void) { } -#endif - -extern void alloc_u3_dart_table(void); - -#endif /* _ASM_IOMMU_H */ diff --git a/include/asm-ppc64/pSeries_reconfig.h b/include/asm-ppc64/pSeries_reconfig.h deleted file mode 100644 index c0db1ea7f7d1..000000000000 --- a/include/asm-ppc64/pSeries_reconfig.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _PPC64_PSERIES_RECONFIG_H -#define _PPC64_PSERIES_RECONFIG_H - -#include - -/* - * Use this API if your code needs to know about OF device nodes being - * added or removed on pSeries systems. - */ - -#define PSERIES_RECONFIG_ADD 0x0001 -#define PSERIES_RECONFIG_REMOVE 0x0002 - -#ifdef CONFIG_PPC_PSERIES -extern int pSeries_reconfig_notifier_register(struct notifier_block *); -extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); -#else /* !CONFIG_PPC_PSERIES */ -static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) -{ - return 0; -} -static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } -#endif /* CONFIG_PPC_PSERIES */ - -#endif /* _PPC64_PSERIES_RECONFIG_H */ diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h deleted file mode 100644 index e7d1b5222802..000000000000 --- a/include/asm-ppc64/rtas.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef _PPC64_RTAS_H -#define _PPC64_RTAS_H - -#include -#include - -/* - * Definitions for talking to the RTAS on CHRP machines. - * - * Copyright (C) 2001 Peter Bergner - * Copyright (C) 2001 PPC 64 Team, IBM Corp - * - * 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. - */ - -#define RTAS_UNKNOWN_SERVICE (-1) -#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ - -/* Buffer size for ppc_rtas system call. */ -#define RTAS_RMOBUF_MAX (64 * 1024) - -/* RTAS return status codes */ -#define RTAS_BUSY -2 /* RTAS Busy */ -#define RTAS_EXTENDED_DELAY_MIN 9900 -#define RTAS_EXTENDED_DELAY_MAX 9905 - -/* - * In general to call RTAS use rtas_token("string") to lookup - * an RTAS token for the given string (e.g. "event-scan"). - * To actually perform the call use - * ret = rtas_call(token, n_in, n_out, ...) - * Where n_in is the number of input parameters and - * n_out is the number of output parameters - * - * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE - * will be returned as a token. rtas_call() does look for this - * token and error out gracefully so rtas_call(rtas_token("str"), ...) - * may be safely used for one-shot calls to RTAS. - * - */ - -typedef u32 rtas_arg_t; - -struct rtas_args { - u32 token; - u32 nargs; - u32 nret; - rtas_arg_t args[16]; - rtas_arg_t *rets; /* Pointer to return values in args[]. */ -}; - -extern struct rtas_args rtas_stop_self_args; - -struct rtas_t { - unsigned long entry; /* physical address pointer */ - unsigned long base; /* physical address pointer */ - unsigned long size; - spinlock_t lock; - struct rtas_args args; - struct device_node *dev; /* virtual address pointer */ -}; - -/* RTAS event classes */ -#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ -#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ -#define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */ -#define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */ -#define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000 - -/* RTAS event severity */ -#define RTAS_SEVERITY_FATAL 0x5 -#define RTAS_SEVERITY_ERROR 0x4 -#define RTAS_SEVERITY_ERROR_SYNC 0x3 -#define RTAS_SEVERITY_WARNING 0x2 -#define RTAS_SEVERITY_EVENT 0x1 -#define RTAS_SEVERITY_NO_ERROR 0x0 - -/* RTAS event disposition */ -#define RTAS_DISP_FULLY_RECOVERED 0x0 -#define RTAS_DISP_LIMITED_RECOVERY 0x1 -#define RTAS_DISP_NOT_RECOVERED 0x2 - -/* RTAS event initiator */ -#define RTAS_INITIATOR_UNKNOWN 0x0 -#define RTAS_INITIATOR_CPU 0x1 -#define RTAS_INITIATOR_PCI 0x2 -#define RTAS_INITIATOR_ISA 0x3 -#define RTAS_INITIATOR_MEMORY 0x4 -#define RTAS_INITIATOR_POWERMGM 0x5 - -/* RTAS event target */ -#define RTAS_TARGET_UNKNOWN 0x0 -#define RTAS_TARGET_CPU 0x1 -#define RTAS_TARGET_PCI 0x2 -#define RTAS_TARGET_ISA 0x3 -#define RTAS_TARGET_MEMORY 0x4 -#define RTAS_TARGET_POWERMGM 0x5 - -/* RTAS event type */ -#define RTAS_TYPE_RETRY 0x01 -#define RTAS_TYPE_TCE_ERR 0x02 -#define RTAS_TYPE_INTERN_DEV_FAIL 0x03 -#define RTAS_TYPE_TIMEOUT 0x04 -#define RTAS_TYPE_DATA_PARITY 0x05 -#define RTAS_TYPE_ADDR_PARITY 0x06 -#define RTAS_TYPE_CACHE_PARITY 0x07 -#define RTAS_TYPE_ADDR_INVALID 0x08 -#define RTAS_TYPE_ECC_UNCORR 0x09 -#define RTAS_TYPE_ECC_CORR 0x0a -#define RTAS_TYPE_EPOW 0x40 -#define RTAS_TYPE_PLATFORM 0xE0 -#define RTAS_TYPE_IO 0xE1 -#define RTAS_TYPE_INFO 0xE2 -#define RTAS_TYPE_DEALLOC 0xE3 -#define RTAS_TYPE_DUMP 0xE4 -/* I don't add PowerMGM events right now, this is a different topic */ -#define RTAS_TYPE_PMGM_POWER_SW_ON 0x60 -#define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61 -#define RTAS_TYPE_PMGM_LID_OPEN 0x62 -#define RTAS_TYPE_PMGM_LID_CLOSE 0x63 -#define RTAS_TYPE_PMGM_SLEEP_BTN 0x64 -#define RTAS_TYPE_PMGM_WAKE_BTN 0x65 -#define RTAS_TYPE_PMGM_BATTERY_WARN 0x66 -#define RTAS_TYPE_PMGM_BATTERY_CRIT 0x67 -#define RTAS_TYPE_PMGM_SWITCH_TO_BAT 0x68 -#define RTAS_TYPE_PMGM_SWITCH_TO_AC 0x69 -#define RTAS_TYPE_PMGM_KBD_OR_MOUSE 0x6a -#define RTAS_TYPE_PMGM_ENCLOS_OPEN 0x6b -#define RTAS_TYPE_PMGM_ENCLOS_CLOSED 0x6c -#define RTAS_TYPE_PMGM_RING_INDICATE 0x6d -#define RTAS_TYPE_PMGM_LAN_ATTENTION 0x6e -#define RTAS_TYPE_PMGM_TIME_ALARM 0x6f -#define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 -#define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 - -struct rtas_error_log { - unsigned long version:8; /* Architectural version */ - unsigned long severity:3; /* Severity level of error */ - unsigned long disposition:2; /* Degree of recovery */ - unsigned long extended:1; /* extended log present? */ - unsigned long /* reserved */ :2; /* Reserved for future use */ - unsigned long initiator:4; /* Initiator of event */ - unsigned long target:4; /* Target of failed operation */ - unsigned long type:8; /* General event or error*/ - unsigned long extended_log_length:32; /* length in bytes */ - unsigned char buffer[1]; -}; - -struct flash_block { - char *data; - unsigned long length; -}; - -/* This struct is very similar but not identical to - * that needed by the rtas flash update. - * All we need to do for rtas is rewrite num_blocks - * into a version/length and translate the pointers - * to absolute. - */ -#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) -struct flash_block_list { - unsigned long num_blocks; - struct flash_block_list *next; - struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; -}; -struct flash_block_list_header { /* just the header of flash_block_list */ - unsigned long num_blocks; - struct flash_block_list *next; -}; -extern struct flash_block_list_header rtas_firmware_flash_list; - -extern struct rtas_t rtas; - -extern void enter_rtas(unsigned long); -extern int rtas_token(const char *service); -extern int rtas_call(int token, int, int, int *, ...); -extern void call_rtas_display_status(unsigned char); -extern void rtas_restart(char *cmd); -extern void rtas_power_off(void); -extern void rtas_halt(void); -extern void rtas_os_term(char *str); -extern int rtas_get_sensor(int sensor, int index, int *state); -extern int rtas_get_power_level(int powerdomain, int *level); -extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); -extern int rtas_set_indicator(int indicator, int index, int new_value); -extern void rtas_progress(char *s, unsigned short hex); -extern void rtas_initialize(void); - -struct rtc_time; -extern void rtas_get_boot_time(struct rtc_time *rtc_time); -extern void rtas_get_rtc_time(struct rtc_time *rtc_time); -extern int rtas_set_rtc_time(struct rtc_time *rtc_time); - -/* Given an RTAS status code of 9900..9905 compute the hinted delay */ -unsigned int rtas_extended_busy_delay_time(int status); -static inline int rtas_is_extended_busy(int status) -{ - return status >= 9900 && status <= 9909; -} - -extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); - -/* Error types logged. */ -#define ERR_FLAG_ALREADY_LOGGED 0x0 -#define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ -#define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ -#define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ - -/* All the types and not flags */ -#define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) - -#define RTAS_DEBUG KERN_DEBUG "RTAS: " - -#define RTAS_ERROR_LOG_MAX 2048 - -/* - * Return the firmware-specified size of the error log buffer - * for all rtas calls that require an error buffer argument. - * This includes 'check-exception' and 'rtas-last-error'. - */ -extern int rtas_get_error_log_max(void); - -/* Event Scan Parameters */ -#define EVENT_SCAN_ALL_EVENTS 0xf0000000 -#define SURVEILLANCE_TOKEN 9000 -#define LOG_NUMBER 64 /* must be a power of two */ -#define LOG_NUMBER_MASK (LOG_NUMBER-1) - -/* Some RTAS ops require a data buffer and that buffer must be < 4G. - * Rather than having a memory allocator, just use this buffer - * (get the lock first), make the RTAS call. Copy the data instead - * of holding the buffer for long. - */ - -#define RTAS_DATA_BUF_SIZE 4096 -extern spinlock_t rtas_data_buf_lock; -extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; - -extern void rtas_stop_self(void); - -/* RMO buffer reserved for user-space RTAS use */ -extern unsigned long rtas_rmo_buf; - -#define GLOBAL_INTERRUPT_QUEUE 9005 - -#endif /* _PPC64_RTAS_H */ From 84d2f07e8e5e2424eec0f5acfef6792c924a0549 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 12 Oct 2005 15:32:05 -0700 Subject: [PATCH 0283/1940] CIFS: cifs_writepages should not write beyond end of file Signed-off-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/file.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 585a62aebd59..23af20d5af7c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1011,6 +1011,7 @@ static int cifs_writepages(struct address_space *mapping, pgoff_t index; int is_range = 0; struct kvec iov[32]; + int len; int n_iov = 0; pgoff_t next; int nr_pages; @@ -1124,16 +1125,26 @@ static int cifs_writepages(struct address_space *mapping, unlock_page(page); break; } + + if (page_offset(page) >= mapping->host->i_size) { + done = 1; + unlock_page(page); + break; + } + /* * BB can we get rid of this? pages are held by pvec */ page_cache_get(page); + len = min(mapping->host->i_size - page_offset(page), + (loff_t)PAGE_CACHE_SIZE); + /* reserve iov[0] for the smb header */ n_iov++; iov[n_iov].iov_base = kmap(page); - iov[n_iov].iov_len = PAGE_CACHE_SIZE; - bytes_to_write += PAGE_CACHE_SIZE; + iov[n_iov].iov_len = len; + bytes_to_write += len; if (first < 0) { first = i; From 4920960f577edcb0a5ef03823a53911cca5875e1 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 12 Oct 2005 15:55:09 +1000 Subject: [PATCH 0284/1940] powerpc: consolidate cputable.c Also simplify arch/ppc64/kernel/Makefile Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 2 +- arch/{ppc => powerpc}/kernel/cputable.c | 413 +++++++++++++++++------- arch/ppc/kernel/Makefile | 4 +- arch/ppc64/kernel/Makefile | 101 ++---- arch/ppc64/kernel/cputable.c | 260 --------------- include/asm-powerpc/cputable.h | 3 - 6 files changed, 337 insertions(+), 446 deletions(-) rename arch/{ppc => powerpc}/kernel/cputable.c (69%) delete mode 100644 arch/ppc64/kernel/cputable.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 931795380978..f03f6d4ffaa6 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -obj-y := semaphore.o +obj-y := semaphore.o cputable.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o diff --git a/arch/ppc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c similarity index 69% rename from arch/ppc/kernel/cputable.c rename to arch/powerpc/kernel/cputable.c index 207d4dd059d9..214f3b088edf 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1,8 +1,9 @@ /* - * arch/ppc/kernel/cputable.c - * * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) * + * Modifications for ppc64: + * Copyright (C) 2003 Dave Engebretsen + * * 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 @@ -20,7 +21,22 @@ #include struct cpu_spec* cur_cpu_spec = NULL; +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(cur_cpu_spec); +#endif +/* NOTE: + * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's + * the responsibility of the appropriate CPU save/restore functions to + * eventually copy these settings over. Those save/restore aren't yet + * part of the cputable though. That has to be fixed for both ppc32 + * and ppc64 + */ +#ifdef CONFIG_PPC64 +extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); +#else extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); @@ -29,35 +45,264 @@ extern void __setup_cpu_750fx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); +#endif /* CONFIG_PPC32 */ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); -#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ - !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ - !defined(CONFIG_BOOKE)) - /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... */ -#define COMMON_PPC (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ - PPC_FEATURE_HAS_MMU) +#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ + PPC_FEATURE_HAS_MMU) +#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) + /* We only set the spe features if the kernel was compiled with * spe support */ #ifdef CONFIG_SPE -#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE +#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE #else -#define PPC_FEATURE_SPE_COMP 0 +#define PPC_FEATURE_SPE_COMP 0 #endif struct cpu_spec cpu_specs[] = { +#ifdef CONFIG_PPC64 + { /* Power3 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00400000, + .cpu_name = "POWER3 (630)", + .cpu_features = CPU_FTRS_POWER3, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power3", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* Power3+ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00410000, + .cpu_name = "POWER3 (630+)", + .cpu_features = CPU_FTRS_POWER3, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power3", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* Northstar */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00330000, + .cpu_name = "RS64-II (northstar)", + .cpu_features = CPU_FTRS_RS64, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/rs64", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* Pulsar */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00340000, + .cpu_name = "RS64-III (pulsar)", + .cpu_features = CPU_FTRS_RS64, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/rs64", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* I-star */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00360000, + .cpu_name = "RS64-III (icestar)", + .cpu_features = CPU_FTRS_RS64, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/rs64", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* S-star */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00370000, + .cpu_name = "RS64-IV (sstar)", + .cpu_features = CPU_FTRS_RS64, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/rs64", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* Power4 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00350000, + .cpu_name = "POWER4 (gp)", + .cpu_features = CPU_FTRS_POWER4, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power4", + .oprofile_model = &op_model_rs64, +#endif + }, + { /* Power4+ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00380000, + .cpu_name = "POWER4+ (gq)", + .cpu_features = CPU_FTRS_POWER4, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power4", + .oprofile_model = &op_model_power4, +#endif + }, + { /* PPC970 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00390000, + .cpu_name = "PPC970", + .cpu_features = CPU_FTRS_PPC970, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/970", + .oprofile_model = &op_model_power4, +#endif + }, +#endif /* CONFIG_PPC64 */ +#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) + { /* PPC970FX */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003c0000, + .cpu_name = "PPC970FX", +#ifdef CONFIG_PPC32 + .cpu_features = CPU_FTRS_970_32, +#else + .cpu_features = CPU_FTRS_PPC970, +#endif + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/970", + .oprofile_model = &op_model_power4, +#endif + }, +#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ +#ifdef CONFIG_PPC64 + { /* PPC970MP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00440000, + .cpu_name = "PPC970MP", + .cpu_features = CPU_FTRS_PPC970, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/970", + .oprofile_model = &op_model_power4, +#endif + }, + { /* Power5 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003a0000, + .cpu_name = "POWER5 (gr)", + .cpu_features = CPU_FTRS_POWER5, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power5", + .oprofile_model = &op_model_power4, +#endif + }, + { /* Power5 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003b0000, + .cpu_name = "POWER5 (gs)", + .cpu_features = CPU_FTRS_POWER5, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power5", + .oprofile_model = &op_model_power4, +#endif + }, + { /* BE DD1.x */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00700000, + .cpu_name = "Cell Broadband Engine", + .cpu_features = CPU_FTRS_CELL, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_be, + }, + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "POWER4 (compatible)", + .cpu_features = CPU_FTRS_COMPATIBLE, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, + } +#endif /* CONFIG_PPC64 */ +#ifdef CONFIG_PPC32 #if CLASSIC_PPC - { /* 601 */ + { /* 601 */ .pvr_mask = 0xffff0000, .pvr_value = 0x00010000, .cpu_name = "601", .cpu_features = CPU_FTRS_PPC601, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR | + .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR | PPC_FEATURE_UNIFIED_CACHE, .icache_bsize = 32, .dcache_bsize = 32, @@ -67,7 +312,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00030000, .cpu_name = "603", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -77,7 +322,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00060000, .cpu_name = "603e", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -87,7 +332,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00070000, .cpu_name = "603ev", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -97,7 +342,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00040000, .cpu_name = "604", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 2, @@ -108,7 +353,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00090000, .cpu_name = "604e", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -119,7 +364,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00090000, .cpu_name = "604r", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -130,7 +375,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000a0000, .cpu_name = "604ev", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -141,7 +386,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00084202, .cpu_name = "740/750", .cpu_features = CPU_FTRS_740_NOTAU, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -152,7 +397,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00080100, .cpu_name = "750CX", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -163,7 +408,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00082200, .cpu_name = "750CX", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -174,7 +419,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00082210, .cpu_name = "750CXe", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -185,7 +430,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00083214, .cpu_name = "750CXe", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -196,7 +441,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00083000, .cpu_name = "745/755", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -207,7 +452,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000100, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX1, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -218,7 +463,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000200, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX2, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -229,7 +474,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000000, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -240,7 +485,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70020000, .cpu_name = "750GX", .cpu_features = CPU_FTRS_750GX, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -251,7 +496,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00080000, .cpu_name = "740/750", .cpu_features = CPU_FTRS_740, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -262,7 +507,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000c1101, .cpu_name = "7400 (1.1)", .cpu_features = CPU_FTRS_7400_NOTAU, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -273,7 +518,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000c0000, .cpu_name = "7400", .cpu_features = CPU_FTRS_7400, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -284,7 +529,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x800c0000, .cpu_name = "7410", .cpu_features = CPU_FTRS_7400, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -295,7 +540,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000200, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_20, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -306,7 +551,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000201, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_21, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -317,7 +562,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000000, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_23, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -328,7 +573,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010100, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455_1, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -339,7 +584,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010200, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455_20, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -350,7 +595,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010000, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -361,7 +606,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020100, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447_10, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -372,7 +617,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020101, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447_10, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -383,7 +628,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020000, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -394,7 +639,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80030000, .cpu_name = "7447A", .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -405,7 +650,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80040000, .cpu_name = "7448", .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC_COMP, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -416,7 +661,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00810000, .cpu_name = "82xx", .cpu_features = CPU_FTRS_82XX, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -426,7 +671,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00820000, .cpu_name = "G2_LE", .cpu_features = CPU_FTRS_G2_LE, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -436,7 +681,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00830000, .cpu_name = "e300", .cpu_features = CPU_FTRS_E300, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603 @@ -446,66 +691,11 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00000000, .cpu_name = "(generic PPC)", .cpu_features = CPU_FTRS_CLASSIC32, - .cpu_user_features = COMMON_PPC, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, }, #endif /* CLASSIC_PPC */ -#ifdef CONFIG_PPC64BRIDGE - { /* Power3 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00400000, - .cpu_name = "Power3 (630)", - .cpu_features = CPU_FTRS_POWER3_32, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - }, - { /* Power3+ */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00410000, - .cpu_name = "Power3 (630+)", - .cpu_features = CPU_FTRS_POWER3_32, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - }, - { /* I-star */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00360000, - .cpu_name = "I-star", - .cpu_features = CPU_FTRS_POWER3_32, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - }, - { /* S-star */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00370000, - .cpu_name = "S-star", - .cpu_features = CPU_FTRS_POWER3_32, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - }, -#endif /* CONFIG_PPC64BRIDGE */ -#ifdef CONFIG_POWER4 - { /* PPC970FX */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x003c0000, - .cpu_name = "PPC970FX", - .cpu_features = CPU_FTRS_970_32, - .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970 - }, -#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8xx { /* 8xx */ .pvr_mask = 0xffff0000, @@ -664,7 +854,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x40000850, .cpu_name = "440EP Rev. A", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ + .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, }, @@ -673,11 +863,11 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x400008d3, .cpu_name = "440EP Rev. B", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ + .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, }, - { /* 440GP Rev. B */ + { /* 440GP Rev. B */ .pvr_mask = 0xf0000fff, .pvr_value = 0x40000440, .cpu_name = "440GP Rev. B", @@ -686,7 +876,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, - { /* 440GP Rev. C */ + { /* 440GP Rev. C */ .pvr_mask = 0xf0000fff, .pvr_value = 0x40000481, .cpu_name = "440GP Rev. C", @@ -742,7 +932,7 @@ struct cpu_spec cpu_specs[] = { }, #endif /* CONFIG_44x */ #ifdef CONFIG_FSL_BOOKE - { /* e200z5 */ + { /* e200z5 */ .pvr_mask = 0xfff00000, .pvr_value = 0x81000000, .cpu_name = "e200z5", @@ -753,7 +943,7 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_UNIFIED_CACHE, .dcache_bsize = 32, }, - { /* e200z6 */ + { /* e200z6 */ .pvr_mask = 0xfff00000, .pvr_value = 0x81100000, .cpu_name = "e200z6", @@ -765,7 +955,7 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_UNIFIED_CACHE, .dcache_bsize = 32, }, - { /* e500 */ + { /* e500 */ .pvr_mask = 0xffff0000, .pvr_value = 0x80200000, .cpu_name = "e500", @@ -778,7 +968,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 32, .num_pmcs = 4, }, - { /* e500v2 */ + { /* e500v2 */ .pvr_mask = 0xffff0000, .pvr_value = 0x80210000, .cpu_name = "e500v2", @@ -803,4 +993,5 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 32, } #endif /* !CLASSIC_PPC */ +#endif /* CONFIG_PPC32 */ }; diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 59b6b62d1120..0cba463adf9a 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -15,7 +15,7 @@ extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ syscalls.o setup.o \ - cputable.o ppc_htab.o perfmon.o + ppc_htab.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_POWER4) += cpu_setup_power4.o @@ -39,7 +39,7 @@ endif else obj-y := irq.o idle.o time.o \ signal.o ptrace.o align.o \ - syscalls.o cputable.o perfmon.o + syscalls.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 5569ea7e6830..834aef034b77 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -7,13 +7,17 @@ ifneq ($(CONFIG_PPC_MERGE),y) EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds -obj-y := setup.o entry.o irq.o idle.o dma.o \ - time.o signal.o syscalls.o misc.o ptrace.o \ +obj-y := setup.o entry.o misc.o prom.o + +endif + +obj-y += irq.o idle.o dma.o \ + time.o signal.o syscalls.o ptrace.o \ align.o bitops.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o \ - cputable.o cpu_setup_power4.o \ - iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o + cpu_setup_power4.o \ + iommu.o sysfs.o vdso.o pmc.o firmware.o obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o @@ -22,72 +26,10 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o - -obj-$(CONFIG_PPC_PSERIES) += rtasd.o ras.o udbg_16550.o - -obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ - bpa_iic.o spider-pic.o - -obj-$(CONFIG_KEXEC) += machine_kexec.o -obj-$(CONFIG_EEH) += eeh.o -obj-$(CONFIG_PROC_FS) += proc_ppc64.o -obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o -obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o -obj-$(CONFIG_RTAS_PROC) += rtas-proc.o -obj-$(CONFIG_SCANLOG) += scanlog.o -obj-$(CONFIG_LPARCFG) += lparcfg.o -obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o -obj-$(CONFIG_BOOTX_TEXT) += btext.o -obj-$(CONFIG_HVCS) += hvcserver.o - -obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y) -obj-$(CONFIG_XICS) += xics.o -obj-$(CONFIG_MPIC) += mpic.o - -obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ - pmac_time.o pmac_nvram.o pmac_low_i2c.o \ - udbg_scc.o - -obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ - udbg_16550.o - -obj-$(CONFIG_U3_DART) += u3_iommu.o - -ifdef CONFIG_SMP -obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o -obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o -endif - -obj-$(CONFIG_KPROBES) += kprobes.o - -CFLAGS_ioctl32.o += -Ifs/ - -ifeq ($(CONFIG_PPC_ISERIES),y) -arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s -AFLAGS_head.o += -Iarch/powerpc/kernel -endif - -else - -# Things still needed from here by the merged ppc code - -obj-y := irq.o idle.o dma.o \ - time.o signal.o syscalls.o ptrace.o \ - align.o bitops.o pacaData.o \ - udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ - ptrace32.o signal32.o rtc.o \ - cputable.o cpu_setup_power4.o \ - iommu.o sysfs.o vdso.o pmc.o firmware.o -obj-y += vdso32/ vdso64/ - -pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o - -obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) - obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o +ifneq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o +endif obj-$(CONFIG_PPC_PSERIES) += rtasd.o ras.o udbg_16550.o @@ -100,15 +42,28 @@ obj-$(CONFIG_PROC_FS) += proc_ppc64.o obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_MODULES) += module.o +ifneq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_MODULES) += ppc_ksyms.o +endif obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o +ifneq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_BOOTX_TEXT) += btext.o +endif obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o +ifneq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_MPIC) += mpic.o + +obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ + pmac_time.o pmac_nvram.o pmac_low_i2c.o \ + udbg_scc.o +endif obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ udbg_16550.o @@ -116,6 +71,9 @@ obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ obj-$(CONFIG_U3_DART) += u3_iommu.o ifdef CONFIG_SMP +ifneq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o +endif obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o endif @@ -123,4 +81,9 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ +ifneq ($(CONFIG_PPC_MERGE),y) +ifeq ($(CONFIG_PPC_ISERIES),y) +arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s +AFLAGS_head.o += -Iarch/powerpc/kernel +endif endif diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c deleted file mode 100644 index 5134c53d536d..000000000000 --- a/arch/ppc64/kernel/cputable.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * arch/ppc64/kernel/cputable.c - * - * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * Modifications for ppc64: - * Copyright (C) 2003 Dave Engebretsen - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -struct cpu_spec* cur_cpu_spec = NULL; -EXPORT_SYMBOL(cur_cpu_spec); - -/* NOTE: - * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's - * the responsibility of the appropriate CPU save/restore functions to - * eventually copy these settings over. Those save/restore aren't yet - * part of the cputable though. That has to be fixed for both ppc32 - * and ppc64 - */ -extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); - -struct cpu_spec cpu_specs[] = { - { /* Power3 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00400000, - .cpu_name = "POWER3 (630)", - .cpu_features = CPU_FTRS_POWER3, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power3", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* Power3+ */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00410000, - .cpu_name = "POWER3 (630+)", - .cpu_features = CPU_FTRS_POWER3, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power3", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* Northstar */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00330000, - .cpu_name = "RS64-II (northstar)", - .cpu_features = CPU_FTRS_RS64, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* Pulsar */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00340000, - .cpu_name = "RS64-III (pulsar)", - .cpu_features = CPU_FTRS_RS64, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* I-star */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00360000, - .cpu_name = "RS64-III (icestar)", - .cpu_features = CPU_FTRS_RS64, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* S-star */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00370000, - .cpu_name = "RS64-IV (sstar)", - .cpu_features = CPU_FTRS_RS64, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power3, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* Power4 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00350000, - .cpu_name = "POWER4 (gp)", - .cpu_features = CPU_FTRS_POWER4, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power4, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power4", - .oprofile_model = &op_model_rs64, -#endif - }, - { /* Power4+ */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00380000, - .cpu_name = "POWER4+ (gq)", - .cpu_features = CPU_FTRS_POWER4, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_power4, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power4", - .oprofile_model = &op_model_power4, -#endif - }, - { /* PPC970 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00390000, - .cpu_name = "PPC970", - .cpu_features = CPU_FTRS_PPC970, - .cpu_user_features = COMMON_USER_PPC64 | - PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/970", - .oprofile_model = &op_model_power4, -#endif - }, - { /* PPC970FX */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x003c0000, - .cpu_name = "PPC970FX", - .cpu_features = CPU_FTRS_PPC970, - .cpu_user_features = COMMON_USER_PPC64 | - PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/970", - .oprofile_model = &op_model_power4, -#endif - }, - { /* PPC970MP */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00440000, - .cpu_name = "PPC970MP", - .cpu_features = CPU_FTRS_PPC970, - .cpu_user_features = COMMON_USER_PPC64 | - PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .cpu_setup = __setup_cpu_ppc970, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/970", - .oprofile_model = &op_model_power4, -#endif - }, - { /* Power5 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x003a0000, - .cpu_name = "POWER5 (gr)", - .cpu_features = CPU_FTRS_POWER5, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_power4, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power5", - .oprofile_model = &op_model_power4, -#endif - }, - { /* Power5 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x003b0000, - .cpu_name = "POWER5 (gs)", - .cpu_features = CPU_FTRS_POWER5, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_power4, -#ifdef CONFIG_OPROFILE - .oprofile_cpu_type = "ppc64/power5", - .oprofile_model = &op_model_power4, -#endif - }, - { /* BE DD1.x */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00700000, - .cpu_name = "Cell Broadband Engine", - .cpu_features = CPU_FTRS_CELL, - .cpu_user_features = COMMON_USER_PPC64 | - PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .cpu_setup = __setup_cpu_be, - }, - { /* default match */ - .pvr_mask = 0x00000000, - .pvr_value = 0x00000000, - .cpu_name = "POWER4 (compatible)", - .cpu_features = CPU_FTRS_COMPATIBLE, - .cpu_user_features = COMMON_USER_PPC64, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_power4, - } -}; diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index a4a50d08d384..373642aff7d8 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -119,9 +119,6 @@ extern void do_cpu_ftr_fixups(unsigned long offset); #ifndef __ASSEMBLY__ -#define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \ - PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU) - #define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL) From 7062018687da3d5d4966f58d6f0a58528b1e331b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 12 Oct 2005 17:44:55 +1000 Subject: [PATCH 0285/1940] powerpc: create 32 bit LOADADDR macro and use it in misc_32.S Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/misc_32.S | 6 ++---- include/asm-powerpc/ppc_asm.h | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index fa8c20ffec78..27274108116f 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -43,8 +43,7 @@ _GLOBAL(reloc_offset) mflr r0 bl 1f 1: mflr r3 - lis r4,1b@ha - addi r4,r4,1b@l + LOADADDR(r4,1b) subf r3,r4,r3 mtlr r0 blr @@ -56,8 +55,7 @@ _GLOBAL(add_reloc_offset) mflr r0 bl 1f 1: mflr r5 - lis r4,1b@ha - addi r4,r4,1b@l + LOADADDR(r4,1b) subf r5,r4,r5 add r3,r3,r5 mtlr r0 diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index e4350e406d2a..6aae414a161b 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -193,6 +193,10 @@ GLUE(.,name): #define CMPI cmpdi #else /* 32-bit */ +#define LOADADDR(rn,name) \ + lis rn,name@ha \ + addi rn,rn,name@l + #define LOADBASE(rn,name) \ lis rn,name@ha From 0f17d0742f27b7a69b0e2dfb21190f06ea3a9087 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 12 Oct 2005 23:23:44 +1000 Subject: [PATCH 0286/1940] powerpc: make 64 bit binaries work Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/process.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index f09908a0beea..92bc75f61ca6 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -620,7 +620,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->nip = start; regs->msr = MSR_USER; #else - if (test_thread_flag(TIF_32BIT)) { + { unsigned long entry, toc, load_addr = regs->gpr[2]; /* start is a relocated pointer to the function descriptor for @@ -641,10 +641,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->nip = entry; regs->gpr[2] = toc; regs->msr = MSR_USER64; - } else { - regs->nip = start; - regs->gpr[2] = 0; - regs->msr = MSR_USER32; } #endif From d4bf9a7858a0766cafb21dcb66ff9a5d92c1cd09 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 13 Oct 2005 13:40:54 +1000 Subject: [PATCH 0287/1940] ppc64: merge binfmt_elf32.c and use start_thread for both 32 and 64 bit bineries. Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 1 + arch/{ppc64 => powerpc}/kernel/binfmt_elf32.c | 3 -- arch/powerpc/kernel/process.c | 6 ++- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/sys_ppc32.c | 46 ------------------- 5 files changed, 7 insertions(+), 51 deletions(-) rename arch/{ppc64 => powerpc}/kernel/binfmt_elf32.c (94%) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f03f6d4ffaa6..adac749a1a8a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -11,6 +11,7 @@ CFLAGS_btext.o += -fPIC endif obj-y := semaphore.o cputable.o +obj-$(CONFIG_PPC64) += binfmt_elf32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o diff --git a/arch/ppc64/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c similarity index 94% rename from arch/ppc64/kernel/binfmt_elf32.c rename to arch/powerpc/kernel/binfmt_elf32.c index fadc699a0497..8ad6b0f33651 100644 --- a/arch/ppc64/kernel/binfmt_elf32.c +++ b/arch/powerpc/kernel/binfmt_elf32.c @@ -70,9 +70,6 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) value->tv_sec = jiffies / HZ; } -extern void start_thread32(struct pt_regs *, unsigned long, unsigned long); -#undef start_thread -#define start_thread start_thread32 #define init_elf_binfmt init_elf32_binfmt #include "../../../fs/binfmt_elf.c" diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 92bc75f61ca6..193c8c1bf132 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -620,7 +620,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->nip = start; regs->msr = MSR_USER; #else - { + if (!test_thread_flag(TIF_32BIT)) { unsigned long entry, toc, load_addr = regs->gpr[2]; /* start is a relocated pointer to the function descriptor for @@ -641,6 +641,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->nip = entry; regs->gpr[2] = toc; regs->msr = MSR_USER64; + } else { + regs->nip = start; + regs->gpr[2] = 0; + regs->msr = MSR_USER32; } #endif diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 834aef034b77..a724f6fc04da 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -14,7 +14,7 @@ endif obj-y += irq.o idle.o dma.o \ time.o signal.o syscalls.o ptrace.o \ align.o bitops.o pacaData.o \ - udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ + udbg.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o \ cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 1cacf61f9c91..b53f565ee443 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -609,52 +609,6 @@ long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2, return error; } -/* Set up a thread for executing a new program. */ -void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp) -{ - set_fs(USER_DS); - - /* - * If we exec out of a kernel thread then thread.regs will not be - * set. Do it now. - */ - if (!current->thread.regs) { - unsigned long childregs = (unsigned long)current->thread_info + - THREAD_SIZE; - childregs -= sizeof(struct pt_regs); - current->thread.regs = (struct pt_regs *)childregs; - } - - /* - * ELF_PLAT_INIT already clears all registers but it also sets r2. - * So just clear r2 here. - */ - regs->gpr[2] = 0; - - regs->nip = nip; - regs->gpr[1] = sp; - regs->msr = MSR_USER32; -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = 0; -#endif /* CONFIG_SMP */ - current->thread.fpscr = 0; - memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); -#ifdef CONFIG_ALTIVEC -#ifndef CONFIG_SMP - if (last_task_used_altivec == current) - last_task_used_altivec = 0; -#endif /* CONFIG_SMP */ - memset(current->thread.vr, 0, sizeof(current->thread.vr)); - current->thread.vscr.u[0] = 0; - current->thread.vscr.u[1] = 0; - current->thread.vscr.u[2] = 0; - current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ - current->thread.vrsave = 0; - current->thread.used_vr = 0; -#endif /* CONFIG_ALTIVEC */ -} - /* Note: it is necessary to treat option as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) From ae2752050d21f5aef811c362d3a47dce4694068d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 13 Oct 2005 14:12:25 +1000 Subject: [PATCH 0288/1940] ppc64: fix arch/ppc64/kernel/Makefile Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index a724f6fc04da..615484b09f90 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -8,6 +8,7 @@ EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds obj-y := setup.o entry.o misc.o prom.o +obj-$(CONFIG_PPC_OF) += of_device.o endif @@ -20,8 +21,6 @@ obj-y += irq.o idle.o dma.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o obj-y += vdso32/ vdso64/ -obj-$(CONFIG_PPC_OF) += of_device.o - pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) From eec5ef909888cd9d25a61f904cd8f0db50ea0455 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 13 Oct 2005 15:16:25 +1000 Subject: [PATCH 0289/1940] ppc64: use powerpc of_device.c Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 3 +- arch/ppc64/kernel/Makefile | 1 - arch/ppc64/kernel/of_device.c | 274 ---------------------------------- 3 files changed, 2 insertions(+), 276 deletions(-) delete mode 100644 arch/ppc64/kernel/of_device.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index adac749a1a8a..bce253969e4c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -14,6 +14,7 @@ obj-y := semaphore.o cputable.o obj-$(CONFIG_PPC64) += binfmt_elf32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o +obj-$(CONFIG_PPC_OF) += of_device.o ifeq ($(CONFIG_PPC_MERGE),y) @@ -32,7 +33,7 @@ obj-y += process.o init_task.o \ prom.o systbl.o traps.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o -obj-$(CONFIG_PPC_OF) += prom_init.o of_device.o +obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 615484b09f90..1a8f3532885a 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -8,7 +8,6 @@ EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds obj-y := setup.o entry.o misc.o prom.o -obj-$(CONFIG_PPC_OF) += of_device.o endif diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c deleted file mode 100644 index 9f200f0f2ad5..000000000000 --- a/arch/ppc64/kernel/of_device.c +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in - * @dev: the of device structure to match against - * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. - */ -const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) -{ - if (!dev->node) - return NULL; - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); - if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); - if (matches->compatible[0]) - match &= device_is_compatible(dev->node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; -} - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_device_id * matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; -} - -struct of_device *of_dev_get(struct of_device *dev) -{ - struct device *tmp; - - if (!dev) - return NULL; - tmp = get_device(&dev->dev); - if (tmp) - return to_of_device(tmp); - else - return NULL; -} - -void of_dev_put(struct of_device *dev) -{ - if (dev) - put_device(&dev->dev); -} - - -static int of_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_device_remove(struct device *dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_device_resume(struct device * dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -struct bus_type of_platform_bus_type = { - .name = "of_platform", - .match = of_platform_bus_match, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; - -static int __init of_bus_driver_init(void) -{ - return bus_register(&of_platform_bus_type); -} - -postcore_initcall(of_bus_driver_init); - -int of_register_driver(struct of_platform_driver *drv) -{ - int count = 0; - - /* initialize common driver fields */ - drv->driver.name = drv->name; - drv->driver.bus = &of_platform_bus_type; - drv->driver.probe = of_device_probe; - drv->driver.remove = of_device_remove; - - /* register with core */ - count = driver_register(&drv->driver); - return count ? count : 1; -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - - -static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); -} - -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); - -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - kfree(ofdev); -} - -int of_device_register(struct of_device *ofdev) -{ - int rc; - struct of_device **odprop; - - BUG_ON(ofdev->node == NULL); - - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (!odprop) { - struct property *new_prop; - - new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), - GFP_KERNEL); - if (new_prop == NULL) - return -ENOMEM; - new_prop->name = "linux,device"; - new_prop->length = sizeof(sizeof(struct of_device *)); - new_prop->value = (unsigned char *)&new_prop[1]; - odprop = (struct of_device **)new_prop->value; - *odprop = NULL; - prom_add_property(ofdev->node, new_prop); - } - *odprop = ofdev; - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; -} - -void of_device_unregister(struct of_device *ofdev) -{ - struct of_device **odprop; - - device_remove_file(&ofdev->dev, &dev_attr_devspec); - - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (odprop) - *odprop = NULL; - - device_unregister(&ofdev->dev); -} - -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->node = np; - dev->dma_mask = 0xffffffffUL; - dev->dev.dma_mask = &dev->dma_mask; - dev->dev.parent = parent; - dev->dev.bus = &of_platform_bus_type; - dev->dev.release = of_release_dev; - - strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); - - if (of_device_register(dev) != 0) { - kfree(dev); - return NULL; - } - - return dev; -} - - -EXPORT_SYMBOL(of_match_device); -EXPORT_SYMBOL(of_platform_bus_type); -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); -EXPORT_SYMBOL(of_device_register); -EXPORT_SYMBOL(of_device_unregister); -EXPORT_SYMBOL(of_dev_get); -EXPORT_SYMBOL(of_dev_put); -EXPORT_SYMBOL(of_platform_device_create); -EXPORT_SYMBOL(of_release_dev); From e8a30302abc42a0c537b9326883523da9963deb6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 13 Oct 2005 15:52:04 +1000 Subject: [PATCH 0290/1940] powerpc: merge ptrace.c Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 2 +- arch/{ppc => powerpc}/kernel/ptrace.c | 168 +++++++++--- arch/ppc/kernel/Makefile | 4 +- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/ptrace.c | 363 -------------------------- 5 files changed, 141 insertions(+), 398 deletions(-) rename arch/{ppc => powerpc}/kernel/ptrace.c (79%) delete mode 100644 arch/ppc64/kernel/ptrace.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index bce253969e4c..ae97295f270d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -obj-y := semaphore.o cputable.o +obj-y := semaphore.o cputable.o ptrace.o obj-$(CONFIG_PPC64) += binfmt_elf32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o diff --git a/arch/ppc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c similarity index 79% rename from arch/ppc/kernel/ptrace.c rename to arch/powerpc/kernel/ptrace.c index e7aee4108dea..336b8bf542d7 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1,6 +1,4 @@ /* - * arch/ppc/kernel/ptrace.c - * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -17,6 +15,7 @@ * this archive for more details. */ +#include #include #include #include @@ -29,13 +28,19 @@ #include #include #include +#ifdef CONFIG_PPC32 #include +#endif #include #include #include #include +#ifdef CONFIG_PPC64 +#include +#endif +#ifdef CONFIG_PPC32 /* * Set of msr bits that gdb can change on behalf of a process. */ @@ -44,12 +49,14 @@ #else #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) #endif +#endif /* CONFIG_PPC32 */ /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ +#ifdef CONFIG_PPC32 /* * Get contents of register REGNO in task TASK. */ @@ -228,6 +235,7 @@ clear_single_step(struct task_struct *task) #endif } } +#endif /* CONFIG_PPC32 */ /* * Called by kernel/ptrace.c when detaching.. @@ -296,25 +304,28 @@ int sys_ptrace(long request, long pid, long addr, long data) } /* read the word at location addr in the USER area. */ - /* XXX this will need fixing for 64-bit */ case PTRACE_PEEKUSR: { unsigned long index, tmp; ret = -EIO; /* convert to index and check */ +#ifdef CONFIG_PPC32 index = (unsigned long) addr >> 2; - if ((addr & 3) || index > PT_FPSCR - || child->thread.regs == NULL) + if ((addr & 3) || (index > PT_FPSCR) + || (child->thread.regs == NULL)) +#else + index = (unsigned long) addr >> 3; + if ((addr & 7) || (index > PT_FPSCR)) +#endif break; +#ifdef CONFIG_PPC32 CHECK_FULL_REGS(child->thread.regs); +#endif if (index < PT_FPR0) { tmp = get_reg(child, (int) index); } else { - preempt_disable(); - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); - preempt_enable(); + flush_fp_to_thread(child); tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0]; } ret = put_user(tmp,(unsigned long __user *) data); @@ -325,7 +336,8 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: ret = 0; - if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + if (access_process_vm(child, addr, &data, sizeof(data), 1) + == sizeof(data)) break; ret = -EIO; break; @@ -336,21 +348,25 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; /* convert to index and check */ +#ifdef CONFIG_PPC32 index = (unsigned long) addr >> 2; - if ((addr & 3) || index > PT_FPSCR - || child->thread.regs == NULL) + if ((addr & 3) || (index > PT_FPSCR) + || (child->thread.regs == NULL)) +#else + index = (unsigned long) addr >> 3; + if ((addr & 7) || (index > PT_FPSCR)) +#endif break; +#ifdef CONFIG_PPC32 CHECK_FULL_REGS(child->thread.regs); +#endif if (index == PT_ORIG_R3) break; if (index < PT_FPR0) { ret = put_reg(child, index, data); } else { - preempt_disable(); - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); - preempt_enable(); + flush_fp_to_thread(child); ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data; ret = 0; } @@ -362,11 +378,10 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if (!valid_signal(data)) break; - if (request == PTRACE_SYSCALL) { + if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } else { + else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } child->exit_code = data; /* make sure the single step bit is not set. */ clear_single_step(child); @@ -404,28 +419,102 @@ int sys_ptrace(long request, long pid, long addr, long data) break; } +#ifdef CONFIG_PPC64 + case PTRACE_GET_DEBUGREG: { + ret = -EINVAL; + /* We only support one DABR and no IABRS at the moment */ + if (addr > 0) + break; + ret = put_user(child->thread.dabr, + (unsigned long __user *)data); + break; + } + + case PTRACE_SET_DEBUGREG: + ret = ptrace_set_debugreg(child, addr, data); + break; +#endif + case PTRACE_DETACH: ret = ptrace_detach(child, data); break; +#ifdef CONFIG_PPC64 + case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ + int i; + unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; + unsigned long __user *tmp = (unsigned long __user *)addr; + + for (i = 0; i < 32; i++) { + ret = put_user(*reg, tmp); + if (ret) + break; + reg++; + tmp++; + } + break; + } + + case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ + int i; + unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; + unsigned long __user *tmp = (unsigned long __user *)addr; + + for (i = 0; i < 32; i++) { + ret = get_user(*reg, tmp); + if (ret) + break; + reg++; + tmp++; + } + break; + } + + case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */ + int i; + unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; + unsigned long __user *tmp = (unsigned long __user *)addr; + + flush_fp_to_thread(child); + + for (i = 0; i < 32; i++) { + ret = put_user(*reg, tmp); + if (ret) + break; + reg++; + tmp++; + } + break; + } + + case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */ + int i; + unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; + unsigned long __user *tmp = (unsigned long __user *)addr; + + flush_fp_to_thread(child); + + for (i = 0; i < 32; i++) { + ret = get_user(*reg, tmp); + if (ret) + break; + reg++; + tmp++; + } + break; + } +#endif /* CONFIG_PPC64 */ + #ifdef CONFIG_ALTIVEC case PTRACE_GETVRREGS: /* Get the child altivec register state. */ - preempt_disable(); - if (child->thread.regs->msr & MSR_VEC) - giveup_altivec(child); - preempt_enable(); + flush_altivec_to_thread(child); ret = get_vrregs((unsigned long __user *)data, child); break; case PTRACE_SETVRREGS: /* Set the child altivec register state. */ - /* this is to clear the MSR_VEC bit to force a reload - * of register state from memory */ - preempt_disable(); - if (child->thread.regs->msr & MSR_VEC) - giveup_altivec(child); - preempt_enable(); + flush_altivec_to_thread(child); ret = set_vrregs(child, (unsigned long __user *)data); break; #endif @@ -478,12 +567,21 @@ static void do_syscall_trace(void) void do_syscall_trace_enter(struct pt_regs *regs) { +#ifdef CONFIG_PPC64 + secure_computing(regs->gpr[0]); +#endif + if (test_thread_flag(TIF_SYSCALL_TRACE) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); if (unlikely(current->audit_context)) - audit_syscall_entry(current, AUDIT_ARCH_PPC, + audit_syscall_entry(current, +#ifdef CONFIG_PPC32 + AUDIT_ARCH_PPC, +#else + test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, +#endif regs->gpr[0], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]); @@ -491,17 +589,25 @@ void do_syscall_trace_enter(struct pt_regs *regs) void do_syscall_trace_leave(struct pt_regs *regs) { +#ifdef CONFIG_PPC32 secure_computing(regs->gpr[0]); +#endif if (unlikely(current->audit_context)) audit_syscall_exit(current, (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, regs->result); - if ((test_thread_flag(TIF_SYSCALL_TRACE)) + if ((test_thread_flag(TIF_SYSCALL_TRACE) +#ifdef CONFIG_PPC64 + || test_thread_flag(TIF_SINGLESTEP) +#endif + ) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); } +#ifdef CONFIG_PPC32 EXPORT_SYMBOL(do_syscall_trace_enter); EXPORT_SYMBOL(do_syscall_trace_leave); +#endif diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 0cba463adf9a..7d16b1f7cd31 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -13,7 +13,7 @@ extra-$(CONFIG_POWER4) += idle_power4.o extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ - process.o signal.o ptrace.o align.o \ + process.o signal.o align.o \ syscalls.o setup.o \ ppc_htab.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o @@ -38,7 +38,7 @@ endif else obj-y := irq.o idle.o time.o \ - signal.o ptrace.o align.o \ + signal.o align.o \ syscalls.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 1a8f3532885a..b1203b79edf0 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := setup.o entry.o misc.o prom.o endif obj-y += irq.o idle.o dma.o \ - time.o signal.o syscalls.o ptrace.o \ + time.o signal.o syscalls.o \ align.o bitops.o pacaData.o \ udbg.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o \ diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c deleted file mode 100644 index b1c044ca5756..000000000000 --- a/arch/ppc64/kernel/ptrace.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * linux/arch/ppc64/kernel/ptrace.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/m68k/kernel/ptrace.c" - * Copyright (C) 1994 by Hamish Macdonald - * Taken from linux/kernel/ptrace.c and modified for M680x0. - * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds - * - * Modified by Cort Dougan (cort@hq.fsmlabs.com) - * and Paul Mackerras (paulus@linuxcare.com.au). - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file README.legal in the main directory of - * this archive for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * does not yet catch signals sent when the child dies. - * in exit.c or in signal.c. - */ - -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure single step bits etc are not set. - */ -void ptrace_disable(struct task_struct *child) -{ - /* make sure the single step bit is not set. */ - clear_single_step(child); -} - -int sys_ptrace(long request, long pid, long addr, long data) -{ - struct task_struct *child; - int ret = -EPERM; - - lock_kernel(); - if (request == PTRACE_TRACEME) { - /* are we already being traced? */ - if (current->ptrace & PT_PTRACED) - goto out; - ret = security_ptrace(current->parent, current); - if (ret) - goto out; - /* set the ptrace bit in the process flags. */ - current->ptrace |= PT_PTRACED; - ret = 0; - goto out; - } - ret = -ESRCH; - read_lock(&tasklist_lock); - child = find_task_by_pid(pid); - if (child) - get_task_struct(child); - read_unlock(&tasklist_lock); - if (!child) - goto out; - - ret = -EPERM; - if (pid == 1) /* you may not mess with init */ - goto out_tsk; - - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - goto out_tsk; - } - - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - goto out_tsk; - - switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { - unsigned long tmp; - int copied; - - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - ret = -EIO; - if (copied != sizeof(tmp)) - break; - ret = put_user(tmp,(unsigned long __user *) data); - break; - } - - /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long index; - unsigned long tmp; - - ret = -EIO; - /* convert to index and check */ - index = (unsigned long) addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) - break; - - if (index < PT_FPR0) { - tmp = get_reg(child, (int)index); - } else { - flush_fp_to_thread(child); - tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0]; - } - ret = put_user(tmp,(unsigned long __user *) data); - break; - } - - /* If I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = 0; - if (access_process_vm(child, addr, &data, sizeof(data), 1) - == sizeof(data)) - break; - ret = -EIO; - break; - - /* write the word at location addr in the USER area */ - case PTRACE_POKEUSR: { - unsigned long index; - - ret = -EIO; - /* convert to index and check */ - index = (unsigned long) addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) - break; - - if (index == PT_ORIG_R3) - break; - if (index < PT_FPR0) { - ret = put_reg(child, index, data); - } else { - flush_fp_to_thread(child); - ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data; - ret = 0; - } - break; - } - - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - ret = -EIO; - if (!valid_signal(data)) - break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - /* make sure the single step bit is not set. */ - clear_single_step(child); - wake_up_process(child); - ret = 0; - break; - } - - /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: { - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - break; - child->exit_code = SIGKILL; - /* make sure the single step bit is not set. */ - clear_single_step(child); - wake_up_process(child); - break; - } - - case PTRACE_SINGLESTEP: { /* set the trap flag. */ - ret = -EIO; - if (!valid_signal(data)) - break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - set_single_step(child); - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - break; - } - - case PTRACE_GET_DEBUGREG: { - ret = -EINVAL; - /* We only support one DABR and no IABRS at the moment */ - if (addr > 0) - break; - ret = put_user(child->thread.dabr, - (unsigned long __user *)data); - break; - } - - case PTRACE_SET_DEBUGREG: - ret = ptrace_set_debugreg(child, addr, data); - break; - - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - - case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ - int i; - unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; - unsigned long __user *tmp = (unsigned long __user *)addr; - - for (i = 0; i < 32; i++) { - ret = put_user(*reg, tmp); - if (ret) - break; - reg++; - tmp++; - } - break; - } - - case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ - int i; - unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; - unsigned long __user *tmp = (unsigned long __user *)addr; - - for (i = 0; i < 32; i++) { - ret = get_user(*reg, tmp); - if (ret) - break; - reg++; - tmp++; - } - break; - } - - case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */ - int i; - unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; - unsigned long __user *tmp = (unsigned long __user *)addr; - - flush_fp_to_thread(child); - - for (i = 0; i < 32; i++) { - ret = put_user(*reg, tmp); - if (ret) - break; - reg++; - tmp++; - } - break; - } - - case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */ - int i; - unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; - unsigned long __user *tmp = (unsigned long __user *)addr; - - flush_fp_to_thread(child); - - for (i = 0; i < 32; i++) { - ret = get_user(*reg, tmp); - if (ret) - break; - reg++; - tmp++; - } - break; - } - -#ifdef CONFIG_ALTIVEC - case PTRACE_GETVRREGS: - /* Get the child altivec register state. */ - flush_altivec_to_thread(child); - ret = get_vrregs((unsigned long __user *)data, child); - break; - - case PTRACE_SETVRREGS: - /* Set the child altivec register state. */ - flush_altivec_to_thread(child); - ret = set_vrregs(child, (unsigned long __user *)data); - break; -#endif - - default: - ret = ptrace_request(child, request, addr, data); - break; - } -out_tsk: - put_task_struct(child); -out: - unlock_kernel(); - return ret; -} - -static void do_syscall_trace(void) -{ - /* the 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - -void do_syscall_trace_enter(struct pt_regs *regs) -{ - secure_computing(regs->gpr[0]); - - if (test_thread_flag(TIF_SYSCALL_TRACE) - && (current->ptrace & PT_PTRACED)) - do_syscall_trace(); - - if (unlikely(current->audit_context)) - audit_syscall_entry(current, - test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, - regs->gpr[0], - regs->gpr[3], regs->gpr[4], - regs->gpr[5], regs->gpr[6]); - -} - -void do_syscall_trace_leave(struct pt_regs *regs) -{ - if (unlikely(current->audit_context)) - audit_syscall_exit(current, - (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, - regs->result); - - if ((test_thread_flag(TIF_SYSCALL_TRACE) - || test_thread_flag(TIF_SINGLESTEP)) - && (current->ptrace & PT_PTRACED)) - do_syscall_trace(); -} From 190554db7bcd41935827f71d4f6f787673da208a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 13 Oct 2005 16:14:15 +1000 Subject: [PATCH 0291/1940] powerpc: fix uname -m It will now give ppc64 on 64bit platforms and ppc on 32bit platforms. Signed-off-by: Stephen Rothwell --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 8d1e7bd14c55..a5f2eb5f89ce 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -51,6 +51,8 @@ OLDARCH := ppc SZ := 32 endif +UTS_MACHINE := $(OLDARCH) + ifeq ($(HAS_BIARCH),y) override AS += -a$(SZ) override LD += -m elf$(SZ)ppc From 426c1a11a677e39a8c8ed744a521d0f4cb2e417e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 14 Oct 2005 14:51:42 +1000 Subject: [PATCH 0292/1940] powerpc: move iSeries/iSeries_pci.h to platforms/iseries The only real user of this file outside platforms/iseries was drivers/net/iseries_veth.c but all it wanted was ISERIES_HV_ADDR() so we move that to abs_addr.h (and lowercase it). Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/iommu.c | 6 ++++-- arch/powerpc/platforms/iseries/mf.c | 9 +++++---- arch/powerpc/platforms/iseries/pci.c | 7 ++++--- .../powerpc/platforms/iseries/pci.h | 19 ++++--------------- arch/powerpc/platforms/iseries/vpdinfo.c | 8 +++++--- arch/ppc64/kernel/pci_iommu.c | 13 ++++--------- drivers/net/iseries_veth.c | 11 ++++++----- include/asm-powerpc/iommu.h | 1 + include/asm-powerpc/prom.h | 1 + include/asm-ppc64/abs_addr.h | 7 +++++++ include/asm-ppc64/pci-bridge.h | 1 + include/asm-ppc64/prom.h | 1 + 12 files changed, 43 insertions(+), 41 deletions(-) rename include/asm-ppc64/iSeries/iSeries_pci.h => arch/powerpc/platforms/iseries/pci.h (80%) diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index e40c50b7cefc..e6f4a4ab57b8 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -30,8 +30,10 @@ #include #include #include +#include #include -#include + +#include "pci.h" extern struct list_head iSeries_Global_Device_List; @@ -127,7 +129,7 @@ static void iommu_table_getparms(struct device_node *dn, parms->itc_slotno = PCI_DN(dn)->LogicalSlot; parms->itc_virtbus = 0; - HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); + HvCallXm_getTceTableParms(iseries_hv_addr(parms)); if (parms->itc_size == 0) panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 82f5abab9afa..3f25f7fc79fc 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1064,10 +1065,10 @@ static void mf_getSrcHistory(char *buffer, int size) ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex(); ev->event.data.vsp_cmd.result_code = 0xFF; ev->event.data.vsp_cmd.reserved = 0; - ev->event.data.vsp_cmd.sub_data.page[0] = ISERIES_HV_ADDR(pages[0]); - ev->event.data.vsp_cmd.sub_data.page[1] = ISERIES_HV_ADDR(pages[1]); - ev->event.data.vsp_cmd.sub_data.page[2] = ISERIES_HV_ADDR(pages[2]); - ev->event.data.vsp_cmd.sub_data.page[3] = ISERIES_HV_ADDR(pages[3]); + ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]); + ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]); + ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]); + ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]); mb(); if (signal_event(ev) != 0) return; diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index f79c5982446b..fe34d1175818 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -34,15 +34,16 @@ #include #include #include +#include #include #include -#include #include #include #include "irq.h" +#include "pci.h" extern unsigned long io_page_mask; @@ -368,7 +369,7 @@ static void scan_PHB_slots(struct pci_controller *Phb) */ for (IdSel = 1; IdSel < MaxAgents; ++IdSel) { HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, - ISERIES_HV_ADDR(DevInfo), + iseries_hv_addr(DevInfo), sizeof(struct HvCallPci_DeviceInfo)); if (HvRc == 0) { if (DevInfo->deviceType == HvCallPci_NodeDevice) @@ -409,7 +410,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, "PCI:Connect EADs: 0x%02X.%02X.%02X\n", bus, SubBus, AgentId); HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, - ISERIES_HV_ADDR(BridgeInfo), + iseries_hv_addr(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo)); if (HvRc == 0) { printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n", diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/arch/powerpc/platforms/iseries/pci.h similarity index 80% rename from include/asm-ppc64/iSeries/iSeries_pci.h rename to arch/powerpc/platforms/iseries/pci.h index a4d88b49fd9f..e7d92504cb05 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/arch/powerpc/platforms/iseries/pci.h @@ -1,8 +1,8 @@ -#ifndef _ISERIES_64_PCI_H -#define _ISERIES_64_PCI_H +#ifndef _PLATFORMS_ISERIES_PCI_H +#define _PLATFORMS_ISERIES_PCI_H /* - * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001. + * Created by Allan Trautman on Tue Feb 20, 2001. * * Define some useful macros for the iSeries pci routines. * Copyright (C) 2001 Allan H Trautman, IBM Corporation @@ -30,8 +30,6 @@ * End Change Activity */ -#include -#include #include struct pci_dev; /* For Forward Reference */ @@ -42,9 +40,6 @@ struct pci_dev; /* For Forward Reference */ #define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber #define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber -#define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata) - -#define EADsMaxAgents 7 /* * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. @@ -59,12 +54,6 @@ struct pci_dev; /* For Forward Reference */ #define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) #define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) -/* - * Converts Virtual Address to Real Address for Hypervisor calls - */ -#define ISERIES_HV_ADDR(virtaddr) \ - (0x8000000000000000 | virt_to_abs(virtaddr)) - extern void iSeries_Device_Information(struct pci_dev*, int); -#endif /* _ISERIES_64_PCI_H */ +#endif /* _PLATFORMS_ISERIES_PCI_H */ diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index d8a6796924e2..6bd8da4f17fe 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -27,12 +27,14 @@ #include #include #include + #include #include - +#include #include #include -#include + +#include "pci.h" /* * Size of Bus VPD data @@ -212,7 +214,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, printk("PCI: Bus VPD Buffer allocation failure.\n"); return; } - BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr), + BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr), BUS_VPDSIZE); if (BusVpdLen == 0) { printk("PCI: Bus VPD Buffer zero length.\n"); diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index 2114dc9c59b5..bdf15dbbf4f0 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c @@ -1,8 +1,8 @@ /* * arch/ppc64/kernel/pci_iommu.c * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation - * - * Rewrite, cleanup, new allocation schemes: + * + * Rewrite, cleanup, new allocation schemes: * Copyright (C) 2004 Olof Johansson, IBM Corporation * * Dynamic DMA mapping support, platform-independent parts. @@ -11,19 +11,18 @@ * 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -39,10 +38,6 @@ #include #include -#ifdef CONFIG_PPC_ISERIES -#include -#endif /* CONFIG_PPC_ISERIES */ - /* * We can use ->sysdata directly and avoid the extra work in * pci_device_to_OF_node since ->sysdata will have been initialised diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 3d56cf5a4e23..db3bc2f6f0fa 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -70,8 +70,9 @@ #include #include #include + +#include #include -#include #include #include @@ -1397,13 +1398,13 @@ static inline void veth_build_dma_list(struct dma_chunk *list, * it just at the granularity of iSeries real->absolute * mapping? Indeed, given the way the allocator works, can we * count on them being absolutely contiguous? */ - list[0].addr = ISERIES_HV_ADDR(p); + list[0].addr = iseries_hv_addr(p); list[0].size = min(length, PAGE_SIZE - ((unsigned long)p & ~PAGE_MASK)); done = list[0].size; while (done < length) { - list[i].addr = ISERIES_HV_ADDR(p + done); + list[i].addr = iseries_hv_addr(p + done); list[i].size = min(length-done, PAGE_SIZE); done += list[i].size; i++; @@ -1496,8 +1497,8 @@ static void veth_receive(struct veth_lpar_connection *cnx, cnx->dst_inst, HvLpDma_AddressType_RealAddress, HvLpDma_AddressType_TceIndex, - ISERIES_HV_ADDR(&local_list), - ISERIES_HV_ADDR(&remote_list), + iseries_hv_addr(&local_list), + iseries_hv_addr(&remote_list), length); if (rc != HvLpDma_Rc_Good) { dev_kfree_skb_irq(skb); diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index f80ec8daf122..9d91bdd667ae 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h @@ -21,6 +21,7 @@ #ifndef _ASM_IOMMU_H #define _ASM_IOMMU_H +#include #include #include #include diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index efc40980cb48..8a21791c7cae 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -15,6 +15,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include #include #include #include diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-ppc64/abs_addr.h index 84c24d4cdb71..dc3fc3fefef2 100644 --- a/include/asm-ppc64/abs_addr.h +++ b/include/asm-ppc64/abs_addr.h @@ -63,4 +63,11 @@ static inline unsigned long phys_to_abs(unsigned long pa) #define virt_to_abs(va) phys_to_abs(__pa(va)) #define abs_to_virt(aa) __va(aa) +/* + * Converts Virtual Address to Real Address for + * Legacy iSeries Hypervisor calls + */ +#define iseries_hv_addr(virtaddr) \ + (0x8000000000000000 | virt_to_abs(virtaddr)) + #endif /* _ABS_ADDR_H */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 56863df18232..01bffca61f89 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -2,6 +2,7 @@ #ifndef _ASM_PCI_BRIDGE_H #define _ASM_PCI_BRIDGE_H +#include #include #include diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index cf0284e081ea..e8d0d2ab4c0f 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h @@ -14,6 +14,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include #include #include From bffa8fc3835b0d3c4a59af8aceeea3aba823b032 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 14 Oct 2005 15:06:10 +1000 Subject: [PATCH 0293/1940] powerpc: remove ISERIES_[SUB]BUS macros This allows us to simplify a couple of things. Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/iommu.c | 11 +++++------ arch/powerpc/platforms/iseries/pci.h | 9 --------- arch/powerpc/platforms/iseries/vpdinfo.c | 7 +++++-- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index e6f4a4ab57b8..533d9b467402 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -31,10 +31,9 @@ #include #include #include +#include #include -#include "pci.h" - extern struct list_head iSeries_Global_Device_List; @@ -114,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) * 2. TCE table per Bus. * 3. TCE Table per IOA. */ -static void iommu_table_getparms(struct device_node *dn, +static void iommu_table_getparms(struct pci_dn *pdn, struct iommu_table* tbl) { struct iommu_table_cb *parms; @@ -125,8 +124,8 @@ static void iommu_table_getparms(struct device_node *dn, memset(parms, 0, sizeof(*parms)); - parms->itc_busno = ISERIES_BUS(dn); - parms->itc_slotno = PCI_DN(dn)->LogicalSlot; + parms->itc_busno = pdn->DsaAddr.Dsa.busNumber; + parms->itc_slotno = pdn->LogicalSlot; parms->itc_virtbus = 0; HvCallXm_getTceTableParms(iseries_hv_addr(parms)); @@ -153,7 +152,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn) tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_getparms(dn, tbl); + iommu_table_getparms(pdn, tbl); /* Look for existing tce table */ pdn->iommu_table = iommu_table_find(tbl); diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h index e7d92504cb05..94b4bfdceadf 100644 --- a/arch/powerpc/platforms/iseries/pci.h +++ b/arch/powerpc/platforms/iseries/pci.h @@ -30,17 +30,8 @@ * End Change Activity */ -#include - struct pci_dev; /* For Forward Reference */ -/* - * Gets iSeries Bus, SubBus, DevFn using device_node structure - */ - -#define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber -#define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber - /* * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index 6bd8da4f17fe..dcdac995565c 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -243,6 +244,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) { struct device_node *DevNode = PciDev->sysdata; + struct pci_dn *pdn; u16 bus; u8 frame; char card[4]; @@ -255,8 +257,9 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) return; } - bus = ISERIES_BUS(DevNode); - subbus = ISERIES_SUBBUS(DevNode); + pdn = PCI_DN(DevNode); + bus = pdn->DsaAddr.Dsa.busNumber; + subbus = pdn->DsaAddr.Dsa.subBusNumber; agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); iSeries_Get_Location_Code(bus, agent, &frame, card); From 20f48ccfa015d8b8391bbf07fc27618453f44969 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 14 Oct 2005 16:49:58 +1000 Subject: [PATCH 0294/1940] powerpc: eliminate DsaAddr from pci_dn Signed-off-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/iommu.c | 2 +- arch/powerpc/platforms/iseries/pci.c | 20 +- arch/powerpc/platforms/iseries/pci.h | 13 ++ arch/powerpc/platforms/iseries/vpdinfo.c | 4 +- include/asm-ppc64/iSeries/HvCallPci.h | 243 ----------------------- include/asm-ppc64/pci-bridge.h | 3 - 6 files changed, 23 insertions(+), 262 deletions(-) diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 533d9b467402..1db26d8be640 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -124,7 +124,7 @@ static void iommu_table_getparms(struct pci_dn *pdn, memset(parms, 0, sizeof(*parms)); - parms->itc_busno = pdn->DsaAddr.Dsa.busNumber; + parms->itc_busno = pdn->busno; parms->itc_slotno = pdn->LogicalSlot; parms->itc_virtbus = 0; diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index fe34d1175818..d14e9d9d7797 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -223,13 +223,8 @@ static struct device_node *build_device_node(HvBusNumber Bus, node->data = pdn; pdn->node = node; list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List); -#if 0 - pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); -#endif - pdn->DsaAddr.DsaAddr = 0; - pdn->DsaAddr.Dsa.busNumber = Bus; - pdn->DsaAddr.Dsa.subBusNumber = SubBus; - pdn->DsaAddr.Dsa.deviceId = 0x10; + pdn->busno = Bus; + pdn->bussubno = SubBus; pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); return node; } @@ -554,8 +549,7 @@ static struct device_node *find_Device_Node(int bus, int devfn) struct pci_dn *pdn; list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { - if ((bus == pdn->DsaAddr.Dsa.busNumber) && - (devfn == pdn->devfn)) + if ((bus == pdn->busno) && (devfn == pdn->devfn)) return pdn->node; } return NULL; @@ -612,7 +606,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, } fn = hv_cfg_read_func[(size - 1) & 3]; - HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0); + HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0); if (ret.rc != 0) { *val = ~0; @@ -640,7 +634,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_BAD_REGISTER_NUMBER; fn = hv_cfg_write_func[(size - 1) & 3]; - ret = HvCall4(fn, PCI_DN(node)->DsaAddr.DsaAddr, offset, val, 0); + ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0); if (ret != 0) return PCIBIOS_DEVICE_NOT_FOUND; @@ -671,7 +665,7 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, ++Pci_Error_Count; (*retry)++; printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", - TextHdr, pdn->DsaAddr.Dsa.busNumber, pdn->devfn, + TextHdr, pdn->busno, pdn->devfn, *retry, (int)ret); /* * Bump the retry and check for retry count exceeded. @@ -712,7 +706,7 @@ static inline struct device_node *xlate_iomm_address( if (DevNode != NULL) { int barnum = iobar_table[TableIndex]; - *dsaptr = PCI_DN(DevNode)->DsaAddr.DsaAddr | (barnum << 24); + *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24); *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; } else panic("PCI: Invalid PCI IoAddress detected!\n"); diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h index 94b4bfdceadf..33a8489fde54 100644 --- a/arch/powerpc/platforms/iseries/pci.h +++ b/arch/powerpc/platforms/iseries/pci.h @@ -30,6 +30,8 @@ * End Change Activity */ +#include + struct pci_dev; /* For Forward Reference */ /* @@ -45,6 +47,17 @@ struct pci_dev; /* For Forward Reference */ #define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) #define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) +/* + * Generate a Direct Select Address for the Hypervisor + */ +static inline u64 iseries_ds_addr(struct device_node *node) +{ + struct pci_dn *pdn = PCI_DN(node); + + return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40) + + ((u64)0x10 << 32); +} + extern void iSeries_Device_Information(struct pci_dev*, int); #endif /* _PLATFORMS_ISERIES_PCI_H */ diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index dcdac995565c..a03984e19c13 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -258,8 +258,8 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) } pdn = PCI_DN(DevNode); - bus = pdn->DsaAddr.Dsa.busNumber; - subbus = pdn->DsaAddr.Dsa.subBusNumber; + bus = pdn->busno; + subbus = pdn->bussubno; agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); iSeries_Get_Location_Code(bus, agent, &frame, card); diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/include/asm-ppc64/iSeries/HvCallPci.h index c8d675c40f5e..17b4840b64b2 100644 --- a/include/asm-ppc64/iSeries/HvCallPci.h +++ b/include/asm-ppc64/iSeries/HvCallPci.h @@ -126,25 +126,6 @@ enum HvCallPci_VpdType { #define HvCallPciUnmaskInterrupts HvCallPci + 49 #define HvCallPciGetBusUnitInfo HvCallPci + 50 -static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, u8 *value) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumber; - dsa.subBusNumber = subBusNumber; - dsa.deviceId = deviceId; - - HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0); - - *value = retVal.value; - - return retVal.rc; -} - static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u16 *value) { @@ -164,25 +145,6 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, return retVal.rc; } -static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, u32 *value) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumber; - dsa.subBusNumber = subBusNumber; - dsa.deviceId = deviceId; - - HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0); - - *value = retVal.value; - - return retVal.rc; -} - static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u8 value) { @@ -197,186 +159,6 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0); } -static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, u16 value) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumber; - dsa.subBusNumber = subBusNumber; - dsa.deviceId = deviceId; - - return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0); -} - -static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, u32 value) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumber; - dsa.subBusNumber = subBusNumber; - dsa.deviceId = deviceId; - - return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0); -} - -static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u8 *valueParm) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0); - - *valueParm = retVal.value; - - return retVal.rc; -} - -static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u16 *valueParm) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0); - - *valueParm = retVal.value; - - return retVal.rc; -} - -static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u32 *valueParm) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0); - - *valueParm = retVal.value; - - return retVal.rc; -} - -static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u64 *valueParm) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0); - - *valueParm = retVal.value; - - return retVal.rc; -} - -static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u8 valueParm) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, - valueParm, 0); -} - -static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u16 valueParm) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, - valueParm, 0); -} - -static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u32 valueParm) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, - valueParm, 0); -} - -static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, - u64 valueParm) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - dsa.barNumber = barNumberParm; - - return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, - valueParm, 0); -} - static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm) { @@ -437,20 +219,6 @@ static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm, return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask); } -static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm, - u8 deviceIdParm, u64 onNotOff) -{ - struct HvCallPci_DsaAddr dsa; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumberParm; - dsa.subBusNumber = subBusParm; - dsa.deviceId = deviceIdParm; - - return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff); -} - static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm, u8 deviceNumberParm, u64 parms, u32 sizeofParms) { @@ -519,15 +287,4 @@ static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, return xRc & 0xFFFF; } -static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, - u16 sizeParm) -{ - u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, - sizeParm, HvCallPci_BusAdapterVpd); - if (xRc == -1) - return -1; - else - return xRc & 0xFFFF; -} - #endif /* _HVCALLPCI_H */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 01bffca61f89..0474bdbf556c 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -77,9 +77,6 @@ struct pci_dn { struct device_node *node; /* back-pointer to the device_node */ #ifdef CONFIG_PPC_ISERIES struct list_head Device_List; - union HvDsaMap DsaAddr; /* Direct Select Address */ - /* busNumber, subBusNumber, */ - /* deviceId, barNumber */ int Irq; /* Assigned IRQ */ int Flags; /* Possible flags(disable/bist)*/ u8 LogicalSlot; /* Hv Slot Index for Tces */ From 0e29bb1a4ef69120a614391a649510010031dd8a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 14 Oct 2005 17:09:16 +1000 Subject: [PATCH 0295/1940] powerpc: move iSeries/HvCallHpt.h to platforms/iseries/call_hpt.h Signed-off-by: Stephen Rothwell --- .../powerpc/platforms/iseries/call_hpt.h | 7 +++---- arch/powerpc/platforms/iseries/htab.c | 3 ++- arch/powerpc/platforms/iseries/setup.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename include/asm-ppc64/iSeries/HvCallHpt.h => arch/powerpc/platforms/iseries/call_hpt.h (96%) diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/arch/powerpc/platforms/iseries/call_hpt.h similarity index 96% rename from include/asm-ppc64/iSeries/HvCallHpt.h rename to arch/powerpc/platforms/iseries/call_hpt.h index 43a1969230b8..321f3bb7a8f5 100644 --- a/include/asm-ppc64/iSeries/HvCallHpt.h +++ b/arch/powerpc/platforms/iseries/call_hpt.h @@ -1,5 +1,4 @@ /* - * HvCallHpt.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -16,8 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _HVCALLHPT_H -#define _HVCALLHPT_H +#ifndef _PLATFORMS_ISERIES_CALL_HPT_H +#define _PLATFORMS_ISERIES_CALL_HPT_H /* * This file contains the "hypervisor call" interface which is used to @@ -99,4 +98,4 @@ static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte) HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r); } -#endif /* _HVCALLHPT_H */ +#endif /* _PLATFORMS_ISERIES_CALL_HPT_H */ diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c index 431b22767d06..c00b8e9e2b3c 100644 --- a/arch/powerpc/platforms/iseries/htab.c +++ b/arch/powerpc/platforms/iseries/htab.c @@ -14,10 +14,11 @@ #include #include #include -#include #include #include +#include "call_hpt.h" + static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED}; diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index b6cf050a8c27..93852c2ee5de 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +59,7 @@ #include "processor_vpd.h" #include "main_store.h" #include "call_sm.h" +#include "call_hpt.h" extern void hvlog(char *fmt, ...); From c6d2ea92d162c81d4d593b4b5e0f5ceb1b940c72 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 14 Oct 2005 17:16:17 +1000 Subject: [PATCH 0296/1940] powerpc: move iSeries/HvCallPci.h to platforms/iseries/call_pci.h Signed-off-by: Stephen Rothwell --- .../powerpc/platforms/iseries/call_pci.h | 6 +++--- arch/powerpc/platforms/iseries/irq.c | 2 +- arch/powerpc/platforms/iseries/pci.c | 2 +- arch/powerpc/platforms/iseries/vpdinfo.c | 2 +- include/asm-ppc64/pci-bridge.h | 2 -- 5 files changed, 6 insertions(+), 8 deletions(-) rename include/asm-ppc64/iSeries/HvCallPci.h => arch/powerpc/platforms/iseries/call_pci.h (98%) diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/arch/powerpc/platforms/iseries/call_pci.h similarity index 98% rename from include/asm-ppc64/iSeries/HvCallPci.h rename to arch/powerpc/platforms/iseries/call_pci.h index 17b4840b64b2..a86e065b9577 100644 --- a/include/asm-ppc64/iSeries/HvCallPci.h +++ b/arch/powerpc/platforms/iseries/call_pci.h @@ -22,8 +22,8 @@ * Created, Jan 9, 2001 */ -#ifndef _HVCALLPCI_H -#define _HVCALLPCI_H +#ifndef _PLATFORMS_ISERIES_CALL_PCI_H +#define _PLATFORMS_ISERIES_CALL_PCI_H #include #include @@ -287,4 +287,4 @@ static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, return xRc & 0xFFFF; } -#endif /* _HVCALLPCI_H */ +#endif /* _PLATFORMS_ISERIES_CALL_PCI_H */ diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 31fb5fa67fa3..937ac99b9d33 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -38,10 +38,10 @@ #include #include #include -#include #include #include "irq.h" +#include "call_pci.h" /* This maps virtual irq numbers to real irqs */ unsigned int virt_irq_to_real_map[NR_IRQS]; diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index d14e9d9d7797..959e59fd9c11 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -44,6 +43,7 @@ #include "irq.h" #include "pci.h" +#include "call_pci.h" extern unsigned long io_page_mask; diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index a03984e19c13..9c318849dee7 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -32,10 +32,10 @@ #include #include #include -#include #include #include "pci.h" +#include "call_pci.h" /* * Size of Bus VPD data diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 0474bdbf556c..1136cb6433bf 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -6,8 +6,6 @@ #include #include -#include - /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License From cf764855620aa1aa5b134687ca18b841ac9be4c7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 17 Oct 2005 11:46:53 +1000 Subject: [PATCH 0297/1940] powerpc: fix 32bit LOADADDR macro I forgot a semicolon. Signed-off-by: Stephen Rothwell --- include/asm-powerpc/ppc_asm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 6aae414a161b..96367e04fa58 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -194,7 +194,7 @@ GLUE(.,name): #else /* 32-bit */ #define LOADADDR(rn,name) \ - lis rn,name@ha \ + lis rn,name@ha; \ addi rn,rn,name@l #define LOADBASE(rn,name) \ From 7dffb72028bfd909ac51a1546d182de2df4d2426 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 17 Oct 2005 11:50:32 +1000 Subject: [PATCH 0298/1940] ppc32: use L1_CACHE_SHIFT/L1_CACHE_BYTES instead of L1_CACHE_LINE_SIZE and LG_L1_CACHE_LINE_SIZE Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/head_32.S | 2 +- arch/powerpc/kernel/misc_32.S | 58 ++++++++++++------------- arch/powerpc/lib/copy_32.S | 24 +++++----- arch/powerpc/platforms/powermac/sleep.S | 4 +- arch/ppc/kernel/cpu_setup_6xx.S | 4 +- arch/ppc/kernel/cpu_setup_power4.S | 4 +- arch/ppc/kernel/head.S | 2 +- arch/ppc/kernel/l2cr.S | 2 +- arch/ppc/kernel/misc.S | 58 ++++++++++++------------- arch/ppc/lib/string.S | 24 +++++----- arch/ppc/platforms/katana.c | 2 +- arch/ppc/platforms/pmac_sleep.S | 4 +- arch/ppc/syslib/mv64x60.c | 2 +- include/asm-ppc/cache.h | 13 +++--- 14 files changed, 100 insertions(+), 103 deletions(-) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 108e78ef3878..d9b063f567e0 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -837,7 +837,7 @@ relocate_kernel: copy_and_flush: addi r5,r5,-4 addi r6,r6,-4 -4: li r0,L1_CACHE_LINE_SIZE/4 +4: li r0,L1_CACHE_BYTES/4 mtctr r0 3: addi r6,r6,4 /* copy a cache line */ lwzx r0,r6,r4 diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 27274108116f..0b0e908b5065 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -496,21 +496,21 @@ _GLOBAL(flush_icache_range) BEGIN_FTR_SECTION blr /* for 601, do nothing */ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 mr r6,r3 1: dcbst 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ mtctr r4 2: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 2b sync /* additional sync needed on g4 */ isync @@ -523,16 +523,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) * clean_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(clean_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbst 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ blr @@ -544,16 +544,16 @@ _GLOBAL(clean_dcache_range) * flush_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(flush_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbf 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ blr @@ -566,16 +566,16 @@ _GLOBAL(flush_dcache_range) * invalidate_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(invalidate_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbi 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbi's to get to ram */ blr @@ -596,7 +596,7 @@ _GLOBAL(flush_dcache_all) mtctr r4 lis r5, KERNELBASE@h 1: lwz r3, 0(r5) /* Load one word from every line */ - addi r5, r5, L1_CACHE_LINE_SIZE + addi r5, r5, L1_CACHE_BYTES bdnz 1b blr #endif /* CONFIG_NOT_COHERENT_CACHE */ @@ -614,16 +614,16 @@ BEGIN_FTR_SECTION blr /* for 601, do nothing */ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 0b sync mtctr r4 1: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 1b sync isync @@ -646,16 +646,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) mtmsr r0 isync rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 0b sync mtctr r4 1: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 1b sync mtmsr r10 /* restore DR */ @@ -670,7 +670,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_LINE_SIZE + li r0,4096/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx @@ -682,7 +682,7 @@ _GLOBAL(clear_pages) #else 1: dcbz 0,r3 #endif - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b blr @@ -708,7 +708,7 @@ _GLOBAL(copy_page) #ifdef CONFIG_8xx /* don't use prefetch on 8xx */ - li r0,4096/L1_CACHE_LINE_SIZE + li r0,4096/L1_CACHE_BYTES mtctr r0 1: COPY_16_BYTES bdnz 1b @@ -722,13 +722,13 @@ _GLOBAL(copy_page) li r11,4 mtctr r0 11: dcbt r11,r4 - addi r11,r11,L1_CACHE_LINE_SIZE + addi r11,r11,L1_CACHE_BYTES bdnz 11b #else /* MAX_COPY_PREFETCH == 1 */ dcbt r5,r4 - li r11,L1_CACHE_LINE_SIZE+4 + li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH + li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq 2: mtctr r0 @@ -736,12 +736,12 @@ _GLOBAL(copy_page) dcbt r11,r4 dcbz r5,r3 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index 420a912198a2..bee51414812e 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -66,9 +66,9 @@ .stabs "copy32.S",N_SO,0,0,0f 0: -CACHELINE_BYTES = L1_CACHE_LINE_SIZE -LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE -CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1) +CACHELINE_BYTES = L1_CACHE_BYTES +LG_CACHELINE_BYTES = L1_CACHE_SHIFT +CACHELINE_MASK = (L1_CACHE_BYTES-1) /* * Use dcbz on the complete cache lines in the destination @@ -205,12 +205,12 @@ _GLOBAL(cacheable_memcpy) dcbz r11,r6 #endif COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES @@ -399,12 +399,12 @@ _GLOBAL(__copy_tofrom_user) .text /* the main body of the cacheline loop */ COPY_16_BYTES_WITHEX(0) -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES_WITHEX(1) -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES_WITHEX(2) COPY_16_BYTES_WITHEX(3) -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES_WITHEX(4) COPY_16_BYTES_WITHEX(5) COPY_16_BYTES_WITHEX(6) @@ -458,12 +458,12 @@ _GLOBAL(__copy_tofrom_user) * 104f (if in read part) or 105f (if in write part), after updating r5 */ COPY_16_BYTES_EXCODE(0) -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES_EXCODE(1) -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES_EXCODE(2) COPY_16_BYTES_EXCODE(3) -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES_EXCODE(4) COPY_16_BYTES_EXCODE(5) COPY_16_BYTES_EXCODE(6) diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index 88419c77ac43..22b113d19b24 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -387,10 +387,10 @@ turn_on_mmu: #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ .section .data - .balign L1_CACHE_LINE_SIZE + .balign L1_CACHE_BYTES sleep_storage: .long 0 - .balign L1_CACHE_LINE_SIZE, 0 + .balign L1_CACHE_BYTES, 0 #endif /* CONFIG_6xx */ .section .text diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S index a5333c07fc3c..55ed7716636f 100644 --- a/arch/ppc/kernel/cpu_setup_6xx.S +++ b/arch/ppc/kernel/cpu_setup_6xx.S @@ -290,10 +290,10 @@ _GLOBAL(__init_fpu_registers) #define CS_SIZE 32 .data - .balign L1_CACHE_LINE_SIZE + .balign L1_CACHE_BYTES cpu_state_storage: .space CS_SIZE - .balign L1_CACHE_LINE_SIZE,0 + .balign L1_CACHE_BYTES,0 .text /* Called in normal context to backup CPU 0 state. This diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S index 0abb5f25b2ca..d7bfd60e21fc 100644 --- a/arch/ppc/kernel/cpu_setup_power4.S +++ b/arch/ppc/kernel/cpu_setup_power4.S @@ -86,10 +86,10 @@ _GLOBAL(__setup_cpu_ppc970) #define CS_SIZE 32 .data - .balign L1_CACHE_LINE_SIZE + .balign L1_CACHE_BYTES cpu_state_storage: .space CS_SIZE - .balign L1_CACHE_LINE_SIZE,0 + .balign L1_CACHE_BYTES,0 .text /* Called in normal context to backup CPU 0 state. This diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 5b43987a943b..c5a890dca9cf 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -916,7 +916,7 @@ relocate_kernel: copy_and_flush: addi r5,r5,-4 addi r6,r6,-4 -4: li r0,L1_CACHE_LINE_SIZE/4 +4: li r0,L1_CACHE_BYTES/4 mtctr r0 3: addi r6,r6,4 /* copy a cache line */ lwzx r0,r6,r4 diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S index 861115249b35..d7f4e982b539 100644 --- a/arch/ppc/kernel/l2cr.S +++ b/arch/ppc/kernel/l2cr.S @@ -203,7 +203,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) * L1 icache */ b 20f - .balign L1_CACHE_LINE_SIZE + .balign L1_CACHE_BYTES 22: sync mtspr SPRN_L2CR,r3 diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 2b9a16274b0b..2350f3e09f95 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -498,21 +498,21 @@ _GLOBAL(flush_icache_range) BEGIN_FTR_SECTION blr /* for 601, do nothing */ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 mr r6,r3 1: dcbst 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ mtctr r4 2: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 2b sync /* additional sync needed on g4 */ isync @@ -525,16 +525,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) * clean_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(clean_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbst 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ blr @@ -546,16 +546,16 @@ _GLOBAL(clean_dcache_range) * flush_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(flush_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbf 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbst's to get to ram */ blr @@ -568,16 +568,16 @@ _GLOBAL(flush_dcache_range) * invalidate_dcache_range(unsigned long start, unsigned long stop) */ _GLOBAL(invalidate_dcache_range) - li r5,L1_CACHE_LINE_SIZE-1 + li r5,L1_CACHE_BYTES-1 andc r3,r3,r5 subf r4,r3,r4 add r4,r4,r5 - srwi. r4,r4,LG_L1_CACHE_LINE_SIZE + srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 1: dcbi 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b sync /* wait for dcbi's to get to ram */ blr @@ -598,7 +598,7 @@ _GLOBAL(flush_dcache_all) mtctr r4 lis r5, KERNELBASE@h 1: lwz r3, 0(r5) /* Load one word from every line */ - addi r5, r5, L1_CACHE_LINE_SIZE + addi r5, r5, L1_CACHE_BYTES bdnz 1b blr #endif /* CONFIG_NOT_COHERENT_CACHE */ @@ -616,16 +616,16 @@ BEGIN_FTR_SECTION blr /* for 601, do nothing */ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 0b sync mtctr r4 1: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 1b sync isync @@ -648,16 +648,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) mtmsr r0 isync rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ + li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 0b sync mtctr r4 1: icbi 0,r6 - addi r6,r6,L1_CACHE_LINE_SIZE + addi r6,r6,L1_CACHE_BYTES bdnz 1b sync mtmsr r10 /* restore DR */ @@ -672,7 +672,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_LINE_SIZE + li r0,4096/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx @@ -684,7 +684,7 @@ _GLOBAL(clear_pages) #else 1: dcbz 0,r3 #endif - addi r3,r3,L1_CACHE_LINE_SIZE + addi r3,r3,L1_CACHE_BYTES bdnz 1b blr @@ -710,7 +710,7 @@ _GLOBAL(copy_page) #ifdef CONFIG_8xx /* don't use prefetch on 8xx */ - li r0,4096/L1_CACHE_LINE_SIZE + li r0,4096/L1_CACHE_BYTES mtctr r0 1: COPY_16_BYTES bdnz 1b @@ -724,13 +724,13 @@ _GLOBAL(copy_page) li r11,4 mtctr r0 11: dcbt r11,r4 - addi r11,r11,L1_CACHE_LINE_SIZE + addi r11,r11,L1_CACHE_BYTES bdnz 11b #else /* MAX_COPY_PREFETCH == 1 */ dcbt r5,r4 - li r11,L1_CACHE_LINE_SIZE+4 + li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH + li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq 2: mtctr r0 @@ -738,12 +738,12 @@ _GLOBAL(copy_page) dcbt r11,r4 dcbz r5,r3 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S index 36c9b97fd92a..2e258c49e8be 100644 --- a/arch/ppc/lib/string.S +++ b/arch/ppc/lib/string.S @@ -65,9 +65,9 @@ .stabs "arch/ppc/lib/",N_SO,0,0,0f .stabs "string.S",N_SO,0,0,0f -CACHELINE_BYTES = L1_CACHE_LINE_SIZE -LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE -CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1) +CACHELINE_BYTES = L1_CACHE_BYTES +LG_CACHELINE_BYTES = L1_CACHE_SHIFT +CACHELINE_MASK = (L1_CACHE_BYTES-1) _GLOBAL(strcpy) addi r5,r3,-1 @@ -265,12 +265,12 @@ _GLOBAL(cacheable_memcpy) dcbz r11,r6 #endif COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES COPY_16_BYTES -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES @@ -485,12 +485,12 @@ _GLOBAL(__copy_tofrom_user) .text /* the main body of the cacheline loop */ COPY_16_BYTES_WITHEX(0) -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES_WITHEX(1) -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES_WITHEX(2) COPY_16_BYTES_WITHEX(3) -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES_WITHEX(4) COPY_16_BYTES_WITHEX(5) COPY_16_BYTES_WITHEX(6) @@ -544,12 +544,12 @@ _GLOBAL(__copy_tofrom_user) * 104f (if in read part) or 105f (if in write part), after updating r5 */ COPY_16_BYTES_EXCODE(0) -#if L1_CACHE_LINE_SIZE >= 32 +#if L1_CACHE_BYTES >= 32 COPY_16_BYTES_EXCODE(1) -#if L1_CACHE_LINE_SIZE >= 64 +#if L1_CACHE_BYTES >= 64 COPY_16_BYTES_EXCODE(2) COPY_16_BYTES_EXCODE(3) -#if L1_CACHE_LINE_SIZE >= 128 +#if L1_CACHE_BYTES >= 128 COPY_16_BYTES_EXCODE(4) COPY_16_BYTES_EXCODE(5) COPY_16_BYTES_EXCODE(6) diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index 3eb611e23f69..a301c5ac58dd 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c @@ -521,7 +521,7 @@ katana_fixup_resources(struct pci_dev *dev) { u16 v16; - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_LINE_SIZE>>2); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES>>2); pci_read_config_word(dev, PCI_COMMAND, &v16); v16 |= PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK; diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S index 88419c77ac43..22b113d19b24 100644 --- a/arch/ppc/platforms/pmac_sleep.S +++ b/arch/ppc/platforms/pmac_sleep.S @@ -387,10 +387,10 @@ turn_on_mmu: #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ .section .data - .balign L1_CACHE_LINE_SIZE + .balign L1_CACHE_BYTES sleep_storage: .long 0 - .balign L1_CACHE_LINE_SIZE, 0 + .balign L1_CACHE_BYTES, 0 #endif /* CONFIG_6xx */ .section .text diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 4849850a59ed..a781c50d2f4c 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -1304,7 +1304,7 @@ mv64x60_config_pci_params(struct pci_controller *hose, early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val); /* Set latency timer, cache line size, clear BIST */ - u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2); + u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2); early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val); mv64x60_pci_exclude_bridge = save_exclude; diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index 38f2f1be4a87..7a157d0f4b5f 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -9,21 +9,18 @@ /* bytes per L1 cache line */ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) -#define L1_CACHE_LINE_SIZE 16 -#define LG_L1_CACHE_LINE_SIZE 4 +#define L1_CACHE_SHIFT 4 #define MAX_COPY_PREFETCH 1 #elif defined(CONFIG_PPC64BRIDGE) -#define L1_CACHE_LINE_SIZE 128 -#define LG_L1_CACHE_LINE_SIZE 7 +#define L1_CACHE_SHIFT 7 #define MAX_COPY_PREFETCH 1 #else -#define L1_CACHE_LINE_SIZE 32 -#define LG_L1_CACHE_LINE_SIZE 5 +#define L1_CACHE_SHIFT 5 #define MAX_COPY_PREFETCH 4 #endif -#define L1_CACHE_BYTES L1_CACHE_LINE_SIZE -#define L1_CACHE_SHIFT LG_L1_CACHE_LINE_SIZE +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + #define SMP_CACHE_BYTES L1_CACHE_BYTES #define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ From 30cd4a4e9c25e154ba087848a839bd0c6d024092 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 19:20:46 +1000 Subject: [PATCH 0299/1940] powerpc: Initialize btext subsystem later, after prom_init We were initializing the btext stuff from prom_init(), thus breaking the rule that all communication between prom_init() and the rest of the kernel has to be via the flattened device tree. This removes the btext initialization calls from prom_init() and initializes it instead after the device tree is unflattened. It would be nice to do it earlier, but that needs some more infrastructure to find the properties we need in the flattened device tree. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head_32.S | 28 ---------------- arch/powerpc/kernel/prom_init.c | 59 --------------------------------- arch/powerpc/kernel/setup_32.c | 16 +++------ arch/powerpc/mm/init_32.c | 7 ---- 4 files changed, 4 insertions(+), 106 deletions(-) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index d9b063f567e0..7ef9a3e3002b 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -153,9 +153,6 @@ __after_mmu_off: bl flush_tlbs bl initial_bats -#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) - bl setup_disp_bat -#endif /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -1297,31 +1294,6 @@ initial_bats: isync blr -#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) -setup_disp_bat: - /* - * setup the display bat prepared for us in prom.c - */ - mflr r8 - bl reloc_offset - mtlr r8 - addis r8,r3,disp_BAT@ha - addi r8,r8,disp_BAT@l - lwz r11,0(r8) - lwz r8,4(r8) - mfspr r9,SPRN_PVR - rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ - cmpwi 0,r9,1 - beq 1f - mtspr SPRN_DBAT3L,r8 - mtspr SPRN_DBAT3U,r11 - blr -1: mtspr SPRN_IBAT3L,r8 - mtspr SPRN_IBAT3U,r11 - blr - -#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ - #ifdef CONFIG_8260 /* Jump into the system reset for the rom. diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 911a803f27da..d9130c839039 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1404,62 +1404,6 @@ static int __init prom_find_machine_type(void) #endif } -static int __init setup_disp(phandle dp) -{ -#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) - int width = 640, height = 480, depth = 8, pitch; - unsigned address; - u32 addrs[8][5]; - int i, naddrs; - char name[32]; - char *getprop = "getprop"; - - prom_printf("Initializing screen: "); - - memset(name, 0, sizeof(name)); - call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); - name[sizeof(name)-1] = 0; - prom_print(name); - prom_print("\n"); - call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); - call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); - call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); - pitch = width * ((depth + 7) / 8); - call_prom(getprop, 4, 1, dp, "linebytes", - &pitch, sizeof(pitch)); - if (pitch == 1) - pitch = 0x1000; /* for strange IBM display */ - address = 0; - call_prom(getprop, 4, 1, dp, "address", &address, sizeof(address)); - if (address == 0) { - /* look for an assigned address with a size of >= 1MB */ - naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses", - addrs, sizeof(addrs)); - naddrs /= 20; - for (i = 0; i < naddrs; ++i) { - if (addrs[i][4] >= (1 << 20)) { - address = addrs[i][2]; - /* use the BE aperture if possible */ - if (addrs[i][4] >= (16 << 20)) - address += (8 << 20); - break; - } - } - if (address == 0) { - prom_print("Failed to get address\n"); - return 0; - } - } - /* kludge for valkyrie */ - if (strcmp(name, "valkyrie") == 0) - address += 0x1000; - - prom_printf("\n\n\n\naddress = %x\n", address); - btext_setup_display(width, height, depth, pitch, address); -#endif /* CONFIG_BOOTX_TEXT && CONFIG_PPC32 */ - return 1; -} - static int __init prom_set_color(ihandle ih, int i, int r, int g, int b) { return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r); @@ -1479,7 +1423,6 @@ static void __init prom_check_displays(void) phandle node; ihandle ih; int i; - int got_display = 0; static unsigned char default_colors[] = { 0x00, 0x00, 0x00, @@ -1546,8 +1489,6 @@ static void __init prom_check_displays(void) clut[2]) != 0) break; #endif /* CONFIG_LOGO_LINUX_CLUT224 */ - if (!got_display) - got_display = setup_disp(node); } } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index bfa155c00ea5..e68f848f24bf 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -294,8 +294,6 @@ unsigned long __init early_init(unsigned long dt_ptr) { unsigned long offset = reloc_offset(); - reloc_got2(offset); - /* * Identify the CPU type and fix up code sections * that depend on which cpu we have. @@ -303,12 +301,6 @@ unsigned long __init early_init(unsigned long dt_ptr) identify_cpu(offset, 0); do_cpu_ftr_fixups(offset); -#ifdef CONFIG_BOOTX_TEXT - btext_prepare_BAT(); -#endif - - reloc_got2(-offset); - return KERNELBASE + offset; } @@ -578,13 +570,13 @@ void __init setup_arch(char **cmdline_p) /* so udelay does something sensible, assume <= 1000 bogomips */ loops_per_jiffy = 500000000 / HZ; -#ifdef CONFIG_BOOTX_TEXT - map_boot_text(); -#endif - unflatten_device_tree(); finish_device_tree(); +#ifdef CONFIG_BOOTX_TEXT + init_boot_display(); +#endif + #ifdef CONFIG_PPC_MULTIPLATFORM /* This could be called "early setup arch", it must be done * now because xmon need it diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index bf13c14e66b3..caeb02ee72c5 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -188,13 +188,6 @@ void __init MMU_init(void) if (ppc_md.progress) ppc_md.progress("MMU:exit", 0x211); - -#ifdef CONFIG_BOOTX_TEXT - /* By default, we are no longer mapped */ - boot_text_mapped = 0; - /* Must be done last, or ppc_md.progress will die. */ - map_boot_text(); -#endif } /* This is only called until mem_init is done. */ From 30286ef6e044bc3d9019c3d8b900572e3fa05e65 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 20:10:13 +1000 Subject: [PATCH 0300/1940] powerpc: Merge syscalls.c and sys_ppc32.c. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 6 +- arch/{ppc64 => powerpc}/kernel/sys_ppc32.c | 48 ---- arch/{ppc64 => powerpc}/kernel/syscalls.c | 180 ++++++++++---- arch/powerpc/kernel/systbl.S | 6 +- arch/ppc/kernel/Makefile | 3 +- arch/ppc/kernel/syscalls.c | 268 --------------------- arch/ppc64/kernel/Makefile | 4 +- arch/ppc64/kernel/misc.S | 8 +- 8 files changed, 147 insertions(+), 376 deletions(-) rename arch/{ppc64 => powerpc}/kernel/sys_ppc32.c (95%) rename arch/{ppc64 => powerpc}/kernel/syscalls.c (56%) delete mode 100644 arch/ppc/kernel/syscalls.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index ae97295f270d..1ca740bc5b47 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -11,7 +11,7 @@ CFLAGS_btext.o += -fPIC endif obj-y := semaphore.o cputable.o ptrace.o -obj-$(CONFIG_PPC64) += binfmt_elf32.o +obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o @@ -30,7 +30,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y += process.o init_task.o \ - prom.o systbl.o traps.o + prom.o systbl.o traps.o syscalls.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o @@ -44,7 +44,7 @@ endif else # stuff used from here for ARCH=ppc or ARCH=ppc64 -obj-$(CONFIG_PPC64) += traps.o process.o init_task.o +obj-$(CONFIG_PPC64) += traps.o process.o init_task.o syscalls.o fpux-$(CONFIG_PPC32) += fpu.o extra-$(CONFIG_PPC_FPU) += $(fpux-y) diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c similarity index 95% rename from arch/ppc64/kernel/sys_ppc32.c rename to arch/powerpc/kernel/sys_ppc32.c index b53f565ee443..9babe055356e 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -985,54 +985,6 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } #endif -asmlinkage int sys32_uname(struct old_utsname __user * name) -{ - int err = 0; - - down_read(&uts_sem); - if (copy_to_user(name, &system_utsname, sizeof(*name))) - err = -EFAULT; - up_read(&uts_sem); - if (!err && personality(current->personality) == PER_LINUX32) { - /* change "ppc64" to "ppc" */ - if (__put_user(0, name->machine + 3) - || __put_user(0, name->machine + 4)) - err = -EFAULT; - } - return err; -} - -asmlinkage int sys32_olduname(struct oldold_utsname __user * name) -{ - int error; - - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) - return -EFAULT; - - down_read(&uts_sem); - error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error |= __put_user(0,name->sysname+__OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error |= __put_user(0,name->nodename+__OLD_UTS_LEN); - error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error |= __put_user(0,name->release+__OLD_UTS_LEN); - error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error |= __put_user(0,name->version+__OLD_UTS_LEN); - error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error |= __put_user(0,name->machine+__OLD_UTS_LEN); - if (personality(current->personality) == PER_LINUX32) { - /* change "ppc64" to "ppc" */ - error |= __put_user(0, name->machine + 3); - error |= __put_user(0, name->machine + 4); - } - - up_read(&uts_sem); - - error = error ? -EFAULT : 0; - - return error; -} - unsigned long sys32_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) diff --git a/arch/ppc64/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c similarity index 56% rename from arch/ppc64/kernel/syscalls.c rename to arch/powerpc/kernel/syscalls.c index 05f16633bd2c..3e3a4f67de96 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -1,7 +1,6 @@ /* - * linux/arch/ppc64/kernel/sys_ppc.c + * Implementation of various system calls for Linux/PowerPC * - * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Derived from "arch/i386/kernel/sys_i386.c" @@ -52,9 +51,8 @@ extern unsigned long wall_jiffies; * * This is really horribly ugly. */ -asmlinkage int -sys_ipc (uint call, int first, unsigned long second, long third, - void __user *ptr, long fifth) +int sys_ipc(uint call, int first, unsigned long second, long third, + void __user *ptr, long fifth) { int version, ret; @@ -88,7 +86,7 @@ sys_ipc (uint call, int first, unsigned long second, long third, } case MSGSND: ret = sys_msgsnd(first, (struct msgbuf __user *)ptr, - (size_t)second, third); + (size_t)second, third); break; case MSGRCV: switch (version) { @@ -113,41 +111,29 @@ sys_ipc (uint call, int first, unsigned long second, long third, } break; case MSGGET: - ret = sys_msgget ((key_t)first, (int)second); + ret = sys_msgget((key_t)first, (int)second); break; case MSGCTL: ret = sys_msgctl(first, (int)second, (struct msqid_ds __user *)ptr); break; - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *) ptr, - (int)second, &raddr); - if (ret) - break; - ret = put_user (raddr, (ulong __user *) third); + case SHMAT: { + ulong raddr; + ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr); + if (ret) break; - } - case 1: /* iBCS2 emulator entry point */ - ret = -EINVAL; - if (!segment_eq(get_fs(), get_ds())) - break; - ret = do_shmat(first, (char __user *)ptr, - (int)second, (ulong *)third); - break; - } + ret = put_user(raddr, (ulong __user *) third); break; - case SHMDT: - ret = sys_shmdt ((char __user *)ptr); + } + case SHMDT: + ret = sys_shmdt((char __user *)ptr); break; case SHMGET: - ret = sys_shmget (first, (size_t)second, third); + ret = sys_shmget(first, (size_t)second, third); break; case SHMCTL: ret = sys_shmctl(first, (int)second, - (struct shmid_ds __user *)ptr); + (struct shmid_ds __user *)ptr); break; } @@ -158,43 +144,89 @@ sys_ipc (uint call, int first, unsigned long second, long third, * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage int sys_pipe(int __user *fildes) +int sys_pipe(int __user *fildes) { int fd[2]; int error; - + error = do_pipe(fd); if (!error) { if (copy_to_user(fildes, fd, 2*sizeof(int))) error = -EFAULT; } - return error; } -unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) +static inline unsigned long do_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long off, int shift) { struct file * file = NULL; - unsigned long ret = -EBADF; + int ret = -EINVAL; + if (shift) { + if (off & ((1 << shift) - 1)) + goto out; + off >>= shift; + } + + ret = -EBADF; if (!(flags & MAP_ANONYMOUS)) { if (!(file = fget(fd))) goto out; } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + down_write(¤t->mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flags, offset); + ret = do_mmap_pgoff(file, addr, len, prot, flags, off); up_write(¤t->mm->mmap_sem); if (file) fput(file); - out: return ret; } +unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12); +} + +unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) +{ + return do_mmap2(addr, len, prot, flags, fd, offset, PAGE_SHIFT); +} + +#ifdef CONFIG_PPC32 +/* + * Due to some executables calling the wrong select we sometimes + * get wrong args. This determines how the args are being passed + * (a single ptr to them all args passed) then calls + * sys_select() with the appropriate args. -- Cort + */ +int +ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp) +{ + if ( (unsigned long)n >= 4096 ) + { + unsigned long __user *buffer = (unsigned long __user *)n; + if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long)) + || __get_user(n, buffer) + || __get_user(inp, ((fd_set __user * __user *)(buffer+1))) + || __get_user(outp, ((fd_set __user * __user *)(buffer+2))) + || __get_user(exp, ((fd_set __user * __user *)(buffer+3))) + || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4)))) + return -EFAULT; + } + return sys_select(n, inp, outp, exp, tvp); +} +#endif + +#ifdef CONFIG_PPC64 long ppc64_personality(unsigned long personality) { long ret; @@ -207,8 +239,25 @@ long ppc64_personality(unsigned long personality) ret = PER_LINUX; return ret; } +#endif -long ppc64_newuname(struct new_utsname __user * name) +#ifdef CONFIG_PPC64 +#define OVERRIDE_MACHINE (personality(current->personality) == PER_LINUX32) +#else +#define OVERRIDE_MACHINE 0 +#endif + +static inline int override_machine(char *mach) +{ + if (OVERRIDE_MACHINE) { + /* change ppc64 to ppc */ + if (__put_user(0, mach+3) || __put_user(0, mach+4)) + return -EFAULT; + } + return 0; +} + +long ppc_newuname(struct new_utsname __user * name) { int err = 0; @@ -216,16 +265,54 @@ long ppc64_newuname(struct new_utsname __user * name) if (copy_to_user(name, &system_utsname, sizeof(*name))) err = -EFAULT; up_read(&uts_sem); - if (!err && personality(current->personality) == PER_LINUX32) { - /* change ppc64 to ppc */ - if (__put_user(0, name->machine + 3) - || __put_user(0, name->machine + 4)) - err = -EFAULT; - } + if (!err) + err = override_machine(name->machine); return err; } -asmlinkage time_t sys64_time(time_t __user * tloc) +int sys_uname(struct old_utsname __user *name) +{ + int err = 0; + + down_read(&uts_sem); + if (copy_to_user(name, &system_utsname, sizeof(*name))) + err = -EFAULT; + up_read(&uts_sem); + if (!err) + err = override_machine(name->machine); + return err; +} + +int sys_olduname(struct oldold_utsname __user *name) +{ + int error; + + if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) + return -EFAULT; + + down_read(&uts_sem); + error = __copy_to_user(&name->sysname, &system_utsname.sysname, + __OLD_UTS_LEN); + error |= __put_user(0, name->sysname + __OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename, &system_utsname.nodename, + __OLD_UTS_LEN); + error |= __put_user(0, name->nodename + __OLD_UTS_LEN); + error |= __copy_to_user(&name->release, &system_utsname.release, + __OLD_UTS_LEN); + error |= __put_user(0, name->release + __OLD_UTS_LEN); + error |= __copy_to_user(&name->version, &system_utsname.version, + __OLD_UTS_LEN); + error |= __put_user(0, name->version + __OLD_UTS_LEN); + error |= __copy_to_user(&name->machine, &system_utsname.machine, + __OLD_UTS_LEN); + error |= override_machine(name->machine); + up_read(&uts_sem); + + return error? -EFAULT: 0; +} + +#ifdef CONFIG_PPC64 +time_t sys64_time(time_t __user * tloc) { time_t secs; time_t usecs; @@ -247,6 +334,7 @@ asmlinkage time_t sys64_time(time_t __user * tloc) return secs; } +#endif void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 82d1fedb441c..b364141ec01c 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -102,7 +102,7 @@ COMPAT_SYS(fcntl) SYSCALL(ni_syscall) SYSCALL32(setpgid) SYSCALL(ni_syscall) -SYS32ONLY(olduname) +SYSX(sys_ni_syscall,sys_olduname, sys_olduname) SYSCALL32(umask) SYSCALL(chroot) SYSCALL(ustat) @@ -152,7 +152,7 @@ COMPAT_SYS(getitimer) COMPAT_SYS(newstat) COMPAT_SYS(newlstat) COMPAT_SYS(newfstat) -SYSX(sys_ni_syscall,sys32_uname,sys_uname) +SYSX(sys_ni_syscall,sys_uname,sys_uname) SYSCALL(ni_syscall) SYSCALL(vhangup) SYSCALL(ni_syscall) @@ -165,7 +165,7 @@ SYSCALL(fsync) SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) PPC_SYS(clone) SYSCALL32(setdomainname) -SYSX(ppc64_newuname,ppc64_newuname,sys_newuname) +PPC_SYS(newuname) SYSCALL(ni_syscall) SYSCALL32(adjtimex) SYSCALL(mprotect) diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 7d16b1f7cd31..87d3be4af820 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -38,8 +38,7 @@ endif else obj-y := irq.o idle.o time.o \ - signal.o align.o \ - syscalls.o perfmon.o + signal.o align.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c deleted file mode 100644 index 127f040de9de..000000000000 --- a/arch/ppc/kernel/syscalls.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * arch/ppc/kernel/sys_ppc.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/i386/kernel/sys_i386.c" - * Adapted from the i386 version by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * and Paul Mackerras (paulus@cs.anu.edu.au). - * - * This file contains various random system calls that - * have a non-standard calling sequence on the Linux/PPC - * platform. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -int -sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - ret = -ENOSYS; - switch (call) { - case SEMOP: - ret = sys_semtimedop (first, (struct sembuf __user *)ptr, - second, NULL); - break; - case SEMTIMEDOP: - ret = sys_semtimedop (first, (struct sembuf __user *)ptr, - second, (const struct timespec __user *) fifth); - break; - case SEMGET: - ret = sys_semget (first, second, third); - break; - case SEMCTL: { - union semun fourth; - - if (!ptr) - break; - if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT) - || (ret = get_user(fourth.__pad, (void __user *__user *)ptr))) - break; - ret = sys_semctl (first, second, third, fourth); - break; - } - case MSGSND: - ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third); - break; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - - if (!ptr) - break; - if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT) - || (ret = copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp)) ? -EFAULT : 0)) - break; - ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, - third); - break; - } - default: - ret = sys_msgrcv (first, (struct msgbuf __user *) ptr, - second, fifth, third); - break; - } - break; - case MSGGET: - ret = sys_msgget ((key_t) first, second); - break; - case MSGCTL: - ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - break; - case SHMAT: { - ulong raddr; - - if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third, - sizeof(ulong)) ? 0 : -EFAULT)) - break; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - break; - ret = put_user (raddr, (ulong __user *) third); - break; - } - case SHMDT: - ret = sys_shmdt ((char __user *)ptr); - break; - case SHMGET: - ret = sys_shmget (first, second, third); - break; - case SHMCTL: - ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr); - break; - } - - return ret; -} - -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way unix traditionally does this, though. - */ -int sys_pipe(int __user *fildes) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(fildes, fd, 2*sizeof(int))) - error = -EFAULT; - } - return error; -} - -static inline unsigned long -do_mmap2(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - struct file * file = NULL; - int ret = -EBADF; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - if (!(file = fget(fd))) - goto out; - } - - down_write(¤t->mm->mmap_sem); - ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - if (file) - fput(file); -out: - return ret; -} - -unsigned long sys_mmap2(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - return do_mmap2(addr, len, prot, flags, fd, pgoff); -} - -unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) -{ - int err = -EINVAL; - - if (offset & ~PAGE_MASK) - goto out; - - err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); -out: - return err; -} - -/* - * Due to some executables calling the wrong select we sometimes - * get wrong args. This determines how the args are being passed - * (a single ptr to them all args passed) then calls - * sys_select() with the appropriate args. -- Cort - */ -int -ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp) -{ - if ( (unsigned long)n >= 4096 ) - { - unsigned long __user *buffer = (unsigned long __user *)n; - if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long)) - || __get_user(n, buffer) - || __get_user(inp, ((fd_set __user * __user *)(buffer+1))) - || __get_user(outp, ((fd_set __user * __user *)(buffer+2))) - || __get_user(exp, ((fd_set __user * __user *)(buffer+3))) - || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4)))) - return -EFAULT; - } - return sys_select(n, inp, outp, exp, tvp); -} - -int sys_uname(struct old_utsname __user * name) -{ - int err = -EFAULT; - - down_read(&uts_sem); - if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) - err = 0; - up_read(&uts_sem); - return err; -} - -int sys_olduname(struct oldold_utsname __user * name) -{ - int error; - - if (!name) - return -EFAULT; - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) - return -EFAULT; - - down_read(&uts_sem); - error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); - error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); - error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); - error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error = __put_user(0,name->machine+__OLD_UTS_LEN); - up_read(&uts_sem); - - error = error ? -EFAULT : 0; - return error; -} - -/* - * We put the arguments in a different order so we only use 6 - * registers for arguments, rather than 7 as sys_fadvise64_64 needs - * (because `offset' goes in r5/r6). - */ -long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len) -{ - return sys_fadvise64_64(fd, offset, len, advice); -} diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index b1203b79edf0..0be7c7ecefdf 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -12,9 +12,9 @@ obj-y := setup.o entry.o misc.o prom.o endif obj-y += irq.o idle.o dma.o \ - time.o signal.o syscalls.o \ + time.o signal.o \ align.o bitops.o pacaData.o \ - udbg.o sys_ppc32.o ioctl32.o \ + udbg.o ioctl32.o \ ptrace32.o signal32.o rtc.o \ cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index f9f2131d2fb5..eb407c429bb0 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -980,7 +980,7 @@ _GLOBAL(sys_call_table32) .llong .sys_ni_syscall /* old mpx syscall */ .llong .sys32_setpgid .llong .sys_ni_syscall /* old ulimit syscall */ - .llong .sys32_olduname + .llong .sys_olduname .llong .sys32_umask /* 60 */ .llong .sys_chroot .llong .sys_ustat @@ -1030,7 +1030,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_newstat .llong .compat_sys_newlstat .llong .compat_sys_newfstat - .llong .sys32_uname + .llong .sys_uname .llong .sys_ni_syscall /* 110 old iopl syscall */ .llong .sys_vhangup .llong .sys_ni_syscall /* old idle syscall */ @@ -1043,7 +1043,7 @@ _GLOBAL(sys_call_table32) .llong .ppc32_sigreturn .llong .ppc_clone /* 120 */ .llong .sys32_setdomainname - .llong .ppc64_newuname + .llong .ppc_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ .llong .sys32_adjtimex .llong .sys_mprotect /* 125 */ @@ -1324,7 +1324,7 @@ _GLOBAL(sys_call_table) .llong .sys_ni_syscall .llong .ppc_clone /* 120 */ .llong .sys_setdomainname - .llong .ppc64_newuname + .llong .ppc_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ .llong .sys_adjtimex .llong .sys_mprotect /* 125 */ From 3e63b9ec51eb1d9f441e5015427b23d70e5991b3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 20:11:03 +1000 Subject: [PATCH 0301/1940] ppc: Use the merged of_device.c from arch/powerpc/kernel Signed-off-by: Paul Mackerras --- arch/ppc/syslib/Makefile | 2 +- arch/ppc/syslib/of_device.c | 276 ------------------------------------ 2 files changed, 1 insertion(+), 277 deletions(-) delete mode 100644 arch/ppc/syslib/of_device.c diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index b8d08f33f7ee..f6a2f1938bfa 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.o i8259.o endif -obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o obj-$(CONFIG_POWER4) += open_pic2.o obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c deleted file mode 100644 index 93c7231ea709..000000000000 --- a/arch/ppc/syslib/of_device.c +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in - * @dev: the of device structure to match against - * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. - */ -const struct of_device_id * of_match_device(const struct of_device_id *matches, - const struct of_device *dev) -{ - if (!dev->node) - return NULL; - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); - if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); - if (matches->compatible[0]) - match &= device_is_compatible(dev->node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; -} - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_device_id * matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; -} - -struct of_device *of_dev_get(struct of_device *dev) -{ - struct device *tmp; - - if (!dev) - return NULL; - tmp = get_device(&dev->dev); - if (tmp) - return to_of_device(tmp); - else - return NULL; -} - -void of_dev_put(struct of_device *dev) -{ - if (dev) - put_device(&dev->dev); -} - - -static int of_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_device_remove(struct device *dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_device_resume(struct device * dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -struct bus_type of_platform_bus_type = { - .name = "of_platform", - .match = of_platform_bus_match, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; - -static int __init of_bus_driver_init(void) -{ - return bus_register(&of_platform_bus_type); -} - -postcore_initcall(of_bus_driver_init); - -int of_register_driver(struct of_platform_driver *drv) -{ - int count = 0; - - /* initialize common driver fields */ - drv->driver.name = drv->name; - drv->driver.bus = &of_platform_bus_type; - drv->driver.probe = of_device_probe; - drv->driver.remove = of_device_remove; - - /* register with core */ - count = driver_register(&drv->driver); - return count ? count : 1; -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - - -static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); -} - -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); - -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - of_node_put(ofdev->node); - kfree(ofdev); -} - -int of_device_register(struct of_device *ofdev) -{ - int rc; - struct of_device **odprop; - - BUG_ON(ofdev->node == NULL); - - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (!odprop) { - struct property *new_prop; - - new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), - GFP_KERNEL); - if (new_prop == NULL) - return -ENOMEM; - new_prop->name = "linux,device"; - new_prop->length = sizeof(sizeof(struct of_device *)); - new_prop->value = (unsigned char *)&new_prop[1]; - odprop = (struct of_device **)new_prop->value; - *odprop = NULL; - prom_add_property(ofdev->node, new_prop); - } - *odprop = ofdev; - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; -} - -void of_device_unregister(struct of_device *ofdev) -{ - struct of_device **odprop; - - device_remove_file(&ofdev->dev, &dev_attr_devspec); - - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (odprop) - *odprop = NULL; - - device_unregister(&ofdev->dev); -} - -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - u32 *reg; - - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->node = of_node_get(np); - dev->dma_mask = 0xffffffffUL; - dev->dev.dma_mask = &dev->dma_mask; - dev->dev.parent = parent; - dev->dev.bus = &of_platform_bus_type; - dev->dev.release = of_release_dev; - - reg = (u32 *)get_property(np, "reg", NULL); - strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); - - if (of_device_register(dev) != 0) { - kfree(dev); - return NULL; - } - - return dev; -} - -EXPORT_SYMBOL(of_match_device); -EXPORT_SYMBOL(of_platform_bus_type); -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); -EXPORT_SYMBOL(of_device_register); -EXPORT_SYMBOL(of_device_unregister); -EXPORT_SYMBOL(of_dev_get); -EXPORT_SYMBOL(of_dev_put); -EXPORT_SYMBOL(of_platform_device_create); -EXPORT_SYMBOL(of_release_dev); From 7ac59c624992281ff315911dea2a98ca3f3ff06e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 20:12:39 +1000 Subject: [PATCH 0302/1940] ppc: Fix various compile errors resulting from ptrace.c merge This introduces flush_{fp,altivec,spe}_to_thread and fixes a branch-too-far error in linking. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/entry.S | 3 +- arch/ppc/kernel/process.c | 136 +++++++++++++++++++++++++++----------- include/asm-ppc/system.h | 18 +++++ 3 files changed, 118 insertions(+), 39 deletions(-) diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 03d4886869f3..68fc61221776 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -633,7 +633,8 @@ sigreturn_exit: rlwinm r12,r1,0,0,18 /* current_thread_info() */ lwz r9,TI_FLAGS(r12) andi. r0,r9,_TIF_SYSCALL_T_OR_A - bnel- do_syscall_trace_leave + beq+ ret_from_except_full + bl do_syscall_trace_leave /* fall through */ .globl ret_from_except_full diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 0870e5553453..6d60c40598e7 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -152,18 +152,66 @@ int check_stack(struct task_struct *tsk) } #endif /* defined(CHECK_STACK) */ -#ifdef CONFIG_ALTIVEC -int -dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) +/* + * Make sure the floating-point register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_fp_to_thread(struct task_struct *tsk) { - if (regs->msr & MSR_VEC) - giveup_altivec(current); - memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); + if (tsk->thread.regs) { + /* + * We need to disable preemption here because if we didn't, + * another process could get scheduled after the regs->msr + * test but before we have finished saving the FP registers + * to the thread_struct. That process could take over the + * FPU, and then when we get scheduled again we would store + * bogus values for the remaining FP registers. + */ + preempt_disable(); + if (tsk->thread.regs->msr & MSR_FP) { +#ifdef CONFIG_SMP + /* + * This should only ever be called for current or + * for a stopped child process. Since we save away + * the FP register state on context switch on SMP, + * there is something wrong if a stopped child appears + * to still have its FP state in the CPU registers. + */ + BUG_ON(tsk != current); +#endif + giveup_fpu(current); + } + preempt_enable(); + } +} + +void enable_kernel_fp(void) +{ + WARN_ON(preemptible()); + +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) + giveup_fpu(current); + else + giveup_fpu(NULL); /* just enables FP for kernel */ +#else + giveup_fpu(last_task_used_math); +#endif /* CONFIG_SMP */ +} +EXPORT_SYMBOL(enable_kernel_fp); + +int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) +{ + preempt_disable(); + if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP)) + giveup_fpu(tsk); + preempt_enable(); + memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); return 1; } -void -enable_kernel_altivec(void) +#ifdef CONFIG_ALTIVEC +void enable_kernel_altivec(void) { WARN_ON(preemptible()); @@ -177,19 +225,35 @@ enable_kernel_altivec(void) #endif /* __SMP __ */ } EXPORT_SYMBOL(enable_kernel_altivec); + +/* + * Make sure the VMX/Altivec register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_altivec_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + preempt_disable(); + if (tsk->thread.regs->msr & MSR_VEC) { +#ifdef CONFIG_SMP + BUG_ON(tsk != current); +#endif + giveup_altivec(current); + } + preempt_enable(); + } +} + +int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) +{ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); + return 1; +} #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SPE -int -dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) -{ - if (regs->msr & MSR_SPE) - giveup_spe(current); - /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */ - memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35); - return 1; -} - void enable_kernel_spe(void) { @@ -205,34 +269,30 @@ enable_kernel_spe(void) #endif /* __SMP __ */ } EXPORT_SYMBOL(enable_kernel_spe); -#endif /* CONFIG_SPE */ -void -enable_kernel_fp(void) +void flush_spe_to_thread(struct task_struct *tsk) { - WARN_ON(preemptible()); - + if (tsk->thread.regs) { + preempt_disable(); + if (tsk->thread.regs->msr & MSR_SPE) { #ifdef CONFIG_SMP - if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) - giveup_fpu(current); - else - giveup_fpu(NULL); /* just enables FP for kernel */ -#else - giveup_fpu(last_task_used_math); -#endif /* CONFIG_SMP */ + BUG_ON(tsk != current); +#endif + giveup_spe(current); + } + preempt_enable(); + } } -EXPORT_SYMBOL(enable_kernel_fp); -int -dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) +int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) { - preempt_disable(); - if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP)) - giveup_fpu(tsk); - preempt_enable(); - memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); + if (regs->msr & MSR_SPE) + giveup_spe(current); + /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */ + memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35); return 1; } +#endif /* CONFIG_SPE */ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index af93ff04c53f..1f310783757e 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -74,6 +74,7 @@ extern void read_rtc_time(void); extern void pmac_find_display(void); extern void giveup_fpu(struct task_struct *); extern void enable_kernel_fp(void); +extern void flush_fp_to_thread(struct task_struct *); extern void enable_kernel_altivec(void); extern void giveup_altivec(struct task_struct *); extern void load_up_altivec(struct task_struct *); @@ -83,6 +84,23 @@ extern void load_up_spe(struct task_struct *); extern int fix_alignment(struct pt_regs *); extern void cvt_fd(float *from, double *to, unsigned long *fpscr); extern void cvt_df(double *from, float *to, unsigned long *fpscr); + +#ifdef CONFIG_ALTIVEC +extern void flush_altivec_to_thread(struct task_struct *); +#else +static inline void flush_altivec_to_thread(struct task_struct *t) +{ +} +#endif + +#ifdef CONFIG_SPE +extern void flush_spe_to_thread(struct task_struct *); +#else +static inline void flush_spe_to_thread(struct task_struct *t) +{ +} +#endif + extern int call_rtas(const char *, int, int, unsigned long *, ...); extern void cacheable_memzero(void *p, unsigned int nb); extern void *cacheable_memcpy(void *, const void *, unsigned int); From dd184343b45e94fd3b0d4d0865070924bc6195ab Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 20:13:47 +1000 Subject: [PATCH 0303/1940] powerpc: Clear the BSS at the start of early_init with ARCH=ppc Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index e68f848f24bf..b95f7cf693e6 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -294,6 +294,10 @@ unsigned long __init early_init(unsigned long dt_ptr) { unsigned long offset = reloc_offset(); + /* First zero the BSS -- use memset_io, some platforms don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); + /* * Identify the CPU type and fix up code sections * that depend on which cpu we have. From 5f2967553394d01f4bafd03398777a42e8344d28 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Oct 2005 20:14:59 +1000 Subject: [PATCH 0304/1940] powerpc: Make CONFIG_PROC_DEVICETREE independent of CONFIG_PPC_OF ... since all platforms will have a device tree. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index cd55c9b0f7ea..e70f7049cc6f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -569,12 +569,12 @@ config SCHED_SMT overhead in some places. If unsure say N here. config PROC_DEVICETREE - bool "Support for Open Firmware device tree in /proc" - depends on (PPC_OF || PPC_ISERIES) && PROC_FS + bool "Support for device tree in /proc" + depends on PROC_FS help This option adds a device-tree directory under /proc which contains an image of the device tree that the kernel copies from Open - Firmware. If unsure, say Y here. + Firmware or other boot firmware. If unsure, say Y here. source "arch/powerpc/platforms/prep/Kconfig" From ea703ce20699dd85ad7954e34b71a2c7c47b6132 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 11 Oct 2005 23:54:00 -0500 Subject: [PATCH 0305/1940] [PATCH] powerpc: replace use of _GLOBAL with .globl The _GLOBAL() macro is for text symbols only. Changed to using .globl for .data symbols. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head_44x.S | 18 +++++++++++------- arch/powerpc/kernel/head_4xx.S | 16 +++++++++++----- arch/powerpc/kernel/head_fsl_booke.S | 17 +++++++++++------ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index b1b9dc08abca..8b49679fad54 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -743,14 +743,18 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 /* * To support >32-bit physical addresses, we use an 8KB pgdir. */ -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 8192 /* Reserved 4k for the critical exception stack & 4k for the machine @@ -759,13 +763,15 @@ _GLOBAL(swapper_pg_dir) .align 12 exception_stack_bottom: .space BOOKE_EXCEPTION_STACK_SIZE -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* * This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* @@ -774,5 +780,3 @@ _GLOBAL(cmd_line) */ abatron_pteptrs: .space 8 - - diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S index 5772ce97e24e..10c261c67021 100644 --- a/arch/powerpc/kernel/head_4xx.S +++ b/arch/powerpc/kernel/head_4xx.S @@ -988,10 +988,14 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 4096 @@ -1001,12 +1005,14 @@ _GLOBAL(swapper_pg_dir) exception_stack_bottom: .space 4096 critical_stack_top: -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* Room for two PTE pointers, usually the kernel and current user pointers diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 53949811efda..5063c603fad4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -1028,10 +1028,14 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 4096 /* Reserved 4k for the critical exception stack & 4k for the machine @@ -1040,13 +1044,15 @@ _GLOBAL(swapper_pg_dir) .align 12 exception_stack_bottom: .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* * This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* @@ -1055,4 +1061,3 @@ _GLOBAL(cmd_line) */ abatron_pteptrs: .space 8 - From 61f684ec074f40e2e13e750513df42c0c046689b Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 13 Oct 2005 14:28:58 +1000 Subject: [PATCH 0306/1940] [PATCH] powerpc: Fix use of LOADBASE in merge tree The merge-tree version of LOADBASE actually loads the whole given address from the toc for ppc64. The matching OFF macro adjust for this, using an offset of 0 for ppc64, but we weren't using that in power4_idle. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/idle_power4.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 5596fad6c87c..1494e2f177f7 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S @@ -39,13 +39,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) * can be cleared by CPU init after the fixups are done */ LOADBASE(r3,cur_cpu_spec) - ld r4,cur_cpu_spec@l(r3) + ld r4,OFF(cur_cpu_spec)(r3) ld r4,CPU_SPEC_FEATURES(r4) andi. r0,r4,CPU_FTR_CAN_NAP beqlr /* Now check if user or arch enabled NAP mode */ LOADBASE(r3,powersave_nap) - lwz r4,powersave_nap@l(r3) + lwz r4,OFF(powersave_nap)(r3) cmpwi 0,r4,0 beqlr From 55d363397f1bdfa4fe861f0e2fadb058c79dafea Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 13 Oct 2005 15:46:22 +1000 Subject: [PATCH 0307/1940] [PATCH] powerpc: Another maple merge tree fix With ARCH=powerpc, a spurious ifdef in prom_init prevented the seconday hold loop being correctly copied down on Maple. With this patch, Maple boots with ARCH=powerpc Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d9130c839039..9b1baaa9eda0 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1955,13 +1955,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, prom_send_capabilities(); #endif -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_BPA) /* * On pSeries and BPA, copy the CPU hold code */ - if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) + if (RELOC(of_platform) != PLATFORM_POWERMAC) copy_and_flush(0, KERNELBASE + offset, 0x100, 0); -#endif /* * Do early parsing of command line From 0c33aeedb2cf99d877ad9adc7c3df07870f60293 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 26 Sep 2005 11:47:53 -0700 Subject: [PATCH 0308/1940] [IB] Add checks to multicast attach and detach Add checks so that we only allow multicast attach/detach with a valid multicast GID and the correct QP type. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/core/verbs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 5081d903e561..72d3ef786db5 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -523,16 +523,22 @@ EXPORT_SYMBOL(ib_dealloc_fmr); int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) { - return qp->device->attach_mcast ? - qp->device->attach_mcast(qp, gid, lid) : - -ENOSYS; + if (!qp->device->attach_mcast) + return -ENOSYS; + if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) + return -EINVAL; + + return qp->device->attach_mcast(qp, gid, lid); } EXPORT_SYMBOL(ib_attach_mcast); int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) { - return qp->device->detach_mcast ? - qp->device->detach_mcast(qp, gid, lid) : - -ENOSYS; + if (!qp->device->detach_mcast) + return -ENOSYS; + if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) + return -EINVAL; + + return qp->device->detach_mcast(qp, gid, lid); } EXPORT_SYMBOL(ib_detach_mcast); From 33033b797225553e48ca68d8d8dc5e64ec22e02b Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 26 Sep 2005 12:30:02 -0700 Subject: [PATCH 0309/1940] [IB] mthca: Report correct atomic capability Return correct atomic capability flag from mthca query function. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_dev.h | 1 + drivers/infiniband/hw/mthca/mthca_main.c | 1 + drivers/infiniband/hw/mthca/mthca_provider.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 7bff5a8425f4..67a2f324a274 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -148,6 +148,7 @@ struct mthca_limits { int reserved_mcgs; int num_pds; int reserved_pds; + u32 flags; u8 port_width_cap; }; diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 23a3f56c7899..576e7fcd053c 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -172,6 +172,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim mdev->limits.reserved_uars = dev_lim->reserved_uars; mdev->limits.reserved_pds = dev_lim->reserved_pds; mdev->limits.port_width_cap = dev_lim->max_port_width; + mdev->limits.flags = dev_lim->flags; /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. May be doable since hardware supports it for SRQ. diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 3f5319a46577..141509dced7e 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -99,6 +99,8 @@ static int mthca_query_device(struct ib_device *ibdev, props->max_qp_rd_atom = 1 << mdev->qp_table.rdb_shift; props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift; props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay; + props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? + IB_ATOMIC_HCA : IB_ATOMIC_NONE; err = 0; out: From 6b73597e7062118c0549c2702bfb7d273518c906 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 26 Sep 2005 13:53:25 -0700 Subject: [PATCH 0310/1940] [IB] uverbs: ABI-breaking fixes for userspace verbs Introduce new userspace verbs ABI version 3. This eliminates some unneeded commands, and adds support for user-created completion channels. This cleans up problems with file leaks on error paths, and also makes sure that file descriptors are always installed into the correct process. Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs.h | 18 +- drivers/infiniband/core/uverbs_cmd.c | 188 ++++++++--------- drivers/infiniband/core/uverbs_main.c | 290 +++++++++++++------------- include/rdma/ib_user_verbs.h | 58 ++---- 4 files changed, 258 insertions(+), 296 deletions(-) diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index cc124344dd2c..475153e510a9 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -53,14 +53,14 @@ struct ib_uverbs_device { struct cdev dev; struct class_device class_dev; struct ib_device *ib_dev; - int num_comp; + int num_comp_vectors; }; struct ib_uverbs_event_file { struct kref ref; + struct file *file; struct ib_uverbs_file *uverbs_file; spinlock_t lock; - int fd; int is_async; wait_queue_head_t poll_wait; struct fasync_struct *async_queue; @@ -73,8 +73,7 @@ struct ib_uverbs_file { struct ib_uverbs_device *device; struct ib_ucontext *ucontext; struct ib_event_handler event_handler; - struct ib_uverbs_event_file async_file; - struct ib_uverbs_event_file comp_file[1]; + struct ib_uverbs_event_file *async_file; }; struct ib_uverbs_event { @@ -110,10 +109,17 @@ extern struct idr ib_uverbs_cq_idr; extern struct idr ib_uverbs_qp_idr; extern struct idr ib_uverbs_srq_idr; +struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, + int is_async, int *fd); +void ib_uverbs_release_event_file(struct kref *ref); +struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); + void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr); +void ib_uverbs_event_handler(struct ib_event_handler *handler, + struct ib_event *event); int ib_umem_get(struct ib_device *dev, struct ib_umem *mem, void *addr, size_t size, int write); @@ -125,16 +131,14 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem); const char __user *buf, int in_len, \ int out_len) -IB_UVERBS_DECLARE_CMD(query_params); IB_UVERBS_DECLARE_CMD(get_context); IB_UVERBS_DECLARE_CMD(query_device); IB_UVERBS_DECLARE_CMD(query_port); -IB_UVERBS_DECLARE_CMD(query_gid); -IB_UVERBS_DECLARE_CMD(query_pkey); IB_UVERBS_DECLARE_CMD(alloc_pd); IB_UVERBS_DECLARE_CMD(dealloc_pd); IB_UVERBS_DECLARE_CMD(reg_mr); IB_UVERBS_DECLARE_CMD(dereg_mr); +IB_UVERBS_DECLARE_CMD(create_comp_channel); IB_UVERBS_DECLARE_CMD(create_cq); IB_UVERBS_DECLARE_CMD(destroy_cq); IB_UVERBS_DECLARE_CMD(create_qp); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 562445165d2b..79b60c3dc8d0 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -33,6 +33,8 @@ * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $ */ +#include + #include #include "uverbs.h" @@ -45,29 +47,6 @@ (udata)->outlen = (olen); \ } while (0) -ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file, - const char __user *buf, - int in_len, int out_len) -{ - struct ib_uverbs_query_params cmd; - struct ib_uverbs_query_params_resp resp; - - if (out_len < sizeof resp) - return -ENOSPC; - - if (copy_from_user(&cmd, buf, sizeof cmd)) - return -EFAULT; - - memset(&resp, 0, sizeof resp); - - resp.num_cq_events = file->device->num_comp; - - if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) - return -EFAULT; - - return in_len; -} - ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -77,7 +56,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, struct ib_udata udata; struct ib_device *ibdev = file->device->ib_dev; struct ib_ucontext *ucontext; - int i; + struct file *filp; int ret; if (out_len < sizeof resp) @@ -110,26 +89,42 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, INIT_LIST_HEAD(&ucontext->srq_list); INIT_LIST_HEAD(&ucontext->ah_list); - resp.async_fd = file->async_file.fd; - for (i = 0; i < file->device->num_comp; ++i) - if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + - i * sizeof (__u32), - &file->comp_file[i].fd, sizeof (__u32))) { - ret = -EFAULT; - goto err_free; - } + resp.num_comp_vectors = file->device->num_comp_vectors; + + filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd); + if (IS_ERR(filp)) { + ret = PTR_ERR(filp); + goto err_free; + } if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_free; + goto err_file; } - file->ucontext = ucontext; + file->async_file = filp->private_data; + + INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev, + ib_uverbs_event_handler); + ret = ib_register_event_handler(&file->event_handler); + if (ret) + goto err_file; + + kref_get(&file->async_file->ref); + kref_get(&file->ref); + file->ucontext = ucontext; + + fd_install(resp.async_fd, filp); + up(&file->mutex); return in_len; +err_file: + put_unused_fd(resp.async_fd); + fput(filp); + err_free: ibdev->dealloc_ucontext(ucontext); @@ -255,62 +250,6 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file, return in_len; } -ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file, - const char __user *buf, - int in_len, int out_len) -{ - struct ib_uverbs_query_gid cmd; - struct ib_uverbs_query_gid_resp resp; - int ret; - - if (out_len < sizeof resp) - return -ENOSPC; - - if (copy_from_user(&cmd, buf, sizeof cmd)) - return -EFAULT; - - memset(&resp, 0, sizeof resp); - - ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index, - (union ib_gid *) resp.gid); - if (ret) - return ret; - - if (copy_to_user((void __user *) (unsigned long) cmd.response, - &resp, sizeof resp)) - return -EFAULT; - - return in_len; -} - -ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file, - const char __user *buf, - int in_len, int out_len) -{ - struct ib_uverbs_query_pkey cmd; - struct ib_uverbs_query_pkey_resp resp; - int ret; - - if (out_len < sizeof resp) - return -ENOSPC; - - if (copy_from_user(&cmd, buf, sizeof cmd)) - return -EFAULT; - - memset(&resp, 0, sizeof resp); - - ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index, - &resp.pkey); - if (ret) - return ret; - - if (copy_to_user((void __user *) (unsigned long) cmd.response, - &resp, sizeof resp)) - return -EFAULT; - - return in_len; -} - ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -595,6 +534,35 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, return ret ? ret : in_len; } +ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_create_comp_channel cmd; + struct ib_uverbs_create_comp_channel_resp resp; + struct file *filp; + + if (out_len < sizeof resp) + return -ENOSPC; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd); + if (IS_ERR(filp)) + return PTR_ERR(filp); + + if (copy_to_user((void __user *) (unsigned long) cmd.response, + &resp, sizeof resp)) { + put_unused_fd(resp.fd); + fput(filp); + return -EFAULT; + } + + fd_install(resp.fd, filp); + return in_len; +} + ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -603,6 +571,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, struct ib_uverbs_create_cq_resp resp; struct ib_udata udata; struct ib_ucq_object *uobj; + struct ib_uverbs_event_file *ev_file = NULL; struct ib_cq *cq; int ret; @@ -616,9 +585,12 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); - if (cmd.event_handler >= file->device->num_comp) + if (cmd.comp_vector >= file->device->num_comp_vectors) return -EINVAL; + if (cmd.comp_channel >= 0) + ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); + uobj = kmalloc(sizeof *uobj, GFP_KERNEL); if (!uobj) return -ENOMEM; @@ -641,7 +613,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, cq->uobject = &uobj->uobject; cq->comp_handler = ib_uverbs_comp_handler; cq->event_handler = ib_uverbs_cq_event_handler; - cq->cq_context = file; + cq->cq_context = ev_file; atomic_set(&cq->usecnt, 0); retry: @@ -700,6 +672,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, struct ib_uverbs_destroy_cq_resp resp; struct ib_cq *cq; struct ib_ucq_object *uobj; + struct ib_uverbs_event_file *ev_file; struct ib_uverbs_event *evt, *tmp; u64 user_handle; int ret = -EINVAL; @@ -716,7 +689,8 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, goto out; user_handle = cq->uobject->user_handle; - uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); + uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); + ev_file = cq->cq_context; ret = ib_destroy_cq(cq); if (ret) @@ -728,19 +702,23 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - spin_lock_irq(&file->comp_file[0].lock); - list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { - list_del(&evt->list); - kfree(evt); - } - spin_unlock_irq(&file->comp_file[0].lock); + if (ev_file) { + spin_lock_irq(&ev_file->lock); + list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { + list_del(&evt->list); + kfree(evt); + } + spin_unlock_irq(&ev_file->lock); - spin_lock_irq(&file->async_file.lock); + kref_put(&ev_file->ref, ib_uverbs_release_event_file); + } + + spin_lock_irq(&file->async_file->lock); list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) { list_del(&evt->list); kfree(evt); } - spin_unlock_irq(&file->async_file.lock); + spin_unlock_irq(&file->async_file->lock); resp.comp_events_reported = uobj->comp_events_reported; resp.async_events_reported = uobj->async_events_reported; @@ -1005,12 +983,12 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - spin_lock_irq(&file->async_file.lock); + spin_lock_irq(&file->async_file->lock); list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { list_del(&evt->list); kfree(evt); } - spin_unlock_irq(&file->async_file.lock); + spin_unlock_irq(&file->async_file->lock); resp.events_reported = uobj->events_reported; @@ -1243,12 +1221,12 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - spin_lock_irq(&file->async_file.lock); + spin_lock_irq(&file->async_file->lock); list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { list_del(&evt->list); kfree(evt); } - spin_unlock_irq(&file->async_file.lock); + spin_unlock_irq(&file->async_file->lock); resp.events_reported = uobj->events_reported; diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 12511808de21..e7058fbc607d 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -77,26 +77,24 @@ static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) = { - [IB_USER_VERBS_CMD_QUERY_PARAMS] = ib_uverbs_query_params, - [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, - [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, - [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, - [IB_USER_VERBS_CMD_QUERY_GID] = ib_uverbs_query_gid, - [IB_USER_VERBS_CMD_QUERY_PKEY] = ib_uverbs_query_pkey, - [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, - [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, - [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, - [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, - [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, - [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, - [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, - [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, - [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, - [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, - [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, - [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, - [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, - [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, + [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, + [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, + [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, + [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, + [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, + [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, + [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, + [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, + [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, + [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, + [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, + [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, + [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, + [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, + [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, + [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, + [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, + [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, }; static struct vfsmount *uverbs_event_mnt; @@ -188,25 +186,19 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf, spin_lock_irq(&file->lock); - while (list_empty(&file->event_list) && file->fd >= 0) { + while (list_empty(&file->event_list)) { spin_unlock_irq(&file->lock); if (filp->f_flags & O_NONBLOCK) return -EAGAIN; if (wait_event_interruptible(file->poll_wait, - !list_empty(&file->event_list) || - file->fd < 0)) + !list_empty(&file->event_list))) return -ERESTARTSYS; spin_lock_irq(&file->lock); } - if (file->fd < 0) { - spin_unlock_irq(&file->lock); - return -ENODEV; - } - event = list_entry(file->event_list.next, struct ib_uverbs_event, list); if (file->is_async) @@ -248,26 +240,19 @@ static unsigned int ib_uverbs_event_poll(struct file *filp, poll_wait(filp, &file->poll_wait, wait); spin_lock_irq(&file->lock); - if (file->fd < 0) - pollflags = POLLERR; - else if (!list_empty(&file->event_list)) + if (!list_empty(&file->event_list)) pollflags = POLLIN | POLLRDNORM; spin_unlock_irq(&file->lock); return pollflags; } -static void ib_uverbs_event_release(struct ib_uverbs_event_file *file) +void ib_uverbs_release_event_file(struct kref *ref) { - struct ib_uverbs_event *entry, *tmp; + struct ib_uverbs_event_file *file = + container_of(ref, struct ib_uverbs_event_file, ref); - spin_lock_irq(&file->lock); - if (file->fd != -1) { - file->fd = -1; - list_for_each_entry_safe(entry, tmp, &file->event_list, list) - kfree(entry); - } - spin_unlock_irq(&file->lock); + kfree(file); } static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) @@ -280,21 +265,30 @@ static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) static int ib_uverbs_event_close(struct inode *inode, struct file *filp) { struct ib_uverbs_event_file *file = filp->private_data; + struct ib_uverbs_event *entry, *tmp; + + spin_lock_irq(&file->lock); + file->file = NULL; + list_for_each_entry_safe(entry, tmp, &file->event_list, list) { + if (entry->counter) + list_del(&entry->obj_list); + kfree(entry); + } + spin_unlock_irq(&file->lock); - ib_uverbs_event_release(file); ib_uverbs_event_fasync(-1, filp, 0); - kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); + + if (file->is_async) { + ib_unregister_event_handler(&file->uverbs_file->event_handler); + kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); + } + kref_put(&file->ref, ib_uverbs_release_event_file); return 0; } static struct file_operations uverbs_event_fops = { - /* - * No .owner field since we artificially create event files, - * so there is no increment to the module reference count in - * the open path. All event files come from a uverbs command - * file, which already takes a module reference, so this is OK. - */ + .owner = THIS_MODULE, .read = ib_uverbs_event_read, .poll = ib_uverbs_event_poll, .release = ib_uverbs_event_close, @@ -303,10 +297,19 @@ static struct file_operations uverbs_event_fops = { void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) { - struct ib_uverbs_file *file = cq_context; - struct ib_ucq_object *uobj; - struct ib_uverbs_event *entry; - unsigned long flags; + struct ib_uverbs_event_file *file = cq_context; + struct ib_ucq_object *uobj; + struct ib_uverbs_event *entry; + unsigned long flags; + + if (!file) + return; + + spin_lock_irqsave(&file->lock, flags); + if (!file->file) { + spin_unlock_irqrestore(&file->lock, flags); + return; + } entry = kmalloc(sizeof *entry, GFP_ATOMIC); if (!entry) @@ -317,13 +320,12 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) entry->desc.comp.cq_handle = cq->uobject->user_handle; entry->counter = &uobj->comp_events_reported; - spin_lock_irqsave(&file->comp_file[0].lock, flags); - list_add_tail(&entry->list, &file->comp_file[0].event_list); + list_add_tail(&entry->list, &file->event_list); list_add_tail(&entry->obj_list, &uobj->comp_list); - spin_unlock_irqrestore(&file->comp_file[0].lock, flags); + spin_unlock_irqrestore(&file->lock, flags); - wake_up_interruptible(&file->comp_file[0].poll_wait); - kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN); + wake_up_interruptible(&file->poll_wait); + kill_fasync(&file->async_queue, SIGIO, POLL_IN); } static void ib_uverbs_async_handler(struct ib_uverbs_file *file, @@ -334,6 +336,12 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, struct ib_uverbs_event *entry; unsigned long flags; + spin_lock_irqsave(&file->async_file->lock, flags); + if (!file->async_file->file) { + spin_unlock_irqrestore(&file->async_file->lock, flags); + return; + } + entry = kmalloc(sizeof *entry, GFP_ATOMIC); if (!entry) return; @@ -342,24 +350,24 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, entry->desc.async.event_type = event; entry->counter = counter; - spin_lock_irqsave(&file->async_file.lock, flags); - list_add_tail(&entry->list, &file->async_file.event_list); + list_add_tail(&entry->list, &file->async_file->event_list); if (obj_list) list_add_tail(&entry->obj_list, obj_list); - spin_unlock_irqrestore(&file->async_file.lock, flags); + spin_unlock_irqrestore(&file->async_file->lock, flags); - wake_up_interruptible(&file->async_file.poll_wait); - kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN); + wake_up_interruptible(&file->async_file->poll_wait); + kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN); } void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) { + struct ib_uverbs_event_file *ev_file = context_ptr; struct ib_ucq_object *uobj; uobj = container_of(event->element.cq->uobject, struct ib_ucq_object, uobject); - ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle, + ib_uverbs_async_handler(ev_file->uverbs_file, uobj->uobject.user_handle, event->event, &uobj->async_list, &uobj->async_events_reported); @@ -389,8 +397,8 @@ void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) &uobj->events_reported); } -static void ib_uverbs_event_handler(struct ib_event_handler *handler, - struct ib_event *event) +void ib_uverbs_event_handler(struct ib_event_handler *handler, + struct ib_event *event) { struct ib_uverbs_file *file = container_of(handler, struct ib_uverbs_file, event_handler); @@ -399,38 +407,90 @@ static void ib_uverbs_event_handler(struct ib_event_handler *handler, NULL, NULL); } -static int ib_uverbs_event_init(struct ib_uverbs_event_file *file, - struct ib_uverbs_file *uverbs_file) +struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, + int is_async, int *fd) { + struct ib_uverbs_event_file *ev_file; struct file *filp; + int ret; - spin_lock_init(&file->lock); - INIT_LIST_HEAD(&file->event_list); - init_waitqueue_head(&file->poll_wait); - file->uverbs_file = uverbs_file; - file->async_queue = NULL; + ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL); + if (!ev_file) + return ERR_PTR(-ENOMEM); - file->fd = get_unused_fd(); - if (file->fd < 0) - return file->fd; + kref_init(&ev_file->ref); + spin_lock_init(&ev_file->lock); + INIT_LIST_HEAD(&ev_file->event_list); + init_waitqueue_head(&ev_file->poll_wait); + ev_file->uverbs_file = uverbs_file; + ev_file->async_queue = NULL; + ev_file->is_async = is_async; + + *fd = get_unused_fd(); + if (*fd < 0) { + ret = *fd; + goto err; + } filp = get_empty_filp(); if (!filp) { - put_unused_fd(file->fd); - return -ENFILE; + ret = -ENFILE; + goto err_fd; } - filp->f_op = &uverbs_event_fops; + ev_file->file = filp; + + /* + * fops_get() can't fail here, because we're coming from a + * system call on a uverbs file, which will already have a + * module reference. + */ + filp->f_op = fops_get(&uverbs_event_fops); filp->f_vfsmnt = mntget(uverbs_event_mnt); filp->f_dentry = dget(uverbs_event_mnt->mnt_root); filp->f_mapping = filp->f_dentry->d_inode->i_mapping; filp->f_flags = O_RDONLY; filp->f_mode = FMODE_READ; - filp->private_data = file; + filp->private_data = ev_file; - fd_install(file->fd, filp); + return filp; - return 0; +err_fd: + put_unused_fd(*fd); + +err: + kfree(ev_file); + return ERR_PTR(ret); +} + +/* + * Look up a completion event file by FD. If lookup is successful, + * takes a ref to the event file struct that it returns; if + * unsuccessful, returns NULL. + */ +struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) +{ + struct ib_uverbs_event_file *ev_file = NULL; + struct file *filp; + + filp = fget(fd); + if (!filp) + return NULL; + + if (filp->f_op != &uverbs_event_fops) + goto out; + + ev_file = filp->private_data; + if (ev_file->is_async) { + ev_file = NULL; + goto out; + } + + kref_get(&ev_file->ref); + +out: + fput(filp); + return ev_file; } static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, @@ -453,8 +513,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, !uverbs_cmd_table[hdr.command]) return -EINVAL; - if (!file->ucontext && - hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS && + if (!file->ucontext && hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) return -EINVAL; @@ -477,82 +536,33 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) struct ib_uverbs_device *dev = container_of(inode->i_cdev, struct ib_uverbs_device, dev); struct ib_uverbs_file *file; - int i = 0; - int ret; if (!try_module_get(dev->ib_dev->owner)) return -ENODEV; - file = kmalloc(sizeof *file + - (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), - GFP_KERNEL); + file = kmalloc(sizeof *file, GFP_KERNEL); if (!file) { - ret = -ENOMEM; - goto err; + module_put(dev->ib_dev->owner); + return -ENOMEM; } - file->device = dev; + file->device = dev; + file->ucontext = NULL; kref_init(&file->ref); init_MUTEX(&file->mutex); - file->ucontext = NULL; - - kref_get(&file->ref); - ret = ib_uverbs_event_init(&file->async_file, file); - if (ret) - goto err_kref; - - file->async_file.is_async = 1; - - for (i = 0; i < dev->num_comp; ++i) { - kref_get(&file->ref); - ret = ib_uverbs_event_init(&file->comp_file[i], file); - if (ret) - goto err_async; - file->comp_file[i].is_async = 0; - } - - filp->private_data = file; - INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev, - ib_uverbs_event_handler); - if (ib_register_event_handler(&file->event_handler)) - goto err_async; - return 0; - -err_async: - while (i--) - ib_uverbs_event_release(&file->comp_file[i]); - - ib_uverbs_event_release(&file->async_file); - -err_kref: - /* - * One extra kref_put() because we took a reference before the - * event file creation that failed and got us here. - */ - kref_put(&file->ref, ib_uverbs_release_file); - kref_put(&file->ref, ib_uverbs_release_file); - -err: - module_put(dev->ib_dev->owner); - return ret; } static int ib_uverbs_close(struct inode *inode, struct file *filp) { struct ib_uverbs_file *file = filp->private_data; - int i; - ib_unregister_event_handler(&file->event_handler); - ib_uverbs_event_release(&file->async_file); ib_dealloc_ucontext(file->ucontext); - for (i = 0; i < file->device->num_comp; ++i) - ib_uverbs_event_release(&file->comp_file[i]); - + kref_put(&file->async_file->ref, ib_uverbs_release_event_file); kref_put(&file->ref, ib_uverbs_release_file); return 0; @@ -631,8 +641,8 @@ static void ib_uverbs_add_one(struct ib_device *device) set_bit(uverbs_dev->devnum, dev_map); spin_unlock(&map_lock); - uverbs_dev->ib_dev = device; - uverbs_dev->num_comp = 1; + uverbs_dev->ib_dev = device; + uverbs_dev->num_comp_vectors = 1; if (device->mmap) cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops); diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index fd85725391a4..0532b78200ca 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -42,15 +42,12 @@ * Increment this value if any changes that break userspace ABI * compatibility are made. */ -#define IB_USER_VERBS_ABI_VERSION 2 +#define IB_USER_VERBS_ABI_VERSION 3 enum { - IB_USER_VERBS_CMD_QUERY_PARAMS, IB_USER_VERBS_CMD_GET_CONTEXT, IB_USER_VERBS_CMD_QUERY_DEVICE, IB_USER_VERBS_CMD_QUERY_PORT, - IB_USER_VERBS_CMD_QUERY_GID, - IB_USER_VERBS_CMD_QUERY_PKEY, IB_USER_VERBS_CMD_ALLOC_PD, IB_USER_VERBS_CMD_DEALLOC_PD, IB_USER_VERBS_CMD_CREATE_AH, @@ -65,6 +62,7 @@ enum { IB_USER_VERBS_CMD_ALLOC_MW, IB_USER_VERBS_CMD_BIND_MW, IB_USER_VERBS_CMD_DEALLOC_MW, + IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL, IB_USER_VERBS_CMD_CREATE_CQ, IB_USER_VERBS_CMD_RESIZE_CQ, IB_USER_VERBS_CMD_DESTROY_CQ, @@ -118,27 +116,14 @@ struct ib_uverbs_cmd_hdr { __u16 out_words; }; -/* - * No driver_data for "query params" command, since this is intended - * to be a core function with no possible device dependence. - */ -struct ib_uverbs_query_params { - __u64 response; -}; - -struct ib_uverbs_query_params_resp { - __u32 num_cq_events; -}; - struct ib_uverbs_get_context { __u64 response; - __u64 cq_fd_tab; __u64 driver_data[0]; }; struct ib_uverbs_get_context_resp { __u32 async_fd; - __u32 reserved; + __u32 num_comp_vectors; }; struct ib_uverbs_query_device { @@ -220,31 +205,6 @@ struct ib_uverbs_query_port_resp { __u8 reserved[3]; }; -struct ib_uverbs_query_gid { - __u64 response; - __u8 port_num; - __u8 index; - __u8 reserved[6]; - __u64 driver_data[0]; -}; - -struct ib_uverbs_query_gid_resp { - __u8 gid[16]; -}; - -struct ib_uverbs_query_pkey { - __u64 response; - __u8 port_num; - __u8 index; - __u8 reserved[6]; - __u64 driver_data[0]; -}; - -struct ib_uverbs_query_pkey_resp { - __u16 pkey; - __u16 reserved; -}; - struct ib_uverbs_alloc_pd { __u64 response; __u64 driver_data[0]; @@ -278,11 +238,21 @@ struct ib_uverbs_dereg_mr { __u32 mr_handle; }; +struct ib_uverbs_create_comp_channel { + __u64 response; +}; + +struct ib_uverbs_create_comp_channel_resp { + __u32 fd; +}; + struct ib_uverbs_create_cq { __u64 response; __u64 user_handle; __u32 cqe; - __u32 event_handler; + __u32 comp_vector; + __s32 comp_channel; + __u32 reserved; __u64 driver_data[0]; }; From eb9d3cd5ce2828fbb99ed7270089ea152c8f64b3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 27 Sep 2005 15:07:25 -0700 Subject: [PATCH 0311/1940] [IB] uverbs: Fix up resource creation error paths By waiting to add resources to our lists until after the last operation that can fail, we don't have to remove them from their lists in the error path. Also, we should hold the idr mutex until we know whether resource creation has succeed or failed, to avoid someone finding a resource in our table before we're ready. Loosely based on work by Robert Walsh . Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_cmd.c | 111 ++++++++++++--------------- 1 file changed, 50 insertions(+), 61 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 79b60c3dc8d0..a0ceb1cbed52 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. + * Copyright (c) 2005 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -288,24 +289,20 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, pd->uobject = uobj; atomic_set(&pd->usecnt, 0); + down(&ib_uverbs_idr_mutex); + retry: if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { ret = -ENOMEM; - goto err_pd; + goto err_up; } - down(&ib_uverbs_idr_mutex); ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id); - up(&ib_uverbs_idr_mutex); if (ret == -EAGAIN) goto retry; if (ret) - goto err_pd; - - down(&file->mutex); - list_add_tail(&uobj->list, &file->ucontext->pd_list); - up(&file->mutex); + goto err_up; memset(&resp, 0, sizeof resp); resp.pd_handle = uobj->id; @@ -313,21 +310,22 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_list; + goto err_idr; } + down(&file->mutex); + list_add_tail(&uobj->list, &file->ucontext->pd_list); + up(&file->mutex); + + up(&ib_uverbs_idr_mutex); + return in_len; -err_list: - down(&file->mutex); - list_del(&uobj->list); - up(&file->mutex); - - down(&ib_uverbs_idr_mutex); +err_idr: idr_remove(&ib_uverbs_pd_idr, uobj->id); - up(&ib_uverbs_idr_mutex); -err_pd: +err_up: + up(&ib_uverbs_idr_mutex); ib_dealloc_pd(pd); err: @@ -463,24 +461,22 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, resp.mr_handle = obj->uobject.id; - down(&file->mutex); - list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); - up(&file->mutex); - if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_list; + goto err_idr; } + down(&file->mutex); + list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); + up(&file->mutex); + up(&ib_uverbs_idr_mutex); return in_len; -err_list: - down(&file->mutex); - list_del(&obj->uobject.list); - up(&file->mutex); +err_idr: + idr_remove(&ib_uverbs_mr_idr, obj->uobject.id); err_unreg: ib_dereg_mr(mr); @@ -616,24 +612,20 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, cq->cq_context = ev_file; atomic_set(&cq->usecnt, 0); + down(&ib_uverbs_idr_mutex); + retry: if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { ret = -ENOMEM; - goto err_cq; + goto err_up; } - down(&ib_uverbs_idr_mutex); ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id); - up(&ib_uverbs_idr_mutex); if (ret == -EAGAIN) goto retry; if (ret) - goto err_cq; - - down(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); - up(&file->mutex); + goto err_up; memset(&resp, 0, sizeof resp); resp.cq_handle = uobj->uobject.id; @@ -642,21 +634,22 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_list; + goto err_idr; } + down(&file->mutex); + list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); + up(&file->mutex); + + up(&ib_uverbs_idr_mutex); + return in_len; -err_list: - down(&file->mutex); - list_del(&uobj->uobject.list); - up(&file->mutex); - - down(&ib_uverbs_idr_mutex); +err_idr: idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); - up(&ib_uverbs_idr_mutex); -err_cq: +err_up: + up(&ib_uverbs_idr_mutex); ib_destroy_cq(cq); err: @@ -837,24 +830,22 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, resp.qp_handle = uobj->uobject.id; - down(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); - up(&file->mutex); - if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_list; + goto err_idr; } + down(&file->mutex); + list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); + up(&file->mutex); + up(&ib_uverbs_idr_mutex); return in_len; -err_list: - down(&file->mutex); - list_del(&uobj->uobject.list); - up(&file->mutex); +err_idr: + idr_remove(&ib_uverbs_qp_idr, uobj->uobject.id); err_destroy: ib_destroy_qp(qp); @@ -1126,24 +1117,22 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, resp.srq_handle = uobj->uobject.id; - down(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); - up(&file->mutex); - if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_list; + goto err_idr; } + down(&file->mutex); + list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); + up(&file->mutex); + up(&ib_uverbs_idr_mutex); return in_len; -err_list: - down(&file->mutex); - list_del(&uobj->uobject.list); - up(&file->mutex); +err_idr: + idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id); err_destroy: ib_destroy_srq(srq); From 274c0891637c44ac71f3ac40be91b43c2318883a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 29 Sep 2005 14:17:48 -0700 Subject: [PATCH 0312/1940] [IB] uverbs: Add device-specific ABI version attribute Add abi_version attribute to uverbs class devices to allow for ABI versioning of device-specific interfaces. Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_main.c | 11 +++++++++++ drivers/infiniband/hw/mthca/mthca_provider.c | 1 + drivers/infiniband/hw/mthca/mthca_user.h | 6 ++++++ include/rdma/ib_verbs.h | 2 ++ 4 files changed, 20 insertions(+) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index e7058fbc607d..c84cc28b60ee 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -598,6 +598,15 @@ static ssize_t show_ibdev(struct class_device *class_dev, char *buf) } static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); +static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf) +{ + struct ib_uverbs_device *dev = + container_of(class_dev, struct ib_uverbs_device, class_dev); + + return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver); +} +static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); + static void ib_uverbs_release_class_dev(struct class_device *class_dev) { struct ib_uverbs_device *dev = @@ -662,6 +671,8 @@ static void ib_uverbs_add_one(struct ib_device *device) if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev)) goto err_class; + if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_abi_version)) + goto err_class; ib_set_client_data(device, &uverbs_client, uverbs_dev); diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 141509dced7e..939b09dcfe09 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1060,6 +1060,7 @@ int mthca_register_device(struct mthca_dev *dev) strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX); dev->ib_dev.owner = THIS_MODULE; + dev->ib_dev.uverbs_abi_ver = MTHCA_UVERBS_ABI_VERSION; dev->ib_dev.node_type = IB_NODE_CA; dev->ib_dev.phys_port_cnt = dev->limits.num_ports; dev->ib_dev.dma_device = &dev->pdev->dev; diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h index 41613ec8a04e..bb015c6494c4 100644 --- a/drivers/infiniband/hw/mthca/mthca_user.h +++ b/drivers/infiniband/hw/mthca/mthca_user.h @@ -37,6 +37,12 @@ #include +/* + * Increment this value if any changes that break userspace ABI + * compatibility are made. + */ +#define MTHCA_UVERBS_ABI_VERSION 1 + /* * Make sure that all structs defined in this file remain laid out so * that they pack the same way on 32-bit and 64-bit architectures (to diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index e6f4c9e55df7..d13f25a78192 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -951,6 +951,8 @@ struct ib_device { IB_DEV_UNREGISTERED } reg_state; + int uverbs_abi_ver; + u8 node_type; u8 phys_port_cnt; }; From 9825051e8c81cbd4400333e7cdc04be77a0bab75 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Sat, 1 Oct 2005 13:09:44 -0700 Subject: [PATCH 0313/1940] [IB] mthca: Fill in more fields in query_port method Add code to fill in the bad_pkey_cntr, max_mtu, active_mtu and subnet_timeout fields in mthca_query_port(). Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_provider.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 939b09dcfe09..4e87ad115712 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -152,9 +152,13 @@ static int mthca_query_port(struct ib_device *ibdev, props->gid_tbl_len = to_mdev(ibdev)->limits.gid_table_len; props->max_msg_sz = 0x80000000; props->pkey_tbl_len = to_mdev(ibdev)->limits.pkey_table_len; + props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46)); props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48)); props->active_width = out_mad->data[31] & 0xf; props->active_speed = out_mad->data[35] >> 4; + props->max_mtu = out_mad->data[41] & 0xf; + props->active_mtu = out_mad->data[36] >> 4; + props->subnet_timeout = out_mad->data[51] & 0x1f; out: kfree(in_mad); From f575394f1de9b4afa4b474f1882c7e2d3b8e51d7 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 3 Oct 2005 09:18:02 -0700 Subject: [PATCH 0314/1940] [IB] uverbs: reject invalid memory registration permission flags Reject userspace memory registrations with invalid permission flags: "local write" is required if "remote write" or "remote atomic" is also requested. Pointed out by Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_cmd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index a0ceb1cbed52..2e959acf2ff1 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -396,6 +396,14 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK)) return -EINVAL; + /* + * Local write permission is required if remote write or + * remote atomic permission is also requested. + */ + if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) && + !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE)) + return -EINVAL; + obj = kmalloc(sizeof *obj, GFP_KERNEL); if (!obj) return -ENOMEM; From 116c0074ecfd6f061570856bec52b691d54dbd3c Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 3 Oct 2005 09:32:33 -0700 Subject: [PATCH 0315/1940] [IB] Check port number in ib_query_port()/ib_modify_port() Check port number before passing query_port or modify_port operations on to device driver. Signed-off-by: Roland Dreier --- drivers/infiniband/core/device.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index d3cf84e01587..5a6e44976405 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -514,6 +514,12 @@ int ib_query_port(struct ib_device *device, u8 port_num, struct ib_port_attr *port_attr) { + if (device->node_type == IB_NODE_SWITCH) { + if (port_num) + return -EINVAL; + } else if (port_num < 1 || port_num > device->phys_port_cnt) + return -EINVAL; + return device->query_port(device, port_num, port_attr); } EXPORT_SYMBOL(ib_query_port); @@ -583,6 +589,12 @@ int ib_modify_port(struct ib_device *device, u8 port_num, int port_modify_mask, struct ib_port_modify *port_modify) { + if (device->node_type == IB_NODE_SWITCH) { + if (port_num) + return -EINVAL; + } else if (port_num < 1 || port_num > device->phys_port_cnt) + return -EINVAL; + return device->modify_port(device, port_num, port_modify_mask, port_modify); } From 90f104da22bbf2e2b8a2136c12fb4e013fccf504 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 6 Oct 2005 13:15:56 -0700 Subject: [PATCH 0316/1940] [IB] mthca: SRQ limit reached events Our hardware supports generating an event when the number of receives posted to a shared receive queue (SRQ) falls below a user-specified limit. Implement mthca_modify_srq() to arm the limit, and add code to handle dispatching SRQ events when they occur. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_dev.h | 2 ++ drivers/infiniband/hw/mthca/mthca_eq.c | 21 +++++++++++++--- drivers/infiniband/hw/mthca/mthca_provider.c | 1 + drivers/infiniband/hw/mthca/mthca_srq.c | 25 +++++++++++++++++++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 67a2f324a274..6e18c128af42 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -448,6 +448,8 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, struct ib_srq_attr *attr, struct mthca_srq *srq); void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq); +int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, + enum ib_srq_attr_mask attr_mask); void mthca_srq_event(struct mthca_dev *dev, u32 srqn, enum ib_event_type event_type); void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr); diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index c81fa8e975ef..f2afdc6c7e60 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -83,7 +83,8 @@ enum { MTHCA_EVENT_TYPE_PATH_MIG = 0x01, MTHCA_EVENT_TYPE_COMM_EST = 0x02, MTHCA_EVENT_TYPE_SQ_DRAINED = 0x03, - MTHCA_EVENT_TYPE_SRQ_LAST_WQE = 0x13, + MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE = 0x13, + MTHCA_EVENT_TYPE_SRQ_LIMIT = 0x14, MTHCA_EVENT_TYPE_CQ_ERROR = 0x04, MTHCA_EVENT_TYPE_WQ_CATAS_ERROR = 0x05, MTHCA_EVENT_TYPE_EEC_CATAS_ERROR = 0x06, @@ -110,8 +111,9 @@ enum { (1ULL << MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR) | \ (1ULL << MTHCA_EVENT_TYPE_PORT_CHANGE) | \ (1ULL << MTHCA_EVENT_TYPE_ECC_DETECT)) -#define MTHCA_SRQ_EVENT_MASK (1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR) | \ - (1ULL << MTHCA_EVENT_TYPE_SRQ_LAST_WQE) +#define MTHCA_SRQ_EVENT_MASK ((1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR) | \ + (1ULL << MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE) | \ + (1ULL << MTHCA_EVENT_TYPE_SRQ_LIMIT)) #define MTHCA_CMD_EVENT_MASK (1ULL << MTHCA_EVENT_TYPE_CMD) #define MTHCA_EQ_DB_INC_CI (1 << 24) @@ -141,6 +143,9 @@ struct mthca_eqe { struct { __be32 qpn; } __attribute__((packed)) qp; + struct { + __be32 srqn; + } __attribute__((packed)) srq; struct { __be32 cqn; u32 reserved1; @@ -305,6 +310,16 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) IB_EVENT_SQ_DRAINED); break; + case MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE: + mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff, + IB_EVENT_QP_LAST_WQE_REACHED); + break; + + case MTHCA_EVENT_TYPE_SRQ_LIMIT: + mthca_srq_event(dev, be32_to_cpu(eqe->event.srq.srqn) & 0xffffff, + IB_EVENT_SRQ_LIMIT_REACHED); + break; + case MTHCA_EVENT_TYPE_WQ_CATAS_ERROR: mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff, IB_EVENT_QP_FATAL); diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 4e87ad115712..53b29a0841bf 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1084,6 +1084,7 @@ int mthca_register_device(struct mthca_dev *dev) if (dev->mthca_flags & MTHCA_FLAG_SRQ) { dev->ib_dev.create_srq = mthca_create_srq; + dev->ib_dev.modify_srq = mthca_modify_srq; dev->ib_dev.destroy_srq = mthca_destroy_srq; if (mthca_is_memfree(dev)) diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 18998d48c53e..13d2290261d9 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -332,6 +332,29 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq) mthca_free_mailbox(dev, mailbox); } +int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, + enum ib_srq_attr_mask attr_mask) +{ + struct mthca_dev *dev = to_mdev(ibsrq->device); + struct mthca_srq *srq = to_msrq(ibsrq); + int ret; + u8 status; + + /* We don't support resizing SRQs (yet?) */ + if (attr_mask & IB_SRQ_MAX_WR) + return -EINVAL; + + if (attr_mask & IB_SRQ_LIMIT) { + ret = mthca_ARM_SRQ(dev, srq->srqn, attr->srq_limit, &status); + if (ret) + return ret; + if (status) + return -EINVAL; + } + + return 0; +} + void mthca_srq_event(struct mthca_dev *dev, u32 srqn, enum ib_event_type event_type) { @@ -354,7 +377,7 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn, event.device = &dev->ib_dev; event.event = event_type; - event.element.srq = &srq->ibsrq; + event.element.srq = &srq->ibsrq; srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context); out: From e23d6d2b090658007732770720a44375cba23200 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 6 Oct 2005 13:25:16 -0700 Subject: [PATCH 0317/1940] [IB] mthca: detect SRQ overflow The hardware relies on us keeping one extra work request that never gets used in SRQs. Add checks to the SRQ work request posting functions so that they fail when someone is about to use up that extra work request, rather than when someone uses the very last work request. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_srq.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 13d2290261d9..e464321a7aa7 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -438,6 +438,14 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, wqe = get_wqe(srq, ind); next_ind = *wqe_to_link(wqe); + + if (next_ind < 0) { + mthca_err(dev, "SRQ %06x full\n", srq->srqn); + err = -ENOMEM; + *bad_wr = wr; + break; + } + prev_wqe = srq->last; srq->last = wqe; @@ -529,6 +537,13 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, wqe = get_wqe(srq, ind); next_ind = *wqe_to_link(wqe); + if (next_ind < 0) { + mthca_err(dev, "SRQ %06x full\n", srq->srqn); + err = -ENOMEM; + *bad_wr = wr; + break; + } + ((struct mthca_next_seg *) wqe)->nda_op = cpu_to_be32((next_ind << srq->wqe_shift) | 1); ((struct mthca_next_seg *) wqe)->ee_nds = 0; From 4ab6fb7e5b3d34b65a1c3473d80d9d1a462d3a49 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 6 Oct 2005 13:28:16 -0700 Subject: [PATCH 0318/1940] [IB] Fix leak on MAD initialization failure There is a bug in ib_mad_init_device(): if ib_agent_port_open() fails for a given port, then the current code doesn't call ib_mad_port_close() for that port. Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 45 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index a14ca87fda18..af302e830561 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -2683,40 +2683,47 @@ static int ib_mad_port_close(struct ib_device *device, int port_num) static void ib_mad_init_device(struct ib_device *device) { - int num_ports, cur_port, i; + int start, end, i; if (device->node_type == IB_NODE_SWITCH) { - num_ports = 1; - cur_port = 0; + start = 0; + end = 0; } else { - num_ports = device->phys_port_cnt; - cur_port = 1; + start = 1; + end = device->phys_port_cnt; } - for (i = 0; i < num_ports; i++, cur_port++) { - if (ib_mad_port_open(device, cur_port)) { + + for (i = start; i <= end; i++) { + if (ib_mad_port_open(device, i)) { printk(KERN_ERR PFX "Couldn't open %s port %d\n", - device->name, cur_port); - goto error_device_open; + device->name, i); + goto error; } - if (ib_agent_port_open(device, cur_port)) { + if (ib_agent_port_open(device, i)) { printk(KERN_ERR PFX "Couldn't open %s port %d " "for agents\n", - device->name, cur_port); - goto error_device_open; + device->name, i); + goto error_agent; } } return; -error_device_open: - while (i > 0) { - cur_port--; - if (ib_agent_port_close(device, cur_port)) +error_agent: + if (ib_mad_port_close(device, i)) + printk(KERN_ERR PFX "Couldn't close %s port %d\n", + device->name, i); + +error: + i--; + + while (i >= start) { + if (ib_agent_port_close(device, i)) printk(KERN_ERR PFX "Couldn't close %s port %d " "for agents\n", - device->name, cur_port); - if (ib_mad_port_close(device, cur_port)) + device->name, i); + if (ib_mad_port_close(device, i)) printk(KERN_ERR PFX "Couldn't close %s port %d\n", - device->name, cur_port); + device->name, i); i--; } } From efaae8f71f3088cc73c9e5ceabbd314aa82ac768 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 10 Oct 2005 13:48:07 -0700 Subject: [PATCH 0319/1940] [IB] mthca: Better limit checking and reporting Check the sizes of CQs, QPs and SRQs when creating objects, and fail instead of creating too-big queues. Also return real limits instead of just plausible-sounding values from mthca_query_device(). Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 6 ++++-- drivers/infiniband/hw/mthca/mthca_dev.h | 6 ++++++ drivers/infiniband/hw/mthca/mthca_main.c | 9 +++++++++ drivers/infiniband/hw/mthca/mthca_mcg.c | 4 ---- drivers/infiniband/hw/mthca/mthca_provider.c | 18 +++++++++++++++--- drivers/infiniband/hw/mthca/mthca_qp.c | 6 ++++-- drivers/infiniband/hw/mthca/mthca_srq.c | 3 ++- 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index f6a8ac026557..1bd7dc8f778c 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -933,9 +933,9 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, goto out; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); - dev_lim->max_srq_sz = 1 << field; + dev_lim->max_srq_sz = (1 << field) - 1; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); - dev_lim->max_qp_sz = 1 << field; + dev_lim->max_qp_sz = (1 << field) - 1; MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); dev_lim->reserved_qps = 1 << (field & 0xf); MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); @@ -1045,6 +1045,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", dev_lim->max_pds, dev_lim->reserved_mgms); + mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", + dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 6e18c128af42..f106bac0f925 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -83,6 +83,8 @@ enum { /* Arbel FW gives us these, but we need them for Tavor */ MTHCA_MPT_ENTRY_SIZE = 0x40, MTHCA_MTT_SEG_SIZE = 0x40, + + MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2) }; enum { @@ -128,12 +130,16 @@ struct mthca_limits { int num_uars; int max_sg; int num_qps; + int max_wqes; + int max_qp_init_rdma; int reserved_qps; int num_srqs; + int max_srq_wqes; int reserved_srqs; int num_eecs; int reserved_eecs; int num_cqs; + int max_cqes; int reserved_cqs; int num_eqs; int reserved_eqs; diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 576e7fcd053c..7c35abec81ea 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -162,9 +162,18 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim mdev->limits.pkey_table_len = dev_lim->max_pkeys; mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay; mdev->limits.max_sg = dev_lim->max_sg; + mdev->limits.max_wqes = dev_lim->max_qp_sz; + mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp; mdev->limits.reserved_qps = dev_lim->reserved_qps; + mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; mdev->limits.reserved_srqs = dev_lim->reserved_srqs; mdev->limits.reserved_eecs = dev_lim->reserved_eecs; + /* + * Subtract 1 from the limit because we need to allocate a + * spare CQE so the HCA HW can tell the difference between an + * empty CQ and a full CQ. + */ + mdev->limits.max_cqes = dev_lim->max_cq_sz - 1; mdev->limits.reserved_cqs = dev_lim->reserved_cqs; mdev->limits.reserved_eqs = dev_lim->reserved_eqs; mdev->limits.reserved_mtts = dev_lim->reserved_mtts; diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index a2707605f4c8..9a0612a9d304 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -37,10 +37,6 @@ #include "mthca_dev.h" #include "mthca_cmd.h" -enum { - MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2) -}; - struct mthca_mgm { __be32 next_gid_index; u32 reserved[3]; diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 53b29a0841bf..46864d18827d 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -90,17 +90,26 @@ static int mthca_query_device(struct ib_device *ibdev, props->max_mr_size = ~0ull; props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; - props->max_qp_wr = 0xffff; + props->max_qp_wr = mdev->limits.max_wqes; props->max_sge = mdev->limits.max_sg; props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs; - props->max_cqe = 0xffff; + props->max_cqe = mdev->limits.max_cqes; props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws; props->max_pd = mdev->limits.num_pds - mdev->limits.reserved_pds; props->max_qp_rd_atom = 1 << mdev->qp_table.rdb_shift; - props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift; + props->max_qp_init_rd_atom = mdev->limits.max_qp_init_rdma; + props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp; + props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs; + props->max_srq_wr = mdev->limits.max_srq_wqes; + props->max_srq_sge = mdev->limits.max_sg; props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay; props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? IB_ATOMIC_HCA : IB_ATOMIC_NONE; + props->max_pkeys = mdev->limits.pkey_table_len; + props->max_mcast_grp = mdev->limits.num_mgms + mdev->limits.num_amgms; + props->max_mcast_qp_attach = MTHCA_QP_PER_MGM; + props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * + props->max_mcast_grp; err = 0; out: @@ -640,6 +649,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries, int nent; int err; + if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes) + return ERR_PTR(-EINVAL); + if (context) { if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) return ERR_PTR(-EFAULT); diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 5fa00669f9b8..2ee0a2b0fd4b 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1112,8 +1112,10 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, struct mthca_qp *qp) { /* Sanity check QP size before proceeding */ - if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 || - cap->max_send_sge > 64 || cap->max_recv_sge > 64) + if (cap->max_send_wr > dev->limits.max_wqes || + cap->max_recv_wr > dev->limits.max_wqes || + cap->max_send_sge > dev->limits.max_sg || + cap->max_recv_sge > dev->limits.max_sg) return -EINVAL; if (mthca_is_memfree(dev)) { diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index e464321a7aa7..64f70aa1b3c0 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -186,7 +186,8 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, int err; /* Sanity check SRQ size before proceeding */ - if (attr->max_wr > 16 << 20 || attr->max_sge > 64) + if (attr->max_wr > dev->limits.max_srq_wqes || + attr->max_sge > dev->limits.max_sg) return -EINVAL; srq->max = attr->max_wr; From 5b6810e048435de508ef66aebd6b78db13d651b8 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 11 Oct 2005 11:08:24 -0700 Subject: [PATCH 0320/1940] [IPoIB] Rename ipoib_create_qp() -> ipoib_init_qp() and fix error cleanup ipoib_create_qp() no longer creates IPoIB's QP, so it shouldn't destroy the QP on failure -- that unwinding happens elsewhere, so the current code can cause a double free. While we're at it, the function's name should match what it actually does, so rename it to ipoib_init_qp(). Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib.h | 2 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 4 ++-- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 4ea1c1ca85bc..6b14bd1c60a0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -277,7 +277,7 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid); -int ipoib_qp_create(struct net_device *dev); +int ipoib_init_qp(struct net_device *dev); int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca); void ipoib_transport_dev_cleanup(struct net_device *dev); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f7440096b5ed..02d0e0006578 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -387,9 +387,9 @@ int ipoib_ib_dev_open(struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; - ret = ipoib_qp_create(dev); + ret = ipoib_init_qp(dev); if (ret) { - ipoib_warn(priv, "ipoib_qp_create returned %d\n", ret); + ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret); return -1; } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 79f59d0563ed..b5902a7ec240 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -92,7 +92,7 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid) return ret; } -int ipoib_qp_create(struct net_device *dev) +int ipoib_init_qp(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; @@ -149,10 +149,11 @@ int ipoib_qp_create(struct net_device *dev) return 0; out_fail: - ib_destroy_qp(priv->qp); - priv->qp = NULL; + qp_attr.qp_state = IB_QPS_RESET; + if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) + ipoib_warn(priv, "Failed to modify QP to RESET state\n"); - return -EINVAL; + return ret; } int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) From 305a7e87055dde2466a855c24ef51a606915d149 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 11 Oct 2005 15:39:38 -0700 Subject: [PATCH 0321/1940] [IB] uverbs: unlock correctly in error paths A couple of functions were missing spin_unlock calls in error paths. Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index c84cc28b60ee..3a887006b253 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -312,8 +312,10 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) } entry = kmalloc(sizeof *entry, GFP_ATOMIC); - if (!entry) + if (!entry) { + spin_unlock_irqrestore(&file->lock, flags); return; + } uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); @@ -343,8 +345,10 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, } entry = kmalloc(sizeof *entry, GFP_ATOMIC); - if (!entry) + if (!entry) { + spin_unlock_irqrestore(&file->async_file->lock, flags); return; + } entry->desc.async.element = element; entry->desc.async.event_type = event; From 56c202d6e4f542468fe79b8a735cf128898b87fb Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 13 Oct 2005 10:45:02 -0700 Subject: [PATCH 0322/1940] [IB] fail SA queries if device initialization failed If the SA query module's initialization fails for a device, then that device won't have a struct ib_sa_device associated. We should fail SA queries in that case, rather than blindly dereferencing the NULL pointer we get back from ib_get_client_data(). Signed-off-by: Roland Dreier --- drivers/infiniband/core/sa_query.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 262618210c1c..a2c4234ca8a3 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -583,10 +583,16 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, { struct ib_sa_path_query *query; struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); - struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; - struct ib_mad_agent *agent = port->agent; + struct ib_sa_port *port; + struct ib_mad_agent *agent; int ret; + if (!sa_dev) + return -ENODEV; + + port = &sa_dev->port[port_num - sa_dev->start_port]; + agent = port->agent; + query = kmalloc(sizeof *query, gfp_mask); if (!query) return -ENOMEM; @@ -685,10 +691,16 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, { struct ib_sa_service_query *query; struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); - struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; - struct ib_mad_agent *agent = port->agent; + struct ib_sa_port *port; + struct ib_mad_agent *agent; int ret; + if (!sa_dev) + return -ENODEV; + + port = &sa_dev->port[port_num - sa_dev->start_port]; + agent = port->agent; + if (method != IB_MGMT_METHOD_GET && method != IB_MGMT_METHOD_SET && method != IB_SA_METHOD_DELETE) @@ -768,10 +780,16 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, { struct ib_sa_mcmember_query *query; struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); - struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; - struct ib_mad_agent *agent = port->agent; + struct ib_sa_port *port; + struct ib_mad_agent *agent; int ret; + if (!sa_dev) + return -ENODEV; + + port = &sa_dev->port[port_num - sa_dev->start_port]; + agent = port->agent; + query = kmalloc(sizeof *query, gfp_mask); if (!query) return -ENOMEM; From 883a99c7024c5763d6d4f22d9239c133893e8d74 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 14 Oct 2005 14:00:58 -0700 Subject: [PATCH 0323/1940] [IB] uverbs: Add a mask of device methods allowed for userspace Give each device a uverbs_cmd_mask, so that a low-level driver can control which methods may be called on behalf of userspace. Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_main.c | 3 ++- drivers/infiniband/hw/mthca/mthca_provider.c | 20 ++++++++++++++++++++ include/rdma/ib_verbs.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 3a887006b253..6a5e5084db7a 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -514,7 +514,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || - !uverbs_cmd_table[hdr.command]) + !uverbs_cmd_table[hdr.command] || + !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) return -EINVAL; if (!file->ucontext && diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 46864d18827d..9e911a1ea415 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -37,6 +37,7 @@ */ #include +#include #include #include "mthca_dev.h" @@ -1077,6 +1078,25 @@ int mthca_register_device(struct mthca_dev *dev) dev->ib_dev.owner = THIS_MODULE; dev->ib_dev.uverbs_abi_ver = MTHCA_UVERBS_ABI_VERSION; + dev->ib_dev.uverbs_cmd_mask = + (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | + (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | + (1ull << IB_USER_VERBS_CMD_QUERY_PORT) | + (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | + (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | + (1ull << IB_USER_VERBS_CMD_REG_MR) | + (1ull << IB_USER_VERBS_CMD_DEREG_MR) | + (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | + (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | + (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | + (1ull << IB_USER_VERBS_CMD_CREATE_QP) | + (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | + (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | + (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | + (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) | + (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) | + (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) | + (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ); dev->ib_dev.node_type = IB_NODE_CA; dev->ib_dev.phys_port_cnt = dev->limits.num_ports; dev->ib_dev.dma_device = &dev->pdev->dev; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index d13f25a78192..a5a963cb5676 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -951,6 +951,7 @@ struct ib_device { IB_DEV_UNREGISTERED } reg_state; + u64 uverbs_cmd_mask; int uverbs_abi_ver; u8 node_type; From 91ecd4ae178bed83da4f6a94ced7992e4d7711eb Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 14 Oct 2005 15:21:44 -0700 Subject: [PATCH 0324/1940] [IB] uverbs: Add ABI structures for more commands Add kernel/user ABI structures for marshalling poll CQ, request CQ notification, post send, post receive, post SRQ receive, create AH and destroy AH commands. These commands allow us to support userspace verbs for devices that can't perform these operations directly from userspace (eg the PathScale HCA). Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 164 ++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 0532b78200ca..072f3a2edace 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. + * Copyright (c) 2005 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -88,8 +89,11 @@ enum { * Make sure that all structs defined in this file remain laid out so * that they pack the same way on 32-bit and 64-bit architectures (to * avoid incompatibility between 32-bit userspace and 64-bit kernels). - * In particular do not use pointer types -- pass pointers in __u64 - * instead. + * Specifically: + * - Do not use pointer types -- pass pointers in __u64 instead. + * - Make sure that any structure larger than 4 bytes is padded to a + * multiple of 8 bytes. Otherwise the structure size will be + * different between 32-bit and 64-bit architectures. */ struct ib_uverbs_async_event_desc { @@ -261,6 +265,41 @@ struct ib_uverbs_create_cq_resp { __u32 cqe; }; +struct ib_uverbs_poll_cq { + __u64 response; + __u32 cq_handle; + __u32 ne; +}; + +struct ib_uverbs_wc { + __u64 wr_id; + __u32 status; + __u32 opcode; + __u32 vendor_err; + __u32 byte_len; + __u32 imm_data; + __u32 qp_num; + __u32 src_qp; + __u32 wc_flags; + __u16 pkey_index; + __u16 slid; + __u8 sl; + __u8 dlid_path_bits; + __u8 port_num; + __u8 reserved; +}; + +struct ib_uverbs_poll_cq_resp { + __u32 count; + __u32 reserved; + struct ib_uverbs_wc wc[0]; +}; + +struct ib_uverbs_req_notify_cq { + __u32 cq_handle; + __u32 solicited_only; +}; + struct ib_uverbs_destroy_cq { __u64 response; __u32 cq_handle; @@ -358,6 +397,127 @@ struct ib_uverbs_destroy_qp_resp { __u32 events_reported; }; +/* + * The ib_uverbs_sge structure isn't used anywhere, since we assume + * the ib_sge structure is packed the same way on 32-bit and 64-bit + * architectures in both kernel and user space. It's just here to + * document the ABI. + */ +struct ib_uverbs_sge { + __u64 addr; + __u32 length; + __u32 lkey; +}; + +struct ib_uverbs_send_wr { + __u64 wr_id; + __u32 num_sge; + __u32 opcode; + __u32 send_flags; + __u32 imm_data; + union { + struct { + __u64 remote_addr; + __u32 rkey; + __u32 reserved; + } rdma; + struct { + __u64 remote_addr; + __u64 compare_add; + __u64 swap; + __u32 rkey; + __u32 reserved; + } atomic; + struct { + __u32 ah; + __u32 remote_qpn; + __u32 remote_qkey; + __u32 reserved; + } ud; + } wr; +}; + +struct ib_uverbs_post_send { + __u64 response; + __u32 qp_handle; + __u32 wr_count; + __u32 sge_count; + __u32 wqe_size; + struct ib_uverbs_send_wr send_wr[0]; +}; + +struct ib_uverbs_post_send_resp { + __u32 bad_wr; +}; + +struct ib_uverbs_recv_wr { + __u64 wr_id; + __u32 num_sge; + __u32 reserved; +}; + +struct ib_uverbs_post_recv { + __u64 response; + __u32 qp_handle; + __u32 wr_count; + __u32 sge_count; + __u32 wqe_size; + struct ib_uverbs_recv_wr recv_wr[0]; +}; + +struct ib_uverbs_post_recv_resp { + __u32 bad_wr; +}; + +struct ib_uverbs_post_srq_recv { + __u64 response; + __u32 srq_handle; + __u32 wr_count; + __u32 sge_count; + __u32 wqe_size; + struct ib_uverbs_recv_wr recv[0]; +}; + +struct ib_uverbs_post_srq_recv_resp { + __u32 bad_wr; +}; + +struct ib_uverbs_global_route { + __u8 dgid[16]; + __u32 flow_label; + __u8 sgid_index; + __u8 hop_limit; + __u8 traffic_class; + __u8 reserved; +}; + +struct ib_uverbs_ah_attr { + struct ib_uverbs_global_route grh; + __u16 dlid; + __u8 sl; + __u8 src_path_bits; + __u8 static_rate; + __u8 is_global; + __u8 port_num; + __u8 reserved; +}; + +struct ib_uverbs_create_ah { + __u64 response; + __u64 user_handle; + __u32 pd_handle; + __u32 reserved; + struct ib_uverbs_ah_attr attr; +}; + +struct ib_uverbs_create_ah_resp { + __u32 ah_handle; +}; + +struct ib_uverbs_destroy_ah { + __u32 ah_handle; +}; + struct ib_uverbs_attach_mcast { __u8 gid[16]; __u32 qp_handle; From 67cdb40ca444c09853ab4d8a41cf547ac26a4de4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 14 Oct 2005 15:26:04 -0700 Subject: [PATCH 0325/1940] [IB] uverbs: Implement more commands Add kernel support for userspace calling poll CQ, request CQ notification, post send, post receive, post SRQ receive, create AH and destroy AH commands. These commands allow us to support userspace verbs for devices that can't perform these operations directly from userspace (eg the PathScale HCA). Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs.h | 8 + drivers/infiniband/core/uverbs_cmd.c | 549 ++++++++++++++++++++++++++ drivers/infiniband/core/uverbs_main.c | 16 +- 3 files changed, 572 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 475153e510a9..63c8085c0c98 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -3,6 +3,7 @@ * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2005 Voltaire, Inc. All rights reserved. + * Copyright (c) 2005 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -140,10 +141,17 @@ IB_UVERBS_DECLARE_CMD(reg_mr); IB_UVERBS_DECLARE_CMD(dereg_mr); IB_UVERBS_DECLARE_CMD(create_comp_channel); IB_UVERBS_DECLARE_CMD(create_cq); +IB_UVERBS_DECLARE_CMD(poll_cq); +IB_UVERBS_DECLARE_CMD(req_notify_cq); IB_UVERBS_DECLARE_CMD(destroy_cq); IB_UVERBS_DECLARE_CMD(create_qp); IB_UVERBS_DECLARE_CMD(modify_qp); IB_UVERBS_DECLARE_CMD(destroy_qp); +IB_UVERBS_DECLARE_CMD(post_send); +IB_UVERBS_DECLARE_CMD(post_recv); +IB_UVERBS_DECLARE_CMD(post_srq_recv); +IB_UVERBS_DECLARE_CMD(create_ah); +IB_UVERBS_DECLARE_CMD(destroy_ah); IB_UVERBS_DECLARE_CMD(attach_mcast); IB_UVERBS_DECLARE_CMD(detach_mcast); IB_UVERBS_DECLARE_CMD(create_srq); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 2e959acf2ff1..14583bb6e2c0 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -665,6 +665,93 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, return ret; } +ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_poll_cq cmd; + struct ib_uverbs_poll_cq_resp *resp; + struct ib_cq *cq; + struct ib_wc *wc; + int ret = 0; + int i; + int rsize; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); + if (!wc) + return -ENOMEM; + + rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); + resp = kmalloc(rsize, GFP_KERNEL); + if (!resp) { + ret = -ENOMEM; + goto out_wc; + } + + down(&ib_uverbs_idr_mutex); + cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); + if (!cq || cq->uobject->context != file->ucontext) { + ret = -EINVAL; + goto out; + } + + resp->count = ib_poll_cq(cq, cmd.ne, wc); + + for (i = 0; i < resp->count; i++) { + resp->wc[i].wr_id = wc[i].wr_id; + resp->wc[i].status = wc[i].status; + resp->wc[i].opcode = wc[i].opcode; + resp->wc[i].vendor_err = wc[i].vendor_err; + resp->wc[i].byte_len = wc[i].byte_len; + resp->wc[i].imm_data = wc[i].imm_data; + resp->wc[i].qp_num = wc[i].qp_num; + resp->wc[i].src_qp = wc[i].src_qp; + resp->wc[i].wc_flags = wc[i].wc_flags; + resp->wc[i].pkey_index = wc[i].pkey_index; + resp->wc[i].slid = wc[i].slid; + resp->wc[i].sl = wc[i].sl; + resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; + resp->wc[i].port_num = wc[i].port_num; + } + + if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) + ret = -EFAULT; + +out: + up(&ib_uverbs_idr_mutex); + kfree(resp); + +out_wc: + kfree(wc); + return ret ? ret : in_len; +} + +ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_req_notify_cq cmd; + struct ib_cq *cq; + int ret = -EINVAL; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + down(&ib_uverbs_idr_mutex); + cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); + if (cq && cq->uobject->context == file->ucontext) { + ib_req_notify_cq(cq, cmd.solicited_only ? + IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); + ret = in_len; + } + up(&ib_uverbs_idr_mutex); + + return ret; +} + ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -1003,6 +1090,468 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, return ret ? ret : in_len; } +ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_post_send cmd; + struct ib_uverbs_post_send_resp resp; + struct ib_uverbs_send_wr *user_wr; + struct ib_send_wr *wr = NULL, *last, *next, *bad_wr; + struct ib_qp *qp; + int i, sg_ind; + ssize_t ret = -EINVAL; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count + + cmd.sge_count * sizeof (struct ib_uverbs_sge)) + return -EINVAL; + + if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr)) + return -EINVAL; + + user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL); + if (!user_wr) + return -ENOMEM; + + down(&ib_uverbs_idr_mutex); + + qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); + if (!qp || qp->uobject->context != file->ucontext) + goto out; + + sg_ind = 0; + last = NULL; + for (i = 0; i < cmd.wr_count; ++i) { + if (copy_from_user(user_wr, + buf + sizeof cmd + i * cmd.wqe_size, + cmd.wqe_size)) { + ret = -EFAULT; + goto out; + } + + if (user_wr->num_sge + sg_ind > cmd.sge_count) { + ret = -EINVAL; + goto out; + } + + next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + + user_wr->num_sge * sizeof (struct ib_sge), + GFP_KERNEL); + if (!next) { + ret = -ENOMEM; + goto out; + } + + if (!last) + wr = next; + else + last->next = next; + last = next; + + next->next = NULL; + next->wr_id = user_wr->wr_id; + next->num_sge = user_wr->num_sge; + next->opcode = user_wr->opcode; + next->send_flags = user_wr->send_flags; + next->imm_data = user_wr->imm_data; + + if (qp->qp_type == IB_QPT_UD) { + next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, + user_wr->wr.ud.ah); + if (!next->wr.ud.ah) { + ret = -EINVAL; + goto out; + } + next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn; + next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey; + } else { + switch (next->opcode) { + case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_WRITE_WITH_IMM: + case IB_WR_RDMA_READ: + next->wr.rdma.remote_addr = + user_wr->wr.rdma.remote_addr; + next->wr.rdma.rkey = + user_wr->wr.rdma.rkey; + break; + case IB_WR_ATOMIC_CMP_AND_SWP: + case IB_WR_ATOMIC_FETCH_AND_ADD: + next->wr.atomic.remote_addr = + user_wr->wr.atomic.remote_addr; + next->wr.atomic.compare_add = + user_wr->wr.atomic.compare_add; + next->wr.atomic.swap = user_wr->wr.atomic.swap; + next->wr.atomic.rkey = user_wr->wr.atomic.rkey; + break; + default: + break; + } + } + + if (next->num_sge) { + next->sg_list = (void *) next + + ALIGN(sizeof *next, sizeof (struct ib_sge)); + if (copy_from_user(next->sg_list, + buf + sizeof cmd + + cmd.wr_count * cmd.wqe_size + + sg_ind * sizeof (struct ib_sge), + next->num_sge * sizeof (struct ib_sge))) { + ret = -EFAULT; + goto out; + } + sg_ind += next->num_sge; + } else + next->sg_list = NULL; + } + + resp.bad_wr = 0; + ret = qp->device->post_send(qp, wr, &bad_wr); + if (ret) + for (next = wr; next; next = next->next) { + ++resp.bad_wr; + if (next == bad_wr) + break; + } + + if (copy_to_user((void __user *) (unsigned long) cmd.response, + &resp, sizeof resp)) + ret = -EFAULT; + +out: + up(&ib_uverbs_idr_mutex); + + while (wr) { + next = wr->next; + kfree(wr); + wr = next; + } + + kfree(user_wr); + + return ret ? ret : in_len; +} + +static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf, + int in_len, + u32 wr_count, + u32 sge_count, + u32 wqe_size) +{ + struct ib_uverbs_recv_wr *user_wr; + struct ib_recv_wr *wr = NULL, *last, *next; + int sg_ind; + int i; + int ret; + + if (in_len < wqe_size * wr_count + + sge_count * sizeof (struct ib_uverbs_sge)) + return ERR_PTR(-EINVAL); + + if (wqe_size < sizeof (struct ib_uverbs_recv_wr)) + return ERR_PTR(-EINVAL); + + user_wr = kmalloc(wqe_size, GFP_KERNEL); + if (!user_wr) + return ERR_PTR(-ENOMEM); + + sg_ind = 0; + last = NULL; + for (i = 0; i < wr_count; ++i) { + if (copy_from_user(user_wr, buf + i * wqe_size, + wqe_size)) { + ret = -EFAULT; + goto err; + } + + if (user_wr->num_sge + sg_ind > sge_count) { + ret = -EINVAL; + goto err; + } + + next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + + user_wr->num_sge * sizeof (struct ib_sge), + GFP_KERNEL); + if (!next) { + ret = -ENOMEM; + goto err; + } + + if (!last) + wr = next; + else + last->next = next; + last = next; + + next->next = NULL; + next->wr_id = user_wr->wr_id; + next->num_sge = user_wr->num_sge; + + if (next->num_sge) { + next->sg_list = (void *) next + + ALIGN(sizeof *next, sizeof (struct ib_sge)); + if (copy_from_user(next->sg_list, + buf + wr_count * wqe_size + + sg_ind * sizeof (struct ib_sge), + next->num_sge * sizeof (struct ib_sge))) { + ret = -EFAULT; + goto err; + } + sg_ind += next->num_sge; + } else + next->sg_list = NULL; + } + + kfree(user_wr); + return wr; + +err: + kfree(user_wr); + + while (wr) { + next = wr->next; + kfree(wr); + wr = next; + } + + return ERR_PTR(ret); +} + +ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_post_recv cmd; + struct ib_uverbs_post_recv_resp resp; + struct ib_recv_wr *wr, *next, *bad_wr; + struct ib_qp *qp; + ssize_t ret = -EINVAL; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd, + in_len - sizeof cmd, cmd.wr_count, + cmd.sge_count, cmd.wqe_size); + if (IS_ERR(wr)) + return PTR_ERR(wr); + + down(&ib_uverbs_idr_mutex); + + qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); + if (!qp || qp->uobject->context != file->ucontext) + goto out; + + resp.bad_wr = 0; + ret = qp->device->post_recv(qp, wr, &bad_wr); + if (ret) + for (next = wr; next; next = next->next) { + ++resp.bad_wr; + if (next == bad_wr) + break; + } + + + if (copy_to_user((void __user *) (unsigned long) cmd.response, + &resp, sizeof resp)) + ret = -EFAULT; + +out: + up(&ib_uverbs_idr_mutex); + + while (wr) { + next = wr->next; + kfree(wr); + wr = next; + } + + return ret ? ret : in_len; +} + +ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_post_srq_recv cmd; + struct ib_uverbs_post_srq_recv_resp resp; + struct ib_recv_wr *wr, *next, *bad_wr; + struct ib_srq *srq; + ssize_t ret = -EINVAL; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd, + in_len - sizeof cmd, cmd.wr_count, + cmd.sge_count, cmd.wqe_size); + if (IS_ERR(wr)) + return PTR_ERR(wr); + + down(&ib_uverbs_idr_mutex); + + srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); + if (!srq || srq->uobject->context != file->ucontext) + goto out; + + resp.bad_wr = 0; + ret = srq->device->post_srq_recv(srq, wr, &bad_wr); + if (ret) + for (next = wr; next; next = next->next) { + ++resp.bad_wr; + if (next == bad_wr) + break; + } + + + if (copy_to_user((void __user *) (unsigned long) cmd.response, + &resp, sizeof resp)) + ret = -EFAULT; + +out: + up(&ib_uverbs_idr_mutex); + + while (wr) { + next = wr->next; + kfree(wr); + wr = next; + } + + return ret ? ret : in_len; +} + +ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, + const char __user *buf, int in_len, + int out_len) +{ + struct ib_uverbs_create_ah cmd; + struct ib_uverbs_create_ah_resp resp; + struct ib_uobject *uobj; + struct ib_pd *pd; + struct ib_ah *ah; + struct ib_ah_attr attr; + int ret; + + if (out_len < sizeof resp) + return -ENOSPC; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + uobj = kmalloc(sizeof *uobj, GFP_KERNEL); + if (!uobj) + return -ENOMEM; + + down(&ib_uverbs_idr_mutex); + + pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); + if (!pd || pd->uobject->context != file->ucontext) { + ret = -EINVAL; + goto err_up; + } + + uobj->user_handle = cmd.user_handle; + uobj->context = file->ucontext; + + attr.dlid = cmd.attr.dlid; + attr.sl = cmd.attr.sl; + attr.src_path_bits = cmd.attr.src_path_bits; + attr.static_rate = cmd.attr.static_rate; + attr.port_num = cmd.attr.port_num; + attr.grh.flow_label = cmd.attr.grh.flow_label; + attr.grh.sgid_index = cmd.attr.grh.sgid_index; + attr.grh.hop_limit = cmd.attr.grh.hop_limit; + attr.grh.traffic_class = cmd.attr.grh.traffic_class; + memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16); + + ah = ib_create_ah(pd, &attr); + if (IS_ERR(ah)) { + ret = PTR_ERR(ah); + goto err_up; + } + + ah->uobject = uobj; + +retry: + if (!idr_pre_get(&ib_uverbs_ah_idr, GFP_KERNEL)) { + ret = -ENOMEM; + goto err_destroy; + } + + ret = idr_get_new(&ib_uverbs_ah_idr, ah, &uobj->id); + + if (ret == -EAGAIN) + goto retry; + if (ret) + goto err_destroy; + + resp.ah_handle = uobj->id; + + if (copy_to_user((void __user *) (unsigned long) cmd.response, + &resp, sizeof resp)) { + ret = -EFAULT; + goto err_idr; + } + + down(&file->mutex); + list_add_tail(&uobj->list, &file->ucontext->ah_list); + up(&file->mutex); + + up(&ib_uverbs_idr_mutex); + + return in_len; + +err_idr: + idr_remove(&ib_uverbs_ah_idr, uobj->id); + +err_destroy: + ib_destroy_ah(ah); + +err_up: + up(&ib_uverbs_idr_mutex); + + kfree(uobj); + return ret; +} + +ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, + const char __user *buf, int in_len, int out_len) +{ + struct ib_uverbs_destroy_ah cmd; + struct ib_ah *ah; + struct ib_uobject *uobj; + int ret = -EINVAL; + + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + + down(&ib_uverbs_idr_mutex); + + ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); + if (!ah || ah->uobject->context != file->ucontext) + goto out; + + uobj = ah->uobject; + + ret = ib_destroy_ah(ah); + if (ret) + goto out; + + idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); + + down(&file->mutex); + list_del(&uobj->list); + up(&file->mutex); + + kfree(uobj); + +out: + up(&ib_uverbs_idr_mutex); + + return ret ? ret : in_len; +} + ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 6a5e5084db7a..ef2312a9ea76 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -3,6 +3,7 @@ * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2005 Voltaire, Inc. All rights reserved. + * Copyright (c) 2005 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -86,10 +87,17 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, + [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq, + [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, + [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, + [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv, + [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv, + [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah, + [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah, [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, @@ -111,7 +119,13 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) down(&ib_uverbs_idr_mutex); - /* XXX Free AHs */ + list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { + struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); + idr_remove(&ib_uverbs_ah_idr, uobj->id); + ib_destroy_ah(ah); + list_del(&uobj->list); + kfree(uobj); + } list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); From 595e726a1f28420c5fc7970b1a87cbce77a1cd45 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 17 Oct 2005 15:33:47 -0700 Subject: [PATCH 0326/1940] [IB] merge ucm.h into ucm.c Eliminate ucm.h. Replace ucm_dbg with direct call to printk KERN_ERR. Signed-off-by: Sean Hefty --- drivers/infiniband/core/ucm.c | 62 +++++++++++++++++--------- drivers/infiniband/core/ucm.h | 83 ----------------------------------- 2 files changed, 41 insertions(+), 104 deletions(-) delete mode 100644 drivers/infiniband/core/ucm.h diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index d0f0b0a2edd3..b7470f0fe83b 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -41,19 +41,52 @@ #include #include #include +#include #include -#include "ucm.h" +#include +#include MODULE_AUTHOR("Libor Michalek"); MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); MODULE_LICENSE("Dual BSD/GPL"); -static int ucm_debug_level; +struct ib_ucm_file { + struct semaphore mutex; + struct file *filp; -module_param_named(debug_level, ucm_debug_level, int, 0644); -MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); + struct list_head ctxs; /* list of active connections */ + struct list_head events; /* list of pending events */ + wait_queue_head_t poll_wait; +}; + +struct ib_ucm_context { + int id; + wait_queue_head_t wait; + atomic_t ref; + int events_reported; + + struct ib_ucm_file *file; + struct ib_cm_id *cm_id; + __u64 uid; + + struct list_head events; /* list of pending events. */ + struct list_head file_list; /* member in file ctx list */ +}; + +struct ib_ucm_event { + struct ib_ucm_context *ctx; + struct list_head file_list; /* member in file event list */ + struct list_head ctx_list; /* member in ctx event list */ + + struct ib_cm_id *cm_id; + struct ib_ucm_event_resp resp; + void *data; + void *info; + int data_len; + int info_len; +}; enum { IB_UCM_MAJOR = 231, @@ -62,17 +95,10 @@ enum { #define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR) -#define PFX "UCM: " - -#define ucm_dbg(format, arg...) \ - do { \ - if (ucm_debug_level > 0) \ - printk(KERN_DEBUG PFX format, ## arg); \ - } while (0) - static struct semaphore ctx_id_mutex; static struct idr ctx_id_table; + static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) { struct ib_ucm_context *ctx; @@ -152,7 +178,6 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) goto error; list_add_tail(&ctx->file_list, &file->ctxs); - ucm_dbg("Allocated CM ID <%d>\n", ctx->id); return ctx; error: @@ -1184,9 +1209,6 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, if (copy_from_user(&hdr, buf, sizeof(hdr))) return -EFAULT; - ucm_dbg("Write. cmd <%d> in <%d> out <%d> len <%Zu>\n", - hdr.cmd, hdr.in, hdr.out, len); - if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table)) return -EINVAL; @@ -1232,8 +1254,6 @@ static int ib_ucm_open(struct inode *inode, struct file *filp) filp->private_data = file; file->filp = filp; - ucm_dbg("Created struct\n"); - return 0; } @@ -1281,7 +1301,7 @@ static int __init ib_ucm_init(void) result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm"); if (result) { - ucm_dbg("Error <%d> registering dev\n", result); + printk(KERN_ERR "ucm: Error <%d> registering dev\n", result); goto err_chr; } @@ -1289,14 +1309,14 @@ static int __init ib_ucm_init(void) result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1); if (result) { - ucm_dbg("Error <%d> adding cdev\n", result); + printk(KERN_ERR "ucm: Error <%d> adding cdev\n", result); goto err_cdev; } ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm"); if (IS_ERR(ib_ucm_class)) { result = PTR_ERR(ib_ucm_class); - ucm_dbg("Error <%d> creating class\n", result); + printk(KERN_ERR "Error <%d> creating class\n", result); goto err_class; } diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h deleted file mode 100644 index f46f37bc1201..000000000000 --- a/drivers/infiniband/core/ucm.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Intel Corporation. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: ucm.h 2208 2005-04-22 23:24:31Z libor $ - */ - -#ifndef UCM_H -#define UCM_H - -#include -#include -#include -#include - -#include -#include - -struct ib_ucm_file { - struct semaphore mutex; - struct file *filp; - - struct list_head ctxs; /* list of active connections */ - struct list_head events; /* list of pending events */ - wait_queue_head_t poll_wait; -}; - -struct ib_ucm_context { - int id; - wait_queue_head_t wait; - atomic_t ref; - int events_reported; - - struct ib_ucm_file *file; - struct ib_cm_id *cm_id; - __u64 uid; - - struct list_head events; /* list of pending events. */ - struct list_head file_list; /* member in file ctx list */ -}; - -struct ib_ucm_event { - struct ib_ucm_context *ctx; - struct list_head file_list; /* member in file event list */ - struct list_head ctx_list; /* member in ctx event list */ - - struct ib_cm_id *cm_id; - struct ib_ucm_event_resp resp; - void *data; - void *info; - int data_len; - int info_len; -}; - -#endif /* UCM_H */ From 07d357d0cbf89d9980b1769d5444a3c70f000e00 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 17 Oct 2005 15:37:43 -0700 Subject: [PATCH 0327/1940] [IB] CM: bind IDs to a specific device Bind communication identifiers to a device to support device removal. Export per HCA CM devices to userspace. Signed-off-by: Sean Hefty --- drivers/infiniband/core/cm.c | 41 +++++-- drivers/infiniband/core/ucm.c | 220 +++++++++++++++++++++++++--------- include/rdma/ib_cm.h | 10 +- include/rdma/ib_user_cm.h | 10 +- 4 files changed, 203 insertions(+), 78 deletions(-) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 54db6d4831f1..6f747debca90 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -366,9 +366,15 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) cur_cm_id_priv = rb_entry(parent, struct cm_id_private, service_node); if ((cur_cm_id_priv->id.service_mask & service_id) == - (service_mask & cur_cm_id_priv->id.service_id)) - return cm_id_priv; - if (service_id < cur_cm_id_priv->id.service_id) + (service_mask & cur_cm_id_priv->id.service_id) && + (cm_id_priv->id.device == cur_cm_id_priv->id.device)) + return cur_cm_id_priv; + + if (cm_id_priv->id.device < cur_cm_id_priv->id.device) + link = &(*link)->rb_left; + else if (cm_id_priv->id.device > cur_cm_id_priv->id.device) + link = &(*link)->rb_right; + else if (service_id < cur_cm_id_priv->id.service_id) link = &(*link)->rb_left; else link = &(*link)->rb_right; @@ -378,7 +384,8 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) return NULL; } -static struct cm_id_private * cm_find_listen(__be64 service_id) +static struct cm_id_private * cm_find_listen(struct ib_device *device, + __be64 service_id) { struct rb_node *node = cm.listen_service_table.rb_node; struct cm_id_private *cm_id_priv; @@ -386,9 +393,15 @@ static struct cm_id_private * cm_find_listen(__be64 service_id) while (node) { cm_id_priv = rb_entry(node, struct cm_id_private, service_node); if ((cm_id_priv->id.service_mask & service_id) == - (cm_id_priv->id.service_mask & cm_id_priv->id.service_id)) + cm_id_priv->id.service_id && + (cm_id_priv->id.device == device)) return cm_id_priv; - if (service_id < cm_id_priv->id.service_id) + + if (device < cm_id_priv->id.device) + node = node->rb_left; + else if (device > cm_id_priv->id.device) + node = node->rb_right; + else if (service_id < cm_id_priv->id.service_id) node = node->rb_left; else node = node->rb_right; @@ -523,7 +536,8 @@ static void cm_reject_sidr_req(struct cm_id_private *cm_id_priv, ib_send_cm_sidr_rep(&cm_id_priv->id, ¶m); } -struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, +struct ib_cm_id *ib_create_cm_id(struct ib_device *device, + ib_cm_handler cm_handler, void *context) { struct cm_id_private *cm_id_priv; @@ -535,6 +549,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, memset(cm_id_priv, 0, sizeof *cm_id_priv); cm_id_priv->id.state = IB_CM_IDLE; + cm_id_priv->id.device = device; cm_id_priv->id.cm_handler = cm_handler; cm_id_priv->id.context = context; cm_id_priv->id.remote_cm_qpn = 1; @@ -1047,7 +1062,6 @@ static void cm_format_req_event(struct cm_work *work, req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; param = &work->cm_event.param.req_rcvd; param->listen_id = listen_id; - param->device = cm_id_priv->av.port->mad_agent->device; param->port = cm_id_priv->av.port->port_num; param->primary_path = &work->path[0]; if (req_msg->alt_local_lid) @@ -1226,7 +1240,8 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, } /* Find matching listen request. */ - listen_cm_id_priv = cm_find_listen(req_msg->service_id); + listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device, + req_msg->service_id); if (!listen_cm_id_priv) { spin_unlock_irqrestore(&cm.lock, flags); cm_issue_rej(work->port, work->mad_recv_wc, @@ -1254,7 +1269,7 @@ static int cm_req_handler(struct cm_work *work) req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; - cm_id = ib_create_cm_id(NULL, NULL); + cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL); if (IS_ERR(cm_id)) return PTR_ERR(cm_id); @@ -2629,7 +2644,6 @@ static void cm_format_sidr_req_event(struct cm_work *work, param = &work->cm_event.param.sidr_req_rcvd; param->pkey = __be16_to_cpu(sidr_req_msg->pkey); param->listen_id = listen_id; - param->device = work->port->mad_agent->device; param->port = work->port->port_num; work->cm_event.private_data = &sidr_req_msg->private_data; } @@ -2642,7 +2656,7 @@ static int cm_sidr_req_handler(struct cm_work *work) struct ib_wc *wc; unsigned long flags; - cm_id = ib_create_cm_id(NULL, NULL); + cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL); if (IS_ERR(cm_id)) return PTR_ERR(cm_id); cm_id_priv = container_of(cm_id, struct cm_id_private, id); @@ -2666,7 +2680,8 @@ static int cm_sidr_req_handler(struct cm_work *work) spin_unlock_irqrestore(&cm.lock, flags); goto out; /* Duplicate message. */ } - cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id); + cur_cm_id_priv = cm_find_listen(cm_id->device, + sidr_req_msg->service_id); if (!cur_cm_id_priv) { rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); spin_unlock_irqrestore(&cm.lock, flags); diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index b7470f0fe83b..d208ea29e07a 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -52,12 +52,20 @@ MODULE_AUTHOR("Libor Michalek"); MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); MODULE_LICENSE("Dual BSD/GPL"); +struct ib_ucm_device { + int devnum; + struct cdev dev; + struct class_device class_dev; + struct ib_device *ib_dev; +}; + struct ib_ucm_file { struct semaphore mutex; struct file *filp; + struct ib_ucm_device *device; - struct list_head ctxs; /* list of active connections */ - struct list_head events; /* list of pending events */ + struct list_head ctxs; + struct list_head events; wait_queue_head_t poll_wait; }; @@ -90,14 +98,24 @@ struct ib_ucm_event { enum { IB_UCM_MAJOR = 231, - IB_UCM_MINOR = 255 + IB_UCM_BASE_MINOR = 224, + IB_UCM_MAX_DEVICES = 32 }; -#define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR) +#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR) -static struct semaphore ctx_id_mutex; -static struct idr ctx_id_table; +static void ib_ucm_add_one(struct ib_device *device); +static void ib_ucm_remove_one(struct ib_device *device); +static struct ib_client ucm_client = { + .name = "ucm", + .add = ib_ucm_add_one, + .remove = ib_ucm_remove_one +}; + +DECLARE_MUTEX(ctx_id_mutex); +DEFINE_IDR(ctx_id_table); +static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) { @@ -184,10 +202,7 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) kfree(ctx); return NULL; } -/* - * Event portion of the API, handle CM events - * and allow event polling. - */ + static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, struct ib_sa_path_rec *kpath) { @@ -234,6 +249,7 @@ static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, ureq->retry_count = kreq->retry_count; ureq->rnr_retry_count = kreq->rnr_retry_count; ureq->srq = kreq->srq; + ureq->port = kreq->port; ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path); ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path); @@ -320,6 +336,8 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, case IB_CM_SIDR_REQ_RECEIVED: uvt->resp.u.sidr_req_resp.pkey = evt->param.sidr_req_rcvd.pkey; + uvt->resp.u.sidr_req_resp.port = + evt->param.sidr_req_rcvd.port; uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; break; case IB_CM_SIDR_REP_RECEIVED: @@ -412,9 +430,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - /* - * wait - */ + down(&file->mutex); while (list_empty(&file->events)) { @@ -496,7 +512,6 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, return result; } - static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, const char __user *inbuf, int in_len, int out_len) @@ -519,29 +534,27 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, return -ENOMEM; ctx->uid = cmd.uid; - ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx); + ctx->cm_id = ib_create_cm_id(file->device->ib_dev, + ib_ucm_event_handler, ctx); if (IS_ERR(ctx->cm_id)) { result = PTR_ERR(ctx->cm_id); - goto err; + goto err1; } resp.id = ctx->id; if (copy_to_user((void __user *)(unsigned long)cmd.response, &resp, sizeof(resp))) { result = -EFAULT; - goto err; + goto err2; } - return 0; -err: +err2: + ib_destroy_cm_id(ctx->cm_id); +err1: down(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); up(&ctx_id_mutex); - - if (!IS_ERR(ctx->cm_id)) - ib_destroy_cm_id(ctx->cm_id); - kfree(ctx); return result; } @@ -1253,6 +1266,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp) filp->private_data = file; file->filp = filp; + file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev); return 0; } @@ -1283,7 +1297,17 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) return 0; } -static struct file_operations ib_ucm_fops = { +static void ib_ucm_release_class_dev(struct class_device *class_dev) +{ + struct ib_ucm_device *dev; + + dev = container_of(class_dev, struct ib_ucm_device, class_dev); + cdev_del(&dev->dev); + clear_bit(dev->devnum, dev_map); + kfree(dev); +} + +static struct file_operations ucm_fops = { .owner = THIS_MODULE, .open = ib_ucm_open, .release = ib_ucm_close, @@ -1291,55 +1315,141 @@ static struct file_operations ib_ucm_fops = { .poll = ib_ucm_poll, }; +static struct class ucm_class = { + .name = "infiniband_cm", + .release = ib_ucm_release_class_dev +}; -static struct class *ib_ucm_class; -static struct cdev ib_ucm_cdev; +static ssize_t show_dev(struct class_device *class_dev, char *buf) +{ + struct ib_ucm_device *dev; + + dev = container_of(class_dev, struct ib_ucm_device, class_dev); + return print_dev_t(buf, dev->dev.dev); +} +static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); + +static ssize_t show_ibdev(struct class_device *class_dev, char *buf) +{ + struct ib_ucm_device *dev; + + dev = container_of(class_dev, struct ib_ucm_device, class_dev); + return sprintf(buf, "%s\n", dev->ib_dev->name); +} +static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); + +static void ib_ucm_add_one(struct ib_device *device) +{ + struct ib_ucm_device *ucm_dev; + + if (!device->alloc_ucontext) + return; + + ucm_dev = kmalloc(sizeof *ucm_dev, GFP_KERNEL); + if (!ucm_dev) + return; + + memset(ucm_dev, 0, sizeof *ucm_dev); + ucm_dev->ib_dev = device; + + ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); + if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES) + goto err; + + set_bit(ucm_dev->devnum, dev_map); + + cdev_init(&ucm_dev->dev, &ucm_fops); + ucm_dev->dev.owner = THIS_MODULE; + kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum); + if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1)) + goto err; + + ucm_dev->class_dev.class = &ucm_class; + ucm_dev->class_dev.dev = device->dma_device; + snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", + ucm_dev->devnum); + if (class_device_register(&ucm_dev->class_dev)) + goto err_cdev; + + if (class_device_create_file(&ucm_dev->class_dev, + &class_device_attr_dev)) + goto err_class; + if (class_device_create_file(&ucm_dev->class_dev, + &class_device_attr_ibdev)) + goto err_class; + + ib_set_client_data(device, &ucm_client, ucm_dev); + return; + +err_class: + class_device_unregister(&ucm_dev->class_dev); +err_cdev: + cdev_del(&ucm_dev->dev); + clear_bit(ucm_dev->devnum, dev_map); +err: + kfree(ucm_dev); + return; +} + +static void ib_ucm_remove_one(struct ib_device *device) +{ + struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client); + + if (!ucm_dev) + return; + + class_device_unregister(&ucm_dev->class_dev); +} + +static ssize_t show_abi_version(struct class *class, char *buf) +{ + return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION); +} +static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); static int __init ib_ucm_init(void) { - int result; + int ret; - result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm"); - if (result) { - printk(KERN_ERR "ucm: Error <%d> registering dev\n", result); - goto err_chr; + ret = register_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES, + "infiniband_cm"); + if (ret) { + printk(KERN_ERR "ucm: couldn't register device number\n"); + goto err; } - cdev_init(&ib_ucm_cdev, &ib_ucm_fops); - - result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1); - if (result) { - printk(KERN_ERR "ucm: Error <%d> adding cdev\n", result); - goto err_cdev; + ret = class_register(&ucm_class); + if (ret) { + printk(KERN_ERR "ucm: couldn't create class infiniband_cm\n"); + goto err_chrdev; } - ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm"); - if (IS_ERR(ib_ucm_class)) { - result = PTR_ERR(ib_ucm_class); - printk(KERN_ERR "Error <%d> creating class\n", result); + ret = class_create_file(&ucm_class, &class_attr_abi_version); + if (ret) { + printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); goto err_class; } - class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm"); - - idr_init(&ctx_id_table); - init_MUTEX(&ctx_id_mutex); - + ret = ib_register_client(&ucm_client); + if (ret) { + printk(KERN_ERR "ucm: couldn't register client\n"); + goto err_class; + } return 0; + err_class: - cdev_del(&ib_ucm_cdev); -err_cdev: - unregister_chrdev_region(IB_UCM_DEV, 1); -err_chr: - return result; + class_unregister(&ucm_class); +err_chrdev: + unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); +err: + return ret; } static void __exit ib_ucm_cleanup(void) { - class_device_destroy(ib_ucm_class, IB_UCM_DEV); - class_destroy(ib_ucm_class); - cdev_del(&ib_ucm_cdev); - unregister_chrdev_region(IB_UCM_DEV, 1); + ib_unregister_client(&ucm_client); + class_unregister(&ucm_class); + unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); } module_init(ib_ucm_init); diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h index 5308683c8c41..0a9fcd59eb43 100644 --- a/include/rdma/ib_cm.h +++ b/include/rdma/ib_cm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Intel Corporation. All rights reserved. + * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. * Copyright (c) 2004 Topspin Corporation. All rights reserved. * Copyright (c) 2004 Voltaire Corporation. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. @@ -109,7 +109,6 @@ struct ib_cm_id; struct ib_cm_req_event_param { struct ib_cm_id *listen_id; - struct ib_device *device; u8 port; struct ib_sa_path_rec *primary_path; @@ -220,7 +219,6 @@ struct ib_cm_apr_event_param { struct ib_cm_sidr_req_event_param { struct ib_cm_id *listen_id; - struct ib_device *device; u8 port; u16 pkey; }; @@ -284,6 +282,7 @@ typedef int (*ib_cm_handler)(struct ib_cm_id *cm_id, struct ib_cm_id { ib_cm_handler cm_handler; void *context; + struct ib_device *device; __be64 service_id; __be64 service_mask; enum ib_cm_state state; /* internal CM/debug use */ @@ -295,6 +294,8 @@ struct ib_cm_id { /** * ib_create_cm_id - Allocate a communication identifier. + * @device: Device associated with the cm_id. All related communication will + * be associated with the specified device. * @cm_handler: Callback invoked to notify the user of CM events. * @context: User specified context associated with the communication * identifier. @@ -302,7 +303,8 @@ struct ib_cm_id { * Communication identifiers are used to track connection states, service * ID resolution requests, and listen requests. */ -struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, +struct ib_cm_id *ib_create_cm_id(struct ib_device *device, + ib_cm_handler cm_handler, void *context); /** diff --git a/include/rdma/ib_user_cm.h b/include/rdma/ib_user_cm.h index e4d1654276ad..3037588b8464 100644 --- a/include/rdma/ib_user_cm.h +++ b/include/rdma/ib_user_cm.h @@ -38,7 +38,7 @@ #include -#define IB_USER_CM_ABI_VERSION 2 +#define IB_USER_CM_ABI_VERSION 3 enum { IB_USER_CM_CMD_CREATE_ID, @@ -299,8 +299,6 @@ struct ib_ucm_event_get { }; struct ib_ucm_req_event_resp { - /* device */ - /* port */ struct ib_ucm_path_rec primary_path; struct ib_ucm_path_rec alternate_path; __be64 remote_ca_guid; @@ -316,6 +314,7 @@ struct ib_ucm_req_event_resp { __u8 retry_count; __u8 rnr_retry_count; __u8 srq; + __u8 port; }; struct ib_ucm_rep_event_resp { @@ -353,10 +352,9 @@ struct ib_ucm_apr_event_resp { }; struct ib_ucm_sidr_req_event_resp { - /* device */ - /* port */ __u16 pkey; - __u8 reserved[2]; + __u8 port; + __u8 reserved; }; struct ib_ucm_sidr_rep_event_resp { From 762a03e21ed08daa5170d9cd98e83539861e7692 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 17 Oct 2005 15:38:50 -0700 Subject: [PATCH 0328/1940] [IB] ucm: quiet sparse warnings Make ctx_id_mutex and ctx_id_table static to quiet sparse warnings. Signed-off-by: Roland Dreier --- drivers/infiniband/core/ucm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index d208ea29e07a..02ca642089bd 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -113,8 +113,8 @@ static struct ib_client ucm_client = { .remove = ib_ucm_remove_one }; -DECLARE_MUTEX(ctx_id_mutex); -DEFINE_IDR(ctx_id_table); +static DECLARE_MUTEX(ctx_id_mutex); +static DEFINE_IDR(ctx_id_table); static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) From 81e7009ea46c951860b8716ee427ff4f54dd26fc Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 18 Oct 2005 11:17:58 +1000 Subject: [PATCH 0329/1940] powerpc: merge ppc signal.c and ppc64 signal32.c Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 2 +- .../signal32.c => powerpc/kernel/signal_32.c} | 977 +++++++++++------- arch/ppc/kernel/Makefile | 4 +- arch/ppc/kernel/signal.c | 771 -------------- arch/ppc64/kernel/Makefile | 2 +- include/asm-ppc64/ppc32.h | 14 +- 6 files changed, 635 insertions(+), 1135 deletions(-) rename arch/{ppc64/kernel/signal32.c => powerpc/kernel/signal_32.c} (55%) delete mode 100644 arch/ppc/kernel/signal.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 1ca740bc5b47..043ddd09521d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -obj-y := semaphore.o cputable.o ptrace.o +obj-y := semaphore.o cputable.o ptrace.o signal_32.o obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o diff --git a/arch/ppc64/kernel/signal32.c b/arch/powerpc/kernel/signal_32.c similarity index 55% rename from arch/ppc64/kernel/signal32.c rename to arch/powerpc/kernel/signal_32.c index a8b7a5a56bb4..e53127ec373d 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1,56 +1,352 @@ /* - * signal32.c: Support 32bit signal syscalls. + * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Copyright (C) 2001 IBM * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) * - * These routines maintain argument size conversion between 32bit and 64bit - * environment. + * Derived from "arch/i386/kernel/signal.c" + * Copyright (C) 1991, 1992 Linus Torvalds + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * - * 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 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. */ #include #include -#include +#include #include #include #include #include -#include #include #include +#ifdef CONFIG_PPC64 +#include #include #include -#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif + #include +#include +#ifdef CONFIG_PPC64 +#include #include #include -#include #include +#else +#include +#include +#endif -#define DEBUG_SIG 0 +#undef DEBUG_SIG #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -#define GP_REGS_SIZE32 min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) +#ifdef CONFIG_PPC64 +#define do_signal do_signal32 +#define sys_sigsuspend sys32_sigsuspend +#define sys_rt_sigsuspend sys32_rt_sigsuspend +#define sys_rt_sigreturn sys32_rt_sigreturn +#define sys_sigaction sys32_sigaction +#define sys_swapcontext sys32_swapcontext +#define sys_sigreturn sys32_sigreturn + +#define old_sigaction old_sigaction32 +#define sigcontext sigcontext32 +#define mcontext mcontext32 +#define ucontext ucontext32 + +/* + * Returning 0 means we return to userspace via + * ret_from_except and thus restore all user + * registers from *regs. This is what we need + * to do when a signal has been delivered. + */ +#define sigreturn_exit(regs) return 0 + +#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) +#undef __SIGNAL_FRAMESIZE +#define __SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE32 +#undef ELF_NVRREG +#define ELF_NVRREG ELF_NVRREG32 + +/* + * Functions for flipping sigsets (thanks to brain dead generic + * implementation that makes things simple for little endian only) + */ +static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) +{ + compat_sigset_t cset; + + switch (_NSIG_WORDS) { + case 4: cset.sig[5] = set->sig[3] & 0xffffffffull; + cset.sig[7] = set->sig[3] >> 32; + case 3: cset.sig[4] = set->sig[2] & 0xffffffffull; + cset.sig[5] = set->sig[2] >> 32; + case 2: cset.sig[2] = set->sig[1] & 0xffffffffull; + cset.sig[3] = set->sig[1] >> 32; + case 1: cset.sig[0] = set->sig[0] & 0xffffffffull; + cset.sig[1] = set->sig[0] >> 32; + } + return copy_to_user(uset, &cset, sizeof(*uset)); +} + +static inline int get_sigset_t(sigset_t *set, compat_sigset_t __user *uset) +{ + compat_sigset_t s32; + + if (copy_from_user(&s32, uset, sizeof(*uset))) + return -EFAULT; + + /* + * Swap the 2 words of the 64-bit sigset_t (they are stored + * in the "wrong" endian in 32-bit user storage). + */ + switch (_NSIG_WORDS) { + case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); + case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); + case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); + case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); + } + return 0; +} + +static inline int get_old_sigaction(struct k_sigaction *new_ka, + struct old_sigaction __user *act) +{ + compat_old_sigset_t mask; + compat_uptr_t handler, restorer; + + if (get_user(handler, &act->sa_handler) || + __get_user(restorer, &act->sa_restorer) || + __get_user(new_ka->sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) + return -EFAULT; + new_ka->sa.sa_handler = compat_ptr(handler); + new_ka->sa.sa_restorer = compat_ptr(restorer); + siginitset(&new_ka->sa.sa_mask, mask); + return 0; +} + +static inline compat_uptr_t to_user_ptr(void *kp) +{ + return (compat_uptr_t)(u64)kp; +} + +#define from_user_ptr(p) compat_ptr(p) + +static inline int save_general_regs(struct pt_regs *regs, + struct mcontext __user *frame) +{ + elf_greg_t64 *gregs = (elf_greg_t64 *)regs; + int i; + + for (i = 0; i <= PT_RESULT; i ++) + if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) + return -EFAULT; + return 0; +} + +static inline int restore_general_regs(struct pt_regs *regs, + struct mcontext __user *sr) +{ + elf_greg_t64 *gregs = (elf_greg_t64 *)regs; + int i; + + for (i = 0; i <= PT_RESULT; i++) { + if ((i == PT_MSR) || (i == PT_SOFTE)) + continue; + if (__get_user(gregs[i], &sr->mc_gregs[i])) + return -EFAULT; + } + return 0; +} + +#else /* CONFIG_PPC64 */ + +extern void sigreturn_exit(struct pt_regs *); + +#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) + +static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) +{ + return copy_to_user(uset, set, sizeof(*uset)); +} + +static inline int get_sigset_t(sigset_t *set, sigset_t __user *uset) +{ + return copy_from_user(set, uset, sizeof(*uset)); +} + +static inline int get_old_sigaction(struct k_sigaction *new_ka, + struct old_sigaction __user *act) +{ + old_sigset_t mask; + + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka->sa.sa_handler, &act->sa_handler) || + __get_user(new_ka->sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka->sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka->sa.sa_mask, mask); + return 0; +} + +#define to_user_ptr(p) (p) +#define from_user_ptr(p) (p) + +static inline int save_general_regs(struct pt_regs *regs, + struct mcontext __user *frame) +{ + return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); +} + +static inline int restore_general_regs(struct pt_regs *regs, + struct mcontext __user *sr) +{ + /* copy up to but not including MSR */ + if (__copy_from_user(regs, &sr->mc_gregs, + PT_MSR * sizeof(elf_greg_t))) + return -EFAULT; + /* copy from orig_r3 (the word after the MSR) up to the end */ + if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3], + GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t))) + return -EFAULT; + return 0; +} + +#endif /* CONFIG_PPC64 */ + +int do_signal(sigset_t *oldset, struct pt_regs *regs); + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, + struct pt_regs *regs) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->result = -EINTR; + regs->gpr[3] = EINTR; + regs->ccr |= 0x10000000; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + sigreturn_exit(regs); + } +} + +long sys_rt_sigsuspend( +#ifdef CONFIG_PPC64 + compat_sigset_t __user *unewset, +#else + sigset_t __user *unewset, +#endif + size_t sigsetsize, int p3, int p4, + int p6, int p7, struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (get_sigset_t(&newset, unewset)) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->result = -EINTR; + regs->gpr[3] = EINTR; + regs->ccr |= 0x10000000; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + sigreturn_exit(regs); + } +} + +#ifdef CONFIG_PPC32 +long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5, + int r6, int r7, int r8, struct pt_regs *regs) +{ + return do_sigaltstack(uss, uoss, regs->gpr[1]); +} +#endif + +long sys_sigaction(int sig, struct old_sigaction __user *act, + struct old_sigaction __user *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + +#ifdef CONFIG_PPC64 + if (sig < 0) + sig = -sig; +#endif + + if (act) { + if (get_old_sigaction(&new_ka, act)) + return -EFAULT; + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(to_user_ptr(old_ka.sa.sa_handler), + &oact->sa_handler) || + __put_user(to_user_ptr(old_ka.sa.sa_restorer), + &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + return -EFAULT; + } + + return ret; +} /* * When we have signals to deliver, we set up on the * user stack, going down from the original stack pointer: - * a sigregs32 struct - * a sigcontext32 struct - * a gap of __SIGNAL_FRAMESIZE32 bytes + * a sigregs struct + * a sigcontext struct + * a gap of __SIGNAL_FRAMESIZE bytes * * Each of these things must be a multiple of 16 bytes in size. * */ -struct sigregs32 { - struct mcontext32 mctx; /* all the register values */ +struct sigregs { + struct mcontext mctx; /* all the register values */ /* * Programs using the rs6000/xcoff abi can save up to 19 gp * regs and 18 fp regs below sp before decrementing it. @@ -64,17 +360,21 @@ struct sigregs32 { /* * When we have rt signals to deliver, we set up on the * user stack, going down from the original stack pointer: - * one rt_sigframe32 struct (siginfo + ucontext + ABI gap) - * a gap of __SIGNAL_FRAMESIZE32+16 bytes - * (the +16 is to get the siginfo and ucontext32 in the same + * one rt_sigframe struct (siginfo + ucontext + ABI gap) + * a gap of __SIGNAL_FRAMESIZE+16 bytes + * (the +16 is to get the siginfo and ucontext in the same * positions as in older kernels). * * Each of these things must be a multiple of 16 bytes in size. * */ -struct rt_sigframe32 { - compat_siginfo_t info; - struct ucontext32 uc; +struct rt_sigframe { +#ifdef CONFIG_PPC64 + compat_siginfo_t info; +#else + struct siginfo info; +#endif + struct ucontext uc; /* * Programs using the rs6000/xcoff abi can save up to 19 gp * regs and 18 fp regs below sp before decrementing it. @@ -82,66 +382,24 @@ struct rt_sigframe32 { int abigap[56]; }; - -/* - * Common utility functions used by signal and context support - * - */ - -/* - * Restore the user process's signal mask - * (implemented in signal.c) - */ -extern void restore_sigmask(sigset_t *set); - -/* - * Functions for flipping sigsets (thanks to brain dead generic - * implementation that makes things simple for little endian only - */ -static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set) -{ - switch (_NSIG_WORDS) { - case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ; - compat->sig[7] = set->sig[3] >> 32; - case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ; - compat->sig[5] = set->sig[2] >> 32; - case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ; - compat->sig[3] = set->sig[1] >> 32; - case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ; - compat->sig[1] = set->sig[0] >> 32; - } -} - -static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat) -{ - switch (_NSIG_WORDS) { - case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32); - case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32); - case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32); - case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32); - } -} - - /* * Save the current user registers on the user stack. - * We only save the altivec registers if the process has used - * altivec instructions at some point. + * We only save the altivec/spe registers if the process has used + * altivec/spe instructions at some point. */ -static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret) +static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + int sigret) { - elf_greg_t64 *gregs = (elf_greg_t64 *)regs; - int i, err = 0; - +#ifdef CONFIG_PPC32 + CHECK_FULL_REGS(regs); +#endif /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); /* save general and floating-point registers */ - for (i = 0; i <= PT_RESULT; i ++) - err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]); - err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr, - ELF_NFPREG * sizeof(double)); - if (err) + if (save_general_regs(regs, frame) || + __copy_to_user(&frame->mc_fregs, current->thread.fpr, + ELF_NFPREG * sizeof(double))) return 1; current->thread.fpscr = 0; /* turn off all fp exceptions */ @@ -151,7 +409,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, if (current->thread.used_vr) { flush_altivec_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.vr, - ELF_NVRREG32 * sizeof(vector128))) + ELF_NVRREG * sizeof(vector128))) return 1; /* set MSR_VEC in the saved MSR value to indicate that frame->mc_vregs contains valid data */ @@ -169,6 +427,25 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, return 1; #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + /* save spe registers */ + if (current->thread.used_spe) { + flush_spe_to_thread(current); + if (__copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32))) + return 1; + /* set MSR_SPE in the saved MSR value to indicate that + frame->mc_vregs contains valid data */ + if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR])) + return 1; + } + /* else assert((regs->msr & MSR_SPE) == 0) */ + + /* We always copy to/from spefscr */ + if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) + return 1; +#endif /* CONFIG_SPE */ + if (sigret) { /* Set up the sigreturn trampoline: li r0,sigret; sc */ if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) @@ -186,13 +463,11 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, * (except for MSR). */ static long restore_user_regs(struct pt_regs *regs, - struct mcontext32 __user *sr, int sig) + struct mcontext __user *sr, int sig) { - elf_greg_t64 *gregs = (elf_greg_t64 *)regs; - int i; - long err = 0; + long err; unsigned int save_r2 = 0; -#ifdef CONFIG_ALTIVEC +#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) unsigned long msr; #endif @@ -202,11 +477,7 @@ static long restore_user_regs(struct pt_regs *regs, */ if (!sig) save_r2 = (unsigned int)regs->gpr[2]; - for (i = 0; i <= PT_RESULT; i++) { - if ((i == PT_MSR) || (i == PT_SOFTE)) - continue; - err |= __get_user(gregs[i], &sr->mc_gregs[i]); - } + err = restore_general_regs(regs, sr); if (!sig) regs->gpr[2] = (unsigned long) save_r2; if (err) @@ -229,135 +500,51 @@ static long restore_user_regs(struct pt_regs *regs, sizeof(sr->mc_vregs))) return 1; } else if (current->thread.used_vr) - memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128)); + memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); /* Always get VRSAVE back */ if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) return 1; #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + /* force the process to reload the spe registers from + current->thread when it next does spe instructions */ + regs->msr &= ~MSR_SPE; + if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { + /* restore spe registers from the stack */ + if (__copy_from_user(current->thread.evr, &sr->mc_vregs, + ELF_NEVRREG * sizeof(u32))) + return 1; + } else if (current->thread.used_spe) + memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); + + /* Always get SPEFSCR back */ + if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG)) + return 1; +#endif /* CONFIG_SPE */ + #ifndef CONFIG_SMP preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) last_task_used_altivec = NULL; +#ifdef CONFIG_SPE + if (last_task_used_spe == current) + last_task_used_spe = NULL; +#endif preempt_enable(); #endif return 0; } - -/* - * Start of nonRT signal support - * - * sigset_t is 32 bits for non-rt signals - * - * System Calls - * sigaction sys32_sigaction - * sigreturn sys32_sigreturn - * - * Note sigsuspend has no special 32 bit routine - uses the 64 bit routine - * - * Other routines - * setup_frame32 - */ - -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ -long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, - struct pt_regs *regs) -{ - sigset_t saveset; - - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal32(&saveset, regs)) - /* - * Returning 0 means we return to userspace via - * ret_from_except and thus restore all user - * registers from *regs. This is what we need - * to do when a signal has been delivered. - */ - return 0; - } -} - -long sys32_sigaction(int sig, struct old_sigaction32 __user *act, - struct old_sigaction32 __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (sig < 0) - sig = -sig; - - if (act) { - compat_old_sigset_t mask; - compat_uptr_t handler, restorer; - - if (get_user(handler, &act->sa_handler) || - __get_user(restorer, &act->sa_restorer) || - __get_user(new_ka.sa.sa_flags, &act->sa_flags) || - __get_user(mask, &act->sa_mask)) - return -EFAULT; - new_ka.sa.sa_handler = compat_ptr(handler); - new_ka.sa.sa_restorer = compat_ptr(restorer); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - if (!ret && oact) { - if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || - __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) - return -EFAULT; - } - - return ret; -} - - - -/* - * Start of RT signal support - * - * sigset_t is 64 bits for rt signals - * - * System Calls - * sigaction sys32_rt_sigaction - * sigpending sys32_rt_sigpending - * sigprocmask sys32_rt_sigprocmask - * sigreturn sys32_rt_sigreturn - * sigqueueinfo sys32_rt_sigqueueinfo - * sigsuspend sys32_rt_sigsuspend - * - * Other routines - * setup_rt_frame32 - * copy_siginfo_to_user32 - * siginfo32to64 - */ - - +#ifdef CONFIG_PPC64 long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact, size_t sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; - compat_sigset_t set32; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(compat_sigset_t)) @@ -368,9 +555,7 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, ret = get_user(handler, &act->sa_handler); new_ka.sa.sa_handler = compat_ptr(handler); - ret |= __copy_from_user(&set32, &act->sa_mask, - sizeof(compat_sigset_t)); - sigset_from_compat(&new_ka.sa.sa_mask, &set32); + ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask); ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); if (ret) return -EFAULT; @@ -378,10 +563,8 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - compat_from_sigset(&set32, &old_ka.sa.sa_mask); ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); - ret |= __copy_to_user(&oact->sa_mask, &set32, - sizeof(compat_sigset_t)); + ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); } return ret; @@ -399,27 +582,24 @@ long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, { sigset_t s; sigset_t __user *up; - compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { - if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) - return -EFAULT; - sigset_from_compat(&s, &s32); + if (get_sigset_t(&s, set)) + return -EFAULT; } - + set_fs(KERNEL_DS); /* This is valid because of the set_fs() */ up = (sigset_t __user *) &s; ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL, - sigsetsize); + sigsetsize); set_fs(old_fs); if (ret) return ret; if (oset) { - compat_from_sigset(&s32, &s); - if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) + if (put_sigset_t(oset, &s)) return -EFAULT; } return 0; @@ -428,7 +608,6 @@ long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) { sigset_t s; - compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); @@ -437,8 +616,7 @@ long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); set_fs(old_fs); if (!ret) { - compat_from_sigset(&s32, &s); - if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) + if (put_sigset_t(set, &s)) return -EFAULT; } return ret; @@ -500,6 +678,8 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) return err; } +#define copy_siginfo_to_user copy_siginfo_to_user32 + /* * Note: it is necessary to treat pid and sig as unsigned ints, with the * corresponding cast to a signed int to insure that the proper conversion @@ -512,7 +692,7 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) siginfo_t info; int ret; mm_segment_t old_fs = get_fs(); - + if (copy_from_user (&info, uinfo, 3*sizeof(int)) || copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32)) return -EFAULT; @@ -522,50 +702,6 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) set_fs (old_fs); return ret; } - -int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3, - int p4, int p6, int p7, struct pt_regs *regs) -{ - sigset_t saveset, newset; - compat_sigset_t s32; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&s32, unewset, sizeof(s32))) - return -EFAULT; - - /* - * Swap the 2 words of the 64-bit sigset_t (they are stored - * in the "wrong" endian in 32-bit user storage). - */ - sigset_from_compat(&newset, &s32); - - sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal32(&saveset, regs)) - /* - * Returning 0 means we return to userspace via - * ret_from_except and thus restore all user - * registers from *regs. This is what we need - * to do when a signal has been delivered. - */ - return 0; - } -} - /* * Start Alternate signal stack support * @@ -615,76 +751,95 @@ int sys32_sigaltstack(u32 __new, u32 __old, int r5, return -EFAULT; return ret; } +#endif /* CONFIG_PPC64 */ +/* + * Restore the user process's signal mask + */ +#ifdef CONFIG_PPC64 +extern void restore_sigmask(sigset_t *set); +#else /* CONFIG_PPC64 */ +static void restore_sigmask(sigset_t *set) +{ + sigdelsetmask(set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = *set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +} +#endif + /* * Set up a signal frame for a "real-time" signal handler * (one which gets siginfo). */ -static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs, unsigned long newsp) +static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, + struct pt_regs *regs, unsigned long newsp) { - struct rt_sigframe32 __user *rt_sf; - struct mcontext32 __user *frame; + struct rt_sigframe __user *rt_sf; + struct mcontext __user *frame; unsigned long origsp = newsp; - compat_sigset_t c_oldset; /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ newsp -= sizeof(*rt_sf); - rt_sf = (struct rt_sigframe32 __user *)newsp; + rt_sf = (struct rt_sigframe __user *)newsp; /* create a stack frame for the caller of the handler */ - newsp -= __SIGNAL_FRAMESIZE32 + 16; + newsp -= __SIGNAL_FRAMESIZE + 16; if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp)) goto badframe; - compat_from_sigset(&c_oldset, oldset); - /* Put the siginfo & fill in most of the ucontext */ - if (copy_siginfo_to_user32(&rt_sf->info, info) + if (copy_siginfo_to_user(&rt_sf->info, info) || __put_user(0, &rt_sf->uc.uc_flags) || __put_user(0, &rt_sf->uc.uc_link) || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) || __put_user(sas_ss_flags(regs->gpr[1]), &rt_sf->uc.uc_stack.ss_flags) || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) - || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) - || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset))) + || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), + &rt_sf->uc.uc_regs) + || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) goto badframe; /* Save user registers on the stack */ frame = &rt_sf->uc.uc_mcontext; - if (put_user(regs->gpr[1], (u32 __user *)newsp)) - goto badframe; - +#ifdef CONFIG_PPC64 if (vdso32_rt_sigtramp && current->thread.vdso_base) { if (save_user_regs(regs, frame, 0)) goto badframe; regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; - } else { + } else +#endif + { if (save_user_regs(regs, frame, __NR_rt_sigreturn)) goto badframe; regs->link = (unsigned long) frame->tramp; } - regs->gpr[1] = (unsigned long) newsp; + if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) + goto badframe; + regs->gpr[1] = newsp; regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) &rt_sf->info; regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; + regs->link = (unsigned long) frame->tramp; regs->trap = 0; +#ifdef CONFIG_PPC64 regs->result = 0; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); - +#endif return 1; badframe: -#if DEBUG_SIG +#ifdef DEBUG_SIG printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); #endif @@ -692,46 +847,50 @@ static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, return 0; } -static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig) +static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig) { - compat_sigset_t c_set; sigset_t set; - u32 mcp; + struct mcontext __user *mcp; - if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set)) - || __get_user(mcp, &ucp->uc_regs)) + if (get_sigset_t(&set, &ucp->uc_sigmask)) return -EFAULT; - sigset_from_compat(&set, &c_set); +#ifdef CONFIG_PPC64 + { + u32 cmcp; + + if (__get_user(cmcp, &ucp->uc_regs)) + return -EFAULT; + mcp = (struct mcontext __user *)(u64)cmcp; + } +#else + if (__get_user(mcp, &ucp->uc_regs)) + return -EFAULT; +#endif restore_sigmask(&set); - if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig)) + if (restore_user_regs(regs, mcp, sig)) return -EFAULT; return 0; } -/* - * Handle {get,set,swap}_context operations for 32 bits processes - */ - -long sys32_swapcontext(struct ucontext32 __user *old_ctx, - struct ucontext32 __user *new_ctx, +long sys_swapcontext(struct ucontext __user *old_ctx, + struct ucontext __user *new_ctx, int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) { unsigned char tmp; - compat_sigset_t c_set; /* Context size is for future use. Right now, we only make sure * we are passed something we understand */ - if (ctx_size < sizeof(struct ucontext32)) + if (ctx_size < sizeof(struct ucontext)) return -EINVAL; if (old_ctx != NULL) { - compat_from_sigset(&c_set, ¤t->blocked); if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) || save_user_regs(regs, &old_ctx->uc_mcontext, 0) - || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set)) - || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs)) + || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) + || __put_user(to_user_ptr(&old_ctx->uc_mcontext), + &old_ctx->uc_regs)) return -EFAULT; } if (new_ctx == NULL) @@ -752,27 +911,26 @@ long sys32_swapcontext(struct ucontext32 __user *old_ctx, * or if another thread unmaps the region containing the context. * We kill the task with a SIGSEGV in this situation. */ - if (do_setcontext32(new_ctx, regs, 0)) + if (do_setcontext(new_ctx, regs, 0)) do_exit(SIGSEGV); - + sigreturn_exit(regs); + /* doesn't actually return back to here */ return 0; } -long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, +long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, struct pt_regs *regs) { - struct rt_sigframe32 __user *rt_sf; - int ret; - + struct rt_sigframe __user *rt_sf; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - rt_sf = (struct rt_sigframe32 __user *) - (regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16); + rt_sf = (struct rt_sigframe __user *) + (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) goto bad; - if (do_setcontext32(&rt_sf->uc, regs, 1)) + if (do_setcontext(&rt_sf->uc, regs, 1)) goto bad; /* @@ -781,62 +939,165 @@ long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, * signal return. But other architectures do this and we have * always done it up until now so it is probably better not to * change it. -- paulus + */ +#ifdef CONFIG_PPC64 + /* * We use the sys32_ version that does the 32/64 bits conversion * and takes userland pointer directly. What about error checking ? * nobody does any... */ - sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); - - ret = regs->result; - - return ret; + sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); + return (int)regs->result; +#else + do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); + sigreturn_exit(regs); /* doesn't return here */ + return 0; +#endif bad: force_sig(SIGSEGV, current); return 0; } +#ifdef CONFIG_PPC32 +int sys_debug_setcontext(struct ucontext __user *ctx, + int ndbg, struct sig_dbg_op __user *dbg, + int r6, int r7, int r8, + struct pt_regs *regs) +{ + struct sig_dbg_op op; + int i; + unsigned long new_msr = regs->msr; +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + unsigned long new_dbcr0 = current->thread.dbcr0; +#endif + + for (i=0; imsr = new_msr; +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + current->thread.dbcr0 = new_dbcr0; +#endif + + /* + * If we get a fault copying the context into the kernel's + * image of the user's registers, we can't just return -EFAULT + * because the user's registers will be corrupted. For instance + * the NIP value may have been updated but not some of the + * other registers. Given that we have done the access_ok + * and successfully read the first and last bytes of the region + * above, this should only happen in an out-of-memory situation + * or if another thread unmaps the region containing the context. + * We kill the task with a SIGSEGV in this situation. + */ + if (do_setcontext(ctx, regs, 1)) { + force_sig(SIGSEGV, current); + goto out; + } + + /* + * It's not clear whether or why it is desirable to save the + * sigaltstack setting on signal delivery and restore it on + * signal return. But other architectures do this and we have + * always done it up until now so it is probably better not to + * change it. -- paulus + */ + do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); + + sigreturn_exit(regs); + /* doesn't actually return back to here */ + + out: + return 0; +} +#endif /* * OK, we're invoking a handler */ -static int handle_signal32(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs, unsigned long newsp) +static int handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, + unsigned long newsp) { - struct sigcontext32 __user *sc; - struct sigregs32 __user *frame; + struct sigcontext __user *sc; + struct sigregs __user *frame; unsigned long origsp = newsp; /* Set up Signal Frame */ - newsp -= sizeof(struct sigregs32); - frame = (struct sigregs32 __user *) newsp; + newsp -= sizeof(struct sigregs); + frame = (struct sigregs __user *) newsp; /* Put a sigcontext on the stack */ newsp -= sizeof(*sc); - sc = (struct sigcontext32 __user *) newsp; + sc = (struct sigcontext __user *) newsp; /* create a stack frame for the caller of the handler */ - newsp -= __SIGNAL_FRAMESIZE32; + newsp -= __SIGNAL_FRAMESIZE; if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) goto badframe; #if _NSIG != 64 -#error "Please adjust handle_signal32()" +#error "Please adjust handle_signal()" #endif - if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler) + if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler) || __put_user(oldset->sig[0], &sc->oldmask) +#ifdef CONFIG_PPC64 || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) - || __put_user((u32)(u64)frame, &sc->regs) +#else + || __put_user(oldset->sig[1], &sc->_unused[3]) +#endif + || __put_user(to_user_ptr(frame), &sc->regs) || __put_user(sig, &sc->signal)) goto badframe; +#ifdef CONFIG_PPC64 if (vdso32_sigtramp && current->thread.vdso_base) { if (save_user_regs(regs, &frame->mctx, 0)) goto badframe; regs->link = current->thread.vdso_base + vdso32_sigtramp; - } else { + } else +#endif + { if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) goto badframe; regs->link = (unsigned long) frame->mctx.tramp; @@ -844,22 +1105,24 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka, if (put_user(regs->gpr[1], (u32 __user *)newsp)) goto badframe; - regs->gpr[1] = (unsigned long) newsp; + regs->gpr[1] = newsp; regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) sc; regs->nip = (unsigned long) ka->sa.sa_handler; regs->trap = 0; +#ifdef CONFIG_PPC64 regs->result = 0; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); +#endif return 1; badframe: -#if DEBUG_SIG - printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n", - regs, frame, *newspp); +#ifdef DEBUG_SIG + printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n", + regs, frame, newsp); #endif force_sigsegv(sig, current); return 0; @@ -868,65 +1131,69 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka, /* * Do a signal return; undo the signal stack. */ -long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, +long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, struct pt_regs *regs) { - struct sigcontext32 __user *sc; - struct sigcontext32 sigctx; - struct mcontext32 __user *sr; + struct sigcontext __user *sc; + struct sigcontext sigctx; + struct mcontext __user *sr; sigset_t set; - int ret; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); + sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); if (copy_from_user(&sigctx, sc, sizeof(sigctx))) goto badframe; +#ifdef CONFIG_PPC64 /* * Note that PPC32 puts the upper 32 bits of the sigmask in the * unused part of the signal stackframe */ set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32); +#else + set.sig[0] = sigctx.oldmask; + set.sig[1] = sigctx._unused[3]; +#endif restore_sigmask(&set); - sr = (struct mcontext32 __user *)(u64)sigctx.regs; + sr = (struct mcontext __user *)from_user_ptr(sigctx.regs); if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) || restore_user_regs(regs, sr, 1)) goto badframe; - ret = regs->result; - return ret; +#ifdef CONFIG_PPC64 + return (int)regs->result; +#else + sigreturn_exit(regs); /* doesn't return */ + return 0; +#endif badframe: force_sig(SIGSEGV, current); return 0; } - - -/* - * Start of do_signal32 routine - * - * This routine gets control when a pending signal needs to be processed - * in the 32 bit target thread - - * - * It handles both rt and non-rt signals - */ - /* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ - -int do_signal32(sigset_t *oldset, struct pt_regs *regs) +int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; + struct k_sigaction ka; unsigned int frame, newsp; int signr, ret; - struct k_sigaction ka; + +#ifdef CONFIG_PPC32 + if (try_to_freeze()) { + signr = 0; + if (!signal_pending(current)) + goto no_signal; + } +#endif if (!oldset) oldset = ¤t->blocked; @@ -934,7 +1201,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) newsp = frame = 0; signr = get_signal_to_deliver(&info, &ka, regs, NULL); - +#ifdef CONFIG_PPC32 +no_signal: +#endif if (TRAP(regs) == 0x0C00 /* System Call! */ && regs->ccr & 0x10000000 /* error signalled */ && ((ret = regs->gpr[3]) == ERESTARTSYS @@ -964,12 +1233,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) return 0; /* no signals delivered */ if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size - && (!on_sig_stack(regs->gpr[1]))) - newsp = (current->sas_ss_sp + current->sas_ss_size); + && !on_sig_stack(regs->gpr[1])) + newsp = current->sas_ss_sp + current->sas_ss_size; else newsp = regs->gpr[1]; newsp &= ~0xfUL; +#ifdef CONFIG_PPC64 /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it @@ -977,12 +1247,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) */ if (current->thread.dabr) set_dabr(current->thread.dabr); +#endif /* Whee! Actually deliver the signal. */ if (ka.sa.sa_flags & SA_SIGINFO) - ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp); + ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp); else - ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); + ret = handle_signal(signr, &ka, &info, oldset, regs, newsp); if (ret) { spin_lock_irq(¤t->sighand->siglock); diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 87d3be4af820..c178397c50af 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -13,7 +13,7 @@ extra-$(CONFIG_POWER4) += idle_power4.o extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ - process.o signal.o align.o \ + process.o align.o \ syscalls.o setup.o \ ppc_htab.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o @@ -38,7 +38,7 @@ endif else obj-y := irq.o idle.o time.o \ - signal.o align.o perfmon.o + align.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c deleted file mode 100644 index 2244bf91e593..000000000000 --- a/arch/ppc/kernel/signal.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - * arch/ppc/kernel/signal.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/i386/kernel/signal.c" - * Copyright (C) 1991, 1992 Linus Torvalds - * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_SIG - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -extern void sigreturn_exit(struct pt_regs *); - -#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) - -int do_signal(sigset_t *oldset, struct pt_regs *regs); - -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ -int -sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, - struct pt_regs *regs) -{ - sigset_t saveset; - - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - sigreturn_exit(regs); - } -} - -int -sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4, - int p6, int p7, struct pt_regs *regs) -{ - sigset_t saveset, newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - sigreturn_exit(regs); - } -} - - -int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5, - int r6, int r7, int r8, struct pt_regs *regs) -{ - return do_sigaltstack(uss, uoss, regs->gpr[1]); -} - -int -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL)); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} - -/* - * When we have signals to deliver, we set up on the - * user stack, going down from the original stack pointer: - * a sigregs struct - * a sigcontext struct - * a gap of __SIGNAL_FRAMESIZE bytes - * - * Each of these things must be a multiple of 16 bytes in size. - * - */ -struct sigregs { - struct mcontext mctx; /* all the register values */ - /* Programs using the rs6000/xcoff abi can save up to 19 gp regs - and 18 fp regs below sp before decrementing it. */ - int abigap[56]; -}; - -/* We use the mc_pad field for the signal return trampoline. */ -#define tramp mc_pad - -/* - * When we have rt signals to deliver, we set up on the - * user stack, going down from the original stack pointer: - * one rt_sigframe struct (siginfo + ucontext + ABI gap) - * a gap of __SIGNAL_FRAMESIZE+16 bytes - * (the +16 is to get the siginfo and ucontext in the same - * positions as in older kernels). - * - * Each of these things must be a multiple of 16 bytes in size. - * - */ -struct rt_sigframe -{ - struct siginfo info; - struct ucontext uc; - /* Programs using the rs6000/xcoff abi can save up to 19 gp regs - and 18 fp regs below sp before decrementing it. */ - int abigap[56]; -}; - -/* - * Save the current user registers on the user stack. - * We only save the altivec/spe registers if the process has used - * altivec/spe instructions at some point. - */ -static int -save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret) -{ - /* save general and floating-point registers */ - CHECK_FULL_REGS(regs); - preempt_disable(); - if (regs->msr & MSR_FP) - giveup_fpu(current); -#ifdef CONFIG_ALTIVEC - if (current->thread.used_vr && (regs->msr & MSR_VEC)) - giveup_altivec(current); -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_SPE - if (current->thread.used_spe && (regs->msr & MSR_SPE)) - giveup_spe(current); -#endif /* CONFIG_ALTIVEC */ - preempt_enable(); - - if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE) - || __copy_to_user(&frame->mc_fregs, current->thread.fpr, - ELF_NFPREG * sizeof(double))) - return 1; - - current->thread.fpscr = 0; /* turn off all fp exceptions */ - -#ifdef CONFIG_ALTIVEC - /* save altivec registers */ - if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, current->thread.vr, - ELF_NVRREG * sizeof(vector128))) - return 1; - /* set MSR_VEC in the saved MSR value to indicate that - frame->mc_vregs contains valid data */ - if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR])) - return 1; - } - /* else assert((regs->msr & MSR_VEC) == 0) */ - - /* We always copy to/from vrsave, it's 0 if we don't have or don't - * use altivec. Since VSCR only contains 32 bits saved in the least - * significant bits of a vector, we "cheat" and stuff VRSAVE in the - * most significant bits of that same vector. --BenH - */ - if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) - return 1; -#endif /* CONFIG_ALTIVEC */ - -#ifdef CONFIG_SPE - /* save spe registers */ - if (current->thread.used_spe) { - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; - /* set MSR_SPE in the saved MSR value to indicate that - frame->mc_vregs contains valid data */ - if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR])) - return 1; - } - /* else assert((regs->msr & MSR_SPE) == 0) */ - - /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; -#endif /* CONFIG_SPE */ - - if (sigret) { - /* Set up the sigreturn trampoline: li r0,sigret; sc */ - if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) - || __put_user(0x44000002UL, &frame->tramp[1])) - return 1; - flush_icache_range((unsigned long) &frame->tramp[0], - (unsigned long) &frame->tramp[2]); - } - - return 0; -} - -/* - * Restore the current user register values from the user stack, - * (except for MSR). - */ -static int -restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig) -{ - unsigned long save_r2 = 0; -#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) - unsigned long msr; -#endif - - /* backup/restore the TLS as we don't want it to be modified */ - if (!sig) - save_r2 = regs->gpr[2]; - /* copy up to but not including MSR */ - if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t))) - return 1; - /* copy from orig_r3 (the word after the MSR) up to the end */ - if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3], - GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t))) - return 1; - if (!sig) - regs->gpr[2] = save_r2; - - /* force the process to reload the FP registers from - current->thread when it next does FP instructions */ - regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1); - if (__copy_from_user(current->thread.fpr, &sr->mc_fregs, - sizeof(sr->mc_fregs))) - return 1; - -#ifdef CONFIG_ALTIVEC - /* force the process to reload the altivec registers from - current->thread when it next does altivec instructions */ - regs->msr &= ~MSR_VEC; - if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) { - /* restore altivec registers from the stack */ - if (__copy_from_user(current->thread.vr, &sr->mc_vregs, - sizeof(sr->mc_vregs))) - return 1; - } else if (current->thread.used_vr) - memset(¤t->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); - - /* Always get VRSAVE back */ - if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) - return 1; -#endif /* CONFIG_ALTIVEC */ - -#ifdef CONFIG_SPE - /* force the process to reload the spe registers from - current->thread when it next does spe instructions */ - regs->msr &= ~MSR_SPE; - if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { - /* restore spe registers from the stack */ - if (__copy_from_user(current->thread.evr, &sr->mc_vregs, - ELF_NEVRREG * sizeof(u32))) - return 1; - } else if (current->thread.used_spe) - memset(¤t->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); - - /* Always get SPEFSCR back */ - if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG)) - return 1; -#endif /* CONFIG_SPE */ - -#ifndef CONFIG_SMP - preempt_disable(); - if (last_task_used_math == current) - last_task_used_math = NULL; - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; - if (last_task_used_spe == current) - last_task_used_spe = NULL; - preempt_enable(); -#endif - return 0; -} - -/* - * Restore the user process's signal mask - */ -static void -restore_sigmask(sigset_t *set) -{ - sigdelsetmask(set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = *set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); -} - -/* - * Set up a signal frame for a "real-time" signal handler - * (one which gets siginfo). - */ -static void -handle_rt_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, - unsigned long newsp) -{ - struct rt_sigframe __user *rt_sf; - struct mcontext __user *frame; - unsigned long origsp = newsp; - - /* Set up Signal Frame */ - /* Put a Real Time Context onto stack */ - newsp -= sizeof(*rt_sf); - rt_sf = (struct rt_sigframe __user *) newsp; - - /* create a stack frame for the caller of the handler */ - newsp -= __SIGNAL_FRAMESIZE + 16; - - if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) - goto badframe; - - /* Put the siginfo & fill in most of the ucontext */ - if (copy_siginfo_to_user(&rt_sf->info, info) - || __put_user(0, &rt_sf->uc.uc_flags) - || __put_user(0, &rt_sf->uc.uc_link) - || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) - || __put_user(sas_ss_flags(regs->gpr[1]), - &rt_sf->uc.uc_stack.ss_flags) - || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) - || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) - || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))) - goto badframe; - - /* Save user registers on the stack */ - frame = &rt_sf->uc.uc_mcontext; - if (save_user_regs(regs, frame, __NR_rt_sigreturn)) - goto badframe; - - if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) - goto badframe; - regs->gpr[1] = newsp; - regs->gpr[3] = sig; - regs->gpr[4] = (unsigned long) &rt_sf->info; - regs->gpr[5] = (unsigned long) &rt_sf->uc; - regs->gpr[6] = (unsigned long) rt_sf; - regs->nip = (unsigned long) ka->sa.sa_handler; - regs->link = (unsigned long) frame->tramp; - regs->trap = 0; - - return; - -badframe: -#ifdef DEBUG_SIG - printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", - regs, frame, newsp); -#endif - force_sigsegv(sig, current); -} - -static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig) -{ - sigset_t set; - struct mcontext __user *mcp; - - if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set)) - || __get_user(mcp, &ucp->uc_regs)) - return -EFAULT; - restore_sigmask(&set); - if (restore_user_regs(regs, mcp, sig)) - return -EFAULT; - - return 0; -} - -int sys_swapcontext(struct ucontext __user *old_ctx, - struct ucontext __user *new_ctx, - int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) -{ - unsigned char tmp; - - /* Context size is for future use. Right now, we only make sure - * we are passed something we understand - */ - if (ctx_size < sizeof(struct ucontext)) - return -EINVAL; - - if (old_ctx != NULL) { - if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) - || save_user_regs(regs, &old_ctx->uc_mcontext, 0) - || __copy_to_user(&old_ctx->uc_sigmask, - ¤t->blocked, sizeof(sigset_t)) - || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs)) - return -EFAULT; - } - if (new_ctx == NULL) - return 0; - if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx)) - || __get_user(tmp, (u8 __user *) new_ctx) - || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1)) - return -EFAULT; - - /* - * If we get a fault copying the context into the kernel's - * image of the user's registers, we can't just return -EFAULT - * because the user's registers will be corrupted. For instance - * the NIP value may have been updated but not some of the - * other registers. Given that we have done the access_ok - * and successfully read the first and last bytes of the region - * above, this should only happen in an out-of-memory situation - * or if another thread unmaps the region containing the context. - * We kill the task with a SIGSEGV in this situation. - */ - if (do_setcontext(new_ctx, regs, 0)) - do_exit(SIGSEGV); - sigreturn_exit(regs); - /* doesn't actually return back to here */ - return 0; -} - -int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, - struct pt_regs *regs) -{ - struct rt_sigframe __user *rt_sf; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - rt_sf = (struct rt_sigframe __user *) - (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); - if (!access_ok(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe))) - goto bad; - if (do_setcontext(&rt_sf->uc, regs, 1)) - goto bad; - - /* - * It's not clear whether or why it is desirable to save the - * sigaltstack setting on signal delivery and restore it on - * signal return. But other architectures do this and we have - * always done it up until now so it is probably better not to - * change it. -- paulus - */ - do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); - - sigreturn_exit(regs); /* doesn't return here */ - return 0; - - bad: - force_sig(SIGSEGV, current); - return 0; -} - -int sys_debug_setcontext(struct ucontext __user *ctx, - int ndbg, struct sig_dbg_op __user *dbg, - int r6, int r7, int r8, - struct pt_regs *regs) -{ - struct sig_dbg_op op; - int i; - unsigned long new_msr = regs->msr; -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - unsigned long new_dbcr0 = current->thread.dbcr0; -#endif - - for (i=0; imsr = new_msr; -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - current->thread.dbcr0 = new_dbcr0; -#endif - - /* - * If we get a fault copying the context into the kernel's - * image of the user's registers, we can't just return -EFAULT - * because the user's registers will be corrupted. For instance - * the NIP value may have been updated but not some of the - * other registers. Given that we have done the access_ok - * and successfully read the first and last bytes of the region - * above, this should only happen in an out-of-memory situation - * or if another thread unmaps the region containing the context. - * We kill the task with a SIGSEGV in this situation. - */ - if (do_setcontext(ctx, regs, 1)) { - force_sig(SIGSEGV, current); - goto out; - } - - /* - * It's not clear whether or why it is desirable to save the - * sigaltstack setting on signal delivery and restore it on - * signal return. But other architectures do this and we have - * always done it up until now so it is probably better not to - * change it. -- paulus - */ - do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); - - sigreturn_exit(regs); - /* doesn't actually return back to here */ - - out: - return 0; -} - -/* - * OK, we're invoking a handler - */ -static void -handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, - unsigned long newsp) -{ - struct sigcontext __user *sc; - struct sigregs __user *frame; - unsigned long origsp = newsp; - - /* Set up Signal Frame */ - newsp -= sizeof(struct sigregs); - frame = (struct sigregs __user *) newsp; - - /* Put a sigcontext on the stack */ - newsp -= sizeof(*sc); - sc = (struct sigcontext __user *) newsp; - - /* create a stack frame for the caller of the handler */ - newsp -= __SIGNAL_FRAMESIZE; - - if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) - goto badframe; - -#if _NSIG != 64 -#error "Please adjust handle_signal()" -#endif - if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) - || __put_user(oldset->sig[0], &sc->oldmask) - || __put_user(oldset->sig[1], &sc->_unused[3]) - || __put_user((struct pt_regs __user *)frame, &sc->regs) - || __put_user(sig, &sc->signal)) - goto badframe; - - if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) - goto badframe; - - if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) - goto badframe; - regs->gpr[1] = newsp; - regs->gpr[3] = sig; - regs->gpr[4] = (unsigned long) sc; - regs->nip = (unsigned long) ka->sa.sa_handler; - regs->link = (unsigned long) frame->mctx.tramp; - regs->trap = 0; - - return; - -badframe: -#ifdef DEBUG_SIG - printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n", - regs, frame, newsp); -#endif - force_sigsegv(sig, current); -} - -/* - * Do a signal return; undo the signal stack. - */ -int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, - struct pt_regs *regs) -{ - struct sigcontext __user *sc; - struct sigcontext sigctx; - struct mcontext __user *sr; - sigset_t set; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); - if (copy_from_user(&sigctx, sc, sizeof(sigctx))) - goto badframe; - - set.sig[0] = sigctx.oldmask; - set.sig[1] = sigctx._unused[3]; - restore_sigmask(&set); - - sr = (struct mcontext __user *) sigctx.regs; - if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) - || restore_user_regs(regs, sr, 1)) - goto badframe; - - sigreturn_exit(regs); /* doesn't return */ - return 0; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - */ -int do_signal(sigset_t *oldset, struct pt_regs *regs) -{ - siginfo_t info; - struct k_sigaction ka; - unsigned long frame, newsp; - int signr, ret; - - if (try_to_freeze()) { - signr = 0; - if (!signal_pending(current)) - goto no_signal; - } - - if (!oldset) - oldset = ¤t->blocked; - - newsp = frame = 0; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - no_signal: - if (TRAP(regs) == 0x0C00 /* System Call! */ - && regs->ccr & 0x10000000 /* error signalled */ - && ((ret = regs->gpr[3]) == ERESTARTSYS - || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR - || ret == ERESTART_RESTARTBLOCK)) { - - if (signr > 0 - && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK - || (ret == ERESTARTSYS - && !(ka.sa.sa_flags & SA_RESTART)))) { - /* make the system call return an EINTR error */ - regs->result = -EINTR; - regs->gpr[3] = EINTR; - /* note that the cr0.SO bit is already set */ - } else { - regs->nip -= 4; /* Back up & retry system call */ - regs->result = 0; - regs->trap = 0; - if (ret == ERESTART_RESTARTBLOCK) - regs->gpr[0] = __NR_restart_syscall; - else - regs->gpr[3] = regs->orig_gpr3; - } - } - - if (signr == 0) - return 0; /* no signals delivered */ - - if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size - && !on_sig_stack(regs->gpr[1])) - newsp = current->sas_ss_sp + current->sas_ss_size; - else - newsp = regs->gpr[1]; - newsp &= ~0xfUL; - - /* Whee! Actually deliver the signal. */ - if (ka.sa.sa_flags & SA_SIGINFO) - handle_rt_signal(signr, &ka, &info, oldset, regs, newsp); - else - handle_signal(signr, &ka, &info, oldset, regs, newsp); - - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); - if (!(ka.sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, signr); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - return 1; -} - diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 0be7c7ecefdf..19846d78b329 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -15,7 +15,7 @@ obj-y += irq.o idle.o dma.o \ time.o signal.o \ align.o bitops.o pacaData.o \ udbg.o ioctl32.o \ - ptrace32.o signal32.o rtc.o \ + ptrace32.o rtc.o \ cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o obj-y += vdso32/ vdso64/ diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h index 6b44a8caf395..3945a55d112a 100644 --- a/include/asm-ppc64/ppc32.h +++ b/include/asm-ppc64/ppc32.h @@ -70,18 +70,18 @@ typedef struct compat_siginfo { #define __old_sigaction32 old_sigaction32 struct __old_sigaction32 { - unsigned sa_handler; + compat_uptr_t sa_handler; compat_old_sigset_t sa_mask; unsigned int sa_flags; - unsigned sa_restorer; /* not used by Linux/SPARC yet */ + compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ }; struct sigaction32 { - unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ + compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ unsigned int sa_flags; - unsigned int sa_restorer; /* Another 32 bit pointer */ + compat_uptr_t sa_restorer; /* Another 32 bit pointer */ compat_sigset_t sa_mask; /* A 32 bit mask */ }; @@ -94,9 +94,9 @@ typedef struct sigaltstack_32 { struct sigcontext32 { unsigned int _unused[4]; int signal; - unsigned int handler; + compat_uptr_t handler; unsigned int oldmask; - u32 regs; /* 4 byte pointer to the pt_regs32 structure. */ + compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ }; struct mcontext32 { @@ -111,7 +111,7 @@ struct ucontext32 { unsigned int uc_link; stack_32_t uc_stack; int uc_pad[7]; - u32 uc_regs; /* points to uc_mcontext field */ + compat_uptr_t uc_regs; /* points to uc_mcontext field */ compat_sigset_t uc_sigmask; /* mask last for extensibility */ /* glibc has 1024-bit signal masks, ours are 64-bit */ int uc_maskext[30]; From 77f543cb467c44960bafa6c91f5af75919d693e4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 18 Oct 2005 14:19:41 +1000 Subject: [PATCH 0330/1940] powerpc: Fix various compile errors with ARCH=ppc, ppc64 and powerpc This makes ppc use the syscalls.c from arch/powerpc/kernel, exports copy_and_flush from head_32.S for use by prom_init.c (ARCH=powerpc), and consolidates the sys_fadvise64_64 implementations for 32-bit. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 1 - arch/powerpc/kernel/Makefile | 10 +++++----- arch/powerpc/kernel/head_32.S | 2 +- arch/powerpc/kernel/sys_ppc32.c | 7 ------- arch/powerpc/kernel/syscalls.c | 7 +++++++ arch/powerpc/kernel/systbl.S | 2 +- arch/ppc/kernel/Makefile | 2 +- arch/ppc64/kernel/misc.S | 2 +- 8 files changed, 16 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index a5f2eb5f89ce..29cda0732703 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -121,7 +121,6 @@ head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o -head-$(CONFIG_6xx) += arch/powerpc/kernel/idle_6xx.o head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 043ddd09521d..01b6d630edc9 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -10,7 +10,8 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -obj-y := semaphore.o cputable.o ptrace.o signal_32.o +obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ + signal_32.o obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o @@ -24,14 +25,13 @@ extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o -extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_PPC64) += entry_64.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y += process.o init_task.o \ - prom.o systbl.o traps.o syscalls.o -obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o + prom.o systbl.o traps.o +obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o @@ -44,7 +44,7 @@ endif else # stuff used from here for ARCH=ppc or ARCH=ppc64 -obj-$(CONFIG_PPC64) += traps.o process.o init_task.o syscalls.o +obj-$(CONFIG_PPC64) += traps.o process.o init_task.o fpux-$(CONFIG_PPC32) += fpu.o extra-$(CONFIG_PPC_FPU) += $(fpux-y) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 7ef9a3e3002b..cd51fe585fcd 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -831,7 +831,7 @@ relocate_kernel: * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. */ -copy_and_flush: +_GLOBAL(copy_and_flush) addi r5,r5,-4 addi r6,r6,-4 4: li r0,L1_CACHE_BYTES/4 diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 9babe055356e..2f1e41a82876 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -1069,13 +1069,6 @@ long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, advice); } -long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, - u32 len_high, u32 len_low) -{ - return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, - (u64)len_high << 32 | len_low, advice); -} - long ppc32_timer_create(clockid_t clock, struct compat_sigevent __user *ev32, timer_t __user *timer_id) diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 3e3a4f67de96..7a23721365a6 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -336,6 +336,13 @@ time_t sys64_time(time_t __user * tloc) } #endif +long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, + u32 len_high, u32 len_low) +{ + return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, + (u64)len_high << 32 | len_low, advice); +} + void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, struct pt_regs *regs) diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index b364141ec01c..1b807f79d5da 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -297,7 +297,7 @@ SYSCALL32(tgkill) SYSCALL32(utimes) COMPAT_SYS(statfs64) COMPAT_SYS(fstatfs64) -SYSX(sys_ni_syscall, ppc32_fadvise64_64, sys_fadvise64_64) +SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) PPC_SYS(rtas) OLDSYS(debug_setcontext) SYSCALL(ni_syscall) diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index c178397c50af..5a742c7b0509 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -14,7 +14,7 @@ extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o align.o \ - syscalls.o setup.o \ + setup.o \ ppc_htab.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index eb407c429bb0..755d73f222e2 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -1175,7 +1175,7 @@ _GLOBAL(sys_call_table32) .llong .sys32_utimes .llong .compat_sys_statfs64 .llong .compat_sys_fstatfs64 - .llong .ppc32_fadvise64_64 /* 32bit only fadvise64_64 */ + .llong .ppc_fadvise64_64 /* 32bit only fadvise64_64 */ .llong .ppc_rtas /* 255 */ .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */ .llong .sys_ni_syscall /* 257 reserved for vserver */ From b09a4913b15d2544f8918f05b9937cb4e99a2319 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 18 Oct 2005 14:51:57 +1000 Subject: [PATCH 0331/1940] powerpc: change sys32_ to compat_sys_ This allows us to get rid of one type of entry in systbl.S. In passing we remove the duplicate compat_sys_getdents and compat_sys_utimes for which there are generic versions. Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/entry_64.S | 10 +- arch/powerpc/kernel/signal_32.c | 28 ++--- arch/powerpc/kernel/sys_ppc32.c | 216 ++++++++------------------------ arch/powerpc/kernel/systbl.S | 116 +++++++++-------- arch/ppc64/kernel/entry.S | 10 +- arch/ppc64/kernel/misc.S | 122 +++++++++--------- arch/ppc64/kernel/ptrace32.c | 2 +- 7 files changed, 195 insertions(+), 309 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 22796e28881a..984a10630714 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -262,7 +262,7 @@ _GLOBAL(save_nvgprs) */ _GLOBAL(ppc32_sigsuspend) bl .save_nvgprs - bl .sys32_sigsuspend + bl .compat_sys_sigsuspend b 70f _GLOBAL(ppc64_rt_sigsuspend) @@ -272,7 +272,7 @@ _GLOBAL(ppc64_rt_sigsuspend) _GLOBAL(ppc32_rt_sigsuspend) bl .save_nvgprs - bl .sys32_rt_sigsuspend + bl .compat_sys_rt_sigsuspend 70: cmpdi 0,r3,0 /* If it returned an error, we need to return via syscall_exit to set the SO bit in cr0 and potentially stop for ptrace. */ @@ -307,7 +307,7 @@ _GLOBAL(ppc_clone) _GLOBAL(ppc32_swapcontext) bl .save_nvgprs - bl .sys32_swapcontext + bl .compat_sys_swapcontext b 80f _GLOBAL(ppc64_swapcontext) @@ -316,11 +316,11 @@ _GLOBAL(ppc64_swapcontext) b 80f _GLOBAL(ppc32_sigreturn) - bl .sys32_sigreturn + bl .compat_sys_sigreturn b 80f _GLOBAL(ppc32_rt_sigreturn) - bl .sys32_rt_sigreturn + bl .compat_sys_rt_sigreturn b 80f _GLOBAL(ppc64_rt_sigreturn) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index e53127ec373d..e7e7aac11f89 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -58,12 +58,12 @@ #ifdef CONFIG_PPC64 #define do_signal do_signal32 -#define sys_sigsuspend sys32_sigsuspend -#define sys_rt_sigsuspend sys32_rt_sigsuspend -#define sys_rt_sigreturn sys32_rt_sigreturn -#define sys_sigaction sys32_sigaction -#define sys_swapcontext sys32_swapcontext -#define sys_sigreturn sys32_sigreturn +#define sys_sigsuspend compat_sys_sigsuspend +#define sys_rt_sigsuspend compat_sys_rt_sigsuspend +#define sys_rt_sigreturn compat_sys_rt_sigreturn +#define sys_sigaction compat_sys_sigaction +#define sys_swapcontext compat_sys_swapcontext +#define sys_sigreturn compat_sys_sigreturn #define old_sigaction old_sigaction32 #define sigcontext sigcontext32 @@ -540,7 +540,7 @@ static long restore_user_regs(struct pt_regs *regs, } #ifdef CONFIG_PPC64 -long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, +long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact, size_t sigsetsize) { struct k_sigaction new_ka, old_ka; @@ -577,7 +577,7 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, * of a signed int (msr in 32-bit mode) and the register representation * of a signed int (msr in 64-bit mode) is performed. */ -long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, +long compat_sys_rt_sigprocmask(u32 how, compat_sigset_t __user *set, compat_sigset_t __user *oset, size_t sigsetsize) { sigset_t s; @@ -605,7 +605,7 @@ long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, return 0; } -long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) +long compat_sys_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) { sigset_t s; int ret; @@ -687,7 +687,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) * (msr in 32-bit mode) and the register representation of a signed int * (msr in 64-bit mode) is performed. */ -long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) +long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) { siginfo_t info; int ret; @@ -706,10 +706,10 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) * Start Alternate signal stack support * * System Calls - * sigaltatck sys32_sigaltstack + * sigaltatck compat_sys_sigaltstack */ -int sys32_sigaltstack(u32 __new, u32 __old, int r5, +int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, int r6, int r7, int r8, struct pt_regs *regs) { stack_32_t __user * newstack = (stack_32_t __user *)(long) __new; @@ -942,11 +942,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, */ #ifdef CONFIG_PPC64 /* - * We use the sys32_ version that does the 32/64 bits conversion + * We use the compat_sys_ version that does the 32/64 bits conversion * and takes userland pointer directly. What about error checking ? * nobody does any... */ - sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); + compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); return (int)regs->result; #else do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 9babe055356e..501333f89d23 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -113,96 +113,6 @@ asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user * return error; } -struct linux_dirent32 { - u32 d_ino; - u32 d_off; - unsigned short d_reclen; - char d_name[1]; -}; - -struct getdents_callback32 { - struct linux_dirent32 __user * current_dir; - struct linux_dirent32 __user * previous; - int count; - int error; -}; - -static int filldir(void * __buf, const char * name, int namlen, off_t offset, - ino_t ino, unsigned int d_type) -{ - struct linux_dirent32 __user * dirent; - struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); - - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - dirent = buf->previous; - if (dirent) { - if (__put_user(offset, &dirent->d_off)) - goto efault; - } - dirent = buf->current_dir; - if (__put_user(ino, &dirent->d_ino)) - goto efault; - if (__put_user(reclen, &dirent->d_reclen)) - goto efault; - if (copy_to_user(dirent->d_name, name, namlen)) - goto efault; - if (__put_user(0, dirent->d_name + namlen)) - goto efault; - if (__put_user(d_type, (char __user *) dirent + reclen - 1)) - goto efault; - buf->previous = dirent; - dirent = (void __user *)dirent + reclen; - buf->current_dir = dirent; - buf->count -= reclen; - return 0; -efault: - buf->error = -EFAULT; - return -EFAULT; -} - -asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent, - unsigned int count) -{ - struct file * file; - struct linux_dirent32 __user * lastdirent; - struct getdents_callback32 buf; - int error; - - error = -EFAULT; - if (!access_ok(VERIFY_WRITE, dirent, count)) - goto out; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.current_dir = dirent; - buf.previous = NULL; - buf.count = count; - buf.error = 0; - - error = vfs_readdir(file, (filldir_t)filldir, &buf); - if (error < 0) - goto out_putf; - error = buf.error; - lastdirent = buf.previous; - if (lastdirent) { - if (put_user(file->f_pos, &lastdirent->d_off)) - error = -EFAULT; - else - error = count - buf.count; - } - -out_putf: - fput(file); -out: - return error; -} - asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, compat_uptr_t tvp_x) @@ -247,7 +157,7 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2) +asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2) { return sys_sysfs((int)option, arg1, arg2); } @@ -269,7 +179,7 @@ struct timex32 { extern int do_adjtimex(struct timex *); extern void ppc_adjtimex(void); -asmlinkage long sys32_adjtimex(struct timex32 __user *utp) +asmlinkage long compat_sys_adjtimex(struct timex32 __user *utp) { struct timex txc; int ret; @@ -328,7 +238,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp) return ret; } -asmlinkage long sys32_pause(void) +asmlinkage long compat_sys_pause(void) { current->state = TASK_INTERRUPTIBLE; schedule(); @@ -374,7 +284,7 @@ struct sysinfo32 { char _f[20-2*sizeof(int)-sizeof(int)]; }; -asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) +asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info) { struct sysinfo s; int ret, err; @@ -431,7 +341,7 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) sorts of things, like timeval and itimerval. */ extern struct timezone sys_tz; -asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { if (tv) { struct timeval ktv; @@ -449,7 +359,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct time -asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { struct timespec kts; struct timezone ktz; @@ -467,7 +377,7 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct time } #ifdef CONFIG_SYSVIPC -long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, +long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth) { int version; @@ -538,7 +448,7 @@ long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) +asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -560,7 +470,7 @@ asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offs return ret; } -asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) +asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -582,7 +492,7 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *off return ret; } -long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2, +long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs *regs) { @@ -614,7 +524,7 @@ long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2, * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) +asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) { return sys_prctl((int)option, (unsigned long) arg2, @@ -628,7 +538,7 @@ asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) +asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) { struct timespec t; int ret; @@ -643,7 +553,7 @@ asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __us return ret; } -asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) +asmlinkage int compat_sys_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) { return sys_pciconfig_read((unsigned long) bus, (unsigned long) dfn, @@ -652,7 +562,7 @@ asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf compat_ptr(ubuf)); } -asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) +asmlinkage int compat_sys_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) { return sys_pciconfig_write((unsigned long) bus, (unsigned long) dfn, @@ -661,7 +571,7 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu compat_ptr(ubuf)); } -asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) +asmlinkage int compat_sys_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) { return sys_pciconfig_iobase(which, in_bus, in_devfn); } @@ -672,7 +582,7 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_access(const char __user * filename, u32 mode) +asmlinkage long compat_sys_access(const char __user * filename, u32 mode) { return sys_access(filename, (int)mode); } @@ -683,7 +593,7 @@ asmlinkage long sys32_access(const char __user * filename, u32 mode) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_creat(const char __user * pathname, u32 mode) +asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode) { return sys_creat(pathname, (int)mode); } @@ -694,7 +604,7 @@ asmlinkage long sys32_creat(const char __user * pathname, u32 mode) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options) +asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options) { return sys_waitpid((int)pid, stat_addr, (int)options); } @@ -705,7 +615,7 @@ asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 opti * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist) +asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist) { return sys_getgroups((int)gidsetsize, grouplist); } @@ -716,7 +626,7 @@ asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_getpgid(u32 pid) +asmlinkage long compat_sys_getpgid(u32 pid) { return sys_getpgid((int)pid); } @@ -728,7 +638,7 @@ asmlinkage long sys32_getpgid(u32 pid) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_getsid(u32 pid) +asmlinkage long compat_sys_getsid(u32 pid) { return sys_getsid((int)pid); } @@ -739,7 +649,7 @@ asmlinkage long sys32_getsid(u32 pid) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_kill(u32 pid, u32 sig) +asmlinkage long compat_sys_kill(u32 pid, u32 sig) { return sys_kill((int)pid, (int)sig); } @@ -750,12 +660,12 @@ asmlinkage long sys32_kill(u32 pid, u32 sig) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_mkdir(const char __user * pathname, u32 mode) +asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode) { return sys_mkdir(pathname, (int)mode); } -long sys32_nice(u32 increment) +long compat_sys_nice(u32 increment) { /* sign extend increment */ return sys_nice((int)increment); @@ -772,7 +682,7 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 bufsiz) +asmlinkage long compat_sys_readlink(const char __user * path, char __user * buf, u32 bufsiz) { return sys_readlink(path, buf, (int)bufsiz); } @@ -782,7 +692,7 @@ asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_get_priority_max(u32 policy) +asmlinkage long compat_sys_sched_get_priority_max(u32 policy) { return sys_sched_get_priority_max((int)policy); } @@ -793,7 +703,7 @@ asmlinkage long sys32_sched_get_priority_max(u32 policy) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_get_priority_min(u32 policy) +asmlinkage long compat_sys_sched_get_priority_min(u32 policy) { return sys_sched_get_priority_min((int)policy); } @@ -804,7 +714,7 @@ asmlinkage long sys32_sched_get_priority_min(u32 policy) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param) +asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param) { return sys_sched_getparam((int)pid, param); } @@ -815,7 +725,7 @@ asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_getscheduler(u32 pid) +asmlinkage long compat_sys_sched_getscheduler(u32 pid) { return sys_sched_getscheduler((int)pid); } @@ -826,7 +736,7 @@ asmlinkage long sys32_sched_getscheduler(u32 pid) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param) +asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param) { return sys_sched_setparam((int)pid, param); } @@ -837,7 +747,7 @@ asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param) +asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param) { return sys_sched_setscheduler((int)pid, (int)policy, param); } @@ -848,7 +758,7 @@ asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_setdomainname(char __user *name, u32 len) +asmlinkage long compat_sys_setdomainname(char __user *name, u32 len) { return sys_setdomainname(name, (int)len); } @@ -859,13 +769,13 @@ asmlinkage long sys32_setdomainname(char __user *name, u32 len) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t __user *grouplist) +asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist) { return sys_setgroups((int)gidsetsize, grouplist); } -asmlinkage long sys32_sethostname(char __user *name, u32 len) +asmlinkage long compat_sys_sethostname(char __user *name, u32 len) { /* sign extend len */ return sys_sethostname(name, (int)len); @@ -877,30 +787,30 @@ asmlinkage long sys32_sethostname(char __user *name, u32 len) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_setpgid(u32 pid, u32 pgid) +asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid) { return sys_setpgid((int)pid, (int)pgid); } -long sys32_getpriority(u32 which, u32 who) +long compat_sys_getpriority(u32 which, u32 who) { /* sign extend which and who */ return sys_getpriority((int)which, (int)who); } -long sys32_setpriority(u32 which, u32 who, u32 niceval) +long compat_sys_setpriority(u32 which, u32 who, u32 niceval) { /* sign extend which, who and niceval */ return sys_setpriority((int)which, (int)who, (int)niceval); } -long sys32_ioprio_get(u32 which, u32 who) +long compat_sys_ioprio_get(u32 which, u32 who) { /* sign extend which and who */ return sys_ioprio_get((int)which, (int)who); } -long sys32_ioprio_set(u32 which, u32 who, u32 ioprio) +long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio) { /* sign extend which, who and ioprio */ return sys_ioprio_set((int)which, (int)who, (int)ioprio); @@ -911,12 +821,12 @@ long sys32_ioprio_set(u32 which, u32 who, u32 ioprio) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_ssetmask(u32 newmask) +asmlinkage long compat_sys_ssetmask(u32 newmask) { return sys_ssetmask((int) newmask); } -asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len) +asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len) { /* sign extend len */ return sys_syslog(type, buf, (int)len); @@ -928,7 +838,7 @@ asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_umask(u32 mask) +asmlinkage long compat_sys_umask(u32 mask) { return sys_umask((int)mask); } @@ -944,7 +854,7 @@ struct __sysctl_args32 { u32 __unused[4]; }; -asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) +asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args) { struct __sysctl_args32 tmp; int error; @@ -985,7 +895,7 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } #endif -unsigned long sys32_mmap2(unsigned long addr, size_t len, +unsigned long compat_sys_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { @@ -993,29 +903,7 @@ unsigned long sys32_mmap2(unsigned long addr, size_t len, return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); } -int get_compat_timeval(struct timeval *tv, struct compat_timeval __user *ctv) -{ - return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) || - __get_user(tv->tv_sec, &ctv->tv_sec) || - __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0; -} - -asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs) -{ - struct timeval ktvs[2], *ptr; - - ptr = NULL; - if (tvs) { - if (get_compat_timeval(&ktvs[0], &tvs[0]) || - get_compat_timeval(&ktvs[1], &tvs[1])) - return -EFAULT; - ptr = ktvs; - } - - return do_utimes(filename, ptr); -} - -long sys32_tgkill(u32 tgid, u32 pid, int sig) +long compat_sys_tgkill(u32 tgid, u32 pid, int sig) { /* sign extend tgid, pid */ return sys_tgkill((int)tgid, (int)pid, sig); @@ -1026,30 +914,30 @@ long sys32_tgkill(u32 tgid, u32 pid, int sig) * The 32 bit ABI passes long longs in an odd even register pair. */ -compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, +compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 reg6, u32 poshi, u32 poslo) { return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); } -compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count, +compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 reg6, u32 poshi, u32 poslo) { return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); } -compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) +compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) { return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); } -asmlinkage int sys32_truncate64(const char __user * path, u32 reg4, +asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, unsigned long high, unsigned long low) { return sys_truncate(path, (high << 32) | low); } -asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, +asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, unsigned long low) { return sys_ftruncate(fd, (high << 32) | low); @@ -1108,7 +996,7 @@ long ppc32_timer_create(clockid_t clock, return err; } -asmlinkage long sys32_add_key(const char __user *_type, +asmlinkage long compat_sys_add_key(const char __user *_type, const char __user *_description, const void __user *_payload, u32 plen, @@ -1117,7 +1005,7 @@ asmlinkage long sys32_add_key(const char __user *_type, return sys_add_key(_type, _description, _payload, plen, ringid); } -asmlinkage long sys32_request_key(const char __user *_type, +asmlinkage long compat_sys_request_key(const char __user *_type, const char __user *_description, const char __user *_callout_info, u32 destringid) diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index b364141ec01c..2103f78f6445 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -19,15 +19,13 @@ #ifdef CONFIG_PPC64 #define SYSCALL(func) .llong .sys_##func,.sys_##func -#define SYSCALL32(func) .llong .sys_##func,.sys32_##func #define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func #define PPC_SYS(func) .llong .ppc_##func,.ppc_##func #define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall -#define SYS32ONLY(func) .llong .sys_ni_syscall,.sys32_##func +#define SYS32ONLY(func) .llong .sys_ni_syscall,.compat_sys_##func #define SYSX(f, f3264, f32) .llong .f,.f3264 #else #define SYSCALL(func) .long sys_##func -#define SYSCALL32(func) .long sys_##func #define COMPAT_SYS(func) .long sys_##func #define PPC_SYS(func) .long ppc_##func #define OLDSYS(func) .long sys_##func @@ -50,11 +48,11 @@ SYSCALL(read) SYSCALL(write) COMPAT_SYS(open) SYSCALL(close) -SYSCALL32(waitpid) -SYSCALL32(creat) +COMPAT_SYS(waitpid) +COMPAT_SYS(creat) SYSCALL(link) SYSCALL(unlink) -SYSCALL32(execve) +COMPAT_SYS(execve) SYSCALL(chdir) SYSX(sys64_time,compat_sys_time,sys_time) SYSCALL(mknod) @@ -69,20 +67,20 @@ SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount) SYSCALL(setuid) SYSCALL(getuid) COMPAT_SYS(stime) -SYSCALL32(ptrace) +COMPAT_SYS(ptrace) SYSCALL(alarm) OLDSYS(fstat) -SYSCALL32(pause) +COMPAT_SYS(pause) COMPAT_SYS(utime) SYSCALL(ni_syscall) SYSCALL(ni_syscall) -SYSCALL32(access) -SYSCALL32(nice) +COMPAT_SYS(access) +COMPAT_SYS(nice) SYSCALL(ni_syscall) SYSCALL(sync) -SYSCALL32(kill) +COMPAT_SYS(kill) SYSCALL(rename) -SYSCALL32(mkdir) +COMPAT_SYS(mkdir) SYSCALL(rmdir) SYSCALL(dup) SYSCALL(pipe) @@ -100,10 +98,10 @@ SYSCALL(ni_syscall) COMPAT_SYS(ioctl) COMPAT_SYS(fcntl) SYSCALL(ni_syscall) -SYSCALL32(setpgid) +COMPAT_SYS(setpgid) SYSCALL(ni_syscall) SYSX(sys_ni_syscall,sys_olduname, sys_olduname) -SYSCALL32(umask) +COMPAT_SYS(umask) SYSCALL(chroot) SYSCALL(ustat) SYSCALL(dup2) @@ -112,23 +110,23 @@ SYSCALL(getpgrp) SYSCALL(setsid) SYS32ONLY(sigaction) SYSCALL(sgetmask) -SYSCALL32(ssetmask) +COMPAT_SYS(ssetmask) SYSCALL(setreuid) SYSCALL(setregid) SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend) COMPAT_SYS(sigpending) -SYSCALL32(sethostname) +COMPAT_SYS(sethostname) COMPAT_SYS(setrlimit) COMPAT_SYS(old_getrlimit) COMPAT_SYS(getrusage) -SYSCALL32(gettimeofday) -SYSCALL32(settimeofday) -SYSCALL32(getgroups) -SYSCALL32(setgroups) +COMPAT_SYS(gettimeofday) +COMPAT_SYS(settimeofday) +COMPAT_SYS(getgroups) +COMPAT_SYS(setgroups) SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select) SYSCALL(symlink) OLDSYS(lstat) -SYSCALL32(readlink) +COMPAT_SYS(readlink) SYSCALL(uselib) SYSCALL(swapon) SYSCALL(reboot) @@ -139,14 +137,14 @@ SYSCALL(truncate) SYSCALL(ftruncate) SYSCALL(fchmod) SYSCALL(fchown) -SYSCALL32(getpriority) -SYSCALL32(setpriority) +COMPAT_SYS(getpriority) +COMPAT_SYS(setpriority) SYSCALL(ni_syscall) COMPAT_SYS(statfs) COMPAT_SYS(fstatfs) SYSCALL(ni_syscall) COMPAT_SYS(socketcall) -SYSCALL32(syslog) +COMPAT_SYS(syslog) COMPAT_SYS(setitimer) COMPAT_SYS(getitimer) COMPAT_SYS(newstat) @@ -159,15 +157,15 @@ SYSCALL(ni_syscall) SYSCALL(ni_syscall) COMPAT_SYS(wait4) SYSCALL(swapoff) -SYSCALL32(sysinfo) -SYSCALL32(ipc) +COMPAT_SYS(sysinfo) +COMPAT_SYS(ipc) SYSCALL(fsync) SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) PPC_SYS(clone) -SYSCALL32(setdomainname) +COMPAT_SYS(setdomainname) PPC_SYS(newuname) SYSCALL(ni_syscall) -SYSCALL32(adjtimex) +COMPAT_SYS(adjtimex) SYSCALL(mprotect) SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask) SYSCALL(ni_syscall) @@ -175,36 +173,36 @@ SYSCALL(init_module) SYSCALL(delete_module) SYSCALL(ni_syscall) SYSCALL(quotactl) -SYSCALL32(getpgid) +COMPAT_SYS(getpgid) SYSCALL(fchdir) SYSCALL(bdflush) -SYSCALL32(sysfs) +COMPAT_SYS(sysfs) SYSX(ppc64_personality,ppc64_personality,sys_personality) SYSCALL(ni_syscall) SYSCALL(setfsuid) SYSCALL(setfsgid) SYSCALL(llseek) -SYSCALL32(getdents) +COMPAT_SYS(getdents) SYSX(sys_select,ppc32_select,ppc_select) SYSCALL(flock) SYSCALL(msync) COMPAT_SYS(readv) COMPAT_SYS(writev) -SYSCALL32(getsid) +COMPAT_SYS(getsid) SYSCALL(fdatasync) -SYSCALL32(sysctl) +COMPAT_SYS(sysctl) SYSCALL(mlock) SYSCALL(munlock) SYSCALL(mlockall) SYSCALL(munlockall) -SYSCALL32(sched_setparam) -SYSCALL32(sched_getparam) -SYSCALL32(sched_setscheduler) -SYSCALL32(sched_getscheduler) +COMPAT_SYS(sched_setparam) +COMPAT_SYS(sched_getparam) +COMPAT_SYS(sched_setscheduler) +COMPAT_SYS(sched_getscheduler) SYSCALL(sched_yield) -SYSCALL32(sched_get_priority_max) -SYSCALL32(sched_get_priority_min) -SYSCALL32(sched_rr_get_interval) +COMPAT_SYS(sched_get_priority_max) +COMPAT_SYS(sched_get_priority_min) +COMPAT_SYS(sched_rr_get_interval) COMPAT_SYS(nanosleep) SYSCALL(mremap) SYSCALL(setresuid) @@ -214,36 +212,36 @@ SYSCALL(poll) COMPAT_SYS(nfsservctl) SYSCALL(setresgid) SYSCALL(getresgid) -SYSCALL32(prctl) +COMPAT_SYS(prctl) SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn) -SYSCALL32(rt_sigaction) -SYSCALL32(rt_sigprocmask) -SYSCALL32(rt_sigpending) +COMPAT_SYS(rt_sigaction) +COMPAT_SYS(rt_sigprocmask) +COMPAT_SYS(rt_sigpending) COMPAT_SYS(rt_sigtimedwait) -SYSCALL32(rt_sigqueueinfo) +COMPAT_SYS(rt_sigqueueinfo) SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend) -SYSCALL32(pread64) -SYSCALL32(pwrite64) +COMPAT_SYS(pread64) +COMPAT_SYS(pwrite64) SYSCALL(chown) SYSCALL(getcwd) SYSCALL(capget) SYSCALL(capset) -SYSCALL32(sigaltstack) -SYSX(sys_sendfile64,sys32_sendfile,sys_sendfile) +COMPAT_SYS(sigaltstack) +SYSX(sys_sendfile64,compat_sys_sendfile,sys_sendfile) SYSCALL(ni_syscall) SYSCALL(ni_syscall) PPC_SYS(vfork) COMPAT_SYS(getrlimit) -SYSCALL32(readahead) +COMPAT_SYS(readahead) SYS32ONLY(mmap2) SYS32ONLY(truncate64) SYS32ONLY(ftruncate64) SYSX(sys_ni_syscall,sys_stat64,sys_stat64) SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64) SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64) -SYSCALL32(pciconfig_read) -SYSCALL32(pciconfig_write) -SYSCALL32(pciconfig_iobase) +COMPAT_SYS(pciconfig_read) +COMPAT_SYS(pciconfig_write) +COMPAT_SYS(pciconfig_iobase) SYSCALL(ni_syscall) SYSCALL(getdents64) SYSCALL(pivot_root) @@ -293,8 +291,8 @@ COMPAT_SYS(clock_gettime) COMPAT_SYS(clock_getres) COMPAT_SYS(clock_nanosleep) SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) -SYSCALL32(tgkill) -SYSCALL32(utimes) +COMPAT_SYS(tgkill) +COMPAT_SYS(utimes) COMPAT_SYS(statfs64) COMPAT_SYS(fstatfs64) SYSX(sys_ni_syscall, ppc32_fadvise64_64, sys_fadvise64_64) @@ -312,12 +310,12 @@ COMPAT_SYS(mq_timedreceive) COMPAT_SYS(mq_notify) COMPAT_SYS(mq_getsetattr) COMPAT_SYS(kexec_load) -SYSCALL32(add_key) -SYSCALL32(request_key) +COMPAT_SYS(add_key) +COMPAT_SYS(request_key) COMPAT_SYS(keyctl) COMPAT_SYS(waitid) -SYSCALL32(ioprio_set) -SYSCALL32(ioprio_get) +COMPAT_SYS(ioprio_set) +COMPAT_SYS(ioprio_get) SYSCALL(inotify_init) SYSCALL(inotify_add_watch) SYSCALL(inotify_rm_watch) diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index ea30af810e0c..5d2fcbe384c1 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -265,7 +265,7 @@ _GLOBAL(save_nvgprs) */ _GLOBAL(ppc32_sigsuspend) bl .save_nvgprs - bl .sys32_sigsuspend + bl .compat_sys_sigsuspend b 70f _GLOBAL(ppc64_rt_sigsuspend) @@ -275,7 +275,7 @@ _GLOBAL(ppc64_rt_sigsuspend) _GLOBAL(ppc32_rt_sigsuspend) bl .save_nvgprs - bl .sys32_rt_sigsuspend + bl .compat_sys_rt_sigsuspend 70: cmpdi 0,r3,0 /* If it returned an error, we need to return via syscall_exit to set the SO bit in cr0 and potentially stop for ptrace. */ @@ -310,7 +310,7 @@ _GLOBAL(ppc_clone) _GLOBAL(ppc32_swapcontext) bl .save_nvgprs - bl .sys32_swapcontext + bl .compat_sys_swapcontext b 80f _GLOBAL(ppc64_swapcontext) @@ -319,11 +319,11 @@ _GLOBAL(ppc64_swapcontext) b 80f _GLOBAL(ppc32_sigreturn) - bl .sys32_sigreturn + bl .compat_sys_sigreturn b 80f _GLOBAL(ppc32_rt_sigreturn) - bl .sys32_rt_sigreturn + bl .compat_sys_rt_sigreturn b 80f _GLOBAL(ppc64_rt_sigreturn) diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index eb407c429bb0..ea8b6cf32c38 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -928,11 +928,11 @@ _GLOBAL(sys_call_table32) .llong .sys_write .llong .compat_sys_open /* 5 */ .llong .sys_close - .llong .sys32_waitpid - .llong .sys32_creat + .llong .compat_sys_waitpid + .llong .compat_sys_creat .llong .sys_link .llong .sys_unlink /* 10 */ - .llong .sys32_execve + .llong .compat_sys_execve .llong .sys_chdir .llong .compat_sys_time .llong .sys_mknod @@ -947,20 +947,20 @@ _GLOBAL(sys_call_table32) .llong .sys_setuid .llong .sys_getuid .llong .compat_sys_stime /* 25 */ - .llong .sys32_ptrace + .llong .compat_sys_ptrace .llong .sys_alarm .llong .sys_ni_syscall /* old fstat syscall */ - .llong .sys32_pause + .llong .compat_sys_pause .llong .compat_sys_utime /* 30 */ .llong .sys_ni_syscall /* old stty syscall */ .llong .sys_ni_syscall /* old gtty syscall */ - .llong .sys32_access - .llong .sys32_nice + .llong .compat_sys_access + .llong .compat_sys_nice .llong .sys_ni_syscall /* 35 - old ftime syscall */ .llong .sys_sync - .llong .sys32_kill + .llong .compat_sys_kill .llong .sys_rename - .llong .sys32_mkdir + .llong .compat_sys_mkdir .llong .sys_rmdir /* 40 */ .llong .sys_dup .llong .sys_pipe @@ -978,35 +978,35 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_ioctl .llong .compat_sys_fcntl /* 55 */ .llong .sys_ni_syscall /* old mpx syscall */ - .llong .sys32_setpgid + .llong .compat_sys_setpgid .llong .sys_ni_syscall /* old ulimit syscall */ .llong .sys_olduname - .llong .sys32_umask /* 60 */ + .llong .compat_sys_umask /* 60 */ .llong .sys_chroot .llong .sys_ustat .llong .sys_dup2 .llong .sys_getppid .llong .sys_getpgrp /* 65 */ .llong .sys_setsid - .llong .sys32_sigaction + .llong .compat_sys_sigaction .llong .sys_sgetmask - .llong .sys32_ssetmask + .llong .compat_sys_ssetmask .llong .sys_setreuid /* 70 */ .llong .sys_setregid .llong .ppc32_sigsuspend .llong .compat_sys_sigpending - .llong .sys32_sethostname + .llong .compat_sys_sethostname .llong .compat_sys_setrlimit /* 75 */ .llong .compat_sys_old_getrlimit .llong .compat_sys_getrusage - .llong .sys32_gettimeofday - .llong .sys32_settimeofday - .llong .sys32_getgroups /* 80 */ - .llong .sys32_setgroups + .llong .compat_sys_gettimeofday + .llong .compat_sys_settimeofday + .llong .compat_sys_getgroups /* 80 */ + .llong .compat_sys_setgroups .llong .sys_ni_syscall /* old select syscall */ .llong .sys_symlink .llong .sys_ni_syscall /* old lstat syscall */ - .llong .sys32_readlink /* 85 */ + .llong .compat_sys_readlink /* 85 */ .llong .sys_uselib .llong .sys_swapon .llong .sys_reboot @@ -1017,14 +1017,14 @@ _GLOBAL(sys_call_table32) .llong .sys_ftruncate .llong .sys_fchmod .llong .sys_fchown /* 95 */ - .llong .sys32_getpriority - .llong .sys32_setpriority + .llong .compat_sys_getpriority + .llong .compat_sys_setpriority .llong .sys_ni_syscall /* old profil syscall */ .llong .compat_sys_statfs .llong .compat_sys_fstatfs /* 100 */ .llong .sys_ni_syscall /* old ioperm syscall */ .llong .compat_sys_socketcall - .llong .sys32_syslog + .llong .compat_sys_syslog .llong .compat_sys_setitimer .llong .compat_sys_getitimer /* 105 */ .llong .compat_sys_newstat @@ -1037,15 +1037,15 @@ _GLOBAL(sys_call_table32) .llong .sys_ni_syscall /* old vm86 syscall */ .llong .compat_sys_wait4 .llong .sys_swapoff /* 115 */ - .llong .sys32_sysinfo - .llong .sys32_ipc + .llong .compat_sys_sysinfo + .llong .compat_sys_ipc .llong .sys_fsync .llong .ppc32_sigreturn .llong .ppc_clone /* 120 */ - .llong .sys32_setdomainname + .llong .compat_sys_setdomainname .llong .ppc_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ - .llong .sys32_adjtimex + .llong .compat_sys_adjtimex .llong .sys_mprotect /* 125 */ .llong .compat_sys_sigprocmask .llong .sys_ni_syscall /* old create_module syscall */ @@ -1053,36 +1053,36 @@ _GLOBAL(sys_call_table32) .llong .sys_delete_module .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */ .llong .sys_quotactl - .llong .sys32_getpgid + .llong .compat_sys_getpgid .llong .sys_fchdir .llong .sys_bdflush - .llong .sys32_sysfs /* 135 */ + .llong .compat_sys_sysfs /* 135 */ .llong .ppc64_personality .llong .sys_ni_syscall /* for afs_syscall */ .llong .sys_setfsuid .llong .sys_setfsgid .llong .sys_llseek /* 140 */ - .llong .sys32_getdents + .llong .compat_sys_getdents .llong .ppc32_select .llong .sys_flock .llong .sys_msync .llong .compat_sys_readv /* 145 */ .llong .compat_sys_writev - .llong .sys32_getsid + .llong .compat_sys_getsid .llong .sys_fdatasync - .llong .sys32_sysctl + .llong .compat_sys_sysctl .llong .sys_mlock /* 150 */ .llong .sys_munlock .llong .sys_mlockall .llong .sys_munlockall - .llong .sys32_sched_setparam - .llong .sys32_sched_getparam /* 155 */ - .llong .sys32_sched_setscheduler - .llong .sys32_sched_getscheduler + .llong .compat_sys_sched_setparam + .llong .compat_sys_sched_getparam /* 155 */ + .llong .compat_sys_sched_setscheduler + .llong .compat_sys_sched_getscheduler .llong .sys_sched_yield - .llong .sys32_sched_get_priority_max - .llong .sys32_sched_get_priority_min /* 160 */ - .llong .sys32_sched_rr_get_interval + .llong .compat_sys_sched_get_priority_max + .llong .compat_sys_sched_get_priority_min /* 160 */ + .llong .compat_sys_sched_rr_get_interval .llong .compat_sys_nanosleep .llong .sys_mremap .llong .sys_setresuid @@ -1092,36 +1092,36 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_nfsservctl .llong .sys_setresgid .llong .sys_getresgid /* 170 */ - .llong .sys32_prctl + .llong .compat_sys_prctl .llong .ppc32_rt_sigreturn - .llong .sys32_rt_sigaction - .llong .sys32_rt_sigprocmask - .llong .sys32_rt_sigpending /* 175 */ + .llong .compat_sys_rt_sigaction + .llong .compat_sys_rt_sigprocmask + .llong .compat_sys_rt_sigpending /* 175 */ .llong .compat_sys_rt_sigtimedwait - .llong .sys32_rt_sigqueueinfo + .llong .compat_sys_rt_sigqueueinfo .llong .ppc32_rt_sigsuspend - .llong .sys32_pread64 - .llong .sys32_pwrite64 /* 180 */ + .llong .compat_sys_pread64 + .llong .compat_sys_pwrite64 /* 180 */ .llong .sys_chown .llong .sys_getcwd .llong .sys_capget .llong .sys_capset - .llong .sys32_sigaltstack /* 185 */ - .llong .sys32_sendfile + .llong .compat_sys_sigaltstack /* 185 */ + .llong .compat_sys_sendfile .llong .sys_ni_syscall /* reserved for streams1 */ .llong .sys_ni_syscall /* reserved for streams2 */ .llong .ppc_vfork .llong .compat_sys_getrlimit /* 190 */ - .llong .sys32_readahead - .llong .sys32_mmap2 - .llong .sys32_truncate64 - .llong .sys32_ftruncate64 + .llong .compat_sys_readahead + .llong .compat_sys_mmap2 + .llong .compat_sys_truncate64 + .llong .compat_sys_ftruncate64 .llong .sys_stat64 /* 195 */ .llong .sys_lstat64 .llong .sys_fstat64 - .llong .sys32_pciconfig_read - .llong .sys32_pciconfig_write - .llong .sys32_pciconfig_iobase /* 200 - pciconfig_iobase */ + .llong .compat_sys_pciconfig_read + .llong .compat_sys_pciconfig_write + .llong .compat_sys_pciconfig_iobase /* 200 - pciconfig_iobase */ .llong .sys_ni_syscall /* reserved for MacOnLinux */ .llong .sys_getdents64 .llong .sys_pivot_root @@ -1147,7 +1147,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_sched_getaffinity .llong .sys_ni_syscall .llong .sys_ni_syscall /* 225 - reserved for tux */ - .llong .sys32_sendfile64 + .llong .compat_sys_sendfile64 .llong .compat_sys_io_setup .llong .sys_io_destroy .llong .compat_sys_io_getevents @@ -1171,8 +1171,8 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_clock_getres .llong .compat_sys_clock_nanosleep .llong .ppc32_swapcontext - .llong .sys32_tgkill /* 250 */ - .llong .sys32_utimes + .llong .compat_sys_tgkill /* 250 */ + .llong .compat_sys_utimes .llong .compat_sys_statfs64 .llong .compat_sys_fstatfs64 .llong .ppc32_fadvise64_64 /* 32bit only fadvise64_64 */ @@ -1190,12 +1190,12 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_mq_notify .llong .compat_sys_mq_getsetattr .llong .compat_sys_kexec_load - .llong .sys32_add_key - .llong .sys32_request_key /* 270 */ + .llong .compat_sys_add_key + .llong .compat_sys_request_key /* 270 */ .llong .compat_sys_keyctl .llong .compat_sys_waitid - .llong .sys32_ioprio_set - .llong .sys32_ioprio_get + .llong .compat_sys_ioprio_set + .llong .compat_sys_ioprio_get .llong .sys_inotify_init /* 275 */ .llong .sys_inotify_add_watch .llong .sys_inotify_rm_watch diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c index fb8c22d6084a..2e1df3ddd9fb 100644 --- a/arch/ppc64/kernel/ptrace32.c +++ b/arch/ppc64/kernel/ptrace32.c @@ -40,7 +40,7 @@ * in exit.c or in signal.c. */ -int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) +int compat_sys_ptrace(long request, long pid, unsigned long addr, unsigned long data) { struct task_struct *child; int ret = -EPERM; From 4b2d319b53810ab00ef3d8fdfc1c1ab0647ab0a7 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 18 Oct 2005 12:20:06 -0700 Subject: [PATCH 0332/1940] [IPoIB] Improve ipoib_timeout() output Use jiffies_to_msecs() so we print a human-readable time so we don't have to worry about what HZ is configured to, and print out a few values to make post-mortem analysis easier. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 6c5bf07489f4..ee303859b044 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -637,8 +637,11 @@ static void ipoib_timeout(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); - ipoib_warn(priv, "transmit timeout: latency %ld\n", - jiffies - dev->trans_start); + ipoib_warn(priv, "transmit timeout: latency %d msecs\n", + jiffies_to_msecs(jiffies - dev->trans_start)); + ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n", + netif_queue_stopped(dev), + priv->tx_head, priv->tx_tail); /* XXX reset QP, etc. */ } From c6f5cb7be0ab478e0618e3c2c6ada27f56d1e7fb Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 18 Oct 2005 13:22:16 -0700 Subject: [PATCH 0333/1940] [IB] mthca: Use enum in mthca_alloc_db() prototype Make the type parameter of mthca_alloc_db() be an enum mthca_db_type instead of an int. This doesn't have any practical effect but documents the functions a little better. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_memfree.c | 3 ++- drivers/infiniband/hw/mthca/mthca_memfree.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 7bd7a4bec7b4..d63b1a147100 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -487,7 +487,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, } } -int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) +int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, + u32 qn, __be32 **db) { int group; int start, end, dir; diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index bafa51544aa3..29c01a4b2656 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -173,7 +173,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, int mthca_init_db_tab(struct mthca_dev *dev); void mthca_cleanup_db_tab(struct mthca_dev *dev); -int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db); +int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, + u32 qn, __be32 **db); void mthca_free_db(struct mthca_dev *dev, int type, int db_index); #endif /* MTHCA_MEMFREE_H */ From d476306f1cc9156ce4b42586aacce70a356ef656 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 18 Oct 2005 14:07:07 -0700 Subject: [PATCH 0334/1940] [IB] mthca: Add struct pci_driver.owner field Set mthca_driver.owner to THIS_MODULE. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 7c35abec81ea..883d1e5a79bc 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -1196,6 +1196,7 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table); static struct pci_driver mthca_driver = { .name = DRV_NAME, + .owner = THIS_MODULE, .id_table = mthca_pci_table, .probe = mthca_init_one, .remove = __devexit_p(mthca_remove_one) From ba8e9310244180bbc820e865d2e4378809b4a443 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 18 Oct 2005 14:14:56 -0700 Subject: [PATCH 0335/1940] [IB] Fail sysfs queries after device is unregistered We keep IB device structures around until the last sysfs reference is gone, but we shouldn't ask the low-level driver to do anything after the LLD unregisters the device. To handle this, check the reg_state field and just fail sysfs show() requests if the device has already been unregistered. Signed-off-by: Roland Dreier --- drivers/infiniband/core/sysfs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 211ba3223f65..7ce7a6c782fa 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -65,6 +65,11 @@ struct port_table_attribute { int index; }; +static inline int ibdev_is_alive(const struct ib_device *dev) +{ + return dev->reg_state == IB_DEV_REGISTERED; +} + static ssize_t port_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -74,6 +79,8 @@ static ssize_t port_attr_show(struct kobject *kobj, if (!port_attr->show) return -EIO; + if (!ibdev_is_alive(p->ibdev)) + return -ENODEV; return port_attr->show(p, port_attr, buf); } @@ -581,6 +588,9 @@ static ssize_t show_node_type(struct class_device *cdev, char *buf) { struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); + if (!ibdev_is_alive(dev)) + return -ENODEV; + switch (dev->node_type) { case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type); case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type); @@ -595,6 +605,9 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf) struct ib_device_attr attr; ssize_t ret; + if (!ibdev_is_alive(dev)) + return -ENODEV; + ret = ib_query_device(dev, &attr); if (ret) return ret; @@ -612,6 +625,9 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf) struct ib_device_attr attr; ssize_t ret; + if (!ibdev_is_alive(dev)) + return -ENODEV; + ret = ib_query_device(dev, &attr); if (ret) return ret; From 7150bf8a98f14f1ba67e090ef2778004c746f465 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Tue, 18 Oct 2005 14:46:38 -0700 Subject: [PATCH 0336/1940] [IB] mthca: Don't enter QP into MCG more than once. Avoid entering a QP as member of a multicast group multiple times. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_mcg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 9a0612a9d304..b47ea7daf088 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -185,7 +185,12 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) } for (i = 0; i < MTHCA_QP_PER_MGM; ++i) - if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) { + if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31))) { + mthca_dbg(dev, "QP %06x already a member of MGM\n", + ibqp->qp_num); + err = 0; + goto out; + } else if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) { mgm->qp[i] = cpu_to_be32(ibqp->qp_num | (1 << 31)); break; } From 972c26bdd6b58e7534473c4f7928584578cf43f4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 18 Oct 2005 22:14:54 -0400 Subject: [PATCH 0337/1940] libata: add ata_sg_is_last() helper, use it in several drivers --- drivers/scsi/pdc_adma.c | 8 ++++---- drivers/scsi/sata_mv.c | 16 +++++++++------- drivers/scsi/sata_sil24.c | 15 ++++++++++----- include/linux/libata.h | 12 ++++++++++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 53b8db4be1a9..c6825da6ae20 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -293,14 +293,14 @@ static void adma_eng_timeout(struct ata_port *ap) static int adma_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; + struct scatterlist *sg; struct ata_port *ap = qc->ap; struct adma_port_priv *pp = ap->private_data; u8 *buf = pp->pkt; - int nelem, i = (2 + buf[3]) * 8; + int i = (2 + buf[3]) * 8; u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0); - for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { + ata_for_each_sg(sg, qc) { u32 addr; u32 len; @@ -312,7 +312,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)(buf + i) = cpu_to_le32(len); i += 4; - if ((nelem + 1) == qc->n_elem) + if (ata_sg_is_last(sg, qc)) pFLAGS |= pEND; buf[i++] = pFLAGS; buf[i++] = qc->dev->dma_mode & 0xf; diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index d457f5673476..be7c378dcd36 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -785,22 +785,24 @@ static void mv_port_stop(struct ata_port *ap) static void mv_fill_sg(struct ata_queued_cmd *qc) { struct mv_port_priv *pp = qc->ap->private_data; - unsigned int i; + unsigned int i = 0; + struct scatterlist *sg; - for (i = 0; i < qc->n_elem; i++) { + ata_for_each_sg(sg, qc) { u32 sg_len; dma_addr_t addr; - addr = sg_dma_address(&qc->sg[i]); - sg_len = sg_dma_len(&qc->sg[i]); + addr = sg_dma_address(sg); + sg_len = sg_dma_len(sg); pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); - } - if (0 < qc->n_elem) { - pp->sg_tbl[qc->n_elem - 1].flags_size |= EPRD_FLAG_END_OF_TBL; + if (ata_sg_is_last(sg, qc)) + pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); + + i++; } } diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 19857814d69f..e16d1815cda0 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -416,15 +416,20 @@ static void sil24_phy_reset(struct ata_port *ap) static inline void sil24_fill_sg(struct ata_queued_cmd *qc, struct sil24_cmd_block *cb) { - struct scatterlist *sg = qc->sg; struct sil24_sge *sge = cb->sge; - unsigned i; + struct scatterlist *sg; + unsigned int idx = 0; - for (i = 0; i < qc->n_elem; i++, sg++, sge++) { + ata_for_each_sg(sg, qc) { sge->addr = cpu_to_le64(sg_dma_address(sg)); sge->cnt = cpu_to_le32(sg_dma_len(sg)); - sge->flags = 0; - sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM); + if (ata_sg_is_last(sg, qc)) + sge->flags = cpu_to_le32(SGE_TRM); + else + sge->flags = 0; + + sge++; + idx++; } } diff --git a/include/linux/libata.h b/include/linux/libata.h index d3f58a796c3a..d3dfefefabec 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -480,6 +480,18 @@ extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); #endif /* CONFIG_PCI */ +static inline int +ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) +{ + if (sg == &qc->pad_sgent) + return 1; + if (qc->pad_len) + return 0; + if (((sg - qc->__sg) + 1) == qc->n_elem) + return 1; + return 0; +} + static inline struct scatterlist * ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) { From 7d0ffdb279105d9a87b447758ce4a634496abfd1 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Wed, 19 Oct 2005 12:21:19 +0100 Subject: [PATCH 0338/1940] NTFS: $EA attributes can be both resident non-resident. Minor tidying. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 1 + fs/ntfs/aops.c | 5 ++--- fs/ntfs/attrib.c | 2 +- fs/ntfs/file.c | 14 ++++++++++++++ fs/ntfs/layout.h | 27 +++++++++++++++++---------- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 03015c7b236c..bc6ec16ad1f8 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -75,6 +75,7 @@ ToDo/Notes: for highly fragmented files, i.e. ones whose data attribute is split across multiple extents. When such a case is encountered, EOPNOTSUPP is returned. + - $EA attributes can be both resident non-resident. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 8f23c60030c0..1c0a4315876a 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1391,8 +1391,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) if (NInoEncrypted(ni)) { unlock_page(page); BUG_ON(ni->type != AT_DATA); - ntfs_debug("Denying write access to encrypted " - "file."); + ntfs_debug("Denying write access to encrypted file."); return -EACCES; } /* Compressed data streams are handled in compress.c. */ @@ -1508,8 +1507,8 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) /* Zero out of bounds area in the page cache page. */ memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_mft_record_page(ctx->ntfs_ino); flush_dcache_page(page); + flush_dcache_mft_record_page(ctx->ntfs_ino); /* We are done with the page. */ end_page_writeback(page); /* Finally, mark the mft record dirty, so it gets written back. */ diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 338e47144fc9..df2e2091f936 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -1411,7 +1411,7 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type) */ int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type) { - if (type == AT_INDEX_ALLOCATION || type == AT_EA) + if (type == AT_INDEX_ALLOCATION) return -EPERM; return 0; } diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index cf2a0e2330df..5fb341a16b52 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -1857,10 +1857,24 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, if (ni->type != AT_INDEX_ALLOCATION) { /* If file is encrypted, deny access, just like NT4. */ if (NInoEncrypted(ni)) { + /* + * Reminder for later: Encrypted files are _always_ + * non-resident so that the content can always be + * encrypted. + */ ntfs_debug("Denying write access to encrypted file."); return -EACCES; } if (NInoCompressed(ni)) { + /* Only unnamed $DATA attribute can be compressed. */ + BUG_ON(ni->type != AT_DATA); + BUG_ON(ni->name_len); + /* + * Reminder for later: If resident, the data is not + * actually compressed. Only on the switch to non- + * resident does compression kick in. This is in + * contrast to encrypted files (see above). + */ ntfs_error(vi->i_sb, "Writing to compressed files is " "not implemented yet. Sorry."); return -EOPNOTSUPP; diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index 5c248d404f05..71b25dab8199 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h @@ -1021,10 +1021,17 @@ enum { FILE_NAME_POSIX = 0x00, /* This is the largest namespace. It is case sensitive and allows all Unicode characters except for: '\0' and '/'. Beware that in - WinNT/2k files which eg have the same name except for their case - will not be distinguished by the standard utilities and thus a "del - filename" will delete both "filename" and "fileName" without - warning. */ + WinNT/2k/2003 by default files which eg have the same name except + for their case will not be distinguished by the standard utilities + and thus a "del filename" will delete both "filename" and "fileName" + without warning. However if for example Services For Unix (SFU) are + installed and the case sensitive option was enabled at installation + time, then you can create/access/delete such files. + Note that even SFU places restrictions on the filenames beyond the + '\0' and '/' and in particular the following set of characters is + not allowed: '"', '/', '<', '>', '\'. All other characters, + including the ones no allowed in WIN32 namespace are allowed. + Tested with SFU 3.5 (this is now free) running on Windows XP. */ FILE_NAME_WIN32 = 0x01, /* The standard WinNT/2k NTFS long filenames. Case insensitive. All Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\', @@ -2375,20 +2382,20 @@ typedef u8 EA_FLAGS; /* * Attribute: Extended attribute (EA) (0xe0). * - * NOTE: Always non-resident. (Is this true?) + * NOTE: Can be resident or non-resident. * * Like the attribute list and the index buffer list, the EA attribute value is * a sequence of EA_ATTR variable length records. - * - * FIXME: It appears weird that the EA name is not unicode. Is it true? */ typedef struct { le32 next_entry_offset; /* Offset to the next EA_ATTR. */ EA_FLAGS flags; /* Flags describing the EA. */ - u8 ea_name_length; /* Length of the name of the EA in bytes. */ + u8 ea_name_length; /* Length of the name of the EA in bytes + excluding the '\0' byte terminator. */ le16 ea_value_length; /* Byte size of the EA's value. */ - u8 ea_name[0]; /* Name of the EA. */ - u8 ea_value[0]; /* The value of the EA. Immediately follows + u8 ea_name[0]; /* Name of the EA. Note this is ASCII, not + Unicode and it is zero terminated. */ + u8 ea_value[0]; /* The value of the EA. Immediately follows the name. */ } __attribute__ ((__packed__)) EA_ATTR; From d5aeaef37dc9cb009ab5cb8abf325338d21d2b1a Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Wed, 19 Oct 2005 12:23:10 +0100 Subject: [PATCH 0339/1940] NTFS: Fix serious data corruption issue when writing. Many thanks to Alberto Patino for testing and reporting the data corruption. And many apologies for corrupting his partition. Signed-off-by: Anton Altaparmakov --- fs/ntfs/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 5fb341a16b52..a142bf3ba1a5 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -787,6 +787,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, vcn_len = rl[1].vcn - vcn; lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits); + cdelta = 0; /* * If the number of remaining clusters in the * @pages is smaller or equal to the number of From 7ed476d17f04473f70d796cb6c172bdcfcc9b8e5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 19 Oct 2005 21:44:51 +1000 Subject: [PATCH 0340/1940] ppc: Minor smp changes for consistency with ppc64 This makes platform code use the smp_ops variable directly instead of ppc_md.smp_ops, removes the two unused `data' and `wait' arguments from the *_message_pass() functions, and removes the call to the never-implemented smp_ops->space_timers() function. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/setup.c | 4 ++-- arch/powerpc/platforms/powermac/smp.c | 5 ++--- arch/ppc/kernel/smp.c | 20 ++++++++------------ arch/ppc/platforms/chrp_setup.c | 2 +- arch/ppc/platforms/gemini_setup.c | 2 +- arch/ppc/platforms/hdpu.c | 4 ++-- arch/ppc/platforms/pmac_setup.c | 4 ++-- arch/ppc/platforms/pmac_smp.c | 3 +-- arch/ppc/platforms/pplus.c | 2 +- arch/ppc/platforms/prep_setup.c | 2 +- arch/ppc/syslib/open_pic.c | 2 +- 11 files changed, 22 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9416fcaa6daa..7eb0c34b6994 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -312,9 +312,9 @@ pmac_setup_arch(void) #ifdef CONFIG_SMP /* Check for Core99 */ if (find_devices("uni-n") || find_devices("u3")) - ppc_md.smp_ops = &core99_smp_ops; + smp_ops = &core99_smp_ops; else - ppc_md.smp_ops = &psurge_smp_ops; + smp_ops = &psurge_smp_ops; #endif /* CONFIG_SMP */ pci_create_OF_bus_map(); diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index fb996336c58b..ccaa0534d60f 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -209,8 +209,7 @@ irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) return IRQ_HANDLED; } -static void smp_psurge_message_pass(int target, int msg, unsigned long data, - int wait) +static void smp_psurge_message_pass(int target, int msg) { int i; @@ -627,7 +626,7 @@ void smp_core99_give_timebase(void) local_irq_restore(flags); } -void smp_core99_message_pass(int target, int msg, unsigned long data, int wait) +void smp_core99_message_pass(int target, int msg) { cpumask_t mask = CPU_MASK_ALL; /* make sure we're sending something that translates to an IPI */ diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 801c793fdec8..bc5bf1124836 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -51,7 +51,7 @@ EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_possible_map); /* SMP operations for this machine */ -static struct smp_ops_t *smp_ops; +struct smp_ops_t *smp_ops; /* all cpu mappings are 1-1 -- Cort */ volatile unsigned long cpu_callin_map[NR_CPUS]; @@ -74,11 +74,11 @@ extern void __save_cpu_setup(void); #define PPC_MSG_XMON_BREAK 3 static inline void -smp_message_pass(int target, int msg, unsigned long data, int wait) +smp_message_pass(int target, int msg) { - if (smp_ops){ + if (smp_ops) { atomic_inc(&ipi_sent); - smp_ops->message_pass(target,msg,data,wait); + smp_ops->message_pass(target, msg); } } @@ -119,7 +119,7 @@ void smp_message_recv(int msg, struct pt_regs *regs) void smp_send_tlb_invalidate(int cpu) { if ( PVR_VER(mfspr(SPRN_PVR)) == 8 ) - smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0); + smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB); } void smp_send_reschedule(int cpu) @@ -135,13 +135,13 @@ void smp_send_reschedule(int cpu) */ /* This is only used if `cpu' is running an idle task, so it will reschedule itself anyway... */ - smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); + smp_message_pass(cpu, PPC_MSG_RESCHEDULE); } #ifdef CONFIG_XMON void smp_send_xmon_break(int cpu) { - smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0); + smp_message_pass(cpu, PPC_MSG_XMON_BREAK); } #endif /* CONFIG_XMON */ @@ -224,7 +224,7 @@ static int __smp_call_function(void (*func) (void *info), void *info, spin_lock(&call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ - smp_message_pass(target, PPC_MSG_CALL_FUNCTION, 0, 0); + smp_message_pass(target, PPC_MSG_CALL_FUNCTION); /* Wait for response */ timeout = 1000000; @@ -294,7 +294,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(smp_processor_id()); cpu_callin_map[smp_processor_id()] = 1; - smp_ops = ppc_md.smp_ops; if (smp_ops == NULL) { printk("SMP not supported on this machine.\n"); return; @@ -308,9 +307,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* Backup CPU 0 state */ __save_cpu_setup(); - if (smp_ops->space_timers) - smp_ops->space_timers(num_cpus); - for_each_cpu(cpu) { if (cpu == smp_processor_id()) continue; diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 8c874e957a4b..56c53bb3dfd4 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -553,7 +553,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_SMP - ppc_md.smp_ops = &chrp_smp_ops; + smp_ops = &chrp_smp_ops; #endif /* CONFIG_SMP */ /* diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c index ec6aa04d001e..729897c59033 100644 --- a/arch/ppc/platforms/gemini_setup.c +++ b/arch/ppc/platforms/gemini_setup.c @@ -575,6 +575,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup; #ifdef CONFIG_SMP - ppc_md.smp_ops = &gemini_smp_ops; + smp_ops = &gemini_smp_ops; #endif /* CONFIG_SMP */ } diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c index ff3796860123..2cc12b04584a 100644 --- a/arch/ppc/platforms/hdpu.c +++ b/arch/ppc/platforms/hdpu.c @@ -753,7 +753,7 @@ static int smp_hdpu_probe(void) } static void -smp_hdpu_message_pass(int target, int msg, unsigned long data, int wait) +smp_hdpu_message_pass(int target, int msg) { if (msg > 0x3) { printk("SMP %d: smp_message_pass: unknown msg %d\n", @@ -949,7 +949,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif /* CONFIG_SERIAL_TEXT_DEBUG */ #ifdef CONFIG_SMP - ppc_md.smp_ops = &hdpu_smp_ops; + smp_ops = &hdpu_smp_ops; #endif /* CONFIG_SMP */ #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index 74165684552a..55d2beffe560 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -330,9 +330,9 @@ pmac_setup_arch(void) #ifdef CONFIG_SMP /* Check for Core99 */ if (find_devices("uni-n") || find_devices("u3")) - ppc_md.smp_ops = &core99_smp_ops; + smp_ops = &core99_smp_ops; else - ppc_md.smp_ops = &psurge_smp_ops; + smp_ops = &psurge_smp_ops; #endif /* CONFIG_SMP */ pci_create_OF_bus_map(); diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c index e613f0e0d9eb..26ff26238f03 100644 --- a/arch/ppc/platforms/pmac_smp.c +++ b/arch/ppc/platforms/pmac_smp.c @@ -209,8 +209,7 @@ irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) return IRQ_HANDLED; } -static void smp_psurge_message_pass(int target, int msg, unsigned long data, - int wait) +static void smp_psurge_message_pass(int target, int msg) { int i; diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c index c8803214405d..59eb330b2090 100644 --- a/arch/ppc/platforms/pplus.c +++ b/arch/ppc/platforms/pplus.c @@ -903,6 +903,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; #endif #ifdef CONFIG_SMP - ppc_md.smp_ops = &pplus_smp_ops; + smp_ops = &pplus_smp_ops; #endif /* CONFIG_SMP */ } diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 490ff175c902..9e5637e5f5a9 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -1160,6 +1160,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_SMP - ppc_md.smp_ops = &prep_smp_ops; + smp_ops = &prep_smp_ops; #endif /* CONFIG_SMP */ } diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 361f113260d7..894779712b46 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -890,7 +890,7 @@ openpic_get_irq(struct pt_regs *regs) #ifdef CONFIG_SMP void -smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) +smp_openpic_message_pass(int target, int msg) { cpumask_t mask = CPU_MASK_ALL; /* make sure we're sending something that translates to an IPI */ From 143a1dec7e04e0a9712ff93e779aabfb21dfd97c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 19 Oct 2005 23:11:21 +1000 Subject: [PATCH 0341/1940] powerpc: Merge machdep.h A few things change for consistency between ppc32 and ppc64: idle functions return void; *_get_boot_time functions return unsigned long (i.e. time_t) rather than filling in a struct rtc_time (since that's useful to the callers and easier for pmac to generate); *_get_rtc_time and *_set_rtc_time functions take a struct rtc_time; irq_canonicalize is gone; nvram_sync returns void. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/iseries/mf.c | 14 ++- arch/powerpc/platforms/iseries/setup.c | 12 +- arch/powerpc/platforms/iseries/setup.h | 2 +- arch/powerpc/platforms/powermac/pmac.h | 7 +- arch/powerpc/platforms/powermac/setup.c | 2 +- arch/powerpc/platforms/powermac/time.c | 24 +++- arch/powerpc/platforms/pseries/setup.c | 12 +- arch/ppc64/kernel/idle.c | 8 +- arch/ppc64/kernel/maple_setup.c | 2 +- arch/ppc64/kernel/maple_time.c | 7 +- arch/ppc64/kernel/pmac.h | 2 +- arch/ppc64/kernel/pmac_nvram.c | 4 +- arch/ppc64/kernel/pmac_time.c | 21 +--- arch/ppc64/kernel/rtas-proc.c | 1 + arch/ppc64/kernel/rtc.c | 11 +- include/{asm-ppc64 => asm-powerpc}/machdep.h | 121 +++++++++++++++++-- include/asm-powerpc/rtas.h | 2 +- 17 files changed, 177 insertions(+), 75 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/machdep.h (59%) diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 3f25f7fc79fc..e5de31aa0015 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -1307,11 +1308,14 @@ int iSeries_set_rtc_time(struct rtc_time *tm) return 0; } -void iSeries_get_boot_time(struct rtc_time *tm) +unsigned long iSeries_get_boot_time(void) { - if (piranha_simulator) - return; + struct rtc_time tm; - mf_get_boot_rtc(tm); - tm->tm_mon -= 1; + if (piranha_simulator) + return 0; + + mf_get_boot_rtc(&tm); + return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); } diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 93852c2ee5de..41cd5b689545 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -73,8 +73,8 @@ extern void hvlog(char *fmt, ...); extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); -static int iseries_shared_idle(void); -static int iseries_dedicated_idle(void); +static void iseries_shared_idle(void); +static void iseries_dedicated_idle(void); #ifdef CONFIG_PCI extern void iSeries_pci_final_fixup(void); #else @@ -693,7 +693,7 @@ static void yield_shared_processor(void) process_iSeries_events(); } -static int iseries_shared_idle(void) +static void iseries_shared_idle(void) { while (1) { while (!need_resched() && !hvlpevent_is_pending()) { @@ -715,11 +715,9 @@ static int iseries_shared_idle(void) schedule(); } - - return 0; } -static int iseries_dedicated_idle(void) +static void iseries_dedicated_idle(void) { long oldval; @@ -749,8 +747,6 @@ static int iseries_dedicated_idle(void) ppc64_runlatch_on(); schedule(); } - - return 0; } #ifndef CONFIG_PCI diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h index 6da89ae991ce..5213044ec411 100644 --- a/arch/powerpc/platforms/iseries/setup.h +++ b/arch/powerpc/platforms/iseries/setup.h @@ -17,7 +17,7 @@ #ifndef __ISERIES_SETUP_H__ #define __ISERIES_SETUP_H__ -extern void iSeries_get_boot_time(struct rtc_time *tm); +extern unsigned long iSeries_get_boot_time(void); extern int iSeries_set_rtc_time(struct rtc_time *tm); extern void iSeries_get_rtc_time(struct rtc_time *tm); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 81f52512b046..0a9ba704865e 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -10,9 +10,12 @@ * pmac_* files. Mostly for use by pmac_setup */ +struct rtc_time; + extern long pmac_time_init(void); -extern unsigned long pmac_get_rtc_time(void); -extern int pmac_set_rtc_time(unsigned long nowtime); +extern unsigned long pmac_get_boot_time(void); +extern void pmac_get_rtc_time(struct rtc_time *); +extern int pmac_set_rtc_time(struct rtc_time *); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); extern void pmac_pcibios_fixup(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 7eb0c34b6994..b6414e7c37d4 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -562,7 +562,6 @@ void __init pmac_init(void) ppc_md.setup_arch = pmac_setup_arch; ppc_md.show_cpuinfo = pmac_show_cpuinfo; ppc_md.show_percpuinfo = pmac_show_percpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ @@ -578,6 +577,7 @@ void __init pmac_init(void) ppc_md.time_init = pmac_time_init; ppc_md.set_rtc_time = pmac_set_rtc_time; ppc_md.get_rtc_time = pmac_get_rtc_time; + ppc_md.get_boot_time = pmac_get_boot_time; ppc_md.calibrate_decr = pmac_calibrate_decr; ppc_md.feature_call = pmac_do_feature_call; diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index edb9fcc64790..3ee6d8aa14c4 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -77,8 +77,7 @@ pmac_time_init(void) #endif } -unsigned long -pmac_get_rtc_time(void) +unsigned long pmac_get_boot_time(void) { #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; @@ -118,20 +117,33 @@ pmac_get_rtc_time(void) return 0; } -int -pmac_set_rtc_time(unsigned long nowtime) +void pmac_get_rtc_time(struct rtc_time *tm) { + unsigned long now; + + now = pmac_get_boot_time(); + to_tm(now, tm); + tm->tm_year -= 1900; + tm->tm_mon -= 1; /* month is 0-based */ +} + +int pmac_set_rtc_time(struct rtc_time *tm) +{ + unsigned long nowtime; #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; #endif + nowtime = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); nowtime += RTC_OFFSET; switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, - nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + nowtime >> 24, nowtime >> 16, nowtime >> 8, + nowtime) < 0) return 0; while (!req.complete) cuda_poll(); @@ -221,7 +233,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) case PBOOK_SLEEP_NOW: do { seq = read_seqbegin_irqsave(&xtime_lock, flags); - time_diff = xtime.tv_sec - pmac_get_rtc_time(); + time_diff = xtime.tv_sec - pmac_get_boot_time(); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); break; case PBOOK_WAKE: diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index eb25ee2eead8..0c84a44b43b4 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -84,8 +84,8 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */ extern void pSeries_system_reset_exception(struct pt_regs *regs); extern int pSeries_machine_check_exception(struct pt_regs *regs); -static int pseries_shared_idle(void); -static int pseries_dedicated_idle(void); +static void pseries_shared_idle(void); +static void pseries_dedicated_idle(void); static volatile void __iomem * chrp_int_ack_special; struct mpic *pSeries_mpic; @@ -488,8 +488,8 @@ static inline void dedicated_idle_sleep(unsigned int cpu) } } -static int pseries_dedicated_idle(void) -{ +static void pseries_dedicated_idle(void) +{ long oldval; struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); @@ -544,7 +544,7 @@ static int pseries_dedicated_idle(void) } } -static int pseries_shared_idle(void) +static void pseries_shared_idle(void) { struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); @@ -586,8 +586,6 @@ static int pseries_shared_idle(void) if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } static int pSeries_pci_probe_mode(struct pci_bus *bus) diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 954395d42636..8abd2ad92832 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -31,7 +31,7 @@ extern void power4_idle(void); -int default_idle(void) +void default_idle(void) { long oldval; unsigned int cpu = smp_processor_id(); @@ -64,11 +64,9 @@ int default_idle(void) if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } -int native_idle(void) +void native_idle(void) { while (1) { ppc64_runlatch_off(); @@ -85,8 +83,6 @@ int native_idle(void) system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } void cpu_idle(void) diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index 22987675f544..a107ed69a355 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c @@ -70,7 +70,7 @@ extern int maple_set_rtc_time(struct rtc_time *tm); extern void maple_get_rtc_time(struct rtc_time *tm); -extern void maple_get_boot_time(struct rtc_time *tm); +extern unsigned long maple_get_boot_time(void); extern void maple_calibrate_decr(void); extern void maple_pci_init(void); extern void maple_pcibios_fixup(void); diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c index d65210abcd03..cf5186335900 100644 --- a/arch/ppc64/kernel/maple_time.c +++ b/arch/ppc64/kernel/maple_time.c @@ -156,8 +156,9 @@ int maple_set_rtc_time(struct rtc_time *tm) return 0; } -void __init maple_get_boot_time(struct rtc_time *tm) +unsigned long __init maple_get_boot_time(void) { + struct rtc_time tm; struct device_node *rtcs; rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); @@ -170,6 +171,8 @@ void __init maple_get_boot_time(struct rtc_time *tm) "legacy address (0x%x)\n", maple_rtc_addr); } - maple_get_rtc_time(tm); + maple_get_rtc_time(&tm); + return mktime(time->tm_year+1900, time->tm_mon+1, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); } diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h index 40e1c5030f74..fa59f2a5c722 100644 --- a/arch/ppc64/kernel/pmac.h +++ b/arch/ppc64/kernel/pmac.h @@ -9,7 +9,7 @@ * pmac_* files. Mostly for use by pmac_setup */ -extern void pmac_get_boot_time(struct rtc_time *tm); +extern unsigned long pmac_get_boot_time(void); extern void pmac_get_rtc_time(struct rtc_time *tm); extern int pmac_set_rtc_time(struct rtc_time *tm); extern void pmac_read_rtc_time(void); diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c index 11586d535f81..5fe9785ad7d8 100644 --- a/arch/ppc64/kernel/pmac_nvram.c +++ b/arch/ppc64/kernel/pmac_nvram.c @@ -341,7 +341,7 @@ static int amd_write_bank(int bank, u8* datas) } -static int core99_nvram_sync(void) +static void core99_nvram_sync(void) { struct core99_header* hdr99; unsigned long flags; @@ -369,8 +369,6 @@ static int core99_nvram_sync(void) printk("nvram: Error writing bank %d\n", core99_bank); bail: spin_unlock_irqrestore(&nv_lock, flags); - - return 0; } int __init pmac_nvram_init(void) diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index 9d8c97decd32..c89bfefbbecd 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -135,23 +136,13 @@ int pmac_set_rtc_time(struct rtc_time *tm) } } -void __init pmac_get_boot_time(struct rtc_time *tm) +unsigned long __init pmac_get_boot_time(void) { - pmac_get_rtc_time(tm); + struct rtc_time tm; -#ifdef disabled__CONFIG_NVRAM - s32 delta = 0; - int dst; - - delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; - delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; - delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); - if (delta & 0x00800000UL) - delta |= 0xFF000000UL; - dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); - printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, - dst ? "on" : "off"); -#endif + pmac_get_rtc_time(&tm); + return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); } /* diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c index 1f3ff860fdf0..5bdd5b079d96 100644 --- a/arch/ppc64/kernel/rtas-proc.c +++ b/arch/ppc64/kernel/rtas-proc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 88ae13f81c46..79e7ed2858dd 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -265,7 +265,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, #ifdef CONFIG_PPC_RTAS #define MAX_RTC_WAIT 5000 /* 5 sec */ #define RTAS_CLOCK_BUSY (-2) -void rtas_get_boot_time(struct rtc_time *rtc_tm) +unsigned long rtas_get_boot_time(void) { int ret[8]; int error, wait_time; @@ -285,15 +285,10 @@ void rtas_get_boot_time(struct rtc_time *rtc_tm) if (error != 0 && printk_ratelimit()) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", error); - return; + return 0; } - rtc_tm->tm_sec = ret[5]; - rtc_tm->tm_min = ret[4]; - rtc_tm->tm_hour = ret[3]; - rtc_tm->tm_mday = ret[2]; - rtc_tm->tm_mon = ret[1] - 1; - rtc_tm->tm_year = ret[0] - 1900; + return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]); } /* NOTE: get_rtc_time will get an error if executed in interrupt context diff --git a/include/asm-ppc64/machdep.h b/include/asm-powerpc/machdep.h similarity index 59% rename from include/asm-ppc64/machdep.h rename to include/asm-powerpc/machdep.h index d35d9d3e44cf..f060553b997a 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -1,6 +1,6 @@ -#ifdef __KERNEL__ #ifndef _PPC64_MACHDEP_H #define _PPC64_MACHDEP_H +#ifdef __KERNEL__ /* * This program is free software; you can redistribute it and/or @@ -16,6 +16,11 @@ #include +/* We export this macro for external modules like Alsa to know if + * ppc_md.feature_call is implemented or not + */ +#define CONFIG_PPC_HAS_FEATURE_CALLS + struct pt_regs; struct pci_bus; struct device_node; @@ -39,6 +44,7 @@ struct smp_ops_t { #endif struct machdep_calls { +#ifdef CONFIG_PPC64 void (*hpte_invalidate)(unsigned long slot, unsigned long va, int large, @@ -74,6 +80,7 @@ struct machdep_calls { void (*iommu_dev_setup)(struct pci_dev *dev); void (*iommu_bus_setup)(struct pci_bus *bus); void (*irq_bus_setup)(struct pci_bus *bus); +#endif int (*probe)(int platform); void (*setup_arch)(void); @@ -86,6 +93,7 @@ struct machdep_calls { void (*cpu_irq_down)(int secondary); /* PCI stuff */ + /* Called after scanning the bus, before allocating resources */ void (*pcibios_fixup)(void); int (*pci_probe_mode)(struct pci_bus *); @@ -95,9 +103,13 @@ struct machdep_calls { void (*panic)(char *str); void (*cpu_die)(void); + long (*time_init)(void); /* Optional, may be NULL */ + int (*set_rtc_time)(struct rtc_time *); void (*get_rtc_time)(struct rtc_time *); - void (*get_boot_time)(struct rtc_time *); + unsigned long (*get_boot_time)(void); + unsigned char (*rtc_read_val)(int addr); + void (*rtc_write_val)(int addr, unsigned char val); void (*calibrate_decr)(void); @@ -109,7 +121,7 @@ struct machdep_calls { ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_size)(void); - int (*nvram_sync)(void); + void (*nvram_sync)(void); /* Exception handlers */ void (*system_reset_exception)(struct pt_regs *regs); @@ -134,14 +146,100 @@ struct machdep_calls { pgprot_t vma_prot); /* Idle loop for this platform, leave empty for default idle loop */ - int (*idle_loop)(void); + void (*idle_loop)(void); - /* Function to enable pmcs for this platform, called once per cpu. */ + /* Function to enable performance monitor counters for this + platform, called once per cpu. */ void (*enable_pmcs)(void); + +#ifdef CONFIG_PPC32 /* XXX for now */ + /* Optional, may be NULL. */ + int (*show_cpuinfo)(struct seq_file *m); + int (*show_percpuinfo)(struct seq_file *m, int i); + + /* A general init function, called by ppc_init in init/main.c. + May be NULL. */ + void (*init)(void); + + void (*idle)(void); + void (*power_save)(void); + + void (*heartbeat)(void); + unsigned long heartbeat_reset; + unsigned long heartbeat_count; + + unsigned long (*find_end_of_memory)(void); + void (*setup_io_mappings)(void); + + void (*early_serial_map)(void); + void (*kgdb_map_scc)(void); + + unsigned char (*nvram_read_val)(int addr); + void (*nvram_write_val)(int addr, unsigned char val); + + /* + * optional PCI "hooks" + */ + + /* Called after PPC generic resource fixup to perform + machine specific fixups */ + void (*pcibios_fixup_resources)(struct pci_dev *); + + /* Called for each PCI bus in the system when it's probed */ + void (*pcibios_fixup_bus)(struct pci_bus *); + + /* Called when pci_enable_device() is called (initial=0) or + * when a device with no assigned resource is found (initial=1). + * Returns 0 to allow assignment/enabling of the device. */ + int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); + + /* For interrupt routing */ + unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *); + int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char); + + /* Called in indirect_* to avoid touching devices */ + int (*pci_exclude_device)(unsigned char, unsigned char); + + /* Called at then very end of pcibios_init() */ + void (*pcibios_after_init)(void); + + /* this is for modules, since _machine can be a define -- Cort */ + int ppc_machine; + +#ifdef CONFIG_KEXEC + /* Called to shutdown machine specific hardware not already controlled + * by other drivers. + * XXX Should we move this one out of kexec scope? + */ + void (*machine_shutdown)(void); + + /* Called to do the minimal shutdown needed to run a kexec'd kernel + * to run successfully. + * XXX Should we move this one out of kexec scope? + */ + void (*machine_crash_shutdown)(void); + + /* Called to do what every setup is needed on image and the + * reboot code buffer. Returns 0 on success. + * Provide your own (maybe dummy) implementation if your platform + * claims to support kexec. + */ + int (*machine_kexec_prepare)(struct kimage *image); + + /* Called to handle any machine specific cleanup on image */ + void (*machine_kexec_cleanup)(struct kimage *image); + + /* Called to perform the _real_ kexec. + * Do NOT allocate memory or fail here. We are past the point of + * no return. + */ + void (*machine_kexec)(struct kimage *image); +#endif /* CONFIG_KEXEC */ +#endif /* CONFIG_PPC32 */ }; -extern int default_idle(void); -extern int native_idle(void); +extern void default_idle(void); +extern void native_idle(void); extern struct machdep_calls ppc_md; extern char cmd_line[COMMAND_LINE_SIZE]; @@ -161,6 +259,13 @@ extern sys_ctrler_t sys_ctrler; #endif /* CONFIG_PPC_PMAC */ +extern void setup_pci_ptrs(void); + +#ifdef CONFIG_SMP +/* Poor default implementations */ +extern void __devinit smp_generic_give_timebase(void); +extern void __devinit smp_generic_take_timebase(void); +#endif /* CONFIG_SMP */ /* Functions to produce codes on the leds. @@ -180,5 +285,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal) ppc_md.log_error(buf, err_type, fatal); } -#endif /* _PPC64_MACHDEP_H */ #endif /* __KERNEL__ */ +#endif /* _PPC64_MACHDEP_H */ diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h index 5c904d371963..2c050332471d 100644 --- a/include/asm-powerpc/rtas.h +++ b/include/asm-powerpc/rtas.h @@ -190,7 +190,7 @@ extern void rtas_progress(char *s, unsigned short hex); extern void rtas_initialize(void); struct rtc_time; -extern void rtas_get_boot_time(struct rtc_time *rtc_time); +extern unsigned long rtas_get_boot_time(void); extern void rtas_get_rtc_time(struct rtc_time *rtc_time); extern int rtas_set_rtc_time(struct rtc_time *rtc_time); From 0b879a31447acd9ebe8b3c5231f72ccebeefad3a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 19 Oct 2005 23:12:01 +1000 Subject: [PATCH 0342/1940] ppc: declare smp_ops in asm/smp.h, since platform setup code needs it Signed-off-by: Paul Mackerras --- include/asm-ppc/smp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 79c1be3dfe61..063d7dedc691 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -35,6 +35,7 @@ extern cpumask_t cpu_possible_map; extern unsigned long smp_proc_in_lock[]; extern volatile unsigned long cpu_callin_map[]; extern int smp_tb_synchronized; +extern struct smp_ops_t *smp_ops; extern void smp_send_tlb_invalidate(int); extern void smp_send_xmon_break(int cpu); From 9b7cf8b49dc4464b222afc9fa32628bb9a2e70a3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 19 Oct 2005 23:13:04 +1000 Subject: [PATCH 0343/1940] powerpc: Eliminate a compile warning in signal_32.c The second argument of get_sigset_t needed to have the const keyword. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/signal_32.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index e7e7aac11f89..1c4eac4c808f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -105,7 +105,8 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) return copy_to_user(uset, &cset, sizeof(*uset)); } -static inline int get_sigset_t(sigset_t *set, compat_sigset_t __user *uset) +static inline int get_sigset_t(sigset_t *set, + const compat_sigset_t __user *uset) { compat_sigset_t s32; @@ -187,7 +188,7 @@ static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) return copy_to_user(uset, set, sizeof(*uset)); } -static inline int get_sigset_t(sigset_t *set, sigset_t __user *uset) +static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) { return copy_from_user(set, uset, sizeof(*uset)); } From b123923d486d38e1a961e82040a26838401aebb5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 09:11:29 +1000 Subject: [PATCH 0344/1940] powerpc: Move ptrace32.c from arch/ppc64 to arch/powerpc Also corrected my email address in ptrace.c and updated the comments at the top of ptrace32.c. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/ptrace.c | 2 +- arch/{ppc64 => powerpc}/kernel/ptrace32.c | 9 +++++---- arch/ppc64/kernel/Makefile | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) rename arch/{ppc64 => powerpc}/kernel/ptrace32.c (97%) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 01b6d630edc9..5c5d2b5f3ca2 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -12,7 +12,7 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ signal_32.o -obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o +obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o ptrace32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 336b8bf542d7..943425a93354 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -8,7 +8,7 @@ * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds * * Modified by Cort Dougan (cort@hq.fsmlabs.com) - * and Paul Mackerras (paulus@linuxcare.com.au). + * and Paul Mackerras (paulus@samba.org). * * This file is subject to the terms and conditions of the GNU General * Public License. See the file README.legal in the main directory of diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c similarity index 97% rename from arch/ppc64/kernel/ptrace32.c rename to arch/powerpc/kernel/ptrace32.c index 2e1df3ddd9fb..544368277d7e 100644 --- a/arch/ppc64/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c @@ -1,5 +1,5 @@ /* - * linux/arch/ppc64/kernel/ptrace32.c + * ptrace for 32-bit processes running on a 64-bit kernel. * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -10,10 +10,10 @@ * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds * * Modified by Cort Dougan (cort@hq.fsmlabs.com) - * and Paul Mackerras (paulus@linuxcare.com.au). + * and Paul Mackerras (paulus@samba.org). * * This file is subject to the terms and conditions of the GNU General - * Public License. See the file README.legal in the main directory of + * Public License. See the file COPYING in the main directory of * this archive for more details. */ @@ -40,7 +40,8 @@ * in exit.c or in signal.c. */ -int compat_sys_ptrace(long request, long pid, unsigned long addr, unsigned long data) +int compat_sys_ptrace(int request, int pid, unsigned long addr, + unsigned long data) { struct task_struct *child; int ret = -EPERM; diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 19846d78b329..8c9012f0ce6a 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -15,7 +15,7 @@ obj-y += irq.o idle.o dma.o \ time.o signal.o \ align.o bitops.o pacaData.o \ udbg.o ioctl32.o \ - ptrace32.o rtc.o \ + rtc.o \ cpu_setup_power4.o \ iommu.o sysfs.o vdso.o pmc.o firmware.o obj-y += vdso32/ vdso64/ From 03f88e9f7145b03fd0d855918d54a3bf5342ac5e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 09:15:05 +1000 Subject: [PATCH 0345/1940] ppc64: Minor compilation fixes This defines CONFIG_PPC_STD_MMU for ppc64, changes an instance of sys32_ to compat_sys_ in the ppc64 syscall table, and removes a reference to a non-existent arch/powerpc/xmon/Makefile. Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 2 +- arch/ppc64/Kconfig | 3 +++ arch/ppc64/kernel/misc.S | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 29cda0732703..dedf1219761a 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -131,7 +131,7 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/sysdev/ \ arch/powerpc/platforms/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ -core-$(CONFIG_XMON) += arch/powerpc/xmon/ +#core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index e656e02d9dd1..8cbac7f32092 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -10,6 +10,9 @@ config MMU bool default y +config PPC_STD_MMU + def_bool y + config UID16 bool diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index c2c3421b8f38..ad73aad8dbb6 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -951,7 +951,7 @@ _GLOBAL(sys_call_table32) .llong .sys_alarm .llong .sys_ni_syscall /* old fstat syscall */ .llong .compat_sys_pause - .llong .compat_sys_utime /* 30 */ + .llong .compat_sys_utime /* 30 */ .llong .sys_ni_syscall /* old stty syscall */ .llong .sys_ni_syscall /* old gtty syscall */ .llong .compat_sys_access @@ -981,7 +981,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_setpgid .llong .sys_ni_syscall /* old ulimit syscall */ .llong .sys_olduname - .llong .compat_sys_umask /* 60 */ + .llong .compat_sys_umask /* 60 */ .llong .sys_chroot .llong .sys_ustat .llong .sys_dup2 @@ -996,17 +996,17 @@ _GLOBAL(sys_call_table32) .llong .ppc32_sigsuspend .llong .compat_sys_sigpending .llong .compat_sys_sethostname - .llong .compat_sys_setrlimit /* 75 */ + .llong .compat_sys_setrlimit /* 75 */ .llong .compat_sys_old_getrlimit .llong .compat_sys_getrusage .llong .compat_sys_gettimeofday .llong .compat_sys_settimeofday - .llong .compat_sys_getgroups /* 80 */ + .llong .compat_sys_getgroups /* 80 */ .llong .compat_sys_setgroups .llong .sys_ni_syscall /* old select syscall */ .llong .sys_symlink .llong .sys_ni_syscall /* old lstat syscall */ - .llong .compat_sys_readlink /* 85 */ + .llong .compat_sys_readlink /* 85 */ .llong .sys_uselib .llong .sys_swapon .llong .sys_reboot @@ -1021,12 +1021,12 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_setpriority .llong .sys_ni_syscall /* old profil syscall */ .llong .compat_sys_statfs - .llong .compat_sys_fstatfs /* 100 */ + .llong .compat_sys_fstatfs /* 100 */ .llong .sys_ni_syscall /* old ioperm syscall */ .llong .compat_sys_socketcall .llong .compat_sys_syslog .llong .compat_sys_setitimer - .llong .compat_sys_getitimer /* 105 */ + .llong .compat_sys_getitimer /* 105 */ .llong .compat_sys_newstat .llong .compat_sys_newlstat .llong .compat_sys_newfstat @@ -1038,7 +1038,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_wait4 .llong .sys_swapoff /* 115 */ .llong .compat_sys_sysinfo - .llong .compat_sys_ipc + .llong .sys32_ipc .llong .sys_fsync .llong .ppc32_sigreturn .llong .ppc_clone /* 120 */ @@ -1056,7 +1056,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_getpgid .llong .sys_fchdir .llong .sys_bdflush - .llong .compat_sys_sysfs /* 135 */ + .llong .compat_sys_sysfs /* 135 */ .llong .ppc64_personality .llong .sys_ni_syscall /* for afs_syscall */ .llong .sys_setfsuid @@ -1101,7 +1101,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_rt_sigqueueinfo .llong .ppc32_rt_sigsuspend .llong .compat_sys_pread64 - .llong .compat_sys_pwrite64 /* 180 */ + .llong .compat_sys_pwrite64 /* 180 */ .llong .sys_chown .llong .sys_getcwd .llong .sys_capget @@ -1166,12 +1166,12 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_timer_gettime .llong .sys_timer_getoverrun .llong .sys_timer_delete - .llong .compat_sys_clock_settime /* 245 */ + .llong .compat_sys_clock_settime/* 245 */ .llong .compat_sys_clock_gettime .llong .compat_sys_clock_getres .llong .compat_sys_clock_nanosleep .llong .ppc32_swapcontext - .llong .compat_sys_tgkill /* 250 */ + .llong .compat_sys_tgkill /* 250 */ .llong .compat_sys_utimes .llong .compat_sys_statfs64 .llong .compat_sys_fstatfs64 From f2783c15007468c14972e2617db51e9affc7fad9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 09:23:26 +1000 Subject: [PATCH 0346/1940] powerpc: Merge time.c and asm/time.h. We now use the merged time.c for both 32-bit and 64-bit compilation with ARCH=powerpc, and for ARCH=ppc64, but not for ARCH=ppc32. This removes setup_default_decr (folds its function into time_init) and moves wakeup_decrementer into time.c. This also makes an asm-powerpc/rtc.h. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 4 +- arch/powerpc/kernel/misc_32.S | 27 ++ arch/powerpc/kernel/ppc_ksyms.c | 1 - arch/powerpc/kernel/setup_64.c | 9 - arch/{ppc64 => powerpc}/kernel/time.c | 515 +++++++++++++--------- arch/powerpc/platforms/powermac/cpufreq.c | 9 - arch/powerpc/platforms/powermac/time.c | 28 +- arch/ppc/kernel/Makefile | 2 +- arch/ppc/kernel/time.c | 9 + arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/pmac_time.c | 2 - arch/ppc64/kernel/setup.c | 9 - drivers/macintosh/via-pmu.c | 11 - include/asm-powerpc/irq.h | 2 + include/asm-powerpc/rtc.h | 80 ++++ include/asm-powerpc/time.h | 212 +++++++++ include/asm-ppc64/time.h | 124 ------ 17 files changed, 659 insertions(+), 387 deletions(-) rename arch/{ppc64 => powerpc}/kernel/time.c (72%) create mode 100644 include/asm-powerpc/rtc.h create mode 100644 include/asm-powerpc/time.h delete mode 100644 include/asm-ppc64/time.h diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 5c5d2b5f3ca2..b347ac320252 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -29,7 +29,7 @@ extra-$(CONFIG_PPC64) += entry_64.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y += process.o init_task.o \ +obj-y += process.o init_task.o time.o \ prom.o systbl.o traps.o obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o @@ -44,7 +44,7 @@ endif else # stuff used from here for ARCH=ppc or ARCH=ppc64 -obj-$(CONFIG_PPC64) += traps.o process.o init_task.o +obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o fpux-$(CONFIG_PPC32) += fpu.o extra-$(CONFIG_PPC_FPU) += $(fpux-y) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 0b0e908b5065..303229b090b8 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -35,6 +35,33 @@ _GLOBAL(__delay) 1: bdnz 1b blr +/* + * This returns the high 64 bits of the product of two 64-bit numbers. + */ +_GLOBAL(mulhdu) + cmpwi r6,0 + cmpwi cr1,r3,0 + mr r10,r4 + mulhwu r4,r4,r5 + beq 1f + mulhwu r0,r10,r6 + mullw r7,r10,r5 + addc r7,r0,r7 + addze r4,r4 +1: beqlr cr1 /* all done if high part of A is 0 */ + mr r10,r3 + mullw r9,r3,r5 + mulhwu r3,r3,r5 + beq 2f + mullw r0,r10,r6 + mulhwu r8,r10,r6 + addc r7,r0,r7 + adde r4,r4,r8 + addze r3,r3 +2: addc r4,r4,r9 + addze r3,r3 + blr + /* * Returns (address we're running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 010554e5fe48..40c9e67e1b28 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -260,7 +260,6 @@ EXPORT_SYMBOL(__res); #ifdef CONFIG_PPC32 EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); -EXPORT_SYMBOL(disarm_decr); #endif #ifdef CONFIG_PPC_STD_MMU_32 diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 4fcf67575cbb..6f29614c3581 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -1083,15 +1083,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg) printk("[terminate]%04x %s\n", src, msg); } -/* This should only be called on processor 0 during calibrate decr */ -void __init setup_default_decr(void) -{ - struct paca_struct *lpaca = get_paca(); - - lpaca->default_decr = tb_ticks_per_jiffy; - lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; -} - #ifndef CONFIG_PPC_ISERIES /* * This function can be used by platforms to "find" legacy serial ports. diff --git a/arch/ppc64/kernel/time.c b/arch/powerpc/kernel/time.c similarity index 72% rename from arch/ppc64/kernel/time.c rename to arch/powerpc/kernel/time.c index 7f63755eddfd..d1608473075f 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -1,5 +1,4 @@ /* - * * Common time routines among all ppc machines. * * Written by Cort Dougan (cort@cs.nmt.edu) to merge @@ -44,29 +43,32 @@ #include #include #include -#include #include #include #include #include #include +#include +#include #include #include #include #include #include +#include +#include +#include +#include +#include +#ifdef CONFIG_PPC64 +#include +#include +#endif #ifdef CONFIG_PPC_ISERIES #include #include #endif -#include -#include -#include -#include -#include -#include -#include u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; @@ -81,27 +83,37 @@ unsigned long iSeries_recal_tb = 0; static unsigned long first_settimeofday = 1; #endif +/* The decrementer counts down by 128 every 128ns on a 601. */ +#define DECREMENTER_COUNT_601 (1000000000 / HZ) + #define XSEC_PER_SEC (1024*1024) +#ifdef CONFIG_PPC64 +#define SCALE_XSEC(xsec, max) (((xsec) * max) / XSEC_PER_SEC) +#else +/* compute ((xsec << 12) * max) >> 32 */ +#define SCALE_XSEC(xsec, max) mulhwu((xsec) << 12, max) +#endif + unsigned long tb_ticks_per_jiffy; unsigned long tb_ticks_per_usec = 100; /* sane default */ EXPORT_SYMBOL(tb_ticks_per_usec); unsigned long tb_ticks_per_sec; -unsigned long tb_to_xs; -unsigned tb_to_us; +u64 tb_to_xs; +unsigned tb_to_us; unsigned long processor_freq; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL_GPL(rtc_lock); -unsigned long tb_to_ns_scale; -unsigned long tb_to_ns_shift; +u64 tb_to_ns_scale; +unsigned tb_to_ns_shift; struct gettimeofday_struct do_gtod; extern unsigned long wall_jiffies; -extern int smp_tb_synchronized; extern struct timezone sys_tz; +static long timezone_offset; void ppc_adjtimex(void); @@ -110,6 +122,10 @@ static unsigned adjusting_time = 0; unsigned long ppc_proc_freq; unsigned long ppc_tb_freq; +#ifdef CONFIG_PPC32 /* XXX for now */ +#define boot_cpuid 0 +#endif + static __inline__ void timer_check_rtc(void) { /* @@ -129,30 +145,30 @@ static __inline__ void timer_check_rtc(void) * seconds like on Intel to avoid problems with non UTC clocks. */ if (ntp_synced() && - xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ && - jiffies - wall_jiffies == 1) { - struct rtc_time tm; - to_tm(xtime.tv_sec+1, &tm); - tm.tm_year -= 1900; - tm.tm_mon -= 1; - if (ppc_md.set_rtc_time(&tm) == 0) - last_rtc_update = xtime.tv_sec+1; - else - /* Try again one minute later */ - last_rtc_update += 60; + xtime.tv_sec - last_rtc_update >= 659 && + abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { + struct rtc_time tm; + to_tm(xtime.tv_sec + 1 + timezone_offset, &tm); + tm.tm_year -= 1900; + tm.tm_mon -= 1; + if (ppc_md.set_rtc_time(&tm) == 0) + last_rtc_update = xtime.tv_sec + 1; + else + /* Try again one minute later */ + last_rtc_update += 60; } } /* * This version of gettimeofday has microsecond resolution. */ -static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val) +static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) { - unsigned long sec, usec, tb_ticks; - unsigned long xsec, tb_xsec; - struct gettimeofday_vars * temp_varp; - unsigned long temp_tb_to_xs, temp_stamp_xsec; + unsigned long sec, usec; + u64 tb_ticks, xsec; + struct gettimeofday_vars *temp_varp; + u64 temp_tb_to_xs, temp_stamp_xsec; /* * These calculations are faster (gets rid of divides) @@ -164,11 +180,10 @@ static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val) tb_ticks = tb_val - temp_varp->tb_orig_stamp; temp_tb_to_xs = temp_varp->tb_to_xs; temp_stamp_xsec = temp_varp->stamp_xsec; - tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs ); - xsec = temp_stamp_xsec + tb_xsec; + xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs); sec = xsec / XSEC_PER_SEC; - xsec -= sec * XSEC_PER_SEC; - usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC; + usec = (unsigned long)xsec & (XSEC_PER_SEC - 1); + usec = SCALE_XSEC(usec, 1000000); tv->tv_sec = sec; tv->tv_usec = usec; @@ -185,6 +200,8 @@ EXPORT_SYMBOL(do_gettimeofday); static inline void timer_sync_xtime(unsigned long cur_tb) { +#ifdef CONFIG_PPC64 + /* why do we do this? */ struct timeval my_tv; __do_gettimeofday(&my_tv, cur_tb); @@ -193,6 +210,51 @@ static inline void timer_sync_xtime(unsigned long cur_tb) xtime.tv_sec = my_tv.tv_sec; xtime.tv_nsec = my_tv.tv_usec * 1000; } +#endif +} + +/* + * There are two copies of tb_to_xs and stamp_xsec so that no + * lock is needed to access and use these values in + * do_gettimeofday. We alternate the copies and as long as a + * reasonable time elapses between changes, there will never + * be inconsistent values. ntpd has a minimum of one minute + * between updates. + */ +static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, + unsigned int new_tb_to_xs) +{ + unsigned temp_idx; + struct gettimeofday_vars *temp_varp; + + temp_idx = (do_gtod.var_idx == 0); + temp_varp = &do_gtod.vars[temp_idx]; + + temp_varp->tb_to_xs = new_tb_to_xs; + temp_varp->tb_orig_stamp = new_tb_stamp; + temp_varp->stamp_xsec = new_stamp_xsec; + smp_mb(); + do_gtod.varp = temp_varp; + do_gtod.var_idx = temp_idx; + +#ifdef CONFIG_PPC64 + /* + * tb_update_count is used to allow the userspace gettimeofday code + * to assure itself that it sees a consistent view of the tb_to_xs and + * stamp_xsec variables. It reads the tb_update_count, then reads + * tb_to_xs and stamp_xsec and then reads tb_update_count again. If + * the two values of tb_update_count match and are even then the + * tb_to_xs and stamp_xsec values are consistent. If not, then it + * loops back and reads them again until this criteria is met. + */ + ++(systemcfg->tb_update_count); + smp_wmb(); + systemcfg->tb_orig_stamp = new_tb_stamp; + systemcfg->stamp_xsec = new_stamp_xsec; + systemcfg->tb_to_xs = new_tb_to_xs; + smp_wmb(); + ++(systemcfg->tb_update_count); +#endif } /* @@ -205,35 +267,17 @@ static inline void timer_sync_xtime(unsigned long cur_tb) * with a too big difference, then the vdso will fallback to calling * the syscall */ -static __inline__ void timer_recalc_offset(unsigned long cur_tb) +static __inline__ void timer_recalc_offset(u64 cur_tb) { - struct gettimeofday_vars * temp_varp; - unsigned temp_idx; - unsigned long offset, new_stamp_xsec, new_tb_orig_stamp; + unsigned long offset; + u64 new_stamp_xsec; - if (((cur_tb - do_gtod.varp->tb_orig_stamp) & 0x80000000u) == 0) + offset = cur_tb - do_gtod.varp->tb_orig_stamp; + if ((offset & 0x80000000u) == 0) return; - - temp_idx = (do_gtod.var_idx == 0); - temp_varp = &do_gtod.vars[temp_idx]; - - new_tb_orig_stamp = cur_tb; - offset = new_tb_orig_stamp - do_gtod.varp->tb_orig_stamp; - new_stamp_xsec = do_gtod.varp->stamp_xsec + mulhdu(offset, do_gtod.varp->tb_to_xs); - - temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; - temp_varp->tb_orig_stamp = new_tb_orig_stamp; - temp_varp->stamp_xsec = new_stamp_xsec; - smp_mb(); - do_gtod.varp = temp_varp; - do_gtod.var_idx = temp_idx; - - ++(systemcfg->tb_update_count); - smp_wmb(); - systemcfg->tb_orig_stamp = new_tb_orig_stamp; - systemcfg->stamp_xsec = new_stamp_xsec; - smp_wmb(); - ++(systemcfg->tb_update_count); + new_stamp_xsec = do_gtod.varp->stamp_xsec + + mulhdu(offset, do_gtod.varp->tb_to_xs); + update_gtod(cur_tb, new_stamp_xsec, do_gtod.varp->tb_to_xs); } #ifdef CONFIG_SMP @@ -313,7 +357,14 @@ static void iSeries_tb_recal(void) * call will not be needed) */ -unsigned long tb_last_stamp __cacheline_aligned_in_smp; +u64 tb_last_stamp __cacheline_aligned_in_smp; + +/* + * Note that on ppc32 this only stores the bottom 32 bits of + * the timebase value, but that's enough to tell when a jiffy + * has passed. + */ +DEFINE_PER_CPU(unsigned long, last_jiffy); /* * timer_interrupt - gets called when the decrementer overflows, @@ -322,17 +373,30 @@ unsigned long tb_last_stamp __cacheline_aligned_in_smp; void timer_interrupt(struct pt_regs * regs) { int next_dec; - unsigned long cur_tb; - struct paca_struct *lpaca = get_paca(); - unsigned long cpu = smp_processor_id(); + int cpu = smp_processor_id(); + unsigned long ticks; + +#ifdef CONFIG_PPC32 + if (atomic_read(&ppc_n_lost_interrupts) != 0) + do_IRQ(regs); +#endif irq_enter(); profile_tick(CPU_PROFILING, regs); - lpaca->lppaca.int_dword.fields.decr_int = 0; +#ifdef CONFIG_PPC_ISERIES + get_paca()->lppaca.int_dword.fields.decr_int = 0; +#endif + + while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) + >= tb_ticks_per_jiffy) { + /* Update last_jiffy */ + per_cpu(last_jiffy, cpu) += tb_ticks_per_jiffy; + /* Handle RTCL overflow on 601 */ + if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000) + per_cpu(last_jiffy, cpu) -= 1000000000; - while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) { /* * We cannot disable the decrementer, so in the period * between this cpu's being marked offline in cpu_online_map @@ -342,27 +406,26 @@ void timer_interrupt(struct pt_regs * regs) */ if (!cpu_is_offline(cpu)) update_process_times(user_mode(regs)); + /* * No need to check whether cpu is offline here; boot_cpuid * should have been fixed up by now. */ - if (cpu == boot_cpuid) { - write_seqlock(&xtime_lock); - tb_last_stamp = lpaca->next_jiffy_update_tb; - timer_recalc_offset(lpaca->next_jiffy_update_tb); - do_timer(regs); - timer_sync_xtime(lpaca->next_jiffy_update_tb); - timer_check_rtc(); - write_sequnlock(&xtime_lock); - if ( adjusting_time && (time_adjust == 0) ) - ppc_adjtimex(); - } - lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy; + if (cpu != boot_cpuid) + continue; + + write_seqlock(&xtime_lock); + tb_last_stamp += tb_ticks_per_jiffy; + timer_recalc_offset(tb_last_stamp); + do_timer(regs); + timer_sync_xtime(tb_last_stamp); + timer_check_rtc(); + write_sequnlock(&xtime_lock); + if (adjusting_time && (time_adjust == 0)) + ppc_adjtimex(); } - next_dec = lpaca->next_jiffy_update_tb - cur_tb; - if (next_dec > lpaca->default_decr) - next_dec = lpaca->default_decr; + next_dec = tb_ticks_per_jiffy - ticks; set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES @@ -370,15 +433,47 @@ void timer_interrupt(struct pt_regs * regs) process_hvlpevents(regs); #endif +#ifdef CONFIG_PPC64 /* collect purr register values often, for accurate calculations */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); cu->current_tb = mfspr(SPRN_PURR); } +#endif irq_exit(); } +void wakeup_decrementer(void) +{ + int i; + + set_dec(tb_ticks_per_jiffy); + /* + * We don't expect this to be called on a machine with a 601, + * so using get_tbl is fine. + */ + tb_last_stamp = get_tb(); + for_each_cpu(i) + per_cpu(last_jiffy, i) = tb_last_stamp; +} + +#ifdef CONFIG_SMPxxx +void __init smp_space_timers(unsigned int max_cpus) +{ + int i; + unsigned long offset = tb_ticks_per_jiffy / max_cpus; + unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); + + for_each_cpu(i) { + if (i != boot_cpuid) { + previous_tb += offset; + per_cpu(last_jiffy, i) = previous_tb; + } + } +} +#endif + /* * Scheduler clock - returns current time in nanosec units. * @@ -396,23 +491,24 @@ int do_settimeofday(struct timespec *tv) time_t wtm_sec, new_sec = tv->tv_sec; long wtm_nsec, new_nsec = tv->tv_nsec; unsigned long flags; - unsigned long delta_xsec; long int tb_delta; - unsigned long new_xsec; + u64 new_xsec; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; write_seqlock_irqsave(&xtime_lock, flags); - /* Updating the RTC is not the job of this code. If the time is - * stepped under NTP, the RTC will be update after STA_UNSYNC - * is cleared. Tool like clock/hwclock either copy the RTC + + /* + * Updating the RTC is not the job of this code. If the time is + * stepped under NTP, the RTC will be updated after STA_UNSYNC + * is cleared. Tools like clock/hwclock either copy the RTC * to the system time, in which case there is no point in writing * to the RTC again, or write to the RTC but then they don't call * settimeofday to perform this operation. */ #ifdef CONFIG_PPC_ISERIES - if ( first_settimeofday ) { + if (first_settimeofday) { iSeries_tb_recal(); first_settimeofday = 0; } @@ -420,7 +516,7 @@ int do_settimeofday(struct timespec *tv) tb_delta = tb_ticks_since(tb_last_stamp); tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; - new_nsec -= tb_delta / tb_ticks_per_usec / 1000; + new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec); @@ -435,28 +531,15 @@ int do_settimeofday(struct timespec *tv) ntp_clear(); - delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp), - do_gtod.varp->tb_to_xs ); - - new_xsec = (new_nsec * XSEC_PER_SEC) / NSEC_PER_SEC; - new_xsec += new_sec * XSEC_PER_SEC; - if ( new_xsec > delta_xsec ) { - do_gtod.varp->stamp_xsec = new_xsec - delta_xsec; - systemcfg->stamp_xsec = new_xsec - delta_xsec; - } - else { - /* This is only for the case where the user is setting the time - * way back to a time such that the boot time would have been - * before 1970 ... eg. we booted ten days ago, and we are setting - * the time to Jan 5, 1970 */ - do_gtod.varp->stamp_xsec = new_xsec; - do_gtod.varp->tb_orig_stamp = tb_last_stamp; - systemcfg->stamp_xsec = new_xsec; - systemcfg->tb_orig_stamp = tb_last_stamp; - } + new_xsec = (u64)new_nsec * XSEC_PER_SEC; + do_div(new_xsec, NSEC_PER_SEC); + new_xsec += (u64)new_sec * XSEC_PER_SEC; + update_gtod(tb_last_stamp, new_xsec, do_gtod.varp->tb_to_xs); +#ifdef CONFIG_PPC64 systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; systemcfg->tz_dsttime = sys_tz.tz_dsttime; +#endif write_sequnlock_irqrestore(&xtime_lock, flags); clock_was_set(); @@ -520,21 +603,40 @@ void __init generic_calibrate_decr(void) tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres); tb_to_xs = divres.result_low; - - setup_default_decr(); } #endif +unsigned long get_boot_time(void) +{ + struct rtc_time tm; + + if (ppc_md.get_boot_time) + return ppc_md.get_boot_time(); + if (!ppc_md.get_rtc_time) + return 0; + ppc_md.get_rtc_time(&tm); + return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +} + +/* This function is only called on the boot processor */ void __init time_init(void) { - /* This function is only called on the boot processor */ unsigned long flags; - struct rtc_time tm; + unsigned long tm = 0; struct div_result res; - unsigned long scale, shift; + u64 scale; + unsigned shift; + + if (ppc_md.time_init != NULL) + timezone_offset = ppc_md.time_init(); ppc_md.calibrate_decr(); +#ifdef CONFIG_PPC64 + get_paca()->default_decr = tb_ticks_per_jiffy; +#endif + /* * Compute scale factor for sched_clock. * The calibrate_decr() function has set tb_ticks_per_sec, @@ -557,29 +659,37 @@ void __init time_init(void) #ifdef CONFIG_PPC_ISERIES if (!piranha_simulator) #endif - ppc_md.get_boot_time(&tm); + tm = get_boot_time(); write_seqlock_irqsave(&xtime_lock, flags); - xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); + xtime.tv_sec = tm; + xtime.tv_nsec = 0; tb_last_stamp = get_tb(); do_gtod.varp = &do_gtod.vars[0]; do_gtod.var_idx = 0; do_gtod.varp->tb_orig_stamp = tb_last_stamp; - get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy; - do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; + __get_cpu_var(last_jiffy) = tb_last_stamp; + do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.varp->tb_to_xs = tb_to_xs; do_gtod.tb_to_us = tb_to_us; +#ifdef CONFIG_PPC64 systemcfg->tb_orig_stamp = tb_last_stamp; systemcfg->tb_update_count = 0; systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; systemcfg->tb_to_xs = tb_to_xs; +#endif time_freq = 0; - xtime.tv_nsec = 0; + /* If platform provided a timezone (pmac), we correct the time */ + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; + sys_tz.tz_dsttime = 0; + xtime.tv_sec -= timezone_offset; + } + last_rtc_update = xtime.tv_sec; set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); @@ -602,25 +712,28 @@ void __init time_init(void) void ppc_adjtimex(void) { - unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec; +#ifdef CONFIG_PPC64 + unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, + new_tb_to_xs, new_xsec, new_stamp_xsec; unsigned long tb_ticks_per_sec_delta; long delta_freq, ltemp; struct div_result divres; unsigned long flags; - struct gettimeofday_vars * temp_varp; - unsigned temp_idx; long singleshot_ppm = 0; - /* Compute parts per million frequency adjustment to accomplish the time adjustment - implied by time_offset to be applied over the elapsed time indicated by time_constant. - Use SHIFT_USEC to get it into the same units as time_freq. */ + /* + * Compute parts per million frequency adjustment to + * accomplish the time adjustment implied by time_offset to be + * applied over the elapsed time indicated by time_constant. + * Use SHIFT_USEC to get it into the same units as + * time_freq. + */ if ( time_offset < 0 ) { ltemp = -time_offset; ltemp <<= SHIFT_USEC - SHIFT_UPDATE; ltemp >>= SHIFT_KG + time_constant; ltemp = -ltemp; - } - else { + } else { ltemp = time_offset; ltemp <<= SHIFT_USEC - SHIFT_UPDATE; ltemp >>= SHIFT_KG + time_constant; @@ -637,7 +750,10 @@ void ppc_adjtimex(void) adjusting_time = 1; - /* Compute parts per million frequency adjustment to match time_adjust */ + /* + * Compute parts per million frequency adjustment + * to match time_adjust + */ singleshot_ppm = tickadj * HZ; /* * The adjustment should be tickadj*HZ to match the code in @@ -645,7 +761,7 @@ void ppc_adjtimex(void) * large. 3/4 of tickadj*HZ seems about right */ singleshot_ppm -= singleshot_ppm / 4; - /* Use SHIFT_USEC to get it into the same units as time_freq */ + /* Use SHIFT_USEC to get it into the same units as time_freq */ singleshot_ppm <<= SHIFT_USEC; if ( time_adjust < 0 ) singleshot_ppm = -singleshot_ppm; @@ -661,7 +777,10 @@ void ppc_adjtimex(void) /* Add up all of the frequency adjustments */ delta_freq = time_freq + ltemp + singleshot_ppm; - /* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */ + /* + * Compute a new value for tb_ticks_per_sec based on + * the frequency adjustment + */ den = 1000000 * (1 << (SHIFT_USEC - 8)); if ( delta_freq < 0 ) { tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den; @@ -676,61 +795,37 @@ void ppc_adjtimex(void) printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm); printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec); #endif - - /* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of - stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp. This - new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs) - which guarantees that the current time remains the same */ - write_seqlock_irqsave( &xtime_lock, flags ); - tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp; - div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres ); - new_tb_to_xs = divres.result_low; - new_xsec = mulhdu( tb_ticks, new_tb_to_xs ); - - old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs ); - new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec; - - /* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these - values in do_gettimeofday. We alternate the copies and as long as a reasonable time elapses between - changes, there will never be inconsistent values. ntpd has a minimum of one minute between updates */ - - temp_idx = (do_gtod.var_idx == 0); - temp_varp = &do_gtod.vars[temp_idx]; - - temp_varp->tb_to_xs = new_tb_to_xs; - temp_varp->stamp_xsec = new_stamp_xsec; - temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; - smp_mb(); - do_gtod.varp = temp_varp; - do_gtod.var_idx = temp_idx; /* - * tb_update_count is used to allow the problem state gettimeofday code - * to assure itself that it sees a consistent view of the tb_to_xs and - * stamp_xsec variables. It reads the tb_update_count, then reads - * tb_to_xs and stamp_xsec and then reads tb_update_count again. If - * the two values of tb_update_count match and are even then the - * tb_to_xs and stamp_xsec values are consistent. If not, then it - * loops back and reads them again until this criteria is met. + * Compute a new value of tb_to_xs (used to convert tb to + * microseconds) and a new value of stamp_xsec which is the + * time (in 1/2^20 second units) corresponding to + * tb_orig_stamp. This new value of stamp_xsec compensates + * for the change in frequency (implied by the new tb_to_xs) + * which guarantees that the current time remains the same. */ - ++(systemcfg->tb_update_count); - smp_wmb(); - systemcfg->tb_to_xs = new_tb_to_xs; - systemcfg->stamp_xsec = new_stamp_xsec; - smp_wmb(); - ++(systemcfg->tb_update_count); + write_seqlock_irqsave( &xtime_lock, flags ); + tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp; + div128_by_32(1024*1024, 0, new_tb_ticks_per_sec, &divres); + new_tb_to_xs = divres.result_low; + new_xsec = mulhdu(tb_ticks, new_tb_to_xs); + + old_xsec = mulhdu(tb_ticks, do_gtod.varp->tb_to_xs); + new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec; + + update_gtod(do_gtod.varp->tb_orig_stamp, new_stamp_xsec, new_tb_to_xs); write_sequnlock_irqrestore( &xtime_lock, flags ); - +#endif /* CONFIG_PPC64 */ } -#define TICK_SIZE tick #define FEBRUARY 2 #define STARTOFTIME 1970 #define SECDAY 86400L #define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) +#define leapyear(year) ((year) % 4 == 0 && \ + ((year) % 100 != 0 || (year) % 400 == 0)) #define days_in_year(a) (leapyear(a) ? 366 : 365) #define days_in_month(a) (month_days[(a) - 1]) @@ -748,37 +843,25 @@ void GregorianDay(struct rtc_time * tm) int day; int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - lastYear=tm->tm_year-1; + lastYear = tm->tm_year - 1; /* * Number of leap corrections to apply up to end of last year */ - leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; + leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400; /* * This year is a leap year if it is divisible by 4 except when it is * divisible by 100 unless it is divisible by 400 * - * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was */ - if((tm->tm_year%4==0) && - ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && - (tm->tm_mon>2)) - { - /* - * We are past Feb. 29 in a leap year - */ - day=1; - } - else - { - day=0; - } + day = tm->tm_mon > 2 && leapyear(tm->tm_year); day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; - tm->tm_wday=day%7; + tm->tm_wday = day % 7; } void to_tm(int tim, struct rtc_time * tm) @@ -824,14 +907,16 @@ void to_tm(int tim, struct rtc_time * tm) * oscillators and the precision with which the timebase frequency * is measured but does not harm. */ -unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) { +unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) +{ unsigned mlt=0, tmp, err; /* No concern for performance, it's done once: use a stupid * but safe and compact method to find the multiplier. */ for (tmp = 1U<<31; tmp != 0; tmp >>= 1) { - if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp; + if (mulhwu(inscale, mlt|tmp) < outscale) + mlt |= tmp; } /* We might still be off by 1 for the best approximation. @@ -841,39 +926,53 @@ unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) { * some might have been forgotten in the test however. */ - err = inscale*(mlt+1); - if (err <= inscale/2) mlt++; + err = inscale * (mlt+1); + if (err <= inscale/2) + mlt++; return mlt; - } +} /* * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit * result. */ - -void div128_by_32( unsigned long dividend_high, unsigned long dividend_low, - unsigned divisor, struct div_result *dr ) +void div128_by_32(u64 dividend_high, u64 dividend_low, + unsigned divisor, struct div_result *dr) { - unsigned long a,b,c,d, w,x,y,z, ra,rb,rc; + unsigned long a, b, c, d; + unsigned long w, x, y, z; + u64 ra, rb, rc; a = dividend_high >> 32; b = dividend_high & 0xffffffff; c = dividend_low >> 32; d = dividend_low & 0xffffffff; - w = a/divisor; - ra = (a - (w * divisor)) << 32; + w = a / divisor; + ra = ((u64)(a - (w * divisor)) << 32) + b; - x = (ra + b)/divisor; - rb = ((ra + b) - (x * divisor)) << 32; +#ifdef CONFIG_PPC64 + x = ra / divisor; + rb = ((ra - (x * divisor)) << 32) + c; - y = (rb + c)/divisor; - rc = ((rb + b) - (y * divisor)) << 32; + y = rb / divisor; + rc = ((rb - (y * divisor)) << 32) + d; - z = (rc + d)/divisor; + z = rc / divisor; +#else + /* for 32-bit, use do_div from div64.h */ + rb = ((u64) do_div(ra, divisor) << 32) + c; + x = ra; - dr->result_high = (w << 32) + x; - dr->result_low = (y << 32) + z; + rc = ((u64) do_div(rb, divisor) << 32) + d; + y = rb; + + do_div(rc, divisor); + z = rc; +#endif + + dr->result_high = ((u64)w << 32) + x; + dr->result_low = ((u64)y << 32) + z; } diff --git a/arch/powerpc/platforms/powermac/cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq.c index bcd9224f3f90..c47f8b69725c 100644 --- a/arch/powerpc/platforms/powermac/cpufreq.c +++ b/arch/powerpc/platforms/powermac/cpufreq.c @@ -110,15 +110,6 @@ static inline void local_delay(unsigned long ms) msleep(ms); } -static inline void wakeup_decrementer(void) -{ - set_dec(tb_ticks_per_jiffy); - /* No currently-supported powerbook has a 601, - * so use get_tbl, not native - */ - last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); -} - #ifdef DEBUG_FREQ static inline void debug_calc_bogomips(void) { diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 3ee6d8aa14c4..eb9969b52f96 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -6,6 +6,8 @@ * * Paul Mackerras August 1996. * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 2003-2005 Benjamin Herrenschmidt. + * */ #include #include @@ -19,7 +21,9 @@ #include #include #include +#include #include +#include #include #include @@ -30,6 +34,14 @@ #include #include +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + /* Apparently the RTC stores seconds since 1 Jan 1904 */ #define RTC_OFFSET 2082844800 @@ -54,10 +66,7 @@ /* Bits in IFR and IER */ #define T1_INT 0x40 /* Timer 1 interrupt */ -extern struct timezone sys_tz; - -long __init -pmac_time_init(void) +long __init pmac_time_init(void) { #ifdef CONFIG_NVRAM s32 delta = 0; @@ -210,7 +219,7 @@ via_calibrate_decr(void) tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); - printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %lu (%u ticks)\n", tb_ticks_per_jiffy, dstart - dend); iounmap(via); @@ -228,6 +237,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) static unsigned long time_diff; unsigned long flags; unsigned long seq; + struct timespec tv; switch (when) { case PBOOK_SLEEP_NOW: @@ -237,11 +247,9 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); break; case PBOOK_WAKE: - write_seqlock_irqsave(&xtime_lock, flags); - xtime.tv_sec = pmac_get_rtc_time() + time_diff; - xtime.tv_nsec = 0; - last_rtc_update = xtime.tv_sec; - write_sequnlock_irqrestore(&xtime_lock, flags); + tv.tv_sec = pmac_get_boot_time() + time_diff; + tv.tv_nsec = 0; + do_settimeofday(&tv); break; } return PBOOK_SLEEP_OK; diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 5a742c7b0509..ccbc442c9ed3 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -37,7 +37,7 @@ endif # These are here while we do the architecture merge else -obj-y := irq.o idle.o time.o \ +obj-y := irq.o idle.o \ align.o perfmon.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 22d7fd1e0aea..76f44ce4772e 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -121,6 +121,15 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); #endif +void wakeup_decrementer(void) +{ + set_dec(tb_ticks_per_jiffy); + /* No currently-supported powerbook has a 601, + * so use get_tbl, not native + */ + last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); +} + /* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 8c9012f0ce6a..18f477fa1df2 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := setup.o entry.o misc.o prom.o endif obj-y += irq.o idle.o dma.o \ - time.o signal.o \ + signal.o \ align.o bitops.o pacaData.o \ udbg.o ioctl32.o \ rtc.o \ diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index c89bfefbbecd..56f335115916 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c @@ -180,7 +180,5 @@ void __init pmac_calibrate_decr(void) if (fp == 0) panic("can't get cpu processor frequency"); ppc_proc_freq = *fp; - - setup_default_decr(); } diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 776b55b45e1b..3e6c1547b718 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -1083,15 +1083,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg) printk("[terminate]%04x %s\n", src, msg); } -/* This should only be called on processor 0 during calibrate decr */ -void __init setup_default_decr(void) -{ - struct paca_struct *lpaca = get_paca(); - - lpaca->default_decr = tb_ticks_per_jiffy; - lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; -} - #ifndef CONFIG_PPC_ISERIES /* * This function can be used by platforms to "find" legacy serial ports. diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 503461884528..91920a1140fa 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -588,17 +588,6 @@ pmu_get_model(void) return pmu_kind; } -#ifndef CONFIG_PPC64 -static inline void wakeup_decrementer(void) -{ - set_dec(tb_ticks_per_jiffy); - /* No currently-supported powerbook has a 601, - * so use get_tbl, not native - */ - last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); -} -#endif - static void pmu_set_server_mode(int server_mode) { struct adb_request req; diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 980393a16be2..07c2b3fc4c66 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h @@ -496,5 +496,7 @@ extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, #endif /* CONFIG_IRQSTACKS */ +extern void do_IRQ(struct pt_regs *regs); + #endif /* _ASM_IRQ_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/rtc.h b/include/asm-powerpc/rtc.h new file mode 100644 index 000000000000..d38f2a077db2 --- /dev/null +++ b/include/asm-powerpc/rtc.h @@ -0,0 +1,80 @@ +/* + * Real-time clock definitions and interfaces + * + * Author: Tom Rini + * + * 2002 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Based on: + * include/asm-m68k/rtc.h + * + * Copyright Richard Zidlicky + * implementation details for genrtc/q40rtc driver + * + * And the old drivers/macintosh/rtc.c which was heavily based on: + * Linux/SPARC Real Time Clock Driver + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + * + * With additional work by Paul Mackerras and Franz Sirl. + */ + +#ifndef __ASM_POWERPC_RTC_H__ +#define __ASM_POWERPC_RTC_H__ + +#ifdef __KERNEL__ + +#include + +#include +#include + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +/* some dummy definitions */ +#define RTC_BATT_BAD 0x100 /* battery bad */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +static inline unsigned int get_rtc_time(struct rtc_time *time) +{ + if (ppc_md.get_rtc_time) + ppc_md.get_rtc_time(time); + return RTC_24H; +} + +/* Set the current date and time in the real time clock. */ +static inline int set_rtc_time(struct rtc_time *time) +{ + if (ppc_md.get_rtc_time) { + ppc_md.set_rtc_time(time); + return 0; + } + return -EINVAL; +} + +static inline unsigned int get_rtc_ss(void) +{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} + +#endif /* __KERNEL__ */ +#endif /* __ASM_POWERPC_RTC_H__ */ diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h new file mode 100644 index 000000000000..4eecc38f7092 --- /dev/null +++ b/include/asm-powerpc/time.h @@ -0,0 +1,212 @@ +/* + * Common time prototypes and such for all ppc machines. + * + * Written by Cort Dougan (cort@cs.nmt.edu) to merge + * Paul Mackerras' version and mine for PReP and Pmac. + * + * 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. + */ + +#ifndef __POWERPC_TIME_H +#define __POWERPC_TIME_H + +#ifdef __KERNEL__ +#include +#include +#include + +#include +#ifdef CONFIG_PPC64 +#include +#include +#endif + +/* time.c */ +extern unsigned long tb_ticks_per_jiffy; +extern unsigned long tb_ticks_per_usec; +extern unsigned long tb_ticks_per_sec; +extern u64 tb_to_xs; +extern unsigned tb_to_us; +extern u64 tb_last_stamp; + +DECLARE_PER_CPU(unsigned long, last_jiffy); + +struct rtc_time; +extern void to_tm(int tim, struct rtc_time * tm); +extern time_t last_rtc_update; + +extern void generic_calibrate_decr(void); +extern void wakeup_decrementer(void); + +/* Some sane defaults: 125 MHz timebase, 1GHz processor */ +extern unsigned long ppc_proc_freq; +#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) +extern unsigned long ppc_tb_freq; +#define DEFAULT_TB_FREQ 125000000UL + +/* + * By putting all of this stuff into a single struct we + * reduce the number of cache lines touched by do_gettimeofday. + * Both by collecting all of the data in one cache line and + * by touching only one TOC entry on ppc64. + */ +struct gettimeofday_vars { + u64 tb_to_xs; + u64 stamp_xsec; + u64 tb_orig_stamp; +}; + +struct gettimeofday_struct { + unsigned long tb_ticks_per_sec; + struct gettimeofday_vars vars[2]; + struct gettimeofday_vars * volatile varp; + unsigned var_idx; + unsigned tb_to_us; +}; + +struct div_result { + u64 result_high; + u64 result_low; +}; + +/* Accessor functions for the timebase (RTC on 601) registers. */ +/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ +#ifdef CONFIG_6xx +#define __USE_RTC() cpu_has_feature(CPU_FTR_USE_TB) +#else +#define __USE_RTC() 0 +#endif + +/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */ +static inline unsigned long get_tbl(void) +{ + unsigned long tbl; + +#if defined(CONFIG_403GCX) + asm volatile("mfspr %0, 0x3dd" : "=r" (tbl)); +#else + asm volatile("mftb %0" : "=r" (tbl)); +#endif + return tbl; +} + +static inline unsigned int get_tbu(void) +{ + unsigned int tbu; + +#if defined(CONFIG_403GCX) + asm volatile("mfspr %0, 0x3dc" : "=r" (tbu)); +#else + asm volatile("mftbu %0" : "=r" (tbu)); +#endif + return tbu; +} + +static inline unsigned int get_rtcl(void) +{ + unsigned int rtcl; + + asm volatile("mfrtcl %0" : "=r" (rtcl)); + return rtcl; +} + +#ifdef CONFIG_PPC64 +static inline u64 get_tb(void) +{ + return mftb(); +} +#else +static inline u64 get_tb(void) +{ + unsigned int tbhi, tblo, tbhi2; + + do { + tbhi = get_tbu(); + tblo = get_tbl(); + tbhi2 = get_tbu(); + } while (tbhi != tbhi2); + + return ((u64)tbhi << 32) | tblo; +} +#endif + +static inline void set_tb(unsigned int upper, unsigned int lower) +{ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, upper); + mtspr(SPRN_TBWL, lower); +} + +/* Accessor functions for the decrementer register. + * The 4xx doesn't even have a decrementer. I tried to use the + * generic timer interrupt code, which seems OK, with the 4xx PIT + * in auto-reload mode. The problem is PIT stops counting when it + * hits zero. If it would wrap, we could use it just like a decrementer. + */ +static inline unsigned int get_dec(void) +{ +#if defined(CONFIG_40x) + return (mfspr(SPRN_PIT)); +#else + return (mfspr(SPRN_DEC)); +#endif +} + +static inline void set_dec(int val) +{ +#if defined(CONFIG_40x) + return; /* Have to let it auto-reload */ +#elif defined(CONFIG_8xx_CPU6) + set_dec_cpu6(val); +#else +#ifdef CONFIG_PPC_ISERIES + struct paca_struct *lpaca = get_paca(); + int cur_dec; + + if (lpaca->lppaca.shared_proc) { + lpaca->lppaca.virtual_decr = val; + cur_dec = get_dec(); + if (cur_dec > val) + HvCall_setVirtualDecr(); + } else +#endif + mtspr(SPRN_DEC, val); +#endif /* not 40x or 8xx_CPU6 */ +} + +static inline unsigned long tb_ticks_since(unsigned long tstamp) +{ + if (__USE_RTC()) { + int delta = get_rtcl() - (unsigned int) tstamp; + return delta < 0 ? delta + 1000000000 : delta; + } + return get_tbl() - tstamp; +} + +#define mulhwu(x,y) \ +({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) + +#ifdef CONFIG_PPC64 +#define mulhdu(x,y) \ +({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) +#else +extern u64 mulhdu(u64, u64); +#endif + +unsigned mulhwu_scale_factor(unsigned, unsigned); +void div128_by_32(u64 dividend_high, u64 dividend_low, + unsigned divisor, struct div_result *dr); + +/* Used to store Processor Utilization register (purr) values */ + +struct cpu_usage { + u64 current_tb; /* Holds the current purr register values */ +}; + +DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array); + +#endif /* __KERNEL__ */ +#endif /* __PPC64_TIME_H */ diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h deleted file mode 100644 index c6c762cad8b0..000000000000 --- a/include/asm-ppc64/time.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Common time prototypes and such for all ppc machines. - * - * Written by Cort Dougan (cort@cs.nmt.edu) to merge - * Paul Mackerras' version and mine for PReP and Pmac. - * - * 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. - */ - -#ifndef __PPC64_TIME_H -#define __PPC64_TIME_H - -#ifdef __KERNEL__ -#include -#include -#include - -#include -#include -#include - -/* time.c */ -extern unsigned long tb_ticks_per_jiffy; -extern unsigned long tb_ticks_per_usec; -extern unsigned long tb_ticks_per_sec; -extern unsigned long tb_to_xs; -extern unsigned tb_to_us; -extern unsigned long tb_last_stamp; - -struct rtc_time; -extern void to_tm(int tim, struct rtc_time * tm); -extern time_t last_rtc_update; - -void generic_calibrate_decr(void); -void setup_default_decr(void); - -/* Some sane defaults: 125 MHz timebase, 1GHz processor */ -extern unsigned long ppc_proc_freq; -#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) -extern unsigned long ppc_tb_freq; -#define DEFAULT_TB_FREQ 125000000UL - -/* - * By putting all of this stuff into a single struct we - * reduce the number of cache lines touched by do_gettimeofday. - * Both by collecting all of the data in one cache line and - * by touching only one TOC entry - */ -struct gettimeofday_vars { - unsigned long tb_to_xs; - unsigned long stamp_xsec; - unsigned long tb_orig_stamp; -}; - -struct gettimeofday_struct { - unsigned long tb_ticks_per_sec; - struct gettimeofday_vars vars[2]; - struct gettimeofday_vars * volatile varp; - unsigned var_idx; - unsigned tb_to_us; -}; - -struct div_result { - unsigned long result_high; - unsigned long result_low; -}; - -int via_calibrate_decr(void); - -static __inline__ unsigned long get_tb(void) -{ - return mftb(); -} - -/* Accessor functions for the decrementer register. */ -static __inline__ unsigned int get_dec(void) -{ - return (mfspr(SPRN_DEC)); -} - -static __inline__ void set_dec(int val) -{ -#ifdef CONFIG_PPC_ISERIES - struct paca_struct *lpaca = get_paca(); - int cur_dec; - - if (lpaca->lppaca.shared_proc) { - lpaca->lppaca.virtual_decr = val; - cur_dec = get_dec(); - if (cur_dec > val) - HvCall_setVirtualDecr(); - } else -#endif - mtspr(SPRN_DEC, val); -} - -static inline unsigned long tb_ticks_since(unsigned long tstamp) -{ - return get_tb() - tstamp; -} - -#define mulhwu(x,y) \ -({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) -#define mulhdu(x,y) \ -({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) - - -unsigned mulhwu_scale_factor(unsigned, unsigned); -void div128_by_32( unsigned long dividend_high, unsigned long dividend_low, - unsigned divisor, struct div_result *dr ); - -/* Used to store Processor Utilization register (purr) values */ - -struct cpu_usage { - u64 current_tb; /* Holds the current purr register values */ -}; - -DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array); - -#endif /* __KERNEL__ */ -#endif /* __PPC64_TIME_H */ From a4bcc95a3ad0ccba6d7b39442dfb81cc57bb7121 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 09:24:18 +1000 Subject: [PATCH 0347/1940] powerpc: Fix a branch-too-far link error for 32-bit targets Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/entry_32.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 094eea6fbd69..fc9dded9ac04 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -633,7 +633,8 @@ sigreturn_exit: rlwinm r12,r1,0,0,18 /* current_thread_info() */ lwz r9,TI_FLAGS(r12) andi. r0,r9,_TIF_SYSCALL_T_OR_A - bnel- do_syscall_trace_leave + beq+ ret_from_except_full + bl do_syscall_trace_leave /* fall through */ .globl ret_from_except_full From 344480b99730bfd205e306d3fd168cdcebe83425 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 09:37:02 +1000 Subject: [PATCH 0348/1940] powerpc: Fix a corner case in __div64_32 The code was incorrectly doing a division by 0 in the case where the denominator was 0x100000000 and the divisor was 0xffffffff. Thanks to Fred Liu of Motorola for pointing this out. Signed-off-by: Paul Mackerras --- arch/powerpc/lib/div64.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/lib/div64.S b/arch/powerpc/lib/div64.S index 3527569e9926..83d9832fd919 100644 --- a/arch/powerpc/lib/div64.S +++ b/arch/powerpc/lib/div64.S @@ -33,9 +33,10 @@ _GLOBAL(__div64_32) cntlzw r0,r5 # we are shifting the dividend right li r10,-1 # to make it < 2^32, and shifting srw r10,r10,r0 # the divisor right the same amount, - add r9,r4,r10 # rounding up (so the estimate cannot + addc r9,r4,r10 # rounding up (so the estimate cannot andc r11,r6,r10 # ever be too large, only too small) andc r9,r9,r10 + addze r9,r9 or r11,r5,r11 rotlw r9,r9,r0 rotlw r11,r11,r0 From b15125fa81a522882247242e569bc7035e28cc82 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 18 Oct 2005 17:42:09 -0500 Subject: [PATCH 0349/1940] [PATCH] powerpc: Some more fixes to allow building for a Book-E processor Some minor fixes that are needed if we are building for a book-e processor. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/mm/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 14b2ffb6c2d8..93441e7a2921 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -7,14 +7,13 @@ EXTRA_CFLAGS += -mno-minimal-toc endif obj-y := fault.o mem.o lmb.o -obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o \ - tlb_32.o +obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \ hash_utils_64.o hash_low_64.o tlb_64.o \ slb_low.o slb.o stab.o mmap.o imalloc.o \ $(hash-y) -obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o +obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o obj-$(CONFIG_40x) += 4xx_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o From 3d904eef54fd145e2ae5fadb52d2c39bc49339ae Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 18 Oct 2005 17:42:41 -0500 Subject: [PATCH 0350/1940] [PATCH] ppc32: replace use of _GLOBAL with .globl for ppc32 The _GLOBAL() macro is for text symbols only. Changed to using .globl for .data symbols. This is also needed in ppc32 land to allow FSL Book-E, 40x, and 44x to work. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/head_44x.S | 18 +++++++++++------- arch/ppc/kernel/head_4xx.S | 16 +++++++++++----- arch/ppc/kernel/head_fsl_booke.S | 17 +++++++++++------ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index b1b9dc08abca..8b49679fad54 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S @@ -743,14 +743,18 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 /* * To support >32-bit physical addresses, we use an 8KB pgdir. */ -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 8192 /* Reserved 4k for the critical exception stack & 4k for the machine @@ -759,13 +763,15 @@ _GLOBAL(swapper_pg_dir) .align 12 exception_stack_bottom: .space BOOKE_EXCEPTION_STACK_SIZE -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* * This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* @@ -774,5 +780,3 @@ _GLOBAL(cmd_line) */ abatron_pteptrs: .space 8 - - diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S index 5772ce97e24e..10c261c67021 100644 --- a/arch/ppc/kernel/head_4xx.S +++ b/arch/ppc/kernel/head_4xx.S @@ -988,10 +988,14 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 4096 @@ -1001,12 +1005,14 @@ _GLOBAL(swapper_pg_dir) exception_stack_bottom: .space 4096 critical_stack_top: -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* Room for two PTE pointers, usually the kernel and current user pointers diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index 53949811efda..5063c603fad4 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S @@ -1028,10 +1028,14 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data -_GLOBAL(sdata) -_GLOBAL(empty_zero_page) + .align 12 + .globl sdata +sdata: + .globl empty_zero_page +empty_zero_page: .space 4096 -_GLOBAL(swapper_pg_dir) + .globl swapper_pg_dir +swapper_pg_dir: .space 4096 /* Reserved 4k for the critical exception stack & 4k for the machine @@ -1040,13 +1044,15 @@ _GLOBAL(swapper_pg_dir) .align 12 exception_stack_bottom: .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS -_GLOBAL(exception_stack_top) + .globl exception_stack_top +exception_stack_top: /* * This space gets a copy of optional info passed to us by the bootstrap * which is used to pass parameters into the kernel like root=/dev/sda1, etc. */ -_GLOBAL(cmd_line) + .globl cmd_line +cmd_line: .space 512 /* @@ -1055,4 +1061,3 @@ _GLOBAL(cmd_line) */ abatron_pteptrs: .space 8 - From f7f6f4fea68d9981d65f99a589ad85f510924d99 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 19 Oct 2005 14:53:32 +1000 Subject: [PATCH 0351/1940] [PATCH] powerpc: Merge ppc64 pmc.[ch] with ppc32 perfmon.[ch] This patches the ppc32 and ppc64 versions of the headers and .c files with helper functions for manipulating the performance counting hardware. As a side effect, it removes use of the term "perfmon" from ppc32, thus avoiding confusion with the unrelated performance counter interface from HP Labs also called "perfmon". Built, but not booted, for g5, pSeries, iSeries, and 32-bit Powermac with both ARCH=powerpc and ARCH=ppc{,64} as appropriate. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/{ppc64 => powerpc}/kernel/pmc.c | 26 +++++- arch/powerpc/kernel/traps.c | 3 +- arch/powerpc/oprofile/common.c | 4 - arch/powerpc/oprofile/op_model_fsl_booke.c | 2 +- arch/ppc/kernel/Makefile | 4 +- arch/ppc/kernel/perfmon.c | 96 ---------------------- arch/ppc/kernel/perfmon_fsl_booke.c | 2 +- arch/ppc/kernel/traps.c | 2 +- arch/ppc64/kernel/Makefile | 2 +- include/{asm-ppc64 => asm-powerpc}/pmc.h | 21 ++++- include/asm-ppc/perfmon.h | 22 ----- 12 files changed, 51 insertions(+), 135 deletions(-) rename arch/{ppc64 => powerpc}/kernel/pmc.c (76%) delete mode 100644 arch/ppc/kernel/perfmon.c rename include/{asm-ppc64 => asm-powerpc}/pmc.h (66%) delete mode 100644 include/asm-ppc/perfmon.h diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b347ac320252..6b0f176265e3 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -11,7 +11,7 @@ CFLAGS_btext.o += -fPIC endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ - signal_32.o + signal_32.o pmc.o obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o ptrace32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o diff --git a/arch/ppc64/kernel/pmc.c b/arch/powerpc/kernel/pmc.c similarity index 76% rename from arch/ppc64/kernel/pmc.c rename to arch/powerpc/kernel/pmc.c index 944d7df7935f..2d333cc84082 100644 --- a/arch/ppc64/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c @@ -1,7 +1,10 @@ /* - * linux/arch/ppc64/kernel/pmc.c + * arch/powerpc/kernel/pmc.c * * Copyright (C) 2004 David Gibson, IBM Corporation. + * Includes code formerly from arch/ppc/kernel/perfmon.c: + * Author: Andy Fleming + * Copyright (c) 2004 Freescale Semiconductor, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,6 +20,20 @@ #include #include +#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) +static void dummy_perf(struct pt_regs *regs) +{ + unsigned int pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 &= ~PMGC0_PMIE; + mtpmr(PMRN_PMGC0, pmgc0); +} +#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) + +#ifndef MMCR0_PMAO +#define MMCR0_PMAO 0 +#endif + /* Ensure exceptions are disabled */ static void dummy_perf(struct pt_regs *regs) { @@ -25,6 +42,11 @@ static void dummy_perf(struct pt_regs *regs) mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO); mtspr(SPRN_MMCR0, mmcr0); } +#else +static void dummy_perf(struct pt_regs *regs) +{ +} +#endif static DEFINE_SPINLOCK(pmc_owner_lock); static void *pmc_owner_caller; /* mostly for debugging */ @@ -66,6 +88,7 @@ void release_pmc_hardware(void) } EXPORT_SYMBOL_GPL(release_pmc_hardware); +#ifdef CONFIG_PPC64 void power4_enable_pmcs(void) { unsigned long hid0; @@ -86,3 +109,4 @@ void power4_enable_pmcs(void) "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0): "memory"); } +#endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 6a881e3ea01d..f87580382da4 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -40,9 +40,9 @@ #include #include #include +#include #ifdef CONFIG_PPC32 #include -#include #endif #ifdef CONFIG_PMAC_BACKLIGHT #include @@ -51,7 +51,6 @@ #include #include #include -#include #endif #ifdef CONFIG_PPC64 /* XXX */ diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 0ec12c8f2c01..af2c05d20ba5 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -22,11 +22,7 @@ #include #include #include -#ifdef __powerpc64__ #include -#else /* __powerpc64__ */ -#include -#endif /* __powerpc64__ */ #include #include diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c index 1917f8df8a8b..86124a94c9af 100644 --- a/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include static unsigned long reset_value[OP_MAX_COUNTER]; diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index ccbc442c9ed3..b35346df1e37 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -15,7 +15,7 @@ extra-y += vmlinux.lds obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o align.o \ setup.o \ - ppc_htab.o perfmon.o + ppc_htab.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_POWER4) += cpu_setup_power4.o @@ -38,7 +38,7 @@ endif else obj-y := irq.o idle.o \ - align.o perfmon.o + align.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c deleted file mode 100644 index c9a38dd0cdc4..000000000000 --- a/arch/ppc/kernel/perfmon.c +++ /dev/null @@ -1,96 +0,0 @@ -/* kernel/perfmon.c - * PPC 32 Performance Monitor Infrastructure - * - * Author: Andy Fleming - * Copyright (c) 2004 Freescale Semiconductor, 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 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* A lock to regulate grabbing the interrupt */ -DEFINE_SPINLOCK(perfmon_lock); - -#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200) -static void dummy_perf(struct pt_regs *regs) -{ - unsigned int pmgc0 = mfpmr(PMRN_PMGC0); - - pmgc0 &= ~PMGC0_PMIE; - mtpmr(PMRN_PMGC0, pmgc0); -} - -#elif defined(CONFIG_6xx) -/* Ensure exceptions are disabled */ -static void dummy_perf(struct pt_regs *regs) -{ - unsigned int mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 &= ~MMCR0_PMXE; - mtspr(SPRN_MMCR0, mmcr0); -} -#else -static void dummy_perf(struct pt_regs *regs) -{ -} -#endif - -void (*perf_irq)(struct pt_regs *) = dummy_perf; - -/* Grab the interrupt, if it's free. - * Returns 0 on success, -1 if the interrupt is taken already */ -int reserve_pmc_hardware(void (*handler)(struct pt_regs *)) -{ - int err = 0; - - spin_lock(&perfmon_lock); - - if (perf_irq == dummy_perf) - perf_irq = handler; - else { - pr_info("perfmon irq already handled by %p\n", perf_irq); - err = -EBUSY; - } - - spin_unlock(&perfmon_lock); - - return err; -} - -void release_pmc_hardware(void) -{ - spin_lock(&perfmon_lock); - - perf_irq = dummy_perf; - - spin_unlock(&perfmon_lock); -} - -EXPORT_SYMBOL(perf_irq); -EXPORT_SYMBOL(reserve_pmc_hardware); -EXPORT_SYMBOL(release_pmc_hardware); diff --git a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/ppc/kernel/perfmon_fsl_booke.c index 03526bfb0840..32455dfcc36b 100644 --- a/arch/ppc/kernel/perfmon_fsl_booke.c +++ b/arch/ppc/kernel/perfmon_fsl_booke.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include static inline u32 get_pmlca(int ctr); static inline void set_pmlca(int ctr, u32 pmlca); diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 3145e9773db9..5e4bf88a1ef5 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -41,7 +41,7 @@ #ifdef CONFIG_PMAC_BACKLIGHT #include #endif -#include +#include #ifdef CONFIG_XMON extern int xmon_bpt(struct pt_regs *regs); diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 18f477fa1df2..6cce419f4b09 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -17,7 +17,7 @@ obj-y += irq.o idle.o dma.o \ udbg.o ioctl32.o \ rtc.o \ cpu_setup_power4.o \ - iommu.o sysfs.o vdso.o pmc.o firmware.o + iommu.o sysfs.o vdso.o firmware.o obj-y += vdso32/ vdso64/ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o diff --git a/include/asm-ppc64/pmc.h b/include/asm-powerpc/pmc.h similarity index 66% rename from include/asm-ppc64/pmc.h rename to include/asm-powerpc/pmc.h index d1d297dbccfe..2f3c3fc2b796 100644 --- a/include/asm-ppc64/pmc.h +++ b/include/asm-powerpc/pmc.h @@ -16,8 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _PPC64_PMC_H -#define _PPC64_PMC_H +#ifndef _POWERPC_PMC_H +#define _POWERPC_PMC_H #include @@ -26,6 +26,21 @@ typedef void (*perf_irq_t)(struct pt_regs *); int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); +#ifdef CONFIG_PPC64 void power4_enable_pmcs(void); +#endif -#endif /* _PPC64_PMC_H */ +#ifdef CONFIG_FSL_BOOKE +void init_pmc_stop(int ctr); +void set_pmc_event(int ctr, int event); +void set_pmc_user_kernel(int ctr, int user, int kernel); +void set_pmc_marked(int ctr, int mark0, int mark1); +void pmc_start_ctr(int ctr, int enable); +void pmc_start_ctrs(int enable); +void pmc_stop_ctrs(void); +void dump_pmcs(void); + +extern struct op_powerpc_model op_model_fsl_booke; +#endif + +#endif /* _POWERPC_PMC_H */ diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h deleted file mode 100644 index 2ae031594a4e..000000000000 --- a/include/asm-ppc/perfmon.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __PERFMON_H -#define __PERFMON_H - -extern void (*perf_irq)(struct pt_regs *); - -int reserve_pmc_hardware(void (*handler)(struct pt_regs *)); -void release_pmc_hardware(void); - -#ifdef CONFIG_FSL_BOOKE -void init_pmc_stop(int ctr); -void set_pmc_event(int ctr, int event); -void set_pmc_user_kernel(int ctr, int user, int kernel); -void set_pmc_marked(int ctr, int mark0, int mark1); -void pmc_start_ctr(int ctr, int enable); -void pmc_start_ctrs(int enable); -void pmc_stop_ctrs(void); -void dump_pmcs(void); - -extern struct op_powerpc_model op_model_fsl_booke; -#endif - -#endif /* __PERFMON_H */ From 971dc77b64db9466f5caab56019e62a93c0ddfc5 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 19 Oct 2005 18:45:03 -0500 Subject: [PATCH 0352/1940] [PATCH] powerpc: Merge types.h This patch merges types.h into include/asm-powerpc. The only real change is the removal of the include of linux/config.h from the 32-bit version - it doesn't appear to be necessary. This patch has been built on several different 32 and 64-bit platforms, and booted on mpc8540_ads. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/types.h | 31 +++++++++- include/asm-ppc/types.h | 69 ---------------------- 2 files changed, 28 insertions(+), 72 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/types.h (74%) delete mode 100644 include/asm-ppc/types.h diff --git a/include/asm-ppc64/types.h b/include/asm-powerpc/types.h similarity index 74% rename from include/asm-ppc64/types.h rename to include/asm-powerpc/types.h index bf294c1761b2..7d803cb547bb 100644 --- a/include/asm-ppc64/types.h +++ b/include/asm-powerpc/types.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_TYPES_H -#define _PPC64_TYPES_H +#ifndef _ASM_POWERPC_TYPES_H +#define _ASM_POWERPC_TYPES_H #ifndef __ASSEMBLY__ @@ -16,7 +16,11 @@ * 2 of the License, or (at your option) any later version. */ +#ifdef __powerpc64__ typedef unsigned int umode_t; +#else +typedef unsigned short umode_t; +#endif /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -32,8 +36,15 @@ typedef unsigned short __u16; typedef __signed__ int __s32; typedef unsigned int __u32; +#ifdef __powerpc64__ typedef __signed__ long __s64; typedef unsigned long __u64; +#else +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif +#endif /* __powerpc64__ */ typedef struct { __u32 u[4]; @@ -45,7 +56,11 @@ typedef struct { /* * These aren't exported outside the kernel to avoid name space clashes */ +#ifdef __powerpc64__ #define BITS_PER_LONG 64 +#else +#define BITS_PER_LONG 32 +#endif #ifndef __ASSEMBLY__ @@ -58,8 +73,13 @@ typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; +#ifdef __powerpc64__ typedef signed long s64; typedef unsigned long u64; +#else +typedef signed long long s64; +typedef unsigned long long u64; +#endif typedef __vector128 vector128; @@ -72,8 +92,13 @@ typedef struct { unsigned long env; } func_descr_t; +#ifdef CONFIG_LBD +typedef u64 sector_t; +#define HAVE_SECTOR_T +#endif + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -#endif /* _PPC64_TYPES_H */ +#endif /* _ASM_POWERPC_TYPES_H */ diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h deleted file mode 100644 index 77dc24d7d2ad..000000000000 --- a/include/asm-ppc/types.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _PPC_TYPES_H -#define _PPC_TYPES_H - -#ifndef __ASSEMBLY__ - -typedef __signed__ char __s8; -typedef unsigned char __u8; - -typedef __signed__ short __s16; -typedef unsigned short __u16; - -typedef __signed__ int __s32; -typedef unsigned int __u32; - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -typedef __signed__ long long __s64; -typedef unsigned long long __u64; -#endif - -typedef struct { - __u32 u[4]; -} __vector128; - -/* - * XXX allowed outside of __KERNEL__ for now, until glibc gets - * a proper set of asm headers of its own. -- paulus - */ -typedef unsigned short umode_t; - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ -/* - * These aren't exported outside the kernel to avoid name space clashes - */ -#define BITS_PER_LONG 32 - -#ifndef __ASSEMBLY__ - -#include - -typedef signed char s8; -typedef unsigned char u8; - -typedef signed short s16; -typedef unsigned short u16; - -typedef signed int s32; -typedef unsigned int u32; - -typedef signed long long s64; -typedef unsigned long long u64; - -typedef __vector128 vector128; - -/* DMA addresses are 32-bits wide */ -typedef u32 dma_addr_t; -typedef u64 dma64_addr_t; - -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif From d8699e65c6bc0a81b5e679ca5b135bfe3c3fb483 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 17:02:01 +1000 Subject: [PATCH 0353/1940] ppc64: Change ppc_md.get_cpuinfo to ppc_md.show_cpuinfo ... for consistency with ppc32; also add in ppc32's show_percpuinfo function. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_64.c | 4 ++-- arch/powerpc/platforms/iseries/setup.c | 4 ++-- arch/ppc64/kernel/bpa_setup.c | 4 ++-- arch/ppc64/kernel/pmac_setup.c | 2 +- arch/ppc64/kernel/setup.c | 4 ++-- include/asm-powerpc/machdep.h | 7 ++----- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6f29614c3581..97ffdcf09c03 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -704,8 +704,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_id == NR_CPUS) { seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - if (ppc_md.get_cpuinfo != NULL) - ppc_md.get_cpuinfo(m); + if (ppc_md.show_cpuinfo != NULL) + ppc_md.show_cpuinfo(m); return 0; } diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 41cd5b689545..b27901481782 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -587,7 +587,7 @@ static void __init iSeries_setup_arch(void) printk("Processor version = %x\n", systemcfg->processor); } -static void iSeries_get_cpuinfo(struct seq_file *m) +static void iSeries_show_cpuinfo(struct seq_file *m) { seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n"); } @@ -760,7 +760,7 @@ static int __init iseries_probe(int platform) struct machdep_calls __initdata iseries_md = { .setup_arch = iSeries_setup_arch, - .get_cpuinfo = iSeries_get_cpuinfo, + .show_cpuinfo = iSeries_show_cpuinfo, .init_IRQ = iSeries_init_IRQ, .get_irq = iSeries_get_irq, .init_early = iSeries_init_early, diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c index 017cf23e91fa..c2dc8f282eb8 100644 --- a/arch/ppc64/kernel/bpa_setup.c +++ b/arch/ppc64/kernel/bpa_setup.c @@ -55,7 +55,7 @@ #define DBG(fmt...) #endif -void bpa_get_cpuinfo(struct seq_file *m) +void bpa_show_cpuinfo(struct seq_file *m) { struct device_node *root; const char *model = ""; @@ -129,7 +129,7 @@ struct machdep_calls __initdata bpa_md = { .probe = bpa_probe, .setup_arch = bpa_setup_arch, .init_early = bpa_init_early, - .get_cpuinfo = bpa_get_cpuinfo, + .show_cpuinfo = bpa_show_cpuinfo, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt, diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index be4c1693d149..c059805d8cce 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -505,7 +505,7 @@ struct machdep_calls __initdata pmac_md = { .probe = pmac_probe, .setup_arch = pmac_setup_arch, .init_early = pmac_init_early, - .get_cpuinfo = pmac_show_cpuinfo, + .show_cpuinfo = pmac_show_cpuinfo, .init_IRQ = pmac_init_IRQ, .get_irq = mpic_get_irq, .pcibios_fixup = pmac_pcibios_fixup, diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 3e6c1547b718..42019be0c6ad 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -703,8 +703,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_id == NR_CPUS) { seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - if (ppc_md.get_cpuinfo != NULL) - ppc_md.get_cpuinfo(m); + if (ppc_md.show_cpuinfo != NULL) + ppc_md.show_cpuinfo(m); return 0; } diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index f060553b997a..8a0969b6243c 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -86,7 +86,8 @@ struct machdep_calls { void (*setup_arch)(void); void (*init_early)(void); /* Optional, may be NULL. */ - void (*get_cpuinfo)(struct seq_file *m); + void (*show_cpuinfo)(struct seq_file *m); + void (*show_percpuinfo)(struct seq_file *m, int i); void (*init_IRQ)(void); int (*get_irq)(struct pt_regs *); @@ -153,10 +154,6 @@ struct machdep_calls { void (*enable_pmcs)(void); #ifdef CONFIG_PPC32 /* XXX for now */ - /* Optional, may be NULL. */ - int (*show_cpuinfo)(struct seq_file *m); - int (*show_percpuinfo)(struct seq_file *m, int i); - /* A general init function, called by ppc_init in init/main.c. May be NULL. */ void (*init)(void); From a9c59264690aea9d0df2d2d76683bc39ec6b7288 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 17:09:51 +1000 Subject: [PATCH 0354/1940] powerpc: Move smp_mpic_message_pass into mpic.c Having it here rather than in arch/ppc64/kernel/smp.c means that we can use it on 32-bit SMP systems easily with ARCH=powerpc. Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 21 +++++++++++++++++++++ arch/ppc64/kernel/smp.c | 22 ---------------------- include/asm-powerpc/mpic.h | 3 +++ include/asm-ppc64/smp.h | 1 - 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 02b4d2488bfd..3948e759d41a 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -904,4 +904,25 @@ void mpic_request_ipis(void) printk("IPIs requested... \n"); } + +void smp_mpic_message_pass(int target, int msg) +{ + /* make sure we're sending something that translates to an IPI */ + if ((unsigned int)msg > 3) { + printk("SMP %d: smp_message_pass: unknown msg %d\n", + smp_processor_id(), msg); + return; + } + switch (target) { + case MSG_ALL: + mpic_send_ipi(msg, 0xffffffff); + break; + case MSG_ALL_BUT_SELF: + mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id())); + break; + default: + mpic_send_ipi(msg, 1 << target); + break; + } +} #endif /* CONFIG_SMP */ diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 6f4f3da12a63..192e3239fadc 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -69,28 +69,6 @@ void smp_call_function_interrupt(void); int smt_enabled_at_boot = 1; #ifdef CONFIG_MPIC -void smp_mpic_message_pass(int target, int msg) -{ - /* make sure we're sending something that translates to an IPI */ - if ( msg > 0x3 ){ - printk("SMP %d: smp_message_pass: unknown msg %d\n", - smp_processor_id(), msg); - return; - } - switch ( target ) - { - case MSG_ALL: - mpic_send_ipi(msg, 0xffffffff); - break; - case MSG_ALL_BUT_SELF: - mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id())); - break; - default: - mpic_send_ipi(msg, 1 << target); - break; - } -} - int __init smp_mpic_probe(void) { int nr_cpus; diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 6b558aeb9cb9..7083d1f74260 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h @@ -273,6 +273,9 @@ extern void mpic_request_ipis(void); /* Send an IPI (non offseted number 0..3) */ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask); +/* Send a message (IPI) to a given target (cpu number or MSG_*) */ +void smp_mpic_message_pass(int target, int msg); + /* Fetch interrupt from a given mpic */ extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); /* This one gets to the primary mpic */ diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index d86f742e9a21..c5e9052e7967 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -77,7 +77,6 @@ extern int smt_enabled_at_boot; extern int smp_mpic_probe(void); extern void smp_mpic_setup_cpu(int cpu); -extern void smp_mpic_message_pass(int target, int msg); extern void smp_generic_kick_cpu(int nr); extern void smp_generic_give_timebase(void); From 0dd194d02d2584c34e06ddd26c7a7896a5fa1974 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 20:48:19 +1000 Subject: [PATCH 0355/1940] powerpc: Fix places where ppc_md.show_[per]cpuinfo was treated as int I missed a few places where ppc code was still assuming that the ppc_md.show_[per]cpuinfo functions returned int. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 14 ++---- arch/powerpc/platforms/powermac/setup.c | 66 +++++++------------------ arch/powerpc/platforms/pseries/setup.c | 4 +- 3 files changed, 26 insertions(+), 58 deletions(-) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index b95f7cf693e6..b9269c038af3 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -150,7 +150,6 @@ extern u32 cpu_temp_both(unsigned long cpu); int show_cpuinfo(struct seq_file *m, void *v) { int i = (int) v - 1; - int err = 0; unsigned int pvr; unsigned short maj, min; unsigned long lpj; @@ -167,8 +166,8 @@ int show_cpuinfo(struct seq_file *m, void *v) #endif /* CONFIG_SMP */ if (ppc_md.show_cpuinfo != NULL) - err = ppc_md.show_cpuinfo(m); - return err; + ppc_md.show_cpuinfo(m); + return 0; } #ifdef CONFIG_SMP @@ -210,15 +209,12 @@ int show_cpuinfo(struct seq_file *m, void *v) } #endif /* CONFIG_TAU */ - if (ppc_md.show_percpuinfo != NULL) { - err = ppc_md.show_percpuinfo(m, i); - if (err) - return err; - } + if (ppc_md.show_percpuinfo != NULL) + ppc_md.show_percpuinfo(m, i); /* If we are a Freescale core do a simple check so * we dont have to keep adding cases in the future */ - if ((PVR_VER(pvr) & 0x8000) == 0x8000) { + if (PVR_VER(pvr) & 0x8000) { maj = PVR_MAJ(pvr); min = PVR_MIN(pvr); } else { diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index b6414e7c37d4..0bad53fa36ef 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -104,24 +104,26 @@ extern struct smp_ops_t psurge_smp_ops; extern struct smp_ops_t core99_smp_ops; #endif /* CONFIG_SMP */ -static int -pmac_show_cpuinfo(struct seq_file *m) +static void pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; char *pp; int plen; - int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, - NULL, PMAC_MB_INFO_MODEL, 0); - unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO, - NULL, PMAC_MB_INFO_FLAGS, 0); + int mbmodel; + unsigned int mbflags; char* mbname; - if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) + mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, + PMAC_MB_INFO_MODEL, 0); + mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, + PMAC_MB_INFO_FLAGS, 0); + if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, + (long) &mbname) != 0) mbname = "Unknown"; /* find motherboard type */ seq_printf(m, "machine\t\t: "); - np = find_devices("device-tree"); + np = of_find_node_by_path("/"); if (np != NULL) { pp = (char *) get_property(np, "model", NULL); if (pp != NULL) @@ -139,6 +141,7 @@ pmac_show_cpuinfo(struct seq_file *m) } seq_printf(m, "\n"); } + of_node_put(np); } else seq_printf(m, "PowerMac\n"); @@ -147,10 +150,10 @@ pmac_show_cpuinfo(struct seq_file *m) seq_printf(m, "pmac flags\t: %08x\n", mbflags); /* find l2 cache info */ - np = find_devices("l2-cache"); - if (np == 0) - np = find_type_devices("cache"); - if (np != 0) { + np = of_find_node_by_name(NULL, "l2-cache"); + if (np == NULL) + np = of_find_node_by_type(NULL, "cache"); + if (np != NULL) { unsigned int *ic = (unsigned int *) get_property(np, "i-cache-size", NULL); unsigned int *dc = (unsigned int *) @@ -170,56 +173,25 @@ pmac_show_cpuinfo(struct seq_file *m) if (pp) seq_printf(m, " %s", pp); seq_printf(m, "\n"); - } - - /* find ram info */ - np = find_devices("memory"); - if (np != 0) { - int n; - struct reg_property *reg = (struct reg_property *) - get_property(np, "reg", &n); - - if (reg != 0) { - unsigned long total = 0; - - for (n /= sizeof(struct reg_property); n > 0; --n) - total += (reg++)->size; - seq_printf(m, "memory\t\t: %luMB\n", total >> 20); - } - } - - /* Checks "l2cr-value" property in the registry */ - np = find_devices("cpus"); - if (np == 0) - np = find_type_devices("cpu"); - if (np != 0) { - unsigned int *l2cr = (unsigned int *) - get_property(np, "l2cr-value", NULL); - if (l2cr != 0) { - seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr); - } + of_node_put(np); } /* Indicate newworld/oldworld */ seq_printf(m, "pmac-generation\t: %s\n", pmac_newworld ? "NewWorld" : "OldWorld"); - - - return 0; } -static int -pmac_show_percpuinfo(struct seq_file *m, int i) +static void pmac_show_percpuinfo(struct seq_file *m, int i) { #ifdef CONFIG_CPU_FREQ_PMAC extern unsigned int pmac_get_one_cpufreq(int i); unsigned int freq = pmac_get_one_cpufreq(i); if (freq != 0) { seq_printf(m, "clock\t\t: %dMHz\n", freq/1000); - return 0; + return; } #endif /* CONFIG_CPU_FREQ_PMAC */ - return of_show_percpuinfo(m, i); + of_show_percpuinfo(m, i); } static volatile u32 *sysctrl_regs; diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 0c84a44b43b4..c53dbbb4490a 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -90,7 +90,7 @@ static void pseries_dedicated_idle(void); static volatile void __iomem * chrp_int_ack_special; struct mpic *pSeries_mpic; -void pSeries_get_cpuinfo(struct seq_file *m) +void pSeries_show_cpuinfo(struct seq_file *m) { struct device_node *root; const char *model = ""; @@ -599,7 +599,7 @@ struct machdep_calls __initdata pSeries_md = { .probe = pSeries_probe, .setup_arch = pSeries_setup_arch, .init_early = pSeries_init_early, - .get_cpuinfo = pSeries_get_cpuinfo, + .show_cpuinfo = pSeries_show_cpuinfo, .log_error = pSeries_log_error, .pcibios_fixup = pSeries_final_fixup, .pci_probe_mode = pSeries_pci_probe_mode, From ff065ddd96c233d27322de493fa023357939c888 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 20:53:39 +1000 Subject: [PATCH 0356/1940] powerpc: Merge various powermac-related header files. Except for smu.h, which moved from asm-ppc64 to asm-powerpc, all of these moved from asm-ppc to asm-powerpc. In each case the asm-ppc64 version (if there was one) was just a single line including the asm-ppc version. Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/dbdma.h | 0 include/{asm-ppc => asm-powerpc}/heathrow.h | 0 include/{asm-ppc => asm-powerpc}/keylargo.h | 0 include/{asm-ppc => asm-powerpc}/macio.h | 0 include/{asm-ppc => asm-powerpc}/mediabay.h | 0 include/{asm-ppc => asm-powerpc}/ohare.h | 0 include/{asm-ppc => asm-powerpc}/pmac_feature.h | 0 include/{asm-ppc => asm-powerpc}/pmac_low_i2c.h | 0 include/{asm-ppc64 => asm-powerpc}/smu.h | 0 include/{asm-ppc => asm-powerpc}/uninorth.h | 0 include/asm-ppc64/dbdma.h | 2 -- include/asm-ppc64/keylargo.h | 2 -- include/asm-ppc64/macio.h | 2 -- include/asm-ppc64/pmac_feature.h | 2 -- include/asm-ppc64/pmac_low_i2c.h | 2 -- include/asm-ppc64/uninorth.h | 2 -- 16 files changed, 12 deletions(-) rename include/{asm-ppc => asm-powerpc}/dbdma.h (100%) rename include/{asm-ppc => asm-powerpc}/heathrow.h (100%) rename include/{asm-ppc => asm-powerpc}/keylargo.h (100%) rename include/{asm-ppc => asm-powerpc}/macio.h (100%) rename include/{asm-ppc => asm-powerpc}/mediabay.h (100%) rename include/{asm-ppc => asm-powerpc}/ohare.h (100%) rename include/{asm-ppc => asm-powerpc}/pmac_feature.h (100%) rename include/{asm-ppc => asm-powerpc}/pmac_low_i2c.h (100%) rename include/{asm-ppc64 => asm-powerpc}/smu.h (100%) rename include/{asm-ppc => asm-powerpc}/uninorth.h (100%) delete mode 100644 include/asm-ppc64/dbdma.h delete mode 100644 include/asm-ppc64/keylargo.h delete mode 100644 include/asm-ppc64/macio.h delete mode 100644 include/asm-ppc64/pmac_feature.h delete mode 100644 include/asm-ppc64/pmac_low_i2c.h delete mode 100644 include/asm-ppc64/uninorth.h diff --git a/include/asm-ppc/dbdma.h b/include/asm-powerpc/dbdma.h similarity index 100% rename from include/asm-ppc/dbdma.h rename to include/asm-powerpc/dbdma.h diff --git a/include/asm-ppc/heathrow.h b/include/asm-powerpc/heathrow.h similarity index 100% rename from include/asm-ppc/heathrow.h rename to include/asm-powerpc/heathrow.h diff --git a/include/asm-ppc/keylargo.h b/include/asm-powerpc/keylargo.h similarity index 100% rename from include/asm-ppc/keylargo.h rename to include/asm-powerpc/keylargo.h diff --git a/include/asm-ppc/macio.h b/include/asm-powerpc/macio.h similarity index 100% rename from include/asm-ppc/macio.h rename to include/asm-powerpc/macio.h diff --git a/include/asm-ppc/mediabay.h b/include/asm-powerpc/mediabay.h similarity index 100% rename from include/asm-ppc/mediabay.h rename to include/asm-powerpc/mediabay.h diff --git a/include/asm-ppc/ohare.h b/include/asm-powerpc/ohare.h similarity index 100% rename from include/asm-ppc/ohare.h rename to include/asm-powerpc/ohare.h diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h similarity index 100% rename from include/asm-ppc/pmac_feature.h rename to include/asm-powerpc/pmac_feature.h diff --git a/include/asm-ppc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h similarity index 100% rename from include/asm-ppc/pmac_low_i2c.h rename to include/asm-powerpc/pmac_low_i2c.h diff --git a/include/asm-ppc64/smu.h b/include/asm-powerpc/smu.h similarity index 100% rename from include/asm-ppc64/smu.h rename to include/asm-powerpc/smu.h diff --git a/include/asm-ppc/uninorth.h b/include/asm-powerpc/uninorth.h similarity index 100% rename from include/asm-ppc/uninorth.h rename to include/asm-powerpc/uninorth.h diff --git a/include/asm-ppc64/dbdma.h b/include/asm-ppc64/dbdma.h deleted file mode 100644 index f2d5d5dc3377..000000000000 --- a/include/asm-ppc64/dbdma.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/asm-ppc64/keylargo.h b/include/asm-ppc64/keylargo.h deleted file mode 100644 index 4d78e3d0314c..000000000000 --- a/include/asm-ppc64/keylargo.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/asm-ppc64/macio.h b/include/asm-ppc64/macio.h deleted file mode 100644 index a3028b364f70..000000000000 --- a/include/asm-ppc64/macio.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/asm-ppc64/pmac_feature.h b/include/asm-ppc64/pmac_feature.h deleted file mode 100644 index e07e36c4cbb2..000000000000 --- a/include/asm-ppc64/pmac_feature.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/asm-ppc64/pmac_low_i2c.h b/include/asm-ppc64/pmac_low_i2c.h deleted file mode 100644 index 7bcfc72c5c8a..000000000000 --- a/include/asm-ppc64/pmac_low_i2c.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/asm-ppc64/uninorth.h b/include/asm-ppc64/uninorth.h deleted file mode 100644 index 7ad7059f2c80..000000000000 --- a/include/asm-ppc64/uninorth.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - From 399fe2bdd315c3a678b59b72659c4ed1ce0e1a24 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 20:57:05 +1000 Subject: [PATCH 0357/1940] ppc: rename pci_assign_all_busses to pci_assign_all_buses ... for consistency with ppc64 and to make merging easier. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/pci.c | 6 +++--- arch/ppc/kernel/pci.c | 10 +++++----- arch/ppc/platforms/chrp_pci.c | 2 +- arch/ppc/platforms/pmac_pci.c | 6 +++--- arch/ppc/syslib/m82xx_pci.c | 2 +- arch/ppc/syslib/mpc52xx_pci.c | 2 +- arch/ppc64/kernel/maple_pci.c | 2 +- arch/ppc64/kernel/pmac_pci.c | 2 +- include/asm-ppc/pci.h | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index afb147e6b89f..34dfe1e9706f 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -608,7 +608,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) static int __init setup_uninorth(struct pci_controller* hose, struct reg_property* addr) { - pci_assign_all_busses = 1; + pci_assign_all_buses = 1; has_uninorth = 1; hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); @@ -640,7 +640,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_busses to the + * on AGP, we'll have to move pci_assign_all_buses to the * pci_controller structure so we enable it for AGP and not for * HT childs. * We hard code the address because of the different size of @@ -1007,7 +1007,7 @@ void __init pmac_find_bridges(void) * some offset between bus number and domains for now when we * assign all busses should help for now */ - if (pci_assign_all_busses) + if (pci_assign_all_buses) pcibios_assign_bus_offset = 0x10; } diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 163276be7cc5..ad4ef2aaa6ab 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -54,7 +54,7 @@ static u8* pci_to_OF_bus_map; /* By default, we don't re-assign bus numbers. We do this only on * some pmacs */ -int pci_assign_all_busses; +int pci_assign_all_buses; struct pci_controller* hose_head; struct pci_controller** hose_tail = &hose_head; @@ -827,7 +827,7 @@ EXPORT_SYMBOL(pci_device_to_OF_node); * PCI bus numbers have not yet been assigned, and you need to * issue PCI config cycles to an OF device. * It could also be used to "fix" RTAS config cycles if you want - * to set pci_assign_all_busses to 1 and still use RTAS for PCI + * to set pci_assign_all_buses to 1 and still use RTAS for PCI * config cycles. */ struct pci_controller* @@ -1270,12 +1270,12 @@ pcibios_init(void) /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { - if (pci_assign_all_busses) + if (pci_assign_all_buses) hose->first_busno = next_busno; hose->last_busno = 0xff; bus = pci_scan_bus(hose->first_busno, hose->ops, hose); hose->last_busno = bus->subordinate; - if (pci_assign_all_busses || next_busno <= hose->last_busno) + if (pci_assign_all_buses || next_busno <= hose->last_busno) next_busno = hose->last_busno + pcibios_assign_bus_offset; } pci_bus_count = next_busno; @@ -1284,7 +1284,7 @@ pcibios_init(void) * numbers vs. kernel bus numbers since we may have to * remap them. */ - if (pci_assign_all_busses && have_of) + if (pci_assign_all_buses && have_of) pcibios_make_OF_bus_map(); /* Do machine dependent PCI interrupt routing */ diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index f12192cc4d42..bd047aac01b1 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c @@ -203,7 +203,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d printk ("RTAS supporting Pegasos OF not found, please upgrade" " your firmware\n"); } - pci_assign_all_busses = 1; + pci_assign_all_buses = 1; } void __init diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c index 1dc638f72239..786295b6ddd0 100644 --- a/arch/ppc/platforms/pmac_pci.c +++ b/arch/ppc/platforms/pmac_pci.c @@ -575,7 +575,7 @@ pmac_find_bridges(void) * some offset between bus number and domains for now when we * assign all busses should help for now */ - if (pci_assign_all_busses) + if (pci_assign_all_buses) pcibios_assign_bus_offset = 0x10; #ifdef CONFIG_POWER4 @@ -643,7 +643,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) static int __init setup_uninorth(struct pci_controller* hose, struct reg_property* addr) { - pci_assign_all_busses = 1; + pci_assign_all_buses = 1; has_uninorth = 1; hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); @@ -677,7 +677,7 @@ setup_u3_agp(struct pci_controller* hose, struct reg_property* addr) { /* On G5, we move AGP up to high bus number so we don't need * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_busses to the + * on AGP, we'll have to move pci_assign_all_buses to the * pci_controller structure so we enable it for AGP and not for * HT childs. * We hard code the address because of the different size of diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c index 9db58c587b46..5cce123789f1 100644 --- a/arch/ppc/syslib/m82xx_pci.c +++ b/arch/ppc/syslib/m82xx_pci.c @@ -302,7 +302,7 @@ pq2ads_setup_pci(struct pci_controller *hose) void __init pq2_find_bridges(void) { - extern int pci_assign_all_busses; + extern int pci_assign_all_buses; struct pci_controller * hose; int host_bridge; diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c index 02edff8befd0..4ac19080eb85 100644 --- a/arch/ppc/syslib/mpc52xx_pci.c +++ b/arch/ppc/syslib/mpc52xx_pci.c @@ -182,7 +182,7 @@ mpc52xx_find_bridges(void) struct mpc52xx_pci __iomem *pci_regs; struct pci_controller *hose; - pci_assign_all_busses = 1; + pci_assign_all_buses = 1; pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE); if (!pci_regs) diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c index 0937649f4961..b901470f55cc 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/ppc64/kernel/maple_pci.c @@ -275,7 +275,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_busses to the + * on AGP, we'll have to move pci_assign_all_buses to the * pci_controller structure so we enable it for AGP and not for * HT childs. * We hard code the address because of the different size of diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index f139fc034199..7a81c8275940 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -381,7 +381,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_busses to the + * on AGP, we'll have to move pci_assign_all_buses to the * pci_controller structure so we enable it for AGP and not for * HT childs. * We hard code the address because of the different size of diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 9dd06cd40096..643740dd727b 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -24,9 +24,9 @@ struct pci_dev; * Set this to 1 if you want the kernel to re-assign all PCI * bus numbers */ -extern int pci_assign_all_busses; +extern int pci_assign_all_buses; -#define pcibios_assign_all_busses() (pci_assign_all_busses) +#define pcibios_assign_all_busses() (pci_assign_all_buses) #define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0x1000 From 0458060c1c59c5378d8fb5daabe18cf4681c35cd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 21:00:20 +1000 Subject: [PATCH 0358/1940] ppc64: Move init_boot_text call and conswitchp init into setup_arch This way they get done in one place for all platforms, and it is more consistent with what ppc32 does. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_64.c | 8 ++++++++ arch/powerpc/platforms/pseries/setup.c | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 97ffdcf09c03..0312422881ae 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -586,6 +586,10 @@ void __init setup_system(void) */ finish_device_tree(); +#ifdef CONFIG_BOOTX_TEXT + init_boot_display(); +#endif + /* * Initialize xmon */ @@ -1039,6 +1043,10 @@ void __init setup_arch(char **cmdline_p) /* initialize the syscall map in systemcfg */ setup_syscall_map(); +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + ppc_md.setup_arch(); /* Use the default idle loop if the platform hasn't provided one. */ diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index c53dbbb4490a..92d18003f152 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -241,10 +241,6 @@ static void __init pSeries_setup_arch(void) find_and_init_phbs(); eeh_init(); -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - pSeries_nvram_init(); /* Choose an idle loop */ From 374e99d450a0c44dc30041fa83eccfd0890330c7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 21:04:51 +1000 Subject: [PATCH 0359/1940] powerpc: Move some calculations from xxx_calibrate_decr to time_init Previously the individual xxx_calibrate_decr functions would each print the timebase and cpu frequency and calculate several values such as tb_to_us and tb_to_xs. This moves those printks and calculations into time_init just after the call to the platform's calibrate_decr function. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 27 ++++++++++++--------------- arch/ppc64/kernel/pmac_time.c | 14 ++------------ 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index d1608473075f..7d406b73a855 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -548,11 +548,9 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) || defined(CONFIG_PPC_ISERIES) void __init generic_calibrate_decr(void) { struct device_node *cpu; - struct div_result divres; unsigned int *fp; int node_found; @@ -591,20 +589,7 @@ void __init generic_calibrate_decr(void) "(not found)\n"); of_node_put(cpu); - - printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", - ppc_tb_freq/1000000, ppc_tb_freq%1000000); - printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n", - ppc_proc_freq/1000000, ppc_proc_freq%1000000); - - tb_ticks_per_jiffy = ppc_tb_freq / HZ; - tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; - tb_ticks_per_usec = ppc_tb_freq / 1000000; - tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); - div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres); - tb_to_xs = divres.result_low; } -#endif unsigned long get_boot_time(void) { @@ -633,6 +618,18 @@ void __init time_init(void) ppc_md.calibrate_decr(); + printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", + ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); + printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n", + ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); + + tb_ticks_per_jiffy = ppc_tb_freq / HZ; + tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; + tb_ticks_per_usec = ppc_tb_freq / 1000000; + tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); + div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res); + tb_to_xs = res.result_low; + #ifdef CONFIG_PPC64 get_paca()->default_decr = tb_ticks_per_jiffy; #endif diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index 56f335115916..928bf213ec4e 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c @@ -152,8 +152,7 @@ unsigned long __init pmac_get_boot_time(void) void __init pmac_calibrate_decr(void) { struct device_node *cpu; - unsigned int freq, *fp; - struct div_result divres; + unsigned int *fp; /* * The cpu node should have a timebase-frequency property @@ -165,16 +164,7 @@ void __init pmac_calibrate_decr(void) fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); if (fp == 0) panic("can't get cpu timebase frequency"); - freq = *fp; - printk("time_init: decrementer frequency = %u.%.6u MHz\n", - freq/1000000, freq%1000000); - tb_ticks_per_jiffy = freq / HZ; - tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; - tb_ticks_per_usec = freq / 1000000; - tb_to_us = mulhwu_scale_factor(freq, 1000000); - div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres ); - tb_to_xs = divres.result_low; - ppc_tb_freq = freq; + ppc_tb_freq = *fp; fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL); if (fp == 0) From d85b525e6e1d0886eebd1d4c4f954d9d2f226a63 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 21:06:44 +1000 Subject: [PATCH 0360/1940] ppc64: Use the merged mpic.c This means we now compile in arch/powerpc/sysdev for ARCH=ppc64. Signed-off-by: Paul Mackerras --- arch/ppc64/Makefile | 1 + arch/ppc64/kernel/Makefile | 3 +- arch/ppc64/kernel/mpic.c | 887 ------------------------------------- 3 files changed, 2 insertions(+), 889 deletions(-) delete mode 100644 arch/ppc64/kernel/mpic.c diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 4a9928ef3032..4d18bdb680f0 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -84,6 +84,7 @@ head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ core-y += arch/powerpc/mm/ +core-y += arch/powerpc/sysdev/ core-y += arch/powerpc/platforms/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 6cce419f4b09..6c02a79955c7 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -55,9 +55,8 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o -ifneq ($(CONFIG_PPC_MERGE),y) -obj-$(CONFIG_MPIC) += mpic.o +ifneq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ pmac_time.o pmac_nvram.o pmac_low_i2c.o \ udbg_scc.o diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c deleted file mode 100644 index ec22321342ad..000000000000 --- a/arch/ppc64/kernel/mpic.c +++ /dev/null @@ -1,887 +0,0 @@ -/* - * arch/ppc64/kernel/mpic.c - * - * Driver for interrupt controllers following the OpenPIC standard, the - * common implementation beeing IBM's MPIC. This driver also can deal - * with various broken implementations of this HW. - * - * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#define DBG(fmt...) printk(fmt) -#else -#define DBG(fmt...) -#endif - -static struct mpic *mpics; -static struct mpic *mpic_primary; -static DEFINE_SPINLOCK(mpic_lock); - - -/* - * Register accessor functions - */ - - -static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, - unsigned int reg) -{ - if (be) - return in_be32(base + (reg >> 2)); - else - return in_le32(base + (reg >> 2)); -} - -static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, - unsigned int reg, u32 value) -{ - if (be) - out_be32(base + (reg >> 2), value); - else - out_le32(base + (reg >> 2), value); -} - -static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) -{ - unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); - - if (mpic->flags & MPIC_BROKEN_IPI) - be = !be; - return _mpic_read(be, mpic->gregs, offset); -} - -static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) -{ - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); - - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); -} - -static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) -{ - unsigned int cpu = 0; - - if (mpic->flags & MPIC_PRIMARY) - cpu = hard_smp_processor_id(); - - return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg); -} - -static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) -{ - unsigned int cpu = 0; - - if (mpic->flags & MPIC_PRIMARY) - cpu = hard_smp_processor_id(); - - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value); -} - -static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) -{ - unsigned int isu = src_no >> mpic->isu_shift; - unsigned int idx = src_no & mpic->isu_mask; - - return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_IRQ_STRIDE)); -} - -static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, - unsigned int reg, u32 value) -{ - unsigned int isu = src_no >> mpic->isu_shift; - unsigned int idx = src_no & mpic->isu_mask; - - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_IRQ_STRIDE), value); -} - -#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) -#define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v)) -#define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) -#define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) -#define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) -#define mpic_cpu_write(i,v) _mpic_cpu_write(mpic,(i),(v)) -#define mpic_irq_read(s,r) _mpic_irq_read(mpic,(s),(r)) -#define mpic_irq_write(s,r,v) _mpic_irq_write(mpic,(s),(r),(v)) - - -/* - * Low level utility functions - */ - - - -/* Check if we have one of those nice broken MPICs with a flipped endian on - * reads from IPI registers - */ -static void __init mpic_test_broken_ipi(struct mpic *mpic) -{ - u32 r; - - mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK); - r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0); - - if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { - printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); - mpic->flags |= MPIC_BROKEN_IPI; - } -} - -#ifdef CONFIG_MPIC_BROKEN_U3 - -/* Test if an interrupt is sourced from HyperTransport (used on broken U3s) - * to force the edge setting on the MPIC and do the ack workaround. - */ -static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no) -{ - if (source_no >= 128 || !mpic->fixups) - return 0; - return mpic->fixups[source_no].base != NULL; -} - -static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no) -{ - struct mpic_irq_fixup *fixup = &mpic->fixups[source_no]; - u32 tmp; - - spin_lock(&mpic->fixup_lock); - writeb(0x11 + 2 * fixup->irq, fixup->base); - tmp = readl(fixup->base + 2); - writel(tmp | 0x80000000ul, fixup->base + 2); - /* config writes shouldn't be posted but let's be safe ... */ - (void)readl(fixup->base + 2); - spin_unlock(&mpic->fixup_lock); -} - - -static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase) -{ - int i, irq; - u32 tmp; - - printk(KERN_INFO "mpic: - Workarounds on AMD 8111 @ %p\n", devbase); - - for (i=0; i < 24; i++) { - writeb(0x10 + 2*i, devbase + 0xf2); - tmp = readl(devbase + 0xf4); - if ((tmp & 0x1) || !(tmp & 0x20)) - continue; - irq = (tmp >> 16) & 0xff; - mpic->fixups[irq].irq = i; - mpic->fixups[irq].base = devbase + 0xf2; - } -} - -static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase) -{ - int i, irq; - u32 tmp; - - printk(KERN_INFO "mpic: - Workarounds on AMD 8131 @ %p\n", devbase); - - for (i=0; i < 4; i++) { - writeb(0x10 + 2*i, devbase + 0xba); - tmp = readl(devbase + 0xbc); - if ((tmp & 0x1) || !(tmp & 0x20)) - continue; - irq = (tmp >> 16) & 0xff; - mpic->fixups[irq].irq = i; - mpic->fixups[irq].base = devbase + 0xba; - } -} - -static void __init mpic_scan_ioapics(struct mpic *mpic) -{ - unsigned int devfn; - u8 __iomem *cfgspace; - - printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n"); - - /* Allocate fixups array */ - mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup)); - BUG_ON(mpic->fixups == NULL); - memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup)); - - /* Init spinlock */ - spin_lock_init(&mpic->fixup_lock); - - /* Map u3 config space. We assume all IO-APICs are on the primary bus - * and slot will never be above "0xf" so we only need to map 32k - */ - cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000); - BUG_ON(cfgspace == NULL); - - /* Now we scan all slots. We do a very quick scan, we read the header type, - * vendor ID and device ID only, that's plenty enough - */ - for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) { - u8 __iomem *devbase = cfgspace + (devfn << 8); - u8 hdr_type = readb(devbase + PCI_HEADER_TYPE); - u32 l = readl(devbase + PCI_VENDOR_ID); - u16 vendor_id, device_id; - int multifunc = 0; - - DBG("devfn %x, l: %x\n", devfn, l); - - /* If no device, skip */ - if (l == 0xffffffff || l == 0x00000000 || - l == 0x0000ffff || l == 0xffff0000) - goto next; - - /* Check if it's a multifunction device (only really used - * to function 0 though - */ - multifunc = !!(hdr_type & 0x80); - vendor_id = l & 0xffff; - device_id = (l >> 16) & 0xffff; - - /* If a known device, go to fixup setup code */ - if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460) - mpic_amd8111_read_irq(mpic, devbase); - if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450) - mpic_amd8131_read_irq(mpic, devbase); - next: - /* next device, if function 0 */ - if ((PCI_FUNC(devfn) == 0) && !multifunc) - devfn += 7; - } -} - -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - -/* Find an mpic associated with a given linux interrupt */ -static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi) -{ - struct mpic *mpic = mpics; - - while(mpic) { - /* search IPIs first since they may override the main interrupts */ - if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) { - if (is_ipi) - *is_ipi = 1; - return mpic; - } - if (irq >= mpic->irq_offset && - irq < (mpic->irq_offset + mpic->irq_count)) { - if (is_ipi) - *is_ipi = 0; - return mpic; - } - mpic = mpic -> next; - } - return NULL; -} - -/* Convert a cpu mask from logical to physical cpu numbers. */ -static inline u32 mpic_physmask(u32 cpumask) -{ - int i; - u32 mask = 0; - - for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1) - mask |= (cpumask & 1) << get_hard_smp_processor_id(i); - return mask; -} - -#ifdef CONFIG_SMP -/* Get the mpic structure from the IPI number */ -static inline struct mpic * mpic_from_ipi(unsigned int ipi) -{ - return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); -} -#endif - -/* Get the mpic structure from the irq number */ -static inline struct mpic * mpic_from_irq(unsigned int irq) -{ - return container_of(irq_desc[irq].handler, struct mpic, hc_irq); -} - -/* Send an EOI */ -static inline void mpic_eoi(struct mpic *mpic) -{ - mpic_cpu_write(MPIC_CPU_EOI, 0); - (void)mpic_cpu_read(MPIC_CPU_WHOAMI); -} - -#ifdef CONFIG_SMP -static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) -{ - struct mpic *mpic = dev_id; - - smp_message_recv(irq - mpic->ipi_offset, regs); - return IRQ_HANDLED; -} -#endif /* CONFIG_SMP */ - -/* - * Linux descriptor level callbacks - */ - - -static void mpic_enable_irq(unsigned int irq) -{ - unsigned int loops = 100000; - struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; - - DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src); - - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); - - /* make sure mask gets to controller before we return to user */ - do { - if (!loops--) { - printk(KERN_ERR "mpic_enable_irq timeout\n"); - break; - } - } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); -} - -static void mpic_disable_irq(unsigned int irq) -{ - unsigned int loops = 100000; - struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; - - DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); - - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK); - - /* make sure mask gets to controller before we return to user */ - do { - if (!loops--) { - printk(KERN_ERR "mpic_enable_irq timeout\n"); - break; - } - } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); -} - -static void mpic_end_irq(unsigned int irq) -{ - struct mpic *mpic = mpic_from_irq(irq); - - DBG("%s: end_irq: %d\n", mpic->name, irq); - - /* We always EOI on end_irq() even for edge interrupts since that - * should only lower the priority, the MPIC should have properly - * latched another edge interrupt coming in anyway - */ - -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic->flags & MPIC_BROKEN_U3) { - unsigned int src = irq - mpic->irq_offset; - if (mpic_is_ht_interrupt(mpic, src)) - mpic_apic_end_irq(mpic, src); - } -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - mpic_eoi(mpic); -} - -#ifdef CONFIG_SMP - -static void mpic_enable_ipi(unsigned int irq) -{ - struct mpic *mpic = mpic_from_ipi(irq); - unsigned int src = irq - mpic->ipi_offset; - - DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src); - mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK); -} - -static void mpic_disable_ipi(unsigned int irq) -{ - /* NEVER disable an IPI... that's just plain wrong! */ -} - -static void mpic_end_ipi(unsigned int irq) -{ - struct mpic *mpic = mpic_from_ipi(irq); - - /* - * IPIs are marked IRQ_PER_CPU. This has the side effect of - * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from - * applying to them. We EOI them late to avoid re-entering. - * We mark IPI's with SA_INTERRUPT as they must run with - * irqs disabled. - */ - mpic_eoi(mpic); -} - -#endif /* CONFIG_SMP */ - -static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) -{ - struct mpic *mpic = mpic_from_irq(irq); - - cpumask_t tmp; - - cpus_and(tmp, cpumask, cpu_online_map); - - mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION, - mpic_physmask(cpus_addr(tmp)[0])); -} - - -/* - * Exported functions - */ - - -struct mpic * __init mpic_alloc(unsigned long phys_addr, - unsigned int flags, - unsigned int isu_size, - unsigned int irq_offset, - unsigned int irq_count, - unsigned int ipi_offset, - unsigned char *senses, - unsigned int senses_count, - const char *name) -{ - struct mpic *mpic; - u32 reg; - const char *vers; - int i; - - mpic = alloc_bootmem(sizeof(struct mpic)); - if (mpic == NULL) - return NULL; - - memset(mpic, 0, sizeof(struct mpic)); - mpic->name = name; - - mpic->hc_irq.typename = name; - mpic->hc_irq.enable = mpic_enable_irq; - mpic->hc_irq.disable = mpic_disable_irq; - mpic->hc_irq.end = mpic_end_irq; - if (flags & MPIC_PRIMARY) - mpic->hc_irq.set_affinity = mpic_set_affinity; -#ifdef CONFIG_SMP - mpic->hc_ipi.typename = name; - mpic->hc_ipi.enable = mpic_enable_ipi; - mpic->hc_ipi.disable = mpic_disable_ipi; - mpic->hc_ipi.end = mpic_end_ipi; -#endif /* CONFIG_SMP */ - - mpic->flags = flags; - mpic->isu_size = isu_size; - mpic->irq_offset = irq_offset; - mpic->irq_count = irq_count; - mpic->ipi_offset = ipi_offset; - mpic->num_sources = 0; /* so far */ - mpic->senses = senses; - mpic->senses_count = senses_count; - - /* Map the global registers */ - mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); - mpic->tmregs = mpic->gregs + (MPIC_TIMER_BASE >> 2); - BUG_ON(mpic->gregs == NULL); - - /* Reset */ - if (flags & MPIC_WANTS_RESET) { - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) - | MPIC_GREG_GCONF_RESET); - while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) - & MPIC_GREG_GCONF_RESET) - mb(); - } - - /* Read feature register, calculate num CPUs and, for non-ISU - * MPICs, num sources as well. On ISU MPICs, sources are counted - * as ISUs are added - */ - reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0); - mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) - >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; - if (isu_size == 0) - mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK) - >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; - - /* Map the per-CPU registers */ - for (i = 0; i < mpic->num_cpus; i++) { - mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE + - i * MPIC_CPU_STRIDE, 0x1000); - BUG_ON(mpic->cpuregs[i] == NULL); - } - - /* Initialize main ISU if none provided */ - if (mpic->isu_size == 0) { - mpic->isu_size = mpic->num_sources; - mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE, - MPIC_IRQ_STRIDE * mpic->isu_size); - BUG_ON(mpic->isus[0] == NULL); - } - mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); - mpic->isu_mask = (1 << mpic->isu_shift) - 1; - - /* Display version */ - switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) { - case 1: - vers = "1.0"; - break; - case 2: - vers = "1.2"; - break; - case 3: - vers = "1.3"; - break; - default: - vers = ""; - break; - } - printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n", - name, vers, phys_addr, mpic->num_cpus); - printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size, - mpic->isu_shift, mpic->isu_mask); - - mpic->next = mpics; - mpics = mpic; - - if (flags & MPIC_PRIMARY) - mpic_primary = mpic; - - return mpic; -} - -void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, - unsigned long phys_addr) -{ - unsigned int isu_first = isu_num * mpic->isu_size; - - BUG_ON(isu_num >= MPIC_MAX_ISU); - - mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size); - if ((isu_first + mpic->isu_size) > mpic->num_sources) - mpic->num_sources = isu_first + mpic->isu_size; -} - -void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler, - void *data) -{ - struct mpic *mpic = mpic_find(irq, NULL); - unsigned long flags; - - /* Synchronization here is a bit dodgy, so don't try to replace cascade - * interrupts on the fly too often ... but normally it's set up at boot. - */ - spin_lock_irqsave(&mpic_lock, flags); - if (mpic->cascade) - mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset); - mpic->cascade = NULL; - wmb(); - mpic->cascade_vec = irq - mpic->irq_offset; - mpic->cascade_data = data; - wmb(); - mpic->cascade = handler; - mpic_enable_irq(irq); - spin_unlock_irqrestore(&mpic_lock, flags); -} - -void __init mpic_init(struct mpic *mpic) -{ - int i; - - BUG_ON(mpic->num_sources == 0); - - printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); - - /* Set current processor priority to max */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); - - /* Initialize timers: just disable them all */ - for (i = 0; i < 4; i++) { - mpic_write(mpic->tmregs, - i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0); - mpic_write(mpic->tmregs, - i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI, - MPIC_VECPRI_MASK | - (MPIC_VEC_TIMER_0 + i)); - } - - /* Initialize IPIs to our reserved vectors and mark them disabled for now */ - mpic_test_broken_ipi(mpic); - for (i = 0; i < 4; i++) { - mpic_ipi_write(i, - MPIC_VECPRI_MASK | - (10 << MPIC_VECPRI_PRIORITY_SHIFT) | - (MPIC_VEC_IPI_0 + i)); -#ifdef CONFIG_SMP - if (!(mpic->flags & MPIC_PRIMARY)) - continue; - irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; - irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; - -#endif /* CONFIG_SMP */ - } - - /* Initialize interrupt sources */ - if (mpic->irq_count == 0) - mpic->irq_count = mpic->num_sources; - -#ifdef CONFIG_MPIC_BROKEN_U3 - /* Do the ioapic fixups on U3 broken mpic */ - DBG("MPIC flags: %x\n", mpic->flags); - if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) - mpic_scan_ioapics(mpic); -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - for (i = 0; i < mpic->num_sources; i++) { - /* start with vector = source number, and masked */ - u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT); - int level = 0; - - /* if it's an IPI, we skip it */ - if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) && - (mpic->irq_offset + i) < (mpic->ipi_offset + i + 4)) - continue; - - /* do senses munging */ - if (mpic->senses && i < mpic->senses_count) { - if (mpic->senses[i] & IRQ_SENSE_LEVEL) - vecpri |= MPIC_VECPRI_SENSE_LEVEL; - if (mpic->senses[i] & IRQ_POLARITY_POSITIVE) - vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; - } else - vecpri |= MPIC_VECPRI_SENSE_LEVEL; - - /* remember if it was a level interrupts */ - level = (vecpri & MPIC_VECPRI_SENSE_LEVEL); - - /* deal with broken U3 */ - if (mpic->flags & MPIC_BROKEN_U3) { -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic_is_ht_interrupt(mpic, i)) { - vecpri &= ~(MPIC_VECPRI_SENSE_MASK | - MPIC_VECPRI_POLARITY_MASK); - vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; - } -#else - printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n"); -#endif - } - - DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri, - (level != 0)); - - /* init hw */ - mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri); - mpic_irq_write(i, MPIC_IRQ_DESTINATION, - 1 << get_hard_smp_processor_id(boot_cpuid)); - - /* init linux descriptors */ - if (i < mpic->irq_count) { - irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; - irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; - } - } - - /* Init spurrious vector */ - mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS); - - /* Disable 8259 passthrough */ - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) - | MPIC_GREG_GCONF_8259_PTHROU_DIS); - - /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); -} - - - -void mpic_irq_set_priority(unsigned int irq, unsigned int pri) -{ - int is_ipi; - struct mpic *mpic = mpic_find(irq, &is_ipi); - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&mpic_lock, flags); - if (is_ipi) { - reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK; - mpic_ipi_write(irq - mpic->ipi_offset, - reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); - } else { - reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI) - & MPIC_VECPRI_PRIORITY_MASK; - mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI, - reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); - } - spin_unlock_irqrestore(&mpic_lock, flags); -} - -unsigned int mpic_irq_get_priority(unsigned int irq) -{ - int is_ipi; - struct mpic *mpic = mpic_find(irq, &is_ipi); - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&mpic_lock, flags); - if (is_ipi) - reg = mpic_ipi_read(irq - mpic->ipi_offset); - else - reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI); - spin_unlock_irqrestore(&mpic_lock, flags); - return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; -} - -void mpic_setup_this_cpu(void) -{ -#ifdef CONFIG_SMP - struct mpic *mpic = mpic_primary; - unsigned long flags; - u32 msk = 1 << hard_smp_processor_id(); - unsigned int i; - - BUG_ON(mpic == NULL); - - DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); - - spin_lock_irqsave(&mpic_lock, flags); - - /* let the mpic know we want intrs. default affinity is 0xffffffff - * until changed via /proc. That's how it's done on x86. If we want - * it differently, then we should make sure we also change the default - * values of irq_affinity in irq.c. - */ - if (distribute_irqs) { - for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_IRQ_DESTINATION, - mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk); - } - - /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); - - spin_unlock_irqrestore(&mpic_lock, flags); -#endif /* CONFIG_SMP */ -} - -/* - * XXX: someone who knows mpic should check this. - * do we need to eoi the ipi including for kexec cpu here (see xics comments)? - * or can we reset the mpic in the new kernel? - */ -void mpic_teardown_this_cpu(int secondary) -{ - struct mpic *mpic = mpic_primary; - unsigned long flags; - u32 msk = 1 << hard_smp_processor_id(); - unsigned int i; - - BUG_ON(mpic == NULL); - - DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); - spin_lock_irqsave(&mpic_lock, flags); - - /* let the mpic know we don't want intrs. */ - for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_IRQ_DESTINATION, - mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); - - /* Set current processor priority to max */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); - - spin_unlock_irqrestore(&mpic_lock, flags); -} - - -void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) -{ - struct mpic *mpic = mpic_primary; - - BUG_ON(mpic == NULL); - - DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); - - mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, - mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); -} - -int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) -{ - u32 irq; - - irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; - DBG("%s: get_one_irq(): %d\n", mpic->name, irq); - - if (mpic->cascade && irq == mpic->cascade_vec) { - DBG("%s: cascading ...\n", mpic->name); - irq = mpic->cascade(regs, mpic->cascade_data); - mpic_eoi(mpic); - return irq; - } - if (unlikely(irq == MPIC_VEC_SPURRIOUS)) - return -1; - if (irq < MPIC_VEC_IPI_0) - return irq + mpic->irq_offset; - DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0); - return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset; -} - -int mpic_get_irq(struct pt_regs *regs) -{ - struct mpic *mpic = mpic_primary; - - BUG_ON(mpic == NULL); - - return mpic_get_one_irq(mpic, regs); -} - - -#ifdef CONFIG_SMP -void mpic_request_ipis(void) -{ - struct mpic *mpic = mpic_primary; - - BUG_ON(mpic == NULL); - - printk("requesting IPIs ... \n"); - - /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */ - request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT, - "IPI0 (call function)", mpic); - request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT, - "IPI1 (reschedule)", mpic); - request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT, - "IPI2 (unused)", mpic); - request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT, - "IPI3 (debugger break)", mpic); - - printk("IPIs requested... \n"); -} -#endif /* CONFIG_SMP */ From 17a6392d30b4ed89b88a47a318b2b6de6ae7b946 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 21:10:09 +1000 Subject: [PATCH 0361/1940] powerpc/ppc/ppc64: Various compile fixes. This declares powersave_nap in system.h and makes it an int everywhere, fixes typos for the maple platform, fixes a couple of places where I missed removing the last two arguments from a message_pass function, and makes ppc64 consistent with ppc32 in the type of the pci_bridge.cfg_data field. Signed-off-by: Paul Mackerras --- arch/ppc/kernel/idle.c | 2 +- arch/ppc64/kernel/maple_time.c | 4 ++-- include/asm-powerpc/system.h | 2 ++ include/asm-ppc/machdep.h | 2 +- include/asm-ppc/open_pic.h | 3 +-- include/asm-ppc64/pci-bridge.h | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 0a12fbef7347..11e5b44713f7 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -75,7 +75,7 @@ void cpu_idle(void) /* * Register the sysctl to set/clear powersave_nap. */ -extern unsigned long powersave_nap; +extern int powersave_nap; static ctl_table powersave_nap_ctl_table[]={ { diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c index cf5186335900..445cb7470bf5 100644 --- a/arch/ppc64/kernel/maple_time.c +++ b/arch/ppc64/kernel/maple_time.c @@ -172,7 +172,7 @@ unsigned long __init maple_get_boot_time(void) } maple_get_rtc_time(&tm); - return mktime(time->tm_year+1900, time->tm_mon+1, time->tm_mday, - time->tm_hour, time->tm_min, time->tm_sec); + return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); } diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 6463453b61a3..d60c8c928922 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -180,6 +180,8 @@ extern struct task_struct *_switch(struct thread_struct *prev, extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ +extern int powersave_nap; /* set if nap mode can be used in idle loop */ + /* * Atomic exchange * diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 1d4ab70a56f3..6c6d23abbe91 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -167,7 +167,7 @@ extern sys_ctrler_t sys_ctrler; #ifdef CONFIG_SMP struct smp_ops_t { - void (*message_pass)(int target, int msg, unsigned long data, int wait); + void (*message_pass)(int target, int msg); int (*probe)(void); void (*kick_cpu)(int nr); void (*setup_cpu)(int nr); diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h index 7848aa610c05..ec2f46629ca2 100644 --- a/include/asm-ppc/open_pic.h +++ b/include/asm-ppc/open_pic.h @@ -58,8 +58,7 @@ extern int openpic_get_irq(struct pt_regs *regs); extern void openpic_reset_processor_phys(u_int cpumask); extern void openpic_setup_ISU(int isu_num, unsigned long addr); extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask); -extern void smp_openpic_message_pass(int target, int msg, unsigned long data, - int wait); +extern void smp_openpic_message_pass(int target, int msg); extern void openpic_set_k2_cascade(int irq); extern void openpic_set_priority(u_int pri); extern u_int openpic_get_priority(void); diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 1136cb6433bf..7d8ecb507a3d 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -36,7 +36,7 @@ struct pci_controller { struct pci_ops *ops; volatile unsigned int __iomem *cfg_addr; - volatile unsigned char __iomem *cfg_data; + volatile void __iomem *cfg_data; /* Currently, we limit ourselves to 1 IO range and 3 mem * ranges since the common pci_bus structure can't handle more From 5d14a18d59b661356409e5a1f624236155a209ba Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 20 Oct 2005 22:33:06 +1000 Subject: [PATCH 0362/1940] powerpc: Fix some bugs in the new merged time code I had the sense of the test for when to use the old 601-style RTC registers inverted. pmac_calibrate_decr and via_calibrate_decr weren't setting ppc_tb_freq, on which all the further calculations depended. Lastly, update_gtod was losing the top 32 bits of the new tb_to_xs value. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 2 +- arch/powerpc/platforms/powermac/time.c | 5 ++--- include/asm-powerpc/time.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 7d406b73a855..3e722370113b 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -222,7 +222,7 @@ static inline void timer_sync_xtime(unsigned long cur_tb) * between updates. */ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, - unsigned int new_tb_to_xs) + u64 new_tb_to_xs) { unsigned temp_idx; struct gettimeofday_vars *temp_varp; diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index eb9969b52f96..a6d2d231d5a0 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -216,8 +216,8 @@ via_calibrate_decr(void) ; dend = get_dec(); + ppc_tb_freq = (dstart - dend) * 100 / 6; tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); - tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %lu (%u ticks)\n", tb_ticks_per_jiffy, dstart - dend); @@ -306,6 +306,5 @@ pmac_calibrate_decr(void) freq = *fp; printk("time_init: decrementer frequency = %u.%.6u MHz\n", freq/1000000, freq%1000000); - tb_ticks_per_jiffy = freq / HZ; - tb_to_us = mulhwu_scale_factor(freq, 1000000); + ppc_tb_freq = freq; } diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index 4eecc38f7092..f8ef186c81e4 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -75,7 +75,7 @@ struct div_result { /* Accessor functions for the timebase (RTC on 601) registers. */ /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ #ifdef CONFIG_6xx -#define __USE_RTC() cpu_has_feature(CPU_FTR_USE_TB) +#define __USE_RTC() (!cpu_has_feature(CPU_FTR_USE_TB)) #else #define __USE_RTC() 0 #endif From 3910f44d79a8a4a26fcfefbf16c5b8e1a7743175 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 20 Oct 2005 12:29:36 -0700 Subject: [PATCH 0363/1940] [IB] cm: Add missing break in switch Add missing "break" in switch statement. Without the break, the CM ended up always falling through and setting every connection request to use RC transport, which meant that UC connections didn't work. Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm_msgs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h index 813ab70bf6d5..4d3aee90c249 100644 --- a/drivers/infiniband/core/cm_msgs.h +++ b/drivers/infiniband/core/cm_msgs.h @@ -186,6 +186,7 @@ static inline void cm_req_set_qp_type(struct cm_req_msg *req_msg, req_msg->offset40 = cpu_to_be32((be32_to_cpu( req_msg->offset40) & 0xFFFFFFF9) | 0x2); + break; default: req_msg->offset40 = cpu_to_be32(be32_to_cpu( req_msg->offset40) & From 2e0c512aff978a7040464e81fc9c0dfdf4639c23 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 20 Oct 2005 12:30:16 -0700 Subject: [PATCH 0364/1940] [IB] user_mad: trivial coding style fixes Add spaces after "sizeof" operator to match the rest of file. Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index a64d6b4dcc16..38f4bfbb7135 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -280,14 +280,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, length = count - sizeof (struct ib_user_mad); packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) + - sizeof(struct ib_rmpp_hdr), GFP_KERNEL); + sizeof (struct ib_rmpp_hdr), GFP_KERNEL); if (!packet) return -ENOMEM; if (copy_from_user(&packet->mad, buf, sizeof (struct ib_user_mad) + - sizeof(struct ib_mad_hdr) + - sizeof(struct ib_rmpp_hdr))) { + sizeof (struct ib_mad_hdr) + + sizeof (struct ib_rmpp_hdr))) { ret = -EFAULT; goto err; } @@ -349,7 +349,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, } rmpp_active = 1; } else { - if (length > sizeof(struct ib_mad)) { + if (length > sizeof (struct ib_mad)) { ret = -EINVAL; goto err_ah; } @@ -376,17 +376,17 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, if (!rmpp_active) { /* Copy message from user into send buffer */ if (copy_from_user(packet->msg->mad, - buf + sizeof(struct ib_user_mad), length)) { + buf + sizeof (struct ib_user_mad), length)) { ret = -EFAULT; goto err_msg; } } else { - rmpp_hdr_size = sizeof(struct ib_mad_hdr) + - sizeof(struct ib_rmpp_hdr); + rmpp_hdr_size = sizeof (struct ib_mad_hdr) + + sizeof (struct ib_rmpp_hdr); /* Only copy MAD headers (RMPP header in place) */ memcpy(packet->msg->mad, packet->mad.data, - sizeof(struct ib_mad_hdr)); + sizeof (struct ib_mad_hdr)); /* Now, copy rest of message from user into send buffer */ if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data, From bbf207860931b6a033d0fbcd170ae2332c0d8216 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 20 Oct 2005 12:54:01 -0700 Subject: [PATCH 0365/1940] [IB] user_mad: Use class_device.devt Use devt member of struct class_device so that we don't have to create our own "dev" file in sysfs. Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 38f4bfbb7135..fd200c064a2e 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -671,17 +671,6 @@ static struct ib_client umad_client = { .remove = ib_umad_remove_one }; -static ssize_t show_dev(struct class_device *class_dev, char *buf) -{ - struct ib_umad_port *port = class_get_devdata(class_dev); - - if (class_dev == &port->class_dev) - return print_dev_t(buf, port->dev.dev); - else - return print_dev_t(buf, port->sm_dev.dev); -} -static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); - static ssize_t show_ibdev(struct class_device *class_dev, char *buf) { struct ib_umad_port *port = class_get_devdata(class_dev); @@ -762,6 +751,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, port->class_dev.class = &umad_class; port->class_dev.dev = device->dma_device; + port->class_dev.devt = port->dev.dev; snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum); @@ -771,8 +761,6 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, class_set_devdata(&port->class_dev, port); kref_get(&port->umad_dev->ref); - if (class_device_create_file(&port->class_dev, &class_device_attr_dev)) - goto err_class; if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev)) goto err_class; if (class_device_create_file(&port->class_dev, &class_device_attr_port)) @@ -786,6 +774,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, port->sm_class_dev.class = &umad_class; port->sm_class_dev.dev = device->dma_device; + port->sm_class_dev.devt = port->sm_dev.dev; snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS); @@ -795,8 +784,6 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, class_set_devdata(&port->sm_class_dev, port); kref_get(&port->umad_dev->ref); - if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev)) - goto err_sm_class; if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev)) goto err_sm_class; if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port)) From 23e7dd7d95f6fdc167a6d6ddea79ced0af33bbff Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 20 Oct 2005 13:44:56 -0700 Subject: [PATCH 0366/1940] [CIFS] Defer close of file handle slightly if there are pending writes that need to get in ahead of it that depend on that file handle. Fixes occassional bad file handle errors on write with heavy use multiple process cases. Signed-off-by: Steve French --- fs/cifs/CHANGES | 6 ++++ fs/cifs/cifsfs.h | 2 +- fs/cifs/cifsglob.h | 1 + fs/cifs/file.c | 88 +++++++++++++++++++++++++++++++++------------- fs/cifs/inode.c | 1 + 5 files changed, 73 insertions(+), 25 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index f554a70c9cf3..5bab24f59053 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,9 @@ +Version 1.39 +------------ +Defer close of a file handle slightly if pending writes depend on that file handle +(this reduces the EBADF bad file handle errors that can be logged under heavy +stress on writes). + Version 1.38 ------------ Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 4cdb29fdc8c2..1223fa81dbd2 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -97,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.38" +#define CIFS_VERSION "1.39" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 839a55667c3c..1ba08f8c5bc4 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -299,6 +299,7 @@ struct cifsFileInfo { struct inode * pInode; /* needed for oplock break */ unsigned closePend:1; /* file is marked to close */ unsigned invalidHandle:1; /* file closed via session abend */ + atomic_t wrtPending; /* handle in use - defer close */ struct semaphore fh_sem; /* prevents reopen race after dead ses*/ char * search_resume_name; /* BB removeme BB */ unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 23af20d5af7c..da4f5e10b3cc 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "cifsfs.h" #include "cifspdu.h" @@ -50,6 +51,11 @@ static inline struct cifsFileInfo *cifs_init_private( private_data->pInode = inode; private_data->invalidHandle = FALSE; private_data->closePend = FALSE; + /* we have to track num writers to the inode, since writepages + does not tell us which handle the write is for so there can + be a close (overlapping with write) of the filehandle that + cifs_writepages chose to use */ + atomic_set(&private_data->wrtPending,0); return private_data; } @@ -473,6 +479,20 @@ int cifs_close(struct inode *inode, struct file *file) /* no sense reconnecting to close a file that is already closed */ if (pTcon->tidStatus != CifsNeedReconnect) { + int timeout = 2; + while((atomic_read(&pSMBFile->wrtPending) != 0) + && (timeout < 1000) ) { + /* Give write a better chance to get to + server ahead of the close. We do not + want to add a wait_q here as it would + increase the memory utilization as + the struct would be in each open file, + but this should give enough time to + clear the socket */ + cERROR(1,("close with pending writes")); + msleep(timeout); + timeout *= 4; + } write_unlock(&file->f_owner.lock); rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid); @@ -919,9 +939,10 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || (open_file->pfile->f_flags & O_WRONLY))) { + atomic_inc(&open_file->wrtPending); read_unlock(&GlobalSMBSeslock); if((open_file->invalidHandle) && - (!open_file->closePend)) { + (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { rc = cifs_reopen_file(&cifs_inode->vfs_inode, open_file->pfile, FALSE); /* if it fails, try another handle - might be */ @@ -929,6 +950,10 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) if(rc) { cFYI(1,("failed on reopen file in wp")); read_lock(&GlobalSMBSeslock); + /* can not use this handle, no write + pending on this one after all */ + atomic_dec + (&open_file->wrtPending); continue; } } @@ -981,6 +1006,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) if (open_file) { bytes_written = cifs_write(open_file->pfile, write_data, to-from, &offset); + atomic_dec(&open_file->wrtPending); /* Does mm or vfs already set times? */ inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); if ((bytes_written > 0) && (offset)) { @@ -1016,7 +1042,7 @@ static int cifs_writepages(struct address_space *mapping, pgoff_t next; int nr_pages; __u64 offset = 0; - struct cifsFileInfo *open_file = NULL; + struct cifsFileInfo *open_file; struct page *page; struct pagevec pvec; int rc = 0; @@ -1071,15 +1097,6 @@ static int cifs_writepages(struct address_space *mapping, int first; unsigned int i; - if (!open_file) { - open_file = find_writable_file(CIFS_I(mapping->host)); - if (!open_file) { - pagevec_release(&pvec); - cERROR(1, ("No writable handles for inode")); - return -EIO; - } - } - first = -1; next = 0; n_iov = 0; @@ -1155,18 +1172,32 @@ static int cifs_writepages(struct address_space *mapping, break; } if (n_iov) { - rc = CIFSSMBWrite2(xid, cifs_sb->tcon, - open_file->netfid, bytes_to_write, - offset, &bytes_written, iov, n_iov, - 1); - if (rc || bytes_written < bytes_to_write) { - cERROR(1,("CIFSSMBWrite2 returned %d, written = %x", - rc, bytes_written)); - set_bit(AS_EIO, &mapping->flags); - SetPageError(page); + /* Search for a writable handle every time we call + * CIFSSMBWrite2. We can't rely on the last handle + * we used to still be valid + */ + open_file = find_writable_file(CIFS_I(mapping->host)); + if (!open_file) { + cERROR(1, ("No writable handles for inode")); + rc = -EBADF; } else { - cifs_stats_bytes_written(cifs_sb->tcon, - bytes_written); + rc = CIFSSMBWrite2(xid, cifs_sb->tcon, + open_file->netfid, + bytes_to_write, offset, + &bytes_written, iov, n_iov, + 1); + atomic_dec(&open_file->wrtPending); + if (rc || bytes_written < bytes_to_write) { + cERROR(1,("Write2 ret %d, written = %d", + rc, bytes_written)); + /* BB what if continued retry is + requested via mount flags? */ + set_bit(AS_EIO, &mapping->flags); + SetPageError(page); + } else { + cifs_stats_bytes_written(cifs_sb->tcon, + bytes_written); + } } for (i = 0; i < n_iov; i++) { page = pvec.pages[first + i]; @@ -1788,9 +1819,18 @@ static int cifs_readpage(struct file *file, struct page *page) page caching in the current Linux kernel design */ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode) { - if (cifsInode && find_writable_file(cifsInode)) + struct cifsFileInfo *open_file = NULL; + + if (cifsInode) + open_file = find_writable_file(cifsInode); + + if(open_file) { + /* there is not actually a write pending so let + this handle go free and allow it to + be closable if needed */ + atomic_dec(&open_file->wrtPending); return 0; - else + } else return 1; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ff4d1cc7c248..912d401600f6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1006,6 +1006,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) __u32 npid = open_file->pid; rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, npid, FALSE); + atomic_dec(&open_file->wrtPending); cFYI(1,("SetFSize for attrs rc = %d", rc)); if(rc == -EINVAL) { int bytes_written; From b0faa28493f97b55b36ff5b1a2b8c81bf253a460 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 21 Oct 2005 15:43:42 +1000 Subject: [PATCH 0367/1940] [PATCH] Fix broken initialization of conswitchp for ARCH=ppc64 In the merge tree, commit 0458060c1c59c5378d8fb5daabe18cf4681c35cd broke boot on some machines because the initialization of conswitchp was moved to arch/powerpc/kernel/setup_64.c, but a corresponding copy was not added to arch/ppc64/kernel/setup.c. This patch fixes it. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/setup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 42019be0c6ad..b7885028fcf1 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -1039,6 +1039,10 @@ void __init setup_arch(char **cmdline_p) /* initialize the syscall map in systemcfg */ setup_syscall_map(); +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + ppc_md.setup_arch(); /* Use the default idle loop if the platform hasn't provided one. */ From 6cb7bfebb145af5ea1d052512a2ae7ff07a47202 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 21 Oct 2005 15:45:50 +1000 Subject: [PATCH 0368/1940] [PATCH] powerpc: Merge thread_info.h Merge ppc32 and ppc64 versions of thread_info.h. They were pretty similar already, the chief changes are: - Instead of inline asm to implement current_thread_info(), which needs to be different for ppc32 and ppc64, we use C with an asm("r1") register variable. gcc turns it into the same asm as we used to have for both platforms. - We replace ppc32's 'local_flags' with the ppc64 'syscall_noerror' field. The noerror flag was in fact the only thing in the local_flags field anyway, so the ppc64 approach is simpler, and means we only need a load-immediate/store instead of load/mask/store when clearing the flag. - In readiness for 64k pages, when THREAD_SIZE will be less than a page, ppc64 used kmalloc() rather than get_free_pages() to allocate the kernel stack. With this patch we do the same for ppc32, since there's no strong reason not to. - For ppc64, we no longer export THREAD_SHIFT and THREAD_SIZE via asm-offsets, thread_info.h can now be safely included in asm, as on ppc32. Built and booted on G4 Powerbook (ARCH=ppc and ARCH=powerpc) and Power5 (ARCH=ppc64 and ARCH=powerpc). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/asm-offsets.c | 6 +- arch/powerpc/kernel/entry_32.S | 25 ++-- arch/powerpc/kernel/head_64.S | 1 + arch/powerpc/kernel/misc_64.S | 1 + arch/ppc/kernel/asm-offsets.c | 2 +- arch/ppc/kernel/entry.S | 9 +- arch/ppc64/kernel/asm-offsets.c | 2 - arch/ppc64/kernel/head.S | 1 + arch/ppc64/kernel/misc.S | 1 + .../{asm-ppc64 => asm-powerpc}/thread_info.h | 34 ++++-- include/asm-ppc/ptrace.h | 2 +- include/asm-ppc/thread_info.h | 107 ------------------ 12 files changed, 45 insertions(+), 146 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/thread_info.h (84%) delete mode 100644 include/asm-ppc/thread_info.h diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index b0d6a7cd85e9..1c83abd9f37c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -56,8 +56,6 @@ int main(void) DEFINE(THREAD, offsetof(struct task_struct, thread)); DEFINE(MM, offsetof(struct task_struct, mm)); #ifdef CONFIG_PPC64 - DEFINE(THREAD_SHIFT, THREAD_SHIFT); - DEFINE(THREAD_SIZE, THREAD_SIZE); DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); #else DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); @@ -94,12 +92,10 @@ int main(void) DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -#ifdef CONFIG_PPC64 DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); -#else +#ifdef CONFIG_PPC32 DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); - DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index fc9dded9ac04..37b4396ca978 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -199,10 +199,9 @@ _GLOBAL(DoSyscall) #ifdef SHOW_SYSCALLS bl do_show_syscall #endif /* SHOW_SYSCALLS */ - rlwinm r10,r1,0,0,18 /* current_thread_info() */ - lwz r11,TI_LOCAL_FLAGS(r10) - rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR - stw r11,TI_LOCAL_FLAGS(r10) + rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + li r11,0 + stb r11,TI_SC_NOERR(r10) lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A bne- syscall_dotrace @@ -225,10 +224,10 @@ ret_from_syscall: mr r6,r3 li r11,-_LAST_ERRNO cmplw 0,r3,r11 - rlwinm r12,r1,0,0,18 /* current_thread_info() */ + rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ blt+ 30f - lwz r11,TI_LOCAL_FLAGS(r12) - andi. r11,r11,_TIFL_FORCE_NOERROR + lbz r11,TI_SC_NOERR(r12) + cmpwi r11,0 bne 30f neg r3,r3 lwz r10,_CCR(r1) /* Set SO bit in CR */ @@ -315,7 +314,7 @@ syscall_exit_work: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) /* disable interrupts again */ - rlwinm r12,r1,0,0,18 /* current_thread_info() */ + rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ lwz r9,TI_FLAGS(r12) 5: andi. r0,r9,_TIF_NEED_RESCHED @@ -630,7 +629,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) .globl sigreturn_exit sigreturn_exit: subi r1,r3,STACK_FRAME_OVERHEAD - rlwinm r12,r1,0,0,18 /* current_thread_info() */ + rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ lwz r9,TI_FLAGS(r12) andi. r0,r9,_TIF_SYSCALL_T_OR_A beq+ ret_from_except_full @@ -657,7 +656,7 @@ ret_from_except: user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ - rlwinm r9,r1,0,0,18 + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r9,TI_FLAGS(r9) andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne do_work @@ -677,7 +676,7 @@ restore_user: /* N.B. the only way to get here is from the beq following ret_from_except. */ resume_kernel: /* check current_thread_info->preempt_count */ - rlwinm r9,r1,0,0,18 + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r0,TI_PREEMPT(r9) cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ bne restore @@ -687,7 +686,7 @@ resume_kernel: andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ 1: bl preempt_schedule_irq - rlwinm r9,r1,0,0,18 + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r3,TI_FLAGS(r9) andi. r0,r3,_TIF_NEED_RESCHED bne- 1b @@ -889,7 +888,7 @@ recheck: LOAD_MSR_KERNEL(r10,MSR_KERNEL) SYNC MTMSRD(r10) /* disable interrupts */ - rlwinm r9,r1,0,0,18 + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r9,TI_FLAGS(r9) andi. r0,r9,_TIF_NEED_RESCHED bne- do_resched diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a4ceb9ae20fc..72b0d26e41d4 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 8fe295693c09..4775bed42cac 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -26,6 +26,7 @@ #include #include #include +#include .text diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c index 7972db1f6570..968261d69572 100644 --- a/arch/ppc/kernel/asm-offsets.c +++ b/arch/ppc/kernel/asm-offsets.c @@ -130,10 +130,10 @@ main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 68fc61221776..f044edbb454f 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -200,9 +200,8 @@ _GLOBAL(DoSyscall) bl do_show_syscall #endif /* SHOW_SYSCALLS */ rlwinm r10,r1,0,0,18 /* current_thread_info() */ - lwz r11,TI_LOCAL_FLAGS(r10) - rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR - stw r11,TI_LOCAL_FLAGS(r10) + li r11,0 + stb r11,TI_SC_NOERR(r10) lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A bne- syscall_dotrace @@ -227,8 +226,8 @@ ret_from_syscall: cmplw 0,r3,r11 rlwinm r12,r1,0,0,18 /* current_thread_info() */ blt+ 30f - lwz r11,TI_LOCAL_FLAGS(r12) - andi. r11,r11,_TIFL_FORCE_NOERROR + lbz r11,TI_SC_NOERR(r12) + cmpwi r11,0 bne 30f neg r3,r3 lwz r10,_CCR(r1) /* Set SO bit in CR */ diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index 1378fbbe1e57..5e6046cb414e 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c @@ -46,8 +46,6 @@ int main(void) { /* thread struct on stack */ - DEFINE(THREAD_SHIFT, THREAD_SHIFT); - DEFINE(THREAD_SIZE, THREAD_SIZE); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index d5e6be200764..15c5f0c48043 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index ad73aad8dbb6..a33448c2bd91 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -28,6 +28,7 @@ #include #include #include +#include .text diff --git a/include/asm-ppc64/thread_info.h b/include/asm-powerpc/thread_info.h similarity index 84% rename from include/asm-ppc64/thread_info.h rename to include/asm-powerpc/thread_info.h index 71244d8a427d..0b4c24551c21 100644 --- a/include/asm-ppc64/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -1,15 +1,25 @@ -/* thread_info.h: PPC low-level thread information +/* thread_info.h: PowerPC low-level thread information * adapted from the i386 version by Paul Mackerras * * Copyright (C) 2002 David Howells (dhowells@redhat.com) * - Incorporating suggestions made by Linus Torvalds and Dave Miller */ -#ifndef _ASM_THREAD_INFO_H -#define _ASM_THREAD_INFO_H +#ifndef _ASM_POWERPC_THREAD_INFO_H +#define _ASM_POWERPC_THREAD_INFO_H #ifdef __KERNEL__ +/* We have 8k stacks on ppc32 and 16k on ppc64 */ + +#ifdef CONFIG_PPC64 +#define THREAD_SHIFT 14 +#else +#define THREAD_SHIFT 13 +#endif + +#define THREAD_SIZE (1 << THREAD_SHIFT) + #ifndef __ASSEMBLY__ #include #include @@ -24,7 +34,8 @@ struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ int cpu; /* cpu we're on */ - int preempt_count; /* 0 => preemptable, <0 => BUG */ + int preempt_count; /* 0 => preemptable, + <0 => BUG */ struct restart_block restart_block; /* set by force_successful_syscall_return */ unsigned char syscall_noerror; @@ -54,9 +65,6 @@ struct thread_info { /* thread information allocation */ -#define THREAD_SHIFT 14 -#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT) -#define THREAD_SIZE (1 << THREAD_SHIFT) #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ ({ \ @@ -68,7 +76,7 @@ struct thread_info { ret; \ }) #else -#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) +#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) #endif #define free_thread_info(ti) kfree(ti) #define get_thread_info(ti) get_task_struct((ti)->task) @@ -77,9 +85,11 @@ struct thread_info { /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) { - struct thread_info *ti; - __asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT)); - return ti; + register unsigned long sp asm("r1"); + + /* gcc4, at least, is smart enough to turn this into a single + * rlwinm for ppc32 and clrrdi for ppc64 */ + return (struct thread_info *)(sp & ~(THREAD_SIZE-1)); } #endif /* __ASSEMBLY__ */ @@ -122,4 +132,4 @@ static inline struct thread_info *current_thread_info(void) #endif /* __KERNEL__ */ -#endif /* _ASM_THREAD_INFO_H */ +#endif /* _ASM_POWERPC_THREAD_INFO_H */ diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h index 7043c164b537..c34fb4e37a97 100644 --- a/include/asm-ppc/ptrace.h +++ b/include/asm-ppc/ptrace.h @@ -57,7 +57,7 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define force_successful_syscall_return() \ do { \ - current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \ + current_thread_info()->syscall_noerror = 1; \ } while(0) /* diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h deleted file mode 100644 index 27903db42efc..000000000000 --- a/include/asm-ppc/thread_info.h +++ /dev/null @@ -1,107 +0,0 @@ -/* thread_info.h: PPC low-level thread information - * adapted from the i386 version by Paul Mackerras - * - * Copyright (C) 2002 David Howells (dhowells@redhat.com) - * - Incorporating suggestions made by Linus Torvalds and Dave Miller - */ - -#ifndef _ASM_THREAD_INFO_H -#define _ASM_THREAD_INFO_H - -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ -/* - * low level task data. - * If you change this, change the TI_* offsets below to match. - */ -struct thread_info { - struct task_struct *task; /* main task structure */ - struct exec_domain *exec_domain; /* execution domain */ - unsigned long flags; /* low level flags */ - unsigned long local_flags; /* non-racy flags */ - int cpu; /* cpu we're on */ - int preempt_count; /* 0 => preemptable, - <0 => BUG */ - struct restart_block restart_block; -}; - -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .exec_domain = &default_exec_domain, \ - .flags = 0, \ - .local_flags = 0, \ - .cpu = 0, \ - .preempt_count = 1, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ -} - -#define init_thread_info (init_thread_union.thread_info) -#define init_stack (init_thread_union.stack) - -/* - * macros/functions for gaining access to the thread information structure - */ - -/* how to get the thread information struct from C */ -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - __asm__("rlwinm %0,1,0,0,18" : "=r"(ti)); - return ti; -} - -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL, 1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) -#define get_thread_info(ti) get_task_struct((ti)->task) -#define put_thread_info(ti) put_task_struct((ti)->task) -#endif /* __ASSEMBLY__ */ - -/* - * Size of kernel stack for each process. - */ -#define THREAD_SIZE 8192 /* 2 pages */ - -#define PREEMPT_ACTIVE 0x10000000 - -/* - * thread information flag bit numbers - */ -#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ -#define TIF_SIGPENDING 2 /* signal pending */ -#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ -#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling - TIF_NEED_RESCHED */ -#define TIF_MEMDIE 5 -#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ -#define TIF_SECCOMP 7 /* secure computing */ - -/* as above, but as bit values */ -#define _TIF_SYSCALL_TRACE (1< Date: Fri, 21 Oct 2005 16:01:33 +1000 Subject: [PATCH 0369/1940] [PATCH] powerpc: Don't blow away load_addr in start_thread The patch to make process.c work for 32-bit and 64-bit (06d67d54741a5bfefa31945ef195dfa748c29025) broke some 64-bit binaries. We were blowing away load_addr in gpr[2], so we weren't properly relocating the entry point. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/process.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 193c8c1bf132..047da1ae21fe 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -595,6 +595,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, */ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) { +#ifdef CONFIG_PPC64 + unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ +#endif + set_fs(USER_DS); /* @@ -621,7 +625,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->msr = MSR_USER; #else if (!test_thread_flag(TIF_32BIT)) { - unsigned long entry, toc, load_addr = regs->gpr[2]; + unsigned long entry, toc; /* start is a relocated pointer to the function descriptor for * the elf _start routine. The first entry in the function From 05d84681abcb33fe34accb5982c413daeb4208c4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 21 Oct 2005 16:01:34 +1000 Subject: [PATCH 0370/1940] [PATCH] powerpc: Fix mmap returning 64 bit addresses The merge of syscalls.c & sys_ppc32.c (30286ef6e044bc3d9019c3d8b900572e3fa05e65) broke mmap, if the mmap returned a 64 bit address. do_mmap2 was taking the return value from do_mmap_pgoff (an unsigned long), and storing it in an int, before returning it to sys_mmap as an unsigned long. So we were losing the high bits of the address. You would have thought the compiler could catch this for us ... Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/syscalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 7a23721365a6..f72ced11212d 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -162,7 +162,7 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, unsigned long fd, unsigned long off, int shift) { struct file * file = NULL; - int ret = -EINVAL; + unsigned long ret = -EINVAL; if (shift) { if (off & ((1 << shift) - 1)) From 5658374766d9e0249bd04e9d62bdb8456b916b64 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:33:38 -0400 Subject: [PATCH 0371/1940] [PARISC] Convert parisc_device tree to use struct device klists Fix parse_tree_node. much more needs to be done to fix this file. Signed-off-by: Matthew Wilcox Make drivers.c compile based on a patch from Pat Mochel. From: Patrick Mochel Signed-off-by: Kyle McMartin Fix drivers.c to create new device tree nodes when no match is found. Signed-off-by: Richard Hirst Do a proper depth-first search returning parents before children, using the new klist infrastructure. Signed-off-by: Richard Hirst Fixed parisc_device traversal so that pdc_stable works again Fixed check_dev so it doesn't dereference a parisc_device until it has verified the bus type Signed-off-by: Randolph Chung Convert pa_dev->hpa from an unsigned long to a struct resource. Use insert_resource() instead of request_mem_region(). Request resources at bus walk time instead of driver probe time. Don't release the resources as we don't have any hotplug parisc_device support yet. Add parisc_pathname() to conveniently get the textual representation of the hwpath used in sysfs. Inline the remnants of claim_device() into its caller. Signed-off-by: Matthew Wilcox I noticed that some of the STI regions weren't showing up in iomem. Reading the STI spec indicated that all STI devices occupy at least 32MB. So check for STI HPAs and give them 32MB instead of 4kB. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/drivers.c | 273 ++++++++++++++++++++--------- drivers/parisc/gsc.c | 11 +- drivers/parisc/sba_iommu.c | 20 ++- include/asm-parisc/parisc-device.h | 5 + 4 files changed, 217 insertions(+), 92 deletions(-) diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index d34bbe7ae0e3..988844a169e6 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -46,36 +46,51 @@ static struct device root = { .bus_id = "parisc", }; -#define for_each_padev(padev) \ - for (padev = next_dev(&root); padev != NULL; \ - padev = next_dev(&padev->dev)) +static inline int check_dev(struct device *dev) +{ + if (dev->bus == &parisc_bus_type) { + struct parisc_device *pdev; + pdev = to_parisc_device(dev); + return pdev->id.hw_type != HPHW_FAULTY; + } + return 1; +} -#define check_dev(padev) \ - (padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev) +static struct device * +parse_tree_node(struct device *parent, int index, struct hardware_path *modpath); + +struct recurse_struct { + void * obj; + int (*fn)(struct device *, void *); +}; + +static int descend_children(struct device * dev, void * data) +{ + struct recurse_struct * recurse_data = (struct recurse_struct *)data; + + if (recurse_data->fn(dev, recurse_data->obj)) + return 1; + else + return device_for_each_child(dev, recurse_data, descend_children); +} /** - * next_dev - enumerates registered devices - * @dev: the previous device returned from next_dev + * for_each_padev - Iterate over all devices in the tree + * @fn: Function to call for each device. + * @data: Data to pass to the called function. * - * next_dev does a depth-first search of the tree, returning parents - * before children. Returns NULL when there are no more devices. + * This performs a depth-first traversal of the tree, calling the + * function passed for each node. It calls the function for parents + * before children. */ -static struct parisc_device *next_dev(struct device *dev) + +static int for_each_padev(int (*fn)(struct device *, void *), void * data) { - if (!list_empty(&dev->children)) { - dev = list_to_dev(dev->children.next); - return check_dev(to_parisc_device(dev)); - } - - while (dev != &root) { - if (dev->node.next != &dev->parent->children) { - dev = list_to_dev(dev->node.next); - return to_parisc_device(dev); - } - dev = dev->parent; - } - - return NULL; + struct recurse_struct recurse_data = { + .obj = data, + .fn = fn, + }; + return device_for_each_child(&root, &recurse_data, descend_children); } /** @@ -105,12 +120,6 @@ static int match_device(struct parisc_driver *driver, struct parisc_device *dev) return 0; } -static void claim_device(struct parisc_driver *driver, struct parisc_device *dev) -{ - dev->driver = driver; - request_mem_region(dev->hpa, 0x1000, driver->name); -} - static int parisc_driver_probe(struct device *dev) { int rc; @@ -119,8 +128,8 @@ static int parisc_driver_probe(struct device *dev) rc = pa_drv->probe(pa_dev); - if(!rc) - claim_device(pa_drv, pa_dev); + if (!rc) + pa_dev->driver = pa_drv; return rc; } @@ -131,7 +140,6 @@ static int parisc_driver_remove(struct device *dev) struct parisc_driver *pa_drv = to_parisc_driver(dev->driver); if (pa_drv->remove) pa_drv->remove(pa_dev); - release_mem_region(pa_dev->hpa, 0x1000); return 0; } @@ -173,6 +181,24 @@ int register_parisc_driver(struct parisc_driver *driver) } EXPORT_SYMBOL(register_parisc_driver); + +struct match_count { + struct parisc_driver * driver; + int count; +}; + +static int match_and_count(struct device * dev, void * data) +{ + struct match_count * m = data; + struct parisc_device * pdev = to_parisc_device(dev); + + if (check_dev(dev)) { + if (match_device(m->driver, pdev)) + m->count++; + } + return 0; +} + /** * count_parisc_driver - count # of devices this driver would match * @driver: the PA-RISC driver to try @@ -182,15 +208,14 @@ EXPORT_SYMBOL(register_parisc_driver); */ int count_parisc_driver(struct parisc_driver *driver) { - struct parisc_device *device; - int cnt = 0; + struct match_count m = { + .driver = driver, + .count = 0, + }; - for_each_padev(device) { - if (match_device(driver, device)) - cnt++; - } + for_each_padev(match_and_count, &m); - return cnt; + return m.count; } @@ -206,14 +231,34 @@ int unregister_parisc_driver(struct parisc_driver *driver) } EXPORT_SYMBOL(unregister_parisc_driver); +struct find_data { + unsigned long hpa; + struct parisc_device * dev; +}; + +static int find_device(struct device * dev, void * data) +{ + struct parisc_device * pdev = to_parisc_device(dev); + struct find_data * d = (struct find_data*)data; + + if (check_dev(dev)) { + if (pdev->hpa.start == d->hpa) { + d->dev = pdev; + return 1; + } + } + return 0; +} + static struct parisc_device *find_device_by_addr(unsigned long hpa) { - struct parisc_device *dev; - for_each_padev(dev) { - if (dev->hpa == hpa) - return dev; - } - return NULL; + struct find_data d = { + .hpa = hpa, + }; + int ret; + + ret = for_each_padev(find_device, &d); + return ret ? d.dev : NULL; } /** @@ -387,6 +432,23 @@ struct parisc_device * create_tree_node(char id, struct device *parent) return dev; } +struct match_id_data { + char id; + struct parisc_device * dev; +}; + +static int match_by_id(struct device * dev, void * data) +{ + struct parisc_device * pdev = to_parisc_device(dev); + struct match_id_data * d = data; + + if (pdev->hw_path == d->id) { + d->dev = pdev; + return 1; + } + return 0; +} + /** * alloc_tree_node - returns a device entry in the iotree * @parent: the parent node in the tree @@ -397,15 +459,13 @@ struct parisc_device * create_tree_node(char id, struct device *parent) */ static struct parisc_device * alloc_tree_node(struct device *parent, char id) { - struct device *dev; - - list_for_each_entry(dev, &parent->children, node) { - struct parisc_device *padev = to_parisc_device(dev); - if (padev->hw_path == id) - return padev; - } - - return create_tree_node(id, parent); + struct match_id_data d = { + .id = id, + }; + if (device_for_each_child(parent, &d, match_by_id)) + return d.dev; + else + return create_tree_node(id, parent); } static struct parisc_device *create_parisc_device(struct hardware_path *modpath) @@ -439,10 +499,8 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path) dev = create_parisc_device(mod_path); if (dev->id.hw_type != HPHW_FAULTY) { - char p[64]; - print_pa_hwpath(dev, p); printk("Two devices have hardware path %s. Please file a bug with HP.\n" - "In the meantime, you could try rearranging your cards.\n", p); + "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev)); return NULL; } @@ -451,12 +509,27 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path) dev->id.hversion_rev = iodc_data[1] & 0x0f; dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) | (iodc_data[5] << 8) | iodc_data[6]; - dev->hpa = hpa; + dev->hpa.name = parisc_pathname(dev); + dev->hpa.start = hpa; + if (hpa == 0xf4000000 || hpa == 0xf6000000 || + hpa == 0xf8000000 || hpa == 0xfa000000) { + dev->hpa.end = hpa + 0x01ffffff; + } else { + dev->hpa.end = hpa + 0xfff; + } + dev->hpa.flags = IORESOURCE_MEM; name = parisc_hardware_description(&dev->id); if (name) { strlcpy(dev->name, name, sizeof(dev->name)); } + /* Silently fail things like mouse ports which are subsumed within + * the keyboard controller + */ + if ((hpa & 0xfff) == 0 && insert_resource(&iomem_resource, &dev->hpa)) + printk("Unable to claim HPA %lx for device %s\n", + hpa, name); + return dev; } @@ -555,6 +628,33 @@ static int match_parisc_device(struct device *dev, int index, return (curr->hw_path == id); } +struct parse_tree_data { + int index; + struct hardware_path * modpath; + struct device * dev; +}; + +static int check_parent(struct device * dev, void * data) +{ + struct parse_tree_data * d = data; + + if (check_dev(dev)) { + if (dev->bus == &parisc_bus_type) { + if (match_parisc_device(dev, d->index, d->modpath)) + d->dev = dev; + } else if (is_pci_dev(dev)) { + if (match_pci_device(dev, d->index, d->modpath)) + d->dev = dev; + } else if (dev->bus == NULL) { + /* we are on a bus bridge */ + struct device *new = parse_tree_node(dev, d->index, d->modpath); + if (new) + d->dev = new; + } + } + return d->dev != NULL; +} + /** * parse_tree_node - returns a device entry in the iotree * @parent: the parent node in the tree @@ -568,24 +668,18 @@ static int match_parisc_device(struct device *dev, int index, static struct device * parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) { - struct device *device; - - list_for_each_entry(device, &parent->children, node) { - if (device->bus == &parisc_bus_type) { - if (match_parisc_device(device, index, modpath)) - return device; - } else if (is_pci_dev(device)) { - if (match_pci_device(device, index, modpath)) - return device; - } else if (device->bus == NULL) { - /* we are on a bus bridge */ - struct device *new = parse_tree_node(device, index, modpath); - if (new) - return new; - } - } + struct parse_tree_data d = { + .index = index, + .modpath = modpath, + }; - return NULL; + struct recurse_struct recurse_data = { + .obj = &d, + .fn = check_parent, + }; + + device_for_each_child(parent, &recurse_data, descend_children); + return d.dev; } /** @@ -636,7 +730,7 @@ EXPORT_SYMBOL(device_to_hwpath); ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT)) #define IS_LOWER_PORT(dev) \ - ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \ + ((gsc_readl(dev->hpa.start + offsetof(struct bc_module, io_status)) \ & BC_PORT_MASK) == BC_LOWER_PORT) #define MAX_NATIVE_DEVICES 64 @@ -645,8 +739,8 @@ EXPORT_SYMBOL(device_to_hwpath); #define FLEX_MASK F_EXTEND(0xfffc0000) #define IO_IO_LOW offsetof(struct bc_module, io_io_low) #define IO_IO_HIGH offsetof(struct bc_module, io_io_high) -#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW) -#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH) +#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_LOW) +#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_HIGH) static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, struct device *parent); @@ -655,10 +749,10 @@ void walk_lower_bus(struct parisc_device *dev) { unsigned long io_io_low, io_io_high; - if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev)) + if (!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev)) return; - if(dev->id.hw_type == HPHW_IOA) { + if (dev->id.hw_type == HPHW_IOA) { io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16); io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET; } else { @@ -731,7 +825,7 @@ static void print_parisc_device(struct parisc_device *dev) print_pa_hwpath(dev, hw_path); printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }", - ++count, dev->name, dev->hpa, hw_path, dev->id.hw_type, + ++count, dev->name, dev->hpa.start, hw_path, dev->id.hw_type, dev->id.hversion_rev, dev->id.hversion, dev->id.sversion); if (dev->num_addrs) { @@ -753,13 +847,20 @@ void init_parisc_bus(void) get_device(&root); } + +static int print_one_device(struct device * dev, void * data) +{ + struct parisc_device * pdev = to_parisc_device(dev); + + if (check_dev(dev)) + print_parisc_device(pdev); + return 0; +} + /** * print_parisc_devices - Print out a list of devices found in this system */ void print_parisc_devices(void) { - struct parisc_device *dev; - for_each_padev(dev) { - print_parisc_device(dev); - } + for_each_padev(print_one_device, NULL); } diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index af5e02526a18..16d40f95978d 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -183,12 +183,20 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) *irqp = irq; } +static struct device *next_device(struct klist_iter *i) +{ + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; +} + void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, void (*choose_irq)(struct parisc_device *, void *)) { struct device *dev; + struct klist_iter i; - list_for_each_entry(dev, &parent->dev.children, node) { + klist_iter_init(&parent->dev.klist_children, &i); + while ((dev = next_device(&i))) { struct parisc_device *padev = to_parisc_device(dev); /* work-around for 715/64 and others which have parent @@ -197,6 +205,7 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, return gsc_fixup_irqs(padev, ctrl, choose_irq); choose_irq(padev, ctrl); } + klist_iter_exit(&i); } int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 82ea68b55df4..a8405f05fb5f 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -1322,19 +1322,29 @@ sba_alloc_pdir(unsigned int pdir_size) return (void *) pdir_base; } -/* setup Mercury or Elroy IBASE/IMASK registers. */ -static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) +static struct device *next_device(struct klist_iter *i) { - /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; +} + +/* setup Mercury or Elroy IBASE/IMASK registers. */ +static void +setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) +{ + /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ extern void lba_set_iregs(struct parisc_device *, u32, u32); struct device *dev; + struct klist_iter i; - list_for_each_entry(dev, &sba->dev.children, node) { + klist_iter_init(&sba->dev.klist_children, &i); + while ((dev = next_device(&i))) { struct parisc_device *lba = to_parisc_device(dev); - int rope_num = (lba->hpa >> 13) & 0xf; + int rope_num = (lba->hpa.start >> 13) & 0xf; if (rope_num >> 3 == ioc_num) lba_set_iregs(lba, ioc->ibase, ioc->imask); } + klist_iter_exit(&i); } static void diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h index ef69ab4b17a9..cbde8b41c84b 100644 --- a/include/asm-parisc/parisc-device.h +++ b/include/asm-parisc/parisc-device.h @@ -39,6 +39,11 @@ struct parisc_driver { #define to_parisc_driver(d) container_of(d, struct parisc_driver, drv) #define parisc_parent(d) to_parisc_device(d->dev.parent) +static inline char *parisc_pathname(struct parisc_device *d) +{ + return d->dev.bus_id; +} + static inline void parisc_set_drvdata(struct parisc_device *d, void *p) { From bdad1f836ab1ca2b18a625222f63f630cfd14e41 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:36:23 -0400 Subject: [PATCH 0372/1940] [PARISC] Change the driver names so /sys/bus/parisc/drivers/ looks better Make /sys/bus/parisc/drivers look better by cleaning up parisc_driver names. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/input/keyboard/hilkbd.c | 2 +- drivers/input/serio/gscps2.c | 2 +- drivers/input/serio/hp_sdc.c | 2 +- drivers/net/lasi_82596.c | 2 +- drivers/parisc/asp.c | 2 +- drivers/parisc/ccio-dma.c | 2 +- drivers/parisc/dino.c | 4 ++-- drivers/parisc/eisa.c | 2 +- drivers/parisc/hppb.c | 2 +- drivers/parisc/lasi.c | 2 +- drivers/scsi/lasi700.c | 2 +- drivers/serial/mux.c | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index eecb77db0847..8aa81c9ac2f7 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -299,7 +299,7 @@ static struct parisc_device_id hil_tbl[] = { MODULE_DEVICE_TABLE(parisc, hil_tbl); static struct parisc_driver hil_driver = { - .name = "HIL", + .name = "hil", .id_table = hil_tbl, .probe = hil_init_chip, }; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 897e4c12b642..4bad2810190c 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -444,7 +444,7 @@ static struct parisc_device_id gscps2_device_tbl[] = { }; static struct parisc_driver parisc_ps2_driver = { - .name = "GSC PS2", + .name = "gsc_ps2", .id_table = gscps2_device_tbl, .probe = gscps2_probe, .remove = gscps2_remove, diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 7629452dd64b..045b9a7a9dbb 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); static int __init hp_sdc_init_hppa(struct parisc_device *d); static struct parisc_driver hp_sdc_driver = { - .name = "HP SDC", + .name = "hp_sdc", .id_table = hp_sdc_tbl, .probe = hp_sdc_init_hppa, }; diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 41bad07ac1ac..180e526a2049 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -1566,7 +1566,7 @@ static struct parisc_device_id lan_tbl[] = { MODULE_DEVICE_TABLE(parisc, lan_tbl); static struct parisc_driver lan_driver = { - .name = "Apricot", + .name = "lasi_82596", .id_table = lan_tbl, .probe = lan_init_chip, }; diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c index 388609967133..52f37b424318 100644 --- a/drivers/parisc/asp.c +++ b/drivers/parisc/asp.c @@ -126,7 +126,7 @@ static struct parisc_device_id asp_tbl[] = { }; struct parisc_driver asp_driver = { - .name = "Asp", + .name = "asp", .id_table = asp_tbl, .probe = asp_init_chip, }; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 0e98a9d9834c..2bb1889c4c4f 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1251,7 +1251,7 @@ static struct parisc_device_id ccio_tbl[] = { static int ccio_probe(struct parisc_device *dev); static struct parisc_driver ccio_driver = { - .name = "U2:Uturn", + .name = "ccio", .id_table = ccio_tbl, .probe = ccio_probe, }; diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 2f2dbef2c3b7..8c61705e67a5 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -1027,9 +1027,9 @@ static struct parisc_device_id dino_tbl[] = { }; static struct parisc_driver dino_driver = { - .name = "Dino", + .name = "dino", .id_table = dino_tbl, - .probe = dino_driver_callback, + .probe = dino_probe, }; /* diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 043d47aea75b..0afeedddf535 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -397,7 +397,7 @@ static struct parisc_device_id eisa_tbl[] = { MODULE_DEVICE_TABLE(parisc, eisa_tbl); static struct parisc_driver eisa_driver = { - .name = "EISA Bus Adapter", + .name = "eisa_ba", .id_table = eisa_tbl, .probe = eisa_probe, }; diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index e869c6020370..a6eae3e7c0cd 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -93,7 +93,7 @@ static struct parisc_device_id hppb_tbl[] = { }; static struct parisc_driver hppb_driver = { - .name = "Gecko Boa", + .name = "gecko_boa", .id_table = hppb_tbl, .probe = hppb_probe, }; diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index cb84a4e84a2f..c776c372ae4e 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -233,7 +233,7 @@ static struct parisc_device_id lasi_tbl[] = { }; struct parisc_driver lasi_driver = { - .name = "Lasi", + .name = "lasi", .id_table = lasi_tbl, .probe = lasi_init_chip, }; diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 4cbb6187cc44..123f4933d8f5 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -168,7 +168,7 @@ lasi700_driver_remove(struct parisc_device *dev) } static struct parisc_driver lasi700_driver = { - .name = "Lasi SCSI", + .name = "lasi_scsi", .id_table = lasi700_ids, .probe = lasi700_probe, .remove = __devexit_p(lasi700_driver_remove), diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 189064607709..a12005b08bca 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -497,7 +497,7 @@ static struct parisc_device_id mux_tbl[] = { MODULE_DEVICE_TABLE(parisc, mux_tbl); static struct parisc_driver serial_mux_driver = { - .name = "Serial MUX", + .name = "serial_mux", .id_table = mux_tbl, .probe = mux_probe, }; From 53f01bba49938f115237fe43a261c31ac13ae5c6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:36:40 -0400 Subject: [PATCH 0373/1940] [PARISC] Convert parisc_device to use struct resource for hpa Convert pa_dev->hpa from an unsigned long to a struct resource. Signed-off-by: Matthew Wilcox Fix up users of ->hpa to use ->hpa.start instead. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/perf.c | 12 +++++++----- arch/parisc/kernel/processor.c | 8 ++++---- drivers/input/keyboard/hilkbd.c | 4 ++-- drivers/input/serio/gscps2.c | 2 +- drivers/input/serio/hp_sdc.c | 6 +++--- drivers/net/lasi_82596.c | 7 ++++--- drivers/parisc/asp.c | 4 ++-- drivers/parisc/ccio-dma.c | 4 ++-- drivers/parisc/ccio-rm-dma.c | 2 +- drivers/parisc/dino.c | 6 +++--- drivers/parisc/eisa.c | 2 +- drivers/parisc/hppb.c | 8 ++++---- drivers/parisc/lasi.c | 2 +- drivers/parisc/lba_pci.c | 14 +++++++------- drivers/parisc/sba_iommu.c | 6 +++--- drivers/parisc/wax.c | 2 +- drivers/parport/parport_gsc.c | 5 +++-- drivers/scsi/lasi700.c | 2 +- drivers/scsi/zalon.c | 4 ++-- drivers/serial/8250_gsc.c | 5 +++-- drivers/serial/mux.c | 2 +- include/asm-parisc/parisc-device.h | 2 +- sound/parisc/harmony.c | 6 +++--- 23 files changed, 60 insertions(+), 55 deletions(-) diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index b3ad0a505b87..44670d6e06f4 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -746,7 +746,8 @@ static int perf_write_image(uint64_t *memaddr) uint64_t *bptr; uint32_t dwords; uint32_t *intrigue_rdr; - uint64_t *intrigue_bitmask, tmp64, proc_hpa; + uint64_t *intrigue_bitmask, tmp64; + void __iomem *runway; struct rdr_tbl_ent *tentry; int i; @@ -798,15 +799,16 @@ static int perf_write_image(uint64_t *memaddr) return -1; } - proc_hpa = cpu_device->hpa; + runway = ioremap(cpu_device->hpa.start, 4096); /* Merge intrigue bits into Runway STATUS 0 */ - tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful; - __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS); + tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful; + __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), + runway + RUNWAY_STATUS); /* Write RUNWAY DEBUG registers */ for (i = 0; i < 8; i++) { - __raw_writeq(*memaddr++, proc_hpa + RUNWAY_DEBUG + i); + __raw_writeq(*memaddr++, runway + RUNWAY_DEBUG); } return 0; diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 13b721cb9f55..4f5bbcf1f5a4 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -92,7 +92,7 @@ static int __init processor_probe(struct parisc_device *dev) * May get overwritten by PAT code. */ cpuid = boot_cpu_data.cpu_count; - txn_addr = dev->hpa; /* for legacy PDC */ + txn_addr = dev->hpa.start; /* for legacy PDC */ #ifdef __LP64__ if (is_pdc_pat()) { @@ -122,7 +122,7 @@ static int __init processor_probe(struct parisc_device *dev) * boot time (ie shutdown a CPU from an OS perspective). */ /* get the cpu number */ - status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa); + status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start); BUG_ON(PDC_OK != status); @@ -130,7 +130,7 @@ static int __init processor_probe(struct parisc_device *dev) printk(KERN_WARNING "IGNORING CPU at 0x%x," " cpu_slot_id > NR_CPUS" " (%ld > %d)\n", - dev->hpa, cpu_info.cpu_num, NR_CPUS); + dev->hpa.start, cpu_info.cpu_num, NR_CPUS); /* Ignore CPU since it will only crash */ boot_cpu_data.cpu_count--; return 1; @@ -149,7 +149,7 @@ static int __init processor_probe(struct parisc_device *dev) p->loops_per_jiffy = loops_per_jiffy; p->dev = dev; /* Save IODC data in case we need it */ - p->hpa = dev->hpa; /* save CPU hpa */ + p->hpa = dev->hpa.start; /* save CPU hpa */ p->cpuid = cpuid; /* save CPU id */ p->txn_addr = txn_addr; /* save CPU IRQ address */ #ifdef CONFIG_SMP diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 8aa81c9ac2f7..e7a1e14f8b0c 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -278,11 +278,11 @@ static int __init hil_init_chip(struct parisc_device *dev) { if (!dev->irq) { - printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa); + printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start); return -ENODEV; } - hil_base = dev->hpa; + hil_base = dev->hpa.start; hil_irq = dev->irq; hil_dev.dev_id = dev; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 4bad2810190c..9790d7169a53 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -331,7 +331,7 @@ static int __init gscps2_probe(struct parisc_device *dev) { struct gscps2port *ps2port; struct serio *serio; - unsigned long hpa = dev->hpa; + unsigned long hpa = dev->hpa.start; int ret; if (!dev->irq) diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 045b9a7a9dbb..a10348bb25e9 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -875,9 +875,9 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) hp_sdc.dev = d; hp_sdc.irq = d->irq; hp_sdc.nmi = d->aux_irq; - hp_sdc.base_io = d->hpa; - hp_sdc.data_io = d->hpa + 0x800; - hp_sdc.status_io = d->hpa + 0x801; + hp_sdc.base_io = d->hpa.start; + hp_sdc.data_io = d->hpa.start + 0x800; + hp_sdc.status_io = d->hpa.start + 0x801; return hp_sdc_init(); } diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 180e526a2049..a63d8a317d9e 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -1528,17 +1528,18 @@ lan_init_chip(struct parisc_device *dev) if (!dev->irq) { printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", - __FILE__, dev->hpa); + __FILE__, dev->hpa.start); return -ENODEV; } - printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa, dev->irq); + printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start, + dev->irq); netdevice = alloc_etherdev(0); if (!netdevice) return -ENOMEM; - netdevice->base_addr = dev->hpa; + netdevice->base_addr = dev->hpa.start; netdevice->irq = dev->irq; retval = i82596_probe(netdevice, &dev->dev); diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c index 52f37b424318..558420bc9f88 100644 --- a/drivers/parisc/asp.c +++ b/drivers/parisc/asp.c @@ -77,12 +77,12 @@ asp_init_chip(struct parisc_device *dev) struct gsc_irq gsc_irq; int ret; - asp.version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf; + asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf; asp.name = (asp.version == 1) ? "Asp" : "Cutoff"; asp.hpa = ASP_INTERRUPT_ADDR; printk(KERN_INFO "%s version %d at 0x%lx found.\n", - asp.name, asp.version, dev->hpa); + asp.name, asp.version, dev->hpa.start); /* the IRQ ASP should use */ ret = -EBUSY; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 2bb1889c4c4f..80d0927dc8a4 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1546,7 +1546,7 @@ static int ccio_probe(struct parisc_device *dev) ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; - printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa); + printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start); for (i = 0; i < ioc_count; i++) { ioc_p = &(*ioc_p)->next; @@ -1554,7 +1554,7 @@ static int ccio_probe(struct parisc_device *dev) *ioc_p = ioc; ioc->hw_path = dev->hw_path; - ioc->ioc_hpa = (struct ioa_registers *)dev->hpa; + ioc->ioc_regs = ioremap(dev->hpa.start, 4096); ccio_ioc_init(ioc); ccio_init_resources(ioc); hppa_dma_ops = &ccio_ops; diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c index 57e6385976e2..356b8357bccc 100644 --- a/drivers/parisc/ccio-rm-dma.c +++ b/drivers/parisc/ccio-rm-dma.c @@ -167,7 +167,7 @@ ccio_probe(struct parisc_device *dev) { printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME, dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn", - dev->hpa); + dev->hpa.start); /* ** FIXME - should check U2 registers to verify it's really running diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 8c61705e67a5..37820b0ae5ee 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -902,15 +902,15 @@ void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); ** If so, initialize the chip appropriately (card-mode vs bridge mode). ** Much of the initialization is common though. */ -static int __init -dino_driver_callback(struct parisc_device *dev) +static int __init dino_probe(struct parisc_device *dev) { struct dino_device *dino_dev; // Dino specific control struct const char *version = "unknown"; char *name; int is_cujo = 0; struct pci_bus *bus; - + unsigned long hpa = dev->hpa.start; + name = "Dino"; if (is_card_dino(&dev->id)) { version = "3.x (card mode)"; diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 0afeedddf535..6362bf99eff6 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -315,7 +315,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) char *name = is_mongoose(dev) ? "Mongoose" : "Wax"; printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", - name, dev->hpa); + name, dev->hpa.start); eisa_dev.hba.dev = dev; eisa_dev.hba.iommu = ccio_get_iommu(dev); diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index a6eae3e7c0cd..5edf93f80757 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -68,14 +68,14 @@ static int hppb_probe(struct parisc_device *dev) memset(card->next, '\0', sizeof(struct hppb_card)); card = card->next; } - printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa); + printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); - card->hpa = dev->hpa; + card->hpa = dev->hpa.start; card->mmio_region.name = "HP-PB Bus"; card->mmio_region.flags = IORESOURCE_MEM; - card->mmio_region.start = __raw_readl(dev->hpa + IO_IO_LOW); - card->mmio_region.end = __raw_readl(dev->hpa + IO_IO_HIGH) - 1; + card->mmio_region.start = gsc_readl(dev->hpa.start + IO_IO_LOW); + card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1; status = ccio_request_resource(dev, &card->mmio_region); if(status < 0) { diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index c776c372ae4e..a8c20396ffbe 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -175,7 +175,7 @@ lasi_init_chip(struct parisc_device *dev) return -ENOMEM; lasi->name = "Lasi"; - lasi->hpa = dev->hpa; + lasi->hpa = dev->hpa.start; /* Check the 4-bit (yes, only 4) version register */ lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 7fdd80b7eb47..5e495dcbc58a 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1288,7 +1288,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) ** Adjust "window" for this rope. */ rsize /= ROPES_PER_IOC; - r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa); + r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start); r->end = r->start + rsize; } else { r->end = r->start = 0; /* Not enabled. */ @@ -1458,7 +1458,7 @@ lba_driver_probe(struct parisc_device *dev) u32 func_class; void *tmp_obj; char *version; - void __iomem *addr = ioremap(dev->hpa, 4096); + void __iomem *addr = ioremap(dev->hpa.start, 4096); /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1476,7 +1476,7 @@ lba_driver_probe(struct parisc_device *dev) } printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", - MODULE_NAME, version, func_class & 0xf, dev->hpa); + MODULE_NAME, version, func_class & 0xf, dev->hpa.start); if (func_class < 2) { printk(KERN_WARNING "Can't support LBA older than " @@ -1503,17 +1503,17 @@ lba_driver_probe(struct parisc_device *dev) * but for the mask for func_class. */ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", - MODULE_NAME, version, func_class & 0xff, dev->hpa); + MODULE_NAME, version, func_class & 0xff, dev->hpa.start); cfg_ops = &mercury_cfg_ops; } else { - printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa); + printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start); return -ENODEV; } /* ** Tell I/O SAPIC driver we have a IRQ handler/region. */ - tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE); + tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE); /* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't ** have an IRT entry will get NULL back from iosapic code. @@ -1635,7 +1635,7 @@ void __init lba_init(void) */ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) { - void __iomem * base_addr = ioremap(lba->hpa, 4096); + void __iomem * base_addr = ioremap(lba->hpa.start, 4096); imask <<= 2; /* adjust for hints - 2 more bits */ diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index a8405f05fb5f..6256ad365d0b 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -1600,7 +1600,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset) { - return ioremap(sba_dev->dev->hpa + offset, SBA_FUNC_SIZE); + return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); } static void sba_hw_init(struct sba_device *sba_dev) @@ -1978,7 +1978,7 @@ sba_driver_callback(struct parisc_device *dev) u32 func_class; int i; char *version; - void __iomem *sba_addr = ioremap(dev->hpa, SBA_FUNC_SIZE); + void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); sba_dump_ranges(sba_addr); @@ -2020,7 +2020,7 @@ sba_driver_callback(struct parisc_device *dev) } printk(KERN_INFO "%s found %s at 0x%lx\n", - MODULE_NAME, version, dev->hpa); + MODULE_NAME, version, dev->hpa.start); sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); if (!sba_dev) { diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index e547d7d024d8..17dce2adf7fe 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c @@ -81,7 +81,7 @@ wax_init_chip(struct parisc_device *dev) return -ENOMEM; wax->name = "wax"; - wax->hpa = dev->hpa; + wax->hpa = dev->hpa.start; wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */ printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa); diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 02d72acd1c89..fde29a75f888 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -359,11 +359,12 @@ static int __devinit parport_init_chip(struct parisc_device *dev) unsigned long port; if (!dev->irq) { - printk("IRQ not found for parallel device at 0x%lx\n", dev->hpa); + printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n", + dev->hpa.start); return -ENODEV; } - port = dev->hpa + PARPORT_GSC_OFFSET; + port = dev->hpa.start + PARPORT_GSC_OFFSET; /* some older machines with ASP-chip don't support * the enhanced parport modes. diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 123f4933d8f5..8028418b3ad6 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(parisc, lasi700_ids); static int __init lasi700_probe(struct parisc_device *dev) { - unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET; + unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET; struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index 5a51051e31f0..b131432c677d 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c @@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev) struct gsc_irq gsc_irq; u32 zalon_vers; int error = -ENODEV; - void __iomem *zalon = ioremap(dev->hpa, 4096); + void __iomem *zalon = ioremap(dev->hpa.start, 4096); void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; struct Scsi_Host *host; @@ -127,7 +127,7 @@ zalon_probe(struct parisc_device *dev) device.chip = zalon720_chip; device.host_id = 7; device.dev = &dev->dev; - device.slot.base = dev->hpa + GSC_SCSI_ZALON_OFFSET; + device.slot.base = dev->hpa.start + GSC_SCSI_ZALON_OFFSET; device.slot.base_v = io_port; device.slot.irq = dev->irq; device.differential = 2; diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 431aa5761a7a..abc5a0cfe243 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -42,12 +42,13 @@ serial_init_chip(struct parisc_device *dev) */ if (parisc_parent(dev)->id.hw_type != HPHW_IOA) { printk(KERN_INFO "Serial: device 0x%lx not configured.\n" - "Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa); + "Enable support for Wax, Lasi, Asp or Dino.\n", + dev->hpa.start); } return -ENODEV; } - address = dev->hpa; + address = dev->hpa.start; if (dev->id.sversion != 0x8d) { address += 0x800; } diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index a12005b08bca..009ce83c8ef5 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -444,7 +444,7 @@ static int __init mux_probe(struct parisc_device *dev) unsigned long bytecnt; struct uart_port *port; - status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32); + status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); if(status != PDC_OK) { printk(KERN_ERR "Serial mux: Unable to read IODC.\n"); return 1; diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h index cbde8b41c84b..1d247e32a608 100644 --- a/include/asm-parisc/parisc-device.h +++ b/include/asm-parisc/parisc-device.h @@ -1,7 +1,7 @@ #include struct parisc_device { - unsigned long hpa; /* Hard Physical Address */ + struct resource hpa; /* Hard Physical Address */ struct parisc_device_id id; struct parisc_driver *driver; /* Driver for this device */ char name[80]; /* The hardware description */ diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index f560dd8cdb90..8b3ea26469ad 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -852,14 +852,14 @@ snd_harmony_create(snd_card_t *card, memset(&h->pbuf, 0, sizeof(h->pbuf)); memset(&h->cbuf, 0, sizeof(h->cbuf)); - h->hpa = padev->hpa; + h->hpa = padev->hpa.start; h->card = card; h->dev = padev; h->irq = padev->irq; - h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE); + h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE); if (h->iobase == NULL) { printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n", - padev->hpa); + padev->hpa.start); err = -EBUSY; goto free_and_ret; } From 64908ad95c34f25849412d6d4735ac10f8fb6575 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:37:20 -0400 Subject: [PATCH 0374/1940] [PARISC] Update sba_iommu from parisc tree revert use of %%sr0 in fdc asm. Thanks to Joel Soete for pointing out this oversight. Signed-off-by: Grant Grundler 2.6.14-rc2-pa3 move "sync" outside the main loop that fills IO Pdir. Signed-off-by: Grant Grundler remove explicit use of sr0 in fdc ops. Thanks to Joel Soete for reminding me were I added those... Signed-off-by: Grant Grundler 2.6.14-rc2-pa2 - make SBA more anal about invalidating pdir entries Previous code cleared the valid flag a pdir entry but it did NOT guarantee this change was visible to the PDIR before writing the PCOM register. Ie the SBA could pick up a stale entry if the write happened to hit the SBA before the cacheline was flushed from the cache. Long term, I think I want to make this a compile time flag. Developement tree should enable anal pdir checking by default and Debian can disable it with either a CONFIG option or one-line patch. fdc/sync options can only negatively affect performance though I haven't measure how much yet. If someone can run netperf TCP_RR across gige and compare -pa1 and -pa2, that would be sufficient. Cleaned up the use of "fdc" to make sure it's using "kernel" space id (specify sr0 but maps to sr4-7). It seems a bit fragile to assume "sr1" gets loaded with KERNEL_SPACE which is how the code works today. Tested on 32 and 64-bit SMP kernels on j6k. Signed-off-by: Grant Grundler remove PDC_NARROW from SBA and document history of PDC_NARROW a bit. It will still show up in an older kernel's .config file. Signed-off-by: Grant Grundler if/ifdef cleanups from Joel Soete. Signed-off-by: Grant Grundler 2.6.12-rc4-pa2 fix 32-bit support for Astro platforms o Since my last SBA code change, SBA could allocate more than 1GB of IOVA space on Astro boxes with more than 1GB of RAM when running 32-bit kernel. This is bad since IOMMU can only talk to the first 1GB at most. Kudos to jejb for quickly spotting that bug. o jejb also noted SBA should *always* reject DMA masks > 32-bits since DMA-mapping.txt indicates caller should try again with 32-bits. o off-by-one error when comparing the mask to IOVA space size. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- drivers/parisc/sba_iommu.c | 140 ++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 49 deletions(-) diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 6256ad365d0b..48591badd4ce 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -91,8 +91,8 @@ extern struct proc_dir_entry * proc_mckinley_root; #define DBG_RES(x...) #endif -#if defined(__LP64__) && !defined(CONFIG_PDC_NARROW) -/* "low end" PA8800 machines use ZX1 chipset */ +#if defined(CONFIG_64BIT) +/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */ #define ZX1_SUPPORT #endif @@ -231,7 +231,7 @@ struct ioc { spinlock_t res_lock; unsigned int res_bitshift; /* from the LEFT! */ unsigned int res_size; /* size of resource map in bytes */ -#if SBA_HINT_SUPPORT +#ifdef SBA_HINT_SUPPORT /* FIXME : DMA HINTs not used */ unsigned long hint_mask_pdir; /* bits used for DMA hints */ unsigned int hint_shift_pdir; @@ -294,7 +294,7 @@ static unsigned long piranha_bad_128k = 0; /* Looks nice and keeps the compiler happy */ #define SBA_DEV(d) ((struct sba_device *) (d)) -#if SBA_AGP_SUPPORT +#ifdef SBA_AGP_SUPPORT static int reserve_sba_gart = 1; #endif @@ -314,7 +314,7 @@ static int reserve_sba_gart = 1; #define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) #define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) -#ifdef __LP64__ +#ifdef CONFIG_64BIT #define READ_REG(addr) READ_REG64(addr) #define WRITE_REG(value, addr) WRITE_REG64(value, addr) #else @@ -324,7 +324,7 @@ static int reserve_sba_gart = 1; #ifdef DEBUG_SBA_INIT -/* NOTE: When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */ +/* NOTE: When CONFIG_64BIT isn't defined, READ_REG64() is two 32-bit reads */ /** * sba_dump_ranges - debugging only - print ranges assigned to this IOA @@ -364,7 +364,7 @@ static void sba_dump_tlb(void __iomem *hpa) #else #define sba_dump_ranges(x) #define sba_dump_tlb(x) -#endif +#endif /* DEBUG_SBA_INIT */ #ifdef ASSERT_PDIR_SANITY @@ -674,7 +674,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size) * ***************************************************************/ -#if SBA_HINT_SUPPORT +#ifdef SBA_HINT_SUPPORT #define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir) #endif @@ -743,9 +743,8 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, * (bit #61, big endian), we have to flush and sync every time * IO-PDIR is changed in Ike/Astro. */ - if (ioc_needs_fdc) { - asm volatile("fdc 0(%%sr1,%0)\n\tsync" : : "r" (pdir_ptr)); - } + if (ioc_needs_fdc) + asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); } @@ -769,42 +768,57 @@ static SBA_INLINE void sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) { u32 iovp = (u32) SBA_IOVP(ioc,iova); - - /* Even though this is a big-endian machine, the entries - ** in the iopdir are little endian. That's why we clear the byte - ** at +7 instead of at +0. - */ - int off = PDIR_INDEX(iovp)*sizeof(u64)+7; + u64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)]; #ifdef ASSERT_PDIR_SANITY - /* Assert first pdir entry is set */ - if (0x80 != (((u8 *) ioc->pdir_base)[off])) { + /* Assert first pdir entry is set. + ** + ** Even though this is a big-endian machine, the entries + ** in the iopdir are little endian. That's why we look at + ** the byte at +7 instead of at +0. + */ + if (0x80 != (((u8 *) pdir_ptr)[7])) { sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp)); } #endif - if (byte_cnt <= IOVP_SIZE) + if (byte_cnt > IOVP_SIZE) { - iovp |= IOVP_SHIFT; /* set "size" field for PCOM */ +#if 0 + unsigned long entries_per_cacheline = ioc_needs_fdc ? + L1_CACHE_ALIGN(((unsigned long) pdir_ptr)) + - (unsigned long) pdir_ptr; + : 262144; +#endif - /* - ** clear I/O PDIR entry "valid" bit - ** Do NOT clear the rest - save it for debugging. - ** We should only clear bits that have previously - ** been enabled. - */ - ((u8 *)(ioc->pdir_base))[off] = 0; - } else { - u32 t = get_order(byte_cnt) + PAGE_SHIFT; + /* set "size" field for PCOM */ + iovp |= get_order(byte_cnt) + PAGE_SHIFT; - iovp |= t; do { /* clear I/O Pdir entry "valid" bit first */ - ((u8 *)(ioc->pdir_base))[off] = 0; - off += sizeof(u64); + ((u8 *) pdir_ptr)[7] = 0; + if (ioc_needs_fdc) { + asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); +#if 0 + entries_per_cacheline = L1_CACHE_SHIFT - 3; +#endif + } + pdir_ptr++; byte_cnt -= IOVP_SIZE; - } while (byte_cnt > 0); - } + } while (byte_cnt > IOVP_SIZE); + } else + iovp |= IOVP_SHIFT; /* set "size" field for PCOM */ + + /* + ** clear I/O PDIR entry "valid" bit. + ** We have to R/M/W the cacheline regardless how much of the + ** pdir entry that we clobber. + ** The rest of the entry would be useful for debugging if we + ** could dump core on HPMC. + */ + ((u8 *) pdir_ptr)[7] = 0; + if (ioc_needs_fdc) + asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM); } @@ -819,18 +833,29 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) static int sba_dma_supported( struct device *dev, u64 mask) { struct ioc *ioc; + if (dev == NULL) { printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n"); BUG(); return(0); } + /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first, + * then fall back to 32-bit if that fails. + * We are just "encouraging" 32-bit DMA masks here since we can + * never allow IOMMU bypass unless we add special support for ZX1. + */ + if (mask > ~0U) + return 0; + ioc = GET_IOC(dev); - /* check if mask is > than the largest IO Virt Address */ - - return((int) (mask >= (ioc->ibase + - (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) ))); + /* + * check if mask is >= than the current max IO Virt Address + * The max IO Virt address will *always* < 30 bits. + */ + return((int)(mask >= (ioc->ibase - 1 + + (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) ))); } @@ -898,11 +923,17 @@ sba_map_single(struct device *dev, void *addr, size_t size, size -= IOVP_SIZE; pdir_start++; } - /* form complete address */ + + /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ + if (ioc_needs_fdc) + asm volatile("sync" : : ); + #ifdef ASSERT_PDIR_SANITY sba_check_pdir(ioc,"Check after sba_map_single()"); #endif spin_unlock_irqrestore(&ioc->res_lock, flags); + + /* form complete address */ return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG); } @@ -958,12 +989,19 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, d--; } ioc->saved_cnt = 0; + READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ } #else /* DELAYED_RESOURCE_CNT == 0 */ sba_free_range(ioc, iova, size); + + /* If fdc's were issued, force fdc's to be visible now */ + if (ioc_needs_fdc) + asm volatile("sync" : : ); + READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ #endif /* DELAYED_RESOURCE_CNT == 0 */ + spin_unlock_irqrestore(&ioc->res_lock, flags); /* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support. @@ -1106,6 +1144,10 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, */ filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry); + /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ + if (ioc_needs_fdc) + asm volatile("sync" : : ); + #ifdef ASSERT_PDIR_SANITY if (sba_check_pdir(ioc,"Check after sba_map_sg()")) { @@ -1234,8 +1276,10 @@ sba_alloc_pdir(unsigned int pdir_size) unsigned long pdir_order = get_order(pdir_size); pdir_base = __get_free_pages(GFP_KERNEL, pdir_order); - if (NULL == (void *) pdir_base) - panic("sba_ioc_init() could not allocate I/O Page Table\n"); + if (NULL == (void *) pdir_base) { + panic("%s() could not allocate I/O Page Table\n", + __FUNCTION__); + } /* If this is not PA8700 (PCX-W2) ** OR newer than ver 2.2 @@ -1353,7 +1397,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) u32 iova_space_mask; u32 iova_space_size; int iov_order, tcnfg; -#if SBA_AGP_SUPPORT +#ifdef SBA_AGP_SUPPORT int agp_found = 0; #endif /* @@ -1390,7 +1434,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) DBG_INIT("%s() pdir %p size %x\n", __FUNCTION__, ioc->pdir_base, ioc->pdir_size); -#if SBA_HINT_SUPPORT +#ifdef SBA_HINT_SUPPORT ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT)); @@ -1414,7 +1458,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK); -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* ** Setting the upper bits makes checking for bypass addresses ** a little faster later on. @@ -1447,7 +1491,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) */ WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); -#if SBA_AGP_SUPPORT +#ifdef SBA_AGP_SUPPORT /* ** If an AGP device is present, only use half of the IOV space ** for PCI DMA. Unfortunately we can't know ahead of time @@ -1499,11 +1543,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) if (iova_space_size < (1 << (20 - PAGE_SHIFT))) { iova_space_size = 1 << (20 - PAGE_SHIFT); } -#ifdef __LP64__ else if (iova_space_size > (1 << (30 - PAGE_SHIFT))) { iova_space_size = 1 << (30 - PAGE_SHIFT); } -#endif /* ** iova space must be log2() in size. @@ -1529,7 +1571,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) DBG_INIT("%s() pdir %p size %x\n", __FUNCTION__, ioc->pdir_base, pdir_size); -#if SBA_HINT_SUPPORT +#ifdef SBA_HINT_SUPPORT /* FIXME : DMA HINTs not used */ ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT)); From 86a61ee9c9f3d8b632d29e86ac6610c43ebbb4f0 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:37:43 -0400 Subject: [PATCH 0375/1940] [PARISC] Update ccio-dma from parisc tree revert use of %%sr0 in fdc asm. Thanks to Joel Soete for pointing out this oversight. Signed-off-by: Grant Grundler 2.6.14-rc2-pa3 fdc/lci should be %r0 instead 0 for index (PA 1.1 compliance) From: Joel Soete Signed-off-by: Grant Grundler Explain why we need insert_resource() instead of request_resource(). Fundementally, this is more convoluted for ccio driver because of o legacy (HP-PB) transperant bridges. o support for MMIO behind card-mode Dino (PCI) o support for above bridges without ccio in the box SBA driver doesn't have to worry about those issues. Signed-off-by: Grant Grundler Use insert_resource instead of request_resource now that the subdevices will already have their resources claimed Signed-off-by: Matthew Wilcox re-enable use of "inline" for perf critical functions. Signed-off-by: Grant Grundler 2.6.12-rc4-pa5 fix sign extension of MMIO range Fixes the problem of claiming a range that is disabled on 64-bit kernel: ccio_init_resource() claimed CCIO bus address space (ffffffff00000000, ffffffffffffffff) also removes use of __FILE__. Tested on both 32 and 64-bit systems by Joel. From: Joel Soete Signed-off-by: Grant Grundler 2.6.12-rc1-pa7 incorrect BUG_ON in ccio ccio-dma.c line 1317 was preventing K-class with 4GB RAM from booting. Any ccio machine with >=2GB of RAM would have (incorrectly) triggered this. Signed-off-by: Grant Grundler Convert to ioremap and __raw_read/write Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/parisc/ccio-dma.c | 136 ++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 58 deletions(-) diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 80d0927dc8a4..f1c442ab9102 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -100,9 +100,9 @@ #define DBG_RUN_SG(x...) #endif -#define CCIO_INLINE /* inline */ -#define WRITE_U32(value, addr) gsc_writel(value, (u32 *)(addr)) -#define READ_U32(addr) gsc_readl((u32 *)(addr)) +#define CCIO_INLINE inline +#define WRITE_U32(value, addr) __raw_writel(value, addr) +#define READ_U32(addr) __raw_readl(addr) #define U2_IOA_RUNWAY 0x580 #define U2_BC_GSC 0x501 @@ -115,28 +115,28 @@ struct ioa_registers { /* Runway Supervisory Set */ - volatile int32_t unused1[12]; - volatile uint32_t io_command; /* Offset 12 */ - volatile uint32_t io_status; /* Offset 13 */ - volatile uint32_t io_control; /* Offset 14 */ - volatile int32_t unused2[1]; + int32_t unused1[12]; + uint32_t io_command; /* Offset 12 */ + uint32_t io_status; /* Offset 13 */ + uint32_t io_control; /* Offset 14 */ + int32_t unused2[1]; /* Runway Auxiliary Register Set */ - volatile uint32_t io_err_resp; /* Offset 0 */ - volatile uint32_t io_err_info; /* Offset 1 */ - volatile uint32_t io_err_req; /* Offset 2 */ - volatile uint32_t io_err_resp_hi; /* Offset 3 */ - volatile uint32_t io_tlb_entry_m; /* Offset 4 */ - volatile uint32_t io_tlb_entry_l; /* Offset 5 */ - volatile uint32_t unused3[1]; - volatile uint32_t io_pdir_base; /* Offset 7 */ - volatile uint32_t io_io_low_hv; /* Offset 8 */ - volatile uint32_t io_io_high_hv; /* Offset 9 */ - volatile uint32_t unused4[1]; - volatile uint32_t io_chain_id_mask; /* Offset 11 */ - volatile uint32_t unused5[2]; - volatile uint32_t io_io_low; /* Offset 14 */ - volatile uint32_t io_io_high; /* Offset 15 */ + uint32_t io_err_resp; /* Offset 0 */ + uint32_t io_err_info; /* Offset 1 */ + uint32_t io_err_req; /* Offset 2 */ + uint32_t io_err_resp_hi; /* Offset 3 */ + uint32_t io_tlb_entry_m; /* Offset 4 */ + uint32_t io_tlb_entry_l; /* Offset 5 */ + uint32_t unused3[1]; + uint32_t io_pdir_base; /* Offset 7 */ + uint32_t io_io_low_hv; /* Offset 8 */ + uint32_t io_io_high_hv; /* Offset 9 */ + uint32_t unused4[1]; + uint32_t io_chain_id_mask; /* Offset 11 */ + uint32_t unused5[2]; + uint32_t io_io_low; /* Offset 14 */ + uint32_t io_io_high; /* Offset 15 */ }; /* @@ -226,7 +226,7 @@ struct ioa_registers { */ struct ioc { - struct ioa_registers *ioc_hpa; /* I/O MMU base address */ + struct ioa_registers __iomem *ioc_regs; /* I/O MMU base address */ u8 *res_map; /* resource map, bit == pdir entry */ u64 *pdir_base; /* physical base address */ u32 pdir_size; /* bytes, function of IOV Space size */ @@ -595,7 +595,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, ** Grab virtual index [0:11] ** Deposit virt_idx bits into I/O PDIR word */ - asm volatile ("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); + asm volatile ("lci %%r0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci)); asm volatile ("depw %1,15,12,%0" : "+r" (pa) : "r" (ci)); @@ -613,7 +613,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, ** the real mode coherence index generation of U2, the PDIR entry ** must be flushed to memory to retain coherence." */ - asm volatile("fdc 0(%0)" : : "r" (pdir_ptr)); + asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); asm volatile("sync"); } @@ -636,7 +636,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt) byte_cnt += chain_size; while(byte_cnt > chain_size) { - WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_hpa->io_command); + WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_regs->io_command); iovp += chain_size; byte_cnt -= chain_size; } @@ -684,7 +684,7 @@ ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) ** Hopefully someone figures out how to patch (NOP) the ** FDC/SYNC out at boot time. */ - asm volatile("fdc 0(%0)" : : "r" (pdir_ptr[7])); + asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7])); iovp += IOVP_SIZE; byte_cnt -= IOVP_SIZE; @@ -1314,14 +1314,13 @@ ccio_ioc_init(struct ioc *ioc) ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); - BUG_ON(ioc->pdir_size >= 4 * 1024 * 1024); /* max pdir size < 4MB */ + BUG_ON(ioc->pdir_size > 8 * 1024 * 1024); /* max pdir size <= 8MB */ /* Verify it's a power of two */ BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT)); - DBG_INIT("%s() hpa 0x%lx mem %luMB IOV %dMB (%d bits)\n", - __FUNCTION__, - ioc->ioc_hpa, + DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n", + __FUNCTION__, ioc->ioc_regs, (unsigned long) num_physpages >> (20 - PAGE_SHIFT), iova_space_size>>20, iov_order + PAGE_SHIFT); @@ -1329,13 +1328,12 @@ ccio_ioc_init(struct ioc *ioc) ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, get_order(ioc->pdir_size)); if(NULL == ioc->pdir_base) { - panic("%s:%s() could not allocate I/O Page Table\n", __FILE__, - __FUNCTION__); + panic("%s() could not allocate I/O Page Table\n", __FUNCTION__); } memset(ioc->pdir_base, 0, ioc->pdir_size); BUG_ON((((unsigned long)ioc->pdir_base) & PAGE_MASK) != (unsigned long)ioc->pdir_base); - DBG_INIT(" base %p", ioc->pdir_base); + DBG_INIT(" base %p\n", ioc->pdir_base); /* resource map size dictated by pdir_size */ ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3; @@ -1344,8 +1342,7 @@ ccio_ioc_init(struct ioc *ioc) ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, get_order(ioc->res_size)); if(NULL == ioc->res_map) { - panic("%s:%s() could not allocate resource map\n", __FILE__, - __FUNCTION__); + panic("%s() could not allocate resource map\n", __FUNCTION__); } memset(ioc->res_map, 0, ioc->res_size); @@ -1366,44 +1363,58 @@ ccio_ioc_init(struct ioc *ioc) ** Initialize IOA hardware */ WRITE_U32(CCIO_CHAINID_MASK << ioc->chainid_shift, - &ioc->ioc_hpa->io_chain_id_mask); + &ioc->ioc_regs->io_chain_id_mask); WRITE_U32(virt_to_phys(ioc->pdir_base), - &ioc->ioc_hpa->io_pdir_base); + &ioc->ioc_regs->io_pdir_base); /* ** Go to "Virtual Mode" */ - WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_hpa->io_control); + WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_regs->io_control); /* ** Initialize all I/O TLB entries to 0 (Valid bit off). */ - WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_m); - WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_l); + WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_m); + WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_l); for(i = 1 << CCIO_CHAINID_SHIFT; i ; i--) { WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)), - &ioc->ioc_hpa->io_command); + &ioc->ioc_regs->io_command); } } static void -ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr) +ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr) { int result; res->parent = NULL; res->flags = IORESOURCE_MEM; - res->start = (unsigned long)(signed) __raw_readl(ioaddr) << 16; - res->end = (unsigned long)(signed) (__raw_readl(ioaddr + 4) << 16) - 1; + /* + * bracing ((signed) ...) are required for 64bit kernel because + * we only want to sign extend the lower 16 bits of the register. + * The upper 16-bits of range registers are hardcoded to 0xffff. + */ + res->start = (unsigned long)((signed) READ_U32(ioaddr) << 16); + res->end = (unsigned long)((signed) (READ_U32(ioaddr + 4) << 16) - 1); res->name = name; + /* + * Check if this MMIO range is disable + */ if (res->end + 1 == res->start) return; - result = request_resource(&iomem_resource, res); + + /* On some platforms (e.g. K-Class), we have already registered + * resources for devices reported by firmware. Some are children + * of ccio. + * "insert" ccio ranges in the mmio hierarchy (/proc/iomem). + */ + result = insert_resource(&iomem_resource, res); if (result < 0) { - printk(KERN_ERR "%s: failed to claim CCIO bus address space (%08lx,%08lx)\n", - __FILE__, res->start, res->end); + printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", + __FUNCTION__, res->start, res->end); } } @@ -1414,9 +1425,8 @@ static void __init ccio_init_resources(struct ioc *ioc) sprintf(name, "GSC Bus [%d/]", ioc->hw_path); - ccio_init_resource(res, name, (unsigned long)&ioc->ioc_hpa->io_io_low); - ccio_init_resource(res + 1, name, - (unsigned long)&ioc->ioc_hpa->io_io_low_hv); + ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); + ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); } static int new_ioc_area(struct resource *res, unsigned long size, @@ -1427,7 +1437,12 @@ static int new_ioc_area(struct resource *res, unsigned long size, res->start = (max - size + 1) &~ (align - 1); res->end = res->start + size; - if (!request_resource(&iomem_resource, res)) + + /* We might be trying to expand the MMIO range to include + * a child device that has already registered it's MMIO space. + * Use "insert" instead of request_resource(). + */ + if (!insert_resource(&iomem_resource, res)) return 0; return new_ioc_area(res, size, min, max - size, align); @@ -1486,15 +1501,15 @@ int ccio_allocate_resource(const struct parisc_device *dev, if (!expand_ioc_area(parent, size, min, max, align)) { __raw_writel(((parent->start)>>16) | 0xffff0000, - (unsigned long)&(ioc->ioc_hpa->io_io_low)); + &ioc->ioc_regs->io_io_low); __raw_writel(((parent->end)>>16) | 0xffff0000, - (unsigned long)&(ioc->ioc_hpa->io_io_high)); + &ioc->ioc_regs->io_io_high); } else if (!expand_ioc_area(parent + 1, size, min, max, align)) { parent++; __raw_writel(((parent->start)>>16) | 0xffff0000, - (unsigned long)&(ioc->ioc_hpa->io_io_low_hv)); + &ioc->ioc_regs->io_io_low_hv); __raw_writel(((parent->end)>>16) | 0xffff0000, - (unsigned long)&(ioc->ioc_hpa->io_io_high_hv)); + &ioc->ioc_regs->io_io_high_hv); } else { return -EBUSY; } @@ -1521,7 +1536,12 @@ int ccio_request_resource(const struct parisc_device *dev, return -EBUSY; } - return request_resource(parent, res); + /* "transparent" bus bridges need to register MMIO resources + * firmware assigned them. e.g. children of hppb.c (e.g. K-class) + * registered their resources in the PDC "bus walk" (See + * arch/parisc/kernel/inventory.c). + */ + return insert_resource(parent, res); } /** From 92b919fe46509820c639a08962cbf78bc8d227d9 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:38:23 -0400 Subject: [PATCH 0376/1940] [PARISC] Update dino from parisc tree Fix card-mode Dino crashes on 725 (and probably other Snake) systems. Dino was coming up in fatal mode after a warm reboot. Resetting Dino brings it out of fatal mode, so do that if the status register indicates we're in fatal mode. Since this was never observed on any later systems, I presume firmware does this for us on those. Signed-off-by: Matthew Wilcox Add debug statements in the cfg_read and cfg_write functions Fix debug statements from the IRQ overhaul last winter Rename dino_driver_callback() to dino_probe() Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/parisc/dino.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 37820b0ae5ee..5ab75334c579 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -178,6 +178,8 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, void __iomem *base_addr = d->hba.base_addr; unsigned long flags; + DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where, + size); spin_lock_irqsave(&d->dinosaur_pen, flags); /* tell HW which CFG address */ @@ -211,6 +213,8 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, void __iomem *base_addr = d->hba.base_addr; unsigned long flags; + DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where, + size); spin_lock_irqsave(&d->dinosaur_pen, flags); /* avoid address stepping feature */ @@ -295,7 +299,7 @@ static void dino_disable_irq(unsigned int irq) struct dino_device *dino_dev = irq_desc[irq].handler_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq); + DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); /* Clear the matching bit in the IMR register */ dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); @@ -308,7 +312,7 @@ static void dino_enable_irq(unsigned int irq) int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); u32 tmp; - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq); + DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); /* ** clear pending IRQ bits @@ -490,7 +494,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB))) break; } - DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n", + DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n", i, res->start, base_addr + DINO_IO_ADDR_EN); __raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN); } @@ -683,6 +687,14 @@ static void __init dino_card_init(struct dino_device *dino_dev) { u32 brdg_feat = 0x00784e05; + unsigned long status; + + status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS); + if (status & 0x0000ff80) { + __raw_writel(0x00000005, + dino_dev->hba.base_addr+DINO_IO_COMMAND); + udelay(1); + } __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK); __raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN); @@ -928,11 +940,11 @@ static int __init dino_probe(struct parisc_device *dev) } } - printk("%s version %s found at 0x%lx\n", name, version, dev->hpa); + printk("%s version %s found at 0x%lx\n", name, version, hpa); - if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) { + if (!request_mem_region(hpa, PAGE_SIZE, name)) { printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n", - dev->hpa); + hpa); return 1; } @@ -940,12 +952,12 @@ static int __init dino_probe(struct parisc_device *dev) if (is_cujo && dev->id.hversion_rev == 1) { #ifdef CONFIG_IOMMU_CCIO printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n"); - if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) { + if (hpa == (unsigned long)CUJO_RAVEN_ADDR) { ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE); - } else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) { + } else if (hpa == (unsigned long)CUJO_FIREHAWK_ADDR) { ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE); } else { - printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa); + printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", hpa); } #endif } else if (!is_cujo && !is_card_dino(&dev->id) && @@ -970,7 +982,7 @@ static int __init dino_probe(struct parisc_device *dev) memset(dino_dev, 0, sizeof(struct dino_device)); dino_dev->hba.dev = dev; - dino_dev->hba.base_addr = ioremap(dev->hpa, 4096); /* faster access */ + dino_dev->hba.base_addr = ioremap(hpa, 4096); dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ spin_lock_init(&dino_dev->dinosaur_pen); dino_dev->hba.iommu = ccio_get_iommu(dev); From b2c1fe81df7471de9f7e2918877ac04ec9cde35f Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:39:43 -0400 Subject: [PATCH 0377/1940] [PARISC] Allow STI_CONSOLE access to some FONTS add || STI_CONSOLE to some of the basic FONTs. May need to get at least one of them to default to "Y" for parisc. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- drivers/video/console/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index eb83a7874c71..7e731691e2a9 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -110,7 +110,7 @@ config STI_CONSOLE config FONTS bool "Select compiled-in fonts" - depends on FRAMEBUFFER_CONSOLE + depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE help Say Y here if you would like to use fonts other than the default your frame buffer console usually use. @@ -123,7 +123,7 @@ config FONTS config FONT_8x8 bool "VGA 8x8 font" if FONTS - depends on FRAMEBUFFER_CONSOLE + depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE default y if !SPARC32 && !SPARC64 && !FONTS help This is the "high resolution" font for the VGA frame buffer (the one @@ -137,7 +137,7 @@ config FONT_8x8 config FONT_8x16 bool "VGA 8x16 font" if FONTS - depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || USB_SISUSBVGA_CON + depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON default y if !SPARC32 && !SPARC64 && !FONTS help This is the "high resolution" font for the VGA frame buffer (the one @@ -147,7 +147,7 @@ config FONT_8x16 config FONT_6x11 bool "Mac console 6x11 font (not supported by all drivers)" if FONTS - depends on FRAMEBUFFER_CONSOLE + depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE default y if !SPARC32 && !SPARC64 && !FONTS && MAC help Small console font with Macintosh-style high-half glyphs. Some Mac From 896a375623c3643a3f189353e7d4828c48a7fdf8 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:40:07 -0400 Subject: [PATCH 0378/1940] [PARISC] Make sure use of RFI conforms to PA 2.0 and 1.1 arch docs 2.6.12-rc4-pa3 : first pass at making sure use of RFI conforms to PA 2.0 arch pages F-4 and F-5, PA 1.1 Arch page 3-19 and 3-20. The discussion revolves around all the rules for clearing PSW Q-bit. The hard part is meeting all the rules for "relied upon translation". .align directive is used to guarantee the critical sequence ends more than 8 instructions (32 bytes) from the end of page. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 51 +++++++------- arch/parisc/kernel/head.S | 47 +++---------- arch/parisc/kernel/pacache.S | 121 +++++++++++++++++----------------- arch/parisc/kernel/real2.S | 18 ++--- include/asm-parisc/assembly.h | 25 +++++++ include/asm-parisc/psw.h | 51 +++++++------- include/asm-parisc/tlbflush.h | 9 +-- 7 files changed, 154 insertions(+), 168 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index be0f07f2fa58..65a82c2645a7 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -30,9 +30,9 @@ * - save registers to kernel stack and handle in assembly or C */ +#include #include /* for LDREG/STREG defines */ #include -#include #include #include #include @@ -67,19 +67,22 @@ /* Switch to virtual mapping, trashing only %r1 */ .macro virt_map - rsm PSW_SM_Q,%r0 - tovirt_r1 %r29 - mfsp %sr7, %r1 - or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ - mtsp %r1, %sr3 + /* pcxt_ssm_bug */ + rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ mtsp %r0, %sr4 mtsp %r0, %sr5 + mfsp %sr7, %r1 + or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ + mtsp %r1, %sr3 + tovirt_r1 %r29 + load32 KERNEL_PSW, %r1 + + rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ mtsp %r0, %sr6 mtsp %r0, %sr7 - load32 KERNEL_PSW, %r1 - mtctl %r1, %cr22 mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ + mtctl %r1, %ipsw load32 4f, %r1 mtctl %r1, %cr18 /* Set IIAOQ tail */ ldo 4(%r1), %r1 @@ -888,9 +891,6 @@ _switch_to_ret: * this way, then we will need to copy %sr3 in to PT_SR[3..7], and * adjust IASQ[0..1]. * - * Note that the following code uses a "relied upon translation". - * See the parisc ACD for details. The ssm is necessary due to a - * PCXT bug. */ .align 4096 @@ -985,24 +985,19 @@ intr_restore: rest_fp %r1 rest_general %r29 - /* Create a "relied upon translation" PA 2.0 Arch. F-5 */ - ssm 0,%r0 - nop - nop - nop - nop - nop - nop - nop + /* inverse of virt_map */ + pcxt_ssm_bug + rsm PSW_SM_QUIET,%r0 /* prepare for rfi */ tophys_r1 %r29 - rsm (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0 /* Restore space id's and special cr's from PT_REGS - * structure pointed to by r29 */ + * structure pointed to by r29 + */ rest_specials %r29 - /* Important: Note that rest_stack restores r29 - * last (we are using it)! It also restores r1 and r30. */ + /* IMPORTANT: rest_stack restores r29 last (we are using it)! + * It also restores r1 and r30. + */ rest_stack rfi @@ -1153,15 +1148,17 @@ intr_save: CMPIB=,n 6,%r26,skip_save_ior - /* save_specials left ipsw value in r8 for us to test */ mfctl %cr20, %r16 /* isr */ + nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ mfctl %cr21, %r17 /* ior */ + #ifdef __LP64__ /* * If the interrupted code was running with W bit off (32 bit), * clear the b bits (bits 0 & 1) in the ior. + * save_specials left ipsw value in r8 for us to test. */ extrd,u,*<> %r8,PSW_W_BIT,1,%r0 depdi 0,1,2,%r17 @@ -1487,10 +1484,10 @@ nadtlb_emulate: add,l %r1,%r24,%r1 /* doesn't affect c/b bits */ nadtlb_nullify: - mfctl %cr22,%r8 /* Get ipsw */ + mfctl %ipsw,%r8 ldil L%PSW_N,%r9 or %r8,%r9,%r8 /* Set PSW_N */ - mtctl %r8,%cr22 + mtctl %r8,%ipsw rfir nop diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 28405edf8448..2b8738576ec2 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -224,8 +224,6 @@ stext_pdc_ret: mtctl %r0,%cr12 mtctl %r0,%cr13 - /* Prepare to RFI! Man all the cannons! */ - /* Initialize the global data pointer */ loadgp @@ -254,46 +252,16 @@ $is_pa20: $install_iva: mtctl %r10,%cr14 -#ifdef __LP64__ - b aligned_rfi + b aligned_rfi /* Prepare to RFI! Man all the cannons! */ nop - .align 256 + .align 128 aligned_rfi: - ssm 0,0 - nop /* 1 */ - nop /* 2 */ - nop /* 3 */ - nop /* 4 */ - nop /* 5 */ - nop /* 6 */ - nop /* 7 */ - nop /* 8 */ -#endif + pcxt_ssm_bug -#ifdef __LP64__ /* move to psw.h? */ -#define PSW_BITS PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R -#else -#define PSW_BITS PSW_SM_Q -#endif + rsm PSW_SM_QUIET,%r0 /* off troublesome PSW bits */ + /* Don't need NOPs, have 8 compliant insn before rfi */ -$rfi: - /* turn off troublesome PSW bits */ - rsm PSW_BITS,%r0 - - /* kernel PSW: - * - no interruptions except HPMC and TOC (which are handled by PDC) - * - Q bit set (IODC / PDC interruptions) - * - big-endian - * - virtually mapped - */ - load32 KERNEL_PSW,%r10 - mtctl %r10,%ipsw - - /* Set the space pointers for the post-RFI world - ** Clear the two-level IIA Space Queue, effectively setting - ** Kernel space. - */ mtctl %r0,%cr17 /* Clear IIASQ tail */ mtctl %r0,%cr17 /* Clear IIASQ head */ @@ -301,8 +269,11 @@ $rfi: mtctl %r11,%cr18 /* IIAOQ head */ ldo 4(%r11),%r11 mtctl %r11,%cr18 /* IIAOQ tail */ + + load32 KERNEL_PSW,%r10 + mtctl %r10,%ipsw - /* Jump to hyperspace */ + /* Jump through hyperspace to Virt Mode */ rfi nop diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 77e03bc0f935..71ade44c4618 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -40,8 +40,8 @@ .level 2.0 #endif -#include #include +#include #include #include @@ -62,32 +62,23 @@ flush_tlb_all_local: * to happen in real mode with all interruptions disabled. */ - /* - * Once again, we do the rfi dance ... some day we need examine - * all of our uses of this type of code and see what can be - * consolidated. - */ + /* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */ + rsm PSW_SM_I, %r19 /* save I-bit state */ + load32 PA(1f), %r1 + nop + nop + nop + nop + nop - rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */ - nop - nop - nop - nop - nop - nop - nop - - rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */ - ldil L%REAL_MODE_PSW, %r1 - ldo R%REAL_MODE_PSW(%r1), %r1 - mtctl %r1, %cr22 + rsm PSW_SM_Q, %r0 /* prep to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - ldil L%PA(1f), %r1 - ldo R%PA(1f)(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ + load32 REAL_MODE_PSW, %r1 + mtctl %r1, %ipsw rfi nop @@ -178,29 +169,36 @@ fdtonemiddle: /* Loop if LOOP = 1 */ ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */ add %r21, %r20, %r20 /* increment space */ + fdtdone: + /* + * Switch back to virtual mode + */ + /* pcxt_ssm_bug */ + rsm PSW_SM_I, %r0 + load32 2f, %r1 + nop + nop + nop + nop + nop - /* Switch back to virtual mode */ - - rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ - ldil L%KERNEL_PSW, %r1 - ldo R%KERNEL_PSW(%r1), %r1 - or %r1, %r19, %r1 /* Set I bit if set on entry */ - mtctl %r1, %cr22 + rsm PSW_SM_Q, %r0 /* prep to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - ldil L%(2f), %r1 - ldo R%(2f)(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ + load32 KERNEL_PSW, %r1 + or %r1, %r19, %r1 /* I-bit to state on entry */ + mtctl %r1, %ipsw /* restore I-bit (entire PSW) */ rfi nop 2: bv %r0(%r2) nop - .exit + .exit .procend .export flush_instruction_cache_local,code @@ -238,7 +236,7 @@ fioneloop: /* Loop if LOOP = 1 */ fisync: sync - mtsm %r22 + mtsm %r22 /* restore I-bit */ bv %r0(%r2) nop .exit @@ -281,7 +279,7 @@ fdoneloop: /* Loop if LOOP = 1 */ fdsync: syncdma sync - mtsm %r22 + mtsm %r22 /* restore I-bit */ bv %r0(%r2) nop .exit @@ -988,11 +986,12 @@ flush_kernel_icache_range_asm: bv %r0(%r2) nop .exit - .procend - .align 128 - + /* align should cover use of rfi in disable_sr_hashing_asm and + * srdis_done. + */ + .align 256 .export disable_sr_hashing_asm,code disable_sr_hashing_asm: @@ -1000,28 +999,26 @@ disable_sr_hashing_asm: .callinfo NO_CALLS .entry - /* Switch to real mode */ + /* + * Switch to real mode + */ + /* pcxt_ssm_bug */ + rsm PSW_SM_I, %r0 + load32 PA(1f), %r1 + nop + nop + nop + nop + nop - ssm 0, %r0 /* relied upon translation! */ - nop - nop - nop - nop - nop - nop - nop - - rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */ - ldil L%REAL_MODE_PSW, %r1 - ldo R%REAL_MODE_PSW(%r1), %r1 - mtctl %r1, %cr22 + rsm PSW_SM_Q, %r0 /* prep to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - ldil L%PA(1f), %r1 - ldo R%PA(1f)(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ + load32 REAL_MODE_PSW, %r1 + mtctl %r1, %ipsw rfi nop @@ -1053,27 +1050,31 @@ srdis_pcxl: srdis_pa20: - /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */ + /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */ .word 0x144008bc /* mfdiag %dr2, %r28 */ depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */ .word 0x145c1840 /* mtdiag %r28, %dr2 */ + srdis_done: - /* Switch back to virtual mode */ + rsm PSW_SM_I, %r0 /* prep to load iia queue */ + load32 2f, %r1 + nop + nop + nop + nop + nop - rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ - ldil L%KERNEL_PSW, %r1 - ldo R%KERNEL_PSW(%r1), %r1 - mtctl %r1, %cr22 + rsm PSW_SM_Q, %r0 /* prep to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - ldil L%(2f), %r1 - ldo R%(2f)(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ + load32 KERNEL_PSW, %r1 + mtctl %r1, %ipsw rfi nop diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 8dd5defb7316..2310fc1b06a9 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -7,8 +7,8 @@ * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com) * */ -#include #include +#include .section .bss .export real_stack @@ -147,20 +147,17 @@ restore_control_regs: .text rfi_virt2real: /* switch to real mode... */ - ssm 0,0 /* See "relied upon translation" */ - nop /* PA 2.0 Arch. F-5 */ - nop - nop + rsm PSW_SM_I,%r0 + load32 PA(rfi_v2r_1), %r1 nop nop nop nop nop - rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q & I bits to load iia queue */ + rsm PSW_SM_Q,%r0 /* disable Q & I bits to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - load32 PA(rfi_v2r_1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ @@ -184,10 +181,8 @@ rfi_v2r_1: .text .align 128 rfi_real2virt: - ssm 0,0 /* See "relied upon translation" */ - nop /* PA 2.0 Arch. F-5 */ - nop - nop + rsm PSW_SM_I,%r0 + load32 (rfi_r2v_1), %r1 nop nop nop @@ -197,7 +192,6 @@ rfi_real2virt: rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */ mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ - load32 (rfi_r2v_1), %r1 mtctl %r1, %cr18 /* IIAOQ head */ ldo 4(%r1), %r1 mtctl %r1, %cr18 /* IIAOQ tail */ diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 30b023411fef..b24a99e3ef9c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -450,5 +450,30 @@ REST_CR (%cr22, PT_PSW (\regs)) .endm + + /* First step to create a "relied upon translation" + * See PA 2.0 Arch. page F-4 and F-5. + * + * The ssm was originally necessary due to a "PCxT bug". + * But someone decided it needed to be added to the architecture + * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual. + * It's been carried forward into PA 2.0 Arch as well. :^( + * + * "ssm 0,%r0" is a NOP with side effects (prefetch barrier). + * rsm/ssm prevents the ifetch unit from speculatively fetching + * instructions past this line in the code stream. + * PA 2.0 processor will single step all insn in the same QUAD (4 insn). + */ + .macro pcxt_ssm_bug + rsm PSW_SM_I,%r0 + nop /* 1 */ + nop /* 2 */ + nop /* 3 */ + nop /* 4 */ + nop /* 5 */ + nop /* 6 */ + nop /* 7 */ + .endm + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h index 51323029f377..4334d6ca2add 100644 --- a/include/asm-parisc/psw.h +++ b/include/asm-parisc/psw.h @@ -1,4 +1,7 @@ #ifndef _PARISC_PSW_H + +#include + #define PSW_I 0x00000001 #define PSW_D 0x00000002 #define PSW_P 0x00000004 @@ -9,6 +12,16 @@ #define PSW_G 0x00000040 /* PA1.x only */ #define PSW_O 0x00000080 /* PA2.0 only */ +/* ssm/rsm instructions number PSW_W and PSW_E differently */ +#define PSW_SM_I PSW_I /* Enable External Interrupts */ +#define PSW_SM_D PSW_D +#define PSW_SM_P PSW_P +#define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */ +#define PSW_SM_R PSW_R /* Enable Recover Counter Trap */ +#define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ + +#define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I + #define PSW_CB 0x0000ff00 #define PSW_M 0x00010000 @@ -30,33 +43,21 @@ #define PSW_Z 0x40000000 /* PA1.x only */ #define PSW_Y 0x80000000 /* PA1.x only */ -#ifdef __LP64__ -#define PSW_HI_CB 0x000000ff /* PA2.0 only */ +#ifdef CONFIG_64BIT +# define PSW_HI_CB 0x000000ff /* PA2.0 only */ #endif -/* PSW bits to be used with ssm/rsm */ -#define PSW_SM_I 0x1 -#define PSW_SM_D 0x2 -#define PSW_SM_P 0x4 -#define PSW_SM_Q 0x8 -#define PSW_SM_R 0x10 -#define PSW_SM_F 0x20 -#define PSW_SM_G 0x40 -#define PSW_SM_O 0x80 -#define PSW_SM_E 0x100 -#define PSW_SM_W 0x200 - -#ifdef __LP64__ -# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) -# define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D) -# define REAL_MODE_PSW (PSW_W | PSW_Q) -# define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) -# define USER_PSW_HI_MASK (PSW_HI_CB) -#else -# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) -# define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D) -# define REAL_MODE_PSW (PSW_Q) -# define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) +#ifdef CONFIG_64BIT +# define USER_PSW_HI_MASK PSW_HI_CB +# define WIDE_PSW PSW_W +#else +# define WIDE_PSW 0 #endif +/* Used when setting up for rfi */ +#define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D) +#define REAL_MODE_PSW (WIDE_PSW | PSW_Q) +#define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) +#define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) + #endif diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index eb27b78930e8..efbb2d8625b1 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -64,29 +64,26 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, { unsigned long npages; - npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (npages >= 512) /* XXX arbitrary, should be tuned */ + if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ flush_tlb_all(); else { mtsp(vma->vm_mm->context,1); + purge_tlb_start(); if (split_tlb) { - purge_tlb_start(); while (npages--) { pdtlb(start); pitlb(start); start += PAGE_SIZE; } - purge_tlb_end(); } else { - purge_tlb_start(); while (npages--) { pdtlb(start); start += PAGE_SIZE; } - purge_tlb_end(); } + purge_tlb_end(); } } From 04d472dc83388c59deb6241e9aed841926aa1c8c Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:40:24 -0400 Subject: [PATCH 0379/1940] [PARISC] Move pa_tlb_lock to tlb_flush.h move pa_tlb_lock and it's primary consumers to tlb_flush.h Future step will be to move spinlock_t definition out of system.h. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/system.h | 19 ------------------- include/asm-parisc/tlbflush.h | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index 26ff844a21c1..a25e9dcd2e79 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h @@ -164,25 +164,6 @@ static inline void set_eiem(unsigned long val) #endif #define KERNEL_START (0x10100000 - 0x1000) - -/* This is for the serialisation of PxTLB broadcasts. At least on the - * N class systems, only one PxTLB inter processor broadcast can be - * active at any one time on the Merced bus. This tlb purge - * synchronisation is fairly lightweight and harmless so we activate - * it on all SMP systems not just the N class. */ -#ifdef CONFIG_SMP -extern spinlock_t pa_tlb_lock; - -#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) -#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) - -#else - -#define purge_tlb_start(x) do { } while(0) -#define purge_tlb_end(x) do { } while (0) - -#endif - #define arch_align_stack(x) (x) #endif diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index efbb2d8625b1..84af4ab1fe51 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -7,6 +7,26 @@ #include #include + +/* This is for the serialisation of PxTLB broadcasts. At least on the + * N class systems, only one PxTLB inter processor broadcast can be + * active at any one time on the Merced bus. This tlb purge + * synchronisation is fairly lightweight and harmless so we activate + * it on all SMP systems not just the N class. */ +#ifdef CONFIG_SMP +extern spinlock_t pa_tlb_lock; + +#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) +#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) + +#else + +#define purge_tlb_start(x) do { } while(0) +#define purge_tlb_end(x) do { } while (0) + +#endif + + extern void flush_tlb_all(void); /* From 14e256c107304367eff401d20f2ab9fa72e33136 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:41:25 -0400 Subject: [PATCH 0380/1940] [PARISC] Update spinlocks from parisc tree Neaten up the CONFIG_PA20 ifdefs More merge fixes, this time for SMP Signed-off-by: Matthew Wilcox Prettify the CONFIG_DEBUG_SPINLOCK __SPIN_LOCK_UNLOCKED initializers. Clean up some warnings with CONFIG_DEBUG_SPINLOCK enabled. Fix build with spinlock debugging turned on. Patch is cleaner like this, too. Remove mandatory 16-byte alignment requirement on PA2.0 processors by using the ldcw,CO completer. Provides a nice insn savings. Signed-off-by: Kyle McMartin --- include/asm-parisc/spinlock.h | 5 ----- include/asm-parisc/spinlock_types.h | 8 ++++++-- include/asm-parisc/system.h | 31 ++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h index 43eaa6e742e0..7c3f406a746a 100644 --- a/include/asm-parisc/spinlock.h +++ b/include/asm-parisc/spinlock.h @@ -5,11 +5,6 @@ #include #include -/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked - * since it only has load-and-zero. Moreover, at least on some PA processors, - * the semaphore address has to be 16-byte aligned. - */ - static inline int __raw_spin_is_locked(raw_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h index 785bba822fbf..d6b479bdb886 100644 --- a/include/asm-parisc/spinlock_types.h +++ b/include/asm-parisc/spinlock_types.h @@ -6,11 +6,15 @@ #endif typedef struct { +#ifdef CONFIG_PA20 + volatile unsigned int slock; +# define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#else volatile unsigned int lock[4]; +# define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } +#endif } raw_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } - typedef struct { raw_spinlock_t lock; volatile int counter; diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index a25e9dcd2e79..f3928d3a80cb 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h @@ -138,13 +138,7 @@ static inline void set_eiem(unsigned long val) #define set_wmb(var, value) do { var = value; wmb(); } while (0) -/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ -#define __ldcw(a) ({ \ - unsigned __ret; \ - __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \ - __ret; \ -}) - +#ifndef CONFIG_PA20 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, and GCC only guarantees 8-byte alignment for stack locals, we can't be assured of 16-byte alignment for atomic lock data even if we @@ -152,12 +146,35 @@ static inline void set_eiem(unsigned long val) we use a struct containing an array of four ints for the atomic lock type and dynamically select the 16-byte aligned int from the array for the semaphore. */ + #define __PA_LDCW_ALIGNMENT 16 #define __ldcw_align(a) ({ \ unsigned long __ret = (unsigned long) &(a)->lock[0]; \ __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ (volatile unsigned int *) __ret; \ }) +#define LDCW "ldcw" + +#else /*CONFIG_PA20*/ +/* From: "Jim Hull" + I've attached a summary of the change, but basically, for PA 2.0, as + long as the ",CO" (coherent operation) completer is specified, then the + 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead + they only require "natural" alignment (4-byte for ldcw, 8-byte for + ldcd). */ + +#define __PA_LDCW_ALIGNMENT 4 +#define __ldcw_align(a) ((volatile unsigned int *)a) +#define LDCW "ldcw,co" + +#endif /*!CONFIG_PA20*/ + +/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ +#define __ldcw(a) ({ \ + unsigned __ret; \ + __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \ + __ret; \ +}) #ifdef CONFIG_SMP # define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) From 951a0150135c46c7791d68e0d1112900d99302d7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:41:49 -0400 Subject: [PATCH 0381/1940] [PARISC] Reorganize sticore probe routine to be a little less convoluted Fix some whitespace issues Reorganise parisc_device probe routine to be a little less convoluted Use ->hpa.start instead of ->hpa Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/video/console/sticore.c | 126 +++++++++++++++----------------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index d940f605acb6..a7bcd17112c0 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -511,12 +511,12 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) struct sti_cooked_font *cooked_font; if (!fbfont_name || !strlen(fbfont_name)) - return NULL; + return NULL; fbfont = find_font(fbfont_name); if (!fbfont) - fbfont = get_default_font(1024,768); + fbfont = get_default_font(1024,768); if (!fbfont) - return NULL; + return NULL; DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n", fbfont->width, fbfont->height, fbfont->name)); @@ -527,7 +527,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) nf = kmalloc(size, GFP_KERNEL); if (!nf) - return NULL; + return NULL; memset(nf, 0, size); nf->first_char = 0; @@ -546,8 +546,8 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); if (!cooked_font) { - kfree(nf); - return NULL; + kfree(nf); + return NULL; } cooked_font->raw = nf; @@ -595,7 +595,7 @@ sti_select_font(struct sti_cooked_rom *rom, static void __init sti_dump_rom(struct sti_rom *rom) { - printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n", + printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n", rom->graphics_id[0], rom->graphics_id[1], rom->revno[0] >> 4, @@ -651,15 +651,16 @@ sti_search_font(struct sti_cooked_rom *rom, int height, int width) struct sti_cooked_font *font; int i = 0; - for(font = rom->font_start; font; font = font->next_font, i++) { - if((font->raw->width == width) && (font->raw->height == height)) + for (font = rom->font_start; font; font = font->next_font, i++) { + if ((font->raw->width == width) && + (font->raw->height == height)) return i; } return 0; } -#define BMODE_RELOCATE(offset) offset = (offset) / 4; -#define BMODE_LAST_ADDR_OFFS 0x50 +#define BMODE_RELOCATE(offset) offset = (offset) / 4; +#define BMODE_LAST_ADDR_OFFS 0x50 static void * __init sti_bmode_font_raw(struct sti_cooked_font *f) @@ -700,35 +701,35 @@ sti_get_bmode_rom (unsigned long address) { struct sti_rom *raw; u32 size; - struct sti_rom_font *raw_font, *font_start; - + struct sti_rom_font *raw_font, *font_start; + sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size); - - size = (size+3) / 4; + + size = (size+3) / 4; raw = kmalloc(size, GFP_KERNEL); if (raw) { - sti_bmode_rom_copy(address, size, raw); - memmove (&raw->res004, &raw->type[0], 0x3c); - raw->type[3] = raw->res004; + sti_bmode_rom_copy(address, size, raw); + memmove (&raw->res004, &raw->type[0], 0x3c); + raw->type[3] = raw->res004; - BMODE_RELOCATE (raw->region_list); - BMODE_RELOCATE (raw->font_start); + BMODE_RELOCATE (raw->region_list); + BMODE_RELOCATE (raw->font_start); - BMODE_RELOCATE (raw->init_graph); - BMODE_RELOCATE (raw->state_mgmt); - BMODE_RELOCATE (raw->font_unpmv); - BMODE_RELOCATE (raw->block_move); - BMODE_RELOCATE (raw->inq_conf); + BMODE_RELOCATE (raw->init_graph); + BMODE_RELOCATE (raw->state_mgmt); + BMODE_RELOCATE (raw->font_unpmv); + BMODE_RELOCATE (raw->block_move); + BMODE_RELOCATE (raw->inq_conf); - raw_font = ((void *)raw) + raw->font_start; - font_start = raw_font; + raw_font = ((void *)raw) + raw->font_start; + font_start = raw_font; - while (raw_font->next_font) { - BMODE_RELOCATE (raw_font->next_font); - raw_font = ((void *)font_start) + raw_font->next_font; - } + while (raw_font->next_font) { + BMODE_RELOCATE (raw_font->next_font); + raw_font = ((void *)font_start) + raw_font->next_font; + } } - return raw; + return raw; } struct sti_rom * __init @@ -736,15 +737,15 @@ sti_get_wmode_rom (unsigned long address) { struct sti_rom *raw; unsigned long size; - + /* read the ROM size directly from the struct in ROM */ size = gsc_readl(address + offsetof(struct sti_rom,last_addr)); raw = kmalloc(size, GFP_KERNEL); - if(raw) - sti_rom_copy(address, size, raw); + if (raw) + sti_rom_copy(address, size, raw); - return raw; + return raw; } int __init @@ -757,14 +758,14 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) if (!cooked) goto out_err; - if (wordmode) - raw = sti_get_wmode_rom (address); - else - raw = sti_get_bmode_rom (address); + if (wordmode) + raw = sti_get_wmode_rom (address); + else + raw = sti_get_bmode_rom (address); + + if (!raw) + goto out_err; - if (!raw) - goto out_err; - if (!sti_cook_fonts(cooked, raw)) { printk(KERN_ERR "No font found for STI at %08lx\n", address); goto out_err; @@ -787,7 +788,7 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) sti->font_width = sti->font->raw->width; sti->font_height = sti->font->raw->height; if (!wordmode) - sti->font->raw = sti_bmode_font_raw(sti->font); + sti->font->raw = sti_bmode_font_raw(sti->font); sti->sti_mem_request = raw->sti_mem_req; sti->graphics_id[0] = raw->graphics_id[0]; @@ -811,16 +812,16 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd u32 sig; if (num_sti_roms >= MAX_STI_ROMS) { - printk(KERN_WARNING "maximum number of STI ROMS reached !\n"); - return NULL; + printk(KERN_WARNING "maximum number of STI ROMS reached !\n"); + return NULL; } sti = kmalloc(sizeof(*sti), GFP_KERNEL); if (!sti) { - printk(KERN_ERR "Not enough memory !\n"); - return NULL; + printk(KERN_ERR "Not enough memory !\n"); + return NULL; } - + memset(sti, 0, sizeof(*sti)); spin_lock_init(&sti->lock); @@ -932,28 +933,21 @@ static void __init sticore_check_for_default_sti(struct sti_struct *sti, char *p */ static int __init sticore_pa_init(struct parisc_device *dev) { - unsigned long rom = 0; char pa_path[21]; struct sti_struct *sti = NULL; - - if(dev->num_addrs) { - rom = dev->addr[0]; - } - if (!rom) { - rom = dev->hpa; - DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa)); - sti = sti_try_rom_generic(rom, dev->hpa, NULL); - rom = PAGE0->proc_sti; - } - if (!sti) { - DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa)); - sti = sti_try_rom_generic(rom, dev->hpa, NULL); - } + int hpa = dev->hpa.start; + + if (dev->num_addrs && dev->addr[0]) + sti = sti_try_rom_generic(dev->addr[0], hpa, NULL); + if (!sti) + sti = sti_try_rom_generic(hpa, hpa, NULL); + if (!sti) + sti = sti_try_rom_generic(PAGE0->proc_sti, hpa, NULL); if (!sti) return 1; - + print_pa_hwpath(dev, pa_path); - sticore_check_for_default_sti (sti, pa_path); + sticore_check_for_default_sti(sti, pa_path); return 0; } From 5cd55b0edee7f979530c86b23728d461ddeb9f3f Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:42:18 -0400 Subject: [PATCH 0382/1940] [PARISC] Take into account nullified insn and lock functions for profiling export profile_pc() symbol - oprofile needs it when built as a module. Signed-off-by: Grant Grundler Take into account nullified insn and lock functions for profiling This is needed at the end of functions; it is typical that the return branch nullifies the next insn, which is in the next function. This causes profiling data to show up against the "wrong" function. We also count lock times against the locker. This is consistent with other architectures. Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- arch/parisc/kernel/time.c | 18 ++++++++++++++++++ include/asm-parisc/ptrace.h | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 7ff67f8e9f8c..163cdf39be20 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -104,6 +104,24 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } + +unsigned long profile_pc(struct pt_regs *regs) +{ + unsigned long pc = instruction_pointer(regs); + + if (regs->gr[0] & PSW_N) + pc -= 4; + +#ifdef CONFIG_SMP + if (in_lock_functions(pc)) + pc = regs->gr[2]; +#endif + + return pc; +} +EXPORT_SYMBOL(profile_pc); + + /*** converted from ia64 ***/ /* * Return the number of micro-seconds that elapsed since the last diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h index 3f428aa371a4..93f990e418f1 100644 --- a/include/asm-parisc/ptrace.h +++ b/include/asm-parisc/ptrace.h @@ -49,7 +49,7 @@ struct pt_regs { #define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) #define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) #define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) -#define profile_pc(regs) instruction_pointer(regs) +unsigned long profile_pc(struct pt_regs *); extern void show_regs(struct pt_regs *); #endif From 3a165680168758733b7a9f7fb835954fbe6b91a8 Mon Sep 17 00:00:00 2001 From: Stuart Brady Date: Fri, 21 Oct 2005 22:42:38 -0400 Subject: [PATCH 0383/1940] [PARISC] Update harmony from parisc tree o Added a control for the input source (which can be either "line" or "mic") o Mute the speaker/line-out/headphone outputs by default. o Increased the buffer size from 10 pages to 16. Signed-off-by: Stuart Brady ALSA Harmony was resetting the capture position when preparing the capture substream, which it shouldn't do. This should fix the problem. Signed-off-by: Stuart Brady ALSA Harmony should no longer play junk (left in the buffers from a previous stream) at the start of a new stream. Implement the monitor mixer channel for ALSA Harmony. Also prevent snd_harmony_volume_get from returning negative values. Signed-off-by: Stuart Brady Use the graveyard/silence buffers in ALSA Harmony. Signed-off-by: Stuart Brady Signed-off-by: Kyle McMartin --- sound/parisc/harmony.c | 118 ++++++++++++++++++++++++++++++++++------- sound/parisc/harmony.h | 17 +++--- 2 files changed, 109 insertions(+), 26 deletions(-) diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 8b3ea26469ad..d833349ed518 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -197,7 +197,7 @@ snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs) spin_unlock(&h->lock); if (dstatus & HARMONY_DSTATUS_PN) { - if (h->psubs) { + if (h->psubs && h->st.playing) { spin_lock(&h->lock); h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */ h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */ @@ -216,7 +216,7 @@ snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs) } if (dstatus & HARMONY_DSTATUS_RN) { - if (h->csubs) { + if (h->csubs && h->st.capturing) { spin_lock(&h->lock); h->cbuf.buf += h->cbuf.count; h->cbuf.buf %= h->cbuf.size; @@ -316,6 +316,7 @@ snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd) case SNDRV_PCM_TRIGGER_STOP: h->st.playing = 0; harmony_mute(h); + harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); harmony_disable_interrupts(h); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -351,8 +352,9 @@ snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd) break; case SNDRV_PCM_TRIGGER_STOP: h->st.capturing = 0; - harmony_mute(h); - harmony_disable_interrupts(h); + harmony_mute(h); + harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); + harmony_disable_interrupts(h); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: @@ -408,7 +410,8 @@ snd_harmony_playback_prepare(snd_pcm_substream_t *ss) h->pbuf.size = snd_pcm_lib_buffer_bytes(ss); h->pbuf.count = snd_pcm_lib_period_bytes(ss); - h->pbuf.buf = 0; + if (h->pbuf.buf >= h->pbuf.size) + h->pbuf.buf = 0; h->st.playing = 0; h->st.rate = snd_harmony_rate_bits(rt->rate); @@ -437,7 +440,8 @@ snd_harmony_capture_prepare(snd_pcm_substream_t *ss) h->cbuf.size = snd_pcm_lib_buffer_bytes(ss); h->cbuf.count = snd_pcm_lib_period_bytes(ss); - h->cbuf.buf = 0; + if (h->cbuf.buf >= h->cbuf.size) + h->cbuf.buf = 0; h->st.capturing = 0; h->st.rate = snd_harmony_rate_bits(rt->rate); @@ -712,13 +716,14 @@ snd_harmony_volume_get(snd_kcontrol_t *kc, left = (h->st.gain >> shift_left) & mask; right = (h->st.gain >> shift_right) & mask; - if (invert) { left = mask - left; right = mask - right; } + ucontrol->value.integer.value[0] = left; - ucontrol->value.integer.value[1] = right; + if (shift_left != shift_right) + ucontrol->value.integer.value[1] = right; spin_unlock_irqrestore(&h->mixer_lock, flags); @@ -738,22 +743,82 @@ snd_harmony_volume_put(snd_kcontrol_t *kc, int old_gain = h->st.gain; unsigned long flags; - left = ucontrol->value.integer.value[0] & mask; - right = ucontrol->value.integer.value[1] & mask; - if (invert) { - left = mask - left; - right = mask - right; - } - spin_lock_irqsave(&h->mixer_lock, flags); - h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) ); - h->st.gain |= ( (left << shift_left) | (right << shift_right) ); + left = ucontrol->value.integer.value[0] & mask; + if (invert) + left = mask - left; + h->st.gain &= ~( (mask << shift_left ) ); + h->st.gain |= (left << shift_left); + + if (shift_left != shift_right) { + right = ucontrol->value.integer.value[1] & mask; + if (invert) + right = mask - right; + h->st.gain &= ~( (mask << shift_right) ); + h->st.gain |= (right << shift_right); + } + snd_harmony_set_new_gain(h); spin_unlock_irqrestore(&h->mixer_lock, flags); - return (old_gain - h->st.gain); + return h->st.gain != old_gain; +} + +static int +snd_harmony_captureroute_info(snd_kcontrol_t *kc, + snd_ctl_elem_info_t *uinfo) +{ + static char *texts[2] = { "Line", "Mic" }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item > 1) + uinfo->value.enumerated.item = 1; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int +snd_harmony_captureroute_get(snd_kcontrol_t *kc, + snd_ctl_elem_value_t *ucontrol) +{ + harmony_t *h = snd_kcontrol_chip(kc); + int value; + unsigned long flags; + + spin_lock_irqsave(&h->mixer_lock, flags); + + value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1; + ucontrol->value.enumerated.item[0] = value; + + spin_unlock_irqrestore(&h->mixer_lock, flags); + + return 0; +} + +static int +snd_harmony_captureroute_put(snd_kcontrol_t *kc, + snd_ctl_elem_value_t *ucontrol) +{ + harmony_t *h = snd_kcontrol_chip(kc); + int value; + int old_gain = h->st.gain; + unsigned long flags; + + spin_lock_irqsave(&h->mixer_lock, flags); + + value = ucontrol->value.enumerated.item[0] & 1; + h->st.gain &= ~HARMONY_GAIN_IS_MASK; + h->st.gain |= value << HARMONY_GAIN_IS_SHIFT; + + snd_harmony_set_new_gain(h); + + spin_unlock_irqrestore(&h->mixer_lock, flags); + + return h->st.gain != old_gain; } #define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \ @@ -767,10 +832,25 @@ snd_harmony_volume_put(snd_kcontrol_t *kc, ((mask) << 16) | ((invert) << 24)) } static snd_kcontrol_new_t snd_harmony_controls[] = { - HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT, + HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT, HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1), HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT, HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0), + HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT, + HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Route", + .info = snd_harmony_captureroute_info, + .get = snd_harmony_captureroute_get, + .put = snd_harmony_captureroute_put + }, + HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT, + HARMONY_GAIN_SE_SHIFT, 1, 0), + HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT, + HARMONY_GAIN_LE_SHIFT, 1, 0), + HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT, + HARMONY_GAIN_HE_SHIFT, 1, 0), }; static void __init diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h index ef77f9a577d5..526c52389de2 100644 --- a/sound/parisc/harmony.h +++ b/sound/parisc/harmony.h @@ -61,7 +61,7 @@ typedef struct snd_card_harmony { #define HARMONY_SIZE 64 #define BUF_SIZE PAGE_SIZE -#define MAX_BUFS 10 +#define MAX_BUFS 16 #define MAX_BUF_SIZE (MAX_BUFS * BUF_SIZE) #define PLAYBACK_BUFS MAX_BUFS @@ -101,28 +101,31 @@ typedef struct snd_card_harmony { #define HARMONY_SS_MONO 0x00000000 #define HARMONY_SS_STEREO 0x00000001 -#define HARMONY_GAIN_SILENCE 0x00F00FFF -#define HARMONY_GAIN_DEFAULT 0x0FF00000 +#define HARMONY_GAIN_SILENCE 0x01F00FFF +#define HARMONY_GAIN_DEFAULT 0x01F00FFF -#define HARMONY_GAIN_HE_SHIFT 27 +#define HARMONY_GAIN_HE_SHIFT 27 /* headphones enabled */ #define HARMONY_GAIN_HE_MASK (1 << HARMONY_GAIN_HE_SHIFT) -#define HARMONY_GAIN_LE_SHIFT 26 +#define HARMONY_GAIN_LE_SHIFT 26 /* line-out enabled */ #define HARMONY_GAIN_LE_MASK (1 << HARMONY_GAIN_LE_SHIFT) -#define HARMONY_GAIN_SE_SHIFT 25 +#define HARMONY_GAIN_SE_SHIFT 25 /* internal-speaker enabled */ #define HARMONY_GAIN_SE_MASK (1 << HARMONY_GAIN_SE_SHIFT) -#define HARMONY_GAIN_IS_SHIFT 24 +#define HARMONY_GAIN_IS_SHIFT 24 /* input select - 0 for line, 1 for mic */ #define HARMONY_GAIN_IS_MASK (1 << HARMONY_GAIN_IS_SHIFT) +/* monitor attenuation */ #define HARMONY_GAIN_MA 0x0f #define HARMONY_GAIN_MA_SHIFT 20 #define HARMONY_GAIN_MA_MASK (HARMONY_GAIN_MA << HARMONY_GAIN_MA_SHIFT) +/* input gain */ #define HARMONY_GAIN_IN 0x0f #define HARMONY_GAIN_LI_SHIFT 16 #define HARMONY_GAIN_LI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_LI_SHIFT) #define HARMONY_GAIN_RI_SHIFT 12 #define HARMONY_GAIN_RI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_RI_SHIFT) +/* output gain (master volume) */ #define HARMONY_GAIN_OUT 0x3f #define HARMONY_GAIN_LO_SHIFT 6 #define HARMONY_GAIN_LO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_LO_SHIFT) From 99ac79479928bae42d694b7cb53644be5d3b6dd2 Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:42:57 -0400 Subject: [PATCH 0384/1940] [PARISC] Replace some calls to bl with b,l or bv to use longer offsets convert some bl calls to b,l or bv to use longer offsets Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 65a82c2645a7..ec04e0ad77fa 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -821,7 +821,12 @@ ret_from_kernel_thread: ldo -16(%r30),%r29 /* Reference param save area */ loadgp /* Thread could have been in a module */ #endif +#ifndef CONFIG_64BIT b sys_exit +#else + load32 sys_exit, %r1 + bv %r0(%r1) +#endif ldi 0, %r26 .import sys_execve, code @@ -1012,7 +1017,7 @@ intr_restore: .import do_softirq,code intr_do_softirq: - bl do_softirq,%r2 + BL do_softirq,%r2 #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ #else @@ -1036,7 +1041,12 @@ intr_do_resched: #endif ldil L%intr_check_sig, %r2 +#ifndef CONFIG_64BIT b schedule +#else + load32 schedule, %r20 + bv %r0(%r20) +#endif ldo R%intr_check_sig(%r2), %r2 @@ -1897,7 +1907,7 @@ sys_vfork_wrapper: #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ #endif - bl \execve,%r2 + BL \execve,%r2 copy %r1,%arg0 ldo -FRAME_SIZE(%r30),%r30 @@ -2226,7 +2236,7 @@ pt_regs_ok: .import do_softirq,code syscall_do_softirq: - bl do_softirq,%r2 + BL do_softirq,%r2 nop /* NOTE: We enable I-bit incase we schedule later, * and we might be going back to userspace if we were From f053725b8985d10c2cc4b837a80a381104c936a4 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 22:43:15 -0400 Subject: [PATCH 0385/1940] [PARISC] Add ability for prctl to change unaligned trap behaviour Add support for changing unaligned trap behaviour on a per-thread basis. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/unaligned.c | 16 ++++++++++------ include/asm-parisc/processor.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 62eea35bcd69..eaae8a021f9f 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -513,15 +513,18 @@ void handle_unaligned(struct pt_regs *regs) register int flop=0; /* true if this is a flop */ /* log a message with pacing */ - if (user_mode(regs)) - { - if (unaligned_count > 5 && jiffies - last_time > 5*HZ) - { + if (user_mode(regs)) { + if (current->thread.flags & PARISC_UAC_SIGBUS) { + goto force_sigbus; + } + + if (unaligned_count > 5 && jiffies - last_time > 5*HZ) { unaligned_count = 0; last_time = jiffies; } - if (++unaligned_count < 5) - { + + if (!(current->thread.flags & PARISC_UAC_NOPRINT) + && ++unaligned_count < 5) { char buf[256]; sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n", current->comm, current->pid, regs->ior, regs->iaoq[0]); @@ -530,6 +533,7 @@ void handle_unaligned(struct pt_regs *regs) show_regs(regs); #endif } + if (!unaligned_enabled) goto force_sigbus; } diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index a9dfadd05658..aae40e8c3aa8 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -122,8 +122,27 @@ struct thread_struct { }; /* Thread struct flags. */ +#define PARISC_UAC_NOPRINT (1UL << 0) /* see prctl and unaligned.c */ +#define PARISC_UAC_SIGBUS (1UL << 1) #define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */ +#define PARISC_UAC_SHIFT 0 +#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS) + +#define SET_UNALIGN_CTL(task,value) \ + ({ \ + (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \ + | (((value) << PARISC_UAC_SHIFT) & \ + PARISC_UAC_MASK)); \ + 0; \ + }) + +#define GET_UNALIGN_CTL(task,addr) \ + ({ \ + put_user(((task)->thread.flags & PARISC_UAC_MASK) \ + >> PARISC_UAC_SHIFT, (int __user *) (addr)); \ + }) + #define INIT_THREAD { \ regs: { gr: { 0, }, \ fr: { 0, }, \ From 2464212f68136527f6364d63c23a529e1fd7d168 Mon Sep 17 00:00:00 2001 From: Stuart Brady Date: Fri, 21 Oct 2005 22:44:14 -0400 Subject: [PATCH 0386/1940] [PARISC] Fix parisc_setup_cache_timing to choose a better flush threshold update comment about CAFL_STRIDE Signed-off-by: Kyle McMartin Fixed a bug in parisc_setup_cache_timing() which caused it to calculate a poor value for parisc_cache_flush_threshold. Thanks to Joel Soete for spotting the bug. Thanks to James Bottomley for pointing out the clean way to fix this. Signed-off-by: Stuart Brady Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index f46a07a79218..e15f09eaed12 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -27,6 +27,7 @@ #include #include #include +#include int split_tlb; int dcache_stride; @@ -207,6 +208,9 @@ parisc_cache_init(void) /* "New and Improved" version from Jim Hull * (1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift)) + * The following CAFL_STRIDE is an optimized version, see + * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023625.html + * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023671.html */ #define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift)) dcache_stride = CAFL_STRIDE(cache_info.dc_conf); @@ -339,17 +343,15 @@ int parisc_cache_flush_threshold = FLUSH_THRESHOLD; void parisc_setup_cache_timing(void) { unsigned long rangetime, alltime; - extern char _text; /* start of kernel code, defined by linker */ - extern char _end; /* end of BSS, defined by linker */ unsigned long size; alltime = mfctl(16); flush_data_cache(); alltime = mfctl(16) - alltime; - size = (unsigned long)(&_end - _text); + size = (unsigned long)(_end - _text); rangetime = mfctl(16); - flush_kernel_dcache_range((unsigned long)&_text, size); + flush_kernel_dcache_range((unsigned long)_text, size); rangetime = mfctl(16) - rangetime; printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n", From a366064c3ff46c985a3c7243468be197d29874dc Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:45:22 -0400 Subject: [PATCH 0387/1940] [PARISC] Update bitops from parisc tree Optimize ext2_find_next_zero_bit. Gives about 25% perf improvement with a rsync test with ext3. Signed-off-by: Randolph Chung fix ext3 performance - ext2_find_next_zero() was culprit. Kudos to jejb for pointing out the the possibility that ext2_test_bit and ext2_find_next_zero() may in fact not be enumerating bits in the bitmap because of endianess. Took sparc64 implementation and adapted it to our tree. I suspect the real problem is ffz() wants an unsigned long and was getting garbage in the top half of the unsigned int. Not confirmed but that's what I suspect. Signed-off-by: Grant Grundler Fix find_next_bit for 32-bit Make masking consistent for bitops From: Joel Soete Signed-off-by: Randolph Chung Add back incorrectly removed ext2_find_first_zero_bit definition Signed-off-by: James Bottomley Fixup bitops.h to use volatile for *_bit() ops Based on this email thread: http://marc.theaimsgroup.com/?t=108826637900003 In a nutshell: *_bit() want use of volatile. __*_bit() are "relaxed" and don't use spinlock or volatile. other minor changes: o replaces hweight64() macro with alias to generic_hweight64() (Joel Soete) o cleanup ext2* macros so (a) it's obvious what the XOR magic is about and (b) one version that works for both 32/64-bit. o replace 2 uses of CONFIG_64BIT with __LP64__. bitops.h used both. I think header files that might go to user space should use something userspace will know about (__LP64__). Signed-off-by: Grant Grundler Move SHIFT_PER_LONG to standard location for BITS_PER_LONG (asm/types.h) and ditch the second definition of BITS_PER_LONG in bitops.h Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/bitops.h | 292 ++++++++++++++++-------------------- include/asm-parisc/types.h | 2 + 2 files changed, 135 insertions(+), 159 deletions(-) diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index af7db694b22d..55b98c67fd82 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h @@ -2,7 +2,7 @@ #define _PARISC_BITOPS_H #include -#include +#include /* for BITS_PER_LONG/SHIFT_PER_LONG */ #include #include @@ -12,193 +12,157 @@ * to include/asm-i386/bitops.h or kerneldoc */ -#ifdef __LP64__ -# define SHIFT_PER_LONG 6 -#ifndef BITS_PER_LONG -# define BITS_PER_LONG 64 -#endif -#else -# define SHIFT_PER_LONG 5 -#ifndef BITS_PER_LONG -# define BITS_PER_LONG 32 -#endif -#endif - -#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1)) +#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1)) #define smp_mb__before_clear_bit() smp_mb() #define smp_mb__after_clear_bit() smp_mb() -static __inline__ void set_bit(int nr, volatile unsigned long * address) +/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion + * on use of volatile and __*_bit() (set/clear/change): + * *_bit() want use of volatile. + * __*_bit() are "relaxed" and don't use spinlock or volatile. + */ + +static __inline__ void set_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); *addr |= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __set_bit(int nr, volatile unsigned long * address) +static __inline__ void __set_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr |= mask; + *m |= 1UL << CHOP_SHIFTCOUNT(nr); } -static __inline__ void clear_bit(int nr, volatile unsigned long * address) +static __inline__ void clear_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = ~(1UL << CHOP_SHIFTCOUNT(nr)); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - *addr &= ~mask; + *addr &= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address) +static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr &= ~mask; + *m &= ~(1UL << CHOP_SHIFTCOUNT(nr)); } -static __inline__ void change_bit(int nr, volatile unsigned long * address) +static __inline__ void change_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); *addr ^= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __change_bit(int nr, volatile unsigned long * address) +static __inline__ void __change_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr ^= mask; + *m ^= 1UL << CHOP_SHIFTCOUNT(nr); } -static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr |= mask; + oldbit = *addr; + *addr = oldbit | mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr |= mask; + oldbit = *addr; + *addr = oldbit | mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } -static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr &= ~mask; + oldbit = *addr; + *addr = oldbit & ~mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); + unsigned long oldbit; - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr &= ~mask; + oldbit = *addr; + *addr = oldbit & ~mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } -static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr ^= mask; + oldbit = *addr; + *addr = oldbit ^ mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); + unsigned long oldbit; - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr ^= mask; + oldbit = *addr; + *addr = oldbit ^ mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int test_bit(int nr, const volatile unsigned long *address) { - unsigned long mask; - const unsigned long *addr = (const unsigned long *)address; - - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + const unsigned long *addr = (const unsigned long *)address + (nr >> SHIFT_PER_LONG); return !!(*addr & mask); } @@ -229,7 +193,7 @@ static __inline__ unsigned long __ffs(unsigned long x) unsigned long ret; __asm__( -#if BITS_PER_LONG > 32 +#ifdef __LP64__ " ldi 63,%1\n" " extrd,u,*<> %0,63,32,%%r0\n" " extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */ @@ -304,14 +268,7 @@ static __inline__ int fls(int x) * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -#define hweight64(x) \ -({ \ - unsigned long __x = (x); \ - unsigned int __w; \ - __w = generic_hweight32((unsigned int) __x); \ - __w += generic_hweight32((unsigned int) (__x>>32)); \ - __w; \ -}) +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) @@ -324,7 +281,13 @@ static __inline__ int fls(int x) */ static inline int sched_find_first_bit(const unsigned long *b) { -#ifndef __LP64__ +#ifdef __LP64__ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 64; + return __ffs(b[2]) + 128; +#else if (unlikely(b[0])) return __ffs(b[0]); if (unlikely(b[1])) @@ -334,14 +297,6 @@ static inline int sched_find_first_bit(const unsigned long *b) if (b[3]) return __ffs(b[3]) + 96; return __ffs(b[4]) + 128; -#else - if (unlikely(b[0])) - return __ffs(b[0]); - if (unlikely(((unsigned int)b[1]))) - return __ffs(b[1]) + 64; - if (b[1] >> 32) - return __ffs(b[1] >> 32) + 96; - return __ffs(b[2]) + 128; #endif } @@ -391,7 +346,7 @@ static __inline__ unsigned long find_next_zero_bit(const void * addr, unsigned l static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - const unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> SHIFT_PER_LONG); unsigned long result = offset & ~(BITS_PER_LONG-1); unsigned long tmp; @@ -445,71 +400,90 @@ static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigne * test_and_{set,clear}_bit guarantee atomicity without * disabling interrupts. */ -#ifdef __LP64__ -#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr) -#else -#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr) -#endif + +/* '3' is bits per byte */ +#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3) + +#define ext2_test_bit(nr, addr) \ + test_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_set_bit(nr, addr) \ + __test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_clear_bit(nr, addr) \ + __test_and_clear_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) + +#define ext2_set_bit_atomic(l,nr,addr) \ + test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_clear_bit_atomic(l,nr,addr) \ + test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) #endif /* __KERNEL__ */ -static __inline__ int ext2_test_bit(int nr, __const__ void * addr) -{ - __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; - - return (ADDR[nr >> 3] >> (nr & 7)) & 1; -} - -/* - * This implementation of ext2_find_{first,next}_zero_bit was stolen from - * Linus' asm-alpha/bitops.h and modified for a big-endian machine. - */ #define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) + ext2_find_next_zero_bit((addr), (size), 0) -extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, - unsigned long size, unsigned long offset) +/* include/linux/byteorder does not support "unsigned long" type */ +static inline unsigned long ext2_swabp(unsigned long * x) { - unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - unsigned int result = offset & ~31UL; - unsigned int tmp; +#ifdef __LP64__ + return (unsigned long) __swab64p((u64 *) x); +#else + return (unsigned long) __swab32p((u32 *) x); +#endif +} + +/* include/linux/byteorder doesn't support "unsigned long" type */ +static inline unsigned long ext2_swab(unsigned long y) +{ +#ifdef __LP64__ + return (unsigned long) __swab64((u64) y); +#else + return (unsigned long) __swab32((u32) y); +#endif +} + +static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = (unsigned long *) addr + (offset >> SHIFT_PER_LONG); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; if (offset >= size) return size; size -= result; - offset &= 31UL; + offset &= (BITS_PER_LONG - 1UL); if (offset) { - tmp = cpu_to_le32p(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) + tmp = ext2_swabp(p++); + tmp |= (~0UL >> (BITS_PER_LONG - offset)); + if (size < BITS_PER_LONG) goto found_first; - if (tmp != ~0U) + if (~tmp) goto found_middle; - size -= 32; - result += 32; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; } - while (size >= 32) { - if ((tmp = cpu_to_le32p(p++)) != ~0U) - goto found_middle; - result += 32; - size -= 32; + + while (size & ~(BITS_PER_LONG - 1)) { + if (~(tmp = *(p++))) + goto found_middle_swap; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; } if (!size) return result; - tmp = cpu_to_le32p(p); + tmp = ext2_swabp(p); found_first: - tmp |= ~0U << size; + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. Skip ffz */ found_middle: return result + ffz(tmp); + +found_middle_swap: + return result + ffz(ext2_swab(tmp)); } + /* Bitmap functions for the minix filesystem. */ #define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr) #define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr)) diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h index d21b9d0d63ea..34fdce361a5a 100644 --- a/include/asm-parisc/types.h +++ b/include/asm-parisc/types.h @@ -33,8 +33,10 @@ typedef unsigned long long __u64; #ifdef __LP64__ #define BITS_PER_LONG 64 +#define SHIFT_PER_LONG 6 #else #define BITS_PER_LONG 32 +#define SHIFT_PER_LONG 5 #endif #ifndef __ASSEMBLY__ From ba1f188cae2f58e6bf3ecf4ea99a8dc4b0e2ea0e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 21 Oct 2005 22:45:57 -0400 Subject: [PATCH 0388/1940] [PARISC] Add new ioprio_{set,get} syscalls add syscall entries for ioprio_set/get as per Jens Axboe. Signed-off-by: Jens Axboe Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 6 ++++++ include/asm-parisc/unistd.h | 16 +++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index dcfa4d3d0e7d..065ab809659d 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -368,5 +368,11 @@ ENTRY_COMP(mbind) /* 260 */ ENTRY_COMP(get_mempolicy) ENTRY_COMP(set_mempolicy) + ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */ + ENTRY_SAME(add_key) + ENTRY_SAME(request_key) /* 265 */ + ENTRY_SAME(keyctl) + ENTRY_SAME(ioprio_set) + ENTRY_SAME(ioprio_get) /* Nothing yet */ diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 6a9f0cadff58..e7a620c5c5e6 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -687,8 +687,8 @@ #define __NR_shmget (__NR_Linux + 194) #define __NR_shmctl (__NR_Linux + 195) -#define __NR_getpmsg (__NR_Linux + 196) /* some people actually want streams */ -#define __NR_putpmsg (__NR_Linux + 197) /* some people actually want streams */ +#define __NR_getpmsg (__NR_Linux + 196) /* Somebody *wants* streams? */ +#define __NR_putpmsg (__NR_Linux + 197) #define __NR_lstat64 (__NR_Linux + 198) #define __NR_truncate64 (__NR_Linux + 199) @@ -755,8 +755,14 @@ #define __NR_mbind (__NR_Linux + 260) #define __NR_get_mempolicy (__NR_Linux + 261) #define __NR_set_mempolicy (__NR_Linux + 262) +#define __NR_vserver (__NR_Linux + 263) +#define __NR_add_key (__NR_Linux + 264) +#define __NR_request_key (__NR_Linux + 265) +#define __NR_keyctl (__NR_Linux + 266) +#define __NR_ioprio_set (__NR_Linux + 267) +#define __NR_ioprio_get (__NR_Linux + 268) -#define __NR_Linux_syscalls 263 +#define __NR_Linux_syscalls 269 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 @@ -807,10 +813,10 @@ #define K_INLINE_SYSCALL(name, nr, args...) ({ \ long __sys_res; \ { \ - register unsigned long __res asm("r28"); \ + register unsigned long __res __asm__("r28"); \ K_LOAD_ARGS_##nr(args) \ /* FIXME: HACK stw/ldw r19 around syscall */ \ - asm volatile( \ + __asm__ volatile( \ K_STW_ASM_PIC \ " ble 0x100(%%sr2, %%r0)\n" \ " ldi %1, %%r20\n" \ From 3499495205a676d85fcc2f3c28e35ec9b43c47e3 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:46:18 -0400 Subject: [PATCH 0389/1940] [PARISC] Use work queue in LED/LCD driver instead of tasklet. 2.6.12-rc1-pa6 use work queue in LED/LCD driver instead of tasklet. Main advantage is it allows use of msleep() in the led_LCD_driver to "atomically" perform two MMIO writes (CMD, then DATA). Lead to nice cleanup of the main led_work_func() and led_LCD_driver(). Kudos to David for being persistent. From: David Pye Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/time.c | 8 -- drivers/parisc/led.c | 225 +++++++++++++++++++------------------- include/asm-parisc/led.h | 3 - 3 files changed, 112 insertions(+), 124 deletions(-) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 163cdf39be20..bc979e1abdec 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -89,14 +89,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) } } -#ifdef CONFIG_CHASSIS_LCD_LED - /* Only schedule the led tasklet on cpu 0, and only if it - * is enabled. - */ - if (cpu == 0 && !atomic_read(&led_tasklet.count)) - tasklet_schedule(&led_tasklet); -#endif - /* check soft power switch status */ if (cpu == 0 && !atomic_read(&power_tasklet.count)) tasklet_schedule(&power_tasklet); diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 286902298e33..95bd07b8b61b 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -18,6 +18,9 @@ * Changes: * - Audit copy_from_user in led_proc_write. * Daniele Bellucci + * - Switch from using a tasklet to a work queue, so the led_LCD_driver + * can sleep. + * David Pye */ #include @@ -37,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -47,25 +51,30 @@ #include /* The control of the LEDs and LCDs on PARISC-machines have to be done - completely in software. The necessary calculations are done in a tasklet - which is scheduled at every timer interrupt and since the calculations - may consume relatively much CPU-time some of the calculations can be + completely in software. The necessary calculations are done in a work queue + task which is scheduled regularly, and since the calculations may consume a + relatively large amount of CPU time, some of the calculations can be turned off with the following variables (controlled via procfs) */ static int led_type = -1; -static int led_heartbeat = 1; -static int led_diskio = 1; -static int led_lanrxtx = 1; +static unsigned char lastleds; /* LED state from most recent update */ +static unsigned int led_heartbeat = 1; +static unsigned int led_diskio = 1; +static unsigned int led_lanrxtx = 1; static char lcd_text[32]; static char lcd_text_default[32]; + +static struct workqueue_struct *led_wq; +static void led_work_func(void *); +static DECLARE_WORK(led_task, led_work_func, NULL); + #if 0 #define DPRINTK(x) printk x #else #define DPRINTK(x) #endif - struct lcd_block { unsigned char command; /* stores the command byte */ unsigned char on; /* value for turning LED on */ @@ -116,12 +125,27 @@ lcd_info __attribute__((aligned(8))) = #define LCD_DATA_REG lcd_info.lcd_data_reg_addr #define LED_DATA_REG lcd_info.lcd_cmd_reg_addr /* LASI & ASP only */ +#define LED_HASLCD 1 +#define LED_NOLCD 0 + +/* The workqueue must be created at init-time */ +static int start_task(void) +{ + /* Display the default text now */ + if (led_type == LED_HASLCD) lcd_print( lcd_text_default ); + + /* Create the work queue and queue the LED task */ + led_wq = create_singlethread_workqueue("led_wq"); + queue_work(led_wq, &led_task); + + return 0; +} + +device_initcall(start_task); /* ptr to LCD/LED-specific function */ static void (*led_func_ptr) (unsigned char); -#define LED_HASLCD 1 -#define LED_NOLCD 0 #ifdef CONFIG_PROC_FS static int led_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -286,52 +310,35 @@ static void led_LASI_driver(unsigned char leds) /* ** ** led_LCD_driver() - ** - ** The logic of the LCD driver is, that we write at every scheduled call - ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers. - ** That way we don't need to let this tasklet busywait for min_cmd_delay - ** milliseconds. - ** - ** TODO: check the value of "min_cmd_delay" against the value of HZ. ** */ static void led_LCD_driver(unsigned char leds) { - static int last_index; /* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */ - static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */ - struct lcd_block *block_ptr; - int value; - - switch (last_index) { - case 0: block_ptr = &lcd_info.heartbeat; - value = leds & LED_HEARTBEAT; - break; - case 1: block_ptr = &lcd_info.disk_io; - value = leds & LED_DISK_IO; - break; - case 2: block_ptr = &lcd_info.lan_rcv; - value = leds & LED_LAN_RCV; - break; - case 3: block_ptr = &lcd_info.lan_tx; - value = leds & LED_LAN_TX; - break; - default: /* should never happen: */ - return; - } - - if (last_was_cmd) { - /* write the value to the LCD data port */ - gsc_writeb( value ? block_ptr->on : block_ptr->off, LCD_DATA_REG ); - } else { - /* write the command-byte to the LCD command register */ - gsc_writeb( block_ptr->command, LCD_CMD_REG ); - } + static int i; + static unsigned char mask[4] = { LED_HEARTBEAT, LED_DISK_IO, + LED_LAN_RCV, LED_LAN_TX }; - /* now update the vars for the next interrupt iteration */ - if (++last_was_cmd == 2) { /* switch between cmd & data */ - last_was_cmd = 0; - if (++last_index == 4) - last_index = 0; /* switch back to heartbeat index */ + static struct lcd_block * blockp[4] = { + &lcd_info.heartbeat, + &lcd_info.disk_io, + &lcd_info.lan_rcv, + &lcd_info.lan_tx + }; + + /* Convert min_cmd_delay to milliseconds */ + unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000); + + for (i=0; i<4; ++i) + { + if ((leds & mask[i]) != (lastleds & mask[i])) + { + gsc_writeb( blockp[i]->command, LCD_CMD_REG ); + msleep(msec_cmd_delay); + + gsc_writeb( leds & mask[i] ? blockp[i]->on : + blockp[i]->off, LCD_DATA_REG ); + msleep(msec_cmd_delay); + } } } @@ -356,7 +363,7 @@ static __inline__ int led_get_net_activity(void) rx_total = tx_total = 0; - /* we are running as tasklet, so locking dev_base + /* we are running as a workqueue task, so locking dev_base * for reading should be OK */ read_lock(&dev_base_lock); rcu_read_lock(); @@ -405,7 +412,7 @@ static __inline__ int led_get_diskio_activity(void) static unsigned long last_pgpgin, last_pgpgout; struct page_state pgstat; int changed; - + get_full_page_state(&pgstat); /* get no of sectors in & out */ /* Just use a very simple calculation here. Do not care about overflow, @@ -413,87 +420,71 @@ static __inline__ int led_get_diskio_activity(void) changed = (pgstat.pgpgin != last_pgpgin) || (pgstat.pgpgout != last_pgpgout); last_pgpgin = pgstat.pgpgin; last_pgpgout = pgstat.pgpgout; - + return (changed ? LED_DISK_IO : 0); } /* - ** led_tasklet_func() + ** led_work_func() ** - ** is scheduled at every timer interrupt from time.c and - ** updates the chassis LCD/LED + ** manages when and which chassis LCD/LED gets updated TODO: - display load average (older machines like 715/64 have 4 "free" LED's for that) - optimizations */ -#define HEARTBEAT_LEN (HZ*6/100) -#define HEARTBEAT_2ND_RANGE_START (HZ*22/100) +#define HEARTBEAT_LEN (HZ*10/100) +#define HEARTBEAT_2ND_RANGE_START (HZ*28/100) #define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN) -#define NORMALIZED_COUNT(count) (count/(HZ/100)) +#define LED_UPDATE_INTERVAL (1 + (HZ*19/1000)) -static void led_tasklet_func(unsigned long unused) +static void led_work_func (void *unused) { - static unsigned char lastleds; - unsigned char currentleds; /* stores current value of the LEDs */ - static unsigned long count; /* static incremented value, not wrapped */ + static unsigned long last_jiffies; static unsigned long count_HZ; /* counter in range 0..HZ */ + unsigned char currentleds = 0; /* stores current value of the LEDs */ /* exit if not initialized */ if (!led_func_ptr) return; - /* increment the local counters */ - ++count; - if (++count_HZ == HZ) + /* increment the heartbeat timekeeper */ + count_HZ += jiffies - last_jiffies; + last_jiffies = jiffies; + if (count_HZ >= HZ) count_HZ = 0; - currentleds = lastleds; - - if (led_heartbeat) + if (likely(led_heartbeat)) { - /* flash heartbeat-LED like a real heart (2 x short then a long delay) */ - if (count_HZ=HEARTBEAT_2ND_RANGE_START && count_HZ= HEARTBEAT_2ND_RANGE_START && + count_HZ < HEARTBEAT_2ND_RANGE_END)) + currentleds |= LED_HEARTBEAT; } - /* look for network activity and flash LEDs respectively */ - if (led_lanrxtx && ((NORMALIZED_COUNT(count)+(8/2)) & 7) == 0) - { - currentleds &= ~(LED_LAN_RCV | LED_LAN_TX); - currentleds |= led_get_net_activity(); - } - - /* avoid to calculate diskio-stats at same irq as netio-stats */ - if (led_diskio && (NORMALIZED_COUNT(count) & 7) == 0) - { - currentleds &= ~LED_DISK_IO; - currentleds |= led_get_diskio_activity(); - } + if (likely(led_lanrxtx)) currentleds |= led_get_net_activity(); + if (likely(led_diskio)) currentleds |= led_get_diskio_activity(); /* blink all LEDs twice a second if we got an Oops (HPMC) */ - if (oops_in_progress) { + if (unlikely(oops_in_progress)) currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff; + + if (currentleds != lastleds) + { + led_func_ptr(currentleds); /* Update the LCD/LEDs */ + lastleds = currentleds; } - - /* update the LCD/LEDs */ - if (currentleds != lastleds) { - led_func_ptr(currentleds); - lastleds = currentleds; - } + + queue_delayed_work(led_wq, &led_task, LED_UPDATE_INTERVAL); } -/* main led tasklet struct (scheduled from time.c) */ -DECLARE_TASKLET_DISABLED(led_tasklet, led_tasklet_func, 0); - - /* ** led_halt() ** @@ -522,9 +513,13 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) default: return NOTIFY_DONE; } - /* completely stop the LED/LCD tasklet */ - tasklet_disable(&led_tasklet); - + /* Cancel the work item and delete the queue */ + if (led_wq) { + cancel_rearming_delayed_workqueue(led_wq, &led_task); + destroy_workqueue(led_wq); + led_wq = NULL; + } + if (lcd_info.model == DISPLAY_MODEL_LCD) lcd_print(txt); else @@ -559,7 +554,6 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d printk(KERN_INFO "LCD display at %lx,%lx registered\n", LCD_CMD_REG , LCD_DATA_REG); led_func_ptr = led_LCD_driver; - lcd_print( lcd_text_default ); led_type = LED_HASLCD; break; @@ -589,9 +583,11 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d initialized++; register_reboot_notifier(&led_notifier); - /* start the led tasklet for the first time */ - tasklet_enable(&led_tasklet); - + /* Ensure the work is queued */ + if (led_wq) { + queue_work(led_wq, &led_task); + } + return 0; } @@ -626,8 +622,8 @@ void __init register_led_regions(void) ** lcd_print() ** ** Displays the given string on the LCD-Display of newer machines. - ** lcd_print() disables the timer-based led tasklet during its - ** execution and enables it afterwards again. + ** lcd_print() disables/enables the timer-based led work queue to + ** avoid a race condition while writing the CMD/DATA register pair. ** */ int lcd_print( char *str ) @@ -637,12 +633,13 @@ int lcd_print( char *str ) if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD) return 0; - /* temporarily disable the led tasklet */ - tasklet_disable(&led_tasklet); + /* temporarily disable the led work task */ + if (led_wq) + cancel_rearming_delayed_workqueue(led_wq, &led_task); /* copy display string to buffer for procfs */ strlcpy(lcd_text, str, sizeof(lcd_text)); - + /* Set LCD Cursor to 1st character */ gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG); udelay(lcd_info.min_cmd_delay); @@ -656,8 +653,10 @@ int lcd_print( char *str ) udelay(lcd_info.min_cmd_delay); } - /* re-enable the led tasklet */ - tasklet_enable(&led_tasklet); + /* re-queue the work */ + if (led_wq) { + queue_work(led_wq, &led_task); + } return lcd_info.lcd_width; } diff --git a/include/asm-parisc/led.h b/include/asm-parisc/led.h index 1ac8ab6c580d..efadfd543ec6 100644 --- a/include/asm-parisc/led.h +++ b/include/asm-parisc/led.h @@ -23,9 +23,6 @@ #define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */ -/* led tasklet struct */ -extern struct tasklet_struct led_tasklet; - /* register_led_driver() */ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg); From 413059f28e9949d9ad2d04d1070c63169798176e Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:46:48 -0400 Subject: [PATCH 0390/1940] [PARISC] Replace uses of __LP64__ with CONFIG_64BIT 2.6.12-rc4-pa3 s/__LP64__/CONFIG_64BIT/ and fixup config.h usage Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 98 +++++++++++++++--------------- arch/parisc/kernel/head.S | 26 ++++---- arch/parisc/kernel/pacache.S | 30 ++++----- arch/parisc/kernel/real2.S | 16 ++--- arch/parisc/kernel/smp.c | 2 +- arch/parisc/kernel/syscall.S | 37 ++++++----- arch/parisc/kernel/syscall_table.S | 4 +- 7 files changed, 108 insertions(+), 105 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ec04e0ad77fa..0ca49710d95e 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -37,7 +37,7 @@ #include #include -#ifdef __LP64__ +#ifdef CONFIG_64BIT #define CMPIB cmpib,* #define CMPB cmpb,* #define COND(x) *x @@ -217,7 +217,7 @@ va = r8 /* virtual address for which the trap occured */ spc = r24 /* space for which the trap occured */ -#ifndef __LP64__ +#ifndef CONFIG_64BIT /* * itlb miss interruption handler (parisc 1.1 - 32 bit) @@ -239,7 +239,7 @@ .macro itlb_20 code mfctl %pcsq, spc -#ifdef __LP64__ +#ifdef CONFIG_64BIT b itlb_miss_20w #else b itlb_miss_20 @@ -249,7 +249,7 @@ .align 32 .endm -#ifndef __LP64__ +#ifndef CONFIG_64BIT /* * naitlb miss interruption handler (parisc 1.1 - 32 bit) * @@ -286,7 +286,7 @@ .macro naitlb_20 code mfctl %isr,spc -#ifdef __LP64__ +#ifdef CONFIG_64BIT b itlb_miss_20w #else b itlb_miss_20 @@ -299,7 +299,7 @@ .align 32 .endm -#ifndef __LP64__ +#ifndef CONFIG_64BIT /* * dtlb miss interruption handler (parisc 1.1 - 32 bit) */ @@ -321,7 +321,7 @@ .macro dtlb_20 code mfctl %isr, spc -#ifdef __LP64__ +#ifdef CONFIG_64BIT b dtlb_miss_20w #else b dtlb_miss_20 @@ -331,7 +331,7 @@ .align 32 .endm -#ifndef __LP64__ +#ifndef CONFIG_64BIT /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */ .macro nadtlb_11 code @@ -349,7 +349,7 @@ .macro nadtlb_20 code mfctl %isr,spc -#ifdef __LP64__ +#ifdef CONFIG_64BIT b nadtlb_miss_20w #else b nadtlb_miss_20 @@ -359,7 +359,7 @@ .align 32 .endm -#ifndef __LP64__ +#ifndef CONFIG_64BIT /* * dirty bit trap interruption handler (parisc 1.1 - 32 bit) */ @@ -381,7 +381,7 @@ .macro dbit_20 code mfctl %isr,spc -#ifdef __LP64__ +#ifdef CONFIG_64BIT b dbit_trap_20w #else b dbit_trap_20 @@ -394,7 +394,7 @@ /* The following are simple 32 vs 64 bit instruction * abstractions for the macros */ .macro EXTR reg1,start,length,reg2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u \reg1,32+\start,\length,\reg2 #else extrw,u \reg1,\start,\length,\reg2 @@ -402,7 +402,7 @@ .endm .macro DEP reg1,start,length,reg2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depd \reg1,32+\start,\length,\reg2 #else depw \reg1,\start,\length,\reg2 @@ -410,7 +410,7 @@ .endm .macro DEPI val,start,length,reg -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi \val,32+\start,\length,\reg #else depwi \val,\start,\length,\reg @@ -421,7 +421,7 @@ * fault. We have to extract this and place it in the va, * zeroing the corresponding bits in the space register */ .macro space_adjust spc,va,tmp -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u \spc,63,SPACEID_SHIFT,\tmp depd %r0,63,SPACEID_SHIFT,\spc depd \tmp,31,SPACEID_SHIFT,\va @@ -479,7 +479,7 @@ bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ copy \pmd,%r9 -#ifdef __LP64__ +#ifdef CONFIG_64BIT shld %r9,PxD_VALUE_SHIFT,\pmd #else shlw %r9,PxD_VALUE_SHIFT,\pmd @@ -610,7 +610,7 @@ .macro do_alias spc,tmp,tmp1,va,pte,prot,fault cmpib,COND(<>),n 0,\spc,\fault ldil L%(TMPALIAS_MAP_START),\tmp -#if defined(__LP64__) && (TMPALIAS_MAP_START >= 0x80000000) +#if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) /* on LP64, ldi will sign extend into the upper 32 bits, * which is behaviour we don't want */ depdi 0,31,32,\tmp @@ -624,7 +624,7 @@ * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u,*= \va,41,1,%r0 #else extrw,u,= \va,9,1,%r0 @@ -691,7 +691,7 @@ fault_vector_20: def 30 def 31 -#ifndef __LP64__ +#ifndef CONFIG_64BIT .export fault_vector_11 @@ -764,7 +764,7 @@ __kernel_thread: copy %r30, %r1 ldo PT_SZ_ALGN(%r30),%r30 -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Yo, function pointers in wide mode are little structs... -PB */ ldd 24(%r26), %r2 STREG %r2, PT_GR27(%r1) /* Store childs %dp */ @@ -780,7 +780,7 @@ __kernel_thread: or %r26, %r24, %r26 /* will have kernel mappings. */ ldi 1, %r25 /* stack_start, signals kernel thread */ stw %r0, -52(%r30) /* user_tid */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif BL do_fork, %r2 @@ -809,7 +809,7 @@ ret_from_kernel_thread: LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 LDREG TASK_PT_GR25(%r1), %r26 -#ifdef __LP64__ +#ifdef CONFIG_64BIT LDREG TASK_PT_GR27(%r1), %r27 LDREG TASK_PT_GR22(%r1), %r22 #endif @@ -817,7 +817,7 @@ ret_from_kernel_thread: ble 0(%sr7, %r1) copy %r31, %r2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ loadgp /* Thread could have been in a module */ #endif @@ -838,7 +838,7 @@ __execve: STREG %r26, PT_GR26(%r16) STREG %r25, PT_GR25(%r16) STREG %r24, PT_GR24(%r16) -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif BL sys_execve, %r2 @@ -916,7 +916,7 @@ syscall_exit_rfi: STREG %r19,PT_IAOQ1(%r16) LDREG PT_PSW(%r16),%r19 load32 USER_PSW_MASK,%r1 -#ifdef __LP64__ +#ifdef CONFIG_64BIT load32 USER_PSW_HI_MASK,%r20 depd %r20,31,32,%r1 #endif @@ -960,7 +960,7 @@ intr_return: /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount ** irq_stat[] is defined using ____cacheline_aligned. */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT shld %r1, 6, %r20 #else shlw %r1, 5, %r20 @@ -1018,7 +1018,7 @@ intr_restore: .import do_softirq,code intr_do_softirq: BL do_softirq,%r2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #else nop @@ -1036,7 +1036,7 @@ intr_do_resched: CMPIB= 0,%r20,intr_restore /* backward */ nop -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1069,7 +1069,7 @@ intr_do_signal: copy %r0, %r24 /* unsigned long in_syscall */ copy %r16, %r25 /* struct pt_regs *regs */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1093,7 +1093,7 @@ intr_extint: mfctl %cr31,%r1 copy %r30,%r17 /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/ -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi 0,63,15,%r17 #else depi 0,31,15,%r17 @@ -1120,7 +1120,7 @@ intr_extint: ldil L%intr_return, %r2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1164,7 +1164,7 @@ intr_save: mfctl %cr21, %r17 /* ior */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* * If the interrupted code was running with W bit off (32 bit), * clear the b bits (bits 0 & 1) in the ior. @@ -1199,7 +1199,7 @@ skip_save_ior: loadgp copy %r29, %r25 /* arg1 is pt_regs */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1237,7 +1237,7 @@ skip_save_ior: spc = r24 /* space for which the trap occured */ ptp = r25 /* page directory/page table pointer */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT dtlb_miss_20w: space_adjust spc,va,t0 @@ -1528,7 +1528,7 @@ nadtlb_probe_check: nop -#ifdef __LP64__ +#ifdef CONFIG_64BIT itlb_miss_20w: /* @@ -1595,7 +1595,7 @@ itlb_miss_20: #endif -#ifdef __LP64__ +#ifdef CONFIG_64BIT dbit_trap_20w: space_adjust spc,va,t0 @@ -1804,7 +1804,7 @@ sys_fork_wrapper: STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1854,7 +1854,7 @@ sys_clone_wrapper: STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1876,7 +1876,7 @@ sys_vfork_wrapper: STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif @@ -1904,7 +1904,7 @@ sys_vfork_wrapper: STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif BL \execve,%r2 @@ -1930,7 +1930,7 @@ error_\execve: sys_execve_wrapper: execve_wrapper sys_execve -#ifdef __LP64__ +#ifdef CONFIG_64BIT .export sys32_execve_wrapper .import sys32_execve @@ -1944,7 +1944,7 @@ sys_rt_sigreturn_wrapper: ldo TASK_REGS(%r26),%r26 /* get pt regs */ /* Don't save regs, we are going to restore them from sigcontext. */ STREG %r2, -RP_OFFSET(%r30) -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo FRAME_SIZE(%r30), %r30 BL sys_rt_sigreturn,%r2 ldo -16(%r30),%r29 /* Reference param save area */ @@ -1975,7 +1975,7 @@ sys_sigaltstack_wrapper: ldo TASK_REGS(%r1),%r24 /* get pt regs */ LDREG TASK_PT_GR30(%r24),%r24 STREG %r2, -RP_OFFSET(%r30) -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo FRAME_SIZE(%r30), %r30 b,l do_sigaltstack,%r2 ldo -16(%r30),%r29 /* Reference param save area */ @@ -1989,7 +1989,7 @@ sys_sigaltstack_wrapper: bv %r0(%r2) nop -#ifdef __LP64__ +#ifdef CONFIG_64BIT .export sys32_sigaltstack_wrapper sys32_sigaltstack_wrapper: /* Get the user stack pointer */ @@ -2013,7 +2013,7 @@ sys_rt_sigsuspend_wrapper: reg_save %r24 STREG %r2, -RP_OFFSET(%r30) -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo FRAME_SIZE(%r30), %r30 b,l sys_rt_sigsuspend,%r2 ldo -16(%r30),%r29 /* Reference param save area */ @@ -2086,7 +2086,7 @@ syscall_check_bh: ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */ /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT shld %r26, 6, %r20 #else shlw %r26, 5, %r20 @@ -2151,7 +2151,7 @@ syscall_restore: depi 3,31,2,%r31 /* ensure return to user mode. */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* decide whether to reset the wide mode bit * * For a syscall, the W bit is stored in the lowest bit @@ -2247,7 +2247,7 @@ syscall_do_softirq: .import schedule,code syscall_do_resched: BL schedule,%r2 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #else nop @@ -2267,7 +2267,7 @@ syscall_do_signal: ldi 1, %r24 /* unsigned long in_syscall */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif BL do_signal,%r2 diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 2b8738576ec2..0b47afc20690 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -12,7 +12,7 @@ * Initial Version 04-23-1999 by Helge Deller */ -#include /* for CONFIG_SMP */ +#include /* for CONFIG_SMP */ #include #include @@ -36,10 +36,10 @@ boot_args: .align 4 .import init_thread_union,data .import fault_vector_20,code /* IVA parisc 2.0 32 bit */ -#ifndef __LP64__ +#ifndef CONFIG_64BIT .import fault_vector_11,code /* IVA parisc 1.1 32 bit */ .import $global$ /* forward declaration */ -#endif /*!LP64*/ +#endif /*!CONFIG_64BIT*/ .export stext .export _stext,data /* Kernel want it this way! */ _stext: @@ -76,7 +76,7 @@ $bss_loop: mtctl %r4,%cr24 /* Initialize kernel root pointer */ mtctl %r4,%cr25 /* Initialize user root pointer */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Set pmd in pgd */ load32 PA(pmd0),%r5 shrd %r5,PxD_VALUE_SHIFT,%r3 @@ -99,7 +99,7 @@ $bss_loop: stw %r3,0(%r4) ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3 addib,> -1,%r1,1b -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo ASM_PMD_ENTRY_SIZE(%r4),%r4 #else ldo ASM_PGD_ENTRY_SIZE(%r4),%r4 @@ -170,7 +170,7 @@ common_stext: stw %r0,0x28(%r0) /* MEM_RENDEZ_HI */ #endif /*CONFIG_SMP*/ -#ifdef __LP64__ +#ifdef CONFIG_64BIT tophys_r1 %sp /* Save the rfi target address */ @@ -233,7 +233,7 @@ stext_pdc_ret: * following short sequence of instructions can determine this * (without being illegal on a PA1.1 machine). */ -#ifndef __LP64__ +#ifndef CONFIG_64BIT ldi 32,%r10 mtctl %r10,%cr11 .level 2.0 @@ -246,7 +246,7 @@ stext_pdc_ret: $is_pa20: .level LEVEL /* restore 1.1 || 2.0w */ -#endif /*!LP64*/ +#endif /*!CONFIG_64BIT*/ load32 PA(fault_vector_20),%r10 $install_iva: @@ -284,7 +284,7 @@ aligned_rfi: .import smp_init_current_idle_task,data .import smp_callin,code -#ifndef __LP64__ +#ifndef CONFIG_64BIT smp_callin_rtn: .proc .callinfo @@ -292,7 +292,7 @@ smp_callin_rtn: nop nop .procend -#endif /*!LP64*/ +#endif /*!CONFIG_64BIT*/ /*************************************************************************** * smp_slave_stext is executed by all non-monarch Processors when the Monarch @@ -327,7 +327,7 @@ smp_slave_stext: mtctl %r4,%cr24 /* Initialize kernel root pointer */ mtctl %r4,%cr25 /* Initialize user root pointer */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Setup PDCE_PROC entry */ copy %arg0,%r3 #else @@ -344,7 +344,7 @@ smp_slave_stext: .procend #endif /* CONFIG_SMP */ -#ifndef __LP64__ +#ifndef CONFIG_64BIT .data .align 4 @@ -354,4 +354,4 @@ smp_slave_stext: .size $global$,4 $global$: .word 0 -#endif /*!LP64*/ +#endif /*!CONFIG_64BIT*/ diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 71ade44c4618..4a7d9c8903f4 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -26,7 +26,7 @@ * can be used. */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT #define ADDIB addib,* #define CMPB cmpb,* #define ANDCM andcm,* @@ -40,6 +40,8 @@ .level 2.0 #endif +#include + #include #include #include @@ -294,7 +296,7 @@ copy_user_page_asm: .callinfo NO_CALLS .entry -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* PA8x00 CPUs can consume 2 loads or 1 store per cycle. * Unroll the loop by hand and arrange insn appropriately. * GCC probably can do this just as well. @@ -454,7 +456,7 @@ copy_user_page_asm: sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */ ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */ extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */ depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */ @@ -541,7 +543,7 @@ __clear_user_page_asm: tophys_r1 %r26 ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef __LP64__ +#ifdef CONFIG_64BIT #if (TMPALIAS_MAP_START >= 0x80000000) depdi 0, 31,32, %r28 /* clear any sign extension */ #endif @@ -558,7 +560,7 @@ __clear_user_page_asm: pdtlb 0(%r28) -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldi 32, %r1 /* PAGE_SIZE/128 == 32 */ /* PREFETCH (Write) has not (yet) been proven to help here */ @@ -583,7 +585,7 @@ __clear_user_page_asm: ADDIB> -1, %r1, 1b ldo 128(%r28), %r28 -#else /* ! __LP64 */ +#else /* ! CONFIG_64BIT */ ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ @@ -606,7 +608,7 @@ __clear_user_page_asm: stw %r0, 60(%r28) ADDIB> -1, %r1, 1b ldo 64(%r28), %r28 -#endif /* __LP64 */ +#endif /* CONFIG_64BIT */ bv %r0(%r2) nop @@ -624,7 +626,7 @@ flush_kernel_dcache_page: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 @@ -668,7 +670,7 @@ flush_user_dcache_page: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1,63-PAGE_SHIFT,1, %r25 #else depwi,z 1,31-PAGE_SHIFT,1, %r25 @@ -712,7 +714,7 @@ flush_user_icache_page: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 @@ -757,7 +759,7 @@ purge_kernel_dcache_page: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 @@ -805,7 +807,7 @@ flush_alias_page: tophys_r1 %r26 ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ @@ -822,7 +824,7 @@ flush_alias_page: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r29 #else depwi,z 1, 31-PAGE_SHIFT,1, %r29 @@ -933,7 +935,7 @@ flush_kernel_icache_page: ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 2310fc1b06a9..085bff7c569d 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -7,6 +7,8 @@ * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com) * */ +#include + #include #include @@ -20,7 +22,7 @@ real32_stack: real64_stack: .block 8192 -#ifdef __LP64__ +#ifdef CONFIG_64BIT # define REG_SZ 8 #else # define REG_SZ 4 @@ -50,7 +52,7 @@ save_cr_end: real32_call_asm: STREG %rp, -RP_OFFSET(%sp) /* save RP */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT callee_save ldo 2*REG_SZ(%sp), %sp /* room for a couple more saves */ STREG %r27, -1*REG_SZ(%sp) @@ -77,7 +79,7 @@ real32_call_asm: b,l save_control_regs,%r2 /* modifies r1, r2, r28 */ nop -#ifdef __LP64__ +#ifdef CONFIG_64BIT rsm PSW_SM_W, %r0 /* go narrow */ #endif @@ -85,7 +87,7 @@ real32_call_asm: bv 0(%r31) nop ric_ret: -#ifdef __LP64__ +#ifdef CONFIG_64BIT ssm PSW_SM_W, %r0 /* go wide */ #endif /* restore CRs before going virtual in case we page fault */ @@ -97,7 +99,7 @@ ric_ret: tovirt_r1 %sp LDREG -REG_SZ(%sp), %sp /* restore SP */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT LDREG -1*REG_SZ(%sp), %r27 LDREG -2*REG_SZ(%sp), %r29 ldo -2*REG_SZ(%sp), %sp @@ -212,7 +214,7 @@ rfi_r2v_1: bv 0(%r2) nop -#ifdef __LP64__ +#ifdef CONFIG_64BIT /************************ 64-bit real-mode calls ***********************/ /* This is only usable in wide kernels right now and will probably stay so */ @@ -290,7 +292,7 @@ pc_in_user_space: ** comparing function pointers. */ __canonicalize_funcptr_for_compare: -#ifdef __LP64__ +#ifdef CONFIG_64BIT bve (%r2) #else bv %r0(%r2) diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index bcc7e83f5142..5db3be4e2704 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -18,7 +18,7 @@ */ #undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */ -#include +#include #include #include diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 8c7a7185cd3b..b29b76b42bb7 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -6,6 +6,7 @@ * thanks to Philipp Rumpf, Mike Shaver and various others * sorry about the wall, puffin.. */ +#include /* for CONFIG_SMP */ #include #include @@ -22,15 +23,13 @@ */ #define KILL_INSN break 0,0 -#include /* for CONFIG_SMP */ - -#ifdef __LP64__ +#ifdef CONFIG_64BIT .level 2.0w #else .level 1.1 #endif -#ifndef __LP64__ +#ifndef CONFIG_64BIT .macro fixup_branch,lbl b \lbl .endm @@ -103,7 +102,7 @@ linux_gateway_entry: mfsp %sr7,%r1 /* save user sr7 */ mtsp %r1,%sr3 /* and store it in sr3 */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* for now we can *always* set the W bit on entry to the syscall * since we don't support wide userland processes. We could * also save the current SM other than in r0 and restore it on @@ -155,7 +154,7 @@ linux_gateway_entry: STREG %r19, TASK_PT_GR19(%r1) LDREGM -FRAME_SIZE(%r30), %r2 /* get users sp back */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT extrd,u %r2,63,1,%r19 /* W hidden in bottom bit */ #if 0 xor %r19,%r2,%r2 /* clear bottom bit */ @@ -186,7 +185,7 @@ linux_gateway_entry: loadgp -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ copy %r19,%r2 /* W bit back to r2 */ #else @@ -205,7 +204,7 @@ linux_gateway_entry: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldil L%sys_call_table, %r1 or,= %r2,%r2,%r2 addil L%(sys_call_table64-sys_call_table), %r1 @@ -321,7 +320,7 @@ tracesys_next: LDREG TASK_PT_GR25(%r1), %r25 LDREG TASK_PT_GR24(%r1), %r24 LDREG TASK_PT_GR23(%r1), %r23 -#ifdef __LP64__ +#ifdef CONFIG_64BIT LDREG TASK_PT_GR22(%r1), %r22 LDREG TASK_PT_GR21(%r1), %r21 ldo -16(%r30),%r29 /* Reference param save area */ @@ -350,7 +349,7 @@ tracesys_next: tracesys_exit: ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ LDREG TI_TASK(%r1), %r1 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif bl syscall_trace, %r2 @@ -371,7 +370,7 @@ tracesys_exit: tracesys_sigexit: ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ LDREG 0(%r1), %r1 -#ifdef __LP64__ +#ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif bl syscall_trace, %r2 @@ -404,7 +403,7 @@ lws_start: gate .+8, %r0 depi 3, 31, 2, %r31 /* Ensure we return to userspace */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* FIXME: If we are a 64-bit kernel just * turn this on unconditionally. */ @@ -440,7 +439,7 @@ lws_exit_nosys: /* Fall through: Return to userspace */ lws_exit: -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* decide whether to reset the wide mode bit * * For a syscall, the W bit is stored in the lowest bit @@ -486,7 +485,7 @@ lws_exit: /* ELF64 Process entry path */ lws_compare_and_swap64: -#ifdef __LP64__ +#ifdef CONFIG_64BIT b,n lws_compare_and_swap #else /* If we are not a 64-bit kernel, then we don't @@ -497,7 +496,7 @@ lws_compare_and_swap64: /* ELF32 Process entry path */ lws_compare_and_swap32: -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Clip all the input registers */ depdi 0, 31, 32, %r26 depdi 0, 31, 32, %r25 @@ -608,7 +607,7 @@ cas_action: the other for the store. Either return -EFAULT. Each of the entries must be relocated. */ .section __ex_table,"aw" -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Pad the address calculation */ .word 0,(2b - linux_gateway_page) .word 0,(3b - linux_gateway_page) @@ -619,7 +618,7 @@ cas_action: .previous .section __ex_table,"aw" -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* Pad the address calculation */ .word 0,(1b - linux_gateway_page) .word 0,(3b - linux_gateway_page) @@ -638,7 +637,7 @@ end_linux_gateway_page: /* Relocate symbols assuming linux_gateway_page is mapped to virtual address 0x0 */ -#ifdef __LP64__ +#ifdef CONFIG_64BIT /* FIXME: The code will always be on the gateay page and thus it will be on the first 4k, the assembler seems to think that the final @@ -666,7 +665,7 @@ lws_table: sys_call_table: #include "syscall_table.S" -#ifdef __LP64__ +#ifdef CONFIG_64BIT .align 4096 .export sys_call_table64 .Lsys_call_table64: diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 065ab809659d..32cbc0489324 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -35,7 +35,7 @@ #undef ENTRY_UHOH #undef ENTRY_COMP #undef ENTRY_OURS -#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT) +#if defined(CONFIG_64BIT) && !defined(SYSCALL_TABLE_64BIT) /* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific * implementation is required on wide palinux. Use ENTRY_COMP where @@ -46,7 +46,7 @@ #define ENTRY_UHOH(_name_) .dword sys32_##unimplemented #define ENTRY_OURS(_name_) .dword parisc_##_name_ #define ENTRY_COMP(_name_) .dword compat_sys_##_name_ -#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT) +#elif defined(CONFIG_64BIT) && defined(SYSCALL_TABLE_64BIT) #define ENTRY_SAME(_name_) .dword sys_##_name_ #define ENTRY_DIFF(_name_) .dword sys_##_name_ #define ENTRY_UHOH(_name_) .dword sys_##_name_ From 3aa0862ce7c120e035bc2aa25997fd000d964d6e Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:47:04 -0400 Subject: [PATCH 0391/1940] [PARISC] Minor iosapic.c cleanup minor cleanup: qualify constant with "UL" Acked-by: "Hmamouche, Youssef" Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- drivers/parisc/iosapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 7a57c1b8373f..a39fbfef789a 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -244,7 +244,7 @@ static struct irt_entry *iosapic_alloc_irt(int num_entries) * 4-byte alignment on 32-bit kernels */ a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL); - a = (a + 7) & ~7; + a = (a + 7UL) & ~7UL; return (struct irt_entry *)a; } From 91313d60d8ad96fa79a833e55e8c13b56f893614 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:47:40 -0400 Subject: [PATCH 0392/1940] [PARISC] Add sync required after fdc to enforce insn ordering PA20 arch book (page 7-52 and 7-55) indicate a "sync" is required after the FDC "to enforce instruction ordering". And we want to make sure FIC is executed after FDC has retired. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/signal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 0224651fd8f1..6c905c128c2a 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -636,6 +636,7 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) /* Stack is 64-byte aligned, and we only * need to flush 1 cache line */ asm("fdc 0(%%sr3, %0)\n" + "sync\n" "fic 0(%%sr3, %0)\n" "sync\n" : : "r"(regs->gr[30])); From 7efe1611b2db9025ffc52a686897ab91820caeb4 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 22:48:03 -0400 Subject: [PATCH 0393/1940] [PARISC] Initialize serial spinlocks in superio.c git commit 976ecd12b8144d066a23fe97c6fbfc1ac8470af7 changed our locking characteristics, and put the onus of spin_lock_init on superio.c. Signed-off-by: Kyle McMartin --- drivers/parisc/superio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index e0efed796b92..bab3bcabcb6e 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -11,6 +11,7 @@ * (C) Copyright 2000 Alex deVries * (C) Copyright 2001 John Marvin * (C) Copyright 2003 Grant Grundler + * (C) Copyright 2005 Kyle McMartin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -405,6 +406,7 @@ static void __devinit superio_serial_init(void) serial[0].iobase = sio_dev.sp1_base; serial[0].irq = SP1_IRQ; + spin_lock_init(&serial[0].lock); retval = early_serial_setup(&serial[0]); if (retval < 0) { @@ -414,6 +416,7 @@ static void __devinit superio_serial_init(void) serial[1].iobase = sio_dev.sp2_base; serial[1].irq = SP2_IRQ; + spin_lock_init(&serial[1].lock); retval = early_serial_setup(&serial[1]); if (retval < 0) From fa681a1800a58234afe4d876c1752c0751826d22 Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:48:34 -0400 Subject: [PATCH 0394/1940] [PARISC] Disable use of fpregs in pa_memcpy Disable use of fpregs in pa_memcpy, and turn on the -mdisable-fpregs flag. Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- arch/parisc/Makefile | 2 +- arch/parisc/lib/memcpy.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 3b339b1cce13..e3549f480fa5 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -43,7 +43,7 @@ cflags-y += -mno-space-regs -mfast-indirect-calls # Currently we save and restore fpregs on all kernel entry/interruption paths. # If that gets optimized, we might need to disable the use of fpregs in the # kernel. -#cflags-y += -mdisable-fpregs +cflags-y += -mdisable-fpregs # Without this, "ld -r" results in .text sections that are too big # (> 0x40000) for branches to reach stubs. diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index feb1b9f42c2b..b7098035321f 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -339,6 +339,7 @@ unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) pds = (double *)pcs; pdd = (double *)pcd; +#if 0 /* Copy 8 doubles at a time */ while (len >= 8*sizeof(double)) { register double r1, r2, r3, r4, r5, r6, r7, r8; @@ -366,6 +367,7 @@ unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) fstdma(d_space, r8, pdd, pmc_store_exc); len -= 8*sizeof(double); } +#endif pws = (unsigned int *)pds; pwd = (unsigned int *)pdd; From 74d13f84a9905e02a025d952ced6abb2e064f1c1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:49:05 -0400 Subject: [PATCH 0395/1940] [PARISC] Fix compile warning in pci.h Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- include/asm-parisc/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index d0b761f690b5..fa39d07d49e9 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -69,7 +69,7 @@ struct pci_hba_data { #define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS) #define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1)) -#if CONFIG_64BIT +#ifdef CONFIG_64BIT #define PCI_F_EXTEND 0xffffffff00000000UL #define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) From eba917273eb8579dd8ae36f6645518ca5579a2ab Mon Sep 17 00:00:00 2001 From: Thibaut Varene Date: Fri, 21 Oct 2005 22:49:25 -0400 Subject: [PATCH 0396/1940] [PARISC] Add printing of fpregs state to stack dump We're using fp regs now in the kernel, so we want to print them on stack dump Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/kernel/traps.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index d2e5b229a2f4..15914f0235a0 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -74,7 +74,10 @@ void show_regs(struct pt_regs *regs) char *level; unsigned long cr30; unsigned long cr31; - + /* carlos says that gcc understands better memory in a struct, + * and it makes our life easier with fpregs -- T-Bone */ + struct { u32 sw[2]; } s; + level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; printk("%s\n", level); /* don't want to have that pretty register dump messed up */ @@ -103,11 +106,33 @@ void show_regs(struct pt_regs *regs) printk("%s\n", buf); } -#if RIDICULOUSLY_VERBOSE - for (i = 0; i < 32; i += 2) - printk("%sFR%02d : %016lx FR%2d : %016lx", level, i, - regs->fr[i], i+1, regs->fr[i+1]); -#endif + /* FR are 64bit everywhere. Need to use asm to get the content + * of fpsr/fper1, and we assume that we won't have a FP Identify + * in our way, otherwise we're screwed. + * The fldd is used to restore the T-bit if there was one, as the + * store clears it anyway. + * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ + __asm__ ( + "fstd %%fr0,0(%1) \n\t" + "fldd 0(%1),%%fr0 \n\t" + : "=m" (s) : "r" (&s) : "%r0" + ); + + printk("%s\n", level); + printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); + printbinary(buf, s.sw[0], 32); + printk("%sFPSR: %s\n", level, buf); + printk("%sFPER1: %08x\n", level, s.sw[1]); + + /* here we'll print fr0 again, tho it'll be meaningless */ + for (i = 0; i < 32; i += 4) { + int j; + p = buf; + p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3); + for (j = 0; j < 4; j++) + p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]); + printk("%s\n", buf); + } cr30 = mfctl(30); cr31 = mfctl(31); From 40c72f20e89300dfaea28300ee17aa56d230d63f Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:49:47 -0400 Subject: [PATCH 0397/1940] [PARISC] Prevent signal loops if we have a problem setting up a frame 2.6.13-rc6-pa2 use force_sigsegv() if we have a problem setting up a frame. This is required to prevent SIGSEGV loops. Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- arch/parisc/kernel/signal.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 6c905c128c2a..befdfe700616 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -490,15 +490,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, give_sigsegv: DBG(1,"setup_rt_frame: sending SIGSEGV\n"); - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - si.si_signo = SIGSEGV; - si.si_errno = 0; - si.si_code = SI_KERNEL; - si.si_pid = current->pid; - si.si_uid = current->uid; - si.si_addr = frame; - force_sig_info(SIGSEGV, &si, current); + force_sigsegv(sig, current); return 0; } From 7c92e972da0dd5b6a9ddf01030aab7dec9912b1f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:50:06 -0400 Subject: [PATCH 0398/1940] [PARISC] Update pdc console from parisc tree Get rid of some unnecessary includes Remove a layer of macro indirection around pdc_console_device Delete pdc_console_die() as it is unused Avoid double-printing on panic by clearing CON_PRINTBUFFER rather than setting con_start to be log_end Make con_start and log_end static again Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pdc_cons.c | 46 ++++++++--------------------------- 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 01f676d1673b..215d78c87bc5 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -41,7 +41,7 @@ /* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */ -#undef EARLY_BOOTUP_DEBUG +#define EARLY_BOOTUP_DEBUG #include @@ -49,14 +49,8 @@ #include #include #include -#include -#include -#include #include #include -#include -#include -#include #include /* for iodc_call() proto and friends */ @@ -96,7 +90,6 @@ static int pdc_console_setup(struct console *co, char *options) } #if defined(CONFIG_PDC_CONSOLE) -#define PDC_CONSOLE_DEVICE pdc_console_device static struct tty_driver * pdc_console_device (struct console *c, int *index) { extern struct tty_driver console_driver; @@ -104,22 +97,19 @@ static struct tty_driver * pdc_console_device (struct console *c, int *index) return &console_driver; } #else -#define PDC_CONSOLE_DEVICE NULL +#define pdc_console_device NULL #endif static struct console pdc_cons = { .name = "ttyB", .write = pdc_console_write, - .device = PDC_CONSOLE_DEVICE, + .device = pdc_console_device, .setup = pdc_console_setup, - .flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED, + .flags = CON_BOOT | CON_PRINTBUFFER | CON_ENABLED, .index = -1, }; static int pdc_console_initialized; -extern unsigned long con_start; /* kernel/printk.c */ -extern unsigned long log_end; /* kernel/printk.c */ - static void pdc_console_init_force(void) { @@ -146,27 +136,11 @@ void __init pdc_console_init(void) } -/* Unregister the pdc console with the printk console layer */ -void pdc_console_die(void) -{ - if (!pdc_console_initialized) - return; - --pdc_console_initialized; - - printk(KERN_INFO "Switching from PDC console\n"); - - /* Don't repeat what we've already printed */ - con_start = log_end; - - unregister_console(&pdc_cons); -} - - /* * Used for emergencies. Currently only used if an HPMC occurs. If an * HPMC occurs, it is possible that the current console may not be - * properly initialed after the PDC IO reset. This routine unregisters all - * of the current consoles, reinitializes the pdc console and + * properly initialised after the PDC IO reset. This routine unregisters + * all of the current consoles, reinitializes the pdc console and * registers it. */ @@ -177,13 +151,13 @@ void pdc_console_restart(void) if (pdc_console_initialized) return; + /* If we've already seen the output, don't bother to print it again */ + if (console_drivers != NULL) + pdc_cons.flags &= ~CON_PRINTBUFFER; + while ((console = console_drivers) != NULL) unregister_console(console_drivers); - /* Don't repeat what we've already printed */ - con_start = log_end; - /* force registering the pdc console */ pdc_console_init_force(); } - From 8054f03f6330f20e9d47e2f6c7b1d01ddf5adeef Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:50:33 -0400 Subject: [PATCH 0399/1940] [PARISC] More informative error message in pcibios_link_hba_resources Generate a more informative message when a resource does not have a parent. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index e6a891a0cad0..88cba49c5301 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -202,7 +202,8 @@ static void pcibios_link_hba_resources( struct resource *hba_res, struct resource *r) { if (!r->parent) { - printk(KERN_EMERG "PCI: Tell willy he's wrong\n"); + printk(KERN_EMERG "PCI: resource not parented! [%lx-%lx]\n", + r->start, r->end); r->parent = hba_res; /* reverse link is harder *sigh* */ From b8db800295fd31f8beb39fd1de63660aa7aef47b Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:50:48 -0400 Subject: [PATCH 0400/1940] [PARISC] Cleanup whitespace and handle proc_mkdir() failures in pci-dma.c 1) cleanup whitespace and handle proc_mkdir() failures. From: Christophe Lucas 2) rename "dino" entry to "pcxl_dma"...also seems like it's in the wrong location. 3) don't dump resource bitmap in /proc/pcxl_dma output 4) fixup compiler warning Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pci-dma.c | 48 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 368cc095c99f..d9b447cb1a0d 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -31,7 +31,7 @@ #include /* get_order */ #include #include - +#include /* for purge_tlb_*() macros */ static struct proc_dir_entry * proc_gsc_root = NULL; static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length); @@ -333,18 +333,28 @@ pcxl_free_range(unsigned long vaddr, size_t size) static int __init pcxl_dma_init(void) { - if (pcxl_dma_start == 0) - return 0; + if (pcxl_dma_start == 0) + return 0; - spin_lock_init(&pcxl_res_lock); - pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3); - pcxl_res_hint = 0; - pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, + spin_lock_init(&pcxl_res_lock); + pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3); + pcxl_res_hint = 0; + pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, get_order(pcxl_res_size)); - memset(pcxl_res_map, 0, pcxl_res_size); - proc_gsc_root = proc_mkdir("gsc", 0); - create_proc_info_entry("dino", 0, proc_gsc_root, pcxl_proc_info); - return 0; + memset(pcxl_res_map, 0, pcxl_res_size); + proc_gsc_root = proc_mkdir("gsc", 0); + if (!proc_gsc_root) + printk(KERN_WARNING + "pcxl_dma_init: Unable to create gsc /proc dir entry\n"); + else { + struct proc_dir_entry* ent; + ent = create_proc_info_entry("pcxl_dma", 0, + proc_gsc_root, pcxl_proc_info); + if (!ent) + printk(KERN_WARNING + "pci-dma.c: Unable to create pcxl_dma /proc entry.\n"); + } + return 0; } __initcall(pcxl_dma_init); @@ -545,16 +555,16 @@ struct hppa_dma_ops pcx_dma_ops = { static int pcxl_proc_info(char *buf, char **start, off_t offset, int len) { +#if 0 u_long i = 0; unsigned long *res_ptr = (u_long *)pcxl_res_map; - unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */ +#endif + unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */ - sprintf(buf, "\nDMA Mapping Area size : %d bytes (%d pages)\n", - PCXL_DMA_MAP_SIZE, - (pcxl_res_size << 3) ); /* 1 bit per page */ + sprintf(buf, "\nDMA Mapping Area size : %d bytes (%ld pages)\n", + PCXL_DMA_MAP_SIZE, total_pages); - sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", - buf, pcxl_res_size, pcxl_res_size << 3); /* 8 bits per byte */ + sprintf(buf, "%sResource bitmap : %d bytes\n", buf, pcxl_res_size); strcat(buf, " total: free: used: % used:\n"); sprintf(buf, "%sblocks %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size, @@ -564,7 +574,8 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len) sprintf(buf, "%spages %8ld %8ld %8ld %8ld%%\n", buf, total_pages, total_pages - pcxl_used_pages, pcxl_used_pages, (pcxl_used_pages * 100 / total_pages)); - + +#if 0 strcat(buf, "\nResource bitmap:"); for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) { @@ -572,6 +583,7 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len) strcat(buf,"\n "); sprintf(buf, "%s %08lx", buf, *res_ptr); } +#endif strcat(buf, "\n"); return strlen(buf); } From c8e8b1937a788ec46ee11d84437311d4cb8be218 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 21 Oct 2005 22:51:23 -0400 Subject: [PATCH 0401/1940] [PARISC] kfree cleanups to ioctl32.c 2.6.12-rc2-pa2 kfree cleanups from Jesper Juhl Signed-off-by: Jesper Juhl Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/ioctl32.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c index 1d3824b670d1..8cad8f004f00 100644 --- a/arch/parisc/kernel/ioctl32.c +++ b/arch/parisc/kernel/ioctl32.c @@ -104,12 +104,9 @@ static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg) } out: - if (kversion.name) - kfree(kversion.name); - if (kversion.date) - kfree(kversion.date); - if (kversion.desc) - kfree(kversion.desc); + kfree(kversion.name); + kfree(kversion.date); + kfree(kversion.desc); return ret; } @@ -166,9 +163,7 @@ static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long a ret = -EFAULT; } - if (karg.unique != NULL) - kfree(karg.unique); - + kfree(karg.unique); return ret; } @@ -265,7 +260,6 @@ static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) } kfree(karg.list); - return ret; } @@ -305,7 +299,6 @@ static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) out: kfree(karg.list); - return ret; } @@ -494,15 +487,10 @@ static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg) } out: - if (karg.send_indices) - kfree(karg.send_indices); - if (karg.send_sizes) - kfree(karg.send_sizes); - if (karg.request_indices) - kfree(karg.request_indices); - if (karg.request_sizes) - kfree(karg.request_sizes); - + kfree(karg.send_indices); + kfree(karg.send_sizes); + kfree(karg.request_indices); + kfree(karg.request_sizes); return ret; } @@ -555,9 +543,7 @@ static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg) ret = -EFAULT; } - if (karg.contexts) - kfree(karg.contexts); - + kfree(karg.contexts); return ret; } From 675ec7a56a77da2dda27180c95ee82ae4879142a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:51:40 -0400 Subject: [PATCH 0402/1940] [PARISC] Document history of PDC_NARROW as it is now obsolete Document history of PDC_NARROW a bit as it will still show up in an older kernel's .config file. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/firmware.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index f244fb200db1..553f8fe03224 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -83,15 +83,15 @@ static unsigned long pdc_result2[32] __attribute__ ((aligned (8))); int parisc_narrow_firmware = 1; #endif -/* on all currently-supported platforms, IODC I/O calls are always - * 32-bit calls, and MEM_PDC calls are always the same width as the OS. - * This means Cxxx boxes can't run wide kernels right now. -PB +/* On most currently-supported platforms, IODC I/O calls are 32-bit calls + * and MEM_PDC calls are always the same width as the OS. + * Some PAT boxes may have 64-bit IODC I/O. * - * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on - * systems with 32-bit MEM_PDC calls. This will allow wide kernels to - * run on Cxxx boxes now. -RB - * - * Note that some PAT boxes may have 64-bit IODC I/O... + * Ryan Bradetich added the now obsolete CONFIG_PDC_NARROW to allow + * 64-bit kernels to run on systems with 32-bit MEM_PDC calls. + * This allowed wide kernels to run on Cxxx boxes. + * We now detect 32-bit-only PDC and dynamically switch to 32-bit mode + * when running a 64-bit kernel on such boxes (e.g. C200 or C360). */ #ifdef __LP64__ From 5beb5f32c56b70f79117e13a1abd54824a78466c Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:52:00 -0400 Subject: [PATCH 0403/1940] [PARISC] Update minimum compiler version and CROSS_COMPILE for parisc64 Prefix changed in debian, include "gnu" in the commandline. Signed-off-by: Carlos O'Donell Ensure the compiler version is new enough (>= 3.3) Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- arch/parisc/Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index e3549f480fa5..9b7e42490dd1 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -20,7 +20,8 @@ NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 ifdef CONFIG_64BIT -CROSS_COMPILE := hppa64-linux- +CROSS_COMPILE := $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \ + echo hppa64-linux-gnu-; else echo hppa64-linux-; fi) UTS_MACHINE := parisc64 CHECKFLAGS += -D__LP64__=1 -m64 else @@ -34,6 +35,14 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align OBJCOPY_FLAGS =-O binary -R .note -R .comment -S +GCC_VERSION := $(call cc-version) +ifneq ($(shell if [ -z $(GCC_VERSION) ] ; then echo "bad"; fi ;),) +$(error Sorry, couldn't find ($(cc-version)).) +endif +ifneq ($(shell if [ $(GCC_VERSION) -lt 0303 ] ; then echo "bad"; fi ;),) +$(error Sorry, your compiler is too old ($(GCC_VERSION)). GCC v3.3 or above is required.) +endif + cflags-y := -pipe # These flags should be implied by an hppa-linux configuration, but they From 8b631342dd9db9ca272e11814e041e4ee3d1a948 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:52:46 -0400 Subject: [PATCH 0404/1940] [PARISC] Update Kconfig for itimer selection 2.6.14-rc2-pa1: enable 100/250/1000HZ itimer selection Signed-off-by: Grant Grundler Mark floppy as broken. Thanks Joel Signed-off-by: Matthew Wilcox make DISCONTIGMEM depend on 64BIT Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 0b07922a2ac6..874a283edb95 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -47,10 +47,10 @@ config PM config ISA_DMA_API bool - default y config ARCH_MAY_HAVE_PC_FDC bool + depends on BROKEN default y source "init/Kconfig" @@ -154,13 +154,14 @@ config HOTPLUG_CPU config ARCH_DISCONTIGMEM_ENABLE bool "Discontiguous memory support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on 64BIT && EXPERIMENTAL help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access) or have huge holes in the physical address space for other reasons. See for more. +source "kernel/Kconfig.hz" source "mm/Kconfig" config PREEMPT From b2450cc1b7ce07d73545ece32db50197d649e230 Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Fri, 21 Oct 2005 22:53:04 -0400 Subject: [PATCH 0405/1940] [PARISC] Implement 5 argument clone. * arch/parisc/kernel/process.c (sys_clone): Use 5 args, and process CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID. (copy_thread): First cut at CLONE_SETTLS. Signed-off-by: Carlos O'Donell Signed-off-by: Kyle McMartin --- arch/parisc/kernel/process.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 46b759385115..7fdca87ef647 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -9,7 +9,7 @@ * Copyright (C) 2000-2003 Paul Bame * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Kennedy - * Copyright (C) 2000 Richard Hirst + * Copyright (C) 2000 Richard Hirst * Copyright (C) 2000 Grant Grundler * Copyright (C) 2001 Alan Modra * Copyright (C) 2001-2002 Ryan Bradetich @@ -245,7 +245,17 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) { - int __user *user_tid = (int __user *)regs->gr[26]; + /* Arugments from userspace are: + r26 = Clone flags. + r25 = Child stack. + r24 = parent_tidptr. + r23 = Is the TLS storage descriptor + r22 = child_tidptr + + However, these last 3 args are only examined + if the proper flags are set. */ + int __user *child_tidptr; + int __user *parent_tidptr; /* usp must be word aligned. This also prevents users from * passing in the value 1 (which is the signal for a special @@ -253,10 +263,20 @@ sys_clone(unsigned long clone_flags, unsigned long usp, usp = ALIGN(usp, 4); /* A zero value for usp means use the current stack */ - if(usp == 0) - usp = regs->gr[30]; + if (usp == 0) + usp = regs->gr[30]; - return do_fork(clone_flags, usp, regs, 0, user_tid, NULL); + if (clone_flags & CLONE_PARENT_SETTID) + parent_tidptr = (int __user *)regs->gr[24]; + else + parent_tidptr = NULL; + + if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) + child_tidptr = (int __user *)regs->gr[22]; + else + child_tidptr = NULL; + + return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); } int @@ -332,6 +352,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, } else { cregs->kpc = (unsigned long) &child_return; } + /* Setup thread TLS area from the 4th parameter in clone */ + if (clone_flags & CLONE_SETTLS) + cregs->cr27 = pregs->gr[23]; + } return 0; From 618febd6784054eea928d712b7e564558a7cefd5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 21 Oct 2005 22:53:26 -0400 Subject: [PATCH 0406/1940] [PARISC] Fix the alloc_slabmgmt panic Fix the alloc_slabmgmt panic Hopefully this should also fix a lot of other intermittent kernel bugs. The problem has been around since 2.6.9-rc2-pa6 when we allowed floating point registers to be used in kernel code. The essence of the problem is that gcc prefers to use floating point for integer divides and multiples. Further, it can rely on the values in the no clobber fp regs being correct across a function call. Unfortunately, our task switch function only saves the integer no clobber registers, not the fp ones, so if gcc makes a function call to any function in the kernel which could sleep, the values it is relying on in any no clobber floating point register may be lost. In the case of alloc_slabmgmt, the value of the page offset is being stored in %fr12 across a call to kmem_getpages(), which sleeps if no pages are available. Thus, the offset can be trashed and the slab code can end up with a completely bogus address leading to corruption. Kudos to Randolph who came up with the program to trip this problem at will and thus allowed it to be tracked and fixed. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 2 ++ include/asm-parisc/assembly.h | 40 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 0ca49710d95e..166df5bab769 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -863,6 +863,7 @@ __execve: _switch_to: STREG %r2, -RP_OFFSET(%r30) + callee_save_float callee_save load32 _switch_to_ret, %r2 @@ -879,6 +880,7 @@ _switch_to: _switch_to_ret: mtctl %r0, %cr0 /* Needed for single stepping */ callee_rest + callee_rest_float LDREG -RP_OFFSET(%r30), %r2 bv %r0(%r2) diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index b24a99e3ef9c..fb8bc7c16e0e 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -21,6 +21,7 @@ #ifndef _PARISC_ASSEMBLY_H #define _PARISC_ASSEMBLY_H +#define CALLEE_FLOAT_FRAME_SIZE 80 #ifdef __LP64__ #define LDREG ldd #define STREG std @@ -30,7 +31,7 @@ #define SHRREG shrd #define RP_OFFSET 16 #define FRAME_SIZE 128 -#define CALLEE_SAVE_FRAME_SIZE 144 +#define CALLEE_REG_FRAME_SIZE 144 #else #define LDREG ldw #define STREG stw @@ -40,8 +41,9 @@ #define SHRREG shr #define RP_OFFSET 20 #define FRAME_SIZE 64 -#define CALLEE_SAVE_FRAME_SIZE 128 +#define CALLEE_REG_FRAME_SIZE 128 #endif +#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #ifdef CONFIG_PA20 #define BL b,l @@ -300,9 +302,35 @@ fldd,mb -8(\regs), %fr0 .endm + .macro callee_save_float + fstd,ma %fr12, 8(%r30) + fstd,ma %fr13, 8(%r30) + fstd,ma %fr14, 8(%r30) + fstd,ma %fr15, 8(%r30) + fstd,ma %fr16, 8(%r30) + fstd,ma %fr17, 8(%r30) + fstd,ma %fr18, 8(%r30) + fstd,ma %fr19, 8(%r30) + fstd,ma %fr20, 8(%r30) + fstd,ma %fr21, 8(%r30) + .endm + + .macro callee_rest_float + fldd,mb -8(%r30), %fr21 + fldd,mb -8(%r30), %fr20 + fldd,mb -8(%r30), %fr19 + fldd,mb -8(%r30), %fr18 + fldd,mb -8(%r30), %fr17 + fldd,mb -8(%r30), %fr16 + fldd,mb -8(%r30), %fr15 + fldd,mb -8(%r30), %fr14 + fldd,mb -8(%r30), %fr13 + fldd,mb -8(%r30), %fr12 + .endm + #ifdef __LP64__ .macro callee_save - std,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) + std,ma %r3, CALLEE_REG_FRAME_SIZE(%r30) mfctl %cr27, %r3 std %r4, -136(%r30) std %r5, -128(%r30) @@ -340,13 +368,13 @@ ldd -128(%r30), %r5 ldd -136(%r30), %r4 mtctl %r3, %cr27 - ldd,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 + ldd,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3 .endm #else /* ! __LP64__ */ .macro callee_save - stw,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) + stw,ma %r3, CALLEE_REG_FRAME_SIZE(%r30) mfctl %cr27, %r3 stw %r4, -124(%r30) stw %r5, -120(%r30) @@ -384,7 +412,7 @@ ldw -120(%r30), %r5 ldw -124(%r30), %r4 mtctl %r3, %cr27 - ldw,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 + ldw,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3 .endm #endif /* ! __LP64__ */ From 05aa10de701409b893484d2901c8974b3382f8fe Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:53:43 -0400 Subject: [PATCH 0407/1940] [PARISC] Add ECANCELED to errno.h add ECANCELED - SuSv3 wants one L. IB/SDP actually returns this error. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/errno.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h index 08464c405471..e2f3ddc796be 100644 --- a/include/asm-parisc/errno.h +++ b/include/asm-parisc/errno.h @@ -114,6 +114,7 @@ #define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ +#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */ /* for robust mutexes */ #define EOWNERDEAD 254 /* Owner died */ From b4b45313e58bf25886072a4ab111fac553747802 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 22:54:00 -0400 Subject: [PATCH 0408/1940] [PARISC] Add other CRT_ID for newer cards to grfioctl.h Add IDs for some other STI graphics cards found on HP PA-RISC machines. Signed-off-by: Kyle McMartin --- include/asm-parisc/grfioctl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h index d3cfc0168fb1..6a910311b56b 100644 --- a/include/asm-parisc/grfioctl.h +++ b/include/asm-parisc/grfioctl.h @@ -69,6 +69,8 @@ #define CRT_ID_TVRX S9000_ID_98765 /* TVRX (gto/falcon) */ #define CRT_ID_ARTIST S9000_ID_ARTIST /* Artist */ #define CRT_ID_SUMMIT 0x2FC1066B /* Summit FX2, FX4, FX6 ... */ +#define CRT_ID_LEGO 0x35ACDA30 /* Lego FX5, FX10 ... */ +#define CRT_ID_PINNACLE 0x35ACDA16 /* Pinnacle FXe */ /* structure for ioctl(GCDESCRIBE) */ From 63af965d2bc8d8c5d4c5949b8d3dbdc3c7b7d97a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:54:20 -0400 Subject: [PATCH 0409/1940] [PARISC] Define pgprot_noncached macro in pgtable.h drivers/infiniband depends on definition of pgprot_noncached() macro. Someone else will have to fix it's wrong. Signed-off-by: Grant Grundler --- include/asm-parisc/pgtable.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 820c6e712cd7..c28fb6f48c6c 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -501,6 +501,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE) + #define MK_IOSPACE_PFN(space, pfn) (pfn) #define GET_IOSPACE(pfn) 0 #define GET_PFN(pfn) (pfn) From dd0fd51dc1585941c2edccdb40e5f11ea3a64496 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 21 Oct 2005 22:54:38 -0400 Subject: [PATCH 0410/1940] [PARISC] Remove the spurious do_softirq calls from entry.S remove the spurious do_softirq calls from entry.S With these in we were calling do_softirq twice; plus the calls in entry.S took no account of nesting. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 166df5bab769..c7e66ee5b083 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -970,9 +970,6 @@ intr_return: add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ #endif /* CONFIG_SMP */ - LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */ - cmpib,<>,n 0,%r20,intr_do_softirq /* forward */ - intr_check_resched: /* check for reschedule */ @@ -1017,17 +1014,6 @@ intr_restore: nop nop - .import do_softirq,code -intr_do_softirq: - BL do_softirq,%r2 -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#else - nop -#endif - b intr_check_resched - nop - .import schedule,code intr_do_resched: /* Only do reschedule if we are returning to user space */ @@ -2096,9 +2082,6 @@ syscall_check_bh: add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ #endif /* CONFIG_SMP */ - LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */ - cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */ - syscall_check_resched: /* check for reschedule */ @@ -2236,16 +2219,6 @@ pt_regs_ok: b intr_restore nop - .import do_softirq,code -syscall_do_softirq: - BL do_softirq,%r2 - nop - /* NOTE: We enable I-bit incase we schedule later, - * and we might be going back to userspace if we were - * traced. */ - b syscall_check_resched - ssm PSW_SM_I, %r0 /* do_softirq returns with I bit off */ - .import schedule,code syscall_do_resched: BL schedule,%r2 From c2709020adb442f7d25f0805af08a3b6cfedd7be Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Fri, 21 Oct 2005 22:55:15 -0400 Subject: [PATCH 0411/1940] [PARISC] Add NETPOLL support to lasi_82596 add netpoll support Patch by Sven Schnelle Signed-off-by: Sven Schnelle Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- drivers/net/lasi_82596.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index a63d8a317d9e..f7b7238d8352 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -415,6 +415,10 @@ static int rx_ring_size = RX_RING_SIZE; static int ticks_limit = 100; static int max_cmd_backlog = TX_RING_SIZE-1; +#ifdef CONFIG_NET_POLL_CONTROLLER +static void i596_poll_controller(struct net_device *dev); +#endif + static inline void CA(struct net_device *dev) { @@ -636,11 +640,11 @@ static int init_i596_mem(struct net_device *dev) disable_irq(dev->irq); /* disable IRQs from LAN */ DEB(DEB_INIT, - printk("RESET 82596 port: %p (with IRQ %d disabled)\n", - (void*)(dev->base_addr + PA_I82596_RESET), + printk("RESET 82596 port: %lx (with IRQ %d disabled)\n", + (dev->base_addr + PA_I82596_RESET), dev->irq)); - gsc_writel(0, (void*)(dev->base_addr + PA_I82596_RESET)); /* Hard Reset */ + gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */ udelay(100); /* Wait 100us - seems to help */ /* change the scp address */ @@ -1209,6 +1213,9 @@ static int __devinit i82596_probe(struct net_device *dev, dev->set_multicast_list = set_multicast_list; dev->tx_timeout = i596_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = i596_poll_controller; +#endif dev->priv = (void *)(dev->mem_start); @@ -1242,6 +1249,14 @@ static int __devinit i82596_probe(struct net_device *dev, return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void i596_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + i596_interrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { From 37318a3cb1028933417533084ddbf9d84be06878 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:55:34 -0400 Subject: [PATCH 0412/1940] [PARISC] Fix copy_user_page_asm to NOT access past end of page 2.6.12-rc2-pa3 fix copy_user_page_asm to NOT access past end of page. My bad. /o\ Lamont confirmed that instructions following a conditional branch are *alway* executed regardless if the branch is taken or not. Unless they are nullified (which was missing in this case). He also noted: Conditional branches nullify on forward taken branch, and on non-taken backward branch. Note that .+4 is a backwards branch. This makes alot more sense than the giberish in the PA20 arch book. Compiles and boots on both 64-bit (a500) and 32-bit (j6k). Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pacache.S | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 4a7d9c8903f4..e217ae369fbb 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -351,7 +351,11 @@ copy_user_page_asm: std %r22, 120(%r26) ldo 128(%r26), %r26 - ADDIB> -1, %r1, 1b /* bundle 10 */ + /* conditional branches nullify on forward taken branch, and on + * non-taken backward branch. Note that .+4 is a backwards branch. + * The ldd should only get executed if the branch is taken. + */ + ADDIB>,n -1, %r1, 1b /* bundle 10 */ ldd 0(%r25), %r19 /* start next loads */ #else @@ -363,10 +367,10 @@ copy_user_page_asm: * the full 64 bit register values on interrupt, we can't * use ldd/std on a 32 bit kernel. */ + ldw 0(%r25), %r19 ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ 1: - ldw 0(%r25), %r19 ldw 4(%r25), %r20 ldw 8(%r25), %r21 ldw 12(%r25), %r22 @@ -396,11 +400,12 @@ copy_user_page_asm: ldw 60(%r25), %r22 stw %r19, 48(%r26) stw %r20, 52(%r26) + ldo 64(%r25), %r25 stw %r21, 56(%r26) stw %r22, 60(%r26) ldo 64(%r26), %r26 - ADDIB> -1, %r1, 1b - ldo 64(%r25), %r25 + ADDIB>,n -1, %r1, 1b + ldw 0(%r25), %r19 #endif bv %r0(%r2) nop From 9b3b331d0322b60de1bde20528bf974f62804ffa Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:55:51 -0400 Subject: [PATCH 0413/1940] [PARISC] Properly specify index field to I/D cache flush ops replace use of "0" with "%r0" since PA 1.1 I/D flush ops only take a general register and not an immediate value for the index field. This just forces the code to always be PA 1.1 "clean". From: Joel Soete Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pacache.S | 4 ++-- arch/parisc/kernel/signal.c | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index e217ae369fbb..08cde5addfca 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -227,7 +227,7 @@ flush_instruction_cache_local: fimanyloop: /* Loop if LOOP >= 2 */ ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */ - fice 0(%sr1, %arg0) + fice %r0(%sr1, %arg0) fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */ movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */ ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */ @@ -269,7 +269,7 @@ flush_data_cache_local: fdmanyloop: /* Loop if LOOP >= 2 */ ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */ - fdce 0(%sr1, %arg0) + fdce %r0(%sr1, %arg0) fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */ movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */ ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */ diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index befdfe700616..82c24e62ab63 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -625,11 +625,14 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) put_user(0xe0008200, &usp[3]); put_user(0x34140000, &usp[4]); - /* Stack is 64-byte aligned, and we only - * need to flush 1 cache line */ - asm("fdc 0(%%sr3, %0)\n" + /* Stack is 64-byte aligned, and we only need + * to flush 1 cache line. + * Flushing one cacheline is cheap. + * "sync" on bigger (> 4 way) boxes is not. + */ + asm("fdc %%r0(%%sr3, %0)\n" "sync\n" - "fic 0(%%sr3, %0)\n" + "fic %%r0(%%sr3, %0)\n" "sync\n" : : "r"(regs->gr[30])); From e635c96ed6c972e1b3cb0c0fc3681c1204697287 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:56:14 -0400 Subject: [PATCH 0414/1940] [PARISC] Explicitly specify sr4 when flushing kernel space Specify sr4 when flushing kernel space (we could equally well use sr5-7, but must not use sr0). Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pacache.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 08cde5addfca..9534ee17b9be 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -949,23 +949,23 @@ flush_kernel_icache_page: sub %r25, %r23, %r25 -1: fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) - fic,m %r23(%r26) +1: fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) + fic,m %r23(%sr4, %r26) CMPB<< %r26, %r25, 1b - fic,m %r23(%r26) + fic,m %r23(%sr4, %r26) sync bv %r0(%r2) @@ -987,7 +987,7 @@ flush_kernel_icache_range_asm: ANDCM %r26, %r21, %r26 1: CMPB<<,n %r26, %r25, 1b - fic,m %r23(%r26) + fic,m %r23(%sr4, %r26) sync bv %r0(%r2) From 61520e1f8f5ec3a78510a3254947324711944b98 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:56:35 -0400 Subject: [PATCH 0415/1940] [PARISC] Specify level to fix binutils level promotion bug fixup.S needs to specify .level and use correct LDREG macro. New binutils has a bug where it doesn't "promote" from PA1.0 to PA1.1 correctly when using ",s" completer. remove use of __LP64__ in assembly.h and add some white space. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/lib/fixup.S | 4 +++- include/asm-parisc/assembly.h | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S index 1b91612ed964..e0661c2978ed 100644 --- a/arch/parisc/lib/fixup.S +++ b/arch/parisc/lib/fixup.S @@ -35,7 +35,7 @@ extrd,u \t2,63,32,\t2 #endif /* t2 = &__per_cpu_offset[smp_processor_id()]; */ - LDREG,s \t2(\t1),\t2 + LDREGX \t2(\t1),\t2 addil LT%per_cpu__exception_data,%r27 LDREG RT%per_cpu__exception_data(%r1),\t1 /* t1 = &__get_cpu_var(exception_data) */ @@ -53,6 +53,8 @@ .endm #endif + .level LEVEL + .text .section .fixup, "ax" diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index fb8bc7c16e0e..3ce3440d1b0c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -22,7 +22,8 @@ #define _PARISC_ASSEMBLY_H #define CALLEE_FLOAT_FRAME_SIZE 80 -#ifdef __LP64__ + +#ifdef CONFIG_64BIT #define LDREG ldd #define STREG std #define LDREGX ldd,s @@ -32,7 +33,7 @@ #define RP_OFFSET 16 #define FRAME_SIZE 128 #define CALLEE_REG_FRAME_SIZE 144 -#else +#else /* CONFIG_64BIT */ #define LDREG ldw #define STREG stw #define LDREGX ldwx,s @@ -43,6 +44,7 @@ #define FRAME_SIZE 64 #define CALLEE_REG_FRAME_SIZE 128 #endif + #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #ifdef CONFIG_PA20 From e55fb3e787ccfbbdb3198ec859d5689e5413c7bd Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:56:53 -0400 Subject: [PATCH 0416/1940] [PARISC] Properly specify section alignment for real2.S .align applies to the current section - ie section directives come first. Thanks to Joel Soete for catching this. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/real2.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 085bff7c569d..8c2859cca77e 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -145,8 +145,8 @@ restore_control_regs: /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for * more general-purpose use by the several places which need RFIs */ - .align 128 .text + .align 128 rfi_virt2real: /* switch to real mode... */ rsm PSW_SM_I,%r0 From abff75439fd6e9b5774e5984d4c3b3b59cb3038b Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:57:13 -0400 Subject: [PATCH 0417/1940] [PARISC] Avoid use of floating point in the kernel don't use *printf %f in the kernel, mm'kay? Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- drivers/parisc/pdc_stable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 67c8f3b44848..273a74179720 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -536,7 +536,7 @@ pdcs_info_read(struct subsystem *entry, char *buf) out += sprintf(out, "Memory tested: "); if ((result & 0x0F) < 0x0E) - out += sprintf(out, "%.3f MB", 0.256*(1<<(result & 0x0F))); + out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); else out += sprintf(out, "All"); out += sprintf(out, "\n"); From 27ee073cd2f72aa794299ef1ead31072f5176533 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:57:43 -0400 Subject: [PATCH 0418/1940] [PARISC] Update scsi drivers from parisc tree Fix lasi700 for James's ioread*be() changes Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/scsi/lasi700.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 8028418b3ad6..459a4daebece 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -125,8 +125,6 @@ lasi700_probe(struct parisc_device *dev) hostdata->dmode_extra = DMODE_FC2; } - NCR_700_set_mem_mapped(hostdata); - host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev); if (!host) goto out_kfree; From ae8c75c1c47029a64976690c37336a2be6b49778 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:58:03 -0400 Subject: [PATCH 0419/1940] [PARISC] Fix mux.c driver Missing spin_lock_init() made the Mux driver hang on SMP systems. Fix up users of ->hpa to use ->hpa.start instead Remove warning in 8250_gsc.c by eliminating serial_line_nr Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- drivers/serial/8250_gsc.c | 1 - drivers/serial/mux.c | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index abc5a0cfe243..8b4947933d9b 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -29,7 +29,6 @@ static int __init serial_init_chip(struct parisc_device *dev) { - static int serial_line_nr; struct uart_port port; unsigned long address; int err; diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 009ce83c8ef5..660bae5ba179 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -27,6 +27,7 @@ #include /* for udelay */ #include #include +#include #include #ifdef CONFIG_MAGIC_SYSRQ @@ -469,16 +470,18 @@ static int __init mux_probe(struct parisc_device *dev) for(i = 0; i < ports; ++i, ++port_cnt) { port = &mux_ports[port_cnt]; port->iobase = 0; - port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET); + port->mapbase = dev->hpa.start + MUX_OFFSET + + (i * MUX_LINE_OFFSET); port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); port->iotype = SERIAL_IO_MEM; port->type = PORT_MUX; - port->irq = SERIAL_IRQ_NONE; + port->irq = NO_IRQ; port->uartclk = 0; port->fifosize = MUX_FIFO_SIZE; port->ops = &mux_pops; port->flags = UPF_BOOT_AUTOCONF; port->line = port_cnt; + spin_lock_init(&port->lock); status = uart_add_one_port(&mux_driver, port); BUG_ON(status); } From 6ab0f5cd364476fe5cb329fd46ee41bea6d4c69c Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:58:51 -0400 Subject: [PATCH 0420/1940] [PARISC] Update parisc specific input code from parisc tree Update drivers to new input layer changes. Signed-off-by: Helge Deller Signed-off-by: Matthew Wilcox Reorder code in gscps2_interrupt() and only enable ports when opened. This fixes issues with hangs booting an SMP kernel on my C360. Previously serio_interrupt() could be called before the lock in struct serio was initialised. Signed-off-by: Richard Hirst Signed-off-by: Kyle McMartin --- drivers/input/keyboard/hil_kbd.c | 28 +- drivers/input/keyboard/hilkbd.c | 2 +- drivers/input/mouse/hil_ptr.c | 33 ++- drivers/input/serio/gscps2.c | 13 +- drivers/input/serio/hil_mlc.c | 14 +- include/linux/hil.h | 483 +++++++++++++++++++++++++++++++ include/linux/hil_mlc.h | 168 +++++++++++ include/linux/hp_sdc.h | 300 +++++++++++++++++++ include/linux/input.h | 1 + 9 files changed, 1011 insertions(+), 31 deletions(-) create mode 100644 include/linux/hil.h create mode 100644 include/linux/hil_mlc.h create mode 100644 include/linux/hp_sdc.h diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index ef78bffed5e7..0a90962c38e7 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio, hil_packet packet; int idx; - kbd = (struct hil_kbd *)serio->private; + kbd = serio_get_drvdata(serio); if (kbd == NULL) { BUG(); return IRQ_HANDLED; @@ -234,7 +234,7 @@ static void hil_kbd_disconnect(struct serio *serio) { struct hil_kbd *kbd; - kbd = (struct hil_kbd *)serio->private; + kbd = serio_get_drvdata(serio); if (kbd == NULL) { BUG(); return; @@ -245,20 +245,20 @@ static void hil_kbd_disconnect(struct serio *serio) kfree(kbd); } -static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) +static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) { struct hil_kbd *kbd; uint8_t did, *idd; int i; - if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; - - if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return; + kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); + if (!kbd) + return -ENOMEM; memset(kbd, 0, sizeof(struct hil_kbd)); if (serio_open(serio, drv)) goto bail0; - serio->private = kbd; + serio_set_drvdata(serio, kbd); kbd->serio = serio; kbd->dev.private = kbd; @@ -342,19 +342,31 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) down(&(kbd->sem)); up(&(kbd->sem)); - return; + return 0; bail1: serio_close(serio); bail0: kfree(kbd); + serio_set_drvdata(serio, NULL); + return -EIO; } +static struct serio_device_id hil_kbd_ids[] = { + { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; struct serio_driver hil_kbd_serio_drv = { .driver = { .name = "hil_kbd", }, .description = "HP HIL keyboard driver", + .id_table = hil_kbd_ids, .connect = hil_kbd_connect, .disconnect = hil_kbd_disconnect, .interrupt = hil_kbd_interrupt diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index e7a1e14f8b0c..e95bc052e32a 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bc22849c6c79..c2bf2ed07dc6 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -196,7 +196,7 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, hil_packet packet; int idx; - ptr = (struct hil_ptr *)serio->private; + ptr = serio_get_drvdata(serio); if (ptr == NULL) { BUG(); return IRQ_HANDLED; @@ -227,7 +227,7 @@ static void hil_ptr_disconnect(struct serio *serio) { struct hil_ptr *ptr; - ptr = (struct hil_ptr *)serio->private; + ptr = serio_get_drvdata(serio); if (ptr == NULL) { BUG(); return; @@ -238,21 +238,19 @@ static void hil_ptr_disconnect(struct serio *serio) kfree(ptr); } -static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) +static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { struct hil_ptr *ptr; char *txt; unsigned int i, naxsets, btntype; uint8_t did, *idd; - if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; - - if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return; + if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; memset(ptr, 0, sizeof(struct hil_ptr)); if (serio_open(serio, driver)) goto bail0; - serio->private = ptr; + serio_set_drvdata(serio, ptr); ptr->serio = serio; ptr->dev.private = ptr; @@ -380,23 +378,34 @@ static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", did); - return; + return 0; bail1: serio_close(serio); bail0: kfree(ptr); - return; + serio_set_drvdata(serio, NULL); + return -ENODEV; } +static struct serio_device_id hil_ptr_ids[] = { + { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; static struct serio_driver hil_ptr_serio_driver = { .driver = { .name = "hil_ptr", }, .description = "HP HIL mouse/tablet driver", - .connect = hil_ptr_connect, - .disconnect = hil_ptr_disconnect, - .interrupt = hil_ptr_interrupt + .id_table = hil_ptr_ids, + .connect = hil_ptr_connect, + .disconnect = hil_ptr_disconnect, + .interrupt = hil_ptr_interrupt }; static int __init hil_ptr_init(void) diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 9790d7169a53..a7b0de0f92b2 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -211,9 +211,6 @@ static void gscps2_reset(struct gscps2port *ps2port) writeb(0xff, addr+GSC_RESET); gscps2_flush(ps2port); spin_unlock_irqrestore(&ps2port->lock, flags); - - /* enable it */ - gscps2_enable(ps2port, ENABLE); } static LIST_HEAD(ps2port_list); @@ -307,6 +304,9 @@ static int gscps2_open(struct serio *port) gscps2_reset(ps2port); + /* enable it */ + gscps2_enable(ps2port, ENABLE); + gscps2_interrupt(0, NULL, NULL); return 0; @@ -370,8 +370,6 @@ static int __init gscps2_probe(struct parisc_device *dev) serio->port_data = ps2port; serio->dev.parent = &dev->dev; - list_add_tail(&ps2port->node, &ps2port_list); - ret = -EBUSY; if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port)) goto fail_miserably; @@ -396,15 +394,16 @@ static int __init gscps2_probe(struct parisc_device *dev) serio_register_port(ps2port->port); + list_add_tail(&ps2port->node, &ps2port_list); + return 0; fail: free_irq(dev->irq, ps2port); fail_miserably: - list_del(&ps2port->node); iounmap(ps2port->addr); - release_mem_region(dev->hpa, GSC_STATUS + 4); + release_mem_region(dev->hpa.start, GSC_STATUS + 4); fail_nomem: kfree(ps2port); diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index c243cb6fdfc4..5704204964a3 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -801,7 +801,8 @@ static int hil_mlc_serio_open(struct serio *serio) { struct hil_mlc_serio_map *map; struct hil_mlc *mlc; - if (serio->private != NULL) return -EBUSY; + if (serio_get_drvdata(serio) != NULL) + return -EBUSY; map = serio->port_data; if (map == NULL) { @@ -832,11 +833,18 @@ static void hil_mlc_serio_close(struct serio *serio) { return; } - serio->private = NULL; + serio_set_drvdata(serio, NULL); serio->drv = NULL; /* TODO wake up interruptable */ } +static struct serio_device_id hil_mlc_serio_id = { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .extra = SERIO_ANY, + .id = SERIO_ANY, +}; + int hil_mlc_register(hil_mlc *mlc) { int i; unsigned long flags; @@ -867,7 +875,7 @@ int hil_mlc_register(hil_mlc *mlc) { mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; memset(mlc_serio, 0, sizeof(*mlc_serio)); - mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC; + mlc_serio->id = hil_mlc_serio_id; mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; mlc_serio->close = hil_mlc_serio_close; diff --git a/include/linux/hil.h b/include/linux/hil.h new file mode 100644 index 000000000000..13352d7d0caf --- /dev/null +++ b/include/linux/hil.h @@ -0,0 +1,483 @@ +#ifndef _HIL_H_ +#define _HIL_H_ + +/* + * Hewlett Packard Human Interface Loop (HP-HIL) Protocol -- header. + * + * Copyright (c) 2001 Brian S. Julin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL"). + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * + * References: + * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A + * + * A note of thanks to HP for providing and shipping reference materials + * free of charge to help in the development of HIL support for Linux. + * + */ + +#include + +/* Physical constants relevant to raw loop/device timing. + */ + +#define HIL_CLOCK 8MHZ +#define HIL_EK1_CLOCK 30HZ +#define HIL_EK2_CLOCK 60HZ + +#define HIL_TIMEOUT_DEV 5 /* ms */ +#define HIL_TIMEOUT_DEVS 10 /* ms */ +#define HIL_TIMEOUT_NORESP 10 /* ms */ +#define HIL_TIMEOUT_DEVS_DATA 16 /* ms */ +#define HIL_TIMEOUT_SELFTEST 200 /* ms */ + + +/* Actual wire line coding. These will only be useful if someone is + * implementing a software MLC to run HIL devices on a non-parisc machine. + */ + +#define HIL_WIRE_PACKET_LEN 15 +enum hil_wire_bitpos { + HIL_WIRE_START = 0, + HIL_WIRE_ADDR2, + HIL_WIRE_ADDR1, + HIL_WIRE_ADDR0, + HIL_WIRE_COMMAND, + HIL_WIRE_DATA7, + HIL_WIRE_DATA6, + HIL_WIRE_DATA5, + HIL_WIRE_DATA4, + HIL_WIRE_DATA3, + HIL_WIRE_DATA2, + HIL_WIRE_DATA1, + HIL_WIRE_DATA0, + HIL_WIRE_PARITY, + HIL_WIRE_STOP +}; + +/* HP documentation uses these bit positions to refer to commands; + * we will call these "packets". + */ +enum hil_pkt_bitpos { + HIL_PKT_CMD = 0x00000800, + HIL_PKT_ADDR2 = 0x00000400, + HIL_PKT_ADDR1 = 0x00000200, + HIL_PKT_ADDR0 = 0x00000100, + HIL_PKT_ADDR_MASK = 0x00000700, + HIL_PKT_ADDR_SHIFT = 8, + HIL_PKT_DATA7 = 0x00000080, + HIL_PKT_DATA6 = 0x00000040, + HIL_PKT_DATA5 = 0x00000020, + HIL_PKT_DATA4 = 0x00000010, + HIL_PKT_DATA3 = 0x00000008, + HIL_PKT_DATA2 = 0x00000004, + HIL_PKT_DATA1 = 0x00000002, + HIL_PKT_DATA0 = 0x00000001, + HIL_PKT_DATA_MASK = 0x000000FF, + HIL_PKT_DATA_SHIFT = 0 +}; + +/* The HIL MLC also has several error/status/control bits. We extend the + * "packet" to include these when direct access to the MLC is available, + * or emulate them in cases where they are not available. + * + * This way the device driver knows that the underlying MLC driver + * has had to deal with loop errors. + */ +enum hil_error_bitpos { + HIL_ERR_OB = 0x00000800, /* MLC is busy sending an auto-poll, + or we have filled up the output + buffer and must wait. */ + HIL_ERR_INT = 0x00010000, /* A normal interrupt has occurred. */ + HIL_ERR_NMI = 0x00020000, /* An NMI has occurred. */ + HIL_ERR_LERR = 0x00040000, /* A poll didn't come back. */ + HIL_ERR_PERR = 0x01000000, /* There was a Parity Error. */ + HIL_ERR_FERR = 0x02000000, /* There was a Framing Error. */ + HIL_ERR_FOF = 0x04000000 /* Input FIFO Overflowed. */ +}; + +enum hil_control_bitpos { + HIL_CTRL_TEST = 0x00010000, + HIL_CTRL_IPF = 0x00040000, + HIL_CTRL_APE = 0x02000000 +}; + +/* Bits 30,31 are unused, we use them to control write behavior. */ +#define HIL_DO_ALTER_CTRL 0x40000000 /* Write MSW of packet to control + before writing LSW to loop */ +#define HIL_CTRL_ONLY 0xc0000000 /* *Only* alter the control registers */ + +/* This gives us a 32-bit "packet" + */ +typedef u32 hil_packet; + + +/* HIL Loop commands + */ +enum hil_command { + HIL_CMD_IFC = 0x00, /* Interface Clear */ + HIL_CMD_EPT = 0x01, /* Enter Pass-Thru Mode */ + HIL_CMD_ELB = 0x02, /* Enter Loop-Back Mode */ + HIL_CMD_IDD = 0x03, /* Identify and Describe */ + HIL_CMD_DSR = 0x04, /* Device Soft Reset */ + HIL_CMD_PST = 0x05, /* Perform Self Test */ + HIL_CMD_RRG = 0x06, /* Read Register */ + HIL_CMD_WRG = 0x07, /* Write Register */ + HIL_CMD_ACF = 0x08, /* Auto Configure */ + HIL_CMDID_ACF = 0x07, /* Auto Configure bits with incremented ID */ + HIL_CMD_POL = 0x10, /* Poll */ + HIL_CMDCT_POL = 0x0f, /* Poll command bits with item count */ + HIL_CMD_RPL = 0x20, /* RePoll */ + HIL_CMDCT_RPL = 0x0f, /* RePoll command bits with item count */ + HIL_CMD_RNM = 0x30, /* Report Name */ + HIL_CMD_RST = 0x31, /* Report Status */ + HIL_CMD_EXD = 0x32, /* Extended Describe */ + HIL_CMD_RSC = 0x33, /* Report Security Code */ + + /* 0x34 to 0x3c reserved for future use */ + + HIL_CMD_DKA = 0x3d, /* Disable Keyswitch Autorepeat */ + HIL_CMD_EK1 = 0x3e, /* Enable Keyswitch Autorepeat 1 */ + HIL_CMD_EK2 = 0x3f, /* Enable Keyswitch Autorepeat 2 */ + HIL_CMD_PR1 = 0x40, /* Prompt1 */ + HIL_CMD_PR2 = 0x41, /* Prompt2 */ + HIL_CMD_PR3 = 0x42, /* Prompt3 */ + HIL_CMD_PR4 = 0x43, /* Prompt4 */ + HIL_CMD_PR5 = 0x44, /* Prompt5 */ + HIL_CMD_PR6 = 0x45, /* Prompt6 */ + HIL_CMD_PR7 = 0x46, /* Prompt7 */ + HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */ + HIL_CMD_AK1 = 0x48, /* Acknowlege1 */ + HIL_CMD_AK2 = 0x49, /* Acknowlege2 */ + HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */ + HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */ + HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */ + HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */ + HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */ + HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */ + + /* 0x50 to 0x78 reserved for future use */ + /* 0x80 to 0xEF device-specific commands */ + /* 0xf0 to 0xf9 reserved for future use */ + + HIL_CMD_RIO = 0xfa, /* Register I/O Error */ + HIL_CMD_SHR = 0xfb, /* System Hard Reset */ + HIL_CMD_TER = 0xfc, /* Transmission Error */ + HIL_CMD_CAE = 0xfd, /* Configuration Address Error */ + HIL_CMD_DHR = 0xfe, /* Device Hard Reset */ + + /* 0xff is prohibited from use. */ +}; + + +/* + * Response "records" to HIL commands + */ + +/* Device ID byte + */ +#define HIL_IDD_DID_TYPE_MASK 0xe0 /* Primary type bits */ +#define HIL_IDD_DID_TYPE_KB_INTEGRAL 0xa0 /* Integral keyboard */ +#define HIL_IDD_DID_TYPE_KB_ITF 0xc0 /* ITD keyboard */ +#define HIL_IDD_DID_TYPE_KB_RSVD 0xe0 /* Reserved keyboard type */ +#define HIL_IDD_DID_TYPE_KB_LANG_MASK 0x1f /* Keyboard locale bits */ +#define HIL_IDD_DID_KBLANG_USE_ESD 0x00 /* Use ESD Locale instead */ +#define HIL_IDD_DID_TYPE_ABS 0x80 /* Absolute Positioners */ +#define HIL_IDD_DID_ABS_RSVD1_MASK 0xf8 /* Reserved */ +#define HIL_IDD_DID_ABS_RSVD1 0x98 +#define HIL_IDD_DID_ABS_TABLET_MASK 0xf8 /* Tablets and digitizers */ +#define HIL_IDD_DID_ABS_TABLET 0x90 +#define HIL_IDD_DID_ABS_TSCREEN_MASK 0xfc /* Touch screens */ +#define HIL_IDD_DID_ABS_TSCREEN 0x8c +#define HIL_IDD_DID_ABS_RSVD2_MASK 0xfc /* Reserved */ +#define HIL_IDD_DID_ABS_RSVD2 0x88 +#define HIL_IDD_DID_ABS_RSVD3_MASK 0xfc /* Reserved */ +#define HIL_IDD_DID_ABS_RSVD3 0x80 +#define HIL_IDD_DID_TYPE_REL 0x60 /* Relative Positioners */ +#define HIL_IDD_DID_REL_RSVD1_MASK 0xf0 /* Reserved */ +#define HIL_IDD_DID_REL_RSVD1 0x70 +#define HIL_IDD_DID_REL_RSVD2_MASK 0xfc /* Reserved */ +#define HIL_IDD_DID_REL_RSVD2 0x6c +#define HIL_IDD_DID_REL_MOUSE_MASK 0xfc /* Mouse */ +#define HIL_IDD_DID_REL_MOUSE 0x68 +#define HIL_IDD_DID_REL_QUAD_MASK 0xf8 /* Other Quadrature Devices */ +#define HIL_IDD_DID_REL_QUAD 0x60 +#define HIL_IDD_DID_TYPE_CHAR 0x40 /* Character Entry */ +#define HIL_IDD_DID_CHAR_BARCODE_MASK 0xfc /* Barcode Reader */ +#define HIL_IDD_DID_CHAR_BARCODE 0x5c +#define HIL_IDD_DID_CHAR_RSVD1_MASK 0xfc /* Reserved */ +#define HIL_IDD_DID_CHAR_RSVD1 0x58 +#define HIL_IDD_DID_CHAR_RSVD2_MASK 0xf8 /* Reserved */ +#define HIL_IDD_DID_CHAR_RSVD2 0x50 +#define HIL_IDD_DID_CHAR_RSVD3_MASK 0xf0 /* Reserved */ +#define HIL_IDD_DID_CHAR_RSVD3 0x40 +#define HIL_IDD_DID_TYPE_OTHER 0x20 /* Miscellaneous */ +#define HIL_IDD_DID_OTHER_RSVD1_MASK 0xf0 /* Reserved */ +#define HIL_IDD_DID_OTHER_RSVD1 0x30 +#define HIL_IDD_DID_OTHER_BARCODE_MASK 0xfc /* Tone Generator */ +#define HIL_IDD_DID_OTHER_BARCODE 0x2c +#define HIL_IDD_DID_OTHER_RSVD2_MASK 0xfc /* Reserved */ +#define HIL_IDD_DID_OTHER_RSVD2 0x28 +#define HIL_IDD_DID_OTHER_RSVD3_MASK 0xf8 /* Reserved */ +#define HIL_IDD_DID_OTHER_RSVD3 0x20 +#define HIL_IDD_DID_TYPE_KEYPAD 0x00 /* Vectra Keyboard */ + +/* IDD record header + */ +#define HIL_IDD_HEADER_AXSET_MASK 0x03 /* Number of axis in a set */ +#define HIL_IDD_HEADER_RSC 0x04 /* Supports RSC command */ +#define HIL_IDD_HEADER_EXD 0x08 /* Supports EXD command */ +#define HIL_IDD_HEADER_IOD 0x10 /* IOD byte to follow */ +#define HIL_IDD_HEADER_16BIT 0x20 /* 16 (vs. 8) bit resolution */ +#define HIL_IDD_HEADER_ABS 0x40 /* Reports Absolute Position */ +#define HIL_IDD_HEADER_2X_AXIS 0x80 /* Two sets of 1-3 axis */ + +/* I/O Descriptor + */ +#define HIL_IDD_IOD_NBUTTON_MASK 0x07 /* Number of buttons */ +#define HIL_IDD_IOD_PROXIMITY 0x08 /* Proximity in/out events */ +#define HIL_IDD_IOD_PROMPT_MASK 0x70 /* Number of prompts/acks */ +#define HIL_IDD_IOD_PROMPT_SHIFT 4 +#define HIL_IDD_IOD_PROMPT 0x80 /* Generic prompt/ack */ + +#define HIL_IDD_NUM_AXES_PER_SET(header_packet) \ +((header_packet) & HIL_IDD_HEADER_AXSET_MASK) + +#define HIL_IDD_NUM_AXSETS(header_packet) \ +(2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS)) + +#define HIL_IDD_LEN(header_packet) \ +((4 - !(header_packet & HIL_IDD_HEADER_IOD) - \ + 2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) + \ + 2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) * \ + !!((header_packet) & HIL_IDD_HEADER_ABS)) + +/* The following HIL_IDD_* macros assume you have an array of + * packets and/or unpacked 8-bit data in the order that they + * were received. + */ + +#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr) \ +(!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 : \ +(((*(header_ptr + 1) & HIL_PKT_DATA_MASK) + \ + ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8) \ +* ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1))) + +#define HIL_IDD_AXIS_MAX(header_ptr, __axnum) \ +((!(*(header_ptr) & HIL_IDD_HEADER_ABS) || \ + (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 : \ + ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) + \ + ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8))) + +#define HIL_IDD_IOD(header_ptr) \ +(*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1)) + +#define HIL_IDD_HAS_GEN_PROMPT(header_ptr) \ +((*header_ptr & HIL_IDD_HEADER_IOD) && \ + (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT)) + +#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr) \ +((*header_ptr & HIL_IDD_HEADER_IOD) && \ + (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY)) + +#define HIL_IDD_NUM_BUTTONS(header_ptr) \ +((*header_ptr & HIL_IDD_HEADER_IOD) ? \ + (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0) + +#define HIL_IDD_NUM_PROMPTS(header_ptr) \ +((*header_ptr & HIL_IDD_HEADER_IOD) ? \ + ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK) \ + >> HIL_IDD_IOD_PROMPT_SHIFT) : 0) + +/* The response to HIL EXD commands -- the "extended describe record" */ +#define HIL_EXD_HEADER_WRG 0x03 /* Supports type2 WRG */ +#define HIL_EXD_HEADER_WRG_TYPE1 0x01 /* Supports type1 WRG */ +#define HIL_EXD_HEADER_WRG_TYPE2 0x02 /* Supports type2 WRG */ +#define HIL_EXD_HEADER_RRG 0x04 /* Supports RRG command */ +#define HIL_EXD_HEADER_RNM 0x10 /* Supports RNM command */ +#define HIL_EXD_HEADER_RST 0x20 /* Supports RST command */ +#define HIL_EXD_HEADER_LOCALE 0x40 /* Contains locale code */ + +#define HIL_EXD_NUM_RRG(header_ptr) \ +((*header_ptr & HIL_EXD_HEADER_RRG) ? \ + (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0) + +#define HIL_EXD_NUM_WWG(header_ptr) \ +((*header_ptr & HIL_EXD_HEADER_WRG) ? \ + (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) & \ + HIL_PKT_DATA_MASK) : 0) + +#define HIL_EXD_LEN(header_ptr) \ +(!!(*header_ptr & HIL_EXD_HEADER_RRG) + \ + !!(*header_ptr & HIL_EXD_HEADER_WRG) + \ + !!(*header_ptr & HIL_EXD_HEADER_LOCALE) + \ + 2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1) + +#define HIL_EXD_LOCALE(header_ptr) \ +(!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 : \ + (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK)) + +#define HIL_EXD_WRG_TYPE2_LEN(header_ptr) \ +(!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1 : \ + (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 - \ + !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) + \ + ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 - \ + !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8)) + +/* Device locale codes. */ + +/* Last defined locale code. Everything above this is "Reserved", + and note that this same table applies to the Device ID Byte where + keyboards may have a nationality code which is only 5 bits. */ +#define HIL_LOCALE_MAX 0x1f + +/* Map to hopefully useful strings. I was trying to make these look + like locale.aliases strings do; maybe that isn't the right table to + emulate. In either case, I didn't have much to work on. */ +#define HIL_LOCALE_MAP \ +"", /* 0x00 Reserved */ \ +"", /* 0x01 Reserved */ \ +"", /* 0x02 Reserved */ \ +"swiss.french", /* 0x03 Swiss/French */ \ +"portuguese", /* 0x04 Portuguese */ \ +"arabic", /* 0x05 Arabic */ \ +"hebrew", /* 0x06 Hebrew */ \ +"english.canadian", /* 0x07 Canadian English */ \ +"turkish", /* 0x08 Turkish */ \ +"greek", /* 0x09 Greek */ \ +"thai", /* 0x0a Thai (Thailand) */ \ +"italian", /* 0x0b Italian */ \ +"korean", /* 0x0c Hangul (Korea) */ \ +"dutch", /* 0x0d Dutch */ \ +"swedish", /* 0x0e Swedish */ \ +"german", /* 0x0f German */ \ +"chinese", /* 0x10 Chinese-PRC */ \ +"chinese", /* 0x11 Chinese-ROC */ \ +"swiss.french", /* 0x12 Swiss/French II */ \ +"spanish", /* 0x13 Spanish */ \ +"swiss.german", /* 0x14 Swiss/German II */ \ +"flemish", /* 0x15 Belgian (Flemish) */ \ +"finnish", /* 0x16 Finnish */ \ +"english.uk", /* 0x17 United Kingdom */ \ +"french.canadian", /* 0x18 French/Canadian */ \ +"swiss.german", /* 0x19 Swiss/German */ \ +"norwegian", /* 0x1a Norwegian */ \ +"french", /* 0x1b French */ \ +"danish", /* 0x1c Danish */ \ +"japanese", /* 0x1d Katakana */ \ +"spanish", /* 0x1e Latin American/Spanish*/\ +"english.us" /* 0x1f United States */ \ + + +/* HIL keycodes */ +#define HIL_KEYCODES_SET1_TBLSIZE 128 +#define HIL_KEYCODES_SET1 \ + KEY_5, KEY_RESERVED, KEY_RIGHTALT, KEY_LEFTALT, \ + KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_LEFTCTRL, KEY_SYSRQ, \ + KEY_KP4, KEY_KP8, KEY_KP5, KEY_KP9, \ + KEY_KP6, KEY_KP7, KEY_KPCOMMA, KEY_KPENTER, \ + KEY_KP1, KEY_KPSLASH, KEY_KP2, KEY_KPPLUS, \ + KEY_KP3, KEY_KPASTERISK, KEY_KP0, KEY_KPMINUS, \ + KEY_B, KEY_V, KEY_C, KEY_X, \ + KEY_Z, KEY_RESERVED, KEY_RESERVED, KEY_ESC, \ + KEY_6, KEY_F10, KEY_3, KEY_F11, \ + KEY_KPDOT, KEY_F9, KEY_TAB /*KP*/, KEY_F12, \ + KEY_H, KEY_G, KEY_F, KEY_D, \ + KEY_S, KEY_A, KEY_RESERVED, KEY_CAPSLOCK, \ + KEY_U, KEY_Y, KEY_T, KEY_R, \ + KEY_E, KEY_W, KEY_Q, KEY_TAB, \ + KEY_7, KEY_6, KEY_5, KEY_4, \ + KEY_3, KEY_2, KEY_1, KEY_GRAVE, \ + KEY_F13, KEY_F14, KEY_F15, KEY_F16, \ + KEY_F17, KEY_F18, KEY_F19, KEY_F20, \ + KEY_MENU, KEY_F4, KEY_F3, KEY_F2, \ + KEY_F1, KEY_VOLUMEUP, KEY_STOP, KEY_SENDFILE, \ + KEY_SYSRQ, KEY_F5, KEY_F6, KEY_F7, \ + KEY_F8, KEY_VOLUMEDOWN, KEY_DEL_EOL, KEY_DEL_EOS, \ + KEY_8, KEY_9, KEY_0, KEY_MINUS, \ + KEY_EQUAL, KEY_BACKSPACE, KEY_INS_LINE, KEY_DEL_LINE, \ + KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, \ + KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_INSERT, KEY_DELETE, \ + KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \ + KEY_APOSTROPHE, KEY_ENTER, KEY_HOME, KEY_PAGEUP, \ + KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, \ + KEY_BACKSLASH, KEY_SELECT, KEY_102ND, KEY_PAGEDOWN, \ + KEY_N, KEY_SPACE, KEY_NEXT, KEY_RESERVED, \ + KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT + + +#define HIL_KEYCODES_SET3_TBLSIZE 128 +#define HIL_KEYCODES_SET3 \ + KEY_RESERVED, KEY_ESC, KEY_1, KEY_2, \ + KEY_3, KEY_4, KEY_5, KEY_6, \ + KEY_7, KEY_8, KEY_9, KEY_0, \ + KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, \ + KEY_Q, KEY_W, KEY_E, KEY_R, \ + KEY_T, KEY_Y, KEY_U, KEY_I, \ + KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, \ + KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S, \ + KEY_D, KEY_F, KEY_G, KEY_H, \ + KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \ + KEY_APOSTROPHE,KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH, \ + KEY_Z, KEY_X, KEY_C, KEY_V, \ + KEY_B, KEY_N, KEY_M, KEY_COMMA, \ + KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK, \ + KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1, \ + KEY_F2, KEY_F3, KEY_F4, KEY_F5, \ + KEY_F6, KEY_F7, KEY_F8, KEY_F9, \ + KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7, \ + KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4, \ + KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, \ + KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT, \ + KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \ + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \ + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \ + KEY_UP, KEY_LEFT, KEY_DOWN, KEY_RIGHT, \ + KEY_HOME, KEY_PAGEUP, KEY_END, KEY_PAGEDOWN, \ + KEY_INSERT, KEY_DELETE, KEY_102ND, KEY_RESERVED, \ + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \ + KEY_F1, KEY_F2, KEY_F3, KEY_F4, \ + KEY_F5, KEY_F6, KEY_F7, KEY_F8, \ + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \ + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED + + +/* Response to POL command, the "poll record header" */ + +#define HIL_POL_NUM_AXES_MASK 0x03 /* Number of axis reported */ +#define HIL_POL_CTS 0x04 /* Device ready to receive data */ +#define HIL_POL_STATUS_PENDING 0x08 /* Device has status to report */ +#define HIL_POL_CHARTYPE_MASK 0x70 /* Type of character data to follow */ +#define HIL_POL_CHARTYPE_NONE 0x00 /* No character data to follow */ +#define HIL_POL_CHARTYPE_RSVD1 0x10 /* Reserved Set 1 */ +#define HIL_POL_CHARTYPE_ASCII 0x20 /* U.S. ASCII */ +#define HIL_POL_CHARTYPE_BINARY 0x30 /* Binary data */ +#define HIL_POL_CHARTYPE_SET1 0x40 /* Keycode Set 1 */ +#define HIL_POL_CHARTYPE_RSVD2 0x50 /* Reserved Set 2 */ +#define HIL_POL_CHARTYPE_SET2 0x60 /* Keycode Set 2 */ +#define HIL_POL_CHARTYPE_SET3 0x70 /* Keycode Set 3 */ +#define HIL_POL_AXIS_ALT 0x80 /* Data is from axis set 2 */ + + +#endif /* _HIL_H_ */ diff --git a/include/linux/hil_mlc.h b/include/linux/hil_mlc.h new file mode 100644 index 000000000000..8df29ca48a13 --- /dev/null +++ b/include/linux/hil_mlc.h @@ -0,0 +1,168 @@ +/* + * HP Human Interface Loop Master Link Controller driver. + * + * Copyright (c) 2001 Brian S. Julin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL"). + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * + * References: + * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A + * + */ + +#include +#include +#include +#include +#include +#include + +typedef struct hil_mlc hil_mlc; + +/* The HIL has a complicated state engine. + * We define the structure of nodes in the state engine here. + */ +enum hilse_act { + /* HILSE_OUT prepares to receive input if the next node + * is an IN or EXPECT, and then sends the given packet. + */ + HILSE_OUT = 0, + + /* HILSE_CTS checks if the loop is busy. */ + HILSE_CTS, + + /* HILSE_OUT_LAST sends the given command packet to + * the last configured/running device on the loop. + */ + HILSE_OUT_LAST, + + /* HILSE_OUT_DISC sends the given command packet to + * the next device past the last configured/running one. + */ + HILSE_OUT_DISC, + + /* HILSE_FUNC runs a callback function with given arguments. + * a positive return value causes the "ugly" branch to be taken. + */ + HILSE_FUNC, + + /* HILSE_IN simply expects any non-errored packet to arrive + * within arg usecs. + */ + HILSE_IN = 0x100, + + /* HILSE_EXPECT expects a particular packet to arrive + * within arg usecs, any other packet is considered an error. + */ + HILSE_EXPECT, + + /* HILSE_EXPECT_LAST as above but dev field should be last + * discovered/operational device. + */ + HILSE_EXPECT_LAST, + + /* HILSE_EXPECT_LAST as above but dev field should be first + * undiscovered/inoperational device. + */ + HILSE_EXPECT_DISC +}; + +typedef int (hilse_func) (hil_mlc *mlc, int arg); +struct hilse_node { + enum hilse_act act; /* How to process this node */ + union { + hilse_func *func; /* Function to call if HILSE_FUNC */ + hil_packet packet; /* Packet to send or to compare */ + } object; + int arg; /* Timeout in usec or parm for func */ + int good; /* Node to jump to on success */ + int bad; /* Node to jump to on error */ + int ugly; /* Node to jump to on timeout */ +}; + +/* Methods for back-end drivers, e.g. hp_sdc_mlc */ +typedef int (hil_mlc_cts) (hil_mlc *mlc); +typedef void (hil_mlc_out) (hil_mlc *mlc); +typedef int (hil_mlc_in) (hil_mlc *mlc, suseconds_t timeout); + +struct hil_mlc_devinfo { + uint8_t idd[16]; /* Device ID Byte and Describe Record */ + uint8_t rsc[16]; /* Security Code Header and Record */ + uint8_t exd[16]; /* Extended Describe Record */ + uint8_t rnm[16]; /* Device name as returned by RNM command */ +}; + +struct hil_mlc_serio_map { + hil_mlc *mlc; + int di_revmap; + int didx; +}; + +/* How many (possibly old/detached) devices the we try to keep track of */ +#define HIL_MLC_DEVMEM 16 + +struct hil_mlc { + struct list_head list; /* hil_mlc is organized as linked list */ + + rwlock_t lock; + + void *priv; /* Data specific to a particular type of MLC */ + + int seidx; /* Current node in state engine */ + int istarted, ostarted; + + hil_mlc_cts *cts; + struct semaphore csem; /* Raised when loop idle */ + + hil_mlc_out *out; + struct semaphore osem; /* Raised when outpacket dispatched */ + hil_packet opacket; + + hil_mlc_in *in; + struct semaphore isem; /* Raised when a packet arrives */ + hil_packet ipacket[16]; + hil_packet imatch; + int icount; + struct timeval instart; + suseconds_t intimeout; + + int ddi; /* Last operational device id */ + int lcv; /* LCV to throttle loops */ + struct timeval lcv_tv; /* Time loop was started */ + + int di_map[7]; /* Maps below items to live devs */ + struct hil_mlc_devinfo di[HIL_MLC_DEVMEM]; + struct serio *serio[HIL_MLC_DEVMEM]; + struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM]; + hil_packet serio_opacket[HIL_MLC_DEVMEM]; + int serio_oidx[HIL_MLC_DEVMEM]; + struct hil_mlc_devinfo di_scratch; /* Temporary area */ + + int opercnt; + + struct tasklet_struct *tasklet; +}; + +int hil_mlc_register(hil_mlc *mlc); +int hil_mlc_unregister(hil_mlc *mlc); diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h new file mode 100644 index 000000000000..debd71515312 --- /dev/null +++ b/include/linux/hp_sdc.h @@ -0,0 +1,300 @@ +/* + * HP i8042 System Device Controller -- header + * + * Copyright (c) 2001 Brian S. Julin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL"). + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * + * References: + * + * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A + * + * System Device Controller Microprocessor Firmware Theory of Operation + * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2 + * + */ + +#ifndef _LINUX_HP_SDC_H +#define _LINUX_HP_SDC_H + +#include +#include +#include +#include +#if defined(__hppa__) +#include +#endif + + +/* No 4X status reads take longer than this (in usec). + */ +#define HP_SDC_MAX_REG_DELAY 20000 + +typedef void (hp_sdc_irqhook) (int irq, void *dev_id, + uint8_t status, uint8_t data); + +int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback); +int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback); +int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback); +int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback); +int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback); +int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback); + +typedef struct { + int actidx; /* Start of act. Acts are atomic WRT I/O to SDC */ + int idx; /* Index within the act */ + int endidx; /* transaction is over and done if idx == endidx */ + uint8_t *seq; /* commands/data for the transaction */ + union { + hp_sdc_irqhook *irqhook; /* Callback, isr or tasklet context */ + struct semaphore *semaphore; /* Semaphore to sleep on. */ + } act; +} hp_sdc_transaction; +int hp_sdc_enqueue_transaction(hp_sdc_transaction *this); +int hp_sdc_dequeue_transaction(hp_sdc_transaction *this); + +/* The HP_SDC_ACT* values are peculiar to this driver. + * Nuance: never HP_SDC_ACT_DATAIN | HP_SDC_ACT_DEALLOC, use another + * act to perform the dealloc. + */ +#define HP_SDC_ACT_PRECMD 0x01 /* Send a command first */ +#define HP_SDC_ACT_DATAREG 0x02 /* Set data registers */ +#define HP_SDC_ACT_DATAOUT 0x04 /* Send data bytes */ +#define HP_SDC_ACT_POSTCMD 0x08 /* Send command after */ +#define HP_SDC_ACT_DATAIN 0x10 /* Collect data after */ +#define HP_SDC_ACT_DURING 0x1f +#define HP_SDC_ACT_SEMAPHORE 0x20 /* Raise semaphore after */ +#define HP_SDC_ACT_CALLBACK 0x40 /* Pass data to IRQ handler */ +#define HP_SDC_ACT_DEALLOC 0x80 /* Destroy transaction after */ +#define HP_SDC_ACT_AFTER 0xe0 +#define HP_SDC_ACT_DEAD 0x60 /* Act timed out. */ + +/* Rest of the flags are straightforward representation of the SDC interface */ +#define HP_SDC_STATUS_IBF 0x02 /* Input buffer full */ + +#define HP_SDC_STATUS_IRQMASK 0xf0 /* Bits containing "level 1" irq */ +#define HP_SDC_STATUS_PERIODIC 0x10 /* Periodic 10ms timer */ +#define HP_SDC_STATUS_USERTIMER 0x20 /* "Special purpose" timer */ +#define HP_SDC_STATUS_TIMER 0x30 /* Both PERIODIC and USERTIMER */ +#define HP_SDC_STATUS_REG 0x40 /* Data from an i8042 register */ +#define HP_SDC_STATUS_HILCMD 0x50 /* Command from HIL MLC */ +#define HP_SDC_STATUS_HILDATA 0x60 /* Data from HIL MLC */ +#define HP_SDC_STATUS_PUP 0x70 /* Sucessful power-up self test */ +#define HP_SDC_STATUS_KCOOKED 0x80 /* Key from cooked kbd */ +#define HP_SDC_STATUS_KRPG 0xc0 /* Key from Repeat Gen */ +#define HP_SDC_STATUS_KMOD_SUP 0x10 /* Shift key is up */ +#define HP_SDC_STATUS_KMOD_CUP 0x20 /* Control key is up */ + +#define HP_SDC_NMISTATUS_FHS 0x40 /* NMI is a fast handshake irq */ + +/* Internal i8042 registers (there are more, but they are not too useful). */ + +#define HP_SDC_USE 0x02 /* Resource usage (including OB bit) */ +#define HP_SDC_IM 0x04 /* Interrupt mask */ +#define HP_SDC_CFG 0x11 /* Configuration register */ +#define HP_SDC_KBLANGUAGE 0x12 /* Keyboard language */ + +#define HP_SDC_D0 0x70 /* General purpose data buffer 0 */ +#define HP_SDC_D1 0x71 /* General purpose data buffer 1 */ +#define HP_SDC_D2 0x72 /* General purpose data buffer 2 */ +#define HP_SDC_D3 0x73 /* General purpose data buffer 3 */ +#define HP_SDC_VT1 0x74 /* Timer for voice 1 */ +#define HP_SDC_VT2 0x75 /* Timer for voice 2 */ +#define HP_SDC_VT3 0x76 /* Timer for voice 3 */ +#define HP_SDC_VT4 0x77 /* Timer for voice 4 */ +#define HP_SDC_KBN 0x78 /* Which HIL devs are Nimitz */ +#define HP_SDC_KBC 0x79 /* Which HIL devs are cooked kbds */ +#define HP_SDC_LPS 0x7a /* i8042's view of HIL status */ +#define HP_SDC_LPC 0x7b /* i8042's view of HIL "control" */ +#define HP_SDC_RSV 0x7c /* Reserved "for testing" */ +#define HP_SDC_LPR 0x7d /* i8042 count of HIL reconfigs */ +#define HP_SDC_XTD 0x7e /* "Extended Configuration" register */ +#define HP_SDC_STR 0x7f /* i8042 self-test result */ + +/* Bitfields for above registers */ +#define HP_SDC_USE_LOOP 0x04 /* Command is currently on the loop. */ + +#define HP_SDC_IM_MASK 0x1f /* these bits not part of cmd/status */ +#define HP_SDC_IM_FH 0x10 /* Mask the fast handshake irq */ +#define HP_SDC_IM_PT 0x08 /* Mask the periodic timer irq */ +#define HP_SDC_IM_TIMERS 0x04 /* Mask the MT/DT/CT irq */ +#define HP_SDC_IM_RESET 0x02 /* Mask the reset key irq */ +#define HP_SDC_IM_HIL 0x01 /* Mask the HIL MLC irq */ + +#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF is "N-key rollover"? */ +#define HP_SDC_CFG_KBD 0x10 /* There is a keyboard */ +#define HP_SDC_CFG_NEW 0x20 /* Supports/uses HIL MLC */ +#define HP_SDC_CFG_KBD_OLD 0x03 /* keyboard code for non-HIL */ +#define HP_SDC_CFG_KBD_NEW 0x07 /* keyboard code from HIL autoconfig */ +#define HP_SDC_CFG_REV 0x40 /* Code revision bit */ +#define HP_SDC_CFG_IDPROM 0x80 /* IDPROM present in kbd (not HIL) */ + +#define HP_SDC_LPS_NDEV 0x07 /* # devices autoconfigured on HIL */ +#define HP_SDC_LPS_ACSUCC 0x08 /* loop autoconfigured successfully */ +#define HP_SDC_LPS_ACFAIL 0x80 /* last loop autoconfigure failed */ + +#define HP_SDC_LPC_APE_IPF 0x01 /* HIL MLC APE/IPF (autopoll) set */ +#define HP_SDC_LPC_ARCONERR 0x02 /* i8042 autoreconfigs loop on err */ +#define HP_SDC_LPC_ARCQUIET 0x03 /* i8042 doesn't report autoreconfigs*/ +#define HP_SDC_LPC_COOK 0x10 /* i8042 cooks devices in _KBN */ +#define HP_SDC_LPC_RC 0x80 /* causes autoreconfig */ + +#define HP_SDC_XTD_REV 0x07 /* contains revision code */ +#define HP_SDC_XTD_REV_STRINGS(val, str) \ +switch (val) { \ + case 0x1: str = "1820-3712"; break; \ + case 0x2: str = "1820-4379"; break; \ + case 0x3: str = "1820-4784"; break; \ + default: str = "unknown"; \ +}; +#define HP_SDC_XTD_BEEPER 0x08 /* TI SN76494 beeper available */ +#define HP_SDC_XTD_BBRTC 0x20 /* OKI MSM-58321 BBRTC present */ + +#define HP_SDC_CMD_LOAD_RT 0x31 /* Load real time (from 8042) */ +#define HP_SDC_CMD_LOAD_FHS 0x36 /* Load the fast handshake timer */ +#define HP_SDC_CMD_LOAD_MT 0x38 /* Load the match timer */ +#define HP_SDC_CMD_LOAD_DT 0x3B /* Load the delay timer */ +#define HP_SDC_CMD_LOAD_CT 0x3E /* Load the cycle timer */ + +#define HP_SDC_CMD_SET_IM 0x40 /* 010xxxxx == set irq mask */ + +/* The documents provided do not explicitly state that all registers betweem + * 0x01 and 0x1f inclusive can be read by sending their register index as a + * command, but this is implied and appears to be the case. + */ +#define HP_SDC_CMD_READ_RAM 0x00 /* Load from i8042 RAM (autoinc) */ +#define HP_SDC_CMD_READ_USE 0x02 /* Undocumented! Load from usage reg */ +#define HP_SDC_CMD_READ_IM 0x04 /* Load current interrupt mask */ +#define HP_SDC_CMD_READ_KCC 0x11 /* Load primary kbd config code */ +#define HP_SDC_CMD_READ_KLC 0x12 /* Load primary kbd language code */ +#define HP_SDC_CMD_READ_T1 0x13 /* Load timer output buffer byte 1 */ +#define HP_SDC_CMD_READ_T2 0x14 /* Load timer output buffer byte 1 */ +#define HP_SDC_CMD_READ_T3 0x15 /* Load timer output buffer byte 1 */ +#define HP_SDC_CMD_READ_T4 0x16 /* Load timer output buffer byte 1 */ +#define HP_SDC_CMD_READ_T5 0x17 /* Load timer output buffer byte 1 */ +#define HP_SDC_CMD_READ_D0 0xf0 /* Load from i8042 RAM location 0x70 */ +#define HP_SDC_CMD_READ_D1 0xf1 /* Load from i8042 RAM location 0x71 */ +#define HP_SDC_CMD_READ_D2 0xf2 /* Load from i8042 RAM location 0x72 */ +#define HP_SDC_CMD_READ_D3 0xf3 /* Load from i8042 RAM location 0x73 */ +#define HP_SDC_CMD_READ_VT1 0xf4 /* Load from i8042 RAM location 0x74 */ +#define HP_SDC_CMD_READ_VT2 0xf5 /* Load from i8042 RAM location 0x75 */ +#define HP_SDC_CMD_READ_VT3 0xf6 /* Load from i8042 RAM location 0x76 */ +#define HP_SDC_CMD_READ_VT4 0xf7 /* Load from i8042 RAM location 0x77 */ +#define HP_SDC_CMD_READ_KBN 0xf8 /* Load from i8042 RAM location 0x78 */ +#define HP_SDC_CMD_READ_KBC 0xf9 /* Load from i8042 RAM location 0x79 */ +#define HP_SDC_CMD_READ_LPS 0xfa /* Load from i8042 RAM location 0x7a */ +#define HP_SDC_CMD_READ_LPC 0xfb /* Load from i8042 RAM location 0x7b */ +#define HP_SDC_CMD_READ_RSV 0xfc /* Load from i8042 RAM location 0x7c */ +#define HP_SDC_CMD_READ_LPR 0xfd /* Load from i8042 RAM location 0x7d */ +#define HP_SDC_CMD_READ_XTD 0xfe /* Load from i8042 RAM location 0x7e */ +#define HP_SDC_CMD_READ_STR 0xff /* Load from i8042 RAM location 0x7f */ + +#define HP_SDC_CMD_SET_ARD 0xA0 /* Set emulated autorepeat delay */ +#define HP_SDC_CMD_SET_ARR 0xA2 /* Set emulated autorepeat rate */ +#define HP_SDC_CMD_SET_BELL 0xA3 /* Set voice 3 params for "beep" cmd */ +#define HP_SDC_CMD_SET_RPGR 0xA6 /* Set "RPG" irq rate (doesn't work) */ +#define HP_SDC_CMD_SET_RTMS 0xAD /* Set the RTC time (milliseconds) */ +#define HP_SDC_CMD_SET_RTD 0xAF /* Set the RTC time (days) */ +#define HP_SDC_CMD_SET_FHS 0xB2 /* Set fast handshake timer */ +#define HP_SDC_CMD_SET_MT 0xB4 /* Set match timer */ +#define HP_SDC_CMD_SET_DT 0xB7 /* Set delay timer */ +#define HP_SDC_CMD_SET_CT 0xBA /* Set cycle timer */ +#define HP_SDC_CMD_SET_RAMP 0xC1 /* Reset READ_RAM autoinc counter */ +#define HP_SDC_CMD_SET_D0 0xe0 /* Load to i8042 RAM location 0x70 */ +#define HP_SDC_CMD_SET_D1 0xe1 /* Load to i8042 RAM location 0x71 */ +#define HP_SDC_CMD_SET_D2 0xe2 /* Load to i8042 RAM location 0x72 */ +#define HP_SDC_CMD_SET_D3 0xe3 /* Load to i8042 RAM location 0x73 */ +#define HP_SDC_CMD_SET_VT1 0xe4 /* Load to i8042 RAM location 0x74 */ +#define HP_SDC_CMD_SET_VT2 0xe5 /* Load to i8042 RAM location 0x75 */ +#define HP_SDC_CMD_SET_VT3 0xe6 /* Load to i8042 RAM location 0x76 */ +#define HP_SDC_CMD_SET_VT4 0xe7 /* Load to i8042 RAM location 0x77 */ +#define HP_SDC_CMD_SET_KBN 0xe8 /* Load to i8042 RAM location 0x78 */ +#define HP_SDC_CMD_SET_KBC 0xe9 /* Load to i8042 RAM location 0x79 */ +#define HP_SDC_CMD_SET_LPS 0xea /* Load to i8042 RAM location 0x7a */ +#define HP_SDC_CMD_SET_LPC 0xeb /* Load to i8042 RAM location 0x7b */ +#define HP_SDC_CMD_SET_RSV 0xec /* Load to i8042 RAM location 0x7c */ +#define HP_SDC_CMD_SET_LPR 0xed /* Load to i8042 RAM location 0x7d */ +#define HP_SDC_CMD_SET_XTD 0xee /* Load to i8042 RAM location 0x7e */ +#define HP_SDC_CMD_SET_STR 0xef /* Load to i8042 RAM location 0x7f */ + +#define HP_SDC_CMD_DO_RTCW 0xc2 /* i8042 RAM 0x70 --> RTC */ +#define HP_SDC_CMD_DO_RTCR 0xc3 /* RTC[0x70 0:3] --> irq/status/data */ +#define HP_SDC_CMD_DO_BEEP 0xc4 /* i8042 RAM 0x70-74 --> beeper,VT3 */ +#define HP_SDC_CMD_DO_HIL 0xc5 /* i8042 RAM 0x70-73 --> + HIL MLC R0,R1 i8042 HIL watchdog */ + +/* Values used to (de)mangle input/output to/from the HIL MLC */ +#define HP_SDC_DATA 0x40 /* Data from an 8042 register */ +#define HP_SDC_HIL_CMD 0x50 /* Data from HIL MLC R1/8042 */ +#define HP_SDC_HIL_R1MASK 0x0f /* Contents of HIL MLC R1 0:3 */ +#define HP_SDC_HIL_AUTO 0x10 /* Set if POL results from i8042 */ +#define HP_SDC_HIL_ISERR 0x80 /* Has meaning as in next 4 values */ +#define HP_SDC_HIL_RC_DONE 0x80 /* i8042 auto-configured loop */ +#define HP_SDC_HIL_ERR 0x81 /* HIL MLC R2 had a bit set */ +#define HP_SDC_HIL_TO 0x82 /* i8042 HIL watchdog expired */ +#define HP_SDC_HIL_RC 0x84 /* i8042 is auto-configuring loop */ +#define HP_SDC_HIL_DAT 0x60 /* Data from HIL MLC R0 */ + + +typedef struct { + rwlock_t ibf_lock; + rwlock_t lock; /* user/tasklet lock */ + rwlock_t rtq_lock; /* isr/tasklet lock */ + rwlock_t hook_lock; /* isr/user lock for handler add/del */ + + unsigned int irq, nmi; /* Our IRQ lines */ + unsigned long base_io, status_io, data_io; /* Our IO ports */ + + uint8_t im; /* Interrupt mask */ + int set_im; /* Interrupt mask needs to be set. */ + + int ibf; /* Last known status of IBF flag */ + uint8_t wi; /* current i8042 write index */ + uint8_t r7[4]; /* current i8042[0x70 - 0x74] values */ + uint8_t r11, r7e; /* Values from version/revision regs */ + + hp_sdc_irqhook *timer, *reg, *hil, *pup, *cooked; + +#define HP_SDC_QUEUE_LEN 16 + hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */ + + int rcurr, rqty; /* Current read transact in process */ + struct timeval rtv; /* Time when current read started */ + int wcurr; /* Current write transact in process */ + + int dev_err; /* carries status from registration */ +#if defined(__hppa__) + struct parisc_device *dev; +#elif defined(__mc68000__) + void *dev; +#else +#error No support for device registration on this arch yet. +#endif + + struct timer_list kicker; /* Keeps below task alive */ + struct tasklet_struct task; + +} hp_i8042_sdc; + +#endif /* _LINUX_HP_SDC_H */ diff --git a/include/linux/input.h b/include/linux/input.h index e8c296ff6257..d7836311ada9 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -644,6 +644,7 @@ struct input_absinfo { #define BUS_ADB 0x17 #define BUS_I2C 0x18 #define BUS_HOST 0x19 +#define BUS_GSC 0x1A /* * Values describing the status of an effect From 27678201333e1b9a9a7fc8e685d858132956113e Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 23:11:03 -0400 Subject: [PATCH 0421/1940] [PARISC] defconfig updates defconfig updates from Kyle McMartin, Grant Grundler, and Matthew Wilcox. Signed-off-by: Kyle McMartin --- arch/parisc/configs/712_defconfig | 456 +++++++++++-------- arch/parisc/configs/a500_defconfig | 551 +++++++++++++--------- arch/parisc/configs/b180_defconfig | 309 ++++++++----- arch/parisc/configs/c3000_defconfig | 678 ++++++++++++++++++---------- arch/parisc/defconfig | 656 +++++++++++++++++++-------- 5 files changed, 1725 insertions(+), 925 deletions(-) diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 6efaa9293eef..3e013f55df64 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig @@ -1,12 +1,16 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-pa5 -# Wed Jan 5 13:20:32 2005 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:04:34 2005 # CONFIG_PARISC=y CONFIG_MMU=y CONFIG_STACK_GROWSUP=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y # # Code maturity level options @@ -15,35 +19,40 @@ CONFIG_EXPERIMENTAL=y # CONFIG_CLEAN_COMPILE is not set CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=16 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,9 +74,18 @@ CONFIG_PA7100LC=y # CONFIG_PA7300LC is not set # CONFIG_PA8X00 is not set CONFIG_PA11=y -# CONFIG_64BIT is not set # CONFIG_SMP is not set -# CONFIG_DISCONTIGMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_PREEMPT is not set # CONFIG_HPUX is not set @@ -81,8 +99,6 @@ CONFIG_GSC_LASI=y # CONFIG_GSC_WAX is not set # CONFIG_EISA is not set # CONFIG_PCI is not set -CONFIG_CHASSIS_LCD_LED=y -# CONFIG_PDC_CHASSIS is not set # # PCCARD (PCMCIA/CardBus) support @@ -90,12 +106,15 @@ CONFIG_CHASSIS_LCD_LED=y # CONFIG_PCCARD is not set # -# PC-card bridges +# PCI Hotplug Support # # -# PCI Hotplug Support +# PA-RISC specific drivers # +CONFIG_CHASSIS_LCD_LED=y +# CONFIG_PDC_CHASSIS is not set +CONFIG_PDC_STABLE=y # # Executable file formats @@ -104,137 +123,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m # -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -CONFIG_PARPORT=y -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_GSC=y -# CONFIG_PARPORT_OTHER is not set -# CONFIG_PARPORT_1284 is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_PARIDE is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=y -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=6144 -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -CONFIG_SCSI_SPI_ATTRS=y -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -CONFIG_SCSI_LASI700=y -CONFIG_53C700_MEM_MAPPED=y -CONFIG_53C700_LE_ON_BE=y -# CONFIG_SCSI_ZALON is not set -CONFIG_SCSI_DEBUG=m - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -# CONFIG_BLK_DEV_DM is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# - -# -# Networking support +# Networking # CONFIG_NET=y @@ -243,12 +132,14 @@ CONFIG_NET=y # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -262,8 +153,10 @@ CONFIG_INET_AH=m CONFIG_INET_ESP=m # CONFIG_INET_IPCOMP is not set CONFIG_INET_TUNNEL=m -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -272,6 +165,7 @@ CONFIG_IP_TCPDIAG=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK is not set # # IP: Netfilter Configuration @@ -279,11 +173,14 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_CONNTRACK=m # CONFIG_IP_NF_CT_ACCT is not set CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set CONFIG_IP_NF_CT_PROTO_SCTP=m CONFIG_IP_NF_FTP=m CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_PPTP is not set CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_LIMIT=m @@ -307,21 +204,23 @@ CONFIG_IP_NF_MATCH_OWNER=m # CONFIG_IP_NF_MATCH_ADDRTYPE is not set # CONFIG_IP_NF_MATCH_REALM is not set CONFIG_IP_NF_MATCH_SCTP=m +# CONFIG_IP_NF_MATCH_DCCP is not set CONFIG_IP_NF_MATCH_COMMENT=m CONFIG_IP_NF_MATCH_CONNMARK=m CONFIG_IP_NF_MATCH_HASHLIMIT=m +# CONFIG_IP_NF_MATCH_STRING is not set CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m @@ -333,6 +232,7 @@ CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_MARK=m CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set CONFIG_IP_NF_TARGET_CONNMARK=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_RAW=m @@ -340,10 +240,11 @@ CONFIG_IP_NF_TARGET_NOTRACK=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set # # SCTP Configuration (EXPERIMENTAL) @@ -362,10 +263,6 @@ CONFIG_LLC2=m # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # CONFIG_NET_CLS_ROUTE is not set @@ -373,17 +270,162 @@ CONFIG_LLC2=m # Network testing # CONFIG_NET_PKTGEN=m -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_GSC=y +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=6144 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_SCSI_LASI700=y +CONFIG_53C700_LE_ON_BE=y +# CONFIG_SCSI_ZALON is not set +CONFIG_SCSI_DEBUG=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +# CONFIG_MD_RAID10 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BLK_DEV_DM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Network device support +# CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_BONDING=m # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_ETHERTAP is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -391,6 +433,7 @@ CONFIG_TUN=m CONFIG_NET_ETHERNET=y CONFIG_MII=m CONFIG_LASI_82596=y +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) @@ -414,6 +457,7 @@ CONFIG_NET_RADIO=y # # CONFIG_STRIP is not set # CONFIG_ATMEL is not set +# CONFIG_HOSTAP is not set # # Wan interfaces @@ -431,6 +475,8 @@ CONFIG_PPPOE=m # CONFIG_SLIP is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -459,19 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PARKBD is not set -CONFIG_SERIO_GSCPS2=y -CONFIG_HP_SDC=y -CONFIG_HIL_MLC=y -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -483,6 +516,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_HIL_OLD=y # CONFIG_KEYBOARD_HIL is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y @@ -493,6 +527,19 @@ CONFIG_MOUSE_HIL=m # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_GSCPS2=y +CONFIG_HP_SDC=y +CONFIG_HIL_MLC=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -511,7 +558,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -546,11 +592,13 @@ CONFIG_GEN_RTC_X=y # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set -# CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# +# TPM devices +# + # # I2C support # @@ -561,10 +609,20 @@ CONFIG_MAX_RAW_DEVS=256 # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -579,28 +637,36 @@ CONFIG_MAX_RAW_DEVS=256 # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y CONFIG_FB_STI=y +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # -CONFIG_STI_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=128 CONFIG_DUMMY_CONSOLE_ROWS=48 -CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_STI_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set # CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set # # Logo configuration @@ -610,6 +676,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_LOGO_PARISC_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -656,10 +723,6 @@ CONFIG_SND_HARMONY=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -670,11 +733,21 @@ CONFIG_SND_HARMONY=y # # CONFIG_MMC is not set +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y @@ -682,20 +755,24 @@ CONFIG_JBD=y # CONFIG_REISERFS_FS is not set CONFIG_JFS_FS=m # CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -# CONFIG_XFS_RT is not set +CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -722,14 +799,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_TMPFS_XATTR=y -# CONFIG_TMPFS_SECURITY is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -754,16 +828,19 @@ CONFIG_UFS_FS=m # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -778,6 +855,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -838,13 +916,19 @@ CONFIG_OPROFILE=m # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set +# CONFIG_DEBUG_FS is not set # # Security options @@ -865,6 +949,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m @@ -881,10 +966,15 @@ CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_TEST=m +# +# Hardware crypto devices +# + # # Library routines # CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index 30fc03ed0cfb..955ef5084f3e 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4-pa1 -# Wed Feb 16 11:32:49 2005 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:04:54 2005 # CONFIG_PARISC=y CONFIG_MMU=y @@ -10,6 +10,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y # # Code maturity level options @@ -19,26 +20,32 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=16 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set +CONFIG_INITRAMFS_SOURCE="" CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -48,6 +55,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -74,7 +82,19 @@ CONFIG_PREFETCH=y CONFIG_64BIT=y CONFIG_SMP=y CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_PREEMPT is not set CONFIG_COMPAT=y CONFIG_NR_CPUS=8 @@ -85,7 +105,7 @@ CONFIG_NR_CPUS=8 # CONFIG_GSC is not set CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_PCI_LBA=y CONFIG_IOSAPIC=y CONFIG_IOMMU_SBA=y @@ -96,6 +116,8 @@ CONFIG_IOMMU_SBA=y CONFIG_PCCARD=m # CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=m +# CONFIG_PCMCIA_LOAD_CIS is not set +CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y # @@ -104,7 +126,6 @@ CONFIG_CARDBUS=y CONFIG_YENTA=m CONFIG_PD6729=m CONFIG_I82092=m -CONFIG_TCIC=m CONFIG_PCCARD_NONSTATIC=m # @@ -126,6 +147,203 @@ CONFIG_PDC_STABLE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_PPTP is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +CONFIG_IP_NF_MATCH_SCTP=m +# CONFIG_IP_NF_MATCH_DCCP is not set +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +# CONFIG_IP_NF_MATCH_STRING is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_LIMIT is not set +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +# CONFIG_IP6_NF_MATCH_MULTIPORT is not set +# CONFIG_IP6_NF_MATCH_OWNER is not set +# CONFIG_IP6_NF_MATCH_MARK is not set +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_NFQUEUE is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_TARGET_MARK is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_RAW=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID3 is not set + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +CONFIG_LLC2=m +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -138,6 +356,11 @@ CONFIG_BINFMT_ELF=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -169,7 +392,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=6144 CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -189,6 +411,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -201,6 +424,7 @@ CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -215,6 +439,7 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m # # SCSI low-level drivers @@ -229,14 +454,12 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_ADVANSYS is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -246,8 +469,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set CONFIG_SCSI_QLOGIC_FC=m # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set @@ -258,7 +479,9 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA22XX is not set CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m -CONFIG_SCSI_QLA6312=m +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set CONFIG_SCSI_DEBUG=m @@ -288,8 +511,11 @@ CONFIG_MD_RAID1=y # # Fusion MPT device support # -CONFIG_FUSION=m -CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +# CONFIG_FUSION_SAS is not set +CONFIG_FUSION_MAX_SGE=128 CONFIG_FUSION_CTL=m # @@ -303,159 +529,24 @@ CONFIG_FUSION_CTL=m # CONFIG_I2O is not set # -# Networking support +# Network device support # -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -# CONFIG_INET_IPCOMP is not set -CONFIG_INET_TUNNEL=m -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_CT_ACCT is not set -CONFIG_IP_NF_CONNTRACK_MARK=y -CONFIG_IP_NF_CT_PROTO_SCTP=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_REALM is not set -CONFIG_IP_NF_MATCH_SCTP=m -CONFIG_IP_NF_MATCH_COMMENT=m -CONFIG_IP_NF_MATCH_CONNMARK=m -CONFIG_IP_NF_MATCH_HASHLIMIT=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -CONFIG_IP_NF_TARGET_CONNMARK=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_XFRM=y -CONFIG_XFRM_USER=m - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -CONFIG_LLC=m -CONFIG_LLC2=m -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_BONDING=m # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_ETHERTAP is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -463,6 +554,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set CONFIG_NET_VENDOR_3COM=y CONFIG_VORTEX=m CONFIG_TYPHOON=m @@ -479,6 +571,7 @@ CONFIG_TULIP_MMIO=y # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set CONFIG_PCMCIA_XIRCOM=m # CONFIG_PCMCIA_XIRTULIP is not set CONFIG_HP100=m @@ -489,48 +582,43 @@ CONFIG_PCNET32=m # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set -CONFIG_EEPRO100=m +# CONFIG_EEPRO100 is not set CONFIG_E100=m -CONFIG_E100_NAPI=y # CONFIG_FEALNX is not set -CONFIG_NATSEMI=m +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139CP is not set -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_8139TOO is not set # CONFIG_SIS900 is not set -CONFIG_EPIC100=m +# CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set -CONFIG_VIA_RHINE=m -CONFIG_VIA_RHINE_MMIO=y +# CONFIG_VIA_RHINE is not set # # Ethernet (1000 Mbit) # CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y -CONFIG_DL2K=m +# CONFIG_DL2K is not set CONFIG_E1000=m CONFIG_E1000_NAPI=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=m +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # -CONFIG_IXGB=m -CONFIG_IXGB_NAPI=y -CONFIG_S2IO=m -CONFIG_S2IO_NAPI=y -# CONFIG_2BUFF_MODE is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices @@ -560,6 +648,7 @@ CONFIG_PCMCIA_RAYCS=m CONFIG_HERMES=m CONFIG_PLX_HERMES=m CONFIG_TMD_HERMES=m +# CONFIG_NORTEL_HERMES is not set CONFIG_PCI_HERMES=m # CONFIG_ATMEL is not set @@ -567,6 +656,7 @@ CONFIG_PCI_HERMES=m # Wireless 802.11b Pcmcia/Cardbus cards support # CONFIG_PCMCIA_HERMES=m +# CONFIG_PCMCIA_SPECTRUM is not set CONFIG_AIRO_CS=m CONFIG_PCMCIA_WL3501=m @@ -574,6 +664,7 @@ CONFIG_PCMCIA_WL3501=m # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # # CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set CONFIG_NET_WIRELESS=y # @@ -607,6 +698,8 @@ CONFIG_PPP_BSDCOMP=m # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -632,13 +725,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set - # # Input Device Drivers # @@ -648,6 +734,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -667,7 +759,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -677,6 +768,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_PDC_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set @@ -707,6 +799,11 @@ CONFIG_GEN_RTC_X=y CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + # # I2C support # @@ -717,10 +814,20 @@ CONFIG_MAX_RAW_DEVS=256 # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -742,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=256 CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 +# CONFIG_STI_CONSOLE is not set # # Sound @@ -751,13 +859,9 @@ CONFIG_DUMMY_CONSOLE_ROWS=64 # # USB support # -# CONFIG_USB is not set CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# +# CONFIG_USB is not set # # USB Gadget Support @@ -772,17 +876,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # InfiniBand support # -CONFIG_INFINIBAND=m -CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set -CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y @@ -794,22 +899,20 @@ CONFIG_JFS_FS=m # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y - -# -# XFS support -# CONFIG_XFS_FS=m CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -836,13 +939,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -867,15 +968,18 @@ CONFIG_UFS_FS=m # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -890,6 +994,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -906,15 +1011,15 @@ CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m +# CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set # CONFIG_NLS_CODEPAGE_860 is not set # CONFIG_NLS_CODEPAGE_861 is not set # CONFIG_NLS_CODEPAGE_862 is not set -CONFIG_NLS_CODEPAGE_863=m +# CONFIG_NLS_CODEPAGE_863 is not set # CONFIG_NLS_CODEPAGE_864 is not set -CONFIG_NLS_CODEPAGE_865=m +# CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set # CONFIG_NLS_CODEPAGE_936 is not set @@ -926,10 +1031,10 @@ CONFIG_NLS_CODEPAGE_865=m # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set @@ -950,11 +1055,15 @@ CONFIG_OPROFILE=m # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_IOREMAP is not set @@ -974,25 +1083,26 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y CONFIG_CRYPTO=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_TEST=m @@ -1004,6 +1114,7 @@ CONFIG_CRYPTO_TEST=m # Library routines # CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 46c9511f3229..8819e7e6ae3f 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -1,12 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-pa5 -# Wed Jan 5 13:35:54 2005 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:06:10 2005 # CONFIG_PARISC=y CONFIG_MMU=y CONFIG_STACK_GROWSUP=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Code maturity level options @@ -14,33 +17,39 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_EXPERIMENTAL is not set CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=16 # CONFIG_HOTPLUG is not set CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -60,8 +69,14 @@ CONFIG_PA7100LC=y # CONFIG_PA7300LC is not set # CONFIG_PA8X00 is not set CONFIG_PA11=y -# CONFIG_64BIT is not set # CONFIG_SMP is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_PREEMPT is not set # CONFIG_HPUX is not set @@ -78,11 +93,25 @@ CONFIG_EISA_NAMES=y CONFIG_ISA=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_GSC_DINO=y # CONFIG_PCI_LBA is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# PA-RISC specific drivers +# CONFIG_CHASSIS_LCD_LED=y # CONFIG_PDC_CHASSIS is not set +CONFIG_PDC_STABLE=y # # Executable file formats @@ -90,6 +119,64 @@ CONFIG_CHASSIS_LCD_LED=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -99,8 +186,14 @@ CONFIG_BINFMT_ELF=y # CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -111,10 +204,8 @@ CONFIG_STANDALONE=y # CONFIG_PARPORT=y CONFIG_PARPORT_PC=y -CONFIG_PARPORT_PC_CML1=y # CONFIG_PARPORT_SERIAL is not set CONFIG_PARPORT_GSC=y -# CONFIG_PARPORT_OTHER is not set # CONFIG_PARPORT_1284 is not set # @@ -125,19 +216,17 @@ CONFIG_PARPORT_GSC=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set @@ -149,6 +238,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=y # # ATA/ATAPI/MFM/RLL support @@ -158,6 +248,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -170,6 +261,7 @@ CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -183,16 +275,16 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -202,14 +294,11 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_IN2000 is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_IPS is not set @@ -219,7 +308,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set CONFIG_SCSI_LASI700=y -CONFIG_53C700_MEM_MAPPED=y CONFIG_53C700_LE_ON_BE=y CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 @@ -231,7 +319,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -240,12 +327,12 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set @@ -263,6 +350,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID5=y +CONFIG_MD_RAID6=y # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set # CONFIG_BLK_DEV_DM is not set @@ -271,6 +359,9 @@ CONFIG_MD_RAID5=y # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -283,58 +374,8 @@ CONFIG_MD_RAID5=y # CONFIG_I2O is not set # -# Networking support +# Network device support # -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_NETFILTER is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -346,6 +387,11 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -354,8 +400,8 @@ CONFIG_NET_ETHERNET=y # CONFIG_LASI_82596 is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set @@ -369,6 +415,7 @@ CONFIG_TULIP=y # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_DEPCA is not set # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set @@ -384,12 +431,15 @@ CONFIG_TULIP=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set @@ -413,12 +463,12 @@ CONFIG_NET_RADIO=y # # Wireless 802.11b ISA/PCI cards support # -# CONFIG_AIRO is not set # CONFIG_HERMES is not set # # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # +# CONFIG_HOSTAP is not set CONFIG_NET_WIRELESS=y # @@ -435,6 +485,8 @@ CONFIG_PPP=y # CONFIG_PPP_BSDCOMP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -463,24 +515,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PARKBD is not set -CONFIG_SERIO_GSCPS2=y -# CONFIG_HP_SDC is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y +# CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set @@ -488,7 +529,7 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_HIL_OLD is not set # CONFIG_KEYBOARD_HIL is not set CONFIG_INPUT_MOUSE=y -# CONFIG_MOUSE_PS2 is not set +CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_INPORT is not set # CONFIG_MOUSE_LOGIBM is not set @@ -501,6 +542,19 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_UINPUT is not set # CONFIG_HP_SDC_RTC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_GSCPS2=y +# CONFIG_HP_SDC is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -519,8 +573,11 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_HUB6 is not set # # Non-8250 serial port support @@ -529,6 +586,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_PDC_CONSOLE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -555,10 +613,13 @@ CONFIG_GEN_RTC=y # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -569,10 +630,20 @@ CONFIG_GEN_RTC=y # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -587,6 +658,11 @@ CONFIG_GEN_RTC=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -595,6 +671,7 @@ CONFIG_FB=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -606,18 +683,19 @@ CONFIG_FB_STI=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # -# CONFIG_MDA_CONSOLE is not set -CONFIG_STI_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 -CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_STI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -630,6 +708,7 @@ CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y CONFIG_LOGO_PARISC_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -639,13 +718,9 @@ CONFIG_LOGO_PARISC_CLUT224=y # # USB support # -# CONFIG_USB is not set CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# +# CONFIG_USB is not set # # USB Gadget Support @@ -657,24 +732,37 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # CONFIG_MMC is not set +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -697,11 +785,10 @@ CONFIG_JOLIET=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -719,15 +806,19 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -785,13 +876,19 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set +# CONFIG_DEBUG_FS is not set # # Security options @@ -815,6 +912,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set @@ -831,9 +929,14 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set +# +# Hardware crypto devices +# + # # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index 67aca6ccc9b0..9d86b6b1ebd1 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -1,12 +1,16 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-pa5 -# Wed Jan 5 13:26:49 2005 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:06:31 2005 # CONFIG_PARISC=y CONFIG_MMU=y CONFIG_STACK_GROWSUP=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y # # Code maturity level options @@ -15,26 +19,31 @@ CONFIG_EXPERIMENTAL=y # CONFIG_CLEAN_COMPILE is not set CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=16 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +53,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -66,10 +76,19 @@ CONFIG_KMOD=y CONFIG_PA8X00=y CONFIG_PA20=y CONFIG_PREFETCH=y -# CONFIG_PARISC64 is not set # CONFIG_64BIT is not set # CONFIG_SMP is not set -# CONFIG_DISCONTIGMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_PREEMPT is not set # CONFIG_HPUX is not set @@ -79,34 +98,215 @@ CONFIG_PREFETCH=y # CONFIG_GSC is not set CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_PCI_LBA=y CONFIG_IOSAPIC=y CONFIG_IOMMU_SBA=y -CONFIG_SUPERIO=y -CONFIG_CHASSIS_LCD_LED=y -# CONFIG_PDC_CHASSIS is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # # CONFIG_HOTPLUG_PCI is not set +# +# PA-RISC specific drivers +# +CONFIG_SUPERIO=y +CONFIG_CHASSIS_LCD_LED=y +# CONFIG_PDC_CHASSIS is not set +CONFIG_PDC_STABLE=y + # # Executable file formats # CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +CONFIG_NETFILTER_DEBUG=y +# CONFIG_NETFILTER_NETLINK is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_PPTP is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_DCCP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +# CONFIG_IP_NF_MATCH_STRING is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_LIMIT is not set +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_MULTIPORT is not set +CONFIG_IP6_NF_MATCH_OWNER=m +# CONFIG_IP6_NF_MATCH_MARK is not set +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_AHESP is not set +CONFIG_IP6_NF_MATCH_LENGTH=m +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_NFQUEUE is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_TARGET_MARK is not set +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_RAW is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -119,6 +319,11 @@ CONFIG_BINFMT_ELF=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -141,14 +346,14 @@ CONFIG_FW_LOADER=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set # @@ -158,6 +363,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -201,6 +407,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set CONFIG_BLK_DEV_NS87415=y # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -218,6 +425,7 @@ CONFIG_BLK_DEV_IDEDMA=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -230,6 +438,7 @@ CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -242,7 +451,9 @@ CONFIG_SCSI_MULTI_LUN=y # SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -258,25 +469,26 @@ CONFIG_SCSI_FC_ATTRS=m # CONFIG_SCSI_ADVANSYS is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set CONFIG_SCSI_SATA=y # CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=m +# CONFIG_SCSI_SATA_MV is not set # CONFIG_SCSI_SATA_NV is not set CONFIG_SCSI_SATA_PROMISE=m +# CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_SX4 is not set CONFIG_SCSI_SATA_SIL=m # CONFIG_SCSI_SATA_SIS is not set # CONFIG_SCSI_SATA_ULI is not set CONFIG_SCSI_SATA_VIA=m # CONFIG_SCSI_SATA_VITESSE is not set -# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_SATA_INTEL_COMBINED=y # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -286,20 +498,17 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set -CONFIG_SCSI_QLOGIC_FC=m -# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set -CONFIG_SCSI_QLOGIC_1280=m -# CONFIG_SCSI_QLOGIC_1280_1040 is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA21XX is not set # CONFIG_SCSI_QLA22XX is not set -CONFIG_SCSI_QLA2300=m -CONFIG_SCSI_QLA2322=m -CONFIG_SCSI_QLA6312=m -CONFIG_SCSI_QLA6322=m +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -316,19 +525,24 @@ CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set # CONFIG_MD_RAID5 is not set # CONFIG_MD_RAID6 is not set -CONFIG_MD_MULTIPATH=y +# CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_EMC is not set # # Fusion MPT device support # -CONFIG_FUSION=m -CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set +CONFIG_FUSION_MAX_SGE=128 CONFIG_FUSION_CTL=m # @@ -342,164 +556,32 @@ CONFIG_FUSION_CTL=m # CONFIG_I2O is not set # -# Networking support +# Network device support # -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_CT_ACCT is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_REALM is not set -# CONFIG_IP_NF_MATCH_SCTP is not set -# CONFIG_IP_NF_MATCH_COMMENT is not set -# CONFIG_IP_NF_MATCH_HASHLIMIT is not set -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -# CONFIG_IP_NF_RAW is not set -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_COMPAT_IPFWADM=m -CONFIG_XFRM=y -CONFIG_XFRM_USER=m - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -CONFIG_LLC=m -CONFIG_LLC2=m -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_BONDING=m # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_ETHERTAP is not set # # ARCnet devices # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y CONFIG_MII=m -CONFIG_HAPPYMEAL=m +# CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # @@ -514,28 +596,22 @@ CONFIG_TULIP_MMIO=y # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y -CONFIG_PCNET32=m +# CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set -CONFIG_ADAPTEC_STARFIRE=m -# CONFIG_ADAPTEC_STARFIRE_NAPI is not set -CONFIG_B44=m +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set +# CONFIG_EEPRO100 is not set CONFIG_E100=m -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set -CONFIG_NATSEMI=m +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139CP is not set -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_8139TOO is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -554,15 +630,18 @@ CONFIG_E1000=m # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=m +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # -CONFIG_IXGB=y -CONFIG_IXGB_NAPI=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set # CONFIG_S2IO is not set # @@ -593,6 +672,8 @@ CONFIG_PPPOE=m # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -621,16 +702,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=m -CONFIG_SERIO_SERPORT=m -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -648,6 +719,16 @@ CONFIG_INPUT_MOUSE=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=m +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=m +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -666,7 +747,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -676,6 +756,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_PDC_CONSOLE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -698,11 +779,15 @@ CONFIG_GEN_RTC_X=y # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + # # I2C support # @@ -713,10 +798,20 @@ CONFIG_MAX_RAW_DEVS=256 # # CONFIG_W1 is not set +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -731,6 +826,11 @@ CONFIG_MAX_RAW_DEVS=256 # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -739,6 +839,7 @@ CONFIG_FB=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -751,18 +852,20 @@ CONFIG_FB_STI=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # -CONFIG_STI_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 -CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_STI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -775,6 +878,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_LOGO_PARISC_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -784,7 +888,78 @@ CONFIG_SOUND=y # # Advanced Linux Sound Architecture # -# CONFIG_SND is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_AD1889=y +# CONFIG_SND_AD1889_OPL3 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set # # Open Sound System @@ -794,6 +969,8 @@ CONFIG_SOUND=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y CONFIG_USB_DEBUG=y @@ -804,23 +981,23 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers # # CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # -# CONFIG_USB_AUDIO is not set +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set # CONFIG_USB_ACM is not set CONFIG_USB_PRINTER=m @@ -829,12 +1006,11 @@ CONFIG_USB_PRINTER=m # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_USBAT=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y @@ -846,21 +1022,25 @@ CONFIG_USB_HID=y CONFIG_USB_HIDINPUT=y # CONFIG_HID_FF is not set CONFIG_USB_HIDDEV=y -CONFIG_USB_AIPTEK=m -CONFIG_USB_WACOM=m -CONFIG_USB_KBTAB=m +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m # # USB Multimedia devices @@ -879,6 +1059,7 @@ CONFIG_USB_HPUSBSCSI=m # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_MON is not set # # USB port drivers @@ -894,7 +1075,6 @@ CONFIG_USB_HPUSBSCSI=m # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set CONFIG_USB_LEGOTOWER=m @@ -903,10 +1083,12 @@ CONFIG_USB_LEGOTOWER=m # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -919,28 +1101,42 @@ CONFIG_USB_LEGOTOWER=m # # CONFIG_MMC is not set +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m -# CONFIG_XFS_RT is not set +CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -966,13 +1162,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -996,16 +1190,19 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -1014,6 +1211,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1074,13 +1272,19 @@ CONFIG_OPROFILE=m # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set +# CONFIG_DEBUG_FS is not set # # Security options @@ -1092,21 +1296,22 @@ CONFIG_MAGIC_SYSRQ=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_HMAC is not set CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m +# CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set # CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_KHAZAD is not set @@ -1116,10 +1321,15 @@ CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_TEST=m +# +# Hardware crypto devices +# + # # Library routines # CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index fdae21c503d7..f38a4620d24f 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig @@ -1,38 +1,56 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:01:33 2005 # CONFIG_PARISC=y CONFIG_MMU=y CONFIG_STACK_GROWSUP=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_AUDIT is not set # CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -45,10 +63,21 @@ CONFIG_IOSCHED_DEADLINE=y CONFIG_PA7000=y # CONFIG_PA7100LC is not set # CONFIG_PA7200 is not set +# CONFIG_PA7300LC is not set # CONFIG_PA8X00 is not set CONFIG_PA11=y -# CONFIG_64BIT is not set # CONFIG_SMP is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_PREEMPT is not set # CONFIG_HPUX is not set @@ -65,14 +94,29 @@ CONFIG_EISA_NAMES=y # CONFIG_ISA is not set CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_GSC_DINO=y CONFIG_PCI_LBA=y CONFIG_IOSAPIC=y CONFIG_IOMMU_SBA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# PA-RISC specific drivers +# CONFIG_SUPERIO=y CONFIG_CHASSIS_LCD_LED=y CONFIG_PDC_CHASSIS=y +CONFIG_PDC_STABLE=y # # Executable file formats @@ -80,6 +124,80 @@ CONFIG_PDC_CHASSIS=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -87,8 +205,16 @@ CONFIG_BINFMT_ELF=y # # Generic Driver Options # +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + # # Memory Technology Devices (MTD) # @@ -99,12 +225,10 @@ CONFIG_BINFMT_ELF=y # CONFIG_PARPORT=y CONFIG_PARPORT_PC=y -CONFIG_PARPORT_PC_CML1=y # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set CONFIG_PARPORT_GSC=y -# CONFIG_PARPORT_OTHER is not set # CONFIG_PARPORT_1284 is not set # @@ -114,18 +238,31 @@ CONFIG_PARPORT_GSC=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -135,6 +272,7 @@ CONFIG_BLK_DEV_INITRD=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -147,53 +285,59 @@ CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + # # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set CONFIG_SCSI_LASI700=y -CONFIG_53C700_MEM_MAPPED=y CONFIG_53C700_LE_ON_BE=y CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set CONFIG_SCSI_ZALON=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -202,7 +346,8 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -217,15 +362,20 @@ CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set CONFIG_MD_RAID5=y # CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set # CONFIG_BLK_DEV_DM is not set # # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -238,80 +388,23 @@ CONFIG_MD_RAID5=y # CONFIG_I2O is not set # -# Macintosh device drivers +# Network device support # - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -321,6 +414,7 @@ CONFIG_NET_ETHERNET=y CONFIG_LASI_82596=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_SMC is not set @@ -336,6 +430,7 @@ CONFIG_TULIP=y # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_DEPCA is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y @@ -361,30 +456,37 @@ CONFIG_NET_PCI=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -CONFIG_DL2K=y +CONFIG_ACENIC=y +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set # CONFIG_SIS190 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_TIGON3=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -399,38 +501,30 @@ CONFIG_NET_RADIO=y # # Wireless 802.11b ISA/PCI cards support # -CONFIG_AIRO=y # CONFIG_HERMES is not set # CONFIG_ATMEL is not set -CONFIG_NET_WIRELESS=y # -# Token Ring devices +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y # # Wan interfaces # # CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -460,10 +554,56 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_HIL_OLD=y +CONFIG_KEYBOARD_HIL=y +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_HIL is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +CONFIG_HP_SDC_RTC=y + +# +# Hardware I/O ports # -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_PARKBD is not set @@ -471,38 +611,8 @@ CONFIG_SERIO_GSCPS2=y CONFIG_HP_SDC=y CONFIG_HIL_MLC=y # CONFIG_SERIO_PCIPS2 is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_KEYBOARD_HIL=y -CONFIG_INPUT_MOUSE=y -# CONFIG_MOUSE_PS2 is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_HIL is not set -CONFIG_INPUT_JOYSTICK=y -# CONFIG_JOYSTICK_IFORCE is not set -# CONFIG_JOYSTICK_WARRIOR is not set -# CONFIG_JOYSTICK_MAGELLAN is not set -# CONFIG_JOYSTICK_SPACEORB is not set -# CONFIG_JOYSTICK_SPACEBALL is not set -# CONFIG_JOYSTICK_STINGER is not set -# CONFIG_JOYSTICK_TWIDDLER is not set -# CONFIG_JOYSTICK_DB9 is not set -# CONFIG_JOYSTICK_GAMECON is not set -# CONFIG_JOYSTICK_TURBOGRAFX is not set -# CONFIG_INPUT_JOYDUMP is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_GUNZE is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_PCSPKR is not set -# CONFIG_INPUT_UINPUT is not set -CONFIG_HP_SDC_RTC=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set # # Character devices @@ -522,16 +632,16 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # # Non-8250 serial port support # -# CONFIG_SERIAL_MUX is not set -# CONFIG_PDC_CONSOLE is not set +CONFIG_SERIAL_MUX=y +CONFIG_SERIAL_MUX_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -540,12 +650,6 @@ CONFIG_PRINTER=y # CONFIG_PPDEV is not set # CONFIG_TIPAR is not set -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_QIC02_TAPE is not set - # # IPMI # @@ -555,7 +659,6 @@ CONFIG_PRINTER=y # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -565,20 +668,39 @@ CONFIG_GEN_RTC=y # # Ftape, the floppy tape device driver # -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + # # I2C support # # CONFIG_I2C is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -593,34 +715,45 @@ CONFIG_GEN_RTC=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # -# CONFIG_MDA_CONSOLE is not set -CONFIG_STI_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 -CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_PCI_CONSOLE=y +CONFIG_STI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -629,6 +762,7 @@ CONFIG_FONT_8x16=y # Logo configuration # # CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -638,17 +772,94 @@ CONFIG_SOUND=y # # Advanced Linux Sound Architecture # -# CONFIG_SND is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_AD1889=y +# CONFIG_SND_AD1889_OPL3 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# GSC devices +# +CONFIG_SND_HARMONY=y # # Open Sound System # # CONFIG_SOUND_PRIME is not set -# CONFIG_SOUND_HARMONY is not set # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y CONFIG_USB_DEBUG=y @@ -658,26 +869,36 @@ CONFIG_USB_DEBUG=y # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set # # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # -# CONFIG_USB_AUDIO is not set +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# # CONFIG_USB_STORAGE is not set # -# USB Human Interface Devices (HID) +# USB Input Devices # # CONFIG_USB_HID is not set @@ -688,16 +909,23 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -709,13 +937,15 @@ CONFIG_USB_OHCI_HCD=y # # -# USB Network adaptors +# USB Network Adapters # # CONFIG_USB_CATC is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_MON=y # # USB port drivers @@ -732,35 +962,63 @@ CONFIG_USB_OHCI_HCD=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set + +# +# USB DSL modem support +# # # USB Gadget Support # # CONFIG_USB_GADGET is not set +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -773,7 +1031,8 @@ CONFIG_JOLIET=y # # DOS/FAT/NT Filesystems # -# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -781,11 +1040,11 @@ CONFIG_JOLIET=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -809,23 +1068,28 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_GSS is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -861,6 +1125,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -885,17 +1150,24 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SLAB is not set CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_RWLOCK is not set -CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set +# CONFIG_DEBUG_FS is not set # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # @@ -909,6 +1181,8 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set @@ -916,11 +1190,23 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_AES is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set +# +# Hardware crypto devices +# + # # Library routines # +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set From 6958ae318bb1af5e0b77968384700fb184fb8893 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 23:11:27 -0400 Subject: [PATCH 0422/1940] [PARISC] Update MAINTAINERS and CREDITS Add Kyle McMartin and Thibaut Varene as maintainers for ALSA ad1889 driver. Add myself to CREDITS. Signed-off-by: Kyle McMartin --- CREDITS | 6 ++++++ MAINTAINERS | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/CREDITS b/CREDITS index a347520bef2d..5b1edf3a38a2 100644 --- a/CREDITS +++ b/CREDITS @@ -2247,6 +2247,12 @@ S: 249 Nichols Avenue S: Syracuse, New York 13206 S: USA +N: Kyle McMartin +E: kyle@parisc-linux.org +D: Linux/PARISC hacker +D: AD1889 sound driver +S: Ottawa, Canada + N: Dirk Melchers E: dirk@merlin.nbg.sub.org D: 8 bit XT hard disk driver for OMTI5520 diff --git a/MAINTAINERS b/MAINTAINERS index 767fb610963e..248b93b32fc4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -197,6 +197,15 @@ M: Thorsten Knabe W: http://linux.thorsten-knabe.de S: Maintained +AD1889 SOUND DRIVER +P: Kyle McMartin +M: kyle@parisc-linux.org +P: Thibaut Varene +M: T-Bone@parisc-linux.org +W: http://wiki.parisc-linux.org/AD1889 +L: parisc-linux@lists.parisc-linux.org +S: Maintained + ADM1025 HARDWARE MONITOR DRIVER P: Jean Delvare M: khali@linux-fr.org From 2d5a2ae52d8863275e2d26398bc010249ea709d1 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 22 Oct 2005 00:14:31 -0400 Subject: [PATCH 0423/1940] drivers/block/sx8: several minor changes * Newer hardware doesn't corrupt data when the queue depth is greater than one. Rather than force the user to recompile with a greater queue depth, make it a module parameter. * update copyright date * add MODULE_VERSION() * trim trailing whitespace * move CARM_SG_BOUNDARY to a separate enum, since its unsigned long * bump to version 1.0 --- drivers/block/sx8.c | 50 +++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index d57007b92f77..b5f612679a31 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -1,7 +1,7 @@ /* * sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware * - * Copyright 2004 Red Hat, Inc. + * Copyright 2004-2005 Red Hat, Inc. * * Author/maintainer: Jeff Garzik * @@ -31,10 +31,6 @@ #include #include -MODULE_AUTHOR("Jeff Garzik"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Promise SATA SX8 block driver"); - #if 0 #define CARM_DEBUG #define CARM_VERBOSE_DEBUG @@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver"); #undef CARM_NDEBUG #define DRV_NAME "sx8" -#define DRV_VERSION "0.8" +#define DRV_VERSION "1.0" #define PFX DRV_NAME ": " +MODULE_AUTHOR("Jeff Garzik"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Promise SATA SX8 block driver"); +MODULE_VERSION(DRV_VERSION); + +/* + * SX8 hardware has a single message queue for all ATA ports. + * When this driver was written, the hardware (firmware?) would + * corrupt data eventually, if more than one request was outstanding. + * As one can imagine, having 8 ports bottlenecking on a single + * command hurts performance. + * + * Based on user reports, later versions of the hardware (firmware?) + * seem to be able to survive with more than one command queued. + * + * Therefore, we default to the safe option -- 1 command -- but + * allow the user to increase this. + * + * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ), + * but problems seem to occur when you exceed ~30, even on newer hardware. + */ +static int max_queue = 1; +module_param(max_queue, int, 0444); +MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)"); + + #define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN) /* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */ @@ -90,12 +112,10 @@ enum { /* command message queue limits */ CARM_MAX_REQ = 64, /* max command msgs per host */ - CARM_MAX_Q = 1, /* one command at a time */ CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */ /* S/G limits, host-wide and per-request */ CARM_MAX_REQ_SG = 32, /* max s/g entries per request */ - CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ CARM_MAX_HOST_SG = 600, /* max s/g entries per host */ CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */ @@ -181,6 +201,10 @@ enum { FL_DYN_MAJOR = (1 << 17), }; +enum { + CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ +}; + enum scatter_gather_types { SGT_32BIT = 0, SGT_64BIT = 1, @@ -448,7 +472,7 @@ static inline int carm_lookup_bucket(u32 msg_size) for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) if (msg_size <= msg_sizes[i]) return i; - + return -ENOENT; } @@ -509,7 +533,7 @@ static struct carm_request *carm_get_request(struct carm_host *host) if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) return NULL; - for (i = 0; i < CARM_MAX_Q; i++) + for (i = 0; i < max_queue; i++) if ((host->msg_alloc & (1ULL << i)) == 0) { struct carm_request *crq = &host->req[i]; crq->port = NULL; @@ -521,14 +545,14 @@ static struct carm_request *carm_get_request(struct carm_host *host) assert(host->n_msgs <= CARM_MAX_REQ); return crq; } - + DPRINTK("no request available, returning NULL\n"); return NULL; } static int carm_put_request(struct carm_host *host, struct carm_request *crq) { - assert(crq->tag < CARM_MAX_Q); + assert(crq->tag < max_queue); if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) return -EINVAL; /* tried to clear a tag that was not active */ @@ -791,7 +815,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, int is_ok) { carm_end_request_queued(host, crq, is_ok); - if (CARM_MAX_Q == 1) + if (max_queue == 1) carm_round_robin(host); else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && (host->hw_sg_used <= CARM_SG_LOW_WATER)) { From 5c8c56ebdfb290e4feaac406518903f58714d874 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 14:42:51 +1000 Subject: [PATCH 0424/1940] powerpc: Move agp_special_page export to where it is defined ... instead of exporting it in arch/*/kernel/ppc_ksyms.c. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/ppc_ksyms.c | 4 ---- arch/powerpc/mm/init_32.c | 1 + arch/ppc/kernel/ppc_ksyms.c | 4 ---- arch/ppc/mm/init.c | 1 + 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 40c9e67e1b28..254bf9c0b5bb 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -274,10 +274,6 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); #endif /* CONFIG_PPC_STD_MMU_32 */ -#ifdef CONFIG_PPC_PMAC -extern unsigned long agp_special_page; -EXPORT_SYMBOL(agp_special_page); -#endif #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) EXPORT_SYMBOL(__mtdcr); EXPORT_SYMBOL(__mfdcr); diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index caeb02ee72c5..aa6a5440cec1 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -69,6 +69,7 @@ unsigned long ppc_memoffset = PAGE_OFFSET; int boot_mapsize; #ifdef CONFIG_PPC_PMAC unsigned long agp_special_page; +EXPORT_SYMBOL(agp_special_page); #endif #ifdef CONFIG_HIGHMEM diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index f4373fb9181f..dcc83440f203 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -323,10 +323,6 @@ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); #endif /* CONFIG_PPC_STD_MMU */ EXPORT_SYMBOL(cur_cpu_spec); -#ifdef CONFIG_PPC_PMAC -extern unsigned long agp_special_page; -EXPORT_SYMBOL(agp_special_page); -#endif #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) EXPORT_SYMBOL(__mtdcr); EXPORT_SYMBOL(__mfdcr); diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 5e9ef23b4671..db94efd25369 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -69,6 +69,7 @@ int init_bootmem_done; int boot_mapsize; #ifdef CONFIG_PPC_PMAC unsigned long agp_special_page; +EXPORT_SYMBOL(agp_special_page); #endif extern char _end[]; From e2b5530698cbe8148577b24097eaefcd835ac9ca Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 14:46:33 +1000 Subject: [PATCH 0425/1940] ppc64: Fix delivery of RT signals to 32-bit processes. An error in merging led to 32-bit processes getting the wrong link register value on entry to RT signal handlers, and the wrong stack chain as well. This fixes it. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/signal_32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 1c4eac4c808f..92452b2db26a 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -821,7 +821,7 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, goto badframe; regs->link = (unsigned long) frame->tramp; } - if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) + if (put_user(regs->gpr[1], (u32 __user *)newsp)) goto badframe; regs->gpr[1] = newsp; regs->gpr[3] = sig; @@ -829,7 +829,6 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; - regs->link = (unsigned long) frame->tramp; regs->trap = 0; #ifdef CONFIG_PPC64 regs->result = 0; From a5b518ed314bfd25ea5e433ce09f8b27080023db Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 14:55:23 +1000 Subject: [PATCH 0426/1940] ppc64/powerpc: Fix time initialization on SMP systems This moves smp_space_timers from arch/ppc64/kernel/smp.c to arch/powerpc/kernel/time.c and makes it initialize last_jiffy[] instead of paca[].next_jiffy_update_tb, since last_jiffy[] is now what the time code uses. It also declares smp_space_timers in include/asm-powerpc/time.h and gets rid of an ifdef in div128_by_32. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 14 +------------- arch/ppc64/kernel/smp.c | 15 --------------- include/asm-powerpc/time.h | 8 +++++--- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 3e722370113b..b635c7de6698 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -458,7 +458,7 @@ void wakeup_decrementer(void) per_cpu(last_jiffy, i) = tb_last_stamp; } -#ifdef CONFIG_SMPxxx +#ifdef CONFIG_SMP void __init smp_space_timers(unsigned int max_cpus) { int i; @@ -948,16 +948,6 @@ void div128_by_32(u64 dividend_high, u64 dividend_low, w = a / divisor; ra = ((u64)(a - (w * divisor)) << 32) + b; -#ifdef CONFIG_PPC64 - x = ra / divisor; - rb = ((ra - (x * divisor)) << 32) + c; - - y = rb / divisor; - rc = ((rb - (y * divisor)) << 32) + d; - - z = rc / divisor; -#else - /* for 32-bit, use do_div from div64.h */ rb = ((u64) do_div(ra, divisor) << 32) + c; x = ra; @@ -966,10 +956,8 @@ void div128_by_32(u64 dividend_high, u64 dividend_low, do_div(rc, divisor); z = rc; -#endif dr->result_high = ((u64)w << 32) + x; dr->result_low = ((u64)y << 32) + z; } - diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 192e3239fadc..017c12919832 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -105,21 +105,6 @@ void __devinit smp_generic_kick_cpu(int nr) #endif /* CONFIG_MPIC */ -static void __init smp_space_timers(unsigned int max_cpus) -{ - int i; - unsigned long offset = tb_ticks_per_jiffy / max_cpus; - unsigned long previous_tb = paca[boot_cpuid].next_jiffy_update_tb; - - for_each_cpu(i) { - if (i != boot_cpuid) { - paca[i].next_jiffy_update_tb = - previous_tb + offset; - previous_tb = paca[i].next_jiffy_update_tb; - } - } -} - void smp_message_recv(int msg, struct pt_regs *regs) { switch(msg) { diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index f8ef186c81e4..99bfe3281768 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -196,9 +196,11 @@ static inline unsigned long tb_ticks_since(unsigned long tstamp) extern u64 mulhdu(u64, u64); #endif -unsigned mulhwu_scale_factor(unsigned, unsigned); -void div128_by_32(u64 dividend_high, u64 dividend_low, - unsigned divisor, struct div_result *dr); +extern void smp_space_timers(unsigned int); + +extern unsigned mulhwu_scale_factor(unsigned, unsigned); +extern void div128_by_32(u64 dividend_high, u64 dividend_low, + unsigned divisor, struct div_result *dr); /* Used to store Processor Utilization register (purr) values */ From f7abbc190b0edec34627d5348ba1d5fa5577da77 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 15:03:21 +1000 Subject: [PATCH 0427/1940] ppc64: Add a `primary' argument to pci_process_bridge_OF_ranges ... for consistency with ppc32 and to make the powermac merge easier. Also make it use just a single resource in the host bridge for multiple consecutive elements of the ranges property. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/maple_pci.c | 2 +- arch/ppc64/kernel/pci.c | 38 +++++++++++++++++++++++++++------- arch/ppc64/kernel/rtas_pci.c | 4 ++-- include/asm-ppc64/pci-bridge.h | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c index b901470f55cc..633324b5e61b 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/ppc64/kernel/maple_pci.c @@ -359,7 +359,7 @@ static int __init add_bridge(struct device_node *dev) /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(hose, dev); + pci_process_bridge_OF_ranges(hose, dev, primary); pci_setup_phb_io(hose, primary); /* Fixup "bus-range" OF property */ diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index feec06bbafc3..b2fb6746f00b 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -880,9 +880,9 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, } void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev) + struct device_node *dev, int prim) { - unsigned int *ranges; + unsigned int *ranges, pci_space; unsigned long size; int rlen = 0; int memno = 0; @@ -905,16 +905,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, ranges = (unsigned int *) get_property(dev, "ranges", &rlen); while ((rlen -= np * sizeof(unsigned int)) >= 0) { res = NULL; - pci_addr = (unsigned long)ranges[1] << 32 | ranges[2]; + pci_space = ranges[0]; + pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; cpu_phys_addr = ranges[3]; - if (na == 2) - cpu_phys_addr = cpu_phys_addr << 32 | ranges[4]; + if (na >= 2) + cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4]; - size = (unsigned long)ranges[na+3] << 32 | ranges[na+4]; + size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; + ranges += np; if (size == 0) continue; - switch ((ranges[0] >> 24) & 0x3) { + + /* Now consume following elements while they are contiguous */ + while (rlen >= np * sizeof(unsigned int)) { + unsigned long addr, phys; + + if (ranges[0] != pci_space) + break; + addr = ((unsigned long)ranges[1] << 32) | ranges[2]; + phys = ranges[3]; + if (na >= 2) + phys = (phys << 32) | ranges[4]; + if (addr != pci_addr + size || + phys != cpu_phys_addr + size) + break; + + size += ((unsigned long)ranges[na+3] << 32) + | ranges[na+4]; + ranges += np; + rlen -= np * sizeof(unsigned int); + } + + switch ((pci_space >> 24) & 0x3) { case 1: /* I/O space */ hose->io_base_phys = cpu_phys_addr; hose->pci_io_size = size; @@ -948,7 +971,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, res->sibling = NULL; res->child = NULL; } - ranges += np; } } diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c index 20361bcd8cfb..3ad15c90fbbd 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/ppc64/kernel/rtas_pci.c @@ -400,7 +400,7 @@ unsigned long __init find_and_init_phbs(void) if (!phb) continue; - pci_process_bridge_OF_ranges(phb, node); + pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); #ifdef CONFIG_PPC_PSERIES if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { @@ -450,7 +450,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) if (!phb) return NULL; - pci_process_bridge_OF_ranges(phb, dn); + pci_process_bridge_OF_ranges(phb, dn, primary); pci_setup_phb_io_dynamic(phb, primary); of_node_put(root); diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 7d8ecb507a3d..60cf8c838af0 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -123,7 +123,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) } extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev); + struct device_node *dev, int primary); extern int pcibios_remove_root_bus(struct pci_controller *phb); From 5fb4dc9bf5e3af1ae91be97108bc3b1233252ddf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 22 Oct 2005 15:25:01 +1000 Subject: [PATCH 0428/1940] merge linus head to drm-mm branch --- drivers/char/drm/drm_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index e84a7876a1b3..3f73aa774c80 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c @@ -155,7 +155,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; page = (map->type == _DRM_CONSISTENT) ? - virt_to_page((void *)i) : vmalloc_to_page((void *)i); + virt_to_page((void *)i) : vmalloc_to_page((void *)i); if (!page) return NOPAGE_OOM; get_page(page); From 7bbaa75452c77cbaa016b987765c5d6c8b744587 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 22 Oct 2005 01:33:18 -0400 Subject: [PATCH 0429/1940] drivers/block/sx8: kill unused variable --- drivers/block/sx8.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index b5f612679a31..1ded3b433459 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -242,7 +242,6 @@ static const char *state_name[] = { struct carm_port { unsigned int port_no; - unsigned int n_queued; struct gendisk *disk; struct carm_host *host; From 529294d59fdc77bf15f00f2308bbeb73e03e7042 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 15:36:52 +1000 Subject: [PATCH 0430/1940] ppc64: Rearrange btext initialization for consistency with ppc32 Moved init_boot_display from arch/ppc64/kernel/pmac_setup.c to arch/ppc64/kernel/btext.c and declared it in asm-ppc64/btext.h. Call it from init_early rather than pmac_init_early. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/btext.c | 42 +++++++++++++++++++++++++++++ arch/ppc64/kernel/pmac_setup.c | 49 ---------------------------------- arch/ppc64/kernel/setup.c | 4 +++ include/asm-ppc64/btext.h | 1 + 4 files changed, 47 insertions(+), 49 deletions(-) diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c index b6fbfbe9032d..506a37885c5c 100644 --- a/arch/ppc64/kernel/btext.c +++ b/arch/ppc64/kernel/btext.c @@ -18,6 +18,7 @@ #include #include #include +#include #undef NO_SCROLL @@ -131,6 +132,47 @@ int btext_initialize(struct device_node *np) return 0; } +static void btext_putc(unsigned char c) +{ + btext_drawchar(c); +} + +void __init init_boot_display(void) +{ + char *name; + struct device_node *np = NULL; + int rc = -ENODEV; + + printk("trying to initialize btext ...\n"); + + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + if (name != NULL) { + np = of_find_node_by_path(name); + if (np != NULL) { + if (strcmp(np->type, "display") != 0) { + printk("boot stdout isn't a display !\n"); + of_node_put(np); + np = NULL; + } + } + } + if (np) + rc = btext_initialize(np); + if (rc) { + for (np = NULL; (np = of_find_node_by_type(np, "display"));) { + if (get_property(np, "linux,opened", NULL)) { + printk("trying %s ...\n", np->full_name); + rc = btext_initialize(np); + printk("result: %d\n", rc); + } + if (rc == 0) + break; + } + } + if (rc == 0 && udbg_putc == NULL) + udbg_putc = btext_putc; +} + /* Calc the base address of a given point (x,y) */ static unsigned char * calc_base(int x, int y) diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index c059805d8cce..c3ea73df937d 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -274,48 +274,6 @@ static void pmac_halt(void) pmac_power_off(); } -#ifdef CONFIG_BOOTX_TEXT -static void btext_putc(unsigned char c) -{ - btext_drawchar(c); -} - -static void __init init_boot_display(void) -{ - char *name; - struct device_node *np = NULL; - int rc = -ENODEV; - - printk("trying to initialize btext ...\n"); - - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (name != NULL) { - np = of_find_node_by_path(name); - if (np != NULL) { - if (strcmp(np->type, "display") != 0) { - printk("boot stdout isn't a display !\n"); - of_node_put(np); - np = NULL; - } - } - } - if (np) - rc = btext_initialize(np); - if (rc == 0) - return; - - for (np = NULL; (np = of_find_node_by_type(np, "display"));) { - if (get_property(np, "linux,opened", NULL)) { - printk("trying %s ...\n", np->full_name); - rc = btext_initialize(np); - printk("result: %d\n", rc); - } - if (rc == 0) - return; - } -} -#endif /* CONFIG_BOOTX_TEXT */ - /* * Early initialization. */ @@ -333,13 +291,6 @@ static void __init pmac_init_early(void) sccdbg = 1; udbg_init_scc(NULL); } -#ifdef CONFIG_BOOTX_TEXT - else { - init_boot_display(); - - udbg_putc = btext_putc; - } -#endif /* CONFIG_BOOTX_TEXT */ /* Setup interrupt mapping options */ ppc64_interrupt_controller = IC_OPEN_PIC; diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index b7885028fcf1..44ee6ebe9a60 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -585,6 +585,10 @@ void __init setup_system(void) */ finish_device_tree(); +#ifdef CONFIG_BOOTX_TEXT + init_boot_display(); +#endif + /* * Initialize xmon */ diff --git a/include/asm-ppc64/btext.h b/include/asm-ppc64/btext.h index 67aef0cc72c0..71cce36bc630 100644 --- a/include/asm-ppc64/btext.h +++ b/include/asm-ppc64/btext.h @@ -15,6 +15,7 @@ extern int boot_text_mapped; extern int btext_initialize(struct device_node *np); extern void map_boot_text(void); +extern void init_boot_display(void); extern void btext_update_display(unsigned long phys, int width, int height, int depth, int pitch); From ef1a12817aebc313049d226f96eee86e4bcc94a3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 15:55:58 +1000 Subject: [PATCH 0431/1940] ppc64: Simplify secondary CPU startup on powermacs ... for consistency with ppc32, and because this way is neater. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/head.S | 25 +++++++++++-------------- arch/ppc64/kernel/pmac_smp.c | 21 ++++----------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 15c5f0c48043..f58af9c246cb 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1556,20 +1556,17 @@ copy_to_here: .section ".text"; .align 2 ; - .globl pmac_secondary_start_1 -pmac_secondary_start_1: - li r24, 1 - b .pmac_secondary_start - - .globl pmac_secondary_start_2 -pmac_secondary_start_2: - li r24, 2 - b .pmac_secondary_start - - .globl pmac_secondary_start_3 -pmac_secondary_start_3: - li r24, 3 - b .pmac_secondary_start + .globl __secondary_start_pmac_0 +__secondary_start_pmac_0: + /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ + li r24,0 + b 1f + li r24,1 + b 1f + li r24,2 + b 1f + li r24,3 +1: _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c index 3a1683f5b07f..83c2f8dc1ec6 100644 --- a/arch/ppc64/kernel/pmac_smp.c +++ b/arch/ppc64/kernel/pmac_smp.c @@ -59,9 +59,7 @@ #define DBG(fmt...) #endif -extern void pmac_secondary_start_1(void); -extern void pmac_secondary_start_2(void); -extern void pmac_secondary_start_3(void); +extern void __secondary_start_pmac_0(void); extern struct smp_ops_t *smp_ops; @@ -236,7 +234,7 @@ static int __init smp_core99_probe(void) static void __init smp_core99_kick_cpu(int nr) { - int save_vector, j; + unsigned int save_vector, j; unsigned long new_vector; unsigned long flags; volatile unsigned int *vector @@ -253,20 +251,9 @@ static void __init smp_core99_kick_cpu(int nr) save_vector = *vector; /* Setup fake reset vector that does - * b .pmac_secondary_start - KERNELBASE + * b __secondary_start_pmac_0 + nr*8 - KERNELBASE */ - switch(nr) { - case 1: - new_vector = (unsigned long)pmac_secondary_start_1; - break; - case 2: - new_vector = (unsigned long)pmac_secondary_start_2; - break; - case 3: - default: - new_vector = (unsigned long)pmac_secondary_start_3; - break; - } + new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; *vector = 0x48000002 + (new_vector - KERNELBASE); /* flush data cache and inval instruction cache */ From b6ba92819dc1304a4e5a0bf06b297c657b58168a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 15:57:55 +1000 Subject: [PATCH 0432/1940] powerpc: Make set_rtc_time() return error code from lower-level function Previously it ignored the return value from ppc_md.set_rtc_time, but in fact the functions that that can point to do return a useful error code, so return it from set_rtc_time(). Signed-off-by: Paul Mackerras --- include/asm-powerpc/rtc.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/asm-powerpc/rtc.h b/include/asm-powerpc/rtc.h index d38f2a077db2..f5802926b6c0 100644 --- a/include/asm-powerpc/rtc.h +++ b/include/asm-powerpc/rtc.h @@ -52,10 +52,8 @@ static inline unsigned int get_rtc_time(struct rtc_time *time) /* Set the current date and time in the real time clock. */ static inline int set_rtc_time(struct rtc_time *time) { - if (ppc_md.get_rtc_time) { - ppc_md.set_rtc_time(time); - return 0; - } + if (ppc_md.set_rtc_time) + return ppc_md.set_rtc_time(time); return -EINVAL; } From 35499c0195e46f479cf6ac16ad8d3f394b5fcc10 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 16:02:39 +1000 Subject: [PATCH 0433/1940] powerpc: Merge in 64-bit powermac support. This brings in a lot of changes from arch/ppc64/kernel/pmac_*.c to arch/powerpc/platforms/powermac/*.c and makes various minor tweaks elsewhere. On the powermac we now initialize ppc_md by copying the whole pmac_md structure into it, which required some changes in the ordering of initializations of individual fields of it. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/head_64.S | 25 +- arch/powerpc/kernel/prom_init.c | 4 +- arch/powerpc/kernel/setup_32.c | 7 +- arch/powerpc/platforms/Makefile | 2 +- arch/powerpc/platforms/powermac/Makefile | 6 +- arch/powerpc/platforms/powermac/feature.c | 5 +- arch/powerpc/platforms/powermac/nvram.c | 183 +++++--- arch/powerpc/platforms/powermac/pci.c | 476 ++++++++----------- arch/powerpc/platforms/powermac/pic.c | 2 +- arch/powerpc/platforms/powermac/pmac.h | 4 +- arch/powerpc/platforms/powermac/setup.c | 462 +++++++++++++------ arch/powerpc/platforms/powermac/smp.c | 532 ++++++++++++++-------- arch/powerpc/platforms/powermac/time.c | 280 +++++++----- include/asm-powerpc/machdep.h | 6 +- include/asm-ppc64/system.h | 2 + include/asm-ppc64/udbg.h | 3 + 17 files changed, 1163 insertions(+), 837 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e70f7049cc6f..27f122e1f849 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -290,6 +290,7 @@ config PPC_PMAC config PPC_PMAC64 bool depends on PPC_PMAC && POWER4 + select U3_DART default y config PPC_PREP diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 72b0d26e41d4..147215a0d6c0 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1501,20 +1501,17 @@ copy_to_here: .section ".text"; .align 2 ; - .globl pmac_secondary_start_1 -pmac_secondary_start_1: - li r24, 1 - b .pmac_secondary_start - - .globl pmac_secondary_start_2 -pmac_secondary_start_2: - li r24, 2 - b .pmac_secondary_start - - .globl pmac_secondary_start_3 -pmac_secondary_start_3: - li r24, 3 - b .pmac_secondary_start + .globl __secondary_start_pmac_0 +__secondary_start_pmac_0: + /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ + li r24,0 + b 1f + li r24,1 + b 1f + li r24,2 + b 1f + li r24,3 +1: _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 9b1baaa9eda0..095659d51b4b 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -772,7 +772,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp) } r = *p++; #ifdef CONFIG_PPC64 - if (s) { + if (s > 1) { r <<= 32; r |= *(p++); } @@ -2059,7 +2059,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, reloc_got2(-offset); #endif - __start(hdr, 0, 0); + __start(hdr, KERNELBASE + offset, 0); return 0; } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index b9269c038af3..2d7fdeb581d1 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -464,14 +464,11 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); #endif /* CONFIG_CMDLINE */ + platform_init(); + #ifdef CONFIG_6xx ppc_md.power_save = ppc6xx_idle; #endif -#ifdef CONFIG_POWER4 - ppc_md.power_save = power4_idle; -#endif - - platform_init(); if (ppc_md.progress) ppc_md.progress("id mach(): done", 0x200); diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index da744d5e52fd..9b54e805b8aa 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -1,4 +1,4 @@ -ifeq ($(CONFIG_PPC32),y) +ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif obj-$(CONFIG_4xx) += 4xx/ diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 74712ede16df..4369676f1d54 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,8 +1,8 @@ -obj-$(CONFIG_PPC_PMAC) += pic.o setup.o time.o feature.o pci.o \ +obj-y += pic.o setup.o time.o feature.o pci.o \ sleep.o low_i2c.o cache.o obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o -ifeq ($(CONFIG_PPC_PMAC),y) obj-$(CONFIG_NVRAM) += nvram.o +# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff +obj-$(CONFIG_PPC64) += nvram.o obj-$(CONFIG_SMP) += smp.o -endif diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 243a24fd025a..10f1d942c661 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -2960,7 +2960,6 @@ static void dump_HT_speeds(char *name, u32 cfg, u32 frq) void __init pmac_check_ht_link(void) { -#if 0 /* Disabled for now */ u32 ufreq, freq, ucfg, cfg; struct device_node *pcix_node; u8 px_bus, px_devfn; @@ -2991,10 +2990,8 @@ void __init pmac_check_ht_link(void) early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg); early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq); dump_HT_speeds("PCI-X HT Downlink", cfg, freq); -#endif } - -#endif /* CONFIG_POWER4 */ +#endif /* 0 */ /* * Early video resume hook diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index 8c9b008c7226..4042e2f06ee0 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c @@ -47,7 +47,8 @@ /* On Core99, nvram is either a sharp, a micron or an AMD flash */ #define SM_FLASH_STATUS_DONE 0x80 -#define SM_FLASH_STATUS_ERR 0x38 +#define SM_FLASH_STATUS_ERR 0x38 + #define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 #define SM_FLASH_CMD_ERASE_SETUP 0x20 #define SM_FLASH_CMD_RESET 0xff @@ -75,11 +76,11 @@ struct core99_header { * Read and write the non-volatile RAM on PowerMacs and CHRP machines. */ static int nvram_naddrs; -static volatile unsigned char *nvram_addr; static volatile unsigned char *nvram_data; -static int nvram_mult, is_core_99; +static int is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; +// XXX Turn that into a sem static DEFINE_SPINLOCK(nv_lock); extern int pmac_newworld; @@ -105,6 +106,52 @@ static void core99_nvram_write_byte(int addr, unsigned char val) nvram_image[addr] = val; } +static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index) +{ + int i; + + if (nvram_image == NULL) + return -ENODEV; + if (*index > NVRAM_SIZE) + return 0; + + i = *index; + if (i + count > NVRAM_SIZE) + count = NVRAM_SIZE - i; + + memcpy(buf, &nvram_image[i], count); + *index = i + count; + return count; +} + +static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index) +{ + int i; + + if (nvram_image == NULL) + return -ENODEV; + if (*index > NVRAM_SIZE) + return 0; + + i = *index; + if (i + count > NVRAM_SIZE) + count = NVRAM_SIZE - i; + + memcpy(&nvram_image[i], buf, count); + *index = i + count; + return count; +} + +static ssize_t core99_nvram_size(void) +{ + if (nvram_image == NULL) + return -ENODEV; + return NVRAM_SIZE; +} + +#ifdef CONFIG_PPC32 +static volatile unsigned char *nvram_addr; +static int nvram_mult; static unsigned char direct_nvram_read_byte(int addr) { @@ -181,7 +228,7 @@ static void pmu_nvram_write_byte(int addr, unsigned char val) } #endif /* CONFIG_ADB_PMU */ - +#endif /* CONFIG_PPC32 */ static u8 chrp_checksum(struct chrp_header* hdr) { @@ -249,7 +296,7 @@ static int sm_erase_bank(int bank) timeout = 0; do { if (++timeout > 1000000) { - printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n"); + printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n"); break; } out_8(base, SM_FLASH_CMD_READ_STATUS); @@ -411,7 +458,7 @@ static void __init lookup_partitions(void) buffer[16] = 0; do { for (i=0;i<16;i++) - buffer[i] = nvram_read_byte(offset+i); + buffer[i] = ppc_md.nvram_read_val(offset+i); if (!strcmp(hdr->name, "common")) nvram_partitions[pmac_nvram_OF] = offset + 0x10; if (!strcmp(hdr->name, "APL,MacOS75")) { @@ -467,65 +514,76 @@ static void core99_nvram_sync(void) #endif } -void __init pmac_nvram_init(void) +static int __init core99_nvram_setup(struct device_node *dp) +{ + int i; + u32 gen_bank0, gen_bank1; + + if (nvram_naddrs < 1) { + printk(KERN_ERR "nvram: no address\n"); + return -EINVAL; + } + nvram_image = alloc_bootmem(NVRAM_SIZE); + if (nvram_image == NULL) { + printk(KERN_ERR "nvram: can't allocate ram image\n"); + return -ENOMEM; + } + nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); + nvram_naddrs = 1; /* Make sure we get the correct case */ + + DBG("nvram: Checking bank 0...\n"); + + gen_bank0 = core99_check((u8 *)nvram_data); + gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); + core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; + + DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); + DBG("nvram: Active bank is: %d\n", core99_bank); + + for (i=0; in_addrs; is_core_99 = device_is_compatible(dp, "nvram,flash"); - if (is_core_99) { - int i; - u32 gen_bank0, gen_bank1; - - if (nvram_naddrs < 1) { - printk(KERN_ERR "nvram: no address\n"); - return; - } - nvram_image = alloc_bootmem(NVRAM_SIZE); - if (nvram_image == NULL) { - printk(KERN_ERR "nvram: can't allocate ram image\n"); - return; - } - nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); - nvram_naddrs = 1; /* Make sure we get the correct case */ - - DBG("nvram: Checking bank 0...\n"); - - gen_bank0 = core99_check((u8 *)nvram_data); - gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); - core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; - - DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); - DBG("nvram: Active bank is: %d\n", core99_bank); - - for (i=0; iaddrs[0].address + isa_mem_base, dp->addrs[0].size); nvram_mult = 1; @@ -547,11 +605,14 @@ void __init pmac_nvram_init(void) ppc_md.nvram_read_val = pmu_nvram_read_byte; ppc_md.nvram_write_val = pmu_nvram_write_byte; #endif /* CONFIG_ADB_PMU */ - } else { - printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n", - nvram_naddrs); + } +#endif + else { + printk(KERN_ERR "Incompatible type of NVRAM\n"); + return -ENXIO; } lookup_partitions(); + return err; } int pmac_get_partition(int partition) @@ -561,9 +622,9 @@ int pmac_get_partition(int partition) u8 pmac_xpram_read(int xpaddr) { - int offset = nvram_partitions[pmac_nvram_XPRAM]; + int offset = pmac_get_partition(pmac_nvram_XPRAM); - if (offset < 0) + if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) return 0xff; return ppc_md.nvram_read_val(xpaddr + offset); @@ -571,9 +632,9 @@ u8 pmac_xpram_read(int xpaddr) void pmac_xpram_write(int xpaddr, u8 data) { - int offset = nvram_partitions[pmac_nvram_XPRAM]; + int offset = pmac_get_partition(pmac_nvram_XPRAM); - if (offset < 0) + if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) return; ppc_md.nvram_write_val(xpaddr + offset, data); diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 34dfe1e9706f..ebe22a2267d2 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -37,14 +37,14 @@ #endif static int add_bridge(struct device_node *dev); -extern void pmac_check_ht_link(void); /* XXX Could be per-controller, but I don't think we risk anything by * assuming we won't have both UniNorth and Bandit */ static int has_uninorth; -#ifdef CONFIG_POWER4 +#ifdef CONFIG_PPC64 static struct pci_controller *u3_agp; -#endif /* CONFIG_POWER4 */ +static struct pci_controller *u3_ht; +#endif /* CONFIG_PPC64 */ extern u8 pci_cache_line_size; extern int pcibios_assign_bus_offset; @@ -229,6 +229,7 @@ static struct pci_ops macrisc_pci_ops = macrisc_write_config }; +#ifdef CONFIG_PPC32 /* * Verify that a specific (bus, dev_fn) exists on chaos */ @@ -282,7 +283,19 @@ static struct pci_ops chaos_pci_ops = chaos_write_config }; -#ifdef CONFIG_POWER4 +static void __init setup_chaos(struct pci_controller *hose, + struct reg_property *addr) +{ + /* assume a `chaos' bridge */ + hose->ops = &chaos_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); +} +#else +#define setup_chaos(hose, addr) +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 /* * These versions of U3 HyperTransport config space access ops do not * implement self-view of the HT host yet @@ -445,8 +458,9 @@ static struct pci_ops u3_ht_pci_ops = u3_ht_read_config, u3_ht_write_config }; -#endif /* CONFIG_POWER4 */ +#endif /* CONFIG_PPC64 */ +#ifdef CONFIG_PPC32 /* * For a bandit bridge, turn on cache coherency if necessary. * N.B. we could clean this up using the hose ops directly. @@ -487,7 +501,6 @@ static void __init init_bandit(struct pci_controller *bp) printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n"); } - /* * Tweak the PCI-PCI bridge chip on the blue & white G3s. */ @@ -539,7 +552,7 @@ static void __init fixup_nec_usb2(void) struct pci_controller *hose; u32 data, *prop; u8 bus, devfn; - + prop = (u32 *)get_property(nec, "vendor-id", NULL); if (prop == NULL) continue; @@ -605,8 +618,27 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) (void)in_le32(bp->cfg_data); } -static int __init -setup_uninorth(struct pci_controller* hose, struct reg_property* addr) +void __init setup_grackle(struct pci_controller *hose) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif +} + +static void __init setup_bandit(struct pci_controller *hose, + struct reg_property *addr) +{ + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + init_bandit(hose); +} + +static int __init setup_uninorth(struct pci_controller *hose, + struct reg_property *addr) { pci_assign_all_buses = 1; has_uninorth = 1; @@ -616,31 +648,14 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr) /* We "know" that the bridge at f2000000 has the PCI slots. */ return addr->address == 0xf2000000; } +#endif -static void __init -setup_bandit(struct pci_controller* hose, struct reg_property* addr) -{ - hose->ops = ¯isc_pci_ops; - hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); - hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); - init_bandit(hose); -} - -static void __init -setup_chaos(struct pci_controller* hose, struct reg_property* addr) -{ - /* assume a `chaos' bridge */ - hose->ops = &chaos_pci_ops; - hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); - hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); -} - -#ifdef CONFIG_POWER4 +#ifdef CONFIG_PPC64 static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_buses to the + * on AGP, we'll have to move pci_assign_all_busses to the * pci_controller structure so we enable it for AGP and not for * HT childs. * We hard code the address because of the different size of @@ -679,8 +694,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) * then read its configuration register (if any). */ hose->io_base_phys = 0xf4000000; - hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); - isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt; + hose->pci_io_size = 0x00400000; hose->io_resource.name = np->full_name; hose->io_resource.start = 0; hose->io_resource.end = 0x003fffff; @@ -693,6 +707,8 @@ static void __init setup_u3_ht(struct pci_controller* hose) hose->mem_resources[0].end = 0xefffffff; hose->mem_resources[0].flags = IORESOURCE_MEM; + u3_ht = hose; + if (u3_agp == NULL) { DBG("U3 has no AGP, using full resource range\n"); return; @@ -730,7 +746,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) printk(KERN_WARNING "Running out of resources for /ht host !\n"); hose->mem_resources[cur].end = res->start - 1; continue; - } + } cur++; DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", cur-1, res->start - 1, cur, res->end + 1); @@ -742,126 +758,17 @@ static void __init setup_u3_ht(struct pci_controller* hose) } } -#endif /* CONFIG_POWER4 */ - -void __init -setup_grackle(struct pci_controller *hose) +/* XXX this needs to be converged between ppc32 and ppc64... */ +static struct pci_controller * __init pcibios_alloc_controller(void) { - setup_indirect_pci(hose, 0xfec00000, 0xfee00000); - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(hose, 1); -#if 0 /* Disabled for now, HW problems ??? */ - grackle_set_stg(hose, 1); -#endif + struct pci_controller *hose; + + hose = alloc_bootmem(sizeof(struct pci_controller)); + if (hose) + pci_setup_pci_controller(hose); + return hose; } - -static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev, int primary) -{ - static unsigned int static_lc_ranges[2024]; - unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; - unsigned int size; - int rlen = 0, orig_rlen; - int memno = 0; - struct resource *res; - int np, na = prom_n_addr_cells(dev); - - np = na + 5; - - /* First we try to merge ranges to fix a problem with some pmacs - * that can have more than 3 ranges, fortunately using contiguous - * addresses -- BenH - */ - dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); - if (!dt_ranges) - return; - /* lc_ranges = alloc_bootmem(rlen);*/ - lc_ranges = static_lc_ranges; - if (!lc_ranges) - return; /* what can we do here ? */ - memcpy(lc_ranges, dt_ranges, rlen); - orig_rlen = rlen; - - /* Let's work on a copy of the "ranges" property instead of damaging - * the device-tree image in memory - */ - ranges = lc_ranges; - prev = NULL; - while ((rlen -= np * sizeof(unsigned int)) >= 0) { - if (prev) { - if (prev[0] == ranges[0] && prev[1] == ranges[1] && - (prev[2] + prev[na+4]) == ranges[2] && - (prev[na+2] + prev[na+4]) == ranges[na+2]) { - prev[na+4] += ranges[na+4]; - ranges[0] = 0; - ranges += np; - continue; - } - } - prev = ranges; - ranges += np; - } - - /* - * The ranges property is laid out as an array of elements, - * each of which comprises: - * cells 0 - 2: a PCI address - * cells 3 or 3+4: a CPU physical address - * (size depending on dev->n_addr_cells) - * cells 4+5 or 5+6: the size of the range - */ - ranges = lc_ranges; - rlen = orig_rlen; - while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { - res = NULL; - size = ranges[na+4]; - switch (ranges[0] >> 24) { - case 1: /* I/O space */ - if (ranges[2] != 0) - break; - hose->io_base_phys = ranges[na+2]; - /* limit I/O space to 16MB */ - if (size > 0x01000000) - size = 0x01000000; - hose->io_base_virt = ioremap(ranges[na+2], size); - if (primary) - isa_io_base = (unsigned long) hose->io_base_virt; - res = &hose->io_resource; - res->flags = IORESOURCE_IO; - res->start = ranges[2]; - break; - case 2: /* memory space */ - memno = 0; - if (ranges[1] == 0 && ranges[2] == 0 - && ranges[na+4] <= (16 << 20)) { - /* 1st 16MB, i.e. ISA memory area */ -#if 0 - if (primary) - isa_mem_base = ranges[na+2]; #endif - memno = 1; - } - while (memno < 3 && hose->mem_resources[memno].flags) - ++memno; - if (memno == 0) - hose->pci_mem_offset = ranges[na+2] - ranges[2]; - if (memno < 3) { - res = &hose->mem_resources[memno]; - res->flags = IORESOURCE_MEM; - res->start = ranges[na+2]; - } - break; - } - if (res != NULL) { - res->name = dev->full_name; - res->end = res->start + size - 1; - res->parent = NULL; - res->sibling = NULL; - res->child = NULL; - } - ranges += np; - } -} /* * We assume that if we have a G3 powermac, we have one bridge called @@ -872,70 +779,78 @@ static int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; +#ifdef CONFIG_PPC32 struct reg_property *addr; - char* disp_name; +#endif + char *disp_name; int *bus_range; int primary = 1; DBG("Adding PCI host bridge %s\n", dev->full_name); - addr = (struct reg_property *) get_property(dev, "reg", &len); - if (addr == NULL || len < sizeof(*addr)) { - printk(KERN_WARNING "Can't use %s: no address\n", - dev->full_name); - return -ENODEV; - } - bus_range = (int *) get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", - dev->full_name); - } +#ifdef CONFIG_PPC32 + /* XXX fix this */ + addr = (struct reg_property *) get_property(dev, "reg", &len); + if (addr == NULL || len < sizeof(*addr)) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + return -ENODEV; + } +#endif + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", + dev->full_name); + } - hose = pcibios_alloc_controller(); - if (!hose) - return -ENOMEM; - hose->arch_data = dev; - hose->first_busno = bus_range ? bus_range[0] : 0; - hose->last_busno = bus_range ? bus_range[1] : 0xff; + hose = pcibios_alloc_controller(); + if (!hose) + return -ENOMEM; + hose->arch_data = dev; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; disp_name = NULL; #ifdef CONFIG_POWER4 - if (device_is_compatible(dev, "u3-agp")) { - setup_u3_agp(hose, addr); - disp_name = "U3-AGP"; - primary = 0; - } else if (device_is_compatible(dev, "u3-ht")) { - setup_u3_ht(hose, addr); - disp_name = "U3-HT"; - primary = 1; - } else -#endif /* CONFIG_POWER4 */ + if (device_is_compatible(dev, "u3-agp")) { + setup_u3_agp(hose); + disp_name = "U3-AGP"; + primary = 0; + } else if (device_is_compatible(dev, "u3-ht")) { + setup_u3_ht(hose); + disp_name = "U3-HT"; + primary = 1; + } + printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", + disp_name, hose->first_busno, hose->last_busno); +#else if (device_is_compatible(dev, "uni-north")) { - primary = setup_uninorth(hose, addr); - disp_name = "UniNorth"; + primary = setup_uninorth(hose, addr); + disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { - /* XXX assume this is a mpc106 (grackle) */ - setup_grackle(hose); - disp_name = "Grackle (MPC106)"; - } else if (strcmp(dev->name, "bandit") == 0) { - setup_bandit(hose, addr); - disp_name = "Bandit"; - } else if (strcmp(dev->name, "chaos") == 0) { - setup_chaos(hose, addr); - disp_name = "Chaos"; - primary = 0; - } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", - disp_name, addr->address, hose->first_busno, hose->last_busno); - DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", - hose, hose->cfg_addr, hose->cfg_data); + /* XXX assume this is a mpc106 (grackle) */ + setup_grackle(hose); + disp_name = "Grackle (MPC106)"; + } else if (strcmp(dev->name, "bandit") == 0) { + setup_bandit(hose, addr); + disp_name = "Bandit"; + } else if (strcmp(dev->name, "chaos") == 0) { + setup_chaos(hose, addr); + disp_name = "Chaos"; + primary = 0; + } + printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); +#endif + DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", + hose, hose->cfg_addr, hose->cfg_data); - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(hose, dev, primary); + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, primary); - /* Fixup "bus-range" OF property */ - fixup_bus_range(dev); + /* Fixup "bus-range" OF property */ + fixup_bus_range(dev); return 0; } @@ -968,14 +883,28 @@ pmac_pcibios_fixup(void) pcibios_fixup_OF_interrupts(); } -void __init pmac_find_bridges(void) +#ifdef CONFIG_PPC64 +static void __init pmac_fixup_phb_resources(void) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + hose->global_number, + hose->io_resource.start, hose->io_resource.end); + } +} +#endif + +void __init pmac_pci_init(void) { struct device_node *np, *root; struct device_node *ht = NULL; root = of_find_node_by_path("/"); if (root == NULL) { - printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); + printk(KERN_CRIT "pmac_pci_init: can't find root " + "of device tree\n"); return; } for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { @@ -994,22 +923,66 @@ void __init pmac_find_bridges(void) } of_node_put(root); +#ifdef CONFIG_PPC64 /* Probe HT last as it relies on the agp resources to be already * setup */ if (ht && add_bridge(ht) != 0) of_node_put(ht); + /* + * We need to call pci_setup_phb_io for the HT bridge first + * so it gets the I/O port numbers starting at 0, and we + * need to call it for the AGP bridge after that so it gets + * small positive I/O port numbers. + */ + if (u3_ht) + pci_setup_phb_io(u3_ht, 1); + if (u3_agp) + pci_setup_phb_io(u3_agp, 0); + + /* + * On ppc64, fixup the IO resources on our host bridges as + * the common code does it only for children of the host bridges + */ + pmac_fixup_phb_resources(); + + /* Setup the linkage between OF nodes and PHBs */ + pci_devs_phb_init(); + + /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We + * assume there is no P2P bridge on the AGP bus, which should be a + * safe assumptions hopefully. + */ + if (u3_agp) { + struct device_node *np = u3_agp->arch_data; + PCI_DN(np)->busno = 0xf0; + for (np = np->child; np; np = np->sibling) + PCI_DN(np)->busno = 0xf0; + } + + /* map in PCI I/O space */ + phbs_remap_io(); + + /* pmac_check_ht_link(); */ + + /* Tell pci.c to not use the common resource allocation mechanism */ + pci_probe_only = 1; + + /* Allow all IO */ + io_page_mask = -1; + +#else /* CONFIG_PPC64 */ init_p2pbridge(); fixup_nec_usb2(); - + /* We are still having some issues with the Xserve G4, enabling * some offset between bus number and domains for now when we * assign all busses should help for now */ if (pci_assign_all_buses) pcibios_assign_bus_offset = 0x10; - +#endif } int @@ -1037,7 +1010,7 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) uninorth_child = node->parent && device_is_compatible(node->parent, "uni-north"); - + /* Firewire & GMAC were disabled after PCI probe, the driver is * claiming them, we must re-enable them now. */ @@ -1057,7 +1030,7 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) if (updatecfg) { u16 cmd; - + /* * Make sure PCI is correctly configured * @@ -1069,10 +1042,12 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) * register the device. */ pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; - pci_write_config_word(dev, PCI_COMMAND, cmd); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER + | PCI_COMMAND_INVALIDATE; + pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + L1_CACHE_BYTES >> 2); } return 0; @@ -1081,8 +1056,7 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) /* We power down some devices after they have been probed. They'll * be powered back on later on */ -void __init -pmac_pcibios_after_init(void) +void __init pmac_pcibios_after_init(void) { struct device_node* nd; @@ -1125,84 +1099,6 @@ pmac_pcibios_after_init(void) } } -#ifdef CONFIG_PPC64 -static void __init pmac_fixup_phb_resources(void) -{ - struct pci_controller *hose, *tmp; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; - hose->io_resource.start += offset; - hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", - hose->global_number, - hose->io_resource.start, hose->io_resource.end); - } -} - -void __init pmac_pci_init(void) -{ - struct device_node *np, *root; - struct device_node *ht = NULL; - - /* Probe root PCI hosts, that is on U3 the AGP host and the - * HyperTransport host. That one is actually "kept" around - * and actually added last as it's resource management relies - * on the AGP resources to have been setup first - */ - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); - return; - } - for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { - if (np->name == NULL) - continue; - if (strcmp(np->name, "pci") == 0) { - if (add_bridge(np) == 0) - of_node_get(np); - } - if (strcmp(np->name, "ht") == 0) { - of_node_get(np); - ht = np; - } - } - of_node_put(root); - - /* Now setup the HyperTransport host if we found any - */ - if (ht && add_bridge(ht) != 0) - of_node_put(ht); - - /* Fixup the IO resources on our host bridges as the common code - * does it only for childs of the host bridges - */ - pmac_fixup_phb_resources(); - - /* Setup the linkage between OF nodes and PHBs */ - pci_devs_phb_init(); - - /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We - * assume there is no P2P bridge on the AGP bus, which should be a - * safe assumptions hopefully. - */ - if (u3_agp) { - struct device_node *np = u3_agp->arch_data; - PCI_DN(np)->busno = 0xf0; - for (np = np->child; np; np = np->sibling) - PCI_DN(np)->busno = 0xf0; - } - - pmac_check_ht_link(); - - /* Tell pci.c to not use the common resource allocation mecanism */ - pci_probe_only = 1; - - /* Allow all IO */ - io_page_mask = -1; -} -#endif - #ifdef CONFIG_PPC32 void pmac_pci_fixup_cardbus(struct pci_dev* dev) { @@ -1217,7 +1113,7 @@ void pmac_pci_fixup_cardbus(struct pci_dev* dev) if (dev->device == PCI_DEVICE_ID_TI_1130 || dev->device == PCI_DEVICE_ID_TI_1131) { u8 val; - /* Enable PCI interrupt */ + /* Enable PCI interrupt */ if (pci_read_config_byte(dev, 0x91, &val) == 0) pci_write_config_byte(dev, 0x91, val | 0x30); /* Disable ISA interrupt mode */ diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 58017d18db70..0eca17df239e 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -430,7 +430,6 @@ void __init pmac_pic_init(void) printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", (unsigned int)irqctrler->addrs[0].address); - ppc_md.get_irq = mpic_get_irq; pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); prom_get_irq_senses(senses, 0, 128); @@ -483,6 +482,7 @@ void __init pmac_pic_init(void) * a Grand Central nor an OHare, then it's an Heathrow * (or Paddington). */ + ppc_md.get_irq = pmac_get_irq; if (find_devices("gc")) level_mask[0] = GC_LEVEL_MASK; else if (find_devices("ohare")) { diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 0a9ba704865e..2ad25e13423e 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -19,7 +19,7 @@ extern int pmac_set_rtc_time(struct rtc_time *); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); extern void pmac_pcibios_fixup(void); -extern void pmac_find_bridges(void); +extern void pmac_pci_init(void); extern unsigned long pmac_ide_get_base(int index); extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq); @@ -41,7 +41,7 @@ extern unsigned long pmac_ide_get_base(int index); extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq); -extern void pmac_nvram_init(void); +extern int pmac_nvram_init(void); extern struct hw_interrupt_type pmac_pic; diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 0bad53fa36ef..da0cb165dfc6 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -1,11 +1,11 @@ /* - * arch/ppc/platforms/setup.c + * Powermac setup and early boot code plus other random bits. * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Adapted for Power Macintosh by Paul Mackerras - * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * Copyright (C) 1996 Paul Mackerras (paulus@samba.org) * * Derived from "arch/alpha/kernel/setup.c" * Copyright (C) 1995 Linus Torvalds @@ -65,13 +65,16 @@ #include #include #include -#include #include #include #include #include #include #include +#include +#include +#include +#include #include "pmac.h" @@ -88,16 +91,24 @@ int pmac_newworld = 1; static int current_root_goodness = -1; extern int pmac_newworld; +extern struct machdep_calls pmac_md; #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ -extern void zs_kgdb_hook(int tty_num); -static void ohare_init(void); -#ifdef CONFIG_BOOTX_TEXT -static void pmac_progress(char *s, unsigned short hex); +#ifdef CONFIG_PPC64 +#include +int sccdbg; #endif +extern void zs_kgdb_hook(int tty_num); + sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; +EXPORT_SYMBOL(sys_ctrler); + +#ifdef CONFIG_PMAC_SMU +unsigned long smu_cmdbuf_abs; +EXPORT_SYMBOL(smu_cmdbuf_abs); +#endif #ifdef CONFIG_SMP extern struct smp_ops_t psurge_smp_ops; @@ -191,44 +202,69 @@ static void pmac_show_percpuinfo(struct seq_file *m, int i) return; } #endif /* CONFIG_CPU_FREQ_PMAC */ +#ifdef CONFIG_PPC32 of_show_percpuinfo(m, i); +#endif } +#ifndef CONFIG_ADB_CUDA +int find_via_cuda(void) +{ + if (!find_devices("via-cuda")) + return 0; + printk("WARNING ! Your machine is CUDA-based but your kernel\n"); + printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); + return 0; +} +#endif + +#ifndef CONFIG_ADB_PMU +int find_via_pmu(void) +{ + if (!find_devices("via-pmu")) + return 0; + printk("WARNING ! Your machine is PMU-based but your kernel\n"); + printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); + return; +} +#endif + +#ifndef CONFIG_PMAC_SMU +int smu_init(void) +{ + /* should check and warn if SMU is present */ + return 0; +} +#endif + +#ifdef CONFIG_PPC32 static volatile u32 *sysctrl_regs; -void __init -pmac_setup_arch(void) +static void __init ohare_init(void) { - struct device_node *cpu; - int *fp; - unsigned long pvr; - - pvr = PVR_VER(mfspr(SPRN_PVR)); - - /* Set loops_per_jiffy to a half-way reasonable value, - for use until calibrate_delay gets called. */ - cpu = find_type_devices("cpu"); - if (cpu != 0) { - fp = (int *) get_property(cpu, "clock-frequency", NULL); - if (fp != 0) { - if (pvr == 4 || pvr >= 8) - /* 604, G3, G4 etc. */ - loops_per_jiffy = *fp / HZ; - else - /* 601, 603, etc. */ - loops_per_jiffy = *fp / (2*HZ); - } else - loops_per_jiffy = 50000000 / HZ; - } - /* this area has the CPU identification register and some registers used by smp boards */ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); - ohare_init(); - /* Lookup PCI hosts */ - pmac_find_bridges(); + /* + * Turn on the L2 cache. + * We assume that we have a PSX memory controller iff + * we have an ohare I/O controller. + */ + if (find_devices("ohare") != NULL) { + if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { + if (sysctrl_regs[4] & 0x10) + sysctrl_regs[4] |= 0x04000020; + else + sysctrl_regs[4] |= 0x04000000; + if(has_l2cache) + printk(KERN_INFO "Level 2 cache enabled\n"); + } + } +} +static void __init l2cr_init(void) +{ /* Checks "l2cr-value" property in the registry */ if (cpu_has_feature(CPU_FTR_L2CR)) { struct device_node *np = find_devices("cpus"); @@ -247,68 +283,90 @@ pmac_setup_arch(void) } if (ppc_override_l2cr) - printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", - ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) + printk(KERN_INFO "L2CR overridden (0x%x), " + "backside cache is %s\n", + ppc_override_l2cr_value, + (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled"); +} +#endif + +void __init pmac_setup_arch(void) +{ + struct device_node *cpu; + int *fp; + unsigned long pvr; + + pvr = PVR_VER(mfspr(SPRN_PVR)); + + /* Set loops_per_jiffy to a half-way reasonable value, + for use until calibrate_delay gets called. */ + loops_per_jiffy = 50000000 / HZ; + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != NULL) { + fp = (int *) get_property(cpu, "clock-frequency", NULL); + if (fp != NULL) { + if (pvr >= 0x30 && pvr < 0x80) + /* PPC970 etc. */ + loops_per_jiffy = *fp / (3 * HZ); + else if (pvr == 4 || pvr >= 8) + /* 604, G3, G4 etc. */ + loops_per_jiffy = *fp / HZ; + else + /* 601, 603, etc. */ + loops_per_jiffy = *fp / (2 * HZ); + } + of_node_put(cpu); + } + + /* Lookup PCI hosts */ + pmac_pci_init(); + +#ifdef CONFIG_PPC32 + ohare_init(); + l2cr_init(); +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + /* Probe motherboard chipset */ + /* this is done earlier in setup_arch for 32-bit */ + pmac_feature_init(); + + /* We can NAP */ + powersave_nap = 1; + printk(KERN_INFO "Using native/NAP idle loop\n"); +#endif #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif -#ifdef CONFIG_ADB_CUDA find_via_cuda(); -#else - if (find_devices("via-cuda")) { - printk("WARNING ! Your machine is Cuda based but your kernel\n"); - printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); - } -#endif -#ifdef CONFIG_ADB_PMU find_via_pmu(); -#else - if (find_devices("via-pmu")) { - printk("WARNING ! Your machine is PMU based but your kernel\n"); - printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); - } -#endif + smu_init(); + #ifdef CONFIG_NVRAM pmac_nvram_init(); #endif + +#ifdef CONFIG_PPC32 #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = Root_RAM0; else #endif ROOT_DEV = DEFAULT_ROOT_DEVICE; +#endif #ifdef CONFIG_SMP /* Check for Core99 */ if (find_devices("uni-n") || find_devices("u3")) smp_ops = &core99_smp_ops; +#ifdef CONFIG_PPC32 else smp_ops = &psurge_smp_ops; +#endif #endif /* CONFIG_SMP */ - - pci_create_OF_bus_map(); -} - -static void __init ohare_init(void) -{ - /* - * Turn on the L2 cache. - * We assume that we have a PSX memory controller iff - * we have an ohare I/O controller. - */ - if (find_devices("ohare") != NULL) { - if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { - if (sysctrl_regs[4] & 0x10) - sysctrl_regs[4] |= 0x04000020; - else - sysctrl_regs[4] |= 0x04000000; - if(has_l2cache) - printk(KERN_INFO "Level 2 cache enabled\n"); - } - } } char *bootpath; @@ -319,8 +377,7 @@ int boot_part; extern dev_t boot_dev; #ifdef CONFIG_SCSI -void __init -note_scsi_host(struct device_node *node, void *host) +void __init note_scsi_host(struct device_node *node, void *host) { int l; char *p; @@ -351,8 +408,7 @@ EXPORT_SYMBOL(note_scsi_host); #endif #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) -static dev_t __init -find_ide_boot(void) +static dev_t __init find_ide_boot(void) { char *p; int n; @@ -369,15 +425,13 @@ find_ide_boot(void) } #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ -static void __init -find_boot_device(void) +static void __init find_boot_device(void) { #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) boot_dev = find_ide_boot(); #endif } -static int initializing = 1; /* TODO: Merge the suspend-to-ram with the common code !!! * currently, this is a stub implementation for suspend-to-disk * only @@ -428,6 +482,8 @@ static struct pm_ops pmac_pm_ops = { #endif /* CONFIG_SOFTWARE_SUSPEND */ +static int initializing = 1; + static int pmac_late_init(void) { initializing = 0; @@ -440,8 +496,7 @@ static int pmac_late_init(void) late_initcall(pmac_late_init); /* can't be __init - can be called whenever a disk is first accessed */ -void -note_bootable_part(dev_t dev, int part, int goodness) +void note_bootable_part(dev_t dev, int part, int goodness) { static int found_boot = 0; char *p; @@ -466,52 +521,68 @@ note_bootable_part(dev_t dev, int part, int goodness) } } -static void -pmac_restart(char *cmd) +#ifdef CONFIG_ADB_CUDA +static void cuda_restart(void) { -#ifdef CONFIG_ADB_CUDA struct adb_request req; -#endif /* CONFIG_ADB_CUDA */ + cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); + for (;;) + cuda_poll(); +} + +static void cuda_shutdown(void) +{ + struct adb_request req; + + cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); + for (;;) + cuda_poll(); +} + +#else +#define cuda_restart() +#define cuda_shutdown() +#endif + +#ifndef CONFIG_ADB_PMU +#define pmu_restart() +#define pmu_shutdown() +#endif + +#ifndef CONFIG_PMAC_SMU +#define smu_restart() +#define smu_shutdown() +#endif + +static void pmac_restart(char *cmd) +{ switch (sys_ctrler) { -#ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: - cuda_request(&req, NULL, 2, CUDA_PACKET, - CUDA_RESET_SYSTEM); - for (;;) - cuda_poll(); + cuda_restart(); break; -#endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU case SYS_CTRLER_PMU: pmu_restart(); break; -#endif /* CONFIG_ADB_PMU */ + case SYS_CTRLER_SMU: + smu_restart(); + break; default: ; } } -static void -pmac_power_off(void) +static void pmac_power_off(void) { -#ifdef CONFIG_ADB_CUDA - struct adb_request req; -#endif /* CONFIG_ADB_CUDA */ - switch (sys_ctrler) { -#ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: - cuda_request(&req, NULL, 2, CUDA_PACKET, - CUDA_POWERDOWN); - for (;;) - cuda_poll(); + cuda_shutdown(); break; -#endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU case SYS_CTRLER_PMU: pmu_shutdown(); break; -#endif /* CONFIG_ADB_PMU */ + case SYS_CTRLER_SMU: + smu_shutdown(); + break; default: ; } } @@ -522,37 +593,17 @@ pmac_halt(void) pmac_power_off(); } +#ifdef CONFIG_PPC32 void __init pmac_init(void) { - /* isa_io_base gets set in pmac_find_bridges */ + /* isa_io_base gets set in pmac_pci_init */ isa_mem_base = PMAC_ISA_MEM_BASE; pci_dram_offset = PMAC_PCI_DRAM_OFFSET; ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 1; DMA_MODE_WRITE = 2; - ppc_md.setup_arch = pmac_setup_arch; - ppc_md.show_cpuinfo = pmac_show_cpuinfo; - ppc_md.show_percpuinfo = pmac_show_percpuinfo; - ppc_md.init_IRQ = pmac_pic_init; - ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ - - ppc_md.pcibios_fixup = pmac_pcibios_fixup; - ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; - ppc_md.pcibios_after_init = pmac_pcibios_after_init; - ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; - - ppc_md.restart = pmac_restart; - ppc_md.power_off = pmac_power_off; - ppc_md.halt = pmac_halt; - - ppc_md.time_init = pmac_time_init; - ppc_md.set_rtc_time = pmac_set_rtc_time; - ppc_md.get_rtc_time = pmac_get_rtc_time; - ppc_md.get_boot_time = pmac_get_boot_time; - ppc_md.calibrate_decr = pmac_calibrate_decr; - - ppc_md.feature_call = pmac_do_feature_call; + ppc_md = pmac_md; #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) #ifdef CONFIG_BLK_DEV_IDE_PMAC @@ -561,27 +612,62 @@ void __init pmac_init(void) #endif /* CONFIG_BLK_DEV_IDE_PMAC */ #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ -#ifdef CONFIG_BOOTX_TEXT - ppc_md.progress = pmac_progress; -#endif /* CONFIG_BOOTX_TEXT */ - if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); } +#endif -#ifdef CONFIG_BOOTX_TEXT -static void __init -pmac_progress(char *s, unsigned short hex) +/* + * Early initialization. + */ +static void __init pmac_init_early(void) { +#ifdef CONFIG_PPC64 + /* Initialize hash table, from now on, we can take hash faults + * and call ioremap + */ + hpte_init_native(); + + /* Init SCC */ + if (strstr(cmd_line, "sccdbg")) { + sccdbg = 1; + udbg_init_scc(NULL); + } + + /* Setup interrupt mapping options */ + ppc64_interrupt_controller = IC_OPEN_PIC; + + iommu_init_early_u3(); +#endif +} + +static void __init pmac_progress(char *s, unsigned short hex) +{ +#ifdef CONFIG_PPC64 + if (sccdbg) { + udbg_puts(s); + udbg_puts("\n"); + return; + } +#endif +#ifdef CONFIG_BOOTX_TEXT if (boot_text_mapped) { btext_drawstring(s); btext_drawchar('\n'); } -} #endif /* CONFIG_BOOTX_TEXT */ +} -static int __init -pmac_declare_of_platform_devices(void) +/* + * pmac has no legacy IO, anything calling this function has to + * fail or bad things will happen + */ +static int pmac_check_legacy_ioport(unsigned int baseport) +{ + return -ENODEV; +} + +static int __init pmac_declare_of_platform_devices(void) { struct device_node *np; @@ -594,6 +680,13 @@ pmac_declare_of_platform_devices(void) break; } } + np = find_devices("valkyrie"); + if (np) + of_platform_device_create(np, "valkyrie", NULL); + np = find_devices("platinum"); + if (np) + of_platform_device_create(np, "platinum", NULL); + np = find_devices("u3"); if (np) { for (np = np->child; np != NULL; np = np->sibling) @@ -603,15 +696,92 @@ pmac_declare_of_platform_devices(void) break; } } - - np = find_devices("valkyrie"); - if (np) - of_platform_device_create(np, "valkyrie", NULL); - np = find_devices("platinum"); - if (np) - of_platform_device_create(np, "platinum", NULL); + np = of_find_node_by_type(NULL, "smu"); + if (np) { + of_platform_device_create(np, "smu", NULL); + of_node_put(np); + } return 0; } device_initcall(pmac_declare_of_platform_devices); + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init pmac_probe(int platform) +{ +#ifdef CONFIG_PPC64 + if (platform != PLATFORM_POWERMAC) + return 0; + + /* + * On U3, the DART (iommu) must be allocated now since it + * has an impact on htab_initialize (due to the large page it + * occupies having to be broken up so the DART itself is not + * part of the cacheable linar mapping + */ + alloc_u3_dart_table(); +#endif + +#ifdef CONFIG_PMAC_SMU + /* + * SMU based G5s need some memory below 2Gb, at least the current + * driver needs that. We have to allocate it now. We allocate 4k + * (1 small page) for now. + */ + smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); +#endif /* CONFIG_PMAC_SMU */ + + return 1; +} + +#ifdef CONFIG_PPC64 +static int pmac_probe_mode(struct pci_bus *bus) +{ + struct device_node *node = bus->sysdata; + + /* We need to use normal PCI probing for the AGP bus, + since the device for the AGP bridge isn't in the tree. */ + if (bus->self == NULL && device_is_compatible(node, "u3-agp")) + return PCI_PROBE_NORMAL; + + return PCI_PROBE_DEVTREE; +} +#endif + +struct machdep_calls __initdata pmac_md = { +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) + .cpu_die = generic_mach_cpu_die, +#endif + .probe = pmac_probe, + .setup_arch = pmac_setup_arch, + .init_early = pmac_init_early, + .show_cpuinfo = pmac_show_cpuinfo, + .show_percpuinfo = pmac_show_percpuinfo, + .init_IRQ = pmac_pic_init, + .get_irq = mpic_get_irq, /* changed later */ + .pcibios_fixup = pmac_pcibios_fixup, + .restart = pmac_restart, + .power_off = pmac_power_off, + .halt = pmac_halt, + .time_init = pmac_time_init, + .get_boot_time = pmac_get_boot_time, + .set_rtc_time = pmac_set_rtc_time, + .get_rtc_time = pmac_get_rtc_time, + .calibrate_decr = pmac_calibrate_decr, + .feature_call = pmac_do_feature_call, + .check_legacy_ioport = pmac_check_legacy_ioport, + .progress = pmac_progress, +#ifdef CONFIG_PPC64 + .pci_probe_mode = pmac_probe_mode, + .idle_loop = native_idle, + .enable_pmcs = power4_enable_pmcs, +#endif +#ifdef CONFIG_PPC32 + .pcibios_enable_device_hook = pmac_pci_enable_device_hook, + .pcibios_after_init = pmac_pcibios_after_init, + .phys_mem_access_prot = pci_phys_mem_access_prot, +#endif +}; diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index ccaa0534d60f..e1f9443cc872 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -44,20 +44,33 @@ #include #include #include -#include #include #include #include #include #include #include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) +#endif + +extern void __secondary_start_pmac_0(void); + +#ifdef CONFIG_PPC32 + +/* Sync flag for HW tb sync */ +static volatile int sec_tb_reset = 0; /* * Powersurge (old powermac SMP) support. */ -extern void __secondary_start_pmac_0(void); - /* Addresses for powersurge registers */ #define HAMMERHEAD_BASE 0xf8000000 #define HHEAD_CONFIG 0x90 @@ -106,47 +119,6 @@ static volatile u32 __iomem *psurge_start; /* what sort of powersurge board we have */ static int psurge_type = PSURGE_NONE; -/* L2 and L3 cache settings to pass from CPU0 to CPU1 */ -volatile static long int core99_l2_cache; -volatile static long int core99_l3_cache; - -/* Timebase freeze GPIO */ -static unsigned int core99_tb_gpio; - -/* Sync flag for HW tb sync */ -static volatile int sec_tb_reset = 0; -static unsigned int pri_tb_hi, pri_tb_lo; -static unsigned int pri_tb_stamp; - -static void __devinit core99_init_caches(int cpu) -{ - if (!cpu_has_feature(CPU_FTR_L2CR)) - return; - - if (cpu == 0) { - core99_l2_cache = _get_L2CR(); - printk("CPU0: L2CR is %lx\n", core99_l2_cache); - } else { - printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); - _set_L2CR(0); - _set_L2CR(core99_l2_cache); - printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); - } - - if (!cpu_has_feature(CPU_FTR_L3CR)) - return; - - if (cpu == 0){ - core99_l3_cache = _get_L3CR(); - printk("CPU0: L3CR is %lx\n", core99_l3_cache); - } else { - printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR()); - _set_L3CR(0); - _set_L3CR(core99_l3_cache); - printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); - } -} - /* * Set and clear IPIs for powersurge. */ @@ -436,65 +408,346 @@ void __init smp_psurge_give_timebase(void) /* Dummy implementation */ } -static int __init smp_core99_probe(void) +/* PowerSurge-style Macs */ +struct smp_ops_t psurge_smp_ops = { + .message_pass = smp_psurge_message_pass, + .probe = smp_psurge_probe, + .kick_cpu = smp_psurge_kick_cpu, + .setup_cpu = smp_psurge_setup_cpu, + .give_timebase = smp_psurge_give_timebase, + .take_timebase = smp_psurge_take_timebase, +}; +#endif /* CONFIG_PPC32 - actually powersurge support */ + +#ifdef CONFIG_PPC64 +/* + * G5s enable/disable the timebase via an i2c-connected clock chip. + */ +static struct device_node *pmac_tb_clock_chip_host; +static u8 pmac_tb_pulsar_addr; +static void (*pmac_tb_freeze)(int freeze); +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase; + +static void smp_core99_cypress_tb_freeze(int freeze) { -#ifdef CONFIG_6xx - extern int powersave_nap; -#endif - struct device_node *cpus, *firstcpu; - int i, ncpus = 0, boot_cpu = -1; - u32 *tbprop = NULL; + u8 data; + int rc; - if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); - cpus = firstcpu = find_type_devices("cpu"); - while(cpus != NULL) { - u32 *regprop = (u32 *)get_property(cpus, "reg", NULL); - char *stateprop = (char *)get_property(cpus, "state", NULL); - if (regprop != NULL && stateprop != NULL && - !strncmp(stateprop, "running", 7)) - boot_cpu = *regprop; - ++ncpus; - cpus = cpus->next; + /* Strangely, the device-tree says address is 0xd2, but darwin + * accesses 0xd0 ... + */ + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + 0xd0 | pmac_low_i2c_read, + 0x81, &data, 1); + if (rc != 0) + goto bail; + + data = (data & 0xf3) | (freeze ? 0x00 : 0x0c); + + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + 0xd0 | pmac_low_i2c_write, + 0x81, &data, 1); + + bail: + if (rc != 0) { + printk("Cypress Timebase %s rc: %d\n", + freeze ? "freeze" : "unfreeze", rc); + panic("Timebase freeze failed !\n"); } - if (boot_cpu == -1) - printk(KERN_WARNING "Couldn't detect boot CPU !\n"); - if (boot_cpu != 0) - printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu); +} - if (machine_is_compatible("MacRISC4")) { - extern struct smp_ops_t core99_smp_ops; - core99_smp_ops.take_timebase = smp_generic_take_timebase; - core99_smp_ops.give_timebase = smp_generic_give_timebase; +static void smp_core99_pulsar_tb_freeze(int freeze) +{ + u8 data; + int rc; + + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + pmac_tb_pulsar_addr | pmac_low_i2c_read, + 0x2e, &data, 1); + if (rc != 0) + goto bail; + + data = (data & 0x88) | (freeze ? 0x11 : 0x22); + + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + pmac_tb_pulsar_addr | pmac_low_i2c_write, + 0x2e, &data, 1); + bail: + if (rc != 0) { + printk(KERN_ERR "Pulsar Timebase %s rc: %d\n", + freeze ? "freeze" : "unfreeze", rc); + panic("Timebase freeze failed !\n"); + } +} + + +static void smp_core99_give_timebase(void) +{ + /* Open i2c bus for synchronous access */ + if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0)) + panic("Can't open i2c for TB sync !\n"); + + spin_lock(&timebase_lock); + (*pmac_tb_freeze)(1); + mb(); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + + spin_lock(&timebase_lock); + (*pmac_tb_freeze)(0); + spin_unlock(&timebase_lock); + + /* Close i2c bus */ + pmac_low_i2c_close(pmac_tb_clock_chip_host); +} + + +static void __devinit smp_core99_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + +static void __init smp_core99_setup(int ncpus) +{ + struct device_node *cc = NULL; + struct device_node *p; + u32 *reg; + int ok; + + /* HW sync only on these platforms */ + if (!machine_is_compatible("PowerMac7,2") && + !machine_is_compatible("PowerMac7,3") && + !machine_is_compatible("RackMac3,1")) + return; + + /* Look for the clock chip */ + while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) { + p = of_get_parent(cc); + ok = p && device_is_compatible(p, "uni-n-i2c"); + of_node_put(p); + if (!ok) + continue; + + reg = (u32 *)get_property(cc, "reg", NULL); + if (reg == NULL) + continue; + + switch (*reg) { + case 0xd2: + if (device_is_compatible(cc, "pulsar-legacy-slewing")) { + pmac_tb_freeze = smp_core99_pulsar_tb_freeze; + pmac_tb_pulsar_addr = 0xd2; + printk(KERN_INFO "Timebase clock is Pulsar chip\n"); + } else if (device_is_compatible(cc, "cy28508")) { + pmac_tb_freeze = smp_core99_cypress_tb_freeze; + printk(KERN_INFO "Timebase clock is Cypress chip\n"); + } + break; + case 0xd4: + pmac_tb_freeze = smp_core99_pulsar_tb_freeze; + pmac_tb_pulsar_addr = 0xd4; + printk(KERN_INFO "Timebase clock is Pulsar chip\n"); + break; + } + if (pmac_tb_freeze != NULL) { + pmac_tb_clock_chip_host = of_get_parent(cc); + of_node_put(cc); + break; + } + } + if (pmac_tb_freeze == NULL) { + smp_ops->give_timebase = smp_generic_give_timebase; + smp_ops->take_timebase = smp_generic_take_timebase; + } +} + +/* nothing to do here, caches are already set up by service processor */ +static inline void __devinit core99_init_caches(int cpu) +{ +} + +#else /* CONFIG_PPC64 */ + +/* + * SMP G4 powermacs use a GPIO to enable/disable the timebase. + */ + +static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */ + +static unsigned int pri_tb_hi, pri_tb_lo; +static unsigned int pri_tb_stamp; + +/* not __init, called in sleep/wakeup code */ +void smp_core99_give_timebase(void) +{ + unsigned long flags; + unsigned int t; + + /* wait for the secondary to be in take_timebase */ + for (t = 100000; t > 0 && !sec_tb_reset; --t) + udelay(10); + if (!sec_tb_reset) { + printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); + return; + } + + /* freeze the timebase and read it */ + /* disable interrupts so the timebase is disabled for the + shortest possible time */ + local_irq_save(flags); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + mb(); + pri_tb_hi = get_tbu(); + pri_tb_lo = get_tbl(); + pri_tb_stamp = last_jiffy_stamp(smp_processor_id()); + mb(); + + /* tell the secondary we're ready */ + sec_tb_reset = 2; + mb(); + + /* wait for the secondary to have taken it */ + for (t = 100000; t > 0 && sec_tb_reset; --t) + udelay(10); + if (sec_tb_reset) + printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); + else + smp_tb_synchronized = 1; + + /* Now, restart the timebase by leaving the GPIO to an open collector */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + local_irq_restore(flags); +} + +/* not __init, called in sleep/wakeup code */ +void smp_core99_take_timebase(void) +{ + unsigned long flags; + + /* tell the primary we're here */ + sec_tb_reset = 1; + mb(); + + /* wait for the primary to set pri_tb_hi/lo */ + while (sec_tb_reset < 2) + mb(); + + /* set our stuff the same as the primary */ + local_irq_save(flags); + set_dec(1); + set_tb(pri_tb_hi, pri_tb_lo); + last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp; + mb(); + + /* tell the primary we're done */ + sec_tb_reset = 0; + mb(); + local_irq_restore(flags); +} + +/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ +volatile static long int core99_l2_cache; +volatile static long int core99_l3_cache; + +static void __devinit core99_init_caches(int cpu) +{ + if (!cpu_has_feature(CPU_FTR_L2CR)) + return; + + if (cpu == 0) { + core99_l2_cache = _get_L2CR(); + printk("CPU0: L2CR is %lx\n", core99_l2_cache); } else { - if (firstcpu != NULL) - tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL); + printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); + _set_L2CR(0); + _set_L2CR(core99_l2_cache); + printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); + } + + if (!cpu_has_feature(CPU_FTR_L3CR)) + return; + + if (cpu == 0){ + core99_l3_cache = _get_L3CR(); + printk("CPU0: L3CR is %lx\n", core99_l3_cache); + } else { + printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR()); + _set_L3CR(0); + _set_L3CR(core99_l3_cache); + printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); + } +} + +static void __init smp_core99_setup(int ncpus) +{ + struct device_node *cpu; + u32 *tbprop = NULL; + int i; + + core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != NULL) { + tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL); if (tbprop) core99_tb_gpio = *tbprop; - else - core99_tb_gpio = KL_GPIO_TB_ENABLE; + of_node_put(cpu); } - if (ncpus > 1) { - mpic_request_ipis(); - for (i = 1; i < ncpus; ++i) - smp_hw_index[i] = i; -#ifdef CONFIG_6xx - powersave_nap = 0; + /* XXX should get this from reg properties */ + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + powersave_nap = 0; +} #endif - core99_init_caches(0); - } + +static int __init smp_core99_probe(void) +{ + struct device_node *cpus; + int ncpus = 0; + + if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); + + /* Count CPUs in the device-tree */ + for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;) + ++ncpus; + + printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus); + + /* Nothing more to do if less than 2 of them */ + if (ncpus <= 1) + return 1; + + smp_core99_setup(ncpus); + mpic_request_ipis(); + core99_init_caches(0); return ncpus; } static void __devinit smp_core99_kick_cpu(int nr) { - unsigned long save_vector, new_vector; + unsigned int save_vector; + unsigned long new_vector; unsigned long flags; + volatile unsigned int *vector + = ((volatile unsigned int *)(KERNELBASE+0x100)); - volatile unsigned long *vector - = ((volatile unsigned long *)(KERNELBASE+0x100)); if (nr < 0 || nr > 3) return; if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); @@ -556,113 +809,10 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr) } } -/* not __init, called in sleep/wakeup code */ -void smp_core99_take_timebase(void) -{ - unsigned long flags; - /* tell the primary we're here */ - sec_tb_reset = 1; - mb(); - - /* wait for the primary to set pri_tb_hi/lo */ - while (sec_tb_reset < 2) - mb(); - - /* set our stuff the same as the primary */ - local_irq_save(flags); - set_dec(1); - set_tb(pri_tb_hi, pri_tb_lo); - last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp; - mb(); - - /* tell the primary we're done */ - sec_tb_reset = 0; - mb(); - local_irq_restore(flags); -} - -/* not __init, called in sleep/wakeup code */ -void smp_core99_give_timebase(void) -{ - unsigned long flags; - unsigned int t; - - /* wait for the secondary to be in take_timebase */ - for (t = 100000; t > 0 && !sec_tb_reset; --t) - udelay(10); - if (!sec_tb_reset) { - printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); - return; - } - - /* freeze the timebase and read it */ - /* disable interrupts so the timebase is disabled for the - shortest possible time */ - local_irq_save(flags); - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); - pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); - mb(); - pri_tb_hi = get_tbu(); - pri_tb_lo = get_tbl(); - pri_tb_stamp = last_jiffy_stamp(smp_processor_id()); - mb(); - - /* tell the secondary we're ready */ - sec_tb_reset = 2; - mb(); - - /* wait for the secondary to have taken it */ - for (t = 100000; t > 0 && sec_tb_reset; --t) - udelay(10); - if (sec_tb_reset) - printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); - else - smp_tb_synchronized = 1; - - /* Now, restart the timebase by leaving the GPIO to an open collector */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); - pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); - local_irq_restore(flags); -} - -void smp_core99_message_pass(int target, int msg) -{ - cpumask_t mask = CPU_MASK_ALL; - /* make sure we're sending something that translates to an IPI */ - if (msg > 0x3) { - printk("SMP %d: smp_message_pass: unknown msg %d\n", - smp_processor_id(), msg); - return; - } - switch (target) { - case MSG_ALL: - mpic_send_ipi(msg, cpus_addr(mask)[0]); - break; - case MSG_ALL_BUT_SELF: - cpu_clear(smp_processor_id(), mask); - mpic_send_ipi(msg, cpus_addr(mask)[0]); - break; - default: - mpic_send_ipi(msg, 1 << target); - break; - } -} - - -/* PowerSurge-style Macs */ -struct smp_ops_t psurge_smp_ops = { - .message_pass = smp_psurge_message_pass, - .probe = smp_psurge_probe, - .kick_cpu = smp_psurge_kick_cpu, - .setup_cpu = smp_psurge_setup_cpu, - .give_timebase = smp_psurge_give_timebase, - .take_timebase = smp_psurge_take_timebase, -}; - -/* Core99 Macs (dual G4s) */ +/* Core99 Macs (dual G4s and G5s) */ struct smp_ops_t core99_smp_ops = { - .message_pass = smp_core99_message_pass, + .message_pass = smp_mpic_message_pass, .probe = smp_core99_probe, .kick_cpu = smp_core99_kick_cpu, .setup_cpu = smp_core99_setup_cpu, @@ -670,7 +820,7 @@ struct smp_ops_t core99_smp_ops = { .take_timebase = smp_core99_take_timebase, }; -#ifdef CONFIG_HOTPLUG_CPU +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) int __cpu_disable(void) { @@ -685,7 +835,7 @@ int __cpu_disable(void) return 0; } -extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */ +extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */ static int cpu_dead[NR_CPUS]; void cpu_die(void) diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index a6d2d231d5a0..82982bf6453c 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -33,6 +33,7 @@ #include #include #include +#include #undef DEBUG @@ -68,8 +69,8 @@ long __init pmac_time_init(void) { -#ifdef CONFIG_NVRAM s32 delta = 0; +#ifdef CONFIG_NVRAM int dst; delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; @@ -80,110 +81,181 @@ long __init pmac_time_init(void) dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, dst ? "on" : "off"); - return delta; -#else - return 0; #endif + return delta; } +static void to_rtc_time(unsigned long now, struct rtc_time *tm) +{ + to_tm(now, tm); + tm->tm_year -= 1900; + tm->tm_mon -= 1; +} + +static unsigned long from_rtc_time(struct rtc_time *tm) +{ + return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +} + +#ifdef CONFIG_ADB_CUDA +static unsigned long cuda_get_time(void) +{ + struct adb_request req; + unsigned long now; + + if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) + return 0; + while (!req.complete) + cuda_poll(); + if (req.reply_len != 7) + printk(KERN_ERR "cuda_get_time: got %d byte reply\n", + req.reply_len); + now = (req.reply[3] << 24) + (req.reply[4] << 16) + + (req.reply[5] << 8) + req.reply[6]; + if (now < RTC_OFFSET) + return 0; + return now - RTC_OFFSET; +} + +#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm)) + +static int cuda_set_rtc_time(struct rtc_time *tm) +{ + unsigned int nowtime; + struct adb_request req; + + nowtime = from_rtc_time(tm) + RTC_OFFSET; + if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, + nowtime >> 24, nowtime >> 16, nowtime >> 8, + nowtime) < 0) + return -ENXIO; + while (!req.complete) + cuda_poll(); + if ((req.reply_len != 3) && (req.reply_len != 7)) + printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n", + req.reply_len); + return 0; +} + +#else +#define cuda_get_time() 0 +#define cuda_get_rtc_time(tm) +#define cuda_set_rtc_time(tm) 0 +#endif + +#ifdef CONFIG_ADB_PMU +static unsigned long pmu_get_time(void) +{ + struct adb_request req; + unsigned long now; + + if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) + return 0; + pmu_wait_complete(&req); + if (req.reply_len != 4) + printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n", + req.reply_len); + now = (req.reply[0] << 24) + (req.reply[1] << 16) + + (req.reply[2] << 8) + req.reply[3]; + if (now < RTC_OFFSET) + return 0; + return now - RTC_OFFSET; +} + +#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm)) + +static int pmu_set_rtc_time(struct rtc_time *tm) +{ + unsigned int nowtime; + struct adb_request req; + + nowtime = from_rtc_time(tm) + RTC_OFFSET; + if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24, + nowtime >> 16, nowtime >> 8, nowtime) < 0) + return -ENXIO; + pmu_wait_complete(&req); + if (req.reply_len != 0) + printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n", + req.reply_len); + return 0; +} + +#else +#define pmu_get_time() 0 +#define pmu_get_rtc_time(tm) +#define pmu_set_rtc_time(tm) 0 +#endif + +#ifdef CONFIG_PMAC_SMU +static unsigned long smu_get_time(void) +{ + struct rtc_time tm; + + if (smu_get_rtc_time(&tm, 1)) + return 0; + return from_rtc_time(&tm); +} + +#else +#define smu_get_time() 0 +#define smu_get_rtc_time(tm, spin) +#define smu_set_rtc_time(tm, spin) 0 +#endif + unsigned long pmac_get_boot_time(void) { -#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) - struct adb_request req; - unsigned long now; -#endif - - /* Get the time from the RTC */ + /* Get the time from the RTC, used only at boot time */ switch (sys_ctrler) { -#ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: - if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) - return 0; - while (!req.complete) - cuda_poll(); - if (req.reply_len != 7) - printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", - req.reply_len); - now = (req.reply[3] << 24) + (req.reply[4] << 16) - + (req.reply[5] << 8) + req.reply[6]; - return now - RTC_OFFSET; -#endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU + return cuda_get_time(); case SYS_CTRLER_PMU: - if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) - return 0; - while (!req.complete) - pmu_poll(); - if (req.reply_len != 4) - printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", - req.reply_len); - now = (req.reply[0] << 24) + (req.reply[1] << 16) - + (req.reply[2] << 8) + req.reply[3]; - return now - RTC_OFFSET; -#endif /* CONFIG_ADB_PMU */ - default: ; - } - return 0; -} - -void pmac_get_rtc_time(struct rtc_time *tm) -{ - unsigned long now; - - now = pmac_get_boot_time(); - to_tm(now, tm); - tm->tm_year -= 1900; - tm->tm_mon -= 1; /* month is 0-based */ -} - -int pmac_set_rtc_time(struct rtc_time *tm) -{ - unsigned long nowtime; -#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) - struct adb_request req; -#endif - - nowtime = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - nowtime += RTC_OFFSET; - - switch (sys_ctrler) { -#ifdef CONFIG_ADB_CUDA - case SYS_CTRLER_CUDA: - if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, - nowtime >> 24, nowtime >> 16, nowtime >> 8, - nowtime) < 0) - return 0; - while (!req.complete) - cuda_poll(); - if ((req.reply_len != 3) && (req.reply_len != 7)) - printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", - req.reply_len); - return 1; -#endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU - case SYS_CTRLER_PMU: - if (pmu_request(&req, NULL, 5, PMU_SET_RTC, - nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) - return 0; - while (!req.complete) - pmu_poll(); - if (req.reply_len != 0) - printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", - req.reply_len); - return 1; -#endif /* CONFIG_ADB_PMU */ + return pmu_get_time(); + case SYS_CTRLER_SMU: + return smu_get_time(); default: return 0; } } +void pmac_get_rtc_time(struct rtc_time *tm) +{ + /* Get the time from the RTC, used only at boot time */ + switch (sys_ctrler) { + case SYS_CTRLER_CUDA: + cuda_get_rtc_time(tm); + break; + case SYS_CTRLER_PMU: + pmu_get_rtc_time(tm); + break; + case SYS_CTRLER_SMU: + smu_get_rtc_time(tm, 1); + break; + default: + ; + } +} + +int pmac_set_rtc_time(struct rtc_time *tm) +{ + switch (sys_ctrler) { + case SYS_CTRLER_CUDA: + return cuda_set_rtc_time(tm); + case SYS_CTRLER_PMU: + return pmu_set_rtc_time(tm); + case SYS_CTRLER_SMU: + return smu_set_rtc_time(tm, 1); + default: + return -ENODEV; + } +} + +#ifdef CONFIG_PPC32 /* * Calibrate the decrementer register using VIA timer 1. * This is used both on powermacs and CHRP machines. */ -int __init -via_calibrate_decr(void) +int __init via_calibrate_decr(void) { struct device_node *vias; volatile unsigned char __iomem *via; @@ -217,15 +289,12 @@ via_calibrate_decr(void) dend = get_dec(); ppc_tb_freq = (dstart - dend) * 100 / 6; - tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); - - printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %lu (%u ticks)\n", - tb_ticks_per_jiffy, dstart - dend); iounmap(via); return 1; } +#endif #ifdef CONFIG_PM /* @@ -262,19 +331,17 @@ static struct pmu_sleep_notifier time_sleep_notifier = { /* * Query the OF and get the decr frequency. - * This was taken from the pmac time_init() when merging the prep/pmac - * time functions. */ -void __init -pmac_calibrate_decr(void) +void __init pmac_calibrate_decr(void) { - struct device_node *cpu; - unsigned int freq, *fp; - #ifdef CONFIG_PM + /* XXX why here? */ pmu_register_sleep_notifier(&time_sleep_notifier); #endif /* CONFIG_PM */ + generic_calibrate_decr(); + +#ifdef CONFIG_PPC32 /* We assume MacRISC2 machines have correct device-tree * calibration. That's better since the VIA itself seems * to be slightly off. --BenH @@ -293,18 +360,5 @@ pmac_calibrate_decr(void) if (machine_is_compatible("PowerMac3,5")) if (via_calibrate_decr()) return; - /* - * The cpu node should have a timebase-frequency property - * to tell us the rate at which the decrementer counts. - */ - cpu = find_type_devices("cpu"); - if (cpu == 0) - panic("can't find cpu node in time_init"); - fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); - if (fp == 0) - panic("can't get cpu timebase frequency"); - freq = *fp; - printk("time_init: decrementer frequency = %u.%.6u MHz\n", - freq/1000000, freq%1000000); - ppc_tb_freq = freq; +#endif } diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 8a0969b6243c..b3a93b476d97 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -119,6 +119,8 @@ struct machdep_calls { /* Interface for platform error logging */ void (*log_error)(char *buf, unsigned int err_type, int fatal); + unsigned char (*nvram_read_val)(int addr); + void (*nvram_write_val)(int addr, unsigned char val); ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_size)(void); @@ -165,15 +167,11 @@ struct machdep_calls { unsigned long heartbeat_reset; unsigned long heartbeat_count; - unsigned long (*find_end_of_memory)(void); void (*setup_io_mappings)(void); void (*early_serial_map)(void); void (*kgdb_map_scc)(void); - unsigned char (*nvram_read_val)(int addr); - void (*nvram_write_val)(int addr, unsigned char val); - /* * optional PCI "hooks" */ diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index d1e00933354c..2e17ef7dbeb4 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -148,6 +148,8 @@ struct thread_struct; extern struct task_struct * _switch(struct thread_struct *prev, struct thread_struct *next); +extern int powersave_nap; /* set if nap mode can be used in idle loop */ + /* * Atomic exchange * diff --git a/include/asm-ppc64/udbg.h b/include/asm-ppc64/udbg.h index c786604aef02..8192fb8541cc 100644 --- a/include/asm-ppc64/udbg.h +++ b/include/asm-ppc64/udbg.h @@ -28,4 +28,7 @@ extern unsigned long udbg_ifdebug(unsigned long flags); extern void __init ppcdbg_initialize(void); extern void udbg_init_uart(void __iomem *comport, unsigned int speed); + +struct device_node; +extern void udbg_init_scc(struct device_node *np); #endif From 834289447542b7ec55c0847486616d4d53ddf891 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 22 Oct 2005 16:06:27 +1000 Subject: [PATCH 0434/1940] ppc64: Use arch/powerpc/platforms/powermac for powermac build. This switches the ARCH=ppc64 build to use arch/powerpc/platforms/powermac instead of arch/ppc64/kernel/pmac*, and deletes the latter set of files. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/Makefile | 4 + arch/ppc64/kernel/Makefile | 10 +- arch/ppc64/kernel/pmac.h | 31 -- arch/ppc64/kernel/pmac_feature.c | 767 ------------------------------ arch/ppc64/kernel/pmac_low_i2c.c | 523 -------------------- arch/ppc64/kernel/pmac_nvram.c | 493 ------------------- arch/ppc64/kernel/pmac_pci.c | 793 ------------------------------- arch/ppc64/kernel/pmac_setup.c | 476 ------------------- arch/ppc64/kernel/pmac_smp.c | 316 ------------ arch/ppc64/kernel/pmac_time.c | 174 ------- 10 files changed, 6 insertions(+), 3581 deletions(-) delete mode 100644 arch/ppc64/kernel/pmac.h delete mode 100644 arch/ppc64/kernel/pmac_feature.c delete mode 100644 arch/ppc64/kernel/pmac_low_i2c.c delete mode 100644 arch/ppc64/kernel/pmac_nvram.c delete mode 100644 arch/ppc64/kernel/pmac_pci.c delete mode 100644 arch/ppc64/kernel/pmac_setup.c delete mode 100644 arch/ppc64/kernel/pmac_smp.c delete mode 100644 arch/ppc64/kernel/pmac_time.c diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 9b54e805b8aa..509622da5408 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -1,5 +1,9 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_PMAC) += powermac/ +else +ifeq ($(CONFIG_PPC64),y) +obj-$(CONFIG_PPC_PMAC) += powermac/ +endif endif obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_85xx) += 85xx/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 6c02a79955c7..424dd250cd87 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -56,11 +56,7 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o -ifneq ($(CONFIG_PPC_MERGE),y) -obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ - pmac_time.o pmac_nvram.o pmac_low_i2c.o \ - udbg_scc.o -endif +obj-$(CONFIG_PPC_PMAC) += udbg_scc.o obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ udbg_16550.o @@ -68,9 +64,7 @@ obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ obj-$(CONFIG_U3_DART) += u3_iommu.o ifdef CONFIG_SMP -ifneq ($(CONFIG_PPC_MERGE),y) -obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o -endif +obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o endif diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h deleted file mode 100644 index fa59f2a5c722..000000000000 --- a/arch/ppc64/kernel/pmac.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __PMAC_H__ -#define __PMAC_H__ - -#include -#include - -/* - * Declaration for the various functions exported by the - * pmac_* files. Mostly for use by pmac_setup - */ - -extern unsigned long pmac_get_boot_time(void); -extern void pmac_get_rtc_time(struct rtc_time *tm); -extern int pmac_set_rtc_time(struct rtc_time *tm); -extern void pmac_read_rtc_time(void); -extern void pmac_calibrate_decr(void); - -extern void pmac_pcibios_fixup(void); -extern void pmac_pci_init(void); -extern void pmac_setup_pci_dma(void); -extern void pmac_check_ht_link(void); - -extern void pmac_setup_smp(void); - -extern unsigned long pmac_ide_get_base(int index); -extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, - unsigned long data_port, unsigned long ctrl_port, int *irq); - -extern void pmac_nvram_init(void); - -#endif /* __PMAC_H__ */ diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c deleted file mode 100644 index 26075f11db77..000000000000 --- a/arch/ppc64/kernel/pmac_feature.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * arch/ppc/platforms/pmac_feature.c - * - * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au) - * Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * 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. - * - * TODO: - * - * - Replace mdelay with some schedule loop if possible - * - Shorten some obfuscated delays on some routines (like modem - * power) - * - Refcount some clocks (see darwin) - * - Split split split... - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_FEATURE - -#ifdef DEBUG_FEATURE -#define DBG(fmt...) printk(KERN_DEBUG fmt) -#else -#define DBG(fmt...) -#endif - -/* - * We use a single global lock to protect accesses. Each driver has - * to take care of its own locking - */ -static DEFINE_SPINLOCK(feature_lock); - -#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); -#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); - - -/* - * Instance of some macio stuffs - */ -struct macio_chip macio_chips[MAX_MACIO_CHIPS] ; - -struct macio_chip* macio_find(struct device_node* child, int type) -{ - while(child) { - int i; - - for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++) - if (child == macio_chips[i].of_node && - (!type || macio_chips[i].type == type)) - return &macio_chips[i]; - child = child->parent; - } - return NULL; -} -EXPORT_SYMBOL_GPL(macio_find); - -static const char* macio_names[] = -{ - "Unknown", - "Grand Central", - "OHare", - "OHareII", - "Heathrow", - "Gatwick", - "Paddington", - "Keylargo", - "Pangea", - "Intrepid", - "K2" -}; - - - -/* - * Uninorth reg. access. Note that Uni-N regs are big endian - */ - -#define UN_REG(r) (uninorth_base + ((r) >> 2)) -#define UN_IN(r) (in_be32(UN_REG(r))) -#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) -#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) -#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) - -static struct device_node* uninorth_node; -static u32* uninorth_base; -static u32 uninorth_rev; -static void *u3_ht; - -extern struct device_node *k2_skiplist[2]; - -/* - * For each motherboard family, we have a table of functions pointers - * that handle the various features. - */ - -typedef long (*feature_call)(struct device_node* node, long param, long value); - -struct feature_table_entry { - unsigned int selector; - feature_call function; -}; - -struct pmac_mb_def -{ - const char* model_string; - const char* model_name; - int model_id; - struct feature_table_entry* features; - unsigned long board_flags; -}; -static struct pmac_mb_def pmac_mb; - -/* - * Here are the chip specific feature functions - */ - - -static long g5_read_gpio(struct device_node* node, long param, long value) -{ - struct macio_chip* macio = &macio_chips[0]; - - return MACIO_IN8(param); -} - - -static long g5_write_gpio(struct device_node* node, long param, long value) -{ - struct macio_chip* macio = &macio_chips[0]; - - MACIO_OUT8(param, (u8)(value & 0xff)); - return 0; -} - -static long g5_gmac_enable(struct device_node* node, long param, long value) -{ - struct macio_chip* macio = &macio_chips[0]; - unsigned long flags; - - if (node == NULL) - return -ENODEV; - - LOCK(flags); - if (value) { - MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); - mb(); - k2_skiplist[0] = NULL; - } else { - k2_skiplist[0] = node; - mb(); - MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); - } - - UNLOCK(flags); - mdelay(1); - - return 0; -} - -static long g5_fw_enable(struct device_node* node, long param, long value) -{ - struct macio_chip* macio = &macio_chips[0]; - unsigned long flags; - - if (node == NULL) - return -ENODEV; - - LOCK(flags); - if (value) { - MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); - mb(); - k2_skiplist[1] = NULL; - } else { - k2_skiplist[1] = node; - mb(); - MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); - } - - UNLOCK(flags); - mdelay(1); - - return 0; -} - -static long g5_mpic_enable(struct device_node* node, long param, long value) -{ - unsigned long flags; - - if (node->parent == NULL || strcmp(node->parent->name, "u3")) - return 0; - - LOCK(flags); - UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE); - UNLOCK(flags); - - return 0; -} - -static long g5_eth_phy_reset(struct device_node* node, long param, long value) -{ - struct macio_chip* macio = &macio_chips[0]; - struct device_node *phy; - int need_reset; - - /* - * We must not reset the combo PHYs, only the BCM5221 found in - * the iMac G5. - */ - phy = of_get_next_child(node, NULL); - if (!phy) - return -ENODEV; - need_reset = device_is_compatible(phy, "B5221"); - of_node_put(phy); - if (!need_reset) - return 0; - - /* PHY reset is GPIO 29, not in device-tree unfortunately */ - MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, - KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - /* Thankfully, this is now always called at a time when we can - * schedule by sungem. - */ - msleep(10); - MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0); - - return 0; -} - -static long g5_i2s_enable(struct device_node *node, long param, long value) -{ - /* Very crude implementation for now */ - struct macio_chip* macio = &macio_chips[0]; - unsigned long flags; - - if (value == 0) - return 0; /* don't disable yet */ - - LOCK(flags); - MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE | - KL3_I2S0_CLK18_ENABLE); - udelay(10); - MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE | - K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE); - udelay(10); - MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET); - UNLOCK(flags); - udelay(10); - - return 0; -} - - -#ifdef CONFIG_SMP -static long g5_reset_cpu(struct device_node* node, long param, long value) -{ - unsigned int reset_io = 0; - unsigned long flags; - struct macio_chip* macio; - struct device_node* np; - - macio = &macio_chips[0]; - if (macio->type != macio_keylargo2) - return -ENODEV; - - np = find_path_device("/cpus"); - if (np == NULL) - return -ENODEV; - for (np = np->child; np != NULL; np = np->sibling) { - u32* num = (u32 *)get_property(np, "reg", NULL); - u32* rst = (u32 *)get_property(np, "soft-reset", NULL); - if (num == NULL || rst == NULL) - continue; - if (param == *num) { - reset_io = *rst; - break; - } - } - if (np == NULL || reset_io == 0) - return -ENODEV; - - LOCK(flags); - MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); - (void)MACIO_IN8(reset_io); - udelay(1); - MACIO_OUT8(reset_io, 0); - (void)MACIO_IN8(reset_io); - UNLOCK(flags); - - return 0; -} -#endif /* CONFIG_SMP */ - -/* - * This can be called from pmac_smp so isn't static - * - * This takes the second CPU off the bus on dual CPU machines - * running UP - */ -void g5_phy_disable_cpu1(void) -{ - UN_OUT(U3_API_PHY_CONFIG_1, 0); -} - -static long generic_get_mb_info(struct device_node* node, long param, long value) -{ - switch(param) { - case PMAC_MB_INFO_MODEL: - return pmac_mb.model_id; - case PMAC_MB_INFO_FLAGS: - return pmac_mb.board_flags; - case PMAC_MB_INFO_NAME: - /* hack hack hack... but should work */ - *((const char **)value) = pmac_mb.model_name; - return 0; - } - return -EINVAL; -} - - -/* - * Table definitions - */ - -/* Used on any machine - */ -static struct feature_table_entry any_features[] = { - { PMAC_FTR_GET_MB_INFO, generic_get_mb_info }, - { 0, NULL } -}; - -/* G5 features - */ -static struct feature_table_entry g5_features[] = { - { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable }, - { PMAC_FTR_1394_ENABLE, g5_fw_enable }, - { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable }, - { PMAC_FTR_READ_GPIO, g5_read_gpio }, - { PMAC_FTR_WRITE_GPIO, g5_write_gpio }, - { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset }, - { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable }, -#ifdef CONFIG_SMP - { PMAC_FTR_RESET_CPU, g5_reset_cpu }, -#endif /* CONFIG_SMP */ - { 0, NULL } -}; - -static struct pmac_mb_def pmac_mb_defs[] = { - { "PowerMac7,2", "PowerMac G5", - PMAC_TYPE_POWERMAC_G5, g5_features, - 0, - }, - { "PowerMac7,3", "PowerMac G5", - PMAC_TYPE_POWERMAC_G5, g5_features, - 0, - }, - { "PowerMac8,1", "iMac G5", - PMAC_TYPE_IMAC_G5, g5_features, - 0, - }, - { "PowerMac9,1", "PowerMac G5", - PMAC_TYPE_POWERMAC_G5_U3L, g5_features, - 0, - }, - { "RackMac3,1", "XServe G5", - PMAC_TYPE_XSERVE_G5, g5_features, - 0, - }, -}; - -/* - * The toplevel feature_call callback - */ -long pmac_do_feature_call(unsigned int selector, ...) -{ - struct device_node* node; - long param, value; - int i; - feature_call func = NULL; - va_list args; - - if (pmac_mb.features) - for (i=0; pmac_mb.features[i].function; i++) - if (pmac_mb.features[i].selector == selector) { - func = pmac_mb.features[i].function; - break; - } - if (!func) - for (i=0; any_features[i].function; i++) - if (any_features[i].selector == selector) { - func = any_features[i].function; - break; - } - if (!func) - return -ENODEV; - - va_start(args, selector); - node = (struct device_node*)va_arg(args, void*); - param = va_arg(args, long); - value = va_arg(args, long); - va_end(args); - - return func(node, param, value); -} - -static int __init probe_motherboard(void) -{ - int i; - struct macio_chip* macio = &macio_chips[0]; - const char* model = NULL; - struct device_node *dt; - - /* Lookup known motherboard type in device-tree. First try an - * exact match on the "model" property, then try a "compatible" - * match is none is found. - */ - dt = find_devices("device-tree"); - if (dt != NULL) - model = (const char *) get_property(dt, "model", NULL); - for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { - if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { - pmac_mb = pmac_mb_defs[i]; - goto found; - } - } - for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { - if (machine_is_compatible(pmac_mb_defs[i].model_string)) { - pmac_mb = pmac_mb_defs[i]; - goto found; - } - } - - /* Fallback to selection depending on mac-io chip type */ - switch(macio->type) { - case macio_keylargo2: - pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2; - pmac_mb.model_name = "Unknown K2-based"; - pmac_mb.features = g5_features; - - default: - return -ENODEV; - } -found: - /* Check for "mobile" machine */ - if (model && (strncmp(model, "PowerBook", 9) == 0 - || strncmp(model, "iBook", 5) == 0)) - pmac_mb.board_flags |= PMAC_MB_MOBILE; - - - printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); - return 0; -} - -/* Initialize the Core99 UniNorth host bridge and memory controller - */ -static void __init probe_uninorth(void) -{ - uninorth_node = of_find_node_by_name(NULL, "u3"); - if (uninorth_node && uninorth_node->n_addrs > 0) { - /* Small hack until I figure out if parsing in prom.c is correct. I should - * get rid of those pre-parsed junk anyway - */ - unsigned long address = uninorth_node->addrs[0].address; - uninorth_base = ioremap(address, 0x40000); - uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); - u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); - } else - uninorth_node = NULL; - - if (!uninorth_node) - return; - - printk(KERN_INFO "Found U3 memory controller & host bridge, revision: %d\n", - uninorth_rev); - printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); - -} - -static void __init probe_one_macio(const char* name, const char* compat, int type) -{ - struct device_node* node; - int i; - volatile u32* base; - u32* revp; - - node = find_devices(name); - if (!node || !node->n_addrs) - return; - if (compat) - do { - if (device_is_compatible(node, compat)) - break; - node = node->next; - } while (node); - if (!node) - return; - for(i=0; i= MAX_MACIO_CHIPS) { - printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); - printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); - return; - } - base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size); - if (!base) { - printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); - return; - } - if (type == macio_keylargo) { - u32* did = (u32 *)get_property(node, "device-id", NULL); - if (*did == 0x00000025) - type = macio_pangea; - if (*did == 0x0000003e) - type = macio_intrepid; - } - macio_chips[i].of_node = node; - macio_chips[i].type = type; - macio_chips[i].base = base; - macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; - macio_chips[i].name = macio_names[type]; - revp = (u32 *)get_property(node, "revision-id", NULL); - if (revp) - macio_chips[i].rev = *revp; - printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", - macio_names[type], macio_chips[i].rev, macio_chips[i].base); -} - -static int __init -probe_macios(void) -{ - probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2); - - macio_chips[0].lbus.index = 0; - macio_chips[1].lbus.index = 1; - - return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; -} - -static void __init -set_initial_features(void) -{ - struct device_node *np; - - if (macio_chips[0].type == macio_keylargo2) { -#ifndef CONFIG_SMP - /* On SMP machines running UP, we have the second CPU eating - * bus cycles. We need to take it off the bus. This is done - * from pmac_smp for SMP kernels running on one CPU - */ - np = of_find_node_by_type(NULL, "cpu"); - if (np != NULL) - np = of_find_node_by_type(np, "cpu"); - if (np != NULL) { - g5_phy_disable_cpu1(); - of_node_put(np); - } -#endif /* CONFIG_SMP */ - /* Enable GMAC for now for PCI probing. It will be disabled - * later on after PCI probe - */ - np = of_find_node_by_name(NULL, "ethernet"); - while(np) { - if (device_is_compatible(np, "K2-GMAC")) - g5_gmac_enable(np, 0, 1); - np = of_find_node_by_name(np, "ethernet"); - } - - /* Enable FW before PCI probe. Will be disabled later on - * Note: We should have a batter way to check that we are - * dealing with uninorth internal cell and not a PCI cell - * on the external PCI. The code below works though. - */ - np = of_find_node_by_name(NULL, "firewire"); - while(np) { - if (device_is_compatible(np, "pci106b,5811")) { - macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; - g5_fw_enable(np, 0, 1); - } - np = of_find_node_by_name(np, "firewire"); - } - } -} - -void __init -pmac_feature_init(void) -{ - /* Detect the UniNorth memory controller */ - probe_uninorth(); - - /* Probe mac-io controllers */ - if (probe_macios()) { - printk(KERN_WARNING "No mac-io chip found\n"); - return; - } - - /* Setup low-level i2c stuffs */ - pmac_init_low_i2c(); - - /* Probe machine type */ - if (probe_motherboard()) - printk(KERN_WARNING "Unknown PowerMac !\n"); - - /* Set some initial features (turn off some chips that will - * be later turned on) - */ - set_initial_features(); -} - -int __init pmac_feature_late_init(void) -{ -#if 0 - struct device_node* np; - - /* Request some resources late */ - if (uninorth_node) - request_OF_resource(uninorth_node, 0, NULL); - np = find_devices("hammerhead"); - if (np) - request_OF_resource(np, 0, NULL); - np = find_devices("interrupt-controller"); - if (np) - request_OF_resource(np, 0, NULL); -#endif - return 0; -} - -device_initcall(pmac_feature_late_init); - -#if 0 -static void dump_HT_speeds(char *name, u32 cfg, u32 frq) -{ - int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 }; - int bits[8] = { 8,16,0,32,2,4,0,0 }; - int freq = (frq >> 8) & 0xf; - - if (freqs[freq] == 0) - printk("%s: Unknown HT link frequency %x\n", name, freq); - else - printk("%s: %d MHz on main link, (%d in / %d out) bits width\n", - name, freqs[freq], - bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]); -} -#endif - -void __init pmac_check_ht_link(void) -{ -#if 0 /* Disabled for now */ - u32 ufreq, freq, ucfg, cfg; - struct device_node *pcix_node; - struct pci_dn *pdn; - u8 px_bus, px_devfn; - struct pci_controller *px_hose; - - (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); - ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); - ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); - dump_HT_speeds("U3 HyperTransport", cfg, freq); - - pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); - if (pcix_node == NULL) { - printk("No PCI-X bridge found\n"); - return; - } - pdn = pcix_node->data; - px_hose = pdn->phb; - px_bus = pdn->busno; - px_devfn = pdn->devfn; - - early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); - early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); - dump_HT_speeds("PCI-X HT Uplink", cfg, freq); - early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg); - early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq); - dump_HT_speeds("PCI-X HT Downlink", cfg, freq); -#endif -} - -/* - * Early video resume hook - */ - -static void (*pmac_early_vresume_proc)(void *data); -static void *pmac_early_vresume_data; - -void pmac_set_early_video_resume(void (*proc)(void *data), void *data) -{ - if (_machine != _MACH_Pmac) - return; - preempt_disable(); - pmac_early_vresume_proc = proc; - pmac_early_vresume_data = data; - preempt_enable(); -} -EXPORT_SYMBOL(pmac_set_early_video_resume); - - -/* - * AGP related suspend/resume code - */ - -static struct pci_dev *pmac_agp_bridge; -static int (*pmac_agp_suspend)(struct pci_dev *bridge); -static int (*pmac_agp_resume)(struct pci_dev *bridge); - -void pmac_register_agp_pm(struct pci_dev *bridge, - int (*suspend)(struct pci_dev *bridge), - int (*resume)(struct pci_dev *bridge)) -{ - if (suspend || resume) { - pmac_agp_bridge = bridge; - pmac_agp_suspend = suspend; - pmac_agp_resume = resume; - return; - } - if (bridge != pmac_agp_bridge) - return; - pmac_agp_suspend = pmac_agp_resume = NULL; - return; -} -EXPORT_SYMBOL(pmac_register_agp_pm); - -void pmac_suspend_agp_for_card(struct pci_dev *dev) -{ - if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL) - return; - if (pmac_agp_bridge->bus != dev->bus) - return; - pmac_agp_suspend(pmac_agp_bridge); -} -EXPORT_SYMBOL(pmac_suspend_agp_for_card); - -void pmac_resume_agp_for_card(struct pci_dev *dev) -{ - if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL) - return; - if (pmac_agp_bridge->bus != dev->bus) - return; - pmac_agp_resume(pmac_agp_bridge); -} -EXPORT_SYMBOL(pmac_resume_agp_for_card); diff --git a/arch/ppc64/kernel/pmac_low_i2c.c b/arch/ppc64/kernel/pmac_low_i2c.c deleted file mode 100644 index f3f39e8e337a..000000000000 --- a/arch/ppc64/kernel/pmac_low_i2c.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * arch/ppc/platforms/pmac_low_i2c.c - * - * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * 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 file contains some low-level i2c access routines that - * need to be used by various bits of the PowerMac platform code - * at times where the real asynchronous & interrupt driven driver - * cannot be used. The API borrows some semantics from the darwin - * driver in order to ease the implementation of the platform - * properties parser - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_LOW_I2C_HOST 4 - -#ifdef DEBUG -#define DBG(x...) do {\ - printk(KERN_DEBUG "KW:" x); \ - } while(0) -#else -#define DBG(x...) -#endif - -struct low_i2c_host; - -typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len); - -struct low_i2c_host -{ - struct device_node *np; /* OF device node */ - struct semaphore mutex; /* Access mutex for use by i2c-keywest */ - low_i2c_func_t func; /* Access function */ - unsigned int is_open : 1; /* Poor man's access control */ - int mode; /* Current mode */ - int channel; /* Current channel */ - int num_channels; /* Number of channels */ - void __iomem *base; /* For keywest-i2c, base address */ - int bsteps; /* And register stepping */ - int speed; /* And speed */ -}; - -static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST]; - -/* No locking is necessary on allocation, we are running way before - * anything can race with us - */ -static struct low_i2c_host *find_low_i2c_host(struct device_node *np) -{ - int i; - - for (i = 0; i < MAX_LOW_I2C_HOST; i++) - if (low_i2c_hosts[i].np == np) - return &low_i2c_hosts[i]; - return NULL; -} - -/* - * - * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's) - * - */ - -/* - * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h, - * should be moved somewhere in include/asm-ppc/ - */ -/* Register indices */ -typedef enum { - reg_mode = 0, - reg_control, - reg_status, - reg_isr, - reg_ier, - reg_addr, - reg_subaddr, - reg_data -} reg_t; - - -/* Mode register */ -#define KW_I2C_MODE_100KHZ 0x00 -#define KW_I2C_MODE_50KHZ 0x01 -#define KW_I2C_MODE_25KHZ 0x02 -#define KW_I2C_MODE_DUMB 0x00 -#define KW_I2C_MODE_STANDARD 0x04 -#define KW_I2C_MODE_STANDARDSUB 0x08 -#define KW_I2C_MODE_COMBINED 0x0C -#define KW_I2C_MODE_MODE_MASK 0x0C -#define KW_I2C_MODE_CHAN_MASK 0xF0 - -/* Control register */ -#define KW_I2C_CTL_AAK 0x01 -#define KW_I2C_CTL_XADDR 0x02 -#define KW_I2C_CTL_STOP 0x04 -#define KW_I2C_CTL_START 0x08 - -/* Status register */ -#define KW_I2C_STAT_BUSY 0x01 -#define KW_I2C_STAT_LAST_AAK 0x02 -#define KW_I2C_STAT_LAST_RW 0x04 -#define KW_I2C_STAT_SDA 0x08 -#define KW_I2C_STAT_SCL 0x10 - -/* IER & ISR registers */ -#define KW_I2C_IRQ_DATA 0x01 -#define KW_I2C_IRQ_ADDR 0x02 -#define KW_I2C_IRQ_STOP 0x04 -#define KW_I2C_IRQ_START 0x08 -#define KW_I2C_IRQ_MASK 0x0F - -/* State machine states */ -enum { - state_idle, - state_addr, - state_read, - state_write, - state_stop, - state_dead -}; - -#define WRONG_STATE(name) do {\ - printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ - name, __kw_state_names[state], isr); \ - } while(0) - -static const char *__kw_state_names[] = { - "state_idle", - "state_addr", - "state_read", - "state_write", - "state_stop", - "state_dead" -}; - -static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg) -{ - return readb(host->base + (((unsigned int)reg) << host->bsteps)); -} - -static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val) -{ - writeb(val, host->base + (((unsigned)reg) << host->bsteps)); - (void)__kw_read_reg(host, reg_subaddr); -} - -#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) -#define kw_read_reg(reg) __kw_read_reg(host, reg) - - -/* Don't schedule, the g5 fan controller is too - * timing sensitive - */ -static u8 kw_wait_interrupt(struct low_i2c_host* host) -{ - int i, j; - u8 isr; - - for (i = 0; i < 100000; i++) { - isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; - if (isr != 0) - return isr; - - /* This code is used with the timebase frozen, we cannot rely - * on udelay ! For now, just use a bogus loop - */ - for (j = 1; j < 10000; j++) - mb(); - } - return isr; -} - -static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr) -{ - u8 ack; - - DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr); - - if (isr == 0) { - if (state != state_stop) { - DBG("KW: Timeout !\n"); - *rc = -EIO; - goto stop; - } - if (state == state_stop) { - ack = kw_read_reg(reg_status); - if (!(ack & KW_I2C_STAT_BUSY)) { - state = state_idle; - kw_write_reg(reg_ier, 0x00); - } - } - return state; - } - - if (isr & KW_I2C_IRQ_ADDR) { - ack = kw_read_reg(reg_status); - if (state != state_addr) { - kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); - WRONG_STATE("KW_I2C_IRQ_ADDR"); - *rc = -EIO; - goto stop; - } - if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { - *rc = -ENODEV; - DBG("KW: NAK on address\n"); - return state_stop; - } else { - if (rw) { - state = state_read; - if (*len > 1) - kw_write_reg(reg_control, KW_I2C_CTL_AAK); - } else { - state = state_write; - kw_write_reg(reg_data, **data); - (*data)++; (*len)--; - } - } - kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); - } - - if (isr & KW_I2C_IRQ_DATA) { - if (state == state_read) { - **data = kw_read_reg(reg_data); - (*data)++; (*len)--; - kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); - if ((*len) == 0) - state = state_stop; - else if ((*len) == 1) - kw_write_reg(reg_control, 0); - } else if (state == state_write) { - ack = kw_read_reg(reg_status); - if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { - DBG("KW: nack on data write\n"); - *rc = -EIO; - goto stop; - } else if (*len) { - kw_write_reg(reg_data, **data); - (*data)++; (*len)--; - } else { - kw_write_reg(reg_control, KW_I2C_CTL_STOP); - state = state_stop; - *rc = 0; - } - kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); - } else { - kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); - WRONG_STATE("KW_I2C_IRQ_DATA"); - if (state != state_stop) { - *rc = -EIO; - goto stop; - } - } - } - - if (isr & KW_I2C_IRQ_STOP) { - kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); - if (state != state_stop) { - WRONG_STATE("KW_I2C_IRQ_STOP"); - *rc = -EIO; - } - return state_idle; - } - - if (isr & KW_I2C_IRQ_START) - kw_write_reg(reg_isr, KW_I2C_IRQ_START); - - return state; - - stop: - kw_write_reg(reg_control, KW_I2C_CTL_STOP); - return state_stop; -} - -static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len) -{ - u8 mode_reg = host->speed; - int state = state_addr; - int rc = 0; - - /* Setup mode & subaddress if any */ - switch(host->mode) { - case pmac_low_i2c_mode_dumb: - printk(KERN_ERR "low_i2c: Dumb mode not supported !\n"); - return -EINVAL; - case pmac_low_i2c_mode_std: - mode_reg |= KW_I2C_MODE_STANDARD; - break; - case pmac_low_i2c_mode_stdsub: - mode_reg |= KW_I2C_MODE_STANDARDSUB; - break; - case pmac_low_i2c_mode_combined: - mode_reg |= KW_I2C_MODE_COMBINED; - break; - } - - /* Setup channel & clear pending irqs */ - kw_write_reg(reg_isr, kw_read_reg(reg_isr)); - kw_write_reg(reg_mode, mode_reg | (host->channel << 4)); - kw_write_reg(reg_status, 0); - - /* Set up address and r/w bit */ - kw_write_reg(reg_addr, addr); - - /* Set up the sub address */ - if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB - || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) - kw_write_reg(reg_subaddr, subaddr); - - /* Start sending address & disable interrupt*/ - kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); - kw_write_reg(reg_control, KW_I2C_CTL_XADDR); - - /* State machine, to turn into an interrupt handler */ - while(state != state_idle) { - u8 isr = kw_wait_interrupt(host); - state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr); - } - - return rc; -} - -static void keywest_low_i2c_add(struct device_node *np) -{ - struct low_i2c_host *host = find_low_i2c_host(NULL); - u32 *psteps, *prate, steps, aoffset = 0; - struct device_node *parent; - - if (host == NULL) { - printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", - np->full_name); - return; - } - memset(host, 0, sizeof(*host)); - - init_MUTEX(&host->mutex); - host->np = of_node_get(np); - psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); - steps = psteps ? (*psteps) : 0x10; - for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) - steps >>= 1; - parent = of_get_parent(np); - host->num_channels = 1; - if (parent && parent->name[0] == 'u') { - host->num_channels = 2; - aoffset = 3; - } - /* Select interface rate */ - host->speed = KW_I2C_MODE_100KHZ; - prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); - if (prate) switch(*prate) { - case 100: - host->speed = KW_I2C_MODE_100KHZ; - break; - case 50: - host->speed = KW_I2C_MODE_50KHZ; - break; - case 25: - host->speed = KW_I2C_MODE_25KHZ; - break; - } - - host->mode = pmac_low_i2c_mode_std; - host->base = ioremap(np->addrs[0].address + aoffset, - np->addrs[0].size); - host->func = keywest_low_i2c_func; -} - -/* - * - * PMU implementation - * - */ - - -#ifdef CONFIG_ADB_PMU - -static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len) -{ - // TODO - return -ENODEV; -} - -static void pmu_low_i2c_add(struct device_node *np) -{ - struct low_i2c_host *host = find_low_i2c_host(NULL); - - if (host == NULL) { - printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", - np->full_name); - return; - } - memset(host, 0, sizeof(*host)); - - init_MUTEX(&host->mutex); - host->np = of_node_get(np); - host->num_channels = 3; - host->mode = pmac_low_i2c_mode_std; - host->func = pmu_low_i2c_func; -} - -#endif /* CONFIG_ADB_PMU */ - -void __init pmac_init_low_i2c(void) -{ - struct device_node *np; - - /* Probe keywest-i2c busses */ - np = of_find_compatible_node(NULL, "i2c", "keywest-i2c"); - while(np) { - keywest_low_i2c_add(np); - np = of_find_compatible_node(np, "i2c", "keywest-i2c"); - } - -#ifdef CONFIG_ADB_PMU - /* Probe PMU busses */ - np = of_find_node_by_name(NULL, "via-pmu"); - if (np) - pmu_low_i2c_add(np); -#endif /* CONFIG_ADB_PMU */ - - /* TODO: Add CUDA support as well */ -} - -int pmac_low_i2c_lock(struct device_node *np) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - down(&host->mutex); - return 0; -} -EXPORT_SYMBOL(pmac_low_i2c_lock); - -int pmac_low_i2c_unlock(struct device_node *np) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - up(&host->mutex); - return 0; -} -EXPORT_SYMBOL(pmac_low_i2c_unlock); - - -int pmac_low_i2c_open(struct device_node *np, int channel) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - - if (channel >= host->num_channels) - return -EINVAL; - - down(&host->mutex); - host->is_open = 1; - host->channel = channel; - - return 0; -} -EXPORT_SYMBOL(pmac_low_i2c_open); - -int pmac_low_i2c_close(struct device_node *np) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - - host->is_open = 0; - up(&host->mutex); - - return 0; -} -EXPORT_SYMBOL(pmac_low_i2c_close); - -int pmac_low_i2c_setmode(struct device_node *np, int mode) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - WARN_ON(!host->is_open); - host->mode = mode; - - return 0; -} -EXPORT_SYMBOL(pmac_low_i2c_setmode); - -int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len) -{ - struct low_i2c_host *host = find_low_i2c_host(np); - - if (!host) - return -ENODEV; - WARN_ON(!host->is_open); - - return host->func(host, addrdir, subaddr, data, len); -} -EXPORT_SYMBOL(pmac_low_i2c_xfer); - diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c deleted file mode 100644 index 5fe9785ad7d8..000000000000 --- a/arch/ppc64/kernel/pmac_nvram.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * arch/ppc/platforms/pmac_nvram.c - * - * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org) - * - * 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. - * - * Todo: - add support for the OF persistent properties - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ - -#define CORE99_SIGNATURE 0x5a -#define CORE99_ADLER_START 0x14 - -/* On Core99, nvram is either a sharp, a micron or an AMD flash */ -#define SM_FLASH_STATUS_DONE 0x80 -#define SM_FLASH_STATUS_ERR 0x38 - -#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 -#define SM_FLASH_CMD_ERASE_SETUP 0x20 -#define SM_FLASH_CMD_RESET 0xff -#define SM_FLASH_CMD_WRITE_SETUP 0x40 -#define SM_FLASH_CMD_CLEAR_STATUS 0x50 -#define SM_FLASH_CMD_READ_STATUS 0x70 - -/* CHRP NVRAM header */ -struct chrp_header { - u8 signature; - u8 cksum; - u16 len; - char name[12]; - u8 data[0]; -}; - -struct core99_header { - struct chrp_header hdr; - u32 adler; - u32 generation; - u32 reserved[2]; -}; - -/* - * Read and write the non-volatile RAM on PowerMacs and CHRP machines. - */ -static volatile unsigned char *nvram_data; -static int core99_bank = 0; -// XXX Turn that into a sem -static DEFINE_SPINLOCK(nv_lock); - -extern int system_running; - -static int (*core99_write_bank)(int bank, u8* datas); -static int (*core99_erase_bank)(int bank); - -static char *nvram_image; - - -static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index) -{ - int i; - - if (nvram_image == NULL) - return -ENODEV; - if (*index > NVRAM_SIZE) - return 0; - - i = *index; - if (i + count > NVRAM_SIZE) - count = NVRAM_SIZE - i; - - memcpy(buf, &nvram_image[i], count); - *index = i + count; - return count; -} - -static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index) -{ - int i; - - if (nvram_image == NULL) - return -ENODEV; - if (*index > NVRAM_SIZE) - return 0; - - i = *index; - if (i + count > NVRAM_SIZE) - count = NVRAM_SIZE - i; - - memcpy(&nvram_image[i], buf, count); - *index = i + count; - return count; -} - -static ssize_t core99_nvram_size(void) -{ - if (nvram_image == NULL) - return -ENODEV; - return NVRAM_SIZE; -} - -static u8 chrp_checksum(struct chrp_header* hdr) -{ - u8 *ptr; - u16 sum = hdr->signature; - for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++) - sum += *ptr; - while (sum > 0xFF) - sum = (sum & 0xFF) + (sum>>8); - return sum; -} - -static u32 core99_calc_adler(u8 *buffer) -{ - int cnt; - u32 low, high; - - buffer += CORE99_ADLER_START; - low = 1; - high = 0; - for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) { - if ((cnt % 5000) == 0) { - high %= 65521UL; - high %= 65521UL; - } - low += buffer[cnt]; - high += low; - } - low %= 65521UL; - high %= 65521UL; - - return (high << 16) | low; -} - -static u32 core99_check(u8* datas) -{ - struct core99_header* hdr99 = (struct core99_header*)datas; - - if (hdr99->hdr.signature != CORE99_SIGNATURE) { - DBG("Invalid signature\n"); - return 0; - } - if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) { - DBG("Invalid checksum\n"); - return 0; - } - if (hdr99->adler != core99_calc_adler(datas)) { - DBG("Invalid adler\n"); - return 0; - } - return hdr99->generation; -} - -static int sm_erase_bank(int bank) -{ - int stat, i; - unsigned long timeout; - - u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; - - DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); - - out_8(base, SM_FLASH_CMD_ERASE_SETUP); - out_8(base, SM_FLASH_CMD_ERASE_CONFIRM); - timeout = 0; - do { - if (++timeout > 1000000) { - printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n"); - break; - } - out_8(base, SM_FLASH_CMD_READ_STATUS); - stat = in_8(base); - } while (!(stat & SM_FLASH_STATUS_DONE)); - - out_8(base, SM_FLASH_CMD_CLEAR_STATUS); - out_8(base, SM_FLASH_CMD_RESET); - - for (i=0; i 1000000) { - printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n"); - break; - } - out_8(base, SM_FLASH_CMD_READ_STATUS); - stat = in_8(base); - } while (!(stat & SM_FLASH_STATUS_DONE)); - if (!(stat & SM_FLASH_STATUS_DONE)) - break; - } - out_8(base, SM_FLASH_CMD_CLEAR_STATUS); - out_8(base, SM_FLASH_CMD_RESET); - for (i=0; i 1000000) { - printk(KERN_ERR "nvram: AMD flash erase timeout !\n"); - break; - } - stat = in_8(base) ^ in_8(base); - } while (stat != 0); - - /* Reset */ - out_8(base, 0xf0); - udelay(1); - - for (i=0; i 1000000) { - printk(KERN_ERR "nvram: AMD flash write timeout !\n"); - break; - } - stat = in_8(base) ^ in_8(base); - } while (stat != 0); - if (stat != 0) - break; - } - - /* Reset */ - out_8(base, 0xf0); - udelay(1); - - for (i=0; igeneration++; - hdr99->hdr.signature = CORE99_SIGNATURE; - hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr); - hdr99->adler = core99_calc_adler(nvram_image); - core99_bank = core99_bank ? 0 : 1; - if (core99_erase_bank) - if (core99_erase_bank(core99_bank)) { - printk("nvram: Error erasing bank %d\n", core99_bank); - goto bail; - } - if (core99_write_bank) - if (core99_write_bank(core99_bank, nvram_image)) - printk("nvram: Error writing bank %d\n", core99_bank); - bail: - spin_unlock_irqrestore(&nv_lock, flags); -} - -int __init pmac_nvram_init(void) -{ - struct device_node *dp; - u32 gen_bank0, gen_bank1; - int i; - - dp = find_devices("nvram"); - if (dp == NULL) { - printk(KERN_ERR "Can't find NVRAM device\n"); - return -ENODEV; - } - if (!device_is_compatible(dp, "nvram,flash")) { - printk(KERN_ERR "Incompatible type of NVRAM\n"); - return -ENXIO; - } - - nvram_image = alloc_bootmem(NVRAM_SIZE); - if (nvram_image == NULL) { - printk(KERN_ERR "nvram: can't allocate ram image\n"); - return -ENOMEM; - } - nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); - - DBG("nvram: Checking bank 0...\n"); - - gen_bank0 = core99_check((u8 *)nvram_data); - gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); - core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; - - DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); - DBG("nvram: Active bank is: %d\n", core99_bank); - - for (i=0; iindex; -} - -u8 pmac_xpram_read(int xpaddr) -{ - int offset = pmac_get_partition(pmac_nvram_XPRAM); - loff_t index; - u8 buf; - ssize_t count; - - if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) - return 0xff; - index = offset + xpaddr; - - count = ppc_md.nvram_read(&buf, 1, &index); - if (count != 1) - return 0xff; - return buf; -} - -void pmac_xpram_write(int xpaddr, u8 data) -{ - int offset = pmac_get_partition(pmac_nvram_XPRAM); - loff_t index; - u8 buf; - - if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) - return; - index = offset + xpaddr; - buf = data; - - ppc_md.nvram_write(&buf, 1, &index); -} - -EXPORT_SYMBOL(pmac_get_partition); -EXPORT_SYMBOL(pmac_xpram_read); -EXPORT_SYMBOL(pmac_xpram_write); diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c deleted file mode 100644 index 7a81c8275940..000000000000 --- a/arch/ppc64/kernel/pmac_pci.c +++ /dev/null @@ -1,793 +0,0 @@ -/* - * Support for PCI bridges found on Power Macintoshes. - * At present the "bandit" and "chaos" bridges are supported. - * Fortunately you access configuration space in the same - * way with either bridge. - * - * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) - * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pmac.h" - -#define DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* XXX Could be per-controller, but I don't think we risk anything by - * assuming we won't have both UniNorth and Bandit */ -static int has_uninorth; -static struct pci_controller *u3_agp; -struct device_node *k2_skiplist[2]; - -static int __init fixup_one_level_bus_range(struct device_node *node, int higher) -{ - for (; node != 0;node = node->sibling) { - int * bus_range; - unsigned int *class_code; - int len; - - /* For PCI<->PCI bridges or CardBus bridges, we go down */ - class_code = (unsigned int *) get_property(node, "class-code", NULL); - if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && - (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) - continue; - bus_range = (int *) get_property(node, "bus-range", &len); - if (bus_range != NULL && len > 2 * sizeof(int)) { - if (bus_range[1] > higher) - higher = bus_range[1]; - } - higher = fixup_one_level_bus_range(node->child, higher); - } - return higher; -} - -/* This routine fixes the "bus-range" property of all bridges in the - * system since they tend to have their "last" member wrong on macs - * - * Note that the bus numbers manipulated here are OF bus numbers, they - * are not Linux bus numbers. - */ -static void __init fixup_bus_range(struct device_node *bridge) -{ - int * bus_range; - int len; - - /* Lookup the "bus-range" property for the hose */ - bus_range = (int *) get_property(bridge, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - bridge->full_name); - return; - } - bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); -} - -/* - * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers. - * - * The "Bandit" version is present in all early PCI PowerMacs, - * and up to the first ones using Grackle. Some machines may - * have 2 bandit controllers (2 PCI busses). - * - * "Chaos" is used in some "Bandit"-type machines as a bridge - * for the separate display bus. It is accessed the same - * way as bandit, but cannot be probed for devices. It therefore - * has its own config access functions. - * - * The "UniNorth" version is present in all Core99 machines - * (iBook, G4, new IMacs, and all the recent Apple machines). - * It contains 3 controllers in one ASIC. - * - * The U3 is the bridge used on G5 machines. It contains on - * AGP bus which is dealt with the old UniNorth access routines - * and an HyperTransport bus which uses its own set of access - * functions. - */ - -#define MACRISC_CFA0(devfn, off) \ - ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ - | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ - | (((unsigned long)(off)) & 0xFCUL)) - -#define MACRISC_CFA1(bus, devfn, off) \ - ((((unsigned long)(bus)) << 16) \ - |(((unsigned long)(devfn)) << 8) \ - |(((unsigned long)(off)) & 0xFCUL) \ - |1UL) - -static unsigned long macrisc_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, u8 offset) -{ - unsigned int caddr; - - if (bus == hose->first_busno) { - if (dev_fn < (11 << 3)) - return 0; - caddr = MACRISC_CFA0(dev_fn, offset); - } else - caddr = MACRISC_CFA1(bus, dev_fn, offset); - - /* Uninorth will return garbage if we don't read back the value ! */ - do { - out_le32(hose->cfg_addr, caddr); - } while (in_le32(hose->cfg_addr) != caddr); - - offset &= has_uninorth ? 0x07 : 0x03; - return ((unsigned long)hose->cfg_data) + offset; -} - -static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - unsigned long addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8((u8 *)addr); - break; - case 2: - *val = in_le16((u16 *)addr); - break; - default: - *val = in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - unsigned long addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); - break; - case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); - break; - default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops macrisc_pci_ops = -{ - macrisc_read_config, - macrisc_write_config -}; - -/* - * These versions of U3 HyperTransport config space access ops do not - * implement self-view of the HT host yet - */ - -/* - * This function deals with some "special cases" devices. - * - * 0 -> No special case - * 1 -> Skip the device but act as if the access was successfull - * (return 0xff's on reads, eventually, cache config space - * accesses in a later version) - * -1 -> Hide the device (unsuccessful acess) - */ -static int u3_ht_skip_device(struct pci_controller *hose, - struct pci_bus *bus, unsigned int devfn) -{ - struct device_node *busdn, *dn; - int i; - - /* We only allow config cycles to devices that are in OF device-tree - * as we are apparently having some weird things going on with some - * revs of K2 on recent G5s - */ - if (bus->self) - busdn = pci_device_to_OF_node(bus->self); - else - busdn = hose->arch_data; - for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->data && PCI_DN(dn)->devfn == devfn) - break; - if (dn == NULL) - return -1; - - /* - * When a device in K2 is powered down, we die on config - * cycle accesses. Fix that here. - */ - for (i=0; i<2; i++) - if (k2_skiplist[i] == dn) - return 1; - - return 0; -} - -#define U3_HT_CFA0(devfn, off) \ - ((((unsigned long)devfn) << 8) | offset) -#define U3_HT_CFA1(bus, devfn, off) \ - (U3_HT_CFA0(devfn, off) \ - + (((unsigned long)bus) << 16) \ - + 0x01000000UL) - -static unsigned long u3_ht_cfg_access(struct pci_controller* hose, - u8 bus, u8 devfn, u8 offset) -{ - if (bus == hose->first_busno) { - /* For now, we don't self probe U3 HT bridge */ - if (PCI_SLOT(devfn) == 0) - return 0; - return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); - } else - return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); -} - -static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - unsigned long addr; - - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (u3_ht_skip_device(hose, bus, devfn)) { - case 0: - break; - case 1: - switch (len) { - case 1: - *val = 0xff; break; - case 2: - *val = 0xffff; break; - default: - *val = 0xfffffffful; break; - } - return PCIBIOS_SUCCESSFUL; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8((u8 *)addr); - break; - case 2: - *val = in_le16((u16 *)addr); - break; - default: - *val = in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - unsigned long addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (u3_ht_skip_device(hose, bus, devfn)) { - case 0: - break; - case 1: - return PCIBIOS_SUCCESSFUL; - default: - return PCIBIOS_DEVICE_NOT_FOUND; - } - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); - break; - case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); - break; - default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops u3_ht_pci_ops = -{ - u3_ht_read_config, - u3_ht_write_config -}; - -static void __init setup_u3_agp(struct pci_controller* hose) -{ - /* On G5, we move AGP up to high bus number so we don't need - * to reassign bus numbers for HT. If we ever have P2P bridges - * on AGP, we'll have to move pci_assign_all_buses to the - * pci_controller structure so we enable it for AGP and not for - * HT childs. - * We hard code the address because of the different size of - * the reg address cell, we shall fix that by killing struct - * reg_property and using some accessor functions instead - */ - hose->first_busno = 0xf0; - hose->last_busno = 0xff; - has_uninorth = 1; - hose->ops = ¯isc_pci_ops; - hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); - hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); - - u3_agp = hose; -} - -static void __init setup_u3_ht(struct pci_controller* hose) -{ - struct device_node *np = (struct device_node *)hose->arch_data; - int i, cur; - - hose->ops = &u3_ht_pci_ops; - - /* We hard code the address because of the different size of - * the reg address cell, we shall fix that by killing struct - * reg_property and using some accessor functions instead - */ - hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); - - /* - * /ht node doesn't expose a "ranges" property, so we "remove" regions that - * have been allocated to AGP. So far, this version of the code doesn't assign - * any of the 0xfxxxxxxx "fine" memory regions to /ht. - * We need to fix that sooner or later by either parsing all child "ranges" - * properties or figuring out the U3 address space decoding logic and - * then read it's configuration register (if any). - */ - hose->io_base_phys = 0xf4000000; - hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); - isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt; - hose->io_resource.name = np->full_name; - hose->io_resource.start = 0; - hose->io_resource.end = 0x003fffff; - hose->io_resource.flags = IORESOURCE_IO; - hose->pci_mem_offset = 0; - hose->first_busno = 0; - hose->last_busno = 0xef; - hose->mem_resources[0].name = np->full_name; - hose->mem_resources[0].start = 0x80000000; - hose->mem_resources[0].end = 0xefffffff; - hose->mem_resources[0].flags = IORESOURCE_MEM; - - if (u3_agp == NULL) { - DBG("U3 has no AGP, using full resource range\n"); - return; - } - - /* We "remove" the AGP resources from the resources allocated to HT, that - * is we create "holes". However, that code does assumptions that so far - * happen to be true (cross fingers...), typically that resources in the - * AGP node are properly ordered - */ - cur = 0; - for (i=0; i<3; i++) { - struct resource *res = &u3_agp->mem_resources[i]; - if (res->flags != IORESOURCE_MEM) - continue; - /* We don't care about "fine" resources */ - if (res->start >= 0xf0000000) - continue; - /* Check if it's just a matter of "shrinking" us in one direction */ - if (hose->mem_resources[cur].start == res->start) { - DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", - cur, hose->mem_resources[cur].start, res->end + 1); - hose->mem_resources[cur].start = res->end + 1; - continue; - } - if (hose->mem_resources[cur].end == res->end) { - DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", - cur, hose->mem_resources[cur].end, res->start - 1); - hose->mem_resources[cur].end = res->start - 1; - continue; - } - /* No, it's not the case, we need a hole */ - if (cur == 2) { - /* not enough resources for a hole, we drop part of the range */ - printk(KERN_WARNING "Running out of resources for /ht host !\n"); - hose->mem_resources[cur].end = res->start - 1; - continue; - } - cur++; - DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", - cur-1, res->start - 1, cur, res->end + 1); - hose->mem_resources[cur].name = np->full_name; - hose->mem_resources[cur].flags = IORESOURCE_MEM; - hose->mem_resources[cur].start = res->end + 1; - hose->mem_resources[cur].end = hose->mem_resources[cur-1].end; - hose->mem_resources[cur-1].end = res->start - 1; - } -} - -static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev, int primary) -{ - static unsigned int static_lc_ranges[2024]; - unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; - unsigned int size; - int rlen = 0, orig_rlen; - int memno = 0; - struct resource *res; - int np, na = prom_n_addr_cells(dev); - - np = na + 5; - - /* First we try to merge ranges to fix a problem with some pmacs - * that can have more than 3 ranges, fortunately using contiguous - * addresses -- BenH - */ - dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); - if (!dt_ranges) - return; - /* lc_ranges = alloc_bootmem(rlen);*/ - lc_ranges = static_lc_ranges; - if (!lc_ranges) - return; /* what can we do here ? */ - memcpy(lc_ranges, dt_ranges, rlen); - orig_rlen = rlen; - - /* Let's work on a copy of the "ranges" property instead of damaging - * the device-tree image in memory - */ - ranges = lc_ranges; - prev = NULL; - while ((rlen -= np * sizeof(unsigned int)) >= 0) { - if (prev) { - if (prev[0] == ranges[0] && prev[1] == ranges[1] && - (prev[2] + prev[na+4]) == ranges[2] && - (prev[na+2] + prev[na+4]) == ranges[na+2]) { - prev[na+4] += ranges[na+4]; - ranges[0] = 0; - ranges += np; - continue; - } - } - prev = ranges; - ranges += np; - } - - /* - * The ranges property is laid out as an array of elements, - * each of which comprises: - * cells 0 - 2: a PCI address - * cells 3 or 3+4: a CPU physical address - * (size depending on dev->n_addr_cells) - * cells 4+5 or 5+6: the size of the range - */ - ranges = lc_ranges; - rlen = orig_rlen; - while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { - res = NULL; - size = ranges[na+4]; - switch (ranges[0] >> 24) { - case 1: /* I/O space */ - if (ranges[2] != 0) - break; - hose->io_base_phys = ranges[na+2]; - /* limit I/O space to 16MB */ - if (size > 0x01000000) - size = 0x01000000; - hose->io_base_virt = ioremap(ranges[na+2], size); - if (primary) - isa_io_base = (unsigned long) hose->io_base_virt; - res = &hose->io_resource; - res->flags = IORESOURCE_IO; - res->start = ranges[2]; - break; - case 2: /* memory space */ - memno = 0; - if (ranges[1] == 0 && ranges[2] == 0 - && ranges[na+4] <= (16 << 20)) { - /* 1st 16MB, i.e. ISA memory area */ -#if 0 - if (primary) - isa_mem_base = ranges[na+2]; -#endif - memno = 1; - } - while (memno < 3 && hose->mem_resources[memno].flags) - ++memno; - if (memno == 0) - hose->pci_mem_offset = ranges[na+2] - ranges[2]; - if (memno < 3) { - res = &hose->mem_resources[memno]; - res->flags = IORESOURCE_MEM; - res->start = ranges[na+2]; - } - break; - } - if (res != NULL) { - res->name = dev->full_name; - res->end = res->start + size - 1; - res->parent = NULL; - res->sibling = NULL; - res->child = NULL; - } - ranges += np; - } -} - -/* - * We assume that if we have a G3 powermac, we have one bridge called - * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, - * if we have one or more bandit or chaos bridges, we don't have a MPC106. - */ -static int __init add_bridge(struct device_node *dev) -{ - int len; - struct pci_controller *hose; - char* disp_name; - int *bus_range; - int primary = 1; - struct property *of_prop; - - DBG("Adding PCI host bridge %s\n", dev->full_name); - - bus_range = (int *) get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", - dev->full_name); - } - - hose = alloc_bootmem(sizeof(struct pci_controller)); - if (hose == NULL) - return -ENOMEM; - pci_setup_pci_controller(hose); - - hose->arch_data = dev; - hose->first_busno = bus_range ? bus_range[0] : 0; - hose->last_busno = bus_range ? bus_range[1] : 0xff; - - of_prop = alloc_bootmem(sizeof(struct property) + - sizeof(hose->global_number)); - if (of_prop) { - memset(of_prop, 0, sizeof(struct property)); - of_prop->name = "linux,pci-domain"; - of_prop->length = sizeof(hose->global_number); - of_prop->value = (unsigned char *)&of_prop[1]; - memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number)); - prom_add_property(dev, of_prop); - } - - disp_name = NULL; - if (device_is_compatible(dev, "u3-agp")) { - setup_u3_agp(hose); - disp_name = "U3-AGP"; - primary = 0; - } else if (device_is_compatible(dev, "u3-ht")) { - setup_u3_ht(hose); - disp_name = "U3-HT"; - primary = 1; - } - printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", - disp_name, hose->first_busno, hose->last_busno); - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pmac_process_bridge_OF_ranges(hose, dev, primary); - - /* Fixup "bus-range" OF property */ - fixup_bus_range(dev); - - return 0; -} - -/* - * We use our own read_irq_line here because PCI_INTERRUPT_PIN is - * crap on some of Apple ASICs. We unconditionally use the Open Firmware - * interrupt number as this is always right. - */ -static int pmac_pci_read_irq_line(struct pci_dev *pci_dev) -{ - struct device_node *node; - - node = pci_device_to_OF_node(pci_dev); - if (node == NULL) - return -1; - if (node->n_intrs == 0) - return -1; - pci_dev->irq = node->intrs[0].line; - pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq); - - return 0; -} - -void __init pmac_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pmac_pci_read_irq_line(dev); -} - -static void __init pmac_fixup_phb_resources(void) -{ - struct pci_controller *hose, *tmp; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; - hose->io_resource.start += offset; - hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", - hose->global_number, - hose->io_resource.start, hose->io_resource.end); - } -} - -void __init pmac_pci_init(void) -{ - struct device_node *np, *root; - struct device_node *ht = NULL; - - /* Probe root PCI hosts, that is on U3 the AGP host and the - * HyperTransport host. That one is actually "kept" around - * and actually added last as it's resource management relies - * on the AGP resources to have been setup first - */ - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); - return; - } - for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { - if (np->name == NULL) - continue; - if (strcmp(np->name, "pci") == 0) { - if (add_bridge(np) == 0) - of_node_get(np); - } - if (strcmp(np->name, "ht") == 0) { - of_node_get(np); - ht = np; - } - } - of_node_put(root); - - /* Now setup the HyperTransport host if we found any - */ - if (ht && add_bridge(ht) != 0) - of_node_put(ht); - - /* Fixup the IO resources on our host bridges as the common code - * does it only for childs of the host bridges - */ - pmac_fixup_phb_resources(); - - /* Setup the linkage between OF nodes and PHBs */ - pci_devs_phb_init(); - - /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We - * assume there is no P2P bridge on the AGP bus, which should be a - * safe assumptions hopefully. - */ - if (u3_agp) { - struct device_node *np = u3_agp->arch_data; - PCI_DN(np)->busno = 0xf0; - for (np = np->child; np; np = np->sibling) - PCI_DN(np)->busno = 0xf0; - } - - pmac_check_ht_link(); - - /* Tell pci.c to not use the common resource allocation mecanism */ - pci_probe_only = 1; - - /* Allow all IO */ - io_page_mask = -1; -} - -/* - * Disable second function on K2-SATA, it's broken - * and disable IO BARs on first one - */ -static void fixup_k2_sata(struct pci_dev* dev) -{ - int i; - u16 cmd; - - if (PCI_FUNC(dev->devfn) > 0) { - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(dev, PCI_COMMAND, cmd); - for (i = 0; i < 6; i++) { - dev->resource[i].start = dev->resource[i].end = 0; - dev->resource[i].flags = 0; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); - } - } else { - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd &= ~PCI_COMMAND_IO; - pci_write_config_word(dev, PCI_COMMAND, cmd); - for (i = 0; i < 5; i++) { - dev->resource[i].start = dev->resource[i].end = 0; - dev->resource[i].flags = 0; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata); - diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c deleted file mode 100644 index c3ea73df937d..000000000000 --- a/arch/ppc64/kernel/pmac_setup.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * arch/ppc/platforms/setup.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Adapted for Power Macintosh by Paul Mackerras - * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) - * - * Derived from "arch/alpha/kernel/setup.c" - * Copyright (C) 1995 Linus Torvalds - * - * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) - * - * 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. - * - */ - -/* - * bootup setup stuff.. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pmac.h" - -#ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -static int current_root_goodness = -1; -#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ - -extern int powersave_nap; -int sccdbg; - -sys_ctrler_t sys_ctrler; -EXPORT_SYMBOL(sys_ctrler); - -#ifdef CONFIG_PMAC_SMU -unsigned long smu_cmdbuf_abs; -EXPORT_SYMBOL(smu_cmdbuf_abs); -#endif - -extern void udbg_init_scc(struct device_node *np); - -static void pmac_show_cpuinfo(struct seq_file *m) -{ - struct device_node *np; - char *pp; - int plen; - char* mbname; - int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, - PMAC_MB_INFO_MODEL, 0); - unsigned int mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, - PMAC_MB_INFO_FLAGS, 0); - - if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, - (long)&mbname) != 0) - mbname = "Unknown"; - - /* find motherboard type */ - seq_printf(m, "machine\t\t: "); - np = find_devices("device-tree"); - if (np != NULL) { - pp = (char *) get_property(np, "model", NULL); - if (pp != NULL) - seq_printf(m, "%s\n", pp); - else - seq_printf(m, "PowerMac\n"); - pp = (char *) get_property(np, "compatible", &plen); - if (pp != NULL) { - seq_printf(m, "motherboard\t:"); - while (plen > 0) { - int l = strlen(pp) + 1; - seq_printf(m, " %s", pp); - plen -= l; - pp += l; - } - seq_printf(m, "\n"); - } - } else - seq_printf(m, "PowerMac\n"); - - /* print parsed model */ - seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); - seq_printf(m, "pmac flags\t: %08x\n", mbflags); - - /* Indicate newworld */ - seq_printf(m, "pmac-generation\t: NewWorld\n"); -} - - -static void __init pmac_setup_arch(void) -{ - /* init to some ~sane value until calibrate_delay() runs */ - loops_per_jiffy = 50000000; - - /* Probe motherboard chipset */ - pmac_feature_init(); -#if 0 - /* Lock-enable the SCC channel used for debug */ - if (sccdbg) { - np = of_find_node_by_name(NULL, "escc"); - if (np) - pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, - PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); - } -#endif - /* We can NAP */ - powersave_nap = 1; - -#ifdef CONFIG_ADB_PMU - /* Initialize the PMU if any */ - find_via_pmu(); -#endif -#ifdef CONFIG_PMAC_SMU - /* Initialize the SMU if any */ - smu_init(); -#endif - - /* Init NVRAM access */ - pmac_nvram_init(); - - /* Setup SMP callback */ -#ifdef CONFIG_SMP - pmac_setup_smp(); -#endif - - /* Lookup PCI hosts */ - pmac_pci_init(); - -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - - printk(KERN_INFO "Using native/NAP idle loop\n"); -} - -#ifdef CONFIG_SCSI -void note_scsi_host(struct device_node *node, void *host) -{ - /* Obsolete */ -} -#endif - - -static int initializing = 1; - -static int pmac_late_init(void) -{ - initializing = 0; - return 0; -} - -late_initcall(pmac_late_init); - -/* can't be __init - can be called whenever a disk is first accessed */ -void note_bootable_part(dev_t dev, int part, int goodness) -{ - extern dev_t boot_dev; - char *p; - - if (!initializing) - return; - if ((goodness <= current_root_goodness) && - ROOT_DEV != DEFAULT_ROOT_DEVICE) - return; - p = strstr(saved_command_line, "root="); - if (p != NULL && (p == saved_command_line || p[-1] == ' ')) - return; - - if (!boot_dev || dev == boot_dev) { - ROOT_DEV = dev + part; - boot_dev = 0; - current_root_goodness = goodness; - } -} - -static void pmac_restart(char *cmd) -{ - switch(sys_ctrler) { -#ifdef CONFIG_ADB_PMU - case SYS_CTRLER_PMU: - pmu_restart(); - break; -#endif - -#ifdef CONFIG_PMAC_SMU - case SYS_CTRLER_SMU: - smu_restart(); - break; -#endif - default: - ; - } -} - -static void pmac_power_off(void) -{ - switch(sys_ctrler) { -#ifdef CONFIG_ADB_PMU - case SYS_CTRLER_PMU: - pmu_shutdown(); - break; -#endif -#ifdef CONFIG_PMAC_SMU - case SYS_CTRLER_SMU: - smu_shutdown(); - break; -#endif - default: - ; - } -} - -static void pmac_halt(void) -{ - pmac_power_off(); -} - -/* - * Early initialization. - */ -static void __init pmac_init_early(void) -{ - DBG(" -> pmac_init_early\n"); - - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); - - /* Init SCC */ - if (strstr(cmd_line, "sccdbg")) { - sccdbg = 1; - udbg_init_scc(NULL); - } - - /* Setup interrupt mapping options */ - ppc64_interrupt_controller = IC_OPEN_PIC; - - iommu_init_early_u3(); - - DBG(" <- pmac_init_early\n"); -} - -static int pmac_u3_cascade(struct pt_regs *regs, void *data) -{ - return mpic_get_one_irq((struct mpic *)data, regs); -} - -static __init void pmac_init_IRQ(void) -{ - struct device_node *irqctrler = NULL; - struct device_node *irqctrler2 = NULL; - struct device_node *np = NULL; - struct mpic *mpic1, *mpic2; - - /* We first try to detect Apple's new Core99 chipset, since mac-io - * is quite different on those machines and contains an IBM MPIC2. - */ - while ((np = of_find_node_by_type(np, "open-pic")) != NULL) { - struct device_node *parent = of_get_parent(np); - if (parent && !strcmp(parent->name, "u3")) - irqctrler2 = of_node_get(np); - else - irqctrler = of_node_get(np); - of_node_put(parent); - } - if (irqctrler != NULL && irqctrler->n_addrs > 0) { - unsigned char senses[128]; - - printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", - (unsigned int)irqctrler->addrs[0].address); - - prom_get_irq_senses(senses, 0, 128); - mpic1 = mpic_alloc(irqctrler->addrs[0].address, - MPIC_PRIMARY | MPIC_WANTS_RESET, - 0, 0, 128, 256, senses, 128, " K2-MPIC "); - BUG_ON(mpic1 == NULL); - mpic_init(mpic1); - - if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && - irqctrler2->n_addrs > 0) { - printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", - (u32)irqctrler2->addrs[0].address, - irqctrler2->intrs[0].line); - - pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); - prom_get_irq_senses(senses, 128, 128 + 128); - - /* We don't need to set MPIC_BROKEN_U3 here since we don't have - * hypertransport interrupts routed to it - */ - mpic2 = mpic_alloc(irqctrler2->addrs[0].address, - MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, - 0, 128, 128, 0, senses, 128, " U3-MPIC "); - BUG_ON(mpic2 == NULL); - mpic_init(mpic2); - mpic_setup_cascade(irqctrler2->intrs[0].line, - pmac_u3_cascade, mpic2); - } - } - of_node_put(irqctrler); - of_node_put(irqctrler2); -} - -static void __init pmac_progress(char *s, unsigned short hex) -{ - if (sccdbg) { - udbg_puts(s); - udbg_puts("\n"); - } -#ifdef CONFIG_BOOTX_TEXT - else if (boot_text_mapped) { - btext_drawstring(s); - btext_drawstring("\n"); - } -#endif /* CONFIG_BOOTX_TEXT */ -} - -/* - * pmac has no legacy IO, anything calling this function has to - * fail or bad things will happen - */ -static int pmac_check_legacy_ioport(unsigned int baseport) -{ - return -ENODEV; -} - -static int __init pmac_declare_of_platform_devices(void) -{ - struct device_node *np, *npp; - - npp = of_find_node_by_name(NULL, "u3"); - if (npp) { - for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) { - if (strncmp(np->name, "i2c", 3) == 0) { - of_platform_device_create(np, "u3-i2c", NULL); - of_node_put(np); - break; - } - } - of_node_put(npp); - } - npp = of_find_node_by_type(NULL, "smu"); - if (npp) { - of_platform_device_create(npp, "smu", NULL); - of_node_put(npp); - } - - return 0; -} - -device_initcall(pmac_declare_of_platform_devices); - -/* - * Called very early, MMU is off, device-tree isn't unflattened - */ -static int __init pmac_probe(int platform) -{ - if (platform != PLATFORM_POWERMAC) - return 0; - /* - * On U3, the DART (iommu) must be allocated now since it - * has an impact on htab_initialize (due to the large page it - * occupies having to be broken up so the DART itself is not - * part of the cacheable linar mapping - */ - alloc_u3_dart_table(); - -#ifdef CONFIG_PMAC_SMU - /* - * SMU based G5s need some memory below 2Gb, at least the current - * driver needs that. We have to allocate it now. We allocate 4k - * (1 small page) for now. - */ - smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); -#endif /* CONFIG_PMAC_SMU */ - - return 1; -} - -static int pmac_probe_mode(struct pci_bus *bus) -{ - struct device_node *node = bus->sysdata; - - /* We need to use normal PCI probing for the AGP bus, - since the device for the AGP bridge isn't in the tree. */ - if (bus->self == NULL && device_is_compatible(node, "u3-agp")) - return PCI_PROBE_NORMAL; - - return PCI_PROBE_DEVTREE; -} - -struct machdep_calls __initdata pmac_md = { -#ifdef CONFIG_HOTPLUG_CPU - .cpu_die = generic_mach_cpu_die, -#endif - .probe = pmac_probe, - .setup_arch = pmac_setup_arch, - .init_early = pmac_init_early, - .show_cpuinfo = pmac_show_cpuinfo, - .init_IRQ = pmac_init_IRQ, - .get_irq = mpic_get_irq, - .pcibios_fixup = pmac_pcibios_fixup, - .pci_probe_mode = pmac_probe_mode, - .restart = pmac_restart, - .power_off = pmac_power_off, - .halt = pmac_halt, - .get_boot_time = pmac_get_boot_time, - .set_rtc_time = pmac_set_rtc_time, - .get_rtc_time = pmac_get_rtc_time, - .calibrate_decr = pmac_calibrate_decr, - .feature_call = pmac_do_feature_call, - .progress = pmac_progress, - .check_legacy_ioport = pmac_check_legacy_ioport, - .idle_loop = native_idle, - .enable_pmcs = power4_enable_pmcs, -}; diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c deleted file mode 100644 index 83c2f8dc1ec6..000000000000 --- a/arch/ppc64/kernel/pmac_smp.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * SMP support for power macintosh. - * - * We support both the old "powersurge" SMP architecture - * and the current Core99 (G4 PowerMac) machines. - * - * Note that we don't support the very first rev. of - * Apple/DayStar 2 CPUs board, the one with the funky - * watchdog. Hopefully, none of these should be there except - * maybe internally to Apple. I should probably still add some - * code to detect this card though and disable SMP. --BenH. - * - * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net) - * and Ben Herrenschmidt . - * - * Support for DayStar quad CPU cards - * Copyright (C) XLR8, Inc. 1994-2000 - * - * 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -extern void __secondary_start_pmac_0(void); - -extern struct smp_ops_t *smp_ops; - -static void (*pmac_tb_freeze)(int freeze); -static struct device_node *pmac_tb_clock_chip_host; -static u8 pmac_tb_pulsar_addr; -static DEFINE_SPINLOCK(timebase_lock); -static unsigned long timebase; - -static void smp_core99_cypress_tb_freeze(int freeze) -{ - u8 data; - int rc; - - /* Strangely, the device-tree says address is 0xd2, but darwin - * accesses 0xd0 ... - */ - pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); - rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, - 0xd0 | pmac_low_i2c_read, - 0x81, &data, 1); - if (rc != 0) - goto bail; - - data = (data & 0xf3) | (freeze ? 0x00 : 0x0c); - - pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); - rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, - 0xd0 | pmac_low_i2c_write, - 0x81, &data, 1); - - bail: - if (rc != 0) { - printk("Cypress Timebase %s rc: %d\n", - freeze ? "freeze" : "unfreeze", rc); - panic("Timebase freeze failed !\n"); - } -} - -static void smp_core99_pulsar_tb_freeze(int freeze) -{ - u8 data; - int rc; - - pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); - rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, - pmac_tb_pulsar_addr | pmac_low_i2c_read, - 0x2e, &data, 1); - if (rc != 0) - goto bail; - - data = (data & 0x88) | (freeze ? 0x11 : 0x22); - - pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); - rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, - pmac_tb_pulsar_addr | pmac_low_i2c_write, - 0x2e, &data, 1); - bail: - if (rc != 0) { - printk(KERN_ERR "Pulsar Timebase %s rc: %d\n", - freeze ? "freeze" : "unfreeze", rc); - panic("Timebase freeze failed !\n"); - } -} - - -static void smp_core99_give_timebase(void) -{ - /* Open i2c bus for synchronous access */ - if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0)) - panic("Can't open i2c for TB sync !\n"); - - spin_lock(&timebase_lock); - (*pmac_tb_freeze)(1); - mb(); - timebase = get_tb(); - spin_unlock(&timebase_lock); - - while (timebase) - barrier(); - - spin_lock(&timebase_lock); - (*pmac_tb_freeze)(0); - spin_unlock(&timebase_lock); - - /* Close i2c bus */ - pmac_low_i2c_close(pmac_tb_clock_chip_host); -} - - -static void __devinit smp_core99_take_timebase(void) -{ - while (!timebase) - barrier(); - spin_lock(&timebase_lock); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - spin_unlock(&timebase_lock); -} - - -static int __init smp_core99_probe(void) -{ - struct device_node *cpus; - struct device_node *cc; - int ncpus = 0; - - /* Maybe use systemconfiguration here ? */ - if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); - - /* Count CPUs in the device-tree */ - for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;) - ++ncpus; - - printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus); - - /* Nothing more to do if less than 2 of them */ - if (ncpus <= 1) - return 1; - - /* HW sync only on these platforms */ - if (!machine_is_compatible("PowerMac7,2") && - !machine_is_compatible("PowerMac7,3") && - !machine_is_compatible("RackMac3,1")) - goto nohwsync; - - /* Look for the clock chip */ - for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) { - struct device_node *p = of_get_parent(cc); - u32 *reg; - int ok; - ok = p && device_is_compatible(p, "uni-n-i2c"); - if (!ok) - goto next; - reg = (u32 *)get_property(cc, "reg", NULL); - if (reg == NULL) - goto next; - switch (*reg) { - case 0xd2: - if (device_is_compatible(cc, "pulsar-legacy-slewing")) { - pmac_tb_freeze = smp_core99_pulsar_tb_freeze; - pmac_tb_pulsar_addr = 0xd2; - printk(KERN_INFO "Timebase clock is Pulsar chip\n"); - } else if (device_is_compatible(cc, "cy28508")) { - pmac_tb_freeze = smp_core99_cypress_tb_freeze; - printk(KERN_INFO "Timebase clock is Cypress chip\n"); - } - break; - case 0xd4: - pmac_tb_freeze = smp_core99_pulsar_tb_freeze; - pmac_tb_pulsar_addr = 0xd4; - printk(KERN_INFO "Timebase clock is Pulsar chip\n"); - break; - } - if (pmac_tb_freeze != NULL) { - pmac_tb_clock_chip_host = p; - smp_ops->give_timebase = smp_core99_give_timebase; - smp_ops->take_timebase = smp_core99_take_timebase; - of_node_put(cc); - of_node_put(p); - break; - } - next: - of_node_put(p); - } - - nohwsync: - mpic_request_ipis(); - - return ncpus; -} - -static void __init smp_core99_kick_cpu(int nr) -{ - unsigned int save_vector, j; - unsigned long new_vector; - unsigned long flags; - volatile unsigned int *vector - = ((volatile unsigned int *)(KERNELBASE+0x100)); - - if (nr < 1 || nr > 3) - return; - if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); - - local_irq_save(flags); - local_irq_disable(); - - /* Save reset vector */ - save_vector = *vector; - - /* Setup fake reset vector that does - * b __secondary_start_pmac_0 + nr*8 - KERNELBASE - */ - new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; - *vector = 0x48000002 + (new_vector - KERNELBASE); - - /* flush data cache and inval instruction cache */ - flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); - - /* Put some life in our friend */ - pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); - paca[nr].cpu_start = 1; - - /* FIXME: We wait a bit for the CPU to take the exception, I should - * instead wait for the entry code to set something for me. Well, - * ideally, all that crap will be done in prom.c and the CPU left - * in a RAM-based wait loop like CHRP. - */ - for (j = 1; j < 1000000; j++) - mb(); - - /* Restore our exception vector */ - *vector = save_vector; - flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); - - local_irq_restore(flags); - if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); -} - -static void __init smp_core99_setup_cpu(int cpu_nr) -{ - /* Setup MPIC */ - mpic_setup_this_cpu(); - - if (cpu_nr == 0) { - extern void g5_phy_disable_cpu1(void); - - /* If we didn't start the second CPU, we must take - * it off the bus - */ - if (num_online_cpus() < 2) - g5_phy_disable_cpu1(); - if (ppc_md.progress) ppc_md.progress("smp_core99_setup_cpu 0 done", 0x349); - } -} - -struct smp_ops_t core99_smp_ops = { - .message_pass = smp_mpic_message_pass, - .probe = smp_core99_probe, - .kick_cpu = smp_core99_kick_cpu, - .setup_cpu = smp_core99_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, -}; - -void __init pmac_setup_smp(void) -{ - smp_ops = &core99_smp_ops; -#ifdef CONFIG_HOTPLUG_CPU - smp_ops->cpu_enable = generic_cpu_enable; - smp_ops->cpu_disable = generic_cpu_disable; - smp_ops->cpu_die = generic_cpu_die; -#endif -} diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c deleted file mode 100644 index 928bf213ec4e..000000000000 --- a/arch/ppc64/kernel/pmac_time.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Support for periodic interrupts (100 per second) and for getting - * the current time from the RTC on Power Macintoshes. - * - * We use the decrementer register for our periodic interrupts. - * - * Paul Mackerras August 1996. - * Copyright (C) 1996 Paul Mackerras. - * Copyright (C) 2003-2005 Benjamin Herrenschmidt. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* Apparently the RTC stores seconds since 1 Jan 1904 */ -#define RTC_OFFSET 2082844800 - -/* - * Calibrate the decrementer frequency with the VIA timer 1. - */ -#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ - -extern struct timezone sys_tz; -extern void to_tm(int tim, struct rtc_time * tm); - -void pmac_get_rtc_time(struct rtc_time *tm) -{ - switch(sys_ctrler) { -#ifdef CONFIG_ADB_PMU - case SYS_CTRLER_PMU: { - /* TODO: Move that to a function in the PMU driver */ - struct adb_request req; - unsigned int now; - - if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) - return; - pmu_wait_complete(&req); - if (req.reply_len != 4) - printk(KERN_ERR "pmac_get_rtc_time: PMU returned a %d" - " bytes reply\n", req.reply_len); - now = (req.reply[0] << 24) + (req.reply[1] << 16) - + (req.reply[2] << 8) + req.reply[3]; - DBG("get: %u -> %u\n", (int)now, (int)(now - RTC_OFFSET)); - now -= RTC_OFFSET; - - to_tm(now, tm); - tm->tm_year -= 1900; - tm->tm_mon -= 1; - - DBG("-> tm_mday: %d, tm_mon: %d, tm_year: %d, %d:%02d:%02d\n", - tm->tm_mday, tm->tm_mon, tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - break; - } -#endif /* CONFIG_ADB_PMU */ - -#ifdef CONFIG_PMAC_SMU - case SYS_CTRLER_SMU: - smu_get_rtc_time(tm, 1); - break; -#endif /* CONFIG_PMAC_SMU */ - default: - ; - } -} - -int pmac_set_rtc_time(struct rtc_time *tm) -{ - switch(sys_ctrler) { -#ifdef CONFIG_ADB_PMU - case SYS_CTRLER_PMU: { - /* TODO: Move that to a function in the PMU driver */ - struct adb_request req; - unsigned int nowtime; - - DBG("set: tm_mday: %d, tm_mon: %d, tm_year: %d," - " %d:%02d:%02d\n", - tm->tm_mday, tm->tm_mon, tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - nowtime = mktime(tm->tm_year + 1900, tm->tm_mon + 1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - DBG("-> %u -> %u\n", (int)nowtime, - (int)(nowtime + RTC_OFFSET)); - nowtime += RTC_OFFSET; - - if (pmu_request(&req, NULL, 5, PMU_SET_RTC, - nowtime >> 24, nowtime >> 16, - nowtime >> 8, nowtime) < 0) - return -ENXIO; - pmu_wait_complete(&req); - if (req.reply_len != 0) - printk(KERN_ERR "pmac_set_rtc_time: PMU returned a %d" - " bytes reply\n", req.reply_len); - return 0; - } -#endif /* CONFIG_ADB_PMU */ - -#ifdef CONFIG_PMAC_SMU - case SYS_CTRLER_SMU: - return smu_set_rtc_time(tm, 1); -#endif /* CONFIG_PMAC_SMU */ - default: - return -ENODEV; - } -} - -unsigned long __init pmac_get_boot_time(void) -{ - struct rtc_time tm; - - pmac_get_rtc_time(&tm); - return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); -} - -/* - * Query the OF and get the decr frequency. - * FIXME: merge this with generic_calibrate_decr - */ -void __init pmac_calibrate_decr(void) -{ - struct device_node *cpu; - unsigned int *fp; - - /* - * The cpu node should have a timebase-frequency property - * to tell us the rate at which the decrementer counts. - */ - cpu = find_type_devices("cpu"); - if (cpu == 0) - panic("can't find cpu node in time_init"); - fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); - if (fp == 0) - panic("can't get cpu timebase frequency"); - ppc_tb_freq = *fp; - - fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL); - if (fp == 0) - panic("can't get cpu processor frequency"); - ppc_proc_freq = *fp; -} - From c8e0ca683dfea7242ff29814561dfe761945e5b3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sat, 22 Oct 2005 09:43:29 -0700 Subject: [PATCH 0435/1940] [IB] mthca: Always re-arm EQs in mthca_tavor_interrupt() We should always re-arm an event queue's interrupt in mthca_tavor_interrupt() if the corresponding bit is set in the event cause register (ECR), even if we didn't find any entries in the EQ. If we don't, then there's a window where we miss an EQ entry and then get stuck because we don't get another EQ event. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_eq.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index c81fa8e975ef..8dfafda5ed24 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -396,20 +396,21 @@ static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr, struct pt_regs writel(dev->eq_table.clr_mask, dev->eq_table.clr_int); ecr = readl(dev->eq_regs.tavor.ecr_base + 4); - if (ecr) { - writel(ecr, dev->eq_regs.tavor.ecr_base + - MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4); + if (!ecr) + return IRQ_NONE; - for (i = 0; i < MTHCA_NUM_EQ; ++i) - if (ecr & dev->eq_table.eq[i].eqn_mask && - mthca_eq_int(dev, &dev->eq_table.eq[i])) { + writel(ecr, dev->eq_regs.tavor.ecr_base + + MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4); + + for (i = 0; i < MTHCA_NUM_EQ; ++i) + if (ecr & dev->eq_table.eq[i].eqn_mask) { + if (mthca_eq_int(dev, &dev->eq_table.eq[i])) tavor_set_eq_ci(dev, &dev->eq_table.eq[i], dev->eq_table.eq[i].cons_index); - tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn); - } - } + tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn); + } - return IRQ_RETVAL(ecr); + return IRQ_HANDLED; } static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr, From 96c44507601d64f29b8ccc867637292e326c7019 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 23 Oct 2005 17:14:56 +1000 Subject: [PATCH 0436/1940] powerpc: Fix time code for 601 processors The 601 doesn't have the timebase register; instead it has an RTCL register that counts nanoseconds and wraps at 1000000000, and an RTCU register that counts seconds. This makes the necessary changes for the merged time code to use the RTCL/U registers when the kernel is running on a 601. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 79 +++++++++++++++++++++++++++----------- include/asm-powerpc/time.h | 14 ++++++- 2 files changed, 69 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index b635c7de6698..ad501d62aa6e 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -126,6 +126,16 @@ unsigned long ppc_tb_freq; #define boot_cpuid 0 #endif +u64 tb_last_jiffy __cacheline_aligned_in_smp; +unsigned long tb_last_stamp; + +/* + * Note that on ppc32 this only stores the bottom 32 bits of + * the timebase value, but that's enough to tell when a jiffy + * has passed. + */ +DEFINE_PER_CPU(unsigned long, last_jiffy); + static __inline__ void timer_check_rtc(void) { /* @@ -191,6 +201,26 @@ static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) void do_gettimeofday(struct timeval *tv) { + if (__USE_RTC()) { + /* do this the old way */ + unsigned long flags, seq; + unsigned int sec, nsec, usec, lost; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp); + lost = jiffies - wall_jiffies; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + usec = nsec / 1000 + lost * (1000000 / HZ); + while (usec >= 1000000) { + usec -= 1000000; + ++sec; + } + tv->tv_sec = sec; + tv->tv_usec = usec; + return; + } __do_gettimeofday(tv, get_tb()); } @@ -272,6 +302,8 @@ static __inline__ void timer_recalc_offset(u64 cur_tb) unsigned long offset; u64 new_stamp_xsec; + if (__USE_RTC()) + return; offset = cur_tb - do_gtod.varp->tb_orig_stamp; if ((offset & 0x80000000u) == 0) return; @@ -357,15 +389,6 @@ static void iSeries_tb_recal(void) * call will not be needed) */ -u64 tb_last_stamp __cacheline_aligned_in_smp; - -/* - * Note that on ppc32 this only stores the bottom 32 bits of - * the timebase value, but that's enough to tell when a jiffy - * has passed. - */ -DEFINE_PER_CPU(unsigned long, last_jiffy); - /* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. @@ -415,10 +438,11 @@ void timer_interrupt(struct pt_regs * regs) continue; write_seqlock(&xtime_lock); - tb_last_stamp += tb_ticks_per_jiffy; - timer_recalc_offset(tb_last_stamp); + tb_last_jiffy += tb_ticks_per_jiffy; + tb_last_stamp = per_cpu(last_jiffy, cpu); + timer_recalc_offset(tb_last_jiffy); do_timer(regs); - timer_sync_xtime(tb_last_stamp); + timer_sync_xtime(tb_last_jiffy); timer_check_rtc(); write_sequnlock(&xtime_lock); if (adjusting_time && (time_adjust == 0)) @@ -453,7 +477,7 @@ void wakeup_decrementer(void) * We don't expect this to be called on a machine with a 601, * so using get_tbl is fine. */ - tb_last_stamp = get_tb(); + tb_last_stamp = tb_last_jiffy = get_tb(); for_each_cpu(i) per_cpu(last_jiffy, i) = tb_last_stamp; } @@ -483,6 +507,8 @@ void __init smp_space_timers(unsigned int max_cpus) */ unsigned long long sched_clock(void) { + if (__USE_RTC()) + return get_rtc(); return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift; } @@ -534,7 +560,7 @@ int do_settimeofday(struct timespec *tv) new_xsec = (u64)new_nsec * XSEC_PER_SEC; do_div(new_xsec, NSEC_PER_SEC); new_xsec += (u64)new_sec * XSEC_PER_SEC; - update_gtod(tb_last_stamp, new_xsec, do_gtod.varp->tb_to_xs); + update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); #ifdef CONFIG_PPC64 systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; @@ -616,12 +642,20 @@ void __init time_init(void) if (ppc_md.time_init != NULL) timezone_offset = ppc_md.time_init(); - ppc_md.calibrate_decr(); - - printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", - ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); - printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n", - ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); + if (__USE_RTC()) { + /* 601 processor: dec counts down by 128 every 128ns */ + ppc_tb_freq = 1000000000; + tb_last_stamp = get_rtcl(); + tb_last_jiffy = tb_last_stamp; + } else { + /* Normal PowerPC with timebase register */ + ppc_md.calibrate_decr(); + printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", + ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); + printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n", + ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); + tb_last_stamp = tb_last_jiffy = get_tb(); + } tb_ticks_per_jiffy = ppc_tb_freq / HZ; tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; @@ -661,17 +695,16 @@ void __init time_init(void) write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = tm; xtime.tv_nsec = 0; - tb_last_stamp = get_tb(); do_gtod.varp = &do_gtod.vars[0]; do_gtod.var_idx = 0; - do_gtod.varp->tb_orig_stamp = tb_last_stamp; + do_gtod.varp->tb_orig_stamp = tb_last_jiffy; __get_cpu_var(last_jiffy) = tb_last_stamp; do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.varp->tb_to_xs = tb_to_xs; do_gtod.tb_to_us = tb_to_us; #ifdef CONFIG_PPC64 - systemcfg->tb_orig_stamp = tb_last_stamp; + systemcfg->tb_orig_stamp = tb_last_jiffy; systemcfg->tb_update_count = 0; systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index 99bfe3281768..410e795f7d43 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -30,7 +30,8 @@ extern unsigned long tb_ticks_per_usec; extern unsigned long tb_ticks_per_sec; extern u64 tb_to_xs; extern unsigned tb_to_us; -extern u64 tb_last_stamp; +extern unsigned long tb_last_stamp; +extern u64 tb_last_jiffy; DECLARE_PER_CPU(unsigned long, last_jiffy); @@ -113,6 +114,17 @@ static inline unsigned int get_rtcl(void) return rtcl; } +static inline u64 get_rtc(void) +{ + unsigned int hi, lo, hi2; + + do { + asm volatile("mfrtcu %0; mfrtcl %1; mfrtcu %2" + : "=r" (hi), "=r" (lo), "=r" (hi2)); + } while (hi2 != hi); + return (u64)hi * 1000000000 + lo; +} + #ifdef CONFIG_PPC64 static inline u64 get_tb(void) { From a575b807172ca7d8850e6e979c8e83d4258e8c43 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 23 Oct 2005 17:23:21 +1000 Subject: [PATCH 0437/1940] powerpc: Run on old powermacs. Old powermacs have a number of differences from current machines: - there is no interrupt tree in the device tree, just interrupt or AAPL,interrupt properties - the chosen node in the device tree is called /chosen@0 - the OF claim method doesn't map the memory, so we have to do an explicit map call as well - there is no /chosen/cpu property on SMP machines - the NVRAM isn't structured as a set of partitions. This adapts the merged powermac support code to cope with these issues. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 36 +++++++++- arch/powerpc/kernel/prom_init.c | 87 ++++++++++++++++++------- arch/powerpc/platforms/powermac/setup.c | 10 ++- 3 files changed, 106 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c8d288457b4c..69f69c38fd27 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -309,6 +309,37 @@ static int __devinit finish_node_interrupts(struct device_node *np, unsigned int *irq, virq; struct device_node *ic; + if (num_interrupt_controllers == 0) { + /* + * Old machines just have a list of interrupt numbers + * and no interrupt-controller nodes. + */ + ints = (unsigned int *) get_property(np, "AAPL,interrupts", + &intlen); + /* XXX old interpret_pci_props looked in parent too */ + /* XXX old interpret_macio_props looked for interrupts + before AAPL,interrupts */ + if (ints == NULL) + ints = (unsigned int *) get_property(np, "interrupts", + &intlen); + if (ints == NULL) + return 0; + + np->n_intrs = intlen / sizeof(unsigned int); + np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]), + mem_start); + if (!np->intrs) + return -ENOMEM; + if (measure_only) + return 0; + + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ints++; + np->intrs[i].sense = 1; + } + return 0; + } + ints = (unsigned int *) get_property(np, "interrupts", &intlen); if (ints == NULL) return 0; @@ -1024,6 +1055,8 @@ void __init unflatten_device_tree(void) /* Get pointer to OF "/chosen" node for use everywhere */ of_chosen = of_find_node_by_path("/chosen"); + if (of_chosen == NULL) + of_chosen = of_find_node_by_path("/chosen@0"); /* Retreive command line */ if (of_chosen != NULL) { @@ -1123,7 +1156,8 @@ static int __init early_init_dt_scan_chosen(unsigned long node, DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname); - if (depth != 1 || strcmp(uname, "chosen") != 0) + if (depth != 1 || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; /* get platform type */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 095659d51b4b..18d266d8935d 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -132,6 +132,7 @@ struct prom_t { ihandle chosen; int cpu; ihandle stdout; + ihandle mmumap; }; struct mem_map_entry { @@ -274,14 +275,6 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, } -static unsigned int __init prom_claim(unsigned long virt, unsigned long size, - unsigned long align) -{ - return (unsigned int)call_prom("claim", 3, 1, - (prom_arg_t)virt, (prom_arg_t)size, - (prom_arg_t)align); -} - static void __init prom_print(const char *msg) { const char *p, *q; @@ -363,6 +356,21 @@ static void __init prom_printf(const char *format, ...) } +static unsigned int __init prom_claim(unsigned long virt, unsigned long size, + unsigned long align) +{ + int ret; + struct prom_t *_prom = &RELOC(prom); + + ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, + (prom_arg_t)align); + if (ret != -1 && _prom->mmumap != 0) + /* old pmacs need us to map as well */ + call_prom("call-method", 6, 1, + ADDR("map"), _prom->mmumap, 0, size, virt, virt); + return ret; +} + static void __init __attribute__((noreturn)) prom_panic(const char *reason) { #ifdef CONFIG_PPC64 @@ -1323,8 +1331,38 @@ static void __init prom_init_client_services(unsigned long pp) _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); if (!PHANDLE_VALID(_prom->root)) prom_panic("cannot find device tree root"); /* msg won't be printed :( */ + + _prom->mmumap = 0; } +#ifdef CONFIG_PPC32 +/* + * For really old powermacs, we need to map things we claim. + * For that, we need the ihandle of the mmu. + */ +static void __init prom_find_mmu(void) +{ + struct prom_t *_prom = &RELOC(prom); + phandle oprom; + char version[64]; + + oprom = call_prom("finddevice", 1, 1, ADDR("/openprom")); + if (!PHANDLE_VALID(oprom)) + return; + if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) + return; + version[sizeof(version) - 1] = 0; + prom_printf("OF version is '%s'\n", version); + /* XXX might need to add other versions here */ + if (strcmp(version, "Open Firmware, 1.0.5") != 0) + return; + prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, + sizeof(_prom->mmumap)); +} +#else +#define prom_find_mmu() +#endif + static void __init prom_init_stdout(void) { struct prom_t *_prom = &RELOC(prom); @@ -1379,7 +1417,7 @@ static int __init prom_find_machine_type(void) if (sl == 0) break; if (strstr(p, RELOC("Power Macintosh")) || - strstr(p, RELOC("MacRISC4"))) + strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; #ifdef CONFIG_PPC64 if (strstr(p, RELOC("Momentum,Maple"))) @@ -1618,22 +1656,17 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, namep[l] = '\0'; /* Fixup an Apple bug where they have bogus \0 chars in the - * middle of the path in some properties + * middle of the path in some properties, and extract + * the unit name (everything after the last '/'). */ - for (p = namep, ep = namep + l; p < ep; p++) - if (*p == '\0') { - memmove(p, p+1, ep - p); - ep--; l--; p--; - } - - /* now try to extract the unit name in that mess */ - for (p = namep, lp = NULL; *p; p++) + for (lp = p = namep, ep = namep + l; p < ep; p++) { if (*p == '/') - lp = p + 1; - if (lp != NULL) - memmove(namep, lp, strlen(lp) + 1); - *mem_start = _ALIGN(((unsigned long) namep) + - strlen(namep) + 1, 4); + lp = namep; + else if (*p != 0) + *lp++ = *p; + } + *lp = 0; + *mem_start = _ALIGN((unsigned long)lp + 1, 4); } /* get it again for debugging */ @@ -1858,8 +1891,9 @@ static void __init prom_find_boot_cpu(void) ihandle prom_cpu; phandle cpu_pkg; + _prom->cpu = 0; if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0) - prom_panic("cannot find boot cpu"); + return; cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); @@ -1933,6 +1967,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_stdout(); + /* + * See if this OF is old enough that we need to do explicit maps + */ + prom_find_mmu(); + /* * Check for an initrd */ diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 50f5dd787900..908e4921bac4 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -225,7 +225,7 @@ int find_via_pmu(void) return 0; printk("WARNING ! Your machine is PMU-based but your kernel\n"); printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); - return; + return 0; } #endif @@ -293,7 +293,7 @@ static void __init l2cr_init(void) void __init pmac_setup_arch(void) { - struct device_node *cpu; + struct device_node *cpu, *ic; int *fp; unsigned long pvr; @@ -319,6 +319,12 @@ void __init pmac_setup_arch(void) of_node_put(cpu); } + /* See if newworld or oldworld */ + ic = of_find_node_by_name(NULL, "interrupt-controller"); + pmac_newworld = (ic != NULL); + if (ic) + of_node_put(ic); + /* Lookup PCI hosts */ pmac_pci_init(); From 85e568ea5843d455a0bcb682ad2c71abb50bdb80 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 23 Oct 2005 17:26:32 +1000 Subject: [PATCH 0438/1940] powerpc: Make coff boot wrapper load the kernel at 8M Previously it claimed 7MB starting at the 9M point and loaded the kernel there. That meant that prom_init put the flattened device tree above 16M. On the 601 that caused the early device tree scan to fail, since only 16MB are mapped with BATs on the 601. Moving this down to 8MB allows prom_init to put the flattened device tree between 15M and 16M, so it works on the 601. Signed-off-by: Paul Mackerras --- arch/ppc/boot/openfirmware/coffmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c index 04ba9d57e110..2da8855e2be0 100644 --- a/arch/ppc/boot/openfirmware/coffmain.c +++ b/arch/ppc/boot/openfirmware/coffmain.c @@ -38,7 +38,7 @@ static char heap[SCRATCH_SIZE]; static unsigned long ram_start = 0; static unsigned long ram_end = 0x1000000; -static unsigned long prog_start = 0x900000; +static unsigned long prog_start = 0x800000; static unsigned long prog_size = 0x700000; typedef void (*kernel_start_t)(int, int, void *); From 580460194e0e647d95cb5a2b66fdd7497b197f92 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 14:22:37 +1000 Subject: [PATCH 0439/1940] powerpc: Merge arch/ppc64/kernel/vio.c into arch/powerpc/kernel/vio.c Merge arch/ppc64/kernel/vio.c into arch/powerpc/kernel/vio.c, update the Makefiles to make it work, and make ARCH=ppc64 still work. Michael's version put vio.c in arch/powerpc/sysedv but after consolting Paulus, this one puts it in arch/powerpc/kernel. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 1 + arch/{ppc64 => powerpc}/kernel/vio.c | 0 arch/ppc64/kernel/Makefile | 1 - 3 files changed, 1 insertion(+), 1 deletion(-) rename arch/{ppc64 => powerpc}/kernel/vio.c (100%) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 6b0f176265e3..f5d8038fed52 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o ptrace32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o +obj-$(CONFIG_IBMVIO) += vio.o ifeq ($(CONFIG_PPC_MERGE),y) diff --git a/arch/ppc64/kernel/vio.c b/arch/powerpc/kernel/vio.c similarity index 100% rename from arch/ppc64/kernel/vio.c rename to arch/powerpc/kernel/vio.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 424dd250cd87..ce5c99db431f 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -53,7 +53,6 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o endif obj-$(CONFIG_HVCS) += hvcserver.o -obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_PPC_PMAC) += udbg_scc.o From f38d87f566195d78bd70538d5c774758f2d926d3 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 14:32:35 +1000 Subject: [PATCH 0440/1940] powerpc: Move include/asm-ppc64/vio.h to include/asm-powerpc/vio.h Move include/asm-ppc64/vio.h to include/asm-powerpc/vio.h, that's it. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- include/{asm-ppc64 => asm-powerpc}/vio.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/vio.h (84%) diff --git a/include/asm-ppc64/vio.h b/include/asm-powerpc/vio.h similarity index 84% rename from include/asm-ppc64/vio.h rename to include/asm-powerpc/vio.h index 03f1b95f433b..f10f72f24fde 100644 --- a/include/asm-ppc64/vio.h +++ b/include/asm-powerpc/vio.h @@ -1,18 +1,18 @@ /* * IBM PowerPC Virtual I/O Infrastructure Support. * - * Copyright (c) 2003 IBM Corp. - * Dave Engebretsen engebret@us.ibm.com - * Santiago Leon santil@us.ibm.com + * Copyright (c) 2003 IBM Corp. + * Dave Engebretsen engebret@us.ibm.com + * Santiago Leon santil@us.ibm.com * - * 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 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. */ -#ifndef _ASM_VIO_H -#define _ASM_VIO_H +#ifndef _ASM_POWERPC_VIO_H +#define _ASM_POWERPC_VIO_H #include #include @@ -103,4 +103,4 @@ static inline struct vio_dev *to_vio_dev(struct device *dev) return container_of(dev, struct vio_dev, dev); } -#endif /* _ASM_VIO_H */ +#endif /* _ASM_POWERPC_VIO_H */ From 6fdf5392caa4c3cba65add0a4beec9f5eb96b723 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 14:53:21 +1000 Subject: [PATCH 0441/1940] powerpc: don't duplicate name between vio_driver and device_driver Just set the name field directly in the device_driver structure contained in the vio_driver struct. Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/vio.c | 3 +-- drivers/block/viodasd.c | 6 ++++-- drivers/cdrom/viocd.c | 6 ++++-- drivers/char/hvc_vio.c | 2 +- drivers/char/hvcs.c | 4 +++- drivers/char/viotape.c | 6 ++++-- drivers/net/ibmveth.c | 10 ++++++---- drivers/net/iseries_veth.c | 6 ++++-- drivers/scsi/ibmvscsi/ibmvscsi.c | 6 ++++-- include/asm-powerpc/vio.h | 1 - 10 files changed, 31 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 0e555b7a6587..3aec492ec767 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -76,10 +76,9 @@ static int vio_bus_remove(struct device *dev) int vio_register_driver(struct vio_driver *viodrv) { printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__, - viodrv->name); + viodrv->driver.name); /* fill in 'struct driver' fields */ - viodrv->driver.name = viodrv->name; viodrv->driver.bus = &vio_bus_type; viodrv->driver.probe = vio_bus_probe; viodrv->driver.remove = vio_bus_remove; diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index e46ecd23b3ac..ea72faa83436 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -781,10 +781,12 @@ static struct vio_device_id viodasd_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, viodasd_device_table); static struct vio_driver viodasd_driver = { - .name = "viodasd", .id_table = viodasd_device_table, .probe = viodasd_probe, - .remove = viodasd_remove + .remove = viodasd_remove, + .driver = { + .name = "viodasd", + } }; /* diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 0829db58462f..255d24ad704b 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -739,10 +739,12 @@ static struct vio_device_id viocd_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, viocd_device_table); static struct vio_driver viocd_driver = { - .name = "viocd", .id_table = viocd_device_table, .probe = viocd_probe, - .remove = viocd_remove + .remove = viocd_remove, + .driver = { + .name = "viocd", + } }; static int __init viocd_init(void) diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 78d681dc35a8..f5212eb2b41d 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -95,11 +95,11 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev) } static struct vio_driver hvc_vio_driver = { - .name = hvc_driver_name, .id_table = hvc_driver_table, .probe = hvc_vio_probe, .remove = hvc_vio_remove, .driver = { + .name = hvc_driver_name, .owner = THIS_MODULE, } }; diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index f47f009f9259..8486298c011f 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -720,10 +720,12 @@ static int __devexit hvcs_remove(struct vio_dev *dev) }; static struct vio_driver hvcs_vio_driver = { - .name = hvcs_driver_name, .id_table = hvcs_driver_table, .probe = hvcs_probe, .remove = hvcs_remove, + .driver = { + .name = hvcs_driver_name, + } }; /* Only called from hvcs_get_pi please */ diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 0aff45fac2e6..8fc1115c4b69 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -996,10 +996,12 @@ static struct vio_device_id viotape_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, viotape_device_table); static struct vio_driver viotape_driver = { - .name = "viotape", .id_table = viotape_device_table, .probe = viotape_probe, - .remove = viotape_remove + .remove = viotape_remove, + .driver = { + .name = "viotape", + } }; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index a2c4dd4fb221..fcf6f2c76300 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1150,10 +1150,12 @@ static struct vio_device_id ibmveth_device_table[] __devinitdata= { MODULE_DEVICE_TABLE(vio, ibmveth_device_table); static struct vio_driver ibmveth_driver = { - .name = (char *)ibmveth_driver_name, - .id_table = ibmveth_device_table, - .probe = ibmveth_probe, - .remove = ibmveth_remove + .id_table = ibmveth_device_table, + .probe = ibmveth_probe, + .remove = ibmveth_remove, + .driver = { + .name = ibmveth_driver_name, + } }; static int __init ibmveth_module_init(void) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index db3bc2f6f0fa..33613fe9556c 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1648,10 +1648,12 @@ static struct vio_device_id veth_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, veth_device_table); static struct vio_driver veth_driver = { - .name = DRV_NAME, .id_table = veth_device_table, .probe = veth_probe, - .remove = veth_remove + .remove = veth_remove, + .driver = { + .name = DRV_NAME, + } }; /* diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index ff25210b00ba..965e5373538c 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1546,10 +1546,12 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); static struct vio_driver ibmvscsi_driver = { - .name = "ibmvscsi", .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, - .remove = ibmvscsi_remove + .remove = ibmvscsi_remove, + .driver = { + .name = "ibmvscsi", + } }; int __init ibmvscsi_module_init(void) diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h index f10f72f24fde..104c58501d0c 100644 --- a/include/asm-powerpc/vio.h +++ b/include/asm-powerpc/vio.h @@ -55,7 +55,6 @@ struct vio_dev { struct vio_driver { struct list_head node; - char *name; const struct vio_device_id *id_table; int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); int (*remove)(struct vio_dev *dev); From 7c7eb28481a038c3859a0efcf38ac5b642aca212 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 15:21:52 +1000 Subject: [PATCH 0442/1940] powerpc: iseries: Fix a bogus comment A comment in lpevents.c refers to code that's actually in HvCallEvent.h. The code in HvCallEvent.h is pretty obvious, so just remove the comment altogether. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell --- arch/powerpc/platforms/iseries/lpevents.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index f8b4155b0481..54c7753dbe05 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -184,11 +184,7 @@ void setup_hvlpevent_queue(void) { void *eventStack; - /* - * Allocate a page for the Event Stack. The Hypervisor needs the - * absolute real address, so we subtract out the KERNELBASE and add - * in the absolute real address of the kernel load area. - */ + /* Allocate a page for the Event Stack. */ eventStack = alloc_bootmem_pages(LpEventStackSize); memset(eventStack, 0, LpEventStackSize); From 915124d8114ec8c3825b10a39151bf9e851593bb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 15:12:22 +1000 Subject: [PATCH 0443/1940] powerpc: set the driver.owner field for all vio drivers Signed-off-by: Stephen Rothwell --- drivers/block/viodasd.c | 3 ++- drivers/cdrom/viocd.c | 3 ++- drivers/char/hvcs.c | 1 + drivers/char/viotape.c | 3 ++- drivers/net/ibmveth.c | 2 +- drivers/net/iseries_veth.c | 1 + drivers/scsi/ibmvscsi/ibmvscsi.c | 3 ++- 7 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ea72faa83436..709f809f79f1 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -778,14 +778,15 @@ static struct vio_device_id viodasd_device_table[] __devinitdata = { { "viodasd", "" }, { "", "" } }; - MODULE_DEVICE_TABLE(vio, viodasd_device_table); + static struct vio_driver viodasd_driver = { .id_table = viodasd_device_table, .probe = viodasd_probe, .remove = viodasd_remove, .driver = { .name = "viodasd", + .owner = THIS_MODULE, } }; diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 255d24ad704b..36f31d202223 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -736,14 +736,15 @@ static struct vio_device_id viocd_device_table[] __devinitdata = { { "viocd", "" }, { "", "" } }; - MODULE_DEVICE_TABLE(vio, viocd_device_table); + static struct vio_driver viocd_driver = { .id_table = viocd_device_table, .probe = viocd_probe, .remove = viocd_remove, .driver = { .name = "viocd", + .owner = THIS_MODULE, } }; diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 8486298c011f..53dc77c760fc 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -725,6 +725,7 @@ static struct vio_driver hvcs_vio_driver = { .remove = hvcs_remove, .driver = { .name = hvcs_driver_name, + .owner = THIS_MODULE, } }; diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 8fc1115c4b69..d92a05645007 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -993,14 +993,15 @@ static struct vio_device_id viotape_device_table[] __devinitdata = { { "viotape", "" }, { "", "" } }; - MODULE_DEVICE_TABLE(vio, viotape_device_table); + static struct vio_driver viotape_driver = { .id_table = viotape_device_table, .probe = viotape_probe, .remove = viotape_remove, .driver = { .name = "viotape", + .owner = THIS_MODULE, } }; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index fcf6f2c76300..f5dc632452f1 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1146,7 +1146,6 @@ static struct vio_device_id ibmveth_device_table[] __devinitdata= { { "network", "IBM,l-lan"}, { "", "" } }; - MODULE_DEVICE_TABLE(vio, ibmveth_device_table); static struct vio_driver ibmveth_driver = { @@ -1155,6 +1154,7 @@ static struct vio_driver ibmveth_driver = { .remove = ibmveth_remove, .driver = { .name = ibmveth_driver_name, + .owner = THIS_MODULE, } }; diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 33613fe9556c..f5ea39ff1017 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1653,6 +1653,7 @@ static struct vio_driver veth_driver = { .remove = veth_remove, .driver = { .name = DRV_NAME, + .owner = THIS_MODULE, } }; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 965e5373538c..822b9fa706f3 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1543,14 +1543,15 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { {"vscsi", "IBM,v-scsi"}, { "", "" } }; - MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); + static struct vio_driver ibmvscsi_driver = { .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, .remove = ibmvscsi_remove, .driver = { .name = "ibmvscsi", + .owner = THIS_MODULE, } }; From 340601043df518d6f4f82da285c60c785ac8a716 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 24 Oct 2005 17:40:23 +1000 Subject: [PATCH 0444/1940] powerpc: Add a shutdown member to vio_driver Add a shutdown member to struct vio_driver. We also need vio_bus_shutdown() which converts from struct device to struct vio_dev and knows how to extract the struct vio_driver. Original patch adjusted for different location of vio.c. Signed-off-by: Michael Ellerman Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/vio.c | 11 +++++++++++ include/asm-powerpc/vio.h | 1 + 2 files changed, 12 insertions(+) diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 3aec492ec767..97082a4203ad 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -69,6 +69,16 @@ static int vio_bus_remove(struct device *dev) return 1; } +/* convert from struct device to struct vio_dev and pass to driver. */ +static void vio_bus_shutdown(struct device *dev) +{ + struct vio_dev *viodev = to_vio_dev(dev); + struct vio_driver *viodrv = to_vio_driver(dev->driver); + + if (viodrv->shutdown) + viodrv->shutdown(viodev); +} + /** * vio_register_driver: - Register a new vio driver * @drv: The vio_driver structure to be registered. @@ -82,6 +92,7 @@ int vio_register_driver(struct vio_driver *viodrv) viodrv->driver.bus = &vio_bus_type; viodrv->driver.probe = vio_bus_probe; viodrv->driver.remove = vio_bus_remove; + viodrv->driver.shutdown = vio_bus_shutdown; return driver_register(&viodrv->driver); } diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h index 104c58501d0c..e0ccf108277c 100644 --- a/include/asm-powerpc/vio.h +++ b/include/asm-powerpc/vio.h @@ -58,6 +58,7 @@ struct vio_driver { const struct vio_device_id *id_table; int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); int (*remove)(struct vio_dev *dev); + void (*shutdown)(struct vio_dev *dev); unsigned long driver_data; struct device_driver driver; }; From d04bd1fb60252f30f4f41a56613ade48df130588 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Mon, 24 Oct 2005 08:41:24 +0100 Subject: [PATCH 0445/1940] NTFS: Use %z for size_t to fix compilation warnings. (Andrew Morton) Signed-off-by: Andrew Morton Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 3 ++- fs/ntfs/file.c | 4 ++-- fs/ntfs/super.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index bc6ec16ad1f8..2a76b1fbbfc0 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -75,7 +75,8 @@ ToDo/Notes: for highly fragmented files, i.e. ones whose data attribute is split across multiple extents. When such a case is encountered, EOPNOTSUPP is returned. - - $EA attributes can be both resident non-resident. + - $EA attributes can be both resident and non-resident. + - Use %z for size_t to fix compilation warnings. (Andrew Morton) 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index a142bf3ba1a5..cdedc84e1372 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -531,7 +531,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, ni = NTFS_I(vi); vol = ni->vol; ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page " - "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%x.", + "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", vi->i_ino, ni->type, pages[0]->index, nr_pages, (long long)pos, bytes); blocksize_bits = vi->i_blkbits; @@ -1693,7 +1693,7 @@ static int ntfs_commit_pages_after_write(struct page **pages, vi = page->mapping->host; ni = NTFS_I(vi); ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page " - "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%x.", + "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", vi->i_ino, ni->type, page->index, nr_pages, (long long)pos, bytes); if (NInoNonResident(ni)) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 453d0d51ea4b..6c16db9e1a8a 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -1447,7 +1447,7 @@ static BOOL load_and_init_usnjrnl(ntfs_volume *vol) if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) { ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max " "attribute (size is 0x%llx but should be at " - "least 0x%x bytes).", i_size_read(tmp_ino), + "least 0x%zx bytes).", i_size_read(tmp_ino), sizeof(USN_HEADER)); return FALSE; } From dda65b941f992ab10fda3d9f09539c68206b7114 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Mon, 24 Oct 2005 08:57:59 +0100 Subject: [PATCH 0446/1940] NTFS: Fix compilation warnings with gcc-4.0.2 on SUSE 10.0. Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 1 + fs/ntfs/attrib.c | 2 +- fs/ntfs/file.c | 23 ++++++++--------------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 2a76b1fbbfc0..dea742405161 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -77,6 +77,7 @@ ToDo/Notes: EOPNOTSUPP is returned. - $EA attributes can be both resident and non-resident. - Use %z for size_t to fix compilation warnings. (Andrew Morton) + - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0. 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index df2e2091f936..eda056bac256 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -91,7 +91,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) struct page *put_this_page = NULL; int err = 0; BOOL ctx_is_temporary, ctx_needs_reset; - ntfs_attr_search_ctx old_ctx; + ntfs_attr_search_ctx old_ctx = { NULL, }; ntfs_debug("Mapping runlist part containing vcn 0x%llx.", (unsigned long long)vcn); diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index cdedc84e1372..cf3e6ced2d01 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -78,12 +78,8 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) * Extend the initialized size of an attribute described by the ntfs inode @ni * to @new_init_size bytes. This involves zeroing any non-sparse space between * the old initialized size and @new_init_size both in the page cache and on - * disk (if relevant complete pages are zeroed in the page cache then these may - * simply be marked dirty for later writeout). There is one caveat and that is - * that if any uptodate page cache pages between the old initialized size and - * the smaller of @new_init_size and the file size (vfs inode->i_size) are in - * memory, these need to be marked dirty without being zeroed since they could - * be non-zero due to mmap() based writes. + * disk (if relevant complete pages are already uptodate in the page cache then + * these are simply marked dirty). * * As a side-effect, the file size (vfs inode->i_size) may be incremented as, * in the resident attribute case, it is tied to the initialized size and, in @@ -98,10 +94,10 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) * with new data via mmap() based writes, so we cannot just zero it. And since * POSIX specifies that the behaviour of resizing a file whilst it is mmap()ped * is unspecified, we choose not to do zeroing and thus we do not need to touch - * the page at all. For a more detailed explanation see ntfs_truncate() which - * is in fs/ntfs/inode.c. + * the page at all. For a more detailed explanation see ntfs_truncate() in + * fs/ntfs/inode.c. * - * @cached_page and @lru_pvec are just optimisations for dealing with multiple + * @cached_page and @lru_pvec are just optimizations for dealing with multiple * pages. * * Return 0 on success and -errno on error. In the case that an error is @@ -110,9 +106,8 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) * this is the case, the necessary zeroing will also have happened and that all * metadata is self-consistent. * - * Locking: This function locks the mft record of the base ntfs inode and - * maintains the lock throughout execution of the function. This is required - * so that the initialized size of the attribute can be modified safely. + * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be + * held by the caller. */ static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size, struct page **cached_page, struct pagevec *lru_pvec) @@ -1836,7 +1831,7 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, VCN last_vcn; LCN lcn; unsigned long flags; - size_t bytes, iov_ofs; + size_t bytes, iov_ofs = 0; /* Offset in the current iovec. */ ssize_t status, written; unsigned nr_pages; int err; @@ -1988,8 +1983,6 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, last_vcn = -1; if (likely(nr_segs == 1)) buf = iov->iov_base; - else - iov_ofs = 0; /* Offset in the current iovec. */ do { VCN vcn; pgoff_t idx, start_idx; From c9c2009a4e915db17f32701d1f0535b400e61b58 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Mon, 24 Oct 2005 09:00:51 +0100 Subject: [PATCH 0447/1940] NTFS: Document extended attribute ($EA) NEED_EA flag. (Based on libntfs patch by Yura Pakhuchiy.) Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 2 ++ fs/ntfs/layout.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index dea742405161..50a7749cfca1 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -78,6 +78,8 @@ ToDo/Notes: - $EA attributes can be both resident and non-resident. - Use %z for size_t to fix compilation warnings. (Andrew Morton) - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0. + - Document extended attribute ($EA) NEED_EA flag. (Based on libntfs + patch by Yura Pakhuchiy.) 2.1.24 - Lots of bug fixes and support more clean journal states. diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index 71b25dab8199..f5678d5d7919 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h @@ -2374,7 +2374,9 @@ typedef struct { * Extended attribute flags (8-bit). */ enum { - NEED_EA = 0x80 + NEED_EA = 0x80 /* If set the file to which the EA belongs + cannot be interpreted without understanding + the associates extended attributes. */ } __attribute__ ((__packed__)); typedef u8 EA_FLAGS; From 67e1a014fbc0e472ccc55766a63640a767ede3bf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 24 Oct 2005 18:41:39 +1000 Subject: [PATCH 0448/1940] drm: fix warning on 64-bit platforms.. This looks ugly, but it is the only thing that makes sense that doesn't change the API. Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 58e513a44740..319bdea8de8a 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -309,7 +309,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, if (copy_to_user(argp, maplist->map, sizeof(drm_map_t))) return -EFAULT; - if (put_user((void *)maplist->user_token, &argp->handle)) + + /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */ + if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle)) return -EFAULT; return 0; } From a4e62fa031a9681477207b08391c3a5c5c831ce7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 24 Oct 2005 18:45:11 +1000 Subject: [PATCH 0449/1940] drm: remove unused components of drm structures These haven't been used in quite a long time, takes 1K buffer out of structures. Signed-off-by: Dave Airlie --- drivers/char/drm/drmP.h | 5 ----- drivers/char/drm/drm_fops.c | 3 --- 2 files changed, 8 deletions(-) diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 255a21783d10..3dc3c9d79ae4 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -108,7 +108,6 @@ #define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ #define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ #define DRM_LOOPING_LIMIT 5000000 -#define DRM_BSZ 1024 /**< Buffer size for /dev/drm? output */ #define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */ #define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */ @@ -707,10 +706,6 @@ typedef struct drm_device { cycles_t ctx_start; cycles_t lck_start; - char buf[DRM_BSZ]; /**< Output buffer */ - char *buf_rp; /**< Read pointer */ - char *buf_wp; /**< Write pointer */ - char *buf_end; /**< End pointer */ struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /**< Processes waiting to read */ wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */ diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index e0124a9ba14a..bf0a740122bf 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c @@ -96,9 +96,6 @@ static int drm_setup(drm_device_t * dev) dev->ctx_start = 0; dev->lck_start = 0; - dev->buf_rp = dev->buf; - dev->buf_wp = dev->buf; - dev->buf_end = dev->buf + DRM_BSZ; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); From 5d7edb3c1a01310725d86f0d83fb3be45685dc82 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 24 Oct 2005 10:53:25 -0700 Subject: [PATCH 0450/1940] [IB] Add idr_destroy() calls on module unload Add idr_destroy() calls to the module_exit() functions of the four IB driver modules that use idrs, so we don't leak idr_layer_cache objects when these modules are unloaded. Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm.c | 1 + drivers/infiniband/core/sa_query.c | 1 + drivers/infiniband/core/ucm.c | 1 + drivers/infiniband/core/uverbs_main.c | 7 +++++++ 4 files changed, 10 insertions(+) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 54db6d4831f1..151ef83cc14f 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -3323,6 +3323,7 @@ static void __exit ib_cm_cleanup(void) flush_workqueue(cm.wq); destroy_workqueue(cm.wq); ib_unregister_client(&cm_client); + idr_destroy(&cm.local_id_table); } module_init(ib_cm_init); diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 262618210c1c..e215cf0478d6 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -975,6 +975,7 @@ static int __init ib_sa_init(void) static void __exit ib_sa_cleanup(void) { ib_unregister_client(&sa_client); + idr_destroy(&query_idr); } module_init(ib_sa_init); diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index d0f0b0a2edd3..5a6ba4030d44 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -1320,6 +1320,7 @@ static void __exit ib_ucm_cleanup(void) class_destroy(ib_ucm_class); cdev_del(&ib_ucm_cdev); unregister_chrdev_region(IB_UCM_DEV, 1); + idr_destroy(&ctx_id_table); } module_init(ib_ucm_init); diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 12511808de21..add45f7faa5b 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -762,6 +762,13 @@ static void __exit ib_uverbs_cleanup(void) unregister_filesystem(&uverbs_event_fs); class_unregister(&uverbs_class); unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); + idr_destroy(&ib_uverbs_pd_idr); + idr_destroy(&ib_uverbs_mr_idr); + idr_destroy(&ib_uverbs_mw_idr); + idr_destroy(&ib_uverbs_ah_idr); + idr_destroy(&ib_uverbs_cq_idr); + idr_destroy(&ib_uverbs_qp_idr); + idr_destroy(&ib_uverbs_srq_idr); } module_init(ib_uverbs_init); From ae7971a7706384ca373fb7e212fe195698e6c5a1 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 24 Oct 2005 12:33:56 -0700 Subject: [PATCH 0451/1940] [IB] CM: Fix initialization of QP attributes for UC QPs. Fix cm_init_qp_init_attr(), cm_init_qp_rtr_attr() and cm_init_qp_rts_attr() so that they correctly handle the differences between UC and RC QPs. This fixes problems with setting up UC QPs through the CM. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm.c | 38 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 3fe6f4754fa8..389fecbaf662 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -135,6 +135,7 @@ struct cm_id_private { __be64 tid; __be32 local_qpn; __be32 remote_qpn; + enum ib_qp_type qp_type; __be32 sq_psn; __be32 rq_psn; int timeout_ms; @@ -926,6 +927,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, cm_id_priv->responder_resources = param->responder_resources; cm_id_priv->retry_count = param->retry_count; cm_id_priv->path_mtu = param->primary_path->mtu; + cm_id_priv->qp_type = param->qp_type; ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); if (ret) @@ -1320,6 +1322,7 @@ static int cm_req_handler(struct cm_work *work) cm_req_get_primary_local_ack_timeout(req_msg); cm_id_priv->retry_count = cm_req_get_retry_count(req_msg); cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); + cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); cm_format_req_event(work, cm_id_priv, &listen_cm_id_priv->id); cm_process_work(cm_id_priv, work); @@ -3079,10 +3082,10 @@ static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, case IB_CM_ESTABLISHED: *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS | IB_QP_PKEY_INDEX | IB_QP_PORT; - qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE; + qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_WRITE; if (cm_id_priv->responder_resources) - qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_WRITE | - IB_ACCESS_REMOTE_READ; + qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ; qp_attr->pkey_index = cm_id_priv->av.pkey_index; qp_attr->port_num = cm_id_priv->av.port->port_num; ret = 0; @@ -3112,14 +3115,18 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv, case IB_CM_MRA_REP_RCVD: case IB_CM_ESTABLISHED: *qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU | - IB_QP_DEST_QPN | IB_QP_RQ_PSN | - IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER; + IB_QP_DEST_QPN | IB_QP_RQ_PSN; qp_attr->ah_attr = cm_id_priv->av.ah_attr; qp_attr->path_mtu = cm_id_priv->path_mtu; qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn); qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn); - qp_attr->max_dest_rd_atomic = cm_id_priv->responder_resources; - qp_attr->min_rnr_timer = 0; + if (cm_id_priv->qp_type == IB_QPT_RC) { + *qp_attr_mask |= IB_QP_MAX_DEST_RD_ATOMIC | + IB_QP_MIN_RNR_TIMER; + qp_attr->max_dest_rd_atomic = + cm_id_priv->responder_resources; + qp_attr->min_rnr_timer = 0; + } if (cm_id_priv->alt_av.ah_attr.dlid) { *qp_attr_mask |= IB_QP_ALT_PATH; qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; @@ -3148,14 +3155,17 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv, case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: case IB_CM_ESTABLISHED: - *qp_attr_mask = IB_QP_STATE | IB_QP_TIMEOUT | IB_QP_RETRY_CNT | - IB_QP_RNR_RETRY | IB_QP_SQ_PSN | - IB_QP_MAX_QP_RD_ATOMIC; - qp_attr->timeout = cm_id_priv->local_ack_timeout; - qp_attr->retry_cnt = cm_id_priv->retry_count; - qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; + *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN; qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn); - qp_attr->max_rd_atomic = cm_id_priv->initiator_depth; + if (cm_id_priv->qp_type == IB_QPT_RC) { + *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | + IB_QP_RNR_RETRY | + IB_QP_MAX_QP_RD_ATOMIC; + qp_attr->timeout = cm_id_priv->local_ack_timeout; + qp_attr->retry_cnt = cm_id_priv->retry_count; + qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; + qp_attr->max_rd_atomic = cm_id_priv->initiator_depth; + } if (cm_id_priv->alt_av.ah_attr.dlid) { *qp_attr_mask |= IB_QP_PATH_MIG_STATE; qp_attr->path_mig_state = IB_MIG_REARM; From 34816ad98efe4d47ffd858a0345321f9d85d9420 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 25 Oct 2005 10:51:39 -0700 Subject: [PATCH 0452/1940] [IB] Fix MAD layer DMA mappings to avoid touching data buffer once mapped The MAD layer was violating the DMA API by touching data buffers used for sends after the DMA mapping was done. This causes problems on non-cache-coherent architectures, because the device doing DMA won't see updates to the payload buffers that exist only in the CPU cache. Fix this by having all MAD consumers use ib_create_send_mad() to allocate their send buffers, and moving the DMA mapping into the MAD layer so it can be done just before calling send (and after any modifications of the send buffer by the MAD layer). Tested on a non-cache-coherent PowerPC 440SPe system. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/agent.c | 299 +++++++----------------- drivers/infiniband/core/agent.h | 13 +- drivers/infiniband/core/agent_priv.h | 62 ----- drivers/infiniband/core/cm.c | 137 ++++------- drivers/infiniband/core/mad.c | 282 ++++++++++------------ drivers/infiniband/core/mad_priv.h | 8 +- drivers/infiniband/core/mad_rmpp.c | 87 ++++--- drivers/infiniband/core/mad_rmpp.h | 2 + drivers/infiniband/core/sa_query.c | 239 +++++++++---------- drivers/infiniband/core/smi.h | 2 + drivers/infiniband/core/user_mad.c | 47 ++-- drivers/infiniband/hw/mthca/mthca_mad.c | 72 +----- include/rdma/ib_mad.h | 66 +++--- include/rdma/ib_verbs.h | 3 - 14 files changed, 475 insertions(+), 844 deletions(-) delete mode 100644 drivers/infiniband/core/agent_priv.h diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index 5ac86f566dc0..0c3c6952faae 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c @@ -37,58 +37,41 @@ * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $ */ -#include - -#include - -#include - -#include "smi.h" -#include "agent_priv.h" -#include "mad_priv.h" #include "agent.h" +#include "smi.h" -spinlock_t ib_agent_port_list_lock; +#define SPFX "ib_agent: " + +struct ib_agent_port_private { + struct list_head port_list; + struct ib_mad_agent *agent[2]; +}; + +static DEFINE_SPINLOCK(ib_agent_port_list_lock); static LIST_HEAD(ib_agent_port_list); -/* - * Caller must hold ib_agent_port_list_lock - */ -static inline struct ib_agent_port_private * -__ib_get_agent_port(struct ib_device *device, int port_num, - struct ib_mad_agent *mad_agent) +static struct ib_agent_port_private * +__ib_get_agent_port(struct ib_device *device, int port_num) { struct ib_agent_port_private *entry; - BUG_ON(!(!!device ^ !!mad_agent)); /* Exactly one MUST be (!NULL) */ - - if (device) { - list_for_each_entry(entry, &ib_agent_port_list, port_list) { - if (entry->smp_agent->device == device && - entry->port_num == port_num) - return entry; - } - } else { - list_for_each_entry(entry, &ib_agent_port_list, port_list) { - if ((entry->smp_agent == mad_agent) || - (entry->perf_mgmt_agent == mad_agent)) - return entry; - } + list_for_each_entry(entry, &ib_agent_port_list, port_list) { + if (entry->agent[0]->device == device && + entry->agent[0]->port_num == port_num) + return entry; } return NULL; } -static inline struct ib_agent_port_private * -ib_get_agent_port(struct ib_device *device, int port_num, - struct ib_mad_agent *mad_agent) +static struct ib_agent_port_private * +ib_get_agent_port(struct ib_device *device, int port_num) { struct ib_agent_port_private *entry; unsigned long flags; spin_lock_irqsave(&ib_agent_port_list_lock, flags); - entry = __ib_get_agent_port(device, port_num, mad_agent); + entry = __ib_get_agent_port(device, port_num); spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); - return entry; } @@ -100,192 +83,76 @@ int smi_check_local_dr_smp(struct ib_smp *smp, if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) return 1; - port_priv = ib_get_agent_port(device, port_num, NULL); + + port_priv = ib_get_agent_port(device, port_num); if (!port_priv) { printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d " - "not open\n", - device->name, port_num); + "not open\n", device->name, port_num); return 1; } - return smi_check_local_smp(port_priv->smp_agent, smp); + return smi_check_local_smp(port_priv->agent[0], smp); } -static int agent_mad_send(struct ib_mad_agent *mad_agent, - struct ib_agent_port_private *port_priv, - struct ib_mad_private *mad_priv, - struct ib_grh *grh, - struct ib_wc *wc) -{ - struct ib_agent_send_wr *agent_send_wr; - struct ib_sge gather_list; - struct ib_send_wr send_wr; - struct ib_send_wr *bad_send_wr; - struct ib_ah_attr ah_attr; - unsigned long flags; - int ret = 1; - - agent_send_wr = kmalloc(sizeof(*agent_send_wr), GFP_KERNEL); - if (!agent_send_wr) - goto out; - agent_send_wr->mad = mad_priv; - - gather_list.addr = dma_map_single(mad_agent->device->dma_device, - &mad_priv->mad, - sizeof(mad_priv->mad), - DMA_TO_DEVICE); - gather_list.length = sizeof(mad_priv->mad); - gather_list.lkey = mad_agent->mr->lkey; - - send_wr.next = NULL; - send_wr.opcode = IB_WR_SEND; - send_wr.sg_list = &gather_list; - send_wr.num_sge = 1; - send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */ - send_wr.wr.ud.timeout_ms = 0; - send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED; - - ah_attr.dlid = wc->slid; - ah_attr.port_num = mad_agent->port_num; - ah_attr.src_path_bits = wc->dlid_path_bits; - ah_attr.sl = wc->sl; - ah_attr.static_rate = 0; - ah_attr.ah_flags = 0; /* No GRH */ - if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) { - if (wc->wc_flags & IB_WC_GRH) { - ah_attr.ah_flags = IB_AH_GRH; - /* Should sgid be looked up ? */ - ah_attr.grh.sgid_index = 0; - ah_attr.grh.hop_limit = grh->hop_limit; - ah_attr.grh.flow_label = be32_to_cpu( - grh->version_tclass_flow) & 0xfffff; - ah_attr.grh.traffic_class = (be32_to_cpu( - grh->version_tclass_flow) >> 20) & 0xff; - memcpy(ah_attr.grh.dgid.raw, - grh->sgid.raw, - sizeof(ah_attr.grh.dgid)); - } - } - - agent_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr); - if (IS_ERR(agent_send_wr->ah)) { - printk(KERN_ERR SPFX "No memory for address handle\n"); - kfree(agent_send_wr); - goto out; - } - - send_wr.wr.ud.ah = agent_send_wr->ah; - if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) { - send_wr.wr.ud.pkey_index = wc->pkey_index; - send_wr.wr.ud.remote_qkey = IB_QP1_QKEY; - } else { /* for SMPs */ - send_wr.wr.ud.pkey_index = 0; - send_wr.wr.ud.remote_qkey = 0; - } - send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr; - send_wr.wr_id = (unsigned long)agent_send_wr; - - pci_unmap_addr_set(agent_send_wr, mapping, gather_list.addr); - - /* Send */ - spin_lock_irqsave(&port_priv->send_list_lock, flags); - if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) { - spin_unlock_irqrestore(&port_priv->send_list_lock, flags); - dma_unmap_single(mad_agent->device->dma_device, - pci_unmap_addr(agent_send_wr, mapping), - sizeof(mad_priv->mad), - DMA_TO_DEVICE); - ib_destroy_ah(agent_send_wr->ah); - kfree(agent_send_wr); - } else { - list_add_tail(&agent_send_wr->send_list, - &port_priv->send_posted_list); - spin_unlock_irqrestore(&port_priv->send_list_lock, flags); - ret = 0; - } - -out: - return ret; -} - -int agent_send(struct ib_mad_private *mad, - struct ib_grh *grh, - struct ib_wc *wc, - struct ib_device *device, - int port_num) +int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn) { struct ib_agent_port_private *port_priv; - struct ib_mad_agent *mad_agent; + struct ib_mad_agent *agent; + struct ib_mad_send_buf *send_buf; + struct ib_ah *ah; + int ret; - port_priv = ib_get_agent_port(device, port_num, NULL); + port_priv = ib_get_agent_port(device, port_num); if (!port_priv) { - printk(KERN_DEBUG SPFX "agent_send %s port %d not open\n", - device->name, port_num); - return 1; + printk(KERN_ERR SPFX "Unable to find port agent\n"); + return -ENODEV; } - /* Get mad agent based on mgmt_class in MAD */ - switch (mad->mad.mad.mad_hdr.mgmt_class) { - case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: - case IB_MGMT_CLASS_SUBN_LID_ROUTED: - mad_agent = port_priv->smp_agent; - break; - case IB_MGMT_CLASS_PERF_MGMT: - mad_agent = port_priv->perf_mgmt_agent; - break; - default: - return 1; + agent = port_priv->agent[qpn]; + ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); + if (IS_ERR(ah)) { + ret = PTR_ERR(ah); + printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret); + return ret; } - return agent_mad_send(mad_agent, port_priv, mad, grh, wc); + send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, + IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, + GFP_KERNEL); + if (IS_ERR(send_buf)) { + ret = PTR_ERR(send_buf); + printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret); + goto err1; + } + + memcpy(send_buf->mad, mad, sizeof *mad); + send_buf->ah = ah; + if ((ret = ib_post_send_mad(send_buf, NULL))) { + printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret); + goto err2; + } + return 0; +err2: + ib_free_send_mad(send_buf); +err1: + ib_destroy_ah(ah); + return ret; } static void agent_send_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_send_wc) { - struct ib_agent_port_private *port_priv; - struct ib_agent_send_wr *agent_send_wr; - unsigned long flags; - - /* Find matching MAD agent */ - port_priv = ib_get_agent_port(NULL, 0, mad_agent); - if (!port_priv) { - printk(KERN_ERR SPFX "agent_send_handler: no matching MAD " - "agent %p\n", mad_agent); - return; - } - - agent_send_wr = (struct ib_agent_send_wr *)(unsigned long)mad_send_wc->wr_id; - spin_lock_irqsave(&port_priv->send_list_lock, flags); - /* Remove completed send from posted send MAD list */ - list_del(&agent_send_wr->send_list); - spin_unlock_irqrestore(&port_priv->send_list_lock, flags); - - dma_unmap_single(mad_agent->device->dma_device, - pci_unmap_addr(agent_send_wr, mapping), - sizeof(agent_send_wr->mad->mad), - DMA_TO_DEVICE); - - ib_destroy_ah(agent_send_wr->ah); - - /* Release allocated memory */ - kmem_cache_free(ib_mad_cache, agent_send_wr->mad); - kfree(agent_send_wr); + ib_destroy_ah(mad_send_wc->send_buf->ah); + ib_free_send_mad(mad_send_wc->send_buf); } int ib_agent_port_open(struct ib_device *device, int port_num) { - int ret; struct ib_agent_port_private *port_priv; unsigned long flags; - - /* First, check if port already open for SMI */ - port_priv = ib_get_agent_port(device, port_num, NULL); - if (port_priv) { - printk(KERN_DEBUG SPFX "%s port %d already open\n", - device->name, port_num); - return 0; - } + int ret; /* Create new device info */ port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL); @@ -294,32 +161,25 @@ int ib_agent_port_open(struct ib_device *device, int port_num) ret = -ENOMEM; goto error1; } - memset(port_priv, 0, sizeof *port_priv); - port_priv->port_num = port_num; - spin_lock_init(&port_priv->send_list_lock); - INIT_LIST_HEAD(&port_priv->send_posted_list); - /* Obtain send only MAD agent for SM class (SMI QP) */ - port_priv->smp_agent = ib_register_mad_agent(device, port_num, - IB_QPT_SMI, - NULL, 0, + /* Obtain send only MAD agent for SMI QP */ + port_priv->agent[0] = ib_register_mad_agent(device, port_num, + IB_QPT_SMI, NULL, 0, &agent_send_handler, - NULL, NULL); - - if (IS_ERR(port_priv->smp_agent)) { - ret = PTR_ERR(port_priv->smp_agent); + NULL, NULL); + if (IS_ERR(port_priv->agent[0])) { + ret = PTR_ERR(port_priv->agent[0]); goto error2; } - /* Obtain send only MAD agent for PerfMgmt class (GSI QP) */ - port_priv->perf_mgmt_agent = ib_register_mad_agent(device, port_num, - IB_QPT_GSI, - NULL, 0, - &agent_send_handler, - NULL, NULL); - if (IS_ERR(port_priv->perf_mgmt_agent)) { - ret = PTR_ERR(port_priv->perf_mgmt_agent); + /* Obtain send only MAD agent for GSI QP */ + port_priv->agent[1] = ib_register_mad_agent(device, port_num, + IB_QPT_GSI, NULL, 0, + &agent_send_handler, + NULL, NULL); + if (IS_ERR(port_priv->agent[1])) { + ret = PTR_ERR(port_priv->agent[1]); goto error3; } @@ -330,7 +190,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num) return 0; error3: - ib_unregister_mad_agent(port_priv->smp_agent); + ib_unregister_mad_agent(port_priv->agent[0]); error2: kfree(port_priv); error1: @@ -343,7 +203,7 @@ int ib_agent_port_close(struct ib_device *device, int port_num) unsigned long flags; spin_lock_irqsave(&ib_agent_port_list_lock, flags); - port_priv = __ib_get_agent_port(device, port_num, NULL); + port_priv = __ib_get_agent_port(device, port_num); if (port_priv == NULL) { spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); printk(KERN_ERR SPFX "Port %d not found\n", port_num); @@ -352,9 +212,8 @@ int ib_agent_port_close(struct ib_device *device, int port_num) list_del(&port_priv->port_list); spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); - ib_unregister_mad_agent(port_priv->perf_mgmt_agent); - ib_unregister_mad_agent(port_priv->smp_agent); + ib_unregister_mad_agent(port_priv->agent[1]); + ib_unregister_mad_agent(port_priv->agent[0]); kfree(port_priv); - return 0; } diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index d9426842254a..c5f3cfec942a 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -39,17 +39,14 @@ #ifndef __AGENT_H_ #define __AGENT_H_ -extern spinlock_t ib_agent_port_list_lock; +#include -extern int ib_agent_port_open(struct ib_device *device, - int port_num); +extern int ib_agent_port_open(struct ib_device *device, int port_num); extern int ib_agent_port_close(struct ib_device *device, int port_num); -extern int agent_send(struct ib_mad_private *mad, - struct ib_grh *grh, - struct ib_wc *wc, - struct ib_device *device, - int port_num); +extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn); #endif /* __AGENT_H_ */ diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h deleted file mode 100644 index 2ec6d7f1b7d0..000000000000 --- a/drivers/infiniband/core/agent_priv.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved. - * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved. - * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. - * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved. - * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: agent_priv.h 1640 2005-01-24 22:39:02Z halr $ - */ - -#ifndef __IB_AGENT_PRIV_H__ -#define __IB_AGENT_PRIV_H__ - -#include - -#define SPFX "ib_agent: " - -struct ib_agent_send_wr { - struct list_head send_list; - struct ib_ah *ah; - struct ib_mad_private *mad; - DECLARE_PCI_UNMAP_ADDR(mapping) -}; - -struct ib_agent_port_private { - struct list_head port_list; - struct list_head send_posted_list; - spinlock_t send_list_lock; - int port_num; - struct ib_mad_agent *smp_agent; /* SM class */ - struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */ -}; - -#endif /* __IB_AGENT_PRIV_H__ */ diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 389fecbaf662..580c3a2bb102 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -176,8 +176,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, cm_id_priv->av.pkey_index, - ah, 0, sizeof(struct ib_mad_hdr), - sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr), + 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_ATOMIC); if (IS_ERR(m)) { ib_destroy_ah(ah); @@ -185,7 +184,8 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, } /* Timeout set by caller if response is expected. */ - m->send_wr.wr.ud.retries = cm_id_priv->max_cm_retries; + m->ah = ah; + m->retries = cm_id_priv->max_cm_retries; atomic_inc(&cm_id_priv->refcount); m->context[0] = cm_id_priv; @@ -206,20 +206,20 @@ static int cm_alloc_response_msg(struct cm_port *port, return PTR_ERR(ah); m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index, - ah, 0, sizeof(struct ib_mad_hdr), - sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr), + 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_ATOMIC); if (IS_ERR(m)) { ib_destroy_ah(ah); return PTR_ERR(m); } + m->ah = ah; *msg = m; return 0; } static void cm_free_msg(struct ib_mad_send_buf *msg) { - ib_destroy_ah(msg->send_wr.wr.ud.ah); + ib_destroy_ah(msg->ah); if (msg->context[0]) cm_deref_id(msg->context[0]); ib_free_send_mad(msg); @@ -678,8 +678,7 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) break; case IB_CM_SIDR_REQ_SENT: cm_id->state = IB_CM_IDLE; - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); spin_unlock_irqrestore(&cm_id_priv->lock, flags); break; case IB_CM_SIDR_REQ_RCVD: @@ -690,8 +689,7 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) case IB_CM_MRA_REQ_RCVD: case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); /* Fall through */ case IB_CM_REQ_RCVD: case IB_CM_MRA_REQ_SENT: @@ -708,8 +706,7 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) ib_send_cm_dreq(cm_id, NULL, 0); goto retest; case IB_CM_DREQ_SENT: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); cm_enter_timewait(cm_id_priv); spin_unlock_irqrestore(&cm_id_priv->lock, flags); break; @@ -883,7 +880,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, struct ib_cm_req_param *param) { struct cm_id_private *cm_id_priv; - struct ib_send_wr *bad_send_wr; struct cm_req_msg *req_msg; unsigned long flags; int ret; @@ -936,7 +932,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad; cm_format_req(req_msg, cm_id_priv, param); cm_id_priv->tid = req_msg->hdr.tid; - cm_id_priv->msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms; + cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms; cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT; cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg); @@ -945,8 +941,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, cm_req_get_primary_local_ack_timeout(req_msg); spin_lock_irqsave(&cm_id_priv->lock, flags); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &cm_id_priv->msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(cm_id_priv->msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); goto error2; @@ -969,7 +964,6 @@ static int cm_issue_rej(struct cm_port *port, void *ari, u8 ari_length) { struct ib_mad_send_buf *msg = NULL; - struct ib_send_wr *bad_send_wr; struct cm_rej_msg *rej_msg, *rcv_msg; int ret; @@ -992,7 +986,7 @@ static int cm_issue_rej(struct cm_port *port, memcpy(rej_msg->ari, ari, ari_length); } - ret = ib_post_send_mad(port->mad_agent, &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) cm_free_msg(msg); @@ -1172,7 +1166,6 @@ static void cm_dup_req_handler(struct cm_work *work, struct cm_id_private *cm_id_priv) { struct ib_mad_send_buf *msg = NULL; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1201,8 +1194,7 @@ static void cm_dup_req_handler(struct cm_work *work, } spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr, - &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) goto free; return; @@ -1367,7 +1359,6 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id, struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; struct cm_rep_msg *rep_msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1389,11 +1380,10 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id, rep_msg = (struct cm_rep_msg *) msg->mad; cm_format_rep(rep_msg, cm_id_priv, param); - msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms; + msg->timeout_ms = cm_id_priv->timeout_ms; msg->context[1] = (void *) (unsigned long) IB_CM_REP_SENT; - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -1431,7 +1421,6 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; void *data; int ret; @@ -1458,8 +1447,7 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id, cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -1504,7 +1492,6 @@ static void cm_dup_rep_handler(struct cm_work *work) struct cm_id_private *cm_id_priv; struct cm_rep_msg *rep_msg; struct ib_mad_send_buf *msg = NULL; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1532,8 +1519,7 @@ static void cm_dup_rep_handler(struct cm_work *work) goto unlock; spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr, - &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) goto free; goto deref; @@ -1601,8 +1587,7 @@ static int cm_rep_handler(struct cm_work *work) /* todo: handle peer_to_peer */ - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); @@ -1636,8 +1621,7 @@ static int cm_establish_handler(struct cm_work *work) goto out; } - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); @@ -1676,8 +1660,7 @@ static int cm_rtu_handler(struct cm_work *work) } cm_id_priv->id.state = IB_CM_ESTABLISHED; - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); @@ -1714,7 +1697,6 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1736,11 +1718,10 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_id, cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv, private_data, private_data_len); - msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms; + msg->timeout_ms = cm_id_priv->timeout_ms; msg->context[1] = (void *) (unsigned long) IB_CM_DREQ_SENT; - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { cm_enter_timewait(cm_id_priv); spin_unlock_irqrestore(&cm_id_priv->lock, flags); @@ -1774,7 +1755,6 @@ int ib_send_cm_drep(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; void *data; int ret; @@ -1804,8 +1784,7 @@ int ib_send_cm_drep(struct ib_cm_id *cm_id, cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr, - &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -1822,7 +1801,6 @@ static int cm_dreq_handler(struct cm_work *work) struct cm_id_private *cm_id_priv; struct cm_dreq_msg *dreq_msg; struct ib_mad_send_buf *msg = NULL; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1841,8 +1819,7 @@ static int cm_dreq_handler(struct cm_work *work) switch (cm_id_priv->id.state) { case IB_CM_REP_SENT: case IB_CM_DREQ_SENT: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); break; case IB_CM_ESTABLISHED: case IB_CM_MRA_REP_RCVD: @@ -1856,8 +1833,7 @@ static int cm_dreq_handler(struct cm_work *work) cm_id_priv->private_data_len); spin_unlock_irqrestore(&cm_id_priv->lock, flags); - if (ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr)) + if (ib_post_send_mad(msg, NULL)) cm_free_msg(msg); goto deref; default: @@ -1904,8 +1880,7 @@ static int cm_drep_handler(struct cm_work *work) } cm_enter_timewait(cm_id_priv); - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); @@ -1930,7 +1905,6 @@ int ib_send_cm_rej(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -1974,8 +1948,7 @@ int ib_send_cm_rej(struct ib_cm_id *cm_id, if (ret) goto out; - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) cm_free_msg(msg); @@ -2051,8 +2024,7 @@ static int cm_rej_handler(struct cm_work *work) case IB_CM_MRA_REQ_RCVD: case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); /* fall through */ case IB_CM_REQ_RCVD: case IB_CM_MRA_REQ_SENT: @@ -2062,8 +2034,7 @@ static int cm_rej_handler(struct cm_work *work) cm_reset_to_idle(cm_id_priv); break; case IB_CM_DREQ_SENT: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); /* fall through */ case IB_CM_REP_RCVD: case IB_CM_MRA_REP_SENT: @@ -2098,7 +2069,6 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; void *data; unsigned long flags; int ret; @@ -2122,8 +2092,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, CM_MSG_RESPONSE_REQ, service_timeout, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) goto error2; cm_id->state = IB_CM_MRA_REQ_SENT; @@ -2136,8 +2105,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, CM_MSG_RESPONSE_REP, service_timeout, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) goto error2; cm_id->state = IB_CM_MRA_REP_SENT; @@ -2150,8 +2118,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, CM_MSG_RESPONSE_OTHER, service_timeout, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) goto error2; cm_id->lap_state = IB_CM_MRA_LAP_SENT; @@ -2213,14 +2180,14 @@ static int cm_mra_handler(struct cm_work *work) case IB_CM_REQ_SENT: if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ || ib_modify_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg, timeout)) + cm_id_priv->msg, timeout)) goto out; cm_id_priv->id.state = IB_CM_MRA_REQ_RCVD; break; case IB_CM_REP_SENT: if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REP || ib_modify_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg, timeout)) + cm_id_priv->msg, timeout)) goto out; cm_id_priv->id.state = IB_CM_MRA_REP_RCVD; break; @@ -2228,7 +2195,7 @@ static int cm_mra_handler(struct cm_work *work) if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER || cm_id_priv->id.lap_state != IB_CM_LAP_SENT || ib_modify_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg, timeout)) + cm_id_priv->msg, timeout)) goto out; cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD; break; @@ -2291,7 +2258,6 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -2312,11 +2278,10 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, cm_format_lap((struct cm_lap_msg *) msg->mad, cm_id_priv, alternate_path, private_data, private_data_len); - msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms; + msg->timeout_ms = cm_id_priv->timeout_ms; msg->context[1] = (void *) (unsigned long) IB_CM_ESTABLISHED; - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -2360,7 +2325,6 @@ static int cm_lap_handler(struct cm_work *work) struct cm_lap_msg *lap_msg; struct ib_cm_lap_event_param *param; struct ib_mad_send_buf *msg = NULL; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -2394,8 +2358,7 @@ static int cm_lap_handler(struct cm_work *work) cm_id_priv->private_data_len); spin_unlock_irqrestore(&cm_id_priv->lock, flags); - if (ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr)) + if (ib_post_send_mad(msg, NULL)) cm_free_msg(msg); goto deref; default: @@ -2451,7 +2414,6 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -2474,8 +2436,7 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id, cm_format_apr((struct cm_apr_msg *) msg->mad, cm_id_priv, status, info, info_length, private_data, private_data_len); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -2514,8 +2475,7 @@ static int cm_apr_handler(struct cm_work *work) goto out; } cm_id_priv->id.lap_state = IB_CM_LAP_IDLE; - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); cm_id_priv->msg = NULL; ret = atomic_inc_and_test(&cm_id_priv->work_count); @@ -2590,7 +2550,6 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -2613,13 +2572,12 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv, param); - msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms; + msg->timeout_ms = cm_id_priv->timeout_ms; msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT; spin_lock_irqsave(&cm_id_priv->lock, flags); if (cm_id->state == IB_CM_IDLE) - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); else ret = -EINVAL; @@ -2733,7 +2691,6 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, { struct cm_id_private *cm_id_priv; struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; unsigned long flags; int ret; @@ -2755,8 +2712,7 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv, param); - ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, - &msg->send_wr, &bad_send_wr); + ret = ib_post_send_mad(msg, NULL); if (ret) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_free_msg(msg); @@ -2809,8 +2765,7 @@ static int cm_sidr_rep_handler(struct cm_work *work) goto out; } cm_id_priv->id.state = IB_CM_IDLE; - ib_cancel_mad(cm_id_priv->av.port->mad_agent, - (unsigned long) cm_id_priv->msg); + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); spin_unlock_irqrestore(&cm_id_priv->lock, flags); cm_format_sidr_rep_event(work); @@ -2878,9 +2833,7 @@ static void cm_process_send_error(struct ib_mad_send_buf *msg, static void cm_send_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_send_wc) { - struct ib_mad_send_buf *msg; - - msg = (struct ib_mad_send_buf *)(unsigned long)mad_send_wc->wr_id; + struct ib_mad_send_buf *msg = mad_send_wc->send_buf; switch (mad_send_wc->status) { case IB_WC_SUCCESS: diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index af302e830561..88f9f8c9eacc 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -579,7 +579,7 @@ static void dequeue_mad(struct ib_mad_list_head *mad_list) } static void snoop_send(struct ib_mad_qp_info *qp_info, - struct ib_send_wr *send_wr, + struct ib_mad_send_buf *send_buf, struct ib_mad_send_wc *mad_send_wc, int mad_snoop_flags) { @@ -597,7 +597,7 @@ static void snoop_send(struct ib_mad_qp_info *qp_info, atomic_inc(&mad_snoop_priv->refcount); spin_unlock_irqrestore(&qp_info->snoop_lock, flags); mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent, - send_wr, mad_send_wc); + send_buf, mad_send_wc); if (atomic_dec_and_test(&mad_snoop_priv->refcount)) wake_up(&mad_snoop_priv->wait); spin_lock_irqsave(&qp_info->snoop_lock, flags); @@ -654,10 +654,10 @@ static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num, * Return < 0 if error */ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, - struct ib_smp *smp, - struct ib_send_wr *send_wr) + struct ib_mad_send_wr_private *mad_send_wr) { int ret; + struct ib_smp *smp = mad_send_wr->send_buf.mad; unsigned long flags; struct ib_mad_local_private *local; struct ib_mad_private *mad_priv; @@ -666,6 +666,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, struct ib_device *device = mad_agent_priv->agent.device; u8 port_num = mad_agent_priv->agent.port_num; struct ib_wc mad_wc; + struct ib_send_wr *send_wr = &mad_send_wr->send_wr; if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { ret = -EINVAL; @@ -745,13 +746,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, goto out; } - local->send_wr = *send_wr; - local->send_wr.sg_list = local->sg_list; - memcpy(local->sg_list, send_wr->sg_list, - sizeof *send_wr->sg_list * send_wr->num_sge); - local->send_wr.next = NULL; - local->tid = send_wr->wr.ud.mad_hdr->tid; - local->wr_id = send_wr->wr_id; + local->mad_send_wr = mad_send_wr; /* Reference MAD agent until send side of local completion handled */ atomic_inc(&mad_agent_priv->refcount); /* Queue local completion to local list */ @@ -781,17 +776,17 @@ static int get_buf_length(int hdr_len, int data_len) struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, u32 remote_qpn, u16 pkey_index, - struct ib_ah *ah, int rmpp_active, + int rmpp_active, int hdr_len, int data_len, gfp_t gfp_mask) { struct ib_mad_agent_private *mad_agent_priv; - struct ib_mad_send_buf *send_buf; + struct ib_mad_send_wr_private *mad_send_wr; int buf_size; void *buf; - mad_agent_priv = container_of(mad_agent, - struct ib_mad_agent_private, agent); + mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private, + agent); buf_size = get_buf_length(hdr_len, data_len); if ((!mad_agent->rmpp_version && @@ -799,45 +794,40 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, (!rmpp_active && buf_size > sizeof(struct ib_mad))) return ERR_PTR(-EINVAL); - buf = kmalloc(sizeof *send_buf + buf_size, gfp_mask); + buf = kmalloc(sizeof *mad_send_wr + buf_size, gfp_mask); if (!buf) return ERR_PTR(-ENOMEM); - memset(buf, 0, sizeof *send_buf + buf_size); + memset(buf, 0, sizeof *mad_send_wr + buf_size); - send_buf = buf + buf_size; - send_buf->mad = buf; + mad_send_wr = buf + buf_size; + mad_send_wr->send_buf.mad = buf; - send_buf->sge.addr = dma_map_single(mad_agent->device->dma_device, - buf, buf_size, DMA_TO_DEVICE); - pci_unmap_addr_set(send_buf, mapping, send_buf->sge.addr); - send_buf->sge.length = buf_size; - send_buf->sge.lkey = mad_agent->mr->lkey; + mad_send_wr->mad_agent_priv = mad_agent_priv; + mad_send_wr->sg_list[0].length = buf_size; + mad_send_wr->sg_list[0].lkey = mad_agent->mr->lkey; - send_buf->send_wr.wr_id = (unsigned long) send_buf; - send_buf->send_wr.sg_list = &send_buf->sge; - send_buf->send_wr.num_sge = 1; - send_buf->send_wr.opcode = IB_WR_SEND; - send_buf->send_wr.send_flags = IB_SEND_SIGNALED; - send_buf->send_wr.wr.ud.ah = ah; - send_buf->send_wr.wr.ud.mad_hdr = &send_buf->mad->mad_hdr; - send_buf->send_wr.wr.ud.remote_qpn = remote_qpn; - send_buf->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY; - send_buf->send_wr.wr.ud.pkey_index = pkey_index; + mad_send_wr->send_wr.wr_id = (unsigned long) mad_send_wr; + mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list; + mad_send_wr->send_wr.num_sge = 1; + mad_send_wr->send_wr.opcode = IB_WR_SEND; + mad_send_wr->send_wr.send_flags = IB_SEND_SIGNALED; + mad_send_wr->send_wr.wr.ud.remote_qpn = remote_qpn; + mad_send_wr->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY; + mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index; if (rmpp_active) { - struct ib_rmpp_mad *rmpp_mad; - rmpp_mad = (struct ib_rmpp_mad *)send_buf->mad; + struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad; rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len - - offsetof(struct ib_rmpp_mad, data) + data_len); + IB_MGMT_RMPP_HDR + data_len); rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version; rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA; ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); } - send_buf->mad_agent = mad_agent; + mad_send_wr->send_buf.mad_agent = mad_agent; atomic_inc(&mad_agent_priv->refcount); - return send_buf; + return &mad_send_wr->send_buf; } EXPORT_SYMBOL(ib_create_send_mad); @@ -847,10 +837,6 @@ void ib_free_send_mad(struct ib_mad_send_buf *send_buf) mad_agent_priv = container_of(send_buf->mad_agent, struct ib_mad_agent_private, agent); - - dma_unmap_single(send_buf->mad_agent->device->dma_device, - pci_unmap_addr(send_buf, mapping), - send_buf->sge.length, DMA_TO_DEVICE); kfree(send_buf->mad); if (atomic_dec_and_test(&mad_agent_priv->refcount)) @@ -861,8 +847,10 @@ EXPORT_SYMBOL(ib_free_send_mad); int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr) { struct ib_mad_qp_info *qp_info; - struct ib_send_wr *bad_send_wr; struct list_head *list; + struct ib_send_wr *bad_send_wr; + struct ib_mad_agent *mad_agent; + struct ib_sge *sge; unsigned long flags; int ret; @@ -871,10 +859,17 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr) mad_send_wr->send_wr.wr_id = (unsigned long)&mad_send_wr->mad_list; mad_send_wr->mad_list.mad_queue = &qp_info->send_queue; + mad_agent = mad_send_wr->send_buf.mad_agent; + sge = mad_send_wr->sg_list; + sge->addr = dma_map_single(mad_agent->device->dma_device, + mad_send_wr->send_buf.mad, sge->length, + DMA_TO_DEVICE); + pci_unmap_addr_set(mad_send_wr, mapping, sge->addr); + spin_lock_irqsave(&qp_info->send_queue.lock, flags); if (qp_info->send_queue.count < qp_info->send_queue.max_active) { - ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp, - &mad_send_wr->send_wr, &bad_send_wr); + ret = ib_post_send(mad_agent->qp, &mad_send_wr->send_wr, + &bad_send_wr); list = &qp_info->send_queue.list; } else { ret = 0; @@ -886,6 +881,11 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr) list_add_tail(&mad_send_wr->mad_list.list, list); } spin_unlock_irqrestore(&qp_info->send_queue.lock, flags); + if (ret) + dma_unmap_single(mad_agent->device->dma_device, + pci_unmap_addr(mad_send_wr, mapping), + sge->length, DMA_TO_DEVICE); + return ret; } @@ -893,45 +893,28 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr) * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated * with the registered client */ -int ib_post_send_mad(struct ib_mad_agent *mad_agent, - struct ib_send_wr *send_wr, - struct ib_send_wr **bad_send_wr) +int ib_post_send_mad(struct ib_mad_send_buf *send_buf, + struct ib_mad_send_buf **bad_send_buf) { - int ret = -EINVAL; struct ib_mad_agent_private *mad_agent_priv; - - /* Validate supplied parameters */ - if (!bad_send_wr) - goto error1; - - if (!mad_agent || !send_wr) - goto error2; - - if (!mad_agent->send_handler) - goto error2; - - mad_agent_priv = container_of(mad_agent, - struct ib_mad_agent_private, - agent); + struct ib_mad_send_buf *next_send_buf; + struct ib_mad_send_wr_private *mad_send_wr; + unsigned long flags; + int ret = -EINVAL; /* Walk list of send WRs and post each on send list */ - while (send_wr) { - unsigned long flags; - struct ib_send_wr *next_send_wr; - struct ib_mad_send_wr_private *mad_send_wr; - struct ib_smp *smp; + for (; send_buf; send_buf = next_send_buf) { - /* Validate more parameters */ - if (send_wr->num_sge > IB_MAD_SEND_REQ_MAX_SG) - goto error2; + mad_send_wr = container_of(send_buf, + struct ib_mad_send_wr_private, + send_buf); + mad_agent_priv = mad_send_wr->mad_agent_priv; - if (send_wr->wr.ud.timeout_ms && !mad_agent->recv_handler) - goto error2; - - if (!send_wr->wr.ud.mad_hdr) { - printk(KERN_ERR PFX "MAD header must be supplied " - "in WR %p\n", send_wr); - goto error2; + if (!send_buf->mad_agent->send_handler || + (send_buf->timeout_ms && + !send_buf->mad_agent->recv_handler)) { + ret = -EINVAL; + goto error; } /* @@ -939,40 +922,24 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent, * current one completes, and the user modifies the work * request associated with the completion */ - next_send_wr = (struct ib_send_wr *)send_wr->next; + next_send_buf = send_buf->next; + mad_send_wr->send_wr.wr.ud.ah = send_buf->ah; - smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr; - if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { - ret = handle_outgoing_dr_smp(mad_agent_priv, smp, - send_wr); + if (((struct ib_mad_hdr *) send_buf->mad)->mgmt_class == + IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { + ret = handle_outgoing_dr_smp(mad_agent_priv, + mad_send_wr); if (ret < 0) /* error */ - goto error2; + goto error; else if (ret == 1) /* locally consumed */ - goto next; + continue; } - /* Allocate MAD send WR tracking structure */ - mad_send_wr = kmalloc(sizeof *mad_send_wr, GFP_ATOMIC); - if (!mad_send_wr) { - printk(KERN_ERR PFX "No memory for " - "ib_mad_send_wr_private\n"); - ret = -ENOMEM; - goto error2; - } - memset(mad_send_wr, 0, sizeof *mad_send_wr); - - mad_send_wr->send_wr = *send_wr; - mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list; - memcpy(mad_send_wr->sg_list, send_wr->sg_list, - sizeof *send_wr->sg_list * send_wr->num_sge); - mad_send_wr->wr_id = send_wr->wr_id; - mad_send_wr->tid = send_wr->wr.ud.mad_hdr->tid; - mad_send_wr->mad_agent_priv = mad_agent_priv; + mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid; /* Timeout will be updated after send completes */ - mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr. - ud.timeout_ms); - mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries; - /* One reference for each work request to QP + response */ + mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms); + mad_send_wr->retries = send_buf->retries; + /* Reference for work request to QP + response */ mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); mad_send_wr->status = IB_WC_SUCCESS; @@ -995,16 +962,13 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent, list_del(&mad_send_wr->agent_list); spin_unlock_irqrestore(&mad_agent_priv->lock, flags); atomic_dec(&mad_agent_priv->refcount); - goto error2; + goto error; } -next: - send_wr = next_send_wr; } return 0; - -error2: - *bad_send_wr = send_wr; -error1: +error: + if (bad_send_buf) + *bad_send_buf = send_buf; return ret; } EXPORT_SYMBOL(ib_post_send_mad); @@ -1447,8 +1411,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv, * of MAD. */ hi_tid = be64_to_cpu(mad->mad_hdr.tid) >> 32; - list_for_each_entry(entry, &port_priv->agent_list, - agent_list) { + list_for_each_entry(entry, &port_priv->agent_list, agent_list) { if (entry->agent.hi_tid == hi_tid) { mad_agent = entry; break; @@ -1571,8 +1534,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) */ list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, agent_list) { - if (is_data_mad(mad_agent_priv, - mad_send_wr->send_wr.wr.ud.mad_hdr) && + if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && mad_send_wr->tid == tid && mad_send_wr->timeout) { /* Verify request has not been canceled */ return (mad_send_wr->status == IB_WC_SUCCESS) ? @@ -1628,14 +1590,14 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, spin_unlock_irqrestore(&mad_agent_priv->lock, flags); /* Defined behavior is to complete response before request */ - mad_recv_wc->wc->wr_id = mad_send_wr->wr_id; + mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf; mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, mad_recv_wc); atomic_dec(&mad_agent_priv->refcount); mad_send_wc.status = IB_WC_SUCCESS; mad_send_wc.vendor_err = 0; - mad_send_wc.wr_id = mad_send_wr->wr_id; + mad_send_wc.send_buf = &mad_send_wr->send_buf; ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); } else { mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, @@ -1728,11 +1690,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, if (ret & IB_MAD_RESULT_CONSUMED) goto out; if (ret & IB_MAD_RESULT_REPLY) { - /* Send response */ - if (!agent_send(response, &recv->grh, wc, - port_priv->device, - port_priv->port_num)) - response = NULL; + agent_send_response(&response->mad.mad, + &recv->grh, wc, + port_priv->device, + port_priv->port_num, + qp_info->qp->qp_num); goto out; } } @@ -1866,15 +1828,15 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, if (mad_send_wr->status != IB_WC_SUCCESS ) mad_send_wc->status = mad_send_wr->status; - if (ret != IB_RMPP_RESULT_INTERNAL) + if (ret == IB_RMPP_RESULT_INTERNAL) + ib_rmpp_send_handler(mad_send_wc); + else mad_agent_priv->agent.send_handler(&mad_agent_priv->agent, mad_send_wc); /* Release reference on agent taken when sending */ if (atomic_dec_and_test(&mad_agent_priv->refcount)) wake_up(&mad_agent_priv->wait); - - kfree(mad_send_wr); return; done: spin_unlock_irqrestore(&mad_agent_priv->lock, flags); @@ -1888,6 +1850,7 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv, struct ib_mad_qp_info *qp_info; struct ib_mad_queue *send_queue; struct ib_send_wr *bad_send_wr; + struct ib_mad_send_wc mad_send_wc; unsigned long flags; int ret; @@ -1898,6 +1861,9 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv, qp_info = send_queue->qp_info; retry: + dma_unmap_single(mad_send_wr->send_buf.mad_agent->device->dma_device, + pci_unmap_addr(mad_send_wr, mapping), + mad_send_wr->sg_list[0].length, DMA_TO_DEVICE); queued_send_wr = NULL; spin_lock_irqsave(&send_queue->lock, flags); list_del(&mad_list->list); @@ -1914,17 +1880,17 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv, } spin_unlock_irqrestore(&send_queue->lock, flags); - /* Restore client wr_id in WC and complete send */ - wc->wr_id = mad_send_wr->wr_id; + mad_send_wc.send_buf = &mad_send_wr->send_buf; + mad_send_wc.status = wc->status; + mad_send_wc.vendor_err = wc->vendor_err; if (atomic_read(&qp_info->snoop_count)) - snoop_send(qp_info, &mad_send_wr->send_wr, - (struct ib_mad_send_wc *)wc, + snoop_send(qp_info, &mad_send_wr->send_buf, &mad_send_wc, IB_MAD_SNOOP_SEND_COMPLETIONS); - ib_mad_complete_send_wr(mad_send_wr, (struct ib_mad_send_wc *)wc); + ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); if (queued_send_wr) { ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr, - &bad_send_wr); + &bad_send_wr); if (ret) { printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret); mad_send_wr = queued_send_wr; @@ -2066,38 +2032,37 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv) list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr, &cancel_list, agent_list) { - mad_send_wc.wr_id = mad_send_wr->wr_id; + mad_send_wc.send_buf = &mad_send_wr->send_buf; + list_del(&mad_send_wr->agent_list); mad_agent_priv->agent.send_handler(&mad_agent_priv->agent, &mad_send_wc); - - list_del(&mad_send_wr->agent_list); - kfree(mad_send_wr); atomic_dec(&mad_agent_priv->refcount); } } static struct ib_mad_send_wr_private* -find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id) +find_send_wr(struct ib_mad_agent_private *mad_agent_priv, + struct ib_mad_send_buf *send_buf) { struct ib_mad_send_wr_private *mad_send_wr; list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, agent_list) { - if (mad_send_wr->wr_id == wr_id) + if (&mad_send_wr->send_buf == send_buf) return mad_send_wr; } list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, agent_list) { - if (is_data_mad(mad_agent_priv, - mad_send_wr->send_wr.wr.ud.mad_hdr) && - mad_send_wr->wr_id == wr_id) + if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && + &mad_send_wr->send_buf == send_buf) return mad_send_wr; } return NULL; } -int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms) +int ib_modify_mad(struct ib_mad_agent *mad_agent, + struct ib_mad_send_buf *send_buf, u32 timeout_ms) { struct ib_mad_agent_private *mad_agent_priv; struct ib_mad_send_wr_private *mad_send_wr; @@ -2107,7 +2072,7 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms) mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private, agent); spin_lock_irqsave(&mad_agent_priv->lock, flags); - mad_send_wr = find_send_by_wr_id(mad_agent_priv, wr_id); + mad_send_wr = find_send_wr(mad_agent_priv, send_buf); if (!mad_send_wr || mad_send_wr->status != IB_WC_SUCCESS) { spin_unlock_irqrestore(&mad_agent_priv->lock, flags); return -EINVAL; @@ -2119,7 +2084,7 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms) mad_send_wr->refcount -= (mad_send_wr->timeout > 0); } - mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms; + mad_send_wr->send_buf.timeout_ms = timeout_ms; if (active) mad_send_wr->timeout = msecs_to_jiffies(timeout_ms); else @@ -2130,9 +2095,10 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms) } EXPORT_SYMBOL(ib_modify_mad); -void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id) +void ib_cancel_mad(struct ib_mad_agent *mad_agent, + struct ib_mad_send_buf *send_buf) { - ib_modify_mad(mad_agent, wr_id, 0); + ib_modify_mad(mad_agent, send_buf, 0); } EXPORT_SYMBOL(ib_cancel_mad); @@ -2166,10 +2132,9 @@ static void local_completions(void *data) * Defined behavior is to complete response * before request */ - build_smp_wc(local->wr_id, + build_smp_wc((unsigned long) local->mad_send_wr, be16_to_cpu(IB_LID_PERMISSIVE), - 0 /* pkey index */, - recv_mad_agent->agent.port_num, &wc); + 0, recv_mad_agent->agent.port_num, &wc); local->mad_priv->header.recv_wc.wc = &wc; local->mad_priv->header.recv_wc.mad_len = @@ -2196,11 +2161,11 @@ static void local_completions(void *data) /* Complete send */ mad_send_wc.status = IB_WC_SUCCESS; mad_send_wc.vendor_err = 0; - mad_send_wc.wr_id = local->wr_id; + mad_send_wc.send_buf = &local->mad_send_wr->send_buf; if (atomic_read(&mad_agent_priv->qp_info->snoop_count)) - snoop_send(mad_agent_priv->qp_info, &local->send_wr, - &mad_send_wc, - IB_MAD_SNOOP_SEND_COMPLETIONS); + snoop_send(mad_agent_priv->qp_info, + &local->mad_send_wr->send_buf, + &mad_send_wc, IB_MAD_SNOOP_SEND_COMPLETIONS); mad_agent_priv->agent.send_handler(&mad_agent_priv->agent, &mad_send_wc); @@ -2221,8 +2186,7 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) if (!mad_send_wr->retries--) return -ETIMEDOUT; - mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr. - wr.ud.timeout_ms); + mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); if (mad_send_wr->mad_agent_priv->agent.rmpp_version) { ret = ib_retry_rmpp(mad_send_wr); @@ -2285,11 +2249,10 @@ static void timeout_sends(void *data) mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR; else mad_send_wc.status = mad_send_wr->status; - mad_send_wc.wr_id = mad_send_wr->wr_id; + mad_send_wc.send_buf = &mad_send_wr->send_buf; mad_agent_priv->agent.send_handler(&mad_agent_priv->agent, &mad_send_wc); - kfree(mad_send_wr); atomic_dec(&mad_agent_priv->refcount); spin_lock_irqsave(&mad_agent_priv->lock, flags); } @@ -2761,7 +2724,6 @@ static int __init ib_mad_init_module(void) int ret; spin_lock_init(&ib_mad_port_list_lock); - spin_lock_init(&ib_agent_port_list_lock); ib_mad_cache = kmem_cache_create("ib_mad", sizeof(struct ib_mad_private), diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index f1ba794e0daa..570f78682af3 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -118,9 +118,10 @@ struct ib_mad_send_wr_private { struct ib_mad_list_head mad_list; struct list_head agent_list; struct ib_mad_agent_private *mad_agent_priv; + struct ib_mad_send_buf send_buf; + DECLARE_PCI_UNMAP_ADDR(mapping) struct ib_send_wr send_wr; struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; - u64 wr_id; /* client WR ID */ __be64 tid; unsigned long timeout; int retries; @@ -141,10 +142,7 @@ struct ib_mad_local_private { struct list_head completion_list; struct ib_mad_private *mad_priv; struct ib_mad_agent_private *recv_mad_agent; - struct ib_send_wr send_wr; - struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; - u64 wr_id; /* client WR ID */ - __be64 tid; + struct ib_mad_send_wr_private *mad_send_wr; }; struct ib_mad_mgmt_method_table { diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index e23836d0e21b..ba112cd5f93c 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -103,12 +103,12 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent) static int data_offset(u8 mgmt_class) { if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) - return offsetof(struct ib_sa_mad, data); + return IB_MGMT_SA_HDR; else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) - return offsetof(struct ib_vendor_mad, data); + return IB_MGMT_VENDOR_HDR; else - return offsetof(struct ib_rmpp_mad, data); + return IB_MGMT_RMPP_HDR; } static void format_ack(struct ib_rmpp_mad *ack, @@ -135,21 +135,18 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, struct ib_mad_recv_wc *recv_wc) { struct ib_mad_send_buf *msg; - struct ib_send_wr *bad_send_wr; - int hdr_len, ret; + int ret; - hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, - recv_wc->wc->pkey_index, rmpp_recv->ah, 1, - hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len, - GFP_KERNEL); + recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR, + IB_MGMT_RMPP_DATA, GFP_KERNEL); if (!msg) return; - format_ack((struct ib_rmpp_mad *) msg->mad, - (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); - ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr, - &bad_send_wr); + format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, + rmpp_recv); + msg->ah = rmpp_recv->ah; + ret = ib_post_send_mad(msg, NULL); if (ret) ib_free_send_mad(msg); } @@ -160,30 +157,31 @@ static int alloc_response_msg(struct ib_mad_agent *agent, { struct ib_mad_send_buf *m; struct ib_ah *ah; - int hdr_len; ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, recv_wc->recv_buf.grh, agent->port_num); if (IS_ERR(ah)) return PTR_ERR(ah); - hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); m = ib_create_send_mad(agent, recv_wc->wc->src_qp, - recv_wc->wc->pkey_index, ah, 1, hdr_len, - sizeof(struct ib_rmpp_mad) - hdr_len, - GFP_KERNEL); + recv_wc->wc->pkey_index, 1, + IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA, GFP_KERNEL); if (IS_ERR(m)) { ib_destroy_ah(ah); return PTR_ERR(m); } + m->ah = ah; *msg = m; return 0; } -static void free_msg(struct ib_mad_send_buf *msg) +void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) { - ib_destroy_ah(msg->send_wr.wr.ud.ah); - ib_free_send_mad(msg); + struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; + + if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK) + ib_destroy_ah(mad_send_wc->send_buf->ah); + ib_free_send_mad(mad_send_wc->send_buf); } static void nack_recv(struct ib_mad_agent_private *agent, @@ -191,14 +189,13 @@ static void nack_recv(struct ib_mad_agent_private *agent, { struct ib_mad_send_buf *msg; struct ib_rmpp_mad *rmpp_mad; - struct ib_send_wr *bad_send_wr; int ret; ret = alloc_response_msg(&agent->agent, recv_wc, &msg); if (ret) return; - rmpp_mad = (struct ib_rmpp_mad *) msg->mad; + rmpp_mad = msg->mad; memcpy(rmpp_mad, recv_wc->recv_buf.mad, data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class)); @@ -210,9 +207,11 @@ static void nack_recv(struct ib_mad_agent_private *agent, rmpp_mad->rmpp_hdr.seg_num = 0; rmpp_mad->rmpp_hdr.paylen_newwin = 0; - ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr); - if (ret) - free_msg(msg); + ret = ib_post_send_mad(msg, NULL); + if (ret) { + ib_destroy_ah(msg->ah); + ib_free_send_mad(msg); + } } static void recv_timeout_handler(void *data) @@ -585,7 +584,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) int timeout; u32 paylen; - rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; + rmpp_mad = mad_send_wr->send_buf.mad; ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num); @@ -612,7 +611,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) } /* 2 seconds for an ACK until we can find the packet lifetime */ - timeout = mad_send_wr->send_wr.wr.ud.timeout_ms; + timeout = mad_send_wr->send_buf.timeout_ms; if (!timeout || timeout > 2000) mad_send_wr->timeout = msecs_to_jiffies(2000); mad_send_wr->seg_num++; @@ -640,7 +639,7 @@ static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, wc.status = IB_WC_REM_ABORT_ERR; wc.vendor_err = rmpp_status; - wc.wr_id = mad_send_wr->wr_id; + wc.send_buf = &mad_send_wr->send_buf; ib_mad_complete_send_wr(mad_send_wr, &wc); return; out: @@ -694,12 +693,12 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, if (seg_num > mad_send_wr->last_ack) { mad_send_wr->last_ack = seg_num; - mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries; + mad_send_wr->retries = mad_send_wr->send_buf.retries; } mad_send_wr->newwin = newwin; if (mad_send_wr->last_ack == mad_send_wr->total_seg) { /* If no response is expected, the ACK completes the send */ - if (!mad_send_wr->send_wr.wr.ud.timeout_ms) { + if (!mad_send_wr->send_buf.timeout_ms) { struct ib_mad_send_wc wc; ib_mark_mad_done(mad_send_wr); @@ -707,13 +706,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, wc.status = IB_WC_SUCCESS; wc.vendor_err = 0; - wc.wr_id = mad_send_wr->wr_id; + wc.send_buf = &mad_send_wr->send_buf; ib_mad_complete_send_wr(mad_send_wr, &wc); return; } if (mad_send_wr->refcount == 1) - ib_reset_mad_timeout(mad_send_wr, mad_send_wr-> - send_wr.wr.ud.timeout_ms); + ib_reset_mad_timeout(mad_send_wr, + mad_send_wr->send_buf.timeout_ms); } else if (mad_send_wr->refcount == 1 && mad_send_wr->seg_num < mad_send_wr->newwin && mad_send_wr->seg_num <= mad_send_wr->total_seg) { @@ -842,7 +841,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr) struct ib_rmpp_mad *rmpp_mad; int i, total_len, ret; - rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; + rmpp_mad = mad_send_wr->send_buf.mad; if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) return IB_RMPP_RESULT_UNHANDLED; @@ -863,7 +862,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr) mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) / (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset); - mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) - + mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); /* We need to wait for the final ACK even if there isn't a response */ @@ -878,23 +877,15 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr, struct ib_mad_send_wc *mad_send_wc) { struct ib_rmpp_mad *rmpp_mad; - struct ib_mad_send_buf *msg; int ret; - rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; + rmpp_mad = mad_send_wr->send_buf.mad; if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ - if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { - msg = (struct ib_mad_send_buf *) (unsigned long) - mad_send_wc->wr_id; - if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK) - ib_free_send_mad(msg); - else - free_msg(msg); + if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */ - } if (mad_send_wc->status != IB_WC_SUCCESS || mad_send_wr->status != IB_WC_SUCCESS) @@ -905,7 +896,7 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr, if (mad_send_wr->last_ack == mad_send_wr->total_seg) { mad_send_wr->timeout = - msecs_to_jiffies(mad_send_wr->send_wr.wr.ud.timeout_ms); + msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); return IB_RMPP_RESULT_PROCESSED; /* Send done */ } @@ -926,7 +917,7 @@ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr) struct ib_rmpp_mad *rmpp_mad; int ret; - rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; + rmpp_mad = mad_send_wr->send_buf.mad; if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ diff --git a/drivers/infiniband/core/mad_rmpp.h b/drivers/infiniband/core/mad_rmpp.h index c4924dfb8e75..f0616fd22494 100644 --- a/drivers/infiniband/core/mad_rmpp.h +++ b/drivers/infiniband/core/mad_rmpp.h @@ -51,6 +51,8 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr, struct ib_mad_send_wc *mad_send_wc); +void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc); + void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent); int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr); diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 0e5ef97f7637..89ce9dc210d4 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -73,11 +73,10 @@ struct ib_sa_device { struct ib_sa_query { void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *); void (*release)(struct ib_sa_query *); - struct ib_sa_port *port; - struct ib_sa_mad *mad; - struct ib_sa_sm_ah *sm_ah; - DECLARE_PCI_UNMAP_ADDR(mapping) - int id; + struct ib_sa_port *port; + struct ib_mad_send_buf *mad_buf; + struct ib_sa_sm_ah *sm_ah; + int id; }; struct ib_sa_service_query { @@ -426,6 +425,7 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query) { unsigned long flags; struct ib_mad_agent *agent; + struct ib_mad_send_buf *mad_buf; spin_lock_irqsave(&idr_lock, flags); if (idr_find(&query_idr, id) != query) { @@ -433,9 +433,10 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query) return; } agent = query->port->agent; + mad_buf = query->mad_buf; spin_unlock_irqrestore(&idr_lock, flags); - ib_cancel_mad(agent, id); + ib_cancel_mad(agent, mad_buf); } EXPORT_SYMBOL(ib_sa_cancel_query); @@ -457,71 +458,46 @@ static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) static int send_mad(struct ib_sa_query *query, int timeout_ms) { - struct ib_sa_port *port = query->port; unsigned long flags; - int ret; - struct ib_sge gather_list; - struct ib_send_wr *bad_wr, wr = { - .opcode = IB_WR_SEND, - .sg_list = &gather_list, - .num_sge = 1, - .send_flags = IB_SEND_SIGNALED, - .wr = { - .ud = { - .mad_hdr = &query->mad->mad_hdr, - .remote_qpn = 1, - .remote_qkey = IB_QP1_QKEY, - .timeout_ms = timeout_ms, - } - } - }; + int ret, id; retry: if (!idr_pre_get(&query_idr, GFP_ATOMIC)) return -ENOMEM; spin_lock_irqsave(&idr_lock, flags); - ret = idr_get_new(&query_idr, query, &query->id); + ret = idr_get_new(&query_idr, query, &id); spin_unlock_irqrestore(&idr_lock, flags); if (ret == -EAGAIN) goto retry; if (ret) return ret; - wr.wr_id = query->id; + query->mad_buf->timeout_ms = timeout_ms; + query->mad_buf->context[0] = query; + query->id = id; - spin_lock_irqsave(&port->ah_lock, flags); - kref_get(&port->sm_ah->ref); - query->sm_ah = port->sm_ah; - wr.wr.ud.ah = port->sm_ah->ah; - spin_unlock_irqrestore(&port->ah_lock, flags); + spin_lock_irqsave(&query->port->ah_lock, flags); + kref_get(&query->port->sm_ah->ref); + query->sm_ah = query->port->sm_ah; + spin_unlock_irqrestore(&query->port->ah_lock, flags); - gather_list.addr = dma_map_single(port->agent->device->dma_device, - query->mad, - sizeof (struct ib_sa_mad), - DMA_TO_DEVICE); - gather_list.length = sizeof (struct ib_sa_mad); - gather_list.lkey = port->agent->mr->lkey; - pci_unmap_addr_set(query, mapping, gather_list.addr); + query->mad_buf->ah = query->sm_ah->ah; - ret = ib_post_send_mad(port->agent, &wr, &bad_wr); + ret = ib_post_send_mad(query->mad_buf, NULL); if (ret) { - dma_unmap_single(port->agent->device->dma_device, - pci_unmap_addr(query, mapping), - sizeof (struct ib_sa_mad), - DMA_TO_DEVICE); - kref_put(&query->sm_ah->ref, free_sm_ah); spin_lock_irqsave(&idr_lock, flags); - idr_remove(&query_idr, query->id); + idr_remove(&query_idr, id); spin_unlock_irqrestore(&idr_lock, flags); + + kref_put(&query->sm_ah->ref, free_sm_ah); } /* * It's not safe to dereference query any more, because the * send may already have completed and freed the query in - * another context. So use wr.wr_id, which has a copy of the - * query's id. + * another context. */ - return ret ? ret : wr.wr_id; + return ret ? ret : id; } static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, @@ -543,7 +519,6 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, static void ib_sa_path_rec_release(struct ib_sa_query *sa_query) { - kfree(sa_query->mad); kfree(container_of(sa_query, struct ib_sa_path_query, sa_query)); } @@ -585,6 +560,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); struct ib_sa_port *port; struct ib_mad_agent *agent; + struct ib_sa_mad *mad; int ret; if (!sa_dev) @@ -596,37 +572,45 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, query = kmalloc(sizeof *query, gfp_mask); if (!query) return -ENOMEM; - query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); - if (!query->sa_query.mad) { - kfree(query); - return -ENOMEM; + + query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, + 0, IB_MGMT_SA_HDR, + IB_MGMT_SA_DATA, gfp_mask); + if (!query->sa_query.mad_buf) { + ret = -ENOMEM; + goto err1; } query->callback = callback; query->context = context; - init_mad(query->sa_query.mad, agent); + mad = query->sa_query.mad_buf->mad; + init_mad(mad, agent); - query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; - query->sa_query.release = ib_sa_path_rec_release; - query->sa_query.port = port; - query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET; - query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC); - query->sa_query.mad->sa_hdr.comp_mask = comp_mask; + query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; + query->sa_query.release = ib_sa_path_rec_release; + query->sa_query.port = port; + mad->mad_hdr.method = IB_MGMT_METHOD_GET; + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC); + mad->sa_hdr.comp_mask = comp_mask; - ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), - rec, query->sa_query.mad->data); + ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data); *sa_query = &query->sa_query; ret = send_mad(&query->sa_query, timeout_ms); - if (ret < 0) { - *sa_query = NULL; - kfree(query->sa_query.mad); - kfree(query); - } + if (ret < 0) + goto err2; return ret; + +err2: + *sa_query = NULL; + ib_free_send_mad(query->sa_query.mad_buf); + +err1: + kfree(query); + return ret; } EXPORT_SYMBOL(ib_sa_path_rec_get); @@ -649,7 +633,6 @@ static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query, static void ib_sa_service_rec_release(struct ib_sa_query *sa_query) { - kfree(sa_query->mad); kfree(container_of(sa_query, struct ib_sa_service_query, sa_query)); } @@ -693,6 +676,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); struct ib_sa_port *port; struct ib_mad_agent *agent; + struct ib_sa_mad *mad; int ret; if (!sa_dev) @@ -709,38 +693,46 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, query = kmalloc(sizeof *query, gfp_mask); if (!query) return -ENOMEM; - query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); - if (!query->sa_query.mad) { - kfree(query); - return -ENOMEM; + + query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, + 0, IB_MGMT_SA_HDR, + IB_MGMT_SA_DATA, gfp_mask); + if (!query->sa_query.mad_buf) { + ret = -ENOMEM; + goto err1; } query->callback = callback; query->context = context; - init_mad(query->sa_query.mad, agent); + mad = query->sa_query.mad_buf->mad; + init_mad(mad, agent); - query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; - query->sa_query.release = ib_sa_service_rec_release; - query->sa_query.port = port; - query->sa_query.mad->mad_hdr.method = method; - query->sa_query.mad->mad_hdr.attr_id = - cpu_to_be16(IB_SA_ATTR_SERVICE_REC); - query->sa_query.mad->sa_hdr.comp_mask = comp_mask; + query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; + query->sa_query.release = ib_sa_service_rec_release; + query->sa_query.port = port; + mad->mad_hdr.method = method; + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC); + mad->sa_hdr.comp_mask = comp_mask; ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table), - rec, query->sa_query.mad->data); + rec, mad->data); *sa_query = &query->sa_query; ret = send_mad(&query->sa_query, timeout_ms); - if (ret < 0) { - *sa_query = NULL; - kfree(query->sa_query.mad); - kfree(query); - } + if (ret < 0) + goto err2; return ret; + +err2: + *sa_query = NULL; + ib_free_send_mad(query->sa_query.mad_buf); + +err1: + kfree(query); + return ret; } EXPORT_SYMBOL(ib_sa_service_rec_query); @@ -763,7 +755,6 @@ static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query, static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query) { - kfree(sa_query->mad); kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query)); } @@ -782,6 +773,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); struct ib_sa_port *port; struct ib_mad_agent *agent; + struct ib_sa_mad *mad; int ret; if (!sa_dev) @@ -793,53 +785,55 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, query = kmalloc(sizeof *query, gfp_mask); if (!query) return -ENOMEM; - query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); - if (!query->sa_query.mad) { - kfree(query); - return -ENOMEM; + + query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, + 0, IB_MGMT_SA_HDR, + IB_MGMT_SA_DATA, gfp_mask); + if (!query->sa_query.mad_buf) { + ret = -ENOMEM; + goto err1; } query->callback = callback; query->context = context; - init_mad(query->sa_query.mad, agent); + mad = query->sa_query.mad_buf->mad; + init_mad(mad, agent); - query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; - query->sa_query.release = ib_sa_mcmember_rec_release; - query->sa_query.port = port; - query->sa_query.mad->mad_hdr.method = method; - query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC); - query->sa_query.mad->sa_hdr.comp_mask = comp_mask; + query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; + query->sa_query.release = ib_sa_mcmember_rec_release; + query->sa_query.port = port; + mad->mad_hdr.method = method; + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC); + mad->sa_hdr.comp_mask = comp_mask; ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table), - rec, query->sa_query.mad->data); + rec, mad->data); *sa_query = &query->sa_query; ret = send_mad(&query->sa_query, timeout_ms); - if (ret < 0) { - *sa_query = NULL; - kfree(query->sa_query.mad); - kfree(query); - } + if (ret < 0) + goto err2; return ret; + +err2: + *sa_query = NULL; + ib_free_send_mad(query->sa_query.mad_buf); + +err1: + kfree(query); + return ret; } EXPORT_SYMBOL(ib_sa_mcmember_rec_query); static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *mad_send_wc) { - struct ib_sa_query *query; + struct ib_sa_query *query = mad_send_wc->send_buf->context[0]; unsigned long flags; - spin_lock_irqsave(&idr_lock, flags); - query = idr_find(&query_idr, mad_send_wc->wr_id); - spin_unlock_irqrestore(&idr_lock, flags); - - if (!query) - return; - if (query->callback) switch (mad_send_wc->status) { case IB_WC_SUCCESS: @@ -856,30 +850,25 @@ static void send_handler(struct ib_mad_agent *agent, break; } - dma_unmap_single(agent->device->dma_device, - pci_unmap_addr(query, mapping), - sizeof (struct ib_sa_mad), - DMA_TO_DEVICE); - kref_put(&query->sm_ah->ref, free_sm_ah); - - query->release(query); - spin_lock_irqsave(&idr_lock, flags); - idr_remove(&query_idr, mad_send_wc->wr_id); + idr_remove(&query_idr, query->id); spin_unlock_irqrestore(&idr_lock, flags); + + ib_free_send_mad(mad_send_wc->send_buf); + kref_put(&query->sm_ah->ref, free_sm_ah); + query->release(query); } static void recv_handler(struct ib_mad_agent *mad_agent, struct ib_mad_recv_wc *mad_recv_wc) { struct ib_sa_query *query; - unsigned long flags; + struct ib_mad_send_buf *mad_buf; - spin_lock_irqsave(&idr_lock, flags); - query = idr_find(&query_idr, mad_recv_wc->wc->wr_id); - spin_unlock_irqrestore(&idr_lock, flags); + mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id; + query = mad_buf->context[0]; - if (query && query->callback) { + if (query->callback) { if (mad_recv_wc->wc->status == IB_WC_SUCCESS) query->callback(query, mad_recv_wc->recv_buf.mad->mad_hdr.status ? diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h index db25503a0736..2b3c40198f81 100644 --- a/drivers/infiniband/core/smi.h +++ b/drivers/infiniband/core/smi.h @@ -39,6 +39,8 @@ #ifndef __SMI_H_ #define __SMI_H_ +#include + int smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, int port_num, diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index fd200c064a2e..fc5519a3de99 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -96,7 +96,6 @@ struct ib_umad_file { }; struct ib_umad_packet { - struct ib_ah *ah; struct ib_mad_send_buf *msg; struct list_head list; int length; @@ -139,10 +138,10 @@ static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *send_wc) { struct ib_umad_file *file = agent->context; - struct ib_umad_packet *timeout, *packet = - (void *) (unsigned long) send_wc->wr_id; + struct ib_umad_packet *timeout; + struct ib_umad_packet *packet = send_wc->send_buf->context[0]; - ib_destroy_ah(packet->msg->send_wr.wr.ud.ah); + ib_destroy_ah(packet->msg->ah); ib_free_send_mad(packet->msg); if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { @@ -268,11 +267,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, struct ib_umad_packet *packet; struct ib_mad_agent *agent; struct ib_ah_attr ah_attr; - struct ib_send_wr *bad_wr; + struct ib_ah *ah; struct ib_rmpp_mad *rmpp_mad; u8 method; __be64 *tid; - int ret, length, hdr_len, data_len, rmpp_hdr_size; + int ret, length, hdr_len, rmpp_hdr_size; int rmpp_active = 0; if (count < sizeof (struct ib_user_mad)) @@ -321,9 +320,9 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; } - packet->ah = ib_create_ah(agent->qp->pd, &ah_attr); - if (IS_ERR(packet->ah)) { - ret = PTR_ERR(packet->ah); + ah = ib_create_ah(agent->qp->pd, &ah_attr); + if (IS_ERR(ah)) { + ret = PTR_ERR(ah); goto err_up; } @@ -337,12 +336,10 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, /* Validate that the management class can support RMPP */ if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { - hdr_len = offsetof(struct ib_sa_mad, data); - data_len = length - hdr_len; + hdr_len = IB_MGMT_SA_HDR; } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) { - hdr_len = offsetof(struct ib_vendor_mad, data); - data_len = length - hdr_len; + hdr_len = IB_MGMT_VENDOR_HDR; } else { ret = -EINVAL; goto err_ah; @@ -353,25 +350,23 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, ret = -EINVAL; goto err_ah; } - hdr_len = offsetof(struct ib_mad, data); - data_len = length - hdr_len; + hdr_len = IB_MGMT_MAD_HDR; } packet->msg = ib_create_send_mad(agent, be32_to_cpu(packet->mad.hdr.qpn), - 0, packet->ah, rmpp_active, - hdr_len, data_len, + 0, rmpp_active, + hdr_len, length - hdr_len, GFP_KERNEL); if (IS_ERR(packet->msg)) { ret = PTR_ERR(packet->msg); goto err_ah; } - packet->msg->send_wr.wr.ud.timeout_ms = packet->mad.hdr.timeout_ms; - packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries; - - /* Override send WR WRID initialized in ib_create_send_mad */ - packet->msg->send_wr.wr_id = (unsigned long) packet; + packet->msg->ah = ah; + packet->msg->timeout_ms = packet->mad.hdr.timeout_ms; + packet->msg->retries = packet->mad.hdr.retries; + packet->msg->context[0] = packet; if (!rmpp_active) { /* Copy message from user into send buffer */ @@ -403,17 +398,17 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, * transaction ID matches the agent being used to send the * MAD. */ - method = packet->msg->mad->mad_hdr.method; + method = ((struct ib_mad_hdr *) packet->msg)->method; if (!(method & IB_MGMT_METHOD_RESP) && method != IB_MGMT_METHOD_TRAP_REPRESS && method != IB_MGMT_METHOD_SEND) { - tid = &packet->msg->mad->mad_hdr.tid; + tid = &((struct ib_mad_hdr *) packet->msg)->tid; *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | (be64_to_cpup(tid) & 0xffffffff)); } - ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr); + ret = ib_post_send_mad(packet->msg, NULL); if (ret) goto err_msg; @@ -425,7 +420,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, ib_free_send_mad(packet->msg); err_ah: - ib_destroy_ah(packet->ah); + ib_destroy_ah(ah); err_up: up_read(&file->agent_mutex); diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 9804174f7f3c..8561b297a19b 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c @@ -46,11 +46,6 @@ enum { MTHCA_VENDOR_CLASS2 = 0xa }; -struct mthca_trap_mad { - struct ib_mad *mad; - DECLARE_PCI_UNMAP_ADDR(mapping) -}; - static void update_sm_ah(struct mthca_dev *dev, u8 port_num, u16 lid, u8 sl) { @@ -116,49 +111,14 @@ static void forward_trap(struct mthca_dev *dev, struct ib_mad *mad) { int qpn = mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED; - struct mthca_trap_mad *tmad; - struct ib_sge gather_list; - struct ib_send_wr *bad_wr, wr = { - .opcode = IB_WR_SEND, - .sg_list = &gather_list, - .num_sge = 1, - .send_flags = IB_SEND_SIGNALED, - .wr = { - .ud = { - .remote_qpn = qpn, - .remote_qkey = qpn ? IB_QP1_QKEY : 0, - .timeout_ms = 0 - } - } - }; + struct ib_mad_send_buf *send_buf; struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; int ret; unsigned long flags; if (agent) { - tmad = kmalloc(sizeof *tmad, GFP_KERNEL); - if (!tmad) - return; - - tmad->mad = kmalloc(sizeof *tmad->mad, GFP_KERNEL); - if (!tmad->mad) { - kfree(tmad); - return; - } - - memcpy(tmad->mad, mad, sizeof *mad); - - wr.wr.ud.mad_hdr = &tmad->mad->mad_hdr; - wr.wr_id = (unsigned long) tmad; - - gather_list.addr = dma_map_single(agent->device->dma_device, - tmad->mad, - sizeof *tmad->mad, - DMA_TO_DEVICE); - gather_list.length = sizeof *tmad->mad; - gather_list.lkey = to_mpd(agent->qp->pd)->ntmr.ibmr.lkey; - pci_unmap_addr_set(tmad, mapping, gather_list.addr); - + send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, + IB_MGMT_MAD_DATA, GFP_ATOMIC); /* * We rely here on the fact that MLX QPs don't use the * address handle after the send is posted (this is @@ -166,21 +126,15 @@ static void forward_trap(struct mthca_dev *dev, * it's OK for our devices). */ spin_lock_irqsave(&dev->sm_lock, flags); - wr.wr.ud.ah = dev->sm_ah[port_num - 1]; - if (wr.wr.ud.ah) - ret = ib_post_send_mad(agent, &wr, &bad_wr); + memcpy(send_buf->mad, mad, sizeof *mad); + if ((send_buf->ah = dev->sm_ah[port_num - 1])) + ret = ib_post_send_mad(send_buf, NULL); else ret = -EINVAL; spin_unlock_irqrestore(&dev->sm_lock, flags); - if (ret) { - dma_unmap_single(agent->device->dma_device, - pci_unmap_addr(tmad, mapping), - sizeof *tmad->mad, - DMA_TO_DEVICE); - kfree(tmad->mad); - kfree(tmad); - } + if (ret) + ib_free_send_mad(send_buf); } } @@ -267,15 +221,7 @@ int mthca_process_mad(struct ib_device *ibdev, static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *mad_send_wc) { - struct mthca_trap_mad *tmad = - (void *) (unsigned long) mad_send_wc->wr_id; - - dma_unmap_single(agent->device->dma_device, - pci_unmap_addr(tmad, mapping), - sizeof *tmad->mad, - DMA_TO_DEVICE); - kfree(tmad->mad); - kfree(tmad); + ib_free_send_mad(mad_send_wc->send_buf); } int mthca_create_agents(struct mthca_dev *dev) diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 4172e6841e3d..2c133506742b 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -109,10 +109,14 @@ #define IB_QP_SET_QKEY 0x80000000 enum { + IB_MGMT_MAD_HDR = 24, IB_MGMT_MAD_DATA = 232, + IB_MGMT_RMPP_HDR = 36, IB_MGMT_RMPP_DATA = 220, + IB_MGMT_VENDOR_HDR = 40, IB_MGMT_VENDOR_DATA = 216, - IB_MGMT_SA_DATA = 200 + IB_MGMT_SA_HDR = 56, + IB_MGMT_SA_DATA = 200, }; struct ib_mad_hdr { @@ -203,26 +207,25 @@ struct ib_class_port_info /** * ib_mad_send_buf - MAD data buffer and work request for sends. - * @mad: References an allocated MAD data buffer. The size of the data - * buffer is specified in the @send_wr.length field. - * @mapping: DMA mapping information. + * @next: A pointer used to chain together MADs for posting. + * @mad: References an allocated MAD data buffer. * @mad_agent: MAD agent that allocated the buffer. + * @ah: The address handle to use when sending the MAD. * @context: User-controlled context fields. - * @send_wr: An initialized work request structure used when sending the MAD. - * The wr_id field of the work request is initialized to reference this - * data structure. - * @sge: A scatter-gather list referenced by the work request. + * @timeout_ms: Time to wait for a response. + * @retries: Number of times to retry a request for a response. * * Users are responsible for initializing the MAD buffer itself, with the * exception of specifying the payload length field in any RMPP MAD. */ struct ib_mad_send_buf { - struct ib_mad *mad; - DECLARE_PCI_UNMAP_ADDR(mapping) + struct ib_mad_send_buf *next; + void *mad; struct ib_mad_agent *mad_agent; + struct ib_ah *ah; void *context[2]; - struct ib_send_wr send_wr; - struct ib_sge sge; + int timeout_ms; + int retries; }; /** @@ -287,7 +290,7 @@ typedef void (*ib_mad_send_handler)(struct ib_mad_agent *mad_agent, * or @mad_send_wc. */ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent, - struct ib_send_wr *send_wr, + struct ib_mad_send_buf *send_buf, struct ib_mad_send_wc *mad_send_wc); /** @@ -334,13 +337,13 @@ struct ib_mad_agent { /** * ib_mad_send_wc - MAD send completion information. - * @wr_id: Work request identifier associated with the send MAD request. + * @send_buf: Send MAD data buffer associated with the send MAD request. * @status: Completion status. * @vendor_err: Optional vendor error information returned with a failed * request. */ struct ib_mad_send_wc { - u64 wr_id; + struct ib_mad_send_buf *send_buf; enum ib_wc_status status; u32 vendor_err; }; @@ -366,7 +369,7 @@ struct ib_mad_recv_buf { * @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers. * @mad_len: The length of the received MAD, without duplicated headers. * - * For received response, the wr_id field of the wc is set to the wr_id + * For received response, the wr_id contains a pointer to the ib_mad_send_buf * for the corresponding send request. */ struct ib_mad_recv_wc { @@ -463,9 +466,9 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent); /** * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated * with the registered client. - * @mad_agent: Specifies the associated registration to post the send to. - * @send_wr: Specifies the information needed to send the MAD(s). - * @bad_send_wr: Specifies the MAD on which an error was encountered. + * @send_buf: Specifies the information needed to send the MAD(s). + * @bad_send_buf: Specifies the MAD on which an error was encountered. This + * parameter is optional if only a single MAD is posted. * * Sent MADs are not guaranteed to complete in the order that they were posted. * @@ -479,9 +482,8 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent); * defined data being transferred. The paylen_newwin field should be * specified in network-byte order. */ -int ib_post_send_mad(struct ib_mad_agent *mad_agent, - struct ib_send_wr *send_wr, - struct ib_send_wr **bad_send_wr); +int ib_post_send_mad(struct ib_mad_send_buf *send_buf, + struct ib_mad_send_buf **bad_send_buf); /** * ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer. @@ -507,23 +509,25 @@ void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc); /** * ib_cancel_mad - Cancels an outstanding send MAD operation. * @mad_agent: Specifies the registration associated with sent MAD. - * @wr_id: Indicates the work request identifier of the MAD to cancel. + * @send_buf: Indicates the MAD to cancel. * * MADs will be returned to the user through the corresponding * ib_mad_send_handler. */ -void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id); +void ib_cancel_mad(struct ib_mad_agent *mad_agent, + struct ib_mad_send_buf *send_buf); /** * ib_modify_mad - Modifies an outstanding send MAD operation. * @mad_agent: Specifies the registration associated with sent MAD. - * @wr_id: Indicates the work request identifier of the MAD to modify. + * @send_buf: Indicates the MAD to modify. * @timeout_ms: New timeout value for sent MAD. * * This call will reset the timeout value for a sent MAD to the specified * value. */ -int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms); +int ib_modify_mad(struct ib_mad_agent *mad_agent, + struct ib_mad_send_buf *send_buf, u32 timeout_ms); /** * ib_redirect_mad_qp - Registers a QP for MAD services. @@ -572,7 +576,6 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent, * @remote_qpn: Specifies the QPN of the receiving node. * @pkey_index: Specifies which PKey the MAD will be sent using. This field * is valid only if the remote_qpn is QP 1. - * @ah: References the address handle used to transfer to the remote node. * @rmpp_active: Indicates if the send will enable RMPP. * @hdr_len: Indicates the size of the data header of the MAD. This length * should include the common MAD header, RMPP header, plus any class @@ -582,11 +585,10 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent, * additional padding that may be necessary. * @gfp_mask: GFP mask used for the memory allocation. * - * This is a helper routine that may be used to allocate a MAD. Users are - * not required to allocate outbound MADs using this call. The returned - * MAD send buffer will reference a data buffer usable for sending a MAD, along + * This routine allocates a MAD for sending. The returned MAD send buffer + * will reference a data buffer usable for sending a MAD, along * with an initialized work request structure. Users may modify the returned - * MAD data buffer or work request before posting the send. + * MAD data buffer before posting the send. * * The returned data buffer will be cleared. Users are responsible for * initializing the common MAD and any class specific headers. If @rmpp_active @@ -594,7 +596,7 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent, */ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, u32 remote_qpn, u16 pkey_index, - struct ib_ah *ah, int rmpp_active, + int rmpp_active, int hdr_len, int data_len, gfp_t gfp_mask); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index a5a963cb5676..f72d46d54e0a 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -595,11 +595,8 @@ struct ib_send_wr { } atomic; struct { struct ib_ah *ah; - struct ib_mad_hdr *mad_hdr; u32 remote_qpn; u32 remote_qkey; - int timeout_ms; /* valid for MADs only */ - int retries; /* valid for MADs only */ u16 pkey_index; /* valid for GSI only */ u8 port_num; /* valid for DR SMPs on switch only */ } ud; From 547e3090738b04be650770b64265835dbb6ddf92 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 25 Oct 2005 10:57:32 -0700 Subject: [PATCH 0453/1940] [IB] mthca: correct modify QP attribute masks for UC The UC transport does not support RDMA reads or atomic operations, so we shouldn't require or even allow the consumer to set attributes relating to these operations for UC QPs. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_qp.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 2ee0a2b0fd4b..62ff091505da 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -338,8 +338,7 @@ static const struct { [UC] = (IB_QP_AV | IB_QP_PATH_MTU | IB_QP_DEST_QPN | - IB_QP_RQ_PSN | - IB_QP_MAX_DEST_RD_ATOMIC), + IB_QP_RQ_PSN), [RC] = (IB_QP_AV | IB_QP_PATH_MTU | IB_QP_DEST_QPN | @@ -368,8 +367,7 @@ static const struct { .trans = MTHCA_TRANS_RTR2RTS, .req_param = { [UD] = IB_QP_SQ_PSN, - [UC] = (IB_QP_SQ_PSN | - IB_QP_MAX_QP_RD_ATOMIC), + [UC] = IB_QP_SQ_PSN, [RC] = (IB_QP_TIMEOUT | IB_QP_RETRY_CNT | IB_QP_RNR_RETRY | @@ -446,8 +444,6 @@ static const struct { [UD] = (IB_QP_PKEY_INDEX | IB_QP_QKEY), [UC] = (IB_QP_AV | - IB_QP_MAX_QP_RD_ATOMIC | - IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_CUR_STATE | IB_QP_ALT_PATH | IB_QP_ACCESS_FLAGS | @@ -478,7 +474,7 @@ static const struct { .opt_param = { [UD] = (IB_QP_CUR_STATE | IB_QP_QKEY), - [UC] = (IB_QP_CUR_STATE), + [UC] = IB_QP_CUR_STATE, [RC] = (IB_QP_CUR_STATE | IB_QP_MIN_RNR_TIMER), [MLX] = (IB_QP_CUR_STATE | From b6a7e1ecef66b9ecd1eed31f46ba0248d6d7e957 Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Thu, 20 Oct 2005 12:31:19 +1000 Subject: [PATCH 0454/1940] [IA64] Allow simulator to use bigger disks The simscsi code at present overflows an int if it's given a large disk image. The attached patch increases the possible size to 128G. While it's unlikely that anyone will want to use SKI with such a large drive, the same framework is currently being used for various virtualisation experiments. Signed-off-by: Peter Chubb Signed-off-by: Tony Luck --- arch/ia64/hp/sim/simscsi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index a18983a3c934..a3fe97531134 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -205,10 +205,11 @@ simscsi_get_disk_size (int fd) char buf[512]; /* - * This is a bit kludgey: the simulator doesn't provide a direct way of determining - * the disk size, so we do a binary search, assuming a maximum disk size of 4GB. + * This is a bit kludgey: the simulator doesn't provide a + * direct way of determining the disk size, so we do a binary + * search, assuming a maximum disk size of 128GB. */ - for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) { + for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) { req.addr = __pa(&buf); req.len = sizeof(buf); ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ); @@ -225,8 +226,10 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) { unsigned long offset; - offset = ( (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16) - | (sc->cmnd[4] << 8) | (sc->cmnd[5] << 0))*512; + offset = (((unsigned long)sc->cmnd[2] << 24) + | ((unsigned long)sc->cmnd[3] << 16) + | ((unsigned long)sc->cmnd[4] << 8) + | ((unsigned long)sc->cmnd[5] << 0))*512UL; if (sc->use_sg > 0) simscsi_sg_readwrite(sc, mode, offset); else From ce6e71ad4866dad366be135b024b776c00ec9ec8 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Tue, 4 Oct 2005 16:35:31 -0700 Subject: [PATCH 0455/1940] [IA64] fix siblings field value in /proc/cpuinfo Fix the "siblings" field value in /proc/cpuinfo so that it now shows the number of siblings as seen by OS, instead of what is available from hardware perspective. Signed-off-by: Suresh Siddha Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 1f5c26dbe705..0ca6ef103952 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -526,7 +526,7 @@ show_cpuinfo (struct seq_file *m, void *v) c->itc_freq / 1000000, c->itc_freq % 1000000, lpj*HZ/500000, (lpj*HZ/5000) % 100); #ifdef CONFIG_SMP - seq_printf(m, "siblings : %u\n", c->num_log); + seq_printf(m, "siblings : %u\n", cpus_weight(cpu_core_map[cpunum])); if (c->threads_per_core > 1 || c->cores_per_socket > 1) seq_printf(m, "physical id: %u\n" From 9c184a073bfd650cc791956d6ca79725bb682716 Mon Sep 17 00:00:00 2001 From: "H. J. Lu" Date: Fri, 7 Oct 2005 11:01:19 -0700 Subject: [PATCH 0456/1940] [IA64] Fix 2.6 kernel for the new ia64 assembler The new ia64 assembler uses slot 1 for the offset of a long (2-slot) instruction and the old assembler uses slot 2. The 2.6 kernel assumes slot 2 and won't boot when the new assembler is used: http://sources.redhat.com/bugzilla/show_bug.cgi?id=1433 This patch will work with either slot 1 or 2. Patch provided by H.J. Lu Signed-off-by: Tony Luck --- arch/ia64/kernel/patch.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index 367804a605fa..6a4ac7d70b35 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c @@ -64,22 +64,30 @@ ia64_patch (u64 insn_addr, u64 mask, u64 val) void ia64_patch_imm64 (u64 insn_addr, u64 val) { - ia64_patch(insn_addr, + /* The assembler may generate offset pointing to either slot 1 + or slot 2 for a long (2-slot) instruction, occupying slots 1 + and 2. */ + insn_addr &= -16UL; + ia64_patch(insn_addr + 2, 0x01fffefe000UL, ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */ | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */ | ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */ | ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */ | ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */)); - ia64_patch(insn_addr - 1, 0x1ffffffffffUL, val >> 22); + ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22); } void ia64_patch_imm60 (u64 insn_addr, u64 val) { - ia64_patch(insn_addr, + /* The assembler may generate offset pointing to either slot 1 + or slot 2 for a long (2-slot) instruction, occupying slots 1 + and 2. */ + insn_addr &= -16UL; + ia64_patch(insn_addr + 2, 0x011ffffe000UL, ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */ | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */)); - ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18); + ia64_patch(insn_addr + 1, 0x1fffffffffcUL, val >> 18); } /* From dc565b525d4b7091a3abb6616d210c8a896a11d7 Mon Sep 17 00:00:00 2001 From: "hawkes@sgi.com" Date: Mon, 10 Oct 2005 08:43:26 -0700 Subject: [PATCH 0457/1940] [IA64] wider use of for_each_cpu_mask() in arch/ia64 In arch/ia64 change the explicit use of for-loops and NR_CPUS into the general for_each_cpu() or for_each_online_cpu() constructs, as appropriate. This widens the scope of potential future optimizations of the general constructs, as well as takes advantage of the existing optimizations of first_cpu() and next_cpu(). Signed-off-by: John Hawkes Signed-off-by: Tony Luck --- arch/ia64/kernel/irq.c | 12 ++++++------ arch/ia64/kernel/module.c | 6 +++--- arch/ia64/kernel/smp.c | 10 +++++----- arch/ia64/kernel/smpboot.c | 6 +++--- arch/ia64/mm/tlb.c | 5 +++-- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 205d98028261..d33244c32759 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -57,9 +57,9 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); - for (j=0; jtypename); seq_printf(p, " %s", action->name); diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index f1aca7cffd12..7a2f0a798d12 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -947,8 +947,8 @@ void percpu_modcopy (void *pcpudst, const void *src, unsigned long size) { unsigned int i; - for (i = 0; i < NR_CPUS; i++) - if (cpu_possible(i)) - memcpy(pcpudst + __per_cpu_offset[i], src, size); + for_each_cpu(i) { + memcpy(pcpudst + __per_cpu_offset[i], src, size); + } } #endif /* CONFIG_SMP */ diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 0166a9847095..657ac99a451c 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -185,8 +185,8 @@ send_IPI_allbutself (int op) { unsigned int i; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_online(i) && i != smp_processor_id()) + for_each_online_cpu(i) { + if (i != smp_processor_id()) send_IPI_single(i, op); } } @@ -199,9 +199,9 @@ send_IPI_all (int op) { int i; - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - send_IPI_single(i, op); + for_each_online_cpu(i) { + send_IPI_single(i, op); + } } /* diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 7d72c0d872b3..400a48987124 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -694,9 +694,9 @@ smp_cpus_done (unsigned int dummy) * Allow the user to impress friends. */ - for (cpu = 0; cpu < NR_CPUS; cpu++) - if (cpu_online(cpu)) - bogosum += cpu_data(cpu)->loops_per_jiffy; + for_each_online_cpu(cpu) { + bogosum += cpu_data(cpu)->loops_per_jiffy; + } printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 464557e4ed82..987fb754d6ad 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -77,9 +77,10 @@ wrap_mmu_context (struct mm_struct *mm) /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */ { int cpu = get_cpu(); /* prevent preemption/migration */ - for (i = 0; i < NR_CPUS; ++i) - if (cpu_online(i) && (i != cpu)) + for_each_online_cpu(i) { + if (i != cpu) per_cpu(ia64_need_tlb_flush, i) = 1; + } put_cpu(); } local_flush_tlb_all(); From ddf6d0a00cbb4ad6d4fb4200cc911bb9389174c1 Mon Sep 17 00:00:00 2001 From: "hawkes@sgi.com" Date: Thu, 13 Oct 2005 12:01:18 -0700 Subject: [PATCH 0458/1940] [IA64] another place to use for_each_cpu_mask() in arch/ia64 In arch/ia64 change the explicit use of a for-loop using NR_CPUS into the general for_each_online_cpu() construct. This widens the scope of potential future optimizations of the general constructs, as well as takes advantage of the existing optimizations of first_cpu() and next_cpu(), which is advantageous when the true CPU count is much smaller than NR_CPUS. Signed-off-by: John Hawkes Signed-off-by: Tony Luck --- arch/ia64/kernel/mca.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index d0a5106fba24..52c47da17246 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -508,9 +508,7 @@ ia64_mca_wakeup_all(void) int cpu; /* Clear the Rendez checkin flag for all cpus */ - for(cpu = 0; cpu < NR_CPUS; cpu++) { - if (!cpu_online(cpu)) - continue; + for_each_online_cpu(cpu) { if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE) ia64_mca_wakeup(cpu); } From 7cc656efb560cda66b5ed48444cad7556ea4fe99 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 25 Oct 2005 15:13:54 -0700 Subject: [PATCH 0459/1940] [IB] simplify mad_rmpp.c:alloc_response_msg() Change alloc_response_msg() in mad_rmpp.c to return the struct it allocates directly (or an error code a la ERR_PTR), rather than returning a status and passing the struct back in a pointer param. This simplifies the code and gets rid of warnings like drivers/infiniband/core/mad_rmpp.c: In function nack_recv: drivers/infiniband/core/mad_rmpp.c:192: warning: msg may be used uninitialized in this function with newer versions of gcc. Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad_rmpp.c | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index ba112cd5f93c..3249e1d8c07b 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -151,28 +151,27 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, ib_free_send_mad(msg); } -static int alloc_response_msg(struct ib_mad_agent *agent, - struct ib_mad_recv_wc *recv_wc, - struct ib_mad_send_buf **msg) +static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, + struct ib_mad_recv_wc *recv_wc) { - struct ib_mad_send_buf *m; + struct ib_mad_send_buf *msg; struct ib_ah *ah; ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, recv_wc->recv_buf.grh, agent->port_num); if (IS_ERR(ah)) - return PTR_ERR(ah); + return (void *) ah; - m = ib_create_send_mad(agent, recv_wc->wc->src_qp, - recv_wc->wc->pkey_index, 1, - IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA, GFP_KERNEL); - if (IS_ERR(m)) { + msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, + recv_wc->wc->pkey_index, 1, + IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA, + GFP_KERNEL); + if (IS_ERR(msg)) ib_destroy_ah(ah); - return PTR_ERR(m); - } - m->ah = ah; - *msg = m; - return 0; + else + msg->ah = ah; + + return msg; } void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) @@ -191,8 +190,8 @@ static void nack_recv(struct ib_mad_agent_private *agent, struct ib_rmpp_mad *rmpp_mad; int ret; - ret = alloc_response_msg(&agent->agent, recv_wc, &msg); - if (ret) + msg = alloc_response_msg(&agent->agent, recv_wc); + if (IS_ERR(msg)) return; rmpp_mad = msg->mad; From e54af724c1ae3530c95135157776c9be65cdb747 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 25 Oct 2005 14:07:43 -0500 Subject: [PATCH 0460/1940] [IA64-SGI] fixes for XPC disengage and open/close protocol This patch addresses a few issues with the open/close protocol that were revealed by the newly added disengage functionality combined with more extensive testing. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/xpc.h | 21 ++-- arch/ia64/sn/kernel/xpc_channel.c | 117 ++++++++++++++------- arch/ia64/sn/kernel/xpc_main.c | 152 ++++++++++++++++++++-------- arch/ia64/sn/kernel/xpc_partition.c | 8 +- include/asm-ia64/sn/xp.h | 6 +- 5 files changed, 211 insertions(+), 93 deletions(-) diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index 565822ab3d08..ae51d7b4c42e 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h @@ -417,6 +417,9 @@ struct xpc_channel { atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */ wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */ + u8 delayed_IPI_flags; /* IPI flags received, but delayed */ + /* action until channel disconnected */ + /* queue of msg senders who want to be notified when msg received */ atomic_t n_to_notify; /* #of msg senders to notify */ @@ -478,7 +481,8 @@ struct xpc_channel { #define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ #define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ -#define XPC_C_WDISCONNECT 0x00008000 /* waiting for channel disconnect */ +#define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */ +#define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */ @@ -508,13 +512,13 @@ struct xpc_partition { int reason_line; /* line# deactivation initiated from */ int reactivate_nasid; /* nasid in partition to reactivate */ - unsigned long disengage_request_timeout; /* timeout in XPC_TICKS */ + unsigned long disengage_request_timeout; /* timeout in jiffies */ struct timer_list disengage_request_timer; /* XPC infrastructure referencing and teardown control */ - volatile u8 setup_state; /* infrastructure setup state */ + volatile u8 setup_state; /* infrastructure setup state */ wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ atomic_t references; /* #of references to infrastructure */ @@ -604,7 +608,7 @@ struct xpc_partition { /* number of seconds to wait for other partitions to disengage */ -#define XPC_DISENGAGE_REQUEST_TIMELIMIT 90 +#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90 /* interval in seconds to print 'waiting disengagement' messages */ #define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 @@ -618,20 +622,18 @@ struct xpc_partition { extern struct xpc_registration xpc_registrations[]; -/* >>> found in xpc_main.c only */ +/* found in xpc_main.c */ extern struct device *xpc_part; extern struct device *xpc_chan; +extern int xpc_disengage_request_timelimit; extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); extern void xpc_dropped_IPI_check(struct xpc_partition *); +extern void xpc_activate_partition(struct xpc_partition *); extern void xpc_activate_kthreads(struct xpc_channel *, int); extern void xpc_create_kthreads(struct xpc_channel *, int); extern void xpc_disconnect_wait(int); -/* found in xpc_main.c and efi-xpc.c */ -extern void xpc_activate_partition(struct xpc_partition *); - - /* found in xpc_partition.c */ extern int xpc_exiting; extern struct xpc_vars *xpc_vars; @@ -1077,6 +1079,7 @@ xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, /* given an AMO variable and a channel#, get its associated IPI flags */ #define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) +#define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8)) #define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f) #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010) diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 195ac1b8e262..abf4fc2a87bb 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c @@ -792,11 +792,20 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) "reason=%d\n", ch->number, ch->partid, ch->reason); } - /* wake the thread that is waiting for this channel to disconnect */ if (ch->flags & XPC_C_WDISCONNECT) { spin_unlock_irqrestore(&ch->lock, *irq_flags); up(&ch->wdisconnect_sema); spin_lock_irqsave(&ch->lock, *irq_flags); + + } else if (ch->delayed_IPI_flags) { + if (part->act_state != XPC_P_DEACTIVATING) { + /* time to take action on any delayed IPI flags */ + spin_lock(&part->IPI_lock); + XPC_SET_IPI_FLAGS(part->local_IPI_amo, ch->number, + ch->delayed_IPI_flags); + spin_unlock(&part->IPI_lock); + } + ch->delayed_IPI_flags = 0; } } @@ -818,6 +827,19 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, spin_lock_irqsave(&ch->lock, irq_flags); +again: + + if ((ch->flags & XPC_C_DISCONNECTED) && + (ch->flags & XPC_C_WDISCONNECT)) { + /* + * Delay processing IPI flags until thread waiting disconnect + * has had a chance to see that the channel is disconnected. + */ + ch->delayed_IPI_flags |= IPI_flags; + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; + } + if (IPI_flags & XPC_IPI_CLOSEREQUEST) { @@ -843,14 +865,22 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, /* both sides have finished disconnecting */ xpc_process_disconnect(ch, &irq_flags); + DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); + goto again; } if (ch->flags & XPC_C_DISCONNECTED) { - // >>> explain this section - if (!(IPI_flags & XPC_IPI_OPENREQUEST)) { - DBUG_ON(part->act_state != - XPC_P_DEACTIVATING); + if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, + ch_number) & XPC_IPI_OPENREQUEST)) { + + DBUG_ON(ch->delayed_IPI_flags != 0); + spin_lock(&part->IPI_lock); + XPC_SET_IPI_FLAGS(part->local_IPI_amo, + ch_number, + XPC_IPI_CLOSEREQUEST); + spin_unlock(&part->IPI_lock); + } spin_unlock_irqrestore(&ch->lock, irq_flags); return; } @@ -880,9 +910,13 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, } XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); - } else { - xpc_process_disconnect(ch, &irq_flags); + + DBUG_ON(IPI_flags & XPC_IPI_CLOSEREPLY); + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; } + + xpc_process_disconnect(ch, &irq_flags); } @@ -898,7 +932,20 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, } DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); - DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST)); + + if (!(ch->flags & XPC_C_RCLOSEREQUEST)) { + if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, ch_number) + & XPC_IPI_CLOSEREQUEST)) { + + DBUG_ON(ch->delayed_IPI_flags != 0); + spin_lock(&part->IPI_lock); + XPC_SET_IPI_FLAGS(part->local_IPI_amo, + ch_number, XPC_IPI_CLOSEREPLY); + spin_unlock(&part->IPI_lock); + } + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; + } ch->flags |= XPC_C_RCLOSEREPLY; @@ -916,8 +963,14 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, "channel=%d\n", args->msg_size, args->local_nentries, ch->partid, ch->number); - if ((ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) || - part->act_state == XPC_P_DEACTIVATING) { + if (part->act_state == XPC_P_DEACTIVATING || + (ch->flags & XPC_C_ROPENREQUEST)) { + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; + } + + if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { + ch->delayed_IPI_flags |= XPC_IPI_OPENREQUEST; spin_unlock_irqrestore(&ch->lock, irq_flags); return; } @@ -931,8 +984,11 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, * msg_size = size of channel's messages in bytes * local_nentries = remote partition's local_nentries */ - DBUG_ON(args->msg_size == 0); - DBUG_ON(args->local_nentries == 0); + if (args->msg_size == 0 || args->local_nentries == 0) { + /* assume OPENREQUEST was delayed by mistake */ + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; + } ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); ch->remote_nentries = args->local_nentries; @@ -970,7 +1026,13 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, spin_unlock_irqrestore(&ch->lock, irq_flags); return; } - DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST)); + if (!(ch->flags & XPC_C_OPENREQUEST)) { + XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError, + &irq_flags); + spin_unlock_irqrestore(&ch->lock, irq_flags); + return; + } + DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); DBUG_ON(ch->flags & XPC_C_CONNECTED); @@ -1024,8 +1086,8 @@ xpc_connect_channel(struct xpc_channel *ch) struct xpc_registration *registration = &xpc_registrations[ch->number]; - if (down_interruptible(®istration->sema) != 0) { - return xpcInterrupted; + if (down_trylock(®istration->sema) != 0) { + return xpcRetry; } if (!XPC_CHANNEL_REGISTERED(ch->number)) { @@ -1445,19 +1507,11 @@ xpc_initiate_connect(int ch_number) if (xpc_part_ref(part)) { ch = &part->channels[ch_number]; - if (!(ch->flags & XPC_C_DISCONNECTING)) { - DBUG_ON(ch->flags & XPC_C_OPENREQUEST); - DBUG_ON(ch->flags & XPC_C_CONNECTED); - DBUG_ON(ch->flags & XPC_C_SETUP); - - /* - * Initiate the establishment of a connection - * on the newly registered channel to the - * remote partition. - */ - xpc_wakeup_channel_mgr(part); - } - + /* + * Initiate the establishment of a connection on the + * newly registered channel to the remote partition. + */ + xpc_wakeup_channel_mgr(part); xpc_part_deref(part); } } @@ -1467,9 +1521,6 @@ xpc_initiate_connect(int ch_number) void xpc_connected_callout(struct xpc_channel *ch) { - unsigned long irq_flags; - - /* let the registerer know that a connection has been established */ if (ch->func != NULL) { @@ -1482,10 +1533,6 @@ xpc_connected_callout(struct xpc_channel *ch) dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, " "partid=%d, channel=%d\n", ch->partid, ch->number); } - - spin_lock_irqsave(&ch->lock, irq_flags); - ch->flags |= XPC_C_CONNECTCALLOUT; - spin_unlock_irqrestore(&ch->lock, irq_flags); } diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index feece200b3c3..db349c6d4c58 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -91,6 +91,10 @@ static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL; static int xpc_hb_check_min_interval = 10; static int xpc_hb_check_max_interval = 120; +int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT; +static int xpc_disengage_request_min_timelimit = 0; +static int xpc_disengage_request_max_timelimit = 120; + static ctl_table xpc_sys_xpc_hb_dir[] = { { 1, @@ -129,6 +133,19 @@ static ctl_table xpc_sys_xpc_dir[] = { 0555, xpc_sys_xpc_hb_dir }, + { + 2, + "disengage_request_timelimit", + &xpc_disengage_request_timelimit, + sizeof(int), + 0644, + NULL, + &proc_dointvec_minmax, + &sysctl_intvec, + NULL, + &xpc_disengage_request_min_timelimit, + &xpc_disengage_request_max_timelimit + }, {0} }; static ctl_table xpc_sys_dir[] = { @@ -153,11 +170,11 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); static unsigned long xpc_hb_check_timeout; -/* used as an indication of when the xpc_hb_checker thread is inactive */ -static DECLARE_MUTEX_LOCKED(xpc_hb_checker_inactive); +/* notification that the xpc_hb_checker thread has exited */ +static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); -/* used as an indication of when the xpc_discovery thread is inactive */ -static DECLARE_MUTEX_LOCKED(xpc_discovery_inactive); +/* notification that the xpc_discovery thread has exited */ +static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); static struct timer_list xpc_hb_timer; @@ -181,7 +198,7 @@ xpc_timeout_partition_disengage_request(unsigned long data) struct xpc_partition *part = (struct xpc_partition *) data; - DBUG_ON(XPC_TICKS < part->disengage_request_timeout); + DBUG_ON(jiffies < part->disengage_request_timeout); (void) xpc_partition_disengaged(part); @@ -292,8 +309,8 @@ xpc_hb_checker(void *ignore) dev_dbg(xpc_part, "heartbeat checker is exiting\n"); - /* mark this thread as inactive */ - up(&xpc_hb_checker_inactive); + /* mark this thread as having exited */ + up(&xpc_hb_checker_exited); return 0; } @@ -312,8 +329,8 @@ xpc_initiate_discovery(void *ignore) dev_dbg(xpc_part, "discovery thread is exiting\n"); - /* mark this thread as inactive */ - up(&xpc_discovery_inactive); + /* mark this thread as having exited */ + up(&xpc_discovery_exited); return 0; } @@ -703,6 +720,7 @@ xpc_daemonize_kthread(void *args) struct xpc_partition *part = &xpc_partitions[partid]; struct xpc_channel *ch; int n_needed; + unsigned long irq_flags; daemonize("xpc%02dc%d", partid, ch_number); @@ -713,11 +731,14 @@ xpc_daemonize_kthread(void *args) ch = &part->channels[ch_number]; if (!(ch->flags & XPC_C_DISCONNECTING)) { - DBUG_ON(!(ch->flags & XPC_C_CONNECTED)); /* let registerer know that connection has been established */ - if (atomic_read(&ch->kthreads_assigned) == 1) { + spin_lock_irqsave(&ch->lock, irq_flags); + if (!(ch->flags & XPC_C_CONNECTCALLOUT)) { + ch->flags |= XPC_C_CONNECTCALLOUT; + spin_unlock_irqrestore(&ch->lock, irq_flags); + xpc_connected_callout(ch); /* @@ -732,14 +753,23 @@ xpc_daemonize_kthread(void *args) !(ch->flags & XPC_C_DISCONNECTING)) { xpc_activate_kthreads(ch, n_needed); } + } else { + spin_unlock_irqrestore(&ch->lock, irq_flags); } xpc_kthread_waitmsgs(part, ch); } if (atomic_dec_return(&ch->kthreads_assigned) == 0) { - if (ch->flags & XPC_C_CONNECTCALLOUT) { + spin_lock_irqsave(&ch->lock, irq_flags); + if ((ch->flags & XPC_C_CONNECTCALLOUT) && + !(ch->flags & XPC_C_DISCONNECTCALLOUT)) { + ch->flags |= XPC_C_DISCONNECTCALLOUT; + spin_unlock_irqrestore(&ch->lock, irq_flags); + xpc_disconnecting_callout(ch); + } else { + spin_unlock_irqrestore(&ch->lock, irq_flags); } if (atomic_dec_return(&part->nchannels_engaged) == 0) { xpc_mark_partition_disengaged(part); @@ -780,9 +810,29 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed) while (needed-- > 0) { + + /* + * The following is done on behalf of the newly created + * kthread. That kthread is responsible for doing the + * counterpart to the following before it exits. + */ + (void) xpc_part_ref(part); + xpc_msgqueue_ref(ch); + if (atomic_inc_return(&ch->kthreads_assigned) == 1 && + atomic_inc_return(&part->nchannels_engaged) == 1) { + xpc_mark_partition_engaged(part); + } + pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0); if (pid < 0) { /* the fork failed */ + if (atomic_dec_return(&ch->kthreads_assigned) == 0 && + atomic_dec_return(&part->nchannels_engaged) == 0) { + xpc_mark_partition_disengaged(part); + xpc_IPI_send_disengage(part); + } + xpc_msgqueue_deref(ch); + xpc_part_deref(part); if (atomic_read(&ch->kthreads_assigned) < ch->kthreads_idle_limit) { @@ -802,18 +852,6 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed) break; } - /* - * The following is done on behalf of the newly created - * kthread. That kthread is responsible for doing the - * counterpart to the following before it exits. - */ - (void) xpc_part_ref(part); - xpc_msgqueue_ref(ch); - if (atomic_inc_return(&ch->kthreads_assigned) == 1) { - if (atomic_inc_return(&part->nchannels_engaged) == 1) { - xpc_mark_partition_engaged(part); - } - } ch->kthreads_created++; // >>> temporary debug only!!! } } @@ -826,26 +864,49 @@ xpc_disconnect_wait(int ch_number) partid_t partid; struct xpc_partition *part; struct xpc_channel *ch; + int wakeup_channel_mgr; /* now wait for all callouts to the caller's function to cease */ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; - if (xpc_part_ref(part)) { - ch = &part->channels[ch_number]; - - if (ch->flags & XPC_C_WDISCONNECT) { - if (!(ch->flags & XPC_C_DISCONNECTED)) { - (void) down(&ch->wdisconnect_sema); - } - spin_lock_irqsave(&ch->lock, irq_flags); - ch->flags &= ~XPC_C_WDISCONNECT; - spin_unlock_irqrestore(&ch->lock, irq_flags); - } - - xpc_part_deref(part); + if (!xpc_part_ref(part)) { + continue; } + + ch = &part->channels[ch_number]; + + if (!(ch->flags & XPC_C_WDISCONNECT)) { + xpc_part_deref(part); + continue; + } + + (void) down(&ch->wdisconnect_sema); + + spin_lock_irqsave(&ch->lock, irq_flags); + DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); + wakeup_channel_mgr = 0; + + if (ch->delayed_IPI_flags) { + if (part->act_state != XPC_P_DEACTIVATING) { + spin_lock(&part->IPI_lock); + XPC_SET_IPI_FLAGS(part->local_IPI_amo, + ch->number, ch->delayed_IPI_flags); + spin_unlock(&part->IPI_lock); + wakeup_channel_mgr = 1; + } + ch->delayed_IPI_flags = 0; + } + + ch->flags &= ~XPC_C_WDISCONNECT; + spin_unlock_irqrestore(&ch->lock, irq_flags); + + if (wakeup_channel_mgr) { + xpc_wakeup_channel_mgr(part); + } + + xpc_part_deref(part); } } @@ -873,11 +934,11 @@ xpc_do_exit(enum xpc_retval reason) /* ignore all incoming interrupts */ free_irq(SGI_XPC_ACTIVATE, NULL); - /* wait for the discovery thread to mark itself inactive */ - down(&xpc_discovery_inactive); + /* wait for the discovery thread to exit */ + down(&xpc_discovery_exited); - /* wait for the heartbeat checker thread to mark itself inactive */ - down(&xpc_hb_checker_inactive); + /* wait for the heartbeat checker thread to exit */ + down(&xpc_hb_checker_exited); /* sleep for a 1/3 of a second or so */ @@ -893,6 +954,7 @@ xpc_do_exit(enum xpc_retval reason) for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; + if (xpc_partition_disengaged(part) && part->act_state == XPC_P_INACTIVE) { continue; @@ -930,7 +992,7 @@ xpc_do_exit(enum xpc_retval reason) /* now it's time to eliminate our heartbeat */ del_timer_sync(&xpc_hb_timer); - DBUG_ON(xpc_vars->heartbeating_to_mask == 0); + DBUG_ON(xpc_vars->heartbeating_to_mask != 0); /* take ourselves off of the reboot_notifier_list */ (void) unregister_reboot_notifier(&xpc_reboot_notifier); @@ -1134,7 +1196,7 @@ xpc_init(void) dev_err(xpc_part, "failed while forking discovery thread\n"); /* mark this new thread as a non-starter */ - up(&xpc_discovery_inactive); + up(&xpc_discovery_exited); xpc_do_exit(xpcUnloading); return -EBUSY; @@ -1172,3 +1234,7 @@ module_param(xpc_hb_check_interval, int, 0); MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between " "heartbeat checks."); +module_param(xpc_disengage_request_timelimit, int, 0); +MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " + "for disengage request to complete."); + diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 79a0fc4c860c..958488f55699 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -578,7 +578,7 @@ xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version, /* - * Prior code has determine the nasid which generated an IPI. Inspect + * Prior code has determined the nasid which generated an IPI. Inspect * that nasid to determine if its partition needs to be activated or * deactivated. * @@ -942,14 +942,14 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, /* set a timelimit on the disengage request */ part->disengage_request_timeout = jiffies + - (XPC_DISENGAGE_REQUEST_TIMELIMIT * HZ); + (xpc_disengage_request_timelimit * HZ); part->disengage_request_timer.expires = part->disengage_request_timeout; add_timer(&part->disengage_request_timer); } - dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid, - reason); + dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", + XPC_PARTID(part), reason); xpc_partition_going_down(part, reason); } diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index f3052a54932b..30312be31206 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h @@ -225,7 +225,9 @@ enum xpc_retval { xpcDisconnecting, /* 49: channel disconnecting (closing) */ - xpcUnknownReason /* 50: unknown reason -- must be last in list */ + xpcOpenCloseError, /* 50: channel open/close protocol error */ + + xpcUnknownReason /* 51: unknown reason -- must be last in list */ }; @@ -350,7 +352,7 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid, * * The 'func' field points to the function to call when aynchronous * notification is required for such events as: a connection established/lost, - * or an incomming message received, or an error condition encountered. A + * or an incoming message received, or an error condition encountered. A * non-NULL 'func' field indicates that there is an active registration for * the channel. */ From 4b38fcd4858204cb3667eb7b3aca48ffb1002f05 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 25 Oct 2005 14:09:51 -0500 Subject: [PATCH 0461/1940] [IA64-SGI] XPC changes to support more than 2k nasids XPC needs to be changed to support up to 16k nasids on an SGI Altix system. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/xpc.h | 77 +++++++++++---- arch/ia64/sn/kernel/xpc_main.c | 8 +- arch/ia64/sn/kernel/xpc_partition.c | 140 ++++++++++++++++------------ 3 files changed, 141 insertions(+), 84 deletions(-) diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index ae51d7b4c42e..33df1b3758b6 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h @@ -68,29 +68,58 @@ /* - * Reserved Page provided by SAL. + * the reserved page * - * SAL provides one page per partition of reserved memory. When SAL - * initialization is complete, SAL_signature, SAL_version, partid, - * part_nasids, and mach_nasids are set. + * SAL reserves one page of memory per partition for XPC. Though a full page + * in length (16384 bytes), its starting address is not page aligned, but it + * is cacheline aligned. The reserved page consists of the following: + * + * reserved page header + * + * The first cacheline of the reserved page contains the header + * (struct xpc_rsvd_page). Before SAL initialization has completed, + * SAL has set up the following fields of the reserved page header: + * SAL_signature, SAL_version, partid, and nasids_size. The other + * fields are set up by XPC. (xpc_rsvd_page points to the local + * partition's reserved page.) + * + * part_nasids mask + * mach_nasids mask + * + * SAL also sets up two bitmaps (or masks), one that reflects the actual + * nasids in this partition (part_nasids), and the other that reflects + * the actual nasids in the entire machine (mach_nasids). We're only + * interested in the even numbered nasids (which contain the processors + * and/or memory), so we only need half as many bits to represent the + * nasids. The part_nasids mask is located starting at the first cacheline + * following the reserved page header. The mach_nasids mask follows right + * after the part_nasids mask. The size in bytes of each mask is reflected + * by the reserved page header field 'nasids_size'. (Local partition's + * mask pointers are xpc_part_nasids and xpc_mach_nasids.) + * + * vars + * vars part + * + * Immediately following the mach_nasids mask are the XPC variables + * required by other partitions. First are those that are generic to all + * partitions (vars), followed on the next available cacheline by those + * which are partition specific (vars part). These are setup by XPC. + * (Local partition's vars pointers are xpc_vars and xpc_vars_part.) * * Note: Until vars_pa is set, the partition XPC code has not been initialized. */ struct xpc_rsvd_page { - u64 SAL_signature; /* SAL unique signature */ - u64 SAL_version; /* SAL specified version */ - u8 partid; /* partition ID from SAL */ + u64 SAL_signature; /* SAL: unique signature */ + u64 SAL_version; /* SAL: version */ + u8 partid; /* SAL: partition ID */ u8 version; - u8 pad[6]; /* pad to u64 align */ + u8 pad1[6]; /* align to next u64 in cacheline */ volatile u64 vars_pa; - struct timespec stamp; /* time when reserved page was initialized */ - u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; - u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; + struct timespec stamp; /* time when reserved page was setup by XPC */ + u64 pad2[9]; /* align to last u64 in cacheline */ + u64 nasids_size; /* SAL: size of each nasid mask in bytes */ }; -#define XPC_RSVD_PAGE_ALIGNED_SIZE \ - (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))) - #define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */ #define XPC_SUPPORTS_RP_STAMP(_version) \ @@ -142,8 +171,6 @@ struct xpc_vars { AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ }; -#define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars))) - #define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */ #define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ @@ -184,7 +211,7 @@ xpc_disallow_hb(partid_t partid, struct xpc_vars *vars) /* * The AMOs page consists of a number of AMO variables which are divided into * four groups, The first two groups are used to identify an IRQ's sender. - * These two groups consist of 64 and 16 AMO variables respectively. The last + * These two groups consist of 64 and 128 AMO variables respectively. The last * two groups, consisting of just one AMO variable each, are used to identify * the remote partitions that are currently engaged (from the viewpoint of * the XPC running on the remote partition). @@ -233,6 +260,16 @@ struct xpc_vars_part { #define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */ +/* the reserved page sizes and offsets */ + +#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)) +#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars)) + +#define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE) +#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) +#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words) +#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE) + /* * Functions registered by add_timer() or called by kernel_thread() only @@ -1147,9 +1184,9 @@ xpc_IPI_send_local_msgrequest(struct xpc_channel *ch) * cacheable mapping for the entire region. This will prevent speculative * reading of cached copies of our lines from being issued which will cause * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 - * (XP_MAX_PARTITIONS) AMO variables for message notification and an - * additional 16 (XP_NASID_MASK_WORDS) AMO variables for partition activation - * and 2 AMO variables for partition deactivation. + * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an + * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition + * activation and 2 AMO variables for partition deactivation. */ static inline AMO_t * xpc_IPI_init(int index) diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index db349c6d4c58..38f2c699192c 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -1049,11 +1049,11 @@ xpc_init(void) /* * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng - * both a partition's reserved page and its XPC variables. Its size was - * based on the size of a reserved page. So we need to ensure that the - * XPC variables will fit as well. + * various portions of a partition's reserved page. Its size is based + * on the size of the reserved page header and part_nasids mask. So we + * need to ensure that the other items will fit as well. */ - if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) { + if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) { dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n"); return -EPERM; } diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 958488f55699..6bb1091f2a4d 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -47,13 +47,16 @@ static u64 xpc_sh2_IPI_access3; u64 xpc_prot_vec[MAX_COMPACT_NODES]; -/* this partition's reserved page */ +/* this partition's reserved page pointers */ struct xpc_rsvd_page *xpc_rsvd_page; - -/* this partition's XPC variables (within the reserved page) */ +static u64 *xpc_part_nasids; +static u64 *xpc_mach_nasids; struct xpc_vars *xpc_vars; struct xpc_vars_part *xpc_vars_part; +static int xp_nasid_mask_bytes; /* actual size in bytes of nasid mask */ +static int xp_nasid_mask_words; /* actual size in words of nasid mask */ + /* * For performance reasons, each entry of xpc_partitions[] is cacheline @@ -65,15 +68,16 @@ struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; /* - * Generic buffer used to store a local copy of the remote partitions - * reserved page or XPC variables. + * Generic buffer used to store a local copy of portions of a remote + * partition's reserved page (either its header and part_nasids mask, + * or its vars). * * xpc_discovery runs only once and is a seperate thread that is * very likely going to be processing in parallel with receiving * interrupts. */ -char ____cacheline_aligned - xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE]; +char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE + + XP_NASID_MASK_BYTES]; /* @@ -136,7 +140,7 @@ xpc_rsvd_page_init(void) { struct xpc_rsvd_page *rp; AMO_t *amos_page; - u64 rp_pa, next_cl, nasid_array = 0; + u64 rp_pa, nasid_array = 0; int i, ret; @@ -144,7 +148,8 @@ xpc_rsvd_page_init(void) rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0), (u64) xpc_remote_copy_buffer, - XPC_RSVD_PAGE_ALIGNED_SIZE); + XPC_RP_HEADER_SIZE + + L1_CACHE_BYTES); if (rp_pa == 0) { dev_err(xpc_part, "SAL failed to locate the reserved page\n"); return NULL; @@ -159,12 +164,19 @@ xpc_rsvd_page_init(void) rp->version = XPC_RP_VERSION; - /* - * Place the XPC variables on the cache line following the - * reserved page structure. - */ - next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE; - xpc_vars = (struct xpc_vars *) next_cl; + /* establish the actual sizes of the nasid masks */ + if (rp->SAL_version == 1) { + /* SAL_version 1 didn't set the nasids_size field */ + rp->nasids_size = 128; + } + xp_nasid_mask_bytes = rp->nasids_size; + xp_nasid_mask_words = xp_nasid_mask_bytes / 8; + + /* setup the pointers to the various items in the reserved page */ + xpc_part_nasids = XPC_RP_PART_NASIDS(rp); + xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp); + xpc_vars = XPC_RP_VARS(rp); + xpc_vars_part = XPC_RP_VARS_PART(rp); /* * Before clearing xpc_vars, see if a page of AMOs had been previously @@ -216,26 +228,23 @@ xpc_rsvd_page_init(void) amos_page = (AMO_t *) TO_AMO((u64) amos_page); } + /* clear xpc_vars */ memset(xpc_vars, 0, sizeof(struct xpc_vars)); - /* - * Place the XPC per partition specific variables on the cache line - * following the XPC variables structure. - */ - next_cl += XPC_VARS_ALIGNED_SIZE; - memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) * - XP_MAX_PARTITIONS); - xpc_vars_part = (struct xpc_vars_part *) next_cl; - xpc_vars->vars_part_pa = __pa(next_cl); - xpc_vars->version = XPC_V_VERSION; xpc_vars->act_nasid = cpuid_to_nasid(0); xpc_vars->act_phys_cpuid = cpu_physical_id(0); + xpc_vars->vars_part_pa = __pa(xpc_vars_part); + xpc_vars->amos_page_pa = ia64_tpa((u64) amos_page); xpc_vars->amos_page = amos_page; /* save for next load of XPC */ + /* clear xpc_vars_part */ + memset((u64 *) xpc_vars_part, 0, sizeof(struct xpc_vars_part) * + XP_MAX_PARTITIONS); + /* initialize the activate IRQ related AMO variables */ - for (i = 0; i < XP_NASID_MASK_WORDS; i++) { + for (i = 0; i < xp_nasid_mask_words; i++) { (void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); } @@ -243,10 +252,7 @@ xpc_rsvd_page_init(void) (void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); (void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO); - /* export AMO page's physical address to other partitions */ - xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page); - - /* timestamp of when reserved page was initialized */ + /* timestamp of when reserved page was setup by XPC */ rp->stamp = CURRENT_TIME; /* @@ -406,7 +412,7 @@ xpc_check_remote_hb(void) /* pull the remote_hb cache line */ bres = xp_bte_copy(part->remote_vars_pa, ia64_tpa((u64) remote_vars), - XPC_VARS_ALIGNED_SIZE, + XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { XPC_DEACTIVATE_PARTITION(part, @@ -434,10 +440,11 @@ xpc_check_remote_hb(void) /* - * Get a copy of the remote partition's rsvd page. + * Get a copy of a portion of the remote partition's rsvd page. * * remote_rp points to a buffer that is cacheline aligned for BTE copies and - * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE. + * is large enough to contain a copy of their reserved page header and + * part_nasids mask. */ static enum xpc_retval xpc_get_remote_rp(int nasid, u64 *discovered_nasids, @@ -449,16 +456,17 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, /* get the reserved page's physical address */ *remote_rp_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, - XPC_RSVD_PAGE_ALIGNED_SIZE); + XPC_RP_HEADER_SIZE + + xp_nasid_mask_bytes); if (*remote_rp_pa == 0) { return xpcNoRsvdPageAddr; } - /* pull over the reserved page structure */ + /* pull over the reserved page header and part_nasids mask */ bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp), - XPC_RSVD_PAGE_ALIGNED_SIZE, + XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { return xpc_map_bte_errors(bres); @@ -466,8 +474,11 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, if (discovered_nasids != NULL) { - for (i = 0; i < XP_NASID_MASK_WORDS; i++) { - discovered_nasids[i] |= remote_rp->part_nasids[i]; + u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); + + + for (i = 0; i < xp_nasid_mask_words; i++) { + discovered_nasids[i] |= remote_part_nasids[i]; } } @@ -494,10 +505,10 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, /* - * Get a copy of the remote partition's XPC variables. + * Get a copy of the remote partition's XPC variables from the reserved page. * * remote_vars points to a buffer that is cacheline aligned for BTE copies and - * assumed to be of size XPC_VARS_ALIGNED_SIZE. + * assumed to be of size XPC_RP_VARS_SIZE. */ static enum xpc_retval xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) @@ -513,7 +524,7 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) /* pull over the cross partition variables */ bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars), - XPC_VARS_ALIGNED_SIZE, + XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { return xpc_map_bte_errors(bres); @@ -778,14 +789,13 @@ xpc_identify_act_IRQ_sender(void) u64 nasid; /* remote nasid */ int n_IRQs_detected = 0; AMO_t *act_amos; - struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page; act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; /* scan through act AMO variable looking for non-zero entries */ - for (word = 0; word < XP_NASID_MASK_WORDS; word++) { + for (word = 0; word < xp_nasid_mask_words; word++) { if (xpc_exiting) { break; @@ -807,7 +817,7 @@ xpc_identify_act_IRQ_sender(void) * remote nasid in our reserved pages machine mask. * This is used in the event of module reload. */ - rp->mach_nasids[word] |= nasid_mask; + xpc_mach_nasids[word] |= nasid_mask; /* locate the nasid(s) which sent interrupts */ @@ -992,6 +1002,7 @@ xpc_discovery(void) u64 remote_rp_pa; u64 remote_vars_pa; int region; + int region_size; int max_regions; int nasid; struct xpc_rsvd_page *rp; @@ -1001,7 +1012,8 @@ xpc_discovery(void) enum xpc_retval ret; - remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE, + remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + + xp_nasid_mask_bytes, GFP_KERNEL, &remote_rp_base); if (remote_rp == NULL) { return; @@ -1009,13 +1021,13 @@ xpc_discovery(void) remote_vars = (struct xpc_vars *) remote_rp; - discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS, + discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words, GFP_KERNEL); if (discovered_nasids == NULL) { kfree(remote_rp_base); return; } - memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS); + memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words); rp = (struct xpc_rsvd_page *) xpc_rsvd_page; @@ -1024,11 +1036,19 @@ xpc_discovery(void) * nodes that can comprise an access protection grouping. The access * protection is in regards to memory, IOI and IPI. */ -//>>> move the next two #defines into either include/asm-ia64/sn/arch.h or -//>>> include/asm-ia64/sn/addrs.h -#define SH1_MAX_REGIONS 64 -#define SH2_MAX_REGIONS 256 - max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS; + max_regions = 64; + region_size = sn_region_size; + + switch (region_size) { + case 128: + max_regions *= 2; + case 64: + max_regions *= 2; + case 32: + max_regions *= 2; + region_size = 16; + DBUG_ON(!is_shub2()); + } for (region = 0; region < max_regions; region++) { @@ -1038,8 +1058,8 @@ xpc_discovery(void) dev_dbg(xpc_part, "searching region %d\n", region); - for (nasid = (region * sn_region_size * 2); - nasid < ((region + 1) * sn_region_size * 2); + for (nasid = (region * region_size * 2); + nasid < ((region + 1) * region_size * 2); nasid += 2) { if ((volatile int) xpc_exiting) { @@ -1049,14 +1069,14 @@ xpc_discovery(void) dev_dbg(xpc_part, "checking nasid %d\n", nasid); - if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) { + if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) { dev_dbg(xpc_part, "PROM indicates Nasid %d is " "part of the local partition; skipping " "region\n", nasid); break; } - if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) { + if (!(XPC_NASID_IN_ARRAY(nasid, xpc_mach_nasids))) { dev_dbg(xpc_part, "PROM indicates Nasid %d was " "not on Numa-Link network at reset\n", nasid); @@ -1178,12 +1198,12 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) return xpcPartitionDown; } - part_nasid_pa = part->remote_rp_pa + - (u64) &((struct xpc_rsvd_page *) 0)->part_nasids; + memset(nasid_mask, 0, XP_NASID_MASK_BYTES); + + part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa); bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask), - L1_CACHE_ALIGN(XP_NASID_MASK_BYTES), - (BTE_NOTIFY | BTE_WACQUIRE), NULL); + xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); return xpc_map_bte_errors(bte_res); } From 279290294662d4a35d209fb7d7c46523cfa3d63d Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 25 Oct 2005 14:11:53 -0500 Subject: [PATCH 0462/1940] [IA64-SGI] cleanup the way XPC locates the reserved page Eliminate the passing in of a scratch buffer used for locating the reserved page setup for XPC. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/xpc_partition.c | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 6bb1091f2a4d..ce5a37ff4388 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -85,13 +85,16 @@ char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE + * for that nasid. This function returns 0 on any error. */ static u64 -xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size) +xpc_get_rsvd_page_pa(int nasid) { bte_result_t bte_res; s64 status; u64 cookie = 0; u64 rp_pa = nasid; /* seed with nasid */ u64 len = 0; + u64 buf = buf; + u64 buf_len = 0; + void *buf_base = NULL; while (1) { @@ -107,13 +110,22 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size) break; } - if (len > buf_size) { - dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len); - status = SALRET_ERROR; - break; + if (L1_CACHE_ALIGN(len) > buf_len) { + if (buf_base != NULL) { + kfree(buf_base); + } + buf_len = L1_CACHE_ALIGN(len); + buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len, + GFP_KERNEL, &buf_base); + if (buf_base == NULL) { + dev_err(xpc_part, "unable to kmalloc " + "len=0x%016lx\n", buf_len); + status = SALRET_ERROR; + break; + } } - bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size, + bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bte_res != BTE_SUCCESS) { dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); @@ -122,6 +134,10 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size) } } + if (buf_base != NULL) { + kfree(buf_base); + } + if (status != SALRET_OK) { rp_pa = 0; } @@ -146,10 +162,9 @@ xpc_rsvd_page_init(void) /* get the local reserved page's address */ - rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0), - (u64) xpc_remote_copy_buffer, - XPC_RP_HEADER_SIZE + - L1_CACHE_BYTES); + preempt_disable(); + rp_pa = xpc_get_rsvd_page_pa(cpuid_to_nasid(smp_processor_id())); + preempt_enable(); if (rp_pa == 0) { dev_err(xpc_part, "SAL failed to locate the reserved page\n"); return NULL; @@ -455,9 +470,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, /* get the reserved page's physical address */ - *remote_rp_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, - XPC_RP_HEADER_SIZE + - xp_nasid_mask_bytes); + *remote_rp_pa = xpc_get_rsvd_page_pa(nasid); if (*remote_rp_pa == 0) { return xpcNoRsvdPageAddr; } From e7f98dbbb89b68b23a5115708412a820a713fbf1 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Tue, 25 Oct 2005 17:34:19 -0500 Subject: [PATCH 0463/1940] [IA64-SGI] fix bte_copy() calling get_nasid() while preemptible bte_copy() calls calls get_nasid(), which will get flagged if preemption if enabled. raw_smp_processor_id() is used instead. It is OK if we migrate off node. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/bte.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index 45854c637e9c..d71f4de44f79 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c @@ -87,7 +87,7 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) unsigned long irq_flags; unsigned long itc_end = 0; int nasid_to_try[MAX_NODES_TO_TRY]; - int my_nasid = get_nasid(); + int my_nasid = cpuid_to_nasid(raw_smp_processor_id()); int bte_if_index, nasid_index; int bte_first, btes_per_node = BTES_PER_NODE; From d2e615125762459fd2bb9f0c91881509a0b9c31b Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 20 Oct 2005 11:43:33 -0500 Subject: [PATCH 0464/1940] [PATCH] powerpc: Make sure we have an RTC before trying to adjust it Its valid for ppc_md.set_rtc_time to be NULL. We need to check that its non-NULL before trying to update the RTC. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ad501d62aa6e..82f2cabb4f47 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -154,7 +154,7 @@ static __inline__ void timer_check_rtc(void) * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ - if (ntp_synced() && + if (ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { From 60dda2565bbf31bbe662fd143a41c861b7a190cf Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 20 Oct 2005 11:44:03 -0500 Subject: [PATCH 0465/1940] [PATCH] powerpc: some prom.c cleanups On !CONFIG_PPC_MULTIPLATFORM _machine is defined as 0. This is ok, but we can't assign a value to _machine then. We may not have CONFIG_PCI available, so only build in support for find_parent_pci_resource(), request_OF_resource(), release_OF_resource() if PCI is enabled. This is probably not the long term fix but works out for now. Make reg_property64 contain 64-bit elements on a 32-bit machine. Mark the deprecated prom.c functions as __deprecated. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 4 ++++ include/asm-powerpc/prom.h | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 69f69c38fd27..8d0c78cbc0bc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1167,8 +1167,10 @@ static int __init early_init_dt_scan_chosen(unsigned long node, #ifdef CONFIG_PPC64 systemcfg->platform = *prop; #else +#ifdef CONFIG_PPC_MULTIPLATFORM _machine = *prop; #endif +#endif #ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ @@ -2005,6 +2007,7 @@ bus_space_to_resource_flags(unsigned int bus_space) } } +#ifdef CONFIG_PCI static struct resource *find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) { @@ -2157,3 +2160,4 @@ int release_OF_resource(struct device_node *node, int index) return 0; } EXPORT_SYMBOL(release_OF_resource); +#endif /* CONFIG_PCI */ diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 8a21791c7cae..49d2c7455f8e 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -104,8 +104,8 @@ struct reg_property32 { }; struct reg_property64 { - unsigned long address; - unsigned long size; + u64 address; + u64 size; }; struct property { @@ -155,12 +155,12 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e /* OBSOLETE: Old style node lookup */ -extern struct device_node *find_devices(const char *name); -extern struct device_node *find_type_devices(const char *type); -extern struct device_node *find_path_device(const char *path); -extern struct device_node *find_compatible_devices(const char *type, +extern __deprecated struct device_node *find_devices(const char *name); +extern __deprecated struct device_node *find_type_devices(const char *type); +extern __deprecated struct device_node *find_path_device(const char *path); +extern __deprecated struct device_node *find_compatible_devices(const char *type, const char *compat); -extern struct device_node *find_all_nodes(void); +extern __deprecated struct device_node *find_all_nodes(void); /* New style node lookup */ extern struct device_node *of_find_node_by_name(struct device_node *from, From d95bbcb3a344b3eb84b45d162c0a20348f0af37f Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 20 Oct 2005 11:44:46 -0500 Subject: [PATCH 0466/1940] [PATCH] powerpc: merge include/asm-ppc*/checksum.h into include/asm-powerpc/checksum.h Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/checksum.h | 47 ++++++-- include/asm-ppc/checksum.h | 107 ------------------ 2 files changed, 36 insertions(+), 118 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/checksum.h (77%) delete mode 100644 include/asm-ppc/checksum.h diff --git a/include/asm-ppc64/checksum.h b/include/asm-powerpc/checksum.h similarity index 77% rename from include/asm-ppc64/checksum.h rename to include/asm-powerpc/checksum.h index d22d4469de43..d8354d8a49ce 100644 --- a/include/asm-ppc64/checksum.h +++ b/include/asm-powerpc/checksum.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_CHECKSUM_H -#define _PPC64_CHECKSUM_H +#ifndef _ASM_POWERPC_CHECKSUM_H +#define _ASM_POWERPC_CHECKSUM_H /* * This program is free software; you can redistribute it and/or @@ -41,8 +41,14 @@ extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); /* - * the same as csum_partial, but copies from src to dst while it - * checksums + * Computes the checksum of a memory block at src, length len, + * and adds in "sum" (32-bit), while copying the block to dst. + * If an access exception occurs on src or dst, it stores -EFAULT + * to *src_err or *dst_err respectively (if that pointer is not + * NULL), and, for an error on src, zeroes the rest of dst. + * + * Like csum_partial, this must be called with even lengths, + * except for the last fragment. */ extern unsigned int csum_partial_copy_generic(const char *src, char *dst, int len, unsigned int sum, @@ -51,12 +57,18 @@ extern unsigned int csum_partial_copy_generic(const char *src, char *dst, * the same as csum_partial, but copies from src to dst while it * checksums. */ - unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum); +#define csum_partial_copy_from_user(src, dst, len, sum, errp) \ + csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL) + +#define csum_partial_copy_nocheck(src, dst, len, sum) \ + csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) + + /* * turns a 32-bit partial checksum (e.g. from csum_partial) into a * 1's complement 16-bit checksum. @@ -83,12 +95,7 @@ static inline unsigned short ip_compute_csum(unsigned char * buff, int len) return csum_fold(csum_partial(buff, len, 0)); } -#define csum_partial_copy_from_user(src, dst, len, sum, errp) \ - csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL) - -#define csum_partial_copy_nocheck(src, dst, len, sum) \ - csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) - +#ifdef __powerpc64__ static inline u32 csum_tcpudp_nofold(u32 saddr, u32 daddr, unsigned short len, @@ -103,5 +110,23 @@ static inline u32 csum_tcpudp_nofold(u32 saddr, s += (s >> 32); return (u32) s; } +#else +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + __asm__("\n\ + addc %0,%0,%1 \n\ + adde %0,%0,%2 \n\ + adde %0,%0,%3 \n\ + addze %0,%0 \n\ + " + : "=r" (sum) + : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum)); + return sum; +} #endif +#endif diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h deleted file mode 100644 index cf953a92c7ab..000000000000 --- a/include/asm-ppc/checksum.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _PPC_CHECKSUM_H -#define _PPC_CHECKSUM_H - - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -extern unsigned int csum_partial(const unsigned char * buff, int len, - unsigned int sum); - -/* - * Computes the checksum of a memory block at src, length len, - * and adds in "sum" (32-bit), while copying the block to dst. - * If an access exception occurs on src or dst, it stores -EFAULT - * to *src_err or *dst_err respectively (if that pointer is not - * NULL), and, for an error on src, zeroes the rest of dst. - * - * Like csum_partial, this must be called with even lengths, - * except for the last fragment. - */ -extern unsigned int csum_partial_copy_generic(const char *src, char *dst, - int len, unsigned int sum, - int *src_err, int *dst_err); - -#define csum_partial_copy_from_user(src, dst, len, sum, errp) \ - csum_partial_copy_generic((__force void *)(src), (dst), (len), (sum), (errp), NULL) - -/* FIXME: this needs to be written to really do no check -- Cort */ -#define csum_partial_copy_nocheck(src, dst, len, sum) \ - csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) - -/* - * turns a 32-bit partial checksum (e.g. from csum_partial) into a - * 1's complement 16-bit checksum. - */ -static inline unsigned int csum_fold(unsigned int sum) -{ - unsigned int tmp; - - /* swap the two 16-bit halves of sum */ - __asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum)); - /* if there is a carry from adding the two 16-bit halves, - it will carry from the lower half into the upper half, - giving us the correct sum in the upper half. */ - sum = ~(sum + tmp) >> 16; - return sum; -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -static inline unsigned short ip_compute_csum(unsigned char * buff, int len) -{ - return csum_fold(csum_partial(buff, len, 0)); -} - -/* - * FIXME: I swiped this one from the sparc and made minor modifications. - * It may not be correct. -- Cort - */ -static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, - unsigned int sum) -{ - __asm__("\n\ - addc %0,%0,%1 \n\ - adde %0,%0,%2 \n\ - adde %0,%0,%3 \n\ - addze %0,%0 \n\ - " - : "=r" (sum) - : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum)); - return sum; -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. ihl is the number - * of 32-bit words and is always >= 5. - */ -extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl); - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -extern unsigned short csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, - unsigned int sum); - -#endif -#endif /* __KERNEL__ */ From bfbac4973687ae32df528f2811483f92b943f251 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Fri, 21 Oct 2005 16:16:58 -0500 Subject: [PATCH 0467/1940] [PATCH] powerpc: Fix types.h Powerpc: Fix types.h I noticed that Paul had already pulled the version of types.h that is missing the config.h include into the merge tree - this patch adds it back in. Signed-off-by: Becky Bruce Signed-off-by: Paul Mackerras --- include/asm-powerpc/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h index 7d803cb547bb..f70cd3fb32d9 100644 --- a/include/asm-powerpc/types.h +++ b/include/asm-powerpc/types.h @@ -64,6 +64,8 @@ typedef struct { #ifndef __ASSEMBLY__ +#include + typedef signed char s8; typedef unsigned char u8; From ab590ccb428f874bb8f9cec1265cc1f9cb38b601 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Mon, 24 Oct 2005 14:50:46 -0500 Subject: [PATCH 0468/1940] [PATCH] ppc: Fix m82xx_pci build A recent patch updated the name of pci_assign_all_busses to pci_assign_all_buses. This instance of its use wasn't corrected by the original patch to use the new name. Builds cleanly on ads8272. Signed-off-by: Becky Bruce Signed-off-by: Paul Mackerras --- arch/ppc/syslib/m82xx_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c index 5cce123789f1..1d1c3956c1ae 100644 --- a/arch/ppc/syslib/m82xx_pci.c +++ b/arch/ppc/syslib/m82xx_pci.c @@ -306,7 +306,7 @@ void __init pq2_find_bridges(void) struct pci_controller * hose; int host_bridge; - pci_assign_all_busses = 1; + pci_assign_all_buses = 1; hose = pcibios_alloc_controller(); From 0fd6f717948083d480f38e97f62cc116faf0e534 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 25 Oct 2005 23:02:59 -0500 Subject: [PATCH 0469/1940] [PATCH] powerpc: Add support for Book-E timer config to generic_calibrate_decr We need to initialize some control SPRS for timers on Book-E before we start taking decrementer interrupts. Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 82f2cabb4f47..9f264c2f02c3 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -610,6 +610,17 @@ void __init generic_calibrate_decr(void) ppc_proc_freq = *fp; } } +#ifdef CONFIG_BOOKE + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +#endif if (!node_found) printk(KERN_ERR "WARNING: Estimating processor frequency " "(not found)\n"); From 6d7f58b04d824843f7539a132e1ad8220bbe589a Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 25 Oct 2005 23:57:33 -0500 Subject: [PATCH 0470/1940] [PATCH] powerpc: Some minor cleanups to setup_32.c * Removed of_show_percpuinfo and just report CPU frequency in generic show_cpuinfo code. * Killed OCP and PPC_SYS related code which doesn't belong in the merge tree Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 45 +++++-------------------- arch/powerpc/platforms/powermac/setup.c | 3 -- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 2d7fdeb581d1..c6a67c65852a 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -39,15 +39,7 @@ #include #include #include -#include - -#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ - defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ - defined(CONFIG_PPC_MPC52xx)) - -#if USES_PPC_SYS -#include -#endif +#include #if defined CONFIG_KGDB #include @@ -234,18 +226,19 @@ int show_cpuinfo(struct seq_file *m, void *v) } } + /* + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ + seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, + ppc_proc_freq % 1000000); + seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", maj, min, PVR_VER(pvr), PVR_REV(pvr)); seq_printf(m, "bogomips\t: %lu.%02lu\n", lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); -#if USES_PPC_SYS - if (cur_ppc_sys_spec->ppc_sys_name) - seq_printf(m, "chipset\t\t: %s\n", - cur_ppc_sys_spec->ppc_sys_name); -#endif - #ifdef CONFIG_SMP seq_printf(m, "\n"); #endif @@ -305,28 +298,6 @@ unsigned long __init early_init(unsigned long dt_ptr) } #ifdef CONFIG_PPC_OF -/* - * Assume here that all clock rates are the same in a - * smp system. -- Cort - */ -int -of_show_percpuinfo(struct seq_file *m, int i) -{ - struct device_node *cpu_node; - u32 *fp; - int s; - - cpu_node = find_type_devices("cpu"); - if (!cpu_node) - return 0; - for (s = 0; s < i && cpu_node->next; s++) - cpu_node = cpu_node->next; - fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); - if (fp) - seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); - return 0; -} - void __init intuit_machine_type(void) { diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 908e4921bac4..72cd503d3d33 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -202,9 +202,6 @@ static void pmac_show_percpuinfo(struct seq_file *m, int i) return; } #endif /* CONFIG_CPU_FREQ_PMAC */ -#ifdef CONFIG_PPC32 - of_show_percpuinfo(m, i); -#endif } #ifndef CONFIG_ADB_CUDA From a6f3546ecd00a1566cee6e0d992f4c33c2d28287 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 24 Oct 2005 15:07:26 +1000 Subject: [PATCH 0471/1940] [PATCH] powerpc: Remove duplicate definition of set_tb() Somewhere along the line we got two definitions of set_tb(). They look to be identical although they're not textually identical. So remove the #ifdef CONFIG_PPC64 version, leaving the common version in time.h. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- include/asm-powerpc/reg.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 06a1f0f2db21..68058d72d8da 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -585,13 +585,6 @@ static inline void ppc64_runlatch_off(void) mtspr(SPRN_CTRLT, ctrl); } } - -static inline void set_tb(unsigned int upper, unsigned int lower) -{ - mttbl(0); - mttbu(upper); - mttbl(lower); -} #endif #define __get_SP() ({unsigned long sp; \ From 8c71632f7a13357b7dc5636fca68317f72d3043e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 24 Oct 2005 15:07:27 +1000 Subject: [PATCH 0472/1940] [PATCH] powerpc: Remove trailing \n" in HMT macros GCC 3.3.3 barfs on the trailing \n" in the HMT macros. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- include/asm-powerpc/ppc_asm.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 96367e04fa58..f8ad5df6ebef 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -76,13 +76,13 @@ #define REST_16EVRS(n,s,base) REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base) #define REST_32EVRS(n,s,base) REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base) -/* Macros to adjust thread priority for Iseries hardware multithreading */ -#define HMT_VERY_LOW or 31,31,31 # very low priority\n" -#define HMT_LOW or 1,1,1 -#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority\n" -#define HMT_MEDIUM or 2,2,2 -#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority\n" -#define HMT_HIGH or 3,3,3 +/* Macros to adjust thread priority for hardware multithreading */ +#define HMT_VERY_LOW or 31,31,31 # very low priority +#define HMT_LOW or 1,1,1 +#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority +#define HMT_MEDIUM or 2,2,2 +#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority +#define HMT_HIGH or 3,3,3 /* handle instructions that older assemblers may not know */ #define RFCI .long 0x4c000066 /* rfci instruction */ From 21f35f28229ad1b017a0ea6cd17c10d6b9ec255f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 24 Oct 2005 15:07:29 +1000 Subject: [PATCH 0473/1940] [PATCH] powerpc: Move firmware.h into include/asm-powerpc Move firmware.h into include/asm-powerpc. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- include/{asm-ppc64 => asm-powerpc}/firmware.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/firmware.h (93%) diff --git a/include/asm-ppc64/firmware.h b/include/asm-powerpc/firmware.h similarity index 93% rename from include/asm-ppc64/firmware.h rename to include/asm-powerpc/firmware.h index 22bb85cf60af..806c142ae9ea 100644 --- a/include/asm-ppc64/firmware.h +++ b/include/asm-powerpc/firmware.h @@ -1,8 +1,4 @@ /* - * include/asm-ppc64/firmware.h - * - * Extracted from include/asm-ppc64/cputable.h - * * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) * * Modifications for ppc64: @@ -13,8 +9,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#ifndef __ASM_PPC_FIRMWARE_H -#define __ASM_PPC_FIRMWARE_H +#ifndef __ASM_POWERPC_FIRMWARE_H +#define __ASM_POWERPC_FIRMWARE_H #ifdef __KERNEL__ @@ -98,4 +94,4 @@ extern firmware_feature_t firmware_features_table[]; #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -#endif /* __ASM_PPC_FIRMWARE_H */ +#endif /* __ASM_POWERPC_FIRMWARE_H */ From d9953105ce000abcfa988d0c160b2662186f5879 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 24 Oct 2005 15:07:30 +1000 Subject: [PATCH 0474/1940] [PATCH] powerpc: Move ras.c into arch/powerpc/platforms/pseries ras.o is only built for CONFIG_PPC_PSERIES, so move it into arch/powerpc/platforms/pseries. Update Makefiles to suit. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/Makefile | 2 +- .../{ppc64/kernel => powerpc/platforms/pseries}/ras.c | 11 +++++------ arch/ppc64/kernel/Makefile | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) rename arch/{ppc64/kernel => powerpc/platforms/pseries}/ras.c (99%) diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 9ebb34180a10..4c817304fc21 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -1,4 +1,4 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o + setup.o iommu.o ras.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_IBMVIO) += vio.o diff --git a/arch/ppc64/kernel/ras.c b/arch/powerpc/platforms/pseries/ras.c similarity index 99% rename from arch/ppc64/kernel/ras.c rename to arch/powerpc/platforms/pseries/ras.c index 41b97dc9cc0a..6562ff4b0a82 100644 --- a/arch/ppc64/kernel/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -1,17 +1,16 @@ /* - * ras.c * Copyright (C) 2001 Dave Engebretsen IBM Corporation - * + * * 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -19,7 +18,7 @@ /* Change Activity: * 2001/09/21 : engebret : Created with minimal EPOW and HW exception support. - * End Change Activity + * End Change Activity */ #include @@ -323,7 +322,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err) nonfatal = 1; } - log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal); + log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal); return nonfatal; } diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index ce5c99db431f..cb6ac3d1a06f 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -29,7 +29,7 @@ ifneq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o endif -obj-$(CONFIG_PPC_PSERIES) += rtasd.o ras.o udbg_16550.o +obj-$(CONFIG_PPC_PSERIES) += rtasd.o udbg_16550.o obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ bpa_iic.o spider-pic.o From 25635c71e44111a6bd48f342e144e2fc02d0a314 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 16:36:55 +1000 Subject: [PATCH 0475/1940] ppc: Use the indirect_pci.c from arch/powerpc/sysdev This defines a CONFIG_INDIRECT_PCI symbol to control whether it gets used or not, and fixes the Kconfig to select that symbol for platforms that need it. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 10 ++ arch/powerpc/platforms/embedded6xx/Kconfig | 8 ++ arch/powerpc/sysdev/Makefile | 3 +- arch/ppc/Kconfig | 18 +++ arch/ppc/Makefile | 3 +- arch/ppc/syslib/Makefile | 38 +++--- arch/ppc/syslib/indirect_pci.c | 134 --------------------- 7 files changed, 58 insertions(+), 156 deletions(-) delete mode 100644 arch/ppc/syslib/indirect_pci.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 27f122e1f849..a3451d5bb788 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -280,11 +280,13 @@ config PPC_PSERIES config PPC_CHRP bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select PPC_INDIRECT_PCI default y config PPC_PMAC bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM + select PPC_INDIRECT_PCI if PPC32 default y config PPC_PMAC64 @@ -296,6 +298,7 @@ config PPC_PMAC64 config PPC_PREP bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select PPC_INDIRECT_PCI default y config PPC_MAPLE @@ -637,6 +640,12 @@ config GENERIC_ISA_DMA depends on PPC64 || POWER4 || 6xx && !CPM2 default y +config PPC_INDIRECT_PCI + bool + depends on PCI + default y if 40x || 44x || 85xx || 83xx + default n + config EISA bool @@ -677,6 +686,7 @@ config PCI_QSPAN config PCI_8260 bool depends on PCI && 8260 + select PPC_INDIRECT_PCI default y config 8260_PCI9 diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 2d755b79d51f..784b41e19465 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -27,6 +27,7 @@ config CHESTNUT config SPRUCE bool "IBM-Spruce" + select PPC_INDIRECT_PCI config HDPU bool "Sky-HDPU" @@ -50,15 +51,19 @@ config LOPEC config MVME5100 bool "Motorola-MVME5100" + select PPC_INDIRECT_PCI config PPLUS bool "Motorola-PowerPlus" + select PPC_INDIRECT_PCI config PRPMC750 bool "Motorola-PrPMC750" + select PPC_INDIRECT_PCI config PRPMC800 bool "Motorola-PrPMC800" + select PPC_INDIRECT_PCI config SANDPOINT bool "Motorola-Sandpoint" @@ -74,6 +79,7 @@ config PAL4 config GEMINI bool "Synergy-Gemini" + select PPC_INDIRECT_PCI depends on BROKEN help Select Gemini if configuring for a Synergy Microsystems' Gemini @@ -226,6 +232,7 @@ config MV64360 # Really MV64360 & MV64460 config MV64X60 bool depends on (GT64260 || MV64360) + select PPC_INDIRECT_PCI default y menu "Set bridge options" @@ -274,6 +281,7 @@ config EPIC_SERIAL_MODE config MPC10X_BRIDGE bool depends on POWERPMC250 || LOPEC || SANDPOINT + select PPC_INDIRECT_PCI default y config MPC10X_OPENPIC diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index c649f03acf68..e66fef652fac 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_MPIC) += mpic.o -indirectpci-$(CONFIG_PPC_PMAC) = indirect_pci.o -obj-$(CONFIG_PPC32) += $(indirectpci-y) +obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index ed9c9727d75f..e3efaf47d083 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -568,6 +568,7 @@ config CHESTNUT config SPRUCE bool "IBM-Spruce" + select PPC_INDIRECT_PCI config HDPU bool "Sky-HDPU" @@ -591,15 +592,19 @@ config LOPEC config MVME5100 bool "Motorola-MVME5100" + select PPC_INDIRECT_PCI config PPLUS bool "Motorola-PowerPlus" + select PPC_INDIRECT_PCI config PRPMC750 bool "Motorola-PrPMC750" + select PPC_INDIRECT_PCI config PRPMC800 bool "Motorola-PrPMC800" + select PPC_INDIRECT_PCI config SANDPOINT bool "Motorola-Sandpoint" @@ -616,6 +621,7 @@ config PAL4 config GEMINI bool "Synergy-Gemini" depends on BROKEN + select PPC_INDIRECT_PCI help Select Gemini if configuring for a Synergy Microsystems' Gemini series Single Board Computer. More information is available at: @@ -749,11 +755,13 @@ config CPM2 config PPC_CHRP bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM + select PPC_INDIRECT_PCI default y config PPC_PMAC bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM + select PPC_INDIRECT_PCI default y config PPC_PMAC64 @@ -764,6 +772,7 @@ config PPC_PMAC64 config PPC_PREP bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM + select PPC_INDIRECT_PCI default y config PPC_OF @@ -797,6 +806,7 @@ config MV64360 # Really MV64360 & MV64460 config MV64X60 bool depends on (GT64260 || MV64360) + select PPC_INDIRECT_PCI default y menu "Set bridge options" @@ -845,6 +855,7 @@ config EPIC_SERIAL_MODE config MPC10X_BRIDGE bool depends on POWERPMC250 || LOPEC || SANDPOINT + select PPC_INDIRECT_PCI default y config MPC10X_OPENPIC @@ -1139,6 +1150,12 @@ config GENERIC_ISA_DMA depends on POWER3 || POWER4 || 6xx && !CPM2 default y +config PPC_INDIRECT_PCI + bool + depends on PCI + default y if 40x || 44x || 85xx || 83xx + default n + config EISA bool help @@ -1182,6 +1199,7 @@ config PCI_QSPAN config PCI_8260 bool depends on PCI && 8260 + select PPC_INDIRECT_PCI default y config 8260_PCI9 diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index aedc9ae13b2a..121d2347b89f 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -61,7 +61,8 @@ head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ arch/ppc/platforms/ \ - arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ + arch/ppc/mm/ arch/ppc/lib/ \ + arch/ppc/syslib/ arch/powerpc/sysdev/ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index f6a2f1938bfa..5739a19b9ed9 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -31,7 +31,7 @@ obj-$(CONFIG_GEN_RTC) += todc_time.o obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o ifeq ($(CONFIG_40x),y) -obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o ppc405_pci.o +obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o endif endif obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ @@ -40,43 +40,43 @@ ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.o i8259.o endif obj-$(CONFIG_PPC_OF) += prom_init.o prom.o -obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o +obj-$(CONFIG_PPC_PMAC) += open_pic.o obj-$(CONFIG_POWER4) += open_pic2.o -obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o -obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o todc_time.o -obj-$(CONFIG_BAMBOO) += indirect_pci.o pci_auto.o todc_time.o +obj-$(CONFIG_PPC_CHRP) += open_pic.o i8259.o +obj-$(CONFIG_PPC_PREP) += open_pic.o i8259.o todc_time.o +obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o -obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o +obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o -obj-$(CONFIG_GEMINI) += open_pic.o indirect_pci.o +obj-$(CONFIG_GEMINI) += open_pic.o obj-$(CONFIG_GT64260) += gt64260_pic.o obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o obj-$(CONFIG_HDPU) += pci_auto.o -obj-$(CONFIG_LUAN) += indirect_pci.o pci_auto.o todc_time.o +obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o obj-$(CONFIG_KATANA) += pci_auto.o obj-$(CONFIG_MV64360) += mv64360_pic.o -obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o indirect_pci.o -obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \ +obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o +obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ pci_auto.o hawk_common.o obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o -obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o +obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o obj-$(CONFIG_PAL4) += cpc700_pic.o obj-$(CONFIG_POWERPMC250) += pci_auto.o obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \ - indirect_pci.o todc_time.o pci_auto.o -obj-$(CONFIG_PRPMC750) += open_pic.o indirect_pci.o pci_auto.o \ + todc_time.o pci_auto.o +obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ hawk_common.o obj-$(CONFIG_HARRIER) += harrier.o -obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o +obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o obj-$(CONFIG_SBC82xx) += todc_time.o -obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ +obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ todc_time.o obj-$(CONFIG_8260) += m8260_setup.o pq2_devices.o pq2_sys.o \ ppc_sys.o -obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o +obj-$(CONFIG_PCI_8260) += m82xx_pci.o pci_auto.o obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o ifeq ($(CONFIG_PPC_GEN550),y) @@ -87,7 +87,7 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y) obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o endif obj-$(CONFIG_BOOTX_TEXT) += btext.o -obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o +obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_BOOKE) += dcr.o @@ -95,12 +95,12 @@ obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ ppc_sys.o i8259.o mpc85xx_sys.o \ mpc85xx_devices.o ifeq ($(CONFIG_85xx),y) -obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o +obj-$(CONFIG_PCI) += pci_auto.o endif obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ mpc83xx_sys.o mpc83xx_devices.o ifeq ($(CONFIG_83xx),y) -obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o +obj-$(CONFIG_PCI) += pci_auto.o endif obj-$(CONFIG_MPC8548_CDS) += todc_time.o obj-$(CONFIG_MPC8555_CDS) += todc_time.o diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c deleted file mode 100644 index e71488469704..000000000000 --- a/arch/ppc/syslib/indirect_pci.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Support for indirect PCI bridges. - * - * Copyright (C) 1998 Gabriel Paubert. - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef CONFIG_PPC_INDIRECT_PCI_BE -#define PCI_CFG_OUT out_be32 -#else -#define PCI_CFG_OUT out_le32 -#endif - -static int -indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 *val) -{ - struct pci_controller *hose = bus->sysdata; - volatile void __iomem *cfg_data; - u8 cfg_type = 0; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (hose->set_cfg_type) - if (bus->number != hose->first_busno) - cfg_type = 1; - - PCI_CFG_OUT(hose->cfg_addr, - (0x80000000 | ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) | cfg_type))); - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - cfg_data = hose->cfg_data + (offset & 3); - switch (len) { - case 1: - *val = in_8(cfg_data); - break; - case 2: - *val = in_le16(cfg_data); - break; - default: - *val = in_le32(cfg_data); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 val) -{ - struct pci_controller *hose = bus->sysdata; - volatile void __iomem *cfg_data; - u8 cfg_type = 0; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (hose->set_cfg_type) - if (bus->number != hose->first_busno) - cfg_type = 1; - - PCI_CFG_OUT(hose->cfg_addr, - (0x80000000 | ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) | cfg_type))); - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - cfg_data = hose->cfg_data + (offset & 3); - switch (len) { - case 1: - out_8(cfg_data, val); - break; - case 2: - out_le16(cfg_data, val); - break; - default: - out_le32(cfg_data, val); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops indirect_pci_ops = -{ - indirect_read_config, - indirect_write_config -}; - -void __init -setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr, - void __iomem * cfg_data) -{ - hose->cfg_addr = cfg_addr; - hose->cfg_data = cfg_data; - hose->ops = &indirect_pci_ops; -} - -void __init -setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) -{ - unsigned long base = cfg_addr & PAGE_MASK; - void __iomem *mbase, *addr, *data; - - mbase = ioremap(base, PAGE_SIZE); - addr = mbase + (cfg_addr & ~PAGE_MASK); - if ((cfg_data & PAGE_MASK) != base) - mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); - data = mbase + (cfg_data & ~PAGE_MASK); - setup_indirect_pci_nomap(hose, addr, data); -} From f9bd170a87948a9e077149b70fb192c563770fdf Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 16:47:42 +1000 Subject: [PATCH 0476/1940] powerpc: Merge i8259.c into arch/powerpc/sysdev This changes the parameters for i8259_init so that it takes two parameters: a physical address for generating an interrupt acknowledge cycle, and an interrupt number offset. i8259_init now sets the irq_desc[] for its interrupts; all the callers were doing this, and that code is gone now. This also defines a CONFIG_PPC_I8259 symbol to select i8259.o for inclusion, and makes the platforms that need it select that symbol. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 10 ++ arch/powerpc/platforms/embedded6xx/Kconfig | 5 + arch/powerpc/platforms/pseries/setup.c | 19 +- arch/powerpc/sysdev/Makefile | 1 + arch/{ppc/syslib => powerpc/sysdev}/i8259.c | 65 ++++--- arch/ppc/Kconfig | 14 ++ arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 5 +- arch/ppc/platforms/chrp_setup.c | 4 +- arch/ppc/platforms/lopec.c | 6 +- arch/ppc/platforms/mvme5100.c | 6 +- arch/ppc/platforms/pplus.c | 5 +- arch/ppc/platforms/prep_setup.c | 8 +- arch/ppc/platforms/radstone_ppc7d.c | 6 +- arch/ppc/platforms/sandpoint.c | 10 +- arch/ppc/syslib/Makefile | 19 +- arch/ppc64/Kconfig | 5 + arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/i8259.c | 177 ------------------- include/asm-powerpc/i8259.h | 3 +- 19 files changed, 99 insertions(+), 271 deletions(-) rename arch/{ppc/syslib => powerpc/sysdev}/i8259.c (76%) delete mode 100644 arch/ppc64/kernel/i8259.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a3451d5bb788..9f279e0d84f2 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -275,11 +275,13 @@ endchoice config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 bool " IBM pSeries & new (POWER5-based) iSeries" + select PPC_I8259 default y config PPC_CHRP bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select PPC_I8259 select PPC_INDIRECT_PCI default y @@ -298,6 +300,7 @@ config PPC_PMAC64 config PPC_PREP bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select PPC_I8259 select PPC_INDIRECT_PCI default y @@ -628,6 +631,7 @@ menu "Bus options" config ISA bool "Support for ISA-bus hardware" depends on PPC_PREP || PPC_CHRP + select PPC_I8259 help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -640,6 +644,11 @@ config GENERIC_ISA_DMA depends on PPC64 || POWER4 || 6xx && !CPM2 default y +config PPC_I8259 + bool + default y if 85xx + default n + config PPC_INDIRECT_PCI bool depends on PCI @@ -679,6 +688,7 @@ config MPC83xx_PCI2 config PCI_QSPAN bool "QSpan PCI" depends on !4xx && !CPM2 && 8xx + select PPC_I8259 help Say Y here if you have a system based on a Motorola 8xx-series embedded processor with a QSPAN PCI interface, otherwise say N. diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 784b41e19465..81250090f98d 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -48,6 +48,7 @@ config EV64260 config LOPEC bool "Motorola-LoPEC" + select PPC_I8259 config MVME5100 bool "Motorola-MVME5100" @@ -55,6 +56,7 @@ config MVME5100 config PPLUS bool "Motorola-PowerPlus" + select PPC_I8259 select PPC_INDIRECT_PCI config PRPMC750 @@ -67,12 +69,14 @@ config PRPMC800 config SANDPOINT bool "Motorola-Sandpoint" + select PPC_I8259 help Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). config RADSTONE_PPC7D bool "Radstone Technology PPC7D board" + select PPC_I8259 config PAL4 bool "SBS-Palomar4" @@ -307,6 +311,7 @@ config HARRIER_STORE_GATHERING config MVME5100_IPMC761_PRESENT bool "MVME5100 configured with an IPMC761" depends on MVME5100 + select PPC_I8259 config SPRUCE_BAUD_33M bool "Spruce baud clock support" diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 92d18003f152..0fa5beae6d1b 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -87,7 +87,6 @@ extern int pSeries_machine_check_exception(struct pt_regs *regs); static void pseries_shared_idle(void); static void pseries_dedicated_idle(void); -static volatile void __iomem * chrp_int_ack_special; struct mpic *pSeries_mpic; void pSeries_show_cpuinfo(struct seq_file *m) @@ -119,19 +118,11 @@ static void __init fwnmi_init(void) fwnmi_active = 1; } -static int pSeries_irq_cascade(struct pt_regs *regs, void *data) -{ - if (chrp_int_ack_special) - return readb(chrp_int_ack_special); - else - return i8259_irq(regs); -} - static void __init pSeries_init_mpic(void) { unsigned int *addrp; struct device_node *np; - int i; + unsigned long intack = 0; /* All ISUs are setup, complete initialization */ mpic_init(pSeries_mpic); @@ -142,16 +133,14 @@ static void __init pSeries_init_mpic(void) get_property(np, "8259-interrupt-acknowledge", NULL))) printk(KERN_ERR "Cannot find pci to get ack address\n"); else - chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1); + intack = addrp[prom_n_addr_cells(np)-1]; of_node_put(np); /* Setup the legacy interrupts & controller */ - for (i = 0; i < NUM_ISA_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - i8259_init(0); + i8259_init(intack, 0); /* Hook cascade to mpic */ - mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL); + mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); } static void __init pSeries_setup_mpic(void) diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index e66fef652fac..f3c9e61c3910 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o +obj-$(CONFIG_PPC_I8259) += i8259.o diff --git a/arch/ppc/syslib/i8259.c b/arch/powerpc/sysdev/i8259.c similarity index 76% rename from arch/ppc/syslib/i8259.c rename to arch/powerpc/sysdev/i8259.c index 5c7908c20e43..90bce6e0c191 100644 --- a/arch/ppc/syslib/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -1,18 +1,26 @@ +/* + * i8259 interrupt controller driver. + * + * 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. + */ #include #include #include #include #include -static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */ +static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */ -unsigned char cached_8259[2] = { 0xff, 0xff }; +static unsigned char cached_8259[2] = { 0xff, 0xff }; #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) static DEFINE_SPINLOCK(i8259_lock); -int i8259_pic_irq_offset; +static int i8259_pic_irq_offset; /* * Acknowledge the IRQ using either the PCI host bridge's interrupt @@ -20,8 +28,7 @@ int i8259_pic_irq_offset; * which is called. It should be noted that polling is broken on some * IBM and Motorola PReP boxes so we must use the int-ack feature on them. */ -int -i8259_irq(struct pt_regs *regs) +int i8259_irq(struct pt_regs *regs) { int irq; @@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs) /* Either int-ack or poll for the IRQ */ if (pci_intack) - irq = *pci_intack; + irq = readb(pci_intack); else { /* Perform an interrupt acknowledge cycle on controller 1. */ outb(0x0C, 0x20); /* prepare for poll */ @@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs) } spin_unlock(&i8259_lock); - return irq; + return irq + i8259_pic_irq_offset; +} + +int i8259_irq_cascade(struct pt_regs *regs, void *unused) +{ + return i8259_irq(regs); } static void i8259_mask_and_ack_irq(unsigned int irq_nr) @@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - + irq_nr -= i8259_pic_irq_offset; if (irq_nr > 7) { cached_A1 |= 1 << (irq_nr-8); - inb(0xA1); /* DUMMY */ - outb(cached_A1,0xA1); - outb(0x20,0xA0); /* Non-specific EOI */ - outb(0x20,0x20); /* Non-specific EOI to cascade */ + inb(0xA1); /* DUMMY */ + outb(cached_A1, 0xA1); + outb(0x20, 0xA0); /* Non-specific EOI */ + outb(0x20, 0x20); /* Non-specific EOI to cascade */ } else { cached_21 |= 1 << irq_nr; - inb(0x21); /* DUMMY */ - outb(cached_21,0x21); - outb(0x20,0x20); /* Non-specific EOI */ + inb(0x21); /* DUMMY */ + outb(cached_21, 0x21); + outb(0x20, 0x20); /* Non-specific EOI */ } spin_unlock_irqrestore(&i8259_lock, flags); } @@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr) unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) + irq_nr -= i8259_pic_irq_offset; + if (irq_nr < 8) cached_21 |= 1 << irq_nr; else cached_A1 |= 1 << (irq_nr-8); @@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr) unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) + irq_nr -= i8259_pic_irq_offset; + if (irq_nr < 8) cached_21 &= ~(1 << irq_nr); else cached_A1 &= ~(1 << (irq_nr-8)); @@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = { * intack_addr - PCI interrupt acknowledge (real) address which will return * the active irq from the 8259 */ -void __init -i8259_init(long intack_addr) +void __init i8259_init(unsigned long intack_addr, int offset) { unsigned long flags; + int i; spin_lock_irqsave(&i8259_lock, flags); + i8259_pic_irq_offset = offset; + /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ @@ -198,11 +208,14 @@ i8259_init(long intack_addr) spin_unlock_irqrestore(&i8259_lock, flags); /* reserve our resources */ - setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction); + setup_irq(offset + 2, &i8259_irqaction); request_resource(&ioport_resource, &pic1_iores); request_resource(&ioport_resource, &pic2_iores); request_resource(&ioport_resource, &pic_edgectrl_iores); if (intack_addr != 0) pci_intack = ioremap(intack_addr, 1); + + for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) + irq_desc[offset + i].handler = &i8259_pic; } diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index e3efaf47d083..114b90fdea24 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -589,6 +589,7 @@ config EV64260 config LOPEC bool "Motorola-LoPEC" + select PPC_I8259 config MVME5100 bool "Motorola-MVME5100" @@ -596,6 +597,7 @@ config MVME5100 config PPLUS bool "Motorola-PowerPlus" + select PPC_I8259 select PPC_INDIRECT_PCI config PRPMC750 @@ -608,12 +610,14 @@ config PRPMC800 config SANDPOINT bool "Motorola-Sandpoint" + select PPC_I8259 help Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). config RADSTONE_PPC7D bool "Radstone Technology PPC7D board" + select PPC_I8259 config PAL4 bool "SBS-Palomar4" @@ -755,6 +759,7 @@ config CPM2 config PPC_CHRP bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM + select PPC_I8259 select PPC_INDIRECT_PCI default y @@ -772,6 +777,7 @@ config PPC_PMAC64 config PPC_PREP bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM + select PPC_I8259 select PPC_INDIRECT_PCI default y @@ -881,6 +887,7 @@ config HARRIER_STORE_GATHERING config MVME5100_IPMC761_PRESENT bool "MVME5100 configured with an IPMC761" depends on MVME5100 + select PPC_I8259 config SPRUCE_BAUD_33M bool "Spruce baud clock support" @@ -1138,6 +1145,7 @@ menu "Bus options" config ISA bool "Support for ISA-bus hardware" depends on PPC_PREP || PPC_CHRP + select PPC_I8259 help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1150,6 +1158,11 @@ config GENERIC_ISA_DMA depends on POWER3 || POWER4 || 6xx && !CPM2 default y +config PPC_I8259 + bool + default y if 85xx + default n + config PPC_INDIRECT_PCI bool depends on PCI @@ -1192,6 +1205,7 @@ config MPC83xx_PCI2 config PCI_QSPAN bool "QSpan PCI" depends on !4xx && !CPM2 && 8xx + select PPC_I8259 help Say Y here if you have a system based on a Motorola 8xx-series embedded processor with a QSPAN PCI interface, otherwise say N. diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 9f9039498ae5..eda659916f24 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void) #ifdef CONFIG_PCI openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); - for (i = 0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - - i8259_init(0); + i8259_init(0, 0); #endif #ifdef CONFIG_CPM2 diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 56c53bb3dfd4..dad81ffd4013 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void) i8259_irq); } - for (i = 0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - i8259_init(chrp_int_ack); + i8259_init(chrp_int_ack, 0); #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) /* see if there is a keyboard in the device tree diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c index 800c56a07a97..06d247c23b82 100644 --- a/arch/ppc/platforms/lopec.c +++ b/arch/ppc/platforms/lopec.c @@ -267,15 +267,11 @@ lopec_init_IRQ(void) openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", &i8259_irq); - /* Map i8259 interrupts */ - for(i = 0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - /* * The EPIC allows for a read in the range of 0xFEF00000 -> * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. */ - i8259_init(0xfef00000); + i8259_init(0xfef00000, 0); } static int __init diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c index ce2ce88c8033..108eb182dddc 100644 --- a/arch/ppc/platforms/mvme5100.c +++ b/arch/ppc/platforms/mvme5100.c @@ -223,11 +223,7 @@ mvme5100_init_IRQ(void) openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", &i8259_irq); - /* Map i8259 interrupts. */ - for (i = 0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - - i8259_init(0); + i8259_init(0, 0); #else openpic_init(0); #endif diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c index 59eb330b2090..22bd40cfb092 100644 --- a/arch/ppc/platforms/pplus.c +++ b/arch/ppc/platforms/pplus.c @@ -665,10 +665,7 @@ static void __init pplus_init_IRQ(void) ppc_md.get_irq = openpic_get_irq; } - for (i = 0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - - i8259_init(0); + i8259_init(0, 0); if (ppc_md.progress) ppc_md.progress("init_irq: exit", 0); diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 9e5637e5f5a9..067d7d53b81e 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -954,11 +954,9 @@ prep_init_IRQ(void) openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", i8259_irq); } - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) - irq_desc[i].handler = &i8259_pic; if (have_residual_data) { - i8259_init(residual_isapic_addr()); + i8259_init(residual_isapic_addr(), 0); return; } @@ -969,11 +967,11 @@ prep_init_IRQ(void) if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN) || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK))) - i8259_init(0); + i8259_init(0, 0); else /* PCI interrupt ack address given in section 6.1.8 of the * PReP specification. */ - i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR); + i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0); } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 5058568c13ec..6f97911c330d 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c @@ -514,13 +514,9 @@ static void __init ppc7d_init_irq(void) int irq; pr_debug("%s\n", __FUNCTION__); - i8259_init(0); + i8259_init(0, 0); mv64360_init_irq(); - /* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */ - for (irq = 0; irq < 16; irq++) { - irq_desc[irq].handler = &i8259_pic; - } /* IRQs 5,6,9,10,11,14,15 are level sensitive */ irq_desc[5].status |= IRQ_LEVEL; irq_desc[6].status |= IRQ_LEVEL; diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index d4c9781989fb..9eeed3572309 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -493,19 +493,11 @@ sandpoint_init_IRQ(void) openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade", i8259_irq); - /* - * openpic_init() has set up irq_desc[16-31] to be openpic - * interrupts. We need to set irq_desc[0-15] to be i8259 - * interrupts. - */ - for(i=0; i < NUM_8259_INTERRUPTS; i++) - irq_desc[i].handler = &i8259_pic; - /* * The EPIC allows for a read in the range of 0xFEF00000 -> * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. */ - i8259_init(0xfef00000); + i8259_init(0xfef00000, 0); } static unsigned long __init diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 5739a19b9ed9..e6e6aa4d291e 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -36,14 +36,12 @@ endif endif obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o -ifeq ($(CONFIG_8xx),y) -obj-$(CONFIG_PCI) += qspan_pci.o i8259.o -endif +obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o obj-$(CONFIG_PPC_OF) += prom_init.o prom.o obj-$(CONFIG_PPC_PMAC) += open_pic.o obj-$(CONFIG_POWER4) += open_pic2.o -obj-$(CONFIG_PPC_CHRP) += open_pic.o i8259.o -obj-$(CONFIG_PPC_PREP) += open_pic.o i8259.o todc_time.o +obj-$(CONFIG_PPC_CHRP) += open_pic.o +obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o @@ -51,7 +49,7 @@ obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o obj-$(CONFIG_GEMINI) += open_pic.o obj-$(CONFIG_GT64260) += gt64260_pic.o -obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o +obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o obj-$(CONFIG_HDPU) += pci_auto.o obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o obj-$(CONFIG_KATANA) += pci_auto.o @@ -59,18 +57,17 @@ obj-$(CONFIG_MV64360) += mv64360_pic.o obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ pci_auto.o hawk_common.o -obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o obj-$(CONFIG_PAL4) += cpc700_pic.o obj-$(CONFIG_POWERPMC250) += pci_auto.o -obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \ +obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \ todc_time.o pci_auto.o obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ hawk_common.o obj-$(CONFIG_HARRIER) += harrier.o obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o -obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o -obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o +obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o +obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o obj-$(CONFIG_SBC82xx) += todc_time.o obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ todc_time.o @@ -92,7 +89,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ - ppc_sys.o i8259.o mpc85xx_sys.o \ + ppc_sys.o mpc85xx_sys.o \ mpc85xx_devices.o ifeq ($(CONFIG_85xx),y) obj-$(CONFIG_PCI) += pci_auto.o diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 8cbac7f32092..963f519b7713 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -123,6 +123,11 @@ config MPIC bool default y +config PPC_I8259 + depends on PPC_PSERIES + bool + default y + config BPA_IIC depends on PPC_BPA bool diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index cb6ac3d1a06f..2c541c6652b2 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -24,7 +24,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o +obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o ifneq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o endif diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c deleted file mode 100644 index 74dcfd68fc75..000000000000 --- a/arch/ppc64/kernel/i8259.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * c 2001 PPC64 Team, IBM Corp - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "i8259.h" - -unsigned char cached_8259[2] = { 0xff, 0xff }; -#define cached_A1 (cached_8259[0]) -#define cached_21 (cached_8259[1]) - -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock); - -static int i8259_pic_irq_offset; -static int i8259_present; - -int i8259_irq(int cpu) -{ - int irq; - - spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); - /* - * Perform an interrupt acknowledge cycle on controller 1 - */ - outb(0x0C, 0x20); - irq = inb(0x20) & 7; - if (irq == 2) - { - /* - * Interrupt is cascaded so perform interrupt - * acknowledge on controller 2 - */ - outb(0x0C, 0xA0); - irq = (inb(0xA0) & 7) + 8; - } - else if (irq==7) - { - /* - * This may be a spurious interrupt - * - * Read the interrupt status register. If the most - * significant bit is not set then there is no valid - * interrupt - */ - outb(0x0b, 0x20); - if(~inb(0x20)&0x80) { - spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); - return -1; - } - } - spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); - return irq; -} - -static void i8259_mask_and_ack_irq(unsigned int irq_nr) -{ - unsigned long flags; - - spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - - if (irq_nr > 7) { - cached_A1 |= 1 << (irq_nr-8); - inb(0xA1); /* DUMMY */ - outb(cached_A1,0xA1); - outb(0x20,0xA0); /* Non-specific EOI */ - outb(0x20,0x20); /* Non-specific EOI to cascade */ - } else { - cached_21 |= 1 << irq_nr; - inb(0x21); /* DUMMY */ - outb(cached_21,0x21); - outb(0x20,0x20); /* Non-specific EOI */ - } - spin_unlock_irqrestore(&i8259_lock, flags); -} - -static void i8259_set_irq_mask(int irq_nr) -{ - outb(cached_A1,0xA1); - outb(cached_21,0x21); -} - -static void i8259_mask_irq(unsigned int irq_nr) -{ - unsigned long flags; - - spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) - cached_21 |= 1 << irq_nr; - else - cached_A1 |= 1 << (irq_nr-8); - i8259_set_irq_mask(irq_nr); - spin_unlock_irqrestore(&i8259_lock, flags); -} - -static void i8259_unmask_irq(unsigned int irq_nr) -{ - unsigned long flags; - - spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) - cached_21 &= ~(1 << irq_nr); - else - cached_A1 &= ~(1 << (irq_nr-8)); - i8259_set_irq_mask(irq_nr); - spin_unlock_irqrestore(&i8259_lock, flags); -} - -static void i8259_end_irq(unsigned int irq) -{ - if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) && - get_irq_desc(irq)->action) - i8259_unmask_irq(irq); -} - -struct hw_interrupt_type i8259_pic = { - .typename = " i8259 ", - .enable = i8259_unmask_irq, - .disable = i8259_mask_irq, - .ack = i8259_mask_and_ack_irq, - .end = i8259_end_irq, -}; - -void __init i8259_init(int offset) -{ - unsigned long flags; - - spin_lock_irqsave(&i8259_lock, flags); - i8259_pic_irq_offset = offset; - i8259_present = 1; - /* init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence */ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0x21); /* Select 8086 mode */ - outb(0xFF, 0x21); /* Mask all */ - /* init slave interrupt controller */ - outb(0x11, 0xA0); /* Start init sequence */ - outb(0x08, 0xA1); /* Vector base */ - outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0xA1); /* Select 8086 mode */ - outb(0xFF, 0xA1); /* Mask all */ - outb(cached_A1, 0xA1); - outb(cached_21, 0x21); - spin_unlock_irqrestore(&i8259_lock, flags); - -} - -static int i8259_request_cascade(void) -{ - if (!i8259_present) - return -ENODEV; - - request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, - "82c59 secondary cascade", NULL ); - - return 0; -} - -arch_initcall(i8259_request_cascade); diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h index 9521ad47740f..fc4bfee124d7 100644 --- a/include/asm-powerpc/i8259.h +++ b/include/asm-powerpc/i8259.h @@ -5,7 +5,8 @@ extern struct hw_interrupt_type i8259_pic; -extern void i8259_init(long intack_addr); +extern void i8259_init(unsigned long intack_addr, int offset); extern int i8259_irq(struct pt_regs *regs); +extern int i8259_irq_cascade(struct pt_regs *regs, void *unused); #endif /* _ASM_POWERPC_I8259_H */ From 033ef338b6e007dc081c6282a4f2a9dd761f8cd2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 17:05:24 +1000 Subject: [PATCH 0477/1940] powerpc: Merge rtas.c into arch/powerpc/kernel This splits arch/ppc64/kernel/rtas.c into arch/powerpc/kernel/rtas.c, which contains generic RTAS functions useful on any CHRP platform, and arch/powerpc/platforms/pseries/rtas-fw.[ch], which contain some pSeries-specific firmware flashing bits. The parts of rtas.c that are to do with pSeries-specific error logging are protected by a new CONFIG_RTAS_ERROR_LOGGING symbol. The inclusion of rtas.o is controlled by the CONFIG_PPC_RTAS symbol, and the relevant platforms select that. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 13 ++ arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/asm-offsets.c | 6 +- arch/powerpc/kernel/entry_32.S | 12 +- arch/powerpc/kernel/prom.c | 3 - arch/{ppc64 => powerpc}/kernel/rtas.c | 255 +++++++---------------- arch/powerpc/platforms/pseries/Kconfig | 5 - arch/powerpc/platforms/pseries/Makefile | 2 +- arch/powerpc/platforms/pseries/rtas-fw.c | 138 ++++++++++++ arch/powerpc/platforms/pseries/rtas-fw.h | 3 + arch/powerpc/platforms/pseries/setup.c | 10 +- arch/ppc64/Kconfig | 5 + arch/ppc64/kernel/Makefile | 2 +- 13 files changed, 256 insertions(+), 199 deletions(-) rename arch/{ppc64 => powerpc}/kernel/rtas.c (72%) create mode 100644 arch/powerpc/platforms/pseries/rtas-fw.c create mode 100644 arch/powerpc/platforms/pseries/rtas-fw.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9f279e0d84f2..ce5100cadd34 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -276,6 +276,8 @@ config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 bool " IBM pSeries & new (POWER5-based) iSeries" select PPC_I8259 + select PPC_RTAS + select RTAS_ERROR_LOGGING default y config PPC_CHRP @@ -283,6 +285,7 @@ config PPC_CHRP depends on PPC_MULTIPLATFORM && PPC32 select PPC_I8259 select PPC_INDIRECT_PCI + select PPC_RTAS default y config PPC_PMAC @@ -317,6 +320,7 @@ config PPC_MAPLE config PPC_BPA bool " Broadband Processor Architecture" depends on PPC_MULTIPLATFORM && PPC64 + select PPC_RTAS config PPC_OF bool @@ -338,6 +342,15 @@ config MPIC bool default y +config PPC_RTAS + bool + default n + +config RTAS_ERROR_LOGGING + bool + depends on PPC_RTAS + default n + config MPIC_BROKEN_U3 bool depends on PPC_MAPLE diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f5d8038fed52..eaedb7e63315 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o ptrace32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o +obj-$(CONFIG_PPC_RTAS) += rtas.o obj-$(CONFIG_IBMVIO) += vio.o ifeq ($(CONFIG_PPC_MERGE),y) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 1c83abd9f37c..710336a9f0fd 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -36,11 +36,11 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include #include #include -#include #include #include #include @@ -97,7 +97,7 @@ int main(void) DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); @@ -142,11 +142,11 @@ int main(void) DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); +#endif /* CONFIG_PPC64 */ /* RTAS */ DEFINE(RTASBASE, offsetof(struct rtas_t, base)); DEFINE(RTASENTRY, offsetof(struct rtas_t, entry)); -#endif /* CONFIG_PPC64 */ /* Interrupt register frame */ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 37b4396ca978..960da7bea043 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -954,7 +954,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) * here so it's easy to add arch-specific sections later. * -- Cort */ -#ifdef CONFIG_PPC_OF +#ifdef CONFIG_PPC_RTAS /* * On CHRP, the Run-Time Abstraction Services (RTAS) have to be * called with the MMU off. @@ -963,14 +963,13 @@ _GLOBAL(enter_rtas) stwu r1,-INT_FRAME_SIZE(r1) mflr r0 stw r0,INT_FRAME_SIZE+4(r1) - lis r4,rtas_data@ha - lwz r4,rtas_data@l(r4) + LOADADDR(r4, rtas) lis r6,1f@ha /* physical return address for rtas */ addi r6,r6,1f@l tophys(r6,r6) tophys(r7,r1) - lis r8,rtas_entry@ha - lwz r8,rtas_entry@l(r8) + lwz r8,RTASENTRY(r4) + lwz r4,RTASBASE(r4) mfmsr r9 stw r9,8(r1) LOAD_MSR_KERNEL(r0,MSR_KERNEL) @@ -978,7 +977,6 @@ _GLOBAL(enter_rtas) MTMSRD(r0) /* don't get trashed */ li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) mtlr r6 - CLR_TOP32(r7) mtspr SPRN_SPRG2,r7 mtspr SPRN_SRR0,r8 mtspr SPRN_SRR1,r9 @@ -999,4 +997,4 @@ machine_check_in_rtas: twi 31,0,0 /* XXX load up BATs and panic */ -#endif /* CONFIG_PPC_OF */ +#endif /* CONFIG_PPC_RTAS */ diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8d0c78cbc0bc..16ac15e73b44 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -110,9 +110,6 @@ struct device_node *of_chosen; struct device_node *dflt_interrupt_controller; int num_interrupt_controllers; -u32 rtas_data; -u32 rtas_entry; - /* * Wrapper for allocating memory for various data that needs to be * attached to device nodes as they are processed at boot or when diff --git a/arch/ppc64/kernel/rtas.c b/arch/powerpc/kernel/rtas.c similarity index 72% rename from arch/ppc64/kernel/rtas.c rename to arch/powerpc/kernel/rtas.c index 36adab591bd3..4d22eeeeb91d 100644 --- a/arch/ppc64/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -25,29 +25,29 @@ #include #include #include -#include -#include #include #include +#include +#ifdef CONFIG_PPC64 #include -#include +#endif -struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; - -struct rtas_t rtas = { +struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED }; EXPORT_SYMBOL(rtas); -char rtas_err_buf[RTAS_ERROR_LOG_MAX]; - DEFINE_SPINLOCK(rtas_data_buf_lock); -char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned; +char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; unsigned long rtas_rmo_buf; -void -call_rtas_display_status(unsigned char c) +/* + * call_rtas_display_status and call_rtas_display_status_delay + * are designed only for very early low-level debugging, which + * is why the token is hard-coded to 10. + */ +void call_rtas_display_status(unsigned char c) { struct rtas_args *args = &rtas.args; unsigned long s; @@ -67,8 +67,7 @@ call_rtas_display_status(unsigned char c) spin_unlock_irqrestore(&rtas.lock, s); } -void -call_rtas_display_status_delay(unsigned char c) +void call_rtas_display_status_delay(unsigned char c) { static int pending_newline = 0; /* did last write end with unprinted newline? */ static int width = 16; @@ -92,8 +91,7 @@ call_rtas_display_status_delay(unsigned char c) } } -void -rtas_progress(char *s, unsigned short hex) +void rtas_progress(char *s, unsigned short hex) { struct device_node *root; int width, *p; @@ -209,18 +207,16 @@ rtas_progress(char *s, unsigned short hex) spin_unlock(&progress_lock); } -int -rtas_token(const char *service) +int rtas_token(const char *service) { int *tokp; - if (rtas.dev == NULL) { - PPCDBG(PPCDBG_RTAS,"\tNo rtas device in device-tree...\n"); + if (rtas.dev == NULL) return RTAS_UNKNOWN_SERVICE; - } tokp = (int *) get_property(rtas.dev, service, NULL); return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; } +#ifdef CONFIG_RTAS_ERROR_LOGGING /* * Return the firmware-specified size of the error log buffer * for all rtas calls that require an error buffer argument. @@ -235,31 +231,38 @@ int rtas_get_error_log_max(void) rtas_error_log_max = rtas_token ("rtas-error-log-max"); if ((rtas_error_log_max == RTAS_UNKNOWN_SERVICE) || (rtas_error_log_max > RTAS_ERROR_LOG_MAX)) { - printk (KERN_WARNING "RTAS: bad log buffer size %d\n", rtas_error_log_max); + printk (KERN_WARNING "RTAS: bad log buffer size %d\n", + rtas_error_log_max); rtas_error_log_max = RTAS_ERROR_LOG_MAX; } return rtas_error_log_max; } +EXPORT_SYMBOL(rtas_get_error_log_max); +char rtas_err_buf[RTAS_ERROR_LOG_MAX]; +int rtas_last_error_token; + /** Return a copy of the detailed error text associated with the * most recent failed call to rtas. Because the error text * might go stale if there are any other intervening rtas calls, * this routine must be called atomically with whatever produced * the error (i.e. with rtas.lock still held from the previous call). */ -static int -__fetch_rtas_last_error(void) +static char *__fetch_rtas_last_error(char *altbuf) { struct rtas_args err_args, save_args; u32 bufsz; + char *buf = NULL; + + if (rtas_last_error_token == -1) + return NULL; bufsz = rtas_get_error_log_max(); - err_args.token = rtas_token("rtas-last-error"); + err_args.token = rtas_last_error_token; err_args.nargs = 2; err_args.nret = 1; - err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf); err_args.args[1] = bufsz; err_args.args[2] = 0; @@ -272,23 +275,38 @@ __fetch_rtas_last_error(void) err_args = rtas.args; rtas.args = save_args; - return err_args.args[2]; + /* Log the error in the unlikely case that there was one. */ + if (unlikely(err_args.args[2] == 0)) { + if (altbuf) { + buf = altbuf; + } else { + buf = rtas_err_buf; + if (mem_init_done) + buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); + } + if (buf) + memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); + } + + return buf; } +#define get_errorlog_buffer() kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL) + +#else /* CONFIG_RTAS_ERROR_LOGGING */ +#define __fetch_rtas_last_error(x) NULL +#define get_errorlog_buffer() NULL +#endif + int rtas_call(int token, int nargs, int nret, int *outputs, ...) { va_list list; - int i, logit = 0; + int i; unsigned long s; struct rtas_args *rtas_args; - char * buff_copy = NULL; + char *buff_copy = NULL; int ret; - PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n"); - PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token); - PPCDBG(PPCDBG_RTAS, "\tnargs = %d\n", nargs); - PPCDBG(PPCDBG_RTAS, "\tnret = %d\n", nret); - PPCDBG(PPCDBG_RTAS, "\t&outputs = 0x%lx\n", outputs); if (token == RTAS_UNKNOWN_SERVICE) return -1; @@ -301,46 +319,25 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) rtas_args->nret = nret; rtas_args->rets = (rtas_arg_t *)&(rtas_args->args[nargs]); va_start(list, outputs); - for (i = 0; i < nargs; ++i) { + for (i = 0; i < nargs; ++i) rtas_args->args[i] = va_arg(list, rtas_arg_t); - PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]); - } va_end(list); for (i = 0; i < nret; ++i) rtas_args->rets[i] = 0; - PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", - __pa(rtas_args)); enter_rtas(__pa(rtas_args)); - PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); /* A -1 return code indicates that the last command couldn't be completed due to a hardware error. */ if (rtas_args->rets[0] == -1) - logit = (__fetch_rtas_last_error() == 0); - - ifppcdebug(PPCDBG_RTAS) { - for(i=0; i < nret ;i++) - udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]); - } + buff_copy = __fetch_rtas_last_error(NULL); if (nret > 1 && outputs != NULL) for (i = 0; i < nret-1; ++i) outputs[i] = rtas_args->rets[i+1]; ret = (nret > 0)? rtas_args->rets[0]: 0; - /* Log the error in the unlikely case that there was one. */ - if (unlikely(logit)) { - buff_copy = rtas_err_buf; - if (mem_init_done) { - buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); - if (buff_copy) - memcpy(buff_copy, rtas_err_buf, - RTAS_ERROR_LOG_MAX); - } - } - /* Gotta do something different here, use global lock for now... */ spin_unlock_irqrestore(&rtas.lock, s); @@ -355,8 +352,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) /* Given an RTAS status code of 990n compute the hinted delay of 10^n * (last digit) milliseconds. For now we bound at n=5 (100 sec). */ -unsigned int -rtas_extended_busy_delay_time(int status) +unsigned int rtas_extended_busy_delay_time(int status) { int order = status - 9900; unsigned long ms; @@ -367,7 +363,7 @@ rtas_extended_busy_delay_time(int status) order = 5; /* bound */ /* Use microseconds for reasonable accuracy */ - for (ms=1; order > 0; order--) + for (ms = 1; order > 0; order--) ms *= 10; return ms; @@ -494,112 +490,23 @@ int rtas_set_indicator(int indicator, int index, int new_value) return rc; } -#define FLASH_BLOCK_LIST_VERSION (1UL) -static void -rtas_flash_firmware(void) +void rtas_restart(char *cmd) { - unsigned long image_size; - struct flash_block_list *f, *next, *flist; - unsigned long rtas_block_list; - int i, status, update_token; - - update_token = rtas_token("ibm,update-flash-64-and-reboot"); - if (update_token == RTAS_UNKNOWN_SERVICE) { - printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n"); - printk(KERN_ALERT "FLASH: firmware will not be flashed\n"); - return; - } - - /* NOTE: the "first" block list is a global var with no data - * blocks in the kernel data segment. We do this because - * we want to ensure this block_list addr is under 4GB. - */ - rtas_firmware_flash_list.num_blocks = 0; - flist = (struct flash_block_list *)&rtas_firmware_flash_list; - rtas_block_list = virt_to_abs(flist); - if (rtas_block_list >= 4UL*1024*1024*1024) { - printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); - return; - } - - printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); - /* Update the block_list in place. */ - image_size = 0; - for (f = flist; f; f = next) { - /* Translate data addrs to absolute */ - for (i = 0; i < f->num_blocks; i++) { - f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data); - image_size += f->blocks[i].length; - } - next = f->next; - /* Don't translate NULL pointer for last entry */ - if (f->next) - f->next = (struct flash_block_list *)virt_to_abs(f->next); - else - f->next = NULL; - /* make num_blocks into the version/length field */ - f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16); - } - - printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); - printk(KERN_ALERT "FLASH: performing flash and reboot\n"); - rtas_progress("Flashing \n", 0x0); - rtas_progress("Please Wait... ", 0x0); - printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); - status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); - switch (status) { /* should only get "bad" status */ - case 0: - printk(KERN_ALERT "FLASH: success\n"); - break; - case -1: - printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n"); - break; - case -3: - printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n"); - break; - case -4: - printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n"); - break; - default: - printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); - break; - } -} - -void rtas_flash_bypass_warning(void) -{ - printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n"); - printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n"); -} - - -void -rtas_restart(char *cmd) -{ - if (rtas_firmware_flash_list.next) - rtas_flash_firmware(); - printk("RTAS system-reboot returned %d\n", rtas_call(rtas_token("system-reboot"), 0, 1, NULL)); for (;;); } -void -rtas_power_off(void) +void rtas_power_off(void) { - if (rtas_firmware_flash_list.next) - rtas_flash_bypass_warning(); /* allow power on only with power button press */ printk("RTAS power-off returned %d\n", rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); for (;;); } -void -rtas_halt(void) +void rtas_halt(void) { - if (rtas_firmware_flash_list.next) - rtas_flash_bypass_warning(); rtas_power_off(); } @@ -632,9 +539,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) { struct rtas_args args; unsigned long flags; - char * buff_copy; + char *buff_copy, *errbuf = NULL; int nargs; - int err_rc = 0; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -653,7 +559,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) nargs * sizeof(rtas_arg_t)) != 0) return -EFAULT; - buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL); + buff_copy = get_errorlog_buffer(); spin_lock_irqsave(&rtas.lock, flags); @@ -665,19 +571,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) /* A -1 return code indicates that the last command couldn't be completed due to a hardware error. */ - if (args.rets[0] == -1) { - err_rc = __fetch_rtas_last_error(); - if ((err_rc == 0) && buff_copy) { - memcpy(buff_copy, rtas_err_buf, RTAS_ERROR_LOG_MAX); - } - } + if (args.rets[0] == -1) + errbuf = __fetch_rtas_last_error(buff_copy); spin_unlock_irqrestore(&rtas.lock, flags); if (buff_copy) { - if ((args.rets[0] == -1) && (err_rc == 0)) { - log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); - } + if (errbuf) + log_error(errbuf, ERR_TYPE_RTAS_LOG, 0); kfree(buff_copy); } @@ -690,6 +591,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) return 0; } +#ifdef CONFIG_SMP /* This version can't take the spinlock, because it never returns */ struct rtas_args rtas_stop_self_args = { @@ -714,6 +616,7 @@ void rtas_stop_self(void) panic("Alas, I survived.\n"); } +#endif /* * Call early during boot, before mem init or bootmem, to retreive the RTAS @@ -722,6 +625,8 @@ void rtas_stop_self(void) */ void __init rtas_initialize(void) { + unsigned long rtas_region = RTAS_INSTANTIATE_MAX; + /* Get RTAS dev node and fill up our "rtas" structure with infos * about it. */ @@ -743,26 +648,27 @@ void __init rtas_initialize(void) } else rtas.dev = NULL; } + if (!rtas.dev) + return; + /* If RTAS was found, allocate the RMO buffer for it and look for * the stop-self token if any */ - if (rtas.dev) { - unsigned long rtas_region = RTAS_INSTANTIATE_MAX; - if (systemcfg->platform == PLATFORM_PSERIES_LPAR) - rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); - - rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, - rtas_region); +#ifdef CONFIG_PPC64 + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); +#endif + rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); #ifdef CONFIG_HOTPLUG_CPU - rtas_stop_self_args.token = rtas_token("stop-self"); + rtas_stop_self_args.token = rtas_token("stop-self"); #endif /* CONFIG_HOTPLUG_CPU */ - } - +#ifdef CONFIG_RTAS_ERROR_LOGGING + rtas_last_error_token = rtas_token("rtas-last-error"); +#endif } -EXPORT_SYMBOL(rtas_firmware_flash_list); EXPORT_SYMBOL(rtas_token); EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_data_buf); @@ -772,4 +678,3 @@ EXPORT_SYMBOL(rtas_get_sensor); EXPORT_SYMBOL(rtas_get_power_level); EXPORT_SYMBOL(rtas_set_power_level); EXPORT_SYMBOL(rtas_set_indicator); -EXPORT_SYMBOL(rtas_get_error_log_max); diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 7a3b6fc4d976..2d57f588151d 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -21,11 +21,6 @@ config EEH depends on PPC_PSERIES default y if !EMBEDDED -config PPC_RTAS - bool - depends on PPC_PSERIES || PPC_BPA - default y - config RTAS_PROC bool "Proc interface to RTAS" depends on PPC_RTAS diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 4c817304fc21..d5c160b789e3 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -1,4 +1,4 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o ras.o + setup.o iommu.o rtas-fw.o ras.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_IBMVIO) += vio.o diff --git a/arch/powerpc/platforms/pseries/rtas-fw.c b/arch/powerpc/platforms/pseries/rtas-fw.c new file mode 100644 index 000000000000..15d81d758ca0 --- /dev/null +++ b/arch/powerpc/platforms/pseries/rtas-fw.c @@ -0,0 +1,138 @@ +/* + * + * Procedures for firmware flash updates on pSeries systems. + * + * Peter Bergner, IBM March 2001. + * Copyright (C) 2001 IBM. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rtas-fw.h" + +struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; + +#define FLASH_BLOCK_LIST_VERSION (1UL) + +static void rtas_flash_firmware(void) +{ + unsigned long image_size; + struct flash_block_list *f, *next, *flist; + unsigned long rtas_block_list; + int i, status, update_token; + + update_token = rtas_token("ibm,update-flash-64-and-reboot"); + if (update_token == RTAS_UNKNOWN_SERVICE) { + printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n"); + printk(KERN_ALERT "FLASH: firmware will not be flashed\n"); + return; + } + + /* NOTE: the "first" block list is a global var with no data + * blocks in the kernel data segment. We do this because + * we want to ensure this block_list addr is under 4GB. + */ + rtas_firmware_flash_list.num_blocks = 0; + flist = (struct flash_block_list *)&rtas_firmware_flash_list; + rtas_block_list = virt_to_abs(flist); + if (rtas_block_list >= 4UL*1024*1024*1024) { + printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); + return; + } + + printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); + /* Update the block_list in place. */ + image_size = 0; + for (f = flist; f; f = next) { + /* Translate data addrs to absolute */ + for (i = 0; i < f->num_blocks; i++) { + f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data); + image_size += f->blocks[i].length; + } + next = f->next; + /* Don't translate NULL pointer for last entry */ + if (f->next) + f->next = (struct flash_block_list *)virt_to_abs(f->next); + else + f->next = NULL; + /* make num_blocks into the version/length field */ + f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16); + } + + printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); + printk(KERN_ALERT "FLASH: performing flash and reboot\n"); + rtas_progress("Flashing \n", 0x0); + rtas_progress("Please Wait... ", 0x0); + printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); + status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); + switch (status) { /* should only get "bad" status */ + case 0: + printk(KERN_ALERT "FLASH: success\n"); + break; + case -1: + printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n"); + break; + case -3: + printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n"); + break; + case -4: + printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n"); + break; + default: + printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); + break; + } +} + +void rtas_flash_bypass_warning(void) +{ + printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n"); + printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n"); +} + + +void rtas_fw_restart(char *cmd) +{ + if (rtas_firmware_flash_list.next) + rtas_flash_firmware(); + rtas_restart(cmd); +} + +void rtas_fw_power_off(void) +{ + if (rtas_firmware_flash_list.next) + rtas_flash_bypass_warning(); + rtas_power_off(); +} + +void rtas_fw_halt(void) +{ + if (rtas_firmware_flash_list.next) + rtas_flash_bypass_warning(); + rtas_halt(); +} + +EXPORT_SYMBOL(rtas_firmware_flash_list); diff --git a/arch/powerpc/platforms/pseries/rtas-fw.h b/arch/powerpc/platforms/pseries/rtas-fw.h new file mode 100644 index 000000000000..e70fa69974a3 --- /dev/null +++ b/arch/powerpc/platforms/pseries/rtas-fw.h @@ -0,0 +1,3 @@ +void rtas_fw_restart(char *cmd); +void rtas_fw_power_off(void); +void rtas_fw_halt(void); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 0fa5beae6d1b..7e7e556e6b48 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -1,5 +1,5 @@ /* - * linux/arch/ppc/kernel/setup.c + * 64-bit pSeries and RS/6000 setup code. * * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas @@ -67,6 +67,8 @@ #include #include +#include "rtas-fw.h" + #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else @@ -589,9 +591,9 @@ struct machdep_calls __initdata pSeries_md = { .pcibios_fixup = pSeries_final_fixup, .pci_probe_mode = pSeries_pci_probe_mode, .irq_bus_setup = pSeries_irq_bus_setup, - .restart = rtas_restart, - .power_off = rtas_power_off, - .halt = rtas_halt, + .restart = rtas_fw_restart, + .power_off = rtas_fw_power_off, + .halt = rtas_fw_halt, .panic = rtas_os_term, .cpu_die = pSeries_mach_cpu_die, .get_boot_time = rtas_get_boot_time, diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 963f519b7713..8cc73cc1b4c4 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -318,6 +318,11 @@ config PPC_RTAS depends on PPC_PSERIES || PPC_BPA default y +config RTAS_ERROR_LOGGING + bool + depends on PPC_RTAS + default y + config RTAS_PROC bool "Proc interface to RTAS" depends on PPC_RTAS diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 2c541c6652b2..83ecefdcfef7 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_MODULES) += module.o ifneq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_MODULES) += ppc_ksyms.o endif -obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o +obj-$(CONFIG_PPC_RTAS) += rtas_pci.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_LPARCFG) += lparcfg.o From 03501dab035ab7da5e1373f5e130cfd6346d3f21 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 17:11:18 +1000 Subject: [PATCH 0478/1940] powerpc: Pull common bits of setup_{32,64}.c into setup-common.c This creates a new arch/powerpc/kernel/setup-common.c with various bits that setup_32.c and setup_64.c had in common - functions like machine_shutdown/restart/power_off, show_cpuinfo, set_preferred_console etc. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/ppc_ksyms.c | 2 - arch/powerpc/kernel/setup-common.c | 412 +++++++++++++++++++++++++++++ arch/powerpc/kernel/setup_32.c | 249 +---------------- 4 files changed, 417 insertions(+), 248 deletions(-) create mode 100644 arch/powerpc/kernel/setup-common.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index eaedb7e63315..30101762f7c0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -32,7 +32,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ - prom.o systbl.o traps.o + prom.o systbl.o traps.o setup-common.o obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += setup_64.o misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 254bf9c0b5bb..5f3a12bb8961 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -231,7 +230,6 @@ EXPORT_SYMBOL(screen_info); #endif #ifdef CONFIG_PPC32 -EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c new file mode 100644 index 000000000000..d4f0a4c3b5bc --- /dev/null +++ b/arch/powerpc/kernel/setup-common.c @@ -0,0 +1,412 @@ +/* + * Common boot and setup code for both 32-bit and 64-bit. + * Extracted from arch/powerpc/kernel/setup_64.c. + * + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) +#endif + +/* + * This still seems to be needed... -- paulus + */ +struct screen_info screen_info = { + .orig_x = 0, + .orig_y = 25, + .orig_video_cols = 80, + .orig_video_lines = 25, + .orig_video_isVGA = 1, + .orig_video_points = 16 +}; + +#ifdef __DO_IRQ_CANON +/* XXX should go elsewhere eventually */ +int ppc_do_canonicalize_irqs; +EXPORT_SYMBOL(ppc_do_canonicalize_irqs); +#endif + +/* also used by kexec */ +void machine_shutdown(void) +{ + if (ppc_md.nvram_sync) + ppc_md.nvram_sync(); +} + +void machine_restart(char *cmd) +{ + machine_shutdown(); + ppc_md.restart(cmd); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} + +void machine_power_off(void) +{ + machine_shutdown(); + ppc_md.power_off(); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} +/* Used by the G5 thermal driver */ +EXPORT_SYMBOL_GPL(machine_power_off); + +void (*pm_power_off)(void) = machine_power_off; +EXPORT_SYMBOL_GPL(pm_power_off); + +void machine_halt(void) +{ + machine_shutdown(); + ppc_md.halt(); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk(KERN_EMERG "System Halted, OK to turn off power\n"); + local_irq_disable(); + while (1) ; +} + + +#ifdef CONFIG_TAU +extern u32 cpu_temp(unsigned long cpu); +extern u32 cpu_temp_both(unsigned long cpu); +#endif /* CONFIG_TAU */ + +#ifdef CONFIG_SMP +DEFINE_PER_CPU(unsigned int, pvr); +#endif + +static int show_cpuinfo(struct seq_file *m, void *v) +{ + unsigned long cpu_id = (unsigned long)v - 1; + unsigned int pvr; + unsigned short maj; + unsigned short min; + + if (cpu_id == NR_CPUS) { +#if defined(CONFIG_SMP) && defined(CONFIG_PPC32) + unsigned long bogosum = 0; + int i; + for (i = 0; i < NR_CPUS; ++i) + if (cpu_online(i)) + bogosum += loops_per_jiffy; + seq_printf(m, "total bogomips\t: %lu.%02lu\n", + bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); +#endif /* CONFIG_SMP && CONFIG_PPC32 */ + seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); + + if (ppc_md.show_cpuinfo != NULL) + ppc_md.show_cpuinfo(m); + + return 0; + } + + /* We only show online cpus: disable preempt (overzealous, I + * knew) to prevent cpu going down. */ + preempt_disable(); + if (!cpu_online(cpu_id)) { + preempt_enable(); + return 0; + } + +#ifdef CONFIG_SMP +#ifdef CONFIG_PPC64 /* XXX for now */ + pvr = per_cpu(pvr, cpu_id); +#else + pvr = cpu_data[cpu_id].pvr; +#endif +#else + pvr = mfspr(SPRN_PVR); +#endif + maj = (pvr >> 8) & 0xFF; + min = pvr & 0xFF; + + seq_printf(m, "processor\t: %lu\n", cpu_id); + seq_printf(m, "cpu\t\t: "); + + if (cur_cpu_spec->pvr_mask) + seq_printf(m, "%s", cur_cpu_spec->cpu_name); + else + seq_printf(m, "unknown (%08x)", pvr); + +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + seq_printf(m, ", altivec supported"); +#endif /* CONFIG_ALTIVEC */ + + seq_printf(m, "\n"); + +#ifdef CONFIG_TAU + if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { +#ifdef CONFIG_TAU_AVERAGE + /* more straightforward, but potentially misleading */ + seq_printf(m, "temperature \t: %u C (uncalibrated)\n", + cpu_temp(i)); +#else + /* show the actual temp sensor range */ + u32 temp; + temp = cpu_temp_both(i); + seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", + temp & 0xff, temp >> 16); +#endif + } +#endif /* CONFIG_TAU */ + + /* + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ + if (ppc_proc_freq) + seq_printf(m, "clock\t\t: %lu.%06luMHz\n", + ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); + + if (ppc_md.show_percpuinfo != NULL) + ppc_md.show_percpuinfo(m, cpu_id); + + /* If we are a Freescale core do a simple check so + * we dont have to keep adding cases in the future */ + if (PVR_VER(pvr) & 0x8000) { + maj = PVR_MAJ(pvr); + min = PVR_MIN(pvr); + } else { + switch (PVR_VER(pvr)) { + case 0x0020: /* 403 family */ + maj = PVR_MAJ(pvr) + 1; + min = PVR_MIN(pvr); + break; + case 0x1008: /* 740P/750P ?? */ + maj = ((pvr >> 8) & 0xFF) - 1; + min = pvr & 0xFF; + break; + default: + maj = (pvr >> 8) & 0xFF; + min = pvr & 0xFF; + break; + } + } + + seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", + maj, min, PVR_VER(pvr), PVR_REV(pvr)); + +#ifdef CONFIG_PPC32 + seq_printf(m, "bogomips\t: %lu.%02lu\n", + loops_per_jiffy / (500000/HZ), + (loops_per_jiffy / (5000/HZ)) % 100); +#endif + +#ifdef CONFIG_SMP + seq_printf(m, "\n"); +#endif + + preempt_enable(); + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + unsigned long i = *pos; + + return i <= NR_CPUS ? (void *)(i + 1) : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start =c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; + +#ifdef CONFIG_PPC_MULTIPLATFORM +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout = NULL; + char *name; + u32 *spd; + int offset = 0; + + DBG(" -> set_preferred_console()\n"); + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) { + DBG(" console was specified !\n"); + return -EBUSY; + } + + if (!of_chosen) { + DBG(" of_chosen is NULL !\n"); + return -ENODEV; + } + /* We are getting a weird phandle from OF ... */ + /* ... So use the full path instead */ + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + if (name == NULL) { + DBG(" no linux,stdout-path !\n"); + return -ENODEV; + } + prom_stdout = of_find_node_by_path(name); + if (!prom_stdout) { + DBG(" can't find stdout package %s !\n", name); + return -ENODEV; + } + DBG("stdout is %s\n", prom_stdout->full_name); + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) { + DBG(" stdout package has no name !\n"); + goto not_found; + } + spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); + + if (0) + ; +#ifdef CONFIG_SERIAL_8250_CONSOLE + else if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + goto not_found; + } + } + } +#endif /* CONFIG_SERIAL_8250_CONSOLE */ +#ifdef CONFIG_PPC_PSERIES + else if (strcmp(name, "vty") == 0) { + u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); + char *compat = (char *)get_property(prom_stdout, "compatible", NULL); + + if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { + /* Host Virtual Serial Interface */ + int offset; + switch (reg[0]) { + case 0x30000000: + offset = 0; + break; + case 0x30000001: + offset = 1; + break; + default: + goto not_found; + } + of_node_put(prom_stdout); + DBG("Found hvsi console at offset %d\n", offset); + return add_preferred_console("hvsi", offset, NULL); + } else { + /* pSeries LPAR virtual console */ + of_node_put(prom_stdout); + DBG("Found hvc console\n"); + return add_preferred_console("hvc", 0, NULL); + } + } +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE + else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; +#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ + else + goto not_found; + of_node_put(prom_stdout); + + DBG("Found serial console at ttyS%d\n", offset); + + if (spd) { + static char __initdata opt[16]; + sprintf(opt, "%d", *spd); + return add_preferred_console("ttyS", offset, opt); + } else + return add_preferred_console("ttyS", offset, NULL); + + not_found: + DBG("No preferred console found !\n"); + of_node_put(prom_stdout); + return -ENODEV; +} +console_initcall(set_preferred_console); +#endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c6a67c65852a..295d5c77f020 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -41,6 +41,8 @@ #include #include +#define DBG(fmt...) + #if defined CONFIG_KGDB #include #endif @@ -108,168 +110,6 @@ struct screen_info screen_info = { }; #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ -void machine_restart(char *cmd) -{ -#ifdef CONFIG_NVRAM - nvram_sync(); -#endif - ppc_md.restart(cmd); -} - -void machine_power_off(void) -{ -#ifdef CONFIG_NVRAM - nvram_sync(); -#endif - ppc_md.power_off(); -} - -void machine_halt(void) -{ -#ifdef CONFIG_NVRAM - nvram_sync(); -#endif - ppc_md.halt(); -} - -void (*pm_power_off)(void) = machine_power_off; - -#ifdef CONFIG_TAU -extern u32 cpu_temp(unsigned long cpu); -extern u32 cpu_temp_both(unsigned long cpu); -#endif /* CONFIG_TAU */ - -int show_cpuinfo(struct seq_file *m, void *v) -{ - int i = (int) v - 1; - unsigned int pvr; - unsigned short maj, min; - unsigned long lpj; - - if (i >= NR_CPUS) { - /* Show summary information */ -#ifdef CONFIG_SMP - unsigned long bogosum = 0; - for (i = 0; i < NR_CPUS; ++i) - if (cpu_online(i)) - bogosum += cpu_data[i].loops_per_jiffy; - seq_printf(m, "total bogomips\t: %lu.%02lu\n", - bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); -#endif /* CONFIG_SMP */ - - if (ppc_md.show_cpuinfo != NULL) - ppc_md.show_cpuinfo(m); - return 0; - } - -#ifdef CONFIG_SMP - if (!cpu_online(i)) - return 0; - pvr = cpu_data[i].pvr; - lpj = cpu_data[i].loops_per_jiffy; -#else - pvr = mfspr(SPRN_PVR); - lpj = loops_per_jiffy; -#endif - - seq_printf(m, "processor\t: %d\n", i); - seq_printf(m, "cpu\t\t: "); - - if (cur_cpu_spec->pvr_mask) - seq_printf(m, "%s", cur_cpu_spec->cpu_name); - else - seq_printf(m, "unknown (%08x)", pvr); -#ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) - seq_printf(m, ", altivec supported"); -#endif - seq_printf(m, "\n"); - -#ifdef CONFIG_TAU - if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { -#ifdef CONFIG_TAU_AVERAGE - /* more straightforward, but potentially misleading */ - seq_printf(m, "temperature \t: %u C (uncalibrated)\n", - cpu_temp(i)); -#else - /* show the actual temp sensor range */ - u32 temp; - temp = cpu_temp_both(i); - seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", - temp & 0xff, temp >> 16); -#endif - } -#endif /* CONFIG_TAU */ - - if (ppc_md.show_percpuinfo != NULL) - ppc_md.show_percpuinfo(m, i); - - /* If we are a Freescale core do a simple check so - * we dont have to keep adding cases in the future */ - if (PVR_VER(pvr) & 0x8000) { - maj = PVR_MAJ(pvr); - min = PVR_MIN(pvr); - } else { - switch (PVR_VER(pvr)) { - case 0x0020: /* 403 family */ - maj = PVR_MAJ(pvr) + 1; - min = PVR_MIN(pvr); - break; - case 0x1008: /* 740P/750P ?? */ - maj = ((pvr >> 8) & 0xFF) - 1; - min = pvr & 0xFF; - break; - default: - maj = (pvr >> 8) & 0xFF; - min = pvr & 0xFF; - break; - } - } - - /* - * Assume here that all clock rates are the same in a - * smp system. -- Cort - */ - seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, - ppc_proc_freq % 1000000); - - seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", - maj, min, PVR_VER(pvr), PVR_REV(pvr)); - - seq_printf(m, "bogomips\t: %lu.%02lu\n", - lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); - -#ifdef CONFIG_SMP - seq_printf(m, "\n"); -#endif - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - int i = *pos; - - return i <= NR_CPUS? (void *) (i + 1): NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -struct seq_operations cpuinfo_op = { - .start =c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - /* * We're called here very early in the boot. We determine the machine * type and call the appropriate low-level setup functions. @@ -297,30 +137,6 @@ unsigned long __init early_init(unsigned long dt_ptr) return KERNELBASE + offset; } -#ifdef CONFIG_PPC_OF -void __init -intuit_machine_type(void) -{ - char *model; - struct device_node *root; - - /* ask the OF info if we're a chrp or pmac */ - root = find_path_device("/"); - if (root != 0) { - /* assume pmac unless proven to be chrp -- Cort */ - _machine = _MACH_Pmac; - model = get_property(root, "device_type", NULL); - if (model && !strncmp("chrp", model, 4)) - _machine = _MACH_chrp; - else { - model = get_property(root, "model", NULL); - if (model && !strncmp(model, "IBM", 3)) - _machine = _MACH_chrp; - } - } -} -#endif - #ifdef CONFIG_PPC_MULTIPLATFORM /* * The PPC_MULTIPLATFORM version of platform_init... @@ -362,64 +178,7 @@ void __init platform_init(void) #endif } } - -#ifdef CONFIG_SERIAL_CORE_CONSOLE -extern char *of_stdout_device; - -static int __init set_preferred_console(void) -{ - struct device_node *prom_stdout; - char *name; - int offset = 0; - - if (of_stdout_device == NULL) - return -ENODEV; - - /* The user has requested a console so this is already set up. */ - if (strstr(saved_command_line, "console=")) - return -EBUSY; - - prom_stdout = find_path_device(of_stdout_device); - if (!prom_stdout) - return -ENODEV; - - name = (char *)get_property(prom_stdout, "name", NULL); - if (!name) - return -ENODEV; - - if (strcmp(name, "serial") == 0) { - int i; - u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); - if (i > 8) { - switch (reg[1]) { - case 0x3f8: - offset = 0; - break; - case 0x2f8: - offset = 1; - break; - case 0x898: - offset = 2; - break; - case 0x890: - offset = 3; - break; - default: - /* We dont recognise the serial port */ - return -ENODEV; - } - } - } else if (strcmp(name, "ch-a") == 0) - offset = 0; - else if (strcmp(name, "ch-b") == 0) - offset = 1; - else - return -ENODEV; - return add_preferred_console("ttyS", offset, NULL); -} -console_initcall(set_preferred_console); -#endif /* CONFIG_SERIAL_CORE_CONSOLE */ -#endif /* CONFIG_PPC_MULTIPLATFORM */ +#endif /* * Find out what kind of machine we're on and save any data we need @@ -545,7 +304,7 @@ void __init setup_arch(char **cmdline_p) init_boot_display(); #endif -#ifdef CONFIG_PPC_MULTIPLATFORM +#ifdef CONFIG_PPC_PMAC /* This could be called "early setup arch", it must be done * now because xmon need it */ From 830825d6c37a28061c0b6ca538a6411001cf3b2a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 17:16:38 +1000 Subject: [PATCH 0479/1940] powerpc: Pull out MPC106 (grackle) initialization code into its own file This is so that the 32-bit CHRP code can use it. The MPC106 initialization code is now in arch/powerpc/sysdev/grackle.c and is controlled by CONFIG_PPC_MPC106. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 5 +++ arch/powerpc/platforms/powermac/pci.c | 45 +------------------ arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/grackle.c | 64 +++++++++++++++++++++++++++ include/asm-powerpc/grackle.h | 7 +++ 5 files changed, 78 insertions(+), 44 deletions(-) create mode 100644 arch/powerpc/sysdev/grackle.c create mode 100644 include/asm-powerpc/grackle.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index ce5100cadd34..964ded4a757f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -286,6 +286,7 @@ config PPC_CHRP select PPC_I8259 select PPC_INDIRECT_PCI select PPC_RTAS + select PPC_MPC106 default y config PPC_PMAC @@ -366,6 +367,10 @@ config IBMVIO bool default y +config PPC_MPC106 + bool + default n + source "drivers/cpufreq/Kconfig" config CPU_FREQ_PMAC diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ebe22a2267d2..8f818d092e2b 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include #include @@ -584,50 +585,6 @@ static void __init fixup_nec_usb2(void) } } -#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ - | (((o) & ~3) << 24)) - -#define GRACKLE_PICR1_STG 0x00000040 -#define GRACKLE_PICR1_LOOPSNOOP 0x00000010 - -/* N.B. this is called before bridges is initialized, so we can't - use grackle_pcibios_{read,write}_config_dword. */ -static inline void grackle_set_stg(struct pci_controller* bp, int enable) -{ - unsigned int val; - - out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); - val = in_le32(bp->cfg_data); - val = enable? (val | GRACKLE_PICR1_STG) : - (val & ~GRACKLE_PICR1_STG); - out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); - out_le32(bp->cfg_data, val); - (void)in_le32(bp->cfg_data); -} - -static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) -{ - unsigned int val; - - out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); - val = in_le32(bp->cfg_data); - val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) : - (val & ~GRACKLE_PICR1_LOOPSNOOP); - out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); - out_le32(bp->cfg_data, val); - (void)in_le32(bp->cfg_data); -} - -void __init setup_grackle(struct pci_controller *hose) -{ - setup_indirect_pci(hose, 0xfec00000, 0xfee00000); - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(hose, 1); -#if 0 /* Disabled for now, HW problems ??? */ - grackle_set_stg(hose, 1); -#endif -} - static void __init setup_bandit(struct pci_controller *hose, struct reg_property *addr) { diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index f3c9e61c3910..97119c0ffc72 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o +obj-$(CONFIG_PPC_MPC106) += grackle.o diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c new file mode 100644 index 000000000000..b6ec793a23be --- /dev/null +++ b/arch/powerpc/sysdev/grackle.c @@ -0,0 +1,64 @@ +/* + * Functions for setting up and using a MPC106 northbridge + * Extracted from arch/powerpc/platforms/powermac/pci.c. + * + * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) + * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) + * + * 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. + */ +#include +#include +#include + +#include +#include +#include +#include + +#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ + | (((o) & ~3) << 24)) + +#define GRACKLE_PICR1_STG 0x00000040 +#define GRACKLE_PICR1_LOOPSNOOP 0x00000010 + +/* N.B. this is called before bridges is initialized, so we can't + use grackle_pcibios_{read,write}_config_dword. */ +static inline void grackle_set_stg(struct pci_controller* bp, int enable) +{ + unsigned int val; + + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + val = in_le32(bp->cfg_data); + val = enable? (val | GRACKLE_PICR1_STG) : + (val & ~GRACKLE_PICR1_STG); + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + out_le32(bp->cfg_data, val); + (void)in_le32(bp->cfg_data); +} + +static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) +{ + unsigned int val; + + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + val = in_le32(bp->cfg_data); + val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) : + (val & ~GRACKLE_PICR1_LOOPSNOOP); + out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); + out_le32(bp->cfg_data, val); + (void)in_le32(bp->cfg_data); +} + +void __init setup_grackle(struct pci_controller *hose) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif +} diff --git a/include/asm-powerpc/grackle.h b/include/asm-powerpc/grackle.h new file mode 100644 index 000000000000..563c7a5e64c9 --- /dev/null +++ b/include/asm-powerpc/grackle.h @@ -0,0 +1,7 @@ +/* + * Functions for setting up and using a MPC106 northbridge + */ + +#include + +extern void setup_grackle(struct pci_controller *hose); From 6d0124fc06be40deafca043c73a8203c78bbfe45 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 17:19:06 +1000 Subject: [PATCH 0480/1940] powerpc: Fix interrupt-tree parsing The interrupt-tree parsing code wasn't offsetting interrupt numbers by 16 on 32-bit platforms with an i8259 interrupt controller, and it was confused about the encoding of interrupt sense and level (which is different for i8259 and openpic interrupt controllers, just to make things interesting). Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 40 +++++++++++++++++++++++++------------- include/asm-powerpc/irq.h | 2 ++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 16ac15e73b44..ab9b291dda54 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -296,13 +296,28 @@ static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictr return nintrc; } +static unsigned char map_isa_senses[4] = { + IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, + IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, + IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, + IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE +}; + +static unsigned char map_mpic_senses[4] = { + IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE, + IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, + /* 2 seems to be used for the 8259 cascade... */ + IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, + IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, +}; + static int __devinit finish_node_interrupts(struct device_node *np, unsigned long *mem_start, int measure_only) { unsigned int *ints; int intlen, intrcells, intrcount; - int i, j, n; + int i, j, n, sense; unsigned int *irq, virq; struct device_node *ic; @@ -332,7 +347,8 @@ static int __devinit finish_node_interrupts(struct device_node *np, for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ints++; - np->intrs[i].sense = 1; + np->intrs[i].sense = IRQ_SENSE_LEVEL + | IRQ_POLARITY_NEGATIVE; } return 0; } @@ -359,19 +375,20 @@ static int __devinit finish_node_interrupts(struct device_node *np, /* don't map IRQ numbers under a cascaded 8259 controller */ if (ic && device_is_compatible(ic, "chrp,iic")) { np->intrs[intrcount].line = irq[0]; + sense = (n > 1)? (irq[1] & 3): 3; + np->intrs[intrcount].sense = map_isa_senses[sense]; } else { -#ifdef CONFIG_PPC64 virq = virt_irq_create_mapping(irq[0]); +#ifdef CONFIG_PPC64 if (virq == NO_IRQ) { printk(KERN_CRIT "Could not allocate interrupt" " number for %s\n", np->full_name); continue; } - virq = irq_offset_up(virq); -#else - virq = irq[0]; #endif - np->intrs[intrcount].line = virq; + np->intrs[intrcount].line = irq_offset_up(virq); + sense = (n > 1)? (irq[1] & 3): 1; + np->intrs[intrcount].sense = map_mpic_senses[sense]; } #ifdef CONFIG_PPC64 @@ -386,9 +403,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, break; } #endif - np->intrs[intrcount].sense = 1; - if (n > 1) - np->intrs[intrcount].sense = irq[1]; if (n > 2) { printk("hmmm, got %d intr cells for %s:", n, np->full_name); @@ -1401,15 +1415,13 @@ void __init prom_get_irq_senses(unsigned char *senses, int off, int max) int i, j; /* default to level-triggered */ - memset(senses, 1, max - off); + memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off); for (np = allnodes; np != 0; np = np->allnext) { for (j = 0; j < np->n_intrs; j++) { i = np->intrs[j].line; if (i >= off && i < max) - senses[i-off] = np->intrs[j].sense ? - IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE : - IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE; + senses[i-off] = np->intrs[j].sense; } } } diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 07c2b3fc4c66..c7c3f912a3c2 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h @@ -432,6 +432,8 @@ extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; extern atomic_t ppc_n_lost_interrupts; +#define virt_irq_create_mapping(x) (x) + #endif /* From 303d72a0006c65bb8d16199c75a26338ce723811 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 17:22:33 +1000 Subject: [PATCH 0481/1940] powerpc: Don't limit pmac_get_rtc_time to return only positive values If the machine's clock is set to a bogus value, this check resulted in userland waiting effectively forever for the RTC value to change, so remove the check. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/time.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 82982bf6453c..5947b21a8588 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -113,8 +113,6 @@ static unsigned long cuda_get_time(void) req.reply_len); now = (req.reply[3] << 24) + (req.reply[4] << 16) + (req.reply[5] << 8) + req.reply[6]; - if (now < RTC_OFFSET) - return 0; return now - RTC_OFFSET; } @@ -158,8 +156,6 @@ static unsigned long pmu_get_time(void) req.reply_len); now = (req.reply[0] << 24) + (req.reply[1] << 16) + (req.reply[2] << 8) + req.reply[3]; - if (now < RTC_OFFSET) - return 0; return now - RTC_OFFSET; } From bbd0abda9cc689a54df509aae00000bbb2a1a7d1 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 21:45:56 +1000 Subject: [PATCH 0482/1940] powerpc: Merge 32-bit CHRP support. SMP still needs more work but UP gets as far as starting userspace at least. This uses the 64-bit-style code for spinning up the cpus. Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 2 +- arch/powerpc/kernel/head_32.S | 9 +- arch/powerpc/kernel/prom_init.c | 54 +-- arch/powerpc/kernel/setup_32.c | 4 + arch/powerpc/platforms/Makefile | 1 + arch/powerpc/platforms/chrp/Makefile | 3 + arch/powerpc/platforms/chrp/pci.c | 310 +++++++++++++ arch/powerpc/platforms/chrp/pegasos_eth.c | 101 +++++ arch/powerpc/platforms/chrp/setup.c | 523 ++++++++++++++++++++++ arch/powerpc/platforms/chrp/smp.c | 94 ++++ arch/powerpc/platforms/chrp/time.c | 188 ++++++++ arch/powerpc/platforms/powermac/pic.c | 4 - 12 files changed, 1256 insertions(+), 37 deletions(-) create mode 100644 arch/powerpc/platforms/chrp/Makefile create mode 100644 arch/powerpc/platforms/chrp/pci.c create mode 100644 arch/powerpc/platforms/chrp/pegasos_eth.c create mode 100644 arch/powerpc/platforms/chrp/setup.c create mode 100644 arch/powerpc/platforms/chrp/smp.c create mode 100644 arch/powerpc/platforms/chrp/time.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 964ded4a757f..9589d621edc5 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -339,7 +339,7 @@ config U3_DART default n config MPIC - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP bool default y diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index cd51fe585fcd..f8673f7b2b2d 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -207,7 +207,7 @@ turn_on_mmu: .globl __secondary_hold __secondary_hold: /* tell the master we're here */ - stw r3,4(0) + stw r3,__secondary_hold_acknowledge@l(0) #ifdef CONFIG_SMP 100: lwz r4,0(0) /* wait until we're told to start */ @@ -220,6 +220,13 @@ __secondary_hold: b . #endif /* CONFIG_SMP */ + .globl __secondary_hold_spinloop +__secondary_hold_spinloop: + .long 0 + .globl __secondary_hold_acknowledge +__secondary_hold_acknowledge: + .long -1 + /* * Exception entry code. This code runs with address translation * turned off, i.e. using physical addresses. diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 18d266d8935d..debe9734636e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1155,9 +1155,18 @@ static void __init prom_initialize_tce_table(void) * * -- Cort */ +extern void __secondary_hold(void); +extern unsigned long __secondary_hold_spinloop; +extern unsigned long __secondary_hold_acknowledge; + +/* + * We want to reference the copy of __secondary_hold_* in the + * 0 - 0x100 address range + */ +#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff) + static void __init prom_hold_cpus(void) { -#ifdef CONFIG_PPC64 unsigned long i; unsigned int reg; phandle node; @@ -1166,20 +1175,18 @@ static void __init prom_hold_cpus(void) unsigned int interrupt_server[MAX_CPU_THREADS]; unsigned int cpu_threads, hw_cpu_num; int propsize; - extern void __secondary_hold(void); - extern unsigned long __secondary_hold_spinloop; - extern unsigned long __secondary_hold_acknowledge; + struct prom_t *_prom = &RELOC(prom); unsigned long *spinloop - = (void *) __pa(&__secondary_hold_spinloop); + = (void *) LOW_ADDR(__secondary_hold_spinloop); unsigned long *acknowledge - = (void *) __pa(&__secondary_hold_acknowledge); + = (void *) LOW_ADDR(__secondary_hold_acknowledge); #ifdef CONFIG_PPC64 + /* __secondary_hold is actually a descriptor, not the text address */ unsigned long secondary_hold = __pa(*PTRRELOC((unsigned long *)__secondary_hold)); #else - unsigned long secondary_hold = __pa(&__secondary_hold); + unsigned long secondary_hold = LOW_ADDR(__secondary_hold); #endif - struct prom_t *_prom = &RELOC(prom); prom_debug("prom_hold_cpus: start...\n"); prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); @@ -1197,9 +1204,8 @@ static void __init prom_hold_cpus(void) *spinloop = 0; #ifdef CONFIG_HMT - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; i < NR_CPUS; i++) RELOC(hmt_thread_data)[i].pir = 0xdeadbeef; - } #endif /* look for cpus */ for (node = 0; prom_next_node(&node); ) { @@ -1250,34 +1256,22 @@ static void __init prom_hold_cpus(void) call_prom("start-cpu", 3, 0, node, secondary_hold, reg); - for ( i = 0 ; (i < 100000000) && - (*acknowledge == ((unsigned long)-1)); i++ ) + for (i = 0; (i < 100000000) && + (*acknowledge == ((unsigned long)-1)); i++ ) mb(); - if (*acknowledge == reg) { + if (*acknowledge == reg) prom_printf("done\n"); - /* We have to get every CPU out of OF, - * even if we never start it. */ - if (cpuid >= NR_CPUS) - goto next; - } else { + else prom_printf("failed: %x\n", *acknowledge); - } } #ifdef CONFIG_SMP else prom_printf("%x : boot cpu %x\n", cpuid, reg); -#endif -next: -#ifdef CONFIG_SMP - /* Init paca for secondary threads. They start later. */ - for (i=1; i < cpu_threads; i++) { - cpuid++; - if (cpuid >= NR_CPUS) - continue; - } #endif /* CONFIG_SMP */ - cpuid++; + + /* Reserve cpu #s for secondary threads. They start later. */ + cpuid += cpu_threads; } #ifdef CONFIG_HMT /* Only enable HMT on processors that provide support. */ @@ -1311,7 +1305,6 @@ static void __init prom_hold_cpus(void) ") exceeded: ignoring extras\n"); prom_debug("prom_hold_cpus: end...\n"); -#endif } @@ -1940,7 +1933,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long r6, unsigned long r7) { struct prom_t *_prom; - extern char _stext[]; unsigned long hdr; u32 getprop_rval; unsigned long offset = reloc_offset(); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 295d5c77f020..0cac112ca89d 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -56,6 +56,10 @@ extern void power4_idle(void); boot_infos_t *boot_infos; struct ide_machdep_calls ppc_ide_md; +/* XXX should go elsewhere */ +int __irq_offset_value; +EXPORT_SYMBOL(__irq_offset_value); + /* Used with the BI_MEMSIZE bootinfo parameter to store the memory size value reported by the boot loader. */ unsigned long boot_mem_size; diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 509622da5408..01723d491b5d 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -5,6 +5,7 @@ ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif endif +obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_85xx) += 85xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile new file mode 100644 index 000000000000..1fde4e68414f --- /dev/null +++ b/arch/powerpc/platforms/chrp/Makefile @@ -0,0 +1,3 @@ +obj-y += setup.o time.o pegasos_eth.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_SMP) += smp.o diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c new file mode 100644 index 000000000000..82c429d487f3 --- /dev/null +++ b/arch/powerpc/platforms/chrp/pci.c @@ -0,0 +1,310 @@ +/* + * CHRP pci routines. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LongTrail */ +void __iomem *gg2_pci_config_base; + +/* + * The VLSI Golden Gate II has only 512K of PCI configuration space, so we + * limit the bus number to 3 bits + */ + +int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 *val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + *val = in_8(cfg_data); + break; + case 2: + *val = in_le16(cfg_data); + break; + default: + *val = in_le32(cfg_data); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + out_8(cfg_data, val); + break; + case 2: + out_le16(cfg_data, val); + break; + default: + out_le32(cfg_data, val); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops gg2_pci_ops = +{ + gg2_read_config, + gg2_write_config +}; + +/* + * Access functions for PCI config space using RTAS calls. + */ +int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int ret = -1; + int rval; + + rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); + *val = ret; + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int rval; + + rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, + addr, len, val); + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rtas_pci_ops = +{ + rtas_read_config, + rtas_write_config +}; + +volatile struct Hydra __iomem *Hydra = NULL; + +int __init +hydra_init(void) +{ + struct device_node *np; + + np = find_devices("mac-io"); + if (np == NULL || np->n_addrs == 0) + return 0; + Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); + printk("Hydra Mac I/O at %lx\n", np->addrs[0].address); + printk("Hydra Feature_Control was %x", + in_le32(&Hydra->Feature_Control)); + out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | + HYDRA_FC_SCSI_CELL_EN | + HYDRA_FC_SCCA_ENABLE | + HYDRA_FC_SCCB_ENABLE | + HYDRA_FC_ARB_BYPASS | + HYDRA_FC_MPIC_ENABLE | + HYDRA_FC_SLOW_SCC_PCLK | + HYDRA_FC_MPIC_IS_MASTER)); + printk(", now %x\n", in_le32(&Hydra->Feature_Control)); + return 1; +} + +void __init +chrp_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + struct device_node *np; + + /* PCI interrupts are controlled by the OpenPIC */ + for_each_pci_dev(dev) { + np = pci_device_to_OF_node(dev); + if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) + dev->irq = np->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +#define PRG_CL_RESET_VALID 0x00010000 + +static void __init +setup_python(struct pci_controller *hose, struct device_node *dev) +{ + u32 __iomem *reg; + u32 val; + unsigned long addr = dev->addrs[0].address; + + setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010); + + /* Clear the magic go-slow bit */ + reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40); + val = in_be32(®[12]); + if (val & PRG_CL_RESET_VALID) { + out_be32(®[12], val & ~PRG_CL_RESET_VALID); + in_be32(®[12]); + } + iounmap(reg); +} + +/* Marvell Discovery II based Pegasos 2 */ +static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev) +{ + struct device_node *root = find_path_device("/"); + struct device_node *rtas; + + rtas = of_find_node_by_name (root, "rtas"); + if (rtas) { + hose->ops = &rtas_pci_ops; + } else { + printk ("RTAS supporting Pegasos OF not found, please upgrade" + " your firmware\n"); + } + pci_assign_all_buses = 1; +} + +void __init +chrp_find_bridges(void) +{ + struct device_node *dev; + int *bus_range; + int len, index = -1; + struct pci_controller *hose; + unsigned int *dma; + char *model, *machine; + int is_longtrail = 0, is_mot = 0, is_pegasos = 0; + struct device_node *root = find_path_device("/"); + + /* + * The PCI host bridge nodes on some machines don't have + * properties to adequately identify them, so we have to + * look at what sort of machine this is as well. + */ + machine = get_property(root, "model", NULL); + if (machine != NULL) { + is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; + is_mot = strncmp(machine, "MOT", 3) == 0; + if (strncmp(machine, "Pegasos2", 8) == 0) + is_pegasos = 2; + else if (strncmp(machine, "Pegasos", 7) == 0) + is_pegasos = 1; + } + for (dev = root->child; dev != NULL; dev = dev->sibling) { + if (dev->type == NULL || strcmp(dev->type, "pci") != 0) + continue; + ++index; + /* The GG2 bridge on the LongTrail doesn't have an address */ + if (dev->n_addrs < 1 && !is_longtrail) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s", dev->type); + if (dev->n_addrs > 0) + printk(" at %lx", dev->addrs[0].address); + printk("\n"); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + + model = get_property(dev, "model", NULL); + if (model == NULL) + model = ""; + if (device_is_compatible(dev, "IBM,python")) { + setup_python(hose, dev); + } else if (is_mot + || strncmp(model, "Motorola, Grackle", 17) == 0) { + setup_grackle(hose); + } else if (is_longtrail) { + void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); + hose->ops = &gg2_pci_ops; + hose->cfg_data = p; + gg2_pci_config_base = p; + } else if (is_pegasos == 1) { + setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); + } else if (is_pegasos == 2) { + setup_peg2(hose, dev); + } else { + printk("No methods for %s (model %s), using RTAS\n", + dev->full_name, model); + hose->ops = &rtas_pci_ops; + } + + pci_process_bridge_OF_ranges(hose, dev, index == 0); + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } + + /* Do not fixup interrupts from OF tree on pegasos */ + if (is_pegasos == 0) + ppc_md.pcibios_fixup = chrp_pcibios_fixup; +} diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c new file mode 100644 index 000000000000..cad5bfa153b2 --- /dev/null +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -0,0 +1,101 @@ +/* + * arch/ppc/platforms/chrp_pegasos_eth.c + * + * Copyright (C) 2005 Sven Luther + * Thanks to : + * Dale Farnsworth + * Mark A. Greer + * Nicolas DET + * Benjamin Herrenschmidt + * And anyone else who helped me on this. + */ + +#include +#include +#include +#include +#include +#include + +/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */ +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +static struct resource mv643xx_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth0_pd; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth0_resources), + .resource = mv643xx_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; + +static struct resource mv643xx_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth1_pd; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv643xx_eth1_resources), + .resource = mv643xx_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, + ð0_device, + ð1_device, +}; + + +int +mv643xx_eth_add_pds(void) +{ + int ret = 0; + static struct pci_device_id pci_marvell_mv64360[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, + { } + }; + + if (pci_dev_present(pci_marvell_mv64360)) { + ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs)); + } + return ret; +} +device_initcall(mv643xx_eth_add_pds); diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c new file mode 100644 index 000000000000..5145990e6a01 --- /dev/null +++ b/arch/powerpc/platforms/chrp/setup.c @@ -0,0 +1,523 @@ +/* + * arch/ppc/platforms/setup.c + * + * Copyright (C) 1995 Linus Torvalds + * Adapted from 'alpha' version by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu) + */ + +/* + * bootup setup stuff.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void chrp_get_rtc_time(struct rtc_time *); +int chrp_set_rtc_time(struct rtc_time *); +void chrp_calibrate_decr(void); +long chrp_time_init(void); + +void chrp_find_bridges(void); +void chrp_event_scan(void); +void rtas_indicator_progress(char *, unsigned short); +void btext_progress(char *, unsigned short); + +int _chrp_type; +EXPORT_SYMBOL(_chrp_type); + +struct mpic *chrp_mpic; + +/* + * XXX this should be in xmon.h, but putting it there means xmon.h + * has to include (to get irqreturn_t), which + * causes all sorts of problems. -- paulus + */ +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); + +extern unsigned long loops_per_jiffy; + +#ifdef CONFIG_SMP +extern struct smp_ops_t chrp_smp_ops; +#endif + +static const char *gg2_memtypes[4] = { + "FPM", "SDRAM", "EDO", "BEDO" +}; +static const char *gg2_cachesizes[4] = { + "256 KB", "512 KB", "1 MB", "Reserved" +}; +static const char *gg2_cachetypes[4] = { + "Asynchronous", "Reserved", "Flow-Through Synchronous", + "Pipelined Synchronous" +}; +static const char *gg2_cachemodes[4] = { + "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" +}; + +void chrp_show_cpuinfo(struct seq_file *m) +{ + int i, sdramen; + unsigned int t; + struct device_node *root; + const char *model = ""; + + root = find_path_device("/"); + if (root) + model = get_property(root, "model", NULL); + seq_printf(m, "machine\t\t: CHRP %s\n", model); + + /* longtrail (goldengate) stuff */ + if (!strncmp(model, "IBM,LongTrail", 13)) { + /* VLSI VAS96011/12 `Golden Gate 2' */ + /* Memory banks */ + sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) + >>31) & 1; + for (i = 0; i < (sdramen ? 4 : 6); i++) { + t = in_le32(gg2_pci_config_base+ + GG2_PCI_DRAM_BANK0+ + i*4); + if (!(t & 1)) + continue; + switch ((t>>8) & 0x1f) { + case 0x1f: + model = "4 MB"; + break; + case 0x1e: + model = "8 MB"; + break; + case 0x1c: + model = "16 MB"; + break; + case 0x18: + model = "32 MB"; + break; + case 0x10: + model = "64 MB"; + break; + case 0x00: + model = "128 MB"; + break; + default: + model = "Reserved"; + break; + } + seq_printf(m, "memory bank %d\t: %s %s\n", i, model, + gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]); + } + /* L2 cache */ + t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL); + seq_printf(m, "board l2\t: %s %s (%s)\n", + gg2_cachesizes[(t>>7) & 3], + gg2_cachetypes[(t>>2) & 3], + gg2_cachemodes[t & 3]); + } +} + +/* + * Fixes for the National Semiconductor PC78308VUL SuperI/O + * + * Some versions of Open Firmware incorrectly initialize the IRQ settings + * for keyboard and mouse + */ +static inline void __init sio_write(u8 val, u8 index) +{ + outb(index, 0x15c); + outb(val, 0x15d); +} + +static inline u8 __init sio_read(u8 index) +{ + outb(index, 0x15c); + return inb(0x15d); +} + +static void __init sio_fixup_irq(const char *name, u8 device, u8 level, + u8 type) +{ + u8 level0, type0, active; + + /* select logical device */ + sio_write(device, 0x07); + active = sio_read(0x30); + level0 = sio_read(0x70); + type0 = sio_read(0x71); + if (level0 != level || type0 != type || !active) { + printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: " + "remapping to level %d, type %d, active\n", + name, level0, type0, !active ? "in" : "", level, type); + sio_write(0x01, 0x30); + sio_write(level, 0x70); + sio_write(type, 0x71); + } +} + +static void __init sio_init(void) +{ + struct device_node *root; + + if ((root = find_path_device("/")) && + !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) { + /* logical device 0 (KBC/Keyboard) */ + sio_fixup_irq("keyboard", 0, 1, 2); + /* select logical device 1 (KBC/Mouse) */ + sio_fixup_irq("mouse", 1, 12, 2); + } +} + + +static void __init pegasos_set_l2cr(void) +{ + struct device_node *np; + + /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */ + if (_chrp_type != _CHRP_Pegasos) + return; + + /* Enable L2 cache if needed */ + np = find_type_devices("cpu"); + if (np != NULL) { + unsigned int *l2cr = (unsigned int *) + get_property (np, "l2cr", NULL); + if (l2cr == NULL) { + printk ("Pegasos l2cr : no cpu l2cr property found\n"); + return; + } + if (!((*l2cr) & 0x80000000)) { + printk ("Pegasos l2cr : L2 cache was not active, " + "activating\n"); + _set_L2CR(0); + _set_L2CR((*l2cr) | 0x80000000); + } + } +} + +void __init chrp_setup_arch(void) +{ + struct device_node *root = find_path_device ("/"); + char *machine = NULL; + struct device_node *device; + unsigned int *p = NULL; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + if (root) + machine = get_property(root, "model", NULL); + if (machine && strncmp(machine, "Pegasos", 7) == 0) { + _chrp_type = _CHRP_Pegasos; + } else if (machine && strncmp(machine, "IBM", 3) == 0) { + _chrp_type = _CHRP_IBM; + } else if (machine && strncmp(machine, "MOT", 3) == 0) { + _chrp_type = _CHRP_Motorola; + } else { + /* Let's assume it is an IBM chrp if all else fails */ + _chrp_type = _CHRP_IBM; + } + printk("chrp type = %x\n", _chrp_type); + + rtas_initialize(); + if (rtas_token("display-character") >= 0) + ppc_md.progress = rtas_progress; + +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && boot_text_mapped) + ppc_md.progress = btext_progress; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + /* this is fine for chrp */ + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ + + /* On pegasos, enable the L2 cache if not already done by OF */ + pegasos_set_l2cr(); + + /* Lookup PCI host bridges */ + chrp_find_bridges(); + + /* + * Temporary fixes for PCI devices. + * -- Geert + */ + hydra_init(); /* Mac I/O */ + + /* + * Fix the Super I/O configuration + */ + sio_init(); + + /* Get the event scan rate for the rtas so we know how + * often it expects a heartbeat. -- Cort + */ + device = find_devices("rtas"); + if (device) + p = (unsigned int *) get_property + (device, "rtas-event-scan-rate", NULL); + if (p && *p) { + ppc_md.heartbeat = chrp_event_scan; + ppc_md.heartbeat_reset = HZ / (*p * 30) - 1; + ppc_md.heartbeat_count = 1; + printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", + *p, ppc_md.heartbeat_reset); + } + + pci_create_OF_bus_map(); + + /* + * Print the banner, then scroll down so boot progress + * can be printed. -- Cort + */ + if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); +} + +void +chrp_event_scan(void) +{ + unsigned char log[1024]; + int ret = 0; + + /* XXX: we should loop until the hardware says no more error logs -- Cort */ + rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, + __pa(log), 1024); + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; +} + +/* + * Finds the open-pic node and sets up the mpic driver. + */ +static void __init chrp_find_openpic(void) +{ + struct device_node *np, *root; + int len, i, j, irq_count; + int isu_size, idu_size; + unsigned int *iranges, *opprop = NULL; + int oplen = 0; + unsigned long opaddr; + int na = 1; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + + np = find_type_devices("open-pic"); + if (np == NULL) + return; + root = find_path_device("/"); + if (root) { + opprop = (unsigned int *) get_property + (root, "platform-open-pic", &oplen); + na = prom_n_addr_cells(root); + } + if (opprop && oplen >= na * sizeof(unsigned int)) { + opaddr = opprop[na-1]; /* assume 32-bit */ + oplen /= na * sizeof(unsigned int); + } else { + if (np->n_addrs == 0) + return; + opaddr = np->addrs[0].address; + oplen = 0; + } + + printk(KERN_INFO "OpenPIC at %lx\n", opaddr); + + irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4); + + iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + if (iranges == NULL) + len = 0; /* non-distributed mpic */ + else + len /= 2 * sizeof(unsigned int); + + /* + * The first pair of cells in interrupt-ranges refers to the + * IDU; subsequent pairs refer to the ISUs. + */ + if (oplen < len) { + printk(KERN_ERR "Insufficient addresses for distributed" + " OpenPIC (%d < %d)\n", np->n_addrs, len); + len = oplen; + } + + isu_size = 0; + idu_size = 0; + if (len > 0 && iranges[1] != 0) { + printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n", + iranges[0], iranges[0] + iranges[1] - 1); + idu_size = iranges[1]; + } + if (len > 1) + isu_size = iranges[3]; + + chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY, + isu_size, NUM_ISA_INTERRUPTS, irq_count, + NR_IRQS - 4, init_senses, irq_count, + " MPIC "); + if (chrp_mpic == NULL) { + printk(KERN_ERR "Failed to allocate MPIC structure\n"); + return; + } + + j = na - 1; + for (i = 1; i < len; ++i) { + iranges += 2; + j += na; + printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x\n", + iranges[0], iranges[0] + iranges[1] - 1, + opprop[j]); + mpic_assign_isu(chrp_mpic, i - 1, opprop[j]); + } + + mpic_init(chrp_mpic); + mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); +} + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +static struct irqaction xmon_irqaction = { + .handler = xmon_irq, + .mask = CPU_MASK_NONE, + .name = "XMON break", +}; +#endif + +void __init chrp_init_IRQ(void) +{ + struct device_node *np; + unsigned long chrp_int_ack = 0; +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + struct device_node *kbd; +#endif + + for (np = find_devices("pci"); np != NULL; np = np->next) { + unsigned int *addrp = (unsigned int *) + get_property(np, "8259-interrupt-acknowledge", NULL); + + if (addrp == NULL) + continue; + chrp_int_ack = addrp[prom_n_addr_cells(np)-1]; + break; + } + if (np == NULL) + printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n"); + + chrp_find_openpic(); + + i8259_init(chrp_int_ack, 0); + + if (_chrp_type == _CHRP_Pegasos) + ppc_md.get_irq = i8259_irq; + else + ppc_md.get_irq = mpic_get_irq; + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction); +#endif +} + +void __init +chrp_init2(void) +{ + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + + if (ppc_md.progress) + ppc_md.progress(" Have fun! ", 0x7777); +} + +void __init chrp_init(void) +{ + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ + ppc_do_canonicalize_irqs = 1; + + /* Assume we have an 8259... */ + __irq_offset_value = NUM_ISA_INTERRUPTS; + + ppc_md.setup_arch = chrp_setup_arch; + ppc_md.show_cpuinfo = chrp_show_cpuinfo; + + ppc_md.init_IRQ = chrp_init_IRQ; + ppc_md.init = chrp_init2; + + ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; + + ppc_md.restart = rtas_restart; + ppc_md.power_off = rtas_power_off; + ppc_md.halt = rtas_halt; + + ppc_md.time_init = chrp_time_init; + ppc_md.set_rtc_time = chrp_set_rtc_time; + ppc_md.get_rtc_time = chrp_get_rtc_time; + ppc_md.calibrate_decr = chrp_calibrate_decr; + +#ifdef CONFIG_SMP + smp_ops = &chrp_smp_ops; +#endif /* CONFIG_SMP */ +} + +#ifdef CONFIG_BOOTX_TEXT +void +btext_progress(char *s, unsigned short hex) +{ + btext_drawstring(s); + btext_drawstring("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c new file mode 100644 index 000000000000..bf68282670dd --- /dev/null +++ b/arch/powerpc/platforms/chrp/smp.c @@ -0,0 +1,94 @@ +/* + * Smp support for CHRP machines. + * + * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great + * deal of code from the sparc and intel versions. + * + * Copyright (C) 1999 Cort Dougan + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern unsigned long smp_chrp_cpu_nr; + +static int __init smp_chrp_probe(void) +{ + if (smp_chrp_cpu_nr > 1) + openpic_request_IPIs(); + + return smp_chrp_cpu_nr; +} + +static void __devinit smp_chrp_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void __devinit smp_chrp_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static DEFINE_SPINLOCK(timebase_lock); +static unsigned int timebase_upper = 0, timebase_lower = 0; + +void __devinit smp_chrp_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase_upper = get_tbu(); + timebase_lower = get_tbl(); + spin_unlock(&timebase_lock); + + while (timebase_upper || timebase_lower) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +void __devinit smp_chrp_take_timebase(void) +{ + while (!(timebase_upper || timebase_lower)) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase_upper, timebase_lower); + timebase_upper = 0; + timebase_lower = 0; + spin_unlock(&timebase_lock); + printk("CPU %i taken timebase\n", smp_processor_id()); +} + +/* CHRP with openpic */ +struct smp_ops_t chrp_smp_ops = { + .message_pass = smp_openpic_message_pass, + .probe = smp_chrp_probe, + .kick_cpu = smp_chrp_kick_cpu, + .setup_cpu = smp_chrp_setup_cpu, + .give_timebase = smp_chrp_give_timebase, + .take_timebase = smp_chrp_take_timebase, +}; diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c new file mode 100644 index 000000000000..9e53535ddb82 --- /dev/null +++ b/arch/powerpc/platforms/chrp/time.c @@ -0,0 +1,188 @@ +/* + * arch/ppc/platforms/chrp_time.c + * + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * + * Adapted for PowerPC (PReP) by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu). + * Copied and modified from arch/i386/kernel/time.c + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern spinlock_t rtc_lock; + +static int nvram_as1 = NVRAM_AS1; +static int nvram_as0 = NVRAM_AS0; +static int nvram_data = NVRAM_DATA; + +long __init chrp_time_init(void) +{ + struct device_node *rtcs; + int base; + + rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); + if (rtcs == NULL) + rtcs = find_compatible_devices("rtc", "ds1385-rtc"); + if (rtcs == NULL || rtcs->addrs == NULL) + return 0; + base = rtcs->addrs[0].address; + nvram_as1 = 0; + nvram_as0 = base; + nvram_data = base + 1; + + return 0; +} + +int chrp_cmos_clock_read(int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + return (inb(nvram_data)); +} + +void chrp_cmos_clock_write(unsigned long val, int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + outb(val, nvram_data); + return; +} + +/* + * Set the hardware clock. -- Cort + */ +int chrp_set_rtc_time(struct rtc_time *tmarg) +{ + unsigned char save_control, save_freq_select; + struct rtc_time tm = *tmarg; + + spin_lock(&rtc_lock); + + save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */ + + chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */ + + chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + tm.tm_year -= 1900; + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + } + chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); + chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); + chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS); + chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH); + chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH); + chrp_cmos_clock_write(tm.tm_year,RTC_YEAR); + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + chrp_cmos_clock_write(save_control, RTC_CONTROL); + chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT); + + spin_unlock(&rtc_lock); + return 0; +} + +void chrp_get_rtc_time(struct rtc_time *tm) +{ + unsigned int year, mon, day, hour, min, sec; + int uip, i; + + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + + /* Since the UIP flag is set for about 2.2 ms and the clock + * is typically written with a precision of 1 jiffy, trying + * to obtain a precision better than a few milliseconds is + * an illusion. Only consistency is interesting, this also + * allows to use the routine for /dev/rtc without a potential + * 1 second kernel busy loop triggered by any reader of /dev/rtc. + */ + + for ( i = 0; i<1000000; i++) { + uip = chrp_cmos_clock_read(RTC_FREQ_SELECT); + sec = chrp_cmos_clock_read(RTC_SECONDS); + min = chrp_cmos_clock_read(RTC_MINUTES); + hour = chrp_cmos_clock_read(RTC_HOURS); + day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); + mon = chrp_cmos_clock_read(RTC_MONTH); + year = chrp_cmos_clock_read(RTC_YEAR); + uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT); + if ((uip & RTC_UIP)==0) break; + } + + if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + if ((year += 1900) < 1970) + year += 100; + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = day; + tm->tm_mon = mon; + tm->tm_year = year; +} + + +void __init chrp_calibrate_decr(void) +{ + struct device_node *cpu; + unsigned int freq, *fp; + + /* + * The cpu node should have a timebase-frequency property + * to tell us the rate at which the decrementer counts. + */ + freq = 16666000; /* hardcoded default */ + cpu = find_type_devices("cpu"); + if (cpu != 0) { + fp = (unsigned int *) + get_property(cpu, "timebase-frequency", NULL); + if (fp != 0) + freq = *fp; + } + ppc_tb_freq = freq; +} diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 0eca17df239e..0037a8c8c81f 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -71,10 +71,6 @@ static u32 level_mask[4]; static DEFINE_SPINLOCK(pmac_pic_lock); -/* XXX here for now, should move to arch/powerpc/kernel/irq.c */ -int ppc_do_canonicalize_irqs; -EXPORT_SYMBOL(ppc_do_canonicalize_irqs); - #define GATWICK_IRQ_POOL_SIZE 10 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; From c49888203d7a316cb947bb8a1cf2ae191f28bcd3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 21:52:53 +1000 Subject: [PATCH 0483/1940] powerpc: Fixes to get the Longtrail CHRP a bit further Talk about buggy firmware... the OF on the Longtrail returns 0 from the claim client service rather than -1 when the claim fails. It also has no device_type on the /memory node and blows up if the output buffer for package-to-path is too big. This also fixes a bug with calling alloc_up with align == 0, where we did _ALIGN_UP(alloc_bottom, 0) which will end up as 0. Lastly, we now check the return value (in r3) from calling the prom, and return -1 from call_prom if we get a negative value back. That is supposed to indicate that the requested client service doesn't exist. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 42 ++++++++++++++++++--------- arch/ppc/boot/of1275/claim.c | 1 + arch/ppc/boot/openfirmware/chrpmain.c | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index debe9734636e..2ad9947bd675 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -145,11 +145,11 @@ typedef u32 cell_t; extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); #ifdef CONFIG_PPC64 -extern void enter_prom(struct prom_args *args, unsigned long entry); +extern int enter_prom(struct prom_args *args, unsigned long entry); #else -static inline void enter_prom(struct prom_args *args, unsigned long entry) +static inline int enter_prom(struct prom_args *args, unsigned long entry) { - ((void (*)(struct prom_args *))entry)(args); + return ((int (*)(struct prom_args *))entry)(args); } #endif @@ -241,7 +241,8 @@ static int __init call_prom(const char *service, int nargs, int nret, ...) for (i = 0; i < nret; i++) args.args[nargs+i] = 0; - enter_prom(&args, RELOC(prom_entry)); + if (enter_prom(&args, RELOC(prom_entry)) < 0) + return PROM_ERROR; return (nret > 0) ? args.args[nargs] : 0; } @@ -265,7 +266,8 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, for (i = 0; i < nret; i++) rets[nargs+i] = 0; - enter_prom(&args, RELOC(prom_entry)); + if (enter_prom(&args, RELOC(prom_entry)) < 0) + return PROM_ERROR; if (rets != NULL) for (i = 1; i < nret; ++i) @@ -670,9 +672,11 @@ static void __init prom_send_capabilities(void) */ static unsigned long __init alloc_up(unsigned long size, unsigned long align) { - unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align); + unsigned long base = RELOC(alloc_bottom); unsigned long addr = 0; + if (align) + base = _ALIGN_UP(base, align); prom_debug("alloc_up(%x, %x)\n", size, align); if (RELOC(ram_top) == 0) prom_panic("alloc_up() called with mem not initialized\n"); @@ -686,7 +690,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) base = _ALIGN_UP(base + 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if (addr != PROM_ERROR) + if (addr != PROM_ERROR && addr != 0) break; addr = 0; if (align == 0) @@ -746,7 +750,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, base = _ALIGN_DOWN(base - 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if (addr != PROM_ERROR) + if (addr != PROM_ERROR && addr != 0) break; addr = 0; } @@ -852,9 +856,16 @@ static void __init prom_init_mem(void) type[0] = 0; prom_getprop(node, "device_type", type, sizeof(type)); + if (type[0] == 0) { + /* + * CHRP Longtrail machines have no device_type + * on the memory node, so check the name instead... + */ + prom_getprop(node, "name", type, sizeof(type)); + } if (strcmp(type, RELOC("memory"))) continue; - + plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf)); if (plen > sizeof(regbuf)) { prom_printf("memory node too large for buffer !\n"); @@ -1632,18 +1643,21 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, unsigned long soff; unsigned char *valp; static char pname[MAX_PROPERTY_NAME]; - int l; + int l, room; dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); /* get the node's full name */ namep = (char *)*mem_start; - l = call_prom("package-to-path", 3, 1, node, - namep, *mem_end - *mem_start); + room = *mem_end - *mem_start; + if (room > 255) + room = 255; + l = call_prom("package-to-path", 3, 1, node, namep, room); if (l >= 0) { /* Didn't fit? Get more room. */ - if ((l+1) > (*mem_end - *mem_start)) { - namep = make_room(mem_start, mem_end, l+1, 1); + if (l >= room) { + if (l >= *mem_end - *mem_start) + namep = make_room(mem_start, mem_end, l+1, 1); call_prom("package-to-path", 3, 1, node, namep, l); } namep[l] = '\0'; diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c index e060292ae2a7..13169a5c4339 100644 --- a/arch/ppc/boot/of1275/claim.c +++ b/arch/ppc/boot/of1275/claim.c @@ -29,6 +29,7 @@ claim(unsigned int virt, unsigned int size, unsigned int align) args.virt = virt; args.size = size; args.align = align; + args.ret = (void *) 0; (*of_prom_entry)(&args); return args.ret; } diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c index effe4a0624b0..245dbd9fc120 100644 --- a/arch/ppc/boot/openfirmware/chrpmain.c +++ b/arch/ppc/boot/openfirmware/chrpmain.c @@ -78,7 +78,7 @@ boot(int a1, int a2, void *prom) begin_avail = avail_high = avail_ram; end_avail = scratch + sizeof(scratch); printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); - gunzip(dst, 0x400000, im, &len); + gunzip(dst, PROG_SIZE - PROG_START, im, &len); printf("done %u bytes\n\r", len); printf("%u bytes of heap consumed, max in use %u\n\r", avail_high - begin_avail, heap_max); From b41fc4f82f6a73b8b2e8f44bd7ef075797d2dacb Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 21:53:19 +1000 Subject: [PATCH 0484/1940] power: Update the multiple inclusion protection symbol on machdep.h Signed-off-by: Paul Mackerras --- include/asm-powerpc/machdep.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index b3a93b476d97..706508b1b04b 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -1,5 +1,5 @@ -#ifndef _PPC64_MACHDEP_H -#define _PPC64_MACHDEP_H +#ifndef _ASM_POWERPC_MACHDEP_H +#define _ASM_POWERPC_MACHDEP_H #ifdef __KERNEL__ /* @@ -281,4 +281,4 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal) } #endif /* __KERNEL__ */ -#endif /* _PPC64_MACHDEP_H */ +#endif /* _ASM_POWERPC_MACHDEP_H */ From fa39dc437a41733adaba241fd9036760283a516a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 21:54:21 +1000 Subject: [PATCH 0485/1940] powerpc32: Limit memory to lowmem if !CONFIG_HIGHMEM. This trims off the extra unusable memory from the lmb structure, so we don't try to use it. Signed-off-by: Paul Mackerras --- arch/powerpc/mm/init_32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index aa6a5440cec1..8dd1f7d0e23c 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -154,10 +154,13 @@ void __init MMU_init(void) * in the fixed entries */ adjust_total_lowmem(); #endif /* CONFIG_FSL_BOOKE */ + if (total_lowmem > __max_low_memory) { total_lowmem = __max_low_memory; #ifndef CONFIG_HIGHMEM total_memory = total_lowmem; + lmb_enforce_memory_limit(total_lowmem); + lmb_analyze(); #endif /* CONFIG_HIGHMEM */ } From bd561c79dce9036c9efb17420b6cf8763c8c9de3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 21:55:33 +1000 Subject: [PATCH 0486/1940] powerpc: Fix incorrect timer register addresses in mpic.c We were computing the wrong address for the MPIC timer registers, so when we went to initialize them we would have been hitting some unrelated ioremap... oops. Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 3948e759d41a..105f05341a41 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -358,7 +358,7 @@ static void mpic_enable_irq(unsigned int irq) struct mpic *mpic = mpic_from_irq(irq); unsigned int src = irq - mpic->irq_offset; - DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src); + DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); @@ -511,7 +511,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, /* Map the global registers */ mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); - mpic->tmregs = mpic->gregs + (MPIC_TIMER_BASE >> 2); + mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2); BUG_ON(mpic->gregs == NULL); /* Reset */ @@ -648,7 +648,6 @@ void __init mpic_init(struct mpic *mpic) continue; irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; - #endif /* CONFIG_SMP */ } From b6a4ce526a87bd8a99a396ac993240d6d3239852 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Oct 2005 22:54:17 +1000 Subject: [PATCH 0487/1940] powerpc: 32-bit powermac needs the mpc106 code Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9589d621edc5..c71ddc0c191a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -293,6 +293,7 @@ config PPC_PMAC bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM select PPC_INDIRECT_PCI if PPC32 + select PPC_MPC106 if PPC32 default y config PPC_PMAC64 From cb4ab974ae0bff3f49086090a1a50373c5edc8f4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 11:08:31 +1000 Subject: [PATCH 0488/1940] powerpc: Remove common stuff from setup_64.c This should have been in commit 03501dab035ab7da5e1373f5e130cfd6346d3f21 but got missed by accident. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_64.c | 270 --------------------------------- 1 file changed, 270 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 0312422881ae..9cdf294e76f6 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -138,23 +138,6 @@ static struct notifier_block ppc64_panic_block = { .priority = INT_MIN /* may not return; must be done last */ }; -/* - * Perhaps we can put the pmac screen_info[] here - * on pmac as well so we don't need the ifdef's. - * Until we get multiple-console support in here - * that is. -- Cort - * Maybe tie it to serial consoles, since this is really what - * these processors use on existing boards. -- Dan - */ -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 25, - .orig_video_cols = 80, - .orig_video_lines = 25, - .orig_video_isVGA = 1, - .orig_video_points = 16 -}; - #ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -641,51 +624,6 @@ void __init setup_system(void) DBG(" <- setup_system()\n"); } -/* also used by kexec */ -void machine_shutdown(void) -{ - if (ppc_md.nvram_sync) - ppc_md.nvram_sync(); -} - -void machine_restart(char *cmd) -{ - machine_shutdown(); - ppc_md.restart(cmd); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} - -void machine_power_off(void) -{ - machine_shutdown(); - ppc_md.power_off(); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} -/* Used by the G5 thermal driver */ -EXPORT_SYMBOL_GPL(machine_power_off); - -void machine_halt(void) -{ - machine_shutdown(); - ppc_md.halt(); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} - static int ppc64_panic_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -693,90 +631,6 @@ static int ppc64_panic_event(struct notifier_block *this, return NOTIFY_DONE; } - -#ifdef CONFIG_SMP -DEFINE_PER_CPU(unsigned int, pvr); -#endif - -static int show_cpuinfo(struct seq_file *m, void *v) -{ - unsigned long cpu_id = (unsigned long)v - 1; - unsigned int pvr; - unsigned short maj; - unsigned short min; - - if (cpu_id == NR_CPUS) { - seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - - if (ppc_md.show_cpuinfo != NULL) - ppc_md.show_cpuinfo(m); - - return 0; - } - - /* We only show online cpus: disable preempt (overzealous, I - * knew) to prevent cpu going down. */ - preempt_disable(); - if (!cpu_online(cpu_id)) { - preempt_enable(); - return 0; - } - -#ifdef CONFIG_SMP - pvr = per_cpu(pvr, cpu_id); -#else - pvr = mfspr(SPRN_PVR); -#endif - maj = (pvr >> 8) & 0xFF; - min = pvr & 0xFF; - - seq_printf(m, "processor\t: %lu\n", cpu_id); - seq_printf(m, "cpu\t\t: "); - - if (cur_cpu_spec->pvr_mask) - seq_printf(m, "%s", cur_cpu_spec->cpu_name); - else - seq_printf(m, "unknown (%08x)", pvr); - -#ifdef CONFIG_ALTIVEC - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - seq_printf(m, ", altivec supported"); -#endif /* CONFIG_ALTIVEC */ - - seq_printf(m, "\n"); - - /* - * Assume here that all clock rates are the same in a - * smp system. -- Cort - */ - seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, - ppc_proc_freq % 1000000); - - seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min); - - preempt_enable(); - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL; -} -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} -static void c_stop(struct seq_file *m, void *v) -{ -} -struct seq_operations cpuinfo_op = { - .start =c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - /* * These three variables are used to save values passed to us by prom_init() * via the device tree. The TCE variables are needed because with a memory_limit @@ -803,130 +657,6 @@ static int __init early_parsemem(char *p) early_param("mem", early_parsemem); #endif /* CONFIG_PPC_ISERIES */ -#ifdef CONFIG_PPC_MULTIPLATFORM -static int __init set_preferred_console(void) -{ - struct device_node *prom_stdout = NULL; - char *name; - u32 *spd; - int offset = 0; - - DBG(" -> set_preferred_console()\n"); - - /* The user has requested a console so this is already set up. */ - if (strstr(saved_command_line, "console=")) { - DBG(" console was specified !\n"); - return -EBUSY; - } - - if (!of_chosen) { - DBG(" of_chosen is NULL !\n"); - return -ENODEV; - } - /* We are getting a weird phandle from OF ... */ - /* ... So use the full path instead */ - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (name == NULL) { - DBG(" no linux,stdout-path !\n"); - return -ENODEV; - } - prom_stdout = of_find_node_by_path(name); - if (!prom_stdout) { - DBG(" can't find stdout package %s !\n", name); - return -ENODEV; - } - DBG("stdout is %s\n", prom_stdout->full_name); - - name = (char *)get_property(prom_stdout, "name", NULL); - if (!name) { - DBG(" stdout package has no name !\n"); - goto not_found; - } - spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); - - if (0) - ; -#ifdef CONFIG_SERIAL_8250_CONSOLE - else if (strcmp(name, "serial") == 0) { - int i; - u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); - if (i > 8) { - switch (reg[1]) { - case 0x3f8: - offset = 0; - break; - case 0x2f8: - offset = 1; - break; - case 0x898: - offset = 2; - break; - case 0x890: - offset = 3; - break; - default: - /* We dont recognise the serial port */ - goto not_found; - } - } - } -#endif /* CONFIG_SERIAL_8250_CONSOLE */ -#ifdef CONFIG_PPC_PSERIES - else if (strcmp(name, "vty") == 0) { - u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); - char *compat = (char *)get_property(prom_stdout, "compatible", NULL); - - if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { - /* Host Virtual Serial Interface */ - int offset; - switch (reg[0]) { - case 0x30000000: - offset = 0; - break; - case 0x30000001: - offset = 1; - break; - default: - goto not_found; - } - of_node_put(prom_stdout); - DBG("Found hvsi console at offset %d\n", offset); - return add_preferred_console("hvsi", offset, NULL); - } else { - /* pSeries LPAR virtual console */ - of_node_put(prom_stdout); - DBG("Found hvc console\n"); - return add_preferred_console("hvc", 0, NULL); - } - } -#endif /* CONFIG_PPC_PSERIES */ -#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE - else if (strcmp(name, "ch-a") == 0) - offset = 0; - else if (strcmp(name, "ch-b") == 0) - offset = 1; -#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ - else - goto not_found; - of_node_put(prom_stdout); - - DBG("Found serial console at ttyS%d\n", offset); - - if (spd) { - static char __initdata opt[16]; - sprintf(opt, "%d", *spd); - return add_preferred_console("ttyS", offset, opt); - } else - return add_preferred_console("ttyS", offset, NULL); - - not_found: - DBG("No preferred console found !\n"); - of_node_put(prom_stdout); - return -ENODEV; -} -console_initcall(set_preferred_console); -#endif /* CONFIG_PPC_MULTIPLATFORM */ - #ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { From f2be34a3f30a1595f5d9c8e7d0bec4d8d3626047 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 25 Oct 2005 22:16:02 -0600 Subject: [PATCH 0489/1940] [SCSI] ncr53c8xx: Cleanup namespace collision with ktimers Replace the mcr53c8xx roll your own ktime_... macros with the correct time_after() et al. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/ncr53c8xx.c | 22 +++++++++++----------- drivers/scsi/sym53c8xx_defs.h | 13 ------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 519486d24b28..9a4f576c0d5e 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -3481,8 +3481,8 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) **---------------------------------------------------- */ if (np->settle_time && cmd->timeout_per_command >= HZ) { - u_long tlimit = ktime_get(cmd->timeout_per_command - HZ); - if (ktime_dif(np->settle_time, tlimit) > 0) + u_long tlimit = jiffies + cmd->timeout_per_command - HZ; + if (time_after(np->settle_time, tlimit)) np->settle_time = tlimit; } @@ -3516,7 +3516,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) ** Force ordered tag if necessary to avoid timeouts ** and to preserve interactivity. */ - if (lp && ktime_exp(lp->tags_stime)) { + if (lp && time_after(jiffies, lp->tags_stime)) { if (lp->tags_smap) { order = M_ORDERED_TAG; if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){ @@ -3524,7 +3524,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) "ordered tag forced.\n"); } } - lp->tags_stime = ktime_get(3*HZ); + lp->tags_stime = jiffies + 3*HZ; lp->tags_smap = lp->tags_umap; } @@ -3792,7 +3792,7 @@ static int ncr_reset_scsi_bus(struct ncb *np, int enab_int, int settle_delay) u32 term; int retv = 0; - np->settle_time = ktime_get(settle_delay * HZ); + np->settle_time = jiffies + settle_delay * HZ; if (bootverbose > 1) printk("%s: resetting, " @@ -5044,7 +5044,7 @@ static void ncr_setup_tags (struct ncb *np, struct scsi_device *sdev) static void ncr_timeout (struct ncb *np) { - u_long thistime = ktime_get(0); + u_long thistime = jiffies; /* ** If release process in progress, let's go @@ -5057,7 +5057,7 @@ static void ncr_timeout (struct ncb *np) return; } - np->timer.expires = ktime_get(SCSI_NCR_TIMER_INTERVAL); + np->timer.expires = jiffies + SCSI_NCR_TIMER_INTERVAL; add_timer(&np->timer); /* @@ -5336,8 +5336,8 @@ void ncr_exception (struct ncb *np) **========================================================= */ - if (ktime_exp(np->regtime)) { - np->regtime = ktime_get(10*HZ); + if (time_after(jiffies, np->regtime)) { + np->regtime = jiffies + 10*HZ; for (i = 0; iregdump); i++) ((char*)&np->regdump)[i] = INB_OFF(i); np->regdump.nc_dstat = dstat; @@ -5453,7 +5453,7 @@ static int ncr_int_sbmc (struct ncb *np) ** Suspend command processing for 1 second and ** reinitialize all except the chip. */ - np->settle_time = ktime_get(1*HZ); + np->settle_time = jiffies + HZ; ncr_init (np, 0, bootverbose ? "scsi mode change" : NULL, HS_RESET); return 1; } @@ -6923,7 +6923,7 @@ static struct lcb *ncr_setup_lcb (struct ncb *np, struct scsi_device *sdev) for (i = 0 ; i < MAX_TAGS ; i++) lp->cb_tags[i] = i; lp->maxnxs = MAX_TAGS; - lp->tags_stime = ktime_get(3*HZ); + lp->tags_stime = jiffies + 3*HZ; ncr_setup_tags (np, sdev); } diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h index 4c4ae7d4713f..139cd0e12e62 100644 --- a/drivers/scsi/sym53c8xx_defs.h +++ b/drivers/scsi/sym53c8xx_defs.h @@ -280,19 +280,6 @@ #define SCSI_NCR_MAX_LUN (1) #endif -/* -** These simple macros limit expression involving -** kernel time values (jiffies) to some that have -** chance not to be too much incorrect. :-) -*/ -#define ktime_get(o) (jiffies + (u_long) o) -#define ktime_exp(b) ((long)(jiffies) - (long)(b) >= 0) -#define ktime_dif(a, b) ((long)(a) - (long)(b)) -/* These ones are not used in this driver */ -#define ktime_add(a, o) ((a) + (u_long)(o)) -#define ktime_sub(a, o) ((a) - (u_long)(o)) - - /* * IO functions definition for big/little endian CPU support. * For now, the NCR is only supported in little endian addressing mode, From bf20a0000377f7bdeb42b78b10ed578deb3d63f1 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 16:45:29 +1000 Subject: [PATCH 0490/1940] powerpc: undeprecate the old OF device tree accessors for now The recent addition of __deprecated to the declarations for find_devices etc. produces a whole pile of warnings from the ppc32 code. Since those functions still work perfectly well on ppc32, which doesn't have hotplug support for anything in the OF device tree, and we don't have time to fix that code now, remove the __deprecated markings for now. Signed-off-by: Paul Mackerras --- include/asm-powerpc/prom.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 49d2c7455f8e..3a0104fa0462 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -155,12 +155,12 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e /* OBSOLETE: Old style node lookup */ -extern __deprecated struct device_node *find_devices(const char *name); -extern __deprecated struct device_node *find_type_devices(const char *type); -extern __deprecated struct device_node *find_path_device(const char *path); -extern __deprecated struct device_node *find_compatible_devices(const char *type, +extern struct device_node *find_devices(const char *name); +extern struct device_node *find_type_devices(const char *type); +extern struct device_node *find_path_device(const char *path); +extern struct device_node *find_compatible_devices(const char *type, const char *compat); -extern __deprecated struct device_node *find_all_nodes(void); +extern struct device_node *find_all_nodes(void); /* New style node lookup */ extern struct device_node *of_find_node_by_name(struct device_node *from, From 8168f902fa9c2ca8930ea8d72cce283234df03b8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 25 Oct 2005 16:56:43 +1000 Subject: [PATCH 0491/1940] [PATCH] ppc64: make dma_addr_t 64 bits There has been a need expressed for dma_addr_t to be 64 bits on PPC64. This patch does that. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- drivers/net/ibmveth.c | 2 +- include/asm-powerpc/types.h | 4 ++++ include/asm-ppc64/scatterlist.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index f5dc632452f1..cbe9368a4d56 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -532,7 +532,7 @@ static int ibmveth_open(struct net_device *netdev) if(lpar_rc != H_Success) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%x filter TCE:0x%x rxq desc:0x%lx MAC:0x%lx\n", + ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h index f70cd3fb32d9..ec3c2ee8bf86 100644 --- a/include/asm-powerpc/types.h +++ b/include/asm-powerpc/types.h @@ -85,7 +85,11 @@ typedef unsigned long long u64; typedef __vector128 vector128; +#ifdef __powerpc64__ +typedef u64 dma_addr_t; +#else typedef u32 dma_addr_t; +#endif typedef u64 dma64_addr_t; typedef struct { diff --git a/include/asm-ppc64/scatterlist.h b/include/asm-ppc64/scatterlist.h index cecce6c6dfbb..65a2a027ac94 100644 --- a/include/asm-ppc64/scatterlist.h +++ b/include/asm-ppc64/scatterlist.h @@ -19,7 +19,7 @@ struct scatterlist { unsigned int length; /* For TCE support */ - u32 dma_address; + dma_addr_t dma_address; u32 dma_length; }; From 89edce0b4e71f6f78e27d7c18c63e957469b74d3 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 25 Oct 2005 16:59:03 +1000 Subject: [PATCH 0492/1940] [PATCH] powerpc: merge scatterlist.h This depends on the 64bit dma_addr_t patch. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- .../{asm-ppc64 => asm-powerpc}/scatterlist.h | 22 +++++++++++++--- include/asm-ppc/scatterlist.h | 25 ------------------- 2 files changed, 18 insertions(+), 29 deletions(-) rename include/{asm-ppc64 => asm-powerpc}/scatterlist.h (54%) delete mode 100644 include/asm-ppc/scatterlist.h diff --git a/include/asm-ppc64/scatterlist.h b/include/asm-powerpc/scatterlist.h similarity index 54% rename from include/asm-ppc64/scatterlist.h rename to include/asm-powerpc/scatterlist.h index 65a2a027ac94..8c992d1491d4 100644 --- a/include/asm-ppc64/scatterlist.h +++ b/include/asm-powerpc/scatterlist.h @@ -1,6 +1,5 @@ -#ifndef _PPC64_SCATTERLIST_H -#define _PPC64_SCATTERLIST_H - +#ifndef _ASM_POWERPC_SCATTERLIST_H +#define _ASM_POWERPC_SCATTERLIST_H /* * Copyright (C) 2001 PPC64 Team, IBM Corp * @@ -10,6 +9,7 @@ * 2 of the License, or (at your option) any later version. */ +#ifdef __KERNEL__ #include #include @@ -23,9 +23,23 @@ struct scatterlist { u32 dma_length; }; +/* + * These macros should be used after a dma_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns, or alternatively stop on the first sg_dma_len(sg) which + * is 0. + */ #define sg_dma_address(sg) ((sg)->dma_address) +#ifdef __powerpc64__ #define sg_dma_len(sg) ((sg)->dma_length) +#else +#define sg_dma_len(sg) ((sg)->length) +#endif +#ifdef __powerpc64__ #define ISA_DMA_THRESHOLD (~0UL) +#endif -#endif /* !(_PPC64_SCATTERLIST_H) */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_SCATTERLIST_H */ diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h deleted file mode 100644 index f21f18f56548..000000000000 --- a/include/asm-ppc/scatterlist.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _PPC_SCATTERLIST_H -#define _PPC_SCATTERLIST_H - -#include - -struct scatterlist { - struct page *page; - unsigned int offset; - dma_addr_t dma_address; - unsigned int length; -}; - -/* - * These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns, or alternatively stop on the first sg_dma_len(sg) which - * is 0. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - -#endif /* !(_PPC_SCATTERLIST_H) */ -#endif /* __KERNEL__ */ From fda262b8978d0089758ef9444508434c74113a61 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 20:20:42 +1000 Subject: [PATCH 0493/1940] [PATCH] ppc64: remove arch/ppc64/kernel/setup.c and use setup_64.c from the merged tree instead. The only difference between them was the code to set up the syscall maps. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 5 +- arch/powerpc/kernel/setup_64.c | 18 +- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/setup.c | 1307 -------------------------------- 4 files changed, 17 insertions(+), 1315 deletions(-) delete mode 100644 arch/ppc64/kernel/setup.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 30101762f7c0..a733347964a0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -12,7 +12,8 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ signal_32.o pmc.o -obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o ptrace32.o +obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ + ptrace32.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o @@ -34,7 +35,7 @@ extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ prom.o systbl.o traps.o setup-common.o obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o -obj-$(CONFIG_PPC64) += setup_64.o misc_64.o +obj-$(CONFIG_PPC64) += misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 9cdf294e76f6..721adeea601d 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -702,6 +702,17 @@ static void __init emergency_stack_init(void) limit)) + PAGE_SIZE; } +extern unsigned long *sys_call_table; +extern unsigned long sys_ni_syscall; +#ifdef CONFIG_PPC_MERGE +#define SYS_CALL_ENTRY64(i) sys_call_table[(i) * 2] +#define SYS_CALL_ENTRY32(i) sys_call_table[(i) * 2 + 1] +#else +extern unsigned long *sys_call_table32; +#define SYS_CALL_ENTRY64(i) sys_call_table[(i)] +#define SYS_CALL_ENTRY32(i) sys_call_table32[(i)] +#endif + /* * Called from setup_arch to initialize the bitmap of available * syscalls in the systemcfg page @@ -709,17 +720,14 @@ static void __init emergency_stack_init(void) void __init setup_syscall_map(void) { unsigned int i, count64 = 0, count32 = 0; - extern unsigned long *sys_call_table; - extern unsigned long sys_ni_syscall; - for (i = 0; i < __NR_syscalls; i++) { - if (sys_call_table[i*2] != sys_ni_syscall) { + if (SYS_CALL_ENTRY64(i) != sys_ni_syscall) { count64++; systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f); } - if (sys_call_table[i*2+1] != sys_ni_syscall) { + if (SYS_CALL_ENTRY32(i) != sys_ni_syscall) { count32++; systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f); diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 83ecefdcfef7..f2f60c9cc55f 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -7,7 +7,7 @@ ifneq ($(CONFIG_PPC_MERGE),y) EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds -obj-y := setup.o entry.o misc.o prom.o +obj-y := entry.o misc.o prom.o endif diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c deleted file mode 100644 index 44ee6ebe9a60..000000000000 --- a/arch/ppc64/kernel/setup.c +++ /dev/null @@ -1,1307 +0,0 @@ -/* - * - * Common boot and setup code. - * - * Copyright (C) 2001 PPC64 Team, IBM Corp - * - * 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -/* - * Here are some early debugging facilities. You can enable one - * but your kernel will not boot on anything else if you do so - */ - -/* This one is for use on LPAR machines that support an HVC console - * on vterm 0 - */ -extern void udbg_init_debug_lpar(void); -/* This one is for use on Apple G5 machines - */ -extern void udbg_init_pmac_realmode(void); -/* That's RTAS panel debug */ -extern void call_rtas_display_status_delay(unsigned char c); -/* Here's maple real mode debug */ -extern void udbg_init_maple_realmode(void); - -#define EARLY_DEBUG_INIT() do {} while(0) - -#if 0 -#define EARLY_DEBUG_INIT() udbg_init_debug_lpar() -#define EARLY_DEBUG_INIT() udbg_init_maple_realmode() -#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode() -#define EARLY_DEBUG_INIT() \ - do { udbg_putc = call_rtas_display_status_delay; } while(0) -#endif - -/* extern void *stab; */ -extern unsigned long klimit; - -extern void mm_init_ppc64(void); -extern void stab_initialize(unsigned long stab); -extern void htab_initialize(void); -extern void early_init_devtree(void *flat_dt); -extern void unflatten_device_tree(void); - -extern void smp_release_cpus(void); - -int have_of = 1; -int boot_cpuid = 0; -int boot_cpuid_phys = 0; -dev_t boot_dev; -u64 ppc64_pft_size; - -struct ppc64_caches ppc64_caches; -EXPORT_SYMBOL_GPL(ppc64_caches); - -/* - * These are used in binfmt_elf.c to put aux entries on the stack - * for each elf executable being started. - */ -int dcache_bsize; -int icache_bsize; -int ucache_bsize; - -/* The main machine-dep calls structure - */ -struct machdep_calls ppc_md; -EXPORT_SYMBOL(ppc_md); - -#ifdef CONFIG_MAGIC_SYSRQ -unsigned long SYSRQ_KEY; -#endif /* CONFIG_MAGIC_SYSRQ */ - - -static int ppc64_panic_event(struct notifier_block *, unsigned long, void *); -static struct notifier_block ppc64_panic_block = { - .notifier_call = ppc64_panic_event, - .priority = INT_MIN /* may not return; must be done last */ -}; - -/* - * Perhaps we can put the pmac screen_info[] here - * on pmac as well so we don't need the ifdef's. - * Until we get multiple-console support in here - * that is. -- Cort - * Maybe tie it to serial consoles, since this is really what - * these processors use on existing boards. -- Dan - */ -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 25, - .orig_video_cols = 80, - .orig_video_lines = 25, - .orig_video_isVGA = 1, - .orig_video_points = 16 -}; - -#ifdef CONFIG_SMP - -static int smt_enabled_cmdline; - -/* Look for ibm,smt-enabled OF option */ -static void check_smt_enabled(void) -{ - struct device_node *dn; - char *smt_option; - - /* Allow the command line to overrule the OF option */ - if (smt_enabled_cmdline) - return; - - dn = of_find_node_by_path("/options"); - - if (dn) { - smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); - - if (smt_option) { - if (!strcmp(smt_option, "on")) - smt_enabled_at_boot = 1; - else if (!strcmp(smt_option, "off")) - smt_enabled_at_boot = 0; - } - } -} - -/* Look for smt-enabled= cmdline option */ -static int __init early_smt_enabled(char *p) -{ - smt_enabled_cmdline = 1; - - if (!p) - return 0; - - if (!strcmp(p, "on") || !strcmp(p, "1")) - smt_enabled_at_boot = 1; - else if (!strcmp(p, "off") || !strcmp(p, "0")) - smt_enabled_at_boot = 0; - - return 0; -} -early_param("smt-enabled", early_smt_enabled); - -/** - * setup_cpu_maps - initialize the following cpu maps: - * cpu_possible_map - * cpu_present_map - * cpu_sibling_map - * - * Having the possible map set up early allows us to restrict allocations - * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. - * - * We do not initialize the online map here; cpus set their own bits in - * cpu_online_map as they come up. - * - * This function is valid only for Open Firmware systems. finish_device_tree - * must be called before using this. - * - * While we're here, we may as well set the "physical" cpu ids in the paca. - */ -static void __init setup_cpu_maps(void) -{ - struct device_node *dn = NULL; - int cpu = 0; - int swap_cpuid = 0; - - check_smt_enabled(); - - while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { - u32 *intserv; - int j, len = sizeof(u32), nthreads; - - intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s", - &len); - if (!intserv) - intserv = (u32 *)get_property(dn, "reg", NULL); - - nthreads = len / sizeof(u32); - - for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { - cpu_set(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, intserv[j]); - - if (intserv[j] == boot_cpuid_phys) - swap_cpuid = cpu; - cpu_set(cpu, cpu_possible_map); - cpu++; - } - } - - /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that - * boot cpu is logical 0. - */ - if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { - u32 tmp; - tmp = get_hard_smp_processor_id(0); - set_hard_smp_processor_id(0, boot_cpuid_phys); - set_hard_smp_processor_id(swap_cpuid, tmp); - } - - /* - * On pSeries LPAR, we need to know how many cpus - * could possibly be added to this partition. - */ - if (systemcfg->platform == PLATFORM_PSERIES_LPAR && - (dn = of_find_node_by_path("/rtas"))) { - int num_addr_cell, num_size_cell, maxcpus; - unsigned int *ireg; - - num_addr_cell = prom_n_addr_cells(dn); - num_size_cell = prom_n_size_cells(dn); - - ireg = (unsigned int *) - get_property(dn, "ibm,lrdr-capacity", NULL); - - if (!ireg) - goto out; - - maxcpus = ireg[num_addr_cell + num_size_cell]; - - /* Double maxcpus for processors which have SMT capability */ - if (cpu_has_feature(CPU_FTR_SMT)) - maxcpus *= 2; - - if (maxcpus > NR_CPUS) { - printk(KERN_WARNING - "Partition configured for %d cpus, " - "operating system maximum is %d.\n", - maxcpus, NR_CPUS); - maxcpus = NR_CPUS; - } else - printk(KERN_INFO "Partition configured for %d cpus.\n", - maxcpus); - - for (cpu = 0; cpu < maxcpus; cpu++) - cpu_set(cpu, cpu_possible_map); - out: - of_node_put(dn); - } - - /* - * Do the sibling map; assume only two threads per processor. - */ - for_each_cpu(cpu) { - cpu_set(cpu, cpu_sibling_map[cpu]); - if (cpu_has_feature(CPU_FTR_SMT)) - cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); - } - - systemcfg->processorCount = num_present_cpus(); -} -#endif /* CONFIG_SMP */ - -extern struct machdep_calls pSeries_md; -extern struct machdep_calls pmac_md; -extern struct machdep_calls maple_md; -extern struct machdep_calls bpa_md; -extern struct machdep_calls iseries_md; - -/* Ultimately, stuff them in an elf section like initcalls... */ -static struct machdep_calls __initdata *machines[] = { -#ifdef CONFIG_PPC_PSERIES - &pSeries_md, -#endif /* CONFIG_PPC_PSERIES */ -#ifdef CONFIG_PPC_PMAC - &pmac_md, -#endif /* CONFIG_PPC_PMAC */ -#ifdef CONFIG_PPC_MAPLE - &maple_md, -#endif /* CONFIG_PPC_MAPLE */ -#ifdef CONFIG_PPC_BPA - &bpa_md, -#endif -#ifdef CONFIG_PPC_ISERIES - &iseries_md, -#endif - NULL -}; - -/* - * Early initialization entry point. This is called by head.S - * with MMU translation disabled. We rely on the "feature" of - * the CPU that ignores the top 2 bits of the address in real - * mode so we can access kernel globals normally provided we - * only toy with things in the RMO region. From here, we do - * some early parsing of the device-tree to setup out LMB - * data structures, and allocate & initialize the hash table - * and segment tables so we can start running with translation - * enabled. - * - * It is this function which will call the probe() callback of - * the various platform types and copy the matching one to the - * global ppc_md structure. Your platform can eventually do - * some very early initializations from the probe() routine, but - * this is not recommended, be very careful as, for example, the - * device-tree is not accessible via normal means at this point. - */ - -void __init early_setup(unsigned long dt_ptr) -{ - struct paca_struct *lpaca = get_paca(); - static struct machdep_calls **mach; - - /* - * Enable early debugging if any specified (see top of - * this file) - */ - EARLY_DEBUG_INIT(); - - DBG(" -> early_setup()\n"); - - /* - * Fill the default DBG level (do we want to keep - * that old mecanism around forever ?) - */ - ppcdbg_initialize(); - - /* - * Do early initializations using the flattened device - * tree, like retreiving the physical memory map or - * calculating/retreiving the hash table size - */ - early_init_devtree(__va(dt_ptr)); - - /* - * Iterate all ppc_md structures until we find the proper - * one for the current machine type - */ - DBG("Probing machine type for platform %x...\n", - systemcfg->platform); - - for (mach = machines; *mach; mach++) { - if ((*mach)->probe(systemcfg->platform)) - break; - } - /* What can we do if we didn't find ? */ - if (*mach == NULL) { - DBG("No suitable machine found !\n"); - for (;;); - } - ppc_md = **mach; - - DBG("Found, Initializing memory management...\n"); - - /* - * Initialize stab / SLB management - */ - if (!firmware_has_feature(FW_FEATURE_ISERIES)) - stab_initialize(lpaca->stab_real); - - /* - * Initialize the MMU Hash table and create the linear mapping - * of memory - */ - htab_initialize(); - - DBG(" <- early_setup()\n"); -} - - -/* - * Initialize some remaining members of the ppc64_caches and systemcfg structures - * (at least until we get rid of them completely). This is mostly some - * cache informations about the CPU that will be used by cache flush - * routines and/or provided to userland - */ -static void __init initialize_cache_info(void) -{ - struct device_node *np; - unsigned long num_cpus = 0; - - DBG(" -> initialize_cache_info()\n"); - - for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) { - num_cpus += 1; - - /* We're assuming *all* of the CPUs have the same - * d-cache and i-cache sizes... -Peter - */ - - if ( num_cpus == 1 ) { - u32 *sizep, *lsizep; - u32 size, lsize; - const char *dc, *ic; - - /* Then read cache informations */ - if (systemcfg->platform == PLATFORM_POWERMAC) { - dc = "d-cache-block-size"; - ic = "i-cache-block-size"; - } else { - dc = "d-cache-line-size"; - ic = "i-cache-line-size"; - } - - size = 0; - lsize = cur_cpu_spec->dcache_bsize; - sizep = (u32 *)get_property(np, "d-cache-size", NULL); - if (sizep != NULL) - size = *sizep; - lsizep = (u32 *) get_property(np, dc, NULL); - if (lsizep != NULL) - lsize = *lsizep; - if (sizep == 0 || lsizep == 0) - DBG("Argh, can't find dcache properties ! " - "sizep: %p, lsizep: %p\n", sizep, lsizep); - - systemcfg->dcache_size = ppc64_caches.dsize = size; - systemcfg->dcache_line_size = - ppc64_caches.dline_size = lsize; - ppc64_caches.log_dline_size = __ilog2(lsize); - ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; - - size = 0; - lsize = cur_cpu_spec->icache_bsize; - sizep = (u32 *)get_property(np, "i-cache-size", NULL); - if (sizep != NULL) - size = *sizep; - lsizep = (u32 *)get_property(np, ic, NULL); - if (lsizep != NULL) - lsize = *lsizep; - if (sizep == 0 || lsizep == 0) - DBG("Argh, can't find icache properties ! " - "sizep: %p, lsizep: %p\n", sizep, lsizep); - - systemcfg->icache_size = ppc64_caches.isize = size; - systemcfg->icache_line_size = - ppc64_caches.iline_size = lsize; - ppc64_caches.log_iline_size = __ilog2(lsize); - ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; - } - } - - /* Add an eye catcher and the systemcfg layout version number */ - strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); - systemcfg->version.major = SYSTEMCFG_MAJOR; - systemcfg->version.minor = SYSTEMCFG_MINOR; - systemcfg->processor = mfspr(SPRN_PVR); - - DBG(" <- initialize_cache_info()\n"); -} - -static void __init check_for_initrd(void) -{ -#ifdef CONFIG_BLK_DEV_INITRD - u64 *prop; - - DBG(" -> check_for_initrd()\n"); - - if (of_chosen) { - prop = (u64 *)get_property(of_chosen, - "linux,initrd-start", NULL); - if (prop != NULL) { - initrd_start = (unsigned long)__va(*prop); - prop = (u64 *)get_property(of_chosen, - "linux,initrd-end", NULL); - if (prop != NULL) { - initrd_end = (unsigned long)__va(*prop); - initrd_below_start_ok = 1; - } else - initrd_start = 0; - } - } - - /* If we were passed an initrd, set the ROOT_DEV properly if the values - * look sensible. If not, clear initrd reference. - */ - if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && - initrd_end > initrd_start) - ROOT_DEV = Root_RAM0; - else - initrd_start = initrd_end = 0; - - if (initrd_start) - printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); - - DBG(" <- check_for_initrd()\n"); -#endif /* CONFIG_BLK_DEV_INITRD */ -} - -/* - * Do some initial setup of the system. The parameters are those which - * were passed in from the bootloader. - */ -void __init setup_system(void) -{ - DBG(" -> setup_system()\n"); - - /* - * Unflatten the device-tree passed by prom_init or kexec - */ - unflatten_device_tree(); - - /* - * Fill the ppc64_caches & systemcfg structures with informations - * retreived from the device-tree. Need to be called before - * finish_device_tree() since the later requires some of the - * informations filled up here to properly parse the interrupt - * tree. - * It also sets up the cache line sizes which allows to call - * routines like flush_icache_range (used by the hash init - * later on). - */ - initialize_cache_info(); - -#ifdef CONFIG_PPC_RTAS - /* - * Initialize RTAS if available - */ - rtas_initialize(); -#endif /* CONFIG_PPC_RTAS */ - - /* - * Check if we have an initrd provided via the device-tree - */ - check_for_initrd(); - - /* - * Do some platform specific early initializations, that includes - * setting up the hash table pointers. It also sets up some interrupt-mapping - * related options that will be used by finish_device_tree() - */ - ppc_md.init_early(); - - /* - * "Finish" the device-tree, that is do the actual parsing of - * some of the properties like the interrupt map - */ - finish_device_tree(); - -#ifdef CONFIG_BOOTX_TEXT - init_boot_display(); -#endif - - /* - * Initialize xmon - */ -#ifdef CONFIG_XMON_DEFAULT - xmon_init(1); -#endif - /* - * Register early console - */ - register_early_udbg_console(); - - /* Save unparsed command line copy for /proc/cmdline */ - strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); - - parse_early_param(); - -#ifdef CONFIG_SMP - /* - * iSeries has already initialized the cpu maps at this point. - */ - setup_cpu_maps(); - - /* Release secondary cpus out of their spinloops at 0x60 now that - * we can map physical -> logical CPU ids - */ - smp_release_cpus(); -#endif - - printk("Starting Linux PPC64 %s\n", system_utsname.version); - - printk("-----------------------------------------------------\n"); - printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); - printk("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch); - printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); - printk("systemcfg = 0x%p\n", systemcfg); - printk("systemcfg->platform = 0x%x\n", systemcfg->platform); - printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); - printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); - printk("ppc64_caches.dcache_line_size = 0x%x\n", - ppc64_caches.dline_size); - printk("ppc64_caches.icache_line_size = 0x%x\n", - ppc64_caches.iline_size); - printk("htab_address = 0x%p\n", htab_address); - printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); - printk("-----------------------------------------------------\n"); - - mm_init_ppc64(); - - DBG(" <- setup_system()\n"); -} - -/* also used by kexec */ -void machine_shutdown(void) -{ - if (ppc_md.nvram_sync) - ppc_md.nvram_sync(); -} - -void machine_restart(char *cmd) -{ - machine_shutdown(); - ppc_md.restart(cmd); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} - -void machine_power_off(void) -{ - machine_shutdown(); - ppc_md.power_off(); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} -/* Used by the G5 thermal driver */ -EXPORT_SYMBOL_GPL(machine_power_off); - -void machine_halt(void) -{ - machine_shutdown(); - ppc_md.halt(); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) ; -} - -static int ppc64_panic_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - ppc_md.panic((char *)ptr); /* May not return */ - return NOTIFY_DONE; -} - - -#ifdef CONFIG_SMP -DEFINE_PER_CPU(unsigned int, pvr); -#endif - -static int show_cpuinfo(struct seq_file *m, void *v) -{ - unsigned long cpu_id = (unsigned long)v - 1; - unsigned int pvr; - unsigned short maj; - unsigned short min; - - if (cpu_id == NR_CPUS) { - seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - - if (ppc_md.show_cpuinfo != NULL) - ppc_md.show_cpuinfo(m); - - return 0; - } - - /* We only show online cpus: disable preempt (overzealous, I - * knew) to prevent cpu going down. */ - preempt_disable(); - if (!cpu_online(cpu_id)) { - preempt_enable(); - return 0; - } - -#ifdef CONFIG_SMP - pvr = per_cpu(pvr, cpu_id); -#else - pvr = mfspr(SPRN_PVR); -#endif - maj = (pvr >> 8) & 0xFF; - min = pvr & 0xFF; - - seq_printf(m, "processor\t: %lu\n", cpu_id); - seq_printf(m, "cpu\t\t: "); - - if (cur_cpu_spec->pvr_mask) - seq_printf(m, "%s", cur_cpu_spec->cpu_name); - else - seq_printf(m, "unknown (%08x)", pvr); - -#ifdef CONFIG_ALTIVEC - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - seq_printf(m, ", altivec supported"); -#endif /* CONFIG_ALTIVEC */ - - seq_printf(m, "\n"); - - /* - * Assume here that all clock rates are the same in a - * smp system. -- Cort - */ - seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, - ppc_proc_freq % 1000000); - - seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min); - - preempt_enable(); - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL; -} -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} -static void c_stop(struct seq_file *m, void *v) -{ -} -struct seq_operations cpuinfo_op = { - .start =c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - -/* - * These three variables are used to save values passed to us by prom_init() - * via the device tree. The TCE variables are needed because with a memory_limit - * in force we may need to explicitly map the TCE are at the top of RAM. - */ -unsigned long memory_limit; -unsigned long tce_alloc_start; -unsigned long tce_alloc_end; - -#ifdef CONFIG_PPC_ISERIES -/* - * On iSeries we just parse the mem=X option from the command line. - * On pSeries it's a bit more complicated, see prom_init_mem() - */ -static int __init early_parsemem(char *p) -{ - if (!p) - return 0; - - memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE); - - return 0; -} -early_param("mem", early_parsemem); -#endif /* CONFIG_PPC_ISERIES */ - -#ifdef CONFIG_PPC_MULTIPLATFORM -static int __init set_preferred_console(void) -{ - struct device_node *prom_stdout = NULL; - char *name; - u32 *spd; - int offset = 0; - - DBG(" -> set_preferred_console()\n"); - - /* The user has requested a console so this is already set up. */ - if (strstr(saved_command_line, "console=")) { - DBG(" console was specified !\n"); - return -EBUSY; - } - - if (!of_chosen) { - DBG(" of_chosen is NULL !\n"); - return -ENODEV; - } - /* We are getting a weird phandle from OF ... */ - /* ... So use the full path instead */ - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (name == NULL) { - DBG(" no linux,stdout-path !\n"); - return -ENODEV; - } - prom_stdout = of_find_node_by_path(name); - if (!prom_stdout) { - DBG(" can't find stdout package %s !\n", name); - return -ENODEV; - } - DBG("stdout is %s\n", prom_stdout->full_name); - - name = (char *)get_property(prom_stdout, "name", NULL); - if (!name) { - DBG(" stdout package has no name !\n"); - goto not_found; - } - spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); - - if (0) - ; -#ifdef CONFIG_SERIAL_8250_CONSOLE - else if (strcmp(name, "serial") == 0) { - int i; - u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); - if (i > 8) { - switch (reg[1]) { - case 0x3f8: - offset = 0; - break; - case 0x2f8: - offset = 1; - break; - case 0x898: - offset = 2; - break; - case 0x890: - offset = 3; - break; - default: - /* We dont recognise the serial port */ - goto not_found; - } - } - } -#endif /* CONFIG_SERIAL_8250_CONSOLE */ -#ifdef CONFIG_PPC_PSERIES - else if (strcmp(name, "vty") == 0) { - u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); - char *compat = (char *)get_property(prom_stdout, "compatible", NULL); - - if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { - /* Host Virtual Serial Interface */ - int offset; - switch (reg[0]) { - case 0x30000000: - offset = 0; - break; - case 0x30000001: - offset = 1; - break; - default: - goto not_found; - } - of_node_put(prom_stdout); - DBG("Found hvsi console at offset %d\n", offset); - return add_preferred_console("hvsi", offset, NULL); - } else { - /* pSeries LPAR virtual console */ - of_node_put(prom_stdout); - DBG("Found hvc console\n"); - return add_preferred_console("hvc", 0, NULL); - } - } -#endif /* CONFIG_PPC_PSERIES */ -#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE - else if (strcmp(name, "ch-a") == 0) - offset = 0; - else if (strcmp(name, "ch-b") == 0) - offset = 1; -#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ - else - goto not_found; - of_node_put(prom_stdout); - - DBG("Found serial console at ttyS%d\n", offset); - - if (spd) { - static char __initdata opt[16]; - sprintf(opt, "%d", *spd); - return add_preferred_console("ttyS", offset, opt); - } else - return add_preferred_console("ttyS", offset, NULL); - - not_found: - DBG("No preferred console found !\n"); - of_node_put(prom_stdout); - return -ENODEV; -} -console_initcall(set_preferred_console); -#endif /* CONFIG_PPC_MULTIPLATFORM */ - -#ifdef CONFIG_IRQSTACKS -static void __init irqstack_early_init(void) -{ - unsigned int i; - - /* - * interrupt stacks must be under 256MB, we cannot afford to take - * SLB misses on them. - */ - for_each_cpu(i) { - softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, - THREAD_SIZE, 0x10000000)); - hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, - THREAD_SIZE, 0x10000000)); - } -} -#else -#define irqstack_early_init() -#endif - -/* - * Stack space used when we detect a bad kernel stack pointer, and - * early in SMP boots before relocation is enabled. - */ -static void __init emergency_stack_init(void) -{ - unsigned long limit; - unsigned int i; - - /* - * Emergency stacks must be under 256MB, we cannot afford to take - * SLB misses on them. The ABI also requires them to be 128-byte - * aligned. - * - * Since we use these as temporary stacks during secondary CPU - * bringup, we need to get at them in real mode. This means they - * must also be within the RMO region. - */ - limit = min(0x10000000UL, lmb.rmo_size); - - for_each_cpu(i) - paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128, - limit)) + PAGE_SIZE; -} - -/* - * Called from setup_arch to initialize the bitmap of available - * syscalls in the systemcfg page - */ -void __init setup_syscall_map(void) -{ - unsigned int i, count64 = 0, count32 = 0; - extern unsigned long *sys_call_table; - extern unsigned long *sys_call_table32; - extern unsigned long sys_ni_syscall; - - - for (i = 0; i < __NR_syscalls; i++) { - if (sys_call_table[i] == sys_ni_syscall) - continue; - count64++; - systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f); - } - for (i = 0; i < __NR_syscalls; i++) { - if (sys_call_table32[i] == sys_ni_syscall) - continue; - count32++; - systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f); - } - printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n", - count32, count64); -} - -/* - * Called into from start_kernel, after lock_kernel has been called. - * Initializes bootmem, which is unsed to manage page allocation until - * mem_init is called. - */ -void __init setup_arch(char **cmdline_p) -{ - extern void do_init_bootmem(void); - - ppc64_boot_msg(0x12, "Setup Arch"); - - *cmdline_p = cmd_line; - - /* - * Set cache line size based on type of cpu as a default. - * Systems with OF can look in the properties on the cpu node(s) - * for a possibly more accurate value. - */ - dcache_bsize = ppc64_caches.dline_size; - icache_bsize = ppc64_caches.iline_size; - - /* reboot on panic */ - panic_timeout = 180; - - if (ppc_md.panic) - notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); - - init_mm.start_code = PAGE_OFFSET; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = klimit; - - irqstack_early_init(); - emergency_stack_init(); - - stabs_alloc(); - - /* set up the bootmem stuff with available memory */ - do_init_bootmem(); - sparse_init(); - - /* initialize the syscall map in systemcfg */ - setup_syscall_map(); - -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - - ppc_md.setup_arch(); - - /* Use the default idle loop if the platform hasn't provided one. */ - if (NULL == ppc_md.idle_loop) { - ppc_md.idle_loop = default_idle; - printk(KERN_INFO "Using default idle loop\n"); - } - - paging_init(); - ppc64_boot_msg(0x15, "Setup Done"); -} - - -/* ToDo: do something useful if ppc_md is not yet setup. */ -#define PPC64_LINUX_FUNCTION 0x0f000000 -#define PPC64_IPL_MESSAGE 0xc0000000 -#define PPC64_TERM_MESSAGE 0xb0000000 - -static void ppc64_do_msg(unsigned int src, const char *msg) -{ - if (ppc_md.progress) { - char buf[128]; - - sprintf(buf, "%08X\n", src); - ppc_md.progress(buf, 0); - snprintf(buf, 128, "%s", msg); - ppc_md.progress(buf, 0); - } -} - -/* Print a boot progress message. */ -void ppc64_boot_msg(unsigned int src, const char *msg) -{ - ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); - printk("[boot]%04x %s\n", src, msg); -} - -/* Print a termination message (print only -- does not stop the kernel) */ -void ppc64_terminate_msg(unsigned int src, const char *msg) -{ - ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); - printk("[terminate]%04x %s\n", src, msg); -} - -#ifndef CONFIG_PPC_ISERIES -/* - * This function can be used by platforms to "find" legacy serial ports. - * It works for "serial" nodes under an "isa" node, and will try to - * respect the "ibm,aix-loc" property if any. It works with up to 8 - * ports. - */ - -#define MAX_LEGACY_SERIAL_PORTS 8 -static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1]; -static unsigned int old_serial_count; - -void __init generic_find_legacy_serial_ports(u64 *physport, - unsigned int *default_speed) -{ - struct device_node *np; - u32 *sizeprop; - - struct isa_reg_property { - u32 space; - u32 address; - u32 size; - }; - struct pci_reg_property { - struct pci_address addr; - u32 size_hi; - u32 size_lo; - }; - - DBG(" -> generic_find_legacy_serial_port()\n"); - - *physport = 0; - if (default_speed) - *default_speed = 0; - - np = of_find_node_by_path("/"); - if (!np) - return; - - /* First fill our array */ - for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { - struct device_node *isa, *pci; - struct isa_reg_property *reg; - unsigned long phys_size, addr_size, io_base; - u32 *rangesp; - u32 *interrupts, *clk, *spd; - char *typep; - int index, rlen, rentsize; - - /* Ok, first check if it's under an "isa" parent */ - isa = of_get_parent(np); - if (!isa || strcmp(isa->name, "isa")) { - DBG("%s: no isa parent found\n", np->full_name); - continue; - } - - /* Now look for an "ibm,aix-loc" property that gives us ordering - * if any... - */ - typep = (char *)get_property(np, "ibm,aix-loc", NULL); - - /* Get the ISA port number */ - reg = (struct isa_reg_property *)get_property(np, "reg", NULL); - if (reg == NULL) - goto next_port; - /* We assume the interrupt number isn't translated ... */ - interrupts = (u32 *)get_property(np, "interrupts", NULL); - /* get clock freq. if present */ - clk = (u32 *)get_property(np, "clock-frequency", NULL); - /* get default speed if present */ - spd = (u32 *)get_property(np, "current-speed", NULL); - /* Default to locate at end of array */ - index = old_serial_count; /* end of the array by default */ - - /* If we have a location index, then use it */ - if (typep && *typep == 'S') { - index = simple_strtol(typep+1, NULL, 0) - 1; - /* if index is out of range, use end of array instead */ - if (index >= MAX_LEGACY_SERIAL_PORTS) - index = old_serial_count; - /* if our index is still out of range, that mean that - * array is full, we could scan for a free slot but that - * make little sense to bother, just skip the port - */ - if (index >= MAX_LEGACY_SERIAL_PORTS) - goto next_port; - if (index >= old_serial_count) - old_serial_count = index + 1; - /* Check if there is a port who already claimed our slot */ - if (serial_ports[index].iobase != 0) { - /* if we still have some room, move it, else override */ - if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) { - DBG("Moved legacy port %d -> %d\n", index, - old_serial_count); - serial_ports[old_serial_count++] = - serial_ports[index]; - } else { - DBG("Replacing legacy port %d\n", index); - } - } - } - if (index >= MAX_LEGACY_SERIAL_PORTS) - goto next_port; - if (index >= old_serial_count) - old_serial_count = index + 1; - - /* Now fill the entry */ - memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port)); - serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16; - serial_ports[index].iobase = reg->address; - serial_ports[index].irq = interrupts ? interrupts[0] : 0; - serial_ports[index].flags = ASYNC_BOOT_AUTOCONF; - - DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", - index, - serial_ports[index].iobase, - serial_ports[index].irq, - serial_ports[index].uartclk); - - /* Get phys address of IO reg for port 1 */ - if (index != 0) - goto next_port; - - pci = of_get_parent(isa); - if (!pci) { - DBG("%s: no pci parent found\n", np->full_name); - goto next_port; - } - - rangesp = (u32 *)get_property(pci, "ranges", &rlen); - if (rangesp == NULL) { - of_node_put(pci); - goto next_port; - } - rlen /= 4; - - /* we need the #size-cells of the PCI bridge node itself */ - phys_size = 1; - sizeprop = (u32 *)get_property(pci, "#size-cells", NULL); - if (sizeprop != NULL) - phys_size = *sizeprop; - /* we need the parent #addr-cells */ - addr_size = prom_n_addr_cells(pci); - rentsize = 3 + addr_size + phys_size; - io_base = 0; - for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) { - if (((rangesp[0] >> 24) & 0x3) != 1) - continue; /* not IO space */ - io_base = rangesp[3]; - if (addr_size == 2) - io_base = (io_base << 32) | rangesp[4]; - } - if (io_base != 0) { - *physport = io_base + reg->address; - if (default_speed && spd) - *default_speed = *spd; - } - of_node_put(pci); - next_port: - of_node_put(isa); - } - - DBG(" <- generic_find_legacy_serial_port()\n"); -} - -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_ports, - }, -}; - -static int __init serial_dev_init(void) -{ - return platform_device_register(&serial_device); -} -arch_initcall(serial_dev_init); - -#endif /* CONFIG_PPC_ISERIES */ - -int check_legacy_ioport(unsigned long base_port) -{ - if (ppc_md.check_legacy_ioport == NULL) - return 0; - return ppc_md.check_legacy_ioport(base_port); -} -EXPORT_SYMBOL(check_legacy_ioport); - -#ifdef CONFIG_XMON -static int __init early_xmon(char *p) -{ - /* ensure xmon is enabled */ - if (p) { - if (strncmp(p, "on", 2) == 0) - xmon_init(1); - if (strncmp(p, "off", 3) == 0) - xmon_init(0); - if (strncmp(p, "early", 5) != 0) - return 0; - } - xmon_init(1); - debugger(NULL); - - return 0; -} -early_param("xmon", early_xmon); -#endif - -void cpu_die(void) -{ - if (ppc_md.cpu_die) - ppc_md.cpu_die(); -} From 25c8a78b1e00ac0cc640677eda78b462c2cd4c6e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 27 Oct 2005 16:27:25 +1000 Subject: [PATCH 0494/1940] [PATCH] powerpc: Fix handling of fpscr on 64-bit The recent merge of fpu.S broken the handling of fpscr for ARCH=powerpc and CONFIG_PPC64=y. FP registers could be corrupted, leading to strange random application crashes. The confusion arises, because the thread_struct has (and requires) a 64-bit area to save the fpscr, because we use load/store double instructions to get it in to/out of the FPU. However, only the low 32-bits are actually used, so we want to treat it as a 32-bit quantity when manipulating its bits to avoid extra load/stores on 32-bit. This patch replaces the current definition with a structure of two 32-bit quantities (pad and val), to clarify things as much as is possible. The 'val' field is used when manipulating bits, the structure itself is used when obtaining the address for loading/unloading the value from the FPU. While we're at it, consolidate the 4 (!) almost identical versions of cvt_fd() and cvt_df() (arch/ppc/kernel/misc.S, arch/ppc64/kernel/misc.S, arch/powerpc/kernel/misc_32.S, arch/powerpc/kernel/misc_64.S) into a single version in fpu.S. The new version takes a pointer to thread_struct and applies the correct offset itself, rather than a pointer to the fpscr field itself, again to avoid confusion as to which is the correct field to use. Finally, this patch makes ARCH=ppc64 also use the consolidated fpu.S code, which it previously did not. Built for G5 (ARCH=ppc64 and ARCH=powerpc), 32-bit powermac (ARCH=ppc and ARCH=powerpc) and Walnut (ARCH=ppc, CONFIG_MATH_EMULATION=y). Booted on G5 (ARCH=powerpc) and things which previously fell over no longer do. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 5 ++- arch/powerpc/kernel/fpu.S | 31 +++++++++++++++-- arch/powerpc/kernel/misc_32.S | 27 --------------- arch/powerpc/kernel/misc_64.S | 19 ----------- arch/powerpc/kernel/process.c | 2 +- arch/powerpc/kernel/signal_32.c | 2 +- arch/powerpc/kernel/traps.c | 2 +- arch/ppc/kernel/align.c | 4 +-- arch/ppc/kernel/misc.S | 27 --------------- arch/ppc/kernel/process.c | 2 +- arch/ppc/kernel/traps.c | 2 +- arch/ppc/math-emu/sfp-machine.h | 2 +- arch/ppc64/Kconfig | 3 ++ arch/ppc64/Makefile | 1 + arch/ppc64/kernel/align.c | 4 +-- arch/ppc64/kernel/head.S | 59 ++------------------------------- arch/ppc64/kernel/misc.S | 51 ---------------------------- arch/ppc64/kernel/signal.c | 2 +- include/asm-powerpc/processor.h | 11 +++--- include/asm-powerpc/system.h | 4 +-- include/asm-ppc/system.h | 4 +-- include/asm-ppc64/system.h | 4 +-- 22 files changed, 59 insertions(+), 209 deletions(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index a733347964a0..94cf917b7854 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -29,7 +29,6 @@ extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_PPC64) += entry_64.o -extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ @@ -49,7 +48,7 @@ else # stuff used from here for ARCH=ppc or ARCH=ppc64 obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o -fpux-$(CONFIG_PPC32) += fpu.o -extra-$(CONFIG_PPC_FPU) += $(fpux-y) endif + +extra-$(CONFIG_PPC_FPU) += fpu.o diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 563d445ff584..51fd78da25b7 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -48,7 +48,7 @@ _GLOBAL(load_up_fpu) addi r4,r4,THREAD /* want last_task_used_math->thread */ SAVE_32FPRS(0, r4) mffs fr0 - stfd fr0,THREAD_FPSCR-4(r4) + stfd fr0,THREAD_FPSCR(r4) LDL r5,PT_REGS(r4) tophys(r5,r5) LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) @@ -71,7 +71,7 @@ _GLOBAL(load_up_fpu) or r12,r12,r4 std r12,_MSR(r1) #endif - lfd fr0,THREAD_FPSCR-4(r5) + lfd fr0,THREAD_FPSCR(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP @@ -104,7 +104,7 @@ _GLOBAL(giveup_fpu) CMPI 0,r5,0 SAVE_32FPRS(0, r3) mffs fr0 - stfd fr0,THREAD_FPSCR-4(r3) + stfd fr0,THREAD_FPSCR(r3) beq 1f LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r3,MSR_FP|MSR_FE0|MSR_FE1 @@ -117,3 +117,28 @@ _GLOBAL(giveup_fpu) STL r5,OFF(last_task_used_math)(r4) #endif /* CONFIG_SMP */ blr + +/* + * These are used in the alignment trap handler when emulating + * single-precision loads and stores. + * We restore and save the fpscr so the task gets the same result + * and exceptions as if the cpu had performed the load or store. + */ + +_GLOBAL(cvt_fd) + lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfs 0,0(r3) + stfd 0,0(r4) + mffs 0 + stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */ + blr + +_GLOBAL(cvt_df) + lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ + mtfsf 0xff,0 + lfd 0,0(r3) + stfs 0,0(r4) + mffs 0 + stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */ + blr diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 303229b090b8..3bedb532aed9 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -992,33 +992,6 @@ _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ blr -/* - * These are used in the alignment trap handler when emulating - * single-precision loads and stores. - * We restore and save the fpscr so the task gets the same result - * and exceptions as if the cpu had performed the load or store. - */ - -#ifdef CONFIG_PPC_FPU -_GLOBAL(cvt_fd) - lfd 0,-4(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfs 0,0(r3) - stfd 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,-4(r5) - blr - -_GLOBAL(cvt_df) - lfd 0,-4(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfd 0,0(r3) - stfs 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,-4(r5) - blr -#endif - /* * Create a kernel thread * kernel_thread(fn, arg, flags) diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 4775bed42cac..b3e95ff0dba0 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -462,25 +462,6 @@ _GLOBAL(_outsl_ns) sync blr - -_GLOBAL(cvt_fd) - lfd 0,0(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfs 0,0(r3) - stfd 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,0(r5) - blr - -_GLOBAL(cvt_df) - lfd 0,0(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfd 0,0(r3) - stfs 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,0(r5) - blr - /* * identify_cpu and calls setup_cpu * In: r3 = base of the cpu_specs array diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 047da1ae21fe..8f85dabe4df3 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -665,7 +665,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #endif #endif /* CONFIG_SMP */ memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); - current->thread.fpscr = 0; + current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC memset(current->thread.vr, 0, sizeof(current->thread.vr)); memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 92452b2db26a..444c3e81884c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -403,7 +403,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, ELF_NFPREG * sizeof(double))) return 1; - current->thread.fpscr = 0; /* turn off all fp exceptions */ + current->thread.fpscr.val = 0; /* turn off all fp exceptions */ #ifdef CONFIG_ALTIVEC /* save altivec registers */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f87580382da4..5d638ecddbd0 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -549,7 +549,7 @@ static void parse_fpe(struct pt_regs *regs) flush_fp_to_thread(current); - fpscr = current->thread.fpscr; + fpscr = current->thread.fpscr.val; /* Invalid operation */ if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index ff81da9598d8..ab398c4b70b6 100644 --- a/arch/ppc/kernel/align.c +++ b/arch/ppc/kernel/align.c @@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs) #ifdef CONFIG_PPC_FPU preempt_disable(); enable_kernel_fp(); - cvt_fd(&data.f, &data.d, ¤t->thread.fpscr); + cvt_fd(&data.f, &data.d, ¤t->thread); preempt_enable(); #else return 0; @@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs) #ifdef CONFIG_PPC_FPU preempt_disable(); enable_kernel_fp(); - cvt_df(&data.d, &data.f, ¤t->thread.fpscr); + cvt_df(&data.d, &data.f, ¤t->thread); preempt_enable(); #else return 0; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 2350f3e09f95..3056ede2424d 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -967,33 +967,6 @@ _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ blr -/* - * These are used in the alignment trap handler when emulating - * single-precision loads and stores. - * We restore and save the fpscr so the task gets the same result - * and exceptions as if the cpu had performed the load or store. - */ - -#ifdef CONFIG_PPC_FPU -_GLOBAL(cvt_fd) - lfd 0,-4(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfs 0,0(r3) - stfd 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,-4(r5) - blr - -_GLOBAL(cvt_df) - lfd 0,-4(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfd 0,0(r3) - stfs 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,-4(r5) - blr -#endif - /* * Create a kernel thread * kernel_thread(fn, arg, flags) diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 6d60c40598e7..78ea10197a0b 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -542,7 +542,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) last_task_used_spe = NULL; #endif memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); - current->thread.fpscr = 0; + current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC memset(current->thread.vr, 0, sizeof(current->thread.vr)); memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 5e4bf88a1ef5..f265b81e7008 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -659,7 +659,7 @@ void program_check_exception(struct pt_regs *regs) giveup_fpu(current); preempt_enable(); - fpscr = current->thread.fpscr; + fpscr = current->thread.fpscr.val; fpscr &= fpscr << 22; /* mask summary bits with enables */ if (fpscr & FPSCR_VX) code = FPE_FLTINV; diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h index 686e06d29186..4b17d83cfcdd 100644 --- a/arch/ppc/math-emu/sfp-machine.h +++ b/arch/ppc/math-emu/sfp-machine.h @@ -166,7 +166,7 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long); #include #include -#define __FPU_FPSCR (current->thread.fpscr) +#define __FPU_FPSCR (current->thread.fpscr.val) /* We only actually write to the destination register * if exceptions signalled (if any) will not trap. diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 8cc73cc1b4c4..b889277ab7de 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -197,6 +197,9 @@ config BOOTX_TEXT config POWER4 def_bool y +config PPC_FPU + def_bool y + config POWER4_ONLY bool "Optimize for POWER4" default n diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 4d18bdb680f0..ba59225fd373 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -80,6 +80,7 @@ endif CFLAGS += $(call cc-option,-funit-at-a-time) head-y := arch/ppc64/kernel/head.o +head-y += arch/powerpc/kernel/fpu.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c index 330e7ef81427..256d5b592aa1 100644 --- a/arch/ppc64/kernel/align.c +++ b/arch/ppc64/kernel/align.c @@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs) /* Doing stfs, have to convert to single */ preempt_disable(); enable_kernel_fp(); - cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr); + cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread); disable_kernel_fp(); preempt_enable(); } @@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs) /* Doing lfs, have to convert to double */ preempt_disable(); enable_kernel_fp(); - cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr); + cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread); disable_kernel_fp(); preempt_enable(); } diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index f58af9c246cb..929f9f42cf7a 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -81,7 +81,7 @@ _stext: _GLOBAL(__start) /* NOP this out unconditionally */ BEGIN_FTR_SECTION - b .__start_initialization_multiplatform + b .__start_initialization_multiplatform END_FTR_SECTION(0, 1) #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -747,6 +747,7 @@ bad_stack: * any task or sent any task a signal, you should use * ret_from_except or ret_from_except_lite instead of this. */ + .globl fast_exception_return fast_exception_return: ld r12,_MSR(r1) ld r11,_NIP(r1) @@ -858,62 +859,6 @@ fp_unavailable_common: bl .kernel_fp_unavailable_exception BUG_OPCODE -/* - * load_up_fpu(unused, unused, tsk) - * Disable FP for the task which had the FPU previously, - * and save its floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - * On SMP we know the fpu is free, since we give it up every - * switch (ie, no lazy save of the FP registers). - * On entry: r13 == 'current' && last_task_used_math != 'current' - */ -_STATIC(load_up_fpu) - mfmsr r5 /* grab the current MSR */ - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - * - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_math@got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save FP state to last_task_used_math's THREAD struct */ - addi r4,r4,THREAD - SAVE_32FPRS(0, r4) - mffs fr0 - stfd fr0,THREAD_FPSCR(r4) - /* Disable FP for last_task_used_math */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r6,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* enable use of FP after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - ld r4,THREAD_FPEXC_MODE(r5) - ori r12,r12,MSR_FP - or r12,r12,r4 - std r12,_MSR(r1) - lfd fr0,THREAD_FPSCR(r5) - mtfsf 0xff,fr0 - REST_32FPRS(0, r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - .align 7 .globl altivec_unavailable_common altivec_unavailable_common: diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index a33448c2bd91..9cae3d5c40e6 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -451,25 +451,6 @@ _GLOBAL(_outsl_ns) sync blr - -_GLOBAL(cvt_fd) - lfd 0,0(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfs 0,0(r3) - stfd 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,0(r5) - blr - -_GLOBAL(cvt_df) - lfd 0,0(r5) /* load up fpscr value */ - mtfsf 0xff,0 - lfd 0,0(r3) - stfs 0,0(r4) - mffs 0 /* save new fpscr value */ - stfd 0,0(r5) - blr - /* * identify_cpu and calls setup_cpu * In: r3 = base of the cpu_specs array @@ -655,38 +636,6 @@ _GLOBAL(disable_kernel_fp) isync blr -/* - * giveup_fpu(tsk) - * Disable FP for the task given as the argument, - * and save the floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - */ -_GLOBAL(giveup_fpu) - mfmsr r5 - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - SAVE_32FPRS(0, r3) - mffs fr0 - stfd fr0,THREAD_FPSCR(r3) - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r3,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r3 /* disable FP for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_math@got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ - blr - #ifdef CONFIG_ALTIVEC #if 0 /* this has no callers for now */ diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index 347112cca3c0..ec9d0984b6a0 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c @@ -133,7 +133,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, flush_fp_to_thread(current); /* Make sure signal doesn't get spurrious FP exceptions */ - current->thread.fpscr = 0; + current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC err |= __put_user(v_regs, &sc->v_regs); diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 9592f533e058..eee954a001fd 100644 --- a/include/asm-powerpc/processor.h +++ b/include/asm-powerpc/processor.h @@ -162,10 +162,11 @@ struct thread_struct { unsigned long dbcr1; #endif double fpr[32]; /* Complete floating point set */ -#ifdef CONFIG_PPC32 - unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ -#endif - unsigned long fpscr; /* Floating point status */ + struct { /* fpr ... fpscr must be contiguous */ + + unsigned int pad; + unsigned int val; /* Floating point status */ + } fpscr; int fpexc_mode; /* floating-point exception mode */ #ifdef CONFIG_PPC64 unsigned long start_tb; /* Start purr when proc switched in */ @@ -207,7 +208,7 @@ struct thread_struct { .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ .fs = KERNEL_DS, \ .fpr = {0}, \ - .fpscr = 0, \ + .fpscr = { .val = 0, }, \ .fpexc_mode = MSR_FE0|MSR_FE1, \ } #endif diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index d60c8c928922..e926e43c4ae6 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -132,8 +132,8 @@ extern int emulate_altivec(struct pt_regs *); extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern int fix_alignment(struct pt_regs *); -extern void cvt_fd(float *from, double *to, unsigned long *fpscr); -extern void cvt_df(double *from, float *to, unsigned long *fpscr); +extern void cvt_fd(float *from, double *to, struct thread_struct *thread); +extern void cvt_df(double *from, float *to, struct thread_struct *thread); #ifdef CONFIG_ALTIVEC extern void flush_altivec_to_thread(struct task_struct *); diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 1f310783757e..eb30c09516ae 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -82,8 +82,8 @@ extern int emulate_altivec(struct pt_regs *); extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); extern int fix_alignment(struct pt_regs *); -extern void cvt_fd(float *from, double *to, unsigned long *fpscr); -extern void cvt_df(double *from, float *to, unsigned long *fpscr); +extern void cvt_fd(float *from, double *to, struct thread_struct *thread); +extern void cvt_df(double *from, float *to, struct thread_struct *thread); #ifdef CONFIG_ALTIVEC extern void flush_altivec_to_thread(struct task_struct *); diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 2e17ef7dbeb4..fd7c1f890c45 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_struct *); extern void disable_kernel_altivec(void); extern void enable_kernel_altivec(void); extern int emulate_altivec(struct pt_regs *); -extern void cvt_fd(float *from, double *to, unsigned long *fpscr); -extern void cvt_df(double *from, float *to, unsigned long *fpscr); +extern void cvt_fd(float *from, double *to, struct thread_struct *thread); +extern void cvt_df(double *from, float *to, struct thread_struct *thread); #ifdef CONFIG_ALTIVEC extern void flush_altivec_to_thread(struct task_struct *); From e37bc5df8e96c72f27ec3579499726b656e4e641 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 24 Oct 2005 11:41:33 +1000 Subject: [PATCH 0495/1940] [PATCH] powerpc: Purge bootinfo.h With ARCH=powerpc we assume the presence of a device tree, so we don't require any support for the old bi_recs method of passing boot parameters. Likewise, we've never needed it for ppc64, but we still had an include/asm-ppc64/bootinfo.h from which nothing was used. This patch removes that file, and all references to it in arch/ppc64 and arch/powerpc. A related, unused variable 'boot_mem_size' is also removed from setup_32.c. The bootinfo stuff remains in ARCH=ppc for the time being. Built and booted on Power5 (ARCH=ppc64 and ARCH=powerpc), built for 32-bit powermac (ARCH=powerpc and ARCH=ppc). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 1 - arch/powerpc/kernel/setup_32.c | 5 ----- arch/powerpc/kernel/setup_64.c | 1 - arch/powerpc/mm/init_32.c | 1 - arch/powerpc/mm/mem.c | 1 - arch/ppc64/kernel/prom.c | 1 - arch/ppc64/kernel/prom_init.c | 1 - 7 files changed, 11 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 2ad9947bd675..9750b3cd8ecd 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 0cac112ca89d..21ef643a0208 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -60,10 +59,6 @@ struct ide_machdep_calls ppc_ide_md; int __irq_offset_value; EXPORT_SYMBOL(__irq_offset_value); -/* Used with the BI_MEMSIZE bootinfo parameter to store the memory - size value reported by the boot loader. */ -unsigned long boot_mem_size; - unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 721adeea601d..a8f7ff5ab1a4 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 8dd1f7d0e23c..4612a79dfb6e 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 5e9206715f09..695db6a588ce 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index a0866f12647f..cd41a47dd43f 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index f252670874a4..69924ba4d7d9 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include From 2765ca254060adb9a5abc2cfc6264b8daafc5742 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 24 Oct 2005 13:07:23 +1000 Subject: [PATCH 0496/1940] [PATCH] powerpc: Merge parport.h Save for the header #define, ppc32 and ppc64 versions of parport.h are identical. This patch merges them. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/parport.h | 6 +++--- include/asm-ppc64/parport.h | 18 ------------------ 2 files changed, 3 insertions(+), 21 deletions(-) rename include/{asm-ppc => asm-powerpc}/parport.h (80%) delete mode 100644 include/asm-ppc64/parport.h diff --git a/include/asm-ppc/parport.h b/include/asm-powerpc/parport.h similarity index 80% rename from include/asm-ppc/parport.h rename to include/asm-powerpc/parport.h index 11f96d3de5b6..d86b410a6f8b 100644 --- a/include/asm-ppc/parport.h +++ b/include/asm-powerpc/parport.h @@ -6,8 +6,8 @@ * This file should only be included by drivers/parport/parport_pc.c. */ -#ifndef _ASM_PPC_PARPORT_H -#define _ASM_PPC_PARPORT_H +#ifndef _ASM_POWERPC_PARPORT_H +#define _ASM_POWERPC_PARPORT_H static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) @@ -15,4 +15,4 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) return parport_pc_find_isa_ports (autoirq, autodma); } -#endif /* !(_ASM_PPC_PARPORT_H) */ +#endif /* !(_ASM_POWERPC_PARPORT_H) */ diff --git a/include/asm-ppc64/parport.h b/include/asm-ppc64/parport.h deleted file mode 100644 index 2f8874c581cc..000000000000 --- a/include/asm-ppc64/parport.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef _ASM_PPC64_PARPORT_H -#define _ASM_PPC64_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASM_PPC_PARPORT_H) */ From 328985b2c69d2592edd7f181a6b7360e51b08515 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 24 Oct 2005 14:05:38 +1000 Subject: [PATCH 0497/1940] [PATCH] powerpc: Don't use kmalloc() for kernel stacks In readiness for 64k pages, when THREAD_SIZE will be less than PAGE_SIZE, ppc64 uses kmalloc() rather than __get_free_pages() to allocate kernel stacks, and since thread_info.h was merged, so does ppc32. However that adds some overhead which we don't really want when PAGE_SIZE <= THREAD_SIZE (including all ppc32 machines), so this patch avoids it. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- include/asm-powerpc/thread_info.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index 0b4c24551c21..ab17db79f69d 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -66,19 +66,26 @@ struct thread_info { /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) \ - ({ \ - struct thread_info *ret; \ - \ - ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \ - if (ret) \ - memset(ret, 0, THREAD_SIZE); \ - ret; \ - }) +#define THREAD_INFO_GFP GFP_KERNEL | __GFP_ZERO #else -#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) +#define THREAD_INFO_GFP GFP_KERNEL #endif + +#if THREAD_SHIFT >= PAGE_SHIFT + +#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT) + +#define alloc_thread_info(tsk) \ + ((struct thread_info *)__get_free_pages(THREAD_INFO_GFP, THREAD_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long)ti, THREAD_ORDER) + +#else /* THREAD_SHIFT < PAGE_SHIFT */ + +#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, THREAD_INFO_GFP) #define free_thread_info(ti) kfree(ti) + +#endif /* THREAD_SHIFT < PAGE_SHIFT */ + #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) From cffb09ce6ba7706c89c6df9ca8e72c81adda13f0 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 26 Oct 2005 09:55:41 -0500 Subject: [PATCH 0498/1940] [PATCH] powerpc: Fix warning related to do_dabr do_dabr() is not relevant on 40x or Book-E processors so dont build it Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/mm/fault.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 3df641fa789d..841d8b6323a8 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -80,6 +80,7 @@ static int store_updates_sp(struct pt_regs *regs) return 0; } +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) static void do_dabr(struct pt_regs *regs, unsigned long error_code) { siginfo_t info; @@ -101,6 +102,7 @@ static void do_dabr(struct pt_regs *regs, unsigned long error_code) info.si_addr = (void __user *)regs->nip; force_sig_info(SIGTRAP, &info, current); } +#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ /* * For 600- and 800-family processors, the error_code parameter is DSISR From 4b24b01c6c0bab24e6a4c3e4a02d53b564f2d05c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 26 Oct 2005 09:56:10 -0500 Subject: [PATCH 0499/1940] [PATCH] powerpc: Moved dcr support to arch/powerpc Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/Makefile | 2 ++ arch/{ppc/syslib => powerpc/sysdev}/dcr.S | 0 arch/ppc/syslib/Makefile | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) rename arch/{ppc/syslib => powerpc/sysdev}/dcr.S (100%) diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 97119c0ffc72..d071ae875e25 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -2,3 +2,5 @@ obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_MPC106) += grackle.o +obj-$(CONFIG_BOOKE) += dcr.o +obj-$(CONFIG_40x) += dcr.o diff --git a/arch/ppc/syslib/dcr.S b/arch/powerpc/sysdev/dcr.S similarity index 100% rename from arch/ppc/syslib/dcr.S rename to arch/powerpc/sysdev/dcr.S diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index e6e6aa4d291e..b4ef15b45c4a 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -86,8 +86,6 @@ endif obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o -obj-$(CONFIG_40x) += dcr.o -obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ ppc_sys.o mpc85xx_sys.o \ mpc85xx_devices.o From eef69e3cfb38d83166dbd8bcb12ededa1b6e78b6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 22:21:37 +1000 Subject: [PATCH 0500/1940] powerpc: remove duplicate screen_info from setup_32.c Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 21ef643a0208..150a919269ae 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -94,21 +94,6 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ - defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) -struct screen_info screen_info = { - 0, 25, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 80, /* orig-video-cols */ - 0,0,0, /* ega_ax, ega_bx, ega_cx */ - 25, /* orig-video-lines */ - 1, /* orig-video-isVGA */ - 16 /* orig-video-points */ -}; -#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ - /* * We're called here very early in the boot. We determine the machine * type and call the appropriate low-level setup functions. From 80579e1f4a6b5f5dec92faa6c3e0645961c99091 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 22:42:04 +1000 Subject: [PATCH 0501/1940] powerpc: 32-bit CHRP SMP fixes Untested, but "should" work... at least this way it compiles. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 12 +++++----- arch/powerpc/kernel/setup_32.c | 4 ++++ arch/powerpc/platforms/chrp/smp.c | 40 ++++++++++++++++++++++++++----- include/asm-ppc/smp.h | 10 +++++++- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ab9b291dda54..6309a1a17c4a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1110,22 +1110,22 @@ static int __init early_init_dt_scan_cpus(unsigned long node, } #endif -#ifdef CONFIG_PPC64 + boot_cpuid = 0; + boot_cpuid_phys = 0; if (initial_boot_params && initial_boot_params->version >= 2) { /* version 2 of the kexec param format adds the phys cpuid * of booted proc. */ boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; - boot_cpuid = 0; } else { - /* Check if it's the boot-cpu, set it's hw index in paca now */ + /* Check if it's the boot-cpu, set it's hw index now */ if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { prop = get_flat_dt_prop(node, "reg", NULL); - set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); - boot_cpuid_phys = get_hard_smp_processor_id(0); + if (prop != NULL) + boot_cpuid_phys = *prop; } } -#endif + set_hard_smp_processor_id(0, boot_cpuid_phys); #ifdef CONFIG_ALTIVEC /* Check if we have a VMX and eventually update CPU features */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 150a919269ae..7c99e6b8c76c 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -59,6 +59,10 @@ struct ide_machdep_calls ppc_ide_md; int __irq_offset_value; EXPORT_SYMBOL(__irq_offset_value); +int boot_cpuid; +EXPORT_SYMBOL_GPL(boot_cpuid); +int boot_cpuid_phys; + unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index bf68282670dd..31ee49c25014 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c @@ -32,15 +32,44 @@ #include #include #include +#include +#include extern unsigned long smp_chrp_cpu_nr; static int __init smp_chrp_probe(void) { - if (smp_chrp_cpu_nr > 1) - openpic_request_IPIs(); + struct device_node *cpus = NULL; + unsigned int *reg; + int reglen; + int ncpus = 0; + int cpuid; + unsigned int phys; - return smp_chrp_cpu_nr; + /* Count CPUs in the device-tree */ + cpuid = 1; /* the boot cpu is logical cpu 0 */ + while ((cpus = of_find_node_by_type(cpus, "cpu")) != NULL) { + phys = ncpus; + reg = (unsigned int *) get_property(cpus, "reg", ®len); + if (reg && reglen >= sizeof(unsigned int)) + /* hmmm, not having a reg property would be bad */ + phys = *reg; + if (phys != boot_cpuid_phys) { + set_hard_smp_processor_id(cpuid, phys); + ++cpuid; + } + ++ncpus; + } + + printk(KERN_INFO "CHRP SMP probe found %d cpus\n", ncpus); + + /* Nothing more to do if less than 2 of them */ + if (ncpus <= 1) + return 1; + + mpic_request_ipis(); + + return ncpus; } static void __devinit smp_chrp_kick_cpu(int nr) @@ -51,8 +80,7 @@ static void __devinit smp_chrp_kick_cpu(int nr) static void __devinit smp_chrp_setup_cpu(int cpu_nr) { - if (OpenPIC_Addr) - do_openpic_setup_cpu(); + mpic_setup_this_cpu(); } static DEFINE_SPINLOCK(timebase_lock); @@ -85,7 +113,7 @@ void __devinit smp_chrp_take_timebase(void) /* CHRP with openpic */ struct smp_ops_t chrp_smp_ops = { - .message_pass = smp_openpic_message_pass, + .message_pass = smp_mpic_message_pass, .probe = smp_chrp_probe, .kick_cpu = smp_chrp_kick_cpu, .setup_cpu = smp_chrp_setup_cpu, diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 063d7dedc691..30e9268a888c 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -53,16 +53,24 @@ extern int __cpu_up(unsigned int cpu); extern int smp_hw_index[]; #define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) #define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)]) - +#define set_hard_smp_processor_id(cpu, phys)\ + (smp_hw_index[(cpu)] = (phys)) + #endif /* __ASSEMBLY__ */ #else /* !(CONFIG_SMP) */ static inline void cpu_die(void) { } #define get_hard_smp_processor_id(cpu) 0 +#define set_hard_smp_processor_id(cpu, phys) #define hard_smp_processor_id() 0 #endif /* !(CONFIG_SMP) */ +#ifndef __ASSEMBLY__ +extern int boot_cpuid; +extern int boot_cpuid_phys; +#endif + #endif /* !(_PPC_SMP_H) */ #endif /* __KERNEL__ */ From 6316222ea050d469c3155881d9dee2c7671d9fef Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 22:44:39 +1000 Subject: [PATCH 0502/1940] powerpc: Introduce toreal/fromreal assembly macros On 32-bit platforms, these convert from kernel virtual addresses to real (physical addresses), like tophys/tovirt but they use the same register for the source and destination. On 64-bit platforms, they do nothing because the hardware ignores the top two bits of the address in real mode. These new macros are used in fpu.S now. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/fpu.S | 8 ++++---- include/asm-powerpc/ppc_asm.h | 29 +++++++++++++++-------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 51fd78da25b7..4d6001fa1cf2 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -40,17 +40,17 @@ _GLOBAL(load_up_fpu) */ #ifndef CONFIG_SMP LOADBASE(r3, last_task_used_math) - tophys(r3,r3) + toreal(r3) LDL r4,OFF(last_task_used_math)(r3) CMPI 0,r4,0 beq 1f - tophys(r4,r4) + toreal(r4) addi r4,r4,THREAD /* want last_task_used_math->thread */ SAVE_32FPRS(0, r4) mffs fr0 stfd fr0,THREAD_FPSCR(r4) LDL r5,PT_REGS(r4) - tophys(r5,r5) + toreal(r5) LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r10,MSR_FP|MSR_FE0|MSR_FE1 andc r4,r4,r10 /* disable FP for previous task */ @@ -76,7 +76,7 @@ _GLOBAL(load_up_fpu) REST_32FPRS(0, r5) #ifndef CONFIG_SMP subi r4,r5,THREAD - tovirt(r4,r4) + fromreal(r4) STL r4,OFF(last_task_used_math)(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index f8ad5df6ebef..470d7400ac59 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -154,7 +154,7 @@ GLUE(.,name): * loads the address of 'name' into 'rn' * * LOADBASE( rn, name ) - * loads the address (less the low 16 bits) of 'name' into 'rn' + * loads the address (possibly without the low 16 bits) of 'name' into 'rn' * suitable for base+disp addressing */ #ifdef __powerpc64__ @@ -166,10 +166,7 @@ GLUE(.,name): ori rn,rn,name##@l #define LOADBASE(rn,name) \ - .section .toc,"aw"; \ -1: .tc name[TC],name; \ - .previous; \ - ld rn,1b@toc(r2) + ld rn,name@got(r2) #define OFF(name) 0 @@ -278,6 +275,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #if defined(CONFIG_BOOKE) +#define toreal(rd) +#define fromreal(rd) + #define tophys(rd,rs) \ addis rd,rs,0 @@ -285,23 +285,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) addis rd,rs,0 #elif defined(CONFIG_PPC64) -/* PPPBBB - DRENG If KERNELBASE is always 0xC0..., - * Then we can easily do this with one asm insn. -Peter - */ +#define toreal(rd) /* we can access c000... in real mode */ +#define fromreal(rd) + #define tophys(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - sub rd,rs,rd + clrldi rd,rs,2 #define tovirt(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - add rd,rs,rd + rotldi rd,rs,16; \ + ori rd,rd,((KERNELBASE>>48)&0xFFFF);\ + rotldi rd,rd,48 #else /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the * physical base address of RAM at compile time. */ +#define toreal(rd) tophys(rd,rd) +#define fromreal(rd) tovirt(rd,rd) + #define tophys(rd,rs) \ 0: addis rd,rs,-KERNELBASE@h; \ .section ".vtop_fixup","aw"; \ From bfab1019b7e8b499dfc471a0dfc98b587420dda9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 27 Oct 2005 22:45:33 +1000 Subject: [PATCH 0503/1940] powerpc: Fix new-world powermac detection My G5 was being reported as an OldWorld in /proc/cpuinfo, which is obviously not right... :) Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 72cd503d3d33..6f62af597291 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -317,7 +317,9 @@ void __init pmac_setup_arch(void) } /* See if newworld or oldworld */ - ic = of_find_node_by_name(NULL, "interrupt-controller"); + for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) + if (get_property(ic, "interrupt-controller", NULL)) + break; pmac_newworld = (ic != NULL); if (ic) of_node_put(ic); From 3d155f8cd0d077938d271225d26ee52f8eb26082 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 27 Oct 2005 11:03:38 -0700 Subject: [PATCH 0504/1940] [IB] mthca: first pass at catastrophic error reporting Add some initial support for detecting and reporting catastrophic errors reported by Mellanox HCAs. We start a periodic timer which polls the catastrophic error reporting buffer in device memory. If an error is detected, we dump the contents of the buffer for port-mortem debugging, and report a fatal asynchronous error to higher levels. In the future we can try to recover from these errors by resetting the device, but this will require some work in higher-level code as well. Let's get this in now, so that we at least get catastrophic errors reported in logs. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/Makefile | 3 +- drivers/infiniband/hw/mthca/mthca_catas.c | 153 +++++++++++++++++++ drivers/infiniband/hw/mthca/mthca_cmd.c | 5 + drivers/infiniband/hw/mthca/mthca_dev.h | 13 ++ drivers/infiniband/hw/mthca/mthca_provider.c | 3 + 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 drivers/infiniband/hw/mthca/mthca_catas.c diff --git a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile index c44f7bae5424..47ec5a7cba0b 100644 --- a/drivers/infiniband/hw/mthca/Makefile +++ b/drivers/infiniband/hw/mthca/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \ mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \ mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \ - mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o + mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o \ + mthca_catas.o diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c new file mode 100644 index 000000000000..7ac52af43b99 --- /dev/null +++ b/drivers/infiniband/hw/mthca/mthca_catas.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005 Cisco Systems. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * $Id$ + */ + +#include "mthca_dev.h" + +enum { + MTHCA_CATAS_POLL_INTERVAL = 5 * HZ, + + MTHCA_CATAS_TYPE_INTERNAL = 0, + MTHCA_CATAS_TYPE_UPLINK = 3, + MTHCA_CATAS_TYPE_DDR = 4, + MTHCA_CATAS_TYPE_PARITY = 5, +}; + +static DEFINE_SPINLOCK(catas_lock); + +static void handle_catas(struct mthca_dev *dev) +{ + struct ib_event event; + const char *type; + int i; + + event.device = &dev->ib_dev; + event.event = IB_EVENT_DEVICE_FATAL; + event.element.port_num = 0; + + ib_dispatch_event(&event); + + switch (swab32(readl(dev->catas_err.map)) >> 24) { + case MTHCA_CATAS_TYPE_INTERNAL: + type = "internal error"; + break; + case MTHCA_CATAS_TYPE_UPLINK: + type = "uplink bus error"; + break; + case MTHCA_CATAS_TYPE_DDR: + type = "DDR data error"; + break; + case MTHCA_CATAS_TYPE_PARITY: + type = "internal parity error"; + break; + default: + type = "unknown error"; + break; + } + + mthca_err(dev, "Catastrophic error detected: %s\n", type); + for (i = 0; i < dev->catas_err.size; ++i) + mthca_err(dev, " buf[%02x]: %08x\n", + i, swab32(readl(dev->catas_err.map + i))); +} + +static void poll_catas(unsigned long dev_ptr) +{ + struct mthca_dev *dev = (struct mthca_dev *) dev_ptr; + unsigned long flags; + int i; + + for (i = 0; i < dev->catas_err.size; ++i) + if (readl(dev->catas_err.map + i)) { + handle_catas(dev); + return; + } + + spin_lock_irqsave(&catas_lock, flags); + if (dev->catas_err.stop) + mod_timer(&dev->catas_err.timer, + jiffies + MTHCA_CATAS_POLL_INTERVAL); + spin_unlock_irqrestore(&catas_lock, flags); + + return; +} + +void mthca_start_catas_poll(struct mthca_dev *dev) +{ + unsigned long addr; + + init_timer(&dev->catas_err.timer); + dev->catas_err.stop = 0; + dev->catas_err.map = NULL; + + addr = pci_resource_start(dev->pdev, 0) + + ((pci_resource_len(dev->pdev, 0) - 1) & + dev->catas_err.addr); + + if (!request_mem_region(addr, dev->catas_err.size * 4, + DRV_NAME)) { + mthca_warn(dev, "couldn't request catastrophic error region " + "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4); + return; + } + + dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4); + if (!dev->catas_err.map) { + mthca_warn(dev, "couldn't map catastrophic error region " + "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4); + release_mem_region(addr, dev->catas_err.size * 4); + return; + } + + dev->catas_err.timer.data = (unsigned long) dev; + dev->catas_err.timer.function = poll_catas; + dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL; + add_timer(&dev->catas_err.timer); +} + +void mthca_stop_catas_poll(struct mthca_dev *dev) +{ + spin_lock_irq(&catas_lock); + dev->catas_err.stop = 1; + spin_unlock_irq(&catas_lock); + + del_timer_sync(&dev->catas_err.timer); + + if (dev->catas_err.map) { + iounmap(dev->catas_err.map); + release_mem_region(pci_resource_start(dev->pdev, 0) + + ((pci_resource_len(dev->pdev, 0) - 1) & + dev->catas_err.addr), + dev->catas_err.size * 4); + } +} diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 1bd7dc8f778c..9220473dbfbd 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Cisco Systems. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -706,9 +707,13 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); dev->cmd.max_cmds = 1 << lg; + MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET); + MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET); mthca_dbg(dev, "FW version %012llx, max commands %d\n", (unsigned long long) dev->fw_ver, dev->cmd.max_cmds); + mthca_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x\n", + (unsigned long long) dev->catas_err.addr, dev->catas_err.size); if (mthca_is_memfree(dev)) { MTHCA_GET(dev->fw.arbel.fw_pages, outbox, QUERY_FW_SIZE_OFFSET); diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index f106bac0f925..7e68bd4a3780 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -258,6 +258,14 @@ struct mthca_mcg_table { struct mthca_icm_table *table; }; +struct mthca_catas_err { + u64 addr; + u32 __iomem *map; + unsigned long stop; + u32 size; + struct timer_list timer; +}; + struct mthca_dev { struct ib_device ib_dev; struct pci_dev *pdev; @@ -318,6 +326,8 @@ struct mthca_dev { struct mthca_av_table av_table; struct mthca_mcg_table mcg_table; + struct mthca_catas_err catas_err; + struct mthca_uar driver_uar; struct mthca_db_table *db_tab; struct mthca_pd driver_pd; @@ -405,6 +415,9 @@ void mthca_cleanup_mcg_table(struct mthca_dev *dev); int mthca_register_device(struct mthca_dev *dev); void mthca_unregister_device(struct mthca_dev *dev); +void mthca_start_catas_poll(struct mthca_dev *dev); +void mthca_stop_catas_poll(struct mthca_dev *dev); + int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar); void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 9e911a1ea415..1b9477edbd7b 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1175,10 +1175,13 @@ int mthca_register_device(struct mthca_dev *dev) } } + mthca_start_catas_poll(dev); + return 0; } void mthca_unregister_device(struct mthca_dev *dev) { + mthca_stop_catas_poll(dev); ib_unregister_device(&dev->ib_dev); } From 0753ca7bc2b876dd136e9db11a20f85cbe4e08b1 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 27 Oct 2005 13:55:12 -0700 Subject: [PATCH 0505/1940] [CIFS] Change pragma pack(1) to attribute(packed) to allow cifs on arm to access unaligned structures coming in off the wire gcc on arm processors generates very odd code with pragma pack specified - although it does pack the structures in some sense - it does not allow you to access unaligned elements in nested structures at the right offset as other architectures do. Oddly enough though, specifying the structures as packed the long way - one by one with the packed attribute does work. Rather than fighting over whether this is a gcc bug or some obscure side effect of pragma pack, it is easier to do what most (all but 96 other places in the kernel) do - and replace pragma pack with dozens of attribute(packed) structure qualifiers. Much more verbose ... but at least it works. Signed-off-by: David Kleikamp Signed-off-by: Steve French CG: ----------------------------------------------------------------------- --- fs/cifs/cifspdu.h | 343 ++++++++++++++++++++++--------------------- fs/cifs/ntlmssp.h | 12 +- fs/cifs/rfc1002pdu.h | 13 +- 3 files changed, 182 insertions(+), 186 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 193f06eb43f9..48a05b9df7eb 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -80,7 +80,7 @@ #define NT_TRANSACT_GET_USER_QUOTA 0x07 #define NT_TRANSACT_SET_USER_QUOTA 0x08 -#define MAX_CIFS_HDR_SIZE 256 /* chained NTCreateXReadX will probably be biggest */ +#define MAX_CIFS_HDR_SIZE 256 /* is future chained NTCreateXReadX bigger? */ /* internal cifs vfs structures */ /***************************************************************** @@ -133,10 +133,11 @@ /* * SMB flag definitions */ -#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock primitives */ +#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */ #define SMBFLG_RCV_POSTED 0x02 /* obsolete */ #define SMBFLG_RSVD 0x04 -#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off implies case sensitive file handling requested) */ +#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off + implies case sensitive file handling request) */ #define SMBFLG_CANONICAL_PATH_FORMAT 0x10 /* obsolete */ #define SMBFLG_OLD_OPLOCK 0x20 /* obsolete */ #define SMBFLG_OLD_OPLOCK_NOTIFY 0x40 /* obsolete */ @@ -145,7 +146,8 @@ /* * SMB flag2 definitions */ -#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) path names in response */ +#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) + path names in response */ #define SMBFLG2_KNOWS_EAS cpu_to_le16(2) #define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) #define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) @@ -164,32 +166,32 @@ * file and can have any suitable combination of the following values: */ -#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */ -#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */ -#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */ -#define FILE_READ_EA 0x00000008 /* Extended attributes associated */ - /* with the file can be read */ -#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */ - /* with the file can be written */ -#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */ - /* the file using system paging I/O */ +#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */ +#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */ +#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */ +#define FILE_READ_EA 0x00000008 /* Extended attributes associated */ + /* with the file can be read */ +#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */ + /* with the file can be written */ +#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */ + /* the file using system paging I/O */ #define FILE_DELETE_CHILD 0x00000040 -#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */ - /* file can be read */ -#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */ - /* file can be written */ -#define DELETE 0x00010000 /* The file can be deleted */ -#define READ_CONTROL 0x00020000 /* The access control list and */ - /* ownership associated with the */ - /* file can be read */ -#define WRITE_DAC 0x00040000 /* The access control list and */ - /* ownership associated with the */ - /* file can be written. */ -#define WRITE_OWNER 0x00080000 /* Ownership information associated */ - /* with the file can be written */ -#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */ - /* synchronize with the completion */ - /* of an input/output request */ +#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */ + /* file can be read */ +#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */ + /* file can be written */ +#define DELETE 0x00010000 /* The file can be deleted */ +#define READ_CONTROL 0x00020000 /* The access control list and */ + /* ownership associated with the */ + /* file can be read */ +#define WRITE_DAC 0x00040000 /* The access control list and */ + /* ownership associated with the */ + /* file can be written. */ +#define WRITE_OWNER 0x00080000 /* Ownership information associated */ + /* with the file can be written */ +#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */ + /* synchronize with the completion */ + /* of an input/output request */ #define GENERIC_ALL 0x10000000 #define GENERIC_EXECUTE 0x20000000 #define GENERIC_WRITE 0x40000000 @@ -197,7 +199,7 @@ /* In summary - Relevant file */ /* access flags from CIFS are */ /* file_read_data, file_write_data */ - /* file_execute, file_read_attributes */ + /* file_execute, file_read_attributes*/ /* write_dac, and delete. */ /* @@ -242,7 +244,8 @@ #define ATTR_SPARSE 0x0200 #define ATTR_REPARSE 0x0400 #define ATTR_COMPRESSED 0x0800 -#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - offline storage */ +#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - + on offline storage */ #define ATTR_NOT_CONTENT_INDEXED 0x2000 #define ATTR_ENCRYPTED 0x4000 #define ATTR_POSIX_SEMANTICS 0x01000000 @@ -309,10 +312,10 @@ #define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */ #define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */ -#pragma pack(1) - struct smb_hdr { - __u32 smb_buf_length; /* big endian on wire *//* BB length is only two or three bytes - with one or two byte type preceding it but that is always zero - we could mask the type byte off just in case BB */ + __u32 smb_buf_length; /* big endian on wire *//* BB length is only two + or three bytes - with one or two byte type preceding it that are + zero - we could mask the type byte off just in case BB */ __u8 Protocol[4]; __u8 Command; union { @@ -320,9 +323,9 @@ struct smb_hdr { __u8 ErrorClass; __u8 Reserved; __le16 Error; - } DosError; + } __attribute__((packed)) DosError; __le32 CifsError; - } Status; + } __attribute__((packed)) Status; __u8 Flags; __le16 Flags2; /* note: le */ __le16 PidHigh; @@ -330,16 +333,16 @@ struct smb_hdr { struct { __le32 SequenceNumber; /* le */ __u32 Reserved; /* zero */ - } Sequence; + } __attribute__((packed)) Sequence; __u8 SecuritySignature[8]; /* le */ - } Signature; + } __attribute__((packed)) Signature; __u8 pad[2]; __u16 Tid; __le16 Pid; __u16 Uid; __u16 Mid; __u8 WordCount; -}; +} __attribute__((packed)); /* given a pointer to an smb_hdr retrieve the value of byte count */ #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) #define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) @@ -391,7 +394,7 @@ typedef struct negotiate_req { struct smb_hdr hdr; /* wct = 0 */ __le16 ByteCount; unsigned char DialectsArray[1]; -} NEGOTIATE_REQ; +} __attribute__((packed)) NEGOTIATE_REQ; typedef struct negotiate_rsp { struct smb_hdr hdr; /* wct = 17 */ @@ -409,16 +412,16 @@ typedef struct negotiate_rsp { __u8 EncryptionKeyLength; __u16 ByteCount; union { - unsigned char EncryptionKey[1]; /* if cap extended security is off */ + unsigned char EncryptionKey[1]; /* cap extended security off */ /* followed by Domain name - if extended security is off */ /* followed by 16 bytes of server GUID */ - /* followed by security blob if cap_extended_security negotiated */ + /* then security blob if cap_extended_security negotiated */ struct { unsigned char GUID[16]; unsigned char SecurityBlob[1]; - } extended_response; - } u; -} NEGOTIATE_RSP; + } __attribute__((packed)) extended_response; + } __attribute__((packed)) u; +} __attribute__((packed)) NEGOTIATE_RSP; /* SecurityMode bits */ #define SECMODE_USER 0x01 /* off indicates share level security */ @@ -464,7 +467,8 @@ typedef union smb_com_session_setup_andx { unsigned char SecurityBlob[1]; /* followed by */ /* STRING NativeOS */ /* STRING NativeLanMan */ - } req; /* NTLM request format (with extended security */ + } __attribute__((packed)) req; /* NTLM request format (with + extended security */ struct { /* request format */ struct smb_hdr hdr; /* wct = 13 */ @@ -475,18 +479,19 @@ typedef union smb_com_session_setup_andx { __le16 MaxMpxCount; __le16 VcNumber; __u32 SessionKey; - __le16 CaseInsensitivePasswordLength; /* ASCII password length */ - __le16 CaseSensitivePasswordLength; /* Unicode password length */ + __le16 CaseInsensitivePasswordLength; /* ASCII password len */ + __le16 CaseSensitivePasswordLength; /* Unicode password length*/ __u32 Reserved; /* see below */ __le32 Capabilities; __le16 ByteCount; - unsigned char CaseInsensitivePassword[1]; /* followed by: */ + unsigned char CaseInsensitivePassword[1]; /* followed by: */ /* unsigned char * CaseSensitivePassword; */ /* STRING AccountName */ /* STRING PrimaryDomain */ /* STRING NativeOS */ /* STRING NativeLanMan */ - } req_no_secext; /* NTLM request format (without extended security */ + } __attribute__((packed)) req_no_secext; /* NTLM request format (without + extended security */ struct { /* default (NTLM) response format */ struct smb_hdr hdr; /* wct = 4 */ @@ -500,7 +505,7 @@ typedef union smb_com_session_setup_andx { /* unsigned char * NativeOS; */ /* unsigned char * NativeLanMan; */ /* unsigned char * PrimaryDomain; */ - } resp; /* NTLM response format (with or without extended security */ + } __attribute__((packed)) resp; /* NTLM response format (with or without extended security */ struct { /* request format */ struct smb_hdr hdr; /* wct = 10 */ @@ -519,7 +524,7 @@ typedef union smb_com_session_setup_andx { /* STRING PrimaryDomain */ /* STRING NativeOS */ /* STRING NativeLanMan */ - } old_req; /* pre-NTLM (LANMAN2.1) request format */ + } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */ struct { /* default (NTLM) response format */ struct smb_hdr hdr; /* wct = 3 */ @@ -531,8 +536,8 @@ typedef union smb_com_session_setup_andx { unsigned char NativeOS[1]; /* followed by */ /* unsigned char * NativeLanMan; */ /* unsigned char * PrimaryDomain; */ - } old_resp; /* pre-NTLM (LANMAN2.1) response format */ -} SESSION_SETUP_ANDX; + } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */ +} __attribute__((packed)) SESSION_SETUP_ANDX; #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" @@ -542,7 +547,8 @@ typedef union smb_com_session_setup_andx { #define CAP_NT_SMBS 0x00000010 #define CAP_STATUS32 0x00000040 #define CAP_LEVEL_II_OPLOCKS 0x00000080 -#define CAP_NT_FIND 0x00000200 /* reserved should be zero (presumably because NT_SMBs implies the same thing) */ +#define CAP_NT_FIND 0x00000200 /* reserved should be zero + (because NT_SMBs implies the same thing?) */ #define CAP_BULK_TRANSFER 0x20000000 #define CAP_EXTENDED_SECURITY 0x80000000 @@ -560,7 +566,7 @@ typedef struct smb_com_tconx_req { unsigned char Password[1]; /* followed by */ /* STRING Path *//* \\server\share name */ /* STRING Service */ -} TCONX_REQ; +} __attribute__((packed)) TCONX_REQ; typedef struct smb_com_tconx_rsp { struct smb_hdr hdr; /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */ @@ -571,13 +577,14 @@ typedef struct smb_com_tconx_rsp { __u16 ByteCount; unsigned char Service[1]; /* always ASCII, not Unicode */ /* STRING NativeFileSystem */ -} TCONX_RSP; +} __attribute__((packed)) TCONX_RSP; /* tree connect Flags */ #define DISCONNECT_TID 0x0001 #define TCON_EXTENDED_SECINFO 0x0008 /* OptionalSupport bits */ -#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* must have bits (exclusive searches suppt. */ +#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits + (exclusive searches supported) */ #define SMB_SHARE_IS_IN_DFS 0x0002 typedef struct smb_com_logoff_andx_req { @@ -586,7 +593,7 @@ typedef struct smb_com_logoff_andx_req { __u8 AndXReserved; __u16 AndXOffset; __u16 ByteCount; -} LOGOFF_ANDX_REQ; +} __attribute__((packed)) LOGOFF_ANDX_REQ; typedef struct smb_com_logoff_andx_rsp { struct smb_hdr hdr; /* wct = 2 */ @@ -594,36 +601,36 @@ typedef struct smb_com_logoff_andx_rsp { __u8 AndXReserved; __u16 AndXOffset; __u16 ByteCount; -} LOGOFF_ANDX_RSP; +} __attribute__((packed)) LOGOFF_ANDX_RSP; typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ struct { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bcc = 0 */ - } req; + } __attribute__((packed)) req; struct { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bcc = 0 */ - } resp; -} TREE_DISCONNECT; + } __attribute__((packed)) resp; +} __attribute__((packed)) TREE_DISCONNECT; typedef struct smb_com_close_req { struct smb_hdr hdr; /* wct = 3 */ __u16 FileID; __u32 LastWriteTime; /* should be zero */ __u16 ByteCount; /* 0 */ -} CLOSE_REQ; +} __attribute__((packed)) CLOSE_REQ; typedef struct smb_com_close_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} CLOSE_RSP; +} __attribute__((packed)) CLOSE_RSP; typedef struct smb_com_findclose_req { struct smb_hdr hdr; /* wct = 1 */ __u16 FileID; __u16 ByteCount; /* 0 */ -} FINDCLOSE_REQ; +} __attribute__((packed)) FINDCLOSE_REQ; /* OpenFlags */ #define REQ_MORE_INFO 0x00000001 /* legacy (OPEN_AND_X) only */ @@ -650,7 +657,7 @@ typedef struct smb_com_open_req { /* also handles create */ __u8 SecurityFlags; __le16 ByteCount; char fileName[1]; -} OPEN_REQ; +} __attribute__((packed)) OPEN_REQ; /* open response: oplock levels */ #define OPLOCK_NONE 0 @@ -680,7 +687,7 @@ typedef struct smb_com_open_rsp { __le16 DeviceState; __u8 DirectoryFlag; __u16 ByteCount; /* bct = 0 */ -} OPEN_RSP; +} __attribute__((packed)) OPEN_RSP; /* format of legacy open request */ typedef struct smb_com_openx_req { @@ -699,7 +706,7 @@ typedef struct smb_com_openx_req { __le32 Reserved; __le16 ByteCount; /* file name follows */ char fileName[1]; -} OPENX_REQ; +} __attribute__((packed)) OPENX_REQ; typedef struct smb_com_openx_rsp { struct smb_hdr hdr; /* wct = 15 */ @@ -717,7 +724,7 @@ typedef struct smb_com_openx_rsp { __u32 FileId; __u16 Reserved; __u16 ByteCount; -} OPENX_RSP; +} __attribute__((packed)) OPENX_RSP; /* Legacy write request for older servers */ typedef struct smb_com_writex_req { @@ -736,7 +743,7 @@ typedef struct smb_com_writex_req { __le16 ByteCount; __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ char Data[0]; -} WRITEX_REQ; +} __attribute__((packed)) WRITEX_REQ; typedef struct smb_com_write_req { struct smb_hdr hdr; /* wct = 14 */ @@ -755,7 +762,7 @@ typedef struct smb_com_write_req { __le16 ByteCount; __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ char Data[0]; -} WRITE_REQ; +} __attribute__((packed)) WRITE_REQ; typedef struct smb_com_write_rsp { struct smb_hdr hdr; /* wct = 6 */ @@ -767,7 +774,7 @@ typedef struct smb_com_write_rsp { __le16 CountHigh; __u16 Reserved; __u16 ByteCount; -} WRITE_RSP; +} __attribute__((packed)) WRITE_RSP; /* legacy read request for older servers */ typedef struct smb_com_readx_req { @@ -782,7 +789,7 @@ typedef struct smb_com_readx_req { __le32 Reserved; __le16 Remaining; __le16 ByteCount; -} READX_REQ; +} __attribute__((packed)) READX_REQ; typedef struct smb_com_read_req { struct smb_hdr hdr; /* wct = 12 */ @@ -797,7 +804,7 @@ typedef struct smb_com_read_req { __le16 Remaining; __le32 OffsetHigh; __le16 ByteCount; -} READ_REQ; +} __attribute__((packed)) READ_REQ; typedef struct smb_com_read_rsp { struct smb_hdr hdr; /* wct = 12 */ @@ -814,7 +821,7 @@ typedef struct smb_com_read_rsp { __u16 ByteCount; __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ char Data[1]; -} READ_RSP; +} __attribute__((packed)) READ_RSP; typedef struct locking_andx_range { __le16 Pid; @@ -823,7 +830,7 @@ typedef struct locking_andx_range { __le32 OffsetLow; __le32 LengthHigh; __le32 LengthLow; -} LOCKING_ANDX_RANGE; +} __attribute__((packed)) LOCKING_ANDX_RANGE; #define LOCKING_ANDX_SHARED_LOCK 0x01 #define LOCKING_ANDX_OPLOCK_RELEASE 0x02 @@ -844,7 +851,7 @@ typedef struct smb_com_lock_req { __le16 NumberOfLocks; __le16 ByteCount; LOCKING_ANDX_RANGE Locks[1]; -} LOCK_REQ; +} __attribute__((packed)) LOCK_REQ; typedef struct cifs_posix_lock { @@ -854,7 +861,7 @@ typedef struct cifs_posix_lock { __le64 start; __le64 length; /* BB what about additional owner info to identify network client */ -} CIFS_POSIX_LOCK; +} __attribute__((packed)) CIFS_POSIX_LOCK; typedef struct smb_com_lock_rsp { struct smb_hdr hdr; /* wct = 2 */ @@ -862,7 +869,7 @@ typedef struct smb_com_lock_rsp { __u8 AndXReserved; __le16 AndXOffset; __u16 ByteCount; -} LOCK_RSP; +} __attribute__((packed)) LOCK_RSP; typedef struct smb_com_rename_req { struct smb_hdr hdr; /* wct = 1 */ @@ -872,7 +879,7 @@ typedef struct smb_com_rename_req { unsigned char OldFileName[1]; /* followed by __u8 BufferFormat2 */ /* followed by NewFileName */ -} RENAME_REQ; +} __attribute__((packed)) RENAME_REQ; /* copy request flags */ #define COPY_MUST_BE_FILE 0x0001 @@ -892,7 +899,7 @@ typedef struct smb_com_copy_req { unsigned char OldFileName[1]; /* followed by __u8 BufferFormat2 */ /* followed by NewFileName string */ -} COPY_REQ; +} __attribute__((packed)) COPY_REQ; typedef struct smb_com_copy_rsp { struct smb_hdr hdr; /* wct = 1 */ @@ -900,7 +907,7 @@ typedef struct smb_com_copy_rsp { __u16 ByteCount; /* may be zero */ __u8 BufferFormat; /* 0x04 - only present if errored file follows */ unsigned char ErrorFileName[1]; /* only present if error in copy */ -} COPY_RSP; +} __attribute__((packed)) COPY_RSP; #define CREATE_HARD_LINK 0x103 #define MOVEFILE_COPY_ALLOWED 0x0002 @@ -916,12 +923,12 @@ typedef struct smb_com_nt_rename_req { /* A5 - also used for create hardlink */ unsigned char OldFileName[1]; /* followed by __u8 BufferFormat2 */ /* followed by NewFileName */ -} NT_RENAME_REQ; +} __attribute__((packed)) NT_RENAME_REQ; typedef struct smb_com_rename_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} RENAME_RSP; +} __attribute__((packed)) RENAME_RSP; typedef struct smb_com_delete_file_req { struct smb_hdr hdr; /* wct = 1 */ @@ -929,43 +936,43 @@ typedef struct smb_com_delete_file_req { __le16 ByteCount; __u8 BufferFormat; /* 4 = ASCII */ unsigned char fileName[1]; -} DELETE_FILE_REQ; +} __attribute__((packed)) DELETE_FILE_REQ; typedef struct smb_com_delete_file_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} DELETE_FILE_RSP; +} __attribute__((packed)) DELETE_FILE_RSP; typedef struct smb_com_delete_directory_req { struct smb_hdr hdr; /* wct = 0 */ __le16 ByteCount; __u8 BufferFormat; /* 4 = ASCII */ unsigned char DirName[1]; -} DELETE_DIRECTORY_REQ; +} __attribute__((packed)) DELETE_DIRECTORY_REQ; typedef struct smb_com_delete_directory_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} DELETE_DIRECTORY_RSP; +} __attribute__((packed)) DELETE_DIRECTORY_RSP; typedef struct smb_com_create_directory_req { struct smb_hdr hdr; /* wct = 0 */ __le16 ByteCount; __u8 BufferFormat; /* 4 = ASCII */ unsigned char DirName[1]; -} CREATE_DIRECTORY_REQ; +} __attribute__((packed)) CREATE_DIRECTORY_REQ; typedef struct smb_com_create_directory_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} CREATE_DIRECTORY_RSP; +} __attribute__((packed)) CREATE_DIRECTORY_RSP; typedef struct smb_com_query_information_req { struct smb_hdr hdr; /* wct = 0 */ __le16 ByteCount; /* 1 + namelen + 1 */ __u8 BufferFormat; /* 4 = ASCII */ unsigned char FileName[1]; -} QUERY_INFORMATION_REQ; +} __attribute__((packed)) QUERY_INFORMATION_REQ; typedef struct smb_com_query_information_rsp { struct smb_hdr hdr; /* wct = 10 */ @@ -974,7 +981,7 @@ typedef struct smb_com_query_information_rsp { __le32 size; __u16 reserved[5]; __le16 ByteCount; /* bcc = 0 */ -} QUERY_INFORMATION_RSP; +} __attribute__((packed)) QUERY_INFORMATION_RSP; typedef struct smb_com_setattr_req { struct smb_hdr hdr; /* wct = 8 */ @@ -985,12 +992,12 @@ typedef struct smb_com_setattr_req { __u16 ByteCount; __u8 BufferFormat; /* 4 = ASCII */ unsigned char fileName[1]; -} SETATTR_REQ; +} __attribute__((packed)) SETATTR_REQ; typedef struct smb_com_setattr_rsp { struct smb_hdr hdr; /* wct = 0 */ __u16 ByteCount; /* bct = 0 */ -} SETATTR_RSP; +} __attribute__((packed)) SETATTR_RSP; /* empty wct response to setattr */ @@ -1020,7 +1027,7 @@ typedef struct smb_com_transaction_ioctl_req { __le16 ByteCount; __u8 Pad[3]; __u8 Data[1]; -} TRANSACT_IOCTL_REQ; +} __attribute__((packed)) TRANSACT_IOCTL_REQ; typedef struct smb_com_transaction_ioctl_rsp { struct smb_hdr hdr; /* wct = 19 */ @@ -1037,7 +1044,7 @@ typedef struct smb_com_transaction_ioctl_rsp { __le16 ReturnedDataLen; __u16 ByteCount; __u8 Pad[3]; -} TRANSACT_IOCTL_RSP; +} __attribute__((packed)) TRANSACT_IOCTL_RSP; typedef struct smb_com_transaction_change_notify_req { struct smb_hdr hdr; /* wct = 23 */ @@ -1061,7 +1068,7 @@ typedef struct smb_com_transaction_change_notify_req { __le16 ByteCount; /* __u8 Pad[3];*/ /* __u8 Data[1];*/ -} TRANSACT_CHANGE_NOTIFY_REQ; +} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; typedef struct smb_com_transaction_change_notify_rsp { struct smb_hdr hdr; /* wct = 18 */ @@ -1077,7 +1084,7 @@ typedef struct smb_com_transaction_change_notify_rsp { __u8 SetupCount; /* 0 */ __u16 ByteCount; /* __u8 Pad[3]; */ -} TRANSACT_CHANGE_NOTIFY_RSP; +} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_RSP; /* Completion Filter flags for Notify */ #define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 #define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 @@ -1108,7 +1115,7 @@ struct file_notify_information { __le32 Action; __le32 FileNameLength; __u8 FileName[0]; -}; +} __attribute__((packed)); struct reparse_data { __u32 ReparseTag; @@ -1119,7 +1126,7 @@ struct reparse_data { __u16 TargetNameOffset; __u16 TargetNameLen; char LinkNamesBuf[1]; -}; +} __attribute__((packed)); struct cifs_quota_data { __u32 rsrvd1; /* 0 */ @@ -1129,7 +1136,7 @@ struct cifs_quota_data { __u64 soft_limit; __u64 hard_limit; char sid[1]; /* variable size? */ -}; +} __attribute__((packed)); /* quota sub commands */ #define QUOTA_LIST_CONTINUE 0 @@ -1155,12 +1162,12 @@ struct trans2_req { __u8 Reserved3; __le16 SubCommand; /* 1st setup word - SetupCount words follow */ __le16 ByteCount; -}; +} __attribute__((packed)); struct smb_t2_req { struct smb_hdr hdr; struct trans2_req t2_req; -}; +} __attribute__((packed)); struct trans2_resp { /* struct smb_hdr hdr precedes. Note wct = 10 + setup count */ @@ -1179,12 +1186,12 @@ struct trans2_resp { __u16 ByteCount; __u16 Reserved2;*/ /* data area follows */ -}; +} __attribute__((packed)); struct smb_t2_rsp { struct smb_hdr hdr; struct trans2_resp t2_rsp; -}; +} __attribute__((packed)); /* PathInfo/FileInfo infolevels */ #define SMB_INFO_STANDARD 1 @@ -1271,14 +1278,14 @@ typedef struct smb_com_transaction2_qpi_req { __le16 InformationLevel; __u32 Reserved4; char FileName[1]; -} TRANSACTION2_QPI_REQ; +} __attribute__((packed)) TRANSACTION2_QPI_REQ; typedef struct smb_com_transaction2_qpi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ struct trans2_resp t2; __u16 ByteCount; __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ -} TRANSACTION2_QPI_RSP; +} __attribute__((packed)) TRANSACTION2_QPI_RSP; typedef struct smb_com_transaction2_spi_req { struct smb_hdr hdr; /* wct = 15 */ @@ -1304,21 +1311,21 @@ typedef struct smb_com_transaction2_spi_req { __le16 InformationLevel; __u32 Reserved4; char FileName[1]; -} TRANSACTION2_SPI_REQ; +} __attribute__((packed)) TRANSACTION2_SPI_REQ; typedef struct smb_com_transaction2_spi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ struct trans2_resp t2; __u16 ByteCount; __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ -} TRANSACTION2_SPI_RSP; +} __attribute__((packed)) TRANSACTION2_SPI_RSP; struct set_file_rename { __le32 overwrite; /* 1 = overwrite dest */ __u32 root_fid; /* zero */ __le32 target_name_len; char target_name[0]; /* Must be unicode */ -}; +} __attribute__((packed)); struct smb_com_transaction2_sfi_req { struct smb_hdr hdr; /* wct = 15 */ @@ -1344,7 +1351,7 @@ struct smb_com_transaction2_sfi_req { __u16 Fid; __le16 InformationLevel; __u16 Reserved4; -}; +} __attribute__((packed)); struct smb_com_transaction2_sfi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ @@ -1352,7 +1359,7 @@ struct smb_com_transaction2_sfi_rsp { __u16 ByteCount; __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ -}; +} __attribute__((packed)); struct smb_t2_qfi_req { struct smb_hdr hdr; @@ -1360,7 +1367,7 @@ struct smb_t2_qfi_req { __u8 Pad; __u16 Fid; __le16 InformationLevel; -}; +} __attribute__((packed)); struct smb_t2_qfi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ @@ -1368,7 +1375,7 @@ struct smb_t2_qfi_rsp { __u16 ByteCount; __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ -}; +} __attribute__((packed)); /* * Flags on T2 FINDFIRST and FINDNEXT @@ -1410,13 +1417,13 @@ typedef struct smb_com_transaction2_ffirst_req { __le16 InformationLevel; __le32 SearchStorageType; char FileName[1]; -} TRANSACTION2_FFIRST_REQ; +} __attribute__((packed)) TRANSACTION2_FFIRST_REQ; typedef struct smb_com_transaction2_ffirst_rsp { struct smb_hdr hdr; /* wct = 10 */ struct trans2_resp t2; __u16 ByteCount; -} TRANSACTION2_FFIRST_RSP; +} __attribute__((packed)) TRANSACTION2_FFIRST_RSP; typedef struct smb_com_transaction2_ffirst_rsp_parms { __u16 SearchHandle; @@ -1424,7 +1431,7 @@ typedef struct smb_com_transaction2_ffirst_rsp_parms { __le16 EndofSearch; __le16 EAErrorOffset; __le16 LastNameOffset; -} T2_FFIRST_RSP_PARMS; +} __attribute__((packed)) T2_FFIRST_RSP_PARMS; typedef struct smb_com_transaction2_fnext_req { struct smb_hdr hdr; /* wct = 15 */ @@ -1452,20 +1459,20 @@ typedef struct smb_com_transaction2_fnext_req { __u32 ResumeKey; __le16 SearchFlags; char ResumeFileName[1]; -} TRANSACTION2_FNEXT_REQ; +} __attribute__((packed)) TRANSACTION2_FNEXT_REQ; typedef struct smb_com_transaction2_fnext_rsp { struct smb_hdr hdr; /* wct = 10 */ struct trans2_resp t2; __u16 ByteCount; -} TRANSACTION2_FNEXT_RSP; +} __attribute__((packed)) TRANSACTION2_FNEXT_RSP; typedef struct smb_com_transaction2_fnext_rsp_parms { __le16 SearchCount; __le16 EndofSearch; __le16 EAErrorOffset; __le16 LastNameOffset; -} T2_FNEXT_RSP_PARMS; +} __attribute__((packed)) T2_FNEXT_RSP_PARMS; /* QFSInfo Levels */ #define SMB_INFO_ALLOCATION 1 @@ -1502,14 +1509,14 @@ typedef struct smb_com_transaction2_qfsi_req { __le16 ByteCount; __u8 Pad; __le16 InformationLevel; -} TRANSACTION2_QFSI_REQ; +} __attribute__((packed)) TRANSACTION2_QFSI_REQ; typedef struct smb_com_transaction_qfsi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ struct trans2_resp t2; __u16 ByteCount; __u8 Pad; /* may be three bytes *//* followed by data area */ -} TRANSACTION2_QFSI_RSP; +} __attribute__((packed)) TRANSACTION2_QFSI_RSP; /* SETFSInfo Levels */ @@ -1539,13 +1546,13 @@ typedef struct smb_com_transaction2_setfsi_req { __le16 ClientUnixMajor; /* Data start. */ __le16 ClientUnixMinor; __le64 ClientUnixCap; /* Data end */ -} TRANSACTION2_SETFSI_REQ; +} __attribute__((packed)) TRANSACTION2_SETFSI_REQ; typedef struct smb_com_transaction2_setfsi_rsp { struct smb_hdr hdr; /* wct = 10 */ struct trans2_resp t2; __u16 ByteCount; -} TRANSACTION2_SETFSI_RSP; +} __attribute__((packed)) TRANSACTION2_SETFSI_RSP; typedef struct smb_com_transaction2_get_dfs_refer_req { @@ -1570,7 +1577,7 @@ typedef struct smb_com_transaction2_get_dfs_refer_req { __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */ __le16 MaxReferralLevel; char RequestFileName[1]; -} TRANSACTION2_GET_DFS_REFER_REQ; +} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ; typedef struct dfs_referral_level_3 { __le16 VersionNumber; @@ -1582,7 +1589,7 @@ typedef struct dfs_referral_level_3 { __le16 DfsPathOffset; __le16 DfsAlternatePathOffset; __le16 NetworkAddressOffset; -} REFERRAL3; +} __attribute__((packed)) REFERRAL3; typedef struct smb_com_transaction_get_dfs_refer_rsp { struct smb_hdr hdr; /* wct = 10 */ @@ -1595,7 +1602,7 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp { __u16 Pad2; REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */ /* followed by the strings pointed to by the referral structures */ -} TRANSACTION2_GET_DFS_REFER_RSP; +} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_RSP; /* DFS Flags */ #define DFSREF_REFERRAL_SERVER 0x0001 @@ -1649,7 +1656,7 @@ struct serverInfo { unsigned char versionMinor; unsigned long type; unsigned int commentOffset; -}; +} __attribute__((packed)); /* * The following structure is the format of the data returned on a NetShareEnum @@ -1661,27 +1668,27 @@ struct shareInfo { char pad; unsigned short type; unsigned int commentOffset; -}; +} __attribute__((packed)); struct aliasInfo { char aliasName[9]; char pad; unsigned int commentOffset; unsigned char type[2]; -}; +} __attribute__((packed)); struct aliasInfo92 { int aliasNameOffset; int serverNameOffset; int shareNameOffset; -}; +} __attribute__((packed)); typedef struct { __le64 TotalAllocationUnits; __le64 FreeAllocationUnits; __le32 SectorsPerAllocationUnit; __le32 BytesPerSector; -} FILE_SYSTEM_INFO; /* size info, level 0x103 */ +} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */ typedef struct { __le32 fsid; @@ -1689,13 +1696,13 @@ typedef struct { __le32 TotalAllocationUnits; __le32 FreeAllocationUnits; __le16 BytesPerSector; -} FILE_SYSTEM_ALLOC_INFO; +} __attribute__((packed)) FILE_SYSTEM_ALLOC_INFO; typedef struct { __le16 MajorVersionNumber; __le16 MinorVersionNumber; __le64 Capability; -} FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ +} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ /* Version numbers for CIFS UNIX major and minor. */ #define CIFS_UNIX_MAJOR_VERSION 1 @@ -1730,7 +1737,7 @@ typedef struct { __le64 FileSysIdentifier; /* fsid */ /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */ /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */ -} FILE_SYSTEM_POSIX_INFO; +} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO; /* DeviceType Flags */ #define FILE_DEVICE_CD_ROM 0x00000002 @@ -1755,14 +1762,14 @@ typedef struct { typedef struct { __le32 DeviceType; __le32 DeviceCharacteristics; -} FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */ +} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */ typedef struct { __le32 Attributes; __le32 MaxPathNameComponentLength; __le32 FileSystemNameLen; char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */ -} FILE_SYSTEM_ATTRIBUTE_INFO; +} __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO; /******************************************************************************/ /* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */ @@ -1789,7 +1796,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */ __le32 AlignmentRequirement; __le32 FileNameLength; char FileName[1]; -} FILE_ALL_INFO; /* level 0x107 QPathInfo */ +} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */ /* defines for enumerating possible values of the Unix type field below */ #define UNIX_FILE 0 @@ -1813,11 +1820,11 @@ typedef struct { __u64 UniqueId; __le64 Permissions; __le64 Nlinks; -} FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ +} __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ typedef struct { char LinkDest[1]; -} FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */ +} __attribute__((packed)) FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */ /* The following three structures are needed only for setting time to NT4 and some older servers via @@ -1826,13 +1833,13 @@ typedef struct { __u16 Day:5; __u16 Month:4; __u16 Year:7; -} SMB_DATE; +} __attribute__((packed)) SMB_DATE; typedef struct { __u16 TwoSeconds:5; __u16 Minutes:6; __u16 Hours:5; -} SMB_TIME; +} __attribute__((packed)) SMB_TIME; typedef struct { __le16 CreationDate; /* SMB Date see above */ @@ -1845,7 +1852,7 @@ typedef struct { __le32 AllocationSize; __le16 Attributes; /* verify not u32 */ __le32 EASize; -} FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */ +} __attribute__((packed)) FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */ typedef struct { __le64 CreationTime; @@ -1854,19 +1861,19 @@ typedef struct { __le64 ChangeTime; __le32 Attributes; __u32 Pad; -} FILE_BASIC_INFO; /* size info, level 0x101 */ +} __attribute__((packed)) FILE_BASIC_INFO; /* size info, level 0x101 */ struct file_allocation_info { __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */ -}; /* size used on disk, level 0x103 for set, 0x105 for query */ +} __attribute__((packed)); /* size used on disk, level 0x103 for set, 0x105 for query */ struct file_end_of_file_info { __le64 FileSize; /* offset to end of file */ -}; /* size info, level 0x104 for set, 0x106 for query */ +} __attribute__((packed)); /* size info, level 0x104 for set, 0x106 for query */ struct file_alt_name_info { __u8 alt_name[1]; -}; /* level 0x0108 */ +} __attribute__((packed)); /* level 0x0108 */ struct file_stream_info { __le32 number_of_streams; /* BB check sizes and verify location */ @@ -1883,7 +1890,7 @@ struct file_compression_info { __u8 ch_shift; __u8 cl_shift; __u8 pad[3]; -}; /* level 0x10b */ +} __attribute__((packed)); /* level 0x10b */ /* POSIX ACL set/query path info structures */ #define CIFS_ACL_VERSION 1 @@ -1891,7 +1898,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */ __u8 cifs_e_tag; __u8 cifs_e_perm; __le64 cifs_uid; /* or gid */ -}; +} __attribute__((packed)); struct cifs_posix_acl { /* access conrol list (ACL) */ __le16 version; @@ -1900,7 +1907,7 @@ struct cifs_posix_acl { /* access conrol list (ACL) */ struct cifs_posix_ace ace_array[0]; /* followed by struct cifs_posix_ace default_ace_arraay[] */ -}; /* level 0x204 */ +} __attribute__((packed)); /* level 0x204 */ /* types of access control entries already defined in posix_acl.h */ /* #define CIFS_POSIX_ACL_USER_OBJ 0x01 @@ -1919,15 +1926,15 @@ struct cifs_posix_acl { /* access conrol list (ACL) */ struct file_internal_info { __u64 UniqueId; /* inode number */ -}; /* level 0x3ee */ +} __attribute__((packed)); /* level 0x3ee */ struct file_mode_info { __le32 Mode; -}; /* level 0x3f8 */ +} __attribute__((packed)); /* level 0x3f8 */ struct file_attrib_tag { __le32 Attribute; __le32 ReparseTag; -}; /* level 0x40b */ +} __attribute__((packed)); /* level 0x40b */ /********************************************************/ @@ -1951,7 +1958,7 @@ typedef struct { __le64 Permissions; __le64 Nlinks; char FileName[1]; -} FILE_UNIX_INFO; /* level 0x202 */ +} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */ typedef struct { __le32 NextEntryOffset; @@ -1965,7 +1972,7 @@ typedef struct { __le32 ExtFileAttributes; __le32 FileNameLength; char FileName[1]; -} FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */ +} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */ typedef struct { __le32 NextEntryOffset; @@ -1980,7 +1987,7 @@ typedef struct { __le32 FileNameLength; __le32 EaSize; /* length of the xattrs */ char FileName[1]; -} FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */ +} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */ typedef struct { __le32 NextEntryOffset; @@ -1997,7 +2004,7 @@ typedef struct { __le32 Reserved; __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ char FileName[1]; -} SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */ +} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */ typedef struct { __le32 NextEntryOffset; @@ -2015,18 +2022,18 @@ typedef struct { __u8 Reserved; __u8 ShortName[12]; char FileName[1]; -} FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ +} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ struct gea { unsigned char name_len; char name[1]; -}; +} __attribute__((packed)); struct gealist { unsigned long list_len; struct gea list[1]; -}; +} __attribute__((packed)); struct fea { unsigned char EA_flags; @@ -2034,21 +2041,21 @@ struct fea { __le16 value_len; char name[1]; /* optionally followed by value */ -}; +} __attribute__((packed)); /* flags for _FEA.fEA */ #define FEA_NEEDEA 0x80 /* need EA bit */ struct fealist { __le32 list_len; struct fea list[1]; -}; +} __attribute__((packed)); /* used to hold an arbitrary blob of data */ struct data_blob { __u8 *data; size_t length; void (*free) (struct data_blob * data_blob); -}; +} __attribute__((packed)); #ifdef CONFIG_CIFS_POSIX @@ -2151,7 +2158,7 @@ struct xsymlink { char cr2; /* \n */ /* if room left, then end with \n then 0x20s by convention but not required */ char path[1024]; -}; +} __attribute__((packed)); typedef struct file_xattr_info { /* BB do we need another field for flags? BB */ @@ -2159,7 +2166,7 @@ typedef struct file_xattr_info { __u32 xattr_value_len; char xattr_name[0]; /* followed by xattr_value[xattr_value_len], no pad */ -} FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ +} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ /* flags for chattr command */ @@ -2185,10 +2192,8 @@ typedef struct file_xattr_info { typedef struct file_chattr_info { __le64 mask; /* list of all possible attribute bits */ __le64 mode; /* list of actual attribute bits on this inode */ -} FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ +} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ #endif -#pragma pack() /* resume default structure packing */ - #endif /* _CIFSPDU_H */ diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h index 6facb41117a3..803389b64a2c 100644 --- a/fs/cifs/ntlmssp.h +++ b/fs/cifs/ntlmssp.h @@ -19,8 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#pragma pack(1) - #define NTLMSSP_SIGNATURE "NTLMSSP" /* Message Types */ #define NtLmNegotiate cpu_to_le32(1) @@ -63,7 +61,7 @@ typedef struct _SECURITY_BUFFER { __le16 Length; __le16 MaximumLength; __le32 Buffer; /* offset to buffer */ -} SECURITY_BUFFER; +} __attribute__((packed)) SECURITY_BUFFER; typedef struct _NEGOTIATE_MESSAGE { __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; @@ -73,7 +71,7 @@ typedef struct _NEGOTIATE_MESSAGE { SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */ char DomainString[0]; /* followed by WorkstationString */ -} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; +} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; typedef struct _CHALLENGE_MESSAGE { __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; @@ -83,7 +81,7 @@ typedef struct _CHALLENGE_MESSAGE { __u8 Challenge[CIFS_CRYPTO_KEY_SIZE]; __u8 Reserved[8]; SECURITY_BUFFER TargetInfoArray; -} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE; +} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE; typedef struct _AUTHENTICATE_MESSAGE { __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; @@ -96,6 +94,4 @@ typedef struct _AUTHENTICATE_MESSAGE { SECURITY_BUFFER SessionKey; __le32 NegotiateFlags; char UserString[0]; -} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE; - -#pragma pack() /* resume default structure packing */ +} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE; diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h index 806c0ed06da9..9222033cad8e 100644 --- a/fs/cifs/rfc1002pdu.h +++ b/fs/cifs/rfc1002pdu.h @@ -21,8 +21,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#pragma pack(1) - /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ /* RFC 1002 session packet types */ @@ -48,17 +46,17 @@ struct rfc1002_session_packet { __u8 calling_len; __u8 calling_name[32]; __u8 scope2; /* null */ - } session_req; + } __attribute__((packed)) session_req; struct { __u32 retarget_ip_addr; __u16 port; - } retarget_resp; + } __attribute__((packed)) retarget_resp; __u8 neg_ses_resp_error_code; /* POSITIVE_SESSION_RESPONSE packet does not include trailer. SESSION_KEEP_ALIVE packet also does not include a trailer. Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */ - } trailer; -}; + } __attribute__((packed)) trailer; +} __attribute__((packed)); /* Negative Session Response error codes */ #define RFC1002_NOT_LISTENING_CALLED 0x80 /* not listening on called name */ @@ -74,6 +72,3 @@ server netbios name). Currently server names are resolved only via DNS (tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/ #define DEFAULT_CIFS_CALLED_NAME "*SMBSERVER " - -#pragma pack() /* resume default structure packing */ - From c1902aae322952f8726469a6657df7b9d5c794fe Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Thu, 27 Oct 2005 15:41:04 -0500 Subject: [PATCH 0506/1940] [IA64] - Avoid slow TLB purges on SGI Altix systems flush_tlb_all() can be a scaling issue on large SGI Altix systems since it uses the global call_lock and always executes on all cpus. When a process enters flush_tlb_range() to purge TLBs for another process, it is possible to avoid flush_tlb_all() and instead allow sn2_global_tlb_purge() to purge TLBs only where necessary. This patch modifies flush_tlb_range() so that this case can be handled by platform TLB purge functions and updates ia64_global_tlb_purge() accordingly. sn2_global_tlb_purge() now calculates the region register value from the mm argument introduced with this patch. Signed-off-by: Dean Roe Signed-off-by: Tony Luck --- arch/ia64/mm/tlb.c | 16 +++++++++------- arch/ia64/sn/kernel/sn2/sn2_smp.c | 31 +++++++++++++++++++------------ include/asm-ia64/machvec.h | 2 +- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 464557e4ed82..99ea8c70f408 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -86,10 +86,15 @@ wrap_mmu_context (struct mm_struct *mm) } void -ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits) +ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) { static DEFINE_SPINLOCK(ptcg_lock); + if (mm != current->active_mm) { + flush_tlb_all(); + return; + } + /* HW requires global serialization of ptc.ga. */ spin_lock(&ptcg_lock); { @@ -135,15 +140,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long unsigned long size = end - start; unsigned long nbits; +#ifndef CONFIG_SMP if (mm != current->active_mm) { - /* this does happen, but perhaps it's not worth optimizing for? */ -#ifdef CONFIG_SMP - flush_tlb_all(); -#else mm->context = 0; -#endif return; } +#endif nbits = ia64_fls(size + 0xfff); while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) @@ -153,7 +155,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long start &= ~((1UL << nbits) - 1); # ifdef CONFIG_SMP - platform_global_tlb_purge(start, end, nbits); + platform_global_tlb_purge(mm, start, end, nbits); # else do { ia64_ptcl(start, (nbits<<2)); diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 0a4ee50c302f..49b530c39a42 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -177,6 +177,7 @@ void sn_tlb_migrate_finish(struct mm_struct *mm) /** * sn2_global_tlb_purge - globally purge translation cache of virtual address range + * @mm: mm_struct containing virtual address range * @start: start of virtual address range * @end: end of virtual address range * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) @@ -188,21 +189,22 @@ void sn_tlb_migrate_finish(struct mm_struct *mm) * - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context. * - cpu_vm_mask is converted into a nodemask of the nodes containing the * cpus in cpu_vm_mask. - * - if only one bit is set in cpu_vm_mask & it is the current cpu, - * then only the local TLB needs to be flushed. This flushing can be done - * using ptc.l. This is the common case & avoids the global spinlock. + * - if only one bit is set in cpu_vm_mask & it is the current cpu & the + * process is purging its own virtual address range, then only the + * local TLB needs to be flushed. This flushing can be done using + * ptc.l. This is the common case & avoids the global spinlock. * - if multiple cpus have loaded the context, then flushing has to be * done with ptc.g/MMRs under protection of the global ptc_lock. */ void -sn2_global_tlb_purge(unsigned long start, unsigned long end, - unsigned long nbits) +sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, + unsigned long end, unsigned long nbits) { int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; + int mymm = (mm == current->active_mm); volatile unsigned long *ptc0, *ptc1; - unsigned long itc, itc2, flags, data0 = 0, data1 = 0; - struct mm_struct *mm = current->active_mm; + unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; short nasids[MAX_NUMNODES], nix; nodemask_t nodes_flushed; @@ -216,9 +218,12 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, i++; } + if (i == 0) + return; + preempt_disable(); - if (likely(i == 1 && lcpu == smp_processor_id())) { + if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) { do { ia64_ptcl(start, nbits << 2); start += (1UL << nbits); @@ -229,7 +234,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, return; } - if (atomic_read(&mm->mm_users) == 1) { + if (atomic_read(&mm->mm_users) == 1 && mymm) { flush_tlb_mm(mm); __get_cpu_var(ptcstats).change_rid++; preempt_enable(); @@ -241,11 +246,13 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, for_each_node_mask(cnode, nodes_flushed) nasids[nix++] = cnodeid_to_nasid(cnode); + rr_value = (mm->context << 3) | REGION_NUMBER(start); + shub1 = is_shub1(); if (shub1) { data0 = (1UL << SH1_PTC_0_A_SHFT) | (nbits << SH1_PTC_0_PS_SHFT) | - ((ia64_get_rr(start) >> 8) << SH1_PTC_0_RID_SHFT) | + (rr_value << SH1_PTC_0_RID_SHFT) | (1UL << SH1_PTC_0_START_SHFT); ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0); ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1); @@ -254,7 +261,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, (nbits << SH2_PTC_PS_SHFT) | (1UL << SH2_PTC_START_SHFT); ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + - ((ia64_get_rr(start) >> 8) << SH2_PTC_RID_SHFT) ); + (rr_value << SH2_PTC_RID_SHFT)); ptc1 = NULL; } @@ -275,7 +282,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end, data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); for (i = 0; i < nix; i++) { nasid = nasids[i]; - if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid)) { + if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) { ia64_ptcga(start, nbits << 2); ia64_srlz_i(); } else { diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 79e89a7db566..522c7f5ba8ce 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -26,7 +26,7 @@ typedef void ia64_mv_cpu_init_t (void); typedef void ia64_mv_irq_init_t (void); typedef void ia64_mv_send_ipi_t (int, int, int, int); typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *); -typedef void ia64_mv_global_tlb_purge_t (unsigned long, unsigned long, unsigned long); +typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long); typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *); typedef unsigned int ia64_mv_local_vector_to_irq (u8); typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *); From 09eee6347166a7baab74783999ef1bf23827647f Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 08:29:36 +1000 Subject: [PATCH 0507/1940] powerpc: Move U3 IOMMU driver to arch/powerpc/sysdev Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/Makefile | 1 + arch/{ppc64/kernel => powerpc/sysdev}/u3_iommu.c | 0 arch/ppc64/kernel/Makefile | 2 -- 3 files changed, 1 insertion(+), 2 deletions(-) rename arch/{ppc64/kernel => powerpc/sysdev}/u3_iommu.c (100%) diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index d071ae875e25..8acd21dee05d 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_40x) += dcr.o +obj-$(CONFIG_U3_DART) += u3_iommu.o diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c similarity index 100% rename from arch/ppc64/kernel/u3_iommu.c rename to arch/powerpc/sysdev/u3_iommu.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index f2f60c9cc55f..863bd7d746fb 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -60,8 +60,6 @@ obj-$(CONFIG_PPC_PMAC) += udbg_scc.o obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ udbg_16550.o -obj-$(CONFIG_U3_DART) += u3_iommu.o - ifdef CONFIG_SMP obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o From 9675c7ebcf1f6308d66b0fcb42ae585e200e80a9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 08:30:25 +1000 Subject: [PATCH 0508/1940] ppc64: Include arch/powerpc/kernel/setup-common.o ... which is needed now that ARCH=ppc64 is using the merged setup_64.c. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 94cf917b7854..68543201df3d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -46,7 +46,8 @@ endif else # stuff used from here for ARCH=ppc or ARCH=ppc64 -obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o +obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \ + setup-common.o endif From 4ac0068f44f192f2de95a7bb36df3e19767a45fb Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Thu, 27 Oct 2005 10:29:08 -0500 Subject: [PATCH 0509/1940] [IA64] ptrace - find memory sharers on children list In arch/ia64/kernel/ptrace.c there is a test for a peek or poke of a register image (in register backing storage). The test can be unnecessarily long (and occurs while holding the tasklist_lock). Especially long on a large system with thousands of active tasks. The ptrace caller (presumably a debugger) specifies the pid of its target and an address to peek or poke. But the debugger could be attached to several tasks. The idea of find_thread_for_addr() is to find whether the target address is in the RBS for any of those tasks. Currently it searches the thread-list of the target pid. If that search does not find a match, and the shared mm-struct's user count indicates that there are other tasks sharing this address space (a rare occurrence), a search is made of all the tasks in the system. Another approach can drastically shorten this procedure. It depends upon the fact that in order to peek or poke from/to any task, the debugger must first attach to that task. And when it does, the attached task is made a child of the debugger (is chained to its children list). Therefore we can search just the debugger's children list. Signed-off-by: Cliff Wickman Signed-off-by: Tony Luck --- arch/ia64/kernel/ptrace.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index bbb8bc7c0552..9a9c1bd01dbc 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -589,6 +589,7 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr) { struct task_struct *g, *p; struct mm_struct *mm; + struct list_head *this, *next; int mm_users; if (!(mm = get_task_mm(child))) @@ -600,28 +601,21 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr) goto out; /* not multi-threaded */ /* - * First, traverse the child's thread-list. Good for scalability with - * NPTL-threads. + * Traverse the current process' children list. Every task that + * one attaches to becomes a child. And it is only attached children + * of the debugger that are of interest (ptrace_check_attach checks + * for this). */ - p = child; - do { - if (thread_matches(p, addr)) { - child = p; - goto out; - } - if (mm_users-- <= 1) - goto out; - } while ((p = next_thread(p)) != child); - - do_each_thread(g, p) { - if (child->mm != mm) + list_for_each_safe(this, next, ¤t->children) { + p = list_entry(this, struct task_struct, sibling); + if (p->mm != mm) continue; - if (thread_matches(p, addr)) { child = p; goto out; } - } while_each_thread(g, p); + } + out: mmput(mm); return child; From e6b4fe92effe88944af2df7257688ccff811996d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 27 Oct 2005 08:54:36 -0500 Subject: [PATCH 0510/1940] [PATCH] powerpc: only build idle_6xx for 6xx For the current time idle_6xx only applies to 6xx ppc32 CPUs Signed-off-by: Kumar K. Gala Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 68543201df3d..8421f1975dad 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -33,11 +33,12 @@ extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ prom.o systbl.o traps.o setup-common.o -obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o +obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o +obj-$(CONFIG_6xx) += idle_6xx.o ifeq ($(CONFIG_PPC_ISERIES),y) $(obj)/head_64.o: $(obj)/lparmap.s From a8e3d48150d70ceab3b8249a4bdbe5c50567a357 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 28 Oct 2005 10:31:49 +1000 Subject: [PATCH 0511/1940] [PATCH] powerpc: Remove dregs of bootinfo.h Since I sent the patch to purge bootinfo.h from ARCH=powerpc and ARCH=ppc64, setup-common.c has come into existence, and another #include of bootinfo.h slipped in. This patch removes it. It also removes include/asm-ppc64/bootinfo.h, which somehow survived the previous patch which was supposed to remove it. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup-common.c | 1 - include/asm-ppc64/bootinfo.h | 70 ------------------------------ 2 files changed, 71 deletions(-) delete mode 100644 include/asm-ppc64/bootinfo.h diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index d4f0a4c3b5bc..aa743a50a20a 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/include/asm-ppc64/bootinfo.h b/include/asm-ppc64/bootinfo.h deleted file mode 100644 index f55e7cb48f46..000000000000 --- a/include/asm-ppc64/bootinfo.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Non-machine dependent bootinfo structure. Basic idea - * borrowed from the m68k. - * - * Copyright (C) 1999 Cort Dougan - * Copyright (c) 2001 PPC64 Team, IBM Corp - * - * 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. - */ - - -#ifndef _PPC64_BOOTINFO_H -#define _PPC64_BOOTINFO_H - -#include - -/* We use a u32 for the type of the fields since they're written by - * the bootloader which is a 32-bit process and read by the kernel - * which is a 64-bit process. This way they can both agree on the - * size of the type. - */ -typedef u32 bi_rec_field; - -struct bi_record { - bi_rec_field tag; /* tag ID */ - bi_rec_field size; /* size of record (in bytes) */ - bi_rec_field data[0]; /* data */ -}; - -#define BI_FIRST 0x1010 /* first record - marker */ -#define BI_LAST 0x1011 /* last record - marker */ -#define BI_CMD_LINE 0x1012 -#define BI_BOOTLOADER_ID 0x1013 -#define BI_INITRD 0x1014 -#define BI_SYSMAP 0x1015 -#define BI_MACHTYPE 0x1016 - -static __inline__ struct bi_record * bi_rec_init(unsigned long addr) -{ - struct bi_record *bi_recs; - bi_recs = (struct bi_record *)_ALIGN(addr, PAGE_SIZE); - bi_recs->size = 0; - return bi_recs; -} - -static __inline__ struct bi_record * bi_rec_alloc(struct bi_record *rec, - unsigned long args) -{ - rec = (struct bi_record *)((unsigned long)rec + rec->size); - rec->size = sizeof(struct bi_record) + args*sizeof(bi_rec_field); - return rec; -} - -static __inline__ struct bi_record * bi_rec_alloc_bytes(struct bi_record *rec, - unsigned long bytes) -{ - rec = (struct bi_record *)((unsigned long)rec + rec->size); - rec->size = sizeof(struct bi_record) + bytes; - return rec; -} - -static __inline__ struct bi_record * bi_rec_next(struct bi_record *rec) -{ - return (struct bi_record *)((unsigned long)rec + rec->size); -} - -#endif /* _PPC64_BOOTINFO_H */ From 2227718ca2f7d5fcc2741c1bbca4d0c2efd340ce Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 11:47:17 +1000 Subject: [PATCH 0512/1940] ppc64: Use the correct prototypes for i8259 functions We still had an old copy of i8259.h lying around; this gets rid of it and corrects the callers of i8259_init and i8259_irq. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/i8259.h | 17 ----------------- arch/ppc64/kernel/xics.c | 7 +++---- 2 files changed, 3 insertions(+), 21 deletions(-) delete mode 100644 arch/ppc64/kernel/i8259.h diff --git a/arch/ppc64/kernel/i8259.h b/arch/ppc64/kernel/i8259.h deleted file mode 100644 index f74764ba0bfa..000000000000 --- a/arch/ppc64/kernel/i8259.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * c 2001 PPC 64 Team, IBM Corp - * - * 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. - */ -#ifndef _PPC_KERNEL_i8259_H -#define _PPC_KERNEL_i8259_H - -extern struct hw_interrupt_type i8259_pic; - -extern void i8259_init(int offset); -extern int i8259_irq(int); - -#endif /* _PPC_KERNEL_i8259_H */ diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index daf93885dcfa..a32207dcf2e3 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -28,8 +28,7 @@ #include #include #include - -#include "i8259.h" +#include static unsigned int xics_startup(unsigned int irq); static void xics_enable_irq(unsigned int irq); @@ -366,7 +365,7 @@ int xics_get_irq(struct pt_regs *regs) /* for sanity, this had better be < NR_IRQS - 16 */ if (vec == xics_irq_8259_cascade_real) { - irq = i8259_irq(cpu); + irq = i8259_irq(regs); if (irq == -1) { /* Spurious cascaded interrupt. Still must ack xics */ xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); @@ -589,7 +588,7 @@ static int __init xics_setup_i8259(void) no_action, 0, "8259 cascade", NULL)) printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 " "cascade\n"); - i8259_init(0); + i8259_init(0, 0); } return 0; } From 640768eef245f1578e75e02c17d277a1496a535b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 28 Oct 2005 12:51:45 +1000 Subject: [PATCH 0513/1940] ppc64: use the merged syscall table This allows us to also use entry_64.S from the merged tree and reverts the setup_64.c part of fda262b8978d0089758ef9444508434c74113a61. Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 9 +- arch/powerpc/kernel/setup_64.c | 18 +- arch/ppc64/Makefile | 1 + arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/entry.S | 845 --------------------------------- arch/ppc64/kernel/misc.S | 563 ---------------------- 6 files changed, 12 insertions(+), 1426 deletions(-) delete mode 100644 arch/ppc64/kernel/entry.S diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 68543201df3d..0118e516b01f 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -13,7 +13,7 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ signal_32.o pmc.o obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ - ptrace32.o + ptrace32.o systbl.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o @@ -28,12 +28,12 @@ extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o -extra-$(CONFIG_PPC64) += entry_64.o extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ - prom.o systbl.o traps.o setup-common.o -obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o + prom.o traps.o setup-common.o +obj-$(CONFIG_PPC32) += entry_32.o idle_6xx.o setup_32.o misc_32.o \ + systbl.o obj-$(CONFIG_PPC64) += misc_64.o obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o @@ -53,3 +53,4 @@ obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \ endif extra-$(CONFIG_PPC_FPU) += fpu.o +extra-$(CONFIG_PPC64) += entry_64.o diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index a8f7ff5ab1a4..950e6f0fea98 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -701,17 +701,6 @@ static void __init emergency_stack_init(void) limit)) + PAGE_SIZE; } -extern unsigned long *sys_call_table; -extern unsigned long sys_ni_syscall; -#ifdef CONFIG_PPC_MERGE -#define SYS_CALL_ENTRY64(i) sys_call_table[(i) * 2] -#define SYS_CALL_ENTRY32(i) sys_call_table[(i) * 2 + 1] -#else -extern unsigned long *sys_call_table32; -#define SYS_CALL_ENTRY64(i) sys_call_table[(i)] -#define SYS_CALL_ENTRY32(i) sys_call_table32[(i)] -#endif - /* * Called from setup_arch to initialize the bitmap of available * syscalls in the systemcfg page @@ -719,14 +708,17 @@ extern unsigned long *sys_call_table32; void __init setup_syscall_map(void) { unsigned int i, count64 = 0, count32 = 0; + extern unsigned long *sys_call_table; + extern unsigned long sys_ni_syscall; + for (i = 0; i < __NR_syscalls; i++) { - if (SYS_CALL_ENTRY64(i) != sys_ni_syscall) { + if (sys_call_table[i*2] != sys_ni_syscall) { count64++; systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f); } - if (SYS_CALL_ENTRY32(i) != sys_ni_syscall) { + if (sys_call_table[i*2+1] != sys_ni_syscall) { count32++; systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f); diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index ba59225fd373..66ee04f13b26 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -81,6 +81,7 @@ CFLAGS += $(call cc-option,-funit-at-a-time) head-y := arch/ppc64/kernel/head.o head-y += arch/powerpc/kernel/fpu.o +head-y += arch/powerpc/kernel/entry_64.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 863bd7d746fb..a20a305b825d 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -7,7 +7,7 @@ ifneq ($(CONFIG_PPC_MERGE),y) EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds -obj-y := entry.o misc.o prom.o +obj-y := misc.o prom.o endif diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S deleted file mode 100644 index 5d2fcbe384c1..000000000000 --- a/arch/ppc64/kernel/entry.S +++ /dev/null @@ -1,845 +0,0 @@ -/* - * arch/ppc64/kernel/entry.S - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP - * Copyright (C) 1996 Cort Dougan - * Adapted for Power Macintosh by Paul Mackerras. - * Low-level exception handlers and MMU support - * rewritten by Paul Mackerras. - * Copyright (C) 1996 Paul Mackerras. - * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). - * - * This file contains the system call entry code, context switch - * code, and exception/interrupt return code for PowerPC. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PPC_ISERIES -#define DO_SOFT_DISABLE -#endif - -/* - * System calls. - */ - .section ".toc","aw" -.SYS_CALL_TABLE: - .tc .sys_call_table[TC],.sys_call_table - -.SYS_CALL_TABLE32: - .tc .sys_call_table32[TC],.sys_call_table32 - -/* This value is used to mark exception frames on the stack. */ -exception_marker: - .tc ID_72656773_68657265[TC],0x7265677368657265 - - .section ".text" - .align 7 - -#undef SHOW_SYSCALLS - - .globl system_call_common -system_call_common: - andi. r10,r12,MSR_PR - mr r10,r1 - addi r1,r1,-INT_FRAME_SIZE - beq- 1f - ld r1,PACAKSAVE(r13) -1: std r10,0(r1) - std r11,_NIP(r1) - std r12,_MSR(r1) - std r0,GPR0(r1) - std r10,GPR1(r1) - std r2,GPR2(r1) - std r3,GPR3(r1) - std r4,GPR4(r1) - std r5,GPR5(r1) - std r6,GPR6(r1) - std r7,GPR7(r1) - std r8,GPR8(r1) - li r11,0 - std r11,GPR9(r1) - std r11,GPR10(r1) - std r11,GPR11(r1) - std r11,GPR12(r1) - std r9,GPR13(r1) - crclr so - mfcr r9 - mflr r10 - li r11,0xc01 - std r9,_CCR(r1) - std r10,_LINK(r1) - std r11,_TRAP(r1) - mfxer r9 - mfctr r10 - std r9,_XER(r1) - std r10,_CTR(r1) - std r3,ORIG_GPR3(r1) - ld r2,PACATOC(r13) - addi r9,r1,STACK_FRAME_OVERHEAD - ld r11,exception_marker@toc(r2) - std r11,-16(r9) /* "regshere" marker */ -#ifdef CONFIG_PPC_ISERIES - /* Hack for handling interrupts when soft-enabling on iSeries */ - cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ - andi. r10,r12,MSR_PR /* from kernel */ - crand 4*cr0+eq,4*cr1+eq,4*cr0+eq - beq hardware_interrupt_entry - lbz r10,PACAPROCENABLED(r13) - std r10,SOFTE(r1) -#endif - mfmsr r11 - ori r11,r11,MSR_EE - mtmsrd r11,1 - -#ifdef SHOW_SYSCALLS - bl .do_show_syscall - REST_GPR(0,r1) - REST_4GPRS(3,r1) - REST_2GPRS(7,r1) - addi r9,r1,STACK_FRAME_OVERHEAD -#endif - clrrdi r11,r1,THREAD_SHIFT - li r12,0 - ld r10,TI_FLAGS(r11) - stb r12,TI_SC_NOERR(r11) - andi. r11,r10,_TIF_SYSCALL_T_OR_A - bne- syscall_dotrace -syscall_dotrace_cont: - cmpldi 0,r0,NR_syscalls - bge- syscall_enosys - -system_call: /* label this so stack traces look sane */ -/* - * Need to vector to 32 Bit or default sys_call_table here, - * based on caller's run-mode / personality. - */ - ld r11,.SYS_CALL_TABLE@toc(2) - andi. r10,r10,_TIF_32BIT - beq 15f - ld r11,.SYS_CALL_TABLE32@toc(2) - clrldi r3,r3,32 - clrldi r4,r4,32 - clrldi r5,r5,32 - clrldi r6,r6,32 - clrldi r7,r7,32 - clrldi r8,r8,32 -15: - slwi r0,r0,3 - ldx r10,r11,r0 /* Fetch system call handler [ptr] */ - mtctr r10 - bctrl /* Call handler */ - -syscall_exit: -#ifdef SHOW_SYSCALLS - std r3,GPR3(r1) - bl .do_show_syscall_exit - ld r3,GPR3(r1) -#endif - std r3,RESULT(r1) - ld r5,_CCR(r1) - li r10,-_LAST_ERRNO - cmpld r3,r10 - clrrdi r12,r1,THREAD_SHIFT - bge- syscall_error -syscall_error_cont: - - /* check for syscall tracing or audit */ - ld r9,TI_FLAGS(r12) - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - bne- syscall_exit_trace -syscall_exit_trace_cont: - - /* disable interrupts so current_thread_info()->flags can't change, - and so that we don't get interrupted after loading SRR0/1. */ - ld r8,_MSR(r1) - andi. r10,r8,MSR_RI - beq- unrecov_restore - mfmsr r10 - rldicl r10,r10,48,1 - rotldi r10,r10,16 - mtmsrd r10,1 - ld r9,TI_FLAGS(r12) - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) - bne- syscall_exit_work - ld r7,_NIP(r1) - stdcx. r0,0,r1 /* to clear the reservation */ - andi. r6,r8,MSR_PR - ld r4,_LINK(r1) - beq- 1f /* only restore r13 if */ - ld r13,GPR13(r1) /* returning to usermode */ -1: ld r2,GPR2(r1) - li r12,MSR_RI - andc r10,r10,r12 - mtmsrd r10,1 /* clear MSR.RI */ - ld r1,GPR1(r1) - mtlr r4 - mtcr r5 - mtspr SPRN_SRR0,r7 - mtspr SPRN_SRR1,r8 - rfid - b . /* prevent speculative execution */ - -syscall_enosys: - li r3,-ENOSYS - std r3,RESULT(r1) - clrrdi r12,r1,THREAD_SHIFT - ld r5,_CCR(r1) - -syscall_error: - lbz r11,TI_SC_NOERR(r12) - cmpwi 0,r11,0 - bne- syscall_error_cont - neg r3,r3 - oris r5,r5,0x1000 /* Set SO bit in CR */ - std r5,_CCR(r1) - b syscall_error_cont - -/* Traced system call support */ -syscall_dotrace: - bl .save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_syscall_trace_enter - ld r0,GPR0(r1) /* Restore original registers */ - ld r3,GPR3(r1) - ld r4,GPR4(r1) - ld r5,GPR5(r1) - ld r6,GPR6(r1) - ld r7,GPR7(r1) - ld r8,GPR8(r1) - addi r9,r1,STACK_FRAME_OVERHEAD - clrrdi r10,r1,THREAD_SHIFT - ld r10,TI_FLAGS(r10) - b syscall_dotrace_cont - -syscall_exit_trace: - std r3,GPR3(r1) - bl .save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_syscall_trace_leave - REST_NVGPRS(r1) - ld r3,GPR3(r1) - ld r5,_CCR(r1) - clrrdi r12,r1,THREAD_SHIFT - b syscall_exit_trace_cont - -/* Stuff to do on exit from a system call. */ -syscall_exit_work: - std r3,GPR3(r1) - std r5,_CCR(r1) - b .ret_from_except_lite - -/* Save non-volatile GPRs, if not already saved. */ -_GLOBAL(save_nvgprs) - ld r11,_TRAP(r1) - andi. r0,r11,1 - beqlr- - SAVE_NVGPRS(r1) - clrrdi r0,r11,1 - std r0,_TRAP(r1) - blr - -/* - * The sigsuspend and rt_sigsuspend system calls can call do_signal - * and thus put the process into the stopped state where we might - * want to examine its user state with ptrace. Therefore we need - * to save all the nonvolatile registers (r14 - r31) before calling - * the C code. Similarly, fork, vfork and clone need the full - * register state on the stack so that it can be copied to the child. - */ -_GLOBAL(ppc32_sigsuspend) - bl .save_nvgprs - bl .compat_sys_sigsuspend - b 70f - -_GLOBAL(ppc64_rt_sigsuspend) - bl .save_nvgprs - bl .sys_rt_sigsuspend - b 70f - -_GLOBAL(ppc32_rt_sigsuspend) - bl .save_nvgprs - bl .compat_sys_rt_sigsuspend -70: cmpdi 0,r3,0 - /* If it returned an error, we need to return via syscall_exit to set - the SO bit in cr0 and potentially stop for ptrace. */ - bne syscall_exit - /* If sigsuspend() returns zero, we are going into a signal handler. We - may need to call audit_syscall_exit() to mark the exit from sigsuspend() */ -#ifdef CONFIG_AUDIT - ld r3,PACACURRENT(r13) - ld r4,AUDITCONTEXT(r3) - cmpdi 0,r4,0 - beq .ret_from_except /* No audit_context: Leave immediately. */ - li r4, 2 /* AUDITSC_FAILURE */ - li r5,-4 /* It's always -EINTR */ - bl .audit_syscall_exit -#endif - b .ret_from_except - -_GLOBAL(ppc_fork) - bl .save_nvgprs - bl .sys_fork - b syscall_exit - -_GLOBAL(ppc_vfork) - bl .save_nvgprs - bl .sys_vfork - b syscall_exit - -_GLOBAL(ppc_clone) - bl .save_nvgprs - bl .sys_clone - b syscall_exit - -_GLOBAL(ppc32_swapcontext) - bl .save_nvgprs - bl .compat_sys_swapcontext - b 80f - -_GLOBAL(ppc64_swapcontext) - bl .save_nvgprs - bl .sys_swapcontext - b 80f - -_GLOBAL(ppc32_sigreturn) - bl .compat_sys_sigreturn - b 80f - -_GLOBAL(ppc32_rt_sigreturn) - bl .compat_sys_rt_sigreturn - b 80f - -_GLOBAL(ppc64_rt_sigreturn) - bl .sys_rt_sigreturn - -80: cmpdi 0,r3,0 - blt syscall_exit - clrrdi r4,r1,THREAD_SHIFT - ld r4,TI_FLAGS(r4) - andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq+ 81f - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_syscall_trace_leave -81: b .ret_from_except - -_GLOBAL(ret_from_fork) - bl .schedule_tail - REST_NVGPRS(r1) - li r3,0 - b syscall_exit - -/* - * This routine switches between two different tasks. The process - * state of one is saved on its kernel stack. Then the state - * of the other is restored from its kernel stack. The memory - * management hardware is updated to the second process's state. - * Finally, we can return to the second process, via ret_from_except. - * On entry, r3 points to the THREAD for the current task, r4 - * points to the THREAD for the new task. - * - * Note: there are two ways to get to the "going out" portion - * of this code; either by coming in via the entry (_switch) - * or via "fork" which must set up an environment equivalent - * to the "_switch" path. If you change this you'll have to change - * the fork code also. - * - * The code which creates the new task context is in 'copy_thread' - * in arch/ppc64/kernel/process.c - */ - .align 7 -_GLOBAL(_switch) - mflr r0 - std r0,16(r1) - stdu r1,-SWITCH_FRAME_SIZE(r1) - /* r3-r13 are caller saved -- Cort */ - SAVE_8GPRS(14, r1) - SAVE_10GPRS(22, r1) - mflr r20 /* Return to switch caller */ - mfmsr r22 - li r0, MSR_FP -#ifdef CONFIG_ALTIVEC -BEGIN_FTR_SECTION - oris r0,r0,MSR_VEC@h /* Disable altivec */ - mfspr r24,SPRN_VRSAVE /* save vrsave register value */ - std r24,THREAD_VRSAVE(r3) -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) -#endif /* CONFIG_ALTIVEC */ - and. r0,r0,r22 - beq+ 1f - andc r22,r22,r0 - mtmsrd r22 - isync -1: std r20,_NIP(r1) - mfcr r23 - std r23,_CCR(r1) - std r1,KSP(r3) /* Set old stack pointer */ - -#ifdef CONFIG_SMP - /* We need a sync somewhere here to make sure that if the - * previous task gets rescheduled on another CPU, it sees all - * stores it has performed on this one. - */ - sync -#endif /* CONFIG_SMP */ - - addi r6,r4,-THREAD /* Convert THREAD to 'current' */ - std r6,PACACURRENT(r13) /* Set new 'current' */ - - ld r8,KSP(r4) /* new stack pointer */ -BEGIN_FTR_SECTION - clrrdi r6,r8,28 /* get its ESID */ - clrrdi r9,r1,28 /* get current sp ESID */ - clrldi. r0,r6,2 /* is new ESID c00000000? */ - cmpd cr1,r6,r9 /* or is new ESID the same as current ESID? */ - cror eq,4*cr1+eq,eq - beq 2f /* if yes, don't slbie it */ - - /* Bolt in the new stack SLB entry */ - ld r7,KSP_VSID(r4) /* Get new stack's VSID */ - oris r0,r6,(SLB_ESID_V)@h - ori r0,r0,(SLB_NUM_BOLTED-1)@l - slbie r6 - slbie r6 /* Workaround POWER5 < DD2.1 issue */ - slbmte r7,r0 - isync - -2: -END_FTR_SECTION_IFSET(CPU_FTR_SLB) - clrrdi r7,r8,THREAD_SHIFT /* base of new stack */ - /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE - because we don't need to leave the 288-byte ABI gap at the - top of the kernel stack. */ - addi r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE - - mr r1,r8 /* start using new stack pointer */ - std r7,PACAKSAVE(r13) - - ld r6,_CCR(r1) - mtcrf 0xFF,r6 - -#ifdef CONFIG_ALTIVEC -BEGIN_FTR_SECTION - ld r0,THREAD_VRSAVE(r4) - mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) -#endif /* CONFIG_ALTIVEC */ - - /* r3-r13 are destroyed -- Cort */ - REST_8GPRS(14, r1) - REST_10GPRS(22, r1) - - /* convert old thread to its task_struct for return value */ - addi r3,r3,-THREAD - ld r7,_NIP(r1) /* Return to _switch caller in new task */ - mtlr r7 - addi r1,r1,SWITCH_FRAME_SIZE - blr - - .align 7 -_GLOBAL(ret_from_except) - ld r11,_TRAP(r1) - andi. r0,r11,1 - bne .ret_from_except_lite - REST_NVGPRS(r1) - -_GLOBAL(ret_from_except_lite) - /* - * Disable interrupts so that current_thread_info()->flags - * can't change between when we test it and when we return - * from the interrupt. - */ - mfmsr r10 /* Get current interrupt state */ - rldicl r9,r10,48,1 /* clear MSR_EE */ - rotldi r9,r9,16 - mtmsrd r9,1 /* Update machine state */ - -#ifdef CONFIG_PREEMPT - clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ - li r0,_TIF_NEED_RESCHED /* bits to check */ - ld r3,_MSR(r1) - ld r4,TI_FLAGS(r9) - /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ - rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING - and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ - bne do_work - -#else /* !CONFIG_PREEMPT */ - ld r3,_MSR(r1) /* Returning to user mode? */ - andi. r3,r3,MSR_PR - beq restore /* if not, just restore regs and return */ - - /* Check current_thread_info()->flags */ - clrrdi r9,r1,THREAD_SHIFT - ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_USER_WORK_MASK - bne do_work -#endif - -restore: -#ifdef CONFIG_PPC_ISERIES - ld r5,SOFTE(r1) - cmpdi 0,r5,0 - beq 4f - /* Check for pending interrupts (iSeries) */ - ld r3,PACALPPACA+LPPACAANYINT(r13) - cmpdi r3,0 - beq+ 4f /* skip do_IRQ if no interrupts */ - - li r3,0 - stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ - ori r10,r10,MSR_EE - mtmsrd r10 /* hard-enable again */ - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_IRQ - b .ret_from_except_lite /* loop back and handle more */ - -4: stb r5,PACAPROCENABLED(r13) -#endif - - ld r3,_MSR(r1) - andi. r0,r3,MSR_RI - beq- unrecov_restore - - andi. r0,r3,MSR_PR - - /* - * r13 is our per cpu area, only restore it if we are returning to - * userspace - */ - beq 1f - REST_GPR(13, r1) -1: - ld r3,_CTR(r1) - ld r0,_LINK(r1) - mtctr r3 - mtlr r0 - ld r3,_XER(r1) - mtspr SPRN_XER,r3 - - REST_8GPRS(5, r1) - - stdcx. r0,0,r1 /* to clear the reservation */ - - mfmsr r0 - li r2, MSR_RI - andc r0,r0,r2 - mtmsrd r0,1 - - ld r0,_MSR(r1) - mtspr SPRN_SRR1,r0 - - ld r2,_CCR(r1) - mtcrf 0xFF,r2 - ld r2,_NIP(r1) - mtspr SPRN_SRR0,r2 - - ld r0,GPR0(r1) - ld r2,GPR2(r1) - ld r3,GPR3(r1) - ld r4,GPR4(r1) - ld r1,GPR1(r1) - - rfid - b . /* prevent speculative execution */ - -/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */ -do_work: -#ifdef CONFIG_PREEMPT - andi. r0,r3,MSR_PR /* Returning to user mode? */ - bne user_work - /* Check that preempt_count() == 0 and interrupts are enabled */ - lwz r8,TI_PREEMPT(r9) - cmpwi cr1,r8,0 -#ifdef CONFIG_PPC_ISERIES - ld r0,SOFTE(r1) - cmpdi r0,0 -#else - andi. r0,r3,MSR_EE -#endif - crandc eq,cr1*4+eq,eq - bne restore - /* here we are preempting the current task */ -1: -#ifdef CONFIG_PPC_ISERIES - li r0,1 - stb r0,PACAPROCENABLED(r13) -#endif - ori r10,r10,MSR_EE - mtmsrd r10,1 /* reenable interrupts */ - bl .preempt_schedule - mfmsr r10 - clrrdi r9,r1,THREAD_SHIFT - rldicl r10,r10,48,1 /* disable interrupts again */ - rotldi r10,r10,16 - mtmsrd r10,1 - ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_NEED_RESCHED - bne 1b - b restore - -user_work: -#endif - /* Enable interrupts */ - ori r10,r10,MSR_EE - mtmsrd r10,1 - - andi. r0,r4,_TIF_NEED_RESCHED - beq 1f - bl .schedule - b .ret_from_except_lite - -1: bl .save_nvgprs - li r3,0 - addi r4,r1,STACK_FRAME_OVERHEAD - bl .do_signal - b .ret_from_except - -unrecov_restore: - addi r3,r1,STACK_FRAME_OVERHEAD - bl .unrecoverable_exception - b unrecov_restore - -#ifdef CONFIG_PPC_RTAS -/* - * On CHRP, the Run-Time Abstraction Services (RTAS) have to be - * called with the MMU off. - * - * In addition, we need to be in 32b mode, at least for now. - * - * Note: r3 is an input parameter to rtas, so don't trash it... - */ -_GLOBAL(enter_rtas) - mflr r0 - std r0,16(r1) - stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */ - - /* Because RTAS is running in 32b mode, it clobbers the high order half - * of all registers that it saves. We therefore save those registers - * RTAS might touch to the stack. (r0, r3-r13 are caller saved) - */ - SAVE_GPR(2, r1) /* Save the TOC */ - SAVE_GPR(13, r1) /* Save paca */ - SAVE_8GPRS(14, r1) /* Save the non-volatiles */ - SAVE_10GPRS(22, r1) /* ditto */ - - mfcr r4 - std r4,_CCR(r1) - mfctr r5 - std r5,_CTR(r1) - mfspr r6,SPRN_XER - std r6,_XER(r1) - mfdar r7 - std r7,_DAR(r1) - mfdsisr r8 - std r8,_DSISR(r1) - mfsrr0 r9 - std r9,_SRR0(r1) - mfsrr1 r10 - std r10,_SRR1(r1) - - /* There is no way it is acceptable to get here with interrupts enabled, - * check it with the asm equivalent of WARN_ON - */ - mfmsr r6 - andi. r0,r6,MSR_EE -1: tdnei r0,0 -.section __bug_table,"a" - .llong 1b,__LINE__ + 0x1000000, 1f, 2f -.previous -.section .rodata,"a" -1: .asciz __FILE__ -2: .asciz "enter_rtas" -.previous - - /* Unfortunately, the stack pointer and the MSR are also clobbered, - * so they are saved in the PACA which allows us to restore - * our original state after RTAS returns. - */ - std r1,PACAR1(r13) - std r6,PACASAVEDMSR(r13) - - /* Setup our real return addr */ - SET_REG_TO_LABEL(r4,.rtas_return_loc) - SET_REG_TO_CONST(r9,KERNELBASE) - sub r4,r4,r9 - mtlr r4 - - li r0,0 - ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI - andc r0,r6,r0 - - li r9,1 - rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG) - ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP - andc r6,r0,r9 - ori r6,r6,MSR_RI - sync /* disable interrupts so SRR0/1 */ - mtmsrd r0 /* don't get trashed */ - - SET_REG_TO_LABEL(r4,rtas) - ld r5,RTASENTRY(r4) /* get the rtas->entry value */ - ld r4,RTASBASE(r4) /* get the rtas->base value */ - - mtspr SPRN_SRR0,r5 - mtspr SPRN_SRR1,r6 - rfid - b . /* prevent speculative execution */ - -_STATIC(rtas_return_loc) - /* relocation is off at this point */ - mfspr r4,SPRN_SPRG3 /* Get PACA */ - SET_REG_TO_CONST(r5, KERNELBASE) - sub r4,r4,r5 /* RELOC the PACA base pointer */ - - mfmsr r6 - li r0,MSR_RI - andc r6,r6,r0 - sync - mtmsrd r6 - - ld r1,PACAR1(r4) /* Restore our SP */ - LOADADDR(r3,.rtas_restore_regs) - ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ - - mtspr SPRN_SRR0,r3 - mtspr SPRN_SRR1,r4 - rfid - b . /* prevent speculative execution */ - -_STATIC(rtas_restore_regs) - /* relocation is on at this point */ - REST_GPR(2, r1) /* Restore the TOC */ - REST_GPR(13, r1) /* Restore paca */ - REST_8GPRS(14, r1) /* Restore the non-volatiles */ - REST_10GPRS(22, r1) /* ditto */ - - mfspr r13,SPRN_SPRG3 - - ld r4,_CCR(r1) - mtcr r4 - ld r5,_CTR(r1) - mtctr r5 - ld r6,_XER(r1) - mtspr SPRN_XER,r6 - ld r7,_DAR(r1) - mtdar r7 - ld r8,_DSISR(r1) - mtdsisr r8 - ld r9,_SRR0(r1) - mtsrr0 r9 - ld r10,_SRR1(r1) - mtsrr1 r10 - - addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */ - ld r0,16(r1) /* get return address */ - - mtlr r0 - blr /* return to caller */ - -#endif /* CONFIG_PPC_RTAS */ - -#ifdef CONFIG_PPC_MULTIPLATFORM - -_GLOBAL(enter_prom) - mflr r0 - std r0,16(r1) - stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ - - /* Because PROM is running in 32b mode, it clobbers the high order half - * of all registers that it saves. We therefore save those registers - * PROM might touch to the stack. (r0, r3-r13 are caller saved) - */ - SAVE_8GPRS(2, r1) - SAVE_GPR(13, r1) - SAVE_8GPRS(14, r1) - SAVE_10GPRS(22, r1) - mfcr r4 - std r4,_CCR(r1) - mfctr r5 - std r5,_CTR(r1) - mfspr r6,SPRN_XER - std r6,_XER(r1) - mfdar r7 - std r7,_DAR(r1) - mfdsisr r8 - std r8,_DSISR(r1) - mfsrr0 r9 - std r9,_SRR0(r1) - mfsrr1 r10 - std r10,_SRR1(r1) - mfmsr r11 - std r11,_MSR(r1) - - /* Get the PROM entrypoint */ - ld r0,GPR4(r1) - mtlr r0 - - /* Switch MSR to 32 bits mode - */ - mfmsr r11 - li r12,1 - rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) - andc r11,r11,r12 - li r12,1 - rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) - andc r11,r11,r12 - mtmsrd r11 - isync - - /* Restore arguments & enter PROM here... */ - ld r3,GPR3(r1) - blrl - - /* Just make sure that r1 top 32 bits didn't get - * corrupt by OF - */ - rldicl r1,r1,0,32 - - /* Restore the MSR (back to 64 bits) */ - ld r0,_MSR(r1) - mtmsrd r0 - isync - - /* Restore other registers */ - REST_GPR(2, r1) - REST_GPR(13, r1) - REST_8GPRS(14, r1) - REST_10GPRS(22, r1) - ld r4,_CCR(r1) - mtcr r4 - ld r5,_CTR(r1) - mtctr r5 - ld r6,_XER(r1) - mtspr SPRN_XER,r6 - ld r7,_DAR(r1) - mtdar r7 - ld r8,_DSISR(r1) - mtdsisr r8 - ld r9,_SRR0(r1) - mtsrr0 r9 - ld r10,_SRR1(r1) - mtsrr1 r10 - - addi r1,r1,PROM_FRAME_SIZE - ld r0,16(r1) - mtlr r0 - blr - -#endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 9cae3d5c40e6..077507ffbab8 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -867,566 +867,3 @@ _GLOBAL(kexec_sequence) li r5,0 blr /* image->start(physid, image->start, 0); */ #endif /* CONFIG_KEXEC */ - -/* Why isn't this a) automatic, b) written in 'C'? */ - .balign 8 -_GLOBAL(sys_call_table32) - .llong .sys_restart_syscall /* 0 */ - .llong .sys_exit - .llong .ppc_fork - .llong .sys_read - .llong .sys_write - .llong .compat_sys_open /* 5 */ - .llong .sys_close - .llong .compat_sys_waitpid - .llong .compat_sys_creat - .llong .sys_link - .llong .sys_unlink /* 10 */ - .llong .compat_sys_execve - .llong .sys_chdir - .llong .compat_sys_time - .llong .sys_mknod - .llong .sys_chmod /* 15 */ - .llong .sys_lchown - .llong .sys_ni_syscall /* old break syscall */ - .llong .sys_ni_syscall /* old stat syscall */ - .llong .ppc32_lseek - .llong .sys_getpid /* 20 */ - .llong .compat_sys_mount - .llong .sys_oldumount - .llong .sys_setuid - .llong .sys_getuid - .llong .compat_sys_stime /* 25 */ - .llong .compat_sys_ptrace - .llong .sys_alarm - .llong .sys_ni_syscall /* old fstat syscall */ - .llong .compat_sys_pause - .llong .compat_sys_utime /* 30 */ - .llong .sys_ni_syscall /* old stty syscall */ - .llong .sys_ni_syscall /* old gtty syscall */ - .llong .compat_sys_access - .llong .compat_sys_nice - .llong .sys_ni_syscall /* 35 - old ftime syscall */ - .llong .sys_sync - .llong .compat_sys_kill - .llong .sys_rename - .llong .compat_sys_mkdir - .llong .sys_rmdir /* 40 */ - .llong .sys_dup - .llong .sys_pipe - .llong .compat_sys_times - .llong .sys_ni_syscall /* old prof syscall */ - .llong .sys_brk /* 45 */ - .llong .sys_setgid - .llong .sys_getgid - .llong .sys_signal - .llong .sys_geteuid - .llong .sys_getegid /* 50 */ - .llong .sys_acct - .llong .sys_umount - .llong .sys_ni_syscall /* old lock syscall */ - .llong .compat_sys_ioctl - .llong .compat_sys_fcntl /* 55 */ - .llong .sys_ni_syscall /* old mpx syscall */ - .llong .compat_sys_setpgid - .llong .sys_ni_syscall /* old ulimit syscall */ - .llong .sys_olduname - .llong .compat_sys_umask /* 60 */ - .llong .sys_chroot - .llong .sys_ustat - .llong .sys_dup2 - .llong .sys_getppid - .llong .sys_getpgrp /* 65 */ - .llong .sys_setsid - .llong .compat_sys_sigaction - .llong .sys_sgetmask - .llong .compat_sys_ssetmask - .llong .sys_setreuid /* 70 */ - .llong .sys_setregid - .llong .ppc32_sigsuspend - .llong .compat_sys_sigpending - .llong .compat_sys_sethostname - .llong .compat_sys_setrlimit /* 75 */ - .llong .compat_sys_old_getrlimit - .llong .compat_sys_getrusage - .llong .compat_sys_gettimeofday - .llong .compat_sys_settimeofday - .llong .compat_sys_getgroups /* 80 */ - .llong .compat_sys_setgroups - .llong .sys_ni_syscall /* old select syscall */ - .llong .sys_symlink - .llong .sys_ni_syscall /* old lstat syscall */ - .llong .compat_sys_readlink /* 85 */ - .llong .sys_uselib - .llong .sys_swapon - .llong .sys_reboot - .llong .old32_readdir - .llong .sys_mmap /* 90 */ - .llong .sys_munmap - .llong .sys_truncate - .llong .sys_ftruncate - .llong .sys_fchmod - .llong .sys_fchown /* 95 */ - .llong .compat_sys_getpriority - .llong .compat_sys_setpriority - .llong .sys_ni_syscall /* old profil syscall */ - .llong .compat_sys_statfs - .llong .compat_sys_fstatfs /* 100 */ - .llong .sys_ni_syscall /* old ioperm syscall */ - .llong .compat_sys_socketcall - .llong .compat_sys_syslog - .llong .compat_sys_setitimer - .llong .compat_sys_getitimer /* 105 */ - .llong .compat_sys_newstat - .llong .compat_sys_newlstat - .llong .compat_sys_newfstat - .llong .sys_uname - .llong .sys_ni_syscall /* 110 old iopl syscall */ - .llong .sys_vhangup - .llong .sys_ni_syscall /* old idle syscall */ - .llong .sys_ni_syscall /* old vm86 syscall */ - .llong .compat_sys_wait4 - .llong .sys_swapoff /* 115 */ - .llong .compat_sys_sysinfo - .llong .sys32_ipc - .llong .sys_fsync - .llong .ppc32_sigreturn - .llong .ppc_clone /* 120 */ - .llong .compat_sys_setdomainname - .llong .ppc_newuname - .llong .sys_ni_syscall /* old modify_ldt syscall */ - .llong .compat_sys_adjtimex - .llong .sys_mprotect /* 125 */ - .llong .compat_sys_sigprocmask - .llong .sys_ni_syscall /* old create_module syscall */ - .llong .sys_init_module - .llong .sys_delete_module - .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */ - .llong .sys_quotactl - .llong .compat_sys_getpgid - .llong .sys_fchdir - .llong .sys_bdflush - .llong .compat_sys_sysfs /* 135 */ - .llong .ppc64_personality - .llong .sys_ni_syscall /* for afs_syscall */ - .llong .sys_setfsuid - .llong .sys_setfsgid - .llong .sys_llseek /* 140 */ - .llong .compat_sys_getdents - .llong .ppc32_select - .llong .sys_flock - .llong .sys_msync - .llong .compat_sys_readv /* 145 */ - .llong .compat_sys_writev - .llong .compat_sys_getsid - .llong .sys_fdatasync - .llong .compat_sys_sysctl - .llong .sys_mlock /* 150 */ - .llong .sys_munlock - .llong .sys_mlockall - .llong .sys_munlockall - .llong .compat_sys_sched_setparam - .llong .compat_sys_sched_getparam /* 155 */ - .llong .compat_sys_sched_setscheduler - .llong .compat_sys_sched_getscheduler - .llong .sys_sched_yield - .llong .compat_sys_sched_get_priority_max - .llong .compat_sys_sched_get_priority_min /* 160 */ - .llong .compat_sys_sched_rr_get_interval - .llong .compat_sys_nanosleep - .llong .sys_mremap - .llong .sys_setresuid - .llong .sys_getresuid /* 165 */ - .llong .sys_ni_syscall /* old query_module syscall */ - .llong .sys_poll - .llong .compat_sys_nfsservctl - .llong .sys_setresgid - .llong .sys_getresgid /* 170 */ - .llong .compat_sys_prctl - .llong .ppc32_rt_sigreturn - .llong .compat_sys_rt_sigaction - .llong .compat_sys_rt_sigprocmask - .llong .compat_sys_rt_sigpending /* 175 */ - .llong .compat_sys_rt_sigtimedwait - .llong .compat_sys_rt_sigqueueinfo - .llong .ppc32_rt_sigsuspend - .llong .compat_sys_pread64 - .llong .compat_sys_pwrite64 /* 180 */ - .llong .sys_chown - .llong .sys_getcwd - .llong .sys_capget - .llong .sys_capset - .llong .compat_sys_sigaltstack /* 185 */ - .llong .compat_sys_sendfile - .llong .sys_ni_syscall /* reserved for streams1 */ - .llong .sys_ni_syscall /* reserved for streams2 */ - .llong .ppc_vfork - .llong .compat_sys_getrlimit /* 190 */ - .llong .compat_sys_readahead - .llong .compat_sys_mmap2 - .llong .compat_sys_truncate64 - .llong .compat_sys_ftruncate64 - .llong .sys_stat64 /* 195 */ - .llong .sys_lstat64 - .llong .sys_fstat64 - .llong .compat_sys_pciconfig_read - .llong .compat_sys_pciconfig_write - .llong .compat_sys_pciconfig_iobase /* 200 - pciconfig_iobase */ - .llong .sys_ni_syscall /* reserved for MacOnLinux */ - .llong .sys_getdents64 - .llong .sys_pivot_root - .llong .compat_sys_fcntl64 - .llong .sys_madvise /* 205 */ - .llong .sys_mincore - .llong .sys_gettid - .llong .sys_tkill - .llong .sys_setxattr - .llong .sys_lsetxattr /* 210 */ - .llong .sys_fsetxattr - .llong .sys_getxattr - .llong .sys_lgetxattr - .llong .sys_fgetxattr - .llong .sys_listxattr /* 215 */ - .llong .sys_llistxattr - .llong .sys_flistxattr - .llong .sys_removexattr - .llong .sys_lremovexattr - .llong .sys_fremovexattr /* 220 */ - .llong .compat_sys_futex - .llong .compat_sys_sched_setaffinity - .llong .compat_sys_sched_getaffinity - .llong .sys_ni_syscall - .llong .sys_ni_syscall /* 225 - reserved for tux */ - .llong .compat_sys_sendfile64 - .llong .compat_sys_io_setup - .llong .sys_io_destroy - .llong .compat_sys_io_getevents - .llong .compat_sys_io_submit - .llong .sys_io_cancel - .llong .sys_set_tid_address - .llong .ppc32_fadvise64 - .llong .sys_exit_group - .llong .ppc32_lookup_dcookie /* 235 */ - .llong .sys_epoll_create - .llong .sys_epoll_ctl - .llong .sys_epoll_wait - .llong .sys_remap_file_pages - .llong .ppc32_timer_create /* 240 */ - .llong .compat_sys_timer_settime - .llong .compat_sys_timer_gettime - .llong .sys_timer_getoverrun - .llong .sys_timer_delete - .llong .compat_sys_clock_settime/* 245 */ - .llong .compat_sys_clock_gettime - .llong .compat_sys_clock_getres - .llong .compat_sys_clock_nanosleep - .llong .ppc32_swapcontext - .llong .compat_sys_tgkill /* 250 */ - .llong .compat_sys_utimes - .llong .compat_sys_statfs64 - .llong .compat_sys_fstatfs64 - .llong .ppc_fadvise64_64 /* 32bit only fadvise64_64 */ - .llong .ppc_rtas /* 255 */ - .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */ - .llong .sys_ni_syscall /* 257 reserved for vserver */ - .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */ - .llong .compat_sys_mbind - .llong .compat_sys_get_mempolicy /* 260 */ - .llong .compat_sys_set_mempolicy - .llong .compat_sys_mq_open - .llong .sys_mq_unlink - .llong .compat_sys_mq_timedsend - .llong .compat_sys_mq_timedreceive /* 265 */ - .llong .compat_sys_mq_notify - .llong .compat_sys_mq_getsetattr - .llong .compat_sys_kexec_load - .llong .compat_sys_add_key - .llong .compat_sys_request_key /* 270 */ - .llong .compat_sys_keyctl - .llong .compat_sys_waitid - .llong .compat_sys_ioprio_set - .llong .compat_sys_ioprio_get - .llong .sys_inotify_init /* 275 */ - .llong .sys_inotify_add_watch - .llong .sys_inotify_rm_watch - - .balign 8 -_GLOBAL(sys_call_table) - .llong .sys_restart_syscall /* 0 */ - .llong .sys_exit - .llong .ppc_fork - .llong .sys_read - .llong .sys_write - .llong .sys_open /* 5 */ - .llong .sys_close - .llong .sys_waitpid - .llong .sys_creat - .llong .sys_link - .llong .sys_unlink /* 10 */ - .llong .sys_execve - .llong .sys_chdir - .llong .sys64_time - .llong .sys_mknod - .llong .sys_chmod /* 15 */ - .llong .sys_lchown - .llong .sys_ni_syscall /* old break syscall */ - .llong .sys_ni_syscall /* old stat syscall */ - .llong .sys_lseek - .llong .sys_getpid /* 20 */ - .llong .sys_mount - .llong .sys_ni_syscall /* old umount syscall */ - .llong .sys_setuid - .llong .sys_getuid - .llong .sys_stime /* 25 */ - .llong .sys_ptrace - .llong .sys_alarm - .llong .sys_ni_syscall /* old fstat syscall */ - .llong .sys_pause - .llong .sys_utime /* 30 */ - .llong .sys_ni_syscall /* old stty syscall */ - .llong .sys_ni_syscall /* old gtty syscall */ - .llong .sys_access - .llong .sys_nice - .llong .sys_ni_syscall /* 35 - old ftime syscall */ - .llong .sys_sync - .llong .sys_kill - .llong .sys_rename - .llong .sys_mkdir - .llong .sys_rmdir /* 40 */ - .llong .sys_dup - .llong .sys_pipe - .llong .sys_times - .llong .sys_ni_syscall /* old prof syscall */ - .llong .sys_brk /* 45 */ - .llong .sys_setgid - .llong .sys_getgid - .llong .sys_signal - .llong .sys_geteuid - .llong .sys_getegid /* 50 */ - .llong .sys_acct - .llong .sys_umount - .llong .sys_ni_syscall /* old lock syscall */ - .llong .sys_ioctl - .llong .sys_fcntl /* 55 */ - .llong .sys_ni_syscall /* old mpx syscall */ - .llong .sys_setpgid - .llong .sys_ni_syscall /* old ulimit syscall */ - .llong .sys_ni_syscall /* old uname syscall */ - .llong .sys_umask /* 60 */ - .llong .sys_chroot - .llong .sys_ustat - .llong .sys_dup2 - .llong .sys_getppid - .llong .sys_getpgrp /* 65 */ - .llong .sys_setsid - .llong .sys_ni_syscall - .llong .sys_sgetmask - .llong .sys_ssetmask - .llong .sys_setreuid /* 70 */ - .llong .sys_setregid - .llong .sys_ni_syscall - .llong .sys_ni_syscall - .llong .sys_sethostname - .llong .sys_setrlimit /* 75 */ - .llong .sys_ni_syscall /* old getrlimit syscall */ - .llong .sys_getrusage - .llong .sys_gettimeofday - .llong .sys_settimeofday - .llong .sys_getgroups /* 80 */ - .llong .sys_setgroups - .llong .sys_ni_syscall /* old select syscall */ - .llong .sys_symlink - .llong .sys_ni_syscall /* old lstat syscall */ - .llong .sys_readlink /* 85 */ - .llong .sys_uselib - .llong .sys_swapon - .llong .sys_reboot - .llong .sys_ni_syscall /* old readdir syscall */ - .llong .sys_mmap /* 90 */ - .llong .sys_munmap - .llong .sys_truncate - .llong .sys_ftruncate - .llong .sys_fchmod - .llong .sys_fchown /* 95 */ - .llong .sys_getpriority - .llong .sys_setpriority - .llong .sys_ni_syscall /* old profil syscall holder */ - .llong .sys_statfs - .llong .sys_fstatfs /* 100 */ - .llong .sys_ni_syscall /* old ioperm syscall */ - .llong .sys_socketcall - .llong .sys_syslog - .llong .sys_setitimer - .llong .sys_getitimer /* 105 */ - .llong .sys_newstat - .llong .sys_newlstat - .llong .sys_newfstat - .llong .sys_ni_syscall /* old uname syscall */ - .llong .sys_ni_syscall /* 110 old iopl syscall */ - .llong .sys_vhangup - .llong .sys_ni_syscall /* old idle syscall */ - .llong .sys_ni_syscall /* old vm86 syscall */ - .llong .sys_wait4 - .llong .sys_swapoff /* 115 */ - .llong .sys_sysinfo - .llong .sys_ipc - .llong .sys_fsync - .llong .sys_ni_syscall - .llong .ppc_clone /* 120 */ - .llong .sys_setdomainname - .llong .ppc_newuname - .llong .sys_ni_syscall /* old modify_ldt syscall */ - .llong .sys_adjtimex - .llong .sys_mprotect /* 125 */ - .llong .sys_ni_syscall - .llong .sys_ni_syscall /* old create_module syscall */ - .llong .sys_init_module - .llong .sys_delete_module - .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */ - .llong .sys_quotactl - .llong .sys_getpgid - .llong .sys_fchdir - .llong .sys_bdflush - .llong .sys_sysfs /* 135 */ - .llong .ppc64_personality - .llong .sys_ni_syscall /* for afs_syscall */ - .llong .sys_setfsuid - .llong .sys_setfsgid - .llong .sys_llseek /* 140 */ - .llong .sys_getdents - .llong .sys_select - .llong .sys_flock - .llong .sys_msync - .llong .sys_readv /* 145 */ - .llong .sys_writev - .llong .sys_getsid - .llong .sys_fdatasync - .llong .sys_sysctl - .llong .sys_mlock /* 150 */ - .llong .sys_munlock - .llong .sys_mlockall - .llong .sys_munlockall - .llong .sys_sched_setparam - .llong .sys_sched_getparam /* 155 */ - .llong .sys_sched_setscheduler - .llong .sys_sched_getscheduler - .llong .sys_sched_yield - .llong .sys_sched_get_priority_max - .llong .sys_sched_get_priority_min /* 160 */ - .llong .sys_sched_rr_get_interval - .llong .sys_nanosleep - .llong .sys_mremap - .llong .sys_setresuid - .llong .sys_getresuid /* 165 */ - .llong .sys_ni_syscall /* old query_module syscall */ - .llong .sys_poll - .llong .sys_nfsservctl - .llong .sys_setresgid - .llong .sys_getresgid /* 170 */ - .llong .sys_prctl - .llong .ppc64_rt_sigreturn - .llong .sys_rt_sigaction - .llong .sys_rt_sigprocmask - .llong .sys_rt_sigpending /* 175 */ - .llong .sys_rt_sigtimedwait - .llong .sys_rt_sigqueueinfo - .llong .ppc64_rt_sigsuspend - .llong .sys_pread64 - .llong .sys_pwrite64 /* 180 */ - .llong .sys_chown - .llong .sys_getcwd - .llong .sys_capget - .llong .sys_capset - .llong .sys_sigaltstack /* 185 */ - .llong .sys_sendfile64 - .llong .sys_ni_syscall /* reserved for streams1 */ - .llong .sys_ni_syscall /* reserved for streams2 */ - .llong .ppc_vfork - .llong .sys_getrlimit /* 190 */ - .llong .sys_readahead - .llong .sys_ni_syscall /* 32bit only mmap2 */ - .llong .sys_ni_syscall /* 32bit only truncate64 */ - .llong .sys_ni_syscall /* 32bit only ftruncate64 */ - .llong .sys_ni_syscall /* 195 - 32bit only stat64 */ - .llong .sys_ni_syscall /* 32bit only lstat64 */ - .llong .sys_ni_syscall /* 32bit only fstat64 */ - .llong .sys_pciconfig_read - .llong .sys_pciconfig_write - .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */ - .llong .sys_ni_syscall /* reserved for MacOnLinux */ - .llong .sys_getdents64 - .llong .sys_pivot_root - .llong .sys_ni_syscall /* 32bit only fcntl64 */ - .llong .sys_madvise /* 205 */ - .llong .sys_mincore - .llong .sys_gettid - .llong .sys_tkill - .llong .sys_setxattr - .llong .sys_lsetxattr /* 210 */ - .llong .sys_fsetxattr - .llong .sys_getxattr - .llong .sys_lgetxattr - .llong .sys_fgetxattr - .llong .sys_listxattr /* 215 */ - .llong .sys_llistxattr - .llong .sys_flistxattr - .llong .sys_removexattr - .llong .sys_lremovexattr - .llong .sys_fremovexattr /* 220 */ - .llong .sys_futex - .llong .sys_sched_setaffinity - .llong .sys_sched_getaffinity - .llong .sys_ni_syscall - .llong .sys_ni_syscall /* 225 - reserved for tux */ - .llong .sys_ni_syscall /* 32bit only sendfile64 */ - .llong .sys_io_setup - .llong .sys_io_destroy - .llong .sys_io_getevents - .llong .sys_io_submit /* 230 */ - .llong .sys_io_cancel - .llong .sys_set_tid_address - .llong .sys_fadvise64 - .llong .sys_exit_group - .llong .sys_lookup_dcookie /* 235 */ - .llong .sys_epoll_create - .llong .sys_epoll_ctl - .llong .sys_epoll_wait - .llong .sys_remap_file_pages - .llong .sys_timer_create /* 240 */ - .llong .sys_timer_settime - .llong .sys_timer_gettime - .llong .sys_timer_getoverrun - .llong .sys_timer_delete - .llong .sys_clock_settime /* 245 */ - .llong .sys_clock_gettime - .llong .sys_clock_getres - .llong .sys_clock_nanosleep - .llong .ppc64_swapcontext - .llong .sys_tgkill /* 250 */ - .llong .sys_utimes - .llong .sys_statfs64 - .llong .sys_fstatfs64 - .llong .sys_ni_syscall /* 32bit only fadvise64_64 */ - .llong .ppc_rtas /* 255 */ - .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */ - .llong .sys_ni_syscall /* 257 reserved for vserver */ - .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */ - .llong .sys_mbind - .llong .sys_get_mempolicy /* 260 */ - .llong .sys_set_mempolicy - .llong .sys_mq_open - .llong .sys_mq_unlink - .llong .sys_mq_timedsend - .llong .sys_mq_timedreceive /* 265 */ - .llong .sys_mq_notify - .llong .sys_mq_getsetattr - .llong .sys_kexec_load - .llong .sys_add_key - .llong .sys_request_key /* 270 */ - .llong .sys_keyctl - .llong .sys_waitid - .llong .sys_ioprio_set - .llong .sys_ioprio_get - .llong .sys_inotify_init /* 275 */ - .llong .sys_inotify_add_watch - .llong .sys_inotify_rm_watch From 1a3c061efd32b620cf6498b71687ff0768cfe2d8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:25:05 +1000 Subject: [PATCH 0514/1940] ppc64: use checksum_64.S from powerpc as it is identical to checksum.S from ppc64. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 5 +- arch/ppc64/Makefile | 1 + arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/checksum.S | 229 -------------------------------------- 4 files changed, 6 insertions(+), 231 deletions(-) delete mode 100644 arch/ppc64/lib/checksum.S diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 30367a0237dd..1f1f01b757d4 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -2,12 +2,15 @@ # Makefile for ppc-specific library files.. # +ifeq ($(CONFIG_PPC_MERGE),y) obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o memcpy_64.o \ - usercopy_64.o sstep.o checksum_64.o mem_64.o + usercopy_64.o sstep.o mem_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o endif +endif +obj-$(CONFIG_PPC64) += checksum_64.o diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 66ee04f13b26..2a7af765bfb6 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -88,6 +88,7 @@ core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ core-y += arch/powerpc/mm/ core-y += arch/powerpc/sysdev/ core-y += arch/powerpc/platforms/ +core-y += arch/powerpc/lib/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 0b6e967de948..fa457a24cae1 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc64-specific library files.. # -lib-y := checksum.o string.o strcase.o +lib-y := string.o strcase.o lib-y += copypage.o memcpy.o copyuser.o usercopy.o # Lock primitives are defined as no-ops in include/linux/spinlock.h diff --git a/arch/ppc64/lib/checksum.S b/arch/ppc64/lib/checksum.S deleted file mode 100644 index ef96c6c58efc..000000000000 --- a/arch/ppc64/lib/checksum.S +++ /dev/null @@ -1,229 +0,0 @@ -/* - * This file contains assembly-language implementations - * of IP-style 1's complement checksum routines. - * - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * 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. - * - * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au). - */ - -#include -#include -#include -#include - -/* - * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header - * len is in words and is always >= 5. - * - * In practice len == 5, but this is not guaranteed. So this code does not - * attempt to use doubleword instructions. - */ -_GLOBAL(ip_fast_csum) - lwz r0,0(r3) - lwzu r5,4(r3) - addic. r4,r4,-2 - addc r0,r0,r5 - mtctr r4 - blelr- -1: lwzu r4,4(r3) - adde r0,r0,r4 - bdnz 1b - addze r0,r0 /* add in final carry */ - rldicl r4,r0,32,0 /* fold two 32-bit halves together */ - add r0,r0,r4 - srdi r0,r0,32 - rlwinm r3,r0,16,0,31 /* fold two halves together */ - add r3,r0,r3 - not r3,r3 - srwi r3,r3,16 - blr - -/* - * Compute checksum of TCP or UDP pseudo-header: - * csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum) - * No real gain trying to do this specially for 64 bit, but - * the 32 bit addition may spill into the upper bits of - * the doubleword so we still must fold it down from 64. - */ -_GLOBAL(csum_tcpudp_magic) - rlwimi r5,r6,16,0,15 /* put proto in upper half of len */ - addc r0,r3,r4 /* add 4 32-bit words together */ - adde r0,r0,r5 - adde r0,r0,r7 - rldicl r4,r0,32,0 /* fold 64 bit value */ - add r0,r4,r0 - srdi r0,r0,32 - rlwinm r3,r0,16,0,31 /* fold two halves together */ - add r3,r0,r3 - not r3,r3 - srwi r3,r3,16 - blr - -/* - * Computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit). - * - * This code assumes at least halfword alignment, though the length - * can be any number of bytes. The sum is accumulated in r5. - * - * csum_partial(r3=buff, r4=len, r5=sum) - */ -_GLOBAL(csum_partial) - subi r3,r3,8 /* we'll offset by 8 for the loads */ - srdi. r6,r4,3 /* divide by 8 for doubleword count */ - addic r5,r5,0 /* clear carry */ - beq 3f /* if we're doing < 8 bytes */ - andi. r0,r3,2 /* aligned on a word boundary already? */ - beq+ 1f - lhz r6,8(r3) /* do 2 bytes to get aligned */ - addi r3,r3,2 - subi r4,r4,2 - addc r5,r5,r6 - srdi. r6,r4,3 /* recompute number of doublewords */ - beq 3f /* any left? */ -1: mtctr r6 -2: ldu r6,8(r3) /* main sum loop */ - adde r5,r5,r6 - bdnz 2b - andi. r4,r4,7 /* compute bytes left to sum after doublewords */ -3: cmpwi 0,r4,4 /* is at least a full word left? */ - blt 4f - lwz r6,8(r3) /* sum this word */ - addi r3,r3,4 - subi r4,r4,4 - adde r5,r5,r6 -4: cmpwi 0,r4,2 /* is at least a halfword left? */ - blt+ 5f - lhz r6,8(r3) /* sum this halfword */ - addi r3,r3,2 - subi r4,r4,2 - adde r5,r5,r6 -5: cmpwi 0,r4,1 /* is at least a byte left? */ - bne+ 6f - lbz r6,8(r3) /* sum this byte */ - slwi r6,r6,8 /* this byte is assumed to be the upper byte of a halfword */ - adde r5,r5,r6 -6: addze r5,r5 /* add in final carry */ - rldicl r4,r5,32,0 /* fold two 32-bit halves together */ - add r3,r4,r5 - srdi r3,r3,32 - blr - -/* - * Computes the checksum of a memory block at src, length len, - * and adds in "sum" (32-bit), while copying the block to dst. - * If an access exception occurs on src or dst, it stores -EFAULT - * to *src_err or *dst_err respectively, and (for an error on - * src) zeroes the rest of dst. - * - * This code needs to be reworked to take advantage of 64 bit sum+copy. - * However, due to tokenring halfword alignment problems this will be very - * tricky. For now we'll leave it until we instrument it somehow. - * - * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err) - */ -_GLOBAL(csum_partial_copy_generic) - addic r0,r6,0 - subi r3,r3,4 - subi r4,r4,4 - srwi. r6,r5,2 - beq 3f /* if we're doing < 4 bytes */ - andi. r9,r4,2 /* Align dst to longword boundary */ - beq+ 1f -81: lhz r6,4(r3) /* do 2 bytes to get aligned */ - addi r3,r3,2 - subi r5,r5,2 -91: sth r6,4(r4) - addi r4,r4,2 - addc r0,r0,r6 - srwi. r6,r5,2 /* # words to do */ - beq 3f -1: mtctr r6 -82: lwzu r6,4(r3) /* the bdnz has zero overhead, so it should */ -92: stwu r6,4(r4) /* be unnecessary to unroll this loop */ - adde r0,r0,r6 - bdnz 82b - andi. r5,r5,3 -3: cmpwi 0,r5,2 - blt+ 4f -83: lhz r6,4(r3) - addi r3,r3,2 - subi r5,r5,2 -93: sth r6,4(r4) - addi r4,r4,2 - adde r0,r0,r6 -4: cmpwi 0,r5,1 - bne+ 5f -84: lbz r6,4(r3) -94: stb r6,4(r4) - slwi r6,r6,8 /* Upper byte of word */ - adde r0,r0,r6 -5: addze r3,r0 /* add in final carry (unlikely with 64-bit regs) */ - rldicl r4,r3,32,0 /* fold 64 bit value */ - add r3,r4,r3 - srdi r3,r3,32 - blr - -/* These shouldn't go in the fixup section, since that would - cause the ex_table addresses to get out of order. */ - - .globl src_error_1 -src_error_1: - li r6,0 - subi r5,r5,2 -95: sth r6,4(r4) - addi r4,r4,2 - srwi. r6,r5,2 - beq 3f - mtctr r6 - .globl src_error_2 -src_error_2: - li r6,0 -96: stwu r6,4(r4) - bdnz 96b -3: andi. r5,r5,3 - beq src_error - .globl src_error_3 -src_error_3: - li r6,0 - mtctr r5 - addi r4,r4,3 -97: stbu r6,1(r4) - bdnz 97b - .globl src_error -src_error: - cmpdi 0,r7,0 - beq 1f - li r6,-EFAULT - stw r6,0(r7) -1: addze r3,r0 - blr - - .globl dst_error -dst_error: - cmpdi 0,r8,0 - beq 1f - li r6,-EFAULT - stw r6,0(r8) -1: addze r3,r0 - blr - -.section __ex_table,"a" - .align 3 - .llong 81b,src_error_1 - .llong 91b,dst_error - .llong 82b,src_error_2 - .llong 92b,dst_error - .llong 83b,src_error_3 - .llong 93b,dst_error - .llong 84b,src_error_3 - .llong 94b,dst_error - .llong 95b,dst_error - .llong 96b,dst_error - .llong 97b,dst_error From 454fb016b3407e7cacbe17e590521ddf86a54f7f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:28:43 +1000 Subject: [PATCH 0515/1940] ppc64: use e2a.c from powerpc/lib since it is identical to e2a.c from ppc64/lib Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 2 +- arch/ppc64/lib/Makefile | 5 -- arch/ppc64/lib/e2a.c | 108 -------------------------------------- 3 files changed, 1 insertion(+), 114 deletions(-) delete mode 100644 arch/ppc64/lib/e2a.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 1f1f01b757d4..87153891d7a7 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -7,10 +7,10 @@ obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o memcpy_64.o \ usercopy_64.o sstep.o mem_64.o -obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o endif endif obj-$(CONFIG_PPC64) += checksum_64.o +obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index fa457a24cae1..62c3116b003f 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -10,9 +10,4 @@ lib-y += copypage.o memcpy.o copyuser.o usercopy.o lib-$(CONFIG_SMP) += locks.o -# e2a provides EBCDIC to ASCII conversions. -ifdef CONFIG_PPC_ISERIES -obj-y += e2a.o -endif - lib-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/arch/ppc64/lib/e2a.c b/arch/ppc64/lib/e2a.c deleted file mode 100644 index d2b834887920..000000000000 --- a/arch/ppc64/lib/e2a.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * arch/ppc64/lib/e2a.c - * - * EBCDIC to ASCII conversion - * - * This function moved here from arch/ppc64/kernel/viopath.c - * - * (C) Copyright 2000-2004 IBM Corporation - * - * 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) anyu 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; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include - -unsigned char e2a(unsigned char x) -{ - switch (x) { - case 0xF0: - return '0'; - case 0xF1: - return '1'; - case 0xF2: - return '2'; - case 0xF3: - return '3'; - case 0xF4: - return '4'; - case 0xF5: - return '5'; - case 0xF6: - return '6'; - case 0xF7: - return '7'; - case 0xF8: - return '8'; - case 0xF9: - return '9'; - case 0xC1: - return 'A'; - case 0xC2: - return 'B'; - case 0xC3: - return 'C'; - case 0xC4: - return 'D'; - case 0xC5: - return 'E'; - case 0xC6: - return 'F'; - case 0xC7: - return 'G'; - case 0xC8: - return 'H'; - case 0xC9: - return 'I'; - case 0xD1: - return 'J'; - case 0xD2: - return 'K'; - case 0xD3: - return 'L'; - case 0xD4: - return 'M'; - case 0xD5: - return 'N'; - case 0xD6: - return 'O'; - case 0xD7: - return 'P'; - case 0xD8: - return 'Q'; - case 0xD9: - return 'R'; - case 0xE2: - return 'S'; - case 0xE3: - return 'T'; - case 0xE4: - return 'U'; - case 0xE5: - return 'V'; - case 0xE6: - return 'W'; - case 0xE7: - return 'X'; - case 0xE8: - return 'Y'; - case 0xE9: - return 'Z'; - } - return ' '; -} -EXPORT_SYMBOL(e2a); - - From 34faa82841b87e6f375b01dad3262ca345de25c0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:35:43 +1000 Subject: [PATCH 0516/1940] ppc64: use copypage_64.S from powerpc/lib since it is identical to copypage.S from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 4 +- arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/copypage.S | 121 -------------------------------------- 3 files changed, 3 insertions(+), 124 deletions(-) delete mode 100644 arch/ppc64/lib/copypage.S diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 87153891d7a7..5e481944250e 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -5,12 +5,12 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o -obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o memcpy_64.o \ +obj-$(CONFIG_PPC64) += copyuser_64.o memcpy_64.o \ usercopy_64.o sstep.o mem_64.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o endif endif -obj-$(CONFIG_PPC64) += checksum_64.o +obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 62c3116b003f..820021885e1a 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -3,7 +3,7 @@ # lib-y := string.o strcase.o -lib-y += copypage.o memcpy.o copyuser.o usercopy.o +lib-y += memcpy.o copyuser.o usercopy.o # Lock primitives are defined as no-ops in include/linux/spinlock.h # for non-SMP configs. Don't build the real versions. diff --git a/arch/ppc64/lib/copypage.S b/arch/ppc64/lib/copypage.S deleted file mode 100644 index 733d61618bbf..000000000000 --- a/arch/ppc64/lib/copypage.S +++ /dev/null @@ -1,121 +0,0 @@ -/* - * arch/ppc64/lib/copypage.S - * - * Copyright (C) 2002 Paul Mackerras, IBM Corp. - * - * 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. - */ -#include -#include - -_GLOBAL(copy_page) - std r31,-8(1) - std r30,-16(1) - std r29,-24(1) - std r28,-32(1) - std r27,-40(1) - std r26,-48(1) - std r25,-56(1) - std r24,-64(1) - std r23,-72(1) - std r22,-80(1) - std r21,-88(1) - std r20,-96(1) - li r5,4096/32 - 1 - addi r3,r3,-8 - li r12,5 -0: addi r5,r5,-24 - mtctr r12 - ld r22,640(4) - ld r21,512(4) - ld r20,384(4) - ld r11,256(4) - ld r9,128(4) - ld r7,0(4) - ld r25,648(4) - ld r24,520(4) - ld r23,392(4) - ld r10,264(4) - ld r8,136(4) - ldu r6,8(4) - cmpwi r5,24 -1: std r22,648(3) - std r21,520(3) - std r20,392(3) - std r11,264(3) - std r9,136(3) - std r7,8(3) - ld r28,648(4) - ld r27,520(4) - ld r26,392(4) - ld r31,264(4) - ld r30,136(4) - ld r29,8(4) - std r25,656(3) - std r24,528(3) - std r23,400(3) - std r10,272(3) - std r8,144(3) - std r6,16(3) - ld r22,656(4) - ld r21,528(4) - ld r20,400(4) - ld r11,272(4) - ld r9,144(4) - ld r7,16(4) - std r28,664(3) - std r27,536(3) - std r26,408(3) - std r31,280(3) - std r30,152(3) - stdu r29,24(3) - ld r25,664(4) - ld r24,536(4) - ld r23,408(4) - ld r10,280(4) - ld r8,152(4) - ldu r6,24(4) - bdnz 1b - std r22,648(3) - std r21,520(3) - std r20,392(3) - std r11,264(3) - std r9,136(3) - std r7,8(3) - addi r4,r4,640 - addi r3,r3,648 - bge 0b - mtctr r5 - ld r7,0(4) - ld r8,8(4) - ldu r9,16(4) -3: ld r10,8(4) - std r7,8(3) - ld r7,16(4) - std r8,16(3) - ld r8,24(4) - std r9,24(3) - ldu r9,32(4) - stdu r10,32(3) - bdnz 3b -4: ld r10,8(4) - std r7,8(3) - std r8,16(3) - std r9,24(3) - std r10,32(3) -9: ld r20,-96(1) - ld r21,-88(1) - ld r22,-80(1) - ld r23,-72(1) - ld r24,-64(1) - ld r25,-56(1) - ld r26,-48(1) - ld r27,-40(1) - ld r28,-32(1) - ld r29,-24(1) - ld r30,-16(1) - ld r31,-8(1) - blr From 43f35ec35c2b9a1c984d885893084eed2101e1bf Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:40:05 +1000 Subject: [PATCH 0517/1940] ppc64: use copyuser_64.S from powerpc/lib since it is identical to copyuser.S from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 4 +- arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/copyuser.S | 576 -------------------------------------- 3 files changed, 3 insertions(+), 579 deletions(-) delete mode 100644 arch/ppc64/lib/copyuser.S diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 5e481944250e..3474c9309e2f 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -5,12 +5,12 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o -obj-$(CONFIG_PPC64) += copyuser_64.o memcpy_64.o \ +obj-$(CONFIG_PPC64) += memcpy_64.o \ usercopy_64.o sstep.o mem_64.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o endif endif -obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o +obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 820021885e1a..f29e76559950 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -3,7 +3,7 @@ # lib-y := string.o strcase.o -lib-y += memcpy.o copyuser.o usercopy.o +lib-y += memcpy.o usercopy.o # Lock primitives are defined as no-ops in include/linux/spinlock.h # for non-SMP configs. Don't build the real versions. diff --git a/arch/ppc64/lib/copyuser.S b/arch/ppc64/lib/copyuser.S deleted file mode 100644 index a0b3fbbd6fb1..000000000000 --- a/arch/ppc64/lib/copyuser.S +++ /dev/null @@ -1,576 +0,0 @@ -/* - * arch/ppc64/lib/copyuser.S - * - * Copyright (C) 2002 Paul Mackerras, IBM Corp. - * - * 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. - */ -#include -#include - - .align 7 -_GLOBAL(__copy_tofrom_user) - /* first check for a whole page copy on a page boundary */ - cmpldi cr1,r5,16 - cmpdi cr6,r5,4096 - or r0,r3,r4 - neg r6,r3 /* LS 3 bits = # bytes to 8-byte dest bdry */ - andi. r0,r0,4095 - std r3,-24(r1) - crand cr0*4+2,cr0*4+2,cr6*4+2 - std r4,-16(r1) - std r5,-8(r1) - dcbt 0,r4 - beq .Lcopy_page - andi. r6,r6,7 - mtcrf 0x01,r5 - blt cr1,.Lshort_copy - bne .Ldst_unaligned -.Ldst_aligned: - andi. r0,r4,7 - addi r3,r3,-16 - bne .Lsrc_unaligned - srdi r7,r5,4 -20: ld r9,0(r4) - addi r4,r4,-8 - mtctr r7 - andi. r5,r5,7 - bf cr7*4+0,22f - addi r3,r3,8 - addi r4,r4,8 - mr r8,r9 - blt cr1,72f -21: ld r9,8(r4) -70: std r8,8(r3) -22: ldu r8,16(r4) -71: stdu r9,16(r3) - bdnz 21b -72: std r8,8(r3) - beq+ 3f - addi r3,r3,16 -23: ld r9,8(r4) -.Ldo_tail: - bf cr7*4+1,1f - rotldi r9,r9,32 -73: stw r9,0(r3) - addi r3,r3,4 -1: bf cr7*4+2,2f - rotldi r9,r9,16 -74: sth r9,0(r3) - addi r3,r3,2 -2: bf cr7*4+3,3f - rotldi r9,r9,8 -75: stb r9,0(r3) -3: li r3,0 - blr - -.Lsrc_unaligned: - srdi r6,r5,3 - addi r5,r5,-16 - subf r4,r0,r4 - srdi r7,r5,4 - sldi r10,r0,3 - cmpldi cr6,r6,3 - andi. r5,r5,7 - mtctr r7 - subfic r11,r10,64 - add r5,r5,r0 - bt cr7*4+0,28f - -24: ld r9,0(r4) /* 3+2n loads, 2+2n stores */ -25: ld r0,8(r4) - sld r6,r9,r10 -26: ldu r9,16(r4) - srd r7,r0,r11 - sld r8,r0,r10 - or r7,r7,r6 - blt cr6,79f -27: ld r0,8(r4) - b 2f - -28: ld r0,0(r4) /* 4+2n loads, 3+2n stores */ -29: ldu r9,8(r4) - sld r8,r0,r10 - addi r3,r3,-8 - blt cr6,5f -30: ld r0,8(r4) - srd r12,r9,r11 - sld r6,r9,r10 -31: ldu r9,16(r4) - or r12,r8,r12 - srd r7,r0,r11 - sld r8,r0,r10 - addi r3,r3,16 - beq cr6,78f - -1: or r7,r7,r6 -32: ld r0,8(r4) -76: std r12,8(r3) -2: srd r12,r9,r11 - sld r6,r9,r10 -33: ldu r9,16(r4) - or r12,r8,r12 -77: stdu r7,16(r3) - srd r7,r0,r11 - sld r8,r0,r10 - bdnz 1b - -78: std r12,8(r3) - or r7,r7,r6 -79: std r7,16(r3) -5: srd r12,r9,r11 - or r12,r8,r12 -80: std r12,24(r3) - bne 6f - li r3,0 - blr -6: cmpwi cr1,r5,8 - addi r3,r3,32 - sld r9,r9,r10 - ble cr1,.Ldo_tail -34: ld r0,8(r4) - srd r7,r0,r11 - or r9,r7,r9 - b .Ldo_tail - -.Ldst_unaligned: - mtcrf 0x01,r6 /* put #bytes to 8B bdry into cr7 */ - subf r5,r6,r5 - li r7,0 - cmpldi r1,r5,16 - bf cr7*4+3,1f -35: lbz r0,0(r4) -81: stb r0,0(r3) - addi r7,r7,1 -1: bf cr7*4+2,2f -36: lhzx r0,r7,r4 -82: sthx r0,r7,r3 - addi r7,r7,2 -2: bf cr7*4+1,3f -37: lwzx r0,r7,r4 -83: stwx r0,r7,r3 -3: mtcrf 0x01,r5 - add r4,r6,r4 - add r3,r6,r3 - b .Ldst_aligned - -.Lshort_copy: - bf cr7*4+0,1f -38: lwz r0,0(r4) -39: lwz r9,4(r4) - addi r4,r4,8 -84: stw r0,0(r3) -85: stw r9,4(r3) - addi r3,r3,8 -1: bf cr7*4+1,2f -40: lwz r0,0(r4) - addi r4,r4,4 -86: stw r0,0(r3) - addi r3,r3,4 -2: bf cr7*4+2,3f -41: lhz r0,0(r4) - addi r4,r4,2 -87: sth r0,0(r3) - addi r3,r3,2 -3: bf cr7*4+3,4f -42: lbz r0,0(r4) -88: stb r0,0(r3) -4: li r3,0 - blr - -/* - * exception handlers follow - * we have to return the number of bytes not copied - * for an exception on a load, we set the rest of the destination to 0 - */ - -136: -137: - add r3,r3,r7 - b 1f -130: -131: - addi r3,r3,8 -120: -122: -124: -125: -126: -127: -128: -129: -133: - addi r3,r3,8 -121: -132: - addi r3,r3,8 -123: -134: -135: -138: -139: -140: -141: -142: - -/* - * here we have had a fault on a load and r3 points to the first - * unmodified byte of the destination - */ -1: ld r6,-24(r1) - ld r4,-16(r1) - ld r5,-8(r1) - subf r6,r6,r3 - add r4,r4,r6 - subf r5,r6,r5 /* #bytes left to go */ - -/* - * first see if we can copy any more bytes before hitting another exception - */ - mtctr r5 -43: lbz r0,0(r4) - addi r4,r4,1 -89: stb r0,0(r3) - addi r3,r3,1 - bdnz 43b - li r3,0 /* huh? all copied successfully this time? */ - blr - -/* - * here we have trapped again, need to clear ctr bytes starting at r3 - */ -143: mfctr r5 - li r0,0 - mr r4,r3 - mr r3,r5 /* return the number of bytes not copied */ -1: andi. r9,r4,7 - beq 3f -90: stb r0,0(r4) - addic. r5,r5,-1 - addi r4,r4,1 - bne 1b - blr -3: cmpldi cr1,r5,8 - srdi r9,r5,3 - andi. r5,r5,7 - blt cr1,93f - mtctr r9 -91: std r0,0(r4) - addi r4,r4,8 - bdnz 91b -93: beqlr - mtctr r5 -92: stb r0,0(r4) - addi r4,r4,1 - bdnz 92b - blr - -/* - * exception handlers for stores: we just need to work - * out how many bytes weren't copied - */ -182: -183: - add r3,r3,r7 - b 1f -180: - addi r3,r3,8 -171: -177: - addi r3,r3,8 -170: -172: -176: -178: - addi r3,r3,4 -185: - addi r3,r3,4 -173: -174: -175: -179: -181: -184: -186: -187: -188: -189: -1: - ld r6,-24(r1) - ld r5,-8(r1) - add r6,r6,r5 - subf r3,r3,r6 /* #bytes not copied */ -190: -191: -192: - blr /* #bytes not copied in r3 */ - - .section __ex_table,"a" - .align 3 - .llong 20b,120b - .llong 21b,121b - .llong 70b,170b - .llong 22b,122b - .llong 71b,171b - .llong 72b,172b - .llong 23b,123b - .llong 73b,173b - .llong 74b,174b - .llong 75b,175b - .llong 24b,124b - .llong 25b,125b - .llong 26b,126b - .llong 27b,127b - .llong 28b,128b - .llong 29b,129b - .llong 30b,130b - .llong 31b,131b - .llong 32b,132b - .llong 76b,176b - .llong 33b,133b - .llong 77b,177b - .llong 78b,178b - .llong 79b,179b - .llong 80b,180b - .llong 34b,134b - .llong 35b,135b - .llong 81b,181b - .llong 36b,136b - .llong 82b,182b - .llong 37b,137b - .llong 83b,183b - .llong 38b,138b - .llong 39b,139b - .llong 84b,184b - .llong 85b,185b - .llong 40b,140b - .llong 86b,186b - .llong 41b,141b - .llong 87b,187b - .llong 42b,142b - .llong 88b,188b - .llong 43b,143b - .llong 89b,189b - .llong 90b,190b - .llong 91b,191b - .llong 92b,192b - - .text - -/* - * Routine to copy a whole page of data, optimized for POWER4. - * On POWER4 it is more than 50% faster than the simple loop - * above (following the .Ldst_aligned label) but it runs slightly - * slower on POWER3. - */ -.Lcopy_page: - std r31,-32(1) - std r30,-40(1) - std r29,-48(1) - std r28,-56(1) - std r27,-64(1) - std r26,-72(1) - std r25,-80(1) - std r24,-88(1) - std r23,-96(1) - std r22,-104(1) - std r21,-112(1) - std r20,-120(1) - li r5,4096/32 - 1 - addi r3,r3,-8 - li r0,5 -0: addi r5,r5,-24 - mtctr r0 -20: ld r22,640(4) -21: ld r21,512(4) -22: ld r20,384(4) -23: ld r11,256(4) -24: ld r9,128(4) -25: ld r7,0(4) -26: ld r25,648(4) -27: ld r24,520(4) -28: ld r23,392(4) -29: ld r10,264(4) -30: ld r8,136(4) -31: ldu r6,8(4) - cmpwi r5,24 -1: -32: std r22,648(3) -33: std r21,520(3) -34: std r20,392(3) -35: std r11,264(3) -36: std r9,136(3) -37: std r7,8(3) -38: ld r28,648(4) -39: ld r27,520(4) -40: ld r26,392(4) -41: ld r31,264(4) -42: ld r30,136(4) -43: ld r29,8(4) -44: std r25,656(3) -45: std r24,528(3) -46: std r23,400(3) -47: std r10,272(3) -48: std r8,144(3) -49: std r6,16(3) -50: ld r22,656(4) -51: ld r21,528(4) -52: ld r20,400(4) -53: ld r11,272(4) -54: ld r9,144(4) -55: ld r7,16(4) -56: std r28,664(3) -57: std r27,536(3) -58: std r26,408(3) -59: std r31,280(3) -60: std r30,152(3) -61: stdu r29,24(3) -62: ld r25,664(4) -63: ld r24,536(4) -64: ld r23,408(4) -65: ld r10,280(4) -66: ld r8,152(4) -67: ldu r6,24(4) - bdnz 1b -68: std r22,648(3) -69: std r21,520(3) -70: std r20,392(3) -71: std r11,264(3) -72: std r9,136(3) -73: std r7,8(3) -74: addi r4,r4,640 -75: addi r3,r3,648 - bge 0b - mtctr r5 -76: ld r7,0(4) -77: ld r8,8(4) -78: ldu r9,16(4) -3: -79: ld r10,8(4) -80: std r7,8(3) -81: ld r7,16(4) -82: std r8,16(3) -83: ld r8,24(4) -84: std r9,24(3) -85: ldu r9,32(4) -86: stdu r10,32(3) - bdnz 3b -4: -87: ld r10,8(4) -88: std r7,8(3) -89: std r8,16(3) -90: std r9,24(3) -91: std r10,32(3) -9: ld r20,-120(1) - ld r21,-112(1) - ld r22,-104(1) - ld r23,-96(1) - ld r24,-88(1) - ld r25,-80(1) - ld r26,-72(1) - ld r27,-64(1) - ld r28,-56(1) - ld r29,-48(1) - ld r30,-40(1) - ld r31,-32(1) - li r3,0 - blr - -/* - * on an exception, reset to the beginning and jump back into the - * standard __copy_tofrom_user - */ -100: ld r20,-120(1) - ld r21,-112(1) - ld r22,-104(1) - ld r23,-96(1) - ld r24,-88(1) - ld r25,-80(1) - ld r26,-72(1) - ld r27,-64(1) - ld r28,-56(1) - ld r29,-48(1) - ld r30,-40(1) - ld r31,-32(1) - ld r3,-24(r1) - ld r4,-16(r1) - li r5,4096 - b .Ldst_aligned - - .section __ex_table,"a" - .align 3 - .llong 20b,100b - .llong 21b,100b - .llong 22b,100b - .llong 23b,100b - .llong 24b,100b - .llong 25b,100b - .llong 26b,100b - .llong 27b,100b - .llong 28b,100b - .llong 29b,100b - .llong 30b,100b - .llong 31b,100b - .llong 32b,100b - .llong 33b,100b - .llong 34b,100b - .llong 35b,100b - .llong 36b,100b - .llong 37b,100b - .llong 38b,100b - .llong 39b,100b - .llong 40b,100b - .llong 41b,100b - .llong 42b,100b - .llong 43b,100b - .llong 44b,100b - .llong 45b,100b - .llong 46b,100b - .llong 47b,100b - .llong 48b,100b - .llong 49b,100b - .llong 50b,100b - .llong 51b,100b - .llong 52b,100b - .llong 53b,100b - .llong 54b,100b - .llong 55b,100b - .llong 56b,100b - .llong 57b,100b - .llong 58b,100b - .llong 59b,100b - .llong 60b,100b - .llong 61b,100b - .llong 62b,100b - .llong 63b,100b - .llong 64b,100b - .llong 65b,100b - .llong 66b,100b - .llong 67b,100b - .llong 68b,100b - .llong 69b,100b - .llong 70b,100b - .llong 71b,100b - .llong 72b,100b - .llong 73b,100b - .llong 74b,100b - .llong 75b,100b - .llong 76b,100b - .llong 77b,100b - .llong 78b,100b - .llong 79b,100b - .llong 80b,100b - .llong 81b,100b - .llong 82b,100b - .llong 83b,100b - .llong 84b,100b - .llong 85b,100b - .llong 86b,100b - .llong 87b,100b - .llong 88b,100b - .llong 89b,100b - .llong 90b,100b - .llong 91b,100b From ecc81e0f719f566b75b222b8aef64c8b809b2e29 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:45:38 +1000 Subject: [PATCH 0518/1940] ppc64: use lockc.c from powerpc/lib since it is effectively the same as locks.c from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 6 +-- arch/ppc64/lib/Makefile | 5 --- arch/ppc64/lib/locks.c | 95 --------------------------------------- 3 files changed, 3 insertions(+), 103 deletions(-) delete mode 100644 arch/ppc64/lib/locks.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 3474c9309e2f..955c06421590 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -7,10 +7,10 @@ obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += memcpy_64.o \ usercopy_64.o sstep.o mem_64.o -ifeq ($(CONFIG_PPC64),y) -obj-$(CONFIG_SMP) += locks.o -endif endif obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o +ifeq ($(CONFIG_PPC64),y) +obj-$(CONFIG_SMP) += locks.o +endif diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index f29e76559950..87c2ff5e1883 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -5,9 +5,4 @@ lib-y := string.o strcase.o lib-y += memcpy.o usercopy.o -# Lock primitives are defined as no-ops in include/linux/spinlock.h -# for non-SMP configs. Don't build the real versions. - -lib-$(CONFIG_SMP) += locks.o - lib-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/arch/ppc64/lib/locks.c b/arch/ppc64/lib/locks.c deleted file mode 100644 index 033643ab69e0..000000000000 --- a/arch/ppc64/lib/locks.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Spin and read/write lock operations. - * - * Copyright (C) 2001-2004 Paul Mackerras , IBM - * Copyright (C) 2001 Anton Blanchard , IBM - * Copyright (C) 2002 Dave Engebretsen , IBM - * Rework to support virtual processors - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* waiting for a spinlock... */ -#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) - -void __spin_yield(raw_spinlock_t *lock) -{ - unsigned int lock_value, holder_cpu, yield_count; - struct paca_struct *holder_paca; - - lock_value = lock->slock; - if (lock_value == 0) - return; - holder_cpu = lock_value & 0xffff; - BUG_ON(holder_cpu >= NR_CPUS); - holder_paca = &paca[holder_cpu]; - yield_count = holder_paca->lppaca.yield_count; - if ((yield_count & 1) == 0) - return; /* virtual cpu is currently running */ - rmb(); - if (lock->slock != lock_value) - return; /* something has changed */ -#ifdef CONFIG_PPC_ISERIES - HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, - ((u64)holder_cpu << 32) | yield_count); -#else - plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), - yield_count); -#endif -} - -/* - * Waiting for a read lock or a write lock on a rwlock... - * This turns out to be the same for read and write locks, since - * we only know the holder if it is write-locked. - */ -void __rw_yield(raw_rwlock_t *rw) -{ - int lock_value; - unsigned int holder_cpu, yield_count; - struct paca_struct *holder_paca; - - lock_value = rw->lock; - if (lock_value >= 0) - return; /* no write lock at present */ - holder_cpu = lock_value & 0xffff; - BUG_ON(holder_cpu >= NR_CPUS); - holder_paca = &paca[holder_cpu]; - yield_count = holder_paca->lppaca.yield_count; - if ((yield_count & 1) == 0) - return; /* virtual cpu is currently running */ - rmb(); - if (rw->lock != lock_value) - return; /* something has changed */ -#ifdef CONFIG_PPC_ISERIES - HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, - ((u64)holder_cpu << 32) | yield_count); -#else - plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), - yield_count); -#endif -} -#endif - -void __raw_spin_unlock_wait(raw_spinlock_t *lock) -{ - while (lock->slock) { - HMT_low(); - if (SHARED_PROCESSOR) - __spin_yield(lock); - } - HMT_medium(); -} - -EXPORT_SYMBOL(__raw_spin_unlock_wait); From 12a39407f021fd17d5f9d33d78bddb005bd106fb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 16:49:44 +1000 Subject: [PATCH 0519/1940] ppc64: use memcpy_64.S from powerpc/lib since it is identical to mempcy.S from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 6 +- arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/memcpy.S | 172 -------------------------------------- 3 files changed, 4 insertions(+), 176 deletions(-) delete mode 100644 arch/ppc64/lib/memcpy.S diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 955c06421590..9cf35ed3f33a 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -5,11 +5,11 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o -obj-$(CONFIG_PPC64) += memcpy_64.o \ - usercopy_64.o sstep.o mem_64.o +obj-$(CONFIG_PPC64) += usercopy_64.o sstep.o mem_64.o endif -obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o +obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ + memcpy_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 87c2ff5e1883..49af089c6049 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -3,6 +3,6 @@ # lib-y := string.o strcase.o -lib-y += memcpy.o usercopy.o +lib-y += usercopy.o lib-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/arch/ppc64/lib/memcpy.S b/arch/ppc64/lib/memcpy.S deleted file mode 100644 index 9ccacdf5bcb9..000000000000 --- a/arch/ppc64/lib/memcpy.S +++ /dev/null @@ -1,172 +0,0 @@ -/* - * arch/ppc64/lib/memcpy.S - * - * Copyright (C) 2002 Paul Mackerras, IBM Corp. - * - * 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. - */ -#include -#include - - .align 7 -_GLOBAL(memcpy) - mtcrf 0x01,r5 - cmpldi cr1,r5,16 - neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry - andi. r6,r6,7 - dcbt 0,r4 - blt cr1,.Lshort_copy - bne .Ldst_unaligned -.Ldst_aligned: - andi. r0,r4,7 - addi r3,r3,-16 - bne .Lsrc_unaligned - srdi r7,r5,4 - ld r9,0(r4) - addi r4,r4,-8 - mtctr r7 - andi. r5,r5,7 - bf cr7*4+0,2f - addi r3,r3,8 - addi r4,r4,8 - mr r8,r9 - blt cr1,3f -1: ld r9,8(r4) - std r8,8(r3) -2: ldu r8,16(r4) - stdu r9,16(r3) - bdnz 1b -3: std r8,8(r3) - beqlr - addi r3,r3,16 - ld r9,8(r4) -.Ldo_tail: - bf cr7*4+1,1f - rotldi r9,r9,32 - stw r9,0(r3) - addi r3,r3,4 -1: bf cr7*4+2,2f - rotldi r9,r9,16 - sth r9,0(r3) - addi r3,r3,2 -2: bf cr7*4+3,3f - rotldi r9,r9,8 - stb r9,0(r3) -3: blr - -.Lsrc_unaligned: - srdi r6,r5,3 - addi r5,r5,-16 - subf r4,r0,r4 - srdi r7,r5,4 - sldi r10,r0,3 - cmpdi cr6,r6,3 - andi. r5,r5,7 - mtctr r7 - subfic r11,r10,64 - add r5,r5,r0 - - bt cr7*4+0,0f - - ld r9,0(r4) # 3+2n loads, 2+2n stores - ld r0,8(r4) - sld r6,r9,r10 - ldu r9,16(r4) - srd r7,r0,r11 - sld r8,r0,r10 - or r7,r7,r6 - blt cr6,4f - ld r0,8(r4) - # s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12 - b 2f - -0: ld r0,0(r4) # 4+2n loads, 3+2n stores - ldu r9,8(r4) - sld r8,r0,r10 - addi r3,r3,-8 - blt cr6,5f - ld r0,8(r4) - srd r12,r9,r11 - sld r6,r9,r10 - ldu r9,16(r4) - or r12,r8,r12 - srd r7,r0,r11 - sld r8,r0,r10 - addi r3,r3,16 - beq cr6,3f - - # d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9 -1: or r7,r7,r6 - ld r0,8(r4) - std r12,8(r3) -2: srd r12,r9,r11 - sld r6,r9,r10 - ldu r9,16(r4) - or r12,r8,r12 - stdu r7,16(r3) - srd r7,r0,r11 - sld r8,r0,r10 - bdnz 1b - -3: std r12,8(r3) - or r7,r7,r6 -4: std r7,16(r3) -5: srd r12,r9,r11 - or r12,r8,r12 - std r12,24(r3) - beqlr - cmpwi cr1,r5,8 - addi r3,r3,32 - sld r9,r9,r10 - ble cr1,.Ldo_tail - ld r0,8(r4) - srd r7,r0,r11 - or r9,r7,r9 - b .Ldo_tail - -.Ldst_unaligned: - mtcrf 0x01,r6 # put #bytes to 8B bdry into cr7 - subf r5,r6,r5 - li r7,0 - cmpldi r1,r5,16 - bf cr7*4+3,1f - lbz r0,0(r4) - stb r0,0(r3) - addi r7,r7,1 -1: bf cr7*4+2,2f - lhzx r0,r7,r4 - sthx r0,r7,r3 - addi r7,r7,2 -2: bf cr7*4+1,3f - lwzx r0,r7,r4 - stwx r0,r7,r3 -3: mtcrf 0x01,r5 - add r4,r6,r4 - add r3,r6,r3 - b .Ldst_aligned - -.Lshort_copy: - bf cr7*4+0,1f - lwz r0,0(r4) - lwz r9,4(r4) - addi r4,r4,8 - stw r0,0(r3) - stw r9,4(r3) - addi r3,r3,8 -1: bf cr7*4+1,2f - lwz r0,0(r4) - addi r4,r4,4 - stw r0,0(r3) - addi r3,r3,4 -2: bf cr7*4+2,3f - lhz r0,0(r4) - addi r4,r4,2 - sth r0,0(r3) - addi r3,r3,2 -3: bf cr7*4+3,4f - lbz r0,0(r4) - stb r0,0(r3) -4: blr From a0d8bf9cf1f9722204936d8ef53370d7ae1181d9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 17:05:27 +1000 Subject: [PATCH 0520/1940] ppc64: use sstep.c from powerpc/lib since it is identical to sstep.c from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 3 +- arch/ppc64/lib/Makefile | 2 - arch/ppc64/lib/sstep.c | 141 -------------------------------------- 3 files changed, 2 insertions(+), 144 deletions(-) delete mode 100644 arch/ppc64/lib/sstep.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 9cf35ed3f33a..a7af96ce9df2 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -5,7 +5,7 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := strcase.o string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o -obj-$(CONFIG_PPC64) += usercopy_64.o sstep.o mem_64.o +obj-$(CONFIG_PPC64) += usercopy_64.o mem_64.o endif obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ @@ -13,4 +13,5 @@ obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o +obj-$(CONFIG_DEBUG_KERNEL) += sstep.o endif diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 49af089c6049..e8ce831d8eae 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -4,5 +4,3 @@ lib-y := string.o strcase.o lib-y += usercopy.o - -lib-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/arch/ppc64/lib/sstep.c b/arch/ppc64/lib/sstep.c deleted file mode 100644 index e79123d1485c..000000000000 --- a/arch/ppc64/lib/sstep.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Single-step support. - * - * Copyright (C) 2004 Paul Mackerras , IBM - * - * 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. - */ -#include -#include -#include -#include - -extern char system_call_common[]; - -/* Bits in SRR1 that are copied from MSR */ -#define MSR_MASK 0xffffffff87c0ffff - -/* - * Determine whether a conditional branch instruction would branch. - */ -static int branch_taken(unsigned int instr, struct pt_regs *regs) -{ - unsigned int bo = (instr >> 21) & 0x1f; - unsigned int bi; - - if ((bo & 4) == 0) { - /* decrement counter */ - --regs->ctr; - if (((bo >> 1) & 1) ^ (regs->ctr == 0)) - return 0; - } - if ((bo & 0x10) == 0) { - /* check bit from CR */ - bi = (instr >> 16) & 0x1f; - if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1)) - return 0; - } - return 1; -} - -/* - * Emulate instructions that cause a transfer of control. - * Returns 1 if the step was emulated, 0 if not, - * or -1 if the instruction is one that should not be stepped, - * such as an rfid, or a mtmsrd that would clear MSR_RI. - */ -int emulate_step(struct pt_regs *regs, unsigned int instr) -{ - unsigned int opcode, rd; - unsigned long int imm; - - opcode = instr >> 26; - switch (opcode) { - case 16: /* bc */ - imm = (signed short)(instr & 0xfffc); - if ((instr & 2) == 0) - imm += regs->nip; - regs->nip += 4; - if ((regs->msr & MSR_SF) == 0) - regs->nip &= 0xffffffffUL; - if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = imm; - return 1; - case 17: /* sc */ - /* - * N.B. this uses knowledge about how the syscall - * entry code works. If that is changed, this will - * need to be changed also. - */ - regs->gpr[9] = regs->gpr[13]; - regs->gpr[11] = regs->nip + 4; - regs->gpr[12] = regs->msr & MSR_MASK; - regs->gpr[13] = (unsigned long) get_paca(); - regs->nip = (unsigned long) &system_call_common; - regs->msr = MSR_KERNEL; - return 1; - case 18: /* b */ - imm = instr & 0x03fffffc; - if (imm & 0x02000000) - imm -= 0x04000000; - if ((instr & 2) == 0) - imm += regs->nip; - if (instr & 1) { - regs->link = regs->nip + 4; - if ((regs->msr & MSR_SF) == 0) - regs->link &= 0xffffffffUL; - } - if ((regs->msr & MSR_SF) == 0) - imm &= 0xffffffffUL; - regs->nip = imm; - return 1; - case 19: - switch (instr & 0x7fe) { - case 0x20: /* bclr */ - case 0x420: /* bcctr */ - imm = (instr & 0x400)? regs->ctr: regs->link; - regs->nip += 4; - if ((regs->msr & MSR_SF) == 0) { - regs->nip &= 0xffffffffUL; - imm &= 0xffffffffUL; - } - if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = imm; - return 1; - case 0x24: /* rfid, scary */ - return -1; - } - case 31: - rd = (instr >> 21) & 0x1f; - switch (instr & 0x7fe) { - case 0xa6: /* mfmsr */ - regs->gpr[rd] = regs->msr & MSR_MASK; - regs->nip += 4; - if ((regs->msr & MSR_SF) == 0) - regs->nip &= 0xffffffffUL; - return 1; - case 0x164: /* mtmsrd */ - /* only MSR_EE and MSR_RI get changed if bit 15 set */ - /* mtmsrd doesn't change MSR_HV and MSR_ME */ - imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; - imm = (regs->msr & MSR_MASK & ~imm) - | (regs->gpr[rd] & imm); - if ((imm & MSR_RI) == 0) - /* can't step mtmsrd that would clear MSR_RI */ - return -1; - regs->msr = imm; - regs->nip += 4; - if ((imm & MSR_SF) == 0) - regs->nip &= 0xffffffffUL; - return 1; - } - } - return 0; -} From a2b0ca84a1198505f0b3c7b55b7769dd5dbd0791 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 17:12:52 +1000 Subject: [PATCH 0521/1940] ppc64: user strcase.c from powerpc/lib since it is identical to strcase.c from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 5 +++-- arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/strcase.c | 31 ------------------------------- 3 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 arch/ppc64/lib/strcase.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index a7af96ce9df2..0726235ef25d 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -3,11 +3,12 @@ # ifeq ($(CONFIG_PPC_MERGE),y) -obj-y := strcase.o string.o -obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o +obj-y := string.o obj-$(CONFIG_PPC64) += usercopy_64.o mem_64.o endif +obj-y += strcase.o +obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ memcpy_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index e8ce831d8eae..f4732c5ffd5f 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -2,5 +2,5 @@ # Makefile for ppc64-specific library files.. # -lib-y := string.o strcase.o +lib-y := string.o lib-y += usercopy.o diff --git a/arch/ppc64/lib/strcase.c b/arch/ppc64/lib/strcase.c deleted file mode 100644 index e84f243368c0..000000000000 --- a/arch/ppc64/lib/strcase.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * c 2001 PPC 64 Team, IBM Corp - * - * 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. - */ -#include - -int strcasecmp(const char *s1, const char *s2) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while (c1 == c2 && c1 != 0); - return c1 - c2; -} - -int strncasecmp(const char *s1, const char *s2, int n) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while ((--n > 0) && c1 == c2 && c1 != 0); - return c1 - c2; -} From a4a264f144d5389a52d467a7e41bec2834cfde75 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 17:28:21 +1000 Subject: [PATCH 0522/1940] ppc64: use usercopy_64.c from powerpc/lib since it is identical to usercopy.c from ppc64/lib. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 4 ++-- arch/ppc64/lib/Makefile | 1 - arch/ppc64/lib/usercopy.c | 41 --------------------------------------- 3 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 arch/ppc64/lib/usercopy.c diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 0726235ef25d..15b6b2696500 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -4,13 +4,13 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := string.o -obj-$(CONFIG_PPC64) += usercopy_64.o mem_64.o +obj-$(CONFIG_PPC64) += mem_64.o endif obj-y += strcase.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ - memcpy_64.o + memcpy_64.o usercopy_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index f4732c5ffd5f..42d5295bf345 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -3,4 +3,3 @@ # lib-y := string.o -lib-y += usercopy.o diff --git a/arch/ppc64/lib/usercopy.c b/arch/ppc64/lib/usercopy.c deleted file mode 100644 index 5eea6f3c1e03..000000000000 --- a/arch/ppc64/lib/usercopy.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Functions which are too large to be inlined. - * - * 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. - */ -#include -#include - -unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n))) - n = __copy_from_user(to, from, n); - else - memset(to, 0, n); - return n; -} - -unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_WRITE, to, n))) - n = __copy_to_user(to, from, n); - return n; -} - -unsigned long copy_in_user(void __user *to, const void __user *from, - unsigned long n) -{ - might_sleep(); - if (likely(access_ok(VERIFY_READ, from, n) && - access_ok(VERIFY_WRITE, to, n))) - n =__copy_tofrom_user(to, from, n); - return n; -} - -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_in_user); - From 299f6ce491aa28515d86f29af2779cbfdc7a4790 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 27 Oct 2005 18:03:58 +1000 Subject: [PATCH 0523/1940] ppc64: use mem_64.S from powerpc/lib and remove the same bits from ppc64/lib/string.S. Signed-off-by: Stephen Rothwell --- arch/powerpc/lib/Makefile | 3 +- arch/ppc64/lib/string.S | 106 -------------------------------------- 2 files changed, 1 insertion(+), 108 deletions(-) diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 15b6b2696500..0115bf96751c 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -4,13 +4,12 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := string.o -obj-$(CONFIG_PPC64) += mem_64.o endif obj-y += strcase.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ - memcpy_64.o usercopy_64.o + memcpy_64.o usercopy_64.o mem_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o diff --git a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S index 813587e5c2ec..e21a0038a4d6 100644 --- a/arch/ppc64/lib/string.S +++ b/arch/ppc64/lib/string.S @@ -65,112 +65,6 @@ _GLOBAL(strlen) subf r3,r3,r4 blr -_GLOBAL(memset) - neg r0,r3 - rlwimi r4,r4,8,16,23 - andi. r0,r0,7 /* # bytes to be 8-byte aligned */ - rlwimi r4,r4,16,0,15 - cmplw cr1,r5,r0 /* do we get that far? */ - rldimi r4,r4,32,0 - mtcrf 1,r0 - mr r6,r3 - blt cr1,8f - beq+ 3f /* if already 8-byte aligned */ - subf r5,r0,r5 - bf 31,1f - stb r4,0(r6) - addi r6,r6,1 -1: bf 30,2f - sth r4,0(r6) - addi r6,r6,2 -2: bf 29,3f - stw r4,0(r6) - addi r6,r6,4 -3: srdi. r0,r5,6 - clrldi r5,r5,58 - mtctr r0 - beq 5f -4: std r4,0(r6) - std r4,8(r6) - std r4,16(r6) - std r4,24(r6) - std r4,32(r6) - std r4,40(r6) - std r4,48(r6) - std r4,56(r6) - addi r6,r6,64 - bdnz 4b -5: srwi. r0,r5,3 - clrlwi r5,r5,29 - mtcrf 1,r0 - beq 8f - bf 29,6f - std r4,0(r6) - std r4,8(r6) - std r4,16(r6) - std r4,24(r6) - addi r6,r6,32 -6: bf 30,7f - std r4,0(r6) - std r4,8(r6) - addi r6,r6,16 -7: bf 31,8f - std r4,0(r6) - addi r6,r6,8 -8: cmpwi r5,0 - mtcrf 1,r5 - beqlr+ - bf 29,9f - stw r4,0(r6) - addi r6,r6,4 -9: bf 30,10f - sth r4,0(r6) - addi r6,r6,2 -10: bflr 31 - stb r4,0(r6) - blr - -_GLOBAL(memmove) - cmplw 0,r3,r4 - bgt .backwards_memcpy - b .memcpy - -_GLOBAL(backwards_memcpy) - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - add r6,r3,r5 - add r4,r4,r5 - beq 2f - andi. r0,r6,3 - mtctr r7 - bne 5f -1: lwz r7,-4(r4) - lwzu r8,-8(r4) - stw r7,-4(r6) - stwu r8,-8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,-4(r4) - subi r5,r5,4 - stwu r0,-4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 -4: lbzu r0,-1(r4) - stbu r0,-1(r6) - bdnz 4b - blr -5: mtctr r0 -6: lbzu r7,-1(r4) - stbu r7,-1(r6) - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - _GLOBAL(memcmp) cmpwi 0,r5,0 ble- 2f From 089a1bedd84be16a4f49a319e7ccb4a128da5ce9 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 27 Oct 2005 20:33:43 -0700 Subject: [PATCH 0524/1940] [IB] ib_umad: fix crash when freeing send buffers The conversion of user_mad.c to the new MAD send API was slightly off: in a few places, we used packet->msg instead of packet->msg->mad when referring to the actual data buffer, which ended up corrupting the underlying data structure and crashing when we free an invalid pointer. Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index fc5519a3de99..a48166a8e04b 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -398,12 +398,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, * transaction ID matches the agent being used to send the * MAD. */ - method = ((struct ib_mad_hdr *) packet->msg)->method; + method = ((struct ib_mad_hdr *) packet->msg->mad)->method; if (!(method & IB_MGMT_METHOD_RESP) && method != IB_MGMT_METHOD_TRAP_REPRESS && method != IB_MGMT_METHOD_SEND) { - tid = &((struct ib_mad_hdr *) packet->msg)->tid; + tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | (be64_to_cpup(tid) & 0xffffffff)); } From cb0f0910f4b41772a6771bdb4fb2d419b27bcd77 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 27 Oct 2005 20:48:11 -0700 Subject: [PATCH 0525/1940] [IB] ib_umad: various cleanups Simplify user_mad.c code in a few places, and convert from kmalloc() + memset() to kzalloc(). This also fixes a theoretical race window by not accessing packet->length after posting the send buffer (the send could complete and packet could be freed before we get to the return statement at the end of ib_umad_write()). Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 73 +++++++++--------------------- 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index a48166a8e04b..17ec0a19dbc0 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -99,7 +99,6 @@ struct ib_umad_packet { struct ib_mad_send_buf *msg; struct list_head list; int length; - DECLARE_PCI_UNMAP_ADDR(mapping) struct ib_user_mad mad; }; @@ -145,15 +144,12 @@ static void send_handler(struct ib_mad_agent *agent, ib_free_send_mad(packet->msg); if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { - timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr), - GFP_KERNEL); + timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL); if (!timeout) goto out; - memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr)); - - timeout->length = sizeof (struct ib_mad_hdr); - timeout->mad.hdr.id = packet->mad.hdr.id; + timeout->length = IB_MGMT_MAD_HDR; + timeout->mad.hdr.id = packet->mad.hdr.id; timeout->mad.hdr.status = ETIMEDOUT; memcpy(timeout->mad.data, packet->mad.data, sizeof (struct ib_mad_hdr)); @@ -176,11 +172,10 @@ static void recv_handler(struct ib_mad_agent *agent, goto out; length = mad_recv_wc->mad_len; - packet = kmalloc(sizeof *packet + length, GFP_KERNEL); + packet = kzalloc(sizeof *packet + length, GFP_KERNEL); if (!packet) goto out; - memset(packet, 0, sizeof *packet + length); packet->length = length; ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data); @@ -246,7 +241,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, else ret = -ENOSPC; } else if (copy_to_user(buf, &packet->mad, - packet->length + sizeof (struct ib_user_mad))) + packet->length + sizeof (struct ib_user_mad))) ret = -EFAULT; else ret = packet->length + sizeof (struct ib_user_mad); @@ -271,22 +266,19 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, struct ib_rmpp_mad *rmpp_mad; u8 method; __be64 *tid; - int ret, length, hdr_len, rmpp_hdr_size; + int ret, length, hdr_len, copy_offset; int rmpp_active = 0; if (count < sizeof (struct ib_user_mad)) return -EINVAL; length = count - sizeof (struct ib_user_mad); - packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) + - sizeof (struct ib_rmpp_hdr), GFP_KERNEL); + packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); if (!packet) return -ENOMEM; if (copy_from_user(&packet->mad, buf, - sizeof (struct ib_user_mad) + - sizeof (struct ib_mad_hdr) + - sizeof (struct ib_rmpp_hdr))) { + sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) { ret = -EFAULT; goto err; } @@ -297,8 +289,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, goto err; } - packet->length = length; - down_read(&file->agent_mutex); agent = file->agent[packet->mad.hdr.id]; @@ -345,12 +335,10 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, goto err_ah; } rmpp_active = 1; + copy_offset = IB_MGMT_RMPP_HDR; } else { - if (length > sizeof (struct ib_mad)) { - ret = -EINVAL; - goto err_ah; - } hdr_len = IB_MGMT_MAD_HDR; + copy_offset = IB_MGMT_MAD_HDR; } packet->msg = ib_create_send_mad(agent, @@ -368,28 +356,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, packet->msg->retries = packet->mad.hdr.retries; packet->msg->context[0] = packet; - if (!rmpp_active) { - /* Copy message from user into send buffer */ - if (copy_from_user(packet->msg->mad, - buf + sizeof (struct ib_user_mad), length)) { - ret = -EFAULT; - goto err_msg; - } - } else { - rmpp_hdr_size = sizeof (struct ib_mad_hdr) + - sizeof (struct ib_rmpp_hdr); - - /* Only copy MAD headers (RMPP header in place) */ - memcpy(packet->msg->mad, packet->mad.data, - sizeof (struct ib_mad_hdr)); - - /* Now, copy rest of message from user into send buffer */ - if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data, - buf + sizeof (struct ib_user_mad) + rmpp_hdr_size, - length - rmpp_hdr_size)) { - ret = -EFAULT; - goto err_msg; - } + /* Copy MAD headers (RMPP header in place) */ + memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR); + /* Now, copy rest of message from user into send buffer */ + if (copy_from_user(packet->msg->mad + copy_offset, + buf + sizeof (struct ib_user_mad) + copy_offset, + length - copy_offset)) { + ret = -EFAULT; + goto err_msg; } /* @@ -414,7 +388,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, up_read(&file->agent_mutex); - return sizeof (struct ib_user_mad_hdr) + packet->length; + return count; err_msg: ib_free_send_mad(packet->msg); @@ -564,12 +538,10 @@ static int ib_umad_open(struct inode *inode, struct file *filp) container_of(inode->i_cdev, struct ib_umad_port, dev); struct ib_umad_file *file; - file = kmalloc(sizeof *file, GFP_KERNEL); + file = kzalloc(sizeof *file, GFP_KERNEL); if (!file) return -ENOMEM; - memset(file, 0, sizeof *file); - spin_lock_init(&file->recv_lock); init_rwsem(&file->agent_mutex); INIT_LIST_HEAD(&file->recv_list); @@ -814,15 +786,12 @@ static void ib_umad_add_one(struct ib_device *device) e = device->phys_port_cnt; } - umad_dev = kmalloc(sizeof *umad_dev + + umad_dev = kzalloc(sizeof *umad_dev + (e - s + 1) * sizeof (struct ib_umad_port), GFP_KERNEL); if (!umad_dev) return; - memset(umad_dev, 0, sizeof *umad_dev + - (e - s + 1) * sizeof (struct ib_umad_port)); - kref_init(&umad_dev->ref); umad_dev->start_port = s; From 007e8f51b26ae7b6a17651af5a0f01ab6491cdca Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 28 Oct 2005 15:35:50 +1000 Subject: [PATCH 0526/1940] [PATCH] powerpc: Move xics.[ch] into platforms/pseries This patch moves the XICS interrupt controller code into the platforms/pseries directory, since it only appears on pSeries machines. If it ever appears on some other machine we can move it to sysdev, although xics.c itself will need a bunch of changes in that case to remove pSeries specific assumptions. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/Makefile | 1 + arch/powerpc/platforms/pseries/setup.c | 2 +- arch/powerpc/platforms/pseries/smp.c | 2 +- .../platforms/pseries}/xics.c | 25 ++++++++++--------- .../powerpc/platforms/pseries}/xics.h | 10 ++++---- arch/ppc64/kernel/Makefile | 2 -- 6 files changed, 21 insertions(+), 21 deletions(-) rename arch/{ppc64/kernel => powerpc/platforms/pseries}/xics.c (98%) rename {include/asm-ppc64 => arch/powerpc/platforms/pseries}/xics.h (84%) diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index d5c160b789e3..5ef494e3a70f 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -2,3 +2,4 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ setup.o iommu.o rtas-fw.o ras.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_IBMVIO) += vio.o +obj-$(CONFIG_XICS) += xics.o diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 7e7e556e6b48..10cb0f2d9b5b 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -59,7 +59,7 @@ #include #include #include -#include +#include "xics.h" #include #include #include diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index ae1bd270f308..9c9458ddfc25 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include "xics.h" #include #include #include diff --git a/arch/ppc64/kernel/xics.c b/arch/powerpc/platforms/pseries/xics.c similarity index 98% rename from arch/ppc64/kernel/xics.c rename to arch/powerpc/platforms/pseries/xics.c index a32207dcf2e3..c72c86f05cb6 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -1,5 +1,5 @@ -/* - * arch/ppc64/kernel/xics.c +/* + * arch/powerpc/platforms/pseries/xics.c * * Copyright 2000 IBM Corporation. * @@ -25,11 +25,12 @@ #include #include #include -#include #include #include #include +#include "xics.h" + static unsigned int xics_startup(unsigned int irq); static void xics_enable_irq(unsigned int irq); static void xics_disable_irq(unsigned int irq); @@ -61,7 +62,7 @@ static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); /* Want a priority other than 0. Various HW issues require this. */ #define DEFAULT_PRIORITY 5 -/* +/* * Mark IPIs as higher priority so we can take them inside interrupts that * arent marked SA_INTERRUPT */ @@ -168,11 +169,11 @@ static inline long plpar_xirr(unsigned long *xirr_ret) static int pSeriesLP_xirr_info_get(int n_cpu) { unsigned long lpar_rc; - unsigned long return_value; + unsigned long return_value; lpar_rc = plpar_xirr(&return_value); if (lpar_rc != H_Success) - panic(" bad return code xirr - rc = %lx \n", lpar_rc); + panic(" bad return code xirr - rc = %lx \n", lpar_rc); return (int)return_value; } @@ -184,7 +185,7 @@ static void pSeriesLP_xirr_info_set(int n_cpu, int value) lpar_rc = plpar_eoi(val64); if (lpar_rc != H_Success) panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc, - val64); + val64); } void pSeriesLP_cppr_info(int n_cpu, u8 value) @@ -193,7 +194,7 @@ void pSeriesLP_cppr_info(int n_cpu, u8 value) lpar_rc = plpar_cppr(value); if (lpar_rc != H_Success) - panic("bad return code cppr - rc = %lx\n", lpar_rc); + panic("bad return code cppr - rc = %lx\n", lpar_rc); } static void pSeriesLP_qirr_info(int n_cpu , u8 value) @@ -202,7 +203,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value) lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value); if (lpar_rc != H_Success) - panic("bad return code qirr - rc = %lx\n", lpar_rc); + panic("bad return code qirr - rc = %lx\n", lpar_rc); } xics_ops pSeriesLP_ops = { @@ -461,7 +462,7 @@ void xics_init_IRQ(void) struct xics_interrupt_node { unsigned long addr; unsigned long size; - } intnodes[NR_CPUS]; + } intnodes[NR_CPUS]; ppc64_boot_msg(0x20, "XICS Init"); @@ -486,7 +487,7 @@ void xics_init_IRQ(void) ireg = (uint *)get_property(np, "reg", &ilen); if (!ireg) panic("xics_init_IRQ: can't find interrupt reg property"); - + while (ilen) { intnodes[indx].addr = (unsigned long)*ireg++ << 32; ilen -= sizeof(uint); @@ -554,7 +555,7 @@ void xics_init_IRQ(void) continue; hard_id = get_hard_smp_processor_id(i); - xics_per_cpu[i] = ioremap(intnodes[hard_id].addr, + xics_per_cpu[i] = ioremap(intnodes[hard_id].addr, intnodes[hard_id].size); } #else diff --git a/include/asm-ppc64/xics.h b/arch/powerpc/platforms/pseries/xics.h similarity index 84% rename from include/asm-ppc64/xics.h rename to arch/powerpc/platforms/pseries/xics.h index 1092af55d707..e14c70868f1d 100644 --- a/include/asm-ppc64/xics.h +++ b/arch/powerpc/platforms/pseries/xics.h @@ -1,5 +1,5 @@ -/* - * arch/ppc64/kernel/xics.h +/* + * arch/powerpc/platforms/pseries/xics.h * * Copyright 2000 IBM Corporation. * @@ -9,8 +9,8 @@ * 2 of the License, or (at your option) any later version. */ -#ifndef _PPC64_KERNEL_XICS_H -#define _PPC64_KERNEL_XICS_H +#ifndef _POWERPC_KERNEL_XICS_H +#define _POWERPC_KERNEL_XICS_H #include @@ -31,4 +31,4 @@ struct xics_ipi_struct { extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; -#endif /* _PPC64_KERNEL_XICS_H */ +#endif /* _POWERPC_KERNEL_XICS_H */ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index a20a305b825d..3cf7f3dab511 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -53,8 +53,6 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o endif obj-$(CONFIG_HVCS) += hvcserver.o -obj-$(CONFIG_XICS) += xics.o - obj-$(CONFIG_PPC_PMAC) += udbg_scc.o obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ From 7fca0aa489c82bef85514b5447f6a0be81543115 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 10:20:25 +0100 Subject: [PATCH 0527/1940] [ARM] 1/4: Move include of asm/hardware.h to asm-arm/arch-*/io.h Including asm/hardware.h into asm/io.h can cause #define clashes between platform specific definitions and driver local definitions. Signed-off-by: Russell King --- include/asm-arm/arch-aaec2000/io.h | 2 ++ include/asm-arm/arch-cl7500/io.h | 2 ++ include/asm-arm/arch-clps711x/io.h | 2 ++ include/asm-arm/arch-ebsa110/io.h | 2 ++ include/asm-arm/arch-ebsa285/io.h | 2 ++ include/asm-arm/arch-epxa10db/io.h | 2 ++ include/asm-arm/arch-h720x/io.h | 2 +- include/asm-arm/arch-imx/io.h | 2 ++ include/asm-arm/arch-integrator/io.h | 2 ++ include/asm-arm/arch-iop3xx/io.h | 2 ++ include/asm-arm/arch-ixp2000/io.h | 2 ++ include/asm-arm/arch-l7200/io.h | 2 +- include/asm-arm/arch-lh7a40x/io.h | 2 ++ include/asm-arm/arch-omap/io.h | 2 ++ include/asm-arm/arch-pxa/io.h | 2 ++ include/asm-arm/arch-rpc/io.h | 2 ++ include/asm-arm/arch-s3c2410/io.h | 2 ++ include/asm-arm/arch-sa1100/io.h | 2 ++ include/asm-arm/arch-shark/io.h | 2 ++ include/asm-arm/arch-versatile/io.h | 2 ++ include/asm-arm/io.h | 1 - 21 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h index c58a8d10425a..8d67907fd4f0 100644 --- a/include/asm-arm/arch-aaec2000/io.h +++ b/include/asm-arm/arch-aaec2000/io.h @@ -6,6 +6,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-cl7500/io.h b/include/asm-arm/arch-cl7500/io.h index f0113bc75630..89a33287f4fe 100644 --- a/include/asm-arm/arch-cl7500/io.h +++ b/include/asm-arm/arch-cl7500/io.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-clps711x/io.h b/include/asm-arm/arch-clps711x/io.h index 14d7e8da5453..62613b0e2d96 100644 --- a/include/asm-arm/arch-clps711x/io.h +++ b/include/asm-arm/arch-clps711x/io.h @@ -20,6 +20,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff #define __io(a) ((void __iomem *)(a)) diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h index 68e04c0bb3f7..ecf433634246 100644 --- a/include/asm-arm/arch-ebsa110/io.h +++ b/include/asm-arm/arch-ebsa110/io.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffff u8 __inb8(unsigned int port); diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h index 70576b17f922..776f9d377057 100644 --- a/include/asm-arm/arch-ebsa285/io.h +++ b/include/asm-arm/arch-ebsa285/io.h @@ -14,6 +14,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffff /* diff --git a/include/asm-arm/arch-epxa10db/io.h b/include/asm-arm/arch-epxa10db/io.h index 1f0afa257621..9fe100c9d6be 100644 --- a/include/asm-arm/arch-epxa10db/io.h +++ b/include/asm-arm/arch-epxa10db/io.h @@ -20,6 +20,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffff diff --git a/include/asm-arm/arch-h720x/io.h b/include/asm-arm/arch-h720x/io.h index 68814828c9a7..d3ccfd8172b7 100644 --- a/include/asm-arm/arch-h720x/io.h +++ b/include/asm-arm/arch-h720x/io.h @@ -14,7 +14,7 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include +#include #define IO_SPACE_LIMIT 0xffffffff diff --git a/include/asm-arm/arch-imx/io.h b/include/asm-arm/arch-imx/io.h index 28a4cca6a4cb..b191cdd05576 100644 --- a/include/asm-arm/arch-imx/io.h +++ b/include/asm-arm/arch-imx/io.h @@ -20,6 +20,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff #define __io(a) ((void __iomem *)(a)) diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h index fbea8be67d26..1329a731160d 100644 --- a/include/asm-arm/arch-integrator/io.h +++ b/include/asm-arm/arch-integrator/io.h @@ -20,6 +20,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffff #define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a))) diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h index 2761dfd8694d..f39046a6ab14 100644 --- a/include/asm-arm/arch-iop3xx/io.h +++ b/include/asm-arm/arch-iop3xx/io.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff #define __io(p) ((void __iomem *)(p)) diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index 3241cd6f0778..7fbcdf9931ee 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/include/asm-arm/arch-ixp2000/io.h @@ -15,6 +15,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff #define __mem_pci(a) (a) diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h index fc012a39e2cb..cab8ad0adf09 100644 --- a/include/asm-arm/arch-l7200/io.h +++ b/include/asm-arm/arch-l7200/io.h @@ -10,7 +10,7 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include +#include #define IO_SPACE_LIMIT 0xffffffff diff --git a/include/asm-arm/arch-lh7a40x/io.h b/include/asm-arm/arch-lh7a40x/io.h index c13bdd9add92..bbcd4335f441 100644 --- a/include/asm-arm/arch-lh7a40x/io.h +++ b/include/asm-arm/arch-lh7a40x/io.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARCH_IO_H #define __ASM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* No ISA or PCI bus on this machine. */ diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h index 11fbf629bf75..3d5bcd545082 100644 --- a/include/asm-arm/arch-omap/io.h +++ b/include/asm-arm/arch-omap/io.h @@ -34,6 +34,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-pxa/io.h b/include/asm-arm/arch-pxa/io.h index c3bdbe44e21f..eb2dd58d397f 100644 --- a/include/asm-arm/arch-pxa/io.h +++ b/include/asm-arm/arch-pxa/io.h @@ -6,6 +6,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h index 24453c405a87..b4da08d7a336 100644 --- a/include/asm-arm/arch-rpc/io.h +++ b/include/asm-arm/arch-rpc/io.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-s3c2410/io.h b/include/asm-arm/arch-s3c2410/io.h index 4bf272ed9add..16fbc8afffd9 100644 --- a/include/asm-arm/arch-s3c2410/io.h +++ b/include/asm-arm/arch-s3c2410/io.h @@ -15,6 +15,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h index 7d969ffbd3bb..9c8f588f35db 100644 --- a/include/asm-arm/arch-sa1100/io.h +++ b/include/asm-arm/arch-sa1100/io.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h index 5e6ed0038b2b..87ffa27f2962 100644 --- a/include/asm-arm/arch-shark/io.h +++ b/include/asm-arm/arch-shark/io.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h index 47e904cf25c7..c2eed7f04b78 100644 --- a/include/asm-arm/arch-versatile/io.h +++ b/include/asm-arm/arch-versatile/io.h @@ -20,6 +20,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xffffffff static inline void __iomem *__io(unsigned long addr) diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 5c4ae8f5dbb0..2e6799632f12 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -26,7 +26,6 @@ #include #include #include -#include /* * ISA I/O bus memory addresses are 1:1 with the physical address. From 766529fa2c95e2006ad4c4485c4cde0912d21f12 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 10:29:21 +0100 Subject: [PATCH 0528/1940] [ARM] 2/4: Remove asm/hardware.h from asm-arm/arch-ebsa110/io.h EBSA110 only requires hardware.h to be included for a couple of files. Move the include there. Signed-off-by: Russell King --- arch/arm/mach-ebsa110/io.c | 1 + drivers/net/arm/am79c961a.c | 1 + include/asm-arm/arch-ebsa110/io.h | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index ef7eb5dc91bd..c648bfb676a1 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -24,6 +24,7 @@ #include #include +#include #include #include diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index c56d86d371a9..3d50e953faaa 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -29,6 +29,7 @@ #include #include +#include #include #define TX_BUFFERS 15 diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h index ecf433634246..68e04c0bb3f7 100644 --- a/include/asm-arm/arch-ebsa110/io.h +++ b/include/asm-arm/arch-ebsa110/io.h @@ -13,8 +13,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include - #define IO_SPACE_LIMIT 0xffff u8 __inb8(unsigned int port); From d73e0c99f5c45e7b86d38725a4ff49f6746f5353 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 22:45:25 +1000 Subject: [PATCH 0529/1940] powerpc: Rename asm offset TRAP to _TRAP for 32-bit ... for consistency with 64-bit. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/asm-offsets.c | 3 +-- arch/powerpc/kernel/entry_32.S | 44 +++++++++++++++---------------- arch/powerpc/kernel/head_32.S | 2 +- arch/powerpc/kernel/head_4xx.S | 2 +- arch/powerpc/kernel/head_8xx.S | 2 +- 5 files changed, 26 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 710336a9f0fd..330cd783206f 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -209,6 +209,7 @@ int main(void) DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); + DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); #ifndef CONFIG_PPC64 DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq)); /* @@ -219,9 +220,7 @@ int main(void) */ DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); - DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); #else /* CONFIG_PPC64 */ - DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe)); /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */ diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 960da7bea043..2e99ae41723c 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -278,7 +278,7 @@ ret_from_fork: syscall_dotrace: SAVE_NVGPRS(r1) li r0,0xc00 - stw r0,TRAP(r1) + stw r0,_TRAP(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_enter lwz r0,GPR0(r1) /* Restore original registers */ @@ -299,12 +299,12 @@ syscall_exit_work: ori r10,r10,MSR_EE SYNC MTMSRD(r10) /* re-enable interrupts */ - lwz r4,TRAP(r1) + lwz r4,_TRAP(r1) andi. r4,r4,1 beq 4f SAVE_NVGPRS(r1) li r4,0xc00 - stw r4,TRAP(r1) + stw r4,_TRAP(r1) 4: addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_leave @@ -410,49 +410,49 @@ show_syscalls_task: .globl ppc_sigsuspend ppc_sigsuspend: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,TRAP(r1) /* register set saved */ + stw r0,_TRAP(r1) /* register set saved */ b sys_sigsuspend .globl ppc_rt_sigsuspend ppc_rt_sigsuspend: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 - stw r0,TRAP(r1) + stw r0,_TRAP(r1) b sys_rt_sigsuspend .globl ppc_fork ppc_fork: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,TRAP(r1) /* register set saved */ + stw r0,_TRAP(r1) /* register set saved */ b sys_fork .globl ppc_vfork ppc_vfork: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,TRAP(r1) /* register set saved */ + stw r0,_TRAP(r1) /* register set saved */ b sys_vfork .globl ppc_clone ppc_clone: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,TRAP(r1) /* register set saved */ + stw r0,_TRAP(r1) /* register set saved */ b sys_clone .globl ppc_swapcontext ppc_swapcontext: SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,TRAP(r1) /* register set saved */ + stw r0,_TRAP(r1) /* register set saved */ b sys_swapcontext /* @@ -469,9 +469,9 @@ handle_page_fault: cmpwi r3,0 beq+ ret_from_except SAVE_NVGPRS(r1) - lwz r0,TRAP(r1) + lwz r0,_TRAP(r1) clrrwi r0,r0,1 - stw r0,TRAP(r1) + stw r0,_TRAP(r1) mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD lwz r4,_DAR(r1) @@ -617,7 +617,7 @@ BEGIN_FTR_SECTION b 2b END_FTR_SECTION_IFSET(CPU_FTR_601) li r10,-1 - stw r10,TRAP(r11) + stw r10,_TRAP(r11) addi r3,r1,STACK_FRAME_OVERHEAD lis r10,MSR_KERNEL@h ori r10,r10,MSR_KERNEL@l @@ -899,12 +899,12 @@ do_user_signal: /* r10 contains MSR_KERNEL here */ SYNC MTMSRD(r10) /* hard-enable interrupts */ /* save r13-r31 in the exception frame, if not already done */ - lwz r3,TRAP(r1) + lwz r3,_TRAP(r1) andi. r0,r3,1 beq 2f SAVE_NVGPRS(r1) rlwinm r3,r3,0,0,30 - stw r3,TRAP(r1) + stw r3,_TRAP(r1) 2: li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD bl do_signal @@ -936,12 +936,12 @@ nonrecoverable: BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_601) - lwz r3,TRAP(r1) + lwz r3,_TRAP(r1) andi. r0,r3,1 beq 4f SAVE_NVGPRS(r1) rlwinm r3,r3,0,0,30 - stw r3,TRAP(r1) + stw r3,_TRAP(r1) 4: addi r3,r1,STACK_FRAME_OVERHEAD bl nonrecoverable_exception /* shouldn't return */ diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index f8673f7b2b2d..600ea19d08b5 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -294,7 +294,7 @@ label: \ #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \ li r10,trap; \ - stw r10,TRAP(r11); \ + stw r10,_TRAP(r11); \ li r10,MSR_KERNEL; \ copyee(r10, r9); \ bl tfer; \ diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S index 10c261c67021..2590e97f5539 100644 --- a/arch/powerpc/kernel/head_4xx.S +++ b/arch/powerpc/kernel/head_4xx.S @@ -214,7 +214,7 @@ label: #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ li r10,trap; \ - stw r10,TRAP(r11); \ + stw r10,_TRAP(r11); \ lis r10,msr@h; \ ori r10,r10,msr@l; \ copyee(r10, r9); \ diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index de0978742221..bc6d1ac55235 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -175,7 +175,7 @@ label: \ #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \ li r10,trap; \ - stw r10,TRAP(r11); \ + stw r10,_TRAP(r11); \ li r10,MSR_KERNEL; \ copyee(r10, r9); \ bl tfer; \ From c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 22:48:08 +1000 Subject: [PATCH 0530/1940] powerpc: Make single-stepping emulation (mostly) usable on 32-bit The sc instruction emulation can't be done the same way on 32-bit as 64-bit yet, but this should work OK. Signed-off-by: Paul Mackerras --- arch/powerpc/lib/sstep.c | 17 +++++++++++++++++ include/asm-powerpc/reg.h | 8 ++++++++ include/{asm-ppc64 => asm-powerpc}/sstep.h | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) rename include/{asm-ppc64 => asm-powerpc}/sstep.h (85%) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index e79123d1485c..666c2aa55016 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -10,13 +10,18 @@ */ #include #include +#include #include #include extern char system_call_common[]; +#ifdef CONFIG_PPC64 /* Bits in SRR1 that are copied from MSR */ #define MSR_MASK 0xffffffff87c0ffff +#else +#define MSR_MASK 0x87c0ffff +#endif /* * Determine whether a conditional branch instruction would branch. @@ -66,6 +71,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) if (branch_taken(instr, regs)) regs->nip = imm; return 1; +#ifdef CONFIG_PPC64 case 17: /* sc */ /* * N.B. this uses knowledge about how the syscall @@ -79,6 +85,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) regs->nip = (unsigned long) &system_call_common; regs->msr = MSR_KERNEL; return 1; +#endif case 18: /* b */ imm = instr & 0x03fffffc; if (imm & 0x02000000) @@ -121,6 +128,15 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) if ((regs->msr & MSR_SF) == 0) regs->nip &= 0xffffffffUL; return 1; + case 0x124: /* mtmsr */ + imm = regs->gpr[rd]; + if ((imm & MSR_RI) == 0) + /* can't step mtmsr that would clear MSR_RI */ + return -1; + regs->msr = imm; + regs->nip += 4; + return 1; +#ifdef CONFIG_PPC64 case 0x164: /* mtmsrd */ /* only MSR_EE and MSR_RI get changed if bit 15 set */ /* mtmsrd doesn't change MSR_HV and MSR_ME */ @@ -135,6 +151,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) if ((imm & MSR_SF) == 0) regs->nip &= 0xffffffffUL; return 1; +#endif } } return 0; diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 68058d72d8da..bfb45a4523d3 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -51,9 +51,17 @@ #define __MASK(X) (1UL<<(X)) #endif +#ifdef CONFIG_PPC64 #define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ #define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ #define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ +#else +/* so tests for these bits fail on 32-bit */ +#define MSR_SF 0 +#define MSR_ISF 0 +#define MSR_HV 0 +#endif + #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ #define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ diff --git a/include/asm-ppc64/sstep.h b/include/asm-powerpc/sstep.h similarity index 85% rename from include/asm-ppc64/sstep.h rename to include/asm-powerpc/sstep.h index 4a68db50ee6f..630a9889c07c 100644 --- a/include/asm-ppc64/sstep.h +++ b/include/asm-powerpc/sstep.h @@ -16,8 +16,10 @@ struct pt_regs; * we don't allow putting a breakpoint on an mtmsrd instruction. * Similarly we don't allow breakpoints on rfid instructions. * These macros tell us if an instruction is a mtmsrd or rfid. + * Note that IS_MTMSRD returns true for both an mtmsr (32-bit) + * and an mtmsrd (64-bit). */ -#define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164) +#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124) #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) /* Emulate instructions that cause a transfer of control. */ From f78541dcec327b0c46b150ee7d727f3db80275c4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 28 Oct 2005 22:53:37 +1000 Subject: [PATCH 0531/1940] powerpc: Merge xmon The merged version follows the ppc64 version pretty closely mostly, and in fact ARCH=ppc64 now uses the arch/powerpc/xmon version. The main difference for ppc64 is that the 'p' command to call show_state (which was always pretty dodgy) has been replaced by the ppc32 'p' command, which calls a given procedure (so in fact the old 'p' command behaviour can be achieved with 'p $show_state'). Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 2 +- arch/powerpc/kernel/head_32.S | 3 + arch/powerpc/kernel/ppc_ksyms.c | 5 - arch/powerpc/kernel/setup_32.c | 6 +- arch/powerpc/kernel/setup_64.c | 1 + arch/powerpc/lib/Makefile | 2 + arch/powerpc/xmon/Makefile | 11 + arch/{ppc64 => powerpc}/xmon/ansidecl.h | 0 arch/{ppc64 => powerpc}/xmon/nonstdio.h | 0 arch/{ppc64 => powerpc}/xmon/ppc-dis.c | 0 arch/{ppc64 => powerpc}/xmon/ppc-opc.c | 0 arch/{ppc64 => powerpc}/xmon/ppc.h | 0 arch/powerpc/xmon/setjmp.S | 135 ++++ arch/powerpc/xmon/start_32.c | 624 ++++++++++++++++++ .../xmon/start.c => powerpc/xmon/start_64.c} | 0 arch/powerpc/xmon/start_8xx.c | 287 ++++++++ arch/{ppc64 => powerpc}/xmon/subr_prf.c | 11 +- arch/{ppc64 => powerpc}/xmon/xmon.c | 394 +++++------ arch/ppc64/Makefile | 2 +- arch/ppc64/xmon/Makefile | 5 - arch/ppc64/xmon/setjmp.S | 73 -- include/asm-powerpc/ppc_asm.h | 8 + include/asm-powerpc/reg.h | 1 + include/asm-powerpc/xmon.h | 2 +- 24 files changed, 1289 insertions(+), 283 deletions(-) create mode 100644 arch/powerpc/xmon/Makefile rename arch/{ppc64 => powerpc}/xmon/ansidecl.h (100%) rename arch/{ppc64 => powerpc}/xmon/nonstdio.h (100%) rename arch/{ppc64 => powerpc}/xmon/ppc-dis.c (100%) rename arch/{ppc64 => powerpc}/xmon/ppc-opc.c (100%) rename arch/{ppc64 => powerpc}/xmon/ppc.h (100%) create mode 100644 arch/powerpc/xmon/setjmp.S create mode 100644 arch/powerpc/xmon/start_32.c rename arch/{ppc64/xmon/start.c => powerpc/xmon/start_64.c} (100%) create mode 100644 arch/powerpc/xmon/start_8xx.c rename arch/{ppc64 => powerpc}/xmon/subr_prf.c (84%) rename arch/{ppc64 => powerpc}/xmon/xmon.c (90%) delete mode 100644 arch/ppc64/xmon/Makefile delete mode 100644 arch/ppc64/xmon/setjmp.S diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index dedf1219761a..29cda0732703 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -131,7 +131,7 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/sysdev/ \ arch/powerpc/platforms/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ -#core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 600ea19d08b5..b102e3a2415e 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -271,6 +271,9 @@ __secondary_hold_acknowledge: li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ MTMSRD(r10); /* (except for mach check in rtas) */ \ stw r0,GPR0(r11); \ + lis r10,0x7265; /* put exception frame marker */ \ + addi r10,r10,0x6773; \ + stw r10,8(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 5f3a12bb8961..8bc540337ba0 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -44,7 +44,6 @@ #include #include #include -#include #ifdef CONFIG_8xx #include @@ -238,10 +237,6 @@ EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(cacheable_memcpy); #endif -#ifdef CONFIG_XMON -EXPORT_SYMBOL(xmon); -EXPORT_SYMBOL(xmon_printf); -#endif EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 7c99e6b8c76c..9680ae99b084 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -302,8 +302,10 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_XMON xmon_map_scc(); - if (strstr(cmd_line, "xmon")) - xmon(NULL); + if (strstr(cmd_line, "xmon")) { + xmon_init(1); + debugger(NULL); + } #endif /* CONFIG_XMON */ if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 950e6f0fea98..681537f8ea10 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -59,6 +59,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 0115bf96751c..e6b2be3bcec1 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -11,6 +11,8 @@ obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ memcpy_64.o usercopy_64.o mem_64.o obj-$(CONFIG_PPC_ISERIES) += e2a.o +obj-$(CONFIG_XMON) += sstep.o + ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o obj-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile new file mode 100644 index 000000000000..79a784f0e7a9 --- /dev/null +++ b/arch/powerpc/xmon/Makefile @@ -0,0 +1,11 @@ +# Makefile for xmon + +ifdef CONFIG_PPC64 +EXTRA_CFLAGS += -mno-minimal-toc +endif + +obj-$(CONFIG_8xx) += start_8xx.o +obj-$(CONFIG_6xx) += start_32.o +obj-$(CONFIG_4xx) += start_32.o +obj-$(CONFIG_PPC64) += start_64.o +obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o diff --git a/arch/ppc64/xmon/ansidecl.h b/arch/powerpc/xmon/ansidecl.h similarity index 100% rename from arch/ppc64/xmon/ansidecl.h rename to arch/powerpc/xmon/ansidecl.h diff --git a/arch/ppc64/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h similarity index 100% rename from arch/ppc64/xmon/nonstdio.h rename to arch/powerpc/xmon/nonstdio.h diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c similarity index 100% rename from arch/ppc64/xmon/ppc-dis.c rename to arch/powerpc/xmon/ppc-dis.c diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c similarity index 100% rename from arch/ppc64/xmon/ppc-opc.c rename to arch/powerpc/xmon/ppc-opc.c diff --git a/arch/ppc64/xmon/ppc.h b/arch/powerpc/xmon/ppc.h similarity index 100% rename from arch/ppc64/xmon/ppc.h rename to arch/powerpc/xmon/ppc.h diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S new file mode 100644 index 000000000000..f8e40dfd2bff --- /dev/null +++ b/arch/powerpc/xmon/setjmp.S @@ -0,0 +1,135 @@ +/* + * Copyright (C) 1996 Paul Mackerras. + * + * 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. + * + * NOTE: assert(sizeof(buf) > 23 * sizeof(long)) + */ +#include +#include +#include + +_GLOBAL(xmon_setjmp) + mflr r0 + STL r0,0(r3) + STL r1,SZL(r3) + STL r2,2*SZL(r3) + mfcr r0 + STL r0,3*SZL(r3) + STL r13,4*SZL(r3) + STL r14,5*SZL(r3) + STL r15,6*SZL(r3) + STL r16,7*SZL(r3) + STL r17,8*SZL(r3) + STL r18,9*SZL(r3) + STL r19,10*SZL(r3) + STL r20,11*SZL(r3) + STL r21,12*SZL(r3) + STL r22,13*SZL(r3) + STL r23,14*SZL(r3) + STL r24,15*SZL(r3) + STL r25,16*SZL(r3) + STL r26,17*SZL(r3) + STL r27,18*SZL(r3) + STL r28,19*SZL(r3) + STL r29,20*SZL(r3) + STL r30,21*SZL(r3) + STL r31,22*SZL(r3) + li r3,0 + blr + +_GLOBAL(xmon_longjmp) + CMPI r4,0 + bne 1f + li r4,1 +1: LDL r13,4*SZL(r3) + LDL r14,5*SZL(r3) + LDL r15,6*SZL(r3) + LDL r16,7*SZL(r3) + LDL r17,8*SZL(r3) + LDL r18,9*SZL(r3) + LDL r19,10*SZL(r3) + LDL r20,11*SZL(r3) + LDL r21,12*SZL(r3) + LDL r22,13*SZL(r3) + LDL r23,14*SZL(r3) + LDL r24,15*SZL(r3) + LDL r25,16*SZL(r3) + LDL r26,17*SZL(r3) + LDL r27,18*SZL(r3) + LDL r28,19*SZL(r3) + LDL r29,20*SZL(r3) + LDL r30,21*SZL(r3) + LDL r31,22*SZL(r3) + LDL r0,3*SZL(r3) + mtcrf 0x38,r0 + LDL r0,0(r3) + LDL r1,SZL(r3) + LDL r2,2*SZL(r3) + mtlr r0 + mr r3,r4 + blr + +/* + * Grab the register values as they are now. + * This won't do a particularily good job because we really + * want our caller's caller's registers, and our caller has + * already executed its prologue. + * ToDo: We could reach back into the caller's save area to do + * a better job of representing the caller's state (note that + * that will be different for 32-bit and 64-bit, because of the + * different ABIs, though). + */ +_GLOBAL(xmon_save_regs) + STL r0,0*SZL(r3) + STL r2,2*SZL(r3) + STL r3,3*SZL(r3) + STL r4,4*SZL(r3) + STL r5,5*SZL(r3) + STL r6,6*SZL(r3) + STL r7,7*SZL(r3) + STL r8,8*SZL(r3) + STL r9,9*SZL(r3) + STL r10,10*SZL(r3) + STL r11,11*SZL(r3) + STL r12,12*SZL(r3) + STL r13,13*SZL(r3) + STL r14,14*SZL(r3) + STL r15,15*SZL(r3) + STL r16,16*SZL(r3) + STL r17,17*SZL(r3) + STL r18,18*SZL(r3) + STL r19,19*SZL(r3) + STL r20,20*SZL(r3) + STL r21,21*SZL(r3) + STL r22,22*SZL(r3) + STL r23,23*SZL(r3) + STL r24,24*SZL(r3) + STL r25,25*SZL(r3) + STL r26,26*SZL(r3) + STL r27,27*SZL(r3) + STL r28,28*SZL(r3) + STL r29,29*SZL(r3) + STL r30,30*SZL(r3) + STL r31,31*SZL(r3) + /* go up one stack frame for SP */ + LDL r4,0(r1) + STL r4,1*SZL(r3) + /* get caller's LR */ + LDL r0,LRSAVE(r4) + STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) + STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) + mfmsr r0 + STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) + mfctr r0 + STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) + mfxer r0 + STL r0,_XER-STACK_FRAME_OVERHEAD(r3) + mfcr r0 + STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) + li r0,0 + STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) + blr diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c new file mode 100644 index 000000000000..69b658c0f760 --- /dev/null +++ b/arch/powerpc/xmon/start_32.c @@ -0,0 +1,624 @@ +/* + * Copyright (C) 1996 Paul Mackerras. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile unsigned char __iomem *sccc, *sccd; +unsigned int TXRDY, RXRDY, DLAB; +static int xmon_expect(const char *str, unsigned int timeout); + +static int use_serial; +static int use_screen; +static int via_modem; +static int xmon_use_sccb; +static struct device_node *channel_node; + +#define TB_SPEED 25000000 + +static inline unsigned int readtb(void) +{ + unsigned int ret; + + asm volatile("mftb %0" : "=r" (ret) :); + return ret; +} + +void buf_access(void) +{ + if (DLAB) + sccd[3] &= ~DLAB; /* reset DLAB */ +} + +extern int adb_init(void); + +#ifdef CONFIG_PPC_CHRP +/* + * This looks in the "ranges" property for the primary PCI host bridge + * to find the physical address of the start of PCI/ISA I/O space. + * It is basically a cut-down version of pci_process_bridge_OF_ranges. + */ +static unsigned long chrp_find_phys_io_base(void) +{ + struct device_node *node; + unsigned int *ranges; + unsigned long base = CHRP_ISA_IO_BASE; + int rlen = 0; + int np; + + node = find_devices("isa"); + if (node != NULL) { + node = node->parent; + if (node == NULL || node->type == NULL + || strcmp(node->type, "pci") != 0) + node = NULL; + } + if (node == NULL) + node = find_devices("pci"); + if (node == NULL) + return base; + + ranges = (unsigned int *) get_property(node, "ranges", &rlen); + np = prom_n_addr_cells(node) + 5; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { + /* I/O space starting at 0, grab the phys base */ + base = ranges[np - 3]; + break; + } + ranges += np; + } + return base; +} +#endif /* CONFIG_PPC_CHRP */ + +#ifdef CONFIG_MAGIC_SYSRQ +static void sysrq_handle_xmon(int key, struct pt_regs *regs, + struct tty_struct *tty) +{ + xmon(regs); +} + +static struct sysrq_key_op sysrq_xmon_op = +{ + .handler = sysrq_handle_xmon, + .help_msg = "Xmon", + .action_msg = "Entering xmon", +}; +#endif + +void +xmon_map_scc(void) +{ +#ifdef CONFIG_PPC_MULTIPLATFORM + volatile unsigned char __iomem *base; + + if (_machine == _MACH_Pmac) { + struct device_node *np; + unsigned long addr; +#ifdef CONFIG_BOOTX_TEXT + if (!use_screen && !use_serial + && !machine_is_compatible("iMac")) { + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (np = find_devices("keyboard"); np; np = np->next) + if (np->parent && np->parent->type + && strcmp(np->parent->type, "adb") == 0) + break; + + /* needs to be hacked if xmon_printk is to be used + from within find_via_pmu() */ +#ifdef CONFIG_ADB_PMU + if (np != NULL && boot_text_mapped && find_via_pmu()) + use_screen = 1; +#endif +#ifdef CONFIG_ADB_CUDA + if (np != NULL && boot_text_mapped && find_via_cuda()) + use_screen = 1; +#endif + } + if (!use_screen && (np = find_devices("escc")) != NULL) { + /* + * look for the device node for the serial port + * we're using and see if it says it has a modem + */ + char *name = xmon_use_sccb? "ch-b": "ch-a"; + char *slots; + int l; + + np = np->child; + while (np != NULL && strcmp(np->name, name) != 0) + np = np->sibling; + if (np != NULL) { + /* XXX should parse this properly */ + channel_node = np; + slots = get_property(np, "slot-names", &l); + if (slots != NULL && l >= 10 + && strcmp(slots+4, "Modem") == 0) + via_modem = 1; + } + } + btext_drawstring("xmon uses "); + if (use_screen) + btext_drawstring("screen and keyboard\n"); + else { + if (via_modem) + btext_drawstring("modem on "); + btext_drawstring(xmon_use_sccb? "printer": "modem"); + btext_drawstring(" port\n"); + } + +#endif /* CONFIG_BOOTX_TEXT */ + +#ifdef CHRP_ESCC + addr = 0xc1013020; +#else + addr = 0xf3013020; +#endif + TXRDY = 4; + RXRDY = 1; + + np = find_devices("mac-io"); + if (np && np->n_addrs) + addr = np->addrs[0].address + 0x13020; + base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); + sccc = base + (addr & ~PAGE_MASK); + sccd = sccc + 0x10; + + } else { + base = (volatile unsigned char *) isa_io_base; + +#ifdef CONFIG_PPC_CHRP + if (_machine == _MACH_chrp) + base = (volatile unsigned char __iomem *) + ioremap(chrp_find_phys_io_base(), 0x1000); +#endif + + sccc = base + 0x3fd; + sccd = base + 0x3f8; + if (xmon_use_sccb) { + sccc -= 0x100; + sccd -= 0x100; + } + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; + } +#elif defined(CONFIG_GEMINI) + /* should already be mapped by the kernel boot */ + sccc = (volatile unsigned char __iomem *) 0xffeffb0d; + sccd = (volatile unsigned char __iomem *) 0xffeffb08; + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; +#elif defined(CONFIG_405GP) + sccc = (volatile unsigned char __iomem *)0xef600305; + sccd = (volatile unsigned char __iomem *)0xef600300; + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; +#endif /* platform */ + + register_sysrq_key('x', &sysrq_xmon_op); +} + +static int scc_initialized = 0; + +void xmon_init_scc(void); +extern void cuda_poll(void); + +static inline void do_poll_adb(void) +{ +#ifdef CONFIG_ADB_PMU + if (sys_ctrler == SYS_CTRLER_PMU) + pmu_poll_adb(); +#endif /* CONFIG_ADB_PMU */ +#ifdef CONFIG_ADB_CUDA + if (sys_ctrler == SYS_CTRLER_CUDA) + cuda_poll(); +#endif /* CONFIG_ADB_CUDA */ +} + +int +xmon_write(void *handle, void *ptr, int nb) +{ + char *p = ptr; + int i, c, ct; + +#ifdef CONFIG_SMP + static unsigned long xmon_write_lock; + int lock_wait = 1000000; + int locked; + + while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) + if (--lock_wait == 0) + break; +#endif + +#ifdef CONFIG_BOOTX_TEXT + if (use_screen) { + /* write it on the screen */ + for (i = 0; i < nb; ++i) + btext_drawchar(*p++); + goto out; + } +#endif + if (!scc_initialized) + xmon_init_scc(); + ct = 0; + for (i = 0; i < nb; ++i) { + while ((*sccc & TXRDY) == 0) + do_poll_adb(); + c = p[i]; + if (c == '\n' && !ct) { + c = '\r'; + ct = 1; + --i; + } else { + ct = 0; + } + buf_access(); + *sccd = c; + eieio(); + } + + out: +#ifdef CONFIG_SMP + if (!locked) + clear_bit(0, &xmon_write_lock); +#endif + return nb; +} + +int xmon_wants_key; +int xmon_adb_keycode; + +#ifdef CONFIG_BOOTX_TEXT +static int xmon_adb_shiftstate; + +static unsigned char xmon_keytab[128] = + "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ + "yt123465=97-80]o" /* 0x10 - 0x1f */ + "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ + "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ + +static unsigned char xmon_shift_keytab[128] = + "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ + "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ + "U{IP\rLJ\"K:|" /* 0x20 - 0x2f */ + "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ + +static int +xmon_get_adb_key(void) +{ + int k, t, on; + + xmon_wants_key = 1; + for (;;) { + xmon_adb_keycode = -1; + t = 0; + on = 0; + do { + if (--t < 0) { + on = 1 - on; + btext_drawchar(on? 0xdb: 0x20); + btext_drawchar('\b'); + t = 200000; + } + do_poll_adb(); + } while (xmon_adb_keycode == -1); + k = xmon_adb_keycode; + if (on) + btext_drawstring(" \b"); + + /* test for shift keys */ + if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { + xmon_adb_shiftstate = (k & 0x80) == 0; + continue; + } + if (k >= 0x80) + continue; /* ignore up transitions */ + k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; + if (k != 0) + break; + } + xmon_wants_key = 0; + return k; +} +#endif /* CONFIG_BOOTX_TEXT */ + +int +xmon_read(void *handle, void *ptr, int nb) +{ + char *p = ptr; + int i; + +#ifdef CONFIG_BOOTX_TEXT + if (use_screen) { + for (i = 0; i < nb; ++i) + *p++ = xmon_get_adb_key(); + return i; + } +#endif + if (!scc_initialized) + xmon_init_scc(); + for (i = 0; i < nb; ++i) { + while ((*sccc & RXRDY) == 0) + do_poll_adb(); + buf_access(); + *p++ = *sccd; + } + return i; +} + +int +xmon_read_poll(void) +{ + if ((*sccc & RXRDY) == 0) { + do_poll_adb(); + return -1; + } + buf_access(); + return *sccd; +} + +static unsigned char scc_inittab[] = { + 13, 0, /* set baud rate divisor */ + 12, 1, + 14, 1, /* baud rate gen enable, src=rtxc */ + 11, 0x50, /* clocks = br gen */ + 5, 0xea, /* tx 8 bits, assert DTR & RTS */ + 4, 0x46, /* x16 clock, 1 stop */ + 3, 0xc1, /* rx enable, 8 bits */ +}; + +void +xmon_init_scc(void) +{ + if ( _machine == _MACH_chrp ) + { + sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ + sccd[0] = 12; eieio(); /* DLL = 9600 baud */ + sccd[1] = 0; eieio(); + sccd[2] = 0; eieio(); /* FCR = 0 */ + sccd[3] = 3; eieio(); /* LCR = 8N1 */ + sccd[1] = 0; eieio(); /* IER = 0 */ + } + else if ( _machine == _MACH_Pmac ) + { + int i, x; + + if (channel_node != 0) + pmac_call_feature( + PMAC_FTR_SCC_ENABLE, + channel_node, + PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); + printk(KERN_INFO "Serial port locked ON by debugger !\n"); + if (via_modem && channel_node != 0) { + unsigned int t0; + + pmac_call_feature( + PMAC_FTR_MODEM_ENABLE, + channel_node, 0, 1); + printk(KERN_INFO "Modem powered up by debugger !\n"); + t0 = readtb(); + while (readtb() - t0 < 3*TB_SPEED) + eieio(); + } + /* use the B channel if requested */ + if (xmon_use_sccb) { + sccc = (volatile unsigned char *) + ((unsigned long)sccc & ~0x20); + sccd = sccc + 0x10; + } + for (i = 20000; i != 0; --i) { + x = *sccc; eieio(); + } + *sccc = 9; eieio(); /* reset A or B side */ + *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); + for (i = 0; i < sizeof(scc_inittab); ++i) { + *sccc = scc_inittab[i]; + eieio(); + } + } + scc_initialized = 1; + if (via_modem) { + for (;;) { + xmon_write(NULL, "ATE1V1\r", 7); + if (xmon_expect("OK", 5)) { + xmon_write(NULL, "ATA\r", 4); + if (xmon_expect("CONNECT", 40)) + break; + } + xmon_write(NULL, "+++", 3); + xmon_expect("OK", 3); + } + } +} + +void *xmon_stdin; +void *xmon_stdout; +void *xmon_stderr; + +int xmon_putc(int c, void *f) +{ + char ch = c; + + if (c == '\n') + xmon_putc('\r', f); + return xmon_write(f, &ch, 1) == 1? c: -1; +} + +int xmon_putchar(int c) +{ + return xmon_putc(c, xmon_stdout); +} + +int xmon_fputs(char *str, void *f) +{ + int n = strlen(str); + + return xmon_write(f, str, n) == n? 0: -1; +} + +int +xmon_readchar(void) +{ + char ch; + + for (;;) { + switch (xmon_read(xmon_stdin, &ch, 1)) { + case 1: + return ch; + case -1: + xmon_printf("read(stdin) returned -1\r\n", 0, 0); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int xmon_expect(const char *str, unsigned int timeout) +{ + int c; + unsigned int t0; + + timeout *= TB_SPEED; + t0 = readtb(); + do { + lineptr = line; + for (;;) { + c = xmon_read_poll(); + if (c == -1) { + if (readtb() - t0 > timeout) + return 0; + continue; + } + if (c == '\n') + break; + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) + *lineptr++ = c; + } + *lineptr = 0; + } while (strstr(line, str) == NULL); + return 1; +} + +int +xmon_getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = xmon_readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + xmon_putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + xmon_putchar('\a'); + else { + xmon_putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +char * +xmon_fgets(char *str, int nb, void *f) +{ + char *p; + int c; + + for (p = str; p < str + nb - 1; ) { + c = xmon_getchar(); + if (c == -1) { + if (p == str) + return NULL; + break; + } + *p++ = c; + if (c == '\n') + break; + } + *p = 0; + return str; +} + +void +xmon_enter(void) +{ +#ifdef CONFIG_ADB_PMU + if (_machine == _MACH_Pmac) { + pmu_suspend(); + } +#endif +} + +void +xmon_leave(void) +{ +#ifdef CONFIG_ADB_PMU + if (_machine == _MACH_Pmac) { + pmu_resume(); + } +#endif +} diff --git a/arch/ppc64/xmon/start.c b/arch/powerpc/xmon/start_64.c similarity index 100% rename from arch/ppc64/xmon/start.c rename to arch/powerpc/xmon/start_64.c diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c new file mode 100644 index 000000000000..a48bd594cf61 --- /dev/null +++ b/arch/powerpc/xmon/start_8xx.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 2000 Dan Malek. + * Quick hack of Paul's code to make XMON work on 8xx processors. Lots + * of assumptions, like the SMC1 is used, it has been initialized by the + * loader at some point, and we can just stuff and suck bytes. + * We rely upon the 8xx uart driver to support us, as the interface + * changes between boot up and operational phases of the kernel. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +extern void xmon_printf(const char *fmt, ...); +extern int xmon_8xx_write(char *str, int nb); +extern int xmon_8xx_read_poll(void); +extern int xmon_8xx_read_char(void); +void prom_drawhex(uint); +void prom_drawstring(const char *str); + +static int use_screen = 1; /* default */ + +#define TB_SPEED 25000000 + +static inline unsigned int readtb(void) +{ + unsigned int ret; + + asm volatile("mftb %0" : "=r" (ret) :); + return ret; +} + +void buf_access(void) +{ +} + +void +xmon_map_scc(void) +{ + + cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); + use_screen = 0; + + prom_drawstring("xmon uses serial port\n"); +} + +static int scc_initialized = 0; + +void xmon_init_scc(void); + +int +xmon_write(void *handle, void *ptr, int nb) +{ + char *p = ptr; + int i, c, ct; + + if (!scc_initialized) + xmon_init_scc(); + + return(xmon_8xx_write(ptr, nb)); +} + +int xmon_wants_key; + +int +xmon_read(void *handle, void *ptr, int nb) +{ + char *p = ptr; + int i; + + if (!scc_initialized) + xmon_init_scc(); + + for (i = 0; i < nb; ++i) { + *p++ = xmon_8xx_read_char(); + } + return i; +} + +int +xmon_read_poll(void) +{ + return(xmon_8xx_read_poll()); +} + +void +xmon_init_scc() +{ + scc_initialized = 1; +} + +#if 0 +extern int (*prom_entry)(void *); + +int +xmon_exit(void) +{ + struct prom_args { + char *service; + } args; + + for (;;) { + args.service = "exit"; + (*prom_entry)(&args); + } +} +#endif + +void *xmon_stdin; +void *xmon_stdout; +void *xmon_stderr; + +void +xmon_init(void) +{ +} + +int +xmon_putc(int c, void *f) +{ + char ch = c; + + if (c == '\n') + xmon_putc('\r', f); + return xmon_write(f, &ch, 1) == 1? c: -1; +} + +int +xmon_putchar(int c) +{ + return xmon_putc(c, xmon_stdout); +} + +int +xmon_fputs(char *str, void *f) +{ + int n = strlen(str); + + return xmon_write(f, str, n) == n? 0: -1; +} + +int +xmon_readchar(void) +{ + char ch; + + for (;;) { + switch (xmon_read(xmon_stdin, &ch, 1)) { + case 1: + return ch; + case -1: + xmon_printf("read(stdin) returned -1\r\n", 0, 0); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +#if 0 +int xmon_expect(const char *str, unsigned int timeout) +{ + int c; + unsigned int t0; + + timeout *= TB_SPEED; + t0 = readtb(); + do { + lineptr = line; + for (;;) { + c = xmon_read_poll(); + if (c == -1) { + if (readtb() - t0 > timeout) + return 0; + continue; + } + if (c == '\n') + break; + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) + *lineptr++ = c; + } + *lineptr = 0; + } while (strstr(line, str) == NULL); + return 1; +} +#endif + +int +xmon_getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = xmon_readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + xmon_putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + xmon_putchar('\a'); + else { + xmon_putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +char * +xmon_fgets(char *str, int nb, void *f) +{ + char *p; + int c; + + for (p = str; p < str + nb - 1; ) { + c = xmon_getchar(); + if (c == -1) { + if (p == str) + return 0; + break; + } + *p++ = c; + if (c == '\n') + break; + } + *p = 0; + return str; +} + +void +prom_drawhex(uint val) +{ + unsigned char buf[10]; + + int i; + for (i = 7; i >= 0; i--) + { + buf[i] = "0123456789abcdef"[val & 0x0f]; + val >>= 4; + } + buf[8] = '\0'; + xmon_fputs(buf, xmon_stdout); +} + +void +prom_drawstring(const char *str) +{ + xmon_fputs(str, xmon_stdout); +} diff --git a/arch/ppc64/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c similarity index 84% rename from arch/ppc64/xmon/subr_prf.c rename to arch/powerpc/xmon/subr_prf.c index 5242bd7d0959..b48738c6dd33 100644 --- a/arch/ppc64/xmon/subr_prf.c +++ b/arch/powerpc/xmon/subr_prf.c @@ -18,13 +18,13 @@ #include #include +#include #include #include "nonstdio.h" extern int xmon_write(void *, void *, int); -void -xmon_vfprintf(void *f, const char *fmt, va_list ap) +void xmon_vfprintf(void *f, const char *fmt, va_list ap) { static char xmon_buf[2048]; int n; @@ -33,8 +33,7 @@ xmon_vfprintf(void *f, const char *fmt, va_list ap) xmon_write(f, xmon_buf, n); } -void -xmon_printf(const char *fmt, ...) +void xmon_printf(const char *fmt, ...) { va_list ap; @@ -42,9 +41,9 @@ xmon_printf(const char *fmt, ...) xmon_vfprintf(stdout, fmt, ap); va_end(ap); } +EXPORT_SYMBOL(xmon_printf); -void -xmon_fprintf(void *f, const char *fmt, ...) +void xmon_fprintf(void *f, const char *fmt, ...) { va_list ap; diff --git a/arch/ppc64/xmon/xmon.c b/arch/powerpc/xmon/xmon.c similarity index 90% rename from arch/ppc64/xmon/xmon.c rename to arch/powerpc/xmon/xmon.c index 74e63a886a69..d0623e0fd8ee 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -17,25 +17,31 @@ #include #include #include +#include #include #include #include #include +#include +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif #include #include #include #include -#include -#include #include #include #include #include + +#ifdef CONFIG_PPC64 #include +#include +#endif #include "nonstdio.h" -#include "privinst.h" #define scanhex xmon_scanhex #define skipbl xmon_skipbl @@ -58,7 +64,7 @@ static unsigned long ncsum = 4096; static int termch; static char tmpstr[128]; -#define JMP_BUF_LEN (184/sizeof(long)) +#define JMP_BUF_LEN 23 static long bus_error_jmp[JMP_BUF_LEN]; static int catch_memory_errors; static long *xmon_fault_jmp[NR_CPUS]; @@ -130,23 +136,36 @@ static void cacheflush(void); static int cpu_cmd(void); static void csum(void); static void bootcmds(void); +static void proccall(void); void dump_segments(void); static void symbol_lookup(void); static void xmon_print_symbol(unsigned long address, const char *mid, const char *after); static const char *getvecname(unsigned long vec); -static void debug_trace(void); - extern int print_insn_powerpc(unsigned long, unsigned long, int); extern void printf(const char *fmt, ...); extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); extern int xmon_putc(int c, void *f); extern int putchar(int ch); + +extern void xmon_enter(void); +extern void xmon_leave(void); + extern int xmon_read_poll(void); -extern int setjmp(long *); -extern void longjmp(long *, int); -extern unsigned long _ASR; +extern long setjmp(long *); +extern void longjmp(long *, long); +extern void xmon_save_regs(struct pt_regs *); + +#ifdef CONFIG_PPC64 +#define REG "%.16lx" +#define REGS_PER_LINE 4 +#define LAST_VOLATILE 13 +#else +#define REG "%.8lx" +#define REGS_PER_LINE 8 +#define LAST_VOLATILE 12 +#endif #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) @@ -186,47 +205,46 @@ Commands:\n\ ml locate a block of memory\n\ mz zero a block of memory\n\ mi show information about memory allocation\n\ - p show the task list\n\ + p call a procedure\n\ r print registers\n\ s single step\n\ S print special registers\n\ t print backtrace\n\ T Enable/Disable PPCDBG flags\n\ x exit monitor and recover\n\ - X exit monitor and dont recover\n\ - u dump segment table or SLB\n\ - ? help\n" - "\ - zr reboot\n\ + X exit monitor and dont recover\n" +#ifdef CONFIG_PPC64 +" u dump segment table or SLB\n" +#endif +#ifdef CONFIG_PPC_STD_MMU_32 +" u dump segment registers\n" +#endif +" ? help\n" +" zr reboot\n\ zh halt\n" ; static struct pt_regs *xmon_regs; -extern inline void sync(void) +static inline void sync(void) { asm volatile("sync; isync"); } -/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs). - A PPC stack frame looks like this: +static inline void store_inst(void *p) +{ + asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); +} - High Address - Back Chain - FP reg save area - GP reg save area - Local var space - Parameter save area (SP+48) - TOC save area (SP+40) - link editor doubleword (SP+32) - compiler doubleword (SP+24) - LR save (SP+16) - CR save (SP+8) - Back Chain (SP+0) +static inline void cflush(void *p) +{ + asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); +} - Note that the LR (ret addr) may not be saved in the current frame if - no functions have been called from the current function. - */ +static inline void cinval(void *p) +{ + asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); +} /* * Disable surveillance (the service processor watchdog function) @@ -310,8 +328,8 @@ int xmon_core(struct pt_regs *regs, int fromipi) unsigned long timeout; #endif - msr = get_msr(); - set_msrd(msr & ~MSR_EE); /* disable interrupts */ + msr = mfmsr(); + mtmsr(msr & ~MSR_EE); /* disable interrupts */ bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) { @@ -487,7 +505,7 @@ int xmon_core(struct pt_regs *regs, int fromipi) insert_cpu_bpts(); - set_msrd(msr); /* restore interrupt enable */ + mtmsr(msr); /* restore interrupt enable */ return cmd != 'X'; } @@ -497,56 +515,23 @@ int xmon(struct pt_regs *excp) struct pt_regs regs; if (excp == NULL) { - /* Ok, grab regs as they are now. - This won't do a particularily good job because the - prologue has already been executed. - ToDo: We could reach back into the callers save - area to do a better job of representing the - caller's state. - */ - asm volatile ("std 0,0(%0)\n\ - std 1,8(%0)\n\ - std 2,16(%0)\n\ - std 3,24(%0)\n\ - std 4,32(%0)\n\ - std 5,40(%0)\n\ - std 6,48(%0)\n\ - std 7,56(%0)\n\ - std 8,64(%0)\n\ - std 9,72(%0)\n\ - std 10,80(%0)\n\ - std 11,88(%0)\n\ - std 12,96(%0)\n\ - std 13,104(%0)\n\ - std 14,112(%0)\n\ - std 15,120(%0)\n\ - std 16,128(%0)\n\ - std 17,136(%0)\n\ - std 18,144(%0)\n\ - std 19,152(%0)\n\ - std 20,160(%0)\n\ - std 21,168(%0)\n\ - std 22,176(%0)\n\ - std 23,184(%0)\n\ - std 24,192(%0)\n\ - std 25,200(%0)\n\ - std 26,208(%0)\n\ - std 27,216(%0)\n\ - std 28,224(%0)\n\ - std 29,232(%0)\n\ - std 30,240(%0)\n\ - std 31,248(%0)" : : "b" (®s)); - - regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2]; - regs.msr = get_msr(); - regs.ctr = get_ctr(); - regs.xer = get_xer(); - regs.ccr = get_cr(); - regs.trap = 0; + xmon_save_regs(®s); excp = ®s; } return xmon_core(excp, 0); } +EXPORT_SYMBOL(xmon); + +irqreturn_t +xmon_irq(int irq, void *d, struct pt_regs *regs) +{ + unsigned long flags; + local_irq_save(flags); + printf("Keyboard interrupt\n"); + xmon(regs); + local_irq_restore(flags); + return IRQ_HANDLED; +} int xmon_bpt(struct pt_regs *regs) { @@ -718,7 +703,7 @@ static void insert_cpu_bpts(void) if (dabr.enabled) set_dabr(dabr.address | (dabr.enabled & 7)); if (iabr && cpu_has_feature(CPU_FTR_IABR)) - set_iabr(iabr->address + mtspr(SPRN_IABR, iabr->address | (iabr->enabled & (BP_IABR|BP_IABR_TE))); } @@ -746,7 +731,7 @@ static void remove_cpu_bpts(void) { set_dabr(0); if (cpu_has_feature(CPU_FTR_IABR)) - set_iabr(0); + mtspr(SPRN_IABR, 0); } /* Command interpreting routine */ @@ -830,9 +815,6 @@ cmds(struct pt_regs *excp) case '?': printf(help_string); break; - case 'p': - show_state(); - break; case 'b': bpt_cmds(); break; @@ -846,12 +828,14 @@ cmds(struct pt_regs *excp) case 'z': bootcmds(); break; - case 'T': - debug_trace(); + case 'p': + proccall(); break; +#ifdef CONFIG_PPC_STD_MMU case 'u': dump_segments(); break; +#endif default: printf("Unrecognized command: "); do { @@ -1070,6 +1054,7 @@ bpt_cmds(void) cmd = inchar(); switch (cmd) { +#ifndef CONFIG_8xx case 'd': /* bd - hardware data breakpoint */ mode = 7; cmd = inchar(); @@ -1111,6 +1096,7 @@ bpt_cmds(void) iabr = bp; } break; +#endif case 'c': if (!scanhex(&a)) { @@ -1152,7 +1138,7 @@ bpt_cmds(void) /* print all breakpoints */ printf(" type address\n"); if (dabr.enabled) { - printf(" data %.16lx [", dabr.address); + printf(" data "REG" [", dabr.address); if (dabr.enabled & 1) printf("r"); if (dabr.enabled & 2) @@ -1231,6 +1217,18 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp, static int xmon_depth_to_print = 64; +#ifdef CONFIG_PPC64 +#define LRSAVE_OFFSET 0x10 +#define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ +#define MARKER_OFFSET 0x60 +#define REGS_OFFSET 0x70 +#else +#define LRSAVE_OFFSET 4 +#define REG_FRAME_MARKER 0x72656773 +#define MARKER_OFFSET 8 +#define REGS_OFFSET 16 +#endif + static void xmon_show_stack(unsigned long sp, unsigned long lr, unsigned long pc) { @@ -1247,7 +1245,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, break; } - if (!mread(sp + 16, &ip, sizeof(unsigned long)) + if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) || !mread(sp, &newsp, sizeof(unsigned long))) { printf("Couldn't read stack frame at %lx\n", sp); break; @@ -1266,7 +1264,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, get_function_bounds(pc, &fnstart, &fnend); nextip = 0; if (newsp > sp) - mread(newsp + 16, &nextip, + mread(newsp + LRSAVE_OFFSET, &nextip, sizeof(unsigned long)); if (lr == ip) { if (lr < PAGE_OFFSET @@ -1280,24 +1278,24 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, xmon_print_symbol(lr, " ", "\n"); } if (printip) { - printf("[%.16lx] ", sp); + printf("["REG"] ", sp); xmon_print_symbol(ip, " ", " (unreliable)\n"); } pc = lr = 0; } else { - printf("[%.16lx] ", sp); + printf("["REG"] ", sp); xmon_print_symbol(ip, " ", "\n"); } /* Look for "regshere" marker to see if this is an exception frame. */ - if (mread(sp + 0x60, &marker, sizeof(unsigned long)) - && marker == 0x7265677368657265ul) { - if (mread(sp + 0x70, ®s, sizeof(regs)) + if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) + && marker == REG_FRAME_MARKER) { + if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) != sizeof(regs)) { printf("Couldn't read registers at %lx\n", - sp + 0x70); + sp + REGS_OFFSET); break; } printf("--- Exception: %lx %s at ", regs.trap, @@ -1371,7 +1369,9 @@ void excprint(struct pt_regs *fp) } printf(" current = 0x%lx\n", current); +#ifdef CONFIG_PPC64 printf(" paca = 0x%lx\n", get_paca()); +#endif if (current) { printf(" pid = %ld, comm = %s\n", current->pid, current->comm); @@ -1383,7 +1383,7 @@ void excprint(struct pt_regs *fp) void prregs(struct pt_regs *fp) { - int n; + int n, trap; unsigned long base; struct pt_regs regs; @@ -1396,7 +1396,7 @@ void prregs(struct pt_regs *fp) __delay(200); } else { catch_memory_errors = 0; - printf("*** Error reading registers from %.16lx\n", + printf("*** Error reading registers from "REG"\n", base); return; } @@ -1404,22 +1404,36 @@ void prregs(struct pt_regs *fp) fp = ®s; } +#ifdef CONFIG_PPC64 if (FULL_REGS(fp)) { for (n = 0; n < 16; ++n) - printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", + printf("R%.2ld = "REG" R%.2ld = "REG"\n", n, fp->gpr[n], n+16, fp->gpr[n+16]); } else { for (n = 0; n < 7; ++n) - printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", + printf("R%.2ld = "REG" R%.2ld = "REG"\n", n, fp->gpr[n], n+7, fp->gpr[n+7]); } +#else + for (n = 0; n < 32; ++n) { + printf("R%.2d = %.8x%s", n, fp->gpr[n], + (n & 3) == 3? "\n": " "); + if (n == 12 && !FULL_REGS(fp)) { + printf("\n"); + break; + } + } +#endif printf("pc = "); xmon_print_symbol(fp->nip, " ", "\n"); printf("lr = "); xmon_print_symbol(fp->link, " ", "\n"); - printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr); - printf("ctr = %.16lx xer = %.16lx trap = %8lx\n", + printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); + printf("ctr = "REG" xer = "REG" trap = %4lx\n", fp->ctr, fp->xer, fp->trap); + trap = TRAP(fp); + if (trap == 0x300 || trap == 0x380 || trap == 0x600) + printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); } void cacheflush(void) @@ -1519,8 +1533,7 @@ static unsigned long regno; extern char exc_prolog; extern char dec_exc; -void -super_regs(void) +void super_regs(void) { int cmd; unsigned long val; @@ -1536,12 +1549,14 @@ super_regs(void) asm("mr %0,1" : "=r" (sp) :); asm("mr %0,2" : "=r" (toc) :); - printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0()); - printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1()); - printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2()); - printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3()); - printf("toc = %.16lx dar = %.16lx\n", toc, get_dar()); - printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1()); + printf("msr = "REG" sprg0= "REG"\n", + mfmsr(), mfspr(SPRN_SPRG0)); + printf("pvr = "REG" sprg1= "REG"\n", + mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); + printf("dec = "REG" sprg2= "REG"\n", + mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); + printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); + printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); #ifdef CONFIG_PPC_ISERIES // Dump out relevant Paca data areas. printf("Paca: \n"); @@ -1578,11 +1593,6 @@ super_regs(void) case 'r': printf("spr %lx = %lx\n", regno, read_spr(regno)); break; - case 'm': - val = get_msr(); - scanhex(&val); - set_msrd(val); - break; } scannl(); } @@ -1604,13 +1614,13 @@ mread(unsigned long adrs, void *buf, int size) q = (char *)buf; switch (size) { case 2: - *(short *)q = *(short *)p; + *(u16 *)q = *(u16 *)p; break; case 4: - *(int *)q = *(int *)p; + *(u32 *)q = *(u32 *)p; break; case 8: - *(long *)q = *(long *)p; + *(u64 *)q = *(u64 *)p; break; default: for( ; n < size; ++n) { @@ -1641,13 +1651,13 @@ mwrite(unsigned long adrs, void *buf, int size) q = (char *) buf; switch (size) { case 2: - *(short *)p = *(short *)q; + *(u16 *)p = *(u16 *)q; break; case 4: - *(int *)p = *(int *)q; + *(u32 *)p = *(u32 *)q; break; case 8: - *(long *)p = *(long *)q; + *(u64 *)p = *(u64 *)q; break; default: for ( ; n < size; ++n) { @@ -1667,11 +1677,12 @@ mwrite(unsigned long adrs, void *buf, int size) } static int fault_type; +static int fault_except; static char *fault_chars[] = { "--", "**", "##" }; -static int -handle_fault(struct pt_regs *regs) +static int handle_fault(struct pt_regs *regs) { + fault_except = TRAP(regs); switch (TRAP(regs)) { case 0x200: fault_type = 0; @@ -1960,7 +1971,7 @@ prdump(unsigned long adrs, long ndump) unsigned char temp[16]; for (n = ndump; n > 0;) { - printf("%.16lx", adrs); + printf(REG, adrs); putchar(' '); r = n < 16? n: 16; nr = mread(adrs, temp, r); @@ -2008,7 +2019,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr) if (nr == 0) { if (praddr) { const char *x = fault_chars[fault_type]; - printf("%.16lx %s%s%s%s\n", adr, x, x, x, x); + printf(REG" %s%s%s%s\n", adr, x, x, x, x); } break; } @@ -2023,7 +2034,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr) dotted = 0; last_inst = inst; if (praddr) - printf("%.16lx %.8x", adr, inst); + printf(REG" %.8x", adr, inst); printf("\t"); print_insn_powerpc(inst, adr, 0); /* always returns 4 */ printf("\n"); @@ -2152,6 +2163,42 @@ memzcan(void) printf("%.8x\n", a - mskip); } +void proccall(void) +{ + unsigned long args[8]; + unsigned long ret; + int i; + typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long); + callfunc_t func; + + if (!scanhex(&adrs)) + return; + if (termch != '\n') + termch = 0; + for (i = 0; i < 8; ++i) + args[i] = 0; + for (i = 0; i < 8; ++i) { + if (!scanhex(&args[i]) || termch == '\n') + break; + termch = 0; + } + func = (callfunc_t) adrs; + ret = 0; + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + ret = func(args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7]); + sync(); + printf("return value is %x\n", ret); + } else { + printf("*** %x exception occurred\n", fault_except); + } + catch_memory_errors = 0; +} + /* Input scanning routines */ int skipbl(void) @@ -2174,7 +2221,12 @@ static char *regnames[N_PTREGS] = { "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe", + "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", +#ifdef CONFIG_PPC64 + "softe", +#else + "mq", +#endif "trap", "dar", "dsisr", "res" }; @@ -2280,8 +2332,7 @@ scannl(void) c = inchar(); } -int -hexdigit(int c) +int hexdigit(int c) { if( '0' <= c && c <= '9' ) return c - '0'; @@ -2378,7 +2429,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, const char *name = NULL; unsigned long offset, size; - printf("%.16lx", address); + printf(REG, address); if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); @@ -2399,55 +2450,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, printf("%s", after); } -static void debug_trace(void) -{ - unsigned long val, cmd, on; - - cmd = skipbl(); - if (cmd == '\n') { - /* show current state */ - unsigned long i; - printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch); - for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) { - on = PPCDBG_BITVAL(i) & ppc64_debug_switch; - printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : ""); - if (((i+1) % 3) == 0) - printf("\n"); - } - printf("\n"); - return; - } - while (cmd != '\n') { - on = 1; /* default if no sign given */ - while (cmd == '+' || cmd == '-') { - on = (cmd == '+'); - cmd = inchar(); - if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */ - ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE; - printf("Setting all values to %s...\n", on ? "on" : "off"); - if (cmd == '\n') return; - else cmd = skipbl(); - } - else - termch = cmd; - } - termch = cmd; /* not +/- ... let scanhex see it */ - scanhex((void *)&val); - if (val >= 64) { - printf("Value %x out of range:\n", val); - return; - } - if (on) { - ppc64_debug_switch |= PPCDBG_BITVAL(val); - printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); - } else { - ppc64_debug_switch &= ~PPCDBG_BITVAL(val); - printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); - } - cmd = skipbl(); - } -} - +#ifdef CONFIG_PPC64 static void dump_slb(void) { int i; @@ -2484,6 +2487,27 @@ static void dump_stab(void) } } +void dump_segments(void) +{ + if (cpu_has_feature(CPU_FTR_SLB)) + dump_slb(); + else + dump_stab(); +} +#endif + +#ifdef CONFIG_PPC_STD_MMU_32 +void dump_segments(void) +{ + int i; + + printf("sr0-15 ="); + for (i = 0; i < 16; ++i) + printf(" %x", mfsrin(i)); + printf("\n"); +} +#endif + void xmon_init(int enable) { if (enable) { @@ -2504,11 +2528,3 @@ void xmon_init(int enable) __debugger_fault_handler = NULL; } } - -void dump_segments(void) -{ - if (cpu_has_feature(CPU_FTR_SLB)) - dump_slb(); - else - dump_stab(); -} diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 2a7af765bfb6..743f0dbdebf3 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -89,7 +89,7 @@ core-y += arch/powerpc/mm/ core-y += arch/powerpc/sysdev/ core-y += arch/powerpc/platforms/ core-y += arch/powerpc/lib/ -core-$(CONFIG_XMON) += arch/ppc64/xmon/ +core-$(CONFIG_XMON) += arch/powerpc/xmon/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ boot := arch/ppc64/boot diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile deleted file mode 100644 index fb21a7088d3e..000000000000 --- a/arch/ppc64/xmon/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# Makefile for xmon - -EXTRA_CFLAGS += -mno-minimal-toc - -obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S deleted file mode 100644 index 30ee643d557c..000000000000 --- a/arch/ppc64/xmon/setjmp.S +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 1996 Paul Mackerras. - * - * 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. - * - * NOTE: assert(sizeof(buf) > 184) - */ -#include -#include - -_GLOBAL(xmon_setjmp) - mflr r0 - std r0,0(r3) - std r1,8(r3) - std r2,16(r3) - mfcr r0 - std r0,24(r3) - std r13,32(r3) - std r14,40(r3) - std r15,48(r3) - std r16,56(r3) - std r17,64(r3) - std r18,72(r3) - std r19,80(r3) - std r20,88(r3) - std r21,96(r3) - std r22,104(r3) - std r23,112(r3) - std r24,120(r3) - std r25,128(r3) - std r26,136(r3) - std r27,144(r3) - std r28,152(r3) - std r29,160(r3) - std r30,168(r3) - std r31,176(r3) - li r3,0 - blr - -_GLOBAL(xmon_longjmp) - cmpdi r4,0 - bne 1f - li r4,1 -1: ld r13,32(r3) - ld r14,40(r3) - ld r15,48(r3) - ld r16,56(r3) - ld r17,64(r3) - ld r18,72(r3) - ld r19,80(r3) - ld r20,88(r3) - ld r21,96(r3) - ld r22,104(r3) - ld r23,112(r3) - ld r24,120(r3) - ld r25,128(r3) - ld r26,136(r3) - ld r27,144(r3) - ld r28,152(r3) - ld r29,160(r3) - ld r30,168(r3) - ld r31,176(r3) - ld r0,24(r3) - mtcrf 56,r0 - ld r0,0(r3) - ld r1,8(r3) - ld r2,16(r3) - mtlr r0 - mr r3,r4 - blr diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 470d7400ac59..f99f2af82ca5 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -188,6 +188,10 @@ GLUE(.,name): #define LDL ld #define STL std #define CMPI cmpdi +#define SZL 8 + +/* offsets for stack frame layout */ +#define LRSAVE 16 #else /* 32-bit */ #define LOADADDR(rn,name) \ @@ -203,6 +207,10 @@ GLUE(.,name): #define LDL lwz #define STL stw #define CMPI cmpwi +#define SZL 4 + +/* offsets for stack frame layout */ +#define LRSAVE 4 #endif diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index bfb45a4523d3..da848412f11b 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -546,6 +546,7 @@ #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ : : "r" (v)) #define mtmsrd(v) __mtmsrd((v), 0) +#define mtmsr(v) mtmsrd(v) #else #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) #endif diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index ca5f33277e0c..43f7129984c7 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h @@ -4,7 +4,7 @@ struct pt_regs; -extern void xmon(struct pt_regs *excp); +extern int xmon(struct pt_regs *excp); extern void xmon_printf(const char *fmt, ...); extern void xmon_init(int); From c6b8fdad144bbb915d124ffd95011ad55730bf9f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:05:16 +0100 Subject: [PATCH 0532/1940] [ARM] 3/4: Remove asm/hardware.h from Versatile and Integrator io.h Signed-off-by: Russell King --- drivers/mmc/mmci.c | 1 + drivers/serial/amba-pl010.c | 1 + drivers/serial/amba-pl011.c | 1 + drivers/video/amba-clcd.c | 1 + include/asm-arm/arch-integrator/hardware.h | 9 --------- include/asm-arm/arch-integrator/io.h | 10 ++++++++-- include/asm-arm/arch-versatile/io.h | 2 -- sound/arm/aaci.c | 1 + 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 91c74843dc0d..1e6bdba26756 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 679e678c7e6a..ddd0307fece2 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -50,6 +50,7 @@ #include #include +#include #include #include diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 1ff629c74750..938d185841c9 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -50,6 +50,7 @@ #include #include +#include #include #include #include diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 321dbe91dc14..cde6fd8eb390 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/include/asm-arm/arch-integrator/hardware.h b/include/asm-arm/arch-integrator/hardware.h index be2716eeaa02..6f0947bc500d 100644 --- a/include/asm-arm/arch-integrator/hardware.h +++ b/include/asm-arm/arch-integrator/hardware.h @@ -33,15 +33,6 @@ #define IO_SIZE 0x0B000000 // How much? #define IO_START INTEGRATOR_HDR_BASE // PA of IO -/* - * Similar to above, but for PCI addresses (memory, IO, Config and the - * V3 chip itself). WARNING: this has to mirror definitions in platform.h - */ -#define PCI_MEMORY_VADDR 0xe8000000 -#define PCI_CONFIG_VADDR 0xec000000 -#define PCI_V3_VADDR 0xed000000 -#define PCI_IO_VADDR 0xee000000 - #define PCIO_BASE PCI_IO_VADDR #define PCIMEM_BASE PCI_MEMORY_VADDR diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h index 1329a731160d..31f2deab51b0 100644 --- a/include/asm-arm/arch-integrator/io.h +++ b/include/asm-arm/arch-integrator/io.h @@ -20,10 +20,16 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include - #define IO_SPACE_LIMIT 0xffff +/* + * WARNING: this has to mirror definitions in platform.h + */ +#define PCI_MEMORY_VADDR 0xe8000000 +#define PCI_CONFIG_VADDR 0xec000000 +#define PCI_V3_VADDR 0xed000000 +#define PCI_IO_VADDR 0xee000000 + #define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a))) #define __mem_pci(a) (a) #define __mem_isa(a) ((a) + PCI_MEMORY_VADDR) diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h index c2eed7f04b78..47e904cf25c7 100644 --- a/include/asm-arm/arch-versatile/io.h +++ b/include/asm-arm/arch-versatile/io.h @@ -20,8 +20,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include - #define IO_SPACE_LIMIT 0xffffffff static inline void __iomem *__io(unsigned long addr) diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b2d5db20ec8c..559ead6367da 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -20,6 +20,7 @@ #include #include +#include #include #include From 674c04538284736c4a44224c78cb784b2c972f98 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:25:28 +0100 Subject: [PATCH 0533/1940] [ARM] 3/4: Remove asm/hardware.h from SA1100 io.h Signed-off-by: Russell King --- arch/arm/mm/ioremap.c | 1 + drivers/mtd/maps/sa1100-flash.c | 1 + include/asm-arm/arch-sa1100/hardware.h | 7 ------- include/asm-arm/arch-sa1100/io.h | 6 +++++- include/asm-arm/arch-sa1100/system.h | 1 + 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 7110e54182b1..6fb1258df1b5 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -26,6 +26,7 @@ #include #include +#include #include #include diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 8dcaa357b4bb..9133351ba483 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h index 19c3b1e186bb..28711aaa4968 100644 --- a/include/asm-arm/arch-sa1100/hardware.h +++ b/include/asm-arm/arch-sa1100/hardware.h @@ -21,13 +21,6 @@ #define UNCACHEABLE_ADDR 0xfa050000 -/* - * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for - * in*()/out*() macros to be usable for all cases. - */ -#define PCIO_BASE 0 - - /* * SA1100 internal I/O mappings * diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h index 9c8f588f35db..9d4fe6cf205b 100644 --- a/include/asm-arm/arch-sa1100/io.h +++ b/include/asm-arm/arch-sa1100/io.h @@ -18,7 +18,11 @@ * We don't actually have real ISA nor PCI buses, but there is so many * drivers out there that might just work if we fake them... */ -#define __io(a) ((void __iomem *)(PCIO_BASE + (a))) +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)addr; +} +#define __io(a) __io(a) #define __mem_pci(a) (a) #define __mem_isa(a) (a) diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h index 6f52118ba1a4..0f0612f79b2b 100644 --- a/include/asm-arm/arch-sa1100/system.h +++ b/include/asm-arm/arch-sa1100/system.h @@ -4,6 +4,7 @@ * Copyright (c) 1999 Nicolas Pitre */ #include +#include static inline void arch_idle(void) { From f339ab3d6c59f8f898c165384aa2b6a0ae5d4c1c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:29:43 +0100 Subject: [PATCH 0534/1940] [ARM] Fix sparse warnings Fix sparse warnings in arch/arm/kernel/module.c, arch/arm/mm/consistent.c, drivers/pcmcia/sa1111_generic.c, and platform support files. Signed-off-by: Russell King --- arch/arm/kernel/module.c | 1 + arch/arm/mm/consistent.c | 6 +++--- drivers/pcmcia/sa1111_generic.c | 2 +- include/asm-arm/mach/arch.h | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 1a85cfdad5ac..6055e1427ba3 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include #include diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 26356ce4da54..0f32de977f5e 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -75,7 +75,7 @@ static struct vm_region consistent_head = { }; static struct vm_region * -vm_region_alloc(struct vm_region *head, size_t size, int gfp) +vm_region_alloc(struct vm_region *head, size_t size, unsigned int gfp) { unsigned long addr = head->vm_start, end = head->vm_end - size; unsigned long flags; @@ -133,8 +133,8 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad #endif static void * -__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, - pgprot_t prot) +__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, + unsigned int gfp, pgprot_t prot) { struct page *page; struct vm_region *c; diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index bb90a1448a53..81ded52c8959 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -122,7 +122,7 @@ void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static int pcmcia_probe(struct sa1111_dev *dev) { - char *base; + void __iomem *base; if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index 4fa95084a8c0..7273c6fd95b5 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -48,10 +48,10 @@ struct machine_desc { * Set of macros to define architecture features. This is built into * a table by the linker. */ -#define MACHINE_START(_type,_name) \ -const struct machine_desc __mach_desc_##_type \ +#define MACHINE_START(_type,_name) \ +static const struct machine_desc __mach_desc_##_type \ __attribute__((__section__(".arch.info.init"))) = { \ - .nr = MACH_TYPE_##_type, \ + .nr = MACH_TYPE_##_type, \ .name = _name, #define MACHINE_END \ From 90072059d2963dec237ae0cf49831ef77ddb5739 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:48:37 +0100 Subject: [PATCH 0535/1940] [ARM] Re-jig bootmem initialisation Make ARM independent of the way bootmem operates internally. We now map each node as we initialise it, and place the bootmem bitmap inside each node, rather than all in the first node. Signed-off-by: Russell King --- arch/arm/mm/init.c | 508 +++++++++++++++++++++--------------------- arch/arm/mm/mm-armv.c | 110 +-------- 2 files changed, 256 insertions(+), 362 deletions(-) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index edffa47a4b2a..d1f1ec73500f 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mm/init.c * - * Copyright (C) 1995-2002 Russell King + * Copyright (C) 1995-2005 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -86,14 +86,19 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } -struct node_info { - unsigned int start; - unsigned int end; - int bootmap_pages; -}; +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} -#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + +#define for_each_nodebank(iter,mi,no) \ + for (iter = 0; iter < mi->nr_banks; iter++) \ + if (mi->bank[iter].node == no) /* * FIXME: We really want to avoid allocating the bootmap bitmap @@ -106,15 +111,12 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) { unsigned int start_pfn, bank, bootmap_pfn; - start_pfn = O_PFN_UP(__pa(&_end)); + start_pfn = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT; bootmap_pfn = 0; - for (bank = 0; bank < mi->nr_banks; bank ++) { + for_each_nodebank(bank, mi, node) { unsigned int start, end; - if (mi->bank[bank].node != node) - continue; - start = mi->bank[bank].start >> PAGE_SHIFT; end = (mi->bank[bank].size + mi->bank[bank].start) >> PAGE_SHIFT; @@ -140,92 +142,6 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) return bootmap_pfn; } -/* - * Scan the memory info structure and pull out: - * - the end of memory - * - the number of nodes - * - the pfn range of each node - * - the number of bootmem bitmap pages - */ -static unsigned int __init -find_memend_and_nodes(struct meminfo *mi, struct node_info *np) -{ - unsigned int i, bootmem_pages = 0, memend_pfn = 0; - - for (i = 0; i < MAX_NUMNODES; i++) { - np[i].start = -1U; - np[i].end = 0; - np[i].bootmap_pages = 0; - } - - for (i = 0; i < mi->nr_banks; i++) { - unsigned long start, end; - int node; - - if (mi->bank[i].size == 0) { - /* - * Mark this bank with an invalid node number - */ - mi->bank[i].node = -1; - continue; - } - - node = mi->bank[i].node; - - /* - * Make sure we haven't exceeded the maximum number of nodes - * that we have in this configuration. If we have, we're in - * trouble. (maybe we ought to limit, instead of bugging?) - */ - if (node >= MAX_NUMNODES) - BUG(); - node_set_online(node); - - /* - * Get the start and end pfns for this bank - */ - start = mi->bank[i].start >> PAGE_SHIFT; - end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; - - if (np[node].start > start) - np[node].start = start; - - if (np[node].end < end) - np[node].end = end; - - if (memend_pfn < end) - memend_pfn = end; - } - - /* - * Calculate the number of pages we require to - * store the bootmem bitmaps. - */ - for_each_online_node(i) { - if (np[i].end == 0) - continue; - - np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end - - np[i].start); - bootmem_pages += np[i].bootmap_pages; - } - - high_memory = __va(memend_pfn << PAGE_SHIFT); - - /* - * This doesn't seem to be used by the Linux memory - * manager any more. If we can get rid of it, we - * also get rid of some of the stuff above as well. - * - * Note: max_low_pfn and max_pfn reflect the number - * of _pages_ in the system, not the maximum PFN. - */ - max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); - max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); - - return bootmem_pages; -} - static int __init check_initrd(struct meminfo *mi) { int initrd_node = -2; @@ -266,9 +182,8 @@ static int __init check_initrd(struct meminfo *mi) /* * Reserve the various regions of node 0 */ -static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages) +static __init void reserve_node_zero(pg_data_t *pgdat) { - pg_data_t *pgdat = NODE_DATA(0); unsigned long res_size = 0; /* @@ -288,13 +203,6 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t)); - /* - * And don't forget to reserve the allocator bitmap, - * which will be freed later. - */ - reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT, - bootmap_pages << PAGE_SHIFT); - /* * Hmm... This should go elsewhere, but we really really need to * stop things allocating the low memory; ideally we need a better @@ -324,93 +232,256 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } -/* - * Register all available RAM in this node with the bootmem allocator. - */ -static inline void free_bootmem_node_bank(int node, struct meminfo *mi) +void __init build_mem_type_table(void); +void __init create_mapping(struct map_desc *md); + +static unsigned long __init +bootmem_init_node(int node, int initrd_node, struct meminfo *mi) { - pg_data_t *pgdat = NODE_DATA(node); - int bank; + unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; + unsigned long start_pfn, end_pfn, boot_pfn; + unsigned int boot_pages; + pg_data_t *pgdat; + int i; - for (bank = 0; bank < mi->nr_banks; bank++) - if (mi->bank[bank].node == node) - free_bootmem_node(pgdat, mi->bank[bank].start, - mi->bank[bank].size); -} - -/* - * Initialise the bootmem allocator for all nodes. This is called - * early during the architecture specific initialisation. - */ -static void __init bootmem_init(struct meminfo *mi) -{ - struct node_info node_info[MAX_NUMNODES], *np = node_info; - unsigned int bootmap_pages, bootmap_pfn, map_pg; - int node, initrd_node; - - bootmap_pages = find_memend_and_nodes(mi, np); - bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages); - initrd_node = check_initrd(mi); - - map_pg = bootmap_pfn; + start_pfn = -1UL; + end_pfn = 0; /* - * Initialise the bootmem nodes. - * - * What we really want to do is: - * - * unmap_all_regions_except_kernel(); - * for_each_node_in_reverse_order(node) { - * map_node(node); - * allocate_bootmem_map(node); - * init_bootmem_node(node); - * free_bootmem_node(node); - * } - * - * but this is a 2.5-type change. For now, we just set - * the nodes up in reverse order. - * - * (we could also do with rolling bootmem_init and paging_init - * into one generic "memory_init" type function). + * Calculate the pfn range, and map the memory banks for this node. */ - np += num_online_nodes() - 1; - for (node = num_online_nodes() - 1; node >= 0; node--, np--) { - /* - * If there are no pages in this node, ignore it. - * Note that node 0 must always have some pages. - */ - if (np->end == 0 || !node_online(node)) { - if (node == 0) - BUG(); - continue; - } + for_each_nodebank(i, mi, node) { + unsigned long start, end; + struct map_desc map; - /* - * Initialise the bootmem allocator. - */ - init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end); - free_bootmem_node_bank(node, mi); - map_pg += np->bootmap_pages; + start = mi->bank[i].start >> PAGE_SHIFT; + end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; - /* - * If this is node 0, we need to reserve some areas ASAP - - * we may use bootmem on node 0 to setup the other nodes. - */ - if (node == 0) - reserve_node_zero(bootmap_pfn, bootmap_pages); + if (start_pfn > start) + start_pfn = start; + if (end_pfn < end) + end_pfn = end; + + map.physical = mi->bank[i].start; + map.virtual = __phys_to_virt(map.physical); + map.length = mi->bank[i].size; + map.type = MT_MEMORY; + + create_mapping(&map); } + /* + * If there is no memory in this node, ignore it. + */ + if (end_pfn == 0) + return end_pfn; + + /* + * Allocate the bootmem bitmap page. + */ + boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); + boot_pfn = find_bootmap_pfn(node, mi, boot_pages); + + /* + * Initialise the bootmem allocator for this node, handing the + * memory banks over to bootmem. + */ + node_set_online(node); + pgdat = NODE_DATA(node); + init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn); + + for_each_nodebank(i, mi, node) + free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size); + + /* + * Reserve the bootmem bitmap for this node. + */ + reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, + boot_pages << PAGE_SHIFT); #ifdef CONFIG_BLK_DEV_INITRD - if (phys_initrd_size && initrd_node >= 0) { - reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start, + /* + * If the initrd is in this node, reserve its memory. + */ + if (node == initrd_node) { + reserve_bootmem_node(pgdat, phys_initrd_start, phys_initrd_size); initrd_start = __phys_to_virt(phys_initrd_start); initrd_end = initrd_start + phys_initrd_size; } #endif - BUG_ON(map_pg != bootmap_pfn + bootmap_pages); + /* + * Finally, reserve any node zero regions. + */ + if (node == 0) + reserve_node_zero(pgdat); + + /* + * initialise the zones within this node. + */ + memset(zone_size, 0, sizeof(zone_size)); + memset(zhole_size, 0, sizeof(zhole_size)); + + /* + * The size of this node has already been determined. If we need + * to do anything fancy with the allocation of this memory to the + * zones, now is the time to do it. + */ + zone_size[0] = end_pfn - start_pfn; + + /* + * For each bank in this node, calculate the size of the holes. + * holes = node_size - sum(bank_sizes_in_node) + */ + zhole_size[0] = zone_size[0]; + for_each_nodebank(i, mi, node) + zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; + + /* + * Adjust the sizes according to any special requirements for + * this machine type. + */ + arch_adjust_zones(node, zone_size, zhole_size); + + free_area_init_node(node, pgdat, zone_size, start_pfn, zhole_size); + + return end_pfn; +} + +static void __init bootmem_init(struct meminfo *mi) +{ + unsigned long addr, memend_pfn = 0; + int node, initrd_node, i; + + /* + * Invalidate the node number for empty or invalid memory banks + */ + for (i = 0; i < mi->nr_banks; i++) + if (mi->bank[i].size == 0 || mi->bank[i].node >= MAX_NUMNODES) + mi->bank[i].node = -1; + + memcpy(&meminfo, mi, sizeof(meminfo)); + +#ifdef CONFIG_XIP_KERNEL +#error needs fixing + p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; + p->virtual = (unsigned long)&_stext & PMD_MASK; + p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; + p->type = MT_ROM; + p ++; +#endif + + /* + * Clear out all the mappings below the kernel image. + * FIXME: what about XIP? + */ + for (addr = 0; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Clear out all the kernel space mappings, except for the first + * memory bank, up to the end of the vmalloc region. + */ + for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); + addr < VMALLOC_END; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Locate which node contains the ramdisk image, if any. + */ + initrd_node = check_initrd(mi); + + /* + * Run through each node initialising the bootmem allocator. + */ + for_each_node(node) { + unsigned long end_pfn; + + end_pfn = bootmem_init_node(node, initrd_node, mi); + + /* + * Remember the highest memory PFN. + */ + if (end_pfn > memend_pfn) + memend_pfn = end_pfn; + } + + high_memory = __va(memend_pfn << PAGE_SHIFT); + + /* + * This doesn't seem to be used by the Linux memory manager any + * more, but is used by ll_rw_block. If we can get rid of it, we + * also get rid of some of the stuff above as well. + * + * Note: max_low_pfn and max_pfn reflect the number of _pages_ in + * the system, not the maximum PFN. + */ + max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; +} + +/* + * Set up device the mappings. Since we clear out the page tables for all + * mappings above VMALLOC_END, we will remove any debug device mappings. + * This means you have to be careful how you debug this function, or any + * called function. (Do it by code inspection!) + */ +static void __init devicemaps_init(struct machine_desc *mdesc) +{ + struct map_desc map; + unsigned long addr; + void *vectors; + + for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Map the cache flushing regions. + */ +#ifdef FLUSH_BASE + map.physical = FLUSH_BASE_PHYS; + map.virtual = FLUSH_BASE; + map.length = PGDIR_SIZE; + map.type = MT_CACHECLEAN; + create_mapping(&map); +#endif +#ifdef FLUSH_BASE_MINICACHE + map.physical = FLUSH_BASE_PHYS + PGDIR_SIZE; + map.virtual = FLUSH_BASE_MINICACHE; + map.length = PGDIR_SIZE; + map.type = MT_MINICLEAN; + create_mapping(&map); +#endif + + flush_cache_all(); + local_flush_tlb_all(); + + vectors = alloc_bootmem_low_pages(PAGE_SIZE); + BUG_ON(!vectors); + + /* + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. + */ + map.physical = virt_to_phys(vectors); + map.virtual = 0xffff0000; + map.length = PAGE_SIZE; + map.type = MT_HIGH_VECTORS; + create_mapping(&map); + + if (!vectors_high()) { + map.virtual = 0; + map.type = MT_LOW_VECTORS; + create_mapping(&map); + } + + /* + * Ask the machine support to map in the statically mapped devices. + * After this point, we can start to touch devices again. + */ + if (mdesc->map_io) + mdesc->map_io(); } /* @@ -420,87 +491,17 @@ static void __init bootmem_init(struct meminfo *mi) void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) { void *zero_page; - int node; + build_mem_type_table(); bootmem_init(mi); + devicemaps_init(mdesc); - memcpy(&meminfo, mi, sizeof(meminfo)); + top_pmd = pmd_off_k(0xffff0000); /* * allocate the zero page. Note that we count on this going ok. */ zero_page = alloc_bootmem_low_pages(PAGE_SIZE); - - /* - * initialise the page tables. - */ - memtable_init(mi); - if (mdesc->map_io) - mdesc->map_io(); - local_flush_tlb_all(); - - /* - * initialise the zones within each node - */ - for_each_online_node(node) { - unsigned long zone_size[MAX_NR_ZONES]; - unsigned long zhole_size[MAX_NR_ZONES]; - struct bootmem_data *bdata; - pg_data_t *pgdat; - int i; - - /* - * Initialise the zone size information. - */ - for (i = 0; i < MAX_NR_ZONES; i++) { - zone_size[i] = 0; - zhole_size[i] = 0; - } - - pgdat = NODE_DATA(node); - bdata = pgdat->bdata; - - /* - * The size of this node has already been determined. - * If we need to do anything fancy with the allocation - * of this memory to the zones, now is the time to do - * it. - */ - zone_size[0] = bdata->node_low_pfn - - (bdata->node_boot_start >> PAGE_SHIFT); - - /* - * If this zone has zero size, skip it. - */ - if (!zone_size[0]) - continue; - - /* - * For each bank in this node, calculate the size of the - * holes. holes = node_size - sum(bank_sizes_in_node) - */ - zhole_size[0] = zone_size[0]; - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].node != node) - continue; - - zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; - } - - /* - * Adjust the sizes according to any special - * requirements for this machine type. - */ - arch_adjust_zones(node, zone_size, zhole_size); - - free_area_init_node(node, pgdat, zone_size, - bdata->node_boot_start >> PAGE_SHIFT, zhole_size); - } - - /* - * finish off the bad pages once - * the mem_map is initialised - */ memzero(zero_page, PAGE_SIZE); empty_zero_page = virt_to_page(zero_page); flush_dcache_page(empty_zero_page); @@ -562,10 +563,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi) * may not be the case, especially if the user has provided the * information on the command line. */ - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].size == 0 || mi->bank[i].node != node) - continue; - + for_each_nodebank(i, mi, node) { bank_start = mi->bank[i].start >> PAGE_SHIFT; if (bank_start < prev_bank_end) { printk(KERN_ERR "MEM: unordered memory banks. " diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index d125a3dc061c..c626361c0f5e 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mm/mm-armv.c * - * Copyright (C) 1998-2002 Russell King + * Copyright (C) 1998-2005 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -305,16 +305,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); } -/* - * Clear any PGD mapping. On a two-level page table system, - * the clearance is done by the middle-level functions (pmd) - * rather than the top-level (pgd) functions. - */ -static inline void clear_mapping(unsigned long virt) -{ - pmd_clear(pmd_off_k(virt)); -} - struct mem_types { unsigned int prot_pte; unsigned int prot_l1; @@ -373,7 +363,7 @@ static struct mem_types mem_types[] __initdata = { /* * Adjust the PMD section entries according to the CPU in use. */ -static void __init build_mem_type_table(void) +void __init build_mem_type_table(void) { struct cachepolicy *cp; unsigned int cr = get_cr(); @@ -483,7 +473,7 @@ static void __init build_mem_type_table(void) * offsets, and we take full advantage of sections and * supersections. */ -static void __init create_mapping(struct map_desc *md) +void __init create_mapping(struct map_desc *md) { unsigned long virt, length; int prot_sect, prot_l1, domain; @@ -601,100 +591,6 @@ void setup_mm_for_reboot(char mode) } } -extern void _stext, _etext; - -/* - * Setup initial mappings. We use the page we allocated for zero page to hold - * the mappings, which will get overwritten by the vectors in traps_init(). - * The mappings must be in virtual address order. - */ -void __init memtable_init(struct meminfo *mi) -{ - struct map_desc *init_maps, *p, *q; - unsigned long address = 0; - int i; - - build_mem_type_table(); - - init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); - -#ifdef CONFIG_XIP_KERNEL - p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; - p->virtual = (unsigned long)&_stext & PMD_MASK; - p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; - p->type = MT_ROM; - p ++; -#endif - - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].size == 0) - continue; - - p->physical = mi->bank[i].start; - p->virtual = __phys_to_virt(p->physical); - p->length = mi->bank[i].size; - p->type = MT_MEMORY; - p ++; - } - -#ifdef FLUSH_BASE - p->physical = FLUSH_BASE_PHYS; - p->virtual = FLUSH_BASE; - p->length = PGDIR_SIZE; - p->type = MT_CACHECLEAN; - p ++; -#endif - -#ifdef FLUSH_BASE_MINICACHE - p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE; - p->virtual = FLUSH_BASE_MINICACHE; - p->length = PGDIR_SIZE; - p->type = MT_MINICLEAN; - p ++; -#endif - - /* - * Go through the initial mappings, but clear out any - * pgdir entries that are not in the description. - */ - q = init_maps; - do { - if (address < q->virtual || q == p) { - clear_mapping(address); - address += PGDIR_SIZE; - } else { - create_mapping(q); - - address = q->virtual + q->length; - address = (address + PGDIR_SIZE - 1) & PGDIR_MASK; - - q ++; - } - } while (address != 0); - - /* - * Create a mapping for the machine vectors at the high-vectors - * location (0xffff0000). If we aren't using high-vectors, also - * create a mapping at the low-vectors virtual address. - */ - init_maps->physical = virt_to_phys(init_maps); - init_maps->virtual = 0xffff0000; - init_maps->length = PAGE_SIZE; - init_maps->type = MT_HIGH_VECTORS; - create_mapping(init_maps); - - if (!vectors_high()) { - init_maps->virtual = 0; - init_maps->type = MT_LOW_VECTORS; - create_mapping(init_maps); - } - - flush_cache_all(); - local_flush_tlb_all(); - - top_pmd = pmd_off_k(0xffff0000); -} - /* * Create the architecture specific mappings */ From b5893c56ca7e664aef010a71c2638db768d4e996 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:51:15 +0100 Subject: [PATCH 0536/1940] [ARM] 1/4 Move oprofile driver model code Signed-off-by: Russell King --- arch/arm/oprofile/common.c | 99 ++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index e57dde882898..5b1d752edbc3 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include "op_counter.h" #include "op_arm_model.h" @@ -20,57 +20,6 @@ static struct op_arm_model_spec *pmu_model; static int pmu_enabled; static struct semaphore pmu_sem; -static int pmu_start(void); -static int pmu_setup(void); -static void pmu_stop(void); -static int pmu_create_files(struct super_block *, struct dentry *); - -#ifdef CONFIG_PM -static int pmu_suspend(struct sys_device *dev, pm_message_t state) -{ - if (pmu_enabled) - pmu_stop(); - return 0; -} - -static int pmu_resume(struct sys_device *dev) -{ - if (pmu_enabled) - pmu_start(); - return 0; -} - -static struct sysdev_class oprofile_sysclass = { - set_kset_name("oprofile"), - .resume = pmu_resume, - .suspend = pmu_suspend, -}; - -static struct sys_device device_oprofile = { - .id = 0, - .cls = &oprofile_sysclass, -}; - -static int __init init_driverfs(void) -{ - int ret; - - if (!(ret = sysdev_class_register(&oprofile_sysclass))) - ret = sysdev_register(&device_oprofile); - - return ret; -} - -static void exit_driverfs(void) -{ - sysdev_unregister(&device_oprofile); - sysdev_class_unregister(&oprofile_sysclass); -} -#else -#define init_driverfs() do { } while (0) -#define exit_driverfs() do { } while (0) -#endif /* CONFIG_PM */ - struct op_counter_config counter_config[OP_MAX_COUNTER]; static int pmu_create_files(struct super_block *sb, struct dentry *root) @@ -126,6 +75,52 @@ static void pmu_stop(void) up(&pmu_sem); } +#ifdef CONFIG_PM +static int pmu_suspend(struct sys_device *dev, pm_message_t state) +{ + if (pmu_enabled) + pmu_stop(); + return 0; +} + +static int pmu_resume(struct sys_device *dev) +{ + if (pmu_enabled) + pmu_start(); + return 0; +} + +static struct sysdev_class oprofile_sysclass = { + set_kset_name("oprofile"), + .resume = pmu_resume, + .suspend = pmu_suspend, +}; + +static struct sys_device device_oprofile = { + .id = 0, + .cls = &oprofile_sysclass, +}; + +static int __init init_driverfs(void) +{ + int ret; + + if (!(ret = sysdev_class_register(&oprofile_sysclass))) + ret = sysdev_register(&device_oprofile); + + return ret; +} + +static void exit_driverfs(void) +{ + sysdev_unregister(&device_oprofile); + sysdev_class_unregister(&oprofile_sysclass); +} +#else +#define init_driverfs() do { } while (0) +#define exit_driverfs() do { } while (0) +#endif /* CONFIG_PM */ + int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec) { init_MUTEX(&pmu_sem); From 7c5b3fc20807279d8f8e78f1e2ef275128668796 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:52:30 +0100 Subject: [PATCH 0537/1940] [ARM] 2/4 Fix oprofile suspend/resume The oprofile suspend/resume was missing locking. If we failed to start oprofile on resume, we still reported that it was enabled. Instead, disable oprofile on error. Signed-off-by: Russell King --- arch/arm/oprofile/common.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 5b1d752edbc3..02e5d6f45166 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -78,15 +78,19 @@ static void pmu_stop(void) #ifdef CONFIG_PM static int pmu_suspend(struct sys_device *dev, pm_message_t state) { + down(&pmu_sem); if (pmu_enabled) - pmu_stop(); + pmu_model->stop(); + up(&pmu_sem); return 0; } static int pmu_resume(struct sys_device *dev) { - if (pmu_enabled) - pmu_start(); + down(&pmu_sem); + if (pmu_enabled && pmu_model->start()) + pmu_enabled = 0; + up(&pmu_sem); return 0; } From 55f052341ff75e5815b1f7f4d2d3b69314ea8712 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:54:21 +0100 Subject: [PATCH 0538/1940] [ARM] 3/4 Rename common oprofile code The common oprofile code assumes the name "PMU" (from Intel's performance management unit). This is misleading when we start adding oprofile support for other machine types which don't use the same terminology. Call it op_arm_* instead of pmu_*. Signed-off-by: Russell King --- arch/arm/oprofile/common.c | 88 ++++++++++++++++---------------- arch/arm/oprofile/init.c | 4 +- arch/arm/oprofile/op_arm_model.h | 4 +- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 02e5d6f45166..7ce6dfa06c85 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -16,17 +16,17 @@ #include "op_counter.h" #include "op_arm_model.h" -static struct op_arm_model_spec *pmu_model; -static int pmu_enabled; -static struct semaphore pmu_sem; +static struct op_arm_model_spec *op_arm_model; +static int op_arm_enabled; +static struct semaphore op_arm_sem; struct op_counter_config counter_config[OP_MAX_COUNTER]; -static int pmu_create_files(struct super_block *sb, struct dentry *root) +static int op_arm_create_files(struct super_block *sb, struct dentry *root) { unsigned int i; - for (i = 0; i < pmu_model->num_counters; i++) { + for (i = 0; i < op_arm_model->num_counters; i++) { struct dentry *dir; char buf[2]; @@ -43,61 +43,61 @@ static int pmu_create_files(struct super_block *sb, struct dentry *root) return 0; } -static int pmu_setup(void) +static int op_arm_setup(void) { int ret; spin_lock(&oprofilefs_lock); - ret = pmu_model->setup_ctrs(); + ret = op_arm_model->setup_ctrs(); spin_unlock(&oprofilefs_lock); return ret; } -static int pmu_start(void) +static int op_arm_start(void) { int ret = -EBUSY; - down(&pmu_sem); - if (!pmu_enabled) { - ret = pmu_model->start(); - pmu_enabled = !ret; + down(&op_arm_sem); + if (!op_arm_enabled) { + ret = op_arm_model->start(); + op_arm_enabled = !ret; } - up(&pmu_sem); + up(&op_arm_sem); return ret; } -static void pmu_stop(void) +static void op_arm_stop(void) { - down(&pmu_sem); - if (pmu_enabled) - pmu_model->stop(); - pmu_enabled = 0; - up(&pmu_sem); + down(&op_arm_sem); + if (op_arm_enabled) + op_arm_model->stop(); + op_arm_enabled = 0; + up(&op_arm_sem); } #ifdef CONFIG_PM -static int pmu_suspend(struct sys_device *dev, pm_message_t state) +static int op_arm_suspend(struct sys_device *dev, pm_message_t state) { - down(&pmu_sem); - if (pmu_enabled) - pmu_model->stop(); - up(&pmu_sem); + down(&op_arm_sem); + if (op_arm_enabled) + op_arm_model->stop(); + up(&op_arm_sem); return 0; } -static int pmu_resume(struct sys_device *dev) +static int op_arm_resume(struct sys_device *dev) { - down(&pmu_sem); - if (pmu_enabled && pmu_model->start()) - pmu_enabled = 0; - up(&pmu_sem); + down(&op_arm_sem); + if (op_arm_enabled && op_arm_model->start()) + op_arm_enabled = 0; + up(&op_arm_sem); return 0; } static struct sysdev_class oprofile_sysclass = { set_kset_name("oprofile"), - .resume = pmu_resume, - .suspend = pmu_suspend, + .resume = op_arm_resume, + .suspend = op_arm_suspend, }; static struct sys_device device_oprofile = { @@ -125,31 +125,31 @@ static void exit_driverfs(void) #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ -int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec) +int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec) { - init_MUTEX(&pmu_sem); + init_MUTEX(&op_arm_sem); if (spec->init() < 0) return -ENODEV; - pmu_model = spec; + op_arm_model = spec; init_driverfs(); - ops->create_files = pmu_create_files; - ops->setup = pmu_setup; - ops->shutdown = pmu_stop; - ops->start = pmu_start; - ops->stop = pmu_stop; - ops->cpu_type = pmu_model->name; - printk(KERN_INFO "oprofile: using %s PMU\n", spec->name); + ops->create_files = op_arm_create_files; + ops->setup = op_arm_setup; + ops->shutdown = op_arm_stop; + ops->start = op_arm_start; + ops->stop = op_arm_stop; + ops->cpu_type = op_arm_model->name; + printk(KERN_INFO "oprofile: using %s\n", spec->name); return 0; } -void pmu_exit(void) +void op_arm_exit(void) { - if (pmu_model) { + if (op_arm_model) { exit_driverfs(); - pmu_model = NULL; + op_arm_model = NULL; } } diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index d315a3a86c86..ccd8c54934a2 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c @@ -17,7 +17,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) int ret = -ENODEV; #ifdef CONFIG_CPU_XSCALE - ret = pmu_init(ops, &op_xscale_spec); + ret = op_arm_init(ops, &op_xscale_spec); #endif ops->backtrace = arm_backtrace; @@ -28,6 +28,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) void oprofile_arch_exit(void) { #ifdef CONFIG_CPU_XSCALE - pmu_exit(); + op_arm_exit(); #endif } diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2148d07484b7..38c6ad158547 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@ -26,6 +26,6 @@ extern struct op_arm_model_spec op_xscale_spec; extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); -extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); -extern void pmu_exit(void); +extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); +extern void op_arm_exit(void); #endif /* OP_ARM_MODEL_H */ From c6b9dafce3e3b434a3e7ffd5072815c03d18cc84 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 14:56:04 +0100 Subject: [PATCH 0539/1940] [ARM] 4/4 Combine oprofile common and init code There is nothing special about having the init code separate from the common code, so combine the two. Signed-off-by: Russell King --- arch/arm/oprofile/Makefile | 4 ++-- arch/arm/oprofile/common.c | 40 ++++++++++++++++++++++++-------------- arch/arm/oprofile/init.c | 33 ------------------------------- 3 files changed, 27 insertions(+), 50 deletions(-) delete mode 100644 arch/arm/oprofile/init.c diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index 8ffb523e6c77..6a94e54848fd 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) init.o backtrace.o -oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o +oprofile-y := $(DRIVER_OBJS) common.o backtrace.o +oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 7ce6dfa06c85..1415930ceee1 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -125,27 +125,37 @@ static void exit_driverfs(void) #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ -int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec) +int __init oprofile_arch_init(struct oprofile_operations *ops) { - init_MUTEX(&op_arm_sem); + struct op_arm_model_spec *spec = NULL; + int ret = -ENODEV; - if (spec->init() < 0) - return -ENODEV; +#ifdef CONFIG_CPU_XSCALE + spec = &op_xscale_spec; +#endif - op_arm_model = spec; - init_driverfs(); - ops->create_files = op_arm_create_files; - ops->setup = op_arm_setup; - ops->shutdown = op_arm_stop; - ops->start = op_arm_start; - ops->stop = op_arm_stop; - ops->cpu_type = op_arm_model->name; - printk(KERN_INFO "oprofile: using %s\n", spec->name); + if (spec) { + init_MUTEX(&op_arm_sem); - return 0; + if (spec->init() < 0) + return -ENODEV; + + op_arm_model = spec; + init_driverfs(); + ops->create_files = op_arm_create_files; + ops->setup = op_arm_setup; + ops->shutdown = op_arm_stop; + ops->start = op_arm_start; + ops->stop = op_arm_stop; + ops->cpu_type = op_arm_model->name; + ops->backtrace = arm_backtrace; + printk(KERN_INFO "oprofile: using %s\n", spec->name); + } + + return ret; } -void op_arm_exit(void) +void oprofile_arch_exit(void) { if (op_arm_model) { exit_driverfs(); diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c deleted file mode 100644 index ccd8c54934a2..000000000000 --- a/arch/arm/oprofile/init.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2004 Oprofile Authors - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ - -#include -#include -#include -#include "op_arm_model.h" - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - int ret = -ENODEV; - -#ifdef CONFIG_CPU_XSCALE - ret = op_arm_init(ops, &op_xscale_spec); -#endif - - ops->backtrace = arm_backtrace; - - return ret; -} - -void oprofile_arch_exit(void) -{ -#ifdef CONFIG_CPU_XSCALE - op_arm_exit(); -#endif -} From f70cd65658388ca2a06071bdbd8a5a6beac5aa47 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:18:56 +0100 Subject: [PATCH 0540/1940] [ARM] 2982/1: Replace map_desc.physical with map_desc.pfn: aaec2000 Patch from Deepak Saxena aaec2000 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-aaec2000/core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index aece0cd4f0a3..9be6c3213254 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -40,9 +40,17 @@ * default mapping provided here. */ static struct map_desc standard_io_desc[] __initdata = { - /* virtual physical length type */ - { VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE }, - { VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE } + { + .virtual = VIO_APB_BASE, + .physical = __phys_to_pfn(PIO_APB_BASE), + .length = IO_APB_LENGTH, + .type = MT_DEVICE + }, { + .virtual = VIO_AHB_BASE, + .physical = __phys_to_pfn(PIO_AHB_BASE), + .length = IO_AHB_LENGTH, + .type = MT_DEVICE + } }; void __init aaec2000_map_io(void) From 4835e64a5f44366e97dde9b6e26ede2ec16249da Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:18:57 +0100 Subject: [PATCH 0541/1940] [ARM] 2983/1: Replace map_desc.physical with map_desc.pfn: IOP3xx Patch from Deepak Saxena IOP3xx map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-iop3xx/iop321-setup.c | 18 +++++++++++------- arch/arm/mach-iop3xx/iop331-setup.c | 18 +++++++++++------- arch/arm/mach-iop3xx/iq31244-mm.c | 10 ++++++---- arch/arm/mach-iop3xx/iq80321-mm.c | 10 ++++++---- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index 0f921ba2750c..bb5091223b63 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -38,13 +38,17 @@ * Standard IO mapping for all IOP321 based systems */ static struct map_desc iop321_std_desc[] __initdata = { - /* virtual physical length type */ - - /* mem mapped registers */ - { IOP321_VIRT_MEM_BASE, IOP321_PHYS_MEM_BASE, 0x00002000, MT_DEVICE }, - - /* PCI IO space */ - { IOP321_PCI_LOWER_IO_VA, IOP321_PCI_LOWER_IO_PA, IOP321_PCI_IO_WINDOW_SIZE, MT_DEVICE } + { /* mem mapped registers */ + .virtual = IOP321_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP321_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA), + .length = IOP321_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } }; #ifdef CONFIG_ARCH_IQ80321 diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index fc74b722f72f..a2533c3ab42f 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -37,13 +37,17 @@ * Standard IO mapping for all IOP331 based systems */ static struct map_desc iop331_std_desc[] __initdata = { - /* virtual physical length type */ - - /* mem mapped registers */ - { IOP331_VIRT_MEM_BASE, IOP331_PHYS_MEM_BASE, 0x00002000, MT_DEVICE }, - - /* PCI IO space */ - { IOP331_PCI_LOWER_IO_VA, IOP331_PCI_LOWER_IO_PA, IOP331_PCI_IO_WINDOW_SIZE, MT_DEVICE } + { /* mem mapped registers */ + .virtual = IOP331_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP331_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA), + .length = IOP331_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } }; static struct uart_port iop331_serial_ports[] = { diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c index 55992ab586ba..e874b54eefe3 100644 --- a/arch/arm/mach-iop3xx/iq31244-mm.c +++ b/arch/arm/mach-iop3xx/iq31244-mm.c @@ -29,10 +29,12 @@ * We use RedBoot's setup for the onboard devices. */ static struct map_desc iq31244_io_desc[] __initdata = { - /* virtual physical length type */ - - /* on-board devices */ - { IQ31244_UART, IQ31244_UART, 0x00100000, MT_DEVICE } + { /* on-board devices */ + .virtual = IQ31244_UART, + .pfn = __phys_to_pfn(IQ31244_UART), + .length = 0x00100000, + .type = MT_DEVICE + } }; void __init iq31244_map_io(void) diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c index bb3e9e5a9aff..d9cac5e1fc3d 100644 --- a/arch/arm/mach-iop3xx/iq80321-mm.c +++ b/arch/arm/mach-iop3xx/iq80321-mm.c @@ -29,10 +29,12 @@ * We use RedBoot's setup for the onboard devices. */ static struct map_desc iq80321_io_desc[] __initdata = { - /* virtual physical length type */ - - /* on-board devices */ - { IQ80321_UART, IQ80321_UART, 0x00100000, MT_DEVICE } + { /* on-board devices */ + .virtual = IQ80321_UART, + .pfn = __phys_to_pfn(IQ80321_UART), + .length = 0x00100000, + .type = MT_DEVICE + } }; void __init iq80321_map_io(void) From db0d087e34d251254f6349e607c2a2ec295cd90b Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:18:58 +0100 Subject: [PATCH 0542/1940] [ARM] 2984/1: Replace map_desc.physical with map_desc.pfn: IXP2000 Patch from Deepak Saxena IXP2000 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp2000/core.c | 16 ++++++++-------- arch/arm/mach-ixp2000/ixdp2x00.c | 2 +- arch/arm/mach-ixp2000/ixdp2x01.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index f4d7f1f6ef85..01c393c504d0 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -83,42 +83,42 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg) static struct map_desc ixp2000_io_desc[] __initdata = { { .virtual = IXP2000_CAP_VIRT_BASE, - .physical = IXP2000_CAP_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), .length = IXP2000_CAP_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_INTCTL_VIRT_BASE, - .physical = IXP2000_INTCTL_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), .length = IXP2000_INTCTL_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_PCI_CREG_VIRT_BASE, - .physical = IXP2000_PCI_CREG_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), .length = IXP2000_PCI_CREG_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_PCI_CSR_VIRT_BASE, - .physical = IXP2000_PCI_CSR_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), .length = IXP2000_PCI_CSR_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_MSF_VIRT_BASE, - .physical = IXP2000_MSF_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), .length = IXP2000_MSF_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_PCI_IO_VIRT_BASE, - .physical = IXP2000_PCI_IO_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), .length = IXP2000_PCI_IO_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_PCI_CFG0_VIRT_BASE, - .physical = IXP2000_PCI_CFG0_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), .length = IXP2000_PCI_CFG0_SIZE, .type = MT_DEVICE }, { .virtual = IXP2000_PCI_CFG1_VIRT_BASE, - .physical = IXP2000_PCI_CFG1_PHYS_BASE, + .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), .length = IXP2000_PCI_CFG1_SIZE, .type = MT_DEVICE } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 63ba0191aa65..8b4a839b6279 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -176,7 +176,7 @@ void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *************************************************************************/ static struct map_desc ixdp2x00_io_desc __initdata = { .virtual = IXDP2X00_VIRT_CPLD_BASE, - .physical = IXDP2X00_PHYS_CPLD_BASE, + .pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE), .length = IXDP2X00_CPLD_SIZE, .type = MT_DEVICE }; diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 7a5109921287..fee1d7b73503 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -136,7 +136,7 @@ void __init ixdp2x01_init_irq(void) *************************************************************************/ static struct map_desc ixdp2x01_io_desc __initdata = { .virtual = IXDP2X01_VIRT_CPLD_BASE, - .physical = IXDP2X01_PHYS_CPLD_BASE, + .pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE), .length = IXDP2X01_CPLD_REGION_SIZE, .type = MT_DEVICE }; From 87fe04bd2a39f263211cc232da9f4f094eaffea0 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:18:59 +0100 Subject: [PATCH 0543/1940] [ARM] 2985/1: Replace map_desc.physical with map_desc.pfn: IXP4xx Patch from Deepak Saxena IXP4xx map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 36b6045213ee..6c396447c4e0 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -44,24 +44,24 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */ .virtual = IXP4XX_PERIPHERAL_BASE_VIRT, - .physical = IXP4XX_PERIPHERAL_BASE_PHYS, + .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS), .length = IXP4XX_PERIPHERAL_REGION_SIZE, .type = MT_DEVICE }, { /* Expansion Bus Config Registers */ .virtual = IXP4XX_EXP_CFG_BASE_VIRT, - .physical = IXP4XX_EXP_CFG_BASE_PHYS, + .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS), .length = IXP4XX_EXP_CFG_REGION_SIZE, .type = MT_DEVICE }, { /* PCI Registers */ .virtual = IXP4XX_PCI_CFG_BASE_VIRT, - .physical = IXP4XX_PCI_CFG_BASE_PHYS, + .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), .length = IXP4XX_PCI_CFG_REGION_SIZE, .type = MT_DEVICE }, #ifdef CONFIG_DEBUG_LL { /* Debug UART mapping */ .virtual = IXP4XX_DEBUG_UART_BASE_VIRT, - .physical = IXP4XX_DEBUG_UART_BASE_PHYS, + .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), .length = IXP4XX_DEBUG_UART_REGION_SIZE, .type = MT_DEVICE } From 36d28c03d17506dd30aeed9d68a4023f3e7631dc Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:18:59 +0100 Subject: [PATCH 0544/1940] [ARM] 2986/1: Replace map_desc.physical with map_desc.pfn: LH7A40x Patch from Deepak Saxena LH7A40x map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-lh7a40x/arch-kev7a400.c | 13 +++- arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 86 ++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index cb3dcd3bd00a..19f2fa2244c4 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -26,8 +26,17 @@ /* This function calls the board specific IRQ initialization function. */ static struct map_desc kev7a400_io_desc[] __initdata = { - { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, - { CPLD_VIRT, CPLD_PHYS, CPLD_SIZE, MT_DEVICE }, + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD_VIRT, + .pfn = __phys_to_pfn(CPLD_PHYS), + .length = CPLD_SIZE, + .type = MT_DEVICE + } }; void __init kev7a400_map_io(void) diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index 6eb61a17c63b..a20eabc132b0 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -227,23 +227,79 @@ void __init lh7a40x_init_board_irq (void) } static struct map_desc lpd7a400_io_desc[] __initdata = { - { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, - /* Mapping added to work around chip select problems */ - { IOBARRIER_VIRT, IOBARRIER_PHYS, IOBARRIER_SIZE, MT_DEVICE }, - { CF_VIRT, CF_PHYS, CF_SIZE, MT_DEVICE }, + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, { /* Mapping added to work around chip select problems */ + .virtual = IOBARRIER_VIRT, + .pfn = __phys_to_pfn(IOBARRIER_PHYS), + .length = IOBARRIER_SIZE, + .type = MT_DEVICE + }, { + .virtual = CF_VIRT, + .pfn = __phys_to_pfn(CF_PHYS), + .length = CF_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD02_VIRT, + .pfn = __phys_to_pfn(CPLD02_PHYS), + .length = CPLD02_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD06_VIRT, + .pfn = __phys_to_pfn(CPLD06_PHYS), + .length = CPLD06_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD08_VIRT, + .pfn = __phys_to_pfn(CPLD08_PHYS), + .length = CPLD08_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD0C_VIRT, + .pfn = __phys_to_pfn(CPLD0C_PHYS), + .length = CPLD0C_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD0E_VIRT, + .pfn = __phys_to_pfn(CPLD0E_PHYS), + .length = CPLD0E_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD10_VIRT, + .pfn = __phys_to_pfn(CPLD10_PHYS), + .length = CPLD10_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD12_VIRT, + .pfn = __phys_to_pfn(CPLD12_PHYS), + .length = CPLD12_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD14_VIRT, + .pfn = __phys_to_pfn(CPLD14_PHYS), + .length = CPLD14_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD16_VIRT, + .pfn = __phys_to_pfn(CPLD16_PHYS), + .length = CPLD16_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD18_VIRT, + .pfn = __phys_to_pfn(CPLD18_PHYS), + .length = CPLD18_SIZE, + .type = MT_DEVICE + }, { + .virtual = CPLD1A_VIRT, + .pfn = __phys_to_pfn(CPLD1A_PHYS), + .length = CPLD1A_SIZE, + .type = MT_DEVICE + }, /* This mapping is redundant since the smc driver performs another. */ /* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */ - { CPLD02_VIRT, CPLD02_PHYS, CPLD02_SIZE, MT_DEVICE }, - { CPLD06_VIRT, CPLD06_PHYS, CPLD06_SIZE, MT_DEVICE }, - { CPLD08_VIRT, CPLD08_PHYS, CPLD08_SIZE, MT_DEVICE }, - { CPLD0C_VIRT, CPLD0C_PHYS, CPLD0C_SIZE, MT_DEVICE }, - { CPLD0E_VIRT, CPLD0E_PHYS, CPLD0E_SIZE, MT_DEVICE }, - { CPLD10_VIRT, CPLD10_PHYS, CPLD10_SIZE, MT_DEVICE }, - { CPLD12_VIRT, CPLD12_PHYS, CPLD12_SIZE, MT_DEVICE }, - { CPLD14_VIRT, CPLD14_PHYS, CPLD14_SIZE, MT_DEVICE }, - { CPLD16_VIRT, CPLD16_PHYS, CPLD16_SIZE, MT_DEVICE }, - { CPLD18_VIRT, CPLD18_PHYS, CPLD18_SIZE, MT_DEVICE }, - { CPLD1A_VIRT, CPLD1A_PHYS, CPLD1A_SIZE, MT_DEVICE }, }; void __init From 9fe133b149e8a48742a64b72f22041bcd31fe827 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:00 +0100 Subject: [PATCH 0545/1940] [ARM] 2987/1: Replace map_desc.physical with map_desc.pfn: OMAP Patch from Deepak Saxena OMAP map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-omap1/board-innovator.c | 8 +++-- arch/arm/mach-omap1/board-perseus2.c | 8 +++-- arch/arm/mach-omap1/io.c | 46 +++++++++++++++++++++++---- arch/arm/plat-omap/sram.c | 6 +++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index df0312b596e4..fd9183ff2ed5 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -103,8 +103,12 @@ static struct platform_device innovator_flash_device = { /* Only FPGA needs to be mapped here. All others are done with ioremap */ static struct map_desc innovator1510_io_desc[] __initdata = { -{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE, - MT_DEVICE }, + { + .virtual = OMAP1510_FPGA_BASE, + .pfn = __phys_to_pfn(OMAP1510_FPGA_START), + .length = OMAP1510_FPGA_SIZE, + .type = MT_DEVICE + } }; static struct resource innovator1510_smc91x_resources[] = { diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 107c68c8ab54..2ba26e239108 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -134,8 +134,12 @@ void omap_perseus2_init_irq(void) /* Only FPGA needs to be mapped here. All others are done with ioremap */ static struct map_desc omap_perseus2_io_desc[] __initdata = { - {H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE, - MT_DEVICE}, + { + .virtual = H2P2_DBG_FPGA_BASE, + .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START), + .length = H2P2_DBG_FPGA_SIZE, + .type = MT_DEVICE + } }; static void __init omap_perseus2_map_io(void) diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index eb8261d7dead..79fb86535ebc 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -26,27 +26,59 @@ extern void omap_sram_init(void); * default mapping provided here. */ static struct map_desc omap_io_desc[] __initdata = { - { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + } }; #ifdef CONFIG_ARCH_OMAP730 static struct map_desc omap730_io_desc[] __initdata = { - { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE }, - { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE }, + { + .virtual = OMAP730_DSP_BASE, + .pfn = __phys_to_pfn(OMAP730_DSP_START), + .length = OMAP730_DSP_SIZE, + .type = MT_DEVICE + }, { + .virtual = OMAP730_DSPREG_BASE, + .pfn = __phys_to_pfn(OMAP730_DSPREG_START), + .length = OMAP730_DSPREG_SIZE, + .type = MT_DEVICE + } }; #endif #ifdef CONFIG_ARCH_OMAP1510 static struct map_desc omap1510_io_desc[] __initdata = { - { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE }, - { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE }, + { + .virtual = OMAP1510_DSP_BASE, + .pfn = __phys_to_pfn(OMAP1510_DSP_START), + .length = OMAP1510_DSP_SIZE, + .type = MT_DEVICE + }, { + .virtual = OMAP1510_DSPREG_BASE, + .pfn = __phys_to_pfn(OMAP1510_DSPREG_START), + .length = OMAP1510_DSPREG_SIZE, + .type = MT_DEVICE + } }; #endif #if defined(CONFIG_ARCH_OMAP16XX) static struct map_desc omap16xx_io_desc[] __initdata = { - { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, - { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, + { + .virtual = OMAP16XX_DSP_BASE, + .pfn = __phys_to_pfn(OMAP16XX_DSP_START), + .length = OMAP16XX_DSP_SIZE, + .type = MT_DEVICE + }, { + .virtual = OMAP16XX_DSPREG_BASE, + .pfn = __phys_to_pfn(OMAP16XX_DSPREG_START), + .length = OMAP16XX_DSPREG_SIZE, + .type = MT_DEVICE + } }; #endif diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 7719a4062e3a..7ad69f14a3e7 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -59,7 +59,11 @@ void __init omap_detect_sram(void) } static struct map_desc omap_sram_io_desc[] __initdata = { - { OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE } + { /* .length gets filled in at runtime */ + .virtual = OMAP1_SRAM_BASE, + .pfn = __phys_to_pfn(OMAP1_SRAM_START), + .type = MT_DEVICE + } }; /* From 6f9182eb32a4e6c46813928bee50df71e3fd1c74 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:01 +0100 Subject: [PATCH 0546/1940] [ARM] 2988/1: Replace map_desc.physical with map_desc.pfn: PXA Patch from Deepak Saxena PXA map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 44 ++++++++++++++++++++++++++++------- arch/arm/mach-pxa/idp.c | 21 +++++++++-------- arch/arm/mach-pxa/lubbock.c | 7 +++++- arch/arm/mach-pxa/mainstone.c | 7 +++++- 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 1d7677669a76..2e9e1702c4b3 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -92,14 +92,42 @@ EXPORT_SYMBOL(pxa_set_cken); * and cache flush area. */ static struct map_desc standard_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */ - { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */ - { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */ - { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */ - { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */ - { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */ - { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */ + { /* Devs */ + .virtual = 0xf2000000, + .pfn = __phys_to_pfn(0x40000000), + .length = 0x02000000, + .type = MT_DEVICE + }, { /* LCD */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x44000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* Mem Ctl */ + .virtual = 0xf6000000, + .pfn = __phys_to_pfn(0x48000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* USB host */ + .virtual = 0xf8000000, + .pfn = __phys_to_pfn(0x4c000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* Camera */ + .virtual = 0xfa000000, + .pfn = __phys_to_pfn(0x50000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* IMem ctl */ + .virtual = 0xfe000000, + .pfn = __phys_to_pfn(0x58000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* UNCACHED_PHYS_0 */ + .virtual = 0xff000000, + .pfn = __phys_to_pfn(0x00000000), + .length = 0x00100000, + .type = MT_DEVICE + } }; void __init pxa_map_io(void) diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 386e107b53cc..01a83ab09ac3 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -152,16 +152,17 @@ static void __init idp_init_irq(void) } static struct map_desc idp_io_desc[] __initdata = { - /* virtual physical length type */ - - { IDP_COREVOLT_VIRT, - IDP_COREVOLT_PHYS, - IDP_COREVOLT_SIZE, - MT_DEVICE }, - { IDP_CPLD_VIRT, - IDP_CPLD_PHYS, - IDP_CPLD_SIZE, - MT_DEVICE } + { + .virtual = IDP_COREVOLT_VIRT, + .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS), + .length = IDP_COREVOLT_SIZE, + .type = MT_DEVICE + }, { + .virtual = IDP_CPLD_VIRT, + .pfn = __phys_to_pfn(IDP_CPLD_PHYS), + .length = IDP_CPLD_SIZE, + .type = MT_DEVICE + } }; static void __init idp_map_io(void) diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 1f38033921e9..69abc7f61ed0 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -246,7 +246,12 @@ static void __init lubbock_init(void) } static struct map_desc lubbock_io_desc[] __initdata = { - { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ + { /* CPLD */ + .virtual = LUBBOCK_FPGA_VIRT, + .pfn = __phys_to_pfn(LUBBOCK_FPGA_PHYS), + .length = 0x00100000, + .type = MT_DEVICE + } }; static void __init lubbock_map_io(void) diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 85fdb5b1470a..8b4a21623fc0 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -317,7 +317,12 @@ static void __init mainstone_init(void) static struct map_desc mainstone_io_desc[] __initdata = { - { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ + { /* CPLD */ + .virtual = MST_FPGA_VIRT, + .pfn = __phys_to_pfn(MST_FPGA_PHYS), + .length = 0x00100000, + .type = MT_DEVICE + } }; static void __init mainstone_map_io(void) From f9258f226baf663099acb7972287ea0e26ce05a7 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:02 +0100 Subject: [PATCH 0547/1940] [ARM] 2989/1: Replace map_desc.physical with map_desc.pfn: RiscPC Patch from Deepak Saxena RiscPC map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-rpc/riscpc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index e3587efec4bf..5c4ac1c008a6 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -61,9 +61,22 @@ static int __init parse_tag_acorn(const struct tag *tag) __tagtable(ATAG_ACORN, parse_tag_acorn); static struct map_desc rpc_io_desc[] __initdata = { - { SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */ - { (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */ - { EASI_BASE, EASI_START, EASI_SIZE, MT_DEVICE } /* EASI space */ + { /* VRAM */ + .virtual = SCREEN_BASE, + .pfn = __phys_to_pfn(SCREEN_START), + .length = 2*1048576, + .type = MT_DEVICE + }, { /* IO space */ + .virtual = (u32)IO_BASE, + .pfn = __phys_to_pfn(IO_START), + .length = IO_SIZE , + .type = MT_DEVICE + }, { /* EASI space */ + .virtual = EASI_BASE, + .pfn = __phys_to_pfn(EASI_START), + .length = EASI_SIZE, + .type = MT_DEVICE + } }; static void __init rpc_map_io(void) From 1cc977a76642b1eec2ab4ba80a6f0db9a63a091e Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:02 +0100 Subject: [PATCH 0548/1940] [ARM] 2990/1: Replace map_desc.physical with map_desc.pfn: S3C2410 Patch from Deepak Saxena S3C2410 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-s3c2410/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h index 478c15c0e36a..9cbe5eef492b 100644 --- a/arch/arm/mach-s3c2410/cpu.h +++ b/arch/arm/mach-s3c2410/cpu.h @@ -21,7 +21,7 @@ /* todo - fix when rmk changes iodescs to use `void __iomem *` */ -#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE } +#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C2410_PA_##x), S3C24XX_SZ_##x, MT_DEVICE } #ifndef MHZ #define MHZ (1000*1000) From cd5fc8bffd70b2d87953334b6195db4bc2125ff9 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:03 +0100 Subject: [PATCH 0549/1940] [ARM] 2991/1: Replace map_desc.physical with map_desc.pfn: Shark Patch from Deepak Saxena Shark map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-shark/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index 946c0d11c73b..2d428b6dbb58 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -62,7 +62,12 @@ arch_initcall(shark_init); extern void shark_init_irq(void); static struct map_desc shark_io_desc[] __initdata = { - { IO_BASE , IO_START , IO_SIZE , MT_DEVICE } + { + .virtual = IO_BASE, + .pfn = __phys_to_pfn(IO_START), + .length = IO_SIZE, + .type = MT_DEVICE + } }; static void __init shark_map_io(void) From 92519d82828a93743adc31202927f411601c0d04 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:04 +0100 Subject: [PATCH 0550/1940] [ARM] 2992/1: Replace map_desc.physical with map_desc.pfn: SA1100 Patch from Deepak Saxena SA1100 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-sa1100/assabet.c | 14 +++++++++++--- arch/arm/mach-sa1100/badge4.c | 20 ++++++++++++++++---- arch/arm/mach-sa1100/cerf.c | 8 ++++++-- arch/arm/mach-sa1100/collie.c | 14 +++++++++++--- arch/arm/mach-sa1100/generic.c | 26 +++++++++++++++++++++----- arch/arm/mach-sa1100/h3600.c | 20 ++++++++++++++++---- arch/arm/mach-sa1100/hackkit.c | 8 ++++++-- arch/arm/mach-sa1100/jornada720.c | 20 ++++++++++++++++---- arch/arm/mach-sa1100/lart.c | 14 +++++++++++--- arch/arm/mach-sa1100/neponset.c | 14 +++++++++++--- arch/arm/mach-sa1100/simpad.c | 16 +++++++++++----- 11 files changed, 136 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 24687f511bf5..75efb5da5b6d 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -388,9 +388,17 @@ static struct sa1100_port_fns assabet_port_fns __initdata = { }; static struct map_desc assabet_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf1000000, 0x12000000, 0x00100000, MT_DEVICE }, /* Board Control Register */ - { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE } /* MQ200 */ + { /* Board Control Register */ + .virtual = 0xf1000000, + .pfn = __phys_to_pfn(0x12000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* MQ200 */ + .virtual = 0xf2800000, + .pfn = __phys_to_pfn(0x4b800000), + .length = 0x00800000, + .type = MT_DEVICE + } }; static void __init assabet_map_io(void) diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index b6169cb09196..c92cebff7f8e 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -254,10 +254,22 @@ EXPORT_SYMBOL(badge4_set_5V); static struct map_desc badge4_io_desc[] __initdata = { - /* virtual physical length type */ - {0xf1000000, 0x08000000, 0x00100000, MT_DEVICE },/* SRAM bank 1 */ - {0xf2000000, 0x10000000, 0x00100000, MT_DEVICE },/* SRAM bank 2 */ - {0xf4000000, 0x48000000, 0x00100000, MT_DEVICE } /* SA-1111 */ + { /* SRAM bank 1 */ + .virtual = 0xf1000000, + .pfn = __phys_to_pfn(0x08000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* SRAM bank 2 */ + .virtual = 0xf2000000, + .pfn = __phys_to_pfn(0x10000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x48000000), + .length = 0x00100000, + .type = MT_DEVICE + } }; static void diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 9484be7dc671..23cb74885275 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -100,8 +100,12 @@ static void __init cerf_init_irq(void) } static struct map_desc cerf_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE } /* Crystal Ethernet Chip */ + { /* Crystal Ethernet Chip */ + .virtual = 0xf0000000, + .pfn = __phys_to_pfn(0x08000000), + .length = 0x00100000, + .type = MT_DEVICE + } }; static void __init cerf_map_io(void) diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 6ecab7e2c238..7fd6e29c36b7 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -171,9 +171,17 @@ static void __init collie_init(void) } static struct map_desc collie_io_desc[] __initdata = { - /* virtual physical length type */ - {0xe8000000, 0x00000000, 0x02000000, MT_DEVICE}, /* 32M main flash (cs0) */ - {0xea000000, 0x08000000, 0x02000000, MT_DEVICE}, /* 32M boot flash (cs1) */ + { /* 32M main flash (cs0) */ + .virtual = 0xe8000000, + .pfn = __phys_to_pfn(0x00000000), + .length = 0x02000000, + .type = MT_DEVICE + }, { /* 32M boot flash (cs1) */ + .virtual = 0xea000000, + .pfn = __phys_to_pfn(0x08000000), + .length = 0x02000000, + .type = MT_DEVICE + } }; static void __init collie_map_io(void) diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 3f1e358455e5..93619497779c 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -369,11 +369,27 @@ EXPORT_SYMBOL(sa1100fb_lcd_power); */ static struct map_desc standard_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */ - { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */ - { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */ - { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE } /* LCD + DMA */ + { /* PCM */ + .virtual = 0xf8000000, + .pfn = __phys_to_pfn(0x80000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* SCM */ + .virtual = 0xfa000000, + .pfn = __phys_to_pfn(0x90000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* MER */ + .virtual = 0xfc000000, + .pfn = __phys_to_pfn(0xa0000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* LCD + DMA */ + .virtual = 0xfe000000, + .pfn = __phys_to_pfn(0xb0000000), + .length = 0x00200000, + .type = MT_DEVICE + }, }; void __init sa1100_map_io(void) diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index e7aa2681ca64..e8352b7f74b0 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -223,10 +223,22 @@ static void h3xxx_lcd_power(int enable) } static struct map_desc h3600_io_desc[] __initdata = { - /* virtual physical length type */ - { H3600_BANK_2_VIRT, SA1100_CS2_PHYS, 0x02800000, MT_DEVICE }, /* static memory bank 2 CS#2 */ - { H3600_BANK_4_VIRT, SA1100_CS4_PHYS, 0x00800000, MT_DEVICE }, /* static memory bank 4 CS#4 */ - { H3600_EGPIO_VIRT, H3600_EGPIO_PHYS, 0x01000000, MT_DEVICE }, /* EGPIO 0 CS#5 */ + { /* static memory bank 2 CS#2 */ + .virtual = H3600_BANK_2_VIRT, + .pfn = __phys_to_pfn(SA1100_CS2_PHYS), + .length = 0x02800000, + .type = MT_DEVICE + }, { /* static memory bank 4 CS#4 */ + .virtual = H3600_BANK_4_VIRT, + .pfn = __phys_to_pfn(SA1100_CS4_PHYS), + .length = 0x00800000, + .type = MT_DEVICE + }, { /* EGPIO 0 CS#5 */ + .virtual = H3600_EGPIO_VIRT, + .pfn = __phys_to_pfn(H3600_EGPIO_PHYS), + .length = 0x01000000, + .type = MT_DEVICE + } }; /* diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index 502d65cfe654..c922e043c424 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -57,8 +57,12 @@ static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate) */ static struct map_desc hackkit_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */ + { /* Flash bank 0 */ + .virtual = 0xe8000000, + .pfn = __phys_to_pfn(0x00000000), + .length = 0x01000000, + .type = MT_DEVICE + }, }; static struct sa1100_port_fns hackkit_port_fns __initdata = { diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 2f497112c96a..9c363bfcf310 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -81,10 +81,22 @@ static int __init jornada720_init(void) arch_initcall(jornada720_init); static struct map_desc jornada720_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf0000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Epson registers */ - { 0xf1000000, 0x48200000, 0x00100000, MT_DEVICE }, /* Epson frame buffer */ - { 0xf4000000, 0x40000000, 0x00100000, MT_DEVICE } /* SA-1111 */ + { /* Epson registers */ + .virtual = 0xf0000000, + .pfn = __phys_to_pfn(0x48000000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* Epson frame buffer */ + .virtual = 0xf1000000, + .pfn = __phys_to_pfn(0x48200000), + .length = 0x00100000, + .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x40000000), + .length = 0x00100000, + .type = MT_DEVICE + } }; static void __init jornada720_map_io(void) diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index ed6744d480af..8c9e3dd52942 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -31,9 +31,17 @@ static void __init lart_init(void) } static struct map_desc lart_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xe8000000, 0x00000000, 0x00400000, MT_DEVICE }, /* main flash memory */ - { 0xec000000, 0x08000000, 0x00400000, MT_DEVICE } /* main flash, alternative location */ + { /* main flash memory */ + .virtual = 0xe8000000, + .pfn = __phys_to_pfn(0x00000000), + .length = 0x00400000, + .type = MT_DEVICE + }, { /* main flash, alternative location */ + .virtual = 0xec000000, + .pfn = __phys_to_pfn(0x08000000), + .length = 0x00400000, + .type = MT_DEVICE + } }; static void __init lart_map_io(void) diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index fc061641b7be..0c5eff3bdc09 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -331,9 +331,17 @@ static int __init neponset_init(void) subsys_initcall(neponset_init); static struct map_desc neponset_io_desc[] __initdata = { - /* virtual physical length type */ - { 0xf3000000, 0x10000000, SZ_1M, MT_DEVICE }, /* System Registers */ - { 0xf4000000, 0x40000000, SZ_1M, MT_DEVICE } /* SA-1111 */ + { /* System Registers */ + .virtual = 0xf3000000, + .pfn = __phys_to_pfn(0x10000000), + .length = SZ_1M, + .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x40000000), + .length = SZ_1M, + .type = MT_DEVICE + } }; void __init neponset_map_io(void) diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 07f6d5fd7bb0..cfb6658e5cdf 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -60,11 +60,17 @@ EXPORT_SYMBOL(set_cs3_bit); EXPORT_SYMBOL(clear_cs3_bit); static struct map_desc simpad_io_desc[] __initdata = { - /* virtual physical length type */ - /* MQ200 */ - { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE }, - /* Paules CS3, write only */ - { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE }, + { /* MQ200 */ + .virtual = 0xf2800000, + .pfn = __phys_to_pfn(0x4b800000), + .length = 0x00800000, + .type = MT_DEVICE + }, { /* Paules CS3, write only */ + .virtual = 0xf1000000, + .pfn = __phys_to_pfn(0x18000000), + .length = 0x00100000, + .type = MT_DEVICE + }, }; From f10083f5a6f4a2735cca3a8c762457272ea66bf0 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:05 +0100 Subject: [PATCH 0551/1940] [ARM] 2993/1: Replace map_desc.physical with map_desc.pfn: CLPS711x Patch from Deepak Saxena CLSP711x map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-clps711x/autcpu12.c | 12 ++++++++---- arch/arm/mach-clps711x/cdb89712.c | 7 ++++++- arch/arm/mach-clps711x/ceiva.c | 12 +++++++----- arch/arm/mach-clps711x/edb7211-mm.c | 30 ++++++++++++++++++++--------- arch/arm/mach-clps711x/mm.c | 8 +++++++- arch/arm/mach-clps711x/p720t.c | 14 ++++++++++++-- 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index dc73feb1ffb0..43b9423d1440 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -46,10 +46,14 @@ */ static struct map_desc autcpu12_io_desc[] __initdata = { - /* virtual, physical, length, type */ - /* memory-mapped extra io and CS8900A Ethernet chip */ - /* ethernet chip */ - { AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, MT_DEVICE } + /* memory-mapped extra io and CS8900A Ethernet chip */ + /* ethernet chip */ + { + .virtual = AUTCPU12_VIRT_CS8900A, + .pfn = __phys_to_pfn(AUTCPU12_PHYS_CS8900A), + .length = SZ_1M, + .type = MT_DEVICE + } }; void __init autcpu12_map_io(void) diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index a46c82cd2711..cba7be5a06c3 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -39,7 +39,12 @@ * ethernet driver, perhaps. */ static struct map_desc cdb89712_io_desc[] __initdata = { - { ETHER_BASE, ETHER_START, ETHER_SIZE, MT_DEVICE } + { + .virtual = ETHER_BASE, + .pfn =__phys_to_pfn(ETHER_START), + .length = ETHER_SIZE, + .type = MT_DEVICE + } }; static void __init cdb89712_map_io(void) diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index 780d91805984..35d51a759b59 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c @@ -37,11 +37,13 @@ #include "common.h" static struct map_desc ceiva_io_desc[] __initdata = { - /* virtual, physical, length, type */ - - /* SED1355 controlled video RAM & registers */ - { CEIVA_VIRT_SED1355, CEIVA_PHYS_SED1355, SZ_2M, MT_DEVICE } - + /* SED1355 controlled video RAM & registers */ + { + .virtual = CEIVA_VIRT_SED1355, + .pfn = __phys_to_pfn(CEIVA_PHYS_SED1355), + .length = SZ_2M, + .type = MT_DEVICE + } }; diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c index 7fd7b01822d0..72f8bb05d55e 100644 --- a/arch/arm/mach-clps711x/edb7211-mm.c +++ b/arch/arm/mach-clps711x/edb7211-mm.c @@ -51,15 +51,27 @@ extern void clps711x_map_io(void); * happens). */ static struct map_desc edb7211_io_desc[] __initdata = { - /* virtual, physical, length, type */ - - /* memory-mapped extra keyboard row and CS8900A Ethernet chip */ - { EP7211_VIRT_EXTKBD, EP7211_PHYS_EXTKBD, SZ_1M, MT_DEVICE }, - { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, SZ_1M, MT_DEVICE }, - - /* flash banks */ - { EP7211_VIRT_FLASH1, EP7211_PHYS_FLASH1, SZ_8M, MT_DEVICE }, - { EP7211_VIRT_FLASH2, EP7211_PHYS_FLASH2, SZ_8M, MT_DEVICE } + { /* memory-mapped extra keyboard row */ + .virtual = EP7211_VIRT_EXTKBD, + .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD), + .length = SZ_1M, + .type - MT_DEVICE + }, { /* and CS8900A Ethernet chip */ + .virtual = EP7211_VIRT_CS8900A, + .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A), + .length = SZ_1M, + .type = MT_DEVICE + }, { /* flash banks */ + .virtual = EP7211_VIRT_FLASH1, + .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1), + .length = SZ_8M, + .type = MT_DEVICE + }, { + .virtual = EP7211_VIRT_FLASH2, + .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2), + .length = SZ_8M, + .type = MT_DEVICE + } }; void __init edb7211_map_io(void) diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c index 120b7cac84b5..a00f77ef8df8 100644 --- a/arch/arm/mach-clps711x/mm.c +++ b/arch/arm/mach-clps711x/mm.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,12 @@ * This maps the generic CLPS711x registers */ static struct map_desc clps711x_io_desc[] __initdata = { - { CLPS7111_VIRT_BASE, CLPS7111_PHYS_BASE, 1048576, MT_DEVICE } + { + .virtual = CLPS7111_VIRT_BASE, + .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE), + .length = SZ_1M, + .type = MT_DEVICE + } }; void __init clps711x_map_io(void) diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index 5bdb90edf992..a1acb945fb51 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,17 @@ * We map both here. */ static struct map_desc p720t_io_desc[] __initdata = { - { SYSPLD_VIRT_BASE, SYSPLD_PHYS_BASE, 1048576, MT_DEVICE }, - { 0xfe400000, 0x10400000, 1048576, MT_DEVICE } + { + .virtual = SYSPLD_VIRT_BASE, + .pfn = __phys_to_pfn(SYSPLD_PHYS_BASE), + .length = SZ_1M, + .type = MT_DEVICE + }, { + .virtual = 0xfe400000, + .pfn = __phys_to_pfn(0x10400000), + .length = SZ_1M, + .type = MT_DEVICE + } }; static void __init From d157e9ecec59383a676d676e2bb39367430396a2 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:05 +0100 Subject: [PATCH 0552/1940] [ARM] 2994/1: Replace map_desc.physical with map_desc.pfn: CLPS7500 Patch from Deepak Saxena CLSP7500 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-clps7500/core.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index e216ab8b9e8f..0364ba4b539e 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -259,10 +259,27 @@ static void __init clps7500_init_irq(void) } static struct map_desc cl7500_io_desc[] __initdata = { - { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, /* IO space */ - { ISA_BASE, ISA_START, ISA_SIZE, MT_DEVICE }, /* ISA space */ - { FLASH_BASE, FLASH_START, FLASH_SIZE, MT_DEVICE }, /* Flash */ - { LED_BASE, LED_START, LED_SIZE, MT_DEVICE } /* LED */ + { /* IO space */ + .virtual = IO_BASE, + .pfn = __phys_to_pfn(IO_START), + .length = IO_SIZE, + .type = MT_DEVICE + }, { /* ISA space */ + .virtual = ISA_BASE, + .pfn = __phys_to_pfn(ISA_START), + .length = ISA_SIZE, + .type = MT_DEVICE + }, { /* Flash */ + .virtual = FLASH_BASE, + .pfn = __phys_to_pfn(FLASH_START), + .length = FLASH_SIZE, + .type = MT_DEVICE + }, { /* LED */ + .virtual = LED_BASE, + .pfn = __phys_to_pfn(LED_START), + .length = LED_SIZE, + .type = MT_DEVICE + } }; static void __init clps7500_map_io(void) From 1311521fb1b8ebbb0b470d028df13f2cbc643e51 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:06 +0100 Subject: [PATCH 0553/1940] [ARM] 2995/1: Replace map_desc.physical with map_desc.pfn: Versatile Patch from Deepak Saxena Versatile map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-versatile/core.c | 83 ++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a30e0451df72..7e4bdd07f4af 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -186,25 +186,82 @@ void __init versatile_init_irq(void) } static struct map_desc versatile_io_desc[] __initdata = { - { IO_ADDRESS(VERSATILE_SYS_BASE), VERSATILE_SYS_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(VERSATILE_SIC_BASE), VERSATILE_SIC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(VERSATILE_VIC_BASE), VERSATILE_VIC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(VERSATILE_SCTL_BASE), VERSATILE_SCTL_BASE, SZ_4K * 9, MT_DEVICE }, + { + .virtual = IO_ADDRESS(VERSATILE_SYS_BASE), + .pfn = __phys_to_pfn(VERSATILE_SYS_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(VERSATILE_SIC_BASE), + .pfn = __phys_to_pfn(VERSATILE_SIC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(VERSATILE_VIC_BASE), + .pfn = __phys_to_pfn(VERSATILE_VIC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE), + .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE), + .length = SZ_4K * 9, + .type = MT_DEVICE + }, #ifdef CONFIG_MACH_VERSATILE_AB - { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(VERSATILE_IB2_BASE), VERSATILE_IB2_BASE, SZ_64M, MT_DEVICE }, + { + .virtual = IO_ADDRESS(VERSATILE_GPIO0_BASE), + .pfn = __phys_to_pfn(VERSATILE_GPIO0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(VERSATILE_IB2_BASE), + .pfn = __phys_to_pfn(VERSATILE_IB2_BASE), + .length = SZ_64M, + .type = MT_DEVICE + }, #endif #ifdef CONFIG_DEBUG_LL - { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE }, + { + .virtual = IO_ADDRESS(VERSATILE_UART0_BASE), + .pfn = __phys_to_pfn(VERSATILE_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, #endif #ifdef CONFIG_PCI - { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE }, - { VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE }, - { VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE }, + { + .virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE), + .pfn = __phys_to_pfn(VERSATILE_PCI_CORE_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_VIRT_BASE, + .pfn = __phys_to_pfn(VERSATILE_PCI_BASE), + .length = VERSATILE_PCI_BASE_SIZE, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_CFG_VIRT_BASE, + .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), + .length = VERSATILE_PCI_CFG_BASE_SIZE, + .type = MT_DEVICE + }, #if 0 - { VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE }, - { VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE }, - { VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE }, + { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE0, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE1, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE2, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2), + .length = SZ_16M, + .type = MT_DEVICE + }, #endif #endif }; From 7a557e246f5c24f4c7218f41f8caf03c492f40f9 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:07 +0100 Subject: [PATCH 0554/1940] [ARM] 2996/1: Replace map_desc.physical with map_desc.pfn: EPXA10DB Patch from Deepak Saxena EPXA10DB mapd_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-epxa10db/mm.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c index 2aa57fa46da3..e8832d0910ee 100644 --- a/arch/arm/mach-epxa10db/mm.c +++ b/arch/arm/mach-epxa10db/mm.c @@ -31,12 +31,37 @@ /* Page table mapping for I/O region */ static struct map_desc epxa10db_io_desc[] __initdata = { - { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_16K, MT_DEVICE }, - { IO_ADDRESS(EXC_PLD_BLOCK0_BASE), EXC_PLD_BLOCK0_BASE, SZ_16K, MT_DEVICE }, - { IO_ADDRESS(EXC_PLD_BLOCK1_BASE), EXC_PLD_BLOCK1_BASE, SZ_16K, MT_DEVICE }, - { IO_ADDRESS(EXC_PLD_BLOCK2_BASE), EXC_PLD_BLOCK2_BASE, SZ_16K, MT_DEVICE }, - { IO_ADDRESS(EXC_PLD_BLOCK3_BASE), EXC_PLD_BLOCK3_BASE, SZ_16K, MT_DEVICE }, - { FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE, SZ_16M, MT_DEVICE } + { + .virtual = IO_ADDRESS(EXC_REGISTERS_BASE), + .pfn = __phys_to_pfn(EXC_REGISTERS_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(EXC_PLD_BLOCK0_BASE), + .pfn = __phys_to_pfn(EXC_PLD_BLOCK0_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(EXC_PLD_BLOCK1_BASE), + .pfn =__phys_to_pfn(EXC_PLD_BLOCK1_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(EXC_PLD_BLOCK2_BASE), + .physical = __phys_to_pfn(EXC_PLD_BLOCK2_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(EXC_PLD_BLOCK3_BASE), + .pfn = __phys_to_pfn(EXC_PLD_BLOCK3_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, { + .virtual = FLASH_VADDR(EXC_EBI_BLOCK0_BASE), + .pfn = __phys_to_pfn(EXC_EBI_BLOCK0_BASE), + .length = SZ_16M, + .type = MT_DEVICE + } }; void __init epxa10db_map_io(void) From 6cb1907c1a88563c84123c923b46424ea68b53eb Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:08 +0100 Subject: [PATCH 0555/1940] [ARM] 2997/1: Replace map_desc.physical with map_desc.pfn: EBSA110 Patch from Deepak Saxena EBSA110 map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ebsa110/core.c | 38 ++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 5aeadfd72143..15261646dcdd 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -76,16 +76,42 @@ static struct map_desc ebsa110_io_desc[] __initdata = { /* * sparse external-decode ISAIO space */ - { IRQ_STAT, TRICK4_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_STAT/IRQ_MCLR */ - { IRQ_MASK, TRICK3_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_MASK/IRQ_MSET */ - { SOFT_BASE, TRICK1_PHYS, PGDIR_SIZE, MT_DEVICE }, /* SOFT_BASE */ - { PIT_BASE, TRICK0_PHYS, PGDIR_SIZE, MT_DEVICE }, /* PIT_BASE */ + { /* IRQ_STAT/IRQ_MCLR */ + .virtual = IRQ_STAT, + .pfn = __phys_to_pfn(TRICK4_PHYS), + .length = PGDIR_SIZE, + .type = MT_DEVICE + }, { /* IRQ_MASK/IRQ_MSET */ + .virtual = IRQ_MASK, + .pfn = __phys_to_pfn(TRICK3_PHYS), + .length = PGDIR_SIZE, + .type = MT_DEVICE + }, { /* SOFT_BASE */ + .virtual = SOFT_BASE, + .pfn = __phys_to_pfn(TRICK1_PHYS), + .length = PGDIR_SIZE, + .type = MT_DEVICE + }, { /* PIT_BASE */ + .virtual = PIT_BASE, + .pfn = __phys_to_pfn(TRICK0_PHYS), + .length = PGDIR_SIZE, + .type = MT_DEVICE + }, /* * self-decode ISAIO space */ - { ISAIO_BASE, ISAIO_PHYS, ISAIO_SIZE, MT_DEVICE }, - { ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, MT_DEVICE } + { + .virtual = ISAIO_BASE, + .pfn = __phys_to_pfn(ISAIO_PHYS), + .length = ISAIO_SIZE, + .type = MT_DEVICE + }, { + .virtual = ISAMEM_BASE, + .pfn = __phys_to_pfn(ISAMEM_PHYS), + .length = ISAMEM_SIZE, + .type = MT_DEVICE + } }; static void __init ebsa110_map_io(void) From a427ceef934d8162c8c61d152e969bc3ec21a4e5 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:08 +0100 Subject: [PATCH 0556/1940] [ARM] 2998/1: Replace map_desc.physical with map_desc.pfn: Footbridge Patch from Deepak Saxena Footbridge map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-footbridge/common.c | 57 ++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index eb8238c1ef06..dc09fd200c16 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -130,8 +130,17 @@ void __init footbridge_init_irq(void) * it means that we have extra bullet protection on our feet. */ static struct map_desc fb_common_io_desc[] __initdata = { - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, MT_DEVICE }, - { XBUS_BASE, 0x40000000, XBUS_SIZE, MT_DEVICE } + { + .virtual = ARMCSR_BASE, + .pfn = DC21285_ARMCSR_BASE, + .length = ARMCSR_SIZE, + .type = MT_DEVICE + }, { + .virtual = XBUS_BASE, + .pfn = __phys_to_pfn(0x40000000), + .length = XBUS_SIZE, + .type = MT_DEVICE + } }; /* @@ -140,11 +149,32 @@ static struct map_desc fb_common_io_desc[] __initdata = { */ static struct map_desc ebsa285_host_io_desc[] __initdata = { #if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST) - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE }, - { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, MT_DEVICE }, - { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, MT_DEVICE }, - { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, MT_DEVICE }, - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE } + { + .virtual = PCIMEM_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_MEM), + .length = PCIMEM_SIZE, + .type = MT_DEVICE + }, { + .virtual = PCICFG0_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG), + .length = PCICFG0_SIZE, + .type = MT_DEVICE + }, { + .virtual = PCICFG1_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG), + .length = PCICFG1_SIZE, + .type = MT_DEVICE + }, { + .virtual = PCIIACK_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_IACK), + .length = PCIIACK_SIZE, + .type = MT_DEVICE + }, { + .virtual = PCIO_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_IO), + .length = PCIO_SIZE, + .type = MT_DEVICE + } #endif }; @@ -153,8 +183,17 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = { */ static struct map_desc co285_io_desc[] __initdata = { #ifdef CONFIG_ARCH_CO285 - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE }, - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE } + { + .virtual = PCIO_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_IO), + .length = PCIO_SIZE, + .type = MT_DEVICE + }, { + .virtual = PCIMEM_BASE, + .pfn = __phys_to_pfn(DC21285_PCI_MEM), + .length = PCIMEM_SIZE, + .type = MT_DEVICE + } #endif }; From 3e9635e4060238549ffac239de34f6122b053653 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:09 +0100 Subject: [PATCH 0557/1940] [ARM] 2999/1: Replace map_desc.physical with map_desc.pfn: H720x Patch from Deepak Saxena H720x map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-h720x/common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index 5110e2e65ddd..c096b4569308 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -237,7 +237,12 @@ void __init h720x_init_irq (void) } static struct map_desc h720x_io_desc[] __initdata = { - { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, }; /* Initialize io tables */ From adecef744fc5b4e9316c851feec2a4d2640dd7ae Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:10 +0100 Subject: [PATCH 0558/1940] [ARM] 3000/1: Replace map_desc.physical with map_desc.pfn: iMX Patch from Deepak Saxena iMX map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-imx/generic.c | 8 ++++++-- arch/arm/mach-imx/mx1ads.c | 38 ++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index f8a742bb2d5b..cb14b0682cef 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -273,8 +273,12 @@ static struct platform_device *devices[] __initdata = { }; static struct map_desc imx_io_desc[] __initdata = { - /* virtual physical length type */ - {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE}, + { + .virtual = IMX_IO_BASE, + .pfn = __phys_to_pfn(IMX_IO_PHYS), + .length = IMX_IO_SIZE, + .type = MT_DEVICE + } }; void __init diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index a7511ddfe364..4cbdc1fe04b1 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -61,13 +61,37 @@ mx1ads_init(void) } static struct map_desc mx1ads_io_desc[] __initdata = { - /* virtual physical length type */ - {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE}, - {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE}, - {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE}, - {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE}, - {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE}, - {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE}, + { + .virtual = IMX_CS0_VIRT, + .pfn = __phys_to_pfn(IMX_CS0_PHYS), + .length = IMX_CS0_SIZE, + .type = MT_DEVICE + }, { + .virtual = IMX_CS1_VIRT, + .pfn = __phys_to_pfn(IMX_CS1_PHYS), + .length = IMX_CS1_SIZE, + .type = MT_DEVICE + }, { + .virtual = IMX_CS2_VIRT, + .pfn = __phys_to_pfn(IMX_CS2_PHYS), + .length = IMX_CS2_SIZE, + .type = MT_DEVICE + }, { + .virtual = IMX_CS3_VIRT, + .pfn = __phys_to_pfn(IMX_CS3_PHYS), + .length = IMX_CS3_SIZE, + .type = MT_DEVICE + }, { + .virtual = IMX_CS4_VIRT, + .pfn = __phys_to_pfn(IMX_CS4_PHYS), + .length = IMX_CS4_SIZE, + .type = MT_DEVICE + }, { + .virtual = IMX_CS5_VIRT, + .pfn = __phys_to_pfn(IMX_CS5_PHYS), + .length = IMX_CS5_SIZE, + .type = MT_DEVICE + } }; static void __init From c8d2729858d76de4ef7522c8171004fc1959cc44 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:10 +0100 Subject: [PATCH 0559/1940] [ARM] 3001/1: Replace map_desc.physical with map_desc.pfn: Integrator Patch from Deepak Saxena Integrator map_desc.pfn conversion Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-integrator/integrator_ap.c | 79 ++++++++++++++++++++---- arch/arm/mach-integrator/integrator_cp.c | 67 ++++++++++++++++---- 2 files changed, 122 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 36e2b6eb67b7..f368b85f0447 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -75,19 +75,72 @@ */ static struct map_desc ap_io_desc[] __initdata = { - { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, - { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, - { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE }, - { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE }, - { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE } + { + .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = PCI_MEMORY_VADDR, + .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE), + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = PCI_CONFIG_VADDR, + .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE), + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = PCI_V3_VADDR, + .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE), + .length = SZ_64K, + .type = MT_DEVICE + }, { + .virtual = PCI_IO_VADDR, + .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE), + .length = SZ_64K, + .type = MT_DEVICE + } }; static void __init ap_map_io(void) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 2be5c03ab87f..aa34c58b96c4 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -74,17 +74,62 @@ */ static struct map_desc intcp_io_desc[] __initdata = { - { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, - { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE }, - { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE }, + { + .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = 0xfca00000, + .pfn = __phys_to_pfn(0xca000000), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = 0xfcb00000, + .pfn = __phys_to_pfn(0xcb000000), + .length = SZ_4K, + .type = MT_DEVICE + } }; static void __init intcp_map_io(void) From 9769c2468d423a1562dd59a5db250bd0a5533ec9 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:11 +0100 Subject: [PATCH 0560/1940] [ARM] 3016/1: Replace map_desc.physical with map_desc.pfn Patch from Deepak Saxena Convert map_desc.physical to map_desc.pfn. This allows us to add support for 36-bit addressed physical devices in the static maps without having to resort to u64 variables. Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mm/init.c | 12 ++++++------ arch/arm/mm/mm-armv.c | 8 ++++---- include/asm-arm/mach/map.h | 5 ++++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index d1f1ec73500f..f4496813615a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -262,8 +262,8 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) if (end_pfn < end) end_pfn = end; - map.physical = mi->bank[i].start; - map.virtual = __phys_to_virt(map.physical); + map.pfn = __phys_to_pfn(mi->bank[i].start); + map.virtual = __phys_to_virt(mi->bank[i].start); map.length = mi->bank[i].size; map.type = MT_MEMORY; @@ -365,7 +365,7 @@ static void __init bootmem_init(struct meminfo *mi) #ifdef CONFIG_XIP_KERNEL #error needs fixing - p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; + p->pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PMD_MASK); p->virtual = (unsigned long)&_stext & PMD_MASK; p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; p->type = MT_ROM; @@ -439,14 +439,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) * Map the cache flushing regions. */ #ifdef FLUSH_BASE - map.physical = FLUSH_BASE_PHYS; + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); map.virtual = FLUSH_BASE; map.length = PGDIR_SIZE; map.type = MT_CACHECLEAN; create_mapping(&map); #endif #ifdef FLUSH_BASE_MINICACHE - map.physical = FLUSH_BASE_PHYS + PGDIR_SIZE; + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE); map.virtual = FLUSH_BASE_MINICACHE; map.length = PGDIR_SIZE; map.type = MT_MINICLEAN; @@ -464,7 +464,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) * location (0xffff0000). If we aren't using high-vectors, also * create a mapping at the low-vectors virtual address. */ - map.physical = virt_to_phys(vectors); + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); map.virtual = 0xffff0000; map.length = PAGE_SIZE; map.type = MT_HIGH_VECTORS; diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index c626361c0f5e..64db10e806b3 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -483,7 +483,7 @@ void __init create_mapping(struct map_desc *md) if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " "0x%08lx at 0x%08lx in user region\n", - md->physical, md->virtual); + __pfn_to_phys(md->pfn), md->virtual); return; } @@ -491,7 +491,7 @@ void __init create_mapping(struct map_desc *md) md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx " "overlaps vmalloc space\n", - md->physical, md->virtual); + __pfn_to_phys(md->pfn), md->virtual); } domain = mem_types[md->type].domain; @@ -500,14 +500,14 @@ void __init create_mapping(struct map_desc *md) prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); virt = md->virtual; - off = md->physical - virt; + off = __pfn_to_phys(md->pfn) - virt; length = md->length; if (mem_types[md->type].prot_l1 == 0 && (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " "be mapped using pages, ignoring.\n", - md->physical, md->virtual); + __pfn_to_phys(md->pfn), md->virtual); return; } diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h index 9ac47cf8d2e4..0619522bd926 100644 --- a/include/asm-arm/mach/map.h +++ b/include/asm-arm/mach/map.h @@ -11,7 +11,7 @@ */ struct map_desc { unsigned long virtual; - unsigned long physical; + unsigned long pfn; unsigned long length; unsigned int type; }; @@ -27,6 +27,9 @@ struct meminfo; #define MT_ROM 6 #define MT_IXP2000_DEVICE 7 +#define __phys_to_pfn(paddr) (paddr >> PAGE_SHIFT) +#define __pfn_to_phys(pfn) (pfn << PAGE_SHIFT) + extern void create_memmap_holes(struct meminfo *); extern void memtable_init(struct meminfo *); extern void iotable_init(struct map_desc *, int); From 0b7cd62ecdc1f09b7df4608a3fee644b1c27985b Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 28 Oct 2005 15:19:12 +0100 Subject: [PATCH 0561/1940] [ARM] 3017/1: Add support for 36-bit addresses to create_mapping() Patch from Deepak Saxena This patch adds support for 36-bit static mapped I/O. While there are no platforms in the tree ATM that use it, it has been tested tested on the IXP2350 NPU and I would like to get the support for that chipset upstream one piece at a time. There are also other Intel chipset ports in development that are waiting on this to go upstream. The patch replaces the print formats for physical addresses with %016llx which will create a bit extraneous output on 32-bit systems, but I think that is cleaner than having #ifdefs, specially since users will only see the output in error cases. Depends on 3016/1. Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mm/mm-armv.c | 58 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 64db10e806b3..61bc2fa0511e 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -478,20 +478,20 @@ void __init create_mapping(struct map_desc *md) unsigned long virt, length; int prot_sect, prot_l1, domain; pgprot_t prot_pte; - long off; + unsigned long off = (u32)__pfn_to_phys(md->pfn); if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " - "0x%08lx at 0x%08lx in user region\n", - __pfn_to_phys(md->pfn), md->virtual); + "0x%016llx at 0x%08lx in user region\n", + __pfn_to_phys((u64)md->pfn), md->virtual); return; } if ((md->type == MT_DEVICE || md->type == MT_ROM) && md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { - printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx " + printk(KERN_WARNING "BUG: mapping for 0x%016llx at 0x%08lx " "overlaps vmalloc space\n", - __pfn_to_phys(md->pfn), md->virtual); + __pfn_to_phys((u64)md->pfn), md->virtual); } domain = mem_types[md->type].domain; @@ -499,8 +499,33 @@ void __init create_mapping(struct map_desc *md) prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + /* + * Catch 36-bit addresses + */ + if(md->pfn >= 0x100000) { + if(domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%016llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + if((md->virtual | md->length | __pfn_to_phys(md->pfn)) + & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%016llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + } + virt = md->virtual; - off = __pfn_to_phys(md->pfn) - virt; + off -= virt; length = md->length; if (mem_types[md->type].prot_l1 == 0 && @@ -525,13 +550,22 @@ void __init create_mapping(struct map_desc *md) * of the actual domain assignments in use. */ if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) { - /* Align to supersection boundary */ - while ((virt & ~SUPERSECTION_MASK || (virt + off) & - ~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); + /* + * Align to supersection boundary if !high pages. + * High pages have already been checked for proper + * alignment above and they will fail the SUPSERSECTION_MASK + * check because of the way the address is encoded into + * offset. + */ + if (md->pfn <= 0x100000) { + while ((virt & ~SUPERSECTION_MASK || + (virt + off) & ~SUPERSECTION_MASK) && + length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } } while (length >= SUPERSECTION_SIZE) { From c09f98271f685af349d3f0199360f1c0e85550e0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 28 Oct 2005 15:26:40 +0100 Subject: [PATCH 0562/1940] [ARM] 2930/1: optimized sha1 implementation for ARM Patch from Nicolas Pitre Here's an ARM assembly SHA1 implementation to replace the default C version. It is approximately 50% faster than the generic C version. On an XScale processor running at 400MHz: generic C version: 9.8 MB/s my version: 14.5 MB/s This code is useful to quite a few callers in the tree: crypto/sha1.c: sha_transform(sctx->state, sctx->buffer, temp); crypto/sha1.c: sha_transform(sctx->state, &data[i], temp); drivers/char/random.c: sha_transform(buf, (__u8 *)r->pool+i, buf + 5); drivers/char/random.c: sha_transform(buf, (__u8 *)data, buf + 5); net/ipv4/syncookies.c: sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5); Signed-off-by: Nicolas Pitre Seems to work fine on big-endian as well. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/lib/Makefile | 2 +- arch/arm/lib/sha1.S | 206 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 arch/arm/lib/sha1.S diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 8725d63e4219..71e5b99e519e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o sha1.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o ifeq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S new file mode 100644 index 000000000000..ff6ece487ffc --- /dev/null +++ b/arch/arm/lib/sha1.S @@ -0,0 +1,206 @@ +/* + * linux/arch/arm/lib/sha1.S + * + * SHA transform optimized for ARM + * + * Copyright: (C) 2005 by Nicolas Pitre + * Created: September 17, 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The reference implementation for this code is linux/lib/sha1.c + */ + +#include + + .text + + +/* + * void sha_transform(__u32 *digest, const char *in, __u32 *W) + * + * Note: the "in" ptr may be unaligned. + */ + +ENTRY(sha_transform) + + stmfd sp!, {r4 - r8, lr} + + @ for (i = 0; i < 16; i++) + @ W[i] = be32_to_cpu(in[i]); */ + +#ifdef __ARMEB__ + mov r4, r0 + mov r0, r2 + mov r2, #64 + bl memcpy + mov r2, r0 + mov r0, r4 +#else + mov r3, r2 + mov lr, #16 +1: ldrb r4, [r1], #1 + ldrb r5, [r1], #1 + ldrb r6, [r1], #1 + ldrb r7, [r1], #1 + subs lr, lr, #1 + orr r5, r5, r4, lsl #8 + orr r6, r6, r5, lsl #8 + orr r7, r7, r6, lsl #8 + str r7, [r3], #4 + bne 1b +#endif + + @ for (i = 0; i < 64; i++) + @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31); + + sub r3, r2, #4 + mov lr, #64 +2: ldr r4, [r3, #4]! + subs lr, lr, #1 + ldr r5, [r3, #8] + ldr r6, [r3, #32] + ldr r7, [r3, #52] + eor r4, r4, r5 + eor r4, r4, r6 + eor r4, r4, r7 + mov r4, r4, ror #31 + str r4, [r3, #64] + bne 2b + + /* + * The SHA functions are: + * + * f1(B,C,D) = (D ^ (B & (C ^ D))) + * f2(B,C,D) = (B ^ C ^ D) + * f3(B,C,D) = ((B & C) | (D & (B | C))) + * + * Then the sub-blocks are processed as follows: + * + * A' = ror(A, 27) + f(B,C,D) + E + K + *W++ + * B' = A + * C' = ror(B, 2) + * D' = C + * E' = D + * + * We therefore unroll each loop 5 times to avoid register shuffling. + * Also the ror for C (and also D and E which are successivelyderived + * from it) is applied in place to cut on an additional mov insn for + * each round. + */ + + .macro sha_f1, A, B, C, D, E + ldr r3, [r2], #4 + eor ip, \C, \D + add \E, r1, \E, ror #2 + and ip, \B, ip, ror #2 + add \E, \E, \A, ror #27 + eor ip, ip, \D, ror #2 + add \E, \E, r3 + add \E, \E, ip + .endm + + .macro sha_f2, A, B, C, D, E + ldr r3, [r2], #4 + add \E, r1, \E, ror #2 + eor ip, \B, \C, ror #2 + add \E, \E, \A, ror #27 + eor ip, ip, \D, ror #2 + add \E, \E, r3 + add \E, \E, ip + .endm + + .macro sha_f3, A, B, C, D, E + ldr r3, [r2], #4 + add \E, r1, \E, ror #2 + orr ip, \B, \C, ror #2 + add \E, \E, \A, ror #27 + and ip, ip, \D, ror #2 + add \E, \E, r3 + and r3, \B, \C, ror #2 + orr ip, ip, r3 + add \E, \E, ip + .endm + + ldmia r0, {r4 - r8} + + mov lr, #4 + ldr r1, .L_sha_K + 0 + + /* adjust initial values */ + mov r6, r6, ror #30 + mov r7, r7, ror #30 + mov r8, r8, ror #30 + +3: subs lr, lr, #1 + sha_f1 r4, r5, r6, r7, r8 + sha_f1 r8, r4, r5, r6, r7 + sha_f1 r7, r8, r4, r5, r6 + sha_f1 r6, r7, r8, r4, r5 + sha_f1 r5, r6, r7, r8, r4 + bne 3b + + ldr r1, .L_sha_K + 4 + mov lr, #4 + +4: subs lr, lr, #1 + sha_f2 r4, r5, r6, r7, r8 + sha_f2 r8, r4, r5, r6, r7 + sha_f2 r7, r8, r4, r5, r6 + sha_f2 r6, r7, r8, r4, r5 + sha_f2 r5, r6, r7, r8, r4 + bne 4b + + ldr r1, .L_sha_K + 8 + mov lr, #4 + +5: subs lr, lr, #1 + sha_f3 r4, r5, r6, r7, r8 + sha_f3 r8, r4, r5, r6, r7 + sha_f3 r7, r8, r4, r5, r6 + sha_f3 r6, r7, r8, r4, r5 + sha_f3 r5, r6, r7, r8, r4 + bne 5b + + ldr r1, .L_sha_K + 12 + mov lr, #4 + +6: subs lr, lr, #1 + sha_f2 r4, r5, r6, r7, r8 + sha_f2 r8, r4, r5, r6, r7 + sha_f2 r7, r8, r4, r5, r6 + sha_f2 r6, r7, r8, r4, r5 + sha_f2 r5, r6, r7, r8, r4 + bne 6b + + ldmia r0, {r1, r2, r3, ip, lr} + add r4, r1, r4 + add r5, r2, r5 + add r6, r3, r6, ror #2 + add r7, ip, r7, ror #2 + add r8, lr, r8, ror #2 + stmia r0, {r4 - r8} + + ldmfd sp!, {r4 - r8, pc} + +.L_sha_K: + .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 + + +/* + * void sha_init(__u32 *buf) + */ + +.L_sha_initial_digest: + .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + +ENTRY(sha_init) + + str lr, [sp, #-4]! + adr r1, .L_sha_initial_digest + ldmia r1, {r1, r2, r3, ip, lr} + stmia r0, {r1, r2, r3, ip, lr} + ldr pc, [sp], #4 + From 42d3a120fe9a1831b88e7037ce0b048d82433b09 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 28 Oct 2005 15:26:41 +0100 Subject: [PATCH 0563/1940] [ARM] 3033/1: S3C2410 - add generic gpio_cfgpin options Patch from Ben Dooks Add generic values for the parameters to the s3c2410_gpio_cfgpin() function, so that a caller does not need to know the exact constant for the specified pin. This is very useful for the case where a driver is passed a gpio pin number and needs to reconfigure the pin's function. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/gpio.c | 22 ++++++++++++++++++++++ include/asm-arm/arch-s3c2410/regs-gpio.h | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c index 94f1776cf312..23ea3d5fa09c 100644 --- a/arch/arm/mach-s3c2410/gpio.c +++ b/arch/arm/mach-s3c2410/gpio.c @@ -30,6 +30,7 @@ * 04-Oct-2004 BJD Added irq filter controls for GPIO * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code * 13-Mar-2005 BJD Updates for __iomem + * 26-Oct-2005 BJD Added generic configuration types */ @@ -58,6 +59,27 @@ void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; } + switch (function) { + case S3C2410_GPIO_LEAVE: + mask = 0; + function = 0; + break; + + case S3C2410_GPIO_INPUT: + case S3C2410_GPIO_OUTPUT: + case S3C2410_GPIO_SFN2: + case S3C2410_GPIO_SFN3: + if (pin < S3C2410_GPIO_BANKB) { + function &= 1; + function <<= S3C2410_GPIO_OFFSET(pin); + } else { + function &= 3; + function <<= S3C2410_GPIO_OFFSET(pin)*2; + } + } + + /* modify the specified register wwith IRQs off */ + local_irq_save(flags); con = __raw_readl(base + 0x00); diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h index 2053cbacffc3..cb33d57c146c 100644 --- a/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/include/asm-arm/arch-s3c2410/regs-gpio.h @@ -20,6 +20,7 @@ * 18-11-2004 BJD Added S3C2440 AC97 controls * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 28-Mar-2005 LCVR Fixed definition of GPB10 + * 26-Oct-2005 BJD Added generic configuration types */ @@ -43,6 +44,11 @@ /* general configuration options */ #define S3C2410_GPIO_LEAVE (0xFFFFFFFF) +#define S3C2410_GPIO_INPUT (0xFFFFFFF0) +#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) +#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */ +#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* not available on A */ +#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */ /* configure GPIO ports A..G */ From a0e0adb96ebe6bf0b8b3fe4cd6c214b1e8964609 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 28 Oct 2005 15:26:42 +0100 Subject: [PATCH 0564/1940] [ARM] 3034/1: S3C2410 - fix size of devices in devs.c Patch from Ben Dooks From: Guillaume GOURAT A number of devices have an extra byte on the end of their areas due to mis-calculating the .end field of their resources Signed-off-by: Guillaume GOURAT Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/devs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 0077937a7ab8..8a37236b04ab 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -47,7 +47,7 @@ struct platform_device *s3c24xx_uart_devs[3]; static struct resource s3c_usb_resource[] = { [0] = { .start = S3C2410_PA_USBHOST, - .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST, + .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -77,7 +77,7 @@ EXPORT_SYMBOL(s3c_device_usb); static struct resource s3c_lcd_resource[] = { [0] = { .start = S3C2410_PA_LCD, - .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD, + .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -117,7 +117,7 @@ EXPORT_SYMBOL(set_s3c2410fb_info); static struct resource s3c_nand_resource[] = { [0] = { .start = S3C2410_PA_NAND, - .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND, + .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1, .flags = IORESOURCE_MEM, } }; @@ -136,7 +136,7 @@ EXPORT_SYMBOL(s3c_device_nand); static struct resource s3c_usbgadget_resource[] = { [0] = { .start = S3C2410_PA_USBDEV, - .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV, + .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -161,7 +161,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget); static struct resource s3c_wdt_resource[] = { [0] = { .start = S3C2410_PA_WATCHDOG, - .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG, + .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -186,7 +186,7 @@ EXPORT_SYMBOL(s3c_device_wdt); static struct resource s3c_i2c_resource[] = { [0] = { .start = S3C2410_PA_IIC, - .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC, + .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -211,7 +211,7 @@ EXPORT_SYMBOL(s3c_device_i2c); static struct resource s3c_iis_resource[] = { [0] = { .start = S3C2410_PA_IIS, - .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS, + .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS -1, .flags = IORESOURCE_MEM, } }; @@ -265,7 +265,7 @@ EXPORT_SYMBOL(s3c_device_rtc); static struct resource s3c_adc_resource[] = { [0] = { .start = S3C2410_PA_ADC, - .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC, + .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -288,7 +288,7 @@ struct platform_device s3c_device_adc = { static struct resource s3c_sdi_resource[] = { [0] = { .start = S3C2410_PA_SDI, - .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI, + .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -465,7 +465,7 @@ EXPORT_SYMBOL(s3c_device_timer3); static struct resource s3c_camif_resource[] = { [0] = { .start = S3C2440_PA_CAMIF, - .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF, + .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1, .flags = IORESOURCE_MEM, }, [1] = { From 63a4b52c9ddca944afc1b78aacbf641c650780d7 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 28 Oct 2005 15:26:42 +0100 Subject: [PATCH 0565/1940] [ARM] 3044/1: Fix sparse warnings about incompatible pointer types for register defined in pxa-regs.h Patch from Ian Campbell The sparse warning initially surfaced in sound/arm/pxa2xx-ac97.c because it was using u32 * variables to hold the unsigned long * register addresses. I submitted an ALSA patch for this http://thread.gmane.org/gmane.linux.alsa.devel/27804 issue and it was suggested that it might be preferable to change the register definitions to use u32. Most other subarches seem to use u32 for their register type, at least the ones which use a __REG macro (like the PXA) do. Nico indicated in the thread above that he wouldn't mind this patch. Changing the type required fixes for opposite warnings in the pxa2xx usb gadget code but that was the only new warning introduced on defconfig or lubbock, mainstone and our own PXA255 boards. Signed-off-by: Ian Campbell Signed-off-by: Russell King --- drivers/usb/gadget/pxa2xx_udc.c | 2 +- drivers/usb/gadget/pxa2xx_udc.h | 8 ++++---- include/asm-arm/arch-pxa/hardware.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 73f8c9404156..feae7c0c5dd9 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -422,7 +422,7 @@ static inline void ep0_idle (struct pxa2xx_udc *dev) } static int -write_packet(volatile unsigned long *uddr, struct pxa2xx_request *req, unsigned max) +write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max) { u8 *buf; unsigned length, count; diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index a58f3e6e71f1..19a883f7d1b8 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h @@ -69,11 +69,11 @@ struct pxa2xx_ep { * UDDR = UDC Endpoint Data Register (the fifo) * DRCM = DMA Request Channel Map */ - volatile unsigned long *reg_udccs; - volatile unsigned long *reg_ubcr; - volatile unsigned long *reg_uddr; + volatile u32 *reg_udccs; + volatile u32 *reg_ubcr; + volatile u32 *reg_uddr; #ifdef USE_DMA - volatile unsigned long *reg_drcmr; + volatile u32 *reg_drcmr; #define drcmr(n) .reg_drcmr = & DRCMR ## n , #else #define drcmr(n) diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index cf35721cfa45..3e70bd95472c 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -44,12 +44,12 @@ #ifndef __ASSEMBLY__ -# define __REG(x) (*((volatile unsigned long *)io_p2v(x))) +# define __REG(x) (*((volatile u32 *)io_p2v(x))) /* With indexed regs we don't want to feed the index through io_p2v() especially if it is a variable, otherwise horrible code will result. */ # define __REG2(x,y) \ - (*(volatile unsigned long *)((unsigned long)&__REG(x) + (y))) + (*(volatile u32 *)((u32)&__REG(x) + (y))) # define __PREG(x) (io_v2p((u32)&(x))) From 3b90c9c33361d49893645ffcebe6ca230f434705 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 28 Oct 2005 15:31:45 +0100 Subject: [PATCH 0566/1940] [ARM] 2908/1: add register definitions for ixp2000 msf Patch from Lennert Buytenhek We already had a mapping for the msf, but we didn't have any register definitions for it yet. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp2000/ixp2000-regs.h | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h index 32aece069869..def089d693d2 100644 --- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h +++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h @@ -392,4 +392,47 @@ #define WDT_RESET_ENABLE 0x01000000 +/* + * MSF registers. The IXP2400 and IXP2800 have somewhat different MSF + * units, but the registers that differ between the two don't overlap, + * so we can have one register list for both. + */ +#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x))) +#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000) +#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004) +#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008) +#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c) +#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010) +#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014) +#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018) +#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024) +#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028) +#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c) +#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040) +#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044) +#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048) +#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054) +#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058) +#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060) +#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064) +#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068) +#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070) +#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070) +#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080) +#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084) +#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088) +#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c) +#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090) +#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094) +#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098) +#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c) +#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0) +#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4) +#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8) +#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000) +#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400) + + #endif /* _IXP2000_H_ */ From 893b03094c2ed929648d76a29cbbfc9e215e8636 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 28 Oct 2005 15:31:45 +0100 Subject: [PATCH 0567/1940] [ARM] 3045/2: S3C2410 - change init for lcd platform data Patch from Ben Dooks Change set_s3c2410fb_info to s3c2410_fb_set_platdata and use kmalloc() for the copy of the information it is passed. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/devs.c | 16 ++++++++++------ arch/arm/mach-s3c2410/mach-h1940.c | 3 ++- include/asm-arm/arch-s3c2410/fb.h | 3 ++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 8a37236b04ab..08bc7d95a45d 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -103,14 +103,18 @@ struct platform_device s3c_device_lcd = { EXPORT_SYMBOL(s3c_device_lcd); -static struct s3c2410fb_mach_info s3c2410fb_info; - -void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info) +void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) { - memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info)); - s3c_device_lcd.dev.platform_data = &s3c2410fb_info; + struct s3c2410fb_mach_info *npd; + + npd = kmalloc(sizeof(*npd), GFP_KERNEL); + if (npd) { + memcpy(npd, pd, sizeof(*npd)); + s3c_device_lcd.dev.platform_data = npd; + } else { + printk(KERN_ERR "no memory for LCD platform data\n"); + } } -EXPORT_SYMBOL(set_s3c2410fb_info); /* NAND Controller */ diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index fb3cb01266e5..7efeaaad2361 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -25,6 +25,7 @@ * 14-Jan-2005 BJD Added clock init * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 20-Sep-2005 BJD Added static to non-exported items + * 26-Oct-2005 BJD Changed name of fb init call */ #include @@ -164,7 +165,7 @@ static void __init h1940_init_irq(void) static void __init h1940_init(void) { - set_s3c2410fb_info(&h1940_lcdcfg); + s3c24xx_fb_set_platdata(&h1940_lcdcfg); } MACHINE_START(H1940, "IPAQ-H1940") diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h index ac57bc887d82..4790491ba9d0 100644 --- a/include/asm-arm/arch-s3c2410/fb.h +++ b/include/asm-arm/arch-s3c2410/fb.h @@ -13,6 +13,7 @@ * 07-Sep-2004 RTP Created file * 03-Nov-2004 BJD Updated and minor cleanups * 03-Aug-2005 RTP Renamed to fb.h + * 26-Oct-2005 BJD Changed name of platdata init */ #ifndef __ASM_ARM_FB_H @@ -64,6 +65,6 @@ struct s3c2410fb_mach_info { unsigned long lpcsel; }; -void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info); +extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *); #endif /* __ASM_ARM_FB_H */ From 58c8d570f30d65836b53903fbdf355707a19aa52 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 28 Oct 2005 15:31:46 +0100 Subject: [PATCH 0568/1940] [ARM] 3046/1: BAST - add framebuffer platform data Patch from Ben Dooks Add framebuffer platform data Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-bast.c | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 7b51bfd0ba6d..c1b5c63ec24a 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -32,6 +32,7 @@ * 25-Jul-2005 BJD Removed ASIX static mappings * 27-Jul-2005 BJD Ensure maximum frequency of i2c bus * 20-Sep-2005 BJD Added static to non-exported items + * 26-Oct-2005 BJD Added FB platform data */ #include @@ -61,8 +62,10 @@ #include #include #include + #include #include +#include #include #include @@ -399,6 +402,38 @@ static struct s3c2410_platform_i2c bast_i2c_info = { .max_freq = 130*1000, }; + +static struct s3c2410fb_mach_info __initdata bast_lcd_info = { + .width = 640, + .height = 480, + + .xres = { + .min = 320, + .max = 1024, + .defval = 640, + }, + + .yres = { + .min = 240, + .max = 600, + .defval = 480, + }, + + .bpp = { + .min = 4, + .max = 16, + .defval = 8, + }, + + .regs = { + .lcdcon1 = 0x00000176, + .lcdcon2 = 0x1d77c7c2, + .lcdcon3 = 0x013a7f13, + .lcdcon4 = 0x00000057, + .lcdcon5 = 0x00014b02, + } +}; + /* Standard BAST devices */ static struct platform_device *bast_devices[] __initdata = { @@ -454,6 +489,10 @@ static void __init bast_map_io(void) usb_simtec_init(); } +static void __init bast_init(void) +{ + s3c24xx_fb_set_platdata(&bast_lcd_info); +} MACHINE_START(BAST, "Simtec-BAST") /* Maintainer: Ben Dooks */ @@ -463,5 +502,6 @@ MACHINE_START(BAST, "Simtec-BAST") .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = bast_map_io, .init_irq = s3c24xx_init_irq, + .init_machine = bast_init, .timer = &s3c24xx_timer, MACHINE_END From 57718976141c2929bddd6219efb32c2abea8360c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 28 Oct 2005 15:31:47 +0100 Subject: [PATCH 0569/1940] [ARM] 3047/1: SMDK2440 - add framebuffer platform data Patch from Ben Dooks Add platform data for framebuffer for the onboard LCD module Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-smdk2440.c | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 722ef46b630a..6950e61b7914 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -19,6 +19,7 @@ * 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA * 14-Mar-2005 BJD void __iomem fixes * 20-Sep-2005 BJD Added static to non-exported items + * 26-Oct-2005 BJD Added framebuffer data */ #include @@ -41,7 +42,10 @@ //#include #include #include +#include + #include +#include #include "s3c2410.h" #include "s3c2440.h" @@ -86,6 +90,70 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] = { } }; +/* LCD driver info */ + +static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { + .regs = { + + .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | + S3C2410_LCDCON1_TFT | + S3C2410_LCDCON1_CLKVAL(0x04), + + .lcdcon2 = S3C2410_LCDCON2_VBPD(7) | + S3C2410_LCDCON2_LINEVAL(319) | + S3C2410_LCDCON2_VFPD(6) | + S3C2410_LCDCON2_VSPW(3), + + .lcdcon3 = S3C2410_LCDCON3_HBPD(19) | + S3C2410_LCDCON3_HOZVAL(239) | + S3C2410_LCDCON3_HFPD(7), + + .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | + S3C2410_LCDCON4_HSPW(3), + + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + }, + +#if 0 + /* currently setup by downloader */ + .gpccon = 0xaa940659, + .gpccon_mask = 0xffffffff, + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + .gpdcon = 0xaa84aaa0, + .gpdcon_mask = 0xffffffff, + .gpdup = 0x0000faff, + .gpdup_mask = 0xffffffff, +#endif + + .lpcsel = ((0xCE6) & ~7) | 1<<4, + + .width = 240, + .height = 320, + + .xres = { + .min = 240, + .max = 240, + .defval = 240, + }, + + .yres = { + .min = 320, + .max = 320, + .defval = 320, + }, + + .bpp = { + .min = 16, + .max = 16, + .defval = 16, + }, +}; + static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, @@ -121,6 +189,8 @@ static void __init smdk2440_machine_init(void) s3c2410_gpio_setpin(S3C2410_GPF6, 0); s3c2410_gpio_setpin(S3C2410_GPF7, 0); + s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); + s3c2410_pm_init(); } From b57235215933d5fde4013e2448223b934b4ac2b7 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 28 Oct 2005 15:31:48 +0100 Subject: [PATCH 0570/1940] [ARM] 3048/1: register i2s resources not i2c resources for the pxa i2s platform device Patch from Ian Campbell As noted by Uli Luckas in the comments of 3025 there is a typo in the i2s platform device. The i2s platform device refers to the i2c resources. Signed-off-by: Ian Campbell Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 2e9e1702c4b3..719b91e93fa2 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -293,7 +293,7 @@ static struct resource i2s_resources[] = { static struct platform_device i2s_device = { .name = "pxa2xx-i2s", .id = -1, - .resource = i2c_resources, + .resource = i2s_resources, .num_resources = ARRAY_SIZE(i2s_resources), }; From 0b83f1400fa6e5f0d4afcff033628a16c163862a Mon Sep 17 00:00:00 2001 From: Jon Ringle Date: Fri, 28 Oct 2005 16:19:37 +0100 Subject: [PATCH 0571/1940] [ARM] 2918/1: [update] Base port of Comdial MP1000 platfrom Patch from Jon Ringle Updated 2898/1 per comments: - Removed fixup - Moved code in mach-mp1000/ to mach-clps711x/ - Cleaned up code in mp1000-seprom.c. Eliminated code that displayed the contents of the eeprom Please comment. Signed-off-by: Jon Ringle Signed-off-by: Russell King --- arch/arm/Kconfig | 3 +- arch/arm/boot/compressed/head.S | 3 +- arch/arm/configs/mp1000_defconfig | 897 ++++++++++++++++++ arch/arm/mach-clps711x/Kconfig | 11 + arch/arm/mach-clps711x/Makefile | 1 + arch/arm/mach-clps711x/mp1000-mach.c | 49 + arch/arm/mach-clps711x/mp1000-mm.c | 47 + arch/arm/mach-clps711x/mp1000-seprom.c | 195 ++++ drivers/serial/clps711x.c | 9 + include/asm-arm/arch-clps711x/hardware.h | 117 +++ include/asm-arm/arch-clps711x/mp1000-seprom.h | 77 ++ 11 files changed, 1407 insertions(+), 2 deletions(-) create mode 100644 arch/arm/configs/mp1000_defconfig create mode 100644 arch/arm/mach-clps711x/mp1000-mach.c create mode 100644 arch/arm/mach-clps711x/mp1000-mm.c create mode 100644 arch/arm/mach-clps711x/mp1000-seprom.c create mode 100644 include/asm-arm/arch-clps711x/mp1000-seprom.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 11fff042aa81..d885cc48bae1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -687,7 +687,8 @@ source "drivers/acorn/block/Kconfig" if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ - || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE + || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ + || MACH_MP1000 source "drivers/ide/Kconfig" endif diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 7c7f475e213e..a54d2eb64892 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -39,7 +39,8 @@ defined(CONFIG_ARCH_IXP4XX) || \ defined(CONFIG_ARCH_IXP2000) || \ defined(CONFIG_ARCH_LH7A40X) || \ - defined(CONFIG_ARCH_OMAP) + defined(CONFIG_ARCH_OMAP) || \ + defined(CONFIG_MACH_MP1000) .macro loadsp, rb addruart \rb .endm diff --git a/arch/arm/configs/mp1000_defconfig b/arch/arm/configs/mp1000_defconfig new file mode 100644 index 000000000000..d2cbc6fada1d --- /dev/null +++ b/arch/arm/configs/mp1000_defconfig @@ -0,0 +1,897 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-rc1 +# Fri Sep 16 15:48:13 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +CONFIG_ARCH_CLPS711X=y +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CEIVA is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +CONFIG_MACH_MP1000=y +CONFIG_MP1000_90MHZ=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y + +# +# Bus support +# +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_SMP is not set +CONFIG_PREEMPT=y +# CONFIG_NO_IDLE_HZ is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_media=rj45" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=m +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x0000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_EDB7312=m +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_MP1000=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +CONFIG_IDE_ARM=y +CONFIG_BLK_DEV_IDE_MP1000=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +CONFIG_CS89x0=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CLPS711X=y +CONFIG_SERIAL_CLPS711X_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 0793dcf54f2e..d5c155045762 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -69,6 +69,17 @@ config EP72XX_ROM_BOOT You almost surely want to say N here. +config MACH_MP1000 + bool "MACH_MP1000" + help + Say Y if you intend to run the kernel on the Comdial MP1000 platform. + +config MP1000_90MHZ + bool "MP1000_90MHZ" + depends on MACH_MP1000 + help + Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ + endmenu endif diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile index 4a197315f0cf..8a6dc1ccf8fe 100644 --- a/arch/arm/mach-clps711x/Makefile +++ b/arch/arm/mach-clps711x/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o +obj-$(CONFIG_MACH_MP1000) += mp1000-mach.o mp1000-mm.o mp1000-seprom.o obj-$(CONFIG_ARCH_P720T) += p720t.o leds-$(CONFIG_ARCH_P720T) += p720t-leds.o obj-$(CONFIG_LEDS) += $(leds-y) diff --git a/arch/arm/mach-clps711x/mp1000-mach.c b/arch/arm/mach-clps711x/mp1000-mach.c new file mode 100644 index 000000000000..c2816bcde5e7 --- /dev/null +++ b/arch/arm/mach-clps711x/mp1000-mach.c @@ -0,0 +1,49 @@ +/* + * linux/arch/arm/mach-mp1000/mp1000.c + * + * Copyright (C) 2005 Comdial Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +extern void mp1000_map_io(void); + +static void __init mp1000_init(void) +{ + seprom_init(); +} + +MACHINE_START(MP1000, "Comdial MP1000") + /* Maintainer: Jon Ringle */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0015100, + .map_io = mp1000_map_io, + .init_irq = clps711x_init_irq, + .init_machine = mp1000_init, + .timer = &clps711x_timer, +MACHINE_END + diff --git a/arch/arm/mach-clps711x/mp1000-mm.c b/arch/arm/mach-clps711x/mp1000-mm.c new file mode 100644 index 000000000000..20e810b0ec0c --- /dev/null +++ b/arch/arm/mach-clps711x/mp1000-mm.c @@ -0,0 +1,47 @@ +/* + * linux/arch/arm/mach-mp1000/mm.c + * + * Extra MM routines for the MP1000 + * + * Copyright (C) 2005 Comdial Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include +#include +#include +#include + +#include + +extern void clps711x_map_io(void); + +static struct map_desc mp1000_io_desc[] __initdata = { + { MP1000_EIO_BASE, MP1000_EIO_START, MP1000_EIO_SIZE, MT_DEVICE }, + { MP1000_FIO_BASE, MP1000_FIO_START, MP1000_FIO_SIZE, MT_DEVICE }, + { MP1000_LIO_BASE, MP1000_LIO_START, MP1000_LIO_SIZE, MT_DEVICE }, + { MP1000_NIO_BASE, MP1000_NIO_START, MP1000_NIO_SIZE, MT_DEVICE }, + { MP1000_IDE_BASE, MP1000_IDE_START, MP1000_IDE_SIZE, MT_DEVICE }, + { MP1000_DSP_BASE, MP1000_DSP_START, MP1000_DSP_SIZE, MT_DEVICE } +}; + +void __init mp1000_map_io(void) +{ + clps711x_map_io(); + iotable_init(mp1000_io_desc, ARRAY_SIZE(mp1000_io_desc)); +} diff --git a/arch/arm/mach-clps711x/mp1000-seprom.c b/arch/arm/mach-clps711x/mp1000-seprom.c new file mode 100644 index 000000000000..b22d0bebb851 --- /dev/null +++ b/arch/arm/mach-clps711x/mp1000-seprom.c @@ -0,0 +1,195 @@ +/*` + * mp1000-seprom.c + * + * This file contains the Serial EEPROM code for the MP1000 board + * + * Copyright (C) 2005 Comdial Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include + +/* If SepromInit() can initialize and checksum the seprom successfully, */ +/* then it will point seprom_data_ptr at the shadow copy. */ + +static eeprom_struct seprom_data; /* shadow copy of seprom content */ + +eeprom_struct *seprom_data_ptr = 0; /* 0 => not initialized */ + +/* + * Port D Bit 5 is Chip Select for EEPROM + * Port E Bit 0 is Input, Data out from EEPROM + * Port E Bit 1 is Output, Data in to EEPROM + * Port E Bit 2 is Output, CLK to EEPROM + */ + +static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR); +static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR); + +#define NO_OF_SHORTS 64 // Device is 64 x 16 bits +#define ENABLE_RW 0 +#define DISABLE_RW 1 + +static inline void toggle_seprom_clock(void) +{ + *port_e_ptr |= HwPortESepromCLK; + *port_e_ptr &= ~(HwPortESepromCLK); +} + +static inline void select_eeprom(void) +{ + *port_d_ptr |= HwPortDEECS; + *port_e_ptr &= ~(HwPortESepromCLK); +} + +static inline void deselect_eeprom(void) +{ + *port_d_ptr &= ~(HwPortDEECS); + *port_e_ptr &= ~(HwPortESepromDIn); +} + +/* + * GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom + * and returns 0 if seprom is not initialized or + * has a checksum error. + */ + +eeprom_struct* get_seprom_ptr(void) +{ + return seprom_data_ptr; +} + +unsigned char* get_eeprom_mac_address(void) +{ + return seprom_data_ptr->variant.eprom_struct.mac_Address; +} + +/* + * ReadSProm, Physically reads data from the Serial PROM + */ +static void read_sprom(short address, int length, eeprom_struct *buffer) +{ + short data = COMMAND_READ | (address & 0x3F); + short bit; + int i; + + select_eeprom(); + + // Clock in 9 bits of the command + for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) { + if (data & bit) + *port_e_ptr |= HwPortESepromDIn; + else + *port_e_ptr &= ~(HwPortESepromDIn); + + toggle_seprom_clock(); + } + + // + // Now read one or more shorts of data from the Seprom + // + while (length-- > 0) { + data = 0; + + // Read 16 bits at a time + for (i = 0; i < 16; i++) { + data <<= 1; + toggle_seprom_clock(); + data |= *port_e_ptr & HwPortESepromDOut; + + } + + buffer->variant.eprom_short_data[address++] = data; + } + + deselect_eeprom(); + + return; +} + + + +/* + * ReadSerialPROM + * + * Input: Pointer to array of 64 x 16 Bits + * + * Output: if no problem reading data is filled in + */ +static void read_serial_prom(eeprom_struct *data) +{ + read_sprom(0, 64, data); +} + + +// +// Compute Serial EEPROM checksum +// +// Input: Pointer to struct with Eprom data +// +// Output: The computed Eprom checksum +// +static short compute_seprom_checksum(eeprom_struct *data) +{ + short checksum = 0; + int i; + + for (i = 0; i < 126; i++) { + checksum += (short)data->variant.eprom_byte_data[i]; + } + + return((short)(0x5555 - (checksum & 0xFFFF))); +} + +// +// Make sure the data port bits for the SEPROM are correctly initialised +// + +void __init seprom_init(void) +{ + short checksum; + + // Init Port D + *(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0; + *(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15; + + // Init Port E + *(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06; + *(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04; + + // + // Make sure that EEPROM struct size never exceeds 128 bytes + // + if (sizeof(eeprom_struct) > 128) { + panic("Serial PROM struct size > 128, aborting read\n"); + } + + read_serial_prom(&seprom_data); + + checksum = compute_seprom_checksum(&seprom_data); + + if (checksum != seprom_data.variant.eprom_short_data[63]) { + panic("Serial EEPROM checksum failed\n"); + } + + seprom_data_ptr = &seprom_data; +} + diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 87ef368384fb..6a67e8f585b3 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -408,7 +408,11 @@ static struct uart_port clps711x_ports[UART_NR] = { { .iobase = SYSCON1, .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */ +#ifdef CONFIG_MP1000_90MHZ + .uartclk = 4515840, +#else .uartclk = 3686400, +#endif .fifosize = 16, .ops = &clps711x_pops, .line = 0, @@ -417,7 +421,11 @@ static struct uart_port clps711x_ports[UART_NR] = { { .iobase = SYSCON2, .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */ +#ifdef CONFIG_MP1000_90MHZ + .uartclk = 4515840, +#else .uartclk = 3686400, +#endif .fifosize = 16, .ops = &clps711x_pops, .line = 1, @@ -551,6 +559,7 @@ console_initcall(clps711xuart_console_init); static struct uart_driver clps711x_reg = { .driver_name = "ttyCL", .dev_name = "ttyCL", + .devfs_name = "ttyCL", .major = SERIAL_CLPS711X_MAJOR, .minor = SERIAL_CLPS711X_MINOR, .nr = UART_NR, diff --git a/include/asm-arm/arch-clps711x/hardware.h b/include/asm-arm/arch-clps711x/hardware.h index 1386871e1a5a..f864c367c934 100644 --- a/include/asm-arm/arch-clps711x/hardware.h +++ b/include/asm-arm/arch-clps711x/hardware.h @@ -235,4 +235,121 @@ #define CEIVA_PB0_BLK_BTN (1<<0) #endif // #if defined (CONFIG_ARCH_CEIVA) +#if defined (CONFIG_MACH_MP1000) +/* NOR FLASH */ +#define MP1000_NIO_BASE 0xf9000000 /* virtual */ +#define MP1000_NIO_START CS0_PHYS_BASE /* physical */ +#define MP1000_NIO_SIZE 0x00400000 + +/* DSP Interface */ +#define MP1000_DSP_BASE 0xfa000000 /* virtual */ +#define MP1000_DSP_START CS1_PHYS_BASE /* physical */ +#define MP1000_DSP_SIZE 0x00100000 + +/* LCD, DAA/DSP, RTC, DAA RW Reg all in CS2 */ +#define MP1000_LIO_BASE 0xfb000000 /* virtual */ +#define MP1000_LIO_START CS2_PHYS_BASE /* physical */ +#define MP1000_LIO_SIZE 0x00100000 + +/* NAND FLASH */ +#define MP1000_FIO_BASE 0xfc000000 /* virtual */ +#define MP1000_FIO_START CS3_PHYS_BASE /* physical */ +#define MP1000_FIO_SIZE 0x00800000 + +/* Ethernet */ +#define MP1000_EIO_BASE 0xfd000000 /* virtual */ +#define MP1000_EIO_START CS4_PHYS_BASE /* physical */ +#define MP1000_EIO_SIZE 0x00100000 + +#define MP1000_LCD_OFFSET 0x00000000 /* LCD offset in CS2 */ +#define MP1000_DDD_OFFSET 0x00001000 /* DAA/DAI/DSP sft reset offst*/ +#define MP1000_RTC_OFFSET 0x00002000 /* RTC offset in CS2 */ +#define MP1000_DAA_OFFSET 0x00003000 /* DAA RW reg offset in CS2 */ + +/* IDE */ +#define MP1000_IDE_BASE 0xfe000000 /* virtual */ +#define MP1000_IDE_START CS5_PHYS_BASE /* physical */ +#define MP1000_IDE_SIZE 0x00100000 /* actually it's only 0x1000 */ + +#define IRQ_HARDDISK IRQ_EINT2 + +/* + * IDE registers definition + */ + +#define IDE_CONTROL_BASE (MP1000_IDE_BASE + 0x1000) +#define IDE_BASE_OFF (MP1000_IDE_BASE) + +#define IDE_WRITE_DEVICE_DATA (IDE_BASE_OFF + 0x0) +#define IDE_FEATURES_REGISTER (IDE_BASE_OFF + 0x2) +#define IDE_SECTOR_COUNT_REGISTER (IDE_BASE_OFF + 0x4) +#define IDE_SECTOR_NUMBER_REGISTER (IDE_BASE_OFF + 0x6) +#define IDE_CYLINDER_LOW_REGISTER (IDE_BASE_OFF + 0x8) +#define IDE_CYLINDER_HIGH_REGISTER (IDE_BASE_OFF + 0xa) +#define IDE_DEVICE_HEAD_REGISTER (IDE_BASE_OFF + 0xc) +#define IDE_COMMAND_DATA_REGISTER (IDE_BASE_OFF + 0xe) +#define IDE_DEVICE_CONTROL_REGISTER (IDE_CONTROL_BASE + 0xc) + +#define IDE_IRQ IRQ_EINT2 + + +#define RTC_PORT(x) (MP1000_LIO_BASE+0x2000 + (x*2)) +#define RTC_ALWAYS_BCD 0 + +/* +// Definitions of the bit fields in the HwPortA register for the +// MP1000 board. +*/ +#define HwPortAKeyboardRow1 0x00000001 +#define HwPortAKeyboardRow2 0x00000002 +#define HwPortAKeyboardRow3 0x00000004 +#define HwPortAKeyboardRow4 0x00000008 +#define HwPortAKeyboardRow5 0x00000010 +#define HwPortAKeyboardRow6 0x00000020 +#define HwPortALCDEnable 0x00000040 +#define HwPortAOffhook 0x00000080 + +/* +// Definitions of the bit fields in the HwPortB register for the +// MP1000 board. +*/ +#define HwPortBL3Mode 0x00000001 +#define HwPortBL3Clk 0x00000002 +#define HwPortBSClk 0x00000001 +#define HwPortBSData 0x00000002 +#define HwPortBL3Data 0x00000004 +#define HwPortBMute 0x00000008 +#define HwPortBQD0 0x00000010 +#define HwPortBQD1 0x00000020 +#define HwPortBQD2 0x00000040 +#define HwPortBQD3 0x00000080 + +/* +// Definitions of the bit fields in the HwPortD register for the +// MP1000 board. +*/ +#define HwPortDLED1 0x00000001 +#define HwPortDLED2 0x00000002 +#define HwPortDLED3 0x00000004 +#define HwPortDLED4 0x00000008 +#define HwPortDLED5 0x00000010 +#define HwPortDEECS 0x00000020 +#define HwPortBRTS 0x00000040 +#define HwPortBRI 0x00000080 + + +/* +// Definitions of the bit fields in the HwPortE register for the +// MP1000 board. +*/ + +#define HwPortECLE 0x00000001 +#define HwPortESepromDOut 0x00000001 +#define HwPortEALE 0x00000002 +#define HwPortESepromDIn 0x00000002 +#define HwPortENANDCS 0x00000004 +#define HwPortESepromCLK 0x00000004 + +#endif // #if defined (CONFIG_MACH_MP1000) + #endif diff --git a/include/asm-arm/arch-clps711x/mp1000-seprom.h b/include/asm-arm/arch-clps711x/mp1000-seprom.h new file mode 100644 index 000000000000..3e5566cf9666 --- /dev/null +++ b/include/asm-arm/arch-clps711x/mp1000-seprom.h @@ -0,0 +1,77 @@ +#ifndef MP1000_SEPROM_H +#define MP1000_SEPROM_H + +/* + * mp1000-seprom.h + * + * + * This file contains the Serial EEPROM definitions for the MP1000 board + * + * Copyright (C) 2005 Comdial Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define COMMAND_ERASE (0x1C0) +#define COMMAND_ERASE_ALL (0x120) +#define COMMAND_WRITE_DISABLE (0x100) +#define COMMAND_WRITE_ENABLE (0x130) +#define COMMAND_READ (0x180) +#define COMMAND_WRITE (0x140) +#define COMMAND_WRITE_ALL (0x110) + +// +// Serial EEPROM data format +// + +#define PACKED __attribute__ ((packed)) + +typedef struct _EEPROM { + union { + unsigned char eprom_byte_data[128]; + unsigned short eprom_short_data[64]; + struct { + unsigned char version PACKED; // EEPROM Version "1" for now + unsigned char box_id PACKED; // Box ID (Standalone, SOHO, embedded, etc) + unsigned char major_hw_version PACKED; // Major Hardware version (Hex) + unsigned char minor_hw_version PACKED; // Minor Hardware Version (Hex) + unsigned char mfg_id[3] PACKED; // Manufacturer ID (3 character Alphabetic) + unsigned char mfg_serial_number[10] PACKED; // Manufacturer Serial number + unsigned char mfg_date[3] PACKED; // Date of Mfg (Formatted YY:MM:DD) + unsigned char country PACKED; // Country of deployment + unsigned char mac_Address[6] PACKED; // MAC Address + unsigned char oem_string[20] PACKED; // OEM ID string + unsigned short feature_bits1 PACKED; // Feature Bits 1 + unsigned short feature_bits2 PACKED; // Feature Bits 2 + unsigned char filler[75] PACKED; // Unused/Undefined “0” initialized + unsigned short checksum PACKED; // byte accumulated short checksum + } eprom_struct; + } variant; +} eeprom_struct; + +/* These settings must be mutually exclusive */ +#define FEATURE_BITS1_DRAMSIZE_16MEG 0x0001 /* 0 signifies 4 MEG system */ +#define FEATURE_BITS1_DRAMSIZE_8MEG 0x0002 /* 1 in bit 1 = 8MEG system */ +#define FEATURE_BITS1_DRAMSIZE_64MEG 0x0004 /* 1 in bit 2 = 64MEG system */ + +#define FEATURE_BITS1_CPUIS90MEG 0x0010 + +extern void seprom_init(void); +extern eeprom_struct* get_seprom_ptr(void); +extern unsigned char* get_eeprom_mac_address(void); + +#endif /* MP1000_SEPROM_H */ + From 917f68f8163eb877a6d71c5b446ee236645c2944 Mon Sep 17 00:00:00 2001 From: Jon Ringle Date: Fri, 28 Oct 2005 16:19:38 +0100 Subject: [PATCH 0572/1940] [ARM] 2919/1: CS8900A ethernet driver modifications for the Comdial MP1000 Patch from Jon Ringle This patch gives support for the CS8900A ethernet chip on the Comdial MP1000 Signed-off-by: Jon Ringle Signed-off-by: Russell King --- drivers/net/Kconfig | 2 +- drivers/net/cs89x0.c | 14 +++++++++++++- drivers/net/cs89x0.h | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c748b0e16419..3e1e323e3003 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1330,7 +1330,7 @@ config FORCEDETH config CS89x0 tristate "CS89x0 support" - depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 + depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 || MACH_MP1000 ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index a6078ad9b654..bfdae10036ed 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -182,6 +182,10 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; #define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */ static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0}; static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0}; +#elif defined(CONFIG_MACH_MP1000) +#include +static unsigned int netcard_portlist[] __initdata = {MP1000_EIO_BASE+0x300, 0}; +static unsigned int cs8900_irq_map[] = {IRQ_EINT3,0,0,0}; #else static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; @@ -590,6 +594,10 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) cnt -= j; } } else +#elif defined(CONFIG_MACH_MP1000) + if (1) { + memcpy(dev->dev_addr, get_eeprom_mac_address(), ETH_ALEN); + } else #endif if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == @@ -649,6 +657,10 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) if (1) { printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n"); } else +#elif defined(CONFIG_MACH_MP1000) + if (1) { + lp->force |= FORCE_RJ45; + } else #endif if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n"); @@ -1231,7 +1243,7 @@ net_open(struct net_device *dev) else #endif { -#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) +#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) && !defined(CONFIG_MACH_MP1000) if (((1 << dev->irq) & lp->irq_map) == 0) { printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", dev->name, dev->irq, lp->irq_map); diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h index decea264f121..f19d1ebe0183 100644 --- a/drivers/net/cs89x0.h +++ b/drivers/net/cs89x0.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) +#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) || defined (CONFIG_MACH_MP1000) /* IXDP2401/IXDP2801 uses dword-aligned register addressing */ #define CS89x0_PORT(reg) ((reg) * 2) #else From 80a18573cea2e6d8e95abe4d42bfc5f97761999a Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 28 Oct 2005 16:25:01 +0100 Subject: [PATCH 0573/1940] [ARM] 2787/2: PXA27x low power modes support Patch from Todd Poynor Add symbols for PXA2xx PWRMODE register M field that selects low-power mode, replace unadorned constants. Honor power mode parameter of pxa_cpu_suspend(mode), no longer force to 3 (sleep). Full Deep Sleep low-power mode support for PXA27x is pending generic PM interfaces to select more than 2 suspend-to-RAM-style power modes, but this is expected soon. This can be hardcoded in the meantime by replacing the pxa_cpu_suspend() parameter value. From David Burrage and Todd Poynor. Try #2 removes one of the register copies and moves the code to save the pxa_cpu_suspend parameter to immediately surround the call that requires the parameter value be preserved. Signed-off-by: Todd Poynor Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/pxa25x.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/sleep.S | 7 +++++-- arch/arm/mach-pxa/standby.S | 2 +- include/asm-arm/arch-pxa/pxa-regs.h | 7 +++++++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 7869c3b4e62f..573a5758e781 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -129,7 +129,7 @@ void pxa_cpu_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); - pxa_cpu_suspend(3); + pxa_cpu_suspend(PWRMODE_SLEEP); break; } } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 9a791b07118d..09a5d593f04b 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -157,7 +157,7 @@ void pxa_cpu_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); - pxa_cpu_suspend(3); + pxa_cpu_suspend(PWRMODE_SLEEP); break; } } diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 5786ccad938c..c9862688ff3d 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -28,7 +28,9 @@ /* * pxa_cpu_suspend() * - * Forces CPU into sleep state + * Forces CPU into sleep state. + * + * r0 = value for PWRMODE M field for desired sleep state */ ENTRY(pxa_cpu_suspend) @@ -53,6 +55,7 @@ ENTRY(pxa_cpu_suspend) mov r10, sp stmfd sp!, {r3 - r10} + mov r5, r0 @ save sleep mode @ preserve phys address of stack mov r0, sp bl sleep_phys_sp @@ -66,7 +69,7 @@ ENTRY(pxa_cpu_suspend) @ (also workaround for sighting 28071) @ prepare value for sleep mode - mov r1, #3 @ sleep mode + mov r1, r5 @ sleep mode @ prepare pointer to physical address 0 (virtual mapping in generic.c) mov r2, #UNCACHED_PHYS_0 diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index 8a3f27b76784..6f6dbbd08021 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -21,7 +21,7 @@ ENTRY(pxa_cpu_standby) ldr r0, =PSSR mov r1, #(PSSR_PH | PSSR_STS) - mov r2, #2 + mov r2, #PWRMODE_STANDBY mov r3, #UNCACHED_PHYS_0 @ Read mem context in. ldr ip, [r3] b 1f diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 3af7165ab0d7..a6a34edec813 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -2282,4 +2282,11 @@ #endif +/* PWRMODE register M field values */ + +#define PWRMODE_IDLE 0x1 +#define PWRMODE_STANDBY 0x2 +#define PWRMODE_SLEEP 0x3 +#define PWRMODE_DEEPSLEEP 0x7 + #endif From d9e29649875df82828167dd45c802d942db863ba Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Fri, 28 Oct 2005 16:25:02 +0100 Subject: [PATCH 0574/1940] [ARM] 3029/1: Add HWUART support for PXA 255/26x Patch from Matt Reimer Adds support for HWUART on PXA 255 / 26x. This patch originally came from http://svn.rungie.com/svn/gumstix-buildroot/trunk/sources/kernel-patches/000-gumstix-hwuart.patch and has been tweaked by me. Signed-off-by: Matt Reimer Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 18 ++++++++++++++- drivers/serial/pxa.c | 21 ++++++++++++++++- include/asm-arm/arch-pxa/pxa-regs.h | 33 +++++++++++++++++++++++++++ include/asm-arm/arch-pxa/uncompress.h | 1 + 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 719b91e93fa2..218eb9671fa3 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -253,6 +253,10 @@ static struct platform_device stuart_device = { .name = "pxa2xx-uart", .id = 2, }; +static struct platform_device hwuart_device = { + .name = "pxa2xx-uart", + .id = 3, +}; static struct resource i2c_resources[] = { { @@ -310,7 +314,19 @@ static struct platform_device *devices[] __initdata = { static int __init pxa_init(void) { - return platform_add_devices(devices, ARRAY_SIZE(devices)); + int cpuid, ret; + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if (ret) + return ret; + + /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ + cpuid = read_cpuid(CPUID_ID); + if (((cpuid >> 4) & 0xfff) == 0x2d0 || + ((cpuid >> 4) & 0xfff) == 0x290) + ret = platform_device_register(&hwuart_device); + + return ret; } subsys_initcall(pxa_init); diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 90c2a86c421b..005f027e081a 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -358,6 +358,9 @@ static int serial_pxa_startup(struct uart_port *port) unsigned long flags; int retval; + if (port->line == 3) /* HWUART */ + up->mcr |= UART_MCR_AFE; + else up->mcr = 0; /* @@ -481,8 +484,10 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios, if ((up->port.uartclk / quot) < (2400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; - else + else if ((up->port.uartclk / quot) < (230400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; + else + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; /* * Ok, we're now changing the port state. Do it with @@ -772,6 +777,20 @@ static struct uart_pxa_port serial_pxa_ports[] = { .ops = &serial_pxa_pops, .line = 2, }, + }, { /* HWUART */ + .name = "HWUART", + .cken = CKEN4_HWUART, + .port = { + .type = PORT_PXA, + .iotype = UPIO_MEM, + .membase = (void *)&HWUART, + .mapbase = __PREG(HWUART), + .irq = IRQ_HWUART, + .uartclk = 921600 * 16, + .fifosize = 64, + .ops = &serial_pxa_pops, + .line = 3, + }, } }; diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index a6a34edec813..75f085dc9894 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -326,6 +326,25 @@ #define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ #define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ +/* Hardware UART (HWUART) */ +#define HWUART HWRBR +#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */ +#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */ +#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */ +#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */ +#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */ +#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */ +#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */ +#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */ +#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */ +#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */ +#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */ +#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */ +#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */ +#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */ +#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + #define IER_DMAE (1 << 7) /* DMA Requests Enable */ #define IER_UUE (1 << 6) /* UART Unit Enable */ #define IER_NRZE (1 << 5) /* NRZ coding Enable */ @@ -1250,9 +1269,13 @@ #define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ #define GPIO41_FFRTS 41 /* FFUART request to send */ #define GPIO42_BTRXD 42 /* BTUART receive data */ +#define GPIO42_HWRXD 42 /* HWUART receive data */ #define GPIO43_BTTXD 43 /* BTUART transmit data */ +#define GPIO43_HWTXD 43 /* HWUART transmit data */ #define GPIO44_BTCTS 44 /* BTUART clear to send */ +#define GPIO44_HWCTS 44 /* HWUART clear to send */ #define GPIO45_BTRTS 45 /* BTUART request to send */ +#define GPIO45_HWRTS 45 /* HWUART request to send */ #define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ #define GPIO46_ICPRXD 46 /* ICP receive data */ #define GPIO46_STRXD 46 /* STD_UART receive data */ @@ -1378,17 +1401,26 @@ #define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) #define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) #define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) +#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) #define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) +#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) #define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) +#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) #define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) +#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) #define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) #define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) #define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) #define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) #define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) #define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) +#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) #define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) #define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) +#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) +#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) #define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) #define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) #define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) @@ -1763,6 +1795,7 @@ #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */ #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */ #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */ +#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */ #define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */ #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */ #define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */ diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h index 4428d3eb7432..fe38090444e0 100644 --- a/include/asm-arm/arch-pxa/uncompress.h +++ b/include/asm-arm/arch-pxa/uncompress.h @@ -12,6 +12,7 @@ #define FFUART ((volatile unsigned long *)0x40100000) #define BTUART ((volatile unsigned long *)0x40200000) #define STUART ((volatile unsigned long *)0x40700000) +#define HWUART ((volatile unsigned long *)0x41600000) #define UART FFUART From dd5b295ff880d5a0699a52f84106f16702c298f2 Mon Sep 17 00:00:00 2001 From: Jon Ringle Date: Fri, 28 Oct 2005 16:27:24 +0100 Subject: [PATCH 0575/1940] [ARM] 2921/1: Support for the RTC / nvram on the Comdial MP1000 Patch from Jon Ringle This adds support for the RTC and nvram on the Comdial MP1000 Signed-off-by: Jon Ringle Signed-off-by: Russell King --- drivers/char/nvram.c | 110 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 1af733d07321..9e24bbd4090c 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -32,9 +32,11 @@ * added changelog * 1.2 Erik Gilling: Cobalt Networks support * Tim Hockin: general cleanup, Cobalt support + * 1.3 Jon Ringle: Comdial MP1000 support + * */ -#define NVRAM_VERSION "1.2" +#define NVRAM_VERSION "1.3" #include #include @@ -45,6 +47,7 @@ #define PC 1 #define ATARI 2 #define COBALT 3 +#define MP1000 4 /* select machine configuration */ #if defined(CONFIG_ATARI) @@ -54,6 +57,9 @@ # if defined(CONFIG_COBALT) # include # define MACH COBALT +# elif defined(CONFIG_MACH_MP1000) +# undef MACH +# define MACH MP1000 # else # define MACH PC # endif @@ -112,6 +118,23 @@ #endif +#if MACH == MP1000 + +/* RTC in a MP1000 */ +#define CHECK_DRIVER_INIT() 1 + +#define MP1000_CKS_RANGE_START 0 +#define MP1000_CKS_RANGE_END 111 +#define MP1000_CKS_LOC 112 + +#define NVRAM_BYTES (128-NVRAM_FIRST_BYTE) + +#define mach_check_checksum mp1000_check_checksum +#define mach_set_checksum mp1000_set_checksum +#define mach_proc_infos mp1000_proc_infos + +#endif + /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with * rtc_lock held. Due to the index-port/data-port design of the RTC, we * don't want two different things trying to get to it at once. (e.g. the @@ -915,6 +938,91 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len, #endif /* MACH == ATARI */ +#if MACH == MP1000 + +static int +mp1000_check_checksum(void) +{ + int i; + unsigned short sum = 0; + unsigned short expect; + + for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i) + sum += __nvram_read_byte(i); + + expect = __nvram_read_byte(MP1000_CKS_LOC+1)<<8 | + __nvram_read_byte(MP1000_CKS_LOC); + return ((sum & 0xffff) == expect); +} + +static void +mp1000_set_checksum(void) +{ + int i; + unsigned short sum = 0; + + for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i) + sum += __nvram_read_byte(i); + __nvram_write_byte(sum >> 8, MP1000_CKS_LOC + 1); + __nvram_write_byte(sum & 0xff, MP1000_CKS_LOC); +} + +#ifdef CONFIG_PROC_FS + +#define SERVER_N_LEN 32 +#define PATH_N_LEN 32 +#define FILE_N_LEN 32 +#define NVRAM_MAGIC_SIG 0xdead + +typedef struct NvRamImage +{ + unsigned short int magic; + unsigned short int mode; + char fname[FILE_N_LEN]; + char path[PATH_N_LEN]; + char server[SERVER_N_LEN]; + char pad[12]; +} NvRam; + +static int +mp1000_proc_infos(unsigned char *nvram, char *buffer, int *len, + off_t *begin, off_t offset, int size) +{ + int checksum; + NvRam* nv = (NvRam*)nvram; + + spin_lock_irq(&rtc_lock); + checksum = __nvram_check_checksum(); + spin_unlock_irq(&rtc_lock); + + PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not "); + + switch( nv->mode ) + { + case 0 : + PRINT_PROC( "\tMode 0, tftp prompt\n" ); + break; + case 1 : + PRINT_PROC( "\tMode 1, booting from disk\n" ); + break; + case 2 : + PRINT_PROC( "\tMode 2, Alternate boot from disk /boot/%s\n", nv->fname ); + break; + case 3 : + PRINT_PROC( "\tMode 3, Booting from net:\n" ); + PRINT_PROC( "\t\t%s:%s%s\n",nv->server, nv->path, nv->fname ); + break; + default: + PRINT_PROC( "\tInconsistant nvram?\n" ); + break; + } + + return 1; +} +#endif + +#endif /* MACH == MP1000 */ + MODULE_LICENSE("GPL"); EXPORT_SYMBOL(__nvram_read_byte); From 8573b80f020dce7aefa3237f1e932d562b65323d Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 28 Oct 2005 16:28:04 +0100 Subject: [PATCH 0576/1940] [ARM] 3031/1: fix typos in comments of mmc.h Patch from Erik Hovland I noticed that the same typo (i before c in associated) showed up twice in the file kernel/include/linux/mmc/mmc.h. This patch fixes both of the instances I found with this mistake. The typos are in comments and should have no affect on working code. E Signed-off-by: Erik Hovland Signed-off-by: Russell King --- include/linux/mmc/mmc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 1ab78e8d6c53..aef6042f8f0b 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -50,7 +50,7 @@ struct mmc_command { #define MMC_ERR_INVALID 5 struct mmc_data *data; /* data segment associated with cmd */ - struct mmc_request *mrq; /* assoicated request */ + struct mmc_request *mrq; /* associated request */ }; struct mmc_data { @@ -68,7 +68,7 @@ struct mmc_data { unsigned int bytes_xfered; struct mmc_command *stop; /* stop command */ - struct mmc_request *mrq; /* assoicated request */ + struct mmc_request *mrq; /* associated request */ unsigned int sg_len; /* size of scatter list */ struct scatterlist *sg; /* I/O scatter list */ From a999cb04b4bfb4a2243383f00d5714b8d7163035 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 28 Oct 2005 16:35:46 +0100 Subject: [PATCH 0577/1940] [ARM] 3035/1: RISCOS compat code fix Patch from Nicolas Pitre From: Daniel Jacobowitz > I also fixed a bug that confused me greatly while trying to debug: one > SIGILL has long been a SIGSEGV because of some broken RISCOS > compatibility code. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f6de76e0a45d..baa09601a64e 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -345,7 +345,9 @@ static int bad_syscall(int n, struct pt_regs *regs) struct thread_info *thread = current_thread_info(); siginfo_t info; - if (current->personality != PER_LINUX && thread->exec_domain->handler) { + if (current->personality != PER_LINUX && + current->personality != PER_LINUX_32BIT && + thread->exec_domain->handler) { thread->exec_domain->handler(n, regs); return regs->ARM_r0; } From 6f475c0133eb91c7df3b056843dc33d2824368a2 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 28 Oct 2005 16:39:33 +0100 Subject: [PATCH 0578/1940] [ARM] 2897/2: PXA2xx IRDA support Patch from Nicolas Pitre This is the PXA2xx common IRDA driver, plus platform support for Lubbock and Mainstone. Signed-off-by: Nicolas Pitre Acked-by: Jean Tourrilhes Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 18 + arch/arm/mach-pxa/lubbock.c | 20 + arch/arm/mach-pxa/mainstone.c | 25 + drivers/net/irda/Kconfig | 10 + drivers/net/irda/Makefile | 1 + drivers/net/irda/pxaficp_ir.c | 871 ++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/irda.h | 17 + include/asm-arm/arch-pxa/pxa-regs.h | 2 - 8 files changed, 962 insertions(+), 2 deletions(-) create mode 100644 drivers/net/irda/pxaficp_ir.c create mode 100644 include/asm-arm/arch-pxa/irda.h diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 218eb9671fa3..3248bc9b9495 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "generic.h" @@ -301,6 +302,22 @@ static struct platform_device i2s_device = { .num_resources = ARRAY_SIZE(i2s_resources), }; +static u64 pxaficp_dmamask = ~(u32)0; + +static struct platform_device pxaficp_device = { + .name = "pxa2xx-ir", + .id = -1, + .dev = { + .dma_mask = &pxaficp_dmamask, + .coherent_dma_mask = 0xffffffff, + }, +}; + +void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) +{ + pxaficp_device.dev.platform_data = info; +} + static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, @@ -308,6 +325,7 @@ static struct platform_device *devices[] __initdata = { &ffuart_device, &btuart_device, &stuart_device, + &pxaficp_device, &i2c_device, &i2s_device, }; diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 69abc7f61ed0..beccf455f796 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -237,11 +238,30 @@ static struct pxamci_platform_data lubbock_mci_platform_data = { .init = lubbock_mci_init, }; +static void lubbock_irda_transceiver_mode(struct device *dev, int mode) +{ + unsigned long flags; + + local_irq_save(flags); + if (mode & IR_SIRMODE) { + LUB_MISC_WR &= ~(1 << 4); + } else if (mode & IR_FIRMODE) { + LUB_MISC_WR |= 1 << 4; + } + local_irq_restore(flags); +} + +static struct pxaficp_platform_data lubbock_ficp_platform_data = { + .transceiver_cap = IR_SIRMODE | IR_FIRMODE, + .transceiver_mode = lubbock_irda_transceiver_mode, +}; + static void __init lubbock_init(void) { pxa_set_udc_info(&udc_info); set_pxa_fb_info(&sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); + pxa_set_ficp_info(&lubbock_ficp_platform_data); (void) platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 8b4a21623fc0..a48c64026e1f 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "generic.h" @@ -294,6 +295,29 @@ static struct pxamci_platform_data mainstone_mci_platform_data = { .exit = mainstone_mci_exit, }; +static void mainstone_irda_transceiver_mode(struct device *dev, int mode) +{ + unsigned long flags; + + local_irq_save(flags); + if (mode & IR_SIRMODE) { + MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR; + } else if (mode & IR_FIRMODE) { + MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR; + } + if (mode & IR_OFF) { + MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF; + } else { + MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL; + } + local_irq_restore(flags); +} + +static struct pxaficp_platform_data mainstone_ficp_platform_data = { + .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, + .transceiver_mode = mainstone_irda_transceiver_mode, +}; + static void __init mainstone_init(void) { /* @@ -313,6 +337,7 @@ static void __init mainstone_init(void) set_pxa_fb_info(&toshiba_ltm035a776c); pxa_set_mci_info(&mainstone_mci_platform_data); + pxa_set_ficp_info(&mainstone_ficp_platform_data); } diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index ca5914091d3a..d54156f11e61 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -400,5 +400,15 @@ config VIA_FIR To compile it as a module, choose M here: the module will be called via-ircc. +config PXA_FICP + tristate "Intel PXA2xx Internal FICP" + depends on ARCH_PXA && IRDA + help + Say Y or M here if you want to build support for the PXA2xx + built-in IRDA interface which can support both SIR and FIR. + This driver relies on platform specific helper routines so + available capabilities may vary from one PXA2xx target to + another. + endmenu diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 29a8bd812b21..e7a8b7f7f5dd 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o obj-$(CONFIG_VIA_FIR) += via-ircc.o +obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o # Old dongle drivers for old SIR drivers obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c new file mode 100644 index 000000000000..aef80f5e7c9c --- /dev/null +++ b/drivers/net/irda/pxaficp_ir.c @@ -0,0 +1,871 @@ +/* + * linux/drivers/net/irda/pxaficp_ir.c + * + * Based on sa1100_ir.c by Russell King + * + * Changes copyright (C) 2003-2005 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MACH_MAINSTONE +#include +#endif + +#define IrSR_RXPL_NEG_IS_ZERO (1<<4) +#define IrSR_RXPL_POS_IS_ZERO 0x0 +#define IrSR_TXPL_NEG_IS_ZERO (1<<3) +#define IrSR_TXPL_POS_IS_ZERO 0x0 +#define IrSR_XMODE_PULSE_1_6 (1<<2) +#define IrSR_XMODE_PULSE_3_16 0x0 +#define IrSR_RCVEIR_IR_MODE (1<<1) +#define IrSR_RCVEIR_UART_MODE 0x0 +#define IrSR_XMITIR_IR_MODE (1<<0) +#define IrSR_XMITIR_UART_MODE 0x0 + +#define IrSR_IR_RECEIVE_ON (\ + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_IR_MODE | \ + IrSR_XMITIR_UART_MODE) + +#define IrSR_IR_TRANSMIT_ON (\ + IrSR_RXPL_NEG_IS_ZERO | \ + IrSR_TXPL_POS_IS_ZERO | \ + IrSR_XMODE_PULSE_3_16 | \ + IrSR_RCVEIR_UART_MODE | \ + IrSR_XMITIR_IR_MODE) + +struct pxa_irda { + int speed; + int newspeed; + unsigned long last_oscr; + + unsigned char *dma_rx_buff; + unsigned char *dma_tx_buff; + dma_addr_t dma_rx_buff_phy; + dma_addr_t dma_tx_buff_phy; + unsigned int dma_tx_buff_len; + int txdma; + int rxdma; + + struct net_device_stats stats; + struct irlap_cb *irlap; + struct qos_info qos; + + iobuff_t tx_buff; + iobuff_t rx_buff; + + struct device *dev; + struct pxaficp_platform_data *pdata; +}; + + +#define IS_FIR(si) ((si)->speed >= 4000000) +#define IRDA_FRAME_SIZE_LIMIT 2047 + +inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si) +{ + DCSR(si->rxdma) = DCSR_NODESC; + DSADR(si->rxdma) = __PREG(ICDR); + DTADR(si->rxdma) = si->dma_rx_buff_phy; + DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT; + DCSR(si->rxdma) |= DCSR_RUN; +} + +inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si) +{ + DCSR(si->txdma) = DCSR_NODESC; + DSADR(si->txdma) = si->dma_tx_buff_phy; + DTADR(si->txdma) = __PREG(ICDR); + DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len; + DCSR(si->txdma) |= DCSR_RUN; +} + +/* + * Set the IrDA communications speed. + */ +static int pxa_irda_set_speed(struct pxa_irda *si, int speed) +{ + unsigned long flags; + unsigned int divisor; + + switch (speed) { + case 9600: case 19200: case 38400: + case 57600: case 115200: + + /* refer to PXA250/210 Developer's Manual 10-7 */ + /* BaudRate = 14.7456 MHz / (16*Divisor) */ + divisor = 14745600 / (16 * speed); + + local_irq_save(flags); + + if (IS_FIR(si)) { + /* stop RX DMA */ + DCSR(si->rxdma) &= ~DCSR_RUN; + /* disable FICP */ + ICCR0 = 0; + pxa_set_cken(CKEN13_FICP, 0); + + /* set board transceiver to SIR mode */ + si->pdata->transceiver_mode(si->dev, IR_SIRMODE); + + /* configure GPIO46/47 */ + pxa_gpio_mode(GPIO46_STRXD_MD); + pxa_gpio_mode(GPIO47_STTXD_MD); + + /* enable the STUART clock */ + pxa_set_cken(CKEN5_STUART, 1); + } + + /* disable STUART first */ + STIER = 0; + + /* access DLL & DLH */ + STLCR |= LCR_DLAB; + STDLL = divisor & 0xff; + STDLH = divisor >> 8; + STLCR &= ~LCR_DLAB; + + si->speed = speed; + STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; + STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; + + local_irq_restore(flags); + break; + + case 4000000: + local_irq_save(flags); + + /* disable STUART */ + STIER = 0; + STISR = 0; + pxa_set_cken(CKEN5_STUART, 0); + + /* disable FICP first */ + ICCR0 = 0; + + /* set board transceiver to FIR mode */ + si->pdata->transceiver_mode(si->dev, IR_FIRMODE); + + /* configure GPIO46/47 */ + pxa_gpio_mode(GPIO46_ICPRXD_MD); + pxa_gpio_mode(GPIO47_ICPTXD_MD); + + /* enable the FICP clock */ + pxa_set_cken(CKEN13_FICP, 1); + + si->speed = speed; + pxa_irda_fir_dma_rx_start(si); + ICCR0 = ICCR0_ITR | ICCR0_RXE; + + local_irq_restore(flags); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/* SIR interrupt service routine. */ +static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct pxa_irda *si = netdev_priv(dev); + int iir, lsr, data; + + iir = STIIR; + + switch (iir & 0x0F) { + case 0x06: /* Receiver Line Status */ + lsr = STLSR; + while (lsr & LSR_FIFOE) { + data = STRBR; + if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { + printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); + si->stats.rx_errors++; + if (lsr & LSR_FE) + si->stats.rx_frame_errors++; + if (lsr & LSR_OE) + si->stats.rx_fifo_errors++; + } else { + si->stats.rx_bytes++; + async_unwrap_char(dev, &si->stats, &si->rx_buff, data); + } + lsr = STLSR; + } + dev->last_rx = jiffies; + si->last_oscr = OSCR; + break; + + case 0x04: /* Received Data Available */ + /* forth through */ + + case 0x0C: /* Character Timeout Indication */ + do { + si->stats.rx_bytes++; + async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR); + } while (STLSR & LSR_DR); + dev->last_rx = jiffies; + si->last_oscr = OSCR; + break; + + case 0x02: /* Transmit FIFO Data Request */ + while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) { + STTHR = *si->tx_buff.data++; + si->tx_buff.len -= 1; + } + + if (si->tx_buff.len == 0) { + si->stats.tx_packets++; + si->stats.tx_bytes += si->tx_buff.data - + si->tx_buff.head; + + /* We need to ensure that the transmitter has finished. */ + while ((STLSR & LSR_TEMT) == 0) + cpu_relax(); + si->last_oscr = OSCR; + + /* + * Ok, we've finished transmitting. Now enable + * the receiver. Sometimes we get a receive IRQ + * immediately after a transmit... + */ + if (si->newspeed) { + pxa_irda_set_speed(si, si->newspeed); + si->newspeed = 0; + } else { + /* enable IR Receiver, disable IR Transmitter */ + STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; + /* enable STUART and receive interrupts */ + STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; + } + /* I'm hungry! */ + netif_wake_queue(dev); + } + break; + } + + return IRQ_HANDLED; +} + +/* FIR Receive DMA interrupt handler */ +static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs) +{ + int dcsr = DCSR(channel); + + DCSR(channel) = dcsr & ~DCSR_RUN; + + printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr); +} + +/* FIR Transmit DMA interrupt handler */ +static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs) +{ + struct net_device *dev = data; + struct pxa_irda *si = netdev_priv(dev); + int dcsr; + + dcsr = DCSR(channel); + DCSR(channel) = dcsr & ~DCSR_RUN; + + if (dcsr & DCSR_ENDINTR) { + si->stats.tx_packets++; + si->stats.tx_bytes += si->dma_tx_buff_len; + } else { + si->stats.tx_errors++; + } + + while (ICSR1 & ICSR1_TBY) + cpu_relax(); + si->last_oscr = OSCR; + + /* + * HACK: It looks like the TBY bit is dropped too soon. + * Without this delay things break. + */ + udelay(120); + + if (si->newspeed) { + pxa_irda_set_speed(si, si->newspeed); + si->newspeed = 0; + } else { + ICCR0 = 0; + pxa_irda_fir_dma_rx_start(si); + ICCR0 = ICCR0_ITR | ICCR0_RXE; + } + netif_wake_queue(dev); +} + +/* EIF(Error in FIFO/End in Frame) handler for FIR */ +static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev) +{ + unsigned int len, stat, data; + + /* Get the current data position. */ + len = DTADR(si->rxdma) - si->dma_rx_buff_phy; + + do { + /* Read Status, and then Data. */ + stat = ICSR1; + rmb(); + data = ICDR; + + if (stat & (ICSR1_CRE | ICSR1_ROR)) { + si->stats.rx_errors++; + if (stat & ICSR1_CRE) { + printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n"); + si->stats.rx_crc_errors++; + } + if (stat & ICSR1_ROR) { + printk(KERN_DEBUG "pxa_ir: fir receive overrun\n"); + si->stats.rx_frame_errors++; + } + } else { + si->dma_rx_buff[len++] = data; + } + /* If we hit the end of frame, there's no point in continuing. */ + if (stat & ICSR1_EOF) + break; + } while (ICSR0 & ICSR0_EIF); + + if (stat & ICSR1_EOF) { + /* end of frame. */ + struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC); + if (!skb) { + printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n"); + si->stats.rx_dropped++; + return; + } + + /* Align IP header to 20 bytes */ + skb_reserve(skb, 1); + memcpy(skb->data, si->dma_rx_buff, len); + skb_put(skb, len); + + /* Feed it to IrLAP */ + skb->dev = dev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + + si->stats.rx_packets++; + si->stats.rx_bytes += len; + + dev->last_rx = jiffies; + } +} + +/* FIR interrupt handler */ +static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct pxa_irda *si = netdev_priv(dev); + int icsr0; + + /* stop RX DMA */ + DCSR(si->rxdma) &= ~DCSR_RUN; + si->last_oscr = OSCR; + icsr0 = ICSR0; + + if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) { + if (icsr0 & ICSR0_FRE) { + printk(KERN_DEBUG "pxa_ir: fir receive frame error\n"); + si->stats.rx_frame_errors++; + } else { + printk(KERN_DEBUG "pxa_ir: fir receive abort\n"); + si->stats.rx_errors++; + } + ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB); + } + + if (icsr0 & ICSR0_EIF) { + /* An error in FIFO occured, or there is a end of frame */ + pxa_irda_fir_irq_eif(si, dev); + } + + ICCR0 = 0; + pxa_irda_fir_dma_rx_start(si); + ICCR0 = ICCR0_ITR | ICCR0_RXE; + + return IRQ_HANDLED; +} + +/* hard_xmit interface of irda device */ +static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct pxa_irda *si = netdev_priv(dev); + int speed = irda_get_next_speed(skb); + + /* + * Does this packet contain a request to change the interface + * speed? If so, remember it until we complete the transmission + * of this frame. + */ + if (speed != si->speed && speed != -1) + si->newspeed = speed; + + /* + * If this is an empty frame, we can bypass a lot. + */ + if (skb->len == 0) { + if (si->newspeed) { + si->newspeed = 0; + pxa_irda_set_speed(si, speed); + } + dev_kfree_skb(skb); + return 0; + } + + netif_stop_queue(dev); + + if (!IS_FIR(si)) { + si->tx_buff.data = si->tx_buff.head; + si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); + + /* Disable STUART interrupts and switch to transmit mode. */ + STIER = 0; + STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6; + + /* enable STUART and transmit interrupts */ + STIER = IER_UUE | IER_TIE; + } else { + unsigned long mtt = irda_get_mtt(skb); + + si->dma_tx_buff_len = skb->len; + memcpy(si->dma_tx_buff, skb->data, skb->len); + + if (mtt) + while ((unsigned)(OSCR - si->last_oscr)/4 < mtt) + cpu_relax(); + + /* stop RX DMA, disable FICP */ + DCSR(si->rxdma) &= ~DCSR_RUN; + ICCR0 = 0; + + pxa_irda_fir_dma_tx_start(si); + ICCR0 = ICCR0_ITR | ICCR0_TXE; + } + + dev_kfree_skb(skb); + dev->trans_start = jiffies; + return 0; +} + +static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) +{ + struct if_irda_req *rq = (struct if_irda_req *)ifreq; + struct pxa_irda *si = netdev_priv(dev); + int ret; + + switch (cmd) { + case SIOCSBANDWIDTH: + ret = -EPERM; + if (capable(CAP_NET_ADMIN)) { + /* + * We are unable to set the speed if the + * device is not running. + */ + if (netif_running(dev)) { + ret = pxa_irda_set_speed(si, + rq->ifr_baudrate); + } else { + printk(KERN_INFO "pxa_ir: SIOCSBANDWIDTH: !netif_running\n"); + ret = 0; + } + } + break; + + case SIOCSMEDIABUSY: + ret = -EPERM; + if (capable(CAP_NET_ADMIN)) { + irda_device_set_media_busy(dev, TRUE); + ret = 0; + } + break; + + case SIOCGRECEIVING: + ret = 0; + rq->ifr_receiving = IS_FIR(si) ? 0 + : si->rx_buff.state != OUTSIDE_FRAME; + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static struct net_device_stats *pxa_irda_stats(struct net_device *dev) +{ + struct pxa_irda *si = netdev_priv(dev); + return &si->stats; +} + +static void pxa_irda_startup(struct pxa_irda *si) +{ + /* Disable STUART interrupts */ + STIER = 0; + /* enable STUART interrupt to the processor */ + STMCR = MCR_OUT2; + /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */ + STLCR = LCR_WLS0 | LCR_WLS1; + /* enable FIFO, we use FIFO to improve performance */ + STFCR = FCR_TRFIFOE | FCR_ITL_32; + + /* disable FICP */ + ICCR0 = 0; + /* configure FICP ICCR2 */ + ICCR2 = ICCR2_TXP | ICCR2_TRIG_32; + + /* configure DMAC */ + DRCMR17 = si->rxdma | DRCMR_MAPVLD; + DRCMR18 = si->txdma | DRCMR_MAPVLD; + + /* force SIR reinitialization */ + si->speed = 4000000; + pxa_irda_set_speed(si, 9600); + + printk(KERN_DEBUG "pxa_ir: irda startup\n"); +} + +static void pxa_irda_shutdown(struct pxa_irda *si) +{ + unsigned long flags; + + local_irq_save(flags); + + /* disable STUART and interrupt */ + STIER = 0; + /* disable STUART SIR mode */ + STISR = 0; + /* disable the STUART clock */ + pxa_set_cken(CKEN5_STUART, 0); + + /* disable DMA */ + DCSR(si->txdma) &= ~DCSR_RUN; + DCSR(si->rxdma) &= ~DCSR_RUN; + /* disable FICP */ + ICCR0 = 0; + /* disable the FICP clock */ + pxa_set_cken(CKEN13_FICP, 0); + + DRCMR17 = 0; + DRCMR18 = 0; + + local_irq_restore(flags); + + /* power off board transceiver */ + si->pdata->transceiver_mode(si->dev, IR_OFF); + + printk(KERN_DEBUG "pxa_ir: irda shutdown\n"); +} + +static int pxa_irda_start(struct net_device *dev) +{ + struct pxa_irda *si = netdev_priv(dev); + int err; + + si->speed = 9600; + + err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev); + if (err) + goto err_irq1; + + err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev); + if (err) + goto err_irq2; + + /* + * The interrupt must remain disabled for now. + */ + disable_irq(IRQ_STUART); + disable_irq(IRQ_ICP); + + err = -EBUSY; + si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev); + if (si->rxdma < 0) + goto err_rx_dma; + + si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev); + if (si->txdma < 0) + goto err_tx_dma; + + err = -ENOMEM; + si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, + &si->dma_rx_buff_phy, GFP_KERNEL ); + if (!si->dma_rx_buff) + goto err_dma_rx_buff; + + si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, + &si->dma_tx_buff_phy, GFP_KERNEL ); + if (!si->dma_tx_buff) + goto err_dma_tx_buff; + + /* Setup the serial port for the initial speed. */ + pxa_irda_startup(si); + + /* + * Open a new IrLAP layer instance. + */ + si->irlap = irlap_open(dev, &si->qos, "pxa"); + err = -ENOMEM; + if (!si->irlap) + goto err_irlap; + + /* + * Now enable the interrupt and start the queue + */ + enable_irq(IRQ_STUART); + enable_irq(IRQ_ICP); + netif_start_queue(dev); + + printk(KERN_DEBUG "pxa_ir: irda driver opened\n"); + + return 0; + +err_irlap: + pxa_irda_shutdown(si); + dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy); +err_dma_tx_buff: + dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy); +err_dma_rx_buff: + pxa_free_dma(si->txdma); +err_tx_dma: + pxa_free_dma(si->rxdma); +err_rx_dma: + free_irq(IRQ_ICP, dev); +err_irq2: + free_irq(IRQ_STUART, dev); +err_irq1: + + return err; +} + +static int pxa_irda_stop(struct net_device *dev) +{ + struct pxa_irda *si = netdev_priv(dev); + + netif_stop_queue(dev); + + pxa_irda_shutdown(si); + + /* Stop IrLAP */ + if (si->irlap) { + irlap_close(si->irlap); + si->irlap = NULL; + } + + free_irq(IRQ_STUART, dev); + free_irq(IRQ_ICP, dev); + + pxa_free_dma(si->rxdma); + pxa_free_dma(si->txdma); + + if (si->dma_rx_buff) + dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy); + if (si->dma_tx_buff) + dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy); + + printk(KERN_DEBUG "pxa_ir: irda driver closed\n"); + return 0; +} + +static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level) +{ + struct net_device *dev = dev_get_drvdata(_dev); + struct pxa_irda *si; + + if (!dev || level != SUSPEND_DISABLE) + return 0; + + if (netif_running(dev)) { + si = netdev_priv(dev); + netif_device_detach(dev); + pxa_irda_shutdown(si); + } + + return 0; +} + +static int pxa_irda_resume(struct device *_dev, u32 level) +{ + struct net_device *dev = dev_get_drvdata(_dev); + struct pxa_irda *si; + + if (!dev || level != RESUME_ENABLE) + return 0; + + if (netif_running(dev)) { + si = netdev_priv(dev); + pxa_irda_startup(si); + netif_device_attach(dev); + netif_wake_queue(dev); + } + + return 0; +} + + +static int pxa_irda_init_iobuf(iobuff_t *io, int size) +{ + io->head = kmalloc(size, GFP_KERNEL | GFP_DMA); + if (io->head != NULL) { + io->truesize = size; + io->in_frame = FALSE; + io->state = OUTSIDE_FRAME; + io->data = io->head; + } + return io->head ? 0 : -ENOMEM; +} + +static int pxa_irda_probe(struct device *_dev) +{ + struct platform_device *pdev = to_platform_device(_dev); + struct net_device *dev; + struct pxa_irda *si; + unsigned int baudrate_mask; + int err; + + if (!pdev->dev.platform_data) + return -ENODEV; + + err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY; + if (err) + goto err_mem_1; + + err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY; + if (err) + goto err_mem_2; + + dev = alloc_irdadev(sizeof(struct pxa_irda)); + if (!dev) + goto err_mem_3; + + si = netdev_priv(dev); + si->dev = &pdev->dev; + si->pdata = pdev->dev.platform_data; + + /* + * Initialise the SIR buffers + */ + err = pxa_irda_init_iobuf(&si->rx_buff, 14384); + if (err) + goto err_mem_4; + err = pxa_irda_init_iobuf(&si->tx_buff, 4000); + if (err) + goto err_mem_5; + + dev->hard_start_xmit = pxa_irda_hard_xmit; + dev->open = pxa_irda_start; + dev->stop = pxa_irda_stop; + dev->do_ioctl = pxa_irda_ioctl; + dev->get_stats = pxa_irda_stats; + + irda_init_max_qos_capabilies(&si->qos); + + baudrate_mask = 0; + if (si->pdata->transceiver_cap & IR_SIRMODE) + baudrate_mask |= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + if (si->pdata->transceiver_cap & IR_FIRMODE) + baudrate_mask |= IR_4000000 << 8; + + si->qos.baud_rate.bits &= baudrate_mask; + si->qos.min_turn_time.bits = 7; /* 1ms or more */ + + irda_qos_bits_to_value(&si->qos); + + err = register_netdev(dev); + + if (err == 0) + dev_set_drvdata(&pdev->dev, dev); + + if (err) { + kfree(si->tx_buff.head); +err_mem_5: + kfree(si->rx_buff.head); +err_mem_4: + free_netdev(dev); +err_mem_3: + release_mem_region(__PREG(FICP), 0x1c); +err_mem_2: + release_mem_region(__PREG(STUART), 0x24); + } +err_mem_1: + return err; +} + +static int pxa_irda_remove(struct device *_dev) +{ + struct net_device *dev = dev_get_drvdata(_dev); + + if (dev) { + struct pxa_irda *si = netdev_priv(dev); + unregister_netdev(dev); + kfree(si->tx_buff.head); + kfree(si->rx_buff.head); + free_netdev(dev); + } + + release_mem_region(__PREG(STUART), 0x24); + release_mem_region(__PREG(FICP), 0x1c); + + return 0; +} + +static struct device_driver pxa_ir_driver = { + .name = "pxa2xx-ir", + .bus = &platform_bus_type, + .probe = pxa_irda_probe, + .remove = pxa_irda_remove, + .suspend = pxa_irda_suspend, + .resume = pxa_irda_resume, +}; + +static int __init pxa_irda_init(void) +{ + return driver_register(&pxa_ir_driver); +} + +static void __exit pxa_irda_exit(void) +{ + driver_unregister(&pxa_ir_driver); +} + +module_init(pxa_irda_init); +module_exit(pxa_irda_exit); + +MODULE_LICENSE("GPL"); diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h new file mode 100644 index 000000000000..748406f384c2 --- /dev/null +++ b/include/asm-arm/arch-pxa/irda.h @@ -0,0 +1,17 @@ +#ifndef ASMARM_ARCH_IRDA_H +#define ASMARM_ARCH_IRDA_H + +/* board specific transceiver capabilities */ + +#define IR_OFF 1 +#define IR_SIRMODE 2 +#define IR_FIRMODE 4 + +struct pxaficp_platform_data { + int transceiver_cap; + void (*transceiver_mode)(struct device *dev, int mode); +}; + +extern void pxa_set_ficp_info(struct pxaficp_platform_data *info); + +#endif diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 75f085dc9894..a75a2470f4f5 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1032,14 +1032,12 @@ #define ICCR0_LBM (1 << 1) /* Loopback mode */ #define ICCR0_ITR (1 << 0) /* IrDA transmission */ -#ifdef CONFIG_PXA27x #define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ #define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ #define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ #define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ #define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ #define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ -#endif #ifdef CONFIG_PXA27x #define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ From 13b1d677d2c872e2d05ef6241b499b6e1f6f91ba Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:40 +0100 Subject: [PATCH 0579/1940] [ARM] 3036/1: AAEC-2000 - Add defines for GPIO registers Patch from Bellido Nicolas Add defines for GPIO registers on the AAEC-2000 processor. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- include/asm-arm/arch-aaec2000/aaec2000.h | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h index 0e9b7e18af05..7472f9e5523f 100644 --- a/include/asm-arm/arch-aaec2000/aaec2000.h +++ b/include/asm-arm/arch-aaec2000/aaec2000.h @@ -17,6 +17,13 @@ #error You must include hardware.h not this file #endif /* __ASM_ARCH_HARDWARE_H */ +/* Chip selects */ +#define AAEC_CS0 0x00000000 +#define AAEC_CS1 0x10000000 +#define AAEC_CS2 0x20000000 +#define AAEC_CS3 0x30000000 + + /* Interrupt controller */ #define IRQ_BASE __REG(0x80000500) #define IRQ_INTSR __REG(0x80000500) /* Int Status Register */ @@ -148,4 +155,47 @@ #define POWER_STFCLR __REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */ #define POWER_CLKSET __REG(0x80000420) /* Clock Speed Control */ +/* GPIO Registers */ +#define AAEC_GPIO_PHYS 0x80000e00 + +#define AAEC_GPIO_PADR __REG(AAEC_GPIO_PHYS + 0x00) +#define AAEC_GPIO_PBDR __REG(AAEC_GPIO_PHYS + 0x04) +#define AAEC_GPIO_PCDR __REG(AAEC_GPIO_PHYS + 0x08) +#define AAEC_GPIO_PDDR __REG(AAEC_GPIO_PHYS + 0x0c) +#define AAEC_GPIO_PADDR __REG(AAEC_GPIO_PHYS + 0x10) +#define AAEC_GPIO_PBDDR __REG(AAEC_GPIO_PHYS + 0x14) +#define AAEC_GPIO_PCDDR __REG(AAEC_GPIO_PHYS + 0x18) +#define AAEC_GPIO_PDDDR __REG(AAEC_GPIO_PHYS + 0x1c) +#define AAEC_GPIO_PEDR __REG(AAEC_GPIO_PHYS + 0x20) +#define AAEC_GPIO_PEDDR __REG(AAEC_GPIO_PHYS + 0x24) +#define AAEC_GPIO_KSCAN __REG(AAEC_GPIO_PHYS + 0x28) +#define AAEC_GPIO_PINMUX __REG(AAEC_GPIO_PHYS + 0x2c) +#define AAEC_GPIO_PFDR __REG(AAEC_GPIO_PHYS + 0x30) +#define AAEC_GPIO_PFDDR __REG(AAEC_GPIO_PHYS + 0x34) +#define AAEC_GPIO_PGDR __REG(AAEC_GPIO_PHYS + 0x38) +#define AAEC_GPIO_PGDDR __REG(AAEC_GPIO_PHYS + 0x3c) +#define AAEC_GPIO_PHDR __REG(AAEC_GPIO_PHYS + 0x40) +#define AAEC_GPIO_PHDDR __REG(AAEC_GPIO_PHYS + 0x44) +#define AAEC_GPIO_RAZ __REG(AAEC_GPIO_PHYS + 0x48) +#define AAEC_GPIO_INTTYPE1 __REG(AAEC_GPIO_PHYS + 0x4c) +#define AAEC_GPIO_INTTYPE2 __REG(AAEC_GPIO_PHYS + 0x50) +#define AAEC_GPIO_FEOI __REG(AAEC_GPIO_PHYS + 0x54) +#define AAEC_GPIO_INTEN __REG(AAEC_GPIO_PHYS + 0x58) +#define AAEC_GPIO_INTSTATUS __REG(AAEC_GPIO_PHYS + 0x5c) +#define AAEC_GPIO_RAWINTSTATUS __REG(AAEC_GPIO_PHYS + 0x60) +#define AAEC_GPIO_DB __REG(AAEC_GPIO_PHYS + 0x64) +#define AAEC_GPIO_PAPINDR __REG(AAEC_GPIO_PHYS + 0x68) +#define AAEC_GPIO_PBPINDR __REG(AAEC_GPIO_PHYS + 0x6c) +#define AAEC_GPIO_PCPINDR __REG(AAEC_GPIO_PHYS + 0x70) +#define AAEC_GPIO_PDPINDR __REG(AAEC_GPIO_PHYS + 0x74) +#define AAEC_GPIO_PEPINDR __REG(AAEC_GPIO_PHYS + 0x78) +#define AAEC_GPIO_PFPINDR __REG(AAEC_GPIO_PHYS + 0x7c) +#define AAEC_GPIO_PGPINDR __REG(AAEC_GPIO_PHYS + 0x80) +#define AAEC_GPIO_PHPINDR __REG(AAEC_GPIO_PHYS + 0x84) + +#define AAEC_GPIO_PINMUX_PE0CON (1 << 0) +#define AAEC_GPIO_PINMUX_PD0CON (1 << 1) +#define AAEC_GPIO_PINMUX_CODECON (1 << 2) +#define AAEC_GPIO_PINMUX_UART3CON (1 << 3) + #endif /* __ARM_ARCH_AAEC2000_H */ From 4028ef4cc1fea245906a2dbd4df1ac9f0353ef5f Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:40 +0100 Subject: [PATCH 0580/1940] [ARM] 3037/1: AAED-2000 - Add defines for GPIO registers on external port. Patch from Bellido Nicolas The AAED-2000 board has GPIO pins on an external port. This patch adds the defines, and do the necessary mapping. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- arch/arm/mach-aaec2000/aaed2000.c | 7 +++++ include/asm-arm/arch-aaec2000/aaed2000.h | 40 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 include/asm-arm/arch-aaec2000/aaed2000.h diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index c9d899886648..7b0a1c7d64a9 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -27,6 +27,8 @@ #include #include +#include + #include "core.h" static void __init aaed2000_init_irq(void) @@ -34,9 +36,14 @@ static void __init aaed2000_init_irq(void) aaec2000_init_irq(); } +static struct map_desc aaed2000_io_desc[] __initdata = { + { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */ +}; + static void __init aaed2000_map_io(void) { aaec2000_map_io(); + iotable_init(aaed2000_io_desc, ARRAY_SIZE(aaed2000_io_desc)); } MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") diff --git a/include/asm-arm/arch-aaec2000/aaed2000.h b/include/asm-arm/arch-aaec2000/aaed2000.h new file mode 100644 index 000000000000..bc76d2badb91 --- /dev/null +++ b/include/asm-arm/arch-aaec2000/aaed2000.h @@ -0,0 +1,40 @@ +/* + * linux/include/asm-arm/arch-aaec2000/aaed2000.h + * + * AAED-2000 specific bits definition + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_AAED2000_H +#define __ASM_ARCH_AAED2000_H + +/* External GPIOs. */ + +#define EXT_GPIO_PBASE AAEC_CS3 +#define EXT_GPIO_VBASE 0xf8100000 +#define EXT_GPIO_LENGTH 0x00001000 + +#define __ext_gpio_p2v(x) ((x) - EXT_GPIO_PBASE + EXT_GPIO_VBASE) +#define __ext_gpio_v2p(x) ((x) + EXT_GPIO_PBASE - EXT_GPIO_VBASE) + +#define __EXT_GPIO_REG(x) (*((volatile u32 *)__ext_gpio_p2v(x))) +#define __EXT_GPIO_PREG(x) (__ext_gpio_v2p((u32)&(x))) + +#define AAED_EXT_GPIO __EXT_GPIO_REG(EXT_GPIO_PBASE) + +#define AAED_EGPIO_KBD_SCAN 0x00003fff /* Keyboard scan data */ +#define AAED_EGPIO_PWR_INT 0x00008fff /* Smart battery charger interrupt */ +#define AAED_EGPIO_SWITCHED 0x000f0000 /* DIP Switches */ +#define AAED_EGPIO_USB_VBUS 0x00400000 /* USB Vbus sense */ +#define AAED_EGPIO_LCD_PWR_EN 0x02000000 /* LCD and backlight PWR enable */ +#define AAED_EGPIO_nLED0 0x20000000 /* LED 0 */ +#define AAED_EGPIO_nLED1 0x20000000 /* LED 1 */ +#define AAED_EGPIO_nLED2 0x20000000 /* LED 2 */ + + +#endif /* __ARM_ARCH_AAED2000_H */ From f0904e29369a940080487fece700e59295196d79 Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:41 +0100 Subject: [PATCH 0581/1940] [ARM] 3038/1: AAEC-2000 - Proper includes in hardware.h Patch from Bellido Nicolas linux/config.h is not necessary in hardware.h, while asm/sizes.h and asm/arch//aaec2000.h will be used later. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- include/asm-arm/arch-aaec2000/hardware.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h index 4c37219e030e..153506fd06ed 100644 --- a/include/asm-arm/arch-aaec2000/hardware.h +++ b/include/asm-arm/arch-aaec2000/hardware.h @@ -11,7 +11,8 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -#include +#include +#include /* The kernel is loaded at physical address 0xf8000000. * We map the IO space a bit after From 4a91ca2eb6eff14bb23f709e6ebf189fdbcdaa22 Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:42 +0100 Subject: [PATCH 0582/1940] [ARM] 3039/1: AAEC-2000 - Add MTD support Patch from Bellido Nicolas This adds platform code for MTD devices on AAEC-2000. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- arch/arm/mach-aaec2000/core.c | 31 ++++++++++++++++++++++++ include/asm-arm/arch-aaec2000/aaec2000.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 9be6c3213254..86c5149b1721 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -163,3 +165,32 @@ struct sys_timer aaec2000_timer = { .offset = aaec2000_gettimeoffset, }; +static struct flash_platform_data aaec2000_flash_data = { + .map_name = "cfi_probe", + .width = 4, +}; + +static struct resource aaec2000_flash_resource = { + .start = AAEC_FLASH_BASE, + .end = AAEC_FLASH_BASE + AAEC_FLASH_SIZE, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device aaec2000_flash_device = { + .name = "armflash", + .id = 0, + .dev = { + .platform_data = &aaec2000_flash_data, + }, + .num_resources = 1, + .resource = &aaec2000_flash_resource, +}; + +static int __init aaec2000_init(void) +{ + platform_device_register(&aaec2000_flash_device); + + return 0; +}; +arch_initcall(aaec2000_init); + diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h index 7472f9e5523f..dfb09389ebc1 100644 --- a/include/asm-arm/arch-aaec2000/aaec2000.h +++ b/include/asm-arm/arch-aaec2000/aaec2000.h @@ -23,6 +23,9 @@ #define AAEC_CS2 0x20000000 #define AAEC_CS3 0x30000000 +/* Flash */ +#define AAEC_FLASH_BASE AAEC_CS0 +#define AAEC_FLASH_SIZE SZ_64M /* Interrupt controller */ #define IRQ_BASE __REG(0x80000500) From 4224b67c9a1d6cbf47b073970bd2db5a89557f92 Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:43 +0100 Subject: [PATCH 0583/1940] [ARM] 3040/1: AAEC-2000 - Preliminary clock interface support Patch from Bellido Nicolas Here is a preliminary clock interface support for the AAEC-2000. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- arch/arm/mach-aaec2000/Makefile | 2 +- arch/arm/mach-aaec2000/clock.c | 110 ++++++++++++++++++++++++++++++++ arch/arm/mach-aaec2000/clock.h | 23 +++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-aaec2000/clock.c create mode 100644 arch/arm/mach-aaec2000/clock.h diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile index 20ec83896c37..a8e462f58bc9 100644 --- a/arch/arm/mach-aaec2000/Makefile +++ b/arch/arm/mach-aaec2000/Makefile @@ -3,7 +3,7 @@ # # Common support (must be linked before board specific support) -obj-y += core.o +obj-y += core.o clock.o # Specific board support obj-$(CONFIG_MACH_AAED2000) += aaed2000.o diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c new file mode 100644 index 000000000000..99e019169dda --- /dev/null +++ b/arch/arm/mach-aaec2000/clock.c @@ -0,0 +1,110 @@ +/* + * linux/arch/arm/mach-aaec2000/clock.c + * + * Copyright (C) 2005 Nicolas Bellido Y Ortega + * + * Based on linux/arch/arm/mach-integrator/clock.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +int clk_use(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_unuse); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + return 0; +} +arch_initcall(clk_init); diff --git a/arch/arm/mach-aaec2000/clock.h b/arch/arm/mach-aaec2000/clock.h new file mode 100644 index 000000000000..d4bb74ff613f --- /dev/null +++ b/arch/arm/mach-aaec2000/clock.h @@ -0,0 +1,23 @@ +/* + * linux/arch/arm/mach-aaec2000/clock.h + * + * Copyright (C) 2005 Nicolas Bellido Y Ortega + * + * Based on linux/arch/arm/mach-integrator/clock.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +struct module; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + void *data; +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); From 049eb3298a832a63c55bc8d8ea4cc881ab99f84b Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:44 +0100 Subject: [PATCH 0584/1940] [ARM] 3041/1: AAEC-2000 - CLCD controller platform glue Patch from Bellido Nicolas The AAEC-2000 has an ARM PrimeCell PL110 Color LCD Controller. This patch contains the platform glue that will be used by specific boards. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-aaec2000/core.c | 90 ++++++++++++++++++++++++ arch/arm/mach-aaec2000/core.h | 11 +++ include/asm-arm/arch-aaec2000/aaec2000.h | 3 + 4 files changed, 105 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d885cc48bae1..682367bd0f65 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -204,6 +204,7 @@ config ARCH_H720X config ARCH_AAEC2000 bool "Agilent AAEC-2000 based" + select ARM_AMBA help This enables support for systems based on the Agilent AAEC-2000 diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 86c5149b1721..0c53dab80905 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -16,18 +16,24 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include #include #include +#include "core.h" +#include "clock.h" + /* * Common I/O mapping: * @@ -165,6 +171,81 @@ struct sys_timer aaec2000_timer = { .offset = aaec2000_gettimeoffset, }; +static struct clcd_panel mach_clcd_panel; + +static int aaec2000_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->panel = &mach_clcd_panel; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, SZ_1M, + &dma, GFP_KERNEL); + + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = SZ_1M; + + return 0; +} + +static int aaec2000_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void aaec2000_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board clcd_plat_data = { + .name = "AAEC-2000", + .check = clcdfb_check, + .decode = clcdfb_decode, + .setup = aaec2000_clcd_setup, + .mmap = aaec2000_clcd_mmap, + .remove = aaec2000_clcd_remove, +}; + +static struct amba_device clcd_device = { + .dev = { + .bus_id = "mb:16", + .coherent_dma_mask = ~0, + .platform_data = &clcd_plat_data, + }, + .res = { + .start = AAEC_CLCD_PHYS, + .end = AAEC_CLCD_PHYS + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { INT_LCD, NO_IRQ }, + .periphid = 0x41110, +}; + +static struct amba_device *amba_devs[] __initdata = { + &clcd_device, +}; + +static struct clk aaec2000_clcd_clk = { + .name = "CLCDCLK", +}; + +void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *clcd) +{ + clcd_plat_data.enable = clcd->enable; + clcd_plat_data.disable = clcd->disable; + memcpy(&mach_clcd_panel, &clcd->panel, sizeof(struct clcd_panel)); +} + static struct flash_platform_data aaec2000_flash_data = { .map_name = "cfi_probe", .width = 4, @@ -188,6 +269,15 @@ static struct platform_device aaec2000_flash_device = { static int __init aaec2000_init(void) { + int i; + + clk_register(&aaec2000_clcd_clk); + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + platform_device_register(&aaec2000_flash_device); return 0; diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h index 91893d848c16..daefc0ea14a1 100644 --- a/arch/arm/mach-aaec2000/core.h +++ b/arch/arm/mach-aaec2000/core.h @@ -9,8 +9,19 @@ * */ +#include + struct sys_timer; extern struct sys_timer aaec2000_timer; extern void __init aaec2000_map_io(void); extern void __init aaec2000_init_irq(void); + +struct aaec2000_clcd_info { + struct clcd_panel panel; + void (*disable)(struct clcd_fb *); + void (*enable)(struct clcd_fb *); +}; + +extern void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *); + diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h index dfb09389ebc1..002227924b9f 100644 --- a/include/asm-arm/arch-aaec2000/aaec2000.h +++ b/include/asm-arm/arch-aaec2000/aaec2000.h @@ -201,4 +201,7 @@ #define AAEC_GPIO_PINMUX_CODECON (1 << 2) #define AAEC_GPIO_PINMUX_UART3CON (1 << 3) +/* LCD Controller */ +#define AAEC_CLCD_PHYS 0x80003000 + #endif /* __ARM_ARCH_AAEC2000_H */ From 50f4c001bc1534db77663592496204ceba151e97 Mon Sep 17 00:00:00 2001 From: Bellido Nicolas Date: Fri, 28 Oct 2005 16:51:44 +0100 Subject: [PATCH 0585/1940] [ARM] 3042/1: AAED-2000 - LCD panel informations Patch from Bellido Nicolas The AAED-2000 is equiped with an 640x480 LCD. This adds the parameters that will be passed to the AAEC-2000 platform code. Signed-off-by: Nicolas Bellido Signed-off-by: Russell King --- arch/arm/mach-aaec2000/aaed2000.c | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 7b0a1c7d64a9..f5ef69702296 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -31,11 +31,53 @@ #include "core.h" +static void aaed2000_clcd_disable(struct clcd_fb *fb) +{ + AAED_EXT_GPIO &= ~AAED_EGPIO_LCD_PWR_EN; +} + +static void aaed2000_clcd_enable(struct clcd_fb *fb) +{ + AAED_EXT_GPIO |= AAED_EGPIO_LCD_PWR_EN; +} + +struct aaec2000_clcd_info clcd_info = { + .enable = aaed2000_clcd_enable, + .disable = aaed2000_clcd_disable, + .panel = { + .mode = { + .name = "Sharp", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 20, + .right_margin = 44, + .upper_margin = 21, + .lower_margin = 34, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_IVS | TIM2_IHS, + .cntl = CNTL_LCDTFT, + .bpp = 16, + }, +}; + static void __init aaed2000_init_irq(void) { aaec2000_init_irq(); } +static void __init aaed2000_init(void) +{ + aaec2000_set_clcd_plat_data(&clcd_info); +} + static struct map_desc aaed2000_io_desc[] __initdata = { { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */ }; @@ -54,4 +96,5 @@ MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") .map_io = aaed2000_map_io, .init_irq = aaed2000_init_irq, .timer = &aaec2000_timer, + .init_machine = aaed2000_init, MACHINE_END From 71e0f32fbc7841d9c34949655039dcf4635540f0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Oct 2005 11:21:10 -0500 Subject: [PATCH 0586/1940] [SCSI] aacraid: Use DMA mask defines From: Mark Haverkamp Received from Mark Salyzyn. This patch changes the driver over to utilizing the DMA_64BIT_MASK and DMA_32BIT_MASK manifests. Applies to the scsi-rc-fixes-2.6 git tree. Signed-off-by: Mark Haverkamp Rejects fixed up and Signed-off-by: James Bottomley --- drivers/scsi/aacraid/aachba.c | 8 ++++---- drivers/scsi/aacraid/linit.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a8e3dfcd0dc7..b864d3d4d133 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -785,12 +785,12 @@ int aac_get_adapter_info(struct aac_dev* dev) dev->dac_support = (dacmode!=0); } if(dev->dac_support != 0) { - if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL) && - !pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL)) { + if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && + !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", dev->name, dev->id); - } else if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFULL) && - !pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFULL)) { + } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && + !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", dev->name, dev->id); dev->dac_support = 0; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 4ff29d7f5825..7a25dab48a9e 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -751,8 +751,8 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, if (pci_enable_device(pdev)) goto out; - if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL) || - pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL)) + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || + pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) goto out; /* * If the quirk31 bit is set, the adapter needs adapter @@ -795,9 +795,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, * address space. */ if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) - if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL)) - goto out_free_fibs; - + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) + goto out_deinit; + aac->maximum_num_channels = aac_drivers[index].channels; aac_get_adapter_info(aac); From 794d0601e7a379f0188655115a3642f1e326116f Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Mon, 24 Oct 2005 10:51:53 -0700 Subject: [PATCH 0587/1940] [SCSI] aacraid: fix inquiry page Received from Mark Salyzyn. This patch uses the adapter supplemental information AdapterTypeText as the default for the array name. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley --- drivers/scsi/aacraid/aachba.c | 47 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index b864d3d4d133..44dbbe3dbe95 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -571,17 +571,43 @@ static char *container_types[] = { * files instead of in OS dependant driver source. */ -static void setinqstr(int devtype, void *data, int tindex) +static void setinqstr(struct aac_dev *dev, void *data, int tindex) { struct scsi_inq *str; - struct aac_driver_ident *mp; - mp = aac_get_driver_ident(devtype); - str = (struct scsi_inq *)(data); /* cast data to scsi inq block */ + memset(str, ' ', sizeof(*str)); - inqstrcpy (mp->vname, str->vid); - inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */ + if (dev->supplement_adapter_info.AdapterTypeText[0]) { + char * cp = dev->supplement_adapter_info.AdapterTypeText; + int c = sizeof(str->vid); + while (*cp && *cp != ' ' && --c) + ++cp; + c = *cp; + *cp = '\0'; + inqstrcpy (dev->supplement_adapter_info.AdapterTypeText, + str->vid); + *cp = c; + while (*cp && *cp != ' ') + ++cp; + while (*cp == ' ') + ++cp; + /* last six chars reserved for vol type */ + c = 0; + if (strlen(cp) > sizeof(str->pid)) { + c = cp[sizeof(str->pid)]; + cp[sizeof(str->pid)] = '\0'; + } + inqstrcpy (cp, str->pid); + if (c) + cp[sizeof(str->pid)] = c; + } else { + struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); + + inqstrcpy (mp->vname, str->vid); + /* last six chars reserved for vol type */ + inqstrcpy (mp->model, str->pid); + } if (tindex < (sizeof(container_types)/sizeof(char *))){ char *findit = str->pid; @@ -590,7 +616,9 @@ static void setinqstr(int devtype, void *data, int tindex) /* RAID is superfluous in the context of a RAID device */ if (memcmp(findit-4, "RAID", 4) == 0) *(findit -= 4) = ' '; - inqstrcpy (container_types[tindex], findit + 1); + if (((findit - str->pid) + strlen(container_types[tindex])) + < (sizeof(str->pid) + sizeof(str->prl))) + inqstrcpy (container_types[tindex], findit + 1); } inqstrcpy ("V1.0", str->prl); } @@ -1287,7 +1315,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) struct Scsi_Host *host = scsicmd->device->host; struct aac_dev *dev = (struct aac_dev *)host->hostdata; struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; - int cardtype = dev->cardtype; int ret; /* @@ -1385,14 +1412,14 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * see: .c i.e. aac.c */ if (scsicmd->device->id == host->this_id) { - setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); + setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; } - setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); + setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); return aac_get_container_name(scsicmd, cid); From 9f30a323a4ad96a3867279e0cdea7e2362dca2ee Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Mon, 24 Oct 2005 10:52:02 -0700 Subject: [PATCH 0588/1940] [SCSI] aacraid: fix struct element cpu order Received from Mark Salyzyn. The compat field needed to be in cpu order. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley --- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commctrl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index e40528185d48..bdfd4a7f950e 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1553,7 +1553,7 @@ struct fib_ioctl struct revision { - __le32 compat; + u32 compat; __le32 version; __le32 build; }; diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 71f1cad9b5f0..0459ba7b5bdb 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -408,7 +408,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg) char *driver_version = aac_driver_version; u32 version; - response.compat = cpu_to_le32(1); + response.compat = 1; version = (simple_strtol(driver_version, &driver_version, 10) << 24) | 0x00000400; version += simple_strtol(driver_version + 1, &driver_version, 10) << 16; From e75d51761debffbc5e556e02c8ceda4f8c1a3e83 Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Mon, 24 Oct 2005 10:52:11 -0700 Subject: [PATCH 0589/1940] [SCSI] aacraid: remove compiler warning Received from Mark Salyzyn. This patch resolves a compiler warning on 64 bit architectures. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley --- drivers/scsi/aacraid/commctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 0459ba7b5bdb..ef623bd965f5 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -574,7 +574,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) rcode = -ENOMEM; goto cleanup; } - sg_user[i] = (void __user *)usg->sg[i].addr; + sg_user[i] = (void __user *)(long)usg->sg[i].addr; sg_list[i] = p; // save so we can clean up later sg_indx = i; @@ -624,7 +624,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) rcode = -ENOMEM; goto cleanup; } - sg_user[i] = (void __user *)upsg->sg[i].addr; + sg_user[i] = (void __user *)(long)upsg->sg[i].addr; sg_list[i] = p; // save so we can clean up later sg_indx = i; From 8e0c5ebde82b08f6d996e11983890fc4cc085fab Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Mon, 24 Oct 2005 10:52:22 -0700 Subject: [PATCH 0590/1940] [SCSI] aacraid: Newer adapter communication iterface support Received from Mark Salyzyn. This patch adds the 'new comm' interface, which modern AAC based adapters that are less than a year old support in the name of much improved performance. These modern adapters support both the legacy and the 'new comm' interfaces. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley --- drivers/scsi/aacraid/README | 2 +- drivers/scsi/aacraid/TODO | 1 - drivers/scsi/aacraid/aachba.c | 23 ++--- drivers/scsi/aacraid/aacraid.h | 25 +++-- drivers/scsi/aacraid/comminit.c | 25 +++++ drivers/scsi/aacraid/commsup.c | 86 ++++++++++------ drivers/scsi/aacraid/dpcsup.c | 115 ++++++++++++++++++++- drivers/scsi/aacraid/linit.c | 27 ++++- drivers/scsi/aacraid/rkt.c | 172 ++++++++++++++++++++------------ drivers/scsi/aacraid/rx.c | 157 +++++++++++++++++------------ drivers/scsi/aacraid/sa.c | 38 +------ 11 files changed, 453 insertions(+), 218 deletions(-) diff --git a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README index 4fa524687bc5..4193865d419c 100644 --- a/drivers/scsi/aacraid/README +++ b/drivers/scsi/aacraid/README @@ -57,7 +57,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit, (fixed 64bit and 64G memory model, changed confusing naming convention where fibs that go to the hardware are consistently called hw_fibs and not just fibs like the name of the driver tracking structure) -Mark Salyzyn Fixed panic issues and added some new product ids for upcoming hbas. +Mark Salyzyn Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations. Original Driver ------------------------- diff --git a/drivers/scsi/aacraid/TODO b/drivers/scsi/aacraid/TODO index 2f148b4617dc..78dc863eff4f 100644 --- a/drivers/scsi/aacraid/TODO +++ b/drivers/scsi/aacraid/TODO @@ -1,4 +1,3 @@ o Testing o More testing -o Drop irq_mask, basically unused o I/O size increase diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a913196459d5..acc3d9209879 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -359,15 +359,6 @@ int aac_get_containers(struct aac_dev *dev) return status; } -static void aac_io_done(struct scsi_cmnd * scsicmd) -{ - unsigned long cpu_flags; - struct Scsi_Host *host = scsicmd->device->host; - spin_lock_irqsave(host->host_lock, cpu_flags); - scsicmd->scsi_done(scsicmd); - spin_unlock_irqrestore(host->host_lock, cpu_flags); -} - static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) { void *buf; @@ -424,7 +415,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) fib_complete(fibptr); fib_free(fibptr); - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); } /** @@ -988,7 +979,7 @@ static void io_callback(void *context, struct fib * fibptr) fib_complete(fibptr); fib_free(fibptr); - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); } static int aac_read(struct scsi_cmnd * scsicmd, int cid) @@ -1167,7 +1158,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return 0; @@ -1239,7 +1230,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) */ if (!(cmd_fibcontext = fib_alloc(dev))) { scsicmd->result = DID_ERROR << 16; - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); return 0; } fib_init(cmd_fibcontext); @@ -1336,7 +1327,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); @@ -1380,7 +1371,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) fib_complete(fibptr); fib_free(fibptr); - aac_io_done(cmd); + cmd->scsi_done(cmd); } static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) @@ -2097,7 +2088,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) fib_complete(fibptr); fib_free(fibptr); - aac_io_done(scsicmd); + scsicmd->scsi_done(scsicmd); } /** diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 2ebe402bc31a..30fd8d6e3f31 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -481,6 +481,7 @@ enum aac_log_level { #define FSAFS_NTC_FIB_CONTEXT 0x030c struct aac_dev; +struct fib; struct adapter_ops { @@ -489,6 +490,7 @@ struct adapter_ops void (*adapter_disable_int)(struct aac_dev *dev); int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); int (*adapter_check_health)(struct aac_dev *dev); + int (*adapter_send)(struct fib * fib); }; /* @@ -659,6 +661,10 @@ struct rx_mu_registers { Status Register */ __le32 OIMR; /* 1334h | 34h | Outbound Interrupt Mask Register */ + __le32 reserved2; /* 1338h | 38h | Reserved */ + __le32 reserved3; /* 133Ch | 3Ch | Reserved */ + __le32 InboundQueue;/* 1340h | 40h | Inbound Queue Port relative to firmware */ + __le32 OutboundQueue;/*1344h | 44h | Outbound Queue Port relative to firmware */ /* * Must access through ATU Inbound Translation Window */ }; @@ -693,8 +699,8 @@ struct rx_inbound { #define OutboundDoorbellReg MUnit.ODR struct rx_registers { - struct rx_mu_registers MUnit; /* 1300h - 1334h */ - __le32 reserved1[6]; /* 1338h - 134ch */ + struct rx_mu_registers MUnit; /* 1300h - 1344h */ + __le32 reserved1[2]; /* 1348h - 134ch */ struct rx_inbound IndexRegs; }; @@ -711,8 +717,8 @@ struct rx_registers { #define rkt_inbound rx_inbound struct rkt_registers { - struct rkt_mu_registers MUnit; /* 1300h - 1334h */ - __le32 reserved1[1010]; /* 1338h - 22fch */ + struct rkt_mu_registers MUnit; /* 1300h - 1344h */ + __le32 reserved1[1006]; /* 1348h - 22fch */ struct rkt_inbound IndexRegs; /* 2300h - */ }; @@ -721,8 +727,6 @@ struct rkt_registers { #define rkt_writeb(AEP, CSR, value) writeb(value, &((AEP)->regs.rkt->CSR)) #define rkt_writel(AEP, CSR, value) writel(value, &((AEP)->regs.rkt->CSR)) -struct fib; - typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); struct aac_fib_context { @@ -937,7 +941,6 @@ struct aac_dev const char *name; int id; - u16 irq_mask; /* * negotiated FIB settings */ @@ -972,6 +975,7 @@ struct aac_dev struct adapter_ops a_ops; unsigned long fsrev; /* Main driver's revision number */ + unsigned base_size; /* Size of mapped in region */ struct aac_init *init; /* Holds initialization info to communicate with adapter */ dma_addr_t init_pa; /* Holds physical address of the init struct */ @@ -992,6 +996,9 @@ struct aac_dev /* * The following is the device specific extension. */ +#if (!defined(AAC_MIN_FOOTPRINT_SIZE)) +# define AAC_MIN_FOOTPRINT_SIZE 8192 +#endif union { struct sa_registers __iomem *sa; @@ -1012,6 +1019,7 @@ struct aac_dev u8 nondasd_support; u8 dac_support; u8 raid_scsi_mode; + u8 new_comm_interface; /* macro side-effects BEWARE */ # define raw_io_interface \ init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) @@ -1034,6 +1042,8 @@ struct aac_dev #define aac_adapter_check_health(dev) \ (dev)->a_ops.adapter_check_health(dev) +#define aac_adapter_send(fib) \ + ((fib)->dev)->a_ops.adapter_send(fib) #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) @@ -1779,6 +1789,7 @@ int aac_rkt_init(struct aac_dev *dev); int aac_sa_init(struct aac_dev *dev); unsigned int aac_response_normal(struct aac_queue * q); unsigned int aac_command_normal(struct aac_queue * q); +unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); int aac_command_thread(struct aac_dev * dev); int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); int fib_adapter_complete(struct fib * fibptr, unsigned short size); diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 59a341b2aedc..82821d331c07 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -116,6 +116,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co } init->InitFlags = 0; + if (dev->new_comm_interface) { + init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); + dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); + } init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); init->MaxFibSize = cpu_to_le32(dev->max_fib_size); @@ -315,12 +319,33 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) - sizeof(struct aac_fibhdr) - sizeof(struct aac_write) + sizeof(struct sgentry)) / sizeof(struct sgentry); + dev->new_comm_interface = 0; dev->raw_io_64 = 0; if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && (status[0] == 0x00000001)) { if (status[1] & AAC_OPT_NEW_COMM_64) dev->raw_io_64 = 1; + if (status[1] & AAC_OPT_NEW_COMM) + dev->new_comm_interface = dev->a_ops.adapter_send != 0; + if (dev->new_comm_interface && (status[2] > dev->base_size)) { + iounmap(dev->regs.sa); + dev->base_size = status[2]; + dprintk((KERN_DEBUG "ioremap(%lx,%d)\n", + host->base, status[2])); + dev->regs.sa = ioremap(host->base, status[2]); + if (dev->regs.sa == NULL) { + /* remap failed, go back ... */ + dev->new_comm_interface = 0; + dev->regs.sa = ioremap(host->base, + AAC_MIN_FOOTPRINT_SIZE); + if (dev->regs.sa == NULL) { + printk(KERN_WARNING + "aacraid: unable to map adapter.\n"); + return NULL; + } + } + } } if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS, 0, 0, 0, 0, 0, 0, diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e4d543a474ae..ee9067255930 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -212,7 +212,7 @@ void fib_init(struct fib *fibptr) hw_fib->header.StructType = FIB_MAGIC; hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); - hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); + hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */ hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); } @@ -380,9 +380,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data) { - u32 index; struct aac_dev * dev = fibptr->dev; - unsigned long nointr = 0; struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_queue * q; unsigned long flags = 0; @@ -417,7 +415,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority * Map the fib into 32bits by using the fib number */ - hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1); + hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); /* * Set FIB state to indicate where it came from and if we want a @@ -456,10 +454,10 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority FIB_COUNTER_INCREMENT(aac_config.FibsSent); - dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index)); dprintk((KERN_DEBUG "Fib contents:.\n")); - dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command)); - dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState)); + dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); + dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); + dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); @@ -469,14 +467,37 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority if(wait) spin_lock_irqsave(&fibptr->event_lock, flags); spin_lock_irqsave(q->lock, qflags); - aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); + if (dev->new_comm_interface) { + unsigned long count = 10000000L; /* 50 seconds */ + list_add_tail(&fibptr->queue, &q->pendingq); + q->numpending++; + spin_unlock_irqrestore(q->lock, qflags); + while (aac_adapter_send(fibptr) != 0) { + if (--count == 0) { + if (wait) + spin_unlock_irqrestore(&fibptr->event_lock, flags); + spin_lock_irqsave(q->lock, qflags); + q->numpending--; + list_del(&fibptr->queue); + spin_unlock_irqrestore(q->lock, qflags); + return -ETIMEDOUT; + } + udelay(5); + } + } else { + u32 index; + unsigned long nointr = 0; + aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); + + list_add_tail(&fibptr->queue, &q->pendingq); + q->numpending++; + *(q->headers.producer) = cpu_to_le32(index + 1); + spin_unlock_irqrestore(q->lock, qflags); + dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index)); + if (!(nointr & aac_config.irq_mod)) + aac_adapter_notify(dev, AdapNormCmdQueue); + } - list_add_tail(&fibptr->queue, &q->pendingq); - q->numpending++; - *(q->headers.producer) = cpu_to_le32(index + 1); - spin_unlock_irqrestore(q->lock, qflags); - if (!(nointr & aac_config.irq_mod)) - aac_adapter_notify(dev, AdapNormCmdQueue); /* * If the caller wanted us to wait for response wait now. */ @@ -492,7 +513,6 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority * hardware failure has occurred. */ unsigned long count = 36000000L; /* 3 minutes */ - unsigned long qflags; while (down_trylock(&fibptr->event_wait)) { if (--count == 0) { spin_lock_irqsave(q->lock, qflags); @@ -621,12 +641,16 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) unsigned long qflags; if (hw_fib->header.XferState == 0) { + if (dev->new_comm_interface) + kfree (hw_fib); return 0; } /* * If we plan to do anything check the structure type first. */ if ( hw_fib->header.StructType != FIB_MAGIC ) { + if (dev->new_comm_interface) + kfree (hw_fib); return -EINVAL; } /* @@ -637,21 +661,25 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) * send the completed cdb to the adapter. */ if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { - u32 index; - hw_fib->header.XferState |= cpu_to_le32(HostProcessed); - if (size) { - size += sizeof(struct aac_fibhdr); - if (size > le16_to_cpu(hw_fib->header.SenderSize)) - return -EMSGSIZE; - hw_fib->header.Size = cpu_to_le16(size); + if (dev->new_comm_interface) { + kfree (hw_fib); + } else { + u32 index; + hw_fib->header.XferState |= cpu_to_le32(HostProcessed); + if (size) { + size += sizeof(struct aac_fibhdr); + if (size > le16_to_cpu(hw_fib->header.SenderSize)) + return -EMSGSIZE; + hw_fib->header.Size = cpu_to_le16(size); + } + q = &dev->queues->queue[AdapNormRespQueue]; + spin_lock_irqsave(q->lock, qflags); + aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr); + *(q->headers.producer) = cpu_to_le32(index + 1); + spin_unlock_irqrestore(q->lock, qflags); + if (!(nointr & (int)aac_config.irq_mod)) + aac_adapter_notify(dev, AdapNormRespQueue); } - q = &dev->queues->queue[AdapNormRespQueue]; - spin_lock_irqsave(q->lock, qflags); - aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr); - *(q->headers.producer) = cpu_to_le32(index + 1); - spin_unlock_irqrestore(q->lock, qflags); - if (!(nointr & (int)aac_config.irq_mod)) - aac_adapter_notify(dev, AdapNormRespQueue); } else { diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index be2e98de9fab..439948ef8251 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -73,7 +73,7 @@ unsigned int aac_response_normal(struct aac_queue * q) int fast; u32 index = le32_to_cpu(entry->addr); fast = index & 0x01; - fib = &dev->fibs[index >> 1]; + fib = &dev->fibs[index >> 2]; hwfib = fib->hw_fib; aac_consumer_free(dev, q, HostNormRespQueue); @@ -213,3 +213,116 @@ unsigned int aac_command_normal(struct aac_queue *q) spin_unlock_irqrestore(q->lock, flags); return 0; } + + +/** + * aac_intr_normal - Handle command replies + * @dev: Device + * @index: completion reference + * + * This DPC routine will be run when the adapter interrupts us to let us + * know there is a response on our normal priority queue. We will pull off + * all QE there are and wake up all the waiters before exiting. + */ + +unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) +{ + u32 index = le32_to_cpu(Index); + + dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, Index)); + if ((index & 0x00000002L)) { + struct hw_fib * hw_fib; + struct fib * fib; + struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue]; + unsigned long flags; + + if (index == 0xFFFFFFFEL) /* Special Case */ + return 0; /* Do nothing */ + /* + * Allocate a FIB. For non queued stuff we can just use + * the stack so we are happy. We need a fib object in order to + * manage the linked lists. + */ + if ((!dev->aif_thread) + || (!(fib = kmalloc(sizeof(struct fib),GFP_ATOMIC)))) + return 1; + if (!(hw_fib = kmalloc(sizeof(struct hw_fib),GFP_ATOMIC))) { + kfree (fib); + return 1; + } + memset(hw_fib, 0, sizeof(struct hw_fib)); + memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib)); + memset(fib, 0, sizeof(struct fib)); + INIT_LIST_HEAD(&fib->fiblink); + fib->type = FSAFS_NTC_FIB_CONTEXT; + fib->size = sizeof(struct fib); + fib->hw_fib = hw_fib; + fib->data = hw_fib->data; + fib->dev = dev; + + spin_lock_irqsave(q->lock, flags); + list_add_tail(&fib->fiblink, &q->cmdq); + wake_up_interruptible(&q->cmdready); + spin_unlock_irqrestore(q->lock, flags); + return 1; + } else { + int fast = index & 0x01; + struct fib * fib = &dev->fibs[index >> 2]; + struct hw_fib * hwfib = fib->hw_fib; + + /* + * Remove this fib from the Outstanding I/O queue. + * But only if it has not already been timed out. + * + * If the fib has been timed out already, then just + * continue. The caller has already been notified that + * the fib timed out. + */ + if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { + printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); + printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); + return 0; + } + + list_del(&fib->queue); + dev->queues->queue[AdapNormCmdQueue].numpending--; + + if (fast) { + /* + * Doctor the fib + */ + *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); + hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); + } + + FIB_COUNTER_INCREMENT(aac_config.FibRecved); + + if (hwfib->header.Command == cpu_to_le16(NuFileSystem)) + { + u32 *pstatus = (u32 *)hwfib->data; + if (*pstatus & cpu_to_le32(0xffff0000)) + *pstatus = cpu_to_le32(ST_OK); + } + if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) + { + if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected)) + FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved); + else + FIB_COUNTER_INCREMENT(aac_config.AsyncRecved); + /* + * NOTE: we cannot touch the fib after this + * call, because it may have been deallocated. + */ + fib->callback(fib->callback_data, fib); + } else { + unsigned long flagv; + dprintk((KERN_INFO "event_wait up\n")); + spin_lock_irqsave(&fib->event_lock, flagv); + fib->done = 1; + up(&fib->event_wait); + spin_unlock_irqrestore(&fib->event_lock, flagv); + FIB_COUNTER_INCREMENT(aac_config.NormalRecved); + } + return 0; + } +} diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index c235d0c0e7a7..ab383d1f59e2 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -788,8 +788,29 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, goto out_free_host; spin_lock_init(&aac->fib_lock); - if ((*aac_drivers[index].init)(aac)) + /* + * Map in the registers from the adapter. + */ + aac->base_size = AAC_MIN_FOOTPRINT_SIZE; + if ((aac->regs.sa = ioremap( + (unsigned long)aac->scsi_host_ptr->base, AAC_MIN_FOOTPRINT_SIZE)) + == NULL) { + printk(KERN_WARNING "%s: unable to map adapter.\n", + AAC_DRIVERNAME); goto out_free_fibs; + } + if ((*aac_drivers[index].init)(aac)) + goto out_unmap; + + /* + * Start any kernel threads needed + */ + aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, + aac, 0); + if (aac->thread_pid < 0) { + printk(KERN_ERR "aacraid: Unable to create command thread.\n"); + goto out_deinit; + } /* * If we had set a smaller DMA mask earlier, set it to 4gig @@ -866,10 +887,11 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, aac_send_shutdown(aac); aac_adapter_disable_int(aac); + free_irq(pdev->irq, aac); + out_unmap: fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); - free_irq(pdev->irq, aac); iounmap(aac->regs.sa); out_free_fibs: kfree(aac->fibs); @@ -910,6 +932,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) iounmap(aac->regs.sa); kfree(aac->fibs); + kfree(aac->fsa_dev); list_del(&aac->entry); scsi_host_put(shost); diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index 557287a0b80b..fc4c73c2a6a9 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c @@ -49,40 +49,57 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) { struct aac_dev *dev = dev_id; - unsigned long bellbits; - u8 intstat, mask; - intstat = rkt_readb(dev, MUnit.OISR); - /* - * Read mask and invert because drawbridge is reversed. - * This allows us to only service interrupts that have - * been enabled. - */ - mask = ~(dev->OIMR); - /* Check to see if this is our interrupt. If it isn't just return */ - if (intstat & mask) - { - bellbits = rkt_readl(dev, OutboundDoorbellReg); - if (bellbits & DoorBellPrintfReady) { - aac_printf(dev, rkt_readl(dev, IndexRegs.Mailbox[5])); - rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); - rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + + if (dev->new_comm_interface) { + u32 Index = rkt_readl(dev, MUnit.OutboundQueue); + if (Index == 0xFFFFFFFFL) + Index = rkt_readl(dev, MUnit.OutboundQueue); + if (Index != 0xFFFFFFFFL) { + do { + if (aac_intr_normal(dev, Index)) { + rkt_writel(dev, MUnit.OutboundQueue, Index); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); + } + Index = rkt_readl(dev, MUnit.OutboundQueue); + } while (Index != 0xFFFFFFFFL); + return IRQ_HANDLED; } - else if (bellbits & DoorBellAdapterNormCmdReady) { - rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); - aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + } else { + unsigned long bellbits; + u8 intstat; + intstat = rkt_readb(dev, MUnit.OISR); + /* + * Read mask and invert because drawbridge is reversed. + * This allows us to only service interrupts that have + * been enabled. + * Check to see if this is our interrupt. If it isn't just return + */ + if (intstat & ~(dev->OIMR)) + { + bellbits = rkt_readl(dev, OutboundDoorbellReg); + if (bellbits & DoorBellPrintfReady) { + aac_printf(dev, rkt_readl (dev, IndexRegs.Mailbox[5])); + rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); + rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + } + else if (bellbits & DoorBellAdapterNormCmdReady) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); +// rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + } + else if (bellbits & DoorBellAdapterNormRespReady) { + rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); + aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + } + else if (bellbits & DoorBellAdapterNormCmdNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + } + else if (bellbits & DoorBellAdapterNormRespNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); + } + return IRQ_HANDLED; } - else if (bellbits & DoorBellAdapterNormRespReady) { - aac_response_normal(&dev->queues->queue[HostNormRespQueue]); - rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); - } - else if (bellbits & DoorBellAdapterNormCmdNotFull) { - rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); - } - else if (bellbits & DoorBellAdapterNormRespNotFull) { - rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); - rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); - } - return IRQ_HANDLED; } return IRQ_NONE; } @@ -173,7 +190,10 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, /* * Restore interrupt mask even though we timed out */ - rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + if (dev->new_comm_interface) + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + else + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); return -ETIMEDOUT; } /* @@ -196,7 +216,10 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, /* * Restore interrupt mask */ - rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + if (dev->new_comm_interface) + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + else + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); return 0; } @@ -268,15 +291,6 @@ static void aac_rkt_start_adapter(struct aac_dev *dev) init = dev->init; init->HostElapsedSeconds = cpu_to_le32(get_seconds()); - /* - * First clear out all interrupts. Then enable the one's that we - * can handle. - */ - rkt_writeb(dev, MUnit.OIMR, 0xff); - rkt_writel(dev, MUnit.ODR, 0xffffffff); -// rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); - rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); - // We can only use a 32 bit address here rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); @@ -349,6 +363,39 @@ static int aac_rkt_check_health(struct aac_dev *dev) return 0; } +/** + * aac_rkt_send + * @fib: fib to issue + * + * Will send a fib, returning 0 if successful. + */ +static int aac_rkt_send(struct fib * fib) +{ + u64 addr = fib->hw_fib_pa; + struct aac_dev *dev = fib->dev; + volatile void __iomem *device = dev->regs.rkt; + u32 Index; + + dprintk((KERN_DEBUG "%p->aac_rkt_send(%p->%llx)\n", dev, fib, addr)); + Index = rkt_readl(dev, MUnit.InboundQueue); + if (Index == 0xFFFFFFFFL) + Index = rkt_readl(dev, MUnit.InboundQueue); + dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); + if (Index == 0xFFFFFFFFL) + return Index; + device += Index; + dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), + (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); + writel((u32)(addr & 0xffffffff), device); + device += sizeof(u32); + writel((u32)(addr >> 32), device); + device += sizeof(u32); + writel(le16_to_cpu(fib->hw_fib->header.Size), device); + rkt_writel(dev, MUnit.InboundQueue, Index); + dprintk((KERN_DEBUG "aac_rkt_send - return 0\n")); + return 0; +} + /** * aac_rkt_init - initialize an i960 based AAC card * @dev: device to configure @@ -369,13 +416,8 @@ int aac_rkt_init(struct aac_dev *dev) name = dev->name; /* - * Map in the registers from the adapter. + * Check to see if the board panic'd while booting. */ - if((dev->regs.rkt = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) - { - printk(KERN_WARNING "aacraid: unable to map i960.\n" ); - goto error_iounmap; - } /* * Check to see if the board failed any self tests. */ @@ -426,6 +468,7 @@ int aac_rkt_init(struct aac_dev *dev) dev->a_ops.adapter_notify = aac_rkt_notify_adapter; dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; dev->a_ops.adapter_check_health = aac_rkt_check_health; + dev->a_ops.adapter_send = aac_rkt_send; /* * First clear out all interrupts. Then enable the one's that we @@ -437,15 +480,24 @@ int aac_rkt_init(struct aac_dev *dev) if (aac_init_adapter(dev) == NULL) goto error_irq; - /* - * Start any kernel threads needed - */ - dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); - if(dev->thread_pid < 0) - { - printk(KERN_ERR "aacraid: Unable to create rkt thread.\n"); - goto error_kfree; - } + if (dev->new_comm_interface) { + /* + * FIB Setup has already been done, but we can minimize the + * damage by at least ensuring the OS never issues more + * commands than we can handle. The Rocket adapters currently + * can only handle 246 commands and 8 AIFs at the same time, + * and in fact do notify us accordingly if we negotiate the + * FIB size. The problem that causes us to add this check is + * to ensure that we do not overdo it with the adapter when a + * hard coded FIB override is being utilized. This special + * case warrants this half baked, but convenient, check here. + */ + if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) { + dev->init->MaxIoCommands = cpu_to_le32(246); + dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB; + } + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + } /* * Tell the adapter that all is configured, and it can start * accepting requests @@ -453,15 +505,11 @@ int aac_rkt_init(struct aac_dev *dev) aac_rkt_start_adapter(dev); return 0; -error_kfree: - kfree(dev->queues); - error_irq: rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_iounmap: - iounmap(dev->regs.rkt); return -1; } diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index a8459faf87ca..da99046e5393 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -49,40 +49,57 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) { struct aac_dev *dev = dev_id; - unsigned long bellbits; - u8 intstat, mask; - intstat = rx_readb(dev, MUnit.OISR); - /* - * Read mask and invert because drawbridge is reversed. - * This allows us to only service interrupts that have - * been enabled. - */ - mask = ~(dev->OIMR); - /* Check to see if this is our interrupt. If it isn't just return */ - if (intstat & mask) - { - bellbits = rx_readl(dev, OutboundDoorbellReg); - if (bellbits & DoorBellPrintfReady) { - aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5])); - rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); - rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + + dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs)); + if (dev->new_comm_interface) { + u32 Index = rx_readl(dev, MUnit.OutboundQueue); + if (Index == 0xFFFFFFFFL) + Index = rx_readl(dev, MUnit.OutboundQueue); + if (Index != 0xFFFFFFFFL) { + do { + if (aac_intr_normal(dev, Index)) { + rx_writel(dev, MUnit.OutboundQueue, Index); + rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); + } + Index = rx_readl(dev, MUnit.OutboundQueue); + } while (Index != 0xFFFFFFFFL); + return IRQ_HANDLED; } - else if (bellbits & DoorBellAdapterNormCmdReady) { - rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); - aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + } else { + unsigned long bellbits; + u8 intstat; + intstat = rx_readb(dev, MUnit.OISR); + /* + * Read mask and invert because drawbridge is reversed. + * This allows us to only service interrupts that have + * been enabled. + * Check to see if this is our interrupt. If it isn't just return + */ + if (intstat & ~(dev->OIMR)) + { + bellbits = rx_readl(dev, OutboundDoorbellReg); + if (bellbits & DoorBellPrintfReady) { + aac_printf(dev, rx_readl (dev, IndexRegs.Mailbox[5])); + rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); + rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + } + else if (bellbits & DoorBellAdapterNormCmdReady) { + rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + } + else if (bellbits & DoorBellAdapterNormRespReady) { + rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); + aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + } + else if (bellbits & DoorBellAdapterNormCmdNotFull) { + rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + } + else if (bellbits & DoorBellAdapterNormRespNotFull) { + rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); + } + return IRQ_HANDLED; } - else if (bellbits & DoorBellAdapterNormRespReady) { - aac_response_normal(&dev->queues->queue[HostNormRespQueue]); - rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); - } - else if (bellbits & DoorBellAdapterNormCmdNotFull) { - rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); - } - else if (bellbits & DoorBellAdapterNormRespNotFull) { - rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); - rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); - } - return IRQ_HANDLED; } return IRQ_NONE; } @@ -173,7 +190,10 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, /* * Restore interrupt mask even though we timed out */ - rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + if (dev->new_comm_interface) + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + else + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); return -ETIMEDOUT; } /* @@ -196,7 +216,10 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, /* * Restore interrupt mask */ - rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + if (dev->new_comm_interface) + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + else + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); return 0; } @@ -267,15 +290,6 @@ static void aac_rx_start_adapter(struct aac_dev *dev) init = dev->init; init->HostElapsedSeconds = cpu_to_le32(get_seconds()); - /* - * First clear out all interrupts. Then enable the one's that we - * can handle. - */ - rx_writeb(dev, MUnit.OIMR, 0xff); - rx_writel(dev, MUnit.ODR, 0xffffffff); -// rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); - rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); - // We can only use a 32 bit address here rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); @@ -348,6 +362,39 @@ static int aac_rx_check_health(struct aac_dev *dev) return 0; } +/** + * aac_rx_send + * @fib: fib to issue + * + * Will send a fib, returning 0 if successful. + */ +static int aac_rx_send(struct fib * fib) +{ + u64 addr = fib->hw_fib_pa; + struct aac_dev *dev = fib->dev; + volatile void __iomem *device = dev->regs.rx; + u32 Index; + + dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr)); + Index = rx_readl(dev, MUnit.InboundQueue); + if (Index == 0xFFFFFFFFL) + Index = rx_readl(dev, MUnit.InboundQueue); + dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); + if (Index == 0xFFFFFFFFL) + return Index; + device += Index; + dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), + (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); + writel((u32)(addr & 0xffffffff), device); + device += sizeof(u32); + writel((u32)(addr >> 32), device); + device += sizeof(u32); + writel(le16_to_cpu(fib->hw_fib->header.Size), device); + rx_writel(dev, MUnit.InboundQueue, Index); + dprintk((KERN_DEBUG "aac_rx_send - return 0\n")); + return 0; +} + /** * aac_rx_init - initialize an i960 based AAC card * @dev: device to configure @@ -368,13 +415,8 @@ int aac_rx_init(struct aac_dev *dev) name = dev->name; /* - * Map in the registers from the adapter. + * Check to see if the board panic'd while booting. */ - if((dev->regs.rx = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) - { - printk(KERN_WARNING "aacraid: unable to map i960.\n" ); - return -1; - } /* * Check to see if the board failed any self tests. */ @@ -426,6 +468,7 @@ int aac_rx_init(struct aac_dev *dev) dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; + dev->a_ops.adapter_send = aac_rx_send; /* * First clear out all interrupts. Then enable the one's that we @@ -437,15 +480,9 @@ int aac_rx_init(struct aac_dev *dev) if (aac_init_adapter(dev) == NULL) goto error_irq; - /* - * Start any kernel threads needed - */ - dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); - if(dev->thread_pid < 0) - { - printk(KERN_ERR "aacraid: Unable to create rx thread.\n"); - goto error_kfree; - } + if (dev->new_comm_interface) + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); + /* * Tell the adapter that all is configured, and it can start * accepting requests @@ -453,15 +490,11 @@ int aac_rx_init(struct aac_dev *dev) aac_rx_start_adapter(dev); return 0; -error_kfree: - kfree(dev->queues); - error_irq: rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_iounmap: - iounmap(dev->regs.rx); return -1; } diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 3900abc5850d..8b9596209164 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -237,29 +237,16 @@ static void aac_sa_interrupt_adapter (struct aac_dev *dev) static void aac_sa_start_adapter(struct aac_dev *dev) { - u32 ret; struct aac_init *init; /* * Fill in the remaining pieces of the init. */ init = dev->init; init->HostElapsedSeconds = cpu_to_le32(get_seconds()); - - /* - * Tell the adapter we are back and up and running so it will scan its command - * queues and enable our interrupts - */ - dev->irq_mask = (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4); - /* - * First clear out all interrupts. Then enable the one's that - * we can handle. - */ - sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); - sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); /* We can only use a 32 bit address here */ sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0, - &ret, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); } /** @@ -313,15 +300,6 @@ int aac_sa_init(struct aac_dev *dev) instance = dev->id; name = dev->name; - /* - * Map in the registers from the adapter. - */ - - if((dev->regs.sa = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) - { - printk(KERN_WARNING "aacraid: unable to map ARM.\n" ); - goto error_iounmap; - } /* * Check to see if the board failed any self tests. */ @@ -377,15 +355,6 @@ int aac_sa_init(struct aac_dev *dev) if(aac_init_adapter(dev) == NULL) goto error_irq; - /* - * Start any kernel threads needed - */ - dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); - if (dev->thread_pid < 0) { - printk(KERN_ERR "aacraid: Unable to create command thread.\n"); - goto error_kfree; - } - /* * Tell the adapter that all is configure, and it can start * accepting requests @@ -393,16 +362,11 @@ int aac_sa_init(struct aac_dev *dev) aac_sa_start_adapter(dev); return 0; - -error_kfree: - kfree(dev->queues); - error_irq: sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_iounmap: - iounmap(dev->regs.sa); return -1; } From 0eedfcf0cdac30b14d1e6c99abc6604347ef0af8 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 27 Oct 2005 11:09:38 -0700 Subject: [PATCH 0591/1940] [SCSI] qla2xxx: Correct issue where fcport is prematurely marked DEAD. The non-handled failure cases of the Fabric Login mailbox command handling logic would incorrectly mark the fcport as dead and not allow the standard port-down-retry-count logic to manage the transition. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index fbb6feee40cf..6fc8bbae9398 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2858,7 +2858,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); fcport->loop_id = FC_NO_LOOP_ID; - atomic_set(&fcport->state, FCS_DEVICE_DEAD); + fcport->login_retry = 0; rval = 3; break; From 4fdfefe52944f5c4132a372ed5c208962a73c3f2 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 27 Oct 2005 11:09:48 -0700 Subject: [PATCH 0592/1940] [SCSI] qla2xxx: Add support to dynamically enable/disable ZIO. ISP23xx and ISP24xx chips have support for an adaptive method of posting SCSI command completions for multiple SCSI commands during a single system interrupt. SCSI commands are placed on the system response queue without interrupting the host until 1) a delay timer expires; or 2) a SCSI command completes with an error. As long as the host software (qla2xxx) services the response queue for completions (this polling is done during queuecommand()) within the 'delay timer' period, the firmware will not generate system interrupt. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 83 +++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_def.h | 8 ++++ drivers/scsi/qla2xxx/qla_gbl.h | 3 +- drivers/scsi/qla2xxx/qla_init.c | 53 +++++++++++++++------ drivers/scsi/qla2xxx/qla_iocb.c | 10 ++++ drivers/scsi/qla2xxx/qla_isr.c | 7 +-- drivers/scsi/qla2xxx/qla_os.c | 23 --------- 7 files changed, 146 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fc25cd834668..47c9ecfc1d8f 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -319,6 +319,83 @@ qla2x00_state_show(struct class_device *cdev, char *buf) return len; } +static ssize_t +qla2x00_zio_show(struct class_device *cdev, char *buf) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int len = 0; + + switch (ha->zio_mode) { + case QLA_ZIO_MODE_5: + len += snprintf(buf + len, PAGE_SIZE-len, "Mode 5\n"); + break; + case QLA_ZIO_MODE_6: + len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); + break; + case QLA_ZIO_DISABLED: + len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); + break; + } + return len; +} + +static ssize_t +qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int val = 0; + uint16_t zio_mode; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + switch (val) { + case 1: + zio_mode = QLA_ZIO_MODE_5; + break; + case 2: + zio_mode = QLA_ZIO_MODE_6; + break; + default: + zio_mode = QLA_ZIO_DISABLED; + break; + } + + /* Update per-hba values and queue a reset. */ + if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { + ha->zio_mode = zio_mode; + set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + } + return strlen(buf); +} + +static ssize_t +qla2x00_zio_timer_show(struct class_device *cdev, char *buf) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + + return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); +} + +static ssize_t +qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, + size_t count) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int val = 0; + uint16_t zio_timer; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + if (val > 25500 || val < 100) + return -ERANGE; + + zio_timer = (uint16_t)(val / 100); + ha->zio_timer = zio_timer; + + return strlen(buf); +} + static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); @@ -329,6 +406,10 @@ static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL); static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL); static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL); static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL); +static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show, + qla2x00_zio_store); +static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, + qla2x00_zio_timer_store); struct class_device_attribute *qla2x00_host_attrs[] = { &class_device_attr_driver_version, @@ -340,6 +421,8 @@ struct class_device_attribute *qla2x00_host_attrs[] = { &class_device_attr_model_desc, &class_device_attr_pci_info, &class_device_attr_state, + &class_device_attr_zio, + &class_device_attr_zio_timer, NULL, }; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b455c31405e4..522bb2d3f084 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -823,6 +823,11 @@ typedef struct { #define PD_STATE_WAIT_PORT_LOGOUT_ACK 11 +#define QLA_ZIO_MODE_5 (BIT_2 | BIT_0) +#define QLA_ZIO_MODE_6 (BIT_2 | BIT_1) +#define QLA_ZIO_DISABLED 0 +#define QLA_ZIO_DEFAULT_TIMER 2 + /* * ISP Initialization Control Block. * Little endian except where noted. @@ -2470,6 +2475,9 @@ typedef struct scsi_qla_host { /* Needed for BEACON */ uint16_t beacon_blink_led; uint16_t beacon_green_on; + + uint16_t zio_mode; + uint16_t zio_timer; } scsi_qla_host_t; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e451941ad81d..c26b74da4054 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -76,8 +76,6 @@ extern char qla2x00_version_str[]; extern int ql2xlogintimeout; extern int qlport_down_retry; extern int ql2xplogiabsentdevice; -extern int ql2xenablezio; -extern int ql2xintrdelaytimer; extern int ql2xloginretrycount; extern int ql2xfdmienable; @@ -223,6 +221,7 @@ extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *); extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *); extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *); extern void qla2x00_process_response_queue(struct scsi_qla_host *); +extern void qla24xx_process_response_queue(struct scsi_qla_host *); /* * Global Function Prototypes in qla_sup.c source file. diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 6fc8bbae9398..9e36fbd9245a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1372,7 +1372,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) nvram_t *nv = (nvram_t *)ha->request_ring; uint8_t *ptr = (uint8_t *)ha->request_ring; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; - uint8_t timer_mode; rval = QLA_SUCCESS; @@ -1650,22 +1649,26 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) ha->flags.process_response_queue = 1; } else { - /* Enable ZIO -- Support mode 5 only. */ - timer_mode = icb->add_firmware_options[0] & - (BIT_3 | BIT_2 | BIT_1 | BIT_0); + /* Enable ZIO. */ + if (!ha->flags.init_done) { + ha->zio_mode = icb->add_firmware_options[0] & + (BIT_3 | BIT_2 | BIT_1 | BIT_0); + ha->zio_timer = icb->interrupt_delay_timer ? + icb->interrupt_delay_timer: 2; + } icb->add_firmware_options[0] &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0); - if (ql2xenablezio) - timer_mode = BIT_2 | BIT_0; - if (timer_mode == (BIT_2 | BIT_0)) { - DEBUG2(printk("scsi(%ld): ZIO enabled; timer delay " - "(%d).\n", ha->host_no, ql2xintrdelaytimer)); + ha->flags.process_response_queue = 0; + if (ha->zio_mode != QLA_ZIO_DISABLED) { + DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer " + "delay (%d us).\n", ha->host_no, ha->zio_mode, + ha->zio_timer * 100)); qla_printk(KERN_INFO, ha, - "ZIO enabled; timer delay (%d).\n", - ql2xintrdelaytimer); + "ZIO mode %d enabled; timer delay (%d us).\n", + ha->zio_mode, ha->zio_timer * 100); - icb->add_firmware_options[0] |= timer_mode; - icb->interrupt_delay_timer = ql2xintrdelaytimer; + icb->add_firmware_options[0] |= (uint8_t)ha->zio_mode; + icb->interrupt_delay_timer = (uint8_t)ha->zio_timer; ha->flags.process_response_queue = 1; } } @@ -3442,6 +3445,30 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) if (ql2xloginretrycount) ha->login_retry_count = ql2xloginretrycount; + /* Enable ZIO. */ + if (!ha->flags.init_done) { + ha->zio_mode = le32_to_cpu(icb->firmware_options_2) & + (BIT_3 | BIT_2 | BIT_1 | BIT_0); + ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ? + le16_to_cpu(icb->interrupt_delay_timer): 2; + } + icb->firmware_options_2 &= __constant_cpu_to_le32( + ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); + ha->flags.process_response_queue = 0; + if (ha->zio_mode != QLA_ZIO_DISABLED) { + DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay " + "(%d us).\n", ha->host_no, ha->zio_mode, + ha->zio_timer * 100)); + qla_printk(KERN_INFO, ha, + "ZIO mode %d enabled; timer delay (%d us).\n", + ha->zio_mode, ha->zio_timer * 100); + + icb->firmware_options_2 |= cpu_to_le32( + (uint32_t)ha->zio_mode); + icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer); + ha->flags.process_response_queue = 1; + } + if (rval) { DEBUG2_3(printk(KERN_WARNING "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 37f82e2cd7fb..d7355627f110 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -440,6 +440,11 @@ qla2x00_start_scsi(srb_t *sp) WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index); RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, reg)); /* PCI Posting. */ + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (ha->flags.process_response_queue && + ha->response_ring_ptr->signature != RESPONSE_PROCESSED) + qla2x00_process_response_queue(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return (QLA_SUCCESS); @@ -877,6 +882,11 @@ qla24xx_start_scsi(srb_t *sp) WRT_REG_DWORD(®->req_q_in, ha->req_ring_index); RD_REG_DWORD_RELAXED(®->req_q_in); /* PCI Posting. */ + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (ha->flags.process_response_queue && + ha->response_ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index c255bb0268a9..cf6c6ce0b42b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -21,13 +21,11 @@ static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); -void qla2x00_process_response_queue(struct scsi_qla_host *); static void qla2x00_status_entry(scsi_qla_host_t *, void *); static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); -void qla24xx_process_response_queue(scsi_qla_host_t *); static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); /** @@ -651,7 +649,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) "scsi(%ld): [R|Z]IO update completion.\n", ha->host_no)); - qla2x00_process_response_queue(ha); + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) + qla24xx_process_response_queue(ha); + else + qla2x00_process_response_queue(ha); break; case MBA_DISCARD_RND_FRAME: diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 7aec93f9d423..77054d7692c4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -61,19 +61,6 @@ MODULE_PARM_DESC(ql2xplogiabsentdevice, "a Fabric scan. This is needed for several broken switches." "Default is 0 - no PLOGI. 1 - perfom PLOGI."); -int ql2xenablezio = 0; -module_param(ql2xenablezio, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(ql2xenablezio, - "Option to enable ZIO:If 1 then enable it otherwise" - " use the default set in the NVRAM." - " Default is 0 : disabled"); - -int ql2xintrdelaytimer = 10; -module_param(ql2xintrdelaytimer, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(ql2xintrdelaytimer, - "ZIO: Waiting time for Firmware before it generates an " - "interrupt to the host to notify completion of request."); - int ql2xloginretrycount = 0; module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xloginretrycount, @@ -400,16 +387,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) if (rval != QLA_SUCCESS) goto qc_host_busy_free_sp; - /* Manage unprocessed RIO/ZIO commands in response queue. */ - if (ha->flags.online && ha->flags.process_response_queue && - ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - qla2x00_process_response_queue(ha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } - spin_lock_irq(ha->host->host_lock); return 0; From 661c3f6cc32e1307fc7df724149884c95e98358d Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 27 Oct 2005 11:09:58 -0700 Subject: [PATCH 0593/1940] [SCSI] qla2xxx: Use midlayer's int_to_scsilun() function. While populating command type 6 and 7 IOCBs. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_fw.h | 4 ++-- drivers/scsi/qla2xxx/qla_iocb.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index fd9df163410c..63f611904a6c 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -394,7 +394,7 @@ struct cmd_type_6 { uint16_t fcp_rsp_dsd_len; /* FCP_RSP DSD length. */ - uint8_t lun[8]; /* FCP LUN (BE). */ + struct scsi_lun lun; /* FCP LUN (BE). */ uint16_t control_flags; /* Control flags. */ #define CF_DATA_SEG_DESCR_ENABLE BIT_2 @@ -432,7 +432,7 @@ struct cmd_type_7 { uint16_t dseg_count; /* Data segment count. */ uint16_t reserved_1; - uint8_t lun[8]; /* FCP LUN (BE). */ + struct scsi_lun lun; /* FCP LUN (BE). */ uint16_t task_mgmt_flags; /* Task management flags. */ #define TMF_CLEAR_ACA BIT_14 diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index d7355627f110..b58ee79177bc 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -839,8 +839,7 @@ qla24xx_start_scsi(srb_t *sp) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->lun[1] = LSB(sp->cmd->device->lun); - cmd_pkt->lun[2] = MSB(sp->cmd->device->lun); + int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); /* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */ if (scsi_populate_tag_msg(cmd, tag)) { From 475172fb18853c31c24a8519b06a3bd5712b2cfe Mon Sep 17 00:00:00 2001 From: "Ed L. Cashin" Date: Thu, 29 Sep 2005 12:47:40 -0400 Subject: [PATCH 0594/1940] [PATCH] aoe: use get_unaligned for accesses in ATA id buffer Signed-off-by: "Ed L. Cashin" Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Use get_unaligned for possibly-unaligned multi-byte accesses to the ATA device identify response buffer. --- drivers/block/aoe/aoecmd.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index b5be4b7d7b5b..5c9c7c1a3d4c 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "aoe.h" #define TIMERTICK (HZ / 10) @@ -311,16 +312,16 @@ ataid_complete(struct aoedev *d, unsigned char *id) u16 n; /* word 83: command set supported */ - n = le16_to_cpup((__le16 *) &id[83<<1]); + n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1])); /* word 86: command set/feature enabled */ - n |= le16_to_cpup((__le16 *) &id[86<<1]); + n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1])); if (n & (1<<10)) { /* bit 10: LBA 48 */ d->flags |= DEVFL_EXT; /* word 100: number lba48 sectors */ - ssize = le64_to_cpup((__le64 *) &id[100<<1]); + ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1])); /* set as in ide-disk.c:init_idedisk_capacity */ d->geo.cylinders = ssize; @@ -331,12 +332,12 @@ ataid_complete(struct aoedev *d, unsigned char *id) d->flags &= ~DEVFL_EXT; /* number lba28 sectors */ - ssize = le32_to_cpup((__le32 *) &id[60<<1]); + ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1])); /* NOTE: obsolete in ATA 6 */ - d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]); - d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]); - d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]); + d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1])); + d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1])); + d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1])); } d->ssize = ssize; d->geo.start = 0; From 3dc7c555636e46bb64b4da3570a345f4b247eaf0 Mon Sep 17 00:00:00 2001 From: "Ed L. Cashin" Date: Thu, 29 Sep 2005 12:47:55 -0400 Subject: [PATCH 0595/1940] [PATCH] aoe: update to version 14 Signed-off-by: "Ed L. Cashin" Signed-off-by: Greg Kroah-Hartman Update driver version number to 14. --- drivers/block/aoe/aoe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 0e9e586e9ba3..881c48d941b7 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -1,5 +1,5 @@ /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ -#define VERSION "12" +#define VERSION "14" #define AOE_MAJOR 152 #define DEVICE_NAME "aoe" From d5dee80ad69439ad8dccf8fa4d7fed0068aec9cf Mon Sep 17 00:00:00 2001 From: Will Dyson Date: Fri, 16 Sep 2005 02:55:07 -0700 Subject: [PATCH 0596/1940] [PATCH] add sysfs support for ide tape I was recently given an old Travan tape drive and asked to do something useful with it. The ide-scsi + st (+serverworks ide controller) combo results in a hard lockup of the machine which I have not had the energy to debug, so I turned to ide-tape (which seems to work). The system in question debian stable, using udev to manage /dev. The following patch to ide-tape.c allows udev to create the cdev nodes for my drive. Cc: Gadi Oxman Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/ide/ide-tape.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ee38e6b143a4..95abe981530d 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj { static DECLARE_MUTEX(idetape_ref_sem); +static struct class *idetape_sysfs_class; + #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) #define ide_tape_g(disk) \ @@ -4704,6 +4706,10 @@ static void ide_tape_release(struct kref *kref) drive->dsc_overlap = 0; drive->driver_data = NULL; + class_device_destroy(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, tape->minor)); + class_device_destroy(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, tape->minor + 128)); devfs_remove("%s/mt", drive->devfs_name); devfs_remove("%s/mtn", drive->devfs_name); devfs_unregister_tape(g->number); @@ -4878,6 +4884,11 @@ static int ide_tape_probe(struct device *dev) idetape_setup(drive, tape, minor); + class_device_create(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name); + class_device_create(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name); + devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), S_IFCHR | S_IRUGO | S_IWUGO, "%s/mt", drive->devfs_name); @@ -4903,6 +4914,7 @@ MODULE_LICENSE("GPL"); static void __exit idetape_exit (void) { driver_unregister(&idetape_driver.gen_driver); + class_destroy(idetape_sysfs_class); unregister_chrdev(IDETAPE_MAJOR, "ht"); } @@ -4911,11 +4923,33 @@ static void __exit idetape_exit (void) */ static int idetape_init (void) { + int error = 1; + idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape"); + if (IS_ERR(idetape_sysfs_class)) { + idetape_sysfs_class = NULL; + printk(KERN_ERR "Unable to create sysfs class for ide tapes\n"); + error = -EBUSY; + goto out; + } + if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); - return -EBUSY; + error = -EBUSY; + goto out_free_class; } - return driver_register(&idetape_driver.gen_driver); + + error = driver_register(&idetape_driver.gen_driver); + if (error) + goto out_free_driver; + + return 0; + +out_free_driver: + driver_unregister(&idetape_driver.gen_driver); +out_free_class: + class_destroy(idetape_sysfs_class); +out: + return error; } module_init(idetape_init); From 4ed17dccd69c4fc13b9d2118001f5e58ea16ebea Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Thu, 6 Oct 2005 10:45:30 -0700 Subject: [PATCH 0597/1940] [PATCH] kobject_uevent.c has a typo in a comment This patch changes trough to through in a comment in kobject_uevent.c. Signed-off-by: Greg Kroah-Hartman --- lib/kobject_uevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 04ca4429ddfa..a318330d254a 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -54,7 +54,7 @@ static char *action_to_string(enum kobject_action action) static struct sock *uevent_sock; /** - * send_uevent - notify userspace by sending event trough netlink socket + * send_uevent - notify userspace by sending event through netlink socket * * @signal: signal name * @obj: object path (kobject) From 2a7ff1feda9f5cd6463744239ec5e661ee7d5f01 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Thu, 6 Oct 2005 10:47:49 -0700 Subject: [PATCH 0598/1940] [PATCH] changes device to driver in porting.txt The document porting.txt in Documentation/driver-model says: When a device is successfully bound to a device I think it should say: When a device is successfully bound to a driver Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-model/porting.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt index ff2fef2107f0..98b233cb8b36 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.txt @@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated over. bus->match() is called for each device that is not already claimed by a driver. -When a device is successfully bound to a device, device->driver is +When a device is successfully bound to a driver, device->driver is set, the device is added to a per-driver list of devices, and a symlink is created in the driver's sysfs directory that points to the device's physical directory: From 0ac85241ebc7bf6b86ab498960cc121d53ef69ae Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 12 Sep 2005 19:39:34 -0700 Subject: [PATCH 0599/1940] [PATCH] driver model wakeup flags This is a refresh of an earlier patch to add "wakeup" support to the PM core model. This provides per-device bus-neutral control of the use of wakeup events. * "struct device_pm_info" has two bits that are initialized as part of setting up the enclosing struct device: - "can_wakeup", reflecting hardware capabilities - "may_wakeup", the policy setting (when CONFIG_PM) * There's a writeable sysfs "wakeup" file, with one of two values: - "enabled", when the policy is to allow wakeup - "disabled", when the policy is not to allow it - "" if the device can't currently issue wakeups By default, wakeup is enabled on all devices that support it. If its driver doesn't support it ... treat it as a bug. :) Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 1 + drivers/base/power/sysfs.c | 73 ++++++++++++++++++++++++++++++++++++++ include/linux/pm.h | 26 +++++++++++++- 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 6ab73f5c799a..31109193e2c4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -225,6 +225,7 @@ void device_initialize(struct device *dev) klist_children_put); INIT_LIST_HEAD(&dev->dma_pools); init_MUTEX(&dev->sem); + device_init_wakeup(dev, 0); } /** diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 8d04fb435c17..89c57875f3e5 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -48,8 +48,81 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c static DEVICE_ATTR(state, 0644, state_show, state_store); +/* + * wakeup - Report/change current wakeup option for device + * + * Some devices support "wakeup" events, which are hardware signals + * used to activate devices from suspended or low power states. Such + * devices have one of three values for the sysfs power/wakeup file: + * + * + "enabled\n" to issue the events; + * + "disabled\n" not to do so; or + * + "\n" for temporary or permanent inability to issue wakeup. + * + * (For example, unconfigured USB devices can't issue wakeups.) + * + * Familiar examples of devices that can issue wakeup events include + * keyboards and mice (both PS2 and USB styles), power buttons, modems, + * "Wake-On-LAN" Ethernet links, GPIO lines, and more. Some events + * will wake the entire system from a suspend state; others may just + * wake up the device (if the system as a whole is already active). + * Some wakeup events use normal IRQ lines; other use special out + * of band signaling. + * + * It is the responsibility of device drivers to enable (or disable) + * wakeup signaling as part of changing device power states, respecting + * the policy choices provided through the driver model. + * + * Devices may not be able to generate wakeup events from all power + * states. Also, the events may be ignored in some configurations; + * for example, they might need help from other devices that aren't + * active, or which may have wakeup disabled. Some drivers rely on + * wakeup events internally (unless they are disabled), keeping + * their hardware in low power modes whenever they're unused. This + * saves runtime power, without requiring system-wide sleep states. + */ + +static const char enabled[] = "enabled"; +static const char disabled[] = "disabled"; + +static ssize_t +wake_show(struct device * dev, struct device_attribute *attr, char * buf) +{ + return sprintf(buf, "%s\n", device_can_wakeup(dev) + ? (device_may_wakeup(dev) ? enabled : disabled) + : ""); +} + +static ssize_t +wake_store(struct device * dev, struct device_attribute *attr, + const char * buf, size_t n) +{ + char *cp; + int len = n; + + if (!device_can_wakeup(dev)) + return -EINVAL; + + cp = memchr(buf, '\n', n); + if (cp) + len = cp - buf; + if (len == sizeof enabled - 1 + && strncmp(buf, enabled, sizeof enabled - 1) == 0) + device_set_wakeup_enable(dev, 1); + else if (len == sizeof disabled - 1 + && strncmp(buf, disabled, sizeof disabled - 1) == 0) + device_set_wakeup_enable(dev, 0); + else + return -EINVAL; + return n; +} + +static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); + + static struct attribute * power_attrs[] = { &dev_attr_state.attr, + &dev_attr_wakeup.attr, NULL, }; static struct attribute_group pm_attr_group = { diff --git a/include/linux/pm.h b/include/linux/pm.h index 5cfb07648eca..7897cf500c51 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -219,7 +219,9 @@ typedef struct pm_message { struct dev_pm_info { pm_message_t power_state; + unsigned can_wakeup:1; #ifdef CONFIG_PM + unsigned should_wakeup:1; pm_message_t prev_state; void * saved_state; atomic_t pm_users; @@ -236,13 +238,35 @@ extern void device_resume(void); #ifdef CONFIG_PM extern int device_suspend(pm_message_t state); -#else + +#define device_set_wakeup_enable(dev,val) \ + ((dev)->power.should_wakeup = !!(val)) +#define device_may_wakeup(dev) \ + (device_can_wakeup(dev) && (dev)->power.should_wakeup) + +#else /* !CONFIG_PM */ + static inline int device_suspend(pm_message_t state) { return 0; } + +#define device_set_wakeup_enable(dev,val) do{}while(0) +#define device_may_wakeup(dev) (0) + #endif +/* changes to device_may_wakeup take effect on the next pm state change. + * by default, devices should wakeup if they can. + */ +#define device_can_wakeup(dev) \ + ((dev)->power.can_wakeup) +#define device_init_wakeup(dev,val) \ + do { \ + device_can_wakeup(dev) = !!(val); \ + device_set_wakeup_enable(dev,val); \ + } while(0) + #endif /* __KERNEL__ */ #endif /* _LINUX_PM_H */ From b94dc6b58667a73eeaf5cfd9c9e90dcd98743c5b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 12 Sep 2005 19:39:39 -0700 Subject: [PATCH 0600/1940] [PATCH] usb device wakeup flags This patch teaches "usb_device" about the new driver model wakeup support: - It updates device wakeup capabilities when entering a configuration with the WAKEUP attribute; - During suspend processing it consults the policy bit to see whether it should enable wakeup for that device. (This resolves a FIXME to not assume the answer is always "yes"; some devices lie about supporting remote wakeup.) Support for root hubs and the HCDs is separate (and more complex). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a12cab5314e9..c3e2024c4347 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1020,9 +1020,15 @@ void usb_set_device_state(struct usb_device *udev, spin_lock_irqsave(&device_state_lock, flags); if (udev->state == USB_STATE_NOTATTACHED) ; /* do nothing */ - else if (new_state != USB_STATE_NOTATTACHED) + else if (new_state != USB_STATE_NOTATTACHED) { udev->state = new_state; - else + if (new_state == USB_STATE_CONFIGURED) + device_init_wakeup(&udev->dev, + (udev->actconfig->desc.bmAttributes + & USB_CONFIG_ATT_WAKEUP)); + else if (new_state != USB_STATE_SUSPENDED) + device_init_wakeup(&udev->dev, 0); + } else recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); } @@ -1546,11 +1552,7 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, * NOTE: OTG devices may issue remote wakeup (or SRP) even when * we don't explicitly enable it here. */ - if (udev->actconfig - // && FIXME (remote wakeup enabled on this bus) - // ... currently assuming it's always appropriate - && (udev->actconfig->desc.bmAttributes - & USB_CONFIG_ATT_WAKEUP) != 0) { + if (device_may_wakeup(&udev->dev)) { status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, USB_DEVICE_REMOTE_WAKEUP, 0, From dbe9035d4f690c44b55d3d0f1bc193e2c3fc57fa Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:37 -0500 Subject: [PATCH 0601/1940] [PATCH] Driver core: send hotplug event before adding class interfaces Move call to kobject_hotplug() above code that adds interfaces to a class device, otherwise children's hotplug events may reach userspace first. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index ce23dc8c18c5..8df58c57dd25 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -524,6 +524,8 @@ int class_device_add(struct class_device *class_dev) class_name); } + kobject_hotplug(&class_dev->kobj, KOBJ_ADD); + /* notify any interfaces this device is now here */ if (parent) { down(&parent->sem); @@ -533,7 +535,6 @@ int class_device_add(struct class_device *class_dev) class_intf->add(class_dev); up(&parent->sem); } - kobject_hotplug(&class_dev->kobj, KOBJ_ADD); register_done: if (error && parent) From 4f5ca09e0b854a29b17401f59487664ae3b21aa4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:32 -0500 Subject: [PATCH 0602/1940] [PATCH] I2O: remove class interface I2O: remove i2o_device_class_interface misuse The intent of class interfaces was to provide different 'views' at the same object, not just run some code every time a new class device is registered. Kill interface structure, make class core register default attributes and set up sysfs links right when registering class devices. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/message/i2o/device.c | 255 +++++++++++++++++------------------ 1 file changed, 122 insertions(+), 133 deletions(-) diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index 21f16ba3ac38..551d582e2887 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c @@ -45,10 +45,10 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd, writel(type, &msg->body[0]); return i2o_msg_post_wait(dev->iop, m, 60); -}; +} /** - * i2o_device_claim - claim a device for use by an OSM + * i2o_device_claim - claim a device for use by an OSM * @dev: I2O device to claim * @drv: I2O driver which wants to claim the device * @@ -73,7 +73,7 @@ int i2o_device_claim(struct i2o_device *dev) up(&dev->lock); return rc; -}; +} /** * i2o_device_claim_release - release a device that the OSM is using @@ -119,7 +119,8 @@ int i2o_device_claim_release(struct i2o_device *dev) up(&dev->lock); return rc; -}; +} + /** * i2o_device_release - release the memory for a I2O device @@ -135,39 +136,62 @@ static void i2o_device_release(struct device *dev) pr_debug("i2o: device %s released\n", dev->bus_id); kfree(i2o_dev); -}; +} /** - * i2o_device_class_release - Remove I2O device attributes + * i2o_device_class_release - I2O class device release function * @cd: I2O class device which is added to the I2O device class * - * Removes attributes from the I2O device again. Also search each device - * on the controller for I2O devices which refert to this device as parent - * or user and remove this links also. + * The function is just a stub - memory will be freed when + * associated I2O device is released. */ static void i2o_device_class_release(struct class_device *cd) { - struct i2o_device *i2o_dev, *tmp; - struct i2o_controller *c; + /* empty */ +} - i2o_dev = to_i2o_device(cd->dev); - c = i2o_dev->iop; +/** + * i2o_device_class_show_class_id - Displays class id of I2O device + * @cd: class device of which the class id should be displayed + * @buf: buffer into which the class id should be printed + * + * Returns the number of bytes which are printed into the buffer. + */ +static ssize_t i2o_device_class_show_class_id(struct class_device *cd, + char *buf) +{ + struct i2o_device *dev = to_i2o_device(cd->dev); - sysfs_remove_link(&i2o_dev->device.kobj, "parent"); - sysfs_remove_link(&i2o_dev->device.kobj, "user"); + sprintf(buf, "0x%03x\n", dev->lct_data.class_id); + return strlen(buf) + 1; +} - list_for_each_entry(tmp, &c->devices, list) { - if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "parent"); - if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "user"); - } +/** + * i2o_device_class_show_tid - Displays TID of I2O device + * @cd: class device of which the TID should be displayed + * @buf: buffer into which the class id should be printed + * + * Returns the number of bytes which are printed into the buffer. + */ +static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf) +{ + struct i2o_device *dev = to_i2o_device(cd->dev); + + sprintf(buf, "0x%03x\n", dev->lct_data.tid); + return strlen(buf) + 1; +} + +static struct class_device_attribute i2o_device_class_attrs[] = { + __ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id, NULL), + __ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL), + __ATTR_NULL }; /* I2O device class */ static struct class i2o_device_class = { - .name = "i2o_device", - .release = i2o_device_class_release + .name = "i2o_device", + .release = i2o_device_class_release, + .class_dev_attrs = i2o_device_class_attrs, }; /** @@ -197,7 +221,67 @@ static struct i2o_device *i2o_device_alloc(void) dev->classdev.dev = &dev->device; return dev; -}; +} + +/** + * i2o_setup_sysfs_links - Adds attributes to the I2O device + * @cd: I2O class device which is added to the I2O device class + * + * This function get called when a I2O device is added to the class. It + * creates the attributes for each device and creates user/parent symlink + * if necessary. + * + * Returns 0 on success or negative error code on failure. + */ +static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev) +{ + struct i2o_controller *c = i2o_dev->iop; + struct i2o_device *tmp; + + /* create user entries for this device */ + tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); + if (tmp && tmp != i2o_dev) + sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "user"); + + /* create user entries refering to this device */ + list_for_each_entry(tmp, &c->devices, list) + if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid && + tmp != i2o_dev) + sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "user"); + + /* create parent entries for this device */ + tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); + if (tmp && tmp != i2o_dev) + sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "parent"); + + /* create parent entries refering to this device */ + list_for_each_entry(tmp, &c->devices, list) + if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid && + tmp != i2o_dev) + sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "parent"); +} + +static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev) +{ + struct i2o_controller *c = i2o_dev->iop; + struct i2o_device *tmp; + + sysfs_remove_link(&i2o_dev->device.kobj, "parent"); + sysfs_remove_link(&i2o_dev->device.kobj, "user"); + + list_for_each_entry(tmp, &c->devices, list) { + if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "parent"); + if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "user"); + } +} + + /** * i2o_device_add - allocate a new I2O device and add it to the IOP @@ -222,6 +306,7 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c, } dev->lct_data = *entry; + dev->iop = c; snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit, dev->lct_data.tid); @@ -229,7 +314,6 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c, snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit, dev->lct_data.tid); - dev->iop = c; dev->device.parent = &c->device; device_register(&dev->device); @@ -238,12 +322,14 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c, class_device_register(&dev->classdev); + i2o_setup_sysfs_links(dev); + i2o_driver_notify_device_add_all(dev); pr_debug("i2o: device %s added\n", dev->device.bus_id); return dev; -}; +} /** * i2o_device_remove - remove an I2O device from the I2O core @@ -256,10 +342,11 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c, void i2o_device_remove(struct i2o_device *i2o_dev) { i2o_driver_notify_device_remove_all(i2o_dev); + i2o_remove_sysfs_links(i2o_dev); class_device_unregister(&i2o_dev->classdev); list_del(&i2o_dev->list); device_unregister(&i2o_dev->device); -}; +} /** * i2o_device_parse_lct - Parse a previously fetched LCT and create devices @@ -337,99 +424,8 @@ int i2o_device_parse_lct(struct i2o_controller *c) up(&c->lct_lock); return 0; -}; +} -/** - * i2o_device_class_show_class_id - Displays class id of I2O device - * @cd: class device of which the class id should be displayed - * @buf: buffer into which the class id should be printed - * - * Returns the number of bytes which are printed into the buffer. - */ -static ssize_t i2o_device_class_show_class_id(struct class_device *cd, - char *buf) -{ - struct i2o_device *dev = to_i2o_device(cd->dev); - - sprintf(buf, "0x%03x\n", dev->lct_data.class_id); - return strlen(buf) + 1; -}; - -/** - * i2o_device_class_show_tid - Displays TID of I2O device - * @cd: class device of which the TID should be displayed - * @buf: buffer into which the class id should be printed - * - * Returns the number of bytes which are printed into the buffer. - */ -static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf) -{ - struct i2o_device *dev = to_i2o_device(cd->dev); - - sprintf(buf, "0x%03x\n", dev->lct_data.tid); - return strlen(buf) + 1; -}; - -/* I2O device class attributes */ -static CLASS_DEVICE_ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id, - NULL); -static CLASS_DEVICE_ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL); - -/** - * i2o_device_class_add - Adds attributes to the I2O device - * @cd: I2O class device which is added to the I2O device class - * - * This function get called when a I2O device is added to the class. It - * creates the attributes for each device and creates user/parent symlink - * if necessary. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_device_class_add(struct class_device *cd) -{ - struct i2o_device *i2o_dev, *tmp; - struct i2o_controller *c; - - i2o_dev = to_i2o_device(cd->dev); - c = i2o_dev->iop; - - class_device_create_file(cd, &class_device_attr_class_id); - class_device_create_file(cd, &class_device_attr_tid); - - /* create user entries for this device */ - tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "user"); - - /* create user entries refering to this device */ - list_for_each_entry(tmp, &c->devices, list) - if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "user"); - - /* create parent entries for this device */ - tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "parent"); - - /* create parent entries refering to this device */ - list_for_each_entry(tmp, &c->devices, list) - if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "parent"); - - return 0; -}; - -/* I2O device class interface */ -static struct class_interface i2o_device_class_interface = { - .class = &i2o_device_class, - .add = i2o_device_class_add -}; /* * Run time support routines @@ -553,11 +549,11 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field, } /* - * if oper == I2O_PARAMS_TABLE_GET, get from all rows - * if fieldcount == -1 return all fields + * if oper == I2O_PARAMS_TABLE_GET, get from all rows + * if fieldcount == -1 return all fields * ibuf and ibuflen are unused (use NULL, 0) - * else return specific fields - * ibuf contains fieldindexes + * else return specific fields + * ibuf contains fieldindexes * * if oper == I2O_PARAMS_LIST_GET, get from specific rows * if fieldcount == -1 return all fields @@ -611,14 +607,8 @@ int i2o_parm_table_get(struct i2o_device *dev, int oper, int group, */ int i2o_device_init(void) { - int rc; - - rc = class_register(&i2o_device_class); - if (rc) - return rc; - - return class_interface_register(&i2o_device_class_interface); -}; + return class_register(&i2o_device_class); +} /** * i2o_device_exit - I2O devices exit function @@ -627,9 +617,8 @@ int i2o_device_init(void) */ void i2o_device_exit(void) { - class_interface_register(&i2o_device_class_interface); class_unregister(&i2o_device_class); -}; +} EXPORT_SYMBOL(i2o_device_claim); EXPORT_SYMBOL(i2o_device_claim_release); From 607cf4d9aa1d766890f42fc892d39d48cf6d6c16 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0603/1940] [PATCH] I2O: Clean up some pretty bad driver model abuses in the i2o code Signed-off-by: Greg Kroah-Hartman --- drivers/message/i2o/iop.c | 22 ++++++++++------------ include/linux/i2o.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 42f8b810d6e5..15deb45ce995 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -833,6 +833,7 @@ void i2o_iop_remove(struct i2o_controller *c) list_for_each_entry_safe(dev, tmp, &c->devices, list) i2o_device_remove(dev); + class_device_unregister(c->classdev); device_del(&c->device); /* Ask the IOP to switch to RESET state */ @@ -1077,9 +1078,7 @@ static void i2o_iop_release(struct device *dev) }; /* I2O controller class */ -static struct class i2o_controller_class = { - .name = "i2o_controller", -}; +static struct class *i2o_controller_class; /** * i2o_iop_alloc - Allocate and initialize a i2o_controller struct @@ -1110,14 +1109,10 @@ struct i2o_controller *i2o_iop_alloc(void) sprintf(c->name, "iop%d", c->unit); device_initialize(&c->device); - class_device_initialize(&c->classdev); c->device.release = &i2o_iop_release; - c->classdev.class = &i2o_controller_class; - c->classdev.dev = &c->device; snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit); - snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit); #if BITS_PER_LONG == 64 spin_lock_init(&c->context_list_lock); @@ -1146,7 +1141,9 @@ int i2o_iop_add(struct i2o_controller *c) goto iop_reset; } - if ((rc = class_device_add(&c->classdev))) { + c->classdev = class_device_create(i2o_controller_class, 0, + &c->device, "iop%d", c->unit); + if (IS_ERR(c->classdev)) { osm_err("%s: could not add controller class\n", c->name); goto device_del; } @@ -1184,7 +1181,7 @@ int i2o_iop_add(struct i2o_controller *c) return 0; class_del: - class_device_del(&c->classdev); + class_device_unregister(c->classdev); device_del: device_del(&c->device); @@ -1250,7 +1247,8 @@ static int __init i2o_iop_init(void) if (rc) goto exit; - if ((rc = class_register(&i2o_controller_class))) { + i2o_controller_class = class_create(THIS_MODULE, "i2o_controller"); + if (IS_ERR(i2o_controller_class)) { osm_err("can't register class i2o_controller\n"); goto device_exit; } @@ -1273,7 +1271,7 @@ static int __init i2o_iop_init(void) i2o_driver_exit(); class_exit: - class_unregister(&i2o_controller_class); + class_destroy(i2o_controller_class); device_exit: i2o_device_exit(); @@ -1292,7 +1290,7 @@ static void __exit i2o_iop_exit(void) i2o_pci_exit(); i2o_exec_exit(); i2o_driver_exit(); - class_unregister(&i2o_controller_class); + class_destroy(i2o_controller_class); i2o_device_exit(); }; diff --git a/include/linux/i2o.h b/include/linux/i2o.h index bdc286ec947c..694ea298d4bc 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -194,7 +194,7 @@ struct i2o_controller { struct resource mem_resource; /* Mem resource allocated to the IOP */ struct device device; - struct class_device classdev; /* I2O controller class */ + struct class_device *classdev; /* I2O controller class device */ struct i2o_device *exec; /* Executive */ #if BITS_PER_LONG == 64 spinlock_t context_list_lock; /* lock for context_list */ From 7bd7b091429705eb281d60c553cc643aada8045a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 29 Sep 2005 00:40:07 -0500 Subject: [PATCH 0604/1940] [PATCH] I2O: remove i2o_device_class I2O: cleanup - remove i2o_device_class I2O devices reside on their own bus so there should be no reason to also have i2c_device class that mirros i2o bus. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/message/i2o/core.h | 3 -- drivers/message/i2o/device.c | 71 +++++++----------------------------- drivers/message/i2o/driver.c | 3 ++ drivers/message/i2o/iop.c | 10 +---- include/linux/i2o.h | 2 - 5 files changed, 17 insertions(+), 72 deletions(-) diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h index c5bcfd70f711..9eefedb16211 100644 --- a/drivers/message/i2o/core.h +++ b/drivers/message/i2o/core.h @@ -36,9 +36,6 @@ extern void __exit i2o_pci_exit(void); extern void i2o_device_remove(struct i2o_device *); extern int i2o_device_parse_lct(struct i2o_controller *); -extern int i2o_device_init(void); -extern void i2o_device_exit(void); - /* IOP */ extern struct i2o_controller *i2o_iop_alloc(void); extern void i2o_iop_free(struct i2o_controller *); diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index 551d582e2887..d9879965eb50 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c @@ -138,17 +138,6 @@ static void i2o_device_release(struct device *dev) kfree(i2o_dev); } -/** - * i2o_device_class_release - I2O class device release function - * @cd: I2O class device which is added to the I2O device class - * - * The function is just a stub - memory will be freed when - * associated I2O device is released. - */ -static void i2o_device_class_release(struct class_device *cd) -{ - /* empty */ -} /** * i2o_device_class_show_class_id - Displays class id of I2O device @@ -157,12 +146,13 @@ static void i2o_device_class_release(struct class_device *cd) * * Returns the number of bytes which are printed into the buffer. */ -static ssize_t i2o_device_class_show_class_id(struct class_device *cd, - char *buf) +static ssize_t i2o_device_show_class_id(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct i2o_device *dev = to_i2o_device(cd->dev); + struct i2o_device *i2o_dev = to_i2o_device(dev); - sprintf(buf, "0x%03x\n", dev->lct_data.class_id); + sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id); return strlen(buf) + 1; } @@ -173,27 +163,22 @@ static ssize_t i2o_device_class_show_class_id(struct class_device *cd, * * Returns the number of bytes which are printed into the buffer. */ -static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf) +static ssize_t i2o_device_show_tid(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct i2o_device *dev = to_i2o_device(cd->dev); + struct i2o_device *i2o_dev = to_i2o_device(dev); - sprintf(buf, "0x%03x\n", dev->lct_data.tid); + sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid); return strlen(buf) + 1; } -static struct class_device_attribute i2o_device_class_attrs[] = { - __ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id, NULL), - __ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL), +struct device_attribute i2o_device_attrs[] = { + __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL), + __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL), __ATTR_NULL }; -/* I2O device class */ -static struct class i2o_device_class = { - .name = "i2o_device", - .release = i2o_device_class_release, - .class_dev_attrs = i2o_device_class_attrs, -}; - /** * i2o_device_alloc - Allocate a I2O device and initialize it * @@ -217,8 +202,6 @@ static struct i2o_device *i2o_device_alloc(void) dev->device.bus = &i2o_bus_type; dev->device.release = &i2o_device_release; - dev->classdev.class = &i2o_device_class; - dev->classdev.dev = &dev->device; return dev; } @@ -311,17 +294,12 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c, snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit, dev->lct_data.tid); - snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit, - dev->lct_data.tid); - dev->device.parent = &c->device; device_register(&dev->device); list_add_tail(&dev->list, &c->devices); - class_device_register(&dev->classdev); - i2o_setup_sysfs_links(dev); i2o_driver_notify_device_add_all(dev); @@ -343,7 +321,6 @@ void i2o_device_remove(struct i2o_device *i2o_dev) { i2o_driver_notify_device_remove_all(i2o_dev); i2o_remove_sysfs_links(i2o_dev); - class_device_unregister(&i2o_dev->classdev); list_del(&i2o_dev->list); device_unregister(&i2o_dev->device); } @@ -598,28 +575,6 @@ int i2o_parm_table_get(struct i2o_device *dev, int oper, int group, return size; } -/** - * i2o_device_init - Initialize I2O devices - * - * Registers the I2O device class. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_device_init(void) -{ - return class_register(&i2o_device_class); -} - -/** - * i2o_device_exit - I2O devices exit function - * - * Unregisters the I2O device class. - */ -void i2o_device_exit(void) -{ - class_unregister(&i2o_device_class); -} - EXPORT_SYMBOL(i2o_device_claim); EXPORT_SYMBOL(i2o_device_claim_release); EXPORT_SYMBOL(i2o_parm_field_get); diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index 739bfdef0c6d..0079a4be0af2 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c @@ -58,9 +58,12 @@ static int i2o_bus_match(struct device *dev, struct device_driver *drv) }; /* I2O bus type */ +extern struct device_attribute i2o_device_attrs[]; + struct bus_type i2o_bus_type = { .name = "i2o", .match = i2o_bus_match, + .dev_attrs = i2o_device_attrs, }; /** diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 15deb45ce995..176fb573ea26 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -1243,14 +1243,10 @@ static int __init i2o_iop_init(void) printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - rc = i2o_device_init(); - if (rc) - goto exit; - i2o_controller_class = class_create(THIS_MODULE, "i2o_controller"); if (IS_ERR(i2o_controller_class)) { osm_err("can't register class i2o_controller\n"); - goto device_exit; + goto exit; } if ((rc = i2o_driver_init())) @@ -1273,9 +1269,6 @@ static int __init i2o_iop_init(void) class_exit: class_destroy(i2o_controller_class); - device_exit: - i2o_device_exit(); - exit: return rc; } @@ -1291,7 +1284,6 @@ static void __exit i2o_iop_exit(void) i2o_exec_exit(); i2o_driver_exit(); class_destroy(i2o_controller_class); - i2o_device_exit(); }; module_init(i2o_iop_init); diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 694ea298d4bc..84db8f6ae7e5 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -66,8 +66,6 @@ struct i2o_device { struct device device; struct semaphore lock; /* device lock */ - - struct class_device classdev; /* i2o device class */ }; /* From d8539d81aeee4dbdc0624a798321e822fb2df7ae Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:36 -0500 Subject: [PATCH 0605/1940] [PATCH] Driver core: pass interface to class interface methods Driver core: pass interface to class intreface methods Pass interface as argument to add() and remove() class interface methods. This way a subsystem can implement generic add/remove handlers and then call interface-specific ones. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 8 ++++---- drivers/pcmcia/ds.c | 6 ++++-- drivers/pcmcia/rsrc_nonstatic.c | 6 ++++-- drivers/pcmcia/socket_sysfs.c | 6 ++++-- drivers/scsi/sg.c | 8 ++++---- include/linux/device.h | 4 ++-- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 8df58c57dd25..73d44cf53db0 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -532,7 +532,7 @@ int class_device_add(struct class_device *class_dev) list_add_tail(&class_dev->node, &parent->children); list_for_each_entry(class_intf, &parent->interfaces, node) if (class_intf->add) - class_intf->add(class_dev); + class_intf->add(class_dev, class_intf); up(&parent->sem); } @@ -612,7 +612,7 @@ void class_device_del(struct class_device *class_dev) list_del_init(&class_dev->node); list_for_each_entry(class_intf, &parent->interfaces, node) if (class_intf->remove) - class_intf->remove(class_dev); + class_intf->remove(class_dev, class_intf); up(&parent->sem); } @@ -729,7 +729,7 @@ int class_interface_register(struct class_interface *class_intf) list_add_tail(&class_intf->node, &parent->interfaces); if (class_intf->add) { list_for_each_entry(class_dev, &parent->children, node) - class_intf->add(class_dev); + class_intf->add(class_dev, class_intf); } up(&parent->sem); @@ -748,7 +748,7 @@ void class_interface_unregister(struct class_interface *class_intf) list_del_init(&class_intf->node); if (class_intf->remove) { list_for_each_entry(class_dev, &parent->children, node) - class_intf->remove(class_dev); + class_intf->remove(class_dev, class_intf); } up(&parent->sem); diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 080608c7381a..39d096b52926 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1157,7 +1157,8 @@ static struct pcmcia_callback pcmcia_bus_callback = { .requery = pcmcia_bus_rescan, }; -static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) +static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct pcmcia_socket *socket = class_get_devdata(class_dev); int ret; @@ -1192,7 +1193,8 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) return 0; } -static void pcmcia_bus_remove_socket(struct class_device *class_dev) +static void pcmcia_bus_remove_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct pcmcia_socket *socket = class_get_devdata(class_dev); diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index f9a5c70284b5..fc87e7e2b6b8 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -994,7 +994,8 @@ static struct class_device_attribute *pccard_rsrc_attributes[] = { NULL, }; -static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev) +static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev, + struct class_interface *class_intf) { struct pcmcia_socket *s = class_get_devdata(class_dev); struct class_device_attribute **attr; @@ -1011,7 +1012,8 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev) return ret; } -static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev) +static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev, + struct class_interface *class_intf) { struct pcmcia_socket *s = class_get_devdata(class_dev); struct class_device_attribute **attr; diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 1040a6c1a8a4..4a3150a7854c 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -341,7 +341,8 @@ static struct bin_attribute pccard_cis_attr = { .write = pccard_store_cis, }; -static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev) +static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct class_device_attribute **attr; int ret = 0; @@ -357,7 +358,8 @@ static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev) return ret; } -static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev) +static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct class_device_attribute **attr; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ad94367df430..f0d8b4eda5ad 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -104,8 +104,8 @@ static int sg_allow_dio = SG_ALLOW_DIO_DEF; #define SG_DEV_ARR_LUMP 32 /* amount to over allocate sg_dev_arr by */ -static int sg_add(struct class_device *); -static void sg_remove(struct class_device *); +static int sg_add(struct class_device *, struct class_interface *); +static void sg_remove(struct class_device *, struct class_interface *); static Scsi_Request *dummy_cmdp; /* only used for sizeof */ @@ -1506,7 +1506,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) } static int -sg_add(struct class_device *cl_dev) +sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) { struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); struct gendisk *disk; @@ -1582,7 +1582,7 @@ sg_add(struct class_device *cl_dev) } static void -sg_remove(struct class_device *cl_dev) +sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) { struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); Sg_device *sdp = NULL; diff --git a/include/linux/device.h b/include/linux/device.h index 95d607a48f06..a53a822c4d16 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -251,8 +251,8 @@ struct class_interface { struct list_head node; struct class *class; - int (*add) (struct class_device *); - void (*remove) (struct class_device *); + int (*add) (struct class_device *, struct class_interface *); + void (*remove) (struct class_device *, struct class_interface *); }; extern int class_interface_register(struct class_interface *); From a7fd67062efc5b0fc9a61368c607fa92d1d57f9e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 1 Oct 2005 14:49:43 +0200 Subject: [PATCH 0606/1940] [PATCH] add sysfs attr to re-emit device hotplug event A "coldplug + udevstart" can be simple like this: for i in /sys/block/*/*/uevent; do echo 1 > $i; done for i in /sys/class/*/*/uevent; do echo 1 > $i; done for i in /sys/bus/*/devices/*/uevent; do echo 1 > $i; done Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 16 ++++++++++-- drivers/base/core.c | 16 ++++++++++++ drivers/block/genhd.c | 25 ++++++++++++++++++ fs/partitions/check.c | 27 +++++++++++++++++++- include/linux/device.h | 57 +++++++++++++++++++++--------------------- include/linux/genhd.h | 1 + 6 files changed, 110 insertions(+), 32 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 73d44cf53db0..3cf6eb36f3d8 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -442,6 +442,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf) return print_dev_t(buf, class_dev->devt); } +static ssize_t store_uevent(struct class_device *class_dev, + const char *buf, size_t count) +{ + kobject_hotplug(&class_dev->kobj, KOBJ_ADD); + return count; +} + void class_device_initialize(struct class_device *class_dev) { kobj_set_kset_s(class_dev, class_obj_subsys); @@ -497,6 +504,12 @@ int class_device_add(struct class_device *class_dev) goto register_done; /* add the needed attributes to this device */ + class_dev->uevent_attr.attr.name = "uevent"; + class_dev->uevent_attr.attr.mode = S_IWUSR; + class_dev->uevent_attr.attr.owner = parent->owner; + class_dev->uevent_attr.store = store_uevent; + class_device_create_file(class_dev, &class_dev->uevent_attr); + if (MAJOR(class_dev->devt)) { struct class_device_attribute *attr; attr = kzalloc(sizeof(*attr), GFP_KERNEL); @@ -505,12 +518,10 @@ int class_device_add(struct class_device *class_dev) kobject_del(&class_dev->kobj); goto register_done; } - attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; attr->attr.owner = parent->owner; attr->show = show_dev; - attr->store = NULL; class_device_create_file(class_dev, attr); class_dev->devt_attr = attr; } @@ -621,6 +632,7 @@ void class_device_del(struct class_device *class_dev) sysfs_remove_link(&class_dev->kobj, "device"); sysfs_remove_link(&class_dev->dev->kobj, class_name); } + class_device_remove_file(class_dev, &class_dev->uevent_attr); if (class_dev->devt_attr) class_device_remove_file(class_dev, class_dev->devt_attr); class_device_remove_attrs(class_dev); diff --git a/drivers/base/core.c b/drivers/base/core.c index 31109193e2c4..ac4b5fdd95f5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = { .hotplug = dev_hotplug, }; +static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + kobject_hotplug(&dev->kobj, KOBJ_ADD); + return count; +} + /** * device_subsys - structure to be registered with kobject core. */ @@ -259,6 +266,14 @@ int device_add(struct device *dev) if ((error = kobject_add(&dev->kobj))) goto Error; + + dev->uevent_attr.attr.name = "uevent"; + dev->uevent_attr.attr.mode = S_IWUSR; + if (dev->driver) + dev->uevent_attr.attr.owner = dev->driver->owner; + dev->uevent_attr.store = store_uevent; + device_create_file(dev, &dev->uevent_attr); + kobject_hotplug(&dev->kobj, KOBJ_ADD); if ((error = device_pm_add(dev))) goto PMError; @@ -350,6 +365,7 @@ void device_del(struct device * dev) if (parent) klist_del(&dev->knode_parent); + device_remove_file(dev, &dev->uevent_attr); /* Notify the platform of the removal, in case they * need to do anything... diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index d42840cc0d1d..486ce1fdeb8c 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr, return ret; } +static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr, + const char *page, size_t count) +{ + struct gendisk *disk = to_disk(kobj); + struct disk_attribute *disk_attr = + container_of(attr,struct disk_attribute,attr); + ssize_t ret = 0; + + if (disk_attr->store) + ret = disk_attr->store(disk, page, count); + return ret; +} + static struct sysfs_ops disk_sysfs_ops = { .show = &disk_attr_show, + .store = &disk_attr_store, }; +static ssize_t disk_uevent_store(struct gendisk * disk, + const char *buf, size_t count) +{ + kobject_hotplug(&disk->kobj, KOBJ_ADD); + return count; +} static ssize_t disk_dev_read(struct gendisk * disk, char *page) { dev_t base = MKDEV(disk->major, disk->first_minor); @@ -382,6 +402,10 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page) jiffies_to_msecs(disk_stat_read(disk, io_ticks)), jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); } +static struct disk_attribute disk_attr_uevent = { + .attr = {.name = "uevent", .mode = S_IWUSR }, + .store = disk_uevent_store +}; static struct disk_attribute disk_attr_dev = { .attr = {.name = "dev", .mode = S_IRUGO }, .show = disk_dev_read @@ -404,6 +428,7 @@ static struct disk_attribute disk_attr_stat = { }; static struct attribute * default_attrs[] = { + &disk_attr_uevent.attr, &disk_attr_dev.attr, &disk_attr_range.attr, &disk_attr_removable.attr, diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 77e178f13162..d95a110293fa 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -192,6 +192,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev) struct part_attribute { struct attribute attr; ssize_t (*show)(struct hd_struct *,char *); + ssize_t (*store)(struct hd_struct *,const char *, size_t); }; static ssize_t @@ -201,14 +202,33 @@ part_attr_show(struct kobject * kobj, struct attribute * attr, char * page) struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); ssize_t ret = 0; if (part_attr->show) - ret = part_attr->show(p,page); + ret = part_attr->show(p, page); + return ret; +} +static ssize_t +part_attr_store(struct kobject * kobj, struct attribute * attr, + const char *page, size_t count) +{ + struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); + struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); + ssize_t ret = 0; + + if (part_attr->store) + ret = part_attr->store(p, page, count); return ret; } static struct sysfs_ops part_sysfs_ops = { .show = part_attr_show, + .store = part_attr_store, }; +static ssize_t part_uevent_store(struct hd_struct * p, + const char *page, size_t count) +{ + kobject_hotplug(&p->kobj, KOBJ_ADD); + return count; +} static ssize_t part_dev_read(struct hd_struct * p, char *page) { struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); @@ -229,6 +249,10 @@ static ssize_t part_stat_read(struct hd_struct * p, char *page) p->reads, (unsigned long long)p->read_sectors, p->writes, (unsigned long long)p->write_sectors); } +static struct part_attribute part_attr_uevent = { + .attr = {.name = "uevent", .mode = S_IWUSR }, + .store = part_uevent_store +}; static struct part_attribute part_attr_dev = { .attr = {.name = "dev", .mode = S_IRUGO }, .show = part_dev_read @@ -247,6 +271,7 @@ static struct part_attribute part_attr_stat = { }; static struct attribute * default_attrs[] = { + &part_attr_uevent.attr, &part_attr_dev.attr, &part_attr_start.attr, &part_attr_size.attr, diff --git a/include/linux/device.h b/include/linux/device.h index a53a822c4d16..e86a580b72e1 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -190,6 +190,18 @@ struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store) extern int class_create_file(struct class *, const struct class_attribute *); extern void class_remove_file(struct class *, const struct class_attribute *); +struct class_device_attribute { + struct attribute attr; + ssize_t (*show)(struct class_device *, char * buf); + ssize_t (*store)(struct class_device *, const char * buf, size_t count); +}; + +#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \ +struct class_device_attribute class_device_attr_##_name = \ + __ATTR(_name,_mode,_show,_store) + +extern int class_device_create_file(struct class_device *, + const struct class_device_attribute *); struct class_device { struct list_head node; @@ -198,6 +210,7 @@ struct class_device { struct class * class; /* required */ dev_t devt; /* dev_t, creates the sysfs "dev" */ struct class_device_attribute *devt_attr; + struct class_device_attribute uevent_attr; struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */ @@ -228,18 +241,6 @@ extern int class_device_rename(struct class_device *, char *); extern struct class_device * class_device_get(struct class_device *); extern void class_device_put(struct class_device *); -struct class_device_attribute { - struct attribute attr; - ssize_t (*show)(struct class_device *, char * buf); - ssize_t (*store)(struct class_device *, const char * buf, size_t count); -}; - -#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \ -struct class_device_attribute class_device_attr_##_name = \ - __ATTR(_name,_mode,_show,_store) - -extern int class_device_create_file(struct class_device *, - const struct class_device_attribute *); extern void class_device_remove_file(struct class_device *, const struct class_device_attribute *); extern int class_device_create_bin_file(struct class_device *, @@ -266,6 +267,20 @@ extern struct class_device *class_device_create(struct class *cls, dev_t devt, extern void class_device_destroy(struct class *cls, dev_t devt); +/* interface for exporting device attributes */ +struct device_attribute { + struct attribute attr; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +}; + +#define DEVICE_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store) + +extern int device_create_file(struct device *device, struct device_attribute * entry); +extern void device_remove_file(struct device * dev, struct device_attribute * attr); struct device { struct klist klist_children; struct klist_node knode_parent; /* node in sibling list */ @@ -275,6 +290,7 @@ struct device { struct kobject kobj; char bus_id[BUS_ID_SIZE]; /* position on parent bus */ + struct device_attribute uevent_attr; struct semaphore sem; /* semaphore to synchronize calls to * its driver. @@ -343,23 +359,6 @@ extern int device_attach(struct device * dev); extern void driver_attach(struct device_driver * drv); -/* driverfs interface for exporting device attributes */ - -struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device *dev, struct device_attribute *attr, - char *buf); - ssize_t (*store)(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count); -}; - -#define DEVICE_ATTR(_name,_mode,_show,_store) \ -struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store) - - -extern int device_create_file(struct device *device, struct device_attribute * entry); -extern void device_remove_file(struct device * dev, struct device_attribute * attr); - /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 01796c41c951..78af34840c69 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -132,6 +132,7 @@ struct gendisk { struct disk_attribute { struct attribute attr; ssize_t (*show)(struct gendisk *, char *); + ssize_t (*store)(struct gendisk *, const char *, size_t); }; /* From 51d172d5f3a193e4b8f76179b2e55d7a36b94117 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0607/1940] [PATCH] Driver Core: add the ability for class_device structures to be nested This patch allows struct class_device to be nested, so that another struct class_device can be the parent of a new one, instead of only having the struct class be the parent. This will allow us to (hopefully) fix up the input and video class subsystem mess. But please people, don't go crazy and start making huge trees of class devices, you should only need 2 levels deep to get everything to work (remember to use a class_interface to get notification of a new class device being added to the system.) Oh, this also allows us to have the possibility of potentially, someday, moving /sys/block into /sys/class. The main hindrance is that pesky /dev numberspace issue... Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 125 ++++++++++++++++++++++++++--------------- include/linux/device.h | 13 ++++- 2 files changed, 91 insertions(+), 47 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 3cf6eb36f3d8..c3e569730afe 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -99,7 +99,8 @@ struct class * class_get(struct class * cls) void class_put(struct class * cls) { - subsys_put(&cls->subsys); + if (cls) + subsys_put(&cls->subsys); } @@ -165,14 +166,25 @@ void class_unregister(struct class * cls) static void class_create_release(struct class *cls) { + pr_debug("%s called for %s\n", __FUNCTION__, cls->name); kfree(cls); } static void class_device_create_release(struct class_device *class_dev) { + pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); kfree(class_dev); } +/* needed to allow these devices to have parent class devices */ +static int class_device_create_hotplug(struct class_device *class_dev, + char **envp, int num_envp, + char *buffer, int buffer_size) +{ + pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); + return 0; +} + /** * class_create - create a struct class structure * @owner: pointer to the module that is to "own" this struct class @@ -301,10 +313,12 @@ static void class_dev_release(struct kobject * kobj) kfree(cd->devt_attr); cd->devt_attr = NULL; - if (cls->release) + if (cd->release) + cd->release(cd); + else if (cls->release) cls->release(cd); else { - printk(KERN_ERR "Device class '%s' does not have a release() function, " + printk(KERN_ERR "Class Device '%s' does not have a release() function, " "it is broken and must be fixed.\n", cd->class_id); WARN_ON(1); @@ -382,14 +396,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp, buffer = &buffer[length]; buffer_size -= length; - if (class_dev->class->hotplug) { - /* have the bus specific function add its stuff */ - retval = class_dev->class->hotplug (class_dev, envp, num_envp, - buffer, buffer_size); - if (retval) { - pr_debug ("%s - hotplug() returned %d\n", - __FUNCTION__, retval); - } + if (class_dev->hotplug) { + /* have the class device specific function add its stuff */ + retval = class_dev->hotplug(class_dev, envp, num_envp, + buffer, buffer_size); + if (retval) + pr_debug("class_dev->hotplug() returned %d\n", retval); + } else if (class_dev->class->hotplug) { + /* have the class specific function add its stuff */ + retval = class_dev->class->hotplug(class_dev, envp, num_envp, + buffer, buffer_size); + if (retval) + pr_debug("class->hotplug() returned %d\n", retval); } return retval; @@ -476,37 +494,42 @@ static char *make_class_name(struct class_device *class_dev) int class_device_add(struct class_device *class_dev) { - struct class * parent = NULL; - struct class_interface * class_intf; + struct class *parent_class = NULL; + struct class_device *parent_class_dev = NULL; + struct class_interface *class_intf; char *class_name = NULL; - int error; + int error = -EINVAL; class_dev = class_device_get(class_dev); if (!class_dev) return -EINVAL; - if (!strlen(class_dev->class_id)) { - error = -EINVAL; + if (!strlen(class_dev->class_id)) goto register_done; - } - parent = class_get(class_dev->class); + parent_class = class_get(class_dev->class); + if (!parent_class) + goto register_done; + parent_class_dev = class_device_get(class_dev->parent); pr_debug("CLASS: registering class device: ID = '%s'\n", class_dev->class_id); /* first, register with generic layer. */ kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); - if (parent) - class_dev->kobj.parent = &parent->subsys.kset.kobj; + if (parent_class_dev) + class_dev->kobj.parent = &parent_class_dev->kobj; + else + class_dev->kobj.parent = &parent_class->subsys.kset.kobj; - if ((error = kobject_add(&class_dev->kobj))) + error = kobject_add(&class_dev->kobj); + if (error) goto register_done; /* add the needed attributes to this device */ class_dev->uevent_attr.attr.name = "uevent"; class_dev->uevent_attr.attr.mode = S_IWUSR; - class_dev->uevent_attr.attr.owner = parent->owner; + class_dev->uevent_attr.attr.owner = parent_class->owner; class_dev->uevent_attr.store = store_uevent; class_device_create_file(class_dev, &class_dev->uevent_attr); @@ -520,7 +543,7 @@ int class_device_add(struct class_device *class_dev) } attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; - attr->attr.owner = parent->owner; + attr->attr.owner = parent_class->owner; attr->show = show_dev; class_device_create_file(class_dev, attr); class_dev->devt_attr = attr; @@ -538,18 +561,20 @@ int class_device_add(struct class_device *class_dev) kobject_hotplug(&class_dev->kobj, KOBJ_ADD); /* notify any interfaces this device is now here */ - if (parent) { - down(&parent->sem); - list_add_tail(&class_dev->node, &parent->children); - list_for_each_entry(class_intf, &parent->interfaces, node) + if (parent_class) { + down(&parent_class->sem); + list_add_tail(&class_dev->node, &parent_class->children); + list_for_each_entry(class_intf, &parent_class->interfaces, node) if (class_intf->add) class_intf->add(class_dev, class_intf); - up(&parent->sem); + up(&parent_class->sem); } register_done: - if (error && parent) - class_put(parent); + if (error) { + class_put(parent_class); + class_device_put(parent_class_dev); + } class_device_put(class_dev); kfree(class_name); return error; @@ -564,21 +589,28 @@ int class_device_register(struct class_device *class_dev) /** * class_device_create - creates a class device and registers it with sysfs * @cs: pointer to the struct class that this device should be registered to. + * @parent: pointer to the parent struct class_device of this new device, if any. * @dev: the dev_t for the char device to be added. * @device: a pointer to a struct device that is assiociated with this class device. * @fmt: string for the class device's name * * This function can be used by char device classes. A struct * class_device will be created in sysfs, registered to the specified - * class. A "dev" file will be created, showing the dev_t for the - * device. The pointer to the struct class_device will be returned from - * the call. Any further sysfs files that might be required can be - * created using this pointer. + * class. + * A "dev" file will be created, showing the dev_t for the device, if + * the dev_t is not 0,0. + * If a pointer to a parent struct class_device is passed in, the newly + * created struct class_device will be a child of that device in sysfs. + * The pointer to the struct class_device will be returned from the + * call. Any further sysfs files that might be required can be created + * using this pointer. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ -struct class_device *class_device_create(struct class *cls, dev_t devt, +struct class_device *class_device_create(struct class *cls, + struct class_device *parent, + dev_t devt, struct device *device, char *fmt, ...) { va_list args; @@ -597,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt, class_dev->devt = devt; class_dev->dev = device; class_dev->class = cls; + class_dev->parent = parent; + class_dev->release = class_device_create_release; + class_dev->hotplug = class_device_create_hotplug; va_start(args, fmt); vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); @@ -614,17 +649,18 @@ struct class_device *class_device_create(struct class *cls, dev_t devt, void class_device_del(struct class_device *class_dev) { - struct class * parent = class_dev->class; - struct class_interface * class_intf; + struct class *parent_class = class_dev->class; + struct class_device *parent_device = class_dev->parent; + struct class_interface *class_intf; char *class_name = NULL; - if (parent) { - down(&parent->sem); + if (parent_class) { + down(&parent_class->sem); list_del_init(&class_dev->node); - list_for_each_entry(class_intf, &parent->interfaces, node) + list_for_each_entry(class_intf, &parent_class->interfaces, node) if (class_intf->remove) class_intf->remove(class_dev, class_intf); - up(&parent->sem); + up(&parent_class->sem); } if (class_dev->dev) { @@ -640,8 +676,8 @@ void class_device_del(struct class_device *class_dev) kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); kobject_del(&class_dev->kobj); - if (parent) - class_put(parent); + class_device_put(parent_device); + class_put(parent_class); kfree(class_name); } @@ -721,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev) void class_device_put(struct class_device *class_dev) { - kobject_put(&class_dev->kobj); + if (class_dev) + kobject_put(&class_dev->kobj); } diff --git a/include/linux/device.h b/include/linux/device.h index e86a580b72e1..226e550ae2ea 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -213,7 +213,11 @@ struct class_device { struct class_device_attribute uevent_attr; struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */ + struct class_device *parent; /* parent of this child device, if there is one */ + void (*release)(struct class_device *dev); + int (*hotplug)(struct class_device *dev, char **envp, + int num_envp, char *buffer, int buffer_size); char class_id[BUS_ID_SIZE]; /* unique to this class */ }; @@ -261,9 +265,12 @@ extern void class_interface_unregister(struct class_interface *); extern struct class *class_create(struct module *owner, char *name); extern void class_destroy(struct class *cls); -extern struct class_device *class_device_create(struct class *cls, dev_t devt, - struct device *device, char *fmt, ...) - __attribute__((format(printf,4,5))); +extern struct class_device *class_device_create(struct class *cls, + struct class_device *parent, + dev_t devt, + struct device *device, + char *fmt, ...) + __attribute__((format(printf,5,6))); extern void class_device_destroy(struct class *cls, dev_t devt); From 53f4654272df7c51064825024340554b39c9efba Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0608/1940] [PATCH] Driver Core: fix up all callers of class_device_create() The previous patch adding the ability to nest struct class_device changed the paramaters to the call class_device_create(). This patch fixes up all in-kernel users of the function. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/cpuid.c | 2 +- arch/i386/kernel/msr.c | 2 +- drivers/block/aoe/aoechr.c | 2 +- drivers/block/paride/pg.c | 2 +- drivers/block/paride/pt.c | 4 ++-- drivers/char/dsp56k.c | 2 +- drivers/char/ftape/zftape/zftape-init.c | 12 ++++++------ drivers/char/ip2main.c | 10 ++++++---- drivers/char/ipmi/ipmi_devintf.c | 2 +- drivers/char/istallion.c | 3 ++- drivers/char/lp.c | 2 +- drivers/char/mem.c | 3 ++- drivers/char/misc.c | 2 +- drivers/char/ppdev.c | 2 +- drivers/char/raw.c | 4 ++-- drivers/char/snsc.c | 2 +- drivers/char/stallion.c | 4 +++- drivers/char/tipar.c | 2 +- drivers/char/tty_io.c | 10 +++++----- drivers/char/vc_screen.c | 10 ++++++---- drivers/char/viotape.c | 4 ++-- drivers/hwmon/hwmon.c | 2 +- drivers/ide/ide-tape.c | 4 ++-- drivers/ieee1394/dv1394.c | 2 +- drivers/ieee1394/raw1394.c | 2 +- drivers/ieee1394/video1394.c | 2 +- drivers/infiniband/core/ucm.c | 2 +- drivers/input/evdev.c | 2 +- drivers/input/joydev.c | 2 +- drivers/input/mousedev.c | 4 ++-- drivers/input/tsdev.c | 2 +- drivers/isdn/capi/capi.c | 2 +- drivers/macintosh/adb.c | 2 +- drivers/media/dvb/dvb-core/dvbdev.c | 2 +- drivers/message/i2o/iop.c | 2 +- drivers/mtd/mtdchar.c | 4 ++-- drivers/net/ppp_generic.c | 2 +- drivers/net/wan/cosa.c | 2 +- drivers/s390/char/tape_class.c | 1 + drivers/s390/char/vmlogrdr.c | 1 + drivers/scsi/ch.c | 2 +- drivers/scsi/osst.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/scsi/st.c | 2 +- drivers/usb/core/devio.c | 2 +- drivers/usb/core/file.c | 4 +++- drivers/usb/core/hcd.c | 3 ++- drivers/video/fbmem.c | 2 +- fs/coda/psdev.c | 4 ++-- sound/core/sound.c | 2 +- sound/oss/soundcard.c | 4 ++-- sound/sound_core.c | 2 +- 52 files changed, 86 insertions(+), 73 deletions(-) diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 4647db4ad6de..13bae799e626 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -163,7 +163,7 @@ static int cpuid_class_device_create(int i) int err = 0; struct class_device *class_err; - class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); + class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); if (IS_ERR(class_err)) err = PTR_ERR(class_err); return err; diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 03100d6fc5d6..44470fea4309 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -246,7 +246,7 @@ static int msr_class_device_create(int i) int err = 0; struct class_device *class_err; - class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); + class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); if (IS_ERR(class_err)) err = PTR_ERR(class_err); return err; diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 45a243096187..41ae0ede619a 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -224,7 +224,7 @@ aoechr_init(void) return PTR_ERR(aoe_class); } for (i = 0; i < ARRAY_SIZE(chardevs); ++i) - class_device_create(aoe_class, + class_device_create(aoe_class, NULL, MKDEV(AOE_MAJOR, chardevs[i].minor), NULL, chardevs[i].name); diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index b3982395f22b..82f2d6d2eeef 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -674,7 +674,7 @@ static int __init pg_init(void) for (unit = 0; unit < PG_UNITS; unit++) { struct pg *dev = &devices[unit]; if (dev->present) { - class_device_create(pg_class, MKDEV(major, unit), + class_device_create(pg_class, NULL, MKDEV(major, unit), NULL, "pg%u", unit); err = devfs_mk_cdev(MKDEV(major, unit), S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u", diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index d8d35233cf49..686c95573452 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -971,7 +971,7 @@ static int __init pt_init(void) devfs_mk_dir("pt"); for (unit = 0; unit < PT_UNITS; unit++) if (pt[unit].present) { - class_device_create(pt_class, MKDEV(major, unit), + class_device_create(pt_class, NULL, MKDEV(major, unit), NULL, "pt%d", unit); err = devfs_mk_cdev(MKDEV(major, unit), S_IFCHR | S_IRUSR | S_IWUSR, @@ -980,7 +980,7 @@ static int __init pt_init(void) class_device_destroy(pt_class, MKDEV(major, unit)); goto out_class; } - class_device_create(pt_class, MKDEV(major, unit + 128), + class_device_create(pt_class, NULL, MKDEV(major, unit + 128), NULL, "pt%dn", unit); err = devfs_mk_cdev(MKDEV(major, unit + 128), S_IFCHR | S_IRUSR | S_IWUSR, diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 26271e3ca823..8693835cb2d5 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(void) err = PTR_ERR(dsp56k_class); goto out_chrdev; } - class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); + class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k"); diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index 5745b74044ec..821357ce7e0e 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c @@ -331,27 +331,27 @@ KERN_INFO zft_class = class_create(THIS_MODULE, "zft"); for (i = 0; i < 4; i++) { - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "qft%i", i); - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4), S_IFCHR | S_IRUSR | S_IWUSR, "nqft%i", i); - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16), S_IFCHR | S_IRUSR | S_IWUSR, "zqft%i", i); - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20), S_IFCHR | S_IRUSR | S_IWUSR, "nzqft%i", i); - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32), S_IFCHR | S_IRUSR | S_IWUSR, "rawqft%i", i); - class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); + class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36), S_IFCHR | S_IRUSR | S_IWUSR, "nrawqft%i", i); diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 9e4e26aef94e..d815d197dc3e 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { - class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR, - 4 * i), NULL, "ipl%d", i); + class_device_create(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i), + NULL, "ipl%d", i); err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/ipl%d", i); @@ -732,8 +733,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) goto out_class; } - class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR, - 4 * i + 1), NULL, "stat%d", i); + class_device_create(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i + 1), + NULL, "stat%d", i); err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/stat%d", i); diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index a09ff1080687..7c0684deea06 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num) devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, "ipmidev/%d", if_num); - class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num); + class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num); } static void ipmi_smi_gone(int if_num) diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 9c19e5435a11..e3ddbdb85a2f 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -5246,7 +5246,8 @@ int __init stli_init(void) devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "staliomem/%d", i); - class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), + class_device_create(istallion_class, NULL, + MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); } diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 2afb9038dbc5..e57260525293 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -805,7 +805,7 @@ static int lp_register(int nr, struct parport *port) if (reset) lp_reset(nr); - class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL, + class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, "lp%d", nr); devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO, "printers/%d", nr); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index f182752fe918..38be4b0dbd1c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -920,7 +920,8 @@ static int __init chr_dev_init(void) mem_class = class_create(THIS_MODULE, "mem"); for (i = 0; i < ARRAY_SIZE(devlist); i++) { - class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor), + class_device_create(mem_class, NULL, + MKDEV(MEM_MAJOR, devlist[i].minor), NULL, devlist[i].name); devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor), S_IFCHR | devlist[i].mode, devlist[i].name); diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 0c8375165e29..3e4c0414a01a 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -234,7 +234,7 @@ int misc_register(struct miscdevice * misc) } dev = MKDEV(MISC_MAJOR, misc->minor); - misc->class = class_device_create(misc_class, dev, misc->dev, + misc->class = class_device_create(misc_class, NULL, dev, misc->dev, "%s", misc->name); if (IS_ERR(misc->class)) { err = PTR_ERR(misc->class); diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 0e22880432bc..306ee0f091a4 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -752,7 +752,7 @@ static struct file_operations pp_fops = { static void pp_attach(struct parport *port) { - class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number), + class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), NULL, "parport%d", port->number); } diff --git a/drivers/char/raw.c b/drivers/char/raw.c index f13e5de02207..30e4cbe16bb0 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct file *filp, static void bind_device(struct raw_config_request *rq) { class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); - class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor), + class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL, "raw%d", rq->raw_minor); } @@ -307,7 +307,7 @@ static int __init raw_init(void) unregister_chrdev_region(dev, MAX_RAW_MINORS); goto error; } - class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); + class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), S_IFCHR | S_IRUGO | S_IWUGO, diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 261a41bf6d02..1758a83327e5 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -437,7 +437,7 @@ scdrv_init(void) continue; } - class_device_create(snsc_class, dev, NULL, + class_device_create(snsc_class, NULL, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 951545a6ef2d..1c686414e0a1 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -3095,7 +3095,9 @@ static int __init stl_init(void) devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR|S_IRUSR|S_IWUSR, "staliomem/%d", i); - class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); + class_device_create(stallion_class, NULL, + MKDEV(STL_SIOMEMMAJOR, i), NULL, + "staliomem%d", i); } stl_serial->owner = THIS_MODULE; diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index ec78d2f161f7..41a94bc79f67 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c @@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port) goto out; } - class_device_create(tipar_class, MKDEV(TIPAR_MAJOR, + class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr), NULL, "par%d", nr); /* Use devfs, tree: /dev/ticables/par/[0..2] */ err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr), diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e5953f3433f3..f5649a337743 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index, pty_line_name(driver, index, name); else tty_line_name(driver, index, name); - class_device_create(tty_class, dev, device, name); + class_device_create(tty_class, NULL, dev, device, "%s", name); } /** @@ -2983,14 +2983,14 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty"); - class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console"); - class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); #ifdef CONFIG_UNIX98_PTYS cdev_init(&ptmx_cdev, &ptmx_fops); @@ -2998,7 +2998,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) panic("Couldn't register /dev/ptmx driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx"); - class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); #endif #ifdef CONFIG_VT @@ -3007,7 +3007,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) panic("Couldn't register /dev/tty0 driver\n"); devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0"); - class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); + class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); vty_init(); #endif diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 79c2928a8817..f66c7ad6fd38 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *tty) devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a%u", tty->index + 1); - class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1); - class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), + NULL, "vcs%u", tty->index + 1); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), + NULL, "vcsa%u", tty->index + 1); } void vcs_remove_devfs(struct tty_struct *tty) { @@ -503,7 +505,7 @@ int __init vcs_init(void) devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0"); devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0"); - class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); return 0; } diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 0aff45fac2e6..a5e104f428f8 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) state[i].cur_part = 0; for (j = 0; j < MAX_PARTITIONS; ++j) state[i].part_stat_rwi[j] = VIOT_IDLE; - class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL, + class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, "iseries!vt%d", i); - class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80), + class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL, "iseries!nvt%d", i); devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "iseries/vt%d", i); diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 9b41c9bd805f..6f48579799b5 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -45,7 +45,7 @@ struct class_device *hwmon_device_register(struct device *dev) return ERR_PTR(-ENOMEM); id = id & MAX_ID_MASK; - cdev = class_device_create(hwmon_class, MKDEV(0,0), dev, + cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, HWMON_ID_FORMAT, id); if (IS_ERR(cdev)) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 95abe981530d..47f2b832555f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4884,9 +4884,9 @@ static int ide_tape_probe(struct device *dev) idetape_setup(drive, tape, minor); - class_device_create(idetape_sysfs_class, + class_device_create(idetape_sysfs_class, NULL, MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name); - class_device_create(idetape_sysfs_class, + class_device_create(idetape_sysfs_class, NULL, MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name); devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index e34730c7a874..cbbbe14b8849 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; - class_device_create(hpsb_protocol_class, MKDEV( + class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL, "dv1394-%d", id); devfs_mk_dir("ieee1394/dv/host%d", id); diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 0470f77a9cd1..24411e666b21 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2912,7 +2912,7 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); - if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV( + if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, RAW1394_DEVICE_NAME))) { ret = -EFAULT; diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 11be9c9c82a8..23911da50154 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host) hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; - class_device_create(hpsb_protocol_class, MKDEV( + class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, minor), NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index d0f0b0a2edd3..021b8f1d36d3 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -1300,7 +1300,7 @@ static int __init ib_ucm_init(void) goto err_class; } - class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm"); + class_device_create(ib_ucm_class, NULL, IB_UCM_DEV, NULL, "ucm"); idr_init(&ctx_id_table); init_MUTEX(&ctx_id_mutex); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 3738d173f9a6..83b694cb8507 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -689,7 +689,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor); - class_device_create(input_class, + class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), dev->dev, "event%d", minor); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index e0938d1d3ad7..c696fb2a6f99 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -516,7 +516,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor); - class_device_create(input_class, + class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), dev->dev, "js%d", minor); diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index c6194a9dd174..d7144e1a9ae3 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -651,7 +651,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor); - class_device_create(input_class, + class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), dev->dev, "mouse%d", minor); @@ -740,7 +740,7 @@ static int __init mousedev_init(void) devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), S_IFCHR|S_IRUGO|S_IWUSR, "input/mice"); - class_device_create(input_class, + class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 50c63a155156..fbb35c97551b 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -414,7 +414,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor); devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2), S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor); - class_device_create(input_class, + class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), dev->dev, "ts%d", minor); diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 04fb606b5ddd..11ae0fddea04 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1505,7 +1505,7 @@ static int __init capi_init(void) return PTR_ERR(capi_class); } - class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi"); + class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, "isdn/capi20"); diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index c0dc1e3fa58b..d2ead1776c16 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -905,5 +905,5 @@ adbdev_init(void) adb_dev_class = class_create(THIS_MODULE, "adb"); if (IS_ERR(adb_dev_class)) return; - class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb"); + class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); } diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 4b7adca3e286..477b4fa56430 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, S_IFCHR | S_IRUSR | S_IWUSR, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); - class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), + class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), NULL, "dvb%d.%s%d", adap->num, dnames[type], id); dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 176fb573ea26..361da8d1d5e7 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -1141,7 +1141,7 @@ int i2o_iop_add(struct i2o_controller *c) goto iop_reset; } - c->classdev = class_device_create(i2o_controller_class, 0, + c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0), &c->device, "iop%d", c->unit); if (IS_ERR(c->classdev)) { osm_err("%s: could not add controller class\n", c->name); diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 1ed602a0f24c..c534fd5d95cb 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -24,10 +24,10 @@ static void mtd_notify_add(struct mtd_info* mtd) if (!mtd) return; - class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), + class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), NULL, "mtd%d", mtd->index); - class_device_create(mtd_class, + class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), NULL, "mtd%dro", mtd->index); } diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 0df7e92b0bf8..d3c9958b00d0 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -863,7 +863,7 @@ static int __init ppp_init(void) err = PTR_ERR(ppp_class); goto out_chrdev; } - class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); + class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "ppp"); if (err) diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 7ff814fd65d0..ace68e5bc6c9 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -400,7 +400,7 @@ static int __init cosa_init(void) goto out_chrdev; } for (i=0; iclass_device = class_device_create( tape_class, + NULL, tcd->char_device->dev, device, "%s", tcd->device_name diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 491f00c032e8..a107fec4457a 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -787,6 +787,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { return ret; } priv->class_device = class_device_create( + NULL, vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num), dev, diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index da6e51c7fe69..540147cb51ce 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -936,7 +936,7 @@ static int ch_probe(struct device *dev) if (init) ch_init_elem(ch); - class_device_create(ch_sysfs_class, + class_device_create(ch_sysfs_class, NULL, MKDEV(SCSI_CHANGER_MAJOR,ch->minor), dev, "s%s", ch->name); diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 3f2f2464fa63..0bb60de0bded 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5627,7 +5627,7 @@ static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * if (!osst_sysfs_valid) return; - osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name); + osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name); if (IS_ERR(osst_class_member)) { printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); return; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index f0d8b4eda5ad..40886e1c9616 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1550,7 +1550,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) if (sg_sysfs_valid) { struct class_device * sg_class_member; - sg_class_member = class_device_create(sg_sysfs_class, + sg_class_member = class_device_create(sg_sysfs_class, NULL, MKDEV(SCSI_GENERIC_MAJOR, k), cl_dev->dev, "%s", disk->disk_name); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index d001c046551b..d45ba4832162 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4375,7 +4375,7 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) snprintf(name, 10, "%s%s%s", rew ? "n" : "", STp->disk->disk_name, st_formats[i]); st_class_member = - class_device_create(st_sysfs_class, + class_device_create(st_sysfs_class, NULL, MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew)), &STp->device->sdev_gendev, "%s", name); diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 487ff672b104..befe0c7f63d1 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1509,7 +1509,7 @@ void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); - dev->class_dev = class_device_create(usb_device_class, + dev->class_dev = class_device_create(usb_device_class, NULL, MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, "usbdev%d.%d", dev->bus->busnum, dev->devnum); diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 65ca131cc44c..78cb4be9529f 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -172,7 +172,9 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); + intf->class_dev = class_device_create(usb_class, NULL, + MKDEV(USB_MAJOR, minor), + &intf->dev, "%s", temp); if (IS_ERR(intf->class_dev)) { spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1017a97a418b..c3eb66f5a1a4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -782,7 +782,8 @@ static int usb_register_bus(struct usb_bus *bus) return -E2BIG; } - bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum); + bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), + bus->controller, "usb_host%d", busnum); if (IS_ERR(bus->class_dev)) { clear_bit(busnum, busmap.busmap); up(&usb_bus_list_lock); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 70be7009f8af..9073be4221a8 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1031,7 +1031,7 @@ register_framebuffer(struct fb_info *fb_info) break; fb_info->node = i; - fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i), + fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i), fb_info->device, "fb%d", i); if (IS_ERR(fb_info->class_device)) { /* Not fatal */ diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 3d1cce3653b8..6a3df88accfe 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -370,8 +370,8 @@ static int init_coda_psdev(void) } devfs_mk_dir ("coda"); for (i = 0; i < MAX_CODADEVS; i++) { - class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i), - NULL, "cfs%d", i); + class_device_create(coda_psdev_class, NULL, + MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i); err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i), S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i); if (err) diff --git a/sound/core/sound.c b/sound/core/sound.c index 9e76bddb2c0b..b57519a3e3d9 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -231,7 +231,7 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name); if (card) device = card->dev; - class_device_create(sound_class, MKDEV(major, minor), device, "%s", name); + class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); up(&sound_mutex); return 0; diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 95fa81e26de2..d33bb464f70e 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -567,7 +567,7 @@ static int __init oss_init(void) devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor), S_IFCHR | dev_list[i].mode, "sound/%s", dev_list[i].name); - class_device_create(sound_class, + class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL, "%s", dev_list[i].name); @@ -579,7 +579,7 @@ static int __init oss_init(void) dev_list[i].minor + (j*0x10)), S_IFCHR | dev_list[i].mode, "sound/%s%d", dev_list[i].name, j); - class_device_create(sound_class, + class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)), NULL, "%s%d", dev_list[i].name, j); } diff --git a/sound/sound_core.c b/sound/sound_core.c index 954f994592ab..394b53e20cb8 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -174,7 +174,7 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor), S_IFCHR | mode, s->name); - class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor), + class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor), dev, s->name+6); return r; From 74be227f728ed68bfc270153665b43fc1f0fa845 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0609/1940] [PATCH] Driver Core: document struct class_device properly Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 226e550ae2ea..10ab7807f8ea 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -203,6 +203,30 @@ struct class_device_attribute class_device_attr_##_name = \ extern int class_device_create_file(struct class_device *, const struct class_device_attribute *); +/** + * struct class_device - class devices + * @class: pointer to the parent class for this class device. This is required. + * @devt: for internal use by the driver core only. + * @node: for internal use by the driver core only. + * @kobj: for internal use by the driver core only. + * @devt_attr: for internal use by the driver core only. + * @dev: if set, a symlink to the struct device is created in the sysfs + * directory for this struct class device. + * @class_data: pointer to whatever you want to store here for this struct + * class_device. Use class_get_devdata() and class_set_devdata() to get and + * set this pointer. + * @parent: pointer to a struct class_device that is the parent of this struct + * class_device. If NULL, this class_device will show up at the root of the + * struct class in sysfs (which is probably what you want to have happen.) + * @release: pointer to a release function for this struct class_device. If + * set, this will be called instead of the class specific release function. + * Only use this if you want to override the default release function, like + * when you are nesting class_device structures. + * @hotplug: pointer to a hotplug function for this struct class_device. If + * set, this will be called instead of the class specific hotplug function. + * Only use this if you want to override the default hotplug function, like + * when you are nesting class_device structures. + */ struct class_device { struct list_head node; From 4f00469c16b86a3dd6ed66b28c605c8430d58eeb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:38 -0500 Subject: [PATCH 0610/1940] [PATCH] Input: kill devfs references Input: remove references to devfs from input subsystem Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/evdev.c | 4 ---- drivers/input/input.c | 7 ------- drivers/input/joydev.c | 4 ---- drivers/input/mousedev.c | 9 +-------- drivers/input/tsdev.c | 7 ------- 5 files changed, 1 insertion(+), 30 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 83b694cb8507..14ea57f963bb 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -20,7 +20,6 @@ #include #include #include -#include #include struct evdev { @@ -687,8 +686,6 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev_table[minor] = evdev; - devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor); class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), dev->dev, "event%d", minor); @@ -703,7 +700,6 @@ static void evdev_disconnect(struct input_handle *handle) class_device_destroy(input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); - devfs_remove("input/event%d", evdev->minor); evdev->exist = 0; if (evdev->open) { diff --git a/drivers/input/input.c b/drivers/input/input.c index 14ae5583e198..072bbf528151 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -22,7 +22,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input core"); @@ -770,13 +769,8 @@ static int __init input_init(void) goto fail2; } - err = devfs_mk_dir("input"); - if (err) - goto fail3; - return 0; - fail3: unregister_chrdev(INPUT_MAJOR, "input"); fail2: input_proc_exit(); fail1: class_destroy(input_class); return err; @@ -785,7 +779,6 @@ static int __init input_init(void) static void __exit input_exit(void) { input_proc_exit(); - devfs_remove("input"); unregister_chrdev(INPUT_MAJOR, "input"); class_destroy(input_class); } diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index c696fb2a6f99..40d2b46cbc79 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -26,7 +26,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Joystick device interfaces"); @@ -514,8 +513,6 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev_table[minor] = joydev; - devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor); class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), dev->dev, "js%d", minor); @@ -529,7 +526,6 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev_list *list; class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); - devfs_remove("input/js%d", joydev->minor); joydev->exist = 0; if (joydev->open) { diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index d7144e1a9ae3..89c3e496f1ed 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -9,7 +9,7 @@ * the Free Software Foundation. */ -#define MOUSEDEV_MINOR_BASE 32 +#define MOUSEDEV_MINOR_BASE 32 #define MOUSEDEV_MINORS 32 #define MOUSEDEV_MIX 31 @@ -24,7 +24,6 @@ #include #include #include -#include #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX #include #endif @@ -649,8 +648,6 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru mousedev_table[minor] = mousedev; - devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor); class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), dev->dev, "mouse%d", minor); @@ -665,7 +662,6 @@ static void mousedev_disconnect(struct input_handle *handle) class_device_destroy(input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); - devfs_remove("input/mouse%d", mousedev->minor); mousedev->exist = 0; if (mousedev->open) { @@ -738,8 +734,6 @@ static int __init mousedev_init(void) mousedev_mix.exist = 1; mousedev_mix.minor = MOUSEDEV_MIX; - devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), - S_IFCHR|S_IRUGO|S_IWUSR, "input/mice"); class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); @@ -759,7 +753,6 @@ static void __exit mousedev_exit(void) if (psaux_registered) misc_deregister(&psaux_mouse); #endif - devfs_remove("input/mice"); class_device_destroy(input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index fbb35c97551b..2d45e4df4163 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -53,7 +53,6 @@ #include #include #include -#include #ifndef CONFIG_INPUT_TSDEV_SCREEN_X #define CONFIG_INPUT_TSDEV_SCREEN_X 240 @@ -410,10 +409,6 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, tsdev_table[minor] = tsdev; - devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor); - devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2), - S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor); class_device_create(input_class, NULL, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), dev->dev, "ts%d", minor); @@ -428,8 +423,6 @@ static void tsdev_disconnect(struct input_handle *handle) class_device_destroy(input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); - devfs_remove("input/ts%d", tsdev->minor); - devfs_remove("input/tsraw%d", tsdev->minor); tsdev->exist = 0; if (tsdev->open) { From d19fbe8a763634395d4bef40fc88cdb61c4a6274 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:39 -0500 Subject: [PATCH 0611/1940] [PATCH] Input: prepare to sysfs integration Input: prepare to sysfs integration Add struct class_device to input_dev; add input_allocate_dev() to dynamically allocate input devices; dynamically allocated devices are automatically registered with sysfs. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 77 ++++++++++++++++++++++++++++++++++++++++--- include/linux/input.h | 24 +++++++++++++- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 072bbf528151..0e2e890c0988 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -27,6 +27,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input core"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(input_allocate_device); EXPORT_SYMBOL(input_register_device); EXPORT_SYMBOL(input_unregister_device); EXPORT_SYMBOL(input_register_handler); @@ -605,6 +606,56 @@ static inline int input_proc_init(void) { return 0; } static inline void input_proc_exit(void) { } #endif +static void input_dev_release(struct class_device *class_dev) +{ + struct input_dev *dev = to_input_dev(class_dev); + + kfree(dev); + module_put(THIS_MODULE); +} + +static struct class input_dev_class = { + .name = "input_dev", + .release = input_dev_release, +}; + +struct input_dev *input_allocate_device(void) +{ + struct input_dev *dev; + + dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); + if (dev) { + dev->dynalloc = 1; + dev->cdev.class = &input_dev_class; + class_device_initialize(&dev->cdev); + INIT_LIST_HEAD(&dev->h_list); + INIT_LIST_HEAD(&dev->node); + } + + return dev; +} + +static void input_register_classdevice(struct input_dev *dev) +{ + static atomic_t input_no = ATOMIC_INIT(0); + const char *path; + + __module_get(THIS_MODULE); + + dev->dev = dev->cdev.dev; + + snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), + "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); + + path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL); + printk(KERN_INFO "input: %s/%s as %s\n", + dev->name ? dev->name : "Unspecified device", + path ? path : "", dev->cdev.class_id); + kfree(path); + + class_device_add(&dev->cdev); +} + void input_register_device(struct input_dev *dev) { struct input_handle *handle; @@ -637,6 +688,10 @@ void input_register_device(struct input_dev *dev) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle); + + if (dev->dynalloc) + input_register_classdevice(dev); + #ifdef CONFIG_HOTPLUG input_call_hotplug("add", dev); #endif @@ -665,6 +720,9 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); + if (dev->dynalloc) + class_device_unregister(&dev->cdev); + input_wakeup_procfs_readers(); } @@ -753,26 +811,34 @@ static int __init input_init(void) { int err; + err = class_register(&input_dev_class); + if (err) { + printk(KERN_ERR "input: unable to register input_dev class\n"); + return err; + } + input_class = class_create(THIS_MODULE, "input"); if (IS_ERR(input_class)) { printk(KERN_ERR "input: unable to register input class\n"); - return PTR_ERR(input_class); + err = PTR_ERR(input_class); + goto fail1; } err = input_proc_init(); if (err) - goto fail1; + goto fail2; err = register_chrdev(INPUT_MAJOR, "input", &input_fops); if (err) { printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); - goto fail2; + goto fail3; } return 0; - fail2: input_proc_exit(); - fail1: class_destroy(input_class); + fail3: input_proc_exit(); + fail2: class_destroy(input_class); + fail1: class_unregister(&input_dev_class); return err; } @@ -781,6 +847,7 @@ static void __exit input_exit(void) input_proc_exit(); unregister_chrdev(INPUT_MAJOR, "input"); class_destroy(input_class); + class_unregister(&input_dev_class); } subsys_initcall(input_init); diff --git a/include/linux/input.h b/include/linux/input.h index e8c296ff6257..3defa29a17d3 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -12,6 +12,7 @@ #ifdef __KERNEL__ #include #include +#include #else #include #include @@ -889,11 +890,15 @@ struct input_dev { struct semaphore sem; /* serializes open and close operations */ unsigned int users; - struct device *dev; + struct class_device cdev; + struct device *dev; /* will be removed soon */ + + int dynalloc; /* temporarily */ struct list_head h_list; struct list_head node; }; +#define to_input_dev(d) container_of(d, struct input_dev, cdev) /* * Structure for hotplug & device<->driver matching. @@ -984,6 +989,23 @@ static inline void init_input_dev(struct input_dev *dev) INIT_LIST_HEAD(&dev->node); } +struct input_dev *input_allocate_device(void); + +static inline void input_free_device(struct input_dev *dev) +{ + kfree(dev); +} + +static inline struct input_dev *input_get_device(struct input_dev *dev) +{ + return to_input_dev(class_device_get(&dev->cdev)); +} + +static inline void input_put_device(struct input_dev *dev) +{ + class_device_put(&dev->cdev); +} + void input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *); From 2e5b636bb5f8dacbb91d08544e2c41ebcad5dace Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:44 -0500 Subject: [PATCH 0612/1940] [PATCH] drivers/input/mouse: convert to dynamic input_dev allocation Input: convert drivers/input/mouse to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/alps.c | 63 +++++++++-------- drivers/input/mouse/alps.h | 2 +- drivers/input/mouse/amimouse.c | 49 +++++++------ drivers/input/mouse/inport.c | 106 +++++++++++++++-------------- drivers/input/mouse/lifebook.c | 16 +++-- drivers/input/mouse/logibm.c | 88 ++++++++++++------------ drivers/input/mouse/logips2pp.c | 20 +++--- drivers/input/mouse/maplemouse.c | 10 +-- drivers/input/mouse/pc110pad.c | 64 +++++++++-------- drivers/input/mouse/psmouse-base.c | 99 ++++++++++++++------------- drivers/input/mouse/psmouse.h | 2 +- drivers/input/mouse/rpcmouse.c | 43 ++++++------ drivers/input/mouse/sermouse.c | 82 +++++++++++----------- drivers/input/mouse/synaptics.c | 6 +- drivers/input/mouse/vsxxxaa.c | 84 +++++++++++------------ 15 files changed, 368 insertions(+), 366 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b20783f9748a..4acc7fd4cd0f 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -79,8 +79,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) { struct alps_data *priv = psmouse->private; unsigned char *packet = psmouse->packet; - struct input_dev *dev = &psmouse->dev; - struct input_dev *dev2 = &priv->dev2; + struct input_dev *dev = psmouse->dev; + struct input_dev *dev2 = priv->dev2; int x, y, z, ges, fin, left, right, middle; int back = 0, forward = 0; @@ -379,20 +379,24 @@ static int alps_reconnect(struct psmouse *psmouse) static void alps_disconnect(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; + psmouse_reset(psmouse); - input_unregister_device(&priv->dev2); + input_unregister_device(priv->dev2); kfree(priv); } int alps_init(struct psmouse *psmouse) { struct alps_data *priv; + struct input_dev *dev1 = psmouse->dev, *dev2; int version; - psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); - if (!priv) + psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + dev2 = input_allocate_device(); + if (!priv || !dev2) goto init_fail; - memset(priv, 0, sizeof(struct alps_data)); + + priv->dev2 = dev2; if (!(priv->i = alps_get_model(psmouse, &version))) goto init_fail; @@ -411,41 +415,39 @@ int alps_init(struct psmouse *psmouse) if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) goto init_fail; - psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY); - psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); - psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER); - psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY); + dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); + dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER); + dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS); - input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0); - input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0); - input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0); + dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS); + input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); + input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); + input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); if (priv->i->flags & ALPS_WHEEL) { - psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL); - psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); + dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL); + dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); } if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { - psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); - psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); + dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); + dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); } sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys); - priv->dev2.phys = priv->phys; - priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; - priv->dev2.id.bustype = BUS_I8042; - priv->dev2.id.vendor = 0x0002; - priv->dev2.id.product = PSMOUSE_ALPS; - priv->dev2.id.version = 0x0000; + dev2->phys = priv->phys; + dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; + dev2->id.bustype = BUS_I8042; + dev2->id.vendor = 0x0002; + dev2->id.product = PSMOUSE_ALPS; + dev2->id.version = 0x0000; - priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); - priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); + dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - input_register_device(&priv->dev2); - - printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys); + input_register_device(priv->dev2); psmouse->protocol_handler = alps_process_byte; psmouse->disconnect = alps_disconnect; @@ -455,6 +457,7 @@ int alps_init(struct psmouse *psmouse) return 0; init_fail: + input_free_device(dev2); kfree(priv); return -1; } diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index aba103dd65b7..e428f8d5d12e 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -22,7 +22,7 @@ struct alps_model_info { }; struct alps_data { - struct input_dev dev2; /* Relative device */ + struct input_dev *dev2; /* Relative device */ char name[32]; /* Name */ char phys[32]; /* Phys */ struct alps_model_info *i; /* Info */ diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index e994849efb8f..d13d4c8fe3c5 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -34,10 +34,7 @@ MODULE_DESCRIPTION("Amiga mouse driver"); MODULE_LICENSE("GPL"); static int amimouse_lastx, amimouse_lasty; -static struct input_dev amimouse_dev; - -static char *amimouse_name = "Amiga mouse"; -static char *amimouse_phys = "amimouse/input0"; +static struct input_dev *amimouse_dev; static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) { @@ -62,16 +59,16 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) potgor = custom.potgor; - input_regs(&amimouse_dev, fp); + input_regs(amimouse_dev, fp); - input_report_rel(&amimouse_dev, REL_X, dx); - input_report_rel(&amimouse_dev, REL_Y, dy); + input_report_rel(amimouse_dev, REL_X, dx); + input_report_rel(amimouse_dev, REL_Y, dy); - input_report_key(&amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); - input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100); - input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400); + input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); + input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); + input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); - input_sync(&amimouse_dev); + input_sync(amimouse_dev); return IRQ_HANDLED; } @@ -103,28 +100,30 @@ static int __init amimouse_init(void) if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) return -ENODEV; - amimouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - amimouse_dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - amimouse_dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - amimouse_dev.open = amimouse_open; - amimouse_dev.close = amimouse_close; + if (!(amimouse_dev = input_allocate_device())) + return -ENOMEM; - amimouse_dev.name = amimouse_name; - amimouse_dev.phys = amimouse_phys; - amimouse_dev.id.bustype = BUS_AMIGA; - amimouse_dev.id.vendor = 0x0001; - amimouse_dev.id.product = 0x0002; - amimouse_dev.id.version = 0x0100; + amimouse_dev->name = "Amiga mouse"; + amimouse_dev->phys = "amimouse/input0"; + amimouse_dev->id.bustype = BUS_AMIGA; + amimouse_dev->id.vendor = 0x0001; + amimouse_dev->id.product = 0x0002; + amimouse_dev->id.version = 0x0100; - input_register_device(&amimouse_dev); + amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + amimouse_dev->open = amimouse_open; + amimouse_dev->close = amimouse_close; + + input_register_device(amimouse_dev); - printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name); return 0; } static void __exit amimouse_exit(void) { - input_unregister_device(&amimouse_dev); + input_unregister_device(amimouse_dev); } module_init(amimouse_init); diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 1f62c0134010..afc66f56df43 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c @@ -87,7 +87,36 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)"); __obsolete_setup("inport_irq="); -static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static struct input_dev *inport_dev; + +static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned char buttons; + + outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); + outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); + + input_regs(inport_dev, regs); + + outb(INPORT_REG_X, INPORT_CONTROL_PORT); + input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT)); + + outb(INPORT_REG_Y, INPORT_CONTROL_PORT); + input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT)); + + outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT); + buttons = inb(INPORT_DATA_PORT); + + input_report_key(inport_dev, BTN_MIDDLE, buttons & 1); + input_report_key(inport_dev, BTN_LEFT, buttons & 2); + input_report_key(inport_dev, BTN_RIGHT, buttons & 4); + + outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); + outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); + + input_sync(inport_dev); + return IRQ_HANDLED; +} static int inport_open(struct input_dev *dev) { @@ -106,54 +135,9 @@ static void inport_close(struct input_dev *dev) free_irq(inport_irq, NULL); } -static struct input_dev inport_dev = { - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) }, - .relbit = { BIT(REL_X) | BIT(REL_Y) }, - .open = inport_open, - .close = inport_close, - .name = INPORT_NAME, - .phys = "isa023c/input0", - .id = { - .bustype = BUS_ISA, - .vendor = INPORT_VENDOR, - .product = 0x0001, - .version = 0x0100, - }, -}; - -static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned char buttons; - - outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); - outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); - - input_regs(&inport_dev, regs); - - outb(INPORT_REG_X, INPORT_CONTROL_PORT); - input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT)); - - outb(INPORT_REG_Y, INPORT_CONTROL_PORT); - input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT)); - - outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT); - buttons = inb(INPORT_DATA_PORT); - - input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1); - input_report_key(&inport_dev, BTN_LEFT, buttons & 2); - input_report_key(&inport_dev, BTN_RIGHT, buttons & 4); - - outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); - outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); - - input_sync(&inport_dev); - return IRQ_HANDLED; -} - static int __init inport_init(void) { - unsigned char a,b,c; + unsigned char a, b, c; if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); @@ -163,26 +147,44 @@ static int __init inport_init(void) a = inb(INPORT_SIGNATURE_PORT); b = inb(INPORT_SIGNATURE_PORT); c = inb(INPORT_SIGNATURE_PORT); - if (( a == b ) || ( a != c )) { + if (a == b || a != c) { release_region(INPORT_BASE, INPORT_EXTENT); printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); return -ENODEV; } + if (!(inport_dev = input_allocate_device())) { + printk(KERN_ERR "inport.c: Not enough memory for input device\n"); + release_region(INPORT_BASE, INPORT_EXTENT); + return -ENOMEM; + } + + inport_dev->name = INPORT_NAME; + inport_dev->phys = "isa023c/input0"; + inport_dev->id.bustype = BUS_ISA; + inport_dev->id.vendor = INPORT_VENDOR; + inport_dev->id.product = 0x0001; + inport_dev->id.version = 0x0100; + + inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + + inport_dev->open = inport_open; + inport_dev->close = inport_close; + outb(INPORT_RESET, INPORT_CONTROL_PORT); outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_BASE, INPORT_DATA_PORT); - input_register_device(&inport_dev); - - printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq); + input_register_device(inport_dev); return 0; } static void __exit inport_exit(void) { - input_unregister_device(&inport_dev); + input_unregister_device(inport_dev); release_region(INPORT_BASE, INPORT_EXTENT); } diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index bd9df9b28325..55991424ac91 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -34,7 +34,7 @@ static struct dmi_system_id lifebook_dmi_table[] = { static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { unsigned char *packet = psmouse->packet; - struct input_dev *dev = &psmouse->dev; + struct input_dev *dev = psmouse->dev; if (psmouse->pktcnt != 3) return PSMOUSE_GOOD_DATA; @@ -113,15 +113,17 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) int lifebook_init(struct psmouse *psmouse) { + struct input_dev *input_dev = psmouse->dev; + if (lifebook_absolute_mode(psmouse)) return -1; - psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); - psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0); - input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0); + input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); psmouse->protocol_handler = lifebook_process_byte; psmouse->set_resolution = lifebook_set_resolution; diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index 8b5243167227..9c7ce38806d7 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c @@ -77,39 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)"); __obsolete_setup("logibm_irq="); -static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs); - -static int logibm_open(struct input_dev *dev) -{ - if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) { - printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq); - return -EBUSY; - } - outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT); - return 0; -} - -static void logibm_close(struct input_dev *dev) -{ - outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); - free_irq(logibm_irq, NULL); -} - -static struct input_dev logibm_dev = { - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) }, - .relbit = { BIT(REL_X) | BIT(REL_Y) }, - .open = logibm_open, - .close = logibm_close, - .name = "Logitech bus mouse", - .phys = "isa023c/input0", - .id = { - .bustype = BUS_ISA, - .vendor = 0x0003, - .product = 0x0001, - .version = 0x0100, - }, -}; +static struct input_dev *logibm_dev; static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -127,18 +95,34 @@ static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs) dy |= (buttons & 0xf) << 4; buttons = ~buttons >> 5; - input_regs(&logibm_dev, regs); - input_report_rel(&logibm_dev, REL_X, dx); - input_report_rel(&logibm_dev, REL_Y, dy); - input_report_key(&logibm_dev, BTN_RIGHT, buttons & 1); - input_report_key(&logibm_dev, BTN_MIDDLE, buttons & 2); - input_report_key(&logibm_dev, BTN_LEFT, buttons & 4); - input_sync(&logibm_dev); + input_regs(logibm_dev, regs); + input_report_rel(logibm_dev, REL_X, dx); + input_report_rel(logibm_dev, REL_Y, dy); + input_report_key(logibm_dev, BTN_RIGHT, buttons & 1); + input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2); + input_report_key(logibm_dev, BTN_LEFT, buttons & 4); + input_sync(logibm_dev); outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT); return IRQ_HANDLED; } +static int logibm_open(struct input_dev *dev) +{ + if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) { + printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq); + return -EBUSY; + } + outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT); + return 0; +} + +static void logibm_close(struct input_dev *dev) +{ + outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); + free_irq(logibm_irq, NULL); +} + static int __init logibm_init(void) { if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) { @@ -159,16 +143,34 @@ static int __init logibm_init(void) outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT); outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); - input_register_device(&logibm_dev); + if (!(logibm_dev = input_allocate_device())) { + printk(KERN_ERR "logibm.c: Not enough memory for input device\n"); + release_region(LOGIBM_BASE, LOGIBM_EXTENT); + return -ENOMEM; + } - printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq); + logibm_dev->name = "Logitech bus mouse"; + logibm_dev->phys = "isa023c/input0"; + logibm_dev->id.bustype = BUS_ISA; + logibm_dev->id.vendor = 0x0003; + logibm_dev->id.product = 0x0001; + logibm_dev->id.version = 0x0100; + + logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + + logibm_dev->open = logibm_open; + logibm_dev->close = logibm_close; + + input_register_device(logibm_dev); return 0; } static void __exit logibm_exit(void) { - input_unregister_device(&logibm_dev); + input_unregister_device(logibm_dev); release_region(LOGIBM_BASE, LOGIBM_EXTENT); } diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 7df96525222e..0f69ff46c1ae 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -40,7 +40,7 @@ struct ps2pp_info { static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { - struct input_dev *dev = &psmouse->dev; + struct input_dev *dev = psmouse->dev; unsigned char *packet = psmouse->packet; if (psmouse->pktcnt < 3) @@ -257,25 +257,27 @@ static struct ps2pp_info *get_model_info(unsigned char model) static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info, int using_ps2pp) { + struct input_dev *input_dev = psmouse->dev; + if (model_info->features & PS2PP_SIDE_BTN) - set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_SIDE, input_dev->keybit); if (model_info->features & PS2PP_EXTRA_BTN) - set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_EXTRA, input_dev->keybit); if (model_info->features & PS2PP_TASK_BTN) - set_bit(BTN_TASK, psmouse->dev.keybit); + set_bit(BTN_TASK, input_dev->keybit); if (model_info->features & PS2PP_NAV_BTN) { - set_bit(BTN_FORWARD, psmouse->dev.keybit); - set_bit(BTN_BACK, psmouse->dev.keybit); + set_bit(BTN_FORWARD, input_dev->keybit); + set_bit(BTN_BACK, input_dev->keybit); } if (model_info->features & PS2PP_WHEEL) - set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(REL_WHEEL, input_dev->relbit); if (model_info->features & PS2PP_HWHEEL) - set_bit(REL_HWHEEL, psmouse->dev.relbit); + set_bit(REL_HWHEEL, input_dev->relbit); switch (model_info->kind) { case PS2PP_KIND_WHEEL: @@ -387,7 +389,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) } if (buttons < 3) - clear_bit(BTN_MIDDLE, psmouse->dev.keybit); + clear_bit(BTN_MIDDLE, psmouse->dev->keybit); if (model_info) ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index e90c60cbbf05..b5b34fe4fee8 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c @@ -41,13 +41,12 @@ static int dc_mouse_connect(struct maple_device *dev) unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); struct input_dev *input_dev; - if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL))) - return -1; + dev->private_data = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; dev->private_data = input_dev; - memset(input_dev, 0, sizeof(struct dc_mouse)); - init_input_dev(input_dev); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); @@ -59,8 +58,6 @@ static int dc_mouse_connect(struct maple_device *dev) maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE); - printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name); - return 0; } @@ -70,7 +67,6 @@ static void dc_mouse_disconnect(struct maple_device *dev) struct input_dev *input_dev = dev->private_data; input_unregister_device(input_dev); - kfree(input_dev); } diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index 93393d5c0078..d284ea712151 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c @@ -53,13 +53,10 @@ MODULE_LICENSE("GPL"); static int pc110pad_irq = 10; static int pc110pad_io = 0x15e0; -static struct input_dev pc110pad_dev; +static struct input_dev *pc110pad_dev; static int pc110pad_data[3]; static int pc110pad_count; -static char *pc110pad_name = "IBM PC110 TouchPad"; -static char *pc110pad_phys = "isa15e0/input0"; - static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) { int value = inb_p(pc110pad_io); @@ -74,14 +71,14 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) if (pc110pad_count < 3) return IRQ_HANDLED; - input_regs(&pc110pad_dev, regs); - input_report_key(&pc110pad_dev, BTN_TOUCH, + input_regs(pc110pad_dev, regs); + input_report_key(pc110pad_dev, BTN_TOUCH, pc110pad_data[0] & 0x01); - input_report_abs(&pc110pad_dev, ABS_X, + input_report_abs(pc110pad_dev, ABS_X, pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100)); - input_report_abs(&pc110pad_dev, ABS_Y, + input_report_abs(pc110pad_dev, ABS_Y, pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80)); - input_sync(&pc110pad_dev); + input_sync(pc110pad_dev); pc110pad_count = 0; return IRQ_HANDLED; @@ -94,9 +91,9 @@ static void pc110pad_close(struct input_dev *dev) static int pc110pad_open(struct input_dev *dev) { - pc110pad_interrupt(0,NULL,NULL); - pc110pad_interrupt(0,NULL,NULL); - pc110pad_interrupt(0,NULL,NULL); + pc110pad_interrupt(0, NULL, NULL); + pc110pad_interrupt(0, NULL, NULL); + pc110pad_interrupt(0, NULL, NULL); outb(PC110PAD_ON, pc110pad_io + 2); pc110pad_count = 0; @@ -127,45 +124,46 @@ static int __init pc110pad_init(void) outb(PC110PAD_OFF, pc110pad_io + 2); - if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) - { + if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) { release_region(pc110pad_io, 4); printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq); return -EBUSY; } - pc110pad_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - pc110pad_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - pc110pad_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + if (!(pc110pad_dev = input_allocate_device())) { + free_irq(pc110pad_irq, NULL); + release_region(pc110pad_io, 4); + printk(KERN_ERR "pc110pad: Not enough memory.\n"); + return -ENOMEM; + } - pc110pad_dev.absmax[ABS_X] = 0x1ff; - pc110pad_dev.absmax[ABS_Y] = 0x0ff; + pc110pad_dev->name = "IBM PC110 TouchPad"; + pc110pad_dev->phys = "isa15e0/input0"; + pc110pad_dev->id.bustype = BUS_ISA; + pc110pad_dev->id.vendor = 0x0003; + pc110pad_dev->id.product = 0x0001; + pc110pad_dev->id.version = 0x0100; - pc110pad_dev.open = pc110pad_open; - pc110pad_dev.close = pc110pad_close; + pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - pc110pad_dev.name = pc110pad_name; - pc110pad_dev.phys = pc110pad_phys; - pc110pad_dev.id.bustype = BUS_ISA; - pc110pad_dev.id.vendor = 0x0003; - pc110pad_dev.id.product = 0x0001; - pc110pad_dev.id.version = 0x0100; + pc110pad_dev->absmax[ABS_X] = 0x1ff; + pc110pad_dev->absmax[ABS_Y] = 0x0ff; - input_register_device(&pc110pad_dev); + pc110pad_dev->open = pc110pad_open; + pc110pad_dev->close = pc110pad_close; - printk(KERN_INFO "input: %s at %#x irq %d\n", - pc110pad_name, pc110pad_io, pc110pad_irq); + input_register_device(pc110pad_dev); return 0; } static void __exit pc110pad_exit(void) { - input_unregister_device(&pc110pad_dev); - outb(PC110PAD_OFF, pc110pad_io + 2); - free_irq(pc110pad_irq, NULL); + input_unregister_device(pc110pad_dev); release_region(pc110pad_io, 4); } diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index af24313ff5bb..6ee9999a2eaa 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -114,7 +114,7 @@ struct psmouse_protocol { static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { - struct input_dev *dev = &psmouse->dev; + struct input_dev *dev = psmouse->dev; unsigned char *packet = psmouse->packet; if (psmouse->pktcnt < psmouse->pktsize) @@ -333,12 +333,11 @@ static int genius_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { - set_bit(BTN_EXTRA, psmouse->dev.keybit); - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(BTN_EXTRA, psmouse->dev->keybit); + set_bit(BTN_SIDE, psmouse->dev->keybit); + set_bit(REL_WHEEL, psmouse->dev->relbit); psmouse->vendor = "Genius"; - psmouse->name = "Wheel Mouse"; psmouse->pktsize = 4; } @@ -365,8 +364,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { - set_bit(BTN_MIDDLE, psmouse->dev.keybit); - set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(BTN_MIDDLE, psmouse->dev->keybit); + set_bit(REL_WHEEL, psmouse->dev->relbit); if (!psmouse->vendor) psmouse->vendor = "Generic"; if (!psmouse->name) psmouse->name = "Wheel Mouse"; @@ -398,10 +397,10 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { - set_bit(BTN_MIDDLE, psmouse->dev.keybit); - set_bit(REL_WHEEL, psmouse->dev.relbit); - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_MIDDLE, psmouse->dev->keybit); + set_bit(REL_WHEEL, psmouse->dev->relbit); + set_bit(BTN_SIDE, psmouse->dev->keybit); + set_bit(BTN_EXTRA, psmouse->dev->keybit); if (!psmouse->vendor) psmouse->vendor = "Generic"; if (!psmouse->name) psmouse->name = "Explorer Mouse"; @@ -433,7 +432,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { - set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev->keybit); psmouse->vendor = "Kensington"; psmouse->name = "ThinkingMouse"; @@ -839,9 +838,9 @@ static void psmouse_disconnect(struct serio *serio) psmouse_set_state(psmouse, PSMOUSE_IGNORE); - input_unregister_device(&psmouse->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(psmouse->dev); kfree(psmouse); if (parent) @@ -852,16 +851,14 @@ static void psmouse_disconnect(struct serio *serio) static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) { - memset(&psmouse->dev, 0, sizeof(struct input_dev)); + struct input_dev *input_dev = psmouse->dev; - init_input_dev(&psmouse->dev); + input_dev->private = psmouse; + input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; - psmouse->dev.private = psmouse; - psmouse->dev.dev = &psmouse->ps2dev.serio->dev; - - psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); psmouse->set_rate = psmouse_set_rate; psmouse->set_resolution = psmouse_set_resolution; @@ -883,12 +880,12 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto sprintf(psmouse->devname, "%s %s %s", psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); - psmouse->dev.name = psmouse->devname; - psmouse->dev.phys = psmouse->phys; - psmouse->dev.id.bustype = BUS_I8042; - psmouse->dev.id.vendor = 0x0002; - psmouse->dev.id.product = psmouse->type; - psmouse->dev.id.version = psmouse->model; + input_dev->name = psmouse->devname; + input_dev->phys = psmouse->phys; + input_dev->id.bustype = BUS_I8042; + input_dev->id.vendor = 0x0002; + input_dev->id.product = psmouse->type; + input_dev->id.version = psmouse->model; return 0; } @@ -900,7 +897,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto static int psmouse_connect(struct serio *serio, struct serio_driver *drv) { struct psmouse *psmouse, *parent = NULL; - int retval; + struct input_dev *input_dev; + int retval = -ENOMEM; down(&psmouse_sem); @@ -913,12 +911,13 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_deactivate(parent); } - if (!(psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL))) { - retval = -ENOMEM; + psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!psmouse || !input_dev) goto out; - } ps2_init(&psmouse->ps2dev, serio); + psmouse->dev = input_dev; sprintf(psmouse->phys, "%s/input0", serio->phys); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); @@ -926,16 +925,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, psmouse); retval = serio_open(serio, drv); - if (retval) { - serio_set_drvdata(serio, NULL); - kfree(psmouse); + if (retval) goto out; - } if (psmouse_probe(psmouse) < 0) { serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(psmouse); retval = -ENODEV; goto out; } @@ -947,13 +941,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_switch_protocol(psmouse, NULL); - input_register_device(&psmouse->dev); - printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); - psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - psmouse_initialize(psmouse); + input_register_device(psmouse->dev); + if (parent && parent->pt_activate) parent->pt_activate(parent); @@ -964,6 +956,12 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) retval = 0; out: + if (retval) { + serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(psmouse); + } + /* If this is a pass-through port the parent needs to be re-activated */ if (parent) psmouse_activate(parent); @@ -1161,6 +1159,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co { struct serio *serio = psmouse->ps2dev.serio; struct psmouse *parent = NULL; + struct input_dev *new_dev; struct psmouse_protocol *proto; int retry = 0; @@ -1170,9 +1169,13 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co if (psmouse->type == proto->type) return count; + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + while (serio->child) { if (++retry > 3) { printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); + input_free_device(new_dev); return -EIO; } @@ -1182,11 +1185,15 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co serio_pin_driver_uninterruptible(serio); down(&psmouse_sem); - if (serio->drv != &psmouse_drv) + if (serio->drv != &psmouse_drv) { + input_free_device(new_dev); return -ENODEV; + } - if (psmouse->type == proto->type) + if (psmouse->type == proto->type) { + input_free_device(new_dev); return count; /* switched by other thread */ + } } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { @@ -1199,8 +1206,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co psmouse->disconnect(psmouse); psmouse_set_state(psmouse, PSMOUSE_IGNORE); - input_unregister_device(&psmouse->dev); + input_unregister_device(psmouse->dev); + psmouse->dev = new_dev; psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); if (psmouse_switch_protocol(psmouse, proto) < 0) { @@ -1212,8 +1220,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co psmouse_initialize(psmouse); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - input_register_device(&psmouse->dev); - printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); + input_register_device(psmouse->dev); if (parent && parent->pt_activate) parent->pt_activate(parent); diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 45d2bd774f00..7c4192bd1279 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -36,7 +36,7 @@ typedef enum { struct psmouse { void *private; - struct input_dev dev; + struct input_dev *dev; struct ps2dev ps2dev; char *vendor; char *name; diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 8fe1212b8fd7..09b6ffdb7582 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c @@ -34,20 +34,7 @@ MODULE_DESCRIPTION("Acorn RiscPC mouse driver"); MODULE_LICENSE("GPL"); static short rpcmouse_lastx, rpcmouse_lasty; - -static struct input_dev rpcmouse_dev = { - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) }, - .relbit = { BIT(REL_X) | BIT(REL_Y) }, - .name = "Acorn RiscPC Mouse", - .phys = "rpcmouse/input0", - .id = { - .bustype = BUS_HOST, - .vendor = 0x0005, - .product = 0x0001, - .version = 0x0100, - }, -}; +static struct input_dev *rpcmouse_dev; static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) { @@ -78,29 +65,41 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } + static int __init rpcmouse_init(void) { - init_input_dev(&rpcmouse_dev); + if (!(rpcmouse_dev = input_allocate_device())) + return -ENOMEM; + + rpcmouse_dev->name = "Acorn RiscPC Mouse"; + rpcmouse_dev->phys = "rpcmouse/input0"; + rpcmouse_dev->id.bustype = BUS_HOST; + rpcmouse_dev->id.vendor = 0x0005; + rpcmouse_dev->id.product = 0x0001; + rpcmouse_dev->id.version = 0x0100; + + rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + rpcmouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX); rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY); - if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", &rpcmouse_dev)) { + if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", rpcmouse_dev)) { printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n"); - return -1; + input_free_device(rpcmouse_dev); + return -EBUSY; } - input_register_device(&rpcmouse_dev); - - printk(KERN_INFO "input: Acorn RiscPC mouse\n"); + input_register_device(rpcmouse_dev); return 0; } static void __exit rpcmouse_exit(void) { - input_unregister_device(&rpcmouse_dev); - free_irq(IRQ_VSYNCPULSE, &rpcmouse_dev); + free_irq(IRQ_VSYNCPULSE, rpcmouse_dev); + input_unregister_device(rpcmouse_dev); } module_init(rpcmouse_init); diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index d12b93ae3900..4bf584364d28 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -48,7 +48,7 @@ static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse" "Logitech MZ++ Mouse"}; struct sermouse { - struct input_dev dev; + struct input_dev *dev; signed char buf[8]; unsigned char count; unsigned char type; @@ -64,7 +64,7 @@ struct sermouse { static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { - struct input_dev *dev = &sermouse->dev; + struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; input_regs(dev, regs); @@ -107,7 +107,7 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, st static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { - struct input_dev *dev = &sermouse->dev; + struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; if (data & 0x40) sermouse->count = 0; @@ -230,9 +230,9 @@ static void sermouse_disconnect(struct serio *serio) { struct sermouse *sermouse = serio_get_drvdata(serio); - input_unregister_device(&sermouse->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(sermouse->dev); kfree(sermouse); } @@ -244,56 +244,52 @@ static void sermouse_disconnect(struct serio *serio) static int sermouse_connect(struct serio *serio, struct serio_driver *drv) { struct sermouse *sermouse; - unsigned char c; - int err; + struct input_dev *input_dev; + unsigned char c = serio->id.extra; + int err = -ENOMEM; - if (!serio->id.proto || serio->id.proto > SERIO_MZPP) - return -ENODEV; - - if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL))) - return -ENOMEM; - - memset(sermouse, 0, sizeof(struct sermouse)); - - init_input_dev(&sermouse->dev); - sermouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - sermouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); - sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - sermouse->dev.private = sermouse; - - sermouse->type = serio->id.proto; - c = serio->id.extra; - - if (c & 0x01) set_bit(BTN_MIDDLE, sermouse->dev.keybit); - if (c & 0x02) set_bit(BTN_SIDE, sermouse->dev.keybit); - if (c & 0x04) set_bit(BTN_EXTRA, sermouse->dev.keybit); - if (c & 0x10) set_bit(REL_WHEEL, sermouse->dev.relbit); - if (c & 0x20) set_bit(REL_HWHEEL, sermouse->dev.relbit); + sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!sermouse || !input_dev) + goto fail; + sermouse->dev = input_dev; sprintf(sermouse->phys, "%s/input0", serio->phys); + sermouse->type = serio->id.proto; - sermouse->dev.name = sermouse_protocols[sermouse->type]; - sermouse->dev.phys = sermouse->phys; - sermouse->dev.id.bustype = BUS_RS232; - sermouse->dev.id.vendor = sermouse->type; - sermouse->dev.id.product = c; - sermouse->dev.id.version = 0x0100; - sermouse->dev.dev = &serio->dev; + input_dev->name = sermouse_protocols[sermouse->type]; + input_dev->phys = sermouse->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = sermouse->type; + input_dev->id.product = c; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->private = sermouse; + + if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); + if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); + if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit); + if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit); + if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit); serio_set_drvdata(serio, sermouse); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(sermouse); - return err; - } + if (err) + goto fail; - input_register_device(&sermouse->dev); - - printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys); + input_register_device(sermouse->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(sermouse); + return err; } static struct serio_device_id sermouse_serio_ids[] = { diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 029309422409..97cdfd6acaca 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -342,7 +342,7 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data */ static void synaptics_process_packet(struct psmouse *psmouse) { - struct input_dev *dev = &psmouse->dev; + struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; struct synaptics_hw_state hw; int num_fingers; @@ -473,7 +473,7 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse) static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { - struct input_dev *dev = &psmouse->dev; + struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; input_regs(dev, regs); @@ -645,7 +645,7 @@ int synaptics_init(struct psmouse *psmouse) SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), priv->model_id, priv->capabilities, priv->ext_cap); - set_input_params(&psmouse->dev, priv); + set_input_params(psmouse->dev, priv); psmouse->protocol_handler = synaptics_process_byte; psmouse->set_rate = synaptics_set_rate; diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index f024be9b44d2..36e9442a16b2 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -112,7 +112,7 @@ MODULE_LICENSE ("GPL"); struct vsxxxaa { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */ unsigned char buf[BUFLEN]; @@ -211,7 +211,7 @@ vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t le static void vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { - struct input_dev *dev = &mouse->dev; + struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; int left, middle, right; int dx, dy; @@ -269,7 +269,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs) static void vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { - struct input_dev *dev = &mouse->dev; + struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; int left, middle, right, touch; int x, y; @@ -323,7 +323,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs) static void vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { - struct input_dev *dev = &mouse->dev; + struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; int left, middle, right; unsigned char error; @@ -483,9 +483,9 @@ vsxxxaa_disconnect (struct serio *serio) { struct vsxxxaa *mouse = serio_get_drvdata (serio); - input_unregister_device (&mouse->dev); serio_close (serio); serio_set_drvdata (serio, NULL); + input_unregister_device (mouse->dev); kfree (mouse); } @@ -493,61 +493,57 @@ static int vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) { struct vsxxxaa *mouse; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; - if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL))) - return -ENOMEM; - - memset (mouse, 0, sizeof (struct vsxxxaa)); - - init_input_dev (&mouse->dev); - set_bit (EV_KEY, mouse->dev.evbit); /* We have buttons */ - set_bit (EV_REL, mouse->dev.evbit); - set_bit (EV_ABS, mouse->dev.evbit); - set_bit (BTN_LEFT, mouse->dev.keybit); /* We have 3 buttons */ - set_bit (BTN_MIDDLE, mouse->dev.keybit); - set_bit (BTN_RIGHT, mouse->dev.keybit); - set_bit (BTN_TOUCH, mouse->dev.keybit); /* ...and Tablet */ - set_bit (REL_X, mouse->dev.relbit); - set_bit (REL_Y, mouse->dev.relbit); - set_bit (ABS_X, mouse->dev.absbit); - set_bit (ABS_Y, mouse->dev.absbit); - - mouse->dev.absmin[ABS_X] = 0; - mouse->dev.absmax[ABS_X] = 1023; - mouse->dev.absmin[ABS_Y] = 0; - mouse->dev.absmax[ABS_Y] = 1023; - - mouse->dev.private = mouse; + mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); + input_dev = input_allocate_device (); + if (!mouse || !input_dev) + goto fail; + mouse->dev = input_dev; + mouse->serio = serio; sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); sprintf (mouse->phys, "%s/input0", serio->phys); - mouse->dev.name = mouse->name; - mouse->dev.phys = mouse->phys; - mouse->dev.id.bustype = BUS_RS232; - mouse->dev.dev = &serio->dev; - mouse->serio = serio; + + input_dev->name = mouse->name; + input_dev->phys = mouse->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->cdev.dev = &serio->dev; + input_dev->private = mouse; + + set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ + set_bit (EV_REL, input_dev->evbit); + set_bit (EV_ABS, input_dev->evbit); + set_bit (BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ + set_bit (BTN_MIDDLE, input_dev->keybit); + set_bit (BTN_RIGHT, input_dev->keybit); + set_bit (BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ + set_bit (REL_X, input_dev->relbit); + set_bit (REL_Y, input_dev->relbit); + input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0); + input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0); serio_set_drvdata (serio, mouse); err = serio_open (serio, drv); - if (err) { - serio_set_drvdata (serio, NULL); - kfree (mouse); - return err; - } + if (err) + goto fail; /* * Request selftest. Standard packet format and differential * mode will be requested after the device ID'ed successfully. */ - mouse->serio->write (mouse->serio, 'T'); /* Test */ + serio->write (serio, 'T'); /* Test */ - input_register_device (&mouse->dev); - - printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys); + input_register_device (input_dev); return 0; + + fail: serio_set_drvdata (serio, NULL); + input_free_device (input_dev); + kfree (mouse); + return err; } static struct serio_device_id vsxxaa_serio_ids[] = { From 3c42f0c3dde8feb59fc87df45cadb847d5511c0a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:45 -0500 Subject: [PATCH 0613/1940] [PATCH] drivers/input/keyboard: convert to dynamic input_dev allocation Input: convert drivers/input/keyboard to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/amikbd.c | 57 +++++---- drivers/input/keyboard/atkbd.c | 188 +++++++++++++++------------- drivers/input/keyboard/corgikbd.c | 76 +++++------ drivers/input/keyboard/lkkbd.c | 126 +++++++++---------- drivers/input/keyboard/maple_keyb.c | 72 +++++------ drivers/input/keyboard/newtonkbd.c | 83 ++++++------ drivers/input/keyboard/spitzkbd.c | 77 +++++++----- drivers/input/keyboard/sunkbd.c | 117 +++++++++-------- drivers/input/keyboard/xtkbd.c | 82 ++++++------ 9 files changed, 448 insertions(+), 430 deletions(-) diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 4e8e8ea214ab..3d63bc1ad322 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -155,10 +155,7 @@ static const char *amikbd_messages[8] = { [7] = KERN_WARNING "amikbd: keyboard interrupt\n" }; -static struct input_dev amikbd_dev; - -static char *amikbd_name = "Amiga keyboard"; -static char *amikbd_phys = "amikbd/input0"; +static struct input_dev *amikbd_dev; static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) { @@ -176,16 +173,16 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) scancode = amikbd_keycode[scancode]; - input_regs(&amikbd_dev, fp); + input_regs(amikbd_dev, fp); if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ - input_report_key(&amikbd_dev, scancode, 1); - input_report_key(&amikbd_dev, scancode, 0); - input_sync(&amikbd_dev); + input_report_key(amikbd_dev, scancode, 1); + input_report_key(amikbd_dev, scancode, 0); } else { - input_report_key(&amikbd_dev, scancode, down); - input_sync(&amikbd_dev); + input_report_key(amikbd_dev, scancode, down); } + + input_sync(amikbd_dev); } else /* scancodes >= 0x78 are error codes */ printk(amikbd_messages[scancode - 0x78]); @@ -202,39 +199,41 @@ static int __init amikbd_init(void) if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) return -EBUSY; - init_input_dev(&amikbd_dev); + amikbd_dev = input_dev_allocate(); + if (!amikbd_dev) { + printk(KERN_ERR "amikbd: not enough memory for input device\n"); + release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); + return -ENOMEM; + } - amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - amikbd_dev.keycode = amikbd_keycode; - amikbd_dev.keycodesize = sizeof(unsigned char); - amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode); + amikbd_dev->name = "Amiga Keyboard"; + amikbd_dev->phys = "amikbd/input0"; + amikbd_dev->id.bustype = BUS_AMIGA; + amikbd_dev->id.vendor = 0x0001; + amikbd_dev->id.product = 0x0001; + amikbd_dev->id.version = 0x0100; + + amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + amikbd_dev->keycode = amikbd_keycode; + amikbd_dev->keycodesize = sizeof(unsigned char); + amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode); for (i = 0; i < 0x78; i++) if (amikbd_keycode[i]) - set_bit(amikbd_keycode[i], amikbd_dev.keybit); + set_bit(amikbd_keycode[i], amikbd_dev->keybit); ciaa.cra &= ~0x41; /* serial data in, turn off TA */ request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); - amikbd_dev.name = amikbd_name; - amikbd_dev.phys = amikbd_phys; - amikbd_dev.id.bustype = BUS_AMIGA; - amikbd_dev.id.vendor = 0x0001; - amikbd_dev.id.product = 0x0001; - amikbd_dev.id.version = 0x0100; - - input_register_device(&amikbd_dev); - - printk(KERN_INFO "input: %s\n", amikbd_name); - + input_register_device(amikbd_dev); return 0; } static void __exit amikbd_exit(void) { - input_unregister_device(&amikbd_dev); free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); - release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100); + input_unregister_device(amikbd_dev); + release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); } module_init(amikbd_init); diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 1ad8c2ee7dbf..820c7fd9a604 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -185,12 +185,12 @@ static struct { struct atkbd { - struct ps2dev ps2dev; + struct ps2dev ps2dev; + struct input_dev *dev; /* Written only during init */ char name[64]; char phys[32]; - struct input_dev dev; unsigned short id; unsigned char keycode[512]; @@ -290,7 +290,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (!atkbd->enabled) goto out; - input_event(&atkbd->dev, EV_MSC, MSC_RAW, code); + input_event(atkbd->dev, EV_MSC, MSC_RAW, code); if (atkbd->translated) { @@ -326,10 +326,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, atkbd->release = 1; goto out; case ATKBD_RET_HANGUEL: - atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3); + atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3); goto out; case ATKBD_RET_HANJA: - atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3); + atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); goto out; case ATKBD_RET_ERR: printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); @@ -345,7 +345,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } if (atkbd->keycode[code] != ATKBD_KEY_NULL) - input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code); + input_event(atkbd->dev, EV_MSC, MSC_SCAN, code); switch (atkbd->keycode[code]) { case ATKBD_KEY_NULL: @@ -365,7 +365,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, "to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f); } - input_sync(&atkbd->dev); + input_sync(atkbd->dev); break; case ATKBD_SCR_1: scroll = 1 - atkbd->release * 2; @@ -390,7 +390,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, break; default: value = atkbd->release ? 0 : - (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key))); + (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key))); switch (value) { /* Workaround Toshiba laptop multiple keypress */ case 0: @@ -398,7 +398,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, break; case 1: atkbd->last = code; - atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2; + atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2; break; case 2: if (!time_after(jiffies, atkbd->time) && atkbd->last == code) @@ -406,16 +406,16 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, break; } - atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value); + atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value); } if (atkbd->scroll) { - input_regs(&atkbd->dev, regs); + input_regs(atkbd->dev, regs); if (click != -1) - input_report_key(&atkbd->dev, BTN_MIDDLE, click); - input_report_rel(&atkbd->dev, REL_WHEEL, scroll); - input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll); - input_sync(&atkbd->dev); + input_report_key(atkbd->dev, BTN_MIDDLE, click); + input_report_rel(atkbd->dev, REL_WHEEL, scroll); + input_report_rel(atkbd->dev, REL_HWHEEL, hscroll); + input_sync(atkbd->dev); } atkbd->release = 0; @@ -463,7 +463,6 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co return 0; - case EV_REP: if (atkbd->softrepeat) return 0; @@ -693,7 +692,7 @@ static void atkbd_disconnect(struct serio *serio) device_remove_file(&serio->dev, &atkbd_attr_softrepeat); device_remove_file(&serio->dev, &atkbd_attr_softraw); - input_unregister_device(&atkbd->dev); + input_unregister_device(atkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(atkbd); @@ -701,7 +700,7 @@ static void atkbd_disconnect(struct serio *serio) /* - * atkbd_set_device_attrs() initializes keyboard's keycode table + * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set */ @@ -737,53 +736,58 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) static void atkbd_set_device_attrs(struct atkbd *atkbd) { + struct input_dev *input_dev = atkbd->dev; int i; - memset(&atkbd->dev, 0, sizeof(struct input_dev)); + if (atkbd->extra) + sprintf(atkbd->name, "AT Set 2 Extra keyboard"); + else + sprintf(atkbd->name, "AT %s Set %d keyboard", + atkbd->translated ? "Translated" : "Raw", atkbd->set); - init_input_dev(&atkbd->dev); + sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys); - atkbd->dev.name = atkbd->name; - atkbd->dev.phys = atkbd->phys; - atkbd->dev.id.bustype = BUS_I8042; - atkbd->dev.id.vendor = 0x0001; - atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set; - atkbd->dev.id.version = atkbd->id; - atkbd->dev.event = atkbd_event; - atkbd->dev.private = atkbd; - atkbd->dev.dev = &atkbd->ps2dev.serio->dev; + input_dev->name = atkbd->name; + input_dev->phys = atkbd->phys; + input_dev->id.bustype = BUS_I8042; + input_dev->id.vendor = 0x0001; + input_dev->id.product = atkbd->translated ? 1 : atkbd->set; + input_dev->id.version = atkbd->id; + input_dev->event = atkbd_event; + input_dev->private = atkbd; + input_dev->cdev.dev = &atkbd->ps2dev.serio->dev; - atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); if (atkbd->write) { - atkbd->dev.evbit[0] |= BIT(EV_LED); - atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + input_dev->evbit[0] |= BIT(EV_LED); + input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); } if (atkbd->extra) - atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | + input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); if (!atkbd->softrepeat) { - atkbd->dev.rep[REP_DELAY] = 250; - atkbd->dev.rep[REP_PERIOD] = 33; + input_dev->rep[REP_DELAY] = 250; + input_dev->rep[REP_PERIOD] = 33; } - atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); + input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); if (atkbd->scroll) { - atkbd->dev.evbit[0] |= BIT(EV_REL); - atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL); - set_bit(BTN_MIDDLE, atkbd->dev.keybit); + input_dev->evbit[0] |= BIT(EV_REL); + input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL); + set_bit(BTN_MIDDLE, input_dev->keybit); } - atkbd->dev.keycode = atkbd->keycode; - atkbd->dev.keycodesize = sizeof(unsigned char); - atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode); + input_dev->keycode = atkbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); for (i = 0; i < 512; i++) if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) - set_bit(atkbd->keycode[i], atkbd->dev.keybit); + set_bit(atkbd->keycode[i], input_dev->keybit); } /* @@ -796,13 +800,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) static int atkbd_connect(struct serio *serio, struct serio_driver *drv) { struct atkbd *atkbd; - int err; + struct input_dev *dev; + int err = -ENOMEM; - if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL))) - return - ENOMEM; - - memset(atkbd, 0, sizeof(struct atkbd)); + atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL); + dev = input_allocate_device(); + if (!atkbd || !dev) + goto fail; + atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); switch (serio->id.type) { @@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, atkbd); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(atkbd); - return err; - } + if (err) + goto fail; if (atkbd->write) { if (atkbd_probe(atkbd)) { serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(atkbd); - return -ENODEV; + err = -ENODEV; + goto fail; } atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); @@ -851,19 +853,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->id = 0xab00; } - if (atkbd->extra) - sprintf(atkbd->name, "AT Set 2 Extra keyboard"); - else - sprintf(atkbd->name, "AT %s Set %d keyboard", - atkbd->translated ? "Translated" : "Raw", atkbd->set); - - sprintf(atkbd->phys, "%s/input0", serio->phys); - atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); - device_create_file(&serio->dev, &atkbd_attr_extra); device_create_file(&serio->dev, &atkbd_attr_scroll); device_create_file(&serio->dev, &atkbd_attr_set); @@ -872,9 +864,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd_enable(atkbd); - printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys); + input_register_device(atkbd->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(dev); + kfree(atkbd); + return err; } /* @@ -896,9 +893,9 @@ static int atkbd_reconnect(struct serio *serio) atkbd_disable(atkbd); if (atkbd->write) { - param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0) - | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0) - | (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0); + param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0) + | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0) + | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0); if (atkbd_probe(atkbd)) return -1; @@ -1008,6 +1005,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) { + struct input_dev *new_dev; unsigned long value; char *rest; @@ -1019,12 +1017,19 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun return -EINVAL; if (atkbd->extra != value) { - /* unregister device as it's properties will change */ - input_unregister_device(&atkbd->dev); + /* + * Since device's properties will change we need to + * unregister old device. But allocate new one first + * to make sure we have it. + */ + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + input_unregister_device(atkbd->dev); + atkbd->dev = new_dev; atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); atkbd_activate(atkbd); atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); + input_register_device(atkbd->dev); } return count; } @@ -1036,6 +1041,7 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) { + struct input_dev *new_dev; unsigned long value; char *rest; @@ -1044,12 +1050,14 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou return -EINVAL; if (atkbd->scroll != value) { - /* unregister device as it's properties will change */ - input_unregister_device(&atkbd->dev); + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + input_unregister_device(atkbd->dev); + atkbd->dev = new_dev; atkbd->scroll = value; atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); + input_register_device(atkbd->dev); } return count; } @@ -1061,6 +1069,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) { + struct input_dev *new_dev; unsigned long value; char *rest; @@ -1072,13 +1081,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) return -EINVAL; if (atkbd->set != value) { - /* unregister device as it's properties will change */ - input_unregister_device(&atkbd->dev); + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + input_unregister_device(atkbd->dev); + atkbd->dev = new_dev; atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); atkbd_activate(atkbd); atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); + input_register_device(atkbd->dev); } return count; } @@ -1090,6 +1101,7 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) { + struct input_dev *new_dev; unsigned long value; char *rest; @@ -1101,15 +1113,16 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t return -EINVAL; if (atkbd->softrepeat != value) { - /* unregister device as it's properties will change */ - input_unregister_device(&atkbd->dev); + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + input_unregister_device(atkbd->dev); + atkbd->dev = new_dev; atkbd->softrepeat = value; if (atkbd->softrepeat) atkbd->softraw = 1; atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); + input_register_device(atkbd->dev); } - return count; } @@ -1121,6 +1134,7 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) { + struct input_dev *new_dev; unsigned long value; char *rest; @@ -1129,11 +1143,13 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co return -EINVAL; if (atkbd->softraw != value) { - /* unregister device as it's properties will change */ - input_unregister_device(&atkbd->dev); + if (!(new_dev = input_allocate_device())) + return -ENOMEM; + input_unregister_device(atkbd->dev); + atkbd->dev = new_dev; atkbd->softraw = value; atkbd_set_device_attrs(atkbd); - input_register_device(&atkbd->dev); + input_register_device(atkbd->dev); } return count; } diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index cd4b6e795013..564bb365f6fc 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -70,8 +70,7 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = { struct corgikbd { unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)]; - struct input_dev input; - char phys[32]; + struct input_dev *input; spinlock_t lock; struct timer_list timer; @@ -147,7 +146,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs spin_lock_irqsave(&corgikbd_data->lock, flags); if (regs) - input_regs(&corgikbd_data->input, regs); + input_regs(corgikbd_data->input, regs); num_pressed = 0; for (col = 0; col < KB_COLS; col++) { @@ -169,14 +168,14 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs scancode = SCANCODE(row, col); pressed = rowd & KB_ROWMASK(row); - input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed); + input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed); if (pressed) num_pressed++; if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF) && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) { - input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); + input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); corgikbd_data->suspend_jiffies=jiffies; } } @@ -185,7 +184,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs corgikbd_activate_all(); - input_sync(&corgikbd_data->input); + input_sync(corgikbd_data->input); /* if any keys are pressed, enable the timer */ if (num_pressed) @@ -249,9 +248,9 @@ static void corgikbd_hinge_timer(unsigned long data) if (hinge_count >= HINGE_STABLE_COUNT) { spin_lock_irqsave(&corgikbd_data->lock, flags); - input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); - input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); - input_sync(&corgikbd_data->input); + input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); + input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); + input_sync(corgikbd_data->input); spin_unlock_irqrestore(&corgikbd_data->lock, flags); } @@ -287,16 +286,21 @@ static int corgikbd_resume(struct device *dev, uint32_t level) static int __init corgikbd_probe(struct device *dev) { - int i; struct corgikbd *corgikbd; + struct input_dev *input_dev; + int i; corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL); - if (!corgikbd) + input_dev = input_allocate_device(); + if (!corgikbd || !input_dev) { + kfree(corgikbd); + input_free_device(input_dev); return -ENOMEM; + } - dev_set_drvdata(dev,corgikbd); - strcpy(corgikbd->phys, "corgikbd/input0"); + dev_set_drvdata(dev, corgikbd); + corgikbd->input = input_dev; spin_lock_init(&corgikbd->lock); /* Init Keyboard rescan timer */ @@ -311,28 +315,30 @@ static int __init corgikbd_probe(struct device *dev) corgikbd->suspend_jiffies=jiffies; - init_input_dev(&corgikbd->input); - corgikbd->input.private = corgikbd; - corgikbd->input.name = "Corgi Keyboard"; - corgikbd->input.dev = dev; - corgikbd->input.phys = corgikbd->phys; - corgikbd->input.id.bustype = BUS_HOST; - corgikbd->input.id.vendor = 0x0001; - corgikbd->input.id.product = 0x0001; - corgikbd->input.id.version = 0x0100; - corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); - corgikbd->input.keycode = corgikbd->keycode; - corgikbd->input.keycodesize = sizeof(unsigned char); - corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode); - memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode)); - for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++) - set_bit(corgikbd->keycode[i], corgikbd->input.keybit); - clear_bit(0, corgikbd->input.keybit); - set_bit(SW_0, corgikbd->input.swbit); - set_bit(SW_1, corgikbd->input.swbit); - input_register_device(&corgikbd->input); + input_dev->name = "Corgi Keyboard"; + input_dev->phys = "corgikbd/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = dev; + input_dev->private = corgikbd; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); + input_dev->keycode = corgikbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode); + + for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++) + set_bit(corgikbd->keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); + set_bit(SW_0, input_dev->swbit); + set_bit(SW_1, input_dev->swbit); + + input_register_device(corgikbd->input); + mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL); /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ @@ -349,8 +355,6 @@ static int __init corgikbd_probe(struct device *dev) for (i = 0; i < CORGI_KEY_STROBE_NUM; i++) pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); - printk(KERN_INFO "input: Corgi Keyboard Registered\n"); - return 0; } @@ -365,7 +369,7 @@ static int corgikbd_remove(struct device *dev) del_timer_sync(&corgikbd->htimer); del_timer_sync(&corgikbd->timer); - input_unregister_device(&corgikbd->input); + input_unregister_device(corgikbd->input); kfree(corgikbd); diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 098963c7cdd6..7f06780a437f 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -102,7 +102,7 @@ static int ctrlclick_volume = 100; /* % */ module_param (ctrlclick_volume, int, 0); MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); -static int lk201_compose_is_alt = 0; +static int lk201_compose_is_alt; module_param (lk201_compose_is_alt, int, 0); MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " "will act as an Alt key"); @@ -274,7 +274,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { }; #define CHECK_LED(LED, BITS) do { \ - if (test_bit (LED, lk->dev.led)) \ + if (test_bit (LED, lk->dev->led)) \ leds_on |= BITS; \ else \ leds_off |= BITS; \ @@ -287,7 +287,7 @@ struct lkkbd { lk_keycode_t keycode[LK_NUM_KEYCODES]; int ignore_bytes; unsigned char id[LK_NUM_IGNORE_BYTES]; - struct input_dev dev; + struct input_dev *dev; struct serio *serio; struct work_struct tq; char name[64]; @@ -423,8 +423,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags, DBG (KERN_INFO "Got byte 0x%02x\n", data); if (lk->ignore_bytes > 0) { - DBG (KERN_INFO "Ignoring a byte on %s\n", - lk->name); + DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name); lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; if (lk->ignore_bytes == 0) @@ -435,14 +434,14 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags, switch (data) { case LK_ALL_KEYS_UP: - input_regs (&lk->dev, regs); + input_regs (lk->dev, regs); for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++) if (lk->keycode[i] != KEY_RESERVED) - input_report_key (&lk->dev, lk->keycode[i], 0); - input_sync (&lk->dev); + input_report_key (lk->dev, lk->keycode[i], 0); + input_sync (lk->dev); break; case LK_METRONOME: - DBG (KERN_INFO "Got LK_METRONOME and don't " + DBG (KERN_INFO "Got %#d and don't " "know how to handle...\n"); break; case LK_OUTPUT_ERROR: @@ -482,12 +481,12 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags, default: if (lk->keycode[data] != KEY_RESERVED) { - input_regs (&lk->dev, regs); - if (!test_bit (lk->keycode[data], lk->dev.key)) - input_report_key (&lk->dev, lk->keycode[data], 1); + input_regs (lk->dev, regs); + if (!test_bit (lk->keycode[data], lk->dev->key)) + input_report_key (lk->dev, lk->keycode[data], 1); else - input_report_key (&lk->dev, lk->keycode[data], 0); - input_sync (&lk->dev); + input_report_key (lk->dev, lk->keycode[data], 0); + input_sync (lk->dev); } else printk (KERN_WARNING "%s: Unknown key with " "scancode 0x%02x on %s.\n", @@ -605,7 +604,7 @@ lkkbd_reinit (void *data) lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume)); /* Enable/disable keyclick (and possibly set volume) */ - if (test_bit (SND_CLICK, lk->dev.snd)) { + if (test_bit (SND_CLICK, lk->dev->snd)) { lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK); lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume)); lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK); @@ -616,7 +615,7 @@ lkkbd_reinit (void *data) } /* Sound the bell if needed */ - if (test_bit (SND_BELL, lk->dev.snd)) + if (test_bit (SND_BELL, lk->dev->snd)) lk->serio->write (lk->serio, LK_CMD_SOUND_BELL); } @@ -627,71 +626,70 @@ static int lkkbd_connect (struct serio *serio, struct serio_driver *drv) { struct lkkbd *lk; + struct input_dev *input_dev; int i; int err; - if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL))) - return -ENOMEM; - - memset (lk, 0, sizeof (struct lkkbd)); - - init_input_dev (&lk->dev); - set_bit (EV_KEY, lk->dev.evbit); - set_bit (EV_LED, lk->dev.evbit); - set_bit (EV_SND, lk->dev.evbit); - set_bit (EV_REP, lk->dev.evbit); - set_bit (LED_CAPSL, lk->dev.ledbit); - set_bit (LED_SLEEP, lk->dev.ledbit); - set_bit (LED_COMPOSE, lk->dev.ledbit); - set_bit (LED_SCROLLL, lk->dev.ledbit); - set_bit (SND_BELL, lk->dev.sndbit); - set_bit (SND_CLICK, lk->dev.sndbit); + lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL); + input_dev = input_allocate_device (); + if (!lk || !input_dev) { + err = -ENOMEM; + goto fail; + } lk->serio = serio; - + lk->dev = input_dev; INIT_WORK (&lk->tq, lkkbd_reinit, lk); - lk->bell_volume = bell_volume; lk->keyclick_volume = keyclick_volume; lk->ctrlclick_volume = ctrlclick_volume; + memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); - lk->dev.keycode = lk->keycode; - lk->dev.keycodesize = sizeof (lk_keycode_t); - lk->dev.keycodemax = LK_NUM_KEYCODES; + strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name)); + snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); - lk->dev.event = lkkbd_event; - lk->dev.private = lk; + input_dev->name = lk->name; + input_dev->phys = lk->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_LKKBD; + input_dev->id.product = 0; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->event = lkkbd_event; + input_dev->private = lk; + + set_bit (EV_KEY, input_dev->evbit); + set_bit (EV_LED, input_dev->evbit); + set_bit (EV_SND, input_dev->evbit); + set_bit (EV_REP, input_dev->evbit); + set_bit (LED_CAPSL, input_dev->ledbit); + set_bit (LED_SLEEP, input_dev->ledbit); + set_bit (LED_COMPOSE, input_dev->ledbit); + set_bit (LED_SCROLLL, input_dev->ledbit); + set_bit (SND_BELL, input_dev->sndbit); + set_bit (SND_CLICK, input_dev->sndbit); + + input_dev->keycode = lk->keycode; + input_dev->keycodesize = sizeof (lk_keycode_t); + input_dev->keycodemax = LK_NUM_KEYCODES; + for (i = 0; i < LK_NUM_KEYCODES; i++) + set_bit (lk->keycode[i], input_dev->keybit); serio_set_drvdata (serio, lk); err = serio_open (serio, drv); - if (err) { - serio_set_drvdata (serio, NULL); - kfree (lk); - return err; - } + if (err) + goto fail; - sprintf (lk->name, "DEC LK keyboard"); - sprintf (lk->phys, "%s/input0", serio->phys); - - memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); - for (i = 0; i < LK_NUM_KEYCODES; i++) - set_bit (lk->keycode[i], lk->dev.keybit); - - lk->dev.name = lk->name; - lk->dev.phys = lk->phys; - lk->dev.id.bustype = BUS_RS232; - lk->dev.id.vendor = SERIO_LKKBD; - lk->dev.id.product = 0; - lk->dev.id.version = 0x0100; - lk->dev.dev = &serio->dev; - - input_register_device (&lk->dev); - - printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys); + input_register_device (lk->dev); lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); return 0; + + fail: serio_set_drvdata (serio, NULL); + input_free_device (input_dev); + kfree (lk); + return err; } /* @@ -702,9 +700,11 @@ lkkbd_disconnect (struct serio *serio) { struct lkkbd *lk = serio_get_drvdata (serio); - input_unregister_device (&lk->dev); + input_get_device (lk->dev); + input_unregister_device (lk->dev); serio_close (serio); serio_set_drvdata (serio, NULL); + input_put_device (lk->dev); kfree (lk); } diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index eecbde294f1f..cc6aaf9e85be 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -37,7 +37,7 @@ static unsigned char dc_kbd_keycode[256] = { struct dc_kbd { - struct input_dev dev; + struct input_dev *dev; unsigned char new[8]; unsigned char old[8]; }; @@ -46,30 +46,24 @@ struct dc_kbd { static void dc_scan_kbd(struct dc_kbd *kbd) { int i; - struct input_dev *dev = &kbd->dev; + struct input_dev *dev = kbd->dev; - for(i=0; i<8; i++) - input_report_key(dev, - dc_kbd_keycode[i+224], - (kbd->new[0]>>i)&1); + for (i = 0; i < 8; i++) + input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); - for(i=2; i<8; i++) { + for (i = 2; i < 8; i++) { - if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) { - if(dc_kbd_keycode[kbd->old[i]]) - input_report_key(dev, - dc_kbd_keycode[kbd->old[i]], - 0); + if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) { + if (dc_kbd_keycode[kbd->old[i]]) + input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0); else printk("Unknown key (scancode %#x) released.", kbd->old[i]); } - if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) { + if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) { if(dc_kbd_keycode[kbd->new[i]]) - input_report_key(dev, - dc_kbd_keycode[kbd->new[i]], - 1); + input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1); else printk("Unknown key (scancode %#x) pressed.", kbd->new[i]); @@ -89,43 +83,39 @@ static void dc_kbd_callback(struct mapleq *mq) unsigned long *buf = mq->recvbuf; if (buf[1] == mapledev->function) { - memcpy(kbd->new, buf+2, 8); + memcpy(kbd->new, buf + 2, 8); dc_scan_kbd(kbd); } } static int dc_kbd_connect(struct maple_device *dev) { - int i; - unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); struct dc_kbd *kbd; + struct input_dev *input_dev; + unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); + int i; - if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL))) - return -1; - memset(kbd, 0, sizeof(struct dc_kbd)); + dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!kbd || !input_dev) { + kfree(kbd); + input_free_device(input_dev); + return -ENOMEM; + } - dev->private_data = kbd; + kbd->dev = input_dev; - kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + input_dev->name = dev->product_name; + input_dev->id.bustype = BUS_MAPLE; + input_dev->private = kbd; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + for (i = 0; i < 255; i++) + set_bit(dc_kbd_keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); - init_input_dev(&kbd->dev); - - for (i=0; i<255; i++) - set_bit(dc_kbd_keycode[i], kbd->dev.keybit); - - clear_bit(0, kbd->dev.keybit); - - kbd->dev.private = kbd; - - kbd->dev.name = dev->product_name; - kbd->dev.id.bustype = BUS_MAPLE; - - input_register_device(&kbd->dev); + input_register_device(kbd->dev); maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD); - - printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name); - return 0; } @@ -134,7 +124,7 @@ static void dc_kbd_disconnect(struct maple_device *dev) { struct dc_kbd *kbd = dev->private_data; - input_unregister_device(&kbd->dev); + input_unregister_device(kbd->dev); kfree(kbd); } diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 2e8ce1613eec..d10983c521e6 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -57,11 +57,9 @@ static unsigned char nkbd_keycode[128] = { KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0 }; -static char *nkbd_name = "Newton Keyboard"; - struct nkbd { unsigned char keycode[128]; - struct input_dev dev; + struct input_dev *dev; struct serio *serio; char phys[32]; }; @@ -73,13 +71,13 @@ static irqreturn_t nkbd_interrupt(struct serio *serio, /* invalid scan codes are probably the init sequence, so we ignore them */ if (nkbd->keycode[data & NKBD_KEY]) { - input_regs(&nkbd->dev, regs); - input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS); - input_sync(&nkbd->dev); + input_regs(nkbd->dev, regs); + input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS); + input_sync(nkbd->dev); } else if (data == 0xe7) /* end of init sequence */ - printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys); + printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys); return IRQ_HANDLED; } @@ -87,62 +85,59 @@ static irqreturn_t nkbd_interrupt(struct serio *serio, static int nkbd_connect(struct serio *serio, struct serio_driver *drv) { struct nkbd *nkbd; + struct input_dev *input_dev; + int err = -ENOMEM; int i; - int err; - if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL))) - return -ENOMEM; - - memset(nkbd, 0, sizeof(struct nkbd)); - - nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!nkbd || !input_dev) + goto fail; nkbd->serio = serio; + nkbd->dev = input_dev; + sprintf(nkbd->phys, "%s/input0", serio->phys); + memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode)); - init_input_dev(&nkbd->dev); - nkbd->dev.keycode = nkbd->keycode; - nkbd->dev.keycodesize = sizeof(unsigned char); - nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode); - nkbd->dev.private = nkbd; + input_dev->name = "Newton Keyboard"; + input_dev->phys = nkbd->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_NEWTON; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = nkbd; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + input_dev->keycode = nkbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode); + for (i = 0; i < 128; i++) + set_bit(nkbd->keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); serio_set_drvdata(serio, nkbd); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(nkbd); - return err; - } - - memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode)); - for (i = 0; i < 128; i++) - set_bit(nkbd->keycode[i], nkbd->dev.keybit); - clear_bit(0, nkbd->dev.keybit); - - sprintf(nkbd->phys, "%s/input0", serio->phys); - - nkbd->dev.name = nkbd_name; - nkbd->dev.phys = nkbd->phys; - nkbd->dev.id.bustype = BUS_RS232; - nkbd->dev.id.vendor = SERIO_NEWTON; - nkbd->dev.id.product = 0x0001; - nkbd->dev.id.version = 0x0100; - nkbd->dev.dev = &serio->dev; - - input_register_device(&nkbd->dev); - - printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys); + if (err) + goto fail; + input_register_device(nkbd->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(nkbd); + return err; } static void nkbd_disconnect(struct serio *serio) { struct nkbd *nkbd = serio_get_drvdata(serio); - input_unregister_device(&nkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(nkbd->dev); kfree(nkbd); } diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 344f46005401..732fb310e487 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -85,7 +85,7 @@ static int spitz_senses[] = { struct spitzkbd { unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)]; - struct input_dev input; + struct input_dev *input; char phys[32]; spinlock_t lock; @@ -187,8 +187,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs spin_lock_irqsave(&spitzkbd_data->lock, flags); - if (regs) - input_regs(&spitzkbd_data->input, regs); + input_regs(spitzkbd_data->input, regs); num_pressed = 0; for (col = 0; col < KB_COLS; col++) { @@ -210,7 +209,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs scancode = SCANCODE(row, col); pressed = rowd & KB_ROWMASK(row); - input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed); + input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed); if (pressed) num_pressed++; @@ -220,15 +219,15 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs spitzkbd_activate_all(); - input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 ); - input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey); + input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 ); + input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey); if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) { - input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1); + input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1); spitzkbd_data->suspend_jiffies = jiffies; } - input_sync(&spitzkbd_data->input); + input_sync(spitzkbd_data->input); /* if any keys are pressed, enable the timer */ if (num_pressed) @@ -259,6 +258,7 @@ static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *reg static void spitzkbd_timer_callback(unsigned long data) { struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; + spitzkbd_scankeyboard(spitzkbd_data, NULL); } @@ -298,9 +298,9 @@ static void spitzkbd_hinge_timer(unsigned long data) if (hinge_count >= HINGE_STABLE_COUNT) { spin_lock_irqsave(&spitzkbd_data->lock, flags); - input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); - input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); - input_sync(&spitzkbd_data->input); + input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); + input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); + input_sync(spitzkbd_data->input); spin_unlock_irqrestore(&spitzkbd_data->lock, flags); } else { @@ -346,14 +346,21 @@ static int spitzkbd_resume(struct device *dev, uint32_t level) static int __init spitzkbd_probe(struct device *dev) { - int i; struct spitzkbd *spitzkbd; + struct input_dev *input_dev; + int i; spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL); if (!spitzkbd) return -ENOMEM; - dev_set_drvdata(dev,spitzkbd); + input_dev = input_allocate_device(); + if (!input_dev) { + kfree(spitzkbd); + return -ENOMEM; + } + + dev_set_drvdata(dev, spitzkbd); strcpy(spitzkbd->phys, "spitzkbd/input0"); spin_lock_init(&spitzkbd->lock); @@ -368,30 +375,34 @@ static int __init spitzkbd_probe(struct device *dev) spitzkbd->htimer.function = spitzkbd_hinge_timer; spitzkbd->htimer.data = (unsigned long) spitzkbd; - spitzkbd->suspend_jiffies=jiffies; + spitzkbd->suspend_jiffies = jiffies; - init_input_dev(&spitzkbd->input); - spitzkbd->input.private = spitzkbd; - spitzkbd->input.name = "Spitz Keyboard"; - spitzkbd->input.dev = dev; - spitzkbd->input.phys = spitzkbd->phys; - spitzkbd->input.id.bustype = BUS_HOST; - spitzkbd->input.id.vendor = 0x0001; - spitzkbd->input.id.product = 0x0001; - spitzkbd->input.id.version = 0x0100; - spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); - spitzkbd->input.keycode = spitzkbd->keycode; - spitzkbd->input.keycodesize = sizeof(unsigned char); - spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode); + spitzkbd->input = input_dev; + + input_dev->private = spitzkbd; + input_dev->name = "Spitz Keyboard"; + input_dev->phys = spitzkbd->phys; + input_dev->cdev.dev = dev; + + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); + input_dev->keycode = spitzkbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode); memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode)); for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++) - set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit); - clear_bit(0, spitzkbd->input.keybit); - set_bit(SW_0, spitzkbd->input.swbit); - set_bit(SW_1, spitzkbd->input.swbit); + set_bit(spitzkbd->keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); + set_bit(SW_0, input_dev->swbit); + set_bit(SW_1, input_dev->swbit); + + input_register_device(input_dev); - input_register_device(&spitzkbd->input); mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ @@ -444,7 +455,7 @@ static int spitzkbd_remove(struct device *dev) del_timer_sync(&spitzkbd->htimer); del_timer_sync(&spitzkbd->timer); - input_unregister_device(&spitzkbd->input); + input_unregister_device(spitzkbd->input); kfree(spitzkbd); diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 4bae5d89348d..b15b6d8d4f83 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -76,13 +76,14 @@ static unsigned char sunkbd_keycode[128] = { struct sunkbd { unsigned char keycode[128]; - struct input_dev dev; + struct input_dev *dev; struct serio *serio; struct work_struct tq; wait_queue_head_t wait; char name[64]; char phys[32]; char type; + unsigned char enabled; volatile s8 reset; volatile s8 layout; }; @@ -124,10 +125,13 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio, break; default: + if (!sunkbd->enabled) + break; + if (sunkbd->keycode[data & SUNKBD_KEY]) { - input_regs(&sunkbd->dev, regs); - input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); - input_sync(&sunkbd->dev); + input_regs(sunkbd->dev, regs); + input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); + input_sync(sunkbd->dev); } else { printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n", data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed"); @@ -184,7 +188,7 @@ static int sunkbd_initialize(struct sunkbd *sunkbd) sunkbd->reset = -2; sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET); wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); - if (sunkbd->reset <0) + if (sunkbd->reset < 0) return -1; sunkbd->type = sunkbd->reset; @@ -213,10 +217,17 @@ static void sunkbd_reinit(void *data) sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED); sunkbd->serio->write(sunkbd->serio, - (!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) | - (!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led)); - sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd)); - sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev.snd)); + (!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) | + (!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led)); + sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd)); + sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd)); +} + +static void sunkbd_enable(struct sunkbd *sunkbd, int enable) +{ + serio_pause_rx(sunkbd->serio); + sunkbd->enabled = 1; + serio_continue_rx(sunkbd->serio); } /* @@ -226,70 +237,64 @@ static void sunkbd_reinit(void *data) static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) { struct sunkbd *sunkbd; + struct input_dev *input_dev; + int err = -ENOMEM; int i; - int err; - if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL))) - return -ENOMEM; - - memset(sunkbd, 0, sizeof(struct sunkbd)); - - init_input_dev(&sunkbd->dev); - init_waitqueue_head(&sunkbd->wait); - - sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); - sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML); - sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL); + sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!sunkbd || !input_dev) + goto fail; sunkbd->serio = serio; - + sunkbd->dev = input_dev; + init_waitqueue_head(&sunkbd->wait); INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd); - - sunkbd->dev.keycode = sunkbd->keycode; - sunkbd->dev.keycodesize = sizeof(unsigned char); - sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode); - - sunkbd->dev.event = sunkbd_event; - sunkbd->dev.private = sunkbd; + snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys); serio_set_drvdata(serio, sunkbd); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(sunkbd); - return err; - } + if (err) + goto fail; if (sunkbd_initialize(sunkbd) < 0) { serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(sunkbd); - return -ENODEV; + goto fail; } sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type); - memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); + + input_dev->name = sunkbd->name; + input_dev->phys = sunkbd->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_SUNKBD; + input_dev->id.product = sunkbd->type; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = sunkbd; + input_dev->event = sunkbd_event; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML); + input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL); + + input_dev->keycode = sunkbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode); for (i = 0; i < 128; i++) - set_bit(sunkbd->keycode[i], sunkbd->dev.keybit); - clear_bit(0, sunkbd->dev.keybit); - - sprintf(sunkbd->phys, "%s/input0", serio->phys); - - sunkbd->dev.name = sunkbd->name; - sunkbd->dev.phys = sunkbd->phys; - sunkbd->dev.id.bustype = BUS_RS232; - sunkbd->dev.id.vendor = SERIO_SUNKBD; - sunkbd->dev.id.product = sunkbd->type; - sunkbd->dev.id.version = 0x0100; - sunkbd->dev.dev = &serio->dev; - - input_register_device(&sunkbd->dev); - - printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys); + set_bit(sunkbd->keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); + sunkbd_enable(sunkbd, 1); + input_register_device(sunkbd->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(sunkbd); + return err; } /* @@ -299,7 +304,9 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) static void sunkbd_disconnect(struct serio *serio) { struct sunkbd *sunkbd = serio_get_drvdata(serio); - input_unregister_device(&sunkbd->dev); + + sunkbd_enable(sunkbd, 0); + input_unregister_device(sunkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(sunkbd); diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 19eaec7789d1..4135e3e16c51 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -56,11 +56,9 @@ static unsigned char xtkbd_keycode[256] = { 106 }; -static char *xtkbd_name = "XT Keyboard"; - struct xtkbd { unsigned char keycode[256]; - struct input_dev dev; + struct input_dev *dev; struct serio *serio; char phys[32]; }; @@ -77,9 +75,9 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio, default: if (xtkbd->keycode[data & XTKBD_KEY]) { - input_regs(&xtkbd->dev, regs); - input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE)); - input_sync(&xtkbd->dev); + input_regs(xtkbd->dev, regs); + input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE)); + input_sync(xtkbd->dev); } else { printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n", data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed"); @@ -91,62 +89,60 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio, static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) { struct xtkbd *xtkbd; + struct input_dev *input_dev; + int err = -ENOMEM; int i; - int err; - if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL))) - return -ENOMEM; - - memset(xtkbd, 0, sizeof(struct xtkbd)); - - xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!xtkbd || !input_dev) + goto fail; xtkbd->serio = serio; + xtkbd->dev = input_dev; + sprintf(xtkbd->phys, "%s/input0", serio->phys); + memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode)); - init_input_dev(&xtkbd->dev); - xtkbd->dev.keycode = xtkbd->keycode; - xtkbd->dev.keycodesize = sizeof(unsigned char); - xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode); - xtkbd->dev.private = xtkbd; + input_dev->name = "XT Keyboard"; + input_dev->phys = xtkbd->phys; + input_dev->id.bustype = BUS_XTKBD; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = xtkbd; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + input_dev->keycode = xtkbd->keycode; + input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode); + + for (i = 0; i < 255; i++) + set_bit(xtkbd->keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); serio_set_drvdata(serio, xtkbd); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(xtkbd); - return err; - } - - memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode)); - for (i = 0; i < 255; i++) - set_bit(xtkbd->keycode[i], xtkbd->dev.keybit); - clear_bit(0, xtkbd->dev.keybit); - - sprintf(xtkbd->phys, "%s/input0", serio->phys); - - xtkbd->dev.name = xtkbd_name; - xtkbd->dev.phys = xtkbd->phys; - xtkbd->dev.id.bustype = BUS_XTKBD; - xtkbd->dev.id.vendor = 0x0001; - xtkbd->dev.id.product = 0x0001; - xtkbd->dev.id.version = 0x0100; - xtkbd->dev.dev = &serio->dev; - - input_register_device(&xtkbd->dev); - - printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys); + if (err) + goto fail; + input_register_device(xtkbd->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(xtkbd); + return err; } static void xtkbd_disconnect(struct serio *serio) { struct xtkbd *xtkbd = serio_get_drvdata(serio); - input_unregister_device(&xtkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(xtkbd->dev); kfree(xtkbd); } From c5b7c7c395a34f12cdf246d66c1feeff2933d584 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:47 -0500 Subject: [PATCH 0614/1940] [PATCH] drivers/usb/input: convert to dynamic input_dev allocation Input: convert drivers/iusb/input to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/acecad.c | 76 +++++----- drivers/usb/input/aiptek.c | 209 +++++++++++++--------------- drivers/usb/input/appletouch.c | 130 +++++++++--------- drivers/usb/input/ati_remote.c | 175 +++++++++++------------ drivers/usb/input/hid-core.c | 49 +++---- drivers/usb/input/hid-input.c | 58 ++++---- drivers/usb/input/hid-lgff.c | 17 +-- drivers/usb/input/hid-tmff.c | 11 +- drivers/usb/input/hid.h | 2 +- drivers/usb/input/itmtouch.c | 70 ++++++---- drivers/usb/input/kbtab.c | 88 ++++++------ drivers/usb/input/keyspan_remote.c | 214 ++++++++++++----------------- drivers/usb/input/mtouchusb.c | 111 ++++++++------- drivers/usb/input/pid.c | 12 +- drivers/usb/input/powermate.c | 136 +++++++++--------- drivers/usb/input/touchkitusb.c | 116 ++++++++-------- drivers/usb/input/usbkbd.c | 105 +++++++------- drivers/usb/input/usbmouse.c | 97 +++++++------ drivers/usb/input/wacom.c | 142 +++++++++---------- drivers/usb/input/xpad.c | 133 +++++++++--------- drivers/usb/input/yealink.c | 66 ++++----- 21 files changed, 988 insertions(+), 1029 deletions(-) diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index 74f8760d7c07..a32558b4048e 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -53,7 +53,7 @@ struct usb_acecad { char name[128]; char phys[64]; struct usb_device *usbdev; - struct input_dev dev; + struct input_dev *input; struct urb *irq; signed char *data; @@ -64,7 +64,7 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) { struct usb_acecad *acecad = urb->context; unsigned char *data = acecad->data; - struct input_dev *dev = &acecad->dev; + struct input_dev *dev = acecad->input; int prox, status; switch (urb->status) { @@ -135,8 +135,8 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct usb_acecad *acecad; + struct input_dev *input_dev; int pipe, maxp; - char path[64]; if (interface->desc.bNumEndpoints != 1) return -ENODEV; @@ -153,8 +153,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL); - if (!acecad) - return -ENOMEM; + input_dev = input_allocate_device(); + if (!acecad || !input_dev) + goto fail1; acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma); if (!acecad->data) @@ -164,6 +165,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ if (!acecad->irq) goto fail2; + acecad->usbdev = dev; + acecad->input = input_dev; + if (dev->manufacturer) strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name)); @@ -173,48 +177,48 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ strlcat(acecad->name, dev->product, sizeof(acecad->name)); } - usb_make_path(dev, path, sizeof(path)); - snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path); + usb_make_path(dev, acecad->phys, sizeof(acecad->phys)); + strlcat(acecad->phys, "/input0", sizeof(acecad->phys)); - acecad->usbdev = dev; + input_dev->name = acecad->name; + input_dev->phys = acecad->phys; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = acecad; - acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2); + input_dev->open = usb_acecad_open; + input_dev->close = usb_acecad_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2); switch (id->driver_info) { case 0: - acecad->dev.absmax[ABS_X] = 5000; - acecad->dev.absmax[ABS_Y] = 3750; - acecad->dev.absmax[ABS_PRESSURE] = 512; + input_dev->absmax[ABS_X] = 5000; + input_dev->absmax[ABS_Y] = 3750; + input_dev->absmax[ABS_PRESSURE] = 512; if (!strlen(acecad->name)) snprintf(acecad->name, sizeof(acecad->name), "USB Acecad Flair Tablet %04x:%04x", - dev->descriptor.idVendor, dev->descriptor.idProduct); + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); break; case 1: - acecad->dev.absmax[ABS_X] = 3000; - acecad->dev.absmax[ABS_Y] = 2250; - acecad->dev.absmax[ABS_PRESSURE] = 1024; + input_dev->absmax[ABS_X] = 3000; + input_dev->absmax[ABS_Y] = 2250; + input_dev->absmax[ABS_PRESSURE] = 1024; if (!strlen(acecad->name)) snprintf(acecad->name, sizeof(acecad->name), "USB Acecad 302 Tablet %04x:%04x", - dev->descriptor.idVendor, dev->descriptor.idProduct); + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); break; } - acecad->dev.absfuzz[ABS_X] = 4; - acecad->dev.absfuzz[ABS_Y] = 4; - - acecad->dev.private = acecad; - acecad->dev.open = usb_acecad_open; - acecad->dev.close = usb_acecad_close; - - acecad->dev.name = acecad->name; - acecad->dev.phys = acecad->phys; - usb_to_input_id(dev, &acecad->dev.id); - acecad->dev.dev = &intf->dev; + input_dev->absfuzz[ABS_X] = 4; + input_dev->absfuzz[ABS_Y] = 4; usb_fill_int_urb(acecad->irq, dev, pipe, acecad->data, maxp > 8 ? 8 : maxp, @@ -222,17 +226,15 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->irq->transfer_dma = acecad->data_dma; acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(&acecad->dev); - - printk(KERN_INFO "input: %s with packet size %d on %s\n", - acecad->name, maxp, path); + input_register_device(acecad->input); usb_set_intfdata(intf, acecad); return 0; fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma); - fail1: kfree(acecad); + fail1: input_free_device(input_dev); + kfree(acecad); return -ENOMEM; } @@ -243,7 +245,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (acecad) { usb_kill_urb(acecad->irq); - input_unregister_device(&acecad->dev); + input_unregister_device(acecad->input); usb_free_urb(acecad->irq); usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma); kfree(acecad); diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index cd0cbfe20723..1c5205321d83 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -317,7 +317,7 @@ struct aiptek_settings { }; struct aiptek { - struct input_dev inputdev; /* input device struct */ + struct input_dev *inputdev; /* input device struct */ struct usb_device *usbdev; /* usb device struct */ struct urb *urb; /* urb for incoming reports */ dma_addr_t data_dma; /* our dma stuffage */ @@ -402,7 +402,7 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs) { struct aiptek *aiptek = urb->context; unsigned char *data = aiptek->data; - struct input_dev *inputdev = &aiptek->inputdev; + struct input_dev *inputdev = aiptek->inputdev; int jitterable = 0; int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck; @@ -955,20 +955,20 @@ static int aiptek_program_tablet(struct aiptek *aiptek) /* Query getXextension */ if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0) return ret; - aiptek->inputdev.absmin[ABS_X] = 0; - aiptek->inputdev.absmax[ABS_X] = ret - 1; + aiptek->inputdev->absmin[ABS_X] = 0; + aiptek->inputdev->absmax[ABS_X] = ret - 1; /* Query getYextension */ if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0) return ret; - aiptek->inputdev.absmin[ABS_Y] = 0; - aiptek->inputdev.absmax[ABS_Y] = ret - 1; + aiptek->inputdev->absmin[ABS_Y] = 0; + aiptek->inputdev->absmax[ABS_Y] = ret - 1; /* Query getPressureLevels */ if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0) return ret; - aiptek->inputdev.absmin[ABS_PRESSURE] = 0; - aiptek->inputdev.absmax[ABS_PRESSURE] = ret - 1; + aiptek->inputdev->absmin[ABS_PRESSURE] = 0; + aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1; /* Depending on whether we are in absolute or relative mode, we will * do a switchToTablet(absolute) or switchToMouse(relative) command. @@ -1025,8 +1025,8 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr return 0; return snprintf(buf, PAGE_SIZE, "%dx%d\n", - aiptek->inputdev.absmax[ABS_X] + 1, - aiptek->inputdev.absmax[ABS_Y] + 1); + aiptek->inputdev->absmax[ABS_X] + 1, + aiptek->inputdev->absmax[ABS_Y] + 1); } /* These structs define the sysfs files, param #1 is the name of the @@ -1048,7 +1048,7 @@ static ssize_t show_tabletProductId(struct device *dev, struct device_attribute return 0; return snprintf(buf, PAGE_SIZE, "0x%04x\n", - aiptek->inputdev.id.product); + aiptek->inputdev->id.product); } static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL); @@ -1063,7 +1063,7 @@ static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute * if (aiptek == NULL) return 0; - return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev.id.vendor); + return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor); } static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL); @@ -1977,7 +1977,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) struct input_dev *inputdev; struct input_handle *inputhandle; struct list_head *node, *next; - char path[64 + 1]; int i; int speeds[] = { 0, AIPTEK_PROGRAMMABLE_DELAY_50, @@ -1996,24 +1995,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ speeds[0] = programmableDelay; - if ((aiptek = kmalloc(sizeof(struct aiptek), GFP_KERNEL)) == NULL) - return -ENOMEM; - memset(aiptek, 0, sizeof(struct aiptek)); + aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); + inputdev = input_allocate_device(); + if (!aiptek || !inputdev) + goto fail1; aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, SLAB_ATOMIC, &aiptek->data_dma); - if (aiptek->data == NULL) { - kfree(aiptek); - return -ENOMEM; - } + if (!aiptek->data) + goto fail1; aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); - if (aiptek->urb == NULL) { - usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, - aiptek->data_dma); - kfree(aiptek); - return -ENOMEM; - } + if (!aiptek->urb) + goto fail2; + + aiptek->inputdev = inputdev; + aiptek->usbdev = usbdev; + aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber; + aiptek->inDelay = 0; + aiptek->endDelay = 0; + aiptek->previousJitterable = 0; /* Set up the curSettings struct. Said struct contains the current * programmable parameters. The newSetting struct contains changes @@ -2036,31 +2037,48 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Both structs should have equivalent settings */ - memcpy(&aiptek->newSetting, &aiptek->curSetting, - sizeof(struct aiptek_settings)); + aiptek->newSetting = aiptek->curSetting; + + /* Determine the usb devices' physical path. + * Asketh not why we always pretend we're using "../input0", + * but I suspect this will have to be refactored one + * day if a single USB device can be a keyboard & a mouse + * & a tablet, and the inputX number actually will tell + * us something... + */ + usb_make_path(usbdev, aiptek->features.usbPath, + sizeof(aiptek->features.usbPath)); + strlcat(aiptek->features.usbPath, "/input0", + sizeof(aiptek->features.usbPath)); + + /* Set up client data, pointers to open and close routines + * for the input device. + */ + inputdev->name = "Aiptek"; + inputdev->phys = aiptek->features.usbPath; + usb_to_input_id(usbdev, &inputdev->id); + inputdev->cdev.dev = &intf->dev; + inputdev->private = aiptek; + inputdev->open = aiptek_open; + inputdev->close = aiptek_close; /* Now program the capacities of the tablet, in terms of being * an input device. */ - aiptek->inputdev.evbit[0] |= BIT(EV_KEY) + inputdev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL) | BIT(EV_MSC); - aiptek->inputdev.absbit[0] |= - (BIT(ABS_X) | - BIT(ABS_Y) | - BIT(ABS_PRESSURE) | - BIT(ABS_TILT_X) | - BIT(ABS_TILT_Y) | BIT(ABS_WHEEL) | BIT(ABS_MISC)); + inputdev->absbit[0] |= BIT(ABS_MISC); - aiptek->inputdev.relbit[0] |= + inputdev->relbit[0] |= (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC)); - aiptek->inputdev.keybit[LONG(BTN_LEFT)] |= + inputdev->keybit[LONG(BTN_LEFT)] |= (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE)); - aiptek->inputdev.keybit[LONG(BTN_DIGI)] |= + inputdev->keybit[LONG(BTN_DIGI)] |= (BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_PENCIL) | @@ -2070,70 +2088,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) BIT(BTN_TOOL_LENS) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2)); - aiptek->inputdev.mscbit[0] = BIT(MSC_SERIAL); + inputdev->mscbit[0] = BIT(MSC_SERIAL); /* Programming the tablet macro keys needs to be done with a for loop * as the keycodes are discontiguous. */ for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i) - set_bit(macroKeyEvents[i], aiptek->inputdev.keybit); + set_bit(macroKeyEvents[i], inputdev->keybit); - /* Set up client data, pointers to open and close routines - * for the input device. - */ - aiptek->inputdev.private = aiptek; - aiptek->inputdev.open = aiptek_open; - aiptek->inputdev.close = aiptek_close; - - /* Determine the usb devices' physical path. - * Asketh not why we always pretend we're using "../input0", - * but I suspect this will have to be refactored one - * day if a single USB device can be a keyboard & a mouse - * & a tablet, and the inputX number actually will tell - * us something... - */ - if (usb_make_path(usbdev, path, 64) > 0) - sprintf(aiptek->features.usbPath, "%s/input0", path); - - /* Program the input device coordinate capacities. We do not yet + /* + * Program the input device coordinate capacities. We do not yet * know what maximum X, Y, and Z values are, so we're putting fake * values in. Later, we'll ask the tablet to put in the correct * values. */ - aiptek->inputdev.absmin[ABS_X] = 0; - aiptek->inputdev.absmax[ABS_X] = 2999; - aiptek->inputdev.absmin[ABS_Y] = 0; - aiptek->inputdev.absmax[ABS_Y] = 2249; - aiptek->inputdev.absmin[ABS_PRESSURE] = 0; - aiptek->inputdev.absmax[ABS_PRESSURE] = 511; - aiptek->inputdev.absmin[ABS_TILT_X] = AIPTEK_TILT_MIN; - aiptek->inputdev.absmax[ABS_TILT_X] = AIPTEK_TILT_MAX; - aiptek->inputdev.absmin[ABS_TILT_Y] = AIPTEK_TILT_MIN; - aiptek->inputdev.absmax[ABS_TILT_Y] = AIPTEK_TILT_MAX; - aiptek->inputdev.absmin[ABS_WHEEL] = AIPTEK_WHEEL_MIN; - aiptek->inputdev.absmax[ABS_WHEEL] = AIPTEK_WHEEL_MAX - 1; - aiptek->inputdev.absfuzz[ABS_X] = 0; - aiptek->inputdev.absfuzz[ABS_Y] = 0; - aiptek->inputdev.absfuzz[ABS_PRESSURE] = 0; - aiptek->inputdev.absfuzz[ABS_TILT_X] = 0; - aiptek->inputdev.absfuzz[ABS_TILT_Y] = 0; - aiptek->inputdev.absfuzz[ABS_WHEEL] = 0; - aiptek->inputdev.absflat[ABS_X] = 0; - aiptek->inputdev.absflat[ABS_Y] = 0; - aiptek->inputdev.absflat[ABS_PRESSURE] = 0; - aiptek->inputdev.absflat[ABS_TILT_X] = 0; - aiptek->inputdev.absflat[ABS_TILT_Y] = 0; - aiptek->inputdev.absflat[ABS_WHEEL] = 0; - aiptek->inputdev.name = "Aiptek"; - aiptek->inputdev.phys = aiptek->features.usbPath; - usb_to_input_id(usbdev, &aiptek->inputdev.id); - aiptek->inputdev.dev = &intf->dev; - - aiptek->usbdev = usbdev; - aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber; - aiptek->inDelay = 0; - aiptek->endDelay = 0; - aiptek->previousJitterable = 0; + input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0); + input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0); + input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0); + input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); + input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); + input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0); endpoint = &intf->altsetting[0].endpoint[0].desc; @@ -2150,28 +2124,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->urb->transfer_dma = aiptek->data_dma; aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - /* Register the tablet as an Input Device - */ - input_register_device(&aiptek->inputdev); - - /* We now will look for the evdev device which is mapped to - * the tablet. The partial name is kept in the link list of - * input_handles associated with this input device. - * What identifies an evdev input_handler is that it begins - * with 'event', continues with a digit, and that in turn - * is mapped to /{devfs}/input/eventN. - */ - inputdev = &aiptek->inputdev; - list_for_each_safe(node, next, &inputdev->h_list) { - inputhandle = to_handle(node); - if (strncmp(inputhandle->name, "event", 5) == 0) { - strcpy(aiptek->features.inputPath, inputhandle->name); - break; - } - } - - info("input: Aiptek on %s (%s)\n", path, aiptek->features.inputPath); - /* Program the tablet. This sets the tablet up in the mode * specified in newSetting, and also queries the tablet's * physical capacities. @@ -2186,13 +2138,32 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) { aiptek->curSetting.programmableDelay = speeds[i]; (void)aiptek_program_tablet(aiptek); - if (aiptek->inputdev.absmax[ABS_X] > 0) { + if (aiptek->inputdev->absmax[ABS_X] > 0) { info("input: Aiptek using %d ms programming speed\n", aiptek->curSetting.programmableDelay); break; } } + /* Register the tablet as an Input Device + */ + input_register_device(aiptek->inputdev); + + /* We now will look for the evdev device which is mapped to + * the tablet. The partial name is kept in the link list of + * input_handles associated with this input device. + * What identifies an evdev input_handler is that it begins + * with 'event', continues with a digit, and that in turn + * is mapped to /{devfs}/input/eventN. + */ + list_for_each_safe(node, next, &inputdev->h_list) { + inputhandle = to_handle(node); + if (strncmp(inputhandle->name, "event", 5) == 0) { + strcpy(aiptek->features.inputPath, inputhandle->name); + break; + } + } + /* Associate this driver's struct with the usb interface. */ usb_set_intfdata(intf, aiptek); @@ -2207,6 +2178,12 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) info("aiptek: error loading 'evdev' module"); return 0; + +fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, + aiptek->data_dma); +fail1: input_free_device(inputdev); + kfree(aiptek); + return -ENOMEM; } /* Forward declaration */ @@ -2234,7 +2211,7 @@ static void aiptek_disconnect(struct usb_interface *intf) /* Free & unhook everything from the system. */ usb_kill_urb(aiptek->urb); - input_unregister_device(&aiptek->inputdev); + input_unregister_device(aiptek->inputdev); aiptek_delete_files(&intf->dev); usb_free_urb(aiptek->urb); usb_buffer_free(interface_to_usbdev(intf), diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index e03c1c567a14..15840db092a5 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -39,7 +39,7 @@ #define APPLE_VENDOR_ID 0x05AC #define ATP_DEVICE(prod) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ .idVendor = APPLE_VENDOR_ID, \ @@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, atp_table); * We try to keep the touchpad aspect ratio while still doing only simple * arithmetics. * The factors below give coordinates like: - * 0 <= x < 960 on 12" and 15" Powerbooks - * 0 <= x < 1600 on 17" Powerbooks - * 0 <= y < 646 + * 0 <= x < 960 on 12" and 15" Powerbooks + * 0 <= x < 1600 on 17" Powerbooks + * 0 <= y < 646 */ #define ATP_XFACT 64 #define ATP_YFACT 43 @@ -93,11 +93,12 @@ MODULE_DEVICE_TABLE (usb, atp_table); /* Structure to hold all of our device specific stuff */ struct atp { + char phys[64]; struct usb_device * udev; /* usb device */ struct urb * urb; /* usb request block */ signed char * data; /* transferred data */ int open; /* non-zero if opened */ - struct input_dev input; /* input dev */ + struct input_dev *input; /* input dev */ int valid; /* are the sensors valid ? */ int x_old; /* last reported x/y, */ int y_old; /* used for smoothing */ @@ -114,11 +115,11 @@ struct atp { int i; \ printk("appletouch: %s %lld", msg, (long long)jiffies); \ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \ - printk(" %02x", tab[i]); \ - printk("\n"); \ + printk(" %02x", tab[i]); \ + printk("\n"); \ } -#define dprintk(format, a...) \ +#define dprintk(format, a...) \ do { \ if (debug) printk(format, ##a); \ } while (0) @@ -219,8 +220,8 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) for (i = 16; i < ATP_XSENSORS; i++) if (dev->xy_cur[i]) { printk("appletouch: 17\" model detected.\n"); - input_set_abs_params(&dev->input, ABS_X, 0, - (ATP_XSENSORS - 1) * + input_set_abs_params(dev->input, ABS_X, 0, + (ATP_XSENSORS - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); break; @@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) "Xz: %3d Yz: %3d\n", x, y, x_z, y_z); - input_report_key(&dev->input, BTN_TOUCH, 1); - input_report_abs(&dev->input, ABS_X, x); - input_report_abs(&dev->input, ABS_Y, y); - input_report_abs(&dev->input, ABS_PRESSURE, + input_report_key(dev->input, BTN_TOUCH, 1); + input_report_abs(dev->input, ABS_X, x); + input_report_abs(dev->input, ABS_Y, y); + input_report_abs(dev->input, ABS_PRESSURE, min(ATP_PRESSURE, x_z + y_z)); - atp_report_fingers(&dev->input, max(x_f, y_f)); + atp_report_fingers(dev->input, max(x_f, y_f)); } dev->x_old = x; dev->y_old = y; @@ -273,17 +274,17 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) else if (!x && !y) { dev->x_old = dev->y_old = -1; - input_report_key(&dev->input, BTN_TOUCH, 0); - input_report_abs(&dev->input, ABS_PRESSURE, 0); - atp_report_fingers(&dev->input, 0); + input_report_key(dev->input, BTN_TOUCH, 0); + input_report_abs(dev->input, ABS_PRESSURE, 0); + atp_report_fingers(dev->input, 0); /* reset the accumulator on release */ memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); } - input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]); + input_report_key(dev->input, BTN_LEFT, !!dev->data[80]); - input_sync(&dev->input); + input_sync(dev->input); exit: retval = usb_submit_urb(dev->urb, GFP_ATOMIC); @@ -314,21 +315,14 @@ static void atp_close(struct input_dev *input) static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id) { - struct atp *dev = NULL; + struct atp *dev; + struct input_dev *input_dev; + struct usb_device *udev = interface_to_usbdev(iface); struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int int_in_endpointAddr = 0; int i, retval = -ENOMEM; - /* allocate memory for our device state and initialize it */ - dev = kmalloc(sizeof(struct atp), GFP_KERNEL); - if (dev == NULL) { - err("Out of memory"); - goto err_kmalloc; - } - memset(dev, 0, sizeof(struct atp)); - - dev->udev = interface_to_usbdev(iface); /* set up the endpoint information */ /* use only the first interrupt-in endpoint */ @@ -345,70 +339,82 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id } } if (!int_in_endpointAddr) { - retval = -EIO; err("Could not find int-in endpoint"); - goto err_endpoint; + return -EIO; } - /* save our data pointer in this interface device */ - usb_set_intfdata(iface, dev); + /* allocate memory for our device state and initialize it */ + dev = kzalloc(sizeof(struct atp), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!dev || !input_dev) { + err("Out of memory"); + goto err_free_devs; + } + + dev->udev = udev; + dev->input = input_dev; dev->urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->urb) { retval = -ENOMEM; - goto err_usballoc; + goto err_free_devs; } + dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL, &dev->urb->transfer_dma); if (!dev->data) { retval = -ENOMEM; - goto err_usbbufalloc; + goto err_free_urb; } - usb_fill_int_urb(dev->urb, dev->udev, - usb_rcvintpipe(dev->udev, int_in_endpointAddr), + + usb_fill_int_urb(dev->urb, udev, + usb_rcvintpipe(udev, int_in_endpointAddr), dev->data, ATP_DATASIZE, atp_complete, dev, 1); - init_input_dev(&dev->input); - dev->input.name = "appletouch"; - dev->input.dev = &iface->dev; - dev->input.private = dev; - dev->input.open = atp_open; - dev->input.close = atp_close; + usb_make_path(udev, dev->phys, sizeof(dev->phys)); + strlcat(dev->phys, "/input0", sizeof(dev->phys)); - usb_to_input_id(dev->udev, &dev->input.id); + input_dev->name = "appletouch"; + input_dev->phys = dev->phys; + usb_to_input_id(dev->udev, &input_dev->id); + input_dev->cdev.dev = &iface->dev; - set_bit(EV_ABS, dev->input.evbit); + input_dev->private = dev; + input_dev->open = atp_open; + input_dev->close = atp_close; + + set_bit(EV_ABS, input_dev->evbit); /* * 12" and 15" Powerbooks only have 16 x sensors, * 17" models are detected later. */ - input_set_abs_params(&dev->input, ABS_X, 0, + input_set_abs_params(input_dev, ABS_X, 0, (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); - input_set_abs_params(&dev->input, ABS_Y, 0, + input_set_abs_params(input_dev, ABS_Y, 0, (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0); - input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); - set_bit(EV_KEY, dev->input.evbit); - set_bit(BTN_TOUCH, dev->input.keybit); - set_bit(BTN_TOOL_FINGER, dev->input.keybit); - set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit); - set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit); - set_bit(BTN_LEFT, dev->input.keybit); + set_bit(EV_KEY, input_dev->evbit); + set_bit(BTN_TOUCH, input_dev->keybit); + set_bit(BTN_TOOL_FINGER, input_dev->keybit); + set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); + set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); + set_bit(BTN_LEFT, input_dev->keybit); - input_register_device(&dev->input); + input_register_device(dev->input); - printk(KERN_INFO "input: appletouch connected\n"); + /* save our data pointer in this interface device */ + usb_set_intfdata(iface, dev); return 0; -err_usbbufalloc: + err_free_urb: usb_free_urb(dev->urb); -err_usballoc: + err_free_devs: usb_set_intfdata(iface, NULL); -err_endpoint: kfree(dev); -err_kmalloc: + input_free_device(input_dev); return retval; } @@ -419,7 +425,7 @@ static void atp_disconnect(struct usb_interface *iface) usb_set_intfdata(iface, NULL); if (dev) { usb_kill_urb(dev->urb); - input_unregister_device(&dev->input); + input_unregister_device(dev->input); usb_free_urb(dev->urb); usb_buffer_free(dev->udev, ATP_DATASIZE, dev->data, dev->urb->transfer_dma); diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index fd99681ee483..9a2a47db9494 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -112,7 +112,6 @@ #define NAME_BUFSIZE 80 /* size of product name, path buffers */ #define DATA_BUFSIZE 63 /* size of URB data buffers */ -#define ATI_INPUTNUM 1 /* Which input device to register as */ static unsigned long channel_mask; module_param(channel_mask, ulong, 0444); @@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; static DECLARE_MUTEX(disconnect_sem); struct ati_remote { - struct input_dev idev; + struct input_dev *idev; struct usb_device *udev; struct usb_interface *interface; @@ -198,15 +197,13 @@ struct ati_remote { #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ /* Translation table from hardware messages to input events. */ -static struct -{ +static struct { short kind; unsigned char data1, data2; int type; unsigned int code; int value; -} ati_remote_tbl[] = -{ +} ati_remote_tbl[] = { /* Directional control pad axes */ {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ @@ -286,7 +283,6 @@ static struct /* Local function prototypes */ static void ati_remote_dump (unsigned char *data, unsigned int actual_length); -static void ati_remote_delete (struct ati_remote *dev); static int ati_remote_open (struct input_dev *inputdev); static void ati_remote_close (struct input_dev *inputdev); static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); @@ -428,7 +424,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) { struct ati_remote *ati_remote = urb->context; unsigned char *data= ati_remote->inbuf; - struct input_dev *dev = &ati_remote->idev; + struct input_dev *dev = ati_remote->idev; int index, acc; int remote_num; @@ -587,17 +583,42 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) } /* - * ati_remote_delete + * ati_remote_alloc_buffers */ -static void ati_remote_delete(struct ati_remote *ati_remote) +static int ati_remote_alloc_buffers(struct usb_device *udev, + struct ati_remote *ati_remote) +{ + ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, + &ati_remote->inbuf_dma); + if (!ati_remote->inbuf) + return -1; + + ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, + &ati_remote->outbuf_dma); + if (!ati_remote->outbuf) + return -1; + + ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ati_remote->irq_urb) + return -1; + + ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ati_remote->out_urb) + return -1; + + return 0; +} + +/* + * ati_remote_free_buffers + */ +static void ati_remote_free_buffers(struct ati_remote *ati_remote) { if (ati_remote->irq_urb) - usb_kill_urb(ati_remote->irq_urb); + usb_free_urb(ati_remote->irq_urb); if (ati_remote->out_urb) - usb_kill_urb(ati_remote->out_urb); - - input_unregister_device(&ati_remote->idev); + usb_free_urb(ati_remote->out_urb); if (ati_remote->inbuf) usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, @@ -605,20 +626,12 @@ static void ati_remote_delete(struct ati_remote *ati_remote) if (ati_remote->outbuf) usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->outbuf, ati_remote->outbuf_dma); - - if (ati_remote->irq_urb) - usb_free_urb(ati_remote->irq_urb); - - if (ati_remote->out_urb) - usb_free_urb(ati_remote->out_urb); - - kfree(ati_remote); + ati_remote->inbuf, ati_remote->outbuf_dma); } static void ati_remote_input_init(struct ati_remote *ati_remote) { - struct input_dev *idev = &(ati_remote->idev); + struct input_dev *idev = ati_remote->idev; int i; idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); @@ -637,7 +650,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) idev->phys = ati_remote->phys; usb_to_input_id(ati_remote->udev, &idev->id); - idev->dev = &ati_remote->udev->dev; + idev->cdev.dev = &ati_remote->udev->dev; } static int ati_remote_initialize(struct ati_remote *ati_remote) @@ -674,7 +687,7 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { dev_err(&ati_remote->interface->dev, "Initializing ati_remote hardware failed.\n"); - return 1; + return -EIO; } return 0; @@ -686,95 +699,83 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); - struct ati_remote *ati_remote = NULL; - struct usb_host_interface *iface_host; - int retval = -ENOMEM; - char path[64]; + struct usb_host_interface *iface_host = interface->cur_altsetting; + struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; + struct ati_remote *ati_remote; + struct input_dev *input_dev; + int err = -ENOMEM; - /* Allocate and clear an ati_remote struct */ - if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL))) - return -ENOMEM; - memset(ati_remote, 0x00, sizeof (struct ati_remote)); - - iface_host = interface->cur_altsetting; if (iface_host->desc.bNumEndpoints != 2) { err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); - retval = -ENODEV; - goto error; + return -ENODEV; } - ati_remote->endpoint_in = &(iface_host->endpoint[0].desc); - ati_remote->endpoint_out = &(iface_host->endpoint[1].desc); - ati_remote->udev = udev; - ati_remote->interface = interface; + endpoint_in = &iface_host->endpoint[0].desc; + endpoint_out = &iface_host->endpoint[1].desc; - if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) { + if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) { err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__); - retval = -ENODEV; - goto error; + return -ENODEV; } - if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) { + if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__); - retval = -ENODEV; - goto error; + return -ENODEV; } - if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) { + if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { err("%s: endpoint_in message size==0? \n", __FUNCTION__); - retval = -ENODEV; - goto error; + return -ENODEV; } + ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ati_remote || !input_dev) + goto fail1; + /* Allocate URB buffers, URBs */ - ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, - &ati_remote->inbuf_dma); - if (!ati_remote->inbuf) - goto error; + if (ati_remote_alloc_buffers(udev, ati_remote)) + goto fail2; - ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, - &ati_remote->outbuf_dma); - if (!ati_remote->outbuf) - goto error; + ati_remote->endpoint_in = endpoint_in; + ati_remote->endpoint_out = endpoint_out; + ati_remote->udev = udev; + ati_remote->idev = input_dev; + ati_remote->interface = interface; - ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ati_remote->irq_urb) - goto error; + usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); + strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); - ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ati_remote->out_urb) - goto error; - - usb_make_path(udev, path, NAME_BUFSIZE); - sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM); if (udev->manufacturer) - strcat(ati_remote->name, udev->manufacturer); + strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); if (udev->product) - sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product); + snprintf(ati_remote->name, sizeof(ati_remote->name), + "%s %s", ati_remote->name, udev->product); if (!strlen(ati_remote->name)) - sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)", + snprintf(ati_remote->name, sizeof(ati_remote->name), + DRIVER_DESC "(%04x,%04x)", le16_to_cpu(ati_remote->udev->descriptor.idVendor), le16_to_cpu(ati_remote->udev->descriptor.idProduct)); + ati_remote_input_init(ati_remote); + /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ - retval = ati_remote_initialize(ati_remote); - if (retval) - goto error; + err = ati_remote_initialize(ati_remote); + if (err) + goto fail3; /* Set up and register input device */ - ati_remote_input_init(ati_remote); - input_register_device(&ati_remote->idev); - - dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n", - ati_remote->name, path); + input_register_device(ati_remote->idev); usb_set_intfdata(interface, ati_remote); + return 0; -error: - if (retval) - ati_remote_delete(ati_remote); - - return retval; +fail3: usb_kill_urb(ati_remote->irq_urb); + usb_kill_urb(ati_remote->out_urb); +fail2: ati_remote_free_buffers(ati_remote); +fail1: input_free_device(input_dev); + kfree(ati_remote); + return err; } /* @@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct usb_interface *interface) return; } - ati_remote_delete(ati_remote); + usb_kill_urb(ati_remote->irq_urb); + usb_kill_urb(ati_remote->out_urb); + input_unregister_device(ati_remote->idev); + ati_remote_free_buffers(ati_remote); + kfree(ati_remote); } /* diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 41f92b924761..411a0645a7a3 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) struct hid_descriptor *hdesc; struct hid_device *hid; unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n, insize = 0; + char *rdesc; + int n, len, insize = 0; for (n = 0; hid_blacklist[n].idVendor; n++) if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && @@ -1630,10 +1630,11 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (quirks & HID_QUIRK_IGNORE) return NULL; - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && + (!interface->desc.bNumEndpoints || + usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { + dbg("class descriptor not present\n"); + return NULL; } for (n = 0; n < hdesc->bNumDescriptors; n++) @@ -1749,32 +1750,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->name[0] = 0; - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; + if (dev->manufacturer) + strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); - if (dev->manufacturer) { - strcat(hid->name, dev->manufacturer); - if (dev->product) - snprintf(hid->name, 64, "%s %s", hid->name, dev->product); - } else if (dev->product) { - snprintf(hid->name, 128, "%s", dev->product); - } else - snprintf(hid->name, 128, "%04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); + if (dev->product) { + if (dev->manufacturer) + strlcat(hid->name, " ", sizeof(hid->name)); + strlcat(hid->name, dev->product, sizeof(hid->name)); + } - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); + if (!strlen(hid->name)) + snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + usb_make_path(dev, hid->phys, sizeof(hid->phys)); + strlcat(hid->phys, "/input", sizeof(hid->phys)); + len = strlen(hid->phys); + if (len < sizeof(hid->phys) - 1) + snprintf(hid->phys + len, sizeof(hid->phys) - len, + "%d", intf->altsetting[0].desc.bInterfaceNumber); if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; - kfree(buf); - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); if (!hid->urbctrl) goto fail; + usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, hid->ctrlbuf, 1, hid_ctrl, hid); hid->urbctrl->setup_dma = hid->cr_dma; diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 0b6452248a39..9ff25eb520a6 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -76,8 +76,8 @@ static struct { static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { - struct input_dev *input = &hidinput->input; - struct hid_device *device = hidinput->input.private; + struct input_dev *input = hidinput->input; + struct hid_device *device = input->private; int max = 0, code; unsigned long *bit = NULL; @@ -461,7 +461,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct if (!field->hidinput) return; - input = &field->hidinput->input; + + input = field->hidinput->input; input_regs(input, regs); @@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { - struct list_head *lh; struct hid_input *hidinput; - list_for_each (lh, &hid->inputs) { - hidinput = list_entry(lh, struct hid_input, list); - input_sync(&hidinput->input); - } + list_for_each_entry(hidinput, &hid->inputs, list) + input_sync(hidinput->input); } static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) @@ -604,6 +602,7 @@ int hidinput_connect(struct hid_device *hid) struct usb_device *dev = hid->dev; struct hid_report *report; struct hid_input *hidinput = NULL; + struct input_dev *input_dev; int i, j, k; INIT_LIST_HEAD(&hid->inputs); @@ -624,25 +623,28 @@ int hidinput_connect(struct hid_device *hid) continue; if (!hidinput) { - hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL); - if (!hidinput) { + hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!hidinput || !input_dev) { + kfree(hidinput); + input_free_device(input_dev); err("Out of memory during hid input probe"); return -1; } - memset(hidinput, 0, sizeof(*hidinput)); + input_dev->private = hid; + input_dev->event = hidinput_input_event; + input_dev->open = hidinput_open; + input_dev->close = hidinput_close; + + input_dev->name = hid->name; + input_dev->phys = hid->phys; + input_dev->uniq = hid->uniq; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &hid->intf->dev; + + hidinput->input = input_dev; list_add_tail(&hidinput->list, &hid->inputs); - - hidinput->input.private = hid; - hidinput->input.event = hidinput_input_event; - hidinput->input.open = hidinput_open; - hidinput->input.close = hidinput_close; - - hidinput->input.name = hid->name; - hidinput->input.phys = hid->phys; - hidinput->input.uniq = hid->uniq; - usb_to_input_id(dev, &hidinput->input.id); - hidinput->input.dev = &hid->intf->dev; } for (i = 0; i < report->maxfield; i++) @@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *hid) * UGCI) cram a lot of unrelated inputs into the * same interface. */ hidinput->report = report; - input_register_device(&hidinput->input); + input_register_device(hidinput->input); hidinput = NULL; } } @@ -667,7 +669,7 @@ int hidinput_connect(struct hid_device *hid) * only useful in this case, and not for multi-input quirks. */ if (hidinput) { hid_ff_init(hid); - input_register_device(&hidinput->input); + input_register_device(hidinput->input); } return 0; @@ -675,13 +677,11 @@ int hidinput_connect(struct hid_device *hid) void hidinput_disconnect(struct hid_device *hid) { - struct list_head *lh, *next; - struct hid_input *hidinput; + struct hid_input *hidinput, *next; - list_for_each_safe(lh, next, &hid->inputs) { - hidinput = list_entry(lh, struct hid_input, list); - input_unregister_device(&hidinput->input); + list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { list_del(&hidinput->list); + input_unregister_device(hidinput->input); kfree(hidinput); } } diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index 0c4c77aa31ea..f82c9c9e5d51 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c @@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct hid_device* hid) u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor); u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct); struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); + struct input_dev *input_dev = hidinput->input; while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct)) dev++; - ff = dev->ff; + for (ff = dev->ff; *ff >= 0; ff++) + set_bit(*ff, input_dev->ffbit); - while (*ff >= 0) { - set_bit(*ff, hidinput->input.ffbit); - ++ff; - } + input_dev->upload_effect = hid_lgff_upload_effect; + input_dev->flush = hid_lgff_flush; - hidinput->input.upload_effect = hid_lgff_upload_effect; - hidinput->input.flush = hid_lgff_flush; - - set_bit(EV_FF, hidinput->input.evbit); - hidinput->input.ff_effects_max = LGFF_EFFECTS; + set_bit(EV_FF, input_dev->evbit); + input_dev->ff_effects_max = LGFF_EFFECTS; } static void hid_lgff_exit(struct hid_device* hid) diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c index 8f6a0a6f94a9..023fd5ac31c8 100644 --- a/drivers/usb/input/hid-tmff.c +++ b/drivers/usb/input/hid-tmff.c @@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid) struct tmff_device *private; struct list_head *pos; struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); + struct input_dev *input_dev = hidinput->input; private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL); if (!private) @@ -155,7 +156,7 @@ int hid_tmff_init(struct hid_device *hid) private->report = report; private->rumble = field; - set_bit(FF_RUMBLE, hidinput->input.ffbit); + set_bit(FF_RUMBLE, input_dev->ffbit); break; default: @@ -164,11 +165,11 @@ int hid_tmff_init(struct hid_device *hid) } /* Fallthrough to here only when a valid usage is found */ - hidinput->input.upload_effect = hid_tmff_upload_effect; - hidinput->input.flush = hid_tmff_flush; + input_dev->upload_effect = hid_tmff_upload_effect; + input_dev->flush = hid_tmff_flush; - set_bit(EV_FF, hidinput->input.evbit); - hidinput->input.ff_effects_max = TMFF_EFFECTS; + set_bit(EV_FF, input_dev->evbit); + input_dev->ff_effects_max = TMFF_EFFECTS; } } diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index ec2412c42f1e..ee48a2276104 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -371,7 +371,7 @@ struct hid_control_fifo { struct hid_input { struct list_head list; struct hid_report *report; - struct input_dev input; + struct input_dev *input; }; struct hid_device { /* device report descriptor */ diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index becb87efb869..3b581853cf10 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c @@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE ); struct itmtouch_dev { struct usb_device *usbdev; /* usb device */ - struct input_dev inputdev; /* input device */ + struct input_dev *inputdev; /* input device */ struct urb *readurb; /* urb */ char rbuf[ITM_BUFSIZE]; /* data */ int users; @@ -88,9 +88,9 @@ static struct usb_device_id itmtouch_ids [] = { static void itmtouch_irq(struct urb *urb, struct pt_regs *regs) { - struct itmtouch_dev * itmtouch = urb->context; + struct itmtouch_dev *itmtouch = urb->context; unsigned char *data = urb->transfer_buffer; - struct input_dev *dev = &itmtouch->inputdev; + struct input_dev *dev = itmtouch->inputdev; int retval; switch (urb->status) { @@ -156,49 +156,62 @@ static void itmtouch_close(struct input_dev *input) static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct itmtouch_dev *itmtouch; + struct input_dev *input_dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); unsigned int pipe; unsigned int maxp; - char path[PATH_SIZE]; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - if (!(itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL))) { + itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!itmtouch || !input_dev) { err("%s - Out of memory.", __FUNCTION__); - return -ENOMEM; + goto fail; } itmtouch->usbdev = udev; + itmtouch->inputdev = input_dev; - itmtouch->inputdev.private = itmtouch; - itmtouch->inputdev.open = itmtouch_open; - itmtouch->inputdev.close = itmtouch_close; + if (udev->manufacturer) + strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name)); - usb_make_path(udev, path, PATH_SIZE); - - itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - itmtouch->inputdev.name = itmtouch->name; - itmtouch->inputdev.phys = itmtouch->phys; - usb_to_input_id(udev, &itmtouch->inputdev.id); - itmtouch->inputdev.dev = &intf->dev; + if (udev->product) { + if (udev->manufacturer) + strlcat(itmtouch->name, " ", sizeof(itmtouch->name)); + strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name)); + } if (!strlen(itmtouch->name)) sprintf(itmtouch->name, "USB ITM touchscreen"); + usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys)); + strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys)); + + input_dev->name = itmtouch->name; + input_dev->phys = itmtouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = itmtouch; + + input_dev->open = itmtouch_open; + input_dev->close = itmtouch_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + /* device limits */ /* as specified by the ITM datasheet, X and Y are 12bit, * Z (pressure) is 8 bit. However, the fields are defined up * to 14 bits for future possible expansion. */ - input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0); - input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0); - input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0); + input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0); /* initialise the URB so we can read from the transport stream */ pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); @@ -208,22 +221,23 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id maxp = ITM_BUFSIZE; itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); - if (!itmtouch->readurb) { dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); - kfree(itmtouch); - return -ENOMEM; + goto fail; } usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf, maxp, itmtouch_irq, itmtouch, endpoint->bInterval); - input_register_device(&itmtouch->inputdev); + input_register_device(itmtouch->inputdev); - printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path); usb_set_intfdata(intf, itmtouch); return 0; + + fail: input_free_device(input_dev); + kfree(itmtouch); + return -ENOMEM; } static void itmtouch_disconnect(struct usb_interface *intf) @@ -233,7 +247,7 @@ static void itmtouch_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (itmtouch) { - input_unregister_device(&itmtouch->inputdev); + input_unregister_device(itmtouch->inputdev); usb_kill_urb(itmtouch->readurb); usb_free_urb(itmtouch->readurb); kfree(itmtouch); diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index b6f6ac8d9c2f..a248664b5d1d 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks"); struct kbtab { signed char *data; dma_addr_t data_dma; - struct input_dev dev; + struct input_dev *dev; struct usb_device *usbdev; struct urb *irq; int x, y; @@ -48,7 +48,7 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs) { struct kbtab *kbtab = urb->context; unsigned char *data = kbtab->data; - struct input_dev *dev = &kbtab->dev; + struct input_dev *dev = kbtab->dev; int retval; switch (urb->status) { @@ -124,53 +124,43 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct kbtab *kbtab; - char path[64]; + struct input_dev *input_dev; - if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL))) - return -ENOMEM; - memset(kbtab, 0, sizeof(struct kbtab)); + kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!kbtab || !input_dev) + goto fail1; kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma); - if (!kbtab->data) { - kfree(kbtab); - return -ENOMEM; - } + if (!kbtab->data) + goto fail1; kbtab->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!kbtab->irq) { - usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); - kfree(kbtab); - return -ENOMEM; - } + if (!kbtab->irq) + goto fail2; - kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); - kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - - kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - - kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); - - kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL); - - kbtab->dev.absmax[ABS_X] = 0x2000; - kbtab->dev.absmax[ABS_Y] = 0x1750; - kbtab->dev.absmax[ABS_PRESSURE] = 0xff; - - kbtab->dev.absfuzz[ABS_X] = 4; - kbtab->dev.absfuzz[ABS_Y] = 4; - - kbtab->dev.private = kbtab; - kbtab->dev.open = kbtab_open; - kbtab->dev.close = kbtab_close; - - usb_make_path(dev, path, 64); - sprintf(kbtab->phys, "%s/input0", path); - - kbtab->dev.name = "KB Gear Tablet"; - kbtab->dev.phys = kbtab->phys; - usb_to_input_id(dev, &kbtab->dev.id); - kbtab->dev.dev = &intf->dev; kbtab->usbdev = dev; + kbtab->dev = input_dev; + + usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys)); + strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys)); + + input_dev->name = "KB Gear Tablet"; + input_dev->phys = kbtab->phys; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = kbtab; + + input_dev->open = kbtab_open; + input_dev->close = kbtab_close; + + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); + input_dev->mscbit[0] |= BIT(MSC_SERIAL); + input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); + input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); endpoint = &intf->cur_altsetting->endpoint[0].desc; @@ -181,23 +171,25 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i kbtab->irq->transfer_dma = kbtab->data_dma; kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(&kbtab->dev); - - printk(KERN_INFO "input: KB Gear Tablet on %s\n", path); + input_register_device(kbtab->dev); usb_set_intfdata(intf, kbtab); - return 0; + +fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); +fail1: input_free_device(input_dev); + kfree(kbtab); + return -ENOMEM; } static void kbtab_disconnect(struct usb_interface *intf) { - struct kbtab *kbtab = usb_get_intfdata (intf); + struct kbtab *kbtab = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); if (kbtab) { usb_kill_urb(kbtab->irq); - input_unregister_device(&kbtab->dev); + input_unregister_device(kbtab->dev); usb_free_urb(kbtab->irq); usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma); kfree(kbtab); diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index 99de1b33c07d..5b8d65f62abf 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_VERSION "v0.1" #define DRIVER_AUTHOR "Michael Downey " @@ -75,7 +76,7 @@ struct usb_keyspan { char name[128]; char phys[64]; struct usb_device* udev; - struct input_dev input; + struct input_dev *input; struct usb_interface* interface; struct usb_endpoint_descriptor* in_endpoint; struct urb* irq_urb; @@ -136,12 +137,11 @@ static struct usb_driver keyspan_driver; */ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/ { - char codes[4*RECV_SIZE]; + char codes[4 * RECV_SIZE]; int i; - for (i = 0; i < RECV_SIZE; i++) { - snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]); - } + for (i = 0; i < RECV_SIZE; i++) + snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]); dev_info(&dev->udev->dev, "%s\n", codes); } @@ -153,7 +153,7 @@ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) { if (dev->data.bits_left >= bits_needed) - return(0); + return 0; /* * Somehow we've missed the last message. The message will be repeated @@ -162,7 +162,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) if (dev->data.pos >= dev->data.len) { dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n", __FUNCTION__, dev->data.pos, dev->data.len); - return(-1); + return -1; } /* Load as much as we can into the tester. */ @@ -172,7 +172,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) dev->data.bits_left += 8; } - return(0); + return 0; } /* @@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) __FUNCTION__, message.system, message.button, message.toggle); if (message.toggle != remote->toggle) { - input_regs(&remote->input, regs); - input_report_key(&remote->input, keyspan_key_table[message.button], 1); - input_report_key(&remote->input, keyspan_key_table[message.button], 0); - input_sync(&remote->input); + input_regs(remote->input, regs); + input_report_key(remote->input, keyspan_key_table[message.button], 1); + input_report_key(remote->input, keyspan_key_table[message.button], 0); + input_sync(remote->input); remote->toggle = message.toggle; } @@ -397,14 +397,9 @@ static int keyspan_open(struct input_dev *dev) { struct usb_keyspan *remote = dev->private; - if (remote->open++) - return 0; - remote->irq_urb->dev = remote->udev; - if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) { - remote->open--; + if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) return -EIO; - } return 0; } @@ -413,8 +408,26 @@ static void keyspan_close(struct input_dev *dev) { struct usb_keyspan *remote = dev->private; - if (!--remote->open) - usb_kill_urb(remote->irq_urb); + usb_kill_urb(remote->irq_urb); +} + +static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface) +{ + + struct usb_endpoint_descriptor *endpoint; + int i; + + for (i = 0; i < iface->desc.bNumEndpoints; ++i) { + endpoint = &iface->endpoint[i].desc; + + if ((endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { + /* we found our interrupt in endpoint */ + return endpoint; + } + } + + return NULL; } /* @@ -422,110 +435,78 @@ static void keyspan_close(struct input_dev *dev) */ static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id) { - int i; - int retval = -ENOMEM; - char path[64]; - char *buf; - struct usb_keyspan *remote = NULL; - struct usb_host_interface *iface_desc; + struct usb_device *udev = interface_to_usbdev(interface); struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); + struct usb_keyspan *remote; + struct input_dev *input_dev; + int i, retval; - /* allocate memory for our device state and initialize it */ - remote = kmalloc(sizeof(*remote), GFP_KERNEL); - if (remote == NULL) { - err("Out of memory\n"); - goto error; + endpoint = keyspan_get_in_endpoint(interface->cur_altsetting); + if (!endpoint) + return -ENODEV; + + remote = kzalloc(sizeof(*remote), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!remote || !input_dev) { + retval = -ENOMEM; + goto fail1; } - memset(remote, 0x00, sizeof(*remote)); remote->udev = udev; + remote->input = input_dev; remote->interface = interface; + remote->in_endpoint = endpoint; remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ - /* set up the endpoint information */ - /* use only the first in interrupt endpoint */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - - if (!remote->in_endpoint && - (endpoint->bEndpointAddress & USB_DIR_IN) && - ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { - /* we found our interrupt in endpoint */ - remote->in_endpoint = endpoint; - - remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma); - if (!remote->in_buffer) { - retval = -ENOMEM; - goto error; - } - } - } - - if (!remote->in_endpoint) { - err("Could not find interrupt input endpoint.\n"); - retval = -ENODEV; - goto error; + remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma); + if (!remote->in_buffer) { + retval = -ENOMEM; + goto fail1; } remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if (!remote->irq_urb) { - err("Failed to allocate urb.\n"); retval = -ENOMEM; - goto error; + goto fail2; } - retval = keyspan_setup(remote->udev); + retval = keyspan_setup(udev); if (retval) { - err("Failed to setup device.\n"); retval = -ENODEV; - goto error; + goto fail3; } - /* - * Setup the input system with the bits we are going to be reporting - */ - remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ - for (i = 0; i < 32; ++i) { - if (keyspan_key_table[i] != KEY_RESERVED) { - set_bit(keyspan_key_table[i], remote->input.keybit); - } + if (udev->manufacturer) + strlcpy(remote->name, udev->manufacturer, sizeof(remote->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(remote->name, " ", sizeof(remote->name)); + strlcat(remote->name, udev->product, sizeof(remote->name)); } - remote->input.private = remote; - remote->input.open = keyspan_open; - remote->input.close = keyspan_close; - - usb_make_path(remote->udev, path, 64); - sprintf(remote->phys, "%s/input0", path); - - remote->input.name = remote->name; - remote->input.phys = remote->phys; - remote->input.id.bustype = BUS_USB; - remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor); - remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct); - remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice); - - if (!(buf = kmalloc(63, GFP_KERNEL))) { - usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); - kfree(remote); - return -ENOMEM; - } - - if (remote->udev->descriptor.iManufacturer && - usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0) - strcat(remote->name, buf); - - if (remote->udev->descriptor.iProduct && - usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0) - sprintf(remote->name, "%s %s", remote->name, buf); - if (!strlen(remote->name)) - sprintf(remote->name, "USB Keyspan Remote %04x:%04x", - remote->input.id.vendor, remote->input.id.product); + snprintf(remote->name, sizeof(remote->name), + "USB Keyspan Remote %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); - kfree(buf); + usb_make_path(udev, remote->phys, sizeof(remote->phys)); + strlcat(remote->phys, "/input0", sizeof(remote->phys)); + + input_dev->name = remote->name; + input_dev->phys = remote->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &interface->dev; + + input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ + for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) + if (keyspan_key_table[i] != KEY_RESERVED) + set_bit(keyspan_key_table[i], input_dev->keybit); + + input_dev->private = remote; + input_dev->open = keyspan_open; + input_dev->close = keyspan_close; /* * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() @@ -538,27 +519,17 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* we can register the device now, as it is ready */ - input_register_device(&remote->input); + input_register_device(remote->input); /* save our data pointer in this interface device */ usb_set_intfdata(interface, remote); - /* let the user know what node this device is now attached to */ - info("connected: %s on %s", remote->name, path); return 0; -error: - /* - * In case of error we need to clean up any allocated buffers - */ - if (remote->irq_urb) - usb_free_urb(remote->irq_urb); - - if (remote->in_buffer) - usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); - - if (remote) - kfree(remote); + fail3: usb_free_urb(remote->irq_urb); + fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma); + fail1: kfree(remote); + input_free_device(input_dev); return retval; } @@ -570,23 +541,16 @@ static void keyspan_disconnect(struct usb_interface *interface) { struct usb_keyspan *remote; - /* prevent keyspan_open() from racing keyspan_disconnect() */ - lock_kernel(); - remote = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); if (remote) { /* We have a valid driver structure so clean up everything we allocated. */ - input_unregister_device(&remote->input); + input_unregister_device(remote->input); usb_kill_urb(remote->irq_urb); usb_free_urb(remote->irq_urb); - usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma); + usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); kfree(remote); } - - unlock_kernel(); - - info("USB Keyspan now disconnected"); } /* diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index ff9275057a18..7fce526560ca 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c @@ -98,7 +98,7 @@ struct mtouch_usb { dma_addr_t data_dma; struct urb *irq; struct usb_device *udev; - struct input_dev input; + struct input_dev *input; char name[128]; char phys[64]; }; @@ -135,14 +135,14 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs) goto exit; } - input_regs(&mtouch->input, regs); - input_report_key(&mtouch->input, BTN_TOUCH, + input_regs(mtouch->input, regs); + input_report_key(mtouch->input, BTN_TOUCH, MTOUCHUSB_GET_TOUCHED(mtouch->data)); - input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); - input_report_abs(&mtouch->input, ABS_Y, + input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); + input_report_abs(mtouch->input, ABS_Y, (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) - MTOUCHUSB_GET_YC(mtouch->data)); - input_sync(&mtouch->input); + input_sync(mtouch->input); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -195,10 +195,10 @@ static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *m static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct mtouch_usb *mtouch; + struct input_dev *input_dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); - char path[64]; int nRet; dbg("%s - called", __FUNCTION__); @@ -209,57 +209,55 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i dbg("%s - setting endpoint", __FUNCTION__); endpoint = &interface->endpoint[0].desc; - if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) { + mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mtouch || !input_dev) { err("%s - Out of memory.", __FUNCTION__); - return -ENOMEM; + goto fail1; } - memset(mtouch, 0, sizeof(struct mtouch_usb)); - mtouch->udev = udev; - dbg("%s - allocating buffers", __FUNCTION__); - if (mtouchusb_alloc_buffers(udev, mtouch)) { - mtouchusb_free_buffers(udev, mtouch); - kfree(mtouch); - return -ENOMEM; - } + if (mtouchusb_alloc_buffers(udev, mtouch)) + goto fail2; - mtouch->input.private = mtouch; - mtouch->input.open = mtouchusb_open; - mtouch->input.close = mtouchusb_close; - - usb_make_path(udev, path, 64); - sprintf(mtouch->phys, "%s/input0", path); - - mtouch->input.name = mtouch->name; - mtouch->input.phys = mtouch->phys; - usb_to_input_id(udev, &mtouch->input.id); - mtouch->input.dev = &intf->dev; - - mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - /* Used to Scale Compensated Data and Flip Y */ - mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC; - mtouch->input.absmax[ABS_X] = raw_coordinates ? - MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC; - mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ; - mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT; - mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC; - mtouch->input.absmax[ABS_Y] = raw_coordinates ? - MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC; - mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ; - mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT; + mtouch->udev = udev; + mtouch->input = input_dev; if (udev->manufacturer) - strcat(mtouch->name, udev->manufacturer); - if (udev->product) - sprintf(mtouch->name, "%s %s", mtouch->name, udev->product); + strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(mtouch->name, " ", sizeof(mtouch->name)); + strlcat(mtouch->name, udev->product, sizeof(mtouch->name)); + } if (!strlen(mtouch->name)) - sprintf(mtouch->name, "USB Touchscreen %04x:%04x", - mtouch->input.id.vendor, mtouch->input.id.product); + snprintf(mtouch->name, sizeof(mtouch->name), + "USB Touchscreen %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys)); + strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys)); + + input_dev->name = mtouch->name; + input_dev->phys = mtouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = mtouch; + + input_dev->open = mtouchusb_open; + input_dev->close = mtouchusb_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC, + raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC, + MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT); + input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC, + raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC, + MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT); nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), MTOUCHUSB_RESET, @@ -272,9 +270,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); if (!mtouch->irq) { dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); - mtouchusb_free_buffers(udev, mtouch); - kfree(mtouch); - return -ENOMEM; + goto fail2; } dbg("%s - usb_fill_int_urb", __FUNCTION__); @@ -284,7 +280,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i mtouchusb_irq, mtouch, endpoint->bInterval); dbg("%s - input_register_device", __FUNCTION__); - input_register_device(&mtouch->input); + input_register_device(mtouch->input); nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), MTOUCHUSB_ASYNC_REPORT, @@ -293,10 +289,13 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", __FUNCTION__, nRet); - printk(KERN_INFO "input: %s on %s\n", mtouch->name, path); usb_set_intfdata(intf, mtouch); - return 0; + +fail2: mtouchusb_free_buffers(udev, mtouch); +fail1: input_free_device(input_dev); + kfree(mtouch); + return -ENOMEM; } static void mtouchusb_disconnect(struct usb_interface *intf) @@ -308,7 +307,7 @@ static void mtouchusb_disconnect(struct usb_interface *intf) if (mtouch) { dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); usb_kill_urb(mtouch->irq); - input_unregister_device(&mtouch->input); + input_unregister_device(mtouch->input); usb_free_urb(mtouch->irq); mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); kfree(mtouch); diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c index acc71ec560e9..a00672c96644 100644 --- a/drivers/usb/input/pid.c +++ b/drivers/usb/input/pid.c @@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid) { struct hid_ff_pid *private; struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list); + struct input_dev *input_dev = hidinput->input; private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); if (!private) @@ -281,11 +282,12 @@ int hid_pid_init(struct hid_device *hid) usb_fill_control_urb(private->urbffout, hid->dev, 0, (void *)&private->ffcr, private->ctrl_buffer, 8, hid_pid_ctrl_out, hid); - hidinput->input.upload_effect = hid_pid_upload_effect; - hidinput->input.flush = hid_pid_flush; - hidinput->input.ff_effects_max = 8; // A random default - set_bit(EV_FF, hidinput->input.evbit); - set_bit(EV_FF_STATUS, hidinput->input.evbit); + + input_dev->upload_effect = hid_pid_upload_effect; + input_dev->flush = hid_pid_flush; + input_dev->ff_effects_max = 8; // A random default + set_bit(EV_FF, input_dev->evbit); + set_bit(EV_FF_STATUS, input_dev->evbit); spin_lock_init(&private->lock); diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index ad4afe7e5897..b7476233ef5d 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -68,7 +68,7 @@ struct powermate_device { struct usb_ctrlrequest *configcr; dma_addr_t configcr_dma; struct usb_device *udev; - struct input_dev input; + struct input_dev *input; spinlock_t lock; int static_brightness; int pulse_speed; @@ -106,10 +106,10 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs) } /* handle updates to device state */ - input_regs(&pm->input, regs); - input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01); - input_report_rel(&pm->input, REL_DIAL, pm->data[1]); - input_sync(&pm->input); + input_regs(pm->input, regs); + input_report_key(pm->input, BTN_0, pm->data[0] & 0x01); + input_report_rel(pm->input, REL_DIAL, pm->data[1]); + input_sync(pm->input); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); @@ -153,10 +153,10 @@ static void powermate_sync_state(struct powermate_device *pm) Only values of 'arg' quite close to 255 are particularly useful/spectacular. */ - if (pm->pulse_speed < 255){ + if (pm->pulse_speed < 255) { op = 0; // divide arg = 255 - pm->pulse_speed; - } else if (pm->pulse_speed > 255){ + } else if (pm->pulse_speed > 255) { op = 2; // multiply arg = pm->pulse_speed - 255; } else { @@ -166,11 +166,11 @@ static void powermate_sync_state(struct powermate_device *pm) pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE ); pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op ); pm->requires_update &= ~UPDATE_PULSE_MODE; - }else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){ + } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) { pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; - }else{ + } else { printk(KERN_ERR "powermate: unknown update required"); pm->requires_update = 0; /* fudge the bug */ return; @@ -228,19 +228,19 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne spin_lock_irqsave(&pm->lock, flags); /* mark state updates which are required */ - if (static_brightness != pm->static_brightness){ + if (static_brightness != pm->static_brightness) { pm->static_brightness = static_brightness; pm->requires_update |= UPDATE_STATIC_BRIGHTNESS; } - if (pulse_asleep != pm->pulse_asleep){ + if (pulse_asleep != pm->pulse_asleep) { pm->pulse_asleep = pulse_asleep; pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS); } - if (pulse_awake != pm->pulse_awake){ + if (pulse_awake != pm->pulse_awake) { pm->pulse_awake = pulse_awake; pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS); } - if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){ + if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) { pm->pulse_speed = pulse_speed; pm->pulse_table = pulse_table; pm->requires_update |= UPDATE_PULSE_MODE; @@ -283,6 +283,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev SLAB_ATOMIC, &pm->data_dma); if (!pm->data) return -1; + pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)), SLAB_ATOMIC, &pm->configcr_dma); if (!pm->configcr) @@ -308,8 +309,9 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct powermate_device *pm; + struct input_dev *input_dev; int pipe, maxp; - char path[64]; + int err = -ENOMEM; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; @@ -323,42 +325,61 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i 0, interface->desc.bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL))) - return -ENOMEM; + pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!pm || !input_dev) + goto fail1; - memset(pm, 0, sizeof(struct powermate_device)); - pm->udev = udev; - - if (powermate_alloc_buffers(udev, pm)) { - powermate_free_buffers(udev, pm); - kfree(pm); - return -ENOMEM; - } + if (powermate_alloc_buffers(udev, pm)) + goto fail2; pm->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!pm->irq) { - powermate_free_buffers(udev, pm); - kfree(pm); - return -ENOMEM; - } + if (!pm->irq) + goto fail2; pm->config = usb_alloc_urb(0, GFP_KERNEL); - if (!pm->config) { - usb_free_urb(pm->irq); - powermate_free_buffers(udev, pm); - kfree(pm); - return -ENOMEM; - } + if (!pm->config) + goto fail3; + + pm->udev = udev; + pm->input = input_dev; + + usb_make_path(udev, pm->phys, sizeof(pm->phys)); + strlcpy(pm->phys, "/input0", sizeof(pm->phys)); spin_lock_init(&pm->lock); - init_input_dev(&pm->input); + + switch (le16_to_cpu(udev->descriptor.idProduct)) { + case POWERMATE_PRODUCT_NEW: + input_dev->name = pm_name_powermate; + break; + case POWERMATE_PRODUCT_OLD: + input_dev->name = pm_name_soundknob; + break; + default: + input_dev->name = pm_name_soundknob; + printk(KERN_WARNING "powermate: unknown product id %04x\n", + le16_to_cpu(udev->descriptor.idProduct)); + } + + input_dev->phys = pm->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = pm; + + input_dev->event = powermate_input_event; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC); + input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); + input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); + input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); /* get a handle to the interrupt data pipe */ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){ - printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n", + if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) { + printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n", POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp); maxp = POWERMATE_PAYLOAD_SIZE_MAX; } @@ -371,35 +392,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i /* register our interrupt URB with the USB system */ if (usb_submit_urb(pm->irq, GFP_KERNEL)) { - powermate_free_buffers(udev, pm); - kfree(pm); - return -EIO; /* failure */ + err = -EIO; + goto fail4; } - switch (le16_to_cpu(udev->descriptor.idProduct)) { - case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break; - case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break; - default: - pm->input.name = pm_name_soundknob; - printk(KERN_WARNING "powermate: unknown product id %04x\n", - le16_to_cpu(udev->descriptor.idProduct)); - } - - pm->input.private = pm; - pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC); - pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0); - pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); - pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); - usb_to_input_id(udev, &pm->input.id); - pm->input.event = powermate_input_event; - pm->input.dev = &intf->dev; - pm->input.phys = pm->phys; - - input_register_device(&pm->input); - - usb_make_path(udev, path, 64); - snprintf(pm->phys, 64, "%s/input0", path); - printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys); + input_register_device(pm->input); /* force an update of everything */ pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; @@ -407,6 +404,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i usb_set_intfdata(intf, pm); return 0; + +fail4: usb_free_urb(pm->config); +fail3: usb_free_urb(pm->irq); +fail2: powermate_free_buffers(udev, pm); +fail1: input_free_device(input_dev); + kfree(pm); + return err; } /* Called when a USB device we've accepted ownership of is removed */ @@ -418,7 +422,7 @@ static void powermate_disconnect(struct usb_interface *intf) if (pm) { pm->requires_update = 0; usb_kill_urb(pm->irq); - input_unregister_device(&pm->input); + input_unregister_device(pm->input); usb_free_urb(pm->irq); usb_free_urb(pm->config); powermate_free_buffers(interface_to_usbdev(intf), pm); diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 4276c24a5080..3766ccc271be 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c @@ -68,7 +68,7 @@ struct touchkit_usb { dma_addr_t data_dma; struct urb *irq; struct usb_device *udev; - struct input_dev input; + struct input_dev *input; char name[128]; char phys[64]; }; @@ -115,12 +115,12 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs) y = TOUCHKIT_GET_Y(touchkit->data); } - input_regs(&touchkit->input, regs); - input_report_key(&touchkit->input, BTN_TOUCH, + input_regs(touchkit->input, regs); + input_report_key(touchkit->input, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(touchkit->data)); - input_report_abs(&touchkit->input, ABS_X, x); - input_report_abs(&touchkit->input, ABS_Y, y); - input_sync(&touchkit->input); + input_report_abs(touchkit->input, ABS_X, x); + input_report_abs(touchkit->input, ABS_Y, y); + input_sync(touchkit->input); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -171,87 +171,81 @@ static void touchkit_free_buffers(struct usb_device *udev, static int touchkit_probe(struct usb_interface *intf, const struct usb_device_id *id) { - int ret; struct touchkit_usb *touchkit; + struct input_dev *input_dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); - char path[64]; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - touchkit = kmalloc(sizeof(struct touchkit_usb), GFP_KERNEL); - if (!touchkit) - return -ENOMEM; - - memset(touchkit, 0, sizeof(struct touchkit_usb)); - touchkit->udev = udev; - - if (touchkit_alloc_buffers(udev, touchkit)) { - ret = -ENOMEM; + touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!touchkit || !input_dev) goto out_free; - } - touchkit->input.private = touchkit; - touchkit->input.open = touchkit_open; - touchkit->input.close = touchkit_close; - - usb_make_path(udev, path, 64); - sprintf(touchkit->phys, "%s/input0", path); - - touchkit->input.name = touchkit->name; - touchkit->input.phys = touchkit->phys; - usb_to_input_id(udev, &touchkit->input.id); - touchkit->input.dev = &intf->dev; - - touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - touchkit->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - touchkit->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - /* Used to Scale Compensated Data */ - touchkit->input.absmin[ABS_X] = TOUCHKIT_MIN_XC; - touchkit->input.absmax[ABS_X] = TOUCHKIT_MAX_XC; - touchkit->input.absfuzz[ABS_X] = TOUCHKIT_XC_FUZZ; - touchkit->input.absflat[ABS_X] = TOUCHKIT_XC_FLAT; - touchkit->input.absmin[ABS_Y] = TOUCHKIT_MIN_YC; - touchkit->input.absmax[ABS_Y] = TOUCHKIT_MAX_YC; - touchkit->input.absfuzz[ABS_Y] = TOUCHKIT_YC_FUZZ; - touchkit->input.absflat[ABS_Y] = TOUCHKIT_YC_FLAT; - - if (udev->manufacturer) - strcat(touchkit->name, udev->manufacturer); - if (udev->product) - sprintf(touchkit->name, "%s %s", touchkit->name, udev->product); - - if (!strlen(touchkit->name)) - sprintf(touchkit->name, "USB Touchscreen %04x:%04x", - touchkit->input.id.vendor, touchkit->input.id.product); + if (touchkit_alloc_buffers(udev, touchkit)) + goto out_free; touchkit->irq = usb_alloc_urb(0, GFP_KERNEL); if (!touchkit->irq) { dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__); - ret = -ENOMEM; goto out_free_buffers; } + touchkit->udev = udev; + touchkit->input = input_dev; + + if (udev->manufacturer) + strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(touchkit->name, " ", sizeof(touchkit->name)); + strlcat(touchkit->name, udev->product, sizeof(touchkit->name)); + } + + if (!strlen(touchkit->name)) + snprintf(touchkit->name, sizeof(touchkit->name), + "USB Touchscreen %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys)); + strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys)); + + input_dev->name = touchkit->name; + input_dev->phys = touchkit->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = touchkit; + input_dev->open = touchkit_open; + input_dev->close = touchkit_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC, + TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT); + input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC, + TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT); + usb_fill_int_urb(touchkit->irq, touchkit->udev, - usb_rcvintpipe(touchkit->udev, 0x81), - touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, - touchkit_irq, touchkit, endpoint->bInterval); + usb_rcvintpipe(touchkit->udev, 0x81), + touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, + touchkit_irq, touchkit, endpoint->bInterval); - input_register_device(&touchkit->input); + input_register_device(touchkit->input); - printk(KERN_INFO "input: %s on %s\n", touchkit->name, path); usb_set_intfdata(intf, touchkit); - return 0; out_free_buffers: touchkit_free_buffers(udev, touchkit); out_free: + input_free_device(input_dev); kfree(touchkit); - return ret; + return -ENOMEM; } static void touchkit_disconnect(struct usb_interface *intf) @@ -265,8 +259,8 @@ static void touchkit_disconnect(struct usb_interface *intf) dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__); usb_set_intfdata(intf, NULL); - input_unregister_device(&touchkit->input); usb_kill_urb(touchkit->irq); + input_unregister_device(touchkit->input); usb_free_urb(touchkit->irq); touchkit_free_buffers(interface_to_usbdev(intf), touchkit); kfree(touchkit); diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 28987f15eeee..226b6f90a907 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = { }; struct usb_kbd { - struct input_dev dev; + struct input_dev *dev; struct usb_device *usbdev; unsigned char old[8]; struct urb *irq, *led; @@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs) goto resubmit; } - input_regs(&kbd->dev, regs); + input_regs(kbd->dev, regs); for (i = 0; i < 8; i++) - input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); + input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); for (i = 2; i < 8; i++) { if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { if (usb_kbd_keycode[kbd->old[i]]) - input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); + input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); else info("Unknown key (scancode %#x) released.", kbd->old[i]); } if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (usb_kbd_keycode[kbd->new[i]]) - input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); + input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); else info("Unknown key (scancode %#x) pressed.", kbd->new[i]); } } - input_sync(&kbd->dev); + input_sync(kbd->dev); memcpy(kbd->old, kbd->new, 8); @@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) static int usb_kbd_probe(struct usb_interface *iface, const struct usb_device_id *id) { - struct usb_device * dev = interface_to_usbdev(iface); + struct usb_device *dev = interface_to_usbdev(iface); struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; + struct input_dev *input_dev; int i, pipe, maxp; - char path[64]; interface = iface->cur_altsetting; @@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_interface *iface, return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!(endpoint->bEndpointAddress & 0x80)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) return -ENODEV; - if ((endpoint->bmAttributes & 3) != 3) + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) - return -ENOMEM; - memset(kbd, 0, sizeof(struct usb_kbd)); + kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!kbd || !input_dev) + goto fail1; - if (usb_kbd_alloc_mem(dev, kbd)) { - usb_kbd_free_mem(dev, kbd); - kfree(kbd); - return -ENOMEM; - } + if (usb_kbd_alloc_mem(dev, kbd)) + goto fail2; kbd->usbdev = dev; + kbd->dev = input_dev; - kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); - kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); + if (dev->manufacturer) + strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name)); + + if (dev->product) { + if (dev->manufacturer) + strlcat(kbd->name, " ", sizeof(kbd->name)); + strlcat(kbd->name, dev->product, sizeof(kbd->name)); + } + + if (!strlen(kbd->name)) + snprintf(kbd->name, sizeof(kbd->name), + "USB HIDBP Keyboard %04x:%04x", + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + usb_make_path(dev, kbd->phys, sizeof(kbd->phys)); + strlcpy(kbd->phys, "/input0", sizeof(kbd->phys)); + + input_dev->name = kbd->name; + input_dev->phys = kbd->phys; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &iface->dev; + input_dev->private = kbd; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); for (i = 0; i < 255; i++) - set_bit(usb_kbd_keycode[i], kbd->dev.keybit); - clear_bit(0, kbd->dev.keybit); + set_bit(usb_kbd_keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); - kbd->dev.private = kbd; - kbd->dev.event = usb_kbd_event; - kbd->dev.open = usb_kbd_open; - kbd->dev.close = usb_kbd_close; + input_dev->event = usb_kbd_event; + input_dev->open = usb_kbd_open; + input_dev->close = usb_kbd_close; usb_fill_int_urb(kbd->irq, dev, pipe, kbd->new, (maxp > 8 ? 8 : maxp), @@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_interface *iface, kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); kbd->cr->wLength = cpu_to_le16(1); - usb_make_path(dev, path, 64); - sprintf(kbd->phys, "%s/input0", path); - - kbd->dev.name = kbd->name; - kbd->dev.phys = kbd->phys; - usb_to_input_id(dev, &kbd->dev.id); - kbd->dev.dev = &iface->dev; - - if (dev->manufacturer) - strcat(kbd->name, dev->manufacturer); - if (dev->product) - sprintf(kbd->name, "%s %s", kbd->name, dev->product); - - if (!strlen(kbd->name)) - sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x", - kbd->dev.id.vendor, kbd->dev.id.product); - usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0), (void *) kbd->cr, kbd->leds, 1, usb_kbd_led, kbd); kbd->led->setup_dma = kbd->cr_dma; kbd->led->transfer_dma = kbd->leds_dma; - kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP - | URB_NO_SETUP_DMA_MAP); + kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - input_register_device(&kbd->dev); - - printk(KERN_INFO "input: %s on %s\n", kbd->name, path); + input_register_device(kbd->dev); usb_set_intfdata(iface, kbd); return 0; + +fail2: usb_kbd_free_mem(dev, kbd); +fail1: input_free_device(input_dev); + kfree(kbd); + return -ENOMEM; } static void usb_kbd_disconnect(struct usb_interface *intf) @@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (kbd) { usb_kill_urb(kbd->irq); - input_unregister_device(&kbd->dev); + input_unregister_device(kbd->dev); usb_kbd_free_mem(interface_to_usbdev(intf), kbd); kfree(kbd); } diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 4104dec847fb..230f6b1b314a 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -50,7 +50,7 @@ struct usb_mouse { char name[128]; char phys[64]; struct usb_device *usbdev; - struct input_dev dev; + struct input_dev *dev; struct urb *irq; signed char *data; @@ -61,7 +61,7 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs) { struct usb_mouse *mouse = urb->context; signed char *data = mouse->data; - struct input_dev *dev = &mouse->dev; + struct input_dev *dev = mouse->dev; int status; switch (urb->status) { @@ -115,14 +115,14 @@ static void usb_mouse_close(struct input_dev *dev) usb_kill_urb(mouse->irq); } -static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) +static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device * dev = interface_to_usbdev(intf); + struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; + struct input_dev *input_dev; int pipe, maxp; - char path[64]; interface = intf->cur_altsetting; @@ -130,59 +130,62 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!(endpoint->bEndpointAddress & 0x80)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) return -ENODEV; - if ((endpoint->bmAttributes & 3) != 3) + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) - return -ENOMEM; - memset(mouse, 0, sizeof(struct usb_mouse)); + mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mouse || !input_dev) + goto fail1; mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma); - if (!mouse->data) { - kfree(mouse); - return -ENOMEM; - } + if (!mouse->data) + goto fail1; mouse->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!mouse->irq) { - usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); - kfree(mouse); - return -ENODEV; - } + if (!mouse->irq) + goto fail2; mouse->usbdev = dev; - - mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); - mouse->dev.relbit[0] |= BIT(REL_WHEEL); - - mouse->dev.private = mouse; - mouse->dev.open = usb_mouse_open; - mouse->dev.close = usb_mouse_close; - - usb_make_path(dev, path, 64); - sprintf(mouse->phys, "%s/input0", path); - - mouse->dev.name = mouse->name; - mouse->dev.phys = mouse->phys; - usb_to_input_id(dev, &mouse->dev.id); - mouse->dev.dev = &intf->dev; + mouse->dev = input_dev; if (dev->manufacturer) - strcat(mouse->name, dev->manufacturer); - if (dev->product) - sprintf(mouse->name, "%s %s", mouse->name, dev->product); + strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name)); + + if (dev->product) { + if (dev->manufacturer) + strlcat(mouse->name, " ", sizeof(mouse->name)); + strlcat(mouse->name, dev->product, sizeof(mouse->name)); + } if (!strlen(mouse->name)) - sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x", - mouse->dev.id.vendor, mouse->dev.id.product); + snprintf(mouse->name, sizeof(mouse->name), + "USB HIDBP Mouse %04x:%04x", + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + + usb_make_path(dev, mouse->phys, sizeof(mouse->phys)); + strlcat(mouse->phys, "/input0", sizeof(mouse->phys)); + + input_dev->name = mouse->name; + input_dev->phys = mouse->phys; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->relbit[0] |= BIT(REL_WHEEL); + + input_dev->private = mouse; + input_dev->open = usb_mouse_open; + input_dev->close = usb_mouse_close; usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), @@ -190,11 +193,15 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ mouse->irq->transfer_dma = mouse->data_dma; mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(&mouse->dev); - printk(KERN_INFO "input: %s on %s\n", mouse->name, path); + input_register_device(mouse->dev); usb_set_intfdata(intf, mouse); return 0; + +fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); +fail1: input_free_device(input_dev); + kfree(mouse); + return -ENOMEM; } static void usb_mouse_disconnect(struct usb_interface *intf) @@ -204,7 +211,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (mouse) { usb_kill_urb(mouse->irq); - input_unregister_device(&mouse->dev); + input_unregister_device(mouse->dev); usb_free_urb(mouse->irq); usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma); kfree(mouse); diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 3b266af3048a..ea0f75773ae1 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -111,7 +111,7 @@ struct wacom_features { struct wacom { signed char *data; dma_addr_t data_dma; - struct input_dev dev; + struct input_dev *dev; struct usb_device *usbdev; struct urb *irq; struct wacom_features *features; @@ -135,7 +135,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; int prox, pressure; int retval; @@ -225,7 +225,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; int retval; switch (urb->status) { @@ -275,7 +275,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; int retval; switch (urb->status) { @@ -318,7 +318,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; int x, y; int retval; @@ -397,7 +397,7 @@ static int wacom_intuos_inout(struct urb *urb) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; int idx; /* tool number */ @@ -479,7 +479,7 @@ static void wacom_intuos_general(struct urb *urb) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; unsigned int t; /* general pen packet */ @@ -509,7 +509,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; + struct input_dev *dev = wacom->dev; unsigned int t; int idx; int retval; @@ -738,95 +738,83 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i { struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; - char rep_data[2] = {0x02, 0x02}; struct wacom *wacom; - char path[64]; + struct input_dev *input_dev; + char rep_data[2] = {0x02, 0x02}; - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) - return -ENOMEM; - memset(wacom, 0, sizeof(struct wacom)); + wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!wacom || !input_dev) + goto fail1; wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom->data) { - kfree(wacom); - return -ENOMEM; - } + if (!wacom->data) + goto fail1; wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) { - usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); - kfree(wacom); - return -ENOMEM; - } + if (!wacom->irq) + goto fail2; + + wacom->usbdev = dev; + wacom->dev = input_dev; + usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); + strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom->features = wacom_features + (id - wacom_ids); + if (wacom->features->pktlen > 10) + BUG(); - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); + input_dev->name = wacom->features->name; + usb_to_input_id(dev, &input_dev->id); + + input_dev->cdev.dev = &intf->dev; + input_dev->private = wacom; + input_dev->open = wacom_open; + input_dev->close = wacom_close; + + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); + input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0); + input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); switch (wacom->features->type) { case GRAPHIRE: - wacom->dev.evbit[0] |= BIT(EV_REL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); + input_dev->evbit[0] |= BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_WHEEL); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); + input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0); break; case INTUOS3: case CINTIQ: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); + input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); + input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); /* fall through */ case INTUOS: - wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) + input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); + input_dev->mscbit[0] |= BIT(MSC_SERIAL); + input_dev->relbit[0] |= BIT(REL_WHEEL); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); + input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0); + input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); + input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); + input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); break; case PL: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); break; } - wacom->dev.absmax[ABS_X] = wacom->features->x_max; - wacom->dev.absmax[ABS_Y] = wacom->features->y_max; - wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max; - wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; - wacom->dev.absmax[ABS_TILT_X] = 127; - wacom->dev.absmax[ABS_TILT_Y] = 127; - wacom->dev.absmax[ABS_WHEEL] = 1023; - - wacom->dev.absmax[ABS_RX] = 4097; - wacom->dev.absmax[ABS_RY] = 4097; - wacom->dev.absmin[ABS_RZ] = -900; - wacom->dev.absmax[ABS_RZ] = 899; - wacom->dev.absmin[ABS_THROTTLE] = -1023; - wacom->dev.absmax[ABS_THROTTLE] = 1023; - - wacom->dev.absfuzz[ABS_X] = 4; - wacom->dev.absfuzz[ABS_Y] = 4; - - wacom->dev.private = wacom; - wacom->dev.open = wacom_open; - wacom->dev.close = wacom_close; - - usb_make_path(dev, path, 64); - sprintf(wacom->phys, "%s/input0", path); - - wacom->dev.name = wacom->features->name; - wacom->dev.phys = wacom->phys; - usb_to_input_id(dev, &wacom->dev.id); - wacom->dev.dev = &intf->dev; - wacom->usbdev = dev; - endpoint = &intf->cur_altsetting->endpoint[0].desc; if (wacom->features->pktlen > 10) @@ -839,18 +827,20 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(&wacom->dev); + input_register_device(wacom->dev); /* ask the tablet to report tablet data */ usb_set_report(intf, 3, 2, rep_data, 2); /* repeat once (not sure why the first call often fails) */ usb_set_report(intf, 3, 2, rep_data, 2); - printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); - usb_set_intfdata(intf, wacom); - return 0; + +fail2: usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); +fail1: input_free_device(input_dev); + kfree(wacom); + return -ENOMEM; } static void wacom_disconnect(struct usb_interface *intf) @@ -860,7 +850,7 @@ static void wacom_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (wacom) { usb_kill_urb(wacom->irq); - input_unregister_device(&wacom->dev); + input_unregister_device(wacom->dev); usb_free_urb(wacom->irq); usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); kfree(wacom); diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 18125e0bffa2..43112f040b6d 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = { MODULE_DEVICE_TABLE (usb, xpad_table); struct usb_xpad { - struct input_dev dev; /* input device interface */ + struct input_dev *dev; /* input device interface */ struct usb_device *udev; /* usb device */ struct urb *irq_in; /* urb for interrupt in report */ @@ -125,7 +125,7 @@ struct usb_xpad { static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) { - struct input_dev *dev = &xpad->dev; + struct input_dev *dev = xpad->dev; input_regs(dev, regs); @@ -214,9 +214,9 @@ static void xpad_close (struct input_dev *dev) static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); - struct usb_xpad *xpad = NULL; + struct usb_xpad *xpad; + struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; - char path[64]; int i; for (i = 0; xpad_device[i].idVendor; i++) { @@ -225,29 +225,63 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id break; } - if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { - err("cannot allocate memory for new pad"); - return -ENOMEM; - } - memset(xpad, 0, sizeof(struct usb_xpad)); + xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!xpad || !input_dev) + goto fail1; xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, SLAB_ATOMIC, &xpad->idata_dma); - if (!xpad->idata) { - kfree(xpad); - return -ENOMEM; - } + if (!xpad->idata) + goto fail1; xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); - if (!xpad->irq_in) { - err("cannot allocate memory for new pad irq urb"); - usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - kfree(xpad); - return -ENOMEM; - } + if (!xpad->irq_in) + goto fail2; + + xpad->udev = udev; + xpad->dev = input_dev; + usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); + strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); + + input_dev->name = xpad_device[i].name; + input_dev->phys = xpad->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = xpad; + input_dev->open = xpad_open; + input_dev->close = xpad_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; xpad_btn[i] >= 0; i++) + set_bit(xpad_btn[i], input_dev->keybit); + + for (i = 0; xpad_abs[i] >= 0; i++) { + + signed short t = xpad_abs[i]; + + set_bit(t, input_dev->absbit); + + switch (t) { + case ABS_X: + case ABS_Y: + case ABS_RX: + case ABS_RY: /* the two sticks */ + input_set_abs_params(input_dev, t, -32768, 32767, 16, 128); + break; + case ABS_Z: + case ABS_RZ: /* the triggers */ + input_set_abs_params(input_dev, t, 0, 255, 0, 0); + break; + case ABS_HAT0X: + case ABS_HAT0Y: /* the d-pad */ + input_set_abs_params(input_dev, t, -1, 1, 0, 0); + break; + } + } ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; - usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, @@ -255,59 +289,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - xpad->udev = udev; - - usb_to_input_id(udev, &xpad->dev.id); - xpad->dev.dev = &intf->dev; - xpad->dev.private = xpad; - xpad->dev.name = xpad_device[i].name; - xpad->dev.phys = xpad->phys; - xpad->dev.open = xpad_open; - xpad->dev.close = xpad_close; - - usb_make_path(udev, path, 64); - snprintf(xpad->phys, 64, "%s/input0", path); - - xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (i = 0; xpad_btn[i] >= 0; i++) - set_bit(xpad_btn[i], xpad->dev.keybit); - - for (i = 0; xpad_abs[i] >= 0; i++) { - - signed short t = xpad_abs[i]; - - set_bit(t, xpad->dev.absbit); - - switch (t) { - case ABS_X: - case ABS_Y: - case ABS_RX: - case ABS_RY: /* the two sticks */ - xpad->dev.absmax[t] = 32767; - xpad->dev.absmin[t] = -32768; - xpad->dev.absflat[t] = 128; - xpad->dev.absfuzz[t] = 16; - break; - case ABS_Z: - case ABS_RZ: /* the triggers */ - xpad->dev.absmax[t] = 255; - xpad->dev.absmin[t] = 0; - break; - case ABS_HAT0X: - case ABS_HAT0Y: /* the d-pad */ - xpad->dev.absmax[t] = 1; - xpad->dev.absmin[t] = -1; - break; - } - } - - input_register_device(&xpad->dev); - - printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); + input_register_device(xpad->dev); usb_set_intfdata(intf, xpad); return 0; + +fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); +fail1: input_free_device(input_dev); + kfree(xpad); + return -ENOMEM; + } static void xpad_disconnect(struct usb_interface *intf) @@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (xpad) { usb_kill_urb(xpad->irq_in); - input_unregister_device(&xpad->dev); + input_unregister_device(xpad->dev); usb_free_urb(xpad->irq_in); usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 58a176ef96a5..f526aebea502 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -54,6 +54,7 @@ #include #include #include +#include #include "map_to_7segment.h" #include "yealink.h" @@ -101,12 +102,12 @@ static const struct lcd_segment_map { }; struct yealink_dev { - struct input_dev idev; /* input device */ + struct input_dev *idev; /* input device */ struct usb_device *udev; /* usb device */ /* irq input channel */ struct yld_ctl_packet *irq_data; - dma_addr_t irq_dma; + dma_addr_t irq_dma; struct urb *urb_irq; /* control output channel */ @@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode) */ static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs) { - struct input_dev *idev = &yld->idev; + struct input_dev *idev = yld->idev; input_regs(idev, regs); if (yld->key_code >= 0) { @@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err) } if (yld->urb_ctl) usb_free_urb(yld->urb_ctl); - if (yld->idev.dev) - input_unregister_device(&yld->idev); + if (yld->idev) { + if (err) + input_free_device(yld->idev); + else + input_unregister_device(yld->idev); + } if (yld->ctl_req) usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), yld->ctl_req, yld->ctl_req_dma); @@ -857,7 +862,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct yealink_dev *yld; - char path[64]; + struct input_dev *input_dev; int ret, pipe, i; i = usb_match(udev); @@ -866,17 +871,21 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - if (!(endpoint->bEndpointAddress & 0x80)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) return -EIO; - if ((endpoint->bmAttributes & 3) != 3) + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -EIO; - if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL) + yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL); + if (!yld) return -ENOMEM; - memset(yld, 0, sizeof(*yld)); yld->udev = udev; + yld->idev = input_dev = input_allocate_device(); + if (!input_dev) + return usb_cleanup(yld, -ENOMEM); + /* allocate usb buffers */ yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, SLAB_ATOMIC, &yld->irq_dma); @@ -935,42 +944,37 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) yld->urb_ctl->dev = udev; /* find out the physical bus location */ - if (usb_make_path(udev, path, sizeof(path)) > 0) - snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path); + usb_make_path(udev, yld->phys, sizeof(yld->phys)); + strlcat(yld->phys, "/input0", sizeof(yld->phys)); /* register settings for the input device */ - init_input_dev(&yld->idev); - yld->idev.private = yld; - yld->idev.id.bustype = BUS_USB; - yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct); - yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); - yld->idev.dev = &intf->dev; - yld->idev.name = yld_device[i].name; - yld->idev.phys = yld->phys; - /* yld->idev.event = input_ev; TODO */ - yld->idev.open = input_open; - yld->idev.close = input_close; + input_dev->name = yld_device[i].name; + input_dev->phys = yld->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + + input_dev->private = yld; + input_dev->open = input_open; + input_dev->close = input_close; + /* input_dev->event = input_ev; TODO */ /* register available key events */ - yld->idev.evbit[0] = BIT(EV_KEY); + input_dev->evbit[0] = BIT(EV_KEY); for (i = 0; i < 256; i++) { int k = map_p1k_to_key(i); if (k >= 0) { - set_bit(k & 0xff, yld->idev.keybit); + set_bit(k & 0xff, input_dev->keybit); if (k >> 8) - set_bit(k >> 8, yld->idev.keybit); + set_bit(k >> 8, input_dev->keybit); } } - printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path); - - input_register_device(&yld->idev); + input_register_device(yld->idev); usb_set_intfdata(intf, yld); /* clear visible elements */ - for (i=0; i Date: Thu, 15 Sep 2005 02:01:48 -0500 Subject: [PATCH 0615/1940] [PATCH] Input: convert ucb1x00-ts to dynamic input_dev allocation Input: convert ucb1x00-ts to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/ucb1x00-ts.c | 43 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index a260f83bcb02..585cded3d365 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -40,7 +40,7 @@ struct ucb1x00_ts { - struct input_dev idev; + struct input_dev *idev; struct ucb1x00 *ucb; wait_queue_head_t irq_wait; @@ -56,16 +56,16 @@ static int adcsync; static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) { - input_report_abs(&ts->idev, ABS_X, x); - input_report_abs(&ts->idev, ABS_Y, y); - input_report_abs(&ts->idev, ABS_PRESSURE, pressure); - input_sync(&ts->idev); + input_report_abs(ts->idev, ABS_X, x); + input_report_abs(ts->idev, ABS_Y, y); + input_report_abs(ts->idev, ABS_PRESSURE, pressure); + input_sync(ts->idev); } static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) { - input_report_abs(&ts->idev, ABS_PRESSURE, 0); - input_sync(&ts->idev); + input_report_abs(ts->idev, ABS_PRESSURE, 0); + input_sync(ts->idev); } /* @@ -341,26 +341,30 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) { struct ucb1x00_ts *ts; - ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); + ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); if (!ts) return -ENOMEM; - memset(ts, 0, sizeof(struct ucb1x00_ts)); + ts->idev = input_allocate_device(); + if (!ts->idev) { + kfree(ts); + return -ENOMEM; + } ts->ucb = dev->ucb; ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; - ts->idev.name = "Touchscreen panel"; - ts->idev.id.product = ts->ucb->id; - ts->idev.open = ucb1x00_ts_open; - ts->idev.close = ucb1x00_ts_close; + ts->idev->name = "Touchscreen panel"; + ts->idev->id.product = ts->ucb->id; + ts->idev->open = ucb1x00_ts_open; + ts->idev->close = ucb1x00_ts_close; - __set_bit(EV_ABS, ts->idev.evbit); - __set_bit(ABS_X, ts->idev.absbit); - __set_bit(ABS_Y, ts->idev.absbit); - __set_bit(ABS_PRESSURE, ts->idev.absbit); + __set_bit(EV_ABS, ts->idev->evbit); + __set_bit(ABS_X, ts->idev->absbit); + __set_bit(ABS_Y, ts->idev->absbit); + __set_bit(ABS_PRESSURE, ts->idev->absbit); - input_register_device(&ts->idev); + input_register_device(ts->idev); dev->priv = ts; @@ -370,7 +374,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) { struct ucb1x00_ts *ts = dev->priv; - input_unregister_device(&ts->idev); + + input_unregister_device(ts->idev); kfree(ts); } From eca1ed196cd5b523c1057204cd3672555ad58dfe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:46 -0500 Subject: [PATCH 0616/1940] [PATCH] drivers/input/touchscreen: convert to dynamic input_dev allocation Input: convert drivers/input/touchscreen to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/corgi_ts.c | 89 ++++++------ drivers/input/touchscreen/elo.c | 91 +++++++------ drivers/input/touchscreen/gunze.c | 66 ++++----- drivers/input/touchscreen/h3600_ts_input.c | 149 ++++++++------------- drivers/input/touchscreen/hp680_ts_input.c | 50 +++---- drivers/input/touchscreen/mk712.c | 82 ++++++------ drivers/input/touchscreen/mtouch.c | 64 ++++----- 7 files changed, 281 insertions(+), 310 deletions(-) diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 4c7fbe550365..40ae183ba1cd 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -41,8 +41,7 @@ struct ts_event { }; struct corgi_ts { - char phys[32]; - struct input_dev input; + struct input_dev *input; struct timer_list timer; struct ts_event tc; int pendown; @@ -182,14 +181,12 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs) if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) return; - if (regs) - input_regs(&corgi_ts->input, regs); - - input_report_abs(&corgi_ts->input, ABS_X, corgi_ts->tc.x); - input_report_abs(&corgi_ts->input, ABS_Y, corgi_ts->tc.y); - input_report_abs(&corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); - input_report_key(&corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); - input_sync(&corgi_ts->input); + input_regs(corgi_ts->input, regs); + input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); + input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); + input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); + input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); + input_sync(corgi_ts->input); } static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs) @@ -273,39 +270,44 @@ static int __init corgits_probe(struct device *dev) { struct corgi_ts *corgi_ts; struct platform_device *pdev = to_platform_device(dev); + struct input_dev *input_dev; + int err = -ENOMEM; - if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL))) - return -ENOMEM; + corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!corgi_ts || !input_dev) + goto fail; dev_set_drvdata(dev, corgi_ts); - memset(corgi_ts, 0, sizeof(struct corgi_ts)); - corgi_ts->machinfo = dev->platform_data; corgi_ts->irq_gpio = platform_get_irq(pdev, 0); if (corgi_ts->irq_gpio < 0) { - kfree(corgi_ts); - return -ENODEV; + err = -ENODEV; + goto fail; } - init_input_dev(&corgi_ts->input); - corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(&corgi_ts->input, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); - input_set_abs_params(&corgi_ts->input, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); - input_set_abs_params(&corgi_ts->input, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); + corgi_ts->input = input_dev; - strcpy(corgi_ts->phys, "corgits/input0"); + init_timer(&corgi_ts->timer); + corgi_ts->timer.data = (unsigned long) corgi_ts; + corgi_ts->timer.function = corgi_ts_timer; - corgi_ts->input.private = corgi_ts; - corgi_ts->input.name = "Corgi Touchscreen"; - corgi_ts->input.dev = dev; - corgi_ts->input.phys = corgi_ts->phys; - corgi_ts->input.id.bustype = BUS_HOST; - corgi_ts->input.id.vendor = 0x0001; - corgi_ts->input.id.product = 0x0002; - corgi_ts->input.id.version = 0x0100; + input_dev->name = "Corgi Touchscreen"; + input_dev->phys = "corgits/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0002; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = dev; + input_dev->private = corgi_ts; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); + input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN); @@ -319,25 +321,24 @@ static int __init corgits_probe(struct device *dev) corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS); mdelay(5); - init_timer(&corgi_ts->timer); - corgi_ts->timer.data = (unsigned long) corgi_ts; - corgi_ts->timer.function = corgi_ts_timer; - - input_register_device(&corgi_ts->input); - corgi_ts->power_mode = PWR_MODE_ACTIVE; - if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) { - input_unregister_device(&corgi_ts->input); - kfree(corgi_ts); - return -EBUSY; + err = -EBUSY; + goto fail; } + input_register_device(corgi_ts->input); + + corgi_ts->power_mode = PWR_MODE_ACTIVE; + /* Enable Falling Edge */ set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); - printk(KERN_INFO "input: Corgi Touchscreen Registered\n"); - return 0; + + fail: input_free_device(input_dev); + kfree(corgi_ts); + return err; + } static int corgits_remove(struct device *dev) @@ -347,7 +348,7 @@ static int corgits_remove(struct device *dev) free_irq(corgi_ts->irq_gpio, NULL); del_timer_sync(&corgi_ts->timer); corgi_ts->machinfo->put_hsync(); - input_unregister_device(&corgi_ts->input); + input_unregister_device(corgi_ts->input); kfree(corgi_ts); return 0; } diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 3cdc9cab688d..c86a2eb310fd 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -36,14 +36,12 @@ MODULE_LICENSE("GPL"); #define ELO_MAX_LENGTH 10 -static char *elo_name = "Elo Serial TouchScreen"; - /* * Per-touchscreen data. */ struct elo { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; int id; int idx; @@ -54,7 +52,7 @@ struct elo { static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs) { - struct input_dev *dev = &elo->dev; + struct input_dev *dev = elo->dev; elo->csum += elo->data[elo->idx] = data; @@ -80,7 +78,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); - input_report_key(dev, BTN_TOUCH, elo->data[2] & 3); + input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]); input_sync(dev); } elo->idx = 0; @@ -91,7 +89,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs) { - struct input_dev *dev = &elo->dev; + struct input_dev *dev = elo->dev; elo->data[elo->idx] = data; @@ -129,7 +127,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re case 5: if ((data & 0xf0) == 0) { input_report_abs(dev, ABS_PRESSURE, elo->data[5]); - input_report_key(dev, BTN_TOUCH, elo->data[5]); + input_report_key(dev, BTN_TOUCH, !!elo->data[5]); } input_sync(dev); elo->idx = 0; @@ -139,7 +137,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs) { - struct input_dev *dev = &elo->dev; + struct input_dev *dev = elo->dev; elo->data[elo->idx] = data; @@ -191,7 +189,7 @@ static void elo_disconnect(struct serio *serio) { struct elo* elo = serio_get_drvdata(serio); - input_unregister_device(&elo->dev); + input_unregister_device(elo->dev); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(elo); @@ -206,67 +204,68 @@ static void elo_disconnect(struct serio *serio) static int elo_connect(struct serio *serio, struct serio_driver *drv) { struct elo *elo; + struct input_dev *input_dev; int err; - if (!(elo = kmalloc(sizeof(struct elo), GFP_KERNEL))) - return -ENOMEM; - - memset(elo, 0, sizeof(struct elo)); - - init_input_dev(&elo->dev); - elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + elo = kzalloc(sizeof(struct elo), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!elo || !input_dev) { + err = -ENOMEM; + goto fail; + } + elo->serio = serio; elo->id = serio->id.id; + elo->dev = input_dev; + snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); + + input_dev->private = elo; + input_dev->name = "Elo Serial TouchScreen"; + input_dev->phys = elo->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_ELO; + input_dev->id.product = elo->id; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); switch (elo->id) { case 0: /* 10-byte protocol */ - input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0); - input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0); - input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); break; case 1: /* 6-byte protocol */ - input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); case 2: /* 4-byte protocol */ - input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0); - input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0); + input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); break; case 3: /* 3-byte protocol */ - input_set_abs_params(&elo->dev, ABS_X, 0, 255, 0, 0); - input_set_abs_params(&elo->dev, ABS_Y, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); break; } - elo->serio = serio; - - sprintf(elo->phys, "%s/input0", serio->phys); - - elo->dev.private = elo; - elo->dev.name = elo_name; - elo->dev.phys = elo->phys; - elo->dev.id.bustype = BUS_RS232; - elo->dev.id.vendor = SERIO_ELO; - elo->dev.id.product = elo->id; - elo->dev.id.version = 0x0100; - serio_set_drvdata(serio, elo); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(elo); - return err; - } - - input_register_device(&elo->dev); - - printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys); + if (err) + goto fail; + input_register_device(elo->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(elo); + return err; } /* diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 53a27e43dd23..466da190ceec 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -48,14 +48,12 @@ MODULE_LICENSE("GPL"); #define GUNZE_MAX_LENGTH 10 -static char *gunze_name = "Gunze AHL-51S TouchScreen"; - /* * Per-touchscreen data. */ struct gunze { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; int idx; unsigned char data[GUNZE_MAX_LENGTH]; @@ -64,7 +62,7 @@ struct gunze { static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) { - struct input_dev *dev = &gunze->dev; + struct input_dev *dev = gunze->dev; if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { @@ -100,11 +98,13 @@ static irqreturn_t gunze_interrupt(struct serio *serio, static void gunze_disconnect(struct serio *serio) { - struct gunze* gunze = serio_get_drvdata(serio); + struct gunze *gunze = serio_get_drvdata(serio); - input_unregister_device(&gunze->dev); + input_get_device(gunze->dev); + input_unregister_device(gunze->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_put_device(gunze->dev); kfree(gunze); } @@ -117,45 +117,45 @@ static void gunze_disconnect(struct serio *serio) static int gunze_connect(struct serio *serio, struct serio_driver *drv) { struct gunze *gunze; + struct input_dev *input_dev; int err; - if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL))) - return -ENOMEM; - - memset(gunze, 0, sizeof(struct gunze)); - - init_input_dev(&gunze->dev); - gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(&gunze->dev, ABS_X, 24, 1000, 0, 0); - input_set_abs_params(&gunze->dev, ABS_Y, 24, 1000, 0, 0); + gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!gunze || !input_dev) { + err = -ENOMEM; + goto fail; + } gunze->serio = serio; - + gunze->dev = input_dev; sprintf(gunze->phys, "%s/input0", serio->phys); - gunze->dev.private = gunze; - gunze->dev.name = gunze_name; - gunze->dev.phys = gunze->phys; - gunze->dev.id.bustype = BUS_RS232; - gunze->dev.id.vendor = SERIO_GUNZE; - gunze->dev.id.product = 0x0051; - gunze->dev.id.version = 0x0100; + input_dev->private = gunze; + input_dev->name = "Gunze AHL-51S TouchScreen"; + input_dev->phys = gunze->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_GUNZE; + input_dev->id.product = 0x0051; + input_dev->id.version = 0x0100; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0); serio_set_drvdata(serio, gunze); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(gunze); - return err; - } - - input_register_device(&gunze->dev); - - printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys); + if (err) + goto fail; + input_register_device(gunze->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(gunze); + return err; } /* diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index bcfa1e36f957..a18d56bdafd9 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -39,7 +39,6 @@ #include #include #include -#include /* SA1100 serial defines */ #include @@ -93,16 +92,12 @@ MODULE_LICENSE("GPL"); #define H3600_SCANCODE_LEFT 8 /* 8 -> left */ #define H3600_SCANCODE_DOWN 9 /* 9 -> down */ -static char *h3600_name = "H3600 TouchScreen"; - /* * Per-touchscreen data. */ struct h3600_dev { - struct input_dev dev; - struct pm_dev *pm_dev; + struct input_dev *dev; struct serio *serio; - struct pm_dev *pm_dev; unsigned char event; /* event ID from packet */ unsigned char chksum; unsigned char len; @@ -163,33 +158,6 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) return 0; } -static int suspended = 0; -static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, - void *data) -{ - struct input_dev *dev = (struct input_dev *) data; - - switch (req) { - case PM_SUSPEND: /* enter D1-D3 */ - suspended = 1; - h3600_flite_power(dev, FLITE_PWR_OFF); - break; - case PM_BLANK: - if (!suspended) - h3600_flite_power(dev, FLITE_PWR_OFF); - break; - case PM_RESUME: /* enter D0 */ - /* same as unblank */ - case PM_UNBLANK: - if (suspended) { - //initSerial(); - suspended = 0; - } - h3600_flite_power(dev, FLITE_PWR_ON); - break; - } - return 0; -} #endif /* @@ -199,7 +167,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, */ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) { - struct input_dev *dev = &ts->dev; + struct input_dev *dev = ts->dev; static int touched = 0; int key, down = 0; @@ -295,6 +263,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) static int h3600ts_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { +#if 0 struct h3600_dev *ts = dev->private; switch (type) { @@ -304,6 +273,8 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, } } return -1; +#endif + return 0; } /* @@ -380,14 +351,48 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data, static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) { struct h3600_dev *ts; + struct input_dev *input_dev; int err; - if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL))) - return -ENOMEM; + ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ts || !input_dev) { + err = -ENOMEM; + goto fail1; + } - memset(ts, 0, sizeof(struct h3600_dev)); + ts->serio = serio; + ts->dev = input_dev; + sprintf(ts->phys, "%s/input0", serio->phys); - init_input_dev(&ts->dev); + input_dev->name = "H3600 TouchScreen"; + input_dev->phys = ts->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_H3600; + input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = ts; + + input_dev->event = h3600ts_event; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); + input_dev->ledbit[0] = BIT(LED_SLEEP); + input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0); + + set_bit(KEY_RECORD, input_dev->keybit); + set_bit(KEY_Q, input_dev->keybit); + set_bit(KEY_PROG1, input_dev->keybit); + set_bit(KEY_PROG2, input_dev->keybit); + set_bit(KEY_PROG3, input_dev->keybit); + set_bit(KEY_UP, input_dev->keybit); + set_bit(KEY_RIGHT, input_dev->keybit); + set_bit(KEY_LEFT, input_dev->keybit); + set_bit(KEY_DOWN, input_dev->keybit); + set_bit(KEY_ENTER, input_dev->keybit); + set_bit(KEY_SUSPEND, input_dev->keybit); + set_bit(BTN_TOUCH, input_dev->keybit); /* Device specific stuff */ set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES); @@ -397,73 +402,35 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, "h3600_action", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); - kfree(ts); - return -EBUSY; + err = -EBUSY; + goto fail2; } if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, "h3600_suspend", &ts->dev)) { - free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); - kfree(ts); - return -EBUSY; + err = -EBUSY; + goto fail3; } - /* Now we have things going we setup our input device */ - ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); - ts->dev.ledbit[0] = BIT(LED_SLEEP); - input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0); - input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0); - - set_bit(KEY_RECORD, ts->dev.keybit); - set_bit(KEY_Q, ts->dev.keybit); - set_bit(KEY_PROG1, ts->dev.keybit); - set_bit(KEY_PROG2, ts->dev.keybit); - set_bit(KEY_PROG3, ts->dev.keybit); - set_bit(KEY_UP, ts->dev.keybit); - set_bit(KEY_RIGHT, ts->dev.keybit); - set_bit(KEY_LEFT, ts->dev.keybit); - set_bit(KEY_DOWN, ts->dev.keybit); - set_bit(KEY_ENTER, ts->dev.keybit); - ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); - ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND); - - ts->serio = serio; - - sprintf(ts->phys, "%s/input0", serio->phys); - - ts->dev.event = h3600ts_event; - ts->dev.private = ts; - ts->dev.name = h3600_name; - ts->dev.phys = ts->phys; - ts->dev.id.bustype = BUS_RS232; - ts->dev.id.vendor = SERIO_H3600; - ts->dev.id.product = 0x0666; /* FIXME !!! We can ask the hardware */ - ts->dev.id.version = 0x0100; - serio_set_drvdata(serio, ts); err = serio_open(serio, drv); - if (err) { - free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts); - free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts); - serio_set_drvdata(serio, NULL); - kfree(ts); + if (err) return err; - } //h3600_flite_control(1, 25); /* default brightness */ -#ifdef CONFIG_PM - ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, - h3600ts_pm_callback); - printk("registered pm callback\n"); -#endif - input_register_device(&ts->dev); - - printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys); + input_register_device(ts->dev); return 0; + +fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); +fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); +fail1: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(ts); + return err; } /* @@ -476,9 +443,11 @@ static void h3600ts_disconnect(struct serio *serio) free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); - input_unregister_device(&ts->dev); + input_get_device(ts->dev); + input_unregister_device(ts->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_put_device(ts->dev); kfree(ts); } diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 7e1404441eca..957dd5a1b15e 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c @@ -21,10 +21,8 @@ static void do_softint(void *data); -static struct input_dev hp680_ts_dev; +static struct input_dev *hp680_ts_dev; static DECLARE_WORK(work, do_softint, 0); -static char *hp680_ts_name = "HP Jornada touchscreen"; -static char *hp680_ts_phys = "input0"; static void do_softint(void *data) { @@ -58,14 +56,14 @@ static void do_softint(void *data) } if (touched) { - input_report_key(&hp680_ts_dev, BTN_TOUCH, 1); - input_report_abs(&hp680_ts_dev, ABS_X, absx); - input_report_abs(&hp680_ts_dev, ABS_Y, absy); + input_report_key(hp680_ts_dev, BTN_TOUCH, 1); + input_report_abs(hp680_ts_dev, ABS_X, absx); + input_report_abs(hp680_ts_dev, ABS_Y, absy); } else { - input_report_key(&hp680_ts_dev, BTN_TOUCH, 0); + input_report_key(hp680_ts_dev, BTN_TOUCH, 0); } - input_sync(&hp680_ts_dev); + input_sync(hp680_ts_dev); enable_irq(HP680_TS_IRQ); } @@ -92,27 +90,29 @@ static int __init hp680_ts_init(void) scpcr |= SCPCR_TS_ENABLE; ctrl_outw(scpcr, SCPCR); - memset(&hp680_ts_dev, 0, sizeof(hp680_ts_dev)); - init_input_dev(&hp680_ts_dev); + hp680_ts_dev = input_allocate_device(); + if (!hp680_ts_dev) + return -ENOMEM; - hp680_ts_dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); - hp680_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - hp680_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - hp680_ts_dev.absmin[ABS_X] = HP680_TS_ABS_X_MIN; - hp680_ts_dev.absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; - hp680_ts_dev.absmax[ABS_X] = HP680_TS_ABS_X_MAX; - hp680_ts_dev.absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; + hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN; + hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; + hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX; + hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; - hp680_ts_dev.name = hp680_ts_name; - hp680_ts_dev.phys = hp680_ts_phys; - input_register_device(&hp680_ts_dev); + hp680_ts_dev->name = "HP Jornada touchscreen"; + hp680_ts_dev->phys = "hp680_ts/input0"; - if (request_irq - (HP680_TS_IRQ, hp680_ts_interrupt, SA_INTERRUPT, MODNAME, 0) < 0) { - printk(KERN_ERR "hp680_touchscreen.c : Can't allocate irq %d\n", + input_register_device(hp680_ts_dev); + + if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, + SA_INTERRUPT, MODNAME, 0) < 0) { + printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", HP680_TS_IRQ); - input_unregister_device(&hp680_ts_dev); + input_unregister_device(hp680_ts_dev); return -EBUSY; } @@ -124,7 +124,7 @@ static void __exit hp680_ts_exit(void) free_irq(HP680_TS_IRQ, 0); cancel_delayed_work(&work); flush_scheduled_work(); - input_unregister_device(&hp680_ts_dev); + input_unregister_device(hp680_ts_dev); } module_init(hp680_ts_init); diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index afaaebe5225b..4844d250a5eb 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c @@ -77,7 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller"); #define MK712_READ_ONE_POINT 0x20 #define MK712_POWERUP 0x40 -static struct input_dev mk712_dev; +static struct input_dev *mk712_dev; static DEFINE_SPINLOCK(mk712_lock); static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -88,7 +88,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) static unsigned short last_y; spin_lock(&mk712_lock); - input_regs(&mk712_dev, regs); + input_regs(mk712_dev, regs); status = inb(mk712_io + MK712_STATUS); @@ -100,7 +100,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (~status & MK712_STATUS_TOUCH) { debounce = 1; - input_report_key(&mk712_dev, BTN_TOUCH, 0); + input_report_key(mk712_dev, BTN_TOUCH, 0); goto end; } @@ -110,15 +110,15 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) goto end; } - input_report_key(&mk712_dev, BTN_TOUCH, 1); - input_report_abs(&mk712_dev, ABS_X, last_x); - input_report_abs(&mk712_dev, ABS_Y, last_y); + input_report_key(mk712_dev, BTN_TOUCH, 1); + input_report_abs(mk712_dev, ABS_X, last_x); + input_report_abs(mk712_dev, ABS_Y, last_y); end: last_x = inw(mk712_io + MK712_X) & 0x0fff; last_y = inw(mk712_io + MK712_Y) & 0x0fff; - input_sync(&mk712_dev); + input_sync(mk712_dev); spin_unlock(&mk712_lock); return IRQ_HANDLED; } @@ -154,30 +154,11 @@ static void mk712_close(struct input_dev *dev) spin_unlock_irqrestore(&mk712_lock, flags); } -static struct input_dev mk712_dev = { - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, - .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, - .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, - .open = mk712_open, - .close = mk712_close, - .name = "ICS MicroClock MK712 TouchScreen", - .phys = "isa0260/input0", - .absmin = { [ABS_X] = 0, [ABS_Y] = 0 }, - .absmax = { [ABS_X] = 0xfff, [ABS_Y] = 0xfff }, - .absfuzz = { [ABS_X] = 88, [ABS_Y] = 88 }, - .id = { - .bustype = BUS_ISA, - .vendor = 0x0005, - .product = 0x0001, - .version = 0x0100, - }, -}; - int __init mk712_init(void) { + int err; - if(!request_region(mk712_io, 8, "mk712")) - { + if (!request_region(mk712_io, 8, "mk712")) { printk(KERN_WARNING "mk712: unable to get IO region\n"); return -ENODEV; } @@ -188,28 +169,49 @@ int __init mk712_init(void) (inw(mk712_io + MK712_Y) & 0xf000) || (inw(mk712_io + MK712_STATUS) & 0xf333)) { printk(KERN_WARNING "mk712: device not present\n"); - release_region(mk712_io, 8); - return -ENODEV; + err = -ENODEV; + goto fail; } - if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712", &mk712_dev)) - { + if (!(mk712_dev = input_allocate_device())) { + printk(KERN_ERR "mk712: not enough memory\n"); + err = -ENOMEM; + goto fail; + } + + mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; + mk712_dev->phys = "isa0260/input0"; + mk712_dev->id.bustype = BUS_ISA; + mk712_dev->id.vendor = 0x0005; + mk712_dev->id.product = 0x0001; + mk712_dev->id.version = 0x0100; + + mk712_dev->open = mk712_open; + mk712_dev->close = mk712_close; + + mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0); + input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0); + + if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { printk(KERN_WARNING "mk712: unable to get IRQ\n"); - release_region(mk712_io, 8); - return -EBUSY; + err = -EBUSY; + goto fail; } - input_register_device(&mk712_dev); - - printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq); - + input_register_device(mk712_dev); return 0; + + fail: input_free_device(mk712_dev); + release_region(mk712_io, 8); + return err; } static void __exit mk712_exit(void) { - input_unregister_device(&mk712_dev); - free_irq(mk712_irq, &mk712_dev); + input_unregister_device(mk712_dev); + free_irq(mk712_irq, mk712_dev); release_region(mk712_io, 8); } diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index aa8ee7842179..1d0d37eeef6e 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -51,14 +51,12 @@ MODULE_LICENSE("GPL"); #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3]) #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0]) -static char *mtouch_name = "MicroTouch Serial TouchScreen"; - /* * Per-touchscreen data. */ struct mtouch { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; int idx; unsigned char data[MTOUCH_MAX_LENGTH]; @@ -67,7 +65,7 @@ struct mtouch { static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs) { - struct input_dev *dev = &mtouch->dev; + struct input_dev *dev = mtouch->dev; if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) { input_regs(dev, regs); @@ -116,9 +114,11 @@ static void mtouch_disconnect(struct serio *serio) { struct mtouch* mtouch = serio_get_drvdata(serio); - input_unregister_device(&mtouch->dev); + input_get_device(mtouch->dev); + input_unregister_device(mtouch->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_put_device(mtouch->dev); kfree(mtouch); } @@ -131,46 +131,46 @@ static void mtouch_disconnect(struct serio *serio) static int mtouch_connect(struct serio *serio, struct serio_driver *drv) { struct mtouch *mtouch; + struct input_dev *input_dev; int err; - if (!(mtouch = kmalloc(sizeof(*mtouch), GFP_KERNEL))) - return -ENOMEM; - - memset(mtouch, 0, sizeof(*mtouch)); - - init_input_dev(&mtouch->dev); - mtouch->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - mtouch->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - input_set_abs_params(&mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); - input_set_abs_params(&mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0); + mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mtouch || !input_dev) { + err = -ENOMEM; + goto fail; + } mtouch->serio = serio; - + mtouch->dev = input_dev; sprintf(mtouch->phys, "%s/input0", serio->phys); - mtouch->dev.private = mtouch; - mtouch->dev.name = mtouch_name; - mtouch->dev.phys = mtouch->phys; - mtouch->dev.id.bustype = BUS_RS232; - mtouch->dev.id.vendor = SERIO_MICROTOUCH; - mtouch->dev.id.product = 0; - mtouch->dev.id.version = 0x0100; + input_dev->private = mtouch; + input_dev->name = "MicroTouch Serial TouchScreen"; + input_dev->phys = mtouch->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_MICROTOUCH; + input_dev->id.product = 0; + input_dev->id.version = 0x0100; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); + input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0); serio_set_drvdata(serio, mtouch); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(mtouch); - return err; - } + if (err) + goto fail; - input_register_device(&mtouch->dev); - - printk(KERN_INFO "input: %s on %s\n", mtouch->dev.name, serio->phys); + input_register_device(mtouch->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(mtouch); + return err; } /* From b416f2e452b6c0f5075145bb7301f7f3d44d8ed5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:50 -0500 Subject: [PATCH 0617/1940] [PATCH] Input: convert sonypi to dynamic input_dev allocation Input: convert sonypi to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/char/sonypi.c | 92 +++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 36ae9ad2598c..a4873684f22c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -424,10 +424,6 @@ static struct sonypi_eventtypes { #define SONYPI_BUF_SIZE 128 -/* The name of the devices for the input device drivers */ -#define SONYPI_JOG_INPUTNAME "Sony Vaio Jogdial" -#define SONYPI_KEY_INPUTNAME "Sony Vaio Keys" - /* Correspondance table between sonypi events and input layer events */ static struct { int sonypiev; @@ -490,8 +486,8 @@ static struct sonypi_device { struct fasync_struct *fifo_async; int open_count; int model; - struct input_dev input_jog_dev; - struct input_dev input_key_dev; + struct input_dev *input_jog_dev; + struct input_dev *input_key_dev; struct work_struct input_work; struct kfifo *input_fifo; spinlock_t input_fifo_lock; @@ -779,8 +775,8 @@ static void input_keyrelease(void *data) static void sonypi_report_input_event(u8 event) { - struct input_dev *jog_dev = &sonypi_device.input_jog_dev; - struct input_dev *key_dev = &sonypi_device.input_key_dev; + struct input_dev *jog_dev = sonypi_device.input_jog_dev; + struct input_dev *key_dev = sonypi_device.input_key_dev; struct sonypi_keypress kp = { NULL }; int i; @@ -1203,6 +1199,47 @@ static struct device_driver sonypi_driver = { .shutdown = sonypi_shutdown, }; +static int __devinit sonypi_create_input_devices(void) +{ + struct input_dev *jog_dev; + struct input_dev *key_dev; + int i; + + sonypi_device.input_jog_dev = jog_dev = input_allocate_device(); + if (!jog_dev) + return -ENOMEM; + + jog_dev->name = "Sony Vaio Jogdial"; + jog_dev->id.bustype = BUS_ISA; + jog_dev->id.vendor = PCI_VENDOR_ID_SONY; + + jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); + jog_dev->relbit[0] = BIT(REL_WHEEL); + + sonypi_device.input_key_dev = key_dev = input_allocate_device(); + if (!key_dev) { + input_free_device(jog_dev); + sonypi_device.input_jog_dev = NULL; + return -ENOMEM; + } + + key_dev->name = "Sony Vaio Keys"; + key_dev->id.bustype = BUS_ISA; + key_dev->id.vendor = PCI_VENDOR_ID_SONY; + + /* Initialize the Input Drivers: special keys */ + key_dev->evbit[0] = BIT(EV_KEY); + for (i = 0; sonypi_inputkeys[i].sonypiev; i++) + if (sonypi_inputkeys[i].inputev) + set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit); + + input_register_device(jog_dev); + input_register_device(key_dev); + + return 0; +} + static int __devinit sonypi_probe(void) { int i, ret; @@ -1298,34 +1335,10 @@ static int __devinit sonypi_probe(void) } if (useinput) { - /* Initialize the Input Drivers: jogdial */ - int i; - sonypi_device.input_jog_dev.evbit[0] = - BIT(EV_KEY) | BIT(EV_REL); - sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = - BIT(BTN_MIDDLE); - sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); - sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; - sonypi_device.input_jog_dev.id.bustype = BUS_ISA; - sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; - input_register_device(&sonypi_device.input_jog_dev); - printk(KERN_INFO "%s input method installed.\n", - sonypi_device.input_jog_dev.name); - - /* Initialize the Input Drivers: special keys */ - sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY); - for (i = 0; sonypi_inputkeys[i].sonypiev; i++) - if (sonypi_inputkeys[i].inputev) - set_bit(sonypi_inputkeys[i].inputev, - sonypi_device.input_key_dev.keybit); - sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; - sonypi_device.input_key_dev.id.bustype = BUS_ISA; - sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; - - input_register_device(&sonypi_device.input_key_dev); - printk(KERN_INFO "%s input method installed.\n", - sonypi_device.input_key_dev.name); + ret = sonypi_create_input_devices(); + if (ret) + goto out_inputdevices; spin_lock_init(&sonypi_device.input_fifo_lock); sonypi_device.input_fifo = @@ -1375,8 +1388,9 @@ static int __devinit sonypi_probe(void) out_platformdev: kfifo_free(sonypi_device.input_fifo); out_infifo: - input_unregister_device(&sonypi_device.input_key_dev); - input_unregister_device(&sonypi_device.input_jog_dev); + input_unregister_device(sonypi_device.input_key_dev); + input_unregister_device(sonypi_device.input_jog_dev); +out_inputdevices: free_irq(sonypi_device.irq, sonypi_irq); out_reqirq: release_region(sonypi_device.ioport1, sonypi_device.region_size); @@ -1402,8 +1416,8 @@ static void __devexit sonypi_remove(void) platform_device_unregister(sonypi_device.pdev); if (useinput) { - input_unregister_device(&sonypi_device.input_key_dev); - input_unregister_device(&sonypi_device.input_jog_dev); + input_unregister_device(sonypi_device.input_key_dev); + input_unregister_device(sonypi_device.input_jog_dev); kfifo_free(sonypi_device.input_fifo); } From 88789672424375882166df86adde9dd77ead630e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:43 -0500 Subject: [PATCH 0618/1940] [PATCH] Input: convert onetouch to dynamic input_dev allocation Input: convert onetouch to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/onetouch.c | 105 +++++++++++++++++---------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 2c9402dc702b..89401a59f952 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -5,7 +5,7 @@ * Copyright (c) 2005 Nick Sillik * * Initial work by: - * Copyright (c) 2003 Erik Thyren + * Copyright (c) 2003 Erik Thyren * * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann) * @@ -46,7 +46,7 @@ void onetouch_release_input(void *onetouch_); struct usb_onetouch { char name[128]; char phys[64]; - struct input_dev dev; /* input device interface */ + struct input_dev *dev; /* input device interface */ struct usb_device *udev; /* usb device */ struct urb *irq; /* urb for interrupt in report */ @@ -58,7 +58,7 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) { struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; - struct input_dev *dev = &onetouch->dev; + struct input_dev *dev = onetouch->dev; int status; switch (urb->status) { @@ -74,11 +74,9 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) } input_regs(dev, regs); - - input_report_key(&onetouch->dev, ONETOUCH_BUTTON, - data[0] & 0x02); - + input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02); input_sync(dev); + resubmit: status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) @@ -113,8 +111,8 @@ int onetouch_connect_input(struct us_data *ss) struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_onetouch *onetouch; + struct input_dev *input_dev; int pipe, maxp; - char path[64]; interface = ss->pusb_intf->cur_altsetting; @@ -122,62 +120,62 @@ int onetouch_connect_input(struct us_data *ss) return -ENODEV; endpoint = &interface->endpoint[2].desc; - if(!(endpoint->bEndpointAddress & USB_DIR_IN)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) return -ENODEV; - if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL))) - return -ENOMEM; + onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!onetouch || !input_dev) + goto fail1; onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, SLAB_ATOMIC, &onetouch->data_dma); - if (!onetouch->data){ - kfree(onetouch); - return -ENOMEM; - } + if (!onetouch->data) + goto fail1; onetouch->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!onetouch->irq){ - kfree(onetouch); - usb_buffer_free(udev, ONETOUCH_PKT_LEN, - onetouch->data, onetouch->data_dma); - return -ENODEV; - } - + if (!onetouch->irq) + goto fail2; onetouch->udev = udev; - - set_bit(EV_KEY, onetouch->dev.evbit); - set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit); - clear_bit(0, onetouch->dev.keybit); - - onetouch->dev.private = onetouch; - onetouch->dev.open = usb_onetouch_open; - onetouch->dev.close = usb_onetouch_close; - - usb_make_path(udev, path, sizeof(path)); - sprintf(onetouch->phys, "%s/input0", path); - - onetouch->dev.name = onetouch->name; - onetouch->dev.phys = onetouch->phys; - - usb_to_input_id(udev, &onetouch->dev.id); - - onetouch->dev.dev = &udev->dev; + onetouch->dev = input_dev; if (udev->manufacturer) - strcat(onetouch->name, udev->manufacturer); - if (udev->product) - sprintf(onetouch->name, "%s %s", onetouch->name, - udev->product); + strlcpy(onetouch->name, udev->manufacturer, + sizeof(onetouch->name)); + if (udev->product) { + if (udev->manufacturer) + strlcat(onetouch->name, " ", sizeof(onetouch->name)); + strlcat(onetouch->name, udev->product, sizeof(onetouch->name)); + } + if (!strlen(onetouch->name)) - sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x", - onetouch->dev.id.vendor, onetouch->dev.id.product); + snprintf(onetouch->name, sizeof(onetouch->name), + "Maxtor Onetouch %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys)); + strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys)); + + input_dev->name = onetouch->name; + input_dev->phys = onetouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &udev->dev; + + set_bit(EV_KEY, input_dev->evbit); + set_bit(ONETOUCH_BUTTON, input_dev->keybit); + clear_bit(0, input_dev->keybit); + + input_dev->private = onetouch; + input_dev->open = usb_onetouch_open; + input_dev->close = usb_onetouch_close; usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, (maxp > 8 ? 8 : maxp), @@ -188,10 +186,15 @@ int onetouch_connect_input(struct us_data *ss) ss->extra_destructor = onetouch_release_input; ss->extra = onetouch; - input_register_device(&onetouch->dev); - printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path); + input_register_device(onetouch->dev); return 0; + + fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN, + onetouch->data, onetouch->data_dma); + fail1: kfree(onetouch); + input_free_device(input_dev); + return -ENOMEM; } void onetouch_release_input(void *onetouch_) @@ -200,11 +203,9 @@ void onetouch_release_input(void *onetouch_) if (onetouch) { usb_kill_urb(onetouch->irq); - input_unregister_device(&onetouch->dev); + input_unregister_device(onetouch->dev); usb_free_urb(onetouch->irq); usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma); - printk(KERN_INFO "usb-input: deregistering %s\n", - onetouch->dev.name); } } From 76b7cddfd576331761e945a508254abad11039e9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:51 -0500 Subject: [PATCH 0619/1940] [PATCH] Input: convert driver/input/misc to dynamic input_dev allocation Input: convert driver/input/misc to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/m68kspkr.c | 36 +++++++++++++-------------- drivers/input/misc/pcspkr.c | 30 +++++++++++------------ drivers/input/misc/sparcspkr.c | 45 +++++++++++++++++----------------- 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index 64abdd98d482..04489ad7702a 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c @@ -24,9 +24,7 @@ MODULE_AUTHOR("Richard Zidlicky "); MODULE_DESCRIPTION("m68k beeper driver"); MODULE_LICENSE("GPL"); -static char m68kspkr_name[] = "m68k beeper"; -static char m68kspkr_phys[] = "m68k/generic"; -static struct input_dev m68kspkr_dev; +static struct input_dev *m68kspkr_dev; static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { @@ -51,32 +49,34 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int static int __init m68kspkr_init(void) { - if (!mach_beep){ - printk("%s: no lowlevel beep support\n", m68kspkr_name); - return -1; + if (!mach_beep) { + printk(KERN_INFO "m68kspkr: no lowlevel beep support\n"); + return -ENODEV; } - m68kspkr_dev.evbit[0] = BIT(EV_SND); - m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - m68kspkr_dev.event = m68kspkr_event; + m68kspkr_dev = input_allocate_device(); + if (!m68kspkr_dev) + return -ENOMEM; - m68kspkr_dev.name = m68kspkr_name; - m68kspkr_dev.phys = m68kspkr_phys; - m68kspkr_dev.id.bustype = BUS_HOST; - m68kspkr_dev.id.vendor = 0x001f; - m68kspkr_dev.id.product = 0x0001; - m68kspkr_dev.id.version = 0x0100; + m68kspkr_dev->name = "m68k beeper"; + m68kspkr_dev->phys = "m68k/generic"; + m68kspkr_dev->id.bustype = BUS_HOST; + m68kspkr_dev->id.vendor = 0x001f; + m68kspkr_dev->id.product = 0x0001; + m68kspkr_dev->id.version = 0x0100; - input_register_device(&m68kspkr_dev); + m68kspkr_dev->evbit[0] = BIT(EV_SND); + m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + m68kspkr_dev->event = m68kspkr_event; - printk(KERN_INFO "input: %s\n", m68kspkr_name); + input_register_device(m68kspkr_dev); return 0; } static void __exit m68kspkr_exit(void) { - input_unregister_device(&m68kspkr_dev); + input_unregister_device(m68kspkr_dev); } module_init(m68kspkr_init); diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 3013194f462b..e34633c37fdd 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -23,9 +23,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); -static char pcspkr_name[] = "PC Speaker"; -static char pcspkr_phys[] = "isa0061/input0"; -static struct input_dev pcspkr_dev; +static struct input_dev *pcspkr_dev; static DEFINE_SPINLOCK(i8253_beep_lock); @@ -68,27 +66,29 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c static int __init pcspkr_init(void) { - pcspkr_dev.evbit[0] = BIT(EV_SND); - pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - pcspkr_dev.event = pcspkr_event; + pcspkr_dev = input_allocate_device(); + if (!pcspkr_dev) + return -ENOMEM; - pcspkr_dev.name = pcspkr_name; - pcspkr_dev.phys = pcspkr_phys; - pcspkr_dev.id.bustype = BUS_ISA; - pcspkr_dev.id.vendor = 0x001f; - pcspkr_dev.id.product = 0x0001; - pcspkr_dev.id.version = 0x0100; + pcspkr_dev->name = "PC Speaker"; + pcspkr_dev->name = "isa0061/input0"; + pcspkr_dev->id.bustype = BUS_ISA; + pcspkr_dev->id.vendor = 0x001f; + pcspkr_dev->id.product = 0x0001; + pcspkr_dev->id.version = 0x0100; - input_register_device(&pcspkr_dev); + pcspkr_dev->evbit[0] = BIT(EV_SND); + pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + pcspkr_dev->event = pcspkr_event; - printk(KERN_INFO "input: %s\n", pcspkr_name); + input_register_device(pcspkr_dev); return 0; } static void __exit pcspkr_exit(void) { - input_unregister_device(&pcspkr_dev); + input_unregister_device(pcspkr_dev); /* turn off the speaker */ pcspkr_event(NULL, EV_SND, SND_BELL, 0); } diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index cdc3fb3d5f46..5778220a18d2 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -17,28 +17,24 @@ #endif MODULE_AUTHOR("David S. Miller "); -MODULE_DESCRIPTION("PC Speaker beeper driver"); +MODULE_DESCRIPTION("Sparc Speaker beeper driver"); MODULE_LICENSE("GPL"); static unsigned long beep_iobase; - -static char *sparcspkr_isa_name = "Sparc ISA Speaker"; -static char *sparcspkr_ebus_name = "Sparc EBUS Speaker"; -static char *sparcspkr_phys = "sparc/input0"; -static struct input_dev sparcspkr_dev; +static struct input_dev *sparcspkr_dev; DEFINE_SPINLOCK(beep_lock); static void __init init_sparcspkr_struct(void) { - sparcspkr_dev.evbit[0] = BIT(EV_SND); - sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + sparcspkr_dev->evbit[0] = BIT(EV_SND); + sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - sparcspkr_dev.phys = sparcspkr_phys; - sparcspkr_dev.id.bustype = BUS_ISA; - sparcspkr_dev.id.vendor = 0x001f; - sparcspkr_dev.id.product = 0x0001; - sparcspkr_dev.id.version = 0x0100; + sparcspkr_dev->phys = "sparc/input0"; + sparcspkr_dev->id.bustype = BUS_ISA; + sparcspkr_dev->id.vendor = 0x001f; + sparcspkr_dev->id.product = 0x0001; + sparcspkr_dev->id.version = 0x0100; } static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -84,14 +80,15 @@ static int __init init_ebus_beep(struct linux_ebus_device *edev) { beep_iobase = edev->resource[0].start; - init_sparcspkr_struct(); + sparcspkr_dev = input_allocate_device(); + if (!sparcspkr_dev) + return -ENOMEM; - sparcspkr_dev.name = sparcspkr_ebus_name; - sparcspkr_dev.event = ebus_spkr_event; + sparcspkr_dev->name = "Sparc EBUS Speaker"; + sparcspkr_dev->event = ebus_spkr_event; - input_register_device(&sparcspkr_dev); + input_register_device(sparcspkr_dev); - printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name); return 0; } @@ -137,15 +134,17 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev) { beep_iobase = isa_dev->resource.start; + sparcspkr_dev = input_allocate_device(); + if (!sparcspkr_dev) + return -ENOMEM; + init_sparcspkr_struct(); - sparcspkr_dev.name = sparcspkr_isa_name; - sparcspkr_dev.event = isa_spkr_event; - sparcspkr_dev.id.bustype = BUS_ISA; + sparcspkr_dev->name = "Sparc ISA Speaker"; + sparcspkr_dev->event = isa_spkr_event; input_register_device(&sparcspkr_dev); - printk(KERN_INFO "input: %s\n", sparcspkr_isa_name); return 0; } #endif @@ -182,7 +181,7 @@ static int __init sparcspkr_init(void) static void __exit sparcspkr_exit(void) { - input_unregister_device(&sparcspkr_dev); + input_unregister_device(sparcspkr_dev); } module_init(sparcspkr_init); From b7df3910c1298fee8ed7b9dfd2da74b85df5539c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:53 -0500 Subject: [PATCH 0620/1940] [PATCH] drivers/media: convert to dynamic input_dev allocation Input: convert drivers/media to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/media/common/ir-common.c | 1 - drivers/media/dvb/cinergyT2/cinergyT2.c | 108 +++++++++++++------- drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 50 +++++---- drivers/media/dvb/dvb-usb/dvb-usb.h | 3 +- drivers/media/dvb/ttpci/av7110_ir.c | 37 ++++--- drivers/media/dvb/ttpci/budget-ci.c | 24 +++-- drivers/media/dvb/ttusb-dec/ttusb_dec.c | 51 +++++---- drivers/media/video/bttvp.h | 2 +- drivers/media/video/cx88/cx88-input.c | 58 ++++++----- drivers/media/video/ir-kbd-gpio.c | 52 +++++----- drivers/media/video/ir-kbd-i2c.c | 33 +++--- drivers/media/video/saa7134/saa7134-input.c | 39 +++---- drivers/media/video/saa7134/saa7134.h | 2 +- 13 files changed, 268 insertions(+), 192 deletions(-) diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index a0e700d7a4a4..06f4d4686a6c 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c @@ -252,7 +252,6 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, if (ir_codes) memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); - init_input_dev(dev); dev->keycode = ir->ir_codes; dev->keycodesize = sizeof(IR_KEYTAB_TYPE); dev->keycodemax = IR_KEYTAB_SIZE; diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 6db0929ef53d..a1607e7d6d6b 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -137,7 +137,8 @@ struct cinergyt2 { struct urb *stream_urb [STREAM_URB_COUNT]; #ifdef ENABLE_RC - struct input_dev rc_input_dev; + struct input_dev *rc_input_dev; + char phys[64]; struct work_struct rc_query_work; int rc_input_event; u32 rc_last_code; @@ -683,6 +684,7 @@ static struct dvb_device cinergyt2_fe_template = { }; #ifdef ENABLE_RC + static void cinergyt2_query_rc (void *data) { struct cinergyt2 *cinergyt2 = data; @@ -703,7 +705,7 @@ static void cinergyt2_query_rc (void *data) /* stop key repeat */ if (cinergyt2->rc_input_event != KEY_MAX) { dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event); - input_report_key(&cinergyt2->rc_input_dev, + input_report_key(cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0); cinergyt2->rc_input_event = KEY_MAX; } @@ -722,7 +724,7 @@ static void cinergyt2_query_rc (void *data) /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; - for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) { + for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) { if (rc_keys[i + 0] == rc_events[n].type && rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) { cinergyt2->rc_input_event = rc_keys[i + 2]; @@ -736,11 +738,11 @@ static void cinergyt2_query_rc (void *data) cinergyt2->rc_last_code != ~0) { /* emit a key-up so the double event is recognized */ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); - input_report_key(&cinergyt2->rc_input_dev, + input_report_key(cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0); } dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event); - input_report_key(&cinergyt2->rc_input_dev, + input_report_key(cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1); cinergyt2->rc_last_code = rc_events[n].value; } @@ -752,7 +754,59 @@ static void cinergyt2_query_rc (void *data) up(&cinergyt2->sem); } -#endif + +static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) +{ + struct input_dev *input_dev; + int i; + + cinergyt2->rc_input_dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); + strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); + cinergyt2->rc_input_event = KEY_MAX; + cinergyt2->rc_last_code = ~0; + INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); + + input_dev->name = DRIVER_NAME " remote control"; + input_dev->phys = cinergyt2->phys; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + for (i = 0; ARRAY_SIZE(rc_keys); i += 3) + set_bit(rc_keys[i + 2], input_dev->keybit); + input_dev->keycodesize = 0; + input_dev->keycodemax = 0; + + input_register_device(cinergyt2->rc_input_dev); + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); +} + +static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) +{ + cancel_delayed_work(&cinergyt2->rc_query_work); + flush_scheduled_work(); + input_unregister_device(cinergyt2->rc_input_dev); +} + +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) +{ + cancel_delayed_work(&cinergyt2->rc_query_work); +} + +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) +{ + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); +} + +#else + +static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; } +static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } + +#endif /* ENABLE_RC */ static void cinergyt2_query (void *data) { @@ -789,9 +843,6 @@ static int cinergyt2_probe (struct usb_interface *intf, { struct cinergyt2 *cinergyt2; int err; -#ifdef ENABLE_RC - int i; -#endif if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { dprintk(1, "out of memory?!?\n"); @@ -846,30 +897,17 @@ static int cinergyt2_probe (struct usb_interface *intf, &cinergyt2_fe_template, cinergyt2, DVB_DEVICE_FRONTEND); -#ifdef ENABLE_RC - cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - cinergyt2->rc_input_dev.keycodesize = 0; - cinergyt2->rc_input_dev.keycodemax = 0; - cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control"; + err = cinergyt2_register_rc(cinergyt2); + if (err) + goto bailout; - for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) - set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit); - - input_register_device(&cinergyt2->rc_input_dev); - - cinergyt2->rc_input_event = KEY_MAX; - cinergyt2->rc_last_code = ~0; - - INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); - schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); -#endif return 0; bailout: dvb_dmxdev_release(&cinergyt2->dmxdev); dvb_dmx_release(&cinergyt2->demux); - dvb_unregister_adapter (&cinergyt2->adapter); - cinergyt2_free_stream_urbs (cinergyt2); + dvb_unregister_adapter(&cinergyt2->adapter); + cinergyt2_free_stream_urbs(cinergyt2); kfree(cinergyt2); return -ENOMEM; } @@ -881,11 +919,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf) if (down_interruptible(&cinergyt2->sem)) return; -#ifdef ENABLE_RC - cancel_delayed_work(&cinergyt2->rc_query_work); - flush_scheduled_work(); - input_unregister_device(&cinergyt2->rc_input_dev); -#endif + cinergyt2_unregister_rc(cinergyt2); cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); dvb_net_release(&cinergyt2->dvbnet); @@ -908,9 +942,8 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) if (state.event > PM_EVENT_ON) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); -#ifdef ENABLE_RC - cancel_delayed_work(&cinergyt2->rc_query_work); -#endif + + cinergyt2_suspend_rc(cinergyt2); cancel_delayed_work(&cinergyt2->query_work); if (cinergyt2->streaming) cinergyt2_stop_stream_xfer(cinergyt2); @@ -938,9 +971,8 @@ static int cinergyt2_resume (struct usb_interface *intf) schedule_delayed_work(&cinergyt2->query_work, HZ/2); } -#ifdef ENABLE_RC - schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); -#endif + cinergyt2_resume_rc(cinergyt2); + up(&cinergyt2->sem); return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index fc7800f1743e..e5c6d9835e06 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -39,9 +39,9 @@ static void dvb_usb_read_remote_control(void *data) d->last_event = event; case REMOTE_KEY_REPEAT: deb_rc("key repeated\n"); - input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1); - input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); - input_sync(&d->rc_input_dev); + input_event(d->rc_input_dev, EV_KEY, event, 1); + input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(d->rc_input_dev); break; default: break; @@ -53,8 +53,8 @@ static void dvb_usb_read_remote_control(void *data) deb_rc("NO KEY PRESSED\n"); if (d->last_state != REMOTE_NO_KEY_PRESSED) { deb_rc("releasing event %d\n",d->last_event); - input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); - input_sync(&d->rc_input_dev); + input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(d->rc_input_dev); } d->last_state = REMOTE_NO_KEY_PRESSED; d->last_event = 0; @@ -63,8 +63,8 @@ static void dvb_usb_read_remote_control(void *data) deb_rc("KEY PRESSED\n"); deb_rc("pressing event %d\n",event); - input_event(&d->rc_input_dev, EV_KEY, event, 1); - input_sync(&d->rc_input_dev); + input_event(d->rc_input_dev, EV_KEY, event, 1); + input_sync(d->rc_input_dev); d->last_event = event; d->last_state = REMOTE_KEY_PRESSED; @@ -73,8 +73,8 @@ static void dvb_usb_read_remote_control(void *data) deb_rc("KEY_REPEAT\n"); if (d->last_state != REMOTE_NO_KEY_PRESSED) { deb_rc("repeating event %d\n",d->last_event); - input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2); - input_sync(&d->rc_input_dev); + input_event(d->rc_input_dev, EV_KEY, d->last_event, 2); + input_sync(d->rc_input_dev); d->last_state = REMOTE_KEY_REPEAT; } default: @@ -89,24 +89,30 @@ static void dvb_usb_read_remote_control(void *data) int dvb_usb_remote_init(struct dvb_usb_device *d) { int i; + if (d->props.rc_key_map == NULL || d->props.rc_query == NULL || dvb_usb_disable_rc_polling) return 0; - /* Initialise the remote-control structures.*/ - init_input_dev(&d->rc_input_dev); + usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); + strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys)); - d->rc_input_dev.evbit[0] = BIT(EV_KEY); - d->rc_input_dev.keycodesize = sizeof(unsigned char); - d->rc_input_dev.keycodemax = KEY_MAX; - d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver"; + d->rc_input_dev = input_allocate_device(); + if (!d->rc_input_dev) + return -ENOMEM; + + d->rc_input_dev->evbit[0] = BIT(EV_KEY); + d->rc_input_dev->keycodesize = sizeof(unsigned char); + d->rc_input_dev->keycodemax = KEY_MAX; + d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver"; + d->rc_input_dev->phys = d->rc_phys; /* set the bits for the keys */ - deb_rc("key map size: %d\n",d->props.rc_key_map_size); + deb_rc("key map size: %d\n", d->props.rc_key_map_size); for (i = 0; i < d->props.rc_key_map_size; i++) { deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i); - set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit); + set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit); } /* Start the remote-control polling. */ @@ -114,14 +120,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) d->props.rc_interval = 100; /* default */ /* setting these two values to non-zero, we have to manage key repeats */ - d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval; - d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150; + d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval; + d->rc_input_dev->rep[REP_DELAY] = d->props.rc_interval + 150; - input_register_device(&d->rc_input_dev); + input_register_device(d->rc_input_dev); INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); - info("schedule remote query interval to %d msecs.",d->props.rc_interval); + info("schedule remote query interval to %d msecs.", d->props.rc_interval); schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); d->state |= DVB_USB_STATE_REMOTE; @@ -134,7 +140,7 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d) if (d->state & DVB_USB_STATE_REMOTE) { cancel_delayed_work(&d->rc_query_work); flush_scheduled_work(); - input_unregister_device(&d->rc_input_dev); + input_unregister_device(d->rc_input_dev); } d->state &= ~DVB_USB_STATE_REMOTE; return 0; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 0e4f1035b0dd..b4a1a98006c7 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -300,7 +300,8 @@ struct dvb_usb_device { int (*fe_init) (struct dvb_frontend *); /* remote control */ - struct input_dev rc_input_dev; + struct input_dev *rc_input_dev; + char rc_phys[64]; struct work_struct rc_query_work; u32 last_event; int last_state; diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 357a3728ec68..f5e59fc924af 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c @@ -15,7 +15,7 @@ static int av_cnt; static struct av7110 *av_list[4]; -static struct input_dev input_dev; +static struct input_dev *input_dev; static u16 key_map [256] = { KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, @@ -43,10 +43,10 @@ static u16 key_map [256] = { static void av7110_emit_keyup(unsigned long data) { - if (!data || !test_bit(data, input_dev.key)) + if (!data || !test_bit(data, input_dev->key)) return; - input_event(&input_dev, EV_KEY, data, !!0); + input_event(input_dev, EV_KEY, data, !!0); } @@ -112,13 +112,13 @@ static void av7110_emit_key(unsigned long parm) if (timer_pending(&keyup_timer)) { del_timer(&keyup_timer); if (keyup_timer.data != keycode || new_toggle != old_toggle) { - input_event(&input_dev, EV_KEY, keyup_timer.data, !!0); - input_event(&input_dev, EV_KEY, keycode, !0); + input_event(input_dev, EV_KEY, keyup_timer.data, !!0); + input_event(input_dev, EV_KEY, keycode, !0); } else - input_event(&input_dev, EV_KEY, keycode, 2); + input_event(input_dev, EV_KEY, keycode, 2); } else - input_event(&input_dev, EV_KEY, keycode, !0); + input_event(input_dev, EV_KEY, keycode, !0); keyup_timer.expires = jiffies + UP_TIMEOUT; keyup_timer.data = keycode; @@ -132,13 +132,13 @@ static void input_register_keys(void) { int i; - memset(input_dev.keybit, 0, sizeof(input_dev.keybit)); + memset(input_dev->keybit, 0, sizeof(input_dev->keybit)); - for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) { + for (i = 0; i < ARRAY_SIZE(key_map); i++) { if (key_map[i] > KEY_MAX) key_map[i] = 0; else if (key_map[i] > KEY_RESERVED) - set_bit(key_map[i], input_dev.keybit); + set_bit(key_map[i], input_dev->keybit); } } @@ -216,12 +216,17 @@ int __init av7110_ir_init(struct av7110 *av7110) init_timer(&keyup_timer); keyup_timer.data = 0; - input_dev.name = "DVB on-card IR receiver"; - set_bit(EV_KEY, input_dev.evbit); - set_bit(EV_REP, input_dev.evbit); + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + input_dev->name = "DVB on-card IR receiver"; + + set_bit(EV_KEY, input_dev->evbit); + set_bit(EV_REP, input_dev->evbit); input_register_keys(); - input_register_device(&input_dev); - input_dev.timer.function = input_repeat_key; + input_register_device(input_dev); + input_dev->timer.function = input_repeat_key; e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); if (e) { @@ -256,7 +261,7 @@ void __exit av7110_ir_exit(struct av7110 *av7110) if (av_cnt == 1) { del_timer_sync(&keyup_timer); remove_proc_entry("av7110_ir", NULL); - input_unregister_device(&input_dev); + input_unregister_device(input_dev); } av_cnt--; diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 2980db3ef22f..51c30ba68140 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -64,7 +64,7 @@ struct budget_ci { struct budget budget; - struct input_dev input_dev; + struct input_dev *input_dev; struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct ciintf_irq_tasklet; int slot_status; @@ -145,7 +145,7 @@ static void msp430_ir_debounce(unsigned long data) static void msp430_ir_interrupt(unsigned long data) { struct budget_ci *budget_ci = (struct budget_ci *) data; - struct input_dev *dev = &budget_ci->input_dev; + struct input_dev *dev = budget_ci->input_dev; unsigned int code = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; @@ -181,25 +181,27 @@ static void msp430_ir_interrupt(unsigned long data) static int msp430_ir_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; + struct input_dev *input_dev; int i; - memset(&budget_ci->input_dev, 0, sizeof(struct input_dev)); + budget_ci->input_dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name); - budget_ci->input_dev.name = budget_ci->ir_dev_name; - set_bit(EV_KEY, budget_ci->input_dev.evbit); + input_dev->name = budget_ci->ir_dev_name; - for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++) + set_bit(EV_KEY, input_dev->evbit); + for (i = 0; i < ARRAY_SIZE(key_map); i++) if (key_map[i]) - set_bit(key_map[i], budget_ci->input_dev.keybit); + set_bit(key_map[i], input_dev->keybit); - input_register_device(&budget_ci->input_dev); + input_register_device(budget_ci->input_dev); - budget_ci->input_dev.timer.function = msp430_ir_debounce; + input_dev->timer.function = msp430_ir_debounce; saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); - saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); return 0; @@ -208,7 +210,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) static void msp430_ir_deinit(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; - struct input_dev *dev = &budget_ci->input_dev; + struct input_dev *dev = budget_ci->input_dev; saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 3d08fc83a754..832d179f26fa 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -152,7 +152,8 @@ struct ttusb_dec { struct list_head filter_info_list; spinlock_t filter_info_list_lock; - struct input_dev rc_input_dev; + struct input_dev *rc_input_dev; + char rc_phys[64]; int active; /* Loaded successfully */ }; @@ -235,9 +236,9 @@ static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs) * this should/could be added later ... * for now lets report each signal as a key down and up*/ dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]); - input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1); - input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0); - input_sync(&dec->rc_input_dev); + input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); + input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); + input_sync(dec->rc_input_dev); } exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -1181,29 +1182,38 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) (unsigned long)dec); } -static void ttusb_init_rc( struct ttusb_dec *dec) +static int ttusb_init_rc(struct ttusb_dec *dec) { + struct input_dev *input_dev; u8 b[] = { 0x00, 0x01 }; int i; - init_input_dev(&dec->rc_input_dev); + usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); + strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); - dec->rc_input_dev.name = "ttusb_dec remote control"; - dec->rc_input_dev.evbit[0] = BIT(EV_KEY); - dec->rc_input_dev.keycodesize = sizeof(u16); - dec->rc_input_dev.keycodemax = 0x1a; - dec->rc_input_dev.keycode = rc_keys; + dec->rc_input_dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; - for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++) - set_bit(rc_keys[i], dec->rc_input_dev.keybit); + input_dev->name = "ttusb_dec remote control"; + input_dev->phys = dec->rc_phys; + input_dev->evbit[0] = BIT(EV_KEY); + input_dev->keycodesize = sizeof(u16); + input_dev->keycodemax = 0x1a; + input_dev->keycode = rc_keys; - input_register_device(&dec->rc_input_dev); + for (i = 0; i < ARRAY_SIZE(rc_keys); i++) + set_bit(rc_keys[i], input_dev->keybit); - if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) { + input_register_device(input_dev); + + if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) printk("%s: usb_submit_urb failed\n",__FUNCTION__); - } + /* enable irq pipe */ ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); + + return 0; } static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) @@ -1513,7 +1523,7 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec) * As the irq is submitted after the interface is changed, * this is the best method i figured out. * Any others?*/ - if(dec->interface == TTUSB_DEC_INTERFACE_IN) + if (dec->interface == TTUSB_DEC_INTERFACE_IN) usb_kill_urb(dec->irq_urb); usb_free_urb(dec->irq_urb); @@ -1521,7 +1531,10 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec) usb_buffer_free(dec->udev,IRQ_PACKET_SIZE, dec->irq_buffer, dec->irq_dma_handle); - input_unregister_device(&dec->rc_input_dev); + if (dec->rc_input_dev) { + input_unregister_device(dec->rc_input_dev); + dec->rc_input_dev = NULL; + } } @@ -1659,7 +1672,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN); - if(enable_rc) + if (enable_rc) ttusb_init_rc(dec); return 0; diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 7a312f79340a..e0e7c7a84bc5 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -240,7 +240,7 @@ struct bttv_pll_info { /* for gpio-connected remote control */ struct bttv_input { - struct input_dev dev; + struct input_dev *dev; struct ir_input_state ir; char name[32]; char phys[32]; diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index d81b21d6e05d..c27fe4c36f69 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -260,7 +260,7 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { struct cx88_IR { struct cx88_core *core; - struct input_dev input; + struct input_dev *input; struct ir_input_state ir; char name[32]; char phys[32]; @@ -315,23 +315,23 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) if (ir->mask_keydown) { /* bit set on keydown */ if (gpio & ir->mask_keydown) { - ir_input_keydown(&ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data, data); } else { - ir_input_nokey(&ir->input, &ir->ir); + ir_input_nokey(ir->input, &ir->ir); } } else if (ir->mask_keyup) { /* bit cleared on keydown */ if (0 == (gpio & ir->mask_keyup)) { - ir_input_keydown(&ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data, data); } else { - ir_input_nokey(&ir->input, &ir->ir); + ir_input_nokey(ir->input, &ir->ir); } } else { /* can't distinguish keydown/up :-/ */ - ir_input_keydown(&ir->input, &ir->ir, data, data); - ir_input_nokey(&ir->input, &ir->ir); + ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_nokey(ir->input, &ir->ir); } } @@ -357,13 +357,19 @@ static void cx88_ir_work(void *data) int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) { struct cx88_IR *ir; + struct input_dev *input_dev; IR_KEYTAB_TYPE *ir_codes = NULL; int ir_type = IR_TYPE_OTHER; - ir = kmalloc(sizeof(*ir), GFP_KERNEL); - if (NULL == ir) + ir = kzalloc(sizeof(*ir), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ir || !input_dev) { + kfree(ir); + input_free_device(input_dev); return -ENOMEM; - memset(ir, 0, sizeof(*ir)); + } + + ir->input = input_dev; /* detect & configure */ switch (core->board) { @@ -425,6 +431,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) if (NULL == ir_codes) { kfree(ir); + input_free_device(input_dev); return -ENODEV; } @@ -433,19 +440,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) cx88_boards[core->board].name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); - ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes); - ir->input.name = ir->name; - ir->input.phys = ir->phys; - ir->input.id.bustype = BUS_PCI; - ir->input.id.version = 1; + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->name = ir->name; + input_dev->phys = ir->phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; if (pci->subsystem_vendor) { - ir->input.id.vendor = pci->subsystem_vendor; - ir->input.id.product = pci->subsystem_device; + input_dev->id.vendor = pci->subsystem_vendor; + input_dev->id.product = pci->subsystem_device; } else { - ir->input.id.vendor = pci->vendor; - ir->input.id.product = pci->device; + input_dev->id.vendor = pci->vendor; + input_dev->id.product = pci->device; } - ir->input.dev = &pci->dev; + input_dev->cdev.dev = &pci->dev; /* record handles to ourself */ ir->core = core; @@ -465,8 +472,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) } /* all done */ - input_register_device(&ir->input); - printk("%s: registered IR remote control\n", core->name); + input_register_device(ir->input); return 0; } @@ -484,7 +490,7 @@ int cx88_ir_fini(struct cx88_core *core) flush_scheduled_work(); } - input_unregister_device(&ir->input); + input_unregister_device(ir->input); kfree(ir); /* done */ @@ -515,7 +521,7 @@ void cx88_ir_irq(struct cx88_core *core) if (!ir->scount) { /* nothing to sample */ if (ir->ir.keypressed && time_after(jiffies, ir->release)) - ir_input_nokey(&ir->input, &ir->ir); + ir_input_nokey(ir->input, &ir->ir); return; } @@ -557,7 +563,7 @@ void cx88_ir_irq(struct cx88_core *core) ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f); - ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff); + ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff); ir->release = jiffies + msecs_to_jiffies(120); break; case CX88_BOARD_HAUPPAUGE: @@ -566,7 +572,7 @@ void cx88_ir_irq(struct cx88_core *core) ir_dprintk("biphase decoded: %x\n", ircode); if ((ircode & 0xfffff000) != 0x3000) break; - ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode); + ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); ir->release = jiffies + msecs_to_jiffies(120); break; } diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c index cf292da8fdd5..234151e48edc 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/ir-kbd-gpio.c @@ -158,7 +158,7 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { struct IR { struct bttv_sub_device *sub; - struct input_dev input; + struct input_dev *input; struct ir_input_state ir; char name[32]; char phys[32]; @@ -217,23 +217,23 @@ static void ir_handle_key(struct IR *ir) if (ir->mask_keydown) { /* bit set on keydown */ if (gpio & ir->mask_keydown) { - ir_input_keydown(&ir->input,&ir->ir,data,data); + ir_input_keydown(ir->input, &ir->ir, data, data); } else { - ir_input_nokey(&ir->input,&ir->ir); + ir_input_nokey(ir->input, &ir->ir); } } else if (ir->mask_keyup) { /* bit cleared on keydown */ if (0 == (gpio & ir->mask_keyup)) { - ir_input_keydown(&ir->input,&ir->ir,data,data); + ir_input_keydown(ir->input, &ir->ir, data, data); } else { - ir_input_nokey(&ir->input,&ir->ir); + ir_input_nokey(ir->input, &ir->ir); } } else { /* can't disturgissh keydown/up :-/ */ - ir_input_keydown(&ir->input,&ir->ir,data,data); - ir_input_nokey(&ir->input,&ir->ir); + ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_nokey(ir->input, &ir->ir); } } @@ -268,13 +268,17 @@ static int ir_probe(struct device *dev) { struct bttv_sub_device *sub = to_bttv_sub_dev(dev); struct IR *ir; + struct input_dev *input_dev; IR_KEYTAB_TYPE *ir_codes = NULL; int ir_type = IR_TYPE_OTHER; - ir = kmalloc(sizeof(*ir),GFP_KERNEL); - if (NULL == ir) + ir = kzalloc(sizeof(*ir), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ir || !input_dev) { + kfree(ir); + input_free_device(input_dev); return -ENOMEM; - memset(ir,0,sizeof(*ir)); + } /* detect & configure */ switch (sub->core->type) { @@ -328,6 +332,7 @@ static int ir_probe(struct device *dev) } if (NULL == ir_codes) { kfree(ir); + input_free_device(input_dev); return -ENODEV; } @@ -341,19 +346,19 @@ static int ir_probe(struct device *dev) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(sub->core->pci)); - ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes); - ir->input.name = ir->name; - ir->input.phys = ir->phys; - ir->input.id.bustype = BUS_PCI; - ir->input.id.version = 1; + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->name = ir->name; + input_dev->phys = ir->phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; if (sub->core->pci->subsystem_vendor) { - ir->input.id.vendor = sub->core->pci->subsystem_vendor; - ir->input.id.product = sub->core->pci->subsystem_device; + input_dev->id.vendor = sub->core->pci->subsystem_vendor; + input_dev->id.product = sub->core->pci->subsystem_device; } else { - ir->input.id.vendor = sub->core->pci->vendor; - ir->input.id.product = sub->core->pci->device; + input_dev->id.vendor = sub->core->pci->vendor; + input_dev->id.product = sub->core->pci->device; } - ir->input.dev = &sub->core->pci->dev; + input_dev->cdev.dev = &sub->core->pci->dev; if (ir->polling) { INIT_WORK(&ir->work, ir_work, ir); @@ -364,9 +369,8 @@ static int ir_probe(struct device *dev) } /* all done */ - dev_set_drvdata(dev,ir); - input_register_device(&ir->input); - printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys); + dev_set_drvdata(dev, ir); + input_register_device(ir->input); return 0; } @@ -380,7 +384,7 @@ static int ir_remove(struct device *dev) flush_scheduled_work(); } - input_unregister_device(&ir->input); + input_unregister_device(ir->input); kfree(ir); return 0; } diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 67105b9804a2..9703d3d351f9 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -121,10 +121,9 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { }; -struct IR; struct IR { struct i2c_client c; - struct input_dev input; + struct input_dev *input; struct ir_input_state ir; struct work_struct work; @@ -271,9 +270,9 @@ static void ir_key_poll(struct IR *ir) } if (0 == rc) { - ir_input_nokey(&ir->input,&ir->ir); + ir_input_nokey(ir->input, &ir->ir); } else { - ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw); + ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw); } } @@ -318,11 +317,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr, char *name; int ir_type; struct IR *ir; + struct input_dev *input_dev; - if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL))) + ir = kzalloc(sizeof(struct IR), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ir || !input_dev) { + kfree(ir); + input_free_device(input_dev); return -ENOMEM; - memset(ir,0,sizeof(*ir)); + } + ir->c = client_template; + ir->input = input_dev; i2c_set_clientdata(&ir->c, ir); ir->c.adapter = adap; @@ -375,13 +381,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir->c.dev.bus_id); /* init + register input device */ - ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes); - ir->input.id.bustype = BUS_I2C; - ir->input.name = ir->c.name; - ir->input.phys = ir->phys; - input_register_device(&ir->input); - printk(DEVNAME ": %s detected at %s [%s]\n", - ir->input.name,ir->input.phys,adap->name); + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->id.bustype = BUS_I2C; + input_dev->name = ir->c.name; + input_dev->phys = ir->phys; + + input_register_device(ir->input); /* start polling via eventd */ INIT_WORK(&ir->work, ir_work, ir); @@ -402,7 +407,7 @@ static int ir_detach(struct i2c_client *client) flush_scheduled_work(); /* unregister devices */ - input_unregister_device(&ir->input); + input_unregister_device(ir->input); i2c_detach_client(&ir->c); /* free memory */ diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 1f456c4d76f2..242cb235cf92 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -425,9 +425,9 @@ static int build_key(struct saa7134_dev *dev) if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(&ir->dev,&ir->ir,data,data); + ir_input_keydown(ir->dev, &ir->ir, data, data); } else { - ir_input_nokey(&ir->dev,&ir->ir); + ir_input_nokey(ir->dev, &ir->ir); } return 0; } @@ -456,6 +456,7 @@ static void saa7134_input_timer(unsigned long data) int saa7134_input_init1(struct saa7134_dev *dev) { struct saa7134_ir *ir; + struct input_dev *input_dev; IR_KEYTAB_TYPE *ir_codes = NULL; u32 mask_keycode = 0; u32 mask_keydown = 0; @@ -535,10 +536,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) return -ENODEV; } - ir = kmalloc(sizeof(*ir),GFP_KERNEL); - if (NULL == ir) + ir = kzalloc(sizeof(*ir), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ir || !input_dev) { + kfree(ir); + input_free_device(input_dev); return -ENOMEM; - memset(ir,0,sizeof(*ir)); + } /* init hardware-specific stuff */ ir->mask_keycode = mask_keycode; @@ -552,19 +556,19 @@ int saa7134_input_init1(struct saa7134_dev *dev) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); - ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes); - ir->dev.name = ir->name; - ir->dev.phys = ir->phys; - ir->dev.id.bustype = BUS_PCI; - ir->dev.id.version = 1; + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->name = ir->name; + input_dev->phys = ir->phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; if (dev->pci->subsystem_vendor) { - ir->dev.id.vendor = dev->pci->subsystem_vendor; - ir->dev.id.product = dev->pci->subsystem_device; + input_dev->id.vendor = dev->pci->subsystem_vendor; + input_dev->id.product = dev->pci->subsystem_device; } else { - ir->dev.id.vendor = dev->pci->vendor; - ir->dev.id.product = dev->pci->device; + input_dev->id.vendor = dev->pci->vendor; + input_dev->id.product = dev->pci->device; } - ir->dev.dev = &dev->pci->dev; + input_dev->cdev.dev = &dev->pci->dev; /* all done */ dev->remote = ir; @@ -576,8 +580,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) add_timer(&ir->timer); } - input_register_device(&dev->remote->dev); - printk("%s: registered input device for IR\n",dev->name); + input_register_device(ir->dev); return 0; } @@ -586,9 +589,9 @@ void saa7134_input_fini(struct saa7134_dev *dev) if (NULL == dev->remote) return; - input_unregister_device(&dev->remote->dev); if (dev->remote->polling) del_timer_sync(&dev->remote->timer); + input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; } diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 3ea09142ec9c..860b89530e2a 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -351,7 +351,7 @@ struct saa7134_oss { /* IR input */ struct saa7134_ir { - struct input_dev dev; + struct input_dev *dev; struct ir_input_state ir; char name[32]; char phys[32]; From c7f7a569d9b4ea7c53ab6fcd1377895312d8372b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:41 -0500 Subject: [PATCH 0621/1940] [PATCH] Input: convert drivers/macintosh to dynamic input_dev allocation Input: convert drivers/macntosh to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/macintosh/adbhid.c | 218 +++++++++++++++++++----------------- drivers/macintosh/mac_hid.c | 40 ++++--- 2 files changed, 136 insertions(+), 122 deletions(-) diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index db654e8bd67e..cdb6d0283195 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -206,7 +206,7 @@ u8 adb_to_linux_keycodes[128] = { }; struct adbhid { - struct input_dev input; + struct input_dev *input; int id; int default_id; int original_handler_id; @@ -291,10 +291,10 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) switch (keycode) { case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */ - input_regs(&ahid->input, regs); - input_report_key(&ahid->input, KEY_CAPSLOCK, 1); - input_report_key(&ahid->input, KEY_CAPSLOCK, 0); - input_sync(&ahid->input); + input_regs(ahid->input, regs); + input_report_key(ahid->input, KEY_CAPSLOCK, 1); + input_report_key(ahid->input, KEY_CAPSLOCK, 0); + input_sync(ahid->input); return; #ifdef CONFIG_PPC_PMAC case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */ @@ -347,10 +347,10 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) } if (adbhid[id]->keycode[keycode]) { - input_regs(&adbhid[id]->input, regs); - input_report_key(&adbhid[id]->input, + input_regs(adbhid[id]->input, regs); + input_report_key(adbhid[id]->input, adbhid[id]->keycode[keycode], !up_flag); - input_sync(&adbhid[id]->input); + input_sync(adbhid[id]->input); } else printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, up_flag ? "released" : "pressed"); @@ -441,20 +441,20 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo break; } - input_regs(&adbhid[id]->input, regs); + input_regs(adbhid[id]->input, regs); - input_report_key(&adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); - input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); + input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); + input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD) - input_report_key(&adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1)); + input_report_key(adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1)); - input_report_rel(&adbhid[id]->input, REL_X, + input_report_rel(adbhid[id]->input, REL_X, ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 )); - input_report_rel(&adbhid[id]->input, REL_Y, + input_report_rel(adbhid[id]->input, REL_Y, ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 )); - input_sync(&adbhid[id]->input); + input_sync(adbhid[id]->input); } static void @@ -467,7 +467,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto return; } - input_regs(&adbhid[id]->input, regs); + input_regs(adbhid[id]->input, regs); switch (adbhid[id]->original_handler_id) { default: @@ -477,19 +477,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto switch (data[1] & 0x0f) { case 0x0: /* microphone */ - input_report_key(&adbhid[id]->input, KEY_SOUND, down); + input_report_key(adbhid[id]->input, KEY_SOUND, down); break; case 0x1: /* mute */ - input_report_key(&adbhid[id]->input, KEY_MUTE, down); + input_report_key(adbhid[id]->input, KEY_MUTE, down); break; case 0x2: /* volume decrease */ - input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down); + input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down); break; case 0x3: /* volume increase */ - input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down); + input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down); break; default: @@ -513,19 +513,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto switch (data[1] & 0x0f) { case 0x8: /* mute */ - input_report_key(&adbhid[id]->input, KEY_MUTE, down); + input_report_key(adbhid[id]->input, KEY_MUTE, down); break; case 0x7: /* volume decrease */ - input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down); + input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down); break; case 0x6: /* volume increase */ - input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down); + input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down); break; case 0xb: /* eject */ - input_report_key(&adbhid[id]->input, KEY_EJECTCD, down); + input_report_key(adbhid[id]->input, KEY_EJECTCD, down); break; case 0xa: /* brightness decrease */ @@ -539,7 +539,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto } } #endif /* CONFIG_PMAC_BACKLIGHT */ - input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); + input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); break; case 0x9: /* brightness increase */ @@ -553,19 +553,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto } } #endif /* CONFIG_PMAC_BACKLIGHT */ - input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); + input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); break; case 0xc: /* videomode switch */ - input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down); + input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down); break; case 0xd: /* keyboard illumination toggle */ - input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down); + input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down); break; case 0xe: /* keyboard illumination decrease */ - input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down); + input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down); break; case 0xf: @@ -573,7 +573,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto case 0x8f: case 0x0f: /* keyboard illumination increase */ - input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down); + input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down); break; case 0x7f: @@ -596,7 +596,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto break; } - input_sync(&adbhid[id]->input); + input_sync(adbhid[id]->input); } static struct adb_request led_request; @@ -683,7 +683,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) int i; for (i = 1; i < 16; i++) { if (adbhid[i]) - del_timer_sync(&adbhid[i]->input.timer); + del_timer_sync(&adbhid[i]->input->timer); } } @@ -699,153 +699,163 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) return NOTIFY_DONE; } -static void +static int adbhid_input_register(int id, int default_id, int original_handler_id, int current_handler_id, int mouse_kind) { + struct adbhid *hid; + struct input_dev *input_dev; + int err; int i; if (adbhid[id]) { printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id); - return; + return -EEXIST; } - if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL))) - return; + adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!hid || !input_dev) { + err = -ENOMEM; + goto fail; - memset(adbhid[id], 0, sizeof(struct adbhid)); - sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id); + } - init_input_dev(&adbhid[id]->input); + sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id); - adbhid[id]->id = default_id; - adbhid[id]->original_handler_id = original_handler_id; - adbhid[id]->current_handler_id = current_handler_id; - adbhid[id]->mouse_kind = mouse_kind; - adbhid[id]->flags = 0; - adbhid[id]->input.private = adbhid[id]; - adbhid[id]->input.name = adbhid[id]->name; - adbhid[id]->input.phys = adbhid[id]->phys; - adbhid[id]->input.id.bustype = BUS_ADB; - adbhid[id]->input.id.vendor = 0x0001; - adbhid[id]->input.id.product = (id << 12) | (default_id << 8) | original_handler_id; - adbhid[id]->input.id.version = 0x0100; + hid->id = default_id; + hid->original_handler_id = original_handler_id; + hid->current_handler_id = current_handler_id; + hid->mouse_kind = mouse_kind; + hid->flags = 0; + input_dev->private = hid; + input_dev->name = hid->name; + input_dev->phys = hid->phys; + input_dev->id.bustype = BUS_ADB; + input_dev->id.vendor = 0x0001; + input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id; + input_dev->id.version = 0x0100; switch (default_id) { case ADB_KEYBOARD: - if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) { - kfree(adbhid[id]); - return; + hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL); + if (!hid->keycode) { + err = -ENOMEM; + goto fail; } - sprintf(adbhid[id]->name, "ADB keyboard"); + sprintf(hid->name, "ADB keyboard"); - memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes)); + memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes)); printk(KERN_INFO "Detected ADB keyboard, type "); switch (original_handler_id) { default: printk(".\n"); - adbhid[id]->input.id.version = ADB_KEYBOARD_UNKNOWN; + input_dev->id.version = ADB_KEYBOARD_UNKNOWN; break; case 0x01: case 0x02: case 0x03: case 0x06: case 0x08: case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C: case 0xC0: case 0xC3: case 0xC6: printk("ANSI.\n"); - adbhid[id]->input.id.version = ADB_KEYBOARD_ANSI; + input_dev->id.version = ADB_KEYBOARD_ANSI; break; case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D: case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1: case 0xC4: case 0xC7: printk("ISO, swapping keys.\n"); - adbhid[id]->input.id.version = ADB_KEYBOARD_ISO; - i = adbhid[id]->keycode[10]; - adbhid[id]->keycode[10] = adbhid[id]->keycode[50]; - adbhid[id]->keycode[50] = i; + input_dev->id.version = ADB_KEYBOARD_ISO; + i = hid->keycode[10]; + hid->keycode[10] = hid->keycode[50]; + hid->keycode[50] = i; break; case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A: case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9: printk("JIS.\n"); - adbhid[id]->input.id.version = ADB_KEYBOARD_JIS; + input_dev->id.version = ADB_KEYBOARD_JIS; break; } for (i = 0; i < 128; i++) - if (adbhid[id]->keycode[i]) - set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit); + if (hid->keycode[i]) + set_bit(hid->keycode[i], input_dev->keybit); - adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); - adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); - adbhid[id]->input.event = adbhid_kbd_event; - adbhid[id]->input.keycodemax = 127; - adbhid[id]->input.keycodesize = 1; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); + input_dev->event = adbhid_kbd_event; + input_dev->keycodemax = 127; + input_dev->keycodesize = 1; break; case ADB_MOUSE: - sprintf(adbhid[id]->name, "ADB mouse"); + sprintf(hid->name, "ADB mouse"); - adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); break; case ADB_MISC: switch (original_handler_id) { case 0x02: /* Adjustable keyboard button device */ - sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons"); - adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - set_bit(KEY_SOUND, adbhid[id]->input.keybit); - set_bit(KEY_MUTE, adbhid[id]->input.keybit); - set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit); - set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit); + sprintf(hid->name, "ADB adjustable keyboard buttons"); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + set_bit(KEY_SOUND, input_dev->keybit); + set_bit(KEY_MUTE, input_dev->keybit); + set_bit(KEY_VOLUMEUP, input_dev->keybit); + set_bit(KEY_VOLUMEDOWN, input_dev->keybit); break; case 0x1f: /* Powerbook button device */ - sprintf(adbhid[id]->name, "ADB Powerbook buttons"); - adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - set_bit(KEY_MUTE, adbhid[id]->input.keybit); - set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit); - set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit); - set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit); - set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit); - set_bit(KEY_EJECTCD, adbhid[id]->input.keybit); - set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit); - set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit); - set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit); - set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit); + sprintf(hid->name, "ADB Powerbook buttons"); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + set_bit(KEY_MUTE, input_dev->keybit); + set_bit(KEY_VOLUMEUP, input_dev->keybit); + set_bit(KEY_VOLUMEDOWN, input_dev->keybit); + set_bit(KEY_BRIGHTNESSUP, input_dev->keybit); + set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit); + set_bit(KEY_EJECTCD, input_dev->keybit); + set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit); + set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit); + set_bit(KEY_KBDILLUMDOWN, input_dev->keybit); + set_bit(KEY_KBDILLUMUP, input_dev->keybit); break; } - if (adbhid[id]->name[0]) + if (hid->name[0]) break; /* else fall through */ default: printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n"); - kfree(adbhid[id]); - return; + err = -ENODEV; + goto fail; } - adbhid[id]->input.keycode = adbhid[id]->keycode; + input_dev->keycode = hid->keycode; - input_register_device(&adbhid[id]->input); - - printk(KERN_INFO "input: %s on %s\n", - adbhid[id]->name, adbhid[id]->phys); + input_register_device(input_dev); if (default_id == ADB_KEYBOARD) { /* HACK WARNING!! This should go away as soon there is an utility * to control that for event devices. */ - adbhid[id]->input.rep[REP_DELAY] = 500; /* input layer default: 250 */ - adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */ + input_dev->rep[REP_DELAY] = 500; /* input layer default: 250 */ + input_dev->rep[REP_PERIOD] = 66; /* input layer default: 33 */ } + + return 0; + + fail: input_free_device(input_dev); + kfree(hid); + adbhid[id] = NULL; + return err; } static void adbhid_input_unregister(int id) { - input_unregister_device(&adbhid[id]->input); + input_unregister_device(adbhid[id]->input); if (adbhid[id]->keycode) kfree(adbhid[id]->keycode); kfree(adbhid[id]); @@ -858,7 +868,7 @@ adbhid_input_reregister(int id, int default_id, int org_handler_id, int cur_handler_id, int mk) { if (adbhid[id]) { - if (adbhid[id]->input.id.product != + if (adbhid[id]->input->id.product != ((id << 12)|(default_id << 8)|org_handler_id)) { adbhid_input_unregister(id); adbhid_input_register(id, default_id, org_handler_id, diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 5ad3a5a9eb7f..a66636116f0b 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -16,8 +16,8 @@ #include -static struct input_dev emumousebtn; -static void emumousebtn_input_register(void); +static struct input_dev *emumousebtn; +static int emumousebtn_input_register(void); static int mouse_emulate_buttons = 0; static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ @@ -90,10 +90,10 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) && (keycode == mouse_button2_keycode || keycode == mouse_button3_keycode)) { if (mouse_emulate_buttons == 1) { - input_report_key(&emumousebtn, + input_report_key(emumousebtn, keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT, down); - input_sync(&emumousebtn); + input_sync(emumousebtn); return 1; } mouse_last_keycode = down ? keycode : 0; @@ -105,30 +105,34 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons); -static void emumousebtn_input_register(void) +static int emumousebtn_input_register(void) { - emumousebtn.name = "Macintosh mouse button emulation"; + emumousebtn = input_allocate_device(); + if (!emumousebtn) + return -ENOMEM; - init_input_dev(&emumousebtn); + emumousebtn->name = "Macintosh mouse button emulation"; + emumousebtn->id.bustype = BUS_ADB; + emumousebtn->id.vendor = 0x0001; + emumousebtn->id.product = 0x0001; + emumousebtn->id.version = 0x0100; - emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y); + emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y); - emumousebtn.id.bustype = BUS_ADB; - emumousebtn.id.vendor = 0x0001; - emumousebtn.id.product = 0x0001; - emumousebtn.id.version = 0x0100; + input_register_device(emumousebtn); - input_register_device(&emumousebtn); - - printk(KERN_INFO "input: Macintosh mouse button emulation\n"); + return 0; } int __init mac_hid_init(void) { + int err; - emumousebtn_input_register(); + err = emumousebtn_input_register(); + if (err) + return err; #if defined(CONFIG_SYSCTL) mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1); From 0259567ad60df13a55583b84d2cddb5526705907 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:42 -0500 Subject: [PATCH 0622/1940] [PATCH] Input: convert konicawc to dynamic input_dev allocation Input: convert konicawc to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/media/konicawc.c | 89 ++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 20ac9e1069d4..9fe2c2710d13 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -119,7 +119,7 @@ struct konicawc { int yplanesz; /* Number of bytes in the Y plane */ unsigned int buttonsts:1; #ifdef CONFIG_INPUT - struct input_dev input; + struct input_dev *input; char input_physname[64]; #endif }; @@ -218,6 +218,57 @@ static void konicawc_adjust_picture(struct uvd *uvd) konicawc_camera_on(uvd); } +#ifdef CONFIG_INPUT + +static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) +{ + struct input_dev *input_dev; + + usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); + strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); + + cam->input = input_dev = input_allocate_device(); + if (!input_dev) { + warn("Not enough memory for camera's input device\n"); + return; + } + + input_dev->name = "Konicawc snapshot button"; + input_dev->phys = cam->input_physname; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &dev->dev; + + input_dev->evbit[0] = BIT(EV_KEY); + input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); + + input_dev->private = cam; + + input_register_device(cam->input); +} + +static void konicawc_unregister_input(struct konicawc *cam) +{ + if (cam->input) { + input_unregister_device(cam->input); + cam->input = NULL; + } +} + +static void konicawc_report_buttonstat(struct konicawc *cam) +{ + if (cam->input) { + input_report_key(cam->input, BTN_0, cam->buttonsts); + input_sync(cam->input); + } +} + +#else + +static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { } +static inline void konicawc_unregister_input(struct konicawc *cam) { } +static inline void konicawc_report_buttonstat(struct konicawc *cam) { } + +#endif /* CONFIG_INPUT */ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb) { @@ -273,10 +324,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur if(button != cam->buttonsts) { DEBUG(2, "button: %sclicked", button ? "" : "un"); cam->buttonsts = button; -#ifdef CONFIG_INPUT - input_report_key(&cam->input, BTN_0, cam->buttonsts); - input_sync(&cam->input); -#endif + konicawc_report_buttonstat(cam); } if(sts == 0x01) { /* drop frame */ @@ -645,9 +693,9 @@ static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw) RingQueue_Flush(&uvd->dp); cam->lastframe = -2; if(uvd->curframe != -1) { - uvd->frame[uvd->curframe].curline = 0; - uvd->frame[uvd->curframe].seqRead_Length = 0; - uvd->frame[uvd->curframe].seqRead_Index = 0; + uvd->frame[uvd->curframe].curline = 0; + uvd->frame[uvd->curframe].seqRead_Length = 0; + uvd->frame[uvd->curframe].seqRead_Index = 0; } konicawc_start_data(uvd); @@ -718,7 +766,6 @@ static void konicawc_configure_video(struct uvd *uvd) DEBUG(1, "setting initial values"); } - static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid) { struct usb_device *dev = interface_to_usbdev(intf); @@ -839,21 +886,8 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id err("usbvideo_RegisterVideoDevice() failed."); uvd = NULL; } -#ifdef CONFIG_INPUT - /* Register input device for button */ - memset(&cam->input, 0, sizeof(struct input_dev)); - cam->input.name = "Konicawc snapshot button"; - cam->input.private = cam; - cam->input.evbit[0] = BIT(EV_KEY); - cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0); - usb_to_input_id(dev, &cam->input.id); - input_register_device(&cam->input); - - usb_make_path(dev, cam->input_physname, 56); - strcat(cam->input_physname, "/input0"); - cam->input.phys = cam->input_physname; - info("konicawc: %s on %s\n", cam->input.name, cam->input.phys); -#endif + + konicawc_register_input(cam, dev); } if (uvd) { @@ -869,10 +903,9 @@ static void konicawc_free_uvd(struct uvd *uvd) int i; struct konicawc *cam = (struct konicawc *)uvd->user_data; -#ifdef CONFIG_INPUT - input_unregister_device(&cam->input); -#endif - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + konicawc_unregister_input(cam); + + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { usb_free_urb(cam->sts_urb[i]); cam->sts_urb[i] = NULL; } From 17dd3f0f7aa729a042af5d3318ff9b3e7781b45b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:52 -0500 Subject: [PATCH 0623/1940] [PATCH] drivers/input/joystick: convert to dynamic input_dev allocation Input: convert drivers/input/joystick to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/adi.c | 93 ++-- drivers/input/joystick/amijoy.c | 89 ++-- drivers/input/joystick/analog.c | 96 ++--- drivers/input/joystick/cobra.c | 74 ++-- drivers/input/joystick/db9.c | 288 ++++++++----- drivers/input/joystick/gamecon.c | 408 ++++++++++-------- drivers/input/joystick/gf2k.c | 69 +-- drivers/input/joystick/grip.c | 91 ++-- drivers/input/joystick/grip_mp.c | 149 ++++--- drivers/input/joystick/guillemot.c | 51 ++- drivers/input/joystick/iforce/iforce-main.c | 106 +++-- .../input/joystick/iforce/iforce-packets.c | 5 +- drivers/input/joystick/iforce/iforce-serio.c | 10 +- drivers/input/joystick/iforce/iforce-usb.c | 22 +- drivers/input/joystick/iforce/iforce.h | 2 +- drivers/input/joystick/interact.c | 53 +-- drivers/input/joystick/magellan.c | 75 ++-- drivers/input/joystick/sidewinder.c | 70 +-- drivers/input/joystick/spaceball.c | 82 ++-- drivers/input/joystick/spaceorb.c | 82 ++-- drivers/input/joystick/stinger.c | 73 ++-- drivers/input/joystick/tmdc.c | 324 ++++++++------ drivers/input/joystick/turbografx.c | 229 ++++++---- drivers/input/joystick/twidjoy.c | 120 +++--- drivers/input/joystick/warrior.c | 81 ++-- 25 files changed, 1486 insertions(+), 1256 deletions(-) diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index cf35ae638a0d..9d95459f4bcb 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); #define ADI_MIN_LENGTH 8 #define ADI_MIN_LEN_LENGTH 10 #define ADI_MIN_ID_LENGTH 66 -#define ADI_MAX_NAME_LENGTH 48 +#define ADI_MAX_NAME_LENGTH 64 #define ADI_MAX_CNAME_LENGTH 16 #define ADI_MAX_PHYS_LENGTH 64 @@ -106,7 +106,7 @@ static struct { */ struct adi { - struct input_dev dev; + struct input_dev *dev; int length; int ret; int idx; @@ -215,7 +215,7 @@ static inline int adi_get_bits(struct adi *adi, int count) static int adi_decode(struct adi *adi) { - struct input_dev *dev = &adi->dev; + struct input_dev *dev = adi->dev; char *abs = adi->abs; short *key = adi->key; int i, t; @@ -318,7 +318,8 @@ static void adi_init_digital(struct gameport *gameport) for (i = 0; seq[i]; i++) { gameport_trigger(gameport); - if (seq[i] > 0) msleep(seq[i]); + if (seq[i] > 0) + msleep(seq[i]); if (seq[i] < 0) { mdelay(-seq[i]); udelay(-seq[i]*14); /* It looks like mdelay() is off by approx 1.4% */ @@ -397,42 +398,46 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port) } } -static void adi_init_input(struct adi *adi, struct adi_port *port, int half) +static int adi_init_input(struct adi *adi, struct adi_port *port, int half) { - int i, t; + struct input_dev *input_dev; char buf[ADI_MAX_NAME_LENGTH]; + int i, t; - if (!adi->length) return; - - init_input_dev(&adi->dev); + adi->dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX; snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id); - snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf); + snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s [%s]", buf, adi->cname); snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half); adi->abs = adi_abs[t]; adi->key = adi_key[t]; - adi->dev.open = adi_open; - adi->dev.close = adi_close; + input_dev->name = adi->name; + input_dev->phys = adi->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; + input_dev->id.product = adi->id; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &port->gameport->dev; + input_dev->private = port; - adi->dev.name = adi->name; - adi->dev.phys = adi->phys; - adi->dev.id.bustype = BUS_GAMEPORT; - adi->dev.id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; - adi->dev.id.product = adi->id; - adi->dev.id.version = 0x0100; + input_dev->open = adi_open; + input_dev->close = adi_close; - adi->dev.private = port; - adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) - set_bit(adi->abs[i], adi->dev.absbit); + set_bit(adi->abs[i], input_dev->absbit); for (i = 0; i < adi->buttons; i++) - set_bit(adi->key[i], adi->dev.keybit); + set_bit(adi->key[i], input_dev->keybit); + + return 0; } static void adi_init_center(struct adi *adi) @@ -445,17 +450,17 @@ static void adi_init_center(struct adi *adi) for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) { t = adi->abs[i]; - x = adi->dev.abs[t]; + x = adi->dev->abs[t]; if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE) x = i < adi->axes10 ? 512 : 128; if (i < adi->axes10) - input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16); + input_set_abs_params(adi->dev, t, 64, x * 2 - 64, 2, 16); else if (i < adi->axes10 + adi->axes8) - input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16); + input_set_abs_params(adi->dev, t, 48, x * 2 - 48, 1, 16); else - input_set_abs_params(&adi->dev, t, -1, 1, 0, 0); + input_set_abs_params(adi->dev, t, -1, 1, 0, 0); } } @@ -469,7 +474,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) int i; int err; - if (!(port = kzalloc(sizeof(struct adi_port), GFP_KERNEL))) + port = kzalloc(sizeof(struct adi_port), GFP_KERNEL); + if (!port) return -ENOMEM; port->gameport = gameport; @@ -477,10 +483,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_drvdata(gameport, port); err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); - if (err) { - kfree(port); - return err; - } + if (err) + goto fail1; adi_init_digital(gameport); adi_read_packet(port); @@ -490,13 +494,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < 2; i++) { adi_id_decode(port->adi + i, port); - adi_init_input(port->adi + i, port, i); + + if (!port->adi[i].length) + continue; + + err = adi_init_input(port->adi + i, port, i); + if (err) + goto fail2; } if (!port->adi[0].length && !port->adi[1].length) { - gameport_close(gameport); - kfree(port); - return -ENODEV; + err = -ENODEV; + goto fail2; } gameport_set_poll_handler(gameport, adi_poll); @@ -511,12 +520,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < 2; i++) if (port->adi[i].length > 0) { adi_init_center(port->adi + i); - input_register_device(&port->adi[i].dev); - printk(KERN_INFO "input: %s [%s] on %s\n", - port->adi[i].name, port->adi[i].cname, gameport->phys); + input_register_device(port->adi[i].dev); } return 0; + + fail2: for (i = 0; i < 2; i++) + if (port->adi[i].dev) + input_free_device(port->adi[i].dev); + gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); + kfree(port); + return err; } static void adi_disconnect(struct gameport *gameport) @@ -526,7 +541,7 @@ static void adi_disconnect(struct gameport *gameport) for (i = 0; i < 2; i++) if (port->adi[i].length > 0) - input_unregister_device(&port->adi[i].dev); + input_unregister_device(port->adi[i].dev); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(port); diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index e996183c5b06..8558a99f6635 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -53,11 +53,9 @@ __obsolete_setup("amijoy="); static int amijoy_used; static DECLARE_MUTEX(amijoy_sem); -static struct input_dev amijoy_dev[2]; +static struct input_dev *amijoy_dev[2]; static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" }; -static char *amijoy_name = "Amiga joystick"; - static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp) { int i, data = 0, button = 0; @@ -70,15 +68,15 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp) case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; } - input_regs(amijoy_dev + i, fp); + input_regs(amijoy_dev[i], fp); - input_report_key(amijoy_dev + i, BTN_TRIGGER, button); + input_report_key(amijoy_dev[i], BTN_TRIGGER, button); - input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1)); + input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1)); data = ~(data ^ (data << 1)); - input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1)); + input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1)); - input_sync(amijoy_dev + i); + input_sync(amijoy_dev[i]); } return IRQ_HANDLED; } @@ -114,39 +112,52 @@ static void amijoy_close(struct input_dev *dev) static int __init amijoy_init(void) { int i, j; + int err; - for (i = 0; i < 2; i++) - if (amijoy[i]) { - if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2, - "amijoy [Denise]")) { - if (i == 1 && amijoy[0]) { - input_unregister_device(amijoy_dev); - release_mem_region(CUSTOM_PHYSADDR+10, 2); - } - return -EBUSY; - } + for (i = 0; i < 2; i++) { + if (!amijoy[i]) + continue; - amijoy_dev[i].open = amijoy_open; - amijoy_dev[i].close = amijoy_close; - amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - for (j = 0; j < 2; j++) { - amijoy_dev[i].absmin[ABS_X + j] = -1; - amijoy_dev[i].absmax[ABS_X + j] = 1; - } - - amijoy_dev[i].name = amijoy_name; - amijoy_dev[i].phys = amijoy_phys[i]; - amijoy_dev[i].id.bustype = BUS_AMIGA; - amijoy_dev[i].id.vendor = 0x0001; - amijoy_dev[i].id.product = 0x0003; - amijoy_dev[i].id.version = 0x0100; - - input_register_device(amijoy_dev + i); - printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i); + amijoy_dev[i] = input_allocate_device(); + if (!amijoy_dev[i]) { + err = -ENOMEM; + goto fail; } + + if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) { + input_free_device(amijoy_dev[i]); + err = -EBUSY; + goto fail; + } + + amijoy_dev[i]->name = "Amiga joystick"; + amijoy_dev[i]->phys = amijoy_phys[i]; + amijoy_dev[i]->id.bustype = BUS_AMIGA; + amijoy_dev[i]->id.vendor = 0x0001; + amijoy_dev[i]->id.product = 0x0003; + amijoy_dev[i]->id.version = 0x0100; + + amijoy_dev[i]->open = amijoy_open; + amijoy_dev[i]->close = amijoy_close; + + amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + for (j = 0; j < 2; j++) { + amijoy_dev[i]->absmin[ABS_X + j] = -1; + amijoy_dev[i]->absmax[ABS_X + j] = 1; + } + + input_register_device(amijoy_dev[i]); + } return 0; + + fail: while (--i >= 0) + if (amijoy[i]) { + input_unregister_device(amijoy_dev[i]); + release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2); + } + return err; } static void __exit amijoy_exit(void) @@ -155,8 +166,8 @@ static void __exit amijoy_exit(void) for (i = 0; i < 2; i++) if (amijoy[i]) { - input_unregister_device(amijoy_dev + i); - release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2); + input_unregister_device(amijoy_dev[i]); + release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2); } } diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 64b1313a3c66..c75ac6eb1ffb 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -111,7 +111,7 @@ static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 }; struct analog { - struct input_dev dev; + struct input_dev *dev; int mask; short *buttons; char name[ANALOG_MAX_NAME_LENGTH]; @@ -182,7 +182,7 @@ static unsigned long analog_faketime = 0; static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons) { - struct input_dev *dev = &analog->dev; + struct input_dev *dev = analog->dev; int i, j; if (analog->mask & ANALOG_HAT_FCS) @@ -428,27 +428,30 @@ static void analog_name(struct analog *analog) * analog_init_device() */ -static void analog_init_device(struct analog_port *port, struct analog *analog, int index) +static int analog_init_device(struct analog_port *port, struct analog *analog, int index) { + struct input_dev *input_dev; int i, j, t, v, w, x, y, z; analog_name(analog); sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; - init_input_dev(&analog->dev); + analog->dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; - analog->dev.name = analog->name; - analog->dev.phys = analog->phys; - analog->dev.id.bustype = BUS_GAMEPORT; - analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG; - analog->dev.id.product = analog->mask >> 4; - analog->dev.id.version = 0x0100; + input_dev->name = analog->name; + input_dev->phys = analog->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; + input_dev->id.product = analog->mask >> 4; + input_dev->id.version = 0x0100; - analog->dev.open = analog_open; - analog->dev.close = analog_close; - analog->dev.private = port; - analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->open = analog_open; + input_dev->close = analog_close; + input_dev->private = port; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = j = 0; i < 4; i++) if (analog->mask & (1 << i)) { @@ -461,8 +464,6 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, v = (x >> 3); w = (x >> 3); - set_bit(t, analog->dev.absbit); - if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3))) x = y; @@ -472,11 +473,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, w = (x >> 4); } - analog->dev.absmax[t] = (x << 1) - v; - analog->dev.absmin[t] = v; - analog->dev.absfuzz[t] = port->fuzz; - analog->dev.absflat[t] = w; - + input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w); j++; } @@ -484,41 +481,30 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, if (analog->mask & analog_exts[i]) for (x = 0; x < 2; x++) { t = analog_hats[j++]; - set_bit(t, analog->dev.absbit); - analog->dev.absmax[t] = 1; - analog->dev.absmin[t] = -1; + input_set_abs_params(input_dev, t, -1, 1, 0, 0); } for (i = j = 0; i < 4; i++) if (analog->mask & (0x10 << i)) - set_bit(analog->buttons[j++], analog->dev.keybit); + set_bit(analog->buttons[j++], input_dev->keybit); if (analog->mask & ANALOG_BTNS_CHF) for (i = 0; i < 2; i++) - set_bit(analog->buttons[j++], analog->dev.keybit); + set_bit(analog->buttons[j++], input_dev->keybit); if (analog->mask & ANALOG_HBTN_CHF) for (i = 0; i < 4; i++) - set_bit(analog->buttons[j++], analog->dev.keybit); + set_bit(analog->buttons[j++], input_dev->keybit); for (i = 0; i < 4; i++) if (analog->mask & (ANALOG_BTN_TL << i)) - set_bit(analog_pads[i], analog->dev.keybit); + set_bit(analog_pads[i], input_dev->keybit); analog_decode(analog, port->axes, port->initial, port->buttons); - input_register_device(&analog->dev); + input_register_device(analog->dev); - printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys); - - if (port->cooked) - printk(" [ADC port]\n"); - else - printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME, - port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed, - port->speed > 10000 ? "M" : "k", - port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000) - : (port->loop * 1000000) / port->speed); + return 0; } /* @@ -659,37 +645,41 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv return - ENOMEM; err = analog_init_port(gameport, drv, port); - if (err) { - kfree(port); - return err; - } + if (err) + goto fail1; err = analog_init_masks(port); - if (err) { - gameport_close(gameport); - gameport_set_drvdata(gameport, NULL); - kfree(port); - return err; - } + if (err) + goto fail2; gameport_set_poll_handler(gameport, analog_poll); gameport_set_poll_interval(gameport, 10); for (i = 0; i < 2; i++) - if (port->analog[i].mask) - analog_init_device(port, port->analog + i, i); + if (port->analog[i].mask) { + err = analog_init_device(port, port->analog + i, i); + if (err) + goto fail3; + } return 0; + + fail3: while (--i >= 0) + input_unregister_device(port->analog[i].dev); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); + kfree(port); + return err; } static void analog_disconnect(struct gameport *gameport) { - int i; struct analog_port *port = gameport_get_drvdata(gameport); + int i; for (i = 0; i < 2; i++) if (port->analog[i].mask) - input_unregister_device(&port->analog[i].dev); + input_unregister_device(port->analog[i].dev); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n", diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 0b2e9fa26579..9a3dfc724a41 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -44,13 +44,11 @@ MODULE_LICENSE("GPL"); #define COBRA_MAX_STROBE 45 /* 45 us max wait for first strobe */ #define COBRA_LENGTH 36 -static char* cobra_name = "Creative Labs Blaster GamePad Cobra"; - static int cobra_btn[] = { BTN_START, BTN_SELECT, BTN_TL, BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL2, BTN_TR2, 0 }; struct cobra { struct gameport *gameport; - struct input_dev dev[2]; + struct input_dev *dev[2]; int reads; int bads; unsigned char exists; @@ -128,7 +126,7 @@ static void cobra_poll(struct gameport *gameport) for (i = 0; i < 2; i++) if (cobra->exists & r & (1 << i)) { - dev = cobra->dev + i; + dev = cobra->dev[i]; input_report_abs(dev, ABS_X, ((data[i] >> 4) & 1) - ((data[i] >> 3) & 1)); input_report_abs(dev, ABS_Y, ((data[i] >> 2) & 1) - ((data[i] >> 1) & 1)); @@ -159,11 +157,13 @@ static void cobra_close(struct input_dev *dev) static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) { struct cobra *cobra; + struct input_dev *input_dev; unsigned int data[2]; int i, j; int err; - if (!(cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL))) + cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL); + if (!cobra) return -ENOMEM; cobra->gameport = gameport; @@ -191,38 +191,46 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, cobra_poll); gameport_set_poll_interval(gameport, 20); - for (i = 0; i < 2; i++) - if ((cobra->exists >> i) & 1) { + for (i = 0; i < 2; i++) { + if (~(cobra->exists >> i) & 1) + continue; - sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i); - - cobra->dev[i].private = cobra; - cobra->dev[i].open = cobra_open; - cobra->dev[i].close = cobra_close; - - cobra->dev[i].name = cobra_name; - cobra->dev[i].phys = cobra->phys[i]; - cobra->dev[i].id.bustype = BUS_GAMEPORT; - cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; - cobra->dev[i].id.product = 0x0008; - cobra->dev[i].id.version = 0x0100; - - cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0); - input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0); - - for (j = 0; cobra_btn[j]; j++) - set_bit(cobra_btn[j], cobra->dev[i].keybit); - - input_register_device(&cobra->dev[i]); - printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys); + cobra->dev[i] = input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + goto fail3; } + sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i); + + input_dev->name = "Creative Labs Blaster GamePad Cobra"; + input_dev->phys = cobra->phys[i]; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; + input_dev->id.product = 0x0008; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = cobra; + + input_dev->open = cobra_open; + input_dev->close = cobra_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0); + input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0); + for (j = 0; cobra_btn[j]; j++) + set_bit(cobra_btn[j], input_dev->keybit); + + input_register_device(cobra->dev[i]); + } + return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail3: for (i = 0; i < 2; i++) + if (cobra->dev[i]) + input_unregister_device(cobra->dev[i]); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); kfree(cobra); return err; } @@ -234,7 +242,7 @@ static void cobra_disconnect(struct gameport *gameport) for (i = 0; i < 2; i++) if ((cobra->exists >> i) & 1) - input_unregister_device(cobra->dev + i); + input_unregister_device(cobra->dev[i]); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(cobra); diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 2a3e4bb2da50..499344c72756 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -43,25 +43,28 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); MODULE_LICENSE("GPL"); -static int db9[] __initdata = { -1, 0 }; -static int db9_nargs __initdata = 0; -module_param_array_named(dev, db9, int, &db9_nargs, 0); +struct db9_config { + int args[2]; + int nargs; +}; + +#define DB9_MAX_PORTS 3 +static struct db9_config db9[DB9_MAX_PORTS] __initdata; + +module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0); MODULE_PARM_DESC(dev, "Describes first attached device (,)"); - -static int db9_2[] __initdata = { -1, 0 }; -static int db9_nargs_2 __initdata = 0; -module_param_array_named(dev2, db9_2, int, &db9_nargs_2, 0); +module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0); MODULE_PARM_DESC(dev2, "Describes second attached device (,)"); - -static int db9_3[] __initdata = { -1, 0 }; -static int db9_nargs_3 __initdata = 0; -module_param_array_named(dev3, db9_3, int, &db9_nargs_3, 0); +module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0); MODULE_PARM_DESC(dev3, "Describes third attached device (,)"); __obsolete_setup("db9="); __obsolete_setup("db9_2="); __obsolete_setup("db9_3="); +#define DB9_ARG_PARPORT 0 +#define DB9_ARG_MODE 1 + #define DB9_MULTI_STICK 0x01 #define DB9_MULTI2_STICK 0x02 #define DB9_GENESIS_PAD 0x03 @@ -87,40 +90,53 @@ __obsolete_setup("db9_3="); #define DB9_NORMAL 0x0a #define DB9_NOSELECT 0x08 -#define DB9_MAX_DEVICES 2 - #define DB9_GENESIS6_DELAY 14 #define DB9_REFRESH_TIME HZ/100 +#define DB9_MAX_DEVICES 2 + +struct db9_mode_data { + const char *name; + const short *buttons; + int n_buttons; + int n_pads; + int n_axis; + int bidirectional; + int reverse; +}; + struct db9 { - struct input_dev dev[DB9_MAX_DEVICES]; + struct input_dev *dev[DB9_MAX_DEVICES]; struct timer_list timer; struct pardevice *pd; int mode; int used; struct semaphore sem; - char phys[2][32]; + char phys[DB9_MAX_DEVICES][32]; }; static struct db9 *db9_base[3]; -static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB }; -static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE }; -static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START }; - -static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 }; -static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn, - db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn, - db9_cd32_btn, db9_cd32_btn }; -static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad", - NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick", - "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" }; - -static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 }; -static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 }; +static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB }; +static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE }; +static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START }; static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y }; -static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 }; -static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 }; + +static const struct db9_mode_data db9_modes[] = { + { NULL, NULL, 0, 0, 0, 0, 0 }, + { "Multisystem joystick", db9_multi_btn, 1, 1, 2, 1, 1 }, + { "Multisystem joystick (2 fire)", db9_multi_btn, 2, 1, 2, 1, 1 }, + { "Genesis pad", db9_genesis_btn, 4, 1, 2, 1, 1 }, + { NULL, NULL, 0, 0, 0, 0, 0 }, + { "Genesis 5 pad", db9_genesis_btn, 6, 1, 2, 1, 1 }, + { "Genesis 6 pad", db9_genesis_btn, 8, 1, 2, 1, 1 }, + { "Saturn pad", db9_cd32_btn, 9, 6, 7, 0, 1 }, + { "Multisystem (0.8.0.2) joystick", db9_multi_btn, 1, 1, 2, 1, 1 }, + { "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn, 1, 2, 2, 1, 1 }, + { "Amiga CD-32 pad", db9_cd32_btn, 7, 1, 2, 1, 1 }, + { "Saturn dpp", db9_cd32_btn, 9, 6, 7, 0, 0 }, + { "Saturn dpp dual", db9_cd32_btn, 9, 12, 7, 0, 0 }, +}; /* * Saturn controllers @@ -342,7 +358,7 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev) default: return -1; } - max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES); + max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES); for (tmp = 0, i = 0; i < n; i++) { id = db9_saturn_read_packet(port, data, type + i, 1); tmp = db9_saturn_report(id, data, dev, tmp, max_pads); @@ -354,17 +370,18 @@ static void db9_timer(unsigned long private) { struct db9 *db9 = (void *) private; struct parport *port = db9->pd->port; - struct input_dev *dev = db9->dev; + struct input_dev *dev = db9->dev[0]; + struct input_dev *dev2 = db9->dev[1]; int data, i; - switch(db9->mode) { + switch (db9->mode) { case DB9_MULTI_0802_2: data = parport_read_data(port) >> 3; - input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); - input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); - input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1); + input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev2, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1); case DB9_MULTI_0802: @@ -405,7 +422,7 @@ static void db9_timer(unsigned long private) input_report_key(dev, BTN_C, ~data & DB9_FIRE2); parport_write_control(port, DB9_NORMAL); - data=parport_read_data(port); + data = parport_read_data(port); input_report_key(dev, BTN_A, ~data & DB9_FIRE1); input_report_key(dev, BTN_START, ~data & DB9_FIRE2); @@ -414,7 +431,7 @@ static void db9_timer(unsigned long private) case DB9_GENESIS5_PAD: parport_write_control(port, DB9_NOSELECT); - data=parport_read_data(port); + data = parport_read_data(port); input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); @@ -422,7 +439,7 @@ static void db9_timer(unsigned long private) input_report_key(dev, BTN_C, ~data & DB9_FIRE2); parport_write_control(port, DB9_NORMAL); - data=parport_read_data(port); + data = parport_read_data(port); input_report_key(dev, BTN_A, ~data & DB9_FIRE1); input_report_key(dev, BTN_X, ~data & DB9_FIRE2); @@ -434,7 +451,7 @@ static void db9_timer(unsigned long private) parport_write_control(port, DB9_NOSELECT); /* 1 */ udelay(DB9_GENESIS6_DELAY); - data=parport_read_data(port); + data = parport_read_data(port); input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); @@ -443,7 +460,7 @@ static void db9_timer(unsigned long private) parport_write_control(port, DB9_NORMAL); udelay(DB9_GENESIS6_DELAY); - data=parport_read_data(port); + data = parport_read_data(port); input_report_key(dev, BTN_A, ~data & DB9_FIRE1); input_report_key(dev, BTN_START, ~data & DB9_FIRE2); @@ -477,7 +494,7 @@ static void db9_timer(unsigned long private) case DB9_CD32_PAD: - data=parport_read_data(port); + data = parport_read_data(port); input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); @@ -489,7 +506,7 @@ static void db9_timer(unsigned long private) parport_write_control(port, 0x02); parport_write_control(port, 0x0a); input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2); - } + } parport_write_control(port, 0x00); break; @@ -513,7 +530,7 @@ static int db9_open(struct input_dev *dev) if (!db9->used++) { parport_claim(db9->pd); parport_write_data(port, 0xff); - if (db9_reverse[db9->mode]) { + if (db9_modes[db9->mode].reverse) { parport_data_reverse(port); parport_write_control(port, DB9_NORMAL); } @@ -539,117 +556,160 @@ static void db9_close(struct input_dev *dev) up(&db9->sem); } -static struct db9 __init *db9_probe(int *config, int nargs) +static struct db9 __init *db9_probe(int parport, int mode) { struct db9 *db9; + const struct db9_mode_data *db9_mode; struct parport *pp; + struct pardevice *pd; + struct input_dev *input_dev; int i, j; + int err; - if (config[0] < 0) - return NULL; - - if (nargs < 2) { - printk(KERN_ERR "db9.c: Device type must be specified.\n"); - return NULL; + if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) { + printk(KERN_ERR "db9.c: Bad device type %d\n", mode); + err = -EINVAL; + goto err_out; } - if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) { - printk(KERN_ERR "db9.c: bad config\n"); - return NULL; - } + db9_mode = &db9_modes[mode]; - pp = parport_find_number(config[0]); + pp = parport_find_number(parport); if (!pp) { printk(KERN_ERR "db9.c: no such parport\n"); - return NULL; + err = -ENODEV; + goto err_out; } - if (db9_bidirectional[config[1]]) { - if (!(pp->modes & PARPORT_MODE_TRISTATE)) { - printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); - parport_put_port(pp); - return NULL; - } + if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { + printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); + err = -EINVAL; + goto err_put_pp; } - if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) { - parport_put_port(pp); - return NULL; + pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!pd) { + printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n"); + err = -EBUSY; + goto err_put_pp; + } + + db9 = kzalloc(sizeof(struct db9), GFP_KERNEL); + if (!db9) { + printk(KERN_ERR "db9.c: Not enough memory\n"); + err = -ENOMEM; + goto err_unreg_pardev; } init_MUTEX(&db9->sem); - db9->mode = config[1]; + db9->pd = pd; + db9->mode = mode; init_timer(&db9->timer); db9->timer.data = (long) db9; db9->timer.function = db9_timer; - db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); - parport_put_port(pp); + for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) { - if (!db9->pd) { - printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n"); - kfree(db9); - return NULL; - } - - for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) { + db9->dev[i] = input_dev = input_allocate_device(); + if (!input_dev) { + printk(KERN_ERR "db9.c: Not enough memory for input device\n"); + err = -ENOMEM; + goto err_free_devs; + } sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i); - db9->dev[i].private = db9; - db9->dev[i].open = db9_open; - db9->dev[i].close = db9_close; + input_dev->name = db9_mode->name; + input_dev->phys = db9->phys[i]; + input_dev->id.bustype = BUS_PARPORT; + input_dev->id.vendor = 0x0002; + input_dev->id.product = mode; + input_dev->id.version = 0x0100; + input_dev->private = db9; - db9->dev[i].name = db9_name[db9->mode]; - db9->dev[i].phys = db9->phys[i]; - db9->dev[i].id.bustype = BUS_PARPORT; - db9->dev[i].id.vendor = 0x0002; - db9->dev[i].id.product = config[1]; - db9->dev[i].id.version = 0x0100; + input_dev->open = db9_open; + input_dev->close = db9_close; - db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (j = 0; j < db9_buttons[db9->mode]; j++) - set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit); - for (j = 0; j < db9_num_axis[db9->mode]; j++) { - set_bit(db9_abs[j], db9->dev[i].absbit); - if (j < 2) { - db9->dev[i].absmin[db9_abs[j]] = -1; - db9->dev[i].absmax[db9_abs[j]] = 1; - } else { - db9->dev[i].absmin[db9_abs[j]] = 1; - db9->dev[i].absmax[db9_abs[j]] = 255; - db9->dev[i].absflat[db9_abs[j]] = 0; - } + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + for (j = 0; j < db9_mode->n_buttons; j++) + set_bit(db9_mode->buttons[j], input_dev->keybit); + for (j = 0; j < db9_mode->n_axis; j++) { + if (j < 2) + input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0); + else + input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0); } - input_register_device(db9->dev + i); - printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name); + + input_register_device(input_dev); } + parport_put_port(pp); return db9; + + err_free_devs: + while (--i >= 0) + input_unregister_device(db9->dev[i]); + kfree(db9); + err_unreg_pardev: + parport_unregister_device(pd); + err_put_pp: + parport_put_port(pp); + err_out: + return ERR_PTR(err); +} + +static void __exit db9_remove(struct db9 *db9) +{ + int i; + + for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++) + input_unregister_device(db9->dev[i]); + parport_unregister_device(db9->pd); + kfree(db9); } static int __init db9_init(void) { - db9_base[0] = db9_probe(db9, db9_nargs); - db9_base[1] = db9_probe(db9_2, db9_nargs_2); - db9_base[2] = db9_probe(db9_3, db9_nargs_3); + int i; + int have_dev = 0; + int err = 0; - if (db9_base[0] || db9_base[1] || db9_base[2]) - return 0; + for (i = 0; i < DB9_MAX_PORTS; i++) { + if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0) + continue; - return -ENODEV; + if (db9[i].nargs < 2) { + printk(KERN_ERR "db9.c: Device type must be specified.\n"); + err = -EINVAL; + break; + } + + db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT], + db9[i].args[DB9_ARG_MODE]); + if (IS_ERR(db9_base[i])) { + err = PTR_ERR(db9_base[i]); + break; + } + + have_dev = 1; + } + + if (err) { + while (--i >= 0) + db9_remove(db9_base[i]); + return err; + } + + return have_dev ? 0 : -ENODEV; } static void __exit db9_exit(void) { - int i, j; + int i; - for (i = 0; i < 3; i++) - if (db9_base[i]) { - for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++) - input_unregister_device(db9_base[i]->dev + j); - parport_unregister_device(db9_base[i]->pd); - } + for (i = 0; i < DB9_MAX_PORTS; i++) + if (db9_base[i]) + db9_remove(db9_base[i]); } module_init(db9_init); diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 5427bf9fc862..7df2d82f2c83 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -41,20 +41,22 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); MODULE_LICENSE("GPL"); -static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 }; -static int gc_nargs __initdata = 0; -module_param_array_named(map, gc, int, &gc_nargs, 0); -MODULE_PARM_DESC(map, "Describers first set of devices (,,,..)"); +#define GC_MAX_PORTS 3 +#define GC_MAX_DEVICES 5 -static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 }; -static int gc_nargs_2 __initdata = 0; -module_param_array_named(map2, gc_2, int, &gc_nargs_2, 0); -MODULE_PARM_DESC(map2, "Describers second set of devices"); +struct gc_config { + int args[GC_MAX_DEVICES + 1]; + int nargs; +}; -static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 }; -static int gc_nargs_3 __initdata = 0; -module_param_array_named(map3, gc_3, int, &gc_nargs_3, 0); -MODULE_PARM_DESC(map3, "Describers third set of devices"); +static struct gc_config gc[GC_MAX_PORTS] __initdata; + +module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0); +MODULE_PARM_DESC(map, "Describes first set of devices (,,,..)"); +module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0); +MODULE_PARM_DESC(map2, "Describes second set of devices"); +module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0); +MODULE_PARM_DESC(map3, "Describes third set of devices"); __obsolete_setup("gc="); __obsolete_setup("gc_2="); @@ -77,12 +79,12 @@ __obsolete_setup("gc_3="); struct gc { struct pardevice *pd; - struct input_dev dev[5]; + struct input_dev *dev[GC_MAX_DEVICES]; struct timer_list timer; unsigned char pads[GC_MAX + 1]; int used; struct semaphore sem; - char phys[5][32]; + char phys[GC_MAX_DEVICES][32]; }; static struct gc *gc_base[3]; @@ -330,7 +332,6 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES static void gc_timer(unsigned long private) { struct gc *gc = (void *) private; - struct input_dev *dev = gc->dev; unsigned char data[GC_MAX_LENGTH]; unsigned char data_psx[5][GC_PSX_BYTES]; int i, j, s; @@ -357,16 +358,16 @@ static void gc_timer(unsigned long private) if (data[31 - j] & s) axes[1] |= 1 << j; } - input_report_abs(dev + i, ABS_X, axes[0]); - input_report_abs(dev + i, ABS_Y, -axes[1]); + input_report_abs(gc->dev[i], ABS_X, axes[0]); + input_report_abs(gc->dev[i], ABS_Y, -axes[1]); - input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); - input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); + input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7])); + input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); for (j = 0; j < 10; j++) - input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); + input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]); - input_sync(dev + i); + input_sync(gc->dev[i]); } } } @@ -384,19 +385,19 @@ static void gc_timer(unsigned long private) s = gc_status_bit[i]; if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { - input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7])); - input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5])); + input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7])); + input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5])); } if (s & gc->pads[GC_NES]) for (j = 0; j < 4; j++) - input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); + input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]); if (s & gc->pads[GC_SNES]) for (j = 0; j < 8; j++) - input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]); - input_sync(dev + i); + input_sync(gc->dev[i]); } } @@ -413,15 +414,15 @@ static void gc_timer(unsigned long private) s = gc_status_bit[i]; if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { - input_report_abs(dev + i, ABS_X, !(s & data[2]) - !(s & data[3])); - input_report_abs(dev + i, ABS_Y, !(s & data[0]) - !(s & data[1])); - input_report_key(dev + i, BTN_TRIGGER, s & data[4]); + input_report_abs(gc->dev[i], ABS_X, !(s & data[2]) - !(s & data[3])); + input_report_abs(gc->dev[i], ABS_Y, !(s & data[0]) - !(s & data[1])); + input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]); } if (s & gc->pads[GC_MULTI2]) - input_report_key(dev + i, BTN_THUMB, s & data[5]); + input_report_key(gc->dev[i], BTN_THUMB, s & data[5]); - input_sync(dev + i); + input_sync(gc->dev[i]); } } @@ -438,44 +439,44 @@ static void gc_timer(unsigned long private) case GC_PSX_RUMBLE: - input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04); - input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02); + input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04); + input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02); case GC_PSX_NEGCON: case GC_PSX_ANALOG: - if(gc->pads[GC_DDR] & gc_status_bit[i]) { + if (gc->pads[GC_DDR] & gc_status_bit[i]) { for(j = 0; j < 4; j++) - input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); + input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); } else { for (j = 0; j < 4; j++) - input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]); + input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]); - input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); - input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); + input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); + input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); } for (j = 0; j < 8; j++) - input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); + input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); - input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08); - input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01); + input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); + input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); - input_sync(dev + i); + input_sync(gc->dev[i]); break; case GC_PSX_NORMAL: - if(gc->pads[GC_DDR] & gc_status_bit[i]) { + if (gc->pads[GC_DDR] & gc_status_bit[i]) { for(j = 0; j < 4; j++) - input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); + input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); } else { - input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); - input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); + input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); + input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); /* for some reason if the extra axes are left unset they drift */ /* for (j = 0; j < 4; j++) - input_report_abs(dev + i, gc_psx_abs[j+2], 128); + input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128); * This needs to be debugged properly, * maybe fuzz processing needs to be done in input_sync() * --vojtech @@ -483,12 +484,12 @@ static void gc_timer(unsigned long private) } for (j = 0; j < 8; j++) - input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); + input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); - input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08); - input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01); + input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); + input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); - input_sync(dev + i); + input_sync(gc->dev[i]); break; @@ -533,177 +534,212 @@ static void gc_close(struct input_dev *dev) up(&gc->sem); } -static struct gc __init *gc_probe(int *config, int nargs) +static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) +{ + struct input_dev *input_dev; + int i; + + if (!pad_type) + return 0; + + if (pad_type < 1 || pad_type > GC_MAX) { + printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type); + return -EINVAL; + } + + gc->dev[idx] = input_dev = input_allocate_device(); + if (!input_dev) { + printk(KERN_ERR "gamecon.c: Not enough memory for input device\n"); + return -ENOMEM; + } + + input_dev->name = gc_names[pad_type]; + input_dev->phys = gc->phys[idx]; + input_dev->id.bustype = BUS_PARPORT; + input_dev->id.vendor = 0x0001; + input_dev->id.product = pad_type; + input_dev->id.version = 0x0100; + input_dev->private = gc; + + input_dev->open = gc_open; + input_dev->close = gc_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; i < 2; i++) + input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); + + gc->pads[0] |= gc_status_bit[idx]; + gc->pads[pad_type] |= gc_status_bit[idx]; + + switch (pad_type) { + + case GC_N64: + for (i = 0; i < 10; i++) + set_bit(gc_n64_btn[i], input_dev->keybit); + + for (i = 0; i < 2; i++) { + input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); + input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); + } + + break; + + case GC_SNES: + for (i = 4; i < 8; i++) + set_bit(gc_snes_btn[i], input_dev->keybit); + case GC_NES: + for (i = 0; i < 4; i++) + set_bit(gc_snes_btn[i], input_dev->keybit); + break; + + case GC_MULTI2: + set_bit(BTN_THUMB, input_dev->keybit); + case GC_MULTI: + set_bit(BTN_TRIGGER, input_dev->keybit); + break; + + case GC_PSX: + for (i = 0; i < 6; i++) + input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2); + for (i = 0; i < 12; i++) + set_bit(gc_psx_btn[i], input_dev->keybit); + + break; + + case GC_DDR: + for (i = 0; i < 4; i++) + set_bit(gc_psx_ddr_btn[i], input_dev->keybit); + for (i = 0; i < 12; i++) + set_bit(gc_psx_btn[i], input_dev->keybit); + + break; + } + + return 0; +} + +static struct gc __init *gc_probe(int parport, int *pads, int n_pads) { struct gc *gc; struct parport *pp; - int i, j; - - if (config[0] < 0) - return NULL; - - if (nargs < 2) { - printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); - return NULL; - } - - pp = parport_find_number(config[0]); + struct pardevice *pd; + int i; + int err; + pp = parport_find_number(parport); if (!pp) { printk(KERN_ERR "gamecon.c: no such parport\n"); - return NULL; + err = -EINVAL; + goto err_out; } - if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) { - parport_put_port(pp); - return NULL; + pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!pd) { + printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); + err = -EBUSY; + goto err_put_pp; + } + + gc = kzalloc(sizeof(struct gc), GFP_KERNEL); + if (!gc) { + printk(KERN_ERR "gamecon.c: Not enough memory\n"); + err = -ENOMEM; + goto err_unreg_pardev; } init_MUTEX(&gc->sem); - - gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); - - parport_put_port(pp); - - if (!gc->pd) { - printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); - kfree(gc); - return NULL; - } - - parport_claim(gc->pd); - + gc->pd = pd; init_timer(&gc->timer); gc->timer.data = (long) gc; gc->timer.function = gc_timer; - for (i = 0; i < nargs - 1; i++) { - - if (!config[i + 1]) + for (i = 0; i < n_pads; i++) { + if (!pads[i]) continue; - if (config[i + 1] < 1 || config[i + 1] > GC_MAX) { - printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]); - continue; - } - - gc->dev[i].private = gc; - gc->dev[i].open = gc_open; - gc->dev[i].close = gc_close; - - gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (j = 0; j < 2; j++) { - set_bit(ABS_X + j, gc->dev[i].absbit); - gc->dev[i].absmin[ABS_X + j] = -1; - gc->dev[i].absmax[ABS_X + j] = 1; - } - - gc->pads[0] |= gc_status_bit[i]; - gc->pads[config[i + 1]] |= gc_status_bit[i]; - - switch(config[i + 1]) { - - case GC_N64: - for (j = 0; j < 10; j++) - set_bit(gc_n64_btn[j], gc->dev[i].keybit); - - for (j = 0; j < 2; j++) { - set_bit(ABS_X + j, gc->dev[i].absbit); - gc->dev[i].absmin[ABS_X + j] = -127; - gc->dev[i].absmax[ABS_X + j] = 126; - gc->dev[i].absflat[ABS_X + j] = 2; - set_bit(ABS_HAT0X + j, gc->dev[i].absbit); - gc->dev[i].absmin[ABS_HAT0X + j] = -1; - gc->dev[i].absmax[ABS_HAT0X + j] = 1; - } - - break; - - case GC_SNES: - for (j = 4; j < 8; j++) - set_bit(gc_snes_btn[j], gc->dev[i].keybit); - case GC_NES: - for (j = 0; j < 4; j++) - set_bit(gc_snes_btn[j], gc->dev[i].keybit); - break; - - case GC_MULTI2: - set_bit(BTN_THUMB, gc->dev[i].keybit); - case GC_MULTI: - set_bit(BTN_TRIGGER, gc->dev[i].keybit); - break; - - case GC_PSX: - case GC_DDR: - if(config[i + 1] == GC_DDR) { - for (j = 0; j < 4; j++) - set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit); - } else { - for (j = 0; j < 6; j++) { - set_bit(gc_psx_abs[j], gc->dev[i].absbit); - gc->dev[i].absmin[gc_psx_abs[j]] = 4; - gc->dev[i].absmax[gc_psx_abs[j]] = 252; - gc->dev[i].absflat[gc_psx_abs[j]] = 2; - } - } - - for (j = 0; j < 12; j++) - set_bit(gc_psx_btn[j], gc->dev[i].keybit); - - break; - } - sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); + err = gc_setup_pad(gc, i, pads[i]); + if (err) + goto err_free_devs; - gc->dev[i].name = gc_names[config[i + 1]]; - gc->dev[i].phys = gc->phys[i]; - gc->dev[i].id.bustype = BUS_PARPORT; - gc->dev[i].id.vendor = 0x0001; - gc->dev[i].id.product = config[i + 1]; - gc->dev[i].id.version = 0x0100; + input_register_device(gc->dev[i]); } - parport_release(gc->pd); - if (!gc->pads[0]) { - parport_unregister_device(gc->pd); - kfree(gc); - return NULL; + printk(KERN_ERR "gamecon.c: No valid devices specified\n"); + err = -EINVAL; + goto err_free_gc; } - for (i = 0; i < 5; i++) - if (gc->pads[0] & gc_status_bit[i]) { - input_register_device(gc->dev + i); - printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name); - } - + parport_put_port(pp); return gc; + + err_free_devs: + while (--i >= 0) + input_unregister_device(gc->dev[i]); + err_free_gc: + kfree(gc); + err_unreg_pardev: + parport_unregister_device(pd); + err_put_pp: + parport_put_port(pp); + err_out: + return ERR_PTR(err); +} + +static void __exit gc_remove(struct gc *gc) +{ + int i; + + for (i = 0; i < GC_MAX_DEVICES; i++) + if (gc->dev[i]) + input_unregister_device(gc->dev[i]); + parport_unregister_device(gc->pd); + kfree(gc); } static int __init gc_init(void) { - gc_base[0] = gc_probe(gc, gc_nargs); - gc_base[1] = gc_probe(gc_2, gc_nargs_2); - gc_base[2] = gc_probe(gc_3, gc_nargs_3); + int i; + int have_dev = 0; + int err = 0; - if (gc_base[0] || gc_base[1] || gc_base[2]) - return 0; + for (i = 0; i < GC_MAX_PORTS; i++) { + if (gc[i].nargs == 0 || gc[i].args[0] < 0) + continue; - return -ENODEV; + if (gc[i].nargs < 2) { + printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); + err = -EINVAL; + break; + } + + gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1); + if (IS_ERR(gc_base[i])) { + err = PTR_ERR(gc_base[i]); + break; + } + + have_dev = 1; + } + + if (err) { + while (--i >= 0) + gc_remove(gc_base[i]); + return err; + } + + return have_dev ? 0 : -ENODEV; } static void __exit gc_exit(void) { - int i, j; + int i; - for (i = 0; i < 3; i++) - if (gc_base[i]) { - for (j = 0; j < 5; j++) - if (gc_base[i]->pads[0] & gc_status_bit[j]) - input_unregister_device(gc_base[i]->dev + j); - parport_unregister_device(gc_base[i]->pd); - } + for (i = 0; i < GC_MAX_PORTS; i++) + if (gc_base[i]) + gc_remove(gc_base[i]); } module_init(gc_init); diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 8e4f92b115e6..e151f8c5bcb9 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -81,7 +81,7 @@ static short gf2k_seq_digital[] = { 590, 320, 860, 0 }; struct gf2k { struct gameport *gameport; - struct input_dev dev; + struct input_dev *dev; int reads; int bads; unsigned char id; @@ -175,7 +175,7 @@ static int gf2k_get_bits(unsigned char *buf, int pos, int num, int shift) static void gf2k_read(struct gf2k *gf2k, unsigned char *data) { - struct input_dev *dev = &gf2k->dev; + struct input_dev *dev = gf2k->dev; int i, t; for (i = 0; i < 4 && i < gf2k_axes[gf2k->id]; i++) @@ -239,13 +239,19 @@ static void gf2k_close(struct input_dev *dev) static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) { struct gf2k *gf2k; + struct input_dev *input_dev; unsigned char data[GF2K_LENGTH]; int i, err; - if (!(gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL))) - return -ENOMEM; + gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!gf2k || !input_dev) { + err = -ENOMEM; + goto fail1; + } gf2k->gameport = gameport; + gf2k->dev = input_dev; gameport_set_drvdata(gameport, gf2k); @@ -295,53 +301,52 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) gf2k->length = gf2k_lens[gf2k->id]; - init_input_dev(&gf2k->dev); + input_dev->name = gf2k_names[gf2k->id]; + input_dev->phys = gf2k->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS; + input_dev->id.product = gf2k->id; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = gf2k; - gf2k->dev.private = gf2k; - gf2k->dev.open = gf2k_open; - gf2k->dev.close = gf2k_close; - gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - gf2k->dev.name = gf2k_names[gf2k->id]; - gf2k->dev.phys = gf2k->phys; - gf2k->dev.id.bustype = BUS_GAMEPORT; - gf2k->dev.id.vendor = GAMEPORT_ID_VENDOR_GENIUS; - gf2k->dev.id.product = gf2k->id; - gf2k->dev.id.version = 0x0100; + input_dev->open = gf2k_open; + input_dev->close = gf2k_close; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < gf2k_axes[gf2k->id]; i++) - set_bit(gf2k_abs[i], gf2k->dev.absbit); + set_bit(gf2k_abs[i], input_dev->absbit); for (i = 0; i < gf2k_hats[gf2k->id]; i++) { - set_bit(ABS_HAT0X + i, gf2k->dev.absbit); - gf2k->dev.absmin[ABS_HAT0X + i] = -1; - gf2k->dev.absmax[ABS_HAT0X + i] = 1; + set_bit(ABS_HAT0X + i, input_dev->absbit); + input_dev->absmin[ABS_HAT0X + i] = -1; + input_dev->absmax[ABS_HAT0X + i] = 1; } for (i = 0; i < gf2k_joys[gf2k->id]; i++) - set_bit(gf2k_btn_joy[i], gf2k->dev.keybit); + set_bit(gf2k_btn_joy[i], input_dev->keybit); for (i = 0; i < gf2k_pads[gf2k->id]; i++) - set_bit(gf2k_btn_pad[i], gf2k->dev.keybit); + set_bit(gf2k_btn_pad[i], input_dev->keybit); gf2k_read_packet(gameport, gf2k->length, data); gf2k_read(gf2k, data); for (i = 0; i < gf2k_axes[gf2k->id]; i++) { - gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 : - gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32; - gf2k->dev.absmin[gf2k_abs[i]] = 32; - gf2k->dev.absfuzz[gf2k_abs[i]] = 8; - gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; + input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 : + input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32; + input_dev->absmin[gf2k_abs[i]] = 32; + input_dev->absfuzz[gf2k_abs[i]] = 8; + input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; } - input_register_device(&gf2k->dev); - printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys); + input_register_device(gf2k->dev); return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); + input_free_device(input_dev); kfree(gf2k); return err; } @@ -350,7 +355,7 @@ static void gf2k_disconnect(struct gameport *gameport) { struct gf2k *gf2k = gameport_get_drvdata(gameport); - input_unregister_device(&gf2k->dev); + input_unregister_device(gf2k->dev); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(gf2k); diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 9d3f910dd568..e206bb56e53c 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -55,7 +55,7 @@ MODULE_LICENSE("GPL"); struct grip { struct gameport *gameport; - struct input_dev dev[2]; + struct input_dev *dev[2]; unsigned char mode[2]; int reads; int bads; @@ -190,7 +190,7 @@ static void grip_poll(struct gameport *gameport) for (i = 0; i < 2; i++) { - dev = grip->dev + i; + dev = grip->dev[i]; grip->reads++; switch (grip->mode[i]) { @@ -297,6 +297,7 @@ static void grip_close(struct input_dev *dev) static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip *grip; + struct input_dev *input_dev; unsigned int data[GRIP_LENGTH_XT]; int i, j, t; int err; @@ -339,48 +340,56 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, grip_poll); gameport_set_poll_interval(gameport, 20); - for (i = 0; i < 2; i++) - if (grip->mode[i]) { + for (i = 0; i < 2; i++) { + if (!grip->mode[i]) + continue; - sprintf(grip->phys[i], "%s/input%d", gameport->phys, i); - - grip->dev[i].private = grip; - - grip->dev[i].open = grip_open; - grip->dev[i].close = grip_close; - - grip->dev[i].name = grip_name[grip->mode[i]]; - grip->dev[i].phys = grip->phys[i]; - grip->dev[i].id.bustype = BUS_GAMEPORT; - grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; - grip->dev[i].id.product = grip->mode[i]; - grip->dev[i].id.version = 0x0100; - - grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) { - - if (j < grip_cen[grip->mode[i]]) - input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2); - else if (j < grip_anx[grip->mode[i]]) - input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0); - else - input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0); - } - - for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++) - if (t > 0) - set_bit(t, grip->dev[i].keybit); - - printk(KERN_INFO "input: %s on %s\n", - grip_name[grip->mode[i]], gameport->phys); - input_register_device(grip->dev + i); + grip->dev[i] = input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + goto fail3; } + sprintf(grip->phys[i], "%s/input%d", gameport->phys, i); + + input_dev->name = grip_name[grip->mode[i]]; + input_dev->phys = grip->phys[i]; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; + input_dev->id.product = grip->mode[i]; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = grip; + + input_dev->open = grip_open; + input_dev->close = grip_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) { + + if (j < grip_cen[grip->mode[i]]) + input_set_abs_params(input_dev, t, 14, 52, 1, 2); + else if (j < grip_anx[grip->mode[i]]) + input_set_abs_params(input_dev, t, 3, 57, 1, 0); + else + input_set_abs_params(input_dev, t, -1, 1, 0, 0); + } + + for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++) + if (t > 0) + set_bit(t, input_dev->keybit); + + input_register_device(grip->dev[i]); + } + return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail3: for (i = 0; i < 2; i++) + if (grip->dev[i]) + input_unregister_device(grip->dev[i]); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); kfree(grip); return err; } @@ -391,8 +400,8 @@ static void grip_disconnect(struct gameport *gameport) int i; for (i = 0; i < 2; i++) - if (grip->mode[i]) - input_unregister_device(grip->dev + i); + if (grip->dev[i]) + input_unregister_device(grip->dev[i]); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(grip); diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index da17eee6f574..a0ba93ccac72 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -32,23 +32,37 @@ MODULE_LICENSE("GPL"); #define dbg(format, arg...) do {} while (0) #endif +#define GRIP_MAX_PORTS 4 /* * Grip multiport state */ +struct grip_port { + struct input_dev *dev; + int mode; + int registered; + + /* individual gamepad states */ + int buttons; + int xaxes; + int yaxes; + int dirty; /* has the state been updated? */ +}; + struct grip_mp { struct gameport *gameport; - struct input_dev dev[4]; - int mode[4]; - int registered[4]; + struct grip_port *port[GRIP_MAX_PORTS]; +// struct input_dev *dev[4]; +// int mode[4]; +// int registered[4]; int reads; int bads; /* individual gamepad states */ - int buttons[4]; - int xaxes[4]; - int yaxes[4]; - int dirty[4]; /* has the state been updated? */ +// int buttons[4]; +// int xaxes[4]; +// int yaxes[4]; +// int dirty[4]; /* has the state been updated? */ }; /* @@ -85,16 +99,16 @@ struct grip_mp { #define GRIP_MODE_GP 2 #define GRIP_MODE_C64 3 -static int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 }; -static int grip_btn_c64[] = { BTN_JOYSTICK, -1 }; +static const int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 }; +static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 }; -static int grip_abs_gp[] = { ABS_X, ABS_Y, -1 }; -static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 }; +static const int grip_abs_gp[] = { ABS_X, ABS_Y, -1 }; +static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 }; -static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 }; -static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 }; +static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 }; +static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 }; -static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" }; +static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" }; static const int init_seq[] = { 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, @@ -104,9 +118,9 @@ static const int init_seq[] = { /* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */ -static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 }; +static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 }; -static void register_slot(int i, struct grip_mp *grip); +static int register_slot(int i, struct grip_mp *grip); /* * Returns whether an odd or even number of bits are on in pkt. @@ -353,9 +367,10 @@ static int dig_mode_start(struct gameport *gameport, u32 *packet) static int get_and_decode_packet(struct grip_mp *grip, int flags) { + struct grip_port *port; u32 packet; int joytype = 0; - int slot = 0; + int slot; /* Get a packet and check for validity */ @@ -377,6 +392,8 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) if ((slot < 0) || (slot > 3)) return flags; + port = grip->port[slot]; + /* * Handle "reset" packets, which occur at startup, and when gamepads * are removed or plugged in. May contain configuration of a new gamepad. @@ -385,14 +402,14 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) joytype = (packet >> 16) & 0x1f; if (!joytype) { - if (grip->registered[slot]) { + if (port->registered) { printk(KERN_INFO "grip_mp: removing %s, slot %d\n", - grip_name[grip->mode[slot]], slot); - input_unregister_device(grip->dev + slot); - grip->registered[slot] = 0; + grip_name[port->mode], slot); + input_unregister_device(port->dev); + port->registered = 0; } dbg("Reset: grip multiport slot %d\n", slot); - grip->mode[slot] = GRIP_MODE_RESET; + port->mode = GRIP_MODE_RESET; flags |= IO_SLOT_CHANGE; return flags; } @@ -402,17 +419,17 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) if (joytype == 0x1f) { int dir = (packet >> 8) & 0xf; /* eight way directional value */ - grip->buttons[slot] = (~packet) & 0xff; - grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1; - grip->xaxes[slot] = (axis_map[dir] & 3) - 1; - grip->dirty[slot] = 1; + port->buttons = (~packet) & 0xff; + port->yaxes = ((axis_map[dir] >> 2) & 3) - 1; + port->xaxes = (axis_map[dir] & 3) - 1; + port->dirty = 1; - if (grip->mode[slot] == GRIP_MODE_RESET) + if (port->mode == GRIP_MODE_RESET) flags |= IO_SLOT_CHANGE; - grip->mode[slot] = GRIP_MODE_GP; + port->mode = GRIP_MODE_GP; - if (!grip->registered[slot]) { + if (!port->registered) { dbg("New Grip pad in multiport slot %d.\n", slot); register_slot(slot, grip); } @@ -445,9 +462,9 @@ static int slots_valid(struct grip_mp *grip) return 0; for (slot = 0; slot < 4; slot++) { - if (grip->mode[slot] == GRIP_MODE_RESET) + if (grip->port[slot]->mode == GRIP_MODE_RESET) invalid = 1; - if (grip->mode[slot] != GRIP_MODE_NONE) + if (grip->port[slot]->mode != GRIP_MODE_NONE) active = 1; } @@ -484,7 +501,7 @@ static int multiport_init(struct grip_mp *grip) /* Get packets, store multiport state, and check state's validity */ for (tries = 0; tries < 4096; tries++) { - if ( slots_valid(grip) ) { + if (slots_valid(grip)) { initialized = 1; break; } @@ -499,24 +516,24 @@ static int multiport_init(struct grip_mp *grip) static void report_slot(struct grip_mp *grip, int slot) { - struct input_dev *dev = &(grip->dev[slot]); - int i, buttons = grip->buttons[slot]; + struct grip_port *port = grip->port[slot]; + int i; /* Store button states with linux input driver */ for (i = 0; i < 8; i++) - input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1); + input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1); /* Store axis states with linux driver */ - input_report_abs(dev, ABS_X, grip->xaxes[slot]); - input_report_abs(dev, ABS_Y, grip->yaxes[slot]); + input_report_abs(port->dev, ABS_X, port->xaxes); + input_report_abs(port->dev, ABS_Y, port->yaxes); /* Tell the receiver of the events to process them */ - input_sync(dev); + input_sync(port->dev); - grip->dirty[slot] = 0; + port->dirty = 0; } /* @@ -540,7 +557,7 @@ static void grip_poll(struct gameport *gameport) } for (i = 0; i < 4; i++) - if (grip->dirty[i]) + if (grip->port[i]->dirty) report_slot(grip, i); } @@ -571,35 +588,43 @@ static void grip_close(struct input_dev *dev) * Tell the linux input layer about a newly plugged-in gamepad. */ -static void register_slot(int slot, struct grip_mp *grip) +static int register_slot(int slot, struct grip_mp *grip) { + struct grip_port *port = grip->port[slot]; + struct input_dev *input_dev; int j, t; - grip->dev[slot].private = grip; - grip->dev[slot].open = grip_open; - grip->dev[slot].close = grip_close; - grip->dev[slot].name = grip_name[grip->mode[slot]]; - grip->dev[slot].id.bustype = BUS_GAMEPORT; - grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; - grip->dev[slot].id.product = 0x0100 + grip->mode[slot]; - grip->dev[slot].id.version = 0x0100; - grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + port->dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; - for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++) - input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0); + input_dev->name = grip_name[port->mode]; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; + input_dev->id.product = 0x0100 + port->mode; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &grip->gameport->dev; + input_dev->private = grip; - for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++) + input_dev->open = grip_open; + input_dev->close = grip_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++) + input_set_abs_params(input_dev, t, -1, 1, 0, 0); + + for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++) if (t > 0) - set_bit(t, grip->dev[slot].keybit); + set_bit(t, input_dev->keybit); - input_register_device(grip->dev + slot); - grip->registered[slot] = 1; + input_register_device(port->dev); + port->registered = 1; - if (grip->dirty[slot]) /* report initial state, if any */ + if (port->dirty) /* report initial state, if any */ report_slot(grip, slot); - printk(KERN_INFO "grip_mp: added %s, slot %d\n", - grip_name[grip->mode[slot]], slot); + return 0; } static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) @@ -626,7 +651,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail2; } - if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) { + if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) { /* nothing plugged in */ err = -ENODEV; goto fail2; @@ -646,8 +671,8 @@ static void grip_disconnect(struct gameport *gameport) int i; for (i = 0; i < 4; i++) - if (grip->registered[i]) - input_unregister_device(grip->dev + i); + if (grip->port[i]->registered) + input_unregister_device(grip->port[i]->dev); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(grip); diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 6a70ec429f06..c528473c09d8 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -67,7 +67,7 @@ struct guillemot_type { struct guillemot { struct gameport *gameport; - struct input_dev dev; + struct input_dev *dev; int bads; int reads; struct guillemot_type *type; @@ -123,7 +123,7 @@ static int guillemot_read_packet(struct gameport *gameport, u8 *data) static void guillemot_poll(struct gameport *gameport) { struct guillemot *guillemot = gameport_get_drvdata(gameport); - struct input_dev *dev = &guillemot->dev; + struct input_dev *dev = guillemot->dev; u8 data[GUILLEMOT_MAX_LENGTH]; int i; @@ -179,14 +179,20 @@ static void guillemot_close(struct input_dev *dev) static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv) { struct guillemot *guillemot; + struct input_dev *input_dev; u8 data[GUILLEMOT_MAX_LENGTH]; int i, t; int err; - if (!(guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL))) - return -ENOMEM; + guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!guillemot || !input_dev) { + err = -ENOMEM; + goto fail1; + } guillemot->gameport = gameport; + guillemot->dev = input_dev; gameport_set_drvdata(gameport, guillemot); @@ -216,41 +222,40 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * gameport_set_poll_interval(gameport, 20); sprintf(guillemot->phys, "%s/input0", gameport->phys); - guillemot->type = guillemot_type + i; - guillemot->dev.private = guillemot; - guillemot->dev.open = guillemot_open; - guillemot->dev.close = guillemot_close; + input_dev->name = guillemot_type[i].name; + input_dev->phys = guillemot->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; + input_dev->id.product = guillemot_type[i].id; + input_dev->id.version = (int)data[14] << 8 | data[15]; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = guillemot; - guillemot->dev.name = guillemot_type[i].name; - guillemot->dev.phys = guillemot->phys; - guillemot->dev.id.bustype = BUS_GAMEPORT; - guillemot->dev.id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; - guillemot->dev.id.product = guillemot_type[i].id; - guillemot->dev.id.version = (int)data[14] << 8 | data[15]; + input_dev->open = guillemot_open; + input_dev->close = guillemot_close; - guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++) - input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0); + input_set_abs_params(input_dev, t, 0, 255, 0, 0); if (guillemot->type->hat) { - input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0); - input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0); + input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); + input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0); } for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) - set_bit(t, guillemot->dev.keybit); + set_bit(t, input_dev->keybit); - input_register_device(&guillemot->dev); - printk(KERN_INFO "input: %s ver %d.%02d on %s\n", - guillemot->type->name, data[14], data[15], gameport->phys); + input_register_device(guillemot->dev); return 0; fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); + input_free_device(input_dev); kfree(guillemot); return err; } @@ -260,7 +265,7 @@ static void guillemot_disconnect(struct gameport *gameport) struct guillemot *guillemot = gameport_get_drvdata(gameport); printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys); - input_unregister_device(&guillemot->dev); + input_unregister_device(guillemot->dev); gameport_close(gameport); kfree(guillemot); } diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index e31b7b93fde2..64b9c31c47fc 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -144,7 +144,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) int is_update; /* Check this effect type is supported by this device */ - if (!test_bit(effect->type, iforce->dev.ffbit)) + if (!test_bit(effect->type, iforce->dev->ffbit)) return -EINVAL; /* @@ -152,30 +152,31 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) */ if (effect->id == -1) { - for (id=0; id < FF_EFFECTS_MAX; ++id) - if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break; + for (id = 0; id < FF_EFFECTS_MAX; ++id) + if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) + break; - if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max) + if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max) return -ENOMEM; effect->id = id; iforce->core_effects[id].owner = current->pid; - iforce->core_effects[id].flags[0] = (1<core_effects[id].flags[0] = (1 << FF_CORE_IS_USED); /* Only IS_USED bit must be set */ is_update = FALSE; } else { /* We want to update an effect */ - if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES; + if (!CHECK_OWNERSHIP(effect->id, iforce)) + return -EACCES; /* Parameter type cannot be updated */ if (effect->type != iforce->core_effects[effect->id].effect.type) return -EINVAL; /* Check the effect is not already being updated */ - if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) { + if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) return -EAGAIN; - } is_update = TRUE; } @@ -339,15 +340,19 @@ void iforce_delete_device(struct iforce *iforce) int iforce_init_device(struct iforce *iforce) { + struct input_dev *input_dev; unsigned char c[] = "CEOV"; int i; + input_dev = input_allocate_device(); + if (input_dev) + return -ENOMEM; + init_waitqueue_head(&iforce->wait); spin_lock_init(&iforce->xmit_lock); init_MUTEX(&iforce->mem_mutex); iforce->xmit.buf = iforce->xmit_data; - - iforce->dev.ff_effects_max = 10; + iforce->dev = input_dev; /* * Input device fields. @@ -356,26 +361,27 @@ int iforce_init_device(struct iforce *iforce) switch (iforce->bus) { #ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: - iforce->dev.id.bustype = BUS_USB; - iforce->dev.dev = &iforce->usbdev->dev; + input_dev->id.bustype = BUS_USB; + input_dev->cdev.dev = &iforce->usbdev->dev; break; #endif #ifdef CONFIG_JOYSTICK_IFORCE_232 case IFORCE_232: - iforce->dev.id.bustype = BUS_RS232; - iforce->dev.dev = &iforce->serio->dev; + input_dev->id.bustype = BUS_RS232; + input_dev->cdev.dev = &iforce->serio->dev; break; #endif } - iforce->dev.private = iforce; - iforce->dev.name = "Unknown I-Force device"; - iforce->dev.open = iforce_open; - iforce->dev.close = iforce_release; - iforce->dev.flush = iforce_flush; - iforce->dev.event = iforce_input_event; - iforce->dev.upload_effect = iforce_upload_effect; - iforce->dev.erase_effect = iforce_erase_effect; + input_dev->private = iforce; + input_dev->name = "Unknown I-Force device"; + input_dev->open = iforce_open; + input_dev->close = iforce_release; + input_dev->flush = iforce_flush; + input_dev->event = iforce_input_event; + input_dev->upload_effect = iforce_upload_effect; + input_dev->erase_effect = iforce_erase_effect; + input_dev->ff_effects_max = 10; /* * On-device memory allocation. @@ -399,7 +405,8 @@ int iforce_init_device(struct iforce *iforce) if (i == 20) { /* 5 seconds */ printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); - return -1; + input_free_device(input_dev); + return -ENODEV; } /* @@ -407,12 +414,12 @@ int iforce_init_device(struct iforce *iforce) */ if (!iforce_get_id_packet(iforce, "M")) - iforce->dev.id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; + input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; else printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n"); if (!iforce_get_id_packet(iforce, "P")) - iforce->dev.id.product = (iforce->edata[2] << 8) | iforce->edata[1]; + input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; else printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n"); @@ -422,15 +429,15 @@ int iforce_init_device(struct iforce *iforce) printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n"); if (!iforce_get_id_packet(iforce, "N")) - iforce->dev.ff_effects_max = iforce->edata[1]; + iforce->dev->ff_effects_max = iforce->edata[1]; else printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n"); /* Check if the device can store more effects than the driver can really handle */ - if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) { + if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) { printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n", - iforce->dev.ff_effects_max, FF_EFFECTS_MAX); - iforce->dev.ff_effects_max = FF_EFFECTS_MAX; + iforce->dev->ff_effects_max, FF_EFFECTS_MAX); + iforce->dev->ff_effects_max = FF_EFFECTS_MAX; } /* @@ -453,29 +460,28 @@ int iforce_init_device(struct iforce *iforce) */ for (i = 0; iforce_device[i].idvendor; i++) - if (iforce_device[i].idvendor == iforce->dev.id.vendor && - iforce_device[i].idproduct == iforce->dev.id.product) + if (iforce_device[i].idvendor == input_dev->id.vendor && + iforce_device[i].idproduct == input_dev->id.product) break; iforce->type = iforce_device + i; - iforce->dev.name = iforce->type->name; + input_dev->name = iforce->type->name; /* * Set input device bitfields and ranges. */ - iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS); for (i = 0; iforce->type->btn[i] >= 0; i++) { signed short t = iforce->type->btn[i]; - set_bit(t, iforce->dev.keybit); + set_bit(t, input_dev->keybit); } - set_bit(BTN_DEAD, iforce->dev.keybit); + set_bit(BTN_DEAD, input_dev->keybit); for (i = 0; iforce->type->abs[i] >= 0; i++) { signed short t = iforce->type->abs[i]; - set_bit(t, iforce->dev.absbit); switch (t) { @@ -483,52 +489,42 @@ int iforce_init_device(struct iforce *iforce) case ABS_Y: case ABS_WHEEL: - iforce->dev.absmax[t] = 1920; - iforce->dev.absmin[t] = -1920; - iforce->dev.absflat[t] = 128; - iforce->dev.absfuzz[t] = 16; - - set_bit(t, iforce->dev.ffbit); + input_set_abs_params(input_dev, t, -1920, 1920, 16, 128); + set_bit(t, input_dev->ffbit); break; case ABS_THROTTLE: case ABS_GAS: case ABS_BRAKE: - iforce->dev.absmax[t] = 255; - iforce->dev.absmin[t] = 0; + input_set_abs_params(input_dev, t, 0, 255, 0, 0); break; case ABS_RUDDER: - iforce->dev.absmax[t] = 127; - iforce->dev.absmin[t] = -128; + input_set_abs_params(input_dev, t, -128, 127, 0, 0); break; case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y: - iforce->dev.absmax[t] = 1; - iforce->dev.absmin[t] = -1; + + input_set_abs_params(input_dev, t, -1, 1, 0, 0); break; } } for (i = 0; iforce->type->ff[i] >= 0; i++) - set_bit(iforce->type->ff[i], iforce->dev.ffbit); + set_bit(iforce->type->ff[i], input_dev->ffbit); /* * Register input device. */ - input_register_device(&iforce->dev); + input_register_device(iforce->dev); - printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open); - - printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n", - iforce->dev.name, iforce->dev.ff_effects_max, - iforce->device_memory.end); + printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); return 0; } diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index e5a31e55d3e2..4a2629243e19 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -139,7 +139,8 @@ printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value); static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) { int i; - for (i=0; idev.ff_effects_max; ++i) { + + for (i = 0; i < iforce->dev->ff_effects_max; ++i) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && (iforce->core_effects[i].mod1_chunk.start == addr || iforce->core_effects[i].mod2_chunk.start == addr)) { @@ -153,7 +154,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs) { - struct input_dev *dev = &iforce->dev; + struct input_dev *dev = iforce->dev; int i; static int being_used = 0; diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index 11f51905cba7..64a78c515484 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c @@ -131,11 +131,10 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) struct iforce *iforce; int err; - if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) + iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL); + if (!iforce) return -ENOMEM; - memset(iforce, 0, sizeof(struct iforce)); - iforce->bus = IFORCE_232; iforce->serio = serio; @@ -148,7 +147,8 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) return err; } - if (iforce_init_device(iforce)) { + err = iforce_init_device(iforce); + if (err) { serio_close(serio); serio_set_drvdata(serio, NULL); kfree(iforce); @@ -162,7 +162,7 @@ static void iforce_serio_disconnect(struct serio *serio) { struct iforce *iforce = serio_get_drvdata(serio); - input_unregister_device(&iforce->dev); + input_unregister_device(iforce->dev); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(iforce); diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 58600f91eff5..64b4a3080985 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -135,28 +135,24 @@ static int iforce_usb_probe(struct usb_interface *intf, struct usb_host_interface *interface; struct usb_endpoint_descriptor *epirq, *epout; struct iforce *iforce; + int err = -ENOMEM; interface = intf->cur_altsetting; epirq = &interface->endpoint[0].desc; epout = &interface->endpoint[1].desc; - if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) + if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) goto fail; - memset(iforce, 0, sizeof(struct iforce)); - - if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) { + if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) goto fail; - } - if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) { + if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) goto fail; - } - if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) { + if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) goto fail; - } iforce->bus = IFORCE_USB; iforce->usbdev = dev; @@ -174,7 +170,9 @@ static int iforce_usb_probe(struct usb_interface *intf, usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0), (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce); - if (iforce_init_device(iforce)) goto fail; + err = iforce_init_device(iforce); + if (err) + goto fail; usb_set_intfdata(intf, iforce); return 0; @@ -187,7 +185,7 @@ static int iforce_usb_probe(struct usb_interface *intf, kfree(iforce); } - return -ENODEV; + return err; } /* Called by iforce_delete() */ @@ -211,7 +209,7 @@ static void iforce_usb_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (iforce) { iforce->usbdev = NULL; - input_unregister_device(&iforce->dev); + input_unregister_device(iforce->dev); if (!open) { iforce_delete_device(iforce); diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index bce247bc300b..146f406b8f8a 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -117,7 +117,7 @@ struct iforce_device { }; struct iforce { - struct input_dev dev; /* Input device interface */ + struct input_dev *dev; /* Input device interface */ struct iforce_device *type; int bus; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index d7b3472bd686..8511ee7bb263 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); struct interact { struct gameport *gameport; - struct input_dev dev; + struct input_dev *dev; int bads; int reads; unsigned char type; @@ -130,7 +130,7 @@ static int interact_read_packet(struct gameport *gameport, int length, u32 *data static void interact_poll(struct gameport *gameport) { struct interact *interact = gameport_get_drvdata(gameport); - struct input_dev *dev = &interact->dev; + struct input_dev *dev = interact->dev; u32 data[3]; int i; @@ -208,14 +208,20 @@ static void interact_close(struct input_dev *dev) static int interact_connect(struct gameport *gameport, struct gameport_driver *drv) { struct interact *interact; + struct input_dev *input_dev; __u32 data[3]; int i, t; int err; - if (!(interact = kzalloc(sizeof(struct interact), GFP_KERNEL))) - return -ENOMEM; + interact = kzalloc(sizeof(struct interact), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!interact || !input_dev) { + err = -ENOMEM; + goto fail1; + } interact->gameport = gameport; + interact->dev = input_dev; gameport_set_drvdata(gameport, interact); @@ -249,41 +255,40 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d interact->type = i; interact->length = interact_type[i].length; - interact->dev.private = interact; - interact->dev.open = interact_open; - interact->dev.close = interact_close; + input_dev->name = interact_type[i].name; + input_dev->phys = interact->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; + input_dev->id.product = interact_type[i].id; + input_dev->id.version = 0x0100; + input_dev->private = interact; - interact->dev.name = interact_type[i].name; - interact->dev.phys = interact->phys; - interact->dev.id.bustype = BUS_GAMEPORT; - interact->dev.id.vendor = GAMEPORT_ID_VENDOR_INTERACT; - interact->dev.id.product = interact_type[i].id; - interact->dev.id.version = 0x0100; + input_dev->open = interact_open; + input_dev->close = interact_close; - interact->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) { - set_bit(t, interact->dev.absbit); + set_bit(t, input_dev->absbit); if (i < interact_type[interact->type].b8) { - interact->dev.absmin[t] = 0; - interact->dev.absmax[t] = 255; + input_dev->absmin[t] = 0; + input_dev->absmax[t] = 255; } else { - interact->dev.absmin[t] = -1; - interact->dev.absmax[t] = 1; + input_dev->absmin[t] = -1; + input_dev->absmax[t] = 1; } } for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) - set_bit(t, interact->dev.keybit); + set_bit(t, input_dev->keybit); - input_register_device(&interact->dev); - printk(KERN_INFO "input: %s on %s\n", - interact_type[interact->type].name, gameport->phys); + input_register_device(interact->dev); return 0; fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); + input_free_device(input_dev); kfree(interact); return err; } @@ -292,7 +297,7 @@ static void interact_disconnect(struct gameport *gameport) { struct interact *interact = gameport_get_drvdata(gameport); - input_unregister_device(&interact->dev); + input_unregister_device(interact->dev); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(interact); diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 1ba503627242..ca3cc2319d6a 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -49,14 +49,13 @@ MODULE_LICENSE("GPL"); static int magellan_buttons[] = { BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 }; static int magellan_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ }; -static char *magellan_name = "LogiCad3D Magellan / SpaceMouse"; /* * Per-Magellan data. */ struct magellan { - struct input_dev dev; + struct input_dev *dev; int idx; unsigned char data[MAGELLAN_MAX_LENGTH]; char phys[32]; @@ -85,7 +84,7 @@ static int magellan_crunch_nibbles(unsigned char *data, int count) static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs) { - struct input_dev *dev = &magellan->dev; + struct input_dev *dev = magellan->dev; unsigned char *data = magellan->data; int i, t; @@ -138,9 +137,9 @@ static void magellan_disconnect(struct serio *serio) { struct magellan* magellan = serio_get_drvdata(serio); - input_unregister_device(&magellan->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(magellan->dev); kfree(magellan); } @@ -153,52 +152,48 @@ static void magellan_disconnect(struct serio *serio) static int magellan_connect(struct serio *serio, struct serio_driver *drv) { struct magellan *magellan; - int i, t; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; + int i; - if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL))) - return -ENOMEM; - - memset(magellan, 0, sizeof(struct magellan)); - - magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (i = 0; i < 9; i++) - set_bit(magellan_buttons[i], magellan->dev.keybit); - - for (i = 0; i < 6; i++) { - t = magellan_axes[i]; - set_bit(t, magellan->dev.absbit); - magellan->dev.absmin[t] = -360; - magellan->dev.absmax[t] = 360; - } + magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!magellan || !input_dev) + goto fail; + magellan->dev = input_dev; sprintf(magellan->phys, "%s/input0", serio->phys); - init_input_dev(&magellan->dev); - magellan->dev.private = magellan; - magellan->dev.name = magellan_name; - magellan->dev.phys = magellan->phys; - magellan->dev.id.bustype = BUS_RS232; - magellan->dev.id.vendor = SERIO_MAGELLAN; - magellan->dev.id.product = 0x0001; - magellan->dev.id.version = 0x0100; - magellan->dev.dev = &serio->dev; + input_dev->name = "LogiCad3D Magellan / SpaceMouse"; + input_dev->phys = magellan->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_MAGELLAN; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = magellan; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; i < 9; i++) + set_bit(magellan_buttons[i], input_dev->keybit); + + for (i = 0; i < 6; i++) + input_set_abs_params(input_dev, magellan_axes[i], -360, 360, 0, 0); serio_set_drvdata(serio, magellan); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(magellan); - return err; - } - - input_register_device(&magellan->dev); - - printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys); + if (err) + goto fail; + input_register_device(magellan->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(magellan); + return err; } /* diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 9e0353721a35..eaaad45cc750 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -113,7 +113,7 @@ static struct { struct sw { struct gameport *gameport; - struct input_dev dev[4]; + struct input_dev *dev[4]; char name[64]; char phys[4][32]; int length; @@ -301,7 +301,7 @@ static int sw_check(__u64 t) static int sw_parse(unsigned char *buf, struct sw *sw) { int hat, i, j; - struct input_dev *dev = sw->dev; + struct input_dev *dev; switch (sw->type) { @@ -310,6 +310,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8) return -1; + dev = sw->dev[0]; + input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7)); input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7)); input_report_abs(dev, ABS_RZ, (GB(35,2) << 7) | GB(40,7)); @@ -335,13 +337,13 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (sw_parity(GB(i*15,15))) return -1; - input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); - input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); + input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); + input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); for (j = 0; j < 10; j++) - input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); + input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); - input_sync(dev + i); + input_sync(sw->dev[i]); } return 0; @@ -352,6 +354,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8) return -1; + dev = sw->dev[0]; input_report_abs(dev, ABS_X, GB( 9,10)); input_report_abs(dev, ABS_Y, GB(19,10)); input_report_abs(dev, ABS_RZ, GB(36, 6)); @@ -372,6 +375,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8) return -1; + dev = sw->dev[0]; input_report_abs(dev, ABS_X, GB( 0,10)); input_report_abs(dev, ABS_Y, GB(16,10)); input_report_abs(dev, ABS_THROTTLE, GB(32, 6)); @@ -396,6 +400,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (!sw_parity(GB(0,33))) return -1; + dev = sw->dev[0]; input_report_abs(dev, ABS_RX, GB( 0,10)); input_report_abs(dev, ABS_RUDDER, GB(10, 6)); input_report_abs(dev, ABS_THROTTLE, GB(16, 6)); @@ -581,6 +586,7 @@ static int sw_guess_mode(unsigned char *buf, int len) static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) { struct sw *sw; + struct input_dev *input_dev; int i, j, k, l; int err; unsigned char *buf = NULL; /* [SW_LENGTH] */ @@ -729,42 +735,50 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); - sw->dev[i].private = sw; + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + goto fail3; + } - sw->dev[i].open = sw_open; - sw->dev[i].close = sw_close; + input_dev->name = sw->name; + input_dev->phys = sw->phys[i]; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; + input_dev->id.product = sw->type; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = sw; - sw->dev[i].name = sw->name; - sw->dev[i].phys = sw->phys[i]; - sw->dev[i].id.bustype = BUS_GAMEPORT; - sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; - sw->dev[i].id.product = sw->type; - sw->dev[i].id.version = 0x0100; + input_dev->open = sw_open; + input_dev->close = sw_close; - sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (j = 0; (bits = sw_bit[sw->type][j]); j++) { code = sw_abs[sw->type][j]; - set_bit(code, sw->dev[i].absbit); - sw->dev[i].absmax[code] = (1 << bits) - 1; - sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0; - sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0; + set_bit(code, input_dev->absbit); + input_dev->absmax[code] = (1 << bits) - 1; + input_dev->absmin[code] = (bits == 1) ? -1 : 0; + input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0; if (code != ABS_THROTTLE) - sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0; + input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0; } for (j = 0; (code = sw_btn[sw->type][j]); j++) - set_bit(code, sw->dev[i].keybit); + set_bit(code, input_dev->keybit); - input_register_device(sw->dev + i); - printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n", - sw->name, comment, gameport->phys, m, l, k); + dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); + + input_register_device(sw->dev[i]); } return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail3: while (--i >= 0) + input_unregister_device(sw->dev[i]); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); kfree(sw); kfree(buf); kfree(idbuf); @@ -777,7 +791,7 @@ static void sw_disconnect(struct gameport *gameport) int i; for (i = 0; i < sw->number; i++) - input_unregister_device(sw->dev + i); + input_unregister_device(sw->dev[i]); gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(sw); diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index a436f2220856..d6f8db8ec3fd 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -70,8 +70,7 @@ static char *spaceball_names[] = { */ struct spaceball { - struct input_dev dev; - struct serio *serio; + struct input_dev *dev; int idx; int escape; unsigned char data[SPACEBALL_MAX_LENGTH]; @@ -85,7 +84,7 @@ struct spaceball { static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs) { - struct input_dev *dev = &spaceball->dev; + struct input_dev *dev = spaceball->dev; unsigned char *data = spaceball->data; int i; @@ -193,9 +192,9 @@ static void spaceball_disconnect(struct serio *serio) { struct spaceball* spaceball = serio_get_drvdata(serio); - input_unregister_device(&spaceball->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(spaceball->dev); kfree(spaceball); } @@ -208,69 +207,62 @@ static void spaceball_disconnect(struct serio *serio) static int spaceball_connect(struct serio *serio, struct serio_driver *drv) { struct spaceball *spaceball; - int i, t, id; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; + int i, id; if ((id = serio->id.id) > SPACEBALL_MAX_ID) return -ENODEV; - if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL))) - return - ENOMEM; + spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!spaceball || !input_dev) + goto fail; - memset(spaceball, 0, sizeof(struct spaceball)); + spaceball->dev = input_dev; + sprintf(spaceball->phys, "%s/input0", serio->phys); - spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->name = spaceball_names[id]; + input_dev->phys = spaceball->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_SPACEBALL; + input_dev->id.product = id; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = spaceball; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); switch (id) { case SPACEBALL_4000FLX: case SPACEBALL_4000FLX_L: - spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9); - spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE); + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9); + input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE); default: - spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8); case SPACEBALL_3003C: - spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8); + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8); } - for (i = 0; i < 6; i++) { - t = spaceball_axes[i]; - set_bit(t, spaceball->dev.absbit); - spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600; - spaceball->dev.absmax[t] = i < 3 ? 8000 : 1600; - spaceball->dev.absflat[t] = i < 3 ? 40 : 8; - spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2; + for (i = 0; i < 3; i++) { + input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40); + input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8); } - spaceball->serio = serio; - spaceball->dev.private = spaceball; - - sprintf(spaceball->phys, "%s/input0", serio->phys); - - init_input_dev(&spaceball->dev); - spaceball->dev.name = spaceball_names[id]; - spaceball->dev.phys = spaceball->phys; - spaceball->dev.id.bustype = BUS_RS232; - spaceball->dev.id.vendor = SERIO_SPACEBALL; - spaceball->dev.id.product = id; - spaceball->dev.id.version = 0x0100; - spaceball->dev.dev = &serio->dev; - serio_set_drvdata(serio, spaceball); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(spaceball); - return err; - } - - input_register_device(&spaceball->dev); - - printk(KERN_INFO "input: %s on serio%s\n", - spaceball_names[id], serio->phys); + if (err) + goto fail; + input_register_device(spaceball->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(spaceball); + return err; } /* diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index 01fd2e4791ae..7c123a01c58e 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -52,15 +52,13 @@ MODULE_LICENSE("GPL"); static int spaceorb_buttons[] = { BTN_TL, BTN_TR, BTN_Y, BTN_X, BTN_B, BTN_A }; static int spaceorb_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ }; -static char *spaceorb_name = "SpaceTec SpaceOrb 360 / Avenger"; /* * Per-Orb data. */ struct spaceorb { - struct input_dev dev; - struct serio *serio; + struct input_dev *dev; int idx; unsigned char data[SPACEORB_MAX_LENGTH]; char phys[32]; @@ -78,7 +76,7 @@ static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs) { - struct input_dev *dev = &spaceorb->dev; + struct input_dev *dev = spaceorb->dev; unsigned char *data = spaceorb->data; unsigned char c = 0; int axes[6]; @@ -95,8 +93,8 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r case 'R': /* Reset packet */ spaceorb->data[spaceorb->idx - 1] = 0; for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++); - printk(KERN_INFO "input: %s [%s] on %s\n", - spaceorb_name, spaceorb->data + i, spaceorb->serio->phys); + printk(KERN_INFO "input: %s [%s] is %s\n", + dev->name, spaceorb->data + i, spaceorb->phys); break; case 'D': /* Ball + button data */ @@ -123,7 +121,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r case 'E': /* Error packet */ if (spaceorb->idx != 4) return; - printk(KERN_ERR "joy-spaceorb: Device error. [ "); + printk(KERN_ERR "spaceorb: Device error. [ "); for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]); printk("]\n"); break; @@ -154,9 +152,9 @@ static void spaceorb_disconnect(struct serio *serio) { struct spaceorb* spaceorb = serio_get_drvdata(serio); - input_unregister_device(&spaceorb->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(spaceorb->dev); kfree(spaceorb); } @@ -169,52 +167,48 @@ static void spaceorb_disconnect(struct serio *serio) static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) { struct spaceorb *spaceorb; - int i, t; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; + int i; - if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL))) - return -ENOMEM; - - memset(spaceorb, 0, sizeof(struct spaceorb)); - - spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (i = 0; i < 6; i++) - set_bit(spaceorb_buttons[i], spaceorb->dev.keybit); - - for (i = 0; i < 6; i++) { - t = spaceorb_axes[i]; - set_bit(t, spaceorb->dev.absbit); - spaceorb->dev.absmin[t] = -508; - spaceorb->dev.absmax[t] = 508; - } - - spaceorb->serio = serio; - spaceorb->dev.private = spaceorb; + spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!spaceorb || !input_dev) + goto fail; + spaceorb->dev = input_dev; sprintf(spaceorb->phys, "%s/input0", serio->phys); - init_input_dev(&spaceorb->dev); - spaceorb->dev.name = spaceorb_name; - spaceorb->dev.phys = spaceorb->phys; - spaceorb->dev.id.bustype = BUS_RS232; - spaceorb->dev.id.vendor = SERIO_SPACEORB; - spaceorb->dev.id.product = 0x0001; - spaceorb->dev.id.version = 0x0100; - spaceorb->dev.dev = &serio->dev; + input_dev->name = "SpaceTec SpaceOrb 360 / Avenger"; + input_dev->phys = spaceorb->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_SPACEORB; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = spaceorb; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; i < 6; i++) + set_bit(spaceorb_buttons[i], input_dev->keybit); + + for (i = 0; i < 6; i++) + input_set_abs_params(input_dev, spaceorb_axes[i], -508, 508, 0, 0); serio_set_drvdata(serio, spaceorb); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(spaceorb); - return err; - } - - input_register_device(&spaceorb->dev); + if (err) + goto fail; + input_register_device(spaceorb->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(spaceorb); + return err; } /* diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 6f6e6753d590..0a9ed1d30636 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -48,14 +48,12 @@ MODULE_LICENSE("GPL"); #define STINGER_MAX_LENGTH 8 -static char *stinger_name = "Gravis Stinger"; - /* * Per-Stinger data. */ struct stinger { - struct input_dev dev; + struct input_dev *dev; int idx; unsigned char data[STINGER_MAX_LENGTH]; char phys[32]; @@ -68,7 +66,7 @@ struct stinger { static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs) { - struct input_dev *dev = &stinger->dev; + struct input_dev *dev = stinger->dev; unsigned char *data = stinger->data; if (!stinger->idx) return; @@ -126,9 +124,9 @@ static void stinger_disconnect(struct serio *serio) { struct stinger *stinger = serio_get_drvdata(serio); - input_unregister_device(&stinger->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(stinger->dev); kfree(stinger); } @@ -141,53 +139,46 @@ static void stinger_disconnect(struct serio *serio) static int stinger_connect(struct serio *serio, struct serio_driver *drv) { struct stinger *stinger; - int i; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; - if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL))) - return -ENOMEM; - - memset(stinger, 0, sizeof(struct stinger)); - - stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \ - BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \ - BIT(BTN_START) | BIT(BTN_SELECT); - stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!stinger || !input_dev) + goto fail; + stinger->dev = input_dev; sprintf(stinger->phys, "%s/serio0", serio->phys); - init_input_dev(&stinger->dev); - stinger->dev.name = stinger_name; - stinger->dev.phys = stinger->phys; - stinger->dev.id.bustype = BUS_RS232; - stinger->dev.id.vendor = SERIO_STINGER; - stinger->dev.id.product = 0x0001; - stinger->dev.id.version = 0x0100; - stinger->dev.dev = &serio->dev; + input_dev->name = "Gravis Stinger"; + input_dev->phys = stinger->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_STINGER; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = stinger; - for (i = 0; i < 2; i++) { - stinger->dev.absmax[ABS_X+i] = 64; - stinger->dev.absmin[ABS_X+i] = -64; - stinger->dev.absflat[ABS_X+i] = 4; - } - - stinger->dev.private = stinger; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | + BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | + BIT(BTN_START) | BIT(BTN_SELECT); + input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4); + input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4); serio_set_drvdata(serio, stinger); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(stinger); - return err; - } - - input_register_device(&stinger->dev); - - printk(KERN_INFO "input: %s on %s\n", stinger_name, serio->phys); + if (err) + goto fail; + input_register_device(stinger->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(stinger); + return err; } /* diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 7431efc4330e..3a7d1bb46472 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -63,37 +63,70 @@ MODULE_LICENSE("GPL"); #define TMDC_ABS_HAT 4 #define TMDC_BTN 16 -static unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 }; -static unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 }; +static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 }; +static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 }; -static signed char tmdc_abs[TMDC_ABS] = +static const signed char tmdc_abs[TMDC_ABS] = { ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE, ABS_RX, ABS_RY, ABS_RZ }; -static signed char tmdc_abs_hat[TMDC_ABS_HAT] = +static const signed char tmdc_abs_hat[TMDC_ABS_HAT] = { ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y }; -static signed char tmdc_abs_at[TMDC_ABS] = +static const signed char tmdc_abs_at[TMDC_ABS] = { ABS_X, ABS_Y, ABS_RUDDER, -1, ABS_THROTTLE }; -static signed char tmdc_abs_fm[TMDC_ABS] = +static const signed char tmdc_abs_fm[TMDC_ABS] = { ABS_RX, ABS_RY, ABS_X, ABS_Y }; -static short tmdc_btn_pad[TMDC_BTN] = +static const short tmdc_btn_pad[TMDC_BTN] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR }; -static short tmdc_btn_joy[TMDC_BTN] = +static const short tmdc_btn_joy[TMDC_BTN] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE, BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z }; -static short tmdc_btn_fm[TMDC_BTN] = +static const short tmdc_btn_fm[TMDC_BTN] = { BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 }; -static short tmdc_btn_at[TMDC_BTN] = +static const short tmdc_btn_at[TMDC_BTN] = { BTN_TRIGGER, BTN_THUMB2, BTN_PINKIE, BTN_THUMB, BTN_BASE6, BTN_BASE5, BTN_BASE4, BTN_BASE3, BTN_BASE2, BTN_BASE }; -static struct { +static const struct { int x; int y; } tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}}; +static const struct tmdc_model { + unsigned char id; + const char *name; + char abs; + char hats; + char btnc[4]; + char btno[4]; + const signed char *axes; + const short *buttons; +} tmdc_models[] = { + { 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy }, + { 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad }, + { 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at }, + { 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm }, + { 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad }, + { 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy } +}; + + +struct tmdc_port { + struct input_dev *dev; + char name[64]; + char phys[32]; + int mode; + const signed char *abs; + const short *btn; + unsigned char absc; + unsigned char btnc[4]; + unsigned char btno[4]; +}; + struct tmdc { struct gameport *gameport; - struct input_dev dev[2]; + struct tmdc_port *port[2]; +#if 0 + struct input_dev *dev[2]; char name[2][64]; char phys[2][32]; int mode[2]; @@ -102,6 +135,7 @@ struct tmdc { unsigned char absc[2]; unsigned char btnc[2][4]; unsigned char btno[2][4]; +#endif int reads; int bads; unsigned char exists; @@ -156,6 +190,50 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1); } +static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data) +{ + int i, k, l; + + if (data[TMDC_BYTE_ID] != port->mode) + return -1; + + for (i = 0; i < port->absc; i++) { + if (port->abs[i] < 0) + return 0; + + input_report_abs(port->dev, port->abs[i], data[tmdc_byte_a[i]]); + } + + switch (port->mode) { + + case TMDC_MODE_M3DI: + + i = tmdc_byte_d[0]; + input_report_abs(port->dev, ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1)); + input_report_abs(port->dev, ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i] & 1)); + break; + + case TMDC_MODE_AT: + + i = tmdc_byte_a[3]; + input_report_abs(port->dev, ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x); + input_report_abs(port->dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y); + break; + + } + + for (k = l = 0; k < 4; k++) { + for (i = 0; i < port->btnc[k]; i++) + input_report_key(port->dev, port->btn[i + l], + ((data[tmdc_byte_d[k]] >> (i + port->btno[k])) & 1)); + l += port->btnc[k]; + } + + input_sync(port->dev); + + return 0; +} + /* * tmdc_poll() reads and analyzes ThrustMaster joystick data. */ @@ -164,57 +242,21 @@ static void tmdc_poll(struct gameport *gameport) { unsigned char data[2][TMDC_MAX_LENGTH]; struct tmdc *tmdc = gameport_get_drvdata(gameport); - struct input_dev *dev; unsigned char r, bad = 0; - int i, j, k, l; + int i; tmdc->reads++; if ((r = tmdc_read_packet(tmdc->gameport, data)) != tmdc->exists) bad = 1; - else + else { + for (i = 0; i < 2; i++) { + if (r & (1 << i) & tmdc->exists) { - for (j = 0; j < 2; j++) - if (r & (1 << j) & tmdc->exists) { - - if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) { - bad = 1; - continue; + if (tmdc_parse_packet(tmdc->port[i], data[i])) + bad = 1; } - - dev = tmdc->dev + j; - - for (i = 0; i < tmdc->absc[j]; i++) { - if (tmdc->abs[j][i] < 0) continue; - input_report_abs(dev, tmdc->abs[j][i], data[j][tmdc_byte_a[i]]); - } - - switch (tmdc->mode[j]) { - - case TMDC_MODE_M3DI: - - i = tmdc_byte_d[0]; - input_report_abs(dev, ABS_HAT0X, ((data[j][i] >> 3) & 1) - ((data[j][i] >> 1) & 1)); - input_report_abs(dev, ABS_HAT0Y, ((data[j][i] >> 2) & 1) - ( data[j][i] & 1)); - break; - - case TMDC_MODE_AT: - - i = tmdc_byte_a[3]; - input_report_abs(dev, ABS_HAT0X, tmdc_hat_to_axis[(data[j][i] - 141) / 25].x); - input_report_abs(dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[j][i] - 141) / 25].y); - break; - - } - - for (k = l = 0; k < 4; k++) { - for (i = 0; i < tmdc->btnc[j][k]; i++) - input_report_key(dev, tmdc->btn[j][i + l], - ((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1)); - l += tmdc->btnc[j][k]; - } - - input_sync(dev); + } } tmdc->bads += bad; @@ -235,31 +277,89 @@ static void tmdc_close(struct input_dev *dev) gameport_stop_polling(tmdc->gameport); } +static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) +{ + const struct tmdc_model *model; + struct tmdc_port *port; + struct input_dev *input_dev; + int i, j, b = 0; + + tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!port || !input_dev) { + kfree(port); + input_free_device(input_dev); + return -ENOMEM; + } + + port->mode = data[TMDC_BYTE_ID]; + + for (model = tmdc_models; model->id && model->id != port->mode; model++) + /* empty */; + + port->abs = model->axes; + port->btn = model->buttons; + + if (!model->id) { + port->absc = data[TMDC_BYTE_DEF] >> 4; + for (i = 0; i < 4; i++) + port->btnc[i] = i < (data[TMDC_BYTE_DEF] & 0xf) ? 8 : 0; + } else { + port->absc = model->abs; + for (i = 0; i < 4; i++) + port->btnc[i] = model->btnc[i]; + } + + for (i = 0; i < 4; i++) + port->btno[i] = model->btno[i]; + + snprintf(port->name, sizeof(port->name), model->name, + port->absc, (data[TMDC_BYTE_DEF] & 0xf) << 3, port->mode); + snprintf(port->phys, sizeof(port->phys), "%s/input%d", tmdc->gameport->phys, i); + + port->dev = input_dev; + + input_dev->name = port->name; + input_dev->phys = port->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; + input_dev->id.product = model->id; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &tmdc->gameport->dev; + input_dev->private = tmdc; + + input_dev->open = tmdc_open; + input_dev->close = tmdc_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; i < port->absc && i < TMDC_ABS; i++) + if (port->abs[i] >= 0) + input_set_abs_params(input_dev, port->abs[i], 8, 248, 2, 4); + + for (i = 0; i < model->hats && i < TMDC_ABS_HAT; i++) + input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0); + + for (i = 0; i < 4; i++) { + for (j = 0; j < port->btnc[i] && j < TMDC_BTN; j++) + set_bit(port->btn[j + b], input_dev->keybit); + b += port->btnc[i]; + } + + input_register_device(port->dev); + + return 0; +} + /* * tmdc_probe() probes for ThrustMaster type joysticks. */ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) { - static struct models { - unsigned char id; - char *name; - char abs; - char hats; - char btnc[4]; - char btno[4]; - signed char *axes; - short *buttons; - } models[] = { { 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy }, - { 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad }, - { 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at }, - { 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm }, - { 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad }, - { 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }}; - unsigned char data[2][TMDC_MAX_LENGTH]; struct tmdc *tmdc; - int i, j, k, l, m; + int i; int err; if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL))) @@ -281,68 +381,25 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, tmdc_poll); gameport_set_poll_interval(gameport, 20); - for (j = 0; j < 2; j++) - if (tmdc->exists & (1 << j)) { + for (i = 0; i < 2; i++) { + if (tmdc->exists & (1 << i)) { - tmdc->mode[j] = data[j][TMDC_BYTE_ID]; - - for (m = 0; models[m].id && models[m].id != tmdc->mode[j]; m++); - - tmdc->abs[j] = models[m].axes; - tmdc->btn[j] = models[m].buttons; - - if (!models[m].id) { - models[m].abs = data[j][TMDC_BYTE_DEF] >> 4; - for (k = 0; k < 4; k++) - models[m].btnc[k] = k < (data[j][TMDC_BYTE_DEF] & 0xf) ? 8 : 0; - } - - tmdc->absc[j] = models[m].abs; - for (k = 0; k < 4; k++) { - tmdc->btnc[j][k] = models[m].btnc[k]; - tmdc->btno[j][k] = models[m].btno[k]; - } - - sprintf(tmdc->name[j], models[m].name, models[m].abs, - (data[j][TMDC_BYTE_DEF] & 0xf) << 3, tmdc->mode[j]); - - sprintf(tmdc->phys[j], "%s/input%d", gameport->phys, j); - - tmdc->dev[j].private = tmdc; - tmdc->dev[j].open = tmdc_open; - tmdc->dev[j].close = tmdc_close; - - tmdc->dev[j].name = tmdc->name[j]; - tmdc->dev[j].phys = tmdc->phys[j]; - tmdc->dev[j].id.bustype = BUS_GAMEPORT; - tmdc->dev[j].id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; - tmdc->dev[j].id.product = models[m].id; - tmdc->dev[j].id.version = 0x0100; - - tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - for (i = 0; i < models[m].abs && i < TMDC_ABS; i++) - if (tmdc->abs[j][i] >= 0) - input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4); - - for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++) - input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0); - - - for (k = l = 0; k < 4; k++) { - for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++) - set_bit(tmdc->btn[j][i + l], tmdc->dev[j].keybit); - l += models[m].btnc[k]; - } - - input_register_device(tmdc->dev + j); - printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys); + err = tmdc_setup_port(tmdc, i, data[i]); + if (err) + goto fail3; } + } return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail3: while (--i >= 0) { + if (tmdc->port[i]) { + input_unregister_device(tmdc->port[i]->dev); + kfree(tmdc->port[i]); + } + } + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); kfree(tmdc); return err; } @@ -352,9 +409,12 @@ static void tmdc_disconnect(struct gameport *gameport) struct tmdc *tmdc = gameport_get_drvdata(gameport); int i; - for (i = 0; i < 2; i++) - if (tmdc->exists & (1 << i)) - input_unregister_device(tmdc->dev + i); + for (i = 0; i < 2; i++) { + if (tmdc->port[i]) { + input_unregister_device(tmdc->port[i]->dev); + kfree(tmdc->port[i]); + } + } gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(tmdc); diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 0c5b9c8297cd..7e9764937d06 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -42,19 +42,21 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); MODULE_LICENSE("GPL"); -static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 }; -static int tgfx_nargs __initdata = 0; -module_param_array_named(map, tgfx, int, &tgfx_nargs, 0); +#define TGFX_MAX_PORTS 3 +#define TGFX_MAX_DEVICES 7 + +struct tgfx_config { + int args[TGFX_MAX_DEVICES + 1]; + int nargs; +}; + +static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata; + +module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0); MODULE_PARM_DESC(map, "Describes first set of devices (,,,.."); - -static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 }; -static int tgfx_nargs_2 __initdata = 0; -module_param_array_named(map2, tgfx_2, int, &tgfx_nargs_2, 0); +module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0); MODULE_PARM_DESC(map2, "Describes second set of devices"); - -static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 }; -static int tgfx_nargs_3 __initdata = 0; -module_param_array_named(map3, tgfx_3, int, &tgfx_nargs_3, 0); +module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0); MODULE_PARM_DESC(map3, "Describes third set of devices"); __obsolete_setup("tgfx="); @@ -75,17 +77,17 @@ __obsolete_setup("tgfx_3="); #define TGFX_TOP2 0x08 static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 }; -static char *tgfx_name = "TurboGraFX Multisystem joystick"; static struct tgfx { struct pardevice *pd; struct timer_list timer; - struct input_dev dev[7]; - char phys[7][32]; + struct input_dev *dev[TGFX_MAX_DEVICES]; + char name[TGFX_MAX_DEVICES][64]; + char phys[TGFX_MAX_DEVICES][32]; int sticks; int used; struct semaphore sem; -} *tgfx_base[3]; +} *tgfx_base[TGFX_MAX_PORTS]; /* * tgfx_timer() reads and analyzes TurboGraFX joystick data. @@ -100,7 +102,7 @@ static void tgfx_timer(unsigned long private) for (i = 0; i < 7; i++) if (tgfx->sticks & (1 << i)) { - dev = tgfx->dev + i; + dev = tgfx->dev[i]; parport_write_data(tgfx->pd->port, ~(1 << i)); data1 = parport_read_status(tgfx->pd->port) ^ 0x7f; @@ -153,118 +155,165 @@ static void tgfx_close(struct input_dev *dev) up(&tgfx->sem); } + + /* * tgfx_probe() probes for tg gamepads. */ -static struct tgfx __init *tgfx_probe(int *config, int nargs) +static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) { struct tgfx *tgfx; + struct input_dev *input_dev; struct parport *pp; + struct pardevice *pd; int i, j; + int err; - if (config[0] < 0) - return NULL; - - if (nargs < 2) { - printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n"); - return NULL; - } - - pp = parport_find_number(config[0]); - + pp = parport_find_number(parport); if (!pp) { printk(KERN_ERR "turbografx.c: no such parport\n"); - return NULL; + err = -EINVAL; + goto err_out; } - if (!(tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL))) { - parport_put_port(pp); - return NULL; + pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!pd) { + printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n"); + err = -EBUSY; + goto err_put_pp; + } + + tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL); + if (!tgfx) { + printk(KERN_ERR "turbografx.c: Not enough memory\n"); + err = -ENOMEM; + goto err_unreg_pardev; } init_MUTEX(&tgfx->sem); - - tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); - - parport_put_port(pp); - - if (!tgfx->pd) { - printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n"); - kfree(tgfx); - return NULL; - } - + tgfx->pd = pd; init_timer(&tgfx->timer); tgfx->timer.data = (long) tgfx; tgfx->timer.function = tgfx_timer; - tgfx->sticks = 0; + for (i = 0; i < n_devs; i++) { + if (n_buttons[i] < 1) + continue; - for (i = 0; i < nargs - 1; i++) - if (config[i+1] > 0 && config[i+1] < 6) { - - tgfx->sticks |= (1 << i); - - tgfx->dev[i].private = tgfx; - tgfx->dev[i].open = tgfx_open; - tgfx->dev[i].close = tgfx_close; - - sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name); - - tgfx->dev[i].name = tgfx_name; - tgfx->dev[i].phys = tgfx->phys[i]; - tgfx->dev[i].id.bustype = BUS_PARPORT; - tgfx->dev[i].id.vendor = 0x0003; - tgfx->dev[i].id.product = config[i+1]; - tgfx->dev[i].id.version = 0x0100; - - tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - - for (j = 0; j < config[i+1]; j++) - set_bit(tgfx_buttons[j], tgfx->dev[i].keybit); - - tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1; - tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1; - - input_register_device(tgfx->dev + i); - printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n", - config[i+1], tgfx->pd->port->name); + if (n_buttons[i] > 6) { + printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]); + err = -EINVAL; + goto err_free_devs; } + tgfx->dev[i] = input_dev = input_allocate_device(); + if (!input_dev) { + printk(KERN_ERR "turbografx.c: Not enough memory for input device\n"); + err = -ENOMEM; + goto err_free_devs; + } + + tgfx->sticks |= (1 << i); + snprintf(tgfx->name[i], sizeof(tgfx->name[i]), + "TurboGraFX %d-button Multisystem joystick", n_buttons[i]); + snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]), + "%s/input%d", tgfx->pd->port->name, i); + + input_dev->name = tgfx->name[i]; + input_dev->phys = tgfx->phys[i]; + input_dev->id.bustype = BUS_PARPORT; + input_dev->id.vendor = 0x0003; + input_dev->id.product = n_buttons[i]; + input_dev->id.version = 0x0100; + + input_dev->private = tgfx; + input_dev->open = tgfx_open; + input_dev->close = tgfx_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0); + input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0); + + for (j = 0; j < n_buttons[i]; j++) + set_bit(tgfx_buttons[j], input_dev->keybit); + + input_register_device(tgfx->dev[i]); + } + if (!tgfx->sticks) { - parport_unregister_device(tgfx->pd); - kfree(tgfx); - return NULL; + printk(KERN_ERR "turbografx.c: No valid devices specified\n"); + err = -EINVAL; + goto err_free_tgfx; } return tgfx; + + err_free_devs: + while (--i >= 0) + input_unregister_device(tgfx->dev[i]); + err_free_tgfx: + kfree(tgfx); + err_unreg_pardev: + parport_unregister_device(pd); + err_put_pp: + parport_put_port(pp); + err_out: + return ERR_PTR(err); +} + +static void __exit tgfx_remove(struct tgfx *tgfx) +{ + int i; + + for (i = 0; i < TGFX_MAX_DEVICES; i++) + if (tgfx->dev[i]) + input_unregister_device(tgfx->dev[i]); + parport_unregister_device(tgfx->pd); + kfree(tgfx); } static int __init tgfx_init(void) { - tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs); - tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2); - tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3); + int i; + int have_dev = 0; + int err = 0; - if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2]) - return 0; + for (i = 0; i < TGFX_MAX_PORTS; i++) { + if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0) + continue; - return -ENODEV; + if (tgfx[i].nargs < 2) { + printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n"); + err = -EINVAL; + break; + } + + tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1); + if (IS_ERR(tgfx_base[i])) { + err = PTR_ERR(tgfx_base[i]); + break; + } + + have_dev = 1; + } + + if (err) { + while (--i >= 0) + tgfx_remove(tgfx_base[i]); + return err; + } + + return have_dev ? 0 : -ENODEV; } static void __exit tgfx_exit(void) { - int i, j; + int i; - for (i = 0; i < 3; i++) - if (tgfx_base[i]) { - for (j = 0; j < 7; j++) - if (tgfx_base[i]->sticks & (1 << j)) - input_unregister_device(tgfx_base[i]->dev + j); - parport_unregister_device(tgfx_base[i]->pd); - } + for (i = 0; i < TGFX_MAX_PORTS; i++) + if (tgfx_base[i]) + tgfx_remove(tgfx_base[i]); } module_init(tgfx_init); diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 0379bc166525..cd3a1e742a30 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -69,8 +69,6 @@ MODULE_LICENSE("GPL"); #define TWIDJOY_MAX_LENGTH 5 -static char *twidjoy_name = "Handykey Twiddler"; - static struct twidjoy_button_spec { int bitshift; int bitmask; @@ -95,7 +93,7 @@ twidjoy_buttons[] = { */ struct twidjoy { - struct input_dev dev; + struct input_dev *dev; int idx; unsigned char data[TWIDJOY_MAX_LENGTH]; char phys[32]; @@ -108,37 +106,33 @@ struct twidjoy { static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs) { - if (twidjoy->idx == TWIDJOY_MAX_LENGTH) { - struct input_dev *dev = &twidjoy->dev; - unsigned char *data = twidjoy->data; - struct twidjoy_button_spec *bp; - int button_bits, abs_x, abs_y; + struct input_dev *dev = twidjoy->dev; + unsigned char *data = twidjoy->data; + struct twidjoy_button_spec *bp; + int button_bits, abs_x, abs_y; - button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f); + button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f); - input_regs(dev, regs); + input_regs(dev, regs); - for (bp = twidjoy_buttons; bp->bitmask; bp++) { - int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift; - int i; + for (bp = twidjoy_buttons; bp->bitmask; bp++) { + int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift; + int i; - for (i = 0; i < bp->bitmask; i++) - input_report_key(dev, bp->buttons[i], i+1 == value); - } - - abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2); - if (data[4] & 0x08) abs_x -= 256; - - abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0); - if (data[3] & 0x02) abs_y -= 256; - - input_report_abs(dev, ABS_X, -abs_x); - input_report_abs(dev, ABS_Y, +abs_y); - - input_sync(dev); + for (i = 0; i < bp->bitmask; i++) + input_report_key(dev, bp->buttons[i], i+1 == value); } - return; + abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2); + if (data[4] & 0x08) abs_x -= 256; + + abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0); + if (data[3] & 0x02) abs_y -= 256; + + input_report_abs(dev, ABS_X, -abs_x); + input_report_abs(dev, ABS_Y, +abs_y); + + input_sync(dev); } /* @@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct serio *serio) { struct twidjoy *twidjoy = serio_get_drvdata(serio); - input_unregister_device(&twidjoy->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(twidjoy->dev); kfree(twidjoy); } @@ -195,59 +189,49 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) { struct twidjoy_button_spec *bp; struct twidjoy *twidjoy; + struct input_dev *input_dev; + int err = -ENOMEM; int i; - int err; - if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL))) - return -ENOMEM; - - memset(twidjoy, 0, sizeof(struct twidjoy)); + twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!twidjoy || !input_dev) + goto fail; + twidjoy->dev = input_dev; sprintf(twidjoy->phys, "%s/input0", serio->phys); - init_input_dev(&twidjoy->dev); - twidjoy->dev.name = twidjoy_name; - twidjoy->dev.phys = twidjoy->phys; - twidjoy->dev.id.bustype = BUS_RS232; - twidjoy->dev.id.vendor = SERIO_TWIDJOY; - twidjoy->dev.id.product = 0x0001; - twidjoy->dev.id.version = 0x0100; - twidjoy->dev.dev = &serio->dev; + input_dev->name = "Handykey Twiddler"; + input_dev->phys = twidjoy->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_TWIDJOY; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = twidjoy; - twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); + input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); - for (bp = twidjoy_buttons; bp->bitmask; bp++) { + for (bp = twidjoy_buttons; bp->bitmask; bp++) for (i = 0; i < bp->bitmask; i++) - set_bit(bp->buttons[i], twidjoy->dev.keybit); - } - - twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - - for (i = 0; i < 2; i++) { - twidjoy->dev.absmax[ABS_X+i] = 50; - twidjoy->dev.absmin[ABS_X+i] = -50; - - /* TODO: arndt 20010708: Are these values appropriate? */ - twidjoy->dev.absfuzz[ABS_X+i] = 4; - twidjoy->dev.absflat[ABS_X+i] = 4; - } - - twidjoy->dev.private = twidjoy; + set_bit(bp->buttons[i], input_dev->keybit); serio_set_drvdata(serio, twidjoy); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(twidjoy); - return err; - } - - input_register_device(&twidjoy->dev); - - printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys); + if (err) + goto fail; + input_register_device(twidjoy->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(twidjoy); + return err; } /* diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 6976a219504c..99a642d2a1fe 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -47,14 +47,13 @@ MODULE_LICENSE("GPL"); #define WARRIOR_MAX_LENGTH 16 static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 }; -static char *warrior_name = "Logitech WingMan Warrior"; /* * Per-Warrior data. */ struct warrior { - struct input_dev dev; + struct input_dev *dev; int idx, len; unsigned char data[WARRIOR_MAX_LENGTH]; char phys[32]; @@ -67,7 +66,7 @@ struct warrior { static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs) { - struct input_dev *dev = &warrior->dev; + struct input_dev *dev = warrior->dev; unsigned char *data = warrior->data; if (!warrior->idx) return; @@ -131,9 +130,9 @@ static void warrior_disconnect(struct serio *serio) { struct warrior *warrior = serio_get_drvdata(serio); - input_unregister_device(&warrior->dev); serio_close(serio); serio_set_drvdata(serio, NULL); + input_unregister_device(warrior->dev); kfree(warrior); } @@ -146,60 +145,48 @@ static void warrior_disconnect(struct serio *serio) static int warrior_connect(struct serio *serio, struct serio_driver *drv) { struct warrior *warrior; - int i; - int err; + struct input_dev *input_dev; + int err = -ENOMEM; - if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL))) - return -ENOMEM; - - memset(warrior, 0, sizeof(struct warrior)); - - warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); - warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); - warrior->dev.relbit[0] = BIT(REL_DIAL); - warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y); + warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!warrior || !input_dev) + goto fail; + warrior->dev = input_dev; sprintf(warrior->phys, "%s/input0", serio->phys); - init_input_dev(&warrior->dev); - warrior->dev.name = warrior_name; - warrior->dev.phys = warrior->phys; - warrior->dev.id.bustype = BUS_RS232; - warrior->dev.id.vendor = SERIO_WARRIOR; - warrior->dev.id.product = 0x0001; - warrior->dev.id.version = 0x0100; - warrior->dev.dev = &serio->dev; + input_dev->name = "Logitech WingMan Warrior"; + input_dev->phys = warrior->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_WARRIOR; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = warrior; - for (i = 0; i < 2; i++) { - warrior->dev.absmax[ABS_X+i] = -64; - warrior->dev.absmin[ABS_X+i] = 64; - warrior->dev.absflat[ABS_X+i] = 8; - } - - warrior->dev.absmax[ABS_THROTTLE] = -112; - warrior->dev.absmin[ABS_THROTTLE] = 112; - - for (i = 0; i < 2; i++) { - warrior->dev.absmax[ABS_HAT0X+i] = -1; - warrior->dev.absmin[ABS_HAT0X+i] = 1; - } - - warrior->dev.private = warrior; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); + input_dev->relbit[0] = BIT(REL_DIAL); + input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8); + input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8); + input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0); + input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); + input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); serio_set_drvdata(serio, warrior); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(warrior); - return err; - } - - input_register_device(&warrior->dev); - - printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys); + if (err) + goto fail; + input_register_device(warrior->dev); return 0; + + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(warrior); + return err; } /* From 34abf91f4036c01669e298e649b7ba85cadf82eb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:40 -0500 Subject: [PATCH 0624/1940] [PATCH] Input: convert net/bluetooth to dynamic input_dev allocation Input: convert net/bluetooth to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hidp/core.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index de8af5f42394..860444a7fc0f 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -520,7 +520,7 @@ static int hidp_session(void *arg) if (session->input) { input_unregister_device(session->input); - kfree(session->input); + session->input = NULL; } up_write(&hidp_session_sem); @@ -536,6 +536,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co input->private = session; + input->name = "Bluetooth HID Boot Protocol Device"; + input->id.bustype = BUS_BLUETOOTH; input->id.vendor = req->vendor; input->id.product = req->product; @@ -582,16 +584,15 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, return -ENOTUNIQ; session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL); - if (!session) + if (!session) return -ENOMEM; memset(session, 0, sizeof(struct hidp_session)); - session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL); + session->input = input_allocate_device(); if (!session->input) { kfree(session); return -ENOMEM; } - memset(session->input, 0, sizeof(struct input_dev)); down_write(&hidp_session_sem); @@ -651,8 +652,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, __hidp_unlink_session(session); - if (session->input) + if (session->input) { input_unregister_device(session->input); + session->input = NULL; /* don't try to free it here */ + } failed: up_write(&hidp_session_sem); From 5ebdcbc2fc4f192c5e685565c9c853a9e01a5eeb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:49 -0500 Subject: [PATCH 0625/1940] [PATCH] Input: convert sound/ppc/beep to dynamic input_dev allocation Input: convert sound/ppc/beep to dynamic input_dev allocation This is required for input_dev sysfs integration Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- sound/ppc/beep.c | 66 +++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index 31ea7a4c069f..1681ee13efbb 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c @@ -31,14 +31,14 @@ #include "pmac.h" struct snd_pmac_beep { - int running; /* boolean */ - int volume; /* mixer volume: 0-100 */ + int running; /* boolean */ + int volume; /* mixer volume: 0-100 */ int volume_play; /* currently playing volume */ int hz; int nsamples; short *buf; /* allocated wave buffer */ dma_addr_t addr; /* physical address of buffer */ - struct input_dev dev; + struct input_dev *dev; }; /* @@ -212,47 +212,55 @@ static snd_kcontrol_new_t snd_pmac_beep_mixer = { int __init snd_pmac_attach_beep(pmac_t *chip) { pmac_beep_t *beep; - int err; + struct input_dev *input_dev; + void *dmabuf; + int err = -ENOMEM; - beep = kmalloc(sizeof(*beep), GFP_KERNEL); - if (! beep) - return -ENOMEM; - - memset(beep, 0, sizeof(*beep)); - beep->buf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, - &beep->addr, GFP_KERNEL); - - beep->dev.evbit[0] = BIT(EV_SND); - beep->dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - beep->dev.event = snd_pmac_beep_event; - beep->dev.private = chip; + beep = kzalloc(sizeof(*beep), GFP_KERNEL); + dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, + &beep->addr, GFP_KERNEL); + input_dev = input_allocate_device(); + if (!beep || !dmabuf || !input_dev) + goto fail; /* FIXME: set more better values */ - beep->dev.name = "PowerMac Beep"; - beep->dev.phys = "powermac/beep"; - beep->dev.id.bustype = BUS_ADB; - beep->dev.id.vendor = 0x001f; - beep->dev.id.product = 0x0001; - beep->dev.id.version = 0x0100; + input_dev->name = "PowerMac Beep"; + input_dev->phys = "powermac/beep"; + input_dev->id.bustype = BUS_ADB; + input_dev->id.vendor = 0x001f; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + input_dev->event = snd_pmac_beep_event; + input_dev->private = chip; + input_dev->cdev.dev = &chip->pdev->dev; + + beep->dev = input_dev; + beep->buf = dmabuf; beep->volume = BEEP_VOLUME; beep->running = 0; - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip))) < 0) { - kfree(beep->buf); - kfree(beep); - return err; - } + + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip)); + if (err < 0) + goto fail; chip->beep = beep; - input_register_device(&beep->dev); + input_register_device(beep->dev); return 0; + + fail: input_free_device(input_dev); + kfree(dmabuf); + kfree(beep); + return err; } void snd_pmac_detach_beep(pmac_t *chip) { if (chip->beep) { - input_unregister_device(&chip->beep->dev); + input_unregister_device(chip->beep->dev); dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, chip->beep->buf, chip->beep->addr); kfree(chip->beep); From 051b2feaa4a92592d160dcb8715cc4a5faaaa52f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:54 -0500 Subject: [PATCH 0626/1940] [PATCH] Input: show sysfs path in /proc/bus/input/devices Input: show sysfs path in /proc/bus/input/devices Show that sysfs and phys path are different objects. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/input/input.c b/drivers/input/input.c index 0e2e890c0988..ceaed631d49f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -475,17 +475,21 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int { struct input_dev *dev; struct input_handle *handle; + const char *path; off_t at = 0; int i, len, cnt = 0; list_for_each_entry(dev, &input_dev_list, node) { + path = dev->dynalloc ? kobject_get_path(&dev->cdev.kobj, GFP_KERNEL) : NULL; + len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); + len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : ""); len += sprintf(buf + len, "H: Handlers="); list_for_each_entry(handle, &dev->h_list, d_node) @@ -516,6 +520,8 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int if (cnt >= count) break; } + + kfree(path); } if (&dev->node == &input_dev_list) From 5c1e9a6a6ab2f4c60462cecb7773860a62d86e39 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:55 -0500 Subject: [PATCH 0627/1940] [PATCH] Input: export input_dev data via sysfs attributes Input: export various input device attributes via sysfs The following structure is exported: input0/ |-- name |-- phys |-- uniq |-- id/{bustype|vendor|product|version} `-- capabilities/{ev|abs|rel|key|led|msc|ff|sw} Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 156 +++++++++++++++++++++++++++++++++++------- 1 file changed, 133 insertions(+), 23 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index ceaed631d49f..57fbfd907157 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -434,6 +434,23 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) #endif +static int input_print_bitmap(char *buf, unsigned long *bitmap, int max) +{ + int i; + int len = 0; + + for (i = NBITS(max) - 1; i > 0; i--) + if (bitmap[i]) + break; + + for (; i >= 0; i--) + len += sprintf(buf + len, "%lx%s", bitmap[i], i > 0 ? " " : ""); + + len += sprintf(buf + len, "\n"); + + return len; +} + #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_bus_input_dir; @@ -455,20 +472,17 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) return 0; } -#define SPRINTF_BIT_B(bit, name, max) \ - do { \ - len += sprintf(buf + len, "B: %s", name); \ - for (i = NBITS(max) - 1; i >= 0; i--) \ - if (dev->bit[i]) break; \ - for (; i >= 0; i--) \ - len += sprintf(buf + len, "%lx ", dev->bit[i]); \ - len += sprintf(buf + len, "\n"); \ +#define SPRINTF_BIT_B(ev, bm) \ + do { \ + len += sprintf(buf + len, "B: %s=", #ev); \ + len += input_print_bitmap(buf + len, \ + dev->bm##bit, ev##_MAX); \ } while (0) -#define SPRINTF_BIT_B2(bit, name, max, ev) \ - do { \ - if (test_bit(ev, dev->evbit)) \ - SPRINTF_BIT_B(bit, name, max); \ +#define SPRINTF_BIT_B2(ev, bm) \ + do { \ + if (test_bit(EV_##ev, dev->evbit)) \ + SPRINTF_BIT_B(ev, bm); \ } while (0) static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) @@ -478,7 +492,7 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int const char *path; off_t at = 0; - int i, len, cnt = 0; + int len, cnt = 0; list_for_each_entry(dev, &input_dev_list, node) { @@ -497,15 +511,15 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int len += sprintf(buf + len, "\n"); - SPRINTF_BIT_B(evbit, "EV=", EV_MAX); - SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); - SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); - SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); - SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); - SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); - SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); - SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); - SPRINTF_BIT_B2(swbit, "SW=", SW_MAX, EV_SW); + SPRINTF_BIT_B(EV, ev); + SPRINTF_BIT_B2(KEY, key); + SPRINTF_BIT_B2(REL, rel); + SPRINTF_BIT_B2(ABS, abs); + SPRINTF_BIT_B2(MSC, msc); + SPRINTF_BIT_B2(LED, led); + SPRINTF_BIT_B2(SND, snd); + SPRINTF_BIT_B2(FF, ff); + SPRINTF_BIT_B2(SW, sw); len += sprintf(buf + len, "\n"); @@ -612,6 +626,96 @@ static inline int input_proc_init(void) { return 0; } static inline void input_proc_exit(void) { } #endif +#define INPUT_DEV_STRING_ATTR_SHOW(name) \ +static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + int retval; \ + \ + retval = down_interruptible(&input_dev->sem); \ + if (retval) \ + return retval; \ + \ + retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \ + \ + up(&input_dev->sem); \ + \ + return retval; \ +} + +INPUT_DEV_STRING_ATTR_SHOW(name); +INPUT_DEV_STRING_ATTR_SHOW(phys); +INPUT_DEV_STRING_ATTR_SHOW(uniq); + +static struct class_device_attribute input_dev_attrs[] = { + __ATTR(name, S_IRUGO, input_dev_show_name, NULL), + __ATTR(phys, S_IRUGO, input_dev_show_phys, NULL), + __ATTR(uniq, S_IRUGO, input_dev_show_uniq, NULL), + __ATTR_NULL +}; + +#define INPUT_DEV_ID_ATTR(name) \ +static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + return sprintf(buf, "%04x\n", input_dev->id.name); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); + +INPUT_DEV_ID_ATTR(bustype); +INPUT_DEV_ID_ATTR(vendor); +INPUT_DEV_ID_ATTR(product); +INPUT_DEV_ID_ATTR(version); + +static struct attribute *input_dev_id_attrs[] = { + &class_device_attr_bustype.attr, + &class_device_attr_vendor.attr, + &class_device_attr_product.attr, + &class_device_attr_version.attr, + NULL +}; + +static struct attribute_group input_dev_id_attr_group = { + .name = "id", + .attrs = input_dev_id_attrs, +}; + +#define INPUT_DEV_CAP_ATTR(ev, bm) \ +static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + return input_print_bitmap(buf, input_dev->bm##bit, ev##_MAX); \ +} \ +static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); + +INPUT_DEV_CAP_ATTR(EV, ev); +INPUT_DEV_CAP_ATTR(KEY, key); +INPUT_DEV_CAP_ATTR(REL, rel); +INPUT_DEV_CAP_ATTR(ABS, abs); +INPUT_DEV_CAP_ATTR(MSC, msc); +INPUT_DEV_CAP_ATTR(LED, led); +INPUT_DEV_CAP_ATTR(SND, snd); +INPUT_DEV_CAP_ATTR(FF, ff); +INPUT_DEV_CAP_ATTR(SW, sw); + +static struct attribute *input_dev_caps_attrs[] = { + &class_device_attr_ev.attr, + &class_device_attr_key.attr, + &class_device_attr_rel.attr, + &class_device_attr_abs.attr, + &class_device_attr_msc.attr, + &class_device_attr_led.attr, + &class_device_attr_snd.attr, + &class_device_attr_ff.attr, + &class_device_attr_sw.attr, + NULL +}; + +static struct attribute_group input_dev_caps_attr_group = { + .name = "capabilities", + .attrs = input_dev_caps_attrs, +}; + static void input_dev_release(struct class_device *class_dev) { struct input_dev *dev = to_input_dev(class_dev); @@ -623,6 +727,7 @@ static void input_dev_release(struct class_device *class_dev) static struct class input_dev_class = { .name = "input_dev", .release = input_dev_release, + .class_dev_attrs = input_dev_attrs, }; struct input_dev *input_allocate_device(void) @@ -660,6 +765,8 @@ static void input_register_classdevice(struct input_dev *dev) kfree(path); class_device_add(&dev->cdev); + sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); + sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); } void input_register_device(struct input_dev *dev) @@ -726,8 +833,11 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); - if (dev->dynalloc) + if (dev->dynalloc) { + sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); class_device_unregister(&dev->cdev); + } input_wakeup_procfs_readers(); } From 102040204f1949562406b72007c14a2a241cb0d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0628/1940] [PATCH] INPUT: register the input class device sooner This is needed so we can actually use the class device within the input handlers. Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 57fbfd907157..03c2ca404f20 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -795,6 +795,9 @@ void input_register_device(struct input_dev *dev) INIT_LIST_HEAD(&dev->h_list); list_add_tail(&dev->node, &input_dev_list); + if (dev->dynalloc) + input_register_classdevice(dev); + list_for_each_entry(handler, &input_handler_list, node) if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) if ((id = input_match_device(handler->id_table, dev))) @@ -802,9 +805,6 @@ void input_register_device(struct input_dev *dev) input_link_handle(handle); - if (dev->dynalloc) - input_register_classdevice(dev); - #ifdef CONFIG_HOTPLUG input_call_hotplug("add", dev); #endif From 23d50901617c2a8bdef509279a42d2e90f523db9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0629/1940] [PATCH] INPUT: export input_dev_class so that input drivers can use it. Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 3 ++- include/linux/input.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 03c2ca404f20..b0ede4cc72b7 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -40,6 +40,7 @@ EXPORT_SYMBOL(input_accept_process); EXPORT_SYMBOL(input_flush_device); EXPORT_SYMBOL(input_event); EXPORT_SYMBOL(input_class); +EXPORT_SYMBOL_GPL(input_dev_class); #define INPUT_DEVICES 256 @@ -724,7 +725,7 @@ static void input_dev_release(struct class_device *class_dev) module_put(THIS_MODULE); } -static struct class input_dev_class = { +struct class input_dev_class = { .name = "input_dev", .release = input_dev_release, .class_dev_attrs = input_dev_attrs, diff --git a/include/linux/input.h b/include/linux/input.h index 3defa29a17d3..5de844157fa9 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1075,6 +1075,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min } extern struct class *input_class; +extern struct class input_dev_class; #endif #endif From 967ca692161d8c4e894932599592af8d62c0a895 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0630/1940] [PATCH] INPUT: move the input class devices under their new input_dev devices Signed-off-by: Greg Kroah-Hartman --- drivers/input/evdev.c | 6 +++--- drivers/input/joydev.c | 6 +++--- drivers/input/mousedev.c | 10 +++++----- drivers/input/tsdev.c | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 14ea57f963bb..579041ded4be 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -686,9 +686,9 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev_table[minor] = evdev; - class_device_create(input_class, NULL, + class_device_create(&input_dev_class, &dev->cdev, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - dev->dev, "event%d", minor); + dev->cdev.dev, "event%d", minor); return &evdev->handle; } @@ -698,7 +698,7 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev *evdev = handle->private; struct evdev_list *list; - class_device_destroy(input_class, + class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 40d2b46cbc79..9c17d1add260 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -513,9 +513,9 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev_table[minor] = joydev; - class_device_create(input_class, NULL, + class_device_create(&input_dev_class, &dev->cdev, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - dev->dev, "js%d", minor); + dev->cdev.dev, "js%d", minor); return &joydev->handle; } @@ -525,7 +525,7 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev *joydev = handle->private; struct joydev_list *list; - class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); + class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; if (joydev->open) { diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 89c3e496f1ed..5ec6291e967f 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -648,9 +648,9 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru mousedev_table[minor] = mousedev; - class_device_create(input_class, NULL, + class_device_create(&input_dev_class, &dev->cdev, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - dev->dev, "mouse%d", minor); + dev->cdev.dev, "mouse%d", minor); return &mousedev->handle; } @@ -660,7 +660,7 @@ static void mousedev_disconnect(struct input_handle *handle) struct mousedev *mousedev = handle->private; struct mousedev_list *list; - class_device_destroy(input_class, + class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; @@ -734,7 +734,7 @@ static int __init mousedev_init(void) mousedev_mix.exist = 1; mousedev_mix.minor = MOUSEDEV_MIX; - class_device_create(input_class, NULL, + class_device_create(&input_dev_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -753,7 +753,7 @@ static void __exit mousedev_exit(void) if (psaux_registered) misc_deregister(&psaux_mouse); #endif - class_device_destroy(input_class, + class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); } diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 2d45e4df4163..0581edb9a560 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -409,9 +409,9 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, tsdev_table[minor] = tsdev; - class_device_create(input_class, NULL, + class_device_create(&input_dev_class, &dev->cdev, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - dev->dev, "ts%d", minor); + dev->cdev.dev, "ts%d", minor); return &tsdev->handle; } @@ -421,7 +421,7 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev *tsdev = handle->private; struct tsdev_list *list; - class_device_destroy(input_class, + class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; From 629b77a42c39c8b3c42a8cf5f5680f0406f8d43f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0631/1940] [PATCH] INPUT: Fix oops when accessing sysfs files of nested input devices Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index b0ede4cc72b7..0d570cf92dc2 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -642,17 +642,22 @@ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ up(&input_dev->sem); \ \ return retval; \ -} +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL); INPUT_DEV_STRING_ATTR_SHOW(name); INPUT_DEV_STRING_ATTR_SHOW(phys); INPUT_DEV_STRING_ATTR_SHOW(uniq); -static struct class_device_attribute input_dev_attrs[] = { - __ATTR(name, S_IRUGO, input_dev_show_name, NULL), - __ATTR(phys, S_IRUGO, input_dev_show_phys, NULL), - __ATTR(uniq, S_IRUGO, input_dev_show_uniq, NULL), - __ATTR_NULL +static struct attribute *input_dev_attrs[] = { + &class_device_attr_name.attr, + &class_device_attr_phys.attr, + &class_device_attr_uniq.attr, + NULL +}; + +static struct attribute_group input_dev_group = { + .attrs = input_dev_attrs, }; #define INPUT_DEV_ID_ATTR(name) \ @@ -728,7 +733,6 @@ static void input_dev_release(struct class_device *class_dev) struct class input_dev_class = { .name = "input_dev", .release = input_dev_release, - .class_dev_attrs = input_dev_attrs, }; struct input_dev *input_allocate_device(void) @@ -766,6 +770,7 @@ static void input_register_classdevice(struct input_dev *dev) kfree(path); class_device_add(&dev->cdev); + sysfs_create_group(&dev->cdev.kobj, &input_dev_group); sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); } From b0fdfebb205fcbf394c3db39679a766b8fc4f07d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0632/1940] [PATCH] INPUT: remove the input_class structure, as it is unused. Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 18 +++--------------- include/linux/input.h | 1 - 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 0d570cf92dc2..5c9044dbf00e 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -39,7 +39,6 @@ EXPORT_SYMBOL(input_close_device); EXPORT_SYMBOL(input_accept_process); EXPORT_SYMBOL(input_flush_device); EXPORT_SYMBOL(input_event); -EXPORT_SYMBOL(input_class); EXPORT_SYMBOL_GPL(input_dev_class); #define INPUT_DEVICES 256 @@ -927,8 +926,6 @@ static struct file_operations input_fops = { .open = input_open_file, }; -struct class *input_class; - static int __init input_init(void) { int err; @@ -939,27 +936,19 @@ static int __init input_init(void) return err; } - input_class = class_create(THIS_MODULE, "input"); - if (IS_ERR(input_class)) { - printk(KERN_ERR "input: unable to register input class\n"); - err = PTR_ERR(input_class); - goto fail1; - } - err = input_proc_init(); if (err) - goto fail2; + goto fail1; err = register_chrdev(INPUT_MAJOR, "input", &input_fops); if (err) { printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); - goto fail3; + goto fail2; } return 0; - fail3: input_proc_exit(); - fail2: class_destroy(input_class); + fail2: input_proc_exit(); fail1: class_unregister(&input_dev_class); return err; } @@ -968,7 +957,6 @@ static void __exit input_exit(void) { input_proc_exit(); unregister_chrdev(INPUT_MAJOR, "input"); - class_destroy(input_class); class_unregister(&input_dev_class); } diff --git a/include/linux/input.h b/include/linux/input.h index 5de844157fa9..256e88755f12 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1074,7 +1074,6 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absbit[LONG(axis)] |= BIT(axis); } -extern struct class *input_class; extern struct class input_dev_class; #endif From ea9f240bd819f9299703283e5326da606bbb4b05 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0633/1940] [PATCH] INPUT: rename input_dev_class to input_class to be correct. Signed-off-by: Greg Kroah-Hartman --- drivers/input/evdev.c | 4 ++-- drivers/input/input.c | 14 +++++++------- drivers/input/joydev.c | 4 ++-- drivers/input/mousedev.c | 8 ++++---- drivers/input/tsdev.c | 4 ++-- include/linux/input.h | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 579041ded4be..2a96b260a2a8 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -686,7 +686,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev_table[minor] = evdev; - class_device_create(&input_dev_class, &dev->cdev, + class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), dev->cdev.dev, "event%d", minor); @@ -698,7 +698,7 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev *evdev = handle->private; struct evdev_list *list; - class_device_destroy(&input_dev_class, + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; diff --git a/drivers/input/input.c b/drivers/input/input.c index 5c9044dbf00e..a8f65fa7e17a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -39,7 +39,7 @@ EXPORT_SYMBOL(input_close_device); EXPORT_SYMBOL(input_accept_process); EXPORT_SYMBOL(input_flush_device); EXPORT_SYMBOL(input_event); -EXPORT_SYMBOL_GPL(input_dev_class); +EXPORT_SYMBOL_GPL(input_class); #define INPUT_DEVICES 256 @@ -729,8 +729,8 @@ static void input_dev_release(struct class_device *class_dev) module_put(THIS_MODULE); } -struct class input_dev_class = { - .name = "input_dev", +struct class input_class = { + .name = "input", .release = input_dev_release, }; @@ -741,7 +741,7 @@ struct input_dev *input_allocate_device(void) dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { dev->dynalloc = 1; - dev->cdev.class = &input_dev_class; + dev->cdev.class = &input_class; class_device_initialize(&dev->cdev); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); @@ -930,7 +930,7 @@ static int __init input_init(void) { int err; - err = class_register(&input_dev_class); + err = class_register(&input_class); if (err) { printk(KERN_ERR "input: unable to register input_dev class\n"); return err; @@ -949,7 +949,7 @@ static int __init input_init(void) return 0; fail2: input_proc_exit(); - fail1: class_unregister(&input_dev_class); + fail1: class_unregister(&input_class); return err; } @@ -957,7 +957,7 @@ static void __exit input_exit(void) { input_proc_exit(); unregister_chrdev(INPUT_MAJOR, "input"); - class_unregister(&input_dev_class); + class_unregister(&input_class); } subsys_initcall(input_init); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9c17d1add260..25f7eba4761f 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -513,7 +513,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev_table[minor] = joydev; - class_device_create(&input_dev_class, &dev->cdev, + class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), dev->cdev.dev, "js%d", minor); @@ -525,7 +525,7 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev *joydev = handle->private; struct joydev_list *list; - class_device_destroy(&input_dev_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; if (joydev->open) { diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 5ec6291e967f..de2808fc85b3 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -648,7 +648,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru mousedev_table[minor] = mousedev; - class_device_create(&input_dev_class, &dev->cdev, + class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), dev->cdev.dev, "mouse%d", minor); @@ -660,7 +660,7 @@ static void mousedev_disconnect(struct input_handle *handle) struct mousedev *mousedev = handle->private; struct mousedev_list *list; - class_device_destroy(&input_dev_class, + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; @@ -734,7 +734,7 @@ static int __init mousedev_init(void) mousedev_mix.exist = 1; mousedev_mix.minor = MOUSEDEV_MIX; - class_device_create(&input_dev_class, NULL, + class_device_create(&input_class, NULL, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -753,7 +753,7 @@ static void __exit mousedev_exit(void) if (psaux_registered) misc_deregister(&psaux_mouse); #endif - class_device_destroy(&input_dev_class, + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); } diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 0581edb9a560..75e165736655 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -409,7 +409,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, tsdev_table[minor] = tsdev; - class_device_create(&input_dev_class, &dev->cdev, + class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), dev->cdev.dev, "ts%d", minor); @@ -421,7 +421,7 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev *tsdev = handle->private; struct tsdev_list *list; - class_device_destroy(&input_dev_class, + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; diff --git a/include/linux/input.h b/include/linux/input.h index 256e88755f12..e3d9c08b5cbe 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1074,7 +1074,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absbit[LONG(axis)] |= BIT(axis); } -extern struct class input_dev_class; +extern struct class input_class; #endif #endif From c9bcd582dfeec845b83bc948a430c9958bf839e6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0634/1940] [PATCH] INPUT: Create symlinks for backwards compatibility This creates symlinks in /sys/class/input/ to the nested class devices to help userspace cope with the nesting. Unfortunatly udev still needs to be updated as it can't handle symlinks properly here :( Signed-off-by: Greg Kroah-Hartman --- drivers/input/evdev.c | 10 ++++++++-- drivers/input/joydev.c | 10 ++++++++-- drivers/input/mousedev.c | 10 ++++++++-- drivers/input/tsdev.c | 10 ++++++++-- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 2a96b260a2a8..a4696cd0978c 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -661,6 +661,7 @@ static struct file_operations evdev_fops = { static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct evdev *evdev; + struct class_device *cdev; int minor; for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); @@ -686,9 +687,13 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev_table[minor] = evdev; - class_device_create(&input_class, &dev->cdev, + cdev = class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - dev->cdev.dev, "event%d", minor); + dev->cdev.dev, evdev->name); + + /* temporary symlink to keep userspace happy */ + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + evdev->name); return &evdev->handle; } @@ -698,6 +703,7 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev *evdev = handle->private; struct evdev_list *list; + sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 25f7eba4761f..20e2972b9204 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -448,6 +448,7 @@ static struct file_operations joydev_fops = { static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct joydev *joydev; + struct class_device *cdev; int i, j, t, minor; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); @@ -513,9 +514,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev_table[minor] = joydev; - class_device_create(&input_class, &dev->cdev, + cdev = class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - dev->cdev.dev, "js%d", minor); + dev->cdev.dev, joydev->name); + + /* temporary symlink to keep userspace happy */ + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + joydev->name); return &joydev->handle; } @@ -525,6 +530,7 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev *joydev = handle->private; struct joydev_list *list; + sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index de2808fc85b3..2d0af44ac4b9 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -620,6 +620,7 @@ static struct file_operations mousedev_fops = { static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct mousedev *mousedev; + struct class_device *cdev; int minor = 0; for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); @@ -648,9 +649,13 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru mousedev_table[minor] = mousedev; - class_device_create(&input_class, &dev->cdev, + cdev = class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - dev->cdev.dev, "mouse%d", minor); + dev->cdev.dev, mousedev->name); + + /* temporary symlink to keep userspace happy */ + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + mousedev->name); return &mousedev->handle; } @@ -660,6 +665,7 @@ static void mousedev_disconnect(struct input_handle *handle) struct mousedev *mousedev = handle->private; struct mousedev_list *list; + sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 75e165736655..ca1547929d62 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -368,6 +368,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, struct input_device_id *id) { struct tsdev *tsdev; + struct class_device *cdev; int minor, delta; for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor]; @@ -409,9 +410,13 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, tsdev_table[minor] = tsdev; - class_device_create(&input_class, &dev->cdev, + cdev = class_device_create(&input_class, &dev->cdev, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - dev->cdev.dev, "ts%d", minor); + dev->cdev.dev, tsdev->name); + + /* temporary symlink to keep userspace happy */ + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + tsdev->name); return &tsdev->handle; } @@ -421,6 +426,7 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev *tsdev = handle->private; struct tsdev_list *list; + sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; From a7fadbe10ccf430e7a8add8b45c561d864087343 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 15 Sep 2005 02:01:57 -0500 Subject: [PATCH 0635/1940] [PATCH] input core: remove custom-made hotplug handler Input: remove custom-made hotplug handler Now that all input devices are registered with sysfs we can remove old custom-made hotplug handler and crate a standard one. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/input.c | 249 ++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 145 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index a8f65fa7e17a..3b1685ff9d10 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -316,125 +316,7 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st return NULL; } - -/* - * Input hotplugging interface - loading event handlers based on - * device bitfields. - */ - -#ifdef CONFIG_HOTPLUG - -/* - * Input hotplugging invokes what /proc/sys/kernel/hotplug says - * (normally /sbin/hotplug) when input devices get added or removed. - * - * This invokes a user mode policy agent, typically helping to load driver - * or other modules, configure the device, and more. Drivers can provide - * a MODULE_DEVICE_TABLE to help with module loading subtasks. - * - */ - -#define SPRINTF_BIT_A(bit, name, max) \ - do { \ - envp[i++] = scratch; \ - scratch += sprintf(scratch, name); \ - for (j = NBITS(max) - 1; j >= 0; j--) \ - if (dev->bit[j]) break; \ - for (; j >= 0; j--) \ - scratch += sprintf(scratch, "%lx ", dev->bit[j]); \ - scratch++; \ - } while (0) - -#define SPRINTF_BIT_A2(bit, name, max, ev) \ - do { \ - if (test_bit(ev, dev->evbit)) \ - SPRINTF_BIT_A(bit, name, max); \ - } while (0) - -static void input_call_hotplug(char *verb, struct input_dev *dev) -{ - char *argv[3], **envp, *buf, *scratch; - int i = 0, j, value; - - if (!hotplug_path[0]) { - printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n"); - return; - } - if (in_interrupt()) { - printk(KERN_ERR "input.c: calling hotplug from interrupt\n"); - return; - } - if (!current->fs->root) { - printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n"); - return; - } - if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) { - printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); - return; - } - if (!(buf = kmalloc(1024, GFP_KERNEL))) { - kfree (envp); - printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); - return; - } - - argv[0] = hotplug_path; - argv[1] = "input"; - argv[2] = NULL; - - envp[i++] = "HOME=/"; - envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - - scratch = buf; - - envp[i++] = scratch; - scratch += sprintf(scratch, "ACTION=%s", verb) + 1; - - envp[i++] = scratch; - scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x", - dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; - - if (dev->name) { - envp[i++] = scratch; - scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; - } - - if (dev->phys) { - envp[i++] = scratch; - scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; - } - - SPRINTF_BIT_A(evbit, "EV=", EV_MAX); - SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY); - SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL); - SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS); - SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC); - SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED); - SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND); - SPRINTF_BIT_A2(ffbit, "FF=", FF_MAX, EV_FF); - SPRINTF_BIT_A2(swbit, "SW=", SW_MAX, EV_SW); - - envp[i++] = NULL; - -#ifdef INPUT_DEBUG - printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n", - argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]); -#endif - - value = call_usermodehelper(argv [0], argv, envp, 0); - - kfree(buf); - kfree(envp); - -#ifdef INPUT_DEBUG - if (value != 0) - printk(KERN_DEBUG "input.c: hotplug returned %d\n", value); -#endif -} - -#endif - -static int input_print_bitmap(char *buf, unsigned long *bitmap, int max) +static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max) { int i; int len = 0; @@ -444,10 +326,8 @@ static int input_print_bitmap(char *buf, unsigned long *bitmap, int max) break; for (; i >= 0; i--) - len += sprintf(buf + len, "%lx%s", bitmap[i], i > 0 ? " " : ""); - - len += sprintf(buf + len, "\n"); - + len += snprintf(buf + len, max(buf_size - len, 0), + "%lx%s", bitmap[i], i > 0 ? " " : ""); return len; } @@ -472,17 +352,18 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) return 0; } -#define SPRINTF_BIT_B(ev, bm) \ +#define SPRINTF_BIT(ev, bm) \ do { \ len += sprintf(buf + len, "B: %s=", #ev); \ - len += input_print_bitmap(buf + len, \ + len += input_print_bitmap(buf + len, INT_MAX, \ dev->bm##bit, ev##_MAX); \ + len += sprintf(buf + len, "\n"); \ } while (0) -#define SPRINTF_BIT_B2(ev, bm) \ +#define TEST_AND_SPRINTF_BIT(ev, bm) \ do { \ if (test_bit(EV_##ev, dev->evbit)) \ - SPRINTF_BIT_B(ev, bm); \ + SPRINTF_BIT(ev, bm); \ } while (0) static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) @@ -511,15 +392,15 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int len += sprintf(buf + len, "\n"); - SPRINTF_BIT_B(EV, ev); - SPRINTF_BIT_B2(KEY, key); - SPRINTF_BIT_B2(REL, rel); - SPRINTF_BIT_B2(ABS, abs); - SPRINTF_BIT_B2(MSC, msc); - SPRINTF_BIT_B2(LED, led); - SPRINTF_BIT_B2(SND, snd); - SPRINTF_BIT_B2(FF, ff); - SPRINTF_BIT_B2(SW, sw); + SPRINTF_BIT(EV, ev); + TEST_AND_SPRINTF_BIT(KEY, key); + TEST_AND_SPRINTF_BIT(REL, rel); + TEST_AND_SPRINTF_BIT(ABS, abs); + TEST_AND_SPRINTF_BIT(MSC, msc); + TEST_AND_SPRINTF_BIT(LED, led); + TEST_AND_SPRINTF_BIT(SND, snd); + TEST_AND_SPRINTF_BIT(FF, ff); + TEST_AND_SPRINTF_BIT(SW, sw); len += sprintf(buf + len, "\n"); @@ -689,7 +570,7 @@ static struct attribute_group input_dev_id_attr_group = { static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ { \ struct input_dev *input_dev = to_input_dev(dev); \ - return input_print_bitmap(buf, input_dev->bm##bit, ev##_MAX); \ + return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\ } \ static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); @@ -729,9 +610,95 @@ static void input_dev_release(struct class_device *class_dev) module_put(THIS_MODULE); } +/* + * Input hotplugging interface - loading event handlers based on + * device bitfields. + */ +static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index, + char *buffer, int buffer_size, int *cur_len, + const char *name, unsigned long *bitmap, int max) +{ + if (*cur_index >= num_envp - 1) + return -ENOMEM; + + envp[*cur_index] = buffer + *cur_len; + + *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); + if (*cur_len > buffer_size) + return -ENOMEM; + + *cur_len += input_print_bitmap(buffer + *cur_len, + max(buffer_size - *cur_len, 0), + bitmap, max) + 1; + if (*cur_len > buffer_size) + return -ENOMEM; + + (*cur_index)++; + return 0; +} + +#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_hotplug_env_var(envp, num_envp, &i, \ + buffer, buffer_size, &len, \ + fmt, val); \ + if (err) \ + return err; \ + } while (0) + +#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ + do { \ + int err = input_add_hotplug_bm_var(envp, num_envp, &i, \ + buffer, buffer_size, &len, \ + name, bm, max); \ + if (err) \ + return err; \ + } while (0) + +static int input_dev_hotplug(struct class_device *cdev, char **envp, + int num_envp, char *buffer, int buffer_size) +{ + struct input_dev *dev = to_input_dev(cdev); + int i = 0; + int len = 0; + + INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", + dev->id.bustype, dev->id.vendor, + dev->id.product, dev->id.version); + if (dev->name) + INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name); + if (dev->phys) + INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys); + if (dev->phys) + INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); + + INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); + if (test_bit(EV_KEY, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); + if (test_bit(EV_REL, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("REL=", dev->relbit, REL_MAX); + if (test_bit(EV_ABS, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("ABS=", dev->absbit, ABS_MAX); + if (test_bit(EV_MSC, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("MSC=", dev->mscbit, MSC_MAX); + if (test_bit(EV_LED, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("LED=", dev->ledbit, LED_MAX); + if (test_bit(EV_SND, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("SND=", dev->sndbit, SND_MAX); + if (test_bit(EV_FF, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX); + if (test_bit(EV_SW, dev->evbit)) + INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX); + + envp[i] = NULL; + + return 0; +} + struct class input_class = { .name = "input", .release = input_dev_release, + .hotplug = input_dev_hotplug, }; struct input_dev *input_allocate_device(void) @@ -810,10 +777,6 @@ void input_register_device(struct input_dev *dev) input_link_handle(handle); -#ifdef CONFIG_HOTPLUG - input_call_hotplug("add", dev); -#endif - input_wakeup_procfs_readers(); } @@ -832,10 +795,6 @@ void input_unregister_device(struct input_dev *dev) handle->handler->disconnect(handle); } -#ifdef CONFIG_HOTPLUG - input_call_hotplug("remove", dev); -#endif - list_del_init(&dev->node); if (dev->dynalloc) { From a1bdc7aad8b557176ccecff1da137ebe3090871e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 13 Oct 2005 17:54:41 +0100 Subject: [PATCH 0636/1940] [PATCH] drivers/base - fix sparse warnings There are a number of sparse warnings from the latest sparse snapshot being generated from the drivers/base build. The main culprits are due to the initialisation functions not being declared in a header file. Also, the firmware.c file should include to get the prototype of firmware_register() and firmware_unregister(). This patch moves the init function declerations from the init.c file to the base.h, and ensures it is included in all the relevant c sources. It also adds to the included headers for firmware.c. The patch does not solve all the sparse errors generated, but reduces the count significantly. drivers/base/core.c:161:1: warning: symbol 'devices_subsys' was not declared. Should it be static? drivers/base/core.c:417:12: warning: symbol 'devices_init' was not declared. Should it be static? drivers/base/sys.c:253:6: warning: symbol 'sysdev_shutdown' was not declared. Should it be static? drivers/base/sys.c:326:5: warning: symbol 'sysdev_suspend' was not declared. Should it be static? drivers/base/sys.c:428:5: warning: symbol 'sysdev_resume' was not declared. Should it be static? drivers/base/sys.c:450:12: warning: symbol 'system_bus_init' was not declared. Should it be static? drivers/base/bus.c:133:1: warning: symbol 'bus_subsys' was not declared. Should it be static? drivers/base/bus.c:667:12: warning: symbol 'buses_init' was not declared. Should it be static? drivers/base/class.c:759:12: warning: symbol 'classes_init' was not declared. Should it be static? drivers/base/platform.c:313:12: warning: symbol 'platform_bus_init' was not declared. Should it be static? drivers/base/cpu.c:110:12: warning: symbol 'cpu_dev_init' was not declared. Should it be static? drivers/base/firmware.c:17:5: warning: symbol 'firmware_register' was not declared. Should it be static? drivers/base/firmware.c:23:6: warning: symbol 'firmware_unregister' was not declared. Should it be static? drivers/base/firmware.c:28:12: warning: symbol 'firmware_init' was not declared. Should it be static? drivers/base/init.c:28:13: warning: symbol 'driver_init' was not declared. Should it be static? drivers/base/dmapool.c:174:10: warning: implicit cast from nocast type drivers/base/attribute_container.c:439:1: warning: symbol 'attribute_container_init' was not declared. Should it be static? drivers/base/power/runtime.c:76:6: warning: symbol 'dpm_set_power_state' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/base/attribute_container.c | 2 ++ drivers/base/base.h | 12 ++++++++++++ drivers/base/cpu.c | 1 + drivers/base/firmware.c | 3 +++ drivers/base/init.c | 10 ++-------- drivers/base/platform.c | 2 ++ 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 6b2eb6f39b4d..2a7d7ae83e1e 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -19,6 +19,8 @@ #include #include +#include "base.h" + /* This is a private structure used to tie the classdev and the * container .. it should never be visible outside this file */ struct internal_container { diff --git a/drivers/base/base.h b/drivers/base/base.h index 783752b68a9a..e3b548d46cff 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -1,3 +1,15 @@ + +/* initialisation functions */ + +extern int devices_init(void); +extern int buses_init(void); +extern int classes_init(void); +extern int firmware_init(void); +extern int platform_bus_init(void); +extern int system_bus_init(void); +extern int cpu_dev_init(void); +extern int attribute_container_init(void); + extern int bus_add_device(struct device * dev); extern void bus_remove_device(struct device * dev); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index b79badd0f158..081c927b1ed8 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -9,6 +9,7 @@ #include #include +#include "base.h" struct sysdev_class cpu_sysdev_class = { set_kset_name("cpu"), diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c index 88ab044932f2..cb1b98ae0d58 100644 --- a/drivers/base/firmware.c +++ b/drivers/base/firmware.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#include "base.h" static decl_subsys(firmware, NULL, NULL); diff --git a/drivers/base/init.c b/drivers/base/init.c index a76ae5a221f3..84e604e25c4f 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c @@ -10,14 +10,8 @@ #include #include -extern int devices_init(void); -extern int buses_init(void); -extern int classes_init(void); -extern int firmware_init(void); -extern int platform_bus_init(void); -extern int system_bus_init(void); -extern int cpu_dev_init(void); -extern int attribute_container_init(void); +#include "base.h" + /** * driver_init - initialize driver model. * diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 361e204209eb..a1a56ff65b76 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -17,6 +17,8 @@ #include #include +#include "base.h" + struct device platform_bus = { .bus_id = "platform", }; From ad7e14a55ed7648d02a4df8e460e291d80a18c98 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2005 22:25:43 -0700 Subject: [PATCH 0637/1940] [PATCH] update required version of udev The 071 release is needed to handle the input changes. Older versions will work properly with module-based systems, but not for users that build input stuff into the kernel. Signed-off-by: Greg Kroah-Hartman --- Documentation/Changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Changes b/Documentation/Changes index 27232be26e1a..783ddc3ce4e8 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -65,7 +65,7 @@ o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version o nfs-utils 1.0.5 # showmount --version o procps 3.2.0 # ps --version o oprofile 0.9 # oprofiled --version -o udev 058 # udevinfo -V +o udev 071 # udevinfo -V Kernel compilation ================== From a3a3395e487abc4c1371fe319a8ecbb3913a70a4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 13 Oct 2005 21:31:08 +0200 Subject: [PATCH 0638/1940] [PATCH] Driver Core: Big kfree NULL check cleanup - Documentation This is the Documentation/ part of the big kfree cleanup patch. Remove pointless checks for NULL prior to calling kfree() in example code in Documentation/. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/writing_usb_driver.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl index 51f3bfb6fb6e..008a341234d0 100644 --- a/Documentation/DocBook/writing_usb_driver.tmpl +++ b/Documentation/DocBook/writing_usb_driver.tmpl @@ -345,8 +345,7 @@ if (!retval) { static inline void skel_delete (struct usb_skel *dev) { - if (dev->bulk_in_buffer != NULL) - kfree (dev->bulk_in_buffer); + kfree (dev->bulk_in_buffer); if (dev->bulk_out_buffer != NULL) usb_buffer_free (dev->udev, dev->bulk_out_size, dev->bulk_out_buffer, From 9480e307cd88ef09ec9294c7d97ebec18e6d2221 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Oct 2005 09:52:56 -0700 Subject: [PATCH 0639/1940] [PATCH] DRIVER MODEL: Get rid of the obsolete tri-level suspend/resume callbacks In PM v1, all devices were called at SUSPEND_DISABLE level. Then all devices were called at SUSPEND_SAVE_STATE level, and finally SUSPEND_POWER_DOWN level. However, with PM v2, to maintain compatibility for platform devices, I arranged for the PM v2 suspend/resume callbacks to call the old PM v1 suspend/resume callbacks three times with each level in order so that existing drivers continued to work. Since this is obsolete infrastructure which is no longer necessary, we can remove it. Here's an (untested) patch to do exactly that. Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-model/driver.txt | 60 +-------------------------- arch/arm/common/locomo.c | 10 +---- arch/arm/common/sa1111.c | 11 +---- arch/arm/common/scoop.c | 24 +++++------ arch/arm/mach-pxa/corgi_ssp.c | 24 +++++------ arch/arm/mach-sa1100/neponset.c | 28 +++++-------- drivers/base/platform.c | 20 +++------ drivers/char/s3c2410-rtc.c | 20 ++++----- drivers/char/sonypi.c | 14 +++---- drivers/char/watchdog/s3c2410_wdt.c | 30 ++++++-------- drivers/hwmon/hdaps.c | 6 +-- drivers/i2c/busses/i2c-s3c2410.c | 8 ++-- drivers/i2c/i2c-core.c | 4 +- drivers/ieee1394/nodemgr.c | 4 +- drivers/input/keyboard/corgikbd.c | 22 +++++----- drivers/input/keyboard/spitzkbd.c | 38 ++++++++--------- drivers/input/serio/i8042.c | 13 ++---- drivers/input/touchscreen/corgi_ts.c | 38 ++++++++--------- drivers/media/video/msp3400.c | 8 ++-- drivers/media/video/tda9887.c | 4 +- drivers/media/video/tuner-core.c | 4 +- drivers/mfd/mcp-sa11x0.c | 20 ++++----- drivers/mmc/pxamci.c | 8 ++-- drivers/mmc/wbsd.c | 4 +- drivers/mtd/maps/sa1100-flash.c | 8 ++-- drivers/net/dm9000.c | 8 ++-- drivers/net/irda/sa1100_ir.c | 8 ++-- drivers/net/irda/smsc-ircc2.c | 12 +++--- drivers/net/phy/mdio_bus.c | 20 +++------ drivers/net/smc91x.c | 8 ++-- drivers/pci/pcie/portdrv_core.c | 4 +- drivers/pcmcia/au1000_generic.c | 21 +--------- drivers/pcmcia/hd64465_ss.c | 20 +-------- drivers/pcmcia/i82365.c | 20 +-------- drivers/pcmcia/m32r_cfc.c | 21 +--------- drivers/pcmcia/m32r_pcc.c | 21 +--------- drivers/pcmcia/omap_cf.c | 18 +------- drivers/pcmcia/pxa2xx_base.c | 24 +++-------- drivers/pcmcia/sa1100_generic.c | 20 +-------- drivers/pcmcia/tcic.c | 20 +-------- drivers/pcmcia/vrc4171_card.c | 24 +---------- drivers/serial/8250.c | 10 +---- drivers/serial/imx.c | 8 ++-- drivers/serial/mpc52xx_uart.c | 8 ++-- drivers/serial/pxa.c | 8 ++-- drivers/serial/s3c2410.c | 9 ++-- drivers/serial/sa1100.c | 8 ++-- drivers/serial/vr41xx_siu.c | 10 +---- drivers/usb/gadget/dummy_hcd.c | 22 ++-------- drivers/usb/gadget/omap_udc.c | 9 +--- drivers/usb/gadget/pxa2xx_udc.c | 17 ++++---- drivers/usb/host/isp116x-hcd.c | 14 ++----- drivers/usb/host/ohci-omap.c | 10 +---- drivers/usb/host/ohci-pxa27x.c | 4 +- drivers/usb/host/sl811-hcd.c | 10 +---- drivers/video/backlight/corgi_bl.c | 10 ++--- drivers/video/imxfb.c | 10 ++--- drivers/video/pxafb.c | 10 ++--- drivers/video/s1d13xxxfb.c | 7 +--- drivers/video/s3c2410fb.c | 27 +++++------- drivers/video/sa1100fb.c | 10 ++--- drivers/video/w100fb.c | 44 ++++++++++---------- include/linux/device.h | 17 +------- sound/arm/pxa2xx-ac97.c | 8 ++-- sound/core/init.c | 14 ++----- sound/pci/ac97/ac97_bus.c | 6 ++- 66 files changed, 321 insertions(+), 688 deletions(-) diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index fabaca1ab1b0..7c26bfae4ba0 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -196,67 +196,11 @@ it into a supported low-power state. int (*suspend) (struct device * dev, pm_message_t state, u32 level); -suspend is called to put the device in a low power state. There are -several stages to successfully suspending a device, which is denoted in -the @level parameter. Breaking the suspend transition into several -stages affords the platform flexibility in performing device power -management based on the requirements of the system and the -user-defined policy. - -SUSPEND_NOTIFY notifies the device that a suspend transition is about -to happen. This happens on system power state transitions to verify -that all devices can successfully suspend. - -A driver may choose to fail on this call, which should cause the -entire suspend transition to fail. A driver should fail only if it -knows that the device will not be able to be resumed properly when the -system wakes up again. It could also fail if it somehow determines it -is in the middle of an operation too important to stop. - -SUSPEND_DISABLE tells the device to stop I/O transactions. When it -stops transactions, or what it should do with unfinished transactions -is a policy of the driver. After this call, the driver should not -accept any other I/O requests. - -SUSPEND_SAVE_STATE tells the device to save the context of the -hardware. This includes any bus-specific hardware state and -device-specific hardware state. A pointer to this saved state can be -stored in the device's saved_state field. - -SUSPEND_POWER_DOWN tells the driver to place the device in the low -power state requested. - -Whether suspend is called with a given level is a policy of the -platform. Some levels may be omitted; drivers must not assume the -reception of any level. However, all levels must be called in the -order above; i.e. notification will always come before disabling; -disabling the device will come before suspending the device. - -All calls are made with interrupts enabled, except for the -SUSPEND_POWER_DOWN level. +suspend is called to put the device in a low power state. int (*resume) (struct device * dev, u32 level); -Resume is used to bring a device back from a low power state. Like the -suspend transition, it happens in several stages. - -RESUME_POWER_ON tells the driver to set the power state to the state -before the suspend call (The device could have already been in a low -power state before the suspend call to put in a lower power state). - -RESUME_RESTORE_STATE tells the driver to restore the state saved by -the SUSPEND_SAVE_STATE suspend call. - -RESUME_ENABLE tells the driver to start accepting I/O transactions -again. Depending on driver policy, the device may already have pending -I/O requests. - -RESUME_POWER_ON is called with interrupts disabled. The other resume -levels are called with interrupts enabled. - -As with the various suspend stages, the driver must not assume that -any other resume calls have been or will be made. Each call should be -self-contained and not dependent on any external state. +Resume is used to bring a device back from a low power state. Attributes diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index e8053d16829b..5cdb4122f057 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -550,15 +550,12 @@ struct locomo_save_data { u16 LCM_SPIMD; }; -static int locomo_suspend(struct device *dev, pm_message_t state, u32 level) +static int locomo_suspend(struct device *dev, pm_message_t state) { struct locomo *lchip = dev_get_drvdata(dev); struct locomo_save_data *save; unsigned long flags; - if (level != SUSPEND_DISABLE) - return 0; - save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL); if (!save) return -ENOMEM; @@ -597,16 +594,13 @@ static int locomo_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int locomo_resume(struct device *dev, u32 level) +static int locomo_resume(struct device *dev) { struct locomo *lchip = dev_get_drvdata(dev); struct locomo_save_data *save; unsigned long r; unsigned long flags; - if (level != RESUME_ENABLE) - return 0; - save = (struct locomo_save_data *) dev->power.saved_state; if (!save) return 0; diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 1a47fbf9cbbc..21e2a518ad3a 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -801,7 +801,7 @@ struct sa1111_save_data { #ifdef CONFIG_PM -static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level) +static int sa1111_suspend(struct device *dev, pm_message_t state) { struct sa1111 *sachip = dev_get_drvdata(dev); struct sa1111_save_data *save; @@ -809,9 +809,6 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level) unsigned int val; void __iomem *base; - if (level != SUSPEND_DISABLE) - return 0; - save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); if (!save) return -ENOMEM; @@ -856,23 +853,19 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level) /* * sa1111_resume - Restore the SA1111 device state. * @dev: device to restore - * @level: resume level * * Restore the general state of the SA1111; clock control and * interrupt controller. Other parts of the SA1111 must be * restored by their respective drivers, and must be called * via LDM after this function. */ -static int sa1111_resume(struct device *dev, u32 level) +static int sa1111_resume(struct device *dev) { struct sa1111 *sachip = dev_get_drvdata(dev); struct sa1111_save_data *save; unsigned long flags, id; void __iomem *base; - if (level != RESUME_ENABLE) - return 0; - save = (struct sa1111_save_data *)dev->power.saved_state; if (!save) return 0; diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 9e5245c702de..e8356b76d7c6 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -102,26 +102,24 @@ static void check_scoop_reg(struct scoop_dev *sdev) } #ifdef CONFIG_PM -static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) +static int scoop_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - struct scoop_dev *sdev = dev_get_drvdata(dev); + struct scoop_dev *sdev = dev_get_drvdata(dev); + + check_scoop_reg(sdev); + sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR); + SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set; - check_scoop_reg(sdev); - sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR); - SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set; - } return 0; } -static int scoop_resume(struct device *dev, uint32_t level) +static int scoop_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - struct scoop_dev *sdev = dev_get_drvdata(dev); + struct scoop_dev *sdev = dev_get_drvdata(dev); + + check_scoop_reg(sdev); + SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; - check_scoop_reg(sdev); - SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; - } return 0; } #else diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 0ef428287055..136c269db0b7 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct device *dev) return 0; } -static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level) +static int corgi_ssp_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - ssp_flush(&corgi_ssp_dev); - ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state); - } + ssp_flush(&corgi_ssp_dev); + ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state); + return 0; } -static int corgi_ssp_resume(struct device *dev, u32 level) +static int corgi_ssp_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ - GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ - ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); - ssp_enable(&corgi_ssp_dev); - } + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ + ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); + ssp_enable(&corgi_ssp_dev); + return 0; } diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index fc061641b7be..7609d69cf1cc 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -178,33 +178,27 @@ static int neponset_probe(struct device *dev) /* * LDM power management. */ -static int neponset_suspend(struct device *dev, pm_message_t state, u32 level) +static int neponset_suspend(struct device *dev, pm_message_t state) { /* * Save state. */ - if (level == SUSPEND_SAVE_STATE || - level == SUSPEND_DISABLE || - level == SUSPEND_POWER_DOWN) { - if (!dev->power.saved_state) - dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL); - if (!dev->power.saved_state) - return -ENOMEM; + if (!dev->power.saved_state) + dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL); + if (!dev->power.saved_state) + return -ENOMEM; - *(unsigned int *)dev->power.saved_state = NCR_0; - } + *(unsigned int *)dev->power.saved_state = NCR_0; return 0; } -static int neponset_resume(struct device *dev, u32 level) +static int neponset_resume(struct device *dev) { - if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) { - if (dev->power.saved_state) { - NCR_0 = *(unsigned int *)dev->power.saved_state; - kfree(dev->power.saved_state); - dev->power.saved_state = NULL; - } + if (dev->power.saved_state) { + NCR_0 = *(unsigned int *)dev->power.saved_state; + kfree(dev->power.saved_state); + dev->power.saved_state = NULL; } return 0; diff --git a/drivers/base/platform.c b/drivers/base/platform.c index a1a56ff65b76..75ce8711bca5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -281,13 +281,9 @@ static int platform_suspend(struct device * dev, pm_message_t state) { int ret = 0; - if (dev->driver && dev->driver->suspend) { - ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE); - if (ret == 0) - ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE); - if (ret == 0) - ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN); - } + if (dev->driver && dev->driver->suspend) + ret = dev->driver->suspend(dev, state); + return ret; } @@ -295,13 +291,9 @@ static int platform_resume(struct device * dev) { int ret = 0; - if (dev->driver && dev->driver->resume) { - ret = dev->driver->resume(dev, RESUME_POWER_ON); - if (ret == 0) - ret = dev->driver->resume(dev, RESUME_RESTORE_STATE); - if (ret == 0) - ret = dev->driver->resume(dev, RESUME_ENABLE); - } + if (dev->driver && dev->driver->resume) + ret = dev->driver->resume(dev); + return ret; } diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c index e1a90d9a8756..887b8b2d7882 100644 --- a/drivers/char/s3c2410-rtc.c +++ b/drivers/char/s3c2410-rtc.c @@ -519,30 +519,28 @@ static struct timespec s3c2410_rtc_delta; static int ticnt_save; -static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 level) +static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state) { struct rtc_time tm; struct timespec time; time.tv_nsec = 0; - if (level == SUSPEND_POWER_DOWN) { - /* save TICNT for anyone using periodic interrupts */ + /* save TICNT for anyone using periodic interrupts */ - ticnt_save = readb(S3C2410_TICNT); + ticnt_save = readb(S3C2410_TICNT); - /* calculate time delta for suspend */ + /* calculate time delta for suspend */ - s3c2410_rtc_gettime(&tm); - rtc_tm_to_time(&tm, &time.tv_sec); - save_time_delta(&s3c2410_rtc_delta, &time); - s3c2410_rtc_enable(dev, 0); - } + s3c2410_rtc_gettime(&tm); + rtc_tm_to_time(&tm, &time.tv_sec); + save_time_delta(&s3c2410_rtc_delta, &time); + s3c2410_rtc_enable(dev, 0); return 0; } -static int s3c2410_rtc_resume(struct device *dev, u32 level) +static int s3c2410_rtc_resume(struct device *dev) { struct rtc_time tm; struct timespec time; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index a4873684f22c..f86c15587238 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1167,19 +1167,17 @@ static int sonypi_disable(void) #ifdef CONFIG_PM static int old_camera_power; -static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level) +static int sonypi_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_DISABLE) { - old_camera_power = sonypi_device.camera_power; - sonypi_disable(); - } + old_camera_power = sonypi_device.camera_power; + sonypi_disable(); + return 0; } -static int sonypi_resume(struct device *dev, u32 level) +static int sonypi_resume(struct device *dev) { - if (level == RESUME_ENABLE) - sonypi_enable(old_camera_power); + sonypi_enable(old_camera_power); return 0; } #endif diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index 3625b2601b42..b732020acadb 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c @@ -464,32 +464,28 @@ static void s3c2410wdt_shutdown(struct device *dev) static unsigned long wtcon_save; static unsigned long wtdat_save; -static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level) +static int s3c2410wdt_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - /* Save watchdog state, and turn it off. */ - wtcon_save = readl(wdt_base + S3C2410_WTCON); - wtdat_save = readl(wdt_base + S3C2410_WTDAT); + /* Save watchdog state, and turn it off. */ + wtcon_save = readl(wdt_base + S3C2410_WTCON); + wtdat_save = readl(wdt_base + S3C2410_WTDAT); - /* Note that WTCNT doesn't need to be saved. */ - s3c2410wdt_stop(); - } + /* Note that WTCNT doesn't need to be saved. */ + s3c2410wdt_stop(); return 0; } -static int s3c2410wdt_resume(struct device *dev, u32 level) +static int s3c2410wdt_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - /* Restore watchdog state. */ + /* Restore watchdog state. */ - writel(wtdat_save, wdt_base + S3C2410_WTDAT); - writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */ - writel(wtcon_save, wdt_base + S3C2410_WTCON); + writel(wtdat_save, wdt_base + S3C2410_WTDAT); + writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */ + writel(wtcon_save, wdt_base + S3C2410_WTCON); - printk(KERN_INFO PFX "watchdog %sabled\n", - (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); - } + printk(KERN_INFO PFX "watchdog %sabled\n", + (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); return 0; } diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 7f0107613827..0015da5668a1 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c @@ -296,11 +296,9 @@ static int hdaps_probe(struct device *dev) return 0; } -static int hdaps_resume(struct device *dev, u32 level) +static int hdaps_resume(struct device *dev) { - if (level == RESUME_ENABLE) - return hdaps_device_init(); - return 0; + return hdaps_device_init(); } static struct device_driver hdaps_driver = { diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 73a092fb0e7e..69fa282df2d5 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -879,14 +879,12 @@ static int s3c24xx_i2c_remove(struct device *dev) } #ifdef CONFIG_PM -static int s3c24xx_i2c_resume(struct device *dev, u32 level) +static int s3c24xx_i2c_resume(struct device *dev) { struct s3c24xx_i2c *i2c = dev_get_drvdata(dev); - - if (i2c != NULL && level == RESUME_ENABLE) { - dev_dbg(dev, "resume: level %d\n", level); + + if (i2c != NULL) s3c24xx_i2c_init(i2c); - } return 0; } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index dda472e5e8be..45aa0e54e297 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -48,7 +48,7 @@ static int i2c_bus_suspend(struct device * dev, pm_message_t state) int rc = 0; if (dev->driver && dev->driver->suspend) - rc = dev->driver->suspend(dev,state,0); + rc = dev->driver->suspend(dev, state); return rc; } @@ -57,7 +57,7 @@ static int i2c_bus_resume(struct device * dev) int rc = 0; if (dev->driver && dev->driver->resume) - rc = dev->driver->resume(dev,0); + rc = dev->driver->resume(dev); return rc; } diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 347ece6b583c..7fff5a1d2ea4 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -1292,7 +1292,7 @@ static void nodemgr_suspend_ne(struct node_entry *ne) if (ud->device.driver && (!ud->device.driver->suspend || - ud->device.driver->suspend(&ud->device, PMSG_SUSPEND, 0))) + ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) device_release_driver(&ud->device); } up_write(&ne->device.bus->subsys.rwsem); @@ -1315,7 +1315,7 @@ static void nodemgr_resume_ne(struct node_entry *ne) continue; if (ud->device.driver && ud->device.driver->resume) - ud->device.driver->resume(&ud->device, 0); + ud->device.driver->resume(&ud->device); } up_read(&ne->device.bus->subsys.rwsem); diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 564bb365f6fc..3210d298b3bc 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -259,24 +259,22 @@ static void corgikbd_hinge_timer(unsigned long data) } #ifdef CONFIG_PM -static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level) +static int corgikbd_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - struct corgikbd *corgikbd = dev_get_drvdata(dev); - corgikbd->suspended = 1; - } + struct corgikbd *corgikbd = dev_get_drvdata(dev); + corgikbd->suspended = 1; + return 0; } -static int corgikbd_resume(struct device *dev, uint32_t level) +static int corgikbd_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - struct corgikbd *corgikbd = dev_get_drvdata(dev); + struct corgikbd *corgikbd = dev_get_drvdata(dev); + + /* Upon resume, ignore the suspend key for a short while */ + corgikbd->suspend_jiffies=jiffies; + corgikbd->suspended = 0; - /* Upon resume, ignore the suspend key for a short while */ - corgikbd->suspend_jiffies=jiffies; - corgikbd->suspended = 0; - } return 0; } #else diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 732fb310e487..cee9c734a048 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -309,34 +309,32 @@ static void spitzkbd_hinge_timer(unsigned long data) } #ifdef CONFIG_PM -static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level) +static int spitzkbd_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - int i; - struct spitzkbd *spitzkbd = dev_get_drvdata(dev); - spitzkbd->suspended = 1; + int i; + struct spitzkbd *spitzkbd = dev_get_drvdata(dev); + spitzkbd->suspended = 1; + + /* Set Strobe lines as inputs - *except* strobe line 0 leave this + enabled so we can detect a power button press for resume */ + for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++) + pxa_gpio_mode(spitz_strobes[i] | GPIO_IN); - /* Set Strobe lines as inputs - *except* strobe line 0 leave this - enabled so we can detect a power button press for resume */ - for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++) - pxa_gpio_mode(spitz_strobes[i] | GPIO_IN); - } return 0; } -static int spitzkbd_resume(struct device *dev, uint32_t level) +static int spitzkbd_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - int i; - struct spitzkbd *spitzkbd = dev_get_drvdata(dev); + int i; + struct spitzkbd *spitzkbd = dev_get_drvdata(dev); - for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++) - pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH); + for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++) + pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH); + + /* Upon resume, ignore the suspend key for a short while */ + spitzkbd->suspend_jiffies = jiffies; + spitzkbd->suspended = 0; - /* Upon resume, ignore the suspend key for a short while */ - spitzkbd->suspend_jiffies = jiffies; - spitzkbd->suspended = 0; - } return 0; } #else diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 40d451ce07ff..4bc40f159996 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -911,12 +911,10 @@ static long i8042_panic_blink(long count) * Here we try to restore the original BIOS settings */ -static int i8042_suspend(struct device *dev, pm_message_t state, u32 level) +static int i8042_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_DISABLE) { - del_timer_sync(&i8042_timer); - i8042_controller_reset(); - } + del_timer_sync(&i8042_timer); + i8042_controller_reset(); return 0; } @@ -926,13 +924,10 @@ static int i8042_suspend(struct device *dev, pm_message_t state, u32 level) * Here we try to reset everything back to a state in which suspended */ -static int i8042_resume(struct device *dev, u32 level) +static int i8042_resume(struct device *dev) { int i; - if (level != RESUME_ENABLE) - return 0; - if (i8042_ctl_test()) return -1; diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 40ae183ba1cd..0ba3e6562bff 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -231,34 +231,32 @@ static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs) } #ifdef CONFIG_PM -static int corgits_suspend(struct device *dev, pm_message_t state, uint32_t level) +static int corgits_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - struct corgi_ts *corgi_ts = dev_get_drvdata(dev); + struct corgi_ts *corgi_ts = dev_get_drvdata(dev); - if (corgi_ts->pendown) { - del_timer_sync(&corgi_ts->timer); - corgi_ts->tc.pressure = 0; - new_data(corgi_ts, NULL); - corgi_ts->pendown = 0; - } - corgi_ts->power_mode = PWR_MODE_SUSPEND; - - corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); + if (corgi_ts->pendown) { + del_timer_sync(&corgi_ts->timer); + corgi_ts->tc.pressure = 0; + new_data(corgi_ts, NULL); + corgi_ts->pendown = 0; } + corgi_ts->power_mode = PWR_MODE_SUSPEND; + + corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); + return 0; } -static int corgits_resume(struct device *dev, uint32_t level) +static int corgits_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - struct corgi_ts *corgi_ts = dev_get_drvdata(dev); + struct corgi_ts *corgi_ts = dev_get_drvdata(dev); + + corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); + /* Enable Falling Edge */ + set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); + corgi_ts->power_mode = PWR_MODE_ACTIVE; - corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); - /* Enable Falling Edge */ - set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); - corgi_ts->power_mode = PWR_MODE_ACTIVE; - } return 0; } #else diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index f0d43fc2632f..262890cb20a7 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -1420,8 +1420,8 @@ static int msp_detach(struct i2c_client *client); static int msp_probe(struct i2c_adapter *adap); static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); -static int msp_suspend(struct device * dev, pm_message_t state, u32 level); -static int msp_resume(struct device * dev, u32 level); +static int msp_suspend(struct device * dev, pm_message_t state); +static int msp_resume(struct device * dev); static void msp_wake_thread(struct i2c_client *client); @@ -1821,7 +1821,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int msp_suspend(struct device * dev, pm_message_t state, u32 level) +static int msp_suspend(struct device * dev, pm_message_t state) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); @@ -1830,7 +1830,7 @@ static int msp_suspend(struct device * dev, pm_message_t state, u32 level) return 0; } -static int msp_resume(struct device * dev, u32 level) +static int msp_resume(struct device * dev) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 0456dda2624d..94053f149ddf 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -784,13 +784,13 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level) +static int tda9887_suspend(struct device * dev, pm_message_t state) { dprintk("tda9887: suspend\n"); return 0; } -static int tda9887_resume(struct device * dev, u32 level) +static int tda9887_resume(struct device * dev) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); struct tda9887 *t = i2c_get_clientdata(c); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 05572020af4d..ad85bef1c3d5 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -697,7 +697,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tuner_suspend(struct device *dev, pm_message_t state, u32 level) +static int tuner_suspend(struct device *dev, pm_message_t state) { struct i2c_client *c = container_of (dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata (c); @@ -707,7 +707,7 @@ static int tuner_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int tuner_resume(struct device *dev, u32 level) +static int tuner_resume(struct device *dev) { struct i2c_client *c = container_of (dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata (c); diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index e9806fbbe696..720e7a326308 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -219,26 +219,24 @@ static int mcp_sa11x0_remove(struct device *dev) return 0; } -static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state, u32 level) +static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state) { struct mcp *mcp = dev_get_drvdata(dev); - if (level == SUSPEND_DISABLE) { - priv(mcp)->mccr0 = Ser4MCCR0; - priv(mcp)->mccr1 = Ser4MCCR1; - Ser4MCCR0 &= ~MCCR0_MCE; - } + priv(mcp)->mccr0 = Ser4MCCR0; + priv(mcp)->mccr1 = Ser4MCCR1; + Ser4MCCR0 &= ~MCCR0_MCE; + return 0; } -static int mcp_sa11x0_resume(struct device *dev, u32 level) +static int mcp_sa11x0_resume(struct device *dev) { struct mcp *mcp = dev_get_drvdata(dev); - if (level == RESUME_RESTORE_STATE) { - Ser4MCCR1 = priv(mcp)->mccr1; - Ser4MCCR0 = priv(mcp)->mccr0; - } + Ser4MCCR1 = priv(mcp)->mccr1; + Ser4MCCR0 = priv(mcp)->mccr0; + return 0; } diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index b53af57074e3..8eba373d42d7 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -571,23 +571,23 @@ static int pxamci_remove(struct device *dev) } #ifdef CONFIG_PM -static int pxamci_suspend(struct device *dev, pm_message_t state, u32 level) +static int pxamci_suspend(struct device *dev, pm_message_t state) { struct mmc_host *mmc = dev_get_drvdata(dev); int ret = 0; - if (mmc && level == SUSPEND_DISABLE) + if (mmc) ret = mmc_suspend_host(mmc, state); return ret; } -static int pxamci_resume(struct device *dev, u32 level) +static int pxamci_resume(struct device *dev) { struct mmc_host *mmc = dev_get_drvdata(dev); int ret = 0; - if (mmc && level == RESUME_ENABLE) + if (mmc) ret = mmc_resume_host(mmc); return ret; diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 3cbca7cbea80..25f7ce7b3bc0 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -1955,14 +1955,14 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) */ #ifdef CONFIG_PM -static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level) +static int wbsd_suspend(struct device *dev, pm_message_t state) { DBGF("Not yet supported\n"); return 0; } -static int wbsd_resume(struct device *dev, u32 level) +static int wbsd_resume(struct device *dev) { DBGF("Not yet supported\n"); diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 8dcaa357b4bb..55f21ddec3df 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -402,21 +402,21 @@ static int __exit sa1100_mtd_remove(struct device *dev) } #ifdef CONFIG_PM -static int sa1100_mtd_suspend(struct device *dev, pm_message_t state, u32 level) +static int sa1100_mtd_suspend(struct device *dev, pm_message_t state) { struct sa_info *info = dev_get_drvdata(dev); int ret = 0; - if (info && level == SUSPEND_SAVE_STATE) + if (info) ret = info->mtd->suspend(info->mtd); return ret; } -static int sa1100_mtd_resume(struct device *dev, u32 level) +static int sa1100_mtd_resume(struct device *dev) { struct sa_info *info = dev_get_drvdata(dev); - if (info && level == RESUME_RESTORE_STATE) + if (info) info->mtd->resume(info->mtd); return 0; } diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index e54fc10f6846..abce1f730d00 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1140,11 +1140,11 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) } static int -dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level) +dm9000_drv_suspend(struct device *dev, pm_message_t state) { struct net_device *ndev = dev_get_drvdata(dev); - if (ndev && level == SUSPEND_DISABLE) { + if (ndev) { if (netif_running(ndev)) { netif_device_detach(ndev); dm9000_shutdown(ndev); @@ -1154,12 +1154,12 @@ dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level) } static int -dm9000_drv_resume(struct device *dev, u32 level) +dm9000_drv_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); board_info_t *db = (board_info_t *) ndev->priv; - if (ndev && level == RESUME_ENABLE) { + if (ndev) { if (netif_running(ndev)) { dm9000_reset(db); diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 8d34ac60d906..06883309916d 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -291,12 +291,12 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si) /* * Suspend the IrDA interface. */ -static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 level) +static int sa1100_irda_suspend(struct device *_dev, pm_message_t state) { struct net_device *dev = dev_get_drvdata(_dev); struct sa1100_irda *si; - if (!dev || level != SUSPEND_DISABLE) + if (!dev) return 0; si = dev->priv; @@ -316,12 +316,12 @@ static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 leve /* * Resume the IrDA interface. */ -static int sa1100_irda_resume(struct device *_dev, u32 level) +static int sa1100_irda_resume(struct device *_dev) { struct net_device *dev = dev_get_drvdata(_dev); struct sa1100_irda *si; - if (!dev || level != RESUME_ENABLE) + if (!dev) return 0; si = dev->priv; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index dd89bda1f131..bbac720cca63 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -213,8 +213,8 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base); /* Power Management */ -static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level); -static int smsc_ircc_resume(struct device *dev, u32 level); +static int smsc_ircc_suspend(struct device *dev, pm_message_t state); +static int smsc_ircc_resume(struct device *dev); static struct device_driver smsc_ircc_driver = { .name = SMSC_IRCC2_DRIVER_NAME, @@ -1646,13 +1646,13 @@ static int smsc_ircc_net_close(struct net_device *dev) return 0; } -static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level) +static int smsc_ircc_suspend(struct device *dev, pm_message_t state) { struct smsc_ircc_cb *self = dev_get_drvdata(dev); IRDA_MESSAGE("%s, Suspending\n", driver_name); - if (level == SUSPEND_DISABLE && !self->io.suspended) { + if (!self->io.suspended) { smsc_ircc_net_close(self->netdev); self->io.suspended = 1; } @@ -1660,11 +1660,11 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int smsc_ircc_resume(struct device *dev, u32 level) +static int smsc_ircc_resume(struct device *dev) { struct smsc_ircc_cb *self = dev_get_drvdata(dev); - if (level == RESUME_ENABLE && self->io.suspended) { + if (self->io.suspended) { smsc_ircc_net_open(self->netdev); self->io.suspended = 0; diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 90630672703d..ad93b0da87f0 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -133,13 +133,9 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state) int ret = 0; struct device_driver *drv = dev->driver; - if (drv && drv->suspend) { - ret = drv->suspend(dev, state, SUSPEND_DISABLE); - if (ret == 0) - ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE); - if (ret == 0) - ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN); - } + if (drv && drv->suspend) + ret = drv->suspend(dev, state); + return ret; } @@ -148,13 +144,9 @@ static int mdio_bus_resume(struct device * dev) int ret = 0; struct device_driver *drv = dev->driver; - if (drv && drv->resume) { - ret = drv->resume(dev, RESUME_POWER_ON); - if (ret == 0) - ret = drv->resume(dev, RESUME_RESTORE_STATE); - if (ret == 0) - ret = drv->resume(dev, RESUME_ENABLE); - } + if (drv && drv->resume) + ret = drv->resume(dev); + return ret; } diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 1438fdd20826..0ddaa611cc61 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -2291,11 +2291,11 @@ static int smc_drv_remove(struct device *dev) return 0; } -static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level) +static int smc_drv_suspend(struct device *dev, pm_message_t state) { struct net_device *ndev = dev_get_drvdata(dev); - if (ndev && level == SUSPEND_DISABLE) { + if (ndev) { if (netif_running(ndev)) { netif_device_detach(ndev); smc_shutdown(ndev); @@ -2305,12 +2305,12 @@ static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int smc_drv_resume(struct device *dev, u32 level) +static int smc_drv_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct net_device *ndev = dev_get_drvdata(dev); - if (ndev && level == RESUME_ENABLE) { + if (ndev) { struct smc_local *lp = netdev_priv(ndev); smc_enable_device(pdev); if (netif_running(ndev)) { diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 393e0cee91a9..14f05d22bb70 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -61,7 +61,7 @@ static int pcie_port_remove_service(struct device *dev) static void pcie_port_shutdown_service(struct device *dev) {} -static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level) +static int pcie_port_suspend_service(struct device *dev, pm_message_t state) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; @@ -76,7 +76,7 @@ static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 return 0; } -static int pcie_port_resume_service(struct device *dev, u32 level) +static int pcie_port_resume_service(struct device *dev) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 470ef756252e..d90a634cebf5 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -519,30 +519,13 @@ static int au1x00_drv_pcmcia_probe(struct device *dev) } -static int au1x00_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - - static struct device_driver au1x00_pcmcia_driver = { .probe = au1x00_drv_pcmcia_probe, .remove = au1x00_drv_pcmcia_remove, .name = "au1x00-pcmcia", .bus = &platform_bus_type, - .suspend = au1x00_drv_pcmcia_suspend, - .resume = au1x00_drv_pcmcia_resume + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device au1x00_device = { diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 316f8bcc878b..b57a0b98b4d6 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -844,27 +844,11 @@ static void hs_exit_socket(hs_socket_t *sp) local_irq_restore(flags); } -static int hd64465_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int hd64465_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - static struct device_driver hd64465_driver = { .name = "hd64465-pcmcia", .bus = &platform_bus_type, - .suspend = hd64465_suspend, - .resume = hd64465_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device hd64465_device = { diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index a713015e8228..4a41f67d185d 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1332,27 +1332,11 @@ static struct pccard_operations pcic_operations = { /*====================================================================*/ -static int i82365_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int i82365_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - static struct device_driver i82365_driver = { .name = "i82365", .bus = &platform_bus_type, - .suspend = i82365_suspend, - .resume = i82365_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device i82365_device = { diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 65f3ee3d4d3c..c6ed70ea4812 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -731,28 +731,11 @@ static struct pccard_operations pcc_operations = { /*====================================================================*/ -static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int m32r_pcc_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - - static struct device_driver pcc_driver = { .name = "cfc", .bus = &platform_bus_type, - .suspend = m32r_pcc_suspend, - .resume = m32r_pcc_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 7b14d7efd68c..3397ff28de6a 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -695,28 +695,11 @@ static struct pccard_operations pcc_operations = { /*====================================================================*/ -static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int m32r_pcc_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - - static struct device_driver pcc_driver = { .name = "pcc", .bus = &platform_bus_type, - .suspend = m32r_pcc_suspend, - .resume = m32r_pcc_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 94be9e51654e..2558c3cc91ec 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -329,27 +329,13 @@ static int __devexit omap_cf_remove(struct device *dev) return 0; } -static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level) -{ - if (level != SUSPEND_SAVE_STATE) - return 0; - return pcmcia_socket_dev_suspend(dev, mesg); -} - -static int omap_cf_resume(struct device *dev, u32 level) -{ - if (level != RESUME_RESTORE_STATE) - return 0; - return pcmcia_socket_dev_resume(dev); -} - static struct device_driver omap_cf_driver = { .name = (char *) driver_name, .bus = &platform_bus_type, .probe = omap_cf_probe, .remove = __devexit_p(omap_cf_remove), - .suspend = omap_cf_suspend, - .resume = omap_cf_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static int __init omap_cf_init(void) diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 325c992f7d8f..c2a12d53f6c7 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -205,32 +205,20 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev) } EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe); -static int pxa2xx_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level) +static int pxa2xx_drv_pcmcia_resume(struct device *dev) { - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} + struct pcmcia_low_level *ops = dev->platform_data; + int nr = ops ? ops->nr : 0; -static int pxa2xx_drv_pcmcia_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - { - struct pcmcia_low_level *ops = dev->platform_data; - int nr = ops ? ops->nr : 0; + MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); - MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); - ret = pcmcia_socket_dev_resume(dev); - } - return ret; + return pcmcia_socket_dev_resume(dev); } static struct device_driver pxa2xx_pcmcia_driver = { .probe = pxa2xx_drv_pcmcia_probe, .remove = soc_common_drv_pcmcia_remove, - .suspend = pxa2xx_drv_pcmcia_suspend, + .suspend = pcmcia_socket_dev_suspend, .resume = pxa2xx_drv_pcmcia_resume, .name = "pxa2xx-pcmcia", .bus = &platform_bus_type, diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index d4ed508b38be..b768fa81f043 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -74,29 +74,13 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev) return ret; } -static int sa11x0_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - static struct device_driver sa11x0_pcmcia_driver = { .probe = sa11x0_drv_pcmcia_probe, .remove = soc_common_drv_pcmcia_remove, .name = "sa11x0-pcmcia", .bus = &platform_bus_type, - .suspend = sa11x0_drv_pcmcia_suspend, - .resume = sa11x0_drv_pcmcia_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; /* sa11x0_pcmcia_init() diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index d5a61eae6119..f158b67f6610 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -372,27 +372,11 @@ static int __init get_tcic_id(void) /*====================================================================*/ -static int tcic_drv_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int tcic_drv_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - static struct device_driver tcic_driver = { .name = "tcic-pcmcia", .bus = &platform_bus_type, - .suspend = tcic_drv_suspend, - .resume = tcic_drv_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static struct platform_device tcic_device = { diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 17bb2da6752b..3d2dca675e02 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -774,31 +774,11 @@ static int __devinit vrc4171_card_setup(char *options) __setup("vrc4171_card=", vrc4171_card_setup); -static int vrc4171_card_suspend(struct device *dev, pm_message_t state, u32 level) -{ - int retval = 0; - - if (level == SUSPEND_SAVE_STATE) - retval = pcmcia_socket_dev_suspend(dev, state); - - return retval; -} - -static int vrc4171_card_resume(struct device *dev, u32 level) -{ - int retval = 0; - - if (level == RESUME_RESTORE_STATE) - retval = pcmcia_socket_dev_resume(dev); - - return retval; -} - static struct device_driver vrc4171_card_driver = { .name = vrc4171_card_name, .bus = &platform_bus_type, - .suspend = vrc4171_card_suspend, - .resume = vrc4171_card_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; static int __devinit vrc4171_card_init(void) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 4d75cdfa0a0a..afb7ddf200e0 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2358,13 +2358,10 @@ static int __devexit serial8250_remove(struct device *dev) return 0; } -static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level) +static int serial8250_suspend(struct device *dev, pm_message_t state) { int i; - if (level != SUSPEND_DISABLE) - return 0; - for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; @@ -2375,13 +2372,10 @@ static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int serial8250_resume(struct device *dev, u32 level) +static int serial8250_resume(struct device *dev) { int i; - if (level != RESUME_ENABLE) - return 0; - for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index bdb4e454b8b0..5b3933b0c997 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -921,21 +921,21 @@ static struct uart_driver imx_reg = { .cons = IMX_CONSOLE, }; -static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level) +static int serial_imx_suspend(struct device *_dev, pm_message_t state) { struct imx_port *sport = dev_get_drvdata(_dev); - if (sport && level == SUSPEND_DISABLE) + if (sport) uart_suspend_port(&imx_reg, &sport->port); return 0; } -static int serial_imx_resume(struct device *_dev, u32 level) +static int serial_imx_resume(struct device *_dev) { struct imx_port *sport = dev_get_drvdata(_dev); - if (sport && level == RESUME_ENABLE) + if (sport) uart_resume_port(&imx_reg, &sport->port); return 0; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 0585ab27ffde..8a79968f8ce1 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -781,22 +781,22 @@ mpc52xx_uart_remove(struct device *dev) #ifdef CONFIG_PM static int -mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level) +mpc52xx_uart_suspend(struct device *dev, pm_message_t state) { struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev); - if (sport && level == SUSPEND_DISABLE) + if (sport) uart_suspend_port(&mpc52xx_uart_driver, port); return 0; } static int -mpc52xx_uart_resume(struct device *dev, u32 level) +mpc52xx_uart_resume(struct device *dev) { struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev); - if (port && level == RESUME_ENABLE) + if (port) uart_resume_port(&mpc52xx_uart_driver, port); return 0; diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 90c2a86c421b..7999686d7b47 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -786,21 +786,21 @@ static struct uart_driver serial_pxa_reg = { .cons = PXA_CONSOLE, }; -static int serial_pxa_suspend(struct device *_dev, pm_message_t state, u32 level) +static int serial_pxa_suspend(struct device *_dev, pm_message_t state) { struct uart_pxa_port *sport = dev_get_drvdata(_dev); - if (sport && level == SUSPEND_DISABLE) + if (sport) uart_suspend_port(&serial_pxa_reg, &sport->port); return 0; } -static int serial_pxa_resume(struct device *_dev, u32 level) +static int serial_pxa_resume(struct device *_dev) { struct uart_pxa_port *sport = dev_get_drvdata(_dev); - if (sport && level == RESUME_ENABLE) + if (sport) uart_resume_port(&serial_pxa_reg, &sport->port); return 0; diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 52692aa345ec..06a17dff1a73 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -1134,23 +1134,22 @@ static int s3c24xx_serial_remove(struct device *_dev) #ifdef CONFIG_PM -static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, - u32 level) +static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state) { struct uart_port *port = s3c24xx_dev_to_port(dev); - if (port && level == SUSPEND_DISABLE) + if (port) uart_suspend_port(&s3c24xx_uart_drv, port); return 0; } -static int s3c24xx_serial_resume(struct device *dev, u32 level) +static int s3c24xx_serial_resume(struct device *dev) { struct uart_port *port = s3c24xx_dev_to_port(dev); struct s3c24xx_uart_port *ourport = to_ourport(port); - if (port && level == RESUME_ENABLE) { + if (port) { clk_enable(ourport->clk); s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); clk_disable(ourport->clk); diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index dd8aed242357..c4a789e6af44 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -834,21 +834,21 @@ static struct uart_driver sa1100_reg = { .cons = SA1100_CONSOLE, }; -static int sa1100_serial_suspend(struct device *_dev, pm_message_t state, u32 level) +static int sa1100_serial_suspend(struct device *_dev, pm_message_t state) { struct sa1100_port *sport = dev_get_drvdata(_dev); - if (sport && level == SUSPEND_DISABLE) + if (sport) uart_suspend_port(&sa1100_reg, &sport->port); return 0; } -static int sa1100_serial_resume(struct device *_dev, u32 level) +static int sa1100_serial_resume(struct device *_dev) { struct sa1100_port *sport = dev_get_drvdata(_dev); - if (sport && level == RESUME_ENABLE) + if (sport) uart_resume_port(&sa1100_reg, &sport->port); return 0; diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 0c5d65a08f6e..2b623ab0e36e 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -976,14 +976,11 @@ static int siu_remove(struct device *dev) return 0; } -static int siu_suspend(struct device *dev, pm_message_t state, u32 level) +static int siu_suspend(struct device *dev, pm_message_t state) { struct uart_port *port; int i; - if (level != SUSPEND_DISABLE) - return 0; - for (i = 0; i < siu_uart_driver.nr; i++) { port = &siu_uart_ports[i]; if ((port->type == PORT_VR41XX_SIU || @@ -995,14 +992,11 @@ static int siu_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int siu_resume(struct device *dev, u32 level) +static int siu_resume(struct device *dev) { struct uart_port *port; int i; - if (level != RESUME_ENABLE) - return 0; - for (i = 0; i < siu_uart_driver.nr; i++) { port = &siu_uart_ports[i]; if ((port->type == PORT_VR41XX_SIU || diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 583db7c38cf1..f2bdf4e1eb80 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -935,14 +935,10 @@ static int dummy_udc_remove (struct device *dev) return 0; } -static int dummy_udc_suspend (struct device *dev, pm_message_t state, - u32 level) +static int dummy_udc_suspend (struct device *dev, pm_message_t state) { struct dummy *dum = dev_get_drvdata(dev); - if (level != SUSPEND_DISABLE) - return 0; - dev_dbg (dev, "%s\n", __FUNCTION__); spin_lock_irq (&dum->lock); dum->udc_suspended = 1; @@ -954,13 +950,10 @@ static int dummy_udc_suspend (struct device *dev, pm_message_t state, return 0; } -static int dummy_udc_resume (struct device *dev, u32 level) +static int dummy_udc_resume (struct device *dev) { struct dummy *dum = dev_get_drvdata(dev); - if (level != RESUME_ENABLE) - return 0; - dev_dbg (dev, "%s\n", __FUNCTION__); spin_lock_irq (&dum->lock); dum->udc_suspended = 0; @@ -1936,14 +1929,10 @@ static int dummy_hcd_remove (struct device *dev) return 0; } -static int dummy_hcd_suspend (struct device *dev, pm_message_t state, - u32 level) +static int dummy_hcd_suspend (struct device *dev, pm_message_t state) { struct usb_hcd *hcd; - if (level != SUSPEND_DISABLE) - return 0; - dev_dbg (dev, "%s\n", __FUNCTION__); hcd = dev_get_drvdata (dev); @@ -1958,13 +1947,10 @@ static int dummy_hcd_suspend (struct device *dev, pm_message_t state, return 0; } -static int dummy_hcd_resume (struct device *dev, u32 level) +static int dummy_hcd_resume (struct device *dev) { struct usb_hcd *hcd; - if (level != RESUME_ENABLE) - return 0; - dev_dbg (dev, "%s\n", __FUNCTION__); hcd = dev_get_drvdata (dev); hcd->state = HC_STATE_RUNNING; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index ff5533e69560..58b3ec97fb9a 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2909,12 +2909,10 @@ static int __exit omap_udc_remove(struct device *dev) * may involve talking to an external transceiver (e.g. isp1301). */ -static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level) +static int omap_udc_suspend(struct device *dev, pm_message_t message) { u32 devstat; - if (level != SUSPEND_POWER_DOWN) - return 0; devstat = UDC_DEVSTAT_REG; /* we're requesting 48 MHz clock if the pullup is enabled @@ -2931,11 +2929,8 @@ static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level) return 0; } -static int omap_udc_resume(struct device *dev, u32 level) +static int omap_udc_resume(struct device *dev) { - if (level != RESUME_POWER_ON) - return 0; - DBG("resume + wakeup/SRP\n"); omap_pullup(&udc->gadget, 1); diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 73f8c9404156..00dfe42d7a86 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -2602,24 +2602,23 @@ static int __exit pxa2xx_udc_remove(struct device *_dev) * VBUS IRQs should probably be ignored so that the PXA device just acts * "dead" to USB hosts until system resume. */ -static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level) +static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state) { struct pxa2xx_udc *udc = dev_get_drvdata(dev); - if (level == SUSPEND_POWER_DOWN) { - if (!udc->mach->udc_command) - WARN("USB host won't detect disconnect!\n"); - pullup(udc, 0); - } + if (!udc->mach->udc_command) + WARN("USB host won't detect disconnect!\n"); + pullup(udc, 0); + return 0; } -static int pxa2xx_udc_resume(struct device *dev, u32 level) +static int pxa2xx_udc_resume(struct device *dev) { struct pxa2xx_udc *udc = dev_get_drvdata(dev); - if (level == RESUME_POWER_ON) - pullup(udc, 1); + pullup(udc, 1); + return 0; } diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index e142056b0d2c..0f6183a829c4 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1774,15 +1774,12 @@ static int __init isp116x_probe(struct device *dev) /* Suspend of platform device */ -static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase) +static int isp116x_suspend(struct device *dev, pm_message_t state) { int ret = 0; struct usb_hcd *hcd = dev_get_drvdata(dev); - VDBG("%s: state %x, phase %x\n", __func__, state, phase); - - if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN) - return 0; + VDBG("%s: state %x\n", __func__, state); ret = usb_suspend_device(hcd->self.root_hub, state); if (!ret) { @@ -1797,15 +1794,12 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase) /* Resume platform device */ -static int isp116x_resume(struct device *dev, u32 phase) +static int isp116x_resume(struct device *dev) { int ret = 0; struct usb_hcd *hcd = dev_get_drvdata(dev); - VDBG("%s: state %x, phase %x\n", __func__, dev->power.power_state, - phase); - if (phase != RESUME_POWER_ON) - return 0; + VDBG("%s: state %x\n", __func__, dev->power.power_state); ret = usb_resume_device(hcd->self.root_hub); if (!ret) { diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index d8f3ba7ad52e..a574216625a0 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -455,14 +455,11 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) #ifdef CONFIG_PM -static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level) +static int ohci_omap_suspend(struct device *dev, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); int status = -EINVAL; - if (level != SUSPEND_POWER_DOWN) - return 0; - down(&ohci_to_hcd(ohci)->self.root_hub->serialize); status = ohci_hub_suspend(ohci_to_hcd(ohci)); if (status == 0) { @@ -476,14 +473,11 @@ static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level return status; } -static int ohci_omap_resume(struct device *dev, u32 level) +static int ohci_omap_resume(struct device *dev) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); int status = 0; - if (level != RESUME_POWER_ON) - return 0; - if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 2fdb262d4726..f042261ecb8e 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -309,7 +309,7 @@ static int ohci_hcd_pxa27x_drv_remove(struct device *dev) return 0; } -static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level) +static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state) { // struct platform_device *pdev = to_platform_device(dev); // struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -318,7 +318,7 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u return 0; } -static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level) +static int ohci_hcd_pxa27x_drv_resume(struct device *dev) { // struct platform_device *pdev = to_platform_device(dev); // struct usb_hcd *hcd = dev_get_drvdata(dev); diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index d42a15d10a46..03cf6accfe64 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1784,15 +1784,12 @@ sl811h_probe(struct device *dev) */ static int -sl811h_suspend(struct device *dev, pm_message_t state, u32 phase) +sl811h_suspend(struct device *dev, pm_message_t state) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct sl811 *sl811 = hcd_to_sl811(hcd); int retval = 0; - if (phase != SUSPEND_POWER_DOWN) - return retval; - if (state.event == PM_EVENT_FREEZE) retval = sl811h_hub_suspend(hcd); else if (state.event == PM_EVENT_SUSPEND) @@ -1803,14 +1800,11 @@ sl811h_suspend(struct device *dev, pm_message_t state, u32 phase) } static int -sl811h_resume(struct device *dev, u32 phase) +sl811h_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct sl811 *sl811 = hcd_to_sl811(hcd); - if (phase != RESUME_POWER_ON) - return 0; - /* with no "check to see if VBUS is still powered" board hook, * let's assume it'd only be powered to enable remote wakeup. */ diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 3c72c627e65e..1991fdb32dfb 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -73,17 +73,15 @@ static void corgibl_blank(int blank) } #ifdef CONFIG_PM -static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level) +static int corgibl_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) - corgibl_blank(FB_BLANK_POWERDOWN); + corgibl_blank(FB_BLANK_POWERDOWN); return 0; } -static int corgibl_resume(struct device *dev, u32 level) +static int corgibl_resume(struct device *dev) { - if (level == RESUME_POWER_ON) - corgibl_blank(FB_BLANK_UNBLANK); + corgibl_blank(FB_BLANK_UNBLANK); return 0; } #else diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 1d54d3d6960b..0b9301facbd3 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -424,23 +424,21 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi) * Power management hooks. Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */ -static int imxfb_suspend(struct device *dev, pm_message_t state, u32 level) +static int imxfb_suspend(struct device *dev, pm_message_t state) { struct imxfb_info *fbi = dev_get_drvdata(dev); pr_debug("%s\n",__FUNCTION__); - if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) - imxfb_disable_controller(fbi); + imxfb_disable_controller(fbi); return 0; } -static int imxfb_resume(struct device *dev, u32 level) +static int imxfb_resume(struct device *dev) { struct imxfb_info *fbi = dev_get_drvdata(dev); pr_debug("%s\n",__FUNCTION__); - if (level == RESUME_ENABLE) - imxfb_enable_controller(fbi); + imxfb_enable_controller(fbi); return 0; } #else diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 194eed0a238c..6206da9dd5da 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -981,21 +981,19 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) * Power management hooks. Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */ -static int pxafb_suspend(struct device *dev, pm_message_t state, u32 level) +static int pxafb_suspend(struct device *dev, pm_message_t state) { struct pxafb_info *fbi = dev_get_drvdata(dev); - if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) - set_ctrlr_state(fbi, C_DISABLE_PM); + set_ctrlr_state(fbi, C_DISABLE_PM); return 0; } -static int pxafb_resume(struct device *dev, u32 level) +static int pxafb_resume(struct device *dev) { struct pxafb_info *fbi = dev_get_drvdata(dev); - if (level == RESUME_ENABLE) - set_ctrlr_state(fbi, C_ENABLE_PM); + set_ctrlr_state(fbi, C_ENABLE_PM); return 0; } #else diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index fa98d91c42eb..cb2f7a1de947 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -655,7 +655,7 @@ s1d13xxxfb_probe(struct device *dev) } #ifdef CONFIG_PM -static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level) +static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state) { struct fb_info *info = dev_get_drvdata(dev); struct s1d13xxxfb_par *s1dfb = info->par; @@ -702,15 +702,12 @@ static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level) return 0; } -static int s1d13xxxfb_resume(struct device *dev, u32 level) +static int s1d13xxxfb_resume(struct device *dev) { struct fb_info *info = dev_get_drvdata(dev); struct s1d13xxxfb_par *s1dfb = info->par; struct s1d13xxxfb_pdata *pdata = NULL; - if (level != RESUME_ENABLE) - return 0; - /* awaken the chip */ s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10); diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 5ab79afb53b7..3862d3cb1fb2 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -847,37 +847,32 @@ static int s3c2410fb_remove(struct device *dev) /* suspend and resume support for the lcd controller */ -static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level) +static int s3c2410fb_suspend(struct device *dev, pm_message_t state) { struct fb_info *fbinfo = dev_get_drvdata(dev); struct s3c2410fb_info *info = fbinfo->par; - if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) { - s3c2410fb_stop_lcd(); + s3c2410fb_stop_lcd(); - /* sleep before disabling the clock, we need to ensure - * the LCD DMA engine is not going to get back on the bus - * before the clock goes off again (bjd) */ + /* sleep before disabling the clock, we need to ensure + * the LCD DMA engine is not going to get back on the bus + * before the clock goes off again (bjd) */ - msleep(1); - clk_disable(info->clk); - } + msleep(1); + clk_disable(info->clk); return 0; } -static int s3c2410fb_resume(struct device *dev, u32 level) +static int s3c2410fb_resume(struct device *dev) { struct fb_info *fbinfo = dev_get_drvdata(dev); struct s3c2410fb_info *info = fbinfo->par; - if (level == RESUME_ENABLE) { - clk_enable(info->clk); - msleep(1); + clk_enable(info->clk); + msleep(1); - s3c2410fb_init_registers(info); - - } + s3c2410fb_init_registers(info); return 0; } diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 8000890e4271..78e5f194b0df 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -1309,21 +1309,19 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, * Power management hooks. Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */ -static int sa1100fb_suspend(struct device *dev, pm_message_t state, u32 level) +static int sa1100fb_suspend(struct device *dev, pm_message_t state) { struct sa1100fb_info *fbi = dev_get_drvdata(dev); - if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) - set_ctrlr_state(fbi, C_DISABLE_PM); + set_ctrlr_state(fbi, C_DISABLE_PM); return 0; } -static int sa1100fb_resume(struct device *dev, u32 level) +static int sa1100fb_resume(struct device *dev) { struct sa1100fb_info *fbi = dev_get_drvdata(dev); - if (level == RESUME_ENABLE) - set_ctrlr_state(fbi, C_ENABLE_PM); + set_ctrlr_state(fbi, C_ENABLE_PM); return 0; } #else diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 0030c071da8f..752bf88906a9 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -438,36 +438,34 @@ static void w100fb_restore_vidmem(struct w100fb_par *par) } } -static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level) +static int w100fb_suspend(struct device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - struct w100_tg_info *tg = par->mach->tg; + struct fb_info *info = dev_get_drvdata(dev); + struct w100fb_par *par=info->par; + struct w100_tg_info *tg = par->mach->tg; + + w100fb_save_vidmem(par); + if(tg && tg->suspend) + tg->suspend(par); + w100_suspend(W100_SUSPEND_ALL); + par->blanked = 1; - w100fb_save_vidmem(par); - if(tg && tg->suspend) - tg->suspend(par); - w100_suspend(W100_SUSPEND_ALL); - par->blanked = 1; - } return 0; } -static int w100fb_resume(struct device *dev, uint32_t level) +static int w100fb_resume(struct device *dev) { - if (level == RESUME_POWER_ON) { - struct fb_info *info = dev_get_drvdata(dev); - struct w100fb_par *par=info->par; - struct w100_tg_info *tg = par->mach->tg; + struct fb_info *info = dev_get_drvdata(dev); + struct w100fb_par *par=info->par; + struct w100_tg_info *tg = par->mach->tg; + + w100_hw_init(par); + w100fb_activate_var(par); + w100fb_restore_vidmem(par); + if(tg && tg->resume) + tg->resume(par); + par->blanked = 0; - w100_hw_init(par); - w100fb_activate_var(par); - w100fb_restore_vidmem(par); - if(tg && tg->resume) - tg->resume(par); - par->blanked = 0; - } return 0; } #else diff --git a/include/linux/device.h b/include/linux/device.h index 10ab7807f8ea..a9e72ac3fb9f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -28,19 +28,6 @@ #define BUS_ID_SIZE KOBJ_NAME_LEN -enum { - SUSPEND_NOTIFY, - SUSPEND_SAVE_STATE, - SUSPEND_DISABLE, - SUSPEND_POWER_DOWN, -}; - -enum { - RESUME_POWER_ON, - RESUME_RESTORE_STATE, - RESUME_ENABLE, -}; - struct device; struct device_driver; struct class; @@ -115,8 +102,8 @@ struct device_driver { int (*probe) (struct device * dev); int (*remove) (struct device * dev); void (*shutdown) (struct device * dev); - int (*suspend) (struct device * dev, pm_message_t state, u32 level); - int (*resume) (struct device * dev, u32 level); + int (*suspend) (struct device * dev, pm_message_t state); + int (*resume) (struct device * dev); }; diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 38b20efc9c0b..877bb00d3295 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -275,23 +275,23 @@ static int pxa2xx_ac97_do_resume(snd_card_t *card) return 0; } -static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level) +static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state) { snd_card_t *card = dev_get_drvdata(_dev); int ret = 0; - if (card && level == SUSPEND_DISABLE) + if (card) ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND); return ret; } -static int pxa2xx_ac97_resume(struct device *_dev, u32 level) +static int pxa2xx_ac97_resume(struct device *_dev) { snd_card_t *card = dev_get_drvdata(_dev); int ret = 0; - if (card && level == RESUME_ENABLE) + if (card) ret = pxa2xx_ac97_do_resume(card); return ret; diff --git a/sound/core/init.c b/sound/core/init.c index c72a79115cca..59202de1d2ce 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -676,8 +676,8 @@ struct snd_generic_device { #define SND_GENERIC_NAME "snd_generic" #ifdef CONFIG_PM -static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level); -static int snd_generic_resume(struct device *dev, u32 level); +static int snd_generic_suspend(struct device *dev, pm_message_t state); +static int snd_generic_resume(struct device *dev); #endif /* initialized in sound.c */ @@ -818,13 +818,10 @@ int snd_card_set_pm_callback(snd_card_t *card, #ifdef CONFIG_SND_GENERIC_DRIVER /* suspend/resume callbacks for snd_generic platform device */ -static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level) +static int snd_generic_suspend(struct device *dev, pm_message_t state) { snd_card_t *card; - if (level != SUSPEND_DISABLE) - return 0; - card = get_snd_generic_card(dev); if (card->power_state == SNDRV_CTL_POWER_D3hot) return 0; @@ -834,13 +831,10 @@ static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level return 0; } -static int snd_generic_resume(struct device *dev, u32 level) +static int snd_generic_resume(struct device *dev) { snd_card_t *card; - if (level != RESUME_ENABLE) - return 0; - card = get_snd_generic_card(dev); if (card->power_state == SNDRV_CTL_POWER_D0) return 0; diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c index becbc420ba41..ec70fadde7d9 100644 --- a/sound/pci/ac97/ac97_bus.c +++ b/sound/pci/ac97/ac97_bus.c @@ -31,7 +31,8 @@ static int ac97_bus_suspend(struct device *dev, pm_message_t state) int ret = 0; if (dev->driver && dev->driver->suspend) - ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN); + ret = dev->driver->suspend(dev, state); + return ret; } @@ -40,7 +41,8 @@ static int ac97_bus_resume(struct device *dev) int ret = 0; if (dev->driver && dev->driver->resume) - ret = dev->driver->resume(dev, RESUME_POWER_ON); + ret = dev->driver->resume(dev); + return ret; } From c41455fbac06712992da491844449775cf9a8c80 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 Oct 2005 11:59:14 -0700 Subject: [PATCH 0640/1940] [PATCH] kernel-doc: drivers/base fixes driver/base: add missing function parameters; eliminate all warnings. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- drivers/base/driver.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index ac4b5fdd95f5..8615b42b517a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -407,11 +407,11 @@ static struct device * next_device(struct klist_iter * i) /** * device_for_each_child - device child iterator. - * @dev: parent struct device. + * @parent: parent struct device. * @data: data for the callback. * @fn: function to be called for each device. * - * Iterate over @dev's child devices, and call @fn for each, + * Iterate over @parent's child devices, and call @fn for each, * passing it @data. * * We check the return of @fn each time. If it returns anything diff --git a/drivers/base/driver.c b/drivers/base/driver.c index ef3fe513e398..161f3a390d90 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i) /** * driver_for_each_device - Iterator for devices bound to a driver. * @drv: Driver we're iterating. + * @start: Device to begin with * @data: Data to pass to the callback. * @fn: Function to call for each device. * @@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); /** * driver_find_device - device iterator for locating a particular device. - * @driver: The device's driver + * @drv: The device's driver * @start: Device to begin with * @data: Data to pass to match function * @match: Callback function to check device From 1a222bca26ca691e83be1b08f5e96ae96d0d8cae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Oct 2005 16:45:34 +0200 Subject: [PATCH 0641/1940] [PATCH] Fix documentation of driver suspend/resume callbacks Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-model/driver.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 7c26bfae4ba0..59806c9761f7 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -14,8 +14,8 @@ struct device_driver { int (*probe) (struct device * dev); int (*remove) (struct device * dev); - int (*suspend) (struct device * dev, pm_message_t state, u32 level); - int (*resume) (struct device * dev, u32 level); + int (*suspend) (struct device * dev, pm_message_t state); + int (*resume) (struct device * dev); }; @@ -194,11 +194,11 @@ device; i.e. anything in the device's driver_data field. If the device is still present, it should quiesce the device and place it into a supported low-power state. - int (*suspend) (struct device * dev, pm_message_t state, u32 level); + int (*suspend) (struct device * dev, pm_message_t state); suspend is called to put the device in a low power state. - int (*resume) (struct device * dev, u32 level); + int (*resume) (struct device * dev); Resume is used to bring a device back from a low power state. From fa90c54f6d27664cc67691f9e52d9165e0c25ca7 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 27 Oct 2005 11:10:08 -0700 Subject: [PATCH 0642/1940] [SCSI] qla2xxx: Update license. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- Documentation/scsi/LICENSE.qla2xxx | 45 +++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/ql2100.c | 9 +++--- drivers/scsi/qla2xxx/ql2100_fw.c | 22 ++++---------- drivers/scsi/qla2xxx/ql2200.c | 9 +++--- drivers/scsi/qla2xxx/ql2200_fw.c | 22 ++++---------- drivers/scsi/qla2xxx/ql2300.c | 9 +++--- drivers/scsi/qla2xxx/ql2300_fw.c | 22 ++++---------- drivers/scsi/qla2xxx/ql2322.c | 7 ++--- drivers/scsi/qla2xxx/ql2322_fw.c | 22 ++++---------- drivers/scsi/qla2xxx/ql6312.c | 7 ++--- drivers/scsi/qla2xxx/ql6312_fw.c | 22 ++++---------- drivers/scsi/qla2xxx/qla_attr.c | 18 ++---------- drivers/scsi/qla2xxx/qla_dbg.c | 18 ++---------- drivers/scsi/qla2xxx/qla_dbg.h | 23 ++++----------- drivers/scsi/qla2xxx/qla_def.h | 25 ++++------------ drivers/scsi/qla2xxx/qla_fw.h | 26 ++++------------- drivers/scsi/qla2xxx/qla_gbl.h | 28 ++++-------------- drivers/scsi/qla2xxx/qla_gs.c | 18 ++---------- drivers/scsi/qla2xxx/qla_init.c | 18 ++---------- drivers/scsi/qla2xxx/qla_inline.h | 19 ++---------- drivers/scsi/qla2xxx/qla_iocb.c | 23 ++++----------- drivers/scsi/qla2xxx/qla_isr.c | 18 ++---------- drivers/scsi/qla2xxx/qla_mbx.c | 18 ++---------- drivers/scsi/qla2xxx/qla_os.c | 18 ++---------- drivers/scsi/qla2xxx/qla_rscn.c | 18 ++---------- drivers/scsi/qla2xxx/qla_settings.h | 22 ++++---------- drivers/scsi/qla2xxx/qla_sup.c | 23 ++++----------- drivers/scsi/qla2xxx/qla_version.h | 22 ++++---------- 28 files changed, 158 insertions(+), 393 deletions(-) create mode 100644 Documentation/scsi/LICENSE.qla2xxx diff --git a/Documentation/scsi/LICENSE.qla2xxx b/Documentation/scsi/LICENSE.qla2xxx new file mode 100644 index 000000000000..9e15b4f9cd28 --- /dev/null +++ b/Documentation/scsi/LICENSE.qla2xxx @@ -0,0 +1,45 @@ +Copyright (c) 2003-2005 QLogic Corporation +QLogic Linux Fibre Channel HBA Driver + +This program includes a device driver for Linux 2.6 that may be +distributed with QLogic hardware specific firmware binary file. +You may modify and redistribute the device driver code under the +GNU General Public License as published by the Free Software +Foundation (version 2 or a later version). + +You may redistribute the hardware specific firmware binary file +under the following terms: + + 1. Redistribution of source code (only if applicable), + must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistribution in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + + 3. The name of QLogic Corporation may not be used to + endorse or promote products derived from this software + without specific prior written permission + +REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE, +THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT +CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR +OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT, +TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN +ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN +COMBINATION WITH THIS PROGRAM. diff --git a/drivers/scsi/qla2xxx/ql2100.c b/drivers/scsi/qla2xxx/ql2100.c index 058733d98d6b..f5db2235e432 100644 --- a/drivers/scsi/qla2xxx/ql2100.c +++ b/drivers/scsi/qla2xxx/ql2100.c @@ -1,11 +1,10 @@ /* - * QLogic ISP2100 device driver for Linux 2.6.x - * Copyright (C) 2003 Christoph Hellwig. - * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com) + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation * - * Released under GPL v2. + * See LICENSE.qla2xxx for copyright and licensing details. */ - #include #include #include diff --git a/drivers/scsi/qla2xxx/ql2100_fw.c b/drivers/scsi/qla2xxx/ql2100_fw.c index 18376b883845..56006162da40 100644 --- a/drivers/scsi/qla2xxx/ql2100_fw.c +++ b/drivers/scsi/qla2xxx/ql2100_fw.c @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - *************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Firmware Version 1.19.25 (13:12 Dec 10, 2003) diff --git a/drivers/scsi/qla2xxx/ql2200.c b/drivers/scsi/qla2xxx/ql2200.c index 5b5ee73744b2..0eef72dc8da0 100644 --- a/drivers/scsi/qla2xxx/ql2200.c +++ b/drivers/scsi/qla2xxx/ql2200.c @@ -1,11 +1,10 @@ /* - * QLogic ISP2200 device driver for Linux 2.6.x - * Copyright (C) 2003 Christoph Hellwig. - * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com) + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation * - * Released under GPL v2. + * See LICENSE.qla2xxx for copyright and licensing details. */ - #include #include #include diff --git a/drivers/scsi/qla2xxx/ql2200_fw.c b/drivers/scsi/qla2xxx/ql2200_fw.c index 6f103fd8b657..ac07e18abb1d 100644 --- a/drivers/scsi/qla2xxx/ql2200_fw.c +++ b/drivers/scsi/qla2xxx/ql2200_fw.c @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - *************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Firmware Version 2.02.08 (17:06 Mar 22, 2005) diff --git a/drivers/scsi/qla2xxx/ql2300.c b/drivers/scsi/qla2xxx/ql2300.c index 22371c864f0c..fd2f4b795a8a 100644 --- a/drivers/scsi/qla2xxx/ql2300.c +++ b/drivers/scsi/qla2xxx/ql2300.c @@ -1,11 +1,10 @@ /* - * QLogic ISP2300 device driver for Linux 2.6.x - * Copyright (C) 2003 Christoph Hellwig. - * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com) + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation * - * Released under GPL v2. + * See LICENSE.qla2xxx for copyright and licensing details. */ - #include #include #include diff --git a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c index 4917ec509720..1896a0eea7e5 100644 --- a/drivers/scsi/qla2xxx/ql2300_fw.c +++ b/drivers/scsi/qla2xxx/ql2300_fw.c @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Firmware Version 3.03.15 (10:03 May 26, 2005) diff --git a/drivers/scsi/qla2xxx/ql2322.c b/drivers/scsi/qla2xxx/ql2322.c index bfe918a4a2cf..c88a22c0d93a 100644 --- a/drivers/scsi/qla2xxx/ql2322.c +++ b/drivers/scsi/qla2xxx/ql2322.c @@ -1,10 +1,9 @@ /* - * QLogic ISP2322 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com) + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * Released under GPL v2. + * See LICENSE.qla2xxx for copyright and licensing details. */ - #include #include #include diff --git a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c index 2645d6239b74..97b5578ae9b1 100644 --- a/drivers/scsi/qla2xxx/ql2322_fw.c +++ b/drivers/scsi/qla2xxx/ql2322_fw.c @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Firmware Version 3.03.15 (10:09 May 26, 2005) diff --git a/drivers/scsi/qla2xxx/ql6312.c b/drivers/scsi/qla2xxx/ql6312.c index e75882dd4cf6..de55397f6f4c 100644 --- a/drivers/scsi/qla2xxx/ql6312.c +++ b/drivers/scsi/qla2xxx/ql6312.c @@ -1,10 +1,9 @@ /* - * QLogic ISP6312 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com) + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * Released under GPL v2. + * See LICENSE.qla2xxx for copyright and licensing details. */ - #include #include #include diff --git a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c index 357980942d73..1f8744ad9cde 100644 --- a/drivers/scsi/qla2xxx/ql6312_fw.c +++ b/drivers/scsi/qla2xxx/ql6312_fw.c @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Firmware Version 3.03.15 (10:00 May 26, 2005) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 47c9ecfc1d8f..49696faa24fa 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 9791496fa788..89793c1c06b1 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 9684e7a91fa9..935a59a8c054 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -1,22 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ - + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Driver debug definitions. */ diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 522bb2d3f084..fc3234c3625b 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1,22 +1,9 @@ -/******************************************************************************** -* QLOGIC LINUX SOFTWARE -* -* QLogic ISP2x00 device driver for Linux 2.6.x -* Copyright (C) 2003-2005 QLogic Corporation -* (www.qlogic.com) -* -* 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. -** -******************************************************************************/ - +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ #ifndef __QLA_DEF_H #define __QLA_DEF_H diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 63f611904a6c..9fb562aa4acc 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1,23 +1,9 @@ - -/******************************************************************************** -* QLOGIC LINUX SOFTWARE -* -* QLogic ISP2x00 device driver for Linux 2.6.x -* Copyright (C) 2003-2005 QLogic Corporation -* (www.qlogic.com) -* -* 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. -** -******************************************************************************/ - +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ #ifndef __QLA_FW_H #define __QLA_FW_H diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index c26b74da4054..fedcb0d3fc72 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -1,25 +1,9 @@ -/******************************************************************************** -* QLOGIC LINUX SOFTWARE -* -* QLogic ISP2x00 device driver for Linux 2.6.x -* Copyright (C) 2003-2005 QLogic Corporation -* (www.qlogic.com) -* -* 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. -* -****************************************************************************** -* Global include file. -******************************************************************************/ - - +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ #ifndef __QLA_GBL_H #define __QLA_GBL_H diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index e7b138c2e339..cd6f7c3cfe68 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9e36fbd9245a..ce7e712ebe8d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index b9ff85b03a5f..ecc3741a452e 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -1,23 +1,10 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ - static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *); /* * qla2x00_debounce_register diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index b58ee79177bc..17f5697feba6 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1,22 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ - + * See LICENSE.qla2xxx for copyright and licensing details. + */ #include "qla_def.h" #include diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index cf6c6ce0b42b..09afc0f06bd4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 13e1c9047079..ad3cacb9192d 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 77054d7692c4..74a26a4a69b6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index 7534efcc8918..cb40d61e82d5 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index d85fbbed79cc..363205c0e84f 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Compile time Options: * 0 - Disable and 1 - Enable diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index c14abf743b7c..4bec0b4fb6b4 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -1,22 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ - + * See LICENSE.qla2xxx for copyright and licensing details. + */ #include "qla_def.h" #include diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index eae7d6edd531..0d5472f2f59b 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -1,21 +1,9 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * 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. - * - ******************************************************************************/ + * See LICENSE.qla2xxx for copyright and licensing details. + */ /* * Driver version */ From d578a4258bf674ef86b16bf29267fb302125aaee Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Oct 2005 12:14:43 -0500 Subject: [PATCH 0643/1940] [SCSI] qla2xxx: Resync with latest released ISP23xx/63xx firmware -- 3.03.18. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/ql2300_fw.c | 13839 +++++++++++++-------------- drivers/scsi/qla2xxx/ql2322_fw.c | 14485 +++++++++++++++-------------- drivers/scsi/qla2xxx/ql6312_fw.c | 13866 +++++++++++++-------------- 3 files changed, 21118 insertions(+), 21072 deletions(-) diff --git a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c index 1896a0eea7e5..dfc9cd58dc06 100644 --- a/drivers/scsi/qla2xxx/ql2300_fw.c +++ b/drivers/scsi/qla2xxx/ql2300_fw.c @@ -6,7 +6,7 @@ */ /* - * Firmware Version 3.03.15 (10:03 May 26, 2005) + * Firmware Version 3.03.18 (12:09 Sep 20, 2005) */ #ifdef UNIQUE_FW_NAME @@ -16,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw2300ipx_version_str[] = {3, 3,15}; +unsigned char fw2300ipx_version_str[] = {3, 3,18}; #else -unsigned char firmware_version[] = {3, 3,15}; +unsigned char firmware_version[] = {3, 3,18}; #endif #ifdef UNIQUE_FW_NAME -#define fw2300ipx_VERSION_STRING "3.03.15" +#define fw2300ipx_VERSION_STRING "3.03.18" #else -#define FW_VERSION_STRING "3.03.15" +#define FW_VERSION_STRING "3.03.18" #endif #ifdef UNIQUE_FW_NAME @@ -38,12 +38,12 @@ unsigned short fw2300ipx_code01[] = { #else unsigned short risc_code01[] = { #endif - 0x0470, 0x0000, 0x0000, 0xed9d, 0x0000, 0x0003, 0x0003, 0x000f, + 0x0470, 0x0000, 0x0000, 0xee08, 0x0000, 0x0003, 0x0003, 0x0012, 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, @@ -52,7 +52,7 @@ unsigned short risc_code01[] = { 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78, - 0x7883, 0x0004, 0x2089, 0x2db5, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x7883, 0x0004, 0x2089, 0x2dac, 0x2051, 0x1800, 0x2a70, 0x20e1, 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e52, 0x2029, 0x4d00, 0x2031, 0xffff, 0x2039, 0x4cd0, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, @@ -66,159 +66,159 @@ unsigned short risc_code01[] = { 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f26, 0x080c, - 0x612f, 0x080c, 0xb07d, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c, - 0x1bf8, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34b1, 0x080c, - 0x785c, 0x080c, 0x6ab0, 0x080c, 0x892f, 0x080c, 0x8610, 0x080c, - 0x24d0, 0x080c, 0x91db, 0x080c, 0x7f2c, 0x080c, 0x2309, 0x080c, - 0x243d, 0x080c, 0x24c5, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, + 0x6135, 0x080c, 0xb097, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c, + 0x1c00, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34ac, 0x080c, + 0x7862, 0x080c, 0x6ab6, 0x080c, 0x8935, 0x080c, 0x8616, 0x080c, + 0x24d8, 0x080c, 0x91e1, 0x080c, 0x7f32, 0x080c, 0x2311, 0x080c, + 0x2445, 0x080c, 0x24cd, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, - 0x1178, 0x080c, 0x4ca8, 0x080c, 0x34d8, 0x080c, 0x78cd, 0x080c, - 0x704e, 0x080c, 0x8a16, 0x080c, 0x863c, 0x080c, 0x2cff, 0x0c58, + 0x1178, 0x080c, 0x4cae, 0x080c, 0x34d3, 0x080c, 0x78d3, 0x080c, + 0x7054, 0x080c, 0x8a1c, 0x080c, 0x8642, 0x080c, 0x2cf6, 0x0c58, 0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae0, 0x0942, 0x0ba0, 0x0d56, 0x0d56, 0x0d56, 0x080c, 0x0dc5, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x080c, 0x0e94, - 0x080c, 0x7563, 0x0150, 0x080c, 0x7586, 0x15a0, 0x2079, 0x0100, - 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x748f, 0x7000, + 0x080c, 0x7569, 0x0150, 0x080c, 0x758c, 0x15a0, 0x2079, 0x0100, + 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x7495, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x7098, 0x9086, 0x0029, 0x1904, - 0x0ab3, 0x080c, 0x85f9, 0x080c, 0x85eb, 0x2001, 0x0161, 0x2003, + 0x0ab3, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f, - 0x7a2a, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, - 0x87dd, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x8030, 0x901e, - 0x7396, 0x04d0, 0x080c, 0x5837, 0x2079, 0x0100, 0x7844, 0x9005, - 0x1904, 0x0ab3, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x73de, - 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x2001, 0x0265, + 0x7a2a, 0x2011, 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, + 0x87e3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x8030, 0x901e, + 0x7396, 0x04d0, 0x080c, 0x583d, 0x2079, 0x0100, 0x7844, 0x9005, + 0x1904, 0x0ab3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x73e4, + 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, - 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, - 0x080c, 0x60d7, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28, - 0x080c, 0x756b, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, - 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001, - 0x080c, 0x2ba4, 0x080c, 0x4be3, 0x7248, 0xc284, 0x724a, 0x2001, - 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7c4, 0x2011, - 0x0004, 0x080c, 0xce4f, 0x080c, 0x693a, 0x080c, 0x7563, 0x1120, - 0x080c, 0x2be8, 0x02e0, 0x0400, 0x080c, 0x60de, 0x0140, 0x7097, - 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a04, 0x0804, 0x0ab3, 0x080c, - 0x57cd, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, - 0x080c, 0x57d1, 0xd0d4, 0x1118, 0x080c, 0x2be8, 0x1270, 0x2011, - 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d1, 0xd0d4, 0x1db8, + 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, + 0x080c, 0x60dd, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28, + 0x080c, 0x7571, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, + 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a9, 0x2003, 0x0001, + 0x080c, 0x2b9b, 0x080c, 0x4be9, 0x7248, 0xc284, 0x724a, 0x2001, + 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7de, 0x2011, + 0x0004, 0x080c, 0xce66, 0x080c, 0x6940, 0x080c, 0x7569, 0x1120, + 0x080c, 0x2bdf, 0x02e0, 0x0400, 0x080c, 0x60e4, 0x0140, 0x7097, + 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a0a, 0x0804, 0x0ab3, 0x080c, + 0x57d3, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, + 0x080c, 0x57d7, 0xd0d4, 0x1118, 0x080c, 0x2bdf, 0x1270, 0x2011, + 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d7, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, - 0xc0bd, 0x2012, 0x080c, 0x6a84, 0x1128, 0xd0a4, 0x0118, 0x2204, - 0xc0fd, 0x2012, 0x080c, 0x6a4a, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, - 0x00a8, 0x707f, 0x0000, 0x080c, 0x7563, 0x1130, 0x70b0, 0x9005, - 0x1168, 0x080c, 0xd292, 0x0050, 0x080c, 0xd292, 0x70dc, 0xd09c, - 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60b4, 0x70e7, 0x0000, - 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2bf0, 0x0228, 0x2011, - 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7563, 0x1178, - 0x9016, 0x0016, 0x080c, 0x29a1, 0x2019, 0x196e, 0x211a, 0x001e, + 0xc0bd, 0x2012, 0x080c, 0x6a8a, 0x1128, 0xd0a4, 0x0118, 0x2204, + 0xc0fd, 0x2012, 0x080c, 0x6a50, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, + 0x00a8, 0x707f, 0x0000, 0x080c, 0x7569, 0x1130, 0x70b0, 0x9005, + 0x1168, 0x080c, 0xd2a9, 0x0050, 0x080c, 0xd2a9, 0x70dc, 0xd09c, + 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60ba, 0x70e7, 0x0000, + 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2be7, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7569, 0x1178, + 0x9016, 0x0016, 0x080c, 0x29ac, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196e, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, - 0xc295, 0x72de, 0x080c, 0x7563, 0x0118, 0x9296, 0x0004, 0x0548, - 0x2011, 0x0001, 0x080c, 0xce4f, 0x70ab, 0x0000, 0x70af, 0xffff, + 0xc295, 0x72de, 0x080c, 0x7569, 0x0118, 0x9296, 0x0004, 0x0548, + 0x2011, 0x0001, 0x080c, 0xce66, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, - 0x0003, 0x782a, 0x00fe, 0x080c, 0x3022, 0x2011, 0x0005, 0x080c, - 0xa8d3, 0x080c, 0x98e7, 0x080c, 0x7563, 0x0148, 0x00c6, 0x2061, - 0x0100, 0x0016, 0x080c, 0x29a1, 0x61e2, 0x001e, 0x00ce, 0x012e, + 0x0003, 0x782a, 0x00fe, 0x080c, 0x3019, 0x2011, 0x0005, 0x080c, + 0xa8ed, 0x080c, 0x98ed, 0x080c, 0x7569, 0x0148, 0x00c6, 0x2061, + 0x0100, 0x0016, 0x080c, 0x29ac, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, - 0x00fe, 0x2011, 0x0005, 0x080c, 0xa8d3, 0x080c, 0x98e7, 0x080c, - 0x7563, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29a1, + 0x00fe, 0x2011, 0x0005, 0x080c, 0xa8ed, 0x080c, 0x98ed, 0x080c, + 0x7569, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29ac, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, - 0x080c, 0x7563, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, - 0x080c, 0x7563, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, + 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, + 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, - 0x090c, 0x3347, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080, + 0x090c, 0x3342, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, - 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3022, 0x080c, - 0x98e7, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, + 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3019, 0x080c, + 0x98ed, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, 0xd084, 0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, - 0xd08c, 0x0508, 0x080c, 0x33aa, 0x11d0, 0x70e0, 0x9086, 0xffff, - 0x01b0, 0x080c, 0x31b7, 0x080c, 0x98e7, 0x70dc, 0xd094, 0x1904, - 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd548, 0x0110, 0x2011, 0x0003, - 0x901e, 0x080c, 0x31f1, 0x080c, 0x98e7, 0x0804, 0x0b9d, 0x70e4, + 0xd08c, 0x0508, 0x080c, 0x33a5, 0x11d0, 0x70e0, 0x9086, 0xffff, + 0x01b0, 0x080c, 0x31b2, 0x080c, 0x98ed, 0x70dc, 0xd094, 0x1904, + 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd561, 0x0110, 0x2011, 0x0003, + 0x901e, 0x080c, 0x31ec, 0x080c, 0x98ed, 0x0804, 0x0b9d, 0x70e4, 0x9005, 0x1904, 0x0b9d, 0x70a8, 0x9005, 0x1904, 0x0b9d, 0x70dc, - 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a4a, 0x1904, - 0x0b9d, 0x080c, 0x6a9d, 0x1904, 0x0b9d, 0x080c, 0x6a84, 0x01c0, - 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6717, + 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a50, 0x1904, + 0x0b9d, 0x080c, 0x6aa3, 0x1904, 0x0b9d, 0x080c, 0x6a8a, 0x01c0, + 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b3d, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b9d, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b5, 0x080c, 0x0f96, 0x2011, 0x19cf, 0x080c, 0x0f96, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e76, 0x9006, - 0x080c, 0x2832, 0x080c, 0x33aa, 0x0118, 0x080c, 0x4d80, 0x0050, - 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4d9a, - 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x7586, 0x0150, - 0x080c, 0x7563, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, + 0x080c, 0x283d, 0x080c, 0x33a5, 0x0118, 0x080c, 0x4d86, 0x0050, + 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4da0, + 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x758c, 0x0150, + 0x080c, 0x7569, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, - 0x1120, 0x2011, 0x0000, 0x080c, 0xa8d3, 0x2011, 0x0000, 0x080c, - 0xa8dd, 0x080c, 0x98e7, 0x080c, 0x9a09, 0x012e, 0x00be, 0x0005, + 0x1120, 0x2011, 0x0000, 0x080c, 0xa8ed, 0x2011, 0x0000, 0x080c, + 0xa8f7, 0x080c, 0x98ed, 0x080c, 0x9a0f, 0x012e, 0x00be, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, - 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x609d, + 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, - 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a8, 0x2004, 0x9005, - 0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bd3, - 0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73, 0x1138, - 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068, 0x080c, - 0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, - 0x080c, 0x29cd, 0x0804, 0x0d0d, 0x080c, 0x7574, 0x0148, 0x080c, - 0x7586, 0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0, - 0x080c, 0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0058, 0x080c, - 0x7563, 0x0140, 0x2009, 0x00f8, 0x080c, 0x609d, 0x7843, 0x0090, + 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a9, 0x2004, 0x9005, + 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bca, + 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a, 0x1138, + 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068, 0x080c, + 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, + 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x080c, 0x757a, 0x0148, 0x080c, + 0x758c, 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0, + 0x080c, 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0058, 0x080c, + 0x7569, 0x0140, 0x2009, 0x00f8, 0x080c, 0x60a3, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, - 0x7563, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c, - 0x0070, 0x7824, 0x080c, 0x757d, 0x0118, 0xd0ac, 0x1904, 0x0d12, + 0x7569, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c, + 0x0070, 0x7824, 0x080c, 0x7583, 0x0118, 0xd0ac, 0x1904, 0x0d12, 0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d12, 0x2001, - 0x0001, 0x080c, 0x2832, 0x0804, 0x0d25, 0x2001, 0x19a8, 0x2004, - 0x9005, 0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c, - 0x2bd3, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73, - 0x1138, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068, - 0x080c, 0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, - 0x0020, 0x080c, 0x29cd, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040, - 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c83, + 0x0001, 0x080c, 0x283d, 0x0804, 0x0d25, 0x2001, 0x19a9, 0x2004, + 0x9005, 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c, + 0x2bca, 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a, + 0x1138, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068, + 0x080c, 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, + 0x0020, 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040, + 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c7a, 0x9085, 0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c66, - 0x080c, 0x87bd, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084, - 0xdfbf, 0x7852, 0x793a, 0x080c, 0x7574, 0x0148, 0x080c, 0x7586, - 0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0, 0x080c, - 0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0020, 0x2009, 0x00f8, - 0x080c, 0x609d, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850, - 0x9085, 0x1400, 0x7852, 0x080c, 0x7563, 0x0120, 0x7843, 0x0090, - 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87bd, - 0x7820, 0xd09c, 0x1588, 0x080c, 0x7563, 0x0904, 0x0cf2, 0x7824, - 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x7586, 0x1530, 0x0046, 0x2021, - 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c83, + 0x080c, 0x87c3, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084, + 0xdfbf, 0x7852, 0x793a, 0x080c, 0x757a, 0x0148, 0x080c, 0x758c, + 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0, 0x080c, + 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0020, 0x2009, 0x00f8, + 0x080c, 0x60a3, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850, + 0x9085, 0x1400, 0x7852, 0x080c, 0x7569, 0x0120, 0x7843, 0x0090, + 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87c3, + 0x7820, 0xd09c, 0x1588, 0x080c, 0x7569, 0x0904, 0x0cf2, 0x7824, + 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x758c, 0x1530, 0x0046, 0x2021, + 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c7a, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d33, 0x8421, - 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87bd, 0x080c, 0x7852, 0x080c, - 0x7848, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda, - 0x080c, 0x87bd, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, + 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87c3, 0x080c, 0x7858, 0x080c, + 0x784e, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda, + 0x080c, 0x87c3, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, - 0x080c, 0x2c64, 0x7924, 0x080c, 0x2c83, 0xd19c, 0x0110, 0x080c, - 0x2ba4, 0x00d8, 0x080c, 0x7574, 0x1140, 0x94a2, 0x03e8, 0x1128, - 0x080c, 0x753b, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, - 0x2c83, 0x7824, 0x080c, 0x757d, 0x0110, 0xd0ac, 0x1158, 0x9084, + 0x080c, 0x2c5b, 0x7924, 0x080c, 0x2c7a, 0xd19c, 0x0110, 0x080c, + 0x2b9b, 0x00d8, 0x080c, 0x757a, 0x1140, 0x94a2, 0x03e8, 0x1128, + 0x080c, 0x7541, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, + 0x2c7a, 0x7824, 0x080c, 0x7583, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800, 0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, - 0x2832, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, + 0x283d, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, - 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a8, 0x2003, + 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a9, 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, - 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87bd, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87c3, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, - 0x0001, 0x1110, 0x080c, 0x34d8, 0x00ee, 0x0005, 0x0005, 0x2a70, - 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f, + 0x0001, 0x1110, 0x080c, 0x34d3, 0x00ee, 0x0005, 0x0005, 0x2a70, + 0x2061, 0x19ad, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0012, 0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, - 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd292, 0x70eb, + 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd2a9, 0x70eb, 0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, - 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6717, + 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x671d, 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, @@ -239,7 +239,7 @@ unsigned short risc_code01[] = { 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, - 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57dc, 0x1108, 0x0099, + 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57e2, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, @@ -251,8 +251,8 @@ unsigned short risc_code01[] = { 0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x080c, 0x0efb, 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0efb, - 0x1148, 0x080c, 0x2c7b, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, - 0x8282, 0x0040, 0x080c, 0x2c7b, 0x1118, 0x2011, 0xcdc5, 0x0010, + 0x1148, 0x080c, 0x2c72, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, + 0x8282, 0x0040, 0x080c, 0x2c72, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f00, 0x002e, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e8, 0x1110, 0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5, @@ -305,7 +305,7 @@ unsigned short risc_code01[] = { 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x012e, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, @@ -370,15 +370,15 @@ unsigned short risc_code01[] = { 0x1117, 0x0005, 0x00de, 0x009e, 0x080c, 0x1117, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4002, 0x080c, 0x6dbe, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, + 0x4002, 0x080c, 0x6dc4, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1040, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, - 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dbe, + 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dc4, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, - 0x080c, 0xb0e7, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, + 0x080c, 0xb101, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1040, 0x7007, 0x0000, 0x080c, 0x1117, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930, @@ -387,12 +387,12 @@ unsigned short risc_code01[] = { 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e, - 0x080c, 0x8c54, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, - 0x080c, 0x8ab9, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007, + 0x080c, 0x8c5a, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, + 0x080c, 0x8abf, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, 0x1a66, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b, - 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e5, - 0x2061, 0xedc4, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, + 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e8, + 0x2061, 0xee29, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04, 0x1312, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0120, 0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a67, 0x2003, 0x0000, @@ -400,15 +400,15 @@ unsigned short risc_code01[] = { 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a8a, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a8a, 0x602f, 0x1cd0, - 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20e8, - 0x2001, 0x33b1, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004, + 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20f0, + 0x2001, 0x33ac, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004, 0xd0c4, 0x1128, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f, - 0x33b1, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3b1, 0x604f, 0x193e, + 0x33ac, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3ac, 0x604f, 0x193e, 0x2001, 0x1929, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, - 0xce2d, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, + 0xce44, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, - 0xb166, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, + 0xb180, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0dbe, 0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0dc5, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005, 0x13cf, 0x13cf, 0x13e6, 0x13eb, 0x13ef, @@ -417,17 +417,17 @@ unsigned short risc_code01[] = { 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13f6, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13d3, 0x13d1, 0x080c, 0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7f, 0x2104, - 0x8000, 0x200a, 0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x2009, - 0x0048, 0x2060, 0x080c, 0xb166, 0x012e, 0x0005, 0x7004, 0xc085, + 0x8000, 0x200a, 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x2009, + 0x0048, 0x2060, 0x080c, 0xb180, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x159b, 0x080c, 0x16fb, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, - 0x0048, 0x080c, 0xb166, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, + 0x0048, 0x080c, 0xb180, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x15a0, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, - 0x009e, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x080c, 0x159b, + 0x009e, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005, 0x080c, 0x159b, 0x080c, 0x0dc5, 0x080c, 0x159b, 0x080c, 0x14ea, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x149b, 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, @@ -443,14 +443,14 @@ unsigned short risc_code01[] = { 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0dc5, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, - 0x080c, 0x8000, 0x080c, 0x1b02, 0x080c, 0xce3f, 0x0158, 0xa9ac, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x080c, 0xce56, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, - 0xc0bd, 0xa882, 0x080c, 0xca5e, 0x0005, 0x6020, 0x9086, 0x0009, - 0x1128, 0x2009, 0x004c, 0x080c, 0xb166, 0x0048, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd22b, 0x2029, + 0xc0bd, 0xa882, 0x080c, 0xca71, 0x0005, 0x6020, 0x9086, 0x0009, + 0x1128, 0x2009, 0x004c, 0x080c, 0xb180, 0x0048, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd242, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x7dbc, 0x080c, 0xed6d, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005, - 0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803, + 0x7dbc, 0x080c, 0xedd2, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x1611, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, @@ -469,9 +469,9 @@ unsigned short risc_code01[] = { 0x020d, 0x2003, 0x0020, 0x080c, 0x1322, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x16de, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, - 0x0053, 0x080c, 0xb166, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, - 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fa5, - 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ba8, 0x0cd0, 0x0005, + 0x0053, 0x080c, 0xb180, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, + 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fab, + 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8bae, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x1611, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x14ea, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, @@ -481,7 +481,7 @@ unsigned short risc_code01[] = { 0x810c, 0x080c, 0x1603, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, - 0x080c, 0x8000, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, @@ -498,16 +498,16 @@ unsigned short risc_code01[] = { 0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026, 0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, - 0x92e7, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e, + 0x92ed, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x01d0, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x00f6, 0x0016, 0x2009, 0x1a83, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, - 0x1f0c, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, + 0x1f14, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x163a, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284, 0x0030, 0x0508, 0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f8, 0x2004, 0x9005, 0x01b8, 0x2001, 0x1a6a, 0x2004, 0x9086, 0x0000, 0x0188, - 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa57b, + 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa595, 0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804, 0x163a, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x080c, 0x1633, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, @@ -516,39 +516,39 @@ unsigned short risc_code01[] = { 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a80, 0x2404, 0x8000, - 0x0208, 0x2022, 0x080c, 0x8000, 0x080c, 0x1b02, 0x9006, 0x00ee, + 0x0208, 0x2022, 0x080c, 0x8006, 0x080c, 0x1b02, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x175d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x175d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x175d, 0x9c06, 0x15f0, 0x0126, - 0x2091, 0x2600, 0x080c, 0x7f47, 0x012e, 0x7358, 0x745c, 0x6014, + 0x2091, 0x2600, 0x080c, 0x7f4d, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x190c, 0xd206, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, + 0xd0bc, 0x190c, 0xd21d, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, - 0x080c, 0x2108, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130, + 0x080c, 0x2110, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x15a0, 0x0005, 0x080c, 0x0dc5, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, - 0x000f, 0x9088, 0x20e8, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794, + 0x000f, 0x9088, 0x20f0, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794, 0x1794, 0x1798, 0x17e3, 0x1794, 0x17b8, 0x178d, 0x17f9, 0x1794, 0x1794, 0x179d, 0x18ef, 0x17cc, 0x17c2, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x17f9, 0x9085, 0x0001, 0x0804, 0x18e5, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1809, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x1874, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, - 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9173, + 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9179, 0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18cd, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1809, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1874, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164, - 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20e8, 0x2065, 0xa888, 0xd19c, + 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20f0, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1874, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, - 0x20e8, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874, + 0x20f0, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1874, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, @@ -581,7 +581,7 @@ unsigned short risc_code01[] = { 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x1794, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, - 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20e3, 0xa813, 0x20e3, + 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20eb, 0xa813, 0x20eb, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0dc5, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, @@ -590,7 +590,7 @@ unsigned short risc_code01[] = { 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa80e, - 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2015, 0x82ff, + 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2015, 0x82ff, 0x090c, 0x0dc5, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a78, 0x19a5, 0x19a5, 0x1a78, 0x19a5, 0x1a72, 0x1a78, 0x19a5, 0x1a15, 0x1a15, 0x1a15, @@ -628,36 +628,37 @@ unsigned short risc_code01[] = { 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, - 0x000e, 0x1130, 0x080c, 0x20a0, 0x1904, 0x194e, 0x900e, 0x0050, + 0x000e, 0x1130, 0x080c, 0x20a8, 0x1904, 0x194e, 0x900e, 0x0050, 0x080c, 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, - 0x080c, 0x20a0, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, + 0x080c, 0x20a8, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, - 0x080c, 0xb166, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, + 0x080c, 0xb180, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, - 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb166, 0x0005, 0x0126, + 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb180, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce, - 0x2001, 0x0038, 0x080c, 0x1b8a, 0x7930, 0x9186, 0x0040, 0x0160, + 0x2001, 0x0038, 0x080c, 0x1b92, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0, - 0x8631, 0x1d40, 0x080c, 0x1b99, 0x000e, 0x6022, 0x012e, 0x0005, - 0x080c, 0x1b86, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, + 0x8631, 0x1d40, 0x080c, 0x1ba1, 0x000e, 0x6022, 0x012e, 0x0005, + 0x080c, 0x1b8e, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, - 0x0004, 0x00fe, 0x080c, 0x7563, 0x1188, 0x2001, 0x0138, 0x2003, + 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0dc5, 0x7aac, 0xd2ac, + 0x1dd0, 0x00fe, 0x080c, 0x7569, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, - 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7610, 0x0479, 0x0039, + 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7616, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, - 0x2071, 0x0200, 0x080c, 0x2c8f, 0x2009, 0x003c, 0x080c, 0x242a, + 0x2071, 0x0200, 0x080c, 0x2c86, 0x2009, 0x003c, 0x080c, 0x2432, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, - 0x080c, 0x85eb, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, + 0x080c, 0x85f1, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1322, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, - 0x080c, 0x7563, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, + 0x080c, 0x7569, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, @@ -666,39 +667,39 @@ unsigned short risc_code01[] = { 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, - 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bf7, 0x2001, 0x001e, + 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bff, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, - 0x0030, 0x080c, 0x1b90, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6, + 0x0030, 0x080c, 0x1b98, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x012e, 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, - 0x1c99, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c15, 0x1c84, 0x1c2c, - 0x1c2e, 0x1c2c, 0x1c6c, 0x1c4c, 0x1c3b, 0x918c, 0x00ff, 0x9186, - 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0x9006, 0xa842, - 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20e3, 0x0804, 0x1c95, - 0x9186, 0x0048, 0x0904, 0x1c84, 0x080c, 0x0dc5, 0x9184, 0x00ff, - 0x9086, 0x0013, 0x0904, 0x1c84, 0x9184, 0x00ff, 0x9086, 0x001b, - 0x0904, 0x1c84, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890, + 0x1ca1, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c1d, 0x1c8c, 0x1c34, + 0x1c36, 0x1c34, 0x1c74, 0x1c54, 0x1c43, 0x918c, 0x00ff, 0x9186, + 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0x9006, 0xa842, + 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20eb, 0x0804, 0x1c9d, + 0x9186, 0x0048, 0x0904, 0x1c8c, 0x080c, 0x0dc5, 0x9184, 0x00ff, + 0x9086, 0x0013, 0x0904, 0x1c8c, 0x9184, 0x00ff, 0x9086, 0x001b, + 0x0904, 0x1c8c, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, - 0xa84a, 0xa988, 0x0804, 0x1c8c, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890, 0xa842, + 0xa84a, 0xa988, 0x0804, 0x1c94, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, - 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20e8, + 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, - 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa804, 0xa85a, 0x2040, - 0xa064, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa988, - 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, + 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa804, 0xa85a, 0x2040, + 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa988, + 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, - 0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, + 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, - 0x1f0c, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d00, + 0x1f14, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d08, 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, @@ -711,47 +712,47 @@ unsigned short risc_code01[] = { 0x001e, 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009, 0x0306, 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, - 0x2108, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, + 0x2110, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076, - 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ebf, - 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ebe, - 0x9705, 0x0904, 0x1ebe, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, - 0x2d00, 0x0002, 0x1e43, 0x1d82, 0x1d82, 0x1e43, 0x1e43, 0x1e20, - 0x1e43, 0x1d82, 0x1e27, 0x1dd1, 0x1dd1, 0x1e43, 0x1e43, 0x1e43, - 0x1e1a, 0x1dd1, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, - 0xdd9c, 0x0904, 0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, - 0x9082, 0x001b, 0x0002, 0x1d6e, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, - 0x1d6c, 0x1d72, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d76, - 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d7a, 0x1d6c, 0x1d6c, - 0x1d6c, 0x1d6c, 0x1d6c, 0x1d7e, 0x080c, 0x0dc5, 0xa774, 0xa678, - 0x0804, 0x1e50, 0xa78c, 0xa690, 0x0804, 0x1e50, 0xa7a4, 0xa6a8, - 0x0804, 0x1e50, 0xa7bc, 0xa6c0, 0x0804, 0x1e50, 0xa7d4, 0xa6d8, - 0x0804, 0x1e50, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x1da5, 0x1da5, 0x1da7, 0x1da5, 0x1da5, 0x1da5, - 0x1dad, 0x1da5, 0x1da5, 0x1da5, 0x1db3, 0x1da5, 0x1da5, 0x1da5, - 0x1db9, 0x1da5, 0x1da5, 0x1da5, 0x1dbf, 0x1da5, 0x1da5, 0x1da5, - 0x1dc5, 0x1da5, 0x1da5, 0x1da5, 0x1dcb, 0x080c, 0x0dc5, 0xa574, - 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa38c, - 0xa290, 0x0804, 0x1e50, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, - 0x1e50, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4, - 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e50, 0xa5c4, 0xa4c8, 0xa3cc, - 0xa2d0, 0x0804, 0x1e50, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, - 0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, - 0x0002, 0x1df4, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1dfc, - 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1e04, 0x1df2, 0x1df2, - 0x1df2, 0x1df2, 0x1df2, 0x1e0c, 0x1df2, 0x1df2, 0x1df2, 0x1df2, - 0x1df2, 0x1e13, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, - 0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa78c, 0xa690, - 0xa394, 0xa298, 0x0804, 0x1e50, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, - 0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, + 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ec7, + 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ec6, + 0x9705, 0x0904, 0x1ec6, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, + 0x2d00, 0x0002, 0x1e4b, 0x1d8a, 0x1d8a, 0x1e4b, 0x1e4b, 0x1e28, + 0x1e4b, 0x1d8a, 0x1e2f, 0x1dd9, 0x1dd9, 0x1e4b, 0x1e4b, 0x1e4b, + 0x1e22, 0x1dd9, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, + 0xdd9c, 0x0904, 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x1d76, 0x1d74, 0x1d74, 0x1d74, 0x1d74, + 0x1d74, 0x1d7a, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d7e, + 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d82, 0x1d74, 0x1d74, + 0x1d74, 0x1d74, 0x1d74, 0x1d86, 0x080c, 0x0dc5, 0xa774, 0xa678, + 0x0804, 0x1e58, 0xa78c, 0xa690, 0x0804, 0x1e58, 0xa7a4, 0xa6a8, + 0x0804, 0x1e58, 0xa7bc, 0xa6c0, 0x0804, 0x1e58, 0xa7d4, 0xa6d8, + 0x0804, 0x1e58, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x1dad, 0x1dad, 0x1daf, 0x1dad, 0x1dad, 0x1dad, + 0x1db5, 0x1dad, 0x1dad, 0x1dad, 0x1dbb, 0x1dad, 0x1dad, 0x1dad, + 0x1dc1, 0x1dad, 0x1dad, 0x1dad, 0x1dc7, 0x1dad, 0x1dad, 0x1dad, + 0x1dcd, 0x1dad, 0x1dad, 0x1dad, 0x1dd3, 0x080c, 0x0dc5, 0xa574, + 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa38c, + 0xa290, 0x0804, 0x1e58, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, + 0x1e58, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4, + 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e58, 0xa5c4, 0xa4c8, 0xa3cc, + 0xa2d0, 0x0804, 0x1e58, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, + 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x1dfc, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e04, + 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e0c, 0x1dfa, 0x1dfa, + 0x1dfa, 0x1dfa, 0x1dfa, 0x1e14, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, + 0x1dfa, 0x1e1b, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, + 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa78c, 0xa690, + 0xa394, 0xa298, 0x0804, 0x1e58, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, + 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518, - 0x080c, 0x20a0, 0x1904, 0x1d1d, 0x900e, 0x0804, 0x1ebf, 0xab64, + 0x080c, 0x20a8, 0x1904, 0x1d25, 0x900e, 0x0804, 0x1ec7, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, - 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd1, 0xab9c, 0x9016, + 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd9, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904, - 0x1dd1, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013, - 0x0904, 0x1d82, 0x9186, 0x001b, 0x0904, 0x1dd1, 0x080c, 0x0dc5, + 0x1dd9, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013, + 0x0904, 0x1d8a, 0x9186, 0x001b, 0x0904, 0x1dd9, 0x080c, 0x0dc5, 0x2009, 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306, 0x2134, 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031, 0x1000, 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278, @@ -760,135 +761,135 @@ unsigned short risc_code01[] = { 0x0000, 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, - 0x7010, 0x9201, 0x7012, 0x080c, 0x20a0, 0x0448, 0xd6b4, 0x0110, + 0x7010, 0x9201, 0x7012, 0x080c, 0x20a8, 0x0448, 0xd6b4, 0x0110, 0x200b, 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, 0x7124, 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, - 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e61, 0x200b, 0x4040, 0x2009, - 0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e61, 0x200a, 0x0804, 0x1e61, - 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e61, 0x9006, 0x002e, + 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e69, 0x200b, 0x4040, 0x2009, + 0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e69, 0x200a, 0x0804, 0x1e69, + 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e69, 0x9006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, - 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0118, - 0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d10, + 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce56, 0x0118, + 0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d18, 0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, - 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca5e, 0x00ce, + 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca71, 0x00ce, 0x2001, 0x19f8, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, - 0x242a, 0x080c, 0xaa3f, 0x2011, 0x0000, 0x080c, 0xa8dd, 0x080c, - 0x9a09, 0x002e, 0x0804, 0x2050, 0x0126, 0x2091, 0x2400, 0xa858, - 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ec8, - 0x7000, 0x0002, 0x2050, 0x1f1e, 0x1f9e, 0x204e, 0x8001, 0x7002, - 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f6b, 0x080c, - 0x1d17, 0x0904, 0x2050, 0x080c, 0x1d17, 0x0804, 0x2050, 0x782b, + 0x2432, 0x080c, 0xaa59, 0x2011, 0x0000, 0x080c, 0xa8f7, 0x080c, + 0x9a0f, 0x002e, 0x0804, 0x2058, 0x0126, 0x2091, 0x2400, 0xa858, + 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ed0, + 0x7000, 0x0002, 0x2058, 0x1f26, 0x1fa6, 0x2056, 0x8001, 0x7002, + 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f73, 0x080c, + 0x1d1f, 0x0904, 0x2058, 0x080c, 0x1d1f, 0x0804, 0x2058, 0x782b, 0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518, 0xa87c, 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x0016, 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101, 0xa832, 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e, - 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20bb, + 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20c3, 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, - 0x0000, 0x0804, 0x2050, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, + 0x0000, 0x0804, 0x2058, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, - 0x7003, 0x0000, 0x080c, 0x1d10, 0x0804, 0x2050, 0x8001, 0x7002, + 0x7003, 0x0000, 0x080c, 0x1d18, 0x0804, 0x2058, 0x8001, 0x7002, 0x7024, 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, - 0x1f11, 0xd19c, 0x1904, 0x204c, 0x8aff, 0x0904, 0x2050, 0x080c, - 0x1d17, 0x0804, 0x2050, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, - 0x20bb, 0xdd9c, 0x1904, 0x200b, 0x2c05, 0x908a, 0x0036, 0x1a0c, - 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fdf, 0x1fdf, 0x1fe1, 0x1fdf, - 0x1fdf, 0x1fdf, 0x1fe7, 0x1fdf, 0x1fdf, 0x1fdf, 0x1fed, 0x1fdf, - 0x1fdf, 0x1fdf, 0x1ff3, 0x1fdf, 0x1fdf, 0x1fdf, 0x1ff9, 0x1fdf, - 0x1fdf, 0x1fdf, 0x1fff, 0x1fdf, 0x1fdf, 0x1fdf, 0x2005, 0x080c, - 0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f40, 0xa08c, - 0x931a, 0xa090, 0x9213, 0x0804, 0x1f40, 0xa09c, 0x931a, 0xa0a0, - 0x9213, 0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, - 0x1f40, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f40, 0xa0cc, - 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a, 0xa0e0, - 0x9213, 0x0804, 0x1f40, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, - 0x9082, 0x001b, 0x0002, 0x202e, 0x202c, 0x202c, 0x202c, 0x202c, - 0x202c, 0x2034, 0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x203a, - 0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x2040, 0x202c, 0x202c, - 0x202c, 0x202c, 0x202c, 0x2046, 0x080c, 0x0dc5, 0xa07c, 0x931a, - 0xa080, 0x9213, 0x0804, 0x1f40, 0xa094, 0x931a, 0xa098, 0x9213, - 0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f40, - 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a, - 0xa0e0, 0x9213, 0x0804, 0x1f40, 0x0804, 0x1f3c, 0x080c, 0x0dc5, + 0x1f19, 0xd19c, 0x1904, 0x2054, 0x8aff, 0x0904, 0x2058, 0x080c, + 0x1d1f, 0x0804, 0x2058, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, + 0x20c3, 0xdd9c, 0x1904, 0x2013, 0x2c05, 0x908a, 0x0036, 0x1a0c, + 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fe7, 0x1fe7, 0x1fe9, 0x1fe7, + 0x1fe7, 0x1fe7, 0x1fef, 0x1fe7, 0x1fe7, 0x1fe7, 0x1ff5, 0x1fe7, + 0x1fe7, 0x1fe7, 0x1ffb, 0x1fe7, 0x1fe7, 0x1fe7, 0x2001, 0x1fe7, + 0x1fe7, 0x1fe7, 0x2007, 0x1fe7, 0x1fe7, 0x1fe7, 0x200d, 0x080c, + 0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f48, 0xa08c, + 0x931a, 0xa090, 0x9213, 0x0804, 0x1f48, 0xa09c, 0x931a, 0xa0a0, + 0x9213, 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, + 0x1f48, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f48, 0xa0cc, + 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a, 0xa0e0, + 0x9213, 0x0804, 0x1f48, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x2036, 0x2034, 0x2034, 0x2034, 0x2034, + 0x2034, 0x203c, 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2042, + 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2048, 0x2034, 0x2034, + 0x2034, 0x2034, 0x2034, 0x204e, 0x080c, 0x0dc5, 0xa07c, 0x931a, + 0xa080, 0x9213, 0x0804, 0x1f48, 0xa094, 0x931a, 0xa098, 0x9213, + 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f48, + 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a, + 0xa0e0, 0x9213, 0x0804, 0x1f48, 0x0804, 0x1f44, 0x080c, 0x0dc5, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9086, - 0x0000, 0x0904, 0x209b, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, + 0x0000, 0x0904, 0x20a3, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, - 0x080c, 0xedb6, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, - 0x0016, 0x2009, 0x0040, 0x080c, 0x242a, 0x001e, 0x2001, 0x020c, + 0x080c, 0xee1b, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, + 0x0016, 0x2009, 0x0040, 0x080c, 0x2432, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, - 0x1120, 0x2009, 0x0040, 0x080c, 0x242a, 0x782c, 0xd0fc, 0x09a8, - 0x080c, 0x1f0c, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, - 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x242a, 0x782b, - 0x0002, 0x7003, 0x0000, 0x080c, 0x1d10, 0x00ee, 0x00fe, 0x0005, + 0x1120, 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x09a8, + 0x080c, 0x1f14, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, + 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b, + 0x0002, 0x7003, 0x0000, 0x080c, 0x1d18, 0x00ee, 0x00fe, 0x0005, 0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, - 0x000f, 0x9080, 0x20e8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51, + 0x000f, 0x9080, 0x20f0, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51, 0x0005, 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61, 0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, - 0x20f8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d, + 0x2100, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, - 0x0000, 0x20db, 0x20d7, 0x20db, 0x20db, 0x20e5, 0x0000, 0x20db, - 0x20e2, 0x20e2, 0x20df, 0x20e2, 0x20e2, 0x0000, 0x20e5, 0x20e2, - 0x0000, 0x20dd, 0x20dd, 0x0000, 0x20dd, 0x20e5, 0x0000, 0x20dd, - 0x20e3, 0x20e3, 0x20e3, 0x0000, 0x20e3, 0x0000, 0x20e5, 0x20e3, + 0x0000, 0x20e3, 0x20df, 0x20e3, 0x20e3, 0x20ed, 0x0000, 0x20e3, + 0x20ea, 0x20ea, 0x20e7, 0x20ea, 0x20ea, 0x0000, 0x20ed, 0x20ea, + 0x0000, 0x20e5, 0x20e5, 0x0000, 0x20e5, 0x20ed, 0x0000, 0x20e5, + 0x20eb, 0x20eb, 0x20eb, 0x0000, 0x20eb, 0x0000, 0x20ed, 0x20eb, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, - 0x22e7, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, - 0x0008, 0x1118, 0x2061, 0x20e3, 0x00d0, 0x9de0, 0x20e8, 0x9d86, + 0x22ef, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, + 0x0008, 0x1118, 0x2061, 0x20eb, 0x00d0, 0x9de0, 0x20f0, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, - 0x0804, 0x22e7, 0xa004, 0x9045, 0x0904, 0x22e7, 0x08d8, 0x2c05, - 0x9005, 0x0904, 0x21cf, 0xdd9c, 0x1904, 0x218b, 0x908a, 0x0036, - 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2160, 0x2160, 0x2162, - 0x2160, 0x2160, 0x2160, 0x2168, 0x2160, 0x2160, 0x2160, 0x216e, - 0x2160, 0x2160, 0x2160, 0x2174, 0x2160, 0x2160, 0x2160, 0x217a, - 0x2160, 0x2160, 0x2160, 0x2180, 0x2160, 0x2160, 0x2160, 0x2186, - 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21c5, - 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21c5, 0xa09c, 0x9422, - 0xa0a0, 0x931b, 0x0804, 0x21c5, 0xa0ac, 0x9422, 0xa0b0, 0x931b, - 0x0804, 0x21c5, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21c5, - 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21c5, 0xa0dc, 0x9422, + 0x0804, 0x22ef, 0xa004, 0x9045, 0x0904, 0x22ef, 0x08d8, 0x2c05, + 0x9005, 0x0904, 0x21d7, 0xdd9c, 0x1904, 0x2193, 0x908a, 0x0036, + 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2168, 0x2168, 0x216a, + 0x2168, 0x2168, 0x2168, 0x2170, 0x2168, 0x2168, 0x2168, 0x2176, + 0x2168, 0x2168, 0x2168, 0x217c, 0x2168, 0x2168, 0x2168, 0x2182, + 0x2168, 0x2168, 0x2168, 0x2188, 0x2168, 0x2168, 0x2168, 0x218e, + 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21cd, + 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21cd, 0xa09c, 0x9422, + 0xa0a0, 0x931b, 0x0804, 0x21cd, 0xa0ac, 0x9422, 0xa0b0, 0x931b, + 0x0804, 0x21cd, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21cd, + 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21cd, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x21ad, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab, - 0x21b2, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21b7, 0x21ab, - 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21bc, 0x21ab, 0x21ab, 0x21ab, - 0x21ab, 0x21ab, 0x21c1, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, + 0x001b, 0x0002, 0x21b5, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3, + 0x21ba, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21bf, 0x21b3, + 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21c4, 0x21b3, 0x21b3, 0x21b3, + 0x21b3, 0x21b3, 0x21c9, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, - 0x0160, 0x8a51, 0x0904, 0x22e7, 0x8c60, 0x0804, 0x2137, 0xa004, - 0x9045, 0x0904, 0x22e7, 0x0804, 0x2112, 0x8a51, 0x0904, 0x22e7, - 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22e7, - 0xa064, 0x90ec, 0x000f, 0x9de0, 0x20e8, 0x2c05, 0x2060, 0xa880, - 0xc0fc, 0xa882, 0x0804, 0x22dc, 0x2c05, 0x8422, 0x8420, 0x831a, - 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2279, 0x9082, - 0x001b, 0x0002, 0x2215, 0x2215, 0x2217, 0x2215, 0x2215, 0x2215, - 0x2225, 0x2215, 0x2215, 0x2215, 0x2233, 0x2215, 0x2215, 0x2215, - 0x2241, 0x2215, 0x2215, 0x2215, 0x224f, 0x2215, 0x2215, 0x2215, - 0x225d, 0x2215, 0x2215, 0x2215, 0x226b, 0x080c, 0x0dc5, 0xa17c, + 0x0160, 0x8a51, 0x0904, 0x22ef, 0x8c60, 0x0804, 0x213f, 0xa004, + 0x9045, 0x0904, 0x22ef, 0x0804, 0x211a, 0x8a51, 0x0904, 0x22ef, + 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22ef, + 0xa064, 0x90ec, 0x000f, 0x9de0, 0x20f0, 0x2c05, 0x2060, 0xa880, + 0xc0fc, 0xa882, 0x0804, 0x22e4, 0x2c05, 0x8422, 0x8420, 0x831a, + 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2281, 0x9082, + 0x001b, 0x0002, 0x221d, 0x221d, 0x221f, 0x221d, 0x221d, 0x221d, + 0x222d, 0x221d, 0x221d, 0x221d, 0x223b, 0x221d, 0x221d, 0x221d, + 0x2249, 0x221d, 0x221d, 0x221d, 0x2257, 0x221d, 0x221d, 0x221d, + 0x2265, 0x221d, 0x221d, 0x221d, 0x2273, 0x080c, 0x0dc5, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074, - 0x9420, 0xa078, 0x9319, 0x0804, 0x22d7, 0xa18c, 0x2400, 0x9122, + 0x9420, 0xa078, 0x9319, 0x0804, 0x22df, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, - 0x9319, 0x0804, 0x22d7, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, + 0x9319, 0x0804, 0x22df, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, - 0x22d7, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, - 0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22d7, 0xa1bc, + 0x22df, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, + 0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22df, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, - 0x9420, 0xa0b8, 0x9319, 0x0804, 0x22d7, 0xa1cc, 0x2400, 0x9122, + 0x9420, 0xa0b8, 0x9319, 0x0804, 0x22df, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8, - 0x9319, 0x0804, 0x22d7, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, + 0x9319, 0x0804, 0x22df, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, - 0x22d7, 0x9082, 0x001b, 0x0002, 0x2297, 0x2295, 0x2295, 0x2295, - 0x2295, 0x2295, 0x22a4, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295, - 0x22b1, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295, 0x22be, 0x2295, - 0x2295, 0x2295, 0x2295, 0x2295, 0x22cb, 0x080c, 0x0dc5, 0xa17c, + 0x22df, 0x9082, 0x001b, 0x0002, 0x229f, 0x229d, 0x229d, 0x229d, + 0x229d, 0x229d, 0x22ac, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d, + 0x22b9, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d, 0x22c6, 0x229d, + 0x229d, 0x229d, 0x229d, 0x229d, 0x22d3, 0x080c, 0x0dc5, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319, @@ -900,25 +901,25 @@ unsigned short risc_code01[] = { 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, - 0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2308, 0x1f0c, - 0x2308, 0x22fe, 0x2301, 0x2304, 0x2301, 0x2304, 0x080c, 0x1f0c, - 0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f0c, 0x080c, 0x11b2, + 0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2310, 0x1f14, + 0x2310, 0x2306, 0x2309, 0x230c, 0x2309, 0x230c, 0x080c, 0x1f14, + 0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f14, 0x080c, 0x11b2, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, - 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2427, 0x7900, 0xd1dc, - 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x234f, - 0x2347, 0x7f47, 0x2347, 0x2349, 0x2349, 0x2349, 0x2349, 0x7f2d, - 0x2347, 0x234b, 0x2347, 0x2349, 0x2347, 0x2349, 0x2347, 0x080c, - 0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f2d, 0x080c, 0x7f47, 0x0005, - 0x0006, 0x0016, 0x0026, 0x080c, 0xedb6, 0x7930, 0x9184, 0x0003, + 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x242f, 0x7900, 0xd1dc, + 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2357, + 0x234f, 0x7f4d, 0x234f, 0x2351, 0x2351, 0x2351, 0x2351, 0x7f33, + 0x234f, 0x2353, 0x234f, 0x2351, 0x234f, 0x2351, 0x234f, 0x080c, + 0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f33, 0x080c, 0x7f4d, 0x0005, + 0x0006, 0x0016, 0x0026, 0x080c, 0xee1b, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001, 0x19f8, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f8, 0x2064, - 0x080c, 0xca5e, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x242a, + 0x080c, 0xca71, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2432, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, - 0x080c, 0x7563, 0x1138, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c, - 0x748f, 0x0010, 0x080c, 0x5fe0, 0x080c, 0x7ff6, 0x0041, 0x0018, + 0x080c, 0x7569, 0x1138, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, + 0x7495, 0x0010, 0x080c, 0x5fe6, 0x080c, 0x7ffc, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, @@ -942,20 +943,20 @@ unsigned short risc_code01[] = { 0x080c, 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, - 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c89, - 0x080c, 0x2ba4, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, + 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c80, + 0x080c, 0x2b9b, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x199e, 0x2011, 0x199f, - 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2be8, 0x1238, 0x939d, + 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2bdf, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, - 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bd3, 0x9006, - 0x080c, 0x2bb6, 0x20a9, 0x0012, 0x1d04, 0x247c, 0x2091, 0x6000, - 0x1f04, 0x247c, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, - 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28c2, - 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28d2, 0x60e7, 0x0000, + 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bca, 0x9006, + 0x080c, 0x2bad, 0x20a9, 0x0012, 0x1d04, 0x2484, 0x2091, 0x6000, + 0x1f04, 0x2484, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, + 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28cd, + 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28dd, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, - 0x0018, 0x60bf, 0x0000, 0x1f04, 0x24a9, 0x60bb, 0x0000, 0x60bf, + 0x0018, 0x60bf, 0x0000, 0x1f04, 0x24b1, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, @@ -967,4969 +968,4970 @@ unsigned short risc_code01[] = { 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, - 0x0d30, 0x0c58, 0x252c, 0x2512, 0x2515, 0x2518, 0x251d, 0x251f, - 0x2523, 0x2527, 0x080c, 0x9218, 0x00b8, 0x080c, 0x92e7, 0x00a0, - 0x080c, 0x92e7, 0x080c, 0x9218, 0x0078, 0x0099, 0x0068, 0x080c, - 0x9218, 0x0079, 0x0048, 0x080c, 0x92e7, 0x0059, 0x0028, 0x080c, - 0x92e7, 0x080c, 0x9218, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, + 0x0d30, 0x0c58, 0x2534, 0x251a, 0x251d, 0x2520, 0x2525, 0x2527, + 0x252b, 0x252f, 0x080c, 0x921e, 0x00b8, 0x080c, 0x92ed, 0x00a0, + 0x080c, 0x92ed, 0x080c, 0x921e, 0x0078, 0x0099, 0x0068, 0x080c, + 0x921e, 0x0079, 0x0048, 0x080c, 0x92ed, 0x0059, 0x0028, 0x080c, + 0x92ed, 0x080c, 0x921e, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, - 0x279a, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7563, 0x0904, 0x2587, - 0x080c, 0xd548, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, - 0x9084, 0x1800, 0x0550, 0x080c, 0x7586, 0x0118, 0x080c, 0x7574, - 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd548, 0x0168, - 0x080c, 0x7586, 0x1150, 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, - 0x1800, 0x080c, 0x73de, 0x0804, 0x279d, 0x70a4, 0x9005, 0x1150, - 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75b7, 0x00de, - 0x1904, 0x279d, 0x080c, 0x7852, 0x0428, 0x080c, 0x7586, 0x1590, - 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7852, 0x080c, - 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0804, 0x279a, 0xd1ac, + 0x27a5, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7569, 0x0904, 0x258f, + 0x080c, 0xd561, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, + 0x9084, 0x1800, 0x0550, 0x080c, 0x758c, 0x0118, 0x080c, 0x757a, + 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd561, 0x0168, + 0x080c, 0x758c, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001, 0x6027, + 0x1800, 0x080c, 0x73e4, 0x0804, 0x27a8, 0x70a4, 0x9005, 0x1150, + 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75bd, 0x00de, + 0x1904, 0x27a8, 0x080c, 0x7858, 0x0428, 0x080c, 0x758c, 0x1590, + 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7858, 0x080c, + 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0804, 0x27a5, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, - 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x7735, - 0x0804, 0x279a, 0x080c, 0x784d, 0x0048, 0x2001, 0x197e, 0x2003, - 0x0002, 0x0020, 0x080c, 0x7698, 0x0804, 0x279a, 0x080c, 0x77d0, - 0x0804, 0x279a, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27f7, - 0xd2b4, 0x1904, 0x280a, 0x0000, 0xd1ac, 0x0904, 0x26af, 0x0036, - 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7563, 0x11c0, 0x6027, - 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1158, 0x080c, - 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x003e, 0x002e, 0x000e, - 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x753b, 0x0016, + 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x773b, + 0x0804, 0x27a5, 0x080c, 0x7853, 0x0048, 0x2001, 0x197e, 0x2003, + 0x0002, 0x0020, 0x080c, 0x769e, 0x0804, 0x27a5, 0x080c, 0x77d6, + 0x0804, 0x27a5, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x2802, + 0xd2b4, 0x1904, 0x2815, 0x0000, 0xd1ac, 0x0904, 0x26ba, 0x0036, + 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7569, 0x11c0, 0x6027, + 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1158, 0x080c, + 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x003e, 0x002e, 0x000e, + 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7541, 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, - 0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, - 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, - 0x4be3, 0x003e, 0x080c, 0xd541, 0x1904, 0x268c, 0x9196, 0xff00, - 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, - 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33a5, 0x0128, 0xc18d, - 0x7132, 0x080c, 0x6a84, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, - 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, - 0x0904, 0x268c, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, - 0xd1ac, 0x1904, 0x268c, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, - 0x8013, 0x080c, 0x4be3, 0x003e, 0x0804, 0x268c, 0x7038, 0xd08c, - 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x268c, 0xc1ad, - 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be3, 0x003e, - 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, - 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x2019, - 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe8b0, 0x00ce, 0x9484, - 0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, - 0x9006, 0x2009, 0x000e, 0x080c, 0xe940, 0x001e, 0x0016, 0x2009, - 0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x00a8, 0x0156, - 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1140, 0x7030, - 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x613b, 0x8108, - 0x1f04, 0x267c, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xb058, - 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, - 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, - 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, - 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, - 0x0904, 0x279a, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2737, 0x080c, - 0x8789, 0x080c, 0xa4fd, 0x6027, 0x0004, 0x00f6, 0x2019, 0x19f2, - 0x2304, 0x907d, 0x0904, 0x2706, 0x7804, 0x9086, 0x0032, 0x15f0, - 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c, 0x685e, - 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, - 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, 0x2d6b, - 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, 0x2c64, - 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2d5b, - 0x9006, 0x080c, 0x2d5b, 0x080c, 0x97db, 0x080c, 0x98e7, 0x7814, - 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xb0e7, 0x009e, 0x00ee, - 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6, - 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, - 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028, 0x080c, 0xd548, 0x0120, - 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000, - 0x602a, 0x00ce, 0x080c, 0xa4d9, 0x0804, 0x2799, 0x2061, 0x0100, - 0x62c0, 0x080c, 0xaede, 0x2019, 0x19f2, 0x2304, 0x9065, 0x0120, - 0x2009, 0x0027, 0x080c, 0xb166, 0x00ce, 0x0804, 0x2799, 0xd2bc, - 0x0904, 0x2780, 0x080c, 0x8796, 0x6014, 0x9084, 0x1984, 0x9085, - 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, - 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x00de, 0x00c6, 0x2061, - 0x19e9, 0x6044, 0x080c, 0xd548, 0x0120, 0x909a, 0x0003, 0x1658, - 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, 0x603c, 0x00ce, - 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9080, 0x0008, - 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984, 0x918d, - 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009, - 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, 0x0016, 0x6116, 0x00c8, - 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa85d, - 0x003e, 0x2019, 0x19f8, 0x2304, 0x9065, 0x0150, 0x2009, 0x004f, - 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, 0x080c, 0xb166, - 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27f2, 0x7038, 0xd0ac, 0x1538, - 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2d95, 0x20a9, 0x0028, - 0xa001, 0x1f04, 0x27a8, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, - 0x0366, 0x1d04, 0x27b1, 0x080c, 0x87bd, 0x6020, 0xd09c, 0x1130, - 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0, 0x080c, 0x2c4b, - 0x1f04, 0x27b1, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, - 0x6028, 0xc09c, 0x602a, 0x080c, 0xb058, 0x60e3, 0x0000, 0x080c, - 0xed95, 0x080c, 0xedb0, 0x080c, 0x57d1, 0xd0fc, 0x1138, 0x080c, - 0xd541, 0x1120, 0x9085, 0x0001, 0x080c, 0x75a7, 0x9006, 0x080c, - 0x2d5b, 0x2009, 0x0002, 0x080c, 0x2c89, 0x00e6, 0x2071, 0x1800, - 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, 0x6027, 0x0008, 0x080c, - 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0016, - 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0904, 0x25b4, 0x0016, - 0x2009, 0x2803, 0x00d0, 0x2001, 0x188b, 0x200c, 0xc184, 0x2102, - 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, - 0x0904, 0x25b4, 0x0016, 0x2009, 0x2816, 0x0038, 0x2001, 0x188b, - 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a, - 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043, - 0x0001, 0x080c, 0x2c83, 0x6027, 0x0080, 0x6017, 0x0000, 0x6043, - 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, - 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, - 0x0904, 0x2881, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2c89, - 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, - 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x4be3, 0x0448, - 0x2001, 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, - 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, - 0x080c, 0x4be3, 0x080c, 0x0ea3, 0x080c, 0x57d1, 0xd0fc, 0x1188, - 0x080c, 0xd541, 0x1170, 0x00c6, 0x080c, 0x291d, 0x080c, 0xa7c4, - 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x3216, - 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, - 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, - 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, - 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294, - 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214, - 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, - 0x826b, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c, - 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b1, 0x200d, 0x918c, - 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003, - 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x28cd, - 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, - 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, - 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, - 0xf58c, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28e2, 0x002e, 0x00de, - 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, - 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, - 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112, - 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, - 0x2001, 0x0404, 0x680e, 0x1f04, 0x2912, 0x680f, 0x0000, 0x000e, - 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x57cd, 0xd0c4, - 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, - 0x080c, 0xe940, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, - 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2989, 0x080c, 0x2be8, 0x0660, - 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e, - 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420, - 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, - 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, - 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548, - 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300, - 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018, - 0x080c, 0x91ab, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, - 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, - 0x7563, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe, - 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, - 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, - 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, 0x001e, 0x000e, 0x012e, - 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, - 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c, - 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007, - 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007, - 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018, - 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016, - 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c, - 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, - 0x29e7, 0x2a05, 0x2a29, 0x2a2b, 0x2a54, 0x2a56, 0x2a58, 0x2001, - 0x0001, 0x080c, 0x2832, 0x080c, 0x2c46, 0x2001, 0x1993, 0x2003, - 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, - 0x080c, 0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, - 0x2011, 0x2a59, 0x080c, 0x879b, 0x0005, 0x2009, 0x1996, 0x200b, - 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003, - 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x2bb6, - 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2c04, 0x2001, 0x1991, - 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a59, 0x080c, 0x879b, - 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, - 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, - 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x2001, - 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, - 0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, - 0x2a59, 0x080c, 0x879b, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x0dc5, - 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, - 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a, - 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, - 0x002e, 0x001e, 0x000e, 0x0005, 0x2a7b, 0x2a9b, 0x2adb, 0x2b0b, - 0x2b2f, 0x2b3f, 0x2b41, 0x080c, 0x2bf8, 0x11b0, 0x7850, 0x9084, - 0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005, - 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, - 0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x2b65, 0x2001, 0xffff, - 0x080c, 0x29f6, 0x0005, 0x080c, 0x2b43, 0x05e0, 0x2009, 0x199a, - 0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1178, 0x7850, 0x9084, - 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518, - 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104, - 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2b4b, 0x00c0, - 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, - 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001, 0x1993, - 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010, - 0x080c, 0x2a18, 0x0005, 0x080c, 0x2b43, 0x0560, 0x2009, 0x199a, - 0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1168, 0x7850, 0x9084, - 0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992, - 0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118, - 0x080c, 0x2b88, 0x0010, 0x080c, 0x2b58, 0x080c, 0x2b4b, 0x2009, - 0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c, - 0x2a18, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2bf8, 0x11b8, - 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104, 0x8000, - 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003, - 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419, - 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x2a43, 0x0005, 0x0099, - 0x0168, 0x080c, 0x2bf8, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852, - 0x080c, 0x2a2f, 0x0018, 0x0079, 0x080c, 0x2a43, 0x0005, 0x080c, - 0x0dc5, 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a, - 0x090c, 0x2ba4, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, - 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005, - 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, - 0x2001, 0x0001, 0x080c, 0x2bb6, 0x0005, 0x2009, 0x1996, 0x2104, - 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, - 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, - 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, - 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005, - 0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, - 0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, - 0x1120, 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, - 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991, - 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2baa, 0x2001, - 0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, - 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, - 0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838, - 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c, - 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, - 0x0138, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, - 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, - 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, - 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, - 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c83, 0xd09c, 0x1110, - 0x1f04, 0x2bfb, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, - 0x8000, 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, - 0x7852, 0x080c, 0x2c83, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, - 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, - 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, - 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, - 0x0006, 0x1d04, 0x2c31, 0x080c, 0x87bd, 0x1f04, 0x2c31, 0x7850, - 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c83, 0x9085, - 0x1000, 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, - 0xffcf, 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, - 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, - 0x1f04, 0x2c55, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c5b, - 0x00fe, 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c64, 0x080c, 0x87bd, - 0x1f04, 0x2c64, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, - 0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, - 0x0001, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, - 0x0002, 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, - 0x0005, 0x0006, 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, - 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, - 0x0080, 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, - 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, - 0x2000, 0x0170, 0x9186, 0x0100, 0x1904, 0x2cfc, 0x0048, 0x0016, - 0x2009, 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, - 0x2009, 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, - 0x0003, 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, - 0x0007, 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, - 0x0076, 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, - 0x2031, 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, - 0x006e, 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, - 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, - 0x2009, 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, - 0x1982, 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, - 0x180c, 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, - 0x0140, 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, - 0x1148, 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, - 0x001e, 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, - 0x2001, 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, - 0x602f, 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, - 0x6106, 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, - 0x0036, 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, - 0x2304, 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, - 0x0001, 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, - 0x9385, 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, - 0x2102, 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x757d, 0x0108, - 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, - 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, - 0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, - 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, - 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, - 0x0140, 0x2104, 0x1128, 0x080c, 0x757d, 0x0110, 0xc0bc, 0x0008, - 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, - 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, - 0x2c83, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2da6, - 0x080c, 0x87bd, 0x1f04, 0x2da6, 0x6050, 0x9085, 0x0400, 0x9084, - 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x3021, 0x3021, 0x2e45, - 0x2e45, 0x2e51, 0x2e51, 0x2e5d, 0x2e5d, 0x2e6b, 0x2e6b, 0x2e77, - 0x2e77, 0x2e85, 0x2e85, 0x2e93, 0x2e93, 0x2ea5, 0x2ea5, 0x2eb1, - 0x2eb1, 0x2ebf, 0x2ebf, 0x2edd, 0x2edd, 0x2efd, 0x2efd, 0x2ecd, - 0x2ecd, 0x2eed, 0x2eed, 0x2f0b, 0x2f0b, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2f1d, 0x2f1d, 0x2f29, - 0x2f29, 0x2f37, 0x2f37, 0x2f45, 0x2f45, 0x2f55, 0x2f55, 0x2f63, - 0x2f63, 0x2f73, 0x2f73, 0x2f83, 0x2f83, 0x2f95, 0x2f95, 0x2fa3, - 0x2fa3, 0x2fb3, 0x2fb3, 0x2fd5, 0x2fd5, 0x2ff7, 0x2ff7, 0x2fc3, - 0x2fc3, 0x2fe6, 0x2fe6, 0x3006, 0x3006, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, - 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x0804, - 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, - 0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, - 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c, - 0x2328, 0x0804, 0x3019, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, - 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x22ed, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x080c, - 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, - 0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, - 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, - 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c, - 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x0804, - 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x298c, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, - 0x22ed, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, - 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c, - 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c, - 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c, - 0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, - 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c, - 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c, - 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c, - 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, - 0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, - 0x080c, 0x22ed, 0x080c, 0x1394, 0x080c, 0x2328, 0x0410, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x298c, 0x080c, 0x1394, 0x080c, 0x2328, 0x0098, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, - 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x080c, 0x2328, - 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, - 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, - 0x6a4a, 0x1904, 0x3132, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, - 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3132, - 0x080c, 0x3137, 0x0804, 0x3132, 0xd2cc, 0x1904, 0x3132, 0x080c, - 0x7563, 0x1120, 0x70af, 0xffff, 0x0804, 0x3132, 0xd294, 0x0120, - 0x70af, 0xffff, 0x0804, 0x3132, 0x080c, 0x33a0, 0x0160, 0x080c, - 0xd548, 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30bf, 0x70af, - 0xffff, 0x0804, 0x3132, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, - 0x0904, 0x30bf, 0xd28c, 0x1904, 0x30bf, 0x0036, 0x73ac, 0x938e, - 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, - 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, - 0x00ff, 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, - 0x1150, 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, - 0xffff, 0x003e, 0x04a0, 0x900e, 0x080c, 0x2889, 0x080c, 0x66ac, - 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, - 0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e, 0xb8af, 0x0000, - 0x080c, 0x6a8c, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, - 0x0138, 0x080c, 0x6937, 0x0120, 0x080c, 0x3150, 0x0148, 0x0028, - 0x080c, 0x3290, 0x080c, 0x317c, 0x0118, 0x8318, 0x0804, 0x306c, - 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3132, 0x9780, - 0x33b1, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, - 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, - 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x3132, - 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x3127, 0xc484, 0x080c, - 0x6717, 0x0148, 0x080c, 0xd548, 0x1904, 0x3127, 0x080c, 0x66ac, - 0x1904, 0x312f, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, - 0x0148, 0x00c6, 0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e, - 0xb8af, 0x0000, 0x080c, 0x6a8c, 0x1130, 0x7030, 0xd08c, 0x01f8, - 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6a8c, - 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x66d1, 0x0028, - 0x080c, 0x331c, 0x01a0, 0x080c, 0x3347, 0x0088, 0x080c, 0x3290, - 0x080c, 0xd548, 0x1160, 0x080c, 0x317c, 0x0188, 0x0040, 0x080c, - 0xd548, 0x1118, 0x080c, 0x331c, 0x0110, 0x0451, 0x0140, 0x001e, - 0x8108, 0x015e, 0x1f04, 0x30d8, 0x70af, 0xffff, 0x0018, 0x001e, - 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, - 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x66ac, 0x1168, - 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3290, 0x04a9, 0x0128, - 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd292, 0x001e, 0x00ce, 0x0005, - 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, - 0x00ff, 0xb842, 0x080c, 0xb139, 0x01d0, 0x2b00, 0x6012, 0x080c, - 0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0x2001, 0x0000, - 0x080c, 0x665d, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, - 0x012e, 0x2009, 0x0004, 0x080c, 0xb166, 0x9085, 0x0001, 0x00ce, - 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, - 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb139, - 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, - 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, - 0x080c, 0x324b, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c, - 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126, 0x2091, 0x8000, - 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xb166, - 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, - 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x66ac, 0x1140, 0xb813, - 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, - 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, - 0xb091, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0001, - 0x9006, 0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126, - 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, - 0x080c, 0xb166, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, - 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, - 0x080c, 0x66ac, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8cf, - 0x0004, 0x080c, 0xb091, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, - 0x0001, 0x620a, 0x080c, 0xd2bb, 0x2009, 0x0022, 0x080c, 0xb166, - 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, - 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x94e5, 0x080c, - 0x9465, 0x080c, 0xaf25, 0x080c, 0xc041, 0x3e08, 0x2130, 0x81ff, - 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, - 0x0016, 0x080c, 0x6717, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, - 0xd0bc, 0x1110, 0x080c, 0x613b, 0x001e, 0x8108, 0x1f04, 0x3230, - 0x9686, 0x0001, 0x190c, 0x3374, 0x00be, 0x002e, 0x003e, 0x006e, - 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, - 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, - 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad, 0x2c08, - 0x080c, 0xe671, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcc0, 0x080c, - 0x613b, 0xba12, 0xbb16, 0xbcc2, 0x00be, 0x001e, 0x002e, 0x003e, - 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, - 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, - 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, - 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, - 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, - 0x20a9, 0x0001, 0x0078, 0x080c, 0x57cd, 0xd0c4, 0x0140, 0xd0a4, - 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe940, 0x20a9, - 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x32fb, 0x928e, - 0x007f, 0x0904, 0x32fb, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, - 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x198f, 0x0006, - 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, - 0x2158, 0x2001, 0x0001, 0x080c, 0x6a56, 0x00ce, 0x00be, 0x2019, - 0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad, - 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, - 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, - 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, - 0xe671, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x32b2, 0x015e, - 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, - 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x57cd, 0xd0c4, 0x0140, - 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xe940, - 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, - 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a84, 0x11d0, 0x2100, 0x080c, - 0x28bc, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, - 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, - 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, - 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, - 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, - 0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c, 0x324b, 0x001e, 0x080c, - 0x66d1, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, - 0x080c, 0xaa80, 0x080c, 0xecaa, 0x002e, 0x001e, 0x0005, 0x2001, - 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7563, - 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x7563, - 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, - 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x66d1, - 0x8108, 0x1f04, 0x3385, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, - 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, - 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, - 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, - 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, - 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, - 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, - 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, - 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, - 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, - 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, - 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, - 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, - 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, - 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, - 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, - 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, - 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, - 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, - 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, - 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, - 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, - 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, - 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, - 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, - 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, - 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, - 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, - 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, - 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, - 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x7038, 0xd084, 0x0190, 0x080c, 0xd561, 0x1118, 0x9186, 0xf800, + 0x1160, 0x7048, 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, + 0x2011, 0x8016, 0x080c, 0x4be9, 0x003e, 0x080c, 0xd55a, 0x1904, + 0x2697, 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, + 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, + 0x33a0, 0x0128, 0xc18d, 0x7132, 0x080c, 0x6a8a, 0x1510, 0x6240, + 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, + 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2697, 0x7038, 0xd08c, 0x1140, + 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2697, 0xc1ad, 0x2102, + 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be9, 0x003e, 0x0804, + 0x2697, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, + 0x1904, 0x2697, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, + 0x080c, 0x4be9, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, + 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, + 0x080c, 0x891c, 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, + 0xe915, 0x00ce, 0x9484, 0x00ff, 0x9080, 0x33ac, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xe9a5, + 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3211, + 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, + 0x671d, 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, + 0x080c, 0x6141, 0x8108, 0x1f04, 0x2687, 0x00be, 0x015e, 0x00ce, + 0x004e, 0x080c, 0xb072, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, + 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, + 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, + 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, + 0x6027, 0x0020, 0xd194, 0x0904, 0x27a5, 0x0016, 0x6220, 0xd2b4, + 0x0904, 0x2742, 0x080c, 0x878f, 0x080c, 0xa517, 0x6027, 0x0004, + 0x00f6, 0x2019, 0x19f2, 0x2304, 0x907d, 0x0904, 0x2711, 0x7804, + 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, + 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, + 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, + 0x1df0, 0x080c, 0x2d62, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, + 0x0009, 0x080c, 0x2c5b, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x080c, 0x97e1, + 0x080c, 0x98ed, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, + 0xb101, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, + 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, + 0x0110, 0x080c, 0x2d62, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028, + 0x080c, 0xd561, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, + 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0xa4f3, 0x0804, + 0x27a4, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaef8, 0x2019, 0x19f2, + 0x2304, 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xb180, 0x00ce, + 0x0804, 0x27a4, 0xd2bc, 0x0904, 0x278b, 0x080c, 0x879c, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, + 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62, + 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6044, 0x080c, 0xd561, 0x0120, + 0x909a, 0x0003, 0x1658, 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, + 0x6046, 0x603c, 0x00ce, 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, + 0x8794, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, + 0x918c, 0x1984, 0x918d, 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, + 0x2004, 0x9086, 0x0009, 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, + 0x0016, 0x6116, 0x00c8, 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, + 0x0001, 0x080c, 0xa877, 0x003e, 0x2019, 0x19f8, 0x2304, 0x9065, + 0x0150, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, + 0x004f, 0x080c, 0xb180, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27fd, + 0x7038, 0xd0ac, 0x1538, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, + 0x2d8c, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x27b3, 0x6150, 0x9185, + 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, 0x27bc, 0x080c, 0x87c3, + 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, + 0x04a0, 0x080c, 0x2c42, 0x1f04, 0x27bc, 0x015e, 0x6152, 0x001e, + 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xb072, + 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x080c, 0x57d7, + 0xd0fc, 0x1138, 0x080c, 0xd55a, 0x1120, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2009, 0x0002, 0x080c, 0x2c80, + 0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, + 0x6027, 0x0008, 0x080c, 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, + 0x00ae, 0x0005, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, + 0x0904, 0x25bc, 0x0016, 0x2009, 0x280e, 0x00d0, 0x2001, 0x188b, + 0x200c, 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, + 0x200c, 0xd194, 0x001e, 0x0904, 0x25bc, 0x0016, 0x2009, 0x2821, + 0x0038, 0x2001, 0x188b, 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, + 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, + 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2c7a, 0x6027, 0x0080, + 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, + 0x71d0, 0x70d2, 0x9116, 0x0904, 0x288c, 0x81ff, 0x01a0, 0x2009, + 0x0000, 0x080c, 0x2c80, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, + 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, + 0x080c, 0x4be9, 0x0448, 0x2001, 0x19aa, 0x200c, 0x81ff, 0x1140, + 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, + 0x2118, 0x2011, 0x8012, 0x080c, 0x4be9, 0x080c, 0x0ea3, 0x080c, + 0x57d7, 0xd0fc, 0x1188, 0x080c, 0xd55a, 0x1170, 0x00c6, 0x080c, + 0x2928, 0x080c, 0xa7de, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, + 0x0002, 0x080c, 0x3211, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, + 0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, + 0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, + 0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, + 0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, + 0x1120, 0x2500, 0x080c, 0x8271, 0x0048, 0x9584, 0x00ff, 0x9080, + 0x33ac, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, + 0x33ac, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, + 0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, + 0x6856, 0x1f04, 0x28d8, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, + 0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, + 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, + 0x9184, 0x000f, 0x9080, 0xf5f7, 0x2005, 0x6856, 0x8211, 0x1f04, + 0x28ed, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, + 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, + 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, + 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, + 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x291d, + 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, + 0x080c, 0x57d3, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, + 0x2020, 0x2009, 0x002e, 0x080c, 0xe9a5, 0x004e, 0x0005, 0x00f6, + 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2994, + 0x080c, 0x2bdf, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, + 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, + 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, + 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, + 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, + 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, + 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, + 0x9080, 0x0020, 0x2018, 0x080c, 0x91b1, 0x928c, 0xff00, 0x0110, + 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, + 0x0138, 0x220a, 0x080c, 0x7569, 0x1118, 0x2009, 0x196e, 0x220a, + 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, + 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, + 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, + 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, + 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, + 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, + 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, + 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, + 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, + 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, + 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, + 0x000e, 0x015e, 0x0005, 0x29f2, 0x2a10, 0x2a34, 0x2a36, 0x2a5f, + 0x2a61, 0x2a63, 0x2001, 0x0001, 0x080c, 0x283d, 0x080c, 0x2c3d, + 0x2001, 0x1993, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, + 0x9006, 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003, + 0x0006, 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005, + 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, + 0x2001, 0x199a, 0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, + 0x9006, 0x080c, 0x2bad, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, + 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, + 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b, + 0x2003, 0x0036, 0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, + 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x2bad, 0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, + 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006, + 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c, + 0x0dc5, 0x080c, 0x0dc5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, + 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, + 0x1993, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, + 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a86, + 0x2aa2, 0x2ade, 0x2b0a, 0x2b2a, 0x2b36, 0x2b38, 0x080c, 0x2bef, + 0x1190, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, + 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1991, + 0x2003, 0x0001, 0x0030, 0x080c, 0x2b5c, 0x2001, 0xffff, 0x080c, + 0x2a01, 0x0005, 0x080c, 0x2b3a, 0x05c0, 0x2009, 0x199a, 0x2104, + 0x8001, 0x200a, 0x080c, 0x2bef, 0x1158, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0005, 0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, + 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, + 0x080c, 0x2b42, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, + 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, + 0x2bca, 0x2001, 0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, + 0x2003, 0x0003, 0x0010, 0x080c, 0x2a23, 0x0005, 0x080c, 0x2b3a, + 0x0540, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bef, + 0x1148, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992, 0x2003, + 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118, 0x080c, + 0x2b7f, 0x0010, 0x080c, 0x2b4f, 0x080c, 0x2b42, 0x2009, 0x1996, + 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c, 0x2a23, + 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x2bef, 0x1198, 0x2009, + 0x1997, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, + 0x2001, 0x199c, 0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, + 0x200a, 0x0038, 0x00f9, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, + 0x2a4e, 0x0005, 0x0079, 0x0148, 0x080c, 0x2bef, 0x1118, 0x080c, + 0x2a3a, 0x0018, 0x0079, 0x080c, 0x2a4e, 0x0005, 0x080c, 0x0dc5, + 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a, 0x090c, + 0x2b9b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x2bad, 0x0005, 0x2009, 0x1996, 0x2104, 0x8000, + 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x0086, + 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, 0x2009, + 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, + 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, 0x0001, + 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9, + 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2ba1, 0x2001, 0x1998, + 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, + 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, + 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c, 0x795a, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138, + 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838, + 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, + 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c7a, 0xd09c, 0x1110, 0x1f04, + 0x2bf2, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, + 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, + 0x080c, 0x2c7a, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186, + 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, + 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, + 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, + 0x1d04, 0x2c28, 0x080c, 0x87c3, 0x1f04, 0x2c28, 0x7850, 0x9085, + 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c7a, 0x9085, 0x1000, + 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, 0xffcf, + 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, + 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, + 0x2c4c, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c52, 0x00fe, + 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c5b, 0x080c, 0x87c3, 0x1f04, + 0x2c5b, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, + 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, + 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, + 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, + 0x0006, 0x2001, 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, + 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, + 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, + 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, + 0x0170, 0x9186, 0x0100, 0x1904, 0x2cf3, 0x0048, 0x0016, 0x2009, + 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, + 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, + 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, + 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, + 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, + 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, + 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, + 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, + 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1982, + 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, + 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, + 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, + 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, + 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, + 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, + 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, + 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, + 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, + 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, + 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, + 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, + 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x7583, 0x0108, 0xc0bc, + 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, + 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, + 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, + 0x2104, 0x1128, 0x080c, 0x7583, 0x0110, 0xc0bc, 0x0008, 0xc0bd, + 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, + 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c7a, + 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2d9d, 0x080c, + 0x87c3, 0x1f04, 0x2d9d, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, + 0x6052, 0x015e, 0x000e, 0x0005, 0x3018, 0x3018, 0x2e3c, 0x2e3c, + 0x2e48, 0x2e48, 0x2e54, 0x2e54, 0x2e62, 0x2e62, 0x2e6e, 0x2e6e, + 0x2e7c, 0x2e7c, 0x2e8a, 0x2e8a, 0x2e9c, 0x2e9c, 0x2ea8, 0x2ea8, + 0x2eb6, 0x2eb6, 0x2ed4, 0x2ed4, 0x2ef4, 0x2ef4, 0x2ec4, 0x2ec4, + 0x2ee4, 0x2ee4, 0x2f02, 0x2f02, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2f14, 0x2f14, 0x2f20, 0x2f20, + 0x2f2e, 0x2f2e, 0x2f3c, 0x2f3c, 0x2f4c, 0x2f4c, 0x2f5a, 0x2f5a, + 0x2f6a, 0x2f6a, 0x2f7a, 0x2f7a, 0x2f8c, 0x2f8c, 0x2f9a, 0x2f9a, + 0x2faa, 0x2faa, 0x2fcc, 0x2fcc, 0x2fee, 0x2fee, 0x2fba, 0x2fba, + 0x2fdd, 0x2fdd, 0x2ffd, 0x2ffd, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x2330, + 0x0804, 0x3010, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x24e1, 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, + 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2997, 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, + 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, + 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, + 0x080c, 0x24e1, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, + 0x22f5, 0x080c, 0x1394, 0x080c, 0x2330, 0x0410, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, + 0x080c, 0x1394, 0x080c, 0x2330, 0x0098, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, + 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394, 0x080c, 0x2330, 0x0000, + 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, + 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a50, + 0x1904, 0x312d, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, + 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x312d, 0x080c, + 0x3132, 0x0804, 0x312d, 0xd2cc, 0x1904, 0x312d, 0x080c, 0x7569, + 0x1120, 0x70af, 0xffff, 0x0804, 0x312d, 0xd294, 0x0120, 0x70af, + 0xffff, 0x0804, 0x312d, 0x080c, 0x339b, 0x0160, 0x080c, 0xd561, + 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30b6, 0x70af, 0xffff, + 0x0804, 0x312d, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, + 0x30b6, 0xd28c, 0x1904, 0x30b6, 0x0036, 0x73ac, 0x938e, 0xffff, + 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0x938c, + 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, + 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, + 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, + 0x003e, 0x04a0, 0x900e, 0x080c, 0x2894, 0x080c, 0x66b2, 0x1538, + 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, + 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c, + 0x6a92, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, + 0x080c, 0x693d, 0x0120, 0x080c, 0x314b, 0x0148, 0x0028, 0x080c, + 0x328b, 0x080c, 0x3177, 0x0118, 0x8318, 0x0804, 0x3063, 0x73ae, + 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x312d, 0x9780, 0x33ac, + 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, + 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, + 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x312d, 0x2700, + 0x0156, 0x0016, 0x9106, 0x0904, 0x3122, 0xc484, 0x080c, 0x671d, + 0x0168, 0x080c, 0xd561, 0x1904, 0x3122, 0x080c, 0x339b, 0x1904, + 0x3122, 0x080c, 0x66b2, 0x1904, 0x312a, 0x0008, 0xc485, 0xb8bb, + 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8bc3, + 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c, 0x6a92, 0x1130, + 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, + 0x0180, 0x080c, 0x6a92, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, + 0x080c, 0x66d7, 0x0028, 0x080c, 0x3317, 0x01a0, 0x080c, 0x3342, + 0x0088, 0x080c, 0x328b, 0x080c, 0xd561, 0x1160, 0x080c, 0x3177, + 0x0188, 0x0040, 0x080c, 0xd561, 0x1118, 0x080c, 0x3317, 0x0110, + 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x30cf, 0x70af, + 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, + 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, + 0x080c, 0x66b2, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, + 0x328b, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd2a9, + 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, + 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb153, 0x01d0, + 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c, + 0x664f, 0x2001, 0x0000, 0x080c, 0x6663, 0x0126, 0x2091, 0x8000, + 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xb180, + 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, + 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, + 0xb842, 0x080c, 0xb153, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, + 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x1110, 0x080c, 0x3246, 0x080c, 0xd2d2, 0x6023, + 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, 0x6663, + 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, + 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, + 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, + 0x66b2, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, + 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x080c, 0xb0ab, 0x01d0, 0x2b00, 0x6012, 0x080c, + 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, + 0x080c, 0x6663, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, + 0x012e, 0x2009, 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2009, 0x007f, 0x080c, 0x66b2, 0x11b8, 0xb813, 0x00ff, + 0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xb0ab, 0x0170, 0x2b00, + 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd2d2, 0x2009, + 0x0022, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, + 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, + 0x080c, 0x94eb, 0x080c, 0x946b, 0x080c, 0xaf3f, 0x080c, 0xc051, + 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1140, 0x9686, + 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6141, 0x001e, + 0x8108, 0x1f04, 0x322b, 0x9686, 0x0001, 0x190c, 0x336f, 0x00be, + 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, + 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, + 0x0026, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000, + 0x080c, 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x001e, 0xba10, + 0xbb14, 0xbcc0, 0x080c, 0x6141, 0xba12, 0xbb16, 0xbcc2, 0x00be, + 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, + 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, + 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, + 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, + 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x57d3, + 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, + 0x080c, 0xe9a5, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, + 0x0904, 0x32f6, 0x928e, 0x007f, 0x0904, 0x32f6, 0x928e, 0x0080, + 0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, + 0x2001, 0x198f, 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, + 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6a5c, + 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, + 0x0000, 0x080c, 0x93b3, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, + 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, + 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, + 0x0016, 0x2c08, 0x080c, 0xe690, 0x001e, 0x007e, 0x002e, 0x8210, + 0x1f04, 0x32ad, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, + 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, + 0x57d3, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, + 0x0029, 0x080c, 0xe9a5, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a8a, + 0x11d0, 0x2100, 0x080c, 0x28c7, 0x81ff, 0x01b8, 0x2019, 0x0001, + 0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, + 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, + 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, + 0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, + 0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c, + 0x3246, 0x001e, 0x080c, 0x66d7, 0x012e, 0x00ce, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2110, 0x080c, 0xaa9a, 0x080c, 0xed0f, 0x002e, + 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, + 0xd0bc, 0x090c, 0x66d7, 0x8108, 0x1f04, 0x3380, 0x2061, 0x1800, + 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, + 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, + 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, + 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, + 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, + 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, + 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, + 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, + 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, + 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, + 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, + 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, + 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, + 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, + 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, + 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, + 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, + 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, + 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, + 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, + 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, + 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, + 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, + 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, + 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, + 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, + 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, + 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, + 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, + 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, + 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, - 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, - 0x18ba, 0x7007, 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, - 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1027, 0x090c, - 0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, - 0x2071, 0x189e, 0x7004, 0x0002, 0x34e0, 0x34e1, 0x34f4, 0x3508, - 0x0005, 0x1004, 0x34f1, 0x0e04, 0x34f1, 0x2079, 0x0000, 0x0126, - 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, - 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, - 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, - 0x35dc, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, - 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, - 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, - 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, - 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, - 0x003f, 0x1a04, 0x35d9, 0x61d0, 0x0804, 0x356e, 0x35b0, 0x35e8, - 0x35d9, 0x35f4, 0x35fe, 0x3604, 0x3608, 0x3618, 0x361c, 0x3632, - 0x3638, 0x363e, 0x3649, 0x3654, 0x3663, 0x3672, 0x3680, 0x3697, - 0x36b2, 0x35d9, 0x375b, 0x3799, 0x383f, 0x3850, 0x3873, 0x35d9, - 0x35d9, 0x35d9, 0x38ab, 0x38c7, 0x38d0, 0x38ff, 0x3905, 0x35d9, - 0x394b, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3956, 0x395f, - 0x3967, 0x3969, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, - 0x3995, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x39b2, 0x3a27, - 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x0002, 0x3a51, - 0x3a54, 0x3ab3, 0x3acc, 0x3afc, 0x3d9e, 0x35d9, 0x5390, 0x35d9, - 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3632, - 0x3638, 0x42c8, 0x57f1, 0x42e6, 0x541f, 0x5471, 0x557c, 0x35d9, - 0x55de, 0x561a, 0x564b, 0x5753, 0x5678, 0x56d3, 0x35d9, 0x42ea, - 0x44b0, 0x44c6, 0x44eb, 0x4550, 0x45c4, 0x45e4, 0x465b, 0x46b7, - 0x4713, 0x4716, 0x473b, 0x47f2, 0x4858, 0x4860, 0x4995, 0x4b0d, - 0x4b41, 0x4da5, 0x35d9, 0x4dc3, 0x4e69, 0x4f52, 0x4fac, 0x35d9, - 0x5063, 0x35d9, 0x50cf, 0x50ea, 0x4860, 0x5330, 0x714c, 0x0000, - 0x2021, 0x4000, 0x080c, 0x4bbf, 0x0126, 0x2091, 0x8000, 0x0e04, - 0x35ba, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, - 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, - 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, - 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, - 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, - 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, - 0x81ff, 0x0d98, 0x0804, 0x4bcc, 0x2039, 0x0001, 0x902e, 0x2520, - 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4bcf, 0x7984, 0x7888, - 0x2114, 0x200a, 0x0804, 0x35b0, 0x7984, 0x2114, 0x0804, 0x35b0, - 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, - 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b0, - 0x7884, 0x2060, 0x0804, 0x3665, 0x2009, 0x0003, 0x2011, 0x0003, - 0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, - 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x35b0, 0x7897, 0x0001, - 0x0804, 0x35b0, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35ec, - 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182, - 0x0040, 0x0210, 0x0804, 0x35e5, 0x2138, 0x7d98, 0x7c9c, 0x0804, - 0x35ec, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5, 0x2138, - 0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182, 0x0040, 0x0210, - 0x0804, 0x35e5, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, - 0x4004, 0x0804, 0x35b0, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, - 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b0, - 0x0804, 0x35df, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5, - 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x35b0, - 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x35e5, 0x8019, - 0x0904, 0x35e5, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, - 0x9006, 0x685a, 0x685e, 0x080c, 0x7879, 0x0804, 0x35b0, 0x2069, - 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x35e5, 0x8019, 0x0904, - 0x35e5, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, - 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6b24, 0x012e, - 0x0804, 0x35b0, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x35e2, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, - 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4b83, 0x1120, 0x2009, - 0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x36d6, 0x0005, 0xa864, 0x2008, - 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, - 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, - 0x1904, 0x35e2, 0x810f, 0x918c, 0x00ff, 0x0904, 0x35e2, 0x7112, - 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4b83, 0x1120, 0x2009, - 0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, - 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, - 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, - 0x4bcc, 0x701f, 0x3714, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x35e2, 0x0888, 0x7014, - 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x6292, 0x0150, 0x0126, - 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x65c2, - 0x1128, 0x7007, 0x0003, 0x701f, 0x3740, 0x0005, 0x080c, 0x7037, - 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, - 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, - 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, - 0xaf60, 0x0804, 0x4bcf, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, - 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, - 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, - 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, - 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004, - 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, - 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, - 0x0427, 0x81ff, 0x1904, 0x35e2, 0x7984, 0x080c, 0x6717, 0x1904, - 0x35e5, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35e5, - 0x7c88, 0x7d8c, 0x080c, 0x687a, 0x080c, 0x6849, 0x0000, 0x1518, - 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, - 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, - 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, - 0x9c02, 0x1a04, 0x35e2, 0x0c30, 0x080c, 0xca5e, 0x012e, 0x0904, - 0x35e2, 0x0804, 0x35b0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037, - 0x0126, 0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dcb, 0x012e, - 0x0804, 0x35b0, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6717, 0x1904, - 0x382c, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, - 0xb5a0, 0x080c, 0x687a, 0x080c, 0x6849, 0x1520, 0x2061, 0x1cd0, - 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, - 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, - 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, - 0x000d, 0x12b0, 0x0c28, 0x080c, 0xca5e, 0x012e, 0x2009, 0x0003, - 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037, 0x0126, - 0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x012e, 0x0070, - 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, - 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, - 0x1904, 0x35e2, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x67de, - 0x0904, 0x35e2, 0x080c, 0x6880, 0x0904, 0x35e2, 0x0804, 0x45db, - 0x81ff, 0x1904, 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, - 0x690e, 0x0904, 0x35e2, 0x2019, 0x0005, 0x79a8, 0x080c, 0x689b, - 0x0904, 0x35e2, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5, 0x8003, - 0x800b, 0x810b, 0x9108, 0x080c, 0x8711, 0x79a8, 0xd184, 0x1904, - 0x35b0, 0x0804, 0x45db, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, - 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, - 0x01f8, 0x2508, 0x080c, 0x6717, 0x11d8, 0x080c, 0x690e, 0x1128, - 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, - 0x080c, 0x689b, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, - 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8711, - 0x8529, 0x1ae0, 0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e2, - 0x012e, 0x0804, 0x35e5, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, - 0x67de, 0x0904, 0x35e2, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, - 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x900e, 0x080c, - 0xe671, 0x007e, 0x00ce, 0x080c, 0x687a, 0x0804, 0x35b0, 0x080c, - 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x687a, 0x2208, 0x0804, 0x35b0, - 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, - 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069, - 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68, - 0x1f04, 0x38e1, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, - 0x35b0, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, - 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, - 0x1910, 0x6910, 0x62bc, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x080c, 0x57e1, - 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x35e2, 0x012e, 0x615c, - 0x9190, 0x33b1, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, - 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, - 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, - 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, - 0x0002, 0x0068, 0x080c, 0x7563, 0x1118, 0x2031, 0x0004, 0x0038, - 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x9036, 0x7e9a, - 0x7f9e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c, - 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x35b0, 0x0126, 0x2091, - 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x35b0, 0x080c, - 0x4bb6, 0x0904, 0x35e5, 0xba44, 0xbb38, 0x0804, 0x35b0, 0x080c, - 0x0dc5, 0x080c, 0x4bb6, 0x2110, 0x0904, 0x35e5, 0xb804, 0x908c, - 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, - 0x2009, 0x0009, 0x1904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x2019, - 0x0005, 0x00c6, 0x9066, 0x080c, 0xaa80, 0x080c, 0x94da, 0x0076, - 0x903e, 0x080c, 0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x00ce, - 0xb807, 0x0407, 0x012e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x7884, - 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, - 0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, - 0x1210, 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a, - 0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, - 0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094, 0x0148, 0x00e6, 0x2071, - 0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208, 0x713e, 0x00ee, 0xd0c4, - 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac, 0x2011, - 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, - 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011, 0x0114, - 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010, 0x918c, - 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, - 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c, - 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, - 0x090c, 0x42c8, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, - 0x2012, 0x012e, 0x0804, 0x35b0, 0x00f6, 0x2079, 0x1800, 0x7a38, - 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, - 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, - 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x35e5, 0x788c, 0x902d, - 0x0904, 0x35e5, 0x900e, 0x080c, 0x6717, 0x1120, 0xba44, 0xbb38, - 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, - 0x4bb6, 0x0904, 0x35e5, 0x7888, 0x900d, 0x0904, 0x35e5, 0x788c, - 0x9005, 0x0904, 0x35e5, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, - 0x35b0, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x57e1, - 0x1904, 0x35e2, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, - 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, - 0x007f, 0x16e0, 0x9188, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x2001, - 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, - 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb091, 0x000e, 0x0510, - 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x66b2, 0x2b08, 0x00be, - 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4b83, 0x01d0, 0x9006, - 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, - 0x3aac, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xb166, 0x012e, - 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35e2, 0x00ce, 0x0804, - 0x35e5, 0x080c, 0xb0e7, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, - 0x35e2, 0x0804, 0x35b0, 0x2061, 0x1a75, 0x0126, 0x2091, 0x8000, - 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354, - 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, - 0x35b0, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35e2, 0x080c, - 0x7563, 0x0904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074, - 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x28f2, 0x080c, 0x5a04, - 0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e5, 0x0006, 0x0016, - 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, 0x1847, 0x6008, - 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x91ab, 0x7206, 0x00ee, - 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, - 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x35b2, 0x7884, 0xd0fc, - 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, - 0x0298, 0x012e, 0x0804, 0x35e5, 0x2001, 0x002a, 0x2004, 0x9005, - 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, - 0x35e5, 0x012e, 0x0804, 0x35e2, 0x080c, 0xb051, 0x0dd0, 0x7884, - 0xd0fc, 0x0904, 0x3b7b, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0d88, - 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, - 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, - 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, - 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, - 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, - 0xa816, 0x080c, 0x3d01, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, - 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, - 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e, 0x7023, - 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, - 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2001, 0x19a0, - 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, - 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3d70, - 0x080c, 0x3d2f, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, - 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, - 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, - 0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e, 0x00ee, 0x00fe, - 0x080c, 0x4039, 0x080c, 0x3f3e, 0x05b8, 0x2001, 0x020b, 0x2004, - 0x9084, 0x0140, 0x1db8, 0x080c, 0x4180, 0x00f6, 0x2079, 0x0300, - 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, - 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, - 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, - 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, - 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, - 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3f48, 0x080c, 0x3d2a, - 0x0058, 0x080c, 0x3d2a, 0x080c, 0x40a4, 0x080c, 0x402f, 0x2001, - 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, - 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, - 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, - 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, - 0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227, 0x200c, 0x2102, - 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, - 0x004e, 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, - 0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x0016, 0x0026, - 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, - 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, - 0x0904, 0x3c9a, 0x2048, 0x1f04, 0x3c4e, 0x7068, 0x2040, 0xa28c, - 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, - 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, - 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e, - 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, - 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bcf, 0x701f, 0x3c3e, 0x015e, - 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, - 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, - 0x701f, 0x3cff, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, - 0x2009, 0x007f, 0x080c, 0x66ac, 0x0110, 0x9006, 0x0030, 0xb813, - 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd30e, 0x015e, 0x00de, 0x009e, - 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, - 0x35e2, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, - 0x0096, 0x00d6, 0x0156, 0x701f, 0x3cd1, 0x7007, 0x0003, 0x0804, - 0x3c8f, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x35b2, - 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, + 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, + 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1027, + 0x090c, 0x0dc5, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x34db, + 0x34dc, 0x34ef, 0x3503, 0x0005, 0x1004, 0x34ec, 0x0e04, 0x34ec, + 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, + 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, + 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, + 0x9086, 0x0200, 0x0904, 0x35d7, 0x0005, 0x7018, 0x2048, 0x2061, + 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, + 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, + 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, + 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, + 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35d4, 0x61d0, 0x0804, + 0x3569, 0x35ab, 0x35e3, 0x35d4, 0x35ef, 0x35f9, 0x35ff, 0x3603, + 0x3613, 0x3617, 0x362d, 0x3633, 0x3639, 0x3644, 0x364f, 0x365e, + 0x366d, 0x367b, 0x3692, 0x36ad, 0x35d4, 0x3756, 0x3794, 0x383a, + 0x384b, 0x386e, 0x35d4, 0x35d4, 0x35d4, 0x38a6, 0x38c2, 0x38cb, + 0x38fa, 0x3900, 0x35d4, 0x3946, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x3951, 0x395a, 0x3962, 0x3964, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x35d4, 0x35d4, 0x3990, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x39ad, 0x3a22, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x0002, 0x3a4c, 0x3a4f, 0x3aae, 0x3ac7, 0x3af7, 0x3d99, + 0x35d4, 0x5396, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x35d4, 0x362d, 0x3633, 0x42ce, 0x57f7, 0x42ec, 0x5425, + 0x5477, 0x5582, 0x35d4, 0x55e4, 0x5620, 0x5651, 0x5759, 0x567e, + 0x56d9, 0x35d4, 0x42f0, 0x44b6, 0x44cc, 0x44f1, 0x4556, 0x45ca, + 0x45ea, 0x4661, 0x46bd, 0x4719, 0x471c, 0x4741, 0x47f8, 0x485e, + 0x4866, 0x499b, 0x4b13, 0x4b47, 0x4dab, 0x35d4, 0x4dc9, 0x4e6f, + 0x4f58, 0x4fb2, 0x35d4, 0x5069, 0x35d4, 0x50d5, 0x50f0, 0x4866, + 0x5336, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4bc5, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x35b5, 0x0010, 0x012e, 0x0cc0, 0x7c36, + 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, + 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, + 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, + 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, + 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, + 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4bd2, 0x2039, + 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, + 0x4bd5, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x35ab, 0x7984, + 0x2114, 0x0804, 0x35ab, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, + 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, + 0x7b8c, 0x0804, 0x35ab, 0x7884, 0x2060, 0x0804, 0x3660, 0x2009, + 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893, + 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, + 0x35ab, 0x7897, 0x0001, 0x0804, 0x35ab, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x35e7, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, + 0x35f3, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x2138, + 0x7d98, 0x7c9c, 0x0804, 0x35e7, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x35e0, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f3, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x21e8, 0x7984, 0x7888, + 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x35ab, 0x2061, 0x0800, + 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, + 0x9005, 0x0904, 0x35ab, 0x0804, 0x35da, 0x79a0, 0x9182, 0x0040, + 0x0210, 0x0804, 0x35e0, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, + 0x4012, 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, + 0x1a04, 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684a, 0x6942, 0x788c, + 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x787f, + 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, + 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684e, 0x6946, 0x788c, 0x6862, + 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6b2a, 0x012e, 0x0804, 0x35ab, 0x902e, 0x2520, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x7984, 0x7b88, 0x7a8c, + 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, + 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x36d1, + 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, + 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, + 0x0120, 0x9096, 0x0029, 0x1904, 0x35dd, 0x810f, 0x918c, 0x00ff, + 0x0904, 0x35dd, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, + 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, + 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, + 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x370f, 0x0005, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, + 0x35dd, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, + 0x6298, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, + 0x0050, 0x080c, 0x65c8, 0x1128, 0x7007, 0x0003, 0x701f, 0x373b, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, + 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4bd5, 0x2091, 0x8000, + 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, + 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, + 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, + 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, + 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, + 0x2001, 0x1a1d, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, + 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, + 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x35dd, 0x7984, + 0x080c, 0x671d, 0x1904, 0x35e0, 0x7e98, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x1a04, 0x35e0, 0x7c88, 0x7d8c, 0x080c, 0x6880, 0x080c, + 0x684f, 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, + 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, + 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, 0x35dd, 0x0c30, 0x080c, + 0xca71, 0x012e, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x900e, 0x2001, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152, + 0x080c, 0x6dd1, 0x012e, 0x0804, 0x35ab, 0x00a6, 0x2950, 0xb198, + 0x080c, 0x671d, 0x1904, 0x3827, 0xb6a4, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6880, 0x080c, 0x684f, + 0x1520, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, + 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, + 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, + 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xca71, + 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, + 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152, 0x080c, + 0x6dc4, 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, + 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, + 0x00ae, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904, + 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904, + 0x35dd, 0x0804, 0x45e1, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x080c, 0x6914, 0x0904, 0x35dd, 0x2019, 0x0005, + 0x79a8, 0x080c, 0x68a1, 0x0904, 0x35dd, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x35e0, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717, + 0x79a8, 0xd184, 0x1904, 0x35ab, 0x0804, 0x45e1, 0x0126, 0x2091, + 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, + 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x671d, 0x11d8, + 0x080c, 0x6914, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, + 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x1118, 0x2009, 0x0006, + 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, + 0x9108, 0x080c, 0x8717, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x35ab, + 0x012e, 0x0804, 0x35dd, 0x012e, 0x0804, 0x35e0, 0x080c, 0x4ba0, + 0x0904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0xbaa0, 0x2019, + 0x0005, 0x00c6, 0x9066, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, + 0x93b3, 0x900e, 0x080c, 0xe690, 0x007e, 0x00ce, 0x080c, 0x6880, + 0x0804, 0x35ab, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6880, + 0x2208, 0x0804, 0x35ab, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, + 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, + 0x20a9, 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, + 0x0059, 0x9210, 0x8d68, 0x1f04, 0x38dc, 0x2300, 0x9218, 0x00ee, + 0x00de, 0x015e, 0x0804, 0x35ab, 0x00f6, 0x0016, 0x907d, 0x0138, + 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, + 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x35ab, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x080c, 0x57e7, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, + 0x35dd, 0x012e, 0x615c, 0x9190, 0x33ac, 0x2215, 0x9294, 0x00ff, + 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, + 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, + 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, + 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x7569, 0x1118, + 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, + 0x35dd, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x35ab, 0x614c, 0x6250, + 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, + 0x35ab, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, + 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xba44, 0xbb38, + 0x0804, 0x35ab, 0x080c, 0x0dc5, 0x080c, 0x4bbc, 0x2110, 0x0904, + 0x35e0, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, + 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x35dd, 0x0126, + 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaa9a, + 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e, 0x080c, + 0xe690, 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x35ab, + 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, + 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a, + 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1988, + 0x2d04, 0x266a, 0x789a, 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000, + 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094, + 0x0148, 0x00e6, 0x2071, 0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208, + 0x713e, 0x00ee, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, + 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, + 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, + 0x00de, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, + 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, + 0x6140, 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, + 0x910e, 0xd1e4, 0x190c, 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, + 0x6046, 0x9084, 0x0001, 0x090c, 0x42ce, 0x6040, 0xd0cc, 0x0120, + 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x35ab, 0x00f6, + 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, + 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, + 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, + 0x35e0, 0x788c, 0x902d, 0x0904, 0x35e0, 0x900e, 0x080c, 0x671d, + 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, + 0x8108, 0x0ca0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x7888, 0x900d, + 0x0904, 0x35e0, 0x788c, 0x9005, 0x0904, 0x35e0, 0xba44, 0xb946, + 0xbb38, 0xb83a, 0x0804, 0x35ab, 0x2011, 0xbc09, 0x0010, 0x2011, + 0xbc05, 0x080c, 0x57e7, 0x1904, 0x35dd, 0x00c6, 0x2061, 0x0100, + 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, + 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x33ac, 0x210d, + 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, + 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, + 0xb0ab, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, + 0x66b8, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, + 0x4b89, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, + 0xc0fd, 0xa86a, 0x701f, 0x3aa7, 0x2900, 0x6016, 0x2009, 0x0032, + 0x080c, 0xb180, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, + 0x35dd, 0x00ce, 0x0804, 0x35e0, 0x080c, 0xb101, 0x0cb0, 0xa830, + 0x9086, 0x0100, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x2061, 0x1a75, + 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, + 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, + 0x78aa, 0x012e, 0x0804, 0x35ab, 0x900e, 0x2110, 0x0c88, 0x81ff, + 0x1904, 0x35dd, 0x080c, 0x7569, 0x0904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, + 0x28fd, 0x080c, 0x5a0a, 0x012e, 0x0804, 0x35ab, 0x012e, 0x0804, + 0x35e0, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19ab, 0x2070, + 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, + 0x91b1, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, + 0x35ad, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, + 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x35e0, 0x2001, + 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, + 0x1230, 0x012e, 0x0804, 0x35e0, 0x012e, 0x0804, 0x35dd, 0x080c, + 0xb06b, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3b76, 0x00c6, 0x080c, + 0x4b89, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, + 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, + 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, + 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, + 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, + 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3cfc, 0x0928, 0x7014, + 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, - 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, - 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, - 0x4bcf, 0x007e, 0x701f, 0x3c3e, 0x7023, 0x0001, 0x0005, 0x0804, - 0x35b0, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, - 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, - 0x4b83, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, - 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, - 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, - 0x000e, 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, - 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, - 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, - 0x6106, 0x080c, 0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, - 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, - 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, - 0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004, - 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, - 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x00e6, 0x080c, 0x4b83, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, - 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, - 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, - 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bd2, + 0x701f, 0x3c39, 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, + 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, + 0x3ae1, 0x2001, 0x19a1, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, + 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, + 0x0012, 0x080c, 0x3d6b, 0x080c, 0x3d2a, 0x00f6, 0x00e6, 0x0086, + 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, + 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, + 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4112, + 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034, 0x080c, 0x3f39, 0x05b8, + 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4186, + 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, + 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, + 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, + 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, + 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, + 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, + 0x3f43, 0x080c, 0x3d25, 0x0058, 0x080c, 0x3d25, 0x080c, 0x40aa, + 0x080c, 0x402a, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, + 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, + 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, + 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, + 0x2102, 0x080c, 0x12fc, 0x2009, 0x0028, 0x080c, 0x2432, 0x2001, + 0x0227, 0x200c, 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005, + 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804, + 0x35ad, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, + 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, + 0x7022, 0xa804, 0x9005, 0x0904, 0x3c95, 0x2048, 0x1f04, 0x3c49, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, + 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, + 0x2048, 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, + 0x4bd2, 0x701f, 0x3c39, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, + 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bd5, + 0x701f, 0x3c39, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, + 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, + 0x9086, 0x0103, 0x1118, 0x701f, 0x3cfa, 0x0450, 0x7014, 0x2048, + 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x66b2, 0x0110, + 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd325, + 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0904, 0x35dd, 0x0016, 0x0026, 0x0036, 0x0046, + 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3ccc, + 0x7007, 0x0003, 0x0804, 0x3c8a, 0xa830, 0x9086, 0x0100, 0x2021, + 0x400c, 0x0904, 0x35ad, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, + 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, + 0x0f8b, 0x000e, 0x080c, 0x4bd5, 0x007e, 0x701f, 0x3c39, 0x7023, + 0x0001, 0x0005, 0x0804, 0x35ab, 0x0156, 0x00c6, 0xa814, 0x908a, + 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, + 0x0168, 0x0016, 0x080c, 0x4b89, 0x001e, 0x0130, 0xa800, 0x2040, + 0xa008, 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, + 0x00ce, 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, + 0x9086, 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003, + 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, + 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, + 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4b89, 0xa813, 0x0019, + 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, + 0x2001, 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, + 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2432, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, + 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4b89, 0x2940, 0xa013, + 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, + 0xa866, 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, + 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, + 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c72, + 0x1130, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x2001, + 0x19a0, 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dba, + 0x3dc3, 0x3dcc, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x012e, + 0x0804, 0x35e0, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, + 0x080c, 0x3f8d, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, + 0x200a, 0x080c, 0x3f8d, 0x0078, 0x080c, 0x7569, 0x1128, 0x012e, + 0x2009, 0x0016, 0x0804, 0x35dd, 0x81ff, 0x0128, 0x012e, 0x2021, + 0x400b, 0x0804, 0x35ad, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, + 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x080c, 0x3ae1, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, + 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4261, 0x080c, 0x41b1, + 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, + 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, + 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, + 0x4112, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c, + 0x2c7a, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034, + 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3f43, 0x2001, 0x0004, + 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, + 0x35dd, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, + 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, + 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x4012, 0x2d00, 0x9c05, + 0x9b05, 0x0120, 0x080c, 0x3f43, 0x0804, 0x3ef0, 0x080c, 0x4186, + 0x080c, 0x40aa, 0x080c, 0x3ff5, 0x080c, 0x402a, 0x00f6, 0x2079, + 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f43, 0x00fe, + 0x0804, 0x3ef0, 0x00fe, 0x080c, 0x3f39, 0x1150, 0x8d68, 0x2001, + 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3f43, 0x0080, + 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, + 0x0038, 0x2001, 0x1a66, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e40, + 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, + 0x9605, 0x0904, 0x3ef0, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, + 0x9b05, 0x1904, 0x3ef0, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, + 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a66, 0x2003, 0x0003, + 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, + 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, + 0x2432, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, + 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, + 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3ec7, 0x00ce, 0x0030, + 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, + 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, + 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dfa, + 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, + 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, + 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, + 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, + 0x2432, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, + 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, + 0x0010, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, + 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804, + 0x35ad, 0x9085, 0x0001, 0x1d04, 0x3f42, 0x2091, 0x6000, 0x8420, + 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, + 0x032a, 0x2003, 0x0004, 0x2001, 0x1a66, 0x2003, 0x0000, 0x0071, + 0x2009, 0x0048, 0x080c, 0x2432, 0x2001, 0x0227, 0x2024, 0x2402, + 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, + 0x2071, 0x1a6a, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, + 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x0d88, 0x080c, + 0x4186, 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, + 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b, 0x0002, + 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x28dd, 0x7850, + 0x9084, 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, + 0x1df0, 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, + 0x1d04, 0x3fa8, 0x2091, 0x6000, 0x1f04, 0x3fa8, 0x7850, 0x9085, + 0x0400, 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, + 0x0003, 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, + 0xa001, 0x1f04, 0x3fc8, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, + 0x61a8, 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, + 0x7827, 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, + 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, + 0x080c, 0x2d52, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, + 0x2d52, 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, + 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x2001, 0x0201, + 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, + 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, + 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, + 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, + 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, + 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, + 0x19ac, 0x2004, 0x70e2, 0x080c, 0x3d1b, 0x1188, 0x2001, 0x1820, + 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, + 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, + 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, + 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, + 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, + 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, + 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, + 0x7016, 0x080c, 0x4186, 0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320, + 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, + 0x6898, 0x780a, 0x00de, 0x080c, 0x3d1b, 0x0140, 0x2001, 0x19a0, + 0x200c, 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, + 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, + 0x0011, 0x080c, 0x4112, 0x2011, 0x0001, 0x080c, 0x4112, 0x00fe, + 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320, + 0x792c, 0xd1fc, 0x0904, 0x410f, 0x782b, 0x0002, 0x9026, 0xd19c, + 0x1904, 0x410b, 0x7000, 0x0002, 0x410f, 0x40c0, 0x40f0, 0x410b, + 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, + 0x080c, 0x4112, 0x0904, 0x410f, 0x080c, 0x4112, 0x0804, 0x410f, + 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, + 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, + 0x0de8, 0x080c, 0x4012, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, + 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, + 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, + 0x40b4, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, + 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, + 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, + 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, + 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398, 0x4140, 0x231d, + 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, + 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, + 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, + 0x417d, 0x4174, 0x416b, 0x4162, 0x4159, 0x4150, 0x4147, 0xa964, + 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, + 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, + 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, + 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, + 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, + 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, + 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, + 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, + 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, + 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x41ad, 0x4199, + 0x41a4, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, + 0x4112, 0x190c, 0x4112, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, + 0x1d38, 0x2011, 0x0001, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, + 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, + 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, + 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, + 0x080c, 0x4b89, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, + 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, + 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, + 0x4229, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4b89, 0xa813, + 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, + 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, + 0x0090, 0x2079, 0x0100, 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, + 0x0040, 0x080c, 0x2432, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, + 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, + 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, + 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, + 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, + 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, + 0x0086, 0x080c, 0x4b89, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, + 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, + 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4b89, + 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, + 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, + 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4229, + 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b89, 0x2940, 0xa013, + 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, + 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, + 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, + 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a66, + 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, - 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c7b, 0x1130, 0x9006, 0x080c, - 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x7884, 0x9084, 0x0007, 0x0002, - 0x3dbb, 0x3dc4, 0x3dcd, 0x3db8, 0x3db8, 0x3db8, 0x3db8, 0x3db8, - 0x012e, 0x0804, 0x35e5, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, - 0x200a, 0x080c, 0x3f92, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, - 0x4000, 0x200a, 0x080c, 0x3f92, 0x0078, 0x080c, 0x7563, 0x1128, - 0x012e, 0x2009, 0x0016, 0x0804, 0x35e2, 0x81ff, 0x0128, 0x012e, - 0x2021, 0x400b, 0x0804, 0x35b2, 0x6000, 0x9086, 0x0003, 0x1db8, - 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90, 0x0086, 0x0096, 0x00a6, - 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2009, - 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, - 0x2058, 0x080c, 0x425b, 0x080c, 0x41ab, 0x903e, 0x2720, 0x00f6, - 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6, - 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, - 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x080c, 0x2c83, - 0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x410c, - 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4039, 0x2009, 0x9c40, 0x8109, - 0x11b0, 0x080c, 0x3f48, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, - 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, - 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35e2, 0x0cf8, 0x2001, - 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, - 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, - 0x0150, 0x080c, 0x4017, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, - 0x3f48, 0x0804, 0x3ef5, 0x080c, 0x4180, 0x080c, 0x40a4, 0x080c, - 0x3ffa, 0x080c, 0x402f, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, - 0x0130, 0x8b58, 0x080c, 0x3f48, 0x00fe, 0x0804, 0x3ef5, 0x00fe, - 0x080c, 0x3f3e, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, - 0x0033, 0x2502, 0x080c, 0x3f48, 0x0080, 0x87ff, 0x0138, 0x2001, - 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a66, - 0x2004, 0x9086, 0x0000, 0x1904, 0x3e45, 0x2001, 0x032f, 0x2003, - 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3ef5, - 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3ef5, - 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, - 0x1148, 0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, - 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, - 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x242a, 0x2900, 0xa85a, - 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, - 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, - 0x2004, 0x1f04, 0x3ecc, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, - 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, - 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, - 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dff, 0x001e, 0x00c6, 0x2001, - 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, - 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, - 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, 0x9084, 0x0003, 0x9086, - 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227, - 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, 0x6052, 0x602f, 0x0000, - 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08, - 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, - 0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x9085, 0x0001, - 0x1d04, 0x3f47, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, - 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, - 0x2001, 0x1a66, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, - 0x242a, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, - 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000, - 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, - 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, - 0x242a, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4180, 0x7000, 0x9086, - 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, - 0x0040, 0x080c, 0x242a, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, - 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, - 0x7932, 0x7936, 0x080c, 0x28d2, 0x7850, 0x9084, 0xfbff, 0x9085, - 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf, - 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3fad, 0x2091, - 0x6000, 0x1f04, 0x3fad, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff, - 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001, - 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843, - 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3fcd, - 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001, - 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850, - 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, - 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x7827, - 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d5b, 0x7827, 0x0048, - 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, - 0x1a66, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, - 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, - 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, - 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, - 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, - 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, - 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, - 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2, - 0x080c, 0x3d20, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f, - 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, - 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, - 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, - 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, - 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, - 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, - 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4180, - 0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, - 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, - 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, - 0x0004, 0x2011, 0x0011, 0x080c, 0x410c, 0x2011, 0x0001, 0x080c, - 0x410c, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66, - 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x4109, 0x782b, 0x0002, - 0x9026, 0xd19c, 0x1904, 0x4105, 0x7000, 0x0002, 0x4109, 0x40ba, - 0x40ea, 0x4105, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, - 0x2011, 0x0001, 0x080c, 0x410c, 0x0904, 0x4109, 0x080c, 0x410c, - 0x0804, 0x4109, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, - 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, - 0x200c, 0x81ff, 0x0de8, 0x080c, 0x4017, 0x2009, 0x0001, 0x00f6, - 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, - 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, - 0xd0fc, 0x1904, 0x40ae, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, - 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, - 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, - 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, - 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, - 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398, - 0x413a, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, - 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, - 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, - 0x0001, 0x0005, 0x4177, 0x416e, 0x4165, 0x415c, 0x4153, 0x414a, - 0x4141, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, - 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, - 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, - 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, - 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, - 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, - 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, - 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, - 0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c, - 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, - 0x41a7, 0x4193, 0x419e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, - 0x0001, 0x080c, 0x410c, 0x190c, 0x410c, 0x0048, 0x8001, 0x7002, - 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, - 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, - 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, - 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, - 0x002f, 0x201c, 0x080c, 0x4b83, 0xa813, 0x0019, 0xaf16, 0x2900, - 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, - 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, - 0x009e, 0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, - 0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, - 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, - 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, - 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, - 0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004, - 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, - 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, - 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, - 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, - 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, - 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, - 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, - 0x0096, 0x2940, 0x0086, 0x080c, 0x4b83, 0x008e, 0xa058, 0x00a6, - 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, - 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, - 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, - 0x080c, 0x4b83, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, - 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, - 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, - 0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b83, - 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, - 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, - 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, - 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, - 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, - 0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, - 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, - 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, - 0x0126, 0x2091, 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, - 0x0001, 0x9006, 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, - 0x0000, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, - 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x35b0, 0x7d98, 0x7c9c, - 0x0804, 0x36b4, 0x080c, 0x7563, 0x190c, 0x60e6, 0x6040, 0x9084, - 0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcc, 0x701f, - 0x4302, 0x0005, 0x080c, 0x57dc, 0x1130, 0x3b00, 0x3a08, 0xc194, - 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, - 0x35e5, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e5, 0xd094, - 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, - 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, - 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, - 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, - 0x928a, 0x007f, 0x1a04, 0x35e5, 0x9288, 0x33b1, 0x210d, 0x918c, - 0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, - 0x35e5, 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, - 0x8004, 0x0006, 0x2009, 0x19b3, 0x9080, 0x29c5, 0x2005, 0x200a, - 0x000e, 0x2009, 0x19b4, 0x9080, 0x29c9, 0x2005, 0x200a, 0x6808, - 0x908a, 0x0100, 0x0a04, 0x35e5, 0x908a, 0x0841, 0x1a04, 0x35e5, - 0x9084, 0x0007, 0x1904, 0x35e5, 0x680c, 0x9005, 0x0904, 0x35e5, - 0x6810, 0x9005, 0x0904, 0x35e5, 0x6848, 0x6940, 0x910a, 0x1a04, - 0x35e5, 0x8001, 0x0904, 0x35e5, 0x684c, 0x6944, 0x910a, 0x1a04, - 0x35e5, 0x8001, 0x0904, 0x35e5, 0x2009, 0x1982, 0x200b, 0x0000, - 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, - 0x080c, 0x0e52, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, - 0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7879, 0x080c, - 0x6ac2, 0x080c, 0x6b24, 0x6808, 0x602a, 0x080c, 0x239c, 0x2009, - 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, - 0x6b08, 0x080c, 0x292c, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, - 0x449e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, - 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, - 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, - 0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, - 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, - 0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, - 0x4001, 0x080c, 0x8828, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, - 0xd384, 0x0510, 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, - 0x1110, 0x839d, 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, - 0x080c, 0x7e35, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, - 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, - 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x43f3, 0x00ce, 0x00c6, - 0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, - 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001, - 0x0001, 0x080c, 0x2bb6, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063, - 0x0001, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0028, - 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70, - 0x080c, 0x0ea3, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, - 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, - 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, - 0x197d, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, - 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, - 0x29a1, 0x2001, 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, - 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7563, - 0x0128, 0x080c, 0x50c3, 0x0110, 0x080c, 0x28f2, 0x60d4, 0x9005, - 0x01c0, 0x6003, 0x0001, 0x2009, 0x4486, 0x00e0, 0x080c, 0x7563, - 0x1168, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, - 0x87dd, 0x080c, 0x784d, 0x080c, 0x748f, 0x0040, 0x080c, 0x5fe0, - 0x0028, 0x6003, 0x0004, 0x2009, 0x449e, 0x0020, 0x080c, 0x69ee, - 0x0804, 0x35b0, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, - 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, - 0x6000, 0x9086, 0x0000, 0x0904, 0x35e2, 0x2069, 0x1847, 0x7890, - 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4bcf, 0x9006, 0x080c, - 0x28f2, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563, 0x11b0, 0x080c, - 0x7848, 0x080c, 0x6121, 0x080c, 0x33a5, 0x0118, 0x6130, 0xc18d, - 0x6132, 0x080c, 0xd548, 0x0130, 0x080c, 0x7586, 0x1118, 0x080c, - 0x753b, 0x0038, 0x080c, 0x748f, 0x0020, 0x080c, 0x60e6, 0x080c, - 0x5fe0, 0x0804, 0x35b0, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563, - 0x1110, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, - 0x0190, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcf, 0x701f, - 0x35ae, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, - 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, - 0x4304, 0x655c, 0x9588, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x216a, - 0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6717, - 0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, - 0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, - 0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, - 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, - 0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x6071, 0x0804, 0x44fb, - 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009, - 0x0002, 0x0804, 0x35e2, 0x080c, 0x57cd, 0xd0b4, 0x0558, 0x7884, - 0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, - 0x0508, 0x080c, 0x33a0, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, - 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, - 0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009, 0x0003, 0x0804, - 0x35e2, 0x7007, 0x0003, 0x701f, 0x4586, 0x0005, 0x080c, 0x4bb6, - 0x0904, 0x35e5, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, - 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, - 0x0006, 0x2098, 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c, - 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, - 0x2098, 0x080c, 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x81ff, 0x1904, 0x35e2, 0x080c, - 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6889, 0x0904, 0x35e2, 0x0058, - 0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x35e2, 0xa974, - 0xaa94, 0x0804, 0x35b0, 0x080c, 0x57d5, 0x0904, 0x35b0, 0x701f, - 0x45d0, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x7888, - 0x908a, 0x1000, 0x1a04, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5, - 0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c, - 0x690e, 0x0904, 0x35e2, 0x2019, 0x0004, 0x900e, 0x080c, 0x689b, - 0x0904, 0x35e2, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, - 0x1000, 0x12f8, 0x080c, 0x4bb4, 0x01e0, 0x080c, 0x6a8c, 0x0118, - 0x080c, 0x6a94, 0x11b0, 0x080c, 0x690e, 0x2009, 0x0002, 0x0168, - 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x689b, 0x2009, 0x0003, - 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0x080c, 0x57d5, 0x0110, 0x9006, 0x0018, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, - 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, - 0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, - 0x080c, 0x6717, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, - 0x080c, 0x8711, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001, - 0x1981, 0x918c, 0x8000, 0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5, - 0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c, - 0x67de, 0x0904, 0x35e2, 0x080c, 0x6892, 0x0904, 0x35e2, 0x2001, - 0x1981, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db, 0xa9a0, - 0x2001, 0x1981, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4ba7, - 0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170, 0x080c, - 0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x6892, 0x1170, 0x2009, - 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, - 0x1981, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110, 0x9006, - 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, - 0x1904, 0x35e2, 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, - 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120, 0x080c, - 0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2, 0x080c, - 0x6880, 0x0904, 0x35e2, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, - 0x35b0, 0x0804, 0x45db, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, - 0xc18d, 0x2102, 0x080c, 0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118, - 0x080c, 0x6a94, 0x1170, 0x080c, 0x67de, 0x2009, 0x0002, 0x0128, - 0x080c, 0x6880, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, - 0x080c, 0x57d5, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x35b0, 0x080c, 0x4bb6, - 0x0904, 0x35e5, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x79a8, 0xd184, - 0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, - 0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, - 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, - 0x0202, 0x0804, 0x35b0, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158, - 0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x35e2, 0x625c, 0x7884, - 0x9206, 0x1904, 0x4796, 0x080c, 0x8812, 0x2001, 0xffec, 0x2009, - 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, - 0x78a8, 0x9084, 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84, - 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e, - 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000, - 0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87, - 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804, - 0x4bcf, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, - 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, - 0x10f8, 0x7007, 0x0002, 0x701f, 0x47b6, 0x0005, 0x81ff, 0x1904, - 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x1904, - 0x35e2, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0904, 0x35e2, 0xa867, - 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfb0, 0x0904, - 0x35e2, 0x7007, 0x0003, 0x701f, 0x47dc, 0x0005, 0x080c, 0x42c8, - 0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000, - 0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86, - 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa, - 0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000, - 0x003e, 0x000e, 0x0804, 0x35b0, 0xa830, 0x9086, 0x0100, 0x0904, - 0x35e2, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0x0804, 0x4bcf, 0x9006, 0x080c, 0x28f2, 0x78a8, 0x9084, 0x00ff, - 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563, - 0x0110, 0x080c, 0x60e6, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5, - 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e5, - 0x2100, 0x080c, 0x28bc, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x2061, 0x19fc, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, - 0x607f, 0x0000, 0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c, - 0x6121, 0x9085, 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x00d0, - 0x080c, 0xb058, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, - 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, - 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x600c, - 0x080c, 0x879b, 0x7984, 0x080c, 0x7563, 0x1110, 0x2009, 0x00ff, - 0x7a88, 0x080c, 0x463e, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35b0, - 0x7984, 0x080c, 0x66ac, 0x2b08, 0x1904, 0x35e5, 0x0804, 0x35b0, - 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac, - 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x080c, - 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x81ff, - 0x0904, 0x35e5, 0x9192, 0x0021, 0x1a04, 0x35e5, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, - 0x080c, 0x4bcc, 0x701f, 0x4893, 0x7880, 0x9086, 0x006e, 0x0110, - 0x701f, 0x5275, 0x0005, 0x2009, 0x0080, 0x080c, 0x6717, 0x1118, - 0x080c, 0x6a8c, 0x0120, 0x2021, 0x400a, 0x0804, 0x35b2, 0x00d6, - 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, - 0x90be, 0x0100, 0x0904, 0x492c, 0x90be, 0x0112, 0x0904, 0x492c, - 0x90be, 0x0113, 0x0904, 0x492c, 0x90be, 0x0114, 0x0904, 0x492c, - 0x90be, 0x0117, 0x0904, 0x492c, 0x90be, 0x011a, 0x0904, 0x492c, - 0x90be, 0x011c, 0x0904, 0x492c, 0x90be, 0x0121, 0x0904, 0x4913, - 0x90be, 0x0131, 0x0904, 0x4913, 0x90be, 0x0171, 0x0904, 0x492c, - 0x90be, 0x0173, 0x0904, 0x492c, 0x90be, 0x01a1, 0x1128, 0xa894, - 0x8007, 0xa896, 0x0804, 0x4937, 0x90be, 0x0212, 0x0904, 0x4920, - 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, - 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, - 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, - 0x0804, 0x35e5, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, - 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x4975, 0x7028, 0x9080, + 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, + 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, + 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, + 0x0108, 0x0005, 0x0804, 0x35ab, 0x7d98, 0x7c9c, 0x0804, 0x36af, + 0x080c, 0x7569, 0x190c, 0x60ec, 0x6040, 0x9084, 0x0020, 0x09b1, + 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd2, 0x701f, 0x4308, 0x0005, + 0x080c, 0x57e2, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, + 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x35e0, 0x6804, + 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e0, 0xd094, 0x00c6, 0x2061, + 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, + 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, + 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, + 0x1a04, 0x35e0, 0x9288, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x6166, + 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x35e0, 0x605e, + 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, + 0x2009, 0x19b3, 0x9080, 0x29d0, 0x2005, 0x200a, 0x000e, 0x2009, + 0x19b4, 0x9080, 0x29d4, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, + 0x0a04, 0x35e0, 0x908a, 0x0841, 0x1a04, 0x35e0, 0x9084, 0x0007, + 0x1904, 0x35e0, 0x680c, 0x9005, 0x0904, 0x35e0, 0x6810, 0x9005, + 0x0904, 0x35e0, 0x6848, 0x6940, 0x910a, 0x1a04, 0x35e0, 0x8001, + 0x0904, 0x35e0, 0x684c, 0x6944, 0x910a, 0x1a04, 0x35e0, 0x8001, + 0x0904, 0x35e0, 0x2009, 0x1982, 0x200b, 0x0000, 0x2001, 0x1869, + 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e52, + 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, + 0x9084, 0x00ff, 0x6052, 0x080c, 0x787f, 0x080c, 0x6ac8, 0x080c, + 0x6b2a, 0x6808, 0x602a, 0x080c, 0x23a4, 0x2009, 0x0170, 0x200b, + 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, + 0x2937, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x44a4, 0x6818, + 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, + 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, + 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, + 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, + 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, + 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, + 0x882e, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510, + 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d, + 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7e3b, + 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, + 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, + 0x6003, 0x0001, 0x1f04, 0x43f9, 0x00ce, 0x00c6, 0x2061, 0x199d, + 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, + 0x0000, 0x2001, 0x0001, 0x080c, 0x2bca, 0x2001, 0x0001, 0x080c, + 0x2bad, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, + 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0028, 0x9286, 0x8000, + 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ea3, + 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, + 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, + 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, + 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x29ac, 0x2001, + 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7569, 0x0128, 0x080c, + 0x50c9, 0x0110, 0x080c, 0x28fd, 0x60d4, 0x9005, 0x01c0, 0x6003, + 0x0001, 0x2009, 0x448c, 0x00e0, 0x080c, 0x7569, 0x1168, 0x2011, + 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x080c, + 0x7853, 0x080c, 0x7495, 0x0040, 0x080c, 0x5fe6, 0x0028, 0x6003, + 0x0004, 0x2009, 0x44a4, 0x0020, 0x080c, 0x69f4, 0x0804, 0x35ab, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x35dd, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4bd5, 0x9006, 0x080c, 0x28fd, 0x81ff, + 0x1904, 0x35dd, 0x080c, 0x7569, 0x11b0, 0x080c, 0x784e, 0x080c, + 0x6127, 0x080c, 0x33a0, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xd561, 0x0130, 0x080c, 0x758c, 0x1118, 0x080c, 0x7541, 0x0038, + 0x080c, 0x7495, 0x0020, 0x080c, 0x60ec, 0x080c, 0x5fe6, 0x0804, + 0x35ab, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x1110, 0x0804, + 0x35dd, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd5, 0x701f, 0x35a9, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x655c, + 0x9588, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x671d, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80, + 0x2099, 0x1c80, 0x080c, 0x6077, 0x0804, 0x4501, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, + 0x35dd, 0x080c, 0x57d3, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x339b, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, + 0x0003, 0x701f, 0x458c, 0x0005, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4bd5, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904, + 0x35e0, 0x080c, 0x688f, 0x0904, 0x35dd, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa974, 0xaa94, 0x0804, + 0x35ab, 0x080c, 0x57db, 0x0904, 0x35ab, 0x701f, 0x45d6, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, + 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x6914, 0x0904, + 0x35dd, 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x0904, 0x35dd, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x4bba, 0x01e0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, + 0x11b0, 0x080c, 0x6914, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x68a1, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x671d, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717, + 0x0005, 0x81ff, 0x1904, 0x35dd, 0x798c, 0x2001, 0x1981, 0x918c, + 0x8000, 0x2102, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92, + 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904, + 0x35dd, 0x080c, 0x6898, 0x0904, 0x35dd, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001, 0x1981, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0, 0x080c, + 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4, 0x2009, + 0x0002, 0x0128, 0x080c, 0x6898, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x35dd, + 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ba0, + 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a, 0x1904, + 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904, + 0x35dd, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804, + 0x45e1, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x4bad, 0x01a0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, + 0x1170, 0x080c, 0x67e4, 0x2009, 0x0002, 0x0128, 0x080c, 0x6886, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x080c, 0x57e7, 0x1904, 0x35dd, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x35ab, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158, 0xd0b4, 0x1148, + 0x939a, 0x0003, 0x1a04, 0x35dd, 0x625c, 0x7884, 0x9206, 0x1904, + 0x479c, 0x080c, 0x8818, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, + 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a, + 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000, + 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80, + 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2, + 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804, 0x4bd5, 0x000e, + 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, + 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, + 0x0002, 0x701f, 0x47bc, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x1904, 0x35dd, 0x00c6, + 0x080c, 0x4b89, 0x00ce, 0x0904, 0x35dd, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfc7, 0x0904, 0x35dd, 0x7007, + 0x0003, 0x701f, 0x47e2, 0x0005, 0x080c, 0x42ce, 0x0006, 0x0036, + 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85, + 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae, + 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000, + 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, + 0x0804, 0x35ab, 0xa830, 0x9086, 0x0100, 0x0904, 0x35dd, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, + 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bd5, + 0x9006, 0x080c, 0x28fd, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, + 0x0118, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x0110, 0x080c, + 0x60ec, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x7984, 0x9186, + 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e0, 0x2100, 0x080c, + 0x28c7, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19fc, + 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, + 0x080c, 0x7569, 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, + 0x0001, 0x080c, 0x75ad, 0x080c, 0x7495, 0x00d0, 0x080c, 0xb072, + 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, + 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, + 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x6012, 0x080c, 0x87a1, + 0x7984, 0x080c, 0x7569, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, + 0x4644, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35ab, 0x7984, 0x080c, + 0x66b2, 0x2b08, 0x1904, 0x35e0, 0x0804, 0x35ab, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c, + 0x1120, 0x2009, 0x0005, 0x0804, 0x35dd, 0x080c, 0x4b89, 0x1120, + 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984, 0x81ff, 0x0904, 0x35e0, + 0x9192, 0x0021, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4bd2, + 0x701f, 0x4899, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x527b, + 0x0005, 0x2009, 0x0080, 0x080c, 0x671d, 0x1118, 0x080c, 0x6a92, + 0x0120, 0x2021, 0x400a, 0x0804, 0x35ad, 0x00d6, 0x0096, 0xa964, + 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, + 0x0904, 0x4932, 0x90be, 0x0112, 0x0904, 0x4932, 0x90be, 0x0113, + 0x0904, 0x4932, 0x90be, 0x0114, 0x0904, 0x4932, 0x90be, 0x0117, + 0x0904, 0x4932, 0x90be, 0x011a, 0x0904, 0x4932, 0x90be, 0x011c, + 0x0904, 0x4932, 0x90be, 0x0121, 0x0904, 0x4919, 0x90be, 0x0131, + 0x0904, 0x4919, 0x90be, 0x0171, 0x0904, 0x4932, 0x90be, 0x0173, + 0x0904, 0x4932, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, + 0x0804, 0x493d, 0x90be, 0x0212, 0x0904, 0x4926, 0x90be, 0x0213, + 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, + 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, + 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x35e0, + 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0007, 0x080c, 0x497b, 0x7028, 0x9080, 0x000e, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x497b, + 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4988, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, - 0x080c, 0x4975, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, - 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4982, 0x00b8, - 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, - 0x20a9, 0x0001, 0x080c, 0x4982, 0x7028, 0x9080, 0x000c, 0x2098, - 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, - 0x080c, 0x4b83, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, - 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, - 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, - 0x009e, 0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, - 0x2048, 0x080c, 0xcfcb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, - 0x7007, 0x0003, 0x701f, 0x496c, 0x0005, 0x00ce, 0x009e, 0x00de, - 0x2009, 0x0002, 0x0804, 0x35e2, 0xa820, 0x9086, 0x8001, 0x1904, - 0x35b0, 0x2009, 0x0004, 0x0804, 0x35e2, 0x0016, 0x0026, 0x3510, - 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, - 0x001e, 0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, - 0x0004, 0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, - 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, - 0x2009, 0x0005, 0x0804, 0x35e2, 0x7984, 0x78a8, 0x2040, 0x080c, - 0xb051, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e5, 0x9186, 0x00ff, - 0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04, 0x35e5, 0x7a8c, 0x7b88, - 0x607c, 0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x35e5, 0x080c, - 0xb051, 0x1120, 0x99cc, 0xff00, 0x0904, 0x35e5, 0x0126, 0x2091, - 0x8000, 0x080c, 0x4a96, 0x0904, 0x4a16, 0x0086, 0x90c6, 0x4000, - 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, - 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, - 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, - 0x080c, 0x6a8c, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x6937, - 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, - 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, - 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, - 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, - 0x2020, 0x012e, 0x0804, 0x35b2, 0x000e, 0x00ce, 0x2b00, 0x7026, - 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb139, 0x0904, - 0x4a6b, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2e58, 0x00ee, 0x00e6, - 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb0e7, - 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, - 0x35e2, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, - 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, - 0x324b, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0xd89c, 0x0138, - 0x2001, 0x0004, 0x080c, 0x665d, 0x2009, 0x0003, 0x0030, 0x2001, - 0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c, 0xb166, 0x78a8, - 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d, - 0xb8ce, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, - 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, - 0x4a7a, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, - 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x5721, 0x900e, - 0xa868, 0xd0f4, 0x1904, 0x35b0, 0x080c, 0x6937, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b0, 0x00e6, 0x00d6, - 0x0096, 0x83ff, 0x0904, 0x4ae5, 0x902e, 0x080c, 0xb051, 0x0130, - 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, - 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, - 0x9406, 0x1904, 0x4af6, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, - 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, - 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, - 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, - 0x9106, 0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a2c, - 0x1570, 0x2001, 0x4000, 0x0460, 0x080c, 0x6a8c, 0x1540, 0x2001, - 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, - 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, - 0x080c, 0xb051, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, - 0x1f04, 0x4aac, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, - 0x0001, 0x0030, 0x080c, 0x66ac, 0x1dd0, 0xbb12, 0xba16, 0x9006, - 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, - 0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, - 0x9005, 0x0904, 0x35e5, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, - 0x1a04, 0x35e5, 0x2010, 0x2918, 0x080c, 0x31f1, 0x1120, 0x2009, - 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x4b38, 0x0005, - 0xa830, 0x9086, 0x0100, 0x1904, 0x35b0, 0x2009, 0x0004, 0x0804, - 0x35e2, 0x7984, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f, 0x0a04, - 0x35e5, 0x9186, 0x00ff, 0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04, - 0x35e5, 0x2001, 0x9400, 0x080c, 0x577c, 0x1904, 0x35e2, 0x0804, - 0x35b0, 0xa998, 0x080c, 0xb051, 0x1118, 0x9182, 0x007f, 0x0280, - 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, - 0x080c, 0x577c, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, - 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, - 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, - 0x2009, 0x000a, 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802, - 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, - 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, - 0x0001, 0x0005, 0x7984, 0x080c, 0x6717, 0x1130, 0x7e88, 0x9684, - 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, - 0x080c, 0x6717, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, - 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, - 0x080c, 0x6717, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, - 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8, - 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, - 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, - 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, - 0x701f, 0x35b0, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, - 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c00, - 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c66, - 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, - 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, - 0x080c, 0x100e, 0x0904, 0x4c5e, 0xa84b, 0x0000, 0x2900, 0x7046, - 0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0098, 0x7038, - 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, - 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, - 0x714a, 0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, - 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, - 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130, - 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, - 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, - 0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, - 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, - 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4c88, 0x4c88, 0x4c8a, - 0x4c88, 0x4c88, 0x4c88, 0x4c8e, 0x4c88, 0x4c88, 0x4c88, 0x4c92, - 0x4c88, 0x4c88, 0x4c88, 0x4c96, 0x4c88, 0x4c88, 0x4c88, 0x4c9a, - 0x4c88, 0x4c88, 0x4c88, 0x4c9e, 0x4c88, 0x4c88, 0x4c88, 0x4ca3, - 0x080c, 0x0dc5, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, - 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, - 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, - 0xa4ce, 0x0804, 0x4c61, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c61, - 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4d3a, 0x0126, - 0x2091, 0x8000, 0x0e04, 0x4d39, 0x00f6, 0x2079, 0x0000, 0x00c6, - 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, - 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, - 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d3c, - 0xa804, 0x9005, 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003, - 0x0000, 0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa04a, 0x0804, - 0x4d3c, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, - 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, - 0x87ff, 0x0118, 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a, - 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040, - 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, - 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, - 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, - 0x9006, 0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048, - 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, - 0x20e8, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, - 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, - 0x4d5b, 0x4d5b, 0x4d5d, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d62, 0x4d5b, - 0x4d5b, 0x4d5b, 0x4d67, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d6c, 0x4d5b, - 0x4d5b, 0x4d5b, 0x4d71, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d76, 0x4d5b, - 0x4d5b, 0x4d5b, 0x4d7b, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c, - 0x0804, 0x4ce7, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ce7, 0xaa94, - 0xab98, 0xac9c, 0x0804, 0x4ce7, 0xaaa4, 0xaba8, 0xacac, 0x0804, - 0x4ce7, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4ce7, 0xaac4, 0xabc8, - 0xaccc, 0x0804, 0x4ce7, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ce7, - 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, - 0x6717, 0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, - 0x2011, 0x801b, 0x080c, 0x4be3, 0x00ce, 0x00be, 0x003e, 0x002e, - 0x001e, 0x0005, 0x0026, 0x080c, 0x57cd, 0xd0c4, 0x0120, 0x2011, - 0x8014, 0x080c, 0x4be3, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35e2, - 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, - 0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085, - 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x0010, 0x080c, 0x5fe0, - 0x012e, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2, - 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804, 0x35e2, 0x7984, - 0x080c, 0x66ac, 0x1904, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5, - 0x2b00, 0x7026, 0x080c, 0x6a8c, 0x7888, 0x1170, 0x9084, 0x0005, - 0x1158, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, - 0x0108, 0xc18d, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2, - 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069, - 0x0904, 0x35e2, 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, - 0x7007, 0x0003, 0x701f, 0x4e56, 0x0005, 0x2061, 0x1800, 0x080c, - 0x57e1, 0x2009, 0x0007, 0x1560, 0x080c, 0x6a84, 0x0118, 0x2009, - 0x0008, 0x0430, 0xa998, 0x080c, 0x66ac, 0x1530, 0x080c, 0x4bb4, - 0x0518, 0x080c, 0x6a8c, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, - 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, - 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd069, 0x11e0, - 0xa89c, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, - 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, - 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, - 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5721, 0x900e, 0x080c, - 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, - 0x35b0, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2, - 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b83, 0x1120, - 0x2009, 0x0002, 0x0804, 0x35e2, 0x900e, 0x2130, 0x7126, 0x7132, - 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, - 0x080c, 0x6717, 0x1904, 0x4eff, 0x080c, 0x6a8c, 0x0138, 0x080c, - 0x6a94, 0x0120, 0x080c, 0x6a2c, 0x1904, 0x4eff, 0xd794, 0x1110, - 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, - 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, - 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x4982, 0x0080, 0xb8c4, - 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, - 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4982, 0x9186, - 0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6a8c, 0x90c2, - 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6937, 0x1108, 0xc1fd, - 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, - 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, - 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, - 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, - 0x4975, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, - 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, - 0x080c, 0xb051, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, - 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, - 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, - 0x4e88, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x35b0, 0x7033, - 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, - 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, - 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, - 0x701f, 0x4f3b, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, - 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, - 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4e88, 0x7124, 0x810b, - 0x0804, 0x35b0, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, - 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, - 0x0a04, 0x35e5, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5, - 0x9502, 0x0a04, 0x35e5, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, - 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9284, 0x00ff, 0x90e2, - 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9384, 0xff00, - 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, - 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, - 0x35e5, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, - 0x9502, 0x0a04, 0x35e5, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, - 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x2061, 0x198a, 0x6102, 0x6206, - 0x630a, 0x640e, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2, - 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, - 0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x4fbf, 0x0005, 0x2001, - 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, - 0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, - 0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, - 0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, - 0x5040, 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x5040, 0x680c, - 0x9005, 0x0904, 0x5040, 0x9082, 0xff01, 0x1a04, 0x5040, 0x6810, - 0x9082, 0x005c, 0x0a04, 0x5040, 0x6824, 0x2008, 0x9082, 0x0008, - 0x0a04, 0x5040, 0x9182, 0x0400, 0x1a04, 0x5040, 0x0056, 0x2029, - 0x0000, 0x080c, 0x8d43, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, - 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, - 0x0678, 0x6840, 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900, - 0x0904, 0x505c, 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, - 0x0000, 0x080c, 0x8bff, 0x00be, 0x00ee, 0x0568, 0x080c, 0x894a, - 0x080c, 0x8999, 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, - 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a, - 0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b0, - 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35e5, 0x080c, - 0x8992, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2, - 0x080c, 0x8be2, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040, - 0x2001, 0x188a, 0x2003, 0x0000, 0x080c, 0x29a1, 0x2001, 0x0138, - 0x2102, 0x0804, 0x35e2, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, - 0x0904, 0x50c1, 0x080c, 0x8bdd, 0x0904, 0x50c1, 0x2001, 0x0101, - 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, - 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, - 0x8be2, 0x0126, 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611, - 0x012e, 0x00c6, 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, - 0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, - 0x2071, 0x1925, 0x080c, 0x8b1c, 0x0120, 0x2f00, 0x080c, 0x8ba8, - 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, - 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a, - 0x2003, 0x0000, 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8992, - 0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2, 0x00ee, - 0x012e, 0x0804, 0x35b0, 0x0006, 0x080c, 0x57cd, 0xd0cc, 0x000e, - 0x0005, 0x0006, 0x080c, 0x57d1, 0xd0bc, 0x000e, 0x0005, 0x6174, - 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x35b0, 0x83ff, - 0x1904, 0x35e5, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e5, 0x2019, - 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35e5, 0x7986, 0x6276, - 0x0804, 0x35b0, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x7c88, 0x7d84, - 0x7e98, 0x7f8c, 0x080c, 0x4b83, 0x0904, 0x35e2, 0x900e, 0x901e, - 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, - 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, - 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1148, 0x20a9, 0x0001, 0xb814, - 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, - 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, - 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804, - 0x35b0, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, - 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, - 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, - 0x0002, 0x701f, 0x5144, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, - 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, - 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x5102, 0x7224, 0x900e, - 0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804, 0x35b0, 0x00f6, - 0x00e6, 0x080c, 0x57e1, 0x2009, 0x0007, 0x1904, 0x51d7, 0x2071, - 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x51d7, 0xac9c, - 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, - 0x0904, 0x51d7, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, - 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, - 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c, 0x0118, 0x080c, - 0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, - 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, - 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, - 0x0003, 0x080c, 0x91ab, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, - 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, - 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, - 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, - 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, - 0x51e3, 0x000e, 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, - 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, - 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, - 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, - 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, - 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab, - 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, - 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6dcb, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, - 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c, - 0x0118, 0x080c, 0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, - 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, - 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, - 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, - 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, - 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, - 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, - 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, - 0x080c, 0x10f8, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, - 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, - 0x009e, 0x0804, 0x35e5, 0xa884, 0xa988, 0x080c, 0x2889, 0x1518, - 0x080c, 0x66ac, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, - 0x4b83, 0x01c8, 0x080c, 0x4b83, 0x01b0, 0x009e, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, - 0xcfeb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, - 0x701f, 0x52b0, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35e2, - 0x7124, 0x080c, 0x3347, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, - 0x0004, 0x0804, 0x35e2, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, - 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, - 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, - 0x20a9, 0x002a, 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, - 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, - 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, - 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4bcf, 0x97c6, 0x7200, - 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, - 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, - 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x530c, 0x0005, - 0x000e, 0x007e, 0x0804, 0x35e5, 0x7020, 0x2048, 0xa804, 0x2048, - 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, - 0x002a, 0x080c, 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, - 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bcf, - 0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, - 0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120, - 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2, - 0x0126, 0x2091, 0x8000, 0x080c, 0x68a4, 0x012e, 0x0904, 0x35e2, - 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db, - 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, - 0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170, - 0x080c, 0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x68a4, 0x1170, - 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x080c, 0x4988, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, + 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4b89, + 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, + 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, + 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, + 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, + 0xcfe2, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, + 0x701f, 0x4972, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, + 0x0804, 0x35dd, 0xa820, 0x9086, 0x8001, 0x1904, 0x35ab, 0x2009, + 0x0004, 0x0804, 0x35dd, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, + 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, + 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, + 0x0804, 0x35dd, 0x7984, 0x78a8, 0x2040, 0x080c, 0xb06b, 0x1120, + 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186, 0x00ff, 0x0904, 0x35e0, + 0x9182, 0x0800, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x607c, 0x9306, + 0x1158, 0x6080, 0x924e, 0x0904, 0x35e0, 0x080c, 0xb06b, 0x1120, + 0x99cc, 0xff00, 0x0904, 0x35e0, 0x0126, 0x2091, 0x8000, 0x080c, + 0x4a9c, 0x0904, 0x4a1c, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, + 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, + 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, + 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6a92, + 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, + 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, + 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, + 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, + 0x0804, 0x35ad, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, + 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb153, 0x0904, 0x4a71, 0x2b00, + 0x6012, 0x080c, 0xd2d2, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, + 0x4b89, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb101, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x900e, + 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3246, 0x6023, + 0x0001, 0x9006, 0x080c, 0x664f, 0xd89c, 0x0138, 0x2001, 0x0004, + 0x080c, 0x6663, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, + 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0x78a8, 0xd094, 0x0138, + 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, + 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, + 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x4a80, 0x0005, + 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, + 0xba04, 0x9294, 0x00ff, 0x0804, 0x5727, 0x900e, 0xa868, 0xd0f4, + 0x1904, 0x35ab, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x0804, 0x35ab, 0x00e6, 0x00d6, 0x0096, 0x83ff, + 0x0904, 0x4aeb, 0x902e, 0x080c, 0xb06b, 0x0130, 0x9026, 0x20a9, + 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, + 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, + 0x4afc, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, + 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, + 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, + 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, + 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a32, 0x1570, 0x2001, + 0x4000, 0x0460, 0x080c, 0x6a92, 0x1540, 0x2001, 0x4000, 0x0430, + 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, + 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xb06b, + 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4ab2, + 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, + 0x080c, 0x66b2, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, + 0x35e0, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x35e0, + 0x2010, 0x2918, 0x080c, 0x31ec, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x4b3e, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1904, 0x35ab, 0x2009, 0x0004, 0x0804, 0x35dd, 0x7984, + 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186, + 0x00ff, 0x0904, 0x35e0, 0x9182, 0x0800, 0x1a04, 0x35e0, 0x2001, + 0x9400, 0x080c, 0x5782, 0x1904, 0x35dd, 0x0804, 0x35ab, 0xa998, + 0x080c, 0xb06b, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, + 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x5782, + 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110, - 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, - 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x4550, 0x080c, 0x4bb6, - 0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e2, 0x080c, 0x6a8c, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, - 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, - 0x0028, 0x080c, 0x57cd, 0xd0b4, 0x0904, 0x458a, 0x7884, 0x908e, - 0x007e, 0x0904, 0x458a, 0x908e, 0x007f, 0x0904, 0x458a, 0x908e, - 0x0080, 0x0904, 0x458a, 0xb800, 0xd08c, 0x1904, 0x458a, 0xa867, - 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009, - 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x53d8, 0x0005, - 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x458a, 0x080c, 0x33a0, - 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, - 0x0804, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804, - 0x35e2, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x458a, 0x9006, - 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069, 0x1120, - 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5411, - 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, - 0x5721, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x53aa, 0x81ff, - 0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009, 0x0007, - 0x1904, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804, - 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x2009, - 0x0009, 0x1904, 0x35e2, 0x080c, 0x4b83, 0x2009, 0x0002, 0x0904, - 0x35e2, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, - 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, - 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, - 0x35e5, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2bc, 0x2009, - 0x0003, 0x0904, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5468, 0x0005, - 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35e2, 0x0804, - 0x35b0, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, - 0x57e1, 0x1188, 0x2009, 0x0014, 0x0804, 0x35e2, 0xd2dc, 0x1578, - 0x81ff, 0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009, - 0x0007, 0x1904, 0x35e2, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, - 0x080c, 0x57a7, 0x0804, 0x35b0, 0xd2fc, 0x0160, 0x080c, 0x4bb6, - 0x0904, 0x35e5, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c, - 0x0804, 0x35b0, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5557, 0x080c, - 0x4b83, 0x2009, 0x0002, 0x0904, 0x5557, 0xa85c, 0x9080, 0x001b, - 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, - 0x4bcc, 0x701f, 0x54c4, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, - 0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, - 0x35e5, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bb6, - 0x1110, 0x0804, 0x35e5, 0x2009, 0x0043, 0x080c, 0xd328, 0x2009, - 0x0003, 0x0904, 0x5557, 0x7007, 0x0003, 0x701f, 0x54e8, 0x0005, - 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5557, 0x7984, - 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, 0x577c, 0x0804, 0x35b0, - 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, - 0x57e1, 0x1158, 0x2009, 0x0014, 0x0804, 0x5546, 0x2061, 0x1800, - 0x080c, 0x57e1, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, - 0x5000, 0xc0d5, 0x080c, 0x57a7, 0x0058, 0xd2fc, 0x0180, 0x080c, - 0x4bb4, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c, - 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, - 0x4bb4, 0x0510, 0x080c, 0x6a8c, 0x2009, 0x0009, 0x11b8, 0xa8c4, - 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, - 0xff00, 0x1190, 0x080c, 0x4bb4, 0x1108, 0x0070, 0x2009, 0x004b, - 0x080c, 0xd328, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, + 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, + 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, + 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, + 0x7984, 0x080c, 0x671d, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x671d, + 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, + 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x671d, + 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, + 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8, 0x7116, 0x711a, + 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, + 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x35ab, + 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, + 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c06, 0x7a36, 0x7833, + 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c6c, 0x0016, 0x0086, + 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, + 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x100e, + 0x0904, 0x4c64, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, + 0x9080, 0x20f0, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, + 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, + 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, + 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, + 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, 0x8108, 0x2105, + 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130, 0x8109, 0xa946, + 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, + 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, + 0x20f0, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, + 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, + 0x9082, 0x001b, 0x0002, 0x4c8e, 0x4c8e, 0x4c90, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4c94, 0x4c8e, 0x4c8e, 0x4c8e, 0x4c98, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4c9c, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca0, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4ca4, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca9, 0x080c, 0x0dc5, + 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, + 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, + 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, + 0x4c67, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c67, 0x00e6, 0x2071, + 0x189e, 0x7048, 0x9005, 0x0904, 0x4d40, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x4d3f, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, + 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, + 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, + 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d42, 0xa804, 0x9005, + 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, + 0x0002, 0x9080, 0x20f0, 0x2005, 0xa04a, 0x0804, 0x4d42, 0x703c, + 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, + 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x87ff, 0x0118, + 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, + 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040, 0x9006, 0x7042, + 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, + 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, + 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, + 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048, 0xa800, 0x9005, + 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x20f0, 0x2005, + 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, + 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4d61, 0x4d61, + 0x4d63, 0x4d61, 0x4d61, 0x4d61, 0x4d68, 0x4d61, 0x4d61, 0x4d61, + 0x4d6d, 0x4d61, 0x4d61, 0x4d61, 0x4d72, 0x4d61, 0x4d61, 0x4d61, + 0x4d77, 0x4d61, 0x4d61, 0x4d61, 0x4d7c, 0x4d61, 0x4d61, 0x4d61, + 0x4d81, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4ced, + 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ced, 0xaa94, 0xab98, 0xac9c, + 0x0804, 0x4ced, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4ced, 0xaab4, + 0xabb8, 0xacbc, 0x0804, 0x4ced, 0xaac4, 0xabc8, 0xaccc, 0x0804, + 0x4ced, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ced, 0x0016, 0x0026, + 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x671d, 0x2019, + 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, + 0x080c, 0x4be9, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0026, 0x080c, 0x57d3, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, + 0x4be9, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x7569, + 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x080c, 0x7495, 0x0010, 0x080c, 0x5fe6, 0x012e, 0x0804, + 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x080c, 0x6a8a, + 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x7984, 0x080c, 0x66b2, + 0x1904, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x2b00, 0x7026, + 0x080c, 0x6a92, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, + 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, + 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x9006, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x0904, 0x35dd, + 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003, + 0x701f, 0x4e5c, 0x0005, 0x2061, 0x1800, 0x080c, 0x57e7, 0x2009, + 0x0007, 0x1560, 0x080c, 0x6a8a, 0x0118, 0x2009, 0x0008, 0x0430, + 0xa998, 0x080c, 0x66b2, 0x1530, 0x080c, 0x4bba, 0x0518, 0x080c, + 0x6a92, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, + 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, + 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd080, 0x11e0, 0xa89c, 0xd094, + 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, + 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, + 0x2058, 0x1110, 0x0804, 0x5727, 0x900e, 0x080c, 0x693d, 0x1108, + 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35ab, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7f84, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, + 0x0804, 0x35dd, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, + 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x671d, + 0x1904, 0x4f05, 0x080c, 0x6a92, 0x0138, 0x080c, 0x6a9a, 0x0120, + 0x080c, 0x6a32, 0x1904, 0x4f05, 0xd794, 0x1110, 0xd784, 0x01a8, + 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, + 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, + 0x20a9, 0x0002, 0x080c, 0x4988, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, + 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, + 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4988, 0x9186, 0x007e, 0x0170, + 0x9186, 0x0080, 0x0158, 0x080c, 0x6a92, 0x90c2, 0x0006, 0x1210, + 0xc1fd, 0x0020, 0x080c, 0x693d, 0x1108, 0xc1fd, 0x4104, 0xc1fc, + 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, + 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, + 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, + 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x497b, 0x9c80, + 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, + 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xb06b, + 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, + 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, + 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4e8e, 0x86ff, + 0x1120, 0x7124, 0x810b, 0x0804, 0x35ab, 0x7033, 0x0001, 0x7122, + 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, + 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x4f41, + 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, + 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x0804, 0x4e8e, 0x7124, 0x810b, 0x0804, 0x35ab, + 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, + 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, + 0x35e0, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, + 0x9502, 0x0a04, 0x35e0, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, + 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0xff00, 0x8007, 0x90e2, + 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0x00ff, + 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9484, + 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, + 0x35e0, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, + 0x0a04, 0x35e0, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, + 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x2009, 0x0016, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, + 0x080c, 0x4bd2, 0x701f, 0x4fc5, 0x0005, 0x2001, 0x0138, 0x2003, + 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, + 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, + 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, + 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5046, 0x6804, + 0x2008, 0x918c, 0xfff8, 0x1904, 0x5046, 0x680c, 0x9005, 0x0904, + 0x5046, 0x9082, 0xff01, 0x1a04, 0x5046, 0x6810, 0x9082, 0x005c, + 0x0a04, 0x5046, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5046, + 0x9182, 0x0400, 0x1a04, 0x5046, 0x0056, 0x2029, 0x0000, 0x080c, + 0x8d49, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, + 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, + 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900, 0x0904, 0x5062, + 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, + 0x8c05, 0x00be, 0x00ee, 0x0568, 0x080c, 0x8950, 0x080c, 0x899f, + 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, + 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a, 0x00ce, 0x080c, + 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804, 0x35ab, 0x080c, 0x29ac, + 0x2001, 0x0138, 0x2102, 0x0804, 0x35e0, 0x080c, 0x8998, 0x00e6, + 0x2071, 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x080c, 0x8be8, + 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040, 0x2001, 0x188a, + 0x2003, 0x0000, 0x080c, 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804, + 0x35dd, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x50c7, + 0x080c, 0x8be3, 0x0904, 0x50c7, 0x2001, 0x0101, 0x200c, 0x918c, + 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, + 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8be8, 0x0126, + 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611, 0x012e, 0x00c6, + 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, + 0x29ac, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, + 0x080c, 0x8b22, 0x0120, 0x2f00, 0x080c, 0x8bae, 0x0cc8, 0x00fe, + 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, + 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a, 0x2003, 0x0000, + 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8998, 0x00e6, 0x2071, + 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x00ee, 0x012e, 0x0804, + 0x35ab, 0x0006, 0x080c, 0x57d3, 0xd0cc, 0x000e, 0x0005, 0x0006, + 0x080c, 0x57d7, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, + 0x82ff, 0x1118, 0x7986, 0x0804, 0x35ab, 0x83ff, 0x1904, 0x35e0, + 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e0, 0x2019, 0xffff, 0x6078, + 0x9302, 0x9200, 0x0a04, 0x35e0, 0x7986, 0x6276, 0x0804, 0x35ab, + 0x080c, 0x57e7, 0x1904, 0x35dd, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, + 0x080c, 0x4b89, 0x0904, 0x35dd, 0x900e, 0x901e, 0x7326, 0x7332, + 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, + 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, + 0x080c, 0x6a9a, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, + 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, + 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, + 0x2001, 0x0003, 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x7033, + 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, + 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, + 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, + 0x514a, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, + 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, + 0xa694, 0xa798, 0x0804, 0x5108, 0x7224, 0x900e, 0x2001, 0x0003, + 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x00f6, 0x00e6, 0x080c, + 0x57e7, 0x2009, 0x0007, 0x1904, 0x51dd, 0x2071, 0x189e, 0x745c, + 0x84ff, 0x2009, 0x000e, 0x1904, 0x51dd, 0xac9c, 0xad98, 0xaea4, + 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, 0x0904, 0x51dd, + 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, + 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, + 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1148, + 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, + 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, + 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, + 0x91b1, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, + 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, + 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, + 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x51e9, 0x000e, + 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, + 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0x00e6, 0x2071, + 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, + 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91b1, 0xaa9a, 0x715c, + 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x705f, 0x0000, + 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, + 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c, + 0x6a9a, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, + 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, + 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0xa09f, 0x0000, + 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, + 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, + 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, + 0x35e0, 0xa884, 0xa988, 0x080c, 0x2894, 0x1518, 0x080c, 0x66b2, + 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4b89, 0x01c8, + 0x080c, 0x4b89, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xd002, 0x1120, + 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x52b6, + 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7124, 0x080c, + 0x3342, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, + 0x35dd, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, + 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, + 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, + 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, + 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, + 0x000e, 0x007e, 0x0804, 0x4bd5, 0x97c6, 0x7200, 0x11b8, 0x96c2, + 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, + 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, + 0x10f8, 0x7007, 0x0002, 0x701f, 0x5312, 0x0005, 0x000e, 0x007e, + 0x0804, 0x35e0, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bd5, 0x81ff, 0x1904, + 0x35dd, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, + 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a, + 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x080c, 0x68aa, 0x012e, 0x0904, 0x35dd, 0x2001, 0x197f, + 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001, + 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0, + 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4, + 0x2009, 0x0002, 0x0128, 0x080c, 0x68aa, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, - 0xd2dc, 0x0904, 0x35e2, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, - 0x080c, 0x577c, 0x001e, 0x1904, 0x35e2, 0x0804, 0x35b0, 0x00f6, - 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, - 0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x577c, - 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, - 0x35e2, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904, - 0x35e5, 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009, - 0x0009, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, - 0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, - 0x0100, 0x8007, 0xa80a, 0x080c, 0xd024, 0x1120, 0x2009, 0x0003, - 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x55b7, 0x0005, 0xa808, - 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35e2, - 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, - 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, - 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x080c, 0x4b83, - 0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x9194, 0xff00, - 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, - 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e5, - 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, - 0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x5607, 0x0005, 0x2001, - 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, - 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, - 0x0804, 0x35b0, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e2, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, - 0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, - 0x19cf, 0x0010, 0x0804, 0x35e5, 0xa85c, 0x9080, 0x0019, 0x20a0, - 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, - 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x0804, 0x4bcf, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e5, - 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, - 0x2061, 0x19fc, 0x614a, 0x00ce, 0x012e, 0x0804, 0x35b0, 0x00c6, - 0x080c, 0x7563, 0x1160, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085, - 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x080c, 0x0dc5, 0x2061, - 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5fe0, 0x00ce, 0x0005, - 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35e2, - 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, - 0x080c, 0x2c6b, 0x01a0, 0x080c, 0x2c73, 0x0188, 0x080c, 0x2c7b, - 0x0170, 0x2162, 0x0804, 0x35e5, 0x2061, 0x0100, 0x6038, 0x9086, - 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, - 0x9086, 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, - 0x0026, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c, - 0xa8dd, 0x002e, 0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d, - 0x003e, 0x60e3, 0x0000, 0x080c, 0xed95, 0x080c, 0xedb0, 0x9085, - 0x0001, 0x080c, 0x75a7, 0x9006, 0x080c, 0x2d5b, 0x2001, 0x1800, - 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x6027, 0x0008, - 0x00ce, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2, - 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904, 0x35e5, - 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009, 0x0009, - 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd027, - 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, - 0x570a, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, - 0x0804, 0x35e2, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, - 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, - 0x4bcf, 0xa898, 0x9086, 0x000d, 0x1904, 0x35e2, 0x2021, 0x4005, - 0x0126, 0x2091, 0x8000, 0x0e04, 0x572e, 0x0010, 0x012e, 0x0cc0, - 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, - 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, - 0x799e, 0x080c, 0x4bbf, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, - 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, - 0x19fc, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, - 0x7898, 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, - 0x2001, 0x1a0c, 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072, - 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, - 0x00ce, 0x012e, 0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x00b6, - 0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, - 0x2019, 0x0029, 0x080c, 0x3365, 0x003e, 0x080c, 0xce8c, 0x000e, - 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, - 0x080c, 0x613b, 0x080c, 0xb051, 0x0110, 0xb817, 0x0000, 0x9006, - 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, - 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, - 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, - 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, - 0x0128, 0x0026, 0x2200, 0x080c, 0x577c, 0x002e, 0x001e, 0x8108, - 0x1f04, 0x57af, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, - 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, - 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, - 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, - 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, - 0x0005, 0x79a4, 0x81ff, 0x0904, 0x35e5, 0x9182, 0x0081, 0x1a04, - 0x35e5, 0x810c, 0x0016, 0x080c, 0x4b83, 0x0170, 0x080c, 0x0f16, - 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, - 0x4bcc, 0x701f, 0x5811, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, - 0x35e2, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, - 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, - 0x080c, 0x4bcf, 0x701f, 0x5825, 0x0005, 0x2061, 0x18b8, 0x2c44, - 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, - 0x080c, 0x0fcb, 0x9006, 0xa802, 0xa806, 0x0804, 0x35b0, 0x0126, - 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, - 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x59e0, 0x0068, 0xd08c, - 0x0118, 0x080c, 0x58e9, 0x0040, 0xd094, 0x0118, 0x080c, 0x58b9, - 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, - 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, - 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, - 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, - 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, - 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, - 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, - 0x609d, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, - 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, - 0x70df, 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, - 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5f83, 0x080c, 0x879b, - 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, - 0x7088, 0x9005, 0x1528, 0x2011, 0x5f83, 0x080c, 0x8703, 0x6040, - 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, - 0xd08c, 0x1168, 0x1f04, 0x58cf, 0x6242, 0x709b, 0x0000, 0x6040, - 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, - 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6126, 0x0000, - 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, - 0x58f3, 0x5944, 0x59df, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, - 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, - 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5902, - 0x080c, 0x0dc5, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, - 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, - 0x6102, 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, - 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, - 0x0004, 0x4003, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00, - 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, - 0x000c, 0x600f, 0x0000, 0x080c, 0x5fb4, 0x00fe, 0x9006, 0x7092, - 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, - 0x9025, 0x0904, 0x59bc, 0x6020, 0xd0b4, 0x1904, 0x59ba, 0x71a0, - 0x81ff, 0x0904, 0x59a8, 0x9486, 0x000c, 0x1904, 0x59b5, 0x9480, - 0x0018, 0x8004, 0x20a8, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2019, - 0x1c00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, - 0x5961, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, - 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, - 0x0002, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x080c, - 0x6102, 0x04c0, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7930, 0x918e, - 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, - 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x60fb, 0x2011, 0x026e, - 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, - 0x11a0, 0x8210, 0x8318, 0x1f04, 0x599c, 0x0078, 0x70a3, 0x0000, - 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, - 0x20a1, 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, - 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, - 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099, - 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, - 0x60c3, 0x000c, 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, - 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4f4, 0x08d8, 0x0005, - 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a11, - 0x5a24, 0x5a4d, 0x5a6d, 0x5a93, 0x5ac2, 0x5ae8, 0x5b20, 0x5b46, - 0x5b74, 0x5baf, 0x5be7, 0x5c05, 0x5c30, 0x5c52, 0x5c6d, 0x5c77, - 0x5cab, 0x5cd1, 0x5d00, 0x5d26, 0x5d5e, 0x5da2, 0x5ddf, 0x5e00, - 0x5e59, 0x5e7b, 0x5ea9, 0x5ea9, 0x00c6, 0x2061, 0x1800, 0x6003, - 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, - 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, - 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, - 0x5f8a, 0x080c, 0x879b, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, - 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x60fb, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0010, 0x080c, 0x5c77, - 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, - 0x6043, 0x0004, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x080c, 0x607f, - 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, - 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a62, 0x60c3, - 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, - 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, - 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, - 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, - 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x607f, - 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb, - 0x080c, 0x60de, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, - 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c, - 0x60b4, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, - 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, - 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x0007, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, - 0x1104, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8, - 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, - 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, - 0x5f37, 0x0180, 0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, + 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, + 0x1118, 0xd084, 0x0904, 0x4556, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x080c, + 0x6a92, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, + 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, + 0x57d3, 0xd0b4, 0x0904, 0x4590, 0x7884, 0x908e, 0x007e, 0x0904, + 0x4590, 0x908e, 0x007f, 0x0904, 0x4590, 0x908e, 0x0080, 0x0904, + 0x4590, 0xb800, 0xd08c, 0x1904, 0x4590, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x53de, 0x0005, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x0804, 0x4590, 0x080c, 0x339b, 0x0108, 0x0005, + 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, + 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0xb89c, + 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4590, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x1120, 0x2009, 0x0003, + 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5417, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5727, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x0804, 0x53b0, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904, 0x35dd, + 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x2009, 0x0009, 0x1904, + 0x35dd, 0x080c, 0x4b89, 0x2009, 0x0002, 0x0904, 0x35dd, 0x9006, + 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, + 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, + 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x35e0, 0xc0e5, + 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2d3, 0x2009, 0x0003, 0x0904, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x546e, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x7aa8, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x57e7, 0x1188, + 0x2009, 0x0014, 0x0804, 0x35dd, 0xd2dc, 0x1578, 0x81ff, 0x2009, + 0x0001, 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904, + 0x35dd, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57ad, + 0x0804, 0x35ab, 0xd2fc, 0x0160, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab, + 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x2009, 0x0009, 0x1904, 0x555d, 0x080c, 0x4b89, 0x2009, + 0x0002, 0x0904, 0x555d, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, + 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4bd2, 0x701f, + 0x54ca, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, + 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x35e0, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bbc, 0x1110, 0x0804, + 0x35e0, 0x2009, 0x0043, 0x080c, 0xd33f, 0x2009, 0x0003, 0x0904, + 0x555d, 0x7007, 0x0003, 0x701f, 0x54ee, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x555d, 0x7984, 0x7aa8, 0x9284, + 0x1000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab, 0x00c6, 0xaab0, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x57e7, 0x1158, + 0x2009, 0x0014, 0x0804, 0x554c, 0x2061, 0x1800, 0x080c, 0x57e7, + 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, + 0x080c, 0x57ad, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bba, 0x0590, + 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bba, 0x0510, + 0x080c, 0x6a92, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, + 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, + 0x080c, 0x4bba, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd33f, + 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, + 0x35dd, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5782, + 0x001e, 0x1904, 0x35dd, 0x0804, 0x35ab, 0x00f6, 0x2d78, 0xaab0, + 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, + 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x5782, 0x001e, 0x9085, + 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, + 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984, + 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186, + 0x007f, 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804, + 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, + 0xa80a, 0x080c, 0xd03b, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, + 0x7007, 0x0003, 0x701f, 0x55bd, 0x0005, 0xa808, 0x8007, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa8e0, 0xa866, + 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x0804, 0x4bd5, 0x080c, 0x4b89, 0x1120, 0x2009, + 0x0002, 0x0804, 0x35dd, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, + 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, + 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e0, 0x2009, 0x001a, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, + 0x080c, 0x4bd2, 0x701f, 0x560d, 0x0005, 0x2001, 0x182e, 0x2003, + 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, + 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x35ab, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984, + 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, + 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, + 0x0804, 0x35e0, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, + 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, + 0x4bd5, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x0126, 0x2091, + 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19fc, + 0x614a, 0x00ce, 0x012e, 0x0804, 0x35ab, 0x00c6, 0x080c, 0x7569, + 0x1160, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x080c, 0x7495, 0x080c, 0x0dc5, 0x2061, 0x1800, 0x6030, + 0xc09d, 0x6032, 0x080c, 0x5fe6, 0x00ce, 0x0005, 0x00c6, 0x2001, + 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35dd, 0x7884, 0x9005, + 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2c62, + 0x01a0, 0x080c, 0x2c6a, 0x0188, 0x080c, 0x2c72, 0x0170, 0x2162, + 0x0804, 0x35e0, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, + 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, + 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011, + 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7, 0x002e, + 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877, 0x003e, 0x60e3, + 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2001, 0x1800, 0x2003, 0x0004, + 0x2001, 0x19a9, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804, + 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186, 0x007f, + 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804, 0x35dd, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd03e, 0x1120, 0x2009, + 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5710, 0x0005, + 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd, + 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4bd5, 0xa898, + 0x9086, 0x000d, 0x1904, 0x35dd, 0x2021, 0x4005, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x5734, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, + 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, + 0x4bc5, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19fc, 0x7984, + 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, + 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a0c, + 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, + 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, + 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, + 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029, + 0x080c, 0x3360, 0x003e, 0x080c, 0xcea3, 0x000e, 0x1198, 0xd0e4, + 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x6141, + 0x080c, 0xb06b, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, + 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, + 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, + 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, + 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, + 0x2200, 0x080c, 0x5782, 0x002e, 0x001e, 0x8108, 0x1f04, 0x57b5, + 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, + 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, + 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, + 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, + 0x81ff, 0x0904, 0x35e0, 0x9182, 0x0081, 0x1a04, 0x35e0, 0x810c, + 0x0016, 0x080c, 0x4b89, 0x0170, 0x080c, 0x0f16, 0x2100, 0x2238, + 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4bd2, 0x701f, + 0x5817, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2079, + 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, + 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, 0x080c, 0x4bd5, + 0x701f, 0x582b, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, + 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, 0x080c, 0x0fcb, + 0x9006, 0xa802, 0xa806, 0x0804, 0x35ab, 0x0126, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, + 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, + 0xd084, 0x0118, 0x080c, 0x59e6, 0x0068, 0xd08c, 0x0118, 0x080c, + 0x58ef, 0x0040, 0xd094, 0x0118, 0x080c, 0x58bf, 0x0018, 0xd09c, + 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, + 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, + 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, + 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, + 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, + 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x00f0, + 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, + 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, + 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, + 0x2009, 0x000f, 0x2011, 0x5f89, 0x080c, 0x87a1, 0x0005, 0x2001, + 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, + 0x1528, 0x2011, 0x5f89, 0x080c, 0x8709, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, + 0x1f04, 0x58d5, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, + 0x708f, 0x0000, 0x9006, 0x080c, 0x612c, 0x0000, 0x0005, 0x708c, + 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x58f9, 0x594a, + 0x59e5, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, + 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, + 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5908, 0x080c, 0x0dc5, + 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, + 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x6108, 0x2079, + 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, + 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, + 0x0000, 0x080c, 0x5fba, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, + 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, + 0x59c2, 0x6020, 0xd0b4, 0x1904, 0x59c0, 0x71a0, 0x81ff, 0x0904, + 0x59ae, 0x9486, 0x000c, 0x1904, 0x59bb, 0x9480, 0x0018, 0x8004, + 0x20a8, 0x080c, 0x6101, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, + 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5967, 0x6043, + 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, + 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, + 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x080c, 0x6108, 0x04c0, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, + 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, + 0x9005, 0x0190, 0x080c, 0x6101, 0x2011, 0x026e, 0x2019, 0x1805, + 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, + 0x8318, 0x1f04, 0x59a2, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6101, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, + 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, + 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, + 0x1db8, 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, + 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x080c, 0xa50e, 0x08d8, 0x0005, 0x7098, 0x908a, + 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a17, 0x5a2a, 0x5a53, + 0x5a73, 0x5a99, 0x5ac8, 0x5aee, 0x5b26, 0x5b4c, 0x5b7a, 0x5bb5, + 0x5bed, 0x5c0b, 0x5c36, 0x5c58, 0x5c73, 0x5c7d, 0x5cb1, 0x5cd7, + 0x5d06, 0x5d2c, 0x5d64, 0x5da8, 0x5de5, 0x5e06, 0x5e5f, 0x5e81, + 0x5eaf, 0x5eaf, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, + 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, + 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, + 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5f90, 0x080c, + 0x87a1, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, + 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x709b, 0x0010, 0x080c, 0x5c7d, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, + 0x2011, 0x5f90, 0x080c, 0x8709, 0x080c, 0x6085, 0x2079, 0x0240, + 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, + 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a68, 0x60c3, 0x0014, 0x080c, + 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x6085, 0x2079, 0x0240, + 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, + 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, + 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703, - 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, - 0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0009, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, - 0x0100, 0x080c, 0x60de, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, - 0x5eaa, 0x1188, 0x9085, 0x0001, 0x080c, 0x28f2, 0x20a9, 0x0008, - 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x0010, - 0x080c, 0x5a04, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, - 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x1560, 0x080c, - 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, - 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, - 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, - 0x080c, 0x5c52, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, - 0x709b, 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, - 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x607f, 0x2079, 0x0240, - 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x60de, 0x0118, 0x2013, - 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, - 0x2009, 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, + 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0007, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, + 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005, + 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180, + 0x080c, 0x50cf, 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, + 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, + 0x6085, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, + 0x60e4, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5eb0, 0x1188, + 0x9085, 0x0001, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x080c, 0x6101, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x0010, 0x080c, 0x5a0a, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x9086, 0x0014, 0x1560, 0x080c, 0x6101, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, + 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, + 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5c58, + 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, + 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, + 0xffff, 0x4304, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1106, + 0x7837, 0x0000, 0x080c, 0x60e4, 0x0118, 0x2013, 0x0000, 0x0020, + 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, + 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, + 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5bda, 0x60c3, + 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x01c0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1178, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, + 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, + 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x6085, + 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6101, + 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, + 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, + 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c1e, + 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, + 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, + 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x6057, + 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, + 0x918d, 0x0001, 0x080c, 0x612c, 0x709b, 0x000f, 0x7093, 0x0000, + 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, + 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f90, + 0x080c, 0x86fd, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, + 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, + 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x60e4, 0x11a0, + 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, + 0x080c, 0x2894, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, + 0x2011, 0x0008, 0x080c, 0x5f3d, 0x60c3, 0x0014, 0x080c, 0x5fba, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, + 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, + 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, + 0x709b, 0x0013, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1103, + 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x1170, 0x7084, + 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, + 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, + 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, + 0x6093, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, + 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, + 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d, 0x918c, 0xff00, + 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180, 0x080c, 0x50cf, + 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, + 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, + 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x15a8, 0x080c, + 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, + 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, + 0x080c, 0x612c, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, + 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, + 0x612c, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, + 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, + 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, + 0x026e, 0x709b, 0x0017, 0x080c, 0x60e4, 0x1150, 0x7084, 0x9005, + 0x1138, 0x080c, 0x5eb0, 0x1188, 0x9085, 0x0001, 0x080c, 0x28fd, + 0x20a9, 0x0008, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x5fba, 0x0010, 0x080c, 0x5a0a, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x01d8, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1190, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, + 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x612c, 0x709b, 0x0018, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0019, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, + 0x0000, 0x080c, 0x6101, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, + 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, + 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e19, 0x2039, 0x1c0e, + 0x080c, 0x60e4, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, + 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, + 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, + 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, + 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, - 0x5bd4, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x01c0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, - 0x0084, 0x1178, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, - 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, - 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, - 0x080c, 0x60fb, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, + 0x5e4c, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, + 0x0084, 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, + 0x6057, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, + 0x0005, 0x9085, 0x0001, 0x080c, 0x612c, 0x709b, 0x001b, 0x080c, + 0xadbc, 0x080c, 0x6101, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, + 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, - 0x1f04, 0x5c18, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c, 0x8703, - 0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, - 0x080c, 0x6051, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60d7, - 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6126, 0x709b, 0x000f, - 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, - 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, - 0x2011, 0x5f8a, 0x080c, 0x86f7, 0x0005, 0x7090, 0x9005, 0x0130, - 0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0000, 0x0005, 0x709b, - 0x0011, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, - 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, - 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, - 0x60de, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, - 0x00ff, 0x0160, 0x080c, 0x2889, 0x9186, 0x007e, 0x0138, 0x9186, - 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f37, 0x60c3, 0x0014, - 0x080c, 0x5fb4, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, - 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, - 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, - 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x608d, 0x2079, 0x0240, - 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, - 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, - 0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c, 0x60b4, 0x20a9, - 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703, - 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, - 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0015, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, - 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8, 0x7084, 0x9005, - 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b1, 0x200d, - 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0180, - 0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9, 0x0008, 0x20e1, - 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, - 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090, - 0x9005, 0x05f0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, - 0x15a8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, - 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, - 0x9085, 0x0001, 0x080c, 0x6126, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, - 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, - 0x0001, 0x080c, 0x6126, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, - 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, - 0x00fe, 0x0005, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000, - 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, - 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, - 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x60de, 0x1150, - 0x7084, 0x9005, 0x1138, 0x080c, 0x5eaa, 0x1188, 0x9085, 0x0001, - 0x080c, 0x28f2, 0x20a9, 0x0008, 0x080c, 0x60fb, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, - 0x0014, 0x080c, 0x5fb4, 0x0010, 0x080c, 0x5a04, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x01d8, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, - 0x0084, 0x1190, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x6126, - 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x0019, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833, - 0x1106, 0x7837, 0x0000, 0x080c, 0x60fb, 0x2009, 0x026e, 0x2039, - 0x1c0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, - 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e13, - 0x2039, 0x1c0e, 0x080c, 0x60de, 0x11e8, 0x2728, 0x2514, 0x8207, - 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, - 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, - 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, - 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, - 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, - 0x0240, 0x1f04, 0x5e46, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c, - 0x8703, 0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, - 0x0001, 0x080c, 0x6051, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, - 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6126, 0x709b, - 0x001b, 0x080c, 0xada2, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2009, - 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, - 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, - 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, - 0x2011, 0x0260, 0x1f04, 0x5e92, 0x60c3, 0x0084, 0x080c, 0x5fb4, - 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, - 0x0008, 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x60fb, - 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, - 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, - 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, - 0x5ec4, 0x0804, 0x5f33, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, - 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f33, 0x918d, - 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, - 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, - 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5eea, 0x04d8, - 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5efc, 0x2328, - 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, - 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f0b, 0x755e, - 0x95c8, 0x33b1, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, - 0x0016, 0x2508, 0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea, - 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, - 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, - 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, - 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, - 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, - 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, - 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, - 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33b1, - 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, - 0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, - 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, - 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, - 0x080c, 0x6040, 0x080c, 0xa4fd, 0x7004, 0x9084, 0x4000, 0x0110, - 0x080c, 0x2d6b, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, - 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x609d, - 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, - 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, - 0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, - 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, - 0x60a7, 0x9575, 0x080c, 0xa4f4, 0x6144, 0xd184, 0x0120, 0x7198, - 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a, - 0x2112, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x0005, - 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb058, - 0x2009, 0x00f7, 0x080c, 0x609d, 0x2061, 0x19fc, 0x900e, 0x611a, - 0x611e, 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, - 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, - 0x0000, 0x2009, 0x002d, 0x2011, 0x600c, 0x080c, 0x86f7, 0x012e, - 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, - 0x8000, 0x0471, 0x2071, 0x0100, 0x080c, 0xa4fd, 0x2071, 0x0140, - 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x080c, 0x756b, - 0x0188, 0x080c, 0x7586, 0x1170, 0x080c, 0x7852, 0x0016, 0x080c, - 0x29a1, 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x784d, 0x080c, - 0x748f, 0x0050, 0x2009, 0x0001, 0x080c, 0x2c89, 0x2001, 0x0001, - 0x080c, 0x2832, 0x080c, 0x5fe0, 0x012e, 0x000e, 0x00ee, 0x0005, - 0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, - 0x8017, 0x2001, 0x199a, 0x201c, 0x080c, 0x4be3, 0x003e, 0x002e, - 0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, - 0x60fb, 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, - 0x080c, 0x60f5, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, - 0x000e, 0x080c, 0x60f8, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, - 0x0005, 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, - 0x8108, 0x8210, 0x1f04, 0x6075, 0x002e, 0x001e, 0x0005, 0x080c, - 0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, - 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xada2, 0x080c, - 0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, - 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, - 0x0100, 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, - 0x1818, 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, - 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a88, - 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe940, 0x2001, - 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, - 0x3216, 0x080c, 0xd548, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, - 0x0007, 0x080c, 0x4d9a, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, - 0x5fe0, 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, - 0x180c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, - 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, - 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, - 0x2009, 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, - 0x6916, 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, - 0x0080, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, - 0x7803, 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, - 0x7823, 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, - 0x0005, 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, - 0x0118, 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, - 0x20a9, 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, - 0x6135, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, - 0x2069, 0x1847, 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, - 0xb80e, 0xb812, 0x9198, 0x33b1, 0x231d, 0x939c, 0x00ff, 0xbb16, - 0x0016, 0x0026, 0xb8c2, 0x080c, 0xb051, 0x1120, 0x9192, 0x007e, - 0x1208, 0xbbc2, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, - 0x0006, 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, - 0x23a0, 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, - 0xb856, 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, - 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, - 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, - 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, - 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, - 0x00c6, 0x2060, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, - 0x2004, 0x9c02, 0x1a0c, 0x0dc5, 0x080c, 0x8bbd, 0x00ce, 0x090c, - 0x8f5e, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, - 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, - 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6223, - 0x9182, 0x0800, 0x1a04, 0x6227, 0x2001, 0x180c, 0x2004, 0x9084, - 0x0003, 0x1904, 0x622d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, - 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, - 0x1904, 0x623f, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, - 0xb84e, 0x080c, 0x9352, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, - 0x2900, 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, - 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, - 0x0006, 0x1290, 0x080c, 0xb051, 0x1160, 0xb8a0, 0x9084, 0xff80, - 0x1140, 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, - 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, - 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, - 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, - 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, - 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, - 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, - 0x6a8c, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61d6, 0x080c, - 0x68b3, 0x0904, 0x61ef, 0x0804, 0x61da, 0x00b6, 0x00e6, 0x0126, - 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c, - 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, - 0x2104, 0x905d, 0x01d0, 0x080c, 0x6a2c, 0x11d0, 0x080c, 0xb091, - 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, - 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, - 0x0043, 0x080c, 0xb166, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, - 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, - 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, - 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, - 0x9182, 0x0800, 0x1a04, 0x6310, 0x9188, 0x1000, 0x2104, 0x905d, - 0x0904, 0x62e8, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, - 0x1178, 0x080c, 0x6a94, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, - 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6a8c, 0x1598, - 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, - 0x2010, 0x080c, 0xce2d, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, - 0x6312, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, - 0x6312, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, - 0xb091, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, - 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0458, - 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb051, - 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, - 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, - 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, - 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, - 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, - 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, - 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, - 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, - 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, - 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, - 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, - 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, - 0x00fe, 0x0005, 0x63a7, 0x6362, 0x6379, 0x63a7, 0x63a7, 0x63a7, - 0x63a7, 0x63a7, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66ac, - 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x63af, 0xb814, 0x9206, - 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a96, 0x0150, - 0x04b0, 0x080c, 0x6717, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, - 0x9206, 0x1568, 0x080c, 0xb091, 0x0530, 0x2b00, 0x6012, 0x080c, - 0xd2bb, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, - 0x9086, 0x0001, 0x1170, 0x080c, 0x324b, 0x9006, 0x080c, 0x6649, - 0x2001, 0x0002, 0x080c, 0x665d, 0x2001, 0x0200, 0xb86e, 0xb893, - 0x0002, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0068, 0x2001, - 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, - 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, - 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, - 0x0015, 0x0904, 0x659a, 0x90c6, 0x0056, 0x0904, 0x659e, 0x90c6, - 0x0066, 0x0904, 0x65a2, 0x90c6, 0x0067, 0x0904, 0x65a6, 0x90c6, - 0x0068, 0x0904, 0x65aa, 0x90c6, 0x0071, 0x0904, 0x65ae, 0x90c6, - 0x0074, 0x0904, 0x65b2, 0x90c6, 0x007c, 0x0904, 0x65b6, 0x90c6, - 0x007e, 0x0904, 0x65ba, 0x90c6, 0x0037, 0x0904, 0x65be, 0x9016, - 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x6595, 0x9182, - 0x0800, 0x1a04, 0x6595, 0x080c, 0x6717, 0x1198, 0xb804, 0x9084, - 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, - 0x080c, 0xb051, 0x1904, 0x657e, 0xb8a0, 0x9084, 0xff80, 0x1904, - 0x657e, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, - 0x64de, 0x90c6, 0x0064, 0x0904, 0x6507, 0x2008, 0x0804, 0x64a0, - 0xa998, 0xa8b0, 0x2040, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f, - 0x0a04, 0x64a0, 0x9186, 0x00ff, 0x0904, 0x64a0, 0x9182, 0x0800, - 0x1a04, 0x64a0, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, - 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a0, - 0x080c, 0xb051, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, - 0x2310, 0x0804, 0x64a0, 0x009e, 0x080c, 0x4a96, 0x0904, 0x64aa, - 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x6937, - 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, - 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, - 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, - 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, - 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, - 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, - 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, - 0x0478, 0x000e, 0x080c, 0xb091, 0x1130, 0x2001, 0x4005, 0x2009, - 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2900, - 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, - 0x0126, 0x2091, 0x8000, 0x080c, 0x324b, 0x012e, 0x9006, 0x080c, - 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c, - 0xb166, 0xa8b0, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, - 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e1, - 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6717, - 0x1904, 0x649b, 0x9186, 0x007f, 0x0130, 0x080c, 0x6a8c, 0x0118, - 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, - 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd027, - 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa998, - 0xaeb0, 0x080c, 0x6717, 0x1904, 0x649b, 0x0096, 0x080c, 0x100e, - 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x655b, 0x2900, 0x009e, - 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, - 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, - 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, - 0x2398, 0x080c, 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x57cd, 0xd0b4, 0x1118, - 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, - 0x00b0, 0x080c, 0x6a8c, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, - 0x57e1, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xd00a, 0x1904, - 0x64d7, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa87b, - 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, - 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, - 0xb608, 0x1904, 0x64d7, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, - 0x900e, 0x0804, 0x64d8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, - 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, - 0x2001, 0x0029, 0x900e, 0x0804, 0x64d8, 0x2001, 0x0029, 0x900e, - 0x0804, 0x64d8, 0x080c, 0x37e2, 0x0804, 0x64d9, 0x080c, 0x54f8, - 0x0804, 0x64d9, 0x080c, 0x4606, 0x0804, 0x64d9, 0x080c, 0x467f, - 0x0804, 0x64d9, 0x080c, 0x46db, 0x0804, 0x64d9, 0x080c, 0x4b59, - 0x0804, 0x64d9, 0x080c, 0x4e0d, 0x0804, 0x64d9, 0x080c, 0x515f, - 0x0804, 0x64d9, 0x080c, 0x5358, 0x0804, 0x64d9, 0x080c, 0x3a0c, - 0x0804, 0x64d9, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, - 0x905d, 0x0140, 0x080c, 0x6a8c, 0x1148, 0x00e9, 0x080c, 0x6842, - 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, - 0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, + 0x1f04, 0x5e98, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x0005, 0x0005, + 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, + 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6101, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, + 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, + 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5eca, 0x0804, + 0x5f39, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, + 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f39, 0x918d, 0xc000, 0x20a9, + 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, + 0x8319, 0x0008, 0x8318, 0x1f04, 0x5ef0, 0x04d8, 0x23a8, 0x2021, + 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f02, 0x2328, 0x8529, 0x92be, + 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, + 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f11, 0x755e, 0x95c8, 0x33ac, + 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, + 0x080c, 0x28dd, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, + 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, + 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, + 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, + 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, + 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, + 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, + 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33ac, 0x242d, 0x95ac, + 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28dd, + 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, + 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x6046, + 0x080c, 0xa517, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, + 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x001e, 0x9094, + 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x2be7, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f3, 0x2013, + 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x080c, 0xa50e, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, + 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a, 0x2112, 0x2009, + 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x0005, 0x0016, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb072, 0x2009, 0x00f7, + 0x080c, 0x60a3, 0x2061, 0x19fc, 0x900e, 0x611a, 0x611e, 0x617a, + 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, + 0x002d, 0x2011, 0x6012, 0x080c, 0x86fd, 0x012e, 0x00ce, 0x002e, + 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, + 0x2071, 0x0100, 0x080c, 0xa517, 0x2071, 0x0140, 0x7004, 0x9084, + 0x4000, 0x0110, 0x080c, 0x2d62, 0x080c, 0x7571, 0x0188, 0x080c, + 0x758c, 0x1170, 0x080c, 0x7858, 0x0016, 0x080c, 0x29ac, 0x2001, + 0x196e, 0x2102, 0x001e, 0x080c, 0x7853, 0x080c, 0x7495, 0x0050, + 0x2009, 0x0001, 0x080c, 0x2c80, 0x2001, 0x0001, 0x080c, 0x283d, + 0x080c, 0x5fe6, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, + 0x199a, 0x201c, 0x080c, 0x4be9, 0x003e, 0x002e, 0x0005, 0x20a9, + 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x6101, 0x20e9, + 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x60fb, + 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, + 0x60fe, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, + 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, + 0x1f04, 0x607b, 0x002e, 0x001e, 0x0005, 0x080c, 0xadbc, 0x20e1, + 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1, + 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, + 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, + 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a8e, 0x0158, 0x9006, + 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001, 0x180c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3211, 0x080c, + 0xd561, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, + 0x4da0, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5fe6, 0x709b, + 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, + 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, + 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, + 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, + 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, + 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, + 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, + 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, + 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118, 0x2003, + 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, + 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x613b, 0x015e, + 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, + 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, + 0x9198, 0x33ac, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, + 0xb8c2, 0x080c, 0xb06b, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, + 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, + 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, + 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, + 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, + 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, + 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, + 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, + 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, + 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1a0c, 0x0dc5, 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af, + 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, + 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6229, 0x9182, 0x0800, + 0x1a04, 0x622d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, + 0x6233, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, + 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x6245, + 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, + 0x9358, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, + 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, + 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, + 0x080c, 0xb06b, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, + 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, + 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, + 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, - 0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, - 0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, - 0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, - 0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, - 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, - 0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, - 0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, - 0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, - 0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, - 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, - 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, - 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, - 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, - 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, - 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, - 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6a88, 0x0140, 0x9284, - 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, - 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, - 0xba90, 0x82ff, 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, - 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, - 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, - 0x080c, 0x6a84, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, - 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, - 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, - 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, - 0x1188, 0x0096, 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, - 0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, - 0x080c, 0x613b, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, - 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, - 0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, - 0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, - 0x080c, 0x1040, 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, - 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c, - 0x0fc0, 0x080c, 0xb0e7, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, - 0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f5e, - 0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, - 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, - 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, - 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, - 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, - 0x080c, 0x7563, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, - 0xb051, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, - 0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, - 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, - 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, - 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, - 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, - 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, - 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, - 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, - 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, - 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, - 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, - 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, - 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, - 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, - 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, - 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, - 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, - 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, - 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, - 0xbbce, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, - 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, - 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, - 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, - 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, - 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, - 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, - 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, - 0xb8a6, 0xa803, 0x0000, 0x080c, 0x68d3, 0xa807, 0x0001, 0xae12, - 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, - 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, - 0x1150, 0x080c, 0x68e2, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, - 0x8001, 0xa806, 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, - 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x9352, 0x012e, - 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, - 0x8000, 0xb84c, 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, - 0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, - 0x1118, 0xa870, 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, - 0x080c, 0xa905, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, - 0x00a6, 0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, - 0x012e, 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, - 0x080c, 0x6937, 0x0128, 0x080c, 0xcefc, 0x0010, 0x9085, 0x0001, - 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcea1, 0x0010, 0x9085, - 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcef9, 0x0010, - 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcec0, - 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, - 0xcf3f, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, - 0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, - 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, - 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, - 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, - 0x01ce, 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, - 0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, - 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, - 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, - 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, - 0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, - 0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, - 0x2091, 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, - 0x2900, 0xb8a6, 0x080c, 0x68d3, 0xa803, 0x0001, 0xa807, 0x0000, - 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, - 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, - 0x080c, 0x1040, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, - 0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c, 0x7563, 0x01b0, 0x71c4, - 0x81ff, 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, - 0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, - 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, - 0xd0a4, 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, - 0x6717, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, - 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, - 0x8108, 0x1f04, 0x695e, 0x015e, 0x080c, 0x6a4a, 0x0120, 0x2001, - 0x1986, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, - 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c, 0x879b, 0x00fe, 0x00be, - 0x0005, 0x00b6, 0x2011, 0x6989, 0x080c, 0x8703, 0x080c, 0x6a4a, - 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, - 0x080c, 0x6a88, 0x0130, 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c, - 0x879b, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, - 0x080c, 0x3022, 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f, - 0x900e, 0x0016, 0x080c, 0x6717, 0x1548, 0xb800, 0xd0ec, 0x0530, - 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, - 0x080c, 0xe940, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a84, - 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, - 0xb806, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, - 0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x004e, 0x001e, 0x8108, - 0x1f04, 0x69b1, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, - 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, - 0x0096, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, - 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, - 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, - 0x613b, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, - 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, - 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, - 0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, - 0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, - 0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, - 0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, - 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, - 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, - 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, - 0x190c, 0x0dc5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, - 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, - 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6a7a, 0x080c, - 0x879b, 0x0005, 0x2011, 0x6a7a, 0x080c, 0x8703, 0x2011, 0x1837, - 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x57cd, 0xd0ac, 0x0005, - 0x080c, 0x57cd, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, - 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, - 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, - 0xd548, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, - 0x2004, 0x905d, 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, - 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, - 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003, - 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a, - 0x080c, 0x57cd, 0xd0fc, 0x1140, 0x080c, 0x57cd, 0x900e, 0xd09c, - 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184, - 0x0007, 0x0002, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6ae2, - 0x6af7, 0x6b05, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184, - 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, - 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, - 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800, - 0x70f3, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, - 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, - 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, - 0x1800, 0x908c, 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f, - 0x0c90, 0x70f3, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, - 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, - 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, - 0x78ba, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, - 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, - 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, - 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, - 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, - 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, - 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286, - 0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0x2071, - 0x1877, 0xa87c, 0x9005, 0x0904, 0x6bc5, 0x7140, 0xa868, 0x9102, - 0x0a04, 0x6dd1, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, - 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f, - 0x0e04, 0x700d, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, - 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, - 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, - 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, - 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c4d, - 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, - 0x6dd1, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6b89, 0x00e6, - 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286, - 0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa84f, - 0x8022, 0xa853, 0x0018, 0x0804, 0x6c32, 0xa868, 0xd0fc, 0x1508, - 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd1, - 0xa978, 0xa874, 0x9105, 0x1904, 0x6dd1, 0x9286, 0x0003, 0x0904, - 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0bc, 0x1904, - 0x6dd1, 0x2200, 0x0002, 0x6dd1, 0x6c2e, 0x6c6a, 0x6c6a, 0x6dd1, - 0x6c6a, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, - 0x1949, 0x210c, 0x81ff, 0x0904, 0x6dd1, 0xa880, 0x9084, 0x00ff, - 0x9086, 0x0001, 0x1904, 0x6dd1, 0x9186, 0x0003, 0x0904, 0x6c6a, - 0x9186, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0cc, 0x0904, 0x6dd1, - 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, - 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f, - 0x0e04, 0x700d, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, - 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011, - 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005, - 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, - 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6d55, 0x782c, - 0x908c, 0x0780, 0x190c, 0x715b, 0x8004, 0x8004, 0x8004, 0x9084, - 0x0003, 0x0002, 0x6c88, 0x6d55, 0x6cac, 0x6cf2, 0x080c, 0x0dc5, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, - 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, - 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x85eb, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, - 0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, - 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, - 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, - 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, - 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044, + 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, + 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x6a92, 0x1990, + 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61dc, 0x080c, 0x68b9, 0x0904, + 0x61f5, 0x0804, 0x61e0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, + 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c, 0x205c, 0x0060, + 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, + 0x01d0, 0x080c, 0x6a32, 0x11d0, 0x080c, 0xb0ab, 0x0570, 0x2b00, + 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, + 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, + 0xb180, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, + 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, + 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, + 0x1a04, 0x6316, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x62ee, + 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, + 0x6a9a, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, + 0x908e, 0x0005, 0x0118, 0x080c, 0x6a92, 0x1598, 0xa87c, 0xd0fc, + 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, + 0xce44, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x6318, 0x6020, + 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x6318, 0x601a, + 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xb0ab, 0x05e8, + 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, + 0x2009, 0x0003, 0x080c, 0xb180, 0x9006, 0x0458, 0x2001, 0x0028, + 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb06b, 0x1160, 0xb8a0, + 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, + 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, + 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, + 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, + 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, + 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, + 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, + 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, + 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, + 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, + 0x63ad, 0x6368, 0x637f, 0x63ad, 0x63ad, 0x63ad, 0x63ad, 0x63ad, + 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66b2, 0x0148, 0x9046, + 0xb810, 0x9306, 0x1904, 0x63b5, 0xb814, 0x9206, 0x15f0, 0x0028, + 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a9c, 0x0150, 0x04b0, 0x080c, + 0x671d, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, + 0x080c, 0xb0ab, 0x0530, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900, + 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, + 0x1170, 0x080c, 0x3246, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, + 0x080c, 0x6663, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, + 0x0003, 0x080c, 0xb180, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, + 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, + 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, + 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, + 0x65a0, 0x90c6, 0x0056, 0x0904, 0x65a4, 0x90c6, 0x0066, 0x0904, + 0x65a8, 0x90c6, 0x0067, 0x0904, 0x65ac, 0x90c6, 0x0068, 0x0904, + 0x65b0, 0x90c6, 0x0071, 0x0904, 0x65b4, 0x90c6, 0x0074, 0x0904, + 0x65b8, 0x90c6, 0x007c, 0x0904, 0x65bc, 0x90c6, 0x007e, 0x0904, + 0x65c0, 0x90c6, 0x0037, 0x0904, 0x65c4, 0x9016, 0x2079, 0x1800, + 0xa974, 0x9186, 0x00ff, 0x0904, 0x659b, 0x9182, 0x0800, 0x1a04, + 0x659b, 0x080c, 0x671d, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, + 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xb06b, + 0x1904, 0x6584, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x6584, 0xa894, + 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x64e4, 0x90c6, + 0x0064, 0x0904, 0x650d, 0x2008, 0x0804, 0x64a6, 0xa998, 0xa8b0, + 0x2040, 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x64a6, + 0x9186, 0x00ff, 0x0904, 0x64a6, 0x9182, 0x0800, 0x1a04, 0x64a6, + 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, + 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a6, 0x080c, 0xb06b, + 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, + 0x64a6, 0x009e, 0x080c, 0x4a9c, 0x0904, 0x64b0, 0x900e, 0x9016, + 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x693d, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, 0x9305, 0xabcc, + 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, + 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, + 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, + 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, + 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, + 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, + 0x080c, 0xb0ab, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, + 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900, 0x6016, 0x6023, + 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x3246, 0x012e, 0x9006, 0x080c, 0x664f, 0x2001, + 0x0002, 0x080c, 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0xa8b0, + 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e, + 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e7, 0x0118, 0x2009, + 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x671d, 0x1904, 0x64a1, + 0x9186, 0x007f, 0x0130, 0x080c, 0x6a92, 0x0118, 0x2009, 0x0009, + 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, 0x2009, 0x0002, + 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd03e, 0x19b0, 0x2009, + 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa998, 0xaeb0, 0x080c, + 0x671d, 0x1904, 0x64a1, 0x0096, 0x080c, 0x100e, 0x1128, 0x009e, + 0x2009, 0x0002, 0x0804, 0x6561, 0x2900, 0x009e, 0xa806, 0x0096, + 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, + 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, + 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0xd684, 0x1168, 0x080c, 0x57d3, 0xd0b4, 0x1118, 0xa89b, 0x000b, + 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, + 0x6a92, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x57e7, 0x0118, + 0xa89b, 0x0007, 0x0050, 0x080c, 0xd021, 0x1904, 0x64dd, 0x2009, + 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa87b, 0x0030, 0xa897, + 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f, 0x1904, + 0x64dd, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, + 0x64de, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, + 0x900e, 0x0804, 0x64de, 0x2001, 0x0029, 0x900e, 0x0804, 0x64de, + 0x080c, 0x37dd, 0x0804, 0x64df, 0x080c, 0x54fe, 0x0804, 0x64df, + 0x080c, 0x460c, 0x0804, 0x64df, 0x080c, 0x4685, 0x0804, 0x64df, + 0x080c, 0x46e1, 0x0804, 0x64df, 0x080c, 0x4b5f, 0x0804, 0x64df, + 0x080c, 0x4e13, 0x0804, 0x64df, 0x080c, 0x5165, 0x0804, 0x64df, + 0x080c, 0x535e, 0x0804, 0x64df, 0x080c, 0x3a07, 0x0804, 0x64df, + 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, + 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140, + 0x080c, 0x6a92, 0x1148, 0x00e9, 0x080c, 0x6848, 0x9006, 0x00b0, + 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, + 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, + 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, + 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900, + 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e, + 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, + 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e9, + 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, + 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, + 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, + 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, + 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, + 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, + 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, + 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, + 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, + 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, + 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, + 0xd0ac, 0x0158, 0x080c, 0x6a8e, 0x0140, 0x9284, 0xff00, 0x8007, + 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, + 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, + 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, + 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, + 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a8a, + 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, + 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, + 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, + 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, + 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, + 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6141, + 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, + 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, + 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0x0fc0, 0x080c, + 0xb101, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, + 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f64, 0x00ce, 0x2b48, + 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, 0x00de, 0x9006, + 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, + 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, + 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, + 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x7569, + 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb06b, 0x11d8, + 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048, + 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, + 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, + 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, + 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, + 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, + 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, + 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, + 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, + 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, + 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, + 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, + 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, + 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, + 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, + 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, + 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, 0xba00, 0x2009, + 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, + 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, + 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbce, 0x003e, + 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, + 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, + 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, + 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, + 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, 0x20e8, 0x3300, + 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, + 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, 0xb8a6, 0xa803, + 0x0000, 0x080c, 0x68d9, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, + 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, + 0x68e8, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, + 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9358, 0x012e, 0x0005, 0x901e, + 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, + 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, + 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0xa91f, + 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, + 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, + 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x693d, + 0x0128, 0x080c, 0xcf13, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x693d, 0x0128, 0x080c, 0xceb8, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x693d, 0x0128, 0x080c, 0xcf10, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xced7, 0x0010, 0x9085, + 0x0001, 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xcf56, 0x0010, + 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, + 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, + 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, + 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, + 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, + 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, + 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, + 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, + 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, + 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, + 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, + 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, 0x2900, 0xb8a6, + 0x080c, 0x68d9, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, + 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1040, + 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, + 0x00b6, 0x00f6, 0x080c, 0x7569, 0x01b0, 0x71c4, 0x81ff, 0x1198, + 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, + 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, + 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, + 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1168, + 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, + 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, + 0x6964, 0x015e, 0x080c, 0x6a50, 0x0120, 0x2001, 0x1986, 0x200c, + 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, + 0x2011, 0x698f, 0x080c, 0x87a1, 0x00fe, 0x00be, 0x0005, 0x00b6, + 0x2011, 0x698f, 0x080c, 0x8709, 0x080c, 0x6a50, 0x01d8, 0x2001, + 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6a8e, + 0x0130, 0x2009, 0x07d0, 0x2011, 0x698f, 0x080c, 0x87a1, 0x00e6, + 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x3019, + 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, + 0x080c, 0x671d, 0x1548, 0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520, + 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe9a5, + 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a8a, 0x2001, 0x0707, + 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, + 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e, + 0x080c, 0xe690, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x69b7, + 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, + 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, 0x080c, + 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, 0x196c, 0x2b02, + 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0, + 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6141, 0xb807, + 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c, + 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000, + 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, + 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff, + 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005, + 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196, + 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, 0x0005, + 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, + 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, + 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0dc5, + 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, + 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138, + 0x2001, 0x1984, 0x200c, 0x2011, 0x6a80, 0x080c, 0x87a1, 0x0005, + 0x2011, 0x6a80, 0x080c, 0x8709, 0x2011, 0x1837, 0x2204, 0xc0cc, + 0x2012, 0x0005, 0x080c, 0x57d3, 0xd0ac, 0x0005, 0x080c, 0x57d3, + 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, + 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, + 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd561, 0x0158, + 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, + 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x2071, 0x1910, + 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, + 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005, + 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a, 0x080c, 0x57d3, + 0xd0fc, 0x1140, 0x080c, 0x57d3, 0x900e, 0xd09c, 0x0108, 0x8108, + 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002, + 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ae8, 0x6afd, 0x6b0b, + 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e, + 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, + 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, + 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800, 0x70f3, 0x0001, + 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x1910, 0x2009, + 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, + 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, + 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70f3, + 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, + 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, + 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x78c0, 0x6a60, + 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, + 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, + 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, + 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, + 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, + 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071, + 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904, + 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0x2071, 0x1877, 0xa87c, + 0x9005, 0x0904, 0x6bcb, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6dd7, + 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, + 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013, + 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086, + 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, + 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, + 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c53, 0xa853, 0x001b, + 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, 0x6dd7, 0xa853, + 0x001a, 0x2001, 0x8024, 0x0804, 0x6b8f, 0x00e6, 0x0026, 0x2071, + 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904, + 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0xa84f, 0x8022, 0xa853, + 0x0018, 0x0804, 0x6c38, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026, + 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd7, 0xa978, 0xa874, + 0x9105, 0x1904, 0x6dd7, 0x9286, 0x0003, 0x0904, 0x6c70, 0x9286, + 0x0005, 0x0904, 0x6c70, 0xa87c, 0xd0bc, 0x1904, 0x6dd7, 0x2200, + 0x0002, 0x6dd7, 0x6c34, 0x6c70, 0x6c70, 0x6dd7, 0x6c70, 0x0005, + 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1949, 0x210c, + 0x81ff, 0x0904, 0x6dd7, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, + 0x1904, 0x6dd7, 0x9186, 0x0003, 0x0904, 0x6c70, 0x9186, 0x0005, + 0x0904, 0x6c70, 0xa87c, 0xd0cc, 0x0904, 0x6dd7, 0xa84f, 0x8021, + 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, + 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013, + 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, + 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, + 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148, + 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58, + 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, + 0x0000, 0x7010, 0x9005, 0x1904, 0x6d5b, 0x782c, 0x908c, 0x0780, + 0x190c, 0x7161, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, + 0x6c8e, 0x6d5b, 0x6cb2, 0x6cf8, 0x080c, 0x0dc5, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, - 0x85eb, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x1d60, - 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x1198, - 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc, - 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, - 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, - 0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, + 0x85f1, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, + 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, + 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, + 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7161, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, - 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, - 0x85eb, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, - 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, - 0x2148, 0xa804, 0x900d, 0x1904, 0x6da9, 0x782c, 0x9094, 0x0780, - 0x190c, 0x715b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, - 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, - 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d68, 0x782c, - 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x01b0, 0x00e6, 0x7824, - 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, - 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, - 0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005, - 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6d65, 0xa868, 0xd0fc, - 0x1904, 0x6e1f, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, - 0x0fc0, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e1f, 0x00e6, - 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, - 0x70ec, 0x8001, 0x0558, 0x1a04, 0x6e1c, 0x2071, 0x1910, 0xa803, - 0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, - 0x9005, 0x1904, 0x6f1b, 0x782c, 0x908c, 0x0780, 0x190c, 0x715b, - 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6e20, 0x6f1b, - 0x6e3b, 0x6eac, 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002, - 0x6de7, 0x6de7, 0x6de7, 0x6c73, 0x6de7, 0x6c73, 0x70ef, 0x0fa0, - 0x71e8, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, - 0x70ea, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, - 0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6ddd, 0x0005, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, - 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, - 0x080c, 0x85eb, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, - 0x900d, 0x1904, 0x6e9b, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0, - 0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, - 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, - 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0, - 0x0e04, 0x6e92, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, - 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, - 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11aa, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, - 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, - 0x080c, 0x85eb, 0x0804, 0x6e4e, 0x0096, 0x00e6, 0x7824, 0x2048, - 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, - 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, - 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6eee, 0x7838, 0x7938, 0x910e, - 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, - 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, - 0x190c, 0x715b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, - 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, - 0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, - 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x00fe, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0808, + 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60, 0x00ee, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x1198, 0x009e, 0x2900, + 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc, 0x7044, 0x9005, + 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, + 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1904, 0x6f8a, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, - 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, - 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, - 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d50, - 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x05b8, 0x00e6, - 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, - 0x190c, 0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f83, 0x7838, - 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, - 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, - 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, - 0x9200, 0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6f2b, 0x2071, - 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, - 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1128, 0x1e04, 0x6fca, 0x002e, 0x00ee, 0x0005, 0x2071, - 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, - 0x0e04, 0x6fb4, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, - 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, - 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, - 0x1910, 0x080c, 0x7147, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, - 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, - 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, - 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, + 0x900d, 0x1904, 0x6daf, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, + 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, + 0x190c, 0x7161, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, + 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, + 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, + 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x85f1, 0x00ee, 0x0804, 0x6d6b, 0xa868, 0xd0fc, 0x1904, 0x6e25, + 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fc0, 0x009e, + 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e25, 0x00e6, 0x0026, 0xa84f, + 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70ec, 0x8001, + 0x0558, 0x1a04, 0x6e22, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, + 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, + 0x6f21, 0x782c, 0x908c, 0x0780, 0x190c, 0x7161, 0x8004, 0x8004, + 0x8004, 0x9084, 0x0003, 0x0002, 0x6e26, 0x6f21, 0x6e41, 0x6eb2, + 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002, 0x6ded, 0x6ded, + 0x6ded, 0x6c79, 0x6ded, 0x6c79, 0x70ef, 0x0fa0, 0x71e8, 0x8107, + 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70ea, 0x3b08, + 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, + 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6de3, 0x0005, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, + 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, + 0x6ea1, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0, 0x9102, 0x1220, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x0e04, 0x6e98, + 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, + 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, + 0x0804, 0x6e54, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60, + 0x00ee, 0x0e04, 0x6ef4, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, + 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, + 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, + 0x6f90, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x11b0, + 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d50, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7161, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, + 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f89, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x85f1, 0x00ee, 0x0804, 0x6f31, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, - 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, - 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, - 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, - 0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005, 0x0006, - 0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, - 0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, - 0x7004, 0x0002, 0x705a, 0x705b, 0x7146, 0x705b, 0x7058, 0x7146, - 0x080c, 0x0dc5, 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7065, - 0x7065, 0x70df, 0x70e0, 0x7065, 0x70e0, 0x0126, 0x2091, 0x8000, - 0x1e0c, 0x7166, 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, - 0x70b0, 0x0e04, 0x708e, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, - 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, - 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, 0x7147, 0x012e, 0x0804, - 0x70de, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, - 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, - 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, - 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, - 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, - 0x2071, 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, - 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, - 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, - 0x00de, 0x2071, 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, - 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, - 0x00d6, 0x2008, 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158, - 0x9186, 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2, - 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, - 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x7112, 0x2069, 0x0000, - 0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc, - 0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, - 0x71d1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, - 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, - 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, - 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, - 0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, - 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, - 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, - 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040, - 0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x715d, 0x0006, - 0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6, - 0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, + 0x1e04, 0x6fd0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0e04, 0x6fba, + 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, + 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, + 0x714d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, + 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, + 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, + 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, + 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, + 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, + 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, + 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, + 0x7060, 0x7061, 0x714c, 0x7061, 0x705e, 0x714c, 0x080c, 0x0dc5, + 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x706b, 0x706b, 0x70e5, + 0x70e6, 0x706b, 0x70e6, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x716c, + 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x70b6, 0x0e04, + 0x7094, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, + 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x2071, 0x1910, 0x080c, 0x714d, 0x012e, 0x0804, 0x70e4, 0xa850, + 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, + 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, + 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, + 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, + 0x2004, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x2071, 0x1910, + 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, + 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, + 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, + 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, + 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, + 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2, 0x210c, 0x9102, + 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, + 0x9106, 0x0190, 0x0e04, 0x7118, 0x2069, 0x0000, 0x6837, 0x8040, + 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc, 0x6847, 0xffff, + 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x71d7, 0x701c, + 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, + 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, + 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, + 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, + 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, + 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, + 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040, 0x0005, 0x012e, + 0x0005, 0x2091, 0x8000, 0x0e04, 0x7163, 0x0006, 0x0016, 0x2001, + 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6, 0x2079, 0x0050, + 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, + 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, + 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, + 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, - 0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, - 0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, - 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, - 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, + 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7161, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0, - 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, - 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, - 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, - 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, - 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, - 0x2004, 0xd084, 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094, - 0x0780, 0x190c, 0x715b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, - 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, - 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, - 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949, - 0x6808, 0x690a, 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005, - 0x1320, 0x2001, 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, - 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d, - 0x001b, 0x6027, 0x1e00, 0x0005, 0x7312, 0x727f, 0x729b, 0x72c5, - 0x7301, 0x7341, 0x7353, 0x729b, 0x7329, 0x723a, 0x7268, 0x72eb, - 0x7239, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, - 0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, - 0x7002, 0x080c, 0x7698, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, - 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, - 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, - 0x080c, 0x1b02, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, - 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, - 0x1160, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, - 0x7735, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, - 0x2001, 0x0090, 0x080c, 0x2d5b, 0x000e, 0x6124, 0xd1e4, 0x1190, - 0x080c, 0x73c0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, - 0x709b, 0x0020, 0x080c, 0x73c0, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2d5b, 0x6124, - 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, - 0x11d8, 0x080c, 0x1b27, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, - 0x080c, 0x758f, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x709b, 0x0029, - 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, - 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b27, 0x60e3, - 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x758f, 0x2001, 0x0080, - 0x080c, 0x2d5b, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, - 0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, - 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, - 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, + 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d70, + 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949, 0x6808, 0x690a, + 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, + 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, + 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d, 0x001b, 0x6027, + 0x1e00, 0x0005, 0x7318, 0x7285, 0x72a1, 0x72cb, 0x7307, 0x7347, + 0x7359, 0x72a1, 0x732f, 0x7240, 0x726e, 0x72f1, 0x723f, 0x0005, + 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, + 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, + 0x769e, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029, + 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, + 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, + 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, + 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b, + 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x773b, 0x6028, + 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, + 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x73c6, + 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020, + 0x080c, 0x73c6, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x2001, 0x0088, 0x080c, 0x2d52, 0x6124, 0xd1cc, 0x11e8, + 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c, + 0x1b2f, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7595, + 0x2001, 0x0080, 0x080c, 0x2d52, 0x709b, 0x0029, 0x0058, 0x709b, + 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, + 0x709b, 0x001f, 0x0005, 0x080c, 0x1b2f, 0x60e3, 0x0001, 0x600c, + 0xc0b4, 0x600e, 0x080c, 0x7595, 0x2001, 0x0080, 0x080c, 0x2d52, + 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184, + 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, - 0x0005, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x6124, 0xd1dc, 0x1138, - 0xd1e4, 0x0138, 0x080c, 0x1b27, 0x709b, 0x001e, 0x0010, 0x709b, - 0x001d, 0x0005, 0x080c, 0x7443, 0x6124, 0xd1dc, 0x1188, 0x080c, - 0x73c0, 0x0016, 0x080c, 0x1b27, 0x001e, 0xd1d4, 0x1128, 0xd1e4, - 0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c0, - 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x000e, 0x6124, - 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, - 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, - 0x0005, 0x080c, 0x7443, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d5b, - 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, - 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, - 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, - 0x1800, 0x2091, 0x8000, 0x080c, 0x7563, 0x11d8, 0x2001, 0x180c, - 0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, - 0x2c83, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d5b, - 0x080c, 0x7848, 0x080c, 0x6121, 0x0428, 0x6028, 0xc0cd, 0x602a, - 0x0408, 0x080c, 0x757d, 0x0150, 0x080c, 0x7574, 0x1138, 0x2001, - 0x0001, 0x080c, 0x2832, 0x080c, 0x753b, 0x00a0, 0x080c, 0x7440, - 0x0178, 0x2001, 0x0001, 0x080c, 0x2832, 0x7098, 0x9086, 0x001e, - 0x0120, 0x7098, 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010, - 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, - 0x0026, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x002e, 0x0016, 0x0026, - 0x2009, 0x0064, 0x2011, 0x73d1, 0x080c, 0x87d4, 0x002e, 0x001e, - 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0xa4fd, 0x2071, 0x1800, - 0x080c, 0x736e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, - 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, - 0x080c, 0xa4fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, - 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, - 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x080c, 0x8789, 0x0036, - 0x901e, 0x080c, 0xa85d, 0x003e, 0x60e3, 0x0000, 0x080c, 0xed95, - 0x080c, 0xedb0, 0x2009, 0x0004, 0x080c, 0x2c89, 0x080c, 0x2ba4, - 0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d1, - 0x080c, 0x87dd, 0x080c, 0x757d, 0x0118, 0x9006, 0x080c, 0x2d5b, - 0x080c, 0x0ba0, 0x2001, 0x0001, 0x080c, 0x2832, 0x012e, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, - 0x00e6, 0x2011, 0x73de, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118, - 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, - 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, - 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2d5b, 0x0156, 0x20a9, 0x002d, - 0x1d04, 0x7450, 0x2091, 0x6000, 0x1f04, 0x7450, 0x015e, 0x00d6, - 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de, - 0x0005, 0x689f, 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086, - 0x0001, 0x1da8, 0x080c, 0x87e9, 0x0c90, 0x00c6, 0x00d6, 0x00e6, - 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7857, + 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, + 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, + 0x00a0, 0x080c, 0x2d52, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, + 0x080c, 0x1b2f, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, 0x0005, + 0x080c, 0x7449, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x73c6, 0x0016, + 0x080c, 0x1b2f, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b, + 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c6, 0x0005, 0x0006, + 0x2001, 0x00a0, 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1d4, 0x1160, + 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, 0x080c, + 0x7449, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, + 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d52, 0x000e, 0x6124, + 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, + 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, + 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, + 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, + 0x8000, 0x080c, 0x7569, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, + 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2c7a, 0x6024, + 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, + 0x080c, 0x6127, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, + 0x7583, 0x0150, 0x080c, 0x757a, 0x1138, 0x2001, 0x0001, 0x080c, + 0x283d, 0x080c, 0x7541, 0x00a0, 0x080c, 0x7446, 0x0178, 0x2001, + 0x0001, 0x080c, 0x283d, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, + 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, + 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, + 0x73d7, 0x080c, 0x87e3, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, + 0x2011, 0x73d7, 0x080c, 0x87da, 0x002e, 0x001e, 0x0005, 0x00e6, + 0x00f6, 0x0016, 0x080c, 0xa517, 0x2071, 0x1800, 0x080c, 0x7374, + 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa517, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, + 0x602a, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, + 0xa8f7, 0x080c, 0xa801, 0x080c, 0x878f, 0x0036, 0x901e, 0x080c, + 0xa877, 0x003e, 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, + 0x2009, 0x0004, 0x080c, 0x2c80, 0x080c, 0x2b9b, 0x2001, 0x1800, + 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d7, 0x080c, 0x87e3, + 0x080c, 0x7583, 0x0118, 0x9006, 0x080c, 0x2d52, 0x080c, 0x0ba0, + 0x2001, 0x0001, 0x080c, 0x283d, 0x012e, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, + 0x73e4, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, + 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, + 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, + 0x00c0, 0x080c, 0x2d52, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x7456, + 0x2091, 0x6000, 0x1f04, 0x7456, 0x015e, 0x00d6, 0x2069, 0x1800, + 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f, + 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, + 0x080c, 0x87ef, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x785d, 0x2001, 0x196e, + 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x2908, + 0x9006, 0x080c, 0x2d52, 0x080c, 0x5fe6, 0x6027, 0xffff, 0x602b, + 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, + 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, + 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7531, 0x709b, + 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, + 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, + 0x080c, 0x2908, 0x0026, 0x080c, 0xb072, 0x002e, 0x7000, 0x908e, + 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, + 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, + 0x012e, 0x015e, 0x080c, 0xd561, 0x0118, 0x9006, 0x080c, 0x2d7c, + 0x0804, 0x753d, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, + 0x2c7a, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2d52, + 0x1f04, 0x74d5, 0x080c, 0x75bd, 0x012e, 0x015e, 0x080c, 0x757a, + 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, + 0x75bd, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, + 0xd0d4, 0x1110, 0x080c, 0x75bd, 0x080c, 0xd561, 0x0118, 0x9006, + 0x080c, 0x2d7c, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, + 0x2009, 0x00c8, 0x2011, 0x73e4, 0x080c, 0x87a1, 0x002e, 0x001e, + 0x080c, 0x85e8, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003, + 0x0004, 0x080c, 0x7227, 0x080c, 0x757a, 0x0138, 0x6804, 0xd0d4, + 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7853, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0x1800, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x080c, 0x785d, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, - 0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x080c, 0x5fe0, 0x6027, - 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, - 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x2001, 0x197e, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, - 0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, - 0x752b, 0x709b, 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, - 0x0023, 0x0010, 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, - 0x2001, 0x0001, 0x080c, 0x28fd, 0x0026, 0x080c, 0xb058, 0x002e, - 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, - 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, - 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xd548, 0x0118, 0x9006, - 0x080c, 0x2d85, 0x0804, 0x7537, 0x6800, 0x9084, 0x00a1, 0xc0bd, - 0x6802, 0x080c, 0x2c83, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, - 0x080c, 0x2d5b, 0x1f04, 0x74cf, 0x080c, 0x75b7, 0x012e, 0x015e, - 0x080c, 0x7574, 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114, - 0x2204, 0x9085, 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, - 0x6052, 0x080c, 0x75b7, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052, - 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x75b7, 0x080c, 0xd548, - 0x0118, 0x9006, 0x080c, 0x2d85, 0x0016, 0x0026, 0x7000, 0x908e, - 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, 0x73de, 0x080c, 0x879b, - 0x002e, 0x001e, 0x080c, 0x85e2, 0x7034, 0xc085, 0x7036, 0x2001, - 0x197e, 0x2003, 0x0004, 0x080c, 0x7221, 0x080c, 0x7574, 0x0138, - 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x784d, 0x00ee, - 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x85f9, 0x080c, 0x85eb, - 0x080c, 0x7857, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, - 0x60e2, 0x6886, 0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x6043, - 0x0090, 0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, - 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086, - 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084, 0x0030, - 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084, - 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, - 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, - 0x57d1, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, - 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020, - 0x080c, 0x291d, 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028, - 0x080c, 0x3216, 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, - 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd541, 0x1128, 0x9085, - 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, - 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, - 0x0006, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, - 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x75cc, 0x2091, 0x6000, - 0x1f04, 0x75cc, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, - 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, - 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, - 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, - 0x080c, 0x28fd, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd548, 0x000e, - 0x0130, 0x080c, 0x2d79, 0x9006, 0x080c, 0x2d85, 0x0010, 0x080c, - 0x2d5b, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, - 0x2079, 0x0100, 0x080c, 0x2bf8, 0x00fe, 0x000e, 0x6052, 0x0005, - 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, - 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, - 0x0138, 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x768a, - 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, - 0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2d5b, 0x20a9, - 0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7639, 0x2091, 0x6000, - 0x1f04, 0x7639, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, - 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c, 0xa85d, 0x2001, - 0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c, - 0xd548, 0x0110, 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c, - 0x1b27, 0x60e3, 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x28fd, - 0x60e2, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x20a9, 0x0366, 0x6027, - 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x0138, - 0x1d04, 0x766f, 0x2091, 0x6000, 0x1f04, 0x766f, 0x0818, 0x6028, - 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, - 0x0008, 0x6886, 0x080c, 0xd548, 0x0110, 0x080c, 0x0d33, 0x9006, - 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, - 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, - 0x0100, 0x2071, 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, - 0x020b, 0x2004, 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, - 0x1a7d, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, - 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, 0x76fd, 0x2001, 0x0088, - 0x080c, 0x2d5b, 0x9006, 0x60e2, 0x6886, 0x080c, 0x28fd, 0x2069, - 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, - 0x9084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000, - 0x206a, 0x709b, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, - 0x76df, 0x2091, 0x6000, 0x1f04, 0x76df, 0x0804, 0x772d, 0x2069, - 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, - 0x2c83, 0x6024, 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, - 0x76eb, 0x2091, 0x6000, 0x1f04, 0x76eb, 0x2011, 0x0003, 0x080c, - 0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, - 0x080c, 0xa85d, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848, - 0x080c, 0x6121, 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b27, 0x2001, - 0x0080, 0x080c, 0x2d5b, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, - 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, - 0x2004, 0x080c, 0x28fd, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, - 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, - 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, - 0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8d3, - 0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c, - 0xa85d, 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c, - 0x7848, 0x080c, 0x6121, 0x0804, 0x77c8, 0x2001, 0x180c, 0x200c, - 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x73c6, 0x2069, 0x0140, - 0x2001, 0x0080, 0x080c, 0x2d5b, 0x60e3, 0x0000, 0x2069, 0x0200, - 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, - 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a, - 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x77c8, 0x6027, 0x1e00, - 0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x01c8, 0x9084, - 0x1c00, 0x11b0, 0x1d04, 0x7786, 0x0006, 0x0016, 0x00c6, 0x00d6, - 0x00e6, 0x080c, 0x863c, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, - 0x00e6, 0x2071, 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400, - 0x0026, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, - 0x87dd, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, - 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, - 0x080c, 0x28fd, 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, - 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, - 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, - 0x0100, 0x2071, 0x1800, 0x080c, 0xd541, 0x1904, 0x7836, 0x7130, - 0xd184, 0x1170, 0x080c, 0x33a5, 0x0138, 0xc18d, 0x7132, 0x2011, - 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x7836, - 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e, - 0x080c, 0xe8b0, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, - 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, 0x6717, 0x1170, - 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, 0xe940, 0x2009, - 0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x001e, 0x8108, 0x1f04, - 0x77ff, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, - 0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x0078, 0x0156, - 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1110, 0x080c, - 0x613b, 0x8108, 0x1f04, 0x782c, 0x00be, 0x015e, 0x080c, 0x1b27, - 0x080c, 0xb058, 0x60e3, 0x0000, 0x080c, 0x6121, 0x080c, 0x748f, - 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, - 0x2001, 0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, - 0x0000, 0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, - 0x197d, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, - 0x7007, 0x0000, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, - 0x2900, 0x704e, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, - 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, - 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, - 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, - 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, - 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, - 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, - 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, - 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, - 0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7e3a, 0x9006, - 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011, - 0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, - 0x3e08, 0x1f04, 0x78be, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, - 0x18fa, 0x7004, 0x0002, 0x78dd, 0x78de, 0x7916, 0x7971, 0x7a81, - 0x78db, 0x78db, 0x7aab, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040, - 0x782c, 0x908c, 0x0780, 0x190c, 0x7f1c, 0xd0a4, 0x01f8, 0x7824, - 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, - 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003, - 0x1168, 0x7004, 0x0002, 0x7906, 0x78e0, 0x7906, 0x7904, 0x7906, - 0x7906, 0x7906, 0x7906, 0x7906, 0x080c, 0x7971, 0x782c, 0xd09c, - 0x090c, 0x7e3a, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b, - 0x0c10, 0x080c, 0x79a7, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79a7, - 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79c9, - 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, - 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, - 0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x7ba1, 0x79a7, 0x79a7, - 0x79a7, 0x79c9, 0x79a7, 0x79b3, 0x7be2, 0x7c23, 0x7c6a, 0x7c7e, - 0x79a7, 0x79a7, 0x79c9, 0x79b3, 0x79dd, 0x79a7, 0x7a55, 0x7d29, - 0x7d44, 0x79a7, 0x79c9, 0x79a7, 0x79dd, 0x79a7, 0x79a7, 0x7a4b, - 0x7d44, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, - 0x79a7, 0x79a7, 0x79f1, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, - 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x7ec0, 0x79a7, 0x7e6a, 0x79a7, - 0x7e6a, 0x79a7, 0x7a06, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, - 0x79a7, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c, - 0x080c, 0x7e63, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802, - 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b, - 0x0c50, 0x00e9, 0x080c, 0x7e3a, 0x0005, 0x79a7, 0x79b3, 0x7b8d, - 0x79a7, 0x79b3, 0x79a7, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d, - 0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d, - 0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x00e6, - 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, - 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009, - 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff, - 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, - 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120, - 0x7007, 0x0001, 0x0804, 0x7b2a, 0x7007, 0x0003, 0x7012, 0x2900, - 0x7016, 0x701a, 0x704b, 0x7b2a, 0x0005, 0xa864, 0x8007, 0x9084, - 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b45, - 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b45, - 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x79af, 0x8001, - 0x1120, 0x7007, 0x0001, 0x0804, 0x7b61, 0x7007, 0x0003, 0x7012, - 0x2900, 0x7016, 0x701a, 0x704b, 0x7b61, 0x0005, 0xa864, 0x8007, - 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x79af, 0x7007, 0x0001, - 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff, - 0xa86a, 0xa883, 0x0000, 0x080c, 0x63b8, 0x1108, 0x0005, 0x0126, - 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dcb, - 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064, - 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186, - 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8, - 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, - 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, - 0x1120, 0x7007, 0x0001, 0x0804, 0x7d5b, 0x2900, 0x7016, 0x701a, - 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, - 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, - 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x79b7, 0xaab4, - 0x928a, 0x0002, 0x1a04, 0x79b7, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, - 0x9105, 0x0118, 0x2001, 0x7ae8, 0x0018, 0x9280, 0x7ade, 0x2005, - 0x7056, 0x7010, 0x9015, 0x0904, 0x7ac9, 0x080c, 0x1027, 0x1118, - 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, - 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, - 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, - 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, - 0xa17e, 0x080c, 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, - 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, - 0x1040, 0x7014, 0x2048, 0x0804, 0x79b7, 0x7020, 0x2048, 0x7018, - 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, - 0x7a81, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, - 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, - 0x9086, 0x001e, 0x0904, 0x7d5b, 0x0804, 0x7b2a, 0x7ae0, 0x7ae4, - 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, - 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, - 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, - 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, - 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, - 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, - 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, - 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, - 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, - 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c, - 0x61b5, 0x1108, 0x0005, 0x080c, 0x7037, 0x0126, 0x2091, 0x8000, - 0x080c, 0xd135, 0x080c, 0x6dcb, 0x012e, 0x0ca0, 0x080c, 0xd541, - 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c, - 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c, - 0x6245, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6dcb, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000, - 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, - 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x631a, 0x1138, 0x0005, 0x9006, - 0xa87a, 0x080c, 0x6292, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, - 0xa87a, 0xa982, 0x080c, 0x6dcb, 0x012e, 0x0cb0, 0x2001, 0x0028, - 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800, - 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908, - 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, - 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, - 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, - 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, - 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, - 0xa974, 0x080c, 0x6717, 0x11b8, 0x0066, 0xae80, 0x080c, 0x6827, - 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, - 0x004e, 0x00c6, 0x080c, 0x6717, 0x1110, 0x080c, 0x6927, 0x8108, - 0x1f04, 0x7bca, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040, - 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, - 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, - 0x6a88, 0x0580, 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888, - 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, - 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, - 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, - 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, - 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, - 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804, 0x7e18, - 0x012e, 0x0804, 0x7e1b, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, - 0x080c, 0x6a88, 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8, - 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, - 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, - 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, - 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, - 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, - 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, - 0x630a, 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e21, 0x012e, - 0x0804, 0x7e1e, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, - 0x1a75, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, - 0x012e, 0x0804, 0x7e32, 0x012e, 0x0804, 0x7e21, 0x00b6, 0x0126, - 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, - 0x00c6, 0x2061, 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, - 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, - 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb11a, 0x0068, 0x6017, - 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a, - 0x2009, 0x0041, 0x080c, 0xb166, 0xa988, 0x918c, 0xff00, 0x9186, - 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x8916, - 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c, - 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, - 0x0804, 0x7e24, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e1e, 0xa984, - 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, - 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, - 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, - 0xa974, 0x080c, 0x6717, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, - 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004, - 0x601a, 0x0804, 0x7cb9, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, - 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb11a, - 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb11a, 0x00ee, 0x0804, 0x7cb9, - 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, - 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, - 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ee, 0x0804, - 0x7cb9, 0x2061, 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, - 0x7e32, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, - 0x012e, 0x0804, 0x7e32, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e2b, - 0xa883, 0x0007, 0x0804, 0x7e2b, 0xa864, 0x8007, 0x9084, 0x00ff, - 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, - 0x79af, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, - 0x704b, 0x7d5b, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, - 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7ddd, 0x6130, - 0xd194, 0x1904, 0x7e07, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04, - 0x7dd1, 0x6068, 0x9e02, 0x1a04, 0x7dd1, 0x7120, 0x9186, 0x0006, - 0x1904, 0x7dc3, 0x7010, 0x905d, 0x0904, 0x7ddd, 0xb800, 0xd0e4, - 0x1904, 0x7e01, 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086, - 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7e0a, 0xa883, 0x0000, - 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, - 0xd0f4, 0x1904, 0x7e0d, 0x080c, 0x57cd, 0xd09c, 0x1118, 0xa87c, - 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8836, 0x012e, 0x00ee, 0x00be, - 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, - 0xd0f4, 0x1904, 0x7e0d, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, - 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7e2b, 0xd184, 0x0db8, - 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6717, 0x15d0, 0xb800, - 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, - 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, - 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x57d1, 0xd0fc, - 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02, - 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, - 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, - 0x1904, 0x7d67, 0x7003, 0x0002, 0x0804, 0x7d67, 0xa883, 0x0028, - 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, - 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, - 0x601b, 0x0014, 0x080c, 0xe4ba, 0x012e, 0x00ee, 0x00be, 0x0005, - 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, - 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, - 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, - 0x012e, 0x0005, 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x882d, - 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, - 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f1c, - 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, - 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, - 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, - 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f1c, - 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb091, - 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, - 0x1138, 0x6008, 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098, - 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, - 0x918c, 0x00ff, 0x080c, 0x2889, 0x1540, 0x00b6, 0x080c, 0x6717, - 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, - 0x080c, 0xb166, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0005, - 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, - 0xaa74, 0x9282, 0x0004, 0x1a04, 0x7f0d, 0xa97c, 0x9188, 0x1000, - 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, - 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb091, - 0x1118, 0x080c, 0xb139, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7eeb, - 0x7ef0, 0x7ef3, 0x7ef9, 0x2019, 0x0002, 0x080c, 0xe8b0, 0x0060, - 0x080c, 0xe847, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe862, - 0x0018, 0xa980, 0x080c, 0xe847, 0x080c, 0xb0e7, 0xa887, 0x0000, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x00be, 0x001e, - 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, - 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, - 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f1e, - 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001, - 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, - 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, - 0x210c, 0xd1ec, 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001, - 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, - 0xd08c, 0x0904, 0x7f9e, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e2, - 0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, - 0x908a, 0x2000, 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fa5, - 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, - 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, - 0x080c, 0xed6d, 0x080c, 0x84c7, 0x7817, 0x0140, 0x00a8, 0x9584, - 0x0076, 0x1118, 0x080c, 0x8525, 0x19c0, 0xd5a4, 0x0148, 0x0046, - 0x0056, 0x080c, 0x8000, 0x080c, 0x238f, 0x005e, 0x004e, 0x0020, - 0x080c, 0xed6d, 0x7817, 0x0140, 0x080c, 0x7563, 0x0168, 0x2001, - 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, - 0x2003, 0x0008, 0x2003, 0x0000, 0x080c, 0x7fe1, 0x2001, 0x19f2, - 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x0002, 0x7fb7, 0x82cf, - 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7817, 0x0140, - 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x7000, - 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, - 0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, - 0x5837, 0x0070, 0x080c, 0x8020, 0x0058, 0x9286, 0x3000, 0x1118, - 0x080c, 0x8207, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83ee, - 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, - 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, - 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, - 0x2518, 0x080c, 0x4be3, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, - 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, - 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, - 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, - 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, - 0x080c, 0x4be3, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, - 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, - 0x0120, 0x9096, 0x0023, 0x1904, 0x81d8, 0x9186, 0x0023, 0x15c0, - 0x080c, 0x848c, 0x0904, 0x81d8, 0x6120, 0x9186, 0x0001, 0x0150, - 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, - 0x1904, 0x81d8, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, - 0x2009, 0x0015, 0x080c, 0xb166, 0x0804, 0x81d8, 0x908e, 0x0214, - 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb166, - 0x0804, 0x81d8, 0x908e, 0x0100, 0x1904, 0x81d8, 0x7034, 0x9005, - 0x1904, 0x81d8, 0x2009, 0x0016, 0x080c, 0xb166, 0x0804, 0x81d8, - 0x9186, 0x0022, 0x1904, 0x81d8, 0x7030, 0x908e, 0x0300, 0x1580, - 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, - 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, - 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x28d2, 0x7932, - 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2889, 0x695e, 0x703c, - 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, - 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0017, 0x0804, 0x8188, - 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x81d8, 0x080c, - 0x7563, 0x0120, 0x2009, 0x001d, 0x0804, 0x8188, 0x68dc, 0xc0a5, - 0x68de, 0x2009, 0x0030, 0x0804, 0x8188, 0x908e, 0x0500, 0x1140, - 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0018, 0x0804, 0x8188, - 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x8188, 0x908e, - 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x8188, 0x908e, 0x5200, - 0x1140, 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x001b, 0x0804, - 0x8188, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81d8, - 0x2009, 0x001c, 0x0804, 0x8188, 0x908e, 0x1300, 0x1120, 0x2009, - 0x0034, 0x0804, 0x8188, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, - 0x1904, 0x81d8, 0x2009, 0x0024, 0x0804, 0x8188, 0x908c, 0xff00, - 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, - 0xd09c, 0x0904, 0x8188, 0x080c, 0xdc7f, 0x1904, 0x81d8, 0x0804, - 0x8186, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, - 0x0804, 0x8188, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, - 0x8188, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, - 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, - 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4be3, 0x004e, - 0x8108, 0x0f04, 0x813c, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, - 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, - 0x0804, 0x8188, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, - 0x8188, 0x908e, 0x5400, 0x1138, 0x080c, 0x8592, 0x1904, 0x81d8, - 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85ba, - 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, - 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, - 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, - 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, - 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, - 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, - 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, - 0x1904, 0x81db, 0x080c, 0x66ac, 0x1904, 0x81db, 0xbe12, 0xbd16, - 0x001e, 0x0016, 0x080c, 0x7563, 0x01c0, 0x68dc, 0xd08c, 0x1148, - 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, - 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, - 0x1120, 0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168, - 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, - 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xb091, 0x01a8, - 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, - 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb166, - 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, - 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x080c, 0xb139, - 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, - 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, - 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, - 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x937d, 0x08a0, 0x080c, - 0x8601, 0x1158, 0x080c, 0x336f, 0x1140, 0x7010, 0x9084, 0xff00, - 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, - 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, - 0x080c, 0x848c, 0x0904, 0x8267, 0x7124, 0x610a, 0x7030, 0x908e, - 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, - 0xb166, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, - 0x2009, 0x0016, 0x080c, 0xb166, 0x0450, 0x9186, 0x0032, 0x1538, - 0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, - 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b8, 0x080c, - 0x66ac, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xb091, 0x0178, 0x2b08, - 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, - 0x080c, 0xb166, 0x080c, 0x98e7, 0x0010, 0x00ce, 0x001e, 0x004e, - 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, - 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, - 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x82c9, 0x9596, 0xfffe, - 0x1120, 0x2009, 0x007e, 0x0804, 0x82c9, 0x9596, 0xfffc, 0x1118, - 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, - 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, - 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, - 0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, - 0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, - 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, - 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, - 0x1f04, 0x829e, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, - 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, - 0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, - 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, - 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x82f7, - 0x82f7, 0x82f7, 0x849e, 0x82f7, 0x8300, 0x832b, 0x83b9, 0x82f7, - 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x7817, - 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, - 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, - 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, - 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, - 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, - 0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, - 0x98e7, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, - 0x838f, 0x7110, 0xd1bc, 0x1904, 0x838f, 0x7108, 0x700c, 0x2028, - 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, - 0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, - 0x9106, 0x0904, 0x838f, 0x080c, 0x66ac, 0x1904, 0x838f, 0xbe12, - 0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, - 0x0600, 0x11a0, 0x080c, 0xb091, 0x05e8, 0x2b08, 0x7028, 0x6046, - 0x702c, 0x604a, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, - 0x6156, 0x2009, 0x0044, 0x080c, 0xdf02, 0x0408, 0x080c, 0x6a8c, - 0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x826b, 0x11c0, 0x0898, - 0x080c, 0xb091, 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, - 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, - 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x7817, - 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00ce, - 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, - 0x8049, 0x080c, 0x4be3, 0x080c, 0xb139, 0x0d48, 0x2b08, 0x6112, - 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, - 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x08b0, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, - 0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, - 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, - 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, - 0x080c, 0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, - 0x090c, 0x98e7, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, - 0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8601, - 0x1180, 0x080c, 0x336f, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, - 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, - 0x000b, 0x0005, 0x8408, 0x8409, 0x8408, 0x8408, 0x846e, 0x847d, - 0x0005, 0x00b6, 0x700c, 0x7108, 0x080c, 0x2889, 0x1904, 0x846c, - 0x080c, 0x66ac, 0x1904, 0x846c, 0xbe12, 0xbd16, 0x7110, 0xd1bc, - 0x0540, 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x846c, - 0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a94, - 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x848c, 0x00ce, - 0x05d8, 0x080c, 0xb091, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2bb, - 0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb166, - 0x0458, 0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, - 0x6a94, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xb091, 0x2b08, - 0x01d8, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0005, 0x7120, 0x610a, - 0x2009, 0x0088, 0x080c, 0xb166, 0x0078, 0x080c, 0xb091, 0x2b08, - 0x0158, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a, - 0x2009, 0x0001, 0x080c, 0xb166, 0x00be, 0x0005, 0x7110, 0xd1bc, - 0x0158, 0x00d1, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a, - 0x2009, 0x0089, 0x080c, 0xb166, 0x0005, 0x7110, 0xd1bc, 0x0158, - 0x0059, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a, 0x2009, - 0x008a, 0x080c, 0xb166, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, - 0x1158, 0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, - 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, - 0x1cd0, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, - 0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, - 0x1120, 0x2009, 0x0051, 0x080c, 0xb166, 0x7817, 0x0140, 0x2001, - 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00be, 0x0005, 0x2031, - 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, - 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, - 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, - 0x080c, 0xb091, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x15a0, 0x080c, 0x66ac, - 0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, - 0xd2bb, 0x080c, 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, - 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, - 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, - 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, - 0x080c, 0x98e7, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb0e7, - 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, - 0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x857c, - 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, - 0x857e, 0x7030, 0x908e, 0x0400, 0x0904, 0x857e, 0x908e, 0x6000, - 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, - 0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a4a, - 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, - 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, - 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, - 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, - 0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x848c, 0x0128, 0x6004, - 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, - 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, - 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, - 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, - 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, - 0x1805, 0x2011, 0x027a, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148, - 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0d3, - 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, - 0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, - 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, - 0x1805, 0x2011, 0x0272, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148, - 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0d3, - 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, - 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, - 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, - 0x1130, 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, - 0x0005, 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, - 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, - 0x2071, 0x19fc, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, - 0x707a, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, - 0xa513, 0x7032, 0x703a, 0x703f, 0x0064, 0x7037, 0xa57b, 0x7047, - 0xffff, 0x704a, 0x704f, 0x565f, 0x7052, 0x7063, 0x87a4, 0x080c, - 0x1027, 0x090c, 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f, - 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f2, - 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c, - 0x2004, 0x9005, 0x190c, 0x8812, 0x2001, 0x1869, 0x2004, 0xd0c4, - 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001, - 0x20d1, 0x0000, 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001, - 0x0126, 0x2091, 0x8000, 0x080c, 0x87e9, 0x7048, 0x900d, 0x0148, - 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, - 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, - 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, - 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8, - 0x702c, 0x8001, 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c, - 0x9184, 0x0030, 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0, - 0x7038, 0x9005, 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7563, - 0x0178, 0x00e6, 0x2071, 0x19e9, 0x080c, 0xa609, 0x00ee, 0x1140, - 0x2009, 0x1a87, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068, - 0x001e, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, - 0x090c, 0xa6bf, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, - 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, - 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, - 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, - 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, - 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, - 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, - 0x080f, 0x012e, 0x7004, 0x0002, 0x871a, 0x871b, 0x8737, 0x00e6, - 0x2071, 0x19fc, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, - 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c, - 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a, - 0x00ee, 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x6717, 0x1168, - 0xb888, 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, - 0x0016, 0x080c, 0x98e7, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, - 0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, - 0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, - 0x6042, 0x1110, 0x080c, 0xd14c, 0x6018, 0x9005, 0x0558, 0x8001, - 0x601a, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, - 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, - 0xce3f, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, - 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, - 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, - 0x080c, 0xcb2b, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a, - 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, - 0x0005, 0x2001, 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, - 0x19fc, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08, - 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e, - 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, - 0x705e, 0x2001, 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, - 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, - 0x080c, 0x10f8, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, - 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, - 0x863c, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, - 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a, - 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, - 0x19fc, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, - 0x0005, 0x2069, 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec, - 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, - 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, - 0x69ea, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, - 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee, - 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, - 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, - 0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, - 0x00c6, 0x2061, 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, - 0x8003, 0x8003, 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a, - 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014, - 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, - 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, - 0x00c0, 0x918e, 0x00c0, 0x0904, 0x88c0, 0xd0b4, 0x1168, 0xd0bc, - 0x1904, 0x8899, 0x2009, 0x0006, 0x080c, 0x88ed, 0x0005, 0x900e, - 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003, - 0x0120, 0x918e, 0x0003, 0x1904, 0x88e7, 0x908c, 0x2020, 0x918e, - 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, - 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb166, - 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xb166, 0x6110, - 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, - 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, - 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, - 0x1904, 0x88e7, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, - 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120, - 0x2009, 0x0042, 0x080c, 0xb166, 0x0005, 0x6110, 0x00b6, 0x2158, - 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, - 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, - 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, - 0x080c, 0xb166, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, - 0x0043, 0x080c, 0xb166, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, - 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, - 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce3f, - 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, - 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, - 0x2061, 0x1a75, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, - 0x6206, 0x00ce, 0x080c, 0x6c0a, 0x6014, 0x904d, 0x0076, 0x2039, - 0x0000, 0x190c, 0x8836, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, - 0x2061, 0x1a75, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, - 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, - 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, - 0x1925, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, - 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b, - 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, - 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, - 0x1925, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, - 0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, - 0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, - 0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, - 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, - 0x0000, 0x0006, 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a, - 0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611, - 0x9006, 0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, - 0x012e, 0x0005, 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a, - 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, - 0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, - 0x9006, 0x9080, 0x0008, 0x1f04, 0x89a9, 0x71c0, 0x9102, 0x02e0, - 0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb091, 0x6023, - 0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, - 0x8000, 0x080c, 0x8b27, 0x012e, 0x1f04, 0x89b5, 0x9006, 0x00ce, - 0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, - 0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, - 0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, - 0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c, - 0x0dc5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, - 0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, - 0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, - 0x8109, 0x0160, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00, - 0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, - 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, - 0x2071, 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8a21, 0x8a1a, - 0x8a1a, 0x0005, 0x8a2b, 0x8a81, 0x8a81, 0x8a81, 0x8a82, 0x8a93, - 0x8a93, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, - 0x9106, 0x1904, 0x8a73, 0x7814, 0xd0bc, 0x1904, 0x8a7c, 0x012e, - 0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8ac5, 0x0005, - 0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, - 0x2001, 0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, - 0x0e50, 0x080c, 0x8c1f, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, - 0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8d28, 0x2100, - 0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, - 0x1a1c, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, - 0x1117, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a33, - 0x080c, 0x8bf7, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, - 0x8a33, 0x0005, 0x700c, 0x0002, 0x8a87, 0x8a8a, 0x8a89, 0x080c, - 0x8a29, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, - 0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, - 0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, - 0x9006, 0x0068, 0x0006, 0x080c, 0x8d28, 0x2100, 0xaa8c, 0x9210, - 0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, - 0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bf7, 0x012e, - 0x0005, 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac3, 0x8ac3, - 0x8ac1, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, - 0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01b0, 0x00e6, 0x2071, - 0x193e, 0x080c, 0x8b77, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027, - 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948, - 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, - 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, - 0x9084, 0x000f, 0x2068, 0x9d88, 0x20e8, 0x2165, 0x0056, 0x2029, - 0x0000, 0x080c, 0x8cad, 0x080c, 0x20a0, 0x1dd8, 0x005e, 0x00ae, - 0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101, - 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b86, 0x012e, - 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078, - 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6, - 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005, - 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8df6, 0x2005, 0x906d, 0x090c, - 0x0dc5, 0x9b80, 0x8dee, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114, - 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, - 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, - 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be3, - 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806, - 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d, - 0x6856, 0x2011, 0x8025, 0x080c, 0x4be3, 0x684c, 0x0096, 0x904d, - 0x090c, 0x0dc5, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000, - 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005, - 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814, - 0x9005, 0x090c, 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101, - 0x190c, 0x0dc5, 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080, - 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208, - 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005, - 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048, - 0x9005, 0x190c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0, - 0x080c, 0xb0e7, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009, - 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001, - 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150, - 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x6013, 0x0000, 0x601b, - 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c, - 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925, - 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112, - 0x2001, 0x003b, 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, - 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, - 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, - 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8d76, 0x0170, 0x080c, - 0x8dab, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, - 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, - 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100, - 0x9202, 0x1618, 0x080c, 0x8dab, 0x090c, 0x0dc5, 0x7018, 0x9005, - 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, - 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, - 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, - 0x9080, 0x000a, 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, - 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, - 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f, - 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, - 0x0003, 0x7104, 0x080c, 0x8d28, 0x810c, 0x2100, 0x9318, 0x8003, - 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, - 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, - 0x8d31, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, - 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, - 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, - 0x8c1f, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, - 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8c5e, 0x012e, 0x00ee, - 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, - 0x0126, 0x2091, 0x8000, 0x9580, 0x8dee, 0x2005, 0x9075, 0x090c, - 0x0dc5, 0x080c, 0x8d03, 0x012e, 0x9580, 0x8dea, 0x2005, 0x9075, - 0x090c, 0x0dc5, 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, - 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, - 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, - 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ced, 0x8ced, 0x8cef, - 0x8ced, 0x8cef, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8cf5, - 0x8ced, 0x8cf5, 0x8ced, 0x8ced, 0x8ced, 0x080c, 0x0dc5, 0x4104, - 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, - 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, - 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, - 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, - 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, - 0x080c, 0x8dba, 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, - 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, - 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, - 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, - 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, - 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d74, - 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, - 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, - 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, - 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, - 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, - 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, - 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8df2, 0x2005, 0x9005, - 0x090c, 0x0dc5, 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, - 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, - 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, - 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, - 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, - 0x1040, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, - 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, - 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, - 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, - 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, - 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, - 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, - 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, - 0x009e, 0x0005, 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000, - 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, - 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, - 0x2071, 0x1877, 0x080c, 0x8f16, 0xa067, 0x0023, 0x6010, 0x905d, - 0x0904, 0x8eeb, 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, - 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, - 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, - 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, - 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20e8, 0x2c65, - 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, - 0x9082, 0x001b, 0x0002, 0x8e56, 0x8e56, 0x8e58, 0x8e56, 0x8e56, - 0x8e56, 0x8e5a, 0x8e56, 0x8e56, 0x8e56, 0x8e5c, 0x8e56, 0x8e56, - 0x8e56, 0x8e5e, 0x8e56, 0x8e56, 0x8e56, 0x8e60, 0x8e56, 0x8e56, - 0x8e56, 0x8e62, 0x8e56, 0x8e56, 0x8e56, 0x8e64, 0x080c, 0x0dc5, - 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, - 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, - 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x8e88, 0x8e86, 0x8e86, - 0x8e86, 0x8e86, 0x8e86, 0x8e8a, 0x8e86, 0x8e86, 0x8e86, 0x8e86, - 0x8e86, 0x8e8c, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e8e, - 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e90, 0x080c, 0x0dc5, - 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, - 0xa1e0, 0x2600, 0x0002, 0x8eac, 0x8eae, 0x8eb0, 0x8eb2, 0x8eb4, - 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, 0x8ec0, 0x8ec2, 0x8ec4, - 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, 0x8ed0, 0x8ed2, 0x8ed4, - 0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x080c, 0x0dc5, 0xb9e2, 0x0468, - 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, - 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, - 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, - 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, - 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, - 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, - 0x080c, 0x20a0, 0x090c, 0x0dc5, 0x0804, 0x8e30, 0x00ae, 0x00be, - 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, - 0x00ff, 0x9006, 0x0804, 0x8e12, 0x0006, 0x0016, 0x00b6, 0x6010, - 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005, - 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, - 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be3, - 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, - 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, - 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, - 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300, - 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001, - 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, - 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, - 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5, - 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, - 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, - 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, - 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, - 0x1f04, 0x8f6b, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, - 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, - 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, - 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, - 0x0000, 0x904d, 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b27, - 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, - 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, - 0x0006, 0x0156, 0x080c, 0x2889, 0x015e, 0x11b0, 0x080c, 0x66ac, - 0x190c, 0x0dc5, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb091, - 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, - 0xb166, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, - 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, - 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe2, 0x9033, 0x8fe0, 0x8fe0, 0x8fe0, - 0x909a, 0x8fe0, 0x90d7, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, - 0x080c, 0x0dc5, 0x9182, 0x0040, 0x0002, 0x8ff5, 0x8ff5, 0x8ff5, - 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff7, 0x900c, - 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x901f, 0x080c, 0x0dc5, 0x0096, - 0x080c, 0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000, - 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bcf, - 0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0x9897, 0x00d6, 0x6114, - 0x080c, 0xce3f, 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dcb, - 0x009e, 0x00de, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0x080c, - 0x9897, 0x080c, 0x324b, 0x6114, 0x0096, 0x2148, 0x080c, 0xce3f, - 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7, - 0x080c, 0x9a09, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, - 0x0002, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, - 0x904e, 0x9050, 0x904e, 0x904e, 0x904e, 0x9096, 0x904e, 0x904e, - 0x904e, 0x904e, 0x904e, 0x904e, 0x9057, 0x904e, 0x080c, 0x0dc5, - 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x9096, 0x6024, - 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, 0x8dfa, 0x0096, - 0xa8a8, 0x2048, 0x080c, 0x6b67, 0x009e, 0xa8ab, 0x0000, 0x6010, - 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0xae88, - 0x00b6, 0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01e0, 0x2071, - 0x193e, 0x080c, 0x8b77, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, - 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900, - 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8aee, 0x00fe, - 0x00ee, 0x009e, 0x0005, 0x080c, 0x8b27, 0x0cd0, 0x080c, 0x9144, - 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, 0x90ae, 0x90ae, - 0x90ae, 0x90b0, 0x90ae, 0x90ae, 0x90ae, 0x90d5, 0x90ae, 0x90ae, - 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x080c, 0x0dc5, - 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0, - 0xa84a, 0xa837, 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a, - 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, - 0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, - 0x080c, 0x9a09, 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c, - 0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, - 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c, - 0xb0e7, 0x009e, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, - 0x0096, 0x0013, 0x009e, 0x0005, 0x9104, 0x9104, 0x9104, 0x9106, - 0x9117, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, - 0x9104, 0x9104, 0x9104, 0x9104, 0x080c, 0x0dc5, 0x080c, 0xaa3f, - 0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, - 0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0005, 0x0461, - 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0096, 0x0013, - 0x009e, 0x0005, 0x9132, 0x9132, 0x9132, 0x9134, 0x9144, 0x9132, - 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, - 0x9132, 0x9132, 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9, - 0x703c, 0x9c06, 0x1120, 0x2019, 0x0000, 0x080c, 0xa85d, 0x080c, - 0xaa3f, 0x00ee, 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, - 0x00e6, 0x601b, 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, - 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x2071, 0x193e, 0x080c, - 0x8b77, 0x0160, 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, - 0x2c78, 0x080c, 0x8aee, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, - 0x0000, 0xa8a8, 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000, - 0x080c, 0x8b27, 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, - 0x20a9, 0x0010, 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6, - 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, - 0x3e08, 0x1208, 0x9200, 0x1f04, 0x918c, 0x93a6, 0x0008, 0x1118, - 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e, - 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, - 0x20a9, 0x0010, 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039, - 0x0100, 0x273c, 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, - 0x3e08, 0x0228, 0x911a, 0x1220, 0x1f04, 0x91b6, 0x0028, 0x911a, - 0x2308, 0x8210, 0x1f04, 0x91b6, 0x0006, 0x3200, 0x9084, 0xefff, - 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, - 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, - 0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, - 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xada2, 0x0401, - 0x080c, 0xad8d, 0x00e9, 0x080c, 0xad90, 0x00d1, 0x080c, 0xad93, - 0x00b9, 0x080c, 0xad96, 0x00a1, 0x080c, 0xad99, 0x0089, 0x080c, - 0xad9c, 0x0071, 0x080c, 0xad9f, 0x0059, 0x01de, 0x014e, 0x015e, - 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005, - 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, - 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x9229, - 0x924d, 0x928e, 0x922f, 0x924d, 0x9229, 0x9227, 0x9227, 0x080c, - 0x0dc5, 0x080c, 0x8789, 0x080c, 0x98e7, 0x00ce, 0x0005, 0x62c0, - 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5f8a, 0x080c, 0x8703, - 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fca, - 0x0c88, 0x62c0, 0x080c, 0xaede, 0x080c, 0x5f8a, 0x7807, 0x0003, - 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, 0x8789, 0x6220, - 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065, - 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb166, 0x00ce, 0x0005, - 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, - 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x2bf0, 0x0278, 0x00c6, - 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000, - 0x7827, 0x0000, 0x00ce, 0x080c, 0x98e7, 0x0c00, 0x080c, 0xa4d9, - 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0xaede, 0x080c, 0xedaa, - 0x2009, 0x0014, 0x080c, 0xb166, 0x00ce, 0x0880, 0x2001, 0x1a05, - 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, - 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1b8, 0x00ce, - 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5, - 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce, - 0x00be, 0x080c, 0x2bf0, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c, - 0x905d, 0x090c, 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160, - 0x080c, 0xb0e7, 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e, - 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c, - 0x98e7, 0x0868, 0x080c, 0xa4d9, 0x0850, 0x2011, 0x0130, 0x2214, - 0x080c, 0xaede, 0x080c, 0xedaa, 0x7824, 0x9065, 0x2009, 0x0014, - 0x080c, 0xb166, 0x00de, 0x00ce, 0x00be, 0x0804, 0x929f, 0x00c6, - 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1f0c, 0x6024, 0x6027, - 0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c, - 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xb166, 0x00ce, 0x0005, - 0x2011, 0x1a08, 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0, - 0x7944, 0x9192, 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188, - 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, - 0x9085, 0x0012, 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c, - 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, - 0x6016, 0x08a0, 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb166, - 0x0868, 0x7848, 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, - 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003, - 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, - 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168, - 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e, - 0x00de, 0x0804, 0x98e7, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818, - 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00, - 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856, - 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, - 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003, - 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, - 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, - 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce, - 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, - 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660, - 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9429, 0x6010, 0x2058, - 0xb8a0, 0x9206, 0x1904, 0x9424, 0x87ff, 0x0120, 0x6054, 0x9106, - 0x1904, 0x9424, 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, - 0x080c, 0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, - 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c, - 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce3f, - 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004, - 0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd135, 0x080c, 0xec9b, - 0x080c, 0x6dcb, 0x007e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c, - 0xb11a, 0x00ce, 0x0804, 0x93c3, 0x2c78, 0x600c, 0x2060, 0x0804, - 0x93c3, 0x85ff, 0x0120, 0x0036, 0x080c, 0x9a09, 0x003e, 0x012e, - 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e, - 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, 0xec9b, 0x080c, - 0xe8e3, 0x007e, 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009, - 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dcb, - 0x080c, 0xb0e7, 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086, - 0x000a, 0x0904, 0x940e, 0x0804, 0x9407, 0x0006, 0x0066, 0x0096, - 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079, - 0x19e9, 0x7838, 0x9065, 0x0904, 0x94ba, 0x600c, 0x0006, 0x600f, - 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, - 0xa85d, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a, - 0x003e, 0x080c, 0xce3f, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086, - 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005, - 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040, - 0x9005, 0x11a8, 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004, - 0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c, 0xb11a, 0x000e, - 0x0804, 0x9472, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, - 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, - 0x080c, 0xe8e3, 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, - 0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0c10, 0x6020, 0x9086, 0x000a, - 0x09a8, 0x0868, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, - 0x95c5, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, - 0x19e9, 0x2091, 0x8000, 0x080c, 0x965c, 0x080c, 0x96ec, 0x012e, - 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, - 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, - 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x958a, 0x6010, 0x2058, - 0xb8a0, 0x9206, 0x1904, 0x9585, 0x88ff, 0x0120, 0x6054, 0x9106, - 0x1904, 0x9585, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, - 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd, - 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, - 0x0804, 0x9585, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, - 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, - 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3f, - 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xd047, 0x1118, - 0x080c, 0xbacb, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, - 0x0016, 0x0036, 0x0086, 0x080c, 0xd135, 0x080c, 0xec9b, 0x080c, - 0x6dcb, 0x008e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c, 0xb11a, - 0x080c, 0xa905, 0x00ce, 0x0804, 0x9503, 0x2c78, 0x600c, 0x2060, - 0x0804, 0x9503, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, - 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xec9b, 0x080c, 0xe8e3, - 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xbacb, 0x6020, 0x9086, - 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, - 0x956b, 0x9086, 0x008b, 0x0904, 0x956b, 0x0840, 0x6020, 0x9086, - 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, - 0x9086, 0x008b, 0x09b0, 0x0804, 0x957e, 0x00b6, 0x00a6, 0x0096, - 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, - 0x905d, 0x0904, 0x9655, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, - 0x19e9, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, - 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, - 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, - 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, - 0x080c, 0x663f, 0x0904, 0x9651, 0x7624, 0x86ff, 0x0904, 0x9640, - 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, - 0x68c0, 0x9005, 0x0560, 0x080c, 0x8789, 0x080c, 0xa4fd, 0x68c3, - 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, - 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, - 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, - 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, - 0x8001, 0xb83e, 0x2660, 0x080c, 0xb11a, 0x00ce, 0x0048, 0x00de, - 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95f8, - 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, - 0xd135, 0x080c, 0xec9b, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804, - 0x95f8, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, - 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, - 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x96bf, 0x600c, 0x0006, - 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, - 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd, - 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6a24, 0x1520, - 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, - 0xce3d, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd047, - 0x1118, 0x080c, 0xbacb, 0x0060, 0x080c, 0x6a24, 0x1168, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a, - 0x080c, 0xb11a, 0x080c, 0xa905, 0x000e, 0x0804, 0x9663, 0x7e16, - 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, - 0x9086, 0x0006, 0x1118, 0x080c, 0xe8e3, 0x0c50, 0x080c, 0xbacb, - 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, - 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, - 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, - 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, - 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x976c, 0xb854, 0x0006, - 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, - 0x663f, 0x0904, 0x9769, 0x7e24, 0x86ff, 0x0904, 0x975c, 0x9680, - 0x0005, 0x2004, 0x9906, 0x1904, 0x975c, 0x00d6, 0x2069, 0x0100, - 0x68c0, 0x9005, 0x0904, 0x9753, 0x080c, 0x8789, 0x080c, 0xa4fd, - 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, - 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, - 0x81ff, 0x1518, 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c, - 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, - 0xb11a, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, - 0x630a, 0x00ce, 0x0804, 0x96ff, 0x89ff, 0x0138, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804, - 0x96ff, 0x000e, 0x0804, 0x96f3, 0x781e, 0x781a, 0x00de, 0x00ce, - 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, - 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, - 0x9606, 0x1170, 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080, - 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, - 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, - 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, - 0x00ce, 0x04b8, 0x080c, 0xa4fd, 0x78c3, 0x0000, 0x080c, 0xaa2f, - 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, - 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, - 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, - 0xaa2f, 0x003e, 0x080c, 0x663f, 0x00c6, 0xb83c, 0x9005, 0x0110, - 0x8001, 0xb83e, 0x2660, 0x080c, 0xb0e7, 0x00ce, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0xd135, 0x080c, 0x6dcb, 0x080c, - 0xa905, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, - 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, - 0x2071, 0x19e9, 0x7004, 0x9084, 0x0007, 0x0002, 0x97f8, 0x97fc, - 0x981a, 0x9843, 0x9881, 0x97f8, 0x9813, 0x97f6, 0x080c, 0x0dc5, - 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, - 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, - 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, - 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, - 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc, - 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, - 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, - 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98e7, - 0x0ca8, 0x7218, 0x721e, 0x080c, 0x98e7, 0x0c80, 0xc2ec, 0x2202, - 0x080c, 0x9a09, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, - 0x1160, 0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, - 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, - 0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, - 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, - 0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc, 0xb802, 0x080c, - 0xa905, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, - 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, - 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0xa905, 0x600c, 0x9015, - 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, - 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, - 0x2069, 0x19e9, 0x6830, 0x9084, 0x0003, 0x0002, 0x98a4, 0x98a6, - 0x98ca, 0x98a2, 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840, - 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, - 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, - 0x2011, 0x1a08, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, - 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, - 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, - 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, - 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, - 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, - 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a09, - 0x2001, 0x19f5, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, - 0x19e9, 0x6804, 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001, - 0x1837, 0x2004, 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004, - 0x9086, 0xaaaa, 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118, - 0xd084, 0x1118, 0x0028, 0x080c, 0x9a09, 0x000e, 0x00de, 0x0005, - 0x000e, 0x0002, 0x9924, 0x99dd, 0x99dd, 0x99dd, 0x99dd, 0x99df, - 0x99dd, 0x9922, 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de, - 0x0005, 0x00c6, 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040, - 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, - 0x7563, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, - 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, - 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, - 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de, 0x0005, - 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99c7, 0xb84c, - 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, - 0x920e, 0x0904, 0x99c7, 0x0028, 0x6818, 0x920e, 0x0904, 0x99c7, - 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, - 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0be, 0x0904, - 0x99c7, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, - 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, - 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, - 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, - 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, - 0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa02d, - 0x2069, 0x19e9, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, - 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, - 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, - 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, - 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x663f, 0x080c, 0xaefe, - 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, - 0x680c, 0x9065, 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, - 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7563, 0x0138, + 0x080c, 0x2908, 0x9006, 0x080c, 0x2d52, 0x6043, 0x0090, 0x6043, + 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x000e, + 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086, 0x0000, + 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086, + 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, + 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, + 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, + 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2928, + 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3211, + 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, + 0x2e04, 0x0130, 0x080c, 0xd55a, 0x1128, 0x9085, 0x0010, 0x0010, + 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, + 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016, + 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a, + 0x20a9, 0x0012, 0x1d04, 0x75d2, 0x2091, 0x6000, 0x1f04, 0x75d2, + 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, + 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2908, + 0x2001, 0x00a0, 0x0006, 0x080c, 0xd561, 0x000e, 0x0130, 0x080c, + 0x2d70, 0x9006, 0x080c, 0x2d7c, 0x0010, 0x080c, 0x2d52, 0x000e, + 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x2bef, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, + 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x7690, 0x2001, 0x180c, + 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, + 0x0200, 0x2001, 0x0090, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6024, + 0xd0cc, 0x1518, 0x1d04, 0x763f, 0x2091, 0x6000, 0x1f04, 0x763f, + 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7, + 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2001, 0x00a0, 0x080c, + 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0xd561, 0x0110, + 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c, 0x1b2f, 0x60e3, + 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908, 0x60e2, 0x2001, + 0x0080, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, + 0x1e00, 0x080c, 0x2c7a, 0x6024, 0x910c, 0x0138, 0x1d04, 0x7675, + 0x2091, 0x6000, 0x1f04, 0x7675, 0x0818, 0x6028, 0x9085, 0x1e00, + 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, + 0x080c, 0xd561, 0x0110, 0x080c, 0x0d33, 0x9006, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, + 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, + 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7d, 0x2d04, + 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, + 0x6884, 0x9005, 0x1904, 0x7703, 0x2001, 0x0088, 0x080c, 0x2d52, + 0x9006, 0x60e2, 0x6886, 0x080c, 0x2908, 0x2069, 0x0200, 0x6804, + 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, + 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, + 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x76e5, 0x2091, + 0x6000, 0x1f04, 0x76e5, 0x0804, 0x7733, 0x2069, 0x0140, 0x20a9, + 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c7a, 0x6024, + 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x76f1, 0x2091, + 0x6000, 0x1f04, 0x76f1, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, + 0x0002, 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, + 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127, + 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b2f, 0x2001, 0x0080, 0x080c, + 0x2d52, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, + 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, + 0x2908, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, + 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, + 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2069, + 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c, + 0x6127, 0x0804, 0x77ce, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, + 0xc1b5, 0x2102, 0x080c, 0x73cc, 0x2069, 0x0140, 0x2001, 0x0080, + 0x080c, 0x2d52, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, + 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, + 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0027, + 0x7003, 0x0001, 0x0804, 0x77ce, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0x080c, 0x2c7a, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, + 0x1d04, 0x778c, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, + 0x8642, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, + 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400, 0x0026, 0x2011, + 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x002e, + 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, + 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908, + 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, + 0x1800, 0x080c, 0xd55a, 0x1904, 0x783c, 0x7130, 0xd184, 0x1170, + 0x080c, 0x33a0, 0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, + 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x783c, 0x2011, 0x1848, + 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e, 0x080c, 0xe915, + 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, + 0x9186, 0x0080, 0x0188, 0x080c, 0x671d, 0x1170, 0x2120, 0x9006, + 0x0016, 0x2009, 0x000e, 0x080c, 0xe9a5, 0x2009, 0x0001, 0x2011, + 0x0100, 0x080c, 0x891c, 0x001e, 0x8108, 0x1f04, 0x7805, 0x00be, + 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, + 0x0004, 0x080c, 0x3211, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, + 0x007f, 0x900e, 0x080c, 0x671d, 0x1110, 0x080c, 0x6141, 0x8108, + 0x1f04, 0x7832, 0x00be, 0x015e, 0x080c, 0x1b2f, 0x080c, 0xb072, + 0x60e3, 0x0000, 0x080c, 0x6127, 0x080c, 0x7495, 0x00ee, 0x00ce, + 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197e, + 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000, 0x0005, + 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d, 0x2003, + 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x704e, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x7052, + 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, + 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, + 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, + 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, + 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, + 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, + 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, + 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa, + 0x6807, 0x0001, 0x00de, 0x080c, 0x7e40, 0x9006, 0x00ee, 0x0005, + 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011, 0x0100, 0x2214, + 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x1f04, + 0x78c4, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, + 0x0002, 0x78e3, 0x78e4, 0x791c, 0x7977, 0x7a87, 0x78e1, 0x78e1, + 0x7ab1, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040, 0x782c, 0x908c, + 0x0780, 0x190c, 0x7f22, 0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006, + 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, + 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003, 0x1168, 0x7004, + 0x0002, 0x790c, 0x78e6, 0x790c, 0x790a, 0x790c, 0x790c, 0x790c, + 0x790c, 0x790c, 0x080c, 0x7977, 0x782c, 0xd09c, 0x090c, 0x7e40, + 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, + 0x79ad, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79cf, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79b9, 0x79ad, 0x7ba7, 0x79ad, 0x79ad, 0x79ad, 0x79cf, + 0x79ad, 0x79b9, 0x7be8, 0x7c29, 0x7c70, 0x7c84, 0x79ad, 0x79ad, + 0x79cf, 0x79b9, 0x79e3, 0x79ad, 0x7a5b, 0x7d2f, 0x7d4a, 0x79ad, + 0x79cf, 0x79ad, 0x79e3, 0x79ad, 0x79ad, 0x7a51, 0x7d4a, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79f7, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x7ec6, 0x79ad, 0x7e70, 0x79ad, 0x7e70, 0x79ad, + 0x7a0c, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x2079, + 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x7e69, + 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, + 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, + 0x080c, 0x7e40, 0x0005, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79b9, + 0x79ad, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79b9, 0x79b9, + 0x79b9, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79ad, + 0x79b9, 0x79ad, 0x79ad, 0x79ad, 0x79b9, 0x00e6, 0x2071, 0x18fa, + 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, + 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009, + 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, + 0x0804, 0x7b30, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, + 0x704b, 0x7b30, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b4b, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b4b, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0904, 0x79b5, 0x8001, 0x1120, 0x7007, + 0x0001, 0x0804, 0x7b67, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, + 0x701a, 0x704b, 0x7b67, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, + 0x9086, 0x0001, 0x1904, 0x79b5, 0x7007, 0x0001, 0x2009, 0x1834, + 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, + 0x0000, 0x080c, 0x63be, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dd1, 0x012e, 0x0ca0, + 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186, + 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8, + 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8, 0x9186, 0x0056, + 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, + 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, + 0x0001, 0x0804, 0x7d61, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, + 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, + 0x7012, 0x9082, 0x0401, 0x1a04, 0x79bd, 0xaab4, 0x928a, 0x0002, + 0x1a04, 0x79bd, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, + 0x2001, 0x7aee, 0x0018, 0x9280, 0x7ae4, 0x2005, 0x7056, 0x7010, + 0x9015, 0x0904, 0x7acf, 0x080c, 0x1027, 0x1118, 0x7007, 0x0004, + 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, + 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, + 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, + 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, + 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, + 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1040, 0x7014, + 0x2048, 0x0804, 0x79bd, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, + 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x7a87, 0x7014, + 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, + 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x0904, 0x7d61, 0x0804, 0x7b30, 0x7ae6, 0x7aea, 0x0002, 0x001d, + 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, + 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, + 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, + 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, + 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, + 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, + 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, + 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, + 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, + 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c, 0x61bb, 0x1108, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd14c, + 0x080c, 0x6dd1, 0x012e, 0x0ca0, 0x080c, 0xd55a, 0x1d70, 0x2001, + 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1188, + 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c, 0x624b, 0x1108, + 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, + 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x0419, + 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, + 0x0120, 0x080c, 0x6320, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, + 0x6298, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, + 0x080c, 0x6dd1, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, + 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800, 0x60d0, 0x9005, + 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908, 0x2048, 0xa906, + 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003, 0x0030, + 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6, + 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, + 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, + 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, + 0x671d, 0x11b8, 0x0066, 0xae80, 0x080c, 0x682d, 0x006e, 0x0088, + 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, + 0x080c, 0x671d, 0x1110, 0x080c, 0x692d, 0x8108, 0x1f04, 0x7bd0, + 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040, 0x00be, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x0005, + 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e, 0x0580, + 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, + 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, + 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, + 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, + 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, + 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x7e2a, + 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804, + 0x7e21, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e, + 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, + 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988, 0x918c, + 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, + 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, + 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, + 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, + 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, + 0x0804, 0x7e2a, 0x012e, 0x0804, 0x7e27, 0x012e, 0x0804, 0x7e24, + 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a75, 0x6300, + 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, + 0x7e38, 0x012e, 0x0804, 0x7e27, 0x00b6, 0x0126, 0x00c6, 0x2091, + 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, + 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, + 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, 0x1834, 0x2004, + 0x9005, 0x0118, 0x080c, 0xb134, 0x0068, 0x6017, 0xf400, 0x605b, + 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, + 0x080c, 0xb180, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, + 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x891c, 0x002e, 0xa87c, + 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c, 0x1120, 0x6008, + 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e2a, + 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e24, 0xa984, 0x9186, 0x002e, + 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, + 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, + 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, + 0x671d, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, + 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004, 0x601a, 0x0804, + 0x7cbf, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, + 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb134, 0x8eff, 0x0118, + 0x2e60, 0x080c, 0xb134, 0x00ee, 0x0804, 0x7cbf, 0x6024, 0xc0dc, + 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, + 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, + 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0804, 0x7cbf, 0x2061, + 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7e38, 0x0126, + 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, + 0x7e38, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e31, 0xa883, 0x0007, + 0x0804, 0x7e31, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, + 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x79b5, 0x0040, + 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7d61, + 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, + 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7de3, 0x6130, 0xd194, 0x1904, + 0x7e0d, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7dd7, 0x6068, + 0x9e02, 0x1a04, 0x7dd7, 0x7120, 0x9186, 0x0006, 0x1904, 0x7dc9, + 0x7010, 0x905d, 0x0904, 0x7de3, 0xb800, 0xd0e4, 0x1904, 0x7e07, + 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, + 0x7024, 0xd0dc, 0x1904, 0x7e10, 0xa883, 0x0000, 0xa803, 0x0000, + 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, + 0x7e13, 0x080c, 0x57d3, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, + 0x2e60, 0x080c, 0x883c, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, + 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, + 0x7e13, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, + 0x0006, 0x00be, 0x0804, 0x7e31, 0xd184, 0x0db8, 0xd1c4, 0x1190, + 0x00a0, 0xa974, 0x080c, 0x671d, 0x15d0, 0xb800, 0xd0e4, 0x15b8, + 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, + 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, + 0xa883, 0x0035, 0x0430, 0x080c, 0x57d7, 0xd0fc, 0x01e8, 0xa878, + 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02, 0x12a8, 0x7120, + 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, + 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x7d6d, + 0x7003, 0x0002, 0x0804, 0x7d6d, 0xa883, 0x0028, 0x0010, 0xa883, + 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, + 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, + 0x080c, 0xe4c8, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, + 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, + 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00, 0x9105, + 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005, + 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x8833, 0x00de, 0x0005, + 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, + 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f22, 0xd09c, 0x11a8, + 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001, 0x70c2, + 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806, 0x2071, + 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, + 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f22, 0x000e, 0x0005, + 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb0ab, 0x05d8, 0x2900, + 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138, 0x6008, + 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098, 0xa8a0, 0x9084, + 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, 0x918c, 0x00ff, + 0x080c, 0x2894, 0x1540, 0x00b6, 0x080c, 0x671d, 0x2b00, 0x00be, + 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xb180, + 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6dd1, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6dd1, 0x012e, 0x080c, 0xb101, 0x0005, 0x00d6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, + 0x0004, 0x1a04, 0x7f13, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, + 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, + 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb0ab, 0x1118, 0x080c, + 0xb153, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ef1, 0x7ef6, 0x7ef9, + 0x7eff, 0x2019, 0x0002, 0x080c, 0xe915, 0x0060, 0x080c, 0xe8ac, + 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe8c7, 0x0018, 0xa980, + 0x080c, 0xe8ac, 0x080c, 0xb101, 0xa887, 0x0000, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, + 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, + 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, + 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f24, 0x0006, 0x0016, + 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001, 0x1834, 0x2004, + 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, + 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, + 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, + 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, + 0x7fa4, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e8, 0x7d44, 0x7c40, + 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, + 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fab, 0x7000, 0x9084, + 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, + 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xedd2, + 0x080c, 0x84cd, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, + 0x080c, 0x852b, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, + 0x8006, 0x080c, 0x2397, 0x005e, 0x004e, 0x0020, 0x080c, 0xedd2, + 0x7817, 0x0140, 0x080c, 0x7569, 0x0168, 0x2001, 0x0111, 0x2004, + 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, + 0x2003, 0x0000, 0x080c, 0x7fe7, 0x2001, 0x19f2, 0x2004, 0x9005, + 0x090c, 0x98ed, 0x0005, 0x0002, 0x7fbd, 0x82d5, 0x7fb4, 0x7fb4, + 0x7fb4, 0x7fb4, 0x7fb4, 0x7fb4, 0x7817, 0x0140, 0x2001, 0x19f2, + 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x7000, 0x908c, 0xff00, + 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, + 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x583d, 0x0070, + 0x080c, 0x8026, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x820d, + 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83f4, 0x7817, 0x0140, + 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, + 0x4be9, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, + 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, + 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, + 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, + 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4be9, + 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, + 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, + 0x0023, 0x1904, 0x81de, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8492, + 0x0904, 0x81de, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, + 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x81de, + 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, + 0x080c, 0xb180, 0x0804, 0x81de, 0x908e, 0x0214, 0x0118, 0x908e, + 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb180, 0x0804, 0x81de, + 0x908e, 0x0100, 0x1904, 0x81de, 0x7034, 0x9005, 0x1904, 0x81de, + 0x2009, 0x0016, 0x080c, 0xb180, 0x0804, 0x81de, 0x9186, 0x0022, + 0x1904, 0x81de, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc, 0xd0a4, + 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e, 0x7004, + 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, + 0x00ff, 0x0016, 0x2008, 0x080c, 0x28dd, 0x7932, 0x7936, 0x001e, + 0x000e, 0x00fe, 0x080c, 0x2894, 0x695e, 0x703c, 0x00e6, 0x2071, + 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005, + 0x1904, 0x81de, 0x2009, 0x0017, 0x0804, 0x818e, 0x908e, 0x0400, + 0x1190, 0x7034, 0x9005, 0x1904, 0x81de, 0x080c, 0x7569, 0x0120, + 0x2009, 0x001d, 0x0804, 0x818e, 0x68dc, 0xc0a5, 0x68de, 0x2009, + 0x0030, 0x0804, 0x818e, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, + 0x1904, 0x81de, 0x2009, 0x0018, 0x0804, 0x818e, 0x908e, 0x2010, + 0x1120, 0x2009, 0x0019, 0x0804, 0x818e, 0x908e, 0x2110, 0x1120, + 0x2009, 0x001a, 0x0804, 0x818e, 0x908e, 0x5200, 0x1140, 0x7034, + 0x9005, 0x1904, 0x81de, 0x2009, 0x001b, 0x0804, 0x818e, 0x908e, + 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de, 0x2009, 0x001c, + 0x0804, 0x818e, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, + 0x818e, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de, + 0x2009, 0x0024, 0x0804, 0x818e, 0x908c, 0xff00, 0x918e, 0x2400, + 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, + 0x818e, 0x080c, 0xdc98, 0x1904, 0x81de, 0x0804, 0x818c, 0x908c, + 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x818e, + 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x818e, 0x908e, + 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, + 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, + 0x8108, 0x0046, 0x2124, 0x080c, 0x4be9, 0x004e, 0x8108, 0x0f04, + 0x8142, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, + 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x818e, + 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, 0x818e, 0x908e, + 0x5400, 0x1138, 0x080c, 0x8598, 0x1904, 0x81de, 0x2009, 0x0046, + 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85c0, 0x1118, 0x2009, + 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800, 0x1118, + 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, + 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, + 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, + 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, + 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1904, 0x81e1, + 0x080c, 0x66b2, 0x1904, 0x81e1, 0xbe12, 0xbd16, 0x001e, 0x0016, + 0x080c, 0x7569, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000, 0x9084, + 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x687c, + 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, + 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168, 0x9186, 0x0046, + 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, 0x9084, 0xff00, + 0x1110, 0x001e, 0x0098, 0x080c, 0xb0ab, 0x01a8, 0x2b08, 0x6112, + 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, + 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb180, 0x00ce, 0x00be, + 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, + 0x2011, 0x8049, 0x080c, 0x4be9, 0x080c, 0xb153, 0x0d90, 0x2b08, + 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, + 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, + 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, + 0x6003, 0x0001, 0x080c, 0x9383, 0x08a0, 0x080c, 0x8607, 0x1158, + 0x080c, 0x336a, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, + 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, + 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8492, + 0x0904, 0x826d, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, + 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xb180, 0x04a8, + 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, + 0x080c, 0xb180, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, + 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2894, 0x11b8, 0x080c, 0x66b2, 0x11a0, + 0xbe12, 0xbd16, 0x080c, 0xb0ab, 0x0178, 0x2b08, 0x6112, 0x080c, + 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xb180, + 0x080c, 0x98ed, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, + 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, + 0x2009, 0x007f, 0x0804, 0x82cf, 0x9596, 0xfffe, 0x1120, 0x2009, + 0x007e, 0x0804, 0x82cf, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, + 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, + 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, + 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, + 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, + 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, + 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, + 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x82a4, + 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, + 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c, + 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, + 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19f2, + 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x82fd, 0x82fd, 0x82fd, + 0x84a4, 0x82fd, 0x8306, 0x8331, 0x83bf, 0x82fd, 0x82fd, 0x82fd, + 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x7817, 0x0140, 0x2001, + 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x00b6, 0x7110, + 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, + 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, + 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, + 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xb180, 0x7817, + 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00be, + 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8395, 0x7110, + 0xd1bc, 0x1904, 0x8395, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, + 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x33ac, + 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, + 0x8395, 0x080c, 0x66b2, 0x1904, 0x8395, 0xbe12, 0xbd16, 0xb800, + 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, + 0x080c, 0xb0ab, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, + 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, + 0x0044, 0x080c, 0xdf10, 0x0408, 0x080c, 0x6a92, 0x1138, 0xb807, + 0x0606, 0x0c30, 0x190c, 0x8271, 0x11c0, 0x0898, 0x080c, 0xb0ab, + 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, + 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, + 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x7817, 0x0140, 0x2001, + 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00ce, 0x00be, 0x0005, + 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, + 0x4be9, 0x080c, 0xb153, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, + 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, + 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x08b0, 0x00b6, + 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, + 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, + 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, + 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xb180, + 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, + 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, + 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8607, 0x1180, 0x080c, + 0x336a, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, + 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, + 0x840e, 0x840f, 0x840e, 0x840e, 0x8474, 0x8483, 0x0005, 0x00b6, + 0x700c, 0x7108, 0x080c, 0x2894, 0x1904, 0x8472, 0x080c, 0x66b2, + 0x1904, 0x8472, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, + 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8472, 0x080c, 0x6a92, + 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118, 0x9086, + 0x0004, 0x1588, 0x00c6, 0x080c, 0x8492, 0x00ce, 0x05d8, 0x080c, + 0xb0ab, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0002, + 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb180, 0x0458, 0x080c, + 0x6a92, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118, + 0x9086, 0x0004, 0x1180, 0x080c, 0xb0ab, 0x2b08, 0x01d8, 0x6112, + 0x080c, 0xd2d2, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, + 0x080c, 0xb180, 0x0078, 0x080c, 0xb0ab, 0x2b08, 0x0158, 0x6112, + 0x080c, 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, + 0x080c, 0xb180, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, + 0x0148, 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, + 0x080c, 0xb180, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, + 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, + 0xb180, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, + 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, + 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, + 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, + 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, + 0x0051, 0x080c, 0xb180, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, + 0x9005, 0x090c, 0x98ed, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, + 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, + 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, + 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0xb0ab, + 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2894, 0x15a0, 0x080c, 0x66b2, 0x1588, 0xbe12, + 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xd2d2, 0x080c, + 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, + 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, + 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, + 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb101, 0x006e, 0x0cc0, + 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, + 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x8582, 0x9186, 0x0022, + 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8584, 0x7030, + 0x908e, 0x0400, 0x0904, 0x8584, 0x908e, 0x6000, 0x05e8, 0x908e, + 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, 0x210c, + 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a50, 0x0588, 0x68b0, + 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, + 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, + 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, + 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, + 0x0023, 0x1140, 0x080c, 0x8492, 0x0128, 0x6004, 0x9086, 0x0002, + 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, + 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x027a, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0e3, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x0272, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, + 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, + 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, + 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19fc, + 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, + 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0xa52d, 0x7032, + 0x703a, 0x703f, 0x0064, 0x7037, 0xa595, 0x7047, 0xffff, 0x704a, + 0x704f, 0x5665, 0x7052, 0x7063, 0x87aa, 0x080c, 0x1027, 0x090c, + 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, + 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f8, 0x2091, 0x6000, + 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c, 0x2004, 0x9005, + 0x190c, 0x8818, 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, + 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, + 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, + 0x8000, 0x080c, 0x87ef, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, + 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, + 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, + 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, + 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8, 0x702c, 0x8001, + 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c, 0x9184, 0x0030, + 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0, 0x7038, 0x9005, + 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7569, 0x0178, 0x00e6, + 0x2071, 0x19e9, 0x080c, 0xa623, 0x00ee, 0x1140, 0x2009, 0x1a87, + 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068, 0x001e, 0x702f, + 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0xa6d9, + 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001, + 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148, + 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060, + 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158, + 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a, + 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, + 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, + 0x7004, 0x0002, 0x8720, 0x8721, 0x873d, 0x00e6, 0x2071, 0x19fc, + 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1120, + 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, + 0x0005, 0x00b6, 0x7110, 0x080c, 0x671d, 0x1168, 0xb888, 0x8001, + 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x98ed, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, + 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, + 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, + 0x080c, 0xd163, 0x6018, 0x9005, 0x0558, 0x8001, 0x601a, 0x1540, + 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, + 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, 0xce56, 0x01b0, + 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, + 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, + 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xcb3e, + 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, + 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, + 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x7132, + 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08, 0x2013, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e, 0x700b, 0x0009, + 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, 0x705e, 0x2001, + 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, + 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, 0x080c, 0x10f8, + 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x8642, 0x015e, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, + 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a, 0x727e, 0x7077, + 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x707c, + 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x2069, + 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a54, + 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, 0x0088, 0x9184, + 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ea, 0x0070, + 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094, 0x00c0, + 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee, 0x002e, 0x0005, + 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, + 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, + 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, + 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, + 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, + 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014, 0x00ce, 0x9005, + 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, + 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, + 0x00c0, 0x0904, 0x88c6, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x889f, + 0x2009, 0x0006, 0x080c, 0x88f3, 0x0005, 0x900e, 0x0c60, 0x2001, + 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, + 0x0003, 0x1904, 0x88ed, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, + 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, + 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb180, 0x0005, 0x87ff, + 0x1de8, 0x2009, 0x0042, 0x0804, 0xb180, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, + 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, + 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x88ed, + 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, + 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, + 0x080c, 0xb180, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, + 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, + 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xb180, + 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, + 0xb180, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, + 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, + 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce56, 0x0518, 0x6014, + 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, + 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a75, + 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, + 0x080c, 0x6c10, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, + 0x883c, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a75, + 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, + 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, + 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925, 0x7003, + 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c, + 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, + 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, + 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925, 0x702c, + 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0xa896, + 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, + 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, 0x8001, + 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010, + 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006, + 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, 0xc095, + 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611, 0x9006, 0x2071, + 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005, + 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6, + 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, + 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, + 0x0008, 0x1f04, 0x89af, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, + 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb0ab, 0x6023, 0x0009, 0x6003, + 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b2d, 0x012e, 0x1f04, 0x89bb, 0x9006, 0x00ce, 0x015e, 0x012e, + 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096, + 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004, + 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, + 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, + 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a, + 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, + 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160, + 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00, 0xa802, 0x2900, + 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, + 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1925, + 0x7004, 0x004b, 0x700c, 0x0002, 0x8a27, 0x8a20, 0x8a20, 0x0005, + 0x8a31, 0x8a87, 0x8a87, 0x8a87, 0x8a88, 0x8a99, 0x8a99, 0x700c, + 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x1904, + 0x8a79, 0x7814, 0xd0bc, 0x1904, 0x8a82, 0x012e, 0x7018, 0x910a, + 0x1128, 0x7030, 0x9005, 0x1904, 0x8acb, 0x0005, 0x1210, 0x7114, + 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888, + 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50, 0x080c, + 0x8c25, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, 0x2048, + 0xa873, 0x0001, 0xa976, 0x080c, 0x8d2e, 0x2100, 0xa87e, 0xa86f, + 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a1c, 0x2104, + 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1117, 0x1de8, + 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a39, 0x080c, 0x8bfd, + 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8a39, 0x0005, + 0x700c, 0x0002, 0x8a8d, 0x8a90, 0x8a8f, 0x080c, 0x8a2f, 0x0005, + 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011, + 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214, + 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, 0x0068, + 0x0006, 0x080c, 0x8d2e, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220, + 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, 0x2091, + 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bfd, 0x012e, 0x0005, 0x00e6, + 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac9, 0x8ac9, 0x8ac7, 0x700f, + 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, + 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, + 0x080c, 0x8b36, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, 0x080c, + 0x8b7d, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027, 0x2900, 0x009e, + 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948, 0x2003, 0x0000, + 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, + 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f, + 0x2068, 0x9d88, 0x20f0, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c, + 0x8cb3, 0x080c, 0x20a8, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101, 0x7813, 0x0000, + 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8c, 0x012e, 0x008e, 0x00ce, + 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078, 0x780c, 0x7032, + 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6, 0x2071, 0x1925, + 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005, 0x00d6, 0x00c6, + 0x0026, 0x9b80, 0x8dfc, 0x2005, 0x906d, 0x090c, 0x0dc5, 0x9b80, + 0x8df4, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114, 0x2600, 0x9102, + 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce, + 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178, + 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be9, 0x684c, 0x0096, + 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006, + 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d, 0x6856, 0x2011, + 0x8025, 0x080c, 0x4be9, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, + 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000, 0x2019, 0x0008, + 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005, 0x0020, 0x0210, + 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814, 0x9005, 0x090c, + 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101, 0x190c, 0x0dc5, + 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080, 0x1940, 0x2f08, + 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208, 0x900e, 0x6906, + 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005, 0x0096, 0x00c6, + 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048, 0x9005, 0x190c, + 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0, 0x080c, 0xb101, + 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x601c, + 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x6000, + 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150, 0x00b6, 0x2058, + 0x080c, 0x8f31, 0x00be, 0x6013, 0x0000, 0x601b, 0x0000, 0x0010, + 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c, 0xd194, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925, 0x7110, 0xc194, + 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, + 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, + 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, + 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, + 0x702f, 0x0000, 0x080c, 0x8d7c, 0x0170, 0x080c, 0x8db1, 0x0158, + 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, + 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, + 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100, 0x9202, 0x1618, + 0x080c, 0x8db1, 0x090c, 0x0dc5, 0x7018, 0x9005, 0x1160, 0x2900, + 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, + 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, + 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, + 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, + 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f, 0x831e, 0x831e, + 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, + 0x080c, 0x8d2e, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, + 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, + 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8d37, 0x2130, + 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, + 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, + 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8c25, 0x002e, + 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, + 0x2500, 0x9212, 0x1904, 0x8c64, 0x012e, 0x00ee, 0x014e, 0x013e, + 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x9580, 0x8df4, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x080c, + 0x8d09, 0x012e, 0x9580, 0x8df0, 0x2005, 0x9075, 0x090c, 0x0dc5, + 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, + 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, + 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, + 0x2e0c, 0x2d00, 0x0002, 0x8cf3, 0x8cf3, 0x8cf5, 0x8cf3, 0x8cf5, + 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cfb, 0x8cf3, 0x8cfb, + 0x8cf3, 0x8cf3, 0x8cf3, 0x080c, 0x0dc5, 0x4104, 0x20a9, 0x0002, + 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, + 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, + 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, + 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, + 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8dc0, + 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, + 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, + 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, + 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, + 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, + 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d7a, 0x901e, 0x6808, + 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, + 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, + 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, + 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, + 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, + 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, + 0x8000, 0x2b00, 0x9080, 0x8df8, 0x2005, 0x9005, 0x090c, 0x0dc5, + 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, 0x2900, 0x7026, + 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, 0x0188, 0x7024, + 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, + 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, + 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1040, 0x2400, + 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, + 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, + 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, + 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x009e, 0x0005, + 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, + 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, + 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, + 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000, 0x0000, 0x0000, + 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, + 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, + 0x080c, 0x8f1c, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x8ef1, + 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, + 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, + 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, + 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, + 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20f0, 0x2c65, 0x9786, 0x0024, + 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x8e5c, 0x8e5c, 0x8e5e, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e60, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e62, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e64, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e66, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e68, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e6a, 0x080c, 0x0dc5, 0xa180, 0x04b8, + 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, + 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x8e8e, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, + 0x8e8c, 0x8e90, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e92, + 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e94, 0x8e8c, 0x8e8c, + 0x8e8c, 0x8e8c, 0x8e8c, 0x8e96, 0x080c, 0x0dc5, 0xa180, 0x0038, + 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, + 0x0002, 0x8eb2, 0x8eb4, 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, + 0x8ec0, 0x8ec2, 0x8ec4, 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, + 0x8ed0, 0x8ed2, 0x8ed4, 0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x8ede, + 0x8ee0, 0x8ee2, 0x080c, 0x0dc5, 0xb9e2, 0x0468, 0xb9de, 0x0458, + 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, + 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, + 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, + 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, + 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, + 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x20a8, + 0x090c, 0x0dc5, 0x0804, 0x8e36, 0x00ae, 0x00be, 0x00ce, 0x00ee, + 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, + 0x0804, 0x8e18, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, + 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005, 0x0188, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, + 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e, + 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, + 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130, + 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a, + 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, + 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, + 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000, + 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140, + 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5, 0x2068, 0x0cb0, + 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200, + 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6, + 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071, + 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, 0x8f71, + 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac, + 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, + 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, + 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, 0x0000, 0x904d, + 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b2d, 0x0c00, 0x2071, + 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156, + 0x080c, 0x2894, 0x015e, 0x11b0, 0x080c, 0x66b2, 0x190c, 0x0dc5, + 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb0ab, 0x0140, 0x2b00, + 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, 0xb180, 0x00be, + 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0x8fe6, 0x8fe6, + 0x8fe6, 0x8fe8, 0x9039, 0x8fe6, 0x8fe6, 0x8fe6, 0x90a0, 0x8fe6, + 0x90dd, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x080c, 0x0dc5, + 0x9182, 0x0040, 0x0002, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, + 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffd, 0x9012, 0x8ffb, 0x8ffb, + 0x8ffb, 0x8ffb, 0x9025, 0x080c, 0x0dc5, 0x0096, 0x080c, 0x989d, + 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bd5, 0x080c, 0xb101, + 0x009e, 0x0005, 0x080c, 0x989d, 0x00d6, 0x6114, 0x080c, 0xce56, + 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dd1, 0x009e, 0x00de, + 0x080c, 0xb101, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x989d, 0x080c, + 0x3246, 0x6114, 0x0096, 0x2148, 0x080c, 0xce56, 0x0120, 0xa87b, + 0x0029, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f, + 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x9054, + 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9056, + 0x9054, 0x9054, 0x9054, 0x909c, 0x9054, 0x9054, 0x9054, 0x9054, + 0x9054, 0x9054, 0x905d, 0x9054, 0x080c, 0x0dc5, 0x6114, 0x2148, + 0xa938, 0x918e, 0xffff, 0x0904, 0x909c, 0x6024, 0xd08c, 0x15c0, + 0x00e6, 0x6114, 0x2148, 0x080c, 0x8e00, 0x0096, 0xa8a8, 0x2048, + 0x080c, 0x6b6d, 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, + 0x00b6, 0x2058, 0x080c, 0x8f31, 0x00be, 0xae88, 0x00b6, 0x2059, + 0x0000, 0x080c, 0x8b36, 0x00be, 0x01e0, 0x2071, 0x193e, 0x080c, + 0x8b7d, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, 0x1948, 0x2004, + 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900, 0x009e, 0x0148, + 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8af4, 0x00fe, 0x00ee, 0x009e, + 0x0005, 0x080c, 0x8b2d, 0x0cd0, 0x080c, 0x914a, 0x009e, 0x0005, + 0x9182, 0x0040, 0x0096, 0x0002, 0x90b4, 0x90b4, 0x90b4, 0x90b6, + 0x90b4, 0x90b4, 0x90b4, 0x90db, 0x90b4, 0x90b4, 0x90b4, 0x90b4, + 0x90b4, 0x90b4, 0x90b4, 0x90b4, 0x080c, 0x0dc5, 0x6003, 0x0003, + 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837, + 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, + 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f, + 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x989d, 0x080c, + 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, + 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dd1, 0x080c, 0xb101, 0x009e, + 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, + 0x009e, 0x0005, 0x910a, 0x910a, 0x910a, 0x910c, 0x911d, 0x910a, + 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, + 0x910a, 0x910a, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x2148, + 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, + 0x080c, 0x6dd1, 0x080c, 0xb101, 0x0005, 0x0461, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005, + 0x9138, 0x9138, 0x9138, 0x913a, 0x914a, 0x9138, 0x9138, 0x9138, + 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, + 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, + 0x1120, 0x2019, 0x0000, 0x080c, 0xa877, 0x080c, 0xaa59, 0x00ee, + 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, + 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, + 0x080c, 0x8f31, 0x00be, 0x2071, 0x193e, 0x080c, 0x8b7d, 0x0160, + 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, + 0x8af4, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, + 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8b2d, + 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, + 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118, + 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208, + 0x9200, 0x1f04, 0x9192, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, + 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e, 0x003e, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, + 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039, 0x0100, 0x273c, + 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x0228, + 0x911a, 0x1220, 0x1f04, 0x91bc, 0x0028, 0x911a, 0x2308, 0x8210, + 0x1f04, 0x91bc, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, + 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, + 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, 0x012e, 0x00d6, + 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, + 0x0000, 0x2069, 0x0200, 0x080c, 0xadbc, 0x0401, 0x080c, 0xada7, + 0x00e9, 0x080c, 0xadaa, 0x00d1, 0x080c, 0xadad, 0x00b9, 0x080c, + 0xadb0, 0x00a1, 0x080c, 0xadb3, 0x0089, 0x080c, 0xadb6, 0x0071, + 0x080c, 0xadb9, 0x0059, 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, + 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, + 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, + 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x922f, 0x9253, 0x9294, + 0x9235, 0x9253, 0x922f, 0x922d, 0x922d, 0x080c, 0x0dc5, 0x080c, + 0x878f, 0x080c, 0x98ed, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, + 0x00ce, 0x0005, 0x2011, 0x5f90, 0x080c, 0x8709, 0x7828, 0x9092, + 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fd0, 0x0c88, 0x62c0, + 0x080c, 0xaef8, 0x080c, 0x5f90, 0x7807, 0x0003, 0x7827, 0x0000, + 0x782b, 0x0000, 0x0c28, 0x080c, 0x878f, 0x6220, 0xd2a4, 0x0170, + 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dc5, + 0x2009, 0x0013, 0x080c, 0xb180, 0x00ce, 0x0005, 0x00c6, 0x7824, + 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, + 0x782a, 0x00ce, 0x080c, 0x2be7, 0x0278, 0x00c6, 0x7924, 0x2160, + 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000, 0x7827, 0x0000, + 0x00ce, 0x080c, 0x98ed, 0x0c00, 0x080c, 0xa4f3, 0x08e8, 0x2011, + 0x0130, 0x2214, 0x080c, 0xaef8, 0x080c, 0xee0f, 0x2009, 0x0014, + 0x080c, 0xb180, 0x00ce, 0x0880, 0x2001, 0x1a05, 0x2003, 0x0000, + 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, + 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1d2, 0x00ce, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5, 0x7828, 0x9092, + 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, + 0x2be7, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, + 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160, 0x080c, 0xb101, + 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e, 0x7807, 0x0000, + 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c, 0x98ed, 0x0868, + 0x080c, 0xa4f3, 0x0850, 0x2011, 0x0130, 0x2214, 0x080c, 0xaef8, + 0x080c, 0xee0f, 0x7824, 0x9065, 0x2009, 0x0014, 0x080c, 0xb180, + 0x00de, 0x00ce, 0x00be, 0x0804, 0x92a5, 0x00c6, 0x2001, 0x009b, + 0x2004, 0xd0fc, 0x190c, 0x1f14, 0x6024, 0x6027, 0x0002, 0xd0f4, + 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c, 0x9065, 0x0130, + 0x2009, 0x0049, 0x080c, 0xb180, 0x00ce, 0x0005, 0x2011, 0x1a08, + 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, + 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188, 0x0008, 0x210c, + 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, 0x9085, 0x0012, + 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0009, + 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08a0, + 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb180, 0x0868, 0x7848, + 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000, + 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, + 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, + 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, + 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, + 0x98ed, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, + 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, + 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856, 0xb85a, 0x2b00, + 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000, + 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, + 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, + 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6034, 0x9005, + 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, + 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, + 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, + 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660, 0x2678, 0x2091, + 0x8000, 0x8cff, 0x0904, 0x942f, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1904, 0x942a, 0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x942a, + 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877, + 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, + 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, + 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce56, 0x01f0, 0x6014, + 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, + 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, + 0x0036, 0x0076, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1, + 0x007e, 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x00ce, + 0x0804, 0x93c9, 0x2c78, 0x600c, 0x2060, 0x0804, 0x93c9, 0x85ff, + 0x0120, 0x0036, 0x080c, 0x9a0f, 0x003e, 0x012e, 0x000e, 0x001e, + 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, + 0x0016, 0x0036, 0x0076, 0x080c, 0xed00, 0x080c, 0xe948, 0x007e, + 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, + 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dd1, 0x080c, 0xb101, + 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086, 0x000a, 0x0904, + 0x9414, 0x0804, 0x940d, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, + 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079, 0x19e9, 0x7838, + 0x9065, 0x0904, 0x94c0, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, + 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877, 0x7833, + 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, + 0xce56, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1590, + 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, + 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004, 0x9086, 0x0040, + 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6dc4, 0x080c, 0xd041, 0x080c, 0xb134, 0x000e, 0x0804, 0x9478, + 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, + 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe948, + 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x6dd1, + 0x080c, 0xb101, 0x0c10, 0x6020, 0x9086, 0x000a, 0x09a8, 0x0868, + 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, 0x95cb, 0x008e, + 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9, 0x2091, + 0x8000, 0x080c, 0x9662, 0x080c, 0x96f2, 0x012e, 0x00fe, 0x0005, + 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, + 0x2678, 0x8cff, 0x0904, 0x9590, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1904, 0x958b, 0x88ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x958b, + 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, + 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x0804, 0x958b, + 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, + 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, + 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce56, 0x01e8, 0x6020, + 0x9086, 0x0003, 0x1580, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, + 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, + 0x0086, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1, 0x008e, + 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x080c, 0xa91f, + 0x00ce, 0x0804, 0x9509, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9509, + 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, + 0x0036, 0x0086, 0x080c, 0xed00, 0x080c, 0xe948, 0x008e, 0x003e, + 0x001e, 0x08d0, 0x080c, 0xbae2, 0x6020, 0x9086, 0x0002, 0x1160, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9571, 0x9086, + 0x008b, 0x0904, 0x9571, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, + 0x09b0, 0x0804, 0x9584, 0x00b6, 0x00a6, 0x0096, 0x00c6, 0x0006, + 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x0904, + 0x965b, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0x19e9, 0xbe54, + 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, 0x1130, 0x86ff, + 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, 0x904d, 0x0108, + 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, 0xb857, 0x0000, + 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645, + 0x0904, 0x9657, 0x7624, 0x86ff, 0x0904, 0x9646, 0x9680, 0x0005, + 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0560, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, + 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, + 0x2660, 0x080c, 0xb134, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, + 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95fe, 0x89ff, 0x0158, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd14c, 0x080c, + 0xed00, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x95fe, 0x006e, + 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x009e, 0x00ae, + 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, + 0x7814, 0x9065, 0x0904, 0x96c5, 0x600c, 0x0006, 0x600f, 0x0000, + 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, + 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x0040, 0x080c, 0x6a2a, 0x1520, 0x6003, 0x0009, + 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xce54, 0x01b0, + 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd05e, 0x1118, 0x080c, + 0xbae2, 0x0060, 0x080c, 0x6a2a, 0x1168, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xb134, + 0x080c, 0xa91f, 0x000e, 0x0804, 0x9669, 0x7e16, 0x7e12, 0x00de, + 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, + 0x1118, 0x080c, 0xe948, 0x0c50, 0x080c, 0xbae2, 0x6020, 0x9086, + 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, + 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, + 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, 0x00c6, 0x00d6, + 0x7818, 0x905d, 0x0904, 0x9772, 0xb854, 0x0006, 0x9006, 0xb856, + 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645, 0x0904, + 0x976f, 0x7e24, 0x86ff, 0x0904, 0x9762, 0x9680, 0x0005, 0x2004, + 0x9906, 0x1904, 0x9762, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0904, 0x9759, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, 0x0002, 0x1168, + 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, 0x81ff, 0x1518, + 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, 0xb134, 0x00ce, + 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, + 0x0804, 0x9705, 0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x9705, 0x000e, + 0x0804, 0x96f9, 0x781e, 0x781a, 0x00de, 0x00ce, 0x00be, 0x009e, + 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0xb800, + 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, 0x9606, 0x1170, + 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080, 0x0005, 0x2004, + 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, 0x006e, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, 0x9005, + 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x04b8, + 0x080c, 0xa517, 0x78c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, + 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2079, 0x0100, + 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0xaa49, 0x003e, + 0x080c, 0x6645, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, + 0x2660, 0x080c, 0xb101, 0x00ce, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0xd14c, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x00fe, + 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204, 0xc0c4, + 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071, 0x19e9, + 0x7004, 0x9084, 0x0007, 0x0002, 0x97fe, 0x9802, 0x9820, 0x9849, + 0x9887, 0x97fe, 0x9819, 0x97fc, 0x080c, 0x0dc5, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, 0x8001, 0x7022, + 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, + 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7216, 0x7212, + 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x9005, 0x0070, + 0x6010, 0x2058, 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x7007, + 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, 0x1148, 0x2001, + 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, 0x00be, 0x0005, + 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98ed, 0x0ca8, 0x7218, + 0x721e, 0x080c, 0x98ed, 0x0c80, 0xc2ec, 0x2202, 0x080c, 0x9a0f, + 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160, 0x080c, + 0xa91f, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0448, + 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, 0x080c, 0xa91f, + 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, + 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, 0x6010, 0x2058, + 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x080c, 0xa91f, 0x701c, + 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, 0x0010, 0x7218, + 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, + 0x9065, 0x0140, 0x080c, 0xa91f, 0x600c, 0x9015, 0x0158, 0x720e, + 0x600f, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069, 0x19e9, + 0x6830, 0x9084, 0x0003, 0x0002, 0x98aa, 0x98ac, 0x98d0, 0x98a8, + 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840, 0x9086, 0x0001, + 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, 0x0170, 0x6a3a, + 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0x1a08, + 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90, + 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, 0x0003, 0x0c50, + 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, 0x9065, 0x0160, + 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x2001, + 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, 0x180c, 0x200c, + 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a0f, 0x2001, 0x19f5, + 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, 0x19e9, 0x6804, + 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, + 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118, 0xd084, 0x1118, + 0x0028, 0x080c, 0x9a0f, 0x000e, 0x00de, 0x0005, 0x000e, 0x0002, + 0x992a, 0x99e3, 0x99e3, 0x99e3, 0x99e3, 0x99e5, 0x99e3, 0x9928, + 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, + 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, + 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, - 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de, - 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe, - 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000, - 0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202, - 0x080c, 0x98f6, 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4, - 0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904, - 0x9aa6, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e, - 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, - 0x002e, 0x080c, 0x1c9a, 0x1158, 0x012e, 0x080c, 0xa35a, 0x00de, - 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x7610, 0x08d0, 0x012e, - 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, - 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, - 0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e, - 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, - 0x002e, 0x080c, 0x1c9a, 0x19d8, 0x012e, 0x080c, 0xa2db, 0x0878, - 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d, - 0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005, - 0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00, - 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, - 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c9a, 0x1904, 0x9a47, - 0x012e, 0x6a3c, 0x2278, 0x080c, 0xa265, 0x0804, 0x9a3f, 0x2011, - 0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x9a3f, 0x6a04, 0x9296, - 0x0006, 0x1904, 0x9a01, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a29, - 0x0804, 0x9a01, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9ac6, - 0x9acb, 0x9f5d, 0x9ff6, 0x9acb, 0x9f5d, 0x9ff6, 0x9ac6, 0x9acb, - 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x080c, 0x97db, - 0x080c, 0x98e7, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, - 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, - 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158, - 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, - 0x9b37, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, - 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9ce0, 0x9d1b, 0x9d44, - 0x9dec, 0x9e0e, 0x9e14, 0x9e21, 0x9e29, 0x9e35, 0x9e3b, 0x9e4c, - 0x9e3b, 0x9ea4, 0x9e29, 0x9eb0, 0x9eb6, 0x9e35, 0x9eb6, 0x9ec2, - 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, - 0x9b35, 0x9b35, 0x9b35, 0xa714, 0xa737, 0xa748, 0xa768, 0xa79a, - 0x9e21, 0x9b35, 0x9e21, 0x9e3b, 0x9b35, 0x9d44, 0x9dec, 0x9b35, - 0xab26, 0x9e3b, 0x9b35, 0xab42, 0x9e3b, 0x9b35, 0x9e35, 0x9cda, - 0x9b58, 0x9b35, 0xab5e, 0xabcb, 0xaca6, 0x9b35, 0xacb3, 0x9e1e, - 0xacde, 0x9b35, 0xa7a4, 0xad0b, 0x9b35, 0x080c, 0x0dc5, 0x2100, - 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, - 0x013e, 0x015e, 0x00be, 0x0005, 0xada6, 0xae58, 0x9b56, 0x9b90, - 0x9c3c, 0x9c47, 0x9b56, 0x9e21, 0x9b56, 0x9ca1, 0x9cad, 0x9bab, - 0x9b56, 0x9bc6, 0x9bfa, 0xafc5, 0xb00a, 0x9e3b, 0x080c, 0x0dc5, - 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x0026, 0x0036, 0x7814, 0x2048, - 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, - 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, - 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, - 0xa854, 0x7026, 0x63c2, 0x080c, 0xa4d1, 0x003e, 0x002e, 0x009e, - 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, - 0xb051, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, - 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x7814, 0x2048, - 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, - 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4d1, - 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003, - 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, - 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, - 0x0010, 0x080c, 0xa4d1, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, - 0x0126, 0x2091, 0x8000, 0x080c, 0x9ed5, 0x20e9, 0x0000, 0x2001, - 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, - 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, - 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x240f, - 0x080c, 0xdbe1, 0x9006, 0x080c, 0x240f, 0x001e, 0xa804, 0x9005, - 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa4d1, 0x012e, 0x009e, - 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, - 0x9f20, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, - 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, - 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, - 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xdbe1, 0x001e, 0xa804, - 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, - 0x0fc0, 0x080c, 0xa4d1, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, - 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, - 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x7800, - 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, - 0x00e6, 0x080c, 0x9f20, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, - 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, - 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, - 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, - 0x8d68, 0x8e70, 0x1f04, 0x9c67, 0x2069, 0x1801, 0x20a9, 0x0004, - 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c70, 0x9096, 0xdf00, 0x0130, - 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, - 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, - 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, - 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, - 0x1f04, 0x9c87, 0x60c3, 0x004c, 0x080c, 0xa4d1, 0x00ee, 0x00de, - 0x0005, 0x080c, 0x9ed5, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, - 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x0026, 0x0016, - 0x080c, 0x9f20, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, - 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, - 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, - 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, - 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa4d1, 0x001e, 0x002e, - 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4d1, - 0x080c, 0x9ed5, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, - 0x0130, 0x6828, 0x0016, 0x080c, 0x28bc, 0x710e, 0x001e, 0x20a9, - 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, - 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, - 0x4003, 0x080c, 0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, - 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, - 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, - 0x001c, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x080c, - 0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, - 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, - 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, + 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, + 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, + 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x00b6, 0x00e6, + 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99cd, 0xb84c, 0x900d, 0x0118, + 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, 0x0904, + 0x99cd, 0x0028, 0x6818, 0x920e, 0x0904, 0x99cd, 0x2058, 0xb84c, + 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, 0xbb3c, + 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0d8, 0x0904, 0x99cd, 0x8318, + 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880, 0x9084, + 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a, 0x199a, + 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, + 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff, 0x918e, + 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbac0, 0x629a, + 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa047, 0x2069, 0x19e9, + 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, + 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, + 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be, 0x00ce, + 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001, 0x6822, + 0x682b, 0x0000, 0x080c, 0x6645, 0x080c, 0xaf18, 0x00ee, 0x00be, + 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, + 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, 0x1837, 0x210c, + 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138, 0x0006, 0x2009, + 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826, + 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x2001, + 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, + 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000, 0x1570, 0x2001, + 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x98fc, + 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4, 0x1508, 0x6838, + 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904, 0x9aac, 0x7920, + 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1ca2, 0x1158, 0x012e, 0x080c, 0xa374, 0x00de, 0x00fe, 0x0005, + 0xc1c4, 0x2102, 0x080c, 0x7616, 0x08d0, 0x012e, 0x6843, 0x0000, + 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0, + 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1ca2, 0x19d8, 0x012e, 0x080c, 0xa2f5, 0x0878, 0x2001, 0x1837, + 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d, 0x2004, 0x9086, + 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005, 0x11f0, 0x2001, + 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00, 0x6833, 0x0001, + 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, + 0x2400, 0x002e, 0x080c, 0x1ca2, 0x1904, 0x9a4d, 0x012e, 0x6a3c, + 0x2278, 0x080c, 0xa27f, 0x0804, 0x9a45, 0x2011, 0x188b, 0x2204, + 0xc08d, 0x2012, 0x0804, 0x9a45, 0x6a04, 0x9296, 0x0006, 0x1904, + 0x9a07, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a2f, 0x0804, 0x9a07, + 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9acc, 0x9ad1, 0x9f77, + 0xa010, 0x9ad1, 0x9f77, 0xa010, 0x9acc, 0x9ad1, 0x9acc, 0x9acc, + 0x9acc, 0x9acc, 0x9acc, 0x9acc, 0x080c, 0x97e1, 0x080c, 0x98ed, + 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, + 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, + 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9b3d, 0x005b, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, + 0x015e, 0x00be, 0x0005, 0x9ce6, 0x9d21, 0x9d4a, 0x9e06, 0x9e28, + 0x9e2e, 0x9e3b, 0x9e43, 0x9e4f, 0x9e55, 0x9e66, 0x9e55, 0x9ebe, + 0x9e43, 0x9eca, 0x9ed0, 0x9e4f, 0x9ed0, 0x9edc, 0x9b3b, 0x9b3b, + 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, + 0x9b3b, 0xa72e, 0xa751, 0xa762, 0xa782, 0xa7b4, 0x9e3b, 0x9b3b, + 0x9e3b, 0x9e55, 0x9b3b, 0x9d4a, 0x9e06, 0x9b3b, 0xab40, 0x9e55, + 0x9b3b, 0xab5c, 0x9e55, 0x9b3b, 0x9e4f, 0x9ce0, 0x9b5e, 0x9b3b, + 0xab78, 0xabe5, 0xacc0, 0x9b3b, 0xaccd, 0x9e38, 0xacf8, 0x9b3b, + 0xa7be, 0xad25, 0x9b3b, 0x080c, 0x0dc5, 0x2100, 0x005b, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, + 0x00be, 0x0005, 0xadc0, 0xae72, 0x9b5c, 0x9b96, 0x9c42, 0x9c4d, + 0x9b5c, 0x9e3b, 0x9b5c, 0x9ca7, 0x9cb3, 0x9bb1, 0x9b5c, 0x9bcc, + 0x9c00, 0xafdf, 0xb024, 0x9e55, 0x080c, 0x0dc5, 0x00d6, 0x0096, + 0x080c, 0x9eef, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc, + 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030, + 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206, + 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, + 0x63c2, 0x080c, 0xa4eb, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005, + 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xb06b, 0x1118, + 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, + 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, + 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, + 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4eb, 0x009e, 0x00de, + 0x0005, 0x00d6, 0x0096, 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814, + 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, + 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, + 0xa4eb, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9eef, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003, + 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5, + 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x2417, 0x080c, 0xdbfa, + 0x9006, 0x080c, 0x2417, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, + 0x0c28, 0x04d9, 0x080c, 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f3a, 0x20e9, + 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, + 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5, + 0x0016, 0x200c, 0x080c, 0xdbfa, 0x001e, 0xa804, 0x9005, 0x0110, + 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x0fc0, 0x080c, + 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, + 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, + 0x1de0, 0x0005, 0x080c, 0x9eef, 0x7003, 0x7800, 0x7808, 0x8007, + 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x00e6, 0x080c, + 0x9f3a, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, + 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010, + 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, + 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, + 0x1f04, 0x9c6d, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, + 0x8e70, 0x1f04, 0x9c76, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000, + 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00, + 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, + 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, + 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9c8d, + 0x60c3, 0x004c, 0x080c, 0xa4eb, 0x00ee, 0x00de, 0x0005, 0x080c, + 0x9eef, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, + 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9f3a, + 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, + 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148, + 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, + 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, + 0x710a, 0x62c2, 0x080c, 0xa4eb, 0x001e, 0x002e, 0x00de, 0x0005, + 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4eb, 0x080c, 0x9eef, + 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, + 0x0016, 0x080c, 0x28c7, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, - 0x60c3, 0x0010, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x9006, 0x080c, - 0x6a56, 0xb8a0, 0x9086, 0x007e, 0x1130, 0x7003, 0x0400, 0x620c, - 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, - 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, - 0x007e, 0x1904, 0x9db3, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, - 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, - 0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, - 0x7022, 0x681c, 0x7026, 0x0090, 0x6800, 0x700a, 0x6804, 0x700e, - 0x6808, 0x080c, 0x7563, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, - 0x3fff, 0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x00de, 0x20a9, - 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, + 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, + 0xb06b, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, + 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, + 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, + 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0500, 0x080c, 0xb06b, 0x1120, + 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, + 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, + 0x0804, 0xa4eb, 0x080c, 0x9eef, 0x9006, 0x080c, 0x6a5c, 0xb8a0, + 0x9086, 0x007e, 0x1170, 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011, + 0x0241, 0x2013, 0xfffe, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, + 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, + 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, + 0x9dcd, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4, + 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, + 0xb082, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, + 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804, 0x700e, 0x00f6, 0x2079, + 0x0100, 0x080c, 0x7569, 0x1128, 0x78e3, 0x0000, 0x080c, 0x2908, + 0x78e2, 0x00fe, 0x6808, 0x080c, 0x7569, 0x1118, 0x9084, 0x37ff, + 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xb082, 0x680c, 0x7016, + 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xada7, 0x2069, 0x1975, + 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d7, 0xd0e4, + 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, + 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106, + 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x2908, 0x61e2, 0x001e, + 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, - 0x4003, 0x00d6, 0x080c, 0xad8d, 0x2069, 0x1975, 0x2071, 0x024e, - 0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d1, 0xd0e4, 0x0110, 0x680c, - 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, - 0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, - 0x60e3, 0x0000, 0x080c, 0x28fd, 0x61e2, 0x001e, 0x20e1, 0x0001, - 0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, - 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, - 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, - 0xad8d, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, - 0x60c3, 0x0074, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x2010, - 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, - 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, - 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, - 0x9e85, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9ed5, - 0x7003, 0x5000, 0x0804, 0x9d5e, 0x080c, 0x9ed5, 0x7003, 0x2110, - 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9f17, - 0x0010, 0x080c, 0x9f20, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, - 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, - 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, - 0x0200, 0x0804, 0x9d5e, 0x080c, 0x9f20, 0x7003, 0x0100, 0x782c, - 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, - 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x080c, 0x9f20, 0x7003, - 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, - 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, - 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, - 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, - 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, - 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, - 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, - 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c, 0x1108, 0xc0cd, - 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, - 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, - 0x0014, 0x00de, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0210, - 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa4d1, - 0x080c, 0x9f20, 0x7003, 0x0200, 0x0804, 0x9ce4, 0x080c, 0x9f20, - 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, - 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x000b, - 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0026, 0x00d6, 0x0036, 0x0046, - 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, - 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0xada2, 0xb810, - 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, - 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, - 0x080c, 0xa4bf, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, - 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0xada2, 0x7003, - 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, - 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, - 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, - 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, - 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, - 0x080c, 0xada2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, - 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, - 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, - 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, - 0x002e, 0x0005, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x7814, - 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, - 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, - 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x6110, - 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, - 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9f8e, - 0x9f9d, 0x9fa8, 0x9f8c, 0x9f8c, 0x9f8c, 0x9f8e, 0x9f8c, 0x9f8c, - 0x9f8c, 0x9f8c, 0x9f8c, 0x9f8c, 0x080c, 0x0dc5, 0x0411, 0x60c3, - 0x0000, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204, - 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4d1, 0x0431, 0x7808, 0x700a, - 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa4d1, - 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, - 0xa4d1, 0x0026, 0x080c, 0xada2, 0xb810, 0x9085, 0x8100, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, - 0x7013, 0x0009, 0x0804, 0x9ef0, 0x0026, 0x080c, 0xada2, 0xb810, - 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, - 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, - 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x0026, 0x080c, 0xada2, - 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, - 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, - 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x00b6, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, - 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a, 0x0054, 0x1a0c, - 0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100, 0x619a, 0x9082, - 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, - 0xa02d, 0xa0f4, 0xa0c7, 0xa216, 0xa02b, 0xa02b, 0xa02b, 0xa02b, - 0xa02b, 0xa02b, 0xa02b, 0xa8ec, 0xa8f1, 0xa8f6, 0xa8fb, 0xa02b, - 0xacea, 0xa02b, 0xa8e7, 0x080c, 0x0dc5, 0x0096, 0x780b, 0xffff, - 0x080c, 0xa098, 0x7914, 0x2148, 0xa978, 0x7956, 0xae64, 0x96b4, - 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036, - 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, 0xa97c, 0x9184, - 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, 0x785c, 0x9084, - 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002, - 0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010, 0x080c, 0x1768, - 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, 0x7047, 0x0000, - 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9, - 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, - 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, 0x0018, 0x4003, - 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, 0x2001, 0x1a05, - 0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009, 0x009e, 0x0005, - 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084, 0x0180, 0x2001, - 0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0, 0x201c, 0x1218, - 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, 0x732a, 0x9294, - 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, - 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e, - 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6, - 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006, - 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de, - 0x0804, 0xa4d1, 0x6813, 0x0008, 0xb810, 0x9085, 0x0500, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, - 0x7013, 0x0889, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, - 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, 0x080c, 0xa1f4, - 0x7814, 0x2048, 0x080c, 0xce3d, 0x1130, 0x7814, 0x9084, 0x0700, - 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, 0x00de, 0x0005, - 0xa112, 0xa17b, 0xa18b, 0xa1b1, 0xa1bd, 0xa1ce, 0xa1d6, 0xa110, - 0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118, - 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316, - 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, 0x2001, 0x19b3, - 0x2004, 0x60c2, 0x0804, 0xa4d1, 0xc3e5, 0x0c88, 0x9186, 0x0001, - 0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904, 0xa178, 0x7316, - 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e, - 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac, - 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010, - 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9, - 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003, - 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005, - 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, 0x0003, 0x0118, - 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, 0x0804, 0xa4d1, - 0xc3e5, 0x0804, 0xa137, 0x2011, 0x0008, 0x2001, 0x180f, 0x2004, - 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, - 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, 0x782c, 0x701a, - 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, - 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, 0x0008, 0x7043, - 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, 0x0200, 0x6813, - 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804, - 0xa4d1, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, - 0x0018, 0x0804, 0xa4d1, 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, - 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, - 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x2011, 0x0008, - 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14, - 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824, - 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, 0x0046, 0x2021, - 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416, - 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810, - 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, - 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898, - 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, - 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, - 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa226, 0xa226, - 0xa228, 0xa226, 0xa226, 0xa226, 0xa242, 0xa226, 0x080c, 0x0dc5, - 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, 0x0003, - 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, - 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, - 0x0804, 0xa4d1, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, - 0x0016, 0x080c, 0xada2, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e, - 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa4bf, 0x721a, - 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6, + 0x4003, 0x080c, 0xada7, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, + 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa4eb, 0x080c, 0x9eef, + 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, + 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, + 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, + 0x00d6, 0x0804, 0x9e9f, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4eb, + 0x080c, 0x9eef, 0x7003, 0x5000, 0x0804, 0x9d6c, 0x080c, 0x9eef, + 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4eb, + 0x080c, 0x9f31, 0x0010, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x60c3, + 0x0004, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b, + 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, + 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9d6c, 0x080c, 0x9f3a, 0x7003, + 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003, + 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x080c, + 0x9f3a, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894, + 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998, + 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, + 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, + 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, + 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, + 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, + 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c, + 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, + 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, + 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa4eb, 0x080c, 0x9f3a, + 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, + 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9cea, + 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, + 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100, + 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, + 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, + 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, + 0x003e, 0x00de, 0x080c, 0xa4d9, 0x721a, 0x9f95, 0x0000, 0x7222, + 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, + 0xadbc, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, + 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, + 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, + 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, + 0x2021, 0x0100, 0x080c, 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a, + 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, + 0x00de, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa4d9, 0x721a, 0x7a08, + 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, + 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, + 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x0005, 0x9fa8, 0x9fb7, 0x9fc2, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa8, + 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x080c, 0x0dc5, + 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2be7, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4eb, 0x0431, + 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, + 0x0804, 0xa4eb, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, + 0x0004, 0x0804, 0xa4eb, 0x0026, 0x080c, 0xadbc, 0xb810, 0x9085, + 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9f0a, 0x0026, 0x080c, + 0xadbc, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, + 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c, 0x0026, + 0x080c, 0xadbc, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, + 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, + 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a, + 0x0054, 0x1a0c, 0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100, + 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x0005, 0xa047, 0xa10e, 0xa0e1, 0xa230, 0xa045, 0xa045, + 0xa045, 0xa045, 0xa045, 0xa045, 0xa045, 0xa906, 0xa90b, 0xa910, + 0xa915, 0xa045, 0xad04, 0xa045, 0xa901, 0x080c, 0x0dc5, 0x0096, + 0x780b, 0xffff, 0x080c, 0xa0b2, 0x7914, 0x2148, 0xa978, 0x7956, + 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, + 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, + 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, + 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, + 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, + 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010, + 0x080c, 0x1768, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, + 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, + 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, + 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, + 0x2001, 0x1a05, 0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009, + 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084, + 0x0180, 0x2001, 0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0, + 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, + 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, + 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, + 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, + 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, + 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, + 0x009e, 0x00de, 0x0804, 0xa4eb, 0x6813, 0x0008, 0xb810, 0x9085, + 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa4d9, 0x721a, 0x7a08, + 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, + 0x080c, 0xa20e, 0x7814, 0x2048, 0x080c, 0xce54, 0x1130, 0x7814, + 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, + 0x00de, 0x0005, 0xa12c, 0xa195, 0xa1a5, 0xa1cb, 0xa1d7, 0xa1e8, + 0xa1f0, 0xa12a, 0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c, + 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, + 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, + 0x2001, 0x19b3, 0x2004, 0x60c2, 0x0804, 0xa4eb, 0xc3e5, 0x0c88, + 0x9186, 0x0001, 0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904, + 0xa192, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, + 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, + 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, + 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, + 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, + 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, + 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, + 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, + 0x0804, 0xa4eb, 0xc3e5, 0x0804, 0xa151, 0x2011, 0x0008, 0x2001, + 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, + 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, + 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, + 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, + 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, + 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, + 0x0032, 0x0804, 0xa4eb, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, + 0x7216, 0x60c3, 0x0018, 0x0804, 0xa4eb, 0x0cd0, 0xc2e5, 0x2011, + 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, + 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4eb, + 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, + 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, + 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, + 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, + 0x7013, 0x0898, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, + 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, + 0xa240, 0xa240, 0xa242, 0xa240, 0xa240, 0xa240, 0xa25c, 0xa240, + 0x080c, 0x0dc5, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, + 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, + 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, + 0x60c3, 0x0001, 0x0804, 0xa4eb, 0x2009, 0x0003, 0x0019, 0x7033, + 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xadbc, 0x001e, 0xb810, 0x9085, + 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, + 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, + 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, + 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, + 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, + 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, + 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, + 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, + 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, + 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, + 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, + 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, + 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, + 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, + 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, + 0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, + 0x2009, 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, - 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028, 0x0110, - 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140, 0x2001, - 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, 0x2001, - 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, 0x0000, - 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c, 0x8000, - 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, 0x607f, - 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, 0x2048, - 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, - 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, - 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128, 0x609f, - 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, 0x602a, 0x609f, - 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, 0x2009, 0x07d0, - 0x080c, 0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, - 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, - 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582, - 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x33b1, - 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480, - 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80, - 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, - 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072, - 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c, - 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, - 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, - 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, - 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803, - 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, 0x07d0, 0x080c, - 0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, - 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, - 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, - 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820, 0x90be, - 0x0006, 0x0904, 0xa42e, 0x90be, 0x000a, 0x1904, 0xa3ea, 0xb8c0, - 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, - 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, - 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, - 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, - 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, - 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, - 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, - 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, - 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, - 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xad87, 0x2009, 0x07d0, - 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, - 0x878e, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, - 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0xa46a, 0x9185, - 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, - 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, - 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, - 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbac0, 0x629e, - 0x080c, 0xad87, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, - 0x0110, 0x2009, 0x1b58, 0x080c, 0x878e, 0x003e, 0x004e, 0x005e, - 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048, - 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0xa486, 0x9185, - 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, - 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, - 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a, - 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930, - 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x080c, 0xad64, - 0x0804, 0xa41a, 0xb8cc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048, - 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600, - 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000, - 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa3fd, 0x9185, 0x0700, - 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118, - 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c, + 0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, + 0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, + 0x9080, 0x33ac, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, + 0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, + 0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, + 0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, + 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, + 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, + 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, + 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, + 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, + 0x0140, 0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, + 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, + 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, + 0x7820, 0x90be, 0x0006, 0x0904, 0xa448, 0x90be, 0x000a, 0x1904, + 0xa404, 0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, + 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, + 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, + 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, + 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, + 0x0129, 0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, + 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, + 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, + 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, - 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e, - 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, - 0xad87, 0x0804, 0xa41a, 0x080c, 0xad64, 0x0804, 0xa41a, 0x7a10, - 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be, - 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843, 0x0001, 0x00de, - 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8780, - 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, - 0x0600, 0x0128, 0x0089, 0x080c, 0x8780, 0x001e, 0x0005, 0xc1e5, - 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000, 0x2001, - 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, - 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, - 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, - 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, - 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, - 0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11c0, 0x2001, 0x1a05, - 0x2004, 0x9005, 0x15d0, 0x080c, 0x7610, 0x1160, 0x2061, 0x0100, - 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0dc5, 0x080c, - 0x8780, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8, 0x6904, 0x9194, - 0x4000, 0x0540, 0x0811, 0x080c, 0x2d6b, 0x00c6, 0x2061, 0x19e9, - 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, - 0x81ff, 0x0198, 0x080c, 0x8780, 0x080c, 0xa4f4, 0x0070, 0x6124, - 0x91e5, 0x0000, 0x0140, 0x080c, 0xedaa, 0x080c, 0x8789, 0x2009, - 0x0014, 0x080c, 0xb166, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, - 0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005, 0x1db0, 0x00c6, - 0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, - 0x00ce, 0x080c, 0x8780, 0x080c, 0x5fe0, 0x2009, 0x1846, 0x2114, - 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, - 0x0026, 0x080c, 0x8796, 0x2071, 0x19e9, 0x713c, 0x81ff, 0x0904, - 0xa5fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11e0, - 0x0036, 0x2019, 0x0002, 0x080c, 0xa85d, 0x003e, 0x713c, 0x2160, - 0x080c, 0xedaa, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, - 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb166, - 0x080c, 0x7610, 0x0804, 0xa5fd, 0x080c, 0xa609, 0x0904, 0xa5fd, - 0x6904, 0xd1f4, 0x0904, 0xa604, 0x080c, 0x2d6b, 0x00c6, 0x703c, - 0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1528, - 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, 0x2104, 0xd0d4, - 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, - 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, 0x080c, 0x2c9d, - 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060, - 0x2009, 0x0049, 0x080c, 0xb166, 0x00c0, 0x0036, 0x2019, 0x0001, - 0x080c, 0xa85d, 0x003e, 0x713c, 0x2160, 0x080c, 0xedaa, 0x2009, - 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, - 0x0006, 0x2009, 0x004a, 0x080c, 0xb166, 0x002e, 0x001e, 0x00ee, - 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0xa5b4, 0x0804, - 0xa5b6, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, 0x090c, 0x0dc5, - 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, 0xa6bc, 0x9184, - 0x0048, 0x9086, 0x0008, 0x1904, 0xa6bc, 0x2009, 0x0206, 0x2104, - 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6bc, 0x2009, 0x022a, - 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, 0x03ff, 0x918c, - 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, 0x2010, 0x2100, - 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, 0x0250, 0x2008, - 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, 0x9102, 0x1a04, - 0xa6bc, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, 0x200a, 0x2069, - 0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010, 0x6916, 0x69c8, - 0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211, 0x1dd8, 0x2001, - 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, 0x0004, 0x2001, - 0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003, 0x0000, 0x6a88, - 0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014, 0x2048, 0xa87c, - 0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e, 0x2c10, 0x080c, - 0x1c01, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, 0x6ac4, 0x69c8, - 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, 0x002e, 0x080c, - 0x1c9a, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009, 0x1a86, 0x2104, - 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, 0x8211, 0x1df0, - 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, 0x0160, 0x6824, - 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085, 0x704a, 0x0079, - 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9006, - 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0026, - 0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8, 0x713c, 0x81ff, - 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, - 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0048, - 0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016, - 0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, - 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010, - 0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058, 0x8bff, 0x0190, - 0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096, - 0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x6849, 0x0110, - 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x1200, - 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, - 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, - 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, - 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa4d1, 0x080c, - 0x9ed5, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, - 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1, - 0x0156, 0x080c, 0x9f20, 0x7003, 0x0200, 0x080c, 0x8812, 0x20a9, - 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, - 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, - 0x0002, 0x1f04, 0xa757, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa4d1, - 0x0016, 0x0026, 0x080c, 0x9efc, 0x080c, 0x9f0e, 0x9e80, 0x0004, - 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, - 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, - 0x0004, 0x8003, 0x60c2, 0x080c, 0xa4d1, 0x002e, 0x001e, 0x0005, - 0x20a9, 0x0010, 0x4003, 0x080c, 0xad8d, 0x20a1, 0x0240, 0x22a8, - 0x4003, 0x0c68, 0x080c, 0x9ed5, 0x7003, 0x6200, 0x7808, 0x700e, - 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0016, 0x0026, 0x080c, 0x9ed5, - 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, - 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, - 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, - 0xa4d1, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, - 0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060, 0x8cff, 0x0178, - 0x080c, 0xd047, 0x1110, 0x080c, 0xbacb, 0x600c, 0x0006, 0x080c, - 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0xa905, 0x00ce, 0x0c78, 0x2c00, - 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, + 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, + 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xada1, + 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, + 0x1b58, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, + 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, + 0xa484, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, + 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, + 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, + 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, + 0xbac0, 0x629e, 0x080c, 0xada1, 0x2009, 0x07d0, 0x60c4, 0x9084, + 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x8794, 0x003e, + 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, + 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, + 0xa4a0, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, + 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, + 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, + 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, + 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, + 0x080c, 0xad7e, 0x0804, 0xa434, 0xb8cc, 0xd084, 0x0148, 0xb88c, + 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, + 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, + 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa417, + 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, + 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, + 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, + 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, + 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, + 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, + 0x0120, 0x080c, 0xada1, 0x0804, 0xa434, 0x080c, 0xad7e, 0x0804, + 0xa434, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, + 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843, + 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, + 0x080c, 0x8786, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, + 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8786, 0x001e, + 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, + 0x0000, 0x2001, 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, + 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, + 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, + 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, + 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, + 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7569, 0x11c0, + 0x2001, 0x1a05, 0x2004, 0x9005, 0x15d0, 0x080c, 0x7616, 0x1160, + 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, + 0x0dc5, 0x080c, 0x8786, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8, + 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2d62, 0x00c6, + 0x2061, 0x19e9, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, + 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x8786, 0x080c, 0xa50e, + 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xee0f, 0x080c, + 0x878f, 0x2009, 0x0014, 0x080c, 0xb180, 0x00ce, 0x0000, 0x002e, + 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005, + 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08, + 0x8108, 0x612a, 0x00ce, 0x080c, 0x8786, 0x080c, 0x5fe6, 0x2009, + 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, + 0x00e6, 0x0016, 0x0026, 0x080c, 0x879c, 0x2071, 0x19e9, 0x713c, + 0x81ff, 0x0904, 0xa617, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, + 0x7569, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, 0xa877, 0x003e, + 0x713c, 0x2160, 0x080c, 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296, + 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, + 0x080c, 0xb180, 0x080c, 0x7616, 0x0804, 0xa617, 0x080c, 0xa623, + 0x0904, 0xa617, 0x6904, 0xd1f4, 0x0904, 0xa61e, 0x080c, 0x2d62, + 0x00c6, 0x703c, 0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086, + 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, + 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, + 0x9294, 0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, + 0x080c, 0x2c94, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, + 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xb180, 0x00c0, 0x0036, + 0x2019, 0x0001, 0x080c, 0xa877, 0x003e, 0x713c, 0x2160, 0x080c, + 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, + 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb180, 0x002e, + 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, + 0xa5ce, 0x0804, 0xa5d0, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, + 0x090c, 0x0dc5, 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, + 0xa6d6, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904, 0xa6d6, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6d6, + 0x2009, 0x022a, 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, + 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, + 0x2010, 0x2100, 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, + 0x0250, 0x2008, 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, + 0x9102, 0x1a04, 0xa6d6, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, + 0x200a, 0x2069, 0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010, + 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211, + 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, + 0x0004, 0x2001, 0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003, + 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014, + 0x2048, 0xa87c, 0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e, + 0x2c10, 0x080c, 0x1c09, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, + 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, + 0x002e, 0x080c, 0x1ca2, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009, + 0x1a86, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, + 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, + 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085, + 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, + 0x8794, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, + 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8, + 0x713c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, + 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, + 0x7016, 0x0048, 0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, + 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, + 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058, + 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, + 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, + 0x684f, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9eef, + 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, + 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, + 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, + 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, + 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, + 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0xa4eb, 0x0156, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x080c, + 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, + 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, + 0x0002, 0x9290, 0x0002, 0x1f04, 0xa771, 0x60c3, 0x001c, 0x015e, + 0x0804, 0xa4eb, 0x0016, 0x0026, 0x080c, 0x9f16, 0x080c, 0x9f28, + 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, + 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, + 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, + 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, 0xa4eb, 0x002e, + 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, 0xada7, 0x20a1, + 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x9eef, 0x7003, 0x6200, + 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0016, 0x0026, + 0x080c, 0x9eef, 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, + 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, + 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, + 0x60c2, 0x080c, 0xa4eb, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060, + 0x8cff, 0x0178, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x600c, + 0x0006, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0xa91f, 0x00ce, + 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19e9, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, 0xa517, 0x6ac0, + 0x68c3, 0x0000, 0x080c, 0x878f, 0x00c6, 0x2061, 0x0100, 0x080c, + 0xaef8, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, + 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, + 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x878f, 0x6814, + 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, + 0x0000, 0x2011, 0x5f90, 0x080c, 0x8709, 0x20a9, 0x01f4, 0x0009, + 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, + 0x4000, 0x190c, 0x2d62, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, + 0x0010, 0x1f04, 0xa859, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, - 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, - 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x7024, - 0x2060, 0x8cff, 0x01f8, 0x080c, 0xa4fd, 0x6ac0, 0x68c3, 0x0000, - 0x080c, 0x8789, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaede, 0x00ce, - 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xb166, 0x000e, - 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, - 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, - 0x9096, 0x0004, 0x0d60, 0x080c, 0x8789, 0x6814, 0x9084, 0x0001, - 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, - 0x5f8a, 0x080c, 0x8703, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, - 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, - 0x2d6b, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, - 0xa83f, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x0005, 0x0126, 0x0156, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, - 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069, - 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c, 0x2060, 0x8cff, - 0x0904, 0xa8c8, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, - 0x0904, 0xa8c8, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, - 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x8796, 0x080c, - 0x2052, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, - 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, - 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2d6b, - 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0xa89e, - 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, - 0x9006, 0x080c, 0x2d5b, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1140, - 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110, 0x080c, 0xb166, - 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, - 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, - 0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c, - 0xa098, 0x7047, 0x1000, 0x0098, 0x080c, 0xa098, 0x7047, 0x4000, - 0x0070, 0x080c, 0xa098, 0x7047, 0x2000, 0x0048, 0x080c, 0xa098, - 0x7047, 0x0400, 0x0020, 0x080c, 0xa098, 0x7047, 0x0200, 0x7854, - 0x7032, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x00e6, 0x2071, 0x19e9, - 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, - 0x87ff, 0x0904, 0xa9aa, 0x8cff, 0x0904, 0xa9aa, 0x6020, 0x9086, - 0x0006, 0x1904, 0xa9a5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, - 0xa9a5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa9a5, - 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9a5, 0x7024, 0x9c06, - 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, - 0x0148, 0x6827, 0x0001, 0x080c, 0x8789, 0x080c, 0xaa2f, 0x7027, - 0x0000, 0x0428, 0x080c, 0x8789, 0x6820, 0xd0b4, 0x0110, 0x68a7, - 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, - 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, - 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, - 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014, - 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, - 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, - 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, - 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xce3d, - 0x0110, 0x080c, 0xe8e3, 0x009e, 0x080c, 0xb11a, 0x080c, 0xa905, - 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa920, 0x2c78, 0x600c, 0x2060, - 0x0804, 0xa920, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, - 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, - 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7638, - 0x2660, 0x2678, 0x8cff, 0x0904, 0xaa1e, 0x6020, 0x9086, 0x0006, - 0x1904, 0xaa19, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xaa19, - 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106, - 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, - 0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, - 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, - 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, + 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, + 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c, + 0x2060, 0x8cff, 0x0904, 0xa8e2, 0x9386, 0x0002, 0x1128, 0x6814, + 0x9084, 0x0002, 0x0904, 0xa8e2, 0x68af, 0x95f5, 0x6817, 0x0010, + 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, + 0x879c, 0x080c, 0x205a, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, + 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, + 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, + 0x190c, 0x2d62, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, + 0x1f04, 0xa8b8, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x6827, 0x4000, 0x6824, + 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110, + 0x080c, 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de, + 0x0005, 0x080c, 0xa0b2, 0x7047, 0x1000, 0x0098, 0x080c, 0xa0b2, + 0x7047, 0x4000, 0x0070, 0x080c, 0xa0b2, 0x7047, 0x2000, 0x0048, + 0x080c, 0xa0b2, 0x7047, 0x0400, 0x0020, 0x080c, 0xa0b2, 0x7047, + 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa4eb, 0x00e6, + 0x2071, 0x19e9, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678, + 0x2039, 0x0001, 0x87ff, 0x0904, 0xa9c4, 0x8cff, 0x0904, 0xa9c4, + 0x6020, 0x9086, 0x0006, 0x1904, 0xa9bf, 0x88ff, 0x0138, 0x2800, + 0x9c06, 0x1904, 0xa9bf, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, + 0x1904, 0xa9bf, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9bf, + 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, + 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x878f, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0428, 0x080c, 0x878f, 0x6820, 0xd0b4, + 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, + 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, - 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0110, - 0x080c, 0xe8e3, 0x080c, 0xb11a, 0x87ff, 0x1198, 0x00ce, 0x0804, - 0xa9ca, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9ca, 0x9006, 0x012e, - 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, - 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, - 0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, - 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, - 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, - 0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540, - 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, + 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, + 0x080c, 0xce54, 0x0110, 0x080c, 0xe948, 0x009e, 0x080c, 0xb134, + 0x080c, 0xa91f, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa93a, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xa93a, 0x9006, 0x012e, 0x000e, 0x006e, + 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, + 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, + 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19e9, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0xaa38, 0x6020, + 0x9086, 0x0006, 0x1904, 0xaa33, 0x87ff, 0x0128, 0x2700, 0x9c06, + 0x1904, 0xaa33, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, + 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, + 0x0001, 0x080c, 0xa877, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, + 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, - 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, - 0x97db, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, - 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, - 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678, - 0x8cff, 0x0904, 0xab15, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, - 0x9206, 0x1904, 0xab10, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, - 0x68c0, 0x9005, 0x0904, 0xaae7, 0x080c, 0xa4fd, 0x68c3, 0x0000, - 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, - 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, - 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, - 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, - 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, - 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd036, 0x1180, 0x080c, - 0x3274, 0x080c, 0xd047, 0x1518, 0x080c, 0xbacb, 0x0400, 0x080c, - 0xaa2f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, - 0xd047, 0x1118, 0x080c, 0xbacb, 0x0090, 0x6014, 0x2048, 0x080c, - 0xce3d, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c, - 0xd2b3, 0x080c, 0xb11a, 0x080c, 0xa905, 0x00ce, 0x0804, 0xaa90, - 0x2c78, 0x600c, 0x2060, 0x0804, 0xaa90, 0x012e, 0x000e, 0x002e, - 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, - 0x9086, 0x0006, 0x1d20, 0x080c, 0xe8e3, 0x0c08, 0x00d6, 0x080c, - 0x9f20, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, - 0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, - 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa4d1, - 0x00de, 0x0005, 0x080c, 0x9f20, 0x700b, 0x0800, 0x7814, 0x9084, - 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, - 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084, - 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4d1, 0x00b6, 0x00d6, - 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xd4c0, 0x00de, - 0x1904, 0xabc3, 0x080c, 0x9ed5, 0x7003, 0x1300, 0x782c, 0x080c, - 0xacc9, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, - 0xbaa0, 0x080c, 0xb051, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, - 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, - 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, - 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, - 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098, - 0x700e, 0x00a8, 0x080c, 0xb051, 0x1130, 0x7810, 0x2058, 0xb8a0, - 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, - 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, - 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, - 0xa4d1, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, - 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, - 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac3e, 0x9186, 0x0005, - 0x0904, 0xac26, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904, - 0xac2f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, - 0xaca6, 0x0005, 0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168, - 0x2009, 0x4000, 0x6800, 0x0002, 0xac07, 0xac12, 0xac09, 0xac12, - 0xac0e, 0xac07, 0xac07, 0xac12, 0xac12, 0xac12, 0xac12, 0xac07, - 0xac07, 0xac07, 0xac07, 0xac07, 0xac12, 0xac07, 0xac12, 0x080c, - 0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, - 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xac60, - 0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, - 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0xac67, - 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9, - 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, - 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6, - 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096, - 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103, - 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, - 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, - 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa4d1, 0x00b6, - 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f20, 0x9006, 0x7003, - 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, - 0x080c, 0xb051, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, - 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, - 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634, - 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, - 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, - 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9f20, - 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, - 0x0008, 0x0804, 0xa4d1, 0x080c, 0x9ecc, 0x7003, 0x1400, 0x7838, - 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, - 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, - 0xa4d1, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, - 0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848, - 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9f17, - 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, - 0x0804, 0xa4d1, 0x0021, 0x60c3, 0x0000, 0x0804, 0xa4d1, 0x00d6, - 0x080c, 0xada2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006, - 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0819, - 0x080c, 0xa4bf, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071, - 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, - 0x60a7, 0x9575, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101, - 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa4f4, 0x080c, 0x8780, - 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c, - 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, - 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, - 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, - 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada2, 0x00de, - 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, - 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, - 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, - 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, - 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, - 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, - 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, - 0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, - 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0, - 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c, - 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009, - 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c, 0x9ed5, - 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, - 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197d, - 0x2004, 0x9086, 0xaaaa, 0x1904, 0xae47, 0x7003, 0x5400, 0x00c6, - 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, - 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c, 0xff00, - 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290, 0x0006, - 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadd8, 0x20a9, 0x0004, - 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xade2, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006, + 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, + 0xce54, 0x0110, 0x080c, 0xe948, 0x080c, 0xb134, 0x87ff, 0x1198, + 0x00ce, 0x0804, 0xa9e4, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9e4, + 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, + 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, + 0x0c80, 0x00e6, 0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678, + 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, + 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, + 0x0040, 0x090c, 0x97e1, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, + 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c, + 0x2660, 0x2678, 0x8cff, 0x0904, 0xab2f, 0x6010, 0x00b6, 0x2058, + 0xb8a0, 0x00be, 0x9206, 0x1904, 0xab2a, 0x7024, 0x9c06, 0x1520, + 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xab01, 0x080c, 0xa517, + 0x68c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, + 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd04d, + 0x1180, 0x080c, 0x326f, 0x080c, 0xd05e, 0x1518, 0x080c, 0xbae2, + 0x0400, 0x080c, 0xaa49, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, + 0x0898, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0090, 0x6014, + 0x2048, 0x080c, 0xce54, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x080c, 0xd2ca, 0x080c, 0xb134, 0x080c, 0xa91f, 0x00ce, + 0x0804, 0xaaaa, 0x2c78, 0x600c, 0x2060, 0x0804, 0xaaaa, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xe948, 0x0c08, + 0x00d6, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, + 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, + 0x080c, 0xa4eb, 0x00de, 0x0005, 0x080c, 0x9f3a, 0x700b, 0x0800, + 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, + 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, + 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4eb, + 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, + 0xd4d7, 0x00de, 0x1904, 0xabdd, 0x080c, 0x9eef, 0x7003, 0x1300, + 0x782c, 0x080c, 0xace3, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, + 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb06b, 0x11d8, 0x9286, 0x007e, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, + 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, + 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, + 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xb06b, 0x1130, 0x7810, + 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, + 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, + 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, + 0x00de, 0x080c, 0xa4eb, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, + 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, + 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac58, + 0x9186, 0x0005, 0x0904, 0xac40, 0x9186, 0x0004, 0x05d8, 0x9186, + 0x0008, 0x0904, 0xac49, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, + 0x1700, 0x080c, 0xacc0, 0x0005, 0x080c, 0xac81, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0xac21, 0xac2c, + 0xac23, 0xac2c, 0xac28, 0xac21, 0xac21, 0xac2c, 0xac2c, 0xac2c, + 0xac2c, 0xac21, 0xac21, 0xac21, 0xac21, 0xac21, 0xac2c, 0xac21, + 0xac2c, 0x080c, 0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, + 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, + 0x0804, 0xac7a, 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, + 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, + 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, + 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, + 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, + 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, + 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, + 0xa4eb, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f3a, + 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, + 0x2058, 0xb8a0, 0x080c, 0xb06b, 0x1118, 0x9092, 0x007e, 0x0268, + 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, + 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, + 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, + 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, + 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, + 0x080c, 0x9f3a, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, + 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9ee6, 0x7003, + 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, + 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, + 0x0010, 0x0804, 0xa4eb, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, + 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844, + 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, + 0x080c, 0x9f31, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, + 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0021, 0x60c3, 0x0000, 0x0804, + 0xa4eb, 0x00d6, 0x080c, 0xadbc, 0xb810, 0x9085, 0x0300, 0x7002, + 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x7013, 0x0819, 0x080c, 0xa4d9, 0x721a, 0x2f10, 0x7222, 0x7a08, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, + 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2be7, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa50e, + 0x080c, 0x8786, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, + 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, + 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, + 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, + 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, + 0xadbc, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, + 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, + 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, + 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, + 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, + 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, + 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092, + 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, + 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, + 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, + 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, + 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, + 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, + 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xae61, 0x7003, + 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, + 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, + 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, + 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadf2, + 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, + 0x1f04, 0xadfc, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, + 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, + 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada7, 0x00de, + 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, - 0x00d6, 0x2069, 0x0200, 0x080c, 0xad8d, 0x00de, 0x2071, 0x0240, - 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002, 0x8007, - 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, - 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c, 0x9080, - 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, - 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c, 0x60a3, - 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, - 0x1168, 0x080c, 0x7563, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x6014, - 0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, 0x080c, 0xa4d1, - 0x080c, 0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6, - 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007, - 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xadbd, - 0x080c, 0x9ed5, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, - 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084, 0x00ff, - 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c, 0x918c, - 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998, 0x918c, - 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d, 0x7112, - 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001, 0x4002, - 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004, 0x2009, - 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xae99, 0x20a9, - 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, - 0xaea3, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xad8d, 0x001e, - 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011, - 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xaeb9, 0x2009, - 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006, - 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaeca, 0x00ce, 0x60c3, - 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4d1, 0x080c, - 0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x9290, - 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000, - 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020, - 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120, - 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096, - 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c, - 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003, - 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a, - 0xa813, 0x20e6, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x9a09, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xafb1, 0x7024, - 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xaf83, - 0x080c, 0xa4fd, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, - 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, - 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, - 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x080c, 0xd036, 0x1180, 0x080c, 0x3274, 0x080c, 0xd047, 0x1518, - 0x080c, 0xbacb, 0x0400, 0x080c, 0xaa2f, 0x6824, 0xd084, 0x09b0, - 0x6827, 0x0001, 0x0898, 0x080c, 0xd047, 0x1118, 0x080c, 0xbacb, - 0x0090, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0168, 0x6020, 0x9086, - 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, - 0x6dcb, 0x080c, 0xd02a, 0x080c, 0xd2b3, 0x080c, 0xb11a, 0x080c, - 0xa905, 0x00ce, 0x0804, 0xaf34, 0x2c78, 0x600c, 0x2060, 0x0804, - 0xaf34, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e, - 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1d08, 0x080c, 0xe8e3, 0x08f0, 0x00d6, 0x0156, 0x080c, - 0x9f20, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, - 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, - 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, - 0x080c, 0x7563, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, - 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x8812, 0x20a9, - 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305, - 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, - 0x0002, 0x1f04, 0xaff7, 0x60c3, 0x0020, 0x080c, 0xa4d1, 0x015e, - 0x00de, 0x0005, 0x0156, 0x080c, 0x9f20, 0x7a14, 0x82ff, 0x0168, - 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, - 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, - 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a, - 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082, - 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820, - 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, - 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, - 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, - 0xa4d1, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005, - 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd, - 0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d, 0x003e, 0x0005, - 0x080c, 0x33aa, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, - 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6717, 0xb85c, 0xc0ac, - 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, 0x188d, 0x7000, - 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800, 0x7076, 0x707a, - 0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b, 0x1cd0, - 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, - 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, - 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, - 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018, - 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, - 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, - 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, + 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, + 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1168, 0x080c, 0x7569, 0x0150, 0x6028, 0xc0bd, + 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, + 0x080c, 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, + 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, + 0x0804, 0xadd7, 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6, + 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, + 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, + 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, + 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, + 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, + 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, + 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaeb3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xaebd, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, + 0xada7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, + 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaed3, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, + 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaee4, + 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, + 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, + 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, + 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, + 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, + 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, + 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, + 0x2900, 0xa85a, 0xa813, 0x20ee, 0x080c, 0x93a0, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9a0f, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, + 0xafcb, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0904, 0xaf9d, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c, 0xaa49, + 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, + 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, + 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x080c, 0xd04d, 0x1180, 0x080c, 0x326f, 0x080c, + 0xd05e, 0x1518, 0x080c, 0xbae2, 0x0400, 0x080c, 0xaa49, 0x6824, + 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xd05e, 0x1118, + 0x080c, 0xbae2, 0x0090, 0x6014, 0x2048, 0x080c, 0xce54, 0x0168, + 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xd2ca, 0x080c, + 0xb134, 0x080c, 0xa91f, 0x00ce, 0x0804, 0xaf4e, 0x2c78, 0x600c, + 0x2060, 0x0804, 0xaf4e, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, + 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe948, 0x08f0, 0x00d6, + 0x0156, 0x080c, 0x9f3a, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, + 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, + 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, + 0xc38d, 0x0060, 0x080c, 0x7569, 0x1110, 0xc3ad, 0x0008, 0xc3a5, + 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, + 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, + 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, + 0x0002, 0x9290, 0x0002, 0x1f04, 0xb011, 0x60c3, 0x0020, 0x080c, + 0xa4eb, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9f3a, 0x7a14, + 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, + 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, + 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, + 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, + 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, + 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, + 0x015e, 0x0804, 0xa4eb, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, + 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, + 0x080c, 0xa8f7, 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877, + 0x003e, 0x0005, 0x080c, 0x33a5, 0x0188, 0x0016, 0x00b6, 0x00c6, + 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x671d, + 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, + 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800, + 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056, + 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, - 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, - 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, - 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, - 0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, - 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026, - 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x602a, - 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086, 0x0001, 0x0108, - 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x98e7, 0x001e, - 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, 0x01c0, 0x601c, - 0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023, 0x0007, 0x2001, - 0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, - 0x601a, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6013, 0x0000, 0x000e, - 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, - 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, - 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, - 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018, - 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, - 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, - 0x000f, 0x0002, 0xb179, 0xb182, 0xb19d, 0xb1b8, 0xd590, 0xd5ad, - 0xd5c8, 0xb179, 0xb182, 0x8fc7, 0xb1d4, 0xb179, 0xb179, 0xb179, - 0xb179, 0x9186, 0x0013, 0x1128, 0x080c, 0x97db, 0x080c, 0x98e7, - 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, - 0x0013, 0x006e, 0x0005, 0xb19b, 0xb91a, 0xbb12, 0xb19b, 0xbba8, - 0xb4b7, 0xb19b, 0xb19b, 0xb89c, 0xc11f, 0xb19b, 0xb19b, 0xb19b, - 0xb19b, 0xb19b, 0xb19b, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, - 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b6, 0xc7e9, - 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xc780, 0xc96b, - 0xb1b6, 0xc82a, 0xc8a9, 0xc82a, 0xc8a9, 0xb1b6, 0x080c, 0x0dc5, - 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x0002, 0xb1d2, - 0xc166, 0xc22e, 0xc35e, 0xc50d, 0xb1d2, 0xb1d2, 0xb1d2, 0xc13a, - 0xc70c, 0xc70f, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xc73e, 0xb1d2, - 0xb1d2, 0xb1d2, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0016, - 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1ed, 0xb1ed, 0xb230, - 0xb2cf, 0xb364, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ef, 0xb1ed, 0xb1ed, - 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0x080c, 0x0dc5, 0x9186, - 0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c, - 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, - 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, - 0x9006, 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, - 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, - 0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x9a09, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, - 0x2c00, 0x080c, 0xb386, 0x080c, 0xd560, 0x6003, 0x0007, 0x0005, - 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, - 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, - 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, - 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, - 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, - 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, - 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, - 0x9405, 0x0002, 0xb297, 0xb297, 0xb292, 0xb295, 0xb297, 0xb28f, - 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, - 0xb282, 0xb282, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, - 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c, - 0xbd75, 0x0028, 0x080c, 0xbe5c, 0x0010, 0x080c, 0xbf52, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, - 0x080c, 0xb444, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, - 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, - 0x2041, 0x126c, 0x080c, 0xb608, 0x0160, 0x000e, 0x9005, 0x0120, - 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, - 0xb0e7, 0x2001, 0x002c, 0x900e, 0x080c, 0xb4aa, 0x0c70, 0x91b6, - 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, - 0x0dc5, 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca, - 0x2001, 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, - 0x0006, 0x0016, 0x0026, 0x080c, 0x92e7, 0x002e, 0x001e, 0x000e, - 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb230, - 0x0005, 0xb302, 0xb302, 0xb304, 0xb33a, 0xb302, 0xb302, 0xb302, - 0xb302, 0xb34d, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c, - 0x9897, 0x080c, 0x9a09, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, - 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, - 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb4aa, 0x080c, 0xb0e7, - 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, - 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, - 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, - 0x00de, 0x0005, 0x080c, 0x9897, 0x00d6, 0x0096, 0x6114, 0x2148, - 0x080c, 0xce3f, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dcb, 0x009e, - 0x00de, 0x080c, 0xb0e7, 0x0804, 0x9a09, 0x080c, 0x9897, 0x080c, - 0x324b, 0x080c, 0xd55d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, - 0xce3f, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x00de, - 0x080c, 0xb0e7, 0x0804, 0x9a09, 0x9182, 0x0047, 0x0002, 0xb374, - 0xb376, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, - 0xb374, 0xb374, 0xb374, 0xb376, 0x080c, 0x0dc5, 0x00d6, 0x0096, - 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, - 0x080c, 0x6dcb, 0x009e, 0x00de, 0x0804, 0xb0e7, 0x0026, 0x0036, - 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e, - 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, - 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, - 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, - 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, - 0x9182, 0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x04c0, - 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x96b2, - 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, - 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, - 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc9f0, - 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, - 0x080c, 0xc9f0, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, - 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, - 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, - 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dcb, - 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, - 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, - 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, - 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, - 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, - 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, - 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, - 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dcb, - 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, - 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, - 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, - 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, - 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e, - 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, - 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, - 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, - 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, - 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, - 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb459, 0x0804, - 0xb45b, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, - 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, - 0xa982, 0x080c, 0x6dbe, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, - 0x0015, 0x1118, 0x080c, 0xb0e7, 0x0030, 0x91b6, 0x0016, 0x190c, - 0x0dc5, 0x080c, 0xb0e7, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, - 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, - 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, - 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, - 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, - 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, - 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xce3f, 0x0130, 0x6014, - 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb0e7, - 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, - 0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, - 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb0e7, - 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, - 0x0016, 0x080c, 0xd548, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, - 0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, - 0xb8f2, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, - 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, - 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, - 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, - 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, - 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, - 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, - 0xb0e7, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, - 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, - 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, - 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xc9f0, 0x080c, - 0xce3f, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, - 0xa867, 0x0103, 0x080c, 0xb0e7, 0x001e, 0x009e, 0x0005, 0x0016, - 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, - 0x0096, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dcb, - 0x009e, 0x080c, 0xb0e7, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, - 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, - 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, - 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xc9f0, 0x009e, 0x080c, - 0xce3f, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, - 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb0e7, 0x009e, 0x001e, 0x0005, - 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, - 0xbacb, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, - 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, - 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, - 0x2031, 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898, - 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, - 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, - 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, - 0x10f8, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, + 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, + 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, + 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, + 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a, + 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006, + 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x1a0c, 0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, + 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056, + 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, + 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086, + 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x98ed, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, + 0x01c0, 0x601c, 0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023, + 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, + 0x0208, 0x8004, 0x601a, 0x080c, 0xec02, 0x6043, 0x0000, 0x6013, + 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, + 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, + 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, + 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x6020, 0x9084, 0x000f, 0x0002, 0xb193, 0xb19c, 0xb1b7, 0xb1d2, + 0xd5a9, 0xd5c6, 0xd5e1, 0xb193, 0xb19c, 0x8fcd, 0xb1eb, 0xb193, + 0xb193, 0xb193, 0xb193, 0x9186, 0x0013, 0x1128, 0x080c, 0x97e1, + 0x080c, 0x98ed, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, + 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b5, 0xb931, 0xbb29, + 0xb1b5, 0xbbbf, 0xb4ce, 0xb1b5, 0xb1b5, 0xb8b3, 0xc12f, 0xb1b5, + 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0x080c, 0x0dc5, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, + 0xb1d0, 0xc7fc, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, + 0xc793, 0xc97e, 0xb1d0, 0xc83d, 0xc8bc, 0xc83d, 0xc8bc, 0xb1d0, + 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000, + 0x0002, 0xb1e9, 0xc176, 0xc23e, 0xc371, 0xc520, 0xb1e9, 0xb1e9, + 0xb1e9, 0xc14a, 0xc71f, 0xc722, 0xb1e9, 0xb1e9, 0xb1e9, 0xb1e9, + 0xc751, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb204, 0xb204, 0xb247, 0xb2e6, + 0xb37b, 0xb204, 0xb204, 0xb204, 0xb206, 0xb204, 0xb204, 0xb204, + 0xb204, 0xb204, 0xb204, 0xb204, 0x080c, 0x0dc5, 0x9186, 0x004c, + 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c, 0xc0ed, + 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, + 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, + 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f, + 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, + 0x080c, 0xb39d, 0x080c, 0xd579, 0x6003, 0x0007, 0x0005, 0x00d6, + 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c, + 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, + 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, + 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, + 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, + 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, + 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, + 0x0002, 0xb2ae, 0xb2ae, 0xb2a9, 0xb2ac, 0xb2ae, 0xb2a6, 0xb299, + 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, + 0xb299, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c, 0xbd80, + 0x0028, 0x080c, 0xbe67, 0x0010, 0x080c, 0xbf5d, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, + 0xb45b, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, + 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, + 0x126c, 0x080c, 0xb61f, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, + 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xb101, + 0x2001, 0x002c, 0x900e, 0x080c, 0xb4c1, 0x0c70, 0x91b6, 0x0015, + 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0dc5, + 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca, 0x2001, + 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x080c, 0x92ed, 0x002e, 0x001e, 0x000e, 0x012e, + 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb247, 0x0005, + 0xb319, 0xb319, 0xb31b, 0xb351, 0xb319, 0xb319, 0xb319, 0xb319, + 0xb364, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c, 0x989d, + 0x080c, 0x9a0f, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, + 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, + 0x2001, 0x0000, 0x900e, 0x080c, 0xb4c1, 0x080c, 0xb101, 0x00a8, + 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, + 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, + 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, + 0x0005, 0x080c, 0x989d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce56, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x00de, + 0x080c, 0xb101, 0x0804, 0x9a0f, 0x080c, 0x989d, 0x080c, 0x3246, + 0x080c, 0xd576, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, + 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x009e, 0x00de, 0x080c, + 0xb101, 0x0804, 0x9a0f, 0x9182, 0x0047, 0x0002, 0xb38b, 0xb38d, + 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, + 0xb38b, 0xb38b, 0xb38d, 0x080c, 0x0dc5, 0x00d6, 0x0096, 0x601f, + 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, + 0x6dd1, 0x009e, 0x00de, 0x0804, 0xb101, 0x0026, 0x0036, 0x0056, + 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e, 0x000e, + 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, + 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990, + 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, + 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, + 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xca03, 0x04c0, 0x2130, + 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xca03, 0x96b2, 0x0034, + 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x01d0, + 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, + 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xca03, 0x00b8, + 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, + 0xca03, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, + 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, + 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dd1, 0x000e, + 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, + 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, + 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, + 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, + 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, + 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dd1, 0x009e, + 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, + 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, + 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, + 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e, 0x2900, + 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, + 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, + 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, + 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, + 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, + 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb470, 0x0804, 0xb472, + 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, + 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, + 0x080c, 0x6dc4, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, + 0x1118, 0x080c, 0xb101, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0dc5, + 0x080c, 0xb101, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, + 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, + 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, + 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, + 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, + 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, + 0x8211, 0x1db8, 0x0096, 0x080c, 0xce56, 0x0130, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb101, 0x0096, + 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, + 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb101, 0x003e, + 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, + 0x080c, 0xd561, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, + 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xb909, + 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, + 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, + 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, + 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, + 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xb101, + 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, + 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, + 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xca03, 0x080c, 0xce56, + 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, + 0x0103, 0x080c, 0xb101, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, + 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, + 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dd1, 0x009e, + 0x080c, 0xb101, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, + 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, + 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, + 0x9005, 0x0108, 0x2048, 0x080c, 0xca03, 0x009e, 0x080c, 0xce56, + 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, + 0xa867, 0x0103, 0x080c, 0xb101, 0x009e, 0x001e, 0x0005, 0x0086, + 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xbae2, + 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, + 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, + 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, + 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, + 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, + 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x10f8, + 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, + 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, + 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, + 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, + 0x080c, 0xd4d7, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, + 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, + 0xb101, 0x0020, 0x0039, 0x0010, 0x080c, 0xb73e, 0x002e, 0x00de, + 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, + 0xb726, 0x918e, 0x0016, 0x1904, 0xb73c, 0x700c, 0x908c, 0xff00, + 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb700, 0x89ff, + 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6e3, 0x0804, 0xb73a, + 0x6808, 0x9086, 0xffff, 0x1904, 0xb728, 0xa87c, 0x9084, 0x0060, + 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xb728, + 0x6824, 0xd084, 0x1904, 0xb728, 0xd0b4, 0x0158, 0x0016, 0x2001, + 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, + 0xb728, 0x080c, 0xd041, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, + 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, + 0x91b1, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, + 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb65, 0x00ce, 0x0804, 0xb73a, + 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61bb, 0x0010, 0x080c, + 0x65c8, 0x00ce, 0x1904, 0xb728, 0x00c6, 0x2d60, 0x080c, 0xb101, + 0x00ce, 0x0804, 0xb73a, 0x00c6, 0x080c, 0xb153, 0x0198, 0x6017, + 0x0000, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x6904, + 0x00c6, 0x2d60, 0x080c, 0xb101, 0x00ce, 0x080c, 0xb180, 0x00ce, + 0x0804, 0xb73a, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce, 0x04d0, + 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, + 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, + 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00, + 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0, + 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, + 0xa87b, 0x0003, 0x080c, 0x6beb, 0x080c, 0xd041, 0x080c, 0xb134, + 0x00de, 0x00ce, 0x080c, 0xb101, 0x009e, 0x0005, 0x9186, 0x0015, + 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, + 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xec02, 0x080c, 0x88f1, + 0x080c, 0xb101, 0x00ce, 0x080c, 0xb101, 0x0005, 0x0026, 0x0036, + 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989, + 0x2004, 0x6842, 0x0804, 0xb7b8, 0x00c6, 0x2d60, 0x080c, 0xca64, + 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, + 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, + 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, + 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, + 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, + 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, + 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, + 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, + 0x2001, 0x0005, 0x6832, 0x080c, 0xd1c9, 0x080c, 0x98ed, 0x0010, + 0x080c, 0xb101, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, - 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, - 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, - 0x0035, 0x080c, 0xd4c0, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, - 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, - 0x080c, 0xb0e7, 0x0020, 0x0039, 0x0010, 0x080c, 0xb727, 0x002e, - 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, - 0x0904, 0xb70f, 0x918e, 0x0016, 0x1904, 0xb725, 0x700c, 0x908c, - 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb6e9, - 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6cc, 0x0804, - 0xb723, 0x6808, 0x9086, 0xffff, 0x1904, 0xb711, 0xa87c, 0x9084, - 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, - 0xb711, 0x6824, 0xd084, 0x1904, 0xb711, 0xd0b4, 0x0158, 0x0016, - 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, - 0x1a04, 0xb711, 0x080c, 0xd02a, 0x685c, 0xa882, 0xa87c, 0xc0dc, - 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, - 0x080c, 0x91ab, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, - 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb52, 0x00ce, 0x0804, - 0xb723, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61b5, 0x0010, - 0x080c, 0x65c2, 0x00ce, 0x1904, 0xb711, 0x00c6, 0x2d60, 0x080c, - 0xb0e7, 0x00ce, 0x0804, 0xb723, 0x00c6, 0x080c, 0xb139, 0x0198, - 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003, - 0x6904, 0x00c6, 0x2d60, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb166, - 0x00ce, 0x0804, 0xb723, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce, - 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, - 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, - 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x00e8, 0x700c, 0x9086, - 0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479, - 0x00a0, 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867, - 0x0103, 0xa87b, 0x0003, 0x080c, 0x6be5, 0x080c, 0xd02a, 0x080c, - 0xb11a, 0x00de, 0x00ce, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x9186, - 0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e, - 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xeb9d, 0x080c, - 0x88eb, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb0e7, 0x0005, 0x0026, - 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, - 0x1989, 0x2004, 0x6842, 0x0804, 0xb7a1, 0x00c6, 0x2d60, 0x080c, - 0xca51, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, - 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x9335, 0x080c, - 0x98e7, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, - 0x090c, 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, - 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, - 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, - 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, - 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, - 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, - 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd1b2, 0x080c, 0x98e7, - 0x0010, 0x080c, 0xb0e7, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, - 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, - 0xba10, 0x00be, 0x9206, 0x1904, 0xb80c, 0x700c, 0x6210, 0x00b6, - 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb80c, 0x6038, 0x2068, - 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb80c, - 0x9286, 0x0002, 0x0904, 0xb80c, 0x9286, 0x0000, 0x05e8, 0x6808, - 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, - 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, - 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, - 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, - 0x2048, 0x080c, 0xce3f, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e, - 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x0030, 0x6038, 0x2070, - 0x2001, 0x1989, 0x2004, 0x7042, 0x080c, 0xb0e7, 0x002e, 0x00de, - 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, - 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, - 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, - 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0e7, 0x002e, - 0x003e, 0x015e, 0x009e, 0x1904, 0xb87b, 0x0096, 0x0156, 0x0036, - 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, - 0x080c, 0xc0e7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, - 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, - 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb4f3, 0x0096, 0x2048, - 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, - 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, - 0xb608, 0x0130, 0x00fe, 0x009e, 0x080c, 0xb0e7, 0x00be, 0x0005, - 0x080c, 0xbacb, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x324b, 0x080c, - 0xd55d, 0x00fe, 0x00c6, 0x080c, 0xb091, 0x2f00, 0x6012, 0x6017, - 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, - 0x0007, 0x080c, 0x665d, 0x080c, 0x6689, 0x080c, 0x937d, 0x080c, - 0x98e7, 0x00ce, 0x0804, 0xb84e, 0x2100, 0x91b2, 0x0053, 0x1a0c, - 0x0dc5, 0x91b2, 0x0040, 0x1a04, 0xb904, 0x0002, 0xb8f2, 0xb8f2, - 0xb8e8, 0xb8f2, 0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, - 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, - 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, - 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8f2, - 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e8, 0xb8e6, - 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, - 0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, - 0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8e6, 0x080c, 0x0dc5, - 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be, - 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, - 0x080c, 0x937d, 0x0010, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000, - 0x080c, 0x98e7, 0x012e, 0x0005, 0x2600, 0x0002, 0xb8f2, 0xb8f2, - 0xb918, 0xb8f2, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918, 0xb8f2, - 0xb918, 0xb8f2, 0xb918, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918, - 0x080c, 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6, - 0x0013, 0x0904, 0xb9ed, 0x91b6, 0x0027, 0x1904, 0xb997, 0x080c, - 0x97db, 0x6004, 0x080c, 0xd036, 0x01b0, 0x080c, 0xd047, 0x01a8, - 0x908e, 0x0021, 0x0904, 0xb994, 0x908e, 0x0022, 0x1130, 0x080c, - 0xb51f, 0x0904, 0xb990, 0x0804, 0xb991, 0x908e, 0x003d, 0x0904, - 0xb994, 0x0804, 0xb98a, 0x080c, 0x3274, 0x2001, 0x0007, 0x080c, - 0x665d, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbacb, - 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, - 0x7563, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, - 0x2110, 0x080c, 0xecaa, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, - 0x2110, 0x2019, 0x0028, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, - 0x93ad, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, - 0xe671, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd55d, 0x0016, - 0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x001e, 0x080c, 0x3347, 0x080c, - 0x98e7, 0x0030, 0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7, - 0x0005, 0x080c, 0xbacb, 0x0cb0, 0x080c, 0xbb07, 0x0c98, 0x9186, - 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd56e, 0x0d80, - 0x6000, 0x9086, 0x0002, 0x0904, 0xbb12, 0x0c50, 0x9186, 0x0014, - 0x1d38, 0x080c, 0x97db, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, - 0xb51f, 0x09f0, 0x080c, 0x324b, 0x080c, 0xd55d, 0x080c, 0xd036, - 0x1198, 0x080c, 0x3274, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, - 0x080c, 0xbacb, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, - 0xc185, 0x2102, 0x0804, 0xb98a, 0x080c, 0xd047, 0x1120, 0x080c, - 0xbacb, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, - 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe, - 0x00ee, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, - 0x0022, 0x090c, 0xbacb, 0x0804, 0xb98a, 0x90b2, 0x0040, 0x1a04, - 0xbaa7, 0x2008, 0x0002, 0xba35, 0xba36, 0xba39, 0xba3c, 0xba3f, - 0xba4c, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, - 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, - 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, - 0xba33, 0xba4f, 0xba5c, 0xba33, 0xba5e, 0xba5c, 0xba33, 0xba33, - 0xba33, 0xba33, 0xba33, 0xba5c, 0xba5c, 0xba33, 0xba33, 0xba33, - 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba8e, 0xba5c, 0xba33, - 0xba58, 0xba33, 0xba33, 0xba33, 0xba59, 0xba33, 0xba33, 0xba33, - 0xba5c, 0xba85, 0xba33, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b, - 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, - 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, - 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, - 0x97db, 0x6003, 0x0005, 0x080c, 0xd560, 0x080c, 0x98e7, 0x0070, - 0x0018, 0x0010, 0x080c, 0x665d, 0x0804, 0xba9f, 0x080c, 0x97db, - 0x080c, 0xd560, 0x6003, 0x0004, 0x080c, 0x98e7, 0x0005, 0x080c, - 0x665d, 0x080c, 0x97db, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, - 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, - 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, - 0x631a, 0x003e, 0x080c, 0x98e7, 0x0c08, 0x080c, 0x97db, 0x080c, - 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x08c0, 0x00e6, 0x00f6, - 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe, 0x00ee, - 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0838, 0x080c, - 0x97db, 0x6003, 0x0002, 0x080c, 0xd560, 0x0804, 0x98e7, 0x2600, - 0x2008, 0x0002, 0xbabe, 0xba9f, 0xbabc, 0xba9f, 0xba9f, 0xbabc, - 0xbabc, 0xbabc, 0xbabc, 0xba9f, 0xbabc, 0xba9f, 0xbabc, 0xba9f, - 0xbabc, 0xbabc, 0xbabc, 0xbabc, 0x080c, 0x0dc5, 0x080c, 0x97db, - 0x0096, 0x6014, 0x2048, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7, - 0x080c, 0x98e7, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, - 0xce3f, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, - 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5567, 0x0130, 0x2001, - 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, - 0x2011, 0x4005, 0x080c, 0xd424, 0x0090, 0xa868, 0xd0fc, 0x0178, - 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, - 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, - 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, - 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, - 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff, - 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120, - 0x080c, 0xd343, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0043, 0x1120, - 0x080c, 0xd38c, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x004b, 0x1120, - 0x080c, 0xd3b8, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0033, 0x1120, - 0x080c, 0xd2d5, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0028, 0x1120, - 0x080c, 0xd085, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0029, 0x1120, - 0x080c, 0xd0c6, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x001f, 0x1120, - 0x080c, 0xb4c4, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0000, 0x1118, - 0x080c, 0xb812, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, - 0xb500, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb626, - 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7a7, 0x0438, - 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb538, 0x0400, 0x6604, - 0x96b6, 0x0044, 0x1118, 0x080c, 0xb574, 0x00c8, 0x6604, 0x96b6, - 0x0049, 0x1118, 0x080c, 0xb5b5, 0x0090, 0x6604, 0x96b6, 0x0041, - 0x1118, 0x080c, 0xb59f, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, - 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe01, 0x00be, - 0x0005, 0x080c, 0xb181, 0x0cd8, 0xbbb4, 0xbbc2, 0xbbb4, 0xbc09, - 0xbbb4, 0xbd75, 0xbe0e, 0xbbb4, 0xbbb4, 0xbdd7, 0xbbb4, 0xbded, - 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, - 0x0103, 0x009e, 0x0804, 0xb0e7, 0xa001, 0xa001, 0x0005, 0x6604, - 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x6649, 0x0804, - 0xb0e7, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074, - 0x1540, 0x080c, 0xe642, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, - 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, - 0x00be, 0x2001, 0x0006, 0x080c, 0x665d, 0x080c, 0x3274, 0x080c, - 0xb0e7, 0x0098, 0x2001, 0x000a, 0x080c, 0x665d, 0x080c, 0x3274, - 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, - 0x0020, 0x2001, 0x0001, 0x080c, 0xbd45, 0x00ee, 0x0005, 0x00d6, - 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x6649, 0x2069, 0x1847, - 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6689, 0x00de, - 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, - 0x0074, 0x1904, 0xbd1a, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, - 0x1120, 0x080c, 0xbf5d, 0x0804, 0xbc7b, 0x080c, 0xbf52, 0x6010, - 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, - 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, - 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0030, 0xa807, - 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, - 0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x0804, 0xbd1f, 0x080c, - 0xbd2d, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, - 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x08f8, 0x080c, 0xbd23, - 0x0160, 0x9006, 0x080c, 0x6649, 0x2001, 0x0004, 0x080c, 0x6689, - 0x2001, 0x0007, 0x080c, 0x665d, 0x08a0, 0x2001, 0x0004, 0x080c, - 0x665d, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x080c, - 0x98e7, 0x0804, 0xbd1f, 0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xd255, - 0x080c, 0x7563, 0x0118, 0xd0dc, 0x1904, 0xbc3d, 0x2011, 0x1837, - 0x2204, 0xc0ad, 0x2012, 0x2001, 0x196e, 0x2004, 0x00f6, 0x2079, - 0x0100, 0x78e3, 0x0000, 0x080c, 0x28fd, 0x78e2, 0x00fe, 0x0804, - 0xbc3d, 0x080c, 0xd292, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, - 0x0006, 0x080c, 0xe7c8, 0x000e, 0x1904, 0xbc3d, 0xc0b5, 0x2012, - 0x2001, 0x0006, 0x080c, 0x665d, 0x9006, 0x080c, 0x6649, 0x00c6, - 0x2001, 0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, - 0x00e6, 0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, - 0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, - 0x780e, 0x00fe, 0x080c, 0x28d2, 0x00f6, 0x2100, 0x900e, 0x080c, - 0x2889, 0x795e, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, - 0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, - 0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, - 0x28d2, 0x00f6, 0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, - 0x080c, 0x2889, 0x795e, 0x00fe, 0x8108, 0x080c, 0x66ac, 0x2b00, - 0x00ce, 0x1904, 0xbc3d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, - 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, - 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x665d, 0x6023, - 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d, 0x080c, - 0x98e7, 0x0028, 0x080c, 0xbacb, 0x2001, 0x0001, 0x0431, 0x00de, - 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, - 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xed03, - 0x0190, 0x2071, 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, - 0x9284, 0xff00, 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, - 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, - 0x2001, 0x0007, 0x080c, 0x665d, 0x080c, 0x57e1, 0x1120, 0x2001, - 0x0007, 0x080c, 0x6689, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, - 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, - 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, - 0x080c, 0x4be3, 0x004e, 0x003e, 0x080c, 0x3274, 0x6020, 0x9086, - 0x000a, 0x1108, 0x0005, 0x0804, 0xb0e7, 0x00b6, 0x00e6, 0x0026, - 0x0016, 0x2071, 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xbdcd, - 0x080c, 0x57e1, 0x1170, 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, - 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4d9a, 0x004e, - 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x67b2, 0x080c, 0xbbf7, - 0x00de, 0x080c, 0xc023, 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, - 0x0560, 0x2001, 0x0006, 0x080c, 0x665d, 0x0096, 0x6014, 0x904d, - 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, - 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0060, 0xa864, - 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, - 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x3274, 0x6020, 0x9086, - 0x000a, 0x0140, 0x080c, 0xb0e7, 0x0028, 0x080c, 0xbacb, 0x9006, - 0x080c, 0xbd45, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, - 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, - 0x665d, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x0804, - 0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x2030, 0x2011, 0x1824, - 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, - 0x0007, 0x080c, 0x665d, 0x0804, 0xb0e7, 0x2001, 0x0001, 0x0804, - 0xbd45, 0x0002, 0xbbb4, 0xbe19, 0xbbb4, 0xbe5c, 0xbbb4, 0xbf09, - 0xbe0e, 0xbbb7, 0xbbb4, 0xbf1d, 0xbbb4, 0xbf2f, 0x6604, 0x9686, - 0x0003, 0x0904, 0xbd75, 0x96b6, 0x001e, 0x1110, 0x080c, 0xb0e7, - 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xbf41, 0x11a0, 0x9006, - 0x080c, 0x6649, 0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0002, - 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d, - 0x080c, 0x98e7, 0x0428, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, - 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, - 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, - 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, - 0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0001, 0x080c, 0xbd45, - 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, - 0x080c, 0xbf4f, 0x00d6, 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168, - 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, - 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, - 0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001, - 0x6007, 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0804, 0xbed9, - 0x080c, 0xce3f, 0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, - 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xd481, - 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, - 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, - 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, - 0xbacb, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, - 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, - 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, - 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, 0x080c, 0x665d, 0x2001, - 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, - 0xbd45, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, - 0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa864, 0x9086, 0x0139, - 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, - 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, - 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, - 0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x0010, 0x080c, 0x324b, - 0x0860, 0x2001, 0x0004, 0x080c, 0x665d, 0x080c, 0xbf4f, 0x1140, - 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x0804, 0x98e7, - 0x080c, 0xbacb, 0x9006, 0x0804, 0xbd45, 0x0489, 0x1160, 0x2001, - 0x0008, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, - 0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x00f9, - 0x1160, 0x2001, 0x000a, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, - 0x0001, 0x080c, 0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804, - 0xbd45, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, - 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, - 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, - 0x6726, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, - 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, - 0x9085, 0x0003, 0x200a, 0x080c, 0xbff5, 0x0560, 0x2009, 0x1837, - 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a88, 0x0158, 0x9006, 0x2020, - 0x2009, 0x002a, 0x080c, 0xe940, 0x2001, 0x180c, 0x200c, 0xc195, - 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, 0x3216, 0x00e6, - 0x2071, 0x1800, 0x080c, 0x3022, 0x00ee, 0x00c6, 0x0156, 0x20a9, - 0x0781, 0x2009, 0x007f, 0x080c, 0x3347, 0x8108, 0x1f04, 0xbf93, - 0x015e, 0x00ce, 0x080c, 0xbf52, 0x2071, 0x0260, 0x2079, 0x0200, - 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, - 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, - 0x0000, 0x2001, 0x1837, 0x2102, 0x2079, 0x0100, 0x2e04, 0x9084, + 0x00be, 0x9206, 0x1904, 0xb823, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x1904, 0xb823, 0x6038, 0x2068, 0x6824, + 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb823, 0x9286, + 0x0002, 0x0904, 0xb823, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, + 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, + 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, + 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, + 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, + 0x080c, 0xce56, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e, 0x080c, + 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, + 0x1989, 0x2004, 0x7042, 0x080c, 0xb101, 0x002e, 0x00de, 0x00ee, + 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, + 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, + 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, + 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0f7, 0x002e, 0x003e, + 0x015e, 0x009e, 0x1904, 0xb892, 0x0096, 0x0156, 0x0036, 0x0026, + 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, + 0xc0f7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, + 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, + 0x00fe, 0x009e, 0x00be, 0x0804, 0xb50a, 0x0096, 0x2048, 0xaa12, + 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, + 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f, + 0x0130, 0x00fe, 0x009e, 0x080c, 0xb101, 0x00be, 0x0005, 0x080c, + 0xbae2, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3246, 0x080c, 0xd576, + 0x00fe, 0x00c6, 0x080c, 0xb0ab, 0x2f00, 0x6012, 0x6017, 0x0000, + 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, + 0x080c, 0x6663, 0x080c, 0x668f, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00ce, 0x0804, 0xb865, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, + 0x91b2, 0x0040, 0x1a04, 0xb91b, 0x0002, 0xb909, 0xb909, 0xb8ff, + 0xb909, 0xb909, 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb909, 0xb909, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8ff, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909, + 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb8fd, 0x080c, 0x0dc5, 0x0066, + 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be, 0x006e, + 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, + 0x9383, 0x0010, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, + 0x98ed, 0x012e, 0x0005, 0x2600, 0x0002, 0xb909, 0xb909, 0xb92f, + 0xb909, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0xb909, 0xb92f, + 0xb909, 0xb92f, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0x080c, + 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6, 0x0013, + 0x0904, 0xba04, 0x91b6, 0x0027, 0x1904, 0xb9ae, 0x080c, 0x97e1, + 0x6004, 0x080c, 0xd04d, 0x01b0, 0x080c, 0xd05e, 0x01a8, 0x908e, + 0x0021, 0x0904, 0xb9ab, 0x908e, 0x0022, 0x1130, 0x080c, 0xb536, + 0x0904, 0xb9a7, 0x0804, 0xb9a8, 0x908e, 0x003d, 0x0904, 0xb9ab, + 0x0804, 0xb9a1, 0x080c, 0x326f, 0x2001, 0x0007, 0x080c, 0x6663, + 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbae2, 0x9186, + 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x7569, + 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, + 0x080c, 0xed0f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, + 0x2019, 0x0028, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, + 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe690, + 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd576, 0x0016, 0x080c, + 0xd2ca, 0x080c, 0xb101, 0x001e, 0x080c, 0x3342, 0x080c, 0x98ed, + 0x0030, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x080c, 0xbae2, 0x0cb0, 0x080c, 0xbb1e, 0x0c98, 0x9186, 0x0015, + 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd587, 0x0d80, 0x6000, + 0x9086, 0x0002, 0x0904, 0xbb29, 0x0c50, 0x9186, 0x0014, 0x1d38, + 0x080c, 0x97e1, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb536, + 0x09f0, 0x080c, 0x3246, 0x080c, 0xd576, 0x080c, 0xd04d, 0x1198, + 0x080c, 0x326f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, + 0xbae2, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, + 0x2102, 0x0804, 0xb9a1, 0x080c, 0xd05e, 0x1120, 0x080c, 0xbae2, + 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, + 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee, + 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, + 0x090c, 0xbae2, 0x0804, 0xb9a1, 0x90b2, 0x0040, 0x1a04, 0xbabe, + 0x2008, 0x0002, 0xba4c, 0xba4d, 0xba50, 0xba53, 0xba56, 0xba63, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba66, 0xba73, 0xba4a, 0xba75, 0xba73, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba73, 0xba73, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xbaa5, 0xba73, 0xba4a, 0xba6f, + 0xba4a, 0xba4a, 0xba4a, 0xba70, 0xba4a, 0xba4a, 0xba4a, 0xba73, + 0xba9c, 0xba4a, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b, 0x0470, + 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500, + 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x97e1, + 0x6003, 0x0005, 0x080c, 0xd579, 0x080c, 0x98ed, 0x0070, 0x0018, + 0x0010, 0x080c, 0x6663, 0x0804, 0xbab6, 0x080c, 0x97e1, 0x080c, + 0xd579, 0x6003, 0x0004, 0x080c, 0x98ed, 0x0005, 0x080c, 0x6663, + 0x080c, 0x97e1, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, + 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007, + 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, + 0x003e, 0x080c, 0x98ed, 0x0c08, 0x080c, 0x97e1, 0x080c, 0xd2ca, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x08c0, 0x00e6, 0x00f6, 0x2071, + 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee, 0x080c, + 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0838, 0x080c, 0x97e1, + 0x6003, 0x0002, 0x080c, 0xd579, 0x0804, 0x98ed, 0x2600, 0x2008, + 0x0002, 0xbad5, 0xbab6, 0xbad3, 0xbab6, 0xbab6, 0xbad3, 0xbad3, + 0xbad3, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3, + 0xbad3, 0xbad3, 0xbad3, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096, + 0x6014, 0x2048, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, + 0x98ed, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, 0xce56, + 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, + 0x9086, 0x0056, 0x1148, 0x080c, 0x556d, 0x0130, 0x2001, 0x0000, + 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, + 0x4005, 0x080c, 0xd43b, 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, + 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, + 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, + 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, + 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, + 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, + 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, + 0xd35a, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, + 0xd3a3, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, + 0xd3cf, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, + 0xd2ec, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, + 0xd09c, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, + 0xd0dd, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, + 0xb4db, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, + 0xb829, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, 0xb517, + 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb63d, 0x0470, + 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7be, 0x0438, 0x6604, + 0x96b6, 0x003d, 0x1118, 0x080c, 0xb54f, 0x0400, 0x6604, 0x96b6, + 0x0044, 0x1118, 0x080c, 0xb58b, 0x00c8, 0x6604, 0x96b6, 0x0049, + 0x1118, 0x080c, 0xb5cc, 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, + 0x080c, 0xb5b6, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, + 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe0c, 0x00be, 0x0005, + 0x080c, 0xb19b, 0x0cd8, 0xbbcb, 0xbbd9, 0xbbcb, 0xbc20, 0xbbcb, + 0xbd80, 0xbe19, 0xbbcb, 0xbbcb, 0xbde2, 0xbbcb, 0xbdf8, 0x0096, + 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, + 0x009e, 0x0804, 0xb101, 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, + 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x664f, 0x0804, 0xb101, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074, 0x1540, + 0x080c, 0xe661, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, + 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, + 0x2001, 0x0006, 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101, + 0x0098, 0x2001, 0x000a, 0x080c, 0x6663, 0x080c, 0x326f, 0x6003, + 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0020, + 0x2001, 0x0001, 0x080c, 0xbd50, 0x00ee, 0x0005, 0x00d6, 0xb800, + 0xd084, 0x0160, 0x9006, 0x080c, 0x664f, 0x2069, 0x1847, 0x6804, + 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x668f, 0x00de, 0x0005, + 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, + 0x1904, 0xbd25, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, + 0x080c, 0xbf68, 0x0804, 0xbc92, 0x080c, 0xbf5d, 0x6010, 0x2058, + 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, + 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, + 0x900e, 0x2011, 0x4000, 0x080c, 0xd43b, 0x0030, 0xa807, 0x0000, + 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x6663, + 0x080c, 0x326f, 0x080c, 0xb101, 0x0804, 0xbd2a, 0x080c, 0xbd38, + 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, + 0x2011, 0x4000, 0x080c, 0xd43b, 0x08f8, 0x080c, 0xbd2e, 0x0160, + 0x9006, 0x080c, 0x664f, 0x2001, 0x0004, 0x080c, 0x668f, 0x2001, + 0x0007, 0x080c, 0x6663, 0x08a0, 0x2001, 0x0004, 0x080c, 0x6663, + 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0804, 0xbd2a, 0xb85c, 0xd0e4, 0x0178, 0x080c, 0xd26c, 0x080c, + 0x7569, 0x0118, 0xd0dc, 0x1904, 0xbc54, 0x2011, 0x1837, 0x2204, + 0xc0ad, 0x2012, 0x0804, 0xbc54, 0x080c, 0xd2a9, 0x2011, 0x1837, + 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe82d, 0x000e, 0x1904, + 0xbc54, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x6663, 0x9006, + 0x080c, 0x664f, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, 0x0520, + 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, 0x9084, + 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff, + 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6, + 0x2100, 0x900e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x9186, 0x0081, + 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079, + 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5, + 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6, 0x2079, 0x1800, 0x7982, + 0x2100, 0x900e, 0x797e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x8108, + 0x080c, 0x66b2, 0x2b00, 0x00ce, 0x1904, 0xbc54, 0x6012, 0x2009, + 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, + 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, + 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x0028, 0x080c, 0xbae2, 0x2001, + 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, + 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, + 0x00e6, 0x080c, 0xed68, 0x0190, 0x2071, 0x0260, 0x7108, 0x720c, + 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, 0x2058, + 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, + 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x6663, 0x080c, + 0x57e7, 0x1120, 0x2001, 0x0007, 0x080c, 0x668f, 0x2600, 0x9005, + 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e, 0x080c, + 0x326f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0xb101, + 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, 0x9086, + 0x0014, 0x1904, 0xbdd8, 0x080c, 0x57e7, 0x1170, 0x6014, 0x9005, + 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, + 0x080c, 0x4da0, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, + 0x67b8, 0x080c, 0xbc0e, 0x00de, 0x080c, 0xc033, 0x1588, 0x6010, + 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x6663, + 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, + 0xd43b, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, + 0x326f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xb101, 0x0028, + 0x080c, 0xbae2, 0x9006, 0x080c, 0xbd50, 0x001e, 0x002e, 0x00ee, + 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, + 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001, 0x0804, 0xbd50, + 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, + 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x6663, 0x0804, 0xb101, + 0x2001, 0x0001, 0x0804, 0xbd50, 0x0002, 0xbbcb, 0xbe24, 0xbbcb, + 0xbe67, 0xbbcb, 0xbf14, 0xbe19, 0xbbce, 0xbbcb, 0xbf28, 0xbbcb, + 0xbf3a, 0x6604, 0x9686, 0x0003, 0x0904, 0xbd80, 0x96b6, 0x001e, + 0x1110, 0x080c, 0xb101, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, + 0xbf4c, 0x11a0, 0x9006, 0x080c, 0x664f, 0x080c, 0x3246, 0x080c, + 0xd576, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0428, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, + 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, + 0x908e, 0x1e00, 0x0990, 0x080c, 0x3246, 0x080c, 0xd576, 0x2001, + 0x0001, 0x080c, 0xbd50, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, + 0x00b6, 0x0026, 0x9016, 0x080c, 0xbf5a, 0x00d6, 0x2069, 0x197d, + 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, + 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, + 0x00de, 0x0088, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, + 0x6663, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0804, 0xbee4, 0x080c, 0xce56, 0x01b0, 0x6014, 0x2048, + 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, + 0x0002, 0x080c, 0xd498, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, + 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, + 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, + 0x9006, 0x0c38, 0x080c, 0xbae2, 0x2009, 0x026e, 0x2134, 0x96b4, + 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, + 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, + 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, + 0x080c, 0x6663, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, + 0x2001, 0x0001, 0x080c, 0xbd50, 0x002e, 0x00be, 0x009e, 0x0005, + 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xce56, 0x0140, + 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, + 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, + 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, + 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee, + 0x0010, 0x080c, 0x3246, 0x0860, 0x2001, 0x0004, 0x080c, 0x6663, + 0x080c, 0xbf5a, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x9383, 0x0804, 0x98ed, 0x080c, 0xbae2, 0x9006, 0x0804, 0xbd50, + 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x6663, 0x6003, 0x0001, + 0x6007, 0x0005, 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001, + 0x0804, 0xbd50, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x6663, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x0804, 0x98ed, + 0x2001, 0x0001, 0x0804, 0xbd50, 0x2009, 0x026e, 0x2104, 0x9086, + 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, + 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, + 0x6110, 0x2158, 0x080c, 0x672c, 0x001e, 0x00ce, 0x00be, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, + 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xc005, + 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a8e, + 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001, + 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, + 0x080c, 0x3211, 0x00e6, 0x2071, 0x1800, 0x080c, 0x3019, 0x00ee, + 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3342, + 0x8108, 0x1f04, 0xbf9e, 0x015e, 0x00ce, 0x080c, 0xbf5d, 0x2071, + 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, + 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, + 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x9184, + 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084, - 0x00ff, 0x2008, 0x080c, 0x28d2, 0x080c, 0x7563, 0x0170, 0x2071, + 0x00ff, 0x2008, 0x080c, 0x28dd, 0x080c, 0x7569, 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, - 0x680a, 0x7054, 0x680e, 0x080c, 0xd255, 0x0040, 0x2001, 0x0006, - 0x080c, 0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x001e, 0x003e, + 0x680a, 0x7054, 0x680e, 0x080c, 0xd26c, 0x0040, 0x2001, 0x0006, + 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, - 0x000a, 0x080c, 0xc0e7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, - 0x2019, 0x0006, 0x080c, 0xc0e7, 0x1100, 0x015e, 0x00ee, 0x003e, + 0x000a, 0x080c, 0xc0f7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x2019, 0x0006, 0x080c, 0xc0f7, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, @@ -5937,23 +5939,23 @@ unsigned short risc_code01[] = { 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7254, 0x7074, - 0x9202, 0x1a04, 0xc0b3, 0x080c, 0x8bbd, 0x0904, 0xc0ac, 0x080c, - 0xe971, 0x0904, 0xc0ac, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0ac, - 0x2500, 0x9c06, 0x0904, 0xc0ac, 0x2400, 0x9c06, 0x05e8, 0x3e08, + 0x9202, 0x1a04, 0xc0c3, 0x080c, 0x8bc3, 0x0904, 0xc0bc, 0x080c, + 0xe9d6, 0x0904, 0xc0bc, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0bc, + 0x2500, 0x9c06, 0x0904, 0xc0bc, 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004, - 0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd047, - 0x1130, 0x00ce, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x00e8, 0x6014, - 0x2048, 0x080c, 0xce3f, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, + 0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd05e, + 0x1130, 0x00ce, 0x080c, 0xbae2, 0x080c, 0xb134, 0x00e8, 0x6014, + 0x2048, 0x080c, 0xce56, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, - 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c, - 0xd02a, 0x080c, 0xb11a, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, - 0x1210, 0x0804, 0xc056, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, + 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x080c, 0xb134, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, + 0x1210, 0x0804, 0xc066, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, - 0x080c, 0xe8e3, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, - 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb166, 0x08e0, 0x9786, + 0x080c, 0xe948, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, + 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb180, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, - 0x8318, 0x1f04, 0xc0d3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, + 0x8318, 0x1f04, 0xc0e3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, @@ -5961,1691 +5963,1702 @@ unsigned short risc_code01[] = { 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, - 0x1f04, 0xc111, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, - 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd036, 0x0120, 0x080c, - 0xd047, 0x0168, 0x0028, 0x080c, 0x3274, 0x080c, 0xd047, 0x0138, - 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c, - 0xbacb, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, - 0x000a, 0x0005, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, - 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc158, 0xc158, 0xc158, - 0xc158, 0xc156, 0xc156, 0xc156, 0xc158, 0xc156, 0x080c, 0x0dc5, - 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126, - 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x9186, 0x0013, - 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc1f0, 0x9186, 0x0027, - 0x1520, 0x080c, 0x97db, 0x080c, 0x324b, 0x080c, 0xd55d, 0x0096, - 0x6114, 0x2148, 0x080c, 0xce3f, 0x0198, 0x080c, 0xd047, 0x1118, - 0x080c, 0xbacb, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, - 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dcb, 0x080c, 0xd02a, - 0x009e, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9186, 0x0014, 0x1120, + 0x1f04, 0xc121, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, + 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd04d, 0x0120, 0x080c, + 0xd05e, 0x0168, 0x0028, 0x080c, 0x326f, 0x080c, 0xd05e, 0x0138, + 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xbae2, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, + 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc168, 0xc168, 0xc168, + 0xc168, 0xc166, 0xc166, 0xc166, 0xc168, 0xc166, 0x080c, 0x0dc5, + 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x9186, 0x0013, + 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc200, 0x9186, 0x0027, + 0x1520, 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096, + 0x6114, 0x2148, 0x080c, 0xce56, 0x0198, 0x080c, 0xd05e, 0x1118, + 0x080c, 0xbae2, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dd1, 0x080c, 0xd041, + 0x009e, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, - 0x0dc5, 0x080c, 0xd56e, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, - 0x0804, 0xc22e, 0x0005, 0x0002, 0xc1ca, 0xc1c8, 0xc1c8, 0xc1c8, - 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1e5, - 0xc1e5, 0xc1e5, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8, - 0x080c, 0x0dc5, 0x080c, 0x97db, 0x0096, 0x6114, 0x2148, 0x080c, - 0xce3f, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, - 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dcb, 0x080c, 0xd02a, 0x009e, - 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c, 0x97db, 0x080c, - 0xd047, 0x090c, 0xbacb, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, - 0x0002, 0xc207, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, - 0xc205, 0xc205, 0xc205, 0xc205, 0xc21e, 0xc21e, 0xc21e, 0xc21e, - 0xc205, 0xc228, 0xc205, 0xc21e, 0xc205, 0x080c, 0x0dc5, 0x0096, - 0x080c, 0x97db, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042, + 0x0dc5, 0x080c, 0xd587, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, + 0x0804, 0xc23e, 0x0005, 0x0002, 0xc1da, 0xc1d8, 0xc1d8, 0xc1d8, + 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1f5, + 0xc1f5, 0xc1f5, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8, + 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce56, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x080c, + 0xd05e, 0x090c, 0xbae2, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x0002, 0xc217, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, + 0xc215, 0xc215, 0xc215, 0xc215, 0xc22e, 0xc22e, 0xc22e, 0xc22e, + 0xc215, 0xc238, 0xc215, 0xc22e, 0xc215, 0x080c, 0x0dc5, 0x0096, + 0x080c, 0x97e1, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, - 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97db, - 0x080c, 0xd560, 0x080c, 0xd565, 0x6003, 0x000f, 0x0804, 0x98e7, - 0x080c, 0x97db, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9182, 0x0054, - 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc24a, 0xc24a, - 0xc24a, 0xc24a, 0xc24a, 0xc24c, 0xc329, 0xc24a, 0xc35d, 0xc24a, - 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, - 0xc24a, 0xc35d, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148, + 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97e1, + 0x080c, 0xd579, 0x080c, 0xd57e, 0x6003, 0x000f, 0x0804, 0x98ed, + 0x080c, 0x97e1, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9182, 0x0054, + 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc25a, 0xc25a, + 0xc25a, 0xc25a, 0xc25a, 0xc25c, 0xc33c, 0xc25a, 0xc370, 0xc25a, + 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, + 0xc25a, 0xc370, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, - 0xd0bc, 0x1904, 0xc318, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, - 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6, - 0x080c, 0x6be5, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, - 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc2fc, 0x080c, 0xb0e7, 0x009e, + 0xd0bc, 0x1904, 0xc32b, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, + 0x080c, 0x6beb, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc30c, 0x080c, 0xb101, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, - 0xd0bc, 0x1904, 0xc300, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0xd0bc, 0x1904, 0xc310, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, - 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc253, 0x735c, 0xab86, + 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc263, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, - 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e, - 0xd6cc, 0x0904, 0xc268, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc268, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e, + 0xd6cc, 0x0904, 0xc278, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc278, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, - 0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd4ed, - 0x0804, 0xc268, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, - 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc98f, 0x00ae, 0x080c, 0xd4ed, - 0x080c, 0xc9e0, 0x0804, 0xc26a, 0x080c, 0xd13f, 0x0804, 0xc277, - 0xa87c, 0xd0ac, 0x0904, 0xc283, 0xa880, 0xd0bc, 0x1904, 0xc283, - 0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, - 0xc283, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc283, 0x0068, - 0xa87c, 0xd0ac, 0x0904, 0xc25b, 0xa838, 0xa934, 0x9105, 0x0904, - 0xc25b, 0xa880, 0xd0bc, 0x1904, 0xc25b, 0x080c, 0xd179, 0x0804, - 0xc277, 0x0096, 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, - 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, - 0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, - 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, - 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, - 0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, 0x080c, 0x1c01, 0x080c, - 0x939a, 0x080c, 0x9a09, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, - 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc37a, 0xc37a, - 0xc37a, 0xc37a, 0xc37a, 0xc37c, 0xc412, 0xc37a, 0xc37a, 0xc429, - 0xc4b9, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 0xc4ce, 0xc37a, 0xc37a, - 0xc37a, 0xc37a, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, - 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, - 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, - 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc40d, 0x9694, - 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, - 0x9284, 0x0300, 0x0904, 0xc40d, 0x080c, 0x100e, 0x090c, 0x0dc5, - 0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, - 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, + 0x080c, 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd504, + 0x0804, 0xc278, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, + 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc9a2, 0x00ae, 0x080c, 0xd504, + 0x080c, 0xc9f3, 0x0804, 0xc27a, 0x080c, 0xd156, 0x0804, 0xc287, + 0xa87c, 0xd0ac, 0x0904, 0xc293, 0xa880, 0xd0bc, 0x1904, 0xc293, + 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc293, + 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e, + 0x0904, 0xc293, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc26b, 0xa838, + 0xa934, 0x9105, 0x0904, 0xc26b, 0xa880, 0xd0bc, 0x1904, 0xc26b, + 0x080c, 0xd190, 0x0804, 0xc287, 0x0096, 0x00f6, 0x6003, 0x0003, + 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, + 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, + 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, + 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, + 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, + 0x080c, 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x009e, 0x0005, + 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, + 0x0005, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38f, 0xc425, + 0xc38d, 0xc38d, 0xc43c, 0xc4cc, 0xc38d, 0xc38d, 0xc38d, 0xc38d, + 0xc4e1, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0x080c, 0x0dc5, 0x0076, + 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, + 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, + 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, + 0x0904, 0xc420, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, + 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc420, 0x080c, + 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, + 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, + 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, + 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, + 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, + 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, + 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, + 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, + 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, + 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, + 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, + 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, + 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2, + 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, + 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, + 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, + 0x080c, 0x1c09, 0x0804, 0xa4e4, 0x6003, 0x0002, 0x6004, 0x9086, + 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, + 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768, + 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, 0x009e, 0x080c, + 0x97e1, 0x080c, 0x98ed, 0x0096, 0x2001, 0x1989, 0x2004, 0x6042, + 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa97c, 0xd1e4, + 0x0904, 0xc4c7, 0xd1cc, 0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, + 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, 0x9184, 0x003f, + 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, + 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, + 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458, + 0x0016, 0x080c, 0x0fc0, 0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, + 0x0016, 0x080c, 0xc9f3, 0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, + 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, 0x0028, 0x1118, + 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, + 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, + 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb101, 0x009e, + 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, + 0x080c, 0x97e1, 0x080c, 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877, + 0x6003, 0x0002, 0x080c, 0xd57e, 0x080c, 0x989d, 0x080c, 0x9a0f, + 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97e1, 0x080c, + 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877, 0x080c, 0x989d, 0x080c, + 0x3246, 0x080c, 0xd576, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, + 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, + 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f, + 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, + 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e, + 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, + 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53e, 0xc53c, 0xc53c, + 0xc5e4, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, + 0xc53c, 0xc53c, 0xc53c, 0xc716, 0x080c, 0x0dc5, 0x0076, 0x00a6, + 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, + 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, + 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, + 0xc5dd, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, + 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc5dd, 0x9686, 0x0100, + 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, + 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, + 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, + 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, - 0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8, + 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, - 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205, + 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, - 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc98f, 0x009e, 0x00ee, 0x00ae, - 0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, - 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, - 0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1c01, 0x0804, - 0xa4ca, 0x6003, 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, - 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, - 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768, 0x00fe, 0x6003, 0x0004, - 0x0010, 0x6003, 0x0002, 0x009e, 0x080c, 0x97db, 0x080c, 0x98e7, - 0x0096, 0x2001, 0x1989, 0x2004, 0x6042, 0x080c, 0x9897, 0x080c, - 0x9a09, 0x6114, 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xc4b4, 0xd1cc, - 0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, - 0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, - 0x810e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, - 0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, - 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, - 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458, 0x0016, 0x080c, 0x0fc0, - 0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xc9e0, - 0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, - 0x0002, 0x0180, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, - 0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, - 0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, 0x080c, 0x6be5, 0x001e, - 0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0xd13f, - 0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97db, 0x080c, - 0x98e7, 0x2019, 0x0001, 0x080c, 0xa85d, 0x6003, 0x0002, 0x080c, - 0xd565, 0x080c, 0x9897, 0x080c, 0x9a09, 0x0005, 0x6004, 0x9086, - 0x0040, 0x1120, 0x080c, 0x97db, 0x080c, 0x98e7, 0x2019, 0x0001, - 0x080c, 0xa85d, 0x080c, 0x9897, 0x080c, 0x324b, 0x080c, 0xd55d, - 0x0096, 0x6114, 0x2148, 0x080c, 0xce3f, 0x0150, 0xa867, 0x0103, - 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a, - 0x009e, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0xa87b, 0x0015, - 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, - 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a, - 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, - 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc529, 0xc529, 0xc529, - 0xc529, 0xc529, 0xc52b, 0xc529, 0xc529, 0xc5d1, 0xc529, 0xc529, - 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, - 0xc703, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, - 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, - 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, - 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc5ca, 0x9694, 0xff00, - 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, - 0x0300, 0x0904, 0xc5ca, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, - 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x100e, 0x090c, 0x0dc5, - 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, - 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, - 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, - 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, - 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, - 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, - 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, - 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, - 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, - 0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, - 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, - 0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, - 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, - 0x080c, 0xc98f, 0x080c, 0x1a83, 0x009e, 0x00ee, 0x00ae, 0x007e, - 0x0005, 0x2001, 0x1989, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, - 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, - 0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc6fe, 0x6043, 0x0000, 0x6010, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, - 0xc6cd, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc68e, 0x0016, 0xa87c, - 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, - 0x90b6, 0x0002, 0x0904, 0xc65b, 0x9086, 0x0028, 0x1904, 0xc647, - 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xc663, 0x6024, 0xd0f4, - 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, - 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, - 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, - 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, - 0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, - 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, - 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd179, 0x0804, 0xc6fe, 0xd1dc, - 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118, - 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, - 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xc4f6, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, - 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, - 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, - 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, - 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd4ed, 0x001e, 0xa874, 0x0006, - 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804, 0xc6fa, 0x0016, 0x00a6, - 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, - 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, - 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118, - 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, - 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xc4f6, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, - 0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd4ed, 0xa974, - 0x0016, 0x080c, 0xc9e0, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, - 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, - 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, - 0xd40d, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, - 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, - 0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6, 0xa974, 0x0016, 0x080c, - 0x6be5, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005, - 0x080c, 0xd13f, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, - 0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c, 0x97db, 0x0010, 0x080c, - 0x9897, 0x080c, 0xce3f, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, - 0xd047, 0x1118, 0x080c, 0xbacb, 0x00a0, 0xa867, 0x0103, 0x2009, - 0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, - 0x918e, 0x0029, 0x1110, 0x080c, 0xec9b, 0xa877, 0x0000, 0x080c, - 0x6dcb, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0804, 0x9a09, - 0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, - 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc75a, 0xc75a, - 0xc75a, 0xc75a, 0xc75a, 0xc75c, 0xc75a, 0xc75a, 0xc75a, 0xc75a, - 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, - 0xc75a, 0xc75a, 0x080c, 0x0dc5, 0x080c, 0x57d5, 0x01f8, 0x6014, - 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, - 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, - 0x0139, 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, - 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7, - 0x9182, 0x0085, 0x0002, 0xc792, 0xc790, 0xc790, 0xc79e, 0xc790, - 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, - 0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126, - 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x0026, 0x0056, - 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, - 0xce2d, 0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, - 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xca51, - 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xca1b, - 0x0010, 0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xca3d, - 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, - 0x98e7, 0x7220, 0x080c, 0xce2d, 0x0178, 0x6810, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, - 0x2d60, 0x080c, 0xd179, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, - 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, - 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082, 0x0085, 0x00e2, - 0x9186, 0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x080c, - 0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa867, - 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, - 0x080c, 0xb11a, 0x0804, 0x98e7, 0xc821, 0xc823, 0xc823, 0xc821, - 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, - 0xc821, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, - 0x98e7, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, - 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, 0x080c, 0x97db, 0x080c, - 0x324b, 0x080c, 0xd55d, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, - 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, - 0x6dcb, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7, - 0x0005, 0x080c, 0xb181, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, - 0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0d60, 0xa867, - 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, - 0x08f0, 0x0002, 0xc879, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, - 0xc891, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0x080c, - 0x0dc5, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, - 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x98e7, - 0x0005, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, - 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x98e7, - 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, - 0x0804, 0xb181, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8c1, 0xc90e, - 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0x080c, - 0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, - 0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xc922, 0x080c, 0xce3f, - 0x1118, 0x080c, 0xd02a, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, - 0x1110, 0x080c, 0xd02a, 0xa867, 0x0103, 0x080c, 0xd528, 0x080c, - 0x6dcb, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01d0, 0x6003, 0x0001, - 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, - 0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd2bb, - 0x6954, 0x6156, 0x6023, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x2d60, 0x00de, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, - 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, - 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd4c0, 0x11f0, 0x080c, - 0xb091, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, - 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, - 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, - 0xd2bb, 0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x00de, 0x0804, - 0xb0e7, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01c8, 0xa867, - 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, + 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2, 0x080c, 0x1a83, 0x009e, + 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1989, 0x2004, 0x6042, + 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, + 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc711, + 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x1500, 0xd1cc, 0x0904, 0xc6e0, 0xa978, 0xa868, 0xd0fc, 0x0904, + 0xc6a1, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, + 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xc66e, 0x9086, + 0x0028, 0x1904, 0xc65a, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, + 0xc676, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, + 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, + 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, + 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, + 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, + 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, + 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd190, + 0x0804, 0xc711, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, + 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, + 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa87c, 0xb07e, + 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, + 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, + 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd504, + 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804, + 0xc70d, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, + 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, + 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa890, 0xb092, + 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e, + 0x080c, 0xd504, 0xa974, 0x0016, 0x080c, 0xc9f3, 0x001e, 0x0468, + 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, + 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, + 0xa87b, 0x0015, 0x080c, 0xd424, 0x0118, 0xa974, 0xc1dc, 0xa976, + 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, + 0xa974, 0x0016, 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c, + 0xb101, 0x009e, 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6114, 0x0096, + 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c, + 0x97e1, 0x0010, 0x080c, 0x989d, 0x080c, 0xce56, 0x01f0, 0x0096, + 0x6114, 0x2148, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x00a0, + 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, + 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, 0x080c, 0xed00, + 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, + 0x98ed, 0x0804, 0x9a0f, 0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, + 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, + 0x0005, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76f, 0xc76d, + 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, + 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0x080c, 0x0dc5, 0x080c, + 0x57db, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, + 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, + 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, 0x0103, 0xa976, + 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dd1, + 0x009e, 0x0804, 0xb101, 0x9182, 0x0085, 0x0002, 0xc7a5, 0xc7a3, + 0xc7a3, 0xc7b1, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, + 0xc7a3, 0xc7a3, 0xc7a3, 0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106, + 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, + 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, + 0x6216, 0x7220, 0x080c, 0xce44, 0x01f8, 0x2268, 0x6800, 0x9086, + 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, + 0x00d6, 0x080c, 0xca64, 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, + 0x1118, 0x080c, 0xca2e, 0x0010, 0x6803, 0x0002, 0x6007, 0x0086, + 0x0028, 0x080c, 0xca50, 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, + 0x080c, 0x933b, 0x080c, 0x98ed, 0x7220, 0x080c, 0xce44, 0x0178, + 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, + 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd190, 0x00ce, 0x00ee, + 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, + 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, + 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, 0x0014, + 0x190c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, + 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb134, 0x0804, 0x98ed, 0xc834, + 0xc836, 0xc836, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834, + 0xc834, 0xc834, 0xc834, 0xc834, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0x9186, 0x0013, 0x1128, + 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, + 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096, 0x6014, + 0x2048, 0x080c, 0xce56, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c, + 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0xb19b, 0x0ce0, 0x9186, + 0x0014, 0x1dd0, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, + 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xc88c, 0xc88a, 0xc88a, + 0xc88a, 0xc88a, 0xc88a, 0xc8a4, 0xc88a, 0xc88a, 0xc88a, 0xc88a, + 0xc88a, 0xc88a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x000c, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x000e, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, + 0x0085, 0x0208, 0x0012, 0x0804, 0xb19b, 0xc8d2, 0xc8d2, 0xc8d2, + 0xc8d2, 0xc8d4, 0xc921, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2, + 0xc8d2, 0xc8d2, 0x080c, 0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e, 0x0804, + 0xc935, 0x080c, 0xce56, 0x1118, 0x080c, 0xd041, 0x0068, 0x6014, + 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xd041, 0xa867, 0x0103, + 0x080c, 0xd541, 0x080c, 0x6dd1, 0x00d6, 0x2c68, 0x080c, 0xb0ab, + 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, + 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x6910, + 0x6112, 0x080c, 0xd2d2, 0x6954, 0x6156, 0x6023, 0x0001, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x2d60, 0x00de, 0x080c, 0xb101, 0x009e, + 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, + 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, + 0xd4d7, 0x11f0, 0x080c, 0xb0ab, 0x01d8, 0x6106, 0x6003, 0x0001, + 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, + 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, + 0x6954, 0x6156, 0x080c, 0xd2d2, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x2d60, 0x00de, 0x0804, 0xb101, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, + 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, + 0x0020, 0xa87b, 0x0005, 0x080c, 0xd152, 0xa877, 0x0000, 0x080c, + 0x6dd1, 0x080c, 0xd041, 0x009e, 0x0804, 0xb101, 0x0016, 0x0096, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0140, 0xa867, 0x0103, 0xa87b, + 0x0028, 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x001e, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, + 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, + 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xca03, + 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, + 0x100e, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, + 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, + 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, + 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, + 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, + 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, + 0x0130, 0xa807, 0x0000, 0x080c, 0x6dd1, 0x2a48, 0x0cb8, 0x080c, + 0x6dd1, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, + 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, + 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, + 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, + 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, + 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, + 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, + 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xce56, 0x0150, 0x2001, + 0x0006, 0xa980, 0xc1d5, 0x080c, 0x703d, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x009e, 0x080c, 0xb134, 0x00ee, 0x00de, 0x00ce, 0x0005, + 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, + 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, + 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, + 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, + 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xca9f, 0xca9f, + 0xca9a, 0xcac1, 0xca8d, 0xca9a, 0xcac1, 0xca9a, 0xca9a, 0x911f, + 0xca9a, 0xca9a, 0xca9a, 0xca8d, 0xca8d, 0x080c, 0x0dc5, 0x0036, + 0x2019, 0x0010, 0x080c, 0xe4c8, 0x6023, 0x0006, 0x6003, 0x0007, + 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, + 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xce56, 0x01c0, 0xa864, + 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, + 0x900e, 0x2001, 0x0005, 0x080c, 0x703d, 0x080c, 0xd152, 0x080c, + 0x6dc4, 0x080c, 0xb134, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, + 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcad7, + 0xcb07, 0xcad9, 0xcb28, 0xcb02, 0xcad7, 0xca9a, 0xca9f, 0xca9f, + 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0x080c, + 0x0dc5, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0168, 0xa87c, 0xd0cc, 0x0140, + 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, + 0x080c, 0xd152, 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003, + 0x000b, 0x6023, 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x9085, + 0x0001, 0x0005, 0x0066, 0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6, + 0x2071, 0x19e9, 0x7024, 0x9c06, 0x1120, 0x080c, 0xa801, 0x00ee, + 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, + 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0xa929, 0x009e, 0x008e, + 0x0010, 0x080c, 0xa6fe, 0x00ee, 0x1904, 0xcad9, 0x0804, 0xca9a, + 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e, + 0x080c, 0xa877, 0x00ee, 0x003e, 0x0804, 0xcad9, 0x080c, 0xaa59, + 0x00ee, 0x003e, 0x1904, 0xcad9, 0x0804, 0xca9a, 0x00c6, 0x6020, + 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xcb5b, 0xcc25, 0xcd8f, + 0xcb65, 0xb134, 0xcb5b, 0xe4ba, 0xd583, 0xcc25, 0x90f1, 0xce1b, + 0xcb54, 0xcb54, 0xcb54, 0xcb54, 0x080c, 0x0dc5, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x0005, 0x080c, 0x97e1, 0x080c, 0x98ed, + 0x0804, 0xb101, 0x601b, 0x0001, 0x0005, 0x080c, 0xce56, 0x0130, + 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, + 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcb84, 0xcb86, 0xcbaa, 0xcbbe, + 0xcbe4, 0xcb84, 0xcb5b, 0xcb5b, 0xcb5b, 0xcbbe, 0xcbbe, 0xcb84, + 0xcb84, 0xcb84, 0xcb84, 0xcbc8, 0x080c, 0x0dc5, 0x00e6, 0x6014, + 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, + 0x7024, 0x9c06, 0x01a0, 0x080c, 0xa6fe, 0x080c, 0xd51b, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, + 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0005, 0x601b, + 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, + 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x0096, 0x601b, + 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, + 0x080c, 0x57db, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, + 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, + 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, + 0x6dd1, 0x009e, 0x0804, 0xb101, 0x6014, 0x0096, 0x904d, 0x05c0, + 0xa97c, 0xd1e4, 0x05a8, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, + 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, + 0x611a, 0x2001, 0x0030, 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, + 0x2004, 0x9086, 0x0041, 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, + 0x0dc5, 0xa880, 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, + 0x0002, 0x0068, 0x009e, 0x00c6, 0x080c, 0x2397, 0x00ce, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005, + 0x009e, 0x080c, 0x1ab7, 0x0804, 0xcbaa, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0xcc3c, 0xcb62, 0xcc3e, 0xcc3c, + 0xcc3e, 0xcc3e, 0xcb5c, 0xcc3c, 0xcb56, 0xcb56, 0xcc3c, 0xcc3c, + 0xcc3c, 0xcc3c, 0xcc3c, 0xcc3c, 0x080c, 0x0dc5, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, + 0x0dc5, 0x00b6, 0x0013, 0x00be, 0x0005, 0xcc59, 0xcd26, 0xcc5b, + 0xcc9b, 0xcc5b, 0xcc9b, 0xcc5b, 0xcc69, 0xcc59, 0xcc9b, 0xcc59, + 0xcc8a, 0x080c, 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, + 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, + 0xcd22, 0x6004, 0x080c, 0xd05e, 0x0904, 0xcd3f, 0x908e, 0x0004, + 0x1110, 0x080c, 0x326f, 0x908e, 0x0021, 0x0904, 0xcd43, 0x908e, + 0x0022, 0x0904, 0xcd8a, 0x908e, 0x003d, 0x0904, 0xcd43, 0x908e, + 0x0039, 0x0904, 0xcd47, 0x908e, 0x0035, 0x0904, 0xcd47, 0x908e, + 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3246, 0x080c, + 0xbae2, 0x0804, 0xb134, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, + 0x0904, 0xcd13, 0x9186, 0x0002, 0x1904, 0xcce8, 0x2001, 0x1837, + 0x2004, 0xd08c, 0x11c8, 0x080c, 0x7569, 0x11b0, 0x080c, 0xd561, + 0x0138, 0x080c, 0x758c, 0x1120, 0x080c, 0x7473, 0x0804, 0xcd73, + 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, + 0x080c, 0x7495, 0x0804, 0xcd73, 0x6010, 0x2058, 0x2001, 0x1837, + 0x2004, 0xd0ac, 0x1904, 0xcd73, 0xb8a0, 0x9084, 0xff80, 0x1904, + 0xcd73, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, + 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, + 0x080c, 0xb0ab, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, + 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, + 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085, + 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee, 0x080c, + 0xbae2, 0x0030, 0x080c, 0xbae2, 0x080c, 0x3246, 0x080c, 0xd576, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x012e, 0x00ee, + 0x080c, 0xb134, 0x0005, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de, + 0x00ce, 0x0c80, 0x080c, 0x326f, 0x0804, 0xcc97, 0x00c6, 0x00d6, + 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0904, 0xcce8, 0x8001, 0xb842, 0x6003, 0x0001, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de, 0x00ce, 0x0898, 0x080c, + 0xbae2, 0x0804, 0xcc99, 0x080c, 0xbb1e, 0x0804, 0xcc99, 0x00d6, + 0x2c68, 0x6104, 0x080c, 0xd4d7, 0x00de, 0x0118, 0x080c, 0xb101, + 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, + 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, + 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, + 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x00de, 0x00ce, 0x080c, 0xbae2, 0x080c, + 0x3246, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x6017, + 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, + 0x00ee, 0x0005, 0x080c, 0xb536, 0x1904, 0xcd3f, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de, + 0x009e, 0x0005, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, + 0xcdaa, 0xcdaa, 0xcdaa, 0xcb5b, 0xcdaa, 0xcb62, 0xcdac, 0xcb62, + 0xcdc6, 0xcdaa, 0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, + 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, + 0x000d, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x080c, 0xd555, + 0x0118, 0x080c, 0xd568, 0x0010, 0x080c, 0xd576, 0x080c, 0xd041, + 0x080c, 0xce56, 0x0570, 0x080c, 0x3246, 0x080c, 0xce56, 0x0168, + 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6dd1, 0x2c68, 0x080c, 0xb0ab, + 0x0150, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x00c6, 0x2d60, 0x080c, + 0xb134, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00c8, 0x080c, 0xd555, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, + 0x080c, 0x3246, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, + 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3246, 0x0868, + 0x080c, 0xb134, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, + 0x0002, 0xce31, 0xce31, 0xce35, 0xce33, 0xce3f, 0xce31, 0xce31, + 0xb134, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, + 0xce31, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x0096, 0x2148, + 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x0804, 0xb101, 0x601c, + 0xd084, 0x190c, 0x1ab7, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282, + 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, + 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, + 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, + 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, + 0x080c, 0xd561, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, + 0x0004, 0x1148, 0x080c, 0x3246, 0x080c, 0xd576, 0x00c6, 0x080c, + 0xb134, 0x00ce, 0x0060, 0x080c, 0xd24c, 0x0148, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x00c6, 0x080c, 0xb101, 0x00ce, 0x9ce0, + 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, + 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c, 0x3246, + 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x01b0, 0x6656, + 0x2b00, 0x6012, 0x080c, 0x57db, 0x0118, 0x080c, 0xcf85, 0x0168, + 0x080c, 0xd2d2, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xb180, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb153, 0x0560, 0x6057, + 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x0016, + 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08, 0x080c, + 0xe690, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb101, 0x9085, + 0x0001, 0x0070, 0x080c, 0x57db, 0x0128, 0xd18c, 0x1170, 0x080c, + 0xcf85, 0x0148, 0x2009, 0x004c, 0x080c, 0xb180, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, + 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, + 0x0016, 0x080c, 0xb0ab, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf97, 0x001e, + 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x1981, + 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb101, 0x00d0, 0x2001, + 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0088, + 0x2f60, 0x080c, 0x57db, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, + 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb180, 0x9085, + 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, + 0x0046, 0x080c, 0xb0ab, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, + 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0060, + 0x2f60, 0x080c, 0x57db, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, + 0x2009, 0x0052, 0x080c, 0xb180, 0x9085, 0x0001, 0x004e, 0x00ce, + 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x4b89, + 0x00ce, 0x1120, 0x080c, 0xb101, 0x9006, 0x0005, 0xa867, 0x0000, + 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, + 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x6851, 0x0158, 0x2001, + 0xcf9c, 0x0006, 0x900e, 0x2400, 0x080c, 0x703d, 0x080c, 0x6dd1, + 0x000e, 0x0807, 0x2418, 0x080c, 0x977b, 0xbaa0, 0x0086, 0x2041, + 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f8, 0x008e, 0x080c, + 0x93b3, 0x2f08, 0x2648, 0x080c, 0xe690, 0xb93c, 0x81ff, 0x090c, + 0x95cb, 0x080c, 0x98ed, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x0190, 0x660a, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, + 0x001f, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, + 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0008, + 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x2009, + 0x0021, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, + 0x8000, 0x080c, 0xb0ab, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, + 0xb180, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x0000, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, + 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, + 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, + 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, + 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, + 0xce56, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, + 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, + 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0198, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, + 0x3246, 0x2009, 0x0028, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, + 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbd38, + 0x00be, 0x080c, 0xbf5d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, + 0x9383, 0x080c, 0x98ed, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, + 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd498, 0x080c, + 0xbae2, 0x080c, 0xb101, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, + 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x009e, 0x080c, 0xb101, 0x0c30, 0x0096, 0x9186, 0x0016, + 0x1128, 0x2001, 0x0004, 0x080c, 0x6663, 0x00e8, 0x9186, 0x0015, + 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, + 0x00b6, 0x2058, 0x080c, 0x67b8, 0x00be, 0x080c, 0xc033, 0x1198, + 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, + 0x0006, 0x080c, 0x6663, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, + 0x080c, 0xb50a, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, + 0x080c, 0xbae2, 0x080c, 0xb101, 0x009e, 0x0005, 0x6014, 0x6310, + 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6dd1, 0x012e, 0x080c, 0xb101, 0x08f8, 0x6014, 0x904d, 0x090c, + 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x080c, 0xb101, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, + 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, + 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, + 0x0005, 0xcb5b, 0xd182, 0xd182, 0xd185, 0xe9f4, 0xea0f, 0xea12, + 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, + 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, + 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, + 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xb0ab, + 0x0508, 0x7810, 0x6012, 0x080c, 0xd2d2, 0x7820, 0x9086, 0x0003, + 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, + 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, + 0x0001, 0x7954, 0x6156, 0x080c, 0x933b, 0x080c, 0x98ed, 0x2f60, + 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x6042, + 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, + 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, + 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, + 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, + 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, + 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, + 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, + 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, + 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, + 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, + 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, + 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, + 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, + 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, + 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, + 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, + 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, + 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, + 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, + 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, + 0x080c, 0x91b1, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d, + 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91b1, 0x2001, 0x1988, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288, + 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, + 0x1611, 0x080c, 0x6a73, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028, + 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001, + 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee, 0x001e, + 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1040, + 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, + 0xb0ab, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, + 0x6016, 0x2009, 0x0033, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, + 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, + 0x1160, 0x2c78, 0x080c, 0x9b88, 0x01d8, 0x707c, 0xaa50, 0x9206, + 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x900e, 0x080c, 0x328f, 0x080c, 0xb50a, 0x0020, + 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005, + 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xb0ab, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd2d2, + 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xb180, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb0ab, 0x0180, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, + 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, + 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, + 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, + 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, + 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x080c, 0xdbac, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, + 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbae2, 0x080c, + 0xb101, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x9b88, 0x01a8, 0x707c, 0xaa74, 0x9206, + 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3246, 0x080c, + 0xb50a, 0x0020, 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee, + 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, + 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b88, + 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, + 0x1160, 0x080c, 0x3246, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, + 0xc0fd, 0x080c, 0x5782, 0x001e, 0x0010, 0x080c, 0x556d, 0x080c, + 0xce56, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x0080, 0x080c, 0xce56, 0x01b8, 0x6014, 0x2048, 0x080c, 0x556d, + 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6dd1, + 0x012e, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, + 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, + 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, + 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, + 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xce56, + 0x0904, 0xd494, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, + 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, + 0xd0f4, 0x1140, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c, 0x9080, + 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b, + 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, + 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, + 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, + 0x6dc4, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, + 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, + 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, + 0x9084, 0x00ff, 0x900e, 0x080c, 0x2894, 0x2118, 0x831f, 0x939c, + 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, + 0x080c, 0x4be9, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, + 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, + 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, + 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, + 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, + 0x080c, 0xce44, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, + 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, + 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, + 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, + 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c, + 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e, + 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xc509, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, + 0x901e, 0x0499, 0x01e0, 0x080c, 0xce56, 0x01c8, 0x080c, 0xd041, + 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, + 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0040, 0xa867, 0x0103, + 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dd1, 0x009e, 0x003e, + 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, - 0x080c, 0xd13b, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a, - 0x009e, 0x0804, 0xb0e7, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, - 0xce3f, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, - 0x080c, 0x6dcb, 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, - 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb181, 0x0030, - 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x0056, - 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, - 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, - 0x0020, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x96b2, 0x0020, 0xb004, - 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x0520, 0x8528, - 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, - 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, - 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, - 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, - 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, - 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, - 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, - 0x080c, 0x6dcb, 0x2a48, 0x0cb8, 0x080c, 0x6dcb, 0x00ae, 0x0005, - 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, - 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, - 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, - 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, - 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, - 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, - 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, - 0x2048, 0x080c, 0xce3f, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, - 0x080c, 0x7037, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x009e, 0x080c, - 0xb11a, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, - 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, - 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, - 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, - 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, - 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, - 0x006e, 0x012e, 0x0005, 0xca8c, 0xca8c, 0xca87, 0xcaae, 0xca7a, - 0xca87, 0xcaae, 0xca87, 0xca7a, 0x9119, 0xca87, 0xca87, 0xca87, - 0xca7a, 0xca7a, 0x080c, 0x0dc5, 0x0036, 0x2019, 0x0010, 0x080c, - 0xe4ba, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, - 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, - 0x2048, 0x080c, 0xce3f, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, - 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, - 0x080c, 0x7037, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x080c, 0xb11a, - 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, - 0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xcac4, 0xcaf4, 0xcac6, 0xcb15, - 0xcaef, 0xcac4, 0xca87, 0xca8c, 0xca8c, 0xca87, 0xca87, 0xca87, - 0xca87, 0xca87, 0xca87, 0xca87, 0x080c, 0x0dc5, 0x86ff, 0x1520, - 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, - 0xce3f, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, - 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd13b, 0x009e, - 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x9085, 0x0001, 0x0005, 0x0066, - 0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7024, - 0x9c06, 0x1120, 0x080c, 0xa7e7, 0x00ee, 0x0840, 0x6020, 0x9084, - 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, - 0x2c40, 0x080c, 0xa90f, 0x009e, 0x008e, 0x0010, 0x080c, 0xa6e4, - 0x00ee, 0x1904, 0xcac6, 0x0804, 0xca87, 0x0036, 0x00e6, 0x2071, - 0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xa85d, 0x00ee, - 0x003e, 0x0804, 0xcac6, 0x080c, 0xaa3f, 0x00ee, 0x003e, 0x1904, - 0xcac6, 0x0804, 0xca87, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, - 0x00ce, 0x0005, 0xcb48, 0xcc13, 0xcd7d, 0xcb52, 0xb11a, 0xcb48, - 0xe4ac, 0xd56a, 0xcc13, 0x90eb, 0xce09, 0xcb41, 0xcb41, 0xcb41, - 0xcb41, 0x080c, 0x0dc5, 0x080c, 0xd047, 0x1110, 0x080c, 0xbacb, - 0x0005, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0804, 0xb0e7, 0x601b, - 0x0001, 0x0005, 0x080c, 0xce3f, 0x0130, 0x6014, 0x0096, 0x2048, - 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, - 0x0002, 0xcb71, 0xcb73, 0xcb97, 0xcbab, 0xcbd1, 0xcb71, 0xcb48, - 0xcb48, 0xcb48, 0xcbab, 0xcbab, 0xcb71, 0xcb71, 0xcb71, 0xcb71, - 0xcbb5, 0x080c, 0x0dc5, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, - 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, 0x7024, 0x9c06, 0x01a0, - 0x080c, 0xa6e4, 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, - 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, - 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xd502, - 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, - 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x57d5, 0x01b8, - 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, - 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, - 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6dcb, 0x009e, 0x0804, - 0xb0e7, 0x6014, 0x0096, 0x904d, 0x05c8, 0xa97c, 0xd1e4, 0x05b0, - 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, - 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030, - 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041, - 0x11a0, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa880, 0xd0f4, - 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0070, 0x009e, - 0x2001, 0x0037, 0x2c08, 0x080c, 0x1611, 0x6000, 0x9086, 0x0004, - 0x1120, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x009e, 0x080c, - 0x1ab7, 0x0804, 0xcb97, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, - 0x000b, 0x0005, 0xcc2a, 0xcb4f, 0xcc2c, 0xcc2a, 0xcc2c, 0xcc2c, - 0xcb49, 0xcc2a, 0xcb43, 0xcb43, 0xcc2a, 0xcc2a, 0xcc2a, 0xcc2a, - 0xcc2a, 0xcc2a, 0x080c, 0x0dc5, 0x6010, 0x00b6, 0x2058, 0xb804, - 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dc5, 0x00b6, - 0x0013, 0x00be, 0x0005, 0xcc47, 0xcd14, 0xcc49, 0xcc89, 0xcc49, - 0xcc89, 0xcc49, 0xcc57, 0xcc47, 0xcc89, 0xcc47, 0xcc78, 0x080c, - 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, - 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcd10, 0x6004, - 0x080c, 0xd047, 0x0904, 0xcd2d, 0x908e, 0x0004, 0x1110, 0x080c, - 0x3274, 0x908e, 0x0021, 0x0904, 0xcd31, 0x908e, 0x0022, 0x0904, - 0xcd78, 0x908e, 0x003d, 0x0904, 0xcd31, 0x908e, 0x0039, 0x0904, - 0xcd35, 0x908e, 0x0035, 0x0904, 0xcd35, 0x908e, 0x001e, 0x0178, - 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, - 0x9086, 0x0006, 0x0110, 0x080c, 0x324b, 0x080c, 0xbacb, 0x0804, - 0xb11a, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcd01, - 0x9186, 0x0002, 0x1904, 0xccd6, 0x2001, 0x1837, 0x2004, 0xd08c, - 0x11c8, 0x080c, 0x7563, 0x11b0, 0x080c, 0xd548, 0x0138, 0x080c, - 0x7586, 0x1120, 0x080c, 0x746d, 0x0804, 0xcd61, 0x2001, 0x197e, - 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x748f, - 0x0804, 0xcd61, 0x6010, 0x2058, 0x2001, 0x1837, 0x2004, 0xd0ac, - 0x1904, 0xcd61, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xcd61, 0xb840, - 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000, - 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0xb091, - 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce, - 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086, - 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085, 0x200a, 0x00e6, - 0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x080c, 0xbacb, 0x0030, - 0x080c, 0xbacb, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00e6, 0x0126, - 0x2091, 0x8000, 0x080c, 0x3274, 0x012e, 0x00ee, 0x080c, 0xb11a, - 0x0005, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00de, 0x00ce, 0x0c80, - 0x080c, 0x3274, 0x0804, 0xcc85, 0x00c6, 0x00d6, 0x6104, 0x9186, - 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, - 0x0904, 0xccd6, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x937d, - 0x080c, 0x98e7, 0x00de, 0x00ce, 0x0898, 0x080c, 0xbacb, 0x0804, - 0xcc87, 0x080c, 0xbb07, 0x0804, 0xcc87, 0x00d6, 0x2c68, 0x6104, - 0x080c, 0xd4c0, 0x00de, 0x0118, 0x080c, 0xb0e7, 0x0408, 0x6004, - 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, - 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1988, - 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108, - 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x0005, 0x00de, 0x00ce, 0x080c, 0xbacb, 0x080c, 0x324b, 0x00e6, - 0x0126, 0x2091, 0x8000, 0x080c, 0x3274, 0x6017, 0x0000, 0x6023, - 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, 0x00ee, 0x0005, - 0x080c, 0xb51f, 0x1904, 0xcd2d, 0x0005, 0x6000, 0x908a, 0x0016, - 0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005, - 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, - 0xcd98, 0xcb48, 0xcd98, 0xcb4f, 0xcd9a, 0xcb4f, 0xcdb4, 0xcd98, - 0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, - 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009, - 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, - 0x9335, 0x080c, 0x98e7, 0x0005, 0x080c, 0xd53c, 0x0118, 0x080c, - 0xd54f, 0x0010, 0x080c, 0xd55d, 0x080c, 0xd02a, 0x080c, 0xce3f, - 0x0570, 0x080c, 0x324b, 0x080c, 0xce3f, 0x0168, 0x6014, 0x2048, - 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed, - 0xa882, 0x080c, 0x6dcb, 0x2c68, 0x080c, 0xb091, 0x0150, 0x6810, - 0x6012, 0x080c, 0xd2bb, 0x00c6, 0x2d60, 0x080c, 0xb11a, 0x00ce, - 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, - 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00c8, 0x080c, - 0xd53c, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x324b, - 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, - 0x9186, 0x0035, 0x1118, 0x080c, 0x324b, 0x0868, 0x080c, 0xb11a, - 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xce1f, - 0xce1f, 0xce21, 0xce21, 0xce21, 0xce1f, 0xce1f, 0xb11a, 0xce1f, - 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0x080c, - 0x0dc5, 0x080c, 0xaa3f, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, - 0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7, 0x9284, 0x0007, 0x1158, - 0x9282, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, - 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, - 0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, - 0xf000, 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6, - 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, - 0x2071, 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, - 0x11f8, 0x080c, 0xd548, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, - 0x9086, 0x0004, 0x1148, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00c6, - 0x080c, 0xb11a, 0x00ce, 0x0060, 0x080c, 0xd235, 0x0148, 0x080c, - 0xd047, 0x1110, 0x080c, 0xbacb, 0x00c6, 0x080c, 0xb0e7, 0x00ce, - 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, - 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, - 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c, - 0x324b, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, - 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x01b0, - 0x6656, 0x2b00, 0x6012, 0x080c, 0x57d5, 0x0118, 0x080c, 0xcf6e, - 0x0168, 0x080c, 0xd2bb, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, - 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, - 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb139, 0x0560, - 0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003, - 0x0016, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08, - 0x080c, 0xe671, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb0e7, - 0x9085, 0x0001, 0x0070, 0x080c, 0x57d5, 0x0128, 0xd18c, 0x1170, - 0x080c, 0xcf6e, 0x0148, 0x2009, 0x004c, 0x080c, 0xb166, 0x9085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, - 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, - 0x0046, 0x0016, 0x080c, 0xb091, 0x2c78, 0x05a0, 0x7e56, 0x2b00, - 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf80, - 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, - 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb0e7, 0x00d0, - 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7, - 0x0088, 0x2f60, 0x080c, 0x57d5, 0x0138, 0xd18c, 0x1118, 0x04f1, - 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb166, - 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, - 0x00c6, 0x0046, 0x080c, 0xb091, 0x2c78, 0x0508, 0x7e56, 0x2b00, - 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, - 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7, - 0x0060, 0x2f60, 0x080c, 0x57d5, 0x0120, 0xd18c, 0x1160, 0x0071, - 0x0130, 0x2009, 0x0052, 0x080c, 0xb166, 0x9085, 0x0001, 0x004e, - 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, - 0x4b83, 0x00ce, 0x1120, 0x080c, 0xb0e7, 0x9006, 0x0005, 0xa867, - 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, - 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x684b, 0x0158, - 0x2001, 0xcf85, 0x0006, 0x900e, 0x2400, 0x080c, 0x7037, 0x080c, - 0x6dcb, 0x000e, 0x0807, 0x2418, 0x080c, 0x9775, 0xbaa0, 0x0086, - 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f2, 0x008e, - 0x080c, 0x93ad, 0x2f08, 0x2648, 0x080c, 0xe671, 0xb93c, 0x81ff, - 0x090c, 0x95c5, 0x080c, 0x98e7, 0x012e, 0x007e, 0x009e, 0x0005, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x0190, 0x660a, - 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, - 0x2009, 0x001f, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, - 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, - 0xb139, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, - 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, - 0x2009, 0x0021, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, - 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, - 0x2091, 0x8000, 0x080c, 0xb091, 0x0198, 0x660a, 0x2b08, 0x6112, - 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, - 0x080c, 0xb166, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, - 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139, - 0x0188, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, - 0x6016, 0x2009, 0x0000, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, - 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, - 0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, - 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, - 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, - 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, - 0x080c, 0xce3f, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, - 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, - 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, - 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139, 0x0198, - 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, - 0x080c, 0x324b, 0x2009, 0x0028, 0x080c, 0xb166, 0x9085, 0x0001, - 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, - 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, - 0xbd2d, 0x00be, 0x080c, 0xbf52, 0x6003, 0x0001, 0x6007, 0x0029, - 0x080c, 0x937d, 0x080c, 0x98e7, 0x0078, 0x6014, 0x0096, 0x2048, - 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd481, - 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x0005, 0x0096, 0x6014, 0x904d, - 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, - 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6dcb, 0x012e, 0x009e, 0x080c, 0xb0e7, 0x0c30, 0x0096, 0x9186, - 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x665d, 0x00e8, 0x9186, - 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, - 0x6010, 0x00b6, 0x2058, 0x080c, 0x67b2, 0x00be, 0x080c, 0xc023, - 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, - 0x2001, 0x0006, 0x080c, 0x665d, 0x6014, 0x2048, 0xa868, 0xd0fc, - 0x0170, 0x080c, 0xb4f3, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, - 0x0528, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6014, - 0x6310, 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883, - 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x08f8, 0x6014, 0x904d, - 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, - 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0840, 0xa878, 0x9086, 0x0005, - 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, - 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, - 0x9335, 0x080c, 0x98e7, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, - 0x00ce, 0x0005, 0xcb48, 0xd16b, 0xd16b, 0xd16e, 0xe98f, 0xe9aa, - 0xe9ad, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, - 0xcb48, 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, - 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, - 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, - 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, - 0xb091, 0x0508, 0x7810, 0x6012, 0x080c, 0xd2bb, 0x7820, 0x9086, - 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, - 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, - 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, - 0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, - 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, - 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, - 0x0fc0, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, - 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, - 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, - 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, - 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, - 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, - 0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, - 0x9335, 0x080c, 0x98e7, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, - 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, - 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, - 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, - 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, - 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, - 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, - 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, - 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, - 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, - 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, - 0x0036, 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, - 0x0032, 0x080c, 0x91ab, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, - 0x0014, 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, - 0x196d, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91ab, 0x2001, - 0x1988, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, - 0x9288, 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, - 0x080c, 0x1611, 0x080c, 0x6a6d, 0x00ee, 0x003e, 0x002e, 0x001e, - 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, - 0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, - 0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, - 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee, - 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, - 0x1040, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0xb091, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, - 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xb166, 0x9085, 0x0001, - 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, - 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, - 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, - 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9b82, 0x01d8, 0x707c, 0xaa50, - 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, - 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x3294, 0x080c, 0xb4f3, - 0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, - 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, - 0x2091, 0x8000, 0x080c, 0xb091, 0x0188, 0x2b08, 0x6112, 0x080c, - 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, - 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb091, 0x0180, - 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, - 0x001e, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, - 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, - 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, - 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, - 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048, - 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, - 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, - 0x200c, 0x080c, 0xdb93, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, - 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbacb, - 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, - 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, - 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, - 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b82, 0x01a8, 0x707c, 0xaa74, - 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x324b, - 0x080c, 0xb4f3, 0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe, - 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, - 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, - 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, - 0x9b82, 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, - 0x9206, 0x1160, 0x080c, 0x324b, 0x0016, 0xa998, 0xaab0, 0x9284, - 0x1000, 0xc0fd, 0x080c, 0x577c, 0x001e, 0x0010, 0x080c, 0x5567, - 0x080c, 0xce3f, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, - 0x4000, 0x0080, 0x080c, 0xce3f, 0x01b8, 0x6014, 0x2048, 0x080c, - 0x5567, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, - 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, - 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x0005, - 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, - 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, - 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, - 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, - 0xce3f, 0x0904, 0xd47d, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, - 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, - 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, - 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, - 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c, - 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, - 0x0f8b, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, - 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, - 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, - 0x080c, 0x6dbe, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, - 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, - 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, - 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x2889, 0x2118, 0x831f, - 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, - 0x8018, 0x080c, 0x4be3, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, - 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, - 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, - 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, - 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, - 0x6a2c, 0x080c, 0xce2d, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, - 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, - 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, - 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, - 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188, - 0x918c, 0x00ff, 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00, - 0x810f, 0x918e, 0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c, - 0xc4f6, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, - 0x0499, 0x01e0, 0x080c, 0xce3f, 0x01c8, 0x080c, 0xd02a, 0x6037, - 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, - 0xd047, 0x1118, 0x080c, 0xbacb, 0x0040, 0xa867, 0x0103, 0xa877, - 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dcb, 0x009e, 0x003e, 0x0005, - 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, - 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, - 0xd13b, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, - 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, - 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, - 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, - 0x080c, 0x4d9a, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, - 0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, - 0x6042, 0x0005, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x2001, 0x0109, - 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, - 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9, 0x2071, - 0x1800, 0x2061, 0x0100, 0x080c, 0x9218, 0x00ce, 0x00ee, 0x00fe, - 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, 0x0005, - 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x001b, - 0x006e, 0x00be, 0x0005, 0xd5ab, 0xdcf2, 0xde72, 0xd5ab, 0xd5ab, - 0xd5ab, 0xd5ab, 0xd5ab, 0xd5e2, 0xdef6, 0xd5ab, 0xd5ab, 0xd5ab, - 0xd5ab, 0xd5ab, 0xd5ab, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, - 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5c6, 0xe445, - 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xe3f2, 0xe499, - 0xd5c6, 0xeaca, 0xeb00, 0xeaca, 0xeb00, 0xd5c6, 0x080c, 0x0dc5, - 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x000a, 0x0005, - 0xd5e0, 0xe0d4, 0xe1a3, 0xe1c6, 0xe286, 0xd5e0, 0xe365, 0xe30e, - 0xdf02, 0xe3c8, 0xe3dd, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0, - 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100, 0x91b2, - 0x0040, 0x1a04, 0xda62, 0x0002, 0xd62c, 0xd830, 0xd62c, 0xd62c, - 0xd62c, 0xd839, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, - 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, - 0xd62c, 0xd62c, 0xd62c, 0xd62e, 0xd691, 0xd6a0, 0xd704, 0xd72f, - 0xd7a8, 0xd81b, 0xd62c, 0xd62c, 0xd83c, 0xd62c, 0xd62c, 0xd851, - 0xd85e, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd904, 0xd62c, - 0xd62c, 0xd918, 0xd62c, 0xd62c, 0xd8d3, 0xd62c, 0xd62c, 0xd62c, - 0xd930, 0xd62c, 0xd62c, 0xd62c, 0xd9ad, 0xd62c, 0xd62c, 0xd62c, - 0xd62c, 0xd62c, 0xd62c, 0xda2a, 0x080c, 0x0dc5, 0x080c, 0x6a4a, - 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, - 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, - 0x0000, 0x0804, 0xd829, 0x080c, 0x69e6, 0x00e6, 0x00c6, 0x0036, - 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, - 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08, 0x080c, - 0xe671, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, - 0x6610, 0x2658, 0x080c, 0x6726, 0xbe04, 0x9684, 0x00ff, 0x9082, - 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, - 0x00be, 0x2c08, 0x080c, 0xed2b, 0x002e, 0x001e, 0x1178, 0x080c, - 0xe5a3, 0x1904, 0xd6fc, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0008, - 0x0804, 0xd829, 0x6007, 0x0009, 0x0804, 0xd829, 0x080c, 0xe7c8, - 0x0128, 0x080c, 0xe5a3, 0x0d78, 0x0804, 0xd6fc, 0x6017, 0x1900, - 0x0c88, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6106, 0x080c, 0xe4f4, - 0x6007, 0x0006, 0x0804, 0xd829, 0x6007, 0x0007, 0x0804, 0xd829, - 0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f, - 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, - 0x1220, 0x2001, 0x0001, 0x080c, 0x6649, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, - 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, - 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, - 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, - 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, - 0x00b0, 0x00ee, 0x080c, 0xe607, 0x1190, 0x9686, 0x0006, 0x1140, - 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e, - 0x080c, 0x67b2, 0x6007, 0x000a, 0x00de, 0x0804, 0xd829, 0x6007, - 0x000b, 0x00de, 0x0804, 0xd829, 0x080c, 0x324b, 0x080c, 0xd55d, - 0x6007, 0x0001, 0x0804, 0xd829, 0x080c, 0xeb3c, 0x1904, 0xda5f, - 0x080c, 0x336f, 0x1904, 0xda5f, 0x2071, 0x0260, 0x7034, 0x90b4, - 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, - 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, - 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e, 0x6007, - 0x000c, 0x2001, 0x0001, 0x080c, 0xed0a, 0x0804, 0xd829, 0x080c, - 0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, - 0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610, 0x2658, - 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, - 0x2001, 0x0006, 0x080c, 0x6689, 0x002e, 0x0050, 0x96b4, 0xff00, - 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc, - 0x080c, 0xe614, 0x1120, 0x6007, 0x000e, 0x0804, 0xd829, 0x0046, - 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b, 0x080c, 0xd55d, - 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, - 0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058, 0xb800, 0xc0e5, - 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd829, 0x2001, - 0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, - 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0d3, 0x003e, - 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, - 0x9682, 0x0004, 0x0a04, 0xd6fc, 0x9682, 0x0007, 0x0a04, 0xd758, - 0x0804, 0xd6fc, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd829, - 0x080c, 0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, - 0x9086, 0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610, - 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, - 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, - 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc, 0x080c, - 0xe642, 0x1138, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0010, 0x0804, - 0xd829, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b, - 0x080c, 0xd55d, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, - 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058, - 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, - 0x080c, 0xe7c8, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, - 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0006, 0x0920, 0x0804, 0xd6fc, 0x001e, 0x6017, 0x1900, - 0x6007, 0x0009, 0x0070, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, - 0xeb3c, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6007, - 0x0012, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, - 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, - 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeb3c, 0x1904, 0xda5f, - 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc, - 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, - 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6007, 0x0023, 0x6003, - 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0xeb3c, - 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30, - 0x1904, 0xd6fc, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, - 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, - 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, - 0xce2d, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, - 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, - 0xb0e7, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, - 0xce2d, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, - 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, - 0x9006, 0x080c, 0xe90a, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, - 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, - 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, - 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb0e7, 0x2160, 0x6007, - 0x0025, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00ee, - 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x6649, 0x0156, - 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, - 0x0276, 0x080c, 0xc0d3, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, - 0x6007, 0x0031, 0x0804, 0xd829, 0x080c, 0xbd45, 0x080c, 0x7563, - 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1138, 0x080c, - 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0010, 0x080c, 0x753b, - 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f, - 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc4c, 0x1120, - 0x6007, 0x002b, 0x0804, 0xd829, 0x6007, 0x002c, 0x0804, 0xd829, - 0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f, - 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc51, 0x1120, - 0x6007, 0x002e, 0x0804, 0xd829, 0x6007, 0x002f, 0x0804, 0xd829, - 0x080c, 0x336f, 0x1904, 0xda5f, 0x00e6, 0x00d6, 0x00c6, 0x6010, - 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, - 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, - 0x0804, 0xd830, 0x080c, 0x57d1, 0xd0e4, 0x0904, 0xd9aa, 0x2071, - 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, - 0x6a88, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, - 0x9206, 0x0510, 0x080c, 0x6a84, 0x15b8, 0x2069, 0x1800, 0x6880, - 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xce2d, - 0x0590, 0x080c, 0xdb1d, 0x0578, 0x080c, 0xe9bc, 0x0560, 0x622e, - 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, - 0x080c, 0xce2d, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, - 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a, - 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, - 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, - 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336f, 0x1904, - 0xda5f, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, - 0x0006, 0x1904, 0xd830, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x57d1, - 0xd0e4, 0x0904, 0xda22, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, - 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, - 0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a, 0x2c10, 0x00ce, 0x05e8, - 0x080c, 0xce2d, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, - 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca51, 0x002e, 0x00ce, - 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, - 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, - 0x9005, 0x0170, 0x080c, 0xdb1d, 0x0904, 0xd9a3, 0x0056, 0x7510, - 0x7614, 0x080c, 0xe9d5, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, - 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x0c78, 0x6007, 0x003b, 0x602f, - 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, - 0x98e7, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, - 0x0804, 0xd97a, 0x00e6, 0x0026, 0x080c, 0x6a4a, 0x0550, 0x080c, - 0x69e6, 0x080c, 0xebad, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, - 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, - 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, - 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a88, 0x0120, 0x2011, 0x1a02, - 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3022, 0x0010, 0x080c, - 0xebe1, 0x002e, 0x00ee, 0x080c, 0xb0e7, 0x0804, 0xd82f, 0x080c, - 0xb0e7, 0x0005, 0x2600, 0x0002, 0xda76, 0xdaa4, 0xdab5, 0xda76, - 0xda76, 0xda78, 0xdac6, 0xda76, 0xda76, 0xda76, 0xda92, 0xda76, - 0xda76, 0xda76, 0xdad1, 0xdae7, 0xdb18, 0xda76, 0x080c, 0x0dc5, - 0x080c, 0xeb3c, 0x1d20, 0x080c, 0x336f, 0x1d08, 0x7038, 0x6016, - 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x937d, 0x0005, 0x080c, - 0x324b, 0x080c, 0xd55d, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, - 0x937d, 0x0005, 0x080c, 0xeb3c, 0x1950, 0x080c, 0x336f, 0x1938, - 0x080c, 0xdc30, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, - 0x0001, 0x080c, 0x937d, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f, - 0x2009, 0x0041, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003, 0x0001, - 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f, 0x1904, - 0xda5f, 0x2009, 0x0042, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003, - 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f, - 0x1904, 0xda5f, 0x2009, 0x0046, 0x080c, 0xebea, 0x080c, 0xb0e7, - 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, - 0xdb3a, 0x0904, 0xda5f, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, - 0x937d, 0x080c, 0x98e7, 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, - 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, - 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004, 0x9106, - 0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190, 0x9186, - 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, - 0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x0110, 0x6017, - 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, - 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, - 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc, 0xd084, - 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048, 0x9106, - 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, - 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, - 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, - 0x19a1, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900, 0x6016, - 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, - 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, - 0x2001, 0x19a1, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, - 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, - 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, - 0x2001, 0x19a1, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, - 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, 0x2048, - 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, - 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, - 0x918c, 0xffff, 0x11b0, 0x080c, 0x2403, 0x2099, 0x026c, 0x2001, - 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, - 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260, - 0x0ca8, 0x080c, 0x2403, 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, - 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, - 0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260, 0x0ca8, - 0x2061, 0x19a1, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, - 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, + 0x080c, 0xd152, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, + 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0007, 0x080c, 0x4da0, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, + 0x0005, 0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, + 0x2004, 0x6042, 0x0005, 0x080c, 0xb101, 0x0804, 0x98ed, 0x2001, + 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9, + 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x921e, 0x00ce, 0x00ee, + 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, + 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, + 0x001b, 0x006e, 0x00be, 0x0005, 0xd5c4, 0xdd0b, 0xde80, 0xd5c4, + 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0xd5fb, 0xdf04, 0xd5c4, 0xd5c4, + 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0x080c, 0x0dc5, 0x0066, 0x6000, + 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5df, + 0xe453, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xe400, + 0xe4a7, 0xd5df, 0xeb2f, 0xeb65, 0xeb2f, 0xeb65, 0xd5df, 0x080c, + 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000, 0x000a, + 0x0005, 0xd5f9, 0xe0e2, 0xe1b1, 0xe1d4, 0xe294, 0xd5f9, 0xe373, + 0xe31c, 0xdf10, 0xe3d6, 0xe3eb, 0xd5f9, 0xd5f9, 0xd5f9, 0xd5f9, + 0xd5f9, 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100, + 0x91b2, 0x0040, 0x1a04, 0xda7b, 0x0002, 0xd645, 0xd849, 0xd645, + 0xd645, 0xd645, 0xd852, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xd647, 0xd6aa, 0xd6b9, 0xd71d, + 0xd748, 0xd7c1, 0xd834, 0xd645, 0xd645, 0xd855, 0xd645, 0xd645, + 0xd86a, 0xd877, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd91d, + 0xd645, 0xd645, 0xd931, 0xd645, 0xd645, 0xd8ec, 0xd645, 0xd645, + 0xd645, 0xd949, 0xd645, 0xd645, 0xd645, 0xd9c6, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xda43, 0x080c, 0x0dc5, 0x080c, + 0x6a50, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, + 0x6017, 0x0000, 0x0804, 0xd842, 0x080c, 0x69ec, 0x00e6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, + 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08, + 0x080c, 0xe690, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x6610, 0x2658, 0x080c, 0x672c, 0xbe04, 0x9684, 0x00ff, + 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xed90, 0x002e, 0x001e, 0x1178, + 0x080c, 0xe5c2, 0x1904, 0xd715, 0x080c, 0xe55e, 0x1120, 0x6007, + 0x0008, 0x0804, 0xd842, 0x6007, 0x0009, 0x0804, 0xd842, 0x080c, + 0xe82d, 0x0128, 0x080c, 0xe5c2, 0x0d78, 0x0804, 0xd715, 0x6017, + 0x1900, 0x0c88, 0x080c, 0x336a, 0x1904, 0xda78, 0x6106, 0x080c, + 0xe502, 0x6007, 0x0006, 0x0804, 0xd842, 0x6007, 0x0007, 0x0804, + 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, + 0xda78, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x664f, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, + 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, + 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, + 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe626, 0x1190, 0x9686, 0x0006, + 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f, + 0x002e, 0x080c, 0x67b8, 0x6007, 0x000a, 0x00de, 0x0804, 0xd842, + 0x6007, 0x000b, 0x00de, 0x0804, 0xd842, 0x080c, 0x3246, 0x080c, + 0xd576, 0x6007, 0x0001, 0x0804, 0xd842, 0x080c, 0xeba1, 0x1904, + 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x2071, 0x0260, 0x7034, + 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, + 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, + 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f, 0x002e, + 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xed6f, 0x0804, 0xd842, + 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, + 0x0026, 0x2001, 0x0006, 0x080c, 0x668f, 0x002e, 0x0050, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, + 0xd715, 0x080c, 0xe633, 0x1120, 0x6007, 0x000e, 0x0804, 0xd842, + 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3246, 0x080c, + 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, + 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010, 0x2058, 0xb800, + 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd842, + 0x2001, 0x0001, 0x080c, 0x664f, 0x0156, 0x0016, 0x0026, 0x0036, + 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0e3, + 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, + 0x8637, 0x9682, 0x0004, 0x0a04, 0xd715, 0x9682, 0x0007, 0x0a04, + 0xd771, 0x0804, 0xd715, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, + 0xd842, 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec, + 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, + 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, + 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd715, + 0x080c, 0xe661, 0x1138, 0x080c, 0xe55e, 0x1120, 0x6007, 0x0010, + 0x0804, 0xd842, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, + 0x3246, 0x080c, 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, + 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010, + 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, + 0x0448, 0x080c, 0xe82d, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, + 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, 0xd715, 0x001e, 0x6017, + 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x336a, 0x1904, 0xda78, + 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, + 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeba1, 0x1904, + 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904, + 0xd715, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0005, 0x080c, 0x336a, 0x1904, 0xda78, 0x6007, 0x0023, + 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c, + 0xdc49, 0x1904, 0xd715, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, + 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, + 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, + 0x080c, 0xce44, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, + 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, + 0x080c, 0xb101, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, + 0x080c, 0xce44, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, + 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, + 0x2c08, 0x9006, 0x080c, 0xe96f, 0x1180, 0x7244, 0x9286, 0xffff, + 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, + 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, + 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb101, 0x2160, + 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x664f, + 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, + 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e, 0x015e, + 0x0120, 0x6007, 0x0031, 0x0804, 0xd842, 0x080c, 0xbd50, 0x080c, + 0x7569, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1138, + 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0010, 0x080c, + 0x7541, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336a, 0x1904, + 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc65, + 0x1120, 0x6007, 0x002b, 0x0804, 0xd842, 0x6007, 0x002c, 0x0804, + 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, + 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc6a, + 0x1120, 0x6007, 0x002e, 0x0804, 0xd842, 0x6007, 0x002f, 0x0804, + 0xd842, 0x080c, 0x336a, 0x1904, 0xda78, 0x00e6, 0x00d6, 0x00c6, + 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, + 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, + 0x00ee, 0x0804, 0xd849, 0x080c, 0x57d7, 0xd0e4, 0x0904, 0xd9c3, + 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, + 0x080c, 0x6a8e, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, + 0xb814, 0x9206, 0x0510, 0x080c, 0x6a8a, 0x15b8, 0x2069, 0x1800, + 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, + 0xce44, 0x0590, 0x080c, 0xdb36, 0x0578, 0x080c, 0xea21, 0x0560, + 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, + 0x0150, 0x080c, 0xce44, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, + 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, + 0xe96f, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, + 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, + 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336a, + 0x1904, 0xda78, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, + 0x9086, 0x0006, 0x1904, 0xd849, 0x00e6, 0x00d6, 0x00c6, 0x080c, + 0x57d7, 0xd0e4, 0x0904, 0xda3b, 0x2069, 0x1800, 0x2071, 0x026c, + 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, + 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe96f, 0x2c10, 0x00ce, + 0x05e8, 0x080c, 0xce44, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, + 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca64, 0x002e, + 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, + 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, + 0x2004, 0x9005, 0x0170, 0x080c, 0xdb36, 0x0904, 0xd9bc, 0x0056, + 0x7510, 0x7614, 0x080c, 0xea3a, 0x005e, 0x00ce, 0x00de, 0x00ee, + 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, + 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c78, 0x6007, 0x003b, + 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, + 0x0000, 0x0804, 0xd993, 0x00e6, 0x0026, 0x080c, 0x6a50, 0x0550, + 0x080c, 0x69ec, 0x080c, 0xec12, 0x1518, 0x2071, 0x1800, 0x70dc, + 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, + 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, + 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a8e, 0x0120, 0x2011, + 0x1a02, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3019, 0x0010, + 0x080c, 0xec46, 0x002e, 0x00ee, 0x080c, 0xb101, 0x0804, 0xd848, + 0x080c, 0xb101, 0x0005, 0x2600, 0x0002, 0xda8f, 0xdabd, 0xdace, + 0xda8f, 0xda8f, 0xda91, 0xdadf, 0xda8f, 0xda8f, 0xda8f, 0xdaab, + 0xda8f, 0xda8f, 0xda8f, 0xdaea, 0xdb00, 0xdb31, 0xda8f, 0x080c, + 0x0dc5, 0x080c, 0xeba1, 0x1d20, 0x080c, 0x336a, 0x1d08, 0x7038, + 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x9383, 0x0005, + 0x080c, 0x3246, 0x080c, 0xd576, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x9383, 0x0005, 0x080c, 0xeba1, 0x1950, 0x080c, 0x336a, + 0x1938, 0x080c, 0xdc49, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, + 0x6003, 0x0001, 0x080c, 0x9383, 0x0005, 0x080c, 0x336a, 0x1904, + 0xda78, 0x2009, 0x0041, 0x080c, 0xec4f, 0x6007, 0x0047, 0x6003, + 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, 0x336a, + 0x1904, 0xda78, 0x2009, 0x0042, 0x080c, 0xec4f, 0x6007, 0x0047, + 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, + 0x336a, 0x1904, 0xda78, 0x2009, 0x0046, 0x080c, 0xec4f, 0x080c, + 0xb101, 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, + 0x080c, 0xdb53, 0x0904, 0xda78, 0x6007, 0x004e, 0x6003, 0x0001, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x6007, 0x0012, 0x0cb0, + 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, + 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004, + 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190, + 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, + 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x0110, + 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, + 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc, + 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048, + 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, + 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, + 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, + 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900, + 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, + 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, + 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, + 0x01b8, 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100, + 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, + 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, + 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, + 0x2048, 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, + 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x240b, 0x2099, 0x026c, + 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, + 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099, + 0x0260, 0x0ca8, 0x080c, 0x240b, 0x2061, 0x19a2, 0x6004, 0x2098, + 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, + 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099, 0x0260, + 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, + 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, + 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, + 0x11b8, 0x080c, 0x2423, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, + 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, + 0x01f8, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98, + 0x080c, 0x2423, 0x2061, 0x19a5, 0x6004, 0x20a0, 0x6008, 0x3518, + 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, + 0x0138, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98, + 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, + 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, - 0x080c, 0x241b, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, - 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, - 0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x080c, - 0x241b, 0x2061, 0x19a4, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, - 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, - 0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x2061, - 0x19a4, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, - 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, - 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, - 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, - 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, - 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdcc8, 0x00de, - 0x0005, 0x00d6, 0x080c, 0xdcd5, 0x1520, 0x680c, 0x908c, 0xff00, - 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, - 0x0130, 0x9006, 0x080c, 0xed0a, 0x2009, 0x0001, 0x0078, 0xd1ec, - 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2889, 0x1148, - 0x2001, 0x0001, 0x080c, 0xed0a, 0x2110, 0x900e, 0x080c, 0x3294, - 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, - 0x00c6, 0x080c, 0xb139, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, - 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x1578, 0x080c, - 0x66ac, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, - 0x6012, 0x080c, 0xeb3c, 0x11d8, 0x080c, 0x336f, 0x11c0, 0x080c, - 0xdc30, 0x0510, 0x2001, 0x0007, 0x080c, 0x665d, 0x2001, 0x0007, - 0x080c, 0x6689, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, - 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0010, 0x080c, - 0xb0e7, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xb0e7, - 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb0e7, 0x9006, 0x0c98, - 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000, - 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069, - 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904, - 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800, - 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, 0x908e, - 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6, - 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde42, 0x040a, - 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, - 0x1148, 0x080c, 0xd56e, 0x0128, 0x6000, 0x9086, 0x0002, 0x0904, - 0xbb12, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001, 0x0007, - 0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, - 0x0005, 0xdd61, 0xdd63, 0xdd61, 0xdd61, 0xdd61, 0xdd63, 0xdd72, - 0xde3b, 0xddc4, 0xde3b, 0xddec, 0xde3b, 0xdd72, 0xde3b, 0xde33, - 0xde3b, 0xde33, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61, 0xdd61, - 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd63, - 0xdd61, 0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xdd61, 0xde38, 0xde3b, - 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xde3b, - 0xde3b, 0xdd61, 0xdd6d, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde37, - 0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61, - 0xdd61, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xd560, 0x6003, - 0x0002, 0x080c, 0x98e7, 0x0804, 0xde41, 0x9006, 0x080c, 0x6649, - 0x0804, 0xde3b, 0x080c, 0x6a84, 0x1904, 0xde3b, 0x9006, 0x080c, - 0x6649, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, - 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, - 0x2058, 0xb8c0, 0x9005, 0x1178, 0x080c, 0xd548, 0x1904, 0xde3b, - 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4d9a, 0x004e, - 0x003e, 0x0804, 0xde3b, 0x080c, 0x33a0, 0x1904, 0xde3b, 0x2001, - 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, - 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x665d, - 0x080c, 0x97db, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, - 0x080c, 0x937d, 0x080c, 0x98e7, 0x6110, 0x2158, 0x2009, 0x0001, - 0x080c, 0x8711, 0x0804, 0xde41, 0x6610, 0x2658, 0xbe04, 0x96b4, - 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, - 0x080c, 0x8ef4, 0x2001, 0x0004, 0x080c, 0x6689, 0x080c, 0xed59, - 0x0904, 0xde3b, 0x080c, 0x97db, 0x2001, 0x0004, 0x080c, 0x665d, - 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, - 0x080c, 0x98e7, 0x0804, 0xde41, 0x2001, 0x1800, 0x2004, 0x9086, - 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, - 0x0006, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, - 0xde5f, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c, 0x6689, - 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006, 0x080c, - 0x665d, 0x080c, 0x6a84, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, - 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, - 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddac, - 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, - 0x0010, 0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, - 0x98e7, 0x0005, 0x2600, 0x0002, 0xde56, 0xde56, 0xde56, 0xde56, - 0xde56, 0xde58, 0xde56, 0xde58, 0xde56, 0xde56, 0xde58, 0xde56, - 0xde56, 0xde56, 0xde58, 0xde58, 0xde58, 0xde58, 0x080c, 0x0dc5, - 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x0016, - 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, - 0x665d, 0x9006, 0x080c, 0x6649, 0x080c, 0x3274, 0x00de, 0x00be, - 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, - 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, - 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbb4, - 0xbbb4, 0xbbb4, 0xbbb4, 0xdef4, 0xbbb4, 0xdede, 0xde9f, 0xbbb4, - 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xdef4, - 0xbbb4, 0xdede, 0xdee5, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0x00f6, - 0x080c, 0x6a84, 0x11d8, 0x080c, 0xd548, 0x11c0, 0x6010, 0x905d, - 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c, 0x6649, 0x2001, - 0x0002, 0x080c, 0x665d, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00f0, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b0, 0x080c, 0x6717, - 0x0118, 0x080c, 0xb0e7, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, - 0xb8c0, 0x0006, 0x080c, 0x613b, 0x000e, 0xb8c2, 0x000e, 0xb816, - 0x000e, 0xb812, 0x080c, 0xb0e7, 0x00fe, 0x0005, 0x6604, 0x96b6, - 0x001e, 0x1110, 0x080c, 0xb0e7, 0x0005, 0x080c, 0xbf4f, 0x1148, - 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, - 0x0010, 0x080c, 0xb0e7, 0x0005, 0x0804, 0xb0e7, 0x6004, 0x908a, - 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, - 0x98e7, 0x0005, 0x9182, 0x0040, 0x0002, 0xdf19, 0xdf19, 0xdf19, - 0xdf19, 0xdf1b, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, - 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, - 0xdf19, 0x080c, 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, - 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, - 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf81, 0x080c, - 0xecfe, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, - 0x0200, 0x080c, 0x8916, 0x0020, 0x9026, 0x080c, 0xeb81, 0x0c38, - 0x080c, 0x100e, 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, - 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, - 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, - 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6dcb, 0x001e, - 0x080c, 0xecfe, 0x1904, 0xdfe1, 0x9486, 0x2000, 0x1130, 0x2019, - 0x0017, 0x080c, 0xe8b0, 0x0804, 0xdfe1, 0x9486, 0x0200, 0x1120, - 0x080c, 0xe847, 0x0804, 0xdfe1, 0x9486, 0x0400, 0x0120, 0x9486, - 0x1000, 0x1904, 0xdfe1, 0x2019, 0x0002, 0x080c, 0xe862, 0x0804, - 0xdfe1, 0x2069, 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe04b, 0x9284, - 0x0300, 0x1904, 0xe044, 0x6804, 0x9005, 0x0904, 0xe02c, 0x2d78, - 0x6003, 0x0007, 0x080c, 0x1027, 0x0904, 0xdfed, 0x7800, 0xd08c, - 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, - 0x2004, 0xd084, 0x1904, 0xe04f, 0x9006, 0xa802, 0xa867, 0x0116, - 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, - 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, - 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, - 0x9080, 0xdfe9, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, - 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, - 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, - 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, - 0x6dcb, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, - 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, - 0xd084, 0x0120, 0x080c, 0x100e, 0x1904, 0xdf96, 0x6017, 0xf100, - 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, - 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, - 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, - 0x9335, 0x080c, 0x98e7, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, - 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x0804, 0xdfe1, 0x2001, 0x180e, 0x2004, 0xd0ec, - 0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x6017, 0xf300, 0x0010, - 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x0804, 0xdfe1, 0x6017, 0xf500, 0x0c98, 0x6017, - 0xf600, 0x0804, 0xe001, 0x6017, 0xf200, 0x0804, 0xe001, 0xa867, - 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, - 0x9084, 0x0003, 0x9080, 0xdfe9, 0x2005, 0xa87e, 0x2928, 0x6010, - 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, - 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, - 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, - 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, - 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0029, 0x20a0, 0x2011, 0xe0cb, 0x2041, 0x0001, 0x223d, 0x9784, - 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, - 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, - 0x0c68, 0x2950, 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, - 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, - 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, - 0x1040, 0x0cc8, 0x080c, 0x1040, 0x0804, 0xdfed, 0x2548, 0x8847, - 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, - 0xe8e3, 0x0804, 0xdfe1, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, - 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, - 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, - 0x2008, 0x0804, 0xe15a, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, - 0xd56e, 0x0500, 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1a3, - 0x9186, 0x0027, 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, - 0x0160, 0x190c, 0x0dc5, 0x080c, 0xd56e, 0x0160, 0x6000, 0x9086, - 0x0004, 0x190c, 0x0dc5, 0x0804, 0xe286, 0x6004, 0x9082, 0x0040, - 0x2008, 0x001a, 0x080c, 0xb181, 0x0005, 0xe121, 0xe123, 0xe123, - 0xe14a, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, - 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, - 0xe121, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0036, - 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xce3f, 0x01c0, 0x6003, - 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, - 0x2019, 0x0004, 0x080c, 0xe8e3, 0x6017, 0x0000, 0x6018, 0x9005, - 0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, - 0x003e, 0x0005, 0x0096, 0x080c, 0x97db, 0x080c, 0x98e7, 0x080c, - 0xce3f, 0x0120, 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb11a, - 0x009e, 0x0005, 0x0002, 0xe16f, 0xe186, 0xe171, 0xe19d, 0xe16f, - 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, - 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0x080c, - 0x0dc5, 0x0096, 0x080c, 0x97db, 0x6014, 0x2048, 0xa87c, 0xd0b4, - 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xb166, 0x0010, - 0x6003, 0x0004, 0x080c, 0x98e7, 0x009e, 0x0005, 0x080c, 0x97db, - 0x080c, 0xce3f, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, - 0xd1ec, 0x1138, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x080c, 0x98e7, - 0x0005, 0x080c, 0xeb45, 0x0db0, 0x0cc8, 0x080c, 0x97db, 0x2009, - 0x0041, 0x0804, 0xe30e, 0x9182, 0x0040, 0x0002, 0xe1ba, 0xe1bc, - 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, - 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1bd, - 0xe1ba, 0xe1ba, 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88eb, - 0x00de, 0x080c, 0xeb9d, 0x080c, 0xb0e7, 0x0005, 0x9182, 0x0040, - 0x0002, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, - 0xe1dd, 0xe1dd, 0xe1df, 0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, - 0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0x080c, 0x0dc5, 0x2001, - 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, - 0x2001, 0x0131, 0x2004, 0x9105, 0x1904, 0xe24e, 0x2009, 0x180c, - 0x2104, 0xd0d4, 0x0904, 0xe24e, 0xc0d4, 0x200a, 0x2009, 0x0105, - 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, - 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, 0x080c, 0x9897, 0x6014, - 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, - 0x0002, 0x0508, 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, - 0x9a09, 0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x080c, 0x9a09, - 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x88eb, 0x009e, 0x0005, - 0x2001, 0x0100, 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, - 0x2004, 0x603a, 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, - 0xd1cc, 0x0110, 0x080c, 0x2c9d, 0x080c, 0x9a09, 0x6014, 0x2048, - 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x009e, - 0x0005, 0x080c, 0xeb45, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, - 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9897, 0x080c, 0x9a09, - 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, - 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, - 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x6018, - 0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, - 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, - 0x0002, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, - 0xe29d, 0xe29f, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, - 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe2ea, 0x080c, 0x0dc5, 0x6014, - 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, - 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, - 0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x6003, 0x0007, 0x601b, - 0x0000, 0x080c, 0x88eb, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, - 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, - 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, - 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, - 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, - 0x0006, 0x00e9, 0x080c, 0x88ed, 0x009e, 0x0005, 0x6003, 0x0002, - 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, - 0xe29f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, - 0x9105, 0x1120, 0x080c, 0x1608, 0x1904, 0xe29f, 0x0005, 0xd2fc, - 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, - 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, - 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, - 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe332, 0xe33e, - 0xe34a, 0xe356, 0xe332, 0xe332, 0xe332, 0xe332, 0xe339, 0xe334, - 0xe334, 0xe332, 0xe332, 0xe332, 0xe332, 0xe334, 0xe332, 0xe334, - 0xe332, 0xe339, 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, - 0x0005, 0x6014, 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, - 0x6106, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7, - 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126, - 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x6003, 0x0003, - 0x6106, 0x2c10, 0x080c, 0x1c01, 0x0126, 0x2091, 0x8000, 0x080c, - 0x939a, 0x080c, 0x9a09, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, - 0x0005, 0xe385, 0xe387, 0xe399, 0xe3b3, 0xe385, 0xe385, 0xe385, - 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, - 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0x080c, 0x0dc5, 0x6014, - 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, - 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, - 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, - 0x080c, 0xe8e3, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, - 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, - 0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x080c, 0x9a09, 0x0005, - 0x080c, 0x97db, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, - 0xec9b, 0x0036, 0x2019, 0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e, - 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x080c, 0x9897, 0x6114, - 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xec9b, 0x0036, 0x2019, - 0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e, 0x080c, 0xb11a, 0x080c, - 0x9a09, 0x0005, 0x9182, 0x0085, 0x0002, 0xe404, 0xe402, 0xe402, - 0xe410, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, - 0xe402, 0xe402, 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, - 0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, - 0x0026, 0x00e6, 0x080c, 0xeb3c, 0x0118, 0x080c, 0xb0e7, 0x0450, - 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, - 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, - 0x014e, 0x080c, 0xb40c, 0x7220, 0x080c, 0xe77e, 0x0118, 0x6007, - 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, - 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x080c, 0x9a09, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, - 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, - 0x0dc5, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, - 0x0014, 0x0118, 0x080c, 0xb181, 0x0050, 0x2001, 0x0007, 0x080c, - 0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, - 0xe475, 0xe477, 0xe477, 0xe475, 0xe475, 0xe475, 0xe475, 0xe475, - 0xe475, 0xe475, 0xe475, 0xe475, 0xe475, 0x080c, 0x0dc5, 0x080c, - 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x9182, 0x0085, - 0x0a0c, 0x0dc5, 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, - 0x0002, 0xe496, 0xe496, 0xe496, 0xe498, 0xe496, 0xe496, 0xe496, - 0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0x080c, 0x0dc5, - 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, - 0x0027, 0x0118, 0x080c, 0xb181, 0x0030, 0x080c, 0x97db, 0x080c, - 0xb11a, 0x080c, 0x98e7, 0x0005, 0x0036, 0x080c, 0xeb9d, 0x6043, - 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, - 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, - 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x1550, 0x0076, - 0x2c38, 0x080c, 0xa9ba, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, - 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, - 0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c, 0x1ab7, 0x6023, - 0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c, 0xe8e3, - 0x009e, 0x6017, 0x0000, 0x080c, 0xeb9d, 0x6023, 0x0007, 0x080c, - 0xd560, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, - 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x2889, 0x15c8, - 0x0016, 0x00c6, 0x080c, 0x6717, 0x1590, 0x001e, 0x00c6, 0x2160, - 0x080c, 0xd55d, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, - 0x080c, 0xaa80, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, - 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe671, 0x007e, 0x0026, - 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, - 0x0004, 0x1118, 0xbaa0, 0x080c, 0x3309, 0x002e, 0xbcc0, 0x001e, - 0x080c, 0x613b, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, - 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, - 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, - 0x1904, 0xe598, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, - 0x6940, 0x9184, 0x8000, 0x0904, 0xe595, 0x2001, 0x197d, 0x2004, - 0x9005, 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, - 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed03, - 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, - 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, - 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, - 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, - 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, - 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, - 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, - 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, - 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, - 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, - 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6726, 0x0804, 0xe600, - 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, - 0x080c, 0xc0e7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, - 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0e7, 0x009e, 0x1548, - 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, - 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe940, 0xb800, 0xc0e5, - 0xb802, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, - 0x080c, 0x93ad, 0x2c08, 0x080c, 0xe671, 0x007e, 0x2001, 0x0007, - 0x080c, 0x6689, 0x2001, 0x0007, 0x080c, 0x665d, 0x001e, 0x004e, - 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, - 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, - 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, - 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2889, - 0x11d0, 0x080c, 0x6717, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, - 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158, - 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, - 0x080c, 0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, - 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, - 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11d0, - 0x080c, 0x6717, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158, 0x2011, - 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, - 0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, - 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, - 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c, - 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, - 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128, - 0x8001, 0x9602, 0x1a04, 0xe70f, 0x0018, 0x9606, 0x0904, 0xe70f, - 0x080c, 0x8bbd, 0x0904, 0xe706, 0x2100, 0x9c06, 0x0904, 0xe706, - 0x6720, 0x9786, 0x0007, 0x0904, 0xe706, 0x080c, 0xe981, 0x1904, - 0xe706, 0x080c, 0xed21, 0x0904, 0xe706, 0x080c, 0xe971, 0x0904, - 0xe706, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x33a0, 0x0904, - 0xe74e, 0x6004, 0x9086, 0x0000, 0x1904, 0xe74e, 0x9786, 0x0004, - 0x0904, 0xe74e, 0x2500, 0x9c06, 0x0904, 0xe706, 0x2400, 0x9c06, - 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, - 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786, - 0x000a, 0x0148, 0x080c, 0xd047, 0x1130, 0x080c, 0xbacb, 0x009e, - 0x080c, 0xb11a, 0x0418, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01d8, - 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, - 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, - 0x0000, 0x080c, 0xec9b, 0x0016, 0x080c, 0xd135, 0x080c, 0x6dbe, - 0x001e, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb11a, 0x9ce0, 0x0018, - 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe685, 0x012e, - 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, - 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, - 0xec9b, 0x080c, 0xe8e3, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009, - 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, - 0x11a0, 0x080c, 0x9897, 0x0096, 0x6114, 0x2148, 0x080c, 0xce3f, - 0x0118, 0x6010, 0x080c, 0x6dcb, 0x009e, 0x00c6, 0x080c, 0xb0e7, - 0x00ce, 0x0036, 0x080c, 0x9a09, 0x003e, 0x009e, 0x0804, 0xe706, - 0x9786, 0x000a, 0x0904, 0xe6f6, 0x0804, 0xe6eb, 0x81ff, 0x0904, - 0xe706, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, - 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe706, 0x6000, 0x9086, - 0x0002, 0x1904, 0xe706, 0x080c, 0xd036, 0x0138, 0x080c, 0xd047, - 0x1904, 0xe706, 0x080c, 0xbacb, 0x0038, 0x080c, 0x3274, 0x080c, - 0xd047, 0x1110, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x0804, 0xe706, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, - 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe90a, 0x001e, 0x0120, - 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe79d, - 0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79f, 0xe79d, 0xe79d, - 0xe79d, 0xe79d, 0xb11a, 0xb11a, 0xe79d, 0x9006, 0x0005, 0x0036, - 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, - 0x2009, 0x0020, 0x080c, 0xe940, 0x001e, 0x004e, 0x2019, 0x0002, - 0x080c, 0xe4ba, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, - 0xce3f, 0x0140, 0x6014, 0x904d, 0x080c, 0xca5e, 0x687b, 0x0005, - 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb11a, 0x9085, 0x0001, 0x0005, - 0x2001, 0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036, - 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xc0d3, - 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, - 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, - 0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xe83a, - 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, 0xe83a, - 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe971, - 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, - 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, - 0x9b06, 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, - 0x601c, 0xd084, 0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c, - 0x1ab7, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0120, - 0x0046, 0x080c, 0xe8e3, 0x004e, 0x009e, 0x080c, 0xb11a, 0x88ff, - 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, - 0x0804, 0xe7ed, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, - 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, - 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, - 0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, - 0x008e, 0x903e, 0x080c, 0xa9ba, 0x080c, 0xe7de, 0x005e, 0x007e, - 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, - 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, - 0x6717, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, - 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c, - 0xa9ba, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe86d, 0x0036, - 0x2508, 0x2029, 0x0003, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce, - 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, - 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, - 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c, - 0xa9ba, 0x2c20, 0x080c, 0xe7de, 0x005e, 0x007e, 0x00be, 0x0005, - 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, - 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6717, 0x1190, 0x0086, - 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xeb81, 0x004e, - 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c, - 0xa9ba, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe8ba, 0x0036, 0x2029, - 0x0002, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, - 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xce3d, 0x0198, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, - 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6dcb, 0x2f48, 0x0cb0, - 0xab82, 0x080c, 0x6dcb, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, - 0x0130, 0xa803, 0x0000, 0x080c, 0x6dcb, 0x2f48, 0x0cb8, 0x080c, - 0x6dcb, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, - 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, - 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, - 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, - 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, - 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, - 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, - 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2, - 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xce2d, 0x2001, - 0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, - 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, - 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, - 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x009e, - 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, - 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, - 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, - 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, - 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, - 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, - 0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335, 0x080c, 0x98e7, - 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, - 0xd0cc, 0x0118, 0x080c, 0xd179, 0x0030, 0x080c, 0xeb9d, 0x080c, - 0x88eb, 0x080c, 0xb0e7, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, - 0x000f, 0x0002, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d2, - 0xe9d2, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0, - 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, - 0x9084, 0x000f, 0x0002, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, - 0xe9e9, 0xe9f6, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, - 0xe9e9, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, - 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x0005, 0x0096, 0x00c6, - 0x2260, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, - 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, - 0x1904, 0xea4f, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, - 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186, - 0x0002, 0x1904, 0xeac6, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, - 0x0007, 0x190c, 0x0dc5, 0x0804, 0xeac6, 0x2048, 0x080c, 0xce3f, - 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, - 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, - 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, - 0xe30e, 0x0804, 0xeac6, 0x2009, 0x0041, 0x0804, 0xeac0, 0x9186, - 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, - 0x009e, 0x0804, 0xe9e9, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5, - 0x0804, 0xea0a, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x9335, - 0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, - 0x9186, 0x0004, 0x1904, 0xeac6, 0x6814, 0x2048, 0xa97c, 0xc1f4, - 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, - 0x080c, 0x1768, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, - 0x100e, 0x090c, 0x0dc5, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, - 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, - 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, - 0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, - 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6dcb, 0x2019, - 0x0045, 0x6008, 0x2068, 0x080c, 0xe4ba, 0x2d00, 0x600a, 0x6023, - 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, - 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe30e, 0x00ce, 0x00de, - 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, - 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x97db, 0x0036, - 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x009e, - 0x003e, 0x080c, 0x98e7, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, - 0xb181, 0x0005, 0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, - 0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0x080c, - 0x0dc5, 0x080c, 0x97db, 0x6003, 0x000c, 0x080c, 0x98e7, 0x0005, - 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, - 0xb181, 0x0005, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb19, 0xeb39, - 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0x080c, - 0x0dc5, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01b0, 0x6003, 0x0001, - 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, - 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, - 0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x080c, 0xb0e7, 0x00de, - 0x0005, 0x080c, 0xb0e7, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c, - 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, - 0x0150, 0x2001, 0x1989, 0x2004, 0x6042, 0x2009, 0x1867, 0x210c, - 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128, - 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c, - 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, - 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, - 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, - 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff, - 0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, - 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x0010, 0x9cf0, 0x0003, 0x2e64, - 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, - 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, - 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, - 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, - 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, - 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, - 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1168, - 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, - 0x0006, 0x080c, 0xc0e7, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60b4, 0x080c, 0x3022, - 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5, - 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8, - 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038, - 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038, - 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a, - 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294, - 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060, - 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e, - 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90, - 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210, - 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210, - 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90, - 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, - 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, - 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e, - 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011, - 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be, - 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011, - 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9, - 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, - 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e, - 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c, - 0x6dcb, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, - 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, - 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, - 0x252c, 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, - 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, - 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, - 0x01d0, 0x080c, 0xe971, 0x01b8, 0x080c, 0xe981, 0x11a0, 0x6000, - 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c, - 0xd036, 0x1110, 0x080c, 0x3274, 0x080c, 0xd047, 0x1110, 0x080c, - 0xbacb, 0x080c, 0xb11a, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, - 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, - 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, - 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c, - 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd548, 0x0168, - 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, - 0x00be, 0x2021, 0x0004, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x000e, - 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xaa80, 0x080c, - 0xb11a, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, - 0x1cd0, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8, - 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, - 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, - 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40, - 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, - 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837, - 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118, - 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, - 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, - 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, - 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, - 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, - 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, - 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, - 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, - 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, - 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, - 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016, - 0x00ee, 0x000e, 0x012e, 0x0005, 0x0003, 0x000b, 0x07c8, 0x0000, - 0xc000, 0x0001, 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, - 0x0101, 0x0008, 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, - 0x580d, 0x000b, 0x79bd, 0x0003, 0x5103, 0x0003, 0x4c0a, 0x0003, - 0xbac0, 0x0009, 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, - 0x340a, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, - 0x2000, 0x0000, 0x167d, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, - 0x0000, 0x0007, 0x4028, 0x0000, 0x4047, 0x000a, 0x808c, 0x0008, - 0x0002, 0x0000, 0x0822, 0x0003, 0x4022, 0x0000, 0x0028, 0x000b, - 0x4122, 0x0008, 0x94c0, 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009, - 0x0500, 0x0008, 0x0aa8, 0x0003, 0x4447, 0x0002, 0x0ea5, 0x0003, - 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x1283, 0x0003, 0x0ca0, 0x0001, - 0x1283, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, - 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, - 0x4436, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, - 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, - 0x443e, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0e80, 0x000b, - 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0e80, 0x000b, - 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x444d, 0x000b, - 0x0240, 0x0002, 0x0a7d, 0x000b, 0x00fe, 0x0000, 0x3280, 0x000b, - 0x0248, 0x000a, 0x085c, 0x0003, 0x9180, 0x0001, 0x0006, 0x0008, - 0x7f62, 0x0008, 0x8002, 0x0008, 0x0003, 0x0008, 0x8066, 0x0000, - 0x020a, 0x0000, 0x445b, 0x0003, 0x112a, 0x0000, 0x002e, 0x0008, - 0x022c, 0x0008, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, - 0x0002, 0x0000, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, - 0x8066, 0x0000, 0x0011, 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008, - 0x42e0, 0x0009, 0x0e71, 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001, - 0x0e71, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, - 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, - 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, - 0x447a, 0x0003, 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, - 0x8062, 0x0008, 0x0002, 0x0000, 0x5880, 0x000b, 0x8066, 0x0000, - 0x3679, 0x0000, 0x4483, 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008, - 0x7f4f, 0x0002, 0x088a, 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c, - 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010, 0x0008, - 0x1efe, 0x0000, 0x300a, 0x000b, 0x00dd, 0x0004, 0x000a, 0x000b, - 0x00fe, 0x0000, 0x349a, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, - 0x0007, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x4499, 0x000b, - 0x03fe, 0x0000, 0x04d0, 0x0001, 0x0cd1, 0x000b, 0x82c0, 0x0001, - 0x1f00, 0x0000, 0xffa0, 0x0001, 0x0400, 0x0000, 0x08af, 0x0003, - 0x14d9, 0x0003, 0x01fe, 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000, - 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x0690, 0x0001, - 0x10af, 0x0003, 0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008, - 0x08d1, 0x0003, 0xb9c0, 0x0009, 0x0030, 0x0008, 0x0cc0, 0x000b, - 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, 0x0008, 0x1a0b, 0x0001, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, 0x0000, 0x44b9, 0x0003, - 0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x040a, 0x0000, 0x44bf, 0x0003, 0x00fe, 0x0000, 0x34c7, 0x000b, - 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002, 0x08c2, 0x000b, - 0x00cb, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008, 0x3945, 0x000a, - 0x08c7, 0x000b, 0x3946, 0x000a, 0x0cd8, 0x000b, 0x0000, 0x0007, - 0x3943, 0x000a, 0x08d8, 0x0003, 0x00cb, 0x0003, 0x00fe, 0x0000, - 0x34d6, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x00d8, 0x000b, - 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f, 0x86c0, 0x0009, - 0xfc00, 0x0008, 0x08d1, 0x0003, 0x00af, 0x000b, 0x1c60, 0x0000, - 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x44e1, 0x000b, - 0x58e2, 0x0003, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, - 0x0cf0, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, - 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000, 0x0d06, 0x0000, - 0x0d08, 0x0008, 0x00f4, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008, - 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a, 0x08f7, 0x000b, - 0x0d4a, 0x0008, 0x58f7, 0x000b, 0x3efe, 0x0008, 0x7f4f, 0x0002, - 0x08fe, 0x000b, 0x8000, 0x0000, 0x0001, 0x0000, 0x0092, 0x000c, - 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008, - 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008, - 0x2b24, 0x0008, 0x5907, 0x0003, 0x8054, 0x0008, 0x0002, 0x0000, - 0x1242, 0x0002, 0x0955, 0x000b, 0x3a45, 0x000a, 0x0944, 0x000b, - 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a, 0x0914, 0x000b, - 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000, - 0x093f, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x451d, 0x0003, - 0x00fe, 0x0000, 0x353c, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008, - 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4525, 0x000b, - 0x00fe, 0x0000, 0x3258, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, - 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, - 0x452e, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, - 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, - 0x8066, 0x0000, 0x0009, 0x0008, 0x4538, 0x000b, 0x003a, 0x0008, - 0x1dfe, 0x0000, 0x0119, 0x000b, 0x0036, 0x0008, 0x00dd, 0x0004, - 0x0155, 0x0003, 0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000, - 0x2000, 0x0000, 0x0155, 0x0003, 0x3a44, 0x0002, 0x0a86, 0x0003, - 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000, - 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3655, 0x000b, 0x26fe, 0x0008, - 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009, - 0x0d67, 0x000b, 0x8074, 0x0000, 0x4040, 0x0008, 0x5955, 0x000b, - 0x5103, 0x0003, 0x3a46, 0x000a, 0x0d67, 0x000b, 0x3a47, 0x0002, - 0x0962, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, - 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x01b1, 0x0003, - 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, - 0x0e4f, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, - 0x8066, 0x0000, 0x362a, 0x0000, 0x456c, 0x0003, 0x2000, 0x0000, - 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000, - 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000, - 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000, - 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000, - 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000, - 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000, - 0x4586, 0x000b, 0x92c0, 0x0009, 0x0780, 0x0008, 0x0e6b, 0x000b, - 0x124b, 0x0002, 0x098f, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, - 0x0a55, 0x000b, 0x3a46, 0x000a, 0x0d9f, 0x0003, 0x5991, 0x0003, - 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a, 0x09ad, 0x0003, - 0x8010, 0x0008, 0x000d, 0x0000, 0x0230, 0x000c, 0x1948, 0x000a, - 0x099c, 0x000b, 0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c, - 0x01ad, 0x000b, 0x1948, 0x000a, 0x09a3, 0x000b, 0x1243, 0x000a, - 0x0a58, 0x0003, 0x194d, 0x000a, 0x09a7, 0x0003, 0x1243, 0x000a, - 0x0a5f, 0x000b, 0x59a7, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, - 0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000, - 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, - 0x3a42, 0x0002, 0x0db7, 0x0003, 0x15fe, 0x0008, 0x3461, 0x000b, - 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008, - 0x000c, 0x0008, 0x0230, 0x000c, 0x000a, 0x000b, 0xbbe0, 0x0009, - 0x0030, 0x0008, 0x0dcd, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, - 0x09ca, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x09ca, 0x000b, - 0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x021d, 0x0003, - 0x8076, 0x0008, 0x0041, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009, - 0x0032, 0x0000, 0x0dd2, 0x0003, 0x3c1e, 0x0008, 0x021d, 0x0003, - 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dd7, 0x0003, 0x3c20, 0x0000, - 0x021d, 0x0003, 0xbbe0, 0x0009, 0x0035, 0x0008, 0x0ddd, 0x0003, - 0x8072, 0x0000, 0x8000, 0x0000, 0x0399, 0x000b, 0xbbe0, 0x0009, - 0x0036, 0x0008, 0x0aba, 0x0003, 0xbbe0, 0x0009, 0x0037, 0x0000, - 0x0dfe, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0dca, 0x0003, - 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, - 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008, - 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000, - 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x45f5, 0x0003, - 0x0225, 0x0004, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, - 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000, 0x01b1, 0x0003, - 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e10, 0x000b, 0x18fe, 0x0000, - 0x3ce0, 0x0009, 0x0a0d, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, - 0x0dc6, 0x0003, 0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, - 0x8072, 0x0000, 0x8000, 0x0000, 0x027d, 0x0003, 0x8076, 0x0008, - 0x0042, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009, 0x0016, 0x0000, - 0x0e1d, 0x0003, 0x8074, 0x0000, 0x0808, 0x0008, 0x3a44, 0x0002, - 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, - 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, - 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, - 0xbc80, 0x0001, 0x0007, 0x0000, 0x0229, 0x000b, 0x1930, 0x000a, - 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, - 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, - 0x462e, 0x0003, 0x4000, 0x000f, 0x2233, 0x000b, 0x0870, 0x0008, - 0x4000, 0x000f, 0x7e30, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, - 0x0e30, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a41, 0x000b, - 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a41, 0x000b, 0x0220, 0x0004, - 0x8076, 0x0008, 0x0040, 0x0000, 0x0243, 0x000b, 0x8076, 0x0008, - 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0230, 0x0003, - 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4c, 0x0003, 0x8074, 0x0000, - 0x0706, 0x0000, 0x024e, 0x0003, 0x8074, 0x0000, 0x0703, 0x0000, - 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x028b, 0x0003, - 0x8010, 0x0008, 0x0008, 0x0000, 0x028b, 0x0003, 0x8010, 0x0008, - 0x0022, 0x0008, 0x028b, 0x0003, 0x0225, 0x0004, 0x8010, 0x0008, - 0x0007, 0x0000, 0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c, - 0x0297, 0x000b, 0x0225, 0x0004, 0x8010, 0x0008, 0x001b, 0x0008, - 0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000, - 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, - 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008, 0x028b, 0x0003, - 0x8010, 0x0008, 0x0005, 0x0008, 0x028b, 0x0003, 0x1648, 0x000a, - 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, - 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003, 0x3a44, 0x0002, - 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028b, 0x0003, 0x8010, 0x0008, - 0x0003, 0x0008, 0x028f, 0x000b, 0x8010, 0x0008, 0x000b, 0x0000, - 0x028f, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000, 0x028f, 0x000b, - 0x3a47, 0x0002, 0x0d55, 0x0003, 0x8010, 0x0008, 0x0006, 0x0008, - 0x028f, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, - 0x3000, 0x0008, 0x0230, 0x000c, 0x0246, 0x0004, 0x3a40, 0x000a, - 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008, 0x0230, 0x000c, - 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, - 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, - 0x0aa2, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, - 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, - 0x0c0a, 0x000b, 0x0280, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, - 0x4447, 0x0002, 0x0ace, 0x0003, 0xc0c0, 0x0001, 0x00ff, 0x0008, - 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea5, 0x0003, 0xc1e0, 0x0001, - 0xffff, 0x0008, 0x0ea5, 0x0003, 0x8010, 0x0008, 0x0013, 0x0000, - 0x0230, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008, 0x000a, 0x000b, - 0x3a40, 0x000a, 0x0ecb, 0x000b, 0x8074, 0x0000, 0x0200, 0x0000, - 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, - 0x43e0, 0x0001, 0x0ec9, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, - 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa5, 0x000b, 0x0d08, 0x0008, - 0x031e, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, - 0x03a2, 0x000c, 0x808c, 0x0008, 0x0001, 0x0000, 0x04fe, 0x0008, - 0x3385, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, - 0x8066, 0x0000, 0x0009, 0x0008, 0x46d8, 0x0003, 0x0004, 0x0000, - 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0x80e0, 0x0001, - 0x0004, 0x0000, 0x0af2, 0x0003, 0x80e0, 0x0001, 0x0005, 0x0008, - 0x0af2, 0x0003, 0x80e0, 0x0001, 0x0006, 0x0008, 0x0af2, 0x0003, - 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x82e0, 0x0009, - 0x0600, 0x0008, 0x0af2, 0x0003, 0x82e0, 0x0009, 0x0500, 0x0008, - 0x0af2, 0x0003, 0x82e0, 0x0009, 0x0400, 0x0000, 0x0f85, 0x0003, - 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009, 0x1000, 0x0000, - 0x0b1e, 0x0003, 0x0393, 0x0004, 0x3941, 0x0002, 0x0afd, 0x0003, - 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0460, 0x0000, - 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x2209, 0x0008, 0x4703, 0x000b, 0x11fe, 0x0000, 0x3319, 0x0003, - 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x470d, 0x0003, - 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x03e0, 0x0009, - 0x0f16, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, - 0x9180, 0x0001, 0x0003, 0x0008, 0x0300, 0x000b, 0x8072, 0x0000, - 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000, 0x0376, 0x0003, - 0x0393, 0x0004, 0x3941, 0x0002, 0x0b24, 0x0003, 0x8072, 0x0000, - 0x0400, 0x0000, 0x000a, 0x000b, 0x035b, 0x000c, 0x11fe, 0x0000, - 0x372c, 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008, - 0x000e, 0x0000, 0x0376, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, - 0x04fe, 0x0008, 0x3741, 0x0003, 0x808c, 0x0008, 0x0000, 0x0008, - 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x0009, 0x0008, 0x4737, 0x0003, 0x0060, 0x0008, 0x8062, 0x0008, - 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0008, 0x8066, 0x0000, - 0x0412, 0x0000, 0x473f, 0x000b, 0x0358, 0x0003, 0x808c, 0x0008, - 0x0001, 0x0000, 0x0460, 0x0000, 0x8062, 0x0008, 0x002b, 0x0008, - 0x8066, 0x0000, 0x0609, 0x0008, 0x4748, 0x000b, 0x8066, 0x0000, - 0x220a, 0x0008, 0x474b, 0x000b, 0x42fe, 0x0000, 0xffc0, 0x0001, - 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, - 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x041a, 0x0008, 0x4757, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, - 0x0046, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x1362, 0x0008, - 0x8066, 0x0000, 0x0411, 0x0000, 0x4760, 0x000b, 0x02fe, 0x0008, - 0x03e0, 0x0009, 0x0f66, 0x000b, 0x0d22, 0x0000, 0x4000, 0x000f, - 0x8280, 0x0009, 0x0002, 0x0000, 0x1380, 0x0001, 0x7f62, 0x0008, - 0x8066, 0x0000, 0x2209, 0x0008, 0x476c, 0x000b, 0x0200, 0x000a, - 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, 0x0000, 0x1362, 0x0008, - 0x8066, 0x0000, 0x060a, 0x0008, 0x4774, 0x000b, 0x4000, 0x000f, - 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, 0x000a, 0x2f44, 0x000a, - 0x0e80, 0x000b, 0x808a, 0x0008, 0x0003, 0x0008, 0x8074, 0x0000, - 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x5b81, 0x0003, - 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x3a44, 0x0002, - 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, - 0x0011, 0x0008, 0x0230, 0x000c, 0x42fe, 0x0000, 0xffc0, 0x0001, - 0x00ff, 0x0008, 0x7f10, 0x0008, 0x0230, 0x000c, 0x4310, 0x0008, - 0x028f, 0x000b, 0x3941, 0x0002, 0x0b96, 0x0003, 0x4000, 0x000f, - 0x8072, 0x0000, 0x0404, 0x0008, 0x4000, 0x000f, 0x8010, 0x0008, - 0x0012, 0x0008, 0x0230, 0x000c, 0x035b, 0x000c, 0x1110, 0x0000, - 0x0230, 0x000c, 0x11fe, 0x0000, 0x379c, 0x0003, 0x000a, 0x000b, - 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0xc3c0, 0x0001, - 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bc7, 0x000b, 0x0d0a, 0x0000, - 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8060, 0x0000, - 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x0000, 0x47b1, 0x000b, - 0x04fe, 0x0008, 0x33c0, 0x000b, 0x0460, 0x0000, 0x8062, 0x0008, - 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x0000, 0x47b9, 0x0003, - 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc0, 0x000b, 0x02fe, 0x0008, - 0x43e0, 0x0001, 0x0bc6, 0x0003, 0x0500, 0x0002, 0x7f0a, 0x0000, - 0xffe0, 0x0009, 0x0800, 0x0000, 0x0faa, 0x000b, 0x0d08, 0x0008, - 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, 0x0001, 0xffc0, 0x0001, - 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x0809, 0x0000, 0x47cf, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000, - 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, 0x000a, 0x7f60, 0x000a, - 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, - 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, 0x0009, 0x1000, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47e1, 0x000b, - 0x4000, 0x000f, 0xb10e, 0xebeb, 0x0001, 0x0002, 0x0004, 0x0008, - 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, - 0x1000, 0x2000, 0x4000, 0x8000, 0x393e + 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, + 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdce1, + 0x00de, 0x0005, 0x00d6, 0x080c, 0xdcee, 0x1520, 0x680c, 0x908c, + 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, + 0xd1e4, 0x0130, 0x9006, 0x080c, 0xed6f, 0x2009, 0x0001, 0x0078, + 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2894, + 0x1148, 0x2001, 0x0001, 0x080c, 0xed6f, 0x2110, 0x900e, 0x080c, + 0x328f, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, + 0x00b6, 0x00c6, 0x080c, 0xb153, 0x05a8, 0x0016, 0x0026, 0x00c6, + 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1578, + 0x080c, 0x66b2, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, + 0x2b00, 0x6012, 0x080c, 0xeba1, 0x11d8, 0x080c, 0x336a, 0x11c0, + 0x080c, 0xdc49, 0x0510, 0x2001, 0x0007, 0x080c, 0x6663, 0x2001, + 0x0007, 0x080c, 0x668f, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010, + 0x080c, 0xb101, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, + 0xb101, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb101, 0x9006, + 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, + 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, + 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, + 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, + 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, + 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, + 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde50, + 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186, + 0x0016, 0x1148, 0x080c, 0xd587, 0x0128, 0x6000, 0x9086, 0x0002, + 0x0904, 0xbb29, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001, + 0x0007, 0x080c, 0x668f, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0xdd7a, 0xdd7c, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7c, + 0xdd8b, 0xde49, 0xddcf, 0xde49, 0xddf7, 0xde49, 0xdd8b, 0xde49, + 0xde41, 0xde49, 0xde41, 0xde49, 0xde49, 0xdd7a, 0xdd7a, 0xdd7a, + 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, + 0xdd7c, 0xdd7a, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xdd7a, 0xde46, + 0xde49, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a, + 0xde49, 0xde49, 0xdd7a, 0xdd86, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, + 0xde45, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a, 0xdd7a, + 0xdd7a, 0xdd7a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xd579, + 0x6003, 0x0002, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x9006, 0x080c, + 0x664f, 0x0804, 0xde49, 0x080c, 0x6a8a, 0x1904, 0xde49, 0x9006, + 0x080c, 0x664f, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, + 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0904, 0xde49, 0x080c, 0x339b, + 0x1904, 0xde49, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, + 0x0002, 0x080c, 0x6663, 0x080c, 0x97e1, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x6110, + 0x2158, 0x2009, 0x0001, 0x080c, 0x8717, 0x0804, 0xde4f, 0x6610, + 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, + 0x9686, 0x0004, 0x0130, 0x080c, 0x8efa, 0x2001, 0x0004, 0x080c, + 0x668f, 0x080c, 0xedbe, 0x0904, 0xde49, 0x080c, 0x97e1, 0x2001, + 0x0004, 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, + 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4da0, 0x004e, 0x003e, + 0x2001, 0x0006, 0x080c, 0xde6d, 0x6610, 0x2658, 0xbe04, 0x0066, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, + 0x0006, 0x080c, 0x668f, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, + 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x6663, 0x080c, + 0x6a8a, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, + 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddb7, 0x2001, 0x0004, + 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, + 0x668f, 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x2600, 0x0002, 0xde64, 0xde64, 0xde64, 0xde64, 0xde64, 0xde66, + 0xde64, 0xde66, 0xde64, 0xde64, 0xde66, 0xde64, 0xde64, 0xde64, + 0xde66, 0xde66, 0xde66, 0xde66, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x0016, 0x00b6, 0x00d6, + 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x6663, 0x9006, + 0x080c, 0x664f, 0x080c, 0x326f, 0x00de, 0x00be, 0x001e, 0x0005, + 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, + 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, + 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbcb, 0xbbcb, 0xbbcb, + 0xbbcb, 0xdf02, 0xbbcb, 0xdeec, 0xdead, 0xbbcb, 0xbbcb, 0xbbcb, + 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xdf02, 0xbbcb, 0xdeec, + 0xdef3, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0x00f6, 0x080c, 0x6a8a, + 0x11d8, 0x080c, 0xd561, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8c0, + 0x9005, 0x0190, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, + 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9383, 0x080c, 0x98ed, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2894, 0x11b0, 0x080c, 0x671d, 0x0118, 0x080c, + 0xb101, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8c0, 0x0006, + 0x080c, 0x6141, 0x000e, 0xb8c2, 0x000e, 0xb816, 0x000e, 0xb812, + 0x080c, 0xb101, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, + 0x080c, 0xb101, 0x0005, 0x080c, 0xbf5a, 0x1148, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010, 0x080c, + 0xb101, 0x0005, 0x0804, 0xb101, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, + 0x9182, 0x0040, 0x0002, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf29, + 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, + 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0x080c, + 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, + 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, + 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf8f, 0x080c, 0xed63, 0x1170, + 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, + 0x891c, 0x0020, 0x9026, 0x080c, 0xebe6, 0x0c38, 0x080c, 0x100e, + 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, + 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, + 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, + 0x0000, 0xa887, 0x0036, 0x080c, 0x6dd1, 0x001e, 0x080c, 0xed63, + 0x1904, 0xdfef, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, + 0xe915, 0x0804, 0xdfef, 0x9486, 0x0200, 0x1120, 0x080c, 0xe8ac, + 0x0804, 0xdfef, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, + 0xdfef, 0x2019, 0x0002, 0x080c, 0xe8c7, 0x0804, 0xdfef, 0x2069, + 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe059, 0x9284, 0x0300, 0x1904, + 0xe052, 0x6804, 0x9005, 0x0904, 0xe03a, 0x2d78, 0x6003, 0x0007, + 0x080c, 0x1027, 0x0904, 0xdffb, 0x7800, 0xd08c, 0x1118, 0x7804, + 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, + 0x1904, 0xe05d, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, + 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, + 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, + 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xdff7, + 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, + 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, + 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, + 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6dd1, 0x002e, + 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, + 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, + 0x080c, 0x100e, 0x1904, 0xdfa4, 0x6017, 0xf100, 0x6003, 0x0001, + 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c00, 0x2069, + 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, + 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, + 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x0804, 0xdfef, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, + 0x8049, 0x080c, 0x4be9, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x0804, 0xdfef, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, + 0xe00f, 0x6017, 0xf200, 0x0804, 0xe00f, 0xa867, 0x0146, 0xa86b, + 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, + 0x9080, 0xdff7, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, + 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, + 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, + 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, + 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, 0x821c, 0x2001, + 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, + 0x2011, 0xe0d9, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, + 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, + 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, + 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, + 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, + 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1040, 0x0cc8, + 0x080c, 0x1040, 0x0804, 0xdffb, 0x2548, 0x8847, 0x9885, 0x0046, + 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe948, 0x0804, + 0xdfef, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, + 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, + 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, 0x2008, 0x0804, + 0xe168, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xd587, 0x0500, + 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1b1, 0x9186, 0x0027, + 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, + 0x0dc5, 0x080c, 0xd587, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, + 0x0dc5, 0x0804, 0xe294, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, + 0x080c, 0xb19b, 0x0005, 0xe12f, 0xe131, 0xe131, 0xe158, 0xe12f, + 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, + 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0x080c, + 0x0dc5, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x0036, 0x0096, 0x6014, + 0x904d, 0x01d8, 0x080c, 0xce56, 0x01c0, 0x6003, 0x0002, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, + 0x080c, 0xe948, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, + 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, + 0x0096, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x080c, 0xce56, 0x0120, + 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb134, 0x009e, 0x0005, + 0x0002, 0xe17d, 0xe194, 0xe17f, 0xe1ab, 0xe17d, 0xe17d, 0xe17d, + 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, + 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0x080c, 0x0dc5, 0x0096, + 0x080c, 0x97e1, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, + 0x0007, 0x2009, 0x0043, 0x080c, 0xb180, 0x0010, 0x6003, 0x0004, + 0x080c, 0x98ed, 0x009e, 0x0005, 0x080c, 0x97e1, 0x080c, 0xce56, + 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, + 0x080c, 0x88f1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xebaa, 0x0db0, 0x0cc8, 0x080c, 0x97e1, 0x2009, 0x0041, 0x0804, + 0xe31c, 0x9182, 0x0040, 0x0002, 0xe1c8, 0xe1ca, 0xe1c8, 0xe1c8, + 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, + 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1cb, 0xe1c8, 0xe1c8, + 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88f1, 0x00de, 0x080c, + 0xec02, 0x080c, 0xb101, 0x0005, 0x9182, 0x0040, 0x0002, 0xe1eb, + 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, + 0xe1ed, 0xe25c, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe25c, 0xe1eb, + 0xe1eb, 0xe1eb, 0xe1eb, 0x080c, 0x0dc5, 0x2001, 0x0105, 0x2004, + 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, + 0x2004, 0x9105, 0x1904, 0xe25c, 0x2009, 0x180c, 0x2104, 0xd0d4, + 0x0904, 0xe25c, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, + 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, 0x2004, 0xd0e4, + 0x1528, 0x603b, 0x0000, 0x080c, 0x989d, 0x6014, 0x0096, 0x2048, + 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, + 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x9a0f, 0x2009, + 0x0041, 0x009e, 0x0804, 0xe31c, 0x080c, 0x9a0f, 0x6003, 0x0007, + 0x601b, 0x0000, 0x080c, 0x88f1, 0x009e, 0x0005, 0x2001, 0x0100, + 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, + 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, + 0x080c, 0x2c94, 0x080c, 0x9a0f, 0x6014, 0x2048, 0xa97c, 0xd1ec, + 0x1130, 0x080c, 0x88f1, 0x080c, 0xb101, 0x009e, 0x0005, 0x080c, + 0xebaa, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, + 0x2102, 0x0036, 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6014, 0x0096, + 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, + 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, + 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, + 0x0080, 0x2019, 0x0004, 0x080c, 0xe948, 0x6018, 0x9005, 0x1128, + 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, + 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe2ab, + 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ad, + 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, + 0xe2ab, 0xe2ab, 0xe2f8, 0x080c, 0x0dc5, 0x6014, 0x0096, 0x2048, + 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, + 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, + 0x009e, 0x0804, 0xe31c, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, + 0x88f1, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, + 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, + 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, + 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, + 0x080c, 0x88f3, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, + 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005, + 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, + 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005, 0xd2fc, 0x0140, 0x8002, + 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, + 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, + 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x6024, + 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe340, 0xe34c, 0xe358, 0xe364, + 0xe340, 0xe340, 0xe340, 0xe340, 0xe347, 0xe342, 0xe342, 0xe340, + 0xe340, 0xe340, 0xe340, 0xe342, 0xe340, 0xe342, 0xe340, 0xe347, + 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0x6014, + 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, + 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, + 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, + 0x080c, 0x98ed, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, + 0x080c, 0x1c09, 0x0126, 0x2091, 0x8000, 0x080c, 0x93a0, 0x080c, + 0x9a0f, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, + 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe393, + 0xe395, 0xe3a7, 0xe3c1, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, + 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, + 0xe393, 0xe393, 0xe393, 0x080c, 0x0dc5, 0x6014, 0x2048, 0xa87c, + 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, + 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0470, 0x6014, + 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, + 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe948, + 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, + 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x97e1, + 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xed00, 0x0036, + 0x2019, 0x0029, 0x080c, 0xe948, 0x003e, 0x009e, 0x080c, 0xb134, + 0x080c, 0x98ed, 0x0005, 0x080c, 0x989d, 0x6114, 0x81ff, 0x0158, + 0x0096, 0x2148, 0x080c, 0xed00, 0x0036, 0x2019, 0x0029, 0x080c, + 0xe948, 0x003e, 0x009e, 0x080c, 0xb134, 0x080c, 0x9a0f, 0x0005, + 0x9182, 0x0085, 0x0002, 0xe412, 0xe410, 0xe410, 0xe41e, 0xe410, + 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, + 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, 0x933b, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x0026, 0x00e6, + 0x080c, 0xeba1, 0x0118, 0x080c, 0xb101, 0x0450, 0x2071, 0x0260, + 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, + 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, + 0xb423, 0x7220, 0x080c, 0xe79d, 0x0118, 0x6007, 0x0086, 0x0040, + 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, + 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x080c, 0x9a0f, + 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, + 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082, + 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, + 0x080c, 0xb19b, 0x0050, 0x2001, 0x0007, 0x080c, 0x668f, 0x080c, + 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0xe483, 0xe485, + 0xe485, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, + 0xe483, 0xe483, 0xe483, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c, + 0xb134, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dc5, + 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, 0x0002, 0xe4a4, + 0xe4a4, 0xe4a4, 0xe4a6, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, + 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0x080c, 0x0dc5, 0x0005, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0x0036, 0x080c, 0xec02, 0x6043, 0x0000, 0x2019, + 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, + 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, + 0x080c, 0xa929, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, + 0xa9d4, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, + 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, + 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007, 0x6014, + 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0xe948, 0x009e, 0x6017, + 0x0000, 0x080c, 0xec02, 0x6023, 0x0007, 0x080c, 0xd579, 0x003e, + 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, + 0x0260, 0x7938, 0x783c, 0x080c, 0x2894, 0x1904, 0xe558, 0x0016, + 0x00c6, 0x080c, 0x671d, 0x1904, 0xe556, 0x001e, 0x00c6, 0x080c, + 0xd561, 0x1130, 0xb8c0, 0x9005, 0x0118, 0x080c, 0x339b, 0x0148, + 0x2b10, 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xd568, 0x000e, + 0x6012, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, + 0xaa9a, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x007e, + 0x001e, 0x0076, 0x903e, 0x080c, 0xe690, 0x007e, 0x0026, 0xba04, + 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, + 0x1118, 0xbaa0, 0x080c, 0x3304, 0x002e, 0xbcc0, 0x001e, 0x080c, + 0x6141, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, 0x001e, + 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, + 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, 0x1904, + 0xe5b7, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, + 0x9184, 0x8000, 0x0904, 0xe5b4, 0x2001, 0x197d, 0x2004, 0x9005, + 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, 0x0800, + 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed68, 0x0118, + 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, + 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, + 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, + 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, + 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, + 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, + 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, + 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, + 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, + 0x9286, 0x0004, 0x0120, 0x080c, 0x672c, 0x0804, 0xe61f, 0x2011, + 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, + 0xc0f7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7, 0x009e, 0x1548, 0x0046, + 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, + 0x0138, 0x2009, 0x0029, 0x080c, 0xe9a5, 0xb800, 0xc0e5, 0xb802, + 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000, 0x080c, + 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x2001, 0x0007, 0x080c, + 0x668f, 0x2001, 0x0007, 0x080c, 0x6663, 0x001e, 0x004e, 0x9006, + 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, + 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, + 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, + 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2894, 0x11d0, + 0x080c, 0x671d, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011, + 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, + 0xc0f7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, + 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x11d0, 0x080c, + 0x671d, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, + 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011, 0x027a, + 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7, + 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, + 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, + 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c, 0x2021, + 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, + 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128, 0x8001, + 0x9602, 0x1a04, 0xe72e, 0x0018, 0x9606, 0x0904, 0xe72e, 0x080c, + 0x8bc3, 0x0904, 0xe725, 0x2100, 0x9c06, 0x0904, 0xe725, 0x6720, + 0x9786, 0x0007, 0x0904, 0xe725, 0x080c, 0xe9e6, 0x1904, 0xe725, + 0x080c, 0xed86, 0x0904, 0xe725, 0x080c, 0xe9d6, 0x0904, 0xe725, + 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x339b, 0x0904, 0xe76d, + 0x6004, 0x9086, 0x0000, 0x1904, 0xe76d, 0x9786, 0x0004, 0x0904, + 0xe76d, 0x2500, 0x9c06, 0x0904, 0xe725, 0x2400, 0x9c06, 0x05e8, + 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, + 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786, 0x000a, + 0x0148, 0x080c, 0xd05e, 0x1130, 0x080c, 0xbae2, 0x009e, 0x080c, + 0xb134, 0x0418, 0x6014, 0x2048, 0x080c, 0xce56, 0x01d8, 0x9786, + 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, + 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, + 0x080c, 0xed00, 0x0016, 0x080c, 0xd14c, 0x080c, 0x6dc4, 0x001e, + 0x080c, 0xd041, 0x009e, 0x080c, 0xb134, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe6a4, 0x012e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, + 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xed00, + 0x080c, 0xe948, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009, 0x11f8, + 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, + 0x080c, 0x989d, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, 0x0118, + 0x6010, 0x080c, 0x6dd1, 0x009e, 0x00c6, 0x080c, 0xb101, 0x00ce, + 0x0036, 0x080c, 0x9a0f, 0x003e, 0x009e, 0x0804, 0xe725, 0x9786, + 0x000a, 0x0904, 0xe715, 0x0804, 0xe70a, 0x81ff, 0x0904, 0xe725, + 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, + 0x2004, 0x9086, 0x002d, 0x1904, 0xe725, 0x6000, 0x9086, 0x0002, + 0x1904, 0xe725, 0x080c, 0xd04d, 0x0138, 0x080c, 0xd05e, 0x1904, + 0xe725, 0x080c, 0xbae2, 0x0038, 0x080c, 0x326f, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134, 0x0804, 0xe725, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, + 0x2c08, 0x2170, 0x9006, 0x080c, 0xe96f, 0x001e, 0x0120, 0x6020, + 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe7bc, 0xe7bc, + 0xe7bc, 0xe7bc, 0xe7bc, 0xe7bc, 0xe7be, 0xe7bc, 0xe7bc, 0xe7bc, + 0xe7e7, 0xb134, 0xb134, 0xe7bc, 0x9006, 0x0005, 0x0036, 0x0046, + 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, + 0x0020, 0x080c, 0xe9a5, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, + 0xe4c8, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xce56, + 0x0140, 0x6014, 0x904d, 0x080c, 0xca71, 0x687b, 0x0005, 0x080c, + 0x6dd1, 0x009e, 0x080c, 0xb134, 0x9085, 0x0001, 0x0005, 0x0019, + 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, + 0x000b, 0x0005, 0xe802, 0xe802, 0xe819, 0xe809, 0xe828, 0xe802, + 0xe802, 0xe804, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802, + 0xe802, 0xe802, 0x080c, 0x0dc5, 0x080c, 0xb134, 0x9085, 0x0001, + 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1128, + 0x2019, 0x0001, 0x080c, 0xa877, 0x0010, 0x080c, 0xaa59, 0x00ee, + 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c, + 0x6dd1, 0x080c, 0xb134, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, + 0x601c, 0xd084, 0x190c, 0x1ab7, 0x0c60, 0x2001, 0x0001, 0x080c, + 0x664f, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e, + 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, + 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1cd0, + 0x2079, 0x0001, 0x8fff, 0x0904, 0xe89f, 0x2071, 0x1800, 0x7654, + 0x7074, 0x8001, 0x9602, 0x1a04, 0xe89f, 0x88ff, 0x0120, 0x2800, + 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe9d6, 0x0580, 0x2400, 0x9c06, + 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, + 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, + 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0120, 0x0046, 0x080c, 0xe948, + 0x004e, 0x009e, 0x080c, 0xb134, 0x88ff, 0x1198, 0x9ce0, 0x0018, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe852, 0x9006, + 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056, 0x0086, + 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, + 0x0096, 0x904e, 0x080c, 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, + 0xa9d4, 0x080c, 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x671d, 0x1180, 0x0056, + 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x005e, 0x003e, + 0x001e, 0x8108, 0x1f04, 0xe8d2, 0x0036, 0x2508, 0x2029, 0x0003, + 0x080c, 0xe843, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, + 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, + 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x2c20, 0x080c, + 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, + 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, + 0x0036, 0x080c, 0x671d, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, + 0x2021, 0x0001, 0x080c, 0xebe6, 0x004e, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x003e, 0x001e, + 0x8108, 0x1f04, 0xe91f, 0x0036, 0x2029, 0x0002, 0x080c, 0xe843, + 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, + 0x0016, 0x00f6, 0x080c, 0xce54, 0x0198, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, + 0xab82, 0x080c, 0x6dd1, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6dd1, + 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, + 0x080c, 0x6dd1, 0x2f48, 0x0cb8, 0x080c, 0x6dd1, 0x0c88, 0x00e6, + 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, + 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, + 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, + 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, + 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, + 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, + 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2, 0xa867, 0x010d, 0xa88e, + 0x0026, 0x2010, 0x080c, 0xce44, 0x2001, 0x0000, 0x0120, 0x2200, + 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, + 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, + 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6dd1, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, + 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, + 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, + 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, + 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, + 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x001e, 0x0005, 0xa001, + 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, + 0xd190, 0x0030, 0x080c, 0xec02, 0x080c, 0x88f1, 0x080c, 0xb101, + 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xea35, + 0xea35, 0xea35, 0xea37, 0xea35, 0xea37, 0xea37, 0xea35, 0xea37, + 0xea35, 0xea35, 0xea35, 0xea35, 0xea35, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, + 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea5b, 0xea4e, + 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0x6007, 0x003b, + 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xec02, + 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, + 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xeab4, 0x6814, + 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, + 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xeb2b, + 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0dc5, + 0x0804, 0xeb2b, 0x2048, 0x080c, 0xce56, 0x1130, 0x0028, 0x2048, + 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, + 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe31c, 0x0804, 0xeb2b, + 0x2009, 0x0041, 0x0804, 0xeb25, 0x9186, 0x0005, 0x15a0, 0x6814, + 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xea4e, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5, 0x0804, 0xea6f, 0x6007, + 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00c6, + 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, + 0xeb2b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, + 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, + 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x100e, 0x090c, 0x0dc5, + 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, + 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, + 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, + 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, + 0xa89f, 0x0001, 0x080c, 0x6dd1, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xe4c8, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, + 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, + 0x0007, 0x080c, 0xe31c, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, + 0x0027, 0x1178, 0x080c, 0x97e1, 0x0036, 0x0096, 0x6014, 0x2048, + 0x2019, 0x0004, 0x080c, 0xe948, 0x009e, 0x003e, 0x080c, 0x98ed, + 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb19b, 0x0005, 0xeb5e, + 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5e, 0xeb5c, 0xeb5c, + 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x6003, 0x000c, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220, + 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xb19b, 0x0005, 0xeb7c, + 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7e, 0xeb9e, 0xeb7c, 0xeb7c, 0xeb7c, + 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7c, 0x080c, 0x0dc5, 0x00d6, 0x2c68, + 0x080c, 0xb0ab, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, + 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, + 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x2d60, 0x080c, 0xb101, 0x00de, 0x0005, 0x080c, 0xb101, + 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, + 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, + 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989, + 0x2004, 0x6042, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, + 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, + 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004, + 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc, + 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, + 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, + 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, + 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x88f1, 0x080c, + 0xb101, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, + 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, + 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, + 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, + 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, + 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, + 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, + 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, + 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xc0f7, + 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x080c, 0x60ba, 0x080c, 0x3019, 0x00ee, 0x0005, 0x0096, + 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xa85c, 0x9080, 0x001a, + 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, + 0x0046, 0x1118, 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, + 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, + 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, + 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, + 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, + 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, + 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, + 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, + 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, + 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, + 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, + 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, + 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, + 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, + 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, + 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, + 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, + 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, + 0x0205, 0x2013, 0x0000, 0x002e, 0x080c, 0x6dd1, 0x009e, 0x0005, + 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, + 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, + 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, + 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021, 0x19f8, + 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, + 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, + 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe9d6, + 0x01b8, 0x080c, 0xe9e6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, + 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c, 0xd04d, 0x1110, 0x080c, + 0x326f, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134, + 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, + 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, + 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, + 0x0036, 0x0046, 0x080c, 0xd561, 0x0168, 0x2019, 0xffff, 0x9005, + 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, + 0x080c, 0x4da0, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, + 0x0001, 0x1128, 0x080c, 0xaa9a, 0x080c, 0xb134, 0x9006, 0x0005, + 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, + 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, + 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, + 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, + 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, + 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, + 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, + 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, + 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, + 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, + 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, + 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, + 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, + 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, + 0x0005, 0x0003, 0x000b, 0x07ce, 0x0000, 0xc000, 0x0001, 0x8064, + 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, + 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x79c0, + 0x0003, 0x5106, 0x0003, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, + 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, + 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x1680, + 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4028, + 0x0000, 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0822, + 0x0003, 0x4022, 0x0000, 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0, + 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009, 0x0500, 0x0008, 0x0aab, + 0x0003, 0x4447, 0x0002, 0x0ea8, 0x000b, 0x0bfe, 0x0008, 0x11a0, + 0x0001, 0x1286, 0x0003, 0x0ca0, 0x0001, 0x1286, 0x0003, 0x9180, + 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4436, 0x000b, 0x808c, + 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, + 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe, + 0x0000, 0x43e0, 0x0001, 0x0e83, 0x000b, 0xc2c0, 0x0009, 0x00ff, + 0x0008, 0x02e0, 0x0001, 0x0e83, 0x000b, 0x9180, 0x0001, 0x0005, + 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, + 0x0000, 0x0019, 0x0000, 0x444d, 0x000b, 0x0240, 0x0002, 0x0a80, + 0x0003, 0x00fe, 0x0000, 0x3283, 0x000b, 0x0248, 0x000a, 0x085c, + 0x0003, 0x9180, 0x0001, 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002, + 0x0008, 0x0003, 0x0008, 0x8066, 0x0000, 0x020a, 0x0000, 0x445b, + 0x0003, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, + 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, + 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, + 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e74, + 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0e74, 0x0003, 0x1734, + 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, + 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a, + 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, + 0x0000, 0x5880, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4483, + 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a, + 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0011, + 0x0008, 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, + 0x000b, 0x00e0, 0x000c, 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a, + 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, + 0x0000, 0x0231, 0x0008, 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0, + 0x0001, 0x0cd4, 0x000b, 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, + 0x0001, 0x0400, 0x0000, 0x08b2, 0x0003, 0x14dc, 0x0003, 0x01fe, + 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000, 0x8690, 0x0009, 0x0000, + 0x0008, 0x7f0c, 0x0000, 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, + 0x0008, 0x0680, 0x0009, 0x10b2, 0x0003, 0x7f08, 0x0008, 0x84c0, + 0x0001, 0xff00, 0x0008, 0x08d4, 0x0003, 0xb9c0, 0x0009, 0x0030, + 0x0008, 0x0cc3, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, + 0x0008, 0x1a0b, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, + 0x0000, 0x44bc, 0x0003, 0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x040a, 0x0000, 0x44c2, 0x0003, 0x00fe, + 0x0000, 0x34ca, 0x0003, 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, + 0x0002, 0x08c5, 0x0003, 0x00ce, 0x0003, 0x8072, 0x0000, 0x2020, + 0x0008, 0x3945, 0x000a, 0x08ca, 0x0003, 0x3946, 0x000a, 0x0cdb, + 0x000b, 0x0000, 0x0007, 0x3943, 0x000a, 0x08db, 0x0003, 0x00ce, + 0x0003, 0x00fe, 0x0000, 0x34d9, 0x000b, 0x8072, 0x0000, 0x1000, + 0x0000, 0x00db, 0x000b, 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, + 0x000f, 0x86c0, 0x0009, 0xfc00, 0x0008, 0x08d4, 0x0003, 0x00b2, + 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, + 0x0008, 0x44e4, 0x000b, 0x58e5, 0x000b, 0x0140, 0x0008, 0x0242, + 0x0000, 0x1f43, 0x0002, 0x0cf3, 0x000b, 0x0d44, 0x0000, 0x0d46, + 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, + 0x0000, 0x0d06, 0x0000, 0x0d08, 0x0008, 0x00f7, 0x0003, 0x0344, + 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, + 0x000a, 0x08fa, 0x0003, 0x0d4a, 0x0008, 0x58fa, 0x0003, 0x3efe, + 0x0008, 0x7f4f, 0x0002, 0x0901, 0x0003, 0x8000, 0x0000, 0x0001, + 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, + 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, + 0x0003, 0x2b24, 0x0008, 0x2b24, 0x0008, 0x590a, 0x000b, 0x8054, + 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x0958, 0x0003, 0x3a45, + 0x000a, 0x0947, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, + 0x000a, 0x0917, 0x000b, 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, + 0x000a, 0x7f3c, 0x0000, 0x0942, 0x000b, 0x1d00, 0x0002, 0x7f3a, + 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, + 0x0008, 0x4520, 0x000b, 0x00fe, 0x0000, 0x353f, 0x000b, 0x1c60, + 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, + 0x0008, 0x4528, 0x0003, 0x00fe, 0x0000, 0x325b, 0x000b, 0x0038, + 0x0000, 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, + 0x0000, 0x0009, 0x0008, 0x4531, 0x000b, 0x80c0, 0x0009, 0x00ff, + 0x0008, 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, + 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x453b, + 0x000b, 0x003a, 0x0008, 0x1dfe, 0x0000, 0x011c, 0x000b, 0x0036, + 0x0008, 0x00e0, 0x000c, 0x0158, 0x000b, 0x8074, 0x0000, 0x2000, + 0x0000, 0x8072, 0x0000, 0x2000, 0x0000, 0x0158, 0x000b, 0x3a44, + 0x0002, 0x0a89, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, + 0x0000, 0x1000, 0x0000, 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3658, + 0x0003, 0x26fe, 0x0008, 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, + 0x0008, 0x00d0, 0x0009, 0x0d6a, 0x0003, 0x8074, 0x0000, 0x4040, + 0x0008, 0x5958, 0x0003, 0x5106, 0x0003, 0x3a46, 0x000a, 0x0d6a, + 0x0003, 0x3a47, 0x0002, 0x0965, 0x000b, 0x8054, 0x0008, 0x0004, + 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x01b4, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, + 0x0003, 0x1246, 0x000a, 0x0e52, 0x000b, 0x1a60, 0x0000, 0x8062, + 0x0008, 0x0002, 0x0000, 0x8066, 0x0000, 0x362a, 0x0000, 0x456f, + 0x0003, 0x2000, 0x0000, 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, + 0x0000, 0x2204, 0x0000, 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, + 0x0000, 0x2408, 0x0000, 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, + 0x0000, 0x260c, 0x0000, 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, + 0x0000, 0x2810, 0x0000, 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, + 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, + 0x0000, 0x0052, 0x0000, 0x4589, 0x000b, 0x92c0, 0x0009, 0x0780, + 0x0008, 0x0e6e, 0x000b, 0x124b, 0x0002, 0x0992, 0x0003, 0x2e4d, + 0x0002, 0x2e4d, 0x0002, 0x0a58, 0x0003, 0x3a46, 0x000a, 0x0da2, + 0x000b, 0x5994, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, + 0x000a, 0x09b0, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0233, + 0x000c, 0x1948, 0x000a, 0x099f, 0x000b, 0x0228, 0x000c, 0x1810, + 0x0000, 0x0233, 0x000c, 0x01b0, 0x000b, 0x1948, 0x000a, 0x09a6, + 0x000b, 0x1243, 0x000a, 0x0a5b, 0x0003, 0x194d, 0x000a, 0x09aa, + 0x000b, 0x1243, 0x000a, 0x0a62, 0x0003, 0x59aa, 0x000b, 0x8054, + 0x0008, 0x0004, 0x0000, 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, + 0x000c, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, + 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0dba, 0x000b, 0x15fe, + 0x0008, 0x3461, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, + 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0233, 0x000c, 0x000a, + 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0dd0, 0x000b, 0x18fe, + 0x0000, 0x3ce0, 0x0009, 0x09cd, 0x0003, 0x15fe, 0x0008, 0x3ce0, + 0x0009, 0x09cd, 0x0003, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, + 0x0000, 0x0220, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0220, + 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0dd5, 0x000b, 0x3c1e, + 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dda, + 0x000b, 0x3c20, 0x0000, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0035, + 0x0008, 0x0de0, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x039c, + 0x000b, 0xbbe0, 0x0009, 0x0036, 0x0008, 0x0abd, 0x000b, 0xbbe0, + 0x0009, 0x0037, 0x0000, 0x0e01, 0x000b, 0x18fe, 0x0000, 0x3ce0, + 0x0009, 0x0dcd, 0x000b, 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, + 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, + 0x0008, 0x2706, 0x0008, 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, + 0x0000, 0x290a, 0x0000, 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, + 0x0000, 0x45f8, 0x000b, 0x0228, 0x000c, 0x8054, 0x0008, 0x0004, + 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, + 0x0000, 0x01b4, 0x0003, 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e13, + 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a10, 0x0003, 0x15fe, + 0x0008, 0x3ce0, 0x0009, 0x0dc9, 0x0003, 0x0223, 0x0004, 0x8076, + 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x0280, + 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0220, 0x000b, 0xbbe0, + 0x0009, 0x0016, 0x0000, 0x0e20, 0x000b, 0x8074, 0x0000, 0x0808, + 0x0008, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, + 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, + 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000, 0x022c, + 0x000b, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, + 0x0000, 0x000a, 0x0008, 0x4631, 0x000b, 0x4000, 0x000f, 0x2236, + 0x000b, 0x0870, 0x0008, 0x4000, 0x000f, 0x7e33, 0x000b, 0xbbe0, + 0x0009, 0x0030, 0x0008, 0x0e33, 0x0003, 0x18fe, 0x0000, 0x3ce0, + 0x0009, 0x0a44, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a44, + 0x000b, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0246, + 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, + 0x0000, 0x0233, 0x0003, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4f, + 0x0003, 0x8074, 0x0000, 0x0706, 0x0000, 0x0251, 0x000b, 0x8074, + 0x0000, 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, + 0x0000, 0x028e, 0x0003, 0x8010, 0x0008, 0x0008, 0x0000, 0x028e, + 0x0003, 0x8010, 0x0008, 0x0022, 0x0008, 0x028e, 0x0003, 0x0228, + 0x000c, 0x8010, 0x0008, 0x0007, 0x0000, 0x0233, 0x000c, 0x1810, + 0x0000, 0x0233, 0x000c, 0x029a, 0x0003, 0x0228, 0x000c, 0x8010, + 0x0008, 0x001b, 0x0008, 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, + 0x000c, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, + 0x0008, 0x028e, 0x0003, 0x8010, 0x0008, 0x0005, 0x0008, 0x028e, + 0x0003, 0x1648, 0x000a, 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, + 0x0000, 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, + 0x0003, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028e, + 0x0003, 0x8010, 0x0008, 0x0003, 0x0008, 0x0292, 0x000b, 0x8010, + 0x0008, 0x000b, 0x0000, 0x0292, 0x000b, 0x8010, 0x0008, 0x0002, + 0x0000, 0x0292, 0x000b, 0x3a47, 0x0002, 0x0d58, 0x000b, 0x8010, + 0x0008, 0x0006, 0x0008, 0x0292, 0x000b, 0x8074, 0x0000, 0xf000, + 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0233, 0x000c, 0x0249, + 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, + 0x0008, 0x0233, 0x000c, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, + 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, + 0x0002, 0x2e4d, 0x0002, 0x0aa5, 0x000b, 0x8054, 0x0008, 0x0019, + 0x0000, 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, + 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0283, 0x000b, 0x808c, + 0x0008, 0x0000, 0x0008, 0x4447, 0x0002, 0x0ad1, 0x000b, 0xc0c0, + 0x0001, 0x00ff, 0x0008, 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea8, + 0x000b, 0xc1e0, 0x0001, 0xffff, 0x0008, 0x0ea8, 0x000b, 0x8010, + 0x0008, 0x0013, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, 0x0202, + 0x0008, 0x000a, 0x000b, 0x3a40, 0x000a, 0x0ece, 0x000b, 0x8074, + 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0000, 0x43e0, 0x0001, 0x0ecc, 0x0003, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa8, + 0x0003, 0x0d08, 0x0008, 0x0321, 0x000b, 0x8072, 0x0000, 0x8000, + 0x0000, 0x000a, 0x000b, 0x03a5, 0x0004, 0x808c, 0x0008, 0x0001, + 0x0000, 0x04fe, 0x0008, 0x3388, 0x000b, 0x0460, 0x0000, 0x8062, + 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x46db, + 0x0003, 0x0004, 0x0000, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, + 0x0000, 0x80e0, 0x0001, 0x0004, 0x0000, 0x0af5, 0x000b, 0x80e0, + 0x0001, 0x0005, 0x0008, 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0006, + 0x0008, 0x0af5, 0x000b, 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, + 0x0008, 0x82e0, 0x0009, 0x0600, 0x0008, 0x0af5, 0x000b, 0x82e0, + 0x0009, 0x0500, 0x0008, 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0400, + 0x0000, 0x0f88, 0x000b, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, + 0x0009, 0x1000, 0x0000, 0x0b21, 0x0003, 0x0396, 0x0004, 0x3941, + 0x0002, 0x0b00, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, + 0x000b, 0x0460, 0x0000, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x4706, 0x000b, 0x11fe, + 0x0000, 0x331c, 0x0003, 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, + 0x0008, 0x4710, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, + 0x0008, 0x03e0, 0x0009, 0x0f19, 0x0003, 0x8072, 0x0000, 0x0400, + 0x0000, 0x0046, 0x0003, 0x9180, 0x0001, 0x0003, 0x0008, 0x0303, + 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, + 0x0000, 0x0379, 0x0003, 0x0396, 0x0004, 0x3941, 0x0002, 0x0b27, + 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x035e, + 0x000c, 0x11fe, 0x0000, 0x372f, 0x000b, 0x8072, 0x0000, 0x0400, + 0x0000, 0x8010, 0x0008, 0x000e, 0x0000, 0x0379, 0x0003, 0x8060, + 0x0000, 0x0400, 0x0000, 0x04fe, 0x0008, 0x3744, 0x0003, 0x808c, + 0x0008, 0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x473a, 0x000b, 0x0060, + 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, + 0x0008, 0x8066, 0x0000, 0x0412, 0x0000, 0x4742, 0x000b, 0x035b, + 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, 0x8062, + 0x0008, 0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x474b, + 0x000b, 0x8066, 0x0000, 0x220a, 0x0008, 0x474e, 0x000b, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, + 0x0000, 0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x041a, 0x0008, 0x475a, 0x000b, 0x8072, + 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, 0x0400, + 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, 0x4763, + 0x000b, 0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f69, 0x000b, 0x0d22, + 0x0000, 0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, 0x1380, + 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x476f, + 0x000b, 0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, + 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, 0x4777, + 0x000b, 0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, + 0x000a, 0x2f44, 0x000a, 0x0e83, 0x000b, 0x808a, 0x0008, 0x0003, + 0x0008, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x5b84, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, + 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, + 0x0008, 0x8010, 0x0008, 0x0011, 0x0008, 0x0233, 0x000c, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, 0x0233, + 0x000c, 0x4310, 0x0008, 0x0292, 0x000b, 0x3941, 0x0002, 0x0b99, + 0x0003, 0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, 0x4000, + 0x000f, 0x8010, 0x0008, 0x0012, 0x0008, 0x0233, 0x000c, 0x035e, + 0x000c, 0x1110, 0x0000, 0x0233, 0x000c, 0x11fe, 0x0000, 0x379f, + 0x0003, 0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, + 0x0000, 0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bca, + 0x0003, 0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, + 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, + 0x0000, 0x47b4, 0x000b, 0x04fe, 0x0008, 0x33c3, 0x000b, 0x0460, + 0x0000, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, + 0x0000, 0x47bc, 0x0003, 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc3, + 0x000b, 0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bc9, 0x0003, 0x0500, + 0x0002, 0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, 0x0fad, + 0x0003, 0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, + 0x0001, 0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47d2, 0x000b, 0x8060, + 0x0000, 0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, + 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, + 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, + 0x0009, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, + 0x0000, 0x47e4, 0x000b, 0x4000, 0x000f, 0xa90f, 0xeaf9, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x95d0 }; #ifdef UNIQUE_FW_NAME -unsigned short fw2300ipx_length01 = 0xed9d; +unsigned short fw2300ipx_length01 = 0xee08; #else -unsigned short risc_code_length01 = 0xed9d; +unsigned short risc_code_length01 = 0xee08; #endif diff --git a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c index 97b5578ae9b1..cb968e7a0fcd 100644 --- a/drivers/scsi/qla2xxx/ql2322_fw.c +++ b/drivers/scsi/qla2xxx/ql2322_fw.c @@ -6,7 +6,7 @@ */ /* - * Firmware Version 3.03.15 (10:09 May 26, 2005) + * Firmware Version 3.03.18 (12:14 Sep 20, 2005) */ #ifdef UNIQUE_FW_NAME @@ -16,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw2322ipx_version_str[] = {3, 3,15}; +unsigned char fw2322ipx_version_str[] = {3, 3,18}; #else -unsigned char firmware_version[] = {3, 3,15}; +unsigned char firmware_version[] = {3, 3,18}; #endif #ifdef UNIQUE_FW_NAME -#define fw2322ipx_VERSION_STRING "3.03.15" +#define fw2322ipx_VERSION_STRING "3.03.18" #else -#define FW_VERSION_STRING "3.03.15" +#define FW_VERSION_STRING "3.03.18" #endif #ifdef UNIQUE_FW_NAME @@ -38,12 +38,12 @@ unsigned short fw2322ipx_code01[] = { #else unsigned short risc_code01[] = { #endif - 0x0470, 0x0000, 0x0000, 0xe3bd, 0x0000, 0x0003, 0x0003, 0x000f, + 0x0470, 0x0000, 0x0000, 0xe428, 0x0000, 0x0003, 0x0003, 0x0012, 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, @@ -52,11 +52,11 @@ unsigned short risc_code01[] = { 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1cff, 0x2059, 0x0000, 0x2b78, - 0x7883, 0x0004, 0x2089, 0x2be4, 0x2051, 0x1800, 0x2a70, 0x20e1, - 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e74, 0x00f6, - 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e7, 0x1170, - 0x2079, 0x0300, 0x080c, 0x20fd, 0x2061, 0xe000, 0x080c, 0x20e7, - 0x1128, 0x2079, 0x0380, 0x080c, 0x20fd, 0x0060, 0x00fe, 0x7883, + 0x7883, 0x0004, 0x2089, 0x2bcb, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e68, 0x00f6, + 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e3, 0x1170, + 0x2079, 0x0300, 0x080c, 0x20f9, 0x2061, 0xe000, 0x080c, 0x20e3, + 0x1128, 0x2079, 0x0380, 0x080c, 0x20f9, 0x0060, 0x00fe, 0x7883, 0x4010, 0x7837, 0x4010, 0x7833, 0x0011, 0x2091, 0x5000, 0x2091, 0x4080, 0x0cf8, 0x00fe, 0x2029, 0x5600, 0x2031, 0xffff, 0x2039, 0x55dc, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, @@ -70,3087 +70,3086 @@ unsigned short risc_code01[] = { 0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211, - 0x1dd8, 0x080c, 0x0f71, 0x080c, 0x618c, 0x080c, 0xaec4, 0x080c, - 0x1128, 0x080c, 0x1352, 0x080c, 0x1c3d, 0x080c, 0x9393, 0x080c, - 0x0d17, 0x080c, 0x10ad, 0x080c, 0x3589, 0x080c, 0x79bb, 0x080c, - 0x6bf9, 0x080c, 0x8afe, 0x080c, 0x875f, 0x080c, 0x22d8, 0x080c, - 0x8096, 0x080c, 0x2116, 0x080c, 0x2254, 0x080c, 0x22cd, 0x2091, + 0x1dd8, 0x080c, 0x0f65, 0x080c, 0x6186, 0x080c, 0xaee4, 0x080c, + 0x111c, 0x080c, 0x1346, 0x080c, 0x1c39, 0x080c, 0x938b, 0x080c, + 0x0d0b, 0x080c, 0x10a1, 0x080c, 0x3574, 0x080c, 0x79b3, 0x080c, + 0x6bf1, 0x080c, 0x8af6, 0x080c, 0x8757, 0x080c, 0x22d4, 0x080c, + 0x808e, 0x080c, 0x2112, 0x080c, 0x2250, 0x080c, 0x22c9, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x0943, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0937, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x1200, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c, - 0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d85, 0x2071, 0x1800, - 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4cf3, 0x080c, 0x35b0, - 0x080c, 0x7a23, 0x080c, 0x717c, 0x080c, 0x8be5, 0x080c, 0x8788, + 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c, + 0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d79, 0x2071, 0x1800, + 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4ced, 0x080c, 0x359b, + 0x080c, 0x7a1b, 0x080c, 0x7174, 0x080c, 0x8bdd, 0x080c, 0x8780, 0x0c68, 0x000b, 0x0c88, 0x096d, 0x096e, 0x0b09, 0x096b, 0x0bc3, - 0x0d16, 0x0d16, 0x0d16, 0x080c, 0x0d85, 0x0005, 0x0126, 0x00f6, + 0x0d0a, 0x0d0a, 0x0d0a, 0x080c, 0x0d79, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x080c, - 0x0ec4, 0x080c, 0x76a5, 0x0150, 0x080c, 0x76c8, 0x15b0, 0x2079, - 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75d4, + 0x0eb8, 0x080c, 0x769d, 0x0150, 0x080c, 0x76c0, 0x15b0, 0x2079, + 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75cc, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x7098, 0x9086, 0x0029, - 0x1904, 0x0adc, 0x080c, 0x8748, 0x080c, 0x873a, 0x2001, 0x0161, - 0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2af5, - 0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7519, 0x080c, 0x8834, - 0x2011, 0x750c, 0x080c, 0x8940, 0x2011, 0x5fe3, 0x080c, 0x8834, - 0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x5890, 0x2079, - 0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fe3, 0x080c, - 0x8834, 0x2011, 0x7519, 0x080c, 0x8834, 0x2011, 0x750c, 0x080c, - 0x8940, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, - 0x9084, 0xfffb, 0x7842, 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, - 0x00c6, 0x2061, 0x0100, 0x080c, 0x6134, 0x00ce, 0x0804, 0x0adc, - 0x780f, 0x006b, 0x7a28, 0x080c, 0x76ad, 0x0118, 0x9295, 0x5e2c, + 0x1904, 0x0adc, 0x080c, 0x8740, 0x080c, 0x8732, 0x2001, 0x0161, + 0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2adc, + 0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7511, 0x080c, 0x882c, + 0x2011, 0x7504, 0x080c, 0x8938, 0x2011, 0x5fdd, 0x080c, 0x882c, + 0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x588a, 0x2079, + 0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x2011, 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c, + 0x8938, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, + 0x9084, 0xfffb, 0x7842, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140, + 0x00c6, 0x2061, 0x0100, 0x080c, 0x612e, 0x00ce, 0x0804, 0x0adc, + 0x780f, 0x006b, 0x7a28, 0x080c, 0x76a5, 0x0118, 0x9295, 0x5e2c, 0x0010, 0x9295, 0x402c, 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, - 0x19a8, 0x2003, 0x0001, 0x080c, 0x29bd, 0x080c, 0x4c2e, 0x7248, + 0x19a9, 0x2003, 0x0001, 0x080c, 0x29a8, 0x080c, 0x4c28, 0x7248, 0xc284, 0x724a, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, - 0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaae0, 0x080c, 0xa2db, - 0x2011, 0x0004, 0x080c, 0xcc26, 0x080c, 0xaafc, 0x080c, 0x6a7f, - 0x080c, 0x76a5, 0x1120, 0x080c, 0x2a1e, 0x0600, 0x0420, 0x080c, - 0x613b, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a5d, - 0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5826, + 0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaaf7, 0x080c, 0xa2ec, + 0x2011, 0x0004, 0x080c, 0xcc43, 0x080c, 0xab13, 0x080c, 0x6a77, + 0x080c, 0x769d, 0x1120, 0x080c, 0x2a09, 0x0600, 0x0420, 0x080c, + 0x6135, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a57, + 0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5820, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, - 0x582a, 0xd0d4, 0x1118, 0x080c, 0x2a1e, 0x1270, 0x2011, 0x180c, - 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x582a, 0xd0d4, 0x1db8, 0x2011, + 0x5824, 0xd0d4, 0x1118, 0x080c, 0x2a09, 0x1270, 0x2011, 0x180c, + 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5824, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd, - 0x2012, 0x080c, 0x6bcd, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd, - 0x2012, 0x080c, 0x6b93, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8, - 0x707f, 0x0000, 0x080c, 0x76a5, 0x1130, 0x70b0, 0x9005, 0x1168, - 0x080c, 0xd084, 0x0050, 0x080c, 0xd084, 0x70dc, 0xd09c, 0x1128, - 0x70b0, 0x9005, 0x0110, 0x080c, 0x6111, 0x70e7, 0x0000, 0x70e3, - 0x0000, 0x70a7, 0x0000, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, - 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x76a5, 0x1178, 0x9016, - 0x0016, 0x080c, 0x27ba, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f, + 0x2012, 0x080c, 0x6bc5, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd, + 0x2012, 0x080c, 0x6b8b, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8, + 0x707f, 0x0000, 0x080c, 0x769d, 0x1130, 0x70b0, 0x9005, 0x1168, + 0x080c, 0xd0a1, 0x0050, 0x080c, 0xd0a1, 0x70dc, 0xd09c, 0x1128, + 0x70b0, 0x9005, 0x0110, 0x080c, 0x610b, 0x70e7, 0x0000, 0x70e3, + 0x0000, 0x70a7, 0x0000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, + 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x769d, 0x1178, 0x9016, + 0x0016, 0x080c, 0x27b9, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196e, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295, - 0x72de, 0x080c, 0x76a5, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011, - 0x0001, 0x080c, 0xcc26, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, - 0x0002, 0x00fe, 0x080c, 0x30e1, 0x080c, 0xaae0, 0x2011, 0x0005, - 0x080c, 0xa40f, 0x080c, 0xaafc, 0x080c, 0x76a5, 0x0148, 0x00c6, - 0x2061, 0x0100, 0x0016, 0x080c, 0x27ba, 0x61e2, 0x001e, 0x00ce, + 0x72de, 0x080c, 0x769d, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011, + 0x0001, 0x080c, 0xcc43, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, + 0x0002, 0x00fe, 0x080c, 0x30c8, 0x080c, 0xaaf7, 0x2011, 0x0005, + 0x080c, 0xa426, 0x080c, 0xab13, 0x080c, 0x769d, 0x0148, 0x00c6, + 0x2061, 0x0100, 0x0016, 0x080c, 0x27b9, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x00e0, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, - 0x080c, 0xaae0, 0x2011, 0x0005, 0x080c, 0xa40f, 0x080c, 0xaafc, - 0x080c, 0x76a5, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, - 0x27ba, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, - 0x00b6, 0x080c, 0x76a5, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, - 0x0782, 0x080c, 0x76a5, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x080c, 0xaaf7, 0x2011, 0x0005, 0x080c, 0xa426, 0x080c, 0xab13, + 0x080c, 0x769d, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, + 0x27b9, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, - 0xd0bc, 0x090c, 0x3419, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000, + 0xd0bc, 0x090c, 0x3404, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000, 0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, - 0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30e1, + 0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30c8, 0x0804, 0x0bc0, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0538, 0xd084, 0x0528, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c, - 0x01e8, 0x080c, 0x3482, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190, - 0x080c, 0x3276, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001, - 0x080c, 0xd33e, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x32b0, + 0x01e8, 0x080c, 0x346d, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190, + 0x080c, 0x3261, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001, + 0x080c, 0xd35d, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x329b, 0x0804, 0x0bc0, 0x70e4, 0x9005, 0x1904, 0x0bc0, 0x70a8, 0x9005, 0x1904, 0x0bc0, 0x70dc, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0bc0, - 0x080c, 0x6b93, 0x1904, 0x0bc0, 0x080c, 0x6be6, 0x1904, 0x0bc0, - 0x080c, 0x6bcd, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, - 0x0016, 0x080c, 0x6789, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, + 0x080c, 0x6b8b, 0x1904, 0x0bc0, 0x080c, 0x6bde, 0x1904, 0x0bc0, + 0x080c, 0x6bc5, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x080c, 0x6783, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b60, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0bc0, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, - 0x000e, 0x2011, 0x19b5, 0x080c, 0x0fe1, 0x2011, 0x19cf, 0x080c, - 0x0fe1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, - 0x080c, 0x0e98, 0x9006, 0x080c, 0x2647, 0x080c, 0x3482, 0x0118, - 0x080c, 0x4dcb, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, - 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, - 0x080c, 0x76c8, 0x0150, 0x080c, 0x76a5, 0x7828, 0x0118, 0x9084, - 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaae0, + 0x000e, 0x2011, 0x19b5, 0x080c, 0x0fd5, 0x2011, 0x19cf, 0x080c, + 0x0fd5, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, + 0x080c, 0x0e8c, 0x9006, 0x080c, 0x2646, 0x080c, 0x346d, 0x0118, + 0x080c, 0x4dc5, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, + 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x76c0, 0x0150, 0x080c, 0x769d, 0x7828, 0x0118, 0x9084, + 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaaf7, 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000, - 0x080c, 0xa40f, 0x2011, 0x0000, 0x080c, 0xa419, 0x080c, 0xaafc, + 0x080c, 0xa426, 0x2011, 0x0000, 0x080c, 0xa430, 0x080c, 0xab13, 0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906, - 0x2009, 0x00f7, 0x080c, 0x60fa, 0x7940, 0x918c, 0x0010, 0x7942, - 0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2af5, 0xd19c, - 0x0120, 0x2011, 0x0008, 0x080c, 0x2af5, 0x0006, 0x0036, 0x0156, - 0x0000, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a89, - 0x1148, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c, - 0x29cf, 0x00b8, 0x080c, 0x2a91, 0x1138, 0x9006, 0x080c, 0x29ec, - 0x9006, 0x080c, 0x29cf, 0x0068, 0x080c, 0x2a99, 0x1d50, 0x2001, - 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e6, 0x0804, - 0x0cc9, 0x2009, 0x19b1, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001, - 0x0120, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x20a9, 0x003a, 0x1d04, - 0x0c1f, 0x080c, 0x8920, 0x1f04, 0x0c1f, 0x080c, 0x76b6, 0x0148, - 0x080c, 0x76c8, 0x1118, 0x080c, 0x79b6, 0x0050, 0x080c, 0x76ad, - 0x0dd0, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x75d4, 0x0020, - 0x2009, 0x00f8, 0x080c, 0x60fa, 0x7850, 0xc0e5, 0x7852, 0x080c, - 0x76a5, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, - 0x2019, 0xea60, 0x0d0c, 0x8920, 0x7820, 0xd09c, 0x15a0, 0x080c, - 0x76a5, 0x0904, 0x0cab, 0x7824, 0xd0ac, 0x1904, 0x0cce, 0x080c, - 0x76c8, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, - 0x2011, 0x1800, 0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x9084, - 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, - 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x8421, 0x1160, 0x1d04, - 0x0c7b, 0x080c, 0x8920, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x7003, - 0x0001, 0x0804, 0x0cce, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004, - 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x1d04, 0x0c91, 0x080c, - 0x8920, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, - 0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2af5, 0x20a9, - 0x0002, 0x080c, 0x2a82, 0x7924, 0x080c, 0x2aa1, 0xd19c, 0x0110, - 0x080c, 0x29bd, 0x00f0, 0x080c, 0x76b6, 0x1140, 0x94a2, 0x03e8, - 0x1128, 0x080c, 0x7679, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800, - 0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x080c, 0x76bf, 0x0110, - 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c83, 0x7003, 0x0001, - 0x0028, 0x2001, 0x0001, 0x080c, 0x2647, 0x00a0, 0x7850, 0xc0e4, - 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, - 0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2af5, 0x7828, 0x9085, - 0x0028, 0x782a, 0x2001, 0x19a8, 0x2003, 0x0000, 0x9006, 0x78f2, - 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x002e, 0x001e, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x00b6, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x8920, 0x015e, - 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e, - 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, - 0x0001, 0x1110, 0x080c, 0x35b0, 0x00ee, 0x0005, 0x0005, 0x2a70, - 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f, - 0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, - 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd084, 0x70ef, - 0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, - 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, - 0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, - 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, - 0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, - 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6789, - 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, - 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, - 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, - 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, - 0x0d87, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, - 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, - 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, - 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, - 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, - 0x1b2c, 0x7a08, 0x226a, 0x2069, 0x1b2d, 0x7a18, 0x226a, 0x8d68, - 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1b3a, 0x201a, 0x2019, 0x1b3d, - 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, - 0x9386, 0x1b56, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, - 0xdead, 0x2019, 0x1b3b, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, - 0x0000, 0x2069, 0x1a82, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, - 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dde, 0x2069, 0x1aa2, 0x2019, - 0x0050, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, - 0x1f04, 0x0deb, 0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, - 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x0180, 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001, - 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, - 0x2003, 0x1001, 0x080c, 0x5835, 0x1170, 0x080c, 0x0f32, 0x0110, - 0x080c, 0x0e85, 0x080c, 0x5835, 0x1130, 0x2071, 0x1800, 0x2011, - 0x8000, 0x080c, 0x0f46, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004, - 0x9084, 0x0007, 0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c, - 0xaad1, 0x2079, 0x0380, 0x2069, 0x1b0c, 0x7818, 0x6802, 0x781c, - 0x6806, 0x7840, 0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, - 0x1b17, 0x9016, 0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210, - 0x8318, 0x8210, 0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a, - 0x7830, 0x681a, 0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826, - 0x7803, 0x0000, 0x2069, 0x1acc, 0x901e, 0x20a9, 0x0020, 0x7b26, - 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e5f, 0x2069, 0x1aec, - 0x2019, 0x00b0, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, - 0x8318, 0x1f04, 0x0e6c, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, - 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, - 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, - 0x0080, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x2011, - 0x0040, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x0c78, - 0x0026, 0x080c, 0x0f32, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294, - 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011, - 0x1b47, 0x080c, 0x0f46, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214, - 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, - 0x2011, 0x6840, 0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0, - 0x080c, 0x0f37, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f32, 0x0148, - 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, - 0x0f37, 0x002e, 0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f32, - 0x1130, 0x2011, 0x8040, 0x080c, 0x0f46, 0x002e, 0x0005, 0x080c, - 0x2a99, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, - 0x0f37, 0x002e, 0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800, - 0xd0b4, 0x70ec, 0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006, - 0x3b00, 0x9084, 0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5, - 0xc1f5, 0x0099, 0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071, - 0x1800, 0xd0e4, 0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016, - 0x71e8, 0x0019, 0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000, - 0x9084, 0x0007, 0x000b, 0x0005, 0x0eea, 0x0ec4, 0x0ec4, 0x0e98, - 0x0ed3, 0x0ec4, 0x0ec4, 0x0ed3, 0xc284, 0x0016, 0x3b08, 0x3a00, - 0x9104, 0x918d, 0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0, - 0x001e, 0x0005, 0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86, - 0x1800, 0x190c, 0x0d85, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee, - 0xd0e4, 0x1118, 0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800, - 0x190c, 0x0d85, 0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4, - 0x1140, 0x9284, 0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1, - 0x0861, 0x0005, 0x1d04, 0x0f5a, 0x2091, 0x6000, 0x1f04, 0x0f5a, - 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, - 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, - 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, - 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, - 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, - 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, - 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, - 0x000e, 0x200f, 0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, - 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, - 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, - 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, - 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, - 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, - 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f61, 0x2100, - 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, - 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, - 0x0005, 0x20e9, 0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, - 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, - 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, - 0x8007, 0x7180, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, - 0x23a0, 0x900e, 0x080c, 0x0d65, 0x2001, 0x0000, 0x810f, 0x20a9, - 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, - 0x0006, 0x080c, 0x108b, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, - 0x1800, 0x080c, 0x1104, 0x090c, 0x0d85, 0x00ee, 0x0005, 0x0086, - 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, - 0x2071, 0x1800, 0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, - 0x9906, 0x090c, 0x0d85, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d85, - 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, - 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x1910, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, - 0x090c, 0x0d85, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, - 0x8001, 0x0270, 0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, - 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, - 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, - 0x70c0, 0x90ca, 0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, - 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, - 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, - 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, - 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, - 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, - 0x080c, 0x873a, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, - 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, - 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, - 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, - 0x11a0, 0x2001, 0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940, - 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, - 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, - 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, - 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, - 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, - 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, - 0x1800, 0x74be, 0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, - 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, - 0x0440, 0x0278, 0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270, - 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, - 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, - 0x00e6, 0x2071, 0x1a25, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, - 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, - 0x0080, 0x9006, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, - 0x113e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, - 0x1f04, 0x1147, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, - 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a25, 0x701c, 0x9088, - 0x1a2f, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, - 0x090c, 0x0d85, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, - 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x00e6, 0x2071, 0x1a25, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, - 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, - 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1190, 0x1313, - 0x118e, 0x118e, 0x1307, 0x1307, 0x1307, 0x1307, 0x080c, 0x0d85, - 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, - 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2f, - 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, - 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, - 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, - 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, - 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, - 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, - 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, - 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, - 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, - 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, - 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, - 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, - 0x2009, 0x1a25, 0x2104, 0xc095, 0x200a, 0x080c, 0x116d, 0x0005, - 0x0016, 0x00e6, 0x2071, 0x1a25, 0x00f6, 0x2079, 0x0080, 0x792c, - 0xd1bc, 0x190c, 0x0d7e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, - 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x117e, - 0x1226, 0x125a, 0x1332, 0x0d85, 0x134d, 0x0d85, 0x918c, 0x0700, - 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, - 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, - 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, - 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11c3, 0x0005, - 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, - 0x080c, 0x117e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, - 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, - 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11d8, 0x0005, 0x7008, - 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, - 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, - 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, - 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906, - 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, - 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, - 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, - 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, 0xa8a8, 0xd08c, 0x0005, - 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, 0x908e, 0x0100, - 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, - 0x6f0d, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x108b, - 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, - 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, - 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, - 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x114e, 0x00e8, - 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6f0d, 0x000e, 0x001e, - 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xaf2e, - 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, - 0x108b, 0x7007, 0x0000, 0x080c, 0x116d, 0x00ae, 0x0005, 0x0126, - 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, - 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930, 0x204c, 0xa87c, - 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, - 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041, - 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, - 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, - 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8e26, - 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8c88, - 0x7007, 0x0000, 0x080c, 0x117e, 0x0005, 0x7007, 0x0000, 0x080c, - 0x117e, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, - 0x1a6f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007, - 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, - 0x0000, 0x2001, 0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0120, - 0x7820, 0x080c, 0x13b6, 0x0cc8, 0x2001, 0x1a70, 0x2003, 0x0000, - 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, - 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, - 0x1a82, 0x78e3, 0xff00, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, - 0x1a71, 0x2003, 0x0000, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, - 0x781f, 0x0303, 0x2061, 0x1a82, 0x602f, 0x1ddc, 0x2001, 0x181a, - 0x2004, 0x9082, 0x1ddc, 0x6032, 0x603b, 0x1ee2, 0x602b, 0x1ac2, - 0x6007, 0x1aa2, 0x2061, 0x1aa2, 0x606f, 0x193e, 0x2001, 0x1929, - 0x2004, 0x607a, 0x783f, 0x3489, 0x00ce, 0x0005, 0x9086, 0x000d, - 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, - 0xcc04, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, - 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, - 0xafcc, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, - 0x9184, 0x0070, 0x190c, 0x0d7e, 0xd19c, 0x05a0, 0x7820, 0x908c, - 0xf000, 0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000, - 0x9086, 0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867, - 0x0103, 0x080c, 0x6d2e, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, - 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x190c, 0x68b4, 0x00be, 0x6044, - 0xd0fc, 0x190c, 0xab09, 0x080c, 0xaf57, 0x7808, 0xd09c, 0x19b0, - 0x012e, 0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d85, 0x002b, 0x012e, - 0x0005, 0x04b0, 0x012e, 0x0005, 0x1438, 0x145e, 0x148e, 0x1493, - 0x1497, 0x149c, 0x14c4, 0x14c8, 0x14d6, 0x14da, 0x1438, 0x15a7, - 0x15ab, 0x161d, 0x1624, 0x1438, 0x1625, 0x1626, 0x1631, 0x1638, - 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x149e, - 0x1438, 0x1466, 0x148b, 0x1452, 0x1438, 0x1472, 0x143c, 0x143a, - 0x080c, 0x0d85, 0x080c, 0x0d7e, 0x080c, 0x1643, 0x2009, 0x1a7e, - 0x2104, 0x8000, 0x200a, 0x080c, 0x8159, 0x080c, 0x1b47, 0x0005, - 0x6044, 0xd0fc, 0x190c, 0xab09, 0x2009, 0x0055, 0x080c, 0xafcc, - 0x012e, 0x0005, 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, - 0xab09, 0x2009, 0x0055, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0048, - 0x080c, 0x1643, 0x2060, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0054, - 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab09, 0x080c, - 0xafcc, 0x0005, 0x080c, 0x1643, 0x2060, 0x0056, 0x0066, 0x080c, - 0x1643, 0x2028, 0x080c, 0x1643, 0x2030, 0x0036, 0x0046, 0x2021, - 0x0000, 0x2418, 0x2009, 0x0056, 0x080c, 0xafcc, 0x004e, 0x003e, - 0x006e, 0x005e, 0x0005, 0x080c, 0x1643, 0x0005, 0x7004, 0xc085, - 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, - 0x1643, 0x080c, 0x1740, 0x0005, 0x080c, 0x0d85, 0x080c, 0x1643, - 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, - 0x0048, 0x080c, 0xafcc, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, - 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1648, 0x2001, - 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, - 0x080c, 0x1643, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, - 0x009e, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005, 0x080c, 0x1643, - 0x080c, 0x0d85, 0x080c, 0x1643, 0x080c, 0x1592, 0x7827, 0x0018, - 0x79ac, 0xd1dc, 0x0904, 0x1543, 0x7827, 0x0015, 0x7828, 0x782b, - 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, - 0x0020, 0x0804, 0x1549, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab, - 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d85, - 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x1577, - 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x0005, 0x7827, - 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, - 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, - 0x0140, 0x00ee, 0x080c, 0x1b47, 0x080c, 0x1366, 0x7803, 0x0001, - 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, - 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, - 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x2001, 0x020d, - 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, - 0x0d85, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, - 0x080c, 0x8159, 0x080c, 0x1b47, 0x080c, 0xcc16, 0x0158, 0xa9ac, - 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, - 0xc0bd, 0xa882, 0x080c, 0xc802, 0x0005, 0x6020, 0x9086, 0x0009, - 0x1128, 0x2009, 0x004c, 0x080c, 0xafcc, 0x0048, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd019, 0x2029, - 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x7dbc, 0x080c, 0xeb55, 0xd5a4, 0x1118, 0x080c, 0x1648, 0x0005, - 0x080c, 0x8159, 0x080c, 0x1b47, 0x0005, 0x781f, 0x0300, 0x7803, - 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, - 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, - 0x080c, 0x16b9, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, - 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d85, - 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, - 0x1723, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, - 0x0020, 0x080c, 0x1648, 0x0005, 0x81ff, 0x190c, 0x0d85, 0x0005, - 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, - 0x1612, 0x2071, 0x0200, 0x080c, 0x1710, 0x05e0, 0x080c, 0x1723, - 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, - 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, - 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, - 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x1936, 0x00fe, 0x2009, 0x01f4, - 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, - 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x1648, 0x0040, 0x2001, - 0x020d, 0x2003, 0x0020, 0x080c, 0x1366, 0x7803, 0x0001, 0x00ee, - 0x001e, 0x0005, 0x080c, 0x1723, 0x0dd0, 0x2001, 0x020d, 0x2003, - 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, - 0x0053, 0x080c, 0xafcc, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, - 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x9177, - 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8d7a, 0x0cd0, 0x0005, - 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, - 0x080c, 0x16b9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, - 0x080c, 0x1592, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, - 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, - 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, - 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, - 0x810c, 0x080c, 0x16ab, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, - 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, - 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, - 0x080c, 0x8159, 0x080c, 0x1b47, 0x0090, 0x7827, 0x0015, 0x782b, - 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, - 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, - 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, - 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, - 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, - 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, - 0x0005, 0x00f6, 0x00e6, 0x2079, 0x0300, 0x0006, 0x2071, 0x1a6f, - 0x7008, 0x9005, 0x1110, 0x78e3, 0x0c0c, 0x8000, 0x700a, 0x0026, - 0x2011, 0x0006, 0x7808, 0xd09c, 0x0150, 0x0016, 0x0026, 0x00c6, - 0x080c, 0x13d4, 0x00ce, 0x002e, 0x001e, 0x8211, 0x1d98, 0x002e, - 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x00b9, - 0x1178, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x0130, 0x8001, 0x0a0c, - 0x0d85, 0x700a, 0x78e3, 0x0c00, 0x000e, 0x00ee, 0x00fe, 0x0005, - 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, 0x2009, - 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, - 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, - 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, - 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, - 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, - 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, - 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, - 0x1158, 0x2021, 0x1a7f, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, - 0x8159, 0x080c, 0x1b47, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, - 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, - 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x17a2, 0x7017, - 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x17a2, 0x2001, - 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, - 0x1904, 0x17a2, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, - 0x80b1, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xcff4, - 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, - 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1f02, 0x1190, - 0x080c, 0x1993, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, - 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, - 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, - 0x080c, 0x1648, 0x0005, 0x080c, 0x0d85, 0x2cf0, 0x0126, 0x2091, - 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, - 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ee2, - 0x2165, 0x0002, 0x17d9, 0x1847, 0x17d9, 0x17d9, 0x17dd, 0x1828, - 0x17d9, 0x17fd, 0x17d2, 0x183e, 0x17d9, 0x17d9, 0x17e2, 0x1934, - 0x1811, 0x1807, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, - 0x183e, 0x9085, 0x0001, 0x0804, 0x192a, 0xa87c, 0xd0ac, 0x0dc8, - 0x0804, 0x184e, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x18b9, 0xa898, - 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00, - 0x9080, 0x0008, 0x2004, 0x9080, 0x9347, 0x2005, 0x9005, 0x090c, - 0x0d85, 0x2004, 0xa8ae, 0x0804, 0x1912, 0xa87c, 0xd0bc, 0x09c8, - 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x184e, 0xa87c, - 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, - 0x18b9, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, - 0xa804, 0x9045, 0x090c, 0x0d85, 0xa164, 0xa91a, 0x91ec, 0x000f, - 0x9d80, 0x1ee2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x18b9, 0x0430, - 0xa87c, 0xd0ac, 0x0904, 0x17d9, 0xa804, 0x9045, 0x090c, 0x0d85, - 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x9006, - 0xa842, 0xa83e, 0xd19c, 0x1904, 0x18b9, 0x0080, 0xa87c, 0xd0ac, - 0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x0804, 0x18b9, 0xa87c, - 0xd0ac, 0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, - 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1871, 0x1871, - 0x1873, 0x1871, 0x1871, 0x1871, 0x187d, 0x1871, 0x1871, 0x1871, - 0x1887, 0x1871, 0x1871, 0x1871, 0x1891, 0x1871, 0x1871, 0x1871, - 0x189b, 0x1871, 0x1871, 0x1871, 0x18a5, 0x1871, 0x1871, 0x1871, - 0x18af, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904, - 0x17e7, 0xa37c, 0xa280, 0x0804, 0x1912, 0xa584, 0xa488, 0x9d86, - 0x0024, 0x0904, 0x17e7, 0xa38c, 0xa290, 0x0804, 0x1912, 0xa594, - 0xa498, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa39c, 0xa2a0, 0x0804, - 0x1912, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3ac, - 0xa2b0, 0x0804, 0x1912, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904, - 0x17e7, 0xa3bc, 0xa2c0, 0x0804, 0x1912, 0xa5c4, 0xa4c8, 0x9d86, - 0x0024, 0x0904, 0x17e7, 0xa3cc, 0xa2d0, 0x0804, 0x1912, 0xa5d4, - 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3dc, 0xa2e0, 0x0804, - 0x1912, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, - 0x0002, 0x18dc, 0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18e7, - 0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18f2, 0x18da, 0x18da, - 0x18da, 0x18da, 0x18da, 0x18fd, 0x18da, 0x18da, 0x18da, 0x18da, - 0x18da, 0x1908, 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, - 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa37c, 0xa280, 0x0458, 0xa584, - 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa394, - 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c, - 0x0904, 0x17e7, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, - 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa3c4, 0xa2c8, 0x0050, - 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x17e7, - 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, - 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, - 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, - 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, - 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x17d9, 0x2ff0, 0x0126, - 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, - 0xa80e, 0x2061, 0x1edd, 0xa813, 0x1edd, 0x2c05, 0xa80a, 0xa964, - 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0d85, 0x9006, 0xa842, 0xa83e, - 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0xadcc, 0xacd0, 0xafd4, - 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, - 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, - 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, - 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, - 0xa804, 0x9045, 0x090c, 0x0d85, 0xa80e, 0xa064, 0xa81a, 0x9084, - 0x000f, 0x9080, 0x1ee2, 0x2015, 0x82ff, 0x090c, 0x0d85, 0xaa12, - 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, - 0x2d00, 0x0002, 0x1abd, 0x19ea, 0x19ea, 0x1abd, 0x19ea, 0x1ab7, - 0x1abd, 0x19ea, 0x1a5a, 0x1a5a, 0x1a5a, 0x1abd, 0x1a5a, 0x1abd, - 0x1ab4, 0x1a5a, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, - 0xdd9c, 0x0904, 0x1abf, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, - 0x9082, 0x001b, 0x0002, 0x19d6, 0x19d4, 0x19d4, 0x19d4, 0x19d4, - 0x19d4, 0x19da, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19de, - 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19e2, 0x19d4, 0x19d4, - 0x19d4, 0x19d4, 0x19d4, 0x19e6, 0x080c, 0x0d85, 0xa774, 0xa678, - 0x0804, 0x1abf, 0xa78c, 0xa690, 0x0804, 0x1abf, 0xa7a4, 0xa6a8, - 0x0804, 0x1abf, 0xa7bc, 0xa6c0, 0x0804, 0x1abf, 0xa7d4, 0xa6d8, - 0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, - 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a12, - 0x1a12, 0x1a14, 0x1a12, 0x1a12, 0x1a12, 0x1a1e, 0x1a12, 0x1a12, - 0x1a12, 0x1a28, 0x1a12, 0x1a12, 0x1a12, 0x1a32, 0x1a12, 0x1a12, - 0x1a12, 0x1a3c, 0x1a12, 0x1a12, 0x1a12, 0x1a46, 0x1a12, 0x1a12, - 0x1a12, 0x1a50, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0004, - 0x0904, 0x1abf, 0xa37c, 0xa280, 0x0804, 0x1abf, 0xa584, 0xa488, - 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa38c, 0xa290, 0x0804, 0x1abf, - 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa39c, 0xa2a0, - 0x0804, 0x1abf, 0xa5a4, 0xa4a8, 0x9d86, 0x0004, 0x0904, 0x1abf, - 0xa3ac, 0xa2b0, 0x0804, 0x1abf, 0xa5b4, 0xa4b8, 0x9d86, 0x0004, - 0x0904, 0x1abf, 0xa3bc, 0xa2c0, 0x0804, 0x1abf, 0xa5c4, 0xa4c8, - 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3cc, 0xa2d0, 0x0804, 0x1abf, - 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3dc, 0xa2e0, - 0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, - 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a82, - 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a8c, 0x1a80, 0x1a80, - 0x1a80, 0x1a80, 0x1a80, 0x1a96, 0x1a80, 0x1a80, 0x1a80, 0x1a80, - 0x1a80, 0x1aa0, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1aaa, - 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x000c, - 0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584, 0xa488, 0xa78c, 0xa690, - 0x9d86, 0x000c, 0x0560, 0xa394, 0xa298, 0x0448, 0xa59c, 0xa4a0, - 0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510, 0xa3ac, 0xa2b0, 0x00f8, - 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x000c, 0x01c0, 0xa3c4, - 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x000c, - 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, - 0x1eb8, 0x1904, 0x1993, 0x900e, 0x0050, 0x080c, 0x0d85, 0xab2e, - 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1eb8, 0x0005, - 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, - 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, - 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, - 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005, - 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, - 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009, - 0x0048, 0x0804, 0xafcc, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, - 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, - 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, - 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x13d4, - 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, - 0x7808, 0xd09c, 0x190c, 0x13d4, 0x00ce, 0x2001, 0x0038, 0x080c, - 0x1bcf, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, - 0x0d85, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, - 0x1bde, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1bcb, 0x7827, - 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, - 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c, - 0x76a5, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, - 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, - 0x0059, 0x0804, 0x7747, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, - 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, - 0x2aad, 0x2009, 0x003c, 0x080c, 0x2241, 0x2001, 0x015d, 0x2003, - 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x873a, 0x70a0, - 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, - 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1366, 0x7803, 0x0001, - 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, - 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x76a5, 0x1108, - 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, - 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, - 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, - 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001, - 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, - 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, - 0x621c, 0x080c, 0x16b9, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, - 0x1702, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, - 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, - 0x0040, 0x0904, 0x1c3c, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, - 0x080c, 0x0d85, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, - 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, - 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, - 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, - 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1bd5, - 0x9186, 0x0040, 0x190c, 0x0d85, 0x00d6, 0x2069, 0x0200, 0x692c, - 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, - 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, - 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0d85, - 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, - 0x2079, 0x0380, 0x2001, 0x19e9, 0x2070, 0x012e, 0x0005, 0x2cf0, - 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964, 0xa91a, - 0x918c, 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c71, 0x1c71, 0x1c71, - 0x1c73, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x1c65, 0x1c7b, 0x1c71, - 0x1c77, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x9086, 0x0008, 0x1148, - 0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x2011, 0x1edd, 0x2205, 0xab88, - 0x00a8, 0x080c, 0x0d85, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186, - 0x001b, 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x9184, - 0x000f, 0x9080, 0x1ee2, 0x2015, 0x2205, 0xab88, 0x2908, 0xa80a, - 0xa90e, 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e, 0x0005, - 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa88c, - 0xa990, 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942, 0xa846, - 0xa94a, 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198, 0x2940, - 0xa064, 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x2c05, - 0x2808, 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x012e, - 0x3e60, 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126, 0x2091, - 0x2400, 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc, 0x1904, - 0x1db5, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109, - 0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1ee2, 0x2145, - 0x0002, 0x1ce9, 0x1cf7, 0x1ce9, 0x1ce9, 0x1ce9, 0x1ceb, 0x1ce9, - 0x1ce9, 0x1d4c, 0x1d4c, 0x1ce9, 0x1ce9, 0x1ce9, 0x1d4a, 0x1ce9, - 0x1ce9, 0x080c, 0x0d85, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184, - 0x000f, 0x9080, 0x1ee2, 0x2045, 0xd19c, 0x1904, 0x1d4c, 0x9036, - 0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, - 0x0002, 0x1d1c, 0x1d1c, 0x1d1e, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d24, - 0x1d1c, 0x1d1c, 0x1d1c, 0x1d2a, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d30, - 0x1d1c, 0x1d1c, 0x1d1c, 0x1d36, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d3c, - 0x1d1c, 0x1d1c, 0x1d1c, 0x1d42, 0x080c, 0x0d85, 0xb574, 0xb478, - 0xb37c, 0xb280, 0x0804, 0x1d91, 0xb584, 0xb488, 0xb38c, 0xb290, - 0x0804, 0x1d91, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d91, - 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d91, 0xb5b4, 0xb4b8, - 0xb3bc, 0xb2c0, 0x0804, 0x1d91, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, - 0x0804, 0x1d91, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d91, - 0x0804, 0x1d91, 0x080c, 0x0d85, 0x2805, 0x908a, 0x0034, 0x1a0c, - 0x0d85, 0x9082, 0x001b, 0x0002, 0x1d6f, 0x1d6d, 0x1d6d, 0x1d6d, - 0x1d6d, 0x1d6d, 0x1d76, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, - 0x1d7d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d84, 0x1d6d, - 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d8b, 0x080c, 0x0d85, 0xb56c, - 0xb470, 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584, 0xb488, - 0xb78c, 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, - 0xb6a8, 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, - 0xb3c4, 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, - 0xb2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, - 0x8109, 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840, 0x2805, - 0x9005, 0x1168, 0xb004, 0x9005, 0x090c, 0x0d85, 0x2050, 0xb164, - 0xa91a, 0x9184, 0x000f, 0x9080, 0x1ee2, 0x2045, 0x2805, 0x2810, - 0x2a08, 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344, 0xd3fc, - 0x190c, 0x0d85, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118, 0xa848, - 0x9206, 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c, 0x1f02, - 0x1998, 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140, 0xa810, - 0x2005, 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070, 0x00c6, - 0x3e60, 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce, 0x8319, - 0xab16, 0x1904, 0x1d9e, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105, - 0x6046, 0x0804, 0x1d9b, 0x080c, 0x0d85, 0x00f6, 0x00e6, 0x0096, - 0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x2079, 0x0090, - 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000, - 0x6014, 0x2048, 0x080c, 0xcc16, 0x0118, 0xa880, 0xc0bd, 0xa882, - 0x6020, 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8, 0x2001, - 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, - 0x60c8, 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xc802, 0x080c, - 0xaae0, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c, - 0x2241, 0x080c, 0xa585, 0x2011, 0x0000, 0x080c, 0xa419, 0x002e, - 0x00ce, 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0090, - 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, - 0x1984, 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319, 0x090c, - 0x0d85, 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102, 0x001e, - 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, - 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090, 0x782b, - 0x0008, 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x2071, - 0x19e9, 0x7054, 0x9086, 0x0000, 0x0904, 0x1eb3, 0x2079, 0x0090, - 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, - 0x9184, 0x0003, 0x0188, 0x080c, 0xeb9e, 0x2001, 0x0133, 0x2004, - 0x9005, 0x090c, 0x0d85, 0x0016, 0x2009, 0x0040, 0x080c, 0x2241, - 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, - 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241, - 0x782c, 0xd0fc, 0x09a8, 0x080c, 0xaafc, 0x782c, 0xd0fc, 0x1de8, - 0x080c, 0xaae0, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004, - 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241, 0x782b, - 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d85, - 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, - 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ee2, - 0x2065, 0x8cff, 0x090c, 0x0d85, 0x8a51, 0x0005, 0x2050, 0x0005, - 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, - 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, - 0x0023, 0x0000, 0x0000, 0x1ed5, 0x1ed1, 0x1ed5, 0x1ed5, 0x1edf, - 0x0000, 0x1ed5, 0x1edc, 0x1edc, 0x1ed9, 0x1edc, 0x1edc, 0x0000, - 0x1edf, 0x1edc, 0x0000, 0x1ed7, 0x1ed7, 0x0000, 0x1ed7, 0x1edf, - 0x0000, 0x1ed7, 0x1edd, 0x1edd, 0x1edd, 0x0000, 0x1edd, 0x0000, - 0x1edf, 0x1edd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, - 0x9055, 0x0904, 0x20e1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, - 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1edd, 0x00d0, 0x9de0, - 0x1ee2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, - 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, - 0x1140, 0x0310, 0x0804, 0x20e1, 0xa004, 0x9045, 0x0904, 0x20e1, - 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fc9, 0xdd9c, 0x1904, 0x1f85, - 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1f5a, - 0x1f5a, 0x1f5c, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f62, 0x1f5a, 0x1f5a, - 0x1f5a, 0x1f68, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f6e, 0x1f5a, 0x1f5a, - 0x1f5a, 0x1f74, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f7a, 0x1f5a, 0x1f5a, - 0x1f5a, 0x1f80, 0x080c, 0x0d85, 0xa07c, 0x9422, 0xa080, 0x931b, - 0x0804, 0x1fbf, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1fbf, - 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1fbf, 0xa0ac, 0x9422, - 0xa0b0, 0x931b, 0x0804, 0x1fbf, 0xa0bc, 0x9422, 0xa0c0, 0x931b, - 0x0804, 0x1fbf, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1fbf, - 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, - 0x0d85, 0x9082, 0x001b, 0x0002, 0x1fa7, 0x1fa5, 0x1fa5, 0x1fa5, - 0x1fa5, 0x1fa5, 0x1fac, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, - 0x1fb1, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fb6, 0x1fa5, - 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fbb, 0x080c, 0x0d85, 0xa07c, - 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, - 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, - 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, - 0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20e1, 0x8c60, 0x0804, - 0x1f31, 0xa004, 0x9045, 0x0904, 0x20e1, 0x0804, 0x1f0c, 0x8a51, - 0x0904, 0x20e1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, - 0x0904, 0x20e1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ee2, 0x2c05, - 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20d6, 0x2c05, 0x8422, - 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, - 0x2073, 0x9082, 0x001b, 0x0002, 0x200f, 0x200f, 0x2011, 0x200f, - 0x200f, 0x200f, 0x201f, 0x200f, 0x200f, 0x200f, 0x202d, 0x200f, - 0x200f, 0x200f, 0x203b, 0x200f, 0x200f, 0x200f, 0x2049, 0x200f, - 0x200f, 0x200f, 0x2057, 0x200f, 0x200f, 0x200f, 0x2065, 0x080c, - 0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, - 0x0d85, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20d1, 0xa18c, - 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, - 0x9420, 0xa088, 0x9319, 0x0804, 0x20d1, 0xa19c, 0x2400, 0x9122, - 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa094, 0x9420, 0xa098, - 0x9319, 0x0804, 0x20d1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, - 0x911b, 0x0a0c, 0x0d85, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, - 0x20d1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, - 0x0d85, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20d1, 0xa1cc, - 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0c4, - 0x9420, 0xa0c8, 0x9319, 0x0804, 0x20d1, 0xa1dc, 0x2400, 0x9122, - 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0d4, 0x9420, 0xa0d8, - 0x9319, 0x0804, 0x20d1, 0x9082, 0x001b, 0x0002, 0x2091, 0x208f, - 0x208f, 0x208f, 0x208f, 0x208f, 0x209e, 0x208f, 0x208f, 0x208f, - 0x208f, 0x208f, 0x20ab, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f, - 0x20b8, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f, 0x20c5, 0x080c, - 0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, - 0x0d85, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, - 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420, - 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, - 0x911b, 0x0a0c, 0x0d85, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, - 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0d85, - 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, - 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0cc, 0x9420, 0xa0d0, - 0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, - 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, - 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x00c6, - 0x610c, 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291, 0x0000, - 0x2c04, 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8, 0x9284, - 0x000f, 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003, 0x780f, - 0x0000, 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002, 0x918a, - 0x0002, 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c, - 0x0d7e, 0xd094, 0x0110, 0x080c, 0x1208, 0x0005, 0x0126, 0x2091, - 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, - 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, - 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, - 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, 0x781c, - 0xd0a4, 0x190c, 0x223e, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, - 0x001a, 0x9084, 0x000e, 0x0002, 0x215c, 0x2154, 0x80b1, 0x2154, - 0x2156, 0x2156, 0x2156, 0x2156, 0x8097, 0x2154, 0x2158, 0x2154, - 0x2156, 0x2154, 0x2156, 0x2154, 0x080c, 0x0d85, 0x0031, 0x0020, - 0x080c, 0x8097, 0x080c, 0x80b1, 0x0005, 0x0006, 0x0016, 0x0026, - 0x080c, 0xeb9e, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xaae0, - 0x2001, 0x19fc, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004, - 0x9005, 0x090c, 0x0d85, 0x00c6, 0x2001, 0x19fc, 0x2064, 0x080c, - 0xaafc, 0x080c, 0xc802, 0x2009, 0x0040, 0x080c, 0x2241, 0x00ce, - 0x0408, 0x2009, 0x0040, 0x080c, 0x2241, 0x080c, 0xaafc, 0x00d0, - 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, - 0x76a5, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c, 0x75d4, - 0x0010, 0x080c, 0x6039, 0x080c, 0x814f, 0x0041, 0x0018, 0x9184, - 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, - 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c, 0x1b47, 0x005e, 0x004e, - 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, - 0x7128, 0x2001, 0x1970, 0x2102, 0x2001, 0x1978, 0x2102, 0x2001, - 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, - 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, - 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, - 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, - 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, - 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, - 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, - 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, - 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, - 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, - 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, - 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, - 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, - 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, - 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, - 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, - 0x0d7e, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, - 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, - 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, - 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x080c, - 0x29bd, 0x2001, 0x199e, 0x2003, 0x0700, 0x2001, 0x199f, 0x2003, - 0x0700, 0x080c, 0x2b18, 0x9006, 0x080c, 0x29ec, 0x9006, 0x080c, - 0x29cf, 0x20a9, 0x0012, 0x1d04, 0x2273, 0x2091, 0x6000, 0x1f04, - 0x2273, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, - 0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x2af5, 0x080c, 0x26db, - 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26eb, 0x60e7, 0x0000, - 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, - 0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061, 0x0140, - 0x608b, 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097, 0x0198, - 0x00ce, 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000, 0x20a9, - 0x0018, 0x60bf, 0x0000, 0x1f04, 0x22b1, 0x60bb, 0x0000, 0x60bf, - 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, - 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, - 0x006b, 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, - 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, - 0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, - 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, - 0x6028, 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, - 0x006e, 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, - 0x1198, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, - 0x0004, 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387, 0x200c, - 0xd1a4, 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387, 0x200c, - 0xd1b4, 0x001e, 0x0d30, 0x0c58, 0x231f, 0x231c, 0x231c, 0x231c, - 0x231e, 0x231c, 0x231c, 0x231c, 0x080c, 0x0d85, 0x0029, 0x002e, - 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, - 0x0118, 0xd19c, 0x1904, 0x25a1, 0xd1f4, 0x190c, 0x0d7e, 0x080c, - 0x76a5, 0x0904, 0x237c, 0x080c, 0xd33e, 0x1120, 0x7000, 0x9086, - 0x0003, 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x76c8, - 0x0118, 0x080c, 0x76b6, 0x1530, 0x2011, 0x0020, 0x080c, 0x2af5, - 0x6043, 0x0000, 0x080c, 0xd33e, 0x0168, 0x080c, 0x76c8, 0x1150, - 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7519, - 0x0804, 0x25a4, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6, - 0x2069, 0x0140, 0x080c, 0x76f9, 0x00de, 0x1904, 0x25a4, 0x080c, - 0x79b1, 0x0428, 0x080c, 0x76c8, 0x1590, 0x6024, 0x9084, 0x1800, - 0x1108, 0x0468, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x617e, - 0x080c, 0x75d4, 0x0804, 0x25a1, 0xd1ac, 0x1508, 0x6024, 0xd0dc, - 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098, - 0x9086, 0x0029, 0x1110, 0x080c, 0x7888, 0x0804, 0x25a1, 0x080c, - 0x79ac, 0x0048, 0x2001, 0x197e, 0x2003, 0x0002, 0x0020, 0x080c, - 0x77e3, 0x0804, 0x25a1, 0x080c, 0x792b, 0x0804, 0x25a1, 0x6220, - 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x260c, 0xd2b4, 0x1904, 0x261e, - 0x0000, 0xd1ac, 0x0904, 0x24ae, 0x0036, 0x6328, 0xc3bc, 0x632a, - 0x003e, 0x080c, 0x76a5, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2af5, - 0x0006, 0x0026, 0x0036, 0x080c, 0x76bf, 0x1158, 0x080c, 0x79a7, - 0x080c, 0x617e, 0x080c, 0x75d4, 0x003e, 0x002e, 0x000e, 0x00ae, - 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7679, 0x0016, 0x0046, - 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, - 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, - 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148, - 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c2e, - 0x003e, 0x080c, 0xd337, 0x1904, 0x2483, 0x9196, 0xff00, 0x05a8, - 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, - 0x7130, 0xd184, 0x1550, 0x080c, 0x347d, 0x0128, 0xc18d, 0x7132, - 0x080c, 0x6bcd, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, - 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, - 0x2483, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, - 0x1904, 0x2483, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, - 0x080c, 0x4c2e, 0x003e, 0x0804, 0x2483, 0x7038, 0xd08c, 0x1140, - 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2483, 0xc1ad, 0x2102, - 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c2e, 0x003e, 0x7130, - 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, - 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5, 0x2019, 0x000e, - 0x00c6, 0x2061, 0x0000, 0x080c, 0xe696, 0x00ce, 0x9484, 0x00ff, - 0x9080, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, - 0x2009, 0x000e, 0x080c, 0xe72a, 0x001e, 0x0016, 0x2009, 0x0002, - 0x2019, 0x0004, 0x080c, 0x32d5, 0x001e, 0x00a8, 0x0156, 0x00b6, - 0x20a9, 0x007f, 0x900e, 0x080c, 0x6789, 0x1140, 0x7030, 0xd084, - 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04, - 0x2473, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaae0, 0x080c, - 0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x001e, - 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0, - 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, - 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, - 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2af5, 0xd194, 0x0904, - 0x25a1, 0x0016, 0x080c, 0xaae0, 0x6220, 0xd2b4, 0x0904, 0x253c, - 0x080c, 0x88ec, 0x080c, 0xa08a, 0x2011, 0x0004, 0x080c, 0x2af5, - 0x00f6, 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2509, 0x7804, - 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, - 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, - 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, - 0x1df0, 0x080c, 0x2acb, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, - 0x0009, 0x080c, 0x2a82, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, - 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x080c, 0x97fe, - 0x080c, 0xaafc, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, - 0xaf2e, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, - 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, - 0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034, - 0x080c, 0xd33e, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, - 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa062, 0x0804, - 0x259e, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa11, 0x2019, 0x19f5, - 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c, - 0xafcc, 0x00ce, 0x0804, 0x259e, 0xd2bc, 0x0904, 0x2581, 0x080c, - 0x88f9, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00d6, 0x2069, 0x0140, - 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6, - 0x2061, 0x19e9, 0x6050, 0x080c, 0xd33e, 0x0120, 0x909a, 0x0003, - 0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c, - 0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88f1, 0x9080, - 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, - 0x0012, 0x080c, 0x2b04, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086, - 0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2b04, - 0x00e8, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00c0, 0x0036, 0x2019, - 0x0001, 0x080c, 0xa380, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065, - 0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, - 0x004f, 0x6003, 0x0003, 0x080c, 0xafcc, 0x00ce, 0x080c, 0xaafc, - 0x001e, 0xd19c, 0x0904, 0x2605, 0x7038, 0xd0ac, 0x1558, 0x0016, - 0x0156, 0x2011, 0x0008, 0x080c, 0x2af5, 0x080c, 0x2b18, 0x080c, - 0x2b4b, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25d0, - 0x1d04, 0x25b8, 0x080c, 0x8920, 0x6020, 0xd09c, 0x1db8, 0x00f6, - 0x2079, 0x0100, 0x080c, 0x2a2e, 0x00fe, 0x1d80, 0x6050, 0xc0e4, - 0x6052, 0x2011, 0x0008, 0x080c, 0x2af5, 0x015e, 0x001e, 0x04a8, - 0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0, - 0x080c, 0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000, - 0x080c, 0xeb7d, 0x080c, 0xeb98, 0x080c, 0x582a, 0xd0fc, 0x1138, - 0x080c, 0xd337, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e9, 0x9006, - 0x080c, 0x2abb, 0x2009, 0x0002, 0x080c, 0x2aa7, 0x00e6, 0x2071, - 0x1800, 0x7003, 0x0004, 0x080c, 0x0ed3, 0x00ee, 0x2011, 0x0008, - 0x080c, 0x2af5, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, - 0x080c, 0x2af5, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, - 0xd1a4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009, 0x2618, 0x00c0, - 0x2001, 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, - 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009, - 0x262a, 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, - 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, - 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2aa1, 0x2011, 0x0080, - 0x080c, 0x2af5, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, - 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x269a, 0x81ff, - 0x01a0, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x2011, 0x8011, 0x2019, - 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, - 0x2019, 0x0000, 0x080c, 0x4c2e, 0x0468, 0x2001, 0x19a9, 0x200c, - 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, - 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c2e, 0x080c, - 0x0ed3, 0x080c, 0x582a, 0xd0fc, 0x11a8, 0x080c, 0xd337, 0x1190, - 0x00c6, 0x080c, 0x2736, 0x080c, 0xaae0, 0x080c, 0xa2db, 0x080c, - 0xaafc, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, - 0x32d5, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, - 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, - 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, - 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, - 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, - 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, - 0x080c, 0x83c2, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3489, 0x200d, - 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3489, 0x200d, - 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, - 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, - 0x26e6, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, - 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, - 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, - 0x9080, 0xebac, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fb, 0x002e, - 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, - 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, - 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, - 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, - 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x272b, 0x680f, 0x0000, - 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5826, - 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, - 0x002e, 0x080c, 0xe72a, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, - 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a2, 0x080c, 0x2a1e, - 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, - 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, - 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, - 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, - 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, - 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, - 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, - 0x2018, 0x080c, 0x936c, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, - 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, - 0x080c, 0x76a5, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, - 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, - 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, - 0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e, 0x002e, 0x001e, 0x000e, - 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, - 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, - 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, - 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, - 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, - 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, - 0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, - 0x1a0c, 0x0d85, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, - 0x0005, 0x2800, 0x281e, 0x2842, 0x2844, 0x286d, 0x286f, 0x2871, - 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x2a6c, 0x2001, 0x1993, - 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, - 0x0009, 0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, - 0x001e, 0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x2009, 0x1996, - 0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, - 0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, - 0x29cf, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a3a, 0x2001, - 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2872, 0x080c, - 0x88fe, 0x0005, 0x080c, 0x0d85, 0x2001, 0x199b, 0x2003, 0x0036, - 0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, - 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29cf, - 0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, - 0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, - 0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x080c, 0x0d85, 0x080c, - 0x0d85, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, - 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, - 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0043, 0x012e, 0x015e, 0x00fe, - 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2894, 0x28b4, 0x28f4, - 0x2924, 0x2948, 0x2958, 0x295a, 0x080c, 0x2a2e, 0x11b0, 0x7850, - 0x9084, 0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, - 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, - 0x2001, 0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x297e, 0x2001, - 0xffff, 0x080c, 0x280f, 0x0005, 0x080c, 0x295c, 0x05e0, 0x2009, - 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1178, 0x7850, - 0x9084, 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, - 0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, - 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2964, - 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, - 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001, - 0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, - 0x0010, 0x080c, 0x2831, 0x0005, 0x080c, 0x295c, 0x0560, 0x2009, - 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1168, 0x7850, - 0x9084, 0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, - 0x1992, 0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, - 0x1118, 0x080c, 0x29a1, 0x0010, 0x080c, 0x2971, 0x080c, 0x2964, - 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, - 0x080c, 0x2831, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2a2e, - 0x11b8, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104, - 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, - 0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, - 0x0419, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285c, 0x0005, - 0x0099, 0x0168, 0x080c, 0x2a2e, 0x1138, 0x7850, 0x9084, 0xefff, - 0x7852, 0x080c, 0x2848, 0x0018, 0x0079, 0x080c, 0x285c, 0x0005, - 0x080c, 0x0d85, 0x080c, 0x0d85, 0x2009, 0x199b, 0x2104, 0x8001, - 0x200a, 0x090c, 0x29bd, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, - 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec, - 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, - 0x0010, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0005, 0x2009, 0x1996, - 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, - 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, - 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, - 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec, - 0x0005, 0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, - 0x0d85, 0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, - 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, 0x0d85, 0x9006, 0x0010, - 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, - 0x1991, 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x29c3, - 0x2001, 0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, - 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, - 0x9085, 0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, - 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, - 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, - 0x0000, 0x0158, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, - 0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb, - 0x9085, 0x0005, 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009, - 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c, - 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010, - 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, - 0x0064, 0x7820, 0x080c, 0x2aa1, 0xd09c, 0x1110, 0x1f04, 0x2a31, - 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c, - 0x2b18, 0x080c, 0x2b4b, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, - 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, - 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, - 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a5e, - 0x080c, 0x8920, 0x1f04, 0x2a5e, 0x7850, 0x9085, 0x1000, 0x7852, - 0x000e, 0x001e, 0x012e, 0x0005, 0x080c, 0x2b4b, 0x0005, 0x0006, - 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, - 0x1100, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a79, 0x00fe, 0x015e, - 0x000e, 0x0005, 0x1d04, 0x2a82, 0x080c, 0x8920, 0x1f04, 0x2a82, - 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e, - 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e, - 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e, - 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, - 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, - 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, - 0xa001, 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76bf, 0x0108, - 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, - 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, - 0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, - 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, - 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, - 0x0140, 0x2104, 0x1128, 0x080c, 0x76bf, 0x0110, 0xc0bc, 0x0008, - 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, - 0x7843, 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, - 0x7843, 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, - 0x0202, 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, - 0x9205, 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, - 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, - 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a82, - 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, - 0x080c, 0x2a82, 0x6054, 0xd0bc, 0x090c, 0x0d85, 0x20a9, 0x0005, - 0x080c, 0x2a82, 0x6054, 0xd0ac, 0x090c, 0x0d85, 0x2009, 0x19b0, - 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, - 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, - 0x0006, 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, - 0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, - 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, - 0x0800, 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d85, - 0x2001, 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, - 0x0006, 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, - 0x76a5, 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, - 0xa001, 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, - 0x080c, 0x76a5, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, - 0x4198, 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, - 0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, - 0x60ee, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, - 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26eb, 0x000e, - 0x00de, 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, - 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2aa1, - 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bd5, 0x080c, - 0x8920, 0x1f04, 0x2bd5, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, - 0x6052, 0x015e, 0x000e, 0x0005, 0x30e0, 0x30e0, 0x2ce4, 0x2ce4, - 0x2cf0, 0x2cf0, 0x2cfc, 0x2cfc, 0x2d0a, 0x2d0a, 0x2d16, 0x2d16, - 0x2d24, 0x2d24, 0x2d32, 0x2d32, 0x2d44, 0x2d44, 0x2d50, 0x2d50, - 0x2d5e, 0x2d5e, 0x2d7c, 0x2d7c, 0x2d9c, 0x2d9c, 0x2d6c, 0x2d6c, - 0x2d8c, 0x2d8c, 0x2daa, 0x2daa, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2dbc, 0x2dbc, 0x2dc8, 0x2dc8, - 0x2dd6, 0x2dd6, 0x2de4, 0x2de4, 0x2df4, 0x2df4, 0x2e02, 0x2e02, - 0x2e12, 0x2e12, 0x2e22, 0x2e22, 0x2e34, 0x2e34, 0x2e42, 0x2e42, - 0x2e52, 0x2e52, 0x2e74, 0x2e74, 0x2e98, 0x2e98, 0x2e62, 0x2e62, - 0x2e86, 0x2e86, 0x2ea8, 0x2ea8, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2ebc, 0x2ebc, 0x2ec8, 0x2ec8, - 0x2ed6, 0x2ed6, 0x2ee4, 0x2ee4, 0x2ef4, 0x2ef4, 0x2f02, 0x2f02, - 0x2f12, 0x2f12, 0x2f22, 0x2f22, 0x2f34, 0x2f34, 0x2f42, 0x2f42, - 0x2f52, 0x2f52, 0x2f62, 0x2f62, 0x2f74, 0x2f74, 0x2f84, 0x2f84, - 0x2f96, 0x2f96, 0x2fa8, 0x2fa8, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2fbc, 0x2fbc, 0x2fca, 0x2fca, - 0x2fda, 0x2fda, 0x2fea, 0x2fea, 0x2ffc, 0x2ffc, 0x300c, 0x300c, - 0x301e, 0x301e, 0x3030, 0x3030, 0x3044, 0x3044, 0x3054, 0x3054, - 0x3066, 0x3066, 0x3078, 0x3078, 0x308c, 0x308c, 0x309d, 0x309d, - 0x30b0, 0x30b0, 0x30c3, 0x30c3, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, - 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x2135, - 0x0804, 0x30d8, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, - 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, - 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, - 0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, - 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, - 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, - 0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0xab46, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, - 0x080c, 0xab46, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, - 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, - 0x080c, 0xab46, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, - 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, - 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x080c, 0x22e1, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, - 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, - 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4, 0x0804, 0x30d8, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, - 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, - 0x080c, 0x13d4, 0x080c, 0x2135, 0x04d8, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, - 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0440, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0xab46, - 0x080c, 0x2135, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, - 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0000, - 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, - 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b93, - 0x1904, 0x31f1, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, - 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31f1, 0x080c, - 0x31f6, 0x0804, 0x31f1, 0xd2cc, 0x1904, 0x31f1, 0x080c, 0x76a5, - 0x1120, 0x70af, 0xffff, 0x0804, 0x31f1, 0xd294, 0x0120, 0x70af, - 0xffff, 0x0804, 0x31f1, 0x080c, 0x3478, 0x0160, 0x080c, 0xd33e, - 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x317e, 0x70af, 0xffff, - 0x0804, 0x31f1, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, - 0x317e, 0xd28c, 0x1904, 0x317e, 0x0036, 0x73ac, 0x938e, 0xffff, - 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, - 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, - 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, - 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, - 0x003e, 0x04a0, 0x900e, 0x080c, 0x26a2, 0x080c, 0x671e, 0x1538, - 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, - 0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x080c, - 0x6bd5, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, - 0x080c, 0x6a7c, 0x0120, 0x080c, 0x320f, 0x0148, 0x0028, 0x080c, - 0x335b, 0x080c, 0x323b, 0x0118, 0x8318, 0x0804, 0x312b, 0x73ae, - 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x31f1, 0x9780, 0x3489, - 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, - 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, - 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31f1, 0x2700, - 0x0156, 0x0016, 0x9106, 0x0904, 0x31e6, 0xc484, 0x080c, 0x6789, - 0x0148, 0x080c, 0xd33e, 0x1904, 0x31e6, 0x080c, 0x671e, 0x1904, - 0x31ee, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, - 0x00c6, 0x2060, 0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, - 0x0000, 0x080c, 0x6bd5, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, - 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6bd5, 0x9082, - 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6743, 0x0028, 0x080c, - 0x33ee, 0x01a0, 0x080c, 0x3419, 0x0088, 0x080c, 0x335b, 0x080c, - 0xd33e, 0x1160, 0x080c, 0x323b, 0x0188, 0x0040, 0x080c, 0xd33e, - 0x1118, 0x080c, 0x33ee, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, - 0x015e, 0x1f04, 0x3197, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, - 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, - 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x671e, 0x1168, 0xb813, - 0x00ff, 0xb817, 0xfffe, 0x080c, 0x335b, 0x04a9, 0x0128, 0x70dc, - 0xc0bd, 0x70de, 0x080c, 0xd084, 0x001e, 0x00ce, 0x0005, 0x0016, - 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, - 0xb842, 0x080c, 0xaf9f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1, - 0x6023, 0x0001, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0000, 0x080c, - 0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, - 0x2009, 0x0004, 0x080c, 0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de, - 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, - 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xaf9f, 0x0548, - 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, - 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, - 0x3310, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006, 0x080c, 0x66bb, - 0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8, - 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xafcc, 0x9085, - 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, - 0x0026, 0x2009, 0x0080, 0x080c, 0x671e, 0x1140, 0xb813, 0x00ff, - 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, - 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xaed8, - 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006, - 0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091, - 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, - 0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, - 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, - 0x671e, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004, - 0x080c, 0xaed8, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, - 0x620a, 0x080c, 0xd0b1, 0x2009, 0x0022, 0x080c, 0xafcc, 0x9085, - 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, - 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0xaae0, 0x0106, 0x080c, - 0x95cc, 0x080c, 0x9538, 0x080c, 0xaa31, 0x080c, 0xbe95, 0x010e, - 0x090c, 0xaafc, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, - 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789, - 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, - 0x6198, 0x001e, 0x8108, 0x1f04, 0x32f5, 0x9686, 0x0001, 0x190c, - 0x344c, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, - 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c, - 0xaae0, 0x0106, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, - 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08, - 0x080c, 0xe440, 0x007e, 0x001e, 0x010e, 0x090c, 0xaafc, 0xba10, - 0xbb14, 0xbc84, 0x080c, 0x6198, 0xba12, 0xbb16, 0xbc86, 0x00be, - 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, - 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, - 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, - 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, - 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, - 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, - 0x2178, 0x080c, 0xaae0, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001, - 0x0078, 0x080c, 0x5826, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, - 0x2020, 0x2009, 0x002d, 0x080c, 0xe72a, 0x20a9, 0x0800, 0x9016, - 0x0026, 0x928e, 0x007e, 0x0904, 0x33ca, 0x928e, 0x007f, 0x0904, - 0x33ca, 0x928e, 0x0080, 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff, - 0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f, 0x0006, 0x2003, 0x0001, - 0x080c, 0x33db, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, - 0x2001, 0x0001, 0x080c, 0x6b9f, 0x00ce, 0x00be, 0x2019, 0x0029, - 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x00b6, - 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, - 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, - 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe440, - 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3380, 0x010e, 0x090c, - 0xaafc, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, - 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x5826, - 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, - 0x080c, 0xe72a, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, - 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6bcd, 0x11d0, - 0x2100, 0x080c, 0x26d5, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, - 0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, - 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, - 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaae0, - 0x0106, 0x0036, 0x2019, 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c, - 0xaafc, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, - 0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c, 0x3310, 0x001e, 0x080c, - 0x6743, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, - 0x080c, 0xa5c6, 0x080c, 0xea92, 0x002e, 0x001e, 0x0005, 0x2001, - 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x76a5, - 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x76a5, - 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, - 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6743, - 0x8108, 0x1f04, 0x345d, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, - 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, - 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, - 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, - 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, - 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, - 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, - 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, - 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, - 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, - 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, - 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, - 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, - 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, - 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, - 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, - 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, - 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, - 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, - 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, - 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, - 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, - 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, - 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, - 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, - 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, - 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, - 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, - 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, - 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, - 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x2009, 0x00f7, 0x080c, 0x60f4, 0x7940, 0x918c, 0x0010, 0x7942, + 0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2adc, 0xd19c, + 0x0120, 0x2011, 0x0008, 0x080c, 0x2adc, 0x0006, 0x0036, 0x0156, + 0x0000, 0x2001, 0x19a9, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a70, + 0x1148, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x0001, 0x080c, + 0x29ba, 0x00b8, 0x080c, 0x2a78, 0x1138, 0x9006, 0x080c, 0x29d7, + 0x9006, 0x080c, 0x29ba, 0x0068, 0x080c, 0x2a80, 0x1d50, 0x2001, + 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e5, 0x0804, + 0x0cbd, 0x20a9, 0x003a, 0x1d04, 0x0c13, 0x080c, 0x8918, 0x1f04, + 0x0c13, 0x080c, 0x76ae, 0x0148, 0x080c, 0x76c0, 0x1118, 0x080c, + 0x79ae, 0x0050, 0x080c, 0x76a5, 0x0dd0, 0x080c, 0x79a9, 0x080c, + 0x799f, 0x080c, 0x75cc, 0x0020, 0x2009, 0x00f8, 0x080c, 0x60f4, + 0x7850, 0xc0e5, 0x7852, 0x080c, 0x769d, 0x0120, 0x7843, 0x0090, + 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x8918, + 0x7820, 0xd09c, 0x15a0, 0x080c, 0x769d, 0x0904, 0x0c9f, 0x7824, + 0xd0ac, 0x1904, 0x0cc2, 0x080c, 0x76c0, 0x1548, 0x0046, 0x2021, + 0x0320, 0x8421, 0x1df0, 0x004e, 0x2011, 0x1800, 0x080c, 0x2adc, + 0x080c, 0x2a88, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, + 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0ce5, 0x8421, 0x1160, 0x1d04, 0x0c6f, 0x080c, 0x8918, 0x080c, + 0x79a9, 0x080c, 0x799f, 0x7003, 0x0001, 0x0804, 0x0cc2, 0x8319, + 0x1928, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0ce5, 0x1d04, 0x0c85, 0x080c, 0x8918, 0x2009, 0x199c, 0x2104, + 0x9005, 0x0118, 0x8001, 0x200a, 0x1188, 0x200b, 0x000a, 0x2011, + 0x0048, 0x080c, 0x2adc, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x7924, + 0x080c, 0x2a88, 0xd19c, 0x0110, 0x080c, 0x29a8, 0x00f0, 0x080c, + 0x76ae, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7671, 0x7003, + 0x0001, 0x00c0, 0x2011, 0x1800, 0x080c, 0x2adc, 0x080c, 0x2a88, + 0x7824, 0x080c, 0x76b7, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, + 0x0904, 0x0c77, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, + 0x2646, 0x00a0, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c, + 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x2011, 0x0048, + 0x080c, 0x2adc, 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x19a9, + 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, + 0x00fe, 0x004e, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, + 0x0071, 0x0d0c, 0x8918, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x004e, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, + 0x2071, 0x189e, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x359b, + 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x19ad, 0x2063, 0x0003, + 0x6007, 0x0003, 0x600b, 0x0012, 0x600f, 0x0137, 0x2001, 0x197d, + 0x900e, 0x2102, 0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, + 0x0218, 0x705f, 0xffff, 0x0008, 0x715e, 0x7067, 0xffff, 0x717e, + 0x7182, 0x080c, 0xd0a1, 0x70ef, 0x00c0, 0x2061, 0x196d, 0x6003, + 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, + 0x6017, 0x001f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x1975, 0x6003, + 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, + 0x601b, 0x0001, 0x611e, 0x2061, 0x198a, 0x6003, 0x514c, 0x6007, + 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182c, 0x2102, + 0x0005, 0x9016, 0x080c, 0x6783, 0x1178, 0xb804, 0x90c4, 0x00ff, + 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, + 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, + 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6, + 0x0010, 0x2091, 0x8000, 0x0e04, 0x0d7b, 0x0006, 0x0016, 0x2001, + 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, + 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, + 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be, + 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, + 0x0026, 0x2079, 0x0300, 0x2069, 0x1b2c, 0x7a08, 0x226a, 0x2069, + 0x1b2d, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, + 0x1b3a, 0x201a, 0x2019, 0x1b3d, 0x9016, 0x7808, 0xd09c, 0x0168, + 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b56, 0x0108, 0x0ca8, + 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1b3b, 0x782c, + 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a82, 0x901e, + 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, + 0x0dd2, 0x2069, 0x1aa2, 0x2019, 0x0050, 0x20a9, 0x0020, 0x7b26, + 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0ddf, 0x0491, 0x002e, + 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26, + 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, + 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x582f, + 0x1170, 0x080c, 0x0f26, 0x0110, 0x080c, 0x0e79, 0x080c, 0x582f, + 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c, 0x0f3a, 0x0c70, + 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, + 0x1120, 0x2001, 0x0015, 0x080c, 0xaae8, 0x2079, 0x0380, 0x2069, + 0x1b0c, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840, 0x680a, 0x7844, + 0x680e, 0x782c, 0x6812, 0x2019, 0x1b17, 0x9016, 0x7808, 0xd09c, + 0x0150, 0x7820, 0x201a, 0x8210, 0x8318, 0x8210, 0x9282, 0x0011, + 0x0ea8, 0x2011, 0xdead, 0x6a2a, 0x7830, 0x681a, 0x7834, 0x681e, + 0x7838, 0x6822, 0x783c, 0x6826, 0x7803, 0x0000, 0x2069, 0x1acc, + 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, + 0x1f04, 0x0e53, 0x2069, 0x1aec, 0x2019, 0x00b0, 0x20a9, 0x0020, + 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e60, 0x0005, + 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, + 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102, + 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f18, 0x20a9, + 0x0900, 0x080c, 0x0f4e, 0x2011, 0x0040, 0x080c, 0x0f18, 0x20a9, + 0x0900, 0x080c, 0x0f4e, 0x0c78, 0x0026, 0x080c, 0x0f26, 0x1188, + 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, + 0x2011, 0x0947, 0x0010, 0x2011, 0x1b47, 0x080c, 0x0f3a, 0x002e, + 0x0005, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, + 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70f3, + 0x0000, 0x1120, 0x70f3, 0x0fa0, 0x080c, 0x0f2b, 0x002e, 0x0005, + 0x0026, 0x080c, 0x0f26, 0x0148, 0xd0a4, 0x1138, 0x2011, 0xcdd5, + 0x0010, 0x2011, 0x0080, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x0026, + 0x70f3, 0x0000, 0x080c, 0x0f26, 0x1130, 0x2011, 0x8040, 0x080c, + 0x0f3a, 0x002e, 0x0005, 0x080c, 0x2a80, 0x1118, 0x2011, 0xcdc5, + 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x00e6, + 0x0016, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70ec, 0x71e8, 0x1118, + 0xc0e4, 0xc1f4, 0x0050, 0x0006, 0x3b00, 0x9084, 0xff3e, 0x20d8, + 0x000e, 0x70f3, 0x0000, 0xc0e5, 0xc1f5, 0x0099, 0x000e, 0x001e, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70ec, 0x1110, + 0xc0dc, 0x0008, 0xc0dd, 0x0016, 0x71e8, 0x0019, 0x001e, 0x00ee, + 0x0005, 0x70ee, 0x71ea, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, + 0x0ede, 0x0eb8, 0x0eb8, 0x0e8c, 0x0ec7, 0x0eb8, 0x0eb8, 0x0ec7, + 0xc284, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c1, 0x21d8, + 0x9084, 0xff3e, 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x183b, + 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70ec, + 0xd0e4, 0x0108, 0xc2e5, 0x72ee, 0xd0e4, 0x1118, 0x9294, 0x00c1, + 0x08f9, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70e8, 0xd0f4, + 0x0108, 0xc2f5, 0x72ea, 0xd0f4, 0x1140, 0x9284, 0x8000, 0x8005, + 0xc284, 0x9215, 0x9294, 0x00c1, 0x0861, 0x0005, 0x1d04, 0x0f4e, + 0x2091, 0x6000, 0x1f04, 0x0f4e, 0x0005, 0x890e, 0x810e, 0x810f, + 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d, + 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036, + 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003, + 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001, + 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02, + 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120, + 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189d, + 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210, + 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200, + 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026, + 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104, + 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e, + 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096, + 0x3348, 0x080c, 0x0f55, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e, + 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007, + 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b8, + 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298, + 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298, + 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180, 0x810f, 0x20a9, + 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0d59, + 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, + 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x107f, 0x009e, + 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x10f8, 0x090c, + 0x0d79, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, + 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, 0x73c0, 0x702c, + 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, 0x0d79, 0x2300, + 0x9202, 0x0120, 0x1a0c, 0x0d79, 0xa000, 0x0c98, 0x012e, 0x003e, + 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010, 0x9005, 0x0140, + 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0d79, 0xa000, 0x0cc8, + 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270, 0x70c2, 0x702c, + 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, + 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca, 0x0020, 0x0268, + 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000, + 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, + 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, + 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x012e, 0x00ee, + 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, + 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, + 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, + 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001, 0x0558, 0xa802, + 0x2048, 0x2009, 0x5600, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, + 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040, + 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308, + 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800, + 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420, + 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000, + 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be, 0x74c2, 0x0005, + 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168, + 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0558, + 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, + 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e, + 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a25, 0x7007, + 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, + 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x702b, 0x0060, + 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1132, 0x702b, 0x0060, 0x702b, + 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x113b, 0x702b, 0x0020, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, + 0x2071, 0x1a25, 0x701c, 0x9088, 0x1a2f, 0x280a, 0x8000, 0x9084, + 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0d79, 0x7004, 0x9005, + 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a25, 0x7004, + 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, + 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, + 0x7000, 0x0002, 0x1184, 0x1307, 0x1182, 0x1182, 0x12fb, 0x12fb, + 0x12fb, 0x12fb, 0x080c, 0x0d79, 0x701c, 0x7120, 0x9106, 0x1148, + 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, + 0x0005, 0x0096, 0x9180, 0x1a2f, 0x2004, 0x700a, 0x2048, 0x8108, + 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, + 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, + 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, + 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, + 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, + 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, + 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, + 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, + 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, + 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, + 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, + 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x1a25, 0x2104, 0xc095, + 0x200a, 0x080c, 0x1161, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a25, + 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0d72, 0x782b, + 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, + 0x00ee, 0x001e, 0x0005, 0x1172, 0x121a, 0x124e, 0x1326, 0x0d79, + 0x1341, 0x0d79, 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, + 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, + 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, + 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, + 0x7806, 0x080c, 0x11b7, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, + 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x7008, + 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, + 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, + 0x080c, 0x11cc, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, + 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, + 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, + 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, + 0x2001, 0x18b9, 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, + 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, + 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, + 0x009e, 0x080c, 0x1161, 0x0005, 0x00de, 0x009e, 0x080c, 0x1161, + 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, + 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x080c, 0x6f05, 0xa09f, 0x0000, 0xa0a3, + 0x0000, 0x2848, 0x080c, 0x107f, 0x009e, 0x0005, 0x00a6, 0xa0a0, + 0x904d, 0x090c, 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, + 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, + 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, + 0x2810, 0x080c, 0x1142, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, + 0x080c, 0x6f05, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, + 0x00c6, 0x2060, 0x080c, 0xaf4e, 0x00ce, 0x7008, 0x2048, 0xa89f, + 0x0000, 0xa8a3, 0x0000, 0x080c, 0x107f, 0x7007, 0x0000, 0x080c, + 0x1161, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, + 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, + 0x2001, 0x1930, 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, + 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, + 0x2091, 0x8000, 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, + 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, + 0xaa7c, 0x009e, 0x080c, 0x8e1e, 0x2009, 0x188c, 0x2104, 0x9084, + 0xfffc, 0x200a, 0x080c, 0x8c80, 0x7007, 0x0000, 0x080c, 0x1172, + 0x0005, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x0126, 0x2091, + 0x2200, 0x2079, 0x0300, 0x2071, 0x1a6f, 0x7003, 0x0000, 0x78bf, + 0x00f6, 0x0041, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, + 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x2001, 0x0165, 0x2003, + 0x4198, 0x7808, 0xd09c, 0x0120, 0x7820, 0x080c, 0x13aa, 0x0cc8, + 0x2001, 0x1a70, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, + 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, + 0x0400, 0x7827, 0x0031, 0x782b, 0x1a82, 0x78e3, 0xff00, 0x781f, + 0xff00, 0x781b, 0xff00, 0x2001, 0x1a71, 0x2003, 0x0000, 0x2001, + 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a82, + 0x602f, 0x1ddc, 0x2001, 0x181a, 0x2004, 0x9082, 0x1ddc, 0x6032, + 0x603b, 0x1ede, 0x602b, 0x1ac2, 0x6007, 0x1aa2, 0x2061, 0x1aa2, + 0x606f, 0x193e, 0x2001, 0x1929, 0x2004, 0x607a, 0x783f, 0x3474, + 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8, + 0x7820, 0x0026, 0x2010, 0x080c, 0xcc21, 0x0180, 0x2260, 0x6000, + 0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108, + 0x0020, 0x2009, 0x004c, 0x080c, 0xafec, 0x001e, 0x002e, 0x0005, + 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0d72, + 0xd19c, 0x05a0, 0x7820, 0x908c, 0xf000, 0x0540, 0x2060, 0x6020, + 0x9086, 0x0003, 0x1550, 0x6000, 0x9086, 0x0004, 0x1530, 0x6114, + 0x2148, 0xa876, 0xa87a, 0xa867, 0x0103, 0x080c, 0x6d26, 0x00b6, + 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, + 0x190c, 0x68ae, 0x00be, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x080c, + 0xaf77, 0x7808, 0xd09c, 0x19b0, 0x012e, 0x0005, 0x908a, 0x0024, + 0x1a0c, 0x0d79, 0x002b, 0x012e, 0x0005, 0x04b0, 0x012e, 0x0005, + 0x142c, 0x1452, 0x1482, 0x1487, 0x148b, 0x1490, 0x14b8, 0x14bc, + 0x14ca, 0x14ce, 0x142c, 0x159b, 0x159f, 0x1611, 0x1618, 0x142c, + 0x1619, 0x161a, 0x1625, 0x162c, 0x142c, 0x142c, 0x142c, 0x142c, + 0x142c, 0x142c, 0x142c, 0x1492, 0x142c, 0x145a, 0x147f, 0x1446, + 0x142c, 0x1466, 0x1430, 0x142e, 0x080c, 0x0d79, 0x080c, 0x0d72, + 0x080c, 0x1637, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a, 0x080c, + 0x8151, 0x080c, 0x1b3b, 0x0005, 0x6044, 0xd0fc, 0x190c, 0xab20, + 0x2009, 0x0055, 0x080c, 0xafec, 0x012e, 0x0005, 0x080c, 0x1637, + 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x2009, 0x0055, 0x080c, + 0xafec, 0x0005, 0x2009, 0x0048, 0x080c, 0x1637, 0x2060, 0x080c, + 0xafec, 0x0005, 0x2009, 0x0054, 0x080c, 0x1637, 0x2060, 0x6044, + 0xd0fc, 0x190c, 0xab20, 0x080c, 0xafec, 0x0005, 0x080c, 0x1637, + 0x2060, 0x0056, 0x0066, 0x080c, 0x1637, 0x2028, 0x080c, 0x1637, + 0x2030, 0x0036, 0x0046, 0x2021, 0x0000, 0x2418, 0x2009, 0x0056, + 0x080c, 0xafec, 0x004e, 0x003e, 0x006e, 0x005e, 0x0005, 0x080c, + 0x1637, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, + 0xc085, 0x7006, 0x0005, 0x080c, 0x1637, 0x080c, 0x1734, 0x0005, + 0x080c, 0x0d79, 0x080c, 0x1637, 0x2060, 0x6014, 0x0096, 0x2048, + 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xafec, 0x2001, + 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, + 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, + 0x1110, 0x080c, 0x163c, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, + 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1637, 0x2060, 0x6014, + 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, + 0xafec, 0x0005, 0x080c, 0x1637, 0x080c, 0x0d79, 0x080c, 0x1637, + 0x080c, 0x1586, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x1537, + 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001, + 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x153d, 0x7004, + 0x9005, 0x01c8, 0x1188, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, + 0x0000, 0xd1bc, 0x090c, 0x0d79, 0x2001, 0x020d, 0x2003, 0x0050, + 0x2003, 0x0020, 0x0804, 0x156b, 0x78ab, 0x0004, 0x7803, 0x0001, + 0x080c, 0x159f, 0x0005, 0x7827, 0x0018, 0xa001, 0x7828, 0x7827, + 0x0011, 0xa001, 0x7928, 0x9106, 0x0110, 0x79ac, 0x08e0, 0x00e6, + 0x2071, 0x0200, 0x702c, 0xd0c4, 0x0140, 0x00ee, 0x080c, 0x1b3b, + 0x080c, 0x135a, 0x7803, 0x0001, 0x0005, 0x7037, 0x0001, 0xa001, + 0x7150, 0x00ee, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x79ac, + 0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab, 0x0004, 0x7803, 0x0001, + 0x080c, 0x159f, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828, + 0x782b, 0x0000, 0x9065, 0x090c, 0x0d79, 0x6014, 0x2048, 0x78ab, + 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x080c, 0xcc33, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, + 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xc81b, + 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x2009, 0x004c, 0x080c, + 0xafec, 0x0048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x6024, 0x190c, 0xd036, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, + 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xebc0, 0xd5a4, + 0x1118, 0x080c, 0x163c, 0x0005, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, + 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, + 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x16ad, 0x00fe, 0x007e, + 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104, + 0x9184, 0x0004, 0x190c, 0x0d79, 0xd184, 0x11b1, 0xd19c, 0x0180, + 0xc19c, 0x7106, 0x0016, 0x080c, 0x1717, 0x001e, 0x0148, 0x2001, + 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x163c, 0x0005, + 0x81ff, 0x190c, 0x0d79, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106, + 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1606, 0x2071, 0x0200, 0x080c, + 0x1704, 0x05e0, 0x080c, 0x1717, 0x05b0, 0x6014, 0x9005, 0x05b0, + 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, + 0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6, + 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x00b0, 0x00f6, 0x2c78, 0x080c, + 0x192a, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201, + 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118, + 0x080c, 0x163c, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, + 0x135a, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x1717, + 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461, + 0x0c90, 0x0429, 0x2060, 0x2009, 0x0053, 0x080c, 0xafec, 0x0005, + 0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1, 0x0006, 0x7004, 0xc09d, + 0x7006, 0x000e, 0x080c, 0x916f, 0x0005, 0x0089, 0x9005, 0x0118, + 0x080c, 0x8d72, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820, + 0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x16ad, 0x0005, 0x7808, + 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x1586, 0x00d6, 0x2069, + 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, + 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, + 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, + 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x169f, 0x6827, + 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, + 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, + 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, + 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, + 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, + 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, + 0x0001, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, + 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, + 0x0021, 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x00e6, 0x2079, + 0x0300, 0x0006, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x1110, 0x78e3, + 0x0c0c, 0x8000, 0x700a, 0x0026, 0x2011, 0x0006, 0x7808, 0xd09c, + 0x0150, 0x0016, 0x0026, 0x00c6, 0x080c, 0x13c8, 0x00ce, 0x002e, + 0x001e, 0x8211, 0x1d98, 0x002e, 0x000e, 0x0006, 0x7832, 0x7936, + 0x7a3a, 0x781b, 0x8080, 0x00b9, 0x1178, 0x2071, 0x1a6f, 0x7008, + 0x9005, 0x0130, 0x8001, 0x0a0c, 0x0d79, 0x700a, 0x78e3, 0x0c00, + 0x000e, 0x00ee, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0d79, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, + 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, + 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, + 0x8000, 0x2004, 0x080c, 0x0d79, 0x7037, 0x0001, 0x7150, 0x7037, + 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, + 0xff00, 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, + 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, + 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a7f, 0x2404, + 0x8000, 0x0208, 0x2022, 0x080c, 0x8151, 0x080c, 0x1b3b, 0x9006, + 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, + 0x0016, 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, + 0xd08c, 0x0904, 0x1796, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, + 0xd0bc, 0x0904, 0x1796, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, + 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1796, 0x9c06, 0x15f0, + 0x0126, 0x2091, 0x2600, 0x080c, 0x80a9, 0x012e, 0x7358, 0x745c, + 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x190c, 0xd011, 0xab42, 0xac3e, 0x2001, 0x1869, + 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, + 0xffff, 0x080c, 0x1efe, 0x1190, 0x080c, 0x1987, 0x2a00, 0xa816, + 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, + 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, + 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x163c, 0x0005, 0x080c, + 0x0d79, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, + 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, + 0x9d84, 0x000f, 0x9088, 0x1ede, 0x2165, 0x0002, 0x17cd, 0x183b, + 0x17cd, 0x17cd, 0x17d1, 0x181c, 0x17cd, 0x17f1, 0x17c6, 0x1832, + 0x17cd, 0x17cd, 0x17d6, 0x1928, 0x1805, 0x17fb, 0xa964, 0x918c, + 0x00ff, 0x918e, 0x0048, 0x0904, 0x1832, 0x9085, 0x0001, 0x0804, + 0x191e, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1842, 0xa87c, 0xd0ac, + 0x0da0, 0x0804, 0x18ad, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, + 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, + 0x933f, 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0xa8ae, 0x0804, + 0x1906, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, + 0xa888, 0x0804, 0x1842, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, + 0xa88c, 0xa83e, 0xa888, 0x0804, 0x18ad, 0xa87c, 0xd0bc, 0x0928, + 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0d79, + 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ede, 0x2065, 0xa888, + 0xd19c, 0x1904, 0x18ad, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x17cd, + 0xa804, 0x9045, 0x090c, 0x0d79, 0xa164, 0xa91a, 0x91ec, 0x000f, + 0x9d80, 0x1ede, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, + 0x18ad, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006, 0xa842, + 0xa83e, 0x0804, 0x18ad, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006, + 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x9082, + 0x001b, 0x0002, 0x1865, 0x1865, 0x1867, 0x1865, 0x1865, 0x1865, + 0x1871, 0x1865, 0x1865, 0x1865, 0x187b, 0x1865, 0x1865, 0x1865, + 0x1885, 0x1865, 0x1865, 0x1865, 0x188f, 0x1865, 0x1865, 0x1865, + 0x1899, 0x1865, 0x1865, 0x1865, 0x18a3, 0x080c, 0x0d79, 0xa574, + 0xa478, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa37c, 0xa280, 0x0804, + 0x1906, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa38c, + 0xa290, 0x0804, 0x1906, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, + 0x17db, 0xa39c, 0xa2a0, 0x0804, 0x1906, 0xa5a4, 0xa4a8, 0x9d86, + 0x0024, 0x0904, 0x17db, 0xa3ac, 0xa2b0, 0x0804, 0x1906, 0xa5b4, + 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3bc, 0xa2c0, 0x0804, + 0x1906, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3cc, + 0xa2d0, 0x0804, 0x1906, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, + 0x17db, 0xa3dc, 0xa2e0, 0x0804, 0x1906, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x18d0, 0x18ce, 0x18ce, + 0x18ce, 0x18ce, 0x18ce, 0x18db, 0x18ce, 0x18ce, 0x18ce, 0x18ce, + 0x18ce, 0x18e6, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18f1, + 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18fc, 0x080c, 0x0d79, + 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17db, + 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, + 0x002c, 0x0904, 0x17db, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, + 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3ac, 0xa2b0, + 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, + 0x17db, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, + 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, + 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, + 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, + 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, + 0x0804, 0x17cd, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, + 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ed9, 0xa813, + 0x1ed9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, + 0x0d79, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, + 0x0d79, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, + 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, + 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, + 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, + 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, + 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d79, + 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ede, 0x2015, + 0x82ff, 0x090c, 0x0d79, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, + 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1ab1, 0x19de, + 0x19de, 0x1ab1, 0x19de, 0x1aab, 0x1ab1, 0x19de, 0x1a4e, 0x1a4e, + 0x1a4e, 0x1ab1, 0x1a4e, 0x1ab1, 0x1aa8, 0x1a4e, 0xc0fc, 0xa882, + 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1ab3, 0x2c05, + 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x19ca, + 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19ce, 0x19c8, 0x19c8, + 0x19c8, 0x19c8, 0x19c8, 0x19d2, 0x19c8, 0x19c8, 0x19c8, 0x19c8, + 0x19c8, 0x19d6, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19da, + 0x080c, 0x0d79, 0xa774, 0xa678, 0x0804, 0x1ab3, 0xa78c, 0xa690, + 0x0804, 0x1ab3, 0xa7a4, 0xa6a8, 0x0804, 0x1ab3, 0xa7bc, 0xa6c0, + 0x0804, 0x1ab3, 0xa7d4, 0xa6d8, 0x0804, 0x1ab3, 0xa898, 0x901d, + 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1a06, 0x1a06, 0x1a08, 0x1a06, 0x1a06, + 0x1a06, 0x1a12, 0x1a06, 0x1a06, 0x1a06, 0x1a1c, 0x1a06, 0x1a06, + 0x1a06, 0x1a26, 0x1a06, 0x1a06, 0x1a06, 0x1a30, 0x1a06, 0x1a06, + 0x1a06, 0x1a3a, 0x1a06, 0x1a06, 0x1a06, 0x1a44, 0x080c, 0x0d79, + 0xa574, 0xa478, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa37c, 0xa280, + 0x0804, 0x1ab3, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1ab3, + 0xa38c, 0xa290, 0x0804, 0x1ab3, 0xa594, 0xa498, 0x9d86, 0x0004, + 0x0904, 0x1ab3, 0xa39c, 0xa2a0, 0x0804, 0x1ab3, 0xa5a4, 0xa4a8, + 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3ac, 0xa2b0, 0x0804, 0x1ab3, + 0xa5b4, 0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3bc, 0xa2c0, + 0x0804, 0x1ab3, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1ab3, + 0xa3cc, 0xa2d0, 0x0804, 0x1ab3, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, + 0x0904, 0x1ab3, 0xa3dc, 0xa2e0, 0x0804, 0x1ab3, 0xa898, 0x901d, + 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1a76, 0x1a74, 0x1a74, 0x1a74, 0x1a74, + 0x1a74, 0x1a80, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a8a, + 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a94, 0x1a74, 0x1a74, + 0x1a74, 0x1a74, 0x1a74, 0x1a9e, 0x080c, 0x0d79, 0xa56c, 0xa470, + 0xa774, 0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498, + 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394, + 0xa298, 0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c, + 0x0510, 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, + 0x9d86, 0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, + 0xa7d4, 0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, + 0x9d86, 0x000e, 0x1130, 0x080c, 0x1eb4, 0x1904, 0x1987, 0x900e, + 0x0050, 0x080c, 0x0d79, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, + 0xae2a, 0x080c, 0x1eb4, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, + 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, + 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, + 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, + 0x0048, 0x080c, 0xafec, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, + 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, + 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xafec, 0x0005, + 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, + 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, + 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, + 0xd09c, 0x0120, 0x080c, 0x13c8, 0x8631, 0x1db8, 0x00ce, 0x781f, + 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x13c8, + 0x00ce, 0x2001, 0x0038, 0x080c, 0x1bcb, 0x7930, 0x9186, 0x0040, + 0x0160, 0x9186, 0x0042, 0x190c, 0x0d79, 0x2001, 0x001e, 0x8001, + 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1bda, 0x000e, 0x6022, 0x012e, + 0x0005, 0x080c, 0x1bc7, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, + 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, + 0x78ab, 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0d79, 0x7aac, + 0xd2ac, 0x1dd0, 0x00fe, 0x080c, 0x769d, 0x1188, 0x2001, 0x0138, + 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, + 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x773f, 0x0479, + 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, + 0x00e6, 0x2071, 0x0200, 0x080c, 0x2a94, 0x2009, 0x003c, 0x080c, + 0x223d, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, + 0x1de0, 0x080c, 0x8732, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, + 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, + 0x080c, 0x135a, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, + 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, + 0x0000, 0x080c, 0x769d, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, + 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, + 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, + 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, + 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, + 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, + 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x16ad, 0x7930, + 0x0005, 0x2c08, 0x621c, 0x080c, 0x16f6, 0x7930, 0x0005, 0x8001, + 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, + 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1c38, 0x2001, + 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0d79, 0x781f, 0x0202, + 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, + 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, + 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, + 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, + 0x2001, 0x0030, 0x080c, 0x1bd1, 0x9186, 0x0040, 0x190c, 0x0d79, + 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, + 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, + 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, + 0x9184, 0x0007, 0x090c, 0x0d79, 0xa001, 0xa001, 0x781f, 0x0200, + 0x0005, 0x0126, 0x2091, 0x2400, 0x2079, 0x0380, 0x2001, 0x19e9, + 0x2070, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, + 0x6014, 0x2048, 0xa964, 0xa91a, 0x918c, 0x00ff, 0x9184, 0x000f, + 0x0002, 0x1c6d, 0x1c6d, 0x1c6d, 0x1c6f, 0x1c6d, 0x1c6d, 0x1c6d, + 0x1c6d, 0x1c61, 0x1c77, 0x1c6d, 0x1c73, 0x1c6d, 0x1c6d, 0x1c6d, + 0x1c6d, 0x9086, 0x0008, 0x1148, 0xa87c, 0xd0b4, 0x0904, 0x1de7, + 0x2011, 0x1ed9, 0x2205, 0xab88, 0x00a8, 0x080c, 0x0d79, 0x9186, + 0x0013, 0x0128, 0x0cd0, 0x9186, 0x001b, 0x0108, 0x0cb0, 0xa87c, + 0xd0b4, 0x0904, 0x1de7, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2015, + 0x2205, 0xab88, 0x2908, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x9006, + 0xa842, 0xa83e, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, + 0x3e60, 0x6014, 0x2048, 0xa88c, 0xa990, 0xaaac, 0xabb0, 0xaa36, + 0xab3a, 0xa83e, 0xa942, 0xa846, 0xa94a, 0xa964, 0x918c, 0x00ff, + 0x9186, 0x001e, 0x0198, 0x2940, 0xa064, 0xa81a, 0x90ec, 0x000f, + 0x9d80, 0x1ede, 0x2065, 0x2c05, 0x2808, 0x2c10, 0xab88, 0xa80a, + 0xa90e, 0xaa12, 0xab16, 0x012e, 0x3e60, 0x0005, 0xa804, 0x2040, + 0x0c58, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, + 0xa97c, 0x2950, 0xd1dc, 0x1904, 0x1db1, 0xc1dd, 0xa97e, 0x9006, + 0xa842, 0xa83e, 0xa988, 0x8109, 0xa916, 0xa964, 0xa91a, 0x9184, + 0x000f, 0x9088, 0x1ede, 0x2145, 0x0002, 0x1ce5, 0x1cf3, 0x1ce5, + 0x1ce5, 0x1ce5, 0x1ce7, 0x1ce5, 0x1ce5, 0x1d48, 0x1d48, 0x1ce5, + 0x1ce5, 0x1ce5, 0x1d46, 0x1ce5, 0x1ce5, 0x080c, 0x0d79, 0xa804, + 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2045, + 0xd19c, 0x1904, 0x1d48, 0x9036, 0x2638, 0x2805, 0x908a, 0x0036, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x1d18, 0x1d18, 0x1d1a, + 0x1d18, 0x1d18, 0x1d18, 0x1d20, 0x1d18, 0x1d18, 0x1d18, 0x1d26, + 0x1d18, 0x1d18, 0x1d18, 0x1d2c, 0x1d18, 0x1d18, 0x1d18, 0x1d32, + 0x1d18, 0x1d18, 0x1d18, 0x1d38, 0x1d18, 0x1d18, 0x1d18, 0x1d3e, + 0x080c, 0x0d79, 0xb574, 0xb478, 0xb37c, 0xb280, 0x0804, 0x1d8d, + 0xb584, 0xb488, 0xb38c, 0xb290, 0x0804, 0x1d8d, 0xb594, 0xb498, + 0xb39c, 0xb2a0, 0x0804, 0x1d8d, 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, + 0x0804, 0x1d8d, 0xb5b4, 0xb4b8, 0xb3bc, 0xb2c0, 0x0804, 0x1d8d, + 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, 0x0804, 0x1d8d, 0xb5d4, 0xb4d8, + 0xb3dc, 0xb2e0, 0x0804, 0x1d8d, 0x0804, 0x1d8d, 0x080c, 0x0d79, + 0x2805, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, + 0x1d6b, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d72, 0x1d69, + 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d79, 0x1d69, 0x1d69, 0x1d69, + 0x1d69, 0x1d69, 0x1d80, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69, + 0x1d87, 0x080c, 0x0d79, 0xb56c, 0xb470, 0xb774, 0xb678, 0xb37c, + 0xb280, 0x00d8, 0xb584, 0xb488, 0xb78c, 0xb690, 0xb394, 0xb298, + 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, 0xb6a8, 0xb3ac, 0xb2b0, 0x0068, + 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, 0xb3c4, 0xb2c8, 0x0030, 0xb5cc, + 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, 0xb2e0, 0xab2e, 0xaa32, 0xad1e, + 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8109, 0xa916, 0x1118, 0x9006, + 0x012e, 0x0005, 0x8840, 0x2805, 0x9005, 0x1168, 0xb004, 0x9005, + 0x090c, 0x0d79, 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, + 0x1ede, 0x2045, 0x2805, 0x2810, 0x2a08, 0xa80a, 0xa90e, 0xaa12, + 0x0c30, 0x3e60, 0x6344, 0xd3fc, 0x190c, 0x0d79, 0xa93c, 0xaa40, + 0xa844, 0x9106, 0x1118, 0xa848, 0x9206, 0x0508, 0x2958, 0xab48, + 0xac44, 0x2940, 0x080c, 0x1efe, 0x1998, 0x2850, 0x2c40, 0xab14, + 0xa880, 0xd0fc, 0x1140, 0xa810, 0x2005, 0xa80a, 0x2a00, 0xa80e, + 0x2009, 0x8015, 0x0070, 0x00c6, 0x3e60, 0x6044, 0xc0a4, 0x9085, + 0x8005, 0x6046, 0x00ce, 0x8319, 0xab16, 0x1904, 0x1d9a, 0x2009, + 0x8005, 0x3e60, 0x6044, 0x9105, 0x6046, 0x0804, 0x1d97, 0x080c, + 0x0d79, 0x00f6, 0x00e6, 0x0096, 0x00c6, 0x0026, 0x704c, 0x9c06, + 0x190c, 0x0d79, 0x2079, 0x0090, 0x2001, 0x0105, 0x2003, 0x0010, + 0x782b, 0x0004, 0x7057, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1170, + 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, + 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x704c, 0x2060, + 0x00c6, 0x080c, 0xc81b, 0x080c, 0xaaf7, 0x00ce, 0x704c, 0x9c06, + 0x1150, 0x2009, 0x0040, 0x080c, 0x223d, 0x080c, 0xa59c, 0x2011, + 0x0000, 0x080c, 0xa430, 0x002e, 0x00ce, 0x009e, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x0090, 0x781c, 0x0006, 0x7818, 0x0006, + 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, + 0x2019, 0x1000, 0x8319, 0x090c, 0x0d79, 0x7820, 0xd0bc, 0x1dd0, + 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, + 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, + 0x7816, 0x2079, 0x0090, 0x782b, 0x0008, 0x7057, 0x0000, 0x00fe, + 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000, + 0x0904, 0x1eaf, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, + 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, + 0xec09, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x0016, + 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x2001, 0x020c, 0x2102, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, + 0x2009, 0x0040, 0x080c, 0x223d, 0x782c, 0xd0fc, 0x09a8, 0x080c, + 0xab13, 0x782c, 0xd0fc, 0x1de8, 0x080c, 0xaaf7, 0x7054, 0x9086, + 0x0000, 0x1950, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, + 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0x080c, 0x0d79, 0x8c60, 0x2c05, 0x9005, 0x0110, + 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, + 0x9084, 0x000f, 0x9080, 0x1ede, 0x2065, 0x8cff, 0x090c, 0x0d79, + 0x8a51, 0x0005, 0x2050, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, + 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, + 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1ed1, + 0x1ecd, 0x1ed1, 0x1ed1, 0x1edb, 0x0000, 0x1ed1, 0x1ed8, 0x1ed8, + 0x1ed5, 0x1ed8, 0x1ed8, 0x0000, 0x1edb, 0x1ed8, 0x0000, 0x1ed3, + 0x1ed3, 0x0000, 0x1ed3, 0x1edb, 0x0000, 0x1ed3, 0x1ed9, 0x1ed9, + 0x1ed9, 0x0000, 0x1ed9, 0x0000, 0x1edb, 0x1ed9, 0x00c6, 0x00d6, + 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20dd, 0x2940, + 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, + 0x2061, 0x1ed9, 0x00d0, 0x9de0, 0x1ede, 0x9d86, 0x0007, 0x0130, + 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20dd, + 0xa004, 0x9045, 0x0904, 0x20dd, 0x08d8, 0x2c05, 0x9005, 0x0904, + 0x1fc5, 0xdd9c, 0x1904, 0x1f81, 0x908a, 0x0036, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1f56, 0x1f56, 0x1f58, 0x1f56, 0x1f56, + 0x1f56, 0x1f5e, 0x1f56, 0x1f56, 0x1f56, 0x1f64, 0x1f56, 0x1f56, + 0x1f56, 0x1f6a, 0x1f56, 0x1f56, 0x1f56, 0x1f70, 0x1f56, 0x1f56, + 0x1f56, 0x1f76, 0x1f56, 0x1f56, 0x1f56, 0x1f7c, 0x080c, 0x0d79, + 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1fbb, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x0804, 0x1fbb, 0xa09c, 0x9422, 0xa0a0, 0x931b, + 0x0804, 0x1fbb, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1fbb, + 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1fbb, 0xa0cc, 0x9422, + 0xa0d0, 0x931b, 0x0804, 0x1fbb, 0xa0dc, 0x9422, 0xa0e0, 0x931b, + 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, + 0x1fa3, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa8, 0x1fa1, + 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fad, 0x1fa1, 0x1fa1, 0x1fa1, + 0x1fa1, 0x1fa1, 0x1fb2, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, + 0x1fb7, 0x080c, 0x0d79, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, + 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, + 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, + 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51, + 0x0904, 0x20dd, 0x8c60, 0x0804, 0x1f2d, 0xa004, 0x9045, 0x0904, + 0x20dd, 0x0804, 0x1f08, 0x8a51, 0x0904, 0x20dd, 0x8c60, 0x2c05, + 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20dd, 0xa064, 0x90ec, + 0x000f, 0x9de0, 0x1ede, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, + 0x0804, 0x20d2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, + 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x206f, 0x9082, 0x001b, 0x0002, + 0x200b, 0x200b, 0x200d, 0x200b, 0x200b, 0x200b, 0x201b, 0x200b, + 0x200b, 0x200b, 0x2029, 0x200b, 0x200b, 0x200b, 0x2037, 0x200b, + 0x200b, 0x200b, 0x2045, 0x200b, 0x200b, 0x200b, 0x2053, 0x200b, + 0x200b, 0x200b, 0x2061, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa074, 0x9420, 0xa078, + 0x9319, 0x0804, 0x20cd, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, + 0x911b, 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, + 0x20cd, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20cd, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0a4, + 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20cd, 0xa1bc, 0x2400, 0x9122, + 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8, + 0x9319, 0x0804, 0x20cd, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, + 0x911b, 0x0a0c, 0x0d79, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, + 0x20cd, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20cd, 0x9082, + 0x001b, 0x0002, 0x208d, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, + 0x209a, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, 0x20a7, 0x208b, + 0x208b, 0x208b, 0x208b, 0x208b, 0x20b4, 0x208b, 0x208b, 0x208b, + 0x208b, 0x208b, 0x20c1, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa06c, 0x9420, 0xa070, + 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, + 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa09c, + 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, + 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8, 0x9319, + 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880, + 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, + 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, + 0x9085, 0x0001, 0x0005, 0x00c6, 0x610c, 0x0016, 0x9026, 0x2410, + 0x6004, 0x9420, 0x9291, 0x0000, 0x2c04, 0x9210, 0x9ce0, 0x0002, + 0x918a, 0x0002, 0x1da8, 0x9284, 0x000f, 0x9405, 0x001e, 0x00ce, + 0x0005, 0x7803, 0x0003, 0x780f, 0x0000, 0x6004, 0x7812, 0x2c04, + 0x7816, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1db8, 0x0005, 0x2001, + 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0d72, 0xd094, 0x0110, 0x080c, + 0x11fc, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, + 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, + 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, + 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, + 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x223a, 0x7900, + 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, + 0x2158, 0x2150, 0x80a9, 0x2150, 0x2152, 0x2152, 0x2152, 0x2152, + 0x808f, 0x2150, 0x2154, 0x2150, 0x2152, 0x2150, 0x2152, 0x2150, + 0x080c, 0x0d79, 0x0031, 0x0020, 0x080c, 0x808f, 0x080c, 0x80a9, + 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xec09, 0x7930, 0x9184, + 0x0003, 0x0510, 0x080c, 0xaaf7, 0x2001, 0x19fc, 0x2004, 0x9005, + 0x01a0, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x00c6, + 0x2001, 0x19fc, 0x2064, 0x080c, 0xab13, 0x080c, 0xc81b, 0x2009, + 0x0040, 0x080c, 0x223d, 0x00ce, 0x0408, 0x2009, 0x0040, 0x080c, + 0x223d, 0x080c, 0xab13, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, + 0x9286, 0x0003, 0x0160, 0x080c, 0x769d, 0x1138, 0x080c, 0x799f, + 0x080c, 0x6178, 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x080c, + 0x8147, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, + 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, + 0x080c, 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1970, 0x2102, + 0x2001, 0x1978, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, + 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, + 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, + 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, + 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, + 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, + 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, + 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, + 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, + 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, + 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, + 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, + 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, + 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, + 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, + 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, + 0x000e, 0x0005, 0x7938, 0x080c, 0x0d72, 0x00f6, 0x2079, 0x0200, + 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, + 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, + 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, + 0x0000, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001, 0x199e, 0x2003, + 0x0700, 0x2001, 0x199f, 0x2003, 0x0700, 0x080c, 0x2aff, 0x9006, + 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x20a9, 0x0012, 0x1d04, + 0x226f, 0x2091, 0x6000, 0x1f04, 0x226f, 0x602f, 0x0100, 0x602f, + 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6224, + 0x080c, 0x2adc, 0x080c, 0x26da, 0x2009, 0x00ef, 0x6132, 0x6136, + 0x080c, 0x26ea, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, + 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, + 0x349f, 0x00c6, 0x2061, 0x0140, 0x608b, 0x000b, 0x608f, 0x10b8, + 0x6093, 0x0000, 0x6097, 0x0198, 0x00ce, 0x6004, 0x9085, 0x8000, + 0x6006, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, + 0x22ad, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, + 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, + 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402c, 0x012e, + 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, + 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, 0x1835, 0x2003, 0x0000, + 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, + 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, 0x910c, 0x0066, 0x2031, + 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, 0xd1bc, + 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, 0x1118, + 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, 0x0082, + 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, 0x001e, 0x0d70, 0x0c98, + 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0d30, 0x0c58, + 0x231b, 0x2318, 0x2318, 0x2318, 0x231a, 0x2318, 0x2318, 0x2318, + 0x080c, 0x0d79, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, + 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x25a0, + 0xd1f4, 0x190c, 0x0d72, 0x080c, 0x769d, 0x0904, 0x2378, 0x080c, + 0xd35d, 0x1120, 0x7000, 0x9086, 0x0003, 0x0580, 0x6024, 0x9084, + 0x1800, 0x0560, 0x080c, 0x76c0, 0x0118, 0x080c, 0x76ae, 0x1530, + 0x2011, 0x0020, 0x080c, 0x2adc, 0x6043, 0x0000, 0x080c, 0xd35d, + 0x0168, 0x080c, 0x76c0, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001, + 0x6027, 0x1800, 0x080c, 0x7511, 0x0804, 0x25a3, 0x70a4, 0x9005, + 0x1150, 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x76f1, + 0x00de, 0x1904, 0x25a3, 0x080c, 0x79a9, 0x0428, 0x080c, 0x76c0, + 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x79a9, + 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc, 0x0804, 0x25a0, + 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, + 0x1190, 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, + 0x7880, 0x0804, 0x25a0, 0x080c, 0x79a4, 0x0048, 0x2001, 0x197e, + 0x2003, 0x0002, 0x0020, 0x080c, 0x77db, 0x0804, 0x25a0, 0x080c, + 0x7923, 0x0804, 0x25a0, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, + 0x260b, 0xd2b4, 0x1904, 0x261d, 0x0000, 0xd1ac, 0x0904, 0x24ad, + 0x0036, 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x769d, 0x11d0, + 0x2011, 0x0020, 0x080c, 0x2adc, 0x0006, 0x0026, 0x0036, 0x080c, + 0x76b7, 0x1158, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc, + 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, + 0x080c, 0x7671, 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, + 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, + 0x74da, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190, 0x080c, 0xd35d, + 0x1118, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148, 0xc085, + 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c28, 0x003e, + 0x080c, 0xd356, 0x1904, 0x2482, 0x9196, 0xff00, 0x05a8, 0x7060, + 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, + 0xd184, 0x1550, 0x080c, 0x3468, 0x0128, 0xc18d, 0x7132, 0x080c, + 0x6bc5, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, + 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2482, + 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, + 0x2482, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, + 0x4c28, 0x003e, 0x0804, 0x2482, 0x7038, 0xd08c, 0x1140, 0x2001, + 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2482, 0xc1ad, 0x2102, 0x0036, + 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c28, 0x003e, 0x7130, 0xc185, + 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, + 0x0001, 0x2011, 0x0100, 0x080c, 0x8add, 0x2019, 0x000e, 0x00c6, + 0x2061, 0x0000, 0x080c, 0xe701, 0x00ce, 0x9484, 0x00ff, 0x9080, + 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, + 0x000e, 0x080c, 0xe795, 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, + 0x0004, 0x080c, 0x32c0, 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9, + 0x007f, 0x900e, 0x080c, 0x6783, 0x1140, 0x7030, 0xd084, 0x1118, + 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x2472, + 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaaf7, 0x080c, 0xadbe, + 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x001e, 0x2001, + 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0, 0x2011, + 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, + 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, + 0x0000, 0x2011, 0x0020, 0x080c, 0x2adc, 0xd194, 0x0904, 0x25a0, + 0x0016, 0x080c, 0xaaf7, 0x6220, 0xd2b4, 0x0904, 0x253b, 0x080c, + 0x88e4, 0x080c, 0xa09b, 0x2011, 0x0004, 0x080c, 0x2adc, 0x00f6, + 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2508, 0x7804, 0x9086, + 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, + 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, + 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, + 0x080c, 0x2ab2, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, + 0x080c, 0x2a69, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, + 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x97f6, 0x080c, + 0xab13, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xaf4e, + 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, + 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, + 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034, 0x080c, + 0xd35d, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, + 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa073, 0x0804, 0x259d, + 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa28, 0x2019, 0x19f5, 0x2304, + 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c, 0xafec, + 0x00ce, 0x0804, 0x259d, 0xd2bc, 0x0904, 0x2580, 0x080c, 0x88f1, + 0x2011, 0x0004, 0x080c, 0x2adc, 0x00d6, 0x2069, 0x0140, 0x6804, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061, + 0x19e9, 0x6050, 0x080c, 0xd35d, 0x0120, 0x909a, 0x0003, 0x1668, + 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c, 0x00ce, + 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88e9, 0x9080, 0x0008, + 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, + 0x080c, 0x2aeb, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009, + 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2aeb, 0x00e8, + 0x2011, 0x0004, 0x080c, 0x2adc, 0x00c0, 0x0036, 0x2019, 0x0001, + 0x080c, 0xa391, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065, 0x0160, + 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, + 0x6003, 0x0003, 0x080c, 0xafec, 0x00ce, 0x080c, 0xab13, 0x001e, + 0xd19c, 0x0904, 0x2604, 0x7038, 0xd0ac, 0x1558, 0x0016, 0x0156, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x080c, 0x2aff, 0x080c, 0x2b32, + 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25cf, 0x1d04, + 0x25b7, 0x080c, 0x8918, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, + 0x0100, 0x080c, 0x2a19, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x015e, 0x001e, 0x04a8, 0x015e, + 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x080c, + 0xadbe, 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, + 0xebe8, 0x080c, 0xec03, 0x080c, 0x5824, 0xd0fc, 0x1138, 0x080c, + 0xd356, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c, + 0x2aa2, 0x2009, 0x0002, 0x080c, 0x2a8e, 0x00e6, 0x2071, 0x1800, + 0x7003, 0x0004, 0x080c, 0x0ec7, 0x00ee, 0x2011, 0x0008, 0x080c, + 0x2adc, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, 0x080c, + 0x2adc, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, + 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2617, 0x00c0, 0x2001, + 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, 0x0387, + 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2629, + 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, 0x6028, + 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, + 0xffff, 0x6043, 0x0001, 0x080c, 0x2a88, 0x2011, 0x0080, 0x080c, + 0x2adc, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x2699, 0x81ff, 0x01a0, + 0x2009, 0x0000, 0x080c, 0x2a8e, 0x2011, 0x8011, 0x2019, 0x010e, + 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, + 0x0000, 0x080c, 0x4c28, 0x0468, 0x2001, 0x19aa, 0x200c, 0x81ff, + 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, + 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c28, 0x080c, 0x0ec7, + 0x080c, 0x5824, 0xd0fc, 0x11a8, 0x080c, 0xd356, 0x1190, 0x00c6, + 0x080c, 0x2735, 0x080c, 0xaaf7, 0x080c, 0xa2ec, 0x080c, 0xab13, + 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x32c0, + 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, + 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, + 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294, + 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214, + 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, + 0x83ba, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3474, 0x200d, 0x918c, + 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3474, 0x200d, 0x918c, + 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003, + 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x26e5, + 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, + 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, + 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, + 0xec17, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fa, 0x002e, 0x00de, + 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, + 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, + 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112, + 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, + 0x2001, 0x0404, 0x680e, 0x1f04, 0x272a, 0x680f, 0x0000, 0x000e, + 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5820, 0xd0c4, + 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, + 0x080c, 0xe795, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, + 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a1, 0x080c, 0x2a09, 0x0660, + 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e, + 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420, + 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, + 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, + 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548, + 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300, + 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018, + 0x080c, 0x9364, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, + 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, + 0x769d, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe, + 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, + 0x0003, 0x0110, 0x080c, 0x0d72, 0x002e, 0x001e, 0x000e, 0x012e, + 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, + 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c, + 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007, + 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007, + 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018, + 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016, + 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c, + 0x0d79, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, + 0x27ff, 0x281d, 0x2841, 0x2843, 0x286c, 0x286e, 0x2870, 0x2001, + 0x0001, 0x080c, 0x2646, 0x080c, 0x2a53, 0x2001, 0x1993, 0x2003, + 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, + 0x080c, 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, + 0x2011, 0x2871, 0x080c, 0x88f6, 0x0005, 0x2009, 0x1996, 0x200b, + 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003, + 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x29ba, + 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a25, 0x2001, 0x1991, + 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2871, 0x080c, 0x88f6, + 0x0005, 0x080c, 0x0d79, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, + 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, 0x2001, + 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, + 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, + 0x2871, 0x080c, 0x88f6, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79, + 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, + 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a, + 0x0007, 0x1a0c, 0x0d79, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, + 0x002e, 0x001e, 0x000e, 0x0005, 0x2893, 0x28af, 0x28eb, 0x2917, + 0x2937, 0x2943, 0x2945, 0x080c, 0x2a19, 0x1190, 0x2009, 0x1999, + 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, + 0x0008, 0xc085, 0x200a, 0x2001, 0x1991, 0x2003, 0x0001, 0x0030, + 0x080c, 0x2969, 0x2001, 0xffff, 0x080c, 0x280e, 0x0005, 0x080c, + 0x2947, 0x05c0, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, + 0x2a19, 0x1158, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518, + 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104, + 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x294f, 0x00c0, + 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x1993, + 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010, + 0x080c, 0x2830, 0x0005, 0x080c, 0x2947, 0x0540, 0x2009, 0x199a, + 0x2104, 0x8001, 0x200a, 0x080c, 0x2a19, 0x1148, 0x2001, 0x1991, + 0x2003, 0x0003, 0x2001, 0x1992, 0x2003, 0x0000, 0x00b8, 0x2009, + 0x199a, 0x2104, 0x9005, 0x1118, 0x080c, 0x298c, 0x0010, 0x080c, + 0x295c, 0x080c, 0x294f, 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, + 0x1993, 0x2003, 0x0001, 0x080c, 0x2830, 0x0000, 0x0005, 0x0479, + 0x01e8, 0x080c, 0x2a19, 0x1198, 0x2009, 0x1997, 0x2104, 0x8000, + 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003, + 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x00f9, + 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285b, 0x0005, 0x0079, + 0x0148, 0x080c, 0x2a19, 0x1118, 0x080c, 0x2847, 0x0018, 0x0079, + 0x080c, 0x285b, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79, 0x2009, + 0x199b, 0x2104, 0x8001, 0x200a, 0x090c, 0x29a8, 0x0005, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x29d7, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, + 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, + 0x0005, 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, + 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, + 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x29d7, 0x0005, 0x0086, 0x2001, 0x1999, 0x2004, + 0x9084, 0x7fff, 0x090c, 0x0d79, 0x2009, 0x1998, 0x2144, 0x8846, + 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, + 0x0d79, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, + 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9, 0x0009, 0x2003, 0x0000, + 0x8000, 0x1f04, 0x29ae, 0x2001, 0x1998, 0x2003, 0x8000, 0x015e, + 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, + 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009, 0x199e, + 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, + 0x783a, 0x2009, 0x199f, 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfffa, + 0x9085, 0x0004, 0x783a, 0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8, + 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x7850, 0x9084, + 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, + 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, + 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, + 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a88, 0xd09c, + 0x1110, 0x1f04, 0x2a1c, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, + 0x2091, 0x8000, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, 0x783b, + 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, 0x0060, + 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, 0x0003, + 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a45, 0x080c, + 0x8918, 0x1f04, 0x2a45, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, + 0x001e, 0x012e, 0x0005, 0x080c, 0x2b32, 0x0005, 0x0006, 0x0156, + 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100, + 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a60, 0x00fe, 0x015e, 0x000e, + 0x0005, 0x1d04, 0x2a69, 0x080c, 0x8918, 0x1f04, 0x2a69, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, + 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, + 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, + 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, + 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76b7, 0x0108, 0xc0bc, + 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, + 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, + 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, + 0x2104, 0x1128, 0x080c, 0x76b7, 0x0110, 0xc0bc, 0x0008, 0xc0bd, + 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, + 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843, + 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202, + 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205, + 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff, + 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x6050, + 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c, + 0x2a69, 0x6054, 0xd0bc, 0x090c, 0x0d79, 0x20a9, 0x0005, 0x080c, + 0x2a69, 0x6054, 0xd0ac, 0x090c, 0x0d79, 0x2009, 0x19b1, 0x9084, + 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd, + 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x0006, + 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, 0x0006, + 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, 0x0006, + 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, 0x0800, + 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d79, 0x2001, + 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, 0x0006, + 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, 0x769d, + 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xa001, + 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, 0x080c, + 0x769d, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, 0x4198, + 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, 0x60e2, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, + 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26ea, 0x000e, 0x00de, + 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, + 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a88, 0x9085, + 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bbc, 0x080c, 0x8918, + 0x1f04, 0x2bbc, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, + 0x015e, 0x000e, 0x0005, 0x30c7, 0x30c7, 0x2ccb, 0x2ccb, 0x2cd7, + 0x2cd7, 0x2ce3, 0x2ce3, 0x2cf1, 0x2cf1, 0x2cfd, 0x2cfd, 0x2d0b, + 0x2d0b, 0x2d19, 0x2d19, 0x2d2b, 0x2d2b, 0x2d37, 0x2d37, 0x2d45, + 0x2d45, 0x2d63, 0x2d63, 0x2d83, 0x2d83, 0x2d53, 0x2d53, 0x2d73, + 0x2d73, 0x2d91, 0x2d91, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2da3, 0x2da3, 0x2daf, 0x2daf, 0x2dbd, + 0x2dbd, 0x2dcb, 0x2dcb, 0x2ddb, 0x2ddb, 0x2de9, 0x2de9, 0x2df9, + 0x2df9, 0x2e09, 0x2e09, 0x2e1b, 0x2e1b, 0x2e29, 0x2e29, 0x2e39, + 0x2e39, 0x2e5b, 0x2e5b, 0x2e7f, 0x2e7f, 0x2e49, 0x2e49, 0x2e6d, + 0x2e6d, 0x2e8f, 0x2e8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2ea3, 0x2ea3, 0x2eaf, 0x2eaf, 0x2ebd, + 0x2ebd, 0x2ecb, 0x2ecb, 0x2edb, 0x2edb, 0x2ee9, 0x2ee9, 0x2ef9, + 0x2ef9, 0x2f09, 0x2f09, 0x2f1b, 0x2f1b, 0x2f29, 0x2f29, 0x2f39, + 0x2f39, 0x2f49, 0x2f49, 0x2f5b, 0x2f5b, 0x2f6b, 0x2f6b, 0x2f7d, + 0x2f7d, 0x2f8f, 0x2f8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2fa3, 0x2fa3, 0x2fb1, 0x2fb1, 0x2fc1, + 0x2fc1, 0x2fd1, 0x2fd1, 0x2fe3, 0x2fe3, 0x2ff3, 0x2ff3, 0x3005, + 0x3005, 0x3017, 0x3017, 0x302b, 0x302b, 0x303b, 0x303b, 0x304d, + 0x304d, 0x305f, 0x305f, 0x3073, 0x3073, 0x3084, 0x3084, 0x3097, + 0x3097, 0x30aa, 0x30aa, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0xab5d, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0xab5d, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0xab5d, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x13c8, 0x080c, 0x2131, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, + 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0440, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c, 0xab5d, 0x080c, + 0x2131, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, + 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0000, 0x015e, + 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, + 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b8b, 0x1904, + 0x31dc, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, 0xd29c, + 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31dc, 0x080c, 0x31e1, + 0x0804, 0x31dc, 0xd2cc, 0x1904, 0x31dc, 0x080c, 0x769d, 0x1120, + 0x70af, 0xffff, 0x0804, 0x31dc, 0xd294, 0x0120, 0x70af, 0xffff, + 0x0804, 0x31dc, 0x080c, 0x3463, 0x0160, 0x080c, 0xd35d, 0x0128, + 0x2001, 0x1818, 0x203c, 0x0804, 0x3165, 0x70af, 0xffff, 0x0804, + 0x31dc, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x3165, + 0xd28c, 0x1904, 0x3165, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, 0x0001, + 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, + 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, 0x7230, + 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, 0x003e, + 0x04a0, 0x900e, 0x080c, 0x26a1, 0x080c, 0x6718, 0x1538, 0x9006, + 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, + 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd, + 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, + 0x6a74, 0x0120, 0x080c, 0x31fa, 0x0148, 0x0028, 0x080c, 0x3346, + 0x080c, 0x3226, 0x0118, 0x8318, 0x0804, 0x3112, 0x73ae, 0x0010, + 0x70af, 0xffff, 0x003e, 0x0804, 0x31dc, 0x9780, 0x3474, 0x203d, + 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, 0xffff, + 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, + 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31dc, 0x2700, 0x0156, + 0x0016, 0x9106, 0x0904, 0x31d1, 0xc484, 0x080c, 0x6783, 0x0168, + 0x080c, 0xd35d, 0x1904, 0x31d1, 0x080c, 0x3463, 0x1904, 0x31d1, + 0x080c, 0x6718, 0x1904, 0x31d9, 0x0008, 0xc485, 0xb8bb, 0x0520, + 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8d87, 0x00ce, + 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd, 0x1130, 0x7030, + 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, + 0x080c, 0x6bcd, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, + 0x673d, 0x0028, 0x080c, 0x33d9, 0x01a0, 0x080c, 0x3404, 0x0088, + 0x080c, 0x3346, 0x080c, 0xd35d, 0x1160, 0x080c, 0x3226, 0x0188, + 0x0040, 0x080c, 0xd35d, 0x1118, 0x080c, 0x33d9, 0x0110, 0x0451, + 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x317e, 0x70af, 0xffff, + 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, + 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, + 0x6718, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3346, + 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd0a1, 0x001e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, + 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xafbf, 0x01d0, 0x2b00, + 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5, + 0x2001, 0x0000, 0x080c, 0x66c9, 0x0126, 0x2091, 0x8000, 0x70a8, + 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xafec, 0x9085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, + 0x080c, 0xafbf, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, + 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x1110, 0x080c, 0x32fb, 0x080c, 0xd0ce, 0x6023, 0x0001, + 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x0126, + 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, + 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6718, + 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, + 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, + 0x00c6, 0x080c, 0xaef8, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0ce, + 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, + 0x2009, 0x0002, 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de, + 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2009, 0x007f, 0x080c, 0x6718, 0x11b8, 0xb813, 0x00ff, 0xb817, + 0xfffd, 0xb8d7, 0x0004, 0x080c, 0xaef8, 0x0170, 0x2b00, 0x6012, + 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd0ce, 0x2009, 0x0022, + 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, + 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, + 0xaaf7, 0x0106, 0x080c, 0x95c4, 0x080c, 0x9530, 0x080c, 0xaa48, + 0x080c, 0xbeab, 0x010e, 0x090c, 0xab13, 0x3e08, 0x2130, 0x81ff, + 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x080c, 0x6783, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, + 0xd0bc, 0x1110, 0x080c, 0x6192, 0x001e, 0x8108, 0x1f04, 0x32e0, + 0x9686, 0x0001, 0x190c, 0x3437, 0x00be, 0x002e, 0x003e, 0x006e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, + 0x0016, 0x00b6, 0x080c, 0xaaf7, 0x0106, 0x6210, 0x2258, 0xbaa0, + 0x0026, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000, + 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x010e, + 0x090c, 0xab13, 0xba10, 0xbb14, 0xbc84, 0x080c, 0x6192, 0xba12, + 0xbb16, 0xbc86, 0x00be, 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, + 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, + 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, + 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, + 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, + 0x0026, 0x0016, 0x0156, 0x2178, 0x080c, 0xaaf7, 0x0106, 0x81ff, + 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x5820, 0xd0c4, 0x0140, + 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe795, + 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x33b5, + 0x928e, 0x007f, 0x0904, 0x33b5, 0x928e, 0x0080, 0x05f0, 0x9288, + 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f, + 0x0006, 0x2003, 0x0001, 0x080c, 0x33c6, 0x000e, 0x2003, 0x0000, + 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6b97, 0x00ce, + 0x00be, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000, + 0x080c, 0x9476, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, + 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, + 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, + 0x2c08, 0x080c, 0xe465, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, + 0x336b, 0x010e, 0x090c, 0xab13, 0x015e, 0x001e, 0x002e, 0x003e, + 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, + 0x0016, 0x080c, 0x5820, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, + 0x2220, 0x2009, 0x0029, 0x080c, 0xe795, 0x001e, 0x002e, 0x004e, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, + 0x080c, 0x6bc5, 0x11d0, 0x2100, 0x080c, 0x26d4, 0x81ff, 0x01b8, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120, + 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, + 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0036, 0x2019, 0x0029, 0x00c1, + 0x003e, 0x010e, 0x090c, 0xab13, 0x9180, 0x1000, 0x2004, 0x9065, + 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c, + 0x32fb, 0x001e, 0x080c, 0x673d, 0x012e, 0x00ce, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2110, 0x080c, 0xa5dd, 0x080c, 0xeafd, 0x002e, + 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, + 0xd0bc, 0x090c, 0x673d, 0x8108, 0x1f04, 0x3448, 0x2061, 0x1800, + 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, + 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, + 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, + 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, + 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, + 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, + 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, + 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, + 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, + 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, + 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, + 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, + 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, + 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, + 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, + 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, + 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, + 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, + 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, + 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, + 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, + 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, + 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, + 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, + 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, + 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, + 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, + 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, + 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, + 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, + 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, - 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, - 0x18ba, 0x7007, 0x0001, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, - 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1072, 0x090c, - 0x0d85, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, - 0x2071, 0x189e, 0x7004, 0x0002, 0x35b8, 0x35b9, 0x35cc, 0x35e0, - 0x0005, 0x1004, 0x35c9, 0x0e04, 0x35c9, 0x2079, 0x0000, 0x0126, - 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, - 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, - 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, - 0x36b4, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, - 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, - 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, - 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, - 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, - 0x003f, 0x1a04, 0x36b1, 0x61d0, 0x0804, 0x3646, 0x3688, 0x36c0, - 0x36b1, 0x36cc, 0x36d6, 0x36dc, 0x36e0, 0x36f0, 0x36f4, 0x370a, - 0x3710, 0x3716, 0x3721, 0x372c, 0x373b, 0x374a, 0x3758, 0x376f, - 0x378a, 0x36b1, 0x3833, 0x3871, 0x3916, 0x3927, 0x394a, 0x36b1, - 0x36b1, 0x36b1, 0x3982, 0x39a2, 0x39ab, 0x39d7, 0x39dd, 0x36b1, - 0x3a23, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a2e, 0x3a37, - 0x3a3f, 0x3a41, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, - 0x3a71, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a8e, 0x3af2, - 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x0002, 0x3b1c, - 0x3b1f, 0x3b7e, 0x3b97, 0x3bc7, 0x3e6d, 0x36b1, 0x53db, 0x36b1, - 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x370a, - 0x3710, 0x4365, 0x584a, 0x4383, 0x546a, 0x54bc, 0x55c7, 0x36b1, - 0x5629, 0x5665, 0x5696, 0x57a6, 0x56c3, 0x5726, 0x36b1, 0x4387, - 0x453c, 0x4552, 0x4577, 0x45dc, 0x4650, 0x4670, 0x46e7, 0x4743, - 0x479f, 0x47a2, 0x47c7, 0x4839, 0x48a3, 0x48ab, 0x49e0, 0x4b58, - 0x4b8c, 0x4df0, 0x36b1, 0x4e0e, 0x4eb4, 0x4f9d, 0x4ff7, 0x36b1, - 0x50ae, 0x36b1, 0x511a, 0x5135, 0x48ab, 0x537b, 0x714c, 0x0000, - 0x2021, 0x4000, 0x080c, 0x4c0a, 0x0126, 0x2091, 0x8000, 0x0e04, - 0x3692, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, - 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, - 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, - 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, - 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, - 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, - 0x81ff, 0x0d98, 0x0804, 0x4c17, 0x2039, 0x0001, 0x902e, 0x2520, - 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4c1a, 0x7984, 0x7888, - 0x2114, 0x200a, 0x0804, 0x3688, 0x7984, 0x2114, 0x0804, 0x3688, - 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, - 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3688, - 0x7884, 0x2060, 0x0804, 0x373d, 0x2009, 0x0003, 0x2011, 0x0003, - 0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, - 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3688, 0x7897, 0x0001, - 0x0804, 0x3688, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36c4, - 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182, - 0x0040, 0x0210, 0x0804, 0x36bd, 0x2138, 0x7d98, 0x7c9c, 0x0804, - 0x36c4, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd, 0x2138, - 0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182, 0x0040, 0x0210, - 0x0804, 0x36bd, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, - 0x4004, 0x0804, 0x3688, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, - 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3688, - 0x0804, 0x36b7, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd, - 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3688, - 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x36bd, 0x8019, - 0x0904, 0x36bd, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, - 0x9006, 0x685a, 0x685e, 0x080c, 0x79d8, 0x0804, 0x3688, 0x2069, - 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x36bd, 0x8019, 0x0904, - 0x36bd, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, - 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c6d, 0x012e, - 0x0804, 0x3688, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x36ba, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, - 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4bce, 0x1120, 0x2009, - 0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x080c, 0x4c17, 0x701f, 0x37ae, 0x0005, 0xa864, 0x2008, - 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, - 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, - 0x1904, 0x36ba, 0x810f, 0x918c, 0x00ff, 0x0904, 0x36ba, 0x7112, - 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4bce, 0x1120, 0x2009, - 0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, - 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, - 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, - 0x4c17, 0x701f, 0x37ec, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x36ba, 0x0888, 0x7014, - 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x62eb, 0x0150, 0x0126, - 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x661b, - 0x1128, 0x7007, 0x0003, 0x701f, 0x3818, 0x0005, 0x080c, 0x7165, - 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, - 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, - 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, - 0xaf60, 0x0804, 0x4c1a, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, - 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, - 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, - 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, - 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26, 0x2004, - 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, - 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, - 0x0427, 0x81ff, 0x1904, 0x36ba, 0x7984, 0x080c, 0x6789, 0x1904, - 0x36bd, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x36bd, - 0x7c88, 0x7d8c, 0x080c, 0x69bf, 0x080c, 0x694c, 0x1518, 0x2061, - 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, - 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, - 0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1a04, 0x36ba, 0x0c30, 0x080c, 0xc802, 0x012e, 0x0904, 0x36ba, - 0x0804, 0x3688, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126, - 0x2091, 0x8000, 0x080c, 0xcf21, 0x080c, 0x6f19, 0x012e, 0x0804, - 0x3688, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6789, 0x1904, 0x3903, - 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, - 0x080c, 0x69bf, 0x080c, 0x694c, 0x1520, 0x2061, 0x1ddc, 0x0126, - 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, - 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, - 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, - 0x12b0, 0x0c28, 0x080c, 0xc802, 0x012e, 0x2009, 0x0003, 0x0178, - 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126, 0x2091, - 0x8000, 0x080c, 0xcf21, 0x080c, 0x6f0d, 0x012e, 0x0070, 0xb097, - 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, - 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, - 0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850, 0x0904, - 0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x0804, 0x4667, 0x81ff, - 0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6a53, - 0x0904, 0x36ba, 0x2019, 0x0005, 0x79a8, 0x080c, 0x69e0, 0x0904, - 0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x8003, 0x800b, - 0x810b, 0x9108, 0x080c, 0x8842, 0x79a8, 0xd184, 0x1904, 0x3688, - 0x0804, 0x4667, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, - 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, - 0x2508, 0x080c, 0x6789, 0x11d8, 0x080c, 0x6a53, 0x1128, 0x2009, - 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, - 0x69e0, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, - 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x8529, - 0x1ae0, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804, 0x36ba, 0x012e, - 0x0804, 0x36bd, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850, - 0x0904, 0x36ba, 0x080c, 0xaae0, 0xbaa0, 0x2019, 0x0005, 0x00c6, - 0x9066, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e, - 0x080c, 0xe440, 0x007e, 0x00ce, 0x080c, 0xaafc, 0x080c, 0x69bf, - 0x0804, 0x3688, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x69bf, - 0x2208, 0x0804, 0x3688, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069, - 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, - 0x901e, 0x2071, 0x19e9, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c, - 0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804, - 0x3688, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, - 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, - 0x1910, 0x6910, 0x62bc, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x583a, - 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x36ba, 0x012e, 0x615c, - 0x9190, 0x3489, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, - 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, - 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, - 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, - 0x0002, 0x0068, 0x080c, 0x76a5, 0x1118, 0x2031, 0x0004, 0x0038, - 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x9036, 0x7e9a, - 0x7f9e, 0x0804, 0x3688, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c, - 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091, - 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3688, 0x080c, - 0x4c01, 0x0904, 0x36bd, 0xba44, 0xbb38, 0x0804, 0x3688, 0x080c, - 0x0d85, 0x080c, 0x4c01, 0x2110, 0x0904, 0x36bd, 0xb804, 0x908c, - 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, - 0x2009, 0x0009, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x2019, - 0x0005, 0x00c6, 0x9066, 0x080c, 0xaae0, 0x080c, 0xa5c6, 0x080c, - 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e, 0x080c, 0xe440, - 0x007e, 0x00ce, 0x080c, 0xaafc, 0xb807, 0x0407, 0x012e, 0x0804, - 0x3688, 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, - 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c, - 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, - 0x1988, 0x2d04, 0x266a, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091, - 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0eeb, - 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac, - 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, - 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011, - 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, - 0x918c, 0xff7f, 0x2112, 0x7988, 0x613e, 0x6140, 0x788c, 0x6042, - 0x910e, 0xd1e4, 0x190c, 0x0f06, 0x9084, 0x0020, 0x0130, 0x78b4, - 0x6046, 0x9084, 0x0001, 0x090c, 0x4365, 0x6040, 0xd0cc, 0x0120, - 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x3688, 0x00f6, - 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, - 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, - 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, - 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, - 0x36bd, 0x788c, 0x902d, 0x0904, 0x36bd, 0x900e, 0x080c, 0x6789, - 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, - 0x8108, 0x0ca0, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7888, 0x900d, - 0x0904, 0x36bd, 0x788c, 0x9005, 0x0904, 0x36bd, 0xba44, 0xb946, - 0xbb38, 0xb83a, 0x0804, 0x3688, 0x2011, 0xbc09, 0x0010, 0x2011, - 0xbc05, 0x080c, 0x583a, 0x1904, 0x36ba, 0x00c6, 0x2061, 0x0100, - 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, - 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x3489, 0x210d, - 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, - 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, - 0xaed8, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, - 0x6724, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, - 0x4bce, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, - 0xc0fd, 0xa86a, 0x701f, 0x3b77, 0x2900, 0x6016, 0x2009, 0x0032, - 0x080c, 0xafcc, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, - 0x36ba, 0x00ce, 0x0804, 0x36bd, 0x080c, 0xaf2e, 0x0cb0, 0xa830, - 0x9086, 0x0100, 0x0904, 0x36ba, 0x0804, 0x3688, 0x2061, 0x1a74, - 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, - 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, - 0x78aa, 0x012e, 0x0804, 0x3688, 0x900e, 0x2110, 0x0c88, 0x81ff, - 0x1904, 0x36ba, 0x080c, 0x76a5, 0x0904, 0x36ba, 0x0126, 0x2091, - 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, - 0x270b, 0x080c, 0x5a5d, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804, - 0x36bd, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, - 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, - 0x936c, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, - 0x368a, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, - 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x36bd, 0x2001, - 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, - 0x1230, 0x012e, 0x0804, 0x36bd, 0x012e, 0x0804, 0x36ba, 0x080c, - 0xae60, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3c46, 0x00c6, 0x080c, - 0x4bce, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, - 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, - 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, - 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, - 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, - 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3dd0, 0x0928, 0x7014, - 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, - 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, - 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17, - 0x701f, 0x3d0d, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xaae0, - 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x080c, 0x3bb1, 0x2001, 0x19a0, 0x2003, 0x0000, 0x2021, - 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, - 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e3f, 0x080c, 0x3dfe, 0x00f6, - 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090, 0x00d6, - 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, - 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, - 0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x080c, - 0x4003, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, - 0x080c, 0x421d, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, - 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, - 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, - 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, - 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, - 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, - 0x0138, 0x080c, 0x400d, 0x080c, 0x3df9, 0x0058, 0x080c, 0x3df9, - 0x080c, 0x4141, 0x080c, 0x40cc, 0x2001, 0x020b, 0x2004, 0xd0e4, - 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, - 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, - 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, - 0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x2009, 0x0028, 0x080c, - 0x2241, 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xaafc, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, - 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3688, - 0x012e, 0x2021, 0x400c, 0x0804, 0x368a, 0x0016, 0x0026, 0x0036, - 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, - 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904, - 0x3d69, 0x2048, 0x1f04, 0x3d1d, 0x7068, 0x2040, 0xa28c, 0xa390, - 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, - 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086, - 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17, 0x701f, 0x3d0d, 0x00b0, + 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, + 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1066, + 0x090c, 0x0d79, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, + 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900, 0x706e, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x35a3, + 0x35a4, 0x35b7, 0x35cb, 0x0005, 0x1004, 0x35b4, 0x0e04, 0x35b4, + 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, + 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, + 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, + 0x9086, 0x0200, 0x0904, 0x369f, 0x0005, 0x7018, 0x2048, 0x2061, + 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, + 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, + 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, + 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, + 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x369c, 0x61d0, 0x0804, + 0x3631, 0x3673, 0x36ab, 0x369c, 0x36b7, 0x36c1, 0x36c7, 0x36cb, + 0x36db, 0x36df, 0x36f5, 0x36fb, 0x3701, 0x370c, 0x3717, 0x3726, + 0x3735, 0x3743, 0x375a, 0x3775, 0x369c, 0x381e, 0x385c, 0x3901, + 0x3912, 0x3935, 0x369c, 0x369c, 0x369c, 0x396d, 0x398d, 0x3996, + 0x39c2, 0x39c8, 0x369c, 0x3a0e, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x3a19, 0x3a22, 0x3a2a, 0x3a2c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x369c, 0x369c, 0x3a5c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x3a79, 0x3add, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x0002, 0x3b07, 0x3b0a, 0x3b69, 0x3b82, 0x3bb2, 0x3e58, + 0x369c, 0x53d5, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x369c, 0x36f5, 0x36fb, 0x435b, 0x5844, 0x4379, 0x5464, + 0x54b6, 0x55c1, 0x369c, 0x5623, 0x565f, 0x5690, 0x57a0, 0x56bd, + 0x5720, 0x369c, 0x437d, 0x4536, 0x454c, 0x4571, 0x45d6, 0x464a, + 0x466a, 0x46e1, 0x473d, 0x4799, 0x479c, 0x47c1, 0x4833, 0x489d, + 0x48a5, 0x49da, 0x4b52, 0x4b86, 0x4dea, 0x369c, 0x4e08, 0x4eae, + 0x4f97, 0x4ff1, 0x369c, 0x50a8, 0x369c, 0x5114, 0x512f, 0x48a5, + 0x5375, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4c04, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x367d, 0x0010, 0x012e, 0x0cc0, 0x7c36, + 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, + 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11f4, 0x7007, 0x0001, 0x2091, 0x5000, + 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, + 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, + 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, + 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4c11, 0x2039, + 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, + 0x4c14, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x3673, 0x7984, + 0x2114, 0x0804, 0x3673, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, + 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, + 0x7b8c, 0x0804, 0x3673, 0x7884, 0x2060, 0x0804, 0x3728, 0x2009, + 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893, + 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, + 0x3673, 0x7897, 0x0001, 0x0804, 0x3673, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x36af, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, + 0x36bb, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x2138, + 0x7d98, 0x7c9c, 0x0804, 0x36af, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x36a8, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x36bb, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x21e8, 0x7984, 0x7888, + 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x3673, 0x2061, 0x0800, + 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, + 0x9005, 0x0904, 0x3673, 0x0804, 0x36a2, 0x79a0, 0x9182, 0x0040, + 0x0210, 0x0804, 0x36a8, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, + 0x4012, 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, + 0x1a04, 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684a, 0x6942, 0x788c, + 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x79d0, + 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, + 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684e, 0x6946, 0x788c, 0x6862, + 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6c65, 0x012e, 0x0804, 0x3673, 0x902e, 0x2520, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x7984, 0x7b88, 0x7a8c, + 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x3799, + 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, + 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, + 0x0120, 0x9096, 0x0029, 0x1904, 0x36a5, 0x810f, 0x918c, 0x00ff, + 0x0904, 0x36a5, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, + 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, + 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x37d7, 0x0005, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, + 0x36a5, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, + 0x62e5, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, + 0x0050, 0x080c, 0x6615, 0x1128, 0x7007, 0x0003, 0x701f, 0x3803, + 0x0005, 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, + 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4c14, 0x2091, 0x8000, + 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, + 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, + 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, + 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, + 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, + 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, + 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, + 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x36a5, 0x7984, + 0x080c, 0x6783, 0x1904, 0x36a8, 0x7e98, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x1a04, 0x36a8, 0x7c88, 0x7d8c, 0x080c, 0x69b7, 0x080c, + 0x6944, 0x1518, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, + 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, + 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1a04, 0x36a5, 0x0c30, 0x080c, 0xc81b, + 0x012e, 0x0904, 0x36a5, 0x0804, 0x3673, 0x900e, 0x2001, 0x0005, + 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c, + 0x6f11, 0x012e, 0x0804, 0x3673, 0x00a6, 0x2950, 0xb198, 0x080c, + 0x6783, 0x1904, 0x38ee, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x69b7, 0x080c, 0x6944, 0x1520, + 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, + 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0158, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xc81b, 0x012e, + 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, + 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c, 0x6f05, + 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, + 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904, 0x36a8, + 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904, 0x36a5, + 0x0804, 0x4661, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x080c, 0x6a4b, 0x0904, 0x36a5, 0x2019, 0x0005, 0x79a8, + 0x080c, 0x69d8, 0x0904, 0x36a5, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x36a8, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a, 0x79a8, + 0xd184, 0x1904, 0x3673, 0x0804, 0x4661, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, + 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x6783, 0x11d8, 0x080c, + 0x6a4b, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, + 0x0004, 0x900e, 0x080c, 0x69d8, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, + 0x080c, 0x883a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3673, 0x012e, + 0x0804, 0x36a5, 0x012e, 0x0804, 0x36a8, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0xaaf7, 0xbaa0, + 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x95b9, 0x0076, 0x903e, + 0x080c, 0x9476, 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c, + 0xab13, 0x080c, 0x69b7, 0x0804, 0x3673, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x69b7, 0x2208, 0x0804, 0x3673, 0x0156, 0x00d6, + 0x00e6, 0x00c6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, + 0x900e, 0x6816, 0x9016, 0x901e, 0x2071, 0x19e9, 0x7028, 0x9065, + 0x0118, 0x8210, 0x600c, 0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee, + 0x00de, 0x015e, 0x0804, 0x3673, 0x00f6, 0x0016, 0x907d, 0x0138, + 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, + 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x0126, 0x2091, + 0x8000, 0x080c, 0x5834, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, + 0x36a5, 0x012e, 0x615c, 0x9190, 0x3474, 0x2215, 0x9294, 0x00ff, + 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, + 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, + 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, + 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x769d, 0x1118, + 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, + 0x36a5, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x3673, 0x614c, 0x6250, + 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, + 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, + 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0xba44, 0xbb38, + 0x0804, 0x3673, 0x080c, 0x0d79, 0x080c, 0x4bfb, 0x2110, 0x0904, + 0x36a8, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, + 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x36a5, 0x0126, + 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaaf7, + 0x080c, 0xa5dd, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c, 0xab13, 0xb807, + 0x0407, 0x012e, 0x0804, 0x3673, 0x614c, 0x6250, 0x7884, 0x604e, + 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, + 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, + 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a, 0x0804, + 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, + 0xd1b4, 0x190c, 0x0edf, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, + 0x199e, 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, + 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, + 0x695a, 0x00de, 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, + 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f, 0x2112, 0x7988, 0x613e, + 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4, 0x190c, 0x0efa, 0x9084, + 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, 0x090c, 0x435b, + 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, + 0x0804, 0x3673, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, + 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, + 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, + 0x7888, 0x9025, 0x0904, 0x36a8, 0x788c, 0x902d, 0x0904, 0x36a8, + 0x900e, 0x080c, 0x6783, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, + 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x7888, 0x900d, 0x0904, 0x36a8, 0x788c, 0x9005, 0x0904, + 0x36a8, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3673, 0x2011, + 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x5834, 0x1904, 0x36a5, + 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, + 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, + 0x9188, 0x3474, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, + 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, + 0x8000, 0x0006, 0x080c, 0xaef8, 0x000e, 0x0510, 0x602e, 0x620a, + 0x7984, 0x00b6, 0x080c, 0x671e, 0x2b08, 0x00be, 0x1500, 0x6112, + 0x6023, 0x0001, 0x080c, 0x4bc8, 0x01d0, 0x9006, 0xa866, 0x7007, + 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3b62, 0x2900, + 0x6016, 0x2009, 0x0032, 0x080c, 0xafec, 0x012e, 0x00ce, 0x0005, + 0x012e, 0x00ce, 0x0804, 0x36a5, 0x00ce, 0x0804, 0x36a8, 0x080c, + 0xaf4e, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x36a5, 0x0804, + 0x3673, 0x2061, 0x1a74, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, + 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, + 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, 0x3673, 0x900e, + 0x2110, 0x0c88, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x0904, + 0x36a5, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, + 0x9085, 0x0001, 0x080c, 0x270a, 0x080c, 0x5a57, 0x012e, 0x0804, + 0x3673, 0x012e, 0x0804, 0x36a8, 0x0006, 0x0016, 0x00c6, 0x00e6, + 0x2001, 0x19ab, 0x2070, 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, + 0x2011, 0x1400, 0x080c, 0x9364, 0x7206, 0x00ee, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, + 0x2021, 0x400b, 0x0804, 0x3675, 0x7884, 0xd0fc, 0x0158, 0x2001, + 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, + 0x0804, 0x36a8, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, + 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x36a8, 0x012e, + 0x0804, 0x36a5, 0x080c, 0xae80, 0x0dd0, 0x7884, 0xd0fc, 0x0904, + 0x3c31, 0x00c6, 0x080c, 0x4bc8, 0x00ce, 0x0d88, 0xa867, 0x0000, + 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, + 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, + 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, + 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, + 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, + 0x3dbb, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, + 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, - 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, - 0x0fd6, 0x000e, 0x080c, 0x4c1a, 0x701f, 0x3d0d, 0x015e, 0x00de, - 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, - 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f, - 0x3dce, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, - 0x007f, 0x080c, 0x671e, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, - 0xb817, 0xfffd, 0x080c, 0xd104, 0x015e, 0x00de, 0x009e, 0x008e, - 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x36ba, + 0x001b, 0x080c, 0x4c11, 0x701f, 0x3cf8, 0x7023, 0x0001, 0x012e, + 0x0005, 0x080c, 0xaaf7, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3b9c, 0x2001, 0x19a1, + 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, + 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e2a, + 0x080c, 0x3de9, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, + 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, + 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, + 0x00de, 0x2011, 0x0001, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, + 0x080c, 0x40c1, 0x080c, 0x3fee, 0x05b8, 0x2001, 0x020b, 0x2004, + 0x9084, 0x0140, 0x1db8, 0x080c, 0x4213, 0x00f6, 0x2079, 0x0300, + 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, + 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, + 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, + 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, + 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, + 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3ff8, 0x080c, 0x3de4, + 0x0058, 0x080c, 0x3de4, 0x080c, 0x4137, 0x080c, 0x40b7, 0x2001, + 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, + 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346, + 0x2009, 0x0028, 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102, + 0x080c, 0xab13, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, + 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005, 0x1118, + 0x012e, 0x0804, 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, - 0x00d6, 0x0156, 0x701f, 0x3da0, 0x7007, 0x0003, 0x0804, 0x3d5e, - 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x368a, 0x0076, - 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120, - 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, - 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fd6, 0x000e, 0x080c, 0x4c1a, - 0x007e, 0x701f, 0x3d0d, 0x7023, 0x0001, 0x0005, 0x0804, 0x3688, - 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e, - 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4bce, - 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58, - 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006, - 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e, - 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6, - 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, - 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, - 0x080c, 0x4bce, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, - 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, - 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, - 0x2009, 0x0040, 0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, - 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, - 0x080c, 0x4bce, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, - 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004, - 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873, - 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003, - 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, - 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x81ff, 0x0148, 0x080c, 0x2a99, 0x1130, 0x9006, 0x080c, 0x29ec, - 0x9006, 0x080c, 0x29cf, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e8a, - 0x3e8b, 0x3e8c, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x012e, - 0x0804, 0x36bd, 0x0ce0, 0x0cd8, 0x080c, 0x76a5, 0x1128, 0x012e, - 0x2009, 0x0016, 0x0804, 0x36ba, 0x81ff, 0x0128, 0x012e, 0x2021, - 0x400b, 0x0804, 0x368a, 0x6000, 0x9086, 0x0003, 0x1db8, 0x2001, - 0x0141, 0x2004, 0xd0dc, 0x0d90, 0x080c, 0xaae0, 0x0086, 0x0096, - 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3bb1, - 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, - 0x2060, 0x2058, 0x080c, 0x42f8, 0x080c, 0x4248, 0x903e, 0x2720, - 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090, - 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, - 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x41a9, 0x080c, - 0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c, - 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x2009, 0x9c40, - 0x8109, 0x11b0, 0x080c, 0x400d, 0x2001, 0x0004, 0x200c, 0x918c, - 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, - 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x36ba, 0x0cf8, - 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, - 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, - 0x81ff, 0x0150, 0x080c, 0x40b4, 0x2d00, 0x9c05, 0x9b05, 0x0120, - 0x080c, 0x400d, 0x0804, 0x3fb6, 0x080c, 0x421d, 0x080c, 0x4141, - 0x080c, 0x4097, 0x080c, 0x40cc, 0x00f6, 0x2079, 0x0100, 0x7824, - 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x400d, 0x00fe, 0x0804, 0x3fb6, - 0x00fe, 0x080c, 0x4003, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, - 0x2001, 0x0033, 0x2502, 0x080c, 0x400d, 0x0080, 0x87ff, 0x0138, - 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, - 0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3f06, 0x2001, 0x032f, - 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, - 0x3fb6, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, - 0x3fb6, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, - 0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001, 0x032a, - 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, - 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2241, 0x2900, - 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, - 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, - 0x0203, 0x2004, 0x1f04, 0x3f8d, 0x00ce, 0x0030, 0xa817, 0x0001, - 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, - 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, - 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3ec0, 0x001e, 0x00c6, - 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, - 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, - 0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x7884, 0x9084, 0x0003, - 0x9086, 0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x2241, 0x2001, - 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b4b, - 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, - 0x0010, 0x080c, 0xaafc, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, - 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, - 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x3688, 0x012e, 0x2021, - 0x400c, 0x0804, 0x368a, 0x9085, 0x0001, 0x1d04, 0x400c, 0x2091, - 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, - 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6f, 0x2003, - 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, 0x2241, 0x2001, 0x0227, - 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, - 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000, 0x0520, - 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, - 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241, 0x782c, 0xd0fc, - 0x0d88, 0x080c, 0x421d, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b, - 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241, - 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, - 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, - 0x26eb, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x784b, 0xf7f7, 0x7843, - 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8, - 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852, - 0x2011, 0x0048, 0x080c, 0x2af5, 0x7843, 0x0040, 0x2019, 0x01f4, - 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2abb, - 0x2011, 0x0020, 0x080c, 0x2af5, 0x7843, 0x0000, 0x9006, 0x080c, - 0x2abb, 0x2011, 0x0048, 0x080c, 0x2af5, 0x00fe, 0x0005, 0x7884, - 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, - 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, - 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, - 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, - 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, - 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, - 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, - 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, - 0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2, 0x080c, 0x3def, 0x1188, - 0x2001, 0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, - 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, - 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, - 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, - 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, - 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, - 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, - 0x9085, 0x0092, 0x7016, 0x080c, 0x421d, 0x00f6, 0x2071, 0x1a6f, - 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, - 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, 0x2009, 0x03e8, 0x8109, - 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, - 0x080c, 0x41a9, 0x2011, 0x0001, 0x080c, 0x41a9, 0x00fe, 0x00ee, - 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c, - 0xd1fc, 0x0904, 0x41a6, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, - 0x41a2, 0x7000, 0x0002, 0x41a6, 0x4157, 0x4187, 0x41a2, 0xd1bc, - 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, - 0x41a9, 0x0904, 0x41a6, 0x080c, 0x41a9, 0x0804, 0x41a6, 0x00f6, - 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, - 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, - 0x080c, 0x40b4, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, - 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, - 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x414b, - 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, - 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, - 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, - 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, - 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, - 0x938a, 0x0007, 0x1a0c, 0x0d85, 0x9398, 0x41d7, 0x231d, 0x083f, - 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, - 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, - 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x4214, - 0x420b, 0x4202, 0x41f9, 0x41f0, 0x41e7, 0x41de, 0xa964, 0x7902, - 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, - 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, - 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, - 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, - 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, - 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, - 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, - 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, - 0x2071, 0x19e9, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, - 0x0002, 0x2940, 0x9026, 0x7054, 0x0002, 0x4244, 0x4230, 0x423b, - 0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x41a9, - 0x190c, 0x41a9, 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, - 0x2011, 0x0001, 0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x0005, - 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ab, - 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, - 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, - 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, - 0x4bce, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, - 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, - 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0, - 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4bce, 0xa813, 0x0019, - 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, - 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, - 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, 0x0040, - 0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, - 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, - 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, - 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, - 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, - 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, - 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, - 0x080c, 0x4bce, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, - 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, - 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, - 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4bce, 0x2940, - 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, - 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, - 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0, 0x1d68, - 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4bce, 0x2940, 0xa013, 0x0019, - 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, - 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, - 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, - 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003, - 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, - 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, - 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, - 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, - 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, - 0x0005, 0x0804, 0x3688, 0x7d98, 0x7c9c, 0x0804, 0x378c, 0x080c, - 0x76a5, 0x190c, 0x6143, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, - 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0x2039, 0x0001, 0x080c, 0x4c17, 0x701f, 0x439f, 0x0005, 0x080c, - 0x5835, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, - 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x36bd, 0x6804, 0xd0ac, - 0x0118, 0xd0a4, 0x0904, 0x36bd, 0xd094, 0x00c6, 0x2061, 0x0100, - 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, - 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, - 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, - 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, - 0x36bd, 0x9288, 0x3489, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, - 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x36bd, 0x605e, 0x6888, - 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, - 0x19b3, 0x9080, 0x27de, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018, - 0x080c, 0xaad1, 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009, - 0x19b4, 0x9080, 0x27e2, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, - 0x0a04, 0x36bd, 0x908a, 0x0841, 0x1a04, 0x36bd, 0x9084, 0x0007, - 0x1904, 0x36bd, 0x680c, 0x9005, 0x0904, 0x36bd, 0x6810, 0x9005, - 0x0904, 0x36bd, 0x6848, 0x6940, 0x910a, 0x1a04, 0x36bd, 0x8001, - 0x0904, 0x36bd, 0x684c, 0x6944, 0x910a, 0x1a04, 0x36bd, 0x8001, - 0x0904, 0x36bd, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, - 0x00ff, 0x6052, 0x080c, 0x79d8, 0x080c, 0x6c0b, 0x080c, 0x6c6d, - 0x6808, 0x602a, 0x080c, 0x21b3, 0x2009, 0x0170, 0x200b, 0x0080, - 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2745, - 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x452a, 0x6818, 0x691c, - 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, - 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, - 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, - 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, - 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9, - 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89c7, - 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, - 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7f9f, 0x6878, 0x6016, - 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, - 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, - 0x1f04, 0x4488, 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284, - 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, - 0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0088, - 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ec, - 0x9006, 0x080c, 0x29cf, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, - 0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed3, 0x00ee, 0x6888, - 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, 0x0180, 0x2012, - 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, - 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, 0x9294, 0x0030, - 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, - 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27ba, 0x2001, 0x196e, 0x2102, - 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, - 0x0000, 0x00ce, 0x080c, 0x76a5, 0x0128, 0x080c, 0x510e, 0x0110, - 0x080c, 0x270b, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, - 0x4512, 0x00e0, 0x080c, 0x76a5, 0x1168, 0x2011, 0x7519, 0x080c, - 0x8834, 0x2011, 0x750c, 0x080c, 0x8940, 0x080c, 0x79ac, 0x080c, - 0x75d4, 0x0040, 0x080c, 0x6039, 0x0028, 0x6003, 0x0004, 0x2009, - 0x452a, 0x0020, 0x080c, 0x6b37, 0x0804, 0x3688, 0x2001, 0x0170, - 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x31bd, - 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, - 0x36ba, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, + 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, + 0xa804, 0x9005, 0x0904, 0x3d54, 0x2048, 0x1f04, 0x3d08, 0x7068, + 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, + 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, + 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c11, + 0x701f, 0x3cf8, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, + 0x20a0, 0x0006, 0x080c, 0x0fca, 0x000e, 0x080c, 0x4c14, 0x701f, + 0x3cf8, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, + 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, + 0x0103, 0x1118, 0x701f, 0x3db9, 0x0450, 0x7014, 0x2048, 0xa868, + 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x6718, 0x0110, 0x9006, + 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd121, 0x015e, + 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, + 0x001e, 0x0904, 0x36a5, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, + 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3d8b, 0x7007, + 0x0003, 0x0804, 0x3d49, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, + 0x0904, 0x3675, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, + 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, + 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fca, + 0x000e, 0x080c, 0x4c14, 0x007e, 0x701f, 0x3cf8, 0x7023, 0x0001, + 0x0005, 0x0804, 0x3673, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, + 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, + 0x0016, 0x080c, 0x4bc8, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, + 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, + 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, + 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003, 0x0001, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ac, + 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce, + 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817, + 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, + 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, + 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d, 0x2001, + 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, + 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019, + 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, + 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, + 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, + 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a80, 0x1130, + 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x2001, 0x19a0, + 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e79, 0x3e7a, + 0x3e7b, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x012e, 0x0804, + 0x36a8, 0x0ce0, 0x0cd8, 0x080c, 0x769d, 0x1128, 0x012e, 0x2009, + 0x0016, 0x0804, 0x36a5, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, + 0x0804, 0x3675, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, 0x080c, + 0xaaf7, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x080c, 0x3b9c, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, + 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x42ee, 0x080c, + 0x423e, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, + 0x19e9, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, + 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, + 0x080c, 0x419f, 0x080c, 0x2a88, 0x080c, 0x2a88, 0x080c, 0x2a88, + 0x080c, 0x2a88, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x080c, + 0x40c1, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3ff8, 0x2001, + 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, + 0x080c, 0x36a5, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, + 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, + 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x409f, 0x2d00, + 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3ff8, 0x0804, 0x3fa1, 0x080c, + 0x4213, 0x080c, 0x4137, 0x080c, 0x4082, 0x080c, 0x40b7, 0x00f6, + 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3ff8, + 0x00fe, 0x0804, 0x3fa1, 0x00fe, 0x080c, 0x3fee, 0x1150, 0x8d68, + 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3ff8, + 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, + 0x8739, 0x0038, 0x2001, 0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904, + 0x3ef1, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, + 0x2500, 0x9605, 0x0904, 0x3fa1, 0x7884, 0xd0bc, 0x0128, 0x2d00, + 0x9c05, 0x9b05, 0x1904, 0x3fa1, 0xa013, 0x0019, 0x2001, 0x032a, + 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003, + 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, + 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, + 0x080c, 0x223d, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, + 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, + 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3f78, 0x00ce, + 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, + 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, + 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, + 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, + 0x3eab, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, + 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346, + 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x01b0, 0x2009, 0x0028, + 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, + 0xb7ff, 0x080c, 0x2b32, 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, + 0x6043, 0x0090, 0x6043, 0x0010, 0x080c, 0xab13, 0x00ce, 0x2d08, + 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, + 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675, 0x9085, 0x0001, + 0x1d04, 0x3ff7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, + 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2001, 0x1a6f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, + 0x223d, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, + 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, + 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, + 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, + 0x223d, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4213, 0x7054, 0x9086, + 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, + 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, + 0x7932, 0x7936, 0x080c, 0x26ea, 0x080c, 0x2aff, 0x080c, 0x2b32, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, + 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, + 0x7850, 0xc0e4, 0x7852, 0x2011, 0x0048, 0x080c, 0x2adc, 0x7843, + 0x0040, 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, + 0x0100, 0x080c, 0x2aa2, 0x2011, 0x0020, 0x080c, 0x2adc, 0x7843, + 0x0000, 0x9006, 0x080c, 0x2aa2, 0x2011, 0x0048, 0x080c, 0x2adc, + 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, + 0x1a6f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, + 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, + 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, + 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, + 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, + 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, + 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ac, 0x2004, 0x70e2, + 0x080c, 0x3dda, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f, + 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, + 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, + 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, + 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, + 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, + 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, + 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4213, + 0x00f6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, + 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, + 0x080c, 0x3dda, 0x0140, 0x2001, 0x19a0, 0x200c, 0x2003, 0x0001, + 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, + 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c, 0x419f, + 0x2011, 0x0001, 0x080c, 0x419f, 0x00fe, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, + 0x419c, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x4198, 0x7000, + 0x0002, 0x419c, 0x414d, 0x417d, 0x4198, 0xd1bc, 0x1170, 0xd1dc, + 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x419f, 0x0904, + 0x419c, 0x080c, 0x419f, 0x0804, 0x419c, 0x00f6, 0x2079, 0x0300, + 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, + 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x409f, + 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, + 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, + 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x4141, 0x2011, 0x0001, + 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, + 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, + 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, + 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, + 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, + 0x1a0c, 0x0d79, 0x9398, 0x41cd, 0x231d, 0x083f, 0x9080, 0x0004, + 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, + 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, + 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x420a, 0x4201, 0x41f8, + 0x41ef, 0x41e6, 0x41dd, 0x41d4, 0xa964, 0x7902, 0xa968, 0x7906, + 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, + 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, + 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, + 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, + 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, + 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, + 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, + 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, 0x19e9, + 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, + 0x9026, 0x7054, 0x0002, 0x423a, 0x4226, 0x4231, 0x8001, 0x7056, + 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x419f, 0x190c, 0x419f, + 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, + 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ac, 0x2004, 0x601a, + 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce, 0x6104, 0xc1ac, + 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, + 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4bc8, 0xa813, + 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, + 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, + 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900, + 0xa85a, 0x00d0, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817, 0x0001, + 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, + 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, + 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, + 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, + 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, + 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, + 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, + 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, + 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, + 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, + 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c, 0x4bc8, + 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, + 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, + 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, + 0x2001, 0x0031, 0x201c, 0x080c, 0x4bc8, 0x2940, 0xa813, 0x0019, + 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, + 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, + 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900, 0xa85a, + 0x00d8, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, + 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, + 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, + 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, + 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, + 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001, + 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, + 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, + 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0007, + 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9, 0x0014, + 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009, 0x013c, + 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, + 0x3673, 0x7d98, 0x7c9c, 0x0804, 0x3777, 0x080c, 0x769d, 0x190c, + 0x613d, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, - 0x0804, 0x4c1a, 0x9006, 0x080c, 0x270b, 0x81ff, 0x1904, 0x36ba, - 0x080c, 0x76a5, 0x11b0, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c, - 0x347d, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xd33e, 0x0130, - 0x080c, 0x76c8, 0x1118, 0x080c, 0x7679, 0x0038, 0x080c, 0x75d4, - 0x0020, 0x080c, 0x6143, 0x080c, 0x6039, 0x0804, 0x3688, 0x81ff, - 0x1904, 0x36ba, 0x080c, 0x76a5, 0x1110, 0x0804, 0x36ba, 0x0126, - 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, 0x0000, 0x2001, - 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, - 0x0001, 0x080c, 0x4c1a, 0x701f, 0x3686, 0x012e, 0x0005, 0x704f, - 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9, 0x0001, - 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x3489, - 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100, - 0x9506, 0x01a8, 0x080c, 0x6789, 0x1190, 0xb814, 0x821c, 0x0238, - 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038, 0x9398, - 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210, 0x8108, - 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105, - 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, 0x2099, 0x1d80, - 0x080c, 0x60ce, 0x0804, 0x4587, 0x080c, 0x4c01, 0x0904, 0x36bd, - 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x080c, - 0x5826, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e, - 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3478, 0x1148, - 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, - 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcde7, - 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f, - 0x4612, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x20a9, 0x002b, + 0x080c, 0x4c11, 0x701f, 0x4395, 0x0005, 0x080c, 0x582f, 0x1130, + 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, + 0x6800, 0x9005, 0x0904, 0x36a8, 0x6804, 0xd0ac, 0x0118, 0xd0a4, + 0x0904, 0x36a8, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, + 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, + 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, + 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, + 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x36a8, 0x9288, + 0x3474, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828, + 0x908a, 0x007f, 0x1a04, 0x36a8, 0x605e, 0x6888, 0x9084, 0x0030, + 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b3, 0x9080, + 0x27dd, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018, 0x080c, 0xaae8, + 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009, 0x19b4, 0x9080, + 0x27e1, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x36a8, + 0x908a, 0x0841, 0x1a04, 0x36a8, 0x9084, 0x0007, 0x1904, 0x36a8, + 0x680c, 0x9005, 0x0904, 0x36a8, 0x6810, 0x9005, 0x0904, 0x36a8, + 0x6848, 0x6940, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8, + 0x684c, 0x6944, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8, + 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, + 0x080c, 0x79d0, 0x080c, 0x6c03, 0x080c, 0x6c65, 0x6808, 0x602a, + 0x080c, 0x21af, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, + 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2744, 0x003e, 0x6000, + 0x9086, 0x0000, 0x1904, 0x4524, 0x6818, 0x691c, 0x6a20, 0x6b24, + 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, + 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, + 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, + 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, + 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, + 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89bf, 0x00c6, 0x900e, + 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, + 0x3508, 0x8109, 0x080c, 0x7f97, 0x6878, 0x6016, 0x6874, 0x2008, + 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, + 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x447e, + 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010, + 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, + 0x29d7, 0x2001, 0x0001, 0x080c, 0x29ba, 0x0088, 0x9286, 0x4000, + 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c, + 0x29ba, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, + 0x00e6, 0x2c70, 0x080c, 0x0ec7, 0x00ee, 0x080c, 0x2aff, 0x080c, + 0x2b32, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, + 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, + 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, + 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27b9, 0x2001, + 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x769d, 0x0128, 0x080c, + 0x5108, 0x0110, 0x080c, 0x270a, 0x60d4, 0x9005, 0x01c0, 0x6003, + 0x0001, 0x2009, 0x450c, 0x00e0, 0x080c, 0x769d, 0x1168, 0x2011, + 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c, 0x8938, 0x080c, + 0x79a4, 0x080c, 0x75cc, 0x0040, 0x080c, 0x6033, 0x0028, 0x6003, + 0x0004, 0x2009, 0x4524, 0x0020, 0x080c, 0x6b2f, 0x0804, 0x3673, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x36a5, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x81ff, + 0x1904, 0x36a5, 0x080c, 0x769d, 0x11b0, 0x080c, 0x799f, 0x080c, + 0x6178, 0x080c, 0x3468, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xd35d, 0x0130, 0x080c, 0x76c0, 0x1118, 0x080c, 0x7671, 0x0038, + 0x080c, 0x75cc, 0x0020, 0x080c, 0x613d, 0x080c, 0x6033, 0x0804, + 0x3673, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x1110, 0x0804, + 0x36a5, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c14, 0x701f, 0x3671, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, + 0x9588, 0x3474, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6783, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, + 0x2099, 0x1d80, 0x080c, 0x60c8, 0x0804, 0x4581, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, + 0x36a5, 0x080c, 0x5820, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x3463, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, + 0x0003, 0x701f, 0x460c, 0x0005, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0fca, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fca, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x69c6, 0x0904, 0x36a5, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa974, 0xaa94, 0x0804, + 0x3673, 0x080c, 0x5828, 0x0904, 0x3673, 0x701f, 0x4656, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c, 0x6bcd, + 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x6a4b, 0x0904, + 0x36a5, 0x2019, 0x0004, 0x900e, 0x080c, 0x69d8, 0x0904, 0x36a5, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x4bf9, 0x01e0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, + 0x11b0, 0x080c, 0x6a4b, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x69d8, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6783, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x798c, 0x2001, 0x1981, 0x918c, + 0x8000, 0x2102, 0x080c, 0x4bdf, 0x0904, 0x36a8, 0x080c, 0x6bcd, + 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x684a, 0x0904, + 0x36a5, 0x080c, 0x69cf, 0x0904, 0x36a5, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x1981, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c, + 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x69cf, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36a5, + 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904, + 0x36a5, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x3673, 0x0804, + 0x4661, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x4bec, 0x01a0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, + 0x1170, 0x080c, 0x684a, 0x2009, 0x0002, 0x0128, 0x080c, 0x69bd, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5828, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x080c, 0x5834, 0x1904, 0x36a5, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x3673, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, + 0x939a, 0x0003, 0x1a04, 0x36a5, 0x625c, 0x7884, 0x9206, 0x1548, + 0x080c, 0x89a9, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, + 0x1118, 0x000e, 0x0804, 0x4c14, 0x000e, 0x2031, 0x0000, 0x2061, + 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4819, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x080c, 0x6bcd, 0x1904, 0x36a5, 0x00c6, 0x080c, 0x4bc8, 0x00ce, + 0x0904, 0x36a5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, + 0x080c, 0xcdaa, 0x0904, 0x36a5, 0x7007, 0x0003, 0x701f, 0x481d, + 0x0005, 0x080c, 0x435b, 0x0804, 0x3673, 0xa830, 0x9086, 0x0100, + 0x0904, 0x36a5, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x78a8, 0x9084, + 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36a5, 0x080c, + 0x769d, 0x0110, 0x080c, 0x613d, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x36a8, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, + 0x36a8, 0x2100, 0x080c, 0x26d4, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x2061, 0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, + 0x0000, 0x607f, 0x0000, 0x080c, 0x769d, 0x1158, 0x080c, 0x799f, + 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, 0x080c, 0x75cc, + 0x00f0, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2061, + 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, + 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, + 0x0000, 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x88f6, 0x7984, + 0x080c, 0x769d, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46c4, + 0x012e, 0x00ce, 0x002e, 0x0804, 0x3673, 0x7984, 0x080c, 0x6718, + 0x2b08, 0x1904, 0x36a8, 0x0804, 0x3673, 0x81ff, 0x0120, 0x2009, + 0x0001, 0x0804, 0x36a5, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, + 0x2009, 0x0005, 0x0804, 0x36a5, 0x080c, 0x4bc8, 0x1120, 0x2009, + 0x0002, 0x0804, 0x36a5, 0x7984, 0x81ff, 0x0904, 0x36a8, 0x9192, + 0x0021, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, + 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c11, 0x701f, + 0x48d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x52ba, 0x0005, + 0x2009, 0x0080, 0x080c, 0x6783, 0x1118, 0x080c, 0x6bcd, 0x0120, + 0x2021, 0x400a, 0x0804, 0x3675, 0x00d6, 0x0096, 0xa964, 0xaa6c, + 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, + 0x4971, 0x90be, 0x0112, 0x0904, 0x4971, 0x90be, 0x0113, 0x0904, + 0x4971, 0x90be, 0x0114, 0x0904, 0x4971, 0x90be, 0x0117, 0x0904, + 0x4971, 0x90be, 0x011a, 0x0904, 0x4971, 0x90be, 0x011c, 0x0904, + 0x4971, 0x90be, 0x0121, 0x0904, 0x4958, 0x90be, 0x0131, 0x0904, + 0x4958, 0x90be, 0x0171, 0x0904, 0x4971, 0x90be, 0x0173, 0x0904, + 0x4971, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, + 0x497c, 0x90be, 0x0212, 0x0904, 0x4965, 0x90be, 0x0213, 0x05e8, + 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, + 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, + 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x36a8, 0x7028, + 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, + 0x0007, 0x080c, 0x49ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, + 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49ba, 0x00c8, + 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0001, 0x080c, 0x49c7, 0x00b8, 0x7028, 0x9080, 0x000e, + 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, + 0x49c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bc8, 0x0550, + 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, + 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, + 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, + 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcdc5, + 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, + 0x49b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, + 0x36a5, 0xa820, 0x9086, 0x8001, 0x1904, 0x3673, 0x2009, 0x0004, + 0x0804, 0x36a5, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, + 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, + 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, + 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, + 0x36a5, 0x7984, 0x78a8, 0x2040, 0x080c, 0xae80, 0x1120, 0x9182, + 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff, 0x0904, 0x36a8, 0x9182, + 0x0800, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, + 0x6080, 0x924e, 0x0904, 0x36a8, 0x080c, 0xae80, 0x1120, 0x99cc, + 0xff00, 0x0904, 0x36a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x4adb, + 0x0904, 0x4a5b, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, + 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, + 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, + 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6bcd, 0x0110, + 0xc89d, 0x0438, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, + 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, + 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, + 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, + 0x3675, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, + 0x00e6, 0x2c70, 0x080c, 0xafbf, 0x0904, 0x4ab0, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bc8, + 0x00ce, 0x2b70, 0x1158, 0x080c, 0xaf4e, 0x00ee, 0x00ce, 0x00be, + 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x900e, 0xa966, + 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, + 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x32fb, 0x6023, 0x0001, + 0x9006, 0x080c, 0x66b5, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, + 0x66c9, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x2009, 0x0002, 0x080c, 0xafec, 0x78a8, 0xd094, 0x0138, 0x00ee, + 0x7024, 0x00e6, 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001, + 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, + 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x4abf, 0x0005, 0xa830, + 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, + 0x9294, 0x00ff, 0x0804, 0x576e, 0x900e, 0xa868, 0xd0f4, 0x1904, + 0x3673, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, + 0xc18d, 0x0804, 0x3673, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, + 0x4b2a, 0x902e, 0x080c, 0xae80, 0x0130, 0x9026, 0x20a9, 0x0800, + 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, + 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b3b, + 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, + 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, + 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, + 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, + 0x0598, 0xd894, 0x1588, 0x080c, 0x6b6d, 0x1570, 0x2001, 0x4000, + 0x0460, 0x080c, 0x6bcd, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, + 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, + 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xae80, 0x1900, + 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af1, 0x85ff, + 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, + 0x6718, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, + 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36a8, + 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x36a8, 0x2010, + 0x2918, 0x080c, 0x329b, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x4b7d, 0x0005, 0xa830, 0x9086, 0x0100, + 0x1904, 0x3673, 0x2009, 0x0004, 0x0804, 0x36a5, 0x7984, 0x080c, + 0xae80, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff, + 0x0904, 0x36a8, 0x9182, 0x0800, 0x1a04, 0x36a8, 0x2001, 0x9400, + 0x080c, 0x57c9, 0x1904, 0x36a5, 0x0804, 0x3673, 0xa998, 0x080c, + 0xae80, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, + 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x57c9, 0x11a8, + 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, + 0x080c, 0x104d, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, + 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, + 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, + 0x080c, 0x6783, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x6783, 0x1130, + 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, + 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x6783, 0x1108, + 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, + 0x2148, 0xa904, 0x080c, 0x107f, 0x0cc8, 0x7116, 0x711a, 0x001e, + 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, + 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x3673, 0x0005, + 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, + 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c45, 0x7a36, 0x7833, 0x0012, + 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11f4, 0x0804, 0x4cab, 0x0016, 0x0086, 0x0096, + 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, + 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x104d, 0x0904, + 0x4ca3, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, + 0x1ede, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, + 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, + 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, + 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, + 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, + 0xa146, 0x1520, 0x080c, 0x104d, 0x1130, 0x8109, 0xa946, 0x7148, + 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, + 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ede, + 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, + 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, + 0x001b, 0x0002, 0x4ccd, 0x4ccd, 0x4ccf, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4cd3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cd7, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4cdb, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cdf, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4ce3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4ce8, 0x080c, 0x0d79, 0xa276, + 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, + 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, + 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4ca6, + 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4ca6, 0x00e6, 0x2071, 0x189e, + 0x7048, 0x9005, 0x0904, 0x4d7f, 0x0126, 0x2091, 0x8000, 0x0e04, + 0x4d7e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, + 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, + 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108, + 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d81, 0xa804, 0x9005, 0x090c, + 0x0d79, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, + 0x9080, 0x1ede, 0x2005, 0xa04a, 0x0804, 0x4d81, 0x703c, 0x2060, + 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, + 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x87ff, 0x0118, 0x2748, + 0x080c, 0x107f, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, + 0x2048, 0x9005, 0x0128, 0x080c, 0x107f, 0x9006, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, + 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, + 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, + 0x7044, 0x9005, 0x090c, 0x0d79, 0x2048, 0xa800, 0x9005, 0x1de0, + 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ede, 0x2005, 0xa84a, + 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, + 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4da0, 0x4da0, 0x4da2, + 0x4da0, 0x4da0, 0x4da0, 0x4da7, 0x4da0, 0x4da0, 0x4da0, 0x4dac, + 0x4da0, 0x4da0, 0x4da0, 0x4db1, 0x4da0, 0x4da0, 0x4da0, 0x4db6, + 0x4da0, 0x4da0, 0x4da0, 0x4dbb, 0x4da0, 0x4da0, 0x4da0, 0x4dc0, + 0x080c, 0x0d79, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d2c, 0xaa84, + 0xab88, 0xac8c, 0x0804, 0x4d2c, 0xaa94, 0xab98, 0xac9c, 0x0804, + 0x4d2c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4d2c, 0xaab4, 0xabb8, + 0xacbc, 0x0804, 0x4d2c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d2c, + 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4d2c, 0x0016, 0x0026, 0x0036, + 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x6783, 0x2019, 0x0001, + 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, + 0x4c28, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, + 0x080c, 0x5820, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c28, + 0x002e, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x0126, 0x2091, 0x8000, + 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x769d, 0x1158, + 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, + 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x012e, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c, 0x6bc5, 0x0120, + 0x2009, 0x0008, 0x0804, 0x36a5, 0x7984, 0x080c, 0x6718, 0x1904, + 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x2b00, 0x7026, 0x080c, + 0x6bcd, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, + 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, + 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x0904, 0x36a5, 0x7888, + 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, + 0x4e9b, 0x0005, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009, 0x0007, + 0x1560, 0x080c, 0x6bc5, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, + 0x080c, 0x6718, 0x1530, 0x080c, 0x4bf9, 0x0518, 0x080c, 0x6bcd, + 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a74, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, + 0xc0fc, 0xa86a, 0x080c, 0xce6c, 0x11e0, 0xa89c, 0xd094, 0x0118, + 0xb8d4, 0xc08d, 0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, + 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, + 0x1110, 0x0804, 0x576e, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3673, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7f84, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, + 0x36a5, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, + 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6783, 0x1904, + 0x4f44, 0x080c, 0x6bcd, 0x0138, 0x080c, 0x6bd5, 0x0120, 0x080c, + 0x6b6d, 0x1904, 0x4f44, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, + 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, + 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, + 0x0002, 0x080c, 0x49c7, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, + 0x3d00, 0x20e0, 0x080c, 0x49c7, 0x9186, 0x007e, 0x0170, 0x9186, + 0x0080, 0x0158, 0x080c, 0x6bcd, 0x90c2, 0x0006, 0x1210, 0xc1fd, + 0x0020, 0x080c, 0x6a74, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, + 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, + 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, + 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x49ba, 0x9c80, 0x0026, + 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, + 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xae80, 0x0118, + 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, + 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, + 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4ecd, 0x86ff, 0x1120, + 0x7124, 0x810b, 0x0804, 0x3673, 0x7033, 0x0001, 0x7122, 0x7024, + 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, + 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4f80, 0x0005, + 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, + 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x0804, 0x4ecd, 0x7124, 0x810b, 0x0804, 0x3673, 0x2029, + 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9184, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, + 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, + 0x0a04, 0x36a8, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, + 0x9502, 0x0a04, 0x36a8, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, + 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9384, 0x00ff, 0x90e2, + 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9484, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, + 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, + 0x36a8, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, + 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x2009, 0x0016, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, + 0x4c11, 0x701f, 0x5004, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000, + 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9, + 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, + 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, + 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5085, 0x6804, 0x2008, + 0x918c, 0xfff8, 0x1904, 0x5085, 0x680c, 0x9005, 0x0904, 0x5085, + 0x9082, 0xff01, 0x1a04, 0x5085, 0x6810, 0x9082, 0x005c, 0x0a04, + 0x5085, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5085, 0x9182, + 0x0400, 0x1a04, 0x5085, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f0d, + 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, + 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, + 0x000f, 0x1658, 0x080c, 0x1066, 0x2900, 0x0904, 0x50a1, 0x684e, + 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dc9, + 0x00be, 0x00ee, 0x0568, 0x080c, 0x8b11, 0x080c, 0x8b60, 0x11e0, + 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, + 0x6106, 0x6b10, 0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27b9, + 0x2001, 0x0138, 0x2102, 0x0804, 0x3673, 0x080c, 0x27b9, 0x2001, + 0x0138, 0x2102, 0x0804, 0x36a8, 0x080c, 0x8b59, 0x00e6, 0x2071, + 0x1932, 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x080c, 0x8dac, 0x00ee, + 0x2001, 0x188a, 0x204c, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003, + 0x0000, 0x080c, 0x27b9, 0x2001, 0x0138, 0x2102, 0x0804, 0x36a5, + 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x5106, 0x080c, + 0x8da7, 0x0904, 0x5106, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, + 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, + 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8dac, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0035, 0x080c, 0x16ad, 0x012e, 0x00c6, 0x2061, + 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27b9, + 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c, + 0x8ce6, 0x0120, 0x2f00, 0x080c, 0x8d72, 0x0cc8, 0x00fe, 0x00ee, + 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, + 0x2148, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, + 0x183e, 0x2003, 0x0020, 0x080c, 0x8b59, 0x00e6, 0x2071, 0x1932, + 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x00ee, 0x012e, 0x0804, 0x3673, + 0x0006, 0x080c, 0x5820, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, + 0x5824, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, + 0x1118, 0x7986, 0x0804, 0x3673, 0x83ff, 0x1904, 0x36a8, 0x2001, + 0xfff0, 0x9200, 0x1a04, 0x36a8, 0x2019, 0xffff, 0x6078, 0x9302, + 0x9200, 0x0a04, 0x36a8, 0x7986, 0x6276, 0x0804, 0x3673, 0x080c, + 0x5834, 0x1904, 0x36a5, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, + 0x4bc8, 0x0904, 0x36a5, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, + 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, + 0x6bd5, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, + 0x0003, 0x080c, 0x9364, 0x2208, 0x0804, 0x3673, 0x7033, 0x0001, + 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, + 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, + 0xa696, 0xa79a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x5189, + 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, + 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0804, 0x5147, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, + 0x9364, 0x2208, 0x0804, 0x3673, 0x00f6, 0x00e6, 0x080c, 0x5834, + 0x2009, 0x0007, 0x1904, 0x521c, 0x2071, 0x189e, 0x745c, 0x84ff, + 0x2009, 0x000e, 0x1904, 0x521c, 0xac9c, 0xad98, 0xaea4, 0xafa0, + 0x0096, 0x080c, 0x1066, 0x2009, 0x0002, 0x0904, 0x521c, 0x2900, + 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, + 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, + 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1148, 0xb814, + 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, + 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, + 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x9364, + 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, + 0x0d79, 0x2148, 0x080c, 0x107f, 0x9006, 0x705e, 0x918d, 0x0001, + 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, + 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, + 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x5228, 0x000e, 0xa0a2, + 0x080c, 0x1142, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0d79, 0x00e6, 0x2071, 0x189e, + 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, + 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, + 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, + 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, + 0x900e, 0x2001, 0x0003, 0x080c, 0x9364, 0xaa9a, 0x715c, 0x81ff, + 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f, 0x705f, 0x0000, 0xa0a0, + 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f, + 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, + 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, + 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, + 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, + 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, + 0x4000, 0x715c, 0x81ff, 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f, + 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f, 0x0000, 0xa0a3, + 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, + 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1142, 0x9006, + 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, + 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36a8, + 0xa884, 0xa988, 0x080c, 0x26a1, 0x1518, 0x080c, 0x6718, 0x1500, + 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4bc8, 0x01c8, 0x080c, + 0x4bc8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xcde5, 0x1120, 0x2009, + 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x52f5, 0x0005, + 0x009e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7124, 0x080c, 0x3404, + 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, + 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, + 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0fca, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, + 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, + 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, + 0x007e, 0x0804, 0x4c14, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, + 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, + 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1142, + 0x7007, 0x0002, 0x701f, 0x5351, 0x0005, 0x000e, 0x007e, 0x0804, + 0x36a8, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fca, + 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x2009, 0x002a, 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5, + 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x0126, 0x2091, 0x8000, + 0x080c, 0x69e1, 0x012e, 0x0904, 0x36a5, 0x2001, 0x197f, 0x2004, + 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x197f, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c, + 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x69e1, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, + 0xd084, 0x0904, 0x45d6, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x080c, 0x6bcd, + 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, + 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5820, + 0xd0b4, 0x0904, 0x4610, 0x7884, 0x908e, 0x007e, 0x0904, 0x4610, + 0x908e, 0x007f, 0x0904, 0x4610, 0x908e, 0x0080, 0x0904, 0x4610, + 0xb800, 0xd08c, 0x1904, 0x4610, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x541d, 0x0005, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x0804, 0x4610, 0x080c, 0x3463, 0x0108, 0x0005, 0x2009, + 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x080c, 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c, + 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0xb89c, 0xd0a4, + 0x1118, 0xd0ac, 0x1904, 0x4610, 0x9006, 0xa866, 0xa832, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x1120, 0x2009, 0x0003, 0x0804, + 0x36a5, 0x7007, 0x0003, 0x701f, 0x5456, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x576e, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x0804, 0x53ef, 0x81ff, 0x2009, 0x0001, 0x1904, + 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5, 0x080c, + 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x2009, 0x0009, 0x1904, 0x36a5, + 0x080c, 0x4bc8, 0x2009, 0x0002, 0x0904, 0x36a5, 0x9006, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, + 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, + 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x36a8, 0xc0e5, 0xa952, + 0xa956, 0xa83e, 0x080c, 0xd0cf, 0x2009, 0x0003, 0x0904, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x54ad, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x36a5, 0x0804, 0x3673, 0x7aa8, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5834, 0x1188, 0x2009, + 0x0014, 0x0804, 0x36a5, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5, + 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57fa, 0x0804, + 0x3673, 0xd2fc, 0x0160, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x7984, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x080c, + 0x4bfb, 0x0904, 0x36a8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x2009, 0x0009, 0x1904, 0x559c, 0x080c, 0x4bc8, 0x2009, 0x0002, + 0x0904, 0x559c, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c11, 0x701f, 0x5509, + 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, + 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x36a8, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bfb, 0x1110, 0x0804, 0x36a8, + 0x2009, 0x0043, 0x080c, 0xd13b, 0x2009, 0x0003, 0x0904, 0x559c, + 0x7007, 0x0003, 0x701f, 0x552d, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x559c, 0x7984, 0x7aa8, 0x9284, 0x1000, + 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x00c6, 0xaab0, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x5834, 0x1158, 0x2009, + 0x0014, 0x0804, 0x558b, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009, + 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, + 0x57fa, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bf9, 0x0590, 0xa998, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0xa87b, 0x0000, 0xa883, + 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bf9, 0x0510, 0x080c, + 0x6bcd, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, + 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, + 0x4bf9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd13b, 0x2009, + 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36a5, + 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e, + 0x1904, 0x36a5, 0x0804, 0x3673, 0x00f6, 0x2d78, 0xaab0, 0x0021, + 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, + 0x9284, 0x1400, 0xc0fd, 0x080c, 0x57c9, 0x001e, 0x9085, 0x0001, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, + 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f, + 0x0138, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5, + 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, + 0x080c, 0xce1e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, + 0x0003, 0x701f, 0x55fc, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, + 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0, 0xa866, 0xa810, + 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, + 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c14, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, + 0x0804, 0x36a5, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, + 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, + 0x7023, 0x19cf, 0x0010, 0x0804, 0x36a8, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, + 0x4c11, 0x701f, 0x564c, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, + 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, + 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x3673, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7984, 0x9194, + 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5, + 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804, + 0x36a8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, + 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c14, + 0x7884, 0x908a, 0x1000, 0x1a04, 0x36a8, 0x0126, 0x2091, 0x8000, + 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a, + 0x00ce, 0x012e, 0x0804, 0x3673, 0x00c6, 0x080c, 0x769d, 0x1160, + 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, + 0x080c, 0x75cc, 0x080c, 0x0d79, 0x2061, 0x1800, 0x6030, 0xc09d, + 0x6032, 0x080c, 0x6033, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, + 0x2004, 0x908e, 0x0000, 0x0904, 0x36a5, 0x7884, 0x9005, 0x0188, + 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a70, 0x01a0, + 0x080c, 0x2a78, 0x0188, 0x080c, 0x2a80, 0x0170, 0x2162, 0x0804, + 0x36a8, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, + 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, + 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x0026, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x002e, 0x080c, 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e, + 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c, 0xec03, + 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c, 0x2aa2, 0x2001, + 0x1800, 0x2003, 0x0004, 0x2001, 0x19a9, 0x2003, 0x0000, 0x0026, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x002e, 0x00ce, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8, 0x96b4, + 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f, 0x0138, + 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce21, 0x1120, 0x2009, 0x0003, + 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x5757, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0, + 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4c14, 0xa898, 0x9086, + 0x000d, 0x1904, 0x36a5, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x577b, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, + 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, + 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c04, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, + 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a, + 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, + 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044, + 0x2001, 0x1a1c, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, + 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, + 0x3673, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, + 0x0198, 0x0006, 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, + 0xaaf7, 0x0106, 0x080c, 0x3428, 0x010e, 0x090c, 0xab13, 0x003e, + 0x080c, 0xcc80, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0160, 0x080c, 0x6192, 0x080c, 0xae80, 0x0110, + 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, + 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, + 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, + 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, + 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57c9, + 0x002e, 0x001e, 0x8108, 0x1f04, 0x5802, 0x015e, 0x012e, 0x0005, + 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, + 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, + 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, + 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36a8, + 0x9182, 0x0081, 0x1a04, 0x36a8, 0x810c, 0x0016, 0x080c, 0x4bc8, + 0x0170, 0x080c, 0x0f55, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, + 0x7a90, 0x001e, 0x080c, 0x4c11, 0x701f, 0x5864, 0x0005, 0x001e, + 0x2009, 0x0002, 0x0804, 0x36a5, 0x2079, 0x0000, 0x7d94, 0x7c98, + 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, + 0xa074, 0x2071, 0x189e, 0x080c, 0x4c14, 0x701f, 0x5878, 0x0005, + 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, + 0x0f5d, 0x002e, 0x001e, 0x080c, 0x100a, 0x9006, 0xa802, 0xa806, + 0x0804, 0x3673, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, + 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, + 0x5a33, 0x0068, 0xd08c, 0x0118, 0x080c, 0x593c, 0x0040, 0xd094, + 0x0118, 0x080c, 0x590c, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, + 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, + 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, + 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, + 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, + 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, + 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, + 0x2009, 0x00f7, 0x080c, 0x60f4, 0x00f0, 0x6040, 0x9084, 0x0010, + 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, + 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, + 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, + 0x5fd6, 0x080c, 0x88f6, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, + 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fd6, + 0x080c, 0x882c, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, + 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5922, 0x6242, + 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, + 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, + 0x080c, 0x617d, 0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, + 0x0d79, 0x000b, 0x0005, 0x5946, 0x5997, 0x5a32, 0x00f6, 0x0016, + 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, + 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, + 0x0120, 0x1f04, 0x5955, 0x080c, 0x0d79, 0x68a0, 0x68a2, 0x689c, + 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, + 0x6837, 0x0020, 0x080c, 0x6159, 0x2079, 0x1d00, 0x7833, 0x1101, + 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, + 0x20a1, 0x1d0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xa8ec, 0x20e1, + 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x6007, + 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, + 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x5a0f, 0x6020, 0xd0b4, + 0x1904, 0x5a0d, 0x71a0, 0x81ff, 0x0904, 0x59fb, 0x9486, 0x000c, + 0x1904, 0x5a08, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6152, + 0x2011, 0x0260, 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, + 0x8210, 0x8318, 0x1f04, 0x59b4, 0x6043, 0x0004, 0x2061, 0x0140, + 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, + 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fdd, + 0x080c, 0x88f6, 0x080c, 0x6159, 0x04c0, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, + 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, + 0x6152, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, + 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59ef, + 0x0078, 0x70a3, 0x0000, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, + 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, + 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, + 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8ec, + 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013, + 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa08e, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d79, + 0x000b, 0x0005, 0x5a64, 0x5a77, 0x5aa0, 0x5ac0, 0x5ae6, 0x5b15, + 0x5b3b, 0x5b73, 0x5b99, 0x5bc7, 0x5c02, 0x5c3a, 0x5c58, 0x5c83, + 0x5ca5, 0x5cc0, 0x5cca, 0x5cfe, 0x5d24, 0x5d53, 0x5d79, 0x5db1, + 0x5df5, 0x5e32, 0x5e53, 0x5eac, 0x5ece, 0x5efc, 0x5efc, 0x00c6, + 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, + 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, + 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, + 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x88f6, 0x0005, 0x00f6, + 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, + 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, + 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b, + 0x0010, 0x080c, 0x5cca, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, + 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, + 0x1f04, 0x5ab5, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, + 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0005, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, + 0x0000, 0x080c, 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005, + 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, + 0x5f8a, 0x0168, 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, + 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, + 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, + 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, + 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60d6, + 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152, + 0x080c, 0x6135, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, + 0xffff, 0x0180, 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, + 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110, + 0x080c, 0x270a, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x60d6, 0x2079, 0x0240, + 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x6135, 0x1150, 0x7084, + 0x9005, 0x1138, 0x080c, 0x5efd, 0x1188, 0x9085, 0x0001, 0x080c, + 0x270a, 0x20a9, 0x0008, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, + 0x080c, 0x6007, 0x0010, 0x080c, 0x5a57, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x05a8, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, + 0x0014, 0x1560, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, + 0x0000, 0x709b, 0x000e, 0x080c, 0x5ca5, 0x0010, 0x080c, 0x612e, + 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, + 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, + 0x60d6, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, + 0x6135, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, + 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, + 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, + 0x2009, 0x0240, 0x1f04, 0x5c27, 0x60c3, 0x0084, 0x080c, 0x6007, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fdd, + 0x080c, 0x882c, 0x9086, 0x0084, 0x1178, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, + 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x000d, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, + 0x1107, 0x7837, 0x0000, 0x080c, 0x6152, 0x20a9, 0x0040, 0x2011, + 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, + 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, + 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c6b, 0x60c3, 0x0084, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, + 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x000e, 0x0029, + 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, + 0x617d, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, + 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, + 0x0004, 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x8820, 0x0005, + 0x7090, 0x9005, 0x0130, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b, + 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, + 0x20a8, 0x4003, 0x080c, 0x6135, 0x11a0, 0x717c, 0x81ff, 0x0188, + 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, 0x26a1, 0x9186, + 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, + 0x5f8a, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, + 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, + 0x60e4, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, + 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, + 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0168, + 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x60e4, 0x2079, 0x0240, + 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152, 0x080c, 0x6135, + 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, + 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, + 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110, 0x080c, 0x270a, + 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6152, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, + 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x617d, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, + 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x617d, 0x7097, 0x0000, + 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, + 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, 0xa8ec, 0x080c, + 0x6152, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, + 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, + 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, + 0x080c, 0x6135, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5efd, + 0x1188, 0x9085, 0x0001, 0x080c, 0x270a, 0x20a9, 0x0008, 0x080c, + 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0010, 0x080c, + 0x5a57, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fdd, + 0x080c, 0x882c, 0x9086, 0x0084, 0x1190, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, + 0x9006, 0x080c, 0x617d, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60e4, + 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6152, + 0x2009, 0x026e, 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, + 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, + 0x0260, 0x1f04, 0x5e66, 0x2039, 0x1d0e, 0x080c, 0x6135, 0x11e8, + 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, + 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, + 0x1d0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, + 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, + 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, + 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5e99, 0x60c3, 0x0084, + 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, + 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c, + 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, + 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x001a, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, + 0x080c, 0x617d, 0x709b, 0x001b, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, + 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, + 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, + 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5ee5, 0x60c3, + 0x0084, 0x080c, 0x6007, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, + 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, + 0x28a0, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, + 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, + 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, + 0x0008, 0x8211, 0x1f04, 0x5f17, 0x0804, 0x5f86, 0x82ff, 0x1160, + 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, + 0x0904, 0x5f86, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, + 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, + 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, + 0x1f04, 0x5f3d, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, + 0x1f04, 0x5f4f, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, + 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, + 0x1f04, 0x5f5e, 0x755e, 0x95c8, 0x3474, 0x292d, 0x95ac, 0x00ff, + 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e, + 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, + 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, + 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, + 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, + 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, + 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, + 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, + 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, + 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, + 0x715e, 0x91a0, 0x3474, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, + 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e, 0x60e7, 0x0000, + 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, + 0x0100, 0x2071, 0x0140, 0x080c, 0x6097, 0x080c, 0xa09b, 0x7004, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x0126, 0x2091, 0x8000, + 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, + 0x00f7, 0x080c, 0x60f4, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, + 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, + 0xc0c5, 0x2012, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000, + 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa08e, 0x6144, + 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, + 0x1000, 0x2011, 0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fdd, + 0x080c, 0x88f6, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2009, + 0x00f7, 0x080c, 0x60f4, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e, + 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, + 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, + 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x8820, 0x012e, 0x00ce, + 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, + 0x0471, 0x2071, 0x0100, 0x080c, 0xa09b, 0x2071, 0x0140, 0x7004, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x080c, 0x76a5, 0x0188, + 0x080c, 0x76c0, 0x1170, 0x080c, 0x79a9, 0x0016, 0x080c, 0x27b9, + 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x79a4, 0x080c, 0x75cc, + 0x0050, 0x2009, 0x0001, 0x080c, 0x2a8e, 0x2001, 0x0001, 0x080c, + 0x2646, 0x080c, 0x6033, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, + 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, + 0x2001, 0x199a, 0x201c, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005, + 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6152, + 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, + 0x614c, 0x2099, 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, + 0x080c, 0x614f, 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, + 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, + 0x8210, 0x1f04, 0x60cc, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8ec, + 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, + 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, + 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, + 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6bc9, 0x0158, + 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe795, 0x2001, 0x180c, + 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32c0, + 0x080c, 0xd35d, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, + 0x080c, 0x4ddf, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6033, + 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, + 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, + 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, + 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, + 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, + 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, + 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, + 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, + 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, + 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118, + 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, + 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x618c, + 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, + 0x1847, 0x9006, 0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, + 0xb812, 0x9198, 0x3474, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, + 0x0026, 0xb886, 0x080c, 0xae80, 0x1120, 0x9192, 0x007e, 0x1208, + 0xbb86, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, + 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, + 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, + 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, + 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, + 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0xb8a7, + 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, + 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, + 0x1ddc, 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, + 0x0d79, 0x080c, 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000, + 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, + 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, + 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6268, 0x9182, 0x0800, 0x1a04, + 0x626c, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6272, + 0x9188, 0x1000, 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, + 0x908e, 0x0006, 0x1188, 0xb8a4, 0x900d, 0x1904, 0x6284, 0x080c, + 0x6644, 0x9006, 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, + 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, + 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, + 0x0d10, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, + 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, + 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, + 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, + 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, + 0x1000, 0x2104, 0x9065, 0x09a8, 0x080c, 0x6bcd, 0x1990, 0xb800, + 0xd0bc, 0x0978, 0x0804, 0x622b, 0x080c, 0x69f0, 0x0904, 0x6234, + 0x0804, 0x622f, 0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, + 0x1128, 0x7030, 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, + 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, + 0x1120, 0x2001, 0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, + 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b6d, + 0x11d0, 0x080c, 0xaef8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, + 0x6023, 0x0009, 0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, + 0x602b, 0x8000, 0x2009, 0x0043, 0x080c, 0xafec, 0x9006, 0x00b0, + 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, + 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x6363, 0x9188, + 0x1000, 0x2104, 0x905d, 0x0904, 0x633b, 0xb8a0, 0x9086, 0x007f, + 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6bd5, 0x0160, 0xa994, + 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, + 0x080c, 0x6bcd, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, + 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xcc21, 0x002e, 0x1120, + 0x2001, 0x0008, 0x0804, 0x6365, 0x6020, 0x9086, 0x000a, 0x0120, + 0x2001, 0x0008, 0x0804, 0x6365, 0x601a, 0x6003, 0x0008, 0x2900, + 0x6016, 0x0058, 0x080c, 0xaef8, 0x05e8, 0x2b00, 0x6012, 0x2900, + 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, + 0xafec, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, + 0x1290, 0x080c, 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, + 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, + 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, + 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, + 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, + 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, + 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, + 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, + 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, + 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, + 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x63fa, 0x63b5, 0x63cc, + 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x2100, 0x9082, 0x007e, + 0x1278, 0x080c, 0x6718, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, + 0x6402, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, + 0x080c, 0x4adb, 0x0150, 0x04b0, 0x080c, 0x6783, 0x1598, 0xb810, + 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0xaef8, 0x0530, + 0x2b00, 0x6012, 0x080c, 0xd0ce, 0x2900, 0x6016, 0x600b, 0xffff, + 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x32fb, + 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x2001, + 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafec, + 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, + 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, + 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x65ed, 0x90c6, 0x0056, + 0x0904, 0x65f1, 0x90c6, 0x0066, 0x0904, 0x65f5, 0x90c6, 0x0067, + 0x0904, 0x65f9, 0x90c6, 0x0068, 0x0904, 0x65fd, 0x90c6, 0x0071, + 0x0904, 0x6601, 0x90c6, 0x0074, 0x0904, 0x6605, 0x90c6, 0x007c, + 0x0904, 0x6609, 0x90c6, 0x007e, 0x0904, 0x660d, 0x90c6, 0x0037, + 0x0904, 0x6611, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, + 0x0904, 0x65e8, 0x9182, 0x0800, 0x1a04, 0x65e8, 0x080c, 0x6783, + 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, + 0x90c6, 0x006f, 0x0148, 0x080c, 0xae80, 0x1904, 0x65d1, 0xb8a0, + 0x9084, 0xff80, 0x1904, 0x65d1, 0xa894, 0x90c6, 0x006f, 0x0158, + 0x90c6, 0x005e, 0x0904, 0x6531, 0x90c6, 0x0064, 0x0904, 0x655a, + 0x2008, 0x0804, 0x64f3, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae80, + 0x1120, 0x9182, 0x007f, 0x0a04, 0x64f3, 0x9186, 0x00ff, 0x0904, + 0x64f3, 0x9182, 0x0800, 0x1a04, 0x64f3, 0xaaa0, 0xab9c, 0x787c, + 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, + 0x009e, 0x0804, 0x64f3, 0x080c, 0xae80, 0x1140, 0x99cc, 0xff00, + 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x64f3, 0x009e, 0x080c, + 0x4adb, 0x0904, 0x64fd, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, + 0x0006, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, + 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, + 0x0fca, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fca, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, + 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, + 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, + 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, + 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, + 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, + 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, 0xaef8, 0x1130, + 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x32fb, + 0x012e, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x2009, 0x0002, 0x080c, 0xafec, 0xa8b0, 0xd094, 0x0118, 0xb8d4, + 0xc08d, 0xb8d6, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, + 0x0005, 0x080c, 0x5834, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, + 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee, 0x9186, 0x007f, 0x0130, + 0x080c, 0x6bcd, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, + 0x104d, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, + 0xa806, 0x080c, 0xce21, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, + 0x0804, 0x64f5, 0xa998, 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee, + 0x0096, 0x080c, 0x104d, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, + 0x65ae, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, - 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, - 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4, - 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x8906, + 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0fca, 0x009e, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, + 0x5820, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, + 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6bcd, 0x0118, 0xa89b, + 0x0009, 0x0080, 0x080c, 0x5834, 0x0118, 0xa89b, 0x0007, 0x0050, + 0x080c, 0xce04, 0x1904, 0x652a, 0x2009, 0x0003, 0x2001, 0x4005, + 0x0804, 0x64f5, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c1a, - 0x81ff, 0x1904, 0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, - 0x69ce, 0x0904, 0x36ba, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009, - 0x0004, 0x0804, 0x36ba, 0xa974, 0xaa94, 0x0804, 0x3688, 0x080c, - 0x582e, 0x0904, 0x3688, 0x701f, 0x465c, 0x7007, 0x0003, 0x0005, - 0x81ff, 0x1904, 0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, - 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c, - 0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6a53, 0x0904, 0x36ba, 0x2019, - 0x0004, 0x900e, 0x080c, 0x69e0, 0x0904, 0x36ba, 0x7984, 0x7a88, - 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4bff, - 0x01e0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x11b0, 0x080c, - 0x6a53, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019, 0x0004, - 0x080c, 0x69e0, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, - 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x080c, - 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, - 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, 0x0110, 0x2508, - 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6789, 0x1138, 0x2200, - 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x0005, 0x81ff, - 0x1904, 0x36ba, 0x798c, 0x2001, 0x1981, 0x918c, 0x8000, 0x2102, - 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c, - 0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6850, 0x0904, 0x36ba, 0x080c, - 0x69d7, 0x0904, 0x36ba, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1904, - 0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x1981, 0x918c, 0x8000, - 0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118, - 0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128, - 0x080c, 0x69d7, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1128, - 0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001, - 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd, - 0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c, - 0x6850, 0x0904, 0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x2001, - 0x1980, 0x2004, 0xd0fc, 0x1904, 0x3688, 0x0804, 0x4667, 0xa9a0, - 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bf2, - 0x01a0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1170, 0x080c, - 0x6850, 0x2009, 0x0002, 0x0128, 0x080c, 0x69c5, 0x1170, 0x2009, - 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, - 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x582e, 0x0110, 0x9006, - 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100, - 0x0804, 0x3688, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x583a, - 0x1904, 0x36ba, 0x79a8, 0xd184, 0x1158, 0xb834, 0x8007, 0x789e, - 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050, - 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f, - 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, 0x3688, 0x78a8, - 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003, - 0x1a04, 0x36ba, 0x625c, 0x7884, 0x9206, 0x1548, 0x080c, 0x89b1, - 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, - 0x0804, 0x4c1a, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, - 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, - 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x481f, 0x0005, 0x81ff, - 0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5, - 0x1904, 0x36ba, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x0904, 0x36ba, - 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcd8d, - 0x0904, 0x36ba, 0x7007, 0x0003, 0x701f, 0x4823, 0x0005, 0x080c, - 0x4365, 0x0804, 0x3688, 0xa830, 0x9086, 0x0100, 0x0904, 0x36ba, - 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, - 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, - 0x4c1a, 0x9006, 0x080c, 0x270b, 0x78a8, 0x9084, 0x00ff, 0x9086, - 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36ba, 0x080c, 0x76a5, 0x0110, - 0x080c, 0x6143, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x7984, - 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x36bd, 0x2100, - 0x080c, 0x26d5, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, - 0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, - 0x0000, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7, 0x080c, 0x617e, - 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4, 0x00f0, 0x080c, - 0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2061, 0x0100, 0x2001, - 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, - 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, - 0x002d, 0x2011, 0x6069, 0x080c, 0x88fe, 0x7984, 0x080c, 0x76a5, - 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46ca, 0x012e, 0x00ce, - 0x002e, 0x0804, 0x3688, 0x7984, 0x080c, 0x671e, 0x2b08, 0x1904, - 0x36bd, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x36ba, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, - 0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, - 0x36ba, 0x7984, 0x81ff, 0x0904, 0x36bd, 0x9192, 0x0021, 0x1a04, - 0x36bd, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, - 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c17, 0x701f, 0x48de, 0x7880, - 0x9086, 0x006e, 0x0110, 0x701f, 0x52c0, 0x0005, 0x2009, 0x0080, - 0x080c, 0x6789, 0x1118, 0x080c, 0x6bd5, 0x0120, 0x2021, 0x400a, - 0x0804, 0x368a, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, - 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4977, 0x90be, - 0x0112, 0x0904, 0x4977, 0x90be, 0x0113, 0x0904, 0x4977, 0x90be, - 0x0114, 0x0904, 0x4977, 0x90be, 0x0117, 0x0904, 0x4977, 0x90be, - 0x011a, 0x0904, 0x4977, 0x90be, 0x011c, 0x0904, 0x4977, 0x90be, - 0x0121, 0x0904, 0x495e, 0x90be, 0x0131, 0x0904, 0x495e, 0x90be, - 0x0171, 0x0904, 0x4977, 0x90be, 0x0173, 0x0904, 0x4977, 0x90be, - 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4982, 0x90be, - 0x0212, 0x0904, 0x496b, 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, - 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, - 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, - 0x05b0, 0x009e, 0x00de, 0x0804, 0x36bd, 0x7028, 0x9080, 0x0010, - 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, - 0x49c0, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, - 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49c0, 0x00c8, 0x7028, 0x9080, - 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, - 0x080c, 0x49cd, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, - 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49cd, 0x7028, - 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, - 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bce, 0x0550, 0xa868, 0xc0fd, - 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, - 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, - 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, 0xa868, - 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcda8, 0x1120, 0x2009, - 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f, 0x49b7, 0x0005, - 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa820, - 0x9086, 0x8001, 0x1904, 0x3688, 0x2009, 0x0004, 0x0804, 0x36ba, - 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, - 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0036, - 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, 0x4104, - 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, - 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x60dc, 0xd0ac, - 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x7984, - 0x78a8, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182, 0x007f, 0x0a04, - 0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd, 0x9182, 0x0800, 0x1a04, - 0x36bd, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e, - 0x0904, 0x36bd, 0x080c, 0xae60, 0x1120, 0x99cc, 0xff00, 0x0904, - 0x36bd, 0x0126, 0x2091, 0x8000, 0x080c, 0x4ae1, 0x0904, 0x4a61, - 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, - 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, - 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, - 0x0570, 0xd88c, 0x1128, 0x080c, 0x6bd5, 0x0110, 0xc89d, 0x0438, - 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, - 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, - 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, - 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, - 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x368a, 0x000e, - 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, - 0x080c, 0xaf9f, 0x0904, 0x4ab6, 0x2b00, 0x6012, 0x080c, 0xd0b1, - 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x2b70, - 0x1158, 0x080c, 0xaf2e, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, - 0x2009, 0x0002, 0x0804, 0x36ba, 0x900e, 0xa966, 0xa96a, 0x2900, - 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, - 0xd89c, 0x1110, 0x080c, 0x3310, 0x6023, 0x0001, 0x9006, 0x080c, - 0x66bb, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x66cf, 0x2009, - 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002, - 0x080c, 0xafcc, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, - 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001, 0x00ee, 0x00ce, - 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, - 0x7007, 0x0003, 0x701f, 0x4ac5, 0x0005, 0xa830, 0x9086, 0x0100, - 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, - 0x0804, 0x5774, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3688, 0x080c, - 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, - 0x3688, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4b30, 0x902e, - 0x080c, 0xae60, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, - 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, - 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b41, 0x2428, 0x94ce, - 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, - 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, - 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, - 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, 0x0598, 0xd894, - 0x1588, 0x080c, 0x6b75, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c, - 0x6bd5, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, - 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, - 0x1128, 0x86ff, 0x0918, 0x080c, 0xae60, 0x1900, 0x2001, 0x4008, - 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af7, 0x85ff, 0x1130, 0x2001, - 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x671e, 0x1dd0, - 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, - 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x4bce, - 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868, - 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36bd, 0x9096, 0x00ff, - 0x0120, 0x9092, 0x0004, 0x1a04, 0x36bd, 0x2010, 0x2918, 0x080c, - 0x32b0, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, - 0x701f, 0x4b83, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x3688, - 0x2009, 0x0004, 0x0804, 0x36ba, 0x7984, 0x080c, 0xae60, 0x1120, - 0x9182, 0x007f, 0x0a04, 0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd, - 0x9182, 0x0800, 0x1a04, 0x36bd, 0x2001, 0x9400, 0x080c, 0x57cf, - 0x1904, 0x36ba, 0x0804, 0x3688, 0xa998, 0x080c, 0xae60, 0x1118, - 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, - 0x1250, 0x2001, 0x9400, 0x080c, 0x57cf, 0x11a8, 0x0060, 0xa897, - 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, 0x1059, - 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, - 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, - 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6789, - 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, - 0x8bff, 0x0005, 0xa998, 0x080c, 0x6789, 0x1130, 0xae9c, 0x9684, - 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, - 0x0008, 0x7e84, 0x2608, 0x080c, 0x6789, 0x1108, 0x0008, 0x905e, - 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, - 0x080c, 0x108b, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, - 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, - 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, - 0x114e, 0x7007, 0x0002, 0x701f, 0x3688, 0x0005, 0x00f6, 0x0126, - 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, - 0x1190, 0x0e04, 0x4c4b, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, - 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x0804, 0x4cb1, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, - 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, - 0x0288, 0x7038, 0x2060, 0x080c, 0x1059, 0x0904, 0x4ca9, 0xa84b, - 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, - 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, - 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, - 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, 0x714a, - 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, - 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, - 0x080c, 0x1059, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, - 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, - 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa846, - 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, - 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, - 0x4cd3, 0x4cd3, 0x4cd5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4cd9, 0x4cd3, - 0x4cd3, 0x4cd3, 0x4cdd, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce1, 0x4cd3, - 0x4cd3, 0x4cd3, 0x4ce5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce9, 0x4cd3, - 0x4cd3, 0x4cd3, 0x4cee, 0x080c, 0x0d85, 0xa276, 0xa37a, 0xa47e, - 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, - 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, - 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4cac, 0xa2d6, 0xa3da, - 0xa4de, 0x0804, 0x4cac, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, - 0x0904, 0x4d85, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4d84, 0x00f6, - 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, - 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, - 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, - 0xa94a, 0x1904, 0x4d87, 0xa804, 0x9005, 0x090c, 0x0d85, 0x7042, - 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x1ee2, - 0x2005, 0xa04a, 0x0804, 0x4d87, 0x703c, 0x2060, 0x2c14, 0x6304, - 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, - 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x1200, 0x87ff, 0x0118, 0x2748, 0x080c, 0x108b, - 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, - 0x0128, 0x080c, 0x108b, 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, - 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, - 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, - 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, 0x9005, - 0x090c, 0x0d85, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, - 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa84a, 0x0000, 0x007e, - 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, - 0x9082, 0x001b, 0x0002, 0x4da6, 0x4da6, 0x4da8, 0x4da6, 0x4da6, - 0x4da6, 0x4dad, 0x4da6, 0x4da6, 0x4da6, 0x4db2, 0x4da6, 0x4da6, - 0x4da6, 0x4db7, 0x4da6, 0x4da6, 0x4da6, 0x4dbc, 0x4da6, 0x4da6, - 0x4da6, 0x4dc1, 0x4da6, 0x4da6, 0x4da6, 0x4dc6, 0x080c, 0x0d85, - 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d32, 0xaa84, 0xab88, 0xac8c, - 0x0804, 0x4d32, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4d32, 0xaaa4, - 0xaba8, 0xacac, 0x0804, 0x4d32, 0xaab4, 0xabb8, 0xacbc, 0x0804, - 0x4d32, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d32, 0xaad4, 0xabd8, - 0xacdc, 0x0804, 0x4d32, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, - 0x2009, 0x007e, 0x080c, 0x6789, 0x2019, 0x0001, 0xb85c, 0xd0ac, - 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, 0x4c2e, 0x00ce, - 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x5826, - 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x002e, 0x0005, - 0x81ff, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, - 0xc085, 0xc0ac, 0x6032, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7, - 0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4, - 0x0010, 0x080c, 0x6039, 0x012e, 0x0804, 0x3688, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009, - 0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0008, - 0x0804, 0x36ba, 0x7984, 0x080c, 0x671e, 0x1904, 0x36bd, 0x080c, - 0x4c01, 0x0904, 0x36bd, 0x2b00, 0x7026, 0x080c, 0x6bd5, 0x7888, - 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6a7c, 0x1108, - 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3688, 0x080c, - 0x4bce, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0xce4f, 0x0904, 0x36ba, 0x7888, 0xd094, 0x0118, - 0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4ea1, 0x0005, - 0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x1560, 0x080c, - 0x6bcd, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x671e, - 0x1530, 0x080c, 0x4bff, 0x0518, 0x080c, 0x6bd5, 0xa89c, 0x1168, - 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, - 0x080c, 0xce4f, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8d4, 0xc08d, - 0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, - 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, - 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, - 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, - 0x5774, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, - 0x0108, 0xc18d, 0x0804, 0x3688, 0x080c, 0x583a, 0x0120, 0x2009, - 0x0007, 0x0804, 0x36ba, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x900e, - 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, - 0x0005, 0x702a, 0x20a0, 0x080c, 0x6789, 0x1904, 0x4f4a, 0x080c, - 0x6bd5, 0x0138, 0x080c, 0x6bdd, 0x0120, 0x080c, 0x6b75, 0x1904, - 0x4f4a, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, - 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, - 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, - 0x49cd, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, - 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, - 0x080c, 0x49cd, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158, - 0x080c, 0x6bd5, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, - 0x6a7c, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, - 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, - 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, - 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, - 0x3d00, 0x20e0, 0x080c, 0x49c0, 0x9c80, 0x0026, 0x2098, 0xb8c4, - 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, - 0x96b0, 0x0005, 0x8108, 0x080c, 0xae60, 0x0118, 0x9186, 0x0800, - 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, - 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, - 0x0028, 0x0150, 0x0804, 0x4ed3, 0x86ff, 0x1120, 0x7124, 0x810b, - 0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, - 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, - 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, - 0x114e, 0x7007, 0x0002, 0x701f, 0x4f86, 0x0005, 0x7030, 0x9005, - 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, - 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, - 0x4ed3, 0x7124, 0x810b, 0x0804, 0x3688, 0x2029, 0x007e, 0x7984, - 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, - 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9184, 0x00ff, 0x90e2, - 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9284, 0xff00, - 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, - 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, - 0x36bd, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd, - 0x9502, 0x0a04, 0x36bd, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, - 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0xff00, 0x8007, 0x90e2, - 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0x00ff, - 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x2061, - 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x3688, 0x080c, - 0x4bce, 0x0904, 0x36ba, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f, - 0x500a, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, - 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e, - 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84, - 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003, - 0x6800, 0x9005, 0x0904, 0x508b, 0x6804, 0x2008, 0x918c, 0xfff8, - 0x1904, 0x508b, 0x680c, 0x9005, 0x0904, 0x508b, 0x9082, 0xff01, - 0x1a04, 0x508b, 0x6810, 0x9082, 0x005c, 0x0a04, 0x508b, 0x6824, - 0x2008, 0x9082, 0x0008, 0x0a04, 0x508b, 0x9182, 0x0400, 0x1a04, - 0x508b, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f15, 0x005e, 0x6944, - 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828, - 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, 0x000f, 0x1658, - 0x080c, 0x1072, 0x2900, 0x0904, 0x50a7, 0x684e, 0x00e6, 0x2071, - 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dd1, 0x00be, 0x00ee, - 0x0568, 0x080c, 0x8b19, 0x080c, 0x8b68, 0x11e0, 0x6857, 0x0000, - 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10, - 0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138, - 0x2102, 0x0804, 0x3688, 0x080c, 0x27ba, 0x2001, 0x0138, 0x2102, - 0x0804, 0x36bd, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c, - 0x8f95, 0x080c, 0x8fa4, 0x080c, 0x8db4, 0x00ee, 0x2001, 0x188a, - 0x204c, 0x080c, 0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x080c, - 0x27ba, 0x2001, 0x0138, 0x2102, 0x0804, 0x36ba, 0x2001, 0x1926, - 0x200c, 0x918e, 0x0000, 0x0904, 0x510c, 0x080c, 0x8daf, 0x0904, - 0x510c, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, - 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, - 0x1de8, 0x00ee, 0x080c, 0x8db4, 0x0126, 0x2091, 0x8000, 0x2001, - 0x0035, 0x080c, 0x16b9, 0x012e, 0x00c6, 0x2061, 0x193e, 0x6004, - 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138, - 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c, 0x8cee, 0x0120, - 0x2f00, 0x080c, 0x8d7a, 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, - 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, - 0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, 0x183e, 0x2003, - 0x0020, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8f95, - 0x080c, 0x8fa4, 0x00ee, 0x012e, 0x0804, 0x3688, 0x0006, 0x080c, - 0x5826, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a, 0xd0bc, - 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, - 0x0804, 0x3688, 0x83ff, 0x1904, 0x36bd, 0x2001, 0xfff0, 0x9200, - 0x1a04, 0x36bd, 0x2019, 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, - 0x36bd, 0x7986, 0x6276, 0x0804, 0x3688, 0x080c, 0x583a, 0x1904, - 0x36ba, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4bce, 0x0904, - 0x36ba, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, - 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, - 0x8bff, 0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, - 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, - 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, - 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, - 0x936c, 0x2208, 0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024, - 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, - 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, - 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x518f, 0x0005, 0x7030, - 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, - 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, - 0x514d, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208, - 0x0804, 0x3688, 0x00f6, 0x00e6, 0x080c, 0x583a, 0x2009, 0x0007, - 0x1904, 0x5222, 0x2071, 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, - 0x1904, 0x5222, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, - 0x1072, 0x2009, 0x0002, 0x0904, 0x5222, 0x2900, 0x705e, 0x900e, - 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, - 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, - 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814, 0x20a9, 0x0001, - 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, - 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, - 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208, 0x009e, - 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, 0x0d85, 0x2148, - 0x080c, 0x108b, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, - 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, - 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, - 0xa696, 0xa79a, 0xa09f, 0x522e, 0x000e, 0xa0a2, 0x080c, 0x114e, - 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, - 0x904d, 0x090c, 0x0d85, 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, - 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, - 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, - 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, - 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, - 0x0003, 0x080c, 0x936c, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0d85, - 0x2148, 0x080c, 0x108b, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3, - 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, - 0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814, - 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, - 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, - 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, - 0x81ff, 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, 0x9006, 0x705e, - 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, - 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, - 0xa592, 0xa696, 0xa79a, 0x080c, 0x114e, 0x9006, 0x00ee, 0x0005, - 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, - 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36bd, 0xa884, 0xa988, - 0x080c, 0x26a2, 0x1518, 0x080c, 0x671e, 0x1500, 0x7126, 0xbe12, - 0xbd16, 0xae7c, 0x080c, 0x4bce, 0x01c8, 0x080c, 0x4bce, 0x01b0, - 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, - 0xa804, 0x2048, 0x080c, 0xcdc8, 0x1120, 0x2009, 0x0003, 0x0804, - 0x36ba, 0x7007, 0x0003, 0x701f, 0x52fb, 0x0005, 0x009e, 0x2009, - 0x0002, 0x0804, 0x36ba, 0x7124, 0x080c, 0x3419, 0xa820, 0x9086, - 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0x2900, 0x7022, - 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, - 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0xaa6c, - 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, - 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, - 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, - 0x4c1a, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, - 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, - 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, - 0x701f, 0x5357, 0x0005, 0x000e, 0x007e, 0x0804, 0x36bd, 0x7020, - 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, - 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, - 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0x2100, 0x2238, - 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, - 0x002a, 0x0804, 0x4c1a, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001, - 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd, - 0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c, - 0x6850, 0x0904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x69e9, - 0x012e, 0x0904, 0x36ba, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, - 0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, - 0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118, - 0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128, - 0x080c, 0x69e9, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, - 0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, - 0x45dc, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x4bce, 0x1120, - 0x2009, 0x0002, 0x0804, 0x36ba, 0x080c, 0x6bd5, 0x0130, 0x908e, - 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, - 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5826, 0xd0b4, 0x0904, - 0x4616, 0x7884, 0x908e, 0x007e, 0x0904, 0x4616, 0x908e, 0x007f, - 0x0904, 0x4616, 0x908e, 0x0080, 0x0904, 0x4616, 0xb800, 0xd08c, - 0x1904, 0x4616, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, - 0xcde7, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, - 0x701f, 0x5423, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x0804, - 0x4616, 0x080c, 0x3478, 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, - 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, - 0x0120, 0x2009, 0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120, - 0x2009, 0x0008, 0x0804, 0x36ba, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, - 0x1904, 0x4616, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, - 0x080c, 0xce4f, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, - 0x0003, 0x701f, 0x545c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, - 0x2009, 0x0004, 0x0804, 0x5774, 0x080c, 0x4c01, 0x0904, 0x36bd, - 0x0804, 0x53f5, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba, 0x080c, - 0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0x080c, 0x6bcd, 0x0120, - 0x2009, 0x0008, 0x0804, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, - 0x080c, 0x6bd5, 0x2009, 0x0009, 0x1904, 0x36ba, 0x080c, 0x4bce, - 0x2009, 0x0002, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868, - 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, - 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, - 0x928e, 0x0100, 0x1904, 0x36bd, 0xc0e5, 0xa952, 0xa956, 0xa83e, - 0x080c, 0xd0b2, 0x2009, 0x0003, 0x0904, 0x36ba, 0x7007, 0x0003, - 0x701f, 0x54b3, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, - 0x0904, 0x36ba, 0x0804, 0x3688, 0x7aa8, 0x9284, 0xc000, 0x0148, - 0xd2ec, 0x01a0, 0x080c, 0x583a, 0x1188, 0x2009, 0x0014, 0x0804, - 0x36ba, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba, - 0x080c, 0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0xd2f4, 0x0138, - 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0804, 0x3688, 0xd2fc, - 0x0160, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7984, 0x9284, 0x9000, - 0xc0d5, 0x080c, 0x57cf, 0x0804, 0x3688, 0x080c, 0x4c01, 0x0904, - 0x36bd, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, - 0x1904, 0x55a2, 0x080c, 0x4bce, 0x2009, 0x0002, 0x0904, 0x55a2, - 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x080c, 0x4c17, 0x701f, 0x550f, 0x0005, 0xa86c, - 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, 0xa874, 0x9084, - 0xff00, 0x0110, 0x1904, 0x36bd, 0xa866, 0xa832, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0x4c01, 0x1110, 0x0804, 0x36bd, 0x2009, 0x0043, - 0x080c, 0xd11e, 0x2009, 0x0003, 0x0904, 0x55a2, 0x7007, 0x0003, - 0x701f, 0x5533, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, - 0x0904, 0x55a2, 0x7984, 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, - 0x57cf, 0x0804, 0x3688, 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, - 0xd2ec, 0x0170, 0x080c, 0x583a, 0x1158, 0x2009, 0x0014, 0x0804, - 0x5591, 0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x15c8, - 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0058, - 0xd2fc, 0x0180, 0x080c, 0x4bff, 0x0590, 0xa998, 0x9284, 0x9000, - 0xc0d5, 0x080c, 0x57cf, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, - 0x4000, 0x0438, 0x080c, 0x4bff, 0x0510, 0x080c, 0x6bd5, 0x2009, - 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, - 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4bff, 0x1108, - 0x0070, 0x2009, 0x004b, 0x080c, 0xd11e, 0x2009, 0x0003, 0x0108, - 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, - 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, - 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36ba, 0x0016, 0x7984, - 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57cf, 0x001e, 0x1904, 0x36ba, - 0x0804, 0x3688, 0x00f6, 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, - 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, 0x9284, 0x1400, - 0xc0fd, 0x080c, 0x57cf, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, - 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, - 0x2009, 0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff, - 0x080c, 0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c, - 0x6bd5, 0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce, - 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868, - 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xce01, - 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f, - 0x5602, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, - 0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, - 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, - 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, - 0x4c1a, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, - 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, - 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf, - 0x0010, 0x0804, 0x36bd, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f, - 0x5652, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, - 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, - 0x20e9, 0x0001, 0x4003, 0x0804, 0x3688, 0x080c, 0x4bce, 0x1120, - 0x2009, 0x0002, 0x0804, 0x36ba, 0x7984, 0x9194, 0xff00, 0x918c, - 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6, - 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804, 0x36bd, 0xa85c, - 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, - 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c1a, 0x7884, 0x908a, - 0x1000, 0x1a04, 0x36bd, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, - 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a, 0x00ce, 0x012e, - 0x0804, 0x3688, 0x00c6, 0x080c, 0x76a5, 0x1160, 0x080c, 0x79a7, - 0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4, - 0x080c, 0x0d85, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, - 0x6039, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, - 0x0000, 0x0904, 0x36ba, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, - 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a89, 0x01a0, 0x080c, 0x2a91, - 0x0188, 0x080c, 0x2a99, 0x0170, 0x2162, 0x0804, 0x36bd, 0x2061, - 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, - 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, 0x2061, 0x0100, - 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0, 0x0026, 0x2011, 0x0003, - 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x002e, 0x080c, - 0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x080c, 0xaafc, - 0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c, 0xeb98, 0x9085, 0x0001, - 0x080c, 0x76e9, 0x9006, 0x080c, 0x2abb, 0x2001, 0x1800, 0x2003, - 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x0026, 0x2011, 0x0008, - 0x080c, 0x2af5, 0x002e, 0x00ce, 0x0804, 0x3688, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009, - 0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, - 0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c, 0x6bd5, - 0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120, - 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, - 0x7007, 0x0003, 0x701f, 0x575d, 0x0005, 0xa830, 0x9086, 0x0100, - 0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa834, - 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0xaf60, 0x0804, 0x4c1a, 0xa898, 0x9086, 0x000d, 0x1904, - 0x36ba, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5781, - 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, - 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, - 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c0a, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x7007, 0x0001, - 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, - 0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a, 0x6156, 0x605f, - 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, 0x606e, 0x7888, - 0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044, 0x2001, 0x1a1c, - 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, - 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x3688, 0x0126, - 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0198, 0x0006, - 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, 0xaae0, 0x0106, - 0x080c, 0x343d, 0x010e, 0x090c, 0xaafc, 0x003e, 0x080c, 0xcc63, - 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, - 0x0160, 0x080c, 0x6198, 0x080c, 0xae60, 0x0110, 0xb817, 0x0000, - 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, - 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, - 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, - 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, - 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57cf, 0x002e, 0x001e, - 0x8108, 0x1f04, 0x5808, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, - 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, - 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, - 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, - 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, - 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36bd, 0x9182, 0x0081, - 0x1a04, 0x36bd, 0x810c, 0x0016, 0x080c, 0x4bce, 0x0170, 0x080c, - 0x0f61, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, - 0x080c, 0x4c17, 0x701f, 0x586a, 0x0005, 0x001e, 0x2009, 0x0002, - 0x0804, 0x36ba, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, - 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, - 0x189e, 0x080c, 0x4c1a, 0x701f, 0x587e, 0x0005, 0x2061, 0x18b8, - 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f69, 0x002e, - 0x001e, 0x080c, 0x1016, 0x9006, 0xa802, 0xa806, 0x0804, 0x3688, - 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, - 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, - 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x5a39, 0x0068, - 0xd08c, 0x0118, 0x080c, 0x5942, 0x0040, 0xd094, 0x0118, 0x080c, - 0x5912, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, - 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, - 0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, - 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, - 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, - 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, - 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, - 0x080c, 0x60fa, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, - 0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, - 0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000, 0x7097, - 0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5fdc, 0x080c, - 0x88fe, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, - 0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fdc, 0x080c, 0x8834, - 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, - 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5928, 0x6242, 0x709b, 0x0000, - 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, - 0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6183, - 0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d85, 0x000b, - 0x0005, 0x594c, 0x599d, 0x5a38, 0x00f6, 0x0016, 0x6900, 0x918c, - 0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, - 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, - 0x595b, 0x080c, 0x0d85, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, - 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, - 0x080c, 0x615f, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000, - 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e, - 0x20a9, 0x0004, 0x4003, 0x080c, 0xa8d5, 0x20e1, 0x0001, 0x2099, - 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, - 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x600d, 0x00fe, 0x9006, - 0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, - 0x0000, 0x9025, 0x0904, 0x5a15, 0x6020, 0xd0b4, 0x1904, 0x5a13, - 0x71a0, 0x81ff, 0x0904, 0x5a01, 0x9486, 0x000c, 0x1904, 0x5a0e, - 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6158, 0x2011, 0x0260, - 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, - 0x1f04, 0x59ba, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, - 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, - 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe, - 0x080c, 0x615f, 0x04c0, 0x080c, 0x6158, 0x2079, 0x0260, 0x7930, - 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, - 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x6158, 0x2011, - 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, - 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59f5, 0x0078, 0x70a3, - 0x0000, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, - 0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, - 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, - 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8d5, 0x20e1, 0x0001, - 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, - 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, - 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x08d8, - 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d85, 0x000b, 0x0005, - 0x5a6a, 0x5a7d, 0x5aa6, 0x5ac6, 0x5aec, 0x5b1b, 0x5b41, 0x5b79, - 0x5b9f, 0x5bcd, 0x5c08, 0x5c40, 0x5c5e, 0x5c89, 0x5cab, 0x5cc6, - 0x5cd0, 0x5d04, 0x5d2a, 0x5d59, 0x5d7f, 0x5db7, 0x5dfb, 0x5e38, - 0x5e59, 0x5eb2, 0x5ed4, 0x5f02, 0x5f02, 0x00c6, 0x2061, 0x1800, - 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, - 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, - 0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, - 0x2011, 0x5fe3, 0x080c, 0x88fe, 0x0005, 0x00f6, 0x7090, 0x9086, - 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6158, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, - 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0010, 0x080c, - 0x5cd0, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0003, 0x6043, 0x0004, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x080c, - 0x60dc, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, - 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5abb, - 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090, - 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, - 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, - 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, - 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, - 0x60dc, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, - 0x6158, 0x080c, 0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, - 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168, - 0x080c, 0x6111, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, - 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, - 0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, - 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, - 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, - 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60dc, 0x2079, 0x0240, - 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b, - 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, - 0x9180, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, - 0x080c, 0x5f90, 0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b, - 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c, - 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, - 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, - 0x0008, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, - 0x709b, 0x0009, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1105, - 0x7837, 0x0100, 0x080c, 0x613b, 0x1150, 0x7084, 0x9005, 0x1138, - 0x080c, 0x5f03, 0x1188, 0x9085, 0x0001, 0x080c, 0x270b, 0x20a9, - 0x0008, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, - 0x0010, 0x080c, 0x5a5d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x05a8, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x1560, - 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, - 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, - 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, - 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, - 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, - 0x000e, 0x080c, 0x5cab, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0, - 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x60dc, 0x2079, - 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x613b, 0x0118, - 0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, - 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210, 0x8108, - 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, - 0x1f04, 0x5c2d, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fe3, 0x080c, 0x8834, - 0x9086, 0x0084, 0x1178, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, - 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x000d, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, - 0x0000, 0x080c, 0x6158, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, - 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, - 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, - 0x0260, 0x1f04, 0x5c71, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3, 0x080c, - 0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, - 0x0001, 0x080c, 0x60ae, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, - 0x6134, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6183, 0x709b, - 0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, - 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, - 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x8828, 0x0005, 0x7090, 0x9005, - 0x0130, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0000, 0x0005, - 0x709b, 0x0011, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000, - 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, - 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, - 0x080c, 0x613b, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, - 0x9084, 0x00ff, 0x0160, 0x080c, 0x26a2, 0x9186, 0x007e, 0x0138, - 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f90, 0x60c3, - 0x0014, 0x080c, 0x600d, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, - 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, - 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, - 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, - 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, - 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x60ea, 0x2079, - 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, - 0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, - 0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168, 0x080c, 0x6111, - 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c, - 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, - 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, - 0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, - 0x709b, 0x0015, 0x080c, 0x60ea, 0x2079, 0x0240, 0x7833, 0x1104, - 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b, 0x11b8, 0x7084, - 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x3489, - 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f90, - 0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b, 0x20a9, 0x0008, - 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, - 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x05f0, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, - 0x0014, 0x15a8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, - 0x1168, 0x9085, 0x0001, 0x080c, 0x6183, 0x7a38, 0xd2fc, 0x0128, - 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x9085, 0x0001, 0x080c, 0x6183, 0x7097, 0x0000, 0x7a38, 0xd2f4, - 0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, - 0x0000, 0x00fe, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, - 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, - 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, - 0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x613b, - 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5f03, 0x1188, 0x9085, - 0x0001, 0x080c, 0x270b, 0x20a9, 0x0008, 0x080c, 0x6158, 0x20e1, - 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, - 0x60c3, 0x0014, 0x080c, 0x600d, 0x0010, 0x080c, 0x5a5d, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fe3, 0x080c, 0x8834, - 0x9086, 0x0084, 0x1190, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, - 0x6183, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, - 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60ea, 0x2079, 0x0240, - 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6158, 0x2009, 0x026e, - 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, - 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, - 0x5e6c, 0x2039, 0x1d0e, 0x080c, 0x613b, 0x11e8, 0x2728, 0x2514, - 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, - 0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1d0e, 0x2414, - 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, - 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, - 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, - 0x2009, 0x0240, 0x1f04, 0x5e9f, 0x60c3, 0x0084, 0x080c, 0x600d, - 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3, - 0x080c, 0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, - 0x7097, 0x0001, 0x080c, 0x60ae, 0x709b, 0x001a, 0x0029, 0x0010, - 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6183, - 0x709b, 0x001b, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x2011, 0x0260, - 0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, - 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, - 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, - 0x6816, 0x2011, 0x0260, 0x1f04, 0x5eeb, 0x60c3, 0x0084, 0x080c, - 0x600d, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, - 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c, - 0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, - 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, - 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, - 0x1f04, 0x5f1d, 0x0804, 0x5f8c, 0x82ff, 0x1160, 0xd5d4, 0x0120, - 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f8c, - 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, - 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, - 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5f43, - 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f55, - 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, - 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f64, - 0x755e, 0x95c8, 0x3489, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, - 0x6536, 0x0016, 0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000, - 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, - 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, - 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, - 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, - 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, - 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, - 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, - 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, - 0x3489, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, - 0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, - 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, - 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, - 0x0140, 0x080c, 0x609d, 0x080c, 0xa08a, 0x7004, 0x9084, 0x4000, - 0x0110, 0x080c, 0x2acb, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, - 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, - 0x60fa, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, - 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, - 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, - 0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x6144, 0xd184, 0x0120, - 0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, - 0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe, - 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, - 0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2009, 0x00f7, 0x080c, - 0x60fa, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e, - 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, - 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d, - 0x2011, 0x6069, 0x080c, 0x8828, 0x012e, 0x00ce, 0x002e, 0x001e, - 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, - 0x0100, 0x080c, 0xa08a, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, - 0x0110, 0x080c, 0x2acb, 0x080c, 0x76ad, 0x0188, 0x080c, 0x76c8, - 0x1170, 0x080c, 0x79b1, 0x0016, 0x080c, 0x27ba, 0x2001, 0x196e, - 0x2102, 0x001e, 0x080c, 0x79ac, 0x080c, 0x75d4, 0x0050, 0x2009, - 0x0001, 0x080c, 0x2aa7, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, - 0x6039, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, - 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x199a, - 0x201c, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, - 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6158, 0x20e9, 0x0000, - 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6152, 0x2099, - 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6155, - 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026, - 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, - 0x60d2, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8d5, 0x20e1, 0x0001, - 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, - 0x4003, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000, - 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, - 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, - 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, - 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, - 0x0005, 0x0016, 0x0046, 0x080c, 0x6bd1, 0x0158, 0x9006, 0x2020, - 0x2009, 0x002a, 0x080c, 0xe72a, 0x2001, 0x180c, 0x200c, 0xc195, - 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32d5, 0x080c, 0xd33e, - 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4de5, - 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6039, 0x709b, 0x0000, - 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, - 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, - 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, - 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, - 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, - 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, - 0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, 0x2200, 0x7807, - 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, - 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, - 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001, - 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, - 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x6192, 0x015e, 0x0005, - 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, - 0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, - 0x3489, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886, - 0x080c, 0xae60, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86, 0x20a9, - 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, - 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, - 0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, 0xb862, 0xb866, - 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, - 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, - 0xb8a4, 0x904d, 0x0110, 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e, - 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, - 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1ddc, 0x0a0c, - 0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x080c, - 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x6814, 0x9084, - 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, - 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x1a04, 0x626e, 0x9182, 0x0800, 0x1a04, 0x6272, 0x2001, - 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6278, 0x9188, 0x1000, - 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, - 0x1188, 0xb8a4, 0x900d, 0x1904, 0x628a, 0x080c, 0x664a, 0x9006, - 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, - 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xae60, 0x1160, - 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0d10, 0x2001, - 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, - 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, - 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, - 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, - 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, - 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, - 0x9065, 0x09a8, 0x080c, 0x6bd5, 0x1990, 0xb800, 0xd0bc, 0x0978, - 0x0804, 0x6231, 0x080c, 0x69f8, 0x0904, 0x623a, 0x0804, 0x6235, - 0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x1128, 0x7030, - 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6, 0x00e6, - 0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, - 0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, - 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b75, 0x11d0, 0x080c, - 0xaed8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, - 0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000, - 0x2009, 0x0043, 0x080c, 0xafcc, 0x9006, 0x00b0, 0x2001, 0x0028, - 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, - 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, - 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, - 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, - 0xa974, 0x9182, 0x0800, 0x1a04, 0x6369, 0x9188, 0x1000, 0x2104, - 0x905d, 0x0904, 0x6341, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, - 0xd0fc, 0x1178, 0x080c, 0x6bdd, 0x0160, 0xa994, 0x81ff, 0x0130, - 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6bd5, - 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, - 0x0026, 0x2010, 0x080c, 0xcc04, 0x002e, 0x1120, 0x2001, 0x0008, - 0x0804, 0x636b, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, - 0x0804, 0x636b, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, - 0x080c, 0xaed8, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, - 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006, - 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, - 0xae60, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, - 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, - 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, - 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, - 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, - 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, - 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, - 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, - 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, - 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, - 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, - 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, - 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, - 0x00be, 0x00fe, 0x0005, 0x6400, 0x63bb, 0x63d2, 0x6400, 0x6400, - 0x6400, 0x6400, 0x6400, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, - 0x671e, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6408, 0xb814, - 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4ae1, - 0x0150, 0x04b0, 0x080c, 0x6789, 0x1598, 0xb810, 0x9306, 0x1580, - 0xb814, 0x9206, 0x1568, 0x080c, 0xaed8, 0x0530, 0x2b00, 0x6012, - 0x080c, 0xd0b1, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, - 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3310, 0x9006, 0x080c, - 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2001, 0x0200, 0xb86e, - 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006, 0x0068, - 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, - 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, - 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, - 0x90c6, 0x0015, 0x0904, 0x65f3, 0x90c6, 0x0056, 0x0904, 0x65f7, - 0x90c6, 0x0066, 0x0904, 0x65fb, 0x90c6, 0x0067, 0x0904, 0x65ff, - 0x90c6, 0x0068, 0x0904, 0x6603, 0x90c6, 0x0071, 0x0904, 0x6607, - 0x90c6, 0x0074, 0x0904, 0x660b, 0x90c6, 0x007c, 0x0904, 0x660f, - 0x90c6, 0x007e, 0x0904, 0x6613, 0x90c6, 0x0037, 0x0904, 0x6617, - 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x65ee, - 0x9182, 0x0800, 0x1a04, 0x65ee, 0x080c, 0x6789, 0x1198, 0xb804, - 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, - 0x0148, 0x080c, 0xae60, 0x1904, 0x65d7, 0xb8a0, 0x9084, 0xff80, - 0x1904, 0x65d7, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, - 0x0904, 0x6537, 0x90c6, 0x0064, 0x0904, 0x6560, 0x2008, 0x0804, - 0x64f9, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182, - 0x007f, 0x0a04, 0x64f9, 0x9186, 0x00ff, 0x0904, 0x64f9, 0x9182, - 0x0800, 0x1a04, 0x64f9, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, - 0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, - 0x64f9, 0x080c, 0xae60, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, - 0x2208, 0x2310, 0x0804, 0x64f9, 0x009e, 0x080c, 0x4ae1, 0x0904, - 0x6503, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, - 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, - 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, - 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, 0x20a9, - 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, - 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0xa8c4, - 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, - 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, - 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, - 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, - 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, - 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, - 0x900e, 0x0478, 0x000e, 0x080c, 0xaed8, 0x1130, 0x2001, 0x4005, - 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd0b1, - 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, - 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x3310, 0x012e, 0x9006, - 0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002, - 0x080c, 0xafcc, 0xa8b0, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, - 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, - 0x583a, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, - 0x6789, 0x1904, 0x64f4, 0x9186, 0x007f, 0x0130, 0x080c, 0x6bd5, - 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1059, 0x1120, - 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, - 0xce04, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb, - 0xa998, 0xaeb0, 0x080c, 0x6789, 0x1904, 0x64f4, 0x0096, 0x080c, - 0x1059, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x65b4, 0x2900, - 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, - 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, - 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, - 0x0006, 0x2398, 0x080c, 0x0fd6, 0x009e, 0xa87b, 0x0000, 0xa883, - 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x5826, 0xd0b4, - 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, - 0x000c, 0x00b0, 0x080c, 0x6bd5, 0x0118, 0xa89b, 0x0009, 0x0080, - 0x080c, 0x583a, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xcde7, - 0x1904, 0x6530, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb, - 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, - 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, - 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8, - 0x080c, 0xb456, 0x1904, 0x6530, 0x2009, 0x0002, 0x08e8, 0x2001, - 0x0028, 0x900e, 0x0804, 0x6531, 0x2009, 0x180c, 0x210c, 0xd18c, - 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, - 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x6531, 0x2001, 0x0029, - 0x900e, 0x0804, 0x6531, 0x080c, 0x38b9, 0x0804, 0x6532, 0x080c, - 0x5543, 0x0804, 0x6532, 0x080c, 0x4692, 0x0804, 0x6532, 0x080c, - 0x470b, 0x0804, 0x6532, 0x080c, 0x4767, 0x0804, 0x6532, 0x080c, - 0x4ba4, 0x0804, 0x6532, 0x080c, 0x4e58, 0x0804, 0x6532, 0x080c, - 0x51aa, 0x0804, 0x6532, 0x080c, 0x53a3, 0x0804, 0x6532, 0x080c, - 0x3ad7, 0x0804, 0x6532, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, - 0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000, - 0x2104, 0x905d, 0x0130, 0x080c, 0x6bd5, 0x1138, 0x00d9, 0x9006, - 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, - 0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, - 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, - 0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, 0x1904, 0x66af, - 0xb888, 0x9005, 0x1904, 0x66af, 0xb838, 0xb93c, 0x9102, 0x1a04, - 0x66af, 0x2b10, 0x080c, 0xaf05, 0x0904, 0x66ab, 0x8108, 0xb93e, - 0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, - 0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, 0x0000, 0xa87c, - 0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1530, 0xa816, - 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8, 0x9084, 0x00ff, - 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x000f, - 0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004, 0x6046, 0x00f6, - 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0010, 0x2c00, - 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c, 0x17ad, 0x601c, - 0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cbd, 0x2001, 0x8004, - 0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b, 0x0001, 0x2908, - 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020, 0x0096, 0x2048, - 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, - 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, - 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, - 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, - 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6bd1, - 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, - 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, - 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d85, 0x000e, 0x00ce, - 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, - 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, - 0xd0a4, 0x0150, 0x080c, 0x6bcd, 0x1138, 0x9284, 0x00ff, 0x9086, - 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, - 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, - 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, - 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x1059, 0x2958, 0x009e, - 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006, - 0xb8a6, 0xb8ae, 0x080c, 0x6198, 0x9006, 0x0010, 0x9085, 0x0001, - 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, - 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6, - 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4, - 0x904d, 0x0110, 0x080c, 0x108b, 0x00d6, 0x00c6, 0xb8bc, 0x2060, - 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xcc16, - 0x0110, 0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x0c88, 0x00ce, - 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110, - 0x080c, 0x9130, 0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862, - 0x080c, 0x109b, 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be, - 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030, - 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005, - 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800, - 0xc08c, 0xb802, 0x080c, 0x76a5, 0x1510, 0xb8a0, 0x9086, 0x007e, - 0x0120, 0x080c, 0xae60, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8, - 0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050, - 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005, - 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040, - 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099, - 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9, - 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9, - 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a, - 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200, - 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e, - 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259, - 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009, - 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, - 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581, - 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e, - 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, - 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036, - 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120, - 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, - 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008, - 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005, - 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900, - 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146, - 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, - 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9, - 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c, - 0x0d85, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, - 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x1059, - 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, 0x6a18, 0xa807, - 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, - 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, - 0xa800, 0x9005, 0x1150, 0x080c, 0x6a27, 0x1158, 0xa804, 0x908a, - 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, 0x108b, 0xb8a7, - 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6, 0xb888, 0x9005, - 0x1904, 0x690d, 0xb8d0, 0x904d, 0x0904, 0x690d, 0x080c, 0xaf05, - 0x0904, 0x6909, 0x8210, 0xba3e, 0xa800, 0xb8d2, 0x9005, 0x1108, - 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, - 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x9084, 0x00ff, - 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8, 0xc0dd, 0xa87e, - 0xa888, 0x8001, 0x1568, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296, - 0x0011, 0x1530, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0, - 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004, 0x0030, 0x080c, - 0x1cbd, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046, 0x2001, 0x0010, - 0x2c08, 0x080c, 0xaad1, 0xb838, 0xba3c, 0x9202, 0x0a04, 0x68ba, - 0x0020, 0x82ff, 0x1110, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005, - 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x08e0, 0x00b6, 0x0096, - 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6789, 0x1158, + 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, + 0x2041, 0x129c, 0x080c, 0xb473, 0x1904, 0x652a, 0x2009, 0x0002, + 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x652b, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x652b, + 0x2001, 0x0029, 0x900e, 0x0804, 0x652b, 0x080c, 0x38a4, 0x0804, + 0x652c, 0x080c, 0x553d, 0x0804, 0x652c, 0x080c, 0x468c, 0x0804, + 0x652c, 0x080c, 0x4705, 0x0804, 0x652c, 0x080c, 0x4761, 0x0804, + 0x652c, 0x080c, 0x4b9e, 0x0804, 0x652c, 0x080c, 0x4e52, 0x0804, + 0x652c, 0x080c, 0x51a4, 0x0804, 0x652c, 0x080c, 0x539d, 0x0804, + 0x652c, 0x080c, 0x3ac2, 0x0804, 0x652c, 0x00b6, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, + 0x9188, 0x1000, 0x2104, 0x905d, 0x0130, 0x080c, 0x6bcd, 0x1138, + 0x00d9, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, + 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, + 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, + 0x900e, 0x9005, 0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, + 0x1904, 0x66a9, 0xb888, 0x9005, 0x1904, 0x66a9, 0xb838, 0xb93c, + 0x9102, 0x1a04, 0x66a9, 0x2b10, 0x080c, 0xaf25, 0x0904, 0x66a5, + 0x8108, 0xb93e, 0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, + 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, + 0x0000, 0xa87c, 0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001, + 0x1530, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8, + 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, + 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004, + 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, + 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c, + 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cb9, + 0x2001, 0x8004, 0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b, + 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020, + 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6, + 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, + 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, + 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, + 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, + 0x080c, 0x6bc9, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, + 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, + 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d79, + 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, + 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, + 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6bc5, 0x1138, 0x9284, + 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, + 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, + 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, + 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x104d, + 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860, + 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6192, 0x9006, 0x0010, + 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, + 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, + 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013, + 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0x00d6, 0x00c6, + 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, + 0x080c, 0xcc33, 0x0110, 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce, + 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c, + 0xd2c4, 0x0110, 0x080c, 0x9128, 0x00ce, 0x2b48, 0xb8c8, 0xb85e, + 0xb8c4, 0xb862, 0x080c, 0x108f, 0x00de, 0x9006, 0x002e, 0x012e, + 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, + 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, + 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x769d, 0x1510, 0xb8a0, + 0x9086, 0x007e, 0x0120, 0x080c, 0xae80, 0x11d8, 0x0078, 0x7040, + 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c, + 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, + 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, + 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, + 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, + 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, + 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, + 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, + 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, + 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, + 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, + 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, + 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, + 0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, + 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, + 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, + 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, + 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, + 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, + 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, + 0x1dd0, 0x080c, 0x0d79, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, + 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, + 0x080c, 0x104d, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, + 0x6a10, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, + 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6a1f, 0x1158, + 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, + 0x107f, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6, + 0xb888, 0x9005, 0x1904, 0x6905, 0xb8d0, 0x904d, 0x0904, 0x6905, + 0x080c, 0xaf25, 0x0904, 0x6903, 0x8210, 0xba3e, 0xa800, 0xb8d2, + 0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, + 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, + 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8, + 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1558, 0xa816, 0xa864, 0x9094, + 0x00f7, 0x9296, 0x0011, 0x1520, 0x9084, 0x00ff, 0xc0bd, 0x601e, + 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004, + 0x0030, 0x080c, 0x1cb9, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046, + 0x2001, 0x0010, 0x2c08, 0x080c, 0xaae8, 0xb838, 0xba3c, 0x9202, + 0x0a04, 0x68b4, 0x0010, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005, + 0x080c, 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x08f0, 0x00b6, 0x0096, + 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6783, 0x1158, 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, 0x1118, 0xb800, - 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x691c, 0x001e, + 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x6914, 0x001e, 0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, 0x904d, 0x0188, 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, 0xa802, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b, 0x080c, 0x6f19, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38, 0x080c, 0x6f11, 0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, 0xb8d0, 0x904d, 0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0128, 0x2940, 0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, 0x1128, 0xb8d2, @@ -3160,18 +3159,18 @@ unsigned short risc_code01[] = { 0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, 0x0120, 0x605c, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, 0x0006, 0x0066, - 0x2830, 0x080c, 0xa20a, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08, + 0x2830, 0x080c, 0xa21b, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08, 0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, 0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, 0x0026, 0x9906, 0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, 0x0108, 0x0c10, 0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, 0x0005, 0x9016, - 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a7c, 0x0128, - 0x080c, 0xccd7, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a7c, - 0x0128, 0x080c, 0xcc78, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, - 0x6a7c, 0x0128, 0x080c, 0xccd4, 0x0010, 0x9085, 0x0001, 0x0005, - 0x080c, 0x6a7c, 0x0128, 0x080c, 0xcc97, 0x0010, 0x9085, 0x0001, - 0x0005, 0x080c, 0x6a7c, 0x0128, 0x080c, 0xcd1a, 0x0010, 0x9085, + 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a74, 0x0128, + 0x080c, 0xccf4, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a74, + 0x0128, 0x080c, 0xcc95, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x6a74, 0x0128, 0x080c, 0xccf1, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x6a74, 0x0128, 0x080c, 0xccb4, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x6a74, 0x0128, 0x080c, 0xcd37, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, @@ -3185,38 +3184,38 @@ unsigned short risc_code01[] = { 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x1128, 0x080c, 0x1059, 0x0168, 0x2900, 0xb8a6, 0x080c, - 0x6a18, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, + 0x904d, 0x1128, 0x080c, 0x104d, 0x0168, 0x2900, 0xb8a6, 0x080c, + 0x6a10, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, - 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x108b, 0x9085, + 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x107f, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, - 0x00f6, 0x080c, 0x76a5, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, + 0x00f6, 0x080c, 0x769d, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156, - 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789, 0x1168, 0xb804, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6783, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, - 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6aa3, - 0x015e, 0x080c, 0x6b93, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038, + 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6a9b, + 0x015e, 0x080c, 0x6b8b, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, - 0x6ace, 0x080c, 0x88fe, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, - 0x6ace, 0x080c, 0x8834, 0x080c, 0x6b93, 0x01d8, 0x2001, 0x107e, - 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bd1, 0x0130, - 0x2009, 0x07d0, 0x2011, 0x6ace, 0x080c, 0x88fe, 0x00e6, 0x2071, - 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30e1, 0x00ee, + 0x6ac6, 0x080c, 0x88f6, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, + 0x6ac6, 0x080c, 0x882c, 0x080c, 0x6b8b, 0x01d8, 0x2001, 0x107e, + 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bc9, 0x0130, + 0x2009, 0x07d0, 0x2011, 0x6ac6, 0x080c, 0x88f6, 0x00e6, 0x2071, + 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30c8, 0x00ee, 0x04e0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, - 0x6789, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046, - 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe72a, 0xb800, - 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bcd, 0x2001, 0x0707, 0x1128, - 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaae0, - 0x2019, 0x0029, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, - 0x900e, 0x080c, 0xe440, 0x007e, 0x004e, 0x080c, 0xaafc, 0x001e, - 0x8108, 0x1f04, 0x6af6, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, + 0x6783, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046, + 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800, + 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bc5, 0x2001, 0x0707, 0x1128, + 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaaf7, + 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x900e, 0x080c, 0xe465, 0x007e, 0x004e, 0x080c, 0xab13, 0x001e, + 0x8108, 0x1f04, 0x6aee, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, - 0x00c6, 0x0096, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2958, 0x009e, + 0x00c6, 0x0096, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2958, 0x009e, 0x2001, 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, - 0x080c, 0x6198, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, + 0x080c, 0x6192, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, @@ -3227,23 +3226,23 @@ unsigned short risc_code01[] = { 0x001e, 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, - 0x9b06, 0x190c, 0x0d85, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, + 0x9b06, 0x190c, 0x0d79, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, - 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bc3, - 0x080c, 0x88fe, 0x0005, 0x2011, 0x6bc3, 0x080c, 0x8834, 0x2011, - 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5826, 0xd0ac, - 0x0005, 0x080c, 0x5826, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, + 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bbb, + 0x080c, 0x88f6, 0x0005, 0x2011, 0x6bbb, 0x080c, 0x882c, 0x2011, + 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5820, 0xd0ac, + 0x0005, 0x080c, 0x5820, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, - 0x080c, 0xd33e, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, + 0x080c, 0xd35d, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110, 0xb8d4, 0xd094, 0x00fe, 0x00be, 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, - 0x710a, 0x080c, 0x5826, 0xd0fc, 0x1140, 0x080c, 0x5826, 0x900e, + 0x710a, 0x080c, 0x5820, 0xd0fc, 0x1140, 0x080c, 0x5820, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, - 0x9184, 0x0007, 0x0002, 0x6c15, 0x6c15, 0x6c15, 0x6c15, 0x6c15, - 0x6c2b, 0x6c40, 0x6c4e, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, + 0x9184, 0x0007, 0x0002, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d, + 0x6c23, 0x6c38, 0x6c46, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, @@ -3254,66 +3253,66 @@ unsigned short risc_code01[] = { 0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, - 0x080c, 0x7a19, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, + 0x080c, 0x7a11, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, - 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e, - 0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3, - 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d0e, 0x7140, 0xa868, - 0x9102, 0x0a04, 0x6f1e, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, + 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16, + 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, + 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d06, 0x7140, 0xa868, + 0x9102, 0x0a04, 0x6f16, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, - 0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, + 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x0804, - 0x6d96, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, - 0x1904, 0x6f1e, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cd2, - 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e, - 0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3, - 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d7b, 0xa868, 0xd0fc, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x0804, + 0x6d8e, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, + 0x1904, 0x6f16, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cca, + 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16, + 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, + 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d73, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, - 0x6f1e, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f1e, 0x9286, 0x0003, - 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0bc, - 0x1904, 0x6f1e, 0x2200, 0x0002, 0x6f1e, 0x6d77, 0x6db3, 0x6db3, - 0x6f1e, 0x6db3, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, - 0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f1e, 0xa880, 0x9084, - 0x00ff, 0x9086, 0x0001, 0x1904, 0x6f1e, 0x9186, 0x0003, 0x0904, - 0x6db3, 0x9186, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0cc, 0x0904, - 0x6f1e, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, + 0x6f16, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f16, 0x9286, 0x0003, + 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0bc, + 0x1904, 0x6f16, 0x2200, 0x0002, 0x6f16, 0x6d6f, 0x6dab, 0x6dab, + 0x6f16, 0x6dab, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, + 0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f16, 0xa880, 0x9084, + 0x00ff, 0x9086, 0x0001, 0x1904, 0x6f16, 0x9186, 0x0003, 0x0904, + 0x6dab, 0x9186, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0cc, 0x0904, + 0x6f16, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, - 0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, + 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1800, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, - 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x002e, 0x00ee, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, - 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6ea4, - 0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004, 0x8004, - 0x9084, 0x0003, 0x0002, 0x6dd1, 0x6ea4, 0x6df5, 0x6e41, 0x080c, - 0x0d85, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, + 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6e9c, + 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004, 0x8004, + 0x9084, 0x0003, 0x0002, 0x6dc9, 0x6e9c, 0x6ded, 0x6e39, 0x080c, + 0x0d79, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, - 0x9200, 0x70c2, 0x080c, 0x873a, 0x0c18, 0x2071, 0x1800, 0x2900, + 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, - 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7289, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, + 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0804, - 0x6dfc, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, - 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, - 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60, 0x00ee, - 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x1198, 0x009e, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0804, + 0x6df4, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, 0x00ee, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x1198, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, @@ -3321,87 +3320,87 @@ unsigned short risc_code01[] = { 0x900d, 0x1168, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, - 0xa804, 0x900d, 0x1904, 0x6ef8, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7289, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, + 0xa804, 0x900d, 0x1904, 0x6ef0, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d68, 0x782c, 0x9094, - 0x0780, 0x190c, 0x7289, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d68, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, - 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, + 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, - 0x080c, 0x873a, 0x00ee, 0x0804, 0x6eb4, 0xa868, 0xd0fc, 0x15e0, - 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x100b, 0x009e, + 0x080c, 0x8732, 0x00ee, 0x0804, 0x6eac, 0xa868, 0xd0fc, 0x15e0, + 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fff, 0x009e, 0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, - 0x7049, 0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004, - 0x8004, 0x9084, 0x0003, 0x0002, 0x6f4d, 0x7049, 0x6f68, 0x6fda, - 0x080c, 0x0d85, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f2d, 0x6f2d, - 0x6f2d, 0x6dbc, 0x6f2d, 0x6dbc, 0x0005, 0x2071, 0x1800, 0x2900, + 0x7041, 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004, + 0x8004, 0x9084, 0x0003, 0x0002, 0x6f45, 0x7041, 0x6f60, 0x6fd2, + 0x080c, 0x0d79, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f25, 0x6f25, + 0x6f25, 0x6db4, 0x6f25, 0x6db4, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0c60, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc9, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c60, + 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc1, 0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x19c8, 0x0e04, 0x6fc0, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x19c8, 0x0e04, 0x6fb8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, - 0x0804, 0x6f77, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, + 0x0804, 0x6f6f, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60, - 0x00ee, 0x0e04, 0x701c, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, + 0x00ee, 0x0e04, 0x7014, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, + 0x11f4, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, - 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x00fe, 0x002e, 0x00ee, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, - 0x70b8, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x11b0, + 0x70b0, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d50, 0x782c, 0x9094, - 0x0780, 0x190c, 0x7289, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d50, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, - 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, - 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70b1, 0x7838, 0x7938, 0x910e, + 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, + 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70a9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x1200, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0xd084, 0x190c, 0x11f4, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, - 0x080c, 0x873a, 0x00ee, 0x0804, 0x7059, 0x2071, 0x1910, 0xa803, + 0x080c, 0x8732, 0x00ee, 0x0804, 0x7051, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, - 0x1e04, 0x70f8, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x1e04, 0x70f0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0e04, 0x70e2, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0e04, 0x70da, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1910, 0x080c, - 0x7275, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1910, 0x080c, + 0x726d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, @@ -3410,23 +3409,23 @@ unsigned short risc_code01[] = { 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, - 0x080c, 0x873a, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, + 0x080c, 0x8732, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, - 0x7188, 0x7189, 0x7274, 0x7189, 0x7186, 0x7274, 0x080c, 0x0d85, - 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7193, 0x7193, 0x720d, - 0x720e, 0x7193, 0x720e, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7294, - 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71de, 0x0e04, - 0x71bc, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, + 0x7180, 0x7181, 0x726c, 0x7181, 0x717e, 0x726c, 0x080c, 0x0d79, + 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x718b, 0x718b, 0x7205, + 0x7206, 0x718b, 0x7206, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x728c, + 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71d6, 0x0e04, + 0x71b4, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, - 0x2071, 0x1910, 0x080c, 0x7275, 0x012e, 0x0804, 0x720c, 0xa850, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, + 0x2071, 0x1910, 0x080c, 0x726d, 0x012e, 0x0804, 0x7204, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, - 0x2004, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x2071, 0x1910, + 0x2004, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x2071, 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, @@ -3435,10 +3434,10 @@ unsigned short risc_code01[] = { 0x2069, 0x1a05, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b74, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, - 0x9106, 0x0190, 0x0e04, 0x7240, 0x2069, 0x0000, 0x6837, 0x8040, + 0x9106, 0x0190, 0x0e04, 0x7238, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, - 0x2004, 0xd084, 0x190c, 0x1200, 0x2069, 0x1a05, 0x6847, 0xffff, - 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7304, 0x701c, + 0x2004, 0xd084, 0x190c, 0x11f4, 0x2069, 0x1a05, 0x6847, 0xffff, + 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x72fc, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, @@ -3446,240 +3445,240 @@ unsigned short risc_code01[] = { 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, - 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x108b, 0x0005, 0x012e, - 0x0005, 0x2091, 0x8000, 0x0e04, 0x728b, 0x0006, 0x0016, 0x2001, - 0x8004, 0x0006, 0x0804, 0x0d8e, 0x0096, 0x00f6, 0x2079, 0x0050, + 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x107f, 0x0005, 0x012e, + 0x0005, 0x2091, 0x8000, 0x0e04, 0x7283, 0x0006, 0x0016, 0x2001, + 0x8004, 0x0006, 0x0804, 0x0d82, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, - 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7289, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00ee, 0x704b, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00fe, - 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x0db8, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00fe, + 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, - 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, - 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, + 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949, 0x6808, 0x690a, 0x2069, 0x1a05, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c, - 0x0d85, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c, - 0x2af5, 0x002e, 0x0005, 0x7449, 0x73b6, 0x73d2, 0x73fc, 0x7438, - 0x7478, 0x748a, 0x73d2, 0x7460, 0x7371, 0x739f, 0x7422, 0x7370, + 0x0d79, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c, + 0x2adc, 0x002e, 0x0005, 0x7441, 0x73ae, 0x73ca, 0x73f4, 0x7430, + 0x7470, 0x7482, 0x73ca, 0x7458, 0x7369, 0x7397, 0x741a, 0x7368, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, - 0x080c, 0x77e3, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, + 0x080c, 0x77db, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c, - 0x1b47, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, + 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, - 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7888, + 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7880, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, - 0x0090, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, - 0x74fb, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, - 0x0020, 0x080c, 0x74fb, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, - 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2abb, 0x6124, 0xd1cc, + 0x0090, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, + 0x74f3, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, + 0x0020, 0x080c, 0x74f3, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, + 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, - 0x080c, 0x1b6c, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, - 0x76d1, 0x2001, 0x0080, 0x080c, 0x2abb, 0x709b, 0x0029, 0x0058, + 0x080c, 0x1b68, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, + 0x76c9, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x709b, 0x0029, 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, - 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b6c, 0x60e3, 0x0001, - 0x600c, 0xc0b4, 0x600e, 0x080c, 0x76d1, 0x2001, 0x0080, 0x080c, - 0x2abb, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, + 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b68, 0x60e3, 0x0001, + 0x600c, 0xc0b4, 0x600e, 0x080c, 0x76c9, 0x2001, 0x0080, 0x080c, + 0x2aa2, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, - 0x2001, 0x00a0, 0x080c, 0x2abb, 0x6124, 0xd1dc, 0x1138, 0xd1e4, - 0x0138, 0x080c, 0x1b6c, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, - 0x0005, 0x080c, 0x7584, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74fb, - 0x0016, 0x080c, 0x1b6c, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, - 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74fb, 0x0005, - 0x0006, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1d4, + 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x6124, 0xd1dc, 0x1138, 0xd1e4, + 0x0138, 0x080c, 0x1b68, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, + 0x0005, 0x080c, 0x757c, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74f3, + 0x0016, 0x080c, 0x1b68, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, + 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74f3, 0x0005, + 0x0006, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, - 0x080c, 0x7584, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x080c, 0x757c, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, - 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2abb, 0x000e, + 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x2091, 0x8000, 0x080c, 0x76a5, 0x11f8, 0x2001, 0x180c, 0x200c, + 0x2091, 0x8000, 0x080c, 0x769d, 0x11f8, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, 0x080c, - 0x2af5, 0x002e, 0x080c, 0x2aa1, 0x6024, 0xd0cc, 0x0148, 0x2001, - 0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x0428, - 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76bf, 0x0150, 0x080c, - 0x76b6, 0x1138, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x7679, - 0x00a0, 0x080c, 0x7581, 0x0178, 0x2001, 0x0001, 0x080c, 0x2647, + 0x2adc, 0x002e, 0x080c, 0x2a88, 0x6024, 0xd0cc, 0x0148, 0x2001, + 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x0428, + 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76b7, 0x0150, 0x080c, + 0x76ae, 0x1138, 0x2001, 0x0001, 0x080c, 0x2646, 0x080c, 0x7671, + 0x00a0, 0x080c, 0x7579, 0x0178, 0x2001, 0x0001, 0x080c, 0x2646, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de, - 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x750c, 0x080c, 0x8940, - 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x750c, 0x080c, - 0x8937, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, - 0xa08a, 0x2071, 0x1800, 0x080c, 0x74a5, 0x001e, 0x00fe, 0x00ee, + 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7504, 0x080c, 0x8938, + 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7504, 0x080c, + 0x892f, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, + 0xa09b, 0x2071, 0x1800, 0x080c, 0x749d, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x0126, 0x2071, 0x1800, 0x080c, 0xa08a, 0x2061, 0x0100, 0x2069, - 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0, - 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, - 0x080c, 0xa300, 0x080c, 0x88ec, 0x0036, 0x901e, 0x080c, 0xa380, - 0x003e, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c, - 0xeb98, 0x2009, 0x0004, 0x080c, 0x2aa7, 0x080c, 0x29bd, 0x2001, - 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2af5, 0x2011, - 0x750c, 0x080c, 0x8940, 0x080c, 0x76bf, 0x0118, 0x9006, 0x080c, - 0x2abb, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2647, 0x012e, + 0x0126, 0x2071, 0x1800, 0x080c, 0xa09b, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x080c, 0xa311, 0x080c, 0x88e4, 0x0036, 0x901e, 0x080c, 0xa391, + 0x003e, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c, + 0xec03, 0x2009, 0x0004, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001, + 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2adc, 0x2011, + 0x7504, 0x080c, 0x8938, 0x080c, 0x76b7, 0x0118, 0x9006, 0x080c, + 0x2aa2, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2646, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, - 0x0026, 0x00e6, 0x2011, 0x7519, 0x2071, 0x1a05, 0x701c, 0x9206, + 0x0026, 0x00e6, 0x2011, 0x7511, 0x2071, 0x1a05, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, - 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2abb, 0x0156, 0x20a9, - 0x002d, 0x1d04, 0x7591, 0x2091, 0x6000, 0x1f04, 0x7591, 0x015e, + 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2aa2, 0x0156, 0x20a9, + 0x002d, 0x1d04, 0x7589, 0x2091, 0x6000, 0x1f04, 0x7589, 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, 0x6800, - 0x9086, 0x0001, 0x1da8, 0x080c, 0x894c, 0x0c90, 0x00c6, 0x00d6, + 0x9086, 0x0001, 0x1da8, 0x080c, 0x8944, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, - 0x79b6, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, - 0x6886, 0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x080c, 0x6039, - 0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b, 0x182c, + 0x79ae, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, + 0x6886, 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x6033, + 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b, 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, - 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7669, 0x709b, 0x0022, + 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7661, 0x709b, 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, - 0x2716, 0x080c, 0xaae0, 0x0026, 0x080c, 0xad9e, 0x080c, 0xae67, - 0x002e, 0x080c, 0xaafc, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, + 0x2715, 0x080c, 0xaaf7, 0x0026, 0x080c, 0xadbe, 0x080c, 0xae87, + 0x002e, 0x080c, 0xab13, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, - 0xd33e, 0x0118, 0x9006, 0x080c, 0x2ae5, 0x0804, 0x7675, 0x6800, - 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2aa1, 0x6904, 0xd1d4, - 0x1140, 0x2001, 0x0100, 0x080c, 0x2abb, 0x1f04, 0x761a, 0x080c, - 0x76f9, 0x012e, 0x015e, 0x080c, 0x76b6, 0x0170, 0x6044, 0x9005, - 0x0130, 0x080c, 0x76f9, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804, - 0xd0d4, 0x1110, 0x080c, 0x76f9, 0x080c, 0xd33e, 0x0118, 0x9006, - 0x080c, 0x2ae5, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, - 0x2009, 0x00c8, 0x2011, 0x7519, 0x080c, 0x88fe, 0x002e, 0x001e, - 0x080c, 0x8731, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003, - 0x0004, 0x080c, 0x7354, 0x080c, 0x76b6, 0x0138, 0x6804, 0xd0d4, - 0x1120, 0xd0dc, 0x1100, 0x080c, 0x79ac, 0x00ee, 0x00de, 0x00ce, + 0xd35d, 0x0118, 0x9006, 0x080c, 0x2acc, 0x0804, 0x766d, 0x6800, + 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a88, 0x6904, 0xd1d4, + 0x1140, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x1f04, 0x7612, 0x080c, + 0x76f1, 0x012e, 0x015e, 0x080c, 0x76ae, 0x0170, 0x6044, 0x9005, + 0x0130, 0x080c, 0x76f1, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804, + 0xd0d4, 0x1110, 0x080c, 0x76f1, 0x080c, 0xd35d, 0x0118, 0x9006, + 0x080c, 0x2acc, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, + 0x2009, 0x00c8, 0x2011, 0x7511, 0x080c, 0x88f6, 0x002e, 0x001e, + 0x080c, 0x8729, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003, + 0x0004, 0x080c, 0x734c, 0x080c, 0x76ae, 0x0138, 0x6804, 0xd0d4, + 0x1120, 0xd0dc, 0x1100, 0x080c, 0x79a4, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, - 0x2071, 0x1800, 0x080c, 0x8748, 0x080c, 0x873a, 0x080c, 0x79b6, + 0x2071, 0x1800, 0x080c, 0x8740, 0x080c, 0x8732, 0x080c, 0x79ae, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, - 0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x6043, 0x0090, 0x6043, - 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b, + 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x6043, 0x0090, 0x6043, + 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b, 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d, - 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a, + 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, - 0x582a, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, - 0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, - 0x0006, 0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, + 0x5824, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, + 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, + 0x0006, 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, - 0x0168, 0x0020, 0x080c, 0x2736, 0x900e, 0x0010, 0x2009, 0x0002, - 0x2019, 0x0028, 0x080c, 0x32d5, 0x9006, 0x0019, 0x001e, 0x003e, - 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd337, + 0x0168, 0x0020, 0x080c, 0x2735, 0x900e, 0x0010, 0x2009, 0x0002, + 0x2019, 0x0028, 0x080c, 0x32c0, 0x9006, 0x0019, 0x001e, 0x003e, + 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd356, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, - 0x0006, 0x6028, 0x0006, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x602f, + 0x0006, 0x6028, 0x0006, 0x080c, 0x2aff, 0x080c, 0x2b32, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x20a9, - 0x0002, 0x080c, 0x2a82, 0x0026, 0x2011, 0x0040, 0x080c, 0x2af5, + 0x0002, 0x080c, 0x2a69, 0x0026, 0x2011, 0x0040, 0x080c, 0x2adc, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, - 0x2716, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd33e, 0x000e, 0x0130, - 0x080c, 0x2ad9, 0x9006, 0x080c, 0x2ae5, 0x0010, 0x080c, 0x2abb, + 0x2715, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd35d, 0x000e, 0x0130, + 0x080c, 0x2ac0, 0x9006, 0x080c, 0x2acc, 0x0010, 0x080c, 0x2aa2, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, - 0x0100, 0x080c, 0x2a2e, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, + 0x0100, 0x080c, 0x2a19, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab3e, 0x0158, 0x2001, - 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaad1, - 0x0804, 0x77d5, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, - 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2001, - 0x0090, 0x080c, 0x2abb, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558, - 0x1d04, 0x7775, 0x2091, 0x6000, 0x1f04, 0x7775, 0x080c, 0xaae0, - 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, - 0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x2001, 0x0386, 0x2003, - 0x7000, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c, - 0x79a7, 0x080c, 0x617e, 0x080c, 0xd33e, 0x0110, 0x080c, 0x0cf1, - 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b6c, 0x60e3, 0x0000, 0x2001, - 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x0080, 0x080c, - 0x2abb, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009, - 0x1e00, 0x080c, 0x2aa1, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77b3, - 0x2091, 0x6000, 0x1f04, 0x77b3, 0x0804, 0x777e, 0x2001, 0x0386, + 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab55, 0x0158, 0x2001, + 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaae8, + 0x0804, 0x77cd, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, + 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2001, + 0x0090, 0x080c, 0x2aa2, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558, + 0x1d04, 0x776d, 0x2091, 0x6000, 0x1f04, 0x776d, 0x080c, 0xaaf7, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x2001, 0x0386, 0x2003, + 0x7000, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c, + 0x799f, 0x080c, 0x6178, 0x080c, 0xd35d, 0x0110, 0x080c, 0x0ce5, + 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b68, 0x60e3, 0x0000, 0x2001, + 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x0080, 0x080c, + 0x2aa2, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009, + 0x1e00, 0x080c, 0x2a88, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77ab, + 0x2091, 0x6000, 0x1f04, 0x77ab, 0x0804, 0x7776, 0x2001, 0x0386, 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005, - 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd33e, 0x0110, - 0x080c, 0x0cf1, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd35d, 0x0110, + 0x080c, 0x0ce5, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, - 0x784c, 0x2001, 0x0088, 0x080c, 0x2abb, 0x9006, 0x60e2, 0x6886, - 0x080c, 0x2716, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, + 0x7844, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x9006, 0x60e2, 0x6886, + 0x080c, 0x2715, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, 0x0400, - 0x080c, 0x2af5, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026, - 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x782c, 0x2091, 0x6000, - 0x1f04, 0x782c, 0x0804, 0x7880, 0x2069, 0x0140, 0x20a9, 0x0384, - 0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1, - 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7838, - 0x2091, 0x6000, 0x1f04, 0x7838, 0x080c, 0xaae0, 0x2011, 0x0003, - 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c, 0xa300, - 0x901e, 0x080c, 0xa380, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c, - 0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x9085, 0x0001, 0x00c0, - 0x080c, 0x1b6c, 0x2001, 0x0080, 0x080c, 0x2abb, 0x2069, 0x0140, + 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7824, 0x2091, 0x6000, + 0x1f04, 0x7824, 0x0804, 0x7878, 0x2069, 0x0140, 0x20a9, 0x0384, + 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88, + 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7830, + 0x2091, 0x6000, 0x1f04, 0x7830, 0x080c, 0xaaf7, 0x2011, 0x0003, + 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c, 0xa311, + 0x901e, 0x080c, 0xa391, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c, + 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x00c0, + 0x080c, 0x1b68, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, - 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x9006, + 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8, 0x080c, - 0xaae0, 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, - 0xa419, 0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x080c, 0xaafc, - 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7, - 0x080c, 0x617e, 0x0804, 0x7923, 0x2001, 0x180c, 0x200c, 0xd1b4, - 0x1160, 0xc1b5, 0x2102, 0x080c, 0x7501, 0x2069, 0x0140, 0x2001, - 0x0080, 0x080c, 0x2abb, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, + 0xaaf7, 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, + 0xa430, 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x080c, 0xab13, + 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f, + 0x080c, 0x6178, 0x0804, 0x791b, 0x2001, 0x180c, 0x200c, 0xd1b4, + 0x1160, 0xc1b5, 0x2102, 0x080c, 0x74f9, 0x2069, 0x0140, 0x2001, + 0x0080, 0x080c, 0x2aa2, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff, - 0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2069, 0x1990, 0x7000, - 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x7923, 0x2011, - 0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1, 0x6024, - 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78df, 0x0006, - 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8788, 0x00ee, 0x00de, + 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000, + 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x791b, 0x2011, + 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88, 0x6024, + 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78d7, 0x0006, + 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8780, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a05, 0x7078, 0x00ee, - 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7519, 0x080c, 0x8834, - 0x2011, 0x750c, 0x080c, 0x8940, 0x002e, 0x2069, 0x0140, 0x60e3, + 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7511, 0x080c, 0x882c, + 0x2011, 0x7504, 0x080c, 0x8938, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, - 0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x180c, + 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, - 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd337, - 0x1904, 0x7991, 0x7130, 0xd184, 0x1170, 0x080c, 0x347d, 0x0138, + 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd356, + 0x1904, 0x7989, 0x7130, 0xd184, 0x1170, 0x080c, 0x3468, 0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, - 0xd08c, 0x0904, 0x7991, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, - 0x0016, 0x2019, 0x000e, 0x080c, 0xe696, 0x0156, 0x00b6, 0x20a9, + 0xd08c, 0x0904, 0x7989, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, + 0x0016, 0x2019, 0x000e, 0x080c, 0xe701, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, - 0x080c, 0x6789, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, - 0x080c, 0xe72a, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5, - 0x001e, 0x8108, 0x1f04, 0x795a, 0x00be, 0x015e, 0x001e, 0xd1ac, - 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32d5, + 0x080c, 0x6783, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, + 0x080c, 0xe795, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8add, + 0x001e, 0x8108, 0x1f04, 0x7952, 0x00be, 0x015e, 0x001e, 0xd1ac, + 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32c0, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, - 0x6789, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04, 0x7987, 0x00be, - 0x015e, 0x080c, 0x1b6c, 0x080c, 0xaae0, 0x080c, 0xae67, 0x080c, - 0xaafc, 0x60e3, 0x0000, 0x080c, 0x617e, 0x080c, 0x75d4, 0x00ee, + 0x6783, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x797f, 0x00be, + 0x015e, 0x080c, 0x1b68, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, + 0xab13, 0x60e3, 0x0000, 0x080c, 0x6178, 0x080c, 0x75cc, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000, 0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, - 0x0000, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, - 0x704e, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, + 0x0000, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900, + 0x704e, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, @@ -3688,78 +3687,78 @@ unsigned short risc_code01[] = { 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, - 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7fa4, 0x9006, 0x00ee, + 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7f9c, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04, - 0x7a1d, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, - 0x0002, 0x7a33, 0x7a34, 0x7a80, 0x7adb, 0x7beb, 0x7a31, 0x7a31, - 0x7c15, 0x080c, 0x0d85, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0, - 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x8086, 0xd0a4, + 0x7a15, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, + 0x0002, 0x7a2b, 0x7a2c, 0x7a78, 0x7ad3, 0x7be3, 0x7a29, 0x7a29, + 0x7c0d, 0x080c, 0x0d79, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0, + 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x807e, 0xd0a4, 0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04, - 0x7a51, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000, + 0x7a49, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000, 0x2102, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, - 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a70, 0x7a3a, 0x7a70, - 0x7a6e, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x080c, 0x7adb, - 0x782c, 0xd09c, 0x090c, 0x7fa4, 0x0005, 0x9082, 0x005a, 0x1218, - 0x2100, 0x003b, 0x0c10, 0x080c, 0x7b11, 0x0c90, 0x00e3, 0x08e8, - 0x0005, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b33, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7d0b, - 0x7b11, 0x7b11, 0x7b11, 0x7b33, 0x7b11, 0x7b1d, 0x7d4c, 0x7d8d, - 0x7dd4, 0x7de8, 0x7b11, 0x7b11, 0x7b33, 0x7b1d, 0x7b47, 0x7b11, - 0x7bbf, 0x7e93, 0x7eae, 0x7b11, 0x7b33, 0x7b11, 0x7b47, 0x7b11, - 0x7b11, 0x7bb5, 0x7eae, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b5b, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x802a, 0x7b11, - 0x7fd4, 0x7b11, 0x7fd4, 0x7b11, 0x7b70, 0x7b11, 0x7b11, 0x7b11, - 0x7b11, 0x7b11, 0x7b11, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, - 0x1198, 0x782c, 0x080c, 0x7fcd, 0xd0a4, 0x0170, 0x7824, 0x2048, + 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a68, 0x7a32, 0x7a68, + 0x7a66, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x080c, 0x7ad3, + 0x782c, 0xd09c, 0x090c, 0x7f9c, 0x0005, 0x9082, 0x005a, 0x1218, + 0x2100, 0x003b, 0x0c10, 0x080c, 0x7b09, 0x0c90, 0x00e3, 0x08e8, + 0x0005, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b2b, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7d03, + 0x7b09, 0x7b09, 0x7b09, 0x7b2b, 0x7b09, 0x7b15, 0x7d44, 0x7d85, + 0x7dcc, 0x7de0, 0x7b09, 0x7b09, 0x7b2b, 0x7b15, 0x7b3f, 0x7b09, + 0x7bb7, 0x7e8b, 0x7ea6, 0x7b09, 0x7b2b, 0x7b09, 0x7b3f, 0x7b09, + 0x7b09, 0x7bad, 0x7ea6, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b53, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x8022, 0x7b09, + 0x7fcc, 0x7b09, 0x7fcc, 0x7b09, 0x7b68, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, + 0x1198, 0x782c, 0x080c, 0x7fc5, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, - 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7fa4, 0x0005, 0x7b11, - 0x7b1d, 0x7cf7, 0x7b11, 0x7b1d, 0x7b11, 0x7b1d, 0x7b1d, 0x7b11, - 0x7b1d, 0x7cf7, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b11, - 0x7b1d, 0x7cf7, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7b11, 0x7b11, - 0x7b1d, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, + 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7f9c, 0x0005, 0x7b09, + 0x7b15, 0x7cef, 0x7b09, 0x7b15, 0x7b09, 0x7b15, 0x7b15, 0x7b09, + 0x7b15, 0x7cef, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b09, + 0x7b15, 0x7cef, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7b09, 0x7b09, + 0x7b15, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6f19, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, - 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c94, 0x7007, 0x0003, - 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c94, 0x0005, 0xa864, + 0x6f11, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c8c, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c8c, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, - 0x0804, 0x7caf, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, - 0x704b, 0x7caf, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, - 0x7b19, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ccb, 0x7007, - 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7ccb, 0x0005, - 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b19, + 0x0804, 0x7ca7, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, + 0x704b, 0x7ca7, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, + 0x7b11, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7cc3, 0x7007, + 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7cc3, 0x0005, + 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b11, 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, - 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6411, 0x1108, + 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x640b, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, - 0x080c, 0x6f19, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, + 0x080c, 0x6f11, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0, - 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ec5, 0x2900, + 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ebd, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, - 0x7b21, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b21, 0x82ff, 0x1138, - 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c52, 0x0018, 0x9280, - 0x7c48, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c33, 0x080c, - 0x1072, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, + 0x7b19, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b19, 0x82ff, 0x1138, + 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c4a, 0x0018, 0x9280, + 0x7c40, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c2b, 0x080c, + 0x1066, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, - 0xa17a, 0x810b, 0xa17e, 0x080c, 0x114e, 0xa06c, 0x908e, 0x0100, + 0xa17a, 0x810b, 0xa17e, 0x080c, 0x1142, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, - 0x2048, 0x080c, 0x108b, 0x7014, 0x2048, 0x0804, 0x7b21, 0x7020, + 0x2048, 0x080c, 0x107f, 0x7014, 0x2048, 0x0804, 0x7b19, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, - 0x711a, 0x0804, 0x7beb, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, + 0x711a, 0x0804, 0x7be3, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, - 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ec5, 0x0804, 0x7c94, - 0x7c4a, 0x7c4e, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, + 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ebd, 0x0804, 0x7c8c, + 0x7c42, 0x7c46, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, @@ -3769,16 +3768,16 @@ unsigned short risc_code01[] = { 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, - 0x1178, 0x080c, 0x6210, 0x1108, 0x0005, 0x080c, 0x7165, 0x0126, - 0x2091, 0x8000, 0x080c, 0xcf1b, 0x080c, 0x6f19, 0x012e, 0x0ca0, - 0x080c, 0xd337, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, + 0x1178, 0x080c, 0x620a, 0x1108, 0x0005, 0x080c, 0x715d, 0x0126, + 0x2091, 0x8000, 0x080c, 0xcf38, 0x080c, 0x6f11, 0x012e, 0x0ca0, + 0x080c, 0xd356, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, - 0x0000, 0x080c, 0x629e, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6f19, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, + 0x0000, 0x080c, 0x6298, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6f11, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, - 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6373, 0x1138, - 0x0005, 0x9006, 0xa87a, 0x080c, 0x62eb, 0x1108, 0x0005, 0x0126, - 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f19, 0x012e, 0x0cb0, + 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x636d, 0x1138, + 0x0005, 0x9006, 0xa87a, 0x080c, 0x62e5, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f11, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, @@ -3786,222 +3785,222 @@ unsigned short risc_code01[] = { 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, - 0x9005, 0x11d8, 0xa974, 0x080c, 0x6789, 0x11b8, 0x0066, 0xae80, - 0x080c, 0x6899, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, - 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6789, 0x1110, 0x080c, - 0x6a6c, 0x8108, 0x1f04, 0x7d34, 0x00ce, 0xa87c, 0xd084, 0x1120, - 0x080c, 0x108b, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6f19, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, - 0x0001, 0x080c, 0x6bd1, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184, + 0x9005, 0x11d8, 0xa974, 0x080c, 0x6783, 0x11b8, 0x0066, 0xae80, + 0x080c, 0x6893, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, + 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6783, 0x1110, 0x080c, + 0x6a64, 0x8108, 0x1f04, 0x7d2c, 0x00ce, 0xa87c, 0xd084, 0x1120, + 0x080c, 0x107f, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6f11, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x6bc9, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, - 0x6202, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804, 0x7f88, 0x012e, - 0x0804, 0x7f82, 0x012e, 0x0804, 0x7f85, 0x0126, 0x2091, 0x8000, - 0x7007, 0x0001, 0x080c, 0x6bd1, 0x05e0, 0x2061, 0x1a74, 0x6000, + 0x6202, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804, 0x7f80, 0x012e, + 0x0804, 0x7f7a, 0x012e, 0x0804, 0x7f7d, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x080c, 0x6bc9, 0x05e0, 0x2061, 0x1a74, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, - 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804, - 0x7f8b, 0x012e, 0x0804, 0x7f88, 0x0126, 0x2091, 0x8000, 0x7007, + 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804, + 0x7f83, 0x012e, 0x0804, 0x7f80, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, - 0x0220, 0x630a, 0x012e, 0x0804, 0x7f9c, 0x012e, 0x0804, 0x7f8b, + 0x0220, 0x630a, 0x012e, 0x0804, 0x7f94, 0x012e, 0x0804, 0x7f83, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, - 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf69, + 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf89, 0x0068, 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110, - 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafcc, 0xa988, 0x918c, + 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafec, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, - 0x080c, 0x8ae5, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74, + 0x080c, 0x8add, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, - 0x012e, 0x00be, 0x0804, 0x7f8e, 0x00ce, 0x012e, 0x00be, 0x0804, - 0x7f88, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, + 0x012e, 0x00be, 0x0804, 0x7f86, 0x00ce, 0x012e, 0x00be, 0x0804, + 0x7f80, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, - 0x0029, 0x1d10, 0xa974, 0x080c, 0x6789, 0x1968, 0xb800, 0xc0e4, + 0x0029, 0x1d10, 0xa974, 0x080c, 0x6783, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, - 0x1987, 0x2004, 0x601a, 0x0804, 0x7e23, 0xa88c, 0x9065, 0x0960, + 0x1987, 0x2004, 0x601a, 0x0804, 0x7e1b, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, - 0x080c, 0xaf69, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf69, 0x00ee, - 0x0804, 0x7e23, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, + 0x080c, 0xaf89, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf89, 0x00ee, + 0x0804, 0x7e1b, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, - 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, - 0x00ee, 0x0804, 0x7e23, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190, - 0xd08c, 0x1904, 0x7f9c, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, - 0x0220, 0x6206, 0x012e, 0x0804, 0x7f9c, 0x012e, 0xa883, 0x0016, - 0x0804, 0x7f95, 0xa883, 0x0007, 0x0804, 0x7f95, 0xa864, 0x8007, + 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, + 0x00ee, 0x0804, 0x7e1b, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190, + 0xd08c, 0x1904, 0x7f94, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0220, 0x6206, 0x012e, 0x0804, 0x7f94, 0x012e, 0xa883, 0x0016, + 0x0804, 0x7f8d, 0xa883, 0x0007, 0x0804, 0x7f8d, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, - 0x0005, 0x080c, 0x7b19, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, - 0x7016, 0x701a, 0x704b, 0x7ec5, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x0005, 0x080c, 0x7b11, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, + 0x7016, 0x701a, 0x704b, 0x7ebd, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, - 0x7f47, 0x6130, 0xd194, 0x1904, 0x7f71, 0xa878, 0x2070, 0x9e82, - 0x1ddc, 0x0a04, 0x7f3b, 0x6068, 0x9e02, 0x1a04, 0x7f3b, 0x7120, - 0x9186, 0x0006, 0x1904, 0x7f2d, 0x7010, 0x905d, 0x0904, 0x7f47, - 0xb800, 0xd0e4, 0x1904, 0x7f6b, 0x2061, 0x1a74, 0x6100, 0x9184, - 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f74, + 0x7f3f, 0x6130, 0xd194, 0x1904, 0x7f69, 0xa878, 0x2070, 0x9e82, + 0x1ddc, 0x0a04, 0x7f33, 0x6068, 0x9e02, 0x1a04, 0x7f33, 0x7120, + 0x9186, 0x0006, 0x1904, 0x7f25, 0x7010, 0x905d, 0x0904, 0x7f3f, + 0xb800, 0xd0e4, 0x1904, 0x7f63, 0x2061, 0x1a74, 0x6100, 0x9184, + 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f6c, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, - 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x080c, 0x5826, 0xd09c, - 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89d5, 0x012e, + 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x080c, 0x5820, 0xd09c, + 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89cd, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, - 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x012e, 0x00ee, 0x00be, - 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f95, - 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6789, + 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f8d, + 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6783, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, - 0x582a, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0, + 0x5824, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0, 0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, - 0x9086, 0x0007, 0x1904, 0x7ed1, 0x7003, 0x0002, 0x0804, 0x7ed1, + 0x9086, 0x0007, 0x1904, 0x7ec9, 0x7003, 0x0002, 0x0804, 0x7ec9, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, - 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe27a, 0x012e, 0x00ee, + 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe28e, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6f19, 0x012e, 0x0005, 0x080c, 0x108b, 0x0005, 0x00d6, - 0x080c, 0x89cc, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, + 0x080c, 0x6f11, 0x012e, 0x0005, 0x080c, 0x107f, 0x0005, 0x00d6, + 0x080c, 0x89c4, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, - 0x190c, 0x8086, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, + 0x190c, 0x807e, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, - 0x190c, 0x8086, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, - 0x080c, 0xaed8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, + 0x190c, 0x807e, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, + 0x080c, 0xaef8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196c, 0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, - 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a2, 0x1540, 0x00b6, - 0x080c, 0x6789, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, + 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a1, 0x1540, 0x00b6, + 0x080c, 0x6783, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, - 0x2009, 0x0041, 0x080c, 0xafcc, 0x0005, 0xa87b, 0x0101, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b, 0x002c, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b, - 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x080c, - 0xaf2e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, - 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x8077, 0xa97c, + 0x2009, 0x0041, 0x080c, 0xafec, 0x0005, 0xa87b, 0x0101, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b, 0x002c, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b, + 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, + 0xaf4e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, + 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x806f, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, - 0x080c, 0xaed8, 0x1118, 0x080c, 0xaf9f, 0x05a8, 0x6212, 0xa874, - 0x0002, 0x8055, 0x805a, 0x805d, 0x8063, 0x2019, 0x0002, 0x080c, - 0xe696, 0x0060, 0x080c, 0xe621, 0x0048, 0x2019, 0x0002, 0xa980, - 0x080c, 0xe640, 0x0018, 0xa980, 0x080c, 0xe621, 0x080c, 0xaf2e, - 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, + 0x080c, 0xaef8, 0x1118, 0x080c, 0xafbf, 0x05a8, 0x6212, 0xa874, + 0x0002, 0x804d, 0x8052, 0x8055, 0x805b, 0x2019, 0x0002, 0x080c, + 0xe701, 0x0060, 0x080c, 0xe68c, 0x0048, 0x2019, 0x0002, 0xa980, + 0x080c, 0xe6ab, 0x0018, 0xa980, 0x080c, 0xe68c, 0x080c, 0xaf4e, + 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, - 0x0e04, 0x8088, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, - 0x0d8e, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, + 0x0e04, 0x8080, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, + 0x0d82, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, - 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x1648, 0x00fe, + 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x163c, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, - 0x0005, 0x781c, 0xd08c, 0x0904, 0x8109, 0x68c0, 0x90aa, 0x0005, - 0x0a04, 0x8731, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d85, 0x9584, + 0x0005, 0x781c, 0xd08c, 0x0904, 0x8101, 0x68c0, 0x90aa, 0x0005, + 0x0a04, 0x8729, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d79, 0x9584, 0x00f6, 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258, 0x9584, 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, - 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xeb55, 0x080c, 0x8618, - 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x8674, - 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8159, 0x080c, - 0x21a6, 0x005e, 0x004e, 0x0020, 0x080c, 0xeb55, 0x7817, 0x0140, - 0x080c, 0x76a5, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, + 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xebc0, 0x080c, 0x8610, + 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x866c, + 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8151, 0x080c, + 0x21a2, 0x005e, 0x004e, 0x0020, 0x080c, 0xebc0, 0x7817, 0x0140, + 0x080c, 0x769d, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, - 0x0489, 0x0005, 0x0002, 0x8116, 0x8426, 0x8113, 0x8113, 0x8113, - 0x8113, 0x8113, 0x8113, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c, + 0x0489, 0x0005, 0x0002, 0x810e, 0x841e, 0x810b, 0x810b, 0x810b, + 0x810b, 0x810b, 0x810b, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, - 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5890, - 0x0070, 0x080c, 0x8179, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, - 0x8360, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x8545, 0x7817, + 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x588a, + 0x0070, 0x080c, 0x8171, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, + 0x8358, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x853d, 0x7817, 0x0140, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, - 0x8048, 0x2518, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x0036, + 0x8048, 0x2518, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, - 0x8048, 0x080c, 0x4c2e, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, + 0x8048, 0x080c, 0x4c28, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, - 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8331, 0x9186, 0x0023, - 0x15c0, 0x080c, 0x85e3, 0x0904, 0x8331, 0x6120, 0x9186, 0x0001, + 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8329, 0x9186, 0x0023, + 0x15c0, 0x080c, 0x85db, 0x0904, 0x8329, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, - 0x000a, 0x1904, 0x8331, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, - 0x1130, 0x2009, 0x0015, 0x080c, 0xafcc, 0x0804, 0x8331, 0x908e, + 0x000a, 0x1904, 0x8329, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, + 0x1130, 0x2009, 0x0015, 0x080c, 0xafec, 0x0804, 0x8329, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, - 0xafcc, 0x0804, 0x8331, 0x908e, 0x0100, 0x1904, 0x8331, 0x7034, - 0x9005, 0x1904, 0x8331, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0804, - 0x8331, 0x9186, 0x0022, 0x1904, 0x8331, 0x7030, 0x908e, 0x0300, + 0xafec, 0x0804, 0x8329, 0x908e, 0x0100, 0x1904, 0x8329, 0x7034, + 0x9005, 0x1904, 0x8329, 0x2009, 0x0016, 0x080c, 0xafec, 0x0804, + 0x8329, 0x9186, 0x0022, 0x1904, 0x8329, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, - 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26eb, - 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a2, 0x695e, + 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26ea, + 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a1, 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, - 0x00ee, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0017, 0x0804, - 0x82e1, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8331, - 0x080c, 0x76a5, 0x0120, 0x2009, 0x001d, 0x0804, 0x82e1, 0x68dc, - 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82e1, 0x908e, 0x0500, - 0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0018, 0x0804, - 0x82e1, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82e1, - 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82e1, 0x908e, - 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x001b, - 0x0804, 0x82e1, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, - 0x8331, 0x2009, 0x001c, 0x0804, 0x82e1, 0x908e, 0x1300, 0x1120, - 0x2009, 0x0034, 0x0804, 0x82e1, 0x908e, 0x1200, 0x1140, 0x7034, - 0x9005, 0x1904, 0x8331, 0x2009, 0x0024, 0x0804, 0x82e1, 0x908c, + 0x00ee, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0017, 0x0804, + 0x82d9, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8329, + 0x080c, 0x769d, 0x0120, 0x2009, 0x001d, 0x0804, 0x82d9, 0x68dc, + 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82d9, 0x908e, 0x0500, + 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0018, 0x0804, + 0x82d9, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82d9, + 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82d9, 0x908e, + 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x001b, + 0x0804, 0x82d9, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, + 0x8329, 0x2009, 0x001c, 0x0804, 0x82d9, 0x908e, 0x1300, 0x1120, + 0x2009, 0x0034, 0x0804, 0x82d9, 0x908e, 0x1200, 0x1140, 0x7034, + 0x9005, 0x1904, 0x8329, 0x2009, 0x0024, 0x0804, 0x82d9, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, - 0x2004, 0xd09c, 0x0904, 0x82e1, 0x080c, 0xda84, 0x1904, 0x8331, - 0x0804, 0x82df, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, - 0x002a, 0x0804, 0x82e1, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, - 0x0804, 0x82e1, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, + 0x2004, 0xd09c, 0x0904, 0x82d9, 0x080c, 0xdaa3, 0x1904, 0x8329, + 0x0804, 0x82d7, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, + 0x002a, 0x0804, 0x82d9, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, + 0x0804, 0x82d9, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, - 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c2e, - 0x004e, 0x8108, 0x0f04, 0x8295, 0x9186, 0x0280, 0x1d88, 0x2504, + 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c28, + 0x004e, 0x8108, 0x0f04, 0x828d, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, - 0x0023, 0x0804, 0x82e1, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, - 0x0804, 0x82e1, 0x908e, 0x5400, 0x1138, 0x080c, 0x86e1, 0x1904, - 0x8331, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, - 0x8709, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, + 0x0023, 0x0804, 0x82d9, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, + 0x0804, 0x82d9, 0x908e, 0x5400, 0x1138, 0x080c, 0x86d9, 0x1904, + 0x8329, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, + 0x8701, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, - 0x26a2, 0x1904, 0x8334, 0x080c, 0x671e, 0x1904, 0x8334, 0xbe12, - 0xbd16, 0x001e, 0x0016, 0x080c, 0x76a5, 0x01c0, 0x68dc, 0xd08c, + 0x26a1, 0x1904, 0x832c, 0x080c, 0x6718, 0x1904, 0x832c, 0xbe12, + 0xbd16, 0x001e, 0x0016, 0x080c, 0x769d, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, - 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaed8, + 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaef8, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, - 0xafcc, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, - 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x080c, - 0xaf9f, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, + 0xafec, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, + 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c28, 0x080c, + 0xafbf, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, - 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x942f, 0x08a0, - 0x080c, 0x8750, 0x1158, 0x080c, 0x3447, 0x1140, 0x7010, 0x9084, + 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x9427, 0x08a0, + 0x080c, 0x8748, 0x1158, 0x080c, 0x3432, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, - 0x11e8, 0x080c, 0x85e3, 0x0904, 0x83be, 0x7124, 0x610a, 0x7030, + 0x11e8, 0x080c, 0x85db, 0x0904, 0x83b6, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015, - 0x080c, 0xafcc, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005, - 0x1568, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0440, 0x9186, 0x0032, + 0x080c, 0xafec, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005, + 0x1568, 0x2009, 0x0016, 0x080c, 0xafec, 0x0440, 0x9186, 0x0032, 0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016, - 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11a8, - 0x080c, 0x671e, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaed8, 0x0168, - 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a, - 0x001e, 0x080c, 0xafcc, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, + 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x11a8, + 0x080c, 0x6718, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaef8, 0x0168, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a, + 0x001e, 0x080c, 0xafec, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, - 0x1120, 0x2009, 0x007f, 0x0804, 0x8420, 0x9596, 0xfffe, 0x1120, - 0x2009, 0x007e, 0x0804, 0x8420, 0x9596, 0xfffc, 0x1118, 0x2009, + 0x1120, 0x2009, 0x007f, 0x0804, 0x8418, 0x9596, 0xfffe, 0x1120, + 0x2009, 0x007e, 0x0804, 0x8418, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, @@ -4009,34 +4008,34 @@ unsigned short risc_code01[] = { 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, - 0x83f5, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, + 0x83ed, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005, - 0x8448, 0x8448, 0x8448, 0x85f5, 0x8448, 0x844b, 0x8470, 0x84f9, - 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, + 0x8440, 0x8440, 0x8440, 0x85ed, 0x8440, 0x8443, 0x8468, 0x84f1, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x7817, 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, - 0x2009, 0x0046, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005, - 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84d5, 0x7110, 0xd1bc, - 0x1904, 0x84d5, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, - 0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3489, 0x200d, - 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84d5, - 0x9182, 0x0801, 0x1a04, 0x84d5, 0x9190, 0x1000, 0x2204, 0x905d, + 0x2009, 0x0046, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005, + 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84cd, 0x7110, 0xd1bc, + 0x1904, 0x84cd, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, + 0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3474, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84cd, + 0x9182, 0x0801, 0x1a04, 0x84cd, 0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, - 0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaed8, 0x0598, 0x2b08, + 0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaef8, 0x0598, 0x2b08, 0x7028, 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120, - 0x610a, 0x7130, 0x615e, 0x080c, 0xdd0b, 0x00f8, 0x080c, 0x6bd5, - 0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83c2, 0x11b0, 0x0880, - 0x080c, 0xaed8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, + 0x610a, 0x7130, 0x615e, 0x080c, 0xdd1f, 0x00f8, 0x080c, 0x6bcd, + 0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83ba, 0x11b0, 0x0880, + 0x080c, 0xaef8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, - 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x7817, 0x0140, 0x00ce, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x7817, 0x0140, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, - 0x8049, 0x080c, 0x4c2e, 0x080c, 0xaf9f, 0x0d78, 0x2b08, 0x6112, + 0x8049, 0x080c, 0x4c28, 0x080c, 0xafbf, 0x0d78, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300, - 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428, + 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x08e0, 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84, 0x0003, 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff, @@ -4044,69 +4043,69 @@ unsigned short risc_code01[] = { 0x11f0, 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271, 0x2004, 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158, 0x0066, 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e, - 0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafcc, 0x7817, + 0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, - 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8750, 0x1180, - 0x080c, 0x3447, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, + 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8748, 0x1180, + 0x080c, 0x3432, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, - 0x0005, 0x855f, 0x8560, 0x855f, 0x855f, 0x85c5, 0x85d4, 0x0005, - 0x00b6, 0x700c, 0x7108, 0x080c, 0x26a2, 0x1904, 0x85c3, 0x080c, - 0x671e, 0x1904, 0x85c3, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, - 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85c3, 0x080c, - 0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd, 0x0118, - 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85e3, 0x00ce, 0x05d8, - 0x080c, 0xaed8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0b1, 0x6023, - 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafcc, 0x0458, - 0x080c, 0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd, - 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaed8, 0x2b08, 0x01d8, - 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, - 0x0088, 0x080c, 0xafcc, 0x0078, 0x080c, 0xaed8, 0x2b08, 0x0158, - 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, - 0x0001, 0x080c, 0xafcc, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, - 0x00d1, 0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009, - 0x0089, 0x080c, 0xafcc, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, - 0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, - 0x080c, 0xafcc, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, + 0x0005, 0x8557, 0x8558, 0x8557, 0x8557, 0x85bd, 0x85cc, 0x0005, + 0x00b6, 0x700c, 0x7108, 0x080c, 0x26a1, 0x1904, 0x85bb, 0x080c, + 0x6718, 0x1904, 0x85bb, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, + 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85bb, 0x080c, + 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5, 0x0118, + 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85db, 0x00ce, 0x05d8, + 0x080c, 0xaef8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafec, 0x0458, + 0x080c, 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5, + 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaef8, 0x2b08, 0x01d8, + 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, + 0x0088, 0x080c, 0xafec, 0x0078, 0x080c, 0xaef8, 0x2b08, 0x0158, + 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, + 0x0001, 0x080c, 0xafec, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, + 0x00d1, 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009, + 0x0089, 0x080c, 0xafec, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, + 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, + 0x080c, 0xafec, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, 0x9c82, 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, - 0x2009, 0x0051, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005, + 0x2009, 0x0051, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, - 0x05c0, 0x080c, 0xaed8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, - 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x1590, 0x080c, - 0x671e, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, - 0x080c, 0xd0b1, 0x080c, 0x1059, 0x0500, 0x2900, 0x6062, 0x9006, + 0x05c0, 0x080c, 0xaef8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x1590, 0x080c, + 0x6718, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, + 0x080c, 0xd0ce, 0x080c, 0x104d, 0x0500, 0x2900, 0x6062, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, - 0x942f, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf2e, 0x006e, + 0x9427, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf4e, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, - 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86cb, 0x9186, - 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86cd, - 0x7030, 0x908e, 0x0400, 0x0904, 0x86cd, 0x908e, 0x6000, 0x05e8, + 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86c3, 0x9186, + 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86c5, + 0x7030, 0x908e, 0x0400, 0x0904, 0x86c5, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, - 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b93, 0x0588, + 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b8b, 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, - 0x9186, 0x0023, 0x1140, 0x080c, 0x85e3, 0x0128, 0x6004, 0x9086, + 0x9186, 0x0023, 0x1140, 0x080c, 0x85db, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, - 0x2011, 0x027a, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9, - 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf2a, 0x1120, + 0x2011, 0x027a, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf40, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, - 0x2011, 0x0272, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9, - 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf2a, 0x1120, + 0x2011, 0x0272, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf40, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, @@ -4115,53 +4114,53 @@ unsigned short risc_code01[] = { 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x1a05, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, - 0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0aa, - 0x7032, 0x7037, 0xa127, 0x7047, 0xffff, 0x704a, 0x704f, 0x56aa, - 0x7052, 0x7063, 0x8907, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, + 0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0bb, + 0x7032, 0x7037, 0xa138, 0x7047, 0xffff, 0x704a, 0x704f, 0x56a4, + 0x7052, 0x7063, 0x88ff, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, - 0x2071, 0x1a05, 0x1d04, 0x8823, 0x2091, 0x6000, 0x700c, 0x8001, - 0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89b1, + 0x2071, 0x1a05, 0x1d04, 0x881b, 0x2091, 0x6000, 0x700c, 0x8001, + 0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89a9, 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, - 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d85, + 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d79, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069, - 0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x8975, - 0x0010, 0x080c, 0x894c, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, + 0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x896d, + 0x0010, 0x080c, 0x8944, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, - 0x007f, 0x090c, 0xa1d5, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, + 0x007f, 0x090c, 0xa1e6, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, - 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x884b, 0x884c, 0x8876, + 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x8843, 0x8844, 0x886e, 0x00e6, 0x2071, 0x1a05, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a05, 0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1a05, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110, - 0x080c, 0x6789, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, + 0x080c, 0x6783, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, 0x0126, 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026, - 0xba3c, 0x0016, 0x080c, 0x68b4, 0x001e, 0x002e, 0x006e, 0x012e, + 0xba3c, 0x0016, 0x080c, 0x68ae, 0x001e, 0x002e, 0x006e, 0x012e, 0x8108, 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128, - 0x8001, 0x604a, 0x1110, 0x080c, 0xcf32, 0x6018, 0x9005, 0x0904, - 0x88ce, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88e1, + 0x8001, 0x604a, 0x1110, 0x080c, 0xcf4f, 0x6018, 0x9005, 0x0904, + 0x88c6, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88d9, 0x781b, 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000, - 0x0804, 0x88e1, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001, + 0x0804, 0x88d9, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001, 0x7918, 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, - 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc16, 0x01b0, 0x6014, 0x2048, + 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc33, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, - 0x611a, 0x080c, 0xd36a, 0x0110, 0x080c, 0xc8f7, 0x012e, 0x9c88, + 0x611a, 0x080c, 0xd389, 0x0110, 0x080c, 0xc910, 0x012e, 0x9c88, 0x001c, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631, - 0x0138, 0x2160, 0x0804, 0x887a, 0x7017, 0x1ddc, 0x7007, 0x0000, + 0x0138, 0x2160, 0x0804, 0x8872, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x0005, 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a05, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0e, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1a05, 0x7132, 0x702f, 0x0009, 0x00ee, @@ -4169,9 +4168,9 @@ unsigned short risc_code01[] = { 0x1a05, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, 0x705e, 0x2001, 0x1a15, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, - 0xa092, 0x7064, 0xa08e, 0x080c, 0x114e, 0x002e, 0x008e, 0x0005, + 0xa092, 0x7064, 0xa08e, 0x080c, 0x1142, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x0156, 0x080c, 0x8788, 0x015e, 0x00fe, 0x00ee, 0x00de, + 0x00f6, 0x0156, 0x080c, 0x8780, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x1a05, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a05, 0x707c, 0x9206, 0x1110, 0x707a, @@ -4180,14 +4179,14 @@ unsigned short risc_code01[] = { 0x8117, 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205, - 0x68ee, 0x080c, 0x0f24, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f, + 0x68ee, 0x080c, 0x0f18, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f, 0x05b8, 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202, 0x0220, 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd, - 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x0400, + 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x0400, 0x69ea, 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001, 0x8007, 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004, 0x9084, 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040, - 0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x002e, + 0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, @@ -4196,42 +4195,42 @@ unsigned short risc_code01[] = { 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a74, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, - 0x918e, 0x00c0, 0x0904, 0x8a8f, 0xd0b4, 0x1168, 0xd0bc, 0x1904, - 0x8a68, 0x2009, 0x0006, 0x080c, 0x8abc, 0x0005, 0x900e, 0x0c60, + 0x918e, 0x00c0, 0x0904, 0x8a87, 0xd0b4, 0x1168, 0xd0bc, 0x1904, + 0x8a60, 0x2009, 0x0006, 0x080c, 0x8ab4, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568, 0x87ff, 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500, 0x1520, 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c, 0xd184, 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035, - 0x080c, 0x1c90, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6, + 0x080c, 0x1c8c, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120, - 0x918e, 0x0003, 0x1904, 0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020, + 0x918e, 0x0003, 0x1904, 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, - 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafcc, 0x0005, - 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafcc, 0x6110, 0x00b6, + 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafec, 0x0005, + 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafec, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, - 0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, - 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, - 0x0042, 0x080c, 0xafcc, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, + 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, + 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, + 0x0042, 0x080c, 0xafec, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, - 0xafcc, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, - 0x080c, 0xafcc, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xafec, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, + 0x080c, 0xafec, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, - 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc16, 0x0518, + 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc33, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, - 0x00ce, 0x080c, 0x6d53, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, - 0x190c, 0x89d5, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, + 0x00ce, 0x080c, 0x6d4b, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, + 0x190c, 0x89cd, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, - 0x080c, 0x1072, 0x090c, 0x0d85, 0xa867, 0x0006, 0xa86b, 0x0001, + 0x080c, 0x1066, 0x090c, 0x0d79, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, @@ -4240,92 +4239,92 @@ unsigned short risc_code01[] = { 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006, 0x2009, 0x1b74, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, - 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16b9, 0x9006, + 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16ad, 0x9006, 0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005, 0x2009, 0x1b74, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, - 0x9080, 0x0008, 0x1f04, 0x8b78, 0x71c0, 0x9102, 0x02e0, 0x2071, - 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaed8, 0x6023, 0x0009, + 0x9080, 0x0008, 0x1f04, 0x8b70, 0x71c0, 0x9102, 0x02e0, 0x2071, + 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaef8, 0x6023, 0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, - 0x080c, 0x8cf9, 0x012e, 0x1f04, 0x8b84, 0x9006, 0x00ce, 0x015e, + 0x080c, 0x8cf1, 0x012e, 0x1f04, 0x8b7c, 0x9006, 0x00ce, 0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, - 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x1059, 0x090c, 0x0d85, + 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x104d, 0x090c, 0x0d79, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, - 0x0160, 0x080c, 0x1059, 0x090c, 0x0d85, 0xad66, 0x2b00, 0xa802, + 0x0160, 0x080c, 0x104d, 0x090c, 0x0d79, 0xad66, 0x2b00, 0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, - 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8bf0, 0x8be9, 0x8be9, - 0x0005, 0x8bfa, 0x8c50, 0x8c50, 0x8c50, 0x8c51, 0x8c62, 0x8c62, + 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8be8, 0x8be1, 0x8be1, + 0x0005, 0x8bf2, 0x8c48, 0x8c48, 0x8c48, 0x8c49, 0x8c5a, 0x8c5a, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, - 0x1904, 0x8c42, 0x7814, 0xd0bc, 0x1904, 0x8c4b, 0x012e, 0x7018, - 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c94, 0x0005, 0x1210, + 0x1904, 0x8c3a, 0x7814, 0xd0bc, 0x1904, 0x8c43, 0x012e, 0x7018, + 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c8c, 0x0005, 0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50, - 0x080c, 0x8df1, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, - 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8efa, 0x2100, 0xa87e, + 0x080c, 0x8de9, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, + 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ef2, 0x2100, 0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a25, - 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x116d, - 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8c02, 0x080c, - 0x8dc9, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8c02, - 0x0005, 0x700c, 0x0002, 0x8c56, 0x8c59, 0x8c58, 0x080c, 0x8bf8, + 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1161, + 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8bfa, 0x080c, + 0x8dc1, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8bfa, + 0x0005, 0x700c, 0x0002, 0x8c4e, 0x8c51, 0x8c50, 0x080c, 0x8bf0, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, - 0x0068, 0x0006, 0x080c, 0x8efa, 0x2100, 0xaa8c, 0x9210, 0xaa8e, + 0x0068, 0x0006, 0x080c, 0x8ef2, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, - 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc9, 0x012e, 0x0005, - 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c92, 0x8c92, 0x8c90, + 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc1, 0x012e, 0x0005, + 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c8a, 0x8c8a, 0x8c88, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, - 0x0000, 0x080c, 0x8d02, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, - 0x080c, 0x8d49, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1072, 0x2900, + 0x0000, 0x080c, 0x8cfa, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, + 0x080c, 0x8d41, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1066, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1948, 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, - 0x000f, 0x2068, 0x9d88, 0x1ee2, 0x2165, 0x0056, 0x2029, 0x0000, - 0x080c, 0x8e7f, 0x080c, 0x1eb8, 0x1dd8, 0x005e, 0x00ae, 0x2001, - 0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17ad, 0x00ce, + 0x000f, 0x2068, 0x9d88, 0x1ede, 0x2165, 0x0056, 0x2029, 0x0000, + 0x080c, 0x8e77, 0x080c, 0x1eb4, 0x1dd8, 0x005e, 0x00ae, 0x2001, + 0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17a1, 0x00ce, 0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, - 0x8d58, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, + 0x8d50, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6, 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032, - 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc8, 0x2005, - 0x906d, 0x090c, 0x0d85, 0x9b80, 0x8fc0, 0x2005, 0x9065, 0x090c, - 0x0d85, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, + 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc0, 0x2005, + 0x906d, 0x090c, 0x0d79, 0x9b80, 0x8fb8, 0x2005, 0x9065, 0x090c, + 0x0d79, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, - 0x080c, 0x4c2e, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa804, + 0x080c, 0x4c28, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d79, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, - 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c2e, 0x684c, - 0x0096, 0x904d, 0x090c, 0x0d85, 0xa800, 0x8000, 0xa802, 0x009e, + 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c28, 0x684c, + 0x0096, 0x904d, 0x090c, 0x0d79, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, - 0x00d6, 0x7814, 0x9005, 0x090c, 0x0d85, 0x781c, 0x9084, 0x0101, - 0x9086, 0x0101, 0x190c, 0x0d85, 0x7827, 0x0000, 0x2069, 0x193e, + 0x00d6, 0x7814, 0x9005, 0x090c, 0x0d79, 0x781c, 0x9084, 0x0101, + 0x9086, 0x0101, 0x190c, 0x0d79, 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080, 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, - 0x0096, 0x2048, 0x9005, 0x190c, 0x108b, 0x009e, 0xa8ab, 0x0000, - 0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x009e, 0x0005, 0x6020, + 0x0096, 0x2048, 0x9005, 0x190c, 0x107f, 0x009e, 0xa8ab, 0x0000, + 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, - 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90fd, 0x00be, 0x6013, + 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90f5, 0x00be, 0x6013, 0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c, 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925, 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, - 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16b9, 0x00ee, 0x012e, + 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16ad, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, - 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f48, - 0x0170, 0x080c, 0x8f7d, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, + 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f40, + 0x0170, 0x080c, 0x8f75, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932, - 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f7d, 0x090c, 0x0d85, + 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f75, 0x090c, 0x0d79, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000, @@ -4333,92 +4332,92 @@ unsigned short risc_code01[] = { 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c, - 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8efa, 0x810c, 0x2100, + 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8ef2, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, - 0x2508, 0x080c, 0x8f03, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, + 0x2508, 0x080c, 0x8efb, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, - 0x0026, 0x080c, 0x8df1, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, - 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e30, + 0x0026, 0x080c, 0x8de9, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, + 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e28, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, - 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fc0, 0x2005, - 0x9075, 0x090c, 0x0d85, 0x080c, 0x8ed5, 0x012e, 0x9580, 0x8fbc, - 0x2005, 0x9075, 0x090c, 0x0d85, 0x0156, 0x0136, 0x01c6, 0x0146, + 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fb8, 0x2005, + 0x9075, 0x090c, 0x0d79, 0x080c, 0x8ecd, 0x012e, 0x9580, 0x8fb4, + 0x2005, 0x9075, 0x090c, 0x0d79, 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100, - 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ebf, - 0x8ebf, 0x8ec1, 0x8ebf, 0x8ec1, 0x8ebf, 0x8ebf, 0x8ebf, 0x8ebf, - 0x8ebf, 0x8ec7, 0x8ebf, 0x8ec7, 0x8ebf, 0x8ebf, 0x8ebf, 0x080c, - 0x0d85, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, + 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8eb7, + 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb7, 0x8eb7, 0x8eb7, + 0x8eb7, 0x8ebf, 0x8eb7, 0x8ebf, 0x8eb7, 0x8eb7, 0x8eb7, 0x080c, + 0x0d79, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005, - 0x0158, 0x0006, 0x080c, 0x8f8c, 0x009e, 0xa807, 0x0000, 0x2900, + 0x0158, 0x0006, 0x080c, 0x8f84, 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008, - 0x2031, 0x8f46, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, + 0x2031, 0x8f3e, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005, - 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fc4, - 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, 0x90a0, 0x000a, 0x080c, - 0x1072, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, - 0x080c, 0x1072, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, + 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fbc, + 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0x90a0, 0x000a, 0x080c, + 0x1066, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, + 0x080c, 0x1066, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048, - 0xac00, 0x080c, 0x108b, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, + 0xac00, 0x080c, 0x107f, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009, - 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x108b, + 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x107f, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138, - 0x2048, 0xa800, 0x0006, 0x080c, 0x108b, 0x000e, 0x0cb8, 0x9006, + 0x2048, 0xa800, 0x0006, 0x080c, 0x107f, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a72, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6, - 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e8, 0xa067, 0x0023, - 0x6010, 0x905d, 0x0904, 0x90bd, 0xb814, 0xa06e, 0xb910, 0xa172, + 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e0, 0xa067, 0x0023, + 0x6010, 0x905d, 0x0904, 0x90b5, 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858, - 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d85, 0x2020, + 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d79, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0, - 0x1ee2, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, - 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x9028, 0x9028, 0x902a, - 0x9028, 0x9028, 0x9028, 0x902c, 0x9028, 0x9028, 0x9028, 0x902e, - 0x9028, 0x9028, 0x9028, 0x9030, 0x9028, 0x9028, 0x9028, 0x9032, - 0x9028, 0x9028, 0x9028, 0x9034, 0x9028, 0x9028, 0x9028, 0x9036, - 0x080c, 0x0d85, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, + 0x1ede, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9020, 0x9020, 0x9022, + 0x9020, 0x9020, 0x9020, 0x9024, 0x9020, 0x9020, 0x9020, 0x9026, + 0x9020, 0x9020, 0x9020, 0x9028, 0x9020, 0x9020, 0x9020, 0x902a, + 0x9020, 0x9020, 0x9020, 0x902c, 0x9020, 0x9020, 0x9020, 0x902e, + 0x080c, 0x0d79, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, - 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x905a, - 0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x905c, 0x9058, 0x9058, - 0x9058, 0x9058, 0x9058, 0x905e, 0x9058, 0x9058, 0x9058, 0x9058, - 0x9058, 0x9060, 0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x9062, - 0x080c, 0x0d85, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, - 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x907e, 0x9080, 0x9082, - 0x9084, 0x9086, 0x9088, 0x908a, 0x908c, 0x908e, 0x9090, 0x9092, - 0x9094, 0x9096, 0x9098, 0x909a, 0x909c, 0x909e, 0x90a0, 0x90a2, - 0x90a4, 0x90a6, 0x90a8, 0x90aa, 0x90ac, 0x90ae, 0x080c, 0x0d85, + 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9052, + 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x9054, 0x9050, 0x9050, + 0x9050, 0x9050, 0x9050, 0x9056, 0x9050, 0x9050, 0x9050, 0x9050, + 0x9050, 0x9058, 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x905a, + 0x080c, 0x0d79, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, + 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x9076, 0x9078, 0x907a, + 0x907c, 0x907e, 0x9080, 0x9082, 0x9084, 0x9086, 0x9088, 0x908a, + 0x908c, 0x908e, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a, + 0x909c, 0x909e, 0x90a0, 0x90a2, 0x90a4, 0x90a6, 0x080c, 0x0d79, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631, - 0x8421, 0x0130, 0x080c, 0x1eb8, 0x090c, 0x0d85, 0x0804, 0x9002, + 0x8421, 0x0130, 0x080c, 0x1eb4, 0x090c, 0x0d79, 0x0804, 0x8ffa, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, - 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fe4, 0x0006, 0x0016, + 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fdc, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014, - 0x080c, 0x4c2e, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, + 0x080c, 0x4c28, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036, @@ -4426,90 +4425,90 @@ unsigned short risc_code01[] = { 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005, - 0x090c, 0x0d85, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, + 0x090c, 0x0d79, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, - 0xd094, 0x0110, 0x1f04, 0x913d, 0x701b, 0x0202, 0xa001, 0xa001, + 0xd094, 0x0110, 0x1f04, 0x9135, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000, - 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d85, 0x080c, 0x108b, - 0x080c, 0x8cf9, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, + 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d79, 0x080c, 0x107f, + 0x080c, 0x8cf1, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, - 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a2, 0x015e, 0x11b0, - 0x080c, 0x671e, 0x190c, 0x0d85, 0x000e, 0x001e, 0xb912, 0xb816, - 0x080c, 0xaed8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, - 0x0001, 0x080c, 0xafcc, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, - 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013, - 0x006e, 0x0005, 0x91b2, 0x91b2, 0x91b2, 0x91b4, 0x91fd, 0x91b2, - 0x91b2, 0x91b2, 0x9264, 0x91b2, 0x929c, 0x91b2, 0x91b2, 0x91b2, - 0x91b2, 0x91b2, 0x080c, 0x0d85, 0x9182, 0x0040, 0x0002, 0x91c7, - 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, - 0x91c9, 0x91da, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91eb, 0x080c, - 0x0d85, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, - 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d18, 0x080c, 0xaf2e, - 0x009e, 0x0005, 0x080c, 0x9859, 0x00d6, 0x6114, 0x080c, 0xcc16, - 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f19, 0x009e, 0x00de, - 0x080c, 0xaf2e, 0x0005, 0x080c, 0x9859, 0x080c, 0x3310, 0x6114, - 0x0096, 0x2148, 0x080c, 0xcc16, 0x0120, 0xa87b, 0x0029, 0x080c, - 0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x601b, 0x0000, 0x9182, - 0x0040, 0x0096, 0x0002, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, - 0x9218, 0x9218, 0x9218, 0x921a, 0x9218, 0x9218, 0x9218, 0x9260, - 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9221, 0x9218, - 0x080c, 0x0d85, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, - 0x9260, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, - 0x8fcc, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6cb0, 0x009e, 0xa8ab, - 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd, - 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8d02, 0x00be, - 0x01e0, 0x2071, 0x193e, 0x080c, 0x8d49, 0x01b8, 0x9086, 0x0001, + 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a1, 0x015e, 0x11b0, + 0x080c, 0x6718, 0x190c, 0x0d79, 0x000e, 0x001e, 0xb912, 0xb816, + 0x080c, 0xaef8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, + 0x0001, 0x080c, 0xafec, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, + 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013, + 0x006e, 0x0005, 0x91aa, 0x91aa, 0x91aa, 0x91ac, 0x91f5, 0x91aa, + 0x91aa, 0x91aa, 0x925c, 0x91aa, 0x9294, 0x91aa, 0x91aa, 0x91aa, + 0x91aa, 0x91aa, 0x080c, 0x0d79, 0x9182, 0x0040, 0x0002, 0x91bf, + 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, + 0x91c1, 0x91d2, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91e3, 0x080c, + 0x0d79, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d10, 0x080c, 0xaf4e, + 0x009e, 0x0005, 0x080c, 0x9851, 0x00d6, 0x6114, 0x080c, 0xcc33, + 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f11, 0x009e, 0x00de, + 0x080c, 0xaf4e, 0x0005, 0x080c, 0x9851, 0x080c, 0x32fb, 0x6114, + 0x0096, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c, + 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x601b, 0x0000, 0x9182, + 0x0040, 0x0096, 0x0002, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, + 0x9210, 0x9210, 0x9210, 0x9212, 0x9210, 0x9210, 0x9210, 0x9258, + 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9219, 0x9210, + 0x080c, 0x0d79, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, + 0x9258, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, + 0x8fc4, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6ca8, 0x009e, 0xa8ab, + 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5, + 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8cfa, 0x00be, + 0x01e0, 0x2071, 0x193e, 0x080c, 0x8d41, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, - 0x1059, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, - 0x8cbd, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf9, 0x0cd0, - 0x080c, 0x9318, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, - 0x9278, 0x9278, 0x9278, 0x927a, 0x9278, 0x9278, 0x9278, 0x929a, - 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, - 0x080c, 0x0d85, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, + 0x104d, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, + 0x8cb5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf1, 0x0cd0, + 0x080c, 0x9310, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, + 0x9270, 0x9270, 0x9270, 0x9272, 0x9270, 0x9270, 0x9270, 0x9292, + 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, + 0x080c, 0x0d79, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, - 0x9210, 0x621a, 0x080c, 0x1c47, 0x2009, 0x8030, 0x080c, 0x946f, - 0x009e, 0x0005, 0x080c, 0x0d85, 0x080c, 0x9859, 0x6114, 0x2148, + 0x9210, 0x621a, 0x080c, 0x1c43, 0x2009, 0x8030, 0x080c, 0x9467, + 0x009e, 0x0005, 0x080c, 0x0d79, 0x080c, 0x9851, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, - 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xaae0, + 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xaaf7, 0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, 0x6000, - 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x0023, 0x009e, 0x080c, - 0xaafc, 0x0005, 0x92d2, 0x92d2, 0x92d2, 0x92d4, 0x92e5, 0x92d2, - 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, - 0x92d2, 0x92d2, 0x080c, 0x0d85, 0x080c, 0xacaf, 0x6114, 0x2148, + 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x0023, 0x009e, 0x080c, + 0xab13, 0x0005, 0x92ca, 0x92ca, 0x92ca, 0x92cc, 0x92dd, 0x92ca, + 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, + 0x92ca, 0x92ca, 0x080c, 0x0d79, 0x080c, 0xaccf, 0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, - 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x0005, 0x0491, 0x0005, 0x080c, - 0xaae0, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003, - 0x0003, 0x2009, 0x0003, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, - 0x0033, 0x009e, 0x0106, 0x080c, 0xaafc, 0x010e, 0x0005, 0x930f, - 0x930f, 0x930f, 0x9311, 0x9318, 0x930f, 0x930f, 0x930f, 0x930f, - 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x080c, - 0x0d85, 0x0036, 0x00e6, 0x080c, 0xacaf, 0x00ee, 0x003e, 0x0005, + 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x0005, 0x0491, 0x0005, 0x080c, + 0xaaf7, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003, + 0x0003, 0x2009, 0x0003, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, + 0x0033, 0x009e, 0x0106, 0x080c, 0xab13, 0x010e, 0x0005, 0x9307, + 0x9307, 0x9307, 0x9309, 0x9310, 0x9307, 0x9307, 0x9307, 0x9307, + 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x080c, + 0x0d79, 0x0036, 0x00e6, 0x080c, 0xaccf, 0x00ee, 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014, - 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd, - 0x00be, 0x2071, 0x193e, 0x080c, 0x8d49, 0x0160, 0x2001, 0x187f, - 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cbd, 0x00ee, + 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5, + 0x00be, 0x2071, 0x193e, 0x080c, 0x8d41, 0x0160, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cb5, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c, - 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf9, 0x0c80, 0x0000, + 0x107f, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf1, 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, - 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9360, 0x8086, 0x818e, + 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9358, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213, - 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x9377, 0x0028, 0x911a, - 0x2308, 0x8210, 0x1f04, 0x9377, 0x0006, 0x3200, 0x9084, 0xefff, + 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x936f, 0x0028, 0x911a, + 0x2308, 0x8210, 0x1f04, 0x936f, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, 0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, - 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x04c9, - 0x080c, 0xa8c0, 0x04b1, 0x080c, 0xa8c3, 0x0499, 0x080c, 0xa8c6, - 0x0481, 0x080c, 0xa8c9, 0x0469, 0x080c, 0xa8cc, 0x0451, 0x080c, - 0xa8cf, 0x0439, 0x080c, 0xa8d2, 0x0421, 0x01de, 0x014e, 0x015e, + 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8ec, 0x04c9, + 0x080c, 0xa8d7, 0x04b1, 0x080c, 0xa8da, 0x0499, 0x080c, 0xa8dd, + 0x0481, 0x080c, 0xa8e0, 0x0469, 0x080c, 0xa8e3, 0x0451, 0x080c, + 0xa8e6, 0x0439, 0x080c, 0xa8e9, 0x0421, 0x01de, 0x014e, 0x015e, 0x6857, 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003, 0x7803, 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084, 0xfffe, 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084, @@ -4518,842 +4517,847 @@ unsigned short risc_code01[] = { 0x0005, 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1af7, 0x781f, 0xff00, 0x781b, 0xff00, 0x2061, 0x1aec, 0x602f, 0x19e9, 0x6033, 0x1800, 0x6037, - 0x1a05, 0x603b, 0x1ee2, 0x603f, 0x1ef2, 0x6042, 0x6047, 0x1ac2, + 0x1a05, 0x603b, 0x1ede, 0x603f, 0x1eee, 0x6042, 0x6047, 0x1ac2, 0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8, - 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaad1, 0x0005, 0x0016, + 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaae8, 0x0005, 0x0016, 0x2009, 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084, - 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaad1, + 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaae8, 0x0088, 0x00c6, 0x2061, 0x19e9, 0x602c, 0x8000, 0x602e, 0x600c, 0x9005, 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112, 0x610e, 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146, - 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaad1, 0x0005, - 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa56e, 0x0005, 0x00f6, 0x00e6, + 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaae8, 0x0005, + 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa585, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7648, - 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9502, 0x9c86, - 0x1b56, 0x0904, 0x94fd, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, - 0x94fd, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94fd, 0x704c, - 0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f, - 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0, - 0x003e, 0x2029, 0x0001, 0x080c, 0x9478, 0x7048, 0x9c36, 0x1110, + 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x94fa, 0x9c86, + 0x1b56, 0x0904, 0x94f5, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, + 0x94f5, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94f5, 0x704c, + 0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f, + 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0, + 0x003e, 0x2029, 0x0001, 0x080c, 0x9470, 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, - 0xcc16, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588, - 0x6004, 0x9086, 0x0040, 0x090c, 0xa56e, 0xa867, 0x0103, 0xab7a, - 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf1b, 0x080c, - 0xea83, 0x080c, 0x6f19, 0x007e, 0x003e, 0x001e, 0x080c, 0xce07, - 0x080c, 0xaf69, 0x00ce, 0x0804, 0x9494, 0x2c78, 0x600c, 0x2060, - 0x0804, 0x9494, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, + 0xcc33, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588, + 0x6004, 0x9086, 0x0040, 0x090c, 0xa585, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf38, 0x080c, + 0xeaee, 0x080c, 0x6f11, 0x007e, 0x003e, 0x001e, 0x080c, 0xce24, + 0x080c, 0xaf89, 0x00ce, 0x0804, 0x948c, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x948c, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, - 0x080c, 0xea83, 0x080c, 0xe6cd, 0x007e, 0x003e, 0x001e, 0x08c0, + 0x080c, 0xeaee, 0x080c, 0xe738, 0x007e, 0x003e, 0x001e, 0x08c0, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, - 0x0076, 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x007e, 0x003e, 0x001e, - 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94e7, 0x0804, 0x94e0, + 0x0076, 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x007e, 0x003e, 0x001e, + 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94df, 0x0804, 0x94d8, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, - 0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x95a1, + 0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x9599, 0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036, - 0x2019, 0x0001, 0x080c, 0xa380, 0x783f, 0x0000, 0x901e, 0x7b4e, - 0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xadc0, 0x003e, 0x000e, 0x9005, + 0x2019, 0x0001, 0x080c, 0xa391, 0x783f, 0x0000, 0x901e, 0x7b4e, + 0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xade0, 0x003e, 0x000e, 0x9005, 0x1118, 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b56, 0x05b0, - 0x00e6, 0x2f70, 0x080c, 0x9478, 0x00ee, 0x080c, 0xcc16, 0x0548, + 0x00e6, 0x2f70, 0x080c, 0x9470, 0x00ee, 0x080c, 0xcc33, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1989, - 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa56e, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c, - 0xce07, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf69, 0x000e, 0x0804, - 0x9545, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, + 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa585, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c, + 0xce24, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf89, 0x000e, 0x0804, + 0x953d, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, - 0xe6cd, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, - 0x6f19, 0x080c, 0xaf2e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, - 0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96b4, + 0xe738, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, + 0x6f11, 0x080c, 0xaf4e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, + 0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96ac, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9, - 0x2091, 0x8000, 0x080c, 0x96fd, 0x080c, 0x9793, 0x080c, 0x6916, + 0x2091, 0x8000, 0x080c, 0x96f5, 0x080c, 0x978b, 0x080c, 0x690e, 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9679, 0x6010, - 0x2058, 0xb8a0, 0x9206, 0x1904, 0x9674, 0x88ff, 0x0120, 0x605c, - 0x9106, 0x1904, 0x9674, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100, - 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88ec, 0x080c, - 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, + 0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9671, 0x6010, + 0x2058, 0xb8a0, 0x9206, 0x1904, 0x966c, 0x88ff, 0x0120, 0x605c, + 0x9106, 0x1904, 0x966c, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100, + 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88e4, 0x080c, + 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, + 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad, - 0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x9674, 0x7020, 0x9c36, + 0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x966c, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01e8, - 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce2d, 0x1118, 0x080c, - 0xb91f, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, - 0x0036, 0x0086, 0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19, - 0x008e, 0x003e, 0x001e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x080c, - 0xa441, 0x00ce, 0x0804, 0x95ec, 0x2c78, 0x600c, 0x2060, 0x0804, - 0x95ec, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01e8, + 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, + 0x0036, 0x0086, 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11, + 0x008e, 0x003e, 0x001e, 0x080c, 0xce24, 0x080c, 0xaf89, 0x080c, + 0xa458, 0x00ce, 0x0804, 0x95e4, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x95e4, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, - 0x0016, 0x0036, 0x0086, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x008e, - 0x003e, 0x001e, 0x08d0, 0x080c, 0xb91f, 0x6020, 0x9086, 0x0002, - 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x965a, - 0x9086, 0x008b, 0x0904, 0x965a, 0x0840, 0x6020, 0x9086, 0x0005, + 0x0016, 0x0036, 0x0086, 0x080c, 0xeaee, 0x080c, 0xe738, 0x008e, + 0x003e, 0x001e, 0x08d0, 0x080c, 0xb93c, 0x6020, 0x9086, 0x0002, + 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9652, + 0x9086, 0x008b, 0x0904, 0x9652, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, - 0x008b, 0x09b0, 0x0804, 0x966d, 0x0006, 0x00f6, 0x00e6, 0x0096, + 0x008b, 0x09b0, 0x0804, 0x9665, 0x0006, 0x00f6, 0x00e6, 0x0096, 0x00b6, 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x2079, 0x19e9, 0x9036, 0x7828, 0x2060, 0x8cff, 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c, - 0xacfa, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa20a, 0x6014, 0x2048, + 0xad1a, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa21b, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, - 0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19, 0x008e, 0x003e, - 0x001e, 0x080c, 0xaf69, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, - 0x08b8, 0x080c, 0x6933, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, + 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11, 0x008e, 0x003e, + 0x001e, 0x080c, 0xaf89, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, + 0x08b8, 0x080c, 0x692b, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, 0x009e, 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066, - 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x9766, 0x600c, + 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x975e, 0x600c, 0x0006, 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06, 0x1598, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, - 0x080c, 0x88ec, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e, + 0x080c, 0x88e4, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7833, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, - 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, - 0x0058, 0x080c, 0x6b6d, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808, - 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc14, - 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce2d, 0x1118, - 0x080c, 0xb91f, 0x0060, 0x080c, 0x6b6d, 0x1168, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c, - 0xaf69, 0x080c, 0xa441, 0x000e, 0x0804, 0x9704, 0x7e22, 0x7e1e, + 0x0058, 0x080c, 0x6b65, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808, + 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc31, + 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce4a, 0x1118, + 0x080c, 0xb93c, 0x0060, 0x080c, 0x6b65, 0x1168, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c, + 0xaf89, 0x080c, 0xa458, 0x000e, 0x0804, 0x96fc, 0x7e22, 0x7e1e, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1118, 0x080c, 0xe6cd, 0x0c50, 0x080c, 0xb91f, 0x6020, + 0x0006, 0x1118, 0x080c, 0xe738, 0x0c50, 0x080c, 0xb93c, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066, 0x9036, 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006, 0x3e08, 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043, - 0xffff, 0x080c, 0xacfa, 0x0180, 0x610c, 0x080c, 0xa20a, 0x6014, - 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, - 0x080c, 0xaf69, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce, + 0xffff, 0x080c, 0xad1a, 0x0180, 0x610c, 0x080c, 0xa21b, 0x6014, + 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11, + 0x080c, 0xaf89, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce, 0x00be, 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, - 0x080c, 0x6290, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005, + 0x080c, 0x628a, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005, 0x2004, 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e9, 0x7030, 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108, 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660, - 0x6043, 0xffff, 0x080c, 0xacfa, 0x0178, 0x080c, 0xa20a, 0x6014, - 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b, - 0x080c, 0x6f19, 0x080c, 0xaf69, 0x00ce, 0x0005, 0x00b6, 0x00e6, - 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4, - 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xaafc, 0x00ce, + 0x6043, 0xffff, 0x080c, 0xad1a, 0x0178, 0x080c, 0xa21b, 0x6014, + 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38, + 0x080c, 0x6f11, 0x080c, 0xaf89, 0x00ce, 0x0005, 0x00b6, 0x00e6, + 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4, + 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x2071, 0x19e9, 0x7030, 0x9005, 0x0da0, - 0x9c06, 0x190c, 0x0d85, 0x7036, 0x080c, 0x88ec, 0x7004, 0x9084, - 0x0007, 0x0002, 0x982c, 0x982e, 0x9835, 0x983f, 0x984d, 0x982c, - 0x983a, 0x982a, 0x080c, 0x0d85, 0x0428, 0x0005, 0x080c, 0xace5, + 0x9c06, 0x190c, 0x0d79, 0x7036, 0x080c, 0x88e4, 0x7004, 0x9084, + 0x0007, 0x0002, 0x9824, 0x9826, 0x982d, 0x9837, 0x9845, 0x9824, + 0x9832, 0x9822, 0x080c, 0x0d79, 0x0428, 0x0005, 0x080c, 0xad05, 0x7007, 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c, - 0xa20a, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c, - 0xacd0, 0x0140, 0x080c, 0xace5, 0x0128, 0x0066, 0x9036, 0x080c, - 0xa20a, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacd0, 0x080c, - 0xa56e, 0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00ee, 0x00be, - 0x0005, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x6044, 0xd0fc, - 0x1130, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x2069, - 0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d85, 0x6852, - 0x00e6, 0x2d70, 0x080c, 0x9478, 0x00ee, 0x080c, 0x88f9, 0x0016, - 0x2009, 0x0040, 0x080c, 0x2241, 0x001e, 0x683c, 0x9084, 0x0003, - 0x0002, 0x9887, 0x9888, 0x98a7, 0x9885, 0x080c, 0x0d85, 0x0468, + 0xa21b, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c, + 0xacf0, 0x0140, 0x080c, 0xad05, 0x0128, 0x0066, 0x9036, 0x080c, + 0xa21b, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacf0, 0x080c, + 0xa585, 0x0000, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00ee, 0x00be, + 0x0005, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x6044, 0xd0fc, + 0x1130, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00de, 0x0005, 0x2069, + 0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d79, 0x6852, + 0x00e6, 0x2d70, 0x080c, 0x9470, 0x00ee, 0x080c, 0x88f1, 0x0016, + 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x683c, 0x9084, 0x0003, + 0x0002, 0x987f, 0x9880, 0x989f, 0x987d, 0x080c, 0x0d79, 0x0490, 0x6868, 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a, - 0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x7042, - 0x684e, 0x683f, 0x0000, 0x00c8, 0x684a, 0x6846, 0x0c98, 0x686b, - 0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x9006, - 0x686a, 0x6852, 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, - 0x0000, 0x0018, 0x684e, 0x684a, 0x6846, 0x080c, 0xadc0, 0x684f, - 0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x0005, - 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x98d5, 0x98d8, 0x9d6a, - 0x9e03, 0x98d8, 0x9d6a, 0x9e03, 0x98d5, 0x98d8, 0x98d5, 0x98d5, - 0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x080c, 0x97fe, 0x0005, - 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, - 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, - 0x0053, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, - 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9944, 0x005b, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, - 0x00be, 0x0005, 0x9aed, 0x9b28, 0x9b51, 0x9bf9, 0x9c1b, 0x9c21, - 0x9c2e, 0x9c36, 0x9c42, 0x9c48, 0x9c59, 0x9c48, 0x9cb1, 0x9c36, - 0x9cbd, 0x9cc3, 0x9c42, 0x9cc3, 0x9ccf, 0x9942, 0x9942, 0x9942, - 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, - 0xa22b, 0xa24e, 0xa25f, 0xa27f, 0xa2b1, 0x9c2e, 0x9942, 0x9c2e, - 0x9c48, 0x9942, 0x9b51, 0x9bf9, 0x9942, 0xa66c, 0x9c48, 0x9942, - 0xa688, 0x9c48, 0x9942, 0x9c42, 0x9ae7, 0x9965, 0x9942, 0xa6a4, - 0xa711, 0xa7f5, 0x9942, 0xa802, 0x9c2b, 0xa82d, 0x9942, 0xa2bb, - 0xa839, 0x9942, 0x080c, 0x0d85, 0x2100, 0x005b, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, - 0x0005, 0xa8d9, 0xa98b, 0x9963, 0x999d, 0x9a49, 0x9a54, 0x9963, - 0x9c2e, 0x9963, 0x9aae, 0x9aba, 0x99b8, 0x9963, 0x99d3, 0x9a07, - 0xadd4, 0xae19, 0x9c48, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x080c, - 0x9ce2, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, - 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, - 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, - 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, - 0x080c, 0xa05a, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, - 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xae60, 0x1118, 0x9084, - 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, - 0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, - 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, - 0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a, 0x009e, 0x00de, 0x0005, - 0x00d6, 0x0096, 0x080c, 0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048, - 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, - 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a, - 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, - 0x080c, 0x9ce2, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, - 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, - 0x200c, 0x2001, 0x0001, 0x080c, 0x2226, 0x080c, 0xd9e6, 0x9006, - 0x080c, 0x2226, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, - 0x04d9, 0x080c, 0xa05a, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, - 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d2d, 0x20e9, 0x0000, - 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, - 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, - 0x200c, 0x080c, 0xd9e6, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, - 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x100b, 0x080c, 0xa05a, - 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, - 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, - 0x0005, 0x080c, 0x9ce2, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, - 0x60c3, 0x0008, 0x0804, 0xa05a, 0x00d6, 0x00e6, 0x080c, 0x9d2d, - 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, - 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, - 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, - 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, - 0x9a74, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, - 0x1f04, 0x9a7d, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, - 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110, - 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, - 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, - 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9a94, 0x60c3, - 0x004c, 0x080c, 0xa05a, 0x00ee, 0x00de, 0x0005, 0x080c, 0x9ce2, - 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, - 0x0804, 0xa05a, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9d2d, 0x7003, - 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, - 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148, 0x2073, - 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, - 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, - 0x62c2, 0x080c, 0xa05a, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, - 0x1818, 0x2004, 0x609a, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003, - 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, - 0x080c, 0x26d5, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, - 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0xae60, - 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, - 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, - 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0xa05a, - 0x080c, 0x9ce2, 0x7003, 0x0500, 0x080c, 0xae60, 0x1120, 0xb8a0, - 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, - 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, - 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, - 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, - 0xa05a, 0x080c, 0x9ce2, 0x9006, 0x080c, 0x6b9f, 0xb8a0, 0x9086, - 0x007e, 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, - 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, - 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bc0, - 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, - 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, 0xae77, - 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, - 0x0090, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808, 0x080c, 0x76a5, - 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, - 0xae77, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, - 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, - 0xa8c0, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, - 0x080c, 0x582a, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, - 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e, - 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, - 0x2716, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, - 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, - 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x024e, - 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804, - 0xa05a, 0x080c, 0x9ce2, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, - 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, - 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, - 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9c92, 0x7026, 0x60c3, - 0x0014, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003, 0x5000, 0x0804, - 0x9b6b, 0x080c, 0x9ce2, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, - 0x0014, 0x0804, 0xa05a, 0x080c, 0x9d24, 0x0010, 0x080c, 0x9d2d, - 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x080c, 0x9d2d, - 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, - 0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0200, 0x0804, 0x9b6b, - 0x080c, 0x9d2d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, - 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, - 0xa05a, 0x00d6, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014, - 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, - 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, - 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, - 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, - 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, - 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, - 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, - 0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, - 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, - 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, - 0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, - 0x0100, 0x60c3, 0x0014, 0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003, - 0x0200, 0x0804, 0x9af1, 0x080c, 0x9d2d, 0x7003, 0x0100, 0x700b, - 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x080c, - 0x9d2d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, - 0xa05a, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, - 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, - 0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810, 0x9305, 0x7002, 0xb814, - 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, - 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a, - 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, - 0x0005, 0x0026, 0x080c, 0xa8d5, 0x7003, 0x02ff, 0x7007, 0xfffc, - 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, - 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, - 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, - 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, - 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810, - 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, - 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, - 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, - 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a, 0x7a08, - 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, - 0xa04e, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, - 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, - 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, - 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, - 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x0005, 0x9d9b, 0x9daa, 0x9db5, 0x9d99, - 0x9d99, 0x9d99, 0x9d9b, 0x9d99, 0x9d99, 0x9d99, 0x9d99, 0x9d99, - 0x9d99, 0x080c, 0x0d85, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, - 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, - 0x0804, 0xa05a, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, - 0xffff, 0x60c3, 0x000c, 0x0804, 0xa05a, 0x04a1, 0x7003, 0x0003, - 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x0026, 0x080c, - 0xa8d5, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, - 0x9cfd, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8400, 0x7002, + 0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, + 0x684e, 0x683f, 0x0000, 0x00f0, 0x684a, 0x6846, 0x0c98, 0x686b, + 0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x6044, + 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, 0x686a, 0x6852, + 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, 0x0000, 0x0010, + 0x684a, 0x6846, 0x080c, 0xade0, 0x684f, 0x0000, 0x010e, 0x090c, + 0xab13, 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084, 0x000f, + 0x000b, 0x0005, 0x98d2, 0x98d5, 0x9d7b, 0x9e14, 0x98d5, 0x9d7b, + 0x9e14, 0x98d2, 0x98d5, 0x98d2, 0x98d2, 0x98d2, 0x98d2, 0x98d2, + 0x98d2, 0x98d2, 0x080c, 0x97f6, 0x0005, 0x00b6, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, + 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d79, + 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, + 0x0040, 0x1a04, 0x9941, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9aea, + 0x9b25, 0x9b4e, 0x9c0a, 0x9c2c, 0x9c32, 0x9c3f, 0x9c47, 0x9c53, + 0x9c59, 0x9c6a, 0x9c59, 0x9cc2, 0x9c47, 0x9cce, 0x9cd4, 0x9c53, + 0x9cd4, 0x9ce0, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, + 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0xa23c, 0xa25f, 0xa270, + 0xa290, 0xa2c2, 0x9c3f, 0x993f, 0x9c3f, 0x9c59, 0x993f, 0x9b4e, + 0x9c0a, 0x993f, 0xa683, 0x9c59, 0x993f, 0xa69f, 0x9c59, 0x993f, + 0x9c53, 0x9ae4, 0x9962, 0x993f, 0xa6bb, 0xa728, 0xa80c, 0x993f, + 0xa819, 0x9c3c, 0xa844, 0x993f, 0xa2cc, 0xa850, 0x993f, 0x080c, + 0x0d79, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xa8f0, 0xa9a2, + 0x9960, 0x999a, 0x9a46, 0x9a51, 0x9960, 0x9c3f, 0x9960, 0x9aab, + 0x9ab7, 0x99b5, 0x9960, 0x99d0, 0x9a04, 0xadf4, 0xae39, 0x9c59, + 0x080c, 0x0d79, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x0026, 0x0036, + 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, + 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, + 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, + 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa06b, 0x003e, + 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, + 0x00be, 0x080c, 0xae80, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, + 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x7003, 0x0500, + 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, + 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, + 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, + 0x9cf3, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, + 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, + 0x701e, 0x60c3, 0x0010, 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9cf3, 0x20e9, + 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x2001, 0x0001, + 0x080c, 0x2222, 0x080c, 0xda05, 0x9006, 0x080c, 0x2222, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa06b, + 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9d3e, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003, + 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x080c, 0xda05, + 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, + 0x2048, 0x080c, 0x0fff, 0x080c, 0xa06b, 0x012e, 0x009e, 0x00de, + 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, + 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9cf3, + 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, + 0xa06b, 0x00d6, 0x00e6, 0x080c, 0x9d3e, 0x7814, 0x9084, 0xff00, + 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, + 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, + 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a71, 0x2069, 0x1801, + 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a7a, 0x9096, + 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, + 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9, + 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, + 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, + 0x8d68, 0x8e70, 0x1f04, 0x9a91, 0x60c3, 0x004c, 0x080c, 0xa06b, + 0x00ee, 0x00de, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x6300, 0x7007, + 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, 0x00d6, + 0x0026, 0x0016, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x7814, 0x700e, + 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, + 0x1925, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, + 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, + 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa06b, + 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, + 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5200, 0x2069, 0x1847, + 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26d4, 0x710e, + 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x0254, 0x4003, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082, + 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, + 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, + 0x7036, 0x60c3, 0x001c, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, + 0x0500, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, + 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, + 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, + 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x080c, 0x9cf3, + 0x9006, 0x080c, 0x6b97, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, + 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, + 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, + 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, + 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bd1, 0x00d6, 0x2069, 0x196d, + 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, + 0x9084, 0x2000, 0x7012, 0x080c, 0xae97, 0x680c, 0x7016, 0x701f, + 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a, + 0x6804, 0x700e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x769d, 0x1128, + 0x78e3, 0x0000, 0x080c, 0x2715, 0x78e2, 0x00fe, 0x6808, 0x080c, + 0x769d, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, + 0x080c, 0xae97, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, + 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, + 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, + 0x080c, 0xa8d7, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd, + 0x7002, 0x080c, 0x5824, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, + 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, + 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, + 0x080c, 0x2715, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, + 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, + 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8d7, 0x20a1, + 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074, + 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x2010, 0x7007, 0x0014, + 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, + 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, + 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9ca3, 0x7026, + 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5000, + 0x0804, 0x9b70, 0x080c, 0x9cf3, 0x7003, 0x2110, 0x7007, 0x0014, + 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d35, 0x0010, 0x080c, + 0x9d3e, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x080c, + 0x9d3e, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, + 0x0008, 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x0804, + 0x9b70, 0x080c, 0x9d3e, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, + 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0xa06b, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007, + 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, + 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, + 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, + 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, + 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, + 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, + 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, + 0x0150, 0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, + 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, + 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, + 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007, 0x0014, + 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d3e, + 0x7003, 0x0200, 0x0804, 0x9aee, 0x080c, 0x9d3e, 0x7003, 0x0100, + 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x080c, 0x9d3e, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, + 0x0804, 0xa06b, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, + 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, + 0x2200, 0x2021, 0x0100, 0x080c, 0xa8ec, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, - 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, - 0x0804, 0x9d5f, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8500, + 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f, + 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, + 0x002e, 0x0005, 0x0026, 0x080c, 0xa8ec, 0x7003, 0x02ff, 0x7007, + 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, + 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, + 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8ec, + 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, + 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, + 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, + 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f, 0x721a, + 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, + 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, + 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, + 0x0d79, 0x908a, 0x0092, 0x1a0c, 0x0d79, 0x6110, 0x2158, 0xb984, + 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9dac, 0x9dbb, 0x9dc6, + 0x9daa, 0x9daa, 0x9daa, 0x9dac, 0x9daa, 0x9daa, 0x9daa, 0x9daa, + 0x9daa, 0x9daa, 0x080c, 0x0d79, 0x0411, 0x60c3, 0x0000, 0x0026, + 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, + 0x002e, 0x0804, 0xa06b, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, + 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa06b, 0x04a1, 0x7003, + 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x0026, + 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, + 0x0804, 0x9d0e, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, - 0x7012, 0x0804, 0x9d5f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, - 0x0a0c, 0x0d85, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x7910, 0x2158, - 0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e38, 0x9e38, 0x9e38, - 0x9e69, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, - 0xa428, 0xa42d, 0xa432, 0xa437, 0x9e38, 0x9e38, 0x9e38, 0xa423, - 0x080c, 0x0d85, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084, - 0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001, 0x1b72, - 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, 0x7b4e, - 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, - 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, - 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, - 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, - 0x0005, 0x9e79, 0x9e79, 0x9e7b, 0x9e79, 0x9e79, 0x9e79, 0x9e95, - 0x9e79, 0x080c, 0x0d85, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, - 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, - 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, - 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa05a, 0x2009, 0x0003, 0x0019, - 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8d5, 0x001e, 0xb810, - 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, - 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, - 0x080c, 0xa04e, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, - 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, - 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, - 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, - 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, - 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, - 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, - 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, - 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, - 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, - 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, - 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, 0x6028, - 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, 0x2af5, - 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2b04, 0x2009, 0x07d0, - 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, - 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, - 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582, - 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x3489, - 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480, - 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80, - 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, - 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072, - 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c, - 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, - 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, - 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, - 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803, - 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2b04, 0x2009, - 0x07d0, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, - 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, - 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, - 0x7820, 0x0002, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, - 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fdb, 0x9fd9, 0x9fd9, 0x9fd9, - 0x9fd9, 0x080c, 0x0d85, 0xb884, 0x609e, 0x7814, 0x2048, 0xa87c, - 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, - 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, - 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, - 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, - 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, 0x0050, - 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, - 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, - 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, - 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, - 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, - 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, - 0x080c, 0xa8b5, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, - 0x0110, 0x2009, 0x1b58, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, - 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294, - 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b, 0x0001, - 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, - 0x88e3, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, - 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88e3, 0x001e, 0x0005, - 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000, - 0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026, - 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2b04, 0x002e, 0x001e, - 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaae0, 0x0106, - 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009, - 0x1804, 0x2011, 0x0008, 0x080c, 0x2b04, 0x002e, 0x001e, 0x010e, - 0x090c, 0xaafc, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, - 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, - 0x2069, 0x0140, 0x080c, 0x76a5, 0x1510, 0x2001, 0x1a0e, 0x2004, - 0x9005, 0x1904, 0xa109, 0x080c, 0x7747, 0x11a8, 0x2069, 0x0380, - 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020, - 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d85, 0x6843, 0x0100, - 0x080c, 0x88e3, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0, 0x6904, - 0x9194, 0x4000, 0x0598, 0x080c, 0xa08a, 0x080c, 0x2acb, 0x00c6, - 0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136, - 0x080c, 0xaae0, 0x6130, 0x080c, 0xaafc, 0x00ce, 0x81ff, 0x01c8, - 0x080c, 0x88e3, 0x080c, 0xa07d, 0x00a0, 0x080c, 0xaae0, 0x6130, - 0x91e5, 0x0000, 0x0150, 0x080c, 0xeb92, 0x080c, 0x88ec, 0x6003, - 0x0001, 0x2009, 0x0014, 0x080c, 0xafcc, 0x080c, 0xaafc, 0x00ce, - 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0e, - 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192, - 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88e3, 0x080c, - 0x6039, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, - 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f9, 0x080c, - 0xaae0, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9, 0x714c, - 0x81ff, 0x0904, 0xa1c3, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, - 0x76a5, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa380, 0x003e, - 0x080c, 0xeb92, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, 0x6220, - 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, - 0x004a, 0x6003, 0x0003, 0x080c, 0xafcc, 0x2001, 0x0386, 0x2003, - 0x5040, 0x080c, 0x7747, 0x0804, 0xa1c3, 0x6904, 0xd1f4, 0x0904, - 0xa1d0, 0x080c, 0x2acb, 0x00c6, 0x704c, 0x9065, 0x090c, 0x0d85, - 0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, 0x9105, - 0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, 0x6214, - 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, 0x0010, - 0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, - 0x704c, 0x2060, 0x080c, 0x9859, 0x2009, 0x0049, 0x080c, 0xafcc, - 0x0450, 0x080c, 0xeb92, 0x704c, 0x9065, 0x9086, 0x1b56, 0x1158, - 0x080c, 0xad9e, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000, 0x6066, - 0x080c, 0x6039, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, - 0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, - 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, - 0x0003, 0x080c, 0xafcc, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c, - 0xaafc, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, - 0xd1ec, 0x1904, 0xa169, 0x0804, 0xa16b, 0x0026, 0x00e6, 0x2071, - 0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff, - 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, - 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2b04, 0x0048, - 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, - 0x2b04, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3, 0x2004, - 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085, - 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006, 0x600e, - 0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, 0x1118, - 0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, 0x610e, - 0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa441, 0x080c, - 0xce07, 0x00fe, 0x0005, 0x080c, 0x9ce2, 0x7003, 0x1200, 0x7838, - 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, - 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, - 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a, - 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa05a, 0x080c, 0x9ce2, - 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, - 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x0156, - 0x080c, 0x9d2d, 0x7003, 0x0200, 0x080c, 0x89b1, 0x20a9, 0x0006, - 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072, - 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, - 0x1f04, 0xa26e, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a, 0x0016, - 0x0026, 0x080c, 0x9d09, 0x080c, 0x9d1b, 0x9e80, 0x0004, 0x20e9, - 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, - 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, - 0x8003, 0x60c2, 0x080c, 0xa05a, 0x002e, 0x001e, 0x0005, 0x20a9, - 0x0010, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x0240, 0x22a8, 0x4003, - 0x0c68, 0x080c, 0x9ce2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, - 0x0008, 0x0804, 0xa05a, 0x0016, 0x0026, 0x080c, 0x9ce2, 0x20e9, - 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, - 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa05a, - 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c, - 0xce2d, 0x1110, 0x080c, 0xb91f, 0x600c, 0x0006, 0x080c, 0xd0a9, - 0x600f, 0x0000, 0x080c, 0xaf2e, 0x080c, 0xa441, 0x00ce, 0x0c68, - 0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, - 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, - 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, - 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, - 0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa08a, 0x6ac0, 0x68c3, - 0x0000, 0x080c, 0x88ec, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaa11, - 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97fe, 0x6044, 0xd0ac, - 0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013, - 0x080c, 0xafcc, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, - 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x88ec, - 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, - 0x68c3, 0x0000, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x20a9, 0x01f4, - 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, - 0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd084, 0x0118, 0x6827, - 0x0001, 0x0010, 0x1f04, 0xa362, 0x7804, 0x9084, 0x1000, 0x0138, - 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x0005, - 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, - 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, - 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x0380, - 0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c, 0x2060, - 0x8cff, 0x0904, 0xa3fd, 0x080c, 0xad50, 0x0904, 0xa3fd, 0x9386, - 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa3fd, 0x68af, - 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, - 0x68cb, 0x0008, 0x080c, 0x88f9, 0x080c, 0x1e65, 0x2001, 0x0032, - 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, - 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, - 0x7804, 0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd08c, 0x0118, - 0x6827, 0x0002, 0x0010, 0x1f04, 0xa3cb, 0x7804, 0x9084, 0x1000, - 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, - 0x6827, 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020, - 0x9086, 0x0009, 0x0150, 0x080c, 0x9859, 0x6044, 0xd0ac, 0x1118, - 0x6003, 0x0002, 0x0010, 0x080c, 0xafcc, 0x000e, 0x2071, 0x0380, - 0xd08c, 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, - 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, - 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e, - 0x012e, 0x00de, 0x0005, 0x080c, 0x9e3a, 0x7047, 0x1000, 0x0098, - 0x080c, 0x9e3a, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e3a, 0x7047, - 0x2000, 0x0048, 0x080c, 0x9e3a, 0x7047, 0x0400, 0x0020, 0x080c, - 0x9e3a, 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804, - 0xa05a, 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001, - 0x702e, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, - 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620, - 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4e6, 0x8cff, - 0x0904, 0xa4e6, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4e1, 0x88ff, - 0x0138, 0x2800, 0x9c06, 0x1904, 0xa4e1, 0x2039, 0x0000, 0x0050, - 0x6010, 0x9b06, 0x1904, 0xa4e1, 0x85ff, 0x0120, 0x605c, 0x9106, - 0x1904, 0xa4e1, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, - 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, - 0x88ec, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0428, 0x080c, 0x88ec, - 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, - 0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, - 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, - 0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, - 0x6827, 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, - 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, - 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, - 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, - 0x0096, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c, 0xe6cd, 0x009e, - 0x080c, 0xaf69, 0x080c, 0xa441, 0x88ff, 0x1190, 0x00ce, 0x0804, - 0xa45c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa45c, 0x9006, 0x012e, - 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, - 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904, - 0xa55d, 0x6020, 0x9086, 0x0006, 0x1904, 0xa558, 0x87ff, 0x0128, - 0x2700, 0x9c06, 0x1904, 0xa558, 0x0048, 0x6010, 0x9b06, 0x1904, - 0xa558, 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06, - 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f, 0x0000, - 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0, 0x003e, + 0x7012, 0x0804, 0x9d70, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085, + 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, + 0xc0bc, 0x7012, 0x0804, 0x9d70, 0x00b6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, + 0x0040, 0x0a0c, 0x0d79, 0x908a, 0x0057, 0x1a0c, 0x0d79, 0x7910, + 0x2158, 0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e49, 0x9e49, + 0x9e49, 0x9e7a, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49, + 0x9e49, 0xa43f, 0xa444, 0xa449, 0xa44e, 0x9e49, 0x9e49, 0x9e49, + 0xa43a, 0x080c, 0x0d79, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, + 0xd084, 0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001, + 0x1b72, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, + 0x7b4e, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, + 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, + 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, + 0xffff, 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, + 0x001e, 0x0005, 0x9e8a, 0x9e8a, 0x9e8c, 0x9e8a, 0x9e8a, 0x9e8a, + 0x9ea6, 0x9e8a, 0x080c, 0x0d79, 0x7914, 0x918c, 0x08ff, 0x918d, + 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, + 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, + 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa06b, 0x2009, 0x0003, + 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8ec, 0x001e, + 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, + 0x7116, 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, + 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, + 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, + 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, + 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, + 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, + 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, + 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, + 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, + 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, + 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, + 0x2adc, 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2aeb, 0x2009, + 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, + 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, + 0x3474, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, + 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, + 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, + 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, + 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, + 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, + 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, + 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, + 0x95d5, 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, + 0x7803, 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2aeb, + 0x2009, 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, + 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, + 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, + 0x7480, 0x7820, 0x0002, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea, + 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fec, 0x9fea, 0x9fea, + 0x9fea, 0x9fea, 0x080c, 0x0d79, 0xb884, 0x609e, 0x7814, 0x2048, + 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, + 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, + 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, + 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, + 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, + 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, + 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, + 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, + 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, + 0x60c6, 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0x080c, 0xa8cc, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, + 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x88e9, 0x003e, 0x004e, + 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, + 0x9294, 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b, + 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, + 0x080c, 0x88db, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, + 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88db, 0x001e, + 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, + 0x0000, 0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, + 0x0026, 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2aeb, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaaf7, + 0x0106, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, + 0x2009, 0x1804, 0x2011, 0x0008, 0x080c, 0x2aeb, 0x002e, 0x001e, + 0x010e, 0x090c, 0xab13, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, + 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, + 0x0100, 0x2069, 0x0140, 0x080c, 0x769d, 0x1510, 0x2001, 0x1a0e, + 0x2004, 0x9005, 0x1904, 0xa11a, 0x080c, 0x773f, 0x11a8, 0x2069, + 0x0380, 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, + 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d79, 0x6843, + 0x0100, 0x080c, 0x88db, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0, + 0x6904, 0x9194, 0x4000, 0x0598, 0x080c, 0xa09b, 0x080c, 0x2ab2, + 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, + 0x6136, 0x080c, 0xaaf7, 0x6130, 0x080c, 0xab13, 0x00ce, 0x81ff, + 0x01c8, 0x080c, 0x88db, 0x080c, 0xa08e, 0x00a0, 0x080c, 0xaaf7, + 0x6130, 0x91e5, 0x0000, 0x0150, 0x080c, 0xebfd, 0x080c, 0x88e4, + 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x080c, 0xab13, + 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, + 0x1a0e, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134, + 0x9192, 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88db, + 0x080c, 0x6033, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, + 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f1, + 0x080c, 0xaaf7, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9, + 0x714c, 0x81ff, 0x0904, 0xa1d4, 0x2061, 0x0100, 0x2069, 0x0140, + 0x080c, 0x769d, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa391, + 0x003e, 0x080c, 0xebfd, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, + 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, + 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0386, + 0x2003, 0x5040, 0x080c, 0x773f, 0x0804, 0xa1d4, 0x6904, 0xd1f4, + 0x0904, 0xa1e1, 0x080c, 0x2ab2, 0x00c6, 0x704c, 0x9065, 0x090c, + 0x0d79, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, + 0x9105, 0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, + 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, + 0x0010, 0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, + 0x6016, 0x704c, 0x2060, 0x080c, 0x9851, 0x2009, 0x0049, 0x080c, + 0xafec, 0x0450, 0x080c, 0xebfd, 0x704c, 0x9065, 0x9086, 0x1b56, + 0x1158, 0x080c, 0xadbe, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000, + 0x6066, 0x080c, 0x6033, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, + 0xa391, 0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, + 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, + 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0387, 0x2003, 0x0200, + 0x080c, 0xab13, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, + 0x0005, 0xd1ec, 0x1904, 0xa17a, 0x0804, 0xa17c, 0x0026, 0x00e6, + 0x2071, 0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, + 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, + 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2aeb, + 0x0048, 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, + 0x080c, 0x2aeb, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3, + 0x2004, 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, + 0x9085, 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006, + 0x600e, 0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, + 0x1118, 0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, + 0x610e, 0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa458, + 0x080c, 0xce24, 0x00fe, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x1200, + 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, + 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, + 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, + 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa06b, 0x080c, + 0x9cf3, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, + 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x0156, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x080c, 0x89a9, 0x20a9, + 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, + 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, + 0x0002, 0x1f04, 0xa27f, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b, + 0x0016, 0x0026, 0x080c, 0x9d1a, 0x080c, 0x9d2c, 0x9e80, 0x0004, + 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, + 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, + 0x0004, 0x8003, 0x60c2, 0x080c, 0xa06b, 0x002e, 0x001e, 0x0005, + 0x20a9, 0x0010, 0x4003, 0x080c, 0xa8d7, 0x20a1, 0x0240, 0x22a8, + 0x4003, 0x0c68, 0x080c, 0x9cf3, 0x7003, 0x6200, 0x7808, 0x700e, + 0x60c3, 0x0008, 0x0804, 0xa06b, 0x0016, 0x0026, 0x080c, 0x9cf3, + 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, + 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, + 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, + 0xa06b, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188, + 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, 0x600c, 0x0006, 0x080c, + 0xd0c6, 0x600f, 0x0000, 0x080c, 0xaf4e, 0x080c, 0xa458, 0x00ce, + 0x0c68, 0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19e9, 0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa09b, 0x6ac0, + 0x68c3, 0x0000, 0x080c, 0x88e4, 0x00c6, 0x2061, 0x0100, 0x080c, + 0xaa28, 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97f6, 0x6044, + 0xd0ac, 0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009, + 0x0013, 0x080c, 0xafec, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, + 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, + 0x88e4, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, + 0x0008, 0x68c3, 0x0000, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x20a9, + 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, + 0x7804, 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd084, 0x0118, + 0x6827, 0x0001, 0x0010, 0x1f04, 0xa373, 0x7804, 0x9084, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x0380, 0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c, + 0x2060, 0x8cff, 0x0904, 0xa414, 0x080c, 0xad70, 0x0904, 0xa414, + 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa414, + 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, + 0x69c6, 0x68cb, 0x0008, 0x080c, 0x88f1, 0x080c, 0x1e61, 0x2001, + 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, + 0x0008, 0x692e, 0x0016, 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, + 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0xa3e2, 0x7804, 0x9084, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x6827, + 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020, 0x9086, + 0x0009, 0x0150, 0x080c, 0x9851, 0x6044, 0xd0ac, 0x1118, 0x6003, + 0x0002, 0x0010, 0x080c, 0xafec, 0x000e, 0x2071, 0x0380, 0xd08c, + 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, + 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e, 0x012e, + 0x00de, 0x0005, 0x080c, 0x9e4b, 0x7047, 0x1000, 0x0098, 0x080c, + 0x9e4b, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e4b, 0x7047, 0x2000, + 0x0048, 0x080c, 0x9e4b, 0x7047, 0x0400, 0x0020, 0x080c, 0x9e4b, + 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa06b, + 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001, 0x702e, + 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620, 0x2660, + 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4fd, 0x8cff, 0x0904, + 0xa4fd, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4f8, 0x88ff, 0x0138, + 0x2800, 0x9c06, 0x1904, 0xa4f8, 0x2039, 0x0000, 0x0050, 0x6010, + 0x9b06, 0x1904, 0xa4f8, 0x85ff, 0x0120, 0x605c, 0x9106, 0x1904, + 0xa4f8, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x88e4, + 0x080c, 0xa585, 0x7033, 0x0000, 0x0428, 0x080c, 0x88e4, 0x6820, + 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, + 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010, + 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, + 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738, 0x009e, 0x080c, + 0xaf89, 0x080c, 0xa458, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa473, + 0x2c78, 0x600c, 0x2060, 0x0804, 0xa473, 0x9006, 0x012e, 0x000e, + 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, + 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, + 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa574, + 0x6020, 0x9086, 0x0006, 0x1904, 0xa56f, 0x87ff, 0x0128, 0x2700, + 0x9c06, 0x1904, 0xa56f, 0x0048, 0x6010, 0x9b06, 0x1904, 0xa56f, + 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06, 0x1178, + 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f, 0x0000, 0x9006, + 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0, 0x003e, 0x7048, + 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738, + 0x080c, 0xaf89, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa51d, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xa51d, 0x9006, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, + 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e9, + 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, + 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10, + 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, - 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, - 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c, - 0xe6cd, 0x080c, 0xaf69, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa506, - 0x2c78, 0x600c, 0x2060, 0x0804, 0xa506, 0x9006, 0x012e, 0x000e, - 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, - 0x19e9, 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158, - 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, - 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, - 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, - 0x2c10, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, - 0x1508, 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, - 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, - 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, - 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97fe, 0x9085, - 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, - 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, - 0xa65b, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, - 0xa656, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, - 0x0904, 0xa62d, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e, - 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, - 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, - 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, - 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, - 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, - 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, - 0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c, 0x333f, 0x080c, - 0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c, 0xa56e, 0x6824, - 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce2d, 0x1118, - 0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0168, - 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07, 0x080c, 0xd0a9, 0x080c, - 0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xa5d6, 0x2c78, 0x600c, - 0x2060, 0x0804, 0xa5d6, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, - 0x1d20, 0x080c, 0xe6cd, 0x0c08, 0x00d6, 0x080c, 0x9d2d, 0x7003, - 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, - 0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, - 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa05a, 0x00de, 0x0005, - 0x080c, 0x9d2d, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, - 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084, - 0x00ff, 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007, - 0x7006, 0x60c2, 0x0804, 0xa05a, 0x00b6, 0x00d6, 0x0016, 0x00d6, - 0x2f68, 0x2009, 0x0035, 0x080c, 0xd2b6, 0x00de, 0x1904, 0xa709, - 0x080c, 0x9ce2, 0x7003, 0x1300, 0x782c, 0x080c, 0xa818, 0x2068, - 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, - 0xae60, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, - 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, - 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, - 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, - 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8, - 0x080c, 0xae60, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, - 0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, - 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, - 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa05a, 0x00be, - 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, - 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, - 0x9186, 0x0003, 0x0904, 0xa788, 0x9186, 0x0005, 0x0904, 0xa770, - 0x9186, 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa779, 0x7807, - 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa7f5, 0x0005, - 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, - 0x6800, 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa750, 0xa75b, 0xa752, - 0xa75b, 0xa757, 0xa750, 0xa750, 0xa75b, 0xa75b, 0xa75b, 0xa75b, - 0xa750, 0xa750, 0xa750, 0xa750, 0xa750, 0xa75b, 0xa750, 0xa75b, - 0x080c, 0x0d85, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, - 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, - 0xa7af, 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, - 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7af, - 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, - 0x04b0, 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, - 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438, - 0x0469, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, - 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, - 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004, - 0xd0fc, 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, - 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, - 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa05a, 0x00b6, 0x0036, - 0x0046, 0x0056, 0x0066, 0x080c, 0x9d2d, 0x9006, 0x7003, 0x0200, - 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, - 0xae60, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, - 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, - 0x00de, 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c, - 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, - 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, - 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d2d, 0x7003, - 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, - 0x0804, 0xa05a, 0x080c, 0x9cd9, 0x7003, 0x1400, 0x7838, 0x700a, - 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, - 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa05a, - 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, - 0x2058, 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e, - 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d24, 0x7003, - 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, - 0xa05a, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, - 0x0026, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, - 0x2012, 0x002e, 0x080c, 0xa07d, 0x080c, 0x88e3, 0x0005, 0x0036, - 0x0096, 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0, - 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, - 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, - 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, - 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x00de, 0x20e9, 0x0000, - 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, - 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, - 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, - 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, - 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, - 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4, - 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, - 0x0036, 0x0026, 0x2110, 0x900e, 0x080c, 0x2b04, 0x002e, 0x0005, - 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, - 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, - 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, - 0x0005, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, - 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, - 0x1138, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa97a, - 0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, - 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, - 0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, - 0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, - 0xa90b, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, - 0x8210, 0x1f04, 0xa915, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, - 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, - 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8c0, - 0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, - 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, - 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, - 0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, - 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, - 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, - 0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x76a5, 0x0150, 0x6028, - 0xc0bd, 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2b04, - 0x0010, 0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e, - 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, - 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, - 0x00ee, 0x0804, 0xa8f0, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096, - 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, - 0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, - 0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, - 0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, - 0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, + 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97f6, 0x9085, 0x0001, + 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa672, + 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa66d, + 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, + 0xa644, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, + 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a, 0x080c, 0xce4a, + 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585, 0x6824, 0xd084, + 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0168, 0x6020, + 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, + 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xd0c6, 0x080c, 0xaf89, + 0x080c, 0xa458, 0x00ce, 0x0804, 0xa5ed, 0x2c78, 0x600c, 0x2060, + 0x0804, 0xa5ed, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, + 0x080c, 0xe738, 0x0c08, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0200, + 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a, + 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, + 0x0004, 0x7027, 0x7878, 0x080c, 0xa06b, 0x00de, 0x0005, 0x080c, + 0x9d3e, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, + 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff, + 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007, 0x7006, + 0x60c2, 0x0804, 0xa06b, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, + 0x2009, 0x0035, 0x080c, 0xd2d3, 0x00de, 0x1904, 0xa720, 0x080c, + 0x9cf3, 0x7003, 0x1300, 0x782c, 0x080c, 0xa82f, 0x2068, 0x6820, + 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xae80, + 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, + 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, + 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, + 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c, + 0xae80, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, + 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, + 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, + 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa06b, 0x00be, 0x0005, + 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, + 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, + 0x0003, 0x0904, 0xa79f, 0x9186, 0x0005, 0x0904, 0xa787, 0x9186, + 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa790, 0x7807, 0x0037, + 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa80c, 0x0005, 0x080c, + 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, + 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa767, 0xa772, 0xa769, 0xa772, + 0xa76e, 0xa767, 0xa767, 0xa772, 0xa772, 0xa772, 0xa772, 0xa767, + 0xa767, 0xa767, 0xa767, 0xa767, 0xa772, 0xa767, 0xa772, 0x080c, + 0x0d79, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, + 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xa7c6, + 0x080c, 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7c6, 0x080c, + 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0, + 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, + 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438, 0x0469, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, + 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, + 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc, + 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, + 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, + 0x0018, 0x002e, 0x00de, 0x0804, 0xa06b, 0x00b6, 0x0036, 0x0046, + 0x0056, 0x0066, 0x080c, 0x9d3e, 0x9006, 0x7003, 0x0200, 0x7938, + 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xae80, + 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, + 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, + 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, + 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, + 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, + 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d3e, 0x7003, 0x0100, + 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, + 0xa06b, 0x080c, 0x9cea, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, + 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, + 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x00e6, + 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, + 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e, 0x00be, + 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d35, 0x7003, 0x0100, + 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, + 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, + 0x002e, 0x080c, 0xa08e, 0x080c, 0x88db, 0x0005, 0x0036, 0x0096, + 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, + 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, + 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, + 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, + 0x2069, 0x0200, 0x080c, 0xa8ec, 0x00de, 0x20e9, 0x0000, 0x20a1, + 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, + 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, + 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, + 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, + 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, + 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c, + 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, + 0x0026, 0x2110, 0x900e, 0x080c, 0x2aeb, 0x002e, 0x0005, 0x2009, + 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, + 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, + 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, + 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, + 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, + 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa991, 0x7003, + 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, + 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, + 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, + 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa922, + 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, + 0x1f04, 0xa92c, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, + 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, + 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d7, 0x00de, + 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, - 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, - 0x1f04, 0xa9cc, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, - 0x8108, 0x8210, 0x1f04, 0xa9d6, 0x00d6, 0x0016, 0x2069, 0x0200, - 0x080c, 0xa8c0, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, - 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, - 0x1f04, 0xa9ec, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, - 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, - 0xa9fd, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, - 0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e, 0x001e, - 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, - 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, - 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, - 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, - 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, - 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, - 0x8cff, 0x0904, 0xaabd, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, - 0x68c0, 0x9005, 0x0904, 0xaa8f, 0x080c, 0xa08a, 0x68c3, 0x0000, - 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, - 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, - 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, - 0x0001, 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, - 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, - 0x700f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c, - 0x333f, 0x080c, 0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c, - 0xa56e, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, - 0xce2d, 0x1118, 0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c, - 0xcc14, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c, - 0xd0a9, 0x080c, 0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xaa40, - 0x2c78, 0x600c, 0x2060, 0x0804, 0xaa40, 0x7013, 0x0000, 0x700f, - 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, - 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe6cd, - 0x08f0, 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8, - 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005, - 0x0016, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, - 0x1188, 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382, - 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0, - 0x080c, 0x0d85, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, - 0x0007, 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, - 0x0005, 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9, - 0x0469, 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, - 0x1000, 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab19, 0x080c, 0x0d85, - 0x080c, 0xaae0, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, - 0x080c, 0x97fe, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, - 0x7042, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x080c, 0x9859, 0x010e, - 0x1919, 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, - 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, - 0x2400, 0x7808, 0xd0a4, 0x190c, 0x0d7e, 0xd09c, 0x0128, 0x7820, - 0x908c, 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab66, 0xaba4, - 0xabce, 0xac05, 0xac15, 0xac26, 0xac35, 0xac43, 0xac70, 0xac74, - 0xab66, 0xab66, 0xac77, 0xac93, 0xab66, 0xab66, 0x080c, 0x0d85, - 0x012e, 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, - 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0012, 0x012e, 0x0005, - 0xab8b, 0xab8d, 0xab8b, 0xab93, 0xab8b, 0xab8b, 0xab8b, 0xab8b, - 0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8b, - 0xab8b, 0xab8d, 0xab8b, 0x080c, 0x0d85, 0x2009, 0x0013, 0x080c, - 0xafcc, 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, - 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x012e, 0x0005, 0x2009, 0x0049, - 0x080c, 0xafcc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x2001, 0x1a0e, - 0x2003, 0x0000, 0x7030, 0x9065, 0x090c, 0x0d85, 0x7034, 0x9092, - 0xc350, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, - 0x7007, 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xae8c, 0x0140, - 0x080c, 0xeb92, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafcc, - 0x781f, 0x0100, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0, - 0x714c, 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0438, - 0x2061, 0x0100, 0x7150, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7152, - 0x714c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, - 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188, - 0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, - 0x9085, 0x0016, 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f, - 0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x714c, - 0x2160, 0x6003, 0x0003, 0x2009, 0x004a, 0x080c, 0xafcc, 0x781f, - 0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, - 0x7820, 0x2060, 0x6003, 0x0003, 0x080c, 0xaae0, 0x080c, 0x1ded, - 0x781f, 0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c, - 0x0de8, 0x7820, 0x2060, 0x080c, 0xaae0, 0x080c, 0x1e35, 0x781f, - 0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, - 0x6044, 0xc0bc, 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, - 0x98c0, 0x012e, 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528, - 0x704c, 0x907d, 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086, - 0x0009, 0x0118, 0x080c, 0x9fb4, 0x00c0, 0x7828, 0xd0fc, 0x1118, - 0x080c, 0x9f33, 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, - 0x1130, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001, - 0x0387, 0x2003, 0x1000, 0x080c, 0x9eb8, 0x00fe, 0x012e, 0x0005, - 0x080c, 0x7747, 0x012e, 0x0005, 0x080c, 0x0d85, 0x0005, 0x2009, - 0x1b67, 0x2104, 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b, - 0x2104, 0x9085, 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac, - 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092, - 0x200a, 0x012e, 0x0005, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8, + 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, + 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1168, 0x080c, 0x769d, 0x0150, 0x6028, 0xc0bd, + 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2aeb, 0x0010, + 0x080c, 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, + 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, + 0x0804, 0xa907, 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6, + 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, + 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, + 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, + 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, + 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, + 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, + 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xa9e3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xa9ed, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, + 0xa8d7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, + 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaa03, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, + 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaa14, + 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, + 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, + 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, + 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, + 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, + 0x0904, 0xaad4, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, + 0x9005, 0x0904, 0xaaa6, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, + 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, + 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, + 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x600f, 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a, + 0x080c, 0xce4a, 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585, + 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a, + 0x1118, 0x080c, 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31, + 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c, 0xd0c6, + 0x080c, 0xaf89, 0x080c, 0xa458, 0x00ce, 0x0804, 0xaa57, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xaa57, 0x7013, 0x0000, 0x700f, 0x0000, + 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe738, 0x08f0, + 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832, + 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016, + 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x1188, + 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c, + 0x0d79, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, + 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, 0x0005, + 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9, 0x0469, + 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000, + 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab30, 0x080c, 0x0d79, 0x080c, + 0xaaf7, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c, + 0x97f6, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042, + 0x704c, 0x9c06, 0x190c, 0x0d79, 0x080c, 0x9851, 0x010e, 0x1919, + 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, 0x2400, + 0x7808, 0xd0a4, 0x190c, 0x0d72, 0xd09c, 0x0128, 0x7820, 0x908c, + 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab7d, 0xabbb, 0xabe5, + 0xac23, 0xac33, 0xac44, 0xac53, 0xac61, 0xac8e, 0xac92, 0xab7d, + 0xab7d, 0xac95, 0xacb1, 0xab7d, 0xab7d, 0x080c, 0x0d79, 0x012e, + 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0012, 0x012e, 0x0005, 0xaba2, + 0xaba4, 0xaba2, 0xabaa, 0xaba2, 0xaba2, 0xaba2, 0xaba2, 0xaba2, + 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba2, 0xaba2, + 0xaba4, 0xaba2, 0x080c, 0x0d79, 0x2009, 0x0013, 0x080c, 0xafec, + 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c, + 0x8ab2, 0x080c, 0xaf4e, 0x012e, 0x0005, 0x2009, 0x0049, 0x080c, + 0xafec, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x2001, 0x1a0e, 0x2003, + 0x0000, 0x7030, 0x9065, 0x090c, 0x0d79, 0x7034, 0x9092, 0xc350, + 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007, + 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xaeac, 0x0140, 0x080c, + 0xebfd, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x781f, + 0x0100, 0x080c, 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c, + 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0470, 0x2061, + 0x0100, 0x7150, 0x9192, 0x7530, 0x1628, 0x8108, 0x7152, 0x714c, + 0x9186, 0x1b56, 0x0120, 0x2001, 0x0391, 0x2003, 0x0400, 0x9188, + 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, + 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188, 0x0008, 0x210c, + 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, + 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f, 0x0200, 0x080c, + 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c, 0x2160, 0x6003, + 0x0003, 0x2009, 0x004a, 0x080c, 0xafec, 0x781f, 0x0200, 0x080c, + 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060, + 0x6003, 0x0003, 0x080c, 0xaaf7, 0x080c, 0x1de9, 0x781f, 0x0400, + 0x080c, 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, + 0x2060, 0x080c, 0xaaf7, 0x080c, 0x1e31, 0x781f, 0x0400, 0x080c, + 0xab13, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc, + 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x98bd, 0x012e, + 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528, 0x704c, 0x907d, + 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086, 0x0009, 0x0118, + 0x080c, 0x9fc5, 0x00c0, 0x7828, 0xd0fc, 0x1118, 0x080c, 0x9f44, + 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1130, 0x2001, + 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001, 0x0387, 0x2003, + 0x1000, 0x080c, 0x9ec9, 0x00fe, 0x012e, 0x0005, 0x080c, 0x773f, + 0x012e, 0x0005, 0x080c, 0x0d79, 0x0005, 0x2009, 0x1b67, 0x2104, + 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b, 0x2104, 0x9085, + 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac, 0x200a, 0x2009, + 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092, 0x200a, 0x012e, + 0x0005, 0x080c, 0x88f1, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8, 0xc08c, 0x200a, 0x2001, 0x1848, 0x2004, 0xd094, 0x1130, 0x2009, 0x0101, 0x2104, 0x9085, 0x0020, 0x200a, 0x2009, 0x1b67, 0x200b, - 0x0000, 0x2001, 0x001b, 0x080c, 0xaad1, 0x012e, 0x0005, 0x00e6, + 0x0000, 0x2001, 0x001b, 0x080c, 0xaae8, 0x012e, 0x0005, 0x00e6, 0x2071, 0x19e9, 0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8, 0x704c, - 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa380, 0x704f, 0x0000, + 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa391, 0x704f, 0x0000, 0x2001, 0x0109, 0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004, - 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa585, 0x00ee, 0x0005, - 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc, + 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa59c, 0x00ee, 0x0005, + 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7212, 0x600f, 0x0000, 0x0010, 0x7212, 0x720e, 0x9006, 0x002e, 0x0005, 0x0026, 0x7020, 0x9c06, - 0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, + 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7222, 0x600f, 0x0000, 0x0010, 0x7222, 0x721e, 0x9006, 0x002e, 0x0005, 0x00d6, 0x0036, 0x7830, 0x9c06, 0x1558, 0x2069, - 0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88ec, 0x080c, 0xa08a, - 0x68c3, 0x0000, 0x080c, 0xa56e, 0x2069, 0x0140, 0x6b04, 0x9384, - 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, - 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88e4, 0x080c, 0xa09b, + 0x68c3, 0x0000, 0x080c, 0xa585, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, + 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x9085, 0x0001, 0x0038, 0x7808, 0xc0ad, 0x780a, 0x6003, 0x0009, 0x630a, 0x9006, 0x003e, 0x00de, 0x0005, 0x0016, 0x0026, 0x0036, 0x6100, 0x2019, 0x0100, 0x2001, 0x0382, 0x2004, 0xd09c, 0x0190, - 0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab46, + 0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab5d, 0x003e, 0x001e, 0x012e, 0x00ce, 0x6200, 0x2200, 0x9106, 0x0d58, 0x2200, 0x0010, 0x8319, 0x1d38, 0x003e, 0x002e, 0x001e, 0x0005, - 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9, + 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100, 0x704c, 0x2060, 0x9086, 0x1b56, 0x15b8, 0x6814, 0xd08c, 0x0188, 0x6817, 0x0010, 0x2009, 0x0019, 0x8109, 0x1df0, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, 0x68d0, 0x9005, 0x0118, 0x9082, 0x0005, 0x0238, 0x6060, 0x8000, - 0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9859, 0x682c, + 0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9851, 0x682c, 0x9084, 0xfffd, 0x682e, 0x2001, 0x1848, 0x2004, 0xd094, 0x1120, 0x6804, 0x9085, 0x0020, 0x6806, 0x2069, 0x0000, 0x010e, 0x090c, - 0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, - 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100, - 0x080c, 0xad50, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240, - 0x080c, 0x2b55, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000, - 0x010e, 0x090c, 0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, + 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100, + 0x080c, 0xad70, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240, + 0x080c, 0x2b3c, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000, + 0x010e, 0x090c, 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0016, 0x2001, 0x0134, 0x2004, 0x9005, 0x0140, 0x9082, 0x0005, 0x1228, 0x2001, 0x0391, 0x2003, 0x0404, 0x0020, 0x2001, 0x0391, - 0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d2d, + 0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d3e, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, - 0x76a5, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, - 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89b1, 0x20a9, 0x0006, + 0x769d, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, + 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89a9, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, - 0x1f04, 0xae06, 0x60c3, 0x0020, 0x080c, 0xa05a, 0x015e, 0x00de, - 0x0005, 0x0156, 0x080c, 0x9d2d, 0x7a14, 0x82ff, 0x0168, 0x9286, + 0x1f04, 0xae26, 0x60c3, 0x0020, 0x080c, 0xa06b, 0x015e, 0x00de, + 0x0005, 0x0156, 0x080c, 0x9d3e, 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a, 0x8210, @@ -5361,12 +5365,12 @@ unsigned short risc_code01[] = { 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, - 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a, + 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, - 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c, - 0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x0005, 0x080c, - 0x3482, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, - 0x7012, 0x2009, 0x007e, 0x080c, 0x6789, 0xb85c, 0xc0ac, 0xb85e, + 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c, + 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e, 0x0005, 0x080c, + 0x346d, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, + 0x7012, 0x2009, 0x007e, 0x080c, 0x6783, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x00d6, 0x00f6, 0x7104, 0x9186, 0x0004, 0x1120, 0x7410, 0x9e90, 0x0004, 0x0068, 0x9186, 0x0001, 0x1120, 0x7420, 0x9e90, 0x0008, 0x0030, 0x9186, 0x0002, 0x1508, @@ -5388,7 +5392,7 @@ unsigned short risc_code01[] = { 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc, - 0x0a0c, 0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, + 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d79, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046, @@ -5396,1941 +5400,1950 @@ unsigned short risc_code01[] = { 0x600e, 0x6016, 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e, 0x6062, 0x604a, 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x0006, 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084, - 0x190c, 0x1afc, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, - 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe985, + 0x190c, 0x1af0, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, + 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe9f0, 0x604b, 0x0000, 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016, - 0x6012, 0x000e, 0x0005, 0x080c, 0xaae0, 0x0106, 0x2001, 0x19fc, - 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, - 0x003e, 0x080c, 0xa585, 0x010e, 0x090c, 0xaafc, 0x0005, 0x00e6, + 0x6012, 0x000e, 0x0005, 0x080c, 0xaaf7, 0x0106, 0x2001, 0x19fc, + 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, + 0x003e, 0x080c, 0xa59c, 0x010e, 0x090c, 0xab13, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, - 0xafe0, 0xafea, 0xb005, 0xb020, 0xd391, 0xd3ae, 0xd3c9, 0xafe0, - 0xafea, 0x9199, 0xb03c, 0xafe0, 0xafe0, 0xafe0, 0xafe0, 0xafe0, - 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97fe, - 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85, - 0x0013, 0x006e, 0x0005, 0xb003, 0xb77f, 0xb966, 0xb003, 0xb9fc, - 0xb305, 0xb003, 0xb003, 0xb701, 0xbf76, 0xb003, 0xb003, 0xb003, - 0xb003, 0xb003, 0xb003, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, - 0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb01e, 0xc58e, - 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xc525, 0xc711, - 0xb01e, 0xc5cb, 0xc64f, 0xc5cb, 0xc64f, 0xb01e, 0x080c, 0x0d85, - 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x0002, 0xb03a, - 0xbfc0, 0xc05a, 0xc1da, 0xc249, 0xb03a, 0xb03a, 0xb03a, 0xbf8f, - 0xc4a6, 0xc4a9, 0xb03a, 0xb03a, 0xb03a, 0xb03a, 0xc4d9, 0xb03a, - 0xb03a, 0xb03a, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, 0x0016, - 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb055, 0xb055, 0xb093, - 0xb132, 0xb1b2, 0xb055, 0xb055, 0xb055, 0xb057, 0xb055, 0xb055, - 0xb055, 0xb055, 0xb055, 0xb055, 0xb055, 0x080c, 0x0d85, 0x9186, - 0x004c, 0x0560, 0x9186, 0x0003, 0x190c, 0x0d85, 0x0096, 0x601c, - 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, - 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, - 0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, - 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x080c, - 0x1c47, 0x2009, 0x8030, 0x080c, 0x946f, 0x0005, 0x6010, 0x00b6, - 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xb1d4, 0x080c, 0xd356, - 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, - 0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, - 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, - 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, - 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, - 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, - 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, - 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, - 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xb0fa, 0xb0fa, 0xb0f5, - 0xb0f8, 0xb0fa, 0xb0f2, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, - 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, - 0x080c, 0x0d85, 0x080c, 0xbbc9, 0x0028, 0x080c, 0xbcb0, 0x0010, - 0x080c, 0xbda6, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, - 0x2c00, 0xa896, 0x000e, 0x080c, 0xb292, 0x0530, 0xa804, 0xa80e, - 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, - 0xadd8, 0x2031, 0x0000, 0x2041, 0x12c2, 0x080c, 0xb456, 0x0160, - 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, - 0x009e, 0x00de, 0x0804, 0xaf2e, 0x2001, 0x002c, 0x900e, 0x080c, - 0xb2f8, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, - 0x91b2, 0x0047, 0x0a0c, 0x0d85, 0x91b2, 0x0050, 0x1a0c, 0x0d85, - 0x9182, 0x0047, 0x0042, 0x080c, 0xad2d, 0x0120, 0x9086, 0x0002, - 0x0904, 0xb093, 0x0005, 0xb154, 0xb154, 0xb156, 0xb188, 0xb154, - 0xb154, 0xb154, 0xb154, 0xb19b, 0x080c, 0x0d85, 0x00d6, 0x0016, - 0x0096, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, - 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, - 0x0000, 0x900e, 0x080c, 0xb2f8, 0x080c, 0xaf2e, 0x00a8, 0x6003, - 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, - 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, - 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, - 0x080c, 0x9859, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, - 0x0120, 0xa87b, 0x0006, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c, - 0xaf2e, 0x0804, 0x98bf, 0x080c, 0x9859, 0x080c, 0x3310, 0x080c, - 0xd353, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0120, - 0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c, 0xaf2e, - 0x0804, 0x98bf, 0x9182, 0x0047, 0x0002, 0xb1c2, 0xb1c4, 0xb1c2, - 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, - 0xb1c2, 0xb1c4, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x601f, 0x0000, - 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6f19, - 0x009e, 0x00de, 0x0804, 0xaf2e, 0x0026, 0x0036, 0x0056, 0x0066, - 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c, - 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, - 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188, - 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, - 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034, - 0x1228, 0x2011, 0x001f, 0x080c, 0xc794, 0x04c0, 0x2130, 0x2009, - 0x0034, 0x2011, 0x001f, 0x080c, 0xc794, 0x96b2, 0x0034, 0xb004, - 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, 0x1059, 0x01d0, 0x8528, - 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, - 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc794, 0x00b8, 0x96b2, - 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xc794, - 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, - 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, - 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, - 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6f19, 0x000e, 0x2048, - 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, - 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1059, - 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, - 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, - 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, - 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, - 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, - 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6f19, 0x009e, 0x00fe, - 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, - 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, - 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, - 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, - 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1059, 0x2900, 0x009e, - 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, - 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, - 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, - 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, - 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, - 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, - 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb2a7, 0x0804, 0xb2a9, 0x9085, - 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, - 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, - 0x6f0d, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, - 0x080c, 0xaf2e, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x080c, - 0xaf2e, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, - 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, - 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, - 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, - 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, - 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, - 0x1db8, 0x0096, 0x080c, 0xcc16, 0x0130, 0x6014, 0x2048, 0xa807, - 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e, 0x0096, 0x00d6, - 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, - 0xb8d7, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, - 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xaf2e, 0x003e, 0x00de, - 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, - 0xd33e, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, - 0x0000, 0x604b, 0x0000, 0x2009, 0x0022, 0x080c, 0xb757, 0x9006, - 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, - 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, - 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, - 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, - 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, - 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, - 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xaf2e, 0x001e, - 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, - 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, - 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, - 0x000c, 0x6014, 0x2048, 0x080c, 0xc794, 0x080c, 0xcc16, 0x0140, - 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, - 0x080c, 0xaf2e, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, - 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, - 0x904d, 0x090c, 0x0d85, 0xa97a, 0x080c, 0x6f19, 0x009e, 0x080c, - 0xaf2e, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, - 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, - 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, - 0x0108, 0x2048, 0x080c, 0xc794, 0x009e, 0x080c, 0xcc16, 0x0148, - 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, - 0x0103, 0x080c, 0xaf2e, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, - 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xb91f, 0x00e0, - 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, - 0x2041, 0x12a8, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, - 0x080c, 0x1059, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, - 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, - 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x114e, 0x008e, - 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, - 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, - 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, - 0x11e0, 0x604b, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, - 0xd2b6, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, - 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xaf2e, - 0x0020, 0x0039, 0x0010, 0x080c, 0xb58c, 0x002e, 0x00de, 0x00ee, - 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb56b, - 0x918e, 0x0016, 0x1904, 0xb58a, 0x700c, 0x908c, 0xff00, 0x9186, - 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb545, 0x89ff, 0x1138, - 0x6800, 0x9086, 0x000f, 0x0904, 0xb527, 0x0804, 0xb588, 0x6808, - 0x9086, 0xffff, 0x1904, 0xb56d, 0xa87c, 0x9084, 0x0060, 0x9086, - 0x0020, 0x1150, 0xa8ac, 0xa934, 0x9106, 0x1904, 0xb56d, 0xa8b0, - 0xa938, 0x9106, 0x1904, 0xb56d, 0x6824, 0xd084, 0x1904, 0xb56d, - 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, - 0x9082, 0x0005, 0x001e, 0x1a04, 0xb56d, 0x080c, 0xce07, 0x6810, - 0x0096, 0x2048, 0xa9a0, 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864, - 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, - 0x6a18, 0x2001, 0x000a, 0x080c, 0x936c, 0xa884, 0x920a, 0x0208, - 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, - 0xc91f, 0x00ce, 0x0804, 0xb588, 0x00c6, 0xa868, 0xd0fc, 0x1118, - 0x080c, 0x6210, 0x0010, 0x080c, 0x661b, 0x00ce, 0x1904, 0xb56d, - 0x00c6, 0x2d60, 0x080c, 0xaf2e, 0x00ce, 0x0804, 0xb588, 0x00c6, - 0x080c, 0xaf9f, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, - 0xd0b1, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf2e, - 0x00ce, 0x080c, 0xafcc, 0x00ce, 0x0804, 0xb588, 0x2001, 0x1989, - 0x2004, 0x684a, 0x00ce, 0x0804, 0xb588, 0x7008, 0x9086, 0x000b, - 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, - 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xd2f8, 0x6007, 0x0085, - 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9428, - 0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989, - 0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d85, - 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, - 0x6d2e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x0026, 0x6010, 0x00b6, - 0x2058, 0xba3c, 0x080c, 0x68b4, 0x00be, 0x002e, 0x00de, 0x00ce, - 0x080c, 0xaf2e, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001, - 0x1989, 0x2004, 0x684a, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, - 0x2d00, 0x2060, 0x080c, 0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e, - 0x00ce, 0x080c, 0xaf2e, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, - 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989, 0x2004, 0x684a, - 0x0804, 0xb606, 0x00c6, 0x2d60, 0x080c, 0xc7f5, 0x00ce, 0x6804, - 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, - 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9428, 0x00ce, 0x04f0, - 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0d85, 0x6800, - 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff, - 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832, - 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150, - 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105, - 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020, - 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, 0x2001, 0x0005, - 0x6832, 0x080c, 0xcf9b, 0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e, - 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, - 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, - 0x1904, 0xb671, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, - 0x9206, 0x1904, 0xb671, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, - 0x6a20, 0x9286, 0x0007, 0x0904, 0xb671, 0x9286, 0x0002, 0x0904, - 0xb671, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8, - 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, 0x0016, 0x1100, - 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186, - 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, 0x004e, 0x0178, - 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, 0x080c, 0xcc16, - 0x090c, 0x0d85, 0xa87b, 0x0003, 0x009e, 0x080c, 0xd2f8, 0x6007, - 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, - 0x9428, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1989, 0x2004, - 0x704a, 0x080c, 0xaf2e, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6, - 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015, - 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096, - 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a, - 0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e, 0x003e, 0x015e, 0x009e, - 0x1904, 0xb6e0, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, - 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e, - 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, - 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, - 0x00be, 0x0804, 0xb341, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, - 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, - 0x2031, 0x0000, 0x2041, 0x12a8, 0x080c, 0xb456, 0x0130, 0x00fe, - 0x009e, 0x080c, 0xaf2e, 0x00be, 0x0005, 0x080c, 0xb91f, 0x0cb8, - 0x2b78, 0x00f6, 0x080c, 0x3310, 0x080c, 0xd353, 0x00fe, 0x00c6, - 0x080c, 0xaed8, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, - 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x66cf, - 0x080c, 0x66fb, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00ce, 0x0804, - 0xb6b3, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x91b2, 0x0040, - 0x1a04, 0xb769, 0x0002, 0xb757, 0xb757, 0xb74d, 0xb757, 0xb757, - 0xb757, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, - 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, - 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, - 0xb74b, 0xb74b, 0xb757, 0xb74b, 0xb757, 0xb757, 0xb74b, 0xb74b, - 0xb74b, 0xb74b, 0xb74b, 0xb74d, 0xb74b, 0xb74b, 0xb74b, 0xb74b, - 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb757, 0xb757, 0xb74b, - 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, - 0xb757, 0xb74b, 0xb74b, 0x080c, 0x0d85, 0x0066, 0x00b6, 0x6610, - 0x2658, 0xb8d4, 0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, - 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x942f, 0x0010, - 0x080c, 0x9428, 0x0126, 0x2091, 0x8000, 0x080c, 0x98bf, 0x012e, - 0x0005, 0x2600, 0x0002, 0xb757, 0xb757, 0xb77d, 0xb757, 0xb757, - 0xb77d, 0xb77d, 0xb77d, 0xb77d, 0xb757, 0xb77d, 0xb757, 0xb77d, - 0xb757, 0xb77d, 0xb77d, 0xb77d, 0xb77d, 0x080c, 0x0d85, 0x6004, - 0x90b2, 0x0053, 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x0904, 0xb854, - 0x91b6, 0x0027, 0x1904, 0xb800, 0x080c, 0x97fe, 0x6004, 0x080c, - 0xce1c, 0x01b0, 0x080c, 0xce2d, 0x01a8, 0x908e, 0x0021, 0x0904, - 0xb7fd, 0x908e, 0x0022, 0x1130, 0x080c, 0xb36d, 0x0904, 0xb7f9, - 0x0804, 0xb7fa, 0x908e, 0x003d, 0x0904, 0xb7fd, 0x0804, 0xb7f3, - 0x080c, 0x333f, 0x2001, 0x0007, 0x080c, 0x66cf, 0x6010, 0x00b6, - 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb91f, 0x9186, 0x007e, 0x1148, - 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x76a5, 0x1108, 0xc2ad, - 0x2202, 0x080c, 0xaae0, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, - 0x080c, 0xea92, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, - 0x2019, 0x0028, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, - 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe440, - 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xaafc, 0x080c, 0xd353, - 0x0016, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x001e, 0x080c, 0x3419, - 0x080c, 0x98bf, 0x0030, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x080c, - 0x98bf, 0x0005, 0x080c, 0xb91f, 0x0cb0, 0x080c, 0xb95b, 0x0c98, - 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d, - 0x0d80, 0x9086, 0x0002, 0x0904, 0xb966, 0x0c58, 0x9186, 0x0014, - 0x1d40, 0x080c, 0x97fe, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, - 0xb36d, 0x09f8, 0x080c, 0x3310, 0x080c, 0xd353, 0x080c, 0xce1c, - 0x1190, 0x080c, 0x333f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, - 0x080c, 0xb91f, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, - 0xc185, 0x2102, 0x0800, 0x080c, 0xce2d, 0x1120, 0x080c, 0xb91f, - 0x0804, 0xb7f3, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, - 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36ba, 0x00fe, 0x00ee, - 0x0804, 0xb7f3, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, - 0x090c, 0xb91f, 0x0804, 0xb7f3, 0x90b2, 0x0040, 0x1a04, 0xb8ff, - 0x2008, 0x0002, 0xb89c, 0xb89d, 0xb8a0, 0xb8a3, 0xb8a6, 0xb8b3, - 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, - 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, - 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, - 0xb8b6, 0xb8c1, 0xb89a, 0xb8c2, 0xb8c1, 0xb89a, 0xb89a, 0xb89a, - 0xb89a, 0xb89a, 0xb8c1, 0xb8c1, 0xb89a, 0xb89a, 0xb89a, 0xb89a, - 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb8ea, 0xb8c1, 0xb89a, 0xb8bd, - 0xb89a, 0xb89a, 0xb89a, 0xb8be, 0xb89a, 0xb89a, 0xb89a, 0xb8c1, - 0xb8e5, 0xb89a, 0x080c, 0x0d85, 0x0420, 0x2001, 0x000b, 0x0448, - 0x2001, 0x0003, 0x0430, 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6, - 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8, - 0x2001, 0x0001, 0x00b0, 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, - 0x080c, 0xd356, 0x080c, 0x98bf, 0x0058, 0x0018, 0x0010, 0x080c, - 0x66cf, 0x04b8, 0x080c, 0xd356, 0x6003, 0x0004, 0x080c, 0x98bf, - 0x0005, 0x080c, 0x66cf, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, - 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, - 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, - 0x631a, 0x003e, 0x080c, 0x98bf, 0x0c18, 0x080c, 0xd0a9, 0x080c, - 0xaf2e, 0x08f0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, - 0x080c, 0x36ba, 0x00fe, 0x00ee, 0x080c, 0x97fe, 0x080c, 0xaf2e, - 0x0878, 0x6003, 0x0002, 0x080c, 0xd356, 0x0804, 0x98bf, 0x2600, - 0x2008, 0x0002, 0xb916, 0xb8f9, 0xb914, 0xb8f9, 0xb8f9, 0xb914, - 0xb914, 0xb914, 0xb914, 0xb8f9, 0xb914, 0xb8f9, 0xb914, 0xb8f9, - 0xb914, 0xb914, 0xb914, 0xb914, 0x080c, 0x0d85, 0x0096, 0x6014, - 0x2048, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x00e6, - 0x0096, 0x0026, 0x0016, 0x080c, 0xcc16, 0x0568, 0x6014, 0x2048, - 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, - 0x080c, 0x55b2, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, - 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd21a, - 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, - 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, - 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, - 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, - 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, - 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d85, - 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xd139, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xd182, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xd1ae, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xd0cb, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xce6b, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xceac, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, 0xb312, 0x0804, 0xb9eb, - 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, 0xb677, 0x04e0, 0x6604, - 0x96b6, 0x0022, 0x1118, 0x080c, 0xb34e, 0x04a8, 0x6604, 0x96b6, - 0x0035, 0x1118, 0x080c, 0xb474, 0x0470, 0x6604, 0x96b6, 0x0039, - 0x1118, 0x080c, 0xb60c, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, - 0x080c, 0xb386, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, - 0xb3c2, 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb403, - 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb3ed, 0x0058, - 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, - 0x00be, 0x0804, 0xbc55, 0x00be, 0x0005, 0x080c, 0xafe9, 0x0cd8, - 0xba08, 0xba16, 0xba08, 0xba5d, 0xba08, 0xbbc9, 0xbc62, 0xba08, - 0xba08, 0xbc2b, 0xba08, 0xbc41, 0x0096, 0x601f, 0x0000, 0x6014, - 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e, - 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, - 0x0001, 0x080c, 0x66bb, 0x0804, 0xaf2e, 0x0005, 0x00e6, 0x2071, - 0x1800, 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe411, 0x11b0, - 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, - 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, - 0x66cf, 0x080c, 0x333f, 0x080c, 0xaf2e, 0x0098, 0x2001, 0x000a, - 0x080c, 0x66cf, 0x080c, 0x333f, 0x6003, 0x0001, 0x6007, 0x0001, - 0x080c, 0x942f, 0x080c, 0x98bf, 0x0020, 0x2001, 0x0001, 0x080c, - 0xbb99, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, - 0x080c, 0x66bb, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, - 0x0006, 0x080c, 0x66fb, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, - 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xbb6e, 0x6010, - 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xbdb1, 0x0804, - 0xbacf, 0x080c, 0xbda6, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, - 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, - 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, - 0x080c, 0xd21a, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, - 0x0200, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f, 0x080c, - 0xaf2e, 0x0804, 0xbb73, 0x080c, 0xbb81, 0x6014, 0x9005, 0x0190, - 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, - 0xd21a, 0x08f8, 0x080c, 0xbb77, 0x0160, 0x9006, 0x080c, 0x66bb, - 0x2001, 0x0004, 0x080c, 0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf, - 0x08a0, 0x2001, 0x0004, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007, - 0x0003, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0804, 0xbb73, 0xb85c, - 0xd0e4, 0x01d8, 0x080c, 0xd043, 0x080c, 0x76a5, 0x0118, 0xd0dc, - 0x1904, 0xba91, 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x2001, - 0x196e, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, - 0x2716, 0x78e2, 0x00fe, 0x0804, 0xba91, 0x080c, 0xd084, 0x2011, - 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe5a2, 0x000e, - 0x1904, 0xba91, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x66cf, - 0x9006, 0x080c, 0x66bb, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, - 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, - 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, - 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb, - 0x00f6, 0x2100, 0x900e, 0x080c, 0x26a2, 0x795e, 0x00fe, 0x9186, - 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, - 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, - 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb, 0x00f6, 0x2079, 0x1800, - 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a2, 0x795e, 0x00fe, - 0x8108, 0x080c, 0x671e, 0x2b00, 0x00ce, 0x1904, 0xba91, 0x6012, - 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, - 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, - 0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0028, 0x080c, 0xb91f, - 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, - 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, - 0x0005, 0x00e6, 0x080c, 0xeaeb, 0x0190, 0x2071, 0x0260, 0x7108, - 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, - 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, - 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x66cf, - 0x080c, 0x583a, 0x1120, 0x2001, 0x0007, 0x080c, 0x66fb, 0x2600, - 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, - 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, - 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x004e, 0x003e, - 0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, - 0xaf2e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, - 0x9086, 0x0014, 0x1904, 0xbc21, 0x080c, 0x583a, 0x1170, 0x6014, - 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, - 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, - 0x080c, 0x6824, 0x080c, 0xba4b, 0x00de, 0x080c, 0xbe77, 0x1588, - 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, - 0x66cf, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, - 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, - 0x080c, 0xd21a, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, - 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, - 0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xaf2e, - 0x0028, 0x080c, 0xb91f, 0x9006, 0x080c, 0xbb99, 0x001e, 0x002e, - 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, - 0x1160, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007, - 0x0001, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001, 0x0001, 0x0804, - 0xbb99, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, - 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66cf, 0x0804, - 0xaf2e, 0x2001, 0x0001, 0x0804, 0xbb99, 0x0002, 0xba08, 0xbc6d, - 0xba08, 0xbcb0, 0xba08, 0xbd5d, 0xbc62, 0xba0b, 0xba08, 0xbd71, - 0xba08, 0xbd83, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbc9, 0x96b6, - 0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x00b6, 0x00d6, 0x00c6, - 0x080c, 0xbd95, 0x11a0, 0x9006, 0x080c, 0x66bb, 0x080c, 0x3310, - 0x080c, 0xd353, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001, - 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0428, 0x2009, - 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, - 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, - 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, - 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3310, 0x080c, 0xd353, - 0x2001, 0x0001, 0x080c, 0xbb99, 0x00ce, 0x00de, 0x00be, 0x0005, - 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbda3, 0x00d6, 0x2069, - 0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, - 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, - 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0002, - 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x0804, 0xbd2d, 0x080c, 0xcc16, 0x01b0, 0x6014, - 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, - 0x2001, 0x0002, 0x080c, 0xd277, 0x00b0, 0x6014, 0x2048, 0xa864, - 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, - 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, - 0x1110, 0x9006, 0x0c38, 0x080c, 0xb91f, 0x2009, 0x026e, 0x2134, - 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, - 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, - 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, - 0x0004, 0x080c, 0x66cf, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, - 0x0020, 0x2001, 0x0001, 0x080c, 0xbb99, 0x002e, 0x00be, 0x009e, - 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcc16, - 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, - 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, - 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, - 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, - 0x00ee, 0x0010, 0x080c, 0x3310, 0x0860, 0x2001, 0x0004, 0x080c, - 0x66cf, 0x080c, 0xbda3, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, - 0x080c, 0x942f, 0x0804, 0x98bf, 0x080c, 0xb91f, 0x9006, 0x0804, - 0xbb99, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66cf, 0x6003, - 0x0001, 0x6007, 0x0005, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001, - 0x0001, 0x0804, 0xbb99, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, - 0x66cf, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f, 0x0804, - 0x98bf, 0x2001, 0x0001, 0x0804, 0xbb99, 0x2009, 0x026e, 0x2104, - 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, - 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, - 0x0016, 0x6110, 0x2158, 0x080c, 0x6798, 0x001e, 0x00ce, 0x00be, - 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, - 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, - 0xbe49, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, - 0x6bd1, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe72a, - 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, - 0x0001, 0x080c, 0x32d5, 0x00e6, 0x2071, 0x1800, 0x080c, 0x30e1, - 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, - 0x3419, 0x8108, 0x1f04, 0xbde7, 0x015e, 0x00ce, 0x080c, 0xbda6, - 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, - 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, - 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, - 0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, - 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, - 0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, - 0x182c, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26eb, - 0x080c, 0x76a5, 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048, - 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, - 0xd043, 0x0040, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f, - 0x080c, 0xaf2e, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, - 0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, - 0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, - 0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, - 0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x1148, - 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf3e, - 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, - 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, - 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, - 0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, - 0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, - 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, - 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, - 0x2071, 0x1800, 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf0a, 0x080c, - 0x8d8f, 0x0904, 0xbf03, 0x080c, 0xe75b, 0x0904, 0xbf03, 0x6720, - 0x9786, 0x0007, 0x0904, 0xbf03, 0x2500, 0x9c06, 0x0904, 0xbf03, - 0x2400, 0x9c06, 0x0904, 0xbf03, 0x3e08, 0x9186, 0x0002, 0x1148, - 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x1590, 0x00c6, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110, - 0x080c, 0x1afc, 0x9786, 0x000a, 0x0148, 0x080c, 0xce2d, 0x1130, - 0x00ce, 0x080c, 0xb91f, 0x080c, 0xaf69, 0x00e8, 0x6014, 0x2048, - 0x080c, 0xcc16, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, - 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x100b, - 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07, - 0x080c, 0xaf69, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210, - 0x0804, 0xbeaa, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, - 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, - 0xe6cd, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, - 0x0d08, 0x2009, 0x004c, 0x080c, 0xafcc, 0x08e0, 0x9786, 0x000a, - 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, - 0x1f04, 0xbf2a, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, - 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, - 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, - 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, - 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, - 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, - 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, - 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, - 0xbf68, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, - 0x0053, 0x1a0c, 0x0d85, 0x080c, 0xce1c, 0x0120, 0x080c, 0xce2d, - 0x0158, 0x0028, 0x080c, 0x333f, 0x080c, 0xce2d, 0x0128, 0x080c, - 0x97fe, 0x080c, 0xaf2e, 0x0005, 0x080c, 0xb91f, 0x0cc0, 0x9182, - 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfae, - 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, - 0xbfae, 0xbfae, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfae, 0xbfae, - 0xbfae, 0xbfb0, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0x080c, 0x0d85, - 0x600b, 0xffff, 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000, - 0x080c, 0xd356, 0x2009, 0x8000, 0x080c, 0x9428, 0x012e, 0x0005, - 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc038, - 0x9186, 0x0027, 0x1520, 0x080c, 0x97fe, 0x080c, 0x3310, 0x080c, - 0xd353, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0198, 0x080c, - 0xce2d, 0x1118, 0x080c, 0xb91f, 0x0068, 0xa867, 0x0103, 0xa87b, - 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f19, - 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0804, 0x98bf, 0x9186, - 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053, - 0x0110, 0x080c, 0x0d85, 0x0005, 0x0002, 0xc016, 0xc014, 0xc014, - 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, - 0xc02f, 0xc02f, 0xc02f, 0xc02f, 0xc014, 0xc02f, 0xc014, 0xc02f, - 0xc014, 0xc014, 0xc014, 0xc014, 0x080c, 0x0d85, 0x080c, 0x97fe, - 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0168, 0xa867, 0x0103, - 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, - 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x080c, - 0x97fe, 0x080c, 0xce2d, 0x090c, 0xb91f, 0x080c, 0xaf2e, 0x0005, - 0x0002, 0xc052, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, - 0xc050, 0xc050, 0xc050, 0xc050, 0xc054, 0xc054, 0xc054, 0xc054, - 0xc050, 0xc056, 0xc050, 0xc054, 0xc050, 0xc050, 0xc050, 0xc050, - 0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0xaf2e, - 0x0804, 0x98bf, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, - 0x000a, 0x0005, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc0b2, - 0xc1a1, 0xc079, 0xc1ad, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, - 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc1ad, 0xc07b, 0xc079, - 0xc1ab, 0x080c, 0x0d85, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010, - 0x2058, 0xb800, 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103, - 0xa877, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, - 0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c, 0x82ff, - 0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4, - 0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0, - 0xa838, 0xa934, 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c, - 0xcf62, 0x0c80, 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc, - 0x1110, 0x7644, 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590, - 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc190, 0xa87b, 0x0000, - 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c, - 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, - 0x68b4, 0x601c, 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc174, - 0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c, - 0x080c, 0x0d85, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, - 0xd0bc, 0x1904, 0xc178, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, - 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, - 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, - 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, - 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, - 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, - 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, - 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc0be, 0x735c, 0xab86, - 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, - 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794, 0x003e, - 0xd6cc, 0x0904, 0xc0d3, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0d3, - 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, - 0x080c, 0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd2e3, - 0x0804, 0xc0d3, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, - 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc733, 0x00ae, 0x080c, 0xd2e3, - 0x080c, 0xc784, 0x0804, 0xc0d5, 0x080c, 0xcf25, 0x0804, 0xc0ea, - 0xa87c, 0xd0ac, 0x0904, 0xc0fb, 0xa880, 0xd0bc, 0x1904, 0xc0fb, - 0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, - 0xc0fb, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc0fb, 0x0068, - 0xa87c, 0xd0ac, 0x0904, 0xc0c6, 0xa838, 0xa934, 0x9105, 0x0904, - 0xc0c6, 0xa880, 0xd0bc, 0x1904, 0xc0c6, 0x080c, 0xcf62, 0x0804, - 0xc0ea, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, - 0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, 0x6003, - 0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0128, - 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, - 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, - 0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, 0xab09, - 0x604b, 0x0000, 0x080c, 0x1cbd, 0x1118, 0x6144, 0x080c, 0x9454, - 0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, - 0x000a, 0x0005, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, - 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1fb, 0xc1f9, 0xc1f9, 0xc1f9, - 0xc1f9, 0xc20c, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc230, 0xc1f9, - 0xc1f9, 0x080c, 0x0d85, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, - 0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x6003, 0x0002, 0x080c, - 0xd35b, 0x080c, 0x9859, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110, - 0x080c, 0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x080c, 0x9859, - 0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6114, 0x2148, 0x080c, - 0xcc16, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, - 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005, - 0x080c, 0x0d85, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, - 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, - 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, - 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, - 0x0005, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc26a, 0xc268, - 0xc268, 0xc327, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, - 0xc268, 0xc268, 0xc268, 0xc268, 0xc467, 0xc268, 0xc471, 0xc268, - 0x080c, 0x0d85, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4, - 0x0120, 0xc084, 0x601e, 0x0804, 0xc05a, 0x6114, 0x0096, 0x2148, - 0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, 0x0096, - 0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, 0x7644, - 0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, - 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, - 0x00be, 0x86ff, 0x0904, 0xc320, 0x9694, 0xff00, 0x9284, 0x0c00, - 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, - 0xc320, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, - 0xb676, 0x0c38, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, 0xb07a, - 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, - 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, - 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, - 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, - 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, - 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, - 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, - 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, - 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794, - 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, - 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, - 0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, - 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc733, - 0x080c, 0x1ac8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, - 0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, - 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c, - 0xd364, 0x0904, 0xc462, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc426, 0xa978, - 0xa868, 0xd0fc, 0x0904, 0xc3e7, 0x0016, 0xa87c, 0x0006, 0xa880, - 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, - 0x0904, 0xc3b4, 0x9086, 0x0028, 0x1904, 0xc3a0, 0xa87b, 0x001c, - 0xb07b, 0x001c, 0x0804, 0xc3bc, 0x6024, 0xd0f4, 0x11d0, 0xa838, - 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, - 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, - 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, - 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, - 0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, - 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, - 0x2048, 0x080c, 0x100b, 0x009e, 0x080c, 0xcf62, 0x0804, 0xc462, - 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203, - 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, - 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, - 0xa938, 0x9115, 0x190c, 0xc232, 0xa87c, 0xb07e, 0xa890, 0xb092, - 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, - 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, - 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, - 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd2e3, 0x001e, 0xa874, - 0x0006, 0x2148, 0x080c, 0x100b, 0x001e, 0x0804, 0xc453, 0x0016, - 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, - 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, - 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203, - 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, - 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, - 0xa938, 0x9115, 0x190c, 0xc232, 0xa890, 0xb092, 0xa88c, 0xb08e, - 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x100b, 0x009e, 0x080c, 0xd2e3, - 0xa974, 0x0016, 0x080c, 0xc784, 0x001e, 0x0468, 0xa867, 0x0103, - 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, - 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, - 0x080c, 0xd203, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, - 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, - 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0xa974, 0x0016, - 0x080c, 0x6d2e, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, 0xb8d0, - 0x0016, 0x9005, 0x190c, 0x68b4, 0x001e, 0x00be, 0xd1e4, 0x1120, - 0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xcf25, 0x0cd8, 0x6114, - 0x0096, 0x2148, 0xa97c, 0x080c, 0xd364, 0x190c, 0x1ae8, 0x009e, - 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8, - 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, 0x6010, - 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d2e, 0xba3c, - 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4, - 0x080c, 0xaf2e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e, - 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc232, 0x0c28, - 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf62, 0x0c60, 0x080c, 0x97fe, - 0x0010, 0x080c, 0x9859, 0x601c, 0xd084, 0x0110, 0x080c, 0x1afc, - 0x080c, 0xcc16, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xce2d, - 0x1118, 0x080c, 0xb91f, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, - 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, 0x918e, - 0x0029, 0x1110, 0x080c, 0xea83, 0xa877, 0x0000, 0x080c, 0x6f19, - 0x009e, 0x0804, 0xaf69, 0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004, - 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, - 0x0005, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4fa, 0xc4f8, - 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, - 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc51e, 0xc4f8, 0xc4f8, - 0x080c, 0x0d85, 0x080c, 0x582e, 0x01f8, 0x6014, 0x7144, 0x918c, - 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, - 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, - 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, - 0xaa9e, 0x080c, 0x6f19, 0x009e, 0x0804, 0xaf2e, 0x080c, 0x582e, - 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, 0x0002, - 0xc537, 0xc535, 0xc535, 0xc543, 0xc535, 0xc535, 0xc535, 0xc535, - 0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0x080c, 0x0d85, 0x6003, - 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, - 0x9428, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, - 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc04, 0x01f8, 0x2268, - 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, - 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc7f5, 0x00de, 0x00ce, 0x0158, - 0x702c, 0xd084, 0x1118, 0x080c, 0xc7bf, 0x0010, 0x6803, 0x0002, - 0x6007, 0x0086, 0x0028, 0x080c, 0xc7e1, 0x0d90, 0x6007, 0x0087, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x7220, 0x080c, - 0xcc04, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xcf62, - 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, - 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, - 0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, - 0x9186, 0x0014, 0x190c, 0x0d85, 0x080c, 0x97fe, 0x0096, 0x6014, - 0x2048, 0x080c, 0xcc16, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, - 0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x0804, - 0x98bf, 0xc5c6, 0xc5c8, 0xc5c8, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, - 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0x080c, 0x0d85, - 0x080c, 0xaf69, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082, - 0x0085, 0x2008, 0x0804, 0xc617, 0x9186, 0x0027, 0x1558, 0x080c, - 0x97fe, 0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6014, 0x2048, - 0x080c, 0xcc16, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, - 0x0029, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, - 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c, - 0xad2d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc64f, 0x0000, 0x080c, - 0xafe9, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97fe, 0x0096, - 0x6014, 0x2048, 0x080c, 0xcc16, 0x0d00, 0xa867, 0x0103, 0xa877, - 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002, - 0xc627, 0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0xc63b, 0xc625, - 0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0x080c, 0x0d85, 0x6034, - 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, - 0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, - 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, - 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, 0x9182, - 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xafe9, - 0xc665, 0xc665, 0xc665, 0xc665, 0xc667, 0xc6b4, 0xc665, 0xc665, - 0xc665, 0xc665, 0xc665, 0xc665, 0xc665, 0x080c, 0x0d85, 0x0096, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, - 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, - 0x1118, 0x009e, 0x0804, 0xc6c8, 0x080c, 0xcc16, 0x1118, 0x080c, - 0xce07, 0x0068, 0x6014, 0x2048, 0x080c, 0xd36a, 0x1110, 0x080c, - 0xce07, 0xa867, 0x0103, 0x080c, 0xd31e, 0x080c, 0x6f19, 0x00d6, - 0x2c68, 0x080c, 0xaed8, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, - 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, - 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0b1, 0x695c, 0x615e, - 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x00de, - 0x080c, 0xaf2e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, - 0x00d6, 0x2c68, 0x080c, 0xd2b6, 0x11f0, 0x080c, 0xaed8, 0x01d8, - 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, - 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, - 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0b1, 0x2009, - 0x8020, 0x080c, 0x9428, 0x2d60, 0x00de, 0x0804, 0xaf2e, 0x0096, - 0x6014, 0x2048, 0x080c, 0xcc16, 0x01c8, 0xa867, 0x0103, 0xa880, - 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, - 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21, - 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x0804, - 0xaf2e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0140, - 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6f19, - 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130, - 0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c, 0x97fe, - 0x080c, 0xaf69, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, - 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, - 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, - 0xc794, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b, - 0x080c, 0x1059, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, - 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, - 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, - 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, - 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, - 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, - 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, - 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f19, 0x2a48, 0x0cb8, - 0x080c, 0x6f19, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, - 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, - 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, - 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, - 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, - 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, - 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, - 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0150, - 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x7165, 0x080c, 0x6f0d, - 0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x00ee, 0x00de, 0x00ce, - 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, - 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, - 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, - 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, - 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, - 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xc847, - 0xc847, 0xc842, 0xc86b, 0xc81f, 0xc842, 0xc821, 0xc842, 0xc81f, - 0x92e7, 0xc842, 0xc842, 0xc842, 0xc81f, 0xc81f, 0xc81f, 0x080c, - 0x0d85, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, 0xc86b, - 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, 0x0118, - 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, 0x0010, - 0x2019, 0x0010, 0x080c, 0xe27a, 0x6023, 0x0006, 0x6003, 0x0007, - 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, - 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d0, 0x6043, - 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, - 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x080c, - 0xcf21, 0x080c, 0x6f0d, 0x080c, 0xaf69, 0x9085, 0x0001, 0x009e, - 0x0005, 0x9006, 0x0ce0, 0x080c, 0xaae0, 0x080c, 0xd378, 0x6000, - 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x002b, 0x0106, 0x080c, 0xaafc, - 0x010e, 0x0005, 0xc88a, 0xc8ba, 0xc88c, 0xc8e1, 0xc8b5, 0xc88a, - 0xc842, 0xc847, 0xc847, 0xc842, 0xc842, 0xc842, 0xc842, 0xc842, - 0xc842, 0xc842, 0x080c, 0x0d85, 0x86ff, 0x1520, 0x6020, 0x9086, - 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0168, - 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, - 0x080c, 0x100b, 0x009e, 0x080c, 0xcf21, 0x009e, 0x080c, 0xd2f8, - 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, - 0x080c, 0x940a, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1afc, - 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06, 0x1120, - 0x080c, 0xa300, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, - 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, - 0xa44b, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa1fc, 0x190c, - 0x0d85, 0x080c, 0xa20a, 0x006e, 0x00ee, 0x1904, 0xc88c, 0x0804, - 0xc842, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1138, - 0x901e, 0x080c, 0xa380, 0x00ee, 0x003e, 0x0804, 0xc88c, 0x080c, - 0xa585, 0x00ee, 0x003e, 0x1904, 0xc88c, 0x0804, 0xc842, 0x00c6, - 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, - 0xc917, 0xc9e6, 0xcb50, 0xc91f, 0xaf69, 0xc917, 0xe26c, 0xd360, - 0xc9e6, 0x92ae, 0xcbdc, 0xc910, 0xc910, 0xc910, 0xc910, 0xc910, - 0x080c, 0x0d85, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x0005, - 0x080c, 0x97fe, 0x0804, 0xaf2e, 0x601b, 0x0001, 0x0005, 0x080c, - 0xcc16, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, - 0x080c, 0xaae0, 0x080c, 0xd378, 0x6000, 0x908a, 0x0016, 0x1a0c, - 0x0d85, 0x0013, 0x0804, 0xaafc, 0xc944, 0xc946, 0xc970, 0xc984, - 0xc9b1, 0xc944, 0xc917, 0xc917, 0xc917, 0xc98b, 0xc98b, 0xc944, - 0xc944, 0xc944, 0xc944, 0xc995, 0x080c, 0x0d85, 0x00e6, 0x6014, - 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, - 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa1fc, 0x190c, 0x0d85, - 0x080c, 0xa20a, 0x006e, 0x080c, 0xd2f8, 0x6007, 0x0085, 0x6003, - 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009, - 0x8020, 0x080c, 0x940a, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, - 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, - 0xd2f8, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, - 0x8020, 0x080c, 0x940a, 0x0005, 0x080c, 0xaae0, 0x080c, 0xacaf, - 0x080c, 0xaafc, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, - 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x582e, 0x01b8, - 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, - 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, - 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f19, 0x009e, 0x0804, - 0xaf2e, 0x6014, 0x0096, 0x904d, 0x0560, 0xa97c, 0xd1e4, 0x1158, - 0x611c, 0xd1fc, 0x0530, 0x6110, 0x00b6, 0x2158, 0xb93c, 0x8109, - 0x0208, 0xb93e, 0x00be, 0x080c, 0xaafc, 0x2001, 0x180f, 0x2004, - 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, - 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c, 0x16b9, - 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc, - 0x0005, 0x009e, 0x080c, 0x1afc, 0x0804, 0xc970, 0x6000, 0x908a, - 0x0016, 0x1a0c, 0x0d85, 0x000b, 0x0005, 0xc9fd, 0xc91c, 0xc9ff, - 0xc9fd, 0xc9ff, 0xc9ff, 0xc918, 0xc9fd, 0xc912, 0xc912, 0xc9fd, - 0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0x080c, 0x0d85, 0x6010, + 0xb000, 0xb00a, 0xb025, 0xb040, 0xd3b0, 0xd3cd, 0xd3e8, 0xb000, + 0xb00a, 0x9191, 0xb059, 0xb000, 0xb000, 0xb000, 0xb000, 0xb000, + 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97f6, + 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, + 0x0013, 0x006e, 0x0005, 0xb023, 0xb79c, 0xb983, 0xb023, 0xba19, + 0xb322, 0xb023, 0xb023, 0xb71e, 0xbf8c, 0xb023, 0xb023, 0xb023, + 0xb023, 0xb023, 0xb023, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xb03e, 0xc5a7, + 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xc53e, 0xc72a, + 0xb03e, 0xc5e4, 0xc668, 0xc5e4, 0xc668, 0xb03e, 0x080c, 0x0d79, + 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x0002, 0xb057, + 0xbfd6, 0xc070, 0xc1f3, 0xc262, 0xb057, 0xb057, 0xb057, 0xbfa5, + 0xc4bf, 0xc4c2, 0xb057, 0xb057, 0xb057, 0xb057, 0xc4f2, 0x080c, + 0x0d79, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013, + 0x006e, 0x0005, 0xb072, 0xb072, 0xb0b0, 0xb14f, 0xb1cf, 0xb072, + 0xb072, 0xb072, 0xb074, 0xb072, 0xb072, 0xb072, 0xb072, 0xb072, + 0xb072, 0xb072, 0x080c, 0x0d79, 0x9186, 0x004c, 0x0560, 0x9186, + 0x0003, 0x190c, 0x0d79, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003, + 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5, + 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0x9006, 0xa846, 0xa84a, + 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, + 0x8213, 0x9210, 0x621a, 0x009e, 0x080c, 0x1c43, 0x2009, 0x8030, + 0x080c, 0x9467, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x080c, 0xb1f1, 0x080c, 0xd375, 0x6003, 0x0007, 0x0005, + 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, + 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, + 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, + 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, + 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, + 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, + 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, + 0x9405, 0x0002, 0xb117, 0xb117, 0xb112, 0xb115, 0xb117, 0xb10f, + 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, + 0xb102, 0xb102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, + 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d79, 0x080c, + 0xbbda, 0x0028, 0x080c, 0xbcc1, 0x0010, 0x080c, 0xbdb7, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, + 0x080c, 0xb2af, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, + 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, + 0x2041, 0x12b6, 0x080c, 0xb473, 0x0160, 0x000e, 0x9005, 0x0120, + 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, + 0xaf4e, 0x2001, 0x002c, 0x900e, 0x080c, 0xb315, 0x0c70, 0x91b6, + 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, + 0x0d79, 0x91b2, 0x0050, 0x1a0c, 0x0d79, 0x9182, 0x0047, 0x0042, + 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002, 0x0904, 0xb0b0, 0x0005, + 0xb171, 0xb171, 0xb173, 0xb1a5, 0xb171, 0xb171, 0xb171, 0xb171, + 0xb1b8, 0x080c, 0x0d79, 0x00d6, 0x0016, 0x0096, 0x6003, 0x0004, + 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, + 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, + 0xb315, 0x080c, 0xaf4e, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, + 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, + 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, + 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c, 0x9851, 0x00d6, + 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0006, + 0x080c, 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc, + 0x080c, 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x00d6, 0x0096, + 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c, + 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9182, + 0x0047, 0x0002, 0xb1df, 0xb1e1, 0xb1df, 0xb1df, 0xb1df, 0xb1df, + 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1e1, 0x080c, + 0x0d79, 0x00d6, 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, + 0x0000, 0xa883, 0x0000, 0x080c, 0x6f11, 0x009e, 0x00de, 0x0804, + 0xaf4e, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, + 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79, 0xa960, 0x21e8, + 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, + 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, + 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, + 0x901e, 0x2029, 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, + 0x080c, 0xc7ad, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, + 0x080c, 0xc7ad, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fff, 0x080c, 0x104d, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, + 0x001b, 0x080c, 0xc7ad, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, + 0x2950, 0x2011, 0x001b, 0x080c, 0xc7ad, 0x0c18, 0x2001, 0x0205, + 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, + 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, + 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, + 0x0006, 0x080c, 0x6f11, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, + 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, + 0x00f6, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79, + 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, + 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, + 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, + 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, + 0x0000, 0x080c, 0x6f11, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, + 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, + 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, + 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, + 0x0096, 0x080c, 0x104d, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, + 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, + 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, + 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, + 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, + 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, + 0x0904, 0xb2c4, 0x0804, 0xb2c6, 0x9085, 0x0001, 0x7817, 0x0000, + 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, + 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6f05, 0x009e, 0x003e, + 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0xaf4e, 0x0030, + 0x91b6, 0x0016, 0x190c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x20a9, + 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, + 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, + 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, + 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, + 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, + 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, + 0xcc33, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, + 0x009e, 0x0804, 0xaf4e, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, + 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000, 0x00be, + 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, + 0xab32, 0x080c, 0xaf4e, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, + 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xd35d, 0x0188, 0x6014, + 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000, + 0x2009, 0x0022, 0x080c, 0xb774, 0x9006, 0x001e, 0x000e, 0x0005, + 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, + 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, + 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, + 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e, 0x009e, 0x0005, 0x0096, + 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, + 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, + 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, + 0x080c, 0xc7ad, 0x080c, 0xcc33, 0x0140, 0x6014, 0x2048, 0xa807, + 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e, + 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, + 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79, + 0xa97a, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x001e, 0x0005, + 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, + 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, + 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, + 0xc7ad, 0x009e, 0x080c, 0xcc33, 0x0148, 0xa804, 0x9005, 0x1158, + 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e, + 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, + 0x0100, 0x1118, 0x080c, 0xb93c, 0x00e0, 0xa034, 0x8007, 0x800c, + 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, + 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129c, 0x0019, + 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e, + 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, + 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, + 0x0086, 0x2940, 0x080c, 0x1142, 0x008e, 0x9085, 0x0001, 0x009e, + 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, + 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, + 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b, 0x0000, + 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd2d3, 0x001e, 0x1158, + 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, + 0x9386, 0x0006, 0x0128, 0x080c, 0xaf4e, 0x0020, 0x0039, 0x0010, + 0x080c, 0xb5a9, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, + 0x2048, 0x9186, 0x0015, 0x0904, 0xb588, 0x918e, 0x0016, 0x1904, + 0xb5a7, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, + 0x0300, 0x1904, 0xb562, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, + 0x0904, 0xb544, 0x0804, 0xb5a5, 0x6808, 0x9086, 0xffff, 0x1904, + 0xb58a, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1150, 0xa8ac, + 0xa934, 0x9106, 0x1904, 0xb58a, 0xa8b0, 0xa938, 0x9106, 0x1904, + 0xb58a, 0x6824, 0xd084, 0x1904, 0xb58a, 0xd0b4, 0x0158, 0x0016, + 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, + 0x1a04, 0xb58a, 0x080c, 0xce24, 0x6810, 0x0096, 0x2048, 0xa9a0, + 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c, 0xc0dc, + 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, + 0x080c, 0x9364, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, + 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xc938, 0x00ce, 0x0804, + 0xb5a5, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x620a, 0x0010, + 0x080c, 0x6615, 0x00ce, 0x1904, 0xb58a, 0x00c6, 0x2d60, 0x080c, + 0xaf4e, 0x00ce, 0x0804, 0xb5a5, 0x00c6, 0x080c, 0xafbf, 0x0198, + 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0003, + 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xafec, + 0x00ce, 0x0804, 0xb5a5, 0x2001, 0x1989, 0x2004, 0x684a, 0x00ce, + 0x0804, 0xb5a5, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, + 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, + 0x0003, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0430, 0x700c, + 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x684a, 0x00e8, + 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d79, 0x00c6, 0x00d6, 0x2d60, + 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6d26, 0x080c, 0xce24, + 0x080c, 0xaf89, 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c, 0x080c, + 0x68ae, 0x00be, 0x002e, 0x00de, 0x00ce, 0x080c, 0xaf4e, 0x009e, + 0x0005, 0x9186, 0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x684a, + 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, + 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xaf4e, + 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, + 0x0130, 0x2001, 0x1989, 0x2004, 0x684a, 0x0804, 0xb623, 0x00c6, + 0x2d60, 0x080c, 0xc80e, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, + 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, + 0x8023, 0x080c, 0x9420, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, + 0x01a8, 0x89ff, 0x090c, 0x0d79, 0x6800, 0x9086, 0x0004, 0x1190, + 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, + 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, + 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, + 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, + 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, + 0x683e, 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xcfb8, + 0x080c, 0x98bc, 0x0010, 0x080c, 0xaf4e, 0x004e, 0x003e, 0x002e, + 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, + 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb68e, 0x700c, + 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb68e, + 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, + 0x0904, 0xb68e, 0x9286, 0x0002, 0x0904, 0xb68e, 0x9286, 0x0000, + 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, + 0x0015, 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, + 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, + 0x004d, 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, + 0x6014, 0x0096, 0x2048, 0x080c, 0xcc33, 0x090c, 0x0d79, 0xa87b, + 0x0003, 0x009e, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, + 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0030, + 0x6038, 0x2070, 0x2001, 0x1989, 0x2004, 0x704a, 0x080c, 0xaf4e, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, + 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, + 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, + 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, + 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xb6fd, 0x0096, + 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, + 0x20a9, 0x0004, 0x080c, 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e, + 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, + 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb35e, + 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, + 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, + 0x129c, 0x080c, 0xb473, 0x0130, 0x00fe, 0x009e, 0x080c, 0xaf4e, + 0x00be, 0x0005, 0x080c, 0xb93c, 0x0cb8, 0x2b78, 0x00f6, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x00fe, 0x00c6, 0x080c, 0xaef8, 0x2f00, + 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, + 0x0001, 0x2001, 0x0007, 0x080c, 0x66c9, 0x080c, 0x66f5, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00ce, 0x0804, 0xb6d0, 0x2100, 0x91b2, + 0x0053, 0x1a0c, 0x0d79, 0x91b2, 0x0040, 0x1a04, 0xb786, 0x0002, + 0xb774, 0xb774, 0xb76a, 0xb774, 0xb774, 0xb774, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774, + 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb76a, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774, 0xb768, 0xb768, + 0x080c, 0x0d79, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4, 0xc08c, + 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, + 0x0032, 0x0118, 0x080c, 0x9427, 0x0010, 0x080c, 0x9420, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98bc, 0x012e, 0x0005, 0x2600, 0x0002, + 0xb774, 0xb774, 0xb79a, 0xb774, 0xb774, 0xb79a, 0xb79a, 0xb79a, + 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb79a, + 0xb79a, 0xb79a, 0x080c, 0x0d79, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0d79, 0x91b6, 0x0013, 0x0904, 0xb871, 0x91b6, 0x0027, 0x1904, + 0xb81d, 0x080c, 0x97f6, 0x6004, 0x080c, 0xce39, 0x01b0, 0x080c, + 0xce4a, 0x01a8, 0x908e, 0x0021, 0x0904, 0xb81a, 0x908e, 0x0022, + 0x1130, 0x080c, 0xb38a, 0x0904, 0xb816, 0x0804, 0xb817, 0x908e, + 0x003d, 0x0904, 0xb81a, 0x0804, 0xb810, 0x080c, 0x332a, 0x2001, + 0x0007, 0x080c, 0x66c9, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, + 0x080c, 0xb93c, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, + 0xc285, 0x080c, 0x769d, 0x1108, 0xc2ad, 0x2202, 0x080c, 0xaaf7, + 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xeafd, 0x002e, + 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, + 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x6010, 0x00b6, 0x905d, + 0x0100, 0x00be, 0x2c08, 0x080c, 0xe465, 0x007e, 0x003e, 0x002e, + 0x001e, 0x080c, 0xab13, 0x080c, 0xd372, 0x0016, 0x080c, 0xd0c6, + 0x080c, 0xaf4e, 0x001e, 0x080c, 0x3404, 0x080c, 0x98bc, 0x0030, + 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c, + 0xb93c, 0x0cb0, 0x080c, 0xb978, 0x0c98, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0d80, 0x9086, 0x0002, + 0x0904, 0xb983, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c, 0x97f6, + 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb38a, 0x09f8, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x080c, 0xce39, 0x1190, 0x080c, 0x332a, + 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb93c, 0x9186, + 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0800, + 0x080c, 0xce4a, 0x1120, 0x080c, 0xb93c, 0x0804, 0xb810, 0x6004, + 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, + 0x0000, 0x080c, 0x36a5, 0x00fe, 0x00ee, 0x0804, 0xb810, 0x6004, + 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xb93c, 0x0804, + 0xb810, 0x90b2, 0x0040, 0x1a04, 0xb91c, 0x2008, 0x0002, 0xb8b9, + 0xb8ba, 0xb8bd, 0xb8c0, 0xb8c3, 0xb8d0, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8d3, 0xb8de, 0xb8b7, + 0xb8df, 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de, + 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb907, 0xb8de, 0xb8b7, 0xb8da, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8db, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de, 0xb902, 0xb8b7, 0x080c, + 0x0d79, 0x0420, 0x2001, 0x000b, 0x0448, 0x2001, 0x0003, 0x0430, + 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, + 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8, 0x2001, 0x0001, 0x00b0, + 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd375, 0x080c, + 0x98bc, 0x0058, 0x0018, 0x0010, 0x080c, 0x66c9, 0x04b8, 0x080c, + 0xd375, 0x6003, 0x0004, 0x080c, 0x98bc, 0x0005, 0x080c, 0x66c9, + 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, + 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, + 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, + 0x98bc, 0x0c18, 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x08f0, 0x00e6, + 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36a5, 0x00fe, + 0x00ee, 0x080c, 0x97f6, 0x080c, 0xaf4e, 0x0878, 0x6003, 0x0002, + 0x080c, 0xd375, 0x0804, 0x98bc, 0x2600, 0x2008, 0x0002, 0xb933, + 0xb916, 0xb931, 0xb916, 0xb916, 0xb931, 0xb931, 0xb931, 0xb931, + 0xb916, 0xb931, 0xb916, 0xb931, 0xb916, 0xb931, 0xb931, 0xb931, + 0xb931, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0x080c, 0x6f11, + 0x009e, 0x080c, 0xaf4e, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, + 0x080c, 0xcc33, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, + 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x55ac, 0x0130, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, + 0x900e, 0x2011, 0x4005, 0x080c, 0xd237, 0x0090, 0xa868, 0xd0fc, + 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, + 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, + 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, + 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, + 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, + 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d79, 0x6604, 0x96b6, 0x004d, + 0x1120, 0x080c, 0xd156, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0043, + 0x1120, 0x080c, 0xd19f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x004b, + 0x1120, 0x080c, 0xd1cb, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0033, + 0x1120, 0x080c, 0xd0e8, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0028, + 0x1120, 0x080c, 0xce88, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0029, + 0x1120, 0x080c, 0xcec9, 0x0804, 0xba08, 0x6604, 0x96b6, 0x001f, + 0x1120, 0x080c, 0xb32f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0000, + 0x1118, 0x080c, 0xb694, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, + 0x080c, 0xb36b, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, + 0xb491, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb629, + 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb3a3, 0x0400, + 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb3df, 0x00c8, 0x6604, + 0x96b6, 0x0049, 0x1118, 0x080c, 0xb420, 0x0090, 0x6604, 0x96b6, + 0x0041, 0x1118, 0x080c, 0xb40a, 0x0058, 0x91b6, 0x0015, 0x1110, + 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbc66, + 0x00be, 0x0005, 0x080c, 0xb009, 0x0cd8, 0xba25, 0xba33, 0xba25, + 0xba7a, 0xba25, 0xbbda, 0xbc73, 0xba25, 0xba25, 0xbc3c, 0xba25, + 0xbc52, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0x009e, 0x0804, 0xaf4e, 0xa001, 0xa001, 0x0005, + 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x66b5, + 0x0804, 0xaf4e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, + 0x0074, 0x1540, 0x080c, 0xe436, 0x11b0, 0x6010, 0x00b6, 0x2058, + 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, + 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a, + 0x080c, 0xaf4e, 0x0098, 0x2001, 0x000a, 0x080c, 0x66c9, 0x080c, + 0x332a, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ee, 0x0005, + 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2069, + 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x66f5, + 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, + 0x9086, 0x0074, 0x1904, 0xbb7f, 0x6010, 0x2058, 0xbaa0, 0x9286, + 0x007e, 0x1120, 0x080c, 0xbdc2, 0x0804, 0xbaec, 0x080c, 0xbdb7, + 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, + 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x0030, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, + 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e, 0x0804, 0xbb84, + 0x080c, 0xbb92, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, + 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, + 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x08f8, 0x080c, + 0xbb88, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0004, 0x080c, + 0x66f5, 0x2001, 0x0007, 0x080c, 0x66c9, 0x08a0, 0x2001, 0x0004, + 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9427, + 0x080c, 0x98bc, 0x0804, 0xbb84, 0xb85c, 0xd0e4, 0x0178, 0x080c, + 0xd060, 0x080c, 0x769d, 0x0118, 0xd0dc, 0x1904, 0xbaae, 0x2011, + 0x1837, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbaae, 0x080c, 0xd0a1, + 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe60d, + 0x000e, 0x1904, 0xbaae, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, + 0x66c9, 0x9006, 0x080c, 0x66b5, 0x00c6, 0x2001, 0x180f, 0x2004, + 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, + 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, + 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, + 0x26ea, 0x00f6, 0x2100, 0x900e, 0x080c, 0x26a1, 0x795e, 0x00fe, + 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, + 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, + 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26ea, 0x00f6, 0x2079, + 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a1, 0x795e, + 0x00fe, 0x8108, 0x080c, 0x6718, 0x2b00, 0x00ce, 0x1904, 0xbaae, + 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, + 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, + 0x2001, 0x0002, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, + 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0028, 0x080c, + 0xb93c, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, + 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, + 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xeb56, 0x0190, 0x2071, 0x0260, + 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, + 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, + 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, + 0x66c9, 0x080c, 0x5834, 0x1120, 0x2001, 0x0007, 0x080c, 0x66f5, + 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, + 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, + 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c28, 0x004e, + 0x003e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, + 0x0804, 0xaf4e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, + 0x7090, 0x9086, 0x0014, 0x1904, 0xbc32, 0x080c, 0x5834, 0x1170, + 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, + 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00d6, 0x6010, + 0x2058, 0x080c, 0x681e, 0x080c, 0xba68, 0x00de, 0x080c, 0xbe8d, + 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, + 0x080c, 0x66c9, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, + 0x4000, 0x080c, 0xd237, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, + 0x009e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, + 0xaf4e, 0x0028, 0x080c, 0xb93c, 0x9006, 0x080c, 0xbbaa, 0x001e, + 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, + 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9427, 0x0804, 0x98bc, 0x2001, 0x0001, + 0x0804, 0xbbaa, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, + 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66c9, + 0x0804, 0xaf4e, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x0002, 0xba25, + 0xbc7e, 0xba25, 0xbcc1, 0xba25, 0xbd6e, 0xbc73, 0xba28, 0xba25, + 0xbd82, 0xba25, 0xbd94, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbda, + 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf4e, 0x0005, 0x00b6, 0x00d6, + 0x00c6, 0x080c, 0xbda6, 0x11a0, 0x9006, 0x080c, 0x66b5, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0428, + 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, + 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, + 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x32fb, 0x080c, + 0xd372, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ce, 0x00de, 0x00be, + 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbdb4, 0x00d6, + 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, + 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, + 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66b5, 0x2001, + 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0804, 0xbd3e, 0x080c, 0xcc33, 0x01b0, + 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, + 0x0016, 0x2001, 0x0002, 0x080c, 0xd294, 0x00b0, 0x6014, 0x2048, + 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, + 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, + 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xb93c, 0x2009, 0x026e, + 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, + 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, + 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, + 0x2001, 0x0004, 0x080c, 0x66c9, 0x2001, 0x0028, 0x601a, 0x6007, + 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x002e, 0x00be, + 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, + 0xcc33, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, + 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, + 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, + 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x610b, 0x00ee, 0x0010, 0x080c, 0x32fb, 0x0860, 0x2001, 0x0004, + 0x080c, 0x66c9, 0x080c, 0xbdb4, 0x1140, 0x6003, 0x0001, 0x6007, + 0x0003, 0x080c, 0x9427, 0x0804, 0x98bc, 0x080c, 0xb93c, 0x9006, + 0x0804, 0xbbaa, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66c9, + 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9427, 0x0804, 0x98bc, + 0x2001, 0x0001, 0x0804, 0xbbaa, 0x00f9, 0x1160, 0x2001, 0x000a, + 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427, + 0x0804, 0x98bc, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, + 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, + 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6792, 0x001e, 0x00ce, + 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, + 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, + 0x080c, 0xbe5f, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, + 0x080c, 0x6bc9, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, + 0xe795, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, + 0x2009, 0x0001, 0x080c, 0x32c0, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x30c8, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, + 0x080c, 0x3404, 0x8108, 0x1f04, 0xbdf8, 0x015e, 0x00ce, 0x080c, + 0xbdb7, 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, + 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, + 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, + 0x2102, 0x9184, 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, + 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, + 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, + 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, + 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26ea, 0x080c, 0x769d, + 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, + 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd060, 0x0040, + 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e, + 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, + 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, + 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, + 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf54, 0x1148, 0x2011, 0x027a, + 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf54, 0x1100, 0x015e, + 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, + 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, + 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, + 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, + 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5, + 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, + 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf20, 0x080c, 0x8d87, 0x0904, + 0xbf19, 0x080c, 0xe7c6, 0x0904, 0xbf19, 0x6720, 0x9786, 0x0007, + 0x0904, 0xbf19, 0x2500, 0x9c06, 0x0904, 0xbf19, 0x2400, 0x9c06, + 0x0904, 0xbf19, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, + 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, + 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1af0, + 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a, 0x1130, 0x00ce, 0x080c, + 0xb93c, 0x080c, 0xaf89, 0x00e8, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, + 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xaf89, + 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xbec0, + 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, + 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xe738, 0x0c30, + 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, + 0x004c, 0x080c, 0xafec, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, + 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf40, + 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, + 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, + 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, + 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, + 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, + 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, + 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, + 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf7e, 0x9006, + 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0d79, 0x080c, 0xce39, 0x0120, 0x080c, 0xce4a, 0x0158, 0x0028, + 0x080c, 0x332a, 0x080c, 0xce4a, 0x0128, 0x080c, 0x97f6, 0x080c, + 0xaf4e, 0x0005, 0x080c, 0xb93c, 0x0cc0, 0x9182, 0x0057, 0x1220, + 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfc4, 0xbfc4, 0xbfc4, + 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, + 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc6, + 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0x080c, 0x0d79, 0x600b, 0xffff, + 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd375, + 0x2009, 0x8000, 0x080c, 0x9420, 0x012e, 0x0005, 0x9186, 0x0013, + 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc04e, 0x9186, 0x0027, + 0x1520, 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, + 0x6114, 0x2148, 0x080c, 0xcc33, 0x0198, 0x080c, 0xce4a, 0x1118, + 0x080c, 0xb93c, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f11, 0x080c, 0xce24, + 0x009e, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9186, 0x0014, 0x1120, + 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c, + 0x0d79, 0x0005, 0x0002, 0xc02c, 0xc02a, 0xc02a, 0xc02a, 0xc02a, + 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc045, 0xc045, + 0xc045, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc02a, + 0xc02a, 0xc02a, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x0096, 0x6114, + 0x2148, 0x080c, 0xcc33, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6f11, 0x080c, + 0xce24, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x080c, 0x97f6, 0x080c, + 0xce4a, 0x090c, 0xb93c, 0x080c, 0xaf4e, 0x0005, 0x0002, 0xc068, + 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, + 0xc066, 0xc066, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 0xc066, 0xc06c, + 0xc066, 0xc06a, 0xc066, 0xc066, 0xc066, 0xc066, 0x080c, 0x0d79, + 0x080c, 0x0d79, 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0804, 0x98bc, + 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc0c8, 0xc1ba, 0xc08f, + 0xc1c6, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, + 0xc08f, 0xc08f, 0xc08f, 0xc1c6, 0xc091, 0xc08f, 0xc1c4, 0x080c, + 0x0d79, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800, + 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, + 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x080c, 0xaf4e, + 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, + 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xcf7f, 0x0c80, + 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644, + 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058, + 0xb800, 0xd0bc, 0x1904, 0xc1a9, 0xa87b, 0x0000, 0xa867, 0x0103, + 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, + 0xc24b, 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x601c, + 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc18a, 0x080c, 0xaf4e, + 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d79, + 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, + 0xc18e, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, + 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, + 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, + 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, + 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, + 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, + 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, + 0x1118, 0xc6c4, 0x0804, 0xc0d4, 0x735c, 0xab86, 0x83ff, 0x0170, + 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, + 0x0018, 0x2011, 0x0025, 0x080c, 0xc7ad, 0x003e, 0xd6cc, 0x0904, + 0xc0e9, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0e9, 0x9192, 0x0021, + 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc7ad, + 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd300, 0x0804, 0xc0e9, + 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, + 0x2950, 0x080c, 0xc74c, 0x00ae, 0x080c, 0xd300, 0x080c, 0xc79d, + 0x0804, 0xc0eb, 0x080c, 0xcf42, 0x0804, 0xc100, 0xa87c, 0xd0ac, + 0x0904, 0xc111, 0xa880, 0xd0bc, 0x1904, 0xc111, 0x9684, 0x0400, + 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc111, 0x00b8, 0x7348, + 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e, 0x0904, 0xc111, + 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc0dc, 0xa838, 0xa934, 0x9105, + 0x0904, 0xc0dc, 0xa880, 0xd0bc, 0x1904, 0xc0dc, 0x080c, 0xcf7f, + 0x0804, 0xc100, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, + 0x6003, 0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, + 0x0128, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, + 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, + 0x0e90, 0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, + 0xab20, 0x604b, 0x0000, 0x080c, 0x1cb9, 0x1118, 0x6144, 0x080c, + 0x944c, 0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xc212, 0xc212, 0xc212, 0xc212, 0xc212, + 0xc212, 0xc212, 0xc212, 0xc212, 0xc212, 0xc214, 0xc212, 0xc212, + 0xc212, 0xc212, 0xc225, 0xc212, 0xc212, 0xc212, 0xc212, 0xc249, + 0xc212, 0xc212, 0x080c, 0x0d79, 0x6004, 0x9086, 0x0040, 0x1110, + 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x6003, 0x0002, + 0x080c, 0xd37a, 0x080c, 0x9851, 0x0005, 0x6004, 0x9086, 0x0040, + 0x1110, 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x080c, + 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6114, 0x2148, + 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf4e, + 0x0005, 0x080c, 0x0d79, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, + 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, + 0x2009, 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, + 0xa88e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc283, + 0xc281, 0xc281, 0xc340, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, + 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc480, 0xc281, 0xc48a, + 0xc281, 0x080c, 0x0d79, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, + 0xd0f4, 0x0120, 0xc084, 0x601e, 0x0804, 0xc070, 0x6114, 0x0096, + 0x2148, 0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, + 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, + 0x7644, 0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, + 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc339, 0x9694, 0xff00, 0x9284, + 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, + 0x0904, 0xc339, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, + 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x104d, 0x090c, 0x0d79, 0x2900, + 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, + 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, + 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, + 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, + 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, + 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, + 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, + 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, + 0xc7ad, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, + 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, + 0x080c, 0xc7ad, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, + 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, + 0xc74c, 0x080c, 0x1abc, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, + 0x2001, 0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, + 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, + 0x080c, 0xd383, 0x0904, 0xc47b, 0x604b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc43f, + 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc400, 0x0016, 0xa87c, 0x0006, + 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x0904, 0xc3cd, 0x9086, 0x0028, 0x1904, 0xc3b9, 0xa87b, + 0x001c, 0xb07b, 0x001c, 0x0804, 0xc3d5, 0x6024, 0xd0f4, 0x11d0, + 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, + 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, + 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, + 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, + 0x00be, 0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, + 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, + 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf7f, 0x0804, + 0xc47b, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, + 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, + 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, + 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa87c, 0xb07e, 0xa890, + 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, + 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, + 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, + 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd300, 0x001e, + 0xa874, 0x0006, 0x2148, 0x080c, 0x0fff, 0x001e, 0x0804, 0xc46c, + 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, + 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, + 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, + 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, + 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, + 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa890, 0xb092, 0xa88c, + 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fff, 0x009e, 0x080c, + 0xd300, 0xa974, 0x0016, 0x080c, 0xc79d, 0x001e, 0x0468, 0xa867, + 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, + 0x0015, 0x080c, 0xd220, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, + 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, + 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa974, + 0x0016, 0x080c, 0x6d26, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, + 0xb8d0, 0x0016, 0x9005, 0x190c, 0x68ae, 0x001e, 0x00be, 0xd1e4, + 0x1120, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xcf42, 0x0cd8, + 0x6114, 0x0096, 0x2148, 0xa97c, 0x080c, 0xd383, 0x190c, 0x1adc, + 0x009e, 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x01e8, 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, + 0x6010, 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d26, + 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, + 0x68ae, 0x080c, 0xaf4e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, + 0xa87e, 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc24b, + 0x0c28, 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf7f, 0x0c60, 0x080c, + 0x97f6, 0x0010, 0x080c, 0x9851, 0x601c, 0xd084, 0x0110, 0x080c, + 0x1af0, 0x080c, 0xcc33, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce4a, 0x1118, 0x080c, 0xb93c, 0x00a0, 0xa867, 0x0103, 0x2009, + 0x180c, 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, + 0x918e, 0x0029, 0x1110, 0x080c, 0xeaee, 0xa877, 0x0000, 0x080c, + 0x6f11, 0x009e, 0x0804, 0xaf89, 0xa87b, 0x0004, 0x0cb0, 0xa87b, + 0x0004, 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc513, + 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, + 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc537, 0xc511, + 0xc511, 0x080c, 0x0d79, 0x080c, 0x5828, 0x01f8, 0x6014, 0x7144, + 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, + 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, + 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, + 0xa99a, 0xaa9e, 0x080c, 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x080c, + 0x5828, 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, + 0x0002, 0xc550, 0xc54e, 0xc54e, 0xc55c, 0xc54e, 0xc54e, 0xc54e, + 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0x080c, 0x0d79, + 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, + 0x080c, 0x9420, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, + 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc21, 0x01f8, + 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, + 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc80e, 0x00de, 0x00ce, + 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xc7d8, 0x0010, 0x6803, + 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xc7fa, 0x0d90, 0x6007, + 0x0087, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x7220, + 0x080c, 0xcc21, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, + 0xcf7f, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, + 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a, + 0x0092, 0x1a0c, 0x0d79, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, + 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x080c, 0x97f6, 0x0096, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0140, 0xa867, 0x0103, 0xa877, + 0x0000, 0xa87b, 0x0029, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf89, + 0x0804, 0x98bc, 0xc5df, 0xc5e1, 0xc5e1, 0xc5df, 0xc5df, 0xc5df, + 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0x080c, + 0x0d79, 0x080c, 0xaf89, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, + 0x9082, 0x0085, 0x2008, 0x0804, 0xc630, 0x9186, 0x0027, 0x1558, + 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6014, + 0x2048, 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c, + 0xaf4e, 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, + 0x080c, 0xad4d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc668, 0x0000, + 0x080c, 0xb009, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97f6, + 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x0d00, 0xa867, 0x0103, + 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, + 0x0002, 0xc640, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc654, + 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0x080c, 0x0d79, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, + 0x601a, 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, + 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, + 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, + 0xb009, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc680, 0xc6cd, 0xc67e, + 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0x080c, 0x0d79, + 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x009e, 0x0804, 0xc6e1, 0x080c, 0xcc33, 0x1118, + 0x080c, 0xce24, 0x0068, 0x6014, 0x2048, 0x080c, 0xd389, 0x1110, + 0x080c, 0xce24, 0xa867, 0x0103, 0x080c, 0xd33d, 0x080c, 0x6f11, + 0x00d6, 0x2c68, 0x080c, 0xaef8, 0x01d0, 0x6003, 0x0001, 0x6007, + 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, + 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0ce, 0x695c, + 0x615e, 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, + 0x00de, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, + 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd2d3, 0x11f0, 0x080c, 0xaef8, + 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, + 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, + 0x6938, 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0ce, + 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, 0x00de, 0x0804, 0xaf4e, + 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01c8, 0xa867, 0x0103, + 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, + 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, + 0xcf3e, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, + 0x0804, 0xaf4e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, + 0x6f11, 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, + 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb009, 0x0020, 0x080c, + 0x97f6, 0x080c, 0xaf89, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, + 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, + 0x080c, 0xc7ad, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fff, 0x080c, 0x104d, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, + 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, + 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, + 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, + 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, + 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f11, 0x2a48, + 0x0cb8, 0x080c, 0x6f11, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, + 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, + 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, + 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, + 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, + 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, + 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x715d, 0x080c, + 0x6f05, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf89, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, + 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, + 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, + 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, + 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, + 0xc860, 0xc860, 0xc85b, 0xc884, 0xc838, 0xc85b, 0xc83a, 0xc85b, + 0xc85b, 0x92df, 0xc85b, 0xc85b, 0xc85b, 0xc838, 0xc838, 0xc838, + 0x080c, 0x0d79, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, + 0xc884, 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, + 0x0118, 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, + 0x0010, 0x2019, 0x0010, 0x080c, 0xe28e, 0x6023, 0x0006, 0x6003, + 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, + 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01d0, + 0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, + 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x715d, + 0x080c, 0xcf3e, 0x080c, 0x6f05, 0x080c, 0xaf89, 0x9085, 0x0001, + 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xaaf7, 0x080c, 0xd397, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x002b, 0x0106, 0x080c, + 0xab13, 0x010e, 0x0005, 0xc8a3, 0xc8d3, 0xc8a5, 0xc8fa, 0xc8ce, + 0xc8a3, 0xc85b, 0xc860, 0xc860, 0xc85b, 0xc85b, 0xc85b, 0xc85b, + 0xc85b, 0xc85b, 0xc85b, 0x080c, 0x0d79, 0x86ff, 0x1520, 0x6020, + 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, + 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf3e, 0x009e, 0x080c, + 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, + 0x8020, 0x080c, 0x9402, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, + 0x1af0, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06, + 0x1120, 0x080c, 0xa311, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, + 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, + 0x080c, 0xa462, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa20d, + 0x190c, 0x0d79, 0x080c, 0xa21b, 0x006e, 0x00ee, 0x1904, 0xc8a5, + 0x0804, 0xc85b, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, + 0x1138, 0x901e, 0x080c, 0xa391, 0x00ee, 0x003e, 0x0804, 0xc8a5, + 0x080c, 0xa59c, 0x00ee, 0x003e, 0x1904, 0xc8a5, 0x0804, 0xc85b, + 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, + 0x0005, 0xc930, 0xc9fe, 0xcb68, 0xc938, 0xaf89, 0xc930, 0xe280, + 0xd37f, 0xc9fe, 0x92a6, 0xcbf4, 0xc929, 0xc929, 0xc929, 0xc929, + 0xc929, 0x080c, 0x0d79, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, + 0x0005, 0x080c, 0x97f6, 0x0804, 0xaf4e, 0x601b, 0x0001, 0x0005, + 0x080c, 0xcc33, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, + 0x009e, 0x080c, 0xaaf7, 0x080c, 0xd397, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0d79, 0x0013, 0x0804, 0xab13, 0xc95d, 0xc95f, 0xc989, + 0xc99d, 0xc9ca, 0xc95d, 0xc930, 0xc930, 0xc930, 0xc9a4, 0xc9a4, + 0xc95d, 0xc95d, 0xc95d, 0xc95d, 0xc9ae, 0x080c, 0x0d79, 0x00e6, + 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, + 0x19e9, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa20d, 0x190c, + 0x0d79, 0x080c, 0xa21b, 0x006e, 0x080c, 0xd317, 0x6007, 0x0085, + 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, + 0x2009, 0x8020, 0x080c, 0x9402, 0x00ee, 0x0005, 0x601b, 0x0001, + 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, + 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x2009, 0x8020, 0x080c, 0x9402, 0x0005, 0x080c, 0xaaf7, 0x080c, + 0xaccf, 0x080c, 0xab13, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, + 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5828, + 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, + 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, + 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f11, 0x009e, + 0x0804, 0xaf4e, 0x6014, 0x0096, 0x904d, 0x0558, 0xa97c, 0xd1e4, + 0x1158, 0x611c, 0xd1fc, 0x0528, 0x6110, 0x00b6, 0x2158, 0xb93c, + 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0xab13, 0x2001, 0x180f, + 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, + 0x800b, 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x21a2, 0x00ce, + 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafec, + 0x0005, 0x009e, 0x080c, 0x1af0, 0x0804, 0xc989, 0x6000, 0x908a, + 0x0010, 0x1a0c, 0x0d79, 0x000b, 0x0005, 0xca15, 0xc935, 0xca17, + 0xca15, 0xca17, 0xca17, 0xc931, 0xca15, 0xc92b, 0xc92b, 0xca15, + 0xca15, 0xca15, 0xca15, 0xca15, 0xca15, 0x080c, 0x0d79, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, - 0x1a0c, 0x0d85, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca1a, 0xcae7, - 0xca1c, 0xca5c, 0xca1c, 0xca5c, 0xca1c, 0xca2a, 0xca1a, 0xca5c, - 0xca1a, 0xca4b, 0x080c, 0x0d85, 0x6004, 0x908e, 0x0016, 0x05c0, + 0x1a0c, 0x0d79, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca32, 0xcaff, + 0xca34, 0xca74, 0xca34, 0xca74, 0xca34, 0xca42, 0xca32, 0xca74, + 0xca32, 0xca63, 0x080c, 0x0d79, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, - 0x0904, 0xcae3, 0x6004, 0x080c, 0xce2d, 0x0904, 0xcb00, 0x908e, - 0x0004, 0x1110, 0x080c, 0x333f, 0x908e, 0x0021, 0x0904, 0xcb04, - 0x908e, 0x0022, 0x0904, 0xcb4b, 0x908e, 0x003d, 0x0904, 0xcb04, - 0x908e, 0x0039, 0x0904, 0xcb08, 0x908e, 0x0035, 0x0904, 0xcb08, + 0x0904, 0xcafb, 0x6004, 0x080c, 0xce4a, 0x0904, 0xcb18, 0x908e, + 0x0004, 0x1110, 0x080c, 0x332a, 0x908e, 0x0021, 0x0904, 0xcb1c, + 0x908e, 0x0022, 0x0904, 0xcb63, 0x908e, 0x003d, 0x0904, 0xcb1c, + 0x908e, 0x0039, 0x0904, 0xcb20, 0x908e, 0x0035, 0x0904, 0xcb20, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, - 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3310, - 0x080c, 0xb91f, 0x0804, 0xaf69, 0x00c6, 0x00d6, 0x6104, 0x9186, - 0x0016, 0x0904, 0xcad4, 0x9186, 0x0002, 0x1904, 0xcaa9, 0x2001, - 0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x76a5, 0x11b0, 0x080c, - 0xd33e, 0x0138, 0x080c, 0x76c8, 0x1120, 0x080c, 0x75ae, 0x0804, - 0xcb34, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, - 0x0001, 0x080c, 0x75d4, 0x0804, 0xcb34, 0x6010, 0x2058, 0x2001, - 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb34, 0xb8a0, 0x9084, 0xff80, - 0x1904, 0xcb34, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x32fb, + 0x080c, 0xb93c, 0x0804, 0xaf89, 0x00c6, 0x00d6, 0x6104, 0x9186, + 0x0016, 0x0904, 0xcaec, 0x9186, 0x0002, 0x1904, 0xcac1, 0x2001, + 0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x769d, 0x11b0, 0x080c, + 0xd35d, 0x0138, 0x080c, 0x76c0, 0x1120, 0x080c, 0x75a6, 0x0804, + 0xcb4c, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, + 0x0001, 0x080c, 0x75cc, 0x0804, 0xcb4c, 0x6010, 0x2058, 0x2001, + 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb4c, 0xb8a0, 0x9084, 0xff80, + 0x1904, 0xcb4c, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, - 0x0000, 0x080c, 0xaed8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, + 0x0000, 0x080c, 0xaef8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, - 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x00ee, - 0x080c, 0xb91f, 0x0030, 0x080c, 0xb91f, 0x080c, 0x3310, 0x080c, - 0xd353, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f, 0x012e, - 0x00ee, 0x080c, 0xaf69, 0x0005, 0x2001, 0x0002, 0x080c, 0x66cf, - 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, - 0x00de, 0x00ce, 0x0c80, 0x080c, 0x333f, 0x0804, 0xca58, 0x00c6, + 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x610b, 0x00ee, + 0x080c, 0xb93c, 0x0030, 0x080c, 0xb93c, 0x080c, 0x32fb, 0x080c, + 0xd372, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a, 0x012e, + 0x00ee, 0x080c, 0xaf89, 0x0005, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, + 0x00de, 0x00ce, 0x0c80, 0x080c, 0x332a, 0x0804, 0xca70, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, - 0x9084, 0x00ff, 0x9005, 0x0904, 0xcaa9, 0x8001, 0xb842, 0x6003, - 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00de, 0x00ce, 0x0898, - 0x080c, 0xb91f, 0x0804, 0xca5a, 0x080c, 0xb95b, 0x0804, 0xca5a, - 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2b6, 0x00de, 0x0118, 0x080c, - 0xaf2e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, + 0x9084, 0x00ff, 0x9005, 0x0904, 0xcac1, 0x8001, 0xb842, 0x6003, + 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x00de, 0x00ce, 0x0898, + 0x080c, 0xb93c, 0x0804, 0xca72, 0x080c, 0xb978, 0x0804, 0xca72, + 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2d3, 0x00de, 0x0118, 0x080c, + 0xaf4e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x2009, - 0x8020, 0x080c, 0x9428, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb91f, - 0x080c, 0x3310, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f, + 0x8020, 0x080c, 0x9420, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb93c, + 0x080c, 0x32fb, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000, - 0x012e, 0x00ee, 0x0005, 0x080c, 0xb36d, 0x1904, 0xcb00, 0x0005, - 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x00d6, 0x001b, - 0x00de, 0x009e, 0x0005, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, - 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xc917, 0xcb6b, 0xc91c, 0xcb6d, - 0xc91c, 0xcb87, 0xcb6b, 0x080c, 0x0d85, 0x6004, 0x9086, 0x008b, + 0x012e, 0x00ee, 0x0005, 0x080c, 0xb38a, 0x1904, 0xcb18, 0x0005, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x00d6, 0x001b, + 0x00de, 0x009e, 0x0005, 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xcb83, + 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xc930, 0xcb83, 0xc935, 0xcb85, + 0xc935, 0xcb9f, 0xcb83, 0x080c, 0x0d79, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, - 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005, 0x080c, - 0xd332, 0x0118, 0x080c, 0xd345, 0x0010, 0x080c, 0xd353, 0x080c, - 0xce07, 0x080c, 0xcc16, 0x0570, 0x080c, 0x3310, 0x080c, 0xcc16, + 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9420, 0x0005, 0x080c, + 0xd351, 0x0118, 0x080c, 0xd364, 0x0010, 0x080c, 0xd372, 0x080c, + 0xce24, 0x080c, 0xcc33, 0x0570, 0x080c, 0x32fb, 0x080c, 0xcc33, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, - 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f19, 0x2c68, 0x080c, - 0xaed8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0b1, 0x00c6, 0x2d60, - 0x080c, 0xaf69, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, - 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c, - 0x98bf, 0x00c8, 0x080c, 0xd332, 0x0138, 0x6034, 0x9086, 0x4000, - 0x1118, 0x080c, 0x3310, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, - 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3310, - 0x0868, 0x080c, 0xaf69, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, - 0x0d85, 0x0002, 0xcbf2, 0xcbf2, 0xcbf4, 0xcbf4, 0xcbf4, 0xcbf2, - 0xcbf2, 0xaf69, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, - 0xcbf2, 0xcbf2, 0x080c, 0x0d85, 0x080c, 0xaae0, 0x080c, 0xacaf, - 0x080c, 0xaafc, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, - 0x6f19, 0x009e, 0x0804, 0xaf2e, 0x9284, 0x0003, 0x1158, 0x9282, - 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, - 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, - 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, - 0x0110, 0x080c, 0x1104, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, - 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071, - 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, - 0x080c, 0xd33e, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, - 0x0004, 0x1148, 0x080c, 0x3310, 0x080c, 0xd353, 0x00c6, 0x080c, - 0xaf69, 0x00ce, 0x0060, 0x080c, 0xd023, 0x0148, 0x080c, 0xce2d, - 0x1110, 0x080c, 0xb91f, 0x00c6, 0x080c, 0xaf2e, 0x00ce, 0x9ce0, - 0x001c, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, - 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, - 0x210c, 0x81ff, 0x0128, 0x2061, 0x1b3a, 0x6112, 0x080c, 0x3310, - 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8, 0x01b0, 0x665e, - 0x2b00, 0x6012, 0x080c, 0x582e, 0x0118, 0x080c, 0xcd49, 0x0168, - 0x080c, 0xd0b1, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xafcc, - 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, - 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xaf9f, 0x0580, 0x605f, - 0x0000, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0003, 0x0016, - 0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, - 0x2c08, 0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x001e, 0xd184, - 0x0128, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x0070, 0x080c, 0x582e, - 0x0128, 0xd18c, 0x1170, 0x080c, 0xcd49, 0x0148, 0x2009, 0x004c, - 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, - 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0xaed8, 0x2c78, - 0x05a0, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, - 0x0005, 0x080c, 0xcd5b, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, - 0x004e, 0x0148, 0x2001, 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, - 0x080c, 0xaf2e, 0x00d0, 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, - 0x2f60, 0x080c, 0xaf2e, 0x0088, 0x2f60, 0x080c, 0x582e, 0x0138, - 0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, - 0x0016, 0x080c, 0xafcc, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, - 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0xaed8, 0x2c78, - 0x0508, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, - 0x0004, 0x0489, 0x009e, 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, - 0x2f60, 0x080c, 0xaf2e, 0x0060, 0x2f60, 0x080c, 0x582e, 0x0120, - 0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xafcc, - 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, - 0x0c98, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x1120, 0x080c, 0xaf2e, - 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, - 0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, - 0x080c, 0xaae0, 0x080c, 0x696b, 0x0158, 0x2001, 0xcd62, 0x0006, - 0x900e, 0x2400, 0x080c, 0x7165, 0x080c, 0x6f19, 0x000e, 0x0807, - 0x2418, 0x080c, 0x97c4, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, - 0x0001, 0x2608, 0x080c, 0x95db, 0x008e, 0x080c, 0x947e, 0x2f08, - 0x2648, 0x080c, 0xe440, 0xb93c, 0x81ff, 0x090c, 0x96b4, 0x080c, - 0xaafc, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0xaed8, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, - 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, - 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x01b8, 0x660a, - 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0008, 0x2900, 0x6016, - 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0021, 0x080c, - 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, - 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, - 0xaed8, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, - 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xafcc, 0x9085, - 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0188, 0x2b08, 0x6112, - 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, - 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, - 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e, - 0x1140, 0xb8d0, 0x9005, 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b, - 0x0001, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, - 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, - 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, - 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc16, - 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, - 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, - 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0198, 0x2b08, 0x6112, - 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x3310, - 0x2009, 0x0028, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, - 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, - 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbb81, 0x00be, - 0x080c, 0xbda6, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, - 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd277, 0x080c, 0xb91f, - 0x080c, 0xaf2e, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85, - 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, - 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, - 0x009e, 0x080c, 0xaf2e, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, - 0x2001, 0x0004, 0x080c, 0x66cf, 0x00e8, 0x9186, 0x0015, 0x1510, - 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, - 0x2058, 0x080c, 0x6824, 0x00be, 0x080c, 0xbe77, 0x1198, 0x6010, - 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, - 0x080c, 0x66cf, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, - 0xb341, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, - 0xb91f, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, - 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, - 0x4000, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, - 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, - 0x012e, 0x080c, 0xaf2e, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d85, - 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, - 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, - 0x080c, 0xaf2e, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, - 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x604b, 0x0000, 0x6017, - 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, - 0x9428, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0130, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, - 0x00ce, 0x0005, 0xc917, 0xcf54, 0xcf54, 0xcf57, 0xe779, 0xe794, - 0xe797, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, - 0xc917, 0xc917, 0x080c, 0x0d85, 0xa001, 0xa001, 0x0005, 0x0096, - 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, - 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0550, 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, - 0x080c, 0xaed8, 0x0508, 0x7810, 0x6012, 0x080c, 0xd0b1, 0x7820, - 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, - 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, - 0x0035, 0x6003, 0x0001, 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, - 0x9428, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, - 0x2004, 0x604a, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0x681c, - 0xd0fc, 0xc0fc, 0x681e, 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4, - 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, - 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x100b, 0x6830, - 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, - 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, - 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, - 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, - 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, - 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x695c, 0x615e, 0x6023, - 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, - 0x9428, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, - 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, - 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, - 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, - 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, - 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, - 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, - 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, - 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, - 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, - 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, - 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, - 0x936c, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, - 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d, 0x711a, - 0x721e, 0x2001, 0x0064, 0x080c, 0x936c, 0x2001, 0x1988, 0x82ff, - 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288, 0x000a, - 0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91, 0x2102, - 0x2001, 0x0032, 0x080c, 0x16b9, 0x080c, 0x6bb6, 0x00ee, 0x003e, - 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, - 0x1987, 0x2003, 0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, - 0x196d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, - 0x001e, 0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91, - 0x2102, 0x2001, 0x0032, 0x080c, 0x16b9, 0x00ee, 0x001e, 0x000e, - 0x0005, 0x0096, 0x6060, 0x904d, 0x0110, 0x080c, 0x108b, 0x009e, - 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8, - 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, - 0x2009, 0x0033, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, - 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, - 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, 0x7090, - 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, - 0x2c78, 0x080c, 0x998f, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, - 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, - 0x00be, 0x900e, 0x080c, 0x335f, 0x080c, 0xb341, 0x0020, 0x080c, - 0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, - 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0xaed8, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, - 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xafcc, 0x9085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, - 0x2091, 0x8000, 0x0016, 0x080c, 0xaed8, 0x0180, 0x2b08, 0x6112, - 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, - 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, - 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, - 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x7190, - 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, - 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, - 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, - 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x080c, - 0xd998, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, - 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb91f, 0x080c, 0xaf2e, - 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, - 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, - 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, - 0x2c78, 0x080c, 0x998f, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, - 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3310, 0x080c, 0xb341, - 0x0020, 0x080c, 0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, - 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, - 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, 0x9086, - 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998f, 0x05f0, - 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, - 0x080c, 0x3310, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, - 0x080c, 0x57cf, 0x001e, 0x0010, 0x080c, 0x55b2, 0x080c, 0xcc16, - 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, - 0x080c, 0xcc16, 0x01b8, 0x6014, 0x2048, 0x080c, 0x55b2, 0x1d70, - 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, - 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6f19, 0x012e, - 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, - 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, - 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, - 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, - 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xcc16, 0x0904, - 0xd273, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, - 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, - 0x1140, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, - 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, - 0x2098, 0x080c, 0x0fd6, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, - 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x00ce, - 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, - 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, - 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f0d, - 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, - 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, - 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, - 0x00ff, 0x900e, 0x080c, 0x26a2, 0x2118, 0x831f, 0x939c, 0xff00, - 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, - 0x4c2e, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, - 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, - 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, - 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, - 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, - 0xcc04, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, - 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, - 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, - 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, - 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff, - 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e, - 0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0x0005, - 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, - 0x080c, 0xcc16, 0x01c8, 0x080c, 0xce07, 0x6037, 0x4000, 0x6014, - 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce2d, 0x1118, - 0x080c, 0xb91f, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, - 0x1129, 0x080c, 0x6f19, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, - 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, - 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21, 0xa877, - 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, - 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, - 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, - 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4de5, - 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987, - 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, - 0x080c, 0xaf2e, 0x0804, 0x98bf, 0x611c, 0xd1fc, 0xa97c, 0x1108, - 0xd1e4, 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, - 0x601c, 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, - 0x6044, 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003, - 0x0002, 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f, - 0x9186, 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, - 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85, - 0x001b, 0x006e, 0x00be, 0x0005, 0xd3ac, 0xdaf5, 0xdc64, 0xd3ac, - 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3e3, 0xdce8, 0xd3ac, 0xd3ac, - 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0x080c, 0x0d85, 0x0066, 0x6000, - 0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xd3c7, - 0xe209, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xe1b8, - 0xe25b, 0xd3c7, 0xe8b4, 0xe8e8, 0xe8b4, 0xe8e8, 0xd3c7, 0x080c, - 0x0d85, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x000a, - 0x0005, 0xd3e1, 0xdec5, 0xdf90, 0xdfb3, 0xe02f, 0xd3e1, 0xe12a, - 0xe0b7, 0xdcf2, 0xe190, 0xe1a5, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1, - 0xd3e1, 0x080c, 0x0d85, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x2100, - 0x91b2, 0x0040, 0x1a04, 0xd867, 0x0002, 0xd42d, 0xd635, 0xd42d, - 0xd42d, 0xd42d, 0xd63e, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, - 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, - 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42f, 0xd496, 0xd4a5, 0xd509, - 0xd534, 0xd5ad, 0xd620, 0xd42d, 0xd42d, 0xd641, 0xd42d, 0xd42d, - 0xd656, 0xd663, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd709, - 0xd42d, 0xd42d, 0xd71d, 0xd42d, 0xd42d, 0xd6d8, 0xd42d, 0xd42d, - 0xd42d, 0xd735, 0xd42d, 0xd42d, 0xd42d, 0xd7b2, 0xd42d, 0xd42d, - 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd82f, 0x080c, 0x0d85, 0x080c, - 0x6b93, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, - 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, - 0x6017, 0x0000, 0x0804, 0xd62e, 0x080c, 0x6b2f, 0x00e6, 0x00c6, - 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, - 0x0029, 0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, - 0x947e, 0x2c08, 0x080c, 0xe440, 0x007e, 0x001e, 0x080c, 0xaafc, - 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, - 0x6798, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, - 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, - 0xeb13, 0x002e, 0x001e, 0x1178, 0x080c, 0xe36e, 0x1904, 0xd501, - 0x080c, 0xe30a, 0x1120, 0x6007, 0x0008, 0x0804, 0xd62e, 0x6007, - 0x0009, 0x0804, 0xd62e, 0x080c, 0xe5a2, 0x0128, 0x080c, 0xe36e, - 0x0d78, 0x0804, 0xd501, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3447, - 0x1904, 0xd864, 0x6106, 0x080c, 0xe2bb, 0x6007, 0x0006, 0x0804, - 0xd62e, 0x6007, 0x0007, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904, - 0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x00d6, 0x6610, 0x2658, - 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, - 0x080c, 0x66bb, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, - 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, - 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, - 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, - 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, - 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, - 0xe3d6, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, - 0xbaa0, 0x900e, 0x080c, 0x335f, 0x002e, 0x080c, 0x6824, 0x6007, - 0x000a, 0x00de, 0x0804, 0xd62e, 0x6007, 0x000b, 0x00de, 0x0804, - 0xd62e, 0x080c, 0x3310, 0x080c, 0xd353, 0x6007, 0x0001, 0x0804, - 0xd62e, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904, - 0xd864, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, - 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, - 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, - 0x900e, 0x080c, 0x335f, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, - 0x080c, 0xeaf2, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140, 0x2001, + 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f11, 0x2c68, 0x080c, + 0xaef8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x00c6, 0x2d60, + 0x080c, 0xaf89, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x00c8, 0x080c, 0xd351, 0x0138, 0x6034, 0x9086, 0x4000, + 0x1118, 0x080c, 0x32fb, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x32fb, + 0x0868, 0x080c, 0xaf89, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, + 0x0d79, 0x0002, 0xcc0a, 0xcc0a, 0xcc12, 0xcc0c, 0xcc1c, 0xcc0a, + 0xcc0a, 0xaf89, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, + 0xcc0a, 0xcc0a, 0x080c, 0x0d79, 0x080c, 0xaaf7, 0x080c, 0xaccf, + 0x080c, 0xab13, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, + 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x601c, 0xd084, 0x190c, 0x1af0, + 0x0c88, 0x9284, 0x0003, 0x1158, 0x9282, 0x1ddc, 0x0240, 0x2001, + 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, + 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, + 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10f8, + 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7354, 0x7074, + 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd35d, 0x0180, + 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x00c6, 0x080c, 0xaf89, 0x00ce, 0x0060, + 0x080c, 0xd040, 0x0148, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, + 0x00c6, 0x080c, 0xaf4e, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, + 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, + 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, + 0x2061, 0x1b3a, 0x6112, 0x080c, 0x32fb, 0x9006, 0x0010, 0x9085, + 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xaef8, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, + 0x5828, 0x0118, 0x080c, 0xcd66, 0x0168, 0x080c, 0xd0ce, 0x6023, + 0x0003, 0x2009, 0x004b, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, + 0xbaa0, 0x080c, 0xafbf, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x6023, 0x0003, 0x0016, 0x080c, 0xaaf7, 0x080c, + 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, + 0x007e, 0x080c, 0xab13, 0x001e, 0xd184, 0x0128, 0x080c, 0xaf4e, + 0x9085, 0x0001, 0x0070, 0x080c, 0x5828, 0x0128, 0xd18c, 0x1170, + 0x080c, 0xcd66, 0x0148, 0x2009, 0x004c, 0x080c, 0xafec, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, + 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, + 0x0046, 0x0016, 0x080c, 0xaef8, 0x2c78, 0x05a0, 0x7e5e, 0x2b00, + 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcd78, + 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, + 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xaf4e, 0x00d0, + 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e, + 0x0088, 0x2f60, 0x080c, 0x5828, 0x0138, 0xd18c, 0x1118, 0x04f1, + 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xafec, + 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, + 0x00c6, 0x0046, 0x080c, 0xaef8, 0x2c78, 0x0508, 0x7e5e, 0x2b00, + 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, + 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e, + 0x0060, 0x2f60, 0x080c, 0x5828, 0x0120, 0xd18c, 0x1160, 0x0071, + 0x0130, 0x2009, 0x0052, 0x080c, 0xafec, 0x9085, 0x0001, 0x004e, + 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, + 0x4bc8, 0x00ce, 0x1120, 0x080c, 0xaf4e, 0x9006, 0x0005, 0xa867, + 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, + 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xaaf7, 0x080c, + 0x6963, 0x0158, 0x2001, 0xcd7f, 0x0006, 0x900e, 0x2400, 0x080c, + 0x715d, 0x080c, 0x6f11, 0x000e, 0x0807, 0x2418, 0x080c, 0x97bc, + 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, + 0x95d3, 0x008e, 0x080c, 0x9476, 0x2f08, 0x2648, 0x080c, 0xe465, + 0xb93c, 0x81ff, 0x090c, 0x96ac, 0x080c, 0xab13, 0x012e, 0x007e, + 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, + 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, + 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xafec, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xafbf, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xd0ce, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, + 0x17a1, 0x00fe, 0x2009, 0x0021, 0x080c, 0xafec, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, + 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0198, 0x660a, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016, + 0x001e, 0x0016, 0x080c, 0xafec, 0x9085, 0x0001, 0x001e, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x080c, 0xafbf, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xafec, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, + 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, + 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e, 0x1140, 0xb8d0, 0x9005, + 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b, 0x0001, 0x00be, 0x002e, + 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, + 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, + 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, + 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc33, 0x0180, 0xa864, 0x9086, + 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, + 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, + 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x080c, 0xafbf, 0x0198, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x080c, 0x32fb, 0x2009, 0x0028, 0x080c, + 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, + 0x1178, 0x00b6, 0x080c, 0xbb92, 0x00be, 0x080c, 0xbdb7, 0x6003, + 0x0001, 0x6007, 0x0029, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0078, + 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, + 0x0001, 0x080c, 0xd294, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x0005, + 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x080c, 0xaf4e, + 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, + 0x66c9, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, + 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x681e, + 0x00be, 0x080c, 0xbe8d, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, + 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x66c9, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xb35e, 0x0048, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xb93c, 0x080c, 0xaf4e, + 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d79, + 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, + 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, + 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x0840, + 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, + 0xa882, 0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, + 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9420, 0x0005, 0x00c6, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066, + 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc930, + 0xcf71, 0xcf71, 0xcf74, 0xe7e4, 0xe7ff, 0xe802, 0xc930, 0xc930, + 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0x080c, + 0x0d79, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, + 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1834, + 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xaef8, 0x0508, + 0x7810, 0x6012, 0x080c, 0xd0ce, 0x7820, 0x9086, 0x0003, 0x0128, + 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, + 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, + 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, 0x9420, 0x2f60, 0x00fe, + 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, + 0x0016, 0x0096, 0x6814, 0x2048, 0x681c, 0xd0fc, 0xc0fc, 0x681e, + 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, + 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, + 0xa878, 0x2048, 0x080c, 0x0fff, 0x6830, 0x6036, 0x908e, 0x0001, + 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, + 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, + 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, + 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, + 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, + 0x6910, 0x6112, 0x695c, 0x615e, 0x6023, 0x0001, 0x6007, 0x0039, + 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x009e, 0x001e, + 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, + 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, + 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, + 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, + 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, + 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, + 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, + 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, + 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, + 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, + 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1983, 0x200c, + 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x9364, 0x2001, 0x1987, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1985, 0x200c, + 0x8000, 0x2014, 0x2071, 0x196d, 0x711a, 0x721e, 0x2001, 0x0064, + 0x080c, 0x9364, 0x2001, 0x1988, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x1989, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017, + 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032, 0x080c, + 0x16ad, 0x080c, 0x6bae, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028, + 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001, + 0x0017, 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032, + 0x080c, 0x16ad, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060, + 0x904d, 0x0110, 0x080c, 0x107f, 0x009e, 0x0005, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112, + 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, + 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, + 0x7090, 0x9086, 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, + 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x998c, + 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, + 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, + 0x334a, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c, 0x080c, 0xaf4e, + 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, + 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x004d, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, + 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xafec, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, + 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, + 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003, + 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, + 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, + 0x2001, 0x19a2, 0x0016, 0x200c, 0x080c, 0xd9b7, 0x001e, 0xa804, + 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, + 0x0010, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, + 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, + 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998c, + 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, + 0x1110, 0x080c, 0x32fb, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c, + 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, + 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x998c, 0x05f0, 0x707c, 0xaacc, 0x9206, + 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x32fb, 0x0016, + 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e, + 0x0010, 0x080c, 0x55ac, 0x080c, 0xcc33, 0x0508, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcc33, 0x01b8, + 0x6014, 0x2048, 0x080c, 0x55ac, 0x1d70, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x00fe, + 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, + 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, + 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, + 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, + 0x00d6, 0x0036, 0x080c, 0xcc33, 0x0904, 0xd290, 0x0096, 0x6314, + 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, + 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6a74, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, + 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, + 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fca, + 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x080c, 0x0fca, 0x00ce, 0x0090, 0xaa96, 0x3918, + 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, + 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, + 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f05, 0x6017, 0x0000, 0x009e, + 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, + 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, + 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, + 0x26a1, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, + 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4c28, 0x00a8, 0x9096, + 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, + 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, + 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, + 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, + 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xcc21, 0x01f0, 0x2260, + 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, + 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, + 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, + 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, + 0xa974, 0xd1cc, 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170, + 0xa9a8, 0x918c, 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0x0005, 0x0036, + 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, + 0xcc33, 0x01c8, 0x080c, 0xce24, 0x6037, 0x4000, 0x6014, 0x6017, + 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, + 0x080c, 0x6f11, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, + 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, + 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf3e, 0xa877, 0x0000, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, + 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, + 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, + 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4ddf, 0x004e, + 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987, 0x2004, + 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, 0x080c, + 0xaf4e, 0x0804, 0x98bc, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4, + 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x601c, + 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x6044, + 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003, 0x0002, + 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186, + 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x0005, + 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x001b, + 0x006e, 0x00be, 0x0005, 0xd3cb, 0xdb14, 0xdc78, 0xd3cb, 0xd3cb, + 0xd3cb, 0xd3cb, 0xd3cb, 0xd402, 0xdcfc, 0xd3cb, 0xd3cb, 0xd3cb, + 0xd3cb, 0xd3cb, 0xd3cb, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xd3e6, 0xe21d, + 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xe1cc, 0xe26f, + 0xd3e6, 0xe91f, 0xe953, 0xe91f, 0xe953, 0xd3e6, 0x080c, 0x0d79, + 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x000a, 0x0005, + 0xd400, 0xded9, 0xdfa4, 0xdfc7, 0xe043, 0xd400, 0xe13e, 0xe0cb, + 0xdd06, 0xe1a4, 0xe1b9, 0xd400, 0xd400, 0xd400, 0xd400, 0xd400, + 0x080c, 0x0d79, 0x91b2, 0x0053, 0x1a0c, 0x0d79, 0x2100, 0x91b2, + 0x0040, 0x1a04, 0xd886, 0x0002, 0xd44c, 0xd654, 0xd44c, 0xd44c, + 0xd44c, 0xd65d, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd44e, 0xd4b5, 0xd4c4, 0xd528, 0xd553, + 0xd5cc, 0xd63f, 0xd44c, 0xd44c, 0xd660, 0xd44c, 0xd44c, 0xd675, + 0xd682, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd728, 0xd44c, + 0xd44c, 0xd73c, 0xd44c, 0xd44c, 0xd6f7, 0xd44c, 0xd44c, 0xd44c, + 0xd754, 0xd44c, 0xd44c, 0xd44c, 0xd7d1, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd84e, 0x080c, 0x0d79, 0x080c, 0x6b8b, + 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, + 0x0000, 0x0804, 0xd64d, 0x080c, 0x6b27, 0x00e6, 0x00c6, 0x0036, + 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, + 0x080c, 0xaaf7, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x080c, 0xab13, 0x001e, + 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6792, + 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, + 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xeb7e, + 0x002e, 0x001e, 0x1178, 0x080c, 0xe393, 0x1904, 0xd520, 0x080c, + 0xe32f, 0x1120, 0x6007, 0x0008, 0x0804, 0xd64d, 0x6007, 0x0009, + 0x0804, 0xd64d, 0x080c, 0xe60d, 0x0128, 0x080c, 0xe393, 0x0d78, + 0x0804, 0xd520, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3432, 0x1904, + 0xd883, 0x6106, 0x080c, 0xe2cf, 0x6007, 0x0006, 0x0804, 0xd64d, + 0x6007, 0x0007, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883, + 0x080c, 0x3432, 0x1904, 0xd883, 0x00d6, 0x6610, 0x2658, 0xbe04, + 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, + 0x66b5, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, + 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, + 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, + 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, + 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, + 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe3fb, + 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, + 0x900e, 0x080c, 0x334a, 0x002e, 0x080c, 0x681e, 0x6007, 0x000a, + 0x00de, 0x0804, 0xd64d, 0x6007, 0x000b, 0x00de, 0x0804, 0xd64d, + 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007, 0x0001, 0x0804, 0xd64d, + 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883, + 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, + 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, + 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, + 0x080c, 0x334a, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, + 0xeb5d, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001, 0x1837, + 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd45b, + 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x66f5, + 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, + 0x9686, 0x0006, 0x1904, 0xd520, 0x080c, 0xe408, 0x1120, 0x6007, + 0x000e, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, + 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016, 0x9006, 0x2009, + 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe795, + 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, + 0x0001, 0x0804, 0xd64d, 0x2001, 0x0001, 0x080c, 0x66b5, 0x0156, + 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x0270, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, + 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd520, + 0x9682, 0x0007, 0x0a04, 0xd57c, 0x0804, 0xd520, 0x6017, 0x1900, + 0x6007, 0x0009, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, - 0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, - 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, - 0x66fb, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, - 0x0120, 0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe3e3, 0x1120, - 0x6007, 0x000e, 0x0804, 0xd62e, 0x0046, 0x6410, 0x2458, 0xbca0, - 0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e, 0x0016, 0x9006, - 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, - 0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, - 0x6007, 0x0001, 0x0804, 0xd62e, 0x2001, 0x0001, 0x080c, 0x66bb, - 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, - 0x2011, 0x0270, 0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e, - 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, - 0xd501, 0x9682, 0x0007, 0x0a04, 0xd55d, 0x0804, 0xd501, 0x6017, - 0x1900, 0x6007, 0x0009, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140, - 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, - 0x0804, 0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684, - 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, - 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, - 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, - 0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe411, 0x1138, 0x080c, - 0xe30a, 0x1120, 0x6007, 0x0010, 0x0804, 0xd62e, 0x0046, 0x6410, - 0x2458, 0xbca0, 0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e, - 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, - 0x0029, 0x080c, 0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, - 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe5a2, 0x0198, - 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, - 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, - 0x0804, 0xd501, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, - 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xe924, 0x1904, 0xd864, - 0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0012, 0x6003, 0x0001, - 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0001, 0x6003, - 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0cb0, 0x6007, 0x0005, - 0x0c68, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904, - 0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0020, 0x6003, - 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x080c, 0x3447, - 0x1904, 0xd864, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x0005, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, - 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x0016, - 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, - 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, - 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc04, 0x0570, 0x2260, - 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, - 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xaf2e, 0x04a0, 0x7244, - 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc04, 0x01b0, 0x2260, - 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, - 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe6f4, - 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, - 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, - 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, - 0x1110, 0x080c, 0xaf2e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, - 0x080c, 0x942f, 0x080c, 0x98bf, 0x00ee, 0x002e, 0x001e, 0x0005, - 0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016, 0x0026, 0x0036, - 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf2a, - 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, - 0xd62e, 0x080c, 0xbb99, 0x080c, 0x76a5, 0x1190, 0x0006, 0x0026, - 0x0036, 0x080c, 0x76bf, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e, - 0x080c, 0x75d4, 0x0010, 0x080c, 0x7679, 0x003e, 0x002e, 0x000e, - 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904, - 0xd501, 0x6106, 0x080c, 0xda51, 0x1120, 0x6007, 0x002b, 0x0804, - 0xd62e, 0x6007, 0x002c, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904, - 0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904, - 0xd501, 0x6106, 0x080c, 0xda56, 0x1120, 0x6007, 0x002e, 0x0804, - 0xd62e, 0x6007, 0x002f, 0x0804, 0xd62e, 0x080c, 0x3447, 0x1904, - 0xd864, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, - 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, - 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd635, 0x080c, - 0x582a, 0xd0e4, 0x0904, 0xd7af, 0x2071, 0x026c, 0x7010, 0x603a, - 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6bd1, 0x0140, 0x6010, - 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, - 0x6bcd, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, - 0x9106, 0x1578, 0x7210, 0x080c, 0xcc04, 0x0590, 0x080c, 0xd922, - 0x0578, 0x080c, 0xe7a6, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, - 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ce, 0x00de, 0x00ee, - 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc04, 0x01c0, - 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, - 0x2c08, 0x9085, 0x0001, 0x080c, 0xe6f4, 0x2c10, 0x2160, 0x0140, - 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, - 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, - 0x0012, 0x0868, 0x080c, 0x3447, 0x1904, 0xd864, 0x6010, 0x2058, - 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd635, - 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x582a, 0xd0e4, 0x0904, 0xd827, - 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, - 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, - 0x080c, 0xe6f4, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc04, 0x05d0, - 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, - 0x2260, 0x080c, 0xc7f5, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, - 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, - 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, - 0xd922, 0x0904, 0xd7a8, 0x0056, 0x7510, 0x7614, 0x080c, 0xe7bf, - 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, - 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, - 0x9428, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0c10, 0x6007, - 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd77f, 0x00e6, - 0x0026, 0x080c, 0x6b93, 0x0550, 0x080c, 0x6b2f, 0x080c, 0xe995, - 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, - 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, - 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, - 0x080c, 0x6bd1, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac, - 0x1128, 0x080c, 0x30e1, 0x0010, 0x080c, 0xe9c9, 0x002e, 0x00ee, - 0x080c, 0xaf2e, 0x0804, 0xd634, 0x080c, 0xaf2e, 0x0005, 0x2600, - 0x0002, 0xd87b, 0xd8a9, 0xd8ba, 0xd87b, 0xd87b, 0xd87d, 0xd8cb, - 0xd87b, 0xd87b, 0xd87b, 0xd897, 0xd87b, 0xd87b, 0xd87b, 0xd8d6, - 0xd8ec, 0xd91d, 0xd87b, 0x080c, 0x0d85, 0x080c, 0xe924, 0x1d20, - 0x080c, 0x3447, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, - 0x0001, 0x080c, 0x942f, 0x0005, 0x080c, 0x3310, 0x080c, 0xd353, - 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x0005, 0x080c, - 0xe924, 0x1950, 0x080c, 0x3447, 0x1938, 0x080c, 0xda35, 0x1d60, - 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x942f, - 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0041, 0x080c, - 0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c, - 0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0042, - 0x080c, 0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, - 0x0046, 0x080c, 0xe9d2, 0x080c, 0xaf2e, 0x0005, 0x2001, 0x1824, - 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xd93f, 0x0904, 0xd864, - 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, - 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, - 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, - 0x7140, 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, - 0x19c0, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, - 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, - 0x080c, 0xbf3e, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, - 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0050, 0x703c, - 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, - 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c, - 0x9106, 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010, - 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, - 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, - 0x080c, 0x1072, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, - 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, - 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1072, - 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, - 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, - 0x1800, 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x100b, 0x9006, - 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, - 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, - 0x080c, 0x221a, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, - 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, - 0x8108, 0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x221a, - 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, - 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, - 0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, 0x2019, - 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, - 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, - 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, - 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2232, 0x20a1, - 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, - 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, - 0x2232, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2232, 0x2061, 0x19a4, - 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, - 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, - 0x2232, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, 0x0260, - 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, + 0xd45b, 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, + 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, + 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, + 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, + 0x0006, 0x1904, 0xd520, 0x080c, 0xe436, 0x1138, 0x080c, 0xe32f, + 0x1120, 0x6007, 0x0010, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458, + 0xbca0, 0x0046, 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016, + 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, + 0x080c, 0xe795, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, + 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe60d, 0x0198, 0x0016, + 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, + 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, + 0xd520, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, + 0x3432, 0x1904, 0xd883, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, + 0xda54, 0x1904, 0xd520, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x9427, 0x080c, 0x98bc, 0x0cb0, 0x6007, 0x0005, 0x0c68, + 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883, + 0x080c, 0xda54, 0x1904, 0xd520, 0x6007, 0x0020, 0x6003, 0x0001, + 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904, + 0xd883, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0005, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, + 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, + 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, + 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc21, 0x0570, 0x2260, 0x6008, + 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, + 0x9086, 0x0007, 0x1508, 0x080c, 0xaf4e, 0x04a0, 0x7244, 0x9286, + 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc21, 0x01b0, 0x2260, 0x7240, + 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, + 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe75f, 0x1180, + 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, + 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, + 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, + 0x080c, 0xaf4e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, + 0x0001, 0x080c, 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e, + 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xd64d, + 0x080c, 0xbbaa, 0x080c, 0x769d, 0x1190, 0x0006, 0x0026, 0x0036, + 0x080c, 0x76b7, 0x1138, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, + 0x75cc, 0x0010, 0x080c, 0x7671, 0x003e, 0x002e, 0x000e, 0x0005, + 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, + 0x6106, 0x080c, 0xda70, 0x1120, 0x6007, 0x002b, 0x0804, 0xd64d, + 0x6007, 0x002c, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883, + 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, + 0x6106, 0x080c, 0xda75, 0x1120, 0x6007, 0x002e, 0x0804, 0xd64d, + 0x6007, 0x002f, 0x0804, 0xd64d, 0x080c, 0x3432, 0x1904, 0xd883, + 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, + 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, + 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd654, 0x080c, 0x5824, + 0xd0e4, 0x0904, 0xd7ce, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, + 0x603e, 0x7108, 0x720c, 0x080c, 0x6bc9, 0x0140, 0x6010, 0x2058, + 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6bc5, + 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, + 0x1578, 0x7210, 0x080c, 0xcc21, 0x0590, 0x080c, 0xd941, 0x0578, + 0x080c, 0xe811, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, + 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc21, 0x01c0, 0x9280, + 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, + 0x9085, 0x0001, 0x080c, 0xe75f, 0x2c10, 0x2160, 0x0140, 0x0890, + 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, + 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, + 0x0868, 0x080c, 0x3432, 0x1904, 0xd883, 0x6010, 0x2058, 0xb804, + 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd654, 0x00e6, + 0x00d6, 0x00c6, 0x080c, 0x5824, 0xd0e4, 0x0904, 0xd846, 0x2069, + 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, + 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, + 0xe75f, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc21, 0x05d0, 0x7108, + 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, + 0x080c, 0xc80e, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, + 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, + 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xd941, + 0x0904, 0xd7c7, 0x0056, 0x7510, 0x7614, 0x080c, 0xe82a, 0x005e, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, + 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, + 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, + 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x0c10, 0x6007, 0x003b, + 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd79e, 0x00e6, 0x0026, + 0x080c, 0x6b8b, 0x0550, 0x080c, 0x6b27, 0x080c, 0xea00, 0x1518, + 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, + 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, + 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, + 0x6bc9, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac, 0x1128, + 0x080c, 0x30c8, 0x0010, 0x080c, 0xea34, 0x002e, 0x00ee, 0x080c, + 0xaf4e, 0x0804, 0xd653, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002, + 0xd89a, 0xd8c8, 0xd8d9, 0xd89a, 0xd89a, 0xd89c, 0xd8ea, 0xd89a, + 0xd89a, 0xd89a, 0xd8b6, 0xd89a, 0xd89a, 0xd89a, 0xd8f5, 0xd90b, + 0xd93c, 0xd89a, 0x080c, 0x0d79, 0x080c, 0xe98f, 0x1d20, 0x080c, + 0x3432, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, + 0x080c, 0x9427, 0x0005, 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005, 0x080c, 0xe98f, + 0x1950, 0x080c, 0x3432, 0x1938, 0x080c, 0xda54, 0x1d60, 0x703c, + 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005, + 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0041, 0x080c, 0xea3d, + 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, + 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0042, 0x080c, + 0xea3d, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0046, + 0x080c, 0xea3d, 0x080c, 0xaf4e, 0x0005, 0x2001, 0x1824, 0x2004, + 0x9082, 0x00e1, 0x1268, 0x080c, 0xd95e, 0x0904, 0xd883, 0x6007, + 0x004e, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005, + 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, + 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, + 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0, + 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, + 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, + 0xbf54, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, + 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, + 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c, 0x9106, + 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, + 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, + 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c, + 0x1066, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, + 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1066, 0x01b0, + 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, + 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x0fff, 0x9006, 0x012e, + 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, + 0x2216, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, + 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, + 0x080c, 0x2216, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x2216, 0x2061, + 0x19a2, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, + 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, + 0x2216, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280, + 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, - 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, - 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, - 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, - 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, - 0x0005, 0x00d6, 0x080c, 0xdacb, 0x00de, 0x0005, 0x00d6, 0x080c, - 0xdad8, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, - 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, - 0xeaf2, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, - 0x00ff, 0x6824, 0x080c, 0x26a2, 0x1148, 0x2001, 0x0001, 0x080c, - 0xeaf2, 0x2110, 0x900e, 0x080c, 0x335f, 0x0018, 0x9085, 0x0001, - 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xaf9f, - 0x0598, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, - 0x220c, 0x080c, 0x26a2, 0x1568, 0x080c, 0x671e, 0x1550, 0xbe12, - 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe924, - 0x11c8, 0x080c, 0x3447, 0x11b0, 0x080c, 0xda35, 0x0500, 0x2001, - 0x0007, 0x080c, 0x66cf, 0x2001, 0x0007, 0x080c, 0x66fb, 0x6017, - 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, - 0x942f, 0x0010, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x00ce, 0x00be, - 0x0005, 0x080c, 0xaf2e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, - 0xaf2e, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, - 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, - 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, - 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, - 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e, - 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, - 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, - 0x1a04, 0xdc38, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015, - 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d, 0x0120, 0x9086, - 0x0002, 0x0904, 0xb966, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d85, - 0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c, 0xaf69, - 0x080c, 0x98bf, 0x0005, 0xdb63, 0xdb65, 0xdb63, 0xdb63, 0xdb63, - 0xdb65, 0xdb72, 0xdc35, 0xdbc2, 0xdc35, 0xdbe6, 0xdc35, 0xdb72, - 0xdc35, 0xdc2d, 0xdc35, 0xdc2d, 0xdc35, 0xdc35, 0xdb63, 0xdb63, - 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, - 0xdb63, 0xdb65, 0xdb63, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdb63, - 0xdc32, 0xdc35, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdc35, 0xdc35, - 0xdb63, 0xdc35, 0xdc35, 0xdb63, 0xdb6d, 0xdb63, 0xdb63, 0xdb63, - 0xdb63, 0xdc31, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdc35, 0xdb63, - 0xdb63, 0xdb63, 0xdb63, 0x080c, 0x0d85, 0x080c, 0xd356, 0x6003, - 0x0002, 0x080c, 0x98bf, 0x0804, 0xdc37, 0x9006, 0x080c, 0x66bb, - 0x0804, 0xdc35, 0x080c, 0x6bcd, 0x1904, 0xdc35, 0x9006, 0x080c, - 0x66bb, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, - 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, - 0x2058, 0xb884, 0x9005, 0x1178, 0x080c, 0xd33e, 0x1904, 0xdc35, - 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4de5, 0x004e, - 0x003e, 0x0804, 0xdc35, 0x080c, 0x3478, 0x1904, 0xdc35, 0x2001, - 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, - 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x66cf, - 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8842, - 0x0804, 0xdc37, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, - 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, 0x90c6, - 0x2001, 0x0004, 0x080c, 0x66fb, 0x080c, 0xeb41, 0x0904, 0xdc35, - 0x2001, 0x0004, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001, - 0x6007, 0x0003, 0x080c, 0x942f, 0x0804, 0xdc37, 0x2001, 0x1800, - 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, - 0xbba0, 0x2021, 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x2001, - 0x0006, 0x080c, 0xdc51, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, - 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, - 0x080c, 0x66fb, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, - 0x0006, 0x080c, 0x66cf, 0x080c, 0x6bcd, 0x11f8, 0x2001, 0x1837, - 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, - 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, - 0x0804, 0xdbac, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409, - 0x0020, 0x0018, 0x0010, 0x080c, 0x66fb, 0x080c, 0xaf2e, 0x0005, - 0x2600, 0x0002, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4e, - 0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4c, - 0xdc4e, 0xdc4e, 0xdc4e, 0xdc4e, 0x080c, 0x0d85, 0x080c, 0xaf2e, - 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, - 0x0138, 0x080c, 0x66cf, 0x9006, 0x080c, 0x66bb, 0x080c, 0x333f, - 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, - 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x91b6, 0x0015, - 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x006b, - 0x0005, 0xba08, 0xba08, 0xba08, 0xba08, 0xdce6, 0xba08, 0xdcd0, - 0xdc91, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, - 0xba08, 0xdce6, 0xba08, 0xdcd0, 0xdcd7, 0xba08, 0xba08, 0xba08, - 0xba08, 0x00f6, 0x080c, 0x6bcd, 0x11d8, 0x080c, 0xd33e, 0x11c0, - 0x6010, 0x905d, 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c, - 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, - 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00f0, - 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11b0, - 0x080c, 0x6789, 0x0118, 0x080c, 0xaf2e, 0x0080, 0xb810, 0x0006, - 0xb814, 0x0006, 0xb884, 0x0006, 0x080c, 0x6198, 0x000e, 0xb886, - 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xaf2e, 0x00fe, 0x0005, - 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x080c, - 0xbda3, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f, - 0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e, 0x0005, 0x0804, 0xaf2e, - 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x080c, 0x97fe, 0x080c, - 0xaf69, 0x0005, 0x9182, 0x0040, 0x0002, 0xdd09, 0xdd09, 0xdd09, - 0xdd09, 0xdd0b, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, - 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, - 0xdd09, 0x080c, 0x0d85, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, - 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007, - 0x0044, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdd72, - 0x080c, 0xeae6, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, - 0x2011, 0x0200, 0x080c, 0x8ae5, 0x0020, 0x9026, 0x080c, 0xe969, - 0x0c30, 0x080c, 0x1059, 0x090c, 0x0d85, 0x6003, 0x0007, 0xa867, - 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, - 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, - 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6f19, - 0x001e, 0x080c, 0xeae6, 0x1904, 0xddd2, 0x9486, 0x2000, 0x1130, - 0x2019, 0x0017, 0x080c, 0xe696, 0x0804, 0xddd2, 0x9486, 0x0200, - 0x1120, 0x080c, 0xe621, 0x0804, 0xddd2, 0x9486, 0x0400, 0x0120, - 0x9486, 0x1000, 0x1904, 0xddd2, 0x2019, 0x0002, 0x080c, 0xe640, - 0x0804, 0xddd2, 0x2069, 0x1a74, 0x6a00, 0xd284, 0x0904, 0xde3c, - 0x9284, 0x0300, 0x1904, 0xde35, 0x6804, 0x9005, 0x0904, 0xde1d, - 0x2d78, 0x6003, 0x0007, 0x080c, 0x1072, 0x0904, 0xddde, 0x7800, - 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, - 0x180f, 0x2004, 0xd084, 0x1904, 0xde40, 0x9006, 0xa802, 0xa867, - 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, - 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, - 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, - 0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, - 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, - 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, - 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, - 0x080c, 0x6f1c, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, - 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, - 0x2004, 0xd084, 0x0120, 0x080c, 0x1059, 0x1904, 0xdd87, 0x6017, - 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, - 0x9428, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, - 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, - 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, - 0x2009, 0xa025, 0x080c, 0x9428, 0x0828, 0x6868, 0x602e, 0x686c, - 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, - 0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x2001, 0x180e, 0x2004, - 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x6017, 0xf300, - 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, - 0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x6017, 0xf500, 0x0c98, - 0x6017, 0xf600, 0x0804, 0xddf2, 0x6017, 0xf200, 0x0804, 0xddf2, - 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, - 0x7044, 0x9084, 0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x2928, - 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, - 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, - 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, - 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d85, - 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0029, 0x20a0, 0x2011, 0xdebc, 0x2041, 0x0001, 0x223d, - 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, - 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, - 0x2098, 0x0c68, 0x2950, 0x080c, 0x1072, 0x0170, 0x2900, 0xb002, - 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, - 0x080c, 0x108b, 0x0cc8, 0x080c, 0x108b, 0x0804, 0xddde, 0x2548, - 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, - 0x080c, 0xe6cd, 0x0804, 0xddd2, 0x8010, 0x0004, 0x801a, 0x0006, - 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, - 0x6004, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x9082, 0x0040, 0x0a0c, - 0x0d85, 0x2008, 0x0804, 0xdf48, 0x9186, 0x0051, 0x0108, 0x0040, - 0x080c, 0xad2d, 0x01e8, 0x9086, 0x0002, 0x0904, 0xdf90, 0x00c0, - 0x9186, 0x0027, 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, - 0x0150, 0x190c, 0x0d85, 0x080c, 0xad2d, 0x0150, 0x9086, 0x0004, - 0x0904, 0xe02f, 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, - 0x080c, 0xafe9, 0x0005, 0xdf0f, 0xdf11, 0xdf11, 0xdf38, 0xdf0f, - 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, - 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0x080c, - 0x0d85, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x0036, 0x0096, 0x6014, - 0x904d, 0x01d8, 0x080c, 0xcc16, 0x01c0, 0x6003, 0x0002, 0x6010, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, - 0x080c, 0xe6cd, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, - 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, - 0x0096, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x080c, 0xcc16, 0x0120, - 0x6014, 0x2048, 0x080c, 0x108b, 0x080c, 0xaf69, 0x009e, 0x0005, - 0x0002, 0xdf5d, 0xdf72, 0xdf5f, 0xdf87, 0xdf5d, 0xdf5d, 0xdf5d, - 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, - 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0x080c, 0x0d85, 0x0096, - 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, - 0x0043, 0x080c, 0xafcc, 0x0010, 0x6003, 0x0004, 0x080c, 0x98bf, - 0x009e, 0x0005, 0x080c, 0xcc16, 0x0138, 0x6114, 0x0096, 0x2148, - 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8aba, 0x080c, 0xaf2e, - 0x080c, 0x98bf, 0x0005, 0x080c, 0xe92d, 0x0db0, 0x0cc8, 0x6003, - 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428, 0x0005, - 0x9182, 0x0040, 0x0002, 0xdfa7, 0xdfa9, 0xdfa7, 0xdfa7, 0xdfa7, - 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, - 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfaa, 0xdfa7, 0xdfa7, 0x080c, - 0x0d85, 0x0005, 0x00d6, 0x080c, 0x8aba, 0x00de, 0x080c, 0xe985, - 0x080c, 0xaf2e, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfca, 0xdfca, - 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfcc, - 0xdff7, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdff7, 0xdfca, 0xdfca, - 0xdfca, 0xdfca, 0x080c, 0x0d85, 0x6014, 0x0096, 0x2048, 0xa87c, - 0xd0fc, 0x0168, 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144, - 0xd1e4, 0x1168, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003, - 0x0007, 0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6014, - 0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8aba, 0x080c, 0xaf2e, - 0x009e, 0x0005, 0x080c, 0xe92d, 0x0db8, 0x009e, 0x0005, 0x2001, - 0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9859, 0x080c, - 0x98bf, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, - 0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, - 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe6cd, - 0x6018, 0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, - 0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, - 0x0040, 0x0002, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, - 0xe046, 0xe046, 0xe048, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, - 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe093, 0x080c, 0x0d85, - 0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, - 0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, - 0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003, 0x0007, - 0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6124, 0xd1f4, - 0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, - 0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, - 0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, - 0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, - 0x6003, 0x0006, 0x00e9, 0x080c, 0x8abc, 0x009e, 0x0005, 0x6003, - 0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x16b0, - 0x1904, 0xe048, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, - 0x009e, 0x9105, 0x1120, 0x080c, 0x16b0, 0x1904, 0xe048, 0x0005, - 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, - 0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, - 0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, - 0x190c, 0x0d85, 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, 0xe0db, - 0xe0e7, 0xe0f3, 0xe0ff, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0e2, - 0xe0dd, 0xe0dd, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0dd, 0xe0db, - 0xe0dd, 0xe0db, 0xe0e2, 0x080c, 0x0d85, 0x6024, 0xd0dc, 0x090c, - 0x0d85, 0x0005, 0x6014, 0x9005, 0x190c, 0x0d85, 0x0005, 0x6003, - 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, - 0x940a, 0x012e, 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091, - 0x8000, 0x2009, 0xa001, 0x080c, 0x9428, 0x012e, 0x0005, 0x6003, - 0x0003, 0x6106, 0x080c, 0x1c90, 0x0126, 0x2091, 0x8000, 0x6014, - 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086, - 0x0002, 0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8, - 0x9005, 0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d, - 0xa035, 0x009e, 0x080c, 0x946f, 0x012e, 0x0005, 0x6144, 0x918d, - 0xa032, 0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, - 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe14a, 0xe14c, - 0xe161, 0xe17b, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, - 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, - 0xe14a, 0xe14a, 0x080c, 0x0d85, 0x6014, 0x2048, 0xa87c, 0xd0fc, - 0x0510, 0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, - 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9428, - 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, - 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001, - 0x080c, 0x9428, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, - 0x080c, 0xe6cd, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, - 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, - 0x080c, 0x1c90, 0x6144, 0x918d, 0xa035, 0x080c, 0x946f, 0x0005, - 0x080c, 0x97fe, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, - 0xea83, 0x0036, 0x2019, 0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e, - 0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005, 0x080c, 0x9859, 0x6114, - 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xea83, 0x0036, 0x2019, - 0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e, 0x080c, 0xaf69, 0x0005, - 0x9182, 0x0085, 0x0002, 0xe1ca, 0xe1c8, 0xe1c8, 0xe1d6, 0xe1c8, - 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, - 0x080c, 0x0d85, 0x6003, 0x000b, 0x6106, 0x0126, 0x2091, 0x8000, - 0x2009, 0x8020, 0x080c, 0x9428, 0x012e, 0x0005, 0x0026, 0x00e6, - 0x080c, 0xe924, 0x0118, 0x080c, 0xaf2e, 0x0440, 0x2071, 0x0260, - 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, - 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, - 0xb25a, 0x7220, 0x080c, 0xe558, 0x0118, 0x6007, 0x0086, 0x0040, - 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ee, 0x002e, - 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, - 0x0d85, 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00a2, - 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xafe9, - 0x0050, 0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c, - 0xaf69, 0x080c, 0x98bf, 0x0005, 0xe239, 0xe23b, 0xe23b, 0xe239, - 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, - 0xe239, 0x080c, 0x0d85, 0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005, - 0x9182, 0x0085, 0x0a0c, 0x0d85, 0x9182, 0x0092, 0x1a0c, 0x0d85, - 0x9182, 0x0085, 0x0002, 0xe258, 0xe258, 0xe258, 0xe25a, 0xe258, - 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, - 0x080c, 0x0d85, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, - 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c, - 0x97fe, 0x080c, 0xaf69, 0x0005, 0x0036, 0x080c, 0xe985, 0x604b, - 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, - 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x080c, 0xaae0, - 0x0106, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, - 0x008e, 0x1558, 0x0076, 0x2c38, 0x080c, 0xa4f6, 0x007e, 0x1528, - 0x6000, 0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8, - 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c, 0xd356, - 0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xcc16, - 0x0110, 0x080c, 0xe6cd, 0x009e, 0x9006, 0x6046, 0x6016, 0x080c, - 0xe985, 0x6023, 0x0007, 0x080c, 0xd356, 0x010e, 0x090c, 0xaafc, - 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, - 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x26a2, 0x15e8, 0x0016, - 0x00c6, 0x080c, 0x6789, 0x15b0, 0x001e, 0x00c6, 0x2160, 0x080c, - 0xd353, 0x00ce, 0x002e, 0x0026, 0x0016, 0x080c, 0xaae0, 0x2019, - 0x0029, 0x080c, 0xa5c6, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, - 0x947e, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe440, 0x007e, - 0x080c, 0xaafc, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, - 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33db, - 0x002e, 0xbc84, 0x001e, 0x080c, 0x6198, 0xbe12, 0xbd16, 0xbc86, - 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, - 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, - 0x2104, 0x9086, 0x0074, 0x1904, 0xe363, 0x2069, 0x0260, 0x6944, - 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe360, - 0x2001, 0x197d, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, - 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, - 0x0648, 0x080c, 0xeaeb, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, - 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, - 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, - 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, - 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, - 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, - 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, - 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, - 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, - 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, - 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, - 0x6798, 0x0804, 0xe3cf, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x15c8, 0x2011, - 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, - 0xbf3e, 0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, - 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, - 0xe72a, 0xb800, 0xc0e5, 0xb802, 0x080c, 0xaae0, 0x2019, 0x0029, - 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08, - 0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x2001, 0x0007, 0x080c, - 0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf, 0x001e, 0x004e, 0x9006, - 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, - 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, - 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, - 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x26a2, 0x11d0, - 0x080c, 0x6789, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011, - 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, - 0xbf3e, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, - 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, - 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11d0, 0x080c, - 0x6789, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, - 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011, 0x027a, - 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf3e, - 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, - 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, - 0x0126, 0x2091, 0x8000, 0x080c, 0xab3e, 0x0106, 0x190c, 0xaae0, - 0x2740, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, - 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, - 0x9186, 0x1b3a, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe4e6, - 0x0018, 0x9606, 0x0904, 0xe4e6, 0x080c, 0x8d8f, 0x0904, 0xe4dd, - 0x2100, 0x9c06, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0007, 0x0904, - 0xe4dd, 0x080c, 0xe76b, 0x1904, 0xe4dd, 0x080c, 0xeb09, 0x0904, - 0xe4dd, 0x080c, 0xe75b, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0001, - 0x1148, 0x080c, 0x3478, 0x0904, 0xe528, 0x6004, 0x9086, 0x0000, - 0x1904, 0xe528, 0x9786, 0x0004, 0x0904, 0xe528, 0x2500, 0x9c06, - 0x0904, 0xe4dd, 0x2400, 0x9c06, 0x0904, 0xe4dd, 0x88ff, 0x0118, - 0x605c, 0x9906, 0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, - 0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x9786, 0x000a, - 0x0148, 0x080c, 0xce2d, 0x1130, 0x080c, 0xb91f, 0x009e, 0x080c, - 0xaf69, 0x0418, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d8, 0x9786, - 0x0003, 0x1588, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, - 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000, - 0x080c, 0xea83, 0x0016, 0x080c, 0xcf1b, 0x080c, 0x6f0d, 0x001e, - 0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001, - 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe459, 0x010e, 0x190c, - 0xaafc, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, - 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, - 0x0128, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x08e0, 0x009e, 0x08e8, - 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, - 0x9086, 0x0003, 0x11a0, 0x080c, 0x9859, 0x0096, 0x6114, 0x2148, - 0x080c, 0xcc16, 0x0118, 0x6010, 0x080c, 0x6f19, 0x009e, 0x00c6, - 0x080c, 0xaf2e, 0x00ce, 0x0036, 0x080c, 0x98bf, 0x003e, 0x009e, - 0x0804, 0xe4dd, 0x9786, 0x000a, 0x0904, 0xe4cd, 0x0804, 0xe4c2, - 0x81ff, 0x0904, 0xe4dd, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, - 0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe4dd, - 0x6000, 0x9086, 0x0002, 0x1904, 0xe4dd, 0x080c, 0xce1c, 0x0138, - 0x080c, 0xce2d, 0x1904, 0xe4dd, 0x080c, 0xb91f, 0x0038, 0x080c, - 0x333f, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x080c, 0xaf69, - 0x0804, 0xe4dd, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, - 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe6f4, - 0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, - 0x0005, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe579, - 0xe577, 0xe577, 0xe577, 0xe577, 0xaf69, 0xaf69, 0xe577, 0x9006, - 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, - 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xe72a, 0x001e, 0x004e, - 0x2019, 0x0002, 0x080c, 0xe27a, 0x003e, 0x9085, 0x0001, 0x0005, - 0x0096, 0x080c, 0xcc16, 0x0140, 0x6014, 0x904d, 0x080c, 0xc802, - 0x687b, 0x0005, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x9085, - 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016, - 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, - 0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, - 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, - 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff, - 0x0904, 0xe614, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, - 0x1a04, 0xe614, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, - 0x080c, 0xe75b, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, - 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, - 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x605c, 0x9106, - 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c, - 0xd356, 0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, - 0xcc16, 0x0120, 0x0046, 0x080c, 0xe6cd, 0x004e, 0x009e, 0x080c, - 0xaf69, 0x88ff, 0x1198, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, - 0x9c02, 0x1210, 0x0804, 0xe5c7, 0x9006, 0x012e, 0x00be, 0x006e, - 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, - 0x0ca0, 0x080c, 0xaae0, 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, - 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, 0x0096, - 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6, - 0x080c, 0xe5b8, 0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005, - 0x080c, 0xaae0, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, - 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, - 0x6789, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, - 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c, - 0xa4f6, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe64d, 0x0036, - 0x2508, 0x2029, 0x0003, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce, - 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c, - 0xaae0, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, - 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0xa44b, - 0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6, 0x2c20, 0x080c, 0xe5b8, - 0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c, 0xaae0, - 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, - 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6789, 0x1190, 0x0086, - 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xe969, 0x004e, - 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c, - 0xa4f6, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe6a2, 0x0036, 0x2029, - 0x0002, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, - 0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x0016, 0x00f6, 0x080c, - 0xcc14, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, - 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6f19, - 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f19, 0x00fe, 0x001e, 0x0005, - 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6f19, 0x2f48, - 0x0cb8, 0x080c, 0x6f19, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, - 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, - 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, - 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, - 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x001c, - 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, - 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, - 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c, - 0x0d85, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, - 0xcc04, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0017, 0x2004, - 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, - 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006, - 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, - 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, - 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, - 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, - 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, - 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, - 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, - 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009, 0x8020, - 0x080c, 0x9428, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, - 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xcf62, 0x0030, 0x080c, - 0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0005, 0x9280, 0x0008, - 0x2004, 0x9084, 0x000f, 0x0002, 0xe7ba, 0xe7ba, 0xe7ba, 0xe7bc, - 0xe7ba, 0xe7bc, 0xe7bc, 0xe7ba, 0xe7bc, 0xe7ba, 0xe7ba, 0xe7ba, - 0xe7ba, 0xe7ba, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, - 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe7d3, 0xe7d3, 0xe7d3, - 0xe7d3, 0xe7d3, 0xe7d3, 0xe7e0, 0xe7d3, 0xe7d3, 0xe7d3, 0xe7d3, - 0xe7d3, 0xe7d3, 0xe7d3, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, - 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005, - 0x0096, 0x00c6, 0x2260, 0x080c, 0xe985, 0x604b, 0x0000, 0x6024, - 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, - 0x9186, 0x0007, 0x1904, 0xe839, 0x6814, 0x9005, 0x0138, 0x2048, - 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60, - 0x6100, 0x9186, 0x0002, 0x1904, 0xe8b0, 0x6014, 0x9005, 0x1138, - 0x6000, 0x9086, 0x0007, 0x190c, 0x0d85, 0x0804, 0xe8b0, 0x2048, - 0x080c, 0xcc16, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, - 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, - 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, - 0x0043, 0x080c, 0xe0b7, 0x0804, 0xe8b0, 0x2009, 0x0041, 0x0804, - 0xe8aa, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, - 0x1120, 0x00de, 0x009e, 0x0804, 0xe7d3, 0xd0b4, 0x0128, 0xd0fc, - 0x090c, 0x0d85, 0x0804, 0xe7f4, 0x6007, 0x003a, 0x6003, 0x0001, - 0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60, 0x6100, 0x9186, - 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xe8b0, 0x6814, 0x2048, - 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, - 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0042, 0x04d0, - 0x0036, 0x080c, 0x1059, 0x090c, 0x0d85, 0xa867, 0x010d, 0x9006, - 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, - 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, - 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, 0x635c, 0xab7a, 0xa876, - 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, - 0x6f19, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe27a, 0x2d00, - 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x634a, - 0x003e, 0x0038, 0x604b, 0x0000, 0x6003, 0x0007, 0x080c, 0xe0b7, - 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, - 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, - 0x97fe, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, - 0xe6cd, 0x009e, 0x003e, 0x080c, 0x98bf, 0x0005, 0x9186, 0x0014, - 0x0d70, 0x080c, 0xafe9, 0x0005, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1, - 0xe8e1, 0xe8e1, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1, - 0xe8e1, 0x080c, 0x0d85, 0x6003, 0x000c, 0x080c, 0x98bf, 0x0005, - 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, - 0xafe9, 0x0005, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe901, 0xe921, - 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0x080c, - 0x0d85, 0x00d6, 0x2c68, 0x080c, 0xaed8, 0x01b0, 0x6003, 0x0001, - 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, - 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, - 0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x080c, 0xaf2e, 0x00de, - 0x0005, 0x080c, 0xaf2e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c, - 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, - 0x0150, 0x2001, 0x1989, 0x2004, 0x604a, 0x2009, 0x1867, 0x210c, - 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128, - 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c, - 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x604a, 0x6010, - 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, - 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, - 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, 0xb8bc, 0x2060, 0x8cff, - 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, 0x1138, 0x600c, 0x2072, - 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0010, 0x9cf0, 0x0003, 0x2e64, - 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, - 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, - 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, - 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, - 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, - 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, - 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1168, - 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, - 0x0006, 0x080c, 0xbf3e, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x080c, 0x30e1, - 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x1059, 0x090c, 0x0d85, - 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8, - 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038, - 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038, - 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a, - 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294, - 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060, - 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e, - 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90, - 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210, - 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210, - 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90, - 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, - 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, - 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e, - 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011, - 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be, - 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011, - 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9, - 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, - 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e, - 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c, - 0x6f19, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, - 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, - 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5, + 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x222e, 0x20a1, 0x024c, + 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, + 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x222e, + 0x20a1, 0x0240, 0x0c98, 0x080c, 0x222e, 0x2061, 0x19a5, 0x6004, + 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, + 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x222e, + 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400, + 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, + 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, + 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, + 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, + 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, + 0x00d6, 0x080c, 0xdaea, 0x00de, 0x0005, 0x00d6, 0x080c, 0xdaf7, + 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, + 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xeb5d, + 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, + 0x6824, 0x080c, 0x26a1, 0x1148, 0x2001, 0x0001, 0x080c, 0xeb5d, + 0x2110, 0x900e, 0x080c, 0x334a, 0x0018, 0x9085, 0x0001, 0x0008, + 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xafbf, 0x0598, + 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x26a1, 0x1568, 0x080c, 0x6718, 0x1550, 0xbe12, 0xbd16, + 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe98f, 0x11c8, + 0x080c, 0x3432, 0x11b0, 0x080c, 0xda54, 0x0500, 0x2001, 0x0007, + 0x080c, 0x66c9, 0x2001, 0x0007, 0x080c, 0x66f5, 0x6017, 0x0000, + 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, + 0x0010, 0x080c, 0xaf4e, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, + 0x080c, 0xaf4e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xaf4e, + 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, + 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, + 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, + 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, + 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e, 0x0014, + 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0d79, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, + 0xdc4c, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002, + 0x0904, 0xb983, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d79, 0x2001, + 0x0007, 0x080c, 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c, + 0x98bc, 0x0005, 0xdb82, 0xdb84, 0xdb82, 0xdb82, 0xdb82, 0xdb84, + 0xdb91, 0xdc49, 0xdbd3, 0xdc49, 0xdbf7, 0xdc49, 0xdb91, 0xdc49, + 0xdc41, 0xdc49, 0xdc41, 0xdc49, 0xdc49, 0xdb82, 0xdb82, 0xdb82, + 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, + 0xdb84, 0xdb82, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdb82, 0xdc46, + 0xdc49, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82, + 0xdc49, 0xdc49, 0xdb82, 0xdb8c, 0xdb82, 0xdb82, 0xdb82, 0xdb82, + 0xdc45, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82, 0xdb82, + 0xdb82, 0xdb82, 0x080c, 0x0d79, 0x080c, 0xd375, 0x6003, 0x0002, + 0x080c, 0x98bc, 0x0804, 0xdc4b, 0x9006, 0x080c, 0x66b5, 0x0804, + 0xdc49, 0x080c, 0x6bc5, 0x1904, 0xdc49, 0x9006, 0x080c, 0x66b5, + 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, + 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, 0x6010, 0x2058, + 0xb884, 0x9005, 0x0904, 0xdc49, 0x080c, 0x3463, 0x1904, 0xdc49, + 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, + 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, + 0x883a, 0x0804, 0xdc4b, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, + 0x90be, 0x2001, 0x0004, 0x080c, 0x66f5, 0x080c, 0xebac, 0x0904, + 0xdc49, 0x2001, 0x0004, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0003, 0x080c, 0x9427, 0x0804, 0xdc4b, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, + 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, + 0x2001, 0x0006, 0x080c, 0xdc65, 0x6610, 0x2658, 0xbe04, 0x0066, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, + 0x0006, 0x080c, 0x66f5, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, + 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, + 0x6bc5, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, + 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xdbbd, 0x2001, 0x0004, + 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, 0x0010, 0x080c, + 0x66f5, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002, 0xdc60, 0xdc60, + 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc60, 0xdc62, 0xdc60, 0xdc60, + 0xdc62, 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc62, 0xdc62, 0xdc62, + 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x0016, 0x00b6, 0x00d6, + 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x66c9, 0x9006, + 0x080c, 0x66b5, 0x080c, 0x332a, 0x00de, 0x00be, 0x001e, 0x0005, + 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, + 0x1a0c, 0x0d79, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, + 0x0016, 0x190c, 0x0d79, 0x006b, 0x0005, 0xba25, 0xba25, 0xba25, + 0xba25, 0xdcfa, 0xba25, 0xdce4, 0xdca5, 0xba25, 0xba25, 0xba25, + 0xba25, 0xba25, 0xba25, 0xba25, 0xba25, 0xdcfa, 0xba25, 0xdce4, + 0xdceb, 0xba25, 0xba25, 0xba25, 0xba25, 0x00f6, 0x080c, 0x6bc5, + 0x11d8, 0x080c, 0xd35d, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb884, + 0x9005, 0x0190, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x26a1, 0x11b0, 0x080c, 0x6783, 0x0118, 0x080c, + 0xaf4e, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb884, 0x0006, + 0x080c, 0x6192, 0x000e, 0xb886, 0x000e, 0xb816, 0x000e, 0xb812, + 0x080c, 0xaf4e, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, + 0x080c, 0xaf4e, 0x0005, 0x080c, 0xbdb4, 0x1148, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0010, 0x080c, + 0xaf4e, 0x0005, 0x0804, 0xaf4e, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0d79, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0040, + 0x0002, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1f, 0xdd1d, 0xdd1d, + 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, + 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0x080c, 0x0d79, 0x0096, + 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, + 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, 0x0260, 0x7444, + 0x94a4, 0xff00, 0x0904, 0xdd86, 0x080c, 0xeb51, 0x1170, 0x9486, + 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8add, + 0x0020, 0x9026, 0x080c, 0xe9d4, 0x0c30, 0x080c, 0x104d, 0x090c, + 0x0d79, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, + 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, + 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, + 0xa887, 0x0036, 0x080c, 0x6f11, 0x001e, 0x080c, 0xeb51, 0x1904, + 0xdde6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xe701, + 0x0804, 0xdde6, 0x9486, 0x0200, 0x1120, 0x080c, 0xe68c, 0x0804, + 0xdde6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xdde6, + 0x2019, 0x0002, 0x080c, 0xe6ab, 0x0804, 0xdde6, 0x2069, 0x1a74, + 0x6a00, 0xd284, 0x0904, 0xde50, 0x9284, 0x0300, 0x1904, 0xde49, + 0x6804, 0x9005, 0x0904, 0xde31, 0x2d78, 0x6003, 0x0007, 0x080c, + 0x1066, 0x0904, 0xddf2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, + 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, + 0xde54, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, + 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, + 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, + 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xddee, 0x2005, + 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, + 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, + 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, + 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6f14, 0x002e, 0x004e, + 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, + 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, + 0x104d, 0x1904, 0xdd9b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0c00, 0x2069, 0x0260, + 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, + 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x2009, 0xa025, 0x080c, 0x9420, + 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804, + 0xdde6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4c28, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804, + 0xdde6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xde06, + 0x6017, 0xf200, 0x0804, 0xde06, 0xa867, 0x0146, 0xa86b, 0x0000, + 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, + 0xddee, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, + 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, + 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, + 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, + 0x9282, 0x0111, 0x1a0c, 0x0d79, 0x8210, 0x821c, 0x2001, 0x026c, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, + 0xded0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, + 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, + 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, + 0x1066, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, + 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x107f, 0x0cc8, 0x080c, + 0x107f, 0x0804, 0xddf2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, + 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe738, 0x0804, 0xdde6, + 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, + 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0057, 0x1a0c, + 0x0d79, 0x9082, 0x0040, 0x0a0c, 0x0d79, 0x2008, 0x0804, 0xdf5c, + 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xad4d, 0x01e8, 0x9086, + 0x0002, 0x0904, 0xdfa4, 0x00c0, 0x9186, 0x0027, 0x0180, 0x9186, + 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, 0x0d79, 0x080c, + 0xad4d, 0x0150, 0x9086, 0x0004, 0x0904, 0xe043, 0x0028, 0x6004, + 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xb009, 0x0005, 0xdf23, + 0xdf25, 0xdf25, 0xdf4c, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, + 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, + 0xdf23, 0xdf23, 0xdf23, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x080c, + 0x98bc, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xcc33, + 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xe738, 0x6017, 0x0000, + 0x6018, 0x9005, 0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x97f6, 0x080c, + 0x98bc, 0x080c, 0xcc33, 0x0120, 0x6014, 0x2048, 0x080c, 0x107f, + 0x080c, 0xaf89, 0x009e, 0x0005, 0x0002, 0xdf71, 0xdf86, 0xdf73, + 0xdf9b, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, + 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, + 0xdf71, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0b4, + 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xafec, 0x0010, + 0x6003, 0x0004, 0x080c, 0x98bc, 0x009e, 0x0005, 0x080c, 0xcc33, + 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, + 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c, + 0xe998, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, + 0xa022, 0x080c, 0x9420, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfbb, + 0xdfbd, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, + 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, + 0xdfbe, 0xdfbb, 0xdfbb, 0x080c, 0x0d79, 0x0005, 0x00d6, 0x080c, + 0x8ab2, 0x00de, 0x080c, 0xe9f0, 0x080c, 0xaf4e, 0x0005, 0x9182, + 0x0040, 0x0002, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde, + 0xdfde, 0xdfde, 0xdfde, 0xdfe0, 0xe00b, 0xdfde, 0xdfde, 0xdfde, + 0xdfde, 0xe00b, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0x080c, 0x0d79, + 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x908c, 0x0003, + 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, 0x2009, 0x0041, + 0x009e, 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, + 0x8ab2, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, + 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xe998, + 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, + 0x0036, 0x080c, 0x9851, 0x080c, 0x98bc, 0x6014, 0x0096, 0x2048, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, + 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, + 0x2019, 0x0004, 0x080c, 0xe738, 0x6018, 0x9005, 0x1128, 0x2001, + 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, + 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe05a, 0xe05a, + 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05c, 0xe05a, + 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, + 0xe05a, 0xe0a7, 0x080c, 0x0d79, 0x6014, 0x0096, 0x2048, 0xa834, + 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, + 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, + 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8ab2, + 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, + 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, + 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, + 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, + 0x8ab4, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, + 0xd0f4, 0x0128, 0x080c, 0x16a4, 0x1904, 0xe05c, 0x0005, 0x6014, + 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, + 0x16a4, 0x1904, 0xe05c, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, + 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, + 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, + 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x6024, 0xd0dc, + 0x090c, 0x0d79, 0x0005, 0xe0ef, 0xe0fb, 0xe107, 0xe113, 0xe0ef, + 0xe0ef, 0xe0ef, 0xe0ef, 0xe0f6, 0xe0f1, 0xe0f1, 0xe0ef, 0xe0ef, + 0xe0ef, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f6, 0x080c, + 0x0d79, 0x6024, 0xd0dc, 0x090c, 0x0d79, 0x0005, 0x6014, 0x9005, + 0x190c, 0x0d79, 0x0005, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, + 0x8000, 0x2009, 0xa022, 0x080c, 0x9402, 0x012e, 0x0005, 0x6003, + 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa001, 0x080c, + 0x9420, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c, + 0x0126, 0x2091, 0x8000, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, + 0x0188, 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x6024, 0xd0cc, + 0x1148, 0xd0c4, 0x1138, 0xa8a8, 0x9005, 0x1120, 0x6144, 0x918d, + 0xb035, 0x0018, 0x6144, 0x918d, 0xa035, 0x009e, 0x080c, 0x9467, + 0x012e, 0x0005, 0x6144, 0x918d, 0xa032, 0x0cb8, 0x0126, 0x2091, + 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, + 0x012e, 0x0005, 0xe15e, 0xe160, 0xe175, 0xe18f, 0xe15e, 0xe15e, + 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, + 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0x080c, 0x0d79, + 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510, 0x909c, 0x0003, 0x939e, + 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, + 0x2009, 0xa022, 0x080c, 0x9420, 0x0470, 0x6014, 0x2048, 0xa87c, + 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003, + 0x0001, 0x6106, 0x2009, 0xa001, 0x080c, 0x9420, 0x00e0, 0x901e, + 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe738, 0x00a0, 0x6014, + 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003, + 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c, 0x6144, 0x918d, + 0xa035, 0x080c, 0x9467, 0x0005, 0x080c, 0x97f6, 0x6114, 0x81ff, + 0x0158, 0x0096, 0x2148, 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029, + 0x080c, 0xe738, 0x003e, 0x009e, 0x080c, 0xaf89, 0x080c, 0x98bc, + 0x0005, 0x080c, 0x9851, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, + 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029, 0x080c, 0xe738, 0x003e, + 0x009e, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0085, 0x0002, 0xe1de, + 0xe1dc, 0xe1dc, 0xe1ea, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, + 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0x080c, 0x0d79, 0x6003, 0x000b, + 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9420, + 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xe98f, 0x0118, 0x080c, + 0xaf4e, 0x0440, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, + 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x2011, 0x014e, 0x080c, 0xb277, 0x7220, 0x080c, 0xe57d, + 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, + 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x2009, 0x8020, + 0x080c, 0x9420, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a, 0x0092, 0x1a0c, + 0x0d79, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, + 0x0014, 0x0118, 0x080c, 0xb009, 0x0050, 0x2001, 0x0007, 0x080c, + 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c, 0x98bc, 0x0005, + 0xe24d, 0xe24f, 0xe24f, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d, + 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0x080c, 0x0d79, 0x080c, + 0xaf89, 0x080c, 0x98bc, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0d79, + 0x9182, 0x0092, 0x1a0c, 0x0d79, 0x9182, 0x0085, 0x0002, 0xe26c, + 0xe26c, 0xe26c, 0xe26e, 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0xe26c, + 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0x080c, 0x0d79, 0x0005, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb009, 0x0020, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005, + 0x0036, 0x080c, 0xe9f0, 0x604b, 0x0000, 0x2019, 0x000b, 0x0031, + 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, + 0x2091, 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0086, 0x2c40, 0x0096, + 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x1558, 0x0076, 0x2c38, + 0x080c, 0xa50d, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000, 0x0508, + 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0110, 0x080c, 0xe738, 0x009e, + 0x9006, 0x6046, 0x6016, 0x080c, 0xe9f0, 0x6023, 0x0007, 0x080c, + 0xd375, 0x010e, 0x090c, 0xab13, 0x003e, 0x012e, 0x0005, 0x00f6, + 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, + 0x080c, 0x26a1, 0x1904, 0xe329, 0x0016, 0x00c6, 0x080c, 0x6783, + 0x1904, 0xe327, 0x001e, 0x00c6, 0x080c, 0xd35d, 0x1130, 0xb884, + 0x9005, 0x0118, 0x080c, 0x3463, 0x0148, 0x2b10, 0x2160, 0x6010, + 0x0006, 0x6212, 0x080c, 0xd364, 0x000e, 0x6012, 0x00ce, 0x002e, + 0x0026, 0x0016, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0xa5dd, + 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x007e, 0x001e, + 0x0076, 0x903e, 0x080c, 0xe465, 0x007e, 0x080c, 0xab13, 0x0026, + 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, + 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33c6, 0x002e, 0xbc84, 0x001e, + 0x080c, 0x6192, 0xbe12, 0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce, + 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, + 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, + 0x1904, 0xe388, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, + 0x6940, 0x9184, 0x8000, 0x0904, 0xe385, 0x2001, 0x197d, 0x2004, + 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, 0x9005, 0x0118, 0x9184, + 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xeb56, + 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, + 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, + 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, + 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, + 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, + 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, + 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, + 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, + 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, + 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, + 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6792, 0x0804, 0xe3f4, + 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xbf54, 0x009e, 0x15c8, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1568, + 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, + 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800, 0xc0e5, + 0xb802, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, + 0x2039, 0x0000, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e, + 0x080c, 0xab13, 0x2001, 0x0007, 0x080c, 0x66f5, 0x2001, 0x0007, + 0x080c, 0x66c9, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, + 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, + 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, + 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, + 0x7930, 0x7834, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8, + 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xbf54, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e, + 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, + 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8, 0x2011, + 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, + 0xbf54, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e, 0x003e, + 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, + 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, + 0x080c, 0xab55, 0x0106, 0x190c, 0xaaf7, 0x2740, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, - 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, - 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, - 0x01d0, 0x080c, 0xe75b, 0x01b8, 0x080c, 0xe76b, 0x11a0, 0x6000, - 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x080c, - 0xce1c, 0x1110, 0x080c, 0x333f, 0x080c, 0xce2d, 0x1110, 0x080c, - 0xb91f, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, - 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, - 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, - 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c, - 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd33e, 0x0168, - 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, - 0x00be, 0x2021, 0x0004, 0x080c, 0x4de5, 0x004e, 0x003e, 0x000e, - 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa5c6, 0x080c, - 0xaf69, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, - 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8, - 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, - 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, - 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40, - 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, - 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837, - 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118, - 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, - 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, - 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, - 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, - 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, - 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, - 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, - 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, - 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, - 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, - 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016, - 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008, - 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, - 0x1000, 0x2000, 0x4000, 0x8000, 0x77f3 + 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1b3a, 0x000e, + 0x0128, 0x8001, 0x9602, 0x1a04, 0xe50b, 0x0018, 0x9606, 0x0904, + 0xe50b, 0x080c, 0x8d87, 0x0904, 0xe502, 0x2100, 0x9c06, 0x0904, + 0xe502, 0x6720, 0x9786, 0x0007, 0x0904, 0xe502, 0x080c, 0xe7d6, + 0x1904, 0xe502, 0x080c, 0xeb74, 0x0904, 0xe502, 0x080c, 0xe7c6, + 0x0904, 0xe502, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3463, + 0x0904, 0xe54d, 0x6004, 0x9086, 0x0000, 0x1904, 0xe54d, 0x9786, + 0x0004, 0x0904, 0xe54d, 0x2500, 0x9c06, 0x0904, 0xe502, 0x2400, + 0x9c06, 0x0904, 0xe502, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0, + 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, + 0x080c, 0x1af0, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a, + 0x1130, 0x080c, 0xb93c, 0x009e, 0x080c, 0xaf89, 0x0418, 0x6014, + 0x2048, 0x080c, 0xcc33, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867, + 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, + 0x0fff, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xeaee, 0x0016, + 0x080c, 0xcf38, 0x080c, 0x6f05, 0x001e, 0x080c, 0xce24, 0x009e, + 0x080c, 0xaf89, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1210, 0x0804, 0xe47e, 0x010e, 0x190c, 0xab13, 0x012e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, + 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xeaee, + 0x080c, 0xe738, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009, 0x11f8, + 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, + 0x080c, 0x9851, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0118, + 0x6010, 0x080c, 0x6f11, 0x009e, 0x00c6, 0x080c, 0xaf4e, 0x00ce, + 0x0036, 0x080c, 0x98bc, 0x003e, 0x009e, 0x0804, 0xe502, 0x9786, + 0x000a, 0x0904, 0xe4f2, 0x0804, 0xe4e7, 0x81ff, 0x0904, 0xe502, + 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, + 0x2004, 0x9086, 0x002d, 0x1904, 0xe502, 0x6000, 0x9086, 0x0002, + 0x1904, 0xe502, 0x080c, 0xce39, 0x0138, 0x080c, 0xce4a, 0x1904, + 0xe502, 0x080c, 0xb93c, 0x0038, 0x080c, 0x332a, 0x080c, 0xce4a, + 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x0804, 0xe502, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, + 0x2c08, 0x2170, 0x9006, 0x080c, 0xe75f, 0x001e, 0x0120, 0x6020, + 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe59c, 0xe59c, + 0xe59c, 0xe59c, 0xe59c, 0xe59c, 0xe59e, 0xe59c, 0xe59c, 0xe59c, + 0xe5c7, 0xaf89, 0xaf89, 0xe59c, 0x9006, 0x0005, 0x0036, 0x0046, + 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, + 0x0020, 0x080c, 0xe795, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, + 0xe28e, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcc33, + 0x0140, 0x6014, 0x904d, 0x080c, 0xc81b, 0x687b, 0x0005, 0x080c, + 0x6f11, 0x009e, 0x080c, 0xaf89, 0x9085, 0x0001, 0x0005, 0x0019, + 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, + 0x000b, 0x0005, 0xe5e2, 0xe5e2, 0xe5f9, 0xe5e9, 0xe608, 0xe5e2, + 0xe5e2, 0xe5e4, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, + 0xe5e2, 0xe5e2, 0x080c, 0x0d79, 0x080c, 0xaf89, 0x9085, 0x0001, + 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1128, + 0x2019, 0x0001, 0x080c, 0xa391, 0x0010, 0x080c, 0xa59c, 0x00ee, + 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c, + 0x6f11, 0x080c, 0xaf89, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, + 0x601c, 0xd084, 0x190c, 0x1af0, 0x0c60, 0x2001, 0x0001, 0x080c, + 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e, + 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, + 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, + 0x2079, 0x0001, 0x8fff, 0x0904, 0xe67f, 0x2071, 0x1800, 0x7654, + 0x7074, 0x8001, 0x9602, 0x1a04, 0xe67f, 0x88ff, 0x0120, 0x2800, + 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe7c6, 0x0580, 0x2400, 0x9c06, + 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, + 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, + 0x0118, 0x605c, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0120, 0x0046, 0x080c, 0xe738, + 0x004e, 0x009e, 0x080c, 0xaf89, 0x88ff, 0x1198, 0x9ce0, 0x001c, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe632, 0x9006, + 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xaaf7, 0x00b6, 0x0076, + 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, + 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, + 0x903e, 0x080c, 0xa50d, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be, + 0x080c, 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056, + 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x0036, 0x080c, 0x6783, 0x1180, 0x0056, 0x0086, 0x9046, + 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa50d, 0x005e, 0x003e, 0x001e, 0x8108, + 0x1f04, 0xe6b8, 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xe623, + 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, + 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0076, 0x0056, 0x6210, + 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, + 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x903e, 0x080c, 0xa50d, + 0x2c20, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be, 0x080c, 0xab13, + 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, + 0x6783, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, + 0x080c, 0xe9d4, 0x004e, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa50d, 0x003e, 0x001e, 0x8108, 0x1f04, + 0xe70d, 0x0036, 0x2029, 0x0002, 0x080c, 0xe623, 0x003e, 0x015e, + 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xab13, 0x0005, + 0x0016, 0x00f6, 0x080c, 0xcc31, 0x0198, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, + 0xab82, 0x080c, 0x6f11, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f11, + 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, + 0x080c, 0x6f11, 0x2f48, 0x0cb8, 0x080c, 0x6f11, 0x0c88, 0x00e6, + 0x0046, 0x0036, 0x2061, 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, + 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, + 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, + 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, + 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, + 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, + 0x104d, 0x000e, 0x090c, 0x0d79, 0xaae2, 0xa867, 0x010d, 0xa88e, + 0x0026, 0x2010, 0x080c, 0xcc21, 0x2001, 0x0000, 0x0120, 0x2200, + 0x9080, 0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, + 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, + 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, + 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, + 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, + 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, + 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, + 0x601a, 0x2009, 0x8020, 0x080c, 0x9420, 0x001e, 0x0005, 0xa001, + 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, + 0xcf7f, 0x0030, 0x080c, 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e, + 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe825, + 0xe825, 0xe825, 0xe827, 0xe825, 0xe827, 0xe827, 0xe825, 0xe827, + 0xe825, 0xe825, 0xe825, 0xe825, 0xe825, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, + 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe84b, 0xe83e, + 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0x6007, 0x003b, + 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, + 0x080c, 0x9420, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xe9f0, + 0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, + 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xe8a4, 0x6814, + 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, + 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, + 0x9420, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xe91b, + 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d79, + 0x0804, 0xe91b, 0x2048, 0x080c, 0xcc33, 0x1130, 0x0028, 0x2048, + 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, + 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe0cb, 0x0804, 0xe91b, + 0x2009, 0x0041, 0x0804, 0xe915, 0x9186, 0x0005, 0x15a0, 0x6814, + 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xe83e, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d79, 0x0804, 0xe85f, 0x6007, + 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x00c6, + 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, + 0xe91b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, + 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x17a1, 0x00fe, + 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x104d, 0x090c, 0x0d79, + 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, + 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, + 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, + 0x635c, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, + 0xa89f, 0x0001, 0x080c, 0x6f11, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xe28e, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, + 0x901e, 0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000, 0x6003, + 0x0007, 0x080c, 0xe0cb, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, + 0x0027, 0x1178, 0x080c, 0x97f6, 0x0036, 0x0096, 0x6014, 0x2048, + 0x2019, 0x0004, 0x080c, 0xe738, 0x009e, 0x003e, 0x080c, 0x98bc, + 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb009, 0x0005, 0xe94e, + 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94e, 0xe94c, 0xe94c, + 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0x080c, 0x0d79, 0x6003, 0x000c, + 0x080c, 0x98bc, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, + 0x0208, 0x001a, 0x080c, 0xb009, 0x0005, 0xe96a, 0xe96a, 0xe96a, + 0xe96a, 0xe96c, 0xe98c, 0xe96a, 0xe96a, 0xe96a, 0xe96a, 0xe96a, + 0xe96a, 0xe96a, 0x080c, 0x0d79, 0x00d6, 0x2c68, 0x080c, 0xaef8, + 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, + 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, + 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, + 0x080c, 0xaf4e, 0x00de, 0x0005, 0x080c, 0xaf4e, 0x0005, 0x00e6, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, + 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, + 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989, 0x2004, 0x604a, + 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, + 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, + 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, + 0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, + 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, + 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, + 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, + 0x1138, 0x600c, 0x2072, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x0010, + 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, + 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, + 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, + 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, + 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, + 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, + 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, + 0xbf54, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, + 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1100, + 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x610b, 0x080c, 0x30c8, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, + 0x104d, 0x090c, 0x0d79, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, + 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, + 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, + 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, + 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, + 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, + 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, + 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, + 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, + 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, + 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, + 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, + 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, + 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, + 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, + 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, + 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, + 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, + 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, + 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, + 0x0000, 0x002e, 0x080c, 0x6f11, 0x009e, 0x0005, 0x00e6, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, + 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, + 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, + 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, + 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, + 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe7c6, 0x01b8, 0x080c, + 0xe7d6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, + 0x1af0, 0x001e, 0x080c, 0xce39, 0x1110, 0x080c, 0x332a, 0x080c, + 0xce4a, 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x9ce0, 0x001c, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, + 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, + 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, + 0x080c, 0xd35d, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, + 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4ddf, + 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, + 0x080c, 0xa5dd, 0x080c, 0xaf89, 0x9006, 0x0005, 0x00e6, 0x00c6, + 0x00b6, 0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, + 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, + 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, + 0x9086, 0x0002, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, + 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, + 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, + 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, + 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, + 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, + 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, + 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, + 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, + 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, + 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, + 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, + 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, + 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, + 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x7163 }; #ifdef UNIQUE_FW_NAME -unsigned short fw2322ipx_length01 = 0xe3bd; +unsigned short fw2322ipx_length01 = 0xe428; #else -unsigned short risc_code_length01 = 0xe3bd; +unsigned short risc_code_length01 = 0xe428; #endif /* @@ -7339,32 +7352,32 @@ unsigned short risc_code_length01 = 0xe3bd; unsigned long rseqipx_code_addr01 = 0x0001c000 ; unsigned short rseqipx_code01[] = { -0x000b, 0x0003, 0x0000, 0x0a20, 0x0001, 0xc000, 0x0008, 0x8064, +0x000b, 0x0003, 0x0000, 0x0a4a, 0x0001, 0xc000, 0x0008, 0x8064, 0x0000, 0x0010, 0x0000, 0x8066, 0x0008, 0x0101, 0x0003, 0xc007, 0x0008, 0x80e0, 0x0008, 0xff00, 0x0000, 0x80e2, 0x0008, 0xff00, 0x0008, 0x0162, 0x0000, 0x8066, 0x0008, 0xa101, 0x000b, 0xc00f, 0x0008, 0x0d02, 0x0000, 0x8060, 0x0000, 0x0400, 0x000b, 0x60c6, - 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7af3, - 0x000b, 0x522c, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a, + 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7b08, + 0x0003, 0x5241, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a, 0x0003, 0x8813, 0x000a, 0x7042, 0x0003, 0x8813, 0x0000, 0x15fc, 0x000b, 0xb013, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0001, 0xffa0, - 0x0000, 0x2000, 0x000b, 0x93b8, 0x0008, 0x808c, 0x0000, 0x0001, + 0x0000, 0x2000, 0x0003, 0x93cd, 0x0008, 0x808c, 0x0000, 0x0001, 0x0007, 0x0000, 0x0007, 0x0000, 0x0000, 0x40d4, 0x000a, 0x4047, 0x0008, 0x808c, 0x0000, 0x0002, 0x0007, 0x0000, 0x000b, 0x0832, 0x0000, 0x4022, 0x0003, 0x0038, 0x0008, 0x4122, 0x0009, 0xeac0, - 0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bdf, - 0x0002, 0x4447, 0x0003, 0x8bdc, 0x0008, 0x0bfe, 0x0001, 0x11a0, - 0x0003, 0x13be, 0x0001, 0x0ca0, 0x0003, 0x13be, 0x0001, 0x9180, + 0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bf4, + 0x0002, 0x4447, 0x0003, 0x8bf1, 0x0008, 0x0bfe, 0x0001, 0x11a0, + 0x000b, 0x13d3, 0x0001, 0x0ca0, 0x000b, 0x13d3, 0x0001, 0x9180, 0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc046, 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc04e, 0x0000, 0x03fe, - 0x0001, 0x43e0, 0x000b, 0x8bbb, 0x0009, 0xc2c0, 0x0008, 0x00ff, - 0x0001, 0x02e0, 0x000b, 0x8bbb, 0x0001, 0x9180, 0x0008, 0x0005, + 0x0001, 0x43e0, 0x0003, 0x8bd0, 0x0009, 0xc2c0, 0x0008, 0x00ff, + 0x0001, 0x02e0, 0x0003, 0x8bd0, 0x0001, 0x9180, 0x0008, 0x0005, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x0003, 0x0bb8, - 0x0008, 0x00fc, 0x000b, 0x33bb, 0x000a, 0x0244, 0x0003, 0x086f, - 0x000c, 0x0205, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62, + 0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x000b, 0x0bcd, + 0x0008, 0x00fc, 0x0003, 0x33d0, 0x000a, 0x0244, 0x0003, 0x086f, + 0x0004, 0x021a, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0002, 0x0234, 0x0008, 0x7f04, 0x0000, 0x8066, 0x0000, 0x040a, 0x0003, 0xc06e, 0x000a, 0x0248, 0x000b, 0x0879, 0x0001, 0x9180, 0x0008, 0x0006, 0x0008, 0x7f62, @@ -7373,7 +7386,7 @@ unsigned short rseqipx_code01[] = { 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, 0x0000, 0x0002, 0x0008, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0000, 0x8066, 0x0008, 0x0011, 0x0003, 0xc085, 0x0008, 0x01fe, 0x0009, 0x42e0, - 0x0003, 0x8bab, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x0003, 0x8bab, + 0x000b, 0x8bc0, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x000b, 0x8bc0, 0x0000, 0x1734, 0x0000, 0x1530, 0x0008, 0x1632, 0x0008, 0x0d2a, 0x0001, 0x9880, 0x0008, 0x0012, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc097, @@ -7389,291 +7402,297 @@ unsigned short rseqipx_code01[] = { 0x0000, 0x064a, 0x000a, 0x1948, 0x0003, 0x08c0, 0x0008, 0x0d4a, 0x0003, 0x58c0, 0x0008, 0x8054, 0x0000, 0x0001, 0x0000, 0x8074, 0x0008, 0x2020, 0x000f, 0x4000, 0x0002, 0x7043, 0x0003, 0x8816, - 0x0002, 0x7040, 0x000b, 0x8934, 0x0000, 0x4820, 0x0008, 0x0bfe, - 0x0009, 0x10a0, 0x000b, 0x112b, 0x0001, 0x0ca0, 0x000b, 0x112b, + 0x0002, 0x7040, 0x000b, 0x8949, 0x0000, 0x4820, 0x0008, 0x0bfe, + 0x0009, 0x10a0, 0x0003, 0x1140, 0x0001, 0x0ca0, 0x0003, 0x1140, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0008, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0d7, - 0x0001, 0x80e0, 0x0008, 0x0003, 0x0003, 0x892b, 0x0000, 0x49b4, - 0x0002, 0x4b4e, 0x0003, 0x893c, 0x0008, 0x808a, 0x0000, 0x0004, - 0x0000, 0x18fe, 0x0001, 0x10e0, 0x0003, 0x88e5, 0x0002, 0x192f, - 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, 0x0003, 0x88ea, - 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0008, 0x0009, 0x0003, 0xc0f1, 0x000a, 0x004f, 0x0003, 0x8922, - 0x000a, 0x0040, 0x000b, 0x090c, 0x0002, 0x004e, 0x000b, 0x090c, - 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00, 0x0000, 0x8066, - 0x0008, 0x000a, 0x0003, 0xc0fd, 0x0008, 0x1010, 0x0004, 0x01ec, - 0x000b, 0xb105, 0x0004, 0x0372, 0x0004, 0x01d6, 0x0003, 0x7816, - 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, - 0x0004, 0x0372, 0x0000, 0x0310, 0x0004, 0x0372, 0x0003, 0x0103, - 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066, 0x0008, 0x000a, - 0x000b, 0xc110, 0x000c, 0x01af, 0x000a, 0x0040, 0x0003, 0x0925, - 0x0004, 0x021c, 0x0000, 0x8000, 0x0000, 0x0002, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc11e, 0x0000, 0x8072, - 0x0000, 0x4000, 0x0003, 0x0103, 0x0008, 0x8010, 0x0008, 0x001e, - 0x0003, 0x0127, 0x0008, 0x8010, 0x0008, 0x001d, 0x0004, 0x0372, - 0x0008, 0x1010, 0x0004, 0x0372, 0x0003, 0x0016, 0x0002, 0x4b4e, - 0x0003, 0x0931, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x6131, - 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, - 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000, - 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6134, 0x000b, 0x0014, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc143, - 0x000a, 0x004f, 0x0003, 0x89a0, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0008, 0x0009, 0x0003, 0xc14d, 0x0008, 0x0060, 0x0008, 0x8062, - 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, 0x0003, 0xc153, - 0x000a, 0x014b, 0x000b, 0x09a0, 0x0008, 0x8062, 0x0008, 0x000f, - 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc15a, 0x0008, 0x01fe, - 0x0001, 0x02d0, 0x0003, 0x89a0, 0x000c, 0x01b8, 0x000b, 0x09a0, - 0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002, 0x0000, 0x8006, - 0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a, 0x0000, 0x0004, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0000, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc16f, - 0x0003, 0xe170, 0x0008, 0x4908, 0x0008, 0x480a, 0x0008, 0x808a, - 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b, - 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc17a, 0x0008, 0x04fe, - 0x0009, 0x02a0, 0x0003, 0x9181, 0x0002, 0x0500, 0x0003, 0x099d, - 0x0003, 0x0182, 0x0000, 0x05fe, 0x0001, 0x03a0, 0x0003, 0x119d, - 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10, 0x0000, 0x0d12, - 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066, - 0x0008, 0x0832, 0x0003, 0xc18d, 0x0000, 0x800a, 0x0000, 0x8005, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, 0x000b, 0xc197, - 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01c3, 0x0003, 0x7816, - 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, 0x0003, 0x0184, - 0x000c, 0x01af, 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x8010, - 0x0008, 0x0021, 0x0004, 0x0372, 0x0008, 0x1010, 0x0004, 0x0372, - 0x0000, 0x4810, 0x0004, 0x0372, 0x0008, 0x4910, 0x0004, 0x0372, - 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1b6, 0x000f, 0x4000, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62, 0x0000, 0x8066, - 0x0000, 0x0411, 0x0003, 0xc1bd, 0x0002, 0x0210, 0x0001, 0xffc0, - 0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002, 0x0009, 0x0a80, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, 0x000b, 0xc1cb, - 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06, - 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x060a, - 0x0003, 0xc1d4, 0x000f, 0x4000, 0x0000, 0x0da0, 0x0008, 0x0da2, - 0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001, 0x0008, 0x7f62, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0008, 0xa012, - 0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x0dac, - 0x0003, 0xc1e4, 0x0009, 0x8880, 0x0008, 0x0009, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0xa03a, 0x000b, 0xc1ea, 0x000f, 0x4000, - 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc1f3, - 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066, - 0x0008, 0x0021, 0x0003, 0xc1f9, 0x0000, 0x00fe, 0x0001, 0x01d0, - 0x000b, 0x8a02, 0x0008, 0x02fe, 0x0009, 0x03d0, 0x0003, 0x0a02, - 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006, 0x0000, 0x0001, - 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b, - 0x0000, 0x8066, 0x0008, 0xa041, 0x0003, 0xc20a, 0x0002, 0x0243, - 0x0003, 0x8a11, 0x0000, 0x54ac, 0x0000, 0x55ae, 0x0008, 0x0da8, - 0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2, 0x0000, 0x0db4, - 0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0007, - 0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc21a, 0x000f, 0x4000, - 0x000a, 0x3945, 0x000b, 0x8a26, 0x0000, 0x8072, 0x0008, 0x4040, - 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a24, 0x000f, 0x4000, - 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000, 0x0007, 0x0000, - 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a1e, 0x000b, 0x0226, - 0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0, 0x0008, 0x0000, - 0x0000, 0x7f24, 0x0003, 0x5a31, 0x0008, 0x8054, 0x0000, 0x0002, - 0x0002, 0x1242, 0x000b, 0x0a77, 0x000a, 0x3a45, 0x000b, 0x0a66, - 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a63, 0x0002, 0x1d00, - 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0008, 0x0009, 0x0003, 0xc241, 0x0008, 0x00fc, 0x000b, 0xb260, - 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066, - 0x0008, 0x0009, 0x000b, 0xc249, 0x0008, 0x00fc, 0x0003, 0x3394, - 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0019, - 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc252, 0x0009, 0x80c0, - 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60, 0x0008, 0x0efe, - 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, - 0x0003, 0xc25c, 0x0008, 0x003a, 0x0000, 0x1dfe, 0x000b, 0x023d, - 0x0008, 0x0036, 0x0004, 0x00aa, 0x0003, 0x0277, 0x0000, 0x8074, - 0x0000, 0x2000, 0x0003, 0x0277, 0x0002, 0x3a44, 0x000b, 0x0bc1, - 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0, 0x0008, 0x0000, - 0x0008, 0x7f0e, 0x000b, 0xb391, 0x0001, 0xa7d0, 0x0008, 0x0000, - 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0009, 0x00d0, - 0x0003, 0x8a87, 0x0000, 0x8074, 0x0008, 0x4040, 0x000b, 0x5a77, - 0x000b, 0x522c, 0x000a, 0x3a46, 0x0003, 0x8a87, 0x0002, 0x3a47, - 0x000b, 0x0a82, 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074, - 0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0x92c0, 0x0000, 0x0fc8, - 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8b8b, 0x0000, 0x1a60, - 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066, 0x0000, 0x367a, - 0x000b, 0xc28c, 0x0009, 0x92c0, 0x0008, 0x0780, 0x000b, 0x8ba5, - 0x0002, 0x124b, 0x000b, 0x0a95, 0x0002, 0x2e4d, 0x0002, 0x2e4d, - 0x000b, 0x0b91, 0x000a, 0x3a46, 0x0003, 0x8aa5, 0x0003, 0x5a97, - 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, 0x0003, 0x0ae5, - 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0372, 0x000a, 0x1948, - 0x0003, 0x0aa2, 0x000c, 0x0367, 0x0000, 0x1810, 0x0004, 0x0372, - 0x000b, 0x02e5, 0x000a, 0x1948, 0x000b, 0x0aa9, 0x000a, 0x1243, - 0x000b, 0x0b94, 0x000a, 0x194d, 0x0003, 0x0aad, 0x000a, 0x1243, - 0x000b, 0x0b9b, 0x0003, 0x5aad, 0x0008, 0x8054, 0x0000, 0x0004, - 0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, 0x0003, 0x0adf, - 0x0002, 0x194f, 0x000b, 0x0abd, 0x000c, 0x0367, 0x0000, 0x1810, - 0x0004, 0x01ec, 0x000b, 0xb2d8, 0x0004, 0x0372, 0x0004, 0x01d6, - 0x000b, 0x02e5, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x001f, - 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc2c2, 0x000a, 0x004c, - 0x000b, 0x8adf, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880, - 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x320a, - 0x0003, 0xc2cc, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880, - 0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, - 0x0003, 0xc2d4, 0x0000, 0x1826, 0x0000, 0x1928, 0x000b, 0x02e5, - 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, 0x0004, 0x0372, - 0x0000, 0x0310, 0x0004, 0x0372, 0x000b, 0x02e5, 0x000c, 0x0367, - 0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0372, 0x0000, 0x1810, - 0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x0d30, - 0x0002, 0x3a42, 0x0003, 0x8aed, 0x0000, 0x15fc, 0x0003, 0xb07e, - 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501, 0x0008, 0x8010, - 0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013, 0x0009, 0xbbe0, - 0x0008, 0x0030, 0x000b, 0x8b09, 0x0000, 0x18fe, 0x0009, 0x3ce0, - 0x0003, 0x0b06, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x0b06, - 0x0008, 0x13fe, 0x0009, 0x3ce0, 0x0003, 0x8b02, 0x0004, 0x0360, - 0x0008, 0x0d26, 0x000b, 0x0303, 0x000c, 0x0362, 0x0008, 0x8076, - 0x0000, 0x0040, 0x0003, 0x035d, 0x0008, 0x8076, 0x0008, 0x0041, - 0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x0032, 0x0003, 0x8b0e, - 0x0008, 0x3c1e, 0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x003b, - 0x0003, 0x8b13, 0x0000, 0x3cdc, 0x0003, 0x035d, 0x0009, 0xbbe0, - 0x0008, 0x0035, 0x0003, 0x8b19, 0x0000, 0x8072, 0x0000, 0x8000, - 0x000b, 0x04ce, 0x0009, 0xbbe0, 0x0008, 0x0036, 0x000b, 0x0bf1, - 0x0009, 0xbbe0, 0x0000, 0x0037, 0x0003, 0x8b3e, 0x0000, 0x18fe, - 0x0009, 0x3ce0, 0x000b, 0x8b06, 0x0008, 0x8076, 0x0000, 0x0040, - 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, 0x0009, 0xa6d0, - 0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0, 0x0008, 0x0000, - 0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000, 0x0008, 0x7f08, - 0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a, 0x0000, 0x8066, - 0x0000, 0x0422, 0x000b, 0xc335, 0x000c, 0x0367, 0x0008, 0x8054, - 0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x8072, - 0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0xbbe0, 0x0000, 0x0038, - 0x000b, 0x8b50, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x0003, 0x0b4d, - 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x8afc, 0x000c, 0x0362, - 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, - 0x000b, 0x03b8, 0x0008, 0x8076, 0x0008, 0x0042, 0x0003, 0x035d, - 0x0009, 0xbbe0, 0x0000, 0x0016, 0x0003, 0x8b5d, 0x0000, 0x8074, - 0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818, 0x0000, 0x8074, - 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000, 0x000f, 0x8000, - 0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x0013, - 0x0002, 0x1430, 0x000b, 0x0363, 0x000a, 0x3d30, 0x0000, 0x7f00, - 0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x036b, 0x000a, 0x1930, - 0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a, - 0x0003, 0xc370, 0x000f, 0x4000, 0x000b, 0x2375, 0x0008, 0x0870, - 0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b72, 0x000b, 0xe37f, - 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000, - 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6378, 0x0008, 0x80e0, - 0x0000, 0x0100, 0x000b, 0x0372, 0x0009, 0xbac0, 0x0008, 0x0090, - 0x0003, 0x0b88, 0x0000, 0x8074, 0x0000, 0x0706, 0x0003, 0x038a, - 0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000, 0x0008, 0x8010, - 0x0000, 0x0023, 0x000b, 0x03c6, 0x0008, 0x8010, 0x0000, 0x0008, - 0x000b, 0x03c6, 0x0008, 0x8010, 0x0008, 0x0022, 0x000b, 0x03c6, - 0x000c, 0x0367, 0x0008, 0x8010, 0x0000, 0x0007, 0x0004, 0x0372, - 0x0000, 0x1810, 0x0004, 0x0372, 0x0003, 0x03d0, 0x000c, 0x0367, - 0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0372, 0x0000, 0x1810, - 0x0004, 0x0372, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, - 0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009, 0x000b, 0x03c6, - 0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03c6, 0x000a, 0x1648, - 0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001, 0x0007, 0x0000, - 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143, 0x000b, 0x088c, - 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a, 0x000b, 0x03c6, - 0x0008, 0x8010, 0x0008, 0x0003, 0x0003, 0x03c8, 0x0008, 0x8010, - 0x0000, 0x000b, 0x0003, 0x03c8, 0x0008, 0x8010, 0x0000, 0x0002, - 0x0003, 0x03c8, 0x0002, 0x3a47, 0x0003, 0x8a77, 0x0008, 0x8010, - 0x0008, 0x0006, 0x0003, 0x03c8, 0x0000, 0x8074, 0x0008, 0xf000, - 0x0004, 0x0372, 0x0004, 0x0382, 0x000a, 0x3a40, 0x000b, 0x0813, - 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013, - 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0002, 0x2e4d, - 0x0002, 0x2e4d, 0x000b, 0x0bd9, 0x0008, 0x8054, 0x0000, 0x0019, - 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009, 0x0003, 0x0013, - 0x0002, 0x3a44, 0x0003, 0x8813, 0x000b, 0x03bb, 0x0008, 0x808c, - 0x0008, 0x0000, 0x0002, 0x4447, 0x000b, 0x0c05, 0x0001, 0xc0c0, - 0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff, 0x0003, 0x8bdc, - 0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bdc, 0x0008, 0x8010, - 0x0000, 0x0013, 0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0x0202, - 0x0003, 0x0013, 0x000a, 0x3a40, 0x000b, 0x8c02, 0x0000, 0x8074, - 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, - 0x0000, 0x8000, 0x0001, 0x43e0, 0x0003, 0x8c00, 0x0000, 0x42fe, - 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, 0x000b, 0x0bdc, - 0x0008, 0x0d08, 0x0003, 0x0455, 0x0000, 0x8072, 0x0000, 0x8000, - 0x0003, 0x0013, 0x000c, 0x04d7, 0x0008, 0x808c, 0x0000, 0x0001, - 0x0000, 0x04fc, 0x000b, 0x34ba, 0x0000, 0x0460, 0x0008, 0x8062, - 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc40f, - 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0000, 0x7f00, - 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c29, 0x0001, 0x80e0, - 0x0008, 0x0005, 0x0003, 0x0c29, 0x0001, 0x80e0, 0x0008, 0x0006, - 0x0003, 0x0c29, 0x0001, 0x82c0, 0x0008, 0xff00, 0x0008, 0x7f04, - 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c29, 0x0009, 0x82e0, - 0x0008, 0x0500, 0x0003, 0x0c29, 0x0009, 0x82e0, 0x0000, 0x0400, - 0x000b, 0x8cba, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0009, 0xffe0, - 0x0000, 0x1000, 0x000b, 0x0c55, 0x0004, 0x04c8, 0x0002, 0x3941, - 0x0003, 0x0c34, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, - 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc43a, 0x0008, 0x11fc, - 0x0003, 0x3450, 0x0001, 0x9180, 0x0000, 0x0002, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0609, - 0x0003, 0xc444, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00, - 0x0009, 0x03e0, 0x0003, 0x8c4d, 0x0000, 0x8072, 0x0000, 0x0400, - 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, 0x000b, 0x0437, - 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x0010, - 0x000b, 0x04ad, 0x0004, 0x04c8, 0x0002, 0x3941, 0x0003, 0x0c5b, - 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, 0x0004, 0x0492, - 0x0008, 0x11fc, 0x000b, 0xb463, 0x0000, 0x8072, 0x0000, 0x0400, - 0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04ad, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb478, 0x0008, 0x808c, - 0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc46e, 0x0008, 0x0060, - 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, - 0x0000, 0x8066, 0x0000, 0x0412, 0x000b, 0xc476, 0x000b, 0x048f, - 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062, - 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609, 0x000b, 0xc47f, - 0x0000, 0x8066, 0x0008, 0x220a, 0x0003, 0xc482, 0x0000, 0x42fe, - 0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc48e, 0x0000, 0x8072, - 0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc497, - 0x0008, 0x02fe, 0x0009, 0x03e0, 0x000b, 0x8c9d, 0x0000, 0x0d22, - 0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80, - 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc4a3, - 0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06, - 0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a, 0x000b, 0xc4ab, - 0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44, - 0x000a, 0x2f44, 0x000b, 0x8bbb, 0x0008, 0x808a, 0x0008, 0x0003, - 0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5cb6, 0x0008, 0x8054, - 0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, - 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, - 0x0004, 0x0372, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, - 0x0008, 0x7f10, 0x0004, 0x0372, 0x0008, 0x4310, 0x0003, 0x03c8, - 0x0002, 0x3941, 0x0003, 0x0ccb, 0x000f, 0x4000, 0x0000, 0x8072, - 0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012, - 0x0004, 0x0372, 0x0004, 0x0492, 0x0000, 0x1110, 0x0004, 0x0372, - 0x0008, 0x11fc, 0x000b, 0xb4d1, 0x0003, 0x0013, 0x0009, 0xc2c0, - 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00, - 0x0009, 0x00d0, 0x000b, 0x0cfc, 0x0000, 0x0d0a, 0x0001, 0x8580, - 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4e6, 0x0000, 0x04fc, - 0x0003, 0x34f5, 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004, - 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc4ee, 0x0008, 0x01fe, - 0x0009, 0x00e0, 0x0003, 0x8cf5, 0x0008, 0x02fe, 0x0001, 0x43e0, - 0x0003, 0x0cfb, 0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0, - 0x0000, 0x0800, 0x000b, 0x8cdf, 0x0008, 0x0d08, 0x000f, 0x4000, - 0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0000, 0x0809, 0x0003, 0xc502, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70, - 0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0000, 0x0809, 0x0003, 0xc50d, 0x000f, 0x4000, 0xe5cd, 0x01ac + 0x0001, 0x80e0, 0x0008, 0x0003, 0x000b, 0x8940, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0004, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0e2, 0x0008, 0x0060, + 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, + 0x000b, 0xc0e8, 0x0008, 0x4afe, 0x0009, 0x03e0, 0x000b, 0x8940, + 0x0009, 0xcbc0, 0x0008, 0x00ff, 0x0001, 0x02e0, 0x000b, 0x8940, + 0x0000, 0x49b4, 0x0002, 0x4b4e, 0x000b, 0x8951, 0x0008, 0x808a, + 0x0000, 0x0004, 0x0000, 0x18fe, 0x0001, 0x10e0, 0x000b, 0x88fa, + 0x0002, 0x192f, 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, + 0x000b, 0x88ff, 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc106, 0x000a, 0x004f, + 0x000b, 0x8937, 0x000a, 0x0040, 0x000b, 0x0921, 0x0002, 0x004e, + 0x000b, 0x0921, 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00, + 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc112, 0x0008, 0x1010, + 0x0004, 0x0201, 0x0003, 0xb11a, 0x0004, 0x0387, 0x000c, 0x01eb, + 0x0003, 0x7816, 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010, + 0x0000, 0x001f, 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387, + 0x0003, 0x0118, 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066, + 0x0008, 0x000a, 0x000b, 0xc125, 0x0004, 0x01c4, 0x000a, 0x0040, + 0x000b, 0x093a, 0x0004, 0x0231, 0x0000, 0x8000, 0x0000, 0x0002, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc133, + 0x0000, 0x8072, 0x0000, 0x4000, 0x0003, 0x0118, 0x0008, 0x8010, + 0x0008, 0x001e, 0x0003, 0x013c, 0x0008, 0x8010, 0x0008, 0x001d, + 0x0004, 0x0387, 0x0008, 0x1010, 0x0004, 0x0387, 0x0003, 0x0016, + 0x0002, 0x4b4e, 0x0003, 0x0946, 0x0008, 0x808a, 0x0000, 0x0004, + 0x000b, 0x6146, 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, + 0x0003, 0x0016, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6149, + 0x000b, 0x0014, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, + 0x000b, 0xc158, 0x000a, 0x004f, 0x000b, 0x89b5, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc162, 0x0008, 0x0060, + 0x0008, 0x8062, 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, + 0x000b, 0xc168, 0x000a, 0x014b, 0x0003, 0x09b5, 0x0008, 0x8062, + 0x0008, 0x000f, 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc16f, + 0x0008, 0x01fe, 0x0001, 0x02d0, 0x000b, 0x89b5, 0x0004, 0x01cd, + 0x0003, 0x09b5, 0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002, + 0x0000, 0x8006, 0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a, + 0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, + 0x0003, 0xc184, 0x0003, 0xe185, 0x0008, 0x4908, 0x0008, 0x480a, + 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0008, 0x002b, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc18f, + 0x0008, 0x04fe, 0x0009, 0x02a0, 0x0003, 0x9196, 0x0002, 0x0500, + 0x000b, 0x09b2, 0x000b, 0x0197, 0x0000, 0x05fe, 0x0001, 0x03a0, + 0x000b, 0x11b2, 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10, + 0x0000, 0x0d12, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0000, 0x8066, 0x0008, 0x0832, 0x000b, 0xc1a2, 0x0000, 0x800a, + 0x0000, 0x8005, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, + 0x0003, 0xc1ac, 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01d8, + 0x0003, 0x7816, 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, + 0x0003, 0x0199, 0x0004, 0x01c4, 0x0008, 0x808a, 0x0000, 0x0004, + 0x0008, 0x8010, 0x0008, 0x0021, 0x0004, 0x0387, 0x0008, 0x1010, + 0x0004, 0x0387, 0x0000, 0x4810, 0x0004, 0x0387, 0x0008, 0x4910, + 0x0004, 0x0387, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1cb, + 0x000f, 0x4000, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62, + 0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc1d2, 0x0002, 0x0210, + 0x0001, 0xffc0, 0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002, + 0x0009, 0x0a80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, + 0x000b, 0xc1e0, 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007, + 0x0000, 0x7f06, 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x060a, 0x000b, 0xc1e9, 0x000f, 0x4000, 0x0000, 0x0da0, + 0x0008, 0x0da2, 0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001, + 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, + 0x0008, 0xa012, 0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa, + 0x0000, 0x0dac, 0x0003, 0xc1f9, 0x0009, 0x8880, 0x0008, 0x0009, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xa03a, 0x0003, 0xc1ff, + 0x000f, 0x4000, 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, + 0x000b, 0xc208, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0000, 0x8066, 0x0008, 0x0021, 0x000b, 0xc20e, 0x0000, 0x00fe, + 0x0001, 0x01d0, 0x0003, 0x8a17, 0x0008, 0x02fe, 0x0009, 0x03d0, + 0x000b, 0x0a17, 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006, + 0x0000, 0x0001, 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0xa041, 0x000b, 0xc21f, + 0x0002, 0x0243, 0x000b, 0x8a26, 0x0000, 0x54ac, 0x0000, 0x55ae, + 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2, + 0x0000, 0x0db4, 0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0000, 0x0007, 0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc22f, + 0x000f, 0x4000, 0x000a, 0x3945, 0x000b, 0x8a3b, 0x0000, 0x8072, + 0x0008, 0x4040, 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a39, + 0x000f, 0x4000, 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a33, + 0x000b, 0x023b, 0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0, + 0x0008, 0x0000, 0x0000, 0x7f24, 0x0003, 0x5a46, 0x0008, 0x8054, + 0x0000, 0x0002, 0x0002, 0x1242, 0x0003, 0x0a8c, 0x000a, 0x3a45, + 0x000b, 0x0a7b, 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a78, + 0x0002, 0x1d00, 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc256, 0x0008, 0x00fc, + 0x0003, 0xb275, 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc25e, 0x0008, 0x00fc, + 0x000b, 0x33a9, 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0000, 0x0019, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc267, + 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60, + 0x0008, 0x0efe, 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x0009, 0x0003, 0xc271, 0x0008, 0x003a, 0x0000, 0x1dfe, + 0x000b, 0x0252, 0x0008, 0x0036, 0x0004, 0x00aa, 0x000b, 0x028c, + 0x0000, 0x8074, 0x0000, 0x2000, 0x000b, 0x028c, 0x0002, 0x3a44, + 0x000b, 0x0bd6, 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0, + 0x0008, 0x0000, 0x0008, 0x7f0e, 0x0003, 0xb3a6, 0x0001, 0xa7d0, + 0x0008, 0x0000, 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000, + 0x0009, 0x00d0, 0x0003, 0x8a9c, 0x0000, 0x8074, 0x0008, 0x4040, + 0x0003, 0x5a8c, 0x0003, 0x5241, 0x000a, 0x3a46, 0x0003, 0x8a9c, + 0x0002, 0x3a47, 0x0003, 0x0a97, 0x0008, 0x8054, 0x0000, 0x0004, + 0x0000, 0x8074, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0x92c0, + 0x0000, 0x0fc8, 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8ba0, + 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066, + 0x0000, 0x367a, 0x000b, 0xc2a1, 0x0009, 0x92c0, 0x0008, 0x0780, + 0x0003, 0x8bba, 0x0002, 0x124b, 0x000b, 0x0aaa, 0x0002, 0x2e4d, + 0x0002, 0x2e4d, 0x0003, 0x0ba6, 0x000a, 0x3a46, 0x000b, 0x8aba, + 0x000b, 0x5aac, 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, + 0x000b, 0x0afa, 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0387, + 0x000a, 0x1948, 0x000b, 0x0ab7, 0x000c, 0x037c, 0x0000, 0x1810, + 0x0004, 0x0387, 0x0003, 0x02fa, 0x000a, 0x1948, 0x000b, 0x0abe, + 0x000a, 0x1243, 0x0003, 0x0ba9, 0x000a, 0x194d, 0x0003, 0x0ac2, + 0x000a, 0x1243, 0x000b, 0x0bb0, 0x0003, 0x5ac2, 0x0008, 0x8054, + 0x0000, 0x0004, 0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, + 0x0003, 0x0af4, 0x0002, 0x194f, 0x000b, 0x0ad2, 0x000c, 0x037c, + 0x0000, 0x1810, 0x0004, 0x0201, 0x000b, 0xb2ed, 0x0004, 0x0387, + 0x000c, 0x01eb, 0x0003, 0x02fa, 0x0000, 0x1a60, 0x0008, 0x8062, + 0x0000, 0x001f, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc2d7, + 0x000a, 0x004c, 0x000b, 0x8af4, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x9880, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0000, 0x320a, 0x0003, 0xc2e1, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x9880, 0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x1e0a, 0x000b, 0xc2e9, 0x0000, 0x1826, 0x0000, 0x1928, + 0x0003, 0x02fa, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, + 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387, 0x0003, 0x02fa, + 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0387, + 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0008, 0xf000, + 0x0000, 0x0d30, 0x0002, 0x3a42, 0x0003, 0x8b02, 0x0000, 0x15fc, + 0x0003, 0xb07e, 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501, + 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387, 0x0003, 0x0013, + 0x0009, 0xbbe0, 0x0008, 0x0030, 0x000b, 0x8b1e, 0x0000, 0x18fe, + 0x0009, 0x3ce0, 0x0003, 0x0b1b, 0x0008, 0x15fe, 0x0009, 0x3ce0, + 0x0003, 0x0b1b, 0x0008, 0x13fe, 0x0009, 0x3ce0, 0x000b, 0x8b17, + 0x000c, 0x0375, 0x0008, 0x0d26, 0x000b, 0x0318, 0x0004, 0x0377, + 0x0008, 0x8076, 0x0000, 0x0040, 0x000b, 0x0372, 0x0008, 0x8076, + 0x0008, 0x0041, 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0032, + 0x0003, 0x8b23, 0x0008, 0x3c1e, 0x000b, 0x0372, 0x0009, 0xbbe0, + 0x0000, 0x003b, 0x000b, 0x8b28, 0x0000, 0x3cdc, 0x000b, 0x0372, + 0x0009, 0xbbe0, 0x0008, 0x0035, 0x000b, 0x8b2e, 0x0000, 0x8072, + 0x0000, 0x8000, 0x000b, 0x04e3, 0x0009, 0xbbe0, 0x0008, 0x0036, + 0x000b, 0x0c06, 0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b53, + 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x8b1b, 0x0008, 0x8076, + 0x0000, 0x0040, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0, + 0x0008, 0x0000, 0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000, + 0x0008, 0x7f08, 0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a, + 0x0000, 0x8066, 0x0000, 0x0422, 0x0003, 0xc34a, 0x000c, 0x037c, + 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0xbbe0, + 0x0000, 0x0038, 0x000b, 0x8b65, 0x0000, 0x18fe, 0x0009, 0x3ce0, + 0x000b, 0x0b62, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x000b, 0x8b11, + 0x0004, 0x0377, 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0003, 0x03cd, 0x0008, 0x8076, 0x0008, 0x0042, + 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0016, 0x000b, 0x8b72, + 0x0000, 0x8074, 0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818, + 0x0000, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000, + 0x000f, 0x8000, 0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, + 0x0003, 0x0013, 0x0002, 0x1430, 0x000b, 0x0378, 0x000a, 0x3d30, + 0x0000, 0x7f00, 0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x0380, + 0x000a, 0x1930, 0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x000a, 0x0003, 0xc385, 0x000f, 0x4000, 0x000b, 0x238a, + 0x0008, 0x0870, 0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b87, + 0x000b, 0xe394, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x638d, + 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x0387, 0x0009, 0xbac0, + 0x0008, 0x0090, 0x000b, 0x0b9d, 0x0000, 0x8074, 0x0000, 0x0706, + 0x000b, 0x039f, 0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000, + 0x0008, 0x8010, 0x0000, 0x0023, 0x000b, 0x03db, 0x0008, 0x8010, + 0x0000, 0x0008, 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0022, + 0x000b, 0x03db, 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0007, + 0x0004, 0x0387, 0x0000, 0x1810, 0x0004, 0x0387, 0x0003, 0x03e5, + 0x000c, 0x037c, 0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0387, + 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0000, 0xf080, + 0x0000, 0x0d30, 0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009, + 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03db, + 0x000a, 0x1648, 0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001, + 0x0007, 0x0000, 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143, + 0x000b, 0x088c, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a, + 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0003, 0x000b, 0x03dd, + 0x0008, 0x8010, 0x0000, 0x000b, 0x000b, 0x03dd, 0x0008, 0x8010, + 0x0000, 0x0002, 0x000b, 0x03dd, 0x0002, 0x3a47, 0x000b, 0x8a8c, + 0x0008, 0x8010, 0x0008, 0x0006, 0x000b, 0x03dd, 0x0000, 0x8074, + 0x0008, 0xf000, 0x0004, 0x0387, 0x000c, 0x0397, 0x000a, 0x3a40, + 0x000b, 0x0813, 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387, + 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, + 0x0002, 0x2e4d, 0x0002, 0x2e4d, 0x0003, 0x0bee, 0x0008, 0x8054, + 0x0000, 0x0019, 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009, + 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0003, 0x03d0, + 0x0008, 0x808c, 0x0008, 0x0000, 0x0002, 0x4447, 0x0003, 0x0c1a, + 0x0001, 0xc0c0, 0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff, + 0x0003, 0x8bf1, 0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bf1, + 0x0008, 0x8010, 0x0000, 0x0013, 0x0004, 0x0387, 0x0000, 0x8074, + 0x0008, 0x0202, 0x0003, 0x0013, 0x000a, 0x3a40, 0x0003, 0x8c17, + 0x0000, 0x8074, 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0001, 0x43e0, 0x000b, 0x8c15, + 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, + 0x000b, 0x0bf1, 0x0008, 0x0d08, 0x0003, 0x046a, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0003, 0x0013, 0x0004, 0x04ec, 0x0008, 0x808c, + 0x0000, 0x0001, 0x0000, 0x04fc, 0x0003, 0x34cf, 0x0000, 0x0460, + 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, + 0x0003, 0xc424, 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, + 0x0000, 0x7f00, 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c3e, + 0x0001, 0x80e0, 0x0008, 0x0005, 0x0003, 0x0c3e, 0x0001, 0x80e0, + 0x0008, 0x0006, 0x0003, 0x0c3e, 0x0001, 0x82c0, 0x0008, 0xff00, + 0x0008, 0x7f04, 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c3e, + 0x0009, 0x82e0, 0x0008, 0x0500, 0x0003, 0x0c3e, 0x0009, 0x82e0, + 0x0000, 0x0400, 0x0003, 0x8ccf, 0x0009, 0xc4c0, 0x0000, 0x7000, + 0x0009, 0xffe0, 0x0000, 0x1000, 0x000b, 0x0c6a, 0x000c, 0x04dd, + 0x0002, 0x3941, 0x0003, 0x0c49, 0x0000, 0x8072, 0x0000, 0x0400, + 0x0003, 0x0013, 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc44f, + 0x0008, 0x11fc, 0x0003, 0x3465, 0x0001, 0x9180, 0x0000, 0x0002, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x0609, 0x0003, 0xc459, 0x0000, 0x42fe, 0x0001, 0xffc0, + 0x0008, 0xff00, 0x0009, 0x03e0, 0x000b, 0x8c62, 0x0000, 0x8072, + 0x0000, 0x0400, 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, + 0x000b, 0x044c, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, + 0x0000, 0x0010, 0x000b, 0x04c2, 0x000c, 0x04dd, 0x0002, 0x3941, + 0x0003, 0x0c70, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, + 0x0004, 0x04a7, 0x0008, 0x11fc, 0x000b, 0xb478, 0x0000, 0x8072, + 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04c2, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb48d, + 0x0008, 0x808c, 0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc483, + 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, + 0x0008, 0x4206, 0x0000, 0x8066, 0x0000, 0x0412, 0x0003, 0xc48b, + 0x000b, 0x04a4, 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460, + 0x0008, 0x8062, 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609, + 0x000b, 0xc494, 0x0000, 0x8066, 0x0008, 0x220a, 0x000b, 0xc497, + 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc4a3, + 0x0000, 0x8072, 0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411, + 0x0003, 0xc4ac, 0x0008, 0x02fe, 0x0009, 0x03e0, 0x0003, 0x8cb2, + 0x0000, 0x0d22, 0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002, + 0x0001, 0x6b80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, + 0x0003, 0xc4b8, 0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007, + 0x0000, 0x7f06, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a, + 0x0003, 0xc4c0, 0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813, + 0x000a, 0x2f44, 0x000a, 0x2f44, 0x0003, 0x8bd0, 0x0008, 0x808a, + 0x0008, 0x0003, 0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5ccb, + 0x0008, 0x8054, 0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44, + 0x0003, 0x8813, 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, + 0x0008, 0x0011, 0x0004, 0x0387, 0x0000, 0x42fe, 0x0001, 0xffc0, + 0x0008, 0x00ff, 0x0008, 0x7f10, 0x0004, 0x0387, 0x0008, 0x4310, + 0x000b, 0x03dd, 0x0002, 0x3941, 0x0003, 0x0ce0, 0x000f, 0x4000, + 0x0000, 0x8072, 0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010, + 0x0008, 0x0012, 0x0004, 0x0387, 0x0004, 0x04a7, 0x0000, 0x1110, + 0x0004, 0x0387, 0x0008, 0x11fc, 0x0003, 0xb4e6, 0x0003, 0x0013, + 0x0009, 0xc2c0, 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0, + 0x0008, 0xff00, 0x0009, 0x00d0, 0x0003, 0x0d11, 0x0000, 0x0d0a, + 0x0001, 0x8580, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4fb, + 0x0000, 0x04fc, 0x000b, 0x350a, 0x0000, 0x0460, 0x0008, 0x8062, + 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x000b, 0xc503, + 0x0008, 0x01fe, 0x0009, 0x00e0, 0x000b, 0x8d0a, 0x0008, 0x02fe, + 0x0001, 0x43e0, 0x000b, 0x0d10, 0x0002, 0x0500, 0x0000, 0x7f0a, + 0x0009, 0xffe0, 0x0000, 0x0800, 0x000b, 0x8cf4, 0x0008, 0x0d08, + 0x000f, 0x4000, 0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc517, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00, + 0x0002, 0x7f70, 0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc522, 0x000f, 0x4000, + 0xe4ae, 0x1eb8 }; -unsigned short rseqipx_code_length01 = 0x0a20; +unsigned short rseqipx_code_length01 = 0x0a4a; /* * */ unsigned long xseqipx_code_addr01 = 0x0001e000 ; unsigned short xseqipx_code01[] = { -0x0013, 0x0003, 0x0000, 0x1246, 0x0001, 0xe000, 0x0005, 0x0032, +0x0013, 0x0003, 0x0000, 0x1252, 0x0001, 0xe000, 0x0005, 0x0032, 0x0000, 0x0010, 0x0015, 0x0033, 0x0010, 0xbb39, 0x000b, 0x8007, - 0x0004, 0x0110, 0x0014, 0x0122, 0x0010, 0xc000, 0x0000, 0xc001, + 0x0004, 0x0113, 0x0004, 0x0125, 0x0010, 0xc000, 0x0000, 0xc001, 0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0010, 0xc0b2, 0x0000, 0xc0b3, 0x0010, 0xc0b4, 0x0000, 0xc0b5, 0x0000, 0xc0b6, 0x0010, 0xc0b7, 0x0010, 0xc0b8, 0x0000, 0xc0b9, 0x0000, 0xc0ba, 0x0000, 0xc0c2, @@ -7683,578 +7702,580 @@ unsigned short xseqipx_code01[] = { 0x0010, 0xc0cf, 0x0015, 0x0039, 0x0010, 0xff00, 0x0015, 0x003a, 0x0010, 0xff00, 0x0005, 0x00d0, 0x0010, 0xff00, 0x0015, 0x00d1, 0x0010, 0xff00, 0x0012, 0x3a40, 0x000b, 0x1031, 0x0002, 0x7940, - 0x001b, 0x1134, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035, - 0x0013, 0xa1df, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941, - 0x001b, 0x1314, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001, + 0x001b, 0x1137, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035, + 0x0003, 0xa1e2, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941, + 0x001b, 0x1317, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001, 0x0013, 0x1054, 0x0000, 0x0cfe, 0x0013, 0x6047, 0x0002, 0x3a44, - 0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13c7, - 0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x1459, 0x0012, 0x3a46, + 0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13cd, + 0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x145f, 0x0012, 0x3a46, 0x000b, 0x1054, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x104f, 0x0011, 0x02e8, 0x0010, 0x0005, 0x000b, 0x1054, 0x0000, 0x12fe, - 0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x168f, + 0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x1695, 0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x8059, 0x0010, 0xb2ff, 0x0001, 0xb3e0, - 0x000c, 0x10d2, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010, + 0x001c, 0x10d5, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010, 0x001b, 0x1071, 0x0000, 0x0afe, 0x000b, 0x6065, 0x0000, 0x3c0b, 0x0003, 0x006d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x0a88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x001b, 0x806c, 0x0010, 0x3c0a, 0x0002, 0x0c00, 0x0010, 0xff0c, - 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084, 0x0010, 0x08fe, 0x000b, 0x6078, 0x0010, 0x3c09, 0x0003, 0x0080, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x000b, 0x807f, - 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00cf, + 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0013, 0x000b, 0x108a, 0x0000, 0x3cb0, - 0x0004, 0x00e2, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0000, 0x0019, + 0x0014, 0x00e5, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0019, 0x000b, 0x109d, 0x0010, 0x04fe, 0x001b, 0x6091, 0x0010, 0x3c05, 0x0013, 0x0099, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0488, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x000b, 0x8098, 0x0000, 0x3c04, 0x0002, 0x0c00, 0x0010, 0xff0c, - 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a3, - 0x0015, 0x000f, 0x0010, 0x0000, 0x0013, 0x00cf, 0x0011, 0x3be8, - 0x0000, 0x0015, 0x001b, 0x10af, 0x0004, 0x0119, 0x0014, 0x012b, - 0x0015, 0x0039, 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0110, - 0x0014, 0x0122, 0x0014, 0x00fb, 0x0013, 0x002d, 0x0011, 0x3be8, - 0x0000, 0x0016, 0x000b, 0x10c1, 0x0001, 0x0fe8, 0x0010, 0x0000, - 0x0003, 0x10bb, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10bb, - 0x0015, 0x0039, 0x0010, 0x1010, 0x0013, 0x00cf, 0x0015, 0x0039, - 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f, - 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c6, - 0x0010, 0x3cc3, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0018, - 0x000b, 0x10cb, 0x0000, 0x3cc2, 0x0013, 0x00cf, 0x0005, 0x00ce, - 0x0000, 0x0001, 0x0000, 0x3bcf, 0x0014, 0x08e1, 0x0015, 0x0039, - 0x0000, 0x8000, 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, - 0x0001, 0xc180, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x80d8, 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, - 0x0010, 0xffb2, 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, - 0x0001, 0xb0d0, 0x001b, 0x80e1, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0011, 0xb088, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0010, 0xb109, 0x000b, 0x80e9, 0x0001, 0xb1e8, 0x0010, 0xffff, - 0x0003, 0x10fa, 0x0000, 0x11fe, 0x001b, 0x60f1, 0x0000, 0xb012, - 0x0013, 0x00f9, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, - 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, - 0x000b, 0x80f8, 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xc411, 0x001b, 0x8102, 0x0011, 0xbc88, - 0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, - 0x001b, 0x8108, 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xc709, 0x001b, 0x810e, 0x0017, 0x4000, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a6, + 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0015, 0x000f, + 0x0010, 0x0000, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0015, + 0x001b, 0x10b2, 0x0004, 0x011c, 0x0014, 0x012e, 0x0015, 0x0039, + 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0113, 0x0004, 0x0125, + 0x0014, 0x00fe, 0x0013, 0x002d, 0x0011, 0x3be8, 0x0000, 0x0016, + 0x000b, 0x10c4, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x10be, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10be, 0x0015, 0x0039, + 0x0010, 0x1010, 0x0013, 0x00d2, 0x0015, 0x0039, 0x0000, 0x5040, + 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0013, 0x00d2, + 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c9, 0x0010, 0x3cc3, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0018, 0x000b, 0x10ce, + 0x0000, 0x3cc2, 0x0013, 0x00d2, 0x0005, 0x00ce, 0x0000, 0x0001, + 0x0000, 0x3bcf, 0x0014, 0x08e7, 0x0015, 0x0039, 0x0000, 0x8000, + 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, 0x0001, 0xc180, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x80db, + 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, 0x0010, 0xffb2, + 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, 0x0001, 0xb0d0, + 0x001b, 0x80e4, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xb088, + 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, + 0x000b, 0x80ec, 0x0001, 0xb1e8, 0x0010, 0xffff, 0x0013, 0x10fd, + 0x0000, 0x11fe, 0x001b, 0x60f4, 0x0000, 0xb012, 0x0013, 0x00fc, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x80fb, + 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xc411, 0x000b, 0x8105, 0x0011, 0xbc88, 0x0010, 0x0018, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, 0x001b, 0x810b, + 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xc709, 0x000b, 0x8111, 0x0017, 0x4000, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0x0269, 0x001b, 0x811a, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x0269, 0x000b, 0x8117, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, 0x001b, 0x8123, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, - 0x0000, 0x0001, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, - 0x001b, 0x8120, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0f59, + 0x001b, 0x812c, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0010, 0x0f59, 0x001b, 0x8129, 0x0017, 0x4000, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0010, 0x0f5a, 0x001b, 0x8132, 0x0017, 0x4000, - 0x0000, 0xd0ff, 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, - 0x0010, 0x0101, 0x0003, 0x9139, 0x0005, 0x0079, 0x0000, 0x0001, - 0x0003, 0x913c, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, - 0x0000, 0x0002, 0x0003, 0x1164, 0x0011, 0x02e8, 0x0000, 0x0001, - 0x0003, 0x117c, 0x0011, 0x02e8, 0x0000, 0x0004, 0x0013, 0x119a, - 0x0011, 0x02e8, 0x0010, 0x0003, 0x0003, 0x11cb, 0x0005, 0x0002, - 0x0010, 0x0000, 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8157, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815b, - 0x0012, 0x3a45, 0x0013, 0x1163, 0x0015, 0x003a, 0x0000, 0x2000, - 0x0015, 0x003a, 0x0010, 0x1010, 0x0014, 0x090b, 0x0003, 0x004f, - 0x0012, 0x7849, 0x0003, 0x11d9, 0x0010, 0x0dfe, 0x0003, 0x614d, - 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb309, 0x000b, 0x8171, 0x0010, 0xb3fe, 0x0013, 0x6179, - 0x0010, 0xb30b, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8177, - 0x0013, 0x01ce, 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0013, 0x01ce, - 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11d9, 0x0002, 0xb049, - 0x0003, 0x11d9, 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71, - 0x0010, 0x0dfe, 0x0003, 0x614b, 0x0012, 0x0c10, 0x0010, 0xff0c, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x818f, - 0x0010, 0xb3fe, 0x0013, 0x6197, 0x0000, 0xb309, 0x0015, 0x0033, - 0x0010, 0xc00a, 0x000b, 0x8195, 0x0013, 0x01ce, 0x0010, 0xc009, - 0x0000, 0xc008, 0x0013, 0x01ce, 0x0000, 0x78b0, 0x0012, 0xb044, - 0x0003, 0x11d9, 0x0002, 0xb049, 0x0003, 0x11d9, 0x0010, 0x71ff, - 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614b, - 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb309, 0x001b, 0x81ad, 0x0010, 0xb3fe, 0x0013, 0x61b5, - 0x0000, 0xb305, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b3, - 0x0003, 0x01b7, 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f, - 0x0002, 0xff27, 0x0000, 0x0db8, 0x0014, 0x03bc, 0x0000, 0x0db8, - 0x0014, 0x091f, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88, - 0x0010, 0x0000, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, - 0x001b, 0x81c4, 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114b, - 0x0005, 0x0002, 0x0010, 0x0005, 0x0003, 0x014d, 0x0012, 0x7849, - 0x0003, 0x11d9, 0x0003, 0x014d, 0x0000, 0x0db8, 0x0012, 0x0345, - 0x000b, 0x11d4, 0x0002, 0x033f, 0x0014, 0x03bc, 0x0003, 0x014b, - 0x0002, 0x033f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f, - 0x0003, 0x014b, 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a, - 0x0010, 0x0101, 0x0014, 0x091f, 0x0003, 0x015c, 0x0001, 0x2bd8, - 0x0010, 0x0000, 0x0000, 0xffba, 0x0013, 0xb1e2, 0x0005, 0x002a, - 0x0000, 0x0002, 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12cf, - 0x0011, 0x15e8, 0x0000, 0x0002, 0x0003, 0x1245, 0x0011, 0x15e8, - 0x0000, 0x0001, 0x0003, 0x11f1, 0x0005, 0x0015, 0x0010, 0x0000, - 0x0003, 0x0228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43, - 0x0003, 0x1229, 0x0013, 0xb1f5, 0x0005, 0x002a, 0x0000, 0x0004, - 0x0012, 0xba42, 0x0003, 0x122f, 0x0012, 0x104b, 0x000b, 0x1228, - 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, - 0x0000, 0x1b2a, 0x001b, 0x8201, 0x0011, 0x20d8, 0x0010, 0x0000, - 0x0000, 0xffb0, 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1, - 0x0001, 0x22d8, 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8, - 0x0010, 0x0000, 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000, - 0x0010, 0xffb4, 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5, - 0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, - 0x0010, 0x0000, 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031, - 0x0000, 0x0007, 0x0015, 0x0033, 0x0010, 0xb032, 0x001b, 0x821f, - 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, - 0x0010, 0xb812, 0x001b, 0x8225, 0x0005, 0x0015, 0x0010, 0x0000, - 0x0013, 0x0035, 0x0000, 0x1efe, 0x0013, 0x623d, 0x0014, 0x0274, - 0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0000, 0x1a30, - 0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x8234, 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031, - 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823b, - 0x0003, 0x01fc, 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x091f, - 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f, - 0x0003, 0x0228, 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42, - 0x0013, 0x1253, 0x0003, 0xb249, 0x0001, 0x2bd8, 0x0010, 0x0000, - 0x0012, 0xff4f, 0x001b, 0x11df, 0x0002, 0xba43, 0x001b, 0x122f, - 0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0001, 0x28d8, - 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, - 0x0000, 0xffb9, 0x0004, 0x02e5, 0x0002, 0x3a42, 0x000b, 0x1228, - 0x0000, 0x1c30, 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43, - 0x001b, 0x1264, 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0266, - 0x0001, 0xff88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb011, 0x000b, 0x8269, 0x0000, 0xb0ff, 0x0011, 0x16a0, - 0x0000, 0xff16, 0x001b, 0x2270, 0x0002, 0xb100, 0x0003, 0x0271, - 0x0010, 0xb1ff, 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x022f, - 0x0000, 0x16ff, 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227b, - 0x0002, 0x1700, 0x0003, 0x12ce, 0x0013, 0x027c, 0x0010, 0x17ff, - 0x0011, 0x19a0, 0x0003, 0x22ce, 0x0011, 0x00d0, 0x0003, 0x12ce, - 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, - 0x000b, 0x8284, 0x0003, 0xb285, 0x0000, 0xb120, 0x0010, 0xb221, - 0x0002, 0x1f43, 0x001b, 0x1291, 0x0010, 0xc022, 0x0000, 0xc023, - 0x0000, 0xb324, 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6, - 0x0003, 0x0295, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, - 0x0010, 0xb625, 0x0013, 0xb295, 0x0005, 0x002a, 0x0000, 0x0001, - 0x0012, 0x1500, 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580, - 0x0000, 0xff16, 0x000b, 0x22a0, 0x0002, 0x1700, 0x0013, 0x02a1, - 0x0010, 0x17ff, 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10, - 0x0010, 0xff1e, 0x0013, 0x62ce, 0x0002, 0x1d00, 0x0010, 0xff1d, - 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x000b, 0x82ac, 0x0010, 0xb0fe, 0x000b, 0x62cd, 0x0000, 0x1c30, - 0x0005, 0x0031, 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009, - 0x000b, 0x82b4, 0x0010, 0xb0fe, 0x000b, 0x62ba, 0x0005, 0x00ce, - 0x0010, 0x0005, 0x0003, 0x08e1, 0x0010, 0xb01c, 0x0000, 0x1c30, - 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, - 0x000b, 0x82c0, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f, - 0x0010, 0xc030, 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb009, 0x000b, 0x82c9, 0x0000, 0xb01d, 0x0010, 0x1dff, - 0x0013, 0x02a8, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41, - 0x0013, 0x12d7, 0x0013, 0xb2d1, 0x0005, 0x002a, 0x0000, 0x0004, - 0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x0228, 0x0000, 0x1a30, + 0x0010, 0x0f5a, 0x000b, 0x8135, 0x0017, 0x4000, 0x0000, 0xd0ff, + 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, 0x0010, 0x0101, + 0x0003, 0x913c, 0x0005, 0x0079, 0x0000, 0x0001, 0x0003, 0x913f, + 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, 0x0000, 0x0002, + 0x0003, 0x1167, 0x0011, 0x02e8, 0x0000, 0x0001, 0x0003, 0x117f, + 0x0011, 0x02e8, 0x0000, 0x0004, 0x0003, 0x119d, 0x0011, 0x02e8, + 0x0010, 0x0003, 0x0003, 0x11ce, 0x0005, 0x0002, 0x0010, 0x0000, + 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x815a, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815e, 0x0012, 0x3a45, + 0x0013, 0x1166, 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a, + 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x004f, 0x0012, 0x7849, + 0x0003, 0x11dc, 0x0010, 0x0dfe, 0x0003, 0x6150, 0x0012, 0x0c10, + 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, + 0x000b, 0x8174, 0x0010, 0xb3fe, 0x0013, 0x617c, 0x0010, 0xb30b, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x817a, 0x0003, 0x01d1, + 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0003, 0x01d1, 0x0000, 0x78b0, + 0x0012, 0xb044, 0x0003, 0x11dc, 0x0002, 0xb049, 0x0003, 0x11dc, + 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, + 0x0003, 0x614e, 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x8192, 0x0010, 0xb3fe, + 0x0003, 0x619a, 0x0000, 0xb309, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x001b, 0x8198, 0x0003, 0x01d1, 0x0010, 0xc009, 0x0000, 0xc008, + 0x0003, 0x01d1, 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11dc, + 0x0002, 0xb049, 0x0003, 0x11dc, 0x0010, 0x71ff, 0x0012, 0xff38, + 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614e, 0x0012, 0x0c10, + 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, + 0x001b, 0x81b0, 0x0010, 0xb3fe, 0x0003, 0x61b8, 0x0000, 0xb305, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b6, 0x0013, 0x01ba, + 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f, 0x0002, 0xff27, + 0x0000, 0x0db8, 0x0014, 0x03c2, 0x0000, 0x0db8, 0x0014, 0x0925, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88, 0x0010, 0x0000, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x81c7, + 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114e, 0x0005, 0x0002, + 0x0010, 0x0005, 0x0003, 0x0150, 0x0012, 0x7849, 0x0003, 0x11dc, + 0x0003, 0x0150, 0x0000, 0x0db8, 0x0012, 0x0345, 0x000b, 0x11d7, + 0x0002, 0x033f, 0x0014, 0x03c2, 0x0003, 0x014e, 0x0002, 0x033f, + 0x0002, 0xff27, 0x0014, 0x03c2, 0x0014, 0x0925, 0x0003, 0x014e, + 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a, 0x0010, 0x0101, + 0x0014, 0x0925, 0x0003, 0x015f, 0x0001, 0x2bd8, 0x0010, 0x0000, + 0x0000, 0xffba, 0x0003, 0xb1e5, 0x0005, 0x002a, 0x0000, 0x0002, + 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12d2, 0x0011, 0x15e8, + 0x0000, 0x0002, 0x0013, 0x1248, 0x0011, 0x15e8, 0x0000, 0x0001, + 0x0003, 0x11f4, 0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x022b, + 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43, 0x0003, 0x122c, + 0x0003, 0xb1f8, 0x0005, 0x002a, 0x0000, 0x0004, 0x0012, 0xba42, + 0x0003, 0x1232, 0x0012, 0x104b, 0x000b, 0x122b, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, - 0x001b, 0x82dc, 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x091f, - 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f, - 0x0013, 0x0039, 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10, - 0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb009, 0x000b, 0x82ed, 0x0010, 0xb0fe, 0x000b, 0x6312, - 0x0000, 0x1cff, 0x0001, 0x1ae0, 0x0013, 0x12fc, 0x0000, 0x1c30, - 0x0005, 0x0031, 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x82f8, 0x0010, 0xb0fe, 0x001b, 0x62fc, 0x0000, 0x1aff, - 0x0000, 0xff1c, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019, - 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8302, 0x0001, 0xb0c8, - 0x0010, 0x000f, 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d, - 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x830c, 0x0010, 0xb0fe, 0x000b, 0x6312, 0x0005, 0x00ce, - 0x0010, 0x0006, 0x0003, 0x08e1, 0x0000, 0xb01b, 0x0017, 0x4000, - 0x0010, 0x79b0, 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039, - 0x0015, 0x00d1, 0x0010, 0x0101, 0x0003, 0x931a, 0x0005, 0x0079, - 0x0000, 0x0002, 0x0013, 0x931d, 0x0015, 0x00d1, 0x0000, 0x0100, - 0x0010, 0x13fe, 0x0003, 0x636b, 0x0012, 0xb04e, 0x000b, 0x1394, - 0x0000, 0x78b0, 0x0002, 0xb045, 0x0003, 0x139a, 0x0012, 0x784a, - 0x0003, 0x139a, 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800, - 0x001b, 0x139a, 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x1339, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x8f0a, 0x000b, 0x8337, - 0x0013, 0x03a0, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1344, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a, - 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8342, 0x0013, 0x03a0, - 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x134b, 0x0005, 0x00ce, - 0x0000, 0x0007, 0x0010, 0x0fcf, 0x0003, 0x08db, 0x0002, 0xd142, - 0x0013, 0x1361, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0005, 0x0031, - 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb409, 0x001b, 0x8353, - 0x0002, 0xb400, 0x0010, 0xffb4, 0x0005, 0x0031, 0x0011, 0x1b6e, - 0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x835a, 0x0012, 0xd042, - 0x0013, 0x136b, 0x0015, 0x00b8, 0x0000, 0x000d, 0x0014, 0x091f, - 0x0003, 0x0054, 0x0000, 0x13b8, 0x0002, 0x1045, 0x0003, 0x1369, - 0x0012, 0x103f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f, - 0x0003, 0x036b, 0x0012, 0x103f, 0x0014, 0x03bc, 0x0015, 0x000f, - 0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x1374, 0x0015, 0x0039, - 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x000c, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x837b, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x837f, - 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0000, 0xa4ff, - 0x0003, 0x638c, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x238c, - 0x0015, 0x00d1, 0x0010, 0x0404, 0x0015, 0x003a, 0x0000, 0x8000, - 0x0002, 0x3a47, 0x0003, 0x1393, 0x0015, 0x003a, 0x0000, 0x8000, - 0x0015, 0x003a, 0x0010, 0x4040, 0x0004, 0x08e6, 0x0013, 0x0039, - 0x0015, 0x00b8, 0x0010, 0x0003, 0x0015, 0x003a, 0x0010, 0x0202, - 0x0014, 0x091f, 0x0003, 0x0383, 0x0015, 0x00b8, 0x0000, 0x0002, - 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x091f, 0x0003, 0x0383, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x83a7, - 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0010, 0xc00a, 0x000b, 0x83ad, 0x0010, 0xb0fe, 0x0013, 0x63b2, - 0x0000, 0xb012, 0x0013, 0x03b4, 0x0010, 0xc012, 0x0010, 0xc011, - 0x0012, 0x104b, 0x0003, 0x134b, 0x0002, 0x103b, 0x0010, 0xff03, - 0x0005, 0x0002, 0x0010, 0x0000, 0x0000, 0xc00d, 0x0013, 0x034b, - 0x0000, 0xffb0, 0x0010, 0xc3b1, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0001, 0xb888, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb012, 0x001b, 0x83c5, 0x0017, 0x4000, 0x0002, 0xd142, - 0x001b, 0x147f, 0x0012, 0x3a43, 0x0003, 0x13d8, 0x0015, 0x003a, - 0x0000, 0x0800, 0x0010, 0x0db0, 0x0013, 0x63d8, 0x0000, 0x0bff, - 0x0001, 0xb0e0, 0x0003, 0x1401, 0x0010, 0x09ff, 0x0001, 0xb0e0, - 0x0013, 0x13e5, 0x0010, 0x05ff, 0x0001, 0xb0e0, 0x0013, 0x13dc, - 0x0000, 0xc00e, 0x0000, 0x05fe, 0x0013, 0x63e2, 0x0000, 0x050d, - 0x0005, 0x0002, 0x0000, 0x0004, 0x0014, 0x0466, 0x0002, 0x3a47, - 0x000b, 0x1465, 0x0013, 0x03fc, 0x0000, 0x09fe, 0x0003, 0x63fe, - 0x0000, 0x090d, 0x0005, 0x0002, 0x0000, 0x0001, 0x0004, 0x0494, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x83ef, - 0x0011, 0x03c8, 0x0010, 0x000f, 0x0000, 0xffb6, 0x0011, 0xb6e8, - 0x0000, 0x0001, 0x0003, 0x1539, 0x0011, 0xb6e8, 0x0000, 0x0002, - 0x0013, 0x155b, 0x0011, 0xb6e8, 0x0010, 0x0003, 0x0003, 0x164d, - 0x0004, 0x08e6, 0x0003, 0x0465, 0x0010, 0x0bfe, 0x0003, 0x6465, - 0x0010, 0x0b0d, 0x0005, 0x0002, 0x0000, 0x0002, 0x0004, 0x0494, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x001b, 0x840b, - 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033, - 0x0000, 0xb009, 0x000b, 0x8411, 0x0001, 0xb0a8, 0x0000, 0x199a, - 0x0013, 0x2417, 0x0005, 0x00b0, 0x0000, 0x1999, 0x0012, 0xb050, - 0x0000, 0xffb0, 0x0002, 0xff50, 0x0002, 0xff50, 0x0001, 0xb080, - 0x0000, 0xffb0, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0010, 0x0006, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, - 0x000b, 0x8424, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0019, - 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x842a, 0x0001, 0xb0c8, - 0x0010, 0x00ff, 0x0001, 0xffe8, 0x0010, 0x0048, 0x000b, 0x14a3, - 0x0005, 0x0002, 0x0010, 0x0006, 0x0012, 0x0c10, 0x0010, 0xff0c, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x843b, - 0x0000, 0xb10b, 0x001b, 0x643f, 0x0010, 0xb10a, 0x0015, 0x0033, - 0x0010, 0xc00a, 0x000b, 0x8441, 0x0002, 0x032b, 0x0010, 0xff03, - 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0010, 0x030a, 0x001b, 0x8449, 0x0000, 0x11fe, 0x001b, 0x644e, - 0x0000, 0x0d12, 0x0013, 0x0457, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0001, 0x1188, 0x0010, 0x0003, 0x0000, 0xff31, 0x0010, 0x0db0, - 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8456, 0x0000, 0x0d11, - 0x0003, 0x0465, 0x0002, 0xd142, 0x0013, 0x145c, 0x0013, 0x047f, - 0x0000, 0x05fe, 0x0003, 0x6465, 0x0005, 0x0002, 0x0000, 0x0004, - 0x0000, 0x050d, 0x0014, 0x0466, 0x0002, 0x3a47, 0x000b, 0x1465, - 0x0004, 0x08e6, 0x0013, 0x0047, 0x0001, 0xc7c8, 0x0010, 0x0028, - 0x000b, 0x147e, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x8470, 0x0002, 0xb04f, 0x0013, 0x147e, 0x0001, 0x0fe8, - 0x0010, 0x0000, 0x0003, 0x147c, 0x0001, 0x0fe8, 0x0000, 0x0002, - 0x0003, 0x147c, 0x0015, 0x003a, 0x0010, 0x8080, 0x0003, 0x047e, - 0x0015, 0x003a, 0x0010, 0x4040, 0x0017, 0x4000, 0x0000, 0x12fe, - 0x001b, 0x604f, 0x0015, 0x0012, 0x0001, 0x1b56, 0x0015, 0x0011, - 0x0001, 0x1b56, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x848a, 0x0005, 0x00b0, - 0x0000, 0x8000, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x8492, 0x0003, 0x004f, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x001b, 0x849b, - 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb909, 0x001b, 0x84a1, 0x0017, 0x4000, 0x0005, 0x00b6, - 0x0010, 0x0600, 0x0004, 0x067d, 0x0014, 0x0515, 0x0000, 0xb05a, - 0x0000, 0xb15b, 0x0005, 0x0054, 0x0010, 0x0829, 0x0010, 0x0d58, - 0x0015, 0x0059, 0x0010, 0xffff, 0x0000, 0xb930, 0x0005, 0x0031, - 0x0010, 0x001e, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84b3, - 0x0000, 0xb05c, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033, - 0x0000, 0xb009, 0x001b, 0x84b9, 0x0001, 0xb0c8, 0x0010, 0x000f, - 0x000b, 0x14c0, 0x0015, 0x00ff, 0x0010, 0x0005, 0x0013, 0x04c8, - 0x0002, 0xb040, 0x0013, 0x14c5, 0x0015, 0x00ff, 0x0000, 0x0004, - 0x0013, 0x04c8, 0x0001, 0xb0c8, 0x0010, 0x0006, 0x0002, 0xff60, - 0x0010, 0xffb2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0000, 0x0019, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, - 0x001b, 0x84d0, 0x0012, 0xb170, 0x0011, 0xffc8, 0x0010, 0xff00, - 0x0011, 0xb2d0, 0x0010, 0xff60, 0x0002, 0xb045, 0x0013, 0x14db, - 0x0015, 0x00b2, 0x0000, 0x0002, 0x0013, 0x04e5, 0x0002, 0xb046, - 0x0003, 0x14e0, 0x0015, 0x00b2, 0x0000, 0x0001, 0x0013, 0x04e5, - 0x0015, 0x00b2, 0x0010, 0x0000, 0x0000, 0xc0b0, 0x0010, 0xc0b1, - 0x0003, 0x04eb, 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x002b, - 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x84ea, 0x0010, 0xb16a, - 0x0010, 0xb06b, 0x0000, 0xb261, 0x0015, 0x0044, 0x0010, 0x0018, - 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, - 0x0000, 0x6241, 0x000b, 0x84f5, 0x0003, 0x94f6, 0x0015, 0x00a0, - 0x0000, 0x0020, 0x0012, 0xd041, 0x000b, 0x14f9, 0x0015, 0x00d1, - 0x0010, 0x0202, 0x0013, 0x94fd, 0x0000, 0x75ff, 0x0011, 0xffc8, - 0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0013, 0x9503, - 0x0000, 0xff75, 0x0013, 0x9505, 0x0015, 0x00d1, 0x0000, 0x0200, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008, - 0x0000, 0xff31, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0, - 0x0010, 0x0009, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8513, - 0x0003, 0x0465, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0035, - 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x851a, 0x0002, 0xb040, - 0x0003, 0x1536, 0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031, - 0x0001, 0x1b72, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8523, - 0x0002, 0xb100, 0x0010, 0xffb1, 0x000b, 0x252a, 0x0012, 0xb000, - 0x0000, 0xffb0, 0x0003, 0x2524, 0x0015, 0x0033, 0x0000, 0xb012, - 0x000b, 0x852c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0000, 0x0013, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, - 0x000b, 0x8534, 0x0003, 0x0538, 0x0010, 0xc0b1, 0x0000, 0xc0b0, - 0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0500, 0x0004, 0x067d, - 0x0005, 0x0054, 0x0010, 0x0889, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb009, 0x000b, 0x8545, 0x0010, 0xb058, 0x0000, 0x0d59, - 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, - 0x0000, 0xb011, 0x001b, 0x854d, 0x0010, 0xb15c, 0x0010, 0xb05d, - 0x0005, 0x0031, 0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011, - 0x000b, 0x8554, 0x0000, 0xb15e, 0x0000, 0xb05f, 0x0003, 0x9557, - 0x0015, 0x00a0, 0x0010, 0x000c, 0x0003, 0x0662, 0x0005, 0x00b6, - 0x0000, 0x0700, 0x0004, 0x067d, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0010, 0xb709, 0x001b, 0x8565, 0x0012, 0xb749, 0x0013, 0x156b, - 0x0005, 0x0054, 0x0010, 0x0889, 0x0003, 0x056d, 0x0005, 0x0054, - 0x0010, 0x0898, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x8574, 0x0010, 0xb058, 0x0000, 0x0d59, 0x0001, 0xb9c8, - 0x0010, 0xf000, 0x0001, 0xffe8, 0x0010, 0xf000, 0x000b, 0x159d, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8583, - 0x0001, 0xb0c8, 0x0000, 0xf700, 0x0000, 0xffb0, 0x0011, 0xb0e8, - 0x0000, 0xf100, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0000, 0xf200, - 0x0013, 0x15e9, 0x0011, 0xb0e8, 0x0010, 0xf300, 0x0013, 0x160e, - 0x0011, 0xb0e8, 0x0000, 0xf400, 0x0013, 0x1613, 0x0011, 0xb0e8, - 0x0010, 0xf500, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0010, 0xf600, - 0x0013, 0x1625, 0x0005, 0x00ce, 0x0010, 0x0009, 0x0000, 0xb0cf, - 0x0003, 0x08db, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0025, - 0x0015, 0x0033, 0x0000, 0xb039, 0x000b, 0x85a2, 0x0012, 0xb749, - 0x0013, 0x15a7, 0x0002, 0xb52c, 0x0000, 0xffb5, 0x0000, 0xb162, - 0x0000, 0xb063, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033, - 0x0000, 0xb309, 0x000b, 0x85ad, 0x0001, 0xb3c8, 0x0010, 0x0003, - 0x0013, 0x15b5, 0x0010, 0xffb2, 0x0001, 0xffe8, 0x0010, 0x0003, - 0x001b, 0x15b7, 0x0000, 0xc2b7, 0x0013, 0x0641, 0x0001, 0xb2e8, - 0x0000, 0x0001, 0x0003, 0x15be, 0x0005, 0x00ce, 0x0010, 0x000a, - 0x0010, 0xb2cf, 0x0003, 0x08db, 0x0010, 0xb465, 0x0010, 0xb667, - 0x0015, 0x00b7, 0x0010, 0x0018, 0x0001, 0xb5c8, 0x0010, 0x0300, - 0x0013, 0x15e3, 0x0012, 0xb548, 0x0003, 0x15ca, 0x0000, 0xb6ff, - 0x0011, 0xb780, 0x0010, 0xffb7, 0x0002, 0xb549, 0x0003, 0x15cf, - 0x0010, 0xb4ff, 0x0011, 0xb780, 0x0010, 0xffb7, 0x0015, 0x0044, - 0x0010, 0x0018, 0x0005, 0x0031, 0x0000, 0x002c, 0x0015, 0x0033, - 0x0000, 0x6841, 0x000b, 0x85d5, 0x0015, 0x0044, 0x0000, 0x0019, - 0x0005, 0x0031, 0x0000, 0x0034, 0x0015, 0x0033, 0x0000, 0x5029, - 0x000b, 0x85dc, 0x0015, 0x0044, 0x0000, 0x0008, 0x0011, 0xb7c8, - 0x0010, 0x0003, 0x0013, 0x15e3, 0x0010, 0xff55, 0x0013, 0x0641, - 0x0005, 0x00b5, 0x0000, 0x0008, 0x0015, 0x00b7, 0x0010, 0x0018, - 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011, - 0x001b, 0x85f0, 0x0010, 0xb1ff, 0x0001, 0xb0d0, 0x0003, 0x15f9, - 0x0005, 0x00b5, 0x0010, 0x0b02, 0x0010, 0xb062, 0x0010, 0xb163, - 0x0003, 0x05fb, 0x0005, 0x00b5, 0x0000, 0x0302, 0x0015, 0x0065, - 0x0010, 0x0012, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x006c, - 0x0000, 0x7000, 0x0005, 0x006d, 0x0010, 0x0500, 0x0015, 0x006f, - 0x0010, 0x000a, 0x0015, 0x0044, 0x0000, 0x0001, 0x0005, 0x0052, - 0x0000, 0x2500, 0x0015, 0x0044, 0x0000, 0x0008, 0x0015, 0x00b7, - 0x0000, 0x0032, 0x0013, 0x0641, 0x0005, 0x00b5, 0x0010, 0x0028, - 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0005, 0x00b5, - 0x0000, 0x0100, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0018, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x861e, 0x0001, 0xb0c8, - 0x0010, 0x00ff, 0x0010, 0xff69, 0x0015, 0x00b7, 0x0000, 0x0020, - 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb609, - 0x000b, 0x862c, 0x0001, 0xb6c8, 0x0010, 0xff00, 0x0000, 0xffb0, - 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8632, 0x0001, 0xb6c8, - 0x0010, 0x00ff, 0x0012, 0xff10, 0x000b, 0x163b, 0x0000, 0xffb5, - 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0010, 0xff63, - 0x0005, 0x00b5, 0x0000, 0x0800, 0x0015, 0x00b7, 0x0010, 0x0018, - 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, - 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x8648, 0x0010, 0xb561, 0x0003, 0x964a, 0x0010, 0xb7a0, - 0x0003, 0x0662, 0x0005, 0x00b6, 0x0010, 0x0300, 0x0004, 0x067d, - 0x0005, 0x0054, 0x0010, 0x0819, 0x0010, 0x0d58, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x865a, 0x0000, 0xb059, - 0x0013, 0x965c, 0x0010, 0xc0a0, 0x0010, 0x71ff, 0x0002, 0xff28, - 0x0010, 0xff71, 0x0003, 0x0662, 0x0012, 0xd041, 0x000b, 0x1662, - 0x0015, 0x00d1, 0x0010, 0x0202, 0x0000, 0x75ff, 0x0011, 0xffc8, - 0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0003, 0x966b, - 0x0000, 0xff75, 0x0003, 0x966d, 0x0015, 0x00d1, 0x0000, 0x0200, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008, - 0x0000, 0xff31, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x00b1, - 0x0010, 0x07d0, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x867b, - 0x0003, 0x0465, 0x0015, 0x0044, 0x0000, 0x0008, 0x0005, 0x0098, - 0x0010, 0x0056, 0x0015, 0x0099, 0x0000, 0x9575, 0x0004, 0x08a2, - 0x0000, 0xb096, 0x0012, 0xb270, 0x0010, 0xff56, 0x0004, 0x08c4, - 0x0010, 0xb052, 0x0010, 0xb153, 0x0000, 0xb6ff, 0x0011, 0xb2d0, - 0x0010, 0xff50, 0x0010, 0xb351, 0x0017, 0x4000, 0x0001, 0x12e8, - 0x0001, 0x1b56, 0x0013, 0x183f, 0x0015, 0x00d1, 0x0000, 0x0400, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0011, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1009, 0x000b, 0x869b, - 0x0015, 0x000f, 0x0000, 0x0001, 0x0010, 0xc014, 0x0000, 0x1213, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0004, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x86a7, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0005, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1a09, 0x001b, 0x86af, - 0x0012, 0x104b, 0x001b, 0x16b8, 0x0000, 0x1a30, 0x0005, 0x0031, - 0x0000, 0x000b, 0x0015, 0x0033, 0x0000, 0x1621, 0x001b, 0x86b7, - 0x0010, 0x15fe, 0x000b, 0x66d7, 0x0014, 0x06fe, 0x0002, 0x3a42, - 0x000b, 0x16fd, 0x0001, 0x10c8, 0x0010, 0x000f, 0x000b, 0x1760, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0008, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86c7, - 0x0011, 0xb0e8, 0x0010, 0x0009, 0x0013, 0x16ce, 0x0011, 0xb0e8, - 0x0000, 0x0001, 0x001b, 0x16fc, 0x0011, 0x1388, 0x0010, 0x000a, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86d3, - 0x0002, 0xb04f, 0x001b, 0x16f3, 0x0013, 0x06fc, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x86de, 0x0015, 0x0033, - 0x0010, 0xc00a, 0x001b, 0x86e1, 0x0010, 0xb0fe, 0x0003, 0x66e6, - 0x0000, 0xb012, 0x0013, 0x06e8, 0x0010, 0xc012, 0x0010, 0xc011, - 0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, 0x0013, 0x16f1, - 0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, - 0x0014, 0x091f, 0x0000, 0xc013, 0x0003, 0x06fd, 0x0010, 0x02fe, - 0x0003, 0x66f8, 0x0015, 0x003a, 0x0010, 0x2020, 0x0003, 0x06fd, - 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a, 0x0010, 0x1010, - 0x0014, 0x090b, 0x0003, 0x0054, 0x0013, 0xb6fe, 0x0005, 0x002a, - 0x0000, 0x0004, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b, - 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8706, 0x0000, 0xc02c, - 0x0000, 0xb02d, 0x0012, 0x104b, 0x0013, 0x1721, 0x0000, 0x1a30, - 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb129, - 0x001b, 0x8710, 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322, - 0x0000, 0xb423, 0x0000, 0xb524, 0x0000, 0xc025, 0x0010, 0xb526, - 0x0010, 0xc027, 0x0010, 0xb516, 0x0010, 0xc017, 0x0000, 0xb518, - 0x0000, 0xc019, 0x0010, 0xc028, 0x0000, 0xc029, 0x0010, 0xc01e, - 0x0013, 0x0757, 0x0012, 0x1044, 0x0003, 0x1751, 0x0002, 0x1034, - 0x0000, 0xff10, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, - 0x0015, 0x0033, 0x0000, 0x1b29, 0x001b, 0x872a, 0x0000, 0x1c30, - 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x001b, 0x872f, - 0x0002, 0x1f43, 0x000b, 0x1736, 0x0010, 0xb3b5, 0x0000, 0xb4b6, - 0x0000, 0xc0b3, 0x0010, 0xc0b4, 0x0000, 0xb120, 0x0010, 0xb221, + 0x001b, 0x8204, 0x0011, 0x20d8, 0x0010, 0x0000, 0x0000, 0xffb0, + 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1, 0x0001, 0x22d8, + 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8, 0x0010, 0x0000, + 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000, 0x0010, 0xffb4, + 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5, 0x0001, 0x28d8, + 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, + 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0007, + 0x0015, 0x0033, 0x0010, 0xb032, 0x000b, 0x8222, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0010, 0xb812, + 0x000b, 0x8228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x0035, + 0x0000, 0x1efe, 0x0013, 0x6240, 0x0014, 0x0277, 0x0000, 0x1efe, + 0x000c, 0x6277, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8237, + 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031, 0x0000, 0x0020, + 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823e, 0x0003, 0x01ff, + 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x0925, 0x0000, 0x13b8, + 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0003, 0x022b, + 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42, 0x0013, 0x1256, + 0x0003, 0xb24c, 0x0001, 0x2bd8, 0x0010, 0x0000, 0x0012, 0xff4f, + 0x000b, 0x11e2, 0x0002, 0xba43, 0x001b, 0x1232, 0x0000, 0x1efe, + 0x000c, 0x6277, 0x0003, 0x022b, 0x0001, 0x28d8, 0x0010, 0x0000, + 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, 0x0000, 0xffb9, + 0x0014, 0x02e8, 0x0002, 0x3a42, 0x000b, 0x122b, 0x0000, 0x1c30, + 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43, 0x001b, 0x1267, + 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0269, 0x0001, 0xff88, + 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011, + 0x000b, 0x826c, 0x0000, 0xb0ff, 0x0011, 0x16a0, 0x0000, 0xff16, + 0x001b, 0x2273, 0x0002, 0xb100, 0x0003, 0x0274, 0x0010, 0xb1ff, + 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x0232, 0x0000, 0x16ff, + 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227e, 0x0002, 0x1700, + 0x0013, 0x12d1, 0x0013, 0x027f, 0x0010, 0x17ff, 0x0011, 0x19a0, + 0x0013, 0x22d1, 0x0011, 0x00d0, 0x0013, 0x12d1, 0x0000, 0x1c30, + 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x000b, 0x8287, + 0x0013, 0xb288, 0x0000, 0xb120, 0x0010, 0xb221, 0x0002, 0x1f43, + 0x001b, 0x1294, 0x0010, 0xc022, 0x0000, 0xc023, 0x0000, 0xb324, + 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0013, 0x0298, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625, - 0x0010, 0xb516, 0x0000, 0xb617, 0x0000, 0x1826, 0x0000, 0x1927, - 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, - 0x0000, 0xb011, 0x001b, 0x8745, 0x0000, 0xb028, 0x0000, 0xb129, - 0x0012, 0x1e10, 0x0010, 0xff1e, 0x0013, 0x6757, 0x0002, 0x1d00, - 0x0010, 0xff1d, 0x0004, 0x02a8, 0x0002, 0x3a42, 0x0003, 0x1757, - 0x0003, 0x075f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, - 0x0015, 0x0033, 0x0000, 0x1b79, 0x000b, 0x8756, 0x0003, 0xb757, - 0x0005, 0x002a, 0x0000, 0x0001, 0x0005, 0x0015, 0x0000, 0x0001, - 0x0000, 0x1efe, 0x0003, 0x675f, 0x0003, 0x0274, 0x0017, 0x4000, - 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, - 0x0010, 0xb051, 0x000b, 0x8765, 0x0000, 0xb0a3, 0x0010, 0xb697, - 0x0010, 0xb946, 0x0015, 0x00a5, 0x0000, 0x0010, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0002, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xb509, 0x000b, 0x8772, 0x0004, 0x08c4, - 0x0004, 0x08b3, 0x0012, 0xb470, 0x0010, 0xffb4, 0x0010, 0xb48e, - 0x0010, 0xb08a, 0x0010, 0xb18b, 0x0012, 0x104d, 0x0013, 0x177d, - 0x0003, 0x07aa, 0x0012, 0x104b, 0x0013, 0x1790, 0x0005, 0x008c, - 0x0010, 0x0829, 0x0010, 0xc08d, 0x0001, 0xb2d8, 0x0010, 0x0600, - 0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591, - 0x0000, 0xc08f, 0x0010, 0x1ab9, 0x0014, 0x0515, 0x0003, 0x978b, - 0x0010, 0xb092, 0x0010, 0xb193, 0x0003, 0x978e, 0x0003, 0x07a5, - 0x0005, 0x008c, 0x0000, 0x0809, 0x0015, 0x008d, 0x0000, 0x0008, - 0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389, - 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0000, 0x1a30, - 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011, - 0x000b, 0x87a0, 0x0013, 0x97a1, 0x0000, 0xb192, 0x0000, 0xb093, - 0x0013, 0x97a4, 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0015, 0x00b1, - 0x0010, 0x0096, 0x0003, 0x081b, 0x0000, 0xb590, 0x0010, 0x1391, - 0x0001, 0x10c8, 0x0010, 0x000f, 0x0001, 0xffe8, 0x0010, 0x0005, - 0x0013, 0x17d1, 0x0001, 0xb2d8, 0x0000, 0x0700, 0x0010, 0xff88, - 0x0010, 0xb389, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, - 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x87bc, 0x0002, 0xb049, 0x0003, 0x17c4, 0x0005, 0x008c, - 0x0010, 0x0889, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0013, 0x07c8, - 0x0005, 0x008c, 0x0010, 0x0898, 0x0015, 0x00b1, 0x0000, 0x0092, - 0x0010, 0xc08d, 0x0000, 0xc08f, 0x0003, 0x97ca, 0x0000, 0xc092, - 0x0010, 0xc093, 0x0013, 0x97cd, 0x0010, 0x19a1, 0x0000, 0x18a2, - 0x0003, 0x081b, 0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88, - 0x0010, 0xb389, 0x0005, 0x008c, 0x0010, 0x0880, 0x0015, 0x008d, - 0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, - 0x0000, 0x000e, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x87e0, 0x0010, 0xb08f, 0x0000, 0xb590, 0x0010, 0x1391, - 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000d, 0x0015, 0x0033, - 0x0000, 0xb021, 0x001b, 0x87e9, 0x0013, 0x97ea, 0x0010, 0xb392, - 0x0010, 0xb293, 0x0003, 0x97ed, 0x0000, 0xb1a1, 0x0010, 0xb0a2, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000b, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x87f7, - 0x0000, 0xb3ff, 0x0001, 0xb080, 0x0000, 0xffb3, 0x001b, 0x27fe, - 0x0002, 0xb200, 0x0003, 0x07ff, 0x0010, 0xb2ff, 0x0011, 0xb180, - 0x0010, 0xffb2, 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0010, 0xb212, 0x000b, 0x8806, 0x0015, 0x00b1, - 0x0000, 0x0092, 0x0002, 0x104c, 0x0003, 0x1819, 0x0011, 0xc2e8, - 0x0010, 0x000c, 0x000b, 0x1811, 0x0015, 0x00ff, 0x0000, 0x0800, - 0x0013, 0x0819, 0x0011, 0xc2e8, 0x0000, 0x0020, 0x000b, 0x1817, - 0x0015, 0x00ff, 0x0010, 0x1800, 0x0013, 0x0819, 0x0015, 0x00ff, - 0x0000, 0x1000, 0x0011, 0xb1d0, 0x0010, 0xffb1, 0x0015, 0x009a, - 0x0010, 0x0036, 0x0005, 0x009b, 0x0000, 0x95d5, 0x0012, 0xd041, - 0x001b, 0x181f, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9823, - 0x0012, 0x104e, 0x0013, 0x1828, 0x0012, 0xb12f, 0x0010, 0xffb1, - 0x0000, 0xb175, 0x0013, 0x9829, 0x0015, 0x00d1, 0x0000, 0x0200, - 0x0001, 0x19c8, 0x0010, 0xfff0, 0x001b, 0x1832, 0x0015, 0x00b1, - 0x0010, 0x07d0, 0x0013, 0x0834, 0x0015, 0x00b1, 0x0000, 0x1b58, - 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0030, 0x0000, 0x0400, - 0x0001, 0xbd88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, - 0x0000, 0xb012, 0x001b, 0x883d, 0x0003, 0x06fd, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0000, 0xa4ff, 0x0003, 0x688d, 0x0011, 0xffa8, - 0x0010, 0x0005, 0x000b, 0x288d, 0x0005, 0x0031, 0x0011, 0x1b6d, - 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x884a, 0x0002, 0xb200, - 0x0010, 0xffb2, 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, - 0x0010, 0xb20a, 0x001b, 0x8851, 0x0015, 0x000f, 0x0000, 0x0001, - 0x0000, 0x1213, 0x0005, 0x0010, 0x0000, 0x8000, 0x0015, 0x00a3, - 0x0000, 0x0200, 0x0000, 0xc697, 0x0005, 0x0046, 0x0000, 0x0002, - 0x0015, 0x00a5, 0x0000, 0x0010, 0x0011, 0xc4d8, 0x0000, 0x3200, - 0x0010, 0xff88, 0x0000, 0xc589, 0x0010, 0xc48a, 0x0010, 0xc58b, - 0x0010, 0xc08e, 0x0005, 0x008c, 0x0010, 0xe109, 0x0010, 0xc08d, - 0x0015, 0x0090, 0x0001, 0x1b56, 0x0005, 0x0091, 0x0010, 0xffff, - 0x0000, 0xb292, 0x0000, 0xb393, 0x0015, 0x009a, 0x0010, 0x0056, - 0x0005, 0x009b, 0x0010, 0x95f5, 0x0012, 0xd042, 0x0003, 0x1880, - 0x0005, 0x00b0, 0x0010, 0x8080, 0x0011, 0x1388, 0x0010, 0x0011, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x887b, - 0x0015, 0x00b8, 0x0010, 0x000c, 0x0014, 0x091f, 0x0003, 0x0882, - 0x0005, 0x0075, 0x0010, 0x8092, 0x0015, 0x00b1, 0x0010, 0x07d0, - 0x0005, 0x00b0, 0x0010, 0x0009, 0x0001, 0xbd88, 0x0000, 0x000b, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x888b, - 0x0003, 0x06fd, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0001, 0x1288, + 0x0003, 0xb298, 0x0005, 0x002a, 0x0000, 0x0001, 0x0012, 0x1500, + 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580, 0x0000, 0xff16, + 0x000b, 0x22a3, 0x0002, 0x1700, 0x0013, 0x02a4, 0x0010, 0x17ff, + 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10, 0x0010, 0xff1e, + 0x0003, 0x62d1, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0010, 0xc030, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82af, + 0x0010, 0xb0fe, 0x000b, 0x62d0, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82b7, + 0x0010, 0xb0fe, 0x001b, 0x62bd, 0x0005, 0x00ce, 0x0010, 0x0005, + 0x0003, 0x08e7, 0x0010, 0xb01c, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82c3, + 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f, 0x0010, 0xc030, + 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x82cc, 0x0000, 0xb01d, 0x0010, 0x1dff, 0x0013, 0x02ab, + 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41, 0x0003, 0x12da, + 0x0013, 0xb2d4, 0x0005, 0x002a, 0x0000, 0x0004, 0x0005, 0x0015, + 0x0010, 0x0000, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, 0x001b, 0x82df, + 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x0925, 0x0000, 0x13b8, + 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0013, 0x0039, + 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10, 0x0010, 0xff1d, + 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x82f0, 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0000, 0x1cff, + 0x0001, 0x1ae0, 0x0013, 0x12ff, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82fb, + 0x0010, 0xb0fe, 0x001b, 0x62ff, 0x0000, 0x1aff, 0x0000, 0xff1c, + 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, + 0x0000, 0xb009, 0x001b, 0x8305, 0x0001, 0xb0c8, 0x0010, 0x000f, + 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d, 0x0010, 0xc030, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x830f, + 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0005, 0x00ce, 0x0010, 0x0006, + 0x0003, 0x08e7, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0010, 0x79b0, + 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039, 0x0015, 0x00d1, + 0x0010, 0x0101, 0x0013, 0x931d, 0x0005, 0x0079, 0x0000, 0x0002, + 0x0003, 0x9320, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0010, 0x13fe, + 0x0013, 0x6371, 0x0012, 0xb04e, 0x001b, 0x139a, 0x0000, 0x78b0, + 0x0002, 0xb045, 0x0003, 0x13a0, 0x0012, 0x784a, 0x0003, 0x13a0, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800, 0x001b, 0x13a0, + 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x133c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0x8f0a, 0x001b, 0x833a, 0x0013, 0x03a6, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1347, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x000b, 0x8345, 0x0013, 0x03a6, 0x0001, 0x0fe8, + 0x0010, 0x0000, 0x0003, 0x134e, 0x0005, 0x00ce, 0x0000, 0x0007, + 0x0010, 0x0fcf, 0x0003, 0x08e1, 0x0002, 0xd142, 0x0013, 0x1367, + 0x0015, 0x00d1, 0x0000, 0x0400, 0x0011, 0x13e8, 0x0001, 0x1b56, + 0x000b, 0x1367, 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033, + 0x0010, 0xb409, 0x001b, 0x8359, 0x0002, 0xb400, 0x0010, 0xffb4, + 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb40a, + 0x001b, 0x8360, 0x0012, 0xd042, 0x0003, 0x1371, 0x0015, 0x00b8, + 0x0000, 0x000d, 0x0014, 0x0925, 0x0003, 0x0054, 0x0000, 0x13b8, + 0x0002, 0x1045, 0x0003, 0x136f, 0x0012, 0x103f, 0x0002, 0xff27, + 0x0014, 0x03c2, 0x0014, 0x0925, 0x0013, 0x0371, 0x0012, 0x103f, + 0x0014, 0x03c2, 0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, + 0x0013, 0x137a, 0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, + 0x0000, 0x0008, 0x0014, 0x0925, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0010, 0x000c, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x001b, 0x8381, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x000b, 0x8385, 0x0010, 0xc014, 0x0000, 0xc013, + 0x0000, 0xc010, 0x0000, 0xa4ff, 0x0003, 0x6392, 0x0011, 0xffa8, + 0x0010, 0x0005, 0x000b, 0x2392, 0x0015, 0x00d1, 0x0010, 0x0404, + 0x0015, 0x003a, 0x0000, 0x8000, 0x0002, 0x3a47, 0x0003, 0x1399, + 0x0015, 0x003a, 0x0000, 0x8000, 0x0015, 0x003a, 0x0010, 0x4040, + 0x0004, 0x08ec, 0x0013, 0x0039, 0x0015, 0x00b8, 0x0010, 0x0003, + 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x0925, 0x0003, 0x0389, + 0x0015, 0x00b8, 0x0000, 0x0002, 0x0015, 0x003a, 0x0010, 0x0202, + 0x0014, 0x0925, 0x0003, 0x0389, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x83ad, 0x0011, 0x1388, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x83b3, + 0x0010, 0xb0fe, 0x0013, 0x63b8, 0x0000, 0xb012, 0x0003, 0x03ba, + 0x0010, 0xc012, 0x0010, 0xc011, 0x0012, 0x104b, 0x0003, 0x134e, + 0x0002, 0x103b, 0x0010, 0xff03, 0x0005, 0x0002, 0x0010, 0x0000, + 0x0000, 0xc00d, 0x0013, 0x034e, 0x0000, 0xffb0, 0x0010, 0xc3b1, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xb888, 0x0010, 0x0011, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x83cb, + 0x0017, 0x4000, 0x0002, 0xd142, 0x001b, 0x1485, 0x0012, 0x3a43, + 0x0003, 0x13de, 0x0015, 0x003a, 0x0000, 0x0800, 0x0010, 0x0db0, + 0x0013, 0x63de, 0x0000, 0x0bff, 0x0001, 0xb0e0, 0x0003, 0x1407, + 0x0010, 0x09ff, 0x0001, 0xb0e0, 0x0003, 0x13eb, 0x0010, 0x05ff, + 0x0001, 0xb0e0, 0x0003, 0x13e2, 0x0000, 0xc00e, 0x0000, 0x05fe, + 0x0013, 0x63e8, 0x0000, 0x050d, 0x0005, 0x0002, 0x0000, 0x0004, + 0x0014, 0x046c, 0x0002, 0x3a47, 0x001b, 0x146b, 0x0013, 0x0402, + 0x0000, 0x09fe, 0x0013, 0x6404, 0x0000, 0x090d, 0x0005, 0x0002, + 0x0000, 0x0001, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x001b, 0x83f5, 0x0011, 0x03c8, 0x0010, 0x000f, + 0x0000, 0xffb6, 0x0011, 0xb6e8, 0x0000, 0x0001, 0x0003, 0x153f, + 0x0011, 0xb6e8, 0x0000, 0x0002, 0x0013, 0x1561, 0x0011, 0xb6e8, + 0x0010, 0x0003, 0x0003, 0x1653, 0x0004, 0x08ec, 0x0013, 0x046b, + 0x0010, 0x0bfe, 0x0013, 0x646b, 0x0010, 0x0b0d, 0x0005, 0x0002, + 0x0000, 0x0002, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x000b, 0x8411, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0010, 0x0021, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8417, + 0x0001, 0xb0a8, 0x0000, 0x199a, 0x0013, 0x241d, 0x0005, 0x00b0, + 0x0000, 0x1999, 0x0012, 0xb050, 0x0000, 0xffb0, 0x0002, 0xff50, + 0x0002, 0xff50, 0x0001, 0xb080, 0x0000, 0xffb0, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0006, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x842a, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x8430, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0001, 0xffe8, + 0x0010, 0x0048, 0x000b, 0x14a9, 0x0005, 0x0002, 0x0010, 0x0006, + 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb109, 0x000b, 0x8441, 0x0000, 0xb10b, 0x000b, 0x6445, + 0x0010, 0xb10a, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8447, + 0x0002, 0x032b, 0x0010, 0xff03, 0x0011, 0x0d88, 0x0010, 0x0011, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x030a, 0x001b, 0x844f, + 0x0000, 0x11fe, 0x000b, 0x6454, 0x0000, 0x0d12, 0x0013, 0x045d, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0010, 0x0db0, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x000b, 0x845c, 0x0000, 0x0d11, 0x0013, 0x046b, 0x0002, 0xd142, + 0x0003, 0x1462, 0x0013, 0x0485, 0x0000, 0x05fe, 0x0013, 0x646b, + 0x0005, 0x0002, 0x0000, 0x0004, 0x0000, 0x050d, 0x0014, 0x046c, + 0x0002, 0x3a47, 0x001b, 0x146b, 0x0004, 0x08ec, 0x0013, 0x0047, + 0x0001, 0xc7c8, 0x0010, 0x0028, 0x000b, 0x1484, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x000a, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8476, 0x0002, 0xb04f, + 0x0013, 0x1484, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x1482, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0013, 0x1482, 0x0015, 0x003a, + 0x0010, 0x8080, 0x0003, 0x0484, 0x0015, 0x003a, 0x0010, 0x4040, + 0x0017, 0x4000, 0x0000, 0x12fe, 0x001b, 0x604f, 0x0015, 0x0012, + 0x0001, 0x1b56, 0x0015, 0x0011, 0x0001, 0x1b56, 0x0001, 0x1288, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x000b, 0x8490, 0x0005, 0x00b0, 0x0000, 0x8000, 0x0001, 0x1288, + 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x001b, 0x8498, 0x0003, 0x004f, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0x0309, 0x001b, 0x84a1, 0x0011, 0x0d88, 0x0010, 0x0005, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb909, 0x001b, 0x84a7, + 0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0600, 0x0014, 0x0683, + 0x0004, 0x051b, 0x0000, 0xb05a, 0x0000, 0xb15b, 0x0005, 0x0054, + 0x0010, 0x0829, 0x0010, 0x0d58, 0x0015, 0x0059, 0x0010, 0xffff, + 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x001e, 0x0015, 0x0033, + 0x0000, 0xb009, 0x001b, 0x84b9, 0x0000, 0xb05c, 0x0005, 0x0031, + 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84bf, + 0x0001, 0xb0c8, 0x0010, 0x000f, 0x000b, 0x14c6, 0x0015, 0x00ff, + 0x0010, 0x0005, 0x0013, 0x04ce, 0x0002, 0xb040, 0x0003, 0x14cb, + 0x0015, 0x00ff, 0x0000, 0x0004, 0x0013, 0x04ce, 0x0001, 0xb0c8, + 0x0010, 0x0006, 0x0002, 0xff60, 0x0010, 0xffb2, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0019, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x84d6, 0x0012, 0xb170, + 0x0011, 0xffc8, 0x0010, 0xff00, 0x0011, 0xb2d0, 0x0010, 0xff60, + 0x0002, 0xb045, 0x0013, 0x14e1, 0x0015, 0x00b2, 0x0000, 0x0002, + 0x0003, 0x04eb, 0x0002, 0xb046, 0x0003, 0x14e6, 0x0015, 0x00b2, + 0x0000, 0x0001, 0x0003, 0x04eb, 0x0015, 0x00b2, 0x0010, 0x0000, + 0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0013, 0x04f1, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011, + 0x000b, 0x84f0, 0x0010, 0xb16a, 0x0010, 0xb06b, 0x0000, 0xb261, + 0x0015, 0x0044, 0x0010, 0x0018, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0x6241, 0x001b, 0x84fb, + 0x0003, 0x94fc, 0x0015, 0x00a0, 0x0000, 0x0020, 0x0012, 0xd041, + 0x000b, 0x14ff, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9503, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8, + 0x0010, 0x0009, 0x0013, 0x9509, 0x0000, 0xff75, 0x0003, 0x950b, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x00b1, + 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0033, + 0x0000, 0xb012, 0x000b, 0x8519, 0x0013, 0x046b, 0x0000, 0xba30, + 0x0005, 0x0031, 0x0010, 0x0035, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x8520, 0x0002, 0xb040, 0x0003, 0x153c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0005, 0x0031, 0x0001, 0x1b72, 0x0015, 0x0033, + 0x0000, 0xb011, 0x000b, 0x8529, 0x0002, 0xb100, 0x0010, 0xffb1, + 0x001b, 0x2530, 0x0012, 0xb000, 0x0000, 0xffb0, 0x0013, 0x252a, + 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8532, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0013, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x853a, 0x0003, 0x053e, + 0x0010, 0xc0b1, 0x0000, 0xc0b0, 0x0017, 0x4000, 0x0005, 0x00b6, + 0x0010, 0x0500, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0889, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x854b, + 0x0010, 0xb058, 0x0000, 0x0d59, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x8553, + 0x0010, 0xb15c, 0x0010, 0xb05d, 0x0005, 0x0031, 0x0010, 0x002b, + 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x855a, 0x0000, 0xb15e, + 0x0000, 0xb05f, 0x0003, 0x955d, 0x0015, 0x00a0, 0x0010, 0x000c, + 0x0003, 0x0668, 0x0005, 0x00b6, 0x0000, 0x0700, 0x0014, 0x0683, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb709, 0x000b, 0x856b, + 0x0012, 0xb749, 0x0003, 0x1571, 0x0005, 0x0054, 0x0010, 0x0889, + 0x0003, 0x0573, 0x0005, 0x0054, 0x0010, 0x0898, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x857a, 0x0010, 0xb058, + 0x0000, 0x0d59, 0x0001, 0xb9c8, 0x0010, 0xf000, 0x0001, 0xffe8, + 0x0010, 0xf000, 0x001b, 0x15a3, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x8589, 0x0001, 0xb0c8, 0x0000, 0xf700, + 0x0000, 0xffb0, 0x0011, 0xb0e8, 0x0000, 0xf100, 0x0013, 0x15ea, + 0x0011, 0xb0e8, 0x0000, 0xf200, 0x0013, 0x15ef, 0x0011, 0xb0e8, + 0x0010, 0xf300, 0x0003, 0x1614, 0x0011, 0xb0e8, 0x0000, 0xf400, + 0x0013, 0x1619, 0x0011, 0xb0e8, 0x0010, 0xf500, 0x0013, 0x15ea, + 0x0011, 0xb0e8, 0x0010, 0xf600, 0x0003, 0x162b, 0x0005, 0x00ce, + 0x0010, 0x0009, 0x0000, 0xb0cf, 0x0003, 0x08e1, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0000, 0x0025, 0x0015, 0x0033, 0x0000, 0xb039, + 0x000b, 0x85a8, 0x0012, 0xb749, 0x0013, 0x15ad, 0x0002, 0xb52c, + 0x0000, 0xffb5, 0x0000, 0xb162, 0x0000, 0xb063, 0x0005, 0x0031, + 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x85b3, + 0x0001, 0xb3c8, 0x0010, 0x0003, 0x0003, 0x15bb, 0x0010, 0xffb2, + 0x0001, 0xffe8, 0x0010, 0x0003, 0x001b, 0x15bd, 0x0000, 0xc2b7, + 0x0013, 0x0647, 0x0001, 0xb2e8, 0x0000, 0x0001, 0x0013, 0x15c4, + 0x0005, 0x00ce, 0x0010, 0x000a, 0x0010, 0xb2cf, 0x0003, 0x08e1, + 0x0010, 0xb465, 0x0010, 0xb667, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0001, 0xb5c8, 0x0010, 0x0300, 0x0013, 0x15e9, 0x0012, 0xb548, + 0x0013, 0x15d0, 0x0000, 0xb6ff, 0x0011, 0xb780, 0x0010, 0xffb7, + 0x0002, 0xb549, 0x0013, 0x15d5, 0x0010, 0xb4ff, 0x0011, 0xb780, + 0x0010, 0xffb7, 0x0015, 0x0044, 0x0010, 0x0018, 0x0005, 0x0031, + 0x0000, 0x002c, 0x0015, 0x0033, 0x0000, 0x6841, 0x001b, 0x85db, + 0x0015, 0x0044, 0x0000, 0x0019, 0x0005, 0x0031, 0x0000, 0x0034, + 0x0015, 0x0033, 0x0000, 0x5029, 0x001b, 0x85e2, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0011, 0xb7c8, 0x0010, 0x0003, 0x0013, 0x15e9, + 0x0010, 0xff55, 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0008, + 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x000b, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x85f6, 0x0010, 0xb1ff, + 0x0001, 0xb0d0, 0x0003, 0x15ff, 0x0005, 0x00b5, 0x0010, 0x0b02, + 0x0010, 0xb062, 0x0010, 0xb163, 0x0003, 0x0601, 0x0005, 0x00b5, + 0x0000, 0x0302, 0x0015, 0x0065, 0x0010, 0x0012, 0x0005, 0x0067, + 0x0000, 0x0008, 0x0015, 0x006c, 0x0000, 0x7000, 0x0005, 0x006d, + 0x0010, 0x0500, 0x0015, 0x006f, 0x0010, 0x000a, 0x0015, 0x0044, + 0x0000, 0x0001, 0x0005, 0x0052, 0x0000, 0x2500, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0015, 0x00b7, 0x0000, 0x0032, 0x0013, 0x0647, + 0x0005, 0x00b5, 0x0010, 0x0028, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0100, 0x0005, 0x0067, + 0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x001b, 0x8624, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0010, 0xff69, + 0x0015, 0x00b7, 0x0000, 0x0020, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb609, 0x000b, 0x8632, 0x0001, 0xb6c8, + 0x0010, 0xff00, 0x0000, 0xffb0, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x000b, 0x8638, 0x0001, 0xb6c8, 0x0010, 0x00ff, 0x0012, 0xff10, + 0x001b, 0x1641, 0x0000, 0xffb5, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0013, 0x0647, 0x0010, 0xff63, 0x0005, 0x00b5, 0x0000, 0x0800, + 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x864e, 0x0010, 0xb561, + 0x0013, 0x9650, 0x0010, 0xb7a0, 0x0003, 0x0668, 0x0005, 0x00b6, + 0x0010, 0x0300, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0819, + 0x0010, 0x0d58, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x001b, 0x8660, 0x0000, 0xb059, 0x0003, 0x9662, 0x0010, 0xc0a0, + 0x0010, 0x71ff, 0x0002, 0xff28, 0x0010, 0xff71, 0x0003, 0x0668, + 0x0012, 0xd041, 0x000b, 0x1668, 0x0015, 0x00d1, 0x0010, 0x0202, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8, + 0x0010, 0x0009, 0x0013, 0x9671, 0x0000, 0xff75, 0x0003, 0x9673, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0005, 0x00b0, + 0x0010, 0x0009, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0015, 0x0033, + 0x0000, 0xb012, 0x001b, 0x8681, 0x0013, 0x046b, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0005, 0x0098, 0x0010, 0x0056, 0x0015, 0x0099, + 0x0000, 0x9575, 0x0004, 0x08a8, 0x0000, 0xb096, 0x0012, 0xb270, + 0x0010, 0xff56, 0x0014, 0x08ca, 0x0010, 0xb052, 0x0010, 0xb153, + 0x0000, 0xb6ff, 0x0011, 0xb2d0, 0x0010, 0xff50, 0x0010, 0xb351, + 0x0017, 0x4000, 0x0001, 0x12e8, 0x0001, 0x1b56, 0x0003, 0x1845, + 0x0015, 0x00d1, 0x0000, 0x0400, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0x1009, 0x000b, 0x86a1, 0x0015, 0x000f, 0x0000, 0x0001, + 0x0010, 0xc014, 0x0000, 0x1213, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x000b, 0x86ad, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0x1a09, 0x000b, 0x86b5, 0x0012, 0x104b, 0x001b, 0x16be, + 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000b, 0x0015, 0x0033, + 0x0000, 0x1621, 0x001b, 0x86bd, 0x0010, 0x15fe, 0x000b, 0x66dd, + 0x0004, 0x0704, 0x0002, 0x3a42, 0x000b, 0x1703, 0x0001, 0x10c8, + 0x0010, 0x000f, 0x000b, 0x1766, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x86cd, 0x0011, 0xb0e8, 0x0010, 0x0009, + 0x0003, 0x16d4, 0x0011, 0xb0e8, 0x0000, 0x0001, 0x001b, 0x1702, + 0x0011, 0x1388, 0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x86d9, 0x0002, 0xb04f, 0x001b, 0x16f9, + 0x0013, 0x0702, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, - 0x001b, 0x8894, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x889a, 0x0010, 0xb0fe, - 0x0003, 0x689f, 0x0000, 0xb012, 0x0003, 0x06fd, 0x0010, 0xc012, - 0x0010, 0xc011, 0x0003, 0x06fd, 0x0000, 0xba30, 0x0005, 0x0031, - 0x0010, 0x0021, 0x0015, 0x0033, 0x0010, 0xb019, 0x001b, 0x88a7, - 0x0002, 0xb200, 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb2, - 0x0010, 0xb2b7, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, - 0x0010, 0xb20a, 0x000b, 0x88b1, 0x0017, 0x4000, 0x0000, 0xba30, - 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb409, - 0x000b, 0x88b8, 0x0002, 0xb400, 0x0011, 0xffc8, 0x0010, 0x00ff, - 0x0010, 0xffb4, 0x0010, 0xb4b7, 0x0005, 0x0031, 0x0000, 0x0023, - 0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x88c2, 0x0017, 0x4000, - 0x0000, 0xba30, 0x0001, 0xc7c8, 0x0000, 0x0020, 0x001b, 0x18d0, - 0x0005, 0x0031, 0x0010, 0x0028, 0x0015, 0x0033, 0x0010, 0xb209, - 0x000b, 0x88cc, 0x0011, 0xb2c8, 0x0000, 0xff80, 0x0003, 0x18d3, - 0x0010, 0xc4b0, 0x0010, 0xc5b1, 0x0013, 0x08d5, 0x0010, 0xc6b1, - 0x0000, 0xc0b0, 0x0005, 0x0031, 0x0000, 0x0004, 0x0015, 0x0033, - 0x0010, 0xb211, 0x001b, 0x88d9, 0x0017, 0x4000, 0x0015, 0x00b8, - 0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0014, 0x091f, - 0x0013, 0x002d, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a, - 0x0010, 0x0707, 0x0003, 0x091f, 0x0004, 0x0119, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, - 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x88ee, 0x0004, 0x08a2, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0010, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x88f7, - 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x000b, 0x88ff, - 0x0002, 0x0327, 0x0010, 0xffb2, 0x0011, 0x0d88, 0x0010, 0x0011, - 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x8907, - 0x0015, 0x00b8, 0x0010, 0x0006, 0x0003, 0x091f, 0x0014, 0x012b, - 0x0004, 0x08a2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, - 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, - 0x001b, 0x8914, 0x0012, 0x1027, 0x0010, 0xffb2, 0x0011, 0x1388, - 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, - 0x000b, 0x891c, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0013, 0x491f, - 0x0000, 0xb838, 0x0017, 0x4000, 0x9aec, 0x3b6c + 0x001b, 0x86e4, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x86e7, + 0x0010, 0xb0fe, 0x0003, 0x66ec, 0x0000, 0xb012, 0x0013, 0x06ee, + 0x0010, 0xc012, 0x0010, 0xc011, 0x0015, 0x000f, 0x0010, 0x0000, + 0x0002, 0x3944, 0x0013, 0x16f7, 0x0015, 0x0039, 0x0000, 0x5040, + 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0000, 0xc013, + 0x0003, 0x0703, 0x0010, 0x02fe, 0x0003, 0x66fe, 0x0015, 0x003a, + 0x0010, 0x2020, 0x0003, 0x0703, 0x0015, 0x003a, 0x0000, 0x2000, + 0x0015, 0x003a, 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x0054, + 0x0003, 0xb704, 0x0005, 0x002a, 0x0000, 0x0004, 0x0000, 0xba30, + 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x870c, 0x0000, 0xc02c, 0x0000, 0xb02d, 0x0012, 0x104b, + 0x0013, 0x1727, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0023, + 0x0015, 0x0033, 0x0000, 0xb129, 0x001b, 0x8716, 0x0000, 0xb120, + 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, + 0x0000, 0xc025, 0x0010, 0xb526, 0x0010, 0xc027, 0x0010, 0xb516, + 0x0010, 0xc017, 0x0000, 0xb518, 0x0000, 0xc019, 0x0010, 0xc028, + 0x0000, 0xc029, 0x0010, 0xc01e, 0x0013, 0x075d, 0x0012, 0x1044, + 0x0003, 0x1757, 0x0002, 0x1034, 0x0000, 0xff10, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b29, + 0x000b, 0x8730, 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033, + 0x0000, 0xb131, 0x000b, 0x8735, 0x0002, 0x1f43, 0x000b, 0x173c, + 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0000, 0xc0b3, 0x0010, 0xc0b4, + 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423, + 0x0000, 0xb524, 0x0010, 0xb625, 0x0010, 0xb516, 0x0000, 0xb617, + 0x0000, 0x1826, 0x0000, 0x1927, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x874b, + 0x0000, 0xb028, 0x0000, 0xb129, 0x0012, 0x1e10, 0x0010, 0xff1e, + 0x0013, 0x675d, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0004, 0x02ab, + 0x0002, 0x3a42, 0x0003, 0x175d, 0x0003, 0x0765, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b79, + 0x000b, 0x875c, 0x0003, 0xb75d, 0x0005, 0x002a, 0x0000, 0x0001, + 0x0005, 0x0015, 0x0000, 0x0001, 0x0000, 0x1efe, 0x0003, 0x6765, + 0x0003, 0x0277, 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031, + 0x0010, 0x001b, 0x0015, 0x0033, 0x0010, 0xb051, 0x001b, 0x876b, + 0x0000, 0xb0a3, 0x0010, 0xb697, 0x0010, 0xb946, 0x0015, 0x00a5, + 0x0000, 0x0010, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, + 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb509, + 0x000b, 0x8778, 0x0014, 0x08ca, 0x0004, 0x08b9, 0x0012, 0xb470, + 0x0010, 0xffb4, 0x0010, 0xb48e, 0x0010, 0xb08a, 0x0010, 0xb18b, + 0x0012, 0x104d, 0x0003, 0x1783, 0x0013, 0x07b0, 0x0012, 0x104b, + 0x0013, 0x1796, 0x0005, 0x008c, 0x0010, 0x0829, 0x0010, 0xc08d, + 0x0001, 0xb2d8, 0x0010, 0x0600, 0x0010, 0xff88, 0x0010, 0xb389, + 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0010, 0x1ab9, + 0x0004, 0x051b, 0x0013, 0x9791, 0x0010, 0xb092, 0x0010, 0xb193, + 0x0013, 0x9794, 0x0013, 0x07ab, 0x0005, 0x008c, 0x0000, 0x0809, + 0x0015, 0x008d, 0x0000, 0x0008, 0x0001, 0xb2d8, 0x0000, 0x0100, + 0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591, + 0x0000, 0xc08f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, + 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x87a6, 0x0013, 0x97a7, + 0x0000, 0xb192, 0x0000, 0xb093, 0x0003, 0x97aa, 0x0010, 0x19a1, + 0x0000, 0x18a2, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0003, 0x0821, + 0x0000, 0xb590, 0x0010, 0x1391, 0x0001, 0x10c8, 0x0010, 0x000f, + 0x0001, 0xffe8, 0x0010, 0x0005, 0x0013, 0x17d7, 0x0001, 0xb2d8, + 0x0000, 0x0700, 0x0010, 0xff88, 0x0010, 0xb389, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87c2, 0x0002, 0xb049, + 0x0013, 0x17ca, 0x0005, 0x008c, 0x0010, 0x0889, 0x0015, 0x00b1, + 0x0010, 0x0096, 0x0013, 0x07ce, 0x0005, 0x008c, 0x0010, 0x0898, + 0x0015, 0x00b1, 0x0000, 0x0092, 0x0010, 0xc08d, 0x0000, 0xc08f, + 0x0013, 0x97d0, 0x0000, 0xc092, 0x0010, 0xc093, 0x0013, 0x97d3, + 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0003, 0x0821, 0x0001, 0xb2d8, + 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389, 0x0005, 0x008c, + 0x0010, 0x0880, 0x0015, 0x008d, 0x0000, 0x0008, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87e6, 0x0010, 0xb08f, + 0x0000, 0xb590, 0x0010, 0x1391, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x000d, 0x0015, 0x0033, 0x0000, 0xb021, 0x001b, 0x87ef, + 0x0003, 0x97f0, 0x0010, 0xb392, 0x0010, 0xb293, 0x0003, 0x97f3, + 0x0000, 0xb1a1, 0x0010, 0xb0a2, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb211, 0x001b, 0x87fd, 0x0000, 0xb3ff, 0x0001, 0xb080, + 0x0000, 0xffb3, 0x001b, 0x2804, 0x0002, 0xb200, 0x0003, 0x0805, + 0x0010, 0xb2ff, 0x0011, 0xb180, 0x0010, 0xffb2, 0x0011, 0x1388, + 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb212, + 0x000b, 0x880c, 0x0015, 0x00b1, 0x0000, 0x0092, 0x0002, 0x104c, + 0x0003, 0x181f, 0x0011, 0xc2e8, 0x0010, 0x000c, 0x000b, 0x1817, + 0x0015, 0x00ff, 0x0000, 0x0800, 0x0013, 0x081f, 0x0011, 0xc2e8, + 0x0000, 0x0020, 0x000b, 0x181d, 0x0015, 0x00ff, 0x0010, 0x1800, + 0x0013, 0x081f, 0x0015, 0x00ff, 0x0000, 0x1000, 0x0011, 0xb1d0, + 0x0010, 0xffb1, 0x0015, 0x009a, 0x0010, 0x0036, 0x0005, 0x009b, + 0x0000, 0x95d5, 0x0012, 0xd041, 0x001b, 0x1825, 0x0015, 0x00d1, + 0x0010, 0x0202, 0x0013, 0x9829, 0x0012, 0x104e, 0x0013, 0x182e, + 0x0012, 0xb12f, 0x0010, 0xffb1, 0x0000, 0xb175, 0x0013, 0x982f, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0001, 0x19c8, 0x0010, 0xfff0, + 0x001b, 0x1838, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0003, 0x083a, + 0x0015, 0x00b1, 0x0000, 0x1b58, 0x0005, 0x00b0, 0x0010, 0x0009, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x000b, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x8843, + 0x0003, 0x0703, 0x0015, 0x0030, 0x0000, 0x0400, 0x0000, 0xa4ff, + 0x0003, 0x6893, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x2893, + 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb211, + 0x000b, 0x8850, 0x0002, 0xb200, 0x0010, 0xffb2, 0x0005, 0x0031, + 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8857, + 0x0015, 0x000f, 0x0000, 0x0001, 0x0000, 0x1213, 0x0005, 0x0010, + 0x0000, 0x8000, 0x0015, 0x00a3, 0x0000, 0x0200, 0x0000, 0xc697, + 0x0005, 0x0046, 0x0000, 0x0002, 0x0015, 0x00a5, 0x0000, 0x0010, + 0x0011, 0xc4d8, 0x0000, 0x3200, 0x0010, 0xff88, 0x0000, 0xc589, + 0x0010, 0xc48a, 0x0010, 0xc58b, 0x0010, 0xc08e, 0x0005, 0x008c, + 0x0010, 0xe109, 0x0010, 0xc08d, 0x0015, 0x0090, 0x0001, 0x1b56, + 0x0005, 0x0091, 0x0010, 0xffff, 0x0000, 0xb292, 0x0000, 0xb393, + 0x0015, 0x009a, 0x0010, 0x0056, 0x0005, 0x009b, 0x0010, 0x95f5, + 0x0012, 0xd042, 0x0003, 0x1886, 0x0005, 0x00b0, 0x0010, 0x8080, + 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb00a, 0x000b, 0x8881, 0x0015, 0x00b8, 0x0010, 0x000c, + 0x0014, 0x0925, 0x0003, 0x0888, 0x0005, 0x0075, 0x0010, 0x8092, + 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009, + 0x0001, 0xbd88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb012, 0x001b, 0x8891, 0x0003, 0x0703, 0x0015, 0x00d1, + 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x889a, 0x0001, 0x1288, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x000b, 0x88a0, 0x0010, 0xb0fe, 0x0003, 0x68a5, 0x0000, 0xb012, + 0x0003, 0x0703, 0x0010, 0xc012, 0x0010, 0xc011, 0x0003, 0x0703, + 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033, + 0x0010, 0xb019, 0x001b, 0x88ad, 0x0002, 0xb200, 0x0011, 0xffc8, + 0x0010, 0x00ff, 0x0010, 0xffb2, 0x0010, 0xb2b7, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x88b7, + 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031, 0x0000, 0x0023, + 0x0015, 0x0033, 0x0010, 0xb409, 0x000b, 0x88be, 0x0002, 0xb400, + 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb4, 0x0010, 0xb4b7, + 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb40a, + 0x001b, 0x88c8, 0x0017, 0x4000, 0x0000, 0xba30, 0x0001, 0xc7c8, + 0x0000, 0x0020, 0x001b, 0x18d6, 0x0005, 0x0031, 0x0010, 0x0028, + 0x0015, 0x0033, 0x0010, 0xb209, 0x000b, 0x88d2, 0x0011, 0xb2c8, + 0x0000, 0xff80, 0x0003, 0x18d9, 0x0010, 0xc4b0, 0x0010, 0xc5b1, + 0x0003, 0x08db, 0x0010, 0xc6b1, 0x0000, 0xc0b0, 0x0005, 0x0031, + 0x0000, 0x0004, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x88df, + 0x0017, 0x4000, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a, + 0x0010, 0x0707, 0x0014, 0x0925, 0x0013, 0x002d, 0x0015, 0x00b8, + 0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0003, 0x0925, + 0x0004, 0x011c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, + 0x001b, 0x88f4, 0x0004, 0x08a8, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb20a, 0x001b, 0x88fd, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0x0309, 0x001b, 0x8905, 0x0002, 0x0327, 0x0010, 0xffb2, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb20a, 0x000b, 0x890d, 0x0015, 0x00b8, 0x0010, 0x0006, + 0x0003, 0x0925, 0x0014, 0x012e, 0x0004, 0x08a8, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0010, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x891a, 0x0012, 0x1027, + 0x0010, 0xffb2, 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8922, 0x0015, 0x00b8, + 0x0000, 0x0007, 0x0013, 0x4925, 0x0000, 0xb838, 0x0017, 0x4000, + 0x9a6c, 0xaf33 }; -unsigned short xseqipx_code_length01 = 0x1246; +unsigned short xseqipx_code_length01 = 0x1252; diff --git a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c index 1f8744ad9cde..5bb837052ef1 100644 --- a/drivers/scsi/qla2xxx/ql6312_fw.c +++ b/drivers/scsi/qla2xxx/ql6312_fw.c @@ -6,7 +6,7 @@ */ /* - * Firmware Version 3.03.15 (10:00 May 26, 2005) + * Firmware Version 3.03.18 (12:07 Sep 20, 2005) */ #ifdef UNIQUE_FW_NAME @@ -16,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw2300flx_version_str[] = {3, 3,15}; +unsigned char fw2300flx_version_str[] = {3, 3,18}; #else -unsigned char firmware_version[] = {3, 3,15}; +unsigned char firmware_version[] = {3, 3,18}; #endif #ifdef UNIQUE_FW_NAME -#define fw2300flx_VERSION_STRING "3.03.15" +#define fw2300flx_VERSION_STRING "3.03.18" #else -#define FW_VERSION_STRING "3.03.15" +#define FW_VERSION_STRING "3.03.18" #endif #ifdef UNIQUE_FW_NAME @@ -38,12 +38,12 @@ unsigned short fw2300flx_code01[] = { #else unsigned short risc_code01[] = { #endif - 0x0470, 0x0000, 0x0000, 0xdb56, 0x0000, 0x0003, 0x0003, 0x000f, + 0x0470, 0x0000, 0x0000, 0xdbb7, 0x0000, 0x0003, 0x0003, 0x0012, 0x0317, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, @@ -52,8 +52,8 @@ unsigned short risc_code01[] = { 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78, - 0x7883, 0x0004, 0x2089, 0x2c1f, 0x2051, 0x1800, 0x2a70, 0x20e1, - 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e87, 0x2029, + 0x7883, 0x0004, 0x2089, 0x2c06, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e7b, 0x2029, 0x2480, 0x2031, 0xffff, 0x2039, 0x2450, 0x2021, 0x0050, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, 0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff, @@ -65,7002 +65,7014 @@ unsigned short risc_code01[] = { 0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, - 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f5b, 0x080c, - 0x5e3e, 0x080c, 0x9f6b, 0x080c, 0x1112, 0x080c, 0x130a, 0x080c, - 0x1a79, 0x080c, 0x0d94, 0x080c, 0x1097, 0x080c, 0x3309, 0x080c, - 0x748f, 0x080c, 0x6785, 0x080c, 0x8195, 0x080c, 0x22b7, 0x080c, - 0x84a6, 0x080c, 0x7b19, 0x080c, 0x20e3, 0x080c, 0x2217, 0x080c, - 0x22ac, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880, + 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f4f, 0x080c, + 0x5e3d, 0x080c, 0x9f80, 0x080c, 0x1106, 0x080c, 0x12fe, 0x080c, + 0x1a75, 0x080c, 0x0d88, 0x080c, 0x108b, 0x080c, 0x32f3, 0x080c, + 0x748e, 0x080c, 0x6784, 0x080c, 0x8194, 0x080c, 0x22b3, 0x080c, + 0x84a5, 0x080c, 0x7b18, 0x080c, 0x20df, 0x080c, 0x2213, 0x080c, + 0x22a8, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0911, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x7003, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, - 0x4add, 0x080c, 0x3330, 0x080c, 0x74f7, 0x080c, 0x6c83, 0x080c, - 0x81be, 0x080c, 0x2b2c, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941, - 0x0ad8, 0x093e, 0x0b8f, 0x0d93, 0x0d93, 0x0d93, 0x080c, 0x0e02, + 0x4adc, 0x080c, 0x331a, 0x080c, 0x74f6, 0x080c, 0x6c82, 0x080c, + 0x81bd, 0x080c, 0x2b13, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941, + 0x0ad8, 0x093e, 0x0b8f, 0x0d87, 0x0d87, 0x0d87, 0x080c, 0x0df6, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, - 0x1904, 0x0aab, 0x080c, 0x0ec9, 0x080c, 0x717f, 0x0150, 0x080c, - 0x71a2, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, - 0x0468, 0x080c, 0x709f, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab, - 0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817e, 0x080c, - 0x8170, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, - 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fee, 0x080c, - 0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x2011, 0x5c99, 0x080c, - 0x825a, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5546, - 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c99, - 0x080c, 0x825a, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1, - 0x080c, 0x832e, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, - 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1980, 0x2004, 0x9005, - 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de6, 0x00ce, 0x0804, - 0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7187, 0x0118, 0x9295, + 0x1904, 0x0aab, 0x080c, 0x0ebd, 0x080c, 0x717e, 0x0150, 0x080c, + 0x71a1, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, + 0x0468, 0x080c, 0x709e, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab, + 0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817d, 0x080c, + 0x816f, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, + 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fed, 0x080c, + 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x2011, 0x5c98, 0x080c, + 0x8259, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5545, + 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0, + 0x080c, 0x832d, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, + 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1981, 0x2004, 0x9005, + 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de5, 0x00ce, 0x0804, + 0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7186, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a, 0x2011, 0x8010, 0x73d4, - 0x2001, 0x1981, 0x2003, 0x0001, 0x080c, 0x2989, 0x080c, 0x4a18, + 0x2001, 0x1982, 0x2003, 0x0001, 0x080c, 0x2974, 0x080c, 0x4a17, 0x7244, 0xc284, 0x7246, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, - 0x2102, 0x080c, 0x9803, 0x2011, 0x0004, 0x080c, 0xbd4b, 0x080c, - 0x65c7, 0x080c, 0x717f, 0x1120, 0x080c, 0x29f6, 0x02e0, 0x0400, - 0x080c, 0x5ded, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c, - 0x5713, 0x0804, 0x0aab, 0x080c, 0x54dc, 0xd094, 0x0188, 0x2011, - 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54e0, 0xd0d4, 0x1118, - 0x080c, 0x29f6, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088, - 0x080c, 0x54e0, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, - 0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c2, - 0x0008, 0x2012, 0x080c, 0x6688, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, - 0x00a8, 0x707b, 0x0000, 0x080c, 0x717f, 0x1130, 0x70ac, 0x9005, - 0x1168, 0x080c, 0xc18e, 0x0050, 0x080c, 0xc18e, 0x70d8, 0xd09c, - 0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc3, 0x70e3, 0x0000, - 0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29fe, 0x0228, 0x2011, - 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717f, 0x1178, + 0x2102, 0x080c, 0x9818, 0x2011, 0x0004, 0x080c, 0xbd5e, 0x080c, + 0x65c6, 0x080c, 0x717e, 0x1120, 0x080c, 0x29e1, 0x02e0, 0x0400, + 0x080c, 0x5dec, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c, + 0x5712, 0x0804, 0x0aab, 0x080c, 0x54db, 0xd094, 0x0188, 0x2011, + 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54df, 0xd0d4, 0x1118, + 0x080c, 0x29e1, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088, + 0x080c, 0x54df, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, + 0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c1, + 0x0008, 0x2012, 0x080c, 0x6687, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, + 0x00a8, 0x707b, 0x0000, 0x080c, 0x717e, 0x1130, 0x70ac, 0x9005, + 0x1168, 0x080c, 0xc1a1, 0x0050, 0x080c, 0xc1a1, 0x70d8, 0xd09c, + 0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc2, 0x70e3, 0x0000, + 0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29e9, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717e, 0x1178, 0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1947, 0x211a, 0x001e, 0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019, 0x1947, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108, - 0xc295, 0x72da, 0x080c, 0x717f, 0x0118, 0x9296, 0x0004, 0x0548, - 0x2011, 0x0001, 0x080c, 0xbd4b, 0x70a7, 0x0000, 0x70ab, 0xffff, + 0xc295, 0x72da, 0x080c, 0x717e, 0x0118, 0x9296, 0x0004, 0x0548, + 0x2011, 0x0001, 0x080c, 0xbd5e, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, - 0x0003, 0x782a, 0x00fe, 0x080c, 0x2e8c, 0x2011, 0x0005, 0x080c, - 0x990e, 0x080c, 0x8b90, 0x080c, 0x717f, 0x0148, 0x00c6, 0x2061, + 0x0003, 0x782a, 0x00fe, 0x080c, 0x2e73, 0x2011, 0x0005, 0x080c, + 0x9923, 0x080c, 0x8b8f, 0x080c, 0x717e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, - 0x00fe, 0x2011, 0x0005, 0x080c, 0x990e, 0x080c, 0x8b90, 0x080c, - 0x717f, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002, + 0x00fe, 0x2011, 0x0005, 0x080c, 0x9923, 0x080c, 0x8b8f, 0x080c, + 0x717e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, - 0x080c, 0x717f, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, - 0x080c, 0x717f, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, + 0x080c, 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, + 0x080c, 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, - 0x090c, 0x31a6, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c, + 0x090c, 0x3190, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c, 0x9084, 0x00ff, 0x707e, 0x70af, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, - 0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e8c, 0x080c, - 0x8b90, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540, + 0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e73, 0x080c, + 0x8b8f, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, - 0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3017, - 0x080c, 0x8b90, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001, - 0x080c, 0xc444, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x3051, - 0x080c, 0x8b90, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c, + 0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3001, + 0x080c, 0x8b8f, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001, + 0x080c, 0xc459, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x303b, + 0x080c, 0x8b8f, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c, 0x70a4, 0x9005, 0x1904, 0x0b8c, 0x70d8, 0xd0a4, 0x0118, 0xd0b4, - 0x0904, 0x0b8c, 0x080c, 0x6688, 0x1904, 0x0b8c, 0x080c, 0x66db, - 0x1904, 0x0b8c, 0x080c, 0x66c2, 0x01c0, 0x0156, 0x00c6, 0x20a9, - 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1118, 0xb800, 0xd0ec, + 0x0904, 0x0b8c, 0x080c, 0x6687, 0x1904, 0x0b8c, 0x080c, 0x66da, + 0x1904, 0x0b8c, 0x080c, 0x66c1, 0x01c0, 0x0156, 0x00c6, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b32, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b8c, 0x0006, 0x2001, 0x0103, - 0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fcb, 0x2011, - 0x19a8, 0x080c, 0x0fcb, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, - 0x70ab, 0xffff, 0x080c, 0x0eab, 0x9006, 0x080c, 0x2617, 0x0036, - 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e, - 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a2, 0x0150, 0x080c, - 0x717f, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, + 0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fbf, 0x2011, + 0x19a8, 0x080c, 0x0fbf, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, + 0x70ab, 0xffff, 0x080c, 0x0e9f, 0x9006, 0x080c, 0x2616, 0x0036, + 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e, + 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a1, 0x0150, 0x080c, + 0x717e, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0x19c3, 0x2004, 0x9086, 0x0005, 0x1120, - 0x2011, 0x0000, 0x080c, 0x990e, 0x2011, 0x0000, 0x080c, 0x9918, - 0x080c, 0x8b90, 0x080c, 0x8c6d, 0x012e, 0x00be, 0x0005, 0x0016, + 0x2011, 0x0000, 0x080c, 0x9923, 0x2011, 0x0000, 0x080c, 0x992d, + 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x012e, 0x00be, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904, - 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x7940, + 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1904, 0x0c23, 0x7954, 0xd1ac, - 0x1904, 0x0c23, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518, 0x080c, - 0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001, 0x0001, - 0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006, 0x080c, - 0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8, 0x1d50, - 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b2, - 0x0804, 0x0d3b, 0x080c, 0x7190, 0x0148, 0x080c, 0x71a2, 0x1118, - 0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0, 0x080c, 0x7485, - 0x080c, 0x747b, 0x080c, 0x709f, 0x0058, 0x080c, 0x717f, 0x0140, - 0x2009, 0x00f8, 0x080c, 0x5dac, 0x7843, 0x0090, 0x7843, 0x0010, - 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717f, 0x0138, - 0x7824, 0xd0ac, 0x1904, 0x0d40, 0x1f04, 0x0c02, 0x0070, 0x7824, - 0x080c, 0x7199, 0x0118, 0xd0ac, 0x1904, 0x0d40, 0x9084, 0x1800, - 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d40, 0x2001, 0x0001, 0x080c, - 0x2617, 0x0804, 0x0d62, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518, - 0x080c, 0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001, - 0x0001, 0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006, - 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8, + 0x1904, 0x0c23, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518, 0x080c, + 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001, 0x0001, + 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006, 0x080c, + 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f, 0x1d50, + 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b1, + 0x0804, 0x0d2f, 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118, + 0x080c, 0x7489, 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484, + 0x080c, 0x747a, 0x080c, 0x709e, 0x0058, 0x080c, 0x717e, 0x0140, + 0x2009, 0x00f8, 0x080c, 0x5dab, 0x7843, 0x0090, 0x7843, 0x0010, + 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717e, 0x0138, + 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x1f04, 0x0c02, 0x0070, 0x7824, + 0x080c, 0x7198, 0x0118, 0xd0ac, 0x1904, 0x0d34, 0x9084, 0x1800, + 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d34, 0x2001, 0x0001, 0x080c, + 0x2616, 0x0804, 0x0d56, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518, + 0x080c, 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001, + 0x0001, 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f, 0x1d50, 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, - 0x27b2, 0x0804, 0x0d3b, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, + 0x27b1, 0x0804, 0x0d2f, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x01f8, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938, 0x7850, 0x9084, - 0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x7852, 0x793a, - 0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830e, 0x1f04, 0x0c62, - 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x00a0, - 0x2009, 0x198a, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001, 0x0120, - 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x20a9, 0x003a, 0x1d04, 0x0c7e, - 0x080c, 0x830e, 0x1f04, 0x0c7e, 0x080c, 0x7190, 0x0148, 0x080c, - 0x71a2, 0x1118, 0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0, - 0x080c, 0x7485, 0x080c, 0x747b, 0x080c, 0x709f, 0x0020, 0x2009, - 0x00f8, 0x080c, 0x5dac, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, - 0x0168, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0ca3, 0x7850, 0x9085, - 0x1400, 0x7852, 0x080c, 0x717f, 0x0158, 0x0030, 0x7850, 0xc0e5, - 0x7852, 0x080c, 0x717f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, - 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x830e, 0x7820, 0xd09c, - 0x1590, 0x080c, 0x717f, 0x0904, 0x0d1f, 0x7824, 0xd0ac, 0x1904, - 0x0d40, 0x080c, 0x71a2, 0x1538, 0x0046, 0x2021, 0x0320, 0x8421, - 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x9084, - 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, - 0x9084, 0x9000, 0x0110, 0x080c, 0x0d70, 0x8421, 0x1160, 0x1d04, - 0x0ceb, 0x080c, 0x830e, 0x080c, 0x7485, 0x080c, 0x747b, 0x7003, - 0x0001, 0x0804, 0x0d40, 0x8319, 0x1938, 0x2001, 0x0100, 0x2004, - 0x9086, 0x000a, 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, - 0x0110, 0x080c, 0x0d70, 0x1d04, 0x0d07, 0x080c, 0x830e, 0x2009, - 0x1975, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b, - 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x7924, - 0x080c, 0x2ab0, 0xd19c, 0x0110, 0x080c, 0x2989, 0x00e0, 0x080c, - 0x7190, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7157, 0x7003, - 0x0001, 0x00b0, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x080c, - 0x7199, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0cf3, - 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2617, 0x00c0, - 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1118, 0x7850, 0xc0e4, - 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, - 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a, - 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0120, 0x7850, 0x9085, - 0x0400, 0x7852, 0x2001, 0x1981, 0x2003, 0x0000, 0x9006, 0x78f2, - 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005, - 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x830e, 0x015e, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005, - 0x00e6, 0x2071, 0x189c, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c, - 0x3330, 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x1985, 0x2063, - 0x0003, 0x6007, 0x0003, 0x600b, 0x000f, 0x600f, 0x0317, 0x2001, - 0x1956, 0x900e, 0x2102, 0x7192, 0x2001, 0x0100, 0x2004, 0x9082, - 0x0002, 0x0218, 0x705b, 0xffff, 0x0008, 0x715a, 0x7063, 0xffff, - 0x717a, 0x717e, 0x080c, 0xc18e, 0x70e7, 0x00c0, 0x2061, 0x1946, - 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, - 0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x194e, - 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, - 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1963, 0x6003, 0x514c, - 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182b, - 0x2102, 0x0005, 0x9016, 0x080c, 0x63a4, 0x1178, 0xb804, 0x90c4, - 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, - 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, - 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e, - 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, 0x0e04, 0x0006, 0x0016, - 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836, - 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, - 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808, - 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, - 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x1a7a, 0x7a08, 0x226a, - 0x2069, 0x1a7b, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c, - 0x2019, 0x1a88, 0x201a, 0x2019, 0x1a8b, 0x9016, 0x7808, 0xd09c, - 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1aa0, 0x0108, - 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1a89, - 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a5a, - 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, - 0x1f04, 0x0e5b, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, - 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x0180, 0x2001, 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, - 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, - 0x1001, 0x080c, 0x54eb, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c, - 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, - 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, - 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f23, 0x20a9, 0x0900, - 0x080c, 0x0f44, 0x2011, 0x0040, 0x080c, 0x0f23, 0x20a9, 0x0900, - 0x080c, 0x0f44, 0x0c78, 0x0026, 0x080c, 0x0f30, 0x1118, 0x2011, - 0x0040, 0x0098, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, - 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4, - 0x70eb, 0x0000, 0x1120, 0x70eb, 0x0fa0, 0x080c, 0x0f35, 0x002e, - 0x0005, 0x0026, 0x080c, 0x0f30, 0x0128, 0xd0a4, 0x1138, 0x2011, - 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f35, 0x002e, 0x0005, - 0x0026, 0x70eb, 0x0000, 0x080c, 0x0f30, 0x1148, 0x080c, 0x2aa8, - 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, 0x8282, 0x0040, 0x080c, - 0x2aa8, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, - 0x0f35, 0x002e, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4, - 0x70e4, 0x1110, 0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f, - 0x20d8, 0x000e, 0x70eb, 0x0000, 0xc0e5, 0x0079, 0x000e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70e4, 0x1110, 0xc0dc, - 0x0008, 0xc0dd, 0x0011, 0x00ee, 0x0005, 0x70e6, 0x7000, 0x9084, - 0x0007, 0x000b, 0x0005, 0x0ef2, 0x0ec9, 0x0ec9, 0x0eab, 0x0ed8, - 0x0ec9, 0x0ec9, 0x0ed8, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, - 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005, - 0x2001, 0x1839, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c, - 0x0e02, 0x70e4, 0xd0e4, 0x0108, 0xc2e5, 0x72e6, 0xd0e4, 0x1118, - 0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04, 0x0f44, 0x2091, 0x6000, - 0x1f04, 0x0f44, 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, - 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, - 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, - 0x188b, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, - 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, - 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, - 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, - 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189b, 0x928a, 0x000e, - 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, - 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, - 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, - 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, - 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, - 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, - 0x0f4b, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, - 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, - 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b4, 0x81ff, 0x11c0, - 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, - 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, - 0x4001, 0x7078, 0x8007, 0x717c, 0x810f, 0x20a9, 0x0002, 0x4001, - 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0de2, 0x2001, 0x0000, - 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, - 0xa807, 0x0000, 0x0006, 0x080c, 0x1075, 0x009e, 0x0cb0, 0x0005, - 0x00e6, 0x2071, 0x1800, 0x080c, 0x10ee, 0x090c, 0x0e02, 0x00ee, - 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, - 0x8000, 0x00c9, 0x2071, 0x1800, 0x73bc, 0x702c, 0x9016, 0x9045, - 0x0158, 0x8210, 0x9906, 0x090c, 0x0e02, 0x2300, 0x9202, 0x0120, - 0x1a0c, 0x0e02, 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, - 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x190e, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, - 0x0128, 0x9906, 0x090c, 0x0e02, 0xa000, 0x0cc8, 0x012e, 0x000e, - 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, - 0x8000, 0x70bc, 0x8001, 0x0270, 0x70be, 0x702c, 0x2048, 0x9085, - 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, - 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1800, 0x70bc, 0x90ca, 0x0040, 0x0268, 0x8001, 0x70be, - 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, - 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, - 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, - 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, - 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, - 0x8000, 0x70be, 0x080c, 0x8170, 0x012e, 0x00ee, 0x0005, 0x2071, - 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, - 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, - 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, - 0x7000, 0x9005, 0x11a0, 0x2001, 0x0492, 0xa802, 0x2048, 0x2009, - 0x2480, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, - 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, - 0x188b, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, - 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, - 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, - 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, - 0x0000, 0x2071, 0x1800, 0x74ba, 0x74be, 0x0005, 0x00e6, 0x0016, - 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, - 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0492, 0x0288, 0x9982, - 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188b, - 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, - 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x19f5, 0x7007, 0x0000, 0x9006, - 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, - 0x7012, 0x2071, 0x0080, 0x9006, 0x0006, 0x2001, 0x0100, 0x2004, - 0x9086, 0x000a, 0x000e, 0x1158, 0x702b, 0x0060, 0x20a9, 0x0040, - 0x7022, 0x1f04, 0x1130, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, - 0x0040, 0x7022, 0x1f04, 0x1139, 0x702b, 0x0020, 0x00ee, 0x0005, - 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x19f5, - 0x701c, 0x9088, 0x19ff, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, - 0x7120, 0x9106, 0x090c, 0x0e02, 0x7004, 0x9005, 0x1128, 0x00f6, - 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x00e6, 0x2071, 0x19f5, 0x7004, 0x9005, 0x1128, - 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, - 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, - 0x1182, 0x1180, 0x1180, 0x1180, 0x12f9, 0x12f9, 0x12f9, 0x12f9, - 0x080c, 0x0e02, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, - 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, - 0x9180, 0x19ff, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, - 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, - 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, - 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, - 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, - 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, - 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, - 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, - 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, - 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, - 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, - 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, - 0x001e, 0x0005, 0x2009, 0x19f5, 0x2104, 0xc095, 0x200a, 0x080c, - 0x115f, 0x0005, 0x0016, 0x00e6, 0x2071, 0x19f5, 0x00f6, 0x2079, - 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dfb, 0x782b, 0x0002, 0xd1fc, - 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, - 0x0005, 0x1170, 0x1218, 0x124c, 0x0e02, 0x0e02, 0x1305, 0x0e02, - 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, - 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, - 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, - 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, - 0x11b5, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, - 0x7007, 0x0000, 0x080c, 0x1170, 0x0005, 0x7008, 0x0096, 0x2048, - 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, - 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11ca, - 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, - 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, - 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, - 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b7, - 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, - 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, - 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, - 0x115f, 0x0005, 0x00de, 0x009e, 0x080c, 0x115f, 0x0005, 0xa8a8, - 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0xa06c, - 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4002, 0x080c, 0x6a16, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, - 0x080c, 0x1075, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, - 0x0e02, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, - 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, - 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, - 0x1140, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6a16, - 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, - 0x080c, 0x9fd5, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, - 0x0000, 0x080c, 0x1075, 0x7007, 0x0000, 0x080c, 0x115f, 0x00ae, - 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, - 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x7007, 0x0000, 0x080c, - 0x1170, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, - 0x1a3f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0419, 0x7803, 0x0003, - 0x780f, 0x0000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128, - 0x20a9, 0x01e8, 0x2061, 0xdba9, 0x0020, 0x20a9, 0x01e8, 0x2061, - 0xdf77, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04, - 0x1329, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, - 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0110, 0x7820, - 0x0cd8, 0x2001, 0x1a40, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, - 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030, - 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a5a, 0x781f, 0xff00, - 0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, - 0x0303, 0x2061, 0x1a5a, 0x602f, 0x1cd0, 0x2001, 0x1819, 0x2004, - 0x9082, 0x1cd0, 0x6032, 0x603b, 0x1ec2, 0x783f, 0x3209, 0x00ce, - 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, - 0x0dfb, 0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a, - 0x0024, 0x1a0c, 0x0e02, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005, - 0x13ac, 0x13ac, 0x13c3, 0x13c8, 0x13cc, 0x13d1, 0x13f9, 0x13fd, - 0x140b, 0x140f, 0x13ac, 0x149b, 0x149f, 0x150f, 0x13ac, 0x13ac, - 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, - 0x13ac, 0x13ac, 0x13ac, 0x13d3, 0x13ac, 0x13ac, 0x13ac, 0x13ac, - 0x13ac, 0x13ac, 0x13b0, 0x13ae, 0x080c, 0x0e02, 0x080c, 0x0dfb, - 0x080c, 0x1516, 0x2009, 0x1a56, 0x2104, 0x8000, 0x200a, 0x080c, - 0x7bed, 0x080c, 0x1983, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c, - 0xa053, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, - 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x1516, 0x080c, 0x15f0, - 0x0005, 0x080c, 0x0e02, 0x080c, 0x1516, 0x2060, 0x6014, 0x0096, - 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa053, - 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, - 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, - 0xd0ec, 0x1110, 0x080c, 0x151b, 0x2001, 0x0307, 0x2003, 0x8000, - 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1516, 0x2060, - 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, - 0x080c, 0xa053, 0x0005, 0x080c, 0x1516, 0x080c, 0x0e02, 0x080c, - 0x1516, 0x080c, 0x1486, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0540, - 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0138, 0x2001, - 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0400, 0x7004, 0x9005, - 0x1180, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, - 0x090c, 0x0e02, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, - 0x0490, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x149f, 0x0005, - 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0e02, 0x6014, 0x2048, - 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7bed, 0x080c, - 0x1983, 0x080c, 0xbd3b, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, - 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, - 0xb974, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x6024, 0x190c, 0xc127, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, - 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xdb52, 0xd5a4, - 0x1118, 0x080c, 0x151b, 0x0005, 0x080c, 0x7bed, 0x080c, 0x1983, - 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, - 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, - 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x158c, 0x00fe, 0x007e, - 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104, - 0x9184, 0x0004, 0x190c, 0x0e02, 0xd184, 0x11b1, 0xd19c, 0x0180, - 0xc19c, 0x7106, 0x0016, 0x080c, 0x15d3, 0x001e, 0x0148, 0x2001, - 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x151b, 0x0005, - 0x81ff, 0x190c, 0x0e02, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106, - 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1504, 0x2071, 0x0200, 0x080c, - 0x15c7, 0x080c, 0x15d3, 0x05a8, 0x6014, 0x9005, 0x05a8, 0x0096, - 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, - 0x908e, 0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6, 0x2c78, - 0x080c, 0x165d, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c, 0x17a7, - 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, - 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x0419, - 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1339, 0x7803, - 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x15d3, 0x0dd0, 0x2001, - 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0069, 0x0c90, 0x0031, - 0x2060, 0x2009, 0x0053, 0x080c, 0xa053, 0x0005, 0x7808, 0xd09c, - 0x0de8, 0x7820, 0x0005, 0x080c, 0x1486, 0x00d6, 0x2069, 0x0200, - 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, - 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, - 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, - 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x157e, 0x6827, 0x0001, - 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, - 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, - 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x7bed, 0x080c, 0x1983, 0x0090, - 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, - 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, - 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, - 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, - 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, - 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, - 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006, - 0x7808, 0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c, 0x1371, - 0x00ce, 0x002e, 0x001e, 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, - 0x781b, 0x8080, 0x0059, 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e, - 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x2009, 0xff00, - 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001, - 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108, - 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x7037, - 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, - 0x7054, 0x2060, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, - 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, - 0x1158, 0x2021, 0x1a57, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, - 0x7bed, 0x080c, 0x1983, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, - 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0879, - 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x1652, 0x7017, - 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x1652, 0x2001, - 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, - 0x1904, 0x1652, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, - 0x7b34, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xc102, - 0xab42, 0xac3e, 0x2001, 0x187d, 0x2004, 0xd0b4, 0x1170, 0x601c, - 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1ee2, 0x1190, - 0x080c, 0x1804, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, - 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, - 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, - 0x080c, 0x151b, 0x0005, 0x080c, 0x0e02, 0x0016, 0x2009, 0x00a0, - 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, - 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, - 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, - 0x1ec2, 0x2165, 0x0002, 0x1692, 0x16df, 0x1692, 0x1692, 0x1692, - 0x16c1, 0x1692, 0x1696, 0x168b, 0x16d6, 0x1692, 0x1692, 0x1692, - 0x179c, 0x16aa, 0x16a0, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, - 0x0904, 0x16d6, 0x9085, 0x0001, 0x0804, 0x1792, 0xa87c, 0xd0bc, - 0x0dc8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x16e6, - 0xa87c, 0xd0bc, 0x0d78, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, - 0x0804, 0x1735, 0xa87c, 0xd0bc, 0x0d28, 0xa890, 0xa842, 0xa88c, - 0xa83e, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa164, 0xa91a, 0x91ec, - 0x000f, 0x9d80, 0x1ec2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1735, - 0x0428, 0xa87c, 0xd0ac, 0x0970, 0xa804, 0x9045, 0x090c, 0x0e02, - 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ec2, 0x2065, 0x9006, - 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1735, 0x0080, 0xa87c, 0xd0ac, - 0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1735, 0xa87c, - 0xd0ac, 0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, - 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1709, 0x1709, - 0x170b, 0x1709, 0x1709, 0x1709, 0x1711, 0x1709, 0x1709, 0x1709, - 0x1717, 0x1709, 0x1709, 0x1709, 0x171d, 0x1709, 0x1709, 0x1709, - 0x1723, 0x1709, 0x1709, 0x1709, 0x1729, 0x1709, 0x1709, 0x1709, - 0x172f, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, - 0x177a, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x177a, 0xa594, - 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x177a, 0xa5a4, 0xa4a8, 0xa3ac, - 0xa2b0, 0x0804, 0x177a, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, - 0x177a, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x177a, 0xa5d4, - 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x177a, 0x2c05, 0x908a, 0x0034, - 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1758, 0x1756, 0x1756, - 0x1756, 0x1756, 0x1756, 0x175f, 0x1756, 0x1756, 0x1756, 0x1756, - 0x1756, 0x1766, 0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x176d, - 0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x1774, 0x080c, 0x0e02, - 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x00d8, 0xa584, - 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x00a0, 0xa59c, 0xa4a0, - 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x0068, 0xa5b4, 0xa4b8, 0xa7bc, - 0xa6c0, 0xa3c4, 0xa2c8, 0x0030, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, - 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, - 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, - 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, - 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, - 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x1692, 0x0016, 0x2009, - 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, - 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, - 0x2940, 0xa80e, 0x2061, 0x1ebd, 0xa813, 0x1ebd, 0x2c05, 0xa80a, - 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0e02, 0x9006, 0xa842, - 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0xadcc, 0xacd0, - 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, - 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, - 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, - 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, - 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, - 0x0005, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa80e, 0xa064, 0xa81a, - 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2015, 0x82ff, 0x090c, 0x0e02, - 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, - 0x1190, 0x2d00, 0x0002, 0x18f9, 0x185b, 0x185b, 0x18f9, 0x18f9, - 0x18f3, 0x18f9, 0x185b, 0x18aa, 0x18aa, 0x18aa, 0x18f9, 0x18f9, - 0x18f9, 0x18f0, 0x18aa, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, - 0xac20, 0xdd9c, 0x0904, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c, - 0x0e02, 0x9082, 0x001b, 0x0002, 0x1847, 0x1845, 0x1845, 0x1845, - 0x1845, 0x1845, 0x184b, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845, - 0x184f, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845, 0x1853, 0x1845, - 0x1845, 0x1845, 0x1845, 0x1845, 0x1857, 0x080c, 0x0e02, 0xa774, - 0xa678, 0x0804, 0x18fb, 0xa78c, 0xa690, 0x0804, 0x18fb, 0xa7a4, - 0xa6a8, 0x0804, 0x18fb, 0xa7bc, 0xa6c0, 0x0804, 0x18fb, 0xa7d4, - 0xa6d8, 0x0804, 0x18fb, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02, - 0x9082, 0x001b, 0x0002, 0x187e, 0x187e, 0x1880, 0x187e, 0x187e, - 0x187e, 0x1886, 0x187e, 0x187e, 0x187e, 0x188c, 0x187e, 0x187e, - 0x187e, 0x1892, 0x187e, 0x187e, 0x187e, 0x1898, 0x187e, 0x187e, - 0x187e, 0x189e, 0x187e, 0x187e, 0x187e, 0x18a4, 0x080c, 0x0e02, - 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x18fb, 0xa584, 0xa488, - 0xa38c, 0xa290, 0x0804, 0x18fb, 0xa594, 0xa498, 0xa39c, 0xa2a0, - 0x0804, 0x18fb, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x18fb, - 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x18fb, 0xa5c4, 0xa4c8, - 0xa3cc, 0xa2d0, 0x0804, 0x18fb, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, - 0x0804, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, - 0x001b, 0x0002, 0x18cd, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb, - 0x18d4, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18db, 0x18cb, - 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18e2, 0x18cb, 0x18cb, 0x18cb, - 0x18cb, 0x18cb, 0x18e9, 0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774, - 0xa678, 0xa37c, 0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690, - 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, - 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, - 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, - 0x9d86, 0x000e, 0x1130, 0x080c, 0x1e80, 0x1904, 0x1804, 0x900e, - 0x0050, 0x080c, 0x0e02, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, - 0xae2a, 0x080c, 0x1e80, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, - 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, - 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, - 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, - 0x0048, 0x080c, 0xa053, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, - 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, - 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xa053, 0x0005, - 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, - 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, - 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, - 0xd09c, 0x0120, 0x080c, 0x1371, 0x8631, 0x1db8, 0x00ce, 0x781f, - 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1371, - 0x00ce, 0x2001, 0x0038, 0x080c, 0x1a0b, 0x7930, 0x9186, 0x0040, - 0x0160, 0x9186, 0x0042, 0x190c, 0x0e02, 0x2001, 0x001e, 0x8001, - 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1a1a, 0x000e, 0x6022, 0x012e, - 0x0005, 0x080c, 0x1a07, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, - 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, - 0x78ab, 0x0004, 0x00fe, 0x080c, 0x717f, 0x1188, 0x2001, 0x0138, - 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, - 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7247, 0x0479, - 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, - 0x00e6, 0x2071, 0x0200, 0x080c, 0x2abc, 0x2009, 0x003c, 0x080c, - 0x2204, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, - 0x1de0, 0x080c, 0x8170, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, - 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, - 0x080c, 0x1339, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, - 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, - 0x0000, 0x080c, 0x717f, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, - 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, - 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, - 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, - 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, - 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, - 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x158c, 0x7930, - 0x0005, 0x2c08, 0x621c, 0x080c, 0x15b9, 0x7930, 0x0005, 0x8001, - 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, - 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1a78, 0x2001, - 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0e02, 0x781f, 0x0202, - 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, - 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, - 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, - 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, - 0x2001, 0x0030, 0x080c, 0x1a11, 0x9186, 0x0040, 0x190c, 0x0e02, - 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, - 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, - 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, - 0x9184, 0x0007, 0x090c, 0x0e02, 0xa001, 0xa001, 0x781f, 0x0200, - 0x0005, 0x0126, 0x2091, 0x2400, 0x2071, 0x1a42, 0x2079, 0x0090, - 0x012e, 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, - 0x1904, 0x1b0d, 0xa964, 0x9184, 0x0007, 0x0002, 0x1a96, 0x1af8, - 0x1aad, 0x1aad, 0x1aad, 0x1ae0, 0x1ac0, 0x1aaf, 0x918c, 0x00ff, - 0x9186, 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0x9006, - 0xa842, 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x1ebd, 0x0804, - 0x1b09, 0x9186, 0x0048, 0x0904, 0x1af8, 0x080c, 0x0e02, 0xa87c, - 0xd0b4, 0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, - 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa988, 0x0804, 0x1b00, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1d38, 0xa87c, 0xd0b4, - 0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, - 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064, - 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005, 0xa812, 0xa988, 0x0448, - 0x918c, 0x00ff, 0x9186, 0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904, - 0x1cc3, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, - 0x1ec2, 0x2005, 0xa812, 0xa988, 0x9006, 0xa842, 0xa83e, 0x0088, - 0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0xa988, 0x9006, 0xa842, 0xa83e, - 0x2900, 0xa85a, 0xa864, 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005, - 0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079, - 0x0090, 0x782c, 0xd0fc, 0x190c, 0x1d04, 0x00e6, 0x2071, 0x1a42, - 0x7000, 0x9005, 0x1904, 0x1b65, 0x7206, 0x9280, 0x0005, 0x204c, - 0x9280, 0x0004, 0x2004, 0x782b, 0x0004, 0x00f6, 0x2079, 0x0200, - 0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, 0xb86c, 0x7836, 0xb890, - 0x00be, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0xa001, 0xa001, - 0xa001, 0xa001, 0xa001, 0xa001, 0x781a, 0x78d7, 0x0000, 0x00fe, - 0xa814, 0x2050, 0xa858, 0x2040, 0xa810, 0x2060, 0xa064, 0x90ec, - 0x000f, 0xa944, 0x791a, 0x7116, 0xa848, 0x781e, 0x701a, 0x9006, - 0x700e, 0x7012, 0x7004, 0xa940, 0xa838, 0x9106, 0x1188, 0xa93c, - 0xa834, 0x9106, 0x1168, 0x8aff, 0x01a8, 0x0126, 0x2091, 0x8000, - 0x00a1, 0x0108, 0x0091, 0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005, - 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, 0x1ee2, 0x004e, 0x003e, - 0x0d50, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x0076, 0x0066, 0x0056, - 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1cbc, 0x700c, 0x7214, - 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1cbb, 0x9705, 0x0904, - 0x1cbb, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, - 0x1c9f, 0x1be0, 0x1be0, 0x1c9f, 0x1c9f, 0x1c7d, 0x1c9f, 0x1be0, - 0x1c83, 0x1c2f, 0x1c2f, 0x1c9f, 0x1c9f, 0x1c9f, 0x1c77, 0x1c2f, - 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, - 0x1ca1, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b, - 0x0002, 0x1bcc, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd0, - 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd4, 0x1bca, 0x1bca, - 0x1bca, 0x1bca, 0x1bca, 0x1bd8, 0x1bca, 0x1bca, 0x1bca, 0x1bca, - 0x1bca, 0x1bdc, 0x080c, 0x0e02, 0xa774, 0xa678, 0x0804, 0x1ca1, - 0xa78c, 0xa690, 0x0804, 0x1ca1, 0xa7a4, 0xa6a8, 0x0804, 0x1ca1, - 0xa7bc, 0xa6c0, 0x0804, 0x1ca1, 0xa7d4, 0xa6d8, 0x0804, 0x1ca1, - 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, - 0x1c03, 0x1c03, 0x1c05, 0x1c03, 0x1c03, 0x1c03, 0x1c0b, 0x1c03, - 0x1c03, 0x1c03, 0x1c11, 0x1c03, 0x1c03, 0x1c03, 0x1c17, 0x1c03, - 0x1c03, 0x1c03, 0x1c1d, 0x1c03, 0x1c03, 0x1c03, 0x1c23, 0x1c03, - 0x1c03, 0x1c03, 0x1c29, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c, - 0xa280, 0x0804, 0x1ca1, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, - 0x1ca1, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1ca1, 0xa5a4, - 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1ca1, 0xa5b4, 0xa4b8, 0xa3bc, - 0xa2c0, 0x0804, 0x1ca1, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, - 0x1ca1, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1ca1, 0x2c05, - 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1c52, - 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c5a, 0x1c50, 0x1c50, - 0x1c50, 0x1c50, 0x1c50, 0x1c62, 0x1c50, 0x1c50, 0x1c50, 0x1c50, - 0x1c50, 0x1c69, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c70, - 0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, - 0x0804, 0x1ca1, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, - 0x0804, 0x1ca1, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, - 0x04c0, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0488, - 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0450, 0xa864, - 0x9084, 0x00ff, 0x9086, 0x001e, 0x1510, 0x080c, 0x1e80, 0x1904, - 0x1b7b, 0x900e, 0x04c8, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048, - 0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce, - 0x0904, 0x1c2f, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98, - 0x0040, 0x9386, 0x0008, 0x0904, 0x1c2f, 0x080c, 0x0e02, 0x080c, - 0x0e02, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b, - 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, 0xa83e, 0xa840, - 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, 0x7010, 0x9201, 0x7012, - 0x080c, 0x1e80, 0x0008, 0x9006, 0x002e, 0x003e, 0x004e, 0x005e, - 0x006e, 0x007e, 0x0005, 0x080c, 0x0e02, 0x0026, 0x2001, 0x0105, - 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, - 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0118, 0xa880, 0xc0bd, 0xa882, - 0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, - 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, - 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xb974, 0x00ce, - 0x2001, 0x19d1, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, - 0x2204, 0x080c, 0x9a7a, 0x2011, 0x0000, 0x080c, 0x9918, 0x080c, - 0x8c6d, 0x002e, 0x0804, 0x1e32, 0x0126, 0x2091, 0x2400, 0xa858, - 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1cc5, - 0x7000, 0x0002, 0x1e32, 0x1d16, 0x1d83, 0x1e30, 0x8001, 0x7002, - 0xd19c, 0x1150, 0x8aff, 0x05b0, 0x080c, 0x1b75, 0x0904, 0x1e32, - 0x080c, 0x1b75, 0x0804, 0x1e32, 0x782b, 0x0004, 0xd194, 0x0148, - 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x11d8, 0xa87c, 0xc0f5, 0xa87e, - 0x00b8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x7810, 0xa82e, 0x931a, - 0x7814, 0xa832, 0x9213, 0x7800, 0xa81e, 0x7804, 0xa822, 0xab3e, - 0xaa42, 0x003e, 0x002e, 0x080c, 0x1e98, 0xa880, 0xc0fd, 0xa882, - 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000, - 0x0804, 0x1e32, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, - 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, - 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0e02, 0x7820, 0xd0bc, - 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, - 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, - 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003, - 0x0000, 0x0804, 0x1e32, 0x8001, 0x7002, 0xd194, 0x0170, 0x782c, - 0xd0fc, 0x1904, 0x1d09, 0xd19c, 0x1904, 0x1e2e, 0x8aff, 0x0904, - 0x1e32, 0x080c, 0x1b75, 0x0804, 0x1e32, 0x0026, 0x0036, 0xab3c, - 0xaa40, 0x080c, 0x1e98, 0xdd9c, 0x1904, 0x1ded, 0x2c05, 0x908a, - 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1dc1, 0x1dc1, - 0x1dc3, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dc9, 0x1dc1, 0x1dc1, 0x1dc1, - 0x1dcf, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dd5, 0x1dc1, 0x1dc1, 0x1dc1, - 0x1ddb, 0x1dc1, 0x1dc1, 0x1dc1, 0x1de1, 0x1dc1, 0x1dc1, 0x1dc1, - 0x1de7, 0x080c, 0x0e02, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, - 0x1d35, 0xa08c, 0x931a, 0xa090, 0x9213, 0x0804, 0x1d35, 0xa09c, - 0x931a, 0xa0a0, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0, - 0x9213, 0x0804, 0x1d35, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, - 0x1d35, 0xa0cc, 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1d35, 0xa0dc, - 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x2c05, 0x908a, 0x0034, - 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1e10, 0x1e0e, 0x1e0e, - 0x1e0e, 0x1e0e, 0x1e0e, 0x1e16, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, - 0x1e0e, 0x1e1c, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e22, - 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e28, 0x080c, 0x0e02, - 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1d35, 0xa094, 0x931a, - 0xa098, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0, 0x9213, - 0x0804, 0x1d35, 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1d35, - 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x0804, 0x1d31, - 0x080c, 0x0e02, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42, - 0x7000, 0x9086, 0x0000, 0x0904, 0x1e7d, 0x2079, 0x0090, 0x2009, - 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, - 0x0003, 0x0188, 0x080c, 0xdb9b, 0x2001, 0x0133, 0x2004, 0x9005, - 0x090c, 0x0e02, 0x0016, 0x2009, 0x0040, 0x080c, 0x2204, 0x001e, - 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, - 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2204, 0x782c, - 0xd0fc, 0x09a8, 0x080c, 0x1d04, 0x7000, 0x9086, 0x0000, 0x1978, - 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, - 0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, - 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, - 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ec2, - 0x2065, 0x8cff, 0x090c, 0x0e02, 0x8a51, 0x0005, 0x2050, 0x0005, - 0x8a50, 0x8c61, 0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, - 0xa000, 0x9005, 0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, - 0x000f, 0x9080, 0x1ed2, 0x2065, 0x8cff, 0x090c, 0x0e02, 0x0005, - 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, - 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, - 0x0023, 0x0000, 0x0000, 0x1eb5, 0x1eb1, 0x0000, 0x0000, 0x1ebf, - 0x0000, 0x1eb5, 0x1ebc, 0x1ebc, 0x1eb9, 0x0000, 0x0000, 0x0000, - 0x1ebf, 0x1ebc, 0x0000, 0x1eb7, 0x1eb7, 0x0000, 0x0000, 0x1ebf, - 0x0000, 0x1eb7, 0x1ebd, 0x1ebd, 0x1ebd, 0x0000, 0x0000, 0x0000, - 0x1ebf, 0x1ebd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, - 0x9055, 0x0904, 0x20c1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, - 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1ebd, 0x00d0, 0x9de0, - 0x1ec2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, - 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, - 0x1140, 0x0310, 0x0804, 0x20c1, 0xa004, 0x9045, 0x0904, 0x20c1, - 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fa9, 0xdd9c, 0x1904, 0x1f65, - 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1f3a, - 0x1f3a, 0x1f3c, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f42, 0x1f3a, 0x1f3a, - 0x1f3a, 0x1f48, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f4e, 0x1f3a, 0x1f3a, - 0x1f3a, 0x1f54, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f5a, 0x1f3a, 0x1f3a, - 0x1f3a, 0x1f60, 0x080c, 0x0e02, 0xa07c, 0x9422, 0xa080, 0x931b, - 0x0804, 0x1f9f, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f9f, - 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f9f, 0xa0ac, 0x9422, - 0xa0b0, 0x931b, 0x0804, 0x1f9f, 0xa0bc, 0x9422, 0xa0c0, 0x931b, - 0x0804, 0x1f9f, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f9f, - 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, - 0x0e02, 0x9082, 0x001b, 0x0002, 0x1f87, 0x1f85, 0x1f85, 0x1f85, - 0x1f85, 0x1f85, 0x1f8c, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85, - 0x1f91, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f96, 0x1f85, - 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f9b, 0x080c, 0x0e02, 0xa07c, - 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, - 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, - 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, - 0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20c1, 0x8c60, 0x0804, - 0x1f11, 0xa004, 0x9045, 0x0904, 0x20c1, 0x0804, 0x1eec, 0x8a51, - 0x0904, 0x20c1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, - 0x0904, 0x20c1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ec2, 0x2c05, - 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20b6, 0x2c05, 0x8422, - 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, - 0x2053, 0x9082, 0x001b, 0x0002, 0x1fef, 0x1fef, 0x1ff1, 0x1fef, - 0x1fef, 0x1fef, 0x1fff, 0x1fef, 0x1fef, 0x1fef, 0x200d, 0x1fef, - 0x1fef, 0x1fef, 0x201b, 0x1fef, 0x1fef, 0x1fef, 0x2029, 0x1fef, - 0x1fef, 0x1fef, 0x2037, 0x1fef, 0x1fef, 0x1fef, 0x2045, 0x080c, - 0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, - 0x0e02, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20b1, 0xa18c, - 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084, - 0x9420, 0xa088, 0x9319, 0x0804, 0x20b1, 0xa19c, 0x2400, 0x9122, - 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa094, 0x9420, 0xa098, - 0x9319, 0x0804, 0x20b1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, - 0x911b, 0x0a0c, 0x0e02, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, - 0x20b1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, - 0x0e02, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20b1, 0xa1cc, - 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0c4, - 0x9420, 0xa0c8, 0x9319, 0x0804, 0x20b1, 0xa1dc, 0x2400, 0x9122, - 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0d4, 0x9420, 0xa0d8, - 0x9319, 0x0804, 0x20b1, 0x9082, 0x001b, 0x0002, 0x2071, 0x206f, - 0x206f, 0x206f, 0x206f, 0x206f, 0x207e, 0x206f, 0x206f, 0x206f, - 0x206f, 0x206f, 0x208b, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f, - 0x2098, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f, 0x20a5, 0x080c, - 0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, - 0x0e02, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, - 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084, 0x9420, - 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, - 0x911b, 0x0a0c, 0x0e02, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, - 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0e02, - 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, - 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0cc, 0x9420, 0xa0d0, - 0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, - 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, - 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, - 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0dfb, 0x9084, 0x0007, 0x0002, - 0x20e2, 0x1d04, 0x20e2, 0x20d8, 0x20db, 0x20de, 0x20db, 0x20de, - 0x080c, 0x1d04, 0x0005, 0x080c, 0x11fa, 0x0005, 0x080c, 0x1d04, - 0x080c, 0x11fa, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, - 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, - 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, - 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, - 0x012e, 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2201, - 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, - 0x0002, 0x2129, 0x2121, 0x7b34, 0x2121, 0x2123, 0x2123, 0x2123, - 0x2123, 0x7b1a, 0x2121, 0x2125, 0x2121, 0x2123, 0x2121, 0x2123, - 0x2121, 0x080c, 0x0e02, 0x0031, 0x0020, 0x080c, 0x7b1a, 0x080c, - 0x7b34, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xdb9b, 0x7930, - 0x9184, 0x0003, 0x01c0, 0x2001, 0x19d1, 0x2004, 0x9005, 0x0170, - 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0e02, 0x00c6, 0x2001, - 0x19d1, 0x2064, 0x080c, 0xb974, 0x00ce, 0x00f8, 0x2009, 0x0040, - 0x080c, 0x2204, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, - 0x0003, 0x0160, 0x080c, 0x717f, 0x1138, 0x080c, 0x747b, 0x080c, - 0x5e30, 0x080c, 0x709f, 0x0010, 0x080c, 0x5cef, 0x080c, 0x7be3, - 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, - 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c, - 0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, - 0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1949, 0x2102, 0x2001, - 0x1951, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, - 0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, - 0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, - 0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, - 0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, - 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, - 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, - 0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, - 0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, - 0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, - 0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, - 0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, - 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, - 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, - 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, - 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, - 0x0005, 0x7938, 0x080c, 0x0dfb, 0x00f6, 0x2079, 0x0200, 0x7902, - 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, - 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, - 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, - 0x080c, 0x2ab6, 0x080c, 0x2989, 0x2001, 0x0100, 0x2004, 0x9086, - 0x000a, 0x0558, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, - 0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, - 0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x1977, 0x2011, 0x1978, - 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x29f6, 0x1238, 0x939d, - 0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, - 0x94a5, 0x8603, 0x230a, 0x2412, 0x0050, 0x2001, 0x1977, 0x2003, - 0x0700, 0x2001, 0x1978, 0x2003, 0x0700, 0x080c, 0x2bc2, 0x9006, - 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x20a9, 0x0012, 0x1d04, - 0x2267, 0x2091, 0x6000, 0x1f04, 0x2267, 0x602f, 0x0100, 0x602f, - 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, - 0x6026, 0x080c, 0x26a7, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, - 0x26b7, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7, - 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f, - 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x2294, - 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0320, - 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, - 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, - 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, - 0x1834, 0x2003, 0x0000, 0x2001, 0x1833, 0x2003, 0x0001, 0x0005, - 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x9184, - 0x5e2c, 0x1118, 0x9184, 0x0007, 0x002a, 0x9195, 0x0004, 0x9284, - 0x0007, 0x0002, 0x22f4, 0x22da, 0x22dd, 0x22e0, 0x22e5, 0x22e7, - 0x22eb, 0x22ef, 0x080c, 0x84e3, 0x00b8, 0x080c, 0x85b2, 0x00a0, - 0x080c, 0x85b2, 0x080c, 0x84e3, 0x0078, 0x0099, 0x0068, 0x080c, - 0x84e3, 0x0079, 0x0048, 0x080c, 0x85b2, 0x0059, 0x0028, 0x080c, - 0x85b2, 0x080c, 0x84e3, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, - 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, - 0x2548, 0xd1f4, 0x190c, 0x0dfb, 0x080c, 0x717f, 0x0904, 0x234f, - 0x080c, 0xc444, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, - 0x9084, 0x1800, 0x0550, 0x080c, 0x71a2, 0x0118, 0x080c, 0x7190, - 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xc444, 0x0168, - 0x080c, 0x71a2, 0x1150, 0x2001, 0x1981, 0x2003, 0x0001, 0x6027, - 0x1800, 0x080c, 0x6fee, 0x0804, 0x254b, 0x70a0, 0x9005, 0x1150, - 0x70a3, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x71d3, 0x00de, - 0x1904, 0x254b, 0x080c, 0x7485, 0x0428, 0x080c, 0x71a2, 0x1590, - 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7485, 0x080c, - 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0804, 0x2548, 0xd1ac, - 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, - 0xd0cc, 0x0130, 0x7094, 0x9086, 0x0029, 0x1110, 0x080c, 0x736a, - 0x0804, 0x2548, 0x080c, 0x7480, 0x0048, 0x2001, 0x1957, 0x2003, - 0x0002, 0x0020, 0x080c, 0x72ce, 0x0804, 0x2548, 0x080c, 0x7404, - 0x0804, 0x2548, 0xd1ac, 0x0904, 0x2469, 0x080c, 0x717f, 0x11c0, - 0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199, 0x1158, - 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x003e, 0x002e, - 0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7157, - 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, - 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74d6, 0x948c, - 0xff00, 0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7044, - 0xd084, 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016, - 0x080c, 0x4a18, 0x003e, 0x080c, 0xc43d, 0x1904, 0x2446, 0x9196, - 0xff00, 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, - 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3204, 0x0128, - 0xc18d, 0x7132, 0x080c, 0x66c2, 0x1510, 0x6240, 0x9294, 0x0010, - 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, - 0xd08c, 0x0904, 0x2446, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, - 0x200c, 0xd1ac, 0x1904, 0x2446, 0xc1ad, 0x2102, 0x0036, 0x73d4, - 0x2011, 0x8013, 0x080c, 0x4a18, 0x003e, 0x0804, 0x2446, 0x7038, - 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2446, - 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a18, - 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, - 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451, 0x2019, - 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xd74e, 0x00ce, 0x9484, - 0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, - 0x9006, 0x2009, 0x000e, 0x080c, 0xd7d6, 0x001e, 0xd1ac, 0x1148, - 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076, 0x001e, - 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a4, - 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, - 0x5e4a, 0x8108, 0x1f04, 0x2436, 0x00be, 0x015e, 0x00ce, 0x004e, - 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, - 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, - 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, - 0x622a, 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027, - 0x0020, 0xd194, 0x0904, 0x2548, 0x0016, 0x6220, 0xd2b4, 0x0904, - 0x24f1, 0x080c, 0x82da, 0x080c, 0x9605, 0x6027, 0x0004, 0x00f6, - 0x2019, 0x19cb, 0x2304, 0x907d, 0x0904, 0x24c0, 0x7804, 0x9086, - 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, - 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, - 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, - 0x080c, 0x2b98, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, - 0x080c, 0x2a91, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x080c, 0x8a84, 0x080c, - 0x8b90, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fd5, - 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, - 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, - 0x080c, 0x2b98, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c, - 0xc444, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, - 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x95e1, 0x0804, 0x2547, - 0x2061, 0x0100, 0x62c0, 0x080c, 0x9de1, 0x2019, 0x19cb, 0x2304, - 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xa053, 0x00ce, 0x0804, - 0x2547, 0xd2bc, 0x0904, 0x2534, 0x080c, 0x82e7, 0x6014, 0x9084, - 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, - 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x00de, - 0x00c6, 0x2061, 0x19c2, 0x6044, 0x080c, 0xc444, 0x0120, 0x909a, - 0x0003, 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046, - 0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82df, - 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, - 0x1984, 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984, - 0x918d, 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036, - 0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x2019, 0x19d1, 0x2304, - 0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0xa053, 0x00ce, 0x001e, - 0xd19c, 0x0904, 0x2612, 0x7038, 0xd0ac, 0x1904, 0x25e7, 0x0016, - 0x0156, 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, - 0x0904, 0x25c4, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, - 0xfbcf, 0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9, - 0x0012, 0x1d04, 0x2569, 0x080c, 0x830e, 0x1f04, 0x2569, 0x6050, - 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001, - 0x1f04, 0x2577, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366, - 0x1d04, 0x2580, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1138, 0x015e, - 0x6152, 0x001e, 0x6027, 0x0008, 0x0804, 0x2612, 0x080c, 0x2a78, - 0x1f04, 0x2580, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, - 0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c, - 0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c, - 0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c, - 0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800, - 0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c, - 0x0b8f, 0x001e, 0x0804, 0x2612, 0x080c, 0x2bc2, 0x080c, 0x2bf5, - 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25e5, 0x1d04, - 0x25cf, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, - 0x0100, 0x080c, 0x2a06, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, - 0x6027, 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016, - 0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c, - 0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c, - 0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c, - 0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800, - 0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c, - 0x0b8f, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006, - 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2666, 0x81ff, - 0x01a0, 0x2009, 0x0000, 0x080c, 0x2ab6, 0x2011, 0x8011, 0x2019, - 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, - 0x2019, 0x0000, 0x080c, 0x4a18, 0x0448, 0x2001, 0x1982, 0x200c, - 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, - 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a18, 0x080c, - 0x0ed8, 0x080c, 0x54e0, 0xd0fc, 0x1188, 0x080c, 0xc43d, 0x1170, - 0x00c6, 0x080c, 0x2702, 0x080c, 0x9803, 0x2061, 0x0100, 0x2019, - 0x0028, 0x2009, 0x0002, 0x080c, 0x3076, 0x00ce, 0x012e, 0x00fe, - 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, - 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214, - 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106, - 0x1190, 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, - 0x9206, 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584, - 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, 0x7e40, 0x0048, 0x9584, - 0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, - 0x0005, 0x9080, 0x3209, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, - 0x2069, 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010, - 0x9006, 0x6852, 0x6856, 0x1f04, 0x26b2, 0x00de, 0x0005, 0x0006, - 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114, - 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, - 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xe345, 0x2005, 0x6856, - 0x8211, 0x1f04, 0x26c7, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, - 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, - 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, - 0x0140, 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, - 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, - 0x1f04, 0x26f7, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, - 0x015e, 0x0005, 0x080c, 0x54dc, 0xd0c4, 0x0150, 0xd0a4, 0x0140, - 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd7d6, 0x004e, - 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, - 0x0904, 0x276e, 0x080c, 0x29f6, 0x0660, 0x9084, 0x0700, 0x908e, - 0x0600, 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, - 0x1120, 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, - 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, - 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, - 0x0004, 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, - 0x0040, 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, - 0x0058, 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847f, 0x928c, - 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, - 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x717f, 0x1118, 0x2009, - 0x1947, 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, - 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, - 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, - 0x0dfb, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, - 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, - 0x918e, 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, - 0x900e, 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, - 0x9108, 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, - 0x9108, 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, - 0x1000, 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, - 0x196a, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02, 0x0033, 0x00ee, - 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, 0x27cc, 0x27ea, 0x280e, - 0x2810, 0x2839, 0x283b, 0x283d, 0x2001, 0x0001, 0x080c, 0x2617, - 0x080c, 0x2a6a, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084, - 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001, - 0x196a, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c, - 0x82ec, 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974, - 0x2003, 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c, - 0x2003, 0x0001, 0x9006, 0x080c, 0x299b, 0x2001, 0xffff, 0x20a9, - 0x0009, 0x080c, 0x2a12, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009, - 0x001e, 0x2011, 0x283e, 0x080c, 0x82ec, 0x0005, 0x080c, 0x0e02, - 0x2001, 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003, - 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, - 0x2001, 0x0001, 0x080c, 0x299b, 0x2001, 0x1970, 0x2003, 0x0000, - 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001, 0x196a, - 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c, 0x82ec, - 0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02, 0x0005, 0x0006, 0x0016, - 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, - 0x0100, 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02, - 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, - 0x0005, 0x2860, 0x2880, 0x28c0, 0x28f0, 0x2914, 0x2924, 0x2926, - 0x080c, 0x2a06, 0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, - 0x1972, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, - 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x196a, 0x2003, 0x0001, - 0x0030, 0x080c, 0x294a, 0x2001, 0xffff, 0x080c, 0x27db, 0x0005, - 0x080c, 0x2928, 0x05e0, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a, - 0x080c, 0x2a06, 0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38, - 0x9294, 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104, - 0xc085, 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086, - 0x0005, 0x0118, 0x080c, 0x2930, 0x00c0, 0x200b, 0x0000, 0x7a38, - 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, - 0x0001, 0x080c, 0x29b8, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028, - 0x2001, 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fd, 0x0005, - 0x080c, 0x2928, 0x0560, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a, - 0x080c, 0x2a06, 0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001, - 0x196a, 0x2003, 0x0003, 0x2001, 0x196b, 0x2003, 0x0000, 0x00b8, - 0x2009, 0x1973, 0x2104, 0x9005, 0x1118, 0x080c, 0x296d, 0x0010, - 0x080c, 0x293d, 0x080c, 0x2930, 0x2009, 0x196f, 0x200b, 0x0000, - 0x2001, 0x196c, 0x2003, 0x0001, 0x080c, 0x27fd, 0x0000, 0x0005, - 0x04b9, 0x0508, 0x080c, 0x2a06, 0x11b8, 0x7850, 0x9084, 0xefff, - 0x7852, 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, - 0x0108, 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972, - 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419, 0x2001, 0x196c, 0x2003, - 0x0004, 0x080c, 0x2828, 0x0005, 0x0099, 0x0168, 0x080c, 0x2a06, - 0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c, 0x2814, 0x0018, - 0x0079, 0x080c, 0x2828, 0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02, - 0x2009, 0x1974, 0x2104, 0x8001, 0x200a, 0x090c, 0x2989, 0x0005, - 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, - 0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x7a38, 0x9294, 0x0006, - 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, - 0x299b, 0x0005, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086, - 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, - 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9, - 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, - 0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x0086, 0x2001, 0x1972, - 0x2004, 0x9084, 0x7fff, 0x090c, 0x0e02, 0x2009, 0x1971, 0x2144, - 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120, - 0x080c, 0x0e02, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e, - 0x0005, 0x0006, 0x0156, 0x2001, 0x196a, 0x20a9, 0x0009, 0x2003, - 0x0000, 0x8000, 0x1f04, 0x298f, 0x2001, 0x1971, 0x2003, 0x8000, - 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, - 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009, - 0x1977, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085, - 0x0006, 0x783a, 0x2009, 0x1978, 0x210c, 0x795a, 0x00fe, 0x0005, - 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0188, 0x7838, 0x9084, - 0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, 0x0100, 0x2004, 0x9086, - 0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, 0x7852, 0x0428, 0x7838, - 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x2001, 0x0100, 0x2004, - 0x9086, 0x000a, 0x11c8, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009, - 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c, - 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010, - 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, - 0x0064, 0x7820, 0x080c, 0x2ab0, 0xd09c, 0x1110, 0x1f04, 0x2a09, - 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, - 0x0100, 0x2004, 0x9086, 0x000a, 0x0170, 0x7850, 0x9085, 0x0040, - 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085, - 0x2000, 0x7852, 0x0020, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x000e, - 0x2008, 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, - 0x0001, 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, - 0x783b, 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, - 0x0000, 0x0006, 0x1d04, 0x2a4a, 0x080c, 0x830e, 0x1f04, 0x2a4a, - 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085, - 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x1000, - 0x7852, 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, - 0x012e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128, - 0x7850, 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bf5, 0x0005, - 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, - 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a82, 0x0028, - 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a88, 0x00fe, 0x015e, 0x000e, - 0x0005, 0x1d04, 0x2a91, 0x080c, 0x830e, 0x1f04, 0x2a91, 0x0005, - 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, - 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, - 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, - 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, - 0x1982, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, - 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, - 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, - 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186, - 0x0100, 0x1904, 0x2b29, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104, - 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c, - 0x0e87, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, - 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, - 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002, - 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c, - 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0, - 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, - 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104, - 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c, - 0x0e87, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc, - 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141, - 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091, - 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005, - 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003, - 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104, - 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040, - 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019, - 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800, - 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385, - 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016, - 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005, - 0x0016, 0x0026, 0x080c, 0x7199, 0x0108, 0xc0bc, 0x2009, 0x0140, - 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, - 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285, - 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, - 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, - 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128, - 0x080c, 0x7199, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e, - 0x000e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, - 0x6050, 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, - 0x080c, 0x2a91, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, - 0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0bc, 0x090c, 0x0e02, - 0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0ac, 0x090c, 0x0e02, - 0x2009, 0x1989, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, - 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, - 0x0100, 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006, - 0x0156, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, - 0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, - 0x1d04, 0x2c10, 0x080c, 0x830e, 0x1f04, 0x2c10, 0x6050, 0x9085, - 0x0400, 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e8b, - 0x2e8b, 0x2caf, 0x2caf, 0x2cbb, 0x2cbb, 0x2cc7, 0x2cc7, 0x2cd5, - 0x2cd5, 0x2ce1, 0x2ce1, 0x2cef, 0x2cef, 0x2cfd, 0x2cfd, 0x2d0f, - 0x2d0f, 0x2d1b, 0x2d1b, 0x2d29, 0x2d29, 0x2d47, 0x2d47, 0x2d67, - 0x2d67, 0x2d37, 0x2d37, 0x2d57, 0x2d57, 0x2d75, 0x2d75, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d87, - 0x2d87, 0x2d93, 0x2d93, 0x2da1, 0x2da1, 0x2daf, 0x2daf, 0x2dbf, - 0x2dbf, 0x2dcd, 0x2dcd, 0x2ddd, 0x2ddd, 0x2ded, 0x2ded, 0x2dff, - 0x2dff, 0x2e0d, 0x2e0d, 0x2e1d, 0x2e1d, 0x2e3f, 0x2e3f, 0x2e61, - 0x2e61, 0x2e2d, 0x2e2d, 0x2e50, 0x2e50, 0x2e70, 0x2e70, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, - 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2102, 0x0804, - 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c, - 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0xa001, 0x0cf0, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804, - 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x20c7, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c, - 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2771, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, 0x22c0, 0x0804, - 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2771, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2771, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x20c7, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2771, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, - 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0498, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x1371, 0x080c, 0x2102, - 0x0410, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2771, 0x080c, 0x1371, 0x080c, 0x2102, 0x0098, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, - 0x080c, 0x2102, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, - 0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, - 0x9026, 0x080c, 0x6688, 0x1904, 0x2f92, 0x72d8, 0x2001, 0x1956, - 0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, - 0x1904, 0x2f92, 0x080c, 0x2f97, 0x0804, 0x2f92, 0xd2cc, 0x1904, - 0x2f92, 0x080c, 0x717f, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f92, - 0xd294, 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x080c, 0x31ff, - 0x0160, 0x080c, 0xc444, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804, - 0x2f24, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2001, 0x1817, 0x203c, - 0x7290, 0xd284, 0x0904, 0x2f24, 0xd28c, 0x1904, 0x2f24, 0x0036, - 0x73a8, 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, - 0x1c80, 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, - 0x0010, 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590, - 0x908e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d, - 0x7292, 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010, - 0x080c, 0x66ee, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e, - 0x080c, 0x266e, 0x080c, 0x6344, 0x11c0, 0x080c, 0x66ca, 0x1168, - 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c4, - 0x0120, 0x080c, 0x2fb0, 0x0148, 0x0028, 0x080c, 0x30f0, 0x080c, - 0x2fdc, 0x0118, 0x8318, 0x0804, 0x2ed6, 0x73aa, 0x0010, 0x70ab, - 0xffff, 0x003e, 0x0804, 0x2f92, 0x9780, 0x3209, 0x203d, 0x97bc, - 0xff00, 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118, - 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, - 0x0020, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2700, 0x0156, 0x0016, - 0x9106, 0x0904, 0x2f87, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, - 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x2f8f, 0xc484, 0x080c, - 0x63a4, 0x0138, 0x080c, 0xc444, 0x1590, 0x080c, 0x6344, 0x15b8, - 0x0008, 0xc485, 0x080c, 0x66ca, 0x1130, 0x7030, 0xd08c, 0x01f8, - 0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, 0x080c, 0x66ca, - 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6368, 0x0028, - 0x080c, 0x317b, 0x01a0, 0x080c, 0x31a6, 0x0088, 0x080c, 0x30f0, - 0x080c, 0xc444, 0x1160, 0x080c, 0x2fdc, 0x0188, 0x0040, 0x080c, - 0xc444, 0x1118, 0x080c, 0x317b, 0x0110, 0x0451, 0x0140, 0x001e, - 0x8108, 0x015e, 0x1f04, 0x2f3d, 0x70ab, 0xffff, 0x0018, 0x001e, - 0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, - 0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, 0x6344, 0x1168, - 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30f0, 0x04a9, 0x0128, - 0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc18e, 0x001e, 0x00ce, 0x0005, - 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084, - 0x00ff, 0xb842, 0x080c, 0xa026, 0x01d0, 0x2b00, 0x6012, 0x080c, - 0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0000, - 0x080c, 0x62f5, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, - 0x012e, 0x2009, 0x0004, 0x080c, 0xa053, 0x9085, 0x0001, 0x00ce, - 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, - 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa026, - 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, - 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, - 0x080c, 0x30ab, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c, - 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126, 0x2091, 0x8000, - 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, 0x080c, 0xa053, - 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, - 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6344, 0x1140, 0xb813, - 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df, 0xffff, 0x002e, - 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, - 0x9f7f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0001, - 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126, - 0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, 0x2009, 0x0002, - 0x080c, 0xa053, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, - 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, - 0x080c, 0x6344, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8bf, - 0x0004, 0x080c, 0x9f7f, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, - 0x0001, 0x620a, 0x080c, 0xc1b7, 0x2009, 0x0022, 0x080c, 0xa053, - 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, - 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x878e, 0x080c, - 0x8718, 0x080c, 0x9e28, 0x080c, 0xaf75, 0x3e08, 0x2130, 0x81ff, - 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, - 0x0016, 0x080c, 0x63a4, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, - 0xd0bc, 0x1110, 0x080c, 0x5e4a, 0x001e, 0x8108, 0x1f04, 0x3090, - 0x9686, 0x0001, 0x190c, 0x31d3, 0x00be, 0x002e, 0x003e, 0x006e, - 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, - 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, - 0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x2c08, - 0x080c, 0xd53b, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcb0, 0x080c, - 0x5e4a, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, 0x002e, 0x003e, - 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, - 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, - 0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001, 0x70e2, 0x0ca8, - 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, - 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, - 0x20a9, 0x0001, 0x0070, 0x080c, 0x54dc, 0xd0c4, 0x0138, 0x0030, - 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd7d6, 0x20a9, 0x0800, - 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x315a, 0x928e, 0x007f, - 0x0904, 0x315a, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c, - 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968, 0x0006, 0x2003, - 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, - 0x2001, 0x0001, 0x080c, 0x6694, 0x00ce, 0x00be, 0x2019, 0x0029, - 0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x00b6, - 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, - 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, - 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xd53b, - 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3111, 0x015e, 0x001e, - 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x0046, 0x0026, 0x0016, 0x080c, 0x54dc, 0xd0c4, 0x0140, 0xd0a4, - 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x001e, - 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7290, - 0x82ff, 0x01e8, 0x080c, 0x66c2, 0x11d0, 0x2100, 0x080c, 0x26a1, - 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, - 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, - 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, - 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, 0x003e, - 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, - 0x1a88, 0x001e, 0x6112, 0x080c, 0x30ab, 0x001e, 0x080c, 0x6368, - 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, - 0x9abb, 0x080c, 0xda8f, 0x002e, 0x001e, 0x0005, 0x2001, 0x1836, - 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x717f, 0x1118, - 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x717f, 0x1110, - 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, - 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6368, 0x8108, - 0x1f04, 0x31e4, 0x2061, 0x1800, 0x607b, 0x0000, 0x607c, 0x9084, - 0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001, - 0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c, 0x2214, 0xd2ec, - 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, - 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, - 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, - 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, - 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, - 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, - 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, - 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, - 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, - 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, - 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, - 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, - 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, - 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, - 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, - 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, - 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, - 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, - 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, - 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, - 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, - 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, - 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, - 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, - 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, - 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, - 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, - 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18b8, 0x703f, - 0x18b8, 0x7007, 0x0001, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900, - 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x105c, 0x090c, - 0x0e02, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, - 0x2071, 0x189c, 0x7004, 0x0002, 0x3338, 0x3339, 0x334c, 0x3360, - 0x0005, 0x1004, 0x3349, 0x0e04, 0x3349, 0x2079, 0x0000, 0x0126, - 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, - 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b6, - 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, - 0x3434, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, - 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, - 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, - 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, - 0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, 0x2100, 0x908a, - 0x003f, 0x1a04, 0x3431, 0x61cc, 0x0804, 0x33c6, 0x3408, 0x3440, - 0x3431, 0x344c, 0x3456, 0x345c, 0x3460, 0x3470, 0x3474, 0x348a, - 0x3490, 0x3496, 0x34a1, 0x34ac, 0x34bb, 0x34ca, 0x34d8, 0x34ef, - 0x350a, 0x3431, 0x35b3, 0x35f1, 0x3697, 0x36a8, 0x36cb, 0x3431, - 0x3431, 0x3431, 0x3703, 0x371f, 0x3728, 0x3757, 0x375d, 0x3431, - 0x37a3, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x37ae, 0x37b7, - 0x37bf, 0x37c1, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, - 0x37ed, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x380a, 0x387e, - 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x0002, 0x38a8, - 0x38ab, 0x390a, 0x3923, 0x3953, 0x3bf5, 0x3431, 0x509f, 0x3431, - 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x348a, - 0x3490, 0x4178, 0x5500, 0x418e, 0x512e, 0x5180, 0x528b, 0x3431, - 0x52ed, 0x5329, 0x535a, 0x5462, 0x5387, 0x53e2, 0x3431, 0x4192, - 0x4337, 0x434d, 0x4372, 0x43d7, 0x444b, 0x446b, 0x44e2, 0x453e, - 0x459a, 0x459d, 0x45c2, 0x4637, 0x469d, 0x46a5, 0x47da, 0x4942, - 0x4976, 0x4bc0, 0x3431, 0x4bde, 0x4c9b, 0x4d78, 0x3431, 0x3431, - 0x3431, 0x3431, 0x4dde, 0x4df9, 0x46a5, 0x503f, 0x714c, 0x0000, - 0x2021, 0x4000, 0x080c, 0x49f4, 0x0126, 0x2091, 0x8000, 0x0e04, - 0x3412, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, - 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, - 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, - 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, - 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, - 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, - 0x81ff, 0x0d98, 0x0804, 0x4a01, 0x2039, 0x0001, 0x902e, 0x2520, - 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a04, 0x7984, 0x7888, - 0x2114, 0x200a, 0x0804, 0x3408, 0x7984, 0x2114, 0x0804, 0x3408, - 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, - 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3408, - 0x7884, 0x2060, 0x0804, 0x34bd, 0x2009, 0x0003, 0x2011, 0x0003, - 0x2019, 0x000f, 0x789b, 0x0317, 0x7893, 0xffff, 0x2001, 0x188d, - 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3408, 0x7897, 0x0001, - 0x0804, 0x3408, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3444, - 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182, - 0x0040, 0x0210, 0x0804, 0x343d, 0x2138, 0x7d98, 0x7c9c, 0x0804, - 0x3444, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d, 0x2138, - 0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182, 0x0040, 0x0210, - 0x0804, 0x343d, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, - 0x4004, 0x0804, 0x3408, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, - 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3408, - 0x0804, 0x3437, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d, - 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3408, - 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04, 0x343d, 0x8019, - 0x0904, 0x343d, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, - 0x9006, 0x685a, 0x685e, 0x080c, 0x74ac, 0x0804, 0x3408, 0x2069, - 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x343d, 0x8019, 0x0904, - 0x343d, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, - 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x67fa, 0x012e, - 0x0804, 0x3408, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x343a, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, - 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b8, 0x1120, 0x2009, - 0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x080c, 0x4a01, 0x701f, 0x352e, 0x0005, 0xa864, 0x2008, - 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, - 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, - 0x1904, 0x343a, 0x810f, 0x918c, 0x00ff, 0x0904, 0x343a, 0x7112, - 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b8, 0x1120, 0x2009, - 0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, - 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, - 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, - 0x4a01, 0x701f, 0x356c, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x343a, 0x0888, 0x7014, - 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3c, 0x0150, 0x0126, - 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x625a, - 0x1128, 0x7007, 0x0003, 0x701f, 0x3598, 0x0005, 0x080c, 0x6c6c, - 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, - 0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, - 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, - 0xaf60, 0x0804, 0x4a04, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, - 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, - 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, - 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, - 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, + 0xfbcf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x793a, + 0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830d, 0x1f04, 0x0c62, + 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x0040, + 0x20a9, 0x003a, 0x1d04, 0x0c72, 0x080c, 0x830d, 0x1f04, 0x0c72, + 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7489, + 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484, 0x080c, 0x747a, + 0x080c, 0x709e, 0x0020, 0x2009, 0x00f8, 0x080c, 0x5dab, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0168, 0x20a9, 0x0028, 0xa001, + 0x1f04, 0x0c97, 0x7850, 0x9085, 0x1400, 0x7852, 0x080c, 0x717e, + 0x0158, 0x0030, 0x7850, 0xc0e5, 0x7852, 0x080c, 0x717e, 0x0120, + 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, + 0x0d0c, 0x830d, 0x7820, 0xd09c, 0x1590, 0x080c, 0x717e, 0x0904, + 0x0d13, 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x080c, 0x71a1, 0x1538, + 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, + 0x080c, 0x2a97, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, + 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0d64, 0x8421, 0x1160, 0x1d04, 0x0cdf, 0x080c, 0x830d, 0x080c, + 0x7484, 0x080c, 0x747a, 0x7003, 0x0001, 0x0804, 0x0d34, 0x8319, + 0x1938, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1140, 0x2001, + 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d64, 0x1d04, + 0x0cfb, 0x080c, 0x830d, 0x2009, 0x1975, 0x2104, 0x9005, 0x0118, + 0x8001, 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, + 0x0002, 0x080c, 0x2a78, 0x7924, 0x080c, 0x2a97, 0xd19c, 0x0110, + 0x080c, 0x2974, 0x00e0, 0x080c, 0x718f, 0x1140, 0x94a2, 0x03e8, + 0x1128, 0x080c, 0x7156, 0x7003, 0x0001, 0x00b0, 0x7827, 0x1800, + 0x080c, 0x2a97, 0x7824, 0x080c, 0x7198, 0x0110, 0xd0ac, 0x1160, + 0x9084, 0x1800, 0x0904, 0x0ce7, 0x7003, 0x0001, 0x0028, 0x2001, + 0x0001, 0x080c, 0x2616, 0x00c0, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x1118, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c, + 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x7827, 0x0048, + 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x0120, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x1982, + 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, + 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, + 0x830d, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, + 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189c, 0x7004, + 0x9086, 0x0001, 0x1110, 0x080c, 0x331a, 0x00ee, 0x0005, 0x0005, + 0x2a70, 0x2061, 0x1986, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, + 0x0012, 0x600f, 0x0317, 0x2001, 0x1956, 0x900e, 0x2102, 0x7192, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705b, 0xffff, + 0x0008, 0x715a, 0x7063, 0xffff, 0x717a, 0x717e, 0x080c, 0xc1a1, + 0x70e7, 0x00c0, 0x2061, 0x1946, 0x6003, 0x0909, 0x6106, 0x600b, + 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a, + 0x601f, 0x07d0, 0x2061, 0x194e, 0x6003, 0x8000, 0x6106, 0x610a, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, + 0x2061, 0x1963, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, + 0x600f, 0x2020, 0x2001, 0x182b, 0x2102, 0x0005, 0x9016, 0x080c, + 0x63a3, 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, + 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, + 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, + 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, + 0x0e04, 0x0df8, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, + 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, + 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, + 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, + 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, + 0x2069, 0x1a7a, 0x7a08, 0x226a, 0x2069, 0x1a7b, 0x7a18, 0x226a, + 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1a88, 0x201a, 0x2019, + 0x1a8b, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, + 0x8318, 0x9386, 0x1aa0, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, + 0x2011, 0xdead, 0x2019, 0x1a89, 0x782c, 0x201a, 0x8318, 0x221a, + 0x7803, 0x0000, 0x2069, 0x1a5a, 0x901e, 0x20a9, 0x0020, 0x7b26, + 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e4f, 0x002e, 0x003e, + 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, - 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, - 0x0427, 0x81ff, 0x1904, 0x343a, 0x7984, 0x080c, 0x63a4, 0x1904, - 0x343d, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x343d, - 0x7c88, 0x7d8c, 0x080c, 0x6507, 0x080c, 0x64d6, 0x0000, 0x1518, + 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x54ea, 0x1108, + 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, + 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, + 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, + 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x2011, 0x0040, + 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x0c78, 0x0026, + 0x080c, 0x0f24, 0x1118, 0x2011, 0x0040, 0x0098, 0x2011, 0x010e, + 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, + 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70eb, 0x0000, 0x1120, 0x70eb, + 0x0fa0, 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f24, + 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, + 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x70eb, 0x0000, 0x080c, + 0x0f24, 0x1148, 0x080c, 0x2a8f, 0x1118, 0x2011, 0x8484, 0x0058, + 0x2011, 0x8282, 0x0040, 0x080c, 0x2a8f, 0x1118, 0x2011, 0xcdc5, + 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f29, 0x002e, 0x0005, 0x00e6, + 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e4, 0x1110, 0xc0e4, 0x0048, + 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70eb, 0x0000, + 0xc0e5, 0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, + 0xd0e4, 0x70e4, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0011, 0x00ee, + 0x0005, 0x70e6, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, 0x0ee6, + 0x0ebd, 0x0ebd, 0x0e9f, 0x0ecc, 0x0ebd, 0x0ebd, 0x0ecc, 0x0016, + 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, + 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x1839, 0x2004, 0xd0dc, + 0x0005, 0x9e86, 0x1800, 0x190c, 0x0df6, 0x70e4, 0xd0e4, 0x0108, + 0xc2e5, 0x72e6, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005, + 0x1d04, 0x0f38, 0x2091, 0x6000, 0x1f04, 0x0f38, 0x0005, 0x890e, + 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, + 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, + 0x0146, 0x0036, 0x0096, 0x2061, 0x188b, 0x600b, 0x0000, 0x600f, + 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, + 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, + 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, + 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, + 0x2001, 0x189b, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, + 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, + 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, + 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, + 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, + 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, + 0x0026, 0x0096, 0x3348, 0x080c, 0x0f3f, 0x2100, 0x9300, 0x2098, + 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, + 0x0001, 0x71b4, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, + 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, + 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x7078, 0x8007, 0x717c, + 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, + 0x080c, 0x0dd6, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, + 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, + 0x1069, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x10e2, 0x090c, 0x0df6, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, + 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, + 0x73bc, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, + 0x0df6, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0df6, 0xa000, 0x0c98, + 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, + 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x190e, 0x7010, + 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0df6, + 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70bc, 0x8001, 0x0270, + 0x70be, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, + 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70bc, 0x90ca, + 0x0040, 0x0268, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e, + 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, + 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, + 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, + 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, + 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, + 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, + 0x0040, 0x0c90, 0x2071, 0x188b, 0x7000, 0x9005, 0x11a0, 0x2001, + 0x0492, 0xa802, 0x2048, 0x2009, 0x2480, 0x8940, 0x2800, 0xa802, + 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, + 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, 0x7104, 0x7200, 0x82ff, + 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, + 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, + 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, + 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74ba, + 0x74be, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, + 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, + 0x9982, 0x0492, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, + 0x0800, 0x0250, 0x2071, 0x188b, 0x7010, 0x9902, 0x1228, 0x9085, + 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, + 0x19f5, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, + 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, + 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x1158, + 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1124, 0x702b, + 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x112d, + 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, + 0xa06f, 0x0000, 0x2071, 0x19f5, 0x701c, 0x9088, 0x19ff, 0x280a, + 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0df6, + 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, + 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, + 0x19f5, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, + 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, + 0x7007, 0x0006, 0x7000, 0x0002, 0x1176, 0x1174, 0x1174, 0x1174, + 0x12ed, 0x12ed, 0x12ed, 0x12ed, 0x080c, 0x0df6, 0x701c, 0x7120, + 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, + 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x19ff, 0x2004, 0x700a, + 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, + 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, + 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, + 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, + 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, + 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, + 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, + 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, + 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, + 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, + 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, + 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x19f5, + 0x2104, 0xc095, 0x200a, 0x080c, 0x1153, 0x0005, 0x0016, 0x00e6, + 0x2071, 0x19f5, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, + 0x0def, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, + 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1164, 0x120c, 0x1240, + 0x0df6, 0x0df6, 0x12f9, 0x0df6, 0x918c, 0x0700, 0x1550, 0x0136, + 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, + 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800, + 0x7802, 0x7804, 0x7806, 0x080c, 0x11a9, 0x0005, 0x7008, 0x0096, + 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1164, + 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, + 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802, + 0x7804, 0x7806, 0x080c, 0x11be, 0x0005, 0x7008, 0x0096, 0x2048, + 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008, + 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c, + 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, + 0x7008, 0x2048, 0x2001, 0x18b7, 0x2004, 0x9906, 0x1128, 0xa89c, + 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, + 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, + 0x008e, 0x00de, 0x009e, 0x080c, 0x1153, 0x0005, 0x00de, 0x009e, + 0x080c, 0x1153, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, + 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, + 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x6a15, 0xa09f, + 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1069, 0x009e, 0x0005, + 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100, + 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, + 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, + 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, + 0xb000, 0xa07a, 0x2810, 0x080c, 0x1134, 0x00e8, 0xa97c, 0xa894, + 0x0016, 0x0006, 0x080c, 0x6a15, 0x000e, 0x001e, 0xd1fc, 0x1138, + 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0x9fea, 0x00ce, 0x7008, + 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1069, 0x7007, + 0x0000, 0x080c, 0x1153, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, + 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, + 0x0005, 0x7007, 0x0000, 0x080c, 0x1164, 0x0005, 0x0126, 0x2091, + 0x2200, 0x2079, 0x0300, 0x2071, 0x1a3f, 0x7003, 0x0000, 0x78bf, + 0x00f6, 0x0419, 0x7803, 0x0003, 0x780f, 0x0000, 0x2001, 0x0100, + 0x2004, 0x9086, 0x000a, 0x0128, 0x20a9, 0x01e8, 0x2061, 0xdc0a, + 0x0020, 0x20a9, 0x01e8, 0x2061, 0xdfd8, 0x2c0d, 0x7912, 0xe104, + 0x9ce0, 0x0002, 0x7916, 0x1f04, 0x131d, 0x7807, 0x0007, 0x7803, + 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, + 0x7808, 0xd09c, 0x0110, 0x7820, 0x0cd8, 0x2001, 0x1a40, 0x2003, + 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, + 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, + 0x782b, 0x1a5a, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, 0x0200, + 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a5a, 0x602f, + 0x1cd0, 0x2001, 0x1819, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, + 0x1ebe, 0x783f, 0x31f3, 0x00ce, 0x0005, 0x0126, 0x2091, 0x2200, + 0x7908, 0x9184, 0x0070, 0x190c, 0x0def, 0xd19c, 0x0158, 0x7820, + 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0df6, 0x0023, + 0x012e, 0x0005, 0x012e, 0x0005, 0x13a0, 0x13a0, 0x13b7, 0x13bc, + 0x13c0, 0x13c5, 0x13ed, 0x13f1, 0x13ff, 0x1403, 0x13a0, 0x148f, + 0x1493, 0x1503, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, + 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13c7, + 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a4, 0x13a2, + 0x080c, 0x0df6, 0x080c, 0x0def, 0x080c, 0x150a, 0x2009, 0x1a56, + 0x2104, 0x8000, 0x200a, 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005, + 0x2009, 0x0048, 0x2060, 0x080c, 0xa068, 0x012e, 0x0005, 0x7004, + 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, + 0x080c, 0x150a, 0x080c, 0x15e4, 0x0005, 0x080c, 0x0df6, 0x080c, + 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, + 0x2009, 0x0048, 0x080c, 0xa068, 0x2001, 0x015d, 0x2003, 0x0000, + 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, + 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x150f, + 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, + 0x0005, 0x080c, 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, + 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, 0x080c, + 0x150a, 0x080c, 0x0df6, 0x080c, 0x150a, 0x080c, 0x147a, 0x7827, + 0x0018, 0x79ac, 0xd1dc, 0x0540, 0x7827, 0x0015, 0x7828, 0x782b, + 0x0000, 0x9065, 0x0138, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0400, 0x7004, 0x9005, 0x1180, 0x78ab, 0x0004, 0x7827, + 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0df6, 0x2001, 0x020d, + 0x2003, 0x0050, 0x2003, 0x0020, 0x0490, 0x78ab, 0x0004, 0x7803, + 0x0001, 0x080c, 0x1493, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, + 0x090c, 0x0df6, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, + 0x01a8, 0x080c, 0x7bec, 0x080c, 0x1977, 0x080c, 0xbd4e, 0x0158, + 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, + 0xa880, 0xc0bd, 0xa882, 0x080c, 0xb983, 0x0005, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xc13a, 0x2029, + 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x7dbc, 0x080c, 0xdbb3, 0xd5a4, 0x1118, 0x080c, 0x150f, 0x0005, + 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005, 0x781f, 0x0300, 0x7803, + 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, + 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, + 0x080c, 0x1580, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, + 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0df6, + 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, + 0x15c7, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x080c, 0x150f, 0x0005, 0x81ff, 0x190c, 0x0df6, 0x0005, + 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, + 0x14f8, 0x2071, 0x0200, 0x080c, 0x15bb, 0x080c, 0x15c7, 0x05a8, + 0x6014, 0x9005, 0x05a8, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, + 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1548, 0x601c, + 0xd084, 0x11d8, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x00a8, + 0x00f6, 0x2c78, 0x080c, 0x179b, 0x00fe, 0x2009, 0x01f4, 0x8109, + 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, + 0x2004, 0xd0ec, 0x1110, 0x0419, 0x0040, 0x2001, 0x020d, 0x2003, + 0x0020, 0x080c, 0x132d, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, + 0x080c, 0x15c7, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0069, 0x0c90, 0x0031, 0x2060, 0x2009, 0x0053, 0x080c, + 0xa068, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, + 0x147a, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, + 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, + 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, + 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, + 0x080c, 0x1572, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, + 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, + 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, + 0x7bec, 0x080c, 0x1977, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, + 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, + 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, + 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, + 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, 0x6802, + 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, + 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, 0x0005, + 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140, 0x0016, + 0x0026, 0x00c6, 0x080c, 0x1365, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118, + 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, + 0x080c, 0x0df6, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, + 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, + 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0df6, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, + 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x0005, 0x0006, + 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, + 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a57, 0x2404, + 0x8000, 0x0208, 0x2022, 0x080c, 0x7bec, 0x080c, 0x1977, 0x9006, + 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, + 0x0016, 0x2071, 0x0200, 0x0879, 0x6124, 0xd1dc, 0x01f8, 0x701c, + 0xd08c, 0x0904, 0x1646, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, + 0xd0bc, 0x0904, 0x1646, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, + 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1646, 0x9c06, 0x15f0, + 0x0126, 0x2091, 0x2600, 0x080c, 0x7b33, 0x012e, 0x7358, 0x745c, + 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x190c, 0xc115, 0xab42, 0xac3e, 0x2001, 0x187d, + 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, + 0xffff, 0x080c, 0x1ede, 0x1190, 0x080c, 0x17f8, 0x2a00, 0xa816, + 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, + 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, + 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x150f, 0x0005, 0x080c, + 0x0df6, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, + 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, + 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, + 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ebe, 0x2165, 0x0002, 0x1686, + 0x16d3, 0x1686, 0x1686, 0x1686, 0x16b5, 0x1686, 0x168a, 0x167f, + 0x16ca, 0x1686, 0x1686, 0x1686, 0x1790, 0x169e, 0x1694, 0xa964, + 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x16ca, 0x9085, 0x0001, + 0x0804, 0x1786, 0xa87c, 0xd0bc, 0x0dc8, 0xa890, 0xa842, 0xa88c, + 0xa83e, 0xa888, 0x0804, 0x16da, 0xa87c, 0xd0bc, 0x0d78, 0xa890, + 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1729, 0xa87c, 0xd0bc, + 0x0d28, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, + 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ebe, 0x2065, + 0xa888, 0xd19c, 0x1904, 0x1729, 0x0428, 0xa87c, 0xd0ac, 0x0970, + 0xa804, 0x9045, 0x090c, 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f, + 0x9d80, 0x1ebe, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, + 0x1729, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006, 0xa842, + 0xa83e, 0x0804, 0x1729, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006, + 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, + 0x001b, 0x0002, 0x16fd, 0x16fd, 0x16ff, 0x16fd, 0x16fd, 0x16fd, + 0x1705, 0x16fd, 0x16fd, 0x16fd, 0x170b, 0x16fd, 0x16fd, 0x16fd, + 0x1711, 0x16fd, 0x16fd, 0x16fd, 0x1717, 0x16fd, 0x16fd, 0x16fd, + 0x171d, 0x16fd, 0x16fd, 0x16fd, 0x1723, 0x080c, 0x0df6, 0xa574, + 0xa478, 0xa37c, 0xa280, 0x0804, 0x176e, 0xa584, 0xa488, 0xa38c, + 0xa290, 0x0804, 0x176e, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, + 0x176e, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x176e, 0xa5b4, + 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x176e, 0xa5c4, 0xa4c8, 0xa3cc, + 0xa2d0, 0x0804, 0x176e, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, + 0x176e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, + 0x0002, 0x174c, 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x1753, + 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x175a, 0x174a, 0x174a, + 0x174a, 0x174a, 0x174a, 0x1761, 0x174a, 0x174a, 0x174a, 0x174a, + 0x174a, 0x1768, 0x080c, 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678, + 0xa37c, 0xa280, 0x00d8, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, + 0xa298, 0x00a0, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, + 0x0068, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0030, + 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, + 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, + 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, + 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, + 0x0804, 0x1686, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, + 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, + 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1eb9, + 0xa813, 0x1eb9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, + 0x090c, 0x0df6, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0df6, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, + 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, + 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, + 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, + 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, + 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, + 0x0df6, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ebe, + 0x2015, 0x82ff, 0x090c, 0x0df6, 0xaa12, 0x2205, 0xa80a, 0x0c08, + 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x18ed, + 0x184f, 0x184f, 0x18ed, 0x18ed, 0x18e7, 0x18ed, 0x184f, 0x189e, + 0x189e, 0x189e, 0x18ed, 0x18ed, 0x18ed, 0x18e4, 0x189e, 0xc0fc, + 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x18ef, + 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, + 0x183b, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839, 0x183f, 0x1839, + 0x1839, 0x1839, 0x1839, 0x1839, 0x1843, 0x1839, 0x1839, 0x1839, + 0x1839, 0x1839, 0x1847, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839, + 0x184b, 0x080c, 0x0df6, 0xa774, 0xa678, 0x0804, 0x18ef, 0xa78c, + 0xa690, 0x0804, 0x18ef, 0xa7a4, 0xa6a8, 0x0804, 0x18ef, 0xa7bc, + 0xa6c0, 0x0804, 0x18ef, 0xa7d4, 0xa6d8, 0x0804, 0x18ef, 0x2c05, + 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1872, + 0x1872, 0x1874, 0x1872, 0x1872, 0x1872, 0x187a, 0x1872, 0x1872, + 0x1872, 0x1880, 0x1872, 0x1872, 0x1872, 0x1886, 0x1872, 0x1872, + 0x1872, 0x188c, 0x1872, 0x1872, 0x1872, 0x1892, 0x1872, 0x1872, + 0x1872, 0x1898, 0x080c, 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280, + 0x0804, 0x18ef, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x18ef, + 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x18ef, 0xa5a4, 0xa4a8, + 0xa3ac, 0xa2b0, 0x0804, 0x18ef, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, + 0x0804, 0x18ef, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x18ef, + 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x18ef, 0x2c05, 0x908a, + 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x18c1, 0x18bf, + 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18c8, 0x18bf, 0x18bf, 0x18bf, + 0x18bf, 0x18bf, 0x18cf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, + 0x18d6, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18dd, 0x080c, + 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0438, + 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0400, 0xa59c, + 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, + 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, + 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, + 0x1e7c, 0x1904, 0x17f8, 0x900e, 0x0050, 0x080c, 0x0df6, 0xab2e, + 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1e7c, 0x0005, + 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, + 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, + 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, + 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, + 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009, + 0x0048, 0x0804, 0xa068, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, + 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, + 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, + 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x1365, + 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, + 0x7808, 0xd09c, 0x190c, 0x1365, 0x00ce, 0x2001, 0x0038, 0x080c, + 0x1a07, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, + 0x0df6, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, + 0x1a16, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1a03, 0x7827, + 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, + 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x2001, 0xf000, + 0x8001, 0x090c, 0x0df6, 0x7aac, 0xd2ac, 0x1dd0, 0x00fe, 0x080c, + 0x717e, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, + 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, + 0x0059, 0x0804, 0x7246, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, + 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, + 0x2aa3, 0x2009, 0x003c, 0x080c, 0x2200, 0x2001, 0x015d, 0x2003, + 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x816f, 0x70a0, + 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, + 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x132d, 0x7803, 0x0001, + 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, + 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x717e, 0x1108, + 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, + 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, + 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, + 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001, + 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, + 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, + 0x621c, 0x080c, 0x1580, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, + 0x15ad, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, + 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, + 0x0040, 0x0904, 0x1a74, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, + 0x080c, 0x0df6, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, + 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, + 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, + 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, + 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1a0d, + 0x9186, 0x0040, 0x190c, 0x0df6, 0x00d6, 0x2069, 0x0200, 0x692c, + 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, + 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, + 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0df6, + 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x012e, 0x0005, 0x9280, 0x0005, + 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1b09, 0xa964, 0x9184, + 0x0007, 0x0002, 0x1a92, 0x1af4, 0x1aa9, 0x1aa9, 0x1aa9, 0x1adc, + 0x1abc, 0x1aab, 0x918c, 0x00ff, 0x9186, 0x0008, 0x1170, 0xa87c, + 0xd0b4, 0x0904, 0x1cbf, 0x9006, 0xa842, 0xa83e, 0xa988, 0x2900, + 0xa85a, 0xa813, 0x1eb9, 0x0804, 0x1b05, 0x9186, 0x0048, 0x0904, + 0x1af4, 0x080c, 0x0df6, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890, + 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, + 0xa84a, 0xa988, 0x0804, 0x1afc, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x001e, 0x1d38, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890, 0xa842, + 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, + 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe, + 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, + 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa804, 0xa85a, 0x2040, + 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa988, + 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, + 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, + 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, + 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, + 0x1d00, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9005, 0x1904, 0x1b61, + 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, + 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, + 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, + 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0x781a, 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040, + 0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116, + 0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940, + 0xa838, 0x9106, 0x1188, 0xa93c, 0xa834, 0x9106, 0x1168, 0x8aff, + 0x01a8, 0x0126, 0x2091, 0x8000, 0x00a1, 0x0108, 0x0091, 0x012e, + 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, + 0x080c, 0x1ede, 0x004e, 0x003e, 0x0d50, 0x0c98, 0x9085, 0x0001, + 0x0c80, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, + 0x0904, 0x1cb8, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, + 0x0a04, 0x1cb7, 0x9705, 0x0904, 0x1cb7, 0x903e, 0x2730, 0xa880, + 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1c9b, 0x1bdc, 0x1bdc, 0x1c9b, + 0x1c9b, 0x1c79, 0x1c9b, 0x1bdc, 0x1c7f, 0x1c2b, 0x1c2b, 0x1c9b, + 0x1c9b, 0x1c9b, 0x1c73, 0x1c2b, 0xc0fc, 0xa882, 0xab2c, 0xaa30, + 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1c9d, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bc8, 0x1bc6, 0x1bc6, + 0x1bc6, 0x1bc6, 0x1bc6, 0x1bcc, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, + 0x1bc6, 0x1bd0, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd4, + 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd8, 0x080c, 0x0df6, + 0xa774, 0xa678, 0x0804, 0x1c9d, 0xa78c, 0xa690, 0x0804, 0x1c9d, + 0xa7a4, 0xa6a8, 0x0804, 0x1c9d, 0xa7bc, 0xa6c0, 0x0804, 0x1c9d, + 0xa7d4, 0xa6d8, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0036, 0x1a0c, + 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bff, 0x1bff, 0x1c01, 0x1bff, + 0x1bff, 0x1bff, 0x1c07, 0x1bff, 0x1bff, 0x1bff, 0x1c0d, 0x1bff, + 0x1bff, 0x1bff, 0x1c13, 0x1bff, 0x1bff, 0x1bff, 0x1c19, 0x1bff, + 0x1bff, 0x1bff, 0x1c1f, 0x1bff, 0x1bff, 0x1bff, 0x1c25, 0x080c, + 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584, + 0xa488, 0xa38c, 0xa290, 0x0804, 0x1c9d, 0xa594, 0xa498, 0xa39c, + 0xa2a0, 0x0804, 0x1c9d, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, + 0x1c9d, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1c9d, 0xa5c4, + 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1c9d, 0xa5d4, 0xa4d8, 0xa3dc, + 0xa2e0, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, + 0x9082, 0x001b, 0x0002, 0x1c4e, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, + 0x1c4c, 0x1c56, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c5e, + 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c65, 0x1c4c, 0x1c4c, + 0x1c4c, 0x1c4c, 0x1c4c, 0x1c6c, 0x080c, 0x0df6, 0xa56c, 0xa470, + 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584, 0xa488, + 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1c9d, 0xa59c, 0xa4a0, + 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x04c0, 0xa5b4, 0xa4b8, 0xa7bc, + 0xa6c0, 0xa3c4, 0xa2c8, 0x0488, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, + 0xa3dc, 0xa2e0, 0x0450, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x1510, 0x080c, 0x1e7c, 0x1904, 0x1b77, 0x900e, 0x04c8, 0xab64, + 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, + 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1c2b, 0xab9c, 0x9016, + 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0040, 0x9386, 0x0008, 0x0904, + 0x1c2b, 0x080c, 0x0df6, 0x080c, 0x0df6, 0x7b12, 0x7a16, 0x7d02, + 0x7c06, 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, + 0xa83c, 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, + 0x700e, 0x7010, 0x9201, 0x7012, 0x080c, 0x1e7c, 0x0008, 0x9006, + 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, + 0x0df6, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1180, + 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, + 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x7004, 0x2060, + 0x00c6, 0x080c, 0xb983, 0x00ce, 0x2001, 0x19d1, 0x2004, 0x9c06, + 0x1160, 0x2009, 0x0040, 0x080c, 0x2200, 0x080c, 0x9a8f, 0x2011, + 0x0000, 0x080c, 0x992d, 0x080c, 0x8c6c, 0x002e, 0x0804, 0x1e2e, + 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, 0x792c, 0x782b, 0x0002, + 0x9184, 0x0700, 0x1904, 0x1cc1, 0x7000, 0x0002, 0x1e2e, 0x1d12, + 0x1d7f, 0x1e2c, 0x8001, 0x7002, 0xd19c, 0x1150, 0x8aff, 0x05b0, + 0x080c, 0x1b71, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804, 0x1e2e, + 0x782b, 0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, + 0x11d8, 0xa87c, 0xc0f5, 0xa87e, 0x00b8, 0x0026, 0x0036, 0xab3c, + 0xaa40, 0x7810, 0xa82e, 0x931a, 0x7814, 0xa832, 0x9213, 0x7800, + 0xa81e, 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, + 0x1e94, 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, + 0x2c00, 0xa812, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x00f6, 0x0026, + 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, + 0x1984, 0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319, + 0x090c, 0x0df6, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, + 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, + 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x002e, + 0x00fe, 0x782b, 0x0008, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x8001, + 0x7002, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1d05, 0xd19c, + 0x1904, 0x1e2a, 0x8aff, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804, + 0x1e2e, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x1e94, 0xdd9c, + 0x1904, 0x1de9, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, + 0x001b, 0x0002, 0x1dbd, 0x1dbd, 0x1dbf, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1dc5, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dcb, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1dd1, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dd7, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1ddd, 0x1dbd, 0x1dbd, 0x1dbd, 0x1de3, 0x080c, 0x0df6, 0xa07c, + 0x931a, 0xa080, 0x9213, 0x0804, 0x1d31, 0xa08c, 0x931a, 0xa090, + 0x9213, 0x0804, 0x1d31, 0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804, + 0x1d31, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0bc, + 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1d31, 0xa0cc, 0x931a, 0xa0d0, + 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, + 0x1d31, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, + 0x0002, 0x1e0c, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e12, + 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e18, 0x1e0a, 0x1e0a, + 0x1e0a, 0x1e0a, 0x1e0a, 0x1e1e, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, + 0x1e0a, 0x1e24, 0x080c, 0x0df6, 0xa07c, 0x931a, 0xa080, 0x9213, + 0x0804, 0x1d31, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, 0x1d31, + 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0c4, 0x931a, + 0xa0c8, 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213, + 0x0804, 0x1d31, 0x0804, 0x1d2d, 0x080c, 0x0df6, 0x012e, 0x0005, + 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9086, 0x0000, 0x0904, + 0x1e79, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, + 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xdbfc, + 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0df6, 0x0016, 0x2009, + 0x0040, 0x080c, 0x2200, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, + 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1d00, + 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac, + 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003, + 0x0000, 0x00ee, 0x00fe, 0x0005, 0x8c60, 0x2c05, 0x9005, 0x0110, + 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, + 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2065, 0x8cff, 0x090c, 0x0df6, + 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8c61, 0x2c05, 0x9005, + 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, 0x2900, + 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ece, 0x2065, + 0x8cff, 0x090c, 0x0df6, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, + 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, + 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1eb1, + 0x1ead, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb1, 0x1eb8, 0x1eb8, + 0x1eb5, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb8, 0x0000, 0x1eb3, + 0x1eb3, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb3, 0x1eb9, 0x1eb9, + 0x1eb9, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb9, 0x00c6, 0x00d6, + 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20bd, 0x2940, + 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, + 0x2061, 0x1eb9, 0x00d0, 0x9de0, 0x1ebe, 0x9d86, 0x0007, 0x0130, + 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20bd, + 0xa004, 0x9045, 0x0904, 0x20bd, 0x08d8, 0x2c05, 0x9005, 0x0904, + 0x1fa5, 0xdd9c, 0x1904, 0x1f61, 0x908a, 0x0036, 0x1a0c, 0x0df6, + 0x9082, 0x001b, 0x0002, 0x1f36, 0x1f36, 0x1f38, 0x1f36, 0x1f36, + 0x1f36, 0x1f3e, 0x1f36, 0x1f36, 0x1f36, 0x1f44, 0x1f36, 0x1f36, + 0x1f36, 0x1f4a, 0x1f36, 0x1f36, 0x1f36, 0x1f50, 0x1f36, 0x1f36, + 0x1f36, 0x1f56, 0x1f36, 0x1f36, 0x1f36, 0x1f5c, 0x080c, 0x0df6, + 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1f9b, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x0804, 0x1f9b, 0xa09c, 0x9422, 0xa0a0, 0x931b, + 0x0804, 0x1f9b, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1f9b, + 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1f9b, 0xa0cc, 0x9422, + 0xa0d0, 0x931b, 0x0804, 0x1f9b, 0xa0dc, 0x9422, 0xa0e0, 0x931b, + 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, + 0x1f83, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f88, 0x1f81, + 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f8d, 0x1f81, 0x1f81, 0x1f81, + 0x1f81, 0x1f81, 0x1f92, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81, + 0x1f97, 0x080c, 0x0df6, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, + 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, + 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, + 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51, + 0x0904, 0x20bd, 0x8c60, 0x0804, 0x1f0d, 0xa004, 0x9045, 0x0904, + 0x20bd, 0x0804, 0x1ee8, 0x8a51, 0x0904, 0x20bd, 0x8c60, 0x2c05, + 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20bd, 0xa064, 0x90ec, + 0x000f, 0x9de0, 0x1ebe, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, + 0x0804, 0x20b2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, + 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x204f, 0x9082, 0x001b, 0x0002, + 0x1feb, 0x1feb, 0x1fed, 0x1feb, 0x1feb, 0x1feb, 0x1ffb, 0x1feb, + 0x1feb, 0x1feb, 0x2009, 0x1feb, 0x1feb, 0x1feb, 0x2017, 0x1feb, + 0x1feb, 0x1feb, 0x2025, 0x1feb, 0x1feb, 0x1feb, 0x2033, 0x1feb, + 0x1feb, 0x1feb, 0x2041, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa074, 0x9420, 0xa078, + 0x9319, 0x0804, 0x20ad, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, + 0x911b, 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, + 0x20ad, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20ad, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0a4, + 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20ad, 0xa1bc, 0x2400, 0x9122, + 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8, + 0x9319, 0x0804, 0x20ad, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, + 0x911b, 0x0a0c, 0x0df6, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, + 0x20ad, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20ad, 0x9082, + 0x001b, 0x0002, 0x206d, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b, + 0x207a, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b, 0x2087, 0x206b, + 0x206b, 0x206b, 0x206b, 0x206b, 0x2094, 0x206b, 0x206b, 0x206b, + 0x206b, 0x206b, 0x20a1, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa06c, 0x9420, 0xa070, + 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, + 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa09c, + 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, + 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8, 0x9319, + 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880, + 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, + 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, + 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c, + 0x0def, 0x9084, 0x0007, 0x0002, 0x20de, 0x1d00, 0x20de, 0x20d4, + 0x20d7, 0x20da, 0x20d7, 0x20da, 0x080c, 0x1d00, 0x0005, 0x080c, + 0x11ee, 0x0005, 0x080c, 0x1d00, 0x080c, 0x11ee, 0x0005, 0x0126, + 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, + 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, + 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, + 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, + 0x781c, 0xd0a4, 0x190c, 0x21fd, 0x7900, 0xd1dc, 0x1118, 0x9084, + 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2125, 0x211d, 0x7b33, + 0x211d, 0x211f, 0x211f, 0x211f, 0x211f, 0x7b19, 0x211d, 0x2121, + 0x211d, 0x211f, 0x211d, 0x211f, 0x211d, 0x080c, 0x0df6, 0x0031, + 0x0020, 0x080c, 0x7b19, 0x080c, 0x7b33, 0x0005, 0x0006, 0x0016, + 0x0026, 0x080c, 0xdbfc, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001, + 0x19d1, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005, + 0x090c, 0x0df6, 0x00c6, 0x2001, 0x19d1, 0x2064, 0x080c, 0xb983, + 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2200, 0x00d0, 0x9184, + 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x717e, + 0x1138, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010, + 0x080c, 0x5cee, 0x080c, 0x7be2, 0x0041, 0x0018, 0x9184, 0x9540, + 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, + 0x0056, 0x2071, 0x1a3f, 0x080c, 0x1977, 0x005e, 0x004e, 0x003e, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, + 0x2001, 0x1949, 0x2102, 0x2001, 0x1951, 0x2102, 0x2001, 0x013b, + 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, + 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, + 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, + 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, + 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, + 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, + 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, + 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, + 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, + 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, + 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, + 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, + 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, + 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0def, + 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, + 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a9d, 0x080c, 0x2974, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0558, 0x6054, 0x8004, + 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150, 0x918c, 0xfff3, + 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085, 0x2000, 0x6052, + 0x2009, 0x1977, 0x2011, 0x1978, 0x6358, 0x939c, 0x38f0, 0x2320, + 0x080c, 0x29e1, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603, 0x230a, + 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a, 0x2412, + 0x0050, 0x2001, 0x1977, 0x2003, 0x0700, 0x2001, 0x1978, 0x2003, + 0x0700, 0x080c, 0x2ba9, 0x9006, 0x080c, 0x29a3, 0x9006, 0x080c, + 0x2986, 0x20a9, 0x0012, 0x1d04, 0x2263, 0x2091, 0x6000, 0x1f04, + 0x2263, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, + 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x26a6, 0x2009, + 0x00ef, 0x6132, 0x6136, 0x080c, 0x26b6, 0x60e7, 0x0000, 0x61ea, + 0x60e3, 0x0002, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, + 0x602f, 0x0000, 0x6007, 0x149f, 0x60bb, 0x0000, 0x20a9, 0x0018, + 0x60bf, 0x0000, 0x1f04, 0x2290, 0x60bb, 0x0000, 0x60bf, 0x0108, + 0x60bf, 0x0012, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, + 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402f, 0x012e, 0x0005, + 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, + 0x0000, 0x00fe, 0x0005, 0x2001, 0x1834, 0x2003, 0x0000, 0x2001, + 0x1833, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x6124, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, + 0x002a, 0x9195, 0x0004, 0x9284, 0x0007, 0x0002, 0x22f0, 0x22d6, + 0x22d9, 0x22dc, 0x22e1, 0x22e3, 0x22e7, 0x22eb, 0x080c, 0x84e2, + 0x00b8, 0x080c, 0x85b1, 0x00a0, 0x080c, 0x85b1, 0x080c, 0x84e2, + 0x0078, 0x0099, 0x0068, 0x080c, 0x84e2, 0x0079, 0x0048, 0x080c, + 0x85b1, 0x0059, 0x0028, 0x080c, 0x85b1, 0x080c, 0x84e2, 0x0029, + 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, + 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2547, 0xd1f4, 0x190c, 0x0def, + 0x080c, 0x717e, 0x0904, 0x234b, 0x080c, 0xc459, 0x1120, 0x7000, + 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800, 0x0550, 0x080c, + 0x71a1, 0x0118, 0x080c, 0x718f, 0x1520, 0x6027, 0x0020, 0x6043, + 0x0000, 0x080c, 0xc459, 0x0168, 0x080c, 0x71a1, 0x1150, 0x2001, + 0x1982, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x6fed, 0x0804, + 0x254a, 0x70a0, 0x9005, 0x1150, 0x70a3, 0x0001, 0x00d6, 0x2069, + 0x0140, 0x080c, 0x71d2, 0x00de, 0x1904, 0x254a, 0x080c, 0x7484, + 0x0428, 0x080c, 0x71a1, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, + 0x0468, 0x080c, 0x7484, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, + 0x709e, 0x0804, 0x2547, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, + 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7094, 0x9086, + 0x0029, 0x1110, 0x080c, 0x7369, 0x0804, 0x2547, 0x080c, 0x747f, + 0x0048, 0x2001, 0x1957, 0x2003, 0x0002, 0x0020, 0x080c, 0x72cd, + 0x0804, 0x2547, 0x080c, 0x7403, 0x0804, 0x2547, 0xd1ac, 0x0904, + 0x2468, 0x080c, 0x717e, 0x11c0, 0x6027, 0x0020, 0x0006, 0x0026, + 0x0036, 0x080c, 0x7198, 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f, + 0x080c, 0x709e, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e, + 0x002e, 0x000e, 0x080c, 0x7156, 0x0016, 0x0046, 0x00c6, 0x644c, + 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, + 0x6043, 0x0010, 0x74d6, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190, + 0x080c, 0xc459, 0x1118, 0x9186, 0xf800, 0x1160, 0x7044, 0xd084, + 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, + 0x4a17, 0x003e, 0x080c, 0xc452, 0x1904, 0x2445, 0x9196, 0xff00, + 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, + 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x31ee, 0x0128, 0xc18d, + 0x7132, 0x080c, 0x66c1, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, + 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, + 0x0904, 0x2445, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, + 0xd1ac, 0x1904, 0x2445, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, + 0x8013, 0x080c, 0x4a17, 0x003e, 0x0804, 0x2445, 0x7038, 0xd08c, + 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2445, 0xc1ad, + 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a17, 0x003e, + 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, 0x0016, + 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x2019, 0x000e, + 0x00c6, 0x2061, 0x0000, 0x080c, 0xd7af, 0x00ce, 0x9484, 0x00ff, + 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, + 0x2009, 0x000e, 0x080c, 0xd837, 0x001e, 0xd1ac, 0x1148, 0x0016, + 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e, 0x00a8, + 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3, 0x1140, + 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49, + 0x8108, 0x1f04, 0x2435, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, + 0x9f70, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, + 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c, + 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, + 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027, 0x0020, + 0xd194, 0x0904, 0x2547, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x24f0, + 0x080c, 0x82d9, 0x080c, 0x961a, 0x6027, 0x0004, 0x00f6, 0x2019, + 0x19cb, 0x2304, 0x907d, 0x0904, 0x24bf, 0x7804, 0x9086, 0x0032, + 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c, + 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, + 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, + 0x2b7f, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, + 0x2a78, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x8a83, 0x080c, 0x8b8f, + 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fea, 0x009e, + 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, + 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, + 0x2b7f, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c, 0xc459, + 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, + 0x8000, 0x602a, 0x00ce, 0x080c, 0x95f6, 0x0804, 0x2546, 0x2061, + 0x0100, 0x62c0, 0x080c, 0x9df6, 0x2019, 0x19cb, 0x2304, 0x9065, + 0x0120, 0x2009, 0x0027, 0x080c, 0xa068, 0x00ce, 0x0804, 0x2546, + 0xd2bc, 0x0904, 0x2533, 0x080c, 0x82e6, 0x6014, 0x9084, 0x1984, + 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, + 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f, 0x00de, 0x00c6, + 0x2061, 0x19c2, 0x6044, 0x080c, 0xc459, 0x0120, 0x909a, 0x0003, + 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046, 0x603c, + 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82de, 0x9080, + 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984, + 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984, 0x918d, + 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036, 0x2019, + 0x0001, 0x080c, 0x98b1, 0x003e, 0x2019, 0x19d1, 0x2304, 0x9065, + 0x0120, 0x2009, 0x004f, 0x080c, 0xa068, 0x00ce, 0x001e, 0xd19c, + 0x0904, 0x2611, 0x7038, 0xd0ac, 0x1904, 0x25e6, 0x0016, 0x0156, + 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0904, + 0x25c3, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, + 0x6052, 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, + 0x1d04, 0x2568, 0x080c, 0x830d, 0x1f04, 0x2568, 0x6050, 0x9085, + 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001, 0x1f04, + 0x2576, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, + 0x257f, 0x080c, 0x830d, 0x6020, 0xd09c, 0x1138, 0x015e, 0x6152, + 0x001e, 0x6027, 0x0008, 0x0804, 0x2611, 0x080c, 0x2a5f, 0x1f04, + 0x257f, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028, + 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb, + 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452, + 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f, + 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003, + 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f, + 0x001e, 0x0804, 0x2611, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6050, + 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25e4, 0x1d04, 0x25ce, + 0x080c, 0x830d, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x29f1, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, 0x6027, + 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016, 0x6028, + 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb, + 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452, + 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f, + 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003, + 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f, + 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2665, 0x81ff, 0x01a0, + 0x2009, 0x0000, 0x080c, 0x2a9d, 0x2011, 0x8011, 0x2019, 0x010e, + 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, + 0x0000, 0x080c, 0x4a17, 0x0448, 0x2001, 0x1983, 0x200c, 0x81ff, + 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, + 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a17, 0x080c, 0x0ecc, + 0x080c, 0x54df, 0xd0fc, 0x1188, 0x080c, 0xc452, 0x1170, 0x00c6, + 0x080c, 0x2701, 0x080c, 0x9818, 0x2061, 0x0100, 0x2019, 0x0028, + 0x2009, 0x0002, 0x080c, 0x3060, 0x00ce, 0x012e, 0x00fe, 0x00ee, + 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, + 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214, 0xd2ac, + 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106, 0x1190, + 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, + 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, + 0x9206, 0x1120, 0x2500, 0x080c, 0x7e3f, 0x0048, 0x9584, 0x00ff, + 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, + 0x9080, 0x31f3, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, + 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, + 0x6852, 0x6856, 0x1f04, 0x26b1, 0x00de, 0x0005, 0x0006, 0x00d6, + 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114, 0x8214, + 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, + 0x1128, 0x9184, 0x000f, 0x9080, 0xe3a6, 0x2005, 0x6856, 0x8211, + 0x1f04, 0x26c6, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, + 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, + 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, + 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, + 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, + 0x26f6, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, + 0x0005, 0x080c, 0x54db, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, + 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd837, 0x004e, 0x0005, + 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, + 0x276d, 0x080c, 0x29e1, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, + 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, + 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, + 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, + 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, + 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, + 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, + 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847e, 0x928c, 0xff00, + 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, + 0x2009, 0x0138, 0x220a, 0x080c, 0x717e, 0x1118, 0x2009, 0x1947, + 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, + 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0def, + 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, + 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, + 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, + 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, + 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, + 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, + 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x196a, + 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0033, 0x00ee, 0x002e, + 0x001e, 0x000e, 0x015e, 0x0005, 0x27cb, 0x27e9, 0x280d, 0x280f, + 0x2838, 0x283a, 0x283c, 0x2001, 0x0001, 0x080c, 0x2616, 0x080c, + 0x2a51, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, + 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a, + 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb, + 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974, 0x2003, + 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c, 0x2003, + 0x0001, 0x9006, 0x080c, 0x2986, 0x2001, 0xffff, 0x20a9, 0x0009, + 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009, 0x001e, + 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005, 0x080c, 0x0df6, 0x2001, + 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x2986, 0x2001, 0x1970, 0x2003, 0x0000, 0x2001, + 0xffff, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003, + 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005, + 0x080c, 0x0df6, 0x080c, 0x0df6, 0x0005, 0x0006, 0x0016, 0x0026, + 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, + 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0043, + 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, + 0x285f, 0x287b, 0x28b7, 0x28e3, 0x2903, 0x290f, 0x2911, 0x080c, + 0x29f1, 0x1190, 0x2009, 0x1972, 0x2104, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, + 0x196a, 0x2003, 0x0001, 0x0030, 0x080c, 0x2935, 0x2001, 0xffff, + 0x080c, 0x27da, 0x0005, 0x080c, 0x2913, 0x05c0, 0x2009, 0x1973, + 0x2104, 0x8001, 0x200a, 0x080c, 0x29f1, 0x1158, 0x7a38, 0x9294, + 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104, 0xc085, + 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, + 0x0118, 0x080c, 0x291b, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, + 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x29a3, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028, 0x2001, + 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fc, 0x0005, 0x080c, + 0x2913, 0x0540, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a, 0x080c, + 0x29f1, 0x1148, 0x2001, 0x196a, 0x2003, 0x0003, 0x2001, 0x196b, + 0x2003, 0x0000, 0x00b8, 0x2009, 0x1973, 0x2104, 0x9005, 0x1118, + 0x080c, 0x2958, 0x0010, 0x080c, 0x2928, 0x080c, 0x291b, 0x2009, + 0x196f, 0x200b, 0x0000, 0x2001, 0x196c, 0x2003, 0x0001, 0x080c, + 0x27fc, 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x29f1, 0x1198, + 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, + 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972, 0x2104, + 0xc0fd, 0x200a, 0x0038, 0x00f9, 0x2001, 0x196c, 0x2003, 0x0004, + 0x080c, 0x2827, 0x0005, 0x0079, 0x0148, 0x080c, 0x29f1, 0x1118, + 0x080c, 0x2813, 0x0018, 0x0079, 0x080c, 0x2827, 0x0005, 0x080c, + 0x0df6, 0x080c, 0x0df6, 0x2009, 0x1974, 0x2104, 0x8001, 0x200a, + 0x090c, 0x2974, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005, + 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, + 0x2001, 0x0001, 0x080c, 0x2986, 0x0005, 0x2009, 0x196f, 0x2104, + 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, + 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, + 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005, + 0x0086, 0x2001, 0x1972, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0df6, + 0x2009, 0x1971, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, + 0x1120, 0xd084, 0x1120, 0x080c, 0x0df6, 0x9006, 0x0010, 0x2001, + 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x196a, + 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x297a, 0x2001, + 0x1971, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, + 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, + 0x0004, 0x783a, 0x2009, 0x1977, 0x210c, 0x795a, 0x0050, 0x7838, + 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x1978, 0x210c, + 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, + 0x0188, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, + 0x7852, 0x0428, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x11c8, 0x7850, 0x9084, + 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, + 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, + 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, + 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a97, 0xd09c, + 0x1110, 0x1f04, 0x29f4, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, + 0x2091, 0x8000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0170, + 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, + 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x0000, 0x000e, 0x2008, + 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, + 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, + 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, + 0x0006, 0x1d04, 0x2a31, 0x080c, 0x830d, 0x1f04, 0x2a31, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085, 0x0400, + 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x1000, 0x7852, + 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, 0x012e, + 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128, 0x7850, + 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bdc, 0x0005, 0x0006, + 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, + 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a69, 0x0028, 0x7854, + 0xd08c, 0x1110, 0x1f04, 0x2a6f, 0x00fe, 0x015e, 0x000e, 0x0005, + 0x1d04, 0x2a78, 0x080c, 0x830d, 0x1f04, 0x2a78, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001, + 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x1983, + 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, + 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a, + 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, + 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186, 0x0100, + 0x1904, 0x2b10, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104, 0x8000, + 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c, 0x0e7b, + 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, 0x2104, + 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, 0x9086, + 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002, 0x233c, + 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c, 0x8738, + 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0, 0x19d0, + 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, 0x918c, + 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104, 0xc0dd, + 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c, 0x0e7b, + 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc, 0x01b0, + 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141, 0x2004, + 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091, 0x8000, + 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005, 0x00c6, + 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003, 0x0000, + 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104, 0x918e, + 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040, 0x04b9, + 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019, 0x0141, + 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800, 0x0dc0, + 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385, 0x0009, + 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016, 0x003e, + 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005, 0x0016, + 0x0026, 0x080c, 0x7198, 0x0108, 0xc0bc, 0x2009, 0x0140, 0x2114, + 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285, 0x1000, + 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, + 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, + 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128, 0x080c, + 0x7198, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e, 0x000e, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, + 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, + 0x2a78, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, + 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0bc, 0x090c, 0x0df6, 0x20a9, + 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0ac, 0x090c, 0x0df6, 0x2009, + 0x198a, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, + 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006, 0x0156, + 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, + 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, + 0x2bf7, 0x080c, 0x830d, 0x1f04, 0x2bf7, 0x6050, 0x9085, 0x0400, + 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e72, 0x2e72, + 0x2c96, 0x2c96, 0x2ca2, 0x2ca2, 0x2cae, 0x2cae, 0x2cbc, 0x2cbc, + 0x2cc8, 0x2cc8, 0x2cd6, 0x2cd6, 0x2ce4, 0x2ce4, 0x2cf6, 0x2cf6, + 0x2d02, 0x2d02, 0x2d10, 0x2d10, 0x2d2e, 0x2d2e, 0x2d4e, 0x2d4e, + 0x2d1e, 0x2d1e, 0x2d3e, 0x2d3e, 0x2d5c, 0x2d5c, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2d6e, 0x2d6e, + 0x2d7a, 0x2d7a, 0x2d88, 0x2d88, 0x2d96, 0x2d96, 0x2da6, 0x2da6, + 0x2db4, 0x2db4, 0x2dc4, 0x2dc4, 0x2dd4, 0x2dd4, 0x2de6, 0x2de6, + 0x2df4, 0x2df4, 0x2e04, 0x2e04, 0x2e26, 0x2e26, 0x2e48, 0x2e48, + 0x2e14, 0x2e14, 0x2e37, 0x2e37, 0x2e57, 0x2e57, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20fe, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0xa001, 0x0cf0, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20c3, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2770, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20c3, 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0498, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2770, 0x080c, 0x20c3, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0410, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2770, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0098, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2770, 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x080c, + 0x20fe, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, + 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, + 0x080c, 0x6687, 0x1904, 0x2f7c, 0x72d8, 0x2001, 0x1956, 0x2004, + 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, + 0x2f7c, 0x080c, 0x2f81, 0x0804, 0x2f7c, 0xd2cc, 0x1904, 0x2f7c, + 0x080c, 0x717e, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0xd294, + 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x080c, 0x31e9, 0x0160, + 0x080c, 0xc459, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804, 0x2f0b, + 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2001, 0x1817, 0x203c, 0x7290, + 0xd284, 0x0904, 0x2f0b, 0xd28c, 0x1904, 0x2f0b, 0x0036, 0x73a8, + 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, + 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, + 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590, 0x908e, + 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d, 0x7292, + 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010, 0x080c, + 0x66ed, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e, 0x080c, + 0x266d, 0x080c, 0x6343, 0x11c0, 0x080c, 0x66c9, 0x1168, 0x7030, + 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c3, 0x0120, + 0x080c, 0x2f9a, 0x0148, 0x0028, 0x080c, 0x30da, 0x080c, 0x2fc6, + 0x0118, 0x8318, 0x0804, 0x2ebd, 0x73aa, 0x0010, 0x70ab, 0xffff, + 0x003e, 0x0804, 0x2f7c, 0x9780, 0x31f3, 0x203d, 0x97bc, 0xff00, + 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118, 0x900e, + 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, + 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2700, 0x0156, 0x0016, 0x9106, + 0x0904, 0x2f71, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, + 0x0120, 0x2009, 0xffff, 0x0804, 0x2f79, 0xc484, 0x080c, 0x63a3, + 0x0150, 0x080c, 0xc459, 0x15a8, 0x080c, 0x31e9, 0x1590, 0x080c, + 0x6343, 0x15b8, 0x0008, 0xc485, 0x080c, 0x66c9, 0x1130, 0x7030, + 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, + 0x080c, 0x66c9, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, + 0x6367, 0x0028, 0x080c, 0x3165, 0x01a0, 0x080c, 0x3190, 0x0088, + 0x080c, 0x30da, 0x080c, 0xc459, 0x1160, 0x080c, 0x2fc6, 0x0188, + 0x0040, 0x080c, 0xc459, 0x1118, 0x080c, 0x3165, 0x0110, 0x0451, + 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2f24, 0x70ab, 0xffff, + 0x0018, 0x001e, 0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be, + 0x0005, 0x00c6, 0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, + 0x6343, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30da, + 0x04a9, 0x0128, 0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc1a1, 0x001e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, + 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa03b, 0x01d0, 0x2b00, + 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0, + 0x2001, 0x0000, 0x080c, 0x62f4, 0x0126, 0x2091, 0x8000, 0x70a4, + 0x8000, 0x70a6, 0x012e, 0x2009, 0x0004, 0x080c, 0xa068, 0x9085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, + 0x080c, 0xa03b, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, + 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x1110, 0x080c, 0x3095, 0x080c, 0xc1ca, 0x6023, 0x0001, + 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x0126, + 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, + 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6343, + 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df, + 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, + 0x00c6, 0x080c, 0x9f94, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1ca, + 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, + 0x62f4, 0x0126, 0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, + 0x2009, 0x0002, 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de, + 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2009, 0x007f, 0x080c, 0x6343, 0x11b8, 0xb813, 0x00ff, 0xb817, + 0xfffd, 0xb8bf, 0x0004, 0x080c, 0x9f94, 0x0170, 0x2b00, 0x6012, + 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xc1ca, 0x2009, 0x0022, + 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, + 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, + 0x878d, 0x080c, 0x8717, 0x080c, 0x9e3d, 0x080c, 0xaf81, 0x3e08, + 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1140, 0x9686, 0x0002, + 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49, 0x001e, 0x8108, + 0x1f04, 0x307a, 0x9686, 0x0001, 0x190c, 0x31bd, 0x00be, 0x002e, + 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, + 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, + 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, + 0x8670, 0x2c08, 0x080c, 0xd556, 0x007e, 0x001e, 0xba10, 0xbb14, + 0xbcb0, 0x080c, 0x5e49, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, + 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, + 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, + 0x2071, 0x1800, 0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e, + 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001, + 0x70e2, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, + 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0070, 0x080c, 0x54db, 0xd0c4, + 0x0138, 0x0030, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd837, + 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x3144, + 0x928e, 0x007f, 0x0904, 0x3144, 0x928e, 0x0080, 0x05e8, 0x9288, + 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968, + 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, + 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6693, 0x00ce, 0x00be, + 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, + 0x8670, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, + 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, + 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, + 0x080c, 0xd556, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x30fb, + 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x54db, 0xd0c4, + 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, + 0xd837, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x7290, 0x82ff, 0x01e8, 0x080c, 0x66c1, 0x11d0, 0x2100, + 0x080c, 0x26a0, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, + 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, + 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, + 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, + 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, + 0x00c6, 0x2061, 0x1a88, 0x001e, 0x6112, 0x080c, 0x3095, 0x001e, + 0x080c, 0x6367, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, + 0x2110, 0x080c, 0x9ad0, 0x080c, 0xdaf0, 0x002e, 0x001e, 0x0005, + 0x2001, 0x1836, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, + 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, + 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, + 0x6367, 0x8108, 0x1f04, 0x31ce, 0x2061, 0x1800, 0x607b, 0x0000, + 0x607c, 0x9084, 0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce, + 0x0005, 0x2001, 0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c, + 0x2214, 0xd2ec, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, + 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, + 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, + 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, + 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, + 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, + 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, + 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, + 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, + 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, + 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, + 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, + 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, + 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, + 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, + 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, + 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, + 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, + 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, + 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, + 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, + 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, + 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, + 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, + 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, + 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, + 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006, + 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, + 0x18b8, 0x703f, 0x18b8, 0x7007, 0x0001, 0x080c, 0x1050, 0x090c, + 0x0df6, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, + 0x1050, 0x090c, 0x0df6, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, + 0xdcb0, 0x0005, 0x2071, 0x189c, 0x7004, 0x0002, 0x3322, 0x3323, + 0x3336, 0x334a, 0x0005, 0x1004, 0x3333, 0x0e04, 0x3333, 0x2079, + 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, + 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, + 0x2061, 0x18b6, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, + 0x0200, 0x0904, 0x341e, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, + 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, + 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, + 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, + 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, + 0x2100, 0x908a, 0x003f, 0x1a04, 0x341b, 0x61cc, 0x0804, 0x33b0, + 0x33f2, 0x342a, 0x341b, 0x3436, 0x3440, 0x3446, 0x344a, 0x345a, + 0x345e, 0x3474, 0x347a, 0x3480, 0x348b, 0x3496, 0x34a5, 0x34b4, + 0x34c2, 0x34d9, 0x34f4, 0x341b, 0x359d, 0x35db, 0x3681, 0x3692, + 0x36b5, 0x341b, 0x341b, 0x341b, 0x36ed, 0x3709, 0x3712, 0x3741, + 0x3747, 0x341b, 0x378d, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x3798, 0x37a1, 0x37a9, 0x37ab, 0x341b, 0x341b, 0x341b, 0x341b, + 0x341b, 0x341b, 0x37d7, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x37f4, 0x3868, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x0002, 0x3892, 0x3895, 0x38f4, 0x390d, 0x393d, 0x3bdf, 0x341b, + 0x509e, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x341b, 0x3474, 0x347a, 0x416d, 0x54ff, 0x4183, 0x512d, 0x517f, + 0x528a, 0x341b, 0x52ec, 0x5328, 0x5359, 0x5461, 0x5386, 0x53e1, + 0x341b, 0x4187, 0x4336, 0x434c, 0x4371, 0x43d6, 0x444a, 0x446a, + 0x44e1, 0x453d, 0x4599, 0x459c, 0x45c1, 0x4636, 0x469c, 0x46a4, + 0x47d9, 0x4941, 0x4975, 0x4bbf, 0x341b, 0x4bdd, 0x4c9a, 0x4d77, + 0x341b, 0x341b, 0x341b, 0x341b, 0x4ddd, 0x4df8, 0x46a4, 0x503e, + 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x49f3, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x33fc, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, + 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, + 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, + 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, + 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, + 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4a00, 0x2039, 0x0001, + 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a03, + 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x33f2, 0x7984, 0x2114, + 0x0804, 0x33f2, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, + 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, + 0x0804, 0x33f2, 0x7884, 0x2060, 0x0804, 0x34a7, 0x2009, 0x0003, + 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0317, 0x7893, 0xffff, + 0x2001, 0x188d, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x33f2, + 0x7897, 0x0001, 0x0804, 0x33f2, 0x2039, 0x0001, 0x7d98, 0x7c9c, + 0x0804, 0x342e, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x343a, + 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3427, 0x2138, 0x7d98, + 0x7c9c, 0x0804, 0x342e, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, + 0x3427, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x343a, 0x79a0, 0x9182, + 0x0040, 0x0210, 0x0804, 0x3427, 0x21e8, 0x7984, 0x7888, 0x20a9, + 0x0001, 0x21a0, 0x4004, 0x0804, 0x33f2, 0x2061, 0x0800, 0xe10c, + 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, + 0x0904, 0x33f2, 0x0804, 0x3421, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x3427, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, + 0x0804, 0x33f2, 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04, + 0x3427, 0x8019, 0x0904, 0x3427, 0x684a, 0x6942, 0x788c, 0x6852, + 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x74ab, 0x0804, + 0x33f2, 0x2069, 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x3427, + 0x8019, 0x0904, 0x3427, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, + 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, + 0x67f9, 0x012e, 0x0804, 0x33f2, 0x902e, 0x2520, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x3424, 0x7984, 0x7b88, 0x7a8c, 0x20a9, + 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0xa85c, + 0x9080, 0x0019, 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3518, 0x0005, + 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, + 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, + 0x9096, 0x0029, 0x1904, 0x3424, 0x810f, 0x918c, 0x00ff, 0x0904, + 0x3424, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0x7068, + 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3556, 0x0005, 0xa864, 0x9084, + 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x3424, + 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, + 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3b, + 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, + 0x080c, 0x6259, 0x1128, 0x7007, 0x0003, 0x701f, 0x3582, 0x0005, + 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, + 0x0001, 0x2099, 0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, + 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, + 0x0020, 0x012e, 0xaf60, 0x0804, 0x4a03, 0x2091, 0x8000, 0x7837, + 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, + 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, + 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, + 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, + 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, + 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, + 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x3424, 0x7984, 0x080c, + 0x63a3, 0x1904, 0x3427, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x1a04, 0x3427, 0x7c88, 0x7d8c, 0x080c, 0x6506, 0x080c, 0x64d5, + 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, + 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, + 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, + 0x1819, 0x2004, 0x9c02, 0x1a04, 0x3424, 0x0c30, 0x080c, 0xb983, + 0x012e, 0x0904, 0x3424, 0x0804, 0x33f2, 0x900e, 0x2001, 0x0005, + 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c, + 0x6a22, 0x012e, 0x0804, 0x33f2, 0x00a6, 0x2950, 0xb198, 0x080c, + 0x63a3, 0x1904, 0x366e, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6506, 0x080c, 0x64d5, 0x1520, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, - 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, - 0x9c02, 0x1a04, 0x343a, 0x0c30, 0x080c, 0xb974, 0x012e, 0x0904, - 0x343a, 0x0804, 0x3408, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c, - 0x0126, 0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a23, 0x012e, - 0x0804, 0x3408, 0x00a6, 0x2950, 0xb198, 0x080c, 0x63a4, 0x1904, - 0x3684, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, - 0xb5a0, 0x080c, 0x6507, 0x080c, 0x64d6, 0x1520, 0x2061, 0x1cd0, - 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, - 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, - 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x2009, - 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb974, 0x012e, 0x2009, 0x0003, - 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c, 0x0126, - 0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a16, 0x012e, 0x0070, - 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, - 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, - 0x1904, 0x343a, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x646b, - 0x0904, 0x343a, 0x080c, 0x650d, 0x0904, 0x343a, 0x0804, 0x4462, - 0x81ff, 0x1904, 0x343a, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, - 0x659b, 0x0904, 0x343a, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6528, - 0x0904, 0x343a, 0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x8003, - 0x800b, 0x810b, 0x9108, 0x080c, 0x8268, 0x79a8, 0xd184, 0x1904, - 0x3408, 0x0804, 0x4462, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, - 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458, 0x2400, 0x9506, - 0x01f8, 0x2508, 0x080c, 0x63a4, 0x11d8, 0x080c, 0x659b, 0x1128, - 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, - 0x080c, 0x6528, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, - 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8268, - 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3408, 0x012e, 0x0804, 0x343a, - 0x012e, 0x0804, 0x343d, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, - 0x646b, 0x0904, 0x343a, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, - 0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, - 0xd53b, 0x007e, 0x00ce, 0x080c, 0x6507, 0x0804, 0x3408, 0x080c, - 0x49cf, 0x0904, 0x343d, 0x080c, 0x6507, 0x2208, 0x0804, 0x3408, - 0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810, 0x6914, 0x910a, - 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069, - 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68, - 0x1f04, 0x3739, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, - 0x3408, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, - 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, - 0x190e, 0x6910, 0x62b8, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x080c, 0x54f0, - 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x343a, 0x012e, 0x6158, - 0x9190, 0x3209, 0x2215, 0x9294, 0x00ff, 0x6378, 0x83ff, 0x0108, - 0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, - 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, - 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, - 0x0002, 0x0068, 0x080c, 0x717f, 0x1118, 0x2031, 0x0004, 0x0038, - 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x343a, 0x9036, 0x7e9a, - 0x7f9e, 0x0804, 0x3408, 0x6148, 0x624c, 0x2019, 0x1960, 0x231c, - 0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x3408, 0x0126, 0x2091, - 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3408, 0x080c, - 0x49eb, 0x0904, 0x343d, 0xba44, 0xbb38, 0x0804, 0x3408, 0x080c, - 0x0e02, 0x080c, 0x49eb, 0x2110, 0x0904, 0x343d, 0xb804, 0x908c, - 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, - 0x2009, 0x0009, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x2019, - 0x0005, 0x00c6, 0x9066, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076, - 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e, 0x00ce, - 0xb807, 0x0407, 0x012e, 0x0804, 0x3408, 0x6148, 0x624c, 0x7884, - 0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f, 0x9305, 0x6816, - 0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, - 0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04, 0x266a, 0x789a, - 0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, - 0x910e, 0xd1b4, 0x190c, 0x0ef3, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, - 0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978, 0x2012, 0x2069, - 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, - 0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, - 0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, - 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060, 0x2011, 0x0116, - 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c, - 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, - 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c, - 0x0f09, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, - 0x012e, 0x0804, 0x3408, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, - 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, - 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, - 0x01a8, 0x7888, 0x9025, 0x0904, 0x343d, 0x788c, 0x902d, 0x0904, - 0x343d, 0x900e, 0x080c, 0x63a4, 0x1120, 0xba44, 0xbb38, 0xbc46, - 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x49eb, - 0x0904, 0x343d, 0x7888, 0x900d, 0x0904, 0x343d, 0x788c, 0x9005, - 0x0904, 0x343d, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3408, - 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x54f0, 0x1904, - 0x343a, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, - 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, - 0x16e0, 0x9188, 0x3209, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1817, - 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, - 0x2091, 0x8000, 0x0006, 0x080c, 0x9f7f, 0x000e, 0x0510, 0x602e, - 0x620a, 0x7984, 0x00b6, 0x080c, 0x634a, 0x2b08, 0x00be, 0x1500, - 0x6112, 0x6023, 0x0001, 0x080c, 0x49b8, 0x01d0, 0x9006, 0xa866, - 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3903, - 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa053, 0x012e, 0x00ce, - 0x0005, 0x012e, 0x00ce, 0x0804, 0x343a, 0x00ce, 0x0804, 0x343d, - 0x080c, 0x9fd5, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a, - 0x0804, 0x3408, 0x2061, 0x1a4c, 0x0126, 0x2091, 0x8000, 0x6000, - 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6350, 0x6070, - 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x3408, - 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, - 0x0904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6250, 0x6070, 0x9202, - 0x0248, 0x9085, 0x0001, 0x080c, 0x26d7, 0x080c, 0x5713, 0x012e, - 0x0804, 0x3408, 0x012e, 0x0804, 0x343d, 0x0006, 0x0016, 0x00c6, - 0x00e6, 0x2001, 0x1983, 0x2070, 0x2061, 0x185b, 0x6008, 0x2072, - 0x900e, 0x2011, 0x1400, 0x080c, 0x847f, 0x7206, 0x00ee, 0x00ce, - 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, - 0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x7884, 0xd0fc, 0x0158, - 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298, - 0x012e, 0x0804, 0x343d, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128, - 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x343d, - 0x012e, 0x0804, 0x343a, 0x080c, 0x9f54, 0x0dd0, 0x7884, 0xd0fc, - 0x0904, 0x39d2, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0d88, 0xa867, - 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001, - 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001, - 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001, - 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001, - 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816, - 0x080c, 0x3b58, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c, - 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, - 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x7023, 0x0001, - 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x393d, 0x2001, 0x1979, 0x2003, - 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, - 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3bc7, 0x080c, - 0x3b86, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42, 0x2079, - 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, - 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, - 0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c, - 0x3ee9, 0x080c, 0x3dae, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, - 0x0140, 0x1db8, 0x080c, 0x4030, 0x00f6, 0x2079, 0x0300, 0x78bc, - 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, - 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, - 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, - 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x181f, - 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, - 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3db8, 0x080c, 0x3b81, 0x0058, - 0x080c, 0x3b81, 0x080c, 0x3f54, 0x080c, 0x3edf, 0x2001, 0x020b, - 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, - 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, - 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, - 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x2009, - 0x0028, 0x080c, 0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, - 0x2001, 0x1979, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3408, - 0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x0016, 0x0026, 0x0036, - 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, - 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904, - 0x3af1, 0x2048, 0x1f04, 0x3aa5, 0x7068, 0x2040, 0xa28c, 0xa390, - 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, - 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086, - 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x00b0, - 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, - 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, - 0x0fc0, 0x000e, 0x080c, 0x4a04, 0x701f, 0x3a95, 0x015e, 0x00de, + 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, + 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb983, 0x012e, + 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, + 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c, 0x6a15, + 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, + 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, + 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904, 0x3427, + 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904, 0x3424, + 0x0804, 0x4461, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ea, 0x0904, + 0x3427, 0x080c, 0x659a, 0x0904, 0x3424, 0x2019, 0x0005, 0x79a8, + 0x080c, 0x6527, 0x0904, 0x3424, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x3427, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267, 0x79a8, + 0xd184, 0x1904, 0x33f2, 0x0804, 0x4461, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458, + 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x63a3, 0x11d8, 0x080c, + 0x659a, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019, + 0x0004, 0x900e, 0x080c, 0x6527, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, + 0x080c, 0x8267, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x33f2, 0x012e, + 0x0804, 0x3424, 0x012e, 0x0804, 0x3427, 0x080c, 0x49ce, 0x0904, + 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0xbaa0, 0x2019, 0x0005, + 0x00c6, 0x9066, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, + 0x900e, 0x080c, 0xd556, 0x007e, 0x00ce, 0x080c, 0x6506, 0x0804, + 0x33f2, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x6506, 0x2208, + 0x0804, 0x33f2, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810, + 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, + 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, + 0x9210, 0x8d68, 0x1f04, 0x3723, 0x2300, 0x9218, 0x00ee, 0x00de, + 0x015e, 0x0804, 0x33f2, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, + 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, + 0x0005, 0x2069, 0x190e, 0x6910, 0x62b8, 0x0804, 0x33f2, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x0126, 0x2091, 0x8000, + 0x080c, 0x54ef, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x3424, + 0x012e, 0x6158, 0x9190, 0x31f3, 0x2215, 0x9294, 0x00ff, 0x6378, + 0x83ff, 0x0108, 0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a, + 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, + 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, + 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x717e, 0x1118, 0x2031, + 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x3424, + 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x33f2, 0x6148, 0x624c, 0x2019, + 0x1960, 0x231c, 0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x33f2, + 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, + 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427, 0xba44, 0xbb38, 0x0804, + 0x33f2, 0x080c, 0x0df6, 0x080c, 0x49ea, 0x2110, 0x0904, 0x3427, + 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, + 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x3424, 0x0126, 0x2091, + 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x9ad0, 0x080c, + 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556, + 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x33f2, 0x6148, + 0x624c, 0x7884, 0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f, + 0x9305, 0x6816, 0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98, + 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04, + 0x266a, 0x789a, 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x6138, + 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ee7, 0xd0c4, 0x01a8, + 0x00d6, 0x78a8, 0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978, + 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, + 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004, + 0x9086, 0x000a, 0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, + 0x0118, 0x918d, 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060, + 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, + 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, + 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, + 0xd1e4, 0x190c, 0x0efd, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, + 0x0114, 0x2012, 0x012e, 0x0804, 0x33f2, 0x00f6, 0x2079, 0x1800, + 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, + 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, + 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, + 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x3427, 0x788c, + 0x902d, 0x0904, 0x3427, 0x900e, 0x080c, 0x63a3, 0x1120, 0xba44, + 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, + 0x080c, 0x49ea, 0x0904, 0x3427, 0x7888, 0x900d, 0x0904, 0x3427, + 0x788c, 0x9005, 0x0904, 0x3427, 0xba44, 0xb946, 0xbb38, 0xb83a, + 0x0804, 0x33f2, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, + 0x54ef, 0x1904, 0x3424, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, + 0x00ff, 0x1130, 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, + 0x9182, 0x007f, 0x16e0, 0x9188, 0x31f3, 0x210d, 0x918c, 0x00ff, + 0x2001, 0x1817, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, + 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x9f94, 0x000e, + 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x6349, 0x2b08, + 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x49b7, 0x01d0, + 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, + 0x701f, 0x38ed, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa068, + 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3424, 0x00ce, + 0x0804, 0x3427, 0x080c, 0x9fea, 0x0cb0, 0xa830, 0x9086, 0x0100, + 0x0904, 0x3424, 0x0804, 0x33f2, 0x2061, 0x1a4c, 0x0126, 0x2091, + 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, + 0x6350, 0x6070, 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, + 0x0804, 0x33f2, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x3424, + 0x080c, 0x717e, 0x0904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6250, + 0x6070, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26d6, 0x080c, + 0x5712, 0x012e, 0x0804, 0x33f2, 0x012e, 0x0804, 0x3427, 0x0006, + 0x0016, 0x00c6, 0x00e6, 0x2001, 0x1984, 0x2070, 0x2061, 0x185b, + 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x847e, 0x7206, + 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x7884, + 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, + 0x00e1, 0x0298, 0x012e, 0x0804, 0x3427, 0x2001, 0x002a, 0x2004, + 0x9005, 0x0128, 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e, + 0x0804, 0x3427, 0x012e, 0x0804, 0x3424, 0x080c, 0x9f69, 0x0dd0, + 0x7884, 0xd0fc, 0x0904, 0x39bc, 0x00c6, 0x080c, 0x49b7, 0x00ce, + 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, + 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, + 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, + 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, + 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, + 0x8004, 0xa816, 0x080c, 0x3b42, 0x0928, 0x7014, 0x2048, 0xad2c, + 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, + 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f, 0x3a7f, + 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2001, + 0x197a, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, + 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, + 0x3bb1, 0x080c, 0x3b70, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, + 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, + 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, + 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee, + 0x00fe, 0x080c, 0x3ed3, 0x080c, 0x3d98, 0x05b8, 0x2001, 0x020b, + 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4025, 0x00f6, 0x2079, + 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, + 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, + 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, + 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, + 0x2001, 0x181f, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, + 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3da2, 0x080c, + 0x3b6b, 0x0058, 0x080c, 0x3b6b, 0x080c, 0x3f49, 0x080c, 0x3ec9, + 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, + 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, + 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, + 0x12fe, 0x2009, 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c, + 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, + 0x008e, 0x004e, 0x2001, 0x197a, 0x2004, 0x9005, 0x1118, 0x012e, + 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4, 0x0016, + 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, + 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, + 0x9005, 0x0904, 0x3adb, 0x2048, 0x1f04, 0x3a8f, 0x7068, 0x2040, + 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, + 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, + 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f, + 0x3a7f, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, + 0x0006, 0x080c, 0x0fb4, 0x000e, 0x080c, 0x4a03, 0x701f, 0x3a7f, + 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, + 0x1118, 0x701f, 0x3b40, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, + 0xa86a, 0x2009, 0x007f, 0x080c, 0x6343, 0x0110, 0x9006, 0x0030, + 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xc21d, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, - 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f, - 0x3b56, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, - 0x007f, 0x080c, 0x6344, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, - 0xb817, 0xfffd, 0x080c, 0xc20a, 0x015e, 0x00de, 0x009e, 0x008e, - 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x343a, - 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, - 0x00d6, 0x0156, 0x701f, 0x3b28, 0x7007, 0x0003, 0x0804, 0x3ae6, - 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x340a, 0x0076, - 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120, - 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, - 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fc0, 0x000e, 0x080c, 0x4a04, - 0x007e, 0x701f, 0x3a95, 0x7023, 0x0001, 0x0005, 0x0804, 0x3408, - 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e, - 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x49b8, - 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58, - 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006, - 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e, - 0x0005, 0x2001, 0x1979, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6, - 0x00c6, 0x2061, 0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061, - 0x0100, 0x2001, 0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, - 0x080c, 0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, - 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, - 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004, 0x6036, - 0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, - 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, - 0x080c, 0x49b8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, - 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004, - 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873, - 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003, + 0x0904, 0x3424, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, + 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3b12, 0x7007, 0x0003, + 0x0804, 0x3ad0, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, + 0x33f4, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, + 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, + 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fb4, 0x000e, + 0x080c, 0x4a03, 0x007e, 0x701f, 0x3a7f, 0x7023, 0x0001, 0x0005, + 0x0804, 0x33f2, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, + 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, + 0x080c, 0x49b7, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, + 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, + 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, + 0x00fe, 0x000e, 0x0005, 0x2001, 0x197a, 0x2003, 0x0001, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x1985, 0x2004, + 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce, 0x6104, + 0xc1ac, 0x6106, 0x080c, 0x49b7, 0xa813, 0x0019, 0xa817, 0x0001, + 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, + 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1984, + 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2200, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, + 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x00e6, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019, 0xa017, + 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, + 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, + 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, + 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a8f, 0x1130, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x2001, 0x1979, 0x2003, + 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c00, 0x3c0f, 0x3c1e, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x012e, 0x0804, 0x3427, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8, 0x2009, 0x0114, + 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3dec, 0x00f0, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009, 0x0114, 0x2104, + 0x9085, 0x4000, 0x200a, 0x080c, 0x3dec, 0x0078, 0x080c, 0x717e, + 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x3424, 0x81ff, 0x0128, + 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x2001, 0x0141, 0x2004, + 0xd0dc, 0x0db0, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2009, 0x0101, 0x210c, 0x0016, + 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4100, + 0x080c, 0x4050, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, + 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, + 0x0001, 0x080c, 0x3fb1, 0x080c, 0x2a97, 0x080c, 0x2a97, 0x080c, + 0x2a97, 0x080c, 0x2a97, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe, + 0x080c, 0x3ed3, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3da2, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, + 0x0017, 0x080c, 0x3424, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, + 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, + 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3eb1, + 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3da2, 0x0804, 0x3d42, + 0x080c, 0x4025, 0x080c, 0x3f49, 0x080c, 0x3e94, 0x080c, 0x3ec9, + 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, + 0x3da2, 0x00fe, 0x0804, 0x3d42, 0x00fe, 0x080c, 0x3d98, 0x1150, + 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, + 0x3da2, 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, + 0x1908, 0x8739, 0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000, + 0x1904, 0x3c92, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, + 0x8529, 0x2500, 0x9605, 0x0904, 0x3d42, 0x7884, 0xd0bc, 0x0128, + 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3d42, 0xa013, 0x0019, 0x2001, + 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f, + 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, + 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, + 0x0040, 0x080c, 0x2200, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, + 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, + 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d19, + 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, + 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, + 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, + 0x0804, 0x3c4c, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, + 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, + 0x12fe, 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, + 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, + 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, + 0x9084, 0xb7ef, 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bdc, 0x6052, + 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, + 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, + 0x012e, 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4, + 0x9085, 0x0001, 0x1d04, 0x3da1, 0x2091, 0x6000, 0x8420, 0x9486, + 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, + 0x2003, 0x0004, 0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009, + 0x0048, 0x080c, 0x2200, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, + 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, + 0x1a42, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, + 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4025, + 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, + 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003, + 0x0000, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x15d0, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, + 0x7932, 0x7936, 0x080c, 0x26b6, 0x080c, 0x2ba9, 0x080c, 0x2bdc, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, + 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, + 0x7850, 0xc0e4, 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, + 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f, + 0x7827, 0x0048, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, + 0x1817, 0x200c, 0x7932, 0x7936, 0x080c, 0x26b6, 0x7850, 0x9084, + 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, + 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, + 0x3e47, 0x2091, 0x6000, 0x1f04, 0x3e47, 0x7850, 0x9085, 0x0400, + 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, + 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, + 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, + 0x1f04, 0x3e67, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, + 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, + 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, + 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f, + 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, + 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, + 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, + 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, + 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, + 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, + 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, + 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1985, + 0x2004, 0x70e2, 0x080c, 0x3b61, 0x1188, 0x2001, 0x181f, 0x2004, + 0x2009, 0x181e, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, + 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, + 0x0002, 0x702e, 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, + 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, + 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, + 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, + 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, + 0x080c, 0x4025, 0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6, + 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, + 0x780a, 0x00de, 0x080c, 0x3b61, 0x0140, 0x2001, 0x1979, 0x200c, + 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, + 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, + 0x080c, 0x3fb1, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x00fe, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x792c, + 0xd1fc, 0x0904, 0x3fae, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, + 0x3faa, 0x7000, 0x0002, 0x3fae, 0x3f5f, 0x3f8f, 0x3faa, 0xd1bc, + 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, + 0x3fb1, 0x0904, 0x3fae, 0x080c, 0x3fb1, 0x0804, 0x3fae, 0x00f6, + 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, + 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, + 0x080c, 0x3eb1, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, + 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, + 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x3f53, + 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, + 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, + 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, + 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, + 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, + 0x938a, 0x0007, 0x1a0c, 0x0df6, 0x9398, 0x3fdf, 0x231d, 0x083f, + 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, + 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, + 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x401c, + 0x4013, 0x400a, 0x4001, 0x3ff8, 0x3fef, 0x3fe6, 0xa964, 0x7902, + 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, + 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, + 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, + 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, + 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, + 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, + 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, + 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, + 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x404c, 0x4038, 0x4043, + 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x3fb1, + 0x190c, 0x3fb1, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38, + 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x1985, + 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce, + 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, + 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, + 0x49b7, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, + 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, + 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8, + 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x49b7, 0xa813, 0x0019, + 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, + 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, + 0x2079, 0x0100, 0x2001, 0x1984, 0x2004, 0x6036, 0x2009, 0x0040, + 0x080c, 0x2200, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, + 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, + 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, + 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, + 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, + 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, + 0x080c, 0x49b7, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, + 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, + 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, + 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x49b7, 0x2940, + 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, + 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, + 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8, 0x1d68, + 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019, + 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, + 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, + 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, + 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a3f, 0x2003, + 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x81ff, 0x0148, 0x080c, 0x2aa8, 0x1130, 0x9006, 0x080c, 0x29b8, - 0x9006, 0x080c, 0x299b, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c12, - 0x3c21, 0x3c30, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x012e, - 0x0804, 0x343d, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8, - 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3e02, - 0x00f0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009, - 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, 0x3e02, 0x0078, - 0x080c, 0x717f, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x343a, - 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x6000, - 0x9086, 0x0003, 0x1db8, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90, - 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x080c, 0x393d, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, - 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x410b, 0x080c, 0x405b, - 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42, - 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, - 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, - 0x3fbc, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c, - 0x2ab0, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3ee9, - 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3db8, 0x2001, 0x0004, - 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, - 0x343a, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, - 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, - 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3ec7, 0x2d00, 0x9c05, - 0x9b05, 0x0120, 0x080c, 0x3db8, 0x0804, 0x3d58, 0x080c, 0x4030, - 0x080c, 0x3f54, 0x080c, 0x3eaa, 0x080c, 0x3edf, 0x00f6, 0x2079, - 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3db8, 0x00fe, - 0x0804, 0x3d58, 0x00fe, 0x080c, 0x3dae, 0x1150, 0x8d68, 0x2001, - 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3db8, 0x0080, - 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, - 0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3ca8, - 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, - 0x9605, 0x0904, 0x3d58, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, - 0x9b05, 0x1904, 0x3d58, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, - 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f, 0x2003, 0x0003, - 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, - 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, - 0x2204, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, - 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, - 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d2f, 0x00ce, 0x0030, - 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, - 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, - 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, - 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3c62, - 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, - 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, - 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x7884, - 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, 0x0028, 0x080c, - 0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, 0x9084, 0xb7ef, - 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bf5, 0x6052, 0x602f, 0x0000, - 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08, - 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, - 0x3408, 0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x9085, 0x0001, - 0x1d04, 0x3db7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, - 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, - 0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, - 0x2204, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, - 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000, - 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, - 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, - 0x2204, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4030, 0x7000, 0x9086, - 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, - 0x0040, 0x080c, 0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, - 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x15d0, - 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, 0x7932, 0x7936, - 0x080c, 0x26b7, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x784b, 0xf7f7, - 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, - 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, - 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, - 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827, - 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048, - 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, - 0x7932, 0x7936, 0x080c, 0x26b7, 0x7850, 0x9084, 0xfbff, 0x9085, - 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf, - 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3e5d, 0x2091, - 0x6000, 0x1f04, 0x3e5d, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff, - 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001, - 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843, - 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3e7d, - 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001, - 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850, - 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, - 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827, - 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048, - 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, - 0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, - 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, - 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, - 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, - 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, - 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, - 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, - 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1984, 0x2004, 0x70e2, - 0x080c, 0x3b77, 0x1188, 0x2001, 0x181f, 0x2004, 0x2009, 0x181e, - 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, - 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, - 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, - 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, - 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, - 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, - 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4030, - 0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, - 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, - 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, - 0x0004, 0x2011, 0x0011, 0x080c, 0x3fbc, 0x2011, 0x0001, 0x080c, - 0x3fbc, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f, - 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x3fb9, 0x782b, 0x0002, - 0x9026, 0xd19c, 0x1904, 0x3fb5, 0x7000, 0x0002, 0x3fb9, 0x3f6a, - 0x3f9a, 0x3fb5, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, - 0x2011, 0x0001, 0x080c, 0x3fbc, 0x0904, 0x3fb9, 0x080c, 0x3fbc, - 0x0804, 0x3fb9, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, - 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, - 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3ec7, 0x2009, 0x0001, 0x00f6, - 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, - 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, - 0xd0fc, 0x1904, 0x3f5e, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, - 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, - 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, - 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, - 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, - 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0e02, 0x9398, - 0x3fea, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, - 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, - 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, - 0x0001, 0x0005, 0x4027, 0x401e, 0x4015, 0x400c, 0x4003, 0x3ffa, - 0x3ff1, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, - 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, - 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, - 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, - 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, - 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, - 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, - 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, - 0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c, - 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, - 0x4057, 0x4043, 0x404e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, - 0x0001, 0x080c, 0x3fbc, 0x190c, 0x3fbc, 0x0048, 0x8001, 0x7002, - 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, - 0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, - 0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, - 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, - 0x002f, 0x201c, 0x080c, 0x49b8, 0xa813, 0x0019, 0xaf16, 0x2900, - 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, - 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, - 0x009e, 0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, - 0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, - 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, - 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, - 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004, - 0x6036, 0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004, - 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, - 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, - 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, - 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, - 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, - 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, - 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, - 0x0096, 0x2940, 0x0086, 0x080c, 0x49b8, 0x008e, 0xa058, 0x00a6, - 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, - 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, - 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, - 0x080c, 0x49b8, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, - 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, - 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, - 0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b8, - 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, - 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, - 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, - 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, - 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, - 0x2001, 0x1a3f, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, - 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, - 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, - 0x0126, 0x2091, 0x8000, 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9, - 0x0001, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, - 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x3408, 0x7d98, 0x7c9c, - 0x0804, 0x350c, 0x080c, 0x717f, 0x190c, 0x5df5, 0x2069, 0x185b, - 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, - 0x0001, 0x080c, 0x4a01, 0x701f, 0x41a6, 0x0005, 0x080c, 0x54eb, - 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, - 0x185b, 0x6800, 0x9005, 0x0904, 0x343d, 0x6804, 0xd094, 0x00c6, - 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, - 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, - 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, - 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, - 0x007f, 0x1a04, 0x343d, 0x9288, 0x3209, 0x210d, 0x918c, 0x00ff, - 0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x343d, - 0x605a, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, - 0x0006, 0x2009, 0x198c, 0x9080, 0x27aa, 0x2005, 0x200a, 0x000e, - 0x2009, 0x198d, 0x9080, 0x27ae, 0x2005, 0x200a, 0x6808, 0x908a, - 0x0100, 0x0a04, 0x343d, 0x908a, 0x0841, 0x1a04, 0x343d, 0x9084, - 0x0007, 0x1904, 0x343d, 0x680c, 0x9005, 0x0904, 0x343d, 0x6810, - 0x9005, 0x0904, 0x343d, 0x6848, 0x6940, 0x910a, 0x1a04, 0x343d, - 0x8001, 0x0904, 0x343d, 0x684c, 0x6944, 0x910a, 0x1a04, 0x343d, - 0x8001, 0x0904, 0x343d, 0x2009, 0x195b, 0x200b, 0x0000, 0x2001, - 0x187d, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, - 0x0e87, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a, - 0x8007, 0x9084, 0x00ff, 0x604e, 0x080c, 0x74ac, 0x080c, 0x6797, - 0x080c, 0x67fa, 0x6808, 0x602a, 0x080c, 0x2176, 0x2009, 0x0170, - 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, - 0x080c, 0x2711, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x4327, - 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, - 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, - 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, - 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, - 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001, - 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001, - 0x080c, 0x8363, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, - 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a78, - 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, - 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, - 0x6003, 0x0001, 0x1f04, 0x4292, 0x00ce, 0x00c6, 0x2061, 0x1976, - 0x2063, 0x0001, 0x9006, 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, - 0x0000, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed8, 0x00ee, 0x6888, - 0xd0ec, 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138, - 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011, - 0x0114, 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, - 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, - 0x2001, 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, - 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, - 0x080c, 0x2786, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6, - 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, - 0x717f, 0x0128, 0x080c, 0x4dd2, 0x0110, 0x080c, 0x26d7, 0x60d0, - 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x430f, 0x00d0, 0x080c, - 0x717f, 0x1168, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1, - 0x080c, 0x832e, 0x080c, 0x7480, 0x080c, 0x709f, 0x0040, 0x080c, - 0x5cef, 0x0028, 0x6003, 0x0004, 0x2009, 0x4327, 0x0010, 0x0804, - 0x3408, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, - 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, - 0x9086, 0x0000, 0x0904, 0x343a, 0x2069, 0x185b, 0x7890, 0x6842, - 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x2039, 0x0001, 0x0804, 0x4a04, 0x9006, 0x080c, 0x26d7, - 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x11b0, 0x080c, 0x747b, - 0x080c, 0x5e30, 0x080c, 0x3204, 0x0118, 0x6130, 0xc18d, 0x6132, - 0x080c, 0xc444, 0x0130, 0x080c, 0x71a2, 0x1118, 0x080c, 0x7157, - 0x0038, 0x080c, 0x709f, 0x0020, 0x080c, 0x5df5, 0x080c, 0x5cef, - 0x0804, 0x3408, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x1110, - 0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190, - 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a04, 0x701f, 0x3406, - 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, - 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, - 0x6558, 0x9588, 0x3209, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, - 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a4, 0x1190, - 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, - 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, - 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, - 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, - 0x1c80, 0x2099, 0x1c80, 0x080c, 0x5d80, 0x0804, 0x4382, 0x080c, - 0x49eb, 0x0904, 0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, - 0x0804, 0x343a, 0x080c, 0x54dc, 0xd0b4, 0x0558, 0x7884, 0x908e, - 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, - 0x080c, 0x31ff, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, - 0x7007, 0x0003, 0x701f, 0x440d, 0x0005, 0x080c, 0x49eb, 0x0904, - 0x343d, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, - 0x9080, 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, - 0x2098, 0x080c, 0x0fc0, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, - 0x000a, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, - 0x080c, 0x0fc0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x0804, 0x4a04, 0x81ff, 0x1904, 0x343a, 0x080c, 0x49cf, - 0x0904, 0x343d, 0x080c, 0x6516, 0x0904, 0x343a, 0x0058, 0xa878, - 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa974, 0xaa94, - 0x0804, 0x3408, 0x080c, 0x54e4, 0x0904, 0x3408, 0x701f, 0x4457, - 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x343a, 0x7888, 0x908a, - 0x1000, 0x1a04, 0x343d, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, - 0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x659b, - 0x0904, 0x343a, 0x2019, 0x0004, 0x900e, 0x080c, 0x6528, 0x0904, - 0x343a, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, - 0x12f8, 0x080c, 0x49e9, 0x01e0, 0x080c, 0x66ca, 0x0118, 0x080c, - 0x66d2, 0x11b0, 0x080c, 0x659b, 0x2009, 0x0002, 0x0168, 0x2009, - 0x0002, 0x2019, 0x0004, 0x080c, 0x6528, 0x2009, 0x0003, 0x0120, - 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, - 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, - 0xa897, 0x4000, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, - 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400, - 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, - 0x63a4, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, - 0x8268, 0x0005, 0x81ff, 0x1904, 0x343a, 0x798c, 0x2001, 0x195a, - 0x918c, 0x8000, 0x2102, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, - 0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x646b, - 0x0904, 0x343a, 0x080c, 0x651f, 0x0904, 0x343a, 0x2001, 0x195a, - 0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0, 0x2001, - 0x195a, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc, 0x01a0, - 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c, 0x646b, - 0x2009, 0x0002, 0x0128, 0x080c, 0x651f, 0x1170, 0x2009, 0x0003, - 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a, - 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, - 0x343a, 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c, - 0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c, 0x66d2, - 0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x080c, 0x650d, - 0x0904, 0x343a, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x3408, - 0x0804, 0x4462, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d, - 0x2102, 0x080c, 0x49dc, 0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c, - 0x66d2, 0x1170, 0x080c, 0x646b, 0x2009, 0x0002, 0x0128, 0x080c, - 0x650d, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, - 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, - 0xa897, 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c, - 0x54e4, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0000, 0x0005, 0x6100, 0x0804, 0x3408, 0x080c, 0x49eb, 0x0904, - 0x343d, 0x080c, 0x54f0, 0x1904, 0x343a, 0x79a8, 0xd184, 0x1158, - 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, - 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, - 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, - 0x0804, 0x3408, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, - 0x1140, 0x939a, 0x0003, 0x1a04, 0x343a, 0x6258, 0x7884, 0x9206, - 0x1560, 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840, - 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, - 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a04, - 0x000e, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, - 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1140, - 0x7007, 0x0002, 0x701f, 0x461d, 0x0005, 0x81ff, 0x1904, 0x343a, - 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x1904, 0x343a, - 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0904, 0x343a, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbeac, 0x0904, 0x343a, - 0x7007, 0x0003, 0x701f, 0x4621, 0x0005, 0x080c, 0x4178, 0x0804, - 0x3408, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a, 0x8906, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, - 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x9006, - 0x080c, 0x26d7, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, - 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x0110, 0x080c, 0x5df5, - 0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x7984, 0x9186, 0x00ff, - 0x0138, 0x9182, 0x007f, 0x1a04, 0x343d, 0x2100, 0x080c, 0x26a1, - 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b, - 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, - 0x717f, 0x1158, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001, - 0x080c, 0x71c3, 0x080c, 0x709f, 0x00d0, 0x080c, 0x9f5b, 0x2061, - 0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, - 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, - 0x0000, 0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x82ec, 0x7984, - 0x080c, 0x717f, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c5, - 0x012e, 0x00ce, 0x002e, 0x0804, 0x3408, 0x7984, 0x080c, 0x6344, - 0x2b08, 0x1904, 0x343d, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x343a, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120, - 0x2009, 0x0005, 0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, - 0x0002, 0x0804, 0x343a, 0x7984, 0x81ff, 0x0904, 0x343d, 0x9192, - 0x0021, 0x1a04, 0x343d, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, - 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a01, 0x701f, - 0x46d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f84, 0x0005, - 0x2009, 0x0080, 0x080c, 0x63a4, 0x1118, 0x080c, 0x66ca, 0x0120, - 0x2021, 0x400a, 0x0804, 0x340a, 0x00d6, 0x0096, 0xa964, 0xaa6c, - 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, - 0x4771, 0x90be, 0x0112, 0x0904, 0x4771, 0x90be, 0x0113, 0x0904, - 0x4771, 0x90be, 0x0114, 0x0904, 0x4771, 0x90be, 0x0117, 0x0904, - 0x4771, 0x90be, 0x011a, 0x0904, 0x4771, 0x90be, 0x011c, 0x0904, - 0x4771, 0x90be, 0x0121, 0x0904, 0x4758, 0x90be, 0x0131, 0x0904, - 0x4758, 0x90be, 0x0171, 0x0904, 0x4771, 0x90be, 0x0173, 0x0904, - 0x4771, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, - 0x477c, 0x90be, 0x0212, 0x0904, 0x4765, 0x90be, 0x0213, 0x05e8, - 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, - 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, - 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x343d, 0x7028, - 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, - 0x0007, 0x080c, 0x47ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, - 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47ba, 0x00c8, - 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, - 0x20a9, 0x0001, 0x080c, 0x47c7, 0x00b8, 0x7028, 0x9080, 0x000e, - 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, - 0x47c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, - 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b8, 0x0550, - 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, - 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, - 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, - 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbec7, - 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, - 0x47b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, - 0x343a, 0xa820, 0x9086, 0x8001, 0x1904, 0x3408, 0x2009, 0x0004, - 0x0804, 0x343a, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, - 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, - 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, - 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, - 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a, - 0x60d8, 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, - 0x343a, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x343a, 0x7984, - 0x78a8, 0x2040, 0x080c, 0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04, - 0x343d, 0x9186, 0x00ff, 0x0904, 0x343d, 0x9182, 0x0800, 0x1a04, - 0x343d, 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e, - 0x0904, 0x343d, 0x080c, 0x9f54, 0x1120, 0x99cc, 0xff00, 0x0904, - 0x343d, 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026, - 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x0140, 0x918d, 0x8000, - 0x080c, 0x6738, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d2, - 0x0560, 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c, - 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, - 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, - 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, - 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, - 0x000a, 0x2020, 0x012e, 0x0804, 0x340a, 0x2b00, 0x7026, 0x0016, - 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa026, 0x0904, 0x489f, - 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2e58, 0x00ee, 0x00e6, 0x00c6, - 0x080c, 0x49b8, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fd5, 0x00ee, - 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x343a, - 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, - 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x30ab, 0x6023, 0x0001, - 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009, - 0x0002, 0x080c, 0xa053, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, - 0x00e6, 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee, - 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, - 0x343a, 0x7007, 0x0003, 0x701f, 0x48ae, 0x0005, 0xa830, 0x2008, - 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x340a, 0x9086, - 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, - 0x00ff, 0x0804, 0x5430, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3408, - 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, - 0x0804, 0x3408, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x491a, - 0x902e, 0x080c, 0x9f54, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, - 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, - 0x2e04, 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce, - 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080, - 0x1130, 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd, - 0x0450, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600, - 0x9206, 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894, - 0x1558, 0x080c, 0x66ca, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, - 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, - 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f54, 0x1930, - 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e8, 0x85ff, - 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, - 0x6344, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, - 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a, - 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0xa867, - 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x343d, - 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x343d, 0x2010, - 0x2918, 0x080c, 0x3051, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, - 0x7007, 0x0003, 0x701f, 0x496d, 0x0005, 0xa830, 0x9086, 0x0100, - 0x1904, 0x3408, 0x2009, 0x0004, 0x0804, 0x343a, 0x7984, 0x080c, - 0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04, 0x343d, 0x9186, 0x00ff, - 0x0904, 0x343d, 0x9182, 0x0800, 0x1a04, 0x343d, 0x2001, 0x9400, - 0x080c, 0x548b, 0x1904, 0x343a, 0x0804, 0x3408, 0xa998, 0x080c, - 0x9f54, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, - 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548b, 0x11a8, - 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, - 0x080c, 0x1043, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, - 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, - 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, - 0x080c, 0x63a4, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, - 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a4, 0x1130, - 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, - 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a4, 0x1108, - 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, - 0x2148, 0xa904, 0x080c, 0x1075, 0x0cc8, 0x7116, 0x711a, 0x001e, - 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6, - 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, - 0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x3408, 0x0005, - 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae, - 0x2004, 0x9005, 0x1190, 0x0e04, 0x4a35, 0x7a36, 0x7833, 0x0012, - 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11f2, 0x0804, 0x4a9b, 0x0016, 0x0086, 0x0096, - 0x00c6, 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148, - 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1043, 0x0904, - 0x4a93, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, - 0x1ec2, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, - 0x18b8, 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a, - 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, - 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, - 0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, - 0xa146, 0x1520, 0x080c, 0x1043, 0x1130, 0x8109, 0xa946, 0x7148, - 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, - 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ec2, - 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, - 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, - 0x001b, 0x0002, 0x4abd, 0x4abd, 0x4abf, 0x4abd, 0x4abd, 0x4abd, - 0x4ac3, 0x4abd, 0x4abd, 0x4abd, 0x4ac7, 0x4abd, 0x4abd, 0x4abd, - 0x4acb, 0x4abd, 0x4abd, 0x4abd, 0x4acf, 0x4abd, 0x4abd, 0x4abd, - 0x4ad3, 0x4abd, 0x4abd, 0x4abd, 0x4ad8, 0x080c, 0x0e02, 0xa276, - 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, - 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, - 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a96, - 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4a96, 0x00e6, 0x2071, 0x189c, - 0x7048, 0x9005, 0x0904, 0x4b6f, 0x0126, 0x2091, 0x8000, 0x0e04, - 0x4b6e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, - 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, - 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108, - 0x2105, 0x9005, 0xa94a, 0x1904, 0x4b71, 0xa804, 0x9005, 0x090c, - 0x0e02, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, - 0x9080, 0x1ec2, 0x2005, 0xa04a, 0x0804, 0x4b71, 0x703c, 0x2060, - 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, - 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x87ff, 0x0118, 0x2748, - 0x080c, 0x1075, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, - 0x2048, 0x9005, 0x0128, 0x080c, 0x1075, 0x9006, 0x7042, 0x7046, - 0x703b, 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508, - 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8, - 0x0210, 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, - 0x7044, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa800, 0x9005, 0x1de0, - 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ec2, 0x2005, 0xa84a, - 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, - 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b90, 0x4b90, 0x4b92, - 0x4b90, 0x4b90, 0x4b90, 0x4b97, 0x4b90, 0x4b90, 0x4b90, 0x4b9c, - 0x4b90, 0x4b90, 0x4b90, 0x4ba1, 0x4b90, 0x4b90, 0x4b90, 0x4ba6, - 0x4b90, 0x4b90, 0x4b90, 0x4bab, 0x4b90, 0x4b90, 0x4b90, 0x4bb0, - 0x080c, 0x0e02, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1c, 0xaa84, - 0xab88, 0xac8c, 0x0804, 0x4b1c, 0xaa94, 0xab98, 0xac9c, 0x0804, - 0x4b1c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1c, 0xaab4, 0xabb8, - 0xacbc, 0x0804, 0x4b1c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1c, - 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4b1c, 0x0026, 0x080c, 0x54dc, - 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4a18, 0x002e, 0x0005, - 0x81ff, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, - 0xc085, 0xc0ac, 0x6032, 0x080c, 0x717f, 0x1158, 0x080c, 0x747b, - 0x080c, 0x5e30, 0x9085, 0x0001, 0x080c, 0x71c3, 0x080c, 0x709f, - 0x0010, 0x080c, 0x5cef, 0x012e, 0x0804, 0x3408, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, - 0x0007, 0x0804, 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, - 0x0804, 0x343a, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e, - 0x0140, 0x7984, 0x080c, 0x6738, 0x1120, 0x2009, 0x4009, 0x0804, - 0x343a, 0x7984, 0x080c, 0x6344, 0x1904, 0x343d, 0x080c, 0x49eb, - 0x0904, 0x343d, 0x2b00, 0x7026, 0x080c, 0x66ca, 0x7888, 0x1170, - 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3408, 0x080c, 0x49b8, - 0x0904, 0x343a, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, - 0x080c, 0xbf65, 0x0904, 0x343a, 0x7888, 0xd094, 0x0118, 0xb8bc, - 0xc08d, 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c80, 0x0005, 0x2061, - 0x1800, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c2, - 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6344, 0x1530, - 0x080c, 0x49e9, 0x0518, 0x080c, 0x66ca, 0xa89c, 0x1168, 0x9084, - 0x0005, 0x1150, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, - 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, - 0xbf65, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, - 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, - 0xa830, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, - 0x340a, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5430, - 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, - 0xc18d, 0x0804, 0x3408, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, - 0x0804, 0x343a, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, - 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0x900e, 0x2130, - 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, - 0x702a, 0x20a0, 0x080c, 0x63a4, 0x1904, 0x4d25, 0x080c, 0x66ca, - 0x0120, 0x080c, 0x66d2, 0x1904, 0x4d25, 0x080c, 0x66c2, 0x1130, - 0x080c, 0x65c4, 0x1118, 0xd79c, 0x0904, 0x4d25, 0xd794, 0x1110, - 0xd784, 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, - 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, - 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c7, 0x0080, 0xb8b4, - 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, - 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c7, 0x4104, - 0xd794, 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000, - 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, - 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, - 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47ba, 0x9c80, - 0x0026, 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, - 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f54, - 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, - 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, - 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cba, 0x86ff, - 0x1120, 0x7124, 0x810b, 0x0804, 0x3408, 0x7033, 0x0001, 0x7122, - 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b, - 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, - 0xa496, 0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x4d61, - 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, - 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, - 0xa494, 0xa598, 0x0804, 0x4cba, 0x7124, 0x810b, 0x0804, 0x3408, - 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, - 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, - 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, - 0x343d, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, - 0x9502, 0x0a04, 0x343d, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, - 0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0xff00, 0x8007, 0x90e2, - 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0x00ff, - 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9484, - 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, - 0x343d, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, - 0x0a04, 0x343d, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e, - 0x0804, 0x3408, 0x0006, 0x080c, 0x54dc, 0xd0cc, 0x000e, 0x0005, - 0x0006, 0x080c, 0x54e0, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84, - 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x3408, 0x83ff, 0x1904, - 0x343d, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x343d, 0x2019, 0xffff, - 0x6074, 0x9302, 0x9200, 0x0a04, 0x343d, 0x7986, 0x6272, 0x0804, - 0x3408, 0x080c, 0x54f0, 0x1904, 0x343a, 0x7c88, 0x7d84, 0x7e98, - 0x7f8c, 0x080c, 0x49b8, 0x0904, 0x343a, 0x900e, 0x901e, 0x7326, - 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, - 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, - 0x0118, 0x080c, 0x66d2, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, - 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, - 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, - 0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408, - 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6, - 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, - 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1140, 0x7007, 0x0002, - 0x701f, 0x4e53, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, - 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c, - 0xa590, 0xa694, 0xa798, 0x0804, 0x4e11, 0x7224, 0x900e, 0x2001, - 0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408, 0x00f6, 0x00e6, - 0x080c, 0x54f0, 0x2009, 0x0007, 0x1904, 0x4ee6, 0x2071, 0x189c, - 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee6, 0xac9c, 0xad98, - 0xaea4, 0xafa0, 0x0096, 0x080c, 0x105c, 0x2009, 0x0002, 0x0904, - 0x4ee6, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, - 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, - 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, - 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, - 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, - 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, - 0x080c, 0x847f, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, - 0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x9006, 0x705e, - 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, - 0x9300, 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076, - 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef2, - 0x000e, 0xa0a2, 0x080c, 0x1140, 0x9006, 0x0048, 0x009e, 0xa897, - 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, - 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0x00e6, - 0x2071, 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, - 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, - 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, - 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, - 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0xaa9a, - 0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x705f, - 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, - 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, - 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118, - 0x080c, 0x66d2, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, - 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, - 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, - 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148, - 0x080c, 0x1075, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, - 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0xa09f, - 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, - 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, - 0x1140, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, - 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, - 0x0804, 0x343d, 0xa884, 0xa988, 0x080c, 0x266e, 0x1518, 0x080c, - 0x6344, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b8, - 0x01c8, 0x080c, 0x49b8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, - 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbee7, - 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, - 0x4fbf, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x343a, 0x7124, - 0x080c, 0x31a6, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, - 0x0804, 0x343a, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, - 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, - 0x002a, 0x080c, 0x0fc0, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, - 0x18b6, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, - 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, - 0x0004, 0x000e, 0x007e, 0x0804, 0x4a04, 0x97c6, 0x7200, 0x11b8, - 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44, - 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, - 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x501b, 0x0005, 0x000e, - 0x007e, 0x0804, 0x343d, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, - 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, - 0x080c, 0x0fc0, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c, - 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a04, 0x81ff, - 0x1904, 0x343a, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102, - 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c, - 0x66d2, 0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6531, 0x012e, 0x0904, 0x343a, 0x2001, - 0x1958, 0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0, - 0x2001, 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc, - 0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c, - 0x646b, 0x2009, 0x0002, 0x0128, 0x080c, 0x6531, 0x1170, 0x2009, - 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, - 0x1958, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006, - 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, - 0xd08c, 0x1118, 0xd084, 0x0904, 0x43d7, 0x080c, 0x49eb, 0x0904, - 0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, - 0x080c, 0x66ca, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, - 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, - 0x080c, 0x54dc, 0xd0b4, 0x0904, 0x4411, 0x7884, 0x908e, 0x007e, - 0x0904, 0x4411, 0x908e, 0x007f, 0x0904, 0x4411, 0x908e, 0x0080, - 0x0904, 0x4411, 0xb800, 0xd08c, 0x1904, 0x4411, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003, - 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x50e7, 0x0005, 0x080c, - 0x49eb, 0x0904, 0x343d, 0x0804, 0x4411, 0x080c, 0x31ff, 0x0108, - 0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, - 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a, - 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4411, 0x9006, 0xa866, - 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf65, 0x1120, 0x2009, - 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5120, 0x0005, - 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5430, - 0x080c, 0x49eb, 0x0904, 0x343d, 0x0804, 0x50b9, 0x81ff, 0x2009, - 0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1904, - 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a, - 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x2009, 0x0009, - 0x1904, 0x343a, 0x080c, 0x49b8, 0x2009, 0x0002, 0x0904, 0x343a, - 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, - 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, - 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x343d, - 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1b8, 0x2009, 0x0003, - 0x0904, 0x343a, 0x7007, 0x0003, 0x701f, 0x5177, 0x0005, 0xa830, - 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x343a, 0x0804, 0x3408, - 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54f0, - 0x1188, 0x2009, 0x0014, 0x0804, 0x343a, 0xd2dc, 0x1578, 0x81ff, - 0x2009, 0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007, - 0x1904, 0x343a, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, - 0x54b6, 0x0804, 0x3408, 0xd2fc, 0x0160, 0x080c, 0x49eb, 0x0904, - 0x343d, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0x0804, - 0x3408, 0x080c, 0x49eb, 0x0904, 0x343d, 0xb804, 0x9084, 0x00ff, - 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5266, 0x080c, 0x49b8, - 0x2009, 0x0002, 0x0904, 0x5266, 0xa85c, 0x9080, 0x001b, 0xaf60, - 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a01, - 0x701f, 0x51d3, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, - 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x343d, - 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49eb, 0x1110, - 0x0804, 0x343d, 0x2009, 0x0043, 0x080c, 0xc224, 0x2009, 0x0003, - 0x0904, 0x5266, 0x7007, 0x0003, 0x701f, 0x51f7, 0x0005, 0xa830, - 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5266, 0x7984, 0x7aa8, - 0x9284, 0x1000, 0xc0d5, 0x080c, 0x548b, 0x0804, 0x3408, 0x00c6, - 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54f0, - 0x1158, 0x2009, 0x0014, 0x0804, 0x5255, 0x2061, 0x1800, 0x080c, - 0x54f0, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, - 0xc0d5, 0x080c, 0x54b6, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e9, - 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0xa87b, - 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e9, - 0x0510, 0x080c, 0x66ca, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, - 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, - 0x1190, 0x080c, 0x49e9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, - 0xc224, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, + 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, + 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, + 0x0005, 0x0804, 0x33f2, 0x7d98, 0x7c9c, 0x0804, 0x34f6, 0x080c, + 0x717e, 0x190c, 0x5df4, 0x2069, 0x185b, 0x2d00, 0x2009, 0x0030, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a00, + 0x701f, 0x419b, 0x0005, 0x080c, 0x54ea, 0x1130, 0x3b00, 0x3a08, + 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x185b, 0x6800, 0x9005, + 0x0904, 0x3427, 0x6804, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, + 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, + 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, + 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, + 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x3427, + 0x9288, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x6162, 0xd0dc, 0x0130, + 0x6828, 0x908a, 0x007f, 0x1a04, 0x3427, 0x605a, 0x6888, 0x9084, + 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x198c, + 0x9080, 0x27a9, 0x2005, 0x200a, 0x000e, 0x2009, 0x198d, 0x9080, + 0x27ad, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x3427, + 0x908a, 0x0841, 0x1a04, 0x3427, 0x9084, 0x0007, 0x1904, 0x3427, + 0x680c, 0x9005, 0x0904, 0x3427, 0x6810, 0x9005, 0x0904, 0x3427, + 0x6848, 0x6940, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427, + 0x684c, 0x6944, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427, + 0x2009, 0x195b, 0x200b, 0x0000, 0x2001, 0x187d, 0x2004, 0xd0c4, + 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e7b, 0x3b00, 0xc085, + 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a, 0x8007, 0x9084, 0x00ff, + 0x604e, 0x080c, 0x74ab, 0x080c, 0x6796, 0x080c, 0x67f9, 0x6808, + 0x602a, 0x080c, 0x2172, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, + 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2710, 0x003e, + 0x6000, 0x9086, 0x0000, 0x1904, 0x4326, 0x6818, 0x691c, 0x6a20, + 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, + 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, + 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, + 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, + 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, + 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001, 0x080c, 0x8362, 0x00c6, + 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, + 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a77, 0x6878, 0x6016, 0x6874, + 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, + 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, + 0x4287, 0x00ce, 0x00c6, 0x2061, 0x1976, 0x2063, 0x0001, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0000, 0x00ce, 0x00e6, + 0x2c70, 0x080c, 0x0ecc, 0x00ee, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x1120, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6888, 0xd0ec, + 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138, 0x2011, + 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011, 0x0114, + 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, + 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, + 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, + 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, + 0x2785, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, + 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x717e, + 0x0128, 0x080c, 0x4dd1, 0x0110, 0x080c, 0x26d6, 0x60d0, 0x9005, + 0x01c0, 0x6003, 0x0001, 0x2009, 0x430e, 0x00d0, 0x080c, 0x717e, + 0x1168, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0, 0x080c, + 0x832d, 0x080c, 0x747f, 0x080c, 0x709e, 0x0040, 0x080c, 0x5cee, + 0x0028, 0x6003, 0x0004, 0x2009, 0x4326, 0x0010, 0x0804, 0x33f2, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x3424, 0x2069, 0x185b, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4a03, 0x9006, 0x080c, 0x26d6, 0x81ff, + 0x1904, 0x3424, 0x080c, 0x717e, 0x11b0, 0x080c, 0x747a, 0x080c, + 0x5e2f, 0x080c, 0x31ee, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xc459, 0x0130, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7156, 0x0038, + 0x080c, 0x709e, 0x0020, 0x080c, 0x5df4, 0x080c, 0x5cee, 0x0804, + 0x33f2, 0x81ff, 0x1904, 0x3424, 0x080c, 0x717e, 0x1110, 0x0804, + 0x3424, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a03, 0x701f, 0x33f0, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x6558, + 0x9588, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a3, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80, + 0x2099, 0x1c80, 0x080c, 0x5d7f, 0x0804, 0x4381, 0x080c, 0x49ea, + 0x0904, 0x3427, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, + 0x3424, 0x080c, 0x54db, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x31e9, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, + 0x0003, 0x701f, 0x440c, 0x0005, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0fb4, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fb4, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4a03, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904, + 0x3427, 0x080c, 0x6515, 0x0904, 0x3424, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa974, 0xaa94, 0x0804, + 0x33f2, 0x080c, 0x54e3, 0x0904, 0x33f2, 0x701f, 0x4456, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x3424, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x3427, 0x080c, 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, + 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x659a, 0x0904, + 0x3424, 0x2019, 0x0004, 0x900e, 0x080c, 0x6527, 0x0904, 0x3424, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x49e8, 0x01e0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, + 0x11b0, 0x080c, 0x659a, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x6527, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x63a3, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267, + 0x0005, 0x81ff, 0x1904, 0x3424, 0x798c, 0x2001, 0x195a, 0x918c, + 0x8000, 0x2102, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9, + 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x646a, 0x0904, + 0x3424, 0x080c, 0x651e, 0x0904, 0x3424, 0x2001, 0x195a, 0x2004, + 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001, 0x195a, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0, 0x080c, + 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x651e, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, - 0x0904, 0x343a, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, - 0x548b, 0x001e, 0x1904, 0x343a, 0x0804, 0x3408, 0x00f6, 0x2d78, - 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, - 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548b, 0x001e, - 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a, - 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d, - 0x9186, 0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009, - 0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, - 0x343a, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, - 0x8007, 0xa80a, 0x080c, 0xbf20, 0x1120, 0x2009, 0x0003, 0x0804, - 0x343a, 0x7007, 0x0003, 0x701f, 0x52c6, 0x0005, 0xa808, 0x8007, - 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa8e0, - 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, - 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x080c, 0x49b8, 0x1120, - 0x2009, 0x0002, 0x0804, 0x343a, 0x7984, 0x9194, 0xff00, 0x918c, - 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6, - 0x0001, 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x343d, 0x2009, - 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x080c, 0x4a01, 0x701f, 0x5316, 0x0005, 0x2001, 0x182d, - 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, - 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, - 0x3408, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, - 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, - 0x2099, 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8, - 0x0010, 0x0804, 0x343d, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, - 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x3424, + 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c, 0x49ce, + 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1, 0x1904, + 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904, + 0x3424, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804, + 0x4461, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x49db, 0x01a0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, + 0x1170, 0x080c, 0x646a, 0x2009, 0x0002, 0x0128, 0x080c, 0x650c, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x080c, 0x54ef, 0x1904, 0x3424, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x33f2, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, + 0x939a, 0x0003, 0x1a04, 0x3424, 0x6258, 0x7884, 0x9206, 0x1560, + 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840, 0x2009, + 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0006, + 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a03, 0x000e, + 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, + 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1134, 0x7007, + 0x0002, 0x701f, 0x461c, 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x1904, 0x3424, 0x00c6, + 0x080c, 0x49b7, 0x00ce, 0x0904, 0x3424, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbebf, 0x0904, 0x3424, 0x7007, + 0x0003, 0x701f, 0x4620, 0x0005, 0x080c, 0x416d, 0x0804, 0x33f2, + 0xa830, 0x9086, 0x0100, 0x0904, 0x3424, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x9006, 0x080c, + 0x26d6, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, + 0x1904, 0x3424, 0x080c, 0x717e, 0x0110, 0x080c, 0x5df4, 0x7888, + 0x908a, 0x1000, 0x1a04, 0x3427, 0x7984, 0x9186, 0x00ff, 0x0138, + 0x9182, 0x007f, 0x1a04, 0x3427, 0x2100, 0x080c, 0x26a0, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b, 0x0000, + 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, 0x717e, + 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x080c, 0x709e, 0x00d0, 0x080c, 0x9f70, 0x2061, 0x0100, + 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, + 0x2009, 0x002d, 0x2011, 0x5d1a, 0x080c, 0x82eb, 0x7984, 0x080c, + 0x717e, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c4, 0x012e, + 0x00ce, 0x002e, 0x0804, 0x33f2, 0x7984, 0x080c, 0x6343, 0x2b08, + 0x1904, 0x3427, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x3424, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, + 0x0005, 0x0804, 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, + 0x0804, 0x3424, 0x7984, 0x81ff, 0x0904, 0x3427, 0x9192, 0x0021, + 0x1a04, 0x3427, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, + 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a00, 0x701f, 0x46d7, + 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f83, 0x0005, 0x2009, + 0x0080, 0x080c, 0x63a3, 0x1118, 0x080c, 0x66c9, 0x0120, 0x2021, + 0x400a, 0x0804, 0x33f4, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, + 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4770, + 0x90be, 0x0112, 0x0904, 0x4770, 0x90be, 0x0113, 0x0904, 0x4770, + 0x90be, 0x0114, 0x0904, 0x4770, 0x90be, 0x0117, 0x0904, 0x4770, + 0x90be, 0x011a, 0x0904, 0x4770, 0x90be, 0x011c, 0x0904, 0x4770, + 0x90be, 0x0121, 0x0904, 0x4757, 0x90be, 0x0131, 0x0904, 0x4757, + 0x90be, 0x0171, 0x0904, 0x4770, 0x90be, 0x0173, 0x0904, 0x4770, + 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x477b, + 0x90be, 0x0212, 0x0904, 0x4764, 0x90be, 0x0213, 0x05e8, 0x90be, + 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, + 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, + 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x3427, 0x7028, 0x9080, + 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, + 0x080c, 0x47b9, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, + 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47b9, 0x00c8, 0x7028, + 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, + 0x0001, 0x080c, 0x47c6, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47c6, + 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b7, 0x0550, 0xa868, + 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, + 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, + 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, + 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbeda, 0x1120, + 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x47b0, + 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x3424, + 0xa820, 0x9086, 0x8001, 0x1904, 0x33f2, 0x2009, 0x0004, 0x0804, + 0x3424, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, + 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, + 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, + 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x60d8, + 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x3424, + 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3424, 0x7984, 0x78a8, + 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427, + 0x9186, 0x00ff, 0x0904, 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427, + 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e, 0x0904, + 0x3427, 0x080c, 0x9f69, 0x1120, 0x99cc, 0xff00, 0x0904, 0x3427, + 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x0140, 0x918d, 0x8000, 0x080c, + 0x6737, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d1, 0x0560, + 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c, 0x65c3, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, + 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, + 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, + 0x2020, 0x012e, 0x0804, 0x33f4, 0x2b00, 0x7026, 0x0016, 0x00b6, + 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa03b, 0x0904, 0x489e, 0x2b00, + 0x6012, 0x080c, 0xc1ca, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, + 0x49b7, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fea, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e, + 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x3095, 0x6023, 0x0001, 0x9006, + 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002, + 0x080c, 0xa068, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, + 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, + 0x7007, 0x0003, 0x701f, 0x48ad, 0x0005, 0xa830, 0x2008, 0x918e, + 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4, 0x9086, 0x0100, + 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, + 0x0804, 0x542f, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x33f2, 0x080c, + 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, + 0x33f2, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4919, 0x902e, + 0x080c, 0x9f69, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, + 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, + 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce, 0x007f, + 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080, 0x1130, + 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd, 0x0450, + 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600, 0x9206, + 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894, 0x1558, + 0x080c, 0x66c9, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, + 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, + 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f69, 0x1930, 0x2001, + 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e7, 0x85ff, 0x1130, + 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x6343, + 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c, + 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x3427, 0x9096, + 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x3427, 0x2010, 0x2918, + 0x080c, 0x303b, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, + 0x0003, 0x701f, 0x496c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, + 0x33f2, 0x2009, 0x0004, 0x0804, 0x3424, 0x7984, 0x080c, 0x9f69, + 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427, 0x9186, 0x00ff, 0x0904, + 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427, 0x2001, 0x9400, 0x080c, + 0x548a, 0x1904, 0x3424, 0x0804, 0x33f2, 0xa998, 0x080c, 0x9f69, + 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, + 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548a, 0x11a8, 0x0060, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, + 0x1037, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, + 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, + 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, + 0x63a3, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, + 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a3, 0x1130, 0xae9c, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, + 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a3, 0x1108, 0x0008, + 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, + 0xa904, 0x080c, 0x1069, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, + 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, + 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, + 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x33f2, 0x0005, 0x00f6, + 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae, 0x2004, + 0x9005, 0x1190, 0x0e04, 0x4a34, 0x7a36, 0x7833, 0x0012, 0x7a82, + 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x0804, 0x4a9a, 0x0016, 0x0086, 0x0096, 0x00c6, + 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, + 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1037, 0x0904, 0x4a92, + 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe, + 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18b8, + 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a, 0x7148, + 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, + 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, + 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, + 0x1520, 0x080c, 0x1037, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, + 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, + 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005, + 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, + 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, + 0x0002, 0x4abc, 0x4abc, 0x4abe, 0x4abc, 0x4abc, 0x4abc, 0x4ac2, + 0x4abc, 0x4abc, 0x4abc, 0x4ac6, 0x4abc, 0x4abc, 0x4abc, 0x4aca, + 0x4abc, 0x4abc, 0x4abc, 0x4ace, 0x4abc, 0x4abc, 0x4abc, 0x4ad2, + 0x4abc, 0x4abc, 0x4abc, 0x4ad7, 0x080c, 0x0df6, 0xa276, 0xa37a, + 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, + 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, + 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a95, 0xa2d6, + 0xa3da, 0xa4de, 0x0804, 0x4a95, 0x00e6, 0x2071, 0x189c, 0x7048, + 0x9005, 0x0904, 0x4b6e, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4b6d, + 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, + 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, + 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105, + 0x9005, 0xa94a, 0x1904, 0x4b70, 0xa804, 0x9005, 0x090c, 0x0df6, + 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, + 0x1ebe, 0x2005, 0xa04a, 0x0804, 0x4b70, 0x703c, 0x2060, 0x2c14, + 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, + 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x87ff, 0x0118, 0x2748, 0x080c, + 0x1069, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, + 0x9005, 0x0128, 0x080c, 0x1069, 0x9006, 0x7042, 0x7046, 0x703b, + 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, + 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8, 0x0210, + 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, + 0x9005, 0x090c, 0x0df6, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, + 0x7042, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005, 0xa84a, 0x0000, + 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, + 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b8f, 0x4b8f, 0x4b91, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4b96, 0x4b8f, 0x4b8f, 0x4b8f, 0x4b9b, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4ba0, 0x4b8f, 0x4b8f, 0x4b8f, 0x4ba5, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4baa, 0x4b8f, 0x4b8f, 0x4b8f, 0x4baf, 0x080c, + 0x0df6, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1b, 0xaa84, 0xab88, + 0xac8c, 0x0804, 0x4b1b, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4b1b, + 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1b, 0xaab4, 0xabb8, 0xacbc, + 0x0804, 0x4b1b, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1b, 0xaad4, + 0xabd8, 0xacdc, 0x0804, 0x4b1b, 0x0026, 0x080c, 0x54db, 0xd0c4, + 0x0120, 0x2011, 0x8014, 0x080c, 0x4a17, 0x002e, 0x0005, 0x81ff, + 0x1904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, + 0xc0ac, 0x6032, 0x080c, 0x717e, 0x1158, 0x080c, 0x747a, 0x080c, + 0x5e2f, 0x9085, 0x0001, 0x080c, 0x71c2, 0x080c, 0x709e, 0x0010, + 0x080c, 0x5cee, 0x012e, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009, + 0x0001, 0x0804, 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, + 0x0804, 0x3424, 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, + 0x3424, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, 0x0140, + 0x7984, 0x080c, 0x6737, 0x1120, 0x2009, 0x4009, 0x0804, 0x3424, + 0x7984, 0x080c, 0x6343, 0x1904, 0x3427, 0x080c, 0x49ea, 0x0904, + 0x3427, 0x2b00, 0x7026, 0x080c, 0x66c9, 0x7888, 0x1170, 0x9084, + 0x0005, 0x1158, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x33f2, 0x080c, 0x49b7, 0x0904, + 0x3424, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, + 0xbf78, 0x0904, 0x3424, 0x7888, 0xd094, 0x0118, 0xb8bc, 0xc08d, + 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c7f, 0x0005, 0x2061, 0x1800, + 0x080c, 0x54ef, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c1, 0x0118, + 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6343, 0x1530, 0x080c, + 0x49e8, 0x0518, 0x080c, 0x66c9, 0xa89c, 0x1168, 0x9084, 0x0005, + 0x1150, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xbf78, + 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x2009, + 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, + 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, + 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4, + 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x542f, 0x900e, + 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, + 0x0804, 0x33f2, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, + 0x3424, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e, 0x2130, 0x7126, + 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, + 0x20a0, 0x080c, 0x63a3, 0x1904, 0x4d24, 0x080c, 0x66c9, 0x0120, + 0x080c, 0x66d1, 0x1904, 0x4d24, 0x080c, 0x66c1, 0x1130, 0x080c, + 0x65c3, 0x1118, 0xd79c, 0x0904, 0x4d24, 0xd794, 0x1110, 0xd784, + 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x3400, + 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, + 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c6, 0x0080, 0xb8b4, 0x20e0, + 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c6, 0x4104, 0xd794, + 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000, 0x2098, + 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, + 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47b9, 0x9c80, 0x0026, + 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, + 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f69, 0x0118, + 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, + 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, + 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cb9, 0x86ff, 0x1120, + 0x7124, 0x810b, 0x0804, 0x33f2, 0x7033, 0x0001, 0x7122, 0x7024, + 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000, + 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x4d60, 0x0005, + 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, + 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x0804, 0x4cb9, 0x7124, 0x810b, 0x0804, 0x33f2, 0x2029, + 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9184, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, + 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, + 0x0a04, 0x3427, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, + 0x9502, 0x0a04, 0x3427, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, + 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9384, 0x00ff, 0x90e2, + 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9484, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, + 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, + 0x3427, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, + 0x33f2, 0x0006, 0x080c, 0x54db, 0xd0cc, 0x000e, 0x0005, 0x0006, + 0x080c, 0x54df, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84, 0x6300, + 0x82ff, 0x1118, 0x7986, 0x0804, 0x33f2, 0x83ff, 0x1904, 0x3427, + 0x2001, 0xfff0, 0x9200, 0x1a04, 0x3427, 0x2019, 0xffff, 0x6074, + 0x9302, 0x9200, 0x0a04, 0x3427, 0x7986, 0x6272, 0x0804, 0x33f2, + 0x080c, 0x54ef, 0x1904, 0x3424, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, + 0x080c, 0x49b7, 0x0904, 0x3424, 0x900e, 0x901e, 0x7326, 0x7332, + 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, + 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, + 0x080c, 0x66d1, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, + 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, + 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, + 0x2001, 0x0003, 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x7033, + 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6, 0x2c44, + 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, + 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, + 0x4e52, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, + 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c, 0xa590, + 0xa694, 0xa798, 0x0804, 0x4e10, 0x7224, 0x900e, 0x2001, 0x0003, + 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x00f6, 0x00e6, 0x080c, + 0x54ef, 0x2009, 0x0007, 0x1904, 0x4ee5, 0x2071, 0x189c, 0x745c, + 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee5, 0xac9c, 0xad98, 0xaea4, + 0xafa0, 0x0096, 0x080c, 0x1050, 0x2009, 0x0002, 0x0904, 0x4ee5, + 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, + 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, + 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1148, + 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, + 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, + 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, + 0x847e, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, + 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x9006, 0x705e, 0x918d, + 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, + 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef1, 0x000e, + 0xa0a2, 0x080c, 0x1134, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, + 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0x00e6, 0x2071, + 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, + 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847e, 0xaa9a, 0x715c, + 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x705f, 0x0000, + 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, + 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c, + 0x66d1, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, + 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c, + 0x1069, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0xa09f, 0x0000, + 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134, + 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, + 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, + 0x3427, 0xa884, 0xa988, 0x080c, 0x266d, 0x1518, 0x080c, 0x6343, + 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b7, 0x01c8, + 0x080c, 0x49b7, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbefa, 0x1120, + 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x4fbe, + 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x3424, 0x7124, 0x080c, + 0x3190, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, + 0x3424, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, + 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, + 0x080c, 0x0fb4, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b6, + 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, + 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, + 0x000e, 0x007e, 0x0804, 0x4a03, 0x97c6, 0x7200, 0x11b8, 0x96c2, + 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44, 0xa076, + 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, + 0x1134, 0x7007, 0x0002, 0x701f, 0x501a, 0x0005, 0x000e, 0x007e, + 0x0804, 0x3427, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0fb4, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a03, 0x81ff, 0x1904, + 0x3424, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102, 0x080c, + 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1, + 0x1904, 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6530, 0x012e, 0x0904, 0x3424, 0x2001, 0x1958, + 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001, + 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0, + 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a, + 0x2009, 0x0002, 0x0128, 0x080c, 0x6530, 0x1170, 0x2009, 0x0003, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1958, + 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, + 0x1118, 0xd084, 0x0904, 0x43d6, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x080c, + 0x66c9, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, + 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, + 0x54db, 0xd0b4, 0x0904, 0x4410, 0x7884, 0x908e, 0x007e, 0x0904, + 0x4410, 0x908e, 0x007f, 0x0904, 0x4410, 0x908e, 0x0080, 0x0904, + 0x4410, 0xb800, 0xd08c, 0x1904, 0x4410, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804, + 0x3424, 0x7007, 0x0003, 0x701f, 0x50e6, 0x0005, 0x080c, 0x49ea, + 0x0904, 0x3427, 0x0804, 0x4410, 0x080c, 0x31e9, 0x0108, 0x0005, + 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, + 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0xb89c, + 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4410, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf78, 0x1120, 0x2009, 0x0003, + 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x511f, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x542f, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x0804, 0x50b8, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904, 0x3424, + 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x2009, 0x0009, 0x1904, + 0x3424, 0x080c, 0x49b7, 0x2009, 0x0002, 0x0904, 0x3424, 0x9006, + 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, + 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, + 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x3427, 0xc0e5, + 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1cb, 0x2009, 0x0003, 0x0904, + 0x3424, 0x7007, 0x0003, 0x701f, 0x5176, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x3424, 0x0804, 0x33f2, 0x7aa8, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54ef, 0x1188, + 0x2009, 0x0014, 0x0804, 0x3424, 0xd2dc, 0x1578, 0x81ff, 0x2009, + 0x0001, 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904, + 0x3424, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x54b5, + 0x0804, 0x33f2, 0xd2fc, 0x0160, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2, + 0x080c, 0x49ea, 0x0904, 0x3427, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x2009, 0x0009, 0x1904, 0x5265, 0x080c, 0x49b7, 0x2009, + 0x0002, 0x0904, 0x5265, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, + 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a00, 0x701f, + 0x51d2, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, + 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x3427, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49ea, 0x1110, 0x0804, + 0x3427, 0x2009, 0x0043, 0x080c, 0xc237, 0x2009, 0x0003, 0x0904, + 0x5265, 0x7007, 0x0003, 0x701f, 0x51f6, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x5265, 0x7984, 0x7aa8, 0x9284, + 0x1000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2, 0x00c6, 0xaab0, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54ef, 0x1158, + 0x2009, 0x0014, 0x0804, 0x5254, 0x2061, 0x1800, 0x080c, 0x54ef, + 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, + 0x080c, 0x54b5, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e8, 0x0590, + 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e8, 0x0510, + 0x080c, 0x66c9, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, + 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, + 0x080c, 0x49e8, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xc237, + 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, + 0x3424, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548a, + 0x001e, 0x1904, 0x3424, 0x0804, 0x33f2, 0x00f6, 0x2d78, 0xaab0, + 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, + 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548a, 0x001e, 0x9085, + 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, + 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984, + 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186, + 0x007f, 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804, + 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, + 0xa80a, 0x080c, 0xbf33, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, + 0x7007, 0x0003, 0x701f, 0x52c5, 0x0005, 0xa808, 0x8007, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa8e0, 0xa866, + 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x080c, 0x49b7, 0x1120, 0x2009, + 0x0002, 0x0804, 0x3424, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, + 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6, 0x0001, + 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x3427, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, - 0x0804, 0x4a04, 0x7884, 0x908a, 0x1000, 0x1a04, 0x343d, 0x0126, - 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, - 0x19d5, 0x614a, 0x00ce, 0x012e, 0x0804, 0x3408, 0x00c6, 0x080c, - 0x717f, 0x1160, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001, - 0x080c, 0x71c3, 0x080c, 0x709f, 0x080c, 0x0e02, 0x2061, 0x1800, - 0x6030, 0xc09d, 0x6032, 0x080c, 0x5cef, 0x00ce, 0x0005, 0x00c6, - 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x343a, 0x7884, - 0x9005, 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c, - 0x2a98, 0x01a0, 0x080c, 0x2aa0, 0x0188, 0x080c, 0x2aa8, 0x0170, - 0x2162, 0x0804, 0x343d, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, - 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, - 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, - 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c, 0x9918, - 0x002e, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c, 0x989c, 0x003e, - 0x60e3, 0x0000, 0x080c, 0xdb7a, 0x080c, 0xdb95, 0x9085, 0x0001, - 0x080c, 0x71c3, 0x9006, 0x080c, 0x2b88, 0x2001, 0x1800, 0x2003, - 0x0004, 0x2001, 0x1981, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, - 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a, - 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a, 0x7984, - 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d, 0x9186, - 0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009, 0x0804, - 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, - 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf23, 0x1120, - 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5419, - 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, - 0x343a, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, - 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a04, - 0xa898, 0x9086, 0x000d, 0x1904, 0x343a, 0x2021, 0x4005, 0x0126, - 0x2091, 0x8000, 0x0e04, 0x543d, 0x0010, 0x012e, 0x0cc0, 0x7c36, - 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, - 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, - 0x080c, 0x49f4, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, - 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5, - 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, - 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, - 0x19e5, 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b, - 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, - 0x012e, 0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, - 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, - 0x0029, 0x080c, 0x31c4, 0x003e, 0x080c, 0xbd88, 0x000e, 0x1198, - 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, - 0x5e4a, 0x080c, 0x9f54, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, - 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, - 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, - 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, - 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, - 0x0026, 0x2200, 0x080c, 0x548b, 0x002e, 0x001e, 0x8108, 0x1f04, - 0x54be, 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005, - 0x2001, 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, - 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, - 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, - 0x2071, 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, - 0x79a4, 0x81ff, 0x0904, 0x343d, 0x9182, 0x0081, 0x1a04, 0x343d, - 0x810c, 0x0016, 0x080c, 0x49b8, 0x0170, 0x080c, 0x0f4b, 0x2100, - 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a01, - 0x701f, 0x5520, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x343a, - 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, - 0x2061, 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c, - 0x4a04, 0x701f, 0x5534, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016, - 0x0026, 0xa270, 0xa174, 0x080c, 0x0f53, 0x002e, 0x001e, 0x080c, - 0x1000, 0x9006, 0xa802, 0xa806, 0x0804, 0x3408, 0x0126, 0x0156, - 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, - 0x11e8, 0xd084, 0x0118, 0x080c, 0x56ef, 0x0068, 0xd08c, 0x0118, - 0x080c, 0x55f8, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c8, 0x0018, - 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, - 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, - 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094, - 0x9005, 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c, - 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, - 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, - 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, - 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dac, - 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, - 0x0000, 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db, - 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087, - 0x000f, 0x2009, 0x000f, 0x2011, 0x5c92, 0x080c, 0x82ec, 0x0005, - 0x2001, 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084, - 0x9005, 0x1528, 0x2011, 0x5c92, 0x080c, 0x825a, 0x6040, 0x9094, - 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, - 0x1168, 0x1f04, 0x55de, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094, - 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097, - 0x0000, 0x708b, 0x0000, 0x9006, 0x080c, 0x5e35, 0x0000, 0x0005, - 0x7088, 0x908a, 0x0003, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5602, - 0x5653, 0x56ee, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b, - 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, - 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5611, 0x080c, - 0x0e02, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, - 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e11, - 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, - 0x4003, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, + 0x080c, 0x4a00, 0x701f, 0x5315, 0x0005, 0x2001, 0x182d, 0x2003, + 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, + 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x33f2, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x7984, + 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, + 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8, 0x0010, + 0x0804, 0x3427, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, + 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, + 0x4a03, 0x7884, 0x908a, 0x1000, 0x1a04, 0x3427, 0x0126, 0x2091, + 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19d5, + 0x614a, 0x00ce, 0x012e, 0x0804, 0x33f2, 0x00c6, 0x080c, 0x717e, + 0x1160, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x080c, 0x709e, 0x080c, 0x0df6, 0x2061, 0x1800, 0x6030, + 0xc09d, 0x6032, 0x080c, 0x5cee, 0x00ce, 0x0005, 0x00c6, 0x2001, + 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x3424, 0x7884, 0x9005, + 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c, 0x2a7f, + 0x01a0, 0x080c, 0x2a87, 0x0188, 0x080c, 0x2a8f, 0x0170, 0x2162, + 0x0804, 0x3427, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, + 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, + 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011, + 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, 0x002e, + 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x60e3, + 0x0000, 0x080c, 0xdbdb, 0x080c, 0xdbf6, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x9006, 0x080c, 0x2b6f, 0x2001, 0x1800, 0x2003, 0x0004, + 0x2001, 0x1982, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804, + 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c, + 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186, 0x007f, + 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804, 0x3424, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf36, 0x1120, 0x2009, + 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x5418, 0x0005, + 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424, + 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a03, 0xa898, + 0x9086, 0x000d, 0x1904, 0x3424, 0x2021, 0x4005, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x543c, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, + 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, + 0x49f3, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5, 0x7984, + 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, + 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x19e5, + 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, + 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, + 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, + 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029, + 0x080c, 0x31ae, 0x003e, 0x080c, 0xbd9b, 0x000e, 0x1198, 0xd0e4, + 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5e49, + 0x080c, 0x9f69, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, + 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, + 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, + 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, + 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, + 0x2200, 0x080c, 0x548a, 0x002e, 0x001e, 0x8108, 0x1f04, 0x54bd, + 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005, 0x2001, + 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, + 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, + 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, + 0x81ff, 0x0904, 0x3427, 0x9182, 0x0081, 0x1a04, 0x3427, 0x810c, + 0x0016, 0x080c, 0x49b7, 0x0170, 0x080c, 0x0f3f, 0x2100, 0x2238, + 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a00, 0x701f, + 0x551f, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x3424, 0x2079, + 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, + 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c, 0x4a03, + 0x701f, 0x5533, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016, 0x0026, + 0xa270, 0xa174, 0x080c, 0x0f47, 0x002e, 0x001e, 0x080c, 0x0ff4, + 0x9006, 0xa802, 0xa806, 0x0804, 0x33f2, 0x0126, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, + 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, + 0xd084, 0x0118, 0x080c, 0x56ee, 0x0068, 0xd08c, 0x0118, 0x080c, + 0x55f7, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c7, 0x0018, 0xd09c, + 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, + 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094, 0x9005, + 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c, 0x9286, + 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, + 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, + 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x00f0, + 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, + 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db, 0x0000, + 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087, 0x000f, + 0x2009, 0x000f, 0x2011, 0x5c91, 0x080c, 0x82eb, 0x0005, 0x2001, + 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084, 0x9005, + 0x1528, 0x2011, 0x5c91, 0x080c, 0x8259, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, + 0x1f04, 0x55dd, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097, 0x0000, + 0x708b, 0x0000, 0x9006, 0x080c, 0x5e34, 0x0000, 0x0005, 0x7088, + 0x908a, 0x0003, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x5601, 0x5652, + 0x56ed, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b, 0x0001, + 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, + 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5610, 0x080c, 0x0df6, + 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, + 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e10, 0x2079, + 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, + 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, + 0x0000, 0x080c, 0x5cc2, 0x00fe, 0x9006, 0x708e, 0x6043, 0x0008, + 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025, 0x0904, + 0x56ca, 0x6020, 0xd0b4, 0x1904, 0x56c8, 0x719c, 0x81ff, 0x0904, + 0x56b6, 0x9486, 0x000c, 0x1904, 0x56c3, 0x9480, 0x0018, 0x8004, + 0x20a8, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, + 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x566f, 0x6043, + 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, + 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002, 0x2009, + 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x080c, 0x5e10, 0x04c0, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, + 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, + 0x9005, 0x0190, 0x080c, 0x5e09, 0x2011, 0x026e, 0x2019, 0x1805, + 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, + 0x8318, 0x1f04, 0x56aa, 0x0078, 0x709f, 0x0000, 0x080c, 0x5e09, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, + 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, + 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, + 0x1db8, 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, - 0x600f, 0x0000, 0x080c, 0x5cc3, 0x00fe, 0x9006, 0x708e, 0x6043, - 0x0008, 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025, - 0x0904, 0x56cb, 0x6020, 0xd0b4, 0x1904, 0x56c9, 0x719c, 0x81ff, - 0x0904, 0x56b7, 0x9486, 0x000c, 0x1904, 0x56c4, 0x9480, 0x0018, - 0x8004, 0x20a8, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2019, 0x1c00, - 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5670, - 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, - 0x2061, 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002, - 0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x080c, 0x5e11, - 0x04c0, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, - 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, - 0x7804, 0x9005, 0x0190, 0x080c, 0x5e0a, 0x2011, 0x026e, 0x2019, - 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, - 0x8210, 0x8318, 0x1f04, 0x56ab, 0x0078, 0x709f, 0x0000, 0x080c, - 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, - 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, - 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, - 0xd0b4, 0x1db8, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00, - 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, - 0x000c, 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3, - 0x0056, 0x60a7, 0x9575, 0x080c, 0x95fc, 0x08d8, 0x0005, 0x7094, - 0x908a, 0x001d, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5720, 0x5733, - 0x575c, 0x577c, 0x57a2, 0x57d1, 0x57f7, 0x582f, 0x5855, 0x5883, - 0x58be, 0x58f6, 0x5914, 0x593f, 0x5961, 0x597c, 0x5986, 0x59ba, - 0x59e0, 0x5a0f, 0x5a35, 0x5a6d, 0x5ab1, 0x5aee, 0x5b0f, 0x5b68, - 0x5b8a, 0x5bb8, 0x5bb8, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, - 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, - 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, - 0x6043, 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c99, - 0x080c, 0x82ec, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510, - 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e0a, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, - 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, - 0x5c99, 0x080c, 0x825a, 0x7097, 0x0010, 0x080c, 0x5986, 0x0010, - 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043, - 0x0004, 0x2011, 0x5c99, 0x080c, 0x825a, 0x080c, 0x5d8e, 0x2079, - 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, - 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5771, 0x60c3, 0x0014, - 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, - 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, - 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, - 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, - 0x70c3, 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de6, - 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8e, 0x2079, - 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, - 0x5ded, 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, - 0x0138, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3, - 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, - 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, - 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, + 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x080c, 0x9611, 0x08d8, 0x0005, 0x7094, 0x908a, + 0x001d, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x571f, 0x5732, 0x575b, + 0x577b, 0x57a1, 0x57d0, 0x57f6, 0x582e, 0x5854, 0x5882, 0x58bd, + 0x58f5, 0x5913, 0x593e, 0x5960, 0x597b, 0x5985, 0x59b9, 0x59df, + 0x5a0e, 0x5a34, 0x5a6c, 0x5ab0, 0x5aed, 0x5b0e, 0x5b67, 0x5b89, + 0x5bb7, 0x5bb7, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, + 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, + 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, + 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c98, 0x080c, + 0x82eb, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510, 0x6042, + 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, + 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7097, 0x0010, 0x080c, 0x5985, 0x0010, 0x708f, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043, 0x0004, + 0x2011, 0x5c98, 0x080c, 0x8259, 0x080c, 0x5d8d, 0x2079, 0x0240, + 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, + 0x200b, 0x0000, 0x8108, 0x1f04, 0x5770, 0x60c3, 0x0014, 0x080c, + 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, + 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, + 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, + 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8d, 0x2079, 0x0240, + 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, + 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, + 0x2011, 0x0008, 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9, + 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, + 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0006, + 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, + 0x0007, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, + 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005, + 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180, + 0x080c, 0x4dd7, 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029, 0x0010, + 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009, 0x080c, + 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, + 0x5dec, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb8, 0x1188, + 0x9085, 0x0001, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x080c, 0x5e09, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x0010, 0x080c, 0x5712, + 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e09, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, + 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1, 0x0098, + 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, + 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c, 0x5960, + 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000b, + 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, + 0xffff, 0x4304, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1106, + 0x7837, 0x0000, 0x080c, 0x5dec, 0x0118, 0x2013, 0x0000, 0x0020, + 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, + 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, + 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e2, 0x60c3, + 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, + 0x01c0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1178, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, + 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010, 0x080c, + 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c, 0x5d8d, + 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x5e09, + 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, + 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, + 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5926, + 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, + 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, + 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, 0x5d5f, + 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, + 0x918d, 0x0001, 0x080c, 0x5e34, 0x7097, 0x000f, 0x708f, 0x0000, + 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, + 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5c98, + 0x080c, 0x824d, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011, 0x080c, + 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080, 0x0007, + 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5dec, 0x11a0, + 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff, 0x0160, + 0x080c, 0x266d, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, + 0x2011, 0x0008, 0x080c, 0x5c45, 0x60c3, 0x0014, 0x080c, 0x5cc2, + 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, + 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, - 0x0006, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, - 0x7097, 0x0007, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1104, - 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080, - 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209, - 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46, - 0x0180, 0x080c, 0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008, - 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, - 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, - 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, - 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, - 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029, - 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009, - 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, - 0x080c, 0x5ded, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb9, - 0x1188, 0x9085, 0x0001, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x080c, - 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x0010, 0x080c, - 0x5713, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011, - 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e0a, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, - 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, - 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1, - 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, - 0x1110, 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c, - 0x5961, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, - 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, - 0x2019, 0xffff, 0x4304, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, - 0x1106, 0x7837, 0x0000, 0x080c, 0x5ded, 0x0118, 0x2013, 0x0000, - 0x0020, 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, - 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, - 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e3, - 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, - 0x9005, 0x01c0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084, - 0x1178, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, - 0x1138, 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010, - 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c, - 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, - 0x5e0a, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, - 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, - 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, - 0x5927, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, - 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, - 0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, - 0x5d60, 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe, - 0x0005, 0x918d, 0x0001, 0x080c, 0x5e35, 0x7097, 0x000f, 0x708f, - 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, - 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, - 0x5c99, 0x080c, 0x824e, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011, - 0x5c99, 0x080c, 0x825a, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011, - 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260, - 0x20e9, 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080, - 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5ded, - 0x11a0, 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff, - 0x0160, 0x080c, 0x266e, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, - 0x0120, 0x2011, 0x0008, 0x080c, 0x5c46, 0x60c3, 0x0014, 0x080c, - 0x5cc3, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, - 0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, - 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, - 0x7097, 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, - 0x00f6, 0x7097, 0x0013, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, - 0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x1170, - 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011, - 0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3, 0x20a9, 0x0008, - 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, - 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, - 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, - 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, - 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029, - 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015, - 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, - 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080, 0x9005, 0x11a0, - 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209, 0x200d, 0x918c, - 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0180, 0x080c, - 0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, - 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, - 0x05f0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x15a8, - 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, - 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, - 0x0001, 0x080c, 0x5e35, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, - 0x1110, 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, - 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001, - 0x080c, 0x5e35, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, - 0x0008, 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, - 0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099, - 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, - 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, - 0x2011, 0x026e, 0x7097, 0x0017, 0x080c, 0x5ded, 0x1150, 0x7080, - 0x9005, 0x1138, 0x080c, 0x5bb9, 0x1188, 0x9085, 0x0001, 0x080c, - 0x26d7, 0x20a9, 0x0008, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099, + 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, + 0x7097, 0x0013, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1103, + 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x1170, 0x7080, + 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, + 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029, 0x0010, + 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015, 0x080c, + 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, + 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160, + 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d, 0x918c, 0xff00, + 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180, 0x080c, 0x4dd7, + 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, - 0x080c, 0x5cc3, 0x0010, 0x080c, 0x5713, 0x0005, 0x00f6, 0x708c, - 0x9005, 0x01d8, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084, - 0x1190, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, - 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e35, 0x7097, - 0x0018, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, - 0x7097, 0x0019, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1106, - 0x7837, 0x0000, 0x080c, 0x5e0a, 0x2009, 0x026e, 0x2039, 0x1c0e, - 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, - 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b22, 0x2039, - 0x1c0e, 0x080c, 0x5ded, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, - 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, - 0x705c, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, - 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, - 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, - 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, - 0x1f04, 0x5b55, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, - 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a, - 0x9086, 0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, - 0x080c, 0x5d60, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000, - 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x5e35, 0x7097, 0x001b, - 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2009, 0x0240, - 0x748c, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, - 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, - 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, - 0x0260, 0x1f04, 0x5ba1, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x0005, - 0x0005, 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008, - 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e0a, 0x20e1, - 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, - 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, - 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd3, - 0x0804, 0x5c42, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, - 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c42, 0x918d, 0xc000, - 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, - 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, - 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf9, 0x04d8, 0x23a8, - 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0b, 0x2328, 0x8529, - 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, - 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c1a, 0x755a, 0x95c8, - 0x3209, 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, - 0x2508, 0x080c, 0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, - 0x2304, 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, - 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, - 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, - 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, - 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, - 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, - 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, - 0x942c, 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x3209, 0x242d, - 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, - 0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084, - 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee, - 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, - 0x5d4f, 0x080c, 0x9605, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, - 0x2b98, 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000, - 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x001e, - 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, - 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29fe, - 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc, - 0x2013, 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, - 0x9575, 0x080c, 0x95fc, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d, - 0x2000, 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112, - 0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x0005, 0x0016, - 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f5b, 0x2009, - 0x00f7, 0x080c, 0x5dac, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e, - 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, - 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, - 0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x824e, 0x012e, 0x00ce, - 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, - 0x0471, 0x2071, 0x0100, 0x080c, 0x9605, 0x2071, 0x0140, 0x7004, - 0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x080c, 0x7187, 0x0188, - 0x080c, 0x71a2, 0x1170, 0x080c, 0x7485, 0x0016, 0x080c, 0x2786, - 0x2001, 0x1947, 0x2102, 0x001e, 0x080c, 0x7480, 0x080c, 0x709f, - 0x0050, 0x2009, 0x0001, 0x080c, 0x2ab6, 0x2001, 0x0001, 0x080c, - 0x2617, 0x080c, 0x5cef, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, - 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, - 0x2001, 0x1973, 0x201c, 0x080c, 0x4a18, 0x003e, 0x002e, 0x0005, - 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e0a, - 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, - 0x5e04, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, - 0x080c, 0x5e07, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, - 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, - 0x8210, 0x1f04, 0x5d84, 0x002e, 0x001e, 0x0005, 0x080c, 0x9ddd, - 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, - 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a, - 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, - 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, - 0x810f, 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817, - 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, - 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c6, 0x0158, - 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6, 0x2001, 0x180c, - 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3076, - 0x080c, 0xc444, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, - 0x080c, 0x4bb5, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cef, - 0x7097, 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, - 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, - 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, - 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, - 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, - 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, - 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, - 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, - 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, - 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1980, 0x0118, - 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, - 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e44, - 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, - 0x185b, 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e, - 0xb812, 0x9198, 0x3209, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, - 0x0026, 0xb8b2, 0x080c, 0x9f54, 0x1120, 0x9192, 0x007e, 0x1208, - 0xbbb2, 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006, - 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, - 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, - 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, - 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, - 0xb89e, 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, - 0x1075, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, - 0x680c, 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, - 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, - 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f1a, 0x9182, - 0x0800, 0x1a04, 0x5f1e, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, - 0x1904, 0x5f24, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, - 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, - 0x5f36, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, - 0x080c, 0x8616, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, - 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, - 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, - 0x1290, 0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, - 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, - 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, - 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, - 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, - 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, - 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, - 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66ca, - 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecd, 0x080c, 0x6540, - 0x0904, 0x5ee6, 0x0804, 0x5ed1, 0x00b6, 0x00e6, 0x0126, 0x2091, - 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fba, 0x9188, 0x1000, - 0x2104, 0x905d, 0x0904, 0x5f92, 0xb8a0, 0x9086, 0x007f, 0x0190, - 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x66d2, 0x0160, 0xa994, 0x81ff, - 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, - 0x66ca, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, - 0x2060, 0x0026, 0x2010, 0x080c, 0xbd29, 0x002e, 0x1120, 0x2001, - 0x0008, 0x0804, 0x5fbc, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, - 0x0008, 0x0804, 0x5fbc, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, - 0x0058, 0x080c, 0x9f7f, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, - 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa053, - 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, - 0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, - 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, - 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, - 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, - 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, - 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, - 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, - 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, - 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, - 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, - 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, - 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, - 0x012e, 0x00be, 0x00fe, 0x0005, 0x6051, 0x600c, 0x6023, 0x6051, - 0x6051, 0x6051, 0x6051, 0x6051, 0x2100, 0x9082, 0x007e, 0x1278, - 0x080c, 0x6344, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6059, - 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, - 0x48d2, 0x0150, 0x04b0, 0x080c, 0x63a4, 0x1598, 0xb810, 0x9306, - 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0x9f7f, 0x0530, 0x2b00, - 0x6012, 0x080c, 0xc1b7, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, - 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x30ab, 0x9006, - 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2001, 0x0200, - 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa053, 0x9006, - 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, - 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, - 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, - 0xa894, 0x90c6, 0x0015, 0x0904, 0x6232, 0x90c6, 0x0056, 0x0904, - 0x6236, 0x90c6, 0x0066, 0x0904, 0x623a, 0x90c6, 0x0067, 0x0904, - 0x623e, 0x90c6, 0x0068, 0x0904, 0x6242, 0x90c6, 0x0071, 0x0904, - 0x6246, 0x90c6, 0x0074, 0x0904, 0x624a, 0x90c6, 0x007c, 0x0904, - 0x624e, 0x90c6, 0x007e, 0x0904, 0x6252, 0x90c6, 0x0037, 0x0904, - 0x6256, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, - 0x622d, 0x9182, 0x0800, 0x1a04, 0x622d, 0x080c, 0x63a4, 0x1198, - 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, - 0x006f, 0x0148, 0x080c, 0x9f54, 0x1904, 0x6216, 0xb8a0, 0x9084, - 0xff80, 0x1904, 0x6216, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, - 0x005e, 0x0904, 0x6176, 0x90c6, 0x0064, 0x0904, 0x619f, 0x2008, - 0x0804, 0x6139, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f54, 0x1120, - 0x9182, 0x007f, 0x0a04, 0x6139, 0x9186, 0x00ff, 0x0904, 0x6139, - 0x9182, 0x0800, 0x1a04, 0x6139, 0xaaa0, 0xab9c, 0x7878, 0x9306, - 0x11a8, 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, - 0x0804, 0x6139, 0x080c, 0x9f54, 0x1140, 0x99cc, 0xff00, 0x009e, - 0x1128, 0x2208, 0x2310, 0x0804, 0x6139, 0x009e, 0x080c, 0x48d2, - 0x0904, 0x6142, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006, - 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, - 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, - 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fc0, - 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, - 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0, - 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, - 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, - 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, - 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, - 0x900e, 0x0470, 0x080c, 0x9f7f, 0x1130, 0x2001, 0x4005, 0x2009, - 0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2900, - 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, - 0x0126, 0x2091, 0x8000, 0x080c, 0x30ab, 0x012e, 0x9006, 0x080c, - 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009, 0x0002, 0x080c, - 0xa053, 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006, - 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54f0, - 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a4, - 0x1904, 0x6134, 0x9186, 0x007f, 0x0130, 0x080c, 0x66ca, 0x0118, - 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1043, 0x1120, 0x009e, - 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf23, - 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa998, - 0xaeb0, 0x080c, 0x63a4, 0x1904, 0x6134, 0x0096, 0x080c, 0x1043, - 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x61f3, 0x2900, 0x009e, - 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, - 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, - 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006, - 0x2398, 0x080c, 0x0fc0, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x54dc, 0xd0b4, 0x1118, - 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, - 0x00b0, 0x080c, 0x66ca, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, - 0x54f0, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf06, 0x1904, - 0x616f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa87b, - 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, - 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c, - 0xa4df, 0x1904, 0x616f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, - 0x900e, 0x0804, 0x6170, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, - 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, - 0x2001, 0x0029, 0x900e, 0x0804, 0x6170, 0x2001, 0x0029, 0x900e, - 0x0804, 0x6170, 0x080c, 0x363a, 0x0804, 0x6171, 0x080c, 0x5207, - 0x0804, 0x6171, 0x080c, 0x448d, 0x0804, 0x6171, 0x080c, 0x4506, - 0x0804, 0x6171, 0x080c, 0x4562, 0x0804, 0x6171, 0x080c, 0x498e, - 0x0804, 0x6171, 0x080c, 0x4c37, 0x0804, 0x6171, 0x080c, 0x4e6e, - 0x0804, 0x6171, 0x080c, 0x5067, 0x0804, 0x6171, 0x080c, 0x3863, - 0x0804, 0x6171, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, - 0x905d, 0x0140, 0x080c, 0x66ca, 0x1148, 0x00e9, 0x080c, 0x64cf, - 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, - 0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, + 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05f0, + 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x15a8, 0x080c, + 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, + 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, + 0x080c, 0x5e34, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, + 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, + 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001, 0x080c, + 0x5e34, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, 0x0008, + 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, + 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, + 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, + 0x026e, 0x7097, 0x0017, 0x080c, 0x5dec, 0x1150, 0x7080, 0x9005, + 0x1138, 0x080c, 0x5bb8, 0x1188, 0x9085, 0x0001, 0x080c, 0x26d6, + 0x20a9, 0x0008, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x5cc2, 0x0010, 0x080c, 0x5712, 0x0005, 0x00f6, 0x708c, 0x9005, + 0x01d8, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1190, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, + 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e34, 0x7097, 0x0018, + 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, + 0x0019, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, + 0x0000, 0x080c, 0x5e09, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, + 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, + 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b21, 0x2039, 0x1c0e, + 0x080c, 0x5dec, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, + 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x705c, + 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, + 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, + 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, + 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, + 0x5b54, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, + 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, + 0x0084, 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, + 0x5d5f, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, + 0x0005, 0x9085, 0x0001, 0x080c, 0x5e34, 0x7097, 0x001b, 0x080c, + 0x9df2, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2009, 0x0240, 0x748c, + 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, + 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, + 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, + 0x1f04, 0x5ba0, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x0005, 0x0005, + 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008, 0x2041, + 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e09, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, + 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, + 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd2, 0x0804, + 0x5c41, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, + 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c41, 0x918d, 0xc000, 0x20a9, + 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, + 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf8, 0x04d8, 0x23a8, 0x2021, + 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0a, 0x2328, 0x8529, 0x92be, + 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, + 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c19, 0x755a, 0x95c8, 0x31f3, + 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, + 0x080c, 0x26b6, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, + 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, + 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, + 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, + 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, + 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, + 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, + 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x31f3, 0x242d, 0x95ac, + 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26b6, + 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee, 0x0005, + 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5d4e, + 0x080c, 0x961a, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000, 0x7840, + 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x001e, 0x9094, + 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29e9, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc, 0x2013, + 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x080c, 0x9611, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d, 0x2000, + 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112, 0x2009, + 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x0005, 0x0016, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f70, 0x2009, 0x00f7, + 0x080c, 0x5dab, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e, 0x617a, + 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, 0x2009, + 0x002d, 0x2011, 0x5d1a, 0x080c, 0x824d, 0x012e, 0x00ce, 0x002e, + 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, + 0x2071, 0x0100, 0x080c, 0x961a, 0x2071, 0x0140, 0x7004, 0x9084, + 0x4000, 0x0110, 0x080c, 0x2b7f, 0x080c, 0x7186, 0x0188, 0x080c, + 0x71a1, 0x1170, 0x080c, 0x7484, 0x0016, 0x080c, 0x2785, 0x2001, + 0x1947, 0x2102, 0x001e, 0x080c, 0x747f, 0x080c, 0x709e, 0x0050, + 0x2009, 0x0001, 0x080c, 0x2a9d, 0x2001, 0x0001, 0x080c, 0x2616, + 0x080c, 0x5cee, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, + 0x1973, 0x201c, 0x080c, 0x4a17, 0x003e, 0x002e, 0x0005, 0x20a9, + 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e09, 0x20e9, + 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x5e03, + 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, + 0x5e06, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, + 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, + 0x1f04, 0x5d83, 0x002e, 0x001e, 0x0005, 0x080c, 0x9df2, 0x20e1, + 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1, + 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, + 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817, 0x2004, + 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, + 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c5, 0x0158, 0x9006, + 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001, 0x180c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3060, 0x080c, + 0xc459, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, + 0x4bb4, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cee, 0x7097, + 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, + 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, + 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, + 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, + 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, + 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, + 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, + 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, + 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1981, 0x0118, 0x2003, + 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, + 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e43, 0x015e, + 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x185b, + 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, + 0x9198, 0x31f3, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, + 0xb8b2, 0x080c, 0x9f69, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbb2, + 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006, 0x9006, + 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, + 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, + 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, + 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, + 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069, + 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, + 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, + 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f19, 0x9182, 0x0800, + 0x1a04, 0x5f1d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, + 0x5f23, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, + 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x5f35, + 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, + 0x8615, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, + 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, + 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, + 0x080c, 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, + 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, + 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, + 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, - 0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, - 0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, - 0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, - 0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, - 0x2071, 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, - 0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, - 0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, - 0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, - 0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, - 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, - 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, - 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, - 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, - 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, - 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, - 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c6, 0x0140, 0x9284, - 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, - 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, - 0xba90, 0x82ff, 0x090c, 0x0e02, 0x000e, 0x00ce, 0x012e, 0x00be, - 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, - 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, - 0x080c, 0x66c2, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, - 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, - 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, - 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, - 0x1180, 0x0096, 0x080c, 0x1043, 0x2958, 0x009e, 0x0160, 0x2b00, - 0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c, - 0x5e4a, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, - 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, - 0x0218, 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, - 0x905d, 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, - 0x1075, 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c, - 0x0006, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0110, 0x080c, 0x0ff5, - 0x080c, 0x9fd5, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8, - 0xb85e, 0xb8b4, 0xb862, 0x080c, 0x1085, 0x00de, 0x9006, 0x002e, - 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, - 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, - 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, - 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717f, 0x1510, - 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0x9f54, 0x11d8, 0x0078, - 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062, - 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, - 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, - 0x1800, 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, - 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088, - 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, - 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, - 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, - 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, - 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, - 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, - 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, - 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, - 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, - 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, - 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, - 0x7054, 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b, - 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, - 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, - 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee, - 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, - 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, - 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, - 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, - 0x8109, 0x1dd0, 0x080c, 0x0e02, 0x3c00, 0x20e8, 0x3300, 0x8001, - 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, - 0x0060, 0x080c, 0x1043, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, - 0x080c, 0x6560, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, - 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, - 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656f, - 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, - 0x080c, 0x1075, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x080c, 0x8616, 0x012e, 0x0005, 0x901e, 0x0010, - 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, - 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, - 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, - 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9940, 0xaa00, - 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, - 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, - 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c4, 0x0128, - 0x080c, 0xbdf8, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c4, - 0x0128, 0x080c, 0xbd9d, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, - 0x65c4, 0x0128, 0x080c, 0xbdf5, 0x0010, 0x9085, 0x0001, 0x0005, - 0x080c, 0x65c4, 0x0128, 0x080c, 0xbdbc, 0x0010, 0x9085, 0x0001, - 0x0005, 0x080c, 0x65c4, 0x0128, 0x080c, 0xbe3b, 0x0010, 0x9085, - 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, - 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, - 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, - 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, - 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, - 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, - 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, + 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, + 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66c9, 0x1990, + 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecc, 0x080c, 0x653f, 0x0904, + 0x5ee5, 0x0804, 0x5ed0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, + 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fb9, 0x9188, 0x1000, 0x2104, + 0x905d, 0x0904, 0x5f91, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, + 0xd0fc, 0x1178, 0x080c, 0x66d1, 0x0160, 0xa994, 0x81ff, 0x0130, + 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x66c9, + 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, + 0x0026, 0x2010, 0x080c, 0xbd3c, 0x002e, 0x1120, 0x2001, 0x0008, + 0x0804, 0x5fbb, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, + 0x0804, 0x5fbb, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, + 0x080c, 0x9f94, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, + 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006, + 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, + 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, + 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, + 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, + 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, + 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, + 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, + 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, + 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, + 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, + 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, + 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, + 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, + 0x00be, 0x00fe, 0x0005, 0x6050, 0x600b, 0x6022, 0x6050, 0x6050, + 0x6050, 0x6050, 0x6050, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, + 0x6343, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6058, 0xb814, + 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x48d1, + 0x0150, 0x04b0, 0x080c, 0x63a3, 0x1598, 0xb810, 0x9306, 0x1580, + 0xb814, 0x9206, 0x1568, 0x080c, 0x9f94, 0x0530, 0x2b00, 0x6012, + 0x080c, 0xc1ca, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, + 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3095, 0x9006, 0x080c, + 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2001, 0x0200, 0xb86e, + 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006, 0x0068, + 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, + 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, + 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, + 0x90c6, 0x0015, 0x0904, 0x6231, 0x90c6, 0x0056, 0x0904, 0x6235, + 0x90c6, 0x0066, 0x0904, 0x6239, 0x90c6, 0x0067, 0x0904, 0x623d, + 0x90c6, 0x0068, 0x0904, 0x6241, 0x90c6, 0x0071, 0x0904, 0x6245, + 0x90c6, 0x0074, 0x0904, 0x6249, 0x90c6, 0x007c, 0x0904, 0x624d, + 0x90c6, 0x007e, 0x0904, 0x6251, 0x90c6, 0x0037, 0x0904, 0x6255, + 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x622c, + 0x9182, 0x0800, 0x1a04, 0x622c, 0x080c, 0x63a3, 0x1198, 0xb804, + 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, + 0x0148, 0x080c, 0x9f69, 0x1904, 0x6215, 0xb8a0, 0x9084, 0xff80, + 0x1904, 0x6215, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, + 0x0904, 0x6175, 0x90c6, 0x0064, 0x0904, 0x619e, 0x2008, 0x0804, + 0x6138, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182, + 0x007f, 0x0a04, 0x6138, 0x9186, 0x00ff, 0x0904, 0x6138, 0x9182, + 0x0800, 0x1a04, 0x6138, 0xaaa0, 0xab9c, 0x7878, 0x9306, 0x11a8, + 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, + 0x6138, 0x080c, 0x9f69, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, + 0x2208, 0x2310, 0x0804, 0x6138, 0x009e, 0x080c, 0x48d1, 0x0904, + 0x6141, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006, 0x080c, + 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, + 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4, + 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9, + 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b4, + 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4, 0x000e, + 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, + 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, + 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, + 0x0470, 0x080c, 0x9f94, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, + 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x2900, 0x6016, + 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, + 0x2091, 0x8000, 0x080c, 0x3095, 0x012e, 0x9006, 0x080c, 0x62e0, + 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002, 0x080c, 0xa068, + 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006, 0x9005, + 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54ef, 0x0118, + 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a3, 0x1904, + 0x6133, 0x9186, 0x007f, 0x0130, 0x080c, 0x66c9, 0x0118, 0x2009, + 0x0009, 0x0080, 0x0096, 0x080c, 0x1037, 0x1120, 0x009e, 0x2009, + 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf36, 0x19b0, + 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa998, 0xaeb0, + 0x080c, 0x63a3, 0x1904, 0x6133, 0x0096, 0x080c, 0x1037, 0x1128, + 0x009e, 0x2009, 0x0002, 0x0804, 0x61f2, 0x2900, 0x009e, 0xa806, + 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, + 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006, 0x2398, + 0x080c, 0x0fb4, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, + 0x4000, 0xd684, 0x1168, 0x080c, 0x54db, 0xd0b4, 0x1118, 0xa89b, + 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, + 0x080c, 0x66c9, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x54ef, + 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf19, 0x1904, 0x616e, + 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa87b, 0x0030, + 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, + 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x080c, 0xa4f1, + 0x1904, 0x616e, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, + 0x0804, 0x616f, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, + 0x0029, 0x900e, 0x0804, 0x616f, 0x2001, 0x0029, 0x900e, 0x0804, + 0x616f, 0x080c, 0x3624, 0x0804, 0x6170, 0x080c, 0x5206, 0x0804, + 0x6170, 0x080c, 0x448c, 0x0804, 0x6170, 0x080c, 0x4505, 0x0804, + 0x6170, 0x080c, 0x4561, 0x0804, 0x6170, 0x080c, 0x498d, 0x0804, + 0x6170, 0x080c, 0x4c36, 0x0804, 0x6170, 0x080c, 0x4e6d, 0x0804, + 0x6170, 0x080c, 0x5066, 0x0804, 0x6170, 0x080c, 0x384d, 0x0804, + 0x6170, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, + 0x0140, 0x080c, 0x66c9, 0x1148, 0x00e9, 0x080c, 0x64ce, 0x9006, + 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, + 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, + 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, + 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, + 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, + 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, + 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, + 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, + 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, + 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, + 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, + 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, + 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, + 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, + 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, + 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, + 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, + 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c5, 0x0140, 0x9284, 0xff00, + 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, + 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, + 0x82ff, 0x090c, 0x0df6, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, + 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, + 0x66c1, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, + 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, + 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, + 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1180, + 0x0096, 0x080c, 0x1037, 0x2958, 0x009e, 0x0160, 0x2b00, 0x2012, + 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c, 0x5e49, + 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, + 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069, + 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, + 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0110, 0x080c, 0x0fe9, 0x080c, + 0x9fea, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8, 0xb85e, + 0xb8b4, 0xb862, 0x080c, 0x1079, 0x00de, 0x9006, 0x002e, 0x012e, + 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, + 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, + 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717e, 0x1510, 0xb8a0, + 0x9086, 0x007e, 0x0120, 0x080c, 0x9f69, 0x11d8, 0x0078, 0x7040, + 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062, 0x704c, + 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, + 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, + 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, + 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088, 0x000a, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, + 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, + 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, + 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, + 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, + 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, + 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, + 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, + 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, + 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b, 0x210c, + 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, + 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, + 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, + 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, + 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, + 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, + 0x1dd0, 0x080c, 0x0df6, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, + 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, + 0x080c, 0x1037, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, + 0x655f, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, + 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656e, 0x1158, + 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, + 0x1069, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8615, 0x012e, 0x0005, 0x901e, 0x0010, 0x2019, + 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, 0xb800, + 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, 0x9606, + 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, + 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9955, 0xaa00, 0xb84c, + 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, 0x00ae, + 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, 0x0489, + 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128, 0x080c, + 0xbe0b, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128, + 0x080c, 0xbdb0, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3, + 0x0128, 0x080c, 0xbe08, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x65c3, 0x0128, 0x080c, 0xbdcf, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x65c3, 0x0128, 0x080c, 0xbe4e, 0x0010, 0x9085, 0x0001, + 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, - 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, - 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, - 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x1128, 0x080c, 0x1043, 0x0168, 0x2900, 0xb8a6, 0x080c, - 0x6560, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, - 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, - 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1075, 0x9085, - 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, - 0x00f6, 0x080c, 0x717f, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8, - 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, - 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, - 0xc0ed, 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9, - 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1168, 0xb804, 0x9084, - 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, - 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65ea, 0x015e, - 0x080c, 0x6688, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079, - 0x185b, 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6614, 0x080c, - 0x82ec, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6614, 0x080c, - 0x825a, 0x080c, 0x6688, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, - 0xb900, 0xc1ec, 0xb902, 0x080c, 0x66c6, 0x0130, 0x2009, 0x07d0, - 0x2011, 0x6614, 0x080c, 0x82ec, 0x00e6, 0x2071, 0x1800, 0x9006, - 0x707a, 0x705c, 0x707e, 0x080c, 0x2e8c, 0x00ee, 0x04c0, 0x0156, - 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1548, - 0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, - 0x9006, 0x2009, 0x0029, 0x080c, 0xd7d6, 0xb800, 0xc0e5, 0xc0ec, - 0xb802, 0x080c, 0x66c2, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, - 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8783, - 0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e, - 0x004e, 0x001e, 0x8108, 0x1f04, 0x663c, 0x00ce, 0x015e, 0x00be, - 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, - 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, - 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005, - 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, - 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, - 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0e02, - 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, - 0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138, - 0x2001, 0x195d, 0x200c, 0x2011, 0x66b8, 0x080c, 0x82ec, 0x0005, - 0x2011, 0x66b8, 0x080c, 0x825a, 0x2011, 0x1836, 0x2204, 0xc0cc, - 0x2012, 0x0005, 0x080c, 0x54dc, 0xd0ac, 0x0005, 0x080c, 0x54dc, - 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, - 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, - 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc444, 0x0158, - 0x70d8, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, - 0x0110, 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, - 0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780, - 0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, - 0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, - 0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, - 0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, - 0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, - 0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, - 0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, - 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, - 0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, - 0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, - 0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c, - 0x9780, 0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, - 0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, - 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, - 0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, - 0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, - 0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, - 0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003, - 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, - 0x700a, 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016, - 0x00e6, 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54dc, 0xd0fc, - 0x1140, 0x080c, 0x54dc, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, - 0x0438, 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002, - 0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67b8, 0x67cd, 0x67db, - 0x7003, 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e, - 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, - 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, - 0x2071, 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001, - 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009, - 0x187c, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, - 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, - 0x0007, 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef, - 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, - 0x00e6, 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, - 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ed, 0x6a60, - 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, - 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, - 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, - 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, - 0x2071, 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, - 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508, - 0x00e6, 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a29, - 0xa978, 0xa874, 0x9105, 0x1904, 0x6a29, 0x9286, 0x0003, 0x0904, - 0x68c2, 0x9286, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0bc, 0x1904, - 0x6a29, 0x2200, 0x0002, 0x6a29, 0x6886, 0x68c2, 0x68c2, 0x6a29, - 0x68c2, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, - 0x1923, 0x210c, 0x81ff, 0x0904, 0x6a29, 0xa880, 0x9084, 0x00ff, - 0x9086, 0x0001, 0x1904, 0x6a29, 0x9186, 0x0003, 0x0904, 0x68c2, - 0x9186, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0cc, 0x0904, 0x6a29, - 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, - 0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf7, - 0x0e04, 0x6c42, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, - 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x2011, - 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, - 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x002e, 0x00ee, 0x0005, - 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, - 0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ad, 0x782c, - 0x908c, 0x0780, 0x190c, 0x6d6b, 0x8004, 0x8004, 0x8004, 0x9084, - 0x0003, 0x0002, 0x68e0, 0x69ad, 0x6904, 0x694a, 0x080c, 0x0e02, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, - 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, - 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, - 0x70be, 0x080c, 0x8170, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, - 0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, - 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, - 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, - 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, - 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044, + 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0146, + 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, 0x20a9, + 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, 0x01c6, + 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, + 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, + 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, + 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, 0x3c00, + 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, 0x01ce, + 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x1128, 0x080c, 0x1037, 0x0168, 0x2900, 0xb8a6, 0x080c, 0x655f, + 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1069, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, 0x00f6, + 0x080c, 0x717e, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8, 0xd19c, + 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, 0x0148, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, + 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9, 0x007f, + 0x900e, 0x0016, 0x080c, 0x63a3, 0x1168, 0xb804, 0x9084, 0xff00, + 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, + 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65e9, 0x015e, 0x080c, + 0x6687, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079, 0x185b, + 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6613, 0x080c, 0x82eb, + 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6613, 0x080c, 0x8259, + 0x080c, 0x6687, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, + 0xc1ec, 0xb902, 0x080c, 0x66c5, 0x0130, 0x2009, 0x07d0, 0x2011, + 0x6613, 0x080c, 0x82eb, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707a, + 0x705c, 0x707e, 0x080c, 0x2e73, 0x00ee, 0x04c0, 0x0156, 0x00c6, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1548, 0xb800, + 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006, + 0x2009, 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xc0ec, 0xb802, + 0x080c, 0x66c1, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, + 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, + 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556, 0x007e, 0x004e, + 0x001e, 0x8108, 0x1f04, 0x663b, 0x00ce, 0x015e, 0x00be, 0x0005, + 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, + 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, + 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x00b6, + 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec, + 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006, + 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0df6, 0x000e, + 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e, + 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138, 0x2001, + 0x195d, 0x200c, 0x2011, 0x66b7, 0x080c, 0x82eb, 0x0005, 0x2011, + 0x66b7, 0x080c, 0x8259, 0x2011, 0x1836, 0x2204, 0xc0cc, 0x2012, + 0x0005, 0x080c, 0x54db, 0xd0ac, 0x0005, 0x080c, 0x54db, 0xd0a4, + 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, + 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006, + 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc459, 0x0158, 0x70d8, + 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110, + 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, 0x0036, + 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780, 0x31f3, + 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, 0x9284, + 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, 0x9706, + 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, 0xd0a4, + 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, 0x0800, + 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, 0x007e, + 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, 0x00be, + 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, 0x0046, + 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, 0x1000, + 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c, 0x9780, + 0x31f3, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, 0x2400, + 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, 0x0130, + 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, 0x9482, + 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, 0x005e, + 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, 0x007e, + 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003, 0x0001, + 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, + 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, + 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54db, 0xd0fc, 0x1140, + 0x080c, 0x54db, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0438, + 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002, 0x67a0, + 0x67a0, 0x67a0, 0x67a0, 0x67a0, 0x67b7, 0x67cc, 0x67da, 0x7003, + 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, + 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, + 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, + 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001, 0x00ee, + 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009, 0x187c, + 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, + 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, + 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef, 0x0005, + 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, + 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, + 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ec, 0x6a60, 0x9200, + 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, + 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, + 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, + 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, + 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, + 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508, 0x00e6, + 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a28, 0xa978, + 0xa874, 0x9105, 0x1904, 0x6a28, 0x9286, 0x0003, 0x0904, 0x68c1, + 0x9286, 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0bc, 0x1904, 0x6a28, + 0x2200, 0x0002, 0x6a28, 0x6885, 0x68c1, 0x68c1, 0x6a28, 0x68c1, + 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1923, + 0x210c, 0x81ff, 0x0904, 0x6a28, 0xa880, 0x9084, 0x00ff, 0x9086, + 0x0001, 0x1904, 0x6a28, 0x9186, 0x0003, 0x0904, 0x68c1, 0x9186, + 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0cc, 0x0904, 0x6a28, 0xa84f, + 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, + 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf6, 0x0e04, + 0x6c41, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, + 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x2011, 0x0001, + 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70bc, + 0x9200, 0x70be, 0x080c, 0x816f, 0x002e, 0x00ee, 0x0005, 0x0096, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, + 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x190e, + 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ac, 0x782c, 0x908c, + 0x0780, 0x190c, 0x6d6a, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, + 0x0002, 0x68df, 0x69ac, 0x6903, 0x6949, 0x080c, 0x0df6, 0x2071, + 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19d5, + 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, + 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, + 0x080c, 0x816f, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, + 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, + 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, 0x7022, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, + 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044, 0x9005, + 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x1d60, 0x00ee, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x1198, 0x009e, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, + 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, + 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, + 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, + 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, + 0xa804, 0x900d, 0x1904, 0x6a00, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d68, 0x782c, 0x9094, + 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, + 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, + 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, + 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, + 0x080c, 0x816f, 0x00ee, 0x0804, 0x69bc, 0xa868, 0xd0fc, 0x1904, + 0x6a76, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fe9, + 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a76, 0x00e6, 0x0026, + 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70e8, + 0x8001, 0x0558, 0x1a04, 0x6a73, 0x2071, 0x190e, 0xa803, 0x0000, + 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, + 0x1904, 0x6b72, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6a, 0x8004, + 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a77, 0x6b72, 0x6a92, + 0x6b03, 0x080c, 0x0df6, 0x2009, 0x1923, 0x2104, 0x0002, 0x6a3e, + 0x6a3e, 0x6a3e, 0x68ca, 0x6a3e, 0x68ca, 0x70eb, 0x0fa0, 0x71e4, + 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70e6, + 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, + 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a34, 0x0005, 0x2071, + 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, - 0x8170, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, - 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x1d60, - 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x1198, - 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5, - 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, - 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, - 0xa804, 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, - 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x816f, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, + 0x1904, 0x6af2, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec, 0x9102, + 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, + 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x0e04, + 0x6ae9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, + 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c, 0xc184, + 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, - 0x8170, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, - 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, - 0x2148, 0xa804, 0x900d, 0x1904, 0x6a01, 0x782c, 0x9094, 0x0780, - 0x190c, 0x6d6b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, + 0x816f, 0x0804, 0x6aa5, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, + 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, + 0x1d60, 0x00ee, 0x0e04, 0x6b45, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, + 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, + 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, + 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1904, 0x6be1, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, + 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, - 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d68, 0x782c, - 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x01b0, 0x00e6, 0x7824, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d50, 0x782c, + 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, - 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, - 0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005, - 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bda, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x704b, 0x0000, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, - 0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x69bd, 0xa868, 0xd0fc, - 0x1904, 0x6a77, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, - 0x0ff5, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a77, 0x00e6, - 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, - 0x70e8, 0x8001, 0x0558, 0x1a04, 0x6a74, 0x2071, 0x190e, 0xa803, - 0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, - 0x9005, 0x1904, 0x6b73, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6b, - 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a78, 0x6b73, - 0x6a93, 0x6b04, 0x080c, 0x0e02, 0x2009, 0x1923, 0x2104, 0x0002, - 0x6a3f, 0x6a3f, 0x6a3f, 0x68cb, 0x6a3f, 0x68cb, 0x70eb, 0x0fa0, - 0x71e4, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, - 0x70e6, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, - 0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a35, 0x0005, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, - 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, - 0x080c, 0x8170, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, - 0x900d, 0x1904, 0x6af3, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec, - 0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, - 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, - 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, - 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0, - 0x0e04, 0x6aea, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, - 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c, - 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11f2, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, - 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, - 0x080c, 0x8170, 0x0804, 0x6aa6, 0x0096, 0x00e6, 0x7824, 0x2048, - 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, - 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, - 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6b46, 0x7838, 0x7938, 0x910e, - 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, - 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, - 0x190c, 0x6d6b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, - 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, - 0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, - 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x70be, 0x080c, 0x816f, 0x00ee, 0x0804, 0x6b82, 0x2071, 0x190e, + 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1128, 0x1e04, 0x6c21, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, - 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1904, 0x6be2, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, - 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, - 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, - 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d50, - 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x05b8, 0x00e6, - 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, - 0x190c, 0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bdb, 0x7838, - 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, - 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, - 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, - 0x9200, 0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x6b83, 0x2071, - 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, - 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, - 0x900d, 0x1128, 0x1e04, 0x6c22, 0x002e, 0x00ee, 0x0005, 0x2071, - 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, - 0x0e04, 0x6c0c, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d, - 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, - 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x002e, - 0x00ee, 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, - 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, - 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, - 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, - 0x8170, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, - 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, - 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, - 0xa87a, 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8f, - 0x6c90, 0x6d56, 0x6c90, 0x6c8d, 0x6d56, 0x080c, 0x0e02, 0x0005, - 0x2001, 0x1923, 0x2004, 0x0002, 0x6c9a, 0x6c9a, 0x6cef, 0x6cf0, - 0x6c9a, 0x6cf0, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d76, 0x701c, - 0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbe, 0xa94c, + 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x0e04, + 0x6c0b, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x012e, 0x0470, - 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, - 0x2071, 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, + 0x190c, 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x002e, 0x00ee, + 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, + 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, + 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, + 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, + 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, + 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8e, 0x6c8f, + 0x6d55, 0x6c8f, 0x6c8c, 0x6d55, 0x080c, 0x0df6, 0x0005, 0x2001, + 0x1923, 0x2004, 0x0002, 0x6c99, 0x6c99, 0x6cee, 0x6cef, 0x6c99, + 0x6cef, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d75, 0x701c, 0x904d, + 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbd, 0xa94c, 0x2071, + 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x012e, 0x0470, 0x2001, + 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x2071, + 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, 0x9184, + 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, + 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, + 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, + 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, + 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2, 0x210c, + 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, + 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d21, 0x2069, 0x0000, 0x6837, + 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2069, 0x19d5, 0x6847, + 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6de0, + 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, + 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, - 0x00de, 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, - 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, - 0x00d6, 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158, - 0x9186, 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2, - 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, - 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d22, 0x2069, 0x0000, - 0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2069, 0x19d5, - 0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, - 0x6de1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, - 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001, - 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, - 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, - 0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, - 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, - 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, - 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1075, - 0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6d, 0x0006, - 0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0e0b, 0x0096, 0x00f6, - 0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, + 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, + 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1069, 0x0005, + 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6c, 0x0006, 0x0016, + 0x2001, 0x8004, 0x0006, 0x0804, 0x0dff, 0x0096, 0x00f6, 0x2079, + 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, + 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, + 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, + 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, - 0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, - 0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, - 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, - 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, - 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0, + 0x190c, 0x11e6, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, + 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11f2, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, - 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, - 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, - 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, - 0x2004, 0xd084, 0x190c, 0x11f2, 0x00fe, 0x0005, 0x782c, 0x9094, - 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, - 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, - 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, - 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923, - 0x6808, 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005, - 0x1320, 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, - 0x0005, 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0e02, 0x9082, 0x001d, - 0x001b, 0x6027, 0x1e00, 0x0005, 0x6f22, 0x6e8f, 0x6eab, 0x6ed5, - 0x6f11, 0x6f51, 0x6f63, 0x6eab, 0x6f39, 0x6e4a, 0x6e78, 0x6efb, - 0x6e49, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, - 0x6808, 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, - 0x7002, 0x080c, 0x72ce, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, - 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085, - 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, - 0x080c, 0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, - 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, - 0x1160, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c, - 0x736a, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, - 0x2001, 0x0090, 0x080c, 0x2b88, 0x000e, 0x6124, 0xd1e4, 0x1190, - 0x080c, 0x6fd0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, - 0x7097, 0x0020, 0x080c, 0x6fd0, 0x0028, 0x7097, 0x001d, 0x0010, - 0x7097, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b88, 0x6124, - 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, - 0x11d8, 0x080c, 0x19a8, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, - 0x080c, 0x71ab, 0x2001, 0x0080, 0x080c, 0x2b88, 0x7097, 0x0029, - 0x0058, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, - 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a8, 0x60e3, - 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71ab, 0x2001, 0x0080, - 0x080c, 0x2b88, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, - 0x1148, 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097, - 0x0028, 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, - 0x7097, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, - 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040, - 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, - 0x0005, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x6124, 0xd1dc, 0x1138, - 0xd1e4, 0x0138, 0x080c, 0x19a8, 0x7097, 0x001e, 0x0010, 0x7097, - 0x001d, 0x0005, 0x080c, 0x7053, 0x6124, 0xd1dc, 0x1188, 0x080c, - 0x6fd0, 0x0016, 0x080c, 0x19a8, 0x001e, 0xd1d4, 0x1128, 0xd1e4, - 0x0138, 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fd0, - 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x000e, 0x6124, - 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, - 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021, - 0x0005, 0x080c, 0x7053, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, - 0x7097, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b88, - 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, - 0x7097, 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6, - 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, - 0x1800, 0x2091, 0x8000, 0x080c, 0x717f, 0x11d8, 0x2001, 0x180c, - 0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, - 0x2ab0, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b88, - 0x080c, 0x747b, 0x080c, 0x5e30, 0x0428, 0x6028, 0xc0cd, 0x602a, - 0x0408, 0x080c, 0x7199, 0x0150, 0x080c, 0x7190, 0x1138, 0x2001, - 0x0001, 0x080c, 0x2617, 0x080c, 0x7157, 0x00a0, 0x080c, 0x7050, - 0x0178, 0x2001, 0x0001, 0x080c, 0x2617, 0x7094, 0x9086, 0x001e, - 0x0120, 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010, - 0x7097, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, - 0x0026, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x0016, 0x0026, - 0x2009, 0x0064, 0x2011, 0x6fe1, 0x080c, 0x8325, 0x002e, 0x001e, - 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x9605, 0x2071, 0x1800, - 0x080c, 0x6f7e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, - 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, - 0x080c, 0x9605, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, - 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, - 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x080c, 0x82da, 0x0036, - 0x901e, 0x080c, 0x989c, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdb7a, - 0x080c, 0xdb95, 0x2009, 0x0004, 0x080c, 0x2ab6, 0x080c, 0x2989, - 0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe1, - 0x080c, 0x832e, 0x080c, 0x7199, 0x0118, 0x9006, 0x080c, 0x2b88, - 0x080c, 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2617, 0x012e, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, - 0x00e6, 0x2011, 0x6fee, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118, - 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, - 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, - 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2b88, 0x0156, 0x20a9, 0x002d, - 0x1d04, 0x7060, 0x2091, 0x6000, 0x1f04, 0x7060, 0x015e, 0x00d6, - 0x2069, 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de, - 0x0005, 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086, - 0x0001, 0x1da8, 0x080c, 0x833a, 0x0c90, 0x00c6, 0x00d6, 0x00e6, - 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x748a, - 0x2001, 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, - 0x080c, 0x26e2, 0x9006, 0x080c, 0x2b88, 0x080c, 0x5cef, 0x6027, - 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, - 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x2001, 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, - 0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, - 0x7147, 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097, - 0x0023, 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, - 0x2001, 0x0001, 0x080c, 0x26e2, 0x0026, 0x080c, 0x9f5b, 0x002e, - 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, - 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, - 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xc444, 0x0118, 0x9006, - 0x080c, 0x2bb2, 0x0804, 0x7153, 0x6800, 0x9084, 0x00a1, 0xc0bd, - 0x6802, 0x080c, 0x2ab0, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x1f04, 0x70df, 0x080c, 0x71d3, 0x012e, 0x015e, - 0x080c, 0x7190, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100, - 0x2004, 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085, - 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, - 0x71d3, 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086, - 0x000a, 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, - 0x080c, 0x71d3, 0x080c, 0xc444, 0x0118, 0x9006, 0x080c, 0x2bb2, - 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, - 0x2011, 0x6fee, 0x080c, 0x82ec, 0x002e, 0x001e, 0x080c, 0x8167, - 0x7034, 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c, - 0x6e31, 0x080c, 0x7190, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, - 0x1100, 0x080c, 0x7480, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, - 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x080c, 0x817e, 0x080c, 0x8170, 0x080c, 0x748a, 0x2001, 0x1947, - 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e2, - 0x9006, 0x080c, 0x2b88, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, - 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, - 0x2001, 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, - 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, - 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, - 0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0010, - 0x000e, 0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, - 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, - 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2702, 0x900e, 0x0010, - 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3076, 0x9006, 0x0019, - 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, - 0x080c, 0xc43d, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, - 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, - 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004, - 0x9086, 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, - 0x9085, 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ee, - 0x2091, 0x6000, 0x1f04, 0x71ee, 0x602f, 0x0100, 0x602f, 0x0000, - 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, - 0x602f, 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2bc2, 0x080c, - 0x2bf5, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, - 0x0000, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x0026, 0x6027, 0x0040, - 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, - 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, - 0x26e2, 0x2001, 0x00a0, 0x0006, 0x080c, 0xc444, 0x000e, 0x0130, - 0x080c, 0x2ba6, 0x9006, 0x080c, 0x2bb2, 0x0010, 0x080c, 0x2b88, - 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, - 0x0100, 0x080c, 0x2a06, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, - 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, - 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72c0, 0x2001, - 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, - 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2b88, 0x20a9, 0x0366, - 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7270, 0x2091, 0x6000, 0x1f04, - 0x7270, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c, - 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2001, 0x00a0, - 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0xc444, - 0x0110, 0x080c, 0x0d70, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a8, - 0x60e3, 0x0000, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001, - 0x0080, 0x080c, 0x2b88, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, - 0x1e00, 0x080c, 0x2ab0, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a5, - 0x2091, 0x6000, 0x1f04, 0x72a5, 0x0820, 0x6028, 0x9085, 0x1e00, - 0x602a, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, - 0x080c, 0xc444, 0x0110, 0x080c, 0x0d70, 0x9006, 0x00ee, 0x00de, - 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, - 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, - 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, - 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04, - 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, - 0x6884, 0x9005, 0x1904, 0x7333, 0x2001, 0x0088, 0x080c, 0x2b88, - 0x9006, 0x60e2, 0x6886, 0x080c, 0x26e2, 0x2069, 0x0200, 0x6804, - 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, - 0x602a, 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, - 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7315, 0x2091, - 0x6000, 0x1f04, 0x7315, 0x0804, 0x7362, 0x2069, 0x0140, 0x20a9, - 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2ab0, 0x6024, - 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7321, 0x2091, - 0x6000, 0x1f04, 0x7321, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, - 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, - 0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30, - 0x9085, 0x0001, 0x00b8, 0x080c, 0x19a8, 0x2001, 0x0080, 0x080c, - 0x2b88, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, - 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2, - 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, - 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, - 0x01c8, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c, - 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2069, 0x0140, - 0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30, - 0x0804, 0x73fc, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, - 0x2102, 0x080c, 0x6fd6, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, - 0x2b88, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, - 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, - 0x0200, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003, - 0x0001, 0x0804, 0x73fc, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, - 0x2ab0, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, - 0x73bb, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81be, - 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5, - 0x7078, 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fee, - 0x080c, 0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x2069, - 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, - 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001, - 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, - 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, - 0xc43d, 0x1904, 0x7469, 0x7130, 0xd184, 0x1170, 0x080c, 0x3204, - 0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120, - 0x7030, 0xd08c, 0x0904, 0x7469, 0x2011, 0x185c, 0x220c, 0x0438, - 0x0016, 0x2019, 0x000e, 0x080c, 0xd74e, 0x0156, 0x00b6, 0x20a9, - 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, - 0x080c, 0x63a4, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, - 0x080c, 0xd7d6, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451, - 0x001e, 0x8108, 0x1f04, 0x7432, 0x00be, 0x015e, 0x001e, 0xd1ac, - 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076, - 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, - 0x63a4, 0x1110, 0x080c, 0x5e4a, 0x8108, 0x1f04, 0x745f, 0x00be, - 0x015e, 0x080c, 0x19a8, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c, - 0x5e30, 0x080c, 0x709f, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, - 0x001e, 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005, - 0x2001, 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003, - 0xaaaa, 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071, - 0x18f8, 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x105c, 0x090c, - 0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x105c, 0x090c, - 0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, - 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, - 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, - 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, - 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, - 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, - 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, - 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, - 0x8000, 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de, - 0x080c, 0x7a7d, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, - 0x0006, 0x8003, 0x818d, 0x1f04, 0x74f1, 0x015e, 0x0005, 0x2079, - 0x0040, 0x2071, 0x18f8, 0x7004, 0x0002, 0x7507, 0x7508, 0x7540, - 0x759b, 0x76e0, 0x7505, 0x7505, 0x770a, 0x080c, 0x0e02, 0x0005, - 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b09, 0xd0a4, - 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, - 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, - 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7530, 0x750a, 0x7530, - 0x752e, 0x7530, 0x7530, 0x7530, 0x7530, 0x7530, 0x080c, 0x759b, - 0x782c, 0xd09c, 0x090c, 0x7a7d, 0x0005, 0x9082, 0x005a, 0x1218, - 0x2100, 0x003b, 0x0c10, 0x080c, 0x75d1, 0x0c90, 0x00e3, 0x08e8, - 0x0005, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x77e4, - 0x75d1, 0x75d1, 0x75d1, 0x75f3, 0x75d1, 0x75dd, 0x7825, 0x7866, - 0x78ad, 0x78c1, 0x75d1, 0x75d1, 0x75f3, 0x75dd, 0x75d1, 0x75d1, - 0x76b4, 0x796c, 0x7987, 0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x76aa, 0x7987, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7607, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7aad, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x761b, 0x75d1, 0x75d1, 0x75d1, - 0x75d1, 0x75d1, 0x75d1, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, - 0x1198, 0x782c, 0x080c, 0x7aa6, 0xd0a4, 0x0170, 0x7824, 0x2048, - 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, - 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7d, 0x0005, 0x75d1, - 0x75dd, 0x77d0, 0x75d1, 0x75dd, 0x75d1, 0x75dd, 0x75dd, 0x75d1, - 0x75dd, 0x77d0, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75d1, - 0x75dd, 0x77d0, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x75d1, 0x75d1, - 0x75dd, 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee, - 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, - 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, - 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6a23, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, - 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7789, 0x7007, 0x0003, - 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7789, 0x0005, 0xa864, - 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, - 0x0804, 0x77a4, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, - 0x704b, 0x77a4, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, - 0x0001, 0x1904, 0x75d9, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c, - 0x81ff, 0x1904, 0x7681, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994, - 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, - 0x0010, 0x080c, 0x66ee, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, - 0x6738, 0x001e, 0x1548, 0x0400, 0x080c, 0x717f, 0x0140, 0xa897, - 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, - 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x01b0, 0x0016, 0x0026, - 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6738, - 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, - 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, - 0xa883, 0x0000, 0x080c, 0x6062, 0x1108, 0x0005, 0x0126, 0x2091, - 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e, - 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, 0x762b, 0x9186, 0x0064, - 0x0904, 0x762b, 0x9186, 0x007c, 0x0904, 0x762b, 0x9186, 0x0028, - 0x0904, 0x762b, 0x9186, 0x0038, 0x0904, 0x762b, 0x9186, 0x0078, - 0x0904, 0x762b, 0x9186, 0x005f, 0x0904, 0x762b, 0x9186, 0x0056, - 0x0904, 0x762b, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, - 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, - 0x7007, 0x0001, 0x0804, 0x799e, 0x2900, 0x7016, 0x701a, 0x20a9, - 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, - 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, - 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e1, 0xaab4, 0x928a, - 0x0002, 0x1a04, 0x75e1, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, - 0x0118, 0x2001, 0x7747, 0x0018, 0x9280, 0x773d, 0x2005, 0x7056, - 0x7010, 0x9015, 0x0904, 0x7728, 0x080c, 0x105c, 0x1118, 0x7007, - 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, - 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, - 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, - 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, - 0x080c, 0x1140, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, - 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1075, - 0x7014, 0x2048, 0x0804, 0x75e1, 0x7020, 0x2048, 0x7018, 0xa802, - 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76e0, - 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, - 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x001e, 0x0904, 0x799e, 0x0804, 0x7789, 0x773f, 0x7743, 0x0002, - 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, - 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, - 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, - 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, - 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, - 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, - 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, - 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, - 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, - 0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eac, - 0x1108, 0x0005, 0x080c, 0x6c6c, 0x0126, 0x2091, 0x8000, 0x080c, - 0xc031, 0x080c, 0x6a23, 0x012e, 0x0ca0, 0x080c, 0xc43d, 0x1d70, - 0x2001, 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005, - 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc4, - 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3c, 0x1108, 0x0005, - 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e, - 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, - 0x00c6, 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005, - 0x7018, 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, - 0x7012, 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, - 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, - 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, - 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, - 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a4, 0x11b8, 0x0066, - 0xae80, 0x080c, 0x64b4, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, - 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a4, 0x1110, - 0x080c, 0x65b4, 0x8108, 0x1f04, 0x780d, 0x00ce, 0xa87c, 0xd084, - 0x1120, 0x080c, 0x1075, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6a23, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, - 0x7007, 0x0001, 0x080c, 0x66c6, 0x0580, 0x2061, 0x1a4c, 0x6100, - 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, - 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, - 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, - 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, - 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, - 0xc28d, 0x6202, 0x012e, 0x0804, 0x7a67, 0x012e, 0x0804, 0x7a61, - 0x012e, 0x0804, 0x7a5b, 0x012e, 0x0804, 0x7a5e, 0x0126, 0x2091, - 0x8000, 0x7007, 0x0001, 0x080c, 0x66c6, 0x05e0, 0x2061, 0x1a4c, - 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, - 0x9484, 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, - 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, - 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, - 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, - 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, - 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a67, 0x012e, - 0x0804, 0x7a64, 0x012e, 0x0804, 0x7a61, 0x0126, 0x2091, 0x8000, - 0x7007, 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308, - 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7a75, 0x012e, 0x0804, - 0x7a64, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, - 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084, - 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, - 0x9065, 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c, - 0xa007, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, - 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa053, 0xa988, - 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, - 0xfdff, 0x080c, 0x8451, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, - 0x1a4c, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, - 0x00ce, 0x012e, 0x00be, 0x0804, 0x7a67, 0x00ce, 0x012e, 0x00be, - 0x0804, 0x7a61, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, - 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, - 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, - 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a4, 0x1968, 0xb800, - 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, - 0x2001, 0x1960, 0x2004, 0x601a, 0x0804, 0x78fc, 0xa88c, 0x9065, - 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005, - 0x0150, 0x080c, 0xa007, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa007, - 0x00ee, 0x0804, 0x78fc, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, - 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, - 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, - 0x8b90, 0x00ee, 0x0804, 0x78fc, 0x2061, 0x1a4c, 0x6000, 0xd084, - 0x0190, 0xd08c, 0x1904, 0x7a75, 0x0126, 0x2091, 0x8000, 0x6204, - 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7a75, 0x012e, 0xa883, - 0x0016, 0x0804, 0x7a6e, 0xa883, 0x0007, 0x0804, 0x7a6e, 0xa864, - 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, - 0x0069, 0x0005, 0x080c, 0x75d9, 0x0040, 0x7007, 0x0003, 0x7012, - 0x2900, 0x7016, 0x701a, 0x704b, 0x799e, 0x0005, 0x00b6, 0x00e6, - 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff, - 0x1904, 0x7a20, 0x6130, 0xd194, 0x1904, 0x7a4a, 0xa878, 0x2070, - 0x9e82, 0x1cd0, 0x0a04, 0x7a14, 0x6064, 0x9e02, 0x1a04, 0x7a14, - 0x7120, 0x9186, 0x0006, 0x1904, 0x7a06, 0x7010, 0x905d, 0x0904, - 0x7a20, 0xb800, 0xd0e4, 0x1904, 0x7a44, 0x2061, 0x1a4c, 0x6100, - 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, - 0x7a4d, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, - 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x080c, 0x54dc, - 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8371, - 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, - 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x012e, 0x00ee, - 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, - 0x7a6e, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, - 0x63a4, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, - 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, - 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, - 0x080c, 0x54e0, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, - 0x02c0, 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, - 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, - 0x7000, 0x9086, 0x0007, 0x1904, 0x79aa, 0x7003, 0x0002, 0x0804, - 0x79aa, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, - 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, - 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd385, 0x012e, - 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, - 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, - 0x0001, 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6a23, 0x012e, 0x0005, 0x080c, 0x1075, 0x0005, - 0x00d6, 0x080c, 0x8368, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, - 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, - 0x0780, 0x190c, 0x7b09, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc, - 0x90ea, 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, - 0x702e, 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, - 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, - 0x0780, 0x190c, 0x7b09, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036, - 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, - 0x1a04, 0x7afa, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, - 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, - 0x1108, 0x04b0, 0x2b10, 0x080c, 0x9f7f, 0x1118, 0x080c, 0xa026, - 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ad8, 0x7add, 0x7ae0, 0x7ae6, - 0x2019, 0x0002, 0x080c, 0xd74e, 0x0060, 0x080c, 0xd6e5, 0x0048, - 0x2019, 0x0002, 0xa980, 0x080c, 0xd700, 0x0018, 0xa980, 0x080c, - 0xd6e5, 0x080c, 0x9fd5, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6a23, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, - 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, - 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, - 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7b0b, 0x0006, 0x0016, 0x2001, - 0x8003, 0x0006, 0x0804, 0x0e0b, 0x2001, 0x1833, 0x2004, 0x9005, - 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, - 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, - 0x080c, 0x151b, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, - 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8b, - 0x68bc, 0x90aa, 0x0005, 0x0a04, 0x8167, 0x7d44, 0x7c40, 0x9584, - 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, - 0x9584, 0x0700, 0x8007, 0x0804, 0x7b92, 0x7000, 0x9084, 0xff00, - 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, - 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdb52, 0x080c, - 0x809c, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, - 0x80fa, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bed, - 0x080c, 0x2169, 0x005e, 0x004e, 0x0020, 0x080c, 0xdb52, 0x7817, - 0x0140, 0x080c, 0x717f, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, - 0x0140, 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, - 0x0000, 0x080c, 0x7bce, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, - 0x8b90, 0x0005, 0x0002, 0x7ba4, 0x7ea4, 0x7b9b, 0x7b9b, 0x7b9b, - 0x7b9b, 0x7b9b, 0x7b9b, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, - 0x9005, 0x090c, 0x8b90, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, - 0xf000, 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150, - 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5546, 0x0070, 0x080c, - 0x7c0d, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddc, 0x0028, - 0x9286, 0x8000, 0x1110, 0x080c, 0x7fc3, 0x7817, 0x0140, 0x2001, - 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x2001, 0x1810, - 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, - 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a18, - 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, - 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, - 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, - 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, - 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a18, 0x002e, - 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, - 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, - 0x1904, 0x7dad, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8061, 0x0904, - 0x7dad, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, - 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dad, 0x7124, - 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, - 0xa053, 0x0804, 0x7dad, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, - 0x1130, 0x2009, 0x0015, 0x080c, 0xa053, 0x0804, 0x7dad, 0x908e, - 0x0100, 0x1904, 0x7dad, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009, - 0x0016, 0x080c, 0xa053, 0x0804, 0x7dad, 0x9186, 0x0022, 0x1904, - 0x7dad, 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528, - 0xc0b5, 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e, - 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, - 0x0016, 0x2008, 0x080c, 0x26b7, 0x7932, 0x7936, 0x001e, 0x000e, - 0x00fe, 0x080c, 0x266e, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140, - 0x7086, 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904, - 0x7dad, 0x2009, 0x0017, 0x0804, 0x7d5d, 0x908e, 0x0400, 0x1190, - 0x7034, 0x9005, 0x1904, 0x7dad, 0x080c, 0x717f, 0x0120, 0x2009, - 0x001d, 0x0804, 0x7d5d, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030, - 0x0804, 0x7d5d, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, - 0x7dad, 0x2009, 0x0018, 0x0804, 0x7d5d, 0x908e, 0x2010, 0x1120, - 0x2009, 0x0019, 0x0804, 0x7d5d, 0x908e, 0x2110, 0x1120, 0x2009, - 0x001a, 0x0804, 0x7d5d, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, - 0x1904, 0x7dad, 0x2009, 0x001b, 0x0804, 0x7d5d, 0x908e, 0x5000, - 0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009, 0x001c, 0x0804, - 0x7d5d, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5d, - 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009, - 0x0024, 0x0804, 0x7d5d, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, - 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5d, - 0x080c, 0xcb4c, 0x1904, 0x7dad, 0x0804, 0x7d5b, 0x908c, 0xff00, - 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5d, 0x908e, - 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5d, 0x908e, 0x6104, - 0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, - 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, - 0x0046, 0x2124, 0x080c, 0x4a18, 0x004e, 0x8108, 0x0f04, 0x7d29, - 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, - 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000, - 0x1118, 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, - 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, - 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, - 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, - 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, - 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x266e, 0x1904, 0x7db0, 0x080c, - 0x6344, 0x1904, 0x7db0, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, - 0x717f, 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, - 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606, - 0x1148, 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, - 0xb8b2, 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, - 0x6878, 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110, - 0x001e, 0x0098, 0x080c, 0x9f7f, 0x01a8, 0x2b08, 0x6112, 0x6023, - 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, - 0x000a, 0x0016, 0x001e, 0x080c, 0xa053, 0x00ce, 0x00be, 0x0005, - 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, - 0x8049, 0x080c, 0x4a18, 0x080c, 0xa026, 0x0d90, 0x2b08, 0x6112, - 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, - 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, - 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, - 0x0001, 0x080c, 0x8641, 0x08a0, 0x080c, 0x8186, 0x1158, 0x080c, - 0x31ce, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, - 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, - 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8061, 0x0904, - 0x7e3c, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, - 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xa053, 0x04a8, 0x908e, - 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, - 0xa053, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, - 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, - 0x220c, 0x080c, 0x266e, 0x11b8, 0x080c, 0x6344, 0x11a0, 0xbe12, - 0xbd16, 0x080c, 0x9f7f, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1b7, - 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa053, 0x080c, - 0x8b90, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, - 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, - 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, - 0x007f, 0x0804, 0x7e9e, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, - 0x0804, 0x7e9e, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, - 0x2011, 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026, - 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, - 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, - 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, - 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, - 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, - 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e73, 0x82ff, - 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, - 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184, - 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, - 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, - 0x9005, 0x090c, 0x8b90, 0x0005, 0x7ecc, 0x7ecc, 0x7ecc, 0x8073, - 0x7ecc, 0x7ed5, 0x7f00, 0x7f8e, 0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc, - 0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc, 0x7817, 0x0140, 0x2001, 0x19cb, - 0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x00b6, 0x7110, 0xd1bc, - 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, + 0xd084, 0x190c, 0x11e6, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, + 0x190c, 0x6d6a, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, + 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, + 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, + 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923, 0x6808, + 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, + 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0df6, 0x9082, 0x001d, 0x001b, + 0x6027, 0x1e00, 0x0005, 0x6f21, 0x6e8e, 0x6eaa, 0x6ed4, 0x6f10, + 0x6f50, 0x6f62, 0x6eaa, 0x6f38, 0x6e49, 0x6e77, 0x6efa, 0x6e48, + 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, + 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, + 0x080c, 0x72cd, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7097, + 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, + 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c, + 0x1977, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, + 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, + 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c, 0x7369, + 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, + 0x0090, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, + 0x6fcf, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7097, + 0x0020, 0x080c, 0x6fcf, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x6124, 0xd1cc, + 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, + 0x080c, 0x19a4, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, + 0x71aa, 0x2001, 0x0080, 0x080c, 0x2b6f, 0x7097, 0x0029, 0x0058, + 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, 0x0020, + 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a4, 0x60e3, 0x0001, + 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71aa, 0x2001, 0x0080, 0x080c, + 0x2b6f, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, + 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097, 0x0028, + 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, + 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040, 0x7097, + 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005, + 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x6124, 0xd1dc, 0x1138, 0xd1e4, + 0x0138, 0x080c, 0x19a4, 0x7097, 0x001e, 0x0010, 0x7097, 0x001d, + 0x0005, 0x080c, 0x7052, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x6fcf, + 0x0016, 0x080c, 0x19a4, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, + 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fcf, 0x0005, + 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1d4, + 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097, + 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021, 0x0005, + 0x080c, 0x7052, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x000e, + 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, + 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, + 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, + 0x2091, 0x8000, 0x080c, 0x717e, 0x11d8, 0x2001, 0x180c, 0x200c, + 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2a97, + 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x080c, + 0x747a, 0x080c, 0x5e2f, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, + 0x080c, 0x7198, 0x0150, 0x080c, 0x718f, 0x1138, 0x2001, 0x0001, + 0x080c, 0x2616, 0x080c, 0x7156, 0x00a0, 0x080c, 0x704f, 0x0178, + 0x2001, 0x0001, 0x080c, 0x2616, 0x7094, 0x9086, 0x001e, 0x0120, + 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010, 0x7097, + 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, + 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x0016, 0x0026, 0x2009, + 0x0064, 0x2011, 0x6fe0, 0x080c, 0x8324, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00f6, 0x0016, 0x080c, 0x961a, 0x2071, 0x1800, 0x080c, + 0x6f7d, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, + 0x961a, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, + 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, + 0x080c, 0x992d, 0x080c, 0x983b, 0x080c, 0x82d9, 0x0036, 0x901e, + 0x080c, 0x98b1, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdbdb, 0x080c, + 0xdbf6, 0x2009, 0x0004, 0x080c, 0x2a9d, 0x080c, 0x2974, 0x2001, + 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe0, 0x080c, + 0x832d, 0x080c, 0x7198, 0x0118, 0x9006, 0x080c, 0x2b6f, 0x080c, + 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2616, 0x012e, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, + 0x2011, 0x6fed, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118, 0x7018, + 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, + 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, + 0x2001, 0x00c0, 0x080c, 0x2b6f, 0x0156, 0x20a9, 0x002d, 0x1d04, + 0x705f, 0x2091, 0x6000, 0x1f04, 0x705f, 0x015e, 0x00d6, 0x2069, + 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de, 0x0005, + 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, + 0x1da8, 0x080c, 0x8339, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7489, 0x2001, + 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, + 0x26e1, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x5cee, 0x6027, 0xffff, + 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, + 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, + 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7146, + 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097, 0x0023, + 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, + 0x0001, 0x080c, 0x26e1, 0x0026, 0x080c, 0x9f70, 0x002e, 0x7000, + 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, + 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, + 0x0150, 0x012e, 0x015e, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c, + 0x2b99, 0x0804, 0x7152, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, + 0x080c, 0x2a97, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x1f04, 0x70de, 0x080c, 0x71d2, 0x012e, 0x015e, 0x080c, + 0x718f, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100, 0x2004, + 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, + 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x71d2, + 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, + 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, + 0x71d2, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c, 0x2b99, 0x0016, + 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, + 0x6fed, 0x080c, 0x82eb, 0x002e, 0x001e, 0x080c, 0x8166, 0x7034, + 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c, 0x6e30, + 0x080c, 0x718f, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, + 0x080c, 0x747f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, + 0x817d, 0x080c, 0x816f, 0x080c, 0x7489, 0x2001, 0x1947, 0x2003, + 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e1, 0x9006, + 0x080c, 0x2b6f, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, 0xffff, + 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, + 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, + 0x54df, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, + 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, + 0x0005, 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0020, + 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, + 0x0013, 0x0168, 0x0020, 0x080c, 0x2701, 0x900e, 0x0010, 0x2009, + 0x0002, 0x2019, 0x0028, 0x080c, 0x3060, 0x9006, 0x0019, 0x001e, + 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, + 0xc452, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, + 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, + 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, + 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ed, 0x2091, + 0x6000, 0x1f04, 0x71ed, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, + 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2ba9, 0x080c, 0x2bdc, + 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, + 0x20a9, 0x0002, 0x080c, 0x2a78, 0x0026, 0x6027, 0x0040, 0x002e, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26e1, + 0x2001, 0x00a0, 0x0006, 0x080c, 0xc459, 0x000e, 0x0130, 0x080c, + 0x2b8d, 0x9006, 0x080c, 0x2b99, 0x0010, 0x080c, 0x2b6f, 0x000e, + 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x29f1, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, + 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72bf, 0x2001, 0x180c, + 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, + 0x0200, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6024, + 0xd0cc, 0x1518, 0x1d04, 0x726f, 0x2091, 0x6000, 0x1f04, 0x726f, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001, 0x00a0, 0x080c, + 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0xc459, 0x0110, + 0x080c, 0x0d64, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a4, 0x60e3, + 0x0000, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x0080, + 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0x080c, 0x2a97, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a4, 0x2091, + 0x6000, 0x1f04, 0x72a4, 0x0820, 0x6028, 0x9085, 0x1e00, 0x602a, + 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, + 0xc459, 0x0110, 0x080c, 0x0d64, 0x9006, 0x00ee, 0x00de, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, + 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04, 0x8000, + 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, + 0x9005, 0x1904, 0x7332, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x9006, + 0x60e2, 0x6886, 0x080c, 0x26e1, 0x2069, 0x0200, 0x6804, 0x9005, + 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a, + 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0026, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7314, 0x2091, 0x6000, + 0x1f04, 0x7314, 0x0804, 0x7361, 0x2069, 0x0140, 0x20a9, 0x0384, + 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97, 0x6024, 0x910c, + 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7320, 0x2091, 0x6000, + 0x1f04, 0x7320, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, + 0x080c, 0x992d, 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001, + 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, + 0x0001, 0x00b8, 0x080c, 0x19a4, 0x2001, 0x0080, 0x080c, 0x2b6f, + 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, + 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, + 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, + 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2069, 0x0140, 0x2001, + 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x0804, + 0x73fb, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, + 0x080c, 0x6fd5, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2b6f, + 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, + 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200, + 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003, 0x0001, + 0x0804, 0x73fb, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97, + 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x73ba, + 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81bd, 0x00ee, + 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5, 0x7078, + 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fed, 0x080c, + 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x2069, 0x0140, + 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, + 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x180c, + 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, + 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xc452, + 0x1904, 0x7468, 0x7130, 0xd184, 0x1170, 0x080c, 0x31ee, 0x0138, + 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120, 0x7030, + 0xd08c, 0x0904, 0x7468, 0x2011, 0x185c, 0x220c, 0x0438, 0x0016, + 0x2019, 0x000e, 0x080c, 0xd7af, 0x0156, 0x00b6, 0x20a9, 0x007f, + 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, + 0x63a3, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, + 0xd837, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x001e, + 0x8108, 0x1f04, 0x7431, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, + 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e, + 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3, + 0x1110, 0x080c, 0x5e49, 0x8108, 0x1f04, 0x745e, 0x00be, 0x015e, + 0x080c, 0x19a4, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0x5e2f, + 0x080c, 0x709e, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005, 0x2001, + 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003, 0xaaaa, + 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071, 0x18f8, + 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1050, 0x090c, 0x0df6, + 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1050, 0x090c, 0x0df6, + 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, + 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, + 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, + 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, + 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, + 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, + 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, + 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, + 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de, 0x080c, + 0x7a7c, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, + 0x8003, 0x818d, 0x1f04, 0x74f0, 0x015e, 0x0005, 0x2079, 0x0040, + 0x2071, 0x18f8, 0x7004, 0x0002, 0x7506, 0x7507, 0x753f, 0x759a, + 0x76df, 0x7504, 0x7504, 0x7709, 0x080c, 0x0df6, 0x0005, 0x2079, + 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b08, 0xd0a4, 0x01f8, + 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, + 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, + 0x0003, 0x1168, 0x7004, 0x0002, 0x752f, 0x7509, 0x752f, 0x752d, + 0x752f, 0x752f, 0x752f, 0x752f, 0x752f, 0x080c, 0x759a, 0x782c, + 0xd09c, 0x090c, 0x7a7c, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, + 0x003b, 0x0c10, 0x080c, 0x75d0, 0x0c90, 0x00e3, 0x08e8, 0x0005, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x77e3, 0x75d0, + 0x75d0, 0x75d0, 0x75f2, 0x75d0, 0x75dc, 0x7824, 0x7865, 0x78ac, + 0x78c0, 0x75d0, 0x75d0, 0x75f2, 0x75dc, 0x75d0, 0x75d0, 0x76b3, + 0x796b, 0x7986, 0x75d0, 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x76a9, 0x7986, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x7606, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x7aac, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x761a, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, + 0x782c, 0x080c, 0x7aa5, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, + 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, + 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7c, 0x0005, 0x75d0, 0x75dc, + 0x77cf, 0x75d0, 0x75dc, 0x75d0, 0x75dc, 0x75dc, 0x75d0, 0x75dc, + 0x77cf, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75d0, 0x75dc, + 0x77cf, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x75d0, 0x75d0, 0x75dc, + 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, + 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, + 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, + 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, + 0x1120, 0x7007, 0x0001, 0x0804, 0x7788, 0x7007, 0x0003, 0x7012, + 0x2900, 0x7016, 0x701a, 0x704b, 0x7788, 0x0005, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, + 0x77a3, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, + 0x77a3, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, + 0x1904, 0x75d8, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c, 0x81ff, + 0x1904, 0x7680, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994, 0x9186, + 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010, + 0x080c, 0x66ed, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x6737, + 0x001e, 0x1548, 0x0400, 0x080c, 0x717e, 0x0140, 0xa897, 0x4005, + 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036, + 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6737, 0x003e, + 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001, + 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, + 0x0000, 0x080c, 0x6061, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0ca0, + 0xa994, 0x9186, 0x0071, 0x0904, 0x762a, 0x9186, 0x0064, 0x0904, + 0x762a, 0x9186, 0x007c, 0x0904, 0x762a, 0x9186, 0x0028, 0x0904, + 0x762a, 0x9186, 0x0038, 0x0904, 0x762a, 0x9186, 0x0078, 0x0904, + 0x762a, 0x9186, 0x005f, 0x0904, 0x762a, 0x9186, 0x0056, 0x0904, + 0x762a, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, + 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, + 0x0001, 0x0804, 0x799d, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, + 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, + 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e0, 0xaab4, 0x928a, 0x0002, + 0x1a04, 0x75e0, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, + 0x2001, 0x7746, 0x0018, 0x9280, 0x773c, 0x2005, 0x7056, 0x7010, + 0x9015, 0x0904, 0x7727, 0x080c, 0x1050, 0x1118, 0x7007, 0x0004, + 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, + 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, + 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, + 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, + 0x1134, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, + 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1069, 0x7014, + 0x2048, 0x0804, 0x75e0, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, + 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76df, 0x7014, + 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, + 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x0904, 0x799d, 0x0804, 0x7788, 0x773e, 0x7742, 0x0002, 0x001d, + 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, + 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, + 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, + 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, + 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, + 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, + 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, + 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, + 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, + 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eab, 0x1108, + 0x0005, 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc044, + 0x080c, 0x6a22, 0x012e, 0x0ca0, 0x080c, 0xc452, 0x1d70, 0x2001, + 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, + 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc3, 0x1138, + 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3b, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0cb0, + 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, + 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, + 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, + 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, + 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, + 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, + 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, + 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a3, 0x11b8, 0x0066, 0xae80, + 0x080c, 0x64b3, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, + 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a3, 0x1110, 0x080c, + 0x65b3, 0x8108, 0x1f04, 0x780c, 0x00ce, 0xa87c, 0xd084, 0x1120, + 0x080c, 0x1069, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x66c5, 0x0580, 0x2061, 0x1a4c, 0x6100, 0xd184, + 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, + 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, + 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, + 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, + 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, + 0x6202, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804, 0x7a60, 0x012e, + 0x0804, 0x7a5a, 0x012e, 0x0804, 0x7a5d, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x080c, 0x66c5, 0x05e0, 0x2061, 0x1a4c, 0x6000, + 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, + 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, + 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, + 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, + 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, + 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, + 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804, + 0x7a63, 0x012e, 0x0804, 0x7a60, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, + 0x0220, 0x630a, 0x012e, 0x0804, 0x7a74, 0x012e, 0x0804, 0x7a63, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, + 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084, 0xfcff, + 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, + 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c, 0xa01c, + 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, + 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa068, 0xa988, 0x918c, + 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, + 0x080c, 0x8450, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a4c, + 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, + 0x012e, 0x00be, 0x0804, 0x7a66, 0x00ce, 0x012e, 0x00be, 0x0804, + 0x7a60, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, + 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, + 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, + 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a3, 0x1968, 0xb800, 0xc0e4, + 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, + 0x1960, 0x2004, 0x601a, 0x0804, 0x78fb, 0xa88c, 0x9065, 0x0960, + 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005, 0x0150, + 0x080c, 0xa01c, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa01c, 0x00ee, + 0x0804, 0x78fb, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, + 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, + 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x00ee, 0x0804, 0x78fb, 0x2061, 0x1a4c, 0x6000, 0xd084, 0x0190, + 0xd08c, 0x1904, 0x7a74, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0220, 0x6206, 0x012e, 0x0804, 0x7a74, 0x012e, 0xa883, 0x0016, + 0x0804, 0x7a6d, 0xa883, 0x0007, 0x0804, 0x7a6d, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, + 0x0005, 0x080c, 0x75d8, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, + 0x7016, 0x701a, 0x704b, 0x799d, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff, 0x1904, + 0x7a1f, 0x6130, 0xd194, 0x1904, 0x7a49, 0xa878, 0x2070, 0x9e82, + 0x1cd0, 0x0a04, 0x7a13, 0x6064, 0x9e02, 0x1a04, 0x7a13, 0x7120, + 0x9186, 0x0006, 0x1904, 0x7a05, 0x7010, 0x905d, 0x0904, 0x7a1f, + 0xb800, 0xd0e4, 0x1904, 0x7a43, 0x2061, 0x1a4c, 0x6100, 0x9184, + 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7a4c, + 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, + 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x080c, 0x54db, 0xd09c, + 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8370, 0x012e, + 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, + 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7a6d, + 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x63a3, + 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, + 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, + 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, + 0x54df, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, + 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, + 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, + 0x9086, 0x0007, 0x1904, 0x79a9, 0x7003, 0x0002, 0x0804, 0x79a9, + 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, + 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, + 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd38f, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, + 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, + 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6a22, 0x012e, 0x0005, 0x080c, 0x1069, 0x0005, 0x00d6, + 0x080c, 0x8367, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, + 0x190c, 0x7b08, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc, 0x90ea, + 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e, + 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, + 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, + 0x190c, 0x7b08, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, + 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, + 0x7af9, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, + 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, + 0x04b0, 0x2b10, 0x080c, 0x9f94, 0x1118, 0x080c, 0xa03b, 0x05a8, + 0x6212, 0xa874, 0x0002, 0x7ad7, 0x7adc, 0x7adf, 0x7ae5, 0x2019, + 0x0002, 0x080c, 0xd7af, 0x0060, 0x080c, 0xd746, 0x0048, 0x2019, + 0x0002, 0xa980, 0x080c, 0xd761, 0x0018, 0xa980, 0x080c, 0xd746, + 0x080c, 0x9fea, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, + 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, + 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, + 0x2091, 0x8000, 0x0e04, 0x7b0a, 0x0006, 0x0016, 0x2001, 0x8003, + 0x0006, 0x0804, 0x0dff, 0x2001, 0x1833, 0x2004, 0x9005, 0x0005, + 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, + 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, + 0x150f, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, + 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8a, 0x68bc, + 0x90aa, 0x0005, 0x0a04, 0x8166, 0x7d44, 0x7c40, 0x9584, 0x00f6, + 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584, + 0x0700, 0x8007, 0x0804, 0x7b91, 0x7000, 0x9084, 0xff00, 0x9086, + 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, + 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdbb3, 0x080c, 0x809b, + 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x80f9, + 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bec, 0x080c, + 0x2165, 0x005e, 0x004e, 0x0020, 0x080c, 0xdbb3, 0x7817, 0x0140, + 0x080c, 0x717e, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, + 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, + 0x080c, 0x7bcd, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, + 0x0005, 0x0002, 0x7ba3, 0x7ea3, 0x7b9a, 0x7b9a, 0x7b9a, 0x7b9a, + 0x7b9a, 0x7b9a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, + 0x090c, 0x8b8f, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, + 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150, 0x6800, + 0x9086, 0x0001, 0x1118, 0x080c, 0x5545, 0x0070, 0x080c, 0x7c0c, + 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddb, 0x0028, 0x9286, + 0x8000, 0x1110, 0x080c, 0x7fc2, 0x7817, 0x0140, 0x2001, 0x19cb, + 0x2004, 0x9005, 0x090c, 0x8b8f, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, + 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a17, 0x003e, + 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, + 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, + 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, + 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, + 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a17, 0x002e, 0x00fe, + 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, + 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, + 0x7dac, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8060, 0x0904, 0x7dac, + 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, + 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dac, 0x7124, 0x610a, + 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xa068, + 0x0804, 0x7dac, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, + 0x2009, 0x0015, 0x080c, 0xa068, 0x0804, 0x7dac, 0x908e, 0x0100, + 0x1904, 0x7dac, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0016, + 0x080c, 0xa068, 0x0804, 0x7dac, 0x9186, 0x0022, 0x1904, 0x7dac, + 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528, 0xc0b5, + 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e, 0x00f6, + 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, + 0x2008, 0x080c, 0x26b6, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, + 0x080c, 0x266d, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, + 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904, 0x7dac, + 0x2009, 0x0017, 0x0804, 0x7d5c, 0x908e, 0x0400, 0x1190, 0x7034, + 0x9005, 0x1904, 0x7dac, 0x080c, 0x717e, 0x0120, 0x2009, 0x001d, + 0x0804, 0x7d5c, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030, 0x0804, + 0x7d5c, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac, + 0x2009, 0x0018, 0x0804, 0x7d5c, 0x908e, 0x2010, 0x1120, 0x2009, + 0x0019, 0x0804, 0x7d5c, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, + 0x0804, 0x7d5c, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, + 0x7dac, 0x2009, 0x001b, 0x0804, 0x7d5c, 0x908e, 0x5000, 0x1140, + 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x001c, 0x0804, 0x7d5c, + 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5c, 0x908e, + 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0024, + 0x0804, 0x7d5c, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, + 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5c, 0x080c, + 0xcb61, 0x1904, 0x7dac, 0x0804, 0x7d5a, 0x908c, 0xff00, 0x918e, + 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5c, 0x908e, 0x0f00, + 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5c, 0x908e, 0x6104, 0x1528, + 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, + 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, + 0x2124, 0x080c, 0x4a17, 0x004e, 0x8108, 0x0f04, 0x7d28, 0x9186, + 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, + 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000, 0x1118, + 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, + 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, + 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, + 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, + 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, + 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x266d, 0x1904, 0x7daf, 0x080c, 0x6343, + 0x1904, 0x7daf, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x717e, + 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, + 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606, 0x1148, + 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb8b2, + 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x6878, + 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, + 0x0098, 0x080c, 0x9f94, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, + 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, + 0x0016, 0x001e, 0x080c, 0xa068, 0x00ce, 0x00be, 0x0005, 0x001e, + 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4a17, 0x080c, 0xa03b, 0x0d90, 0x2b08, 0x6112, 0x6023, + 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, + 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, + 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, + 0x080c, 0x8640, 0x08a0, 0x080c, 0x8185, 0x1158, 0x080c, 0x31b8, + 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, + 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, + 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8060, 0x0904, 0x7e3b, + 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, + 0x15d0, 0x2009, 0x0015, 0x080c, 0xa068, 0x04a8, 0x908e, 0x0100, + 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0xa068, + 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518, + 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x266d, 0x11b8, 0x080c, 0x6343, 0x11a0, 0xbe12, 0xbd16, + 0x080c, 0x9f94, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, + 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa068, 0x080c, 0x8b8f, + 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, + 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f, + 0x0804, 0x7e9d, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, + 0x7e9d, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, + 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, + 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, + 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0, + 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600, + 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, + 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, + 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e72, 0x82ff, 0x1118, + 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, + 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184, 0x0080, + 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, + 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, + 0x090c, 0x8b8f, 0x0005, 0x7ecb, 0x7ecb, 0x7ecb, 0x8072, 0x7ecb, + 0x7ed4, 0x7eff, 0x7f8d, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb, + 0x7ecb, 0x7ecb, 0x7ecb, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, + 0x9005, 0x090c, 0x8b8f, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, + 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, + 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, + 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, + 0x610a, 0x2009, 0x0046, 0x080c, 0xa068, 0x7817, 0x0140, 0x2001, + 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005, 0x00b6, + 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f63, 0x7110, 0xd1bc, 0x1904, + 0x7f63, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, + 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x31f3, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f63, 0x080c, + 0x6343, 0x1904, 0x7f63, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8, + 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0x9f94, + 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, 0x6023, + 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c, + 0xcdd7, 0x0408, 0x080c, 0x66c9, 0x1138, 0xb807, 0x0606, 0x0c30, + 0x190c, 0x7e3f, 0x11c0, 0x0898, 0x080c, 0x9f94, 0x2b08, 0x0198, + 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, + 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, + 0x9005, 0x090c, 0x8b8f, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a17, 0x080c, + 0xa03b, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, + 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041, + 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x08b0, 0x00b6, 0x7110, 0xd1bc, + 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, - 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xa053, 0x7817, 0x0140, - 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be, 0x0005, - 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f64, 0x7110, 0xd1bc, - 0x1904, 0x7f64, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, - 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x3209, 0x200d, - 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f64, - 0x080c, 0x6344, 0x1904, 0x7f64, 0xbe12, 0xbd16, 0xb800, 0xd0ec, - 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, - 0x9f7f, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, - 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, - 0x080c, 0xcdcd, 0x0408, 0x080c, 0x66ca, 0x1138, 0xb807, 0x0606, - 0x0c30, 0x190c, 0x7e40, 0x11c0, 0x0898, 0x080c, 0x9f7f, 0x2b08, - 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, - 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, - 0x080c, 0x8641, 0x080c, 0x8b90, 0x7817, 0x0140, 0x2001, 0x19cb, - 0x2004, 0x9005, 0x090c, 0x8b90, 0x00ce, 0x00be, 0x0005, 0x2001, - 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18, - 0x080c, 0xa026, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, - 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, - 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x08b0, 0x00b6, 0x7110, - 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, - 0x1cd0, 0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, - 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, - 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa053, 0x7817, - 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be, - 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, - 0x9085, 0x0001, 0x0005, 0x080c, 0x8186, 0x1180, 0x080c, 0x31ce, - 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, - 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdd, - 0x7fde, 0x7fdd, 0x7fdd, 0x8043, 0x8052, 0x0005, 0x00b6, 0x700c, - 0x7108, 0x080c, 0x266e, 0x1904, 0x8041, 0x080c, 0x6344, 0x1904, - 0x8041, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, - 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8041, 0x080c, 0x66ca, 0x0148, - 0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086, 0x0004, - 0x1588, 0x00c6, 0x080c, 0x8061, 0x00ce, 0x05d8, 0x080c, 0x9f7f, - 0x2b08, 0x05b8, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0002, 0x7120, - 0x610a, 0x2009, 0x0088, 0x080c, 0xa053, 0x0458, 0x080c, 0x66ca, - 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086, - 0x0004, 0x1180, 0x080c, 0x9f7f, 0x2b08, 0x01d8, 0x6112, 0x080c, - 0xc1b7, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, - 0xa053, 0x0078, 0x080c, 0x9f7f, 0x2b08, 0x0158, 0x6112, 0x080c, - 0xc1b7, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, - 0xa053, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, - 0x080c, 0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, - 0xa053, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, - 0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa053, - 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, - 0x0240, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, - 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, - 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864, - 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, - 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, - 0x080c, 0xa053, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, - 0x090c, 0x8b90, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, - 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, - 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, - 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f7f, 0x05b8, - 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, - 0x080c, 0x266e, 0x15a0, 0x080c, 0x6344, 0x1588, 0xbe12, 0xbd16, - 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1b7, 0x080c, 0x1043, - 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, - 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, - 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, - 0x0001, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00fe, - 0x009e, 0x00ce, 0x0005, 0x080c, 0x9fd5, 0x006e, 0x0cc0, 0x004e, - 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, - 0x810f, 0x9086, 0x2000, 0x1904, 0x8151, 0x9186, 0x0022, 0x15f0, - 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8153, 0x7030, 0x908e, - 0x0400, 0x0904, 0x8153, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, - 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c, - 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6688, 0x0588, 0x68ac, 0x9084, - 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac, - 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, - 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, - 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, - 0x1140, 0x080c, 0x8061, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, - 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, - 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836, - 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6, - 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, - 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, - 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, - 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, - 0x1836, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, - 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003, - 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, - 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0x961b, 0x7032, 0x7037, - 0x9683, 0x7047, 0xffff, 0x704a, 0x704f, 0x536e, 0x7052, 0x7063, - 0x82f5, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900, 0x7042, 0xa867, - 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5, - 0x1d04, 0x8249, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510, - 0x2001, 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, - 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0e02, - 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, - 0x833a, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, - 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, - 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, - 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, - 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, - 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, - 0x9701, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, - 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, - 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, - 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, - 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, - 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, - 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, - 0x012e, 0x7004, 0x0002, 0x8271, 0x8272, 0x828e, 0x00e6, 0x2071, - 0x19d5, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, - 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206, - 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, - 0x00e6, 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, - 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a4, 0x1168, 0xb888, - 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, - 0x080c, 0x8b90, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, - 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, - 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, - 0x1110, 0x080c, 0xc048, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a, - 0x1510, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, - 0x080c, 0xbd3b, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, - 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, - 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, - 0x0110, 0x080c, 0xba41, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, - 0x1819, 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, - 0x0005, 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009, - 0x00ee, 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6, - 0x2071, 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, - 0x19e1, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a, - 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, - 0x8000, 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000, - 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, - 0xa08e, 0x080c, 0x1140, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, - 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, - 0x080c, 0x81be, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, - 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5, - 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, - 0x2071, 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, - 0x00ee, 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026, - 0xd1ec, 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294, - 0x00c0, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, - 0x0110, 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, - 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c, - 0x0f23, 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005, - 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060, - 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, - 0x2061, 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, - 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, - 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fb, - 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x83d4, 0x2009, 0x0006, 0x080c, - 0x8428, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, - 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8422, - 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, - 0x2009, 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, - 0x0043, 0x0804, 0xa053, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, - 0x0804, 0xa053, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, - 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, - 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, - 0x0120, 0x918e, 0x0003, 0x1904, 0x8422, 0x908c, 0x2020, 0x918e, - 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x165d, 0x00fe, - 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa053, 0x0005, - 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, - 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, - 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, - 0x1120, 0x2009, 0x0041, 0x080c, 0xa053, 0x0005, 0x00b9, 0x0ce8, - 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa053, 0x0cb0, 0x6110, - 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, - 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, - 0x0096, 0x080c, 0xbd3b, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, - 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, - 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120, - 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6862, 0x6014, - 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x8371, 0x007e, 0x009e, - 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110, - 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, - 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, - 0x0001, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, - 0x0010, 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, - 0x8473, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, - 0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, - 0x848a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x848a, 0x0006, - 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, - 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, - 0x2800, 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803, - 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, - 0x080c, 0x9ddd, 0x0401, 0x080c, 0x9dc8, 0x00e9, 0x080c, 0x9dcb, - 0x00d1, 0x080c, 0x9dce, 0x00b9, 0x080c, 0x9dd1, 0x00a1, 0x080c, - 0x9dd4, 0x0089, 0x080c, 0x9dd7, 0x0071, 0x080c, 0x9dda, 0x0059, - 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, - 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, - 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, - 0x0007, 0x0002, 0x84f4, 0x8518, 0x8559, 0x84fa, 0x8518, 0x84f4, - 0x84f2, 0x84f2, 0x080c, 0x0e02, 0x080c, 0x82da, 0x080c, 0x8b90, - 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, - 0x5c99, 0x080c, 0x825a, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, - 0x782a, 0x080c, 0x5cd9, 0x0c88, 0x62c0, 0x080c, 0x9de1, 0x080c, - 0x5c99, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, - 0x080c, 0x82da, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, - 0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013, 0x080c, - 0xa053, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0e02, - 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, - 0x29fe, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, - 0x0e02, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b90, - 0x0c00, 0x080c, 0x95e1, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, - 0x9de1, 0x080c, 0xdb8f, 0x2009, 0x0014, 0x080c, 0xa053, 0x00ce, - 0x0880, 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, - 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013, - 0x080c, 0xa0a5, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, - 0x9005, 0x090c, 0x0e02, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, - 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x29fe, 0x02f0, 0x00b6, - 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0e02, 0xb800, 0xc0dc, - 0xb802, 0x7924, 0x2160, 0x080c, 0x9fd5, 0xb93c, 0x81ff, 0x090c, - 0x0e02, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, - 0x00ce, 0x00be, 0x080c, 0x8b90, 0x0868, 0x080c, 0x95e1, 0x0850, - 0x2011, 0x0130, 0x2214, 0x080c, 0x9de1, 0x080c, 0xdb8f, 0x7824, - 0x9065, 0x2009, 0x0014, 0x080c, 0xa053, 0x00de, 0x00ce, 0x00be, - 0x0804, 0x856a, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, - 0x1d04, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, - 0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, - 0xa053, 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8, - 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108, - 0x7946, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, - 0x6014, 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014, - 0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160, - 0x2009, 0x004a, 0x080c, 0xa053, 0x08a0, 0x7848, 0xc085, 0x784a, - 0x0880, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, - 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010, - 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, - 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, - 0x19c2, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, - 0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b90, 0x00de, - 0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, - 0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, - 0x2069, 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, - 0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, - 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008, - 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, - 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, - 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080, - 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, - 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, - 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, - 0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, - 0x0904, 0x86ed, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e8, - 0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x86e8, 0x703c, 0x9c06, - 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000, - 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, - 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, - 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, - 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, - 0x600f, 0x0000, 0x080c, 0xbd3b, 0x01f0, 0x6014, 0x2048, 0x6020, - 0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, - 0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x007e, 0x003e, - 0x001e, 0x080c, 0xbf26, 0x080c, 0xa007, 0x00ce, 0x0804, 0x8687, - 0x2c78, 0x600c, 0x2060, 0x0804, 0x8687, 0x85ff, 0x0120, 0x0036, - 0x080c, 0x8c6d, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, - 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, - 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, - 0x0076, 0x080c, 0xda80, 0x080c, 0xd781, 0x007e, 0x003e, 0x001e, - 0x0890, 0x6020, 0x9086, 0x000a, 0x0904, 0x86d2, 0x0804, 0x86cb, - 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, - 0x2091, 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876d, - 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, - 0x2019, 0x0001, 0x080c, 0x989c, 0x7833, 0x0000, 0x901e, 0x7b3e, - 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd3b, 0x0548, 0x6014, - 0x2048, 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, - 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004, - 0x6042, 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c, 0xbf26, - 0x080c, 0xa007, 0x000e, 0x0804, 0x8725, 0x7e3a, 0x7e36, 0x012e, - 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, - 0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x6020, 0x9086, - 0x000a, 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, - 0x080c, 0x886e, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, - 0x2079, 0x19c2, 0x2091, 0x8000, 0x080c, 0x8905, 0x080c, 0x8995, - 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19c2, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8833, 0x6010, - 0x2058, 0xb8a0, 0x9206, 0x1904, 0x882e, 0x88ff, 0x0120, 0x6054, - 0x9106, 0x1904, 0x882e, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, - 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c, - 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, - 0x630a, 0x0804, 0x882e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, - 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, - 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, - 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, - 0xbd3b, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf43, - 0x1118, 0x080c, 0xa995, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xc031, 0x080c, 0xda80, - 0x080c, 0x6a23, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf26, 0x080c, - 0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x87ac, 0x2c78, 0x600c, - 0x2060, 0x0804, 0x87ac, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xda80, 0x080c, - 0xd781, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa995, 0x6020, - 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, - 0x0904, 0x8814, 0x9086, 0x008b, 0x0904, 0x8814, 0x0840, 0x6020, - 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, - 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x8827, 0x00b6, 0x00a6, - 0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, - 0x2004, 0x905d, 0x0904, 0x88fe, 0x00f6, 0x00e6, 0x00d6, 0x0066, - 0x2071, 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, - 0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, - 0xb858, 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, - 0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, - 0xb802, 0x080c, 0x62d7, 0x0904, 0x88fa, 0x7624, 0x86ff, 0x0904, - 0x88e9, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, - 0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x82da, 0x080c, 0x9605, - 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, + 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa068, 0x7817, 0x0140, + 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005, + 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, + 0x0001, 0x0005, 0x080c, 0x8185, 0x1180, 0x080c, 0x31b8, 0x1168, + 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, + 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdc, 0x7fdd, + 0x7fdc, 0x7fdc, 0x8042, 0x8051, 0x0005, 0x00b6, 0x700c, 0x7108, + 0x080c, 0x266d, 0x1904, 0x8040, 0x080c, 0x6343, 0x1904, 0x8040, + 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120, + 0xb800, 0xd0bc, 0x1904, 0x8040, 0x080c, 0x66c9, 0x0148, 0x9086, + 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004, 0x1588, + 0x00c6, 0x080c, 0x8060, 0x00ce, 0x05d8, 0x080c, 0x9f94, 0x2b08, + 0x05b8, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0002, 0x7120, 0x610a, + 0x2009, 0x0088, 0x080c, 0xa068, 0x0458, 0x080c, 0x66c9, 0x0148, + 0x9086, 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004, + 0x1180, 0x080c, 0x9f94, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xa068, + 0x0078, 0x080c, 0x9f94, 0x2b08, 0x0158, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xa068, + 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, + 0x7fb8, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xa068, + 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x7fb8, + 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa068, 0x0005, + 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, 0x0240, + 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, + 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, + 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864, 0x9c02, + 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, + 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c, + 0xa068, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, + 0x8b8f, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, + 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, + 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, + 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f94, 0x05b8, 0x0066, + 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, + 0x266d, 0x15a0, 0x080c, 0x6343, 0x1588, 0xbe12, 0xbd16, 0x2b00, + 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1ca, 0x080c, 0x1037, 0x0510, + 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, + 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, + 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00fe, 0x009e, + 0x00ce, 0x0005, 0x080c, 0x9fea, 0x006e, 0x0cc0, 0x004e, 0x00ce, + 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f, + 0x9086, 0x2000, 0x1904, 0x8150, 0x9186, 0x0022, 0x15f0, 0x2001, + 0x0111, 0x2004, 0x9005, 0x1904, 0x8152, 0x7030, 0x908e, 0x0400, + 0x0904, 0x8152, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, + 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c, 0x1590, + 0xd1a4, 0x1580, 0x080c, 0x6687, 0x0588, 0x68ac, 0x9084, 0x00ff, + 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac, 0x918c, + 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, + 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, + 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140, + 0x080c, 0x8060, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, + 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, + 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836, 0x2004, + 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6, 0x2079, + 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800, + 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1836, + 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003, 0x0003, + 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, 0x1cd0, + 0x7007, 0x0000, 0x7026, 0x702b, 0x9630, 0x7032, 0x7037, 0x9698, + 0x7047, 0xffff, 0x704a, 0x704f, 0x536d, 0x7052, 0x7063, 0x82f4, + 0x080c, 0x1050, 0x090c, 0x0df6, 0x2900, 0x7042, 0xa867, 0x0003, + 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5, 0x1d04, + 0x8248, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510, 0x2001, + 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, + 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0df6, 0x700f, + 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x8339, + 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, + 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, + 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, + 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, + 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, + 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0x9716, + 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001, + 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148, + 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060, + 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158, + 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a, + 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, + 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, + 0x7004, 0x0002, 0x8270, 0x8271, 0x828d, 0x00e6, 0x2071, 0x19d5, + 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1120, + 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, + 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a3, 0x1168, 0xb888, 0x8001, + 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x8b8f, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, + 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, + 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, + 0x080c, 0xc05b, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a, 0x1510, + 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, 0x080c, + 0xbd4e, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, + 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, + 0x080c, 0xba50, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x1819, + 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, + 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x19e1, + 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a, 0x721e, + 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, + 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, + 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, + 0x080c, 0x1134, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, + 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, + 0x81bd, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, + 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x717a, + 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, + 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, + 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026, 0xd1ec, + 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, + 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, + 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, + 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c, 0x0f17, + 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005, 0x9184, + 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060, 0x0005, + 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, + 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, + 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, + 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fa, 0xd0b4, + 0x1168, 0xd0bc, 0x1904, 0x83d3, 0x2009, 0x0006, 0x080c, 0x8427, + 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, + 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8421, 0x908c, + 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, + 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, + 0x0804, 0xa068, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, + 0xa068, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, + 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, + 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, + 0x918e, 0x0003, 0x1904, 0x8421, 0x908c, 0x2020, 0x918e, 0x2020, + 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x007e, + 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa068, 0x0005, 0x6110, + 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, + 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, + 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, + 0x2009, 0x0041, 0x080c, 0xa068, 0x0005, 0x00b9, 0x0ce8, 0x87ff, + 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa068, 0x0cb0, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, + 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, + 0x080c, 0xbd4e, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, + 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, + 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120, 0x6204, + 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6861, 0x6014, 0x904d, + 0x0076, 0x2039, 0x0000, 0x190c, 0x8370, 0x007e, 0x009e, 0x0005, + 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110, 0x9205, + 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, + 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, + 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x8472, + 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, + 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x8489, + 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x8489, 0x0006, 0x3200, + 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, + 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, + 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803, 0x0005, + 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, + 0x9df2, 0x0401, 0x080c, 0x9ddd, 0x00e9, 0x080c, 0x9de0, 0x00d1, + 0x080c, 0x9de3, 0x00b9, 0x080c, 0x9de6, 0x00a1, 0x080c, 0x9de9, + 0x0089, 0x080c, 0x9dec, 0x0071, 0x080c, 0x9def, 0x0059, 0x01de, + 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, + 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, + 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, + 0x0002, 0x84f3, 0x8517, 0x8558, 0x84f9, 0x8517, 0x84f3, 0x84f1, + 0x84f1, 0x080c, 0x0df6, 0x080c, 0x82d9, 0x080c, 0x8b8f, 0x00ce, + 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, + 0x080c, 0x5cd8, 0x0c88, 0x62c0, 0x080c, 0x9df6, 0x080c, 0x5c98, + 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, + 0x82d9, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, + 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c, 0xa068, + 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0df6, 0x7828, + 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x29e9, + 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0df6, + 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b8f, 0x0c00, + 0x080c, 0x95f6, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0x9df6, + 0x080c, 0xdbf0, 0x2009, 0x0014, 0x080c, 0xa068, 0x00ce, 0x0880, + 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, + 0x0000, 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c, + 0xa0ba, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, + 0x090c, 0x0df6, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, + 0x00de, 0x00ce, 0x00be, 0x080c, 0x29e9, 0x02f0, 0x00b6, 0x00c6, + 0x00d6, 0x781c, 0x905d, 0x090c, 0x0df6, 0xb800, 0xc0dc, 0xb802, + 0x7924, 0x2160, 0x080c, 0x9fea, 0xb93c, 0x81ff, 0x090c, 0x0df6, + 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, + 0x00be, 0x080c, 0x8b8f, 0x0868, 0x080c, 0x95f6, 0x0850, 0x2011, + 0x0130, 0x2214, 0x080c, 0x9df6, 0x080c, 0xdbf0, 0x7824, 0x9065, + 0x2009, 0x0014, 0x080c, 0xa068, 0x00de, 0x00ce, 0x00be, 0x0804, + 0x8569, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1d00, + 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, 0x9205, + 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xa068, + 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8, 0x793c, + 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7946, + 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014, 0x9084, + 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160, 0x2009, + 0x004a, 0x080c, 0xa068, 0x08a0, 0x7848, 0xc085, 0x784a, 0x0880, + 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, + 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19c2, + 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, + 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b8f, 0x00de, 0x0005, + 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, + 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, + 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, + 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, + 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, + 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, + 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, + 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, + 0x86ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e7, 0x87ff, + 0x0120, 0x6054, 0x9106, 0x1904, 0x86e7, 0x703c, 0x9c06, 0x1178, + 0x0036, 0x2019, 0x0001, 0x080c, 0x98b1, 0x7033, 0x0000, 0x9006, + 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, + 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x080c, 0xbd4e, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, + 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, + 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x007e, 0x003e, 0x001e, + 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce, 0x0804, 0x8686, 0x2c78, + 0x600c, 0x2060, 0x0804, 0x8686, 0x85ff, 0x0120, 0x0036, 0x080c, + 0x8c6c, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, + 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, + 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x007e, 0x003e, 0x001e, 0x0890, + 0x6020, 0x9086, 0x000a, 0x0904, 0x86d1, 0x0804, 0x86ca, 0x0006, + 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, + 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876c, 0x600c, + 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, + 0x0001, 0x080c, 0x98b1, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, + 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd4e, 0x0548, 0x6014, 0x2048, + 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, + 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004, 0x6042, + 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, + 0xa01c, 0x000e, 0x0804, 0x8724, 0x7e3a, 0x7e36, 0x012e, 0x00fe, + 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x6020, 0x9086, 0x000a, + 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, + 0x886d, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, + 0x19c2, 0x2091, 0x8000, 0x080c, 0x8904, 0x080c, 0x8994, 0x012e, + 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, + 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8832, 0x6010, 0x2058, + 0xb8a0, 0x9206, 0x1904, 0x882d, 0x88ff, 0x0120, 0x6054, 0x9106, + 0x1904, 0x882d, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, + 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, - 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa007, 0x00ce, 0x0048, - 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, - 0x88a1, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, - 0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x080c, 0x9940, - 0x0804, 0x88a1, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, - 0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, - 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8968, 0x600c, - 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, - 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c, - 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6680, - 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, - 0x080c, 0xbd39, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, - 0xbf43, 0x1118, 0x080c, 0xa995, 0x0060, 0x080c, 0x6680, 0x1168, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, - 0xbf26, 0x080c, 0xa007, 0x080c, 0x9940, 0x000e, 0x0804, 0x890c, - 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, - 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x080c, - 0xa995, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, - 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, - 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, - 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, - 0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a15, 0xb854, - 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, - 0x080c, 0x62d7, 0x0904, 0x8a12, 0x7e24, 0x86ff, 0x0904, 0x8a05, - 0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x8a05, 0x00d6, 0x2069, - 0x0100, 0x68c0, 0x9005, 0x0904, 0x89fc, 0x080c, 0x82da, 0x080c, - 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, - 0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, - 0x200c, 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0, - 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, - 0x080c, 0xa007, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, - 0x0009, 0x630a, 0x00ce, 0x0804, 0x89a8, 0x89ff, 0x0138, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0x9940, - 0x0804, 0x89a8, 0x000e, 0x0804, 0x899c, 0x781e, 0x781a, 0x00de, - 0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, - 0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, - 0xa878, 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148, - 0x9080, 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, - 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, - 0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, - 0x630a, 0x00ce, 0x04b8, 0x080c, 0x9605, 0x78c3, 0x0000, 0x080c, - 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, - 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c, - 0x2b88, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, - 0x080c, 0x9a6a, 0x003e, 0x080c, 0x62d7, 0x00c6, 0xb83c, 0x9005, - 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fd5, 0x00ce, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xc031, 0x080c, 0x6a23, - 0x080c, 0x9940, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, - 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, - 0x2202, 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa1, - 0x8aa5, 0x8ac3, 0x8aec, 0x8b2a, 0x8aa1, 0x8abc, 0x8a9f, 0x080c, - 0x0e02, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, - 0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, - 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, - 0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, - 0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800, - 0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, - 0x7022, 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, - 0x00ee, 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, - 0x8b90, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b90, 0x0c80, 0xc2ec, - 0x2202, 0x080c, 0x8c6d, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, - 0x9c06, 0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x720e, - 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, - 0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, - 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, - 0x1198, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800, 0xc0dc, 0xb802, - 0x080c, 0x9940, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, - 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, - 0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9940, 0x600c, - 0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a6a, 0x7027, - 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, - 0x00d6, 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4d, - 0x8b4f, 0x8b73, 0x8b4b, 0x080c, 0x0e02, 0x00de, 0x0005, 0x00c6, - 0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, - 0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, - 0x0000, 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, - 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, - 0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, - 0x683c, 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, - 0x0000, 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, - 0x00de, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, - 0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, - 0x8c6d, 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, - 0x2069, 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8bb0, 0x8c55, - 0x8c55, 0x8c55, 0x8c55, 0x8c57, 0x8c55, 0x8bae, 0x080c, 0x0e02, - 0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, - 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4, - 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, - 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005, - 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3f, 0xb84c, - 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, - 0x920e, 0x0904, 0x8c3f, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3f, - 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, - 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fac, 0x0904, - 0x8c3f, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, - 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, - 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, - 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, - 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, - 0xbab0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x922a, - 0x2069, 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, - 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, - 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, - 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, - 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x62d7, 0x080c, 0x9e01, - 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, - 0x680c, 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, - 0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, - 0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, - 0x19c2, 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014, - 0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9f, 0x2069, 0x19c2, - 0x2001, 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0, - 0x6a04, 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847, - 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, - 0x080c, 0x1b0e, 0x1158, 0x012e, 0x080c, 0x9462, 0x00de, 0x00fe, - 0x0005, 0xc1c4, 0x2102, 0x080c, 0x7247, 0x08f8, 0x012e, 0x6843, - 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, - 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, - 0x0cc0, 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c65, 0x6a30, 0x9296, - 0x0000, 0x0950, 0x0804, 0x8c65, 0x6020, 0x9084, 0x000f, 0x000b, - 0x0005, 0x8cd8, 0x8cdd, 0x915a, 0x91f3, 0x8cdd, 0x915a, 0x91f3, - 0x8cd8, 0x8cdd, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, - 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x00b6, 0x0156, 0x0136, - 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, - 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02, - 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, - 0x0040, 0x1a04, 0x8d49, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee4, - 0x8f1f, 0x8f48, 0x8feb, 0x900c, 0x9012, 0x901f, 0x9027, 0x9033, - 0x9039, 0x904a, 0x9039, 0x90a1, 0x9027, 0x90ad, 0x90b3, 0x9033, - 0x90b3, 0x90bf, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, - 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x9753, 0x9776, 0x9787, - 0x97a7, 0x97d9, 0x901f, 0x8d47, 0x901f, 0x9039, 0x8d47, 0x8f48, - 0x8feb, 0x8d47, 0x9b61, 0x9039, 0x8d47, 0x9b7d, 0x9039, 0x8d47, - 0x9033, 0x8ede, 0x8d6a, 0x8d47, 0x9b99, 0x9c06, 0x9ce1, 0x8d47, - 0x9cee, 0x901c, 0x9d19, 0x8d47, 0x97e3, 0x9d46, 0x8d47, 0x080c, - 0x0e02, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, - 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d68, 0x8d68, - 0x8d68, 0x8da2, 0x8e4e, 0x8e59, 0x8d68, 0x8d68, 0x8d68, 0x8eb3, - 0x8ebf, 0x8dbd, 0x8d68, 0x8dd8, 0x8e0c, 0x9ec8, 0x9f0d, 0x9039, - 0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x0026, 0x0036, - 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, - 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, - 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, - 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95d9, 0x003e, - 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, - 0x00be, 0x080c, 0x9f54, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, - 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x7003, 0x0500, - 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, - 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, - 0x080c, 0x95d9, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, - 0x90d2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, - 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, - 0x701e, 0x60c3, 0x0010, 0x080c, 0x95d9, 0x009e, 0x00de, 0x0005, - 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90d2, 0x20e9, - 0x0000, 0x2001, 0x197d, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, - 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x2001, 0x0001, - 0x080c, 0x21e9, 0x080c, 0xcaae, 0x9006, 0x080c, 0x21e9, 0x001e, - 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95d9, - 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, - 0x8000, 0x080c, 0x911d, 0x20e9, 0x0000, 0x2001, 0x197d, 0x2003, - 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, - 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x080c, 0xcaae, - 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, - 0x2048, 0x080c, 0x0ff5, 0x080c, 0x95d9, 0x012e, 0x009e, 0x00de, - 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, - 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90d2, - 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, - 0x95d9, 0x00d6, 0x00e6, 0x080c, 0x911d, 0x7814, 0x9084, 0xff00, - 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, - 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, - 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, - 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e79, 0x2069, 0x1801, - 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e82, 0x9096, - 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, - 0x2069, 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9, - 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, - 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, - 0x8d68, 0x8e70, 0x1f04, 0x8e99, 0x60c3, 0x004c, 0x080c, 0x95d9, - 0x00ee, 0x00de, 0x0005, 0x080c, 0x90d2, 0x7003, 0x6300, 0x7007, - 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x00d6, - 0x0026, 0x0016, 0x080c, 0x911d, 0x7003, 0x0200, 0x7814, 0x700e, - 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, - 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, - 0x080c, 0x95d9, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, - 0x2004, 0x609a, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5200, - 0x2069, 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, - 0x26a1, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, - 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, - 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f54, 0x1120, - 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, - 0x2001, 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, - 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95d9, 0x080c, - 0x90d2, 0x7003, 0x0500, 0x080c, 0x9f54, 0x1120, 0xb8a0, 0x9082, - 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f, - 0x2004, 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, - 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, - 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95d9, - 0x080c, 0x90d2, 0x9006, 0x080c, 0x6694, 0xb8a0, 0x9086, 0x007e, - 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, - 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, - 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fb3, 0x00d6, - 0x2069, 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800, - 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f, - 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0080, 0x6800, 0x700a, - 0x6804, 0x700e, 0x6808, 0x080c, 0x717f, 0x1118, 0x9084, 0x37ff, - 0x0010, 0x9084, 0x3fff, 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9, - 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, - 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, - 0x4003, 0x00d6, 0x080c, 0x9dc8, 0x2069, 0x194e, 0x2071, 0x024e, - 0x6800, 0xc0dd, 0x7002, 0x080c, 0x54e0, 0xd0e4, 0x0110, 0x680c, - 0x700e, 0x00de, 0x04a0, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, - 0x0016, 0x2009, 0x0002, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, - 0x0000, 0x080c, 0x26e2, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, - 0x1946, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, - 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, - 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0x9dc8, - 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3, - 0x0074, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x2010, 0x7007, - 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, - 0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, - 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9082, 0x7026, - 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5000, - 0x0804, 0x8f62, 0x080c, 0x90d2, 0x7003, 0x2110, 0x7007, 0x0014, - 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x9114, 0x0010, 0x080c, - 0x911d, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x080c, - 0x911d, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, - 0x0008, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003, 0x0200, 0x0804, - 0x8f62, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, - 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, - 0x0804, 0x95d9, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007, - 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, - 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, - 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, - 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, - 0x2079, 0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, - 0x0010, 0x9085, 0x0010, 0x2009, 0x187d, 0x210c, 0xd184, 0x1110, - 0x9085, 0x0002, 0x0026, 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150, - 0xc0c5, 0xbabc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, - 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, - 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, - 0x95d9, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, - 0x0100, 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003, - 0x0200, 0x0804, 0x8ee8, 0x080c, 0x911d, 0x7003, 0x0100, 0x700b, - 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c, - 0x911d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, - 0x95d9, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, - 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, - 0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810, 0x9305, 0x7002, 0xb814, - 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, - 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a, - 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, - 0x0005, 0x0026, 0x080c, 0x9ddd, 0x7003, 0x02ff, 0x7007, 0xfffc, - 0x00d6, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x00de, - 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, - 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, - 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, - 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810, - 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, - 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, - 0x0020, 0x6878, 0x700a, 0x687c, 0x700e, 0x0000, 0x9485, 0x0098, - 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a, 0x7a08, - 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, - 0x95c7, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, - 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, - 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02, - 0x908a, 0x0092, 0x1a0c, 0x0e02, 0x6110, 0x2158, 0xb9b0, 0x2c78, - 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x0005, 0x918b, 0x919a, 0x91a5, 0x9189, - 0x9189, 0x9189, 0x918b, 0x9189, 0x9189, 0x9189, 0x9189, 0x9189, - 0x9189, 0x080c, 0x0e02, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, - 0x29fe, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, - 0x0804, 0x95d9, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, - 0xffff, 0x60c3, 0x000c, 0x0804, 0x95d9, 0x04a1, 0x7003, 0x0003, - 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x0026, 0x080c, - 0x9ddd, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, - 0x90ed, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8400, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, - 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, - 0x0804, 0x914f, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8500, - 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, - 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, - 0x7012, 0x0804, 0x914f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, - 0x0a0c, 0x0e02, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x7910, 0x2158, - 0xb9b0, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x922a, 0x92f1, 0x92c4, - 0x9413, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, - 0x9927, 0x992c, 0x9931, 0x9936, 0x9228, 0x9d25, 0x9228, 0x9922, - 0x080c, 0x0e02, 0x0096, 0x780b, 0xffff, 0x080c, 0x9295, 0x7914, - 0x2148, 0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, - 0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, - 0x703e, 0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, - 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, - 0x0006, 0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, - 0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, - 0x080c, 0x179e, 0x0010, 0x080c, 0x165d, 0x0050, 0xd1b4, 0x0118, - 0x7047, 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, - 0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, - 0x2069, 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, - 0x0020, 0x6017, 0x0009, 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001, - 0x19dd, 0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, - 0x8210, 0xb8bc, 0xd084, 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108, - 0x2102, 0x2001, 0x1aa0, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, - 0x794a, 0x712e, 0x7b46, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, - 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, - 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10, - 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, - 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, - 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0x95d9, 0x6813, - 0x0008, 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0889, 0x080c, - 0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, - 0x0005, 0x00d6, 0x0096, 0x080c, 0x93f1, 0x7814, 0x2048, 0x080c, - 0xbd39, 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, - 0x9006, 0x001b, 0x009e, 0x00de, 0x0005, 0x930f, 0x9378, 0x9388, - 0x93ae, 0x93ba, 0x93cb, 0x93d3, 0x930d, 0x080c, 0x0e02, 0x0016, - 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, - 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, - 0x701e, 0x003e, 0x001e, 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804, - 0x95d9, 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0e02, 0xaba8, - 0x7824, 0xd0cc, 0x1904, 0x9375, 0x7316, 0xa898, 0x701a, 0xa894, - 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, - 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, - 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, - 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, - 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, - 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, - 0x6812, 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, - 0x61c2, 0x003e, 0x001e, 0x0804, 0x95d9, 0xc3e5, 0x0804, 0x9334, - 0x2011, 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, - 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, - 0x2011, 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, - 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, - 0x7027, 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, - 0x704f, 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, - 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804, 0x95d9, 0x2011, 0x0028, - 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804, 0x95d9, - 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, - 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, - 0x0020, 0x0804, 0x95d9, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, - 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, - 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, - 0x7216, 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, - 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, - 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, - 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0x95c7, 0x721a, - 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, - 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, - 0x0013, 0x001e, 0x0005, 0x9423, 0x9423, 0x9425, 0x9423, 0x9423, - 0x9423, 0x943f, 0x9423, 0x080c, 0x0e02, 0x7914, 0x918c, 0x08ff, - 0x918d, 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b, - 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, - 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0x95d9, 0x2009, - 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9ddd, - 0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d, - 0x0008, 0x7116, 0x080c, 0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10, - 0x7226, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, - 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, - 0xb8a0, 0x2028, 0xb910, 0xba14, 0x7378, 0x747c, 0x7820, 0x90be, - 0x0006, 0x0904, 0x9536, 0x90be, 0x000a, 0x1904, 0x94f2, 0xb8b0, - 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, - 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, - 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, - 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, - 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, - 0x0000, 0xb8b0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, - 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, - 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, - 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, - 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0x9dc2, 0x2009, 0x07d0, - 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, - 0x82df, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, - 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0x9572, 0x9185, - 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, - 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, - 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, - 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e, - 0x080c, 0x9dc2, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, - 0x0110, 0x2009, 0x1b58, 0x080c, 0x82df, 0x003e, 0x004e, 0x005e, - 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048, - 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0x958e, 0x9185, - 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, - 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, - 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a, - 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930, - 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, 0x629e, 0x080c, 0x9d9f, - 0x0804, 0x9522, 0xb8bc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048, - 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600, - 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000, - 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0x9505, 0x9185, 0x0700, - 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118, - 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c, - 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, - 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e, - 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0xbab0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, - 0x9dc2, 0x0804, 0x9522, 0x080c, 0x9d9f, 0x0804, 0x9522, 0x7a10, - 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be, - 0x8217, 0x0005, 0x00d6, 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de, - 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d1, - 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, - 0x0600, 0x0128, 0x0089, 0x080c, 0x82d1, 0x001e, 0x0005, 0xc1e5, - 0x2001, 0x180c, 0x2102, 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001, - 0x19cb, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, - 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, - 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, - 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, - 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, - 0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x11c0, 0x2001, 0x19de, - 0x2004, 0x9005, 0x15d0, 0x080c, 0x7247, 0x1160, 0x2061, 0x0100, - 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0e02, 0x080c, - 0x82d1, 0x0458, 0x00c6, 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194, - 0x4000, 0x0540, 0x0811, 0x080c, 0x2b98, 0x00c6, 0x2061, 0x19c2, - 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, - 0x81ff, 0x0198, 0x080c, 0x82d1, 0x080c, 0x95fc, 0x0070, 0x6124, - 0x91e5, 0x0000, 0x0140, 0x080c, 0xdb8f, 0x080c, 0x82da, 0x2009, - 0x0014, 0x080c, 0xa053, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, - 0x00ce, 0x0005, 0x2001, 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6, - 0x2061, 0x19c2, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, - 0x00ce, 0x080c, 0x82d1, 0x080c, 0x5cef, 0x2009, 0x185a, 0x2114, - 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, - 0x0026, 0x080c, 0x82e7, 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904, - 0x96f5, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x1190, - 0x0036, 0x2019, 0x0002, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160, - 0x080c, 0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x080c, 0x7247, - 0x0804, 0x96f5, 0x6904, 0xd1f4, 0x0904, 0x96fc, 0x080c, 0x2b98, - 0x00c6, 0x703c, 0x9065, 0x090c, 0x0e02, 0x6020, 0x00ce, 0x9086, - 0x0006, 0x1568, 0x61c8, 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c, - 0x2104, 0xd0d4, 0x0520, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, - 0x9294, 0x0002, 0x1550, 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110, - 0x080c, 0x2aca, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, - 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xa053, 0x0070, 0x0036, - 0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160, 0x080c, - 0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x002e, 0x001e, 0x00ee, - 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0x96ae, 0x0804, - 0x96b0, 0x0026, 0x00e6, 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0, - 0x713c, 0x81ff, 0x01a8, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, - 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, - 0x7016, 0x0030, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, - 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, - 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, - 0xbca0, 0x2071, 0x19c2, 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, - 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, - 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x64d6, 0x0110, 0x9085, - 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00be, 0x0005, 0x080c, 0x90d2, 0x7003, 0x1200, 0x7838, - 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, - 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, - 0x0020, 0x2061, 0x1800, 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a, - 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0x95d9, 0x080c, 0x90d2, - 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, - 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0156, - 0x080c, 0x911d, 0x7003, 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, - 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, - 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, - 0x1f04, 0x9798, 0x60c3, 0x001c, 0x015e, 0x0804, 0x95d9, 0x0016, - 0x0026, 0x080c, 0x90f9, 0x080c, 0x910b, 0x9e80, 0x0004, 0x20e9, - 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, - 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, - 0x8003, 0x60c2, 0x080c, 0x95d9, 0x002e, 0x001e, 0x0005, 0x20a9, - 0x0010, 0x4003, 0x080c, 0x9dc8, 0x20a1, 0x0240, 0x22a8, 0x4003, - 0x0c68, 0x080c, 0x90d2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, - 0x0008, 0x0804, 0x95d9, 0x0016, 0x0026, 0x080c, 0x90d2, 0x20e9, - 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, - 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0x95d9, - 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19c2, 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, - 0xbf43, 0x1110, 0x080c, 0xa995, 0x600c, 0x0006, 0x080c, 0xc1af, - 0x080c, 0x9fd5, 0x080c, 0x9940, 0x00ce, 0x0c78, 0x2c00, 0x700e, - 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, - 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, - 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060, - 0x8cff, 0x01f8, 0x080c, 0x9605, 0x6ac0, 0x68c3, 0x0000, 0x080c, - 0x82da, 0x00c6, 0x2061, 0x0100, 0x080c, 0x9de1, 0x00ce, 0x20a9, - 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xa053, 0x000e, 0x001e, - 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, - 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, - 0x0004, 0x0d60, 0x080c, 0x82da, 0x6814, 0x9084, 0x0001, 0x0110, - 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c99, - 0x080c, 0x825a, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, - 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98, - 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x987e, - 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, - 0x9006, 0x080c, 0x2b88, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, - 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, - 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, - 0x2079, 0x0140, 0x2071, 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904, - 0x9903, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, - 0x9903, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, - 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x82e7, 0x080c, 0x1e34, - 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, - 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, - 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98, 0x0090, - 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0x98dd, 0x7804, - 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, - 0x080c, 0x2b88, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009, - 0x0049, 0x080c, 0xa053, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, - 0x2091, 0x8000, 0x2069, 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005, - 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e, - 0x00de, 0x0005, 0x080c, 0x9295, 0x7047, 0x1000, 0x0098, 0x080c, - 0x9295, 0x7047, 0x4000, 0x0070, 0x080c, 0x9295, 0x7047, 0x2000, - 0x0048, 0x080c, 0x9295, 0x7047, 0x0400, 0x0020, 0x080c, 0x9295, - 0x7047, 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0x95d9, - 0x00e6, 0x2071, 0x19c2, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, - 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, - 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660, - 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x99e5, 0x8cff, 0x0904, - 0x99e5, 0x6020, 0x9086, 0x0006, 0x1904, 0x99e0, 0x88ff, 0x0138, - 0x2800, 0x9c06, 0x1904, 0x99e0, 0x2039, 0x0000, 0x0050, 0x6010, - 0x9b06, 0x1904, 0x99e0, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, - 0x99e0, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, - 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x82da, - 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0428, 0x080c, 0x82da, 0x6820, - 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, - 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, - 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, - 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, - 0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, + 0x0804, 0x882d, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, - 0x2048, 0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x009e, 0x080c, - 0xa007, 0x080c, 0x9940, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x995b, - 0x2c78, 0x600c, 0x2060, 0x0804, 0x995b, 0x9006, 0x012e, 0x000e, - 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, - 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, - 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, - 0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a59, - 0x6020, 0x9086, 0x0006, 0x1904, 0x9a54, 0x87ff, 0x0128, 0x2700, - 0x9c06, 0x1904, 0x9a54, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, - 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, - 0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000, 0x9006, 0x703e, - 0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, - 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, - 0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x080c, 0xa007, 0x87ff, - 0x1198, 0x00ce, 0x0804, 0x9a05, 0x2c78, 0x600c, 0x2060, 0x0804, - 0x9a05, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, - 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004, - 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, - 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, - 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660, - 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, - 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, - 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, - 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, - 0x9086, 0x0040, 0x090c, 0x8a84, 0x9085, 0x0001, 0x0020, 0x2c78, - 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, - 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, - 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, - 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9b50, 0x6010, 0x00b6, - 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0x9b4b, 0x7024, 0x9c06, - 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9b22, 0x080c, - 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, - 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, - 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, - 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, - 0xbf32, 0x1180, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1518, 0x080c, - 0xa995, 0x0400, 0x080c, 0x9a6a, 0x6824, 0xd084, 0x09b0, 0x6827, - 0x0001, 0x0898, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995, 0x0090, - 0x6014, 0x2048, 0x080c, 0xbd39, 0x0168, 0x6020, 0x9086, 0x0003, - 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, - 0x080c, 0xbf26, 0x080c, 0xc1af, 0x080c, 0xa007, 0x080c, 0x9940, - 0x00ce, 0x0804, 0x9acb, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9acb, - 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xd781, - 0x0c08, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0200, 0x7007, 0x0014, - 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000, - 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, - 0x7878, 0x080c, 0x95d9, 0x00de, 0x0005, 0x080c, 0x911d, 0x700b, - 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, - 0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, - 0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, - 0x95d9, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, - 0x080c, 0xc3bc, 0x00de, 0x1904, 0x9bfe, 0x080c, 0x90d2, 0x7003, - 0x1300, 0x782c, 0x080c, 0x9d04, 0x2068, 0x6820, 0x9086, 0x0003, - 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0x9f54, 0x11d8, 0x9286, - 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, - 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, - 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, - 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, - 0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0x9f54, 0x1130, - 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, - 0x181e, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, - 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, - 0x001e, 0x00de, 0x080c, 0x95d9, 0x00be, 0x0005, 0x781b, 0x0001, - 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, - 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, - 0x9c79, 0x9186, 0x0005, 0x0904, 0x9c61, 0x9186, 0x0004, 0x05d8, - 0x9186, 0x0008, 0x0904, 0x9c6a, 0x7807, 0x0037, 0x782f, 0x0003, - 0x7817, 0x1700, 0x080c, 0x9ce1, 0x0005, 0x080c, 0x9ca2, 0x00d6, - 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0x9c42, - 0x9c4d, 0x9c44, 0x9c4d, 0x9c49, 0x9c42, 0x9c42, 0x9c4d, 0x9c4d, - 0x9c4d, 0x9c4d, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c4d, - 0x9c42, 0x9c4d, 0x080c, 0x0e02, 0x6824, 0xd0e4, 0x0110, 0xd0cc, - 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, - 0x7026, 0x0804, 0x9c9b, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c, - 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, - 0x04d0, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, - 0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, - 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, - 0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, - 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, - 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, - 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, - 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, - 0x0804, 0x95d9, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, - 0x911d, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, - 0x7810, 0x2058, 0xb8a0, 0x080c, 0x9f54, 0x1118, 0x9092, 0x007e, - 0x0268, 0x00d6, 0x2069, 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, - 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, - 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, - 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, - 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, - 0x0005, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, - 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c, 0x90c9, - 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, - 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, - 0x60c3, 0x0010, 0x0804, 0x95d9, 0x00e6, 0x2071, 0x0240, 0x0006, - 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120, - 0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, - 0x0005, 0x080c, 0x9114, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, - 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0021, 0x60c3, 0x0000, - 0x0804, 0x95d9, 0x00d6, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x0300, - 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, - 0x700e, 0x7013, 0x0819, 0x080c, 0x95c7, 0x721a, 0x2f10, 0x7222, - 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, - 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x29fe, - 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, - 0x95fc, 0x080c, 0x82d1, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, - 0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, - 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, - 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, - 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, - 0x080c, 0x9ddd, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, - 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, - 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, - 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, - 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, - 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, - 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, - 0x200c, 0xc1d5, 0x2102, 0x2009, 0x198d, 0x210c, 0x009e, 0x918d, - 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, - 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, - 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, - 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, - 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, - 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, - 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, - 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, - 0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, - 0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, - 0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, - 0xa83e, 0x2900, 0xa85a, 0xa813, 0x1ec0, 0x080c, 0x865e, 0x0126, - 0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x009e, 0x00de, 0x0005, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, - 0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff, - 0x0904, 0x9eb4, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, - 0x9005, 0x0904, 0x9e86, 0x080c, 0x9605, 0x68c3, 0x0000, 0x080c, - 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, - 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c, - 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, - 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, - 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, + 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf56, 0x1118, + 0x080c, 0xa9a7, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, + 0x0016, 0x0036, 0x0086, 0x080c, 0xc044, 0x080c, 0xdae1, 0x080c, + 0x6a22, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf39, 0x080c, 0xa01c, + 0x080c, 0x9955, 0x00ce, 0x0804, 0x87ab, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x87ab, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, + 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xdae1, 0x080c, 0xd7e2, + 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa9a7, 0x6020, 0x9086, + 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, + 0x8813, 0x9086, 0x008b, 0x0904, 0x8813, 0x0840, 0x6020, 0x9086, + 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, + 0x9086, 0x008b, 0x09b0, 0x0804, 0x8826, 0x00b6, 0x00a6, 0x0096, + 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, + 0x905d, 0x0904, 0x88fd, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, + 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, + 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, + 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, + 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, + 0x080c, 0x62d6, 0x0904, 0x88f9, 0x7624, 0x86ff, 0x0904, 0x88e8, + 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0560, 0x080c, 0x82d9, 0x080c, 0x961a, 0x68c3, + 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, + 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, + 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x080c, 0xa01c, 0x00ce, 0x0048, 0x00de, + 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x88a0, + 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804, + 0x88a0, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, + 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, + 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8967, 0x600c, 0x0006, + 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, + 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x667f, 0x1520, + 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, + 0xbd4c, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xbf56, + 0x1118, 0x080c, 0xa9a7, 0x0060, 0x080c, 0x667f, 0x1168, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, + 0x080c, 0xa01c, 0x080c, 0x9955, 0x000e, 0x0804, 0x890b, 0x7e16, + 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x080c, 0xa9a7, + 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, + 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, + 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, + 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, + 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a14, 0xb854, 0x0006, + 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, + 0x62d6, 0x0904, 0x8a11, 0x7e24, 0x86ff, 0x0904, 0x8a04, 0x9680, + 0x0005, 0x2004, 0x9906, 0x1904, 0x8a04, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0904, 0x89fb, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, + 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, + 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0, 0xb83c, + 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, + 0xa01c, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, + 0x630a, 0x00ce, 0x0804, 0x89a7, 0x89ff, 0x0138, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804, + 0x89a7, 0x000e, 0x0804, 0x899b, 0x781e, 0x781a, 0x00de, 0x00ce, + 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, + 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, + 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148, 0x9080, + 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, + 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, + 0x00ce, 0x04b8, 0x080c, 0x961a, 0x78c3, 0x0000, 0x080c, 0x9a7f, + 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, + 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, + 0x9a7f, 0x003e, 0x080c, 0x62d6, 0x00c6, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fea, 0x00ce, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0xc044, 0x080c, 0x6a22, 0x080c, + 0x9955, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, + 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, + 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa0, 0x8aa4, + 0x8ac2, 0x8aeb, 0x8b29, 0x8aa0, 0x8abb, 0x8a9e, 0x080c, 0x0df6, + 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, + 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, + 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, + 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, + 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc, + 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, + 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x8b8f, + 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b8f, 0x0c80, 0xc2ec, 0x2202, + 0x080c, 0x8c6c, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, + 0x1160, 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, + 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, + 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, + 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, + 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc, 0xb802, 0x080c, + 0x9955, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, + 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, + 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9955, 0x600c, 0x9015, + 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, + 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, + 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4c, 0x8b4e, + 0x8b72, 0x8b4a, 0x080c, 0x0df6, 0x00de, 0x0005, 0x00c6, 0x6840, + 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, + 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, + 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, + 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, + 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, + 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, + 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, + 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, + 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x8c6c, + 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, + 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8baf, 0x8c54, 0x8c54, + 0x8c54, 0x8c54, 0x8c56, 0x8c54, 0x8bad, 0x080c, 0x0df6, 0x6820, + 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0150, + 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce, + 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, + 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x00b6, + 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3e, 0xb84c, 0x900d, + 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, + 0x0904, 0x8c3e, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3e, 0x2058, + 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, + 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fc1, 0x0904, 0x8c3e, + 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880, + 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318, + 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff, + 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbab0, + 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x923f, 0x2069, + 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26, + 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, + 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be, + 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001, + 0x6822, 0x682b, 0x0000, 0x080c, 0x62d6, 0x080c, 0x9e16, 0x00ee, + 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c, + 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, + 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, + 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19c2, + 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014, 0xd2e4, + 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9e, 0x2069, 0x19c2, 0x2001, + 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0, 0x6a04, + 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1b0a, 0x1158, 0x012e, 0x080c, 0x9477, 0x00de, 0x00fe, 0x0005, + 0xc1c4, 0x2102, 0x080c, 0x7246, 0x08f8, 0x012e, 0x6843, 0x0000, + 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0, + 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c64, 0x6a30, 0x9296, 0x0000, + 0x0950, 0x0804, 0x8c64, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, + 0x8cd7, 0x8cdc, 0x916f, 0x9208, 0x8cdc, 0x916f, 0x9208, 0x8cd7, + 0x8cdc, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x080c, + 0x8a83, 0x080c, 0x8b8f, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, + 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, + 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x6110, + 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, + 0x1a04, 0x8d48, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee3, 0x8f1e, + 0x8f47, 0x9000, 0x9021, 0x9027, 0x9034, 0x903c, 0x9048, 0x904e, + 0x905f, 0x904e, 0x90b6, 0x903c, 0x90c2, 0x90c8, 0x9048, 0x90c8, + 0x90d4, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, + 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x9768, 0x978b, 0x979c, 0x97bc, + 0x97ee, 0x9034, 0x8d46, 0x9034, 0x904e, 0x8d46, 0x8f47, 0x9000, + 0x8d46, 0x9b76, 0x904e, 0x8d46, 0x9b92, 0x904e, 0x8d46, 0x9048, + 0x8edd, 0x8d69, 0x8d46, 0x9bae, 0x9c1b, 0x9cf6, 0x8d46, 0x9d03, + 0x9031, 0x9d2e, 0x8d46, 0x97f8, 0x9d5b, 0x8d46, 0x080c, 0x0df6, + 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d67, 0x8d67, 0x8d67, + 0x8da1, 0x8e4d, 0x8e58, 0x8d67, 0x8d67, 0x8d67, 0x8eb2, 0x8ebe, + 0x8dbc, 0x8d67, 0x8dd7, 0x8e0b, 0x9edd, 0x9f22, 0x904e, 0x080c, + 0x0df6, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x0026, 0x0036, 0x7814, + 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, + 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, + 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, + 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95ee, 0x003e, 0x002e, + 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x080c, 0x9f69, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, + 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x7003, 0x0500, 0x7814, + 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, + 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, + 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7, + 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, + 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, + 0x60c3, 0x0010, 0x080c, 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90e7, 0x20e9, 0x0000, + 0x2001, 0x197e, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, + 0x21e5, 0x080c, 0xcac3, 0x9006, 0x080c, 0x21e5, 0x001e, 0xa804, + 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95ee, 0x012e, + 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, + 0x080c, 0x9132, 0x20e9, 0x0000, 0x2001, 0x197e, 0x2003, 0x0000, + 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x080c, 0xcac3, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, + 0x080c, 0x0fe9, 0x080c, 0x95ee, 0x012e, 0x009e, 0x00de, 0x0005, + 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, + 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90e7, 0x7003, + 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x00d6, 0x00e6, 0x080c, 0x9132, 0x7814, 0x9084, 0xff00, 0x2073, + 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, + 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, + 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, + 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e78, 0x2069, 0x1801, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e81, 0x9096, 0xdf00, + 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, + 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9, 0x001a, + 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, + 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, + 0x8e70, 0x1f04, 0x8e98, 0x60c3, 0x004c, 0x080c, 0x95ee, 0x00ee, + 0x00de, 0x0005, 0x080c, 0x90e7, 0x7003, 0x6300, 0x7007, 0x0028, + 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6, 0x0026, + 0x0016, 0x080c, 0x9132, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, + 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800, + 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, + 0x95ee, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, 0x2004, + 0x609a, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5200, 0x2069, + 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26a0, + 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, + 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, + 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f69, 0x1120, 0xb8a0, + 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, 0x2001, + 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, + 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95ee, 0x080c, 0x90e7, + 0x7003, 0x0500, 0x080c, 0x9f69, 0x1120, 0xb8a0, 0x9082, 0x007f, + 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f, 0x2004, + 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x700e, + 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, + 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95ee, 0x080c, + 0x90e7, 0x9006, 0x080c, 0x6693, 0xb8a0, 0x9086, 0x007e, 0x1170, + 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, + 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, + 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, + 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fc8, 0x00d6, 0x2069, + 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800, 0x700a, + 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f, 0x2710, + 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804, + 0x700e, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100, 0x080c, 0x717e, + 0x1128, 0x78e3, 0x0000, 0x080c, 0x26e1, 0x78e2, 0x00fe, 0x6808, + 0x080c, 0x717e, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, + 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, + 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, + 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, + 0x9ddd, 0x2069, 0x194e, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, + 0x080c, 0x54df, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a0, + 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016, 0x2009, 0x0002, + 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x26e1, + 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x1946, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, + 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x025a, 0x4003, 0x080c, 0x9ddd, 0x20a1, 0x024e, 0x20a9, + 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3, 0x0074, 0x0804, 0x95ee, + 0x080c, 0x90e7, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, + 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x185b, 0x7904, 0x00fe, + 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, 0x9085, + 0x0002, 0x00d6, 0x0804, 0x9097, 0x7026, 0x60c3, 0x0014, 0x0804, + 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5000, 0x0804, 0x8f69, 0x080c, + 0x90e7, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, + 0x95ee, 0x080c, 0x9129, 0x0010, 0x080c, 0x9132, 0x7003, 0x0200, + 0x60c3, 0x0004, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100, + 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8f69, 0x080c, 0x9132, + 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, + 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6, + 0x080c, 0x9132, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, + 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, + 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, + 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, + 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x185b, 0x7904, + 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, + 0x2009, 0x187d, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, + 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbabc, 0xd28c, + 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, + 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, + 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0x95ee, 0x080c, 0x9132, + 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, + 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8ee7, + 0x080c, 0x9132, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, + 0x60c3, 0x0008, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100, + 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, + 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, + 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, + 0x003e, 0x00de, 0x080c, 0x95dc, 0x721a, 0x9f95, 0x0000, 0x7222, + 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, + 0x9df2, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, + 0x6878, 0x700a, 0x687c, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, + 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, + 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, + 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, + 0x2021, 0x0100, 0x080c, 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x6878, 0x700a, + 0x687c, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, + 0x00de, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x95dc, 0x721a, 0x7a08, + 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c, + 0x0df6, 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, + 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x0005, 0x91a0, 0x91af, 0x91ba, 0x919e, 0x919e, 0x919e, 0x91a0, + 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x080c, 0x0df6, + 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0x95ee, 0x0431, + 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, + 0x0804, 0x95ee, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, + 0x0004, 0x0804, 0x95ee, 0x0026, 0x080c, 0x9df2, 0xb810, 0x9085, + 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, + 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, 0x9102, 0x0026, 0x080c, + 0x9df2, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7a20, + 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164, 0x0026, + 0x080c, 0x9df2, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, + 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, + 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0df6, 0x908a, + 0x0054, 0x1a0c, 0x0df6, 0x7910, 0x2158, 0xb9b0, 0x2061, 0x0100, + 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x0005, 0x923f, 0x9306, 0x92d9, 0x9428, 0x923d, 0x923d, + 0x923d, 0x923d, 0x923d, 0x923d, 0x923d, 0x993c, 0x9941, 0x9946, + 0x994b, 0x923d, 0x9d3a, 0x923d, 0x9937, 0x080c, 0x0df6, 0x0096, + 0x780b, 0xffff, 0x080c, 0x92aa, 0x7914, 0x2148, 0xa978, 0x7956, + 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, + 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, + 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, + 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, + 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, + 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x1792, 0x0010, + 0x080c, 0x1651, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, + 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, + 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, + 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, + 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001, 0x19dd, 0x2003, 0x0009, + 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8bc, 0xd084, + 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1aa0, + 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, + 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, + 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a78, 0x720a, + 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, + 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, + 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, + 0x009e, 0x00de, 0x0804, 0x95ee, 0x6813, 0x0008, 0xb810, 0x9085, + 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, + 0x687c, 0x700e, 0x7013, 0x0889, 0x080c, 0x95dc, 0x721a, 0x7a08, + 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, + 0x080c, 0x9406, 0x7814, 0x2048, 0x080c, 0xbd4c, 0x1130, 0x7814, + 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, + 0x00de, 0x0005, 0x9324, 0x938d, 0x939d, 0x93c3, 0x93cf, 0x93e0, + 0x93e8, 0x9322, 0x080c, 0x0df6, 0x0016, 0x0036, 0xa97c, 0x918c, + 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, + 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, + 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804, 0x95ee, 0xc3e5, 0x0c88, + 0x9186, 0x0001, 0x190c, 0x0df6, 0xaba8, 0x7824, 0xd0cc, 0x1904, + 0x938a, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, + 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, + 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, + 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, + 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, + 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, + 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, + 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, + 0x0804, 0x95ee, 0xc3e5, 0x0804, 0x9349, 0x2011, 0x0008, 0x2001, + 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, + 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, + 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, + 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, + 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, + 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, + 0x0032, 0x0804, 0x95ee, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, + 0x7216, 0x60c3, 0x0018, 0x0804, 0x95ee, 0x0cd0, 0xc2e5, 0x2011, + 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, + 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0x95ee, + 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, + 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, + 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, + 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7824, 0xd0cc, 0x1168, + 0x7013, 0x0898, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, + 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, + 0x9438, 0x9438, 0x943a, 0x9438, 0x9438, 0x9438, 0x9454, 0x9438, + 0x080c, 0x0df6, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, + 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b, 0x6804, 0xd0bc, 0x0130, + 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, + 0x60c3, 0x0001, 0x0804, 0x95ee, 0x2009, 0x0003, 0x0019, 0x7033, + 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9df2, 0x001e, 0xb810, 0x9085, + 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a78, 0x720a, + 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, + 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, + 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, + 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, + 0xba14, 0x7378, 0x747c, 0x7820, 0x90be, 0x0006, 0x0904, 0x954b, + 0x90be, 0x000a, 0x1904, 0x9507, 0xb8b0, 0x609e, 0x7814, 0x2048, + 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, + 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, + 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, + 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, + 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb8b0, 0x609e, + 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, + 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, + 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, + 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, + 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0x080c, 0x9dd7, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, + 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x82de, 0x003e, 0x004e, + 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, + 0x9086, 0x0040, 0x0904, 0x9587, 0x9185, 0x0100, 0x6062, 0x6266, + 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, + 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, + 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e, 0x080c, 0x9dd7, 0x2009, + 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, + 0x080c, 0x82de, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, + 0x009e, 0x00be, 0x0005, 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x0904, 0x95a3, 0x9185, 0x0100, 0x6062, 0x6266, + 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, + 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, + 0x6086, 0x7808, 0x6082, 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, + 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, + 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xbab0, 0x629e, 0x080c, 0x9db4, 0x0804, 0x9537, 0xb8bc, + 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, + 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, + 0x646e, 0x6073, 0x0829, 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, + 0x0000, 0x0804, 0x951a, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, + 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, + 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, + 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, + 0x6082, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, + 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, + 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, 0x9dd7, 0x0804, 0x9537, + 0x080c, 0x9db4, 0x0804, 0x9537, 0x7a10, 0x00b6, 0x2258, 0xba8c, + 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, + 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d0, 0x0005, 0x0016, 0x2001, + 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, + 0x080c, 0x82d0, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, + 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001, 0x19cb, 0x2003, 0x0000, + 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, + 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, + 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, + 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, + 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, + 0x080c, 0x717e, 0x11c0, 0x2001, 0x19de, 0x2004, 0x9005, 0x15d0, + 0x080c, 0x7246, 0x1160, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, + 0x6024, 0xd084, 0x090c, 0x0df6, 0x080c, 0x82d0, 0x0458, 0x00c6, + 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, + 0x080c, 0x2b7f, 0x00c6, 0x2061, 0x19c2, 0x6128, 0x9192, 0x0008, + 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, + 0x82d0, 0x080c, 0x9611, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, + 0x080c, 0xdbf0, 0x080c, 0x82d9, 0x2009, 0x0014, 0x080c, 0xa068, + 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, + 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19c2, 0x6128, + 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x82d0, + 0x080c, 0x5cee, 0x2009, 0x185a, 0x2114, 0x8210, 0x220a, 0x0c10, + 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x82e6, + 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904, 0x970a, 0x2061, 0x0100, + 0x2069, 0x0140, 0x080c, 0x717e, 0x1190, 0x0036, 0x2019, 0x0002, + 0x080c, 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009, + 0x004a, 0x080c, 0xa068, 0x080c, 0x7246, 0x0804, 0x970a, 0x6904, + 0xd1f4, 0x0904, 0x9711, 0x080c, 0x2b7f, 0x00c6, 0x703c, 0x9065, + 0x090c, 0x0df6, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1568, 0x61c8, + 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0520, + 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x1550, + 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110, 0x080c, 0x2ab1, 0x6014, + 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060, 0x2009, + 0x0049, 0x080c, 0xa068, 0x0070, 0x0036, 0x2019, 0x0001, 0x080c, + 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009, 0x004a, + 0x080c, 0xa068, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, + 0x0005, 0xd1ec, 0x1904, 0x96c3, 0x0804, 0x96c5, 0x0026, 0x00e6, + 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, 0x01a8, + 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, + 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0030, 0x7014, + 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, + 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, + 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19c2, + 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, + 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, + 0x009e, 0x080c, 0x64d5, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, + 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, + 0x080c, 0x90e7, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, + 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, + 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, + 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, + 0x002c, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x0f00, 0x7808, + 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, + 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0156, 0x080c, 0x9132, 0x7003, + 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, + 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, 0x2376, 0x8e70, 0x2276, + 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x97ad, 0x60c3, + 0x001c, 0x015e, 0x0804, 0x95ee, 0x0016, 0x0026, 0x080c, 0x910e, + 0x080c, 0x9120, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, + 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, + 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, + 0x95ee, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, + 0x9ddd, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x90e7, + 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x0016, 0x0026, 0x080c, 0x90e7, 0x20e9, 0x0000, 0x20a1, 0x024c, + 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, + 0x4003, 0x8003, 0x60c2, 0x080c, 0x95ee, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, + 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xbf56, 0x1110, 0x080c, + 0xa9a7, 0x600c, 0x0006, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, + 0x9955, 0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, + 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, + 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, + 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, + 0x961a, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x82d9, 0x00c6, 0x2061, + 0x0100, 0x080c, 0x9df6, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, + 0x0013, 0x080c, 0xa068, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, + 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, + 0x82d9, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, + 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c98, 0x080c, 0x8259, 0x20a9, + 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, + 0x7804, 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd084, 0x0118, + 0x6827, 0x0001, 0x0010, 0x1f04, 0x9893, 0x7804, 0x9084, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904, 0x9918, 0x9386, 0x0002, + 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0x9918, 0x68af, 0x95f5, + 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, + 0x0008, 0x080c, 0x82e6, 0x080c, 0x1e30, 0x2001, 0x0032, 0x6920, + 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, + 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0x98f2, 0x7804, 0x9084, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x6827, + 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009, 0x0049, 0x080c, 0xa068, + 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, + 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c, + 0x92aa, 0x7047, 0x1000, 0x0098, 0x080c, 0x92aa, 0x7047, 0x4000, + 0x0070, 0x080c, 0x92aa, 0x7047, 0x2000, 0x0048, 0x080c, 0x92aa, + 0x7047, 0x0400, 0x0020, 0x080c, 0x92aa, 0x7047, 0x0200, 0x7854, + 0x7032, 0x60c3, 0x0020, 0x0804, 0x95ee, 0x00e6, 0x2071, 0x19c2, + 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0904, 0x99fa, 0x8cff, 0x0904, 0x99fa, 0x6020, 0x9086, + 0x0006, 0x1904, 0x99f5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, + 0x99f5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0x99f5, + 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x99f5, 0x7024, 0x9c06, + 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, + 0x0148, 0x6827, 0x0001, 0x080c, 0x82d9, 0x080c, 0x9a7f, 0x7027, + 0x0000, 0x0428, 0x080c, 0x82d9, 0x6820, 0xd0b4, 0x0110, 0x68a7, + 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014, + 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, + 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xbd4c, + 0x0110, 0x080c, 0xd7e2, 0x009e, 0x080c, 0xa01c, 0x080c, 0x9955, + 0x88ff, 0x1190, 0x00ce, 0x0804, 0x9970, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x9970, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, + 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a6e, 0x6020, 0x9086, 0x0006, + 0x1904, 0x9a69, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0x9a69, + 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106, + 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, + 0x98b1, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, + 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, - 0x2678, 0x600f, 0x0000, 0x080c, 0xbf32, 0x1180, 0x080c, 0x30d4, - 0x080c, 0xbf43, 0x1518, 0x080c, 0xa995, 0x0400, 0x080c, 0x9a6a, - 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xbf43, - 0x1118, 0x080c, 0xa995, 0x0090, 0x6014, 0x2048, 0x080c, 0xbd39, - 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, - 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x080c, 0xc1af, - 0x080c, 0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x9e37, 0x2c78, - 0x600c, 0x2060, 0x0804, 0x9e37, 0x700f, 0x0000, 0x700b, 0x0000, - 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xd781, 0x08f0, - 0x00d6, 0x0156, 0x080c, 0x911d, 0x7a14, 0x82ff, 0x0138, 0x7003, - 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, - 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, - 0x1110, 0xc38d, 0x0060, 0x080c, 0x717f, 0x1110, 0xc3ad, 0x0008, - 0xc3a5, 0x6ad8, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, - 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, - 0x2019, 0x1841, 0x2071, 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, - 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x9efc, 0x60c3, 0x0020, - 0x080c, 0x95d9, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x911d, - 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, - 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, - 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x1998, - 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, - 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, - 0x7022, 0x2001, 0x181f, 0x2004, 0x7026, 0x0030, 0x2001, 0x1817, - 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, - 0x001c, 0x015e, 0x0804, 0x95d9, 0x0006, 0x2001, 0x1836, 0x2004, - 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, - 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c, - 0x989c, 0x003e, 0x0005, 0x2071, 0x188b, 0x7000, 0x9005, 0x0140, - 0x2001, 0x0976, 0x2071, 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0, - 0x2071, 0x1800, 0x7070, 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6, - 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0010, - 0x0608, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, - 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, - 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, - 0x1230, 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, - 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550, - 0x9582, 0x0010, 0x0600, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, - 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, - 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, - 0x7064, 0x9502, 0x1228, 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005, - 0x7057, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, - 0x0e02, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a0c, 0x0e02, 0x9006, - 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, - 0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, - 0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x2061, 0x1800, 0x6050, - 0x8000, 0x6052, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, - 0x8000, 0x0016, 0x080c, 0x8b90, 0x001e, 0x012e, 0x0cb0, 0x0006, - 0x6000, 0x9086, 0x0000, 0x01c0, 0x601c, 0xd084, 0x190c, 0x1938, - 0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x1960, 0x2004, 0x0006, - 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xda33, - 0x6043, 0x0000, 0x6013, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, - 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0001, 0x0608, + 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0110, + 0x080c, 0xd7e2, 0x080c, 0xa01c, 0x87ff, 0x1198, 0x00ce, 0x0804, + 0x9a1a, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9a1a, 0x9006, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, + 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, + 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540, + 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, + 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, + 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, + 0x8a83, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, + 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678, + 0x8cff, 0x0904, 0x9b65, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x9206, 0x1904, 0x9b60, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0904, 0x9b37, 0x080c, 0x961a, 0x68c3, 0x0000, + 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, + 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, + 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xbf45, 0x1180, 0x080c, + 0x30be, 0x080c, 0xbf56, 0x1518, 0x080c, 0xa9a7, 0x0400, 0x080c, + 0x9a7f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, + 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0090, 0x6014, 0x2048, 0x080c, + 0xbd4c, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, + 0xc1c2, 0x080c, 0xa01c, 0x080c, 0x9955, 0x00ce, 0x0804, 0x9ae0, + 0x2c78, 0x600c, 0x2060, 0x0804, 0x9ae0, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0006, 0x1d20, 0x080c, 0xd7e2, 0x0c08, 0x00d6, 0x080c, + 0x9132, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, + 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, + 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0x95ee, + 0x00de, 0x0005, 0x080c, 0x9132, 0x700b, 0x0800, 0x7814, 0x9084, + 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, + 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084, + 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0x95ee, 0x00b6, 0x00d6, + 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xc3cf, 0x00de, + 0x1904, 0x9c13, 0x080c, 0x90e7, 0x7003, 0x1300, 0x782c, 0x080c, + 0x9d19, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, + 0xbaa0, 0x080c, 0x9f69, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, + 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, + 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098, + 0x700e, 0x00a8, 0x080c, 0x9f69, 0x1130, 0x7810, 0x2058, 0xb8a0, + 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181e, 0x2d04, 0x700a, + 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, + 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, + 0x95ee, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, + 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, + 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0x9c8e, 0x9186, 0x0005, + 0x0904, 0x9c76, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904, + 0x9c7f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, + 0x9cf6, 0x0005, 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x6800, 0x0002, 0x9c57, 0x9c62, 0x9c59, 0x9c62, + 0x9c5e, 0x9c57, 0x9c57, 0x9c62, 0x9c62, 0x9c62, 0x9c62, 0x9c57, + 0x9c57, 0x9c57, 0x9c57, 0x9c57, 0x9c62, 0x9c57, 0x9c62, 0x080c, + 0x0df6, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, + 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0x9cb0, + 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0x9cb7, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, + 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6, + 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096, + 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103, + 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, + 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, + 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0x95ee, 0x00b6, + 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9132, 0x9006, 0x7003, + 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, + 0x080c, 0x9f69, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, + 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, + 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634, + 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, + 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, + 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9132, + 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, + 0x0008, 0x0804, 0x95ee, 0x080c, 0x90de, 0x7003, 0x1400, 0x7838, + 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, + 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, + 0x95ee, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, + 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848, + 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9129, + 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0x95ee, 0x0021, 0x60c3, 0x0000, 0x0804, 0x95ee, 0x00d6, + 0x080c, 0x9df2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0819, + 0x080c, 0x95dc, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071, + 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, + 0x60a7, 0x9575, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011, 0x0101, + 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0x9611, 0x080c, 0x82d0, + 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c, + 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, + 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, + 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, + 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0x9df2, 0x00de, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, + 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, + 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, + 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, + 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, + 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, + 0x2009, 0x198d, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, + 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0, + 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c, + 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009, + 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x00d6, 0x9290, + 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000, + 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020, + 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120, + 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096, + 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c, + 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003, + 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a, + 0xa813, 0x1ebc, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8c6c, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9ec9, 0x7024, + 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9e9b, + 0x080c, 0x961a, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, + 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x080c, 0xbf45, 0x1180, 0x080c, 0x30be, 0x080c, 0xbf56, 0x1518, + 0x080c, 0xa9a7, 0x0400, 0x080c, 0x9a7f, 0x6824, 0xd084, 0x09b0, + 0x6827, 0x0001, 0x0898, 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7, + 0x0090, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0168, 0x6020, 0x9086, + 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6a22, 0x080c, 0xbf39, 0x080c, 0xc1c2, 0x080c, 0xa01c, 0x080c, + 0x9955, 0x00ce, 0x0804, 0x9e4c, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x9e4c, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e, + 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1d08, 0x080c, 0xd7e2, 0x08f0, 0x00d6, 0x0156, 0x080c, + 0x9132, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, + 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, + 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, + 0x080c, 0x717e, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6ad8, 0xd29c, + 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x2011, 0x1848, 0x63f0, + 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x2071, + 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, + 0x0002, 0x1f04, 0x9f11, 0x60c3, 0x0020, 0x080c, 0x95ee, 0x015e, + 0x00de, 0x0005, 0x0156, 0x080c, 0x9132, 0x7a14, 0x82ff, 0x0168, + 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, + 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, + 0x001c, 0x700f, 0x0001, 0x2011, 0x1998, 0x2204, 0x8007, 0x701a, + 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082, + 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7022, 0x2001, 0x181f, + 0x2004, 0x7026, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, + 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, + 0x95ee, 0x0006, 0x2001, 0x1836, 0x2004, 0xd0ac, 0x000e, 0x0005, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x0005, + 0x2071, 0x188b, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, + 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0, 0x2071, 0x1800, 0x7070, + 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, + 0x2091, 0x8000, 0x7550, 0x9582, 0x0010, 0x0608, 0x7054, 0x2060, + 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, + 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, + 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085, + 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006, + 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550, 0x9582, 0x0010, 0x0600, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, - 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, - 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, - 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xa066, - 0xa06f, 0xa08a, 0xa0a5, 0xc48c, 0xc4a9, 0xc4c4, 0xa066, 0xa06f, - 0xa066, 0xa0c1, 0xa066, 0xa066, 0xa066, 0xa066, 0x9186, 0x0013, - 0x1128, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x0005, 0x0066, - 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013, 0x006e, 0x0005, - 0xa088, 0xa7f1, 0xa9dc, 0xa088, 0xaa6a, 0xa3a4, 0xa088, 0xa088, - 0xa773, 0xb035, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088, - 0x080c, 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, - 0x0013, 0x006e, 0x0005, 0xa0a3, 0xb6ff, 0xa0a3, 0xa0a3, 0xa0a3, - 0xa0a3, 0xa0a3, 0xa0a3, 0xb696, 0xb881, 0xa0a3, 0xb740, 0xb7bf, - 0xb740, 0xb7bf, 0xa0a3, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016, - 0x1a0c, 0x0e02, 0x6000, 0x0002, 0xa0bf, 0xb07c, 0xb144, 0xb274, - 0xb423, 0xa0bf, 0xa0bf, 0xa0bf, 0xb050, 0xb622, 0xb625, 0xa0bf, - 0xa0bf, 0xa0bf, 0xa0bf, 0xb654, 0xa0bf, 0xa0bf, 0xa0bf, 0x080c, - 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013, - 0x006e, 0x0005, 0xa0da, 0xa0da, 0xa11d, 0xa1bc, 0xa251, 0xa0da, - 0xa0da, 0xa0da, 0xa0dc, 0xa0da, 0xa0da, 0xa0da, 0xa0da, 0xa0da, - 0xa0da, 0xa0da, 0x080c, 0x0e02, 0x9186, 0x004c, 0x0588, 0x9186, - 0x0003, 0x190c, 0x0e02, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003, - 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5, - 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, 0xa836, 0xa83a, - 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, - 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, 0x1a82, 0x080c, - 0x865e, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x0005, - 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xa273, - 0x080c, 0xc45c, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, - 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110, - 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140, - 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028, - 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000, - 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118, - 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001, - 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xa184, - 0xa184, 0xa17f, 0xa182, 0xa184, 0xa17c, 0xa16f, 0xa16f, 0xa16f, - 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0x00fe, - 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, - 0x009e, 0x00de, 0x080c, 0x0e02, 0x080c, 0xac67, 0x0028, 0x080c, - 0xad98, 0x0010, 0x080c, 0xae86, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xa331, 0x0530, - 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, - 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12b4, 0x080c, - 0xa4df, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, - 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fd5, 0x2001, 0x002c, - 0x900e, 0x080c, 0xa397, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, - 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0e02, 0x91b2, 0x0050, - 0x1a0c, 0x0e02, 0x9182, 0x0047, 0x00ca, 0x2001, 0x0109, 0x2004, - 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, - 0x080c, 0x85b2, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000, - 0x9086, 0x0002, 0x1110, 0x0804, 0xa11d, 0x0005, 0xa1ef, 0xa1ef, - 0xa1f1, 0xa227, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa23a, 0x080c, - 0x0e02, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b40, 0x080c, 0x8c6d, - 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, - 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, - 0x900e, 0x080c, 0xa397, 0x080c, 0x9fd5, 0x00a8, 0x6003, 0x0002, - 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, - 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, - 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c, - 0x8b40, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120, - 0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5, - 0x0804, 0x8c6d, 0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459, - 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120, 0xa87b, - 0x0029, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5, 0x0804, - 0x8c6d, 0x9182, 0x0047, 0x0002, 0xa261, 0xa263, 0xa261, 0xa261, - 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, - 0xa263, 0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x1583, 0x6114, - 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6a23, 0x009e, - 0x00de, 0x0804, 0x9fd5, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, - 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1043, 0x000e, 0x090c, 0x0e02, - 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, - 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c, 0x9188, 0x0018, - 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205, - 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034, 0x1228, - 0x2011, 0x001f, 0x080c, 0xb906, 0x04c0, 0x2130, 0x2009, 0x0034, - 0x2011, 0x001f, 0x080c, 0xb906, 0x96b2, 0x0034, 0xb004, 0x904d, - 0x0110, 0x080c, 0x0ff5, 0x080c, 0x1043, 0x01d0, 0x8528, 0xa867, - 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, - 0x2608, 0x2011, 0x001b, 0x080c, 0xb906, 0x00b8, 0x96b2, 0x003c, - 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xb906, 0x0c18, - 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, - 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003, - 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804, - 0xa807, 0x0000, 0x0006, 0x080c, 0x6a23, 0x000e, 0x2048, 0x9005, - 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, - 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1043, 0x000e, - 0x090c, 0x0e02, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, - 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800, - 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009, - 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080, - 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, - 0x4003, 0x2003, 0x0000, 0x080c, 0x6a23, 0x009e, 0x00fe, 0x00de, - 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205, - 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98, - 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e, - 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486, - 0x003e, 0x1170, 0x0096, 0x080c, 0x1043, 0x2900, 0x009e, 0x05c0, - 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, - 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a, - 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400, - 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200, - 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086, - 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98, - 0x2310, 0x84ff, 0x0904, 0xa346, 0x0804, 0xa348, 0x9085, 0x0001, - 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, - 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6a16, - 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, - 0x9fd5, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0e02, 0x080c, 0x9fd5, - 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096, - 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196, - 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, - 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, - 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, - 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, - 0x0096, 0x080c, 0xbd3b, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, - 0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0x0096, 0x00d6, 0x0036, - 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8bf, - 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, - 0xa867, 0x0103, 0xab32, 0x080c, 0x9fd5, 0x003e, 0x00de, 0x009e, - 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xc444, - 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, - 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7c9, 0x9006, 0x001e, - 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, - 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, - 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, - 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, - 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, - 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fd5, 0x001e, 0x009e, - 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, - 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, - 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, - 0x6014, 0x2048, 0x080c, 0xb906, 0x080c, 0xbd3b, 0x0140, 0x6014, - 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, - 0x9fd5, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, - 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, - 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, - 0x9005, 0x0108, 0x2048, 0x080c, 0xb906, 0x009e, 0x080c, 0xbd3b, - 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, - 0xa867, 0x0103, 0x080c, 0x9fd5, 0x009e, 0x001e, 0x0005, 0x0086, - 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xa995, - 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, - 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, - 0x0000, 0x2041, 0x129a, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, - 0x0006, 0x080c, 0x1043, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, - 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, - 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x1140, - 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, - 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, - 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, - 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, - 0x080c, 0xc3bc, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, - 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, - 0x9fd5, 0x0020, 0x0039, 0x0010, 0x080c, 0xa5fe, 0x002e, 0x00de, - 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, - 0xa5e6, 0x918e, 0x0016, 0x1904, 0xa5fc, 0x700c, 0x908c, 0xff00, - 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xa5c0, 0x89ff, - 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5a3, 0x0804, 0xa5fa, - 0x6808, 0x9086, 0xffff, 0x1904, 0xa5e8, 0xa87c, 0x9084, 0x0060, - 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xa5e8, - 0x6824, 0xd084, 0x1904, 0xa5e8, 0xd0b4, 0x0158, 0x0016, 0x2001, - 0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, - 0xa5e8, 0x080c, 0xbf26, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, - 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, - 0x847f, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, - 0x1138, 0x00c6, 0x2d60, 0x080c, 0xba68, 0x00ce, 0x0804, 0xa5fa, - 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eac, 0x0010, 0x080c, - 0x625a, 0x00ce, 0x1904, 0xa5e8, 0x00c6, 0x2d60, 0x080c, 0x9fd5, - 0x00ce, 0x0804, 0xa5fa, 0x00c6, 0x080c, 0xa026, 0x0198, 0x6017, - 0x0000, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0003, 0x6904, - 0x00c6, 0x2d60, 0x080c, 0x9fd5, 0x00ce, 0x080c, 0xa053, 0x00ce, - 0x0804, 0xa5fa, 0x2001, 0x1962, 0x2004, 0x6842, 0x00ce, 0x04d0, - 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, - 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, - 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00, - 0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0, - 0x89ff, 0x090c, 0x0e02, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, - 0xa87b, 0x0003, 0x080c, 0x683d, 0x080c, 0xbf26, 0x080c, 0xa007, - 0x00de, 0x00ce, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x9186, 0x0015, - 0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, - 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda33, 0x080c, 0x8426, - 0x080c, 0x9fd5, 0x00ce, 0x080c, 0x9fd5, 0x0005, 0x0026, 0x0036, - 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1962, - 0x2004, 0x6842, 0x0804, 0xa678, 0x00c6, 0x2d60, 0x080c, 0xb967, - 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, - 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90, - 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, - 0x0e02, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, - 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, - 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, - 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, - 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, - 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, - 0x2001, 0x0005, 0x6832, 0x080c, 0xc0ae, 0x080c, 0x8b90, 0x0010, - 0x080c, 0x9fd5, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, - 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, - 0x00be, 0x9206, 0x1904, 0xa6e3, 0x700c, 0x6210, 0x00b6, 0x2258, - 0xba14, 0x00be, 0x9206, 0x1904, 0xa6e3, 0x6038, 0x2068, 0x6824, - 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xa6e3, 0x9286, - 0x0002, 0x0904, 0xa6e3, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, - 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, - 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, - 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, - 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, - 0x080c, 0xbd3b, 0x090c, 0x0e02, 0xa87b, 0x0003, 0x009e, 0x080c, - 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, - 0x1962, 0x2004, 0x7042, 0x080c, 0x9fd5, 0x002e, 0x00de, 0x00ee, - 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, - 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, - 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, - 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb00b, 0x002e, 0x003e, - 0x015e, 0x009e, 0x1904, 0xa752, 0x0096, 0x0156, 0x0036, 0x0026, - 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, - 0xb00b, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, - 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, - 0x00fe, 0x009e, 0x00be, 0x0804, 0xa3e0, 0x0096, 0x2048, 0xaa12, - 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, - 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c, 0xa4df, - 0x0130, 0x00fe, 0x009e, 0x080c, 0x9fd5, 0x00be, 0x0005, 0x080c, - 0xa995, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x30ab, 0x080c, 0xc459, - 0x00fe, 0x00c6, 0x080c, 0x9f7f, 0x2f00, 0x6012, 0x6017, 0x0000, - 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, - 0x080c, 0x62f5, 0x080c, 0x6321, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x00ce, 0x0804, 0xa725, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0e02, - 0x91b2, 0x0040, 0x1a04, 0xa7db, 0x0002, 0xa7c9, 0xa7c9, 0xa7bf, - 0xa7c9, 0xa7c9, 0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, - 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, - 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, - 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7c9, 0xa7c9, - 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bf, 0xa7bd, 0xa7bd, - 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9, - 0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, - 0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7bd, 0x080c, 0x0e02, 0x0066, - 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, 0x00be, 0x006e, - 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, - 0x8641, 0x0010, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c, - 0x8b90, 0x012e, 0x0005, 0x2600, 0x0002, 0xa7ef, 0xa7ef, 0xa7ef, - 0xa7c9, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7c9, 0xa7ef, - 0xa7c9, 0xa7ef, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0x080c, - 0x0e02, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013, - 0x0904, 0xa8c4, 0x91b6, 0x0027, 0x1904, 0xa86e, 0x080c, 0x8a84, - 0x6004, 0x080c, 0xbf32, 0x01b0, 0x080c, 0xbf43, 0x01a8, 0x908e, - 0x0021, 0x0904, 0xa86b, 0x908e, 0x0022, 0x1130, 0x080c, 0xa40c, - 0x0904, 0xa867, 0x0804, 0xa868, 0x908e, 0x003d, 0x0904, 0xa86b, - 0x0804, 0xa861, 0x080c, 0x30d4, 0x2001, 0x0007, 0x080c, 0x62f5, - 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xa995, 0x9186, - 0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285, 0x080c, 0x717f, - 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, - 0x080c, 0xda8f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, - 0x2019, 0x0028, 0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671, - 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xd53b, - 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc459, 0x0016, 0x080c, - 0xc1af, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x080c, 0x8b90, - 0x0030, 0x080c, 0xc1af, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, - 0x080c, 0xa995, 0x0cb0, 0x080c, 0xa9d1, 0x0c98, 0x9186, 0x0015, - 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a, 0x0d80, 0x6000, - 0x9086, 0x0002, 0x0904, 0xa9dc, 0x0c50, 0x9186, 0x0014, 0x1d38, - 0x080c, 0x8a84, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xa40c, - 0x09f0, 0x080c, 0x30ab, 0x080c, 0xc459, 0x080c, 0xbf32, 0x1198, - 0x080c, 0x30d4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, - 0xa995, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, 0x200c, 0xc185, - 0x2102, 0x0804, 0xa861, 0x080c, 0xbf43, 0x1120, 0x080c, 0xa995, - 0x0804, 0xa861, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, - 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee, - 0x0804, 0xa861, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, - 0x090c, 0xa995, 0x0804, 0xa861, 0x90b2, 0x0040, 0x1a04, 0xa97e, - 0x2008, 0x0002, 0xa90c, 0xa90d, 0xa910, 0xa913, 0xa916, 0xa923, - 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, - 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, - 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, - 0xa926, 0xa933, 0xa90a, 0xa935, 0xa933, 0xa90a, 0xa90a, 0xa90a, - 0xa90a, 0xa90a, 0xa933, 0xa933, 0xa90a, 0xa90a, 0xa90a, 0xa90a, - 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa965, 0xa933, 0xa90a, 0xa92f, - 0xa90a, 0xa90a, 0xa90a, 0xa930, 0xa90a, 0xa90a, 0xa90a, 0xa933, - 0xa95c, 0xa90a, 0x080c, 0x0e02, 0x0430, 0x2001, 0x000b, 0x0470, - 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6, - 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500, - 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x8a84, - 0x6003, 0x0005, 0x080c, 0xc45c, 0x080c, 0x8b90, 0x0070, 0x0018, - 0x0010, 0x080c, 0x62f5, 0x0804, 0xa976, 0x080c, 0x8a84, 0x080c, - 0xc45c, 0x6003, 0x0004, 0x080c, 0x8b90, 0x0005, 0x080c, 0x62f5, - 0x080c, 0x8a84, 0x6003, 0x0002, 0x0036, 0x2019, 0x1866, 0x2304, - 0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c, 0x0040, 0x8007, - 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, - 0x003e, 0x080c, 0x8b90, 0x0c08, 0x080c, 0x8a84, 0x080c, 0xc1af, - 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x08c0, 0x00e6, 0x00f6, 0x2071, - 0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee, 0x080c, - 0x8a84, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0838, 0x080c, 0x8a84, - 0x6003, 0x0002, 0x080c, 0xc45c, 0x0804, 0x8b90, 0x2600, 0x2008, - 0x0002, 0xa993, 0xa993, 0xa993, 0xa976, 0xa976, 0xa993, 0xa993, - 0xa993, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993, - 0xa993, 0xa993, 0xa993, 0x080c, 0x0e02, 0x00e6, 0x0096, 0x0026, - 0x0016, 0x080c, 0xbd3b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, - 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5276, - 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, - 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc320, 0x0090, 0xa868, - 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, - 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, - 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, - 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, - 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, - 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x6604, 0x96b6, - 0x004d, 0x1120, 0x080c, 0xc23f, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x0043, 0x1120, 0x080c, 0xc288, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x004b, 0x1120, 0x080c, 0xc2b4, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x0033, 0x1120, 0x080c, 0xc1d1, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x0028, 0x1120, 0x080c, 0xbf81, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x0029, 0x1120, 0x080c, 0xbfc2, 0x0804, 0xaa59, 0x6604, 0x96b6, - 0x001f, 0x1118, 0x080c, 0xa3b1, 0x04e0, 0x6604, 0x96b6, 0x0000, - 0x1118, 0x080c, 0xa6e9, 0x04a8, 0x6604, 0x96b6, 0x0022, 0x1118, - 0x080c, 0xa3ed, 0x0470, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, - 0xa4fd, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xa67e, - 0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xa425, 0x00c8, - 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa461, 0x0090, 0x6604, - 0x96b6, 0x0049, 0x1118, 0x080c, 0xa48c, 0x0058, 0x91b6, 0x0015, - 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, - 0xad3f, 0x00be, 0x0005, 0x080c, 0xa06e, 0x0cd8, 0xaa76, 0xaa84, - 0xaa76, 0xaac8, 0xaa76, 0xac67, 0xad4c, 0xaa76, 0xaa76, 0xad19, - 0xaa76, 0xad2d, 0x0096, 0x080c, 0x1583, 0x6014, 0x2048, 0xa800, - 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0xa001, 0xa001, - 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, - 0x62e1, 0x0804, 0x9fd5, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708c, - 0x9086, 0x0074, 0x1540, 0x080c, 0xd50c, 0x11b0, 0x6010, 0x00b6, - 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, - 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, - 0x30d4, 0x080c, 0x9fd5, 0x0088, 0x2001, 0x000a, 0x080c, 0x62f5, - 0x080c, 0x30d4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8641, - 0x080c, 0x8b90, 0x0010, 0x080c, 0xac52, 0x00ee, 0x0005, 0x00d6, - 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e1, 0x2069, 0x185b, - 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6321, 0x00de, 0x0005, - 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, 0x9086, 0x0074, - 0x1904, 0xac29, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, - 0x080c, 0xae91, 0x0804, 0xab8b, 0x00d6, 0x080c, 0x717f, 0x01a0, - 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xab2c, - 0x080c, 0x54f0, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, - 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, - 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, - 0x66ee, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, - 0x900e, 0x2011, 0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048, - 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, - 0xb9a0, 0x0016, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c, - 0x31a6, 0x00de, 0x0804, 0xac2c, 0x00de, 0x080c, 0xae86, 0x6010, - 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, - 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, - 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x0030, 0xa807, - 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, - 0x62f5, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x0804, 0xac2c, 0x080c, - 0xac3a, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, - 0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x08f8, 0x080c, 0xac30, - 0x0160, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0004, 0x080c, 0x6321, - 0x2001, 0x0007, 0x080c, 0x62f5, 0x08a0, 0x2001, 0x0004, 0x080c, - 0x62f5, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x080c, - 0x8b90, 0x0804, 0xac2c, 0xb85c, 0xd0e4, 0x01d0, 0x080c, 0xc151, - 0x080c, 0x717f, 0x0118, 0xd0dc, 0x1904, 0xab4d, 0x2011, 0x1836, - 0x2204, 0xc0ad, 0x2012, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100, - 0x78e3, 0x0000, 0x080c, 0x26e2, 0x78e2, 0x00fe, 0x0804, 0xab4d, - 0x080c, 0xc18e, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006, - 0x080c, 0xd666, 0x000e, 0x1904, 0xab4d, 0xc0b5, 0x2012, 0x2001, - 0x0006, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x00c6, 0x2001, - 0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, - 0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010, - 0x78ea, 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, - 0x00fe, 0x080c, 0x26b7, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266e, - 0x795a, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, - 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, - 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b7, - 0x00f6, 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c, - 0x266e, 0x795a, 0x00fe, 0x8108, 0x080c, 0x6344, 0x2b00, 0x00ce, - 0x1904, 0xab4d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, - 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, - 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001, - 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x0018, 0x080c, 0xa995, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, - 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, - 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xdae8, 0x0190, 0x2071, 0x0260, - 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, - 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, - 0x00ee, 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f5, 0x080c, - 0x54f0, 0x1120, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x30d4, - 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fd5, 0x00b6, - 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014, - 0x1904, 0xad10, 0x00d6, 0x080c, 0x717f, 0x01a0, 0x0026, 0x2011, - 0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xacc2, 0x080c, 0x54f0, - 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, - 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, - 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, - 0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, - 0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, - 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, - 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x00de, - 0x0804, 0xad14, 0x00de, 0x080c, 0x54f0, 0x1170, 0x6014, 0x9005, - 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, - 0x080c, 0x4bb5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, - 0x643f, 0x080c, 0xaab7, 0x00de, 0x080c, 0xaf57, 0x1588, 0x6010, - 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f5, - 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, - 0xc320, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, - 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, - 0x30d4, 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fd5, 0x0020, - 0x080c, 0xa995, 0x080c, 0xac52, 0x001e, 0x002e, 0x00ee, 0x00be, - 0x0005, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, - 0x0002, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, - 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2030, 0x2011, 0x1823, - 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, - 0x0007, 0x080c, 0x62f5, 0x0804, 0x9fd5, 0x0804, 0xac52, 0x0002, - 0xaa76, 0xad57, 0xaa76, 0xad98, 0xaa76, 0xae43, 0xad4c, 0xaa79, - 0xaa76, 0xae55, 0xaa76, 0xae65, 0x6604, 0x9686, 0x0003, 0x0904, - 0xac67, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005, 0x00b6, - 0x00d6, 0x00c6, 0x080c, 0xae75, 0x11a0, 0x9006, 0x080c, 0x62e1, - 0x080c, 0x30ab, 0x080c, 0xc459, 0x2001, 0x0002, 0x080c, 0x62f5, - 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x0418, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, - 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, - 0x601b, 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, - 0x908e, 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x30ab, - 0x080c, 0xc459, 0x080c, 0xac52, 0x00ce, 0x00de, 0x00be, 0x0005, - 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xae83, 0x00d6, 0x2069, - 0x1956, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, - 0x007e, 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de, - 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, - 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, - 0x080c, 0x8b90, 0x0804, 0xae13, 0x080c, 0xbd3b, 0x01b0, 0x6014, - 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, - 0x2001, 0x0002, 0x080c, 0xc37d, 0x00b0, 0x6014, 0x2048, 0xa864, - 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, - 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, - 0x1110, 0x9006, 0x0c38, 0x080c, 0xa995, 0x2009, 0x026e, 0x2134, - 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8, - 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, - 0x01b0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001, - 0x0004, 0x080c, 0x62f5, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, - 0x0010, 0x080c, 0xac52, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, - 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa864, - 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010, - 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, - 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, - 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3, 0x00ee, 0x0010, - 0x080c, 0x30ab, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f5, 0x04d9, - 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x0804, - 0x8b90, 0x080c, 0xa995, 0x0804, 0xac52, 0x0469, 0x1160, 0x2001, - 0x0008, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, - 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x00e9, 0x1160, 0x2001, - 0x000a, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, - 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2009, 0x026e, 0x2104, - 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, - 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, - 0x0016, 0x6110, 0x2158, 0x080c, 0x63b3, 0x001e, 0x00ce, 0x00be, - 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, - 0x2058, 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, - 0xaf29, 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c, - 0x66c6, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6, - 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, - 0x0001, 0x080c, 0x3076, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e8c, - 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, - 0x31a6, 0x8108, 0x1f04, 0xaec7, 0x015e, 0x00ce, 0x080c, 0xae86, - 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836, - 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, - 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102, - 0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181e, 0x206a, - 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x181f, 0x206a, 0x78ea, - 0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, - 0x182b, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26b7, - 0x080c, 0x717f, 0x0170, 0x2071, 0x0260, 0x2069, 0x195c, 0x7048, - 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, - 0xc151, 0x0040, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x30d4, - 0x080c, 0x9fd5, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, - 0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182b, - 0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, - 0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, - 0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x1148, - 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xb00b, - 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, - 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, - 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, - 0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, - 0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, - 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, - 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0, - 0x2071, 0x1800, 0x7250, 0x7070, 0x9202, 0x1a04, 0xafe3, 0x080c, - 0xd807, 0x0904, 0xafdc, 0x6720, 0x9786, 0x0007, 0x0904, 0xafdc, - 0x2500, 0x9c06, 0x0904, 0xafdc, 0x2400, 0x9c06, 0x05e8, 0x3e08, - 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004, - 0x1110, 0x080c, 0x1938, 0x9786, 0x000a, 0x0148, 0x080c, 0xbf43, - 0x1130, 0x00ce, 0x080c, 0xa995, 0x080c, 0xa007, 0x00e8, 0x6014, - 0x2048, 0x080c, 0xbd3b, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, - 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, - 0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c, - 0xbf26, 0x080c, 0xa007, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02, - 0x1210, 0x0804, 0xaf8a, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, - 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, - 0x080c, 0xd781, 0x0c30, 0x9786, 0x000a, 0x09e0, 0x0880, 0x220c, - 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xaff7, 0x9006, - 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, - 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, - 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, - 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, - 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, - 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, - 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x6004, 0x908a, 0x0053, - 0x1a0c, 0x0e02, 0x080c, 0xbf32, 0x0120, 0x080c, 0xbf43, 0x0168, - 0x0028, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x0138, 0x080c, 0x8a84, - 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xa995, 0x0cb0, + 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1228, + 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc8, + 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0df6, 0x2001, 0x1819, + 0x2004, 0x9c02, 0x1a0c, 0x0df6, 0x9006, 0x6006, 0x600a, 0x600e, + 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, + 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, + 0x603e, 0x6042, 0x2061, 0x1800, 0x6050, 0x8000, 0x6052, 0x9086, + 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x8b8f, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, + 0x01c0, 0x601c, 0xd084, 0x190c, 0x192c, 0x6017, 0x0000, 0x6023, + 0x0007, 0x2001, 0x1960, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, + 0x0208, 0x8004, 0x601a, 0x080c, 0xda94, 0x6043, 0x0000, 0x6013, + 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7550, 0x9582, 0x0001, 0x0608, 0x7054, 0x2060, 0x6000, + 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, + 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, + 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x6020, 0x9084, 0x000f, 0x0002, 0xa07b, 0xa084, 0xa09f, 0xa0ba, + 0xc4a1, 0xc4be, 0xc4d9, 0xa07b, 0xa084, 0xa07b, 0xa0d3, 0xa07b, + 0xa07b, 0xa07b, 0xa07b, 0x9186, 0x0013, 0x1128, 0x080c, 0x8a83, + 0x080c, 0x8b8f, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, + 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xa09d, 0xa803, 0xa9ee, + 0xa09d, 0xaa7c, 0xa3b6, 0xa09d, 0xa09d, 0xa785, 0xb041, 0xa09d, + 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0x080c, 0x0df6, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, + 0xa0b8, 0xb70e, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, + 0xb6a5, 0xb890, 0xa0b8, 0xb74f, 0xb7ce, 0xb74f, 0xb7ce, 0xa0b8, + 0x080c, 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000, + 0x0002, 0xa0d1, 0xb088, 0xb150, 0xb283, 0xb432, 0xa0d1, 0xa0d1, + 0xa0d1, 0xb05c, 0xb631, 0xb634, 0xa0d1, 0xa0d1, 0xa0d1, 0xa0d1, + 0xb663, 0x080c, 0x0df6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0df6, 0x0013, 0x006e, 0x0005, 0xa0ec, 0xa0ec, 0xa12f, 0xa1ce, + 0xa263, 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ee, 0xa0ec, 0xa0ec, 0xa0ec, + 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ec, 0x080c, 0x0df6, 0x9186, 0x004c, + 0x0588, 0x9186, 0x0003, 0x190c, 0x0df6, 0x0096, 0x601c, 0xc0ed, + 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, + 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, + 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, + 0x1a7e, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6c, + 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, + 0x080c, 0xa285, 0x080c, 0xc471, 0x6003, 0x0007, 0x0005, 0x00d6, + 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c, + 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, + 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, + 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, + 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, + 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, + 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, + 0x0002, 0xa196, 0xa196, 0xa191, 0xa194, 0xa196, 0xa18e, 0xa181, + 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, + 0xa181, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0df6, 0x080c, 0xac6e, + 0x0028, 0x080c, 0xad9f, 0x0010, 0x080c, 0xae8d, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, + 0xa343, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, + 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, + 0x12a8, 0x080c, 0xa4f1, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, + 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fea, + 0x2001, 0x002c, 0x900e, 0x080c, 0xa3a9, 0x0c70, 0x91b6, 0x0015, + 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0df6, + 0x91b2, 0x0050, 0x1a0c, 0x0df6, 0x9182, 0x0047, 0x00ca, 0x2001, + 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x080c, 0x85b1, 0x002e, 0x001e, 0x000e, 0x012e, + 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xa12f, 0x0005, + 0xa201, 0xa201, 0xa203, 0xa239, 0xa201, 0xa201, 0xa201, 0xa201, + 0xa24c, 0x080c, 0x0df6, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b3f, + 0x080c, 0x8c6c, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, + 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, + 0x2001, 0x0000, 0x900e, 0x080c, 0xa3a9, 0x080c, 0x9fea, 0x00a8, + 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, + 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, + 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, + 0x0005, 0x080c, 0x8b3f, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, + 0xbd4e, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x00de, + 0x080c, 0x9fea, 0x0804, 0x8c6c, 0x080c, 0x8b3f, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e, + 0x0120, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x00de, 0x080c, + 0x9fea, 0x0804, 0x8c6c, 0x9182, 0x0047, 0x0002, 0xa273, 0xa275, + 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, + 0xa273, 0xa273, 0xa275, 0x080c, 0x0df6, 0x00d6, 0x0096, 0x080c, + 0x1577, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, + 0x6a22, 0x009e, 0x00de, 0x0804, 0x9fea, 0x0026, 0x0036, 0x0056, + 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1037, 0x000e, + 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, + 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c, + 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, + 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, + 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xb915, 0x04c0, 0x2130, + 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xb915, 0x96b2, 0x0034, + 0xb004, 0x904d, 0x0110, 0x080c, 0x0fe9, 0x080c, 0x1037, 0x01d0, + 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, + 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xb915, 0x00b8, + 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, + 0xb915, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, + 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, + 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6a22, 0x000e, + 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, + 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, + 0x1037, 0x000e, 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, + 0x2079, 0x1800, 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, + 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, + 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6a22, 0x009e, + 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, + 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, + 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, + 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1037, 0x2900, + 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, + 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, + 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, + 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, + 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, + 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xa358, 0x0804, 0xa35a, + 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, + 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, + 0x080c, 0x6a15, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, + 0x1118, 0x080c, 0x9fea, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0df6, + 0x080c, 0x9fea, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, + 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, + 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, + 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, + 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, + 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, + 0x8211, 0x1db8, 0x0096, 0x080c, 0xbd4e, 0x0130, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea, 0x0096, + 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, + 0x2058, 0xb8bf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0x9fea, 0x003e, + 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, + 0x080c, 0xc459, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, + 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7db, + 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, + 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, + 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, + 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, + 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fea, + 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, + 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, + 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xb915, 0x080c, 0xbd4e, + 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, + 0x0103, 0x080c, 0x9fea, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096, + 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, + 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, + 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xb915, 0x009e, + 0x080c, 0xbd4e, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, + 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0x9fea, 0x009e, 0x001e, + 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, + 0x080c, 0xa9a7, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x0019, 0x0d08, 0x008e, + 0x0898, 0x0096, 0x0006, 0x080c, 0x1037, 0x000e, 0x01b0, 0xa8ab, + 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, + 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, + 0x080c, 0x1134, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, + 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, + 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, + 0x2009, 0x0035, 0x080c, 0xc3cf, 0x001e, 0x1158, 0x622c, 0x2268, + 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, + 0x0128, 0x080c, 0x9fea, 0x0020, 0x0039, 0x0010, 0x080c, 0xa610, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, + 0x0015, 0x0904, 0xa5f8, 0x918e, 0x0016, 0x1904, 0xa60e, 0x700c, + 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, + 0xa5d2, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5b5, + 0x0804, 0xa60c, 0x6808, 0x9086, 0xffff, 0x1904, 0xa5fa, 0xa87c, + 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, + 0x1904, 0xa5fa, 0x6824, 0xd084, 0x1904, 0xa5fa, 0xd0b4, 0x0158, + 0x0016, 0x2001, 0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, + 0x001e, 0x1a04, 0xa5fa, 0x080c, 0xbf39, 0x685c, 0xa882, 0xa87c, + 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, + 0x000a, 0x080c, 0x847e, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, + 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xba77, 0x00ce, + 0x0804, 0xa60c, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eab, + 0x0010, 0x080c, 0x6259, 0x00ce, 0x1904, 0xa5fa, 0x00c6, 0x2d60, + 0x080c, 0x9fea, 0x00ce, 0x0804, 0xa60c, 0x00c6, 0x080c, 0xa03b, + 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x6023, + 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x9fea, 0x00ce, 0x080c, + 0xa068, 0x00ce, 0x0804, 0xa60c, 0x2001, 0x1962, 0x2004, 0x6842, + 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, + 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, + 0x0003, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x00e8, 0x700c, + 0x9086, 0x2a00, 0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0, + 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0df6, 0x00c6, 0x00d6, 0x2d60, + 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x683c, 0x080c, 0xbf39, + 0x080c, 0xa01c, 0x00de, 0x00ce, 0x080c, 0x9fea, 0x009e, 0x0005, + 0x9186, 0x0015, 0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068, + 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda94, + 0x080c, 0x8425, 0x080c, 0x9fea, 0x00ce, 0x080c, 0x9fea, 0x0005, + 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, + 0x2001, 0x1962, 0x2004, 0x6842, 0x0804, 0xa68a, 0x00c6, 0x2d60, + 0x080c, 0xb976, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, + 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, + 0x89ff, 0x090c, 0x0df6, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, + 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, + 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, + 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, + 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, + 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, + 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xc0c1, 0x080c, + 0x8b8f, 0x0010, 0x080c, 0x9fea, 0x004e, 0x003e, 0x002e, 0x0005, + 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, + 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x700c, 0x6210, + 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x6038, + 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, + 0xa6f5, 0x9286, 0x0002, 0x0904, 0xa6f5, 0x9286, 0x0000, 0x05e8, + 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, + 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, + 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, + 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, + 0x0096, 0x2048, 0x080c, 0xbd4e, 0x090c, 0x0df6, 0xa87b, 0x0003, + 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x0030, 0x6038, + 0x2070, 0x2001, 0x1962, 0x2004, 0x7042, 0x080c, 0x9fea, 0x002e, + 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, + 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, + 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, + 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb017, + 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xa764, 0x0096, 0x0156, + 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, + 0x0004, 0x080c, 0xb017, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, + 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, + 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xa3f2, 0x0096, + 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, + 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, + 0x080c, 0xa4f1, 0x0130, 0x00fe, 0x009e, 0x080c, 0x9fea, 0x00be, + 0x0005, 0x080c, 0xa9a7, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x00fe, 0x00c6, 0x080c, 0x9f94, 0x2f00, 0x6012, + 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, + 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x6320, 0x080c, 0x8640, + 0x080c, 0x8b8f, 0x00ce, 0x0804, 0xa737, 0x2100, 0x91b2, 0x0053, + 0x1a0c, 0x0df6, 0x91b2, 0x0040, 0x1a04, 0xa7ed, 0x0002, 0xa7db, + 0xa7db, 0xa7d1, 0xa7db, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf, + 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7d1, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf, 0xa7cf, 0x080c, + 0x0df6, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, + 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, + 0x0118, 0x080c, 0x8640, 0x0010, 0x080c, 0x85f8, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x2600, 0x0002, 0xa801, + 0xa801, 0xa801, 0xa7db, 0xa7db, 0xa801, 0xa801, 0xa801, 0xa801, + 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa801, 0xa801, + 0xa801, 0x080c, 0x0df6, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0df6, + 0x91b6, 0x0013, 0x0904, 0xa8d6, 0x91b6, 0x0027, 0x1904, 0xa880, + 0x080c, 0x8a83, 0x6004, 0x080c, 0xbf45, 0x01b0, 0x080c, 0xbf56, + 0x01a8, 0x908e, 0x0021, 0x0904, 0xa87d, 0x908e, 0x0022, 0x1130, + 0x080c, 0xa41e, 0x0904, 0xa879, 0x0804, 0xa87a, 0x908e, 0x003d, + 0x0904, 0xa87d, 0x0804, 0xa873, 0x080c, 0x30be, 0x2001, 0x0007, + 0x080c, 0x62f4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, + 0xa9a7, 0x9186, 0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285, + 0x080c, 0x717e, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, + 0x0028, 0x2110, 0x080c, 0xdaf0, 0x002e, 0x003e, 0x0016, 0x0026, + 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x8782, 0x0076, 0x903e, + 0x080c, 0x8670, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc46e, + 0x0016, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190, + 0x080c, 0x8b8f, 0x0030, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, + 0x8b8f, 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x080c, 0xa9e3, 0x0c98, + 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f, + 0x0d80, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9ee, 0x0c50, 0x9186, + 0x0014, 0x1d38, 0x080c, 0x8a83, 0x6004, 0x908e, 0x0022, 0x1118, + 0x080c, 0xa41e, 0x09f0, 0x080c, 0x3095, 0x080c, 0xc46e, 0x080c, + 0xbf45, 0x1198, 0x080c, 0x30be, 0x6010, 0x00b6, 0x2058, 0xb9a0, + 0x00be, 0x080c, 0xa9a7, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, + 0x200c, 0xc185, 0x2102, 0x0804, 0xa873, 0x080c, 0xbf56, 0x1120, + 0x080c, 0xa9a7, 0x0804, 0xa873, 0x6004, 0x908e, 0x0032, 0x1160, + 0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424, + 0x00fe, 0x00ee, 0x0804, 0xa873, 0x6004, 0x908e, 0x0021, 0x0d40, + 0x908e, 0x0022, 0x090c, 0xa9a7, 0x0804, 0xa873, 0x90b2, 0x0040, + 0x1a04, 0xa990, 0x2008, 0x0002, 0xa91e, 0xa91f, 0xa922, 0xa925, + 0xa928, 0xa935, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa938, 0xa945, 0xa91c, 0xa947, 0xa945, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa945, 0xa945, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa977, 0xa945, + 0xa91c, 0xa941, 0xa91c, 0xa91c, 0xa91c, 0xa942, 0xa91c, 0xa91c, + 0xa91c, 0xa945, 0xa96e, 0xa91c, 0x080c, 0x0df6, 0x0430, 0x2001, + 0x000b, 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, + 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, + 0x0000, 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, + 0x080c, 0x8a83, 0x6003, 0x0005, 0x080c, 0xc471, 0x080c, 0x8b8f, + 0x0070, 0x0018, 0x0010, 0x080c, 0x62f4, 0x0804, 0xa988, 0x080c, + 0x8a83, 0x080c, 0xc471, 0x6003, 0x0004, 0x080c, 0x8b8f, 0x0005, + 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6003, 0x0002, 0x0036, 0x2019, + 0x1866, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c, + 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, + 0x9318, 0x631a, 0x003e, 0x080c, 0x8b8f, 0x0c08, 0x080c, 0x8a83, + 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x08c0, 0x00e6, + 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424, 0x00fe, + 0x00ee, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0838, + 0x080c, 0x8a83, 0x6003, 0x0002, 0x080c, 0xc471, 0x0804, 0x8b8f, + 0x2600, 0x2008, 0x0002, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa988, + 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa9a5, 0xa988, 0xa9a5, + 0xa988, 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0x080c, 0x0df6, 0x00e6, + 0x0096, 0x0026, 0x0016, 0x080c, 0xbd4e, 0x0568, 0x6014, 0x2048, + 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, + 0x080c, 0x5275, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, + 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc333, + 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, + 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, + 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, + 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, + 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0df6, + 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xc252, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xc29b, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xc2c7, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xc1e4, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xbf94, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xbfd5, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x001f, 0x1118, 0x080c, 0xa3c3, 0x04e0, 0x6604, + 0x96b6, 0x0000, 0x1118, 0x080c, 0xa6fb, 0x04a8, 0x6604, 0x96b6, + 0x0022, 0x1118, 0x080c, 0xa3ff, 0x0470, 0x6604, 0x96b6, 0x0035, + 0x1118, 0x080c, 0xa50f, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, + 0x080c, 0xa690, 0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, + 0xa437, 0x00c8, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa473, + 0x0090, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xa49e, 0x0058, + 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, + 0x00be, 0x0804, 0xad46, 0x00be, 0x0005, 0x080c, 0xa083, 0x0cd8, + 0xaa88, 0xaa96, 0xaa88, 0xaada, 0xaa88, 0xac6e, 0xad53, 0xaa88, + 0xaa88, 0xad20, 0xaa88, 0xad34, 0x0096, 0x080c, 0x1577, 0x6014, + 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea, + 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0804, 0x9fea, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x708c, 0x9086, 0x0074, 0x1540, 0x080c, 0xd527, 0x11b0, + 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, + 0x0110, 0xc0c5, 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, + 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0088, 0x2001, 0x000a, + 0x080c, 0x62f4, 0x080c, 0x30be, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0xac59, 0x00ee, + 0x0005, 0x00d6, 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e0, + 0x2069, 0x185b, 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6320, + 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, + 0x9086, 0x0074, 0x1904, 0xac30, 0x6010, 0x2058, 0xbaa0, 0x9286, + 0x007e, 0x1120, 0x080c, 0xae98, 0x0804, 0xab9d, 0x00d6, 0x080c, + 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, + 0x0904, 0xab3e, 0x080c, 0x54ef, 0x1598, 0x6014, 0x2048, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, + 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, + 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, + 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xc333, 0x0040, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, + 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x30be, 0x080c, 0x9fea, + 0x001e, 0x080c, 0x3190, 0x00de, 0x0804, 0xac33, 0x00de, 0x080c, + 0xae8d, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, + 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, + 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, + 0x0006, 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0804, + 0xac33, 0x080c, 0xac41, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, + 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, 0x08f8, + 0x080c, 0xac37, 0x0160, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0004, + 0x080c, 0x6320, 0x2001, 0x0007, 0x080c, 0x62f4, 0x08a0, 0x2001, + 0x0004, 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x0804, 0xac33, 0xb85c, 0xd0e4, 0x0178, + 0x080c, 0xc164, 0x080c, 0x717e, 0x0118, 0xd0dc, 0x1904, 0xab5f, + 0x2011, 0x1836, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xab5f, 0x080c, + 0xc1a1, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, + 0xd6c7, 0x000e, 0x1904, 0xab5f, 0xc0b5, 0x2012, 0x2001, 0x0006, + 0x080c, 0x62f4, 0x9006, 0x080c, 0x62e0, 0x00c6, 0x2001, 0x180f, + 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, + 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010, 0x78ea, + 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, + 0x080c, 0x26b6, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266d, 0x795a, + 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, + 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, + 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b6, 0x00f6, + 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c, 0x266d, + 0x795a, 0x00fe, 0x8108, 0x080c, 0x6343, 0x2b00, 0x00ce, 0x1904, + 0xab5f, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, + 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, + 0xb916, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0018, + 0x080c, 0xa9a7, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, 0xd0ac, + 0x0005, 0x00e6, 0x080c, 0xdb49, 0x0190, 0x2071, 0x0260, 0x7108, + 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, + 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, + 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x54ef, + 0x1120, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x30be, 0x6020, + 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fea, 0x00b6, 0x00e6, + 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014, 0x1904, + 0xad17, 0x00d6, 0x080c, 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010, + 0x080c, 0x66ed, 0x002e, 0x0904, 0xacc9, 0x080c, 0x54ef, 0x1598, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, + 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, + 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548, + 0x6014, 0x9005, 0x090c, 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, + 0x080c, 0xc333, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, + 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, + 0x30be, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190, 0x00de, 0x0804, + 0xad1b, 0x00de, 0x080c, 0x54ef, 0x1170, 0x6014, 0x9005, 0x1158, + 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, + 0x4bb4, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x643e, + 0x080c, 0xaac9, 0x00de, 0x080c, 0xaf63, 0x1588, 0x6010, 0x2058, + 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f4, 0x0096, + 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, + 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x30be, + 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fea, 0x0020, 0x080c, + 0xa9a7, 0x080c, 0xac59, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, + 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2030, 0x2011, 0x1823, 0x2204, + 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, + 0x080c, 0x62f4, 0x0804, 0x9fea, 0x0804, 0xac59, 0x0002, 0xaa88, + 0xad5e, 0xaa88, 0xad9f, 0xaa88, 0xae4a, 0xad53, 0xaa8b, 0xaa88, + 0xae5c, 0xaa88, 0xae6c, 0x6604, 0x9686, 0x0003, 0x0904, 0xac6e, + 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fea, 0x0005, 0x00b6, 0x00d6, + 0x00c6, 0x080c, 0xae7c, 0x11a0, 0x9006, 0x080c, 0x62e0, 0x080c, + 0x3095, 0x080c, 0xc46e, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0418, + 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, + 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, + 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x080c, 0xac59, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, + 0x00b6, 0x0026, 0x9016, 0x080c, 0xae8a, 0x00d6, 0x2069, 0x1956, + 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, + 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, + 0x00de, 0x0088, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, + 0x62f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, + 0x8b8f, 0x0804, 0xae1a, 0x080c, 0xbd4e, 0x01b0, 0x6014, 0x2048, + 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, + 0x0002, 0x080c, 0xc390, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, + 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, + 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, + 0x9006, 0x0c38, 0x080c, 0xa9a7, 0x2009, 0x026e, 0x2134, 0x96b4, + 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8, 0x2009, + 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01b0, + 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001, 0x0004, + 0x080c, 0x62f4, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0010, + 0x080c, 0xac59, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, + 0x0160, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa864, 0x9086, + 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, + 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x0010, 0x080c, + 0x3095, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f4, 0x04d9, 0x1140, + 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8640, 0x0804, 0x8b8f, + 0x080c, 0xa9a7, 0x0804, 0xac59, 0x0469, 0x1160, 0x2001, 0x0008, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x00e9, 0x1160, 0x2001, 0x000a, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2009, 0x026e, 0x2104, 0x9086, + 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, + 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, + 0x6110, 0x2158, 0x080c, 0x63b2, 0x001e, 0x00ce, 0x00be, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, + 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xaf35, + 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x66c5, + 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001, + 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, + 0x080c, 0x3060, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e73, 0x00ee, + 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3190, + 0x8108, 0x1f04, 0xaece, 0x015e, 0x00ce, 0x080c, 0xae8d, 0x2071, + 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836, 0x200c, + 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, + 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102, 0x9184, + 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, + 0x00ff, 0x2069, 0x181e, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, + 0x2069, 0x181f, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, + 0xff00, 0x001e, 0x9105, 0x2009, 0x182b, 0x200a, 0x2200, 0x9084, + 0x00ff, 0x2008, 0x080c, 0x26b6, 0x080c, 0x717e, 0x0170, 0x2071, + 0x0260, 0x2069, 0x195c, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, + 0x680a, 0x7054, 0x680e, 0x080c, 0xc164, 0x0040, 0x2001, 0x0006, + 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x001e, 0x003e, + 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, + 0x00e6, 0x0156, 0x2019, 0x182b, 0x231c, 0x83ff, 0x01f0, 0x2071, + 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, + 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xb017, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x2019, 0x0006, 0x080c, 0xb017, 0x1100, 0x015e, 0x00ee, 0x003e, + 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, + 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, + 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, + 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, + 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7250, 0x7070, + 0x9202, 0x1a04, 0xafef, 0x080c, 0xd868, 0x0904, 0xafe8, 0x6720, + 0x9786, 0x0007, 0x0904, 0xafe8, 0x2500, 0x9c06, 0x0904, 0xafe8, + 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, + 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, + 0x00c6, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x192c, 0x9786, + 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x00ce, 0x080c, 0xa9a7, + 0x080c, 0xa01c, 0x00e8, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x01a8, + 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, + 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce, + 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1210, 0x0804, 0xaf96, 0x012e, + 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, + 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c30, 0x9786, + 0x000a, 0x09e0, 0x0880, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, + 0x8318, 0x1f04, 0xb003, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, + 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, + 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, + 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, + 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, + 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, + 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, + 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x080c, 0xbf45, + 0x0120, 0x080c, 0xbf56, 0x0168, 0x0028, 0x080c, 0x30be, 0x080c, + 0xbf56, 0x0138, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, + 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, + 0x0040, 0x0208, 0x000a, 0x0005, 0xb078, 0xb078, 0xb078, 0xb078, + 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb07a, + 0xb07a, 0xb07a, 0xb07a, 0xb078, 0xb078, 0xb078, 0xb07a, 0xb078, + 0x080c, 0x0df6, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, + 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, + 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xb112, + 0x9186, 0x0027, 0x1520, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e, 0x0198, 0x080c, + 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0068, 0xa867, 0x0103, 0xa87b, + 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6a22, + 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x9186, + 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, + 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, + 0x0048, 0x190c, 0x0df6, 0x080c, 0xc47f, 0x0130, 0x6000, 0x9086, + 0x0002, 0x1110, 0x0804, 0xb150, 0x0005, 0x0002, 0xb0ec, 0xb0ea, + 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, + 0xb0ea, 0xb107, 0xb107, 0xb107, 0xb107, 0xb0ea, 0xb107, 0xb0ea, + 0xb107, 0xb0ea, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6114, + 0x2148, 0x080c, 0xbd4e, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6a22, 0x080c, + 0xbf39, 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, + 0x8a83, 0x080c, 0xbf56, 0x090c, 0xa9a7, 0x080c, 0x9fea, 0x080c, + 0x8b8f, 0x0005, 0x0002, 0xb129, 0xb127, 0xb127, 0xb127, 0xb127, + 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb140, 0xb140, + 0xb140, 0xb140, 0xb127, 0xb14a, 0xb127, 0xb140, 0xb127, 0x080c, + 0x0df6, 0x0096, 0x080c, 0x8a83, 0x6014, 0x2048, 0x2001, 0x1962, + 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, + 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, + 0x080c, 0x8a83, 0x080c, 0xc471, 0x080c, 0xc476, 0x6003, 0x000f, + 0x0804, 0x8b8f, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, - 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, - 0xb06c, 0xb06c, 0xb06c, 0xb06e, 0xb06e, 0xb06e, 0xb06e, 0xb06c, - 0xb06c, 0xb06c, 0xb06e, 0xb06c, 0x080c, 0x0e02, 0x600b, 0xffff, - 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, - 0x080c, 0x8b90, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, - 0x9082, 0x0040, 0x0804, 0xb106, 0x9186, 0x0027, 0x1520, 0x080c, - 0x8a84, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114, 0x2148, - 0x080c, 0xbd3b, 0x0198, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995, - 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c, - 0xc1c5, 0xa97e, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c, - 0x9fd5, 0x0804, 0x8b90, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082, - 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186, 0x0045, 0x0138, - 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, 0x0e02, 0x080c, - 0xc46a, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb144, - 0x0005, 0x0002, 0xb0e0, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de, - 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0fb, 0xb0fb, 0xb0fb, - 0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0x080c, 0x0e02, - 0x080c, 0x8a84, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0168, - 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, - 0xa882, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c, 0x9fd5, - 0x080c, 0x8b90, 0x0005, 0x080c, 0x8a84, 0x080c, 0xbf43, 0x090c, - 0xa995, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x0002, 0xb11d, - 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, - 0xb11b, 0xb11b, 0xb134, 0xb134, 0xb134, 0xb134, 0xb11b, 0xb13e, - 0xb11b, 0xb134, 0xb11b, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84, - 0x6014, 0x2048, 0x2001, 0x1962, 0x2004, 0x6042, 0xa97c, 0xd1ac, - 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, 0xa87e, 0x009e, - 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x8a84, 0x080c, 0xc45c, - 0x080c, 0xc461, 0x6003, 0x000f, 0x0804, 0x8b90, 0x080c, 0x8a84, - 0x080c, 0x9fd5, 0x0804, 0x8b90, 0x9182, 0x0054, 0x1220, 0x9182, - 0x0040, 0x0208, 0x000a, 0x0005, 0xb160, 0xb160, 0xb160, 0xb160, - 0xb160, 0xb162, 0xb23f, 0xb160, 0xb273, 0xb160, 0xb160, 0xb160, - 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb273, - 0x080c, 0x0e02, 0x00b6, 0x0096, 0x6114, 0x2148, 0x7644, 0x96b4, - 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, - 0xb22e, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, - 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x080c, 0x683d, - 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x7044, - 0xd0e4, 0x1904, 0xb212, 0x080c, 0x9fd5, 0x009e, 0x00be, 0x0005, - 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, - 0xb216, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, - 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, - 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, - 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, - 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, - 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, - 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, - 0x1118, 0xc6c4, 0x0804, 0xb169, 0x735c, 0xab86, 0x83ff, 0x0170, - 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, - 0x0018, 0x2011, 0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x0904, - 0xb17e, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xb17e, 0x9192, 0x0021, - 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb906, - 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xc3e9, 0x0804, 0xb17e, - 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, - 0x2950, 0x080c, 0xb8a5, 0x00ae, 0x080c, 0xc3e9, 0x080c, 0xb8f6, - 0x0804, 0xb180, 0x080c, 0xc03b, 0x0804, 0xb18d, 0xa87c, 0xd0ac, - 0x0904, 0xb199, 0xa880, 0xd0bc, 0x1904, 0xb199, 0x7348, 0xa838, - 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, 0xb199, 0xd6d4, - 0x0190, 0xab38, 0x9305, 0x0904, 0xb199, 0x0068, 0xa87c, 0xd0ac, - 0x0904, 0xb171, 0xa838, 0xa934, 0x9105, 0x0904, 0xb171, 0xa880, - 0xd0bc, 0x1904, 0xb171, 0x080c, 0xc075, 0x0804, 0xb18d, 0x0096, - 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, - 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, - 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, - 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, - 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, - 0x6043, 0x0000, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e, 0x080c, - 0x8c6d, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, - 0x0040, 0x0208, 0x000a, 0x0005, 0xb290, 0xb290, 0xb290, 0xb290, - 0xb290, 0xb292, 0xb328, 0xb290, 0xb290, 0xb33f, 0xb3cf, 0xb290, - 0xb290, 0xb290, 0xb290, 0xb3e4, 0xb290, 0xb290, 0xb290, 0xb290, - 0x080c, 0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, - 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, - 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, - 0xba3e, 0x00be, 0x86ff, 0x0904, 0xb323, 0x9694, 0xff00, 0x9284, - 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, - 0x0904, 0xb323, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a, - 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, - 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, - 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, - 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, - 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, - 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, - 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, - 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, - 0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, - 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, - 0x2011, 0x0029, 0x080c, 0xb906, 0x2011, 0x0205, 0x2013, 0x0000, - 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, - 0x2950, 0x080c, 0xb8a5, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, - 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, - 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, - 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1a82, 0x0804, 0x95d2, 0x6003, - 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, - 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, - 0x2078, 0x080c, 0x165d, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, - 0x0002, 0x009e, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0096, 0x2001, - 0x1962, 0x2004, 0x6042, 0x080c, 0x8b40, 0x080c, 0x8c6d, 0x6114, - 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xb3ca, 0xd1cc, 0x05c8, 0xa978, - 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, - 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, - 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, - 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, - 0x0ff5, 0x001e, 0x0458, 0x0016, 0x080c, 0x0ff5, 0x009e, 0xa87c, - 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xb8f6, 0x001e, 0x00f0, - 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, - 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, - 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, - 0xa87b, 0x0000, 0x0016, 0x080c, 0x683d, 0x001e, 0xd1e4, 0x1120, - 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b, 0x0cd8, 0x6004, - 0x9086, 0x0040, 0x1120, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019, - 0x0001, 0x080c, 0x989c, 0x6003, 0x0002, 0x080c, 0xc461, 0x080c, - 0x8b40, 0x080c, 0x8c6d, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, - 0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019, 0x0001, 0x080c, 0x989c, - 0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114, - 0x2148, 0x080c, 0xbd3b, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, - 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c, - 0x9fd5, 0x080c, 0x8c6d, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, - 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, - 0x0016, 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, - 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, - 0x0208, 0x000a, 0x0005, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, - 0xb441, 0xb43f, 0xb43f, 0xb4e7, 0xb43f, 0xb43f, 0xb43f, 0xb43f, - 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb619, 0x080c, - 0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, + 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16e, 0xb24e, 0xb16c, + 0xb282, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, + 0xb16c, 0xb16c, 0xb16c, 0xb282, 0x080c, 0x0df6, 0x00b6, 0x0096, + 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb23d, 0xa87b, 0x0000, 0xa867, + 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0x080c, 0x683c, 0x6210, 0x2258, 0xba3c, 0x82ff, + 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xb21e, 0x080c, + 0x9fea, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb222, 0x7348, 0xab92, 0x734c, + 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, + 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, + 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, + 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, + 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, + 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xb175, + 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, + 0xb915, 0x003e, 0xd6cc, 0x0904, 0xb18a, 0x7154, 0xa98a, 0x81ff, + 0x0904, 0xb18a, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, + 0x2011, 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000, + 0x080c, 0xc3fc, 0x0804, 0xb18a, 0xa868, 0xd0fc, 0x0120, 0x2009, + 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xb8b4, 0x00ae, + 0x080c, 0xc3fc, 0x080c, 0xb905, 0x0804, 0xb18c, 0x080c, 0xc04e, + 0x0804, 0xb199, 0xa87c, 0xd0ac, 0x0904, 0xb1a5, 0xa880, 0xd0bc, + 0x1904, 0xb1a5, 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, + 0x0904, 0xb1a5, 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, + 0xa834, 0x931e, 0x0904, 0xb1a5, 0x0068, 0xa87c, 0xd0ac, 0x0904, + 0xb17d, 0xa838, 0xa934, 0x9105, 0x0904, 0xb17d, 0xa880, 0xd0bc, + 0x1904, 0xb17d, 0x080c, 0xc088, 0x0804, 0xb199, 0x0096, 0x00f6, + 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, + 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, + 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, + 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, + 0x0000, 0x2c10, 0x080c, 0x1a7e, 0x080c, 0x865d, 0x080c, 0x8c6c, + 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0xb29f, + 0xb2a1, 0xb337, 0xb29f, 0xb29f, 0xb34e, 0xb3de, 0xb29f, 0xb29f, + 0xb29f, 0xb29f, 0xb3f3, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0x080c, + 0x0df6, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, - 0x00be, 0x86ff, 0x0904, 0xb4e0, 0x9694, 0xff00, 0x9284, 0x0c00, + 0x00be, 0x86ff, 0x0904, 0xb332, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, - 0xb4e0, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, - 0xb676, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a, - 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, - 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, - 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, - 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, - 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, - 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, - 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, - 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, - 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb906, - 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, - 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, - 0xb906, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, - 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8a5, - 0x080c, 0x1904, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, - 0x1962, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, - 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, - 0xd1e4, 0x0904, 0xb614, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5e3, 0xa978, - 0xa868, 0xd0fc, 0x0904, 0xb5a4, 0x0016, 0xa87c, 0x0006, 0xa880, - 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, - 0x0904, 0xb571, 0x9086, 0x0028, 0x1904, 0xb55d, 0xa87b, 0x001c, - 0xb07b, 0x001c, 0x0804, 0xb579, 0x6024, 0xd0f4, 0x11d0, 0xa838, - 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, - 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, - 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, - 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, - 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, - 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0ff5, - 0x009e, 0x080c, 0xc075, 0x0804, 0xb614, 0xd1dc, 0x0158, 0xa87b, - 0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc, - 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, - 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, - 0xb40c, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, - 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, - 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, - 0xa87e, 0x080c, 0xc3e9, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, - 0x0ff5, 0x001e, 0x0804, 0xb610, 0x0016, 0x00a6, 0x2150, 0xb174, - 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, - 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, - 0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc, - 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, - 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, - 0xb40c, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, - 0x080c, 0x0ff5, 0x009e, 0x080c, 0xc3e9, 0xa974, 0x0016, 0x080c, - 0xb8f6, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, - 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, - 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc309, 0x0118, - 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, - 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xb40c, 0xa974, 0x0016, 0x080c, 0x683d, 0x001e, - 0xd1e4, 0x1120, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b, - 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1924, - 0x009e, 0x0005, 0x080c, 0x8a84, 0x0010, 0x080c, 0x8b40, 0x080c, - 0xbd3b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf43, 0x1118, - 0x080c, 0xa995, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, - 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, - 0x1110, 0x080c, 0xda80, 0xa877, 0x0000, 0x080c, 0x6a23, 0x009e, - 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0804, 0x8c6d, 0xa87b, 0x0004, - 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, - 0x0040, 0x0208, 0x000a, 0x0005, 0xb670, 0xb670, 0xb670, 0xb670, - 0xb670, 0xb672, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, - 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, - 0x080c, 0x0e02, 0x080c, 0x54e4, 0x01f8, 0x6014, 0x7144, 0x918c, - 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, - 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, - 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, - 0xaa9e, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x9182, 0x0085, - 0x0002, 0xb6a8, 0xb6a6, 0xb6a6, 0xb6b4, 0xb6a6, 0xb6a6, 0xb6a6, - 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0x080c, 0x0e02, - 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, - 0x080c, 0x8b90, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, - 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd29, 0x01f8, - 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, - 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb967, 0x00de, 0x00ce, - 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xb931, 0x0010, 0x6803, - 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xb953, 0x0d90, 0x6007, - 0x0087, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x7220, - 0x080c, 0xbd29, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, - 0xc075, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, - 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02, 0x908a, - 0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, - 0x0120, 0x9186, 0x0014, 0x190c, 0x0e02, 0x080c, 0x8a84, 0x0096, - 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa867, 0x0103, 0xa877, - 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x009e, 0x080c, 0xa007, - 0x0804, 0x8b90, 0xb737, 0xb739, 0xb739, 0xb737, 0xb737, 0xb737, - 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0x080c, - 0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, - 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, - 0x9186, 0x0027, 0x11f8, 0x080c, 0x8a84, 0x080c, 0x30ab, 0x080c, - 0xc459, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0150, 0xa867, - 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x080c, - 0xbf26, 0x009e, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, - 0xa06e, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a84, 0x0096, - 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0d60, 0xa867, 0x0103, 0xa877, - 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, - 0xb78f, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb7a7, 0xb78d, - 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0x080c, 0x0e02, 0x080c, - 0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, - 0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, - 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x080c, - 0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, - 0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, - 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x8b90, 0x0005, 0x9182, - 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa06e, - 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d7, 0xb824, 0xb7d5, 0xb7d5, - 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0x080c, 0x0e02, 0x0096, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, - 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, - 0x1118, 0x009e, 0x0804, 0xb838, 0x080c, 0xbd3b, 0x1118, 0x080c, - 0xbf26, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, - 0xbf26, 0xa867, 0x0103, 0x080c, 0xc424, 0x080c, 0x6a23, 0x00d6, - 0x2c68, 0x080c, 0x9f7f, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, - 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, - 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xc1b7, 0x6954, 0x6156, - 0x6023, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de, - 0x080c, 0x9fd5, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, - 0x00d6, 0x2c68, 0x080c, 0xc3bc, 0x11f0, 0x080c, 0x9f7f, 0x01d8, - 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, - 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, - 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1b7, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de, 0x0804, 0x9fd5, 0x0096, - 0x6014, 0x2048, 0x080c, 0xbd3b, 0x01c8, 0xa867, 0x0103, 0xa880, - 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, - 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc037, - 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x0804, - 0x9fd5, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, - 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a23, - 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, - 0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030, 0x080c, 0x8a84, - 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0056, 0x0066, 0x0096, - 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, - 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, - 0x0029, 0x080c, 0xb906, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, - 0x080c, 0x0ff5, 0x080c, 0x1043, 0x0520, 0x8528, 0xa867, 0x0110, - 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, - 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, - 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, - 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, - 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, - 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, - 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a23, - 0x2a48, 0x0cb8, 0x080c, 0x6a23, 0x00ae, 0x0005, 0x00f6, 0x2079, - 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, - 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, - 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, - 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, - 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, - 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, - 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, - 0xbd3b, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6c, - 0x080c, 0x6a16, 0x080c, 0xbf26, 0x009e, 0x080c, 0xa007, 0x00ee, - 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, - 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, - 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, - 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, - 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, - 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, - 0x0005, 0xb9a2, 0xb9a2, 0xb99d, 0xb9c4, 0xb990, 0xb99d, 0xb9c4, - 0xb99d, 0xb990, 0xb990, 0xb99d, 0xb99d, 0xb99d, 0xb990, 0xb990, - 0x080c, 0x0e02, 0x0036, 0x2019, 0x0010, 0x080c, 0xd385, 0x6023, - 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, - 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, - 0xbd3b, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, - 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c, - 0x080c, 0xc037, 0x080c, 0x6a16, 0x080c, 0xa007, 0x9085, 0x0001, - 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c, - 0x0e02, 0x0002, 0xb9da, 0xba0a, 0xb9dc, 0xba2b, 0xba05, 0xb9da, - 0xb99d, 0xb9a2, 0xb9a2, 0xb99d, 0xb99d, 0xb99d, 0xb99d, 0xb99d, - 0xb99d, 0xb99d, 0x080c, 0x0e02, 0x86ff, 0x1520, 0x6020, 0x9086, - 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0168, - 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, - 0x080c, 0x0ff5, 0x009e, 0x080c, 0xc037, 0x009e, 0x080c, 0xc3fe, - 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9, - 0x080c, 0x8b90, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1938, - 0x006e, 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120, - 0x080c, 0x9826, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, - 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, - 0x994a, 0x009e, 0x008e, 0x0010, 0x080c, 0x9723, 0x00ee, 0x1904, - 0xb9dc, 0x0804, 0xb99d, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, - 0x9c06, 0x1138, 0x901e, 0x080c, 0x989c, 0x00ee, 0x003e, 0x0804, - 0xb9dc, 0x080c, 0x9a7a, 0x00ee, 0x003e, 0x1904, 0xb9dc, 0x0804, - 0xb99d, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, - 0xba5e, 0xbb0f, 0xbc79, 0xba68, 0xa007, 0xba5e, 0xd377, 0xc466, - 0xbb0f, 0xba57, 0xbd05, 0xba57, 0xba57, 0xba57, 0xba57, 0x080c, - 0x0e02, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x0005, 0x080c, - 0x8a84, 0x080c, 0x8b90, 0x0804, 0x9fd5, 0x601b, 0x0001, 0x0005, - 0x080c, 0xbd3b, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, - 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0002, 0xba87, - 0xba89, 0xbaad, 0xbac1, 0xbae7, 0xba87, 0xba5e, 0xba5e, 0xba5e, - 0xbac1, 0xbac1, 0xba87, 0xba87, 0xba87, 0xba87, 0xbacb, 0x080c, - 0x0e02, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, - 0x009e, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9723, - 0x080c, 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x2001, 0x1961, 0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90, - 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, - 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc3fe, 0x6007, 0x0085, - 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9, 0x080c, 0x8b90, - 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, - 0xa882, 0x009e, 0x0005, 0x080c, 0x54e4, 0x01b8, 0x6014, 0x0096, - 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, - 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, - 0xa89b, 0x0004, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x6014, - 0x0096, 0x904d, 0x01f8, 0xa97c, 0xd1e4, 0x01e0, 0x2001, 0x180f, - 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, - 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c, - 0x158c, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, - 0xa053, 0x0005, 0x009e, 0x080c, 0x1938, 0x0804, 0xbaad, 0x6000, - 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0xbb26, 0xba65, - 0xbb28, 0xbb26, 0xbb28, 0xbb28, 0xba5f, 0xbb26, 0xba59, 0xba59, - 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0x080c, 0x0e02, - 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, - 0x000c, 0x1a0c, 0x0e02, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb43, - 0xbc10, 0xbb45, 0xbb85, 0xbb45, 0xbb85, 0xbb45, 0xbb53, 0xbb43, - 0xbb85, 0xbb43, 0xbb74, 0x080c, 0x0e02, 0x6004, 0x908e, 0x0016, - 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, - 0x0052, 0x0904, 0xbc0c, 0x6004, 0x080c, 0xbf43, 0x0904, 0xbc29, - 0x908e, 0x0004, 0x1110, 0x080c, 0x30d4, 0x908e, 0x0021, 0x0904, - 0xbc2d, 0x908e, 0x0022, 0x0904, 0xbc74, 0x908e, 0x003d, 0x0904, - 0xbc2d, 0x908e, 0x0039, 0x0904, 0xbc31, 0x908e, 0x0035, 0x0904, - 0xbc31, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, - 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, - 0x30ab, 0x080c, 0xa995, 0x0804, 0xa007, 0x00c6, 0x00d6, 0x6104, - 0x9186, 0x0016, 0x0904, 0xbbfd, 0x9186, 0x0002, 0x1904, 0xbbd2, - 0x2001, 0x1836, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717f, 0x11b0, - 0x080c, 0xc444, 0x0138, 0x080c, 0x71a2, 0x1120, 0x080c, 0x707d, - 0x0804, 0xbc5d, 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800, - 0x2003, 0x0001, 0x080c, 0x709f, 0x0804, 0xbc5d, 0x6010, 0x2058, - 0x2001, 0x1836, 0x2004, 0xd0ac, 0x1904, 0xbc5d, 0xb8a0, 0x9084, - 0xff80, 0x1904, 0xbc5d, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, - 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, - 0x6043, 0x0000, 0x080c, 0x9f7f, 0x0128, 0x2b00, 0x6012, 0x6023, - 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, - 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836, - 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3, - 0x00ee, 0x080c, 0xa995, 0x0030, 0x080c, 0xa995, 0x080c, 0x30ab, - 0x080c, 0xc459, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30d4, - 0x012e, 0x00ee, 0x080c, 0xa007, 0x0005, 0x2001, 0x0002, 0x080c, - 0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, - 0x8b90, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x30d4, 0x0804, 0xbb81, - 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, - 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xbbd2, 0x8001, 0xb842, - 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00de, 0x00ce, - 0x0898, 0x080c, 0xa995, 0x0804, 0xbb83, 0x080c, 0xa9d1, 0x0804, - 0xbb83, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xc3bc, 0x00de, 0x0118, - 0x080c, 0x9fd5, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, - 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x603c, 0x600a, 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08, - 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, - 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005, 0x00de, 0x00ce, 0x080c, - 0xa995, 0x080c, 0x30ab, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, - 0x30d4, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, - 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xa40c, 0x1904, 0xbc29, - 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0096, 0x00d6, - 0x001b, 0x00de, 0x009e, 0x0005, 0xbc94, 0xbc94, 0xbc94, 0xbc94, - 0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xba5e, 0xbc94, 0xba65, - 0xbc96, 0xba65, 0xbcb0, 0xbc94, 0x080c, 0x0e02, 0x6004, 0x9086, - 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, - 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, - 0x008b, 0x6003, 0x000d, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005, - 0x080c, 0xc438, 0x0118, 0x080c, 0xc44b, 0x0010, 0x080c, 0xc459, - 0x080c, 0xbf26, 0x080c, 0xbd3b, 0x0570, 0x080c, 0x30ab, 0x080c, - 0xbd3b, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, - 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a23, 0x2c68, - 0x080c, 0x9f7f, 0x0150, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x00c6, - 0x2d60, 0x080c, 0xa007, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, - 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641, - 0x080c, 0x8b90, 0x00c8, 0x080c, 0xc438, 0x0138, 0x6034, 0x9086, - 0x4000, 0x1118, 0x080c, 0x30ab, 0x08d0, 0x6034, 0x908c, 0xff00, - 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, - 0x30ab, 0x0868, 0x080c, 0xa007, 0x0005, 0x6000, 0x908a, 0x0016, - 0x1a0c, 0x0e02, 0x0002, 0xbd1b, 0xbd1b, 0xbd1d, 0xbd1d, 0xbd1d, - 0xbd1b, 0xbd1b, 0xa007, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b, - 0xbd1b, 0xbd1b, 0xbd1b, 0x080c, 0x0e02, 0x080c, 0x9a7a, 0x6114, - 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x0804, - 0x9fd5, 0x9284, 0x0007, 0x1158, 0x9282, 0x1cd0, 0x0240, 0x2001, - 0x1819, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, - 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, - 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10ee, - 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, - 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7350, 0x7070, - 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xc444, 0x0180, - 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, - 0x30ab, 0x080c, 0xc459, 0x00c6, 0x080c, 0xa007, 0x00ce, 0x0060, - 0x080c, 0xc131, 0x0148, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, - 0x00c6, 0x080c, 0x9fd5, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02, - 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, - 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, - 0x2061, 0x1a88, 0x6112, 0x080c, 0x30ab, 0x9006, 0x0010, 0x9085, - 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0x9f7f, 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c, - 0x54e4, 0x0118, 0x080c, 0xbe6a, 0x0168, 0x080c, 0xc1b7, 0x6023, - 0x0003, 0x2009, 0x004b, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, - 0xbaa0, 0x080c, 0xa026, 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012, - 0x080c, 0xc1b7, 0x6023, 0x0003, 0x0016, 0x080c, 0x8783, 0x0076, - 0x903e, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e, - 0xd184, 0x0128, 0x080c, 0x9fd5, 0x9085, 0x0001, 0x0070, 0x080c, - 0x54e4, 0x0128, 0xd18c, 0x1170, 0x080c, 0xbe6a, 0x0148, 0x2009, - 0x004c, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, - 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, - 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0x9f7f, - 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, - 0x2021, 0x0005, 0x080c, 0xbe7c, 0x001e, 0x9186, 0x004d, 0x0118, - 0x9186, 0x004e, 0x0148, 0x2001, 0x195a, 0x200c, 0xd1fc, 0x0168, - 0x2f60, 0x080c, 0x9fd5, 0x00d0, 0x2001, 0x1959, 0x200c, 0xd1fc, - 0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0088, 0x2f60, 0x080c, 0x54e4, - 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, - 0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001, 0x001e, 0x004e, - 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0x9f7f, - 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, - 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, 0x1958, 0x200c, 0xd1fc, - 0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0060, 0x2f60, 0x080c, 0x54e4, - 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, - 0xa053, 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, - 0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x1120, 0x080c, - 0x9fd5, 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, - 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, - 0x8000, 0x080c, 0x64d8, 0x0158, 0x2001, 0xbe81, 0x0006, 0x900e, - 0x2400, 0x080c, 0x6c6c, 0x080c, 0x6a23, 0x000e, 0x0807, 0x2418, - 0x080c, 0x8a1e, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, - 0x2608, 0x080c, 0x879b, 0x008e, 0x080c, 0x8671, 0x2f08, 0x2648, - 0x080c, 0xd53b, 0xb93c, 0x81ff, 0x090c, 0x886e, 0x080c, 0x8b90, - 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0x9f7f, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7, - 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xa053, + 0xb332, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c, + 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, + 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, + 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, + 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, + 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, + 0x080c, 0xb915, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, + 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, + 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, + 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, + 0x080c, 0xb8b4, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, + 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, + 0x00fe, 0x2c10, 0x080c, 0x1a7e, 0x0804, 0x95e7, 0x6003, 0x0002, + 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, + 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, + 0x080c, 0x1651, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, + 0x009e, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0096, 0x2001, 0x1962, + 0x2004, 0x6042, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6114, 0x2148, + 0xa97c, 0xd1e4, 0x0904, 0xb3d9, 0xd1cc, 0x05c8, 0xa978, 0xa868, + 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, + 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, + 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9, + 0x001e, 0x0458, 0x0016, 0x080c, 0x0fe9, 0x009e, 0xa87c, 0xc0cc, + 0xa87e, 0xa974, 0x0016, 0x080c, 0xb905, 0x001e, 0x00f0, 0xa867, + 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4, 0x1120, 0x080c, + 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8, 0x6004, 0x9086, + 0x0040, 0x1120, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001, + 0x080c, 0x98b1, 0x6003, 0x0002, 0x080c, 0xc476, 0x080c, 0x8b3f, + 0x080c, 0x8c6c, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, + 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001, 0x080c, 0x98b1, 0x080c, + 0x8b3f, 0x080c, 0x3095, 0x080c, 0xc46e, 0x0096, 0x6114, 0x2148, + 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea, + 0x080c, 0x8c6c, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, + 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, + 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, + 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb450, + 0xb44e, 0xb44e, 0xb4f6, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, + 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb628, 0x080c, 0x0df6, + 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, + 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, + 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, + 0x86ff, 0x0904, 0xb4ef, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, + 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xb4ef, + 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, + 0x0c38, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c, + 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, + 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, + 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, + 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, + 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, + 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, + 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb915, 0x003e, + 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, + 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb915, + 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8b4, 0x080c, + 0x18f8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1962, + 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, + 0x0904, 0xb623, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5f2, 0xa978, 0xa868, + 0xd0fc, 0x0904, 0xb5b3, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, + 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, + 0xb580, 0x9086, 0x0028, 0x1904, 0xb56c, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x0804, 0xb588, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, + 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, + 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, + 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, + 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, + 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, + 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, + 0x080c, 0xc088, 0x0804, 0xb623, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b, + 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, + 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, + 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, + 0x080c, 0xc3fc, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9, + 0x001e, 0x0804, 0xb61f, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, + 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, + 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b, + 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, + 0x0fe9, 0x009e, 0x080c, 0xc3fc, 0xa974, 0x0016, 0x080c, 0xb905, + 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, + 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xa974, + 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, + 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0xa974, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4, + 0x1120, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8, + 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1918, 0x009e, + 0x0005, 0x080c, 0x8a83, 0x0010, 0x080c, 0x8b3f, 0x080c, 0xbd4e, + 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf56, 0x1118, 0x080c, + 0xa9a7, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, + 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, + 0x080c, 0xdae1, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e, 0x080c, + 0x9fea, 0x080c, 0x8b8f, 0x0804, 0x8c6c, 0xa87b, 0x0004, 0x0c90, + 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, + 0xb681, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, + 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0x080c, + 0x0df6, 0x080c, 0x54e3, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, + 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, + 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, + 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, + 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x9182, 0x0085, 0x0002, + 0xb6b7, 0xb6b5, 0xb6b5, 0xb6c3, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, + 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0x080c, 0x0df6, 0x6003, + 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b8f, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, + 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd3c, 0x01f8, 0x2268, + 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, + 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb976, 0x00de, 0x00ce, 0x0158, + 0x702c, 0xd084, 0x1118, 0x080c, 0xb940, 0x0010, 0x6803, 0x0002, + 0x6007, 0x0086, 0x0028, 0x080c, 0xb962, 0x0d90, 0x6007, 0x0087, + 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x7220, 0x080c, + 0xbd3c, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xc088, + 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, + 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092, + 0x1a0c, 0x0df6, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, + 0x9186, 0x0014, 0x190c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x0804, + 0x8b8f, 0xb746, 0xb748, 0xb748, 0xb746, 0xb746, 0xb746, 0xb746, + 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, + 0x0027, 0x11f8, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c, 0xc46e, + 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103, + 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x080c, 0xbf39, + 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xa083, + 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a83, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xb79e, + 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb7b6, 0xb79c, 0xb79c, + 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0x080c, 0x0df6, 0x080c, 0x8a83, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004, + 0x601a, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x080c, 0x8a83, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004, + 0x601a, 0x6003, 0x000e, 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0092, + 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa083, 0xb7e4, + 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e6, 0xb833, 0xb7e4, 0xb7e4, 0xb7e4, + 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e4, 0x080c, 0x0df6, 0x0096, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x009e, 0x0804, 0xb847, 0x080c, 0xbd4e, 0x1118, 0x080c, 0xbf39, + 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xbf39, + 0xa867, 0x0103, 0x080c, 0xc439, 0x080c, 0x6a22, 0x00d6, 0x2c68, + 0x080c, 0x9f94, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, + 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x6910, 0x6112, 0x080c, 0xc1ca, 0x6954, 0x6156, 0x6023, + 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x080c, + 0x9fea, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, + 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, + 0x2c68, 0x080c, 0xc3cf, 0x11f0, 0x080c, 0x9f94, 0x01d8, 0x6106, + 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, + 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, + 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1ca, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x0804, 0x9fea, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, + 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, + 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc04a, 0xa877, + 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x0804, 0x9fea, + 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867, + 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e, + 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, + 0x0027, 0x0118, 0x080c, 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c, + 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, + 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, + 0x080c, 0xb915, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fe9, 0x080c, 0x1037, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, + 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, + 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, + 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, + 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, + 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a22, 0x2a48, + 0x0cb8, 0x080c, 0x6a22, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, + 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, + 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, + 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, + 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, + 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, + 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6b, 0x080c, + 0x6a15, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, + 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, + 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, + 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, + 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, + 0xb9b1, 0xb9b1, 0xb9ac, 0xb9d3, 0xb99f, 0xb9ac, 0xb9d3, 0xb9ac, + 0xb9ac, 0xb99f, 0xb9ac, 0xb9ac, 0xb9ac, 0xb99f, 0xb99f, 0x080c, + 0x0df6, 0x0036, 0x2019, 0x0010, 0x080c, 0xd38f, 0x6023, 0x0006, + 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, + 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, + 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6b, 0x080c, + 0xc04a, 0x080c, 0x6a15, 0x080c, 0xa01c, 0x9085, 0x0001, 0x009e, + 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, + 0x0002, 0xb9e9, 0xba19, 0xb9eb, 0xba3a, 0xba14, 0xb9e9, 0xb9ac, + 0xb9b1, 0xb9b1, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, + 0xb9ac, 0x080c, 0x0df6, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, + 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0168, 0xa87c, + 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, + 0x0fe9, 0x009e, 0x080c, 0xc04a, 0x009e, 0x080c, 0xc413, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c, + 0x8b8f, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x192c, 0x006e, + 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120, 0x080c, + 0x983b, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, + 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x995f, + 0x009e, 0x008e, 0x0010, 0x080c, 0x9738, 0x00ee, 0x1904, 0xb9eb, + 0x0804, 0xb9ac, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, 0x9c06, + 0x1138, 0x901e, 0x080c, 0x98b1, 0x00ee, 0x003e, 0x0804, 0xb9eb, + 0x080c, 0x9a8f, 0x00ee, 0x003e, 0x1904, 0xb9eb, 0x0804, 0xb9ac, + 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba6d, + 0xbb1d, 0xbc87, 0xba77, 0xa01c, 0xba6d, 0xd381, 0xc47b, 0xbb1d, + 0xba66, 0xbd13, 0xba66, 0xba66, 0xba66, 0xba66, 0x080c, 0x0df6, + 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x0005, 0x080c, 0x8a83, + 0x080c, 0x8b8f, 0x0804, 0x9fea, 0x601b, 0x0001, 0x0005, 0x080c, + 0xbd4e, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0002, 0xba96, 0xba98, + 0xbabc, 0xbad0, 0xbaf6, 0xba96, 0xba6d, 0xba6d, 0xba6d, 0xbad0, + 0xbad0, 0xba96, 0xba96, 0xba96, 0xba96, 0xbada, 0x080c, 0x0df6, + 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, + 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9738, 0x080c, + 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, + 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ee, + 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, + 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, + 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, + 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, + 0x009e, 0x0005, 0x080c, 0x54e3, 0x01b8, 0x6014, 0x0096, 0x904d, + 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, + 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x6014, 0x0096, + 0x904d, 0x01f0, 0xa97c, 0xd1e4, 0x01d8, 0x2001, 0x180f, 0x2004, + 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, + 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x2165, 0x00ce, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, + 0x009e, 0x080c, 0x192c, 0x0804, 0xbabc, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xbb34, 0xba74, 0xbb36, 0xbb34, + 0xbb36, 0xbb36, 0xba6e, 0xbb34, 0xba68, 0xba68, 0xbb34, 0xbb34, + 0xbb34, 0xbb34, 0xbb34, 0xbb34, 0x080c, 0x0df6, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, + 0x0df6, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb51, 0xbc1e, 0xbb53, + 0xbb93, 0xbb53, 0xbb93, 0xbb53, 0xbb61, 0xbb51, 0xbb93, 0xbb51, + 0xbb82, 0x080c, 0x0df6, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, + 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, + 0xbc1a, 0x6004, 0x080c, 0xbf56, 0x0904, 0xbc37, 0x908e, 0x0004, + 0x1110, 0x080c, 0x30be, 0x908e, 0x0021, 0x0904, 0xbc3b, 0x908e, + 0x0022, 0x0904, 0xbc82, 0x908e, 0x003d, 0x0904, 0xbc3b, 0x908e, + 0x0039, 0x0904, 0xbc3f, 0x908e, 0x0035, 0x0904, 0xbc3f, 0x908e, + 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3095, 0x080c, + 0xa9a7, 0x0804, 0xa01c, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, + 0x0904, 0xbc0b, 0x9186, 0x0002, 0x1904, 0xbbe0, 0x2001, 0x1836, + 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717e, 0x11b0, 0x080c, 0xc459, + 0x0138, 0x080c, 0x71a1, 0x1120, 0x080c, 0x707c, 0x0804, 0xbc6b, + 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, + 0x080c, 0x709e, 0x0804, 0xbc6b, 0x6010, 0x2058, 0x2001, 0x1836, + 0x2004, 0xd0ac, 0x1904, 0xbc6b, 0xb8a0, 0x9084, 0xff80, 0x1904, + 0xbc6b, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, + 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, + 0x080c, 0x9f94, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, + 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, + 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836, 0x2104, 0xc085, + 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x080c, + 0xa9a7, 0x0030, 0x080c, 0xa9a7, 0x080c, 0x3095, 0x080c, 0xc46e, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x012e, 0x00ee, + 0x080c, 0xa01c, 0x0005, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de, + 0x00ce, 0x0c80, 0x080c, 0x30be, 0x0804, 0xbb8f, 0x00c6, 0x00d6, + 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0904, 0xbbe0, 0x8001, 0xb842, 0x6003, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de, 0x00ce, 0x0898, 0x080c, + 0xa9a7, 0x0804, 0xbb91, 0x080c, 0xa9e3, 0x0804, 0xbb91, 0x00d6, + 0x2c68, 0x6104, 0x080c, 0xc3cf, 0x00de, 0x0118, 0x080c, 0x9fea, + 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, + 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, + 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, + 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x0005, 0x00de, 0x00ce, 0x080c, 0xa9a7, 0x080c, + 0x3095, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x6017, + 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, + 0x00ee, 0x0005, 0x080c, 0xa41e, 0x1904, 0xbc37, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0096, 0x00d6, 0x001b, 0x00de, + 0x009e, 0x0005, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2, + 0xbca2, 0xbca2, 0xbca2, 0xba6d, 0xbca2, 0xba74, 0xbca4, 0xba74, + 0xbcbe, 0xbca2, 0x080c, 0x0df6, 0x6004, 0x9086, 0x008b, 0x01b0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, + 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, + 0x000d, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xc44d, + 0x0118, 0x080c, 0xc460, 0x0010, 0x080c, 0xc46e, 0x080c, 0xbf39, + 0x080c, 0xbd4e, 0x0570, 0x080c, 0x3095, 0x080c, 0xbd4e, 0x0168, + 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a22, 0x2c68, 0x080c, 0x9f94, + 0x0150, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x00c6, 0x2d60, 0x080c, + 0xa01c, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x00c8, 0x080c, 0xc44d, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, + 0x080c, 0x3095, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, + 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3095, 0x0868, + 0x080c, 0xa01c, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, + 0x0002, 0xbd29, 0xbd29, 0xbd2d, 0xbd2b, 0xbd37, 0xbd29, 0xbd29, + 0xa01c, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, + 0xbd29, 0x080c, 0x0df6, 0x080c, 0x9a8f, 0x6114, 0x0096, 0x2148, + 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x601c, + 0xd084, 0x190c, 0x192c, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282, + 0x1cd0, 0x0240, 0x2001, 0x1819, 0x2004, 0x9202, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, + 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, + 0x0110, 0x080c, 0x10e2, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, + 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7350, 0x7070, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, + 0x080c, 0xc459, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, + 0x0004, 0x1148, 0x080c, 0x3095, 0x080c, 0xc46e, 0x00c6, 0x080c, + 0xa01c, 0x00ce, 0x0060, 0x080c, 0xc144, 0x0148, 0x080c, 0xbf56, + 0x1110, 0x080c, 0xa9a7, 0x00c6, 0x080c, 0x9fea, 0x00ce, 0x9ce0, + 0x0018, 0x7064, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, + 0x210c, 0x81ff, 0x0128, 0x2061, 0x1a88, 0x6112, 0x080c, 0x3095, + 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x01b0, 0x6656, + 0x2b00, 0x6012, 0x080c, 0x54e3, 0x0118, 0x080c, 0xbe7d, 0x0168, + 0x080c, 0xc1ca, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xa026, 0x01b8, 0x660a, 0x2b08, - 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, - 0x2c78, 0x080c, 0x165d, 0x00fe, 0x2009, 0x0021, 0x080c, 0xa053, - 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, - 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0x9f7f, - 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001, - 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001, - 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, - 0x2091, 0x8000, 0x080c, 0xa026, 0x0188, 0x2b08, 0x6112, 0x080c, - 0xc1b7, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, - 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, - 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, - 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, - 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, - 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, - 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, - 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xbd3b, 0x0180, 0xa864, - 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, - 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, - 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0xa026, 0x0198, 0x2b08, 0x6112, 0x080c, 0xc1b7, - 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x30ab, 0x2009, 0x0028, - 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1823, 0x2204, 0x9086, - 0x0074, 0x1178, 0x00b6, 0x080c, 0xac3a, 0x00be, 0x080c, 0xae86, - 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, - 0x2001, 0x0001, 0x080c, 0xc37d, 0x080c, 0xa995, 0x080c, 0x9fd5, - 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030, - 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x080c, - 0x9fd5, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, - 0x080c, 0x62f5, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1823, - 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, - 0x643f, 0x00be, 0x080c, 0xaf57, 0x1198, 0x6010, 0x00b6, 0x2058, - 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x62f5, - 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xa3e0, 0x0048, - 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xa995, 0x080c, - 0x9fd5, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, - 0x0e02, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, - 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, - 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c, - 0x9fd5, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030, - 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5, - 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, - 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, 0x6017, 0x0000, 0x6003, - 0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005, - 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120, - 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba5e, 0xc067, - 0xc067, 0xc06a, 0xd825, 0xd840, 0xd843, 0xba5e, 0xba5e, 0xba5e, - 0xba5e, 0xba5e, 0xba5e, 0xba5e, 0xba5e, 0x080c, 0x0e02, 0xa001, - 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, - 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1833, 0x2004, 0x9005, - 0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f7f, 0x0508, 0x7810, 0x6012, - 0x080c, 0xc1b7, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, - 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, - 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7954, 0x6156, - 0x080c, 0x85f9, 0x080c, 0x8b90, 0x2f60, 0x00fe, 0x0005, 0x2f60, - 0x00fe, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x0016, 0x0096, - 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, - 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, - 0xa87e, 0xa878, 0x2048, 0x080c, 0x0ff5, 0x6830, 0x6036, 0x908e, - 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, - 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, - 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, - 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, - 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, - 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, 0x6023, 0x0001, 0x6007, - 0x0039, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x009e, - 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, - 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, - 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, - 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, - 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, - 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, - 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, - 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, - 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, - 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x195c, - 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x847f, 0x2001, - 0x1960, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x195e, - 0x200c, 0x8000, 0x2014, 0x2071, 0x1946, 0x711a, 0x721e, 0x2001, - 0x0064, 0x080c, 0x847f, 0x2001, 0x1961, 0x82ff, 0x1110, 0x2011, - 0x0014, 0x2202, 0x2001, 0x1962, 0x9288, 0x000a, 0x2102, 0x2001, - 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x158c, 0x080c, 0x66ab, - 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, - 0x00e6, 0x2001, 0x1960, 0x2003, 0x0028, 0x2001, 0x1961, 0x2003, - 0x0014, 0x2071, 0x1946, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, - 0x1962, 0x2009, 0x001e, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001, - 0x0032, 0x080c, 0x158c, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, - 0x6058, 0x904d, 0x0110, 0x080c, 0x1075, 0x009e, 0x0005, 0x0005, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f, 0x0180, 0x2b08, - 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, - 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, - 0x1520, 0x708c, 0x9086, 0x0018, 0x0120, 0x708c, 0x9086, 0x0014, - 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, - 0x8d94, 0x01d8, 0x7078, 0xaa50, 0x9206, 0x1160, 0x707c, 0xaa54, - 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, - 0x080c, 0x30f4, 0x080c, 0xa3e0, 0x0020, 0x080c, 0xa995, 0x080c, - 0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaa54, 0x9206, - 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f, - 0x0188, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x2900, - 0x6016, 0x2009, 0x004d, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x0016, 0x080c, 0x9f7f, 0x0180, 0x2b08, 0x6112, 0x080c, 0xc1b7, - 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xa053, 0x9085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, - 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, - 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x718c, 0x6014, 0x2048, - 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x197a, - 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, - 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, - 0x20a0, 0x2001, 0x197a, 0x0016, 0x200c, 0x080c, 0xca60, 0x001e, - 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, - 0x0103, 0x0010, 0x080c, 0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee, - 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, - 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, - 0x708c, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, - 0x8d94, 0x01a8, 0x7078, 0xaa74, 0x9206, 0x1130, 0x707c, 0xaa78, - 0x9206, 0x1110, 0x080c, 0x30ab, 0x080c, 0xa3e0, 0x0020, 0x080c, - 0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, - 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, - 0x1800, 0x9186, 0x0015, 0x1550, 0x708c, 0x9086, 0x0004, 0x1530, - 0x6014, 0x2048, 0x2c78, 0x080c, 0x8d94, 0x05f0, 0x7078, 0xaacc, - 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, 0x1160, 0x080c, 0x30ab, - 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548b, - 0x001e, 0x0010, 0x080c, 0x5276, 0x080c, 0xbd3b, 0x0508, 0xa87b, - 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xbd3b, - 0x01b8, 0x6014, 0x2048, 0x080c, 0x5276, 0x1d70, 0xa87b, 0x0030, - 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, - 0x8000, 0xa867, 0x0139, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5, - 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaad0, 0x9206, 0x0930, - 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, - 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, - 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, - 0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd3b, 0x0904, 0xc379, 0x0096, - 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, - 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, - 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, - 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, - 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, - 0x0fc0, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b8, - 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0, 0x00ce, 0x0090, 0xaa96, - 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, - 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, - 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6a16, 0x6017, 0x0000, - 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, - 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, - 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, - 0x080c, 0x266e, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, - 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4a18, 0x00a8, - 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, - 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, - 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, - 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, - 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xbd29, 0x01f0, - 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, - 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, - 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, - 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, - 0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff, 0x918e, 0x0002, - 0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e, 0x0001, 0x1128, - 0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x0005, 0x0036, 0x2019, - 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd3b, - 0x01c8, 0x080c, 0xbf26, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, - 0x0096, 0x2048, 0xa87c, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995, - 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, - 0x6a23, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, - 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, - 0x0020, 0xa87b, 0x0005, 0x080c, 0xc037, 0xa877, 0x0000, 0x0005, - 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, - 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, - 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, - 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e, - 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1960, 0x2004, 0x601a, - 0x0005, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x080c, 0x9fd5, - 0x0804, 0x8b90, 0x2001, 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, - 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, - 0x00c6, 0x2079, 0x19c2, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, - 0x84e3, 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, - 0x012e, 0x9085, 0x0001, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, - 0x0016, 0x1a0c, 0x0e02, 0x001b, 0x006e, 0x00be, 0x0005, 0xc4a7, - 0xcbbf, 0xcd3d, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4de, - 0xcdc1, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0x080c, - 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013, - 0x006e, 0x0005, 0xc4c2, 0xd310, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, - 0xc4c2, 0xc4c2, 0xd2bd, 0xd364, 0xc4c2, 0xd960, 0xd996, 0xd960, - 0xd996, 0xc4c2, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016, 0x1a0c, - 0x0e02, 0x6000, 0x000a, 0x0005, 0xc4dc, 0xcf9f, 0xd06e, 0xd091, - 0xd151, 0xc4dc, 0xd230, 0xd1d9, 0xcdcd, 0xd293, 0xd2a8, 0xc4dc, - 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0x080c, 0x0e02, 0x91b2, 0x0053, - 0x1a0c, 0x0e02, 0x2100, 0x91b2, 0x0040, 0x1a04, 0xc95c, 0x0002, - 0xc528, 0xc72a, 0xc528, 0xc528, 0xc528, 0xc733, 0xc528, 0xc528, - 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, - 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc52a, - 0xc58d, 0xc59c, 0xc600, 0xc62b, 0xc6a3, 0xc715, 0xc528, 0xc528, - 0xc736, 0xc528, 0xc528, 0xc74b, 0xc758, 0xc528, 0xc528, 0xc528, - 0xc528, 0xc528, 0xc7fe, 0xc528, 0xc528, 0xc812, 0xc528, 0xc528, - 0xc7cd, 0xc528, 0xc528, 0xc528, 0xc82a, 0xc528, 0xc528, 0xc528, - 0xc8a7, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc924, - 0x080c, 0x0e02, 0x080c, 0x6688, 0x1150, 0x2001, 0x1836, 0x2004, - 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, - 0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804, 0xc723, 0x080c, - 0x6671, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, - 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076, 0x903e, - 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e, 0x001e, - 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b3, - 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, - 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb10, - 0x002e, 0x001e, 0x1178, 0x080c, 0xd46e, 0x1904, 0xc5f8, 0x080c, - 0xd40a, 0x1120, 0x6007, 0x0008, 0x0804, 0xc723, 0x6007, 0x0009, - 0x0804, 0xc723, 0x080c, 0xd666, 0x0128, 0x080c, 0xd46e, 0x0d78, - 0x0804, 0xc5f8, 0x6017, 0x1900, 0x0c88, 0x080c, 0x31ce, 0x1904, - 0xc959, 0x6106, 0x080c, 0xd3bf, 0x6007, 0x0006, 0x0804, 0xc723, - 0x6007, 0x0007, 0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959, - 0x080c, 0x31ce, 0x1904, 0xc959, 0x00d6, 0x6610, 0x2658, 0xbe04, - 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, - 0x62e1, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, - 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, - 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, - 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, - 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, - 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4d1, - 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, - 0x900e, 0x080c, 0x30f4, 0x002e, 0x080c, 0x643f, 0x6007, 0x000a, - 0x00de, 0x0804, 0xc723, 0x6007, 0x000b, 0x00de, 0x0804, 0xc723, - 0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x0804, 0xc723, - 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959, - 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, - 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, - 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, - 0x080c, 0x30f4, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, - 0xdaef, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836, - 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537, - 0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, - 0x0006, 0x06c0, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x6321, - 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, - 0x9686, 0x0006, 0x1904, 0xc5f8, 0x080c, 0xd4de, 0x1120, 0x6007, - 0x000e, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, - 0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006, 0x2009, - 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x6010, - 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, - 0x0804, 0xc723, 0x2001, 0x0001, 0x080c, 0x62e1, 0x0156, 0x0016, - 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, - 0x080c, 0xaff7, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, - 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xc5f8, 0x9682, - 0x0007, 0x0a04, 0xc654, 0x0804, 0xc5f8, 0x6017, 0x1900, 0x6007, - 0x0009, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836, - 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537, - 0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, - 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, - 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x0698, 0x0150, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, - 0x1904, 0xc5f8, 0x080c, 0xd50c, 0x1138, 0x080c, 0xd40a, 0x1120, - 0x6007, 0x0010, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0, - 0x0046, 0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006, - 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6, - 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, - 0x0001, 0x0448, 0x080c, 0xd666, 0x0198, 0x0016, 0x968c, 0x00ff, - 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, - 0xff00, 0x8637, 0x9686, 0x0006, 0x0928, 0x0804, 0xc5f8, 0x001e, - 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x31ce, 0x1904, - 0xc959, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, - 0xc5f8, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, - 0x8b90, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641, - 0x080c, 0x8b90, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xd9d2, - 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959, 0x080c, 0xcafd, - 0x1904, 0xc5f8, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x8641, - 0x080c, 0x8b90, 0x0005, 0x080c, 0x31ce, 0x1904, 0xc959, 0x6007, - 0x0023, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0005, - 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959, - 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x0016, 0x0026, 0x00e6, 0x2071, - 0x0260, 0x2c08, 0x2011, 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0, - 0x2011, 0x181e, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, - 0x7240, 0x080c, 0xbd29, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, - 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, - 0x1508, 0x080c, 0x9fd5, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, - 0x2c08, 0x080c, 0xbd29, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, - 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, - 0x7240, 0x2c08, 0x9006, 0x080c, 0xd7a8, 0x1180, 0x7244, 0x9286, - 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, - 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, - 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0x9fd5, - 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, - 0x8b90, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, - 0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, - 0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xc723, 0x080c, 0xac52, - 0x080c, 0x717f, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199, - 0x1138, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0010, - 0x080c, 0x7157, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x31ce, - 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c, - 0xcb19, 0x1120, 0x6007, 0x002b, 0x0804, 0xc723, 0x6007, 0x002c, - 0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, - 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c, - 0xcb1e, 0x1120, 0x6007, 0x002e, 0x0804, 0xc723, 0x6007, 0x002f, - 0x0804, 0xc723, 0x080c, 0x31ce, 0x1904, 0xc959, 0x00e6, 0x00d6, - 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, - 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, - 0x00de, 0x00ee, 0x0804, 0xc72a, 0x080c, 0x54e0, 0xd0e4, 0x0904, - 0xc8a4, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, - 0x720c, 0x080c, 0x66c6, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, - 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x66c2, 0x15b8, 0x2069, - 0x1800, 0x687c, 0x9206, 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, - 0x080c, 0xbd29, 0x0590, 0x080c, 0xc9ea, 0x0578, 0x080c, 0xd852, - 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x85f9, - 0x080c, 0x8b90, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, - 0xffff, 0x0150, 0x080c, 0xbd29, 0x01c0, 0x9280, 0x0002, 0x2004, - 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, - 0x080c, 0xd7a8, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, - 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, - 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, - 0x31ce, 0x1904, 0xc959, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, - 0x8007, 0x9086, 0x0006, 0x1904, 0xc72a, 0x00e6, 0x00d6, 0x00c6, - 0x080c, 0x54e0, 0xd0e4, 0x0904, 0xc91c, 0x2069, 0x1800, 0x2071, - 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, - 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd7a8, 0x2c10, - 0x00ce, 0x05e8, 0x080c, 0xbd29, 0x05d0, 0x7108, 0x9280, 0x0002, - 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xb967, - 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, - 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, - 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xc9ea, 0x0904, 0xc89d, - 0x0056, 0x7510, 0x7614, 0x080c, 0xd86b, 0x005e, 0x00ce, 0x00de, - 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, - 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0c78, 0x6007, - 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, - 0x6017, 0x0000, 0x0804, 0xc874, 0x00e6, 0x0026, 0x080c, 0x6688, - 0x0550, 0x080c, 0x6671, 0x080c, 0xda43, 0x1518, 0x2071, 0x1800, - 0x70d8, 0x9085, 0x0003, 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac, - 0x9284, 0x00ff, 0x707a, 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205, - 0x707e, 0x78ea, 0x00fe, 0x70e3, 0x0000, 0x080c, 0x66c6, 0x0120, - 0x2011, 0x19db, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e8c, - 0x0010, 0x080c, 0xda77, 0x002e, 0x00ee, 0x080c, 0x9fd5, 0x0804, - 0xc729, 0x080c, 0x9fd5, 0x0005, 0x2600, 0x0002, 0xc970, 0xc970, - 0xc970, 0xc970, 0xc970, 0xc972, 0xc970, 0xc970, 0xc970, 0xc970, - 0xc98c, 0xc970, 0xc970, 0xc970, 0xc99e, 0xc9b4, 0xc9e5, 0xc970, - 0x080c, 0x0e02, 0x080c, 0xd9d2, 0x1d20, 0x080c, 0x31ce, 0x1d08, - 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x8641, - 0x0005, 0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x6003, - 0x0001, 0x080c, 0x8641, 0x0005, 0x080c, 0xd9d2, 0x1950, 0x080c, - 0x31ce, 0x1938, 0x080c, 0xcafd, 0x1d60, 0x703c, 0x6016, 0x6007, - 0x004a, 0x6003, 0x0001, 0x080c, 0x8641, 0x0005, 0x2001, 0x1823, - 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xca07, 0x0904, 0xc959, - 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, - 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, - 0x7140, 0x2001, 0x1998, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, - 0x1999, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, - 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, - 0x080c, 0xb00b, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, - 0x080c, 0x8641, 0x080c, 0x8b90, 0x0005, 0x6007, 0x0050, 0x703c, - 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, - 0x2260, 0x6010, 0x2058, 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044, - 0x9106, 0x1120, 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, - 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, - 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x197a, 0x2003, 0x0000, - 0x080c, 0x105c, 0x05a0, 0x2900, 0x6016, 0x708c, 0x8004, 0xa816, - 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016, - 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x105c, - 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016, - 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, - 0x1800, 0x708f, 0x0000, 0x6014, 0x2048, 0x080c, 0x0ff5, 0x9006, - 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, - 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, - 0x080c, 0x21dd, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, - 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, - 0x8108, 0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21dd, - 0x2061, 0x197a, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, - 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, - 0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x197a, 0x2019, - 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, - 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, - 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, - 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x21f5, 0x20a1, - 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, - 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, - 0x21f5, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x21f5, 0x2061, 0x197d, - 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, - 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, - 0x21f5, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x197d, 0x2019, 0x0260, - 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, - 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, - 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, - 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, - 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, - 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, - 0x0005, 0x00d6, 0x080c, 0xcb95, 0x00de, 0x0005, 0x00d6, 0x080c, - 0xcba2, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, - 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, - 0xdaef, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, - 0x00ff, 0x6824, 0x080c, 0x266e, 0x1148, 0x2001, 0x0001, 0x080c, - 0xdaef, 0x2110, 0x900e, 0x080c, 0x30f4, 0x0018, 0x9085, 0x0001, - 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa026, - 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, - 0x220c, 0x080c, 0x266e, 0x1578, 0x080c, 0x6344, 0x1560, 0xbe12, - 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xd9d2, - 0x11d8, 0x080c, 0x31ce, 0x11c0, 0x080c, 0xcafd, 0x0510, 0x2001, - 0x0007, 0x080c, 0x62f5, 0x2001, 0x0007, 0x080c, 0x6321, 0x6017, - 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, - 0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x9085, 0x0001, - 0x00ce, 0x00be, 0x0005, 0x080c, 0x9fd5, 0x00ce, 0x002e, 0x001e, - 0x0ca8, 0x080c, 0x9fd5, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, - 0x9082, 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, - 0x9006, 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, - 0xff00, 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, - 0x9186, 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, - 0x615a, 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, - 0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013, 0x1130, 0x2008, - 0x91b2, 0x0040, 0x1a04, 0xcd0d, 0x040a, 0x91b6, 0x0027, 0x0198, - 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a, - 0x0128, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9dc, 0x0005, 0x91b6, - 0x0014, 0x190c, 0x0e02, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, - 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0xcc2e, 0xcc30, - 0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc3f, 0xcd06, 0xcc91, 0xcd06, - 0xccb7, 0xcd06, 0xcc3f, 0xcd06, 0xccfe, 0xcd06, 0xccfe, 0xcd06, - 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, - 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc2e, 0xcd06, 0xcc2e, - 0xcc2e, 0xcd06, 0xcc2e, 0xcd03, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, - 0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcc3a, - 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcd02, 0xcd06, 0xcc2e, 0xcc2e, - 0xcd06, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0x080c, 0x0e02, - 0x080c, 0x8a84, 0x080c, 0xc45c, 0x6003, 0x0002, 0x080c, 0x8b90, - 0x0804, 0xcd0c, 0x9006, 0x080c, 0x62e1, 0x0804, 0xcd06, 0x080c, - 0x66c2, 0x1904, 0xcd06, 0x9006, 0x080c, 0x62e1, 0x6010, 0x2058, - 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4, - 0x8000, 0x78a6, 0x00fe, 0x0428, 0x6010, 0x2058, 0xb8b0, 0x9005, - 0x1178, 0x080c, 0xc444, 0x1904, 0xcd06, 0x0036, 0x0046, 0xbba0, - 0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e, 0x0804, 0xcd06, - 0x080c, 0x31ff, 0x1904, 0xcd06, 0x2001, 0x1800, 0x2004, 0x9086, - 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, - 0x00fe, 0x2001, 0x0002, 0x080c, 0x62f5, 0x080c, 0x8a84, 0x6023, - 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, - 0x8b90, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8268, 0x0804, - 0xcd0c, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, - 0x0006, 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c, - 0x6321, 0x080c, 0xdb3e, 0x0904, 0xcd06, 0x080c, 0x8a84, 0x2001, - 0x0004, 0x080c, 0x62f5, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0003, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0804, 0xcd0c, 0x2001, - 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, - 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e, 0x003e, - 0x2001, 0x0006, 0x080c, 0xcd2a, 0x6610, 0x2658, 0xbe04, 0x0066, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, - 0x0006, 0x080c, 0x6321, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, - 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x66c2, 0x11f8, 0x2001, - 0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, - 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, - 0x00fe, 0x0804, 0xcc79, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, - 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6321, 0x080c, 0x8a84, - 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x2600, 0x0002, 0xcd21, - 0xcd21, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21, - 0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd23, 0xcd23, - 0xcd23, 0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0x9fd5, 0x080c, - 0x8b90, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, - 0xd184, 0x0138, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x080c, - 0x30d4, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, - 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x91b6, - 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0e02, - 0x006b, 0x0005, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xcdbf, 0xaa76, - 0xcda9, 0xcd6a, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76, - 0xaa76, 0xaa76, 0xcdbf, 0xaa76, 0xcda9, 0xcdb0, 0xaa76, 0xaa76, - 0xaa76, 0xaa76, 0x00f6, 0x080c, 0x66c2, 0x11d8, 0x080c, 0xc444, - 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, 0x0190, 0x9006, - 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001, - 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90, - 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266e, - 0x11b0, 0x080c, 0x63a4, 0x0118, 0x080c, 0x9fd5, 0x0080, 0xb810, - 0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, 0x5e4a, 0x000e, - 0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0x9fd5, 0x00fe, - 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005, - 0x080c, 0xae83, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, - 0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x0005, 0x0804, - 0x9fd5, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02, 0x080c, 0x8a84, - 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0040, 0x0002, - 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde6, 0xcde4, 0xcde4, 0xcde4, - 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, - 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0x080c, 0x0e02, 0x0096, 0x00b6, - 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8ac, - 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, - 0x0904, 0xce4c, 0x080c, 0xdae3, 0x1170, 0x9486, 0x2000, 0x1158, - 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8451, 0x0020, 0x9026, - 0x080c, 0xda17, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x6003, - 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, - 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, - 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, - 0x080c, 0x6a23, 0x001e, 0x080c, 0xdae3, 0x1904, 0xceac, 0x9486, - 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd74e, 0x0804, 0xceac, - 0x9486, 0x0200, 0x1120, 0x080c, 0xd6e5, 0x0804, 0xceac, 0x9486, - 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceac, 0x2019, 0x0002, - 0x080c, 0xd700, 0x0804, 0xceac, 0x2069, 0x1a4c, 0x6a00, 0xd284, - 0x0904, 0xcf16, 0x9284, 0x0300, 0x1904, 0xcf0f, 0x6804, 0x9005, - 0x0904, 0xcef7, 0x2d78, 0x6003, 0x0007, 0x080c, 0x105c, 0x0904, - 0xceb8, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, - 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xcf1a, 0x9006, - 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, - 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, - 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, - 0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005, 0xa87e, 0x20a9, - 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, - 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, - 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, - 0x200c, 0xa9ae, 0x080c, 0x6a23, 0x002e, 0x004e, 0x00fe, 0x00ee, - 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, - 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x1043, 0x1904, - 0xce61, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, - 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, - 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, - 0x6007, 0x0043, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0828, 0x6868, - 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, - 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x2001, - 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18, - 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, - 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x6017, - 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xcecc, 0x6017, 0xf200, - 0x0804, 0xcecc, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, - 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005, - 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, - 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, - 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, - 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, - 0x1a0c, 0x0e02, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xcf96, 0x2041, - 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, - 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, - 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x105c, 0x0170, - 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, - 0x902d, 0x0118, 0x080c, 0x1075, 0x0cc8, 0x080c, 0x1075, 0x0804, - 0xceb8, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, - 0x200b, 0x0000, 0x080c, 0xd781, 0x0804, 0xceac, 0x8010, 0x0004, - 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, - 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x9082, - 0x0040, 0x0a0c, 0x0e02, 0x2008, 0x0804, 0xd025, 0x9186, 0x0051, - 0x0108, 0x0048, 0x080c, 0xc46a, 0x0500, 0x6000, 0x9086, 0x0002, - 0x11e0, 0x0804, 0xd06e, 0x9186, 0x0027, 0x0190, 0x9186, 0x0048, - 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0e02, 0x080c, 0xc46a, - 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0e02, 0x0804, 0xd151, - 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xa06e, 0x0005, - 0xcfec, 0xcfee, 0xcfee, 0xd015, 0xcfec, 0xcfec, 0xcfec, 0xcfec, - 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, - 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0x080c, 0x0e02, 0x080c, 0x8a84, - 0x080c, 0x8b90, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, - 0xbd3b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xd781, 0x6017, - 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961, 0x2004, 0x601a, - 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x8a84, - 0x080c, 0x8b90, 0x080c, 0xbd3b, 0x0120, 0x6014, 0x2048, 0x080c, - 0x1075, 0x080c, 0xa007, 0x009e, 0x0005, 0x0002, 0xd03a, 0xd051, - 0xd03c, 0xd068, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, - 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, - 0xd03a, 0xd03a, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84, 0x6014, - 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, - 0x080c, 0xa053, 0x0010, 0x6003, 0x0004, 0x080c, 0x8b90, 0x009e, - 0x0005, 0x080c, 0x8a84, 0x080c, 0xbd3b, 0x0138, 0x6114, 0x0096, - 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8426, 0x080c, - 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xd9db, 0x0db0, 0x0cc8, - 0x080c, 0x8a84, 0x2009, 0x0041, 0x0804, 0xd1d9, 0x9182, 0x0040, - 0x0002, 0xd085, 0xd087, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, - 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, - 0xd085, 0xd085, 0xd088, 0xd085, 0xd085, 0x080c, 0x0e02, 0x0005, - 0x00d6, 0x080c, 0x8426, 0x00de, 0x080c, 0xda33, 0x080c, 0x9fd5, - 0x0005, 0x9182, 0x0040, 0x0002, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, - 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0aa, 0xd119, 0xd0a8, - 0xd0a8, 0xd0a8, 0xd0a8, 0xd119, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, - 0x080c, 0x0e02, 0x2001, 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, - 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004, 0x9105, 0x1904, - 0xd119, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904, 0xd119, 0xc0d4, - 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, - 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, - 0x080c, 0x8b40, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, - 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001, 0x180c, 0x2004, - 0xd0d4, 0x11e0, 0x080c, 0x8c6d, 0x2009, 0x0041, 0x009e, 0x0804, - 0xd1d9, 0x080c, 0x8c6d, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, - 0x8426, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9082, 0x0005, - 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890, 0x2001, 0x180c, - 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c, 0x2aca, 0x080c, - 0x8c6d, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8426, - 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xd9db, 0x0db8, 0x009e, - 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, - 0x8b40, 0x080c, 0x8c6d, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, - 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, - 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, - 0x080c, 0xd781, 0x6018, 0x9005, 0x1128, 0x2001, 0x1961, 0x2004, - 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, - 0x0005, 0x9182, 0x0040, 0x0002, 0xd168, 0xd168, 0xd168, 0xd168, - 0xd168, 0xd168, 0xd168, 0xd168, 0xd16a, 0xd168, 0xd168, 0xd168, - 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd1b5, - 0x080c, 0x0e02, 0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, - 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, - 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xd1d9, - 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8426, 0x009e, 0x0005, - 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, - 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, - 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, - 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, - 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, 0x8428, 0x009e, - 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, - 0x080c, 0x1583, 0x1904, 0xd16a, 0x0005, 0x6014, 0x0096, 0x2048, - 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, 0x1583, 0x1904, - 0xd16a, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, - 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, - 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, - 0x9186, 0x0014, 0x190c, 0x0e02, 0x6024, 0xd0dc, 0x090c, 0x0e02, - 0x0005, 0xd1fd, 0xd209, 0xd215, 0xd221, 0xd1fd, 0xd1fd, 0xd1fd, - 0xd1fd, 0xd204, 0xd1ff, 0xd1ff, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fd, - 0xd1ff, 0xd1fd, 0xd1ff, 0xd1fd, 0xd204, 0x080c, 0x0e02, 0x6024, - 0xd0dc, 0x090c, 0x0e02, 0x0005, 0x6014, 0x9005, 0x190c, 0x0e02, - 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, - 0x8000, 0x080c, 0x8b90, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, - 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b90, 0x012e, - 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x0126, - 0x2091, 0x8000, 0x080c, 0x865e, 0x080c, 0x8c6d, 0x012e, 0x0005, - 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, - 0x009e, 0x003e, 0x012e, 0x0005, 0xd250, 0xd252, 0xd264, 0xd27e, - 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, - 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, - 0x080c, 0x0e02, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, - 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, - 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, - 0x6106, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x00e0, 0x901e, 0x6316, - 0x631a, 0x2019, 0x0004, 0x080c, 0xd781, 0x00a0, 0x6014, 0x2048, - 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, - 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e, - 0x080c, 0x8c6d, 0x0005, 0x080c, 0x8a84, 0x6114, 0x81ff, 0x0158, - 0x0096, 0x2148, 0x080c, 0xda80, 0x0036, 0x2019, 0x0029, 0x080c, - 0xd781, 0x003e, 0x009e, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, - 0x080c, 0x8b40, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, - 0xda80, 0x0036, 0x2019, 0x0029, 0x080c, 0xd781, 0x003e, 0x009e, - 0x080c, 0xa007, 0x080c, 0x8c6d, 0x0005, 0x9182, 0x0085, 0x0002, - 0xd2cf, 0xd2cd, 0xd2cd, 0xd2db, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, - 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0x080c, 0x0e02, 0x6003, - 0x000b, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c, - 0x8b90, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xd9d2, 0x0118, - 0x080c, 0x9fd5, 0x0450, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, - 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, - 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa2f9, 0x7220, 0x080c, - 0xd61c, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, - 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x080c, 0x8c6d, 0x00ee, 0x002e, 0x0005, - 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02, - 0x908a, 0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00a2, 0x9186, - 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xa06e, 0x0050, - 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x8a84, 0x080c, 0xa007, - 0x080c, 0x8b90, 0x0005, 0xd340, 0xd342, 0xd342, 0xd340, 0xd340, - 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, - 0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, - 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0e02, 0x9182, 0x0092, 0x1a0c, - 0x0e02, 0x9182, 0x0085, 0x0002, 0xd361, 0xd361, 0xd361, 0xd363, - 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, - 0xd361, 0x080c, 0x0e02, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, - 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030, - 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0036, - 0x080c, 0xda33, 0x6043, 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, - 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, - 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e, - 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x99f5, 0x007e, 0x1520, - 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, - 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda33, 0x080c, 0xc45c, - 0x080c, 0x1938, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b, - 0x0110, 0x080c, 0xd781, 0x009e, 0x6017, 0x0000, 0x080c, 0xda33, - 0x6023, 0x0007, 0x080c, 0xc45c, 0x003e, 0x012e, 0x0005, 0x00f6, - 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, - 0x080c, 0x266e, 0x15c8, 0x0016, 0x00c6, 0x080c, 0x63a4, 0x1590, - 0x001e, 0x00c6, 0x2160, 0x080c, 0xc459, 0x00ce, 0x002e, 0x0026, - 0x0016, 0x2019, 0x0029, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076, - 0x903e, 0x080c, 0x8671, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, - 0xd53b, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, - 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x3168, - 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e4a, 0xbe12, 0xbd16, 0xbcb2, - 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, - 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1823, - 0x2104, 0x9086, 0x0074, 0x1904, 0xd463, 0x2069, 0x0260, 0x6944, - 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xd460, - 0x2001, 0x1956, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb8b0, - 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, - 0x0648, 0x080c, 0xdae8, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, - 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, - 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, - 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, - 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, - 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, - 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, - 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, - 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, - 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, - 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, - 0x63b3, 0x0804, 0xd4ca, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x15a0, 0x2011, - 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, - 0xb00b, 0x009e, 0x1540, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, - 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, 0x0029, 0x080c, 0xd7d6, - 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076, - 0x2039, 0x0000, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, - 0x2001, 0x0007, 0x080c, 0x6321, 0x2001, 0x0007, 0x080c, 0x62f5, - 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, - 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, - 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, - 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, - 0x080c, 0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0270, - 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, - 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, - 0x2019, 0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e, - 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, - 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, - 0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0276, 0x20a9, - 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, - 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, - 0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, - 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, - 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, - 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, - 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1a88, - 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xd5d5, 0x0018, 0x9606, - 0x0904, 0xd5d5, 0x2100, 0x9c06, 0x0904, 0xd5cc, 0x6720, 0x9786, - 0x0007, 0x0904, 0xd5cc, 0x080c, 0xd817, 0x1904, 0xd5cc, 0x080c, - 0xdb06, 0x0904, 0xd5cc, 0x080c, 0xd807, 0x0904, 0xd5cc, 0x6720, - 0x9786, 0x0001, 0x1148, 0x080c, 0x31ff, 0x0904, 0xd5f0, 0x6004, - 0x9086, 0x0000, 0x1904, 0xd5f0, 0x9786, 0x0004, 0x0904, 0xd5f0, - 0x2500, 0x9c06, 0x0904, 0xd5cc, 0x2400, 0x9c06, 0x05e8, 0x88ff, - 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004, - 0x1120, 0x0016, 0x080c, 0x1938, 0x001e, 0x9786, 0x000a, 0x0148, - 0x080c, 0xbf43, 0x1130, 0x080c, 0xa995, 0x009e, 0x080c, 0xa007, - 0x0418, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x01d8, 0x9786, 0x0003, - 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, - 0x2048, 0x080c, 0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, - 0xda80, 0x0016, 0x080c, 0xc031, 0x080c, 0x6a16, 0x001e, 0x080c, - 0xbf26, 0x009e, 0x080c, 0xa007, 0x9ce0, 0x0018, 0x2001, 0x1819, - 0x2004, 0x9c02, 0x1210, 0x0804, 0xd54f, 0x012e, 0x002e, 0x004e, - 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, - 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xda80, 0x080c, - 0xd781, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x000a, 0x0968, 0x0808, - 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0130, - 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1970, 0x6000, 0x9086, - 0x0002, 0x1950, 0x080c, 0xbf32, 0x0130, 0x080c, 0xbf43, 0x1920, - 0x080c, 0xa995, 0x0038, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1110, - 0x080c, 0xa995, 0x080c, 0xa007, 0x0804, 0xd5cc, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08, - 0x2170, 0x9006, 0x080c, 0xd7a8, 0x001e, 0x0120, 0x6020, 0x9084, - 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd63b, 0xd63b, 0xd63b, - 0xd63b, 0xd63b, 0xd63b, 0xd63d, 0xd63b, 0xd63b, 0xd63b, 0xd63b, - 0xa007, 0xa007, 0xd63b, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, - 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020, - 0x080c, 0xd7d6, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, 0xd385, - 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xbd3b, 0x0140, - 0x6014, 0x904d, 0x080c, 0xb974, 0x687b, 0x0005, 0x080c, 0x6a23, - 0x009e, 0x080c, 0xa007, 0x9085, 0x0001, 0x0005, 0x2001, 0x0001, - 0x080c, 0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, - 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e, - 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, - 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, - 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd6d8, 0x2071, 0x1800, - 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd6d8, 0x88ff, 0x0120, - 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd807, 0x0580, 0x2400, - 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, - 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, - 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, - 0x0140, 0x080c, 0xda33, 0x080c, 0xc45c, 0x080c, 0x1938, 0x6023, - 0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0120, 0x0046, 0x080c, - 0xd781, 0x004e, 0x009e, 0x080c, 0xa007, 0x88ff, 0x1198, 0x9ce0, - 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd68b, - 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, - 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056, - 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, - 0x2258, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, - 0x080c, 0x99f5, 0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005, - 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, - 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a4, 0x1180, - 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, - 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x005e, - 0x003e, 0x001e, 0x8108, 0x1f04, 0xd70b, 0x0036, 0x2508, 0x2029, - 0x0003, 0x080c, 0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, - 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, - 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, - 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x2c20, - 0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, - 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, - 0x0016, 0x0036, 0x080c, 0x63a4, 0x1190, 0x0086, 0x9046, 0x2828, - 0x0046, 0x2021, 0x0001, 0x080c, 0xda17, 0x004e, 0x0096, 0x904e, - 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x003e, - 0x001e, 0x8108, 0x1f04, 0xd758, 0x0036, 0x2029, 0x0002, 0x080c, - 0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, - 0x0005, 0x0016, 0x00f6, 0x080c, 0xbd39, 0x0198, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, - 0x0000, 0xab82, 0x080c, 0x6a23, 0x2f48, 0x0cb0, 0xab82, 0x080c, - 0x6a23, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, - 0x0000, 0x080c, 0x6a23, 0x2f48, 0x0cb8, 0x080c, 0x6a23, 0x0c88, - 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071, - 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, - 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, 0x1130, - 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, - 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, - 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, 0x0006, - 0x080c, 0x1043, 0x000e, 0x090c, 0x0e02, 0xaae2, 0xa867, 0x010d, - 0xa88e, 0x0026, 0x2010, 0x080c, 0xbd29, 0x2001, 0x0000, 0x0120, - 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, - 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, - 0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x0005, 0x6700, - 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, - 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, - 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, - 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, - 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, - 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1961, - 0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x001e, 0x0005, - 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, - 0x080c, 0xc075, 0x0030, 0x080c, 0xda33, 0x080c, 0x8426, 0x080c, - 0x9fd5, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, - 0xd866, 0xd866, 0xd866, 0xd868, 0xd866, 0xd868, 0xd868, 0xd866, - 0xd868, 0xd866, 0xd866, 0xd866, 0xd866, 0xd866, 0x9006, 0x0005, - 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, - 0x0002, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd88c, - 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0x6007, + 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xa03b, 0x0560, 0x6057, + 0x0000, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0003, 0x0016, + 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08, 0x080c, + 0xd556, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x9fea, 0x9085, + 0x0001, 0x0070, 0x080c, 0x54e3, 0x0128, 0xd18c, 0x1170, 0x080c, + 0xbe7d, 0x0148, 0x2009, 0x004c, 0x080c, 0xa068, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, + 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, + 0x0016, 0x080c, 0x9f94, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xbe8f, 0x001e, + 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x195a, + 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0x9fea, 0x00d0, 0x2001, + 0x1959, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0088, + 0x2f60, 0x080c, 0x54e3, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, + 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xa068, 0x9085, + 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, + 0x0046, 0x080c, 0x9f94, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, + 0x1958, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0060, + 0x2f60, 0x080c, 0x54e3, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, + 0x2009, 0x0052, 0x080c, 0xa068, 0x9085, 0x0001, 0x004e, 0x00ce, + 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b7, + 0x00ce, 0x1120, 0x080c, 0x9fea, 0x9006, 0x0005, 0xa867, 0x0000, + 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, + 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x64d7, 0x0158, 0x2001, + 0xbe94, 0x0006, 0x900e, 0x2400, 0x080c, 0x6c6b, 0x080c, 0x6a22, + 0x000e, 0x0807, 0x2418, 0x080c, 0x8a1d, 0xbaa0, 0x0086, 0x2041, + 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x879a, 0x008e, 0x080c, + 0x8670, 0x2f08, 0x2648, 0x080c, 0xd556, 0xb93c, 0x81ff, 0x090c, + 0x886d, 0x080c, 0x8b8f, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x0190, 0x660a, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, + 0x001f, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, + 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0008, + 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x2009, + 0x0021, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, + 0x8000, 0x080c, 0x9f94, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, + 0xa068, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x0000, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, + 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, + 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, + 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, + 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, + 0xbd4e, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, + 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, + 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0198, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, + 0x3095, 0x2009, 0x0028, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, + 0x1823, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xac41, + 0x00be, 0x080c, 0xae8d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, + 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xc390, 0x080c, + 0xa9a7, 0x080c, 0x9fea, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, + 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x009e, 0x080c, 0x9fea, 0x0c30, 0x0096, 0x9186, 0x0016, + 0x1128, 0x2001, 0x0004, 0x080c, 0x62f4, 0x00e8, 0x9186, 0x0015, + 0x1510, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, + 0x00b6, 0x2058, 0x080c, 0x643e, 0x00be, 0x080c, 0xaf63, 0x1198, + 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, + 0x0006, 0x080c, 0x62f4, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, + 0x080c, 0xa3f2, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, + 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x009e, 0x0005, 0x6014, 0x6310, + 0x2358, 0x904d, 0x090c, 0x0df6, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x080c, 0x9fea, 0x08f8, 0x6014, 0x904d, 0x090c, + 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x080c, 0x9fea, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, + 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, + 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, + 0x0005, 0xba6d, 0xc07a, 0xc07a, 0xc07d, 0xd886, 0xd8a1, 0xd8a4, + 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, + 0x080c, 0x0df6, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, + 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, + 0x1833, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f94, + 0x0508, 0x7810, 0x6012, 0x080c, 0xc1ca, 0x7820, 0x9086, 0x0003, + 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, + 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, + 0x0001, 0x7954, 0x6156, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2f60, + 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1962, 0x2004, 0x6042, + 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, + 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, + 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fe9, + 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, + 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, + 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, + 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, + 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, + 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, + 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, + 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, + 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, + 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, + 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, + 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, + 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, + 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, + 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, + 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, + 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00e6, 0x2001, 0x195c, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, + 0x080c, 0x847e, 0x2001, 0x1960, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x195e, 0x200c, 0x8000, 0x2014, 0x2071, 0x1946, + 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x847e, 0x2001, 0x1961, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1962, 0x9288, + 0x000a, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, + 0x1580, 0x080c, 0x66aa, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1960, 0x2003, 0x0028, + 0x2001, 0x1961, 0x2003, 0x0014, 0x2071, 0x1946, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1962, 0x2009, 0x001e, 0x2102, 0x2001, + 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x1580, 0x00ee, 0x001e, + 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1069, + 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, + 0x9f94, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, + 0x6016, 0x2009, 0x0033, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1520, 0x708c, 0x9086, 0x0018, 0x0120, + 0x708c, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, + 0x1160, 0x2c78, 0x080c, 0x8d93, 0x01d8, 0x7078, 0xaa50, 0x9206, + 0x1160, 0x707c, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x900e, 0x080c, 0x30de, 0x080c, 0xa3f2, 0x0020, + 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005, + 0x705c, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9f94, 0x0188, 0x2b08, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xa068, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x9f94, 0x0180, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, + 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, + 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, + 0x718c, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, + 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, + 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, + 0x080c, 0xca75, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, + 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xa9a7, 0x080c, + 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x11b8, 0x708c, 0x9086, 0x0004, 0x1198, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x8d93, 0x01a8, 0x7078, 0xaa74, 0x9206, + 0x1130, 0x707c, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3095, 0x080c, + 0xa3f2, 0x0020, 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee, + 0x009e, 0x0005, 0x705c, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x708c, + 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x8d93, + 0x05f0, 0x7078, 0xaacc, 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, + 0x1160, 0x080c, 0x3095, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, + 0xc0fd, 0x080c, 0x548a, 0x001e, 0x0010, 0x080c, 0x5275, 0x080c, + 0xbd4e, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x0080, 0x080c, 0xbd4e, 0x01b8, 0x6014, 0x2048, 0x080c, 0x5275, + 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6a22, + 0x012e, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, + 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, + 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, + 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, + 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd4e, + 0x0904, 0xc38c, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, + 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, + 0xd0f4, 0x1140, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9, 0x0004, 0xa85c, 0x9080, + 0x0035, 0x20a0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4, + 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, + 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, + 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, + 0x6a15, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, + 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, + 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, + 0x9084, 0x00ff, 0x900e, 0x080c, 0x266d, 0x2118, 0x831f, 0x939c, + 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, + 0x080c, 0x4a17, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, + 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, + 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, + 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, + 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, + 0x080c, 0xbd3c, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, + 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, + 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, + 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, + 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c, + 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e, + 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, + 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd4e, 0x01c8, 0x080c, 0xbf39, + 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, + 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0040, 0xa867, 0x0103, + 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6a22, 0x009e, 0x003e, + 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, + 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, + 0x080c, 0xc04a, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, + 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0007, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, + 0x0005, 0x2001, 0x1960, 0x2004, 0x601a, 0x0005, 0x2001, 0x1962, + 0x2004, 0x6042, 0x0005, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x2001, + 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19c2, + 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x84e2, 0x00ce, 0x00ee, + 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, + 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6, + 0x001b, 0x006e, 0x00be, 0x0005, 0xc4bc, 0xcbd4, 0xcd47, 0xc4bc, + 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4f3, 0xcdcb, 0xc4bc, 0xc4bc, + 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0x080c, 0x0df6, 0x0066, 0x6000, + 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xc4d7, + 0xd31a, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xd2c7, + 0xd36e, 0xc4d7, 0xd9c1, 0xd9f7, 0xd9c1, 0xd9f7, 0xc4d7, 0x080c, + 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000, 0x000a, + 0x0005, 0xc4f1, 0xcfa9, 0xd078, 0xd09b, 0xd15b, 0xc4f1, 0xd23a, + 0xd1e3, 0xcdd7, 0xd29d, 0xd2b2, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, + 0xc4f1, 0x080c, 0x0df6, 0x91b2, 0x0053, 0x1a0c, 0x0df6, 0x2100, + 0x91b2, 0x0040, 0x1a04, 0xc971, 0x0002, 0xc53d, 0xc73f, 0xc53d, + 0xc53d, 0xc53d, 0xc748, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53f, 0xc5a2, 0xc5b1, 0xc615, + 0xc640, 0xc6b8, 0xc72a, 0xc53d, 0xc53d, 0xc74b, 0xc53d, 0xc53d, + 0xc760, 0xc76d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc813, + 0xc53d, 0xc53d, 0xc827, 0xc53d, 0xc53d, 0xc7e2, 0xc53d, 0xc53d, + 0xc53d, 0xc83f, 0xc53d, 0xc53d, 0xc53d, 0xc8bc, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc939, 0x080c, 0x0df6, 0x080c, + 0x6687, 0x1150, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, + 0x6017, 0x0000, 0x0804, 0xc738, 0x080c, 0x6670, 0x00e6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, + 0x0029, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b2, 0xbe04, 0x9684, 0x00ff, + 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb71, 0x002e, 0x001e, 0x1178, + 0x080c, 0xd489, 0x1904, 0xc60d, 0x080c, 0xd425, 0x1120, 0x6007, + 0x0008, 0x0804, 0xc738, 0x6007, 0x0009, 0x0804, 0xc738, 0x080c, + 0xd6c7, 0x0128, 0x080c, 0xd489, 0x0d78, 0x0804, 0xc60d, 0x6017, + 0x1900, 0x0c88, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6106, 0x080c, + 0xd3c9, 0x6007, 0x0006, 0x0804, 0xc738, 0x6007, 0x0007, 0x0804, + 0xc738, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904, + 0xc96e, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x62e0, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, + 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, + 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, + 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4ec, 0x1190, 0x9686, 0x0006, + 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de, + 0x002e, 0x080c, 0x643e, 0x6007, 0x000a, 0x00de, 0x0804, 0xc738, + 0x6007, 0x000b, 0x00de, 0x0804, 0xc738, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x6007, 0x0001, 0x0804, 0xc738, 0x080c, 0xda33, 0x1904, + 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x2071, 0x0260, 0x7034, + 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, + 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, + 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de, 0x002e, + 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xdb50, 0x0804, 0xc738, + 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138, + 0x0026, 0x2001, 0x0006, 0x080c, 0x6320, 0x002e, 0x0050, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, + 0xc60d, 0x080c, 0xd4f9, 0x1120, 0x6007, 0x000e, 0x0804, 0xc738, + 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048, + 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800, 0xc0e5, + 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xc738, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xb003, 0x003e, + 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, + 0x9682, 0x0004, 0x0a04, 0xc60d, 0x9682, 0x0007, 0x0a04, 0xc669, + 0x0804, 0xc60d, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xc738, + 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, + 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, + 0x000e, 0x9082, 0x0006, 0x0698, 0x0150, 0x96b4, 0xff00, 0x8637, + 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc60d, 0x080c, + 0xd527, 0x1138, 0x080c, 0xd425, 0x1120, 0x6007, 0x0010, 0x0804, + 0xc738, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, + 0x0048, 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800, + 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, + 0xd6c7, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, + 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, + 0x0006, 0x0928, 0x0804, 0xc60d, 0x001e, 0x6017, 0x1900, 0x6007, + 0x0009, 0x0070, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xda33, + 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007, 0x0012, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0cb0, + 0x6007, 0x0005, 0x0c68, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c, + 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007, + 0x0020, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, + 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6007, 0x0023, 0x6003, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda33, 0x1904, + 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, + 0xc60d, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, + 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181e, 0x2214, + 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xbd3c, + 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, + 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0x9fea, + 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xbd3c, + 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, + 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, + 0x080c, 0xd809, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, + 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, + 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, + 0x9086, 0x0024, 0x1110, 0x080c, 0x9fea, 0x2160, 0x6007, 0x0025, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, + 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, + 0x080c, 0xb003, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, + 0x0031, 0x0804, 0xc738, 0x080c, 0xac59, 0x080c, 0x717e, 0x1190, + 0x0006, 0x0026, 0x0036, 0x080c, 0x7198, 0x1138, 0x080c, 0x747a, + 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010, 0x080c, 0x7156, 0x003e, + 0x002e, 0x000e, 0x0005, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, + 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb2e, 0x1120, 0x6007, + 0x002b, 0x0804, 0xc738, 0x6007, 0x002c, 0x0804, 0xc738, 0x080c, + 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, + 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb33, 0x1120, 0x6007, + 0x002e, 0x0804, 0xc738, 0x6007, 0x002f, 0x0804, 0xc738, 0x080c, + 0x31b8, 0x1904, 0xc96e, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, + 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, + 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, + 0xc73f, 0x080c, 0x54df, 0xd0e4, 0x0904, 0xc8b9, 0x2071, 0x026c, + 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x66c5, + 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, + 0x0510, 0x080c, 0x66c1, 0x15b8, 0x2069, 0x1800, 0x687c, 0x9206, + 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, 0x080c, 0xbd3c, 0x0590, + 0x080c, 0xc9ff, 0x0578, 0x080c, 0xd8b3, 0x0560, 0x622e, 0x6007, + 0x0036, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, + 0xbd3c, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, + 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10, + 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, + 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, + 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x31b8, 0x1904, 0xc96e, + 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, + 0x1904, 0xc73f, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x54df, 0xd0e4, + 0x0904, 0xc931, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, + 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, + 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10, 0x00ce, 0x05e8, 0x080c, + 0xbd3c, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, + 0x00c6, 0x0026, 0x2260, 0x080c, 0xb976, 0x002e, 0x00ce, 0x7118, + 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, + 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, + 0x0170, 0x080c, 0xc9ff, 0x0904, 0xc8b2, 0x0056, 0x7510, 0x7614, + 0x080c, 0xd8cc, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, - 0x85f9, 0x080c, 0x8b90, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, - 0xda33, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, - 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd8e5, - 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, - 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9, - 0x080c, 0x8b90, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, - 0xd95c, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, - 0x0e02, 0x0804, 0xd95c, 0x2048, 0x080c, 0xbd3b, 0x1130, 0x0028, - 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, - 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, - 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1d9, 0x0804, - 0xd95c, 0x2009, 0x0041, 0x0804, 0xd956, 0x9186, 0x0005, 0x15a0, - 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, - 0xd87f, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0e02, 0x0804, 0xd8a0, - 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, - 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, - 0x1904, 0xd95c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, - 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x165d, - 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1043, 0x090c, - 0x0e02, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, - 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, - 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, - 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, - 0xae96, 0xa89f, 0x0001, 0x080c, 0x6a23, 0x2019, 0x0045, 0x6008, - 0x2068, 0x080c, 0xd385, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, - 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, - 0x6003, 0x0007, 0x080c, 0xd1d9, 0x00ce, 0x00de, 0x009e, 0x0005, - 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, - 0x9186, 0x0027, 0x1178, 0x080c, 0x8a84, 0x0036, 0x0096, 0x6014, - 0x2048, 0x2019, 0x0004, 0x080c, 0xd781, 0x009e, 0x003e, 0x080c, - 0x8b90, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa06e, 0x0005, - 0xd98f, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98f, 0xd98d, - 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0x080c, 0x0e02, 0x080c, - 0x8a84, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0092, - 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa06e, 0x0005, - 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9af, 0xd9cf, 0xd9ad, 0xd9ad, - 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0x080c, 0x0e02, 0x00d6, - 0x2c68, 0x080c, 0x9f7f, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, - 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, - 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x85f9, - 0x080c, 0x8b90, 0x2d60, 0x080c, 0x9fd5, 0x00de, 0x0005, 0x080c, - 0x9fd5, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, 0x05b0, - 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, - 0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x1520, - 0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, - 0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001, 0x1960, - 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058, - 0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, - 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, - 0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, 0x84ff, - 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x8426, - 0x080c, 0x9fd5, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, - 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8ac, - 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, - 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182b, - 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, - 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, - 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, - 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x1168, 0x2011, 0x0274, - 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, - 0xb00b, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, - 0x2071, 0x1800, 0x080c, 0x5dc3, 0x080c, 0x2e8c, 0x00ee, 0x0005, - 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, - 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, - 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, - 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, - 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x9606, - 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, - 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xd807, - 0x01b8, 0x080c, 0xd817, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, - 0x0016, 0x080c, 0x1938, 0x001e, 0x080c, 0xbf32, 0x1110, 0x080c, - 0x30d4, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x080c, 0xa007, - 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, 0x0858, - 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, - 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, - 0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, - 0x0036, 0x0046, 0x080c, 0xc444, 0x0168, 0x2019, 0xffff, 0x9005, - 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, - 0x080c, 0x4bb5, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, - 0x0001, 0x1128, 0x080c, 0x9abb, 0x080c, 0xa007, 0x9006, 0x0005, - 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, - 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, - 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, - 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, - 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, - 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, - 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0138, - 0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, - 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, - 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056, 0xd5b4, - 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500, 0x9084, - 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, - 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee, 0x000e, - 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, - 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, 0x8000, - 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, 0x00e6, - 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1844, - 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, - 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e, 0x012e, - 0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, - 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, - 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, - 0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, - 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, - 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x15bf, - 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, - 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, - 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x0de3, - 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, - 0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, - 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, - 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, - 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, - 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0dc2, - 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0dc2, - 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, - 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x4447, - 0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, - 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, - 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, - 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, - 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0db5, - 0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b, 0x1734, - 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, - 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, - 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b, 0x808a, - 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, - 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4473, - 0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, - 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, - 0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, - 0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003, 0x0140, - 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003, 0x0d44, - 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, - 0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, - 0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, - 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, - 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, - 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, - 0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, - 0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, - 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44ab, - 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000, 0x8062, - 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x44b3, - 0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, - 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, - 0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, - 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, - 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b, 0x003a, - 0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, - 0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, - 0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, - 0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0x359b, - 0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, - 0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003, 0x8074, - 0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, - 0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, - 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, - 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, - 0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, - 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b, 0x92c0, - 0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002, 0x08ff, - 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, - 0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, - 0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, - 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, - 0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, - 0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, - 0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, - 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003, 0x15fe, - 0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, - 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, - 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b, 0x18fe, - 0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, - 0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, - 0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, - 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003, 0x3c1e, - 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x0d5b, - 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b, 0x8076, - 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, - 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, - 0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, - 0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, - 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b, 0x017e, - 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, - 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, - 0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000, 0x3ce0, - 0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0d2d, - 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, - 0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, - 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x0d76, - 0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000, 0x8000, - 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, - 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, - 0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, - 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0x4587, - 0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, - 0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, - 0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, - 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, - 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, - 0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, - 0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, - 0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, - 0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, - 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, - 0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, - 0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, - 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, - 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, - 0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, - 0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, - 0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008, 0x0006, - 0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, - 0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, - 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, - 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, - 0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, - 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, - 0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd, 0x0003, - 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, 0x0010, - 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003, 0x8060, - 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003, 0x5096, - 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, 0x880a, - 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009, 0x7000, - 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b, 0x808c, - 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a, 0x808c, - 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000, 0x0022, - 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b, 0x0bfe, - 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001, 0x11c5, - 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc030, - 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, - 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0xc038, - 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b, 0xc2c0, - 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b, 0x9180, - 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, - 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b, 0x0240, - 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b, 0x112a, - 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x880a, - 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, 0x8062, - 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, 0xc058, - 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b, 0x00fe, - 0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000, 0x1530, - 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, - 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, - 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008, 0x0003, - 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x5870, - 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003, 0x5874, - 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010, - 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004, 0x000a, - 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, - 0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008, 0x0242, - 0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000, 0x0d46, - 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b, 0x0344, - 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x5890, - 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, - 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003, 0xabd0, - 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b, 0x8054, - 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003, 0x3a45, - 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000, 0x08cd, - 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, 0x7f62, - 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003, 0x00fe, - 0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, 0x0001, - 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003, 0x00fe, - 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, 0x8062, - 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0bc, - 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, 0x0d60, - 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, 0x8066, - 0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008, 0x1dfe, - 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004, 0x00e1, - 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b, 0x3a44, - 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0xadd0, - 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003, 0xa7d0, - 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, 0x0000, - 0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000, 0x4040, - 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a, 0x88f1, - 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008, 0x0004, - 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0x92c0, - 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, 0x8995, - 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x8066, - 0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009, 0x0780, - 0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003, 0x2e4d, - 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a, 0x890c, - 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, - 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0189, - 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b, 0x194d, - 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b, 0x5910, - 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c, 0x1810, - 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008, 0x0d30, - 0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008, 0xb051, - 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, - 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0xbbe0, - 0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000, 0x3ce0, - 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0931, - 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0176, - 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b, 0xbbe0, - 0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008, 0x0176, - 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b, 0x18fe, - 0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008, 0x0040, - 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0xa6d0, - 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, 0x0000, - 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, 0x7f08, - 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, 0x8066, - 0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c, 0x8054, - 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, - 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009, 0x0038, - 0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x096a, - 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003, 0x0179, - 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, - 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0176, - 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b, 0x3a44, - 0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, - 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, - 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, - 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, - 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, - 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003, 0x4000, - 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0, - 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000, 0x0706, - 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000, - 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b, 0x8010, - 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0022, - 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008, 0x0007, - 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x01d7, - 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, 0x0189, - 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf080, - 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, - 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, 0x01cd, - 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, 0x0004, - 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002, 0x880a, - 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0003, - 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000, 0x01cf, - 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003, 0x3a47, - 0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, 0x01cf, - 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004, 0x018c, - 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, - 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, - 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x09e0, - 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x8054, - 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, 0x880a, - 0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002, 0x0004, - 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, - 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0xdac8 + 0x85f8, 0x080c, 0x8b8f, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, + 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, + 0xc889, 0x00e6, 0x0026, 0x080c, 0x6687, 0x0550, 0x080c, 0x6670, + 0x080c, 0xdaa4, 0x1518, 0x2071, 0x1800, 0x70d8, 0x9085, 0x0003, + 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac, 0x9284, 0x00ff, 0x707a, + 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205, 0x707e, 0x78ea, 0x00fe, + 0x70e3, 0x0000, 0x080c, 0x66c5, 0x0120, 0x2011, 0x19db, 0x2013, + 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e73, 0x0010, 0x080c, 0xdad8, + 0x002e, 0x00ee, 0x080c, 0x9fea, 0x0804, 0xc73e, 0x080c, 0x9fea, + 0x0005, 0x2600, 0x0002, 0xc985, 0xc985, 0xc985, 0xc985, 0xc985, + 0xc987, 0xc985, 0xc985, 0xc985, 0xc985, 0xc9a1, 0xc985, 0xc985, + 0xc985, 0xc9b3, 0xc9c9, 0xc9fa, 0xc985, 0x080c, 0x0df6, 0x080c, + 0xda33, 0x1d20, 0x080c, 0x31b8, 0x1d08, 0x7038, 0x6016, 0x6007, + 0x0045, 0x6003, 0x0001, 0x080c, 0x8640, 0x0005, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, + 0x0005, 0x080c, 0xda33, 0x1950, 0x080c, 0x31b8, 0x1938, 0x080c, + 0xcb12, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, + 0x080c, 0x8640, 0x0005, 0x2001, 0x1823, 0x2004, 0x9082, 0x00e1, + 0x1268, 0x080c, 0xca1c, 0x0904, 0xc96e, 0x6007, 0x004e, 0x6003, + 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007, 0x0012, + 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, + 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x1998, + 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x1999, 0x2004, 0x9106, + 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, + 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e, + 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, + 0x8b8f, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, + 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, + 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, + 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, + 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, + 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, + 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x080c, 0x1050, 0x05a0, + 0x2900, 0x6016, 0x708c, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, + 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x0471, 0x001e, + 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1050, 0x01b0, 0x2900, 0xa006, + 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x00b1, 0x001e, + 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x708f, 0x0000, + 0x6014, 0x2048, 0x080c, 0x0fe9, 0x9006, 0x012e, 0x01de, 0x01ce, + 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x21d9, 0x2099, + 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, + 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9, + 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21d9, 0x2061, 0x197b, 0x6004, + 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, + 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9, 0x2099, + 0x0260, 0x0ca8, 0x2061, 0x197b, 0x2019, 0x0280, 0x3300, 0x931e, + 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, + 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x81ff, 0x11b8, 0x080c, 0x21f1, 0x20a1, 0x024c, 0x2001, 0x0014, + 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, + 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240, + 0x0c98, 0x080c, 0x21f1, 0x2061, 0x197e, 0x6004, 0x20a0, 0x6008, + 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, + 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240, + 0x0c98, 0x2061, 0x197e, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, + 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, + 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, + 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, + 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, + 0xcbaa, 0x00de, 0x0005, 0x00d6, 0x080c, 0xcbb7, 0x1520, 0x680c, + 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, + 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xdb50, 0x2009, 0x0001, + 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, + 0x266d, 0x1148, 0x2001, 0x0001, 0x080c, 0xdb50, 0x2110, 0x900e, + 0x080c, 0x30de, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, + 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa03b, 0x05a8, 0x0016, 0x0026, + 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266d, + 0x1578, 0x080c, 0x6343, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, + 0x001e, 0x2b00, 0x6012, 0x080c, 0xda33, 0x11d8, 0x080c, 0x31b8, + 0x11c0, 0x080c, 0xcb12, 0x0510, 0x2001, 0x0007, 0x080c, 0x62f4, + 0x2001, 0x0007, 0x080c, 0x6320, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x0010, 0x080c, 0x9fea, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, + 0x080c, 0x9fea, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0x9fea, + 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, + 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, + 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, + 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, + 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, + 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0df6, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, + 0xcd17, 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f, 0x0128, 0x6000, 0x9086, + 0x0002, 0x0904, 0xa9ee, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0df6, + 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83, 0x080c, 0xa01c, + 0x080c, 0x8b8f, 0x0005, 0xcc43, 0xcc45, 0xcc43, 0xcc43, 0xcc43, + 0xcc45, 0xcc54, 0xcd10, 0xcc98, 0xcd10, 0xccbe, 0xcd10, 0xcc54, + 0xcd10, 0xcd08, 0xcd10, 0xcd08, 0xcd10, 0xcd10, 0xcc43, 0xcc43, + 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, + 0xcc43, 0xcc45, 0xcc43, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcc43, + 0xcd0d, 0xcd10, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcd10, 0xcd10, + 0xcc43, 0xcd10, 0xcd10, 0xcc43, 0xcc4f, 0xcc43, 0xcc43, 0xcc43, + 0xcc43, 0xcd0c, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcd10, 0xcc43, + 0xcc43, 0xcc43, 0xcc43, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, + 0xc471, 0x6003, 0x0002, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x9006, + 0x080c, 0x62e0, 0x0804, 0xcd10, 0x080c, 0x66c1, 0x1904, 0xcd10, + 0x9006, 0x080c, 0x62e0, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, + 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, + 0x00b8, 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0904, 0xcd10, 0x080c, + 0x31e9, 0x1904, 0xcd10, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, + 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, + 0x2001, 0x0002, 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6023, 0x0001, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8267, 0x0804, 0xcd16, + 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, + 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c, 0x6320, + 0x080c, 0xdb9f, 0x0904, 0xcd10, 0x080c, 0x8a83, 0x2001, 0x0004, + 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x2001, 0x1800, + 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, + 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x2001, + 0x0006, 0x080c, 0xcd34, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, 0x0006, + 0x080c, 0x6320, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, 0x908e, + 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x62f4, 0x080c, 0x66c1, + 0x11f8, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, + 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, + 0x8000, 0x78a6, 0x00fe, 0x0804, 0xcc80, 0x2001, 0x0004, 0x0030, + 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6320, + 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x2600, + 0x0002, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b, + 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, + 0xcd2d, 0xcd2d, 0xcd2d, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, + 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, + 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x62f4, 0x9006, 0x080c, + 0x62e0, 0x080c, 0x30be, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, + 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, + 0x0df6, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, + 0x190c, 0x0df6, 0x006b, 0x0005, 0xaa88, 0xaa88, 0xaa88, 0xaa88, + 0xcdc9, 0xaa88, 0xcdb3, 0xcd74, 0xaa88, 0xaa88, 0xaa88, 0xaa88, + 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0xcdc9, 0xaa88, 0xcdb3, 0xcdba, + 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0x00f6, 0x080c, 0x66c1, 0x11d8, + 0x080c, 0xc459, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, + 0x0190, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, + 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, + 0x080c, 0x8b8f, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x266d, 0x11b0, 0x080c, 0x63a3, 0x0118, 0x080c, 0x9fea, + 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, + 0x5e49, 0x000e, 0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, + 0x9fea, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, + 0x9fea, 0x0005, 0x080c, 0xae8a, 0x1148, 0x6003, 0x0001, 0x6007, + 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0x9fea, + 0x0005, 0x0804, 0x9fea, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9182, + 0x0040, 0x0002, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdf0, 0xcdee, + 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, + 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0x080c, 0x0df6, + 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, + 0x2258, 0xb8ac, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, + 0x94a4, 0xff00, 0x0904, 0xce56, 0x080c, 0xdb44, 0x1170, 0x9486, + 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8450, + 0x0020, 0x9026, 0x080c, 0xda78, 0x0c38, 0x080c, 0x1037, 0x090c, + 0x0df6, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, + 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, + 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, + 0xa887, 0x0036, 0x080c, 0x6a22, 0x001e, 0x080c, 0xdb44, 0x1904, + 0xceb6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd7af, + 0x0804, 0xceb6, 0x9486, 0x0200, 0x1120, 0x080c, 0xd746, 0x0804, + 0xceb6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceb6, + 0x2019, 0x0002, 0x080c, 0xd761, 0x0804, 0xceb6, 0x2069, 0x1a4c, + 0x6a00, 0xd284, 0x0904, 0xcf20, 0x9284, 0x0300, 0x1904, 0xcf19, + 0x6804, 0x9005, 0x0904, 0xcf01, 0x2d78, 0x6003, 0x0007, 0x080c, + 0x1050, 0x0904, 0xcec2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, + 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, + 0xcf24, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, + 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, + 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, + 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xcebe, 0x2005, + 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, + 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, + 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, + 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6a22, 0x002e, 0x004e, + 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, + 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, + 0x1037, 0x1904, 0xce6b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0c00, 0x2069, 0x0260, + 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, + 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804, + 0xceb6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4a17, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804, + 0xceb6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xced6, + 0x6017, 0xf200, 0x0804, 0xced6, 0xa867, 0x0146, 0xa86b, 0x0000, + 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, + 0xcebe, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, + 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, + 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, + 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, + 0x9282, 0x0111, 0x1a0c, 0x0df6, 0x8210, 0x821c, 0x2001, 0x026c, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, + 0xcfa0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, + 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, + 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, + 0x1050, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, + 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1069, 0x0cc8, 0x080c, + 0x1069, 0x0804, 0xcec2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, + 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xd7e2, 0x0804, 0xceb6, + 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, + 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, + 0x0df6, 0x9082, 0x0040, 0x0a0c, 0x0df6, 0x2008, 0x0804, 0xd02f, + 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xc47f, 0x0500, 0x6000, + 0x9086, 0x0002, 0x11e0, 0x0804, 0xd078, 0x9186, 0x0027, 0x0190, + 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0df6, + 0x080c, 0xc47f, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0df6, + 0x0804, 0xd15b, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, + 0xa083, 0x0005, 0xcff6, 0xcff8, 0xcff8, 0xd01f, 0xcff6, 0xcff6, + 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, + 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0036, 0x0096, 0x6014, 0x904d, + 0x01d8, 0x080c, 0xbd4e, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, + 0xd7e2, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961, + 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, + 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x080c, 0xbd4e, 0x0120, 0x6014, + 0x2048, 0x080c, 0x1069, 0x080c, 0xa01c, 0x009e, 0x0005, 0x0002, + 0xd044, 0xd05b, 0xd046, 0xd072, 0xd044, 0xd044, 0xd044, 0xd044, + 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, + 0xd044, 0xd044, 0xd044, 0xd044, 0x080c, 0x0df6, 0x0096, 0x080c, + 0x8a83, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, + 0x2009, 0x0043, 0x080c, 0xa068, 0x0010, 0x6003, 0x0004, 0x080c, + 0x8b8f, 0x009e, 0x0005, 0x080c, 0x8a83, 0x080c, 0xbd4e, 0x0138, + 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, + 0x8425, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda3c, + 0x0db0, 0x0cc8, 0x080c, 0x8a83, 0x2009, 0x0041, 0x0804, 0xd1e3, + 0x9182, 0x0040, 0x0002, 0xd08f, 0xd091, 0xd08f, 0xd08f, 0xd08f, + 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, + 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd092, 0xd08f, 0xd08f, 0x080c, + 0x0df6, 0x0005, 0x00d6, 0x080c, 0x8425, 0x00de, 0x080c, 0xda94, + 0x080c, 0x9fea, 0x0005, 0x9182, 0x0040, 0x0002, 0xd0b2, 0xd0b2, + 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b4, + 0xd123, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd123, 0xd0b2, 0xd0b2, + 0xd0b2, 0xd0b2, 0x080c, 0x0df6, 0x2001, 0x0105, 0x2004, 0x9084, + 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004, + 0x9105, 0x1904, 0xd123, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904, + 0xd123, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd, + 0x9085, 0x0010, 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528, + 0x603b, 0x0000, 0x080c, 0x8b3f, 0x6014, 0x0096, 0x2048, 0xa87c, + 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001, + 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x8c6c, 0x2009, 0x0041, + 0x009e, 0x0804, 0xd1e3, 0x080c, 0x8c6c, 0x6003, 0x0007, 0x601b, + 0x0000, 0x080c, 0x8425, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004, + 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890, + 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c, + 0x2ab1, 0x080c, 0x8c6c, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, + 0x080c, 0x8425, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xda3c, + 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, + 0x0036, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6014, 0x0096, 0x2048, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, + 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, + 0x2019, 0x0004, 0x080c, 0xd7e2, 0x6018, 0x9005, 0x1128, 0x2001, + 0x1961, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, + 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xd172, 0xd172, + 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd174, 0xd172, + 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, + 0xd172, 0xd1bf, 0x080c, 0x0df6, 0x6014, 0x0096, 0x2048, 0xa834, + 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, + 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, + 0x0804, 0xd1e3, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8425, + 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, + 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, + 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, + 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, + 0x8427, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, + 0xd0f4, 0x0128, 0x080c, 0x1577, 0x1904, 0xd174, 0x0005, 0x6014, + 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, + 0x1577, 0x1904, 0xd174, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, + 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, + 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, + 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0df6, 0x6024, 0xd0dc, + 0x090c, 0x0df6, 0x0005, 0xd207, 0xd213, 0xd21f, 0xd22b, 0xd207, + 0xd207, 0xd207, 0xd207, 0xd20e, 0xd209, 0xd209, 0xd207, 0xd207, + 0xd207, 0xd207, 0xd209, 0xd207, 0xd209, 0xd207, 0xd20e, 0x080c, + 0x0df6, 0x6024, 0xd0dc, 0x090c, 0x0df6, 0x0005, 0x6014, 0x9005, + 0x190c, 0x0df6, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8, + 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x6003, + 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b8f, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, + 0x1a7e, 0x0126, 0x2091, 0x8000, 0x080c, 0x865d, 0x080c, 0x8c6c, + 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, + 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xd25a, 0xd25c, + 0xd26e, 0xd288, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, + 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, + 0xd25a, 0xd25a, 0x080c, 0x0df6, 0x6014, 0x2048, 0xa87c, 0xd0fc, + 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001, + 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0470, 0x6014, 0x2048, + 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, + 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00e0, + 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x00a0, + 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, + 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a7e, + 0x080c, 0x865d, 0x080c, 0x8c6c, 0x0005, 0x080c, 0x8a83, 0x6114, + 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019, + 0x0029, 0x080c, 0xd7e2, 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c, + 0x8b8f, 0x0005, 0x080c, 0x8b3f, 0x6114, 0x81ff, 0x0158, 0x0096, + 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019, 0x0029, 0x080c, 0xd7e2, + 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c, 0x8c6c, 0x0005, 0x9182, + 0x0085, 0x0002, 0xd2d9, 0xd2d7, 0xd2d7, 0xd2e5, 0xd2d7, 0xd2d7, + 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0x080c, + 0x0df6, 0x6003, 0x000b, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, + 0xda33, 0x0118, 0x080c, 0x9fea, 0x0450, 0x2071, 0x0260, 0x7224, + 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, + 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa30b, + 0x7220, 0x080c, 0xd637, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, + 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, + 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x00ee, + 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, + 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c, 0x0df6, 0x9082, 0x0085, + 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, + 0xa083, 0x0050, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83, + 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0xd34a, 0xd34c, 0xd34c, + 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, + 0xd34a, 0xd34a, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, 0xa01c, + 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0df6, 0x9182, + 0x0092, 0x1a0c, 0x0df6, 0x9182, 0x0085, 0x0002, 0xd36b, 0xd36b, + 0xd36b, 0xd36d, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, + 0xd36b, 0xd36b, 0xd36b, 0x080c, 0x0df6, 0x0005, 0x9186, 0x0013, + 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, + 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, + 0x0005, 0x0036, 0x080c, 0xda94, 0x6043, 0x0000, 0x2019, 0x000b, + 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, + 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, + 0x995f, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x9a0a, + 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, + 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda94, + 0x080c, 0xc471, 0x080c, 0x192c, 0x6023, 0x0007, 0x6014, 0x2048, + 0x080c, 0xbd4e, 0x0110, 0x080c, 0xd7e2, 0x009e, 0x6017, 0x0000, + 0x080c, 0xda94, 0x6023, 0x0007, 0x080c, 0xc471, 0x003e, 0x012e, + 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, + 0x7938, 0x783c, 0x080c, 0x266d, 0x1904, 0xd41f, 0x0016, 0x00c6, + 0x080c, 0x63a3, 0x1904, 0xd41d, 0x001e, 0x00c6, 0x080c, 0xc459, + 0x1130, 0xb8b0, 0x9005, 0x0118, 0x080c, 0x31e9, 0x0148, 0x2b10, + 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xc460, 0x000e, 0x6012, + 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x9ad0, + 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x007e, 0x001e, + 0x0076, 0x903e, 0x080c, 0xd556, 0x007e, 0x0026, 0xba04, 0x9294, + 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, + 0xbaa0, 0x080c, 0x3152, 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e49, + 0xbe12, 0xbd16, 0xbcb2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, + 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, + 0x0016, 0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xd47e, + 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, + 0x8000, 0x0904, 0xd47b, 0x2001, 0x1956, 0x2004, 0x9005, 0x1140, + 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, + 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xdb49, 0x0118, 0x6978, + 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, + 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, + 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, + 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, + 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, + 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, + 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, + 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, + 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, + 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, + 0x0004, 0x0120, 0x080c, 0x63b2, 0x0804, 0xd4e5, 0x2011, 0x0276, + 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb017, + 0x009e, 0x15a0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, + 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x1540, 0x0046, 0x0016, + 0xbaa0, 0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, + 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, + 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, 0x8670, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x2001, 0x0007, 0x080c, 0x6320, 0x2001, + 0x0007, 0x080c, 0x62f4, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, + 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, + 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, + 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, + 0x026c, 0x7930, 0x7834, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3, + 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, + 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, + 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, + 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3, 0x11b8, + 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x015e, + 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, + 0x8000, 0x2740, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, + 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150, + 0x0006, 0x9186, 0x1a88, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, + 0xd5f0, 0x0018, 0x9606, 0x0904, 0xd5f0, 0x2100, 0x9c06, 0x0904, + 0xd5e7, 0x6720, 0x9786, 0x0007, 0x0904, 0xd5e7, 0x080c, 0xd878, + 0x1904, 0xd5e7, 0x080c, 0xdb67, 0x0904, 0xd5e7, 0x080c, 0xd868, + 0x0904, 0xd5e7, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x31e9, + 0x0904, 0xd60b, 0x6004, 0x9086, 0x0000, 0x1904, 0xd60b, 0x9786, + 0x0004, 0x0904, 0xd60b, 0x2500, 0x9c06, 0x0904, 0xd5e7, 0x2400, + 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, + 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x192c, 0x001e, + 0x9786, 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x080c, 0xa9a7, + 0x009e, 0x080c, 0xa01c, 0x0418, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, + 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a, + 0xa877, 0x0000, 0x080c, 0xdae1, 0x0016, 0x080c, 0xc044, 0x080c, + 0x6a15, 0x001e, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x9ce0, + 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd56a, + 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, + 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, + 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x08f8, 0x009e, 0x0c00, 0x9786, + 0x000a, 0x0968, 0x0808, 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, + 0x9086, 0x0018, 0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, + 0x1970, 0x6000, 0x9086, 0x0002, 0x1950, 0x080c, 0xbf45, 0x0130, + 0x080c, 0xbf56, 0x1920, 0x080c, 0xa9a7, 0x0038, 0x080c, 0x30be, + 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c, 0xa01c, 0x0804, + 0xd5e7, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, + 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xd809, 0x001e, + 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, + 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd658, 0xd656, + 0xd656, 0xd656, 0xd681, 0xa01c, 0xa01c, 0xd656, 0x9006, 0x0005, + 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x2009, 0x0020, 0x080c, 0xd837, 0x001e, 0x004e, 0x2019, + 0x0002, 0x080c, 0xd38f, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, + 0x080c, 0xbd4e, 0x0140, 0x6014, 0x904d, 0x080c, 0xb983, 0x687b, + 0x0005, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x9085, 0x0001, + 0x0005, 0x0019, 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xd69c, 0xd69c, 0xd6b3, 0xd6a3, + 0xd6c2, 0xd69c, 0xd69c, 0xd69e, 0xd69c, 0xd69c, 0xd69c, 0xd69c, + 0xd69c, 0xd69c, 0xd69c, 0xd69c, 0x080c, 0x0df6, 0x080c, 0xa01c, + 0x9085, 0x0001, 0x0005, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, + 0x9c06, 0x1128, 0x2019, 0x0001, 0x080c, 0x98b1, 0x0010, 0x080c, + 0x9a8f, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, + 0x0005, 0x080c, 0x6a22, 0x080c, 0xa01c, 0x00de, 0x009e, 0x9085, + 0x0001, 0x0005, 0x601c, 0xd084, 0x190c, 0x192c, 0x0c60, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xb003, 0x003e, + 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, + 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd739, 0x2071, + 0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd739, 0x88ff, + 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd868, 0x0580, + 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, + 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, + 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, + 0xd084, 0x0140, 0x080c, 0xda94, 0x080c, 0xc471, 0x080c, 0x192c, + 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0120, 0x0046, + 0x080c, 0xd7e2, 0x004e, 0x009e, 0x080c, 0xa01c, 0x88ff, 0x1198, + 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, + 0xd6ec, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, + 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, + 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, + 0x903e, 0x080c, 0x9a0a, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, + 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3, + 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd76c, 0x0036, 0x2508, + 0x2029, 0x0003, 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e, + 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, + 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x2c20, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, + 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3, 0x1190, 0x0086, 0x9046, + 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xda78, 0x004e, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x003e, 0x001e, 0x8108, 0x1f04, 0xd7b9, 0x0036, 0x2029, 0x0002, + 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, + 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xbd4c, 0x0198, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, + 0xa803, 0x0000, 0xab82, 0x080c, 0x6a22, 0x2f48, 0x0cb0, 0xab82, + 0x080c, 0x6a22, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, + 0xa803, 0x0000, 0x080c, 0x6a22, 0x2f48, 0x0cb8, 0x080c, 0x6a22, + 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, + 0x2071, 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, + 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, + 0x1130, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, + 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, + 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, + 0x0006, 0x080c, 0x1037, 0x000e, 0x090c, 0x0df6, 0xaae2, 0xa867, + 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xbd3c, 0x2001, 0x0000, + 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, + 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, + 0x2001, 0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0x009e, 0x0005, + 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, + 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, + 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, + 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, + 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, + 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x001e, + 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, + 0x0118, 0x080c, 0xc088, 0x0030, 0x080c, 0xda94, 0x080c, 0x8425, + 0x080c, 0x9fea, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, + 0x0002, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c9, 0xd8c9, + 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0x9006, + 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, + 0x000f, 0x0002, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, + 0xd8ed, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, + 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, + 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x0096, 0x00c6, 0x2260, + 0x080c, 0xda94, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, + 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, + 0xd946, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, + 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, + 0x85f8, 0x080c, 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, + 0x1904, 0xd9bd, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, + 0x190c, 0x0df6, 0x0804, 0xd9bd, 0x2048, 0x080c, 0xbd4e, 0x1130, + 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, + 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1e3, + 0x0804, 0xd9bd, 0x2009, 0x0041, 0x0804, 0xd9b7, 0x9186, 0x0005, + 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, + 0x0804, 0xd8e0, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0df6, 0x0804, + 0xd901, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, + 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, + 0x0004, 0x1904, 0xd9bd, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, + 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, + 0x1651, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1037, + 0x090c, 0x0df6, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, + 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, + 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, + 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, + 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6a22, 0x2019, 0x0045, + 0x6008, 0x2068, 0x080c, 0xd38f, 0x2d00, 0x600a, 0x6023, 0x0006, + 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, + 0x0000, 0x6003, 0x0007, 0x080c, 0xd1e3, 0x00ce, 0x00de, 0x009e, + 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, + 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x8a83, 0x0036, 0x0096, + 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x009e, 0x003e, + 0x080c, 0x8b8f, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa083, + 0x0005, 0xd9f0, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9f0, + 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x9182, + 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa083, + 0x0005, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda10, 0xda30, 0xda0e, + 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0x080c, 0x0df6, + 0x00d6, 0x2c68, 0x080c, 0x9f94, 0x01b0, 0x6003, 0x0001, 0x6007, + 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, + 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x080c, 0x9fea, 0x00de, 0x0005, + 0x080c, 0x9fea, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, + 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, + 0x2001, 0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, + 0x1520, 0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, + 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001, + 0x1960, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, + 0x2058, 0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, + 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, + 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, + 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, + 0x8425, 0x080c, 0x9fea, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, + 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, + 0xb8ac, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, + 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, + 0x182b, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, + 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, + 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, + 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e, 0x1168, 0x2011, + 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, + 0x080c, 0xb017, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x080c, 0x2e73, 0x00ee, + 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, + 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, + 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, + 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, + 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, + 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, + 0xd868, 0x01b8, 0x080c, 0xd878, 0x11a0, 0x6000, 0x9086, 0x0004, + 0x1120, 0x0016, 0x080c, 0x192c, 0x001e, 0x080c, 0xbf45, 0x1110, + 0x080c, 0x30be, 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c, + 0xa01c, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, + 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, + 0x0005, 0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, + 0x0006, 0x0036, 0x0046, 0x080c, 0xc459, 0x0168, 0x2019, 0xffff, + 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0004, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, + 0x9086, 0x0001, 0x1128, 0x080c, 0x9ad0, 0x080c, 0xa01c, 0x9006, + 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, + 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, + 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, + 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, + 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4, + 0x0138, 0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, + 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, + 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056, + 0xd5b4, 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500, + 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, + 0x908e, 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, + 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, + 0x00e6, 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, + 0x1844, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, + 0x8000, 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, + 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, + 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, + 0x7924, 0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, + 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, + 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, + 0x15bf, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, + 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, + 0x4022, 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, + 0x0de3, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, + 0x0ca0, 0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, + 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x0009, 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, + 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, + 0x0411, 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, + 0x0dc2, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, + 0x0dc2, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, + 0x4447, 0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, + 0x31c2, 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, + 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, + 0x0011, 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, + 0x0db5, 0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b, + 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, + 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b, + 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x0002, 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, + 0x4473, 0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, + 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, + 0x007d, 0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, + 0x8066, 0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003, + 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003, + 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, + 0x0090, 0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, + 0x064a, 0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, + 0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, + 0x0c0d, 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, + 0x589b, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, + 0x08e1, 0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, + 0x7f3c, 0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, + 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, + 0x44ab, 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000, + 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, + 0x44b3, 0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, + 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, + 0x0009, 0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, + 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b, + 0x003a, 0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, + 0x007d, 0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, + 0x00e1, 0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, + 0x1000, 0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, + 0x359b, 0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, + 0xa6d0, 0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003, + 0x8074, 0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, + 0x3a46, 0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, + 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, + 0x0118, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, + 0x1246, 0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x0002, 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b, + 0x92c0, 0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002, + 0x08ff, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, + 0x3a46, 0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, + 0x0004, 0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, + 0x000d, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x0116, 0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, + 0x09a5, 0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, + 0x017e, 0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, + 0xf000, 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003, + 0x15fe, 0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, + 0x0501, 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, + 0x000a, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b, + 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, + 0x3ce0, 0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, + 0x0040, 0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003, + 0x3c1e, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, + 0x0d5b, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b, + 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x000d, 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, + 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, + 0x0000, 0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, + 0x7f0a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b, + 0x017e, 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, + 0xf000, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, + 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000, + 0x3ce0, 0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, + 0x0d2d, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, + 0x8072, 0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, + 0x0042, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, + 0x0d76, 0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000, + 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, + 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, + 0xbc80, 0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, + 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, + 0x4587, 0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, + 0x4000, 0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, + 0x8074, 0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, + 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, + 0x01cd, 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, + 0x8010, 0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, + 0x0189, 0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, + 0x001b, 0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, + 0x8010, 0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0005, 0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, + 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, + 0x000b, 0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, + 0x01cf, 0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008, + 0x0006, 0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, + 0x0189, 0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, + 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, + 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, + 0x2e4d, 0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, + 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd, + 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, + 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003, + 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003, + 0x5096, 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, + 0x880a, 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009, + 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b, + 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a, + 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000, + 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b, + 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001, + 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, + 0xc030, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, + 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, + 0xc038, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b, + 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b, + 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b, + 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b, + 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, + 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, + 0xc058, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b, + 0x00fe, 0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000, + 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, + 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, + 0x8066, 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008, + 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, + 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003, + 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, + 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004, + 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, + 0x0231, 0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008, + 0x0242, 0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000, + 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b, + 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, + 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, + 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003, + 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b, + 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003, + 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000, + 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003, + 0x00fe, 0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, + 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003, + 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, + 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, + 0xc0bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, + 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, + 0x8066, 0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008, + 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004, + 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b, + 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, + 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003, + 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, + 0x0000, 0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000, + 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a, + 0x88f1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008, + 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, + 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, + 0x8995, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, + 0x8066, 0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009, + 0x0780, 0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003, + 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a, + 0x890c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, + 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, + 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b, + 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b, + 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c, + 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008, + 0x0d30, 0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008, + 0xb051, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, + 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, + 0xbbe0, 0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000, + 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, + 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, + 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b, + 0xbbe0, 0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b, + 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008, + 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, + 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, + 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, + 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, + 0x8066, 0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c, + 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, + 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009, + 0x0038, 0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, + 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003, + 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, + 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b, + 0x3a44, 0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, + 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, + 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, + 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, + 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003, + 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, + 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000, + 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, + 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008, + 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, + 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, + 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, + 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, + 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, + 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000, + 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003, + 0x3a47, 0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, + 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004, + 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, + 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, + 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, + 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, + 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002, + 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, + 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x92c4 }; #ifdef UNIQUE_FW_NAME -unsigned short fw2300flx_length01 = 0xdb56; +unsigned short fw2300flx_length01 = 0xdbb7; #else -unsigned short risc_code_length01 = 0xdb56; +unsigned short risc_code_length01 = 0xdbb7; #endif From 408c1ce2716c7a004851c93f9f9dcf3d763bc240 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:36 +0200 Subject: [PATCH 0644/1940] [Bluetooth] Move CRC table into RFCOMM core This patch moves rfcomm_crc_table[] into the RFCOMM core, because there is no need to keep it in a separate file. Signed-off-by: Marcel Holtmann --- include/net/bluetooth/rfcomm.h | 3 -- net/bluetooth/rfcomm/Makefile | 2 +- net/bluetooth/rfcomm/core.c | 43 ++++++++++++++++++++ net/bluetooth/rfcomm/crc.c | 71 ---------------------------------- 4 files changed, 44 insertions(+), 75 deletions(-) delete mode 100644 net/bluetooth/rfcomm/crc.c diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index fbe557f7ea1d..e656be7c001a 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -275,9 +275,6 @@ static inline void rfcomm_session_hold(struct rfcomm_session *s) atomic_inc(&s->refcnt); } -/* ---- RFCOMM chechsum ---- */ -extern u8 rfcomm_crc_table[]; - /* ---- RFCOMM sockets ---- */ struct sockaddr_rc { sa_family_t rc_family; diff --git a/net/bluetooth/rfcomm/Makefile b/net/bluetooth/rfcomm/Makefile index aecec45ec68d..fe07988a3705 100644 --- a/net/bluetooth/rfcomm/Makefile +++ b/net/bluetooth/rfcomm/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm.o -rfcomm-y := core.o sock.o crc.o +rfcomm-y := core.o sock.o rfcomm-$(CONFIG_BT_RFCOMM_TTY) += tty.o diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 35adce6482b6..c3d56ead840c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -133,6 +133,49 @@ static inline void rfcomm_session_put(struct rfcomm_session *s) /* ---- RFCOMM FCS computation ---- */ +/* reversed, 8-bit, poly=0x07 */ +static unsigned char rfcomm_crc_table[256] = { + 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, + 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, + 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, + 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, + + 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, + 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, + 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, + 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, + + 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, + 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, + 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, + 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, + + 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, + 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, + 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, + 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, + + 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, + 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, + 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, + 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, + + 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, + 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, + 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, + 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, + + 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, + 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, + 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, + 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, + + 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, + 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, + 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, + 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf +}; + /* CRC on 2 bytes */ #define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]]) diff --git a/net/bluetooth/rfcomm/crc.c b/net/bluetooth/rfcomm/crc.c deleted file mode 100644 index 1011bc4a8692..000000000000 --- a/net/bluetooth/rfcomm/crc.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - RFCOMM implementation for Linux Bluetooth stack (BlueZ). - Copyright (C) 2002 Maxim Krasnyansky - Copyright (C) 2002 Marcel Holtmann - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - -/* - * RFCOMM FCS calculation. - * - * $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $ - */ - -/* reversed, 8-bit, poly=0x07 */ -unsigned char rfcomm_crc_table[256] = { - 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, - 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, - 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, - 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, - - 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, - 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, - 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, - 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, - - 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, - 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, - 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, - 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, - - 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, - 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, - 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, - 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, - - 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, - 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, - 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, - 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, - - 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, - 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, - 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, - 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, - - 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, - 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, - 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, - 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, - - 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, - 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, - 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, - 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf -}; From 20dd6f59d6ea5fe47397c5254606c76b1d047727 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:40 +0200 Subject: [PATCH 0645/1940] [Bluetooth] Remove TXCRC compile option for BCSP driver The TXCRC compile option is not really useful and thus change it into a module parameter. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/Kconfig | 8 ------- drivers/bluetooth/hci_bcsp.c | 42 +++++++++++++++++++---------------- drivers/bluetooth/hci_bcsp.h | 1 + drivers/bluetooth/hci_ldisc.c | 2 +- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 543f93e0f23f..b9fbe6e7f9ae 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -55,14 +55,6 @@ config BT_HCIUART_BCSP Say Y here to compile support for HCI BCSP protocol. -config BT_HCIUART_BCSP_TXCRC - bool "Transmit CRC with every BCSP packet" - depends on BT_HCIUART_BCSP - help - If you say Y here, a 16-bit CRC checksum will be transmitted along with - every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip. - This increases reliability, but slightly reduces efficiency. - config BT_HCIBCM203X tristate "HCI BCM203x USB driver" depends on USB diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 0ee324e1265d..91bd293d7a0a 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -28,7 +28,7 @@ * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $ */ -#define VERSION "0.2" +#define VERSION "0.3" #include #include @@ -60,6 +60,7 @@ #define BT_DBG( A... ) #endif +static int txcrc = 1; static int hciextn = 1; /* ---- BCSP CRC calculation ---- */ @@ -173,11 +174,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, { struct sk_buff *nskb; u8 hdr[4], chan; - int rel, i; - -#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC u16 BCSP_CRC_INIT(bcsp_txmsg_crc); -#endif + int rel, i; switch (pkt_type) { case HCI_ACLDATA_PKT: @@ -240,9 +238,9 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq); bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07; } -#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC - hdr[0] |= 0x40; -#endif + + if (bcsp->use_crc) + hdr[0] |= 0x40; hdr[1] = ((len << 4) & 0xff) | chan; hdr[2] = len >> 4; @@ -251,25 +249,25 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, /* Put BCSP header */ for (i = 0; i < 4; i++) { bcsp_slip_one_byte(nskb, hdr[i]); -#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC - bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]); -#endif + + if (bcsp->use_crc) + bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]); } /* Put payload */ for (i = 0; i < len; i++) { bcsp_slip_one_byte(nskb, data[i]); -#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC - bcsp_crc_update(&bcsp_txmsg_crc, data[i]); -#endif + + if (bcsp->use_crc) + bcsp_crc_update(&bcsp_txmsg_crc, data[i]); } -#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC /* Put CRC */ - bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc); - bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff)); - bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff)); -#endif + if (bcsp->use_crc) { + bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc); + bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff)); + bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff)); + } bcsp_slip_msgdelim(nskb); return nskb; @@ -698,6 +696,9 @@ static int bcsp_open(struct hci_uart *hu) bcsp->rx_state = BCSP_W4_PKT_DELIMITER; + if (txcrc) + bcsp->use_crc = 1; + return 0; } @@ -743,5 +744,8 @@ int bcsp_deinit(void) return hci_uart_unregister_proto(&bcsp); } +module_param(txcrc, bool, 0644); +MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet"); + module_param(hciextn, bool, 0644); MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets"); diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h index a2b3bb92274b..01bbc664db74 100644 --- a/drivers/bluetooth/hci_bcsp.h +++ b/drivers/bluetooth/hci_bcsp.h @@ -60,6 +60,7 @@ struct bcsp_struct { BCSP_ESCSTATE_ESC } rx_esc_state; + u8 use_crc; u16 message_crc; u8 txack_req; /* Do we need to send ack's to the peer? */ diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index aed80cc22890..8c9317bcd53c 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -27,7 +27,7 @@ * * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $ */ -#define VERSION "2.1" +#define VERSION "2.2" #include #include From 0372a6627f862f90a2c43772befeecef508cfd7b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:45 +0200 Subject: [PATCH 0646/1940] [Bluetooth] Cleanup of the HCI UART driver This patch contains the big cleanup of the HCI UART driver. The uneeded header files are removed and their structure declarations are moved into the protocol implementations. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcsp.c | 120 ++++++++++++++++++---------- drivers/bluetooth/hci_bcsp.h | 71 ----------------- drivers/bluetooth/hci_h4.c | 101 +++++++++++++++--------- drivers/bluetooth/hci_h4.h | 44 ----------- drivers/bluetooth/hci_ldisc.c | 144 +++++++++++++++++----------------- drivers/bluetooth/hci_uart.h | 84 ++++++++++---------- 6 files changed, 258 insertions(+), 306 deletions(-) delete mode 100644 drivers/bluetooth/hci_bcsp.h delete mode 100644 drivers/bluetooth/hci_h4.h diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 91bd293d7a0a..0a4761415ac3 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -1,35 +1,27 @@ -/* - BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ). - Copyright 2002 by Fabrizio Gennari - - Based on - hci_h4.c by Maxim Krasnyansky - ABCSP by Carl Orsborn - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $ + * + * Bluetooth HCI UART driver + * + * Copyright (C) 2002-2003 Fabrizio Gennari + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ -#define VERSION "0.3" - #include #include @@ -52,17 +44,56 @@ #include #include + #include "hci_uart.h" -#include "hci_bcsp.h" #ifndef CONFIG_BT_HCIUART_DEBUG #undef BT_DBG #define BT_DBG( A... ) #endif +#define VERSION "0.3" + static int txcrc = 1; static int hciextn = 1; +#define BCSP_TXWINSIZE 4 + +#define BCSP_ACK_PKT 0x05 +#define BCSP_LE_PKT 0x06 + +struct bcsp_struct { + struct sk_buff_head unack; /* Unack'ed packets queue */ + struct sk_buff_head rel; /* Reliable packets queue */ + struct sk_buff_head unrel; /* Unreliable packets queue */ + + unsigned long rx_count; + struct sk_buff *rx_skb; + u8 rxseq_txack; /* rxseq == txack. */ + u8 rxack; /* Last packet sent by us that the peer ack'ed */ + struct timer_list tbcsp; + + enum { + BCSP_W4_PKT_DELIMITER, + BCSP_W4_PKT_START, + BCSP_W4_BCSP_HDR, + BCSP_W4_DATA, + BCSP_W4_CRC + } rx_state; + + enum { + BCSP_ESCSTATE_NOESC, + BCSP_ESCSTATE_ESC + } rx_esc_state; + + u8 use_crc; + u16 message_crc; + u8 txack_req; /* Do we need to send ack's to the peer? */ + + /* Reliable packet sequence number - used to assign seq to each rel pkt. */ + u8 msgq_txseq; +}; + /* ---- BCSP CRC calculation ---- */ /* Table for calculating CRC for polynomial 0x1021, LSB processed first, @@ -112,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc) rev |= (crc & 1); crc = crc >> 1; } + return (rev); } @@ -120,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc) static void bcsp_slip_msgdelim(struct sk_buff *skb) { const char pkt_delim = 0xc0; + memcpy(skb_put(skb, 1), &pkt_delim, 1); } @@ -315,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) spin_unlock_irqrestore(&bcsp->unack.lock, flags); - /* We could not send a reliable packet, either because there are none or because there are too many unack'ed pkts. Did we receive any packets we have not acknowledged yet ? */ @@ -361,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) BT_ERR("Peer acked invalid packet"); BT_DBG("Removing %u pkts out of %u, up to seqno %u", - pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); + pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed && skb != (struct sk_buff *) &bcsp->unack; i++) { @@ -372,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) kfree_skb(skb); skb = nskb; } + if (bcsp->unack.qlen == 0) del_timer(&bcsp->tbcsp); + spin_unlock_irqrestore(&bcsp->unack.lock, flags); if (i != pkts_to_be_removed) @@ -528,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu) hci_recv_frame(bcsp->rx_skb); } + bcsp->rx_state = BCSP_W4_PKT_DELIMITER; bcsp->rx_skb = NULL; } @@ -596,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) BT_ERR ("Checksum failed: computed %04x received %04x", bcsp_crc_reverse(bcsp->message_crc), - (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + - bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); + (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + + bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); kfree_skb(bcsp->rx_skb); bcsp->rx_state = BCSP_W4_PKT_DELIMITER; @@ -631,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) bcsp->rx_count = 4; bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; BCSP_CRC_INIT(bcsp->message_crc); - + /* Do not increment ptr or decrement count * Allocate packet. Max len of a BCSP pkt= * 0xFFF (payload) +4 (header) +2 (crc) */ @@ -719,18 +754,19 @@ static int bcsp_close(struct hci_uart *hu) } static struct hci_uart_proto bcsp = { - .id = HCI_UART_BCSP, - .open = bcsp_open, - .close = bcsp_close, - .enqueue = bcsp_enqueue, - .dequeue = bcsp_dequeue, - .recv = bcsp_recv, - .flush = bcsp_flush + .id = HCI_UART_BCSP, + .open = bcsp_open, + .close = bcsp_close, + .enqueue = bcsp_enqueue, + .dequeue = bcsp_dequeue, + .recv = bcsp_recv, + .flush = bcsp_flush }; int bcsp_init(void) { int err = hci_uart_register_proto(&bcsp); + if (!err) BT_INFO("HCI BCSP protocol initialized"); else diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h deleted file mode 100644 index 01bbc664db74..000000000000 --- a/drivers/bluetooth/hci_bcsp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ). - Copyright 2002 by Fabrizio Gennari - - Based on - hci_h4.c by Maxim Krasnyansky - ABCSP by Carl Orsborn - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $ - */ - -#ifndef __HCI_BCSP_H__ -#define __HCI_BCSP_H__ - -#define BCSP_TXWINSIZE 4 - -#define BCSP_ACK_PKT 0x05 -#define BCSP_LE_PKT 0x06 - -struct bcsp_struct { - struct sk_buff_head unack; /* Unack'ed packets queue */ - struct sk_buff_head rel; /* Reliable packets queue */ - struct sk_buff_head unrel; /* Unreliable packets queue */ - - unsigned long rx_count; - struct sk_buff *rx_skb; - u8 rxseq_txack; /* rxseq == txack. */ - u8 rxack; /* Last packet sent by us that the peer ack'ed */ - struct timer_list tbcsp; - - enum { - BCSP_W4_PKT_DELIMITER, - BCSP_W4_PKT_START, - BCSP_W4_BCSP_HDR, - BCSP_W4_DATA, - BCSP_W4_CRC - } rx_state; - - enum { - BCSP_ESCSTATE_NOESC, - BCSP_ESCSTATE_ESC - } rx_esc_state; - - u8 use_crc; - u16 message_crc; - u8 txack_req; /* Do we need to send ack's to the peer? */ - - /* Reliable packet sequence number - used to assign seq to each rel pkt. */ - u8 msgq_txseq; -}; - -#endif /* __HCI_BCSP_H__ */ diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index cf8a22d58d96..12e369a66fc2 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -1,33 +1,27 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - /* - * Bluetooth HCI UART(H4) protocol. * - * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $ + * Bluetooth HCI UART driver + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ -#define VERSION "1.2" #include #include @@ -51,24 +45,41 @@ #include #include + #include "hci_uart.h" -#include "hci_h4.h" #ifndef CONFIG_BT_HCIUART_DEBUG #undef BT_DBG #define BT_DBG( A... ) #endif +#define VERSION "1.2" + +struct h4_struct { + unsigned long rx_state; + unsigned long rx_count; + struct sk_buff *rx_skb; + struct sk_buff_head txq; +}; + +/* H4 receiver States */ +#define H4_W4_PACKET_TYPE 0 +#define H4_W4_EVENT_HDR 1 +#define H4_W4_ACL_HDR 2 +#define H4_W4_SCO_HDR 3 +#define H4_W4_DATA 4 + /* Initialize protocol */ static int h4_open(struct hci_uart *hu) { struct h4_struct *h4; - + BT_DBG("hu %p", hu); - + h4 = kmalloc(sizeof(*h4), GFP_ATOMIC); if (!h4) return -ENOMEM; + memset(h4, 0, sizeof(*h4)); skb_queue_head_init(&h4->txq); @@ -83,7 +94,9 @@ static int h4_flush(struct hci_uart *hu) struct h4_struct *h4 = hu->priv; BT_DBG("hu %p", hu); + skb_queue_purge(&h4->txq); + return 0; } @@ -91,16 +104,19 @@ static int h4_flush(struct hci_uart *hu) static int h4_close(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; + hu->priv = NULL; BT_DBG("hu %p", hu); skb_queue_purge(&h4->txq); + if (h4->rx_skb) kfree_skb(h4->rx_skb); hu->priv = NULL; kfree(h4); + return 0; } @@ -114,6 +130,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); skb_queue_tail(&h4->txq, skb); + return 0; } @@ -122,6 +139,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) register int room = skb_tailroom(h4->rx_skb); BT_DBG("len %d room %d", len, room); + if (!len) { hci_recv_frame(h4->rx_skb); } else if (len > room) { @@ -136,6 +154,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) h4->rx_state = H4_W4_PACKET_TYPE; h4->rx_skb = NULL; h4->rx_count = 0; + return 0; } @@ -228,6 +247,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) ptr++; count--; continue; }; + ptr++; count--; /* Allocate packet */ @@ -238,9 +258,11 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) h4->rx_count = 0; return 0; } + h4->rx_skb->dev = (void *) hu->hdev; bt_cb(h4->rx_skb)->pkt_type = type; } + return count; } @@ -251,23 +273,24 @@ static struct sk_buff *h4_dequeue(struct hci_uart *hu) } static struct hci_uart_proto h4p = { - .id = HCI_UART_H4, - .open = h4_open, - .close = h4_close, - .recv = h4_recv, - .enqueue = h4_enqueue, - .dequeue = h4_dequeue, - .flush = h4_flush, + .id = HCI_UART_H4, + .open = h4_open, + .close = h4_close, + .recv = h4_recv, + .enqueue = h4_enqueue, + .dequeue = h4_dequeue, + .flush = h4_flush, }; - + int h4_init(void) { int err = hci_uart_register_proto(&h4p); + if (!err) BT_INFO("HCI H4 protocol initialized"); else BT_ERR("HCI H4 protocol registration failed"); - + return err; } diff --git a/drivers/bluetooth/hci_h4.h b/drivers/bluetooth/hci_h4.h deleted file mode 100644 index b95ff54bfd47..000000000000 --- a/drivers/bluetooth/hci_h4.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $ - */ - -#ifdef __KERNEL__ -struct h4_struct { - unsigned long rx_state; - unsigned long rx_count; - struct sk_buff *rx_skb; - struct sk_buff_head txq; -}; - -/* H4 receiver States */ -#define H4_W4_PACKET_TYPE 0 -#define H4_W4_EVENT_HDR 1 -#define H4_W4_ACL_HDR 2 -#define H4_W4_SCO_HDR 3 -#define H4_W4_DATA 4 - -#endif /* __KERNEL__ */ diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8c9317bcd53c..4a775f6ea390 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -1,33 +1,27 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - /* - * Bluetooth HCI UART driver. * - * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $ + * Bluetooth HCI UART driver + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ -#define VERSION "2.2" #include #include @@ -59,6 +53,8 @@ #define BT_DBG( A... ) #endif +#define VERSION "2.2" + static int reset = 0; static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO]; @@ -72,6 +68,7 @@ int hci_uart_register_proto(struct hci_uart_proto *p) return -EEXIST; hup[p->id] = p; + return 0; } @@ -84,6 +81,7 @@ int hci_uart_unregister_proto(struct hci_uart_proto *p) return -EINVAL; hup[p->id] = NULL; + return 0; } @@ -91,13 +89,14 @@ static struct hci_uart_proto *hci_uart_get_proto(unsigned int id) { if (id >= HCI_UART_MAX_PROTO) return NULL; + return hup[id]; } static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) { struct hci_dev *hdev = hu->hdev; - + /* Update HCI stat counters */ switch (pkt_type) { case HCI_COMMAND_PKT: @@ -117,10 +116,12 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) { struct sk_buff *skb = hu->tx_skb; + if (!skb) skb = hu->proto->dequeue(hu); else hu->tx_skb = NULL; + return skb; } @@ -129,7 +130,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) struct tty_struct *tty = hu->tty; struct hci_dev *hdev = hu->hdev; struct sk_buff *skb; - + if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); return 0; @@ -142,7 +143,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) while ((skb = hci_uart_dequeue(hu))) { int len; - + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); len = tty->driver->write(tty, skb->data, skb->len); hdev->stat.byte_tx += len; @@ -152,11 +153,11 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) hu->tx_skb = skb; break; } - + hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type); kfree_skb(skb); - } - + } + if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)) goto restart; @@ -173,6 +174,7 @@ static int hci_uart_open(struct hci_dev *hdev) /* Nothing to do for UART driver */ set_bit(HCI_RUNNING, &hdev->flags); + return 0; } @@ -234,6 +236,7 @@ static int hci_uart_send_frame(struct sk_buff *skb) hu->proto->enqueue(hu, skb); hci_uart_tx_wakeup(hu); + return 0; } @@ -241,7 +244,8 @@ static void hci_uart_destruct(struct hci_dev *hdev) { struct hci_uart *hu; - if (!hdev) return; + if (!hdev) + return; BT_DBG("%s", hdev->name); @@ -272,6 +276,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) BT_ERR("Can't allocate controll structure"); return -ENFILE; } + memset(hu, 0, sizeof(struct hci_uart)); tty->disc_data = hu; @@ -280,8 +285,10 @@ static int hci_uart_tty_open(struct tty_struct *tty) spin_lock_init(&hu->rx_lock); /* Flush any pending characters in the driver and line discipline. */ + /* FIXME: why is this needed. Note don't use ldisc_ref here as the open path is before the ldisc is referencable */ + if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); @@ -372,13 +379,13 @@ static int hci_uart_tty_room (struct tty_struct *tty) static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; - + if (!hu || tty != hu->tty) return; if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) return; - + spin_lock(&hu->rx_lock); hu->proto->recv(hu, (void *) data, count); hu->hdev->stat.byte_rx += count; @@ -429,8 +436,8 @@ static int hci_uart_register_dev(struct hci_uart *hu) static int hci_uart_set_proto(struct hci_uart *hu, int id) { struct hci_uart_proto *p; - int err; - + int err; + p = hci_uart_get_proto(id); if (!p) return -EPROTONOSUPPORT; @@ -446,6 +453,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) p->close(hu); return err; } + return 0; } @@ -463,7 +471,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) * Return Value: Command dependent */ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { struct hci_uart *hu = (void *)tty->disc_data; int err = 0; @@ -483,14 +491,14 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, return err; } tty->low_latency = 1; - } else + } else return -EBUSY; case HCIUARTGETPROTO: if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) return hu->proto->id; return -EUNATCH; - + default: err = n_tty_ioctl(tty, file, cmd, arg); break; @@ -502,27 +510,23 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, /* * We don't provide read/write/poll interface for user space. */ -static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr) -{ - return 0; -} -static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count) -{ - return 0; -} -static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait) +static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) { return 0; } -#ifdef CONFIG_BT_HCIUART_H4 -int h4_init(void); -int h4_deinit(void); -#endif -#ifdef CONFIG_BT_HCIUART_BCSP -int bcsp_init(void); -int bcsp_deinit(void); -#endif +static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, + const unsigned char *data, size_t count) +{ + return 0; +} + +static unsigned int hci_uart_tty_poll(struct tty_struct *tty, + struct file *filp, poll_table *wait) +{ + return 0; +} static int __init hci_uart_init(void) { @@ -534,18 +538,18 @@ static int __init hci_uart_init(void) /* Register the tty discipline */ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc)); - hci_uart_ldisc.magic = TTY_LDISC_MAGIC; - hci_uart_ldisc.name = "n_hci"; - hci_uart_ldisc.open = hci_uart_tty_open; - hci_uart_ldisc.close = hci_uart_tty_close; - hci_uart_ldisc.read = hci_uart_tty_read; - hci_uart_ldisc.write = hci_uart_tty_write; - hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; - hci_uart_ldisc.poll = hci_uart_tty_poll; - hci_uart_ldisc.receive_room= hci_uart_tty_room; - hci_uart_ldisc.receive_buf = hci_uart_tty_receive; - hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup; - hci_uart_ldisc.owner = THIS_MODULE; + hci_uart_ldisc.magic = TTY_LDISC_MAGIC; + hci_uart_ldisc.name = "n_hci"; + hci_uart_ldisc.open = hci_uart_tty_open; + hci_uart_ldisc.close = hci_uart_tty_close; + hci_uart_ldisc.read = hci_uart_tty_read; + hci_uart_ldisc.write = hci_uart_tty_write; + hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; + hci_uart_ldisc.poll = hci_uart_tty_poll; + hci_uart_ldisc.receive_room = hci_uart_tty_room; + hci_uart_ldisc.receive_buf = hci_uart_tty_receive; + hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; + hci_uart_ldisc.owner = THIS_MODULE; if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { BT_ERR("HCI line discipline registration failed. (%d)", err); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 0a57d72790ec..b250e6789dee 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -1,32 +1,29 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $ + * + * Bluetooth HCI UART driver + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ -#ifndef N_HCI +#ifndef N_HCI #define N_HCI 15 #endif @@ -42,7 +39,6 @@ #define HCI_UART_3WIRE 2 #define HCI_UART_H4DS 3 -#ifdef __KERNEL__ struct hci_uart; struct hci_uart_proto { @@ -56,27 +52,35 @@ struct hci_uart_proto { }; struct hci_uart { - struct tty_struct *tty; - struct hci_dev *hdev; - unsigned long flags; + struct tty_struct *tty; + struct hci_dev *hdev; + unsigned long flags; - struct hci_uart_proto *proto; - void *priv; - - struct sk_buff *tx_skb; - unsigned long tx_state; - spinlock_t rx_lock; + struct hci_uart_proto *proto; + void *priv; + + struct sk_buff *tx_skb; + unsigned long tx_state; + spinlock_t rx_lock; }; /* HCI_UART flag bits */ -#define HCI_UART_PROTO_SET 0 +#define HCI_UART_PROTO_SET 0 /* TX states */ -#define HCI_UART_SENDING 1 -#define HCI_UART_TX_WAKEUP 2 +#define HCI_UART_SENDING 1 +#define HCI_UART_TX_WAKEUP 2 int hci_uart_register_proto(struct hci_uart_proto *p); int hci_uart_unregister_proto(struct hci_uart_proto *p); int hci_uart_tx_wakeup(struct hci_uart *hu); -#endif /* __KERNEL__ */ +#ifdef CONFIG_BT_HCIUART_H4 +int h4_init(void); +int h4_deinit(void); +#endif + +#ifdef CONFIG_BT_HCIUART_BCSP +int bcsp_init(void); +int bcsp_deinit(void); +#endif From 6516455d3b42b33759a33a8102c1b8b48af4d9c9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:48 +0200 Subject: [PATCH 0647/1940] [Bluetooth] Make more functions static This patch makes another bunch of functions static. Signed-off-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 6 ++++++ net/bluetooth/af_bluetooth.c | 6 ------ net/bluetooth/hci_core.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 210458624840..e42d728b1620 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -171,4 +171,10 @@ static inline int skb_frags_no(struct sk_buff *skb) int bt_err(__u16 code); +extern int hci_sock_init(void); +extern int hci_sock_cleanup(void); + +extern int bt_sysfs_init(void); +extern void bt_sysfs_cleanup(void); + #endif /* __BLUETOOTH_H */ diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 12b43345b54f..03532062a46a 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -308,12 +308,6 @@ static struct net_proto_family bt_sock_family_ops = { .create = bt_sock_create, }; -extern int hci_sock_init(void); -extern int hci_sock_cleanup(void); - -extern int bt_sysfs_init(void); -extern int bt_sysfs_cleanup(void); - static int __init bt_init(void) { BT_INFO("Core ver %s", VERSION); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 55dc42eac92c..cf0df1c8c933 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -87,7 +87,7 @@ int hci_unregister_notifier(struct notifier_block *nb) return notifier_chain_unregister(&hci_notifier, nb); } -void hci_notify(struct hci_dev *hdev, int event) +static void hci_notify(struct hci_dev *hdev, int event) { notifier_call_chain(&hci_notifier, event, hdev); } @@ -1347,7 +1347,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) kfree_skb(skb); } -void hci_rx_task(unsigned long arg) +static void hci_rx_task(unsigned long arg) { struct hci_dev *hdev = (struct hci_dev *) arg; struct sk_buff *skb; From dd7f5527b3e68a7b2f715ae1a21164383f418013 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:53 +0200 Subject: [PATCH 0648/1940] [Bluetooth] Update security filter for Extended Inquiry Response This patch updates the HCI security filter with support for the Extended Inquiry Response (EIR) feature. Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_sock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 32ef7975a139..799e448750ad 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -66,20 +66,20 @@ static struct hci_sec_filter hci_sec_filter = { /* Packet types */ 0x10, /* Events */ - { 0x1000d9fe, 0x0000300c }, + { 0x1000d9fe, 0x0000b00c }, /* Commands */ { { 0x0 }, /* OGF_LINK_CTL */ - { 0xbe000006, 0x00000001, 0x0000, 0x00 }, + { 0xbe000006, 0x00000001, 0x000000, 0x00 }, /* OGF_LINK_POLICY */ - { 0x00005200, 0x00000000, 0x0000, 0x00 }, + { 0x00005200, 0x00000000, 0x000000, 0x00 }, /* OGF_HOST_CTL */ - { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 }, + { 0xaab00200, 0x2b402aaa, 0x020154, 0x00 }, /* OGF_INFO_PARAM */ - { 0x000002be, 0x00000000, 0x0000, 0x00 }, + { 0x000002be, 0x00000000, 0x000000, 0x00 }, /* OGF_STATUS_PARAM */ - { 0x000000ea, 0x00000000, 0x0000, 0x00 } + { 0x000000ea, 0x00000000, 0x000000, 0x00 } } }; From 245dc3d19b6ff7db42c9f3cca9006c8db59e2dee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 19:20:57 +0200 Subject: [PATCH 0649/1940] [Bluetooth] Ignore additional interfaces of BPA 100/105 devices If a BPA 100/105 device contains more then one interface then ignore the additional interfaces, because they are unused. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bpa10x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 4fa85234d8b5..0db0400519c9 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -550,6 +550,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id * if (ignore) return -ENODEV; + if (intf->cur_altsetting->desc.bInterfaceNumber > 0) + return -ENODEV; + data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) { BT_ERR("Can't allocate data structure"); From 7a691bd34130920bef4d118a3f555ebc48544a63 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Oct 2005 13:17:30 -0500 Subject: [PATCH 0650/1940] [SCSI] avoid overflows in disk size calculations Be more careful about doing the arithmetic in the non-LBD case. Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9a1dc0cea03c..98da5c8057bf 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1253,14 +1253,13 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, * Jacques Gelinas (Jacques@solucorp.qc.ca) */ int hard_sector = sector_size; - sector_t sz = sdkp->capacity * (hard_sector/256); + sector_t sz = (sdkp->capacity/2) * (hard_sector/256); request_queue_t *queue = sdp->request_queue; - sector_t mb; + sector_t mb = sz; blk_queue_hardsect_size(queue, hard_sector); /* avoid 64-bit division on 32-bit platforms */ - mb = sz >> 1; - sector_div(sz, 1250); + sector_div(sz, 625); mb -= sz - 974; sector_div(mb, 1950); From 9a41a62b74388827998253d62c58707e63cc5874 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 20 Sep 2005 13:25:53 -0700 Subject: [PATCH 0651/1940] [SCSI] qla2xxx: remove eh_active checks in qla2xxx error handling Here's a patch which drops the eh_active checks in the qla2xxx eh_handler callbacks. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 41 +++++++++++++---------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 74a26a4a69b6..92976c235ee2 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -762,29 +762,19 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) goto eh_dev_reset_done; } - /* - * If we are coming down the EH path, wait for all commands to - * complete for the device. - */ - if (cmd->device->host->eh_active) { - if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) - ret = FAILED; + /* Flush outstanding commands. */ + if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) + ret = FAILED; + if (ret == FAILED) { + DEBUG3(printk("%s(%ld): failed while waiting for commands\n", + __func__, ha->host_no)); + qla_printk(KERN_INFO, ha, + "%s: failed while waiting for commands\n", __func__); + } else + qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, + id, lun); - if (ret == FAILED) { - DEBUG3(printk("%s(%ld): failed while waiting for " - "commands\n", __func__, ha->host_no)); - qla_printk(KERN_INFO, ha, - "%s: failed while waiting for commands\n", - __func__); - - goto eh_dev_reset_done; - } - } - - qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun); - -eh_dev_reset_done: return ret; } @@ -886,10 +876,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) if (ret == FAILED) goto eh_bus_reset_done; - /* Waiting for our command in done_queue to be returned to OS.*/ - if (cmd->device->host->eh_active) - if (!qla2x00_eh_wait_for_pending_commands(ha)) - ret = FAILED; + /* Flush outstanding commands. */ + if (!qla2x00_eh_wait_for_pending_commands(ha)) + ret = FAILED; eh_bus_reset_done: qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, From 7038f1cbac899654cf0515e60dbe3e44d58271de Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 28 Oct 2005 13:27:40 -0500 Subject: [PATCH 0652/1940] JFS: make sure right-most xtree pages have header.next set to zero The xtTruncate code was only doing this for leaf pages. When a file is horribly fragmented, we may truncate a file leaving an internal page with an invalid head.next field, which may cause a stale page to be referenced. Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_xtree.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index a7fe2f2b969f..e72f4ebb6e9c 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -3516,16 +3516,10 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) /* process entries backward from last index */ index = le16_to_cpu(p->header.nextindex) - 1; - if (p->header.flag & BT_INTERNAL) - goto getChild; - /* - * leaf page - */ - - /* Since this is the rightmost leaf, and we may have already freed - * a page that was formerly to the right, let's make sure that the - * next pointer is zero. + /* Since this is the rightmost page at this level, and we may have + * already freed a page that was formerly to the right, let's make + * sure that the next pointer is zero. */ if (p->header.next) { if (log) @@ -3539,6 +3533,12 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) p->header.next = 0; } + if (p->header.flag & BT_INTERNAL) + goto getChild; + + /* + * leaf page + */ freed = 0; /* does region covered by leaf page precede Teof ? */ From e89e9cf539a28df7d0eb1d0a545368e9920b34ac Mon Sep 17 00:00:00 2001 From: Ananda Raju Date: Tue, 18 Oct 2005 15:46:41 -0700 Subject: [PATCH 0653/1940] [IPv4/IPv6]: UFO Scatter-gather approach Attached is kernel patch for UDP Fragmentation Offload (UFO) feature. 1. This patch incorporate the review comments by Jeff Garzik. 2. Renamed USO as UFO (UDP Fragmentation Offload) 3. udp sendfile support with UFO This patches uses scatter-gather feature of skb to generate large UDP datagram. Below is a "how-to" on changes required in network device driver to use the UFO interface. UDP Fragmentation Offload (UFO) Interface: ------------------------------------------- UFO is a feature wherein the Linux kernel network stack will offload the IP fragmentation functionality of large UDP datagram to hardware. This will reduce the overhead of stack in fragmenting the large UDP datagram to MTU sized packets 1) Drivers indicate their capability of UFO using dev->features |= NETIF_F_UFO | NETIF_F_HW_CSUM | NETIF_F_SG NETIF_F_HW_CSUM is required for UFO over ipv6. 2) UFO packet will be submitted for transmission using driver xmit routine. UFO packet will have a non-zero value for "skb_shinfo(skb)->ufo_size" skb_shinfo(skb)->ufo_size will indicate the length of data part in each IP fragment going out of the adapter after IP fragmentation by hardware. skb->data will contain MAC/IP/UDP header and skb_shinfo(skb)->frags[] contains the data payload. The skb->ip_summed will be set to CHECKSUM_HW indicating that hardware has to do checksum calculation. Hardware should compute the UDP checksum of complete datagram and also ip header checksum of each fragmented IP packet. For IPV6 the UFO provides the fragment identification-id in skb_shinfo(skb)->ip6_frag_id. The adapter should use this ID for generating IPv6 fragments. Signed-off-by: Ananda Raju Signed-off-by: Rusty Russell (forwarded) Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/ethtool.h | 8 ++++ include/linux/netdevice.h | 1 + include/linux/skbuff.h | 7 ++++ net/core/dev.c | 14 +++++++ net/core/ethtool.c | 53 +++++++++++++++++++++++++ net/core/skbuff.c | 75 +++++++++++++++++++++++++++++++++++ net/ipv4/ip_output.c | 83 ++++++++++++++++++++++++++++++++++++--- net/ipv6/ip6_output.c | 71 ++++++++++++++++++++++++++++++++- 8 files changed, 306 insertions(+), 6 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ed1440ea4c91..d2c390eff1b2 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -269,6 +269,8 @@ u32 ethtool_op_get_tso(struct net_device *dev); int ethtool_op_set_tso(struct net_device *dev, u32 data); int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *addr, u8 *data); +u32 ethtool_op_get_ufo(struct net_device *dev); +int ethtool_op_set_ufo(struct net_device *dev, u32 data); /** * ðtool_ops - Alter and report network device settings @@ -298,6 +300,8 @@ int ethtool_op_get_perm_addr(struct net_device *dev, * set_sg: Turn scatter-gather on or off * get_tso: Report whether TCP segmentation offload is enabled * set_tso: Turn TCP segmentation offload on or off + * get_ufo: Report whether UDP fragmentation offload is enabled + * set_ufo: Turn UDP fragmentation offload on or off * self_test: Run specified self-tests * get_strings: Return a set of strings that describe the requested objects * phys_id: Identify the device @@ -364,6 +368,8 @@ struct ethtool_ops { int (*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *); int (*begin)(struct net_device *); void (*complete)(struct net_device *); + u32 (*get_ufo)(struct net_device *); + int (*set_ufo)(struct net_device *, u32); }; /* CMDs currently supported */ @@ -400,6 +406,8 @@ struct ethtool_ops { #define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ #define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ #define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */ +#define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */ +#define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a9281b24c40b..c6efce4a04a4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -308,6 +308,7 @@ struct net_device #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ #define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ #define NETIF_F_LLTX 4096 /* LockLess TX */ +#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/ struct net_device *next_sched; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b756935da9c8..4286d832166f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -137,6 +137,8 @@ struct skb_shared_info { unsigned int nr_frags; unsigned short tso_size; unsigned short tso_segs; + unsigned short ufo_size; + unsigned int ip6_frag_id; struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; }; @@ -341,6 +343,11 @@ extern void skb_over_panic(struct sk_buff *skb, int len, extern void skb_under_panic(struct sk_buff *skb, int len, void *here); +extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, + int getfrag(void *from, char *to, int offset, + int len,int odd, struct sk_buff *skb), + void *from, int length); + struct skb_seq_state { __u32 lower_offset; diff --git a/net/core/dev.c b/net/core/dev.c index a44eeef24edf..8d1541595277 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2717,6 +2717,20 @@ int register_netdevice(struct net_device *dev) dev->name); dev->features &= ~NETIF_F_TSO; } + if (dev->features & NETIF_F_UFO) { + if (!(dev->features & NETIF_F_HW_CSUM)) { + printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " + "NETIF_F_HW_CSUM feature.\n", + dev->name); + dev->features &= ~NETIF_F_UFO; + } + if (!(dev->features & NETIF_F_SG)) { + printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " + "NETIF_F_SG feature.\n", + dev->name); + dev->features &= ~NETIF_F_UFO; + } + } /* * nil rebuild_header routine, diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 404b761e82ce..0350586e9195 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -93,6 +93,20 @@ int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *a } +u32 ethtool_op_get_ufo(struct net_device *dev) +{ + return (dev->features & NETIF_F_UFO) != 0; +} + +int ethtool_op_set_ufo(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_UFO; + else + dev->features &= ~NETIF_F_UFO; + return 0; +} + /* Handlers for each ethtool command */ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) @@ -483,6 +497,11 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data) return err; } + if (!data && dev->ethtool_ops->set_ufo) { + err = dev->ethtool_ops->set_ufo(dev, 0); + if (err) + return err; + } return dev->ethtool_ops->set_sg(dev, data); } @@ -569,6 +588,32 @@ static int ethtool_set_tso(struct net_device *dev, char __user *useraddr) return dev->ethtool_ops->set_tso(dev, edata.data); } +static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTSO }; + + if (!dev->ethtool_ops->get_ufo) + return -EOPNOTSUPP; + edata.data = dev->ethtool_ops->get_ufo(dev); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} +static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_ufo) + return -EOPNOTSUPP; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + if (edata.data && !(dev->features & NETIF_F_SG)) + return -EINVAL; + if (edata.data && !(dev->features & NETIF_F_HW_CSUM)) + return -EINVAL; + return dev->ethtool_ops->set_ufo(dev, edata.data); +} + static int ethtool_self_test(struct net_device *dev, char __user *useraddr) { struct ethtool_test test; @@ -854,6 +899,12 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_GPERMADDR: rc = ethtool_get_perm_addr(dev, useraddr); break; + case ETHTOOL_GUFO: + rc = ethtool_get_ufo(dev, useraddr); + break; + case ETHTOOL_SUFO: + rc = ethtool_set_ufo(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } @@ -882,3 +933,5 @@ EXPORT_SYMBOL(ethtool_op_set_sg); EXPORT_SYMBOL(ethtool_op_set_tso); EXPORT_SYMBOL(ethtool_op_set_tx_csum); EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); +EXPORT_SYMBOL(ethtool_op_set_ufo); +EXPORT_SYMBOL(ethtool_op_get_ufo); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index ef9d46b91eb9..95501e40100e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -176,6 +176,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, skb_shinfo(skb)->tso_size = 0; skb_shinfo(skb)->tso_segs = 0; skb_shinfo(skb)->frag_list = NULL; + skb_shinfo(skb)->ufo_size = 0; + skb_shinfo(skb)->ip6_frag_id = 0; out: return skb; nodata: @@ -1696,6 +1698,78 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, return textsearch_find(config, state); } +/** + * skb_append_datato_frags: - append the user data to a skb + * @sk: sock structure + * @skb: skb structure to be appened with user data. + * @getfrag: call back function to be used for getting the user data + * @from: pointer to user message iov + * @length: length of the iov message + * + * Description: This procedure append the user data in the fragment part + * of the skb if any page alloc fails user this procedure returns -ENOMEM + */ +int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, + int getfrag(void *from, char *to, int offset, + int len, int odd, struct sk_buff *skb), + void *from, int length) +{ + int frg_cnt = 0; + skb_frag_t *frag = NULL; + struct page *page = NULL; + int copy, left; + int offset = 0; + int ret; + + do { + /* Return error if we don't have space for new frag */ + frg_cnt = skb_shinfo(skb)->nr_frags; + if (frg_cnt >= MAX_SKB_FRAGS) + return -EFAULT; + + /* allocate a new page for next frag */ + page = alloc_pages(sk->sk_allocation, 0); + + /* If alloc_page fails just return failure and caller will + * free previous allocated pages by doing kfree_skb() + */ + if (page == NULL) + return -ENOMEM; + + /* initialize the next frag */ + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; + skb_fill_page_desc(skb, frg_cnt, page, 0, 0); + skb->truesize += PAGE_SIZE; + atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); + + /* get the new initialized frag */ + frg_cnt = skb_shinfo(skb)->nr_frags; + frag = &skb_shinfo(skb)->frags[frg_cnt - 1]; + + /* copy the user data to page */ + left = PAGE_SIZE - frag->page_offset; + copy = (length > left)? left : length; + + ret = getfrag(from, (page_address(frag->page) + + frag->page_offset + frag->size), + offset, copy, 0, skb); + if (ret < 0) + return -EFAULT; + + /* copy was successful so update the size parameters */ + sk->sk_sndmsg_off += copy; + frag->size += copy; + skb->len += copy; + skb->data_len += copy; + offset += copy; + length -= copy; + + } while (length > 0); + + return 0; +} + void __init skb_init(void) { skbuff_head_cache = kmem_cache_create("skbuff_head_cache", @@ -1747,3 +1821,4 @@ EXPORT_SYMBOL(skb_prepare_seq_read); EXPORT_SYMBOL(skb_seq_read); EXPORT_SYMBOL(skb_abort_seq_read); EXPORT_SYMBOL(skb_find_text); +EXPORT_SYMBOL(skb_append_datato_frags); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 87e350069abb..17758234a3e3 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -275,7 +275,8 @@ int ip_output(struct sk_buff *skb) { IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); - if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size) + if (skb->len > dst_mtu(skb->dst) && + !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) return ip_fragment(skb, ip_finish_output); else return ip_finish_output(skb); @@ -688,6 +689,60 @@ csum_page(struct page *page, int offset, int copy) return csum; } +inline int ip_ufo_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, int len, + int odd, struct sk_buff *skb), + void *from, int length, int hh_len, int fragheaderlen, + int transhdrlen, int mtu,unsigned int flags) +{ + struct sk_buff *skb; + int err; + + /* There is support for UDP fragmentation offload by network + * device, so create one single skb packet containing complete + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); + + if (skb == NULL) + return err; + + /* reserve space for Hardware header */ + skb_reserve(skb, hh_len); + + /* create space for UDP/IP header */ + skb_put(skb,fragheaderlen + transhdrlen); + + /* initialize network header pointer */ + skb->nh.raw = skb->data; + + /* initialize protocol header pointer */ + skb->h.raw = skb->data + fragheaderlen; + + skb->ip_summed = CHECKSUM_HW; + skb->csum = 0; + sk->sk_sndmsg_off = 0; + } + + err = skb_append_datato_frags(sk,skb, getfrag, from, + (length - transhdrlen)); + if (!err) { + /* specify the length of each IP datagram fragment*/ + skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); + __skb_queue_tail(&sk->sk_write_queue, skb); + + return 0; + } + /* There is not enough support do UFO , + * so follow normal path + */ + kfree_skb(skb); + return err; +} + /* * ip_append_data() and ip_append_page() can make one large IP datagram * from many pieces of data. Each pieces will be holded on the socket @@ -777,6 +832,15 @@ int ip_append_data(struct sock *sk, csummode = CHECKSUM_HW; inet->cork.length += length; + if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && + (rt->u.dst.dev->features & NETIF_F_UFO)) { + + if(ip_ufo_append_data(sk, getfrag, from, length, hh_len, + fragheaderlen, transhdrlen, mtu, flags)) + goto error; + + return 0; + } /* So, what's going on in the loop below? * @@ -1008,14 +1072,23 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, return -EINVAL; inet->cork.length += size; + if ((sk->sk_protocol == IPPROTO_UDP) && + (rt->u.dst.dev->features & NETIF_F_UFO)) + skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); + while (size > 0) { int i; - /* Check if the remaining data fits into current packet. */ - len = mtu - skb->len; - if (len < size) - len = maxfraglen - skb->len; + if (skb_shinfo(skb)->ufo_size) + len = size; + else { + + /* Check if the remaining data fits into current packet. */ + len = mtu - skb->len; + if (len < size) + len = maxfraglen - skb->len; + } if (len <= 0) { struct sk_buff *skb_prev; char *data; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 563b442ffab8..614296a920c6 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -147,7 +147,8 @@ static int ip6_output2(struct sk_buff *skb) int ip6_output(struct sk_buff *skb) { - if (skb->len > dst_mtu(skb->dst) || dst_allfrag(skb->dst)) + if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) || + dst_allfrag(skb->dst)) return ip6_fragment(skb, ip6_output2); else return ip6_output2(skb); @@ -768,6 +769,65 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) *dst = NULL; return err; } +inline int ip6_ufo_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, int len, + int odd, struct sk_buff *skb), + void *from, int length, int hh_len, int fragheaderlen, + int transhdrlen, int mtu,unsigned int flags) + +{ + struct sk_buff *skb; + int err; + + /* There is support for UDP large send offload by network + * device, so create one single skb packet containing complete + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); + if (skb == NULL) + return -ENOMEM; + + /* reserve space for Hardware header */ + skb_reserve(skb, hh_len); + + /* create space for UDP/IP header */ + skb_put(skb,fragheaderlen + transhdrlen); + + /* initialize network header pointer */ + skb->nh.raw = skb->data; + + /* initialize protocol header pointer */ + skb->h.raw = skb->data + fragheaderlen; + + skb->ip_summed = CHECKSUM_HW; + skb->csum = 0; + sk->sk_sndmsg_off = 0; + } + + err = skb_append_datato_frags(sk,skb, getfrag, from, + (length - transhdrlen)); + if (!err) { + struct frag_hdr fhdr; + + /* specify the length of each IP datagram fragment*/ + skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - + sizeof(struct frag_hdr); + ipv6_select_ident(skb, &fhdr); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); + + return 0; + } + /* There is not enough support do UPD LSO, + * so follow normal path + */ + kfree_skb(skb); + + return err; +} int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), @@ -860,6 +920,15 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, */ inet->cork.length += length; + if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && + (rt->u.dst.dev->features & NETIF_F_UFO)) { + + if(ip6_ufo_append_data(sk, getfrag, from, length, hh_len, + fragheaderlen, transhdrlen, mtu, flags)) + goto error; + + return 0; + } if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) goto alloc_new_skb; From f12baeab9d65e2fe1b43b09b666f5efcb81b9369 Mon Sep 17 00:00:00 2001 From: Yan Zheng Date: Sat, 29 Oct 2005 00:02:32 +0800 Subject: [PATCH 0654/1940] [MCAST] IPv6: Fix algorithm to compute Querier's Query Interval 5.1.3. Maximum Response Code The Maximum Response Code field specifies the maximum time allowed before sending a responding Report. The actual time allowed, called the Maximum Response Delay, is represented in units of milliseconds, and is derived from the Maximum Response Code as follows: If Maximum Response Code < 32768, Maximum Response Delay = Maximum Response Code If Maximum Response Code >=32768, Maximum Response Code represents a floating-point value as follows: 0 1 2 3 4 5 6 7 8 9 A B C D E F +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| exp | mant | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Maximum Response Delay = (mant | 0x1000) << (exp+3) 5.1.9. QQIC (Querier's Query Interval Code) The Querier's Query Interval Code field specifies the [Query Interval] used by the Querier. The actual interval, called the Querier's Query Interval (QQI), is represented in units of seconds, and is derived from the Querier's Query Interval Code as follows: If QQIC < 128, QQI = QQIC If QQIC >= 128, QQIC represents a floating-point value as follows: 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ |1| exp | mant | +-+-+-+-+-+-+-+-+ QQI = (mant | 0x10) << (exp + 3) -- rfc3810 #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) Above macro are defined in mcast.c. but 1 << 4 == 0x10 and 1 << 12 == 0x1000. So the result computed by original Macro is larger. Signed-off-by: Yan Zheng Acked-by: David L Stevens Signed-off-by: Arnaldo Carvalho de Melo --- net/ipv6/mcast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 39a96c768102..c4f2a0ef7489 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -164,7 +164,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, #define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) #define MLDV2_EXP(thresh, nbmant, nbexp, value) \ ((value) < (thresh) ? (value) : \ - ((MLDV2_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \ + ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) From 9ccfc756a70d454dfa82f48897e2883560c01a0e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 2 Oct 2005 11:45:08 -0500 Subject: [PATCH 0655/1940] [SCSI] move the mid-layer printk's over to shost/starget/sdev_printk This should eliminate (at least in the mid layer) to make numeric assumptions about any of the enumeration variables. As a side effect, it will also make all the messages consistent and line us up nicely for the error logging strategy (if it ever shows itself again). Signed-off-by: James Bottomley --- drivers/scsi/constants.c | 5 +--- drivers/scsi/hosts.c | 10 +++---- drivers/scsi/osst.c | 6 ++-- drivers/scsi/scsi.c | 21 ++++++-------- drivers/scsi/scsi_error.c | 25 ++++++----------- drivers/scsi/scsi_ioctl.c | 10 ++----- drivers/scsi/scsi_lib.c | 46 +++++++++++++++---------------- drivers/scsi/scsi_scan.c | 7 ++--- drivers/scsi/scsi_transport_fc.c | 2 -- drivers/scsi/scsi_transport_spi.c | 24 ++++++++-------- drivers/scsi/sd.c | 10 +++---- drivers/scsi/sg.c | 14 ++++------ drivers/scsi/sr.c | 15 +++++----- drivers/scsi/st.c | 10 +++---- include/scsi/scsi_device.h | 6 ++++ include/scsi/scsi_host.h | 4 +++ 16 files changed, 96 insertions(+), 119 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index f6be2c1c3942..09bc81557b6e 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1389,10 +1389,7 @@ EXPORT_SYMBOL(scsi_print_msg); void scsi_print_command(struct scsi_cmnd *cmd) { /* Assume appended output (i.e. not at start of line) */ - printk("scsi%d : destination target %d, lun %d\n", - cmd->device->host->host_no, - cmd->device->id, - cmd->device->lun); + sdev_printk("", cmd->device, "\n"); printk(KERN_INFO " command: "); scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0); } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index f24d84538fd5..0d48c9ceebd3 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -139,11 +139,11 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) illegal: SCSI_LOG_ERROR_RECOVERY(1, - dev_printk(KERN_ERR, &shost->shost_gendev, - "Illegal host state transition" - "%s->%s\n", - scsi_host_state_name(oldstate), - scsi_host_state_name(state))); + shost_printk(KERN_ERR, shost, + "Illegal host state transition" + "%s->%s\n", + scsi_host_state_name(oldstate), + scsi_host_state_name(state))); return -EINVAL; } EXPORT_SYMBOL(scsi_host_set_state); diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index af1133104b3f..c1131c9cae64 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5819,9 +5819,9 @@ static int osst_probe(struct device *dev) } drive->number = devfs_register_tape(SDp->devfs_name); - printk(KERN_INFO - "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n", - SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt)); + dev_printk(KERN_INFO, &SDp->sdev_gendev, + "osst :I: Attached OnStream %.5s tape as %s\n", + SDp->model, tape_name(tpnt)); return 0; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a5711d545d71..071d109b4b2a 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -410,9 +410,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) SCSI_LOG_MLQUEUE_BITS); if (level > 1) { sdev = cmd->device; - printk(KERN_INFO "scsi <%d:%d:%d:%d> send ", - sdev->host->host_no, sdev->channel, sdev->id, - sdev->lun); + sdev_printk(KERN_INFO, sdev, "send "); if (level > 2) printk("0x%p ", cmd); /* @@ -456,9 +454,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) if (((level > 0) && (cmd->result || disposition != SUCCESS)) || (level > 1)) { sdev = cmd->device; - printk(KERN_INFO "scsi <%d:%d:%d:%d> done ", - sdev->host->host_no, sdev->channel, sdev->id, - sdev->lun); + sdev_printk(KERN_INFO, sdev, "done "); if (level > 2) printk("0x%p ", cmd); /* @@ -810,9 +806,9 @@ static void scsi_softirq(struct softirq_action *h) disposition = scsi_decide_disposition(cmd); if (disposition != SUCCESS && time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { - dev_printk(KERN_ERR, &cmd->device->sdev_gendev, - "timing out command, waited %lus\n", - wait_for/HZ); + sdev_printk(KERN_ERR, cmd->device, + "timing out command, waited %lus\n", + wait_for/HZ); disposition = SUCCESS; } @@ -970,10 +966,9 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) sdev->simple_tags = 1; break; default: - printk(KERN_WARNING "(scsi%d:%d:%d:%d) " - "scsi_adjust_queue_depth, bad queue type, " - "disabled\n", sdev->host->host_no, - sdev->channel, sdev->id, sdev->lun); + sdev_printk(KERN_WARNING, sdev, + "scsi_adjust_queue_depth, bad queue type, " + "disabled\n"); case 0: sdev->ordered_tags = sdev->simple_tags = 0; sdev->queue_depth = tags; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 52b348c36d56..dd6a9f61bdf1 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -241,11 +241,10 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost, if (cmd_cancel || cmd_failed) { SCSI_LOG_ERROR_RECOVERY(3, - printk("%s: %d:%d:%d:%d cmds failed: %d," - " cancel: %d\n", - __FUNCTION__, shost->host_no, - sdev->channel, sdev->id, sdev->lun, - cmd_failed, cmd_cancel)); + sdev_printk(KERN_INFO, sdev, + "%s: cmds failed: %d, cancel: %d\n", + __FUNCTION__, cmd_failed, + cmd_cancel)); cmd_cancel = 0; cmd_failed = 0; ++devices_failed; @@ -1174,13 +1173,9 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, struct scsi_cmnd *scmd, *next; list_for_each_entry_safe(scmd, next, work_q, eh_entry) { - printk(KERN_INFO "scsi: Device offlined - not" - " ready after error recovery: host" - " %d channel %d id %d lun %d\n", - scmd->device->host->host_no, - scmd->device->channel, - scmd->device->id, - scmd->device->lun); + sdev_printk(KERN_INFO, scmd->device, + "scsi: Device offlined - not" + " ready after error recovery\n"); scsi_device_set_state(scmd->device, SDEV_OFFLINE); if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) { /* @@ -1342,10 +1337,8 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) return SUCCESS; case RESERVATION_CONFLICT: - printk(KERN_INFO "scsi: reservation conflict: host" - " %d channel %d id %d lun %d\n", - scmd->device->host->host_no, scmd->device->channel, - scmd->device->id, scmd->device->lun); + sdev_printk(KERN_INFO, scmd->device, + "reservation conflict\n"); return SUCCESS; /* causes immediate i/o error */ default: return FAILED; diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 6a3f6aae8a97..26f5bc6d9c82 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -122,13 +122,9 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, break; } default: /* Fall through for non-removable media */ - printk(KERN_INFO "ioctl_internal_command: <%d %d %d " - "%d> return code = %x\n", - sdev->host->host_no, - sdev->channel, - sdev->id, - sdev->lun, - result); + sdev_printk(KERN_INFO, sdev, + "ioctl_internal_command return code = %x\n", + result); scsi_print_sense_hdr(" ", &sshdr); break; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3ff538809786..19ac888001e6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -951,16 +951,16 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, return; } if (!(req->flags & REQ_QUIET)) - dev_printk(KERN_INFO, - &cmd->device->sdev_gendev, - "Device not ready.\n"); + sdev_printk(KERN_INFO, + cmd->device, + "Device not ready.\n"); scsi_end_request(cmd, 0, this_count, 1); return; case VOLUME_OVERFLOW: if (!(req->flags & REQ_QUIET)) { - dev_printk(KERN_INFO, - &cmd->device->sdev_gendev, - "Volume overflow, CDB: "); + sdev_printk(KERN_INFO, + cmd->device, + "Volume overflow, CDB: "); __scsi_print_command(cmd->data_cmnd); scsi_print_sense("", cmd); } @@ -981,8 +981,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, } if (result) { if (!(req->flags & REQ_QUIET)) { - dev_printk(KERN_INFO, &cmd->device->sdev_gendev, - "SCSI error: return code = 0x%x\n", result); + sdev_printk(KERN_INFO, cmd->device, + "SCSI error: return code = 0x%x\n", + result); if (driver_byte(result) & DRIVER_SENSE) scsi_print_sense("", cmd); @@ -1141,8 +1142,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) * online before trying any recovery commands */ if (unlikely(!scsi_device_online(sdev))) { - printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n", - sdev->host->host_no, sdev->id, sdev->lun); + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to offline device\n"); goto kill; } if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { @@ -1151,8 +1152,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) if (sdev->sdev_state == SDEV_DEL) { /* Device is fully deleted, no commands * at all allowed down */ - printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n", - sdev->host->host_no, sdev->id, sdev->lun); + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to dead device\n"); goto kill; } /* OK, we only allow special commands (i.e. not @@ -1187,8 +1188,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) specials_only == SDEV_BLOCK) goto defer; - printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n", - sdev->host->host_no, sdev->id, sdev->lun); + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to device being removed\n"); goto kill; } @@ -1315,9 +1316,8 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, */ if (--sdev->device_blocked == 0) { SCSI_LOG_MLQUEUE(3, - printk("scsi%d (%d:%d) unblocking device at" - " zero depth\n", sdev->host->host_no, - sdev->id, sdev->lun)); + sdev_printk(KERN_INFO, sdev, + "unblocking device at zero depth\n")); } else { blk_plug_device(q); return 0; @@ -1436,8 +1436,8 @@ static void scsi_request_fn(struct request_queue *q) break; if (unlikely(!scsi_device_online(sdev))) { - printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n", - sdev->host->host_no, sdev->id, sdev->lun); + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to offline device\n"); scsi_kill_request(req, q); continue; } @@ -1893,10 +1893,10 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) illegal: SCSI_LOG_ERROR_RECOVERY(1, - dev_printk(KERN_ERR, &sdev->sdev_gendev, - "Illegal state transition %s->%s\n", - scsi_device_state_name(oldstate), - scsi_device_state_name(state)) + sdev_printk(KERN_ERR, sdev, + "Illegal state transition %s->%s\n", + scsi_device_state_name(oldstate), + scsi_device_state_name(state)) ); return -EINVAL; } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 327c5d7e5bd2..ce8456c3b718 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -462,10 +462,9 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, pass = 1; next_pass: - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY pass %d " - "to host %d channel %d id %d lun %d, length %d\n", - pass, sdev->host->host_no, sdev->channel, - sdev->id, sdev->lun, try_inquiry_len)); + SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, + "scsi scan: INQUIRY pass %d length %d\n", + pass, try_inquiry_len)); /* Each pass gets up to three chances to ignore Unit Attention */ for (count = 0; count < 3; ++count) { diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 771e97ef136e..473a82d5e3e2 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -32,8 +32,6 @@ #include #include "scsi_priv.h" -#define FC_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a) - /* * Redefine so that we can have same named attributes in the * sdev/starget/host objects. diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index ef577c8c2182..718a2bc4ed5e 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -33,8 +33,6 @@ #include #include -#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) - #define SPI_NUM_ATTRS 14 /* increase this if you add attributes */ #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always * on" attributes */ @@ -618,7 +616,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, return SPI_COMPARE_SKIP_TEST; - SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", result); + sdev_printk(KERN_ERR, sdev, "Write Buffer failure %x\n", result); return SPI_COMPARE_FAILURE; } @@ -702,10 +700,10 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr, * IU, then QAS (if we can control them), then finally * fall down the periods */ if (i->f->set_iu && spi_iu(starget)) { - SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Information Units\n"); + starget_printk(KERN_ERR, starget, "Domain Validation Disabing Information Units\n"); DV_SET(iu, 0); } else if (i->f->set_qas && spi_qas(starget)) { - SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Quick Arbitration and Selection\n"); + starget_printk(KERN_ERR, starget, "Domain Validation Disabing Quick Arbitration and Selection\n"); DV_SET(qas, 0); } else { newperiod = spi_period(starget); @@ -717,11 +715,11 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr, if (unlikely(period > 0xff || period == prevperiod)) { /* Total failure; set to async and return */ - SPI_PRINTK(starget, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); + starget_printk(KERN_ERR, starget, "Domain Validation Failure, dropping back to Asynchronous\n"); DV_SET(offset, 0); return SPI_COMPARE_FAILURE; } - SPI_PRINTK(starget, KERN_ERR, "Domain Validation detected failure, dropping back\n"); + starget_printk(KERN_ERR, starget, "Domain Validation detected failure, dropping back\n"); DV_SET(period, period); prevperiod = period; } @@ -788,7 +786,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) != SPI_COMPARE_SUCCESS) { - SPI_PRINTK(starget, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); + starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); /* FIXME: should probably offline the device here? */ return; } @@ -802,7 +800,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) buffer + len, DV_LOOPS) != SPI_COMPARE_SUCCESS) { - SPI_PRINTK(starget, KERN_ERR, "Wide Transfers Fail\n"); + starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); i->f->set_width(starget, 0); } } @@ -844,14 +842,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) } if (len == 0) { - SPI_PRINTK(starget, KERN_INFO, "Domain Validation skipping write tests\n"); + starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n"); spi_dv_retrain(sdev, buffer, buffer + len, spi_dv_device_compare_inquiry); return; } if (len > SPI_MAX_ECHO_BUFFER_SIZE) { - SPI_PRINTK(starget, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); + starget_printk(KERN_WARNING, starget, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); len = SPI_MAX_ECHO_BUFFER_SIZE; } @@ -902,11 +900,11 @@ spi_dv_device(struct scsi_device *sdev) spi_dv_pending(starget) = 1; down(&spi_dv_sem(starget)); - SPI_PRINTK(starget, KERN_INFO, "Beginning Domain Validation\n"); + starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n"); spi_dv_device_internal(sdev, buffer); - SPI_PRINTK(starget, KERN_INFO, "Ending Domain Validation\n"); + starget_printk(KERN_INFO, starget, "Ending Domain Validation\n"); up(&spi_dv_sem(starget)); spi_dv_pending(starget) = 0; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 98da5c8057bf..9de8e186cb69 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1534,8 +1534,8 @@ static int sd_probe(struct device *dev) if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC) goto out; - SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", - sdp->host->host_no, sdp->channel, sdp->id, sdp->lun)); + SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp, + "sd_attach\n")); error = -ENOMEM; sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL); @@ -1607,10 +1607,8 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, " - "id %d, lun %d\n", sdp->removable ? "removable " : "", - gd->disk_name, sdp->host->host_no, sdp->channel, - sdp->id, sdp->lun); + sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n", + sdp->removable ? "removable " : "", gd->disk_name); return 0; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index fd56b7ec88b6..49b9269d487a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1497,10 +1497,9 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) overflow: write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - printk(KERN_WARNING - "Unable to attach sg device <%d, %d, %d, %d> type=%d, minor " - "number exceeds %d\n", scsidp->host->host_no, scsidp->channel, - scsidp->id, scsidp->lun, scsidp->type, SG_MAX_DEVS - 1); + sdev_printk(KERN_WARNING, scsidp, + "Unable to attach sg device type=%d, minor " + "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); error = -ENODEV; goto out; } @@ -1566,11 +1565,8 @@ sg_add(struct class_device *cl_dev) } else printk(KERN_WARNING "sg_add: sg_sys INvalid\n"); - printk(KERN_NOTICE - "Attached scsi generic sg%d at scsi%d, channel" - " %d, id %d, lun %d, type %d\n", k, - scsidp->host->host_no, scsidp->channel, scsidp->id, - scsidp->lun, scsidp->type); + sdev_printk(KERN_NOTICE, scsidp, + "Attached scsi generic sg%d type %d\n", k,scsidp->type); return 0; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 561901b1cf11..9e267c6d3a43 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) } if (s_size != 512 && s_size != 1024 && s_size != 2048) { - printk("sr: bad sector size %d\n", s_size); + sdev_printk(KERN_ERR, SCpnt->device, "bad sector size %d\n", s_size); return 0; } @@ -385,8 +385,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) size += sg[i].length; if (size != SCpnt->request_bufflen && SCpnt->use_sg) { - printk(KERN_ERR "sr: mismatch count %d, bytes %d\n", - size, SCpnt->request_bufflen); + sdev_printk(KERN_ERR, SCpnt->device, + "mismatch count %d, bytes %d\n", + size, SCpnt->request_bufflen); if (SCpnt->request_bufflen > size) SCpnt->request_bufflen = SCpnt->bufflen = size; } @@ -397,7 +398,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) */ if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { - printk("sr: unaligned transfer\n"); + sdev_printk(KERN_NOTICE, SCpnt->device, "unaligned transfer\n"); return 0; } @@ -622,10 +623,8 @@ static int sr_probe(struct device *dev) disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); - printk(KERN_DEBUG - "Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n", - cd->cdi.name, sdev->host->host_no, sdev->channel, - sdev->id, sdev->lun); + sdev_printk(KERN_DEBUG, sdev, + "Attached scsi CD-ROM %s\n", cd->cdi.name); return 0; fail_put: diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 927d700f0073..dc5ffc16a252 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3887,9 +3887,8 @@ static int st_probe(struct device *dev) if (SDp->type != TYPE_TAPE) return -ENODEV; if ((stp = st_incompatible(SDp))) { - printk(KERN_INFO - "st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n", - SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); + sdev_printk(KERN_INFO, SDp, + "Found incompatible tape\n"); printk(KERN_INFO "st: The suggested driver is %s.\n", stp); return -ENODEV; } @@ -4077,9 +4076,8 @@ static int st_probe(struct device *dev) } disk->number = devfs_register_tape(SDp->devfs_name); - printk(KERN_WARNING - "Attached scsi tape %s at scsi%d, channel %d, id %d, lun %d\n", - tape_name(tpnt), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); + sdev_printk(KERN_WARNING, SDp, + "Attached scsi tape %s", tape_name(tpnt)); printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n", tape_name(tpnt), tpnt->try_dio ? "yes" : "no", queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 7ece05666feb..7f621ab2865d 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -148,6 +148,9 @@ struct scsi_device { #define transport_class_to_sdev(class_dev) \ to_scsi_device(class_dev->dev) +#define sdev_printk(prefix, sdev, fmt, a...) \ + dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) + /* * scsi_target: representation of a scsi target, for now, this is only * used for single_lun devices. If no one has active IO to the target, @@ -177,6 +180,9 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev) #define transport_class_to_starget(class_dev) \ to_scsi_target(class_dev->dev) +#define starget_printk(prefix, starget, fmt, a...) \ + dev_printk(prefix, &(starget)->dev, fmt, ##a) + extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, uint, uint, uint, void *hostdata); extern int scsi_add_device(struct Scsi_Host *host, uint channel, diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 69313ba7505b..ea7ad7235397 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -609,6 +609,10 @@ struct Scsi_Host { #define class_to_shost(d) \ container_of(d, struct Scsi_Host, shost_classdev) +#define shost_printk(prefix, shost, fmt, a...) \ + dev_printk(prefix, &(shost)->shost_gendev, fmt, ##a) + + int scsi_is_host_device(const struct device *); static inline struct Scsi_Host *dev_to_shost(struct device *dev) From aa353de649f1ba05a71b2f5b8eb1e99632ab54eb Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 11 Oct 2005 16:31:08 -0700 Subject: [PATCH 0656/1940] [SCSI] qla2xxx: fix compile warning The file is missing an include of scsi_transport_fc.h drivers/scsi/qla2xxx/qla_rscn.c:334: error: implicit declaration of function 'fc_remote_port_unblock' Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_rscn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index cb40d61e82d5..3e53f62d640d 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c @@ -6,6 +6,8 @@ */ #include "qla_def.h" +#include + /** * IO descriptor handle definitions. * From 72df8325f4808330977d8f54c3458d30615dcb54 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Oct 2005 14:41:19 -0500 Subject: [PATCH 0657/1940] [SCSI] qla2xxx: fix unnecessary activation of blk tag queue From: 'Andrew Vasquez' Drop scsi_populate_tag_msg() interrogation. Signed-off-by: Andrew Vasquez Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_iocb.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 17f5697feba6..7ec0b8d6f07b 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -303,7 +303,6 @@ qla2x00_start_scsi(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct device_reg_2xxx __iomem *reg; - char tag[2]; /* Setup device pointers. */ ret = 0; @@ -388,18 +387,6 @@ qla2x00_start_scsi(srb_t *sp) /* Update tagged queuing modifier */ cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG); - if (scsi_populate_tag_msg(cmd, tag)) { - switch (tag[0]) { - case MSG_HEAD_TAG: - cmd_pkt->control_flags = - __constant_cpu_to_le16(CF_HEAD_TAG); - break; - case MSG_ORDERED_TAG: - cmd_pkt->control_flags = - __constant_cpu_to_le16(CF_ORDERED_TAG); - break; - } - } /* Load SCSI command packet. */ memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len); @@ -741,7 +728,6 @@ qla24xx_start_scsi(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct device_reg_24xx __iomem *reg; - char tag[2]; /* Setup device pointers. */ ret = 0; @@ -816,6 +802,7 @@ qla24xx_start_scsi(srb_t *sp) cmd_pkt->handle = handle; /* Zero out remaining portion of packet. */ + /* tagged queuing modifier -- default is TSK_SIMPLE (0). */ clr_ptr = (uint32_t *)cmd_pkt + 2; memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); @@ -828,18 +815,6 @@ qla24xx_start_scsi(srb_t *sp) int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); - /* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */ - if (scsi_populate_tag_msg(cmd, tag)) { - switch (tag[0]) { - case MSG_HEAD_TAG: - cmd_pkt->task = TSK_HEAD_OF_QUEUE; - break; - case MSG_ORDERED_TAG: - cmd_pkt->task = TSK_ORDERED; - break; - } - } - /* Load SCSI command packet. */ memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); From a21a84a375ea3783cf9a53730d643c4db24371bc Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 28 Oct 2005 15:43:16 -0400 Subject: [PATCH 0658/1940] [libata pdc_adma] minor fixes and cleanups Changes mostly from Mark Lord. - fix bugs in probe-time error handling - only complete qc if not NULL - check port-level polling flags --- drivers/scsi/pdc_adma.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 9820f272f889..7999817915c3 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -46,7 +46,7 @@ #include #define DRV_NAME "pdc_adma" -#define DRV_VERSION "0.01" +#define DRV_VERSION "0.03" /* macro to calculate base address for ATA regs */ #define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40)) @@ -79,7 +79,6 @@ enum { aNIEN = (1 << 8), /* irq mask: 1==masked */ aGO = (1 << 7), /* packet trigger ("Go!") */ aRSTADM = (1 << 5), /* ADMA logic reset */ - aRSTA = (1 << 2), /* ATA hard reset */ aPIOMD4 = 0x0003, /* PIO mode 4 */ /* ADMA_STATUS register bits */ @@ -452,24 +451,25 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) struct adma_port_priv *pp; struct ata_queued_cmd *qc; void __iomem *chan = ADMA_REGS(mmio_base, port_no); - u8 drv_stat, status = readb(chan + ADMA_STATUS); + u8 drv_stat = 0, status = readb(chan + ADMA_STATUS); if (status == 0) continue; handled = 1; adma_enter_reg_mode(ap); - if ((ap->flags & ATA_FLAG_PORT_DISABLED)) + if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) continue; pp = ap->private_data; if (!pp || pp->state != adma_state_pkt) continue; qc = ata_qc_from_tag(ap, ap->active_tag); - drv_stat = 0; - if ((status & (aPERR | aPSD | aUIRQ))) - drv_stat = ATA_ERR; - else if (pp->pkt[0] != cDONE) - drv_stat = ATA_ERR; - ata_qc_complete(qc, drv_stat); + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { + if ((status & (aPERR | aPSD | aUIRQ))) + drv_stat = ATA_ERR; + else if (pp->pkt[0] != cDONE) + drv_stat = ATA_ERR; + ata_qc_complete(qc, drv_stat); + } } return handled; } @@ -561,15 +561,15 @@ static int adma_port_start(struct ata_port *ap) if ((pp->pkt_dma & 7) != 0) { printk("bad alignment for pp->pkt_dma: %08x\n", (u32)pp->pkt_dma); - goto err_out_kfree2; + dma_free_coherent(dev, ADMA_PKT_BYTES, + pp->pkt, pp->pkt_dma); + goto err_out_kfree; } memset(pp->pkt, 0, ADMA_PKT_BYTES); ap->private_data = pp; adma_reinit_engine(ap); return 0; -err_out_kfree2: - kfree(pp); err_out_kfree: kfree(pp); err_out: From b04fc679055f76cfd17c6870716a8286ccfa3b8e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 15 Oct 2005 02:41:36 +0100 Subject: [PATCH 0659/1940] [SCSI] dec_esp: Fix mapping of ESP. From: Maciej W. Rozycki Date: Mon Jun 13 19:55:42 2005 +0000 These should really be addresses obtained with ioremap() or some bus-specific backend, but for now... Signed-off-by: Ralf Baechle Signed-off-by: James Bottomley --- drivers/scsi/dec_esp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c index 315f95a0d6c0..4f39890b44ac 100644 --- a/drivers/scsi/dec_esp.c +++ b/drivers/scsi/dec_esp.c @@ -228,7 +228,7 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt) mem_start = get_tc_base_addr(slot); /* Store base addr into esp struct */ - esp->slot = PHYSADDR(mem_start); + esp->slot = CPHYSADDR(mem_start); esp->dregs = 0; esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG); From 73711b352f1f1e1e9eedd772e232b7c1bd12a305 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 15 Oct 2005 02:26:31 +0100 Subject: [PATCH 0660/1940] [SCSI] dec_esp: Use physical addresses Use physical addresses at the interface level, letting drivers remap them as appropriate. Signed-off-by: Ralf Baechle Signed-off-by: James Bottomley --- drivers/scsi/dec_esp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c index 4f39890b44ac..90e2faf94a09 100644 --- a/drivers/scsi/dec_esp.c +++ b/drivers/scsi/dec_esp.c @@ -18,7 +18,7 @@ * 20001005 - Initialization fixes for 2.4.0-test9 * Florian Lohoff * - * Copyright (C) 2002, 2003 Maciej W. Rozycki + * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki */ #include @@ -41,6 +41,7 @@ #include #include #include +#include #include #define DEC_SCSI_SREG 0 @@ -183,7 +184,8 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt) esp->dregs = 0; /* ESP register base */ - esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI); + esp->eregs = (void *)CKSEG1ADDR(dec_kn_slot_base + + IOASIC_SCSI); /* Set the command buffer */ esp->esp_command = (volatile unsigned char *) cmd_buffer; @@ -228,10 +230,11 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt) mem_start = get_tc_base_addr(slot); /* Store base addr into esp struct */ - esp->slot = CPHYSADDR(mem_start); + esp->slot = mem_start; esp->dregs = 0; - esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG); + esp->eregs = (void *)CKSEG1ADDR(mem_start + + DEC_SCSI_SREG); esp->do_pio_cmds = 1; /* Set the command buffer */ From af13cbebb27aaa9cae0bd18cf2608a3d4dd5fa94 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 15 Oct 2005 02:44:26 +0100 Subject: [PATCH 0661/1940] [SCSI] dec_esp: Use the right address space macro Signed-off-by: James Bottomley --- drivers/scsi/dec_esp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c index 90e2faf94a09..2d7bde693d96 100644 --- a/drivers/scsi/dec_esp.c +++ b/drivers/scsi/dec_esp.c @@ -516,14 +516,15 @@ static void dma_advance_sg(struct scsi_cmnd * sp) static void pmaz_dma_drain(struct NCR_ESP *esp) { memcpy(phys_to_virt(esp_virt_buffer), - (void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), - scsi_current_length); + (void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM + + ESP_TGT_DMA_SIZE), + scsi_current_length); } static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) { volatile u32 *dmareg = - (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); + (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); if (length > ESP_TGT_DMA_SIZE) length = ESP_TGT_DMA_SIZE; @@ -539,9 +540,10 @@ static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) { volatile u32 *dmareg = - (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); + (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); - memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), + memcpy((void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM + + ESP_TGT_DMA_SIZE), phys_to_virt(vaddress), length); wmb(); From d25cf1ced9d446dcd3fd399e15b518fea936f3ed Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 20 Oct 2005 19:04:34 +0100 Subject: [PATCH 0662/1940] [SCSI] sgiwd93: small fixes Move the remaining bits of sgiwd93.h into sgiwd93.c; replace the use of CMD_PER_LUN and CAN_QUEUE by raw numbers. Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle Signed-off-by: James Bottomley --- drivers/scsi/sgiwd93.c | 5 ++--- drivers/scsi/sgiwd93.h | 24 ------------------------ 2 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 drivers/scsi/sgiwd93.h diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index a5ba2c692752..09fd203e4b86 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -33,7 +33,6 @@ #include "scsi.h" #include #include "wd33c93.h" -#include "sgiwd93.h" #include @@ -335,10 +334,10 @@ static Scsi_Host_Template driver_template = { .eh_abort_handler = wd33c93_abort, .eh_bus_reset_handler = sgiwd93_bus_reset, .eh_host_reset_handler = wd33c93_host_reset, - .can_queue = CAN_QUEUE, + .can_queue = 16, .this_id = 7, .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, + .cmd_per_lun = 8, .use_clustering = DISABLE_CLUSTERING, }; #include "scsi_module.c" diff --git a/drivers/scsi/sgiwd93.h b/drivers/scsi/sgiwd93.h deleted file mode 100644 index 981d0b7a85d4..000000000000 --- a/drivers/scsi/sgiwd93.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: sgiwd93.h,v 1.5 1998/08/25 09:18:50 ralf Exp $ - * sgiwd93.h: SGI WD93 scsi definitions. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#ifndef _SGIWD93_H -#define _SGIWD93_H - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 8 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - -int sgiwd93_detect(Scsi_Host_Template *); -int sgiwd93_release(struct Scsi_Host *instance); -const char *wd33c93_info(void); -int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int wd33c93_abort(Scsi_Cmnd *); -int wd33c93_host_reset(Scsi_Cmnd * SCpnt); - -#endif /* !(_SGIWD93_H) */ From c3ee74c4e91017169c7f1fa74a57ba8502ec49c3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Sep 2005 21:59:42 +0200 Subject: [PATCH 0663/1940] [SCSI] scsi_transport_sas: support link error attributes For now supporting the ->get_linkerrors method is mandatory. I'll probably be beaten to implement the .show_foo variables and different types of attributes soon.. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 31 ++++++++++++++++++++++++++++++- include/scsi/scsi_transport_sas.h | 23 +++++++++++++++++++---- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 1d145d2f9a38..63445f90097e 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -34,7 +34,7 @@ #define SAS_HOST_ATTRS 0 -#define SAS_PORT_ATTRS 11 +#define SAS_PORT_ATTRS 15 #define SAS_RPORT_ATTRS 5 struct sas_internal { @@ -257,6 +257,26 @@ show_sas_phy_##field(struct class_device *cdev, char *buf) \ sas_phy_show_linkspeed(field) \ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL) +#define sas_phy_show_linkerror(field) \ +static ssize_t \ +show_sas_phy_##field(struct class_device *cdev, char *buf) \ +{ \ + struct sas_phy *phy = transport_class_to_phy(cdev); \ + struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); \ + struct sas_internal *i = to_sas_internal(shost->transportt); \ + int error; \ + \ + error = i->f->get_linkerrors(phy); \ + if (error) \ + return error; \ + return snprintf(buf, 20, "%u\n", phy->field); \ +} + +#define sas_phy_linkerror_attr(field) \ + sas_phy_show_linkerror(field) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL) + + static ssize_t show_sas_device_type(struct class_device *cdev, char *buf) { @@ -282,6 +302,10 @@ sas_phy_linkspeed_attr(minimum_linkrate_hw); sas_phy_linkspeed_attr(minimum_linkrate); sas_phy_linkspeed_attr(maximum_linkrate_hw); sas_phy_linkspeed_attr(maximum_linkrate); +sas_phy_linkerror_attr(invalid_dword_count); +sas_phy_linkerror_attr(running_disparity_error_count); +sas_phy_linkerror_attr(loss_of_dword_sync_count); +sas_phy_linkerror_attr(phy_reset_problem_count); static DECLARE_TRANSPORT_CLASS(sas_phy_class, @@ -749,6 +773,11 @@ sas_attach_transport(struct sas_function_template *ft) SETUP_PORT_ATTRIBUTE(minimum_linkrate); SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw); SETUP_PORT_ATTRIBUTE(maximum_linkrate); + + SETUP_PORT_ATTRIBUTE(invalid_dword_count); + SETUP_PORT_ATTRIBUTE(running_disparity_error_count); + SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); + SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); i->phy_attrs[count] = NULL; count = 0; diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index bc4aeb660dd3..38389d8dd56e 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -41,20 +41,28 @@ struct sas_identify { u8 phy_identifier; }; -/* The functions by which the transport class and the driver communicate */ -struct sas_function_template { -}; - struct sas_phy { struct device dev; int number; + + /* phy identification */ struct sas_identify identify; + + /* phy attributes */ enum sas_linkrate negotiated_linkrate; enum sas_linkrate minimum_linkrate_hw; enum sas_linkrate minimum_linkrate; enum sas_linkrate maximum_linkrate_hw; enum sas_linkrate maximum_linkrate; u8 port_identifier; + + /* link error statistics */ + u32 invalid_dword_count; + u32 running_disparity_error_count; + u32 loss_of_dword_sync_count; + u32 phy_reset_problem_count; + + /* the other end of the link */ struct sas_rphy *rphy; }; @@ -79,6 +87,13 @@ struct sas_rphy { #define rphy_to_shost(rphy) \ dev_to_shost((rphy)->dev.parent) + +/* The functions by which the transport class and the driver communicate */ +struct sas_function_template { + int (*get_linkerrors)(struct sas_phy *); +}; + + extern void sas_remove_host(struct Scsi_Host *); extern struct sas_phy *sas_phy_alloc(struct device *, int); From 00ac37f508689da281586c7ef304f26b5138d8a6 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Fri, 28 Oct 2005 15:58:28 -0400 Subject: [PATCH 0664/1940] [libata scsi] MODE SELECT, strengthen mode sense - move default mode pages to the front of libata-scsi.c so various functions can access them - partial annotation of these pages, point out divergence from sat-r06 - replace various mode page magic numbers with defines - strengthen MODE SENSE command decoding: handle DBD bit in cdb, yield block descriptor (per sat-r06) and handle mode sub pages Signed-off-by: Douglas Gilbert Signed-off-by: Jeff Garzik --- drivers/scsi/libata-scsi.c | 144 ++++++++++++++++++++++++++----------- 1 file changed, 103 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index b761bd1b9717..89a04b1a5a0e 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -51,6 +51,45 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scs static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); +#define RW_RECOVERY_MPAGE 0x1 +#define RW_RECOVERY_MPAGE_LEN 12 +#define CACHE_MPAGE 0x8 +#define CACHE_MPAGE_LEN 20 +#define CONTROL_MPAGE 0xa +#define CONTROL_MPAGE_LEN 12 +#define ALL_MPAGES 0x3f +#define ALL_SUB_MPAGES 0xff + + +static const u8 def_rw_recovery_mpage[] = { + RW_RECOVERY_MPAGE, + RW_RECOVERY_MPAGE_LEN - 2, + (1 << 7) | /* AWRE, sat-r06 say it shall be 0 */ + (1 << 6), /* ARRE (auto read reallocation) */ + 0, /* read retry count */ + 0, 0, 0, 0, + 0, /* write retry count */ + 0, 0, 0 +}; + +static const u8 def_cache_mpage[CACHE_MPAGE_LEN] = { + CACHE_MPAGE, + CACHE_MPAGE_LEN - 2, + 0, /* contains WCE, needs to be 0 for logic */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* contains DRA, needs to be 0 for logic */ + 0, 0, 0, 0, 0, 0, 0 +}; + +static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { + CONTROL_MPAGE, + CONTROL_MPAGE_LEN - 2, + 2, /* DSENSE=0, GLTSD=1 */ + 0, /* [QAM+QERR may be 1, see 05-359r1] */ + 0, 0, 0, 0, 0xff, 0xff, + 0, 30 /* extended self test time, see 05-359r1 */ +}; + static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) @@ -1583,13 +1622,9 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last, static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io, const u8 *last) { - u8 page[] = { - 0x8, /* page code */ - 0x12, /* page length */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */ - 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */ - }; + u8 page[CACHE_MPAGE_LEN]; + memcpy(page, def_cache_mpage, sizeof(page)); if (ata_id_wcache_enabled(id)) page[2] |= (1 << 2); /* write cache enable */ if (!ata_id_rahead_enabled(id)) @@ -1613,15 +1648,9 @@ static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io, static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last) { - const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30}; - - /* byte 2: set the descriptor format sense data bit (bit 2) - * since we need to support returning this format for SAT - * commands and any SCSI commands against a 48b LBA device. - */ - - ata_msense_push(ptr_io, last, page, sizeof(page)); - return sizeof(page); + ata_msense_push(ptr_io, last, def_control_mpage, + sizeof(def_control_mpage)); + return sizeof(def_control_mpage); } /** @@ -1638,15 +1667,10 @@ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last) static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last) { - const u8 page[] = { - 0x1, /* page code */ - 0xa, /* page length */ - (1 << 7) | (1 << 6), /* note auto r/w reallocation */ - 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */ - }; - ata_msense_push(ptr_io, last, page, sizeof(page)); - return sizeof(page); + ata_msense_push(ptr_io, last, def_rw_recovery_mpage, + sizeof(def_rw_recovery_mpage)); + return sizeof(def_rw_recovery_mpage); } /** @@ -1655,7 +1679,9 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last) * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. * - * Simulate MODE SENSE commands. + * Simulate MODE SENSE commands. Assume this is invoked for direct + * access devices (e.g. disks) only. There should be no block + * descriptor for other device types. * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1665,15 +1691,22 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen) { u8 *scsicmd = args->cmd->cmnd, *p, *last; - unsigned int page_control, six_byte, output_len; + const u8 sat_blk_desc[] = { + 0, 0, 0, 0, /* number of blocks: sat unspecified */ + 0, + 0, 0x2, 0x0 /* block length: 512 bytes */ + }; + u8 pg, spg; + unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen; VPRINTK("ENTER\n"); six_byte = (scsicmd[0] == MODE_SENSE); - - /* we only support saved and current values (which we treat - * in the same manner) + ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */ + /* + * LLBA bit in msense(10) ignored (compliant) */ + page_control = scsicmd[2] >> 6; switch (page_control) { case 0: /* current */ @@ -1686,29 +1719,42 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, goto invalid_fld; } - if (six_byte) - output_len = 4; - else - output_len = 8; + if (six_byte) { + output_len = 4 + (ebd ? 8 : 0); + alloc_len = scsicmd[4]; + } else { + output_len = 8 + (ebd ? 8 : 0); + alloc_len = (scsicmd[7] << 8) + scsicmd[8]; + } + minlen = (alloc_len < buflen) ? alloc_len : buflen; p = rbuf + output_len; - last = rbuf + buflen - 1; + last = rbuf + minlen - 1; - switch(scsicmd[2] & 0x3f) { - case 0x01: /* r/w error recovery */ + pg = scsicmd[2] & 0x3f; + spg = scsicmd[3]; + /* + * No mode subpages supported (yet) but asking for _all_ + * subpages may be valid + */ + if (spg && (spg != ALL_SUB_MPAGES)) + goto invalid_fld; + + switch(pg) { + case RW_RECOVERY_MPAGE: output_len += ata_msense_rw_recovery(&p, last); break; - case 0x08: /* caching */ + case CACHE_MPAGE: output_len += ata_msense_caching(args->id, &p, last); break; - case 0x0a: { /* control mode */ + case CONTROL_MPAGE: { output_len += ata_msense_ctl_mode(&p, last); break; } - case 0x3f: /* all pages */ + case ALL_MPAGES: output_len += ata_msense_rw_recovery(&p, last); output_len += ata_msense_caching(args->id, &p, last); output_len += ata_msense_ctl_mode(&p, last); @@ -1718,15 +1764,31 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, goto invalid_fld; } + if (minlen < 1) + return 0; if (six_byte) { output_len--; rbuf[0] = output_len; + if (ebd) { + if (minlen > 3) + rbuf[3] = sizeof(sat_blk_desc); + if (minlen > 11) + memcpy(rbuf + 4, sat_blk_desc, + sizeof(sat_blk_desc)); + } } else { output_len -= 2; rbuf[0] = output_len >> 8; - rbuf[1] = output_len; + if (minlen > 1) + rbuf[1] = output_len; + if (ebd) { + if (minlen > 7) + rbuf[7] = sizeof(sat_blk_desc); + if (minlen > 15) + memcpy(rbuf + 8, sat_blk_desc, + sizeof(sat_blk_desc)); + } } - return 0; invalid_fld: @@ -2156,7 +2218,7 @@ ata_scsi_map_proto(u8 byte1) * Zero on success, non-zero on failure. */ static unsigned int -ata_scsi_pass_thru(struct ata_queued_cmd *qc, u8 *scsicmd) +ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) { struct ata_taskfile *tf = &(qc->tf); struct scsi_cmnd *cmd = qc->scsicmd; From a4e2b347848bf626b822599329933887dc90e50f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 26 Oct 2005 15:46:52 -0700 Subject: [PATCH 0665/1940] [PATCH] tg3: add 5714/5715 support Add complete support for 5714/5715. These chips are very similar to 5780 so the changes are very trivial. A TG3_FLG2_5780_CLASS flag is added to identify these chips. Signed-off-by: Michael Chan Signed-off-by: Jeff Garzik --- drivers/net/tg3.c | 39 +++++++++++++++++++++++++-------------- drivers/net/tg3.h | 11 +++++++++-- include/linux/pci_ids.h | 2 ++ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1802c3b48799..cf2204f5b7f9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -219,6 +219,10 @@ static struct pci_device_id tg3_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S, @@ -570,7 +574,7 @@ static void tg3_switch_clocks(struct tg3 *tp) u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL); u32 orig_clock_ctrl; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) return; orig_clock_ctrl = clock_ctrl; @@ -1210,7 +1214,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state) CLOCK_CTRL_ALTCLK | CLOCK_CTRL_PWRDOWN_PLL133); udelay(40); - } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { + } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { /* do nothing */ } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) { @@ -3712,14 +3716,14 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, dev->mtu = new_mtu; if (new_mtu > ETH_DATA_LEN) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; ethtool_op_set_tso(dev, 0); } else tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE; } else { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE; } @@ -3850,7 +3854,7 @@ static void tg3_init_rings(struct tg3 *tp) memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) && + if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) && (tp->dev->mtu > ETH_DATA_LEN)) tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ; @@ -4347,7 +4351,7 @@ static int tg3_chip_reset(struct tg3 *tp) val &= ~PCIX_CAPS_RELAXED_ORDERING; pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { u32 val; /* Chip reset on 5780 will reset MSI enable bit, @@ -6003,7 +6007,7 @@ static int tg3_reset_hw(struct tg3 *tp) tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK); if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && - (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)) + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) limit = 8; else limit = 16; @@ -7237,7 +7241,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->supported |= (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_10baseT_Half | @@ -8380,7 +8384,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp) } if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) { + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: tp->nvram_jedecnum = JEDEC_ATMEL; @@ -8980,7 +8984,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->phy_id = eeprom_phy_id; if (eeprom_phy_serdes) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; else tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; @@ -9393,8 +9397,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } /* Find msi capability. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { + tp->tg3_flags2 |= TG3_FLG2_5780_CLASS; tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); + } /* Initialize misc host control in PCI block. */ tp->misc_host_ctrl |= (misc_ctrl_reg & @@ -9412,7 +9419,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) || @@ -9607,7 +9614,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) * ether_setup() via the alloc_etherdev() call */ if (tp->dev->mtu > ETH_DATA_LEN && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780) + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE; /* Determine WakeOnLan speed to use. */ @@ -9830,7 +9837,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) mac_offset = 0x7c; if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && !(tp->tg3_flags & TG3_FLG2_SUN_570X)) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; if (tg3_nvram_lock(tp)) @@ -10148,6 +10155,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { /* 5780 always in PCIX mode */ tp->dma_rwctrl |= 0x00144000; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { + /* 5714 always in PCIX mode */ + tp->dma_rwctrl |= 0x00148000; } else { tp->dma_rwctrl |= 0x001b000f; } @@ -10347,6 +10357,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5705: return "5705"; case PHY_ID_BCM5750: return "5750"; case PHY_ID_BCM5752: return "5752"; + case PHY_ID_BCM5714: return "5714"; case PHY_ID_BCM5780: return "5780"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 2e733c60bfa4..456ef2b3d0ef 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -137,6 +137,7 @@ #define ASIC_REV_5750 0x04 #define ASIC_REV_5752 0x06 #define ASIC_REV_5780 0x08 +#define ASIC_REV_5714 0x09 #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -531,6 +532,8 @@ #define MAC_SERDES_CFG_EDGE_SELECT 0x00001000 #define MAC_SERDES_STAT 0x00000594 /* 0x598 --> 0x5b0 unused */ +#define SERDES_RX_CTRL 0x000005b0 /* 5780/5714 only */ +#define SERDES_RX_SIG_DETECT 0x00000400 #define SG_DIG_CTRL 0x000005b0 #define SG_DIG_USING_HW_AUTONEG 0x80000000 #define SG_DIG_SOFT_RESET 0x40000000 @@ -1329,6 +1332,8 @@ #define GRC_LCLCTRL_CLEARINT 0x00000002 #define GRC_LCLCTRL_SETINT 0x00000004 #define GRC_LCLCTRL_INT_ON_ATTN 0x00000008 +#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */ +#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */ #define GRC_LCLCTRL_GPIO_INPUT3 0x00000020 #define GRC_LCLCTRL_GPIO_OE3 0x00000040 #define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080 @@ -2175,6 +2180,7 @@ struct tg3 { TG3_FLG2_MII_SERDES) #define TG3_FLG2_PARALLEL_DETECT 0x01000000 #define TG3_FLG2_ICH_WORKAROUND 0x02000000 +#define TG3_FLG2_5780_CLASS 0x04000000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -2222,6 +2228,7 @@ struct tg3 { #define PHY_ID_BCM5705 0x600081a0 #define PHY_ID_BCM5750 0x60008180 #define PHY_ID_BCM5752 0x60008100 +#define PHY_ID_BCM5714 0x60008340 #define PHY_ID_BCM5780 0x60008350 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff @@ -2246,8 +2253,8 @@ struct tg3 { (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ - (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \ - (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ + (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 71834f05504f..d6865bbd9ea4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2165,11 +2165,13 @@ #define PCI_DEVICE_ID_TIGON3_5721 0x1659 #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_TIGON3_5714 0x1668 #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 +#define PCI_DEVICE_ID_TIGON3_5715 0x1678 #define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e From 28fbef78a420acdea20570d31f3bdcbfa0cac0d2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 26 Oct 2005 15:48:35 -0700 Subject: [PATCH 0666/1940] [PATCH] tg3: fix ASF heartbeat Change the ASF heart beat to 5 seconds for faster detection of system crash. The driver sends the heartbeat every 2 seconds and the ASF firmware will timeout and reset the device if no heartbeat is received after 5 seconds. The old scheme of 2 minutes is ineffective. tg3_write_mem_fast() is added to speed up the IO to send the heartbeat. When no workaround is needed, it will use direct MMIO to memory space to write to memory. Signed-off-by: Michael Chan Signed-off-by: Jeff Garzik --- drivers/net/tg3.c | 21 ++++++++++++++++----- drivers/net/tg3.h | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index cf2204f5b7f9..479be21425fb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -470,6 +470,15 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) spin_unlock_irqrestore(&tp->indirect_lock, flags); } +static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) +{ + /* If no workaround is needed, write to mem space directly */ + if (tp->write32 != tg3_write_indirect_reg32) + tw32(NIC_SRAM_WIN_BASE + off, val); + else + tg3_write_mem(tp, off, val); +} + static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) { unsigned long flags; @@ -6195,14 +6204,16 @@ static void tg3_timer(unsigned long __opaque) tp->timer_counter = tp->timer_multiplier; } - /* Heartbeat is only sent once every 120 seconds. */ + /* Heartbeat is only sent once every 2 seconds. */ if (!--tp->asf_counter) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; - tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE); - tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); - tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, + FWCMD_NICDRV_ALIVE2); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); + /* 5 seconds timeout */ + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); val = tr32(GRC_RX_CPU_EVENT); val |= (1 << 14); tw32(GRC_RX_CPU_EVENT, val); @@ -6413,7 +6424,7 @@ static int tg3_open(struct net_device *dev) tp->timer_counter = tp->timer_multiplier = (HZ / tp->timer_offset); tp->asf_counter = tp->asf_multiplier = - ((HZ / tp->timer_offset) * 120); + ((HZ / tp->timer_offset) * 2); init_timer(&tp->timer); tp->timer.expires = jiffies + tp->timer_offset; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 456ef2b3d0ef..fb7e2a5f4a08 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1512,6 +1512,7 @@ #define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004 #define FWCMD_NICDRV_FIX_DMAR 0x00000005 #define FWCMD_NICDRV_FIX_DMAW 0x00000006 +#define FWCMD_NICDRV_ALIVE2 0x0000000d #define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c #define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80 #define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00 From 37ff238d68683d42e7363eee3303773906c336d9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 26 Oct 2005 15:49:51 -0700 Subject: [PATCH 0667/1940] [PATCH] tg3: update version and minor fixes Update version and reldate and add more sanity checking to tg3_set_settings(). Signed-off-by: Gary Zambrano Signed-off-by: Michael Chan Signed-off-by: Jeff Garzik --- drivers/net/tg3.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 479be21425fb..551c9449322d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -67,8 +67,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.42" -#define DRV_MODULE_RELDATE "Oct 3, 2005" +#define DRV_MODULE_VERSION "3.43" +#define DRV_MODULE_RELDATE "Oct 24, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -7279,7 +7279,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct tg3 *tp = netdev_priv(dev); - if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { /* These are the only valid advertisement bits allowed. */ if (cmd->autoneg == AUTONEG_ENABLE && (cmd->advertising & ~(ADVERTISED_1000baseT_Half | @@ -7287,7 +7287,17 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ADVERTISED_Autoneg | ADVERTISED_FIBRE))) return -EINVAL; - } + /* Fiber can only do SPEED_1000. */ + else if ((cmd->autoneg != AUTONEG_ENABLE) && + (cmd->speed != SPEED_1000)) + return -EINVAL; + /* Copper cannot force SPEED_1000. */ + } else if ((cmd->autoneg != AUTONEG_ENABLE) && + (cmd->speed == SPEED_1000)) + return -EINVAL; + else if ((cmd->speed == SPEED_1000) && + (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) + return -EINVAL; tg3_full_lock(tp, 0); From 0abe791e94033b727f2b55670c2966f3d3d3cf70 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Wed, 26 Oct 2005 10:46:53 -0600 Subject: [PATCH 0668/1940] [PATCH] ibmveth fix bonding This patch updates dev->trans_start and dev->last_rx so that the ibmveth driver can be used with the ARP monitor in the bonding driver. Signed-off-by: Santiago Leon Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index a2c4dd4fb221..5617bec7fd53 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -725,6 +725,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) } else { adapter->stats.tx_packets++; adapter->stats.tx_bytes += skb->len; + netdev->trans_start = jiffies; } do { @@ -776,6 +777,7 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) adapter->stats.rx_packets++; adapter->stats.rx_bytes += length; frames_processed++; + netdev->last_rx = jiffies; } } else { more_work = 0; From b6d35182fe62e57d368062adcc880ca35119d88e Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Wed, 26 Oct 2005 10:47:01 -0600 Subject: [PATCH 0669/1940] [PATCH] ibmveth fix buffer pool management This patch changes the way the ibmveth driver handles the receive buffers. The old code mallocs and maps all the buffers in the pools regardless of MTU size and it also limits the number of buffer pools to three. This patch makes the driver malloc and map the buffers necessary to support the current MTU. It also changes the hardcoded names of the buffer pool number, size, and elements to arrays to make it easier to change (with the hope of making them runtime parameters in the future). Signed-off-by: Santiago Leon Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 102 ++++++++++++++++++++++++++++++------------ drivers/net/ibmveth.h | 18 +++++--- 2 files changed, 85 insertions(+), 35 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 5617bec7fd53..d985b804a762 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -97,6 +97,7 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*); +static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); #ifdef CONFIG_PROC_FS #define IBMVETH_PROC_DIR "net/ibmveth" @@ -181,6 +182,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) atomic_set(&pool->available, 0); pool->producer_index = 0; pool->consumer_index = 0; + pool->active = 0; return 0; } @@ -258,9 +260,14 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc /* check if replenishing is needed. */ static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter) { - return ((atomic_read(&adapter->rx_buff_pool[0].available) < adapter->rx_buff_pool[0].threshold) || - (atomic_read(&adapter->rx_buff_pool[1].available) < adapter->rx_buff_pool[1].threshold) || - (atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold)); + int i; + + for(i = 0; i < IbmVethNumBufferPools; i++) + if(adapter->rx_buff_pool[i].active && + (atomic_read(&adapter->rx_buff_pool[i].available) < + adapter->rx_buff_pool[i].threshold)) + return 1; + return 0; } /* kick the replenish tasklet if we need replenishing and it isn't already running */ @@ -275,11 +282,14 @@ static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter /* replenish tasklet routine */ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) { + int i; + adapter->replenish_task_cycles++; - ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[0]); - ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[1]); - ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[2]); + for(i = 0; i < IbmVethNumBufferPools; i++) + if(adapter->rx_buff_pool[i].active) + ibmveth_replenish_buffer_pool(adapter, + &adapter->rx_buff_pool[i]); adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); @@ -321,6 +331,7 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm kfree(pool->skbuff); pool->skbuff = NULL; } + pool->active = 0; } /* remove a buffer from a pool */ @@ -379,6 +390,12 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) ibmveth_assert(pool < IbmVethNumBufferPools); ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + if(!adapter->rx_buff_pool[pool].active) { + ibmveth_rxq_harvest_buffer(adapter); + ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); + return; + } + desc.desc = 0; desc.fields.valid = 1; desc.fields.length = adapter->rx_buff_pool[pool].buff_size; @@ -409,6 +426,8 @@ static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { + int i; + if(adapter->buffer_list_addr != NULL) { if(!dma_mapping_error(adapter->buffer_list_dma)) { dma_unmap_single(&adapter->vdev->dev, @@ -443,26 +462,24 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->rx_queue.queue_addr = NULL; } - ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[0]); - ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[1]); - ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]); + for(i = 0; irx_buff_pool[i]); } static int ibmveth_open(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev->priv; u64 mac_address = 0; - int rxq_entries; + int rxq_entries = 1; unsigned long lpar_rc; int rc; union ibmveth_buf_desc rxq_desc; + int i; ibmveth_debug_printk("open starting\n"); - rxq_entries = - adapter->rx_buff_pool[0].size + - adapter->rx_buff_pool[1].size + - adapter->rx_buff_pool[2].size + 1; + for(i = 0; irx_buff_pool[i].size; adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL); adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL); @@ -502,14 +519,8 @@ static int ibmveth_open(struct net_device *netdev) adapter->rx_queue.num_slots = rxq_entries; adapter->rx_queue.toggle = 1; - if(ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0]) || - ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[1]) || - ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[2])) - { - ibmveth_error_printk("unable to allocate buffer pools\n"); - ibmveth_cleanup(adapter); - return -ENOMEM; - } + /* call change_mtu to init the buffer pools based in initial mtu */ + ibmveth_change_mtu(netdev, netdev->mtu); memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); mac_address = mac_address >> 16; @@ -885,17 +896,52 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) { - if ((new_mtu < 68) || (new_mtu > (1<<20))) + struct ibmveth_adapter *adapter = dev->priv; + int i; + int prev_smaller = 1; + + if ((new_mtu < 68) || + (new_mtu > (pool_size[IbmVethNumBufferPools-1]) - IBMVETH_BUFF_OH)) return -EINVAL; + + for(i = 0; i (pool_size[i] - IBMVETH_BUFF_OH)) { + activate = 1; + prev_smaller= 1; + } else { + if (prev_smaller) + activate = 1; + prev_smaller= 0; + } + + if (activate && !adapter->rx_buff_pool[i].active) { + struct ibmveth_buff_pool *pool = + &adapter->rx_buff_pool[i]; + if(ibmveth_alloc_buffer_pool(pool)) { + ibmveth_error_printk("unable to alloc pool\n"); + return -ENOMEM; + } + adapter->rx_buff_pool[i].active = 1; + } else if (!activate && adapter->rx_buff_pool[i].active) { + adapter->rx_buff_pool[i].active = 0; + h_free_logical_lan_buffer(adapter->vdev->unit_address, + (u64)pool_size[i]); + } + + } + + + ibmveth_schedule_replenishing(adapter); dev->mtu = new_mtu; return 0; } static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { - int rc; + int rc, i; struct net_device *netdev; - struct ibmveth_adapter *adapter; + struct ibmveth_adapter *adapter = NULL; unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; @@ -965,9 +1011,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); - ibmveth_init_buffer_pool(&adapter->rx_buff_pool[0], 0, IbmVethPool0DftCnt, IbmVethPool0DftSize); - ibmveth_init_buffer_pool(&adapter->rx_buff_pool[1], 1, IbmVethPool1DftCnt, IbmVethPool1DftSize); - ibmveth_init_buffer_pool(&adapter->rx_buff_pool[2], 2, IbmVethPool2DftCnt, IbmVethPool2DftSize); + for(i = 0; irx_buff_pool[i], i, + pool_count[i], pool_size[i]); ibmveth_debug_printk("adapter @ 0x%p\n", adapter); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index 51a470da9686..a5d27a9cdf1f 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -49,6 +49,7 @@ #define H_SEND_LOGICAL_LAN 0x120 #define H_MULTICAST_CTRL 0x130 #define H_CHANGE_LOGICAL_LAN_MAC 0x14C +#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 /* hcall macros */ #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ @@ -69,13 +70,15 @@ #define h_change_logical_lan_mac(ua, mac) \ plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) -#define IbmVethNumBufferPools 3 -#define IbmVethPool0DftSize (1024 * 2) -#define IbmVethPool1DftSize (1024 * 4) -#define IbmVethPool2DftSize (1024 * 10) -#define IbmVethPool0DftCnt 256 -#define IbmVethPool1DftCnt 256 -#define IbmVethPool2DftCnt 256 +#define h_free_logical_lan_buffer(ua, bufsize) \ + plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize) + +#define IbmVethNumBufferPools 5 +#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ + +/* pool_size should be sorted */ +static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 }; +static int pool_count[] = { 256, 768, 256, 256, 256 }; #define IBM_VETH_INVALID_MAP ((u16)0xffff) @@ -90,6 +93,7 @@ struct ibmveth_buff_pool { u16 *free_map; dma_addr_t *dma_addr; struct sk_buff **skbuff; + int active; }; struct ibmveth_rx_q { From e2adbcb480992de8a01acf9218e8bbd9b507fc6f Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Wed, 26 Oct 2005 10:47:08 -0600 Subject: [PATCH 0670/1940] [PATCH] ibmveth fix buffer replenishing This patch removes the allocation of RX skb's buffers from a workqueue to be called directly at RX processing time. This change was suggested by Dave Miller when the driver was starving the RX buffers and deadlocking under heavy traffic: > Allocating RX SKBs via tasklet is, IMHO, the worst way to > do it. It is no surprise that there are starvation cases. > > If tasklets or work queues get delayed in any way, you lose, > and it's very easy for a card to catch up with the driver RX'ing > packets very fast, no matter how aggressive you make the > replenishing. By the time you detect that you need to be > "more aggressive" it is already too late. > The only pseudo-reliable way is to allocate at RX processing time. > Signed-off-by: Santiago Leon Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 48 ++++++++----------------------------------- drivers/net/ibmveth.h | 4 ---- 2 files changed, 8 insertions(+), 44 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index d985b804a762..aea1598b2253 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -96,7 +96,6 @@ static void ibmveth_proc_unregister_driver(void); static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*); static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); #ifdef CONFIG_PROC_FS @@ -257,29 +256,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc atomic_add(buffers_added, &(pool->available)); } -/* check if replenishing is needed. */ -static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter) -{ - int i; - - for(i = 0; i < IbmVethNumBufferPools; i++) - if(adapter->rx_buff_pool[i].active && - (atomic_read(&adapter->rx_buff_pool[i].available) < - adapter->rx_buff_pool[i].threshold)) - return 1; - return 0; -} - -/* kick the replenish tasklet if we need replenishing and it isn't already running */ -static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter) -{ - if(ibmveth_is_replenishing_needed(adapter) && - (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) { - schedule_work(&adapter->replenish_task); - } -} - -/* replenish tasklet routine */ +/* replenish routine */ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) { int i; @@ -292,10 +269,6 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) &adapter->rx_buff_pool[i]); adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); - - atomic_inc(&adapter->not_replenishing); - - ibmveth_schedule_replenishing(adapter); } /* empty and free ana buffer pool - also used to do cleanup in error paths */ @@ -563,10 +536,10 @@ static int ibmveth_open(struct net_device *netdev) return rc; } - netif_start_queue(netdev); + ibmveth_debug_printk("initial replenish cycle\n"); + ibmveth_replenish_task(adapter); - ibmveth_debug_printk("scheduling initial replenish cycle\n"); - ibmveth_schedule_replenishing(adapter); + netif_start_queue(netdev); ibmveth_debug_printk("open complete\n"); @@ -584,9 +557,6 @@ static int ibmveth_close(struct net_device *netdev) free_irq(netdev->irq, netdev); - cancel_delayed_work(&adapter->replenish_task); - flush_scheduled_work(); - do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy)); @@ -795,7 +765,7 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) } } while(more_work && (frames_processed < max_frames_to_process)); - ibmveth_schedule_replenishing(adapter); + ibmveth_replenish_task(adapter); if(more_work) { /* more work to do - return that we are not done yet */ @@ -931,8 +901,10 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) } + /* kick the interrupt handler so that the new buffer pools get + replenished or deallocated */ + ibmveth_interrupt(dev->irq, dev, NULL); - ibmveth_schedule_replenishing(adapter); dev->mtu = new_mtu; return 0; } @@ -1017,14 +989,10 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ ibmveth_debug_printk("adapter @ 0x%p\n", adapter); - INIT_WORK(&adapter->replenish_task, (void*)ibmveth_replenish_task, (void*)adapter); - adapter->buffer_list_dma = DMA_ERROR_CODE; adapter->filter_list_dma = DMA_ERROR_CODE; adapter->rx_queue.queue_dma = DMA_ERROR_CODE; - atomic_set(&adapter->not_replenishing, 1); - ibmveth_debug_printk("registering netdev...\n"); rc = register_netdev(netdev); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index a5d27a9cdf1f..a3ea02937d63 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -118,10 +118,6 @@ struct ibmveth_adapter { dma_addr_t filter_list_dma; struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools]; struct ibmveth_rx_q rx_queue; - atomic_t not_replenishing; - - /* helper tasks */ - struct work_struct replenish_task; /* adapter specific stats */ u64 replenish_task_cycles; From 60296d9e4be1cd9e096f7804ce6e839e0cbd97cf Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Wed, 26 Oct 2005 10:47:16 -0600 Subject: [PATCH 0671/1940] [PATCH] ibmveth lockless TX This patch adds the lockless TX feature to the ibmveth driver. The hypervisor has its own locking so the only change that is necessary is to protect the statistics counters. Signed-off-by: Santiago Leon Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 44 ++++++++++++++++++++++++++++--------------- drivers/net/ibmveth.h | 1 + 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index aea1598b2253..987bcba01889 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -621,12 +621,18 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) unsigned long lpar_rc; int nfrags = 0, curfrag; unsigned long correlator; + unsigned long flags; unsigned int retry_count; + unsigned int tx_dropped = 0; + unsigned int tx_bytes = 0; + unsigned int tx_packets = 0; + unsigned int tx_send_failed = 0; + unsigned int tx_map_failed = 0; + if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) { - adapter->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; + tx_dropped++; + goto out; } memset(&desc, 0, sizeof(desc)); @@ -645,10 +651,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) if(dma_mapping_error(desc[0].fields.address)) { ibmveth_error_printk("tx: unable to map initial fragment\n"); - adapter->tx_map_failed++; - adapter->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; + tx_map_failed++; + tx_dropped++; + goto out; } curfrag = nfrags; @@ -665,8 +670,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) if(dma_mapping_error(desc[curfrag+1].fields.address)) { ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag); - adapter->tx_map_failed++; - adapter->stats.tx_dropped++; + tx_map_failed++; + tx_dropped++; /* Free all the mappings we just created */ while(curfrag < nfrags) { dma_unmap_single(&adapter->vdev->dev, @@ -675,8 +680,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) DMA_TO_DEVICE); curfrag++; } - dev_kfree_skb(skb); - return 0; + goto out; } } @@ -701,11 +705,11 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i, desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address); } - adapter->tx_send_failed++; - adapter->stats.tx_dropped++; + tx_send_failed++; + tx_dropped++; } else { - adapter->stats.tx_packets++; - adapter->stats.tx_bytes += skb->len; + tx_packets++; + tx_bytes += skb->len; netdev->trans_start = jiffies; } @@ -715,6 +719,14 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) desc[nfrags].fields.length, DMA_TO_DEVICE); } while(--nfrags >= 0); +out: spin_lock_irqsave(&adapter->stats_lock, flags); + adapter->stats.tx_dropped += tx_dropped; + adapter->stats.tx_bytes += tx_bytes; + adapter->stats.tx_packets += tx_packets; + adapter->tx_send_failed += tx_send_failed; + adapter->tx_map_failed += tx_map_failed; + spin_unlock_irqrestore(&adapter->stats_lock, flags); + dev_kfree_skb(skb); return 0; } @@ -980,6 +992,8 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->ethtool_ops = &netdev_ethtool_ops; netdev->change_mtu = ibmveth_change_mtu; SET_NETDEV_DEV(netdev, &dev->dev); + netdev->features |= NETIF_F_LLTX; + spin_lock_init(&adapter->stats_lock); memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index a3ea02937d63..46919a814fca 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -131,6 +131,7 @@ struct ibmveth_adapter { u64 tx_linearize_failed; u64 tx_map_failed; u64 tx_send_failed; + spinlock_t stats_lock; }; struct ibmveth_buf_desc_fields { From 82702d37a559cf94fe238cd3f8ef63cf7fa699a9 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Wed, 26 Oct 2005 10:47:23 -0600 Subject: [PATCH 0672/1940] [PATCH] ibmveth fix failed addbuf This patch fixes a bug that happens when the hypervisor can't add a buffer. The old code wrote IBM_VETH_INVALID_MAP into the free_map array, so next time the index was used, a ibmveth_assert() caught it and called BUG(). The patch writes the right value into the free_map array so that the index can be reused. Signed-off-by: Santiago Leon Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 987bcba01889..f5819527ec9d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -237,7 +237,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); if(lpar_rc != H_Success) { - pool->free_map[free_index] = IBM_VETH_INVALID_MAP; + pool->free_map[free_index] = index; pool->skbuff[index] = NULL; pool->consumer_index--; dma_unmap_single(&adapter->vdev->dev, From d89a64bedf956ef0b406018a7cb76e027fe3e751 Mon Sep 17 00:00:00 2001 From: Komuro Date: Fri, 28 Oct 2005 16:09:54 -0400 Subject: [PATCH 0673/1940] pcnet_cs: fix mii init code for older DL10019 based cards Some older DL10019 based cards need to setup the auto-negotiation-advertisement register to advertise 100Full,100Half,10Full and 10Half. Signed-off-by: Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/pcnet_cs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 9f22d138e3ad..818c185d6438 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1020,6 +1020,12 @@ static void set_misc_reg(struct net_device *dev) } else { outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG); } + } else if (info->flags & IS_DL10019) { + /* Advertise 100F, 100H, 10F, 10H */ + mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); + /* Restart MII autonegotiation */ + mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); + mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); } } From 008d55903a1e9e179ff1d366dfcfa9b72abd116d Mon Sep 17 00:00:00 2001 From: Roger While Date: Fri, 28 Oct 2005 16:11:49 -0400 Subject: [PATCH 0674/1940] [wireless prism54] Fix frame length prism54 is leaking information when passing transmits to the firmware. There is no requirement to adjust the length to >= ETH_ZLEN. Just pass the skb length (after possible adjustment). Signed-off-by: Roger While Signed-off-by: Jeff Garzik --- drivers/net/wireless/prism54/islpci_eth.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 5952e9960499..0975dd4ed77d 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -97,12 +97,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) /* lock the driver code */ spin_lock_irqsave(&priv->slock, flags); - /* determine the amount of fragments needed to store the frame */ - - frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; - if (init_wds) - frame_size += 6; - /* check whether the destination queue has enough fragments for the frame */ curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]); if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) { @@ -213,6 +207,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) /* store the skb address for future freeing */ priv->data_low_tx[index] = skb; /* set the proper fragment start address and size information */ + frame_size = skb->len; fragment->size = cpu_to_le16(frame_size); fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */ fragment->address = cpu_to_le32(pci_map_address); From 9eb343aeb3e106c1e4c07e2863f45b2c121b3b78 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 21 Oct 2005 19:06:42 +0900 Subject: [PATCH 0675/1940] [PATCH] s2io: kconfig help fix The documentation about s2io is available at Documentation/networking/s2io.txt. Signed-off-by: Akinobu Mita Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5148d47492a0..8fa0e26fa805 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2201,8 +2201,8 @@ config S2IO depends on PCI ---help--- This driver supports the 10Gbe XFrame NIC of S2IO. - For help regarding driver compilation, installation and - tuning please look into ~/drivers/net/s2io/README.txt. + More specific information on configuring the driver is in + . config S2IO_NAPI bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" From adf6e00064ebcd3d82009ba6ef66f489f0885ebd Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 4 Oct 2005 11:25:17 -0600 Subject: [PATCH 0676/1940] [PATCH] b44 reports wrong advertised flags Looks like someone used the MII constants instead of the ethtool constants. Signed-off-by: Matthew Wilcox Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 282ebd15f011..225d14fd9239 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -1619,14 +1619,14 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->advertising = 0; if (bp->flags & B44_FLAG_ADV_10HALF) - cmd->advertising |= ADVERTISE_10HALF; + cmd->advertising |= ADVERTISED_10baseT_Half; if (bp->flags & B44_FLAG_ADV_10FULL) - cmd->advertising |= ADVERTISE_10FULL; + cmd->advertising |= ADVERTISED_10baseT_Full; if (bp->flags & B44_FLAG_ADV_100HALF) - cmd->advertising |= ADVERTISE_100HALF; + cmd->advertising |= ADVERTISED_100baseT_Half; if (bp->flags & B44_FLAG_ADV_100FULL) - cmd->advertising |= ADVERTISE_100FULL; - cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + cmd->advertising |= ADVERTISED_100baseT_Full; + cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause; cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ? SPEED_100 : SPEED_10; cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ? From 8fee5f51a56aa7a67d955993572a2ae05d31a2c6 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Wed, 5 Oct 2005 23:29:58 +0200 Subject: [PATCH 0677/1940] [PATCH] sis190.c: fix multicast MAC filter Here is a patch that changes the way the MAC filter is computed for the multicast addresses. The computation is taken from the SiS GPL driver. This patch is necessary to get IPv6 working. Signed-off-by: Aurelien Jarno Signed-off-by: Jeff Garzik --- drivers/net/sis190.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 92f75529eff8..478791e09bf7 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -842,7 +842,7 @@ static void sis190_set_rx_mode(struct net_device *dev) for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { int bit_nr = - ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f; mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); rx_mode |= AcceptMulticast; } From 99e1baf869cf20791e66e38facd51d14b28551f8 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 5 Oct 2005 11:10:24 -0400 Subject: [PATCH 0678/1940] [PATCH] smc91x: shut down power after probing If the interface is not used right away after being probed it wastes power needlessly. Noted by Holger Schurig. Signed-off-by: Nicolas Pitre Signed-off-by: Jeff Garzik --- drivers/net/smc91x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 1438fdd20826..c5bc8ae84dd3 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1983,6 +1983,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) if (lp->version >= (CHIP_91100 << 4)) smc_phy_detect(dev); + /* then shut everything down to save power */ + smc_shutdown(dev); + smc_phy_powerdown(dev); + /* Set default parameters */ lp->msg_enable = NETIF_MSG_LINK; lp->ctl_rfduplx = 0; From 712cb1ebb1653538527500165d8382ca48a7fca1 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Sun, 23 Oct 2005 13:41:35 -0700 Subject: [PATCH 0679/1940] [PATCH] Fix CS89x0 KConfig for IXDP2X01 IXDP2x01 systems can be built without PCI network cards, so we should not require NET_PCI to build CS89x0 on these systems. Signed-off-by: Deepak Saxena Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8fa0e26fa805..814a93b8c903 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1338,7 +1338,7 @@ config FORCEDETH config CS89x0 tristate "CS89x0 support" - depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 + depends on (NET_PCI && ISA) || ARCH_PNX0105 || ARCH_IXDP2X01 ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the From d8840ac907c7943bc7e196b11812adfa95cb28ef Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 7 Oct 2005 02:05:23 +0400 Subject: [PATCH 0680/1940] [PATCH] starfire: free_irq() on error path of netdev_open() Signed-off-by: Alexey Dobriyan Signed-off-by: Jeff Garzik --- drivers/net/starfire.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index efdb179ecc8c..38b2b0a3ce96 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1091,8 +1091,10 @@ static int netdev_open(struct net_device *dev) rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE; np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size; np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma); - if (np->queue_mem == 0) + if (np->queue_mem == NULL) { + free_irq(dev->irq, dev); return -ENOMEM; + } np->tx_done_q = np->queue_mem; np->tx_done_q_dma = np->queue_mem_dma; From 48257c4f168e5d040394aeca4d37b59f68e0d36b Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 28 Oct 2005 16:25:58 -0400 Subject: [PATCH 0681/1940] Add fs_enet ethernet network driver, for several embedded platforms. --- drivers/net/Kconfig | 1 + drivers/net/Makefile | 3 + drivers/net/fs_enet/Kconfig | 20 + drivers/net/fs_enet/Makefile | 10 + drivers/net/fs_enet/fs_enet-main.c | 1226 ++++++++++++++++++++++++++++ drivers/net/fs_enet/fs_enet-mii.c | 507 ++++++++++++ drivers/net/fs_enet/fs_enet.h | 245 ++++++ drivers/net/fs_enet/mac-fcc.c | 578 +++++++++++++ drivers/net/fs_enet/mac-fec.c | 653 +++++++++++++++ drivers/net/fs_enet/mac-scc.c | 524 ++++++++++++ drivers/net/fs_enet/mii-bitbang.c | 405 +++++++++ drivers/net/fs_enet/mii-fixed.c | 92 +++ include/linux/fs_enet_pd.h | 136 +++ 13 files changed, 4400 insertions(+) create mode 100644 drivers/net/fs_enet/Kconfig create mode 100644 drivers/net/fs_enet/Makefile create mode 100644 drivers/net/fs_enet/fs_enet-main.c create mode 100644 drivers/net/fs_enet/fs_enet-mii.c create mode 100644 drivers/net/fs_enet/fs_enet.h create mode 100644 drivers/net/fs_enet/mac-fcc.c create mode 100644 drivers/net/fs_enet/mac-fec.c create mode 100644 drivers/net/fs_enet/mac-scc.c create mode 100644 drivers/net/fs_enet/mii-bitbang.c create mode 100644 drivers/net/fs_enet/mii-fixed.c create mode 100644 include/linux/fs_enet_pd.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 814a93b8c903..27732fdeeea4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1775,6 +1775,7 @@ config NE_H8300 controller on the Renesas H8/300 processor. source "drivers/net/fec_8xx/Kconfig" +source "drivers/net/fs_enet/Kconfig" endmenu diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1a84e0435f64..7c313cb341b8 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -203,3 +203,6 @@ obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_NETCONSOLE) += netconsole.o + +obj-$(CONFIG_FS_ENET) += fs_enet/ + diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig new file mode 100644 index 000000000000..6aaee67dd4b7 --- /dev/null +++ b/drivers/net/fs_enet/Kconfig @@ -0,0 +1,20 @@ +config FS_ENET + tristate "Freescale Ethernet Driver" + depends on NET_ETHERNET && (CPM1 || CPM2) + select MII + +config FS_ENET_HAS_SCC + bool "Chip has an SCC usable for ethernet" + depends on FS_ENET && (CPM1 || CPM2) + default y + +config FS_ENET_HAS_FCC + bool "Chip has an FCC usable for ethernet" + depends on FS_ENET && CPM2 + default y + +config FS_ENET_HAS_FEC + bool "Chip has an FEC usable for ethernet" + depends on FS_ENET && CPM1 + default y + diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile new file mode 100644 index 000000000000..d6dd3f2fb43e --- /dev/null +++ b/drivers/net/fs_enet/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the Freescale Ethernet controllers +# + +obj-$(CONFIG_FS_ENET) += fs_enet.o + +obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o +obj-$(CONFIG_8260) += mac-fcc.o + +fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c new file mode 100644 index 000000000000..44fac7373289 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -0,0 +1,1226 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * Heavily based on original FEC driver by Dan Malek + * and modifications by Joakim Tjernlund + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; + +MODULE_AUTHOR("Pantelis Antoniou "); +MODULE_DESCRIPTION("Freescale Ethernet Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +MODULE_PARM(fs_enet_debug, "i"); +MODULE_PARM_DESC(fs_enet_debug, + "Freescale bitmapped debugging message enable value"); + +int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */ + +static void fs_set_multicast_list(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + (*fep->ops->set_multicast_list)(dev); +} + +/* NAPI receive function */ +static int fs_enet_rx_napi(struct net_device *dev, int *budget) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + cbd_t *bdp; + struct sk_buff *skb, *skbn, *skbt; + int received = 0; + u16 pkt_len, sc; + int curidx; + int rx_work_limit = 0; /* pacify gcc */ + + rx_work_limit = min(dev->quota, *budget); + + if (!netif_running(dev)) + return 0; + + /* + * First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. + */ + bdp = fep->cur_rx; + + /* clear RX status bits for napi*/ + (*fep->ops->napi_clear_rx_event)(dev); + + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { + + curidx = bdp - fep->rx_bd_base; + + /* + * Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ + if ((sc & BD_ENET_RX_LAST) == 0) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s rcv is not +last\n", + dev->name); + + /* + * Check for errors. + */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { + fep->stats.rx_errors++; + /* Frame too long or too short. */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) + fep->stats.rx_length_errors++; + /* Frame alignment */ + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) + fep->stats.rx_frame_errors++; + /* CRC Error */ + if (sc & BD_ENET_RX_CR) + fep->stats.rx_crc_errors++; + /* FIFO overrun */ + if (sc & BD_ENET_RX_OV) + fep->stats.rx_crc_errors++; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + skbn = skb; + + } else { + + /* napi, got packet but no quota */ + if (--rx_work_limit < 0) + break; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + /* + * Process the incoming frame. + */ + fep->stats.rx_packets++; + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ + fep->stats.rx_bytes += pkt_len + 4; + + if (pkt_len <= fpi->rx_copybreak) { + /* +2 to make IP header L1 cache aligned */ + skbn = dev_alloc_skb(pkt_len + 2); + if (skbn != NULL) { + skb_reserve(skbn, 2); /* align IP header */ + memcpy(skbn->data, skb->data, pkt_len); + /* swap */ + skbt = skb; + skb = skbn; + skbn = skbt; + } + } else + skbn = dev_alloc_skb(ENET_RX_FRSIZE); + + if (skbn != NULL) { + skb->dev = dev; + skb_put(skb, pkt_len); /* Make room */ + skb->protocol = eth_type_trans(skb, dev); + received++; + netif_receive_skb(skb); + } else { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, dropping packet.\n", + dev->name); + fep->stats.rx_dropped++; + skbn = skb; + } + } + + fep->rx_skbuff[curidx] = skbn; + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); + + /* + * Update BD pointer to next entry. + */ + if ((sc & BD_ENET_RX_WRAP) == 0) + bdp++; + else + bdp = fep->rx_bd_base; + + (*fep->ops->rx_bd_done)(dev); + } + + fep->cur_rx = bdp; + + dev->quota -= received; + *budget -= received; + + if (rx_work_limit < 0) + return 1; /* not done */ + + /* done */ + netif_rx_complete(dev); + + (*fep->ops->napi_enable_rx)(dev); + + return 0; +} + +/* non NAPI receive function */ +static int fs_enet_rx_non_napi(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + cbd_t *bdp; + struct sk_buff *skb, *skbn, *skbt; + int received = 0; + u16 pkt_len, sc; + int curidx; + /* + * First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. + */ + bdp = fep->cur_rx; + + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { + + curidx = bdp - fep->rx_bd_base; + + /* + * Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ + if ((sc & BD_ENET_RX_LAST) == 0) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s rcv is not +last\n", + dev->name); + + /* + * Check for errors. + */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { + fep->stats.rx_errors++; + /* Frame too long or too short. */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) + fep->stats.rx_length_errors++; + /* Frame alignment */ + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) + fep->stats.rx_frame_errors++; + /* CRC Error */ + if (sc & BD_ENET_RX_CR) + fep->stats.rx_crc_errors++; + /* FIFO overrun */ + if (sc & BD_ENET_RX_OV) + fep->stats.rx_crc_errors++; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + skbn = skb; + + } else { + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + /* + * Process the incoming frame. + */ + fep->stats.rx_packets++; + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ + fep->stats.rx_bytes += pkt_len + 4; + + if (pkt_len <= fpi->rx_copybreak) { + /* +2 to make IP header L1 cache aligned */ + skbn = dev_alloc_skb(pkt_len + 2); + if (skbn != NULL) { + skb_reserve(skbn, 2); /* align IP header */ + memcpy(skbn->data, skb->data, pkt_len); + /* swap */ + skbt = skb; + skb = skbn; + skbn = skbt; + } + } else + skbn = dev_alloc_skb(ENET_RX_FRSIZE); + + if (skbn != NULL) { + skb->dev = dev; + skb_put(skb, pkt_len); /* Make room */ + skb->protocol = eth_type_trans(skb, dev); + received++; + netif_rx(skb); + } else { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, dropping packet.\n", + dev->name); + fep->stats.rx_dropped++; + skbn = skb; + } + } + + fep->rx_skbuff[curidx] = skbn; + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); + + /* + * Update BD pointer to next entry. + */ + if ((sc & BD_ENET_RX_WRAP) == 0) + bdp++; + else + bdp = fep->rx_bd_base; + + (*fep->ops->rx_bd_done)(dev); + } + + fep->cur_rx = bdp; + + return 0; +} + +static void fs_enet_tx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + struct sk_buff *skb; + int dirtyidx, do_wake, do_restart; + u16 sc; + + spin_lock(&fep->lock); + bdp = fep->dirty_tx; + + do_wake = do_restart = 0; + while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { + + dirtyidx = bdp - fep->tx_bd_base; + + if (fep->tx_free == fep->tx_ring) + break; + + skb = fep->tx_skbuff[dirtyidx]; + + /* + * Check for errors. + */ + if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | + BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { + + if (sc & BD_ENET_TX_HB) /* No heartbeat */ + fep->stats.tx_heartbeat_errors++; + if (sc & BD_ENET_TX_LC) /* Late collision */ + fep->stats.tx_window_errors++; + if (sc & BD_ENET_TX_RL) /* Retrans limit */ + fep->stats.tx_aborted_errors++; + if (sc & BD_ENET_TX_UN) /* Underrun */ + fep->stats.tx_fifo_errors++; + if (sc & BD_ENET_TX_CSL) /* Carrier lost */ + fep->stats.tx_carrier_errors++; + + if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { + fep->stats.tx_errors++; + do_restart = 1; + } + } else + fep->stats.tx_packets++; + + if (sc & BD_ENET_TX_READY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s HEY! Enet xmit interrupt and TX_READY.\n", + dev->name); + + /* + * Deferred means some collisions occurred during transmit, + * but we eventually sent the packet OK. + */ + if (sc & BD_ENET_TX_DEF) + fep->stats.collisions++; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); + + /* + * Free the sk buffer associated with this last transmit. + */ + dev_kfree_skb_irq(skb); + fep->tx_skbuff[dirtyidx] = NULL; + + /* + * Update pointer to next buffer descriptor to be transmitted. + */ + if ((sc & BD_ENET_TX_WRAP) == 0) + bdp++; + else + bdp = fep->tx_bd_base; + + /* + * Since we have freed up a buffer, the ring is no longer + * full. + */ + if (!fep->tx_free++) + do_wake = 1; + } + + fep->dirty_tx = bdp; + + if (do_restart) + (*fep->ops->tx_restart)(dev); + + spin_unlock(&fep->lock); + + if (do_wake) + netif_wake_queue(dev); +} + +/* + * The interrupt handler. + * This is called from the MPC core interrupt. + */ +static irqreturn_t +fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + u32 int_events; + u32 int_clr_events; + int nr, napi_ok; + int handled; + + fep = netdev_priv(dev); + fpi = fep->fpi; + + nr = 0; + while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) { + + nr++; + + int_clr_events = int_events; + if (fpi->use_napi) + int_clr_events &= ~fep->ev_napi_rx; + + (*fep->ops->clear_int_events)(dev, int_clr_events); + + if (int_events & fep->ev_err) + (*fep->ops->ev_error)(dev, int_events); + + if (int_events & fep->ev_rx) { + if (!fpi->use_napi) + fs_enet_rx_non_napi(dev); + else { + napi_ok = netif_rx_schedule_prep(dev); + + (*fep->ops->napi_disable_rx)(dev); + (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx); + + /* NOTE: it is possible for FCCs in NAPI mode */ + /* to submit a spurious interrupt while in poll */ + if (napi_ok) + __netif_rx_schedule(dev); + } + } + + if (int_events & fep->ev_tx) + fs_enet_tx(dev); + } + + handled = nr > 0; + return IRQ_RETVAL(handled); +} + +void fs_init_bds(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + struct sk_buff *skb; + int i; + + fs_cleanup_bds(dev); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->tx_free = fep->tx_ring; + fep->cur_rx = fep->rx_bd_base; + + /* + * Initialize the receive buffer descriptors. + */ + for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { + skb = dev_alloc_skb(ENET_RX_FRSIZE); + if (skb == NULL) { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, unable to allocate skb\n", + dev->name); + break; + } + fep->rx_skbuff[i] = skb; + skb->dev = dev; + CBDW_BUFADDR(bdp, + dma_map_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); /* zero */ + CBDW_SC(bdp, BD_ENET_RX_EMPTY | + ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); + } + /* + * if we failed, fillup remainder + */ + for (; i < fep->rx_ring; i++, bdp++) { + fep->rx_skbuff[i] = NULL; + CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); + } + + /* + * ...and the same for transmit. + */ + for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { + fep->tx_skbuff[i] = NULL; + CBDW_BUFADDR(bdp, 0); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); + } +} + +void fs_cleanup_bds(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct sk_buff *skb; + int i; + + /* + * Reset SKB transmit buffers. + */ + for (i = 0; i < fep->tx_ring; i++) { + if ((skb = fep->tx_skbuff[i]) == NULL) + continue; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); + + fep->tx_skbuff[i] = NULL; + dev_kfree_skb(skb); + } + + /* + * Reset SKB receive buffers + */ + for (i = 0; i < fep->rx_ring; i++) { + if ((skb = fep->rx_skbuff[i]) == NULL) + continue; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + fep->rx_skbuff[i] = NULL; + + dev_kfree_skb(skb); + } +} + +/**********************************************************************************/ + +static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + int curidx; + u16 sc; + unsigned long flags; + + spin_lock_irqsave(&fep->tx_lock, flags); + + /* + * Fill in a Tx ring entry + */ + bdp = fep->cur_tx; + + if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { + netif_stop_queue(dev); + spin_unlock_irqrestore(&fep->tx_lock, flags); + + /* + * Ooops. All transmit buffers are full. Bail out. + * This should not happen, since the tx queue should be stopped. + */ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s tx queue full!.\n", dev->name); + return NETDEV_TX_BUSY; + } + + curidx = bdp - fep->tx_bd_base; + /* + * Clear all of the status flags. + */ + CBDC_SC(bdp, BD_ENET_TX_STATS); + + /* + * Save skb pointer. + */ + fep->tx_skbuff[curidx] = skb; + + fep->stats.tx_bytes += skb->len; + + /* + * Push the data cache so the CPM does not get stale memory data. + */ + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, + skb->data, skb->len, DMA_TO_DEVICE)); + CBDW_DATLEN(bdp, skb->len); + + dev->trans_start = jiffies; + + /* + * If this was the last BD in the ring, start at the beginning again. + */ + if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) + fep->cur_tx++; + else + fep->cur_tx = fep->tx_bd_base; + + if (!--fep->tx_free) + netif_stop_queue(dev); + + /* Trigger transmission start */ + sc = BD_ENET_TX_READY | BD_ENET_TX_INTR | + BD_ENET_TX_LAST | BD_ENET_TX_TC; + + /* note that while FEC does not have this bit + * it marks it as available for software use + * yay for hw reuse :) */ + if (skb->len <= 60) + sc |= BD_ENET_TX_PAD; + CBDS_SC(bdp, sc); + + (*fep->ops->tx_kickstart)(dev); + + spin_unlock_irqrestore(&fep->tx_lock, flags); + + return NETDEV_TX_OK; +} + +static int fs_request_irq(struct net_device *dev, int irq, const char *name, + irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs)) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + (*fep->ops->pre_request_irq)(dev, irq); + return request_irq(irq, irqf, SA_SHIRQ, name, dev); +} + +static void fs_free_irq(struct net_device *dev, int irq) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + free_irq(irq, dev); + (*fep->ops->post_free_irq)(dev, irq); +} + +/**********************************************************************************/ + +/* This interrupt occurs when the PHY detects a link change. */ +static irqreturn_t +fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + + fep = netdev_priv(dev); + fpi = fep->fpi; + + /* + * Acknowledge the interrupt if possible. If we have not + * found the PHY yet we can't process or acknowledge the + * interrupt now. Instead we ignore this interrupt for now, + * which we can do since it is edge triggered. It will be + * acknowledged later by fs_enet_open(). + */ + if (!fep->phy) + return IRQ_NONE; + + fs_mii_ack_int(dev); + fs_mii_link_status_change_check(dev, 0); + + return IRQ_HANDLED; +} + +static void fs_timeout(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int wake = 0; + + fep->stats.tx_errors++; + + spin_lock_irqsave(&fep->lock, flags); + + if (dev->flags & IFF_UP) { + (*fep->ops->stop)(dev); + (*fep->ops->restart)(dev); + } + + wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY); + spin_unlock_irqrestore(&fep->lock, flags); + + if (wake) + netif_wake_queue(dev); +} + +static int fs_enet_open(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + int r; + + /* Install our interrupt handler. */ + r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s Could not allocate FEC IRQ!", dev->name); + return -EINVAL; + } + + /* Install our phy interrupt handler */ + if (fpi->phy_irq != -1) { + + r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s Could not allocate PHY IRQ!", dev->name); + fs_free_irq(dev, fep->interrupt); + return -EINVAL; + } + } + + fs_mii_startup(dev); + netif_carrier_off(dev); + fs_mii_link_status_change_check(dev, 1); + + return 0; +} + +static int fs_enet_close(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + unsigned long flags; + + netif_stop_queue(dev); + netif_carrier_off(dev); + fs_mii_shutdown(dev); + + spin_lock_irqsave(&fep->lock, flags); + (*fep->ops->stop)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + + /* release any irqs */ + if (fpi->phy_irq != -1) + fs_free_irq(dev, fpi->phy_irq); + fs_free_irq(dev, fep->interrupt); + + return 0; +} + +static struct net_device_stats *fs_enet_get_stats(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return &fep->stats; +} + +/*************************************************************************/ + +static void fs_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); +} + +static int fs_get_regs_len(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + return (*fep->ops->get_regs_len)(dev); +} + +static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int r, len; + + len = regs->len; + + spin_lock_irqsave(&fep->lock, flags); + r = (*fep->ops->get_regs)(dev, p, &len); + spin_unlock_irqrestore(&fep->lock, flags); + + if (r == 0) + regs->version = 0; +} + +static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_gset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; +} + +static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_sset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; +} + +static int fs_nway_reset(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return mii_nway_restart(&fep->mii_if); +} + +static u32 fs_get_msglevel(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return fep->msg_enable; +} + +static void fs_set_msglevel(struct net_device *dev, u32 value) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fep->msg_enable = value; +} + +static struct ethtool_ops fs_ethtool_ops = { + .get_drvinfo = fs_get_drvinfo, + .get_regs_len = fs_get_regs_len, + .get_settings = fs_get_settings, + .set_settings = fs_set_settings, + .nway_reset = fs_nway_reset, + .get_link = ethtool_op_get_link, + .get_msglevel = fs_get_msglevel, + .set_msglevel = fs_set_msglevel, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_regs = fs_get_regs, +}; + +static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; + unsigned long flags; + int rc; + + if (!netif_running(dev)) + return -EINVAL; + + spin_lock_irqsave(&fep->lock, flags); + rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); + spin_unlock_irqrestore(&fep->lock, flags); + return rc; +} + +extern int fs_mii_connect(struct net_device *dev); +extern void fs_mii_disconnect(struct net_device *dev); + +static struct net_device *fs_init_instance(struct device *dev, + const struct fs_platform_info *fpi) +{ + struct net_device *ndev = NULL; + struct fs_enet_private *fep = NULL; + int privsize, i, r, err = 0, registered = 0; + + /* guard */ + if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) + return ERR_PTR(-EINVAL); + + privsize = sizeof(*fep) + (sizeof(struct sk_buff **) * + (fpi->rx_ring + fpi->tx_ring)); + + ndev = alloc_etherdev(privsize); + if (!ndev) { + err = -ENOMEM; + goto err; + } + SET_MODULE_OWNER(ndev); + + fep = netdev_priv(ndev); + memset(fep, 0, privsize); /* clear everything */ + + fep->dev = dev; + dev_set_drvdata(dev, ndev); + fep->fpi = fpi; + if (fpi->init_ioports) + fpi->init_ioports(); + +#ifdef CONFIG_FS_ENET_HAS_FEC + if (fs_get_fec_index(fpi->fs_no) >= 0) + fep->ops = &fs_fec_ops; +#endif + +#ifdef CONFIG_FS_ENET_HAS_SCC + if (fs_get_scc_index(fpi->fs_no) >=0 ) + fep->ops = &fs_scc_ops; +#endif + +#ifdef CONFIG_FS_ENET_HAS_FCC + if (fs_get_fcc_index(fpi->fs_no) >= 0) + fep->ops = &fs_fcc_ops; +#endif + + if (fep->ops == NULL) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s No matching ops found (%d).\n", + ndev->name, fpi->fs_no); + err = -EINVAL; + goto err; + } + + r = (*fep->ops->setup_data)(ndev); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s setup_data failed\n", + ndev->name); + err = r; + goto err; + } + + /* point rx_skbuff, tx_skbuff */ + fep->rx_skbuff = (struct sk_buff **)&fep[1]; + fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; + + /* init locks */ + spin_lock_init(&fep->lock); + spin_lock_init(&fep->tx_lock); + + /* + * Set the Ethernet address. + */ + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = fpi->macaddr[i]; + + r = (*fep->ops->allocate_bd)(ndev); + + if (fep->ring_base == NULL) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r); + err = r; + goto err; + } + + /* + * Set receive and transmit descriptor base. + */ + fep->rx_bd_base = fep->ring_base; + fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; + + /* initialize ring size variables */ + fep->tx_ring = fpi->tx_ring; + fep->rx_ring = fpi->rx_ring; + + /* + * The FEC Ethernet specific entries in the device structure. + */ + ndev->open = fs_enet_open; + ndev->hard_start_xmit = fs_enet_start_xmit; + ndev->tx_timeout = fs_timeout; + ndev->watchdog_timeo = 2 * HZ; + ndev->stop = fs_enet_close; + ndev->get_stats = fs_enet_get_stats; + ndev->set_multicast_list = fs_set_multicast_list; + if (fpi->use_napi) { + ndev->poll = fs_enet_rx_napi; + ndev->weight = fpi->napi_weight; + } + ndev->ethtool_ops = &fs_ethtool_ops; + ndev->do_ioctl = fs_ioctl; + + init_timer(&fep->phy_timer_list); + + netif_carrier_off(ndev); + + err = register_netdev(ndev); + if (err != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s register_netdev failed.\n", ndev->name); + goto err; + } + registered = 1; + + err = fs_mii_connect(ndev); + if (err != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s fs_mii_connect failed.\n", ndev->name); + goto err; + } + + return ndev; + + err: + if (ndev != NULL) { + + if (registered) + unregister_netdev(ndev); + + if (fep != NULL) { + (*fep->ops->free_bd)(ndev); + (*fep->ops->cleanup_data)(ndev); + } + + free_netdev(ndev); + } + + dev_set_drvdata(dev, NULL); + + return ERR_PTR(err); +} + +static int fs_cleanup_instance(struct net_device *ndev) +{ + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + struct device *dev; + + if (ndev == NULL) + return -EINVAL; + + fep = netdev_priv(ndev); + if (fep == NULL) + return -EINVAL; + + fpi = fep->fpi; + + fs_mii_disconnect(ndev); + + unregister_netdev(ndev); + + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), + fep->ring_base, fep->ring_mem_addr); + + /* reset it */ + (*fep->ops->cleanup_data)(ndev); + + dev = fep->dev; + if (dev != NULL) { + dev_set_drvdata(dev, NULL); + fep->dev = NULL; + } + + free_netdev(ndev); + + return 0; +} + +/**************************************************************************************/ + +/* handy pointer to the immap */ +void *fs_enet_immap = NULL; + +static int setup_immap(void) +{ + phys_addr_t paddr = 0; + unsigned long size = 0; + +#ifdef CONFIG_CPM1 + paddr = IMAP_ADDR; + size = 0x10000; /* map 64K */ +#endif + +#ifdef CONFIG_CPM2 + paddr = CPM_MAP_ADDR; + size = 0x40000; /* map 256 K */ +#endif + fs_enet_immap = ioremap(paddr, size); + if (fs_enet_immap == NULL) + return -EBADF; /* XXX ahem; maybe just BUG_ON? */ + + return 0; +} + +static void cleanup_immap(void) +{ + if (fs_enet_immap != NULL) { + iounmap(fs_enet_immap); + fs_enet_immap = NULL; + } +} + +/**************************************************************************************/ + +static int __devinit fs_enet_probe(struct device *dev) +{ + struct net_device *ndev; + + /* no fixup - no device */ + if (dev->platform_data == NULL) { + printk(KERN_INFO "fs_enet: " + "probe called with no platform data; " + "remove unused devices\n"); + return -ENODEV; + } + + ndev = fs_init_instance(dev, dev->platform_data); + if (IS_ERR(ndev)) + return PTR_ERR(ndev); + return 0; +} + +static int fs_enet_remove(struct device *dev) +{ + return fs_cleanup_instance(dev_get_drvdata(dev)); +} + +static struct device_driver fs_enet_fec_driver = { + .name = "fsl-cpm-fec", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static struct device_driver fs_enet_scc_driver = { + .name = "fsl-cpm-scc", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static struct device_driver fs_enet_fcc_driver = { + .name = "fsl-cpm-fcc", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static int __init fs_init(void) +{ + int r; + + printk(KERN_INFO + "%s", version); + + r = setup_immap(); + if (r != 0) + return r; + r = driver_register(&fs_enet_fec_driver); + if (r != 0) + goto err; + + r = driver_register(&fs_enet_fcc_driver); + if (r != 0) + goto err; + + r = driver_register(&fs_enet_scc_driver); + if (r != 0) + goto err; + + return 0; +err: + cleanup_immap(); + return r; + +} + +static void __exit fs_cleanup(void) +{ + driver_unregister(&fs_enet_fec_driver); + driver_unregister(&fs_enet_fcc_driver); + driver_unregister(&fs_enet_scc_driver); + cleanup_immap(); +} + +/**************************************************************************************/ + +module_init(fs_init); +module_exit(fs_cleanup); diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c new file mode 100644 index 000000000000..c6770377ef87 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet-mii.c @@ -0,0 +1,507 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * Heavily based on original FEC driver by Dan Malek + * and modifications by Joakim Tjernlund + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +/* + * Generic PHY support. + * Should work for all PHYs, but link change is detected by polling + */ + +static void generic_timer_callback(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; + + add_timer(&fep->phy_timer_list); + + fs_mii_link_status_change_check(dev, 0); +} + +static void generic_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ + fep->phy_timer_list.data = (unsigned long)dev; + fep->phy_timer_list.function = generic_timer_callback; + add_timer(&fep->phy_timer_list); +} + +static void generic_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + del_timer_sync(&fep->phy_timer_list); +} + +/* ------------------------------------------------------------------------- */ +/* The Davicom DM9161 is used on the NETTA board */ + +/* register definitions */ + +#define MII_DM9161_ANAR 4 /* Aux. Config Register */ +#define MII_DM9161_ACR 16 /* Aux. Config Register */ +#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ +#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ +#define MII_DM9161_INTR 21 /* Interrupt Register */ +#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ +#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ + +static void dm9161_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); + /* Start autonegotiation */ + fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ*8); +} + +static void dm9161_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); +} + +static void dm9161_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); +} + +/**********************************************************************************/ + +static const struct phy_info phy_info[] = { + { + .id = 0x00181b88, + .name = "DM9161", + .startup = dm9161_startup, + .ack_int = dm9161_ack_int, + .shutdown = dm9161_shutdown, + }, { + .id = 0, + .name = "GENERIC", + .startup = generic_startup, + .shutdown = generic_shutdown, + }, +}; + +/**********************************************************************************/ + +static int phy_id_detect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = fep->mii_bus; + int i, r, start, end, phytype, physubtype; + const struct phy_info *phy; + int phy_hwid, phy_id; + + phy_hwid = -1; + fep->phy = NULL; + + /* auto-detect? */ + if (fpi->phy_addr == -1) { + start = 1; + end = 32; + } else { /* direct */ + start = fpi->phy_addr; + end = start + 1; + } + + for (phy_id = start; phy_id < end; phy_id++) { + /* skip already used phy addresses on this bus */ + if (bus->usage_map & (1 << phy_id)) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID1); + if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID2); + if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) + continue; + phy_hwid = (phytype << 16) | physubtype; + if (phy_hwid != -1) + break; + } + + if (phy_hwid == -1) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s No PHY detected! range=0x%02x-0x%02x\n", + dev->name, start, end); + return -1; + } + + for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) + if (phy->id == (phy_hwid >> 4) || phy->id == 0) + break; + + if (i >= ARRAY_SIZE(phy_info)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s PHY id 0x%08x is not supported!\n", + dev->name, phy_hwid); + return -1; + } + + fep->phy = phy; + + /* mark this address as used */ + bus->usage_map |= (1 << phy_id); + + printk(KERN_INFO DRV_MODULE_NAME + ": %s Phy @ 0x%x, type %s (0x%08x)%s\n", + dev->name, phy_id, fep->phy->name, phy_hwid, + fpi->phy_addr == -1 ? " (auto-detected)" : ""); + + return phy_id; +} + +void fs_mii_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->startup) + (*fep->phy->startup) (dev); +} + +void fs_mii_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->shutdown) + (*fep->phy->shutdown) (dev); +} + +void fs_mii_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->ack_int) + (*fep->phy->ack_int) (dev); +} + +#define MII_LINK 0x0001 +#define MII_HALF 0x0002 +#define MII_FULL 0x0004 +#define MII_BASE4 0x0008 +#define MII_10M 0x0010 +#define MII_100M 0x0020 +#define MII_1G 0x0040 +#define MII_10G 0x0080 + +/* return full mii info at one gulp, with a usable form */ +static unsigned int mii_full_status(struct mii_if_info *mii) +{ + unsigned int status; + int bmsr, adv, lpa, neg; + struct fs_enet_private* fep = netdev_priv(mii->dev); + + /* first, a dummy read, needed to latch some MII phys */ + (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + + /* no link */ + if ((bmsr & BMSR_LSTATUS) == 0) + return 0; + + status = MII_LINK; + + /* Lets look what ANEG says if it's supported - otherwize we shall + take the right values from the platform info*/ + if(!mii->force_media) { + /* autoneg not completed; don't bother */ + if ((bmsr & BMSR_ANEGCOMPLETE) == 0) + return 0; + + adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE); + lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA); + + neg = lpa & adv; + } else { + neg = fep->fpi->bus_info->lpa; + } + + if (neg & LPA_100FULL) + status |= MII_FULL | MII_100M; + else if (neg & LPA_100BASE4) + status |= MII_FULL | MII_BASE4 | MII_100M; + else if (neg & LPA_100HALF) + status |= MII_HALF | MII_100M; + else if (neg & LPA_10FULL) + status |= MII_FULL | MII_10M; + else + status |= MII_HALF | MII_10M; + + return status; +} + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct mii_if_info *mii = &fep->mii_if; + unsigned int mii_status; + int ok_to_print, link, duplex, speed; + unsigned long flags; + + ok_to_print = netif_msg_link(fep); + + mii_status = mii_full_status(mii); + + if (!init_media && mii_status == fep->last_mii_status) + return; + + fep->last_mii_status = mii_status; + + link = !!(mii_status & MII_LINK); + duplex = !!(mii_status & MII_FULL); + speed = (mii_status & MII_100M) ? 100 : 10; + + if (link == 0) { + netif_carrier_off(mii->dev); + netif_stop_queue(dev); + if (!init_media) { + spin_lock_irqsave(&fep->lock, flags); + (*fep->ops->stop)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + } + + if (ok_to_print) + printk(KERN_INFO "%s: link down\n", mii->dev->name); + + } else { + + mii->full_duplex = duplex; + + netif_carrier_on(mii->dev); + + spin_lock_irqsave(&fep->lock, flags); + fep->duplex = duplex; + fep->speed = speed; + (*fep->ops->restart)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + + netif_start_queue(dev); + + if (ok_to_print) + printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n", + dev->name, speed, duplex ? "full" : "half"); + } +} + +/**********************************************************************************/ + +int fs_mii_read(struct net_device *dev, int phy_id, int location) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + + unsigned long flags; + int ret; + + spin_lock_irqsave(&bus->mii_lock, flags); + ret = (*bus->mii_read)(bus, phy_id, location); + spin_unlock_irqrestore(&bus->mii_lock, flags); + + return ret; +} + +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + unsigned long flags; + + spin_lock_irqsave(&bus->mii_lock, flags); + (*bus->mii_write)(bus, phy_id, location, value); + spin_unlock_irqrestore(&bus->mii_lock, flags); +} + +/*****************************************************************************/ + +/* list of all registered mii buses */ +static LIST_HEAD(fs_mii_bus_list); + +static struct fs_enet_mii_bus *lookup_bus(int method, int id) +{ + struct list_head *ptr; + struct fs_enet_mii_bus *bus; + + list_for_each(ptr, &fs_mii_bus_list) { + bus = list_entry(ptr, struct fs_enet_mii_bus, list); + if (bus->bus_info->method == method && + bus->bus_info->id == id) + return bus; + } + return NULL; +} + +static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) +{ + struct fs_enet_mii_bus *bus; + int ret = 0; + + bus = kmalloc(sizeof(*bus), GFP_KERNEL); + if (bus == NULL) { + ret = -ENOMEM; + goto err; + } + memset(bus, 0, sizeof(*bus)); + spin_lock_init(&bus->mii_lock); + bus->bus_info = bi; + bus->refs = 0; + bus->usage_map = 0; + + /* perform initialization */ + switch (bi->method) { + + case fsmii_fixed: + ret = fs_mii_fixed_init(bus); + if (ret != 0) + goto err; + break; + + case fsmii_bitbang: + ret = fs_mii_bitbang_init(bus); + if (ret != 0) + goto err; + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + ret = fs_mii_fec_init(bus); + if (ret != 0) + goto err; + break; +#endif + default: + ret = -EINVAL; + goto err; + } + + list_add(&bus->list, &fs_mii_bus_list); + + return bus; + +err: + if (bus) + kfree(bus); + return ERR_PTR(ret); +} + +static void destroy_bus(struct fs_enet_mii_bus *bus) +{ + /* remove from bus list */ + list_del(&bus->list); + + /* nothing more needed */ + kfree(bus); +} + +int fs_mii_connect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = NULL; + + /* check method validity */ + switch (fpi->bus_info->method) { + case fsmii_fixed: + case fsmii_bitbang: + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + break; +#endif + default: + printk(KERN_ERR DRV_MODULE_NAME + ": %s Unknown MII bus method (%d)!\n", + dev->name, fpi->bus_info->method); + return -EINVAL; + } + + bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id); + + /* if not found create new bus */ + if (bus == NULL) { + bus = create_bus(fpi->bus_info); + if (IS_ERR(bus)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s MII bus creation failure!\n", dev->name); + return PTR_ERR(bus); + } + } + + bus->refs++; + + fep->mii_bus = bus; + + fep->mii_if.dev = dev; + fep->mii_if.phy_id_mask = 0x1f; + fep->mii_if.reg_num_mask = 0x1f; + fep->mii_if.mdio_read = fs_mii_read; + fep->mii_if.mdio_write = fs_mii_write; + fep->mii_if.force_media = fpi->bus_info->disable_aneg; + fep->mii_if.phy_id = phy_id_detect(dev); + + return 0; +} + +void fs_mii_disconnect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = NULL; + + bus = fep->mii_bus; + fep->mii_bus = NULL; + + if (--bus->refs <= 0) + destroy_bus(bus); +} diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h new file mode 100644 index 000000000000..1105543b9d88 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet.h @@ -0,0 +1,245 @@ +#ifndef FS_ENET_H +#define FS_ENET_H + +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef CONFIG_CPM1 +#include +#endif + +#ifdef CONFIG_CPM2 +#include +#endif + +/* hw driver ops */ +struct fs_ops { + int (*setup_data)(struct net_device *dev); + int (*allocate_bd)(struct net_device *dev); + void (*free_bd)(struct net_device *dev); + void (*cleanup_data)(struct net_device *dev); + void (*set_multicast_list)(struct net_device *dev); + void (*restart)(struct net_device *dev); + void (*stop)(struct net_device *dev); + void (*pre_request_irq)(struct net_device *dev, int irq); + void (*post_free_irq)(struct net_device *dev, int irq); + void (*napi_clear_rx_event)(struct net_device *dev); + void (*napi_enable_rx)(struct net_device *dev); + void (*napi_disable_rx)(struct net_device *dev); + void (*rx_bd_done)(struct net_device *dev); + void (*tx_kickstart)(struct net_device *dev); + u32 (*get_int_events)(struct net_device *dev); + void (*clear_int_events)(struct net_device *dev, u32 int_events); + void (*ev_error)(struct net_device *dev, u32 int_events); + int (*get_regs)(struct net_device *dev, void *p, int *sizep); + int (*get_regs_len)(struct net_device *dev); + void (*tx_restart)(struct net_device *dev); +}; + +struct phy_info { + unsigned int id; + const char *name; + void (*startup) (struct net_device * dev); + void (*shutdown) (struct net_device * dev); + void (*ack_int) (struct net_device * dev); +}; + +/* The FEC stores dest/src/type, data, and checksum for receive packets. + */ +#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ +#define MIN_MTU 46 /* this is data size */ +#define CRC_LEN 4 + +#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) +#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) + +/* Must be a multiple of 32 (to cover both FEC & FCC) */ +#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31) +/* This is needed so that invalidate_xxx wont invalidate too much */ +#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) + +struct fs_enet_mii_bus { + struct list_head list; + spinlock_t mii_lock; + const struct fs_mii_bus_info *bus_info; + int refs; + u32 usage_map; + + int (*mii_read)(struct fs_enet_mii_bus *bus, + int phy_id, int location); + + void (*mii_write)(struct fs_enet_mii_bus *bus, + int phy_id, int location, int value); + + union { + struct { + unsigned int mii_speed; + void *fecp; + } fec; + + struct { + /* note that the actual port size may */ + /* be different; cpm(s) handle it OK */ + u8 mdio_msk; + u8 *mdio_dir; + u8 *mdio_dat; + u8 mdc_msk; + u8 *mdc_dir; + u8 *mdc_dat; + } bitbang; + + struct { + u16 lpa; + } fixed; + }; +}; + +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus); +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); +int fs_mii_fec_init(struct fs_enet_mii_bus *bus); + +struct fs_enet_private { + struct device *dev; /* pointer back to the device (must be initialized first) */ + spinlock_t lock; /* during all ops except TX pckt processing */ + spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ + const struct fs_platform_info *fpi; + const struct fs_ops *ops; + int rx_ring, tx_ring; + dma_addr_t ring_mem_addr; + void *ring_base; + struct sk_buff **rx_skbuff; + struct sk_buff **tx_skbuff; + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ + cbd_t *tx_bd_base; + cbd_t *dirty_tx; /* ring entries to be free()ed. */ + cbd_t *cur_rx; + cbd_t *cur_tx; + int tx_free; + struct net_device_stats stats; + struct timer_list phy_timer_list; + const struct phy_info *phy; + u32 msg_enable; + struct mii_if_info mii_if; + unsigned int last_mii_status; + struct fs_enet_mii_bus *mii_bus; + int interrupt; + + int duplex, speed; /* current settings */ + + /* event masks */ + u32 ev_napi_rx; /* mask of NAPI rx events */ + u32 ev_rx; /* rx event mask */ + u32 ev_tx; /* tx event mask */ + u32 ev_err; /* error event mask */ + + u16 bd_rx_empty; /* mask of BD rx empty */ + u16 bd_rx_err; /* mask of BD rx errors */ + + union { + struct { + int idx; /* FEC1 = 0, FEC2 = 1 */ + void *fecp; /* hw registers */ + u32 hthi, htlo; /* state for multicast */ + } fec; + + struct { + int idx; /* FCC1-3 = 0-2 */ + void *fccp; /* hw registers */ + void *ep; /* parameter ram */ + void *fcccp; /* hw registers cont. */ + void *mem; /* FCC DPRAM */ + u32 gaddrh, gaddrl; /* group address */ + } fcc; + + struct { + int idx; /* FEC1 = 0, FEC2 = 1 */ + void *sccp; /* hw registers */ + void *ep; /* parameter ram */ + u32 hthi, htlo; /* state for multicast */ + } scc; + + }; +}; + +/***************************************************************************/ + +int fs_mii_read(struct net_device *dev, int phy_id, int location); +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value); + +void fs_mii_startup(struct net_device *dev); +void fs_mii_shutdown(struct net_device *dev); +void fs_mii_ack_int(struct net_device *dev); + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media); + +void fs_init_bds(struct net_device *dev); +void fs_cleanup_bds(struct net_device *dev); + +/***************************************************************************/ + +#define DRV_MODULE_NAME "fs_enet" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Aug 8, 2005" + +/***************************************************************************/ + +int fs_enet_platform_init(void); +void fs_enet_platform_cleanup(void); + +/***************************************************************************/ + +/* buffer descriptor access macros */ + +/* access macros */ +#if defined(CONFIG_CPM1) +/* for a a CPM1 __raw_xxx's are sufficient */ +#define __cbd_out32(addr, x) __raw_writel(x, addr) +#define __cbd_out16(addr, x) __raw_writew(x, addr) +#define __cbd_in32(addr) __raw_readl(addr) +#define __cbd_in16(addr) __raw_readw(addr) +#else +/* for others play it safe */ +#define __cbd_out32(addr, x) out_be32(addr, x) +#define __cbd_out16(addr, x) out_be16(addr, x) +#define __cbd_in32(addr) in_be32(addr) +#define __cbd_in16(addr) in_be16(addr) +#endif + +/* write */ +#define CBDW_SC(_cbd, _sc) __cbd_out16(&(_cbd)->cbd_sc, (_sc)) +#define CBDW_DATLEN(_cbd, _datlen) __cbd_out16(&(_cbd)->cbd_datlen, (_datlen)) +#define CBDW_BUFADDR(_cbd, _bufaddr) __cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) + +/* read */ +#define CBDR_SC(_cbd) __cbd_in16(&(_cbd)->cbd_sc) +#define CBDR_DATLEN(_cbd) __cbd_in16(&(_cbd)->cbd_datlen) +#define CBDR_BUFADDR(_cbd) __cbd_in32(&(_cbd)->cbd_bufaddr) + +/* set bits */ +#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) + +/* clear bits */ +#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) + +/*******************************************************************/ + +extern const struct fs_ops fs_fec_ops; +extern const struct fs_ops fs_fcc_ops; +extern const struct fs_ops fs_scc_ops; + +/*******************************************************************/ + +/* handy pointer to the immap */ +extern void *fs_enet_immap; + +/*******************************************************************/ + +#endif diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c new file mode 100644 index 000000000000..a940b96433c7 --- /dev/null +++ b/drivers/net/fs_enet/mac-fcc.c @@ -0,0 +1,578 @@ +/* + * FCC driver for Motorola MPC82xx (PQ2). + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +/* FCC access macros */ + +#define __fcc_out32(addr, x) out_be32((unsigned *)addr, x) +#define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x) +#define __fcc_out8(addr, x) out_8((unsigned char *)addr, x) +#define __fcc_in32(addr) in_be32((unsigned *)addr) +#define __fcc_in16(addr) in_be16((unsigned short *)addr) +#define __fcc_in8(addr) in_8((unsigned char *)addr) + +/* parameter space */ + +/* write, read, set bits, clear bits */ +#define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v)) +#define R32(_p, _m) __fcc_in32(&(_p)->_m) +#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) +#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) + +#define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v)) +#define R16(_p, _m) __fcc_in16(&(_p)->_m) +#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) +#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) + +#define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v)) +#define R8(_p, _m) __fcc_in8(&(_p)->_m) +#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) +#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) + +/*************************************************/ + +#define FCC_MAX_MULTICAST_ADDRS 64 + +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) +#define mk_mii_end 0 + +#define MAX_CR_CMD_LOOPS 10000 + +static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) +{ + const struct fs_platform_info *fpi = fep->fpi; + + cpm2_map_t *immap = fs_enet_immap; + cpm_cpm2_t *cpmp = &immap->im_cpm; + u32 v; + int i; + + /* Currently I don't know what feature call will look like. But + I guess there'd be something like do_cpm_cmd() which will require page & sblock */ + v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); + W32(cpmp, cp_cpcr, v | CPM_CR_FLG); + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) + if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) + break; + + if (i >= MAX_CR_CMD_LOOPS) { + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; + } + + return 0; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq(pdev, 0); + + /* Attach the memory for the FCC Parameter RAM */ + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); + fep->fcc.ep = (void *)r->start; + + if (fep->fcc.ep == NULL) + return -EINVAL; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); + fep->fcc.fccp = (void *)r->start; + + if (fep->fcc.fccp == NULL) + return -EINVAL; + + fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; + + if (fep->fcc.fcccp == NULL) + return -EINVAL; + + return 0; +} + +#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) +#define FCC_RX_EVENT (FCC_ENET_RXF) +#define FCC_TX_EVENT (FCC_ENET_TXB) +#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); + if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ + return -EINVAL; + + fep->fcc.mem = (void *)fpi->mem_offset; + + if (do_pd_setup(fep) != 0) + return -EINVAL; + + fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK; + fep->ev_rx = FCC_RX_EVENT; + fep->ev_tx = FCC_TX_EVENT; + fep->ev_err = FCC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_base = dma_alloc_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), &fep->ring_mem_addr, + GFP_KERNEL); + if (fep->ring_base == NULL) + return -ENOMEM; + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + if (fep->ring_base) + dma_free_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), + fep->ring_base, fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + S32(fccp, fcc_fpsmr, FCC_PSMR_PRO); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_enet_t *ep = fep->fcc.ep; + + W32(ep, fen_gaddrh, 0); + W32(ep, fen_gaddrl, 0); +} + +static void set_multicast_one(struct net_device *dev, const u8 *mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_enet_t *ep = fep->fcc.ep; + u16 taddrh, taddrm, taddrl; + + taddrh = ((u16)mac[5] << 8) | mac[4]; + taddrm = ((u16)mac[3] << 8) | mac[2]; + taddrl = ((u16)mac[1] << 8) | mac[0]; + + W16(ep, fen_taddrh, taddrh); + W16(ep, fen_taddrm, taddrm); + W16(ep, fen_taddrl, taddrl); + fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + fcc_enet_t *ep = fep->fcc.ep; + + /* clear promiscuous always */ + C32(fccp, fcc_fpsmr, FCC_PSMR_PRO); + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > FCC_MAX_MULTICAST_ADDRS) { + + W32(ep, fen_gaddrh, 0xffffffff); + W32(ep, fen_gaddrl, 0xffffffff); + } + + /* read back */ + fep->fcc.gaddrh = R32(ep, fen_gaddrh); + fep->fcc.gaddrl = R32(ep, fen_gaddrl); +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +static void restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + fcc_t *fccp = fep->fcc.fccp; + fcc_c_t *fcccp = fep->fcc.fcccp; + fcc_enet_t *ep = fep->fcc.ep; + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; + u16 paddrh, paddrm, paddrl; + u16 mem_addr; + const unsigned char *mac; + int i; + + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); + + /* clear everything (slow & steady does it) */ + for (i = 0; i < sizeof(*ep); i++) + __fcc_out8((char *)ep + i, 0); + + /* get physical address */ + rx_bd_base_phys = fep->ring_mem_addr; + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; + + /* point to bds */ + W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys); + W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys); + + /* Set maximum bytes per receive buffer. + * It must be a multiple of 32. + */ + W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE); + + W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24); + W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24); + + /* Allocate space in the reserved FCC area of DPRAM for the + * internal buffers. No one uses this space (yet), so we + * can do this. Later, we will add resource management for + * this area. + */ + + mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */ + + W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff)); + W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff)); + W16(ep, fen_padptr, mem_addr + 64); + + /* fill with special symbol... */ + memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32); + + W32(ep, fen_genfcc.fcc_rbptr, 0); + W32(ep, fen_genfcc.fcc_tbptr, 0); + W32(ep, fen_genfcc.fcc_rcrc, 0); + W32(ep, fen_genfcc.fcc_tcrc, 0); + W16(ep, fen_genfcc.fcc_res1, 0); + W32(ep, fen_genfcc.fcc_res2, 0); + + /* no CAM */ + W32(ep, fen_camptr, 0); + + /* Set CRC preset and mask */ + W32(ep, fen_cmask, 0xdebb20e3); + W32(ep, fen_cpres, 0xffffffff); + + W32(ep, fen_crcec, 0); /* CRC Error counter */ + W32(ep, fen_alec, 0); /* alignment error counter */ + W32(ep, fen_disfc, 0); /* discard frame counter */ + W16(ep, fen_retlim, 15); /* Retry limit threshold */ + W16(ep, fen_pper, 0); /* Normal persistence */ + + /* set group address */ + W32(ep, fen_gaddrh, fep->fcc.gaddrh); + W32(ep, fen_gaddrl, fep->fcc.gaddrh); + + /* Clear hash filter tables */ + W32(ep, fen_iaddrh, 0); + W32(ep, fen_iaddrl, 0); + + /* Clear the Out-of-sequence TxBD */ + W16(ep, fen_tfcstat, 0); + W16(ep, fen_tfclen, 0); + W32(ep, fen_tfcptr, 0); + + W16(ep, fen_mflr, PKT_MAXBUF_SIZE); /* maximum frame length register */ + W16(ep, fen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ + + /* set address */ + mac = dev->dev_addr; + paddrh = ((u16)mac[5] << 8) | mac[4]; + paddrm = ((u16)mac[3] << 8) | mac[2]; + paddrl = ((u16)mac[1] << 8) | mac[0]; + + W16(ep, fen_paddrh, paddrh); + W16(ep, fen_paddrm, paddrm); + W16(ep, fen_paddrl, paddrl); + + W16(ep, fen_taddrh, 0); + W16(ep, fen_taddrm, 0); + W16(ep, fen_taddrl, 0); + + W16(ep, fen_maxd1, 1520); /* maximum DMA1 length */ + W16(ep, fen_maxd2, 1520); /* maximum DMA2 length */ + + /* Clear stat counters, in case we ever enable RMON */ + W32(ep, fen_octc, 0); + W32(ep, fen_colc, 0); + W32(ep, fen_broc, 0); + W32(ep, fen_mulc, 0); + W32(ep, fen_uspc, 0); + W32(ep, fen_frgc, 0); + W32(ep, fen_ospc, 0); + W32(ep, fen_jbrc, 0); + W32(ep, fen_p64c, 0); + W32(ep, fen_p65c, 0); + W32(ep, fen_p128c, 0); + W32(ep, fen_p256c, 0); + W32(ep, fen_p512c, 0); + W32(ep, fen_p1024c, 0); + + W16(ep, fen_rfthr, 0); /* Suggested by manual */ + W16(ep, fen_rfcnt, 0); + W16(ep, fen_cftype, 0); + + fs_init_bds(dev); + + /* adjust to speed (for RMII mode) */ + if (fpi->use_rmii) { + if (fep->speed == 100) + C8(fcccp, fcc_gfemr, 0x20); + else + S8(fcccp, fcc_gfemr, 0x20); + } + + fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); + + /* clear events */ + W16(fccp, fcc_fcce, 0xffff); + + /* Enable interrupts we wish to service */ + W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB); + + /* Set GFMR to enable Ethernet operating mode */ + W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); + + /* set sync/delimiters */ + W16(fccp, fcc_fdsr, 0xd555); + + W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC); + + if (fpi->use_rmii) + S32(fccp, fcc_fpsmr, FCC_PSMR_RMII); + + /* adjust to duplex mode */ + if (fep->duplex) + S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); + else + C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); + + S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + /* stop ethernet */ + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); + + /* clear events */ + W16(fccp, fcc_fcce, 0xffff); + + /* clear interrupt mask */ + W16(fccp, fcc_fccm, 0); + + fs_cleanup_bds(dev); +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + /* nothing */ +} + +static void tx_kickstart(struct net_device *dev) +{ + /* nothing */ +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + return (u32)R16(fccp, fcc_fcce); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + W16(fccp, fcc_fcce, int_events & 0xffff); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events); +} + +int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) + return -EINVAL; + + memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); + p = (char *)p + sizeof(fcc_t); + + memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); + p = (char *)p + sizeof(fcc_c_t); + + memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); + + return 0; +} + +int get_regs_len(struct net_device *dev) +{ + return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); +} + +/* Some transmit errors cause the transmitter to shut + * down. We now issue a restart transmit. Since the + * errors close the BD and update the pointers, the restart + * _should_ pick up without having to reset any of our + * pointers either. Also, To workaround 8260 device erratum + * CPM37, we must disable and then re-enable the transmitter + * following a Late Collision, Underrun, or Retry Limit error. + */ +void tx_restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + C32(fccp, fcc_gfmr, FCC_GFMR_ENT); + udelay(10); + S32(fccp, fcc_gfmr, FCC_GFMR_ENT); + + fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); +} + +/*************************************************************************/ + +const struct fs_ops fs_fcc_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c new file mode 100644 index 000000000000..5ef4e845a387 --- /dev/null +++ b/drivers/net/fs_enet/mac-fec.c @@ -0,0 +1,653 @@ +/* + * Freescale Ethernet controllers + * + * Copyright (c) 2005 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_8xx +#include +#include +#include +#include +#endif + +#include "fs_enet.h" + +/*************************************************/ + +#if defined(CONFIG_CPM1) +/* for a CPM1 __raw_xxx's are sufficient */ +#define __fs_out32(addr, x) __raw_writel(x, addr) +#define __fs_out16(addr, x) __raw_writew(x, addr) +#define __fs_in32(addr) __raw_readl(addr) +#define __fs_in16(addr) __raw_readw(addr) +#else +/* for others play it safe */ +#define __fs_out32(addr, x) out_be32(addr, x) +#define __fs_out16(addr, x) out_be16(addr, x) +#define __fs_in32(addr) in_be32(addr) +#define __fs_in16(addr) in_be16(addr) +#endif + +/* write */ +#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v)) + +/* read */ +#define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg) + +/* set bits */ +#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) + +/* clear bits */ +#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) + + +/* CRC polynomium used by the FEC for the multicast group filtering */ +#define FEC_CRC_POLY 0x04C11DB7 + +#define FEC_MAX_MULTICAST_ADDRS 64 + +/* Interrupt events/masks. +*/ +#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ +#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ +#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ +#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ +#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ +#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ +#define FEC_ENET_RXF 0x02000000U /* Full frame received */ +#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ +#define FEC_ENET_MII 0x00800000U /* MII interrupt */ +#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ + +#define FEC_ECNTRL_PINMUX 0x00000004 +#define FEC_ECNTRL_ETHER_EN 0x00000002 +#define FEC_ECNTRL_RESET 0x00000001 + +#define FEC_RCNTRL_BC_REJ 0x00000010 +#define FEC_RCNTRL_PROM 0x00000008 +#define FEC_RCNTRL_MII_MODE 0x00000004 +#define FEC_RCNTRL_DRT 0x00000002 +#define FEC_RCNTRL_LOOP 0x00000001 + +#define FEC_TCNTRL_FDEN 0x00000004 +#define FEC_TCNTRL_HBC 0x00000002 +#define FEC_TCNTRL_GTS 0x00000001 + + +/* Make MII read/write commands for the FEC. +*/ +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) +#define mk_mii_end 0 + +#define FEC_MII_LOOPS 10000 + +/* + * Delay to wait for FEC reset command to complete (in us) + */ +#define FEC_RESET_DELAY 50 + +static int whack_reset(fec_t * fecp) +{ + int i; + + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); + for (i = 0; i < FEC_RESET_DELAY; i++) { + if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0) + return 0; /* OK */ + udelay(1); + } + + return -1; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + fep->fec.fecp =(void*)r->start; + + if(fep->fec.fecp == NULL) + return -EINVAL; + + return 0; + +} + +#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) +#define FEC_RX_EVENT (FEC_ENET_RXF) +#define FEC_TX_EVENT (FEC_ENET_TXF) +#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \ + FEC_ENET_BABT | FEC_ENET_EBERR) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (do_pd_setup(fep) != 0) + return -EINVAL; + + fep->fec.hthi = 0; + fep->fec.htlo = 0; + + fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK; + fep->ev_rx = FEC_RX_EVENT; + fep->ev_tx = FEC_TX_EVENT; + fep->ev_err = FEC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_base = dma_alloc_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), &fep->ring_mem_addr, + GFP_KERNEL); + if (fep->ring_base == NULL) + return -ENOMEM; + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + if(fep->ring_base) + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) + * sizeof(cbd_t), + fep->ring_base, + fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FS(fecp, r_cntrl, FEC_RCNTRL_PROM); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fep->fec.hthi = 0; + fep->fec.htlo = 0; +} + +static void set_multicast_one(struct net_device *dev, const u8 *mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + int temp, hash_index, i, j; + u32 crc, csrVal; + u8 byte, msb; + + crc = 0xffffffff; + for (i = 0; i < 6; i++) { + byte = mac[i]; + for (j = 0; j < 8; j++) { + msb = crc >> 31; + crc <<= 1; + if (msb ^ (byte & 0x1)) + crc ^= FEC_CRC_POLY; + byte >>= 1; + } + } + + temp = (crc & 0x3f) >> 1; + hash_index = ((temp & 0x01) << 4) | + ((temp & 0x02) << 2) | + ((temp & 0x04)) | + ((temp & 0x08) >> 2) | + ((temp & 0x10) >> 4); + csrVal = 1 << hash_index; + if (crc & 1) + fep->fec.hthi |= csrVal; + else + fep->fec.htlo |= csrVal; +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { + fep->fec.hthi = 0xffffffffU; + fep->fec.htlo = 0xffffffffU; + } + + FC(fecp, r_cntrl, FEC_RCNTRL_PROM); + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +static void restart(struct net_device *dev) +{ +#ifdef CONFIG_DUET + immap_t *immap = fs_enet_immap; + u32 cptr; +#endif + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + const struct fs_platform_info *fpi = fep->fpi; + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; + int r; + u32 addrhi, addrlo; + + r = whack_reset(fep->fec.fecp); + if (r != 0) + printk(KERN_ERR DRV_MODULE_NAME + ": %s FEC Reset FAILED!\n", dev->name); + + /* + * Set station address. + */ + addrhi = ((u32) dev->dev_addr[0] << 24) | + ((u32) dev->dev_addr[1] << 16) | + ((u32) dev->dev_addr[2] << 8) | + (u32) dev->dev_addr[3]; + addrlo = ((u32) dev->dev_addr[4] << 24) | + ((u32) dev->dev_addr[5] << 16); + FW(fecp, addr_low, addrhi); + FW(fecp, addr_high, addrlo); + + /* + * Reset all multicast. + */ + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); + + /* + * Set maximum receive buffer size. + */ + FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); + FW(fecp, r_hash, PKT_MAXBUF_SIZE); + + /* get physical address */ + rx_bd_base_phys = fep->ring_mem_addr; + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; + + /* + * Set receive and transmit descriptor base. + */ + FW(fecp, r_des_start, rx_bd_base_phys); + FW(fecp, x_des_start, tx_bd_base_phys); + + fs_init_bds(dev); + + /* + * Enable big endian and don't care about SDMA FC. + */ + FW(fecp, fun_code, 0x78000000); + + /* + * Set MII speed. + */ + FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed); + + /* + * Clear any outstanding interrupt. + */ + FW(fecp, ievent, 0xffc0); + FW(fecp, ivec, (fep->interrupt / 2) << 29); + + + /* + * adjust to speed (only for DUET & RMII) + */ +#ifdef CONFIG_DUET + if (fpi->use_rmii) { + cptr = in_be32(&immap->im_cpm.cp_cptr); + switch (fs_get_fec_index(fpi->fs_no)) { + case 0: + cptr |= 0x100; + if (fep->speed == 10) + cptr |= 0x0000010; + else if (fep->speed == 100) + cptr &= ~0x0000010; + break; + case 1: + cptr |= 0x80; + if (fep->speed == 10) + cptr |= 0x0000008; + else if (fep->speed == 100) + cptr &= ~0x0000008; + break; + default: + BUG(); /* should never happen */ + break; + } + out_be32(&immap->im_cpm.cp_cptr, cptr); + } +#endif + + FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + /* + * adjust to duplex mode + */ + if (fep->duplex) { + FC(fecp, r_cntrl, FEC_RCNTRL_DRT); + FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ + } else { + FS(fecp, r_cntrl, FEC_RCNTRL_DRT); + FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ + } + + /* + * Enable interrupts we wish to service. + */ + FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB); + + /* + * And last, enable the transmit and receive processing. + */ + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, r_des_active, 0x01000000); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + struct fs_enet_mii_bus *bus = fep->mii_bus; + const struct fs_mii_bus_info *bi = bus->bus_info; + int i; + + if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) + return; /* already down */ + + FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ + for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && + i < FEC_RESET_DELAY; i++) + udelay(1); + + if (i == FEC_RESET_DELAY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FEC timeout on graceful transmit stop\n", + dev->name); + /* + * Disable FEC. Let only MII interrupts. + */ + FW(fecp, imask, 0); + FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN); + + fs_cleanup_bds(dev); + + /* shut down FEC1? that's where the mii bus is */ + if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) { + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, ievent, FEC_ENET_MII); + FW(fecp, mii_speed, bus->fec.mii_speed); + } +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + immap_t *immap = fs_enet_immap; + u32 siel; + + /* SIU interrupt */ + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { + + siel = in_be32(&immap->im_siu_conf.sc_siel); + if ((irq & 1) == 0) + siel |= (0x80000000 >> irq); + else + siel &= ~(0x80000000 >> (irq & ~1)); + out_be32(&immap->im_siu_conf.sc_siel, siel); + } +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, r_des_active, 0x01000000); +} + +static void tx_kickstart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, x_des_active, 0x01000000); +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + return FR(fecp, ievent) & FR(fecp, imask); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, ievent, int_events); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events); +} + +int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(fec_t)) + return -EINVAL; + + memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t)); + + return 0; +} + +int get_regs_len(struct net_device *dev) +{ + return sizeof(fec_t); +} + +void tx_restart(struct net_device *dev) +{ + /* nothing */ +} + +/*************************************************************************/ + +const struct fs_ops fs_fec_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; + +/***********************************************************************/ + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + fec_t *fecp = bus->fec.fecp; + int i, ret = -1; + + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) { + FW(fecp, ievent, FEC_ENET_MII); + ret = FR(fecp, mii_data) & 0xffff; + } + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value) +{ + fec_t *fecp = bus->fec.fecp; + int i; + + /* this must never happen */ + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) + FW(fecp, ievent, FEC_ENET_MII); +} + +int fs_mii_fec_init(struct fs_enet_mii_bus *bus) +{ + bd_t *bd = (bd_t *)__res; + const struct fs_mii_bus_info *bi = bus->bus_info; + fec_t *fecp; + + if (bi->id != 0) + return -1; + + bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec; + bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) + & 0x3F) << 1; + + fecp = bus->fec.fecp; + + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, ievent, FEC_ENET_MII); + FW(fecp, mii_speed, bus->fec.mii_speed); + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c new file mode 100644 index 000000000000..d8c6e9cadcf5 --- /dev/null +++ b/drivers/net/fs_enet/mac-scc.c @@ -0,0 +1,524 @@ +/* + * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_8xx +#include +#include +#include +#include +#endif + +#include "fs_enet.h" + +/*************************************************/ + +#if defined(CONFIG_CPM1) +/* for a 8xx __raw_xxx's are sufficient */ +#define __fs_out32(addr, x) __raw_writel(x, addr) +#define __fs_out16(addr, x) __raw_writew(x, addr) +#define __fs_out8(addr, x) __raw_writeb(x, addr) +#define __fs_in32(addr) __raw_readl(addr) +#define __fs_in16(addr) __raw_readw(addr) +#define __fs_in8(addr) __raw_readb(addr) +#else +/* for others play it safe */ +#define __fs_out32(addr, x) out_be32(addr, x) +#define __fs_out16(addr, x) out_be16(addr, x) +#define __fs_in32(addr) in_be32(addr) +#define __fs_in16(addr) in_be16(addr) +#endif + +/* write, read, set bits, clear bits */ +#define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v)) +#define R32(_p, _m) __fs_in32(&(_p)->_m) +#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) +#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) + +#define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v)) +#define R16(_p, _m) __fs_in16(&(_p)->_m) +#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) +#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) + +#define W8(_p, _m, _v) __fs_out8(&(_p)->_m, (_v)) +#define R8(_p, _m) __fs_in8(&(_p)->_m) +#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) +#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) + +#define SCC_MAX_MULTICAST_ADDRS 64 + +/* + * Delay to wait for SCC reset command to complete (in us) + */ +#define SCC_RESET_DELAY 50 +#define MAX_CR_CMD_LOOPS 10000 + +static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) +{ + cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; + u32 v, ch; + int i = 0; + + ch = fep->scc.idx << 2; + v = mk_cr_cmd(ch, op); + W16(cpmp, cp_cpcr, v | CPM_CR_FLG); + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) + if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) + break; + + if (i >= MAX_CR_CMD_LOOPS) { + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; + } + return 0; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq_byname(pdev, "interrupt"); + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + fep->scc.sccp = (void *)r->start; + + if (fep->scc.sccp == NULL) + return -EINVAL; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"); + fep->scc.ep = (void *)r->start; + + if (fep->scc.ep == NULL) + return -EINVAL; + + return 0; +} + +#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB) +#define SCC_RX_EVENT (SCCE_ENET_RXF) +#define SCC_TX_EVENT (SCCE_ENET_TXB) +#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->scc.idx = fs_get_scc_index(fpi->fs_no); + if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ + return -EINVAL; + + do_pd_setup(fep); + + fep->scc.hthi = 0; + fep->scc.htlo = 0; + + fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; + fep->ev_rx = SCC_RX_EVENT; + fep->ev_tx = SCC_TX_EVENT; + fep->ev_err = SCC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), 8); + if (IS_DPERR(fep->ring_mem_addr)) + return -ENOMEM; + + fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr); + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->ring_base) + cpm_dpfree(fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + S16(sccp, scc_psmr, SCC_PSMR_PRO); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_enet_t *ep = fep->scc.ep; + + W16(ep, sen_gaddr1, 0); + W16(ep, sen_gaddr2, 0); + W16(ep, sen_gaddr3, 0); + W16(ep, sen_gaddr4, 0); +} + +static void set_multicast_one(struct net_device *dev, const u8 * mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_enet_t *ep = fep->scc.ep; + u16 taddrh, taddrm, taddrl; + + taddrh = ((u16) mac[5] << 8) | mac[4]; + taddrm = ((u16) mac[3] << 8) | mac[2]; + taddrl = ((u16) mac[1] << 8) | mac[0]; + + W16(ep, sen_taddrh, taddrh); + W16(ep, sen_taddrm, taddrm); + W16(ep, sen_taddrl, taddrl); + scc_cr_cmd(fep, CPM_CR_SET_GADDR); +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + scc_enet_t *ep = fep->scc.ep; + + /* clear promiscuous always */ + C16(sccp, scc_psmr, SCC_PSMR_PRO); + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > SCC_MAX_MULTICAST_ADDRS) { + + W16(ep, sen_gaddr1, 0xffff); + W16(ep, sen_gaddr2, 0xffff); + W16(ep, sen_gaddr3, 0xffff); + W16(ep, sen_gaddr4, 0xffff); + } +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +/* + * This function is called to start or restart the FEC during a link + * change. This only happens when switching between half and full + * duplex. + */ +static void restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + scc_enet_t *ep = fep->scc.ep; + const struct fs_platform_info *fpi = fep->fpi; + u16 paddrh, paddrm, paddrl; + const unsigned char *mac; + int i; + + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* clear everything (slow & steady does it) */ + for (i = 0; i < sizeof(*ep); i++) + __fs_out8((char *)ep + i, 0); + + /* point to bds */ + W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr); + W16(ep, sen_genscc.scc_tbase, + fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring); + + /* Initialize function code registers for big-endian. + */ + W8(ep, sen_genscc.scc_rfcr, SCC_EB); + W8(ep, sen_genscc.scc_tfcr, SCC_EB); + + /* Set maximum bytes per receive buffer. + * This appears to be an Ethernet frame size, not the buffer + * fragment size. It must be a multiple of four. + */ + W16(ep, sen_genscc.scc_mrblr, 0x5f0); + + /* Set CRC preset and mask. + */ + W32(ep, sen_cpres, 0xffffffff); + W32(ep, sen_cmask, 0xdebb20e3); + + W32(ep, sen_crcec, 0); /* CRC Error counter */ + W32(ep, sen_alec, 0); /* alignment error counter */ + W32(ep, sen_disfc, 0); /* discard frame counter */ + + W16(ep, sen_pads, 0x8888); /* Tx short frame pad character */ + W16(ep, sen_retlim, 15); /* Retry limit threshold */ + + W16(ep, sen_maxflr, 0x5ee); /* maximum frame length register */ + + W16(ep, sen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ + + W16(ep, sen_maxd1, 0x000005f0); /* maximum DMA1 length */ + W16(ep, sen_maxd2, 0x000005f0); /* maximum DMA2 length */ + + /* Clear hash tables. + */ + W16(ep, sen_gaddr1, 0); + W16(ep, sen_gaddr2, 0); + W16(ep, sen_gaddr3, 0); + W16(ep, sen_gaddr4, 0); + W16(ep, sen_iaddr1, 0); + W16(ep, sen_iaddr2, 0); + W16(ep, sen_iaddr3, 0); + W16(ep, sen_iaddr4, 0); + + /* set address + */ + mac = dev->dev_addr; + paddrh = ((u16) mac[5] << 8) | mac[4]; + paddrm = ((u16) mac[3] << 8) | mac[2]; + paddrl = ((u16) mac[1] << 8) | mac[0]; + + W16(ep, sen_paddrh, paddrh); + W16(ep, sen_paddrm, paddrm); + W16(ep, sen_paddrl, paddrl); + + W16(ep, sen_pper, 0); + W16(ep, sen_taddrl, 0); + W16(ep, sen_taddrm, 0); + W16(ep, sen_taddrh, 0); + + fs_init_bds(dev); + + scc_cr_cmd(fep, CPM_CR_INIT_TRX); + + W16(sccp, scc_scce, 0xffff); + + /* Enable interrupts we wish to service. + */ + W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); + + /* Set GSMR_H to enable all normal operating modes. + * Set GSMR_L to enable Ethernet to MC68160. + */ + W32(sccp, scc_gsmrh, 0); + W32(sccp, scc_gsmrl, + SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | + SCC_GSMRL_MODE_ENET); + + /* Set sync/delimiters. + */ + W16(sccp, scc_dsr, 0xd555); + + /* Set processing mode. Use Ethernet CRC, catch broadcast, and + * start frame search 22 bit times after RENA. + */ + W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22); + + /* Set full duplex mode if needed */ + if (fep->duplex) + S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); + + S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + int i; + + for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++) + udelay(1); + + if (i == SCC_RESET_DELAY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s SCC timeout on graceful transmit stop\n", + dev->name); + + W16(sccp, scc_sccm, 0); + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + fs_cleanup_bds(dev); +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + immap_t *immap = fs_enet_immap; + u32 siel; + + /* SIU interrupt */ + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { + + siel = in_be32(&immap->im_siu_conf.sc_siel); + if ((irq & 1) == 0) + siel |= (0x80000000 >> irq); + else + siel &= ~(0x80000000 >> (irq & ~1)); + out_be32(&immap->im_siu_conf.sc_siel, siel); + } +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + /* nothing */ +} + +static void tx_kickstart(struct net_device *dev) +{ + /* nothing */ +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + return (u32) R16(sccp, scc_scce); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + W16(sccp, scc_scce, int_events & 0xffff); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events); +} + +static int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t)) + return -EINVAL; + + memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t)); + p = (char *)p + sizeof(scc_t); + + memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t)); + + return 0; +} + +static int get_regs_len(struct net_device *dev) +{ + return sizeof(scc_t) + sizeof(scc_enet_t); +} + +static void tx_restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + scc_cr_cmd(fep, CPM_CR_RESTART_TX); +} + +/*************************************************************************/ + +const struct fs_ops fs_scc_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c new file mode 100644 index 000000000000..24a5e2e23d18 --- /dev/null +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -0,0 +1,405 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +#ifdef CONFIG_8xx +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) +{ + immap_t *im = (immap_t *)fs_enet_immap; + void *dir, *dat, *ppar; + int adv; + u8 msk; + + switch (port) { + case fsiop_porta: + dir = &im->im_ioport.iop_padir; + dat = &im->im_ioport.iop_padat; + ppar = &im->im_ioport.iop_papar; + break; + + case fsiop_portb: + dir = &im->im_cpm.cp_pbdir; + dat = &im->im_cpm.cp_pbdat; + ppar = &im->im_cpm.cp_pbpar; + break; + + case fsiop_portc: + dir = &im->im_ioport.iop_pcdir; + dat = &im->im_ioport.iop_pcdat; + ppar = &im->im_ioport.iop_pcpar; + break; + + case fsiop_portd: + dir = &im->im_ioport.iop_pddir; + dat = &im->im_ioport.iop_pddat; + ppar = &im->im_ioport.iop_pdpar; + break; + + case fsiop_porte: + dir = &im->im_cpm.cp_pedir; + dat = &im->im_cpm.cp_pedat; + ppar = &im->im_cpm.cp_pepar; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } + + adv = bit >> 3; + dir = (char *)dir + adv; + dat = (char *)dat + adv; + ppar = (char *)ppar + adv; + + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + + *dirp = dir; + *datp = dat; + *mskp = msk; + + return 0; +} +#endif + +#ifdef CONFIG_8260 +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) +{ + iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport; + void *dir, *dat, *ppar; + int adv; + u8 msk; + + switch (port) { + case fsiop_porta: + dir = &io->iop_pdira; + dat = &io->iop_pdata; + ppar = &io->iop_ppara; + break; + + case fsiop_portb: + dir = &io->iop_pdirb; + dat = &io->iop_pdatb; + ppar = &io->iop_pparb; + break; + + case fsiop_portc: + dir = &io->iop_pdirc; + dat = &io->iop_pdatc; + ppar = &io->iop_pparc; + break; + + case fsiop_portd: + dir = &io->iop_pdird; + dat = &io->iop_pdatd; + ppar = &io->iop_ppard; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } + + adv = bit >> 3; + dir = (char *)dir + adv; + dat = (char *)dat + adv; + ppar = (char *)ppar + adv; + + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + + *dirp = dir; + *datp = dat; + *mskp = msk; + + return 0; +} +#endif + +static inline void bb_set(u8 *p, u8 m) +{ + out_8(p, in_8(p) | m); +} + +static inline void bb_clr(u8 *p, u8 m) +{ + out_8(p, in_8(p) & ~m); +} + +static inline int bb_read(u8 *p, u8 m) +{ + return (in_8(p) & m) != 0; +} + +static inline void mdio_active(struct fs_enet_mii_bus *bus) +{ + bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); +} + +static inline void mdio_tristate(struct fs_enet_mii_bus *bus) +{ + bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); +} + +static inline int mdio_read(struct fs_enet_mii_bus *bus) +{ + return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); +} + +static inline void mdio(struct fs_enet_mii_bus *bus, int what) +{ + if (what) + bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); + else + bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); +} + +static inline void mdc(struct fs_enet_mii_bus *bus, int what) +{ + if (what) + bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); + else + bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); +} + +static inline void mii_delay(struct fs_enet_mii_bus *bus) +{ + udelay(bus->bus_info->i.bitbang.delay); +} + +/* Utility to send the preamble, address, and register (common to read and write). */ +static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg) +{ + int j; + + /* + * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. + * The IEEE spec says this is a PHY optional requirement. The AMD + * 79C874 requires one after power up and one after a MII communications + * error. This means that we are doing more preambles than we need, + * but it is safer and will be much more robust. + */ + + mdio_active(bus); + mdio(bus, 1); + for (j = 0; j < 32; j++) { + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + } + + /* send the start bit (01) and the read opcode (10) or write (10) */ + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, !read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* send the PHY address */ + for (j = 0; j < 5; j++) { + mdc(bus, 0); + mdio(bus, (addr & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + addr <<= 1; + } + + /* send the register address */ + for (j = 0; j < 5; j++) { + mdc(bus, 0); + mdio(bus, (reg & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + reg <<= 1; + } +} + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + u16 rdreg; + int ret, j; + u8 addr = phy_id & 0xff; + u8 reg = location & 0xff; + + bitbang_pre(bus, 1, addr, reg); + + /* tri-state our MDIO I/O pin so we can read */ + mdc(bus, 0); + mdio_tristate(bus); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* check the turnaround bit: the PHY should be driving it to zero */ + if (mdio_read(bus) != 0) { + /* PHY didn't drive TA low */ + for (j = 0; j < 32; j++) { + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + } + ret = -1; + goto out; + } + + mdc(bus, 0); + mii_delay(bus); + + /* read 16 bits of register data, MSB first */ + rdreg = 0; + for (j = 0; j < 16; j++) { + mdc(bus, 1); + mii_delay(bus); + rdreg <<= 1; + rdreg |= mdio_read(bus); + mdc(bus, 0); + mii_delay(bus); + } + + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + ret = rdreg; +out: + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) +{ + int j; + u8 addr = phy_id & 0xff; + u8 reg = location & 0xff; + u16 value = val & 0xffff; + + bitbang_pre(bus, 0, addr, reg); + + /* send the turnaround (10) */ + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* write 16 bits of register data, MSB first */ + for (j = 0; j < 16; j++) { + mdc(bus, 0); + mdio(bus, (value & 0x8000) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + value <<= 1; + } + + /* + * Tri-state the MDIO line. + */ + mdio_tristate(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); +} + +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus) +{ + const struct fs_mii_bus_info *bi = bus->bus_info; + int r; + + r = bitbang_prep_bit(&bus->bitbang.mdio_dir, + &bus->bitbang.mdio_dat, + &bus->bitbang.mdio_msk, + bi->i.bitbang.mdio_port, + bi->i.bitbang.mdio_bit); + if (r != 0) + return r; + + r = bitbang_prep_bit(&bus->bitbang.mdc_dir, + &bus->bitbang.mdc_dat, + &bus->bitbang.mdc_msk, + bi->i.bitbang.mdc_port, + bi->i.bitbang.mdc_bit); + if (r != 0) + return r; + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c new file mode 100644 index 000000000000..b3e192d612e5 --- /dev/null +++ b/drivers/net/fs_enet/mii-fixed.c @@ -0,0 +1,92 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +static const u16 mii_regs[7] = { + 0x3100, + 0x786d, + 0x0fff, + 0x0fff, + 0x01e1, + 0x45e1, + 0x0003, +}; + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + int ret = 0; + + if ((unsigned int)location >= ARRAY_SIZE(mii_regs)) + return -1; + + if (location != 5) + ret = mii_regs[location]; + else + ret = bus->fixed.lpa; + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) +{ + /* do nothing */ +} + +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus) +{ + const struct fs_mii_bus_info *bi = bus->bus_info; + + bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */ + + /* if speed is fixed at 10Mb, remove 100Mb modes */ + if (bi->i.fixed.speed == 10) + bus->fixed.lpa &= ~LPA_100; + + /* if duplex is half, remove full duplex modes */ + if (bi->i.fixed.duplex == 0) + bus->fixed.lpa &= ~LPA_DUPLEX; + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h new file mode 100644 index 000000000000..bef23bbf8690 --- /dev/null +++ b/include/linux/fs_enet_pd.h @@ -0,0 +1,136 @@ +/* + * Platform information definitions for the + * universal Freescale Ethernet driver. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef FS_ENET_PD_H +#define FS_ENET_PD_H + +#include +#include + +#define FS_ENET_NAME "fs_enet" + +enum fs_id { + fsid_fec1, + fsid_fec2, + fsid_fcc1, + fsid_fcc2, + fsid_fcc3, + fsid_scc1, + fsid_scc2, + fsid_scc3, + fsid_scc4, +}; + +#define FS_MAX_INDEX 9 + +static inline int fs_get_fec_index(enum fs_id id) +{ + if (id >= fsid_fec1 && id <= fsid_fec2) + return id - fsid_fec1; + return -1; +} + +static inline int fs_get_fcc_index(enum fs_id id) +{ + if (id >= fsid_fcc1 && id <= fsid_fcc3) + return id - fsid_fcc1; + return -1; +} + +static inline int fs_get_scc_index(enum fs_id id) +{ + if (id >= fsid_scc1 && id <= fsid_scc4) + return id - fsid_scc1; + return -1; +} + +enum fs_mii_method { + fsmii_fixed, + fsmii_fec, + fsmii_bitbang, +}; + +enum fs_ioport { + fsiop_porta, + fsiop_portb, + fsiop_portc, + fsiop_portd, + fsiop_porte, +}; + +struct fs_mii_bus_info { + int method; /* mii method */ + int id; /* the id of the mii_bus */ + int disable_aneg; /* if the controller needs to negothiate speed & duplex */ + int lpa; /* the default board-specific vallues will be applied otherwise */ + + union { + struct { + int duplex; + int speed; + } fixed; + + struct { + /* nothing */ + } fec; + + struct { + /* nothing */ + } scc; + + struct { + int mdio_port; /* port & bit for MDIO */ + int mdio_bit; + int mdc_port; /* port & bit for MDC */ + int mdc_bit; + int delay; /* delay in us */ + } bitbang; + } i; +}; + +struct fs_platform_info { + + void(*init_ioports)(void); + /* device specific information */ + int fs_no; /* controller index */ + + u32 cp_page; /* CPM page */ + u32 cp_block; /* CPM sblock */ + + u32 clk_trx; /* some stuff for pins & mux configuration*/ + u32 clk_route; + u32 clk_mask; + + u32 mem_offset; + u32 dpram_offset; + u32 fcc_regs_c; + + u32 device_flags; + + int phy_addr; /* the phy address (-1 no phy) */ + int phy_irq; /* the phy irq (if it exists) */ + + const struct fs_mii_bus_info *bus_info; + + int rx_ring, tx_ring; /* number of buffers on rx */ + __u8 macaddr[6]; /* mac address */ + int rx_copybreak; /* limit we copy small frames */ + int use_napi; /* use NAPI */ + int napi_weight; /* NAPI weight */ + + int use_rmii; /* use RMII mode */ +}; + +#endif From 19c1f3ca4272008a256cc153f3e3feb097799070 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 28 Oct 2005 21:37:29 +0100 Subject: [PATCH 0682/1940] [MMC] wbsd suspend support Proper handling of suspend/resume in the wbsd driver. Signed-off-by: Pierre Ossman Signed-off-by: Russell King --- drivers/mmc/wbsd.c | 119 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 28 deletions(-) diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 25f7ce7b3bc0..3ace875decc4 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -1033,13 +1033,16 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) } else { - setup &= ~WBSD_DAT3_H; + if (setup & WBSD_DAT3_H) + { + setup &= ~WBSD_DAT3_H; - /* - * We cannot resume card detection immediatly - * because of capacitance and delays in the chip. - */ - mod_timer(&host->ignore_timer, jiffies + HZ/100); + /* + * We cannot resume card detection immediatly + * because of capacitance and delays in the chip. + */ + mod_timer(&host->ignore_timer, jiffies + HZ/100); + } } wbsd_write_index(host, WBSD_IDX_SETUP, setup); @@ -1461,8 +1464,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host) { id = 0xFFFF; - outb(unlock_codes[j], config_ports[i]); - outb(unlock_codes[j], config_ports[i]); + host->config = config_ports[i]; + host->unlock_code = unlock_codes[j]; + + wbsd_unlock_config(host); outb(WBSD_CONF_ID_HI, config_ports[i]); id = inb(config_ports[i] + 1) << 8; @@ -1470,13 +1475,13 @@ static int __devinit wbsd_scan(struct wbsd_host* host) outb(WBSD_CONF_ID_LO, config_ports[i]); id |= inb(config_ports[i] + 1); + wbsd_lock_config(host); + for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) { if (id == valid_ids[k]) { host->chip_id = id; - host->config = config_ports[i]; - host->unlock_code = unlock_codes[i]; return 0; } @@ -1487,13 +1492,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host) DBG("Unknown hardware (id %x) found at %x\n", id, config_ports[i]); } - - outb(LOCK_CODE, config_ports[i]); } release_region(config_ports[i], 2); } + host->config = 0; + host->unlock_code = 0; + return -ENODEV; } @@ -1699,8 +1705,10 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host) * Configure the resources the chip should use. */ -static void __devinit wbsd_chip_config(struct wbsd_host* host) +static void wbsd_chip_config(struct wbsd_host* host) { + wbsd_unlock_config(host); + /* * Reset the chip. */ @@ -1733,16 +1741,20 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host) */ wbsd_write_config(host, WBSD_CONF_ENABLE, 1); wbsd_write_config(host, WBSD_CONF_POWER, 0x20); + + wbsd_lock_config(host); } /* * Check that configured resources are correct. */ -static int __devinit wbsd_chip_validate(struct wbsd_host* host) +static int wbsd_chip_validate(struct wbsd_host* host) { int base, irq, dma; + wbsd_unlock_config(host); + /* * Select SD/MMC function. */ @@ -1758,6 +1770,8 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host) dma = wbsd_read_config(host, WBSD_CONF_DRQ); + wbsd_lock_config(host); + /* * Validate against given configuration. */ @@ -1771,6 +1785,20 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host) return 1; } +/* + * Powers down the SD function + */ + +static void wbsd_chip_poweroff(struct wbsd_host* host) +{ + wbsd_unlock_config(host); + + wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); + wbsd_write_config(host, WBSD_CONF_ENABLE, 0); + + wbsd_lock_config(host); +} + /*****************************************************************************\ * * * Devices setup and shutdown * @@ -1844,7 +1872,11 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, */ #ifdef CONFIG_PM if (host->config) + { + wbsd_unlock_config(host); wbsd_write_config(host, WBSD_CONF_PME, 0xA0); + wbsd_lock_config(host); + } #endif /* * Allow device to initialise itself properly. @@ -1885,16 +1917,11 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp) mmc_remove_host(mmc); + /* + * Power down the SD/MMC function. + */ if (!pnp) - { - /* - * Power down the SD/MMC function. - */ - wbsd_unlock_config(host); - wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); - wbsd_write_config(host, WBSD_CONF_ENABLE, 0); - wbsd_lock_config(host); - } + wbsd_chip_poweroff(host); wbsd_release_resources(host); @@ -1955,23 +1982,59 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) */ #ifdef CONFIG_PM + static int wbsd_suspend(struct device *dev, pm_message_t state) { - DBGF("Not yet supported\n"); + struct mmc_host *mmc = dev_get_drvdata(dev); + struct wbsd_host *host; + int ret; + + if (!mmc) + return 0; + + DBG("Suspending...\n"); + + ret = mmc_suspend_host(mmc, state); + if (!ret) + return ret; + + host = mmc_priv(mmc); + + wbsd_chip_poweroff(host); return 0; } static int wbsd_resume(struct device *dev) { - DBGF("Not yet supported\n"); + struct mmc_host *mmc = dev_get_drvdata(dev); + struct wbsd_host *host; - return 0; + if (!mmc) + return 0; + + DBG("Resuming...\n"); + + host = mmc_priv(mmc); + + wbsd_chip_config(host); + + /* + * Allow device to initialise itself properly. + */ + mdelay(5); + + wbsd_init_device(host); + + return mmc_resume_host(mmc); } -#else + +#else /* CONFIG_PM */ + #define wbsd_suspend NULL #define wbsd_resume NULL -#endif + +#endif /* CONFIG_PM */ static struct platform_device *wbsd_device; From 89358f90ab6f6657d386e77e19c805d7ab88694f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 28 Oct 2005 16:38:02 -0400 Subject: [PATCH 0683/1940] [netdrvr b44] include linux/dma-mapping.h to eliminate warning --- drivers/net/b44.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 225d14fd9239..ab845076ff9f 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include From b71b95efa5abca33e1bfb85d55162c7f99f54c23 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Fri, 28 Oct 2005 12:23:47 +0200 Subject: [PATCH 0684/1940] [PATCH] sundance: fix DFE-580TX Tx Underrun Under heavy PCI bus load, ports of the DFE-580TX 4-ethernet port board stop working, with currently no other cure than a powercycle. Here is a tested fix. By the way, I also fixed some references and attribution. Signed-off-by: Philippe De Muyter Signed-off-by: Jeff Garzik --- drivers/net/sundance.c | 62 ++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 5de0554fd7c6..0ab9c38b4a34 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -80,7 +80,7 @@ I/O access could affect performance in ARM-based system - Add Linux software VLAN support - Version LK1.08 (D-Link): + Version LK1.08 (Philippe De Muyter phdm@macqel.be): - Fix bug of custom mac address (StationAddr register only accept word write) @@ -91,11 +91,14 @@ Version LK1.09a (ICPlus): - Add the delay time in reading the contents of EEPROM + Version LK1.10 (Philippe De Muyter phdm@macqel.be): + - Make 'unblock interface after Tx underrun' work + */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.09a" -#define DRV_RELDATE "10-Jul-2003" +#define DRV_VERSION "1.01+LK1.10" +#define DRV_RELDATE "28-Oct-2005" /* The user-configurable values. @@ -263,8 +266,10 @@ IV. Notes IVb. References The Sundance ST201 datasheet, preliminary version. -http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html -http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html +The Kendin KS8723 datasheet, preliminary version. +The ICplus IP100 datasheet, preliminary version. +http://www.scyld.com/expert/100mbps.html +http://www.scyld.com/expert/NWay.html IVc. Errata @@ -500,6 +505,25 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int netdev_close(struct net_device *dev); static struct ethtool_ops ethtool_ops; +static void sundance_reset(struct net_device *dev, unsigned long reset_cmd) +{ + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base + ASICCtrl; + int countdown; + + /* ST201 documentation states ASICCtrl is a 32bit register */ + iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr); + /* ST201 documentation states reset can take up to 1 ms */ + countdown = 10 + 1; + while (ioread32 (ioaddr) & (ResetBusy << 16)) { + if (--countdown == 0) { + printk(KERN_WARNING "%s : reset not completed !!\n", dev->name); + break; + } + udelay(100); + } +} + static int __devinit sundance_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1190,23 +1214,33 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs ("%s: Transmit status is %2.2x.\n", dev->name, tx_status); if (tx_status & 0x1e) { + if (netif_msg_tx_err(np)) + printk("%s: Transmit error status %4.4x.\n", + dev->name, tx_status); np->stats.tx_errors++; if (tx_status & 0x10) np->stats.tx_fifo_errors++; if (tx_status & 0x08) np->stats.collisions++; + if (tx_status & 0x04) + np->stats.tx_fifo_errors++; if (tx_status & 0x02) np->stats.tx_window_errors++; - /* This reset has not been verified!. */ - if (tx_status & 0x10) { /* Reset the Tx. */ - np->stats.tx_fifo_errors++; - spin_lock(&np->lock); - reset_tx(dev); - spin_unlock(&np->lock); + /* + ** This reset has been verified on + ** DFE-580TX boards ! phdm@macqel.be. + */ + if (tx_status & 0x10) { /* TxUnderrun */ + unsigned short txthreshold; + + txthreshold = ioread16 (ioaddr + TxStartThresh); + /* Restart Tx FIFO and transmitter */ + sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16); + iowrite16 (txthreshold, ioaddr + TxStartThresh); + /* No need to reset the Tx pointer here */ } - if (tx_status & 0x1e) /* Restart the Tx. */ - iowrite16 (TxEnable, - ioaddr + MACCtrl1); + /* Restart the Tx. */ + iowrite16 (TxEnable, ioaddr + MACCtrl1); } /* Yup, this is a documentation bug. It cost me *hours*. */ iowrite16 (0, ioaddr + TxStatus); From 37448f7d39717db7c1098c1a88b9074694c69797 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Mon, 10 Oct 2005 16:58:14 -0700 Subject: [PATCH 0685/1940] [PATCH] New PowerPC 4xx on-chip ethernet controller driver This patch replaces current PowerPC 4xx EMAC driver with new, re-written from the scratch version. This patch is quite big (~234K) because there is virtualy 0% of common code between old and new version. New driver uses NAPI, it solves stability problems under heavy packet load and low memory, corrects chip register access and fixes numerous small bugs I don't even remember now. This patch has been tested on all supported in 2.6 PPC 4xx boards. It's been used in production for almost a year now on custom 4xx hardware. PPC32 specific parts are already upstream. Patch was acked by the current EMAC driver maintainer (Matt Porter). I will be maintaining this new version. Signed-off-by: Eugene Surovegin -- Kconfig | 72 ibm_emac/Makefile | 13 ibm_emac/ibm_emac.h | 418 +++-- ibm_emac/ibm_emac_core.c | 3414 ++++++++++++++++++++++++---------------------- ibm_emac/ibm_emac_core.h | 313 ++-- ibm_emac/ibm_emac_debug.c | 377 ++--- ibm_emac/ibm_emac_debug.h | 63 ibm_emac/ibm_emac_mal.c | 674 +++++---- ibm_emac/ibm_emac_mal.h | 336 +++- ibm_emac/ibm_emac_phy.c | 335 ++-- ibm_emac/ibm_emac_phy.h | 105 - ibm_emac/ibm_emac_rgmii.c | 201 ++ ibm_emac/ibm_emac_rgmii.h | 68 ibm_emac/ibm_emac_tah.c | 111 + ibm_emac/ibm_emac_tah.h | 96 - ibm_emac/ibm_emac_zmii.c | 255 +++ ibm_emac/ibm_emac_zmii.h | 114 - 17 files changed, 4114 insertions(+), 2851 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 72 +- drivers/net/ibm_emac/Makefile | 13 +- drivers/net/ibm_emac/ibm_emac.h | 408 +-- drivers/net/ibm_emac/ibm_emac_core.c | 3864 +++++++++++++------------ drivers/net/ibm_emac/ibm_emac_core.h | 293 +- drivers/net/ibm_emac/ibm_emac_debug.c | 377 ++- drivers/net/ibm_emac/ibm_emac_debug.h | 63 + drivers/net/ibm_emac/ibm_emac_mal.c | 686 +++-- drivers/net/ibm_emac/ibm_emac_mal.h | 330 ++- drivers/net/ibm_emac/ibm_emac_phy.c | 459 +-- drivers/net/ibm_emac/ibm_emac_phy.h | 105 +- drivers/net/ibm_emac/ibm_emac_rgmii.c | 201 ++ drivers/net/ibm_emac/ibm_emac_rgmii.h | 60 +- drivers/net/ibm_emac/ibm_emac_tah.c | 111 + drivers/net/ibm_emac/ibm_emac_tah.h | 96 +- drivers/net/ibm_emac/ibm_emac_zmii.c | 255 ++ drivers/net/ibm_emac/ibm_emac_zmii.h | 104 +- 17 files changed, 4380 insertions(+), 3117 deletions(-) create mode 100644 drivers/net/ibm_emac/ibm_emac_debug.h create mode 100644 drivers/net/ibm_emac/ibm_emac_rgmii.c create mode 100644 drivers/net/ibm_emac/ibm_emac_tah.c create mode 100644 drivers/net/ibm_emac/ibm_emac_zmii.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 27732fdeeea4..54ab70e7eff4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1163,38 +1163,74 @@ config IBMVETH be called ibmveth. config IBM_EMAC - bool "IBM PPC4xx EMAC driver support" + tristate "PowerPC 4xx on-chip Ethernet support" depends on 4xx - select CRC32 - ---help--- - This driver supports the IBM PPC4xx EMAC family of on-chip - Ethernet controllers. - -config IBM_EMAC_ERRMSG - bool "Verbose error messages" - depends on IBM_EMAC && BROKEN + help + This driver supports the PowerPC 4xx EMAC family of on-chip + Ethernet controllers. config IBM_EMAC_RXB int "Number of receive buffers" depends on IBM_EMAC - default "128" if IBM_EMAC4 - default "64" + default "128" config IBM_EMAC_TXB int "Number of transmit buffers" depends on IBM_EMAC - default "128" if IBM_EMAC4 - default "8" + default "64" -config IBM_EMAC_FGAP - int "Frame gap" +config IBM_EMAC_POLL_WEIGHT + int "MAL NAPI polling weight" depends on IBM_EMAC - default "8" + default "32" -config IBM_EMAC_SKBRES - int "Skb reserve amount" +config IBM_EMAC_RX_COPY_THRESHOLD + int "RX skb copy threshold (bytes)" + depends on IBM_EMAC + default "256" + +config IBM_EMAC_RX_SKB_HEADROOM + int "Additional RX skb headroom (bytes)" depends on IBM_EMAC default "0" + help + Additional receive skb headroom. Note, that driver + will always reserve at least 2 bytes to make IP header + aligned, so usualy there is no need to add any additional + headroom. + + If unsure, set to 0. + +config IBM_EMAC_PHY_RX_CLK_FIX + bool "PHY Rx clock workaround" + depends on IBM_EMAC && (405EP || 440GX || 440EP) + help + Enable this if EMAC attached to a PHY which doesn't generate + RX clock if there is no link, if this is the case, you will + see "TX disable timeout" or "RX disable timeout" in the system + log. + + If unsure, say N. + +config IBM_EMAC_DEBUG + bool "Debugging" + depends on IBM_EMAC + default n + +config IBM_EMAC_ZMII + bool + depends on IBM_EMAC && (NP405H || NP405L || 44x) + default y + +config IBM_EMAC_RGMII + bool + depends on IBM_EMAC && 440GX + default y + +config IBM_EMAC_TAH + bool + depends on IBM_EMAC && 440GX + default y config NET_PCI bool "EISA, VLB, PCI and on board controllers" diff --git a/drivers/net/ibm_emac/Makefile b/drivers/net/ibm_emac/Makefile index 7f583a333c24..f98ddf0e807a 100644 --- a/drivers/net/ibm_emac/Makefile +++ b/drivers/net/ibm_emac/Makefile @@ -1,12 +1,11 @@ # -# Makefile for the IBM PPC4xx EMAC controllers +# Makefile for the PowerPC 4xx on-chip ethernet driver # obj-$(CONFIG_IBM_EMAC) += ibm_emac.o -ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o - -# Only need this if you want to see additional debug messages -ifeq ($(CONFIG_IBM_EMAC_ERRMSG), y) -ibm_emac-objs += ibm_emac_debug.o -endif +ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o +ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o +ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o +ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o +ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h index 15d5a0e82862..28c476f28c20 100644 --- a/drivers/net/ibm_emac/ibm_emac.h +++ b/drivers/net/ibm_emac/ibm_emac.h @@ -1,110 +1,142 @@ /* - * ibm_emac.h + * drivers/net/ibm_emac/ibm_emac.h * + * Register definitions for PowerPC 4xx on-chip ethernet contoller * - * Armin Kuster akuster@mvista.com - * June, 2002 + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or * - * Copyright 2002 MontaVista Softare Inc. + * Based on original work by + * Matt Porter + * Armin Kuster + * Copyright 2002-2004 MontaVista Software 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 of the License, or (at your * option) any later version. + * */ +#ifndef __IBM_EMAC_H_ +#define __IBM_EMAC_H_ -#ifndef _IBM_EMAC_H_ -#define _IBM_EMAC_H_ -/* General defines needed for the driver */ +#include +#include -/* Emac */ -typedef struct emac_regs { - u32 em0mr0; - u32 em0mr1; - u32 em0tmr0; - u32 em0tmr1; - u32 em0rmr; - u32 em0isr; - u32 em0iser; - u32 em0iahr; - u32 em0ialr; - u32 em0vtpid; - u32 em0vtci; - u32 em0ptr; - u32 em0iaht1; - u32 em0iaht2; - u32 em0iaht3; - u32 em0iaht4; - u32 em0gaht1; - u32 em0gaht2; - u32 em0gaht3; - u32 em0gaht4; - u32 em0lsah; - u32 em0lsal; - u32 em0ipgvr; - u32 em0stacr; - u32 em0trtr; - u32 em0rwmr; -} emac_t; +/* This is a simple check to prevent use of this driver on non-tested SoCs */ +#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \ + !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \ + !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) +#error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK" +#endif -/* MODE REG 0 */ -#define EMAC_M0_RXI 0x80000000 -#define EMAC_M0_TXI 0x40000000 -#define EMAC_M0_SRST 0x20000000 -#define EMAC_M0_TXE 0x10000000 -#define EMAC_M0_RXE 0x08000000 -#define EMAC_M0_WKE 0x04000000 +/* EMAC registers Write Access rules */ +struct emac_regs { + u32 mr0; /* special */ + u32 mr1; /* Reset */ + u32 tmr0; /* special */ + u32 tmr1; /* special */ + u32 rmr; /* Reset */ + u32 isr; /* Always */ + u32 iser; /* Reset */ + u32 iahr; /* Reset, R, T */ + u32 ialr; /* Reset, R, T */ + u32 vtpid; /* Reset, R, T */ + u32 vtci; /* Reset, R, T */ + u32 ptr; /* Reset, T */ + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 lsah; + u32 lsal; + u32 ipgvr; /* Reset, T */ + u32 stacr; /* special */ + u32 trtr; /* special */ + u32 rwmr; /* Reset */ + u32 octx; + u32 ocrx; + u32 ipcr; +}; -/* MODE Reg 1 */ -#define EMAC_M1_FDE 0x80000000 -#define EMAC_M1_ILE 0x40000000 -#define EMAC_M1_VLE 0x20000000 -#define EMAC_M1_EIFC 0x10000000 -#define EMAC_M1_APP 0x08000000 -#define EMAC_M1_AEMI 0x02000000 -#define EMAC_M1_IST 0x01000000 -#define EMAC_M1_MF_1000GPCS 0x00c00000 /* Internal GPCS */ -#define EMAC_M1_MF_1000MBPS 0x00800000 /* External GPCS */ -#define EMAC_M1_MF_100MBPS 0x00400000 -#define EMAC_M1_RFS_16K 0x00280000 /* 000 for 512 byte */ -#define EMAC_M1_TR 0x00008000 -#ifdef CONFIG_IBM_EMAC4 -#define EMAC_M1_RFS_8K 0x00200000 -#define EMAC_M1_RFS_4K 0x00180000 -#define EMAC_M1_RFS_2K 0x00100000 -#define EMAC_M1_RFS_1K 0x00080000 -#define EMAC_M1_TX_FIFO_16K 0x00050000 /* 0's for 512 byte */ -#define EMAC_M1_TX_FIFO_8K 0x00040000 -#define EMAC_M1_TX_FIFO_4K 0x00030000 -#define EMAC_M1_TX_FIFO_2K 0x00020000 -#define EMAC_M1_TX_FIFO_1K 0x00010000 -#define EMAC_M1_TX_TR 0x00008000 -#define EMAC_M1_TX_MWSW 0x00001000 /* 0 wait for status */ -#define EMAC_M1_JUMBO_ENABLE 0x00000800 /* Upt to 9Kr status */ -#define EMAC_M1_OPB_CLK_66 0x00000008 /* 66Mhz */ -#define EMAC_M1_OPB_CLK_83 0x00000010 /* 83Mhz */ -#define EMAC_M1_OPB_CLK_100 0x00000018 /* 100Mhz */ -#define EMAC_M1_OPB_CLK_100P 0x00000020 /* 100Mhz+ */ -#else /* CONFIG_IBM_EMAC4 */ -#define EMAC_M1_RFS_4K 0x00300000 /* ~4k for 512 byte */ -#define EMAC_M1_RFS_2K 0x00200000 -#define EMAC_M1_RFS_1K 0x00100000 -#define EMAC_M1_TX_FIFO_2K 0x00080000 /* 0's for 512 byte */ -#define EMAC_M1_TX_FIFO_1K 0x00040000 -#define EMAC_M1_TR0_DEPEND 0x00010000 /* 0'x for single packet */ -#define EMAC_M1_TR1_DEPEND 0x00004000 -#define EMAC_M1_TR1_MULTI 0x00002000 -#define EMAC_M1_JUMBO_ENABLE 0x00001000 -#endif /* CONFIG_IBM_EMAC4 */ -#define EMAC_M1_BASE (EMAC_M1_TX_FIFO_2K | \ - EMAC_M1_APP | \ - EMAC_M1_TR | EMAC_M1_VLE) +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_ETHTOOL_REGS_VER 0 +#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32)) +#else +#define EMAC_ETHTOOL_REGS_VER 1 +#define EMAC_ETHTOOL_REGS_SIZE sizeof(struct emac_regs) +#endif -/* Transmit Mode Register 0 */ -#define EMAC_TMR0_GNP0 0x80000000 -#define EMAC_TMR0_GNP1 0x40000000 -#define EMAC_TMR0_GNPD 0x20000000 -#define EMAC_TMR0_FC 0x10000000 +/* EMACx_MR0 */ +#define EMAC_MR0_RXI 0x80000000 +#define EMAC_MR0_TXI 0x40000000 +#define EMAC_MR0_SRST 0x20000000 +#define EMAC_MR0_TXE 0x10000000 +#define EMAC_MR0_RXE 0x08000000 +#define EMAC_MR0_WKE 0x04000000 + +/* EMACx_MR1 */ +#define EMAC_MR1_FDE 0x80000000 +#define EMAC_MR1_ILE 0x40000000 +#define EMAC_MR1_VLE 0x20000000 +#define EMAC_MR1_EIFC 0x10000000 +#define EMAC_MR1_APP 0x08000000 +#define EMAC_MR1_IST 0x01000000 + +#define EMAC_MR1_MF_MASK 0x00c00000 +#define EMAC_MR1_MF_10 0x00000000 +#define EMAC_MR1_MF_100 0x00400000 +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_MR1_MF_1000 0x00000000 +#define EMAC_MR1_MF_1000GPCS 0x00000000 +#define EMAC_MR1_MF_IPPA(id) 0x00000000 +#else +#define EMAC_MR1_MF_1000 0x00800000 +#define EMAC_MR1_MF_1000GPCS 0x00c00000 +#define EMAC_MR1_MF_IPPA(id) (((id) & 0x1f) << 6) +#endif + +#define EMAC_TX_FIFO_SIZE 2048 + +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_MR1_RFS_4K 0x00300000 +#define EMAC_MR1_RFS_16K 0x00000000 +#define EMAC_RX_FIFO_SIZE(gige) 4096 +#define EMAC_MR1_TFS_2K 0x00080000 +#define EMAC_MR1_TR0_MULT 0x00008000 +#define EMAC_MR1_JPSM 0x00000000 +#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT) +#else +#define EMAC_MR1_RFS_4K 0x00180000 +#define EMAC_MR1_RFS_16K 0x00280000 +#define EMAC_RX_FIFO_SIZE(gige) ((gige) ? 16384 : 4096) +#define EMAC_MR1_TFS_2K 0x00020000 +#define EMAC_MR1_TR 0x00008000 +#define EMAC_MR1_MWSW_001 0x00001000 +#define EMAC_MR1_JPSM 0x00000800 +#define EMAC_MR1_OBCI_MASK 0x00000038 +#define EMAC_MR1_OBCI_50 0x00000000 +#define EMAC_MR1_OBCI_66 0x00000008 +#define EMAC_MR1_OBCI_83 0x00000010 +#define EMAC_MR1_OBCI_100 0x00000018 +#define EMAC_MR1_OBCI_100P 0x00000020 +#define EMAC_MR1_OBCI(freq) ((freq) <= 50 ? EMAC_MR1_OBCI_50 : \ + (freq) <= 66 ? EMAC_MR1_OBCI_66 : \ + (freq) <= 83 ? EMAC_MR1_OBCI_83 : \ + (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P) +#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \ + EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb)) +#endif + +/* EMACx_TMR0 */ +#define EMAC_TMR0_GNP 0x80000000 +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_TMR0_DEFAULT 0x00000000 +#else #define EMAC_TMR0_TFAE_2_32 0x00000001 #define EMAC_TMR0_TFAE_4_64 0x00000002 #define EMAC_TMR0_TFAE_8_128 0x00000003 @@ -112,14 +144,36 @@ typedef struct emac_regs { #define EMAC_TMR0_TFAE_32_512 0x00000005 #define EMAC_TMR0_TFAE_64_1024 0x00000006 #define EMAC_TMR0_TFAE_128_2048 0x00000007 +#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32 +#endif +#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT) -/* Receive Mode Register */ +/* EMACx_TMR1 */ + +/* IBM manuals are not very clear here. + * This is my interpretation of how things are. --ebs + */ +#if defined(CONFIG_40x) +#define EMAC_FIFO_ENTRY_SIZE 8 +#define EMAC_MAL_BURST_SIZE (16 * 4) +#else +#define EMAC_FIFO_ENTRY_SIZE 16 +#define EMAC_MAL_BURST_SIZE (64 * 4) +#endif + +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0xff) << 16)) +#else +#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0x3ff) << 14)) +#endif + +/* EMACx_RMR */ #define EMAC_RMR_SP 0x80000000 #define EMAC_RMR_SFCS 0x40000000 -#define EMAC_RMR_ARRP 0x20000000 -#define EMAC_RMR_ARP 0x10000000 -#define EMAC_RMR_AROP 0x08000000 -#define EMAC_RMR_ARPI 0x04000000 +#define EMAC_RMR_RRP 0x20000000 +#define EMAC_RMR_RFP 0x10000000 +#define EMAC_RMR_ROP 0x08000000 +#define EMAC_RMR_RPIR 0x04000000 #define EMAC_RMR_PPP 0x02000000 #define EMAC_RMR_PME 0x01000000 #define EMAC_RMR_PMME 0x00800000 @@ -127,6 +181,9 @@ typedef struct emac_regs { #define EMAC_RMR_MIAE 0x00200000 #define EMAC_RMR_BAE 0x00100000 #define EMAC_RMR_MAE 0x00080000 +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_RMR_BASE 0x00000000 +#else #define EMAC_RMR_RFAF_2_32 0x00000001 #define EMAC_RMR_RFAF_4_64 0x00000002 #define EMAC_RMR_RFAF_8_128 0x00000003 @@ -134,9 +191,21 @@ typedef struct emac_regs { #define EMAC_RMR_RFAF_32_512 0x00000005 #define EMAC_RMR_RFAF_64_1024 0x00000006 #define EMAC_RMR_RFAF_128_2048 0x00000007 -#define EMAC_RMR_BASE (EMAC_RMR_IAE | EMAC_RMR_BAE) +#define EMAC_RMR_BASE EMAC_RMR_RFAF_128_2048 +#endif -/* Interrupt Status & enable Regs */ +/* EMACx_ISR & EMACx_ISER */ +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_ISR_TXPE 0x00000000 +#define EMAC_ISR_RXPE 0x00000000 +#define EMAC_ISR_TXUE 0x00000000 +#define EMAC_ISR_RXOE 0x00000000 +#else +#define EMAC_ISR_TXPE 0x20000000 +#define EMAC_ISR_RXPE 0x10000000 +#define EMAC_ISR_TXUE 0x08000000 +#define EMAC_ISR_RXOE 0x04000000 +#endif #define EMAC_ISR_OVR 0x02000000 #define EMAC_ISR_PP 0x01000000 #define EMAC_ISR_BP 0x00800000 @@ -147,53 +216,62 @@ typedef struct emac_regs { #define EMAC_ISR_PTLE 0x00040000 #define EMAC_ISR_ORE 0x00020000 #define EMAC_ISR_IRE 0x00010000 -#define EMAC_ISR_DBDM 0x00000200 -#define EMAC_ISR_DB0 0x00000100 -#define EMAC_ISR_SE0 0x00000080 -#define EMAC_ISR_TE0 0x00000040 -#define EMAC_ISR_DB1 0x00000020 -#define EMAC_ISR_SE1 0x00000010 -#define EMAC_ISR_TE1 0x00000008 +#define EMAC_ISR_SQE 0x00000080 +#define EMAC_ISR_TE 0x00000040 #define EMAC_ISR_MOS 0x00000002 #define EMAC_ISR_MOF 0x00000001 -/* STA CONTROL REG */ +/* EMACx_STACR */ +#define EMAC_STACR_PHYD_MASK 0xffff +#define EMAC_STACR_PHYD_SHIFT 16 #define EMAC_STACR_OC 0x00008000 #define EMAC_STACR_PHYE 0x00004000 -#define EMAC_STACR_WRITE 0x00002000 -#define EMAC_STACR_READ 0x00001000 -#define EMAC_STACR_CLK_83MHZ 0x00000800 /* 0's for 50Mhz */ -#define EMAC_STACR_CLK_66MHZ 0x00000400 -#define EMAC_STACR_CLK_100MHZ 0x00000C00 +#define EMAC_STACR_STAC_MASK 0x00003000 +#define EMAC_STACR_STAC_READ 0x00001000 +#define EMAC_STACR_STAC_WRITE 0x00002000 +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_STACR_OPBC_MASK 0x00000C00 +#define EMAC_STACR_OPBC_50 0x00000000 +#define EMAC_STACR_OPBC_66 0x00000400 +#define EMAC_STACR_OPBC_83 0x00000800 +#define EMAC_STACR_OPBC_100 0x00000C00 +#define EMAC_STACR_OPBC(freq) ((freq) <= 50 ? EMAC_STACR_OPBC_50 : \ + (freq) <= 66 ? EMAC_STACR_OPBC_66 : \ + (freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100) +#define EMAC_STACR_BASE(opb) EMAC_STACR_OPBC(opb) +#else +#define EMAC_STACR_BASE(opb) 0x00000000 +#endif +#define EMAC_STACR_PCDA_MASK 0x1f +#define EMAC_STACR_PCDA_SHIFT 5 +#define EMAC_STACR_PRA_MASK 0x1f -/* Transmit Request Threshold Register */ -#define EMAC_TRTR_1600 0x18000000 /* 0's for 64 Bytes */ -#define EMAC_TRTR_1024 0x0f000000 -#define EMAC_TRTR_512 0x07000000 -#define EMAC_TRTR_256 0x03000000 -#define EMAC_TRTR_192 0x10000000 -#define EMAC_TRTR_128 0x01000000 +/* EMACx_TRTR */ +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_TRTR_SHIFT 27 +#else +#define EMAC_TRTR_SHIFT 24 +#endif +#define EMAC_TRTR(size) ((((size) >> 6) - 1) << EMAC_TRTR_SHIFT) +/* EMACx_RWMR */ +#if !defined(CONFIG_IBM_EMAC4) +#define EMAC_RWMR(l,h) (((l) << 23) | ( ((h) & 0x1ff) << 7)) +#else +#define EMAC_RWMR(l,h) (((l) << 22) | ( ((h) & 0x3ff) << 6)) +#endif + +/* EMAC specific TX descriptor control fields (write access) */ #define EMAC_TX_CTRL_GFCS 0x0200 #define EMAC_TX_CTRL_GP 0x0100 #define EMAC_TX_CTRL_ISA 0x0080 #define EMAC_TX_CTRL_RSA 0x0040 #define EMAC_TX_CTRL_IVT 0x0020 #define EMAC_TX_CTRL_RVT 0x0010 -#define EMAC_TX_CTRL_TAH_CSUM 0x000e /* TAH only */ -#define EMAC_TX_CTRL_TAH_SEG4 0x000a /* TAH only */ -#define EMAC_TX_CTRL_TAH_SEG3 0x0008 /* TAH only */ -#define EMAC_TX_CTRL_TAH_SEG2 0x0006 /* TAH only */ -#define EMAC_TX_CTRL_TAH_SEG1 0x0004 /* TAH only */ -#define EMAC_TX_CTRL_TAH_SEG0 0x0002 /* TAH only */ -#define EMAC_TX_CTRL_TAH_DIS 0x0000 /* TAH only */ +#define EMAC_TX_CTRL_TAH_CSUM 0x000e -#define EMAC_TX_CTRL_DFLT ( \ - MAL_TX_CTRL_INTR | EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP ) - -/* madmal transmit status / Control bits */ +/* EMAC specific TX descriptor status fields (read access) */ #define EMAC_TX_ST_BFCS 0x0200 -#define EMAC_TX_ST_BPP 0x0100 #define EMAC_TX_ST_LCS 0x0080 #define EMAC_TX_ST_ED 0x0040 #define EMAC_TX_ST_EC 0x0020 @@ -202,8 +280,16 @@ typedef struct emac_regs { #define EMAC_TX_ST_SC 0x0004 #define EMAC_TX_ST_UR 0x0002 #define EMAC_TX_ST_SQE 0x0001 +#if !defined(CONFIG_IBM_EMAC_TAH) +#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \ + EMAC_TX_ST_EC | EMAC_TX_ST_LC | \ + EMAC_TX_ST_MC | EMAC_TX_ST_UR)) +#else +#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \ + EMAC_TX_ST_EC | EMAC_TX_ST_LC)) +#endif -/* madmal receive status / Control bits */ +/* EMAC specific RX descriptor status fields (read access) */ #define EMAC_RX_ST_OE 0x0200 #define EMAC_RX_ST_PP 0x0100 #define EMAC_RX_ST_BP 0x0080 @@ -214,54 +300,10 @@ typedef struct emac_regs { #define EMAC_RX_ST_PTL 0x0004 #define EMAC_RX_ST_ORE 0x0002 #define EMAC_RX_ST_IRE 0x0001 -#define EMAC_BAD_RX_PACKET 0x02ff -#define EMAC_CSUM_VER_ERROR 0x0003 - -/* identify a bad rx packet dependent on emac features */ -#ifdef CONFIG_IBM_EMAC4 -#define EMAC_IS_BAD_RX_PACKET(desc) \ - (((desc & (EMAC_BAD_RX_PACKET & ~EMAC_CSUM_VER_ERROR)) || \ - ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_ORE) || \ - ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_IRE))) -#else -#define EMAC_IS_BAD_RX_PACKET(desc) \ - (desc & EMAC_BAD_RX_PACKET) -#endif - -/* SoC implementation specific EMAC register defaults */ -#if defined(CONFIG_440GP) -#define EMAC_RWMR_DEFAULT 0x80009000 -#define EMAC_TMR0_DEFAULT 0x00000000 -#define EMAC_TMR1_DEFAULT 0xf8640000 -#elif defined(CONFIG_440GX) -#define EMAC_RWMR_DEFAULT 0x1000a200 -#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32 -#define EMAC_TMR1_DEFAULT 0xa00f0000 -#elif defined(CONFIG_440SP) -#define EMAC_RWMR_DEFAULT 0x08002000 -#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_128_2048 -#define EMAC_TMR1_DEFAULT 0xf8200000 -#else -#define EMAC_RWMR_DEFAULT 0x0f002000 -#define EMAC_TMR0_DEFAULT 0x00000000 -#define EMAC_TMR1_DEFAULT 0x380f0000 -#endif /* CONFIG_440GP */ - -/* Revision specific EMAC register defaults */ -#ifdef CONFIG_IBM_EMAC4 -#define EMAC_M1_DEFAULT (EMAC_M1_BASE | \ - EMAC_M1_OPB_CLK_83 | \ - EMAC_M1_TX_MWSW) -#define EMAC_RMR_DEFAULT (EMAC_RMR_BASE | \ - EMAC_RMR_RFAF_128_2048) -#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP0 | \ - EMAC_TMR0_DEFAULT) -#define EMAC_TRTR_DEFAULT EMAC_TRTR_1024 -#else /* !CONFIG_IBM_EMAC4 */ -#define EMAC_M1_DEFAULT EMAC_M1_BASE -#define EMAC_RMR_DEFAULT EMAC_RMR_BASE -#define EMAC_TMR0_XMIT EMAC_TMR0_GNP0 -#define EMAC_TRTR_DEFAULT EMAC_TRTR_1600 -#endif /* CONFIG_IBM_EMAC4 */ - -#endif +#define EMAC_RX_TAH_BAD_CSUM 0x0003 +#define EMAC_BAD_RX_MASK (EMAC_RX_ST_OE | EMAC_RX_ST_BP | \ + EMAC_RX_ST_RP | EMAC_RX_ST_SE | \ + EMAC_RX_ST_AE | EMAC_RX_ST_BFCS | \ + EMAC_RX_ST_PTL | EMAC_RX_ST_ORE | \ + EMAC_RX_ST_IRE ) +#endif /* __IBM_EMAC_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 14e9b6315f20..943fbd1546ff 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -1,13 +1,14 @@ /* - * ibm_emac_core.c + * drivers/net/ibm_emac/ibm_emac_core.c * - * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC - * processors. - * - * (c) 2003 Benjamin Herrenschmidt + * Driver for PowerPC 4xx on-chip ethernet controller. + * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or * * Based on original work by - * + * Matt Porter + * (c) 2003 Benjamin Herrenschmidt * Armin Kuster * Johnnie Peters * @@ -15,29 +16,24 @@ * 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. - * TODO - * - Check for races in the "remove" code path - * - Add some Power Management to the MAC and the PHY - * - Audit remaining of non-rewritten code (--BenH) - * - Cleanup message display using msglevel mecanism - * - Address all errata - * - Audit all register update paths to ensure they - * are being written post soft reset if required. + * */ + +#include #include #include #include #include -#include -#include #include -#include -#include #include #include #include #include -#include +#include +#include +#include +#include +#include #include #include #include @@ -45,1691 +41,1893 @@ #include #include #include -#include #include #include -#include -#include -#include -#include - #include "ibm_emac_core.h" - -//#define MDIO_DEBUG(fmt) printk fmt -#define MDIO_DEBUG(fmt) - -//#define LINK_DEBUG(fmt) printk fmt -#define LINK_DEBUG(fmt) - -//#define PKT_DEBUG(fmt) printk fmt -#define PKT_DEBUG(fmt) - -#define DRV_NAME "emac" -#define DRV_VERSION "2.0" -#define DRV_AUTHOR "Benjamin Herrenschmidt " -#define DRV_DESC "IBM EMAC Ethernet driver" +#include "ibm_emac_debug.h" /* - * When mdio_idx >= 0, contains a list of emac ocp_devs - * that have had their initialization deferred until the - * common MDIO controller has been initialized. + * Lack of dma_unmap_???? calls is intentional. + * + * API-correct usage requires additional support state information to be + * maintained for every RX and TX buffer descriptor (BD). Unfortunately, due to + * EMAC design (e.g. TX buffer passed from network stack can be split into + * several BDs, dma_map_single/dma_map_page can be used to map particular BD), + * maintaining such information will add additional overhead. + * Current DMA API implementation for 4xx processors only ensures cache coherency + * and dma_unmap_???? routines are empty and are likely to stay this way. + * I decided to omit dma_unmap_??? calls because I don't want to add additional + * complexity just for the sake of following some abstract API, when it doesn't + * add any real benefit to the driver. I understand that this decision maybe + * controversial, but I really tried to make code API-correct and efficient + * at the same time and didn't come up with code I liked :(. --ebs */ -LIST_HEAD(emac_init_list); -MODULE_AUTHOR(DRV_AUTHOR); +#define DRV_NAME "emac" +#define DRV_VERSION "3.53" +#define DRV_DESC "PPC 4xx OCP EMAC driver" + MODULE_DESCRIPTION(DRV_DESC); +MODULE_AUTHOR + ("Eugene Surovegin or "); MODULE_LICENSE("GPL"); -static int skb_res = SKB_RES; -module_param(skb_res, int, 0444); -MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n" - "The 405 handles a misaligned IP header fine but\n" - "this can help if you are routing to a tunnel or a\n" - "device that needs aligned data. 0..2"); +/* minimum number of free TX descriptors required to wake up TX process */ +#define EMAC_TX_WAKEUP_THRESH (NUM_TX_BUFF / 4) -#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev)) - -static unsigned int rgmii_enable[] = { - RGMII_RTBI, - RGMII_RGMII, - RGMII_TBI, - RGMII_GMII -}; - -static unsigned int rgmii_speed_mask[] = { - RGMII_MII2_SPDMASK, - RGMII_MII3_SPDMASK -}; - -static unsigned int rgmii_speed100[] = { - RGMII_MII2_100MB, - RGMII_MII3_100MB -}; - -static unsigned int rgmii_speed1000[] = { - RGMII_MII2_1000MB, - RGMII_MII3_1000MB -}; - -#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev)) - -static unsigned int zmii_enable[][4] = { - {ZMII_SMII0, ZMII_RMII0, ZMII_MII0, - ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)}, - {ZMII_SMII1, ZMII_RMII1, ZMII_MII1, - ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)}, - {ZMII_SMII2, ZMII_RMII2, ZMII_MII2, - ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)}, - {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)} -}; - -static unsigned int mdi_enable[] = { - ZMII_MDI0, - ZMII_MDI1, - ZMII_MDI2, - ZMII_MDI3 -}; - -static unsigned int zmii_speed = 0x0; -static unsigned int zmii_speed100[] = { - ZMII_MII0_100MB, - ZMII_MII1_100MB, - ZMII_MII2_100MB, - ZMII_MII3_100MB -}; +/* If packet size is less than this number, we allocate small skb and copy packet + * contents into it instead of just sending original big skb up + */ +#define EMAC_RX_COPY_THRESH CONFIG_IBM_EMAC_RX_COPY_THRESHOLD /* Since multiple EMACs share MDIO lines in various ways, we need * to avoid re-using the same PHY ID in cases where the arch didn't * setup precise phy_map entries */ -static u32 busy_phy_map = 0; +static u32 busy_phy_map; -/* If EMACs share a common MDIO device, this points to it */ -static struct net_device *mdio_ndev = NULL; - -struct emac_def_dev { - struct list_head link; - struct ocp_device *ocpdev; - struct ibm_ocp_mal *mal; -}; - -static struct net_device_stats *emac_stats(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - return &fep->stats; -}; - -static int -emac_init_rgmii(struct ocp_device *rgmii_dev, int input, int phy_mode) -{ - struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(rgmii_dev); - const char *mode_name[] = { "RTBI", "RGMII", "TBI", "GMII" }; - int mode = -1; - - if (!rgmii) { - rgmii = kmalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL); - - if (rgmii == NULL) { - printk(KERN_ERR - "rgmii%d: Out of memory allocating RGMII structure!\n", - rgmii_dev->def->index); - return -ENOMEM; - } - - memset(rgmii, 0, sizeof(*rgmii)); - - rgmii->base = - (struct rgmii_regs *)ioremap(rgmii_dev->def->paddr, - sizeof(*rgmii->base)); - if (rgmii->base == NULL) { - printk(KERN_ERR - "rgmii%d: Cannot ioremap bridge registers!\n", - rgmii_dev->def->index); - - kfree(rgmii); - return -ENOMEM; - } - ocp_set_drvdata(rgmii_dev, rgmii); - } - - if (phy_mode) { - switch (phy_mode) { - case PHY_MODE_GMII: - mode = GMII; - break; - case PHY_MODE_TBI: - mode = TBI; - break; - case PHY_MODE_RTBI: - mode = RTBI; - break; - case PHY_MODE_RGMII: - default: - mode = RGMII; - } - rgmii->base->fer &= ~RGMII_FER_MASK(input); - rgmii->base->fer |= rgmii_enable[mode] << (4 * input); - } else { - switch ((rgmii->base->fer & RGMII_FER_MASK(input)) >> (4 * - input)) { - case RGMII_RTBI: - mode = RTBI; - break; - case RGMII_RGMII: - mode = RGMII; - break; - case RGMII_TBI: - mode = TBI; - break; - case RGMII_GMII: - mode = GMII; - } - } - - /* Set mode to RGMII if nothing valid is detected */ - if (mode < 0) - mode = RGMII; - - printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n", - rgmii_dev->def->index, input, mode_name[mode]); - - rgmii->mode[input] = mode; - rgmii->users++; - - return 0; -} - -static void -emac_rgmii_port_speed(struct ocp_device *ocpdev, int input, int speed) -{ - struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev); - unsigned int rgmii_speed; - - rgmii_speed = in_be32(&rgmii->base->ssr); - - rgmii_speed &= ~rgmii_speed_mask[input]; - - if (speed == 1000) - rgmii_speed |= rgmii_speed1000[input]; - else if (speed == 100) - rgmii_speed |= rgmii_speed100[input]; - - out_be32(&rgmii->base->ssr, rgmii_speed); -} - -static void emac_close_rgmii(struct ocp_device *ocpdev) -{ - struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev); - BUG_ON(!rgmii || rgmii->users == 0); - - if (!--rgmii->users) { - ocp_set_drvdata(ocpdev, NULL); - iounmap((void *)rgmii->base); - kfree(rgmii); - } -} - -static int emac_init_zmii(struct ocp_device *zmii_dev, int input, int phy_mode) -{ - struct ibm_ocp_zmii *zmii = ZMII_PRIV(zmii_dev); - const char *mode_name[] = { "SMII", "RMII", "MII" }; - int mode = -1; - - if (!zmii) { - zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL); - if (zmii == NULL) { - printk(KERN_ERR - "zmii%d: Out of memory allocating ZMII structure!\n", - zmii_dev->def->index); - return -ENOMEM; - } - memset(zmii, 0, sizeof(*zmii)); - - zmii->base = - (struct zmii_regs *)ioremap(zmii_dev->def->paddr, - sizeof(*zmii->base)); - if (zmii->base == NULL) { - printk(KERN_ERR - "zmii%d: Cannot ioremap bridge registers!\n", - zmii_dev->def->index); - - kfree(zmii); - return -ENOMEM; - } - ocp_set_drvdata(zmii_dev, zmii); - } - - if (phy_mode) { - switch (phy_mode) { - case PHY_MODE_MII: - mode = MII; - break; - case PHY_MODE_RMII: - mode = RMII; - break; - case PHY_MODE_SMII: - default: - mode = SMII; - } - zmii->base->fer &= ~ZMII_FER_MASK(input); - zmii->base->fer |= zmii_enable[input][mode]; - } else { - switch ((zmii->base->fer & ZMII_FER_MASK(input)) << (4 * input)) { - case ZMII_MII0: - mode = MII; - break; - case ZMII_RMII0: - mode = RMII; - break; - case ZMII_SMII0: - mode = SMII; - } - } - - /* Set mode to SMII if nothing valid is detected */ - if (mode < 0) - mode = SMII; - - printk(KERN_NOTICE "zmii%d: input %d in %s mode\n", - zmii_dev->def->index, input, mode_name[mode]); - - zmii->mode[input] = mode; - zmii->users++; - - return 0; -} - -static void emac_enable_zmii_port(struct ocp_device *ocpdev, int input) -{ - u32 mask; - struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); - - mask = in_be32(&zmii->base->fer); - mask &= zmii_enable[input][MDI]; /* turn all non enabled MDI's off */ - mask |= zmii_enable[input][zmii->mode[input]] | mdi_enable[input]; - out_be32(&zmii->base->fer, mask); -} - -static void -emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed) -{ - struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); - - if (speed == 100) - zmii_speed |= zmii_speed100[input]; - else - zmii_speed &= ~zmii_speed100[input]; - - out_be32(&zmii->base->ssr, zmii_speed); -} - -static void emac_close_zmii(struct ocp_device *ocpdev) -{ - struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); - BUG_ON(!zmii || zmii->users == 0); - - if (!--zmii->users) { - ocp_set_drvdata(ocpdev, NULL); - iounmap((void *)zmii->base); - kfree(zmii); - } -} - -int emac_phy_read(struct net_device *dev, int mii_id, int reg) -{ - int count; - uint32_t stacr; - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - - MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id, - reg)); - - /* Enable proper ZMII port */ - if (fep->zmii_dev) - emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input); - - /* Use the EMAC that has the MDIO port */ - if (fep->mdio_dev) { - dev = fep->mdio_dev; - fep = dev->priv; - emacp = fep->emacp; - } - - count = 0; - while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) - && (count++ < MDIO_DELAY)) - udelay(1); - MDIO_DEBUG((" (count was %d)\n", count)); - - if ((stacr & EMAC_STACR_OC) == 0) { - printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name); - return -1; - } - - /* Clear the speed bits and make a read request to the PHY */ - stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ); - stacr |= ((mii_id & 0x1F) << 5); - - out_be32(&emacp->em0stacr, stacr); - - count = 0; - while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) - && (count++ < MDIO_DELAY)) - udelay(1); - MDIO_DEBUG((" (count was %d)\n", count)); - - if ((stacr & EMAC_STACR_OC) == 0) { - printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); - return -1; - } - - /* Check for a read error */ - if (stacr & EMAC_STACR_PHYE) { - MDIO_DEBUG(("EMAC MDIO PHY error !\n")); - return -1; - } - - MDIO_DEBUG((" -> 0x%x\n", stacr >> 16)); - - return (stacr >> 16); -} - -void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) -{ - int count; - uint32_t stacr; - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - - MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n", - dev->name, mii_id, reg, data)); - - /* Enable proper ZMII port */ - if (fep->zmii_dev) - emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input); - - /* Use the EMAC that has the MDIO port */ - if (fep->mdio_dev) { - dev = fep->mdio_dev; - fep = dev->priv; - emacp = fep->emacp; - } - - count = 0; - while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) - && (count++ < MDIO_DELAY)) - udelay(1); - MDIO_DEBUG((" (count was %d)\n", count)); - - if ((stacr & EMAC_STACR_OC) == 0) { - printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); - return; - } - - /* Clear the speed bits and make a read request to the PHY */ - - stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ); - stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16); - - out_be32(&emacp->em0stacr, stacr); - - count = 0; - while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) - && (count++ < MDIO_DELAY)) - udelay(1); - MDIO_DEBUG((" (count was %d)\n", count)); - - if ((stacr & EMAC_STACR_OC) == 0) - printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); - - /* Check for a write error */ - if ((stacr & EMAC_STACR_PHYE) != 0) { - MDIO_DEBUG(("EMAC MDIO PHY error !\n")); - } -} - -static void emac_txeob_dev(void *param, u32 chanmask) -{ - struct net_device *dev = param; - struct ocp_enet_private *fep = dev->priv; - unsigned long flags; - - spin_lock_irqsave(&fep->lock, flags); - - PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt)); - - while (fep->tx_cnt && - !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) { - - if (fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_LAST) { - /* Tell the system the transmit completed. */ - dma_unmap_single(&fep->ocpdev->dev, - fep->tx_desc[fep->ack_slot].data_ptr, - fep->tx_desc[fep->ack_slot].data_len, - DMA_TO_DEVICE); - dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]); - - if (fep->tx_desc[fep->ack_slot].ctrl & - (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC)) - fep->stats.collisions++; - } - - fep->tx_skb[fep->ack_slot] = (struct sk_buff *)NULL; - if (++fep->ack_slot == NUM_TX_BUFF) - fep->ack_slot = 0; - - fep->tx_cnt--; - } - if (fep->tx_cnt < NUM_TX_BUFF) - netif_wake_queue(dev); - - PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt)); - - spin_unlock_irqrestore(&fep->lock, flags); -} - -/* - Fill/Re-fill the rx chain with valid ctrl/ptrs. - This function will fill from rx_slot up to the parm end. - So to completely fill the chain pre-set rx_slot to 0 and - pass in an end of 0. +#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && (defined(CONFIG_405EP) || defined(CONFIG_440EP)) +/* 405EP has "EMAC to PHY Control Register" (CPC0_EPCTL) which can help us + * with PHY RX clock problem. + * 440EP has more sane SDR0_MFR register implementation than 440GX, which + * also allows controlling each EMAC clock */ -static void emac_rx_fill(struct net_device *dev, int end) +static inline void EMAC_RX_CLK_TX(int idx) { - int i; - struct ocp_enet_private *fep = dev->priv; - - i = fep->rx_slot; - do { - /* We don't want the 16 bytes skb_reserve done by dev_alloc_skb, - * it breaks our cache line alignement. However, we still allocate - * +16 so that we end up allocating the exact same size as - * dev_alloc_skb() would do. - * Also, because of the skb_res, the max DMA size we give to EMAC - * is slighly wrong, causing it to potentially DMA 2 more bytes - * from a broken/oversized packet. These 16 bytes will take care - * that we don't walk on somebody else toes with that. - */ - fep->rx_skb[i] = - alloc_skb(fep->rx_buffer_size + 16, GFP_ATOMIC); - - if (fep->rx_skb[i] == NULL) { - /* Keep rx_slot here, the next time clean/fill is called - * we will try again before the MAL wraps back here - * If the MAL tries to use this descriptor with - * the EMPTY bit off it will cause the - * rxde interrupt. That is where we will - * try again to allocate an sk_buff. - */ - break; - - } - - if (skb_res) - skb_reserve(fep->rx_skb[i], skb_res); - - /* We must NOT dma_map_single the cache line right after the - * buffer, so we must crop our sync size to account for the - * reserved space - */ - fep->rx_desc[i].data_ptr = - (unsigned char *)dma_map_single(&fep->ocpdev->dev, - (void *)fep->rx_skb[i]-> - data, - fep->rx_buffer_size - - skb_res, DMA_FROM_DEVICE); - - /* - * Some 4xx implementations use the previously - * reserved bits in data_len to encode the MS - * 4-bits of a 36-bit physical address (ERPN) - * This must be initialized. - */ - fep->rx_desc[i].data_len = 0; - fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR | - (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0); - - } while ((i = (i + 1) % NUM_RX_BUFF) != end); - - fep->rx_slot = i; -} - -static void -emac_rx_csum(struct net_device *dev, unsigned short ctrl, struct sk_buff *skb) -{ - struct ocp_enet_private *fep = dev->priv; - - /* Exit if interface has no TAH engine */ - if (!fep->tah_dev) { - skb->ip_summed = CHECKSUM_NONE; - return; - } - - /* Check for TCP/UDP/IP csum error */ - if (ctrl & EMAC_CSUM_VER_ERROR) { - /* Let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; -/* adapter->hw_csum_err++; */ - } else { - /* Csum is good */ - skb->ip_summed = CHECKSUM_UNNECESSARY; -/* adapter->hw_csum_good++; */ - } -} - -static int emac_rx_clean(struct net_device *dev) -{ - int i, b, bnum = 0, buf[6]; - int error, frame_length; - struct ocp_enet_private *fep = dev->priv; - unsigned short ctrl; - - i = fep->rx_slot; - - PKT_DEBUG(("emac_rx_clean() entry, rx_slot: %d\n", fep->rx_slot)); - - do { - if (fep->rx_skb[i] == NULL) - continue; /*we have already handled the packet but haved failed to alloc */ - /* - since rx_desc is in uncached mem we don't keep reading it directly - we pull out a local copy of ctrl and do the checks on the copy. - */ - ctrl = fep->rx_desc[i].ctrl; - if (ctrl & MAL_RX_CTRL_EMPTY) - break; /*we don't have any more ready packets */ - - if (EMAC_IS_BAD_RX_PACKET(ctrl)) { - fep->stats.rx_errors++; - fep->stats.rx_dropped++; - - if (ctrl & EMAC_RX_ST_OE) - fep->stats.rx_fifo_errors++; - if (ctrl & EMAC_RX_ST_AE) - fep->stats.rx_frame_errors++; - if (ctrl & EMAC_RX_ST_BFCS) - fep->stats.rx_crc_errors++; - if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL | - EMAC_RX_ST_ORE | EMAC_RX_ST_IRE)) - fep->stats.rx_length_errors++; - } else { - if ((ctrl & (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) == - (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) { - /* Single descriptor packet */ - emac_rx_csum(dev, ctrl, fep->rx_skb[i]); - /* Send the skb up the chain. */ - frame_length = fep->rx_desc[i].data_len - 4; - skb_put(fep->rx_skb[i], frame_length); - fep->rx_skb[i]->dev = dev; - fep->rx_skb[i]->protocol = - eth_type_trans(fep->rx_skb[i], dev); - error = netif_rx(fep->rx_skb[i]); - - if ((error == NET_RX_DROP) || - (error == NET_RX_BAD)) { - fep->stats.rx_dropped++; - } else { - fep->stats.rx_packets++; - fep->stats.rx_bytes += frame_length; - } - fep->rx_skb[i] = NULL; - } else { - /* Multiple descriptor packet */ - if (ctrl & MAL_RX_CTRL_FIRST) { - if (fep->rx_desc[(i + 1) % NUM_RX_BUFF]. - ctrl & MAL_RX_CTRL_EMPTY) - break; - bnum = 0; - buf[bnum] = i; - ++bnum; - continue; - } - if (((ctrl & MAL_RX_CTRL_FIRST) != - MAL_RX_CTRL_FIRST) && - ((ctrl & MAL_RX_CTRL_LAST) != - MAL_RX_CTRL_LAST)) { - if (fep->rx_desc[(i + 1) % - NUM_RX_BUFF].ctrl & - MAL_RX_CTRL_EMPTY) { - i = buf[0]; - break; - } - buf[bnum] = i; - ++bnum; - continue; - } - if (ctrl & MAL_RX_CTRL_LAST) { - buf[bnum] = i; - ++bnum; - skb_put(fep->rx_skb[buf[0]], - fep->rx_desc[buf[0]].data_len); - for (b = 1; b < bnum; b++) { - /* - * MAL is braindead, we need - * to copy the remainder - * of the packet from the - * latter descriptor buffers - * to the first skb. Then - * dispose of the source - * skbs. - * - * Once the stack is fixed - * to handle frags on most - * protocols we can generate - * a fragmented skb with - * no copies. - */ - memcpy(fep->rx_skb[buf[0]]-> - data + - fep->rx_skb[buf[0]]->len, - fep->rx_skb[buf[b]]-> - data, - fep->rx_desc[buf[b]]. - data_len); - skb_put(fep->rx_skb[buf[0]], - fep->rx_desc[buf[b]]. - data_len); - dma_unmap_single(&fep->ocpdev-> - dev, - fep-> - rx_desc[buf - [b]]. - data_ptr, - fep-> - rx_desc[buf - [b]]. - data_len, - DMA_FROM_DEVICE); - dev_kfree_skb(fep-> - rx_skb[buf[b]]); - } - emac_rx_csum(dev, ctrl, - fep->rx_skb[buf[0]]); - - fep->rx_skb[buf[0]]->dev = dev; - fep->rx_skb[buf[0]]->protocol = - eth_type_trans(fep->rx_skb[buf[0]], - dev); - error = netif_rx(fep->rx_skb[buf[0]]); - - if ((error == NET_RX_DROP) - || (error == NET_RX_BAD)) { - fep->stats.rx_dropped++; - } else { - fep->stats.rx_packets++; - fep->stats.rx_bytes += - fep->rx_skb[buf[0]]->len; - } - for (b = 0; b < bnum; b++) - fep->rx_skb[buf[b]] = NULL; - } - } - } - } while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot); - - PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot)); - - return i; -} - -static void emac_rxeob_dev(void *param, u32 chanmask) -{ - struct net_device *dev = param; - struct ocp_enet_private *fep = dev->priv; unsigned long flags; + local_irq_save(flags); + +#if defined(CONFIG_405EP) + mtdcr(0xf3, mfdcr(0xf3) | (1 << idx)); +#else /* CONFIG_440EP */ + SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) | (0x08000000 >> idx)); +#endif + + local_irq_restore(flags); +} + +static inline void EMAC_RX_CLK_DEFAULT(int idx) +{ + unsigned long flags; + local_irq_save(flags); + +#if defined(CONFIG_405EP) + mtdcr(0xf3, mfdcr(0xf3) & ~(1 << idx)); +#else /* CONFIG_440EP */ + SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~(0x08000000 >> idx)); +#endif + + local_irq_restore(flags); +} +#else +#define EMAC_RX_CLK_TX(idx) ((void)0) +#define EMAC_RX_CLK_DEFAULT(idx) ((void)0) +#endif + +#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && defined(CONFIG_440GX) +/* We can switch Ethernet clock to the internal source through SDR0_MFR[ECS], + * unfortunately this is less flexible than 440EP case, because it's a global + * setting for all EMACs, therefore we do this clock trick only during probe. + */ +#define EMAC_CLK_INTERNAL SDR_WRITE(DCRN_SDR_MFR, \ + SDR_READ(DCRN_SDR_MFR) | 0x08000000) +#define EMAC_CLK_EXTERNAL SDR_WRITE(DCRN_SDR_MFR, \ + SDR_READ(DCRN_SDR_MFR) & ~0x08000000) +#else +#define EMAC_CLK_INTERNAL ((void)0) +#define EMAC_CLK_EXTERNAL ((void)0) +#endif + +/* I don't want to litter system log with timeout errors + * when we have brain-damaged PHY. + */ +static inline void emac_report_timeout_error(struct ocp_enet_private *dev, + const char *error) +{ +#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) + DBG("%d: %s" NL, dev->def->index, error); +#else + if (net_ratelimit()) + printk(KERN_ERR "emac%d: %s\n", dev->def->index, error); +#endif +} + +/* PHY polling intervals */ +#define PHY_POLL_LINK_ON HZ +#define PHY_POLL_LINK_OFF (HZ / 5) + +/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ +static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { + "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", + "tx_packets_csum", "tx_undo", "rx_dropped_stack", "rx_dropped_oom", + "rx_dropped_error", "rx_dropped_resize", "rx_dropped_mtu", + "rx_stopped", "rx_bd_errors", "rx_bd_overrun", "rx_bd_bad_packet", + "rx_bd_runt_packet", "rx_bd_short_event", "rx_bd_alignment_error", + "rx_bd_bad_fcs", "rx_bd_packet_too_long", "rx_bd_out_of_range", + "rx_bd_in_range", "rx_parity", "rx_fifo_overrun", "rx_overrun", + "rx_bad_packet", "rx_runt_packet", "rx_short_event", + "rx_alignment_error", "rx_bad_fcs", "rx_packet_too_long", + "rx_out_of_range", "rx_in_range", "tx_dropped", "tx_bd_errors", + "tx_bd_bad_fcs", "tx_bd_carrier_loss", "tx_bd_excessive_deferral", + "tx_bd_excessive_collisions", "tx_bd_late_collision", + "tx_bd_multple_collisions", "tx_bd_single_collision", + "tx_bd_underrun", "tx_bd_sqe", "tx_parity", "tx_underrun", "tx_sqe", + "tx_errors" +}; + +static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs); +static void emac_clean_tx_ring(struct ocp_enet_private *dev); + +static inline int emac_phy_supports_gige(int phy_mode) +{ + return phy_mode == PHY_MODE_GMII || + phy_mode == PHY_MODE_RGMII || + phy_mode == PHY_MODE_TBI || + phy_mode == PHY_MODE_RTBI; +} + +static inline int emac_phy_gpcs(int phy_mode) +{ + return phy_mode == PHY_MODE_TBI || + phy_mode == PHY_MODE_RTBI; +} + +static inline void emac_tx_enable(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + u32 r; + + local_irq_save(flags); + + DBG("%d: tx_enable" NL, dev->def->index); + + r = in_be32(&p->mr0); + if (!(r & EMAC_MR0_TXE)) + out_be32(&p->mr0, r | EMAC_MR0_TXE); + local_irq_restore(flags); +} + +static void emac_tx_disable(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + u32 r; + + local_irq_save(flags); + + DBG("%d: tx_disable" NL, dev->def->index); + + r = in_be32(&p->mr0); + if (r & EMAC_MR0_TXE) { + int n = 300; + out_be32(&p->mr0, r & ~EMAC_MR0_TXE); + while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) + --n; + if (unlikely(!n)) + emac_report_timeout_error(dev, "TX disable timeout"); + } + local_irq_restore(flags); +} + +static void emac_rx_enable(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + u32 r; + + local_irq_save(flags); + if (unlikely(dev->commac.rx_stopped)) + goto out; + + DBG("%d: rx_enable" NL, dev->def->index); + + r = in_be32(&p->mr0); + if (!(r & EMAC_MR0_RXE)) { + if (unlikely(!(r & EMAC_MR0_RXI))) { + /* Wait if previous async disable is still in progress */ + int n = 100; + while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) + --n; + if (unlikely(!n)) + emac_report_timeout_error(dev, + "RX disable timeout"); + } + out_be32(&p->mr0, r | EMAC_MR0_RXE); + } + out: + local_irq_restore(flags); +} + +static void emac_rx_disable(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + u32 r; + + local_irq_save(flags); + + DBG("%d: rx_disable" NL, dev->def->index); + + r = in_be32(&p->mr0); + if (r & EMAC_MR0_RXE) { + int n = 300; + out_be32(&p->mr0, r & ~EMAC_MR0_RXE); + while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) + --n; + if (unlikely(!n)) + emac_report_timeout_error(dev, "RX disable timeout"); + } + local_irq_restore(flags); +} + +static inline void emac_rx_disable_async(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + u32 r; + + local_irq_save(flags); + + DBG("%d: rx_disable_async" NL, dev->def->index); + + r = in_be32(&p->mr0); + if (r & EMAC_MR0_RXE) + out_be32(&p->mr0, r & ~EMAC_MR0_RXE); + local_irq_restore(flags); +} + +static int emac_reset(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + unsigned long flags; + int n = 20; + + DBG("%d: reset" NL, dev->def->index); + + local_irq_save(flags); + + if (!dev->reset_failed) { + /* 40x erratum suggests stopping RX channel before reset, + * we stop TX as well + */ + emac_rx_disable(dev); + emac_tx_disable(dev); + } + + out_be32(&p->mr0, EMAC_MR0_SRST); + while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n) + --n; + local_irq_restore(flags); + + if (n) { + dev->reset_failed = 0; + return 0; + } else { + emac_report_timeout_error(dev, "reset timeout"); + dev->reset_failed = 1; + return -ETIMEDOUT; + } +} + +static void emac_hash_mc(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + u16 gaht[4] = { 0 }; + struct dev_mc_list *dmi; + + DBG("%d: hash_mc %d" NL, dev->def->index, dev->ndev->mc_count); + + for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { + int bit; + DBG2("%d: mc %02x:%02x:%02x:%02x:%02x:%02x" NL, + dev->def->index, + dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], + dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); + + bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26); + gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f); + } + out_be32(&p->gaht1, gaht[0]); + out_be32(&p->gaht2, gaht[1]); + out_be32(&p->gaht3, gaht[2]); + out_be32(&p->gaht4, gaht[3]); +} + +static inline u32 emac_iff2rmr(struct net_device *ndev) +{ + u32 r = EMAC_RMR_SP | EMAC_RMR_SFCS | EMAC_RMR_IAE | EMAC_RMR_BAE | + EMAC_RMR_BASE; + + if (ndev->flags & IFF_PROMISC) + r |= EMAC_RMR_PME; + else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32) + r |= EMAC_RMR_PMME; + else if (ndev->mc_count > 0) + r |= EMAC_RMR_MAE; + + return r; +} + +static inline int emac_opb_mhz(void) +{ + return (ocp_sys_info.opb_bus_freq + 500000) / 1000000; +} + +/* BHs disabled */ +static int emac_configure(struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + struct net_device *ndev = dev->ndev; + int gige; + u32 r; + + DBG("%d: configure" NL, dev->def->index); + + if (emac_reset(dev) < 0) + return -ETIMEDOUT; + + tah_reset(dev->tah_dev); + + /* Mode register */ + r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; + if (dev->phy.duplex == DUPLEX_FULL) + r |= EMAC_MR1_FDE; + switch (dev->phy.speed) { + case SPEED_1000: + if (emac_phy_gpcs(dev->phy.mode)) { + r |= EMAC_MR1_MF_1000GPCS | + EMAC_MR1_MF_IPPA(dev->phy.address); + + /* Put some arbitrary OUI, Manuf & Rev IDs so we can + * identify this GPCS PHY later. + */ + out_be32(&p->ipcr, 0xdeadbeef); + } else + r |= EMAC_MR1_MF_1000; + r |= EMAC_MR1_RFS_16K; + gige = 1; + + if (dev->ndev->mtu > ETH_DATA_LEN) + r |= EMAC_MR1_JPSM; + break; + case SPEED_100: + r |= EMAC_MR1_MF_100; + /* Fall through */ + default: + r |= EMAC_MR1_RFS_4K; + gige = 0; + break; + } + + if (dev->rgmii_dev) + rgmii_set_speed(dev->rgmii_dev, dev->rgmii_input, + dev->phy.speed); + else + zmii_set_speed(dev->zmii_dev, dev->zmii_input, dev->phy.speed); + +#if !defined(CONFIG_40x) + /* on 40x erratum forces us to NOT use integrated flow control, + * let's hope it works on 44x ;) + */ + if (dev->phy.duplex == DUPLEX_FULL) { + if (dev->phy.pause) + r |= EMAC_MR1_EIFC | EMAC_MR1_APP; + else if (dev->phy.asym_pause) + r |= EMAC_MR1_APP; + } +#endif + out_be32(&p->mr1, r); + + /* Set individual MAC address */ + out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]); + out_be32(&p->ialr, (ndev->dev_addr[2] << 24) | + (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) | + ndev->dev_addr[5]); + + /* VLAN Tag Protocol ID */ + out_be32(&p->vtpid, 0x8100); + + /* Receive mode register */ + r = emac_iff2rmr(ndev); + if (r & EMAC_RMR_MAE) + emac_hash_mc(dev); + out_be32(&p->rmr, r); + + /* FIFOs thresholds */ + r = EMAC_TMR1((EMAC_MAL_BURST_SIZE / EMAC_FIFO_ENTRY_SIZE) + 1, + EMAC_TX_FIFO_SIZE / 2 / EMAC_FIFO_ENTRY_SIZE); + out_be32(&p->tmr1, r); + out_be32(&p->trtr, EMAC_TRTR(EMAC_TX_FIFO_SIZE / 2)); + + /* PAUSE frame is sent when RX FIFO reaches its high-water mark, + there should be still enough space in FIFO to allow the our link + partner time to process this frame and also time to send PAUSE + frame itself. + + Here is the worst case scenario for the RX FIFO "headroom" + (from "The Switch Book") (100Mbps, without preamble, inter-frame gap): + + 1) One maximum-length frame on TX 1522 bytes + 2) One PAUSE frame time 64 bytes + 3) PAUSE frame decode time allowance 64 bytes + 4) One maximum-length frame on RX 1522 bytes + 5) Round-trip propagation delay of the link (100Mb) 15 bytes + ---------- + 3187 bytes + + I chose to set high-water mark to RX_FIFO_SIZE / 4 (1024 bytes) + low-water mark to RX_FIFO_SIZE / 8 (512 bytes) + */ + r = EMAC_RWMR(EMAC_RX_FIFO_SIZE(gige) / 8 / EMAC_FIFO_ENTRY_SIZE, + EMAC_RX_FIFO_SIZE(gige) / 4 / EMAC_FIFO_ENTRY_SIZE); + out_be32(&p->rwmr, r); + + /* Set PAUSE timer to the maximum */ + out_be32(&p->ptr, 0xffff); + + /* IRQ sources */ + out_be32(&p->iser, EMAC_ISR_TXPE | EMAC_ISR_RXPE | /* EMAC_ISR_TXUE | + EMAC_ISR_RXOE | */ EMAC_ISR_OVR | EMAC_ISR_BP | EMAC_ISR_SE | + EMAC_ISR_ALE | EMAC_ISR_BFCS | EMAC_ISR_PTLE | EMAC_ISR_ORE | + EMAC_ISR_IRE | EMAC_ISR_TE); + + /* We need to take GPCS PHY out of isolate mode after EMAC reset */ + if (emac_phy_gpcs(dev->phy.mode)) + mii_reset_phy(&dev->phy); + + return 0; +} + +/* BHs disabled */ +static void emac_reinitialize(struct ocp_enet_private *dev) +{ + DBG("%d: reinitialize" NL, dev->def->index); + + if (!emac_configure(dev)) { + emac_tx_enable(dev); + emac_rx_enable(dev); + } +} + +/* BHs disabled */ +static void emac_full_tx_reset(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + struct ocp_func_emac_data *emacdata = dev->def->additions; + + DBG("%d: full_tx_reset" NL, dev->def->index); + + emac_tx_disable(dev); + mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan); + emac_clean_tx_ring(dev); + dev->tx_cnt = dev->tx_slot = dev->ack_slot = 0; + + emac_configure(dev); + + mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan); + emac_tx_enable(dev); + emac_rx_enable(dev); + + netif_wake_queue(ndev); +} + +static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) +{ + struct emac_regs *p = dev->emacp; + u32 r; int n; - spin_lock_irqsave(&fep->lock, flags); - if ((n = emac_rx_clean(dev)) != fep->rx_slot) - emac_rx_fill(dev, n); - spin_unlock_irqrestore(&fep->lock, flags); -} + DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg); -/* - * This interrupt should never occurr, we don't program - * the MAL for contiunous mode. - */ -static void emac_txde_dev(void *param, u32 chanmask) -{ - struct net_device *dev = param; - struct ocp_enet_private *fep = dev->priv; + /* Enable proper MDIO port */ + zmii_enable_mdio(dev->zmii_dev, dev->zmii_input); - printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name); - - emac_mac_dump(dev); - emac_mal_dump(dev); - - /* Reenable the transmit channel */ - mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); -} - -/* - * This interrupt should be very rare at best. This occurs when - * the hardware has a problem with the receive descriptors. The manual - * states that it occurs when the hardware cannot the receive descriptor - * empty bit is not set. The recovery mechanism will be to - * traverse through the descriptors, handle any that are marked to be - * handled and reinitialize each along the way. At that point the driver - * will be restarted. - */ -static void emac_rxde_dev(void *param, u32 chanmask) -{ - struct net_device *dev = param; - struct ocp_enet_private *fep = dev->priv; - unsigned long flags; - - if (net_ratelimit()) { - printk(KERN_WARNING "%s: receive descriptor error\n", - fep->ndev->name); - - emac_mac_dump(dev); - emac_mal_dump(dev); - emac_desc_dump(dev); + /* Wait for management interface to become idle */ + n = 10; + while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { + udelay(1); + if (!--n) + goto to; } - /* Disable RX channel */ - spin_lock_irqsave(&fep->lock, flags); - mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + /* Issue read command */ + out_be32(&p->stacr, + EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ | + (reg & EMAC_STACR_PRA_MASK) + | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT)); - /* For now, charge the error against all emacs */ - fep->stats.rx_errors++; + /* Wait for read to complete */ + n = 100; + while (!((r = in_be32(&p->stacr)) & EMAC_STACR_OC)) { + udelay(1); + if (!--n) + goto to; + } - /* so do we have any good packets still? */ - emac_rx_clean(dev); + if (unlikely(r & EMAC_STACR_PHYE)) { + DBG("%d: mdio_read(%02x, %02x) failed" NL, dev->def->index, + id, reg); + return -EREMOTEIO; + } - /* When the interface is restarted it resets processing to the - * first descriptor in the table. + r = ((r >> EMAC_STACR_PHYD_SHIFT) & EMAC_STACR_PHYD_MASK); + DBG2("%d: mdio_read -> %04x" NL, dev->def->index, r); + return r; + to: + DBG("%d: MII management interface timeout (read)" NL, dev->def->index); + return -ETIMEDOUT; +} + +static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg, + u16 val) +{ + struct emac_regs *p = dev->emacp; + int n; + + DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg, + val); + + /* Enable proper MDIO port */ + zmii_enable_mdio(dev->zmii_dev, dev->zmii_input); + + /* Wait for management interface to be idle */ + n = 10; + while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { + udelay(1); + if (!--n) + goto to; + } + + /* Issue write command */ + out_be32(&p->stacr, + EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE | + (reg & EMAC_STACR_PRA_MASK) | + ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) | + (val << EMAC_STACR_PHYD_SHIFT)); + + /* Wait for write to complete */ + n = 100; + while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { + udelay(1); + if (!--n) + goto to; + } + return; + to: + DBG("%d: MII management interface timeout (write)" NL, dev->def->index); +} + +static int emac_mdio_read(struct net_device *ndev, int id, int reg) +{ + struct ocp_enet_private *dev = ndev->priv; + int res; + + local_bh_disable(); + res = __emac_mdio_read(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id, + (u8) reg); + local_bh_enable(); + return res; +} + +static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val) +{ + struct ocp_enet_private *dev = ndev->priv; + + local_bh_disable(); + __emac_mdio_write(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id, + (u8) reg, (u16) val); + local_bh_enable(); +} + +/* BHs disabled */ +static void emac_set_multicast_list(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + struct emac_regs *p = dev->emacp; + u32 rmr = emac_iff2rmr(ndev); + + DBG("%d: multicast %08x" NL, dev->def->index, rmr); + BUG_ON(!netif_running(dev->ndev)); + + /* I decided to relax register access rules here to avoid + * full EMAC reset. + * + * There is a real problem with EMAC4 core if we use MWSW_001 bit + * in MR1 register and do a full EMAC reset. + * One TX BD status update is delayed and, after EMAC reset, it + * never happens, resulting in TX hung (it'll be recovered by TX + * timeout handler eventually, but this is just gross). + * So we either have to do full TX reset or try to cheat here :) + * + * The only required change is to RX mode register, so I *think* all + * we need is just to stop RX channel. This seems to work on all + * tested SoCs. --ebs */ - - fep->rx_slot = 0; - emac_rx_fill(dev, 0); - - set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask); - set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask); - - /* Reenable the receive channels */ - mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - spin_unlock_irqrestore(&fep->lock, flags); + emac_rx_disable(dev); + if (rmr & EMAC_RMR_MAE) + emac_hash_mc(dev); + out_be32(&p->rmr, rmr); + emac_rx_enable(dev); } -static irqreturn_t -emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs) +/* BHs disabled */ +static int emac_resize_rx_ring(struct ocp_enet_private *dev, int new_mtu) { - struct net_device *dev = dev_instance; - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - unsigned long tmp_em0isr; + struct ocp_func_emac_data *emacdata = dev->def->additions; + int rx_sync_size = emac_rx_sync_size(new_mtu); + int rx_skb_size = emac_rx_skb_size(new_mtu); + int i, ret = 0; - /* EMAC interrupt */ - tmp_em0isr = in_be32(&emacp->em0isr); - if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) { - /* This error is a hard transmit error - could retransmit */ - fep->stats.tx_errors++; + emac_rx_disable(dev); + mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan); - /* Reenable the transmit channel */ - mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); - - } else { - fep->stats.rx_errors++; + if (dev->rx_sg_skb) { + ++dev->estats.rx_dropped_resize; + dev_kfree_skb(dev->rx_sg_skb); + dev->rx_sg_skb = NULL; } - if (tmp_em0isr & EMAC_ISR_RP) - fep->stats.rx_length_errors++; - if (tmp_em0isr & EMAC_ISR_ALE) - fep->stats.rx_frame_errors++; - if (tmp_em0isr & EMAC_ISR_BFCS) - fep->stats.rx_crc_errors++; - if (tmp_em0isr & EMAC_ISR_PTLE) - fep->stats.rx_length_errors++; - if (tmp_em0isr & EMAC_ISR_ORE) - fep->stats.rx_length_errors++; - if (tmp_em0isr & EMAC_ISR_TE0) - fep->stats.tx_aborted_errors++; + /* Make a first pass over RX ring and mark BDs ready, dropping + * non-processed packets on the way. We need this as a separate pass + * to simplify error recovery in the case of allocation failure later. + */ + for (i = 0; i < NUM_RX_BUFF; ++i) { + if (dev->rx_desc[i].ctrl & MAL_RX_CTRL_FIRST) + ++dev->estats.rx_dropped_resize; - emac_err_dump(dev, tmp_em0isr); + dev->rx_desc[i].data_len = 0; + dev->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | + (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0); + } - out_be32(&emacp->em0isr, tmp_em0isr); + /* Reallocate RX ring only if bigger skb buffers are required */ + if (rx_skb_size <= dev->rx_skb_size) + goto skip; + + /* Second pass, allocate new skbs */ + for (i = 0; i < NUM_RX_BUFF; ++i) { + struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC); + if (!skb) { + ret = -ENOMEM; + goto oom; + } + + BUG_ON(!dev->rx_skb[i]); + dev_kfree_skb(dev->rx_skb[i]); + + skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2); + dev->rx_desc[i].data_ptr = + dma_map_single(dev->ldev, skb->data - 2, rx_sync_size, + DMA_FROM_DEVICE) + 2; + dev->rx_skb[i] = skb; + } + skip: + /* Check if we need to change "Jumbo" bit in MR1 */ + if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) { + /* This is to prevent starting RX channel in emac_rx_enable() */ + dev->commac.rx_stopped = 1; + + dev->ndev->mtu = new_mtu; + emac_full_tx_reset(dev->ndev); + } + + mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(new_mtu)); + oom: + /* Restart RX */ + dev->commac.rx_stopped = dev->rx_slot = 0; + mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan); + emac_rx_enable(dev); + + return ret; +} + +/* Process ctx, rtnl_lock semaphore */ +static int emac_change_mtu(struct net_device *ndev, int new_mtu) +{ + struct ocp_enet_private *dev = ndev->priv; + int ret = 0; + + if (new_mtu < EMAC_MIN_MTU || new_mtu > EMAC_MAX_MTU) + return -EINVAL; + + DBG("%d: change_mtu(%d)" NL, dev->def->index, new_mtu); + + local_bh_disable(); + if (netif_running(ndev)) { + /* Check if we really need to reinitalize RX ring */ + if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu)) + ret = emac_resize_rx_ring(dev, new_mtu); + } + + if (!ret) { + ndev->mtu = new_mtu; + dev->rx_skb_size = emac_rx_skb_size(new_mtu); + dev->rx_sync_size = emac_rx_sync_size(new_mtu); + } + local_bh_enable(); + + return ret; +} + +static void emac_clean_tx_ring(struct ocp_enet_private *dev) +{ + int i; + for (i = 0; i < NUM_TX_BUFF; ++i) { + if (dev->tx_skb[i]) { + dev_kfree_skb(dev->tx_skb[i]); + dev->tx_skb[i] = NULL; + if (dev->tx_desc[i].ctrl & MAL_TX_CTRL_READY) + ++dev->estats.tx_dropped; + } + dev->tx_desc[i].ctrl = 0; + dev->tx_desc[i].data_ptr = 0; + } +} + +static void emac_clean_rx_ring(struct ocp_enet_private *dev) +{ + int i; + for (i = 0; i < NUM_RX_BUFF; ++i) + if (dev->rx_skb[i]) { + dev->rx_desc[i].ctrl = 0; + dev_kfree_skb(dev->rx_skb[i]); + dev->rx_skb[i] = NULL; + dev->rx_desc[i].data_ptr = 0; + } + + if (dev->rx_sg_skb) { + dev_kfree_skb(dev->rx_sg_skb); + dev->rx_sg_skb = NULL; + } +} + +static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot, + int flags) +{ + struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags); + if (unlikely(!skb)) + return -ENOMEM; + + dev->rx_skb[slot] = skb; + dev->rx_desc[slot].data_len = 0; + + skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2); + dev->rx_desc[slot].data_ptr = + dma_map_single(dev->ldev, skb->data - 2, dev->rx_sync_size, + DMA_FROM_DEVICE) + 2; + barrier(); + dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY | + (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0); + + return 0; +} + +static void emac_print_link_status(struct ocp_enet_private *dev) +{ + if (netif_carrier_ok(dev->ndev)) + printk(KERN_INFO "%s: link is up, %d %s%s\n", + dev->ndev->name, dev->phy.speed, + dev->phy.duplex == DUPLEX_FULL ? "FDX" : "HDX", + dev->phy.pause ? ", pause enabled" : + dev->phy.asym_pause ? ", assymetric pause enabled" : ""); + else + printk(KERN_INFO "%s: link is down\n", dev->ndev->name); +} + +/* Process ctx, rtnl_lock semaphore */ +static int emac_open(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + struct ocp_func_emac_data *emacdata = dev->def->additions; + int err, i; + + DBG("%d: open" NL, dev->def->index); + + /* Setup error IRQ handler */ + err = request_irq(dev->def->irq, emac_irq, 0, "EMAC", dev); + if (err) { + printk(KERN_ERR "%s: failed to request IRQ %d\n", + ndev->name, dev->def->irq); + return err; + } + + /* Allocate RX ring */ + for (i = 0; i < NUM_RX_BUFF; ++i) + if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) { + printk(KERN_ERR "%s: failed to allocate RX ring\n", + ndev->name); + goto oom; + } + + local_bh_disable(); + dev->tx_cnt = dev->tx_slot = dev->ack_slot = dev->rx_slot = + dev->commac.rx_stopped = 0; + dev->rx_sg_skb = NULL; + + if (dev->phy.address >= 0) { + int link_poll_interval; + if (dev->phy.def->ops->poll_link(&dev->phy)) { + dev->phy.def->ops->read_link(&dev->phy); + EMAC_RX_CLK_DEFAULT(dev->def->index); + netif_carrier_on(dev->ndev); + link_poll_interval = PHY_POLL_LINK_ON; + } else { + EMAC_RX_CLK_TX(dev->def->index); + netif_carrier_off(dev->ndev); + link_poll_interval = PHY_POLL_LINK_OFF; + } + mod_timer(&dev->link_timer, jiffies + link_poll_interval); + emac_print_link_status(dev); + } else + netif_carrier_on(dev->ndev); + + emac_configure(dev); + mal_poll_add(dev->mal, &dev->commac); + mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan); + mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(ndev->mtu)); + mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan); + emac_tx_enable(dev); + emac_rx_enable(dev); + netif_start_queue(ndev); + local_bh_enable(); + + return 0; + oom: + emac_clean_rx_ring(dev); + free_irq(dev->def->irq, dev); + return -ENOMEM; +} + +/* BHs disabled */ +static int emac_link_differs(struct ocp_enet_private *dev) +{ + u32 r = in_be32(&dev->emacp->mr1); + + int duplex = r & EMAC_MR1_FDE ? DUPLEX_FULL : DUPLEX_HALF; + int speed, pause, asym_pause; + + if (r & (EMAC_MR1_MF_1000 | EMAC_MR1_MF_1000GPCS)) + speed = SPEED_1000; + else if (r & EMAC_MR1_MF_100) + speed = SPEED_100; + else + speed = SPEED_10; + + switch (r & (EMAC_MR1_EIFC | EMAC_MR1_APP)) { + case (EMAC_MR1_EIFC | EMAC_MR1_APP): + pause = 1; + asym_pause = 0; + break; + case EMAC_MR1_APP: + pause = 0; + asym_pause = 1; + break; + default: + pause = asym_pause = 0; + } + return speed != dev->phy.speed || duplex != dev->phy.duplex || + pause != dev->phy.pause || asym_pause != dev->phy.asym_pause; +} + +/* BHs disabled */ +static void emac_link_timer(unsigned long data) +{ + struct ocp_enet_private *dev = (struct ocp_enet_private *)data; + int link_poll_interval; + + DBG2("%d: link timer" NL, dev->def->index); + + if (dev->phy.def->ops->poll_link(&dev->phy)) { + if (!netif_carrier_ok(dev->ndev)) { + EMAC_RX_CLK_DEFAULT(dev->def->index); + + /* Get new link parameters */ + dev->phy.def->ops->read_link(&dev->phy); + + if (dev->tah_dev || emac_link_differs(dev)) + emac_full_tx_reset(dev->ndev); + + netif_carrier_on(dev->ndev); + emac_print_link_status(dev); + } + link_poll_interval = PHY_POLL_LINK_ON; + } else { + if (netif_carrier_ok(dev->ndev)) { + EMAC_RX_CLK_TX(dev->def->index); +#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) + emac_reinitialize(dev); +#endif + netif_carrier_off(dev->ndev); + emac_print_link_status(dev); + } + + /* Retry reset if the previous attempt failed. + * This is needed mostly for CONFIG_IBM_EMAC_PHY_RX_CLK_FIX + * case, but I left it here because it shouldn't trigger for + * sane PHYs anyway. + */ + if (unlikely(dev->reset_failed)) + emac_reinitialize(dev); + + link_poll_interval = PHY_POLL_LINK_OFF; + } + mod_timer(&dev->link_timer, jiffies + link_poll_interval); +} + +/* BHs disabled */ +static void emac_force_link_update(struct ocp_enet_private *dev) +{ + netif_carrier_off(dev->ndev); + if (timer_pending(&dev->link_timer)) + mod_timer(&dev->link_timer, jiffies + PHY_POLL_LINK_OFF); +} + +/* Process ctx, rtnl_lock semaphore */ +static int emac_close(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + struct ocp_func_emac_data *emacdata = dev->def->additions; + + DBG("%d: close" NL, dev->def->index); + + local_bh_disable(); + + if (dev->phy.address >= 0) + del_timer_sync(&dev->link_timer); + + netif_stop_queue(ndev); + emac_rx_disable(dev); + emac_tx_disable(dev); + mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan); + mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan); + mal_poll_del(dev->mal, &dev->commac); + local_bh_enable(); + + emac_clean_tx_ring(dev); + emac_clean_rx_ring(dev); + free_irq(dev->def->irq, dev); + + return 0; +} + +static inline u16 emac_tx_csum(struct ocp_enet_private *dev, + struct sk_buff *skb) +{ +#if defined(CONFIG_IBM_EMAC_TAH) + if (skb->ip_summed == CHECKSUM_HW) { + ++dev->stats.tx_packets_csum; + return EMAC_TX_CTRL_TAH_CSUM; + } +#endif + return 0; +} + +static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len) +{ + struct emac_regs *p = dev->emacp; + struct net_device *ndev = dev->ndev; + + /* Send the packet out */ + out_be32(&p->tmr0, EMAC_TMR0_XMIT); + + if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) { + netif_stop_queue(ndev); + DBG2("%d: stopped TX queue" NL, dev->def->index); + } + + ndev->trans_start = jiffies; + ++dev->stats.tx_packets; + dev->stats.tx_bytes += len; + + return 0; +} + +/* BHs disabled */ +static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + unsigned int len = skb->len; + int slot; + + u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY | + MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb); + + slot = dev->tx_slot++; + if (dev->tx_slot == NUM_TX_BUFF) { + dev->tx_slot = 0; + ctrl |= MAL_TX_CTRL_WRAP; + } + + DBG2("%d: xmit(%u) %d" NL, dev->def->index, len, slot); + + dev->tx_skb[slot] = skb; + dev->tx_desc[slot].data_ptr = dma_map_single(dev->ldev, skb->data, len, + DMA_TO_DEVICE); + dev->tx_desc[slot].data_len = (u16) len; + barrier(); + dev->tx_desc[slot].ctrl = ctrl; + + return emac_xmit_finish(dev, len); +} + +#if defined(CONFIG_IBM_EMAC_TAH) +static inline int emac_xmit_split(struct ocp_enet_private *dev, int slot, + u32 pd, int len, int last, u16 base_ctrl) +{ + while (1) { + u16 ctrl = base_ctrl; + int chunk = min(len, MAL_MAX_TX_SIZE); + len -= chunk; + + slot = (slot + 1) % NUM_TX_BUFF; + + if (last && !len) + ctrl |= MAL_TX_CTRL_LAST; + if (slot == NUM_TX_BUFF - 1) + ctrl |= MAL_TX_CTRL_WRAP; + + dev->tx_skb[slot] = NULL; + dev->tx_desc[slot].data_ptr = pd; + dev->tx_desc[slot].data_len = (u16) chunk; + dev->tx_desc[slot].ctrl = ctrl; + ++dev->tx_cnt; + + if (!len) + break; + + pd += chunk; + } + return slot; +} + +/* BHs disabled (SG version for TAH equipped EMACs) */ +static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + int nr_frags = skb_shinfo(skb)->nr_frags; + int len = skb->len, chunk; + int slot, i; + u16 ctrl; + u32 pd; + + /* This is common "fast" path */ + if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE)) + return emac_start_xmit(skb, ndev); + + len -= skb->data_len; + + /* Note, this is only an *estimation*, we can still run out of empty + * slots because of the additional fragmentation into + * MAL_MAX_TX_SIZE-sized chunks + */ + if (unlikely(dev->tx_cnt + nr_frags + mal_tx_chunks(len) > NUM_TX_BUFF)) + goto stop_queue; + + ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY | + emac_tx_csum(dev, skb); + slot = dev->tx_slot; + + /* skb data */ + dev->tx_skb[slot] = NULL; + chunk = min(len, MAL_MAX_TX_SIZE); + dev->tx_desc[slot].data_ptr = pd = + dma_map_single(dev->ldev, skb->data, len, DMA_TO_DEVICE); + dev->tx_desc[slot].data_len = (u16) chunk; + len -= chunk; + if (unlikely(len)) + slot = emac_xmit_split(dev, slot, pd + chunk, len, !nr_frags, + ctrl); + /* skb fragments */ + for (i = 0; i < nr_frags; ++i) { + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + len = frag->size; + + if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF)) + goto undo_frame; + + pd = dma_map_page(dev->ldev, frag->page, frag->page_offset, len, + DMA_TO_DEVICE); + + slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1, + ctrl); + } + + DBG2("%d: xmit_sg(%u) %d - %d" NL, dev->def->index, skb->len, + dev->tx_slot, slot); + + /* Attach skb to the last slot so we don't release it too early */ + dev->tx_skb[slot] = skb; + + /* Send the packet out */ + if (dev->tx_slot == NUM_TX_BUFF - 1) + ctrl |= MAL_TX_CTRL_WRAP; + barrier(); + dev->tx_desc[dev->tx_slot].ctrl = ctrl; + dev->tx_slot = (slot + 1) % NUM_TX_BUFF; + + return emac_xmit_finish(dev, skb->len); + + undo_frame: + /* Well, too bad. Our previous estimation was overly optimistic. + * Undo everything. + */ + while (slot != dev->tx_slot) { + dev->tx_desc[slot].ctrl = 0; + --dev->tx_cnt; + if (--slot < 0) + slot = NUM_TX_BUFF - 1; + } + ++dev->estats.tx_undo; + + stop_queue: + netif_stop_queue(ndev); + DBG2("%d: stopped TX queue" NL, dev->def->index); + return 1; +} +#else +# define emac_start_xmit_sg emac_start_xmit +#endif /* !defined(CONFIG_IBM_EMAC_TAH) */ + +/* BHs disabled */ +static void emac_parse_tx_error(struct ocp_enet_private *dev, u16 ctrl) +{ + struct ibm_emac_error_stats *st = &dev->estats; + DBG("%d: BD TX error %04x" NL, dev->def->index, ctrl); + + ++st->tx_bd_errors; + if (ctrl & EMAC_TX_ST_BFCS) + ++st->tx_bd_bad_fcs; + if (ctrl & EMAC_TX_ST_LCS) + ++st->tx_bd_carrier_loss; + if (ctrl & EMAC_TX_ST_ED) + ++st->tx_bd_excessive_deferral; + if (ctrl & EMAC_TX_ST_EC) + ++st->tx_bd_excessive_collisions; + if (ctrl & EMAC_TX_ST_LC) + ++st->tx_bd_late_collision; + if (ctrl & EMAC_TX_ST_MC) + ++st->tx_bd_multple_collisions; + if (ctrl & EMAC_TX_ST_SC) + ++st->tx_bd_single_collision; + if (ctrl & EMAC_TX_ST_UR) + ++st->tx_bd_underrun; + if (ctrl & EMAC_TX_ST_SQE) + ++st->tx_bd_sqe; +} + +static void emac_poll_tx(void *param) +{ + struct ocp_enet_private *dev = param; + DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt, + dev->ack_slot); + + if (dev->tx_cnt) { + u16 ctrl; + int slot = dev->ack_slot, n = 0; + again: + ctrl = dev->tx_desc[slot].ctrl; + if (!(ctrl & MAL_TX_CTRL_READY)) { + struct sk_buff *skb = dev->tx_skb[slot]; + ++n; + + if (skb) { + dev_kfree_skb(skb); + dev->tx_skb[slot] = NULL; + } + slot = (slot + 1) % NUM_TX_BUFF; + + if (unlikely(EMAC_IS_BAD_TX(ctrl))) + emac_parse_tx_error(dev, ctrl); + + if (--dev->tx_cnt) + goto again; + } + if (n) { + dev->ack_slot = slot; + if (netif_queue_stopped(dev->ndev) && + dev->tx_cnt < EMAC_TX_WAKEUP_THRESH) + netif_wake_queue(dev->ndev); + + DBG2("%d: tx %d pkts" NL, dev->def->index, n); + } + } +} + +static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot, + int len) +{ + struct sk_buff *skb = dev->rx_skb[slot]; + DBG2("%d: recycle %d %d" NL, dev->def->index, slot, len); + + if (len) + dma_map_single(dev->ldev, skb->data - 2, + EMAC_DMA_ALIGN(len + 2), DMA_FROM_DEVICE); + + dev->rx_desc[slot].data_len = 0; + barrier(); + dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY | + (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0); +} + +static void emac_parse_rx_error(struct ocp_enet_private *dev, u16 ctrl) +{ + struct ibm_emac_error_stats *st = &dev->estats; + DBG("%d: BD RX error %04x" NL, dev->def->index, ctrl); + + ++st->rx_bd_errors; + if (ctrl & EMAC_RX_ST_OE) + ++st->rx_bd_overrun; + if (ctrl & EMAC_RX_ST_BP) + ++st->rx_bd_bad_packet; + if (ctrl & EMAC_RX_ST_RP) + ++st->rx_bd_runt_packet; + if (ctrl & EMAC_RX_ST_SE) + ++st->rx_bd_short_event; + if (ctrl & EMAC_RX_ST_AE) + ++st->rx_bd_alignment_error; + if (ctrl & EMAC_RX_ST_BFCS) + ++st->rx_bd_bad_fcs; + if (ctrl & EMAC_RX_ST_PTL) + ++st->rx_bd_packet_too_long; + if (ctrl & EMAC_RX_ST_ORE) + ++st->rx_bd_out_of_range; + if (ctrl & EMAC_RX_ST_IRE) + ++st->rx_bd_in_range; +} + +static inline void emac_rx_csum(struct ocp_enet_private *dev, + struct sk_buff *skb, u16 ctrl) +{ +#if defined(CONFIG_IBM_EMAC_TAH) + if (!ctrl && dev->tah_dev) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + ++dev->stats.rx_packets_csum; + } +#endif +} + +static inline int emac_rx_sg_append(struct ocp_enet_private *dev, int slot) +{ + if (likely(dev->rx_sg_skb != NULL)) { + int len = dev->rx_desc[slot].data_len; + int tot_len = dev->rx_sg_skb->len + len; + + if (unlikely(tot_len + 2 > dev->rx_skb_size)) { + ++dev->estats.rx_dropped_mtu; + dev_kfree_skb(dev->rx_sg_skb); + dev->rx_sg_skb = NULL; + } else { + cacheable_memcpy(dev->rx_sg_skb->tail, + dev->rx_skb[slot]->data, len); + skb_put(dev->rx_sg_skb, len); + emac_recycle_rx_skb(dev, slot, len); + return 0; + } + } + emac_recycle_rx_skb(dev, slot, 0); + return -1; +} + +/* BHs disabled */ +static int emac_poll_rx(void *param, int budget) +{ + struct ocp_enet_private *dev = param; + int slot = dev->rx_slot, received = 0; + + DBG2("%d: poll_rx(%d)" NL, dev->def->index, budget); + + again: + while (budget > 0) { + int len; + struct sk_buff *skb; + u16 ctrl = dev->rx_desc[slot].ctrl; + + if (ctrl & MAL_RX_CTRL_EMPTY) + break; + + skb = dev->rx_skb[slot]; + barrier(); + len = dev->rx_desc[slot].data_len; + + if (unlikely(!MAL_IS_SINGLE_RX(ctrl))) + goto sg; + + ctrl &= EMAC_BAD_RX_MASK; + if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) { + emac_parse_rx_error(dev, ctrl); + ++dev->estats.rx_dropped_error; + emac_recycle_rx_skb(dev, slot, 0); + len = 0; + goto next; + } + + if (len && len < EMAC_RX_COPY_THRESH) { + struct sk_buff *copy_skb = + alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC); + if (unlikely(!copy_skb)) + goto oom; + + skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2); + cacheable_memcpy(copy_skb->data - 2, skb->data - 2, + len + 2); + emac_recycle_rx_skb(dev, slot, len); + skb = copy_skb; + } else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) + goto oom; + + skb_put(skb, len); + push_packet: + skb->dev = dev->ndev; + skb->protocol = eth_type_trans(skb, dev->ndev); + emac_rx_csum(dev, skb, ctrl); + + if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) + ++dev->estats.rx_dropped_stack; + next: + ++dev->stats.rx_packets; + skip: + dev->stats.rx_bytes += len; + slot = (slot + 1) % NUM_RX_BUFF; + --budget; + ++received; + continue; + sg: + if (ctrl & MAL_RX_CTRL_FIRST) { + BUG_ON(dev->rx_sg_skb); + if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) { + DBG("%d: rx OOM %d" NL, dev->def->index, slot); + ++dev->estats.rx_dropped_oom; + emac_recycle_rx_skb(dev, slot, 0); + } else { + dev->rx_sg_skb = skb; + skb_put(skb, len); + } + } else if (!emac_rx_sg_append(dev, slot) && + (ctrl & MAL_RX_CTRL_LAST)) { + + skb = dev->rx_sg_skb; + dev->rx_sg_skb = NULL; + + ctrl &= EMAC_BAD_RX_MASK; + if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) { + emac_parse_rx_error(dev, ctrl); + ++dev->estats.rx_dropped_error; + dev_kfree_skb(skb); + len = 0; + } else + goto push_packet; + } + goto skip; + oom: + DBG("%d: rx OOM %d" NL, dev->def->index, slot); + /* Drop the packet and recycle skb */ + ++dev->estats.rx_dropped_oom; + emac_recycle_rx_skb(dev, slot, 0); + goto next; + } + + if (received) { + DBG2("%d: rx %d BDs" NL, dev->def->index, received); + dev->rx_slot = slot; + } + + if (unlikely(budget && dev->commac.rx_stopped)) { + struct ocp_func_emac_data *emacdata = dev->def->additions; + + barrier(); + if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) { + DBG2("%d: rx restart" NL, dev->def->index); + received = 0; + goto again; + } + + if (dev->rx_sg_skb) { + DBG2("%d: dropping partial rx packet" NL, + dev->def->index); + ++dev->estats.rx_dropped_error; + dev_kfree_skb(dev->rx_sg_skb); + dev->rx_sg_skb = NULL; + } + + dev->commac.rx_stopped = 0; + mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan); + emac_rx_enable(dev); + dev->rx_slot = 0; + } + return received; +} + +/* BHs disabled */ +static int emac_peek_rx(void *param) +{ + struct ocp_enet_private *dev = param; + return !(dev->rx_desc[dev->rx_slot].ctrl & MAL_RX_CTRL_EMPTY); +} + +/* BHs disabled */ +static int emac_peek_rx_sg(void *param) +{ + struct ocp_enet_private *dev = param; + int slot = dev->rx_slot; + while (1) { + u16 ctrl = dev->rx_desc[slot].ctrl; + if (ctrl & MAL_RX_CTRL_EMPTY) + return 0; + else if (ctrl & MAL_RX_CTRL_LAST) + return 1; + + slot = (slot + 1) % NUM_RX_BUFF; + + /* I'm just being paranoid here :) */ + if (unlikely(slot == dev->rx_slot)) + return 0; + } +} + +/* Hard IRQ */ +static void emac_rxde(void *param) +{ + struct ocp_enet_private *dev = param; + ++dev->estats.rx_stopped; + emac_rx_disable_async(dev); +} + +/* Hard IRQ */ +static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ocp_enet_private *dev = dev_instance; + struct emac_regs *p = dev->emacp; + struct ibm_emac_error_stats *st = &dev->estats; + + u32 isr = in_be32(&p->isr); + out_be32(&p->isr, isr); + + DBG("%d: isr = %08x" NL, dev->def->index, isr); + + if (isr & EMAC_ISR_TXPE) + ++st->tx_parity; + if (isr & EMAC_ISR_RXPE) + ++st->rx_parity; + if (isr & EMAC_ISR_TXUE) + ++st->tx_underrun; + if (isr & EMAC_ISR_RXOE) + ++st->rx_fifo_overrun; + if (isr & EMAC_ISR_OVR) + ++st->rx_overrun; + if (isr & EMAC_ISR_BP) + ++st->rx_bad_packet; + if (isr & EMAC_ISR_RP) + ++st->rx_runt_packet; + if (isr & EMAC_ISR_SE) + ++st->rx_short_event; + if (isr & EMAC_ISR_ALE) + ++st->rx_alignment_error; + if (isr & EMAC_ISR_BFCS) + ++st->rx_bad_fcs; + if (isr & EMAC_ISR_PTLE) + ++st->rx_packet_too_long; + if (isr & EMAC_ISR_ORE) + ++st->rx_out_of_range; + if (isr & EMAC_ISR_IRE) + ++st->rx_in_range; + if (isr & EMAC_ISR_SQE) + ++st->tx_sqe; + if (isr & EMAC_ISR_TE) + ++st->tx_errors; return IRQ_HANDLED; } -static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) +static struct net_device_stats *emac_stats(struct net_device *ndev) { - unsigned short ctrl; - unsigned long flags; - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - int len = skb->len; - unsigned int offset = 0, size, f, tx_slot_first; - unsigned int nr_frags = skb_shinfo(skb)->nr_frags; + struct ocp_enet_private *dev = ndev->priv; + struct ibm_emac_stats *st = &dev->stats; + struct ibm_emac_error_stats *est = &dev->estats; + struct net_device_stats *nst = &dev->nstats; - spin_lock_irqsave(&fep->lock, flags); + DBG2("%d: stats" NL, dev->def->index); - len -= skb->data_len; + /* Compute "legacy" statistics */ + local_irq_disable(); + nst->rx_packets = (unsigned long)st->rx_packets; + nst->rx_bytes = (unsigned long)st->rx_bytes; + nst->tx_packets = (unsigned long)st->tx_packets; + nst->tx_bytes = (unsigned long)st->tx_bytes; + nst->rx_dropped = (unsigned long)(est->rx_dropped_oom + + est->rx_dropped_error + + est->rx_dropped_resize + + est->rx_dropped_mtu); + nst->tx_dropped = (unsigned long)est->tx_dropped; - if ((fep->tx_cnt + nr_frags + len / DESC_BUF_SIZE + 1) > NUM_TX_BUFF) { - PKT_DEBUG(("emac_start_xmit() stopping queue\n")); - netif_stop_queue(dev); - spin_unlock_irqrestore(&fep->lock, flags); - return -EBUSY; - } + nst->rx_errors = (unsigned long)est->rx_bd_errors; + nst->rx_fifo_errors = (unsigned long)(est->rx_bd_overrun + + est->rx_fifo_overrun + + est->rx_overrun); + nst->rx_frame_errors = (unsigned long)(est->rx_bd_alignment_error + + est->rx_alignment_error); + nst->rx_crc_errors = (unsigned long)(est->rx_bd_bad_fcs + + est->rx_bad_fcs); + nst->rx_length_errors = (unsigned long)(est->rx_bd_runt_packet + + est->rx_bd_short_event + + est->rx_bd_packet_too_long + + est->rx_bd_out_of_range + + est->rx_bd_in_range + + est->rx_runt_packet + + est->rx_short_event + + est->rx_packet_too_long + + est->rx_out_of_range + + est->rx_in_range); - tx_slot_first = fep->tx_slot; - - while (len) { - size = min(len, DESC_BUF_SIZE); - - fep->tx_desc[fep->tx_slot].data_len = (short)size; - fep->tx_desc[fep->tx_slot].data_ptr = - (unsigned char *)dma_map_single(&fep->ocpdev->dev, - (void *)((unsigned int)skb-> - data + offset), - size, DMA_TO_DEVICE); - - ctrl = EMAC_TX_CTRL_DFLT; - if (fep->tx_slot != tx_slot_first) - ctrl |= MAL_TX_CTRL_READY; - if ((NUM_TX_BUFF - 1) == fep->tx_slot) - ctrl |= MAL_TX_CTRL_WRAP; - if (!nr_frags && (len == size)) { - ctrl |= MAL_TX_CTRL_LAST; - fep->tx_skb[fep->tx_slot] = skb; - } - if (skb->ip_summed == CHECKSUM_HW) - ctrl |= EMAC_TX_CTRL_TAH_CSUM; - - fep->tx_desc[fep->tx_slot].ctrl = ctrl; - - len -= size; - offset += size; - - /* Bump tx count */ - if (++fep->tx_cnt == NUM_TX_BUFF) - netif_stop_queue(dev); - - /* Next descriptor */ - if (++fep->tx_slot == NUM_TX_BUFF) - fep->tx_slot = 0; - } - - for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; - - frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; - offset = 0; - - while (len) { - size = min(len, DESC_BUF_SIZE); - - dma_map_page(&fep->ocpdev->dev, - frag->page, - frag->page_offset + offset, - size, DMA_TO_DEVICE); - - ctrl = EMAC_TX_CTRL_DFLT | MAL_TX_CTRL_READY; - if ((NUM_TX_BUFF - 1) == fep->tx_slot) - ctrl |= MAL_TX_CTRL_WRAP; - if ((f == (nr_frags - 1)) && (len == size)) { - ctrl |= MAL_TX_CTRL_LAST; - fep->tx_skb[fep->tx_slot] = skb; - } - - if (skb->ip_summed == CHECKSUM_HW) - ctrl |= EMAC_TX_CTRL_TAH_CSUM; - - fep->tx_desc[fep->tx_slot].data_len = (short)size; - fep->tx_desc[fep->tx_slot].data_ptr = - (char *)((page_to_pfn(frag->page) << PAGE_SHIFT) + - frag->page_offset + offset); - fep->tx_desc[fep->tx_slot].ctrl = ctrl; - - len -= size; - offset += size; - - /* Bump tx count */ - if (++fep->tx_cnt == NUM_TX_BUFF) - netif_stop_queue(dev); - - /* Next descriptor */ - if (++fep->tx_slot == NUM_TX_BUFF) - fep->tx_slot = 0; - } - } - - /* - * Deferred set READY on first descriptor of packet to - * avoid TX MAL race. - */ - fep->tx_desc[tx_slot_first].ctrl |= MAL_TX_CTRL_READY; - - /* Send the packet out. */ - out_be32(&emacp->em0tmr0, EMAC_TMR0_XMIT); - - fep->stats.tx_packets++; - fep->stats.tx_bytes += skb->len; - - PKT_DEBUG(("emac_start_xmit() exitn")); - - spin_unlock_irqrestore(&fep->lock, flags); - - return 0; + nst->tx_errors = (unsigned long)(est->tx_bd_errors + est->tx_errors); + nst->tx_fifo_errors = (unsigned long)(est->tx_bd_underrun + + est->tx_underrun); + nst->tx_carrier_errors = (unsigned long)est->tx_bd_carrier_loss; + nst->collisions = (unsigned long)(est->tx_bd_excessive_deferral + + est->tx_bd_excessive_collisions + + est->tx_bd_late_collision + + est->tx_bd_multple_collisions); + local_irq_enable(); + return nst; } -static int emac_adjust_to_link(struct ocp_enet_private *fep) +static void emac_remove(struct ocp_device *ocpdev) { - emac_t *emacp = fep->emacp; - unsigned long mode_reg; - int full_duplex, speed; + struct ocp_enet_private *dev = ocp_get_drvdata(ocpdev); - full_duplex = 0; - speed = SPEED_10; + DBG("%d: remove" NL, dev->def->index); - /* set mode register 1 defaults */ - mode_reg = EMAC_M1_DEFAULT; + ocp_set_drvdata(ocpdev, 0); + unregister_netdev(dev->ndev); - /* Read link mode on PHY */ - if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) { - /* If an error occurred, we don't deal with it yet */ - full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL); - speed = fep->phy_mii.speed; - } + tah_fini(dev->tah_dev); + rgmii_fini(dev->rgmii_dev, dev->rgmii_input); + zmii_fini(dev->zmii_dev, dev->zmii_input); + emac_dbg_register(dev->def->index, 0); - /* set speed (default is 10Mb) */ - switch (speed) { - case SPEED_1000: - mode_reg |= EMAC_M1_RFS_16K; - if (fep->rgmii_dev) { - struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev); - - if ((rgmii->mode[fep->rgmii_input] == RTBI) - || (rgmii->mode[fep->rgmii_input] == TBI)) - mode_reg |= EMAC_M1_MF_1000GPCS; - else - mode_reg |= EMAC_M1_MF_1000MBPS; - - emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input, - 1000); - } - break; - case SPEED_100: - mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K; - if (fep->rgmii_dev) - emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input, - 100); - if (fep->zmii_dev) - emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, - 100); - break; - case SPEED_10: - default: - mode_reg = (mode_reg & ~EMAC_M1_MF_100MBPS) | EMAC_M1_RFS_4K; - if (fep->rgmii_dev) - emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input, - 10); - if (fep->zmii_dev) - emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, - 10); - } - - if (full_duplex) - mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST; - else - mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE); - - LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n", - fep->ndev->name, speed, full_duplex, fep->opened)); - - printk(KERN_INFO "%s: Speed: %d, %s duplex.\n", - fep->ndev->name, speed, full_duplex ? "Full" : "Half"); - if (fep->opened) - out_be32(&emacp->em0mr1, mode_reg); - - return 0; + mal_unregister_commac(dev->mal, &dev->commac); + iounmap((void *)dev->emacp); + kfree(dev->ndev); } -static int emac_set_mac_address(struct net_device *ndev, void *p) +static struct mal_commac_ops emac_commac_ops = { + .poll_tx = &emac_poll_tx, + .poll_rx = &emac_poll_rx, + .peek_rx = &emac_peek_rx, + .rxde = &emac_rxde, +}; + +static struct mal_commac_ops emac_commac_sg_ops = { + .poll_tx = &emac_poll_tx, + .poll_rx = &emac_poll_rx, + .peek_rx = &emac_peek_rx_sg, + .rxde = &emac_rxde, +}; + +/* Ethtool support */ +static int emac_ethtool_get_settings(struct net_device *ndev, + struct ethtool_cmd *cmd) { - struct ocp_enet_private *fep = ndev->priv; - emac_t *emacp = fep->emacp; - struct sockaddr *addr = p; + struct ocp_enet_private *dev = ndev->priv; - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); - - /* set the high address */ - out_be32(&emacp->em0iahr, - (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]); - - /* set the low address */ - out_be32(&emacp->em0ialr, - (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16) - | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]); - - return 0; -} - -static int emac_change_mtu(struct net_device *dev, int new_mtu) -{ - struct ocp_enet_private *fep = dev->priv; - int old_mtu = dev->mtu; - unsigned long mode_reg; - emac_t *emacp = fep->emacp; - u32 em0mr0; - int i, full; - unsigned long flags; - - if ((new_mtu < EMAC_MIN_MTU) || (new_mtu > EMAC_MAX_MTU)) { - printk(KERN_ERR - "emac: Invalid MTU setting, MTU must be between %d and %d\n", - EMAC_MIN_MTU, EMAC_MAX_MTU); - return -EINVAL; - } - - if (old_mtu != new_mtu && netif_running(dev)) { - /* Stop rx engine */ - em0mr0 = in_be32(&emacp->em0mr0); - out_be32(&emacp->em0mr0, em0mr0 & ~EMAC_M0_RXE); - - /* Wait for descriptors to be empty */ - do { - full = 0; - for (i = 0; i < NUM_RX_BUFF; i++) - if (!(fep->rx_desc[i].ctrl & MAL_RX_CTRL_EMPTY)) { - printk(KERN_NOTICE - "emac: RX ring is still full\n"); - full = 1; - } - } while (full); - - spin_lock_irqsave(&fep->lock, flags); - - mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - - /* Destroy all old rx skbs */ - for (i = 0; i < NUM_RX_BUFF; i++) { - dma_unmap_single(&fep->ocpdev->dev, - fep->rx_desc[i].data_ptr, - fep->rx_desc[i].data_len, - DMA_FROM_DEVICE); - dev_kfree_skb(fep->rx_skb[i]); - fep->rx_skb[i] = NULL; - } - - /* Set new rx_buffer_size, jumbo cap, and advertise new mtu */ - mode_reg = in_be32(&emacp->em0mr1); - if (new_mtu > ENET_DEF_MTU_SIZE) { - mode_reg |= EMAC_M1_JUMBO_ENABLE; - fep->rx_buffer_size = EMAC_MAX_FRAME; - } else { - mode_reg &= ~EMAC_M1_JUMBO_ENABLE; - fep->rx_buffer_size = ENET_DEF_BUF_SIZE; - } - dev->mtu = new_mtu; - out_be32(&emacp->em0mr1, mode_reg); - - /* Re-init rx skbs */ - fep->rx_slot = 0; - emac_rx_fill(dev, 0); - - /* Restart the rx engine */ - mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - out_be32(&emacp->em0mr0, em0mr0 | EMAC_M0_RXE); - - spin_unlock_irqrestore(&fep->lock, flags); - } - - return 0; -} - -static void __emac_set_multicast_list(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - u32 rmr = in_be32(&emacp->em0rmr); - - /* First clear all special bits, they can be set later */ - rmr &= ~(EMAC_RMR_PME | EMAC_RMR_PMME | EMAC_RMR_MAE); - - if (dev->flags & IFF_PROMISC) { - rmr |= EMAC_RMR_PME; - } else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) { - /* - * Must be setting up to use multicast - * Now check for promiscuous multicast - */ - rmr |= EMAC_RMR_PMME; - } else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) { - unsigned short em0gaht[4] = { 0, 0, 0, 0 }; - struct dev_mc_list *dmi; - - /* Need to hash on the multicast address. */ - for (dmi = dev->mc_list; dmi; dmi = dmi->next) { - unsigned long mc_crc; - unsigned int bit_number; - - mc_crc = ether_crc(6, (char *)dmi->dmi_addr); - bit_number = 63 - (mc_crc >> 26); /* MSB: 0 LSB: 63 */ - em0gaht[bit_number >> 4] |= - 0x8000 >> (bit_number & 0x0f); - } - emacp->em0gaht1 = em0gaht[0]; - emacp->em0gaht2 = em0gaht[1]; - emacp->em0gaht3 = em0gaht[2]; - emacp->em0gaht4 = em0gaht[3]; - - /* Turn on multicast addressing */ - rmr |= EMAC_RMR_MAE; - } - out_be32(&emacp->em0rmr, rmr); -} - -static int emac_init_tah(struct ocp_enet_private *fep) -{ - tah_t *tahp; - - /* Initialize TAH and enable checksum verification */ - tahp = (tah_t *) ioremap(fep->tah_dev->def->paddr, sizeof(*tahp)); - - if (tahp == NULL) { - printk(KERN_ERR "tah%d: Cannot ioremap TAH registers!\n", - fep->tah_dev->def->index); - - return -ENOMEM; - } - - out_be32(&tahp->tah_mr, TAH_MR_SR); - - /* wait for reset to complete */ - while (in_be32(&tahp->tah_mr) & TAH_MR_SR) ; - - /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ - out_be32(&tahp->tah_mr, - TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | - TAH_MR_DIG); - - iounmap(tahp); - - return 0; -} - -static void emac_init_rings(struct net_device *dev) -{ - struct ocp_enet_private *ep = dev->priv; - int loop; - - ep->tx_desc = (struct mal_descriptor *)((char *)ep->mal->tx_virt_addr + - (ep->mal_tx_chan * - MAL_DT_ALIGN)); - ep->rx_desc = - (struct mal_descriptor *)((char *)ep->mal->rx_virt_addr + - (ep->mal_rx_chan * MAL_DT_ALIGN)); - - /* Fill in the transmit descriptor ring. */ - for (loop = 0; loop < NUM_TX_BUFF; loop++) { - if (ep->tx_skb[loop]) { - dma_unmap_single(&ep->ocpdev->dev, - ep->tx_desc[loop].data_ptr, - ep->tx_desc[loop].data_len, - DMA_TO_DEVICE); - dev_kfree_skb_irq(ep->tx_skb[loop]); - } - ep->tx_skb[loop] = NULL; - ep->tx_desc[loop].ctrl = 0; - ep->tx_desc[loop].data_len = 0; - ep->tx_desc[loop].data_ptr = NULL; - } - ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP; - - /* Format the receive descriptor ring. */ - ep->rx_slot = 0; - /* Default is MTU=1500 + Ethernet overhead */ - ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE; - emac_rx_fill(dev, 0); - if (ep->rx_slot != 0) { - printk(KERN_ERR - "%s: Not enough mem for RxChain durning Open?\n", - dev->name); - /*We couldn't fill the ring at startup? - *We could clean up and fail to open but right now we will try to - *carry on. It may be a sign of a bad NUM_RX_BUFF value - */ - } - - ep->tx_cnt = 0; - ep->tx_slot = 0; - ep->ack_slot = 0; -} - -static void emac_reset_configure(struct ocp_enet_private *fep) -{ - emac_t *emacp = fep->emacp; - int i; - - mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask); - mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - - /* - * Check for a link, some PHYs don't provide a clock if - * no link is present. Some EMACs will not come out of - * soft reset without a PHY clock present. - */ - if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) { - /* Reset the EMAC */ - out_be32(&emacp->em0mr0, EMAC_M0_SRST); - udelay(20); - for (i = 0; i < 100; i++) { - if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0) - break; - udelay(10); - } - - if (i >= 100) { - printk(KERN_ERR "%s: Cannot reset EMAC\n", - fep->ndev->name); - return; - } - } - - /* Switch IRQs off for now */ - out_be32(&emacp->em0iser, 0); - - /* Configure MAL rx channel */ - mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG); - - /* set the high address */ - out_be32(&emacp->em0iahr, - (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]); - - /* set the low address */ - out_be32(&emacp->em0ialr, - (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16) - | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]); - - /* Adjust to link */ - if (netif_carrier_ok(fep->ndev)) - emac_adjust_to_link(fep); - - /* enable broadcast/individual address and RX FIFO defaults */ - out_be32(&emacp->em0rmr, EMAC_RMR_DEFAULT); - - /* set transmit request threshold register */ - out_be32(&emacp->em0trtr, EMAC_TRTR_DEFAULT); - - /* Reconfigure multicast */ - __emac_set_multicast_list(fep->ndev); - - /* Set receiver/transmitter defaults */ - out_be32(&emacp->em0rwmr, EMAC_RWMR_DEFAULT); - out_be32(&emacp->em0tmr0, EMAC_TMR0_DEFAULT); - out_be32(&emacp->em0tmr1, EMAC_TMR1_DEFAULT); - - /* set frame gap */ - out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP); - - /* set VLAN Tag Protocol Identifier */ - out_be32(&emacp->em0vtpid, 0x8100); - - /* Init ring buffers */ - emac_init_rings(fep->ndev); -} - -static void emac_kick(struct ocp_enet_private *fep) -{ - emac_t *emacp = fep->emacp; - unsigned long emac_ier; - - emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP | - EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE | - EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE; - - out_be32(&emacp->em0iser, emac_ier); - - /* enable all MAL transmit and receive channels */ - mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); - mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - - /* set transmit and receive enable */ - out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE); -} - -static void -emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep) -{ - u32 advertise; - int autoneg; - int forced_speed; - int forced_duplex; - - /* Default advertise */ - advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full; - autoneg = fep->want_autoneg; - forced_speed = fep->phy_mii.speed; - forced_duplex = fep->phy_mii.duplex; - - /* Setup link parameters */ - if (ep) { - if (ep->autoneg == AUTONEG_ENABLE) { - advertise = ep->advertising; - autoneg = 1; - } else { - autoneg = 0; - forced_speed = ep->speed; - forced_duplex = ep->duplex; - } - } - - /* Configure PHY & start aneg */ - fep->want_autoneg = autoneg; - if (autoneg) { - LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n", - fep->ndev->name, advertise)); - fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise); - } else { - LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n", - fep->ndev->name, forced_speed, forced_duplex)); - fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed, - forced_duplex); - } - fep->timer_ticks = 0; - mod_timer(&fep->link_timer, jiffies + HZ); -} - -static void emac_link_timer(unsigned long data) -{ - struct ocp_enet_private *fep = (struct ocp_enet_private *)data; - int link; - - if (fep->going_away) - return; - - spin_lock_irq(&fep->lock); - - link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii); - LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link)); - - if (link == netif_carrier_ok(fep->ndev)) { - if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10) - emac_start_link(fep, NULL); - goto out; - } - printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name, - link ? "Up" : "Down"); - if (link) { - netif_carrier_on(fep->ndev); - /* Chip needs a full reset on config change. That sucks, so I - * should ultimately move that to some tasklet to limit - * latency peaks caused by this code - */ - emac_reset_configure(fep); - if (fep->opened) - emac_kick(fep); - } else { - fep->timer_ticks = 0; - netif_carrier_off(fep->ndev); - } - out: - mod_timer(&fep->link_timer, jiffies + HZ); - spin_unlock_irq(&fep->lock); -} - -static void emac_set_multicast_list(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - - spin_lock_irq(&fep->lock); - __emac_set_multicast_list(dev); - spin_unlock_irq(&fep->lock); -} - -static int emac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) -{ - struct ocp_enet_private *fep = ndev->priv; - - cmd->supported = fep->phy_mii.def->features; + cmd->supported = dev->phy.features; cmd->port = PORT_MII; - cmd->transceiver = XCVR_EXTERNAL; - cmd->phy_address = fep->mii_phy_addr; - spin_lock_irq(&fep->lock); - cmd->autoneg = fep->want_autoneg; - cmd->speed = fep->phy_mii.speed; - cmd->duplex = fep->phy_mii.duplex; - spin_unlock_irq(&fep->lock); + cmd->phy_address = dev->phy.address; + cmd->transceiver = + dev->phy.address >= 0 ? XCVR_EXTERNAL : XCVR_INTERNAL; + + local_bh_disable(); + cmd->advertising = dev->phy.advertising; + cmd->autoneg = dev->phy.autoneg; + cmd->speed = dev->phy.speed; + cmd->duplex = dev->phy.duplex; + local_bh_enable(); + return 0; } -static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) +static int emac_ethtool_set_settings(struct net_device *ndev, + struct ethtool_cmd *cmd) { - struct ocp_enet_private *fep = ndev->priv; - unsigned long features = fep->phy_mii.def->features; + struct ocp_enet_private *dev = ndev->priv; + u32 f = dev->phy.features; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; + DBG("%d: set_settings(%d, %d, %d, 0x%08x)" NL, dev->def->index, + cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising); + /* Basic sanity checks */ + if (dev->phy.address < 0) + return -EOPNOTSUPP; if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) return -EINVAL; if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) return -EINVAL; if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) return -EINVAL; - if (cmd->autoneg == AUTONEG_DISABLE) + + if (cmd->autoneg == AUTONEG_DISABLE) { switch (cmd->speed) { case SPEED_10: - if (cmd->duplex == DUPLEX_HALF && - (features & SUPPORTED_10baseT_Half) == 0) + if (cmd->duplex == DUPLEX_HALF + && !(f & SUPPORTED_10baseT_Half)) return -EINVAL; - if (cmd->duplex == DUPLEX_FULL && - (features & SUPPORTED_10baseT_Full) == 0) + if (cmd->duplex == DUPLEX_FULL + && !(f & SUPPORTED_10baseT_Full)) return -EINVAL; break; case SPEED_100: - if (cmd->duplex == DUPLEX_HALF && - (features & SUPPORTED_100baseT_Half) == 0) + if (cmd->duplex == DUPLEX_HALF + && !(f & SUPPORTED_100baseT_Half)) return -EINVAL; - if (cmd->duplex == DUPLEX_FULL && - (features & SUPPORTED_100baseT_Full) == 0) + if (cmd->duplex == DUPLEX_FULL + && !(f & SUPPORTED_100baseT_Full)) return -EINVAL; break; case SPEED_1000: - if (cmd->duplex == DUPLEX_HALF && - (features & SUPPORTED_1000baseT_Half) == 0) + if (cmd->duplex == DUPLEX_HALF + && !(f & SUPPORTED_1000baseT_Half)) return -EINVAL; - if (cmd->duplex == DUPLEX_FULL && - (features & SUPPORTED_1000baseT_Full) == 0) + if (cmd->duplex == DUPLEX_FULL + && !(f & SUPPORTED_1000baseT_Full)) return -EINVAL; break; default: return -EINVAL; - } else if ((features & SUPPORTED_Autoneg) == 0) - return -EINVAL; - spin_lock_irq(&fep->lock); - emac_start_link(fep, cmd); - spin_unlock_irq(&fep->lock); + } + + local_bh_disable(); + dev->phy.def->ops->setup_forced(&dev->phy, cmd->speed, + cmd->duplex); + + } else { + if (!(f & SUPPORTED_Autoneg)) + return -EINVAL; + + local_bh_disable(); + dev->phy.def->ops->setup_aneg(&dev->phy, + (cmd->advertising & f) | + (dev->phy.advertising & + (ADVERTISED_Pause | + ADVERTISED_Asym_Pause))); + } + emac_force_link_update(dev); + local_bh_enable(); + return 0; } -static void -emac_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) +static void emac_ethtool_get_ringparam(struct net_device *ndev, + struct ethtool_ringparam *rp) { - struct ocp_enet_private *fep = ndev->priv; + rp->rx_max_pending = rp->rx_pending = NUM_RX_BUFF; + rp->tx_max_pending = rp->tx_pending = NUM_TX_BUFF; +} - strcpy(info->driver, DRV_NAME); +static void emac_ethtool_get_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *pp) +{ + struct ocp_enet_private *dev = ndev->priv; + + local_bh_disable(); + if ((dev->phy.features & SUPPORTED_Autoneg) && + (dev->phy.advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause))) + pp->autoneg = 1; + + if (dev->phy.duplex == DUPLEX_FULL) { + if (dev->phy.pause) + pp->rx_pause = pp->tx_pause = 1; + else if (dev->phy.asym_pause) + pp->tx_pause = 1; + } + local_bh_enable(); +} + +static u32 emac_ethtool_get_rx_csum(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + return dev->tah_dev != 0; +} + +static int emac_get_regs_len(struct ocp_enet_private *dev) +{ + return sizeof(struct emac_ethtool_regs_subhdr) + EMAC_ETHTOOL_REGS_SIZE; +} + +static int emac_ethtool_get_regs_len(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + return sizeof(struct emac_ethtool_regs_hdr) + + emac_get_regs_len(dev) + mal_get_regs_len(dev->mal) + + zmii_get_regs_len(dev->zmii_dev) + + rgmii_get_regs_len(dev->rgmii_dev) + + tah_get_regs_len(dev->tah_dev); +} + +static void *emac_dump_regs(struct ocp_enet_private *dev, void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + + hdr->version = EMAC_ETHTOOL_REGS_VER; + hdr->index = dev->def->index; + memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE); + return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE); +} + +static void emac_ethtool_get_regs(struct net_device *ndev, + struct ethtool_regs *regs, void *buf) +{ + struct ocp_enet_private *dev = ndev->priv; + struct emac_ethtool_regs_hdr *hdr = buf; + + hdr->components = 0; + buf = hdr + 1; + + local_irq_disable(); + buf = mal_dump_regs(dev->mal, buf); + buf = emac_dump_regs(dev, buf); + if (dev->zmii_dev) { + hdr->components |= EMAC_ETHTOOL_REGS_ZMII; + buf = zmii_dump_regs(dev->zmii_dev, buf); + } + if (dev->rgmii_dev) { + hdr->components |= EMAC_ETHTOOL_REGS_RGMII; + buf = rgmii_dump_regs(dev->rgmii_dev, buf); + } + if (dev->tah_dev) { + hdr->components |= EMAC_ETHTOOL_REGS_TAH; + buf = tah_dump_regs(dev->tah_dev, buf); + } + local_irq_enable(); +} + +static int emac_ethtool_nway_reset(struct net_device *ndev) +{ + struct ocp_enet_private *dev = ndev->priv; + int res = 0; + + DBG("%d: nway_reset" NL, dev->def->index); + + if (dev->phy.address < 0) + return -EOPNOTSUPP; + + local_bh_disable(); + if (!dev->phy.autoneg) { + res = -EINVAL; + goto out; + } + + dev->phy.def->ops->setup_aneg(&dev->phy, dev->phy.advertising); + emac_force_link_update(dev); + + out: + local_bh_enable(); + return res; +} + +static int emac_ethtool_get_stats_count(struct net_device *ndev) +{ + return EMAC_ETHTOOL_STATS_COUNT; +} + +static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset, + u8 * buf) +{ + if (stringset == ETH_SS_STATS) + memcpy(buf, &emac_stats_keys, sizeof(emac_stats_keys)); +} + +static void emac_ethtool_get_ethtool_stats(struct net_device *ndev, + struct ethtool_stats *estats, + u64 * tmp_stats) +{ + struct ocp_enet_private *dev = ndev->priv; + local_irq_disable(); + memcpy(tmp_stats, &dev->stats, sizeof(dev->stats)); + tmp_stats += sizeof(dev->stats) / sizeof(u64); + memcpy(tmp_stats, &dev->estats, sizeof(dev->estats)); + local_irq_enable(); +} + +static void emac_ethtool_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) +{ + struct ocp_enet_private *dev = ndev->priv; + + strcpy(info->driver, "ibm_emac"); strcpy(info->version, DRV_VERSION); info->fw_version[0] = '\0'; - sprintf(info->bus_info, "IBM EMAC %d", fep->ocpdev->def->index); - info->regdump_len = 0; -} - -static int emac_nway_reset(struct net_device *ndev) -{ - struct ocp_enet_private *fep = ndev->priv; - - if (!fep->want_autoneg) - return -EINVAL; - spin_lock_irq(&fep->lock); - emac_start_link(fep, NULL); - spin_unlock_irq(&fep->lock); - return 0; -} - -static u32 emac_get_link(struct net_device *ndev) -{ - return netif_carrier_ok(ndev); + sprintf(info->bus_info, "PPC 4xx EMAC %d", dev->def->index); + info->n_stats = emac_ethtool_get_stats_count(ndev); + info->regdump_len = emac_ethtool_get_regs_len(ndev); } static struct ethtool_ops emac_ethtool_ops = { - .get_settings = emac_get_settings, - .set_settings = emac_set_settings, - .get_drvinfo = emac_get_drvinfo, - .nway_reset = emac_nway_reset, - .get_link = emac_get_link + .get_settings = emac_ethtool_get_settings, + .set_settings = emac_ethtool_set_settings, + .get_drvinfo = emac_ethtool_get_drvinfo, + + .get_regs_len = emac_ethtool_get_regs_len, + .get_regs = emac_ethtool_get_regs, + + .nway_reset = emac_ethtool_nway_reset, + + .get_ringparam = emac_ethtool_get_ringparam, + .get_pauseparam = emac_ethtool_get_pauseparam, + + .get_rx_csum = emac_ethtool_get_rx_csum, + + .get_strings = emac_ethtool_get_strings, + .get_stats_count = emac_ethtool_get_stats_count, + .get_ethtool_stats = emac_ethtool_get_ethtool_stats, + + .get_link = ethtool_op_get_link, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, }; -static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { - struct ocp_enet_private *fep = dev->priv; + struct ocp_enet_private *dev = ndev->priv; uint16_t *data = (uint16_t *) & rq->ifr_ifru; + DBG("%d: ioctl %08x" NL, dev->def->index, cmd); + + if (dev->phy.address < 0) + return -EOPNOTSUPP; + switch (cmd) { case SIOCGMIIPHY: - data[0] = fep->mii_phy_addr; + case SIOCDEVPRIVATE: + data[0] = dev->phy.address; /* Fall through */ case SIOCGMIIREG: - data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]); + case SIOCDEVPRIVATE + 1: + data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]); return 0; + case SIOCSMIIREG: + case SIOCDEVPRIVATE + 2: if (!capable(CAP_NET_ADMIN)) return -EPERM; - - emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]); + emac_mdio_write(ndev, dev->phy.address, data[1], data[2]); return 0; default: return -EOPNOTSUPP; } } -static int emac_open(struct net_device *dev) +static int __init emac_probe(struct ocp_device *ocpdev) { - struct ocp_enet_private *fep = dev->priv; - int rc; - - spin_lock_irq(&fep->lock); - - fep->opened = 1; - netif_carrier_off(dev); - - /* Reset & configure the chip */ - emac_reset_configure(fep); - - spin_unlock_irq(&fep->lock); - - /* Request our interrupt lines */ - rc = request_irq(dev->irq, emac_mac_irq, 0, "IBM EMAC MAC", dev); - if (rc != 0) { - printk("dev->irq %d failed\n", dev->irq); - goto bail; - } - /* Kick the chip rx & tx channels into life */ - spin_lock_irq(&fep->lock); - emac_kick(fep); - spin_unlock_irq(&fep->lock); - - netif_start_queue(dev); - bail: - return rc; -} - -static int emac_close(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - emac_t *emacp = fep->emacp; - - /* XXX Stop IRQ emitting here */ - spin_lock_irq(&fep->lock); - fep->opened = 0; - mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask); - mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); - netif_carrier_off(dev); - netif_stop_queue(dev); - - /* - * Check for a link, some PHYs don't provide a clock if - * no link is present. Some EMACs will not come out of - * soft reset without a PHY clock present. - */ - if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) { - out_be32(&emacp->em0mr0, EMAC_M0_SRST); - udelay(10); - - if (emacp->em0mr0 & EMAC_M0_SRST) { - /*not sure what to do here hopefully it clears before another open */ - printk(KERN_ERR - "%s: Phy SoftReset didn't clear, no link?\n", - dev->name); - } - } - - /* Free the irq's */ - free_irq(dev->irq, dev); - - spin_unlock_irq(&fep->lock); - - return 0; -} - -static void emac_remove(struct ocp_device *ocpdev) -{ - struct net_device *dev = ocp_get_drvdata(ocpdev); - struct ocp_enet_private *ep = dev->priv; - - /* FIXME: locking, races, ... */ - ep->going_away = 1; - ocp_set_drvdata(ocpdev, NULL); - if (ep->rgmii_dev) - emac_close_rgmii(ep->rgmii_dev); - if (ep->zmii_dev) - emac_close_zmii(ep->zmii_dev); - - unregister_netdev(dev); - del_timer_sync(&ep->link_timer); - mal_unregister_commac(ep->mal, &ep->commac); - iounmap((void *)ep->emacp); - kfree(dev); -} - -struct mal_commac_ops emac_commac_ops = { - .txeob = &emac_txeob_dev, - .txde = &emac_txde_dev, - .rxeob = &emac_rxeob_dev, - .rxde = &emac_rxde_dev, -}; - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void emac_netpoll(struct net_device *ndev) -{ - emac_rxeob_dev((void *)ndev, 0); - emac_txeob_dev((void *)ndev, 0); -} -#endif - -static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal) -{ - int deferred_init = 0; - int rc = 0, i; + struct ocp_func_emac_data *emacdata = ocpdev->def->additions; struct net_device *ndev; - struct ocp_enet_private *ep; - struct ocp_func_emac_data *emacdata; - int commac_reg = 0; - u32 phy_map; + struct ocp_device *maldev; + struct ocp_enet_private *dev; + int err, i; + + DBG("%d: probe" NL, ocpdev->def->index); - emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions; if (!emacdata) { printk(KERN_ERR "emac%d: Missing additional data!\n", ocpdev->def->index); @@ -1738,304 +1936,312 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal) /* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct ocp_enet_private)); - if (ndev == NULL) { - printk(KERN_ERR - "emac%d: Could not allocate ethernet device.\n", + if (!ndev) { + printk(KERN_ERR "emac%d: could not allocate ethernet device!\n", ocpdev->def->index); return -ENOMEM; } - ep = ndev->priv; - ep->ndev = ndev; - ep->ocpdev = ocpdev; - ndev->irq = ocpdev->def->irq; - ep->wol_irq = emacdata->wol_irq; - if (emacdata->mdio_idx >= 0) { - if (emacdata->mdio_idx == ocpdev->def->index) { - /* Set the common MDIO net_device */ - mdio_ndev = ndev; - deferred_init = 1; + dev = ndev->priv; + dev->ndev = ndev; + dev->ldev = &ocpdev->dev; + dev->def = ocpdev->def; + SET_MODULE_OWNER(ndev); + + /* Find MAL device we are connected to */ + maldev = + ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_MAL, emacdata->mal_idx); + if (!maldev) { + printk(KERN_ERR "emac%d: unknown mal%d device!\n", + dev->def->index, emacdata->mal_idx); + err = -ENODEV; + goto out; + } + dev->mal = ocp_get_drvdata(maldev); + if (!dev->mal) { + printk(KERN_ERR "emac%d: mal%d hasn't been initialized yet!\n", + dev->def->index, emacdata->mal_idx); + err = -ENODEV; + goto out; + } + + /* Register with MAL */ + dev->commac.ops = &emac_commac_ops; + dev->commac.dev = dev; + dev->commac.tx_chan_mask = MAL_CHAN_MASK(emacdata->mal_tx_chan); + dev->commac.rx_chan_mask = MAL_CHAN_MASK(emacdata->mal_rx_chan); + err = mal_register_commac(dev->mal, &dev->commac); + if (err) { + printk(KERN_ERR "emac%d: failed to register with mal%d!\n", + dev->def->index, emacdata->mal_idx); + goto out; + } + dev->rx_skb_size = emac_rx_skb_size(ndev->mtu); + dev->rx_sync_size = emac_rx_sync_size(ndev->mtu); + + /* Get pointers to BD rings */ + dev->tx_desc = + dev->mal->bd_virt + mal_tx_bd_offset(dev->mal, + emacdata->mal_tx_chan); + dev->rx_desc = + dev->mal->bd_virt + mal_rx_bd_offset(dev->mal, + emacdata->mal_rx_chan); + + DBG("%d: tx_desc %p" NL, ocpdev->def->index, dev->tx_desc); + DBG("%d: rx_desc %p" NL, ocpdev->def->index, dev->rx_desc); + + /* Clean rings */ + memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor)); + memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor)); + + /* If we depend on another EMAC for MDIO, check whether it was probed already */ + if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) { + struct ocp_device *mdiodev = + ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, + emacdata->mdio_idx); + if (!mdiodev) { + printk(KERN_ERR "emac%d: unknown emac%d device!\n", + dev->def->index, emacdata->mdio_idx); + err = -ENODEV; + goto out2; } - ep->mdio_dev = mdio_ndev; - } else { - ep->mdio_dev = ndev; - } - - ocp_set_drvdata(ocpdev, ndev); - - spin_lock_init(&ep->lock); - - /* Fill out MAL informations and register commac */ - ep->mal = mal; - ep->mal_tx_chan = emacdata->mal_tx_chan; - ep->mal_rx_chan = emacdata->mal_rx_chan; - ep->commac.ops = &emac_commac_ops; - ep->commac.dev = ndev; - ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan); - ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan); - rc = mal_register_commac(ep->mal, &ep->commac); - if (rc != 0) - goto bail; - commac_reg = 1; - - /* Map our MMIOs */ - ep->emacp = (emac_t *) ioremap(ocpdev->def->paddr, sizeof(emac_t)); - - /* Check if we need to attach to a ZMII */ - if (emacdata->zmii_idx >= 0) { - ep->zmii_input = emacdata->zmii_mux; - ep->zmii_dev = - ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII, - emacdata->zmii_idx); - if (ep->zmii_dev == NULL) - printk(KERN_WARNING - "emac%d: ZMII %d requested but not found !\n", - ocpdev->def->index, emacdata->zmii_idx); - else if ((rc = - emac_init_zmii(ep->zmii_dev, ep->zmii_input, - emacdata->phy_mode)) != 0) - goto bail; - } - - /* Check if we need to attach to a RGMII */ - if (emacdata->rgmii_idx >= 0) { - ep->rgmii_input = emacdata->rgmii_mux; - ep->rgmii_dev = - ocp_find_device(OCP_ANY_ID, OCP_FUNC_RGMII, - emacdata->rgmii_idx); - if (ep->rgmii_dev == NULL) - printk(KERN_WARNING - "emac%d: RGMII %d requested but not found !\n", - ocpdev->def->index, emacdata->rgmii_idx); - else if ((rc = - emac_init_rgmii(ep->rgmii_dev, ep->rgmii_input, - emacdata->phy_mode)) != 0) - goto bail; - } - - /* Check if we need to attach to a TAH */ - if (emacdata->tah_idx >= 0) { - ep->tah_dev = - ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH, - emacdata->tah_idx); - if (ep->tah_dev == NULL) - printk(KERN_WARNING - "emac%d: TAH %d requested but not found !\n", - ocpdev->def->index, emacdata->tah_idx); - else if ((rc = emac_init_tah(ep)) != 0) - goto bail; - } - - if (deferred_init) { - if (!list_empty(&emac_init_list)) { - struct list_head *entry; - struct emac_def_dev *ddev; - - list_for_each(entry, &emac_init_list) { - ddev = - list_entry(entry, struct emac_def_dev, - link); - emac_init_device(ddev->ocpdev, ddev->mal); - } + dev->mdio_dev = ocp_get_drvdata(mdiodev); + if (!dev->mdio_dev) { + printk(KERN_ERR + "emac%d: emac%d hasn't been initialized yet!\n", + dev->def->index, emacdata->mdio_idx); + err = -ENODEV; + goto out2; } } - /* Init link monitoring timer */ - init_timer(&ep->link_timer); - ep->link_timer.function = emac_link_timer; - ep->link_timer.data = (unsigned long)ep; - ep->timer_ticks = 0; + /* Attach to ZMII, if needed */ + if ((err = zmii_attach(dev)) != 0) + goto out2; - /* Fill up the mii_phy structure */ - ep->phy_mii.dev = ndev; - ep->phy_mii.mdio_read = emac_phy_read; - ep->phy_mii.mdio_write = emac_phy_write; - ep->phy_mii.mode = emacdata->phy_mode; + /* Attach to RGMII, if needed */ + if ((err = rgmii_attach(dev)) != 0) + goto out3; - /* Find PHY */ - phy_map = emacdata->phy_map | busy_phy_map; - for (i = 0; i <= 0x1f; i++, phy_map >>= 1) { - if ((phy_map & 0x1) == 0) { - int val = emac_phy_read(ndev, i, MII_BMCR); - if (val != 0xffff && val != -1) - break; - } - } - if (i == 0x20) { - printk(KERN_WARNING "emac%d: Can't find PHY.\n", - ocpdev->def->index); - rc = -ENODEV; - goto bail; - } - busy_phy_map |= 1 << i; - ep->mii_phy_addr = i; - rc = mii_phy_probe(&ep->phy_mii, i); - if (rc) { - printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n", - ocpdev->def->index); - rc = -ENODEV; - goto bail; - } - - /* Disable any PHY features not supported by the platform */ - ep->phy_mii.def->features &= ~emacdata->phy_feat_exc; + /* Attach to TAH, if needed */ + if ((err = tah_attach(dev)) != 0) + goto out4; - /* Setup initial PHY config & startup aneg */ - if (ep->phy_mii.def->ops->init) - ep->phy_mii.def->ops->init(&ep->phy_mii); - netif_carrier_off(ndev); - if (ep->phy_mii.def->features & SUPPORTED_Autoneg) - ep->want_autoneg = 1; - else { - ep->want_autoneg = 0; - - /* Select highest supported speed/duplex */ - if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) { - ep->phy_mii.speed = SPEED_1000; - ep->phy_mii.duplex = DUPLEX_FULL; - } else if (ep->phy_mii.def->features & - SUPPORTED_1000baseT_Half) { - ep->phy_mii.speed = SPEED_1000; - ep->phy_mii.duplex = DUPLEX_HALF; - } else if (ep->phy_mii.def->features & - SUPPORTED_100baseT_Full) { - ep->phy_mii.speed = SPEED_100; - ep->phy_mii.duplex = DUPLEX_FULL; - } else if (ep->phy_mii.def->features & - SUPPORTED_100baseT_Half) { - ep->phy_mii.speed = SPEED_100; - ep->phy_mii.duplex = DUPLEX_HALF; - } else if (ep->phy_mii.def->features & - SUPPORTED_10baseT_Full) { - ep->phy_mii.speed = SPEED_10; - ep->phy_mii.duplex = DUPLEX_FULL; - } else { - ep->phy_mii.speed = SPEED_10; - ep->phy_mii.duplex = DUPLEX_HALF; - } + /* Map EMAC regs */ + dev->emacp = + (struct emac_regs *)ioremap(dev->def->paddr, + sizeof(struct emac_regs)); + if (!dev->emacp) { + printk(KERN_ERR "emac%d: could not ioremap device registers!\n", + dev->def->index); + err = -ENOMEM; + goto out5; } - emac_start_link(ep, NULL); - /* read the MAC Address */ - for (i = 0; i < 6; i++) + /* Fill in MAC address */ + for (i = 0; i < 6; ++i) ndev->dev_addr[i] = emacdata->mac_addr[i]; + /* Set some link defaults before we can find out real parameters */ + dev->phy.speed = SPEED_100; + dev->phy.duplex = DUPLEX_FULL; + dev->phy.autoneg = AUTONEG_DISABLE; + dev->phy.pause = dev->phy.asym_pause = 0; + init_timer(&dev->link_timer); + dev->link_timer.function = emac_link_timer; + dev->link_timer.data = (unsigned long)dev; + + /* Find PHY if any */ + dev->phy.dev = ndev; + dev->phy.mode = emacdata->phy_mode; + if (emacdata->phy_map != 0xffffffff) { + u32 phy_map = emacdata->phy_map | busy_phy_map; + u32 adv; + + DBG("%d: PHY maps %08x %08x" NL, dev->def->index, + emacdata->phy_map, busy_phy_map); + + EMAC_RX_CLK_TX(dev->def->index); + + dev->phy.mdio_read = emac_mdio_read; + dev->phy.mdio_write = emac_mdio_write; + + /* Configure EMAC with defaults so we can at least use MDIO + * This is needed mostly for 440GX + */ + if (emac_phy_gpcs(dev->phy.mode)) { + /* XXX + * Make GPCS PHY address equal to EMAC index. + * We probably should take into account busy_phy_map + * and/or phy_map here. + */ + dev->phy.address = dev->def->index; + } + + emac_configure(dev); + + for (i = 0; i < 0x20; phy_map >>= 1, ++i) + if (!(phy_map & 1)) { + int r; + busy_phy_map |= 1 << i; + + /* Quick check if there is a PHY at the address */ + r = emac_mdio_read(dev->ndev, i, MII_BMCR); + if (r == 0xffff || r < 0) + continue; + if (!mii_phy_probe(&dev->phy, i)) + break; + } + if (i == 0x20) { + printk(KERN_WARNING "emac%d: can't find PHY!\n", + dev->def->index); + goto out6; + } + + /* Init PHY */ + if (dev->phy.def->ops->init) + dev->phy.def->ops->init(&dev->phy); + + /* Disable any PHY features not supported by the platform */ + dev->phy.def->features &= ~emacdata->phy_feat_exc; + + /* Setup initial link parameters */ + if (dev->phy.features & SUPPORTED_Autoneg) { + adv = dev->phy.features; +#if !defined(CONFIG_40x) + adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause; +#endif + /* Restart autonegotiation */ + dev->phy.def->ops->setup_aneg(&dev->phy, adv); + } else { + u32 f = dev->phy.def->features; + int speed = SPEED_10, fd = DUPLEX_HALF; + + /* Select highest supported speed/duplex */ + if (f & SUPPORTED_1000baseT_Full) { + speed = SPEED_1000; + fd = DUPLEX_FULL; + } else if (f & SUPPORTED_1000baseT_Half) + speed = SPEED_1000; + else if (f & SUPPORTED_100baseT_Full) { + speed = SPEED_100; + fd = DUPLEX_FULL; + } else if (f & SUPPORTED_100baseT_Half) + speed = SPEED_100; + else if (f & SUPPORTED_10baseT_Full) + fd = DUPLEX_FULL; + + /* Force link parameters */ + dev->phy.def->ops->setup_forced(&dev->phy, speed, fd); + } + } else { + emac_reset(dev); + + /* PHY-less configuration. + * XXX I probably should move these settings to emacdata + */ + dev->phy.address = -1; + dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII; + dev->phy.pause = 1; + } + /* Fill in the driver function table */ ndev->open = &emac_open; - ndev->hard_start_xmit = &emac_start_xmit; + if (dev->tah_dev) { + ndev->hard_start_xmit = &emac_start_xmit_sg; + ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; + } else + ndev->hard_start_xmit = &emac_start_xmit; + ndev->tx_timeout = &emac_full_tx_reset; + ndev->watchdog_timeo = 5 * HZ; ndev->stop = &emac_close; ndev->get_stats = &emac_stats; - if (emacdata->jumbo) - ndev->change_mtu = &emac_change_mtu; - ndev->set_mac_address = &emac_set_mac_address; ndev->set_multicast_list = &emac_set_multicast_list; ndev->do_ioctl = &emac_ioctl; + if (emac_phy_supports_gige(emacdata->phy_mode)) { + ndev->change_mtu = &emac_change_mtu; + dev->commac.ops = &emac_commac_sg_ops; + } SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); - if (emacdata->tah_idx >= 0) - ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG; -#ifdef CONFIG_NET_POLL_CONTROLLER - ndev->poll_controller = emac_netpoll; -#endif - SET_MODULE_OWNER(ndev); + netif_carrier_off(ndev); + netif_stop_queue(ndev); - rc = register_netdev(ndev); - if (rc != 0) - goto bail; + err = register_netdev(ndev); + if (err) { + printk(KERN_ERR "emac%d: failed to register net device (%d)!\n", + dev->def->index, err); + goto out6; + } - printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - ndev->name, + ocp_set_drvdata(ocpdev, dev); + + printk("%s: emac%d, MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + ndev->name, dev->def->index, ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); - printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n", - ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr); - bail: - if (rc && commac_reg) - mal_unregister_commac(ep->mal, &ep->commac); - if (rc && ndev) - kfree(ndev); + if (dev->phy.address >= 0) + printk("%s: found %s PHY (0x%02x)\n", ndev->name, + dev->phy.def->name, dev->phy.address); - return rc; -} - -static int emac_probe(struct ocp_device *ocpdev) -{ - struct ocp_device *maldev; - struct ibm_ocp_mal *mal; - struct ocp_func_emac_data *emacdata; - - emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions; - if (emacdata == NULL) { - printk(KERN_ERR "emac%d: Missing additional datas !\n", - ocpdev->def->index); - return -ENODEV; - } - - /* Get the MAL device */ - maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx); - if (maldev == NULL) { - printk("No maldev\n"); - return -ENODEV; - } - /* - * Get MAL driver data, it must be here due to link order. - * When the driver is modularized, symbol dependencies will - * ensure the MAL driver is already present if built as a - * module. - */ - mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev); - if (mal == NULL) { - printk("No maldrv\n"); - return -ENODEV; - } - - /* If we depend on another EMAC for MDIO, wait for it to show up */ - if (emacdata->mdio_idx >= 0 && - (emacdata->mdio_idx != ocpdev->def->index) && !mdio_ndev) { - struct emac_def_dev *ddev; - /* Add this index to the deferred init table */ - ddev = kmalloc(sizeof(struct emac_def_dev), GFP_KERNEL); - ddev->ocpdev = ocpdev; - ddev->mal = mal; - list_add_tail(&ddev->link, &emac_init_list); - } else { - emac_init_device(ocpdev, mal); - } + emac_dbg_register(dev->def->index, dev); return 0; + out6: + iounmap((void *)dev->emacp); + out5: + tah_fini(dev->tah_dev); + out4: + rgmii_fini(dev->rgmii_dev, dev->rgmii_input); + out3: + zmii_fini(dev->zmii_dev, dev->zmii_input); + out2: + mal_unregister_commac(dev->mal, &dev->commac); + out: + kfree(ndev); + return err; } -/* Structure for a device driver */ static struct ocp_device_id emac_ids[] = { - {.vendor = OCP_ANY_ID,.function = OCP_FUNC_EMAC}, - {.vendor = OCP_VENDOR_INVALID} + { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_EMAC }, + { .vendor = OCP_VENDOR_INVALID} }; static struct ocp_driver emac_driver = { .name = "emac", .id_table = emac_ids, - .probe = emac_probe, .remove = emac_remove, }; static int __init emac_init(void) { - printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n"); - printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n"); + printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n"); - if (skb_res > 2) { - printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n", - skb_res); - skb_res = 2; + DBG(": init" NL); + + if (mal_init()) + return -ENODEV; + + EMAC_CLK_INTERNAL; + if (ocp_register_driver(&emac_driver)) { + EMAC_CLK_EXTERNAL; + ocp_unregister_driver(&emac_driver); + mal_exit(); + return -ENODEV; } + EMAC_CLK_EXTERNAL; - return ocp_register_driver(&emac_driver); + emac_init_debug(); + return 0; } static void __exit emac_exit(void) { + DBG(": exit" NL); ocp_unregister_driver(&emac_driver); + mal_exit(); + emac_fini_debug(); } module_init(emac_init); diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index 97e6e1ea8c89..e9b44d030ac3 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h @@ -1,146 +1,221 @@ /* - * ibm_emac_core.h + * drivers/net/ibm_emac/ibm_emac_core.h * - * Ethernet driver for the built in ethernet on the IBM 405 PowerPC - * processor. + * Driver for PowerPC 4xx on-chip ethernet controller. * - * Armin Kuster akuster@mvista.com - * Sept, 2001 + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or * - * Orignial driver - * Johnnie Peters - * jpeters@mvista.com - * - * Copyright 2000 MontaVista Softare Inc. + * Based on original work by + * Armin Kuster + * Johnnie Peters + * Copyright 2000, 2001 MontaVista Softare 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 of the License, or (at your * option) any later version. + * */ +#ifndef __IBM_EMAC_CORE_H_ +#define __IBM_EMAC_CORE_H_ -#ifndef _IBM_EMAC_CORE_H_ -#define _IBM_EMAC_CORE_H_ - +#include #include +#include #include -#include /* For phys_addr_t */ #include "ibm_emac.h" #include "ibm_emac_phy.h" -#include "ibm_emac_rgmii.h" #include "ibm_emac_zmii.h" +#include "ibm_emac_rgmii.h" #include "ibm_emac_mal.h" #include "ibm_emac_tah.h" -#ifndef CONFIG_IBM_EMAC_TXB -#define NUM_TX_BUFF 64 -#define NUM_RX_BUFF 64 -#else -#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB -#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB +#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB +#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB + +/* Simple sanity check */ +#if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256 +#error Invalid number of buffer descriptors (greater than 256) #endif -/* This does 16 byte alignment, exactly what we need. - * The packet length includes FCS, but we don't want to - * include that when passing upstream as it messes up - * bridging applications. +// XXX +#define EMAC_MIN_MTU 46 +#define EMAC_MAX_MTU 9000 + +/* Maximum L2 header length (VLAN tagged, no FCS) */ +#define EMAC_MTU_OVERHEAD (6 * 2 + 2 + 4) + +/* RX BD size for the given MTU */ +static inline int emac_rx_size(int mtu) +{ + if (mtu > ETH_DATA_LEN) + return MAL_MAX_RX_SIZE; + else + return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD); +} + +#define EMAC_DMA_ALIGN(x) ALIGN((x), dma_get_cache_alignment()) + +#define EMAC_RX_SKB_HEADROOM \ + EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM) + +/* Size of RX skb for the given MTU */ +static inline int emac_rx_skb_size(int mtu) +{ + int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu)); + return EMAC_DMA_ALIGN(size + 2) + EMAC_RX_SKB_HEADROOM; +} + +/* RX DMA sync size */ +static inline int emac_rx_sync_size(int mtu) +{ + return EMAC_DMA_ALIGN(emac_rx_size(mtu) + 2); +} + +/* Driver statistcs is split into two parts to make it more cache friendly: + * - normal statistics (packet count, etc) + * - error statistics + * + * When statistics is requested by ethtool, these parts are concatenated, + * normal one goes first. + * + * Please, keep these structures in sync with emac_stats_keys. */ -#ifndef CONFIG_IBM_EMAC_SKBRES -#define SKB_RES 2 -#else -#define SKB_RES CONFIG_IBM_EMAC_SKBRES -#endif -/* Note about alignement. alloc_skb() returns a cache line - * aligned buffer. However, dev_alloc_skb() will add 16 more - * bytes and "reserve" them, so our buffer will actually end - * on a half cache line. What we do is to use directly - * alloc_skb, allocate 16 more bytes to match the total amount - * allocated by dev_alloc_skb(), but we don't reserve. - */ -#define MAX_NUM_BUF_DESC 255 -#define DESC_BUF_SIZE 4080 /* max 4096-16 */ -#define DESC_BUF_SIZE_REG (DESC_BUF_SIZE / 16) +/* Normal TX/RX Statistics */ +struct ibm_emac_stats { + u64 rx_packets; + u64 rx_bytes; + u64 tx_packets; + u64 tx_bytes; + u64 rx_packets_csum; + u64 tx_packets_csum; +}; -/* Transmitter timeout. */ -#define TX_TIMEOUT (2*HZ) +/* Error statistics */ +struct ibm_emac_error_stats { + u64 tx_undo; -/* MDIO latency delay */ -#define MDIO_DELAY 250 + /* Software RX Errors */ + u64 rx_dropped_stack; + u64 rx_dropped_oom; + u64 rx_dropped_error; + u64 rx_dropped_resize; + u64 rx_dropped_mtu; + u64 rx_stopped; + /* BD reported RX errors */ + u64 rx_bd_errors; + u64 rx_bd_overrun; + u64 rx_bd_bad_packet; + u64 rx_bd_runt_packet; + u64 rx_bd_short_event; + u64 rx_bd_alignment_error; + u64 rx_bd_bad_fcs; + u64 rx_bd_packet_too_long; + u64 rx_bd_out_of_range; + u64 rx_bd_in_range; + /* EMAC IRQ reported RX errors */ + u64 rx_parity; + u64 rx_fifo_overrun; + u64 rx_overrun; + u64 rx_bad_packet; + u64 rx_runt_packet; + u64 rx_short_event; + u64 rx_alignment_error; + u64 rx_bad_fcs; + u64 rx_packet_too_long; + u64 rx_out_of_range; + u64 rx_in_range; -/* Power managment shift registers */ -#define IBM_CPM_EMMII 0 /* Shift value for MII */ -#define IBM_CPM_EMRX 1 /* Shift value for recv */ -#define IBM_CPM_EMTX 2 /* Shift value for MAC */ -#define IBM_CPM_EMAC(x) (((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX)) + /* Software TX Errors */ + u64 tx_dropped; + /* BD reported TX errors */ + u64 tx_bd_errors; + u64 tx_bd_bad_fcs; + u64 tx_bd_carrier_loss; + u64 tx_bd_excessive_deferral; + u64 tx_bd_excessive_collisions; + u64 tx_bd_late_collision; + u64 tx_bd_multple_collisions; + u64 tx_bd_single_collision; + u64 tx_bd_underrun; + u64 tx_bd_sqe; + /* EMAC IRQ reported TX errors */ + u64 tx_parity; + u64 tx_underrun; + u64 tx_sqe; + u64 tx_errors; +}; -#define ENET_HEADER_SIZE 14 -#define ENET_FCS_SIZE 4 -#define ENET_DEF_MTU_SIZE 1500 -#define ENET_DEF_BUF_SIZE (ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE) -#define EMAC_MIN_FRAME 64 -#define EMAC_MAX_FRAME 9018 -#define EMAC_MIN_MTU (EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE) -#define EMAC_MAX_MTU (EMAC_MAX_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE) - -#ifdef CONFIG_IBM_EMAC_ERRMSG -void emac_serr_dump_0(struct net_device *dev); -void emac_serr_dump_1(struct net_device *dev); -void emac_err_dump(struct net_device *dev, int em0isr); -void emac_phy_dump(struct net_device *); -void emac_desc_dump(struct net_device *); -void emac_mac_dump(struct net_device *); -void emac_mal_dump(struct net_device *); -#else -#define emac_serr_dump_0(dev) do { } while (0) -#define emac_serr_dump_1(dev) do { } while (0) -#define emac_err_dump(dev,x) do { } while (0) -#define emac_phy_dump(dev) do { } while (0) -#define emac_desc_dump(dev) do { } while (0) -#define emac_mac_dump(dev) do { } while (0) -#define emac_mal_dump(dev) do { } while (0) -#endif +#define EMAC_ETHTOOL_STATS_COUNT ((sizeof(struct ibm_emac_stats) + \ + sizeof(struct ibm_emac_error_stats)) \ + / sizeof(u64)) struct ocp_enet_private { - struct sk_buff *tx_skb[NUM_TX_BUFF]; - struct sk_buff *rx_skb[NUM_RX_BUFF]; - struct mal_descriptor *tx_desc; - struct mal_descriptor *rx_desc; - struct mal_descriptor *rx_dirty; - struct net_device_stats stats; - int tx_cnt; - int rx_slot; - int dirty_rx; - int tx_slot; - int ack_slot; - int rx_buffer_size; + struct net_device *ndev; /* 0 */ + struct emac_regs *emacp; + + struct mal_descriptor *tx_desc; + int tx_cnt; + int tx_slot; + int ack_slot; - struct mii_phy phy_mii; - int mii_phy_addr; - int want_autoneg; - int timer_ticks; - struct timer_list link_timer; - struct net_device *mdio_dev; + struct mal_descriptor *rx_desc; + int rx_slot; + struct sk_buff *rx_sg_skb; /* 1 */ + int rx_skb_size; + int rx_sync_size; - struct ocp_device *rgmii_dev; - int rgmii_input; + struct ibm_emac_stats stats; + struct ocp_device *tah_dev; - struct ocp_device *zmii_dev; - int zmii_input; + struct ibm_ocp_mal *mal; + struct mal_commac commac; - struct ibm_ocp_mal *mal; - int mal_tx_chan, mal_rx_chan; - struct mal_commac commac; + struct sk_buff *tx_skb[NUM_TX_BUFF]; + struct sk_buff *rx_skb[NUM_RX_BUFF]; - struct ocp_device *tah_dev; + struct ocp_device *zmii_dev; + int zmii_input; + struct ocp_enet_private *mdio_dev; + struct ocp_device *rgmii_dev; + int rgmii_input; - int opened; - int going_away; - int wol_irq; - emac_t *emacp; - struct ocp_device *ocpdev; - struct net_device *ndev; - spinlock_t lock; + struct ocp_def *def; + + struct mii_phy phy; + struct timer_list link_timer; + int reset_failed; + + struct ibm_emac_error_stats estats; + struct net_device_stats nstats; + + struct device* ldev; }; -#endif /* _IBM_EMAC_CORE_H_ */ + +/* Ethtool get_regs complex data. + * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH + * when available. + * + * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr, + * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers. + * Each register component is preceded with emac_ethtool_regs_subhdr. + * Order of the optional headers follows their relative bit posititions + * in emac_ethtool_regs_hdr.components + */ +#define EMAC_ETHTOOL_REGS_ZMII 0x00000001 +#define EMAC_ETHTOOL_REGS_RGMII 0x00000002 +#define EMAC_ETHTOOL_REGS_TAH 0x00000004 + +struct emac_ethtool_regs_hdr { + u32 components; +}; + +struct emac_ethtool_regs_subhdr { + u32 version; + u32 index; +}; + +#endif /* __IBM_EMAC_CORE_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c index c8512046cf84..75d3b8639041 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/drivers/net/ibm_emac/ibm_emac_debug.c @@ -1,224 +1,213 @@ /* - * ibm_ocp_debug.c + * drivers/net/ibm_emac/ibm_emac_debug.c * - * This has all the debug routines that where in *_enet.c + * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. * - * Armin Kuster akuster@mvista.com - * April , 2002 - * - * Copyright 2002 MontaVista Softare Inc. + * Copyright (c) 2004, 2005 Zultys Technologies + * Eugene Surovegin or * * 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. + * */ - #include +#include +#include #include #include +#include #include -#include "ibm_ocp_mal.h" -#include "ibm_ocp_zmii.h" -#include "ibm_ocp_enet.h" -extern int emac_phy_read(struct net_device *dev, int mii_id, int reg); +#include "ibm_emac_core.h" -void emac_phy_dump(struct net_device *dev) +static void emac_desc_dump(int idx, struct ocp_enet_private *p) { - struct ocp_enet_private *fep = dev->priv; - unsigned long i; - uint data; + int i; + printk("** EMAC%d TX BDs **\n" + " tx_cnt = %d tx_slot = %d ack_slot = %d\n", + idx, p->tx_cnt, p->tx_slot, p->ack_slot); + for (i = 0; i < NUM_TX_BUFF / 2; ++i) + printk + ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n", + i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ', + p->tx_desc[i].ctrl, p->tx_desc[i].data_len, + NUM_TX_BUFF / 2 + i, + p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr, + p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ', + p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl, + p->tx_desc[NUM_TX_BUFF / 2 + i].data_len); - printk(KERN_DEBUG " Prepare for Phy dump....\n"); - for (i = 0; i < 0x1A; i++) { - data = emac_phy_read(dev, fep->mii_phy_addr, i); - printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data); - if (i == 0x07) - i = 0x0f; + printk("** EMAC%d RX BDs **\n" + " rx_slot = %d rx_stopped = %d rx_skb_size = %d rx_sync_size = %d\n" + " rx_sg_skb = 0x%p\n", + idx, p->rx_slot, p->commac.rx_stopped, p->rx_skb_size, + p->rx_sync_size, p->rx_sg_skb); + for (i = 0; i < NUM_RX_BUFF / 2; ++i) + printk + ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n", + i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ', + p->rx_desc[i].ctrl, p->rx_desc[i].data_len, + NUM_RX_BUFF / 2 + i, + p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr, + p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ', + p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl, + p->rx_desc[NUM_RX_BUFF / 2 + i].data_len); +} + +static void emac_mac_dump(int idx, struct ocp_enet_private *dev) +{ + struct emac_regs *p = dev->emacp; + + printk("** EMAC%d registers **\n" + "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" + "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" + "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n" + "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x " + "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n" + "LSA = %04x%08x IPGVR = 0x%04x\n" + "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" + "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n", + idx, in_be32(&p->mr0), in_be32(&p->mr1), + in_be32(&p->tmr0), in_be32(&p->tmr1), + in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), + in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), + in_be32(&p->vtci), + in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3), + in_be32(&p->iaht4), + in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3), + in_be32(&p->gaht4), + in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr), + in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr), + in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr) + ); + + emac_desc_dump(idx, dev); +} + +static void emac_mal_dump(struct ibm_ocp_mal *mal) +{ + struct ocp_func_mal_data *maldata = mal->def->additions; + int i; + + printk("** MAL%d Registers **\n" + "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" + "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" + "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", + mal->def->index, + get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR), + get_mal_dcrn(mal, MAL_IER), + get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR), + get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR), + get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR), + get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR) + ); + + printk("TX|"); + for (i = 0; i < maldata->num_tx_chans; ++i) { + if (i && !(i % 4)) + printk("\n "); + printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i))); } -} - -void emac_desc_dump(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - int curr_slot; - - printk(KERN_DEBUG - "dumping the receive descriptors: current slot is %d\n", - fep->rx_slot); - for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) { - printk(KERN_DEBUG - "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n", - curr_slot, fep->rx_desc[curr_slot].ctrl, - fep->rx_desc[curr_slot].data_len, - (unsigned int)fep->rx_desc[curr_slot].data_ptr); + printk("\nRX|"); + for (i = 0; i < maldata->num_rx_chans; ++i) { + if (i && !(i % 4)) + printk("\n "); + printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i))); } -} - -void emac_mac_dump(struct net_device *dev) -{ - struct ocp_enet_private *fep = dev->priv; - volatile emac_t *emacp = fep->emacp; - - printk(KERN_DEBUG "EMAC DEBUG ********** \n"); - printk(KERN_DEBUG "EMAC_M0 ==> 0x%x\n", in_be32(&emacp->em0mr0)); - printk(KERN_DEBUG "EMAC_M1 ==> 0x%x\n", in_be32(&emacp->em0mr1)); - printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0)); - printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1)); - printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr)); - printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr)); - printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser)); - printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr)); - printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr)); - printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n", - in_be32(&emacp->em0vtpid)); -} - -void emac_mal_dump(struct net_device *dev) -{ - struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal; - - printk(KERN_DEBUG " MAL DEBUG ********** \n"); - printk(KERN_DEBUG " MCR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALCR)); - printk(KERN_DEBUG " ESR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALESR)); - printk(KERN_DEBUG " IER ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALIER)); -#ifdef CONFIG_40x - printk(KERN_DEBUG " DBR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALDBR)); -#endif /* CONFIG_40x */ - printk(KERN_DEBUG " TXCASR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCASR)); - printk(KERN_DEBUG " TXCARR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCARR)); - printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXEOBISR)); - printk(KERN_DEBUG " TXDEIR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXDEIR)); - printk(KERN_DEBUG " RXCASR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCASR)); - printk(KERN_DEBUG " RXCARR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCARR)); - printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXEOBISR)); - printk(KERN_DEBUG " RXDEIR ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXDEIR)); - printk(KERN_DEBUG " TXCTP0R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP0R)); - printk(KERN_DEBUG " TXCTP1R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP1R)); - printk(KERN_DEBUG " TXCTP2R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP2R)); - printk(KERN_DEBUG " TXCTP3R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP3R)); - printk(KERN_DEBUG " RXCTP0R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP0R)); - printk(KERN_DEBUG " RXCTP1R ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP1R)); - printk(KERN_DEBUG " RCBS0 ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS0)); - printk(KERN_DEBUG " RCBS1 ==> 0x%x\n", - (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS1)); -} - -void emac_serr_dump_0(struct net_device *dev) -{ - struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal; - unsigned long int mal_error, plb_error, plb_addr; - - mal_error = get_mal_dcrn(mal, DCRN_MALESR); - printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n", - (mal_error & 0x40000000) ? "Receive" : - "Transmit", (mal_error & 0x3e000000) >> 25); - printk(KERN_DEBUG " ----- latched error -----\n"); - if (mal_error & MALESR_DE) - printk(KERN_DEBUG " DE: descriptor error\n"); - if (mal_error & MALESR_OEN) - printk(KERN_DEBUG " ONE: OPB non-fullword error\n"); - if (mal_error & MALESR_OTE) - printk(KERN_DEBUG " OTE: OPB timeout error\n"); - if (mal_error & MALESR_OSE) - printk(KERN_DEBUG " OSE: OPB slave error\n"); - - if (mal_error & MALESR_PEIN) { - plb_error = mfdcr(DCRN_PLB0_BESR); - printk(KERN_DEBUG - " PEIN: PLB error, PLB0_BESR is 0x%x\n", - (unsigned int)plb_error); - plb_addr = mfdcr(DCRN_PLB0_BEAR); - printk(KERN_DEBUG - " PEIN: PLB error, PLB0_BEAR is 0x%x\n", - (unsigned int)plb_addr); + printk("\n "); + for (i = 0; i < maldata->num_rx_chans; ++i) { + u32 r = get_mal_dcrn(mal, MAL_RCBS(i)); + if (i && !(i % 3)) + printk("\n "); + printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16); } + printk("\n"); } -void emac_serr_dump_1(struct net_device *dev) +static struct ocp_enet_private *__emacs[4]; +static struct ibm_ocp_mal *__mals[1]; + +void emac_dbg_register(int idx, struct ocp_enet_private *dev) { - struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal; - int mal_error = get_mal_dcrn(mal, DCRN_MALESR); + unsigned long flags; - printk(KERN_DEBUG " ----- cumulative errors -----\n"); - if (mal_error & MALESR_DEI) - printk(KERN_DEBUG " DEI: descriptor error interrupt\n"); - if (mal_error & MALESR_ONEI) - printk(KERN_DEBUG " OPB non-fullword error interrupt\n"); - if (mal_error & MALESR_OTEI) - printk(KERN_DEBUG " OTEI: timeout error interrupt\n"); - if (mal_error & MALESR_OSEI) - printk(KERN_DEBUG " OSEI: slave error interrupt\n"); - if (mal_error & MALESR_PBEI) - printk(KERN_DEBUG " PBEI: PLB bus error interrupt\n"); + if (idx >= sizeof(__emacs) / sizeof(__emacs[0])) { + printk(KERN_WARNING + "invalid index %d when registering EMAC for debugging\n", + idx); + return; + } + + local_irq_save(flags); + __emacs[idx] = dev; + local_irq_restore(flags); } -void emac_err_dump(struct net_device *dev, int em0isr) +void mal_dbg_register(int idx, struct ibm_ocp_mal *mal) { - printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name); + unsigned long flags; - if (em0isr & EMAC_ISR_OVR) - printk(KERN_DEBUG " OVR: overrun\n"); - if (em0isr & EMAC_ISR_PP) - printk(KERN_DEBUG " PP: control pause packet\n"); - if (em0isr & EMAC_ISR_BP) - printk(KERN_DEBUG " BP: packet error\n"); - if (em0isr & EMAC_ISR_RP) - printk(KERN_DEBUG " RP: runt packet\n"); - if (em0isr & EMAC_ISR_SE) - printk(KERN_DEBUG " SE: short event\n"); - if (em0isr & EMAC_ISR_ALE) - printk(KERN_DEBUG " ALE: odd number of nibbles in packet\n"); - if (em0isr & EMAC_ISR_BFCS) - printk(KERN_DEBUG " BFCS: bad FCS\n"); - if (em0isr & EMAC_ISR_PTLE) - printk(KERN_DEBUG " PTLE: oversized packet\n"); - if (em0isr & EMAC_ISR_ORE) - printk(KERN_DEBUG - " ORE: packet length field > max allowed LLC\n"); - if (em0isr & EMAC_ISR_IRE) - printk(KERN_DEBUG " IRE: In Range error\n"); - if (em0isr & EMAC_ISR_DBDM) - printk(KERN_DEBUG " DBDM: xmit error or SQE\n"); - if (em0isr & EMAC_ISR_DB0) - printk(KERN_DEBUG " DB0: xmit error or SQE on TX channel 0\n"); - if (em0isr & EMAC_ISR_SE0) - printk(KERN_DEBUG - " SE0: Signal Quality Error test failure from TX channel 0\n"); - if (em0isr & EMAC_ISR_TE0) - printk(KERN_DEBUG " TE0: xmit channel 0 aborted\n"); - if (em0isr & EMAC_ISR_DB1) - printk(KERN_DEBUG " DB1: xmit error or SQE on TX channel \n"); - if (em0isr & EMAC_ISR_SE1) - printk(KERN_DEBUG - " SE1: Signal Quality Error test failure from TX channel 1\n"); - if (em0isr & EMAC_ISR_TE1) - printk(KERN_DEBUG " TE1: xmit channel 1 aborted\n"); - if (em0isr & EMAC_ISR_MOS) - printk(KERN_DEBUG " MOS\n"); - if (em0isr & EMAC_ISR_MOF) - printk(KERN_DEBUG " MOF\n"); + if (idx >= sizeof(__mals) / sizeof(__mals[0])) { + printk(KERN_WARNING + "invalid index %d when registering MAL for debugging\n", + idx); + return; + } - emac_mac_dump(dev); - emac_mal_dump(dev); + local_irq_save(flags); + __mals[idx] = mal; + local_irq_restore(flags); } + +void emac_dbg_dump_all(void) +{ + unsigned int i; + unsigned long flags; + + local_irq_save(flags); + + for (i = 0; i < sizeof(__mals) / sizeof(__mals[0]); ++i) + if (__mals[i]) + emac_mal_dump(__mals[i]); + + for (i = 0; i < sizeof(__emacs) / sizeof(__emacs[0]); ++i) + if (__emacs[i]) + emac_mac_dump(i, __emacs[i]); + + local_irq_restore(flags); +} + +#if defined(CONFIG_MAGIC_SYSRQ) +static void emac_sysrq_handler(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + emac_dbg_dump_all(); +} + +static struct sysrq_key_op emac_sysrq_op = { + .handler = emac_sysrq_handler, + .help_msg = "emaC", + .action_msg = "Show EMAC(s) status", +}; + +int __init emac_init_debug(void) +{ + return register_sysrq_key('c', &emac_sysrq_op); +} + +void __exit emac_fini_debug(void) +{ + unregister_sysrq_key('c', &emac_sysrq_op); +} + +#else +int __init emac_init_debug(void) +{ + return 0; +} +void __exit emac_fini_debug(void) +{ +} +#endif /* CONFIG_MAGIC_SYSRQ */ diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h new file mode 100644 index 000000000000..e85fbe0a8da9 --- /dev/null +++ b/drivers/net/ibm_emac/ibm_emac_debug.h @@ -0,0 +1,63 @@ +/* + * drivers/net/ibm_emac/ibm_ocp_debug.h + * + * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. + * + * Copyright (c) 2004, 2005 Zultys Technologies + * Eugene Surovegin or + * + * 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. + * + */ +#ifndef __IBM_EMAC_DEBUG_H_ +#define __IBM_EMAC_DEBUG_H_ + +#include +#include +#include "ibm_emac_core.h" +#include "ibm_emac_mal.h" + +#if defined(CONFIG_IBM_EMAC_DEBUG) +void emac_dbg_register(int idx, struct ocp_enet_private *dev); +void mal_dbg_register(int idx, struct ibm_ocp_mal *mal); +int emac_init_debug(void) __init; +void emac_fini_debug(void) __exit; +void emac_dbg_dump_all(void); +# define DBG_LEVEL 1 +#else +# define emac_dbg_register(x,y) ((void)0) +# define mal_dbg_register(x,y) ((void)0) +# define emac_init_debug() ((void)0) +# define emac_fini_debug() ((void)0) +# define emac_dbg_dump_all() ((void)0) +# define DBG_LEVEL 0 +#endif + +#if DBG_LEVEL > 0 +# define DBG(f,x...) printk("emac" f, ##x) +# define MAL_DBG(f,x...) printk("mal" f, ##x) +# define ZMII_DBG(f,x...) printk("zmii" f, ##x) +# define RGMII_DBG(f,x...) printk("rgmii" f, ##x) +# define NL "\n" +#else +# define DBG(f,x...) ((void)0) +# define MAL_DBG(f,x...) ((void)0) +# define ZMII_DBG(f,x...) ((void)0) +# define RGMII_DBG(f,x...) ((void)0) +#endif +#if DBG_LEVEL > 1 +# define DBG2(f,x...) DBG(f, ##x) +# define MAL_DBG2(f,x...) MAL_DBG(f, ##x) +# define ZMII_DBG2(f,x...) ZMII_DBG(f, ##x) +# define RGMII_DBG2(f,x...) RGMII_DBG(f, ##x) +#else +# define DBG2(f,x...) ((void)0) +# define MAL_DBG2(f,x...) ((void)0) +# define ZMII_DBG2(f,x...) ((void)0) +# define RGMII_DBG2(f,x...) ((void)0) +#endif + +#endif /* __IBM_EMAC_DEBUG_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c index e59f57f363ca..da88d43081cc 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.c +++ b/drivers/net/ibm_emac/ibm_emac_mal.c @@ -1,436 +1,565 @@ /* - * ibm_ocp_mal.c + * drivers/net/ibm_emac/ibm_emac_mal.c * - * Armin Kuster akuster@mvista.com - * Juen, 2002 + * Memory Access Layer (MAL) support + * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or * - * Copyright 2002 MontaVista Softare Inc. + * Based on original work by + * Benjamin Herrenschmidt , + * David Gibson , + * + * Armin Kuster + * Copyright 2002 MontaVista Softare 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 of the License, or (at your * option) any later version. + * */ - #include #include #include #include #include #include +#include #include -#include -#include #include +#include "ibm_emac_core.h" #include "ibm_emac_mal.h" +#include "ibm_emac_debug.h" -// Locking: Should we share a lock with the client ? The client could provide -// a lock pointer (optionally) in the commac structure... I don't think this is -// really necessary though - -/* This lock protects the commac list. On today UP implementations, it's - * really only used as IRQ protection in mal_{register,unregister}_commac() - */ -static DEFINE_RWLOCK(mal_list_lock); - -int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac) +int __init mal_register_commac(struct ibm_ocp_mal *mal, + struct mal_commac *commac) { unsigned long flags; + local_irq_save(flags); - write_lock_irqsave(&mal_list_lock, flags); + MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index, + commac->tx_chan_mask, commac->rx_chan_mask); - /* Don't let multiple commacs claim the same channel */ + /* Don't let multiple commacs claim the same channel(s) */ if ((mal->tx_chan_mask & commac->tx_chan_mask) || (mal->rx_chan_mask & commac->rx_chan_mask)) { - write_unlock_irqrestore(&mal_list_lock, flags); + local_irq_restore(flags); + printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n", + mal->def->index); return -EBUSY; } mal->tx_chan_mask |= commac->tx_chan_mask; mal->rx_chan_mask |= commac->rx_chan_mask; + list_add(&commac->list, &mal->list); - list_add(&commac->list, &mal->commac); - - write_unlock_irqrestore(&mal_list_lock, flags); - + local_irq_restore(flags); return 0; } -int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac) +void __exit mal_unregister_commac(struct ibm_ocp_mal *mal, + struct mal_commac *commac) { unsigned long flags; + local_irq_save(flags); - write_lock_irqsave(&mal_list_lock, flags); + MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index, + commac->tx_chan_mask, commac->rx_chan_mask); mal->tx_chan_mask &= ~commac->tx_chan_mask; mal->rx_chan_mask &= ~commac->rx_chan_mask; - list_del_init(&commac->list); - write_unlock_irqrestore(&mal_list_lock, flags); - - return 0; + local_irq_restore(flags); } int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size) { - switch (channel) { - case 0: - set_mal_dcrn(mal, DCRN_MALRCBS0, size); - break; -#ifdef DCRN_MALRCBS1 - case 1: - set_mal_dcrn(mal, DCRN_MALRCBS1, size); - break; -#endif -#ifdef DCRN_MALRCBS2 - case 2: - set_mal_dcrn(mal, DCRN_MALRCBS2, size); - break; -#endif -#ifdef DCRN_MALRCBS3 - case 3: - set_mal_dcrn(mal, DCRN_MALRCBS3, size); - break; -#endif - default: + struct ocp_func_mal_data *maldata = mal->def->additions; + BUG_ON(channel < 0 || channel >= maldata->num_rx_chans || + size > MAL_MAX_RX_SIZE); + + MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size); + + if (size & 0xf) { + printk(KERN_WARNING + "mal%d: incorrect RX size %lu for the channel %d\n", + mal->def->index, size, channel); return -EINVAL; } + set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4); return 0; } +int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel) +{ + struct ocp_func_mal_data *maldata = mal->def->additions; + BUG_ON(channel < 0 || channel >= maldata->num_tx_chans); + return channel * NUM_TX_BUFF; +} + +int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel) +{ + struct ocp_func_mal_data *maldata = mal->def->additions; + BUG_ON(channel < 0 || channel >= maldata->num_rx_chans); + return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF; +} + +void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel) +{ + local_bh_disable(); + MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel); + set_mal_dcrn(mal, MAL_TXCASR, + get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel)); + local_bh_enable(); +} + +void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel) +{ + set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel)); + MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel); +} + +void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel) +{ + local_bh_disable(); + MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel); + set_mal_dcrn(mal, MAL_RXCASR, + get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel)); + local_bh_enable(); +} + +void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel) +{ + set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel)); + MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel); +} + +void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac) +{ + local_bh_disable(); + MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac); + list_add_tail(&commac->poll_list, &mal->poll_list); + local_bh_enable(); +} + +void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac) +{ + local_bh_disable(); + MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac); + list_del(&commac->poll_list); + local_bh_enable(); +} + +/* synchronized by mal_poll() */ +static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal) +{ + MAL_DBG2("%d: enable_irq" NL, mal->def->index); + set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE); +} + +/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */ +static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal) +{ + set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE); + MAL_DBG2("%d: disable_irq" NL, mal->def->index); +} + static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; - unsigned long mal_error; - - /* - * This SERR applies to one of the devices on the MAL, here we charge - * it against the first EMAC registered for the MAL. - */ - - mal_error = get_mal_dcrn(mal, DCRN_MALESR); - - printk(KERN_ERR "%s: System Error (MALESR=%lx)\n", - "MAL" /* FIXME: get the name right */ , mal_error); - - /* FIXME: decipher error */ - /* DIXME: distribute to commacs, if possible */ + u32 esr = get_mal_dcrn(mal, MAL_ESR); /* Clear the error status register */ - set_mal_dcrn(mal, DCRN_MALESR, mal_error); + set_mal_dcrn(mal, MAL_ESR, esr); + MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr); + + if (esr & MAL_ESR_EVB) { + if (esr & MAL_ESR_DE) { + /* We ignore Descriptor error, + * TXDE or RXDE interrupt will be generated anyway. + */ + return IRQ_HANDLED; + } + + if (esr & MAL_ESR_PEIN) { + /* PLB error, it's probably buggy hardware or + * incorrect physical address in BD (i.e. bug) + */ + if (net_ratelimit()) + printk(KERN_ERR + "mal%d: system error, PLB (ESR = 0x%08x)\n", + mal->def->index, esr); + return IRQ_HANDLED; + } + + /* OPB error, it's probably buggy hardware or incorrect EBC setup */ + if (net_ratelimit()) + printk(KERN_ERR + "mal%d: system error, OPB (ESR = 0x%08x)\n", + mal->def->index, esr); + } return IRQ_HANDLED; } +static inline void mal_schedule_poll(struct ibm_ocp_mal *mal) +{ + if (likely(netif_rx_schedule_prep(&mal->poll_dev))) { + MAL_DBG2("%d: schedule_poll" NL, mal->def->index); + mal_disable_eob_irq(mal); + __netif_rx_schedule(&mal->poll_dev); + } else + MAL_DBG2("%d: already in poll" NL, mal->def->index); +} + static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; - struct list_head *l; - unsigned long isr; - - isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR); - set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr); - - read_lock(&mal_list_lock); - list_for_each(l, &mal->commac) { - struct mal_commac *mc = list_entry(l, struct mal_commac, list); - - if (isr & mc->tx_chan_mask) { - mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask); - } - } - read_unlock(&mal_list_lock); - + u32 r = get_mal_dcrn(mal, MAL_TXEOBISR); + MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r); + mal_schedule_poll(mal); + set_mal_dcrn(mal, MAL_TXEOBISR, r); return IRQ_HANDLED; } static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; - struct list_head *l; - unsigned long isr; - - isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR); - set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr); - - read_lock(&mal_list_lock); - list_for_each(l, &mal->commac) { - struct mal_commac *mc = list_entry(l, struct mal_commac, list); - - if (isr & mc->rx_chan_mask) { - mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask); - } - } - read_unlock(&mal_list_lock); - + u32 r = get_mal_dcrn(mal, MAL_RXEOBISR); + MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r); + mal_schedule_poll(mal); + set_mal_dcrn(mal, MAL_RXEOBISR, r); return IRQ_HANDLED; } static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; - struct list_head *l; - unsigned long deir; + u32 deir = get_mal_dcrn(mal, MAL_TXDEIR); + set_mal_dcrn(mal, MAL_TXDEIR, deir); - deir = get_mal_dcrn(mal, DCRN_MALTXDEIR); + MAL_DBG("%d: txde %08x" NL, mal->def->index, deir); - /* FIXME: print which MAL correctly */ - printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n", - "MAL", deir); - - read_lock(&mal_list_lock); - list_for_each(l, &mal->commac) { - struct mal_commac *mc = list_entry(l, struct mal_commac, list); - - if (deir & mc->tx_chan_mask) { - mc->ops->txde(mc->dev, deir & mc->tx_chan_mask); - } - } - read_unlock(&mal_list_lock); + if (net_ratelimit()) + printk(KERN_ERR + "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n", + mal->def->index, deir); return IRQ_HANDLED; } -/* - * This interrupt should be very rare at best. This occurs when - * the hardware has a problem with the receive descriptors. The manual - * states that it occurs when the hardware cannot the receive descriptor - * empty bit is not set. The recovery mechanism will be to - * traverse through the descriptors, handle any that are marked to be - * handled and reinitialize each along the way. At that point the driver - * will be restarted. - */ static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; struct list_head *l; - unsigned long deir; + u32 deir = get_mal_dcrn(mal, MAL_RXDEIR); - deir = get_mal_dcrn(mal, DCRN_MALRXDEIR); + MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir); - /* - * This really is needed. This case encountered in stress testing. - */ - if (deir == 0) - return IRQ_HANDLED; - - /* FIXME: print which MAL correctly */ - printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n", - "MAL", deir); - - read_lock(&mal_list_lock); - list_for_each(l, &mal->commac) { + list_for_each(l, &mal->list) { struct mal_commac *mc = list_entry(l, struct mal_commac, list); - if (deir & mc->rx_chan_mask) { - mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask); + mc->rx_stopped = 1; + mc->ops->rxde(mc->dev); } } - read_unlock(&mal_list_lock); + + mal_schedule_poll(mal); + set_mal_dcrn(mal, MAL_RXDEIR, deir); return IRQ_HANDLED; } +static int mal_poll(struct net_device *ndev, int *budget) +{ + struct ibm_ocp_mal *mal = ndev->priv; + struct list_head *l; + int rx_work_limit = min(ndev->quota, *budget), received = 0, done; + + MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget, + rx_work_limit); + again: + /* Process TX skbs */ + list_for_each(l, &mal->poll_list) { + struct mal_commac *mc = + list_entry(l, struct mal_commac, poll_list); + mc->ops->poll_tx(mc->dev); + } + + /* Process RX skbs. + * We _might_ need something more smart here to enforce polling fairness. + */ + list_for_each(l, &mal->poll_list) { + struct mal_commac *mc = + list_entry(l, struct mal_commac, poll_list); + int n = mc->ops->poll_rx(mc->dev, rx_work_limit); + if (n) { + received += n; + rx_work_limit -= n; + if (rx_work_limit <= 0) { + done = 0; + goto more_work; // XXX What if this is the last one ? + } + } + } + + /* We need to disable IRQs to protect from RXDE IRQ here */ + local_irq_disable(); + __netif_rx_complete(ndev); + mal_enable_eob_irq(mal); + local_irq_enable(); + + done = 1; + + /* Check for "rotting" packet(s) */ + list_for_each(l, &mal->poll_list) { + struct mal_commac *mc = + list_entry(l, struct mal_commac, poll_list); + if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) { + MAL_DBG2("%d: rotting packet" NL, mal->def->index); + if (netif_rx_reschedule(ndev, received)) + mal_disable_eob_irq(mal); + else + MAL_DBG2("%d: already in poll list" NL, + mal->def->index); + + if (rx_work_limit > 0) + goto again; + else + goto more_work; + } + mc->ops->poll_tx(mc->dev); + } + + more_work: + ndev->quota -= received; + *budget -= received; + + MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget, + done ? 0 : 1); + return done ? 0 : 1; +} + +static void mal_reset(struct ibm_ocp_mal *mal) +{ + int n = 10; + MAL_DBG("%d: reset" NL, mal->def->index); + + set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR); + + /* Wait for reset to complete (1 system clock) */ + while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n) + --n; + + if (unlikely(!n)) + printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index); +} + +int mal_get_regs_len(struct ibm_ocp_mal *mal) +{ + return sizeof(struct emac_ethtool_regs_subhdr) + + sizeof(struct ibm_mal_regs); +} + +void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1); + struct ocp_func_mal_data *maldata = mal->def->additions; + int i; + + hdr->version = MAL_VERSION; + hdr->index = mal->def->index; + + regs->tx_count = maldata->num_tx_chans; + regs->rx_count = maldata->num_rx_chans; + + regs->cfg = get_mal_dcrn(mal, MAL_CFG); + regs->esr = get_mal_dcrn(mal, MAL_ESR); + regs->ier = get_mal_dcrn(mal, MAL_IER); + regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR); + regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR); + regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR); + regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR); + regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR); + regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR); + regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR); + regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR); + + for (i = 0; i < regs->tx_count; ++i) + regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i)); + + for (i = 0; i < regs->rx_count; ++i) { + regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i)); + regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i)); + } + return regs + 1; +} + static int __init mal_probe(struct ocp_device *ocpdev) { - struct ibm_ocp_mal *mal = NULL; + struct ibm_ocp_mal *mal; struct ocp_func_mal_data *maldata; - int err = 0; + int err = 0, i, bd_size; - maldata = (struct ocp_func_mal_data *)ocpdev->def->additions; + MAL_DBG("%d: probe" NL, ocpdev->def->index); + + maldata = ocpdev->def->additions; if (maldata == NULL) { - printk(KERN_ERR "mal%d: Missing additional datas !\n", + printk(KERN_ERR "mal%d: missing additional data!\n", ocpdev->def->index); return -ENODEV; } - mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL); - if (mal == NULL) { + mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL); + if (!mal) { printk(KERN_ERR - "mal%d: Out of memory allocating MAL structure !\n", + "mal%d: out of memory allocating MAL structure!\n", ocpdev->def->index); return -ENOMEM; } - memset(mal, 0, sizeof(*mal)); + mal->dcrbase = maldata->dcr_base; + mal->def = ocpdev->def; - switch (ocpdev->def->index) { - case 0: - mal->dcrbase = DCRN_MAL_BASE; - break; -#ifdef DCRN_MAL1_BASE - case 1: - mal->dcrbase = DCRN_MAL1_BASE; - break; -#endif - default: - BUG(); - } + INIT_LIST_HEAD(&mal->poll_list); + set_bit(__LINK_STATE_START, &mal->poll_dev.state); + mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT; + mal->poll_dev.poll = mal_poll; + mal->poll_dev.priv = mal; + atomic_set(&mal->poll_dev.refcnt, 1); - /**************************/ + INIT_LIST_HEAD(&mal->list); - INIT_LIST_HEAD(&mal->commac); - - set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF); - set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF); - - set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR); /* 384 */ - /* FIXME: Add delay */ + /* Load power-on reset defaults */ + mal_reset(mal); /* Set the MAL configuration register */ - set_mal_dcrn(mal, DCRN_MALCR, - MALCR_PLBB | MALCR_OPBBL | MALCR_LEA | - MALCR_PLBLT_DEFAULT); + set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB | + MAL_CFG_OPBBL | MAL_CFG_LEA); - /* It would be nice to allocate buffers separately for each - * channel, but we can't because the channels share the upper - * 13 bits of address lines. Each channels buffer must also - * be 4k aligned, so we allocate 4k for each channel. This is - * inefficient FIXME: do better, if possible */ - mal->tx_virt_addr = dma_alloc_coherent(&ocpdev->dev, - MAL_DT_ALIGN * - maldata->num_tx_chans, - &mal->tx_phys_addr, GFP_KERNEL); - if (mal->tx_virt_addr == NULL) { + mal_enable_eob_irq(mal); + + /* Allocate space for BD rings */ + BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32); + BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32); + bd_size = sizeof(struct mal_descriptor) * + (NUM_TX_BUFF * maldata->num_tx_chans + + NUM_RX_BUFF * maldata->num_rx_chans); + mal->bd_virt = + dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL); + + if (!mal->bd_virt) { printk(KERN_ERR - "mal%d: Out of memory allocating MAL descriptors !\n", - ocpdev->def->index); + "mal%d: out of memory allocating RX/TX descriptors!\n", + mal->def->index); err = -ENOMEM; goto fail; } + memset(mal->bd_virt, 0, bd_size); - /* God, oh, god, I hate DCRs */ - set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr); -#ifdef DCRN_MALTXCTP1R - if (maldata->num_tx_chans > 1) - set_mal_dcrn(mal, DCRN_MALTXCTP1R, - mal->tx_phys_addr + MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP1R */ -#ifdef DCRN_MALTXCTP2R - if (maldata->num_tx_chans > 2) - set_mal_dcrn(mal, DCRN_MALTXCTP2R, - mal->tx_phys_addr + 2 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP2R */ -#ifdef DCRN_MALTXCTP3R - if (maldata->num_tx_chans > 3) - set_mal_dcrn(mal, DCRN_MALTXCTP3R, - mal->tx_phys_addr + 3 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP3R */ -#ifdef DCRN_MALTXCTP4R - if (maldata->num_tx_chans > 4) - set_mal_dcrn(mal, DCRN_MALTXCTP4R, - mal->tx_phys_addr + 4 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP4R */ -#ifdef DCRN_MALTXCTP5R - if (maldata->num_tx_chans > 5) - set_mal_dcrn(mal, DCRN_MALTXCTP5R, - mal->tx_phys_addr + 5 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP5R */ -#ifdef DCRN_MALTXCTP6R - if (maldata->num_tx_chans > 6) - set_mal_dcrn(mal, DCRN_MALTXCTP6R, - mal->tx_phys_addr + 6 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP6R */ -#ifdef DCRN_MALTXCTP7R - if (maldata->num_tx_chans > 7) - set_mal_dcrn(mal, DCRN_MALTXCTP7R, - mal->tx_phys_addr + 7 * MAL_DT_ALIGN); -#endif /* DCRN_MALTXCTP7R */ + for (i = 0; i < maldata->num_tx_chans; ++i) + set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma + + sizeof(struct mal_descriptor) * + mal_tx_bd_offset(mal, i)); - mal->rx_virt_addr = dma_alloc_coherent(&ocpdev->dev, - MAL_DT_ALIGN * - maldata->num_rx_chans, - &mal->rx_phys_addr, GFP_KERNEL); - - set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr); -#ifdef DCRN_MALRXCTP1R - if (maldata->num_rx_chans > 1) - set_mal_dcrn(mal, DCRN_MALRXCTP1R, - mal->rx_phys_addr + MAL_DT_ALIGN); -#endif /* DCRN_MALRXCTP1R */ -#ifdef DCRN_MALRXCTP2R - if (maldata->num_rx_chans > 2) - set_mal_dcrn(mal, DCRN_MALRXCTP2R, - mal->rx_phys_addr + 2 * MAL_DT_ALIGN); -#endif /* DCRN_MALRXCTP2R */ -#ifdef DCRN_MALRXCTP3R - if (maldata->num_rx_chans > 3) - set_mal_dcrn(mal, DCRN_MALRXCTP3R, - mal->rx_phys_addr + 3 * MAL_DT_ALIGN); -#endif /* DCRN_MALRXCTP3R */ + for (i = 0; i < maldata->num_rx_chans; ++i) + set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma + + sizeof(struct mal_descriptor) * + mal_rx_bd_offset(mal, i)); err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal); if (err) - goto fail; - err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE ", mal); + goto fail2; + err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal); if (err) - goto fail; + goto fail3; err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal); if (err) - goto fail; + goto fail4; err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal); if (err) - goto fail; + goto fail5; err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal); if (err) - goto fail; + goto fail6; - set_mal_dcrn(mal, DCRN_MALIER, - MALIER_DE | MALIER_NE | MALIER_TE | - MALIER_OPBE | MALIER_PLBE); + /* Enable all MAL SERR interrupt sources */ + set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS); - /* Advertise me to the rest of the world */ + /* Advertise this instance to the rest of the world */ ocp_set_drvdata(ocpdev, mal); - printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n", - ocpdev->def->index, maldata->num_tx_chans, - maldata->num_rx_chans); + mal_dbg_register(mal->def->index, mal); + printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n", + mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans); return 0; + fail6: + free_irq(maldata->rxde_irq, mal); + fail5: + free_irq(maldata->txeob_irq, mal); + fail4: + free_irq(maldata->txde_irq, mal); + fail3: + free_irq(maldata->serr_irq, mal); + fail2: + dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma); fail: - /* FIXME: dispose requested IRQs ! */ - if (err && mal) - kfree(mal); + kfree(mal); return err; } static void __exit mal_remove(struct ocp_device *ocpdev) { struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev); - struct ocp_func_mal_data *maldata = ocpdev->def->additions; + struct ocp_func_mal_data *maldata = mal->def->additions; - BUG_ON(!maldata); + MAL_DBG("%d: remove" NL, mal->def->index); + + /* Syncronize with scheduled polling, + stolen from net/core/dev.c:dev_close() + */ + clear_bit(__LINK_STATE_START, &mal->poll_dev.state); + netif_poll_disable(&mal->poll_dev); + + if (!list_empty(&mal->list)) { + /* This is *very* bad */ + printk(KERN_EMERG + "mal%d: commac list is not empty on remove!\n", + mal->def->index); + } ocp_set_drvdata(ocpdev, NULL); - /* FIXME: shut down the MAL, deal with dependency with emac */ free_irq(maldata->serr_irq, mal); free_irq(maldata->txde_irq, mal); free_irq(maldata->txeob_irq, mal); free_irq(maldata->rxde_irq, mal); free_irq(maldata->rxeob_irq, mal); - if (mal->tx_virt_addr) - dma_free_coherent(&ocpdev->dev, - MAL_DT_ALIGN * maldata->num_tx_chans, - mal->tx_virt_addr, mal->tx_phys_addr); + mal_reset(mal); - if (mal->rx_virt_addr) - dma_free_coherent(&ocpdev->dev, - MAL_DT_ALIGN * maldata->num_rx_chans, - mal->rx_virt_addr, mal->rx_phys_addr); + mal_dbg_register(mal->def->index, NULL); + + dma_free_coherent(&ocpdev->dev, + sizeof(struct mal_descriptor) * + (NUM_TX_BUFF * maldata->num_tx_chans + + NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt, + mal->bd_dma); kfree(mal); } /* Structure for a device driver */ static struct ocp_device_id mal_ids[] = { - {.vendor = OCP_ANY_ID,.function = OCP_FUNC_MAL}, - {.vendor = OCP_VENDOR_INVALID} + { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL }, + { .vendor = OCP_VENDOR_INVALID} }; static struct ocp_driver mal_driver = { @@ -441,23 +570,14 @@ static struct ocp_driver mal_driver = { .remove = mal_remove, }; -static int __init init_mals(void) +int __init mal_init(void) { - int rc; - - rc = ocp_register_driver(&mal_driver); - if (rc < 0) { - ocp_unregister_driver(&mal_driver); - return -ENODEV; - } - - return 0; + MAL_DBG(": init" NL); + return ocp_register_driver(&mal_driver); } -static void __exit exit_mals(void) +void __exit mal_exit(void) { + MAL_DBG(": exit" NL); ocp_unregister_driver(&mal_driver); } - -module_init(init_mals); -module_exit(exit_mals); diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h index dd9f0dabc6e0..15b0bdae26ac 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.h +++ b/drivers/net/ibm_emac/ibm_emac_mal.h @@ -1,131 +1,267 @@ -#ifndef _IBM_EMAC_MAL_H -#define _IBM_EMAC_MAL_H +/* + * drivers/net/ibm_emac/ibm_emac_mal.h + * + * Memory Access Layer (MAL) support + * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or + * + * Based on original work by + * Armin Kuster + * Copyright 2002 MontaVista Softare 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 of the License, or (at your + * option) any later version. + * + */ +#ifndef __IBM_EMAC_MAL_H_ +#define __IBM_EMAC_MAL_H_ +#include +#include #include +#include -#define MAL_DT_ALIGN (4096) /* Alignment for each channel's descriptor table */ +#include -#define MAL_CHAN_MASK(chan) (0x80000000 >> (chan)) +/* + * These MAL "versions" probably aren't the real versions IBM uses for these + * MAL cores, I assigned them just to make #ifdefs in this file nicer and + * reflect the fact that 40x and 44x have slightly different MALs. --ebs + */ +#if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \ + defined(CONFIG_440EP) || defined(CONFIG_NP405H) +#define MAL_VERSION 1 +#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) +#define MAL_VERSION 2 +#else +#error "Unknown SoC, please check chip manual and choose MAL 'version'" +#endif + +/* MALx DCR registers */ +#define MAL_CFG 0x00 +#define MAL_CFG_SR 0x80000000 +#define MAL_CFG_PLBB 0x00004000 +#define MAL_CFG_OPBBL 0x00000080 +#define MAL_CFG_EOPIE 0x00000004 +#define MAL_CFG_LEA 0x00000002 +#define MAL_CFG_SD 0x00000001 +#if MAL_VERSION == 1 +#define MAL_CFG_PLBP_MASK 0x00c00000 +#define MAL_CFG_PLBP_10 0x00800000 +#define MAL_CFG_GA 0x00200000 +#define MAL_CFG_OA 0x00100000 +#define MAL_CFG_PLBLE 0x00080000 +#define MAL_CFG_PLBT_MASK 0x00078000 +#define MAL_CFG_DEFAULT (MAL_CFG_PLBP_10 | MAL_CFG_PLBT_MASK) +#elif MAL_VERSION == 2 +#define MAL_CFG_RPP_MASK 0x00c00000 +#define MAL_CFG_RPP_10 0x00800000 +#define MAL_CFG_RMBS_MASK 0x00300000 +#define MAL_CFG_WPP_MASK 0x000c0000 +#define MAL_CFG_WPP_10 0x00080000 +#define MAL_CFG_WMBS_MASK 0x00030000 +#define MAL_CFG_PLBLE 0x00008000 +#define MAL_CFG_DEFAULT (MAL_CFG_RMBS_MASK | MAL_CFG_WMBS_MASK | \ + MAL_CFG_RPP_10 | MAL_CFG_WPP_10) +#else +#error "Unknown MAL version" +#endif + +#define MAL_ESR 0x01 +#define MAL_ESR_EVB 0x80000000 +#define MAL_ESR_CIDT 0x40000000 +#define MAL_ESR_CID_MASK 0x3e000000 +#define MAL_ESR_CID_SHIFT 25 +#define MAL_ESR_DE 0x00100000 +#define MAL_ESR_OTE 0x00040000 +#define MAL_ESR_OSE 0x00020000 +#define MAL_ESR_PEIN 0x00010000 +#define MAL_ESR_DEI 0x00000010 +#define MAL_ESR_OTEI 0x00000004 +#define MAL_ESR_OSEI 0x00000002 +#define MAL_ESR_PBEI 0x00000001 +#if MAL_VERSION == 1 +#define MAL_ESR_ONE 0x00080000 +#define MAL_ESR_ONEI 0x00000008 +#elif MAL_VERSION == 2 +#define MAL_ESR_PTE 0x00800000 +#define MAL_ESR_PRE 0x00400000 +#define MAL_ESR_PWE 0x00200000 +#define MAL_ESR_PTEI 0x00000080 +#define MAL_ESR_PREI 0x00000040 +#define MAL_ESR_PWEI 0x00000020 +#else +#error "Unknown MAL version" +#endif + +#define MAL_IER 0x02 +#define MAL_IER_DE 0x00000010 +#define MAL_IER_OTE 0x00000004 +#define MAL_IER_OE 0x00000002 +#define MAL_IER_PE 0x00000001 +#if MAL_VERSION == 1 +#define MAL_IER_NWE 0x00000008 +#define MAL_IER_SOC_EVENTS MAL_IER_NWE +#elif MAL_VERSION == 2 +#define MAL_IER_PT 0x00000080 +#define MAL_IER_PRE 0x00000040 +#define MAL_IER_PWE 0x00000020 +#define MAL_IER_SOC_EVENTS (MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE) +#else +#error "Unknown MAL version" +#endif +#define MAL_IER_EVENTS (MAL_IER_SOC_EVENTS | MAL_IER_OTE | \ + MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE) + +#define MAL_TXCASR 0x04 +#define MAL_TXCARR 0x05 +#define MAL_TXEOBISR 0x06 +#define MAL_TXDEIR 0x07 +#define MAL_RXCASR 0x10 +#define MAL_RXCARR 0x11 +#define MAL_RXEOBISR 0x12 +#define MAL_RXDEIR 0x13 +#define MAL_TXCTPR(n) ((n) + 0x20) +#define MAL_RXCTPR(n) ((n) + 0x40) +#define MAL_RCBS(n) ((n) + 0x60) + +/* In reality MAL can handle TX buffers up to 4095 bytes long, + * but this isn't a good round number :) --ebs + */ +#define MAL_MAX_TX_SIZE 4080 +#define MAL_MAX_RX_SIZE 4080 + +static inline int mal_rx_size(int len) +{ + len = (len + 0xf) & ~0xf; + return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len; +} + +static inline int mal_tx_chunks(int len) +{ + return (len + MAL_MAX_TX_SIZE - 1) / MAL_MAX_TX_SIZE; +} + +#define MAL_CHAN_MASK(n) (0x80000000 >> (n)) /* MAL Buffer Descriptor structure */ struct mal_descriptor { - unsigned short ctrl; /* MAL / Commac status control bits */ - short data_len; /* Max length is 4K-1 (12 bits) */ - unsigned char *data_ptr; /* pointer to actual data buffer */ -} __attribute__ ((packed)); + u16 ctrl; /* MAL / Commac status control bits */ + u16 data_len; /* Max length is 4K-1 (12 bits) */ + u32 data_ptr; /* pointer to actual data buffer */ +}; /* the following defines are for the MadMAL status and control registers. */ /* MADMAL transmit and receive status/control bits */ -#define MAL_RX_CTRL_EMPTY 0x8000 -#define MAL_RX_CTRL_WRAP 0x4000 -#define MAL_RX_CTRL_CM 0x2000 -#define MAL_RX_CTRL_LAST 0x1000 -#define MAL_RX_CTRL_FIRST 0x0800 -#define MAL_RX_CTRL_INTR 0x0400 +#define MAL_RX_CTRL_EMPTY 0x8000 +#define MAL_RX_CTRL_WRAP 0x4000 +#define MAL_RX_CTRL_CM 0x2000 +#define MAL_RX_CTRL_LAST 0x1000 +#define MAL_RX_CTRL_FIRST 0x0800 +#define MAL_RX_CTRL_INTR 0x0400 +#define MAL_RX_CTRL_SINGLE (MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST) +#define MAL_IS_SINGLE_RX(ctrl) (((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE) -#define MAL_TX_CTRL_READY 0x8000 -#define MAL_TX_CTRL_WRAP 0x4000 -#define MAL_TX_CTRL_CM 0x2000 -#define MAL_TX_CTRL_LAST 0x1000 -#define MAL_TX_CTRL_INTR 0x0400 +#define MAL_TX_CTRL_READY 0x8000 +#define MAL_TX_CTRL_WRAP 0x4000 +#define MAL_TX_CTRL_CM 0x2000 +#define MAL_TX_CTRL_LAST 0x1000 +#define MAL_TX_CTRL_INTR 0x0400 struct mal_commac_ops { - void (*txeob) (void *dev, u32 chanmask); - void (*txde) (void *dev, u32 chanmask); - void (*rxeob) (void *dev, u32 chanmask); - void (*rxde) (void *dev, u32 chanmask); + void (*poll_tx) (void *dev); + int (*poll_rx) (void *dev, int budget); + int (*peek_rx) (void *dev); + void (*rxde) (void *dev); }; struct mal_commac { - struct mal_commac_ops *ops; - void *dev; - u32 tx_chan_mask, rx_chan_mask; - struct list_head list; + struct mal_commac_ops *ops; + void *dev; + struct list_head poll_list; + int rx_stopped; + + u32 tx_chan_mask; + u32 rx_chan_mask; + struct list_head list; }; struct ibm_ocp_mal { - int dcrbase; + int dcrbase; - struct list_head commac; - u32 tx_chan_mask, rx_chan_mask; + struct list_head poll_list; + struct net_device poll_dev; - dma_addr_t tx_phys_addr; - struct mal_descriptor *tx_virt_addr; + struct list_head list; + u32 tx_chan_mask; + u32 rx_chan_mask; - dma_addr_t rx_phys_addr; - struct mal_descriptor *rx_virt_addr; + dma_addr_t bd_dma; + struct mal_descriptor *bd_virt; + + struct ocp_def *def; }; -#define GET_MAL_STANZA(base,dcrn) \ - case base: \ - x = mfdcr(dcrn(base)); \ - break; - -#define SET_MAL_STANZA(base,dcrn, val) \ - case base: \ - mtdcr(dcrn(base), (val)); \ - break; - -#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn) -#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val) - -#ifdef DCRN_MAL1_BASE -#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn) -#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val) -#else /* ! DCRN_MAL1_BASE */ -#define GET_MAL1_STANZA(dcrn) -#define SET_MAL1_STANZA(dcrn,val) -#endif - -#define get_mal_dcrn(mal, dcrn) ({ \ - u32 x; \ - switch ((mal)->dcrbase) { \ - GET_MAL0_STANZA(dcrn) \ - GET_MAL1_STANZA(dcrn) \ - default: \ - x = 0; \ - BUG(); \ - } \ -x; }) - -#define set_mal_dcrn(mal, dcrn, val) do { \ - switch ((mal)->dcrbase) { \ - SET_MAL0_STANZA(dcrn,val) \ - SET_MAL1_STANZA(dcrn,val) \ - default: \ - BUG(); \ - } } while (0) - -static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask) +static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg) { - set_mal_dcrn(mal, DCRN_MALTXCASR, - get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask); + return mfdcr(mal->dcrbase + reg); } -static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal, - u32 chanmask) +static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val) { - set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask); + mtdcr(mal->dcrbase + reg, val); } -static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask) -{ - set_mal_dcrn(mal, DCRN_MALRXCASR, - get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask); -} +/* Register MAL devices */ +int mal_init(void) __init; +void mal_exit(void) __exit; -static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal, - u32 chanmask) -{ - set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask); -} +int mal_register_commac(struct ibm_ocp_mal *mal, + struct mal_commac *commac) __init; +void mal_unregister_commac(struct ibm_ocp_mal *mal, + struct mal_commac *commac) __exit; +int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size); -extern int mal_register_commac(struct ibm_ocp_mal *mal, - struct mal_commac *commac); -extern int mal_unregister_commac(struct ibm_ocp_mal *mal, - struct mal_commac *commac); +/* Returns BD ring offset for a particular channel + (in 'struct mal_descriptor' elements) +*/ +int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel); +int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel); -extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, - unsigned long size); +void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel); +void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel); +void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel); +void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel); -#endif /* _IBM_EMAC_MAL_H */ +/* Add/remove EMAC to/from MAL polling list */ +void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac); +void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac); + +/* Ethtool MAL registers */ +struct ibm_mal_regs { + u32 tx_count; + u32 rx_count; + + u32 cfg; + u32 esr; + u32 ier; + u32 tx_casr; + u32 tx_carr; + u32 tx_eobisr; + u32 tx_deir; + u32 rx_casr; + u32 rx_carr; + u32 rx_eobisr; + u32 rx_deir; + u32 tx_ctpr[32]; + u32 rx_ctpr[32]; + u32 rcbs[32]; +}; + +int mal_get_regs_len(struct ibm_ocp_mal *mal); +void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf); + +#endif /* __IBM_EMAC_MAL_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c index 14213f090e91..a27e49cfe43b 100644 --- a/drivers/net/ibm_emac/ibm_emac_phy.c +++ b/drivers/net/ibm_emac/ibm_emac_phy.c @@ -1,61 +1,256 @@ /* - * ibm_ocp_phy.c + * drivers/net/ibm_emac/ibm_emac_phy.c * - * PHY drivers for the ibm ocp ethernet driver. Borrowed - * from sungem_phy.c, though I only kept the generic MII + * Driver for PowerPC 4xx on-chip ethernet controller, PHY support. + * Borrowed from sungem_phy.c, though I only kept the generic MII * driver for now. * * This file should be shared with other drivers or eventually * merged as the "low level" part of miilib * * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org) + * (c) 2004-2005, Eugene Surovegin * */ - #include - #include - #include -#include #include #include -#include #include #include #include +#include + #include "ibm_emac_phy.h" -static int reset_one_mii_phy(struct mii_phy *phy, int phy_id) +static inline int phy_read(struct mii_phy *phy, int reg) { - u16 val; + return phy->mdio_read(phy->dev, phy->address, reg); +} + +static inline void phy_write(struct mii_phy *phy, int reg, int val) +{ + phy->mdio_write(phy->dev, phy->address, reg, val); +} + +int mii_reset_phy(struct mii_phy *phy) +{ + int val; int limit = 10000; - val = __phy_read(phy, phy_id, MII_BMCR); + val = phy_read(phy, MII_BMCR); val &= ~BMCR_ISOLATE; val |= BMCR_RESET; - __phy_write(phy, phy_id, MII_BMCR, val); + phy_write(phy, MII_BMCR, val); - udelay(100); + udelay(300); while (limit--) { - val = __phy_read(phy, phy_id, MII_BMCR); - if ((val & BMCR_RESET) == 0) + val = phy_read(phy, MII_BMCR); + if (val >= 0 && (val & BMCR_RESET) == 0) break; udelay(10); } if ((val & BMCR_ISOLATE) && limit > 0) - __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); + phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE); - return (limit <= 0); + return limit <= 0; } +static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) +{ + int ctl, adv; + + phy->autoneg = AUTONEG_ENABLE; + phy->speed = SPEED_10; + phy->duplex = DUPLEX_HALF; + phy->pause = phy->asym_pause = 0; + phy->advertising = advertise; + + /* Setup standard advertise */ + adv = phy_read(phy, MII_ADVERTISE); + if (adv < 0) + return adv; + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + if (advertise & ADVERTISED_10baseT_Half) + adv |= ADVERTISE_10HALF; + if (advertise & ADVERTISED_10baseT_Full) + adv |= ADVERTISE_10FULL; + if (advertise & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + if (advertise & ADVERTISED_Pause) + adv |= ADVERTISE_PAUSE_CAP; + if (advertise & ADVERTISED_Asym_Pause) + adv |= ADVERTISE_PAUSE_ASYM; + phy_write(phy, MII_ADVERTISE, adv); + + if (phy->features & + (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) { + adv = phy_read(phy, MII_CTRL1000); + if (adv < 0) + return adv; + adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if (advertise & ADVERTISED_1000baseT_Full) + adv |= ADVERTISE_1000FULL; + if (advertise & ADVERTISED_1000baseT_Half) + adv |= ADVERTISE_1000HALF; + phy_write(phy, MII_CTRL1000, adv); + } + + /* Start/Restart aneg */ + ctl = phy_read(phy, MII_BMCR); + ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); + phy_write(phy, MII_BMCR, ctl); + + return 0; +} + +static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) +{ + int ctl; + + phy->autoneg = AUTONEG_DISABLE; + phy->speed = speed; + phy->duplex = fd; + phy->pause = phy->asym_pause = 0; + + ctl = phy_read(phy, MII_BMCR); + if (ctl < 0) + return ctl; + ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE); + + /* First reset the PHY */ + phy_write(phy, MII_BMCR, ctl | BMCR_RESET); + + /* Select speed & duplex */ + switch (speed) { + case SPEED_10: + break; + case SPEED_100: + ctl |= BMCR_SPEED100; + break; + case SPEED_1000: + ctl |= BMCR_SPEED1000; + break; + default: + return -EINVAL; + } + if (fd == DUPLEX_FULL) + ctl |= BMCR_FULLDPLX; + phy_write(phy, MII_BMCR, ctl); + + return 0; +} + +static int genmii_poll_link(struct mii_phy *phy) +{ + int status; + + /* Clear latched value with dummy read */ + phy_read(phy, MII_BMSR); + status = phy_read(phy, MII_BMSR); + if (status < 0 || (status & BMSR_LSTATUS) == 0) + return 0; + if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE)) + return 0; + return 1; +} + +static int genmii_read_link(struct mii_phy *phy) +{ + if (phy->autoneg == AUTONEG_ENABLE) { + int glpa = 0; + int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE); + if (lpa < 0) + return lpa; + + if (phy->features & + (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) { + int adv = phy_read(phy, MII_CTRL1000); + glpa = phy_read(phy, MII_STAT1000); + + if (glpa < 0 || adv < 0) + return adv; + + glpa &= adv << 2; + } + + phy->speed = SPEED_10; + phy->duplex = DUPLEX_HALF; + phy->pause = phy->asym_pause = 0; + + if (glpa & (LPA_1000FULL | LPA_1000HALF)) { + phy->speed = SPEED_1000; + if (glpa & LPA_1000FULL) + phy->duplex = DUPLEX_FULL; + } else if (lpa & (LPA_100FULL | LPA_100HALF)) { + phy->speed = SPEED_100; + if (lpa & LPA_100FULL) + phy->duplex = DUPLEX_FULL; + } else if (lpa & LPA_10FULL) + phy->duplex = DUPLEX_FULL; + + if (phy->duplex == DUPLEX_FULL) { + phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; + phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; + } + } else { + int bmcr = phy_read(phy, MII_BMCR); + if (bmcr < 0) + return bmcr; + + if (bmcr & BMCR_FULLDPLX) + phy->duplex = DUPLEX_FULL; + else + phy->duplex = DUPLEX_HALF; + if (bmcr & BMCR_SPEED1000) + phy->speed = SPEED_1000; + else if (bmcr & BMCR_SPEED100) + phy->speed = SPEED_100; + else + phy->speed = SPEED_10; + + phy->pause = phy->asym_pause = 0; + } + return 0; +} + +/* Generic implementation for most 10/100/1000 PHYs */ +static struct mii_phy_ops generic_phy_ops = { + .setup_aneg = genmii_setup_aneg, + .setup_forced = genmii_setup_forced, + .poll_link = genmii_poll_link, + .read_link = genmii_read_link +}; + +static struct mii_phy_def genmii_phy_def = { + .phy_id = 0x00000000, + .phy_id_mask = 0x00000000, + .name = "Generic MII", + .ops = &generic_phy_ops +}; + +/* CIS8201 */ +#define MII_CIS8201_EPCR 0x17 +#define EPCR_MODE_MASK 0x3000 +#define EPCR_GMII_MODE 0x0000 +#define EPCR_RGMII_MODE 0x1000 +#define EPCR_TBI_MODE 0x2000 +#define EPCR_RTBI_MODE 0x3000 + static int cis8201_init(struct mii_phy *phy) { - u16 epcr; + int epcr; epcr = phy_read(phy, MII_CIS8201_EPCR); + if (epcr < 0) + return epcr; + epcr &= ~EPCR_MODE_MASK; switch (phy->mode) { @@ -78,178 +273,19 @@ static int cis8201_init(struct mii_phy *phy) return 0; } -static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) -{ - u16 ctl, adv; - - phy->autoneg = 1; - phy->speed = SPEED_10; - phy->duplex = DUPLEX_HALF; - phy->pause = 0; - phy->advertising = advertise; - - /* Setup standard advertise */ - adv = phy_read(phy, MII_ADVERTISE); - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); - if (advertise & ADVERTISED_10baseT_Half) - adv |= ADVERTISE_10HALF; - if (advertise & ADVERTISED_10baseT_Full) - adv |= ADVERTISE_10FULL; - if (advertise & ADVERTISED_100baseT_Half) - adv |= ADVERTISE_100HALF; - if (advertise & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL; - phy_write(phy, MII_ADVERTISE, adv); - - /* Start/Restart aneg */ - ctl = phy_read(phy, MII_BMCR); - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - phy_write(phy, MII_BMCR, ctl); - - return 0; -} - -static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) -{ - u16 ctl; - - phy->autoneg = 0; - phy->speed = speed; - phy->duplex = fd; - phy->pause = 0; - - ctl = phy_read(phy, MII_BMCR); - ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE); - - /* First reset the PHY */ - phy_write(phy, MII_BMCR, ctl | BMCR_RESET); - - /* Select speed & duplex */ - switch (speed) { - case SPEED_10: - break; - case SPEED_100: - ctl |= BMCR_SPEED100; - break; - case SPEED_1000: - default: - return -EINVAL; - } - if (fd == DUPLEX_FULL) - ctl |= BMCR_FULLDPLX; - phy_write(phy, MII_BMCR, ctl); - - return 0; -} - -static int genmii_poll_link(struct mii_phy *phy) -{ - u16 status; - - (void)phy_read(phy, MII_BMSR); - status = phy_read(phy, MII_BMSR); - if ((status & BMSR_LSTATUS) == 0) - return 0; - if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE)) - return 0; - return 1; -} - -#define MII_CIS8201_ACSR 0x1c -#define ACSR_DUPLEX_STATUS 0x0020 -#define ACSR_SPEED_1000BASET 0x0010 -#define ACSR_SPEED_100BASET 0x0008 - -static int cis8201_read_link(struct mii_phy *phy) -{ - u16 acsr; - - if (phy->autoneg) { - acsr = phy_read(phy, MII_CIS8201_ACSR); - - if (acsr & ACSR_DUPLEX_STATUS) - phy->duplex = DUPLEX_FULL; - else - phy->duplex = DUPLEX_HALF; - if (acsr & ACSR_SPEED_1000BASET) { - phy->speed = SPEED_1000; - } else if (acsr & ACSR_SPEED_100BASET) - phy->speed = SPEED_100; - else - phy->speed = SPEED_10; - phy->pause = 0; - } - /* On non-aneg, we assume what we put in BMCR is the speed, - * though magic-aneg shouldn't prevent this case from occurring - */ - - return 0; -} - -static int genmii_read_link(struct mii_phy *phy) -{ - u16 lpa; - - if (phy->autoneg) { - lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE); - - phy->speed = SPEED_10; - phy->duplex = DUPLEX_HALF; - phy->pause = 0; - - if (lpa & (LPA_100FULL | LPA_100HALF)) { - phy->speed = SPEED_100; - if (lpa & LPA_100FULL) - phy->duplex = DUPLEX_FULL; - } else if (lpa & LPA_10FULL) - phy->duplex = DUPLEX_FULL; - } - /* On non-aneg, we assume what we put in BMCR is the speed, - * though magic-aneg shouldn't prevent this case from occurring - */ - - return 0; -} - -#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ - SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII) -#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ - SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) - -/* CIS8201 phy ops */ static struct mii_phy_ops cis8201_phy_ops = { - init:cis8201_init, - setup_aneg:genmii_setup_aneg, - setup_forced:genmii_setup_forced, - poll_link:genmii_poll_link, - read_link:cis8201_read_link -}; - -/* Generic implementation for most 10/100 PHYs */ -static struct mii_phy_ops generic_phy_ops = { - setup_aneg:genmii_setup_aneg, - setup_forced:genmii_setup_forced, - poll_link:genmii_poll_link, - read_link:genmii_read_link + .init = cis8201_init, + .setup_aneg = genmii_setup_aneg, + .setup_forced = genmii_setup_forced, + .poll_link = genmii_poll_link, + .read_link = genmii_read_link }; static struct mii_phy_def cis8201_phy_def = { - phy_id:0x000fc410, - phy_id_mask:0x000ffff0, - name:"CIS8201 Gigabit Ethernet", - features:MII_GBIT_FEATURES, - magic_aneg:0, - ops:&cis8201_phy_ops -}; - -static struct mii_phy_def genmii_phy_def = { - phy_id:0x00000000, - phy_id_mask:0x00000000, - name:"Generic MII", - features:MII_BASIC_FEATURES, - magic_aneg:0, - ops:&generic_phy_ops + .phy_id = 0x000fc410, + .phy_id_mask = 0x000ffff0, + .name = "CIS8201 Gigabit Ethernet", + .ops = &cis8201_phy_ops }; static struct mii_phy_def *mii_phy_table[] = { @@ -258,39 +294,60 @@ static struct mii_phy_def *mii_phy_table[] = { NULL }; -int mii_phy_probe(struct mii_phy *phy, int mii_id) +int mii_phy_probe(struct mii_phy *phy, int address) { - int rc; - u32 id; struct mii_phy_def *def; int i; + u32 id; - phy->autoneg = 0; + phy->autoneg = AUTONEG_DISABLE; phy->advertising = 0; - phy->mii_id = mii_id; - phy->speed = 0; - phy->duplex = 0; - phy->pause = 0; + phy->address = address; + phy->speed = SPEED_10; + phy->duplex = DUPLEX_HALF; + phy->pause = phy->asym_pause = 0; - /* Take PHY out of isloate mode and reset it. */ - rc = reset_one_mii_phy(phy, mii_id); - if (rc) + /* Take PHY out of isolate mode and reset it. */ + if (mii_reset_phy(phy)) return -ENODEV; /* Read ID and find matching entry */ - id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)) - & 0xfffffff0; + id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2); for (i = 0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; /* Should never be NULL (we have a generic entry), but... */ - if (def == NULL) + if (!def) return -ENODEV; phy->def = def; + /* Determine PHY features if needed */ + phy->features = def->features; + if (!phy->features) { + u16 bmsr = phy_read(phy, MII_BMSR); + if (bmsr & BMSR_ANEGCAPABLE) + phy->features |= SUPPORTED_Autoneg; + if (bmsr & BMSR_10HALF) + phy->features |= SUPPORTED_10baseT_Half; + if (bmsr & BMSR_10FULL) + phy->features |= SUPPORTED_10baseT_Full; + if (bmsr & BMSR_100HALF) + phy->features |= SUPPORTED_100baseT_Half; + if (bmsr & BMSR_100FULL) + phy->features |= SUPPORTED_100baseT_Full; + if (bmsr & BMSR_ESTATEN) { + u16 esr = phy_read(phy, MII_ESTATUS); + if (esr & ESTATUS_1000_TFULL) + phy->features |= SUPPORTED_1000baseT_Full; + if (esr & ESTATUS_1000_THALF) + phy->features |= SUPPORTED_1000baseT_Half; + } + phy->features |= SUPPORTED_MII; + } + /* Setup default advertising */ - phy->advertising = def->features; + phy->advertising = phy->features; return 0; } diff --git a/drivers/net/ibm_emac/ibm_emac_phy.h b/drivers/net/ibm_emac/ibm_emac_phy.h index 61afbea96563..a70e0fea54c4 100644 --- a/drivers/net/ibm_emac/ibm_emac_phy.h +++ b/drivers/net/ibm_emac/ibm_emac_phy.h @@ -1,65 +1,25 @@ - /* - * ibm_emac_phy.h + * drivers/net/ibm_emac/ibm_emac_phy.h * + * Driver for PowerPC 4xx on-chip ethernet controller, PHY support * - * Benjamin Herrenschmidt - * February 2003 + * Benjamin Herrenschmidt + * February 2003 + * + * Minor additions by Eugene Surovegin , 2004 * * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * + * 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 file basically duplicates sungem_phy.{c,h} with different PHYs * supported. I'm looking into merging that in a single mii layer more * flexible than mii.c */ -#ifndef _IBM_EMAC_PHY_H_ -#define _IBM_EMAC_PHY_H_ - -/* - * PHY mode settings - * Used for multi-mode capable PHYs - */ -#define PHY_MODE_NA 0 -#define PHY_MODE_MII 1 -#define PHY_MODE_RMII 2 -#define PHY_MODE_SMII 3 -#define PHY_MODE_RGMII 4 -#define PHY_MODE_TBI 5 -#define PHY_MODE_GMII 6 -#define PHY_MODE_RTBI 7 -#define PHY_MODE_SGMII 8 - -/* - * PHY specific registers/values - */ - -/* CIS8201 */ -#define MII_CIS8201_EPCR 0x17 -#define EPCR_MODE_MASK 0x3000 -#define EPCR_GMII_MODE 0x0000 -#define EPCR_RGMII_MODE 0x1000 -#define EPCR_TBI_MODE 0x2000 -#define EPCR_RTBI_MODE 0x3000 +#ifndef _IBM_OCP_PHY_H_ +#define _IBM_OCP_PHY_H_ struct mii_phy; @@ -77,7 +37,8 @@ struct mii_phy_ops { struct mii_phy_def { u32 phy_id; /* Concatenated ID1 << 16 | ID2 */ u32 phy_id_mask; /* Significant bits */ - u32 features; /* Ethtool SUPPORTED_* defines */ + u32 features; /* Ethtool SUPPORTED_* defines or + 0 for autodetect */ int magic_aneg; /* Autoneg does all speed test for us */ const char *name; const struct mii_phy_ops *ops; @@ -86,8 +47,11 @@ struct mii_phy_def { /* An instance of a PHY, partially borrowed from mii_if_info */ struct mii_phy { struct mii_phy_def *def; - int advertising; - int mii_id; + u32 advertising; /* Ethtool ADVERTISED_* defines */ + u32 features; /* Copied from mii_phy_def.features + or determined automaticaly */ + int address; /* PHY address */ + int mode; /* PHY mode */ /* 1: autoneg enabled, 0: disabled */ int autoneg; @@ -98,40 +62,19 @@ struct mii_phy { int speed; int duplex; int pause; - - /* PHY mode - if needed */ - int mode; + int asym_pause; /* Provided by host chip */ struct net_device *dev; - int (*mdio_read) (struct net_device * dev, int mii_id, int reg); - void (*mdio_write) (struct net_device * dev, int mii_id, int reg, + int (*mdio_read) (struct net_device * dev, int addr, int reg); + void (*mdio_write) (struct net_device * dev, int addr, int reg, int val); }; /* Pass in a struct mii_phy with dev, mdio_read and mdio_write * filled, the remaining fields will be filled on return */ -extern int mii_phy_probe(struct mii_phy *phy, int mii_id); +int mii_phy_probe(struct mii_phy *phy, int address); +int mii_reset_phy(struct mii_phy *phy); -static inline int __phy_read(struct mii_phy *phy, int id, int reg) -{ - return phy->mdio_read(phy->dev, id, reg); -} - -static inline void __phy_write(struct mii_phy *phy, int id, int reg, int val) -{ - phy->mdio_write(phy->dev, id, reg, val); -} - -static inline int phy_read(struct mii_phy *phy, int reg) -{ - return phy->mdio_read(phy->dev, phy->mii_id, reg); -} - -static inline void phy_write(struct mii_phy *phy, int reg, int val) -{ - phy->mdio_write(phy->dev, phy->mii_id, reg, val); -} - -#endif /* _IBM_EMAC_PHY_H_ */ +#endif /* _IBM_OCP_PHY_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c new file mode 100644 index 000000000000..f0b1ffb2dbbf --- /dev/null +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.c @@ -0,0 +1,201 @@ +/* + * drivers/net/ibm_emac/ibm_emac_rgmii.c + * + * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. + * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or + * + * Based on original work by + * Matt Porter + * Copyright 2004 MontaVista Software, 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 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +#include "ibm_emac_core.h" +#include "ibm_emac_debug.h" + +/* RGMIIx_FER */ +#define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4)) +#define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4)) +#define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) +#define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) +#define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) + +/* RGMIIx_SSR */ +#define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) +#define RGMII_SSR_100(idx) (0x2 << ((idx) * 8)) +#define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8)) + +/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */ +static inline int rgmii_valid_mode(int phy_mode) +{ + return phy_mode == PHY_MODE_GMII || + phy_mode == PHY_MODE_RGMII || + phy_mode == PHY_MODE_TBI || + phy_mode == PHY_MODE_RTBI; +} + +static inline const char *rgmii_mode_name(int mode) +{ + switch (mode) { + case PHY_MODE_RGMII: + return "RGMII"; + case PHY_MODE_TBI: + return "TBI"; + case PHY_MODE_GMII: + return "GMII"; + case PHY_MODE_RTBI: + return "RTBI"; + default: + BUG(); + } +} + +static inline u32 rgmii_mode_mask(int mode, int input) +{ + switch (mode) { + case PHY_MODE_RGMII: + return RGMII_FER_RGMII(input); + case PHY_MODE_TBI: + return RGMII_FER_TBI(input); + case PHY_MODE_GMII: + return RGMII_FER_GMII(input); + case PHY_MODE_RTBI: + return RGMII_FER_RTBI(input); + default: + BUG(); + } +} + +static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode) +{ + struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); + struct rgmii_regs *p; + + RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode); + + if (!dev) { + dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL); + if (!dev) { + printk(KERN_ERR + "rgmii%d: couldn't allocate device structure!\n", + ocpdev->def->index); + return -ENOMEM; + } + + p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr, + sizeof(struct rgmii_regs)); + if (!p) { + printk(KERN_ERR + "rgmii%d: could not ioremap device registers!\n", + ocpdev->def->index); + kfree(dev); + return -ENOMEM; + } + + dev->base = p; + ocp_set_drvdata(ocpdev, dev); + + /* Disable all inputs by default */ + out_be32(&p->fer, 0); + } else + p = dev->base; + + /* Enable this input */ + out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); + + printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n", + ocpdev->def->index, input, rgmii_mode_name(mode)); + + ++dev->users; + return 0; +} + +int __init rgmii_attach(void *emac) +{ + struct ocp_enet_private *dev = emac; + struct ocp_func_emac_data *emacdata = dev->def->additions; + + /* Check if we need to attach to a RGMII */ + if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) { + dev->rgmii_input = emacdata->rgmii_mux; + dev->rgmii_dev = + ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII, + emacdata->rgmii_idx); + if (!dev->rgmii_dev) { + printk(KERN_ERR "emac%d: unknown rgmii%d!\n", + dev->def->index, emacdata->rgmii_idx); + return -ENODEV; + } + if (rgmii_init + (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) { + printk(KERN_ERR + "emac%d: rgmii%d initialization failed!\n", + dev->def->index, emacdata->rgmii_idx); + return -ENODEV; + } + } + return 0; +} + +void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed) +{ + struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); + u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input); + + RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed); + + if (speed == SPEED_1000) + ssr |= RGMII_SSR_1000(input); + else if (speed == SPEED_100) + ssr |= RGMII_SSR_100(input); + + out_be32(&dev->base->ssr, ssr); +} + +void __exit __rgmii_fini(struct ocp_device *ocpdev, int input) +{ + struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); + BUG_ON(!dev || dev->users == 0); + + RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input); + + /* Disable this input */ + out_be32(&dev->base->fer, + in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input)); + + if (!--dev->users) { + /* Free everything if this is the last user */ + ocp_set_drvdata(ocpdev, NULL); + iounmap((void *)dev->base); + kfree(dev); + } +} + +int __rgmii_get_regs_len(struct ocp_device *ocpdev) +{ + return sizeof(struct emac_ethtool_regs_subhdr) + + sizeof(struct rgmii_regs); +} + +void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf) +{ + struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev); + struct emac_ethtool_regs_subhdr *hdr = buf; + struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1); + + hdr->version = 0; + hdr->index = ocpdev->def->index; + memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs)); + return regs + 1; +} diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h index 49f188f4ea6e..a1ffb8a44fff 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h @@ -1,5 +1,7 @@ /* - * Defines for the IBM RGMII bridge + * drivers/net/ibm_emac/ibm_emac_rgmii.c + * + * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. * * Based on ocp_zmii.h/ibm_emac_zmii.h * Armin Kuster akuster@mvista.com @@ -7,6 +9,9 @@ * Copyright 2004 MontaVista Software, Inc. * Matt Porter * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or + * * 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 @@ -19,47 +24,42 @@ #include /* RGMII bridge */ -typedef struct rgmii_regs { +struct rgmii_regs { u32 fer; /* Function enable register */ u32 ssr; /* Speed select register */ -} rgmii_t; - -#define RGMII_INPUTS 4 +}; /* RGMII device */ struct ibm_ocp_rgmii { struct rgmii_regs *base; - int mode[RGMII_INPUTS]; int users; /* number of EMACs using this RGMII bridge */ }; -/* Fuctional Enable Reg */ -#define RGMII_FER_MASK(x) (0x00000007 << (4*x)) -#define RGMII_RTBI 0x00000004 -#define RGMII_RGMII 0x00000005 -#define RGMII_TBI 0x00000006 -#define RGMII_GMII 0x00000007 +#ifdef CONFIG_IBM_EMAC_RGMII +int rgmii_attach(void *emac) __init; -/* Speed Selection reg */ +void __rgmii_fini(struct ocp_device *ocpdev, int input) __exit; +static inline void rgmii_fini(struct ocp_device *ocpdev, int input) +{ + if (ocpdev) + __rgmii_fini(ocpdev, input); +} -#define RGMII_SP2_100 0x00000002 -#define RGMII_SP2_1000 0x00000004 -#define RGMII_SP3_100 0x00000200 -#define RGMII_SP3_1000 0x00000400 +void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed); -#define RGMII_MII2_SPDMASK 0x00000007 -#define RGMII_MII3_SPDMASK 0x00000700 +int __rgmii_get_regs_len(struct ocp_device *ocpdev); +static inline int rgmii_get_regs_len(struct ocp_device *ocpdev) +{ + return ocpdev ? __rgmii_get_regs_len(ocpdev) : 0; +} -#define RGMII_MII2_100MB RGMII_SP2_100 & ~RGMII_SP2_1000 -#define RGMII_MII2_1000MB RGMII_SP2_1000 & ~RGMII_SP2_100 -#define RGMII_MII2_10MB ~(RGMII_SP2_100 | RGMII_SP2_1000) -#define RGMII_MII3_100MB RGMII_SP3_100 & ~RGMII_SP3_1000 -#define RGMII_MII3_1000MB RGMII_SP3_1000 & ~RGMII_SP3_100 -#define RGMII_MII3_10MB ~(RGMII_SP3_100 | RGMII_SP3_1000) - -#define RTBI 0 -#define RGMII 1 -#define TBI 2 -#define GMII 3 +void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf); +#else +# define rgmii_attach(x) 0 +# define rgmii_fini(x,y) ((void)0) +# define rgmii_set_speed(x,y,z) ((void)0) +# define rgmii_get_regs_len(x) 0 +# define rgmii_dump_regs(x,buf) (buf) +#endif /* !CONFIG_IBM_EMAC_RGMII */ #endif /* _IBM_EMAC_RGMII_H_ */ diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c new file mode 100644 index 000000000000..af08afc22f9f --- /dev/null +++ b/drivers/net/ibm_emac/ibm_emac_tah.c @@ -0,0 +1,111 @@ +/* + * drivers/net/ibm_emac/ibm_emac_tah.c + * + * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. + * + * Copyright 2004 MontaVista Software, Inc. + * Matt Porter + * + * Copyright (c) 2005 Eugene Surovegin + * + * 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. + */ +#include +#include + +#include "ibm_emac_core.h" + +static int __init tah_init(struct ocp_device *ocpdev) +{ + struct tah_regs *p; + + if (ocp_get_drvdata(ocpdev)) { + printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index); + return -EBUSY; + } + + /* Initialize TAH and enable IPv4 checksum verification, no TSO yet */ + p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p)); + if (!p) { + printk(KERN_ERR "tah%d: could not ioremap device registers!\n", + ocpdev->def->index); + return -ENOMEM; + } + ocp_set_drvdata(ocpdev, p); + __tah_reset(ocpdev); + + return 0; +} + +int __init tah_attach(void *emac) +{ + struct ocp_enet_private *dev = emac; + struct ocp_func_emac_data *emacdata = dev->def->additions; + + /* Check if we need to attach to a TAH */ + if (emacdata->tah_idx >= 0) { + dev->tah_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH, + emacdata->tah_idx); + if (!dev->tah_dev) { + printk(KERN_ERR "emac%d: unknown tah%d!\n", + dev->def->index, emacdata->tah_idx); + return -ENODEV; + } + if (tah_init(dev->tah_dev)) { + printk(KERN_ERR + "emac%d: tah%d initialization failed!\n", + dev->def->index, emacdata->tah_idx); + return -ENODEV; + } + } + return 0; +} + +void __exit __tah_fini(struct ocp_device *ocpdev) +{ + struct tah_regs *p = ocp_get_drvdata(ocpdev); + BUG_ON(!p); + ocp_set_drvdata(ocpdev, NULL); + iounmap((void *)p); +} + +void __tah_reset(struct ocp_device *ocpdev) +{ + struct tah_regs *p = ocp_get_drvdata(ocpdev); + int n; + + /* Reset TAH */ + out_be32(&p->mr, TAH_MR_SR); + n = 100; + while ((in_be32(&p->mr) & TAH_MR_SR) && n) + --n; + + if (unlikely(!n)) + printk(KERN_ERR "tah%d: reset timeout\n", ocpdev->def->index); + + /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ + out_be32(&p->mr, + TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | + TAH_MR_DIG); +} + +int __tah_get_regs_len(struct ocp_device *ocpdev) +{ + return sizeof(struct emac_ethtool_regs_subhdr) + + sizeof(struct tah_regs); +} + +void *tah_dump_regs(struct ocp_device *ocpdev, void *buf) +{ + struct tah_regs *dev = ocp_get_drvdata(ocpdev); + struct emac_ethtool_regs_subhdr *hdr = buf; + struct tah_regs *regs = (struct tah_regs *)(hdr + 1); + + hdr->version = 0; + hdr->index = ocpdev->def->index; + memcpy_fromio(regs, dev, sizeof(struct tah_regs)); + return regs + 1; +} diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h index ecfc69805521..9299b5dd7eb1 100644 --- a/drivers/net/ibm_emac/ibm_emac_tah.h +++ b/drivers/net/ibm_emac/ibm_emac_tah.h @@ -1,9 +1,13 @@ /* - * Defines for the IBM TAH + * drivers/net/ibm_emac/ibm_emac_tah.h + * + * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. * * Copyright 2004 MontaVista Software, Inc. * Matt Porter * + * Copyright (c) 2005 Eugene Surovegin + * * 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 @@ -13,36 +17,72 @@ #ifndef _IBM_EMAC_TAH_H #define _IBM_EMAC_TAH_H +#include +#include +#include + /* TAH */ -typedef struct tah_regs { - u32 tah_revid; +struct tah_regs { + u32 revid; u32 pad[3]; - u32 tah_mr; - u32 tah_ssr0; - u32 tah_ssr1; - u32 tah_ssr2; - u32 tah_ssr3; - u32 tah_ssr4; - u32 tah_ssr5; - u32 tah_tsr; -} tah_t; + u32 mr; + u32 ssr0; + u32 ssr1; + u32 ssr2; + u32 ssr3; + u32 ssr4; + u32 ssr5; + u32 tsr; +}; /* TAH engine */ -#define TAH_MR_CVR 0x80000000 -#define TAH_MR_SR 0x40000000 -#define TAH_MR_ST_256 0x01000000 -#define TAH_MR_ST_512 0x02000000 -#define TAH_MR_ST_768 0x03000000 -#define TAH_MR_ST_1024 0x04000000 -#define TAH_MR_ST_1280 0x05000000 -#define TAH_MR_ST_1536 0x06000000 -#define TAH_MR_TFS_16KB 0x00000000 -#define TAH_MR_TFS_2KB 0x00200000 -#define TAH_MR_TFS_4KB 0x00400000 -#define TAH_MR_TFS_6KB 0x00600000 -#define TAH_MR_TFS_8KB 0x00800000 -#define TAH_MR_TFS_10KB 0x00a00000 -#define TAH_MR_DTFP 0x00100000 -#define TAH_MR_DIG 0x00080000 +#define TAH_MR_CVR 0x80000000 +#define TAH_MR_SR 0x40000000 +#define TAH_MR_ST_256 0x01000000 +#define TAH_MR_ST_512 0x02000000 +#define TAH_MR_ST_768 0x03000000 +#define TAH_MR_ST_1024 0x04000000 +#define TAH_MR_ST_1280 0x05000000 +#define TAH_MR_ST_1536 0x06000000 +#define TAH_MR_TFS_16KB 0x00000000 +#define TAH_MR_TFS_2KB 0x00200000 +#define TAH_MR_TFS_4KB 0x00400000 +#define TAH_MR_TFS_6KB 0x00600000 +#define TAH_MR_TFS_8KB 0x00800000 +#define TAH_MR_TFS_10KB 0x00a00000 +#define TAH_MR_DTFP 0x00100000 +#define TAH_MR_DIG 0x00080000 + +#ifdef CONFIG_IBM_EMAC_TAH +int tah_attach(void *emac) __init; + +void __tah_fini(struct ocp_device *ocpdev) __exit; +static inline void tah_fini(struct ocp_device *ocpdev) +{ + if (ocpdev) + __tah_fini(ocpdev); +} + +void __tah_reset(struct ocp_device *ocpdev); +static inline void tah_reset(struct ocp_device *ocpdev) +{ + if (ocpdev) + __tah_reset(ocpdev); +} + +int __tah_get_regs_len(struct ocp_device *ocpdev); +static inline int tah_get_regs_len(struct ocp_device *ocpdev) +{ + return ocpdev ? __tah_get_regs_len(ocpdev) : 0; +} + +void *tah_dump_regs(struct ocp_device *ocpdev, void *buf); +#else +# define tah_attach(x) 0 +# define tah_fini(x) ((void)0) +# define tah_reset(x) ((void)0) +# define tah_get_regs_len(x) 0 +# define tah_dump_regs(x,buf) (buf) +#endif /* !CONFIG_IBM_EMAC_TAH */ #endif /* _IBM_EMAC_TAH_H */ diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c new file mode 100644 index 000000000000..35c1185079ed --- /dev/null +++ b/drivers/net/ibm_emac/ibm_emac_zmii.c @@ -0,0 +1,255 @@ +/* + * drivers/net/ibm_emac/ibm_emac_zmii.c + * + * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. + * + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or + * + * Based on original work by + * Armin Kuster + * Copyright 2001 MontaVista Softare 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 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +#include "ibm_emac_core.h" +#include "ibm_emac_debug.h" + +/* ZMIIx_FER */ +#define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4)) +#define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \ + ZMII_FER_MDI(2) | ZMII_FER_MDI(3)) + +#define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4)) +#define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4)) +#define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4)) + +/* ZMIIx_SSR */ +#define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4)) +#define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4)) +#define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4)) + +/* ZMII only supports MII, RMII and SMII + * we also support autodetection for backward compatibility + */ +static inline int zmii_valid_mode(int mode) +{ + return mode == PHY_MODE_MII || + mode == PHY_MODE_RMII || + mode == PHY_MODE_SMII || + mode == PHY_MODE_NA; +} + +static inline const char *zmii_mode_name(int mode) +{ + switch (mode) { + case PHY_MODE_MII: + return "MII"; + case PHY_MODE_RMII: + return "RMII"; + case PHY_MODE_SMII: + return "SMII"; + default: + BUG(); + } +} + +static inline u32 zmii_mode_mask(int mode, int input) +{ + switch (mode) { + case PHY_MODE_MII: + return ZMII_FER_MII(input); + case PHY_MODE_RMII: + return ZMII_FER_RMII(input); + case PHY_MODE_SMII: + return ZMII_FER_SMII(input); + default: + return 0; + } +} + +static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) +{ + struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); + struct zmii_regs *p; + + ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode); + + if (!dev) { + dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL); + if (!dev) { + printk(KERN_ERR + "zmii%d: couldn't allocate device structure!\n", + ocpdev->def->index); + return -ENOMEM; + } + dev->mode = PHY_MODE_NA; + + p = (struct zmii_regs *)ioremap(ocpdev->def->paddr, + sizeof(struct zmii_regs)); + if (!p) { + printk(KERN_ERR + "zmii%d: could not ioremap device registers!\n", + ocpdev->def->index); + kfree(dev); + return -ENOMEM; + } + dev->base = p; + ocp_set_drvdata(ocpdev, dev); + + /* We may need FER value for autodetection later */ + dev->fer_save = in_be32(&p->fer); + + /* Disable all inputs by default */ + out_be32(&p->fer, 0); + } else + p = dev->base; + + if (!zmii_valid_mode(*mode)) { + /* Probably an EMAC connected to RGMII, + * but it still may need ZMII for MDIO + */ + goto out; + } + + /* Autodetect ZMII mode if not specified. + * This is only for backward compatibility with the old driver. + * Please, always specify PHY mode in your board port to avoid + * any surprises. + */ + if (dev->mode == PHY_MODE_NA) { + if (*mode == PHY_MODE_NA) { + u32 r = dev->fer_save; + + ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL, + ocpdev->def->index, r); + + if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1))) + dev->mode = PHY_MODE_MII; + else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1))) + dev->mode = PHY_MODE_RMII; + else + dev->mode = PHY_MODE_SMII; + } else + dev->mode = *mode; + + printk(KERN_NOTICE "zmii%d: bridge in %s mode\n", + ocpdev->def->index, zmii_mode_name(dev->mode)); + } else { + /* All inputs must use the same mode */ + if (*mode != PHY_MODE_NA && *mode != dev->mode) { + printk(KERN_ERR + "zmii%d: invalid mode %d specified for input %d\n", + ocpdev->def->index, *mode, input); + return -EINVAL; + } + } + + /* Report back correct PHY mode, + * it may be used during PHY initialization. + */ + *mode = dev->mode; + + /* Enable this input */ + out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input)); + out: + ++dev->users; + return 0; +} + +int __init zmii_attach(void *emac) +{ + struct ocp_enet_private *dev = emac; + struct ocp_func_emac_data *emacdata = dev->def->additions; + + if (emacdata->zmii_idx >= 0) { + dev->zmii_input = emacdata->zmii_mux; + dev->zmii_dev = + ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII, + emacdata->zmii_idx); + if (!dev->zmii_dev) { + printk(KERN_ERR "emac%d: unknown zmii%d!\n", + dev->def->index, emacdata->zmii_idx); + return -ENODEV; + } + if (zmii_init + (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) { + printk(KERN_ERR + "emac%d: zmii%d initialization failed!\n", + dev->def->index, emacdata->zmii_idx); + return -ENODEV; + } + } + return 0; +} + +void __zmii_enable_mdio(struct ocp_device *ocpdev, int input) +{ + struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); + u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL; + + ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input); + + out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input)); +} + +void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed) +{ + struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); + u32 ssr = in_be32(&dev->base->ssr); + + ZMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed); + + if (speed == SPEED_100) + ssr |= ZMII_SSR_SP(input); + else + ssr &= ~ZMII_SSR_SP(input); + + out_be32(&dev->base->ssr, ssr); +} + +void __exit __zmii_fini(struct ocp_device *ocpdev, int input) +{ + struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); + BUG_ON(!dev || dev->users == 0); + + ZMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input); + + /* Disable this input */ + out_be32(&dev->base->fer, + in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input)); + + if (!--dev->users) { + /* Free everything if this is the last user */ + ocp_set_drvdata(ocpdev, NULL); + iounmap((void *)dev->base); + kfree(dev); + } +} + +int __zmii_get_regs_len(struct ocp_device *ocpdev) +{ + return sizeof(struct emac_ethtool_regs_subhdr) + + sizeof(struct zmii_regs); +} + +void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf) +{ + struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); + struct emac_ethtool_regs_subhdr *hdr = buf; + struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1); + + hdr->version = 0; + hdr->index = ocpdev->def->index; + memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs)); + return regs + 1; +} diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h index 6f6cd2a39e38..0bb26062c0ad 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.h +++ b/drivers/net/ibm_emac/ibm_emac_zmii.h @@ -1,23 +1,27 @@ /* - * ocp_zmii.h + * drivers/net/ibm_emac/ibm_emac_zmii.h * - * Defines for the IBM ZMII bridge + * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. * - * Armin Kuster akuster@mvista.com - * Dec, 2001 + * Copyright (c) 2004, 2005 Zultys Technologies. + * Eugene Surovegin or * - * Copyright 2001 MontaVista Softare Inc. + * Based on original work by + * Armin Kuster + * Copyright 2001 MontaVista Softare 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 of the License, or (at your * option) any later version. + * */ - #ifndef _IBM_EMAC_ZMII_H_ #define _IBM_EMAC_ZMII_H_ #include +#include +#include /* ZMII bridge registers */ struct zmii_regs { @@ -26,68 +30,54 @@ struct zmii_regs { u32 smiirs; /* SMII status reg */ }; -#define ZMII_INPUTS 4 - /* ZMII device */ struct ibm_ocp_zmii { struct zmii_regs *base; - int mode[ZMII_INPUTS]; + int mode; /* subset of PHY_MODE_XXXX */ int users; /* number of EMACs using this ZMII bridge */ + u32 fer_save; /* FER value left by firmware */ }; -/* Fuctional Enable Reg */ +#ifdef CONFIG_IBM_EMAC_ZMII +int zmii_attach(void *emac) __init; -#define ZMII_FER_MASK(x) (0xf0000000 >> (4*x)) +void __zmii_fini(struct ocp_device *ocpdev, int input) __exit; +static inline void zmii_fini(struct ocp_device *ocpdev, int input) +{ + if (ocpdev) + __zmii_fini(ocpdev, input); +} -#define ZMII_MDI0 0x80000000 -#define ZMII_SMII0 0x40000000 -#define ZMII_RMII0 0x20000000 -#define ZMII_MII0 0x10000000 -#define ZMII_MDI1 0x08000000 -#define ZMII_SMII1 0x04000000 -#define ZMII_RMII1 0x02000000 -#define ZMII_MII1 0x01000000 -#define ZMII_MDI2 0x00800000 -#define ZMII_SMII2 0x00400000 -#define ZMII_RMII2 0x00200000 -#define ZMII_MII2 0x00100000 -#define ZMII_MDI3 0x00080000 -#define ZMII_SMII3 0x00040000 -#define ZMII_RMII3 0x00020000 -#define ZMII_MII3 0x00010000 +void __zmii_enable_mdio(struct ocp_device *ocpdev, int input); +static inline void zmii_enable_mdio(struct ocp_device *ocpdev, int input) +{ + if (ocpdev) + __zmii_enable_mdio(ocpdev, input); +} -/* Speed Selection reg */ +void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed); +static inline void zmii_set_speed(struct ocp_device *ocpdev, int input, + int speed) +{ + if (ocpdev) + __zmii_set_speed(ocpdev, input, speed); +} -#define ZMII_SCI0 0x40000000 -#define ZMII_FSS0 0x20000000 -#define ZMII_SP0 0x10000000 -#define ZMII_SCI1 0x04000000 -#define ZMII_FSS1 0x02000000 -#define ZMII_SP1 0x01000000 -#define ZMII_SCI2 0x00400000 -#define ZMII_FSS2 0x00200000 -#define ZMII_SP2 0x00100000 -#define ZMII_SCI3 0x00040000 -#define ZMII_FSS3 0x00020000 -#define ZMII_SP3 0x00010000 +int __zmii_get_regs_len(struct ocp_device *ocpdev); +static inline int zmii_get_regs_len(struct ocp_device *ocpdev) +{ + return ocpdev ? __zmii_get_regs_len(ocpdev) : 0; +} -#define ZMII_MII0_100MB ZMII_SP0 -#define ZMII_MII0_10MB ~ZMII_SP0 -#define ZMII_MII1_100MB ZMII_SP1 -#define ZMII_MII1_10MB ~ZMII_SP1 -#define ZMII_MII2_100MB ZMII_SP2 -#define ZMII_MII2_10MB ~ZMII_SP2 -#define ZMII_MII3_100MB ZMII_SP3 -#define ZMII_MII3_10MB ~ZMII_SP3 +void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf); -/* SMII Status reg */ - -#define ZMII_STS0 0xFF000000 /* EMAC0 smii status mask */ -#define ZMII_STS1 0x00FF0000 /* EMAC1 smii status mask */ - -#define SMII 0 -#define RMII 1 -#define MII 2 -#define MDI 3 +#else +# define zmii_attach(x) 0 +# define zmii_fini(x,y) ((void)0) +# define zmii_enable_mdio(x,y) ((void)0) +# define zmii_set_speed(x,y,z) ((void)0) +# define zmii_get_regs_len(x) 0 +# define zmii_dump_regs(x,buf) (buf) +#endif /* !CONFIG_IBM_EMAC_ZMII */ #endif /* _IBM_EMAC_ZMII_H_ */ From 24682978eb5316b9e6041c2773e210180a037d05 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Fri, 14 Oct 2005 03:00:53 -0700 Subject: [PATCH 0686/1940] [PATCH] Add MAINTAINER entry for the new PowerPC 4xx on-chip ethernet controller driver Add MAINTAINER entry for the new PPC4xx EMAC driver Signed-off-by: Eugene Surovegin Signed-off-by: Jeff Garzik --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 767fb610963e..900bd58f2dbe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1942,6 +1942,14 @@ M: george@mvista.com L: netdev@vger.kernel.org S: Supported +POWERPC 4xx EMAC DRIVER +P: Eugene Surovegin +M: ebs@ebshome.net +W: http://kernel.ebshome.net/emac/ +L: linuxppc-embedded@ozlabs.org +L: netdev@vger.kernel.org +S: Maintained + PNP SUPPORT P: Adam Belay M: ambx1@neo.rr.com From b2795f596932286ef12dc08857960d654f577405 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 28 Oct 2005 16:43:40 -0400 Subject: [PATCH 0687/1940] [git] change permissions on drivers/net/amd8111e.[ch] to 0644, removing executable bits. --- drivers/net/amd8111e.c | 0 drivers/net/amd8111e.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/net/amd8111e.c mode change 100755 => 100644 drivers/net/amd8111e.h diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c old mode 100755 new mode 100644 diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h old mode 100755 new mode 100644 From 7380a78a973a8109c13cb0e47617c456b6f6e1f5 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Fri, 28 Oct 2005 16:46:35 -0400 Subject: [PATCH 0688/1940] sis900: come alive after temporary memory shortage 1) Forgotten counter incrementation in sis900_rx() in case it doesn't get memory for skb, that leads to whole interface failure. Problem is accompanied with messages: eth0: Memory squeeze,deferring packet. eth0: NULL pointer encountered in Rx ring, skipping 2) If counter cur_rx overflows and there'll be temporary memory problems buffer can't be recreated later, when memory IS available. 3) Limit the work in handler to prevent the endless packets processing if new packets are generated faster then handled. Signed-off-by: Konstantin Khorenko Signed-off-by: Vasily Averin Signed-off-by: Jeff Garzik --- drivers/net/sis900.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 23b713c700b3..1d4d88680db1 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *net_dev) long ioaddr = net_dev->base_addr; unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC; u32 rx_status = sis_priv->rx_ring[entry].cmdsts; + int rx_work_limit; if (netif_msg_rx_status(sis_priv)) printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d " "status:0x%8.8x\n", sis_priv->cur_rx, sis_priv->dirty_rx, rx_status); + rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx; while (rx_status & OWN) { unsigned int rx_size; + if (--rx_work_limit < 0) + break; + rx_size = (rx_status & DSIZE) - CRC_SIZE; if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { @@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *net_dev) we are working on NULL sk_buff :-( */ if (sis_priv->rx_skbuff[entry] == NULL) { if (netif_msg_rx_err(sis_priv)) - printk(KERN_INFO "%s: NULL pointer " - "encountered in Rx ring, skipping\n", - net_dev->name); + printk(KERN_WARNING "%s: NULL pointer " + "encountered in Rx ring\n" + "cur_rx:%4.4d, dirty_rx:%4.4d\n", + net_dev->name, sis_priv->cur_rx, + sis_priv->dirty_rx); break; } @@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_ring[entry].cmdsts = 0; sis_priv->rx_ring[entry].bufptr = 0; sis_priv->stats.rx_dropped++; + sis_priv->cur_rx++; break; } skb->dev = net_dev; @@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *net_dev) /* refill the Rx buffer, what if the rate of refilling is slower * than consuming ?? */ - for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) { + for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) { struct sk_buff *skb; entry = sis_priv->dirty_rx % NUM_RX_DESC; From b4558ea93d66a43f7990d26f145fd4c54a01c9bf Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 28 Oct 2005 16:53:13 -0400 Subject: [PATCH 0689/1940] drivers/net: Remove pointless checks for NULL prior to calling kfree() --- drivers/net/acenic.c | 6 +-- drivers/net/au1000_eth.c | 6 +-- drivers/net/b44.c | 12 ++---- drivers/net/bmac.c | 6 +-- drivers/net/bnx2.c | 12 ++---- drivers/net/e1000/e1000_ethtool.c | 7 +--- drivers/net/hamradio/mkiss.c | 6 +-- drivers/net/ibmveth.c | 6 +-- drivers/net/irda/donauboe.c | 6 +-- drivers/net/irda/irda-usb.c | 6 +-- drivers/net/irda/irport.c | 3 +- drivers/net/irda/sir_dev.c | 3 +- drivers/net/irda/vlsi_ir.c | 3 +- drivers/net/mace.c | 6 +-- drivers/net/ni65.c | 9 ++-- drivers/net/rrunner.c | 6 +-- drivers/net/s2io.c | 3 +- drivers/net/saa9730.c | 8 +--- drivers/net/tg3.c | 6 +-- drivers/net/tulip/de2104x.c | 6 +-- drivers/net/tulip/tulip_core.c | 6 +-- drivers/net/via-velocity.c | 6 +-- drivers/net/wireless/airo.c | 48 +++++++++------------- drivers/net/wireless/airo_cs.c | 4 +- drivers/net/wireless/atmel.c | 6 +-- drivers/net/wireless/atmel_cs.c | 3 +- drivers/net/wireless/hostap/hostap_ioctl.c | 9 +--- drivers/net/wireless/prism54/islpci_dev.c | 3 +- drivers/net/wireless/prism54/oid_mgt.c | 9 ++-- drivers/net/wireless/strip.c | 38 ++++++----------- include/net/ax25.h | 3 +- include/net/netrom.h | 3 +- 32 files changed, 90 insertions(+), 174 deletions(-) diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index dbecc6bf7851..b8953de5664a 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -871,10 +871,8 @@ static void ace_init_cleanup(struct net_device *dev) if (ap->info) pci_free_consistent(ap->pdev, sizeof(struct ace_info), ap->info, ap->info_dma); - if (ap->skb) - kfree(ap->skb); - if (ap->trace_buf) - kfree(ap->trace_buf); + kfree(ap->skb); + kfree(ap->trace_buf); if (dev->irq) free_irq(dev->irq, dev); diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 78506911d656..332e9953c55c 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -1606,8 +1606,7 @@ au1000_probe(u32 ioaddr, int irq, int port_num) /* here we should have a valid dev plus aup-> register addresses * so we can reset the mac properly.*/ reset_mac(dev); - if (aup->mii) - kfree(aup->mii); + kfree(aup->mii); for (i = 0; i < NUM_RX_DMA; i++) { if (aup->rx_db_inuse[i]) ReleaseDB(aup, aup->rx_db_inuse[i]); @@ -1806,8 +1805,7 @@ static void __exit au1000_cleanup_module(void) if (dev) { aup = (struct au1000_private *) dev->priv; unregister_netdev(dev); - if (aup->mii) - kfree(aup->mii); + kfree(aup->mii); for (j = 0; j < NUM_RX_DMA; j++) { if (aup->rx_db_inuse[j]) ReleaseDB(aup, aup->rx_db_inuse[j]); diff --git a/drivers/net/b44.c b/drivers/net/b44.c index ab845076ff9f..5485e3b1cd35 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -1131,14 +1131,10 @@ static void b44_init_rings(struct b44 *bp) */ static void b44_free_consistent(struct b44 *bp) { - if (bp->rx_buffers) { - kfree(bp->rx_buffers); - bp->rx_buffers = NULL; - } - if (bp->tx_buffers) { - kfree(bp->tx_buffers); - bp->tx_buffers = NULL; - } + kfree(bp->rx_buffers); + bp->rx_buffers = NULL; + kfree(bp->tx_buffers); + bp->tx_buffers = NULL; if (bp->rx_ring) { if (bp->flags & B44_FLAG_RX_RING_HACK) { dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma, diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 60dba4a1ca5c..73f2fcfc557f 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1689,10 +1689,8 @@ static void __exit bmac_exit(void) { macio_unregister_driver(&bmac_driver); - if (bmac_emergency_rxbuf != NULL) { - kfree(bmac_emergency_rxbuf); - bmac_emergency_rxbuf = NULL; - } + kfree(bmac_emergency_rxbuf); + bmac_emergency_rxbuf = NULL; } MODULE_AUTHOR("Randy Gobbel/Paul Mackerras"); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3a2ace01e444..11d252318221 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -314,20 +314,16 @@ bnx2_free_mem(struct bnx2 *bp) bp->tx_desc_ring, bp->tx_desc_mapping); bp->tx_desc_ring = NULL; } - if (bp->tx_buf_ring) { - kfree(bp->tx_buf_ring); - bp->tx_buf_ring = NULL; - } + kfree(bp->tx_buf_ring); + bp->tx_buf_ring = NULL; if (bp->rx_desc_ring) { pci_free_consistent(bp->pdev, sizeof(struct rx_bd) * RX_DESC_CNT, bp->rx_desc_ring, bp->rx_desc_mapping); bp->rx_desc_ring = NULL; } - if (bp->rx_buf_ring) { - kfree(bp->rx_buf_ring); - bp->rx_buf_ring = NULL; - } + kfree(bp->rx_buf_ring); + bp->rx_buf_ring = NULL; } static int diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 6b9acc7f94a3..9c7feaeaa6a4 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -965,11 +965,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter) if(rxdr->desc) pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); - if(txdr->buffer_info) - kfree(txdr->buffer_info); - if(rxdr->buffer_info) - kfree(rxdr->buffer_info); - + kfree(txdr->buffer_info); + kfree(rxdr->buffer_info); return; } diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 85d6dc005be0..3e9accf137e7 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -390,10 +390,8 @@ static void ax_changedmtu(struct mkiss *ax) "MTU change cancelled.\n", ax->dev->name); dev->mtu = ax->mtu; - if (xbuff != NULL) - kfree(xbuff); - if (rbuff != NULL) - kfree(rbuff); + kfree(xbuff); + kfree(rbuff); return; } diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index f5819527ec9d..36da54ad2b7b 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -276,10 +276,8 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm { int i; - if(pool->free_map) { - kfree(pool->free_map); - pool->free_map = NULL; - } + kfree(pool->free_map); + pool->free_map = NULL; if(pool->skbuff && pool->dma_addr) { for(i = 0; i < pool->size; ++i) { diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 0a08c539c051..0282771b1cbb 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1695,11 +1695,9 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) freebufs: for (i = 0; i < TX_SLOTS; ++i) - if (self->tx_bufs[i]) - kfree (self->tx_bufs[i]); + kfree (self->tx_bufs[i]); for (i = 0; i < RX_SLOTS; ++i) - if (self->rx_bufs[i]) - kfree (self->rx_bufs[i]); + kfree (self->rx_bufs[i]); kfree(self->ringbuf); freeregion: diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6c766fdc51a6..c22c0517883c 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1168,10 +1168,8 @@ static inline void irda_usb_close(struct irda_usb_cb *self) unregister_netdev(self->netdev); /* Remove the speed buffer */ - if (self->speed_buff != NULL) { - kfree(self->speed_buff); - self->speed_buff = NULL; - } + kfree(self->speed_buff); + self->speed_buff = NULL; } /********************** USB CONFIG SUBROUTINES **********************/ diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 5971315f3fa0..3d016a498e1d 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -235,8 +235,7 @@ static int irport_close(struct irport_cb *self) __FUNCTION__, self->io.sir_base); release_region(self->io.sir_base, self->io.sir_ext); - if (self->tx_buff.head) - kfree(self->tx_buff.head); + kfree(self->tx_buff.head); if (self->rx_buff.skb) kfree_skb(self->rx_buff.skb); diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index efc5a8870565..df22b8b532e7 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -490,8 +490,7 @@ static void sirdev_free_buffers(struct sir_dev *dev) { if (dev->rx_buff.skb) kfree_skb(dev->rx_buff.skb); - if (dev->tx_buff.head) - kfree(dev->tx_buff.head); + kfree(dev->tx_buff.head); dev->rx_buff.head = dev->tx_buff.head = NULL; dev->rx_buff.skb = NULL; } diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 651c5a6578fd..a9f49f058cfb 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -473,8 +473,7 @@ static int vlsi_free_ring(struct vlsi_ring *r) rd_set_addr_status(rd, 0, 0); if (busaddr) pci_unmap_single(r->pdev, busaddr, r->len, r->dir); - if (rd->buf) - kfree(rd->buf); + kfree(rd->buf); } kfree(r); return 0; diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 81d0a26e4f41..09b1e7b364e5 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -1035,10 +1035,8 @@ static void __exit mace_cleanup(void) { macio_unregister_driver(&mace_driver); - if (dummy_buf) { - kfree(dummy_buf); - dummy_buf = NULL; - } + kfree(dummy_buf); + dummy_buf = NULL; } MODULE_AUTHOR("Paul Mackerras"); diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index 925d1dfcc4dc..bb42ff218484 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -696,8 +696,7 @@ static void ni65_free_buffer(struct priv *p) return; for(i=0;itmdbounce[i]) - kfree(p->tmdbounce[i]); + kfree(p->tmdbounce[i]); #ifdef XMT_VIA_SKB if(p->tmd_skb[i]) dev_kfree_skb(p->tmd_skb[i]); @@ -710,12 +709,10 @@ static void ni65_free_buffer(struct priv *p) if(p->recv_skb[i]) dev_kfree_skb(p->recv_skb[i]); #else - if(p->recvbounce[i]) - kfree(p->recvbounce[i]); + kfree(p->recvbounce[i]); #endif } - if(p->self) - kfree(p->self); + kfree(p->self); } diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index ec1a18d189a1..19c2df9c86fe 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1710,10 +1710,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) error = -EFAULT; } wf_out: - if (oldimage) - kfree(oldimage); - if (image) - kfree(image); + kfree(oldimage); + kfree(image); return error; case SIOCRRID: diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index d303d162974f..5ea897714a14 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -705,8 +705,7 @@ static void free_shared_mem(struct s2io_nic *nic) } kfree(mac_control->rings[i].ba[j]); } - if (mac_control->rings[i].ba) - kfree(mac_control->rings[i].ba); + kfree(mac_control->rings[i].ba); } #endif diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c index fd0167077fbe..110e777f206e 100644 --- a/drivers/net/saa9730.c +++ b/drivers/net/saa9730.c @@ -997,10 +997,7 @@ static void __devexit saa9730_remove_one(struct pci_dev *pdev) if (dev) { unregister_netdev(dev); - - if (dev->priv) - kfree(dev->priv); - + kfree(dev->priv); free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); @@ -1096,8 +1093,7 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq) return 0; out: - if (dev->priv) - kfree(dev->priv); + kfree(dev->priv); return ret; } diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 551c9449322d..b547233ad9f7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3918,10 +3918,8 @@ static void tg3_init_rings(struct tg3 *tp) */ static void tg3_free_consistent(struct tg3 *tp) { - if (tp->rx_std_buffers) { - kfree(tp->rx_std_buffers); - tp->rx_std_buffers = NULL; - } + kfree(tp->rx_std_buffers); + tp->rx_std_buffers = NULL; if (tp->rx_std) { pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES, tp->rx_std, tp->rx_std_mapping); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 6b8eee8f7bfd..d7fb3ffe06ac 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -2076,8 +2076,7 @@ static int __init de_init_one (struct pci_dev *pdev, return 0; err_out_iomap: - if (de->ee_data) - kfree(de->ee_data); + kfree(de->ee_data); iounmap(regs); err_out_res: pci_release_regions(pdev); @@ -2096,8 +2095,7 @@ static void __exit de_remove_one (struct pci_dev *pdev) if (!dev) BUG(); unregister_netdev(dev); - if (de->ee_data) - kfree(de->ee_data); + kfree(de->ee_data); iounmap(de->regs); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 6266a9a7e6e3..125ed00e95a5 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1727,8 +1727,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, tp->rx_ring, tp->rx_ring_dma); err_out_mtable: - if (tp->mtable) - kfree (tp->mtable); + kfree (tp->mtable); pci_iounmap(pdev, ioaddr); err_out_free_res: @@ -1806,8 +1805,7 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev) sizeof (struct tulip_rx_desc) * RX_RING_SIZE + sizeof (struct tulip_tx_desc) * TX_RING_SIZE, tp->rx_ring, tp->rx_ring_dma); - if (tp->mtable) - kfree (tp->mtable); + kfree (tp->mtable); pci_iounmap(pdev, tp->base_addr); free_netdev (dev); pci_release_regions (pdev); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index abc5cee6eedc..a368d08e7d19 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1212,10 +1212,8 @@ static void velocity_free_td_ring(struct velocity_info *vptr) velocity_free_td_ring_entry(vptr, j, i); } - if (vptr->td_infos[j]) { - kfree(vptr->td_infos[j]); - vptr->td_infos[j] = NULL; - } + kfree(vptr->td_infos[j]); + vptr->td_infos[j] = NULL; } } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index cb429e783749..4c11699bad91 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2381,14 +2381,10 @@ void stop_airo_card( struct net_device *dev, int freeres ) dev_kfree_skb(skb); } - if (ai->flash) - kfree(ai->flash); - if (ai->rssi) - kfree(ai->rssi); - if (ai->APList) - kfree(ai->APList); - if (ai->SSID) - kfree(ai->SSID); + kfree(ai->flash); + kfree(ai->rssi); + kfree(ai->APList); + kfree(ai->SSID); if (freeres) { /* PCMCIA frees this stuff, so only for PCI and ISA */ release_region( dev->base_addr, 64 ); @@ -3626,10 +3622,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) int rc; memset( &mySsid, 0, sizeof( mySsid ) ); - if (ai->flash) { - kfree (ai->flash); - ai->flash = NULL; - } + kfree (ai->flash); + ai->flash = NULL; /* The NOP is the first step in getting the card going */ cmd.cmd = NOP; @@ -3666,14 +3660,10 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) tdsRssiRid rssi_rid; CapabilityRid cap_rid; - if (ai->APList) { - kfree(ai->APList); - ai->APList = NULL; - } - if (ai->SSID) { - kfree(ai->SSID); - ai->SSID = NULL; - } + kfree(ai->APList); + ai->APList = NULL; + kfree(ai->SSID); + ai->SSID = NULL; // general configuration (read/modify/write) status = readConfigRid(ai, lock); if ( status != SUCCESS ) return ERROR; @@ -3687,10 +3677,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */ } else { - if (ai->rssi) { - kfree(ai->rssi); - ai->rssi = NULL; - } + kfree(ai->rssi); + ai->rssi = NULL; if (cap_rid.softCap & 8) ai->config.rmode |= RXMODE_NORMALIZED_RSSI; else @@ -5369,11 +5357,13 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { static int proc_close( struct inode *inode, struct file *file ) { - struct proc_data *data = (struct proc_data *)file->private_data; - if ( data->on_close != NULL ) data->on_close( inode, file ); - if ( data->rbuffer ) kfree( data->rbuffer ); - if ( data->wbuffer ) kfree( data->wbuffer ); - kfree( data ); + struct proc_data *data = file->private_data; + + if (data->on_close != NULL) + data->on_close(inode, file); + kfree(data->rbuffer); + kfree(data->wbuffer); + kfree(data); return 0; } diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index bf25584d68d3..784de9109113 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -258,9 +258,7 @@ static void airo_detach(dev_link_t *link) /* Unlink device structure, free pieces */ *linkp = link->next; - if (link->priv) { - kfree(link->priv); - } + kfree(link->priv); kfree(link); } /* airo_detach */ diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index d57011028b72..1fbe027d26b6 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1653,8 +1653,7 @@ void stop_atmel_card(struct net_device *dev, int freeres) unregister_netdev(dev); remove_proc_entry("driver/atmel", NULL); free_irq(dev->irq, dev); - if (priv->firmware) - kfree(priv->firmware); + kfree(priv->firmware); if (freeres) { /* PCMCIA frees this stuff, so only for PCI */ release_region(dev->base_addr, 64); @@ -2450,8 +2449,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } - if (priv->firmware) - kfree(priv->firmware); + kfree(priv->firmware); priv->firmware = new_firmware; priv->firmware_length = com.len; diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index ff031a3985b3..195cb36619e8 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -259,8 +259,7 @@ static void atmel_detach(dev_link_t *link) /* Unlink device structure, free pieces */ *linkp = link->next; - if (link->priv) - kfree(link->priv); + kfree(link->priv); kfree(link); } diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 53f5246c40aa..2617d70bcda9 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -552,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct net_device *dev, kfree(addr); kfree(qual); - return 0; } @@ -3081,9 +3080,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p) ret = local->func->download(local, param); out: - if (param != NULL) - kfree(param); - + kfree(param); return ret; } #endif /* PRISM2_DOWNLOAD_SUPPORT */ @@ -3890,9 +3887,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p) } out: - if (param != NULL) - kfree(param); - + kfree(param); return ret; } diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 6c9584a9f284..78bdb359835e 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -754,8 +754,7 @@ islpci_free_memory(islpci_private *priv) pci_unmap_single(priv->pdev, buf->pci_addr, buf->size, PCI_DMA_FROMDEVICE); buf->pci_addr = 0; - if (buf->mem) - kfree(buf->mem); + kfree(buf->mem); buf->size = 0; buf->mem = NULL; } diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index 12123e24b113..eea2f04c8c6d 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -268,11 +268,10 @@ mgt_clean(islpci_private *priv) if (!priv->mib) return; - for (i = 0; i < OID_NUM_LAST; i++) - if (priv->mib[i]) { - kfree(priv->mib[i]); - priv->mib[i] = NULL; - } + for (i = 0; i < OID_NUM_LAST; i++) { + kfree(priv->mib[i]); + priv->mib[i] = NULL; + } kfree(priv->mib); priv->mib = NULL; } diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 7bc7fc823128..d25264ba0c0e 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -860,12 +860,9 @@ static int allocate_buffers(struct strip *strip_info, int mtu) strip_info->mtu = dev->mtu = mtu; return (1); } - if (r) - kfree(r); - if (s) - kfree(s); - if (t) - kfree(t); + kfree(r); + kfree(s); + kfree(t); return (0); } @@ -922,13 +919,9 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu) printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n", strip_info->dev->name, old_mtu, strip_info->mtu); - if (orbuff) - kfree(orbuff); - if (osbuff) - kfree(osbuff); - if (otbuff) - kfree(otbuff); - + kfree(orbuff); + kfree(osbuff); + kfree(otbuff); return 0; } @@ -2498,18 +2491,13 @@ static int strip_close_low(struct net_device *dev) /* * Free all STRIP frame buffers. */ - if (strip_info->rx_buff) { - kfree(strip_info->rx_buff); - strip_info->rx_buff = NULL; - } - if (strip_info->sx_buff) { - kfree(strip_info->sx_buff); - strip_info->sx_buff = NULL; - } - if (strip_info->tx_buff) { - kfree(strip_info->tx_buff); - strip_info->tx_buff = NULL; - } + kfree(strip_info->rx_buff); + strip_info->rx_buff = NULL; + kfree(strip_info->sx_buff); + strip_info->sx_buff = NULL; + kfree(strip_info->tx_buff); + strip_info->tx_buff = NULL; + del_timer(&strip_info->idle_timer); return 0; } diff --git a/include/net/ax25.h b/include/net/ax25.h index 30bb4a893237..2250a18b0cbb 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -237,8 +237,7 @@ typedef struct ax25_cb { static __inline__ void ax25_cb_put(ax25_cb *ax25) { if (atomic_dec_and_test(&ax25->refcount)) { - if (ax25->digipeat) - kfree(ax25->digipeat); + kfree(ax25->digipeat); kfree(ax25); } } diff --git a/include/net/netrom.h b/include/net/netrom.h index a6bf6e0f606a..a5ee53bce62f 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h @@ -136,8 +136,7 @@ static __inline__ void nr_node_put(struct nr_node *nr_node) static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh) { if (atomic_dec_and_test(&nr_neigh->refcount)) { - if (nr_neigh->digipeat != NULL) - kfree(nr_neigh->digipeat); + kfree(nr_neigh->digipeat); kfree(nr_neigh); } } From 030ee39c0fef49d7dcd32e71b1ca98fcc23e2a72 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 28 Oct 2005 13:55:08 -0700 Subject: [PATCH 0690/1940] pcmcia: add socket register data to sysfs for yenta devices It's simple, and it's a good debugging aid. Signed-off-by: Linus Torvalds --- drivers/pcmcia/yenta_socket.c | 42 ++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index db9f952f9e3c..ec6ab65f0872 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -151,6 +151,40 @@ static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) readb(socket->base + 0x800 + reg + 1); } +static ssize_t show_yenta_registers(struct device *yentadev, struct device_attribute *attr, char *buf) +{ + struct pci_dev *dev = to_pci_dev(yentadev); + struct yenta_socket *socket = pci_get_drvdata(dev); + int offset = 0, i; + + offset = snprintf(buf, PAGE_SIZE, "CB registers:"); + for (i = 0; i < 0x24; i += 4) { + unsigned val; + if (!(i & 15)) + offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i); + val = cb_readl(socket, i); + offset += snprintf(buf + offset, PAGE_SIZE - offset, " %08x", val); + } + + offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n\nExCA registers:"); + for (i = 0; i < 0x45; i++) { + unsigned char val; + if (!(i & 7)) { + if (i & 8) { + memcpy(buf + offset, " -", 2); + offset += 2; + } else + offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i); + } + val = exca_readb(socket, i); + offset += snprintf(buf + offset, PAGE_SIZE - offset, " %02x", val); + } + buf[offset++] = '\n'; + return offset; +} + +static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL); + /* * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend * on what kind of card is inserted.. @@ -765,6 +799,9 @@ static void yenta_close(struct pci_dev *dev) { struct yenta_socket *sock = pci_get_drvdata(dev); + /* Remove the register attributes */ + device_remove_file(&dev->dev, &dev_attr_yenta_registers); + /* we don't want a dying socket registered */ pcmcia_unregister_socket(&sock->socket); @@ -1138,8 +1175,11 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i /* Register it with the pcmcia layer.. */ ret = pcmcia_register_socket(&socket->socket); - if (ret == 0) + if (ret == 0) { + /* Add the yenta register attributes */ + device_create_file(&dev->dev, &dev_attr_yenta_registers); goto out; + } unmap: iounmap(socket->base); From 4f075707a9380592586d608a8d04dfbdb3c40339 Mon Sep 17 00:00:00 2001 From: Komuro Date: Fri, 28 Oct 2005 16:55:55 -0400 Subject: [PATCH 0691/1940] [netdrvr] ne2k-pci based card does not support bus-mastering. pci_set_master is unnecessary. Signed-off-by: komurojun-mbn@nifty.com Signed-off-by: Jeff Garzik --- drivers/net/ne2k-pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index e531a4eedfee..d11821dd86ed 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -675,7 +675,6 @@ static int ne2k_pci_resume (struct pci_dev *pdev) pci_set_power_state(pdev, 0); pci_restore_state(pdev); pci_enable_device(pdev); - pci_set_master(pdev); NS8390_init(dev, 1); netif_device_attach(dev); From ad18b0ea089928367185e13d11424aea91d4b41f Mon Sep 17 00:00:00 2001 From: Panagiotis Issaris Date: Mon, 5 Sep 2005 04:14:10 +0200 Subject: [PATCH 0692/1940] [PATCH] ipw2200: Missing kmalloc check The ipw2200 driver code in current GIT contains a kmalloc() followed by a memset() without handling a possible memory allocation failure. Signed-off-by: Panagiotis Issaris Signed-off-by: Jeff Garzik --- drivers/net/wireless/ipw2200.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index de4e6c23e4b8..3db0c32afe82 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -4030,6 +4030,10 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv) int i; rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL); + if (unlikely(!rxq)) { + IPW_ERROR("memory allocation failed\n"); + return NULL; + } memset(rxq, 0, sizeof(*rxq)); spin_lock_init(&rxq->lock); INIT_LIST_HEAD(&rxq->rx_free); From 6cd37cda7ed117d5a13d9b69aeded57b4fd6de14 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Fri, 28 Oct 2005 20:23:39 +0200 Subject: [PATCH 0693/1940] [PATCH] Fix ext3 warning for unused var Fix compile warning in ext3 quota code. Signed-off-by: Peter Osterlund Signed-off-by: Linus Torvalds --- fs/ext3/super.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 9e24ceb019fe..097383c11154 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -510,19 +510,11 @@ static void ext3_clear_inode(struct inode *inode) kfree(rsv); } -static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) +static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) { - struct super_block *sb = vfs->mnt_sb; +#if defined(CONFIG_QUOTA) struct ext3_sb_info *sbi = EXT3_SB(sb); - if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) - seq_puts(seq, ",data=journal"); - else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) - seq_puts(seq, ",data=ordered"); - else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) - seq_puts(seq, ",data=writeback"); - -#if defined(CONFIG_QUOTA) if (sbi->s_jquota_fmt) seq_printf(seq, ",jqfmt=%s", (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0"); @@ -539,6 +531,20 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) seq_puts(seq, ",grpquota"); #endif +} + +static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) +{ + struct super_block *sb = vfs->mnt_sb; + + if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) + seq_puts(seq, ",data=journal"); + else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + seq_puts(seq, ",data=ordered"); + else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + seq_puts(seq, ",data=writeback"); + + ext3_show_quota_options(seq, sb); return 0; } From 406119f49d4a6cf8b6eee639128e0575a95065e3 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 27 Oct 2005 14:46:53 -0400 Subject: [PATCH 0694/1940] [PATCH] Ensure that 'make distclean' does not delete files in '.git' Currently, 'make distclean' causes stgit to barf since it may delete files in .git/patches. We really shouldn't allow 'make distclean' anywhere near .git... Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f1d121f23025..79601320ac3e 100644 --- a/Makefile +++ b/Makefile @@ -371,8 +371,8 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_ve # Files to ignore in find ... statements -RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg \) -prune -o -export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg +RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o +export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git # =========================================================================== # Rules shared between *config targets and build targets From 07c1da2396632a4ad2cab41c6cd939b159f54968 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 28 Oct 2005 17:00:31 -0400 Subject: [PATCH 0695/1940] [libata sata_promise] add pci id Contributed by Daniel Mueller @ Siemens AG. --- drivers/scsi/sata_promise.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index eee93b0016df..50495569f409 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -195,6 +195,8 @@ static struct ata_port_info pdc_port_info[] = { static struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0, From 205cf13e0b57500e2cc6442effa991c1a63f4db7 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Sat, 17 Sep 2005 05:32:55 +1000 Subject: [PATCH 0696/1940] [PATCH] hwmon: adm9240 driver update - cleanups hwmon: adm9240 update 1/2: cleanups: o remove i2c read/write wrapper interface as it does nothing, o change kmalloc + memset to kzalloc Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adm9240.c | 92 ++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index bc7faef162f7..ecef342e5fa3 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -170,17 +170,6 @@ struct adm9240_data { u8 vrm; /* -- vrm set on startup, no accessor */ }; -/* i2c byte read/write interface */ -static int adm9240_read_value(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - /*** sysfs accessors ***/ /* temperature */ @@ -207,7 +196,7 @@ static ssize_t set_##value(struct device *dev, \ \ down(&data->update_lock); \ data->value = TEMP_TO_REG(temp); \ - adm9240_write_value(client, reg, data->value); \ + i2c_smbus_write_byte_data(client, reg, data->value); \ up(&data->update_lock); \ return count; \ } @@ -249,7 +238,8 @@ static ssize_t set_in_min(struct device *dev, const char *buf, down(&data->update_lock); data->in_min[nr] = IN_TO_REG(val, nr); - adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), data->in_min[nr]); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(nr), + data->in_min[nr]); up(&data->update_lock); return count; } @@ -263,7 +253,8 @@ static ssize_t set_in_max(struct device *dev, const char *buf, down(&data->update_lock); data->in_max[nr] = IN_TO_REG(val, nr); - adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), data->in_max[nr]); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(nr), + data->in_max[nr]); up(&data->update_lock); return count; } @@ -341,11 +332,11 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, { u8 reg, old, shift = (nr + 2) * 2; - reg = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); + reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); old = (reg >> shift) & 3; reg &= ~(3 << shift); reg |= (fan_div << shift); - adm9240_write_value(client, ADM9240_REG_VID_FAN_DIV, reg); + i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); dev_dbg(&client->dev, "fan%d clock divider changed from %u " "to %u\n", nr + 1, 1 << old, 1 << fan_div); } @@ -406,7 +397,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, data->fan_div[nr] = new_div; adm9240_write_fan_div(client, nr, new_div); } - adm9240_write_value(client, ADM9240_REG_FAN_MIN(nr), + i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr), data->fan_min[nr]); up(&data->update_lock); @@ -479,7 +470,7 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const down(&data->update_lock); data->aout = AOUT_TO_REG(val); - adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, data->aout); + i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout); up(&data->update_lock); return count; } @@ -492,7 +483,8 @@ static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, unsigned long val = simple_strtol(buf, NULL, 10); if (val == 1) { - adm9240_write_value(client, ADM9240_REG_CHASSIS_CLEAR, 0x80); + i2c_smbus_write_byte_data(client, + ADM9240_REG_CHASSIS_CLEAR, 0x80); dev_dbg(&client->dev, "chassis intrusion latch cleared\n"); } return count; @@ -513,11 +505,10 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct adm9240_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); @@ -533,7 +524,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) if (kind < 0) { /* verify chip: reg address should match i2c address */ - if (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR) + if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR) != address) { dev_err(&adapter->dev, "detect fail: address match, " "0x%02x\n", address); @@ -541,8 +532,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) } /* check known chip manufacturer */ - man_id = adm9240_read_value(new_client, ADM9240_REG_MAN_ID); - + man_id = i2c_smbus_read_byte_data(new_client, + ADM9240_REG_MAN_ID); if (man_id == 0x23) { kind = adm9240; } else if (man_id == 0xda) { @@ -556,7 +547,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) } /* successful detect, print chip info */ - die_rev = adm9240_read_value(new_client, ADM9240_REG_DIE_REV); + die_rev = i2c_smbus_read_byte_data(new_client, + ADM9240_REG_DIE_REV); dev_info(&adapter->dev, "found %s revision %u\n", man_id == 0x23 ? "ADM9240" : man_id == 0xda ? "DS1780" : "LM81", die_rev); @@ -654,8 +646,8 @@ static int adm9240_detach_client(struct i2c_client *client) static void adm9240_init_client(struct i2c_client *client) { struct adm9240_data *data = i2c_get_clientdata(client); - u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG); - u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3; + u8 conf = i2c_smbus_read_byte_data(client, ADM9240_REG_CONFIG); + u8 mode = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF) & 3; data->vrm = vid_which_vrm(); /* need this to report vid as mV */ @@ -672,18 +664,22 @@ static void adm9240_init_client(struct i2c_client *client) for (i = 0; i < 6; i++) { - adm9240_write_value(client, + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(i), 0); - adm9240_write_value(client, + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(i), 255); } - adm9240_write_value(client, ADM9240_REG_FAN_MIN(0), 255); - adm9240_write_value(client, ADM9240_REG_FAN_MIN(1), 255); - adm9240_write_value(client, ADM9240_REG_TEMP_HIGH, 127); - adm9240_write_value(client, ADM9240_REG_TEMP_HYST, 127); + i2c_smbus_write_byte_data(client, + ADM9240_REG_FAN_MIN(0), 255); + i2c_smbus_write_byte_data(client, + ADM9240_REG_FAN_MIN(1), 255); + i2c_smbus_write_byte_data(client, + ADM9240_REG_TEMP_HIGH, 127); + i2c_smbus_write_byte_data(client, + ADM9240_REG_TEMP_HYST, 127); /* start measurement cycle */ - adm9240_write_value(client, ADM9240_REG_CONFIG, 1); + i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); dev_info(&client->dev, "cold start: config was 0x%02x " "mode %u\n", conf, mode); @@ -704,25 +700,25 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) for (i = 0; i < 6; i++) /* read voltages */ { - data->in[i] = adm9240_read_value(client, + data->in[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN(i)); } - data->alarms = adm9240_read_value(client, + data->alarms = i2c_smbus_read_byte_data(client, ADM9240_REG_INT(0)) | - adm9240_read_value(client, + i2c_smbus_read_byte_data(client, ADM9240_REG_INT(1)) << 8; /* read temperature: assume temperature changes less than * 0.5'C per two measurement cycles thus ignore possible * but unlikely aliasing error on lsb reading. --Grant */ - data->temp = ((adm9240_read_value(client, + data->temp = ((i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP) << 8) | - adm9240_read_value(client, + i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF)) / 128; for (i = 0; i < 2; i++) /* read fans */ { - data->fan[i] = adm9240_read_value(client, + data->fan[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_FAN(i)); /* adjust fan clock divider on overflow */ @@ -747,30 +743,30 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) for (i = 0; i < 6; i++) { - data->in_min[i] = adm9240_read_value(client, + data->in_min[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN_MIN(i)); - data->in_max[i] = adm9240_read_value(client, + data->in_max[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN_MAX(i)); } for (i = 0; i < 2; i++) { - data->fan_min[i] = adm9240_read_value(client, + data->fan_min[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_FAN_MIN(i)); } - data->temp_high = adm9240_read_value(client, + data->temp_high = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_HIGH); - data->temp_hyst = adm9240_read_value(client, + data->temp_hyst = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_HYST); /* read fan divs and 5-bit VID */ - i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); + i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); data->fan_div[0] = (i >> 4) & 3; data->fan_div[1] = (i >> 6) & 3; data->vid = i & 0x0f; - data->vid |= (adm9240_read_value(client, + data->vid |= (i2c_smbus_read_byte_data(client, ADM9240_REG_VID4) & 1) << 4; /* read analog out */ - data->aout = adm9240_read_value(client, + data->aout = i2c_smbus_read_byte_data(client, ADM9240_REG_ANALOG_OUT); data->last_updated_config = jiffies; From c7461a6652f40ce4f8e19d7368c7a807a618fb68 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Sat, 17 Sep 2005 05:32:57 +1000 Subject: [PATCH 0697/1940] [PATCH] hwmon: adm9240 driver update - dynamic sysfs hwmon: adm9240 update 2/2: convert to use dynamic sysfs accessors This patch converts adm9240 to use Yani Ioannou's dynamic sysfs callbacks, reducing driver memory footprint from 16312 to 14104 bytes on 2.6.14-rc1, removing the old driver macro mess. Run tested on Intel SE440BX-2 mobo. Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adm9240.c | 332 +++++++++++++++++++--------------------- 1 file changed, 161 insertions(+), 171 deletions(-) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index ecef342e5fa3..8bb6d6e45ed5 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -69,8 +70,7 @@ I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81); #define ADM9240_REG_INT(nr) (0x41 + (nr)) #define ADM9240_REG_INT_MASK(nr) (0x43 + (nr)) #define ADM9240_REG_TEMP 0x27 -#define ADM9240_REG_TEMP_HIGH 0x39 -#define ADM9240_REG_TEMP_HYST 0x3a +#define ADM9240_REG_TEMP_MAX(nr) (0x39 + (nr)) /* 0, 1 = high, hyst */ #define ADM9240_REG_ANALOG_OUT 0x19 #define ADM9240_REG_CHASSIS_CLEAR 0x46 #define ADM9240_REG_VID_FAN_DIV 0x47 @@ -162,8 +162,7 @@ struct adm9240_data { u8 fan_min[2]; /* rw fan1_min */ u8 fan_div[2]; /* rw fan1_div, read-only accessor */ s16 temp; /* ro temp1_input, 9-bit sign-extended */ - s8 temp_high; /* rw temp1_max */ - s8 temp_hyst; /* rw temp1_max_hyst */ + s8 temp_max[2]; /* rw 0 -> temp_max, 1 -> temp_max_hyst */ u16 alarms; /* ro alarms */ u8 aout; /* rw aout_output */ u8 vid; /* ro vid */ @@ -173,157 +172,143 @@ struct adm9240_data { /*** sysfs accessors ***/ /* temperature */ -#define show_temp(value, scale) \ -static ssize_t show_##value(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct adm9240_data *data = adm9240_update_device(dev); \ - return sprintf(buf, "%d\n", data->value * scale); \ -} -show_temp(temp_high, 1000); -show_temp(temp_hyst, 1000); -show_temp(temp, 500); /* 0.5'C per bit */ - -#define set_temp(value, reg) \ -static ssize_t set_##value(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct adm9240_data *data = adm9240_update_device(dev); \ - long temp = simple_strtoul(buf, NULL, 10); \ - \ - down(&data->update_lock); \ - data->value = TEMP_TO_REG(temp); \ - i2c_smbus_write_byte_data(client, reg, data->value); \ - up(&data->update_lock); \ - return count; \ +static ssize_t show_temp(struct device *dev, struct device_attribute *dummy, + char *buf) +{ + struct adm9240_data *data = adm9240_update_device(dev); + return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */ } -set_temp(temp_high, ADM9240_REG_TEMP_HIGH); -set_temp(temp_hyst, ADM9240_REG_TEMP_HYST); +static ssize_t show_max(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adm9240_data *data = adm9240_update_device(dev); + return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000); +} + +static ssize_t set_max(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adm9240_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + + down(&data->update_lock); + data->temp_max[attr->index] = TEMP_TO_REG(val); + i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index), + data->temp_max[attr->index]); + up(&data->update_lock); + return count; +} -static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - show_temp_high, set_temp_high); -static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - show_temp_hyst, set_temp_hyst); static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, + show_max, set_max, 0); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, + show_max, set_max, 1); /* voltage */ -static ssize_t show_in(struct device *dev, char *buf, int nr) +static ssize_t show_in(struct device *dev, struct device_attribute *devattr, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr)); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index], + attr->index)); } -static ssize_t show_in_min(struct device *dev, char *buf, int nr) +static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr)); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index], + attr->index)); } -static ssize_t show_in_max(struct device *dev, char *buf, int nr) +static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr)); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index], + attr->index)); } -static ssize_t set_in_min(struct device *dev, const char *buf, - size_t count, int nr) +static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); down(&data->update_lock); - data->in_min[nr] = IN_TO_REG(val, nr); - i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(nr), - data->in_min[nr]); + data->in_min[attr->index] = IN_TO_REG(val, attr->index); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index), + data->in_min[attr->index]); up(&data->update_lock); return count; } -static ssize_t set_in_max(struct device *dev, const char *buf, - size_t count, int nr) +static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); down(&data->update_lock); - data->in_max[nr] = IN_TO_REG(val, nr); - i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(nr), - data->in_max[nr]); + data->in_max[attr->index] = IN_TO_REG(val, attr->index); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index), + data->in_max[attr->index]); up(&data->update_lock); return count; } -#define show_in_offset(offset) \ -static ssize_t show_in##offset(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_in(dev, buf, offset); \ -} \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); \ -static ssize_t show_in##offset##_min(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_in_min(dev, buf, offset); \ -} \ -static ssize_t show_in##offset##_max(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_in_max(dev, buf, offset); \ -} \ -static ssize_t \ -set_in##offset##_min(struct device *dev, \ - struct device_attribute *attr, const char *buf, \ - size_t count) \ -{ \ - return set_in_min(dev, buf, count, offset); \ -} \ -static ssize_t \ -set_in##offset##_max(struct device *dev, \ - struct device_attribute *attr, const char *buf, \ - size_t count) \ -{ \ - return set_in_max(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min); \ -static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max); +#define vin(nr) \ +static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, \ + show_in, NULL, nr); \ +static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR, \ + show_in_min, set_in_min, nr); \ +static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR, \ + show_in_max, set_in_max, nr); -show_in_offset(0); -show_in_offset(1); -show_in_offset(2); -show_in_offset(3); -show_in_offset(4); -show_in_offset(5); +vin(0); +vin(1); +vin(2); +vin(3); +vin(4); +vin(5); /* fans */ -static ssize_t show_fan(struct device *dev, char *buf, int nr) +static ssize_t show_fan(struct device *dev, + struct device_attribute *devattr, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], - 1 << data->fan_div[nr])); + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], + 1 << data->fan_div[attr->index])); } -static ssize_t show_fan_min(struct device *dev, char *buf, int nr) +static ssize_t show_fan_min(struct device *dev, + struct device_attribute *devattr, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], - 1 << data->fan_div[nr])); + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index], + 1 << data->fan_div[attr->index])); } -static ssize_t show_fan_div(struct device *dev, char *buf, int nr) +static ssize_t show_fan_div(struct device *dev, + struct device_attribute *devattr, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); - return sprintf(buf, "%d\n", 1 << data->fan_div[nr]); + return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); } /* write new fan div, callers must hold data->update_lock */ @@ -352,12 +337,15 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, * - otherwise: select fan clock divider to suit fan speed low limit, * measurement code may adjust registers to ensure fan speed reading */ -static ssize_t set_fan_min(struct device *dev, const char *buf, - size_t count, int nr) +static ssize_t set_fan_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); + int nr = attr->index; u8 new_div; down(&data->update_lock); @@ -404,40 +392,16 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, return count; } -#define show_fan_offset(offset) \ -static ssize_t show_fan_##offset (struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ -return show_fan(dev, buf, offset - 1); \ -} \ -static ssize_t show_fan_##offset##_div (struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ -return show_fan_div(dev, buf, offset - 1); \ -} \ -static ssize_t show_fan_##offset##_min (struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ -return show_fan_min(dev, buf, offset - 1); \ -} \ -static ssize_t set_fan_##offset##_min (struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ -return set_fan_min(dev, buf, count, offset - 1); \ -} \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ - show_fan_##offset, NULL); \ -static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ - show_fan_##offset##_div, NULL); \ -static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_min, set_fan_##offset##_min); +#define fan(nr) \ +static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO, \ + show_fan, NULL, nr - 1); \ +static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO, \ + show_fan_div, NULL, nr - 1); \ +static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR, \ + show_fan_min, set_fan_min, nr - 1); -show_fan_offset(1); -show_fan_offset(2); +fan(1); +fan(2); /* alarms */ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) @@ -580,33 +544,59 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_detach; } - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); - device_create_file(&new_client->dev, &dev_attr_in5_input); - device_create_file(&new_client->dev, &dev_attr_in5_min); - device_create_file(&new_client->dev, &dev_attr_in5_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); + device_create_file(&new_client->dev, + &sensor_dev_attr_in0_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in0_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in0_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in1_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in1_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in1_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in2_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in2_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in2_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in3_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in3_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in3_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in4_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in4_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in4_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in5_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in5_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_in5_max.dev_attr); device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_fan2_min); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max_hyst.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_div.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_min.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_div.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_min.dev_attr); device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_aout_output); device_create_file(&new_client->dev, &dev_attr_chassis_clear); @@ -674,9 +664,9 @@ static void adm9240_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(1), 255); i2c_smbus_write_byte_data(client, - ADM9240_REG_TEMP_HIGH, 127); + ADM9240_REG_TEMP_MAX(0), 127); i2c_smbus_write_byte_data(client, - ADM9240_REG_TEMP_HYST, 127); + ADM9240_REG_TEMP_MAX(1), 127); /* start measurement cycle */ i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); @@ -753,10 +743,10 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) data->fan_min[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_FAN_MIN(i)); } - data->temp_high = i2c_smbus_read_byte_data(client, - ADM9240_REG_TEMP_HIGH); - data->temp_hyst = i2c_smbus_read_byte_data(client, - ADM9240_REG_TEMP_HYST); + data->temp_max[0] = i2c_smbus_read_byte_data(client, + ADM9240_REG_TEMP_MAX(0)); + data->temp_max[1] = i2c_smbus_read_byte_data(client, + ADM9240_REG_TEMP_MAX(1)); /* read fan divs and 5-bit VID */ i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); From 088341bd0c78143bf82ff21f7f0a715f99568c73 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 10 Sep 2005 23:00:46 +0200 Subject: [PATCH 0698/1940] [PATCH] hwmon: via686a: save 0.5k by long v[256] -> s16 v[256] We can save 0.5kB of data in the via686a driver. From: Denis Vlasenko Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/via686a.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 05ddc88e7dd2..60e94879f415 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -198,7 +198,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) but the function is very linear in the useful range (0-80 deg C), so we'll just use linear interpolation for 10-bit readings.) So, tempLUT is the temp at via register values 0-255: */ -static const long tempLUT[] = +static const s16 tempLUT[] = { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, @@ -270,7 +270,7 @@ static inline u8 TEMP_TO_REG(long val) } /* for 8-bit temperature hyst and over registers */ -#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100) +#define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100) /* for 10-bit temperature readings */ static inline long TEMP_FROM_REG10(u16 val) From e415e48b68155bea8b5452113dedba4ec486f3f6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:14:18 +0200 Subject: [PATCH 0699/1940] [PATCH] hwmon: adm9240 whitespace cleanups This whitespace cleanup patch removes one trailing space and breaks lines longer than 80 characters. Signed-off-by: Grant Coady Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/hwmon/adm9240.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) --- drivers/hwmon/adm9240.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 8bb6d6e45ed5..11dc95f8a17e 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -219,8 +219,8 @@ static ssize_t show_in(struct device *dev, struct device_attribute *devattr, attr->index)); } -static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t show_in_min(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); @@ -228,8 +228,8 @@ static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, attr->index)); } -static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, - char *buf) +static ssize_t show_in_max(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adm9240_data *data = adm9240_update_device(dev); @@ -237,7 +237,8 @@ static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, attr->index)); } -static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, +static ssize_t set_in_min(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); @@ -253,7 +254,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, return count; } -static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, +static ssize_t set_in_max(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); @@ -326,7 +328,7 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, "to %u\n", nr + 1, 1 << old, 1 << fan_div); } -/* +/* * set fan speed low limit: * * - value is zero: disable fan speed low limit alarm @@ -404,7 +406,8 @@ fan(1); fan(2); /* alarms */ -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm9240_data *data = adm9240_update_device(dev); return sprintf(buf, "%u\n", data->alarms); @@ -412,7 +415,8 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); /* vid */ -static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vid(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm9240_data *data = adm9240_update_device(dev); return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); @@ -420,13 +424,16 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); /* analog output */ -static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_aout(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm9240_data *data = adm9240_update_device(dev); return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout)); } -static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_aout(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); @@ -441,7 +448,9 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); /* chassis_clear */ -static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t chassis_clear(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); unsigned long val = simple_strtol(buf, NULL, 10); From b918ecd2429e1a89b846d9e49ca4520b963c13e8 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:18:49 +0200 Subject: [PATCH 0700/1940] [PATCH] hwmon: Do not forcibly enable via686a by default Do not enable the VIA VT82C686A/B integrated sensors by default, as disabled sensors usually means that this feature is not used so the values won't make any sense. This has been confusing many users in the past: http://www2.lm-sensors.nu/~lm78/readticket.cgi?ticket=1786 http://www2.lm-sensors.nu/~lm78/readticket.cgi?ticket=1811 http://www2.lm-sensors.nu/~lm78/readticket.cgi?ticket=2052 It is still possible to forcibly enable the sensors by using the force_addr module parameter. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Documentation/hwmon/via686a | 17 +++++++++++++++-- drivers/hwmon/via686a.c | 18 +++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) --- Documentation/hwmon/via686a | 17 +++++++++++++++-- drivers/hwmon/via686a.c | 18 +++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Documentation/hwmon/via686a b/Documentation/hwmon/via686a index b82014cb7c53..a936fb3824b2 100644 --- a/Documentation/hwmon/via686a +++ b/Documentation/hwmon/via686a @@ -18,8 +18,9 @@ Authors: Module Parameters ----------------- -force_addr=0xaddr Set the I/O base address. Useful for Asus A7V boards - that don't set the address in the BIOS. Does not do a +force_addr=0xaddr Set the I/O base address. Useful for boards that + don't set the address in the BIOS. Look for a BIOS + upgrade before resorting to this. Does not do a PCI force; the via686a must still be present in lspci. Don't use this unless the driver complains that the base address is not set. @@ -63,3 +64,15 @@ miss once-only alarms. The driver only updates its values each 1.5 seconds; reading it more often will do no harm, but will return 'old' values. + +Known Issues +------------ + +This driver handles sensors integrated in some VIA south bridges. It is +possible that a motherboard maker used a VT82C686A/B chip as part of a +product design but was not interested in its hardware monitoring features, +in which case the sensor inputs will not be wired. This is the case of +the Asus K7V, A7V and A7V133 motherboards, to name only a few of them. +So, if you need the force_addr parameter, and end up with values which +don't seem to make any sense, don't look any further: your chip is simply +not wired for hardware monitoring. diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 60e94879f415..688ccf924c3a 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -589,10 +589,8 @@ static int via686a_detect(struct i2c_adapter *adapter) u16 val; /* 8231 requires multiple of 256, we enforce that on 686 as well */ - if (force_addr) - address = force_addr & 0xFF00; - if (force_addr) { + address = force_addr & 0xFF00; dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address); if (PCIBIOS_SUCCESSFUL != @@ -603,11 +601,17 @@ static int via686a_detect(struct i2c_adapter *adapter) pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) return -ENODEV; if (!(val & 0x0001)) { - dev_warn(&adapter->dev, "enabling sensors\n"); - if (PCIBIOS_SUCCESSFUL != - pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, - val | 0x0001)) + if (force_addr) { + dev_info(&adapter->dev, "enabling sensors\n"); + if (PCIBIOS_SUCCESSFUL != + pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, + val | 0x0001)) + return -ENODEV; + } else { + dev_warn(&adapter->dev, "sensors disabled - enable " + "with force_addr=0x%x\n", address); return -ENODEV; + } } /* Reserve the ISA region */ From 605070952f0b41caaa211c47b02eeac703529008 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:23:07 +0200 Subject: [PATCH 0701/1940] [PATCH] i2c: Discard explicit static initializations to 0 Kill explicit static initializations to 0 in 10 i2c drivers. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/algos/i2c-algo-pca.c | 2 +- drivers/i2c/algos/i2c-algo-sibyte.c | 2 +- drivers/i2c/busses/i2c-ali15x3.c | 4 ++-- drivers/i2c/busses/i2c-amd756.c | 2 +- drivers/i2c/busses/i2c-iop3xx.c | 2 +- drivers/i2c/busses/i2c-piix4.c | 8 ++++---- drivers/i2c/busses/i2c-sis5595.c | 4 ++-- drivers/i2c/busses/i2c-sis630.c | 2 +- drivers/i2c/busses/i2c-sis96x.c | 2 +- drivers/i2c/busses/i2c-via.c | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) --- drivers/i2c/algos/i2c-algo-pca.c | 2 +- drivers/i2c/algos/i2c-algo-sibyte.c | 2 +- drivers/i2c/busses/i2c-ali15x3.c | 4 ++-- drivers/i2c/busses/i2c-amd756.c | 2 +- drivers/i2c/busses/i2c-iop3xx.c | 2 +- drivers/i2c/busses/i2c-piix4.c | 8 ++++---- drivers/i2c/busses/i2c-sis5595.c | 4 ++-- drivers/i2c/busses/i2c-sis630.c | 2 +- drivers/i2c/busses/i2c-sis96x.c | 2 +- drivers/i2c/busses/i2c-via.c | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index beb10edfe9c1..82946acab4c7 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -34,7 +34,7 @@ #define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0) #define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0) -static int i2c_debug=0; +static int i2c_debug; #define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val) #define pca_inw(adap, reg) adap->read_byte(adap, reg) diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 8ed5ad12552f..938848ae162d 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -42,7 +42,7 @@ /* module parameters: */ -static int bit_scan=0; /* have a look at what's hanging 'round */ +static int bit_scan; /* have a look at what's hanging 'round */ static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index b3f50bff39a0..e13d60c120b9 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -125,12 +125,12 @@ /* If force_addr is set to anything different from 0, we forcibly enable the device at the given address. */ -static u16 force_addr = 0; +static u16 force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"); -static unsigned short ali15x3_smba = 0; +static unsigned short ali15x3_smba; static int ali15x3_setup(struct pci_dev *ALI15X3_dev) { diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 6ad0603384b8..3bbac2f8ce38 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -86,7 +86,7 @@ #define AMD756_BLOCK_DATA 0x05 -static unsigned short amd756_ioport = 0; +static unsigned short amd756_ioport; /* SMBUS event = I/O 28-29 bit 11 diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 7bd9102db701..745e3a51f3e5 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -43,7 +43,7 @@ #include "i2c-iop3xx.h" /* global unit counter */ -static int i2c_id = 0; +static int i2c_id; static inline unsigned char iic_cook_addr(struct i2c_msg *msg) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 6d48a4da7bed..1b2d3ebd1075 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -90,13 +90,13 @@ struct sd { /* If force is set to anything different from 0, we forcibly enable the PIIX4. DANGEROUS! */ -static int force = 0; +static int force; module_param (force, int, 0); MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!"); /* If force_addr is set to anything different from 0, we forcibly enable the PIIX4 at the given address. VERY DANGEROUS! */ -static int force_addr = 0; +static int force_addr; module_param (force_addr, int, 0); MODULE_PARM_DESC(force_addr, "Forcibly enable the PIIX4 at the given address. " @@ -104,14 +104,14 @@ MODULE_PARM_DESC(force_addr, /* If fix_hstcfg is set to anything different from 0, we reset one of the registers to be a valid value. */ -static int fix_hstcfg = 0; +static int fix_hstcfg; module_param (fix_hstcfg, int, 0); MODULE_PARM_DESC(fix_hstcfg, "Fix config register. Needed on some boards (Force CPCI735)."); static int piix4_transaction(void); -static unsigned short piix4_smba = 0; +static unsigned short piix4_smba; static struct i2c_adapter piix4_adapter; static struct dmi_system_id __devinitdata piix4_dmi_table[] = { diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 080318d6f54b..3fd38f4673e3 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -123,11 +123,11 @@ static int blacklist[] = { /* If force_addr is set to anything different from 0, we forcibly enable the device at the given address. */ -static u16 force_addr = 0; +static u16 force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"); -static unsigned short sis5595_base = 0; +static unsigned short sis5595_base; static u8 sis5595_read(u8 reg) { diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 86f0f448fa0b..44c4e68e9a98 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -101,7 +101,7 @@ module_param(force, bool, 0); MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!"); /* acpi base address */ -static unsigned short acpi_base = 0; +static unsigned short acpi_base; /* supported chips */ static int supported[] = { diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index ead2ff3cf60e..9ddd910c3b99 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -83,7 +83,7 @@ #define SIS96x_BLOCK_DATA 0x05 static struct i2c_adapter sis96x_adapter; -static u16 sis96x_smbus_base = 0; +static u16 sis96x_smbus_base; static inline u8 sis96x_read(u8 reg) { diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 040b8abeabba..0b3edd4e6c12 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -45,7 +45,7 @@ #define IOSPACE 0x06 #define IOTEXT "via-i2c" -static u16 pm_io_base = 0; +static u16 pm_io_base; /* It does not appear from the datasheet that the GPIO pins are From 0200296310a454b39efc995e676f9ff60e641edb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:26:44 +0200 Subject: [PATCH 0702/1940] [PATCH] hwmon: Discard explicit static initializations to 0 Kill explicit static initializations to 0 in 2 hwmon drivers. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/hwmon/adm1021.c | 2 +- drivers/hwmon/via686a.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) --- drivers/hwmon/adm1021.c | 2 +- drivers/hwmon/via686a.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index e928cdb041cb..58aee3a00caa 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -121,7 +121,7 @@ static int adm1021_write_value(struct i2c_client *client, u8 reg, static struct adm1021_data *adm1021_update_device(struct device *dev); /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ -static int read_only = 0; +static int read_only; /* This is the driver that will be inserted */ diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 688ccf924c3a..54861f13fee2 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -44,7 +44,7 @@ /* If force_addr is set to anything different from 0, we forcibly enable the device at the given address. */ -static unsigned short force_addr = 0; +static unsigned short force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); From 7d845b10d06fa20a595a5161edabc5e846ed28a6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:29:38 +0200 Subject: [PATCH 0703/1940] [PATCH] hwmon: Discard bogus comment about init setting limits Discard a common out-of-date comment in 5 hardware monitoring drivers. The hardware monitoring chip drivers are no more setting sensor limits at initialization time, for quite some time already. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/hwmon/lm78.c | 1 - drivers/hwmon/via686a.c | 1 - drivers/hwmon/w83627hf.c | 1 - drivers/hwmon/w83781d.c | 1 - drivers/hwmon/w83792d.c | 1 - 5 files changed, 5 deletions(-) --- drivers/hwmon/lm78.c | 1 - drivers/hwmon/via686a.c | 1 - drivers/hwmon/w83627hf.c | 1 - drivers/hwmon/w83781d.c | 1 - drivers/hwmon/w83792d.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index f6730dc3573b..d697a554286f 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -726,7 +726,6 @@ static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -/* Called when we have found a new LM78. It should set limits, etc. */ static void lm78_init_client(struct i2c_client *client) { u8 config = lm78_read_value(client, LM78_REG_CONFIG); diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 54861f13fee2..c6e64f4abdea 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -712,7 +712,6 @@ static int via686a_detach_client(struct i2c_client *client) return 0; } -/* Called when we have found a new VIA686A. Set limits, etc. */ static void via686a_init_client(struct i2c_client *client) { u8 reg; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 3479dc5208e2..7f6f7280878d 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1275,7 +1275,6 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) return 0; } -/* Called when we have found a new W83781D. It should set limits, etc. */ static void w83627hf_init_client(struct i2c_client *client) { struct w83627hf_data *data = i2c_get_clientdata(client); diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 4c43337ca780..26b1fac7c619 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1451,7 +1451,6 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) return 0; } -/* Called when we have found a new W83781D. It should set limits, etc. */ static void w83781d_init_client(struct i2c_client *client) { diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index ba0c28015f6a..7bbd1888ce94 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -1429,7 +1429,6 @@ w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) return 0; } -/* Called when we have found a new W83792D. It should set limits, etc. */ static void w83792d_init_client(struct i2c_client *client) { From d6072f842a77014220683ee5b781b7cee8f020d1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:37:04 +0200 Subject: [PATCH 0704/1940] [PATCH] i2c: Reuse name strings in i2c bus drivers Clean up name string usage in 12 i2c bus drivers: * Use the i2c_adapter name for requesting the I/O region rather than redefining a new string. * Do not initialize the i2c_adapter name to "unset". This should save a few data bytes here and there. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-ali1535.c | 6 +++--- drivers/i2c/busses/i2c-ali1563.c | 6 ++++-- drivers/i2c/busses/i2c-ali15x3.c | 5 +++-- drivers/i2c/busses/i2c-amd756.c | 5 ++--- drivers/i2c/busses/i2c-amd8111.c | 4 +++- drivers/i2c/busses/i2c-i801.c | 4 ++-- drivers/i2c/busses/i2c-nforce2.c | 4 ++-- drivers/i2c/busses/i2c-piix4.c | 4 ++-- drivers/i2c/busses/i2c-sis5595.c | 5 +++-- drivers/i2c/busses/i2c-sis630.c | 6 ++++-- drivers/i2c/busses/i2c-sis96x.c | 5 +++-- drivers/i2c/busses/i2c-via.c | 4 ++-- 12 files changed, 33 insertions(+), 25 deletions(-) --- drivers/i2c/busses/i2c-ali1535.c | 6 +++--- drivers/i2c/busses/i2c-ali1563.c | 6 ++++-- drivers/i2c/busses/i2c-ali15x3.c | 5 +++-- drivers/i2c/busses/i2c-amd756.c | 5 ++--- drivers/i2c/busses/i2c-amd8111.c | 4 +++- drivers/i2c/busses/i2c-i801.c | 4 ++-- drivers/i2c/busses/i2c-nforce2.c | 4 ++-- drivers/i2c/busses/i2c-piix4.c | 4 ++-- drivers/i2c/busses/i2c-sis5595.c | 5 +++-- drivers/i2c/busses/i2c-sis630.c | 6 ++++-- drivers/i2c/busses/i2c-sis96x.c | 5 +++-- drivers/i2c/busses/i2c-via.c | 4 ++-- 12 files changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index f021acd2674e..3eb47890db40 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -134,7 +134,7 @@ /* -> Read = 1 */ #define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */ - +static struct pci_driver ali1535_driver; static unsigned short ali1535_smba; static DECLARE_MUTEX(i2c_ali1535_sem); @@ -162,7 +162,8 @@ static int ali1535_setup(struct pci_dev *dev) goto exit; } - if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb")) { + if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, + ali1535_driver.name)) { dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n", ali1535_smba); goto exit; @@ -480,7 +481,6 @@ static struct i2c_adapter ali1535_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static struct pci_device_id ali1535_ids[] = { diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 86947504aea1..e6f63208fc4a 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -60,6 +60,7 @@ #define HST_CNTL2_SIZEMASK 0x38 +static struct pci_driver ali1563_pci_driver; static unsigned short ali1563_smba; static int ali1563_transaction(struct i2c_adapter * a, int size) @@ -350,7 +351,8 @@ static int __devinit ali1563_setup(struct pci_dev * dev) dev_warn(&dev->dev,"ali1563_smba Uninitialized\n"); goto Err; } - if (!request_region(ali1563_smba,ALI1563_SMB_IOSIZE,"i2c-ali1563")) { + if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE, + ali1563_pci_driver.name)) { dev_warn(&dev->dev,"Could not allocate I/O space"); goto Err; } @@ -406,7 +408,7 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = { MODULE_DEVICE_TABLE (pci, ali1563_id_table); static struct pci_driver ali1563_pci_driver = { - .name = "ali1563_i2c", + .name = "ali1563_smbus", .id_table = ali1563_id_table, .probe = ali1563_probe, .remove = __devexit_p(ali1563_remove), diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index e13d60c120b9..7a5c0941dbc1 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -130,6 +130,7 @@ module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"); +static struct pci_driver ali15x3_driver; static unsigned short ali15x3_smba; static int ali15x3_setup(struct pci_dev *ALI15X3_dev) @@ -166,7 +167,8 @@ static int ali15x3_setup(struct pci_dev *ALI15X3_dev) if(force_addr) ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1); - if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) { + if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, + ali15x3_driver.name)) { dev_err(&ALI15X3_dev->dev, "ALI15X3_smb region 0x%x already in use!\n", ali15x3_smba); @@ -470,7 +472,6 @@ static struct i2c_adapter ali15x3_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static struct pci_device_id ali15x3_ids[] = { diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 3bbac2f8ce38..1750dedaf4b5 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -85,7 +85,7 @@ #define AMD756_PROCESS_CALL 0x04 #define AMD756_BLOCK_DATA 0x05 - +static struct pci_driver amd756_driver; static unsigned short amd756_ioport; /* @@ -303,7 +303,6 @@ struct i2c_adapter amd756_smbus = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 }; @@ -365,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev, amd756_ioport += SMB_ADDR_OFFSET; } - if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) { + if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", amd756_ioport); return -ENODEV; diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 45ea24ba14d5..49ff11e5134f 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -30,6 +30,8 @@ struct amd_smbus { int size; }; +static struct pci_driver amd8111_driver; + /* * AMD PCI control registers definitions. */ @@ -352,7 +354,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_ smbus->base = pci_resource_start(dev, 0); smbus->size = pci_resource_len(dev, 0); - if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0")) + if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) goto out_kfree; smbus->adapter.owner = THIS_MODULE; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 709beab76609..588583530c9f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -110,6 +110,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, int command); static unsigned short i801_smba; +static struct pci_driver i801_driver; static struct pci_dev *I801_dev; static int isich4; @@ -143,7 +144,7 @@ static int i801_setup(struct pci_dev *dev) } } - if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) { + if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", i801_smba); error_return = -EBUSY; @@ -543,7 +544,6 @@ static struct i2c_adapter i801_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static struct pci_device_id i801_ids[] = { diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index fe9c0f42a2b7..dd4b6d8e03ef 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -97,6 +97,7 @@ struct nforce2_smbus { #define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA 0x4a #define NVIDIA_SMB_PRTCL_PEC 0x80 +static struct pci_driver nforce2_driver; static s32 nforce2_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, @@ -113,7 +114,6 @@ static struct i2c_adapter nforce2_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; /* Return -1 on error. See smbus.h for more information */ @@ -285,7 +285,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, smbus->base = iobase & 0xfffc; smbus->size = 8; - if (!request_region(smbus->base, smbus->size, "nForce2 SMBus")) { + if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", smbus->base, smbus->base+smbus->size-1, name); return -1; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 1b2d3ebd1075..692f47345481 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -112,6 +112,7 @@ MODULE_PARM_DESC(fix_hstcfg, static int piix4_transaction(void); static unsigned short piix4_smba; +static struct pci_driver piix4_driver; static struct i2c_adapter piix4_adapter; static struct dmi_system_id __devinitdata piix4_dmi_table[] = { @@ -157,7 +158,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, } } - if (!request_region(piix4_smba, SMBIOSIZE, "piix4-smbus")) { + if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n", piix4_smba); return -ENODEV; @@ -407,7 +408,6 @@ static struct i2c_adapter piix4_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static struct pci_device_id piix4_ids[] = { diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 3fd38f4673e3..b57ab74d23ec 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -127,6 +127,7 @@ static u16 force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"); +static struct pci_driver sis5595_driver; static unsigned short sis5595_base; static u8 sis5595_read(u8 reg) @@ -172,7 +173,8 @@ static int sis5595_setup(struct pci_dev *SIS5595_dev) /* NB: We grab just the two SMBus registers here, but this may still * interfere with ACPI :-( */ - if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) { + if (!request_region(sis5595_base + SMB_INDEX, 2, + sis5595_driver.name)) { dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n", sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1); return -ENODEV; @@ -364,7 +366,6 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis5595_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, - .name = "unset", .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 44c4e68e9a98..acb75e282414 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -92,6 +92,8 @@ #define SIS630_PCALL 0x04 #define SIS630_BLOCK_DATA 0x05 +static struct pci_driver sis630_driver; + /* insmod parameters */ static int high_clock; static int force; @@ -432,7 +434,8 @@ static int sis630_setup(struct pci_dev *sis630_dev) dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base); /* Everything is happy, let's grab the memory and set things up. */ - if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")) { + if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, + sis630_driver.name)) { dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already " "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA); goto exit; @@ -455,7 +458,6 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis630_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, - .name = "unset", .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 9ddd910c3b99..3024907cdafe 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -82,6 +82,7 @@ #define SIS96x_PROC_CALL 0x04 #define SIS96x_BLOCK_DATA 0x05 +static struct pci_driver sis96x_driver; static struct i2c_adapter sis96x_adapter; static u16 sis96x_smbus_base; @@ -257,7 +258,6 @@ static struct i2c_adapter sis96x_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static struct pci_device_id sis96x_ids[] = { @@ -294,7 +294,8 @@ static int __devinit sis96x_probe(struct pci_dev *dev, sis96x_smbus_base); /* Everything is happy, let's grab the memory and set things up. */ - if (!request_region(sis96x_smbus_base, SMB_IOSIZE, "sis96x-smbus")) { + if (!request_region(sis96x_smbus_base, SMB_IOSIZE, + sis96x_driver.name)) { dev_err(&dev->dev, "SMBus registers 0x%04x-0x%04x " "already in use!\n", sis96x_smbus_base, sis96x_smbus_base + SMB_IOSIZE - 1); diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 0b3edd4e6c12..484bbacfce6b 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -43,8 +43,8 @@ /* io-region reservation */ #define IOSPACE 0x06 -#define IOTEXT "via-i2c" +static struct pci_driver vt586b_driver; static u16 pm_io_base; /* @@ -130,7 +130,7 @@ static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_i pci_read_config_word(dev, base, &pm_io_base); pm_io_base &= (0xff << 8); - if (!request_region(I2C_DIR, IOSPACE, IOTEXT)) { + if (!request_region(I2C_DIR, IOSPACE, vt586b_driver.name)) { dev_err(&dev->dev, "IO 0x%x-0x%x already in use\n", I2C_DIR, I2C_DIR + IOSPACE); return -ENODEV; } From 709439a284bc5b7d42a70fee7119feb186c1ca99 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:41:18 +0200 Subject: [PATCH 0705/1940] [PATCH] hwmon: w83l785ts converted to dynamic sysfs callbacks Convert the w83l785ts driver to use dynamic sysfs callbacks. This is a small driver so the benefit is thin, but still worth it. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/hwmon/w83l785ts.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) --- drivers/hwmon/w83l785ts.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 133e34ab1d0a..fcb2c39b04fd 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /* How many retries on register read error */ @@ -111,27 +112,24 @@ struct w83l785ts_data { unsigned long last_updated; /* in jiffies */ /* registers values */ - u8 temp, temp_over; + u8 temp[2]; /* 0: input + 1: critical limit */ }; /* * Sysfs stuff */ -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct w83l785ts_data *data = w83l785ts_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); } -static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct w83l785ts_data *data = w83l785ts_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); -} - -static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); -static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1); /* * Real code @@ -228,7 +226,7 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) init_MUTEX(&data->update_lock); /* Default values in case the first read fails (unlikely). */ - data->temp_over = data->temp = 0; + data->temp[1] = data->temp[0] = 0; /* Tell the I2C layer a new client has arrived. */ if ((err = i2c_attach_client(new_client))) @@ -246,8 +244,10 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_detach; } - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); return 0; @@ -305,10 +305,10 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev) if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) { dev_dbg(&client->dev, "Updating w83l785ts data.\n"); - data->temp = w83l785ts_read_value(client, - W83L785TS_REG_TEMP, data->temp); - data->temp_over = w83l785ts_read_value(client, - W83L785TS_REG_TEMP_OVER, data->temp_over); + data->temp[0] = w83l785ts_read_value(client, + W83L785TS_REG_TEMP, data->temp[0]); + data->temp[1] = w83l785ts_read_value(client, + W83L785TS_REG_TEMP_OVER, data->temp[1]); data->last_updated = jiffies; data->valid = 1; From cb929eae78ec0b243dbf58039bce4af354f6020c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:45:03 +0200 Subject: [PATCH 0706/1940] [PATCH] hwmon: Minor w83l785ts optimization Using s8 instead of u8 to store temperature register values saves a few instructions on sysfs file read. The very same was done for several other drivers a while ago (lm63, lm83, lm90...) Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/hwmon/w83l785ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- drivers/hwmon/w83l785ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index fcb2c39b04fd..db12a620b331 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -74,7 +74,7 @@ I2C_CLIENT_INSMOD_1(w83l785ts); * The W83L785TS-S uses signed 8-bit values. */ -#define TEMP_FROM_REG(val) ((val & 0x80 ? val-0x100 : val) * 1000) +#define TEMP_FROM_REG(val) ((val) * 1000) /* * Functions declaration @@ -112,7 +112,7 @@ struct w83l785ts_data { unsigned long last_updated; /* in jiffies */ /* registers values */ - u8 temp[2]; /* 0: input + s8 temp[2]; /* 0: input 1: critical limit */ }; From 4366dc946c01305cff49b07dabb806d2364f1edb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:50:06 +0200 Subject: [PATCH 0707/1940] [PATCH] i2c: Adjust i2c_probe() for busses without SMBUS_QUICK Move the check for SMBUS_QUICK in i2c_probe() after the forced addresses have been handled. This makes it possible for a driver to leave the probed address lists empty, only providing forced addresses, and get i2c_probe to work even if the bus doesn't support SMBUS_QUICK. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/i2c-core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- drivers/i2c/i2c-core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 45aa0e54e297..b55097d57b7a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -706,10 +706,6 @@ int i2c_probe(struct i2c_adapter *adapter, int i, err; int adap_id = i2c_adapter_id(adapter); - /* Forget it if we can't probe using SMBUS_QUICK */ - if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK)) - return -1; - /* Force entries are done first, and are not affected by ignore entries */ if (address_data->forces) { @@ -736,6 +732,17 @@ int i2c_probe(struct i2c_adapter *adapter, } } + /* Stop here if we can't use SMBUS_QUICK */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { + if (address_data->probe[0] == I2C_CLIENT_END + && address_data->normal_i2c[0] == I2C_CLIENT_END) + return 0; + + dev_warn(&adapter->dev, "SMBus Quick command not supported, " + "can't probe for chips\n"); + return -1; + } + /* Probe entries are done second, and are not affected by ignore entries either */ for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) { From d057c96cab72bc6b70570d25b90404f81d98e886 Mon Sep 17 00:00:00 2001 From: Hideki Iwamoto Date: Sun, 25 Sep 2005 16:53:04 +0200 Subject: [PATCH 0708/1940] [PATCH] i2c: Fix I2C_FUNC_PROTOCOL_MANGLING documentation Fix the description of I2C_FUNC_PROTOCOL_MANGLING. From: Hideki Iwamoto Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Documentation/i2c/functionality | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) --- Documentation/i2c/functionality | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality index 41ffefbdc60c..60cca249e452 100644 --- a/Documentation/i2c/functionality +++ b/Documentation/i2c/functionality @@ -17,9 +17,10 @@ For the most up-to-date list of functionality constants, please check I2C_FUNC_I2C Plain i2c-level commands (Pure SMBus adapters typically can not do these) I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions - I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_REV_DIR_ADDR, - I2C_M_REV_DIR_ADDR and I2C_M_REV_DIR_NOSTART - flags (which modify the i2c protocol!) + I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK, + I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and + I2C_M_NO_RD_ACK flags (which modify the + I2C protocol!) I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command From 332bf92b3338e140cbcfc25f69911e8ca59788c7 Mon Sep 17 00:00:00 2001 From: Hideki Iwamoto Date: Sun, 25 Sep 2005 16:56:43 +0200 Subject: [PATCH 0709/1940] [PATCH] i2c: Fix union i2c_smbus_data definition The i2c_smbus_data union block member has a comment stating that an extra byte is required for SMBus Block Process Call transactions. This has been true for three weeks around June 2002, but no more since, so it is about time that we drop this comment and fix the definition. From: Hideki Iwamoto Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman include/linux/i2c.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) --- include/linux/i2c.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 3d49a305bf88..17d63c1efdce 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -454,8 +454,7 @@ struct i2c_msg { union i2c_smbus_data { __u8 byte; __u16 word; - __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */ - /* one more for read length in block process call */ + __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ /* and one more for PEC */ }; From 0f69a612f950f7508e556bf1b09390087d112115 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 25 Sep 2005 16:58:22 +0200 Subject: [PATCH 0710/1940] [PATCH] i2c: Minor i2c-amd8111 cleanup I noticed a useless instruction in the i2c-amd8111 driver. Signed-off-by: Jean Delvare CC: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-amd8111.c | 1 - 1 file changed, 1 deletion(-) --- drivers/i2c/busses/i2c-amd8111.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 49ff11e5134f..6200c9a087ad 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -244,7 +244,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl break; case I2C_SMBUS_BLOCK_PROC_CALL: - protocol |= pec; len = min_t(u8, data->block[0], 31); amd_ec_write(smbus, AMD_SMB_CMD, command); amd_ec_write(smbus, AMD_SMB_BCNT, len); From 5c50d1885981537ff3b8df6433951de6c9cb72cb Mon Sep 17 00:00:00 2001 From: Hideki Iwamoto Date: Sun, 25 Sep 2005 17:01:11 +0200 Subject: [PATCH 0711/1940] [PATCH] i2c: Several PEC-related fixes in software SMBus emulation Fix several errors in I2C SMBus emulation when PEC is used: * Weird logic error in SMBus Write Word transactions. * Wrong buffer size, affecting SMBus Block Write transactions. * Potential buffer overrun in SMBus Block Write transactions. From: Hideki Iwamoto Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/i2c-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) --- drivers/i2c/i2c-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b55097d57b7a..9583a54ce16b 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -864,7 +864,7 @@ static int i2c_smbus_add_pec(u16 addr, u8 command, int size, break; case I2C_SMBUS_BYTE_DATA: buf[2] = data->byte; - data->word = buf[2] || + data->word = buf[2] | (i2c_smbus_pec(3, buf, NULL) << 8); size = I2C_SMBUS_WORD_DATA; break; @@ -1033,8 +1033,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, need to use only one message; when reading, we need two. We initialize most things with sane defaults, to keep the code below somewhat simpler. */ - unsigned char msgbuf0[34]; - unsigned char msgbuf1[34]; + unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; int num = read_write == I2C_SMBUS_READ?2:1; struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, { addr, flags | I2C_M_RD, 0, msgbuf1 } @@ -1097,7 +1097,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, } if(size == I2C_SMBUS_BLOCK_DATA_PEC) (msg[0].len)++; - for (i = 1; i <= msg[0].len; i++) + for (i = 1; i < msg[0].len; i++) msgbuf0[i] = data->block[i-1]; } break; From 32c0a520f506c046f241de2a3a9b02a395ef76d2 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 21:47:58 +0200 Subject: [PATCH 0712/1940] [PATCH] i2c-viapro: New maintainer I am taking over the maintenance of the i2c-viapro SMBus driver. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 248b93b32fc4..3928dc7d6ea9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2736,6 +2736,12 @@ P: Roger Luethi M: rl@hellgate.ch S: Maintained +VIAPRO SMBUS DRIVER +P: Jean Delvare +M: khali@linux-fr.org +L: lm-sensors@lm-sensors.org +S: Maintained + UCLINUX (AND M68KNOMMU) P: Greg Ungerer M: gerg@uclinux.org From 5f49ef8e8cefe0a95948b4270db28507c1c287d4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 21:50:47 +0200 Subject: [PATCH 0713/1940] [PATCH] i2c-viapro: Coding style fixes Before I go on cleaning up and improving the i2c-viapro driver, let's fix all the coding style issues: mostly trailing white space, and spaces used where tabs should be. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Documentation/i2c/busses/i2c-viapro | 12 ++--- drivers/i2c/busses/i2c-viapro.c | 76 ++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 45 deletions(-) --- Documentation/i2c/busses/i2c-viapro | 12 ++--- drivers/i2c/busses/i2c-viapro.c | 76 ++++++++++++++--------------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 702f5ac68c09..ef0f1e94e726 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro @@ -4,17 +4,17 @@ Supported adapters: * VIA Technologies, Inc. VT82C596A/B Datasheet: Sometimes available at the VIA website - * VIA Technologies, Inc. VT82C686A/B + * VIA Technologies, Inc. VT82C686A/B Datasheet: Sometimes available at the VIA website * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237 Datasheet: available on request from Via Authors: - Frodo Looijaard , - Philip Edelbrock , - Kyösti Mälkki , - Mark D. Studebaker + Frodo Looijaard , + Philip Edelbrock , + Kyösti Mälkki , + Mark D. Studebaker Module Parameters ----------------- @@ -43,5 +43,3 @@ Your lspci -n listing must show one of these : If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. - - diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 99d209e0485a..262755e1ae02 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -1,7 +1,7 @@ /* i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - Copyright (c) 1998 - 2002 Frodo Looijaard , + Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , Kyösti Mälkki , Mark D. Studebaker @@ -46,9 +46,9 @@ static struct pci_dev *vt596_pdev; -#define SMBBA1 0x90 -#define SMBBA2 0x80 -#define SMBBA3 0xD0 +#define SMBBA1 0x90 +#define SMBBA2 0x80 +#define SMBBA3 0xD0 /* SMBus address offsets */ static unsigned short vt596_smba; @@ -68,26 +68,26 @@ static unsigned short vt596_smba; /* PCI Address Constants */ /* SMBus data in configuration space can be found in two places, - We try to select the better one*/ + We try to select the better one */ static unsigned short smb_cf_hstcfg = 0xD2; -#define SMBHSTCFG (smb_cf_hstcfg) -#define SMBSLVC (smb_cf_hstcfg + 1) -#define SMBSHDW1 (smb_cf_hstcfg + 2) -#define SMBSHDW2 (smb_cf_hstcfg + 3) -#define SMBREV (smb_cf_hstcfg + 4) +#define SMBHSTCFG (smb_cf_hstcfg) +#define SMBSLVC (smb_cf_hstcfg + 1) +#define SMBSHDW1 (smb_cf_hstcfg + 2) +#define SMBSHDW2 (smb_cf_hstcfg + 3) +#define SMBREV (smb_cf_hstcfg + 4) /* Other settings */ #define MAX_TIMEOUT 500 #define ENABLE_INT9 0 /* VT82C596 constants */ -#define VT596_QUICK 0x00 -#define VT596_BYTE 0x04 -#define VT596_BYTE_DATA 0x08 -#define VT596_WORD_DATA 0x0C -#define VT596_BLOCK_DATA 0x14 +#define VT596_QUICK 0x00 +#define VT596_BYTE 0x04 +#define VT596_BYTE_DATA 0x08 +#define VT596_WORD_DATA 0x0C +#define VT596_BLOCK_DATA 0x14 /* If force is set to anything different from 0, we forcibly enable the @@ -115,19 +115,19 @@ static int vt596_transaction(void) int timeout = 0; dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " - "Resetting...\n", temp); - + "Resetting...\n", temp); + outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp); - + return -1; } else { dev_dbg(&vt596_adapter.dev, "Successfull!\n"); @@ -137,7 +137,7 @@ static int vt596_transaction(void) /* start the transaction by setting bit 6 */ outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); - /* We will always wait for a fraction of a second! + /* We will always wait for a fraction of a second! I don't know if VIA needs this, Intel did */ do { msleep(1); @@ -177,16 +177,16 @@ static int vt596_transaction(void) dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); - + return result; } /* Return -1 on error. */ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, - unsigned short flags, char read_write, u8 command, - int size, union i2c_smbus_data *data) + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) { int i, len; @@ -256,7 +256,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, case VT596_BYTE: /* Where is the result put? I assume here it is in * SMBHSTDAT0 but it might just as well be in the - * SMBHSTCMD. No clue in the docs + * SMBHSTCMD. No clue in the docs */ data->byte = inb_p(SMBHSTDAT0); break; @@ -302,7 +302,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, { unsigned char temp; int error = -ENODEV; - + /* Determine the address of the SMBus areas */ if (force_addr) { vt596_smba = force_addr & 0xfff0; @@ -333,10 +333,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev, return -ENODEV; } - found: +found: if (!request_region(vt596_smba, 8, "viapro-smbus")) { dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", - vt596_smba); + vt596_smba); return -ENODEV; } @@ -348,13 +348,13 @@ static int __devinit vt596_probe(struct pci_dev *pdev, pci_write_config_word(pdev, id->driver_data, vt596_smba); pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01); dev_warn(&pdev->dev, "WARNING: SMBus interface set to new " - "address 0x%04x!\n", vt596_smba); + "address 0x%04x!\n", vt596_smba); } else if ((temp & 1) == 0) { if (force) { - /* NOTE: This assumes I/O space and other allocations - * WERE done by the Bios! Don't complain if your - * hardware does weird things after enabling this. - * :') Check for Bios updates before resorting to + /* NOTE: This assumes I/O space and other allocations + * WERE done by the Bios! Don't complain if your + * hardware does weird things after enabling this. + * :') Check for Bios updates before resorting to * this. */ pci_write_config_byte(pdev, SMBHSTCFG, temp | 1); @@ -381,8 +381,8 @@ static int __devinit vt596_probe(struct pci_dev *pdev, vt596_adapter.dev.parent = &pdev->dev; snprintf(vt596_adapter.name, I2C_NAME_SIZE, - "SMBus Via Pro adapter at %04x", vt596_smba); - + "SMBus Via Pro adapter at %04x", vt596_smba); + vt596_pdev = pci_dev_get(pdev); if (i2c_add_adapter(&vt596_adapter)) { pci_dev_put(vt596_pdev); @@ -395,7 +395,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, */ return -ENODEV; - release_region: +release_region: release_region(vt596_smba, 8); return error; } @@ -420,7 +420,7 @@ static struct pci_device_id vt596_ids[] = { { 0, } }; -MODULE_DEVICE_TABLE (pci, vt596_ids); +MODULE_DEVICE_TABLE(pci, vt596_ids); static struct pci_driver vt596_driver = { .name = "vt596_smbus", From f118301416953d677de738100c33eb8cfb7adecb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 21:58:41 +0200 Subject: [PATCH 0714/1940] [PATCH] i2c-viapro: Implement I2C Block transactions Implement the I2C block transactions on VIA chips which support them: VT82C686B, VT8233, VT8233A, VT8235 and VT8237R. This speeds up EEPROM accesses by a factor 10 or so. I would like to thank Antonino A. Daplas, Hinko Kocevar, Salah Coronya and Andreas Henriksson for their help in testing this new feature. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Documentation/i2c/busses/i2c-viapro | 7 +++++- drivers/i2c/busses/i2c-viapro.c | 39 +++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) --- Documentation/i2c/busses/i2c-viapro | 7 +++++- drivers/i2c/busses/i2c-viapro.c | 39 ++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index ef0f1e94e726..387cbd4015fc 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro @@ -14,7 +14,8 @@ Authors: Frodo Looijaard , Philip Edelbrock , Kyösti Mälkki , - Mark D. Studebaker + Mark D. Studebaker , + Jean Delvare Module Parameters ----------------- @@ -43,3 +44,7 @@ Your lspci -n listing must show one of these : If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. + +Except for the oldest chips (VT82C596A/B, VT82C686A and most probably +VT8231), this driver supports I2C block transactions. Such transactions +are mainly useful to read from and write to EEPROMs. diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 262755e1ae02..b420e752b1dc 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -4,6 +4,7 @@ Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , Kyösti Mälkki , Mark D. Studebaker + Copyright (C) 2005 Jean Delvare 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 @@ -88,6 +89,7 @@ static unsigned short smb_cf_hstcfg = 0xD2; #define VT596_BYTE_DATA 0x08 #define VT596_WORD_DATA 0x0C #define VT596_BLOCK_DATA 0x14 +#define VT596_I2C_BLOCK_DATA 0x34 /* If force is set to anything different from 0, we forcibly enable the @@ -107,6 +109,9 @@ MODULE_PARM_DESC(force_addr, static struct i2c_adapter vt596_adapter; +#define FEATURE_I2CBLOCK (1<<0) +static unsigned int vt596_features; + /* Another internally used function */ static int vt596_transaction(void) { @@ -225,6 +230,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, } size = VT596_WORD_DATA; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + if (!(vt596_features & FEATURE_I2CBLOCK)) + return -1; + if (read_write == I2C_SMBUS_READ) + outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0); + /* Fall through */ case I2C_SMBUS_BLOCK_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); @@ -240,11 +251,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, for (i = 1; i <= len; i++) outb_p(data->block[i], SMBBLKDAT); } - size = VT596_BLOCK_DATA; + size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ? + VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA; break; } - outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); + outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); if (vt596_transaction()) /* Error in transaction */ return -1; @@ -266,6 +278,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, case VT596_WORD_DATA: data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); break; + case VT596_I2C_BLOCK_DATA: case VT596_BLOCK_DATA: data->block[0] = inb_p(SMBHSTDAT0); if (data->block[0] > I2C_SMBUS_BLOCK_MAX) @@ -280,9 +293,13 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, static u32 vt596_func(struct i2c_adapter *adapter) { - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA; + + if (vt596_features & FEATURE_I2CBLOCK) + func |= I2C_FUNC_SMBUS_I2C_BLOCK; + return func; } static struct i2c_algorithm smbus_algorithm = { @@ -379,6 +396,22 @@ static int __devinit vt596_probe(struct pci_dev *pdev, dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp); dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba); + switch (pdev->device) { + case PCI_DEVICE_ID_VIA_8237: + case PCI_DEVICE_ID_VIA_8235: + case PCI_DEVICE_ID_VIA_8233A: + case PCI_DEVICE_ID_VIA_8233_0: + vt596_features |= FEATURE_I2CBLOCK; + break; + case PCI_DEVICE_ID_VIA_82C686_4: + /* The VT82C686B (rev 0x40) does support I2C block + transactions, but the VT82C686A (rev 0x30) doesn't */ + if (!pci_read_config_byte(pdev, PCI_REVISION_ID, &temp) + && temp >= 0x40) + vt596_features |= FEATURE_I2CBLOCK; + break; + } + vt596_adapter.dev.parent = &pdev->dev; snprintf(vt596_adapter.name, I2C_NAME_SIZE, "SMBus Via Pro adapter at %04x", vt596_smba); From c2f559d5df5751780c0bd3ea0bd0aa17d47c0b39 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 22:01:07 +0200 Subject: [PATCH 0715/1940] [PATCH] i2c-viapro: Code cleanups Cleanups to the i2c-viapro driver: * Kill unused defines. * Kill interrupt-related code, as the driver doesn't use interrupts. * Fix broken comments (some copied from i2c-piix4.) * Centralize the unsupported command error case in vt596_access. That way we'll catch all unsupported commands, not only I2C_SMBUS_PROC_CALL. * Refactor some code. * Convert some dev_dbg into dev_err. Errors better be reported even in non-debug mode. * Do not verify that the final reset succeeded. It'll be checked at the beginning of the next transaction anyway. * Use the driver name to reserve the I/O region. * Do not print the contents of the SMBREV register, it reads 0 on all chips I've seen so far. * Some other minor fixes all over the place. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-viapro.c | 122 +++++++++++++--------------------------- 1 file changed, 41 insertions(+), 81 deletions(-) --- drivers/i2c/busses/i2c-viapro.c | 122 +++++++++++--------------------- 1 file changed, 41 insertions(+), 81 deletions(-) diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index b420e752b1dc..5cf8fe182806 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -54,34 +53,22 @@ static struct pci_dev *vt596_pdev; /* SMBus address offsets */ static unsigned short vt596_smba; #define SMBHSTSTS (vt596_smba + 0) -#define SMBHSLVSTS (vt596_smba + 1) #define SMBHSTCNT (vt596_smba + 2) #define SMBHSTCMD (vt596_smba + 3) #define SMBHSTADD (vt596_smba + 4) #define SMBHSTDAT0 (vt596_smba + 5) #define SMBHSTDAT1 (vt596_smba + 6) #define SMBBLKDAT (vt596_smba + 7) -#define SMBSLVCNT (vt596_smba + 8) -#define SMBSHDWCMD (vt596_smba + 9) -#define SMBSLVEVT (vt596_smba + 0xA) -#define SMBSLVDAT (vt596_smba + 0xC) /* PCI Address Constants */ /* SMBus data in configuration space can be found in two places, We try to select the better one */ -static unsigned short smb_cf_hstcfg = 0xD2; - -#define SMBHSTCFG (smb_cf_hstcfg) -#define SMBSLVC (smb_cf_hstcfg + 1) -#define SMBSHDW1 (smb_cf_hstcfg + 2) -#define SMBSHDW2 (smb_cf_hstcfg + 3) -#define SMBREV (smb_cf_hstcfg + 4) +static unsigned short SMBHSTCFG = 0xD2; /* Other settings */ #define MAX_TIMEOUT 500 -#define ENABLE_INT9 0 /* VT82C596 constants */ #define VT596_QUICK 0x00 @@ -107,12 +94,13 @@ MODULE_PARM_DESC(force_addr, "EXTREMELY DANGEROUS!"); +static struct pci_driver vt596_driver; static struct i2c_adapter vt596_adapter; #define FEATURE_I2CBLOCK (1<<0) static unsigned int vt596_features; -/* Another internally used function */ +/* Return -1 on error, 0 on success */ static int vt596_transaction(void) { int temp; @@ -127,23 +115,21 @@ static int vt596_transaction(void) /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " - "Resetting...\n", temp); + "Resetting... ", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { - dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp); - + printk("Failed! (0x%02x)\n", temp); return -1; } else { - dev_dbg(&vt596_adapter.dev, "Successfull!\n"); + printk("Successful!\n"); } } - /* start the transaction by setting bit 6 */ - outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); + /* Start the transaction by setting bit 6 */ + outb_p(inb(SMBHSTCNT) | 0x40, SMBHSTCNT); - /* We will always wait for a fraction of a second! - I don't know if VIA needs this, Intel did */ + /* We will always wait for a fraction of a second */ do { msleep(1); temp = inb_p(SMBHSTSTS); @@ -152,33 +138,32 @@ static int vt596_transaction(void) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { result = -1; - dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n"); + dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); } if (temp & 0x10) { result = -1; - dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n"); + dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", + inb_p(SMBHSTCNT) & 0x3C); } if (temp & 0x08) { result = -1; - dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be " - "locked until next hard\nreset. (sorry!)\n"); - /* Clock stops and slave is stuck in mid-transmission */ + dev_err(&vt596_adapter.dev, "SMBus collision!\n"); } if (temp & 0x04) { result = -1; - dev_dbg(&vt596_adapter.dev, "Error: no response!\n"); + /* Quick commands are used to probe for chips, so + errors are expected, and we don't want to frighten the + user. */ + if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) + dev_err(&vt596_adapter.dev, "Transaction error!\n"); } - if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { + /* Resetting status register */ + if (temp & 0x1F) outb_p(temp, SMBHSTSTS); - if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { - dev_warn(&vt596_adapter.dev, "Failed reset at end " - "of transaction (%02x)\n", temp); - } - } dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), @@ -188,41 +173,29 @@ static int vt596_transaction(void) return result; } -/* Return -1 on error. */ +/* Return -1 on error, 0 on success */ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { - int i, len; + int i; switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_info(&vt596_adapter.dev, - "I2C_SMBUS_PROC_CALL not supported!\n"); - return -1; case I2C_SMBUS_QUICK: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), - SMBHSTADD); size = VT596_QUICK; break; case I2C_SMBUS_BYTE: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), - SMBHSTADD); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD); size = VT596_BYTE; break; case I2C_SMBUS_BYTE_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), - SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) outb_p(data->byte, SMBHSTDAT0); size = VT596_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), - SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMBHSTDAT0); @@ -232,31 +205,30 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, break; case I2C_SMBUS_I2C_BLOCK_DATA: if (!(vt596_features & FEATURE_I2CBLOCK)) - return -1; + goto exit_unsupported; if (read_write == I2C_SMBUS_READ) outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0); /* Fall through */ case I2C_SMBUS_BLOCK_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), - SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { - len = data->block[0]; - if (len < 0) - len = 0; + u8 len = data->block[0]; if (len > I2C_SMBUS_BLOCK_MAX) len = I2C_SMBUS_BLOCK_MAX; outb_p(len, SMBHSTDAT0); - i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= len; i++) outb_p(data->block[i], SMBBLKDAT); } size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ? VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA; break; + default: + goto exit_unsupported; } - outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); + outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD); + outb_p((size & 0x3C), SMBHSTCNT); if (vt596_transaction()) /* Error in transaction */ return -1; @@ -266,12 +238,6 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, switch (size) { case VT596_BYTE: - /* Where is the result put? I assume here it is in - * SMBHSTDAT0 but it might just as well be in the - * SMBHSTCMD. No clue in the docs - */ - data->byte = inb_p(SMBHSTDAT0); - break; case VT596_BYTE_DATA: data->byte = inb_p(SMBHSTDAT0); break; @@ -283,12 +249,17 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, data->block[0] = inb_p(SMBHSTDAT0); if (data->block[0] > I2C_SMBUS_BLOCK_MAX) data->block[0] = I2C_SMBUS_BLOCK_MAX; - i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= data->block[0]; i++) data->block[i] = inb_p(SMBBLKDAT); break; } return 0; + +exit_unsupported: + dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n", + size); + return -1; } static u32 vt596_func(struct i2c_adapter *adapter) @@ -311,7 +282,6 @@ static struct i2c_adapter vt596_adapter = { .owner = THIS_MODULE, .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, - .name = "unset", }; static int __devinit vt596_probe(struct pci_dev *pdev, @@ -328,12 +298,12 @@ static int __devinit vt596_probe(struct pci_dev *pdev, } if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) || - !(vt596_smba & 0x1)) { + !(vt596_smba & 0x0001)) { /* try 2nd address and config reg. for 596 */ if (id->device == PCI_DEVICE_ID_VIA_82C596_3 && !pci_read_config_word(pdev, SMBBA2, &vt596_smba) && - (vt596_smba & 0x1)) { - smb_cf_hstcfg = 0x84; + (vt596_smba & 0x0001)) { + SMBHSTCFG = 0x84; } else { /* no matches at all */ dev_err(&pdev->dev, "Cannot configure " @@ -351,7 +321,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, } found: - if (!request_region(vt596_smba, 8, "viapro-smbus")) { + if (!request_region(vt596_smba, 8, vt596_driver.name)) { dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", vt596_smba); return -ENODEV; @@ -366,7 +336,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01); dev_warn(&pdev->dev, "WARNING: SMBus interface set to new " "address 0x%04x!\n", vt596_smba); - } else if ((temp & 1) == 0) { + } else if (!(temp & 0x01)) { if (force) { /* NOTE: This assumes I/O space and other allocations * WERE done by the Bios! Don't complain if your @@ -374,7 +344,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, * :') Check for Bios updates before resorting to * this. */ - pci_write_config_byte(pdev, SMBHSTCFG, temp | 1); + pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01); dev_info(&pdev->dev, "Enabling SMBus device\n"); } else { dev_err(&pdev->dev, "SMBUS: Error: Host SMBus " @@ -384,16 +354,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev, } } - if ((temp & 0x0E) == 8) - dev_dbg(&pdev->dev, "using Interrupt 9 for SMBus.\n"); - else if ((temp & 0x0E) == 0) - dev_dbg(&pdev->dev, "using Interrupt SMI# for SMBus.\n"); - else - dev_dbg(&pdev->dev, "Illegal Interrupt configuration " - "(or code out of date)!\n"); - - pci_read_config_byte(pdev, SMBREV, &temp); - dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp); dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba); switch (pdev->device) { From aaf7f1477668f34dda65aba17e87c0bc2ebe84d1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 22:09:07 +0200 Subject: [PATCH 0716/1940] [PATCH] i2c-viapro: Update supported devices list Make it clearer which chips are supported by the i2c-viapro driver, and which support I2C block transactions. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Documentation/i2c/busses/i2c-viapro | 12 ++++++------ drivers/i2c/busses/i2c-viapro.c | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) --- Documentation/i2c/busses/i2c-viapro | 12 ++++++------ drivers/i2c/busses/i2c-viapro.c | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 387cbd4015fc..9363b8bd6109 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro @@ -29,18 +29,18 @@ Description ----------- i2c-viapro is a true SMBus host driver for motherboards with one of the -supported VIA southbridges. +supported VIA south bridges. Your lspci -n listing must show one of these : - device 1106:3050 (VT82C596 function 3) - device 1106:3051 (VT82C596 function 3) + device 1106:3050 (VT82C596A function 3) + device 1106:3051 (VT82C596B function 3) device 1106:3057 (VT82C686 function 4) device 1106:3074 (VT8233) device 1106:3147 (VT8233A) - device 1106:8235 (VT8231) - devide 1106:3177 (VT8235) - devide 1106:3227 (VT8237) + device 1106:8235 (VT8231 function 4) + device 1106:3177 (VT8235) + device 1106:3227 (VT8237R) If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 5cf8fe182806..3be476cd4bc5 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -22,15 +22,19 @@ */ /* - Supports Via devices: - 82C596A/B (0x3050) - 82C596B (0x3051) - 82C686A/B - 8231 - 8233 - 8233A (0x3147 and 0x3177) - 8235 - 8237 + Supports the following VIA south bridges: + + Chip name PCI ID REV I2C block + VT82C596A 0x3050 no + VT82C596B 0x3051 no + VT82C686A 0x3057 0x30 no + VT82C686B 0x3057 0x40 yes + VT8231 0x8235 no? + VT8233 0x3074 yes + VT8233A 0x3147 yes? + VT8235 0x3177 yes + VT8237R 0x3227 yes + Note: we assume there can only be one device, with one SMBus interface. */ From 50c1cc339ca72f7cb95d440d384346f4238dc494 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 22:15:53 +0200 Subject: [PATCH 0717/1940] [PATCH] i2c-viapro: Refactor control outb By slightly shifting the interface between vt596_access and vt596_transaction, we can save two I/O accesses per SMBus transaction. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-viapro.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) --- drivers/i2c/busses/i2c-viapro.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 3be476cd4bc5..a89a21264d37 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -105,7 +105,7 @@ static struct i2c_adapter vt596_adapter; static unsigned int vt596_features; /* Return -1 on error, 0 on success */ -static int vt596_transaction(void) +static int vt596_transaction(u8 size) { int temp; int result = 0; @@ -131,7 +131,7 @@ static int vt596_transaction(void) } /* Start the transaction by setting bit 6 */ - outb_p(inb(SMBHSTCNT) | 0x40, SMBHSTCNT); + outb_p(0x40 | (size & 0x3C), SMBHSTCNT); /* We will always wait for a fraction of a second */ do { @@ -232,9 +232,8 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, } outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD); - outb_p((size & 0x3C), SMBHSTCNT); - if (vt596_transaction()) /* Error in transaction */ + if (vt596_transaction(size)) /* Error in transaction */ return -1; if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) From ed5453e54f0c4a29605fd8399f58649d8739f5f0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 22 Sep 2005 22:23:32 +0200 Subject: [PATCH 0718/1940] [PATCH] i2c-viapro: Improve register dump Improve the register dump used to debug the i2c-viapro driver. The original dump was missing the HSTSTS register and the block data buffer. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-viapro.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) --- drivers/i2c/busses/i2c-viapro.c | 38 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index a89a21264d37..c1c9eb1d714f 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -104,6 +104,30 @@ static struct i2c_adapter vt596_adapter; #define FEATURE_I2CBLOCK (1<<0) static unsigned int vt596_features; +#ifdef DEBUG +static void vt596_dump_regs(const char *msg, u8 size) +{ + dev_dbg(&vt596_adapter.dev, "%s: STS=%02x CNT=%02x CMD=%02x ADD=%02x " + "DAT=%02x,%02x\n", msg, inb_p(SMBHSTSTS), inb_p(SMBHSTCNT), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), + inb_p(SMBHSTDAT1)); + + if (size == VT596_BLOCK_DATA + || size == VT596_I2C_BLOCK_DATA) { + int i; + + dev_dbg(&vt596_adapter.dev, "BLK="); + for (i = 0; i < I2C_SMBUS_BLOCK_MAX / 2; i++) + printk("%02x,", inb_p(SMBBLKDAT)); + printk("\n"); + dev_dbg(&vt596_adapter.dev, " "); + for (; i < I2C_SMBUS_BLOCK_MAX - 1; i++) + printk("%02x,", inb_p(SMBBLKDAT)); + printk("%02x\n", inb_p(SMBBLKDAT)); + } +} +#endif + /* Return -1 on error, 0 on success */ static int vt596_transaction(u8 size) { @@ -111,10 +135,9 @@ static int vt596_transaction(u8 size) int result = 0; int timeout = 0; - dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), - inb_p(SMBHSTDAT1)); +#ifdef DEBUG + vt596_dump_regs("Transaction (pre)", size); +#endif /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { @@ -169,10 +192,9 @@ static int vt596_transaction(u8 size) if (temp & 0x1F) outb_p(temp, SMBHSTSTS); - dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), - inb_p(SMBHSTDAT1)); +#ifdef DEBUG + vt596_dump_regs("Transaction (post)", size); +#endif return result; } From ca68f1193e8fc86470d4222d563d13b5584dc4f8 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 22 Sep 2005 22:23:32 +0200 Subject: [PATCH 0719/1940] [PATCH] i2c-viapro: Cleanup ifdef usage It's not nice to put #ifdef in the middle of functions. CC: Jean Delvare Signed-off-by: Greg Kroah-Hartman drivers/i2c/busses/i2c-viapro.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) --- drivers/i2c/busses/i2c-viapro.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index c1c9eb1d714f..566342d50c5f 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -126,6 +126,8 @@ static void vt596_dump_regs(const char *msg, u8 size) printk("%02x\n", inb_p(SMBBLKDAT)); } } +#else +static inline void vt596_dump_regs(const char *msg, u8 size) { } #endif /* Return -1 on error, 0 on success */ @@ -135,9 +137,7 @@ static int vt596_transaction(u8 size) int result = 0; int timeout = 0; -#ifdef DEBUG vt596_dump_regs("Transaction (pre)", size); -#endif /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { @@ -192,9 +192,7 @@ static int vt596_transaction(u8 size) if (temp & 0x1F) outb_p(temp, SMBHSTSTS); -#ifdef DEBUG vt596_dump_regs("Transaction (post)", size); -#endif return result; } From 8a1b028bca95b5af36e94a660c4d284fe3313f74 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 7 Oct 2005 23:04:48 +0200 Subject: [PATCH 0720/1940] [PATCH] i2c: Add missing i2c-ixp2000/4xx adapter name The ixp4xx and ixp2000 i2c bus drivers omit to fill the required i2c_adapter name field. Copy the device driver name field there. Signed-off-by: Jean Delvare Signed-off-by: Deepak Saxena Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-ixp2000.c | 4 ++++ drivers/i2c/busses/i2c-ixp4xx.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 1956af382cd8..9dee505ceed2 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -36,6 +36,8 @@ #include /* Pick up IXP2000-specific bits */ #include +static struct device_driver ixp2000_i2c_driver; + static inline int ixp2000_scl_pin(void *data) { return ((struct ixp2000_i2c_pins*)data)->scl_pin; @@ -121,6 +123,8 @@ static int ixp2000_i2c_probe(struct device *dev) drv_data->algo_data.timeout = 100; drv_data->adapter.id = I2C_HW_B_IXP2000, + strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name, + I2C_NAME_SIZE); drv_data->adapter.algo_data = &drv_data->algo_data, drv_data->adapter.dev.parent = &plat_dev->dev; diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index f6f5ca31fdba..013981df38af 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -35,6 +35,8 @@ #include /* Pick up IXP4xx-specific bits */ +static struct device_driver ixp4xx_i2c_driver; + static inline int ixp4xx_scl_pin(void *data) { return ((struct ixp4xx_i2c_pins*)data)->scl_pin; @@ -129,6 +131,8 @@ static int ixp4xx_i2c_probe(struct device *dev) drv_data->algo_data.timeout = 100; drv_data->adapter.id = I2C_HW_B_IXP4XX; + strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.name, + I2C_NAME_SIZE); drv_data->adapter.algo_data = &drv_data->algo_data; drv_data->adapter.dev.parent = &plat_dev->dev; From e8aafcb2bba1fe122907161701a167e38174c7a5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 7 Oct 2005 23:06:27 +0200 Subject: [PATCH 0721/1940] [PATCH] i2c: Cleanup i2c-dev ioctl debug message Cleanup the ioctl debug message in i2c-dev. In particular, the minor number is redundant now that the minor number and the adapter number are kept in sync. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index aa7a4fadef64..89f54a5e8484 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -177,8 +177,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, int i,datasize,res; unsigned long funcs; - dev_dbg(&client->adapter->dev, "i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", - iminor(inode),cmd, arg); + dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", + cmd, arg); switch ( cmd ) { case I2C_SLAVE: From bf813b314a2271c3f3903eb3279ebf5e09b3d27a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 7 Oct 2005 23:09:04 +0200 Subject: [PATCH 0722/1940] [PATCH] i2c: Drop useless CVS revision IDs CVS revision IDs are totally useless and irrelevant by now. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c-algo-bit.h | 2 -- include/linux/i2c-algo-pcf.h | 2 -- include/linux/i2c-dev.h | 2 -- include/linux/i2c.h | 2 -- 4 files changed, 8 deletions(-) diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h index 110904481238..fb592147caec 100644 --- a/include/linux/i2c-algo-bit.h +++ b/include/linux/i2c-algo-bit.h @@ -21,8 +21,6 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* $Id: i2c-algo-bit.h,v 1.10 2003/01/21 08:08:16 kmalkki Exp $ */ - #ifndef _LINUX_I2C_ALGO_BIT_H #define _LINUX_I2C_ALGO_BIT_H diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 2a508562255f..a0e534b334a9 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -22,8 +22,6 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* $Id: i2c-algo-pcf.h,v 1.8 2003/01/21 08:08:16 kmalkki Exp $ */ - #ifndef _LINUX_I2C_ALGO_PCF_H #define _LINUX_I2C_ALGO_PCF_H diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h index 541695679762..81c229a0fbca 100644 --- a/include/linux/i2c-dev.h +++ b/include/linux/i2c-dev.h @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: i2c-dev.h,v 1.13 2003/01/21 08:08:16 kmalkki Exp $ */ - #ifndef _LINUX_I2C_DEV_H #define _LINUX_I2C_DEV_H diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 17d63c1efdce..ec8188414506 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -23,8 +23,6 @@ /* With some changes from Kyösti Mälkki and Frodo Looijaard */ -/* $Id: i2c.h,v 1.68 2003/01/21 08:08:16 kmalkki Exp $ */ - #ifndef _LINUX_I2C_H #define _LINUX_I2C_H From ada0c2f8fa087dc1dbc34e096c318739b1d6381a Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Fri, 7 Oct 2005 23:11:03 +0200 Subject: [PATCH 0723/1940] [PATCH] hwmon: Fix w83627ehf/hf vs PNPACPI conflict (bug #4014) This patch changes w83627hf and w83627ehf drivers to reserve only ports 0x295-0x296, instead of full 0x290-0x297 range. While some other sensors chips respond to all addresses in 0x290-0x297 range, Winbond chips respond to 0x295-0x296 only (this behavior is implied by documentation, and matches behavior observed on real systems). This is not problem alone, as no BIOS was found to put something at these unused addresses, and sensors chip itself provides nothing there as well. But in addition to only respond to these two addresses, also BIOS vendors report in their ACPI-PnP structures that there is some resource at I/O address 0x295 of length 2. And when later this hwmon driver attempts to request region with base 0x290/length 8, it fails as one request_region cannot span more than one device. Due to this we have to ask only for region this hardware really occupies, otherwise driver cannot be loaded on systems with ACPI-PnP enabled. Signed-off-by: Petr Vandrovec Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/w83627ehf.c | 13 ++++++++----- drivers/hwmon/w83627hf.c | 21 +++++++++++++-------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index b60efe8f8b26..685eeb766809 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -105,7 +105,9 @@ superio_exit(void) * ISA constants */ -#define REGION_LENGTH 8 +#define REGION_ALIGNMENT ~7 +#define REGION_OFFSET 5 +#define REGION_LENGTH 2 #define ADDR_REG_OFFSET 5 #define DATA_REG_OFFSET 6 @@ -673,7 +675,8 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) struct w83627ehf_data *data; int i, err = 0; - if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) { + if (!request_region(address + REGION_OFFSET, REGION_LENGTH, + w83627ehf_driver.name)) { err = -EBUSY; goto exit; } @@ -762,7 +765,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) exit_free: kfree(data); exit_release: - release_region(address, REGION_LENGTH); + release_region(address + REGION_OFFSET, REGION_LENGTH); exit: return err; } @@ -776,7 +779,7 @@ static int w83627ehf_detach_client(struct i2c_client *client) if ((err = i2c_detach_client(client))) return err; - release_region(client->addr, REGION_LENGTH); + release_region(client->addr + REGION_OFFSET, REGION_LENGTH); kfree(data); return 0; @@ -807,7 +810,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr) superio_select(W83627EHF_LD_HWM); val = (superio_inb(SIO_REG_ADDR) << 8) | superio_inb(SIO_REG_ADDR + 1); - *addr = val & ~(REGION_LENGTH - 1); + *addr = val & REGION_ALIGNMENT; if (*addr == 0) { superio_exit(); return -ENODEV; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 7f6f7280878d..494274d27f01 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -142,10 +142,14 @@ superio_exit(void) #define WINB_BASE_REG 0x60 /* Constants specified below */ -/* Length of ISA address segment */ -#define WINB_EXTENT 8 +/* Alignment of the base address */ +#define WINB_ALIGNMENT ~7 -/* Where are the ISA address/data registers relative to the base address */ +/* Offset & size of I/O region we are interested in */ +#define WINB_REGION_OFFSET 5 +#define WINB_REGION_SIZE 2 + +/* Where are the sensors address/data registers relative to the base address */ #define W83781D_ADDR_REG_OFFSET 5 #define W83781D_DATA_REG_OFFSET 6 @@ -981,7 +985,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr) superio_select(W83627HF_LD_HWM); val = (superio_inb(WINB_BASE_REG) << 8) | superio_inb(WINB_BASE_REG + 1); - *addr = val & ~(WINB_EXTENT - 1); + *addr = val & WINB_ALIGNMENT; if (*addr == 0 && force_addr == 0) { superio_exit(); return -ENODEV; @@ -1000,9 +1004,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter) const char *client_name = ""; if(force_addr) - address = force_addr & ~(WINB_EXTENT - 1); + address = force_addr & WINB_ALIGNMENT; - if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) { + if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, + w83627hf_driver.name)) { err = -EBUSY; goto ERROR0; } @@ -1148,7 +1153,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) ERROR2: kfree(data); ERROR1: - release_region(address, WINB_EXTENT); + release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE); ERROR0: return err; } @@ -1163,7 +1168,7 @@ static int w83627hf_detach_client(struct i2c_client *client) if ((err = i2c_detach_client(client))) return err; - release_region(client->addr, WINB_EXTENT); + release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE); kfree(data); return 0; From 47b8b103f7f50d56568eb8d6cff0e3a2373f0eb3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 7 Oct 2005 23:56:46 +0200 Subject: [PATCH 0724/1940] [PATCH] i2c: Cleanup i2c-i801 ifdefs No more need to check for PEC support being available now that both the i2c-core and the i2c-i801 drivers are part of the Linux kernel source tree. It's just there. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 588583530c9f..413930cafc49 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -52,10 +52,6 @@ #include #include -#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC -#define HAVE_PEC -#endif - /* I801 SMBus address offsets */ #define SMBHSTSTS (0 + i801_smba) #define SMBHSTCNT (2 + i801_smba) @@ -392,7 +388,6 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, goto END; } -#ifdef HAVE_PEC if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { /* wait for INTR bit as advised by Intel */ timeout = 0; @@ -407,7 +402,6 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, } outb_p(temp, SMBHSTSTS); } -#endif result = 0; END: if (command == I2C_SMBUS_I2C_BLOCK_DATA) { @@ -426,10 +420,8 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, int block = 0; int ret, xact = 0; -#ifdef HAVE_PEC if(isich4) hwpec = (flags & I2C_CLIENT_PEC) != 0; -#endif switch (size) { case I2C_SMBUS_QUICK: @@ -464,11 +456,9 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA: -#ifdef HAVE_PEC case I2C_SMBUS_BLOCK_DATA_PEC: if(hwpec && size == I2C_SMBUS_BLOCK_DATA) size = I2C_SMBUS_BLOCK_DATA_PEC; -#endif outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); @@ -480,13 +470,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, return -1; } -#ifdef HAVE_PEC if(isich4 && hwpec) { if(size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA) outb_p(1, SMBAUXCTL); /* enable HW PEC */ } -#endif if(block) ret = i801_block_transaction(data, read_write, size); else { @@ -494,13 +482,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, ret = i801_transaction(); } -#ifdef HAVE_PEC if(isich4 && hwpec) { if(size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA) outb_p(0, SMBAUXCTL); } -#endif if(block) return ret; @@ -527,12 +513,8 @@ static u32 i801_func(struct i2c_adapter *adapter) return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK -#ifdef HAVE_PEC | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC | - I2C_FUNC_SMBUS_HWPEC_CALC - : 0) -#endif - ; + I2C_FUNC_SMBUS_HWPEC_CALC : 0); } static struct i2c_algorithm smbus_algorithm = { From 7865e24935ec7e76fb482c749015a23052e51f76 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:00:31 +0200 Subject: [PATCH 0725/1940] [PATCH] i2c: Documentation fixes i2c documentation fixes. >From Hideki Iwamoto: * i2c_smbus_read_i2c_block_data is not deleted in 2.6.10. It still exists. * The name which can be set to i2c_driver is up to 31 characters. >From Jean Delvare: * Reword the paragraph about i2c_driver.name, to reflect the "new" naming policy. * Delete the out-of-date note about now gone inc_use and dec_use fields. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/i2c/writing-clients | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 077275722a7c..1882811c7f5d 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -33,8 +33,8 @@ static struct i2c_driver foo_driver = { .command = &foo_command /* may be NULL */ } -The name can be chosen freely, and may be upto 40 characters long. Please -use something descriptive here. +The name field must match the driver name, including the case. It must not +contain spaces, and may be up to 31 characters long. Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This means that your driver will be notified when new adapters are found. @@ -43,9 +43,6 @@ This is almost always what you want. All other fields are for call-back functions which will be explained below. -There use to be two additional fields in this structure, inc_use et dec_use, -for module usage count, but these fields were obsoleted and removed. - Extra client data ================= @@ -576,12 +573,12 @@ SMBus communication extern s32 i2c_smbus_write_block_data(struct i2c_client * client, u8 command, u8 length, u8 *values); + extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, + u8 command, u8 *values); These ones were removed in Linux 2.6.10 because they had no users, but could be added back later if needed: - extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, - u8 command, u8 *values); extern s32 i2c_smbus_read_block_data(struct i2c_client * client, u8 command, u8 *values); extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, From 31ec5bc57146a479fac6f6878146059180413e43 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:04:13 +0200 Subject: [PATCH 0726/1940] [PATCH] i2c: Fix misplaced i2c.h comment Fix a misplaced comment in i2c.h. Spotted by Hideki Iwamoto. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ec8188414506..6a1f3424f10f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -92,10 +92,10 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client, extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_write_word_data(struct i2c_client * client, u8 command, u16 value); -/* Returns the number of bytes transferred */ extern s32 i2c_smbus_write_block_data(struct i2c_client * client, u8 command, u8 length, u8 *values); +/* Returns the number of read bytes */ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, u8 command, u8 *values); From 80ce3b7d0f52877b80cddc3ace8b332d888f0131 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:06:09 +0200 Subject: [PATCH 0727/1940] [PATCH] i2c: Drop out-of-date, colliding ioctl definitions Delete 2 out-of-date, colliding ioctl defines. I2C_UDELAY and I2C_MDELAY are supposed to be used by i2c-algo-bit, but actually aren't (and I suspect never were). Moreover, their values are the same as I2C_FUNCS and I2C_SLAVE_FORCE, respectively, which *are* widely used. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 6a1f3424f10f..74103d0a8cd2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -503,11 +503,6 @@ union i2c_smbus_data { #define I2C_SMBUS 0x0720 /* SMBus-level access */ -/* ... algo-bit.c recognizes */ -#define I2C_UDELAY 0x0705 /* set delay in microsecs between each */ - /* written byte (except address) */ -#define I2C_MDELAY 0x0706 /* millisec delay between written bytes */ - /* ----- I2C-DEV: char device interface stuff ------------------------- */ #define I2C_MAJOR 89 /* Device major number */ From 91749996287c230671788014f422f72e594e7b86 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:10:00 +0200 Subject: [PATCH 0728/1940] [PATCH] hwmon: Drop legacy ISA address support from it87 Drop legacy ISA address support from the it87 driver. All supported chips are Super-I/O chips, so the device ISA address can be safely read from Super-I/O space rather than blindly assumed. Two nearby inaccurate documentation statements have been fixed as well: * The IT8705F doesn't have an SMBus interface. * The SiS950 doesn't have a distinct prefix. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/hwmon/it87 | 8 +++---- drivers/hwmon/it87.c | 51 +++++++++------------------------------- 2 files changed, 15 insertions(+), 44 deletions(-) diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 0d0195040d88..7f42e441c645 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -4,18 +4,18 @@ Kernel driver it87 Supported chips: * IT8705F Prefix: 'it87' - Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports) + Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website http://www.ite.com.tw/ * IT8712F Prefix: 'it8712' Addresses scanned: I2C 0x28 - 0x2f - from Super I/O config space, or default ISA 0x290 (8 I/O ports) + from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website http://www.ite.com.tw/ * SiS950 [clone of IT8705F] - Prefix: 'sis950' - Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports) + Prefix: 'it87' + Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: No longer be available Author: Christophe Gauthron diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 53cc2b6d6385..55e1c835a046 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2,7 +2,7 @@ it87.c - Part of lm_sensors, Linux kernel modules for hardware monitoring. - Supports: IT8705F Super I/O chip w/LPC interface & SMBus + Supports: IT8705F Super I/O chip w/LPC interface IT8712F Super I/O chip w/LPC interface & SMBus Sis950 A clone of the IT8705F @@ -47,7 +47,7 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; -static unsigned short isa_address = 0x290; +static unsigned short isa_address; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(it87, it8712); @@ -706,7 +706,7 @@ static int it87_isa_attach_adapter(struct i2c_adapter *adapter) } /* SuperIO detection - will change isa_address if a chip is found */ -static int __init it87_find(int *address) +static int __init it87_find(unsigned short *address) { int err = -ENODEV; @@ -757,34 +757,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) if (!request_region(address, IT87_EXTENT, it87_isa_driver.name)) goto ERROR0; - /* Probe whether there is anything available on this address. Already - done for SMBus and Super-I/O clients */ - if (kind < 0) { - if (is_isa && !chip_type) { -#define REALLY_SLOW_IO - /* We need the timeouts for at least some IT87-like chips. But only - if we read 'undefined' registers. */ - i = inb_p(address + 1); - if (inb_p(address + 2) != i - || inb_p(address + 3) != i - || inb_p(address + 7) != i) { - err = -ENODEV; - goto ERROR1; - } -#undef REALLY_SLOW_IO - - /* Let's just hope nothing breaks here */ - i = inb_p(address + 5) & 0x7f; - outb_p(~i & 0x7f, address + 5); - if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { - outb_p(i, address + 5); - err = -ENODEV; - goto ERROR1; - } - } - } - - /* OK. For now, we presume we have a valid client. We now create the + /* For now, we presume we have a valid client. We create the client structure, even though we cannot fill it completely yet. But it allows us to access it87_{read,write}_value. */ @@ -1182,20 +1155,18 @@ static struct it87_data *it87_update_device(struct device *dev) static int __init sm_it87_init(void) { - int addr, res; - - if (!it87_find(&addr)) { - isa_address = addr; - } + int res; res = i2c_add_driver(&it87_driver); if (res) return res; - res = i2c_isa_add_driver(&it87_isa_driver); - if (res) { - i2c_del_driver(&it87_driver); - return res; + if (!it87_find(&isa_address)) { + res = i2c_isa_add_driver(&it87_isa_driver); + if (res) { + i2c_del_driver(&it87_driver); + return res; + } } return 0; From 862bc36f682b25dd97833f702b4f8c97661b8811 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:12:01 +0200 Subject: [PATCH 0729/1940] [PATCH] hwmon: Drop useless w83627hf initialization step Drop a useless initialization step in the w83627hf driver. The comment says that the W83627HF PWM2 can be disabled, but it can't. I suppose this is a leftover from the w83781d driver (from which the w83627hf driver is derived), as for example the W83782D had the ability to disable PWM2. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/w83627hf.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 494274d27f01..48270819ff99 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -201,7 +201,6 @@ superio_exit(void) #define W83627HF_REG_PWM1 0x5A #define W83627HF_REG_PWM2 0x5B -#define W83627HF_REG_PWMCLK12 0x5C #define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */ #define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ @@ -1373,12 +1372,6 @@ static void w83627hf_init_client(struct i2c_client *client) } } - if (type == w83627hf) { - /* enable PWM2 control (can't hurt since PWM reg - should have been reset to 0xff) */ - w83627hf_write_value(client, W83627HF_REG_PWMCLK12, - 0x19); - } /* enable comparator mode for temp2 and temp3 so alarm indication will work correctly */ i = w83627hf_read_value(client, W83781D_REG_IRQ); From d3554b4a2fb0e2229eb0d3fa9ece5b2f0b906d3e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:14:17 +0200 Subject: [PATCH 0730/1940] [PATCH] i2c: Drop unused per-i2c-algorithm adapter max There are no more per-i2c-algorithm adapter max. Last time there were was in July 1999. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c-algo-bit.h | 2 -- include/linux/i2c-algo-pca.h | 2 -- include/linux/i2c-algo-pcf.h | 2 -- 3 files changed, 6 deletions(-) diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h index fb592147caec..c0e7fab28ce3 100644 --- a/include/linux/i2c-algo-bit.h +++ b/include/linux/i2c-algo-bit.h @@ -44,8 +44,6 @@ struct i2c_algo_bit_data { int timeout; /* in jiffies */ }; -#define I2C_BIT_ADAP_MAX 16 - int i2c_bit_add_bus(struct i2c_adapter *); int i2c_bit_del_bus(struct i2c_adapter *); diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h index 941b786c5732..226693e0d88b 100644 --- a/include/linux/i2c-algo-pca.h +++ b/include/linux/i2c-algo-pca.h @@ -9,8 +9,6 @@ struct i2c_algo_pca_data { int (*wait_for_interrupt) (struct i2c_algo_pca_data *adap); }; -#define I2C_PCA_ADAP_MAX 16 - int i2c_pca_add_bus(struct i2c_adapter *); int i2c_pca_del_bus(struct i2c_adapter *); diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index a0e534b334a9..18b0adf57a3d 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -39,8 +39,6 @@ struct i2c_algo_pcf_data { int timeout; }; -#define I2C_PCF_ADAP_MAX 16 - int i2c_pcf_add_bus(struct i2c_adapter *); int i2c_pcf_del_bus(struct i2c_adapter *); From 30dac7469741906436b50f9413dccd446366d371 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:15:59 +0200 Subject: [PATCH 0731/1940] [PATCH] i2c: Drop I2C_SMBUS_I2C_BLOCK_MAX Drop I2C_SMBUS_I2C_BLOCK_MAX, use I2C_SMBUS_BLOCK_MAX instead. I2C_SMBUS_I2C_BLOCK_MAX has always been defined to the same value as I2C_SMBUS_BLOCK_MAX, and this will never change: setting it to a lower value would make no sense, setting it to a higher value would break i2c_smbus_data compatibility. There is no point in changing i2c_smbus_data to support larger block transactions in SMBus mode, as no SMBus hardware supports more than 32 byte blocks. Thus, for larger transactions, direct I2C transfers are the way to go. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/eeprom.c | 4 ++-- drivers/i2c/i2c-core.c | 8 ++++---- include/linux/i2c.h | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index d58403a47908..7fb739c43935 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -88,8 +88,8 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_I2C_BLOCK_MAX) - if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_I2C_BLOCK_MAX) + for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_BLOCK_MAX) + if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_BLOCK_MAX) goto exit; } else { if (i2c_smbus_write_byte(client, slice << 5)) { diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 9583a54ce16b..15354176ff63 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1108,10 +1108,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, return -1; case I2C_SMBUS_I2C_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) { - msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX; + msg[1].len = I2C_SMBUS_BLOCK_MAX; } else { msg[0].len = data->block[0] + 1; - if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) { + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " "invalid block write size (%d)\n", data->block[0]); @@ -1144,8 +1144,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, break; case I2C_SMBUS_I2C_BLOCK_DATA: /* fixed at 32 for now */ - data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX; - for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++) + data->block[0] = I2C_SMBUS_BLOCK_MAX; + for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++) data->block[i+1] = msgbuf1[i]; break; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 74103d0a8cd2..64c13c042f9d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -448,7 +448,6 @@ struct i2c_msg { * Data for SMBus Messages */ #define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ -#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ union i2c_smbus_data { __u8 byte; __u16 word; From 6c129be8c7bd1bdbd47ba8e17f6e5053ef04aee8 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:17:35 +0200 Subject: [PATCH 0732/1940] [PATCH] i2c: Rename i2c-parport variable to avoid confusion It's a bit confusing to name a variable the same as an unrelated structure. The compiler doesn't complain, but it certainly makes the code harder to understand, and could confuse grep and LXR among others. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-parport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 71a2502fe069..fa506187fbe1 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -232,7 +232,7 @@ static void i2c_parport_detach (struct parport *port) } } -static struct parport_driver i2c_driver = { +static struct parport_driver i2c_parport_driver = { .name = "i2c-parport", .attach = i2c_parport_attach, .detach = i2c_parport_detach, @@ -250,12 +250,12 @@ static int __init i2c_parport_init(void) type = 0; } - return parport_register_driver(&i2c_driver); + return parport_register_driver(&i2c_parport_driver); } static void __exit i2c_parport_exit(void) { - parport_unregister_driver(&i2c_driver); + parport_unregister_driver(&i2c_parport_driver); } MODULE_AUTHOR("Jean Delvare "); From 00bffb6e29c5ef12cea7904905f8b959187076c9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 8 Oct 2005 00:19:52 +0200 Subject: [PATCH 0733/1940] [PATCH] i2c: Drop meaningless use of I2C_DF_NOTIFY in i2c_client structures I2C_DF_NOTIFY is an i2c_driver flag, using it as an i2c_client flag doesn't make any sense. Signed-off-by: Jean Delvare Acked-by: Mark A. Greer Acked-by: Randy Vinson Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/ds1374.c | 1 - drivers/i2c/chips/m41t00.c | 1 - drivers/i2c/chips/rtc8564.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 0936327a946d..ec640e9f085a 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c @@ -199,7 +199,6 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) memset(client, 0, sizeof(struct i2c_client)); strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE); - client->flags = I2C_DF_NOTIFY; client->addr = addr; client->adapter = adap; client->driver = &ds1374_driver; diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 3f14528a52a9..554f7ba61627 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c @@ -180,7 +180,6 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) memset(client, 0, sizeof(struct i2c_client)); strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); - client->flags = I2C_DF_NOTIFY; client->addr = addr; client->adapter = adap; client->driver = &m41t00_driver; diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index 0b5385c892b1..dd9d42d7b6e7 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c @@ -158,7 +158,7 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind) strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); i2c_set_clientdata(new_client, d); - new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY; + new_client->flags = I2C_CLIENT_ALLOW_USE; new_client->addr = addr; new_client->adapter = adap; new_client->driver = &rtc8564_driver; From 3634ff6a32e90d9db0ec19297e80059143c1aa7f Mon Sep 17 00:00:00 2001 From: Stig Telfer Date: Sat, 8 Oct 2005 00:21:48 +0200 Subject: [PATCH 0734/1940] [PATCH] i2c: Fix i2c-elektor on Alpha This patch updates the i2c-elektor driver, enabling it to compile cleanly, load and run. The key change is that it uses the new __iomem/iowrite8/ioread8 functions to abstract the direct or memory-mapped variants of register access. Also, the original driver would crash on module load on the Alpha because the PCI memory region was not remapped into kernel memory. I have managed the following testing: * compiled and tested it on my Alpha UP2000+ system. * compiles cleanly for x86 but I don't have the hardware to test. Signed-off-by: Stig Telfer Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-elektor.c | 74 +++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index 6930b660e508..75b4b442a636 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -46,6 +46,8 @@ #define DEFAULT_BASE 0x330 static int base; +static u8 __iomem *base_iomem; + static int irq; static int clock = 0x1c; static int own = 0x55; @@ -64,36 +66,27 @@ static spinlock_t lock; static void pcf_isa_setbyte(void *data, int ctl, int val) { - int address = ctl ? (base + 1) : base; + u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem; /* enable irq if any specified for serial operation */ if (ctl && irq && (val & I2C_PCF_ESO)) { val |= I2C_PCF_ENI; } - pr_debug("i2c-elektor: Write 0x%X 0x%02X\n", address, val & 255); - - switch (mmapped) { - case 0: /* regular I/O */ - outb(val, address); - break; - case 2: /* double mapped I/O needed for UP2000 board, - I don't know why this... */ - writeb(val, (void *)address); - /* fall */ - case 1: /* memory mapped I/O */ - writeb(val, (void *)address); - break; - } + pr_debug("i2c-elektor: Write %p 0x%02X\n", address, val); + iowrite8(val, address); +#ifdef __alpha__ + /* API UP2000 needs some hardware fudging to make the write stick */ + iowrite8(val, address); +#endif } static int pcf_isa_getbyte(void *data, int ctl) { - int address = ctl ? (base + 1) : base; - int val = mmapped ? readb((void *)address) : inb(address); - - pr_debug("i2c-elektor: Read 0x%X 0x%02X\n", address, val); + u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem; + int val = ioread8(address); + pr_debug("i2c-elektor: Read %p 0x%02X\n", address, val); return (val); } @@ -155,7 +148,30 @@ static int pcf_isa_init(void) "is in use.\n", base); return -ENODEV; } + base_iomem = ioport_map(base, 2); + if (!base_iomem) { + printk(KERN_ERR "i2c-elektor: remap of I/O region " + "%#x failed\n", base); + release_region(base, 2); + return -ENODEV; + } + } else { + if (!request_mem_region(base, 2, "i2c-elektor")) { + printk(KERN_ERR "i2c-elektor: requested memory region " + "(%#x:2) is in use\n", base); + return -ENODEV; + } + base_iomem = ioremap(base, 2); + if (base_iomem == NULL) { + printk(KERN_ERR "i2c-elektor: remap of memory region " + "%#x failed\n", base); + release_mem_region(base, 2); + return -ENODEV; + } } + pr_debug("i2c-elektor: registers %#x remapped to %p\n", base, + base_iomem); + if (irq > 0) { if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", NULL) < 0) { printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq); @@ -200,7 +216,7 @@ static int __init i2c_pcfisa_init(void) cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, NULL); if (cy693_dev) { - char config; + unsigned char config; /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { @@ -219,9 +235,7 @@ static int __init i2c_pcfisa_init(void) if ((config & 0x7f) == 0x61) { /* seems to be UP2000 like board */ base = 0xe0000; - /* I don't know why we need to - write twice */ - mmapped = 2; + mmapped = 1; /* UP2000 drives ISA with 8.25 MHz (PCI/4) clock (this can be read from cypress) */ @@ -262,8 +276,13 @@ static int __init i2c_pcfisa_init(void) free_irq(irq, NULL); } - if (!mmapped) + if (!mmapped) { + ioport_unmap(base_iomem); release_region(base , 2); + } else { + iounmap(base_iomem); + release_mem_region(base, 2); + } return -ENODEV; } @@ -276,8 +295,13 @@ static void i2c_pcfisa_exit(void) free_irq(irq, NULL); } - if (!mmapped) + if (!mmapped) { + ioport_unmap(base_iomem); release_region(base , 2); + } else { + iounmap(base_iomem); + release_mem_region(base, 2); + } } MODULE_AUTHOR("Hans Berglund "); From fe3d6a99782d5345b1927e872d77d1778668094b Mon Sep 17 00:00:00 2001 From: Stig Telfer Date: Sat, 8 Oct 2005 00:23:27 +0200 Subject: [PATCH 0735/1940] [PATCH] i2c: Big i2c-elektor cleanup Cleanups to the i2c-elektor driver: * Set the i2c_adapter name field to "i2c-elektor" and use this string in all resource requests and printks. * Change space-padding for tab indentation, kill trailing white space, remove space before comma. * Use dev_info, pr_info and pr_debug instead of printk. * Lines chopped to 80 columns. Signed-off-by: Stig Telfer Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-elektor.c | 84 +++++++++++++++++--------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index 75b4b442a636..59f8308c2356 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -22,7 +22,7 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of +/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of for Alpha Processor Inc. UP-2000(+) boards */ #include @@ -53,7 +53,7 @@ static int clock = 0x1c; static int own = 0x55; static int mmapped; -/* vdovikin: removed static struct i2c_pcf_isa gpi; code - +/* vdovikin: removed static struct i2c_pcf_isa gpi; code - this module in real supports only one device, due to missing arguments in some functions, called from the algo-pcf module. Sometimes it's need to be rewriten - but for now just remove this for simpler reading */ @@ -62,6 +62,8 @@ static wait_queue_head_t pcf_wait; static int pcf_pending; static spinlock_t lock; +static struct i2c_adapter pcf_isa_ops; + /* ----- local functions ---------------------------------------------- */ static void pcf_isa_setbyte(void *data, int ctl, int val) @@ -73,7 +75,7 @@ static void pcf_isa_setbyte(void *data, int ctl, int val) val |= I2C_PCF_ENI; } - pr_debug("i2c-elektor: Write %p 0x%02X\n", address, val); + pr_debug("%s: Write %p 0x%02X\n", pcf_isa_ops.name, address, val); iowrite8(val, address); #ifdef __alpha__ /* API UP2000 needs some hardware fudging to make the write stick */ @@ -86,7 +88,7 @@ static int pcf_isa_getbyte(void *data, int ctl) u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem; int val = ioread8(address); - pr_debug("i2c-elektor: Read %p 0x%02X\n", address, val); + pr_debug("%s: Read %p 0x%02X\n", pcf_isa_ops.name, address, val); return (val); } @@ -142,39 +144,40 @@ static int pcf_isa_init(void) { spin_lock_init(&lock); if (!mmapped) { - if (!request_region(base, 2, "i2c (isa bus adapter)")) { - printk(KERN_ERR - "i2c-elektor: requested I/O region (0x%X:2) " - "is in use.\n", base); + if (!request_region(base, 2, pcf_isa_ops.name)) { + printk(KERN_ERR "%s: requested I/O region (%#x:2) is " + "in use\n", pcf_isa_ops.name, base); return -ENODEV; } base_iomem = ioport_map(base, 2); if (!base_iomem) { - printk(KERN_ERR "i2c-elektor: remap of I/O region " - "%#x failed\n", base); + printk(KERN_ERR "%s: remap of I/O region %#x failed\n", + pcf_isa_ops.name, base); release_region(base, 2); return -ENODEV; } } else { - if (!request_mem_region(base, 2, "i2c-elektor")) { - printk(KERN_ERR "i2c-elektor: requested memory region " - "(%#x:2) is in use\n", base); + if (!request_mem_region(base, 2, pcf_isa_ops.name)) { + printk(KERN_ERR "%s: requested memory region (%#x:2) " + "is in use\n", pcf_isa_ops.name, base); return -ENODEV; } base_iomem = ioremap(base, 2); if (base_iomem == NULL) { - printk(KERN_ERR "i2c-elektor: remap of memory region " - "%#x failed\n", base); + printk(KERN_ERR "%s: remap of memory region %#x " + "failed\n", pcf_isa_ops.name, base); release_mem_region(base, 2); return -ENODEV; } } - pr_debug("i2c-elektor: registers %#x remapped to %p\n", base, + pr_debug("%s: registers %#x remapped to %p\n", pcf_isa_ops.name, base, base_iomem); if (irq > 0) { - if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", NULL) < 0) { - printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq); + if (request_irq(irq, pcf_isa_handler, 0, pcf_isa_ops.name, + NULL) < 0) { + printk(KERN_ERR "%s: Request irq%d failed\n", + pcf_isa_ops.name, irq); irq = 0; } else enable_irq(irq); @@ -202,45 +205,49 @@ static struct i2c_adapter pcf_isa_ops = { .class = I2C_CLASS_HWMON, .id = I2C_HW_P_ELEK, .algo_data = &pcf_isa_data, - .name = "PCF8584 ISA adapter", + .name = "i2c-elektor", }; -static int __init i2c_pcfisa_init(void) +static int __init i2c_pcfisa_init(void) { #ifdef __alpha__ - /* check to see we have memory mapped PCF8584 connected to the + /* check to see we have memory mapped PCF8584 connected to the Cypress cy82c693 PCI-ISA bridge as on UP2000 board */ if (base == 0) { struct pci_dev *cy693_dev; - - cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ, + + cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, NULL); if (cy693_dev) { unsigned char config; /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { - - pr_debug("i2c-elektor: found cy82c693, config register 0x47 = 0x%02x.\n", config); + + pr_debug("%s: found cy82c693, config " + "register 0x47 = 0x%02x\n", + pcf_isa_ops.name, config); /* UP2000 board has this register set to 0xe1, - but the most significant bit as seems can be + but the most significant bit as seems can be reset during the proper initialisation - sequence if guys from API decides to do that - (so, we can even enable Tsunami Pchip - window for the upper 1 Gb) */ + sequence if guys from API decides to do that + (so, we can even enable Tsunami Pchip + window for the upper 1 Gb) */ /* so just check for ROMCS at 0xe0000, - ROMCS enabled for writes + ROMCS enabled for writes and external XD Bus buffer in use. */ if ((config & 0x7f) == 0x61) { /* seems to be UP2000 like board */ base = 0xe0000; mmapped = 1; - /* UP2000 drives ISA with + /* UP2000 drives ISA with 8.25 MHz (PCI/4) clock (this can be read from cypress) */ clock = I2C_PCF_CLK | I2C_PCF_TRNS90; - printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n"); + pr_info("%s: found API UP2000 like " + "board, will probe PCF8584 " + "later\n", pcf_isa_ops.name); } } pci_dev_put(cy693_dev); @@ -250,12 +257,11 @@ static int __init i2c_pcfisa_init(void) /* sanity checks for mmapped I/O */ if (mmapped && base < 0xc8000) { - printk(KERN_ERR "i2c-elektor: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); + printk(KERN_ERR "%s: incorrect base address (%#x) specified " + "for mmapped I/O\n", pcf_isa_ops.name, base); return -ENODEV; } - printk(KERN_INFO "i2c-elektor: i2c pcf8584-isa adapter driver\n"); - if (base == 0) { base = DEFAULT_BASE; } @@ -265,8 +271,8 @@ static int __init i2c_pcfisa_init(void) return -ENODEV; if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) goto fail; - - printk(KERN_ERR "i2c-elektor: found device at %#x.\n", base); + + dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base); return 0; @@ -278,7 +284,7 @@ static int __init i2c_pcfisa_init(void) if (!mmapped) { ioport_unmap(base_iomem); - release_region(base , 2); + release_region(base, 2); } else { iounmap(base_iomem); release_mem_region(base, 2); @@ -297,7 +303,7 @@ static void i2c_pcfisa_exit(void) if (!mmapped) { ioport_unmap(base_iomem); - release_region(base , 2); + release_region(base, 2); } else { iounmap(base_iomem); release_mem_region(base, 2); From ccd7aa0cc9413b79b69f6cd7c18daa1c22dfa512 Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Mon, 17 Oct 2005 22:47:48 +0200 Subject: [PATCH 0736/1940] [PATCH] Owner field additions to many i2c drivers, 1 of 5 This patch updates .owner field for various struct pci_driver variables. Signed-off-by: Laurent Riffard Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-ali1535.c | 1 + drivers/i2c/busses/i2c-ali1563.c | 1 + drivers/i2c/busses/i2c-ali15x3.c | 1 + drivers/i2c/busses/i2c-amd756.c | 1 + drivers/i2c/busses/i2c-amd8111.c | 1 + drivers/i2c/busses/i2c-hydra.c | 1 + drivers/i2c/busses/i2c-i801.c | 1 + drivers/i2c/busses/i2c-i810.c | 1 + drivers/i2c/busses/i2c-nforce2.c | 1 + drivers/i2c/busses/i2c-piix4.c | 1 + drivers/i2c/busses/i2c-prosavage.c | 1 + drivers/i2c/busses/i2c-savage4.c | 1 + drivers/i2c/busses/i2c-sis5595.c | 1 + drivers/i2c/busses/i2c-sis630.c | 1 + drivers/i2c/busses/i2c-sis96x.c | 1 + drivers/i2c/busses/i2c-via.c | 1 + drivers/i2c/busses/i2c-viapro.c | 1 + drivers/i2c/busses/i2c-voodoo3.c | 1 + 18 files changed, 18 insertions(+) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 3eb47890db40..ba90f5140af6 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -513,6 +513,7 @@ static void __devexit ali1535_remove(struct pci_dev *dev) } static struct pci_driver ali1535_driver = { + .owner = THIS_MODULE, .name = "ali1535_smbus", .id_table = ali1535_ids, .probe = ali1535_probe, diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index e6f63208fc4a..f1a62d892425 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -408,6 +408,7 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = { MODULE_DEVICE_TABLE (pci, ali1563_id_table); static struct pci_driver ali1563_pci_driver = { + .owner = THIS_MODULE, .name = "ali1563_smbus", .id_table = ali1563_id_table, .probe = ali1563_probe, diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 7a5c0941dbc1..400b08ed4299 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -504,6 +504,7 @@ static void __devexit ali15x3_remove(struct pci_dev *dev) } static struct pci_driver ali15x3_driver = { + .owner = THIS_MODULE, .name = "ali15x3_smbus", .id_table = ali15x3_ids, .probe = ali15x3_probe, diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 1750dedaf4b5..de035d137c3f 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -401,6 +401,7 @@ static void __devexit amd756_remove(struct pci_dev *dev) } static struct pci_driver amd756_driver = { + .owner = THIS_MODULE, .name = "amd756_smbus", .id_table = amd756_ids, .probe = amd756_probe, diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 6200c9a087ad..0d29e78dff63 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -392,6 +392,7 @@ static void __devexit amd8111_remove(struct pci_dev *dev) } static struct pci_driver amd8111_driver = { + .owner = THIS_MODULE, .name = "amd8111_smbus2", .id_table = amd8111_ids, .probe = amd8111_probe, diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c index e0cb3b0f92fa..1b5354e24bf5 100644 --- a/drivers/i2c/busses/i2c-hydra.c +++ b/drivers/i2c/busses/i2c-hydra.c @@ -155,6 +155,7 @@ static void __devexit hydra_remove(struct pci_dev *dev) static struct pci_driver hydra_driver = { + .owner = THIS_MODULE, .name = "hydra_smbus", .id_table = hydra_ids, .probe = hydra_probe, diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 413930cafc49..e90b6c4e7da3 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -568,6 +568,7 @@ static void __devexit i801_remove(struct pci_dev *dev) } static struct pci_driver i801_driver = { + .owner = THIS_MODULE, .name = "i801_smbus", .id_table = i801_ids, .probe = i801_probe, diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c index 0ff7016e0629..1b3393b7c461 100644 --- a/drivers/i2c/busses/i2c-i810.c +++ b/drivers/i2c/busses/i2c-i810.c @@ -232,6 +232,7 @@ static void __devexit i810_remove(struct pci_dev *dev) } static struct pci_driver i810_driver = { + .owner = THIS_MODULE, .name = "i810_smbus", .id_table = i810_ids, .probe = i810_probe, diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index dd4b6d8e03ef..5dc62114cc8d 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -356,6 +356,7 @@ static void __devexit nforce2_remove(struct pci_dev *dev) } static struct pci_driver nforce2_driver = { + .owner = THIS_MODULE, .name = "nForce2_smbus", .id_table = nforce2_ids, .probe = nforce2_probe, diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 692f47345481..7d63eec423fe 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -462,6 +462,7 @@ static void __devexit piix4_remove(struct pci_dev *dev) } static struct pci_driver piix4_driver = { + .owner = THIS_MODULE, .name = "piix4_smbus", .id_table = piix4_ids, .probe = piix4_probe, diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c index 83fd16d61ce5..92b744273577 100644 --- a/drivers/i2c/busses/i2c-prosavage.c +++ b/drivers/i2c/busses/i2c-prosavage.c @@ -308,6 +308,7 @@ static struct pci_device_id prosavage_pci_tbl[] = { MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl); static struct pci_driver prosavage_driver = { + .owner = THIS_MODULE, .name = "prosavage_smbus", .id_table = prosavage_pci_tbl, .probe = prosavage_probe, diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c index 0c8518298e4d..aebe87ba4033 100644 --- a/drivers/i2c/busses/i2c-savage4.c +++ b/drivers/i2c/busses/i2c-savage4.c @@ -179,6 +179,7 @@ static void __devexit savage4_remove(struct pci_dev *dev) } static struct pci_driver savage4_driver = { + .owner = THIS_MODULE, .name = "savage4_smbus", .id_table = savage4_ids, .probe = savage4_probe, diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index b57ab74d23ec..3ad27c3ba15b 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -398,6 +398,7 @@ static void __devexit sis5595_remove(struct pci_dev *dev) } static struct pci_driver sis5595_driver = { + .owner = THIS_MODULE, .name = "sis5595_smbus", .id_table = sis5595_ids, .probe = sis5595_probe, diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index acb75e282414..7f49e5fd3ff0 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -496,6 +496,7 @@ static void __devexit sis630_remove(struct pci_dev *dev) static struct pci_driver sis630_driver = { + .owner = THIS_MODULE, .name = "sis630_smbus", .id_table = sis630_ids, .probe = sis630_probe, diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 3024907cdafe..6a134c091324 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -329,6 +329,7 @@ static void __devexit sis96x_remove(struct pci_dev *dev) } static struct pci_driver sis96x_driver = { + .owner = THIS_MODULE, .name = "sis96x_smbus", .id_table = sis96x_ids, .probe = sis96x_probe, diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 484bbacfce6b..544a38e64394 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -159,6 +159,7 @@ static void __devexit vt586b_remove(struct pci_dev *dev) static struct pci_driver vt586b_driver = { + .owner = THIS_MODULE, .name = "vt586b_smbus", .id_table = vt586b_ids, .probe = vt586b_probe, diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 566342d50c5f..c9366b504833 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -439,6 +439,7 @@ static struct pci_device_id vt596_ids[] = { MODULE_DEVICE_TABLE(pci, vt596_ids); static struct pci_driver vt596_driver = { + .owner = THIS_MODULE, .name = "vt596_smbus", .id_table = vt596_ids, .probe = vt596_probe, diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c index b675773b0cc1..650c3ebde84c 100644 --- a/drivers/i2c/busses/i2c-voodoo3.c +++ b/drivers/i2c/busses/i2c-voodoo3.c @@ -225,6 +225,7 @@ static void __devexit voodoo3_remove(struct pci_dev *dev) } static struct pci_driver voodoo3_driver = { + .owner = THIS_MODULE, .name = "voodoo3_smbus", .id_table = voodoo3_ids, .probe = voodoo3_probe, From 0cf3628181660be4e21fe520766dcbc3da9d71c8 Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Mon, 17 Oct 2005 22:51:37 +0200 Subject: [PATCH 0737/1940] [PATCH] Owner field additions to many i2c drivers, 2 of 5 This patch updates the .owner field for various struct xxxx_driver variables, other than pci_driver. Signed-off-by: Laurent Riffard Signed-off-by: Jean Delvare Acked-by: Mark A. Greer Acked-by: Ben Dooks Acked-by: Deepak Saxena Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-iop3xx.c | 1 + drivers/i2c/busses/i2c-ixp2000.c | 1 + drivers/i2c/busses/i2c-ixp4xx.c | 1 + drivers/i2c/busses/i2c-mpc.c | 1 + drivers/i2c/busses/i2c-mv64xxx.c | 1 + drivers/i2c/busses/i2c-s3c2410.c | 2 ++ drivers/i2c/chips/isp1301_omap.c | 1 + 7 files changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 745e3a51f3e5..0f7dfd8f4546 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -525,6 +525,7 @@ iop3xx_i2c_probe(struct device *dev) static struct device_driver iop3xx_i2c_driver = { + .owner = THIS_MODULE, .name = "IOP3xx-I2C", .bus = &platform_bus_type, .probe = iop3xx_i2c_probe, diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 9dee505ceed2..c3292dc743f1 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -146,6 +146,7 @@ static int ixp2000_i2c_probe(struct device *dev) } static struct device_driver ixp2000_i2c_driver = { + .owner = THIS_MODULE, .name = "IXP2000-I2C", .bus = &platform_bus_type, .probe = ixp2000_i2c_probe, diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 013981df38af..3169280c25a6 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -155,6 +155,7 @@ static int ixp4xx_i2c_probe(struct device *dev) } static struct device_driver ixp4xx_i2c_driver = { + .owner = THIS_MODULE, .name = "IXP4XX-I2C", .bus = &platform_bus_type, .probe = ixp4xx_i2c_probe, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f065583ddcf1..b81c54620030 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -361,6 +361,7 @@ static int fsl_i2c_remove(struct device *device) /* Structure for a device driver */ static struct device_driver fsl_i2c_driver = { + .owner = THIS_MODULE, .name = "fsl-i2c", .bus = &platform_bus_type, .probe = fsl_i2c_probe, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 99abca45fece..69709ee0b896 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -570,6 +570,7 @@ mv64xxx_i2c_remove(struct device *dev) } static struct device_driver mv64xxx_i2c_driver = { + .owner = THIS_MODULE, .name = MV64XXX_I2C_CTLR_NAME, .bus = &platform_bus_type, .probe = mv64xxx_i2c_probe, diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 69fa282df2d5..6ced28e90070 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -896,6 +896,7 @@ static int s3c24xx_i2c_resume(struct device *dev) /* device driver for platform bus bits */ static struct device_driver s3c2410_i2c_driver = { + .owner = THIS_MODULE, .name = "s3c2410-i2c", .bus = &platform_bus_type, .probe = s3c24xx_i2c_probe, @@ -904,6 +905,7 @@ static struct device_driver s3c2410_i2c_driver = { }; static struct device_driver s3c2440_i2c_driver = { + .owner = THIS_MODULE, .name = "s3c2440-i2c", .bus = &platform_bus_type, .probe = s3c24xx_i2c_probe, diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 8ee56d4b3891..eaa4742e04fa 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -888,6 +888,7 @@ static int otg_remove(struct device *dev) } struct device_driver omap_otg_driver = { + .owner = THIS_MODULE, .name = "omap_otg", .bus = &platform_bus_type, .probe = otg_probe, From e78f857cc5299c3f6b3d046084696ef205948837 Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Mon, 17 Oct 2005 22:53:52 +0200 Subject: [PATCH 0738/1940] [PATCH] Owner field additions to many i2c drivers, 3 of 5 This patch updates the .owner field for various struct xxxx_driver variables which are available on PPC_MAC arch. This one was _not_ even compile-tested... Signed-off-by: Laurent Riffard Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-keywest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index eff5896ce865..34e43c8d8d5e 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -716,6 +716,7 @@ static struct of_device_id i2c_keywest_match[] = static struct macio_driver i2c_keywest_macio_driver = { + .owner = THIS_MODULE, .name = "i2c-keywest", .match_table = i2c_keywest_match, .probe = create_iface_macio, @@ -724,6 +725,7 @@ static struct macio_driver i2c_keywest_macio_driver = static struct of_platform_driver i2c_keywest_of_platform_driver = { + .owner = THIS_MODULE, .name = "i2c-keywest", .match_table = i2c_keywest_match, .probe = create_iface_of_platform, From 6586bcd7b2bbe255110b2db772da4415c7865a2a Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Mon, 17 Oct 2005 22:54:45 +0200 Subject: [PATCH 0739/1940] [PATCH] Owner field additions to many i2c drivers, 4 of 5 This patch updates the .owner field for the i2c core struct xxxx_driver variables. Signed-off-by: Laurent Riffard Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 15354176ff63..0040981b6698 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -85,6 +85,7 @@ void i2c_adapter_dev_release(struct device *dev) } struct device_driver i2c_adapter_driver = { + .owner = THIS_MODULE, .name = "i2c_adapter", .bus = &i2c_bus_type, .probe = i2c_device_probe, @@ -98,6 +99,7 @@ static void i2c_adapter_class_dev_release(struct class_device *dev) } struct class i2c_adapter_class = { + .owner = THIS_MODULE, .name = "i2c-adapter", .release = &i2c_adapter_class_dev_release, }; @@ -291,6 +293,7 @@ int i2c_add_driver(struct i2c_driver *driver) down(&core_lists); /* add the driver to the list of i2c drivers in the driver core */ + driver->driver.owner = driver->owner; driver->driver.name = driver->name; driver->driver.bus = &i2c_bus_type; driver->driver.probe = i2c_device_probe; From 1747ef1b8c9b7b9c6a9aae3543a9b99acabb7e10 Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Mon, 17 Oct 2005 22:58:35 +0200 Subject: [PATCH 0740/1940] [PATCH] Owner field additions to many i2c drivers, 5 of 5 In function i2c_isa_add_driver, copied driver should inherit the owner field as well as the name field. Signed-off-by: Laurent Riffard Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-isa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index bdc6806dafae..4fdc02411609 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -92,6 +92,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver) /* Add the driver to the list of i2c drivers in the driver core */ driver->driver.name = driver->name; + driver->driver.owner = driver->owner; driver->driver.bus = &i2c_bus_type; driver->driver.probe = i2c_isa_device_probe; driver->driver.remove = i2c_isa_device_remove; From 7ab83a9137ccd3e092fb6ad0cb105b4d1fb617ae Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Mon, 17 Oct 2005 23:01:45 +0200 Subject: [PATCH 0741/1940] [PATCH] hwmon: New device ID for the smsc47b397 driver This patch adds a new ID to the SMSC LPC47B397-NC hardware monitoring driver - for a chip that is claimed to be 100% compatible otherwise. Signed-off-by: Bryan Young (Utilitek Systems, Inc.) Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/hwmon/smsc47b397 | 8 ++++++-- drivers/hwmon/smsc47b397.c | 7 ++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Documentation/hwmon/smsc47b397 b/Documentation/hwmon/smsc47b397 index da9d80c96432..20682f15ae41 100644 --- a/Documentation/hwmon/smsc47b397 +++ b/Documentation/hwmon/smsc47b397 @@ -3,6 +3,7 @@ Kernel driver smsc47b397 Supported chips: * SMSC LPC47B397-NC + * SMSC SCH5307-NS Prefix: 'smsc47b397' Addresses scanned: none, address read from Super I/O config space Datasheet: In this file @@ -12,11 +13,14 @@ Authors: Mark M. Hoffman November 23, 2004 -The following specification describes the SMSC LPC47B397-NC sensor chip +The following specification describes the SMSC LPC47B397-NC[1] sensor chip (for which there is no public datasheet available). This document was provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected by Mark M. Hoffman . +[1] And SMSC SCH5307-NS, which has a different device ID but is otherwise +compatible. + * * * * * Methods for detecting the HP SIO and reading the thermal data on a dc7100. @@ -127,7 +131,7 @@ OUT DX,AL The registers of interest for identifying the SIO on the dc7100 are Device ID (0x20) and Device Rev (0x21). -The Device ID will read 0X6F +The Device ID will read 0x6F (for SCH5307-NS, 0x81) The Device Rev currently reads 0x01 Obtaining the HWM Base Address. diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 7fe71576dea4..37ed8b33f01a 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -299,7 +299,7 @@ static int __init smsc47b397_find(unsigned short *addr) superio_enter(); id = superio_inb(SUPERIO_REG_DEVID); - if (id != 0x6f) { + if ((id != 0x6f) && (id != 0x81)) { superio_exit(); return -ENODEV; } @@ -310,8 +310,9 @@ static int __init smsc47b397_find(unsigned short *addr) *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); - printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC " - "(base address 0x%04x, revision %u)\n", *addr, rev); + printk(KERN_INFO "smsc47b397: found SMSC %s " + "(base address 0x%04x, revision %u)\n", + id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); superio_exit(); return 0; From ddec748f328af6b67e4d0ce0248a8e9f36751827 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 17 Oct 2005 23:02:42 +0200 Subject: [PATCH 0742/1940] [PATCH] hwmon: Missing class check in two hwmon drivers The atxp1 and ds1621 drivers should make sure they do not probe non-hwmon i2c adapters. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/atxp1.c | 2 ++ drivers/hwmon/ds1621.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index deb4d34c9539..441324fc6b8b 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -253,6 +253,8 @@ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2); static int atxp1_attach_adapter(struct i2c_adapter *adapter) { + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; return i2c_probe(adapter, &addr_data, &atxp1_detect); }; diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index b0199e063d0e..e1ff22cf984a 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -180,6 +180,8 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); static int ds1621_attach_adapter(struct i2c_adapter *adapter) { + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; return i2c_probe(adapter, &addr_data, ds1621_detect); } From 4d4e5ce8648561b964699afb2df5e7268a84599b Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Mon, 17 Oct 2005 23:04:42 +0200 Subject: [PATCH 0743/1940] [PATCH] i2c: New Xicor X1205 RTC driver New driver for the Xicor X1205 RTC chip. Signed-off-by: Alessandro Zummo Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/i2c/chips/x1205 | 38 ++ drivers/i2c/chips/Kconfig | 9 + drivers/i2c/chips/Makefile | 1 + drivers/i2c/chips/x1205.c | 698 ++++++++++++++++++++++++++++++++++ include/linux/x1205.h | 31 ++ 5 files changed, 777 insertions(+) create mode 100644 Documentation/i2c/chips/x1205 create mode 100644 drivers/i2c/chips/x1205.c create mode 100644 include/linux/x1205.h diff --git a/Documentation/i2c/chips/x1205 b/Documentation/i2c/chips/x1205 new file mode 100644 index 000000000000..09407c991fe5 --- /dev/null +++ b/Documentation/i2c/chips/x1205 @@ -0,0 +1,38 @@ +Kernel driver x1205 +=================== + +Supported chips: + * Xicor X1205 RTC + Prefix: 'x1205' + Addresses scanned: none + Datasheet: http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html + +Authors: + Karen Spearel , + Alessandro Zummo + +Description +----------- + +This module aims to provide complete access to the Xicor X1205 RTC. +Recently Xicor has merged with Intersil, but the chip is +still sold under the Xicor brand. + +This chip is located at address 0x6f and uses a 2-byte register addressing. +Two bytes need to be written to read a single register, while most +other chips just require one and take the second one as the data +to be written. To prevent corrupting unknown chips, the user must +explicitely set the probe parameter. + +example: + +modprobe x1205 probe=0,0x6f + +The module supports one more option, hctosys, which is used to set the +software clock from the x1205. On systems where the x1205 is the +only hardware rtc, this parameter could be used to achieve a correct +date/time earlier in the system boot sequence. + +example: + +modprobe x1205 probe=0,0x6f hctosys=1 diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 6bd44a44cd28..f9fae28f5612 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -126,4 +126,13 @@ config SENSORS_MAX6875 This driver can also be built as a module. If so, the module will be called max6875. +config RTC_X1205_I2C + tristate "Xicor X1205 RTC chip" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Xicor X1205 RTC chip. + + This driver can also be built as a module. If so, the module + will be called x1205. + endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index a876dd42b860..46178b57b1f1 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TPS65010) += tps65010.o +obj-$(CONFIG_RTC_X1205_I2C) += x1205.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c new file mode 100644 index 000000000000..7da366cdc18c --- /dev/null +++ b/drivers/i2c/chips/x1205.c @@ -0,0 +1,698 @@ +/* + * x1205.c - An i2c driver for the Xicor X1205 RTC + * Copyright 2004 Karen Spearel + * Copyright 2005 Alessandro Zummo + * + * please send all reports to: + * kas11 at tampabay dot rr dot com + * a dot zummo at towertech dot it + * + * based on the other drivers in this same directory. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_VERSION "0.9.9" + +/* Addresses to scan: none. This chip is located at + * 0x6f and uses a two bytes register addressing. + * Two bytes need to be written to read a single register, + * while most other chips just require one and take the second + * one as the data to be written. To prevent corrupting + * unknown chips, the user must explicitely set the probe parameter. + */ + +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD; +I2C_CLIENT_MODULE_PARM(hctosys, + "Set the system time from the hardware clock upon initialization"); + +/* offsets into CCR area */ + +#define CCR_SEC 0 +#define CCR_MIN 1 +#define CCR_HOUR 2 +#define CCR_MDAY 3 +#define CCR_MONTH 4 +#define CCR_YEAR 5 +#define CCR_WDAY 6 +#define CCR_Y2K 7 + +#define X1205_REG_SR 0x3F /* status register */ +#define X1205_REG_Y2K 0x37 +#define X1205_REG_DW 0x36 +#define X1205_REG_YR 0x35 +#define X1205_REG_MO 0x34 +#define X1205_REG_DT 0x33 +#define X1205_REG_HR 0x32 +#define X1205_REG_MN 0x31 +#define X1205_REG_SC 0x30 +#define X1205_REG_DTR 0x13 +#define X1205_REG_ATR 0x12 +#define X1205_REG_INT 0x11 +#define X1205_REG_0 0x10 +#define X1205_REG_Y2K1 0x0F +#define X1205_REG_DWA1 0x0E +#define X1205_REG_YRA1 0x0D +#define X1205_REG_MOA1 0x0C +#define X1205_REG_DTA1 0x0B +#define X1205_REG_HRA1 0x0A +#define X1205_REG_MNA1 0x09 +#define X1205_REG_SCA1 0x08 +#define X1205_REG_Y2K0 0x07 +#define X1205_REG_DWA0 0x06 +#define X1205_REG_YRA0 0x05 +#define X1205_REG_MOA0 0x04 +#define X1205_REG_DTA0 0x03 +#define X1205_REG_HRA0 0x02 +#define X1205_REG_MNA0 0x01 +#define X1205_REG_SCA0 0x00 + +#define X1205_CCR_BASE 0x30 /* Base address of CCR */ +#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */ + +#define X1205_SR_RTCF 0x01 /* Clock failure */ +#define X1205_SR_WEL 0x02 /* Write Enable Latch */ +#define X1205_SR_RWEL 0x04 /* Register Write Enable */ + +#define X1205_DTR_DTR0 0x01 +#define X1205_DTR_DTR1 0x02 +#define X1205_DTR_DTR2 0x04 + +#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ + +/* Prototypes */ +static int x1205_attach(struct i2c_adapter *adapter); +static int x1205_detach(struct i2c_client *client); +static int x1205_probe(struct i2c_adapter *adapter, int address, int kind); +static int x1205_command(struct i2c_client *client, unsigned int cmd, + void *arg); + +static struct i2c_driver x1205_driver = { + .owner = THIS_MODULE, + .name = "x1205", + .flags = I2C_DF_NOTIFY, + .attach_adapter = &x1205_attach, + .detach_client = &x1205_detach, +}; + +struct x1205_data { + struct i2c_client client; + struct list_head list; + unsigned int epoch; +}; + +static const unsigned char days_in_mo[] = + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +static LIST_HEAD(x1205_clients); + +/* Workaround until the I2C subsytem will allow to send + * commands to a specific client. This function will send the command + * to the first client. + */ +int x1205_do_command(unsigned int cmd, void *arg) +{ + struct list_head *walk; + struct list_head *tmp; + struct x1205_data *data; + + list_for_each_safe(walk, tmp, &x1205_clients) { + data = list_entry(walk, struct x1205_data, list); + return x1205_command(&data->client, cmd, arg); + } + + return -ENODEV; +} + +#define is_leap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +/* make sure the rtc_time values are in bounds */ +static int x1205_validate_tm(struct rtc_time *tm) +{ + int year = tm->tm_year + 1900; + + if ((tm->tm_year < 70) || (tm->tm_year > 255)) + return -EINVAL; + + if ((tm->tm_mon > 11) || (tm->tm_mday == 0)) + return -EINVAL; + + if (tm->tm_mday > days_in_mo[tm->tm_mon] + + ((tm->tm_mon == 1) && is_leap(year))) + return -EINVAL; + + if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60)) + return -EINVAL; + + return 0; +} + +/* + * In the routines that deal directly with the x1205 hardware, we use + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch + * Epoch is initialized as 2000. Time is set to UTC. + */ +static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, + u8 reg_base) +{ + unsigned char dt_addr[2] = { 0, reg_base }; + static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; + + unsigned char buf[8], sr; + + struct i2c_msg msgs[] = { + { client->addr, 0, 2, sr_addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 1, &sr }, /* read status */ + { client->addr, 0, 2, dt_addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 8, buf }, /* read date */ + }; + + struct x1205_data *data = i2c_get_clientdata(client); + + /* read status register */ + if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { + dev_err(&client->dev, "%s: read error\n", __FUNCTION__); + return -EIO; + } + + /* check for battery failure */ + if (sr & X1205_SR_RTCF) { + dev_warn(&client->dev, + "Clock had a power failure, you must set the date.\n"); + return -EINVAL; + } + + /* read date registers */ + if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) { + dev_err(&client->dev, "%s: read error\n", __FUNCTION__); + return -EIO; + } + + dev_dbg(&client->dev, + "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " + "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", + __FUNCTION__, + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + + tm->tm_sec = BCD2BIN(buf[CCR_SEC]); + tm->tm_min = BCD2BIN(buf[CCR_MIN]); + tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ + tm->tm_mday = BCD2BIN(buf[CCR_MDAY]); + tm->tm_mon = BCD2BIN(buf[CCR_MONTH]); + data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100; + tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900; + tm->tm_wday = buf[CCR_WDAY]; + + dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " + "mday=%d, mon=%d, year=%d, wday=%d\n", + __FUNCTION__, + tm->tm_sec, tm->tm_min, tm->tm_hour, + tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + + return 0; +} + +static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, + int datetoo, u8 reg_base) +{ + int i, err, xfer; + + unsigned char buf[8]; + + static const unsigned char wel[3] = { 0, X1205_REG_SR, + X1205_SR_WEL }; + + static const unsigned char rwel[3] = { 0, X1205_REG_SR, + X1205_SR_WEL | X1205_SR_RWEL }; + + static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 }; + + struct x1205_data *data = i2c_get_clientdata(client); + + /* check if all values in the tm struct are correct */ + if ((err = x1205_validate_tm(tm)) < 0) + return err; + + dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " + "mday=%d, mon=%d, year=%d, wday=%d\n", + __FUNCTION__, + tm->tm_sec, tm->tm_min, tm->tm_hour, + tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + + buf[CCR_SEC] = BIN2BCD(tm->tm_sec); + buf[CCR_MIN] = BIN2BCD(tm->tm_min); + + /* set hour and 24hr bit */ + buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL; + + /* should we also set the date? */ + if (datetoo) { + buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); + + /* month, 0 - 11 */ + buf[CCR_MONTH] = BIN2BCD(tm->tm_mon); + + /* year, since 1900 */ + buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch); + buf[CCR_WDAY] = tm->tm_wday & 0x07; + buf[CCR_Y2K] = BIN2BCD(data->epoch / 100); + } + + /* this sequence is required to unlock the chip */ + xfer = i2c_master_send(client, wel, 3); + if (xfer != 3) { + dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer); + return -EIO; + } + + xfer = i2c_master_send(client, rwel, 3); + if (xfer != 3) { + dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer); + return -EIO; + } + + /* write register's data */ + for (i = 0; i < (datetoo ? 8 : 3); i++) { + unsigned char rdata[3] = { 0, reg_base + i, buf[i] }; + + xfer = i2c_master_send(client, rdata, 3); + if (xfer != 3) { + dev_err(&client->dev, + "%s: xfer=%d addr=%02x, data=%02x\n", + __FUNCTION__, + xfer, rdata[1], rdata[2]); + return -EIO; + } + }; + + /* disable further writes */ + xfer = i2c_master_send(client, diswe, 3); + if (xfer != 3) { + dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer); + return -EIO; + } + + return 0; +} + +static int x1205_get_dtrim(struct i2c_client *client, int *trim) +{ + unsigned char dtr; + static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; + + struct i2c_msg msgs[] = { + { client->addr, 0, 2, dtr_addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */ + }; + + /* read dtr register */ + if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { + dev_err(&client->dev, "%s: read error\n", __FUNCTION__); + return -EIO; + } + + dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr); + + *trim = 0; + + if (dtr & X1205_DTR_DTR0) + *trim += 20; + + if (dtr & X1205_DTR_DTR1) + *trim += 10; + + if (dtr & X1205_DTR_DTR2) + *trim = -*trim; + + return 0; +} + +static int x1205_get_atrim(struct i2c_client *client, int *trim) +{ + s8 atr; + static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; + + struct i2c_msg msgs[] = { + { client->addr, 0, 2, atr_addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 1, &atr }, /* read atr */ + }; + + /* read atr register */ + if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { + dev_err(&client->dev, "%s: read error\n", __FUNCTION__); + return -EIO; + } + + dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr); + + /* atr is a two's complement value on 6 bits, + * perform sign extension. The formula is + * Catr = (atr * 0.25pF) + 11.00pF. + */ + if (atr & 0x20) + atr |= 0xC0; + + dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr); + + *trim = (atr * 250) + 11000; + + dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim); + + return 0; +} + +static int x1205_hctosys(struct i2c_client *client) +{ + int err; + + struct rtc_time tm; + struct timespec tv; + + err = x1205_command(client, X1205_CMD_GETDATETIME, &tm); + + if (err) { + dev_err(&client->dev, + "Unable to set the system clock\n"); + return err; + } + + /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary + * whether it stores the most close value or the value with partial + * seconds truncated. However, it is important that we use it to store + * the truncated value. This is because otherwise it is necessary, + * in an rtc sync function, to read both xtime.tv_sec and + * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read + * of >32bits is not possible. So storing the most close value would + * slow down the sync API. So here we have the truncated value and + * the best guess is to add 0.5s. + */ + + tv.tv_nsec = NSEC_PER_SEC >> 1; + + /* WARNING: this is not the C library 'mktime' call, it is a built in + * inline function from include/linux/time.h. It expects (requires) + * the month to be in the range 1-12 + */ + + tv.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, + tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec); + + do_settimeofday(&tv); + + dev_info(&client->dev, + "setting the system clock to %d-%d-%d %d:%d:%d\n", + tm.tm_year + 1900, tm.tm_mon + 1, + tm.tm_mday, tm.tm_hour, tm.tm_min, + tm.tm_sec); + + return 0; +} + +struct x1205_limit +{ + unsigned char reg; + unsigned char mask; + unsigned char min; + unsigned char max; +}; + +static int x1205_validate_client(struct i2c_client *client) +{ + int i, xfer; + + /* Probe array. We will read the register at the specified + * address and check if the given bits are zero. + */ + static const unsigned char probe_zero_pattern[] = { + /* register, mask */ + X1205_REG_SR, 0x18, + X1205_REG_DTR, 0xF8, + X1205_REG_ATR, 0xC0, + X1205_REG_INT, 0x18, + X1205_REG_0, 0xFF, + }; + + static const struct x1205_limit probe_limits_pattern[] = { + /* register, mask, min, max */ + { X1205_REG_Y2K, 0xFF, 19, 20 }, + { X1205_REG_DW, 0xFF, 0, 6 }, + { X1205_REG_YR, 0xFF, 0, 99 }, + { X1205_REG_MO, 0xFF, 0, 12 }, + { X1205_REG_DT, 0xFF, 0, 31 }, + { X1205_REG_HR, 0x7F, 0, 23 }, + { X1205_REG_MN, 0xFF, 0, 59 }, + { X1205_REG_SC, 0xFF, 0, 59 }, + { X1205_REG_Y2K1, 0xFF, 19, 20 }, + { X1205_REG_Y2K0, 0xFF, 19, 20 }, + }; + + /* check that registers have bits a 0 where expected */ + for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) { + unsigned char buf; + + unsigned char addr[2] = { 0, probe_zero_pattern[i] }; + + struct i2c_msg msgs[2] = { + { client->addr, 0, 2, addr }, + { client->addr, I2C_M_RD, 1, &buf }, + }; + + xfer = i2c_transfer(client->adapter, msgs, 2); + if (xfer != 2) { + dev_err(&client->adapter->dev, + "%s: could not read register %x\n", + __FUNCTION__, addr[1]); + + return -EIO; + } + + if ((buf & probe_zero_pattern[i+1]) != 0) { + dev_err(&client->adapter->dev, + "%s: register=%02x, zero pattern=%d, value=%x\n", + __FUNCTION__, addr[1], i, buf); + + return -ENODEV; + } + } + + /* check limits (only registers with bcd values) */ + for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) { + unsigned char reg, value; + + unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; + + struct i2c_msg msgs[2] = { + { client->addr, 0, 2, addr }, + { client->addr, I2C_M_RD, 1, ® }, + }; + + xfer = i2c_transfer(client->adapter, msgs, 2); + + if (xfer != 2) { + dev_err(&client->adapter->dev, + "%s: could not read register %x\n", + __FUNCTION__, addr[1]); + + return -EIO; + } + + value = BCD2BIN(reg & probe_limits_pattern[i].mask); + + if (value > probe_limits_pattern[i].max || + value < probe_limits_pattern[i].min) { + dev_dbg(&client->adapter->dev, + "%s: register=%x, lim pattern=%d, value=%d\n", + __FUNCTION__, addr[1], i, value); + + return -ENODEV; + } + } + + return 0; +} + +static int x1205_attach(struct i2c_adapter *adapter) +{ + dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); + + return i2c_probe(adapter, &addr_data, x1205_probe); +} + +int x1205_direct_attach(int adapter_id, + struct i2c_client_address_data *address_data) +{ + int err; + struct i2c_adapter *adapter = i2c_get_adapter(adapter_id); + + if (adapter) { + err = i2c_probe(adapter, + address_data, x1205_probe); + + i2c_put_adapter(adapter); + + return err; + } + + return -ENODEV; +} + +static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *client; + struct x1205_data *data; + + int err = 0; + + dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + err = -ENODEV; + goto exit; + } + + if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + /* Initialize our structures */ + data->epoch = 2000; + + client = &data->client; + client->addr = address; + client->driver = &x1205_driver; + client->adapter = adapter; + + strlcpy(client->name, "x1205", I2C_NAME_SIZE); + + i2c_set_clientdata(client, data); + + /* Verify the chip is really an X1205 */ + if (kind < 0) { + if (x1205_validate_client(client) < 0) { + err = -ENODEV; + goto exit_kfree; + } + } + + /* Inform the i2c layer */ + if ((err = i2c_attach_client(client))) + goto exit_kfree; + + list_add(&data->list, &x1205_clients); + + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + + /* If requested, set the system time */ + if (hctosys) + x1205_hctosys(client); + + return 0; + +exit_kfree: + kfree(data); + +exit: + return err; +} + +static int x1205_detach(struct i2c_client *client) +{ + int err; + struct x1205_data *data = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "%s\n", __FUNCTION__); + + if ((err = i2c_detach_client(client))) + return err; + + list_del(&data->list); + + kfree(data); + + return 0; +} + +static int x1205_command(struct i2c_client *client, unsigned int cmd, + void *param) +{ + if (param == NULL) + return -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd); + + switch (cmd) { + case X1205_CMD_GETDATETIME: + return x1205_get_datetime(client, param, X1205_CCR_BASE); + + case X1205_CMD_SETTIME: + return x1205_set_datetime(client, param, 0, + X1205_CCR_BASE); + + case X1205_CMD_SETDATETIME: + return x1205_set_datetime(client, param, 1, + X1205_CCR_BASE); + + case X1205_CMD_GETALARM: + return x1205_get_datetime(client, param, X1205_ALM0_BASE); + + case X1205_CMD_SETALARM: + return x1205_set_datetime(client, param, 1, + X1205_ALM0_BASE); + + case X1205_CMD_GETDTRIM: + return x1205_get_dtrim(client, param); + + case X1205_CMD_GETATRIM: + return x1205_get_atrim(client, param); + + default: + return -EINVAL; + } +} + +static int __init x1205_init(void) +{ + return i2c_add_driver(&x1205_driver); +} + +static void __exit x1205_exit(void) +{ + i2c_del_driver(&x1205_driver); +} + +MODULE_AUTHOR( + "Karen Spearel , " + "Alessandro Zummo "); +MODULE_DESCRIPTION("Xicor X1205 RTC driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +EXPORT_SYMBOL_GPL(x1205_do_command); +EXPORT_SYMBOL_GPL(x1205_direct_attach); + +module_init(x1205_init); +module_exit(x1205_exit); diff --git a/include/linux/x1205.h b/include/linux/x1205.h new file mode 100644 index 000000000000..64fd3af894a5 --- /dev/null +++ b/include/linux/x1205.h @@ -0,0 +1,31 @@ +/* + * x1205.h - defines for drivers/i2c/chips/x1205.c + * Copyright 2004 Karen Spearel + * Copyright 2005 Alessandro Zummo + * + * 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. + */ + +#ifndef __LINUX_X1205_H__ +#define __LINUX_X1205_H__ + +/* commands */ + +#define X1205_CMD_GETDATETIME 0 +#define X1205_CMD_SETTIME 1 +#define X1205_CMD_SETDATETIME 2 +#define X1205_CMD_GETALARM 3 +#define X1205_CMD_SETALARM 4 +#define X1205_CMD_GETDTRIM 5 +#define X1205_CMD_SETDTRIM 6 +#define X1205_CMD_GETATRIM 7 +#define X1205_CMD_SETATRIM 8 + +extern int x1205_do_command(unsigned int cmd, void *arg); +extern int x1205_direct_attach(int adapter_id, + struct i2c_client_address_data *address_data); + +#endif /* __LINUX_X1205_H__ */ From 2286066faf51890e49ad61e2ceab683666cd9108 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 17 Oct 2005 23:07:05 +0200 Subject: [PATCH 0744/1940] [PATCH] i2c: kzalloc conversion, ixp bus drivers Use kzalloc instead of kmalloc+memzero in the ixp2000 and ixp4xx I2C bus drivers. Signed-off-by: Deepak Saxena Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-ixp2000.c | 3 +-- drivers/i2c/busses/i2c-ixp4xx.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index c3292dc743f1..42016ee6ef13 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -106,11 +106,10 @@ static int ixp2000_i2c_probe(struct device *dev) struct platform_device *plat_dev = to_platform_device(dev); struct ixp2000_i2c_pins *gpio = plat_dev->dev.platform_data; struct ixp2000_i2c_data *drv_data = - kmalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL); + kzalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL); if (!drv_data) return -ENOMEM; - memzero(drv_data, sizeof(*drv_data)); drv_data->gpio_pins = gpio; drv_data->algo_data.data = gpio; diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 3169280c25a6..69303ab65e04 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -107,12 +107,11 @@ static int ixp4xx_i2c_probe(struct device *dev) struct platform_device *plat_dev = to_platform_device(dev); struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data; struct ixp4xx_i2c_data *drv_data = - kmalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL); + kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL); if(!drv_data) return -ENOMEM; - memzero(drv_data, sizeof(struct ixp4xx_i2c_data)); drv_data->gpio_pins = gpio; /* From ba9c2e8d15da029ea3051c95e446b2d638ef02e2 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 17 Oct 2005 23:08:32 +0200 Subject: [PATCH 0745/1940] [PATCH] hwmon: kzalloc conversion Use kzalloc instead of kmalloc+memset in all hardware monitoring drivers. Signed-off-by: Deepak Saxena Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adm1021.c | 3 +-- drivers/hwmon/adm1025.c | 3 +-- drivers/hwmon/adm1026.c | 4 +--- drivers/hwmon/adm1031.c | 3 +-- drivers/hwmon/asb100.c | 11 ++++------- drivers/hwmon/atxp1.c | 3 +-- drivers/hwmon/ds1621.c | 3 +-- drivers/hwmon/fscher.c | 3 +-- drivers/hwmon/fscpos.c | 3 +-- drivers/hwmon/gl518sm.c | 3 +-- drivers/hwmon/gl520sm.c | 3 +-- drivers/hwmon/it87.c | 3 +-- drivers/hwmon/lm63.c | 3 +-- drivers/hwmon/lm75.c | 3 +-- drivers/hwmon/lm77.c | 3 +-- drivers/hwmon/lm78.c | 3 +-- drivers/hwmon/lm80.c | 3 +-- drivers/hwmon/lm83.c | 3 +-- drivers/hwmon/lm85.c | 3 +-- drivers/hwmon/lm87.c | 3 +-- drivers/hwmon/lm90.c | 3 +-- drivers/hwmon/lm92.c | 3 +-- drivers/hwmon/max1619.c | 3 +-- drivers/hwmon/pc87360.c | 3 +-- drivers/hwmon/sis5595.c | 3 +-- drivers/hwmon/smsc47b397.c | 3 +-- drivers/hwmon/smsc47m1.c | 3 +-- drivers/hwmon/via686a.c | 3 +-- drivers/hwmon/w83627ehf.c | 3 +-- drivers/hwmon/w83627hf.c | 3 +-- drivers/hwmon/w83781d.c | 10 +++------- drivers/hwmon/w83792d.c | 6 ++---- drivers/hwmon/w83l785ts.c | 4 +--- 33 files changed, 39 insertions(+), 80 deletions(-) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 58aee3a00caa..8102876c7c3f 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -204,11 +204,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access adm1021_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { err = -ENOMEM; goto error0; } - memset(data, 0, sizeof(struct adm1021_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 526b7ff179eb..3ec12421694f 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -331,11 +331,10 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct adm1025_data)); /* The common I2C client data is placed right before the ADM1025-specific data. */ diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 625158110fd4..3b5814183738 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -1470,13 +1470,11 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, client structure, even though we cannot fill it completely yet. But it allows us to access adm1026_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct adm1026_data)); - new_client = &data->client; i2c_set_clientdata(new_client, data); new_client->addr = address; diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 58338ed7c8a1..7c545d5eee45 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -740,11 +740,10 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct adm1031_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 8e34855a6274..52c469722a65 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -629,19 +629,17 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, int i, id, err; struct asb100_data *data = i2c_get_clientdata(new_client); - data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!(data->lm75[0])) { err = -ENOMEM; goto ERROR_SC_0; } - memset(data->lm75[0], 0x00, sizeof(struct i2c_client)); - data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!(data->lm75[1])) { err = -ENOMEM; goto ERROR_SC_1; } - memset(data->lm75[1], 0x00, sizeof(struct i2c_client)); id = i2c_adapter_id(adapter); @@ -724,12 +722,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access asb100_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) { - pr_debug("asb100.o: detect failed, kmalloc failed!\n"); + if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) { + pr_debug("asb100.o: detect failed, kzalloc failed!\n"); err = -ENOMEM; goto ERROR0; } - memset(data, 0, sizeof(struct asb100_data)); new_client = &data->client; init_MUTEX(&data->lock); diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 441324fc6b8b..53324f56404e 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -268,12 +268,11 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct atxp1_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct atxp1_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index e1ff22cf984a..c5afa0058308 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -202,11 +202,10 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access ds1621_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct ds1621_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index eef6061d786b..a02e1c34c757 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c @@ -303,11 +303,10 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the * client structure, even though we cannot fill it completely yet. * But it allows us to access i2c_smbus_read_byte_data. */ - if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct fscher_data)); /* The common I2C client data is placed right before the * Hermes-specific data. */ diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 5fc77a5fed07..a378e4f5c93b 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -453,11 +453,10 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) * But it allows us to access fscpos_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct fscpos_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 256b9323c84b..2f178dbe3d87 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -365,11 +365,10 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access gl518_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct gl518_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 12fd757066fc..c39ba1239426 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -536,11 +536,10 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access gl520_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct gl520_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 55e1c835a046..9a5b8b268397 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -761,11 +761,10 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access it87_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } - memset(data, 0, sizeof(struct it87_data)); new_client = &data->client; if (is_isa) diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index be5c7095ecbb..954ec2497249 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -375,11 +375,10 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct lm63_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm63_data)); /* The common I2C client data is placed right before the LM63-specific data. */ diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 9a3ebdf583f4..d70f4c8fc1e6 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -127,11 +127,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access lm75_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm75_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 866eab96a6f6..9380fda7dcd1 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -226,11 +226,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access lm77_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct lm77_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm77_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index d697a554286f..924462362743 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -540,11 +540,10 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access lm78_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } - memset(data, 0, sizeof(struct lm78_data)); new_client = &data->client; if (is_isa) diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 83af8b3a0cac..b4cd6c661f11 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -407,11 +407,10 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access lm80_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm80_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index d74b2c20c719..9a70611a9f69 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -230,11 +230,10 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm83_data)); /* The common I2C client data is placed right after the * LM83-specific data. */ diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index ab214df9624b..d5537a5377f7 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1033,11 +1033,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address, client structure, even though we cannot fill it completely yet. But it allows us to access lm85_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } - memset(data, 0, sizeof(struct lm85_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index dca996de4c33..eeec18177861 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -554,11 +554,10 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm87_data)); /* The common I2C client data is placed right before the LM87-specific data. */ diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 14de05fcd431..dad0f1074956 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -370,11 +370,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm90_data)); /* The common I2C client data is placed right before the LM90-specific data. */ diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 647b7c7cd575..7a4b3701ed1a 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -300,11 +300,10 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | I2C_FUNC_SMBUS_WORD_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct lm92_data)); /* Fill in enough client fields so that we can read from the chip, which is required for identication */ diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 16bf71f3a04d..6a82ffae1bfd 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -197,11 +197,10 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct max1619_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct max1619_data)); /* The common I2C client data is placed right before the MAX1619-specific data. */ diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index cf2a35799c7c..17f745a23d04 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -754,9 +754,8 @@ static int pc87360_detect(struct i2c_adapter *adapter) const char *name = "pc87360"; int use_thermistors = 0; - if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL))) + if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) return -ENOMEM; - memset(data, 0x00, sizeof(struct pc87360_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 21aa9a41f62c..9c6cadec1087 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -518,11 +518,10 @@ static int sis5595_detect(struct i2c_adapter *adapter) goto exit_release; } - if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { err = -ENOMEM; goto exit_release; } - memset(data, 0, sizeof(struct sis5595_data)); new_client = &data->client; new_client->addr = address; diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 37ed8b33f01a..2a3e21b5b6b4 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -244,11 +244,10 @@ static int smsc47b397_detect(struct i2c_adapter *adapter) return -EBUSY; } - if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { err = -ENOMEM; goto error_release; } - memset(data, 0x00, sizeof(struct smsc47b397_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index c9cc683eba4a..bbe93a0688ec 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -396,11 +396,10 @@ static int smsc47m1_detect(struct i2c_adapter *adapter) return -EBUSY; } - if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { err = -ENOMEM; goto error_release; } - memset(data, 0x00, sizeof(struct smsc47m1_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index c6e64f4abdea..6f696f897176 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -621,11 +621,10 @@ static int via686a_detect(struct i2c_adapter *adapter) return -ENODEV; } - if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) { err = -ENOMEM; goto exit_release; } - memset(data, 0, sizeof(struct via686a_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 685eeb766809..eee22a57e929 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -681,11 +681,10 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) goto exit; } - if (!(data = kmalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) { err = -ENOMEM; goto exit_release; } - memset(data, 0, sizeof(struct w83627ehf_data)); client = &data->client; i2c_set_clientdata(client, data); diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 48270819ff99..70ef926c3bd8 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1045,11 +1045,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter) client structure, even though we cannot fill it completely yet. But it allows us to access w83627hf_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } - memset(data, 0, sizeof(struct w83627hf_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 26b1fac7c619..9265f32122fa 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -889,12 +889,11 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, const char *client_name = ""; struct w83781d_data *data = i2c_get_clientdata(new_client); - data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!(data->lm75[0])) { err = -ENOMEM; goto ERROR_SC_0; } - memset(data->lm75[0], 0x00, sizeof (struct i2c_client)); id = i2c_adapter_id(adapter); @@ -919,13 +918,11 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, } if (kind != w83783s) { - - data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!(data->lm75[1])) { err = -ENOMEM; goto ERROR_SC_1; } - memset(data->lm75[1], 0x0, sizeof(struct i2c_client)); if (force_subclients[0] == id && force_subclients[1] == address) { @@ -1064,11 +1061,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access w83781d_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } - memset(data, 0, sizeof(struct w83781d_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 7bbd1888ce94..4be59dbb78c4 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -1086,11 +1086,10 @@ w83792d_create_subclient(struct i2c_adapter *adapter, int err; struct i2c_client *sub_client; - (*sub_cli) = sub_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + (*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!(sub_client)) { return -ENOMEM; } - memset(sub_client, 0x00, sizeof(struct i2c_client)); sub_client->addr = 0x48 + addr; i2c_set_clientdata(sub_client, NULL); sub_client->adapter = adapter; @@ -1184,11 +1183,10 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) client structure, even though we cannot fill it completely yet. But it allows us to access w83792d_{read,write}_value. */ - if (!(data = kmalloc(sizeof(struct w83792d_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } - memset(data, 0, sizeof(struct w83792d_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index db12a620b331..f495b6378668 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -156,12 +156,10 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto exit; - if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct w83l785ts_data)); - /* The common I2C client data is placed right before the * W83L785TS-specific data. */ From 5263ebb51eb098b01caf229498c954999117e4a7 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 17 Oct 2005 23:09:43 +0200 Subject: [PATCH 0746/1940] [PATCH] i2c: kzalloc conversion, other drivers Use kzalloc instead of kmalloc+memset in all remaining i2c bus and chip drivers. Signed-off-by: Deepak Saxena Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-amd8111.c | 3 +-- drivers/i2c/busses/i2c-ibm_iic.c | 3 +-- drivers/i2c/busses/i2c-iop3xx.c | 6 ++---- drivers/i2c/busses/i2c-keywest.c | 3 +-- drivers/i2c/busses/i2c-mpc.c | 3 +-- drivers/i2c/busses/i2c-mv64xxx.c | 5 +---- drivers/i2c/busses/i2c-nforce2.c | 3 +-- drivers/i2c/busses/i2c-parport.c | 5 ++--- drivers/i2c/busses/i2c-pmac-smu.c | 3 +-- drivers/i2c/busses/i2c-prosavage.c | 4 +--- drivers/i2c/busses/scx200_acb.c | 3 +-- drivers/i2c/chips/ds1337.c | 3 +-- drivers/i2c/chips/ds1374.c | 3 +-- drivers/i2c/chips/eeprom.c | 3 +-- drivers/i2c/chips/m41t00.c | 3 +-- drivers/i2c/chips/max6875.c | 6 ++---- drivers/i2c/chips/pca9539.c | 3 +-- drivers/i2c/chips/pcf8574.c | 3 +-- drivers/i2c/chips/pcf8591.c | 3 +-- drivers/i2c/chips/rtc8564.c | 3 +-- drivers/i2c/chips/tps65010.c | 3 +-- drivers/i2c/i2c-dev.c | 3 +-- 22 files changed, 25 insertions(+), 52 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 0d29e78dff63..aface7938a5b 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -344,10 +344,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_ if (~pci_resource_flags(dev, 0) & IORESOURCE_IO) return -ENODEV; - smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL); + smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL); if (!smbus) return -ENOMEM; - memset(smbus, 0, sizeof(struct amd_smbus)); smbus->dev = dev; smbus->base = pci_resource_start(dev, 0); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index a3ed9590f028..1a587253d716 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -672,13 +672,12 @@ static int __devinit iic_probe(struct ocp_device *ocp){ printk(KERN_WARNING"ibm-iic%d: missing additional data!\n", ocp->def->index); - if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){ + if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) { printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n", ocp->def->index); return -ENOMEM; } - memset(dev, 0, sizeof(*dev)); dev->idx = ocp->def->index; ocp_set_drvdata(ocp, dev); diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 0f7dfd8f4546..9888fae1f37a 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -440,19 +440,17 @@ iop3xx_i2c_probe(struct device *dev) struct i2c_adapter *new_adapter; struct i2c_algo_iop3xx_data *adapter_data; - new_adapter = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL); + new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); if (!new_adapter) { ret = -ENOMEM; goto out; } - memset((void*)new_adapter, 0, sizeof(*new_adapter)); - adapter_data = kmalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); + adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); if (!adapter_data) { ret = -ENOMEM; goto free_adapter; } - memset((void*)adapter_data, 0, sizeof(*adapter_data)); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 34e43c8d8d5e..ef281e0c567b 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -535,13 +535,12 @@ create_iface(struct device_node *np, struct device *dev) tsize = sizeof(struct keywest_iface) + (sizeof(struct keywest_chan) + 4) * nchan; - iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL); + iface = (struct keywest_iface *) kzalloc(tsize, GFP_KERNEL); if (iface == NULL) { printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); pmac_low_i2c_unlock(np); return -ENOMEM; } - memset(iface, 0, tsize); spin_lock_init(&iface->lock); init_completion(&iface->complete); iface->node = of_node_get(np); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index b81c54620030..8491633005b8 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -296,10 +296,9 @@ static int fsl_i2c_probe(struct device *device) pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; - if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) { + if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) { return -ENOMEM; } - memset(i2c, 0, sizeof(*i2c)); i2c->irq = platform_get_irq(pdev, 0); i2c->flags = pdata->device_flags; diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 69709ee0b896..d0d2a6f1386e 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -500,13 +500,10 @@ mv64xxx_i2c_probe(struct device *dev) if ((pd->id != 0) || !pdata) return -ENODEV; - drv_data = kmalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL); - + drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL); if (!drv_data) return -ENOMEM; - memset(drv_data, 0, sizeof(struct mv64xxx_i2c_data)); - if (mv64xxx_i2c_map_regs(pd, drv_data)) { rc = -ENODEV; goto exit_kfree; diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 5dc62114cc8d..87b6e26aa8a0 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -313,10 +313,9 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ int res1, res2; /* we support 2 SMBus adapters */ - if (!(smbuses = (void *)kmalloc(2*sizeof(struct nforce2_smbus), + if (!(smbuses = (void *)kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL))) return -ENOMEM; - memset (smbuses, 0, 2*sizeof(struct nforce2_smbus)); pci_set_drvdata(dev, smbuses); /* SMBus adapter 1 */ diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index fa506187fbe1..2854d858fc9b 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -155,12 +155,11 @@ static void i2c_parport_attach (struct parport *port) { struct i2c_par *adapter; - adapter = kmalloc(sizeof(struct i2c_par), GFP_KERNEL); + adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL); if (adapter == NULL) { - printk(KERN_ERR "i2c-parport: Failed to kmalloc\n"); + printk(KERN_ERR "i2c-parport: Failed to kzalloc\n"); return; } - memset(adapter, 0x00, sizeof(struct i2c_par)); pr_debug("i2c-parport: attaching to %s\n", port->name); adapter->pdev = parport_register_device(port, "i2c-parport", diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c index 8a9f5648a23d..bfefe7f7a53d 100644 --- a/drivers/i2c/busses/i2c-pmac-smu.c +++ b/drivers/i2c/busses/i2c-pmac-smu.c @@ -211,12 +211,11 @@ static int create_iface(struct device_node *np, struct device *dev) } busid = *reg; - iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL); + iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL); if (iface == NULL) { printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n"); return -ENOMEM; } - memset(iface, 0, sizeof(struct smu_iface)); init_completion(&iface->complete); iface->busid = busid; diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c index 92b744273577..42f8b5ce3bf8 100644 --- a/drivers/i2c/busses/i2c-prosavage.c +++ b/drivers/i2c/busses/i2c-prosavage.c @@ -241,14 +241,12 @@ static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_devic struct s_i2c_chip *chip; struct s_i2c_bus *bus; - pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); + pci_set_drvdata(dev, kzalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); chip = (struct s_i2c_chip *)pci_get_drvdata(dev); if (chip == NULL) { return -ENOMEM; } - memset(chip, 0, sizeof(struct s_i2c_chip)); - base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK; len = dev->resource[0].end - base + 1; chip->mmio = ioremap_nocache(base, len); diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index a1d580e05361..d3478e084522 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -442,14 +442,13 @@ static int __init scx200_acb_create(int base, int index) int rc = 0; char description[64]; - iface = kmalloc(sizeof(*iface), GFP_KERNEL); + iface = kzalloc(sizeof(*iface), GFP_KERNEL); if (!iface) { printk(KERN_ERR NAME ": can't allocate memory\n"); rc = -ENOMEM; goto errout; } - memset(iface, 0, sizeof(*iface)); adapter = &iface->adapter; i2c_set_adapdata(adapter, iface); snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index); diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 9d3175c03395..01b037007410 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c @@ -243,11 +243,10 @@ static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind) I2C_FUNC_I2C)) goto exit; - if (!(data = kmalloc(sizeof(struct ds1337_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct ds1337_data)); INIT_LIST_HEAD(&data->list); /* The common I2C client data is placed right before the diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index ec640e9f085a..1596e6478782 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c @@ -193,11 +193,10 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) struct i2c_client *client; int rc; - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!client) return -ENOMEM; - memset(client, 0, sizeof(struct i2c_client)); strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE); client->addr = addr; client->adapter = adap; diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 7fb739c43935..ee7cbc823fd1 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -171,11 +171,10 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) | I2C_FUNC_SMBUS_BYTE)) goto exit; - if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct eeprom_data)); new_client = &data->client; memset(data->data, 0xff, EEPROM_SIZE); diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 554f7ba61627..3df309ae44a6 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c @@ -174,11 +174,10 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) struct i2c_client *client; int rc; - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!client) return -ENOMEM; - memset(client, 0, sizeof(struct i2c_client)); strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); client->addr = addr; client->adapter = adap; diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index 9e1aeb69abf9..b376a006883c 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c @@ -179,16 +179,14 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) if (address & 1) return 0; - if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL))) + if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) return -ENOMEM; - memset(data, 0, sizeof(struct max6875_data)); /* A fake client is created on the odd address */ - if (!(fake_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { err = -ENOMEM; goto exit_kfree1; } - memset(fake_client, 0, sizeof(struct i2c_client)); /* Init real i2c_client */ real_client = &data->client; diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index 225577fdda4d..59a930346229 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c @@ -122,11 +122,10 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. */ - if (!(data = kmalloc(sizeof(struct pca9539_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct pca9539_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index 6525743ff9fd..2c2555d46fdf 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c @@ -127,11 +127,10 @@ int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. */ - if (!(data = kmalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct pcf8574_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 80f1df9a4500..3c815b153249 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c @@ -178,11 +178,10 @@ int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. */ - if (!(data = kmalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - memset(data, 0, sizeof(struct pcf8591_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index dd9d42d7b6e7..916cdc1af23c 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c @@ -148,12 +148,11 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind) {addr, I2C_M_RD, 2, data} }; - d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL); + d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL); if (!d) { ret = -ENOMEM; goto done; } - memset(d, 0, sizeof(struct rtc8564_data)); new_client = &d->client; strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 280e9638c0f8..280dd7a45db6 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c @@ -500,11 +500,10 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) return 0; } - tps = kmalloc(sizeof *tps, GFP_KERNEL); + tps = kzalloc(sizeof *tps, GFP_KERNEL); if (!tps) return 0; - memset(tps, 0, sizeof *tps); init_MUTEX(&tps->lock); INIT_WORK(&tps->work, tps65010_work, tps); tps->irq = -1; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 89f54a5e8484..276ec42a0717 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -80,10 +80,9 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; - i2c_dev = kmalloc(sizeof(*i2c_dev), GFP_KERNEL); + i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL); if (!i2c_dev) return ERR_PTR(-ENOMEM); - memset(i2c_dev, 0x00, sizeof(*i2c_dev)); spin_lock(&i2c_dev_array_lock); if (i2c_dev_array[adap->nr]) { From 078d9fe4fe8dada13e37d2e2790b0ad780324097 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 17 Oct 2005 23:12:36 +0200 Subject: [PATCH 0747/1940] [PATCH] i2c: kzalloc cleanups, 1 of 2 Drop useless casts on kzalloc returned values, as suggested by Jiri Slaby. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-keywest.c | 2 +- drivers/i2c/busses/i2c-nforce2.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index ef281e0c567b..d61f748278fc 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -535,7 +535,7 @@ create_iface(struct device_node *np, struct device *dev) tsize = sizeof(struct keywest_iface) + (sizeof(struct keywest_chan) + 4) * nchan; - iface = (struct keywest_iface *) kzalloc(tsize, GFP_KERNEL); + iface = kzalloc(tsize, GFP_KERNEL); if (iface == NULL) { printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); pmac_low_i2c_unlock(np); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 87b6e26aa8a0..9b4247610815 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -313,8 +313,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ int res1, res2; /* we support 2 SMBus adapters */ - if (!(smbuses = (void *)kzalloc(2*sizeof(struct nforce2_smbus), - GFP_KERNEL))) + if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL))) return -ENOMEM; pci_set_drvdata(dev, smbuses); From deb875c7ff2ef417a2daff41ee4b357098b7ab10 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 17 Oct 2005 23:14:31 +0200 Subject: [PATCH 0748/1940] [PATCH] i2c: kzalloc cleanups, 2 of 2 Use kzalloc instead of kmalloc in the S4882 SMBus multiplexing driver. I guess it's safer that way. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-amd756-s4882.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 4e553e8c5cba..f51ab652300a 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -169,12 +169,12 @@ static int __init amd756_s4882_init(void) init_MUTEX(&amd756_lock); /* Define the 5 virtual adapters and algorithms structures */ - if (!(s4882_adapter = kmalloc(5 * sizeof(struct i2c_adapter), + if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL))) { error = -ENOMEM; goto ERROR1; } - if (!(s4882_algo = kmalloc(5 * sizeof(struct i2c_algorithm), + if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL))) { error = -ENOMEM; goto ERROR2; From 2445eb62e98250f1ec8cbc8cf7c4be9cfafe88e5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 17 Oct 2005 23:16:25 +0200 Subject: [PATCH 0749/1940] [PATCH] i2c: Documentation update Update the i2c documentation: kzalloc should be used instead of kmalloc. I also fixed a couple other things nearby in writing-clients, as several past changes had never been reported there. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/i2c/porting-clients | 2 +- Documentation/i2c/writing-clients | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients index 4849dfd6961c..184fac2377aa 100644 --- a/Documentation/i2c/porting-clients +++ b/Documentation/i2c/porting-clients @@ -82,7 +82,7 @@ Technical changes: exit and exit_free. For i2c+isa drivers, labels should be named ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before jumping to error labels. By the way, labels should be left-aligned. - Use memset to fill the client and data area with 0x00. + Use kzalloc instead of kmalloc. Use i2c_set_clientdata to set the client data (as opposed to a direct access to client->data). Use strlcpy instead of strcpy to copy the client name. diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 1882811c7f5d..e94d9c6cc522 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -55,6 +55,7 @@ be very useful. An example structure is below. struct foo_data { + struct i2c_client client; struct semaphore lock; /* For ISA access in `sensors' drivers. */ int sysctl_id; /* To keep the /proc directory entry for `sensors' drivers. */ @@ -307,22 +308,15 @@ For now, you can ignore the `flags' parameter. It is there for future use. client structure, even though we cannot fill it completely yet. But it allows us to access several i2c functions safely */ - /* Note that we reserve some space for foo_data too. If you don't - need it, remove it. We do it here to help to lessen memory - fragmentation. */ - if (! (new_client = kmalloc(sizeof(struct i2c_client) + - sizeof(struct foo_data), - GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } - /* This is tricky, but it will set the data to the right value. */ - client->data = new_client + 1; - data = (struct foo_data *) (client->data); + new_client = &data->client; + i2c_set_clientdata(new_client, data); new_client->addr = address; - new_client->data = data; new_client->adapter = adapter; new_client->driver = &foo_driver; new_client->flags = 0; @@ -448,7 +442,7 @@ much simpler than the attachment code, fortunately! release_region(client->addr,LM78_EXTENT); /* HYBRID SENSORS CHIP ONLY END */ - kfree(client); /* Frees client data too, if allocated at the same time */ + kfree(data); return 0; } From 6536c49a1ee2bd85eee0e7fa41e67c5743f2f93e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 26 Oct 2005 21:04:12 +0200 Subject: [PATCH 0750/1940] [PATCH] i2c: Static function fixes, 1 of 4 eeprom_detect is first declared static and then when the function is actually implemented, there is no static. Signed-off-by: Ben Dooks Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index ee7cbc823fd1..4baf573fa04f 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -155,7 +155,7 @@ static int eeprom_attach_adapter(struct i2c_adapter *adapter) } /* This function is called by i2c_probe */ -int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) +static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) { struct i2c_client *new_client; struct eeprom_data *data; From d8d2061590c87c20bf78133461bc74df78803ecb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 26 Oct 2005 21:05:46 +0200 Subject: [PATCH 0751/1940] [PATCH] hwmon: Static function fixes, 2 of 4 lm78.c and lm85.c have a number of items declared static then implemented without the static on them. The following patch fixes these sparse errors. Signed-off-by: Ben Dooks Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/lm78.c | 2 +- drivers/hwmon/lm85.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 924462362743..bde0cda9477e 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -480,7 +480,7 @@ static int lm78_isa_attach_adapter(struct i2c_adapter *adapter) } /* This function is called by i2c_probe */ -int lm78_detect(struct i2c_adapter *adapter, int address, int kind) +static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) { int i, err; struct i2c_client *new_client; diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index d5537a5377f7..d1070ed2bee6 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1007,14 +1007,14 @@ temp_auto(1); temp_auto(2); temp_auto(3); -int lm85_attach_adapter(struct i2c_adapter *adapter) +static int lm85_attach_adapter(struct i2c_adapter *adapter) { if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_probe(adapter, &addr_data, lm85_detect); } -int lm85_detect(struct i2c_adapter *adapter, int address, +static int lm85_detect(struct i2c_adapter *adapter, int address, int kind) { int company, verstep ; @@ -1235,7 +1235,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address, return err; } -int lm85_detach_client(struct i2c_client *client) +static int lm85_detach_client(struct i2c_client *client) { struct lm85_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->class_dev); @@ -1245,7 +1245,7 @@ int lm85_detach_client(struct i2c_client *client) } -int lm85_read_value(struct i2c_client *client, u8 reg) +static int lm85_read_value(struct i2c_client *client, u8 reg) { int res; @@ -1275,7 +1275,7 @@ int lm85_read_value(struct i2c_client *client, u8 reg) return res ; } -int lm85_write_value(struct i2c_client *client, u8 reg, int value) +static int lm85_write_value(struct i2c_client *client, u8 reg, int value) { int res ; @@ -1304,7 +1304,7 @@ int lm85_write_value(struct i2c_client *client, u8 reg, int value) return res ; } -void lm85_init_client(struct i2c_client *client) +static void lm85_init_client(struct i2c_client *client) { int value; struct lm85_data *data = i2c_get_clientdata(client); From c49efceffa599299ab3f38b1cdf8c2f1bf9811c4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 26 Oct 2005 21:07:25 +0200 Subject: [PATCH 0752/1940] [PATCH] hwmon: Static function fixes, 3 of 4 Fixup functions that have been declared static and then actually defined without the static on. Signed-off-by: Ben Dooks Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adm1026.c | 18 +++++++++--------- drivers/hwmon/ds1621.c | 4 ++-- drivers/hwmon/fscpos.c | 2 +- drivers/hwmon/it87.c | 2 +- drivers/hwmon/lm80.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 3b5814183738..e0f56549d1d8 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -315,7 +315,7 @@ static struct i2c_driver adm1026_driver = { .detach_client = adm1026_detach_client, }; -int adm1026_attach_adapter(struct i2c_adapter *adapter) +static int adm1026_attach_adapter(struct i2c_adapter *adapter) { if (!(adapter->class & I2C_CLASS_HWMON)) { return 0; @@ -323,7 +323,7 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, adm1026_detect); } -int adm1026_detach_client(struct i2c_client *client) +static int adm1026_detach_client(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->class_dev); @@ -332,7 +332,7 @@ int adm1026_detach_client(struct i2c_client *client) return 0; } -int adm1026_read_value(struct i2c_client *client, u8 reg) +static int adm1026_read_value(struct i2c_client *client, u8 reg) { int res; @@ -346,7 +346,7 @@ int adm1026_read_value(struct i2c_client *client, u8 reg) return res; } -int adm1026_write_value(struct i2c_client *client, u8 reg, int value) +static int adm1026_write_value(struct i2c_client *client, u8 reg, int value) { int res; @@ -360,7 +360,7 @@ int adm1026_write_value(struct i2c_client *client, u8 reg, int value) return res; } -void adm1026_init_client(struct i2c_client *client) +static void adm1026_init_client(struct i2c_client *client) { int value, i; struct adm1026_data *data = i2c_get_clientdata(client); @@ -460,7 +460,7 @@ void adm1026_init_client(struct i2c_client *client) } } -void adm1026_print_gpio(struct i2c_client *client) +static void adm1026_print_gpio(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); int i; @@ -492,7 +492,7 @@ void adm1026_print_gpio(struct i2c_client *client) } } -void adm1026_fixup_gpio(struct i2c_client *client) +static void adm1026_fixup_gpio(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); int i; @@ -1452,8 +1452,8 @@ static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); -int adm1026_detect(struct i2c_adapter *adapter, int address, - int kind) +static int adm1026_detect(struct i2c_adapter *adapter, int address, + int kind) { int company, verstep; struct i2c_client *new_client; diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index c5afa0058308..34f71b7c7f37 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -186,8 +186,8 @@ static int ds1621_attach_adapter(struct i2c_adapter *adapter) } /* This function is called by i2c_probe */ -int ds1621_detect(struct i2c_adapter *adapter, int address, - int kind) +static int ds1621_detect(struct i2c_adapter *adapter, int address, + int kind) { int conf, temp; struct i2c_client *new_client; diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index a378e4f5c93b..64e4edc64f8d 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -438,7 +438,7 @@ static int fscpos_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, fscpos_detect); } -int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) +static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) { struct i2c_client *new_client; struct fscpos_data *data; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 9a5b8b268397..6c41e25e670b 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -738,7 +738,7 @@ static int __init it87_find(unsigned short *address) } /* This function is called by i2c_probe */ -int it87_detect(struct i2c_adapter *adapter, int address, int kind) +static int it87_detect(struct i2c_adapter *adapter, int address, int kind) { int i; struct i2c_client *new_client; diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index b4cd6c661f11..c359fdea211e 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -393,7 +393,7 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm80_detect); } -int lm80_detect(struct i2c_adapter *adapter, int address, int kind) +static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) { int i, cur; struct i2c_client *new_client; From 6344a8ece0bacccf61817450e8ccf78c973fc0c5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 26 Oct 2005 21:09:41 +0200 Subject: [PATCH 0753/1940] [PATCH] i2c: Static function fixes, 4 of 4 Fix functions declared static and then implemented without the static in drivers/i2c/chips. Signed-off-by: Ben Dooks Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/ds1374.c | 3 ++- drivers/i2c/chips/pcf8574.c | 2 +- drivers/i2c/chips/pcf8591.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 1596e6478782..da488b735abf 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c @@ -167,7 +167,8 @@ static void ds1374_set_tlet(ulong arg) static ulong new_time; -DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, (ulong) & new_time); +static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, + (ulong) & new_time); int ds1374_set_rtc_time(ulong nowtime) { diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index 2c2555d46fdf..c323c2de236c 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c @@ -115,7 +115,7 @@ static int pcf8574_attach_adapter(struct i2c_adapter *adapter) } /* This function is called by i2c_probe */ -int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) +static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) { struct i2c_client *new_client; struct pcf8574_data *data; diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 3c815b153249..ce420a67560b 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c @@ -166,7 +166,7 @@ static int pcf8591_attach_adapter(struct i2c_adapter *adapter) } /* This function is called by i2c_probe */ -int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) +static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) { struct i2c_client *new_client; struct pcf8591_data *data; From cd19cc4732395eb3dbaf49042233b5ac69b1fbd3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:14:16 +0200 Subject: [PATCH 0754/1940] [PATCH] i2c: ID redefinition cleanups Fix several redefinitions of i2c IDs. i2c IDs must not be defined outside of i2c-id.h. Signed-off-by: Jean Delvare Signed-off-by: Henk Vergonet Acked-by: Mark McClelland Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-prosavage.c | 5 ----- include/media/ovcamchip.h | 14 -------------- 2 files changed, 19 deletions(-) diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c index 42f8b5ce3bf8..42cb1d8ca659 100644 --- a/drivers/i2c/busses/i2c-prosavage.c +++ b/drivers/i2c/busses/i2c-prosavage.c @@ -83,11 +83,6 @@ struct s_i2c_chip { /* * i2c configuration */ -#ifndef I2C_HW_B_S3VIA -#define I2C_HW_B_S3VIA 0x18 /* S3VIA ProSavage adapter */ -#endif - -/* delays */ #define CYCLE_DELAY 10 #define TIMEOUT (HZ / 2) diff --git a/include/media/ovcamchip.h b/include/media/ovcamchip.h index cb7c0aa96f22..8138983adced 100644 --- a/include/media/ovcamchip.h +++ b/include/media/ovcamchip.h @@ -17,20 +17,6 @@ #include #include -/* Remove these once they are officially defined */ -#ifndef I2C_DRIVERID_OVCAMCHIP - #define I2C_DRIVERID_OVCAMCHIP 0xf00f -#endif -#ifndef I2C_HW_SMBUS_OV511 - #define I2C_HW_SMBUS_OV511 0xfe -#endif -#ifndef I2C_HW_SMBUS_OV518 - #define I2C_HW_SMBUS_OV518 0xff -#endif -#ifndef I2C_HW_SMBUS_OVFX2 - #define I2C_HW_SMBUS_OVFX2 0xfd -#endif - /* --------------------------------- */ /* ENUMERATIONS */ /* --------------------------------- */ From eb00a28ae1a8fc4b3914f94ab1944396b8dda9fc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:20:17 +0200 Subject: [PATCH 0755/1940] [PATCH] i2c: Drop unused parport i2c IDs Drop unused i2c-over-parallel-port i2c IDs: * I2C_HW_B_LPC was never actually used as far as I could search. * I2C_HW_B_ELV and I2C_HW_B_VELLE are no more used since the introduction of the unified i2c-parport driver in Linux 2.6.2. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c-id.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 44f30876a1c9..1ce4b54caa21 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -164,10 +164,7 @@ /* --- Bit algorithm adapters */ #define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ -#define I2C_HW_B_LPC 0x010001 /* Parallel port control reg. */ #define I2C_HW_B_SER 0x010002 /* Serial line interface */ -#define I2C_HW_B_ELV 0x010003 /* ELV Card */ -#define I2C_HW_B_VELLE 0x010004 /* Vellemann K8000 */ #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ #define I2C_HW_B_WNV 0x010006 /* Winnov Videums */ #define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ From 142078f6f09986c2b8f5ebe215ce405438080317 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:21:50 +0200 Subject: [PATCH 0756/1940] [PATCH] i2c: i2c-i810 documentation update Update the documented list of devices supported by the i2c-i810 driver. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/i2c/busses/i2c-i810 | 1 + drivers/i2c/busses/Kconfig | 3 ++- drivers/i2c/busses/i2c-i810.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/i2c/busses/i2c-i810 b/Documentation/i2c/busses/i2c-i810 index 0544eb332887..83c3b9743c3c 100644 --- a/Documentation/i2c/busses/i2c-i810 +++ b/Documentation/i2c/busses/i2c-i810 @@ -2,6 +2,7 @@ Kernel driver i2c-i810 Supported adapters: * Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH) + * Intel 82845G (GMCH) Authors: Frodo Looijaard , diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3badfec75b1c..4010fe92e72b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -135,11 +135,12 @@ config I2C_I810 help If you say yes to this option, support will be included for the Intel 810/815 family of mainboard I2C interfaces. Specifically, the - following versions of the chipset is supported: + following versions of the chipset are supported: i810AA i810AB i810E i815 + i845G This driver can also be built as a module. If so, the module will be called i2c-i810. diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c index 1b3393b7c461..52bc30593bd7 100644 --- a/drivers/i2c/busses/i2c-i810.c +++ b/drivers/i2c/busses/i2c-i810.c @@ -32,6 +32,7 @@ i810AB 7123 i810E 7125 i815 1132 + i845G 2562 */ #include From b8095544bc27044a7aa79e1e073b781a249910c3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:25:04 +0200 Subject: [PATCH 0757/1940] [PATCH] i2c: SMBus PEC support rewrite, 1 of 3 Discard I2C_FUNC_SMBUS_*_PEC defines. i2c clients are not supposed to check for PEC support of i2c bus drivers on individual SMBus transactions, and i2c bus drivers are not supposed to advertise them. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 3 +-- include/linux/i2c.h | 18 ------------------ 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e90b6c4e7da3..b05e045f770c 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -513,8 +513,7 @@ static u32 i801_func(struct i2c_adapter *adapter) return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK - | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC | - I2C_FUNC_SMBUS_HWPEC_CALC : 0); + | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0); } static struct i2c_algorithm smbus_algorithm = { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 64c13c042f9d..bcd4bb1b450c 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -389,10 +389,6 @@ struct i2c_msg { #define I2C_FUNC_10BIT_ADDR 0x00000002 #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ #define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_QUICK 0x00010000 #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 @@ -408,8 +404,6 @@ struct i2c_msg { #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ -#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ I2C_FUNC_SMBUS_WRITE_BYTE) @@ -423,17 +417,6 @@ struct i2c_msg { I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) #define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2) -#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC (I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC) -#define I2C_FUNC_SMBUS_WORD_DATA_PEC (I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC) - -#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA -#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA -#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA -#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA -#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA -#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA #define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ I2C_FUNC_SMBUS_BYTE | \ @@ -441,7 +424,6 @@ struct i2c_msg { I2C_FUNC_SMBUS_WORD_DATA | \ I2C_FUNC_SMBUS_PROC_CALL | \ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ I2C_FUNC_SMBUS_I2C_BLOCK) /* From 421ef47be20c5454b12ae0ec918d5073a9d2b938 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:28:55 +0200 Subject: [PATCH 0758/1940] [PATCH] i2c: SMBus PEC support rewrite, 2 of 3 This is my rewrite of the SMBus PEC support. The original implementation was known to have bugs (credits go to Hideki Iwamoto for reporting many of them recently), and was incomplete due to a conceptual limitation. The rewrite affects only software PEC. Hardware PEC needs very little code and is mostly untouched. Technically, both implementations differ in that the original one was emulating PEC in software by modifying the contents of an i2c_smbus_data union (changing the transaction to a different type), while the new one works one level lower, on i2c_msg structures (working on message contents). Due to the definition of the i2c_smbus_data union, not all SMBus transactions could be handled (at least not without changing the definition of this union, which would break user-space compatibility), and those which could had to be implemented individually. At the opposite, adding PEC to an i2c_msg structure can be done on any SMBus transaction with common code. Advantages of the new implementation: * It's about twice as small (from ~136 lines before to ~70 now, only counting i2c-core, including blank and comment lines). The memory used by i2c-core is down by ~640 bytes (~3.5%). * Easier to validate, less tricky code. The code being common to all transactions by design, the risk that a bug can stay uncovered is lower. * All SMBus transactions have PEC support in I2C emulation mode (providing the non-PEC transaction is also implemented). Transactions which have no emulation code right now will get PEC support for free when they finally get implemented. * Allows for code simplifications in header files and bus drivers (patch follows). Drawbacks (I guess there had to be at least one): * PEC emulation for non-PEC capable non-I2C SMBus masters was dropped. It was based on SMBus tricks and doesn't quite fit in the new design. I don't think it's really a problem, as the benefit was certainly not worth the additional complexity, but it's only fair that I at least mention it. Lastly, let's note that the new implementation does slightly affect compatibility (both in kernel and user-space), but doesn't actually break it. Some defines will be dropped, but the code can always be changed in a way that will work with both the old and the new implementations. It shouldn't be a problem as there doesn't seem to be many users of SMBus PEC to date anyway. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-core.c | 162 ++++++++++++----------------------------- include/linux/i2c.h | 2 +- 2 files changed, 49 insertions(+), 115 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0040981b6698..02e335a04f09 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -19,7 +19,8 @@ /* With some changes from Kyösti Mälkki . All SMBus-related things are written by Frodo Looijaard - SMBus 2.0 support by Mark Studebaker */ + SMBus 2.0 support by Mark Studebaker and + Jean Delvare */ #include #include @@ -830,101 +831,44 @@ crc8(u16 data) return (u8)(data >> 8); } -/* CRC over count bytes in the first array plus the bytes in the rest - array if it is non-null. rest[0] is the (length of rest) - 1 - and is included. */ -static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest) +/* Incremental CRC8 over count bytes in the array pointed to by p */ +static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) { int i; for(i = 0; i < count; i++) - crc = crc8((crc ^ first[i]) << 8); - if(rest != NULL) - for(i = 0; i <= rest[0]; i++) - crc = crc8((crc ^ rest[i]) << 8); + crc = crc8((crc ^ p[i]) << 8); return crc; } -static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest) +/* Assume a 7-bit address, which is reasonable for SMBus */ +static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) { - return i2c_smbus_partial_pec(0, count, first, rest); + /* The address will be sent first */ + u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD); + pec = i2c_smbus_pec(pec, &addr, 1); + + /* The data buffer follows */ + return i2c_smbus_pec(pec, msg->buf, msg->len); } -/* Returns new "size" (transaction type) - Note that we convert byte to byte_data and byte_data to word_data - rather than invent new xxx_PEC transactions. */ -static int i2c_smbus_add_pec(u16 addr, u8 command, int size, - union i2c_smbus_data *data) +/* Used for write only transactions */ +static inline void i2c_smbus_add_pec(struct i2c_msg *msg) { - u8 buf[3]; - - buf[0] = addr << 1; - buf[1] = command; - switch(size) { - case I2C_SMBUS_BYTE: - data->byte = i2c_smbus_pec(2, buf, NULL); - size = I2C_SMBUS_BYTE_DATA; - break; - case I2C_SMBUS_BYTE_DATA: - buf[2] = data->byte; - data->word = buf[2] | - (i2c_smbus_pec(3, buf, NULL) << 8); - size = I2C_SMBUS_WORD_DATA; - break; - case I2C_SMBUS_WORD_DATA: - /* unsupported */ - break; - case I2C_SMBUS_BLOCK_DATA: - data->block[data->block[0] + 1] = - i2c_smbus_pec(2, buf, data->block); - size = I2C_SMBUS_BLOCK_DATA_PEC; - break; - } - return size; + msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg); + msg->len++; } -static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial, - union i2c_smbus_data *data) +/* Return <0 on CRC error + If there was a write before this read (most cases) we need to take the + partial CRC from the write part into account. + Note that this function does modify the message (we need to decrease the + message length to hide the CRC byte from the caller). */ +static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) { - u8 buf[3], rpec, cpec; + u8 rpec = msg->buf[--msg->len]; + cpec = i2c_smbus_msg_pec(cpec, msg); - buf[1] = command; - switch(size) { - case I2C_SMBUS_BYTE_DATA: - buf[0] = (addr << 1) | 1; - cpec = i2c_smbus_pec(2, buf, NULL); - rpec = data->byte; - break; - case I2C_SMBUS_WORD_DATA: - buf[0] = (addr << 1) | 1; - buf[2] = data->word & 0xff; - cpec = i2c_smbus_pec(3, buf, NULL); - rpec = data->word >> 8; - break; - case I2C_SMBUS_WORD_DATA_PEC: - /* unsupported */ - cpec = rpec = 0; - break; - case I2C_SMBUS_PROC_CALL_PEC: - /* unsupported */ - cpec = rpec = 0; - break; - case I2C_SMBUS_BLOCK_DATA_PEC: - buf[0] = (addr << 1); - buf[2] = (addr << 1) | 1; - cpec = i2c_smbus_pec(3, buf, data->block); - rpec = data->block[data->block[0] + 1]; - break; - case I2C_SMBUS_BLOCK_PROC_CALL_PEC: - buf[0] = (addr << 1) | 1; - rpec = i2c_smbus_partial_pec(partial, 1, - buf, data->block); - cpec = data->block[data->block[0] + 1]; - break; - default: - cpec = rpec = 0; - break; - } if (rpec != cpec) { pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n", rpec, cpec); @@ -951,9 +895,8 @@ s32 i2c_smbus_read_byte(struct i2c_client *client) s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) { - union i2c_smbus_data data; /* only for PEC */ return i2c_smbus_xfer(client->adapter,client->addr,client->flags, - I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data); + I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) @@ -1043,6 +986,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, { addr, flags | I2C_M_RD, 0, msgbuf1 } }; int i; + u8 partial_pec = 0; msgbuf0[0] = command; switch(size) { @@ -1085,7 +1029,6 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, msgbuf0[2] = (data->word >> 8) & 0xff; break; case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_BLOCK_DATA_PEC: if (read_write == I2C_SMBUS_READ) { dev_err(&adapter->dev, "Block read not supported " "under I2C emulation!\n"); @@ -1098,14 +1041,11 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, data->block[0]); return -1; } - if(size == I2C_SMBUS_BLOCK_DATA_PEC) - (msg[0].len)++; for (i = 1; i < msg[0].len; i++) msgbuf0[i] = data->block[i-1]; } break; case I2C_SMBUS_BLOCK_PROC_CALL: - case I2C_SMBUS_BLOCK_PROC_CALL_PEC: dev_dbg(&adapter->dev, "Block process call not supported " "under I2C emulation!\n"); return -1; @@ -1130,9 +1070,30 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, return -1; } + i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK + && size != I2C_SMBUS_I2C_BLOCK_DATA); + if (i) { + /* Compute PEC if first message is a write */ + if (!(msg[0].flags & I2C_M_RD)) { + if (num == 1) /* Write only */ + i2c_smbus_add_pec(&msg[0]); + else /* Write followed by read */ + partial_pec = i2c_smbus_msg_pec(0, &msg[0]); + } + /* Ask for PEC if last message is a read */ + if (msg[num-1].flags & I2C_M_RD) + msg[num-1].len++; + } + if (i2c_transfer(adapter, msg, num) < 0) return -1; + /* Check PEC if last message is a read */ + if (i && (msg[num-1].flags & I2C_M_RD)) { + if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0) + return -1; + } + if (read_write == I2C_SMBUS_READ) switch(size) { case I2C_SMBUS_BYTE: @@ -1161,28 +1122,8 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, union i2c_smbus_data * data) { s32 res; - int swpec = 0; - u8 partial = 0; flags &= I2C_M_TEN | I2C_CLIENT_PEC; - if((flags & I2C_CLIENT_PEC) && - !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) { - swpec = 1; - if(read_write == I2C_SMBUS_READ && - size == I2C_SMBUS_BLOCK_DATA) - size = I2C_SMBUS_BLOCK_DATA_PEC; - else if(size == I2C_SMBUS_PROC_CALL) - size = I2C_SMBUS_PROC_CALL_PEC; - else if(size == I2C_SMBUS_BLOCK_PROC_CALL) { - i2c_smbus_add_pec(addr, command, - I2C_SMBUS_BLOCK_DATA, data); - partial = data->block[data->block[0] + 1]; - size = I2C_SMBUS_BLOCK_PROC_CALL_PEC; - } else if(read_write == I2C_SMBUS_WRITE && - size != I2C_SMBUS_QUICK && - size != I2C_SMBUS_I2C_BLOCK_DATA) - size = i2c_smbus_add_pec(addr, command, size, data); - } if (adapter->algo->smbus_xfer) { down(&adapter->bus_lock); @@ -1193,13 +1134,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, command,size,data); - if(res >= 0 && swpec && - size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA && - (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC || - size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) { - if(i2c_smbus_check_pec(addr, command, size, partial, data)) - return -1; - } return res; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index bcd4bb1b450c..78c64f7b3105 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -434,7 +434,7 @@ union i2c_smbus_data { __u8 byte; __u16 word; __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ - /* and one more for PEC */ + /* and one more for user-space compatibility */ }; /* smbus_access read or write markers */ From 585b3160f8212e58325bc1c0292c2ec01ac5db84 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:31:15 +0200 Subject: [PATCH 0759/1940] [PATCH] i2c: SMBus PEC support rewrite, 3 of 3 The new SMBus PEC implementation doesn't support PEC emulation on non-PEC non-I2C SMBus masters, so we can drop all related code. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-amd8111.c | 7 ------- drivers/i2c/busses/i2c-i801.c | 13 +++++-------- drivers/i2c/busses/i2c-nforce2.c | 7 ------- include/linux/i2c.h | 4 ---- 4 files changed, 5 insertions(+), 26 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index aface7938a5b..f3b79a68dbec 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -253,13 +253,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl read_write = I2C_SMBUS_READ; break; - case I2C_SMBUS_WORD_DATA_PEC: - case I2C_SMBUS_BLOCK_DATA_PEC: - case I2C_SMBUS_PROC_CALL_PEC: - case I2C_SMBUS_BLOCK_PROC_CALL_PEC: - dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size); - return -1; - default: dev_warn(&adap->dev, "Unsupported transaction %d\n", size); return -1; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index b05e045f770c..27e7894a9d1c 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -102,8 +102,8 @@ MODULE_PARM_DESC(force_addr, "EXTREMELY DANGEROUS!"); static int i801_transaction(void); -static int i801_block_transaction(union i2c_smbus_data *data, - char read_write, int command); +static int i801_block_transaction(union i2c_smbus_data *data, char read_write, + int command, int hwpec); static unsigned short i801_smba; static struct pci_driver i801_driver; @@ -249,7 +249,7 @@ static int i801_transaction(void) /* All-inclusive block transaction function */ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, - int command) + int command, int hwpec) { int i, len; int smbcmd; @@ -388,7 +388,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, goto END; } - if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { + if (hwpec && command == I2C_SMBUS_BLOCK_DATA) { /* wait for INTR bit as advised by Intel */ timeout = 0; do { @@ -456,9 +456,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA: - case I2C_SMBUS_BLOCK_DATA_PEC: - if(hwpec && size == I2C_SMBUS_BLOCK_DATA) - size = I2C_SMBUS_BLOCK_DATA_PEC; outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); @@ -476,7 +473,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, outb_p(1, SMBAUXCTL); /* enable HW PEC */ } if(block) - ret = i801_block_transaction(data, read_write, size); + ret = i801_block_transaction(data, read_write, size, hwpec); else { outb_p(xact | ENABLE_INT9, SMBHSTCNT); ret = i801_transaction(); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 9b4247610815..fd26036e68a3 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -188,13 +188,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n"); return -1; - case I2C_SMBUS_WORD_DATA_PEC: - case I2C_SMBUS_BLOCK_DATA_PEC: - case I2C_SMBUS_PROC_CALL_PEC: - case I2C_SMBUS_BLOCK_PROC_CALL_PEC: - dev_err(&adap->dev, "Unexpected software PEC transaction %d\n.", size); - return -1; - default: dev_err(&adap->dev, "Unsupported transaction %d\n", size); return -1; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 78c64f7b3105..32977fb1d99a 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -451,10 +451,6 @@ union i2c_smbus_data { #define I2C_SMBUS_BLOCK_DATA 5 #define I2C_SMBUS_I2C_BLOCK_DATA 6 #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ -#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */ -#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */ -#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */ -#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */ /* ----- commands for the ioctl like i2c_command call: From e8aac4a9b417643dd9739b48473790a09b8b6cbe Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:34:42 +0200 Subject: [PATCH 0760/1940] [PATCH] i2c: i2c-i801 PEC code cleanups The tests leading to the use of hardware PEC in the i2c-i801 driver can be simplified. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-i801.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 27e7894a9d1c..4f63195069da 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -388,7 +388,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, goto END; } - if (hwpec && command == I2C_SMBUS_BLOCK_DATA) { + if (hwpec) { /* wait for INTR bit as advised by Intel */ timeout = 0; do { @@ -416,12 +416,13 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { - int hwpec = 0; + int hwpec; int block = 0; int ret, xact = 0; - if(isich4) - hwpec = (flags & I2C_CLIENT_PEC) != 0; + hwpec = isich4 && (flags & I2C_CLIENT_PEC) + && size != I2C_SMBUS_QUICK + && size != I2C_SMBUS_I2C_BLOCK_DATA; switch (size) { case I2C_SMBUS_QUICK: @@ -467,11 +468,9 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, return -1; } - if(isich4 && hwpec) { - if(size != I2C_SMBUS_QUICK && - size != I2C_SMBUS_I2C_BLOCK_DATA) - outb_p(1, SMBAUXCTL); /* enable HW PEC */ - } + if (hwpec) + outb_p(1, SMBAUXCTL); /* enable hardware PEC */ + if(block) ret = i801_block_transaction(data, read_write, size, hwpec); else { @@ -479,11 +478,8 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, ret = i801_transaction(); } - if(isich4 && hwpec) { - if(size != I2C_SMBUS_QUICK && - size != I2C_SMBUS_I2C_BLOCK_DATA) - outb_p(0, SMBAUXCTL); - } + if (hwpec) + outb_p(0, SMBAUXCTL); /* disable hardware PEC */ if(block) return ret; From 8256fe0f40f1cd72f80f2c46fe0ab1638f03a98d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:37:52 +0200 Subject: [PATCH 0761/1940] [PATCH] hwmon: Separate the lm90 register read function Preparatory patch to add PEC support to the lm90 driver. We need a centralized function to read register values, where the PEC code will be later inserted. A positive side effect is that read errors are now handled properly. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/lm90.c | 105 +++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index dad0f1074956..5acc12ae4e36 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -349,6 +349,22 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); * Real code */ +static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) +{ + int err; + + err = i2c_smbus_read_byte_data(client, reg); + + if (err < 0) { + dev_warn(&client->dev, "Register %#02x read failed (%d)\n", + reg, err); + return err; + } + *value = err; + + return 0; +} + static int lm90_attach_adapter(struct i2c_adapter *adapter) { if (!(adapter->class & I2C_CLASS_HWMON)) @@ -402,20 +418,22 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) if (kind < 0) { /* detection and identification */ u8 man_id, chip_id, reg_config1, reg_convrate; - man_id = i2c_smbus_read_byte_data(new_client, - LM90_REG_R_MAN_ID); - chip_id = i2c_smbus_read_byte_data(new_client, - LM90_REG_R_CHIP_ID); - reg_config1 = i2c_smbus_read_byte_data(new_client, - LM90_REG_R_CONFIG1); - reg_convrate = i2c_smbus_read_byte_data(new_client, - LM90_REG_R_CONVRATE); + if (lm90_read_reg(new_client, LM90_REG_R_MAN_ID, + &man_id) < 0 + || lm90_read_reg(new_client, LM90_REG_R_CHIP_ID, + &chip_id) < 0 + || lm90_read_reg(new_client, LM90_REG_R_CONFIG1, + ®_config1) < 0 + || lm90_read_reg(new_client, LM90_REG_R_CONVRATE, + ®_convrate) < 0) + goto exit_free; if (man_id == 0x01) { /* National Semiconductor */ u8 reg_config2; - reg_config2 = i2c_smbus_read_byte_data(new_client, - LM90_REG_R_CONFIG2); + if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, + ®_config2) < 0) + goto exit_free; if ((reg_config1 & 0x2A) == 0x00 && (reg_config2 & 0xF8) == 0x00 @@ -547,7 +565,10 @@ static void lm90_init_client(struct i2c_client *client) */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 5); /* 2 Hz */ - config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1); + if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { + dev_warn(&client->dev, "Initialization failed!\n"); + return; + } if (config & 0x40) i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config & 0xBF); /* run */ @@ -575,21 +596,15 @@ static struct lm90_data *lm90_update_device(struct device *dev) down(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { - u8 oldh, newh; + u8 oldh, newh, l; dev_dbg(&client->dev, "Updating lm90 data.\n"); - data->temp8[0] = i2c_smbus_read_byte_data(client, - LM90_REG_R_LOCAL_TEMP); - data->temp8[1] = i2c_smbus_read_byte_data(client, - LM90_REG_R_LOCAL_LOW); - data->temp8[2] = i2c_smbus_read_byte_data(client, - LM90_REG_R_LOCAL_HIGH); - data->temp8[3] = i2c_smbus_read_byte_data(client, - LM90_REG_R_LOCAL_CRIT); - data->temp8[4] = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_CRIT); - data->temp_hyst = i2c_smbus_read_byte_data(client, - LM90_REG_R_TCRIT_HYST); + lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); + lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]); + lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]); + lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]); + lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); + lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); /* * There is a trick here. We have to read two registers to @@ -605,36 +620,20 @@ static struct lm90_data *lm90_update_device(struct device *dev) * then we have a valid reading. Else we have to read the low * byte again, and now we believe we have a correct reading. */ - oldh = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_TEMPH); - data->temp11[0] = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_TEMPL); - newh = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_TEMPH); - if (newh != oldh) { - data->temp11[0] = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_TEMPL); -#ifdef DEBUG - oldh = i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_TEMPH); - /* oldh is actually newer */ - if (newh != oldh) - dev_warn(&client->dev, "Remote temperature may be " - "wrong.\n"); -#endif - } - data->temp11[0] |= (newh << 8); + if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0 + && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0 + && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0 + && (newh == oldh + || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0)) + data->temp11[0] = (newh << 8) | l; - data->temp11[1] = (i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_LOWH) << 8) + - i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_LOWL); - data->temp11[2] = (i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_HIGHH) << 8) + - i2c_smbus_read_byte_data(client, - LM90_REG_R_REMOTE_HIGHL); - data->alarms = i2c_smbus_read_byte_data(client, - LM90_REG_R_STATUS); + if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0 + && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) + data->temp11[1] = (newh << 8) | l; + if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 + && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) + data->temp11[2] = (newh << 8) | l; + lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); data->last_updated = jiffies; data->valid = 1; From c3df5806cdae6fac678c662b527cb974bef4b60c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 21:39:40 +0200 Subject: [PATCH 0762/1940] [PATCH] hwmon: Add PEC support to the lm90 driver Add PEC support to the lm90 driver. Only the ADM1032 chip supports it, and in a rather tricky way, which is why this patch comes with documentation reinforcements. At least, this demonstrates that the new PEC support logic in i2c-core can properly deal with chips with partial PEC support. As enabling PEC causes a significant performance drop, it can be disabled through a sysfs file (unsurprisingly named "pec"). Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/hwmon/lm90 | 39 +++++++++++++++++++- Documentation/hwmon/sysfs-interface | 3 ++ drivers/hwmon/lm90.c | 57 ++++++++++++++++++++++++++++- 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 2c4cf39471f4..70abf93ea376 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 @@ -71,8 +71,8 @@ increased resolution of the remote temperature measurement. The different chipsets of the family are not strictly identical, although very similar. This driver doesn't handle any specific feature for now, -but could if there ever was a need for it. For reference, here comes a -non-exhaustive list of specific features: +with the exception of SMBus PEC. For reference, here comes a non-exhaustive +list of specific features: LM90: * Filter and alert configuration register at 0xBF. @@ -91,6 +91,7 @@ ADM1032: * Conversion averaging. * Up to 64 conversions/s. * ALERT is triggered by open remote sensor. + * SMBus PEC support for Write Byte and Receive Byte transactions. ADT7461 * Extended temperature range (breaks compatibility) @@ -119,3 +120,37 @@ The lm90 driver will not update its values more frequently than every other second; reading them more often will do no harm, but will return 'old' values. +PEC Support +----------- + +The ADM1032 is the only chip of the family which supports PEC. It does +not support PEC on all transactions though, so some care must be taken. + +When reading a register value, the PEC byte is computed and sent by the +ADM1032 chip. However, in the case of a combined transaction (SMBus Read +Byte), the ADM1032 computes the CRC value over only the second half of +the message rather than its entirety, because it thinks the first half +of the message belongs to a different transaction. As a result, the CRC +value differs from what the SMBus master expects, and all reads fail. + +For this reason, the lm90 driver will enable PEC for the ADM1032 only if +the bus supports the SMBus Send Byte and Receive Byte transaction types. +These transactions will be used to read register values, instead of +SMBus Read Byte, and PEC will work properly. + +Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC. +Instead, it will try to write the PEC value to the register (because the +SMBus Send Byte transaction with PEC is similar to a Write Byte transaction +without PEC), which is not what we want. Thus, PEC is explicitely disabled +on SMBus Send Byte transactions in the lm90 driver. + +PEC on byte data transactions represents a significant increase in bandwidth +usage (+33% for writes, +25% for reads) in normal conditions. With the need +to use two SMBus transaction for reads, this overhead jumps to +50%. Worse, +two transactions will typically mean twice as much delay waiting for +transaction completion, effectively doubling the register cache refresh time. +I guess reliability comes at a price, but it's quite expensive this time. + +So, as not everyone might enjoy the slowdown, PEC can be disabled through +sysfs. Just write 0 to the "pec" file and PEC will be disabled. Write 1 +to that file to enable PEC again. diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index 346400519d0d..764cdc5480e7 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -272,3 +272,6 @@ beep_mask Bitmask for beep. eeprom Raw EEPROM data in binary form. Read only. + +pec Enable or disable PEC (SMBus only) + Read/Write diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 5acc12ae4e36..fa0793e684fd 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -345,15 +345,63 @@ static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +/* pec used for ADM1032 only */ +static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); +} + +static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + long val = simple_strtol(buf, NULL, 10); + + switch (val) { + case 0: + client->flags &= ~I2C_CLIENT_PEC; + break; + case 1: + client->flags |= I2C_CLIENT_PEC; + break; + default: + return -EINVAL; + } + + return count; +} + +static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); + /* * Real code */ +/* The ADM1032 supports PEC but not on write byte transactions, so we need + to explicitely ask for a transaction without PEC. */ +static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) +{ + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags & ~I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); +} + +/* It is assumed that client->update_lock is held (unless we are in + detection or initialization steps). This matters when PEC is enabled, + because we don't want the address pointer to change between the write + byte and the read byte transactions. */ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) { int err; - err = i2c_smbus_read_byte_data(client, reg); + if (client->flags & I2C_CLIENT_PEC) { + err = adm1032_write_byte(client, reg); + if (err >= 0) + err = i2c_smbus_read_byte(client); + } else + err = i2c_smbus_read_byte_data(client, reg); if (err < 0) { dev_warn(&client->dev, "Register %#02x read failed (%d)\n", @@ -494,6 +542,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) name = "lm90"; } else if (kind == adm1032) { name = "adm1032"; + /* The ADM1032 supports PEC, but only if combined + transactions are not used. */ + if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) + new_client->flags |= I2C_CLIENT_PEC; } else if (kind == lm99) { name = "lm99"; } else if (kind == lm86) { @@ -546,6 +598,9 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) &sensor_dev_attr_temp2_crit_hyst.dev_attr); device_create_file(&new_client->dev, &dev_attr_alarms); + if (new_client->flags & I2C_CLIENT_PEC) + device_create_file(&new_client->dev, &dev_attr_pec); + return 0; exit_detach: From 90209b42d0498d57a804bf81fea427bf39c5315c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 22:20:21 +0200 Subject: [PATCH 0763/1940] [PATCH] hwmon: lm90 documentation update Update the I2C addresses for the ADM1032 and ADT7461 chips. Also update the links to the Analog Devices web site. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/hwmon/lm90 | 8 ++++---- drivers/hwmon/lm90.c | 16 +++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 70abf93ea376..438cb24cee5b 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 @@ -24,14 +24,14 @@ Supported chips: http://www.national.com/pf/LM/LM86.html * Analog Devices ADM1032 Prefix: 'adm1032' - Addresses scanned: I2C 0x4c + Addresses scanned: I2C 0x4c and 0x4d Datasheet: Publicly available at the Analog Devices website - http://products.analog.com/products/info.asp?product=ADM1032 + http://www.analog.com/en/prod/0,2877,ADM1032,00.html * Analog Devices ADT7461 Prefix: 'adt7461' - Addresses scanned: I2C 0x4c + Addresses scanned: I2C 0x4c and 0x4d Datasheet: Publicly available at the Analog Devices website - http://products.analog.com/products/info.asp?product=ADT7461 + http://www.analog.com/en/prod/0,2877,ADT7461,00.html Note: Only if in ADM1032 compatibility mode * Maxim MAX6657 Prefix: 'max6657' diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index fa0793e684fd..83cf2e1b09f5 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -31,7 +31,7 @@ * Devices. That chip is similar to the LM90, with a few differences * that are not handled by this driver. Complete datasheet can be * obtained from Analog's website at: - * http://products.analog.com/products/info.asp?product=ADM1032 + * http://www.analog.com/en/prod/0,2877,ADM1032,00.html * Among others, it has a higher accuracy than the LM90, much like the * LM86 does. * @@ -49,7 +49,7 @@ * register values are decoded differently) it is ignored by this * driver. Complete datasheet can be obtained from Analog's website * at: - * http://products.analog.com/products/info.asp?product=ADT7461 + * http://www.analog.com/en/prod/0,2877,ADT7461,00.html * * Since the LM90 was the first chipset supported by this driver, most * comments will refer to this chipset, but are actually general and @@ -83,10 +83,10 @@ * Addresses to scan * Address is fully defined internally and cannot be changed except for * MAX6659. - * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c. - * LM89-1, and LM99-1 have address 0x4d. + * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 + * have address 0x4c. + * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). - * ADT7461 always has address 0x4c. */ static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; @@ -500,14 +500,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) } } else if (man_id == 0x41) { /* Analog Devices */ - if (address == 0x4C - && (chip_id & 0xF0) == 0x40 /* ADM1032 */ + if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ && (reg_config1 & 0x3F) == 0x00 && reg_convrate <= 0x0A) { kind = adm1032; } else - if (address == 0x4c - && chip_id == 0x51 /* ADT7461 */ + if (chip_id == 0x51 /* ADT7461 */ && (reg_config1 & 0x1F) == 0x00 /* check compat mode */ && reg_convrate <= 0x0A) { kind = adt7461; From b890a07f7b002ee473986fa85ae3582de399a4cf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 Oct 2005 22:21:24 +0200 Subject: [PATCH 0764/1940] [PATCH] hwmon: smsc47m1 documentation update The SMSC LPC47M997 Super-I/O chip seems to be compatible with the LPC47M192, so it is supported by the smsc47m1 driver. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/hwmon/smsc47m1 | 7 +++++++ drivers/hwmon/smsc47m1.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/hwmon/smsc47m1 b/Documentation/hwmon/smsc47m1 index 34e6478c1425..c15bbe68264e 100644 --- a/Documentation/hwmon/smsc47m1 +++ b/Documentation/hwmon/smsc47m1 @@ -12,6 +12,10 @@ Supported chips: http://www.smsc.com/main/datasheets/47m14x.pdf http://www.smsc.com/main/tools/discontinued/47m15x.pdf http://www.smsc.com/main/datasheets/47m192.pdf + * SMSC LPC47M997 + Addresses scanned: none, address read from Super I/O config space + Prefix: 'smsc47m1' + Datasheet: none Authors: Mark D. Studebaker , @@ -30,6 +34,9 @@ The 47M15x and 47M192 chips contain a full 'hardware monitoring block' in addition to the fan monitoring and control. The hardware monitoring block is not supported by the driver. +No documentation is available for the 47M997, but it has the same device +ID as the 47M15x and 47M192 chips and seems to be compatible. + Fan rotation speeds are reported in RPM (rotations per minute). An alarm is triggered if the rotation speed has dropped below a programmable limit. Fan readings can be divided by a programmable divider (1, 2, 4 or 8) to give diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index bbe93a0688ec..5905c1af88f2 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -3,7 +3,7 @@ for hardware monitoring Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, - LPC47M15x and LPC47M192 Super-I/O chips. + LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. Copyright (C) 2002 Mark D. Studebaker Copyright (C) 2004 Jean Delvare @@ -356,6 +356,8 @@ static int __init smsc47m1_find(unsigned short *addr) * 0x5F) and LPC47B27x (device id 0x51) have fan control. * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" * can do much more besides (device id 0x60). + * The LPC47M997 is undocumented, but seems to be compatible with + * the LPC47M192, and has the same device id. */ if (val == 0x51) printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); @@ -364,7 +366,8 @@ static int __init smsc47m1_find(unsigned short *addr) else if (val == 0x5F) printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); else if (val == 0x60) - printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n"); + printk(KERN_INFO "smsc47m1: Found SMSC " + "LPC47M15x/LPC47M192/LPC47M997\n"); else { superio_exit(); return -ENODEV; From 0dc9a32d9a975ccd25b9f531451165c93e1c7313 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 22 Oct 2005 00:23:27 +0200 Subject: [PATCH 0765/1940] [PATCH] I2C: remove devfs support from i2c-dev driver as devfs is gone, this isn't needed anymore. Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-dev.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 276ec42a0717..ea14c8f1c82b 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -26,15 +26,11 @@ /* The I2C_RDWR ioctl code is written by Kolja Waschk */ -/* The devfs code is contributed by Philipp Matthias Hahn - */ - #include #include #include #include #include -#include #include #include #include @@ -431,8 +427,6 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) if (IS_ERR(i2c_dev)) return PTR_ERR(i2c_dev); - devfs_mk_cdev(MKDEV(I2C_MAJOR, i2c_dev->minor), - S_IFCHR|S_IRUSR|S_IWUSR, "i2c/%d", i2c_dev->minor); pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", adap->name, i2c_dev->minor); @@ -465,7 +459,6 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) return -ENODEV; init_completion(&i2c_dev->released); - devfs_remove("i2c/%d", i2c_dev->minor); return_i2c_dev(i2c_dev); class_device_unregister(&i2c_dev->class_dev); wait_for_completion(&i2c_dev->released); @@ -521,8 +514,6 @@ static int __init i2c_dev_init(void) if (res) goto out_unreg_class; - devfs_mk_dir("i2c"); - return 0; out_unreg_class: @@ -538,7 +529,6 @@ static void __exit i2c_dev_exit(void) { i2c_del_driver(&i2cdev_driver); class_unregister(&i2c_dev_class); - devfs_remove("i2c"); unregister_chrdev(I2C_MAJOR,"i2c"); } From a9d1b24d91f91b77db3da8aeacb414764f789b9c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 22 Oct 2005 00:23:27 +0200 Subject: [PATCH 0766/1940] [PATCH] I2C: add i2c module alias for i2c drivers to use This is the start of adding hotplug-like support for i2c devices. Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c.h | 1 + include/linux/mod_devicetable.h | 5 +++++ scripts/mod/file2alias.c | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 32977fb1d99a..f88577ca3b3a 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -29,6 +29,7 @@ #include #include #include +#include #include /* for struct device */ #include diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 2f0299a448f6..7b08c11ec4cc 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -244,4 +244,9 @@ struct pcmcia_device_id { #define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200 #define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400 +/* I2C */ +struct i2c_device_id { + __u16 id; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f2ee673329a7..e3d144a3f10b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -359,6 +359,13 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio, return 1; } +static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *alias) +{ + strcpy(alias, "i2c:"); + ADD(alias, "id", 1, i2c->id); + return 1; +} + /* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -443,6 +450,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(symname, "__mod_vio_device_table")) do_table(symval, sym->st_size, sizeof(struct vio_device_id), do_vio_entry, mod); + else if (sym_is(symname, "__mod_i2c_device_table")) + do_table(symval, sym->st_size, sizeof(struct i2c_device_id), + do_i2c_entry, mod); } From c45154a3b1fecdbb51b5462c9f730b44e62b83a5 Mon Sep 17 00:00:00 2001 From: Ed Kear Date: Sat, 16 Jul 2005 23:32:19 -0400 Subject: [PATCH 0767/1940] [PATCH] libata: add support for Promise SATA 300 TX2plus PDC40775 I'm using this card in a RAID1 with 2 new SATA drives with no problems. Card - SATA 300 TX2plus PDC40775 (3d73) Signed-off-by: Ed Kear Signed-off-by: Jeff Garzik --- drivers/scsi/sata_promise.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 50495569f409..63911f16b6ec 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -209,6 +209,8 @@ static struct pci_device_id pdc_ata_pci_tbl[] = { board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, From eaa5c54dbec70e2a93d6ed412bb589bbf9c90a17 Mon Sep 17 00:00:00 2001 From: Ivan Skytte Jorgensen Date: Fri, 28 Oct 2005 15:10:00 -0700 Subject: [PATCH 0768/1940] [SCTP] Rename SCTP specific control message flags. Rename SCTP specific control message flags to use SCTP_ prefix rather than MSG_ prefix as per the latest sctp sockets API draft. Signed-off-by: Ivan Skytte Jorgensen Signed-off-by: Sridhar Samudrala --- include/net/sctp/user.h | 8 ++++---- net/sctp/sm_make_chunk.c | 2 +- net/sctp/socket.c | 32 ++++++++++++++++---------------- net/sctp/ulpevent.c | 6 +++--- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 1c5f19f995ad..f1c3bc54526a 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -171,10 +171,10 @@ struct sctp_sndrcvinfo { */ enum sctp_sinfo_flags { - MSG_UNORDERED = 1, /* Send/receive message unordered. */ - MSG_ADDR_OVER = 2, /* Override the primary destination. */ - MSG_ABORT=4, /* Send an ABORT message to the peer. */ - /* MSG_EOF is already defined per socket.h */ + SCTP_UNORDERED = 1, /* Send/receive message unordered. */ + SCTP_ADDR_OVER = 2, /* Override the primary destination. */ + SCTP_ABORT=4, /* Send an ABORT message to the peer. */ + SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ }; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 10e82ec2ebd3..660c61bdf164 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -554,7 +554,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, dp.ppid = sinfo->sinfo_ppid; /* Set the flags for an unordered send. */ - if (sinfo->sinfo_flags & MSG_UNORDERED) { + if (sinfo->sinfo_flags & SCTP_UNORDERED) { flags |= SCTP_DATA_UNORDERED; dp.ssn = 0; } else diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 02e068d3450d..170045b6ee98 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1389,27 +1389,27 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", msg_len, sinfo_flags); - /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */ - if (sctp_style(sk, TCP) && (sinfo_flags & (MSG_EOF | MSG_ABORT))) { + /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */ + if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) { err = -EINVAL; goto out_nounlock; } - /* If MSG_EOF is set, no data can be sent. Disallow sending zero - * length messages when MSG_EOF|MSG_ABORT is not set. - * If MSG_ABORT is set, the message length could be non zero with + /* If SCTP_EOF is set, no data can be sent. Disallow sending zero + * length messages when SCTP_EOF|SCTP_ABORT is not set. + * If SCTP_ABORT is set, the message length could be non zero with * the msg_iov set to the user abort reason. */ - if (((sinfo_flags & MSG_EOF) && (msg_len > 0)) || - (!(sinfo_flags & (MSG_EOF|MSG_ABORT)) && (msg_len == 0))) { + if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) || + (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) { err = -EINVAL; goto out_nounlock; } - /* If MSG_ADDR_OVER is set, there must be an address + /* If SCTP_ADDR_OVER is set, there must be an address * specified in msg_name. */ - if ((sinfo_flags & MSG_ADDR_OVER) && (!msg->msg_name)) { + if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) { err = -EINVAL; goto out_nounlock; } @@ -1458,14 +1458,14 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, goto out_unlock; } - if (sinfo_flags & MSG_EOF) { + if (sinfo_flags & SCTP_EOF) { SCTP_DEBUG_PRINTK("Shutting down association: %p\n", asoc); sctp_primitive_SHUTDOWN(asoc, NULL); err = 0; goto out_unlock; } - if (sinfo_flags & MSG_ABORT) { + if (sinfo_flags & SCTP_ABORT) { SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); sctp_primitive_ABORT(asoc, msg); err = 0; @@ -1477,7 +1477,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, if (!asoc) { SCTP_DEBUG_PRINTK("There is no association yet.\n"); - if (sinfo_flags & (MSG_EOF | MSG_ABORT)) { + if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) { err = -EINVAL; goto out_unlock; } @@ -1611,10 +1611,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, /* If an address is passed with the sendto/sendmsg call, it is used * to override the primary destination address in the TCP model, or - * when MSG_ADDR_OVER flag is set in the UDP model. + * when SCTP_ADDR_OVER flag is set in the UDP model. */ if ((sctp_style(sk, TCP) && msg_name) || - (sinfo_flags & MSG_ADDR_OVER)) { + (sinfo_flags & SCTP_ADDR_OVER)) { chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); if (!chunk_tp) { err = -EINVAL; @@ -4640,8 +4640,8 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, /* Minimally, validate the sinfo_flags. */ if (cmsgs->info->sinfo_flags & - ~(MSG_UNORDERED | MSG_ADDR_OVER | - MSG_ABORT | MSG_EOF)) + ~(SCTP_UNORDERED | SCTP_ADDR_OVER | + SCTP_ABORT | SCTP_EOF)) return -EINVAL; break; diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 057e7fac3af0..e049f41faa47 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -698,7 +698,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, event->ssn = ntohs(chunk->subh.data_hdr->ssn); event->ppid = chunk->subh.data_hdr->ppid; if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { - event->flags |= MSG_UNORDERED; + event->flags |= SCTP_UNORDERED; event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); } event->tsn = ntohl(chunk->subh.data_hdr->tsn); @@ -824,7 +824,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, * * recvmsg() flags: * - * MSG_UNORDERED - This flag is present when the message was sent + * SCTP_UNORDERED - This flag is present when the message was sent * non-ordered. */ sinfo.sinfo_flags = event->flags; @@ -839,7 +839,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, * This field will hold the current cumulative TSN as * known by the underlying SCTP layer. Note this field is * ignored when sending and only valid for a receive - * operation when sinfo_flags are set to MSG_UNORDERED. + * operation when sinfo_flags are set to SCTP_UNORDERED. */ sinfo.sinfo_cumtsn = event->cumtsn; /* sinfo_assoc_id: sizeof (sctp_assoc_t) From 28f22b031f8959cdf53202cd9f6ca8b9ce19b3a6 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Oct 2005 17:22:18 -0500 Subject: [PATCH 0769/1940] [SCSI] qla2xxx: put back label erroneously removed by eh_active patch The label eh_dev_reset_done is still in use Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 92976c235ee2..d9eccdf4f403 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -774,7 +774,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun); - + eh_dev_reset_done: return ret; } From b5141128027c53b8ca40736d969f75c9a1cdb64b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 28 Oct 2005 22:07:41 +0200 Subject: [PATCH 0770/1940] [SCSI] mptsas: support link error attributes .. and the fusion part. I had to move around the debug functions around a little bit so they are below the transport class methods. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 242 +++++++++++++++++++++----------- 1 file changed, 161 insertions(+), 81 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 7de19a84dc74..6512027bc69a 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -123,6 +123,101 @@ struct mptsas_portinfo { struct mptsas_phyinfo *phy_info; }; + +#ifdef SASDEBUG +static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) +{ + printk("---- IO UNIT PAGE 0 ------------\n"); + printk("Handle=0x%X\n", + le16_to_cpu(phy_data->AttachedDeviceHandle)); + printk("Controller Handle=0x%X\n", + le16_to_cpu(phy_data->ControllerDevHandle)); + printk("Port=0x%X\n", phy_data->Port); + printk("Port Flags=0x%X\n", phy_data->PortFlags); + printk("PHY Flags=0x%X\n", phy_data->PhyFlags); + printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate); + printk("Controller PHY Device Info=0x%X\n", + le32_to_cpu(phy_data->ControllerPhyDeviceInfo)); + printk("DiscoveryStatus=0x%X\n", + le32_to_cpu(phy_data->DiscoveryStatus)); + printk("\n"); +} + +static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0) +{ + __le64 sas_address; + + memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); + + printk("---- SAS PHY PAGE 0 ------------\n"); + printk("Attached Device Handle=0x%X\n", + le16_to_cpu(pg0->AttachedDevHandle)); + printk("SAS Address=0x%llX\n", + (unsigned long long)le64_to_cpu(sas_address)); + printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier); + printk("Attached Device Info=0x%X\n", + le32_to_cpu(pg0->AttachedDeviceInfo)); + printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate); + printk("Change Count=0x%X\n", pg0->ChangeCount); + printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo)); + printk("\n"); +} + +static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1) +{ + printk("---- SAS PHY PAGE 1 ------------\n"); + printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount); + printk("Running Disparity Error Count=0x%x\n", + pg1->RunningDisparityErrorCount); + printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount); + printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount); + printk("\n"); +} + +static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) +{ + __le64 sas_address; + + memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); + + printk("---- SAS DEVICE PAGE 0 ---------\n"); + printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); + printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); + printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); + printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); + printk("Target ID=0x%X\n", pg0->TargetID); + printk("Bus=0x%X\n", pg0->Bus); + printk("PhyNum=0x%X\n", pg0->PhyNum); + printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus)); + printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)); + printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags)); + printk("Physical Port=0x%X\n", pg0->PhysicalPort); + printk("\n"); +} + +static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) +{ + printk("---- SAS EXPANDER PAGE 1 ------------\n"); + + printk("Physical Port=0x%X\n", pg1->PhysicalPort); + printk("PHY Identifier=0x%X\n", pg1->Phy); + printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate); + printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate); + printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate); + printk("Owner Device Handle=0x%X\n", + le16_to_cpu(pg1->OwnerDevHandle)); + printk("Attached Device Handle=0x%X\n", + le16_to_cpu(pg1->AttachedDevHandle)); +} +#else +#define mptsas_print_phy_data(phy_data) do { } while (0) +#define mptsas_print_phy_pg0(pg0) do { } while (0) +#define mptsas_print_phy_pg1(pg1) do { } while (0) +#define mptsas_print_device_pg0(pg0) do { } while (0) +#define mptsas_print_expander_pg1(pg1) do { } while (0) +#endif + + /* * This is pretty ugly. We will be able to seriously clean it up * once the DV code in mptscsih goes away and we can properly @@ -200,92 +295,77 @@ static struct scsi_host_template mptsas_driver_template = { .use_clustering = ENABLE_CLUSTERING, }; +static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy) +{ + struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); + return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; +} + +static int mptsas_get_linkerrors(struct sas_phy *phy) +{ + MPT_ADAPTER *ioc = phy_to_ioc(phy); + ConfigExtendedPageHeader_t hdr; + CONFIGPARMS cfg; + SasPhyPage1_t *buffer; + dma_addr_t dma_handle; + int error; + + hdr.PageVersion = MPI_SASPHY1_PAGEVERSION; + hdr.ExtPageLength = 0; + hdr.PageNumber = 1 /* page number 1*/; + hdr.Reserved1 = 0; + hdr.Reserved2 = 0; + hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; + hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY; + + cfg.cfghdr.ehdr = &hdr; + cfg.physAddr = -1; + cfg.pageAddr = phy->identify.phy_identifier; + cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; + cfg.dir = 0; /* read */ + cfg.timeout = 10; + + error = mpt_config(ioc, &cfg); + if (error) + return error; + if (!hdr.ExtPageLength) + return -ENXIO; + + buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, + &dma_handle); + if (!buffer) + return -ENOMEM; + + cfg.physAddr = dma_handle; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + + error = mpt_config(ioc, &cfg); + if (error) + goto out_free_consistent; + + mptsas_print_phy_pg1(buffer); + + phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount); + phy->running_disparity_error_count = + le32_to_cpu(buffer->RunningDisparityErrorCount); + phy->loss_of_dword_sync_count = + le32_to_cpu(buffer->LossDwordSynchCount); + phy->phy_reset_problem_count = + le32_to_cpu(buffer->PhyResetProblemCount); + + out_free_consistent: + pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, + buffer, dma_handle); + return error; +} + + static struct sas_function_template mptsas_transport_functions = { + .get_linkerrors = mptsas_get_linkerrors, }; static struct scsi_transport_template *mptsas_transport_template; -#ifdef SASDEBUG -static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) -{ - printk("---- IO UNIT PAGE 0 ------------\n"); - printk("Handle=0x%X\n", - le16_to_cpu(phy_data->AttachedDeviceHandle)); - printk("Controller Handle=0x%X\n", - le16_to_cpu(phy_data->ControllerDevHandle)); - printk("Port=0x%X\n", phy_data->Port); - printk("Port Flags=0x%X\n", phy_data->PortFlags); - printk("PHY Flags=0x%X\n", phy_data->PhyFlags); - printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate); - printk("Controller PHY Device Info=0x%X\n", - le32_to_cpu(phy_data->ControllerPhyDeviceInfo)); - printk("DiscoveryStatus=0x%X\n", - le32_to_cpu(phy_data->DiscoveryStatus)); - printk("\n"); -} - -static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0) -{ - __le64 sas_address; - - memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); - - printk("---- SAS PHY PAGE 0 ------------\n"); - printk("Attached Device Handle=0x%X\n", - le16_to_cpu(pg0->AttachedDevHandle)); - printk("SAS Address=0x%llX\n", - (unsigned long long)le64_to_cpu(sas_address)); - printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier); - printk("Attached Device Info=0x%X\n", - le32_to_cpu(pg0->AttachedDeviceInfo)); - printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate); - printk("Change Count=0x%X\n", pg0->ChangeCount); - printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo)); - printk("\n"); -} - -static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) -{ - __le64 sas_address; - - memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); - - printk("---- SAS DEVICE PAGE 0 ---------\n"); - printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); - printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); - printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); - printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); - printk("Target ID=0x%X\n", pg0->TargetID); - printk("Bus=0x%X\n", pg0->Bus); - printk("Parent Phy Num=0x%X\n", pg0->PhyNum); - printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus)); - printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)); - printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags)); - printk("Physical Port=0x%X\n", pg0->PhysicalPort); - printk("\n"); -} - -static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) -{ - printk("---- SAS EXPANDER PAGE 1 ------------\n"); - - printk("Physical Port=0x%X\n", pg1->PhysicalPort); - printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier); - printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate); - printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate); - printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate); - printk("Owner Device Handle=0x%X\n", - le16_to_cpu(pg1->OwnerDevHandle)); - printk("Attached Device Handle=0x%X\n", - le16_to_cpu(pg1->AttachedDevHandle)); -} -#else -#define mptsas_print_phy_data(phy_data) do { } while (0) -#define mptsas_print_phy_pg0(pg0) do { } while (0) -#define mptsas_print_device_pg0(pg0) do { } while (0) -#define mptsas_print_expander_pg1(pg1) do { } while (0) -#endif - static int mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) { From 1993d683f39f77ddb46a662d7146247877d50b8f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 28 Oct 2005 15:30:34 -0700 Subject: [PATCH 0771/1940] [IPoIB] Drop RX packets when out of memory Change the way IPoIB handles RX packets when it can't allocate a new receive skbuff. If the allocation of a new receive skb fails, we now drop the packet we just received and repost the original receive skb. This means that the receive ring always stays full and we don't have to monkey around with trying to schedule a refill task for later. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib.h | 21 ++-- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 128 +++++++++++++--------- drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 +- 3 files changed, 91 insertions(+), 66 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 6b14bd1c60a0..c994a916a58a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -100,7 +100,12 @@ struct ipoib_pseudoheader { struct ipoib_mcast; -struct ipoib_buf { +struct ipoib_rx_buf { + struct sk_buff *skb; + dma_addr_t mapping; +}; + +struct ipoib_tx_buf { struct sk_buff *skb; DECLARE_PCI_UNMAP_ADDR(mapping) }; @@ -150,14 +155,14 @@ struct ipoib_dev_priv { unsigned int admin_mtu; unsigned int mcast_mtu; - struct ipoib_buf *rx_ring; + struct ipoib_rx_buf *rx_ring; - spinlock_t tx_lock; - struct ipoib_buf *tx_ring; - unsigned tx_head; - unsigned tx_tail; - struct ib_sge tx_sge; - struct ib_send_wr tx_wr; + spinlock_t tx_lock; + struct ipoib_tx_buf *tx_ring; + unsigned tx_head; + unsigned tx_tail; + struct ib_sge tx_sge; + struct ib_send_wr tx_wr; struct ib_wc ibwc[IPOIB_NUM_WC]; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 02d0e0006578..192fef884e21 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -95,65 +95,77 @@ void ipoib_free_ah(struct kref *kref) } } -static inline int ipoib_ib_receive(struct ipoib_dev_priv *priv, - unsigned int wr_id, - dma_addr_t addr) -{ - struct ib_sge list = { - .addr = addr, - .length = IPOIB_BUF_SIZE, - .lkey = priv->mr->lkey, - }; - struct ib_recv_wr param = { - .wr_id = wr_id | IPOIB_OP_RECV, - .sg_list = &list, - .num_sge = 1, - }; - struct ib_recv_wr *bad_wr; - - return ib_post_recv(priv->qp, ¶m, &bad_wr); -} - static int ipoib_ib_post_receive(struct net_device *dev, int id) { struct ipoib_dev_priv *priv = netdev_priv(dev); - struct sk_buff *skb; - dma_addr_t addr; + struct ib_sge list; + struct ib_recv_wr param; + struct ib_recv_wr *bad_wr; int ret; - skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4); - if (!skb) { - ipoib_warn(priv, "failed to allocate receive buffer\n"); + list.addr = priv->rx_ring[id].mapping; + list.length = IPOIB_BUF_SIZE; + list.lkey = priv->mr->lkey; - priv->rx_ring[id].skb = NULL; - return -ENOMEM; - } - skb_reserve(skb, 4); /* 16 byte align IP header */ - priv->rx_ring[id].skb = skb; - addr = dma_map_single(priv->ca->dma_device, - skb->data, IPOIB_BUF_SIZE, - DMA_FROM_DEVICE); - pci_unmap_addr_set(&priv->rx_ring[id], mapping, addr); + param.next = NULL; + param.wr_id = id | IPOIB_OP_RECV; + param.sg_list = &list; + param.num_sge = 1; - ret = ipoib_ib_receive(priv, id, addr); - if (ret) { - ipoib_warn(priv, "ipoib_ib_receive failed for buf %d (%d)\n", - id, ret); - dma_unmap_single(priv->ca->dma_device, addr, + ret = ib_post_recv(priv->qp, ¶m, &bad_wr); + if (unlikely(ret)) { + ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret); + dma_unmap_single(priv->ca->dma_device, + priv->rx_ring[id].mapping, IPOIB_BUF_SIZE, DMA_FROM_DEVICE); - dev_kfree_skb_any(skb); + dev_kfree_skb_any(priv->rx_ring[id].skb); priv->rx_ring[id].skb = NULL; } return ret; } +static int ipoib_alloc_rx_skb(struct net_device *dev, int id) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + struct sk_buff *skb; + dma_addr_t addr; + + skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4); + if (!skb) + return -ENOMEM; + + /* + * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte + * header. So we need 4 more bytes to get to 48 and align the + * IP header to a multiple of 16. + */ + skb_reserve(skb, 4); + + addr = dma_map_single(priv->ca->dma_device, + skb->data, IPOIB_BUF_SIZE, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(addr))) { + dev_kfree_skb_any(skb); + return -EIO; + } + + priv->rx_ring[id].skb = skb; + priv->rx_ring[id].mapping = addr; + + return 0; +} + static int ipoib_ib_post_receives(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); int i; for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) { + if (ipoib_alloc_rx_skb(dev, i)) { + ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); + return -ENOMEM; + } if (ipoib_ib_post_receive(dev, i)) { ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i); return -EIO; @@ -176,28 +188,36 @@ static void ipoib_ib_handle_wc(struct net_device *dev, wr_id &= ~IPOIB_OP_RECV; if (wr_id < IPOIB_RX_RING_SIZE) { - struct sk_buff *skb = priv->rx_ring[wr_id].skb; + struct sk_buff *skb = priv->rx_ring[wr_id].skb; + dma_addr_t addr = priv->rx_ring[wr_id].mapping; - priv->rx_ring[wr_id].skb = NULL; - - dma_unmap_single(priv->ca->dma_device, - pci_unmap_addr(&priv->rx_ring[wr_id], - mapping), - IPOIB_BUF_SIZE, - DMA_FROM_DEVICE); - - if (wc->status != IB_WC_SUCCESS) { + if (unlikely(wc->status != IB_WC_SUCCESS)) { if (wc->status != IB_WC_WR_FLUSH_ERR) ipoib_warn(priv, "failed recv event " "(status=%d, wrid=%d vend_err %x)\n", wc->status, wr_id, wc->vendor_err); + dma_unmap_single(priv->ca->dma_device, addr, + IPOIB_BUF_SIZE, DMA_FROM_DEVICE); dev_kfree_skb_any(skb); + priv->rx_ring[wr_id].skb = NULL; return; } + /* + * If we can't allocate a new RX buffer, dump + * this packet and reuse the old buffer. + */ + if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) { + ++priv->stats.rx_dropped; + goto repost; + } + ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", wc->byte_len, wc->slid); + dma_unmap_single(priv->ca->dma_device, addr, + IPOIB_BUF_SIZE, DMA_FROM_DEVICE); + skb_put(skb, wc->byte_len); skb_pull(skb, IB_GRH_BYTES); @@ -220,8 +240,8 @@ static void ipoib_ib_handle_wc(struct net_device *dev, dev_kfree_skb_any(skb); } - /* repost receive */ - if (ipoib_ib_post_receive(dev, wr_id)) + repost: + if (unlikely(ipoib_ib_post_receive(dev, wr_id))) ipoib_warn(priv, "ipoib_ib_post_receive failed " "for buf %d\n", wr_id); } else @@ -229,7 +249,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev, wr_id); } else { - struct ipoib_buf *tx_req; + struct ipoib_tx_buf *tx_req; unsigned long flags; if (wr_id >= IPOIB_TX_RING_SIZE) { @@ -302,7 +322,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_ah *address, u32 qpn) { struct ipoib_dev_priv *priv = netdev_priv(dev); - struct ipoib_buf *tx_req; + struct ipoib_tx_buf *tx_req; dma_addr_t addr; if (skb->len > dev->mtu + INFINIBAND_ALEN) { @@ -468,7 +488,7 @@ int ipoib_ib_dev_stop(struct net_device *dev) struct ib_qp_attr qp_attr; int attr_mask; unsigned long begin; - struct ipoib_buf *tx_req; + struct ipoib_tx_buf *tx_req; int i; /* Kill the existing QP and allocate a new one */ diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index ee303859b044..cd4f42328dbe 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -732,7 +732,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) /* Allocate RX/TX "rings" to hold queued skbs */ - priv->rx_ring = kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf), + priv->rx_ring = kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf), GFP_KERNEL); if (!priv->rx_ring) { printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", @@ -740,9 +740,9 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) goto out; } memset(priv->rx_ring, 0, - IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf)); + IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf)); - priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf), + priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf), GFP_KERNEL); if (!priv->tx_ring) { printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", @@ -750,7 +750,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) goto out_rx_ring_cleanup; } memset(priv->tx_ring, 0, - IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf)); + IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf)); /* priv->tx_head & tx_tail are already 0 */ From a1ab3582699def352dab1355adcadd3d47f79f0f Mon Sep 17 00:00:00 2001 From: Ivan Skytte Jorgensen Date: Fri, 28 Oct 2005 15:33:24 -0700 Subject: [PATCH 0772/1940] [SCTP] Fix SCTP_SETADAPTION sockopt to use the correct structure. Signed-off-by: Ivan Skytte Jorgensen Signed-off-by: Sridhar Samudrala --- net/sctp/socket.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 170045b6ee98..c66c161908c0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2384,14 +2384,14 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, int optlen) { - __u32 val; + struct sctp_setadaption adaption; - if (optlen < sizeof(__u32)) + if (optlen != sizeof(struct sctp_setadaption)) return -EINVAL; - if (copy_from_user(&val, optval, sizeof(__u32))) + if (copy_from_user(&adaption, optval, optlen)) return -EFAULT; - sctp_sk(sk)->adaption_ind = val; + sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind; return 0; } @@ -3672,17 +3672,15 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, char __user *optval, int __user *optlen) { - __u32 val; + struct sctp_setadaption adaption; - if (len < sizeof(__u32)) + if (len != sizeof(struct sctp_setadaption)) return -EINVAL; - len = sizeof(__u32); - val = sctp_sk(sk)->adaption_ind; - if (put_user(len, optlen)) - return -EFAULT; - if (copy_to_user(optval, &val, len)) + adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind; + if (copy_to_user(optval, &adaption, len)) return -EFAULT; + return 0; } From 96a339985d4c6874d32909e8f1903e6e6c141399 Mon Sep 17 00:00:00 2001 From: Ivan Skytte Jorgensen Date: Fri, 28 Oct 2005 15:36:12 -0700 Subject: [PATCH 0773/1940] [SCTP] Allow SCTP_MAXSEG to revert to default frag point with a '0' value. Signed-off-by: Ivan Skytte Jorgensen Signed-off-by: Sridhar Samudrala --- net/sctp/socket.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c66c161908c0..97b556c1c450 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2306,16 +2306,14 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl return -EINVAL; if (get_user(val, (int __user *)optval)) return -EFAULT; - if ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)) + if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))) return -EINVAL; sp->user_frag = val; - if (val) { - /* Update the frag_point of the existing associations. */ - list_for_each(pos, &(sp->ep->asocs)) { - asoc = list_entry(pos, struct sctp_association, asocs); - asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); - } + /* Update the frag_point of the existing associations. */ + list_for_each(pos, &(sp->ep->asocs)) { + asoc = list_entry(pos, struct sctp_association, asocs); + asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); } return 0; From 2cea752f683af1be58ee8f25717c0a8118e0ac5b Mon Sep 17 00:00:00 2001 From: "R.Marek@sh.cvut.cz" Date: Tue, 27 Sep 2005 21:54:51 +0000 Subject: [PATCH 0774/1940] [PATCH] PCI: ICH6 ACPI and GPIO quirk This patch just adds ACPI and GPIO regions to its LPC bridge, similar way as ICH4 did. I would like to thank Michal Mleczko for testing. Signed-off-by: Rudolf Marek Signed-off-by: Greg Kroah-Hartman drivers/pci/quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) --- drivers/pci/quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7992bc8cc6a4..0663428a0e64 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -414,6 +414,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi ); +static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) +{ + u32 region; + + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO"); + + pci_read_config_dword(dev, 0x48, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); + /* * VIA ACPI: One IO region pointed to by longword at * 0x48 or 0x20 (256 bytes of ACPI registers) From e04b0ea2e0f9c1bb0d874db4493fc7f7a623116b Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 27 Sep 2005 01:21:55 -0700 Subject: [PATCH 0775/1940] [PATCH] PCI: Block config access during BIST Some PCI adapters (eg. ipr scsi adapters) have an exposure today in that they issue BIST to the adapter to reset the card. If, during the time it takes to complete BIST, userspace attempts to access PCI config space, the host bus bridge will master abort the access since the ipr adapter does not respond on the PCI bus for a brief period of time when running BIST. On PPC64 hardware, this master abort results in the host PCI bridge isolating that PCI device from the rest of the system, making the device unusable until Linux is rebooted. This patch is an attempt to close that exposure by introducing some blocking code in the PCI code. When blocked, writes will be humored and reads will return the cached value. Ben Herrenschmidt has also mentioned that he plans to use this in PPC power management. Signed-off-by: Brian King Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman drivers/pci/access.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 20 +++++----- drivers/pci/pci.h | 7 +++ drivers/pci/proc.c | 28 +++++++-------- drivers/pci/syscall.c | 14 +++---- include/linux/pci.h | 7 +++ 6 files changed, 134 insertions(+), 31 deletions(-) --- drivers/pci/access.c | 89 +++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 20 ++++----- drivers/pci/pci.h | 7 ++++ drivers/pci/proc.c | 28 ++++++------- drivers/pci/syscall.c | 14 +++---- include/linux/pci.h | 7 ++++ 6 files changed, 134 insertions(+), 31 deletions(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 24a76de49f41..2a42add7f563 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -60,3 +60,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword); EXPORT_SYMBOL(pci_bus_write_config_byte); EXPORT_SYMBOL(pci_bus_write_config_word); EXPORT_SYMBOL(pci_bus_write_config_dword); + +static u32 pci_user_cached_config(struct pci_dev *dev, int pos) +{ + u32 data; + + data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])]; + data >>= (pos % sizeof(dev->saved_config_space[0])) * 8; + return data; +} + +#define PCI_USER_READ_CONFIG(size,type) \ +int pci_user_read_config_##size \ + (struct pci_dev *dev, int pos, type *val) \ +{ \ + unsigned long flags; \ + int ret = 0; \ + u32 data = -1; \ + if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->read(dev->bus, dev->devfn, \ + pos, sizeof(type), &data); \ + else if (pos < sizeof(dev->saved_config_space)) \ + data = pci_user_cached_config(dev, pos); \ + spin_unlock_irqrestore(&pci_lock, flags); \ + *val = (type)data; \ + return ret; \ +} + +#define PCI_USER_WRITE_CONFIG(size,type) \ +int pci_user_write_config_##size \ + (struct pci_dev *dev, int pos, type val) \ +{ \ + unsigned long flags; \ + int ret = -EIO; \ + if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->write(dev->bus, dev->devfn, \ + pos, sizeof(type), val); \ + spin_unlock_irqrestore(&pci_lock, flags); \ + return ret; \ +} + +PCI_USER_READ_CONFIG(byte, u8) +PCI_USER_READ_CONFIG(word, u16) +PCI_USER_READ_CONFIG(dword, u32) +PCI_USER_WRITE_CONFIG(byte, u8) +PCI_USER_WRITE_CONFIG(word, u16) +PCI_USER_WRITE_CONFIG(dword, u32) + +/** + * pci_block_user_cfg_access - Block userspace PCI config reads/writes + * @dev: pci device struct + * + * This function blocks any userspace PCI config accesses from occurring. + * When blocked, any writes will be bit bucketed and reads will return the + * data saved using pci_save_state for the first 64 bytes of config + * space and return 0xff for all other config reads. + **/ +void pci_block_user_cfg_access(struct pci_dev *dev) +{ + unsigned long flags; + + pci_save_state(dev); + + /* spinlock to synchronize with anyone reading config space now */ + spin_lock_irqsave(&pci_lock, flags); + dev->block_ucfg_access = 1; + spin_unlock_irqrestore(&pci_lock, flags); +} +EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); + +/** + * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes + * @dev: pci device struct + * + * This function allows userspace PCI config accesses to resume. + **/ +void pci_unblock_user_cfg_access(struct pci_dev *dev) +{ + unsigned long flags; + + /* spinlock to synchronize with anyone reading saved config space */ + spin_lock_irqsave(&pci_lock, flags); + dev->block_ucfg_access = 0; + spin_unlock_irqrestore(&pci_lock, flags); +} +EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 2898830c496f..965a5934623a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 1) && size) { u8 val; - pci_read_config_byte(dev, off, &val); + pci_user_read_config_byte(dev, off, &val); data[off - init_off] = val; off++; size--; @@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 3) && size > 2) { u16 val; - pci_read_config_word(dev, off, &val); + pci_user_read_config_word(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; off += 2; @@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) while (size > 3) { u32 val; - pci_read_config_dword(dev, off, &val); + pci_user_read_config_dword(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; data[off - init_off + 2] = (val >> 16) & 0xff; @@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size >= 2) { u16 val; - pci_read_config_word(dev, off, &val); + pci_user_read_config_word(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; off += 2; @@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size > 0) { u8 val; - pci_read_config_byte(dev, off, &val); + pci_user_read_config_byte(dev, off, &val); data[off - init_off] = val; off++; --size; @@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) } if ((off & 1) && size) { - pci_write_config_byte(dev, off, data[off - init_off]); + pci_user_write_config_byte(dev, off, data[off - init_off]); off++; size--; } @@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 3) && size > 2) { u16 val = data[off - init_off]; val |= (u16) data[off - init_off + 1] << 8; - pci_write_config_word(dev, off, val); + pci_user_write_config_word(dev, off, val); off += 2; size -= 2; } @@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) val |= (u32) data[off - init_off + 1] << 8; val |= (u32) data[off - init_off + 2] << 16; val |= (u32) data[off - init_off + 3] << 24; - pci_write_config_dword(dev, off, val); + pci_user_write_config_dword(dev, off, val); off += 4; size -= 4; } @@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size >= 2) { u16 val = data[off - init_off]; val |= (u16) data[off - init_off + 1] << 8; - pci_write_config_word(dev, off, val); + pci_user_write_config_word(dev, off, val); off += 2; size -= 2; } if (size) { - pci_write_config_byte(dev, off, data[off - init_off]); + pci_user_write_config_byte(dev, off, data[off - init_off]); off++; --size; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d3f3dd42240d..6527b36c9a61 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -15,6 +15,13 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); +extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); +extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); +extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); +extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); +extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); +extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); + /* PCI /proc functions */ #ifdef CONFIG_PROC_FS extern int pci_proc_attach_device(struct pci_dev *dev); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 9613f666c110..9eb465727fce 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -80,7 +80,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if ((pos & 1) && cnt) { unsigned char val; - pci_read_config_byte(dev, pos, &val); + pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; @@ -89,7 +89,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if ((pos & 3) && cnt > 2) { unsigned short val; - pci_read_config_word(dev, pos, &val); + pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (unsigned short __user *) buf); buf += 2; pos += 2; @@ -98,7 +98,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp while (cnt >= 4) { unsigned int val; - pci_read_config_dword(dev, pos, &val); + pci_user_read_config_dword(dev, pos, &val); __put_user(cpu_to_le32(val), (unsigned int __user *) buf); buf += 4; pos += 4; @@ -107,7 +107,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (cnt >= 2) { unsigned short val; - pci_read_config_word(dev, pos, &val); + pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (unsigned short __user *) buf); buf += 2; pos += 2; @@ -116,7 +116,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (cnt) { unsigned char val; - pci_read_config_byte(dev, pos, &val); + pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; @@ -151,7 +151,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if ((pos & 1) && cnt) { unsigned char val; __get_user(val, buf); - pci_write_config_byte(dev, pos, val); + pci_user_write_config_byte(dev, pos, val); buf++; pos++; cnt--; @@ -160,7 +160,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if ((pos & 3) && cnt > 2) { unsigned short val; __get_user(val, (unsigned short __user *) buf); - pci_write_config_word(dev, pos, le16_to_cpu(val)); + pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; cnt -= 2; @@ -169,7 +169,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof while (cnt >= 4) { unsigned int val; __get_user(val, (unsigned int __user *) buf); - pci_write_config_dword(dev, pos, le32_to_cpu(val)); + pci_user_write_config_dword(dev, pos, le32_to_cpu(val)); buf += 4; pos += 4; cnt -= 4; @@ -178,7 +178,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (cnt >= 2) { unsigned short val; __get_user(val, (unsigned short __user *) buf); - pci_write_config_word(dev, pos, le16_to_cpu(val)); + pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; cnt -= 2; @@ -187,7 +187,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (cnt) { unsigned char val; __get_user(val, buf); - pci_write_config_byte(dev, pos, val); + pci_user_write_config_byte(dev, pos, val); buf++; pos++; cnt--; @@ -484,10 +484,10 @@ static int show_dev_config(struct seq_file *m, void *v) drv = pci_dev_driver(dev); - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); - pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); - pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat); + pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); + pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); + pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat); seq_printf(m, " Bus %2d, device %3d, function %2d:\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); seq_printf(m, " Class %04x", class_rev >> 16); diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index c071790cc983..87fafc08cb9d 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -13,7 +13,7 @@ #include #include #include - +#include "pci.h" asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, @@ -38,13 +38,13 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, lock_kernel(); switch (len) { case 1: - cfg_ret = pci_read_config_byte(dev, off, &byte); + cfg_ret = pci_user_read_config_byte(dev, off, &byte); break; case 2: - cfg_ret = pci_read_config_word(dev, off, &word); + cfg_ret = pci_user_read_config_word(dev, off, &word); break; case 4: - cfg_ret = pci_read_config_dword(dev, off, &dword); + cfg_ret = pci_user_read_config_dword(dev, off, &dword); break; default: err = -EINVAL; @@ -112,7 +112,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(byte, (u8 __user *)buf); if (err) break; - err = pci_write_config_byte(dev, off, byte); + err = pci_user_write_config_byte(dev, off, byte); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; @@ -121,7 +121,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(word, (u16 __user *)buf); if (err) break; - err = pci_write_config_word(dev, off, word); + err = pci_user_write_config_word(dev, off, word); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; @@ -130,7 +130,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(dword, (u32 __user *)buf); if (err) break; - err = pci_write_config_dword(dev, off, dword); + err = pci_user_write_config_dword(dev, off, dword); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; diff --git a/include/linux/pci.h b/include/linux/pci.h index 7349058ed778..3596ac94ecff 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -132,6 +132,7 @@ struct pci_dev { unsigned int is_enabled:1; /* pci_enable_device has been called */ unsigned int is_busmaster:1; /* device is busmaster */ unsigned int no_msi:1; /* device may not use msi */ + unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ u32 saved_config_space[16]; /* config space saved at suspend time */ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ @@ -490,6 +491,9 @@ extern void pci_disable_msix(struct pci_dev *dev); extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); #endif +extern void pci_block_user_cfg_access(struct pci_dev *dev); +extern void pci_unblock_user_cfg_access(struct pci_dev *dev); + /* * PCI domain support. Sometimes called PCI segment (eg by ACPI), * a PCI domain is defined to be a set of PCI busses which share @@ -560,6 +564,9 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) +static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } +static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } + #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ From b30197d2c07b396907b81673354a015a9d2b216c Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 27 Sep 2005 01:21:56 -0700 Subject: [PATCH 0776/1940] [PATCH] PCI: ipr: Block config access during BIST IPR scsi adapter have an exposure today in that they issue BIST to the adapter to reset the card. If, during the time it takes to complete BIST, userspace attempts to access PCI config space, the host bus bridge will master abort the access since the ipr adapter does not respond on the PCI bus for a brief period of time when running BIST. On PPC64 hardware, this master abort results in the host PCI bridge isolating that PCI device from the rest of the system, making the device unusable until Linux is rebooted. This patch makes use of some newly added PCI layer APIs that allow for protection from userspace accessing config space of a device in scenarios such as this. Signed-off-by: Brian King Cc: Benjamin Herrenschmidt Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman drivers/scsi/ipr.c | 2 ++ 1 file changed, 2 insertions(+) --- drivers/scsi/ipr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index babd48363402..e0039dfae8e5 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4944,6 +4944,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) int rc; ENTER; + pci_unblock_user_cfg_access(ioa_cfg->pdev); rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { @@ -4998,6 +4999,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) int rc; ENTER; + pci_block_user_cfg_access(ioa_cfg->pdev); rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START); if (rc != PCIBIOS_SUCCESSFUL) { From d3535fbbce0eef8faa8de30d187fc83b11b858ef Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 28 Sep 2005 17:50:51 -0400 Subject: [PATCH 0777/1940] [PATCH] pci: cleanup need_restore switch statement Cleanup the need_restore switch statement in pci_set_power_state(). This makes it more safe by explicitly handling all the PCI power states instead of handling them as the default case. It also reads a little better IMHO. Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 259d247b7551..39bdb938521d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -314,19 +314,19 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) * sets PowerState to 0. */ switch (dev->current_state) { + case PCI_D0: + case PCI_D1: + case PCI_D2: + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= state; + break; case PCI_UNKNOWN: /* Boot-up */ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) need_restore = 1; /* Fall-through: force to D0 */ - case PCI_D3hot: - case PCI_D3cold: - case PCI_POWER_ERROR: - pmcsr = 0; - break; default: - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= state; + pmcsr = 0; break; } From c8920f0c8b3b42537ab4a54ff92c11daf48fdfec Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 28 Sep 2005 15:15:16 -0600 Subject: [PATCH 0778/1940] [PATCH] cpcihp_zt5550: add pci_enable_device() Add pci_{enable,disable}_device() calls. Without pci_enable_device(), dev->irq is garbage, and cpcihp_zt5550 relies on it. Compiled but untested, since I don't have the hardware. Signed-off-by: Bjorn Helgaas Signed-off-by: Scott Murray Signed-off-by: Greg Kroah-Hartman drivers/pci/hotplug/cpcihp_zt5550.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) --- drivers/pci/hotplug/cpcihp_zt5550.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index e9928024be78..790abadd816c 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c @@ -78,11 +78,20 @@ static void __iomem *csr_int_mask; static int zt5550_hc_config(struct pci_dev *pdev) { + int ret; + /* Since we know that no boards exist with two HC chips, treat it as an error */ if(hc_dev) { err("too many host controller devices?"); return -EBUSY; } + + ret = pci_enable_device(pdev); + if(ret) { + err("cannot enable %s\n", pci_name(pdev)); + return ret; + } + hc_dev = pdev; dbg("hc_dev = %p", hc_dev); dbg("pci resource start %lx", pci_resource_start(hc_dev, 1)); @@ -91,7 +100,8 @@ static int zt5550_hc_config(struct pci_dev *pdev) if(!request_mem_region(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1), MY_NAME)) { err("cannot reserve MMIO region"); - return -ENOMEM; + ret = -ENOMEM; + goto exit_disable_device; } hc_registers = @@ -99,9 +109,8 @@ static int zt5550_hc_config(struct pci_dev *pdev) if(!hc_registers) { err("cannot remap MMIO region %lx @ %lx", pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1)); - release_mem_region(pci_resource_start(hc_dev, 1), - pci_resource_len(hc_dev, 1)); - return -ENODEV; + ret = -ENODEV; + goto exit_release_region; } csr_hc_index = hc_registers + CSR_HCINDEX; @@ -124,6 +133,13 @@ static int zt5550_hc_config(struct pci_dev *pdev) writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask); dbg("disabled timer0, timer1 and ENUM interrupts"); return 0; + +exit_release_region: + release_mem_region(pci_resource_start(hc_dev, 1), + pci_resource_len(hc_dev, 1)); +exit_disable_device: + pci_disable_device(hc_dev); + return ret; } static int zt5550_hc_cleanup(void) @@ -134,6 +150,7 @@ static int zt5550_hc_cleanup(void) iounmap(hc_registers); release_mem_region(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); + pci_disable_device(hc_dev); return 0; } From fe89cf4c4b7a3d9a0ff95eb0506aa7c9baaccda1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 28 Sep 2005 14:03:08 -0600 Subject: [PATCH 0779/1940] [PATCH] cpqphp: add pci_enable_device() Add pci_{enable,disable}_device() calls. Without pci_enable_device(), dev->irq is garbage, and cpqphp relies on it. This fixes a problem reported by Bruno Redondi. He reported a flood of ACPI interrupts, that caused kacpid to run 100% of the time: http://bugzilla.kernel.org/show_bug.cgi?id=5312 Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman drivers/pci/hotplug/cpqphp_core.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) --- drivers/pci/hotplug/cpqphp_core.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 8c6d3987d461..9aed8efe6a11 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -794,12 +794,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u32 rc; struct controller *ctrl; struct pci_func *func; + int err; + + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n", + pci_name(pdev), err); + return err; + } // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) { err(msg_HPC_non_compaq_or_intel); - return -ENODEV; + rc = -ENODEV; + goto err_disable_device; } dbg("Vendor ID: %x\n", vendor_id); @@ -807,7 +816,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dbg("revision: %d\n", rev); if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) { err(msg_HPC_rev_error); - return -ENODEV; + rc = -ENODEV; + goto err_disable_device; } /* Check for the proper subsytem ID's @@ -820,18 +830,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); if (rc) { err("%s : pci_read_config_word failed\n", __FUNCTION__); - return rc; + goto err_disable_device; } dbg("Subsystem Vendor ID: %x\n", subsystem_vid); if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) { err(msg_HPC_non_compaq_or_intel); - return -ENODEV; + rc = -ENODEV; + goto err_disable_device; } ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); if (!ctrl) { err("%s : out of memory\n", __FUNCTION__); - return -ENOMEM; + rc = -ENOMEM; + goto err_disable_device; } memset(ctrl, 0, sizeof(struct controller)); @@ -1264,6 +1276,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) kfree(ctrl->pci_bus); err_free_ctrl: kfree(ctrl); +err_disable_device: + pci_disable_device(pdev); return rc; } From acc06632e387fd05d2bf3480f6a2f4d1a62734b8 Mon Sep 17 00:00:00 2001 From: "R.Marek@sh.cvut.cz" Date: Thu, 29 Sep 2005 08:35:41 +0000 Subject: [PATCH 0780/1940] [PATCH] unhide ICH6 SMBus - take 2 This patch unhides hidden SMBus on ICH6 chipset installed in Asus M6V notebook. I would like to thank Michal Mleczko for testing and help. Signed-Off-By: Rudolf Marek Signed-off-by: Greg Kroah-Hartman drivers/pci/quirks.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) --- drivers/pci/quirks.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0663428a0e64..e1bd169cf55c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -934,6 +934,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x186a: /* M6Ne notebook */ asus_hides_smbus = 1; } + if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { + switch (dev->subsystem_device) { + case 0x1882: /* M6V notebook */ + asus_hides_smbus = 1; + } + } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { @@ -978,6 +984,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); static void __init asus_hides_smbus_lpc(struct pci_dev *dev) { @@ -1002,6 +1009,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, as DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); +static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) +{ + u32 val, rcba; + void __iomem *base; + + if (likely(!asus_hides_smbus)) + return; + pci_read_config_dword(dev, 0xF0, &rcba); + base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */ + if (base == NULL) return; + val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ + writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ + iounmap(base); + printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); + /* * SiS 96x south bridge: BIOS typically hides SMBus device... */ From b135c4815051bad6b2472e4ad0152f205918d2c5 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 29 Sep 2005 10:39:46 +1000 Subject: [PATCH 0781/1940] [PATCH] pci_ids: remove duplicates from pci_ids.h pci_ids.h cleanup: remove duplicated entries and change some defines to explicit value rather than in terms of another constant, preparation for removing unused symbols Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman include/linux/pci_ids.h | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) --- include/linux/pci_ids.h | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 71834f05504f..0631074954f7 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -274,7 +274,6 @@ #define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050 #define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051 #define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052 -#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452 #define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053 #define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054 #define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055 @@ -517,16 +516,16 @@ #define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 #define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414 #define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440 -# define PCI_DEVICE_ID_AMD_VIPER_7440 PCI_DEVICE_ID_AMD_OPUS_7440 +#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 #define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 -# define PCI_DEVICE_ID_AMD_VIPER_7441 PCI_DEVICE_ID_AMD_OPUS_7441 +#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441 #define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 -# define PCI_DEVICE_ID_AMD_VIPER_7443 PCI_DEVICE_ID_AMD_OPUS_7443 +#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 #define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 #define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448 -# define PCI_DEVICE_ID_AMD_VIPER_7448 PCI_DEVICE_ID_AMD_OPUS_7448 +#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448 #define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449 -# define PCI_DEVICE_ID_AMD_VIPER_7449 PCI_DEVICE_ID_AMD_OPUS_7449 +#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449 #define PCI_DEVICE_ID_AMD_8111_LAN 0x7462 #define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 @@ -585,7 +584,6 @@ #define PCI_DEVICE_ID_CT_65550 0x00e0 #define PCI_DEVICE_ID_CT_65554 0x00e4 #define PCI_DEVICE_ID_CT_65555 0x00e5 -#define PCI_DEVICE_ID_CT_69000 0x00c0 #define PCI_VENDOR_ID_MIRO 0x1031 #define PCI_DEVICE_ID_MIRO_36050 0x5601 @@ -1197,7 +1195,6 @@ #define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc #define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 -#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 #define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 @@ -1623,7 +1620,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB +#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB 0x0220 #define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 #define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 @@ -1792,10 +1789,6 @@ #define PCI_DEVICE_ID_PC300_TE_M_2 0x0320 #define PCI_DEVICE_ID_PC300_TE_M_1 0x0321 -/* Allied Telesyn */ -#define PCI_VENDOR_ID_AT 0x1259 -#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 - #define PCI_VENDOR_ID_ESSENTIAL 0x120f #define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 @@ -2340,16 +2333,13 @@ #define PCI_VENDOR_ID_DUNORD 0x5544 #define PCI_DEVICE_ID_DUNORD_I3000 0x0001 +#define PCI_VENDOR_ID_GENROCO 0x5555 +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 + #define PCI_VENDOR_ID_DCI 0x6666 #define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 #define PCI_DEVICE_ID_DCI_PCCOM8 0x0002 -#define PCI_VENDOR_ID_DUNORD 0x5544 -#define PCI_DEVICE_ID_DUNORD_I3000 0x0001 - -#define PCI_VENDOR_ID_GENROCO 0x5555 -#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 - #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 #define PCI_DEVICE_ID_INTEL_21145 0x0039 From 4153812fc10ea91cb1a7b6ea4f4337dd211c1ef7 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 29 Sep 2005 10:40:52 +1000 Subject: [PATCH 0782/1940] [PATCH] pci_ids: macros: replace partial with whole symbols pci_ids cleanup: replace symbols built by macros with whole symbols to aid grep searches. Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman drivers/video/cirrusfb.c | 24 ++++++++++++------------ sound/oss/ymfpci.c | 17 +++++++++-------- sound/pci/bt87x.c | 11 +++++++---- 3 files changed, 28 insertions(+), 24 deletions(-) --- drivers/video/cirrusfb.c | 24 ++++++++++++------------ sound/oss/ymfpci.c | 17 +++++++++-------- sound/pci/bt87x.c | 11 +++++++---- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index a3040429c27b..3a26f9cc8585 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -275,20 +275,20 @@ static const struct cirrusfb_board_info_rec { #ifdef CONFIG_PCI #define CHIP(id, btype) \ - { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } + { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } static struct pci_device_id cirrusfb_pci_table[] = { - CHIP( CIRRUS_5436, BT_ALPINE ), - CHIP( CIRRUS_5434_8, BT_ALPINE ), - CHIP( CIRRUS_5434_4, BT_ALPINE ), - CHIP( CIRRUS_5430, BT_ALPINE ), /* GD-5440 has identical id */ - CHIP( CIRRUS_7543, BT_ALPINE ), - CHIP( CIRRUS_7548, BT_ALPINE ), - CHIP( CIRRUS_5480, BT_GD5480 ), /* MacPicasso probably */ - CHIP( CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is a GD5446 */ - CHIP( CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ - CHIP( CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ - CHIP( CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ + CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */ + CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */ + CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */ + CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ + CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ + CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ { 0, } }; MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c index 05203ad523f7..8dae59bd05a2 100644 --- a/sound/oss/ymfpci.c +++ b/sound/oss/ymfpci.c @@ -107,14 +107,15 @@ static LIST_HEAD(ymf_devs); */ static struct pci_device_id ymf_id_tbl[] = { -#define DEV(v, d, data) \ - { PCI_VENDOR_ID_##v, PCI_DEVICE_ID_##v##_##d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)data } - DEV (YAMAHA, 724, "YMF724"), - DEV (YAMAHA, 724F, "YMF724F"), - DEV (YAMAHA, 740, "YMF740"), - DEV (YAMAHA, 740C, "YMF740C"), - DEV (YAMAHA, 744, "YMF744"), - DEV (YAMAHA, 754, "YMF754"), +#define DEV(dev, data) \ + { PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \ + (unsigned long)data } + DEV (PCI_DEVICE_ID_YAMAHA_724, "YMF724"), + DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"), + DEV (PCI_DEVICE_ID_YAMAHA_740, "YMF740"), + DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"), + DEV (PCI_DEVICE_ID_YAMAHA_744, "YMF744"), + DEV (PCI_DEVICE_ID_YAMAHA_754, "YMF754"), #undef DEV { } }; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 2236c958aec0..01d98eeb242e 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -761,15 +761,18 @@ static int __devinit snd_bt87x_create(snd_card_t *card, #define BT_DEVICE(chip, subvend, subdev, rate) \ { .vendor = PCI_VENDOR_ID_BROOKTREE, \ - .device = PCI_DEVICE_ID_BROOKTREE_##chip, \ + .device = chip, \ .subvendor = subvend, .subdevice = subdev, \ .driver_data = rate } /* driver_data is the default digital_rate value for that device */ static struct pci_device_id snd_bt87x_ids[] = { - BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ - BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ - BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */ + /* Hauppauge WinTV series */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000), + /* Hauppauge WinTV series */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), + /* Viewcast Osprey 200 */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); From b7924c38c9a9c6151213bc0d91776eace614e761 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 29 Sep 2005 11:06:40 +1000 Subject: [PATCH 0783/1940] [PATCH] pci_ids: remove non-referenced symbols from pci_ids.h pci_ids.h cleanup: removed non-referenced symbols, compile tested with 'make allmodconfig' Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman include/linux/pci_ids.h | 540 ------------------------------------------------ 1 file changed, 540 deletions(-) --- include/linux/pci_ids.h | 540 ---------------------------------------- 1 file changed, 540 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0631074954f7..11fed60a928d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -132,9 +132,6 @@ #define PCI_VENDOR_ID_COMPAQ 0x0e11 #define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 -#define PCI_DEVICE_ID_COMPAQ_1280 0x3033 -#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000 -#define PCI_DEVICE_ID_COMPAQ_6010 0x6010 #define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 #define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 @@ -281,8 +278,6 @@ #define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057 #define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058 /* Rage128 M4 */ -#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45 -#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46 /* Radeon R100 */ #define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 #define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 @@ -303,32 +298,22 @@ #define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 #define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 /* Radeon NV-100 */ -#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159 -#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a /* Radeon RV250 (9000) */ #define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 #define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 #define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 #define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 /* Radeon RV280 (9200) */ -#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960 #define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961 #define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964 /* Radeon R300 (9500) */ -#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144 /* Radeon R300 (9700) */ #define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 #define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 #define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 #define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 -#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145 -#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146 /* Radeon R350 (9800) */ -#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48 -#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49 /* Radeon RV350 (9600) */ -#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150 -#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152 /* Radeon M6 */ #define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 #define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a @@ -341,10 +326,6 @@ #define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66 #define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67 /* Radeon */ -#define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144 -#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145 -#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146 -#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147 /* RadeonIGP */ #define PCI_DEVICE_ID_ATI_RS100 0xcab0 #define PCI_DEVICE_ID_ATI_RS200 0xcab2 @@ -445,34 +426,18 @@ #define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 #define PCI_DEVICE_ID_CIRRUS_6729 0x1100 #define PCI_DEVICE_ID_CIRRUS_6832 0x1110 -#define PCI_DEVICE_ID_CIRRUS_7542 0x1200 #define PCI_DEVICE_ID_CIRRUS_7543 0x1202 -#define PCI_DEVICE_ID_CIRRUS_7541 0x1204 #define PCI_DEVICE_ID_CIRRUS_4610 0x6001 #define PCI_DEVICE_ID_CIRRUS_4612 0x6003 #define PCI_DEVICE_ID_CIRRUS_4615 0x6004 -#define PCI_DEVICE_ID_CIRRUS_4281 0x6005 #define PCI_VENDOR_ID_IBM 0x1014 -#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a #define PCI_DEVICE_ID_IBM_TR 0x0018 -#define PCI_DEVICE_ID_IBM_82G2675 0x001d -#define PCI_DEVICE_ID_IBM_MCA 0x0020 -#define PCI_DEVICE_ID_IBM_82351 0x0022 -#define PCI_DEVICE_ID_IBM_PYTHON 0x002d -#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e #define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e -#define PCI_DEVICE_ID_IBM_MPIC 0x0046 -#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d -#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096 #define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc -#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105 -#define PCI_DEVICE_ID_IBM_405GP 0x0156 #define PCI_DEVICE_ID_IBM_SNIPE 0x0180 -#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd #define PCI_DEVICE_ID_IBM_CITRINE 0x028C #define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166 -#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031 #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219 #define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A @@ -483,7 +448,6 @@ #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 #define PCI_VENDOR_ID_WD 0x101c -#define PCI_DEVICE_ID_WD_7197 0x3296 #define PCI_DEVICE_ID_WD_90C 0xc24a #define PCI_VENDOR_ID_AMI 0x101e @@ -500,33 +464,18 @@ #define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006 #define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007 #define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C -#define PCI_DEVICE_ID_AMD_FE_GATE_700D 0x700D #define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E -#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F -#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400 #define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401 -#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403 -#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404 -#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408 #define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409 #define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B -#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C #define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410 #define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411 #define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 -#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414 -#define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440 #define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 #define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 -#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441 #define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 #define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 #define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 -#define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448 -#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448 -#define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449 -#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449 -#define PCI_DEVICE_ID_AMD_8111_LAN 0x7462 #define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 #define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a @@ -637,7 +586,6 @@ #define PCI_DEVICE_ID_SI_550 0x0550 #define PCI_DEVICE_ID_SI_540_VGA 0x5300 #define PCI_DEVICE_ID_SI_550_VGA 0x5315 -#define PCI_DEVICE_ID_SI_601 0x0601 #define PCI_DEVICE_ID_SI_620 0x0620 #define PCI_DEVICE_ID_SI_630 0x0630 #define PCI_DEVICE_ID_SI_633 0x0633 @@ -648,30 +596,22 @@ #define PCI_DEVICE_ID_SI_648 0x0648 #define PCI_DEVICE_ID_SI_650 0x0650 #define PCI_DEVICE_ID_SI_651 0x0651 -#define PCI_DEVICE_ID_SI_652 0x0652 #define PCI_DEVICE_ID_SI_655 0x0655 #define PCI_DEVICE_ID_SI_661 0x0661 #define PCI_DEVICE_ID_SI_730 0x0730 #define PCI_DEVICE_ID_SI_733 0x0733 #define PCI_DEVICE_ID_SI_630_VGA 0x6300 -#define PCI_DEVICE_ID_SI_730_VGA 0x7300 #define PCI_DEVICE_ID_SI_735 0x0735 #define PCI_DEVICE_ID_SI_740 0x0740 #define PCI_DEVICE_ID_SI_741 0x0741 #define PCI_DEVICE_ID_SI_745 0x0745 #define PCI_DEVICE_ID_SI_746 0x0746 -#define PCI_DEVICE_ID_SI_748 0x0748 -#define PCI_DEVICE_ID_SI_750 0x0750 -#define PCI_DEVICE_ID_SI_751 0x0751 -#define PCI_DEVICE_ID_SI_752 0x0752 #define PCI_DEVICE_ID_SI_755 0x0755 #define PCI_DEVICE_ID_SI_760 0x0760 #define PCI_DEVICE_ID_SI_900 0x0900 #define PCI_DEVICE_ID_SI_961 0x0961 #define PCI_DEVICE_ID_SI_962 0x0962 #define PCI_DEVICE_ID_SI_963 0x0963 -#define PCI_DEVICE_ID_SI_5107 0x5107 -#define PCI_DEVICE_ID_SI_5300 0x5300 #define PCI_DEVICE_ID_SI_5511 0x5511 #define PCI_DEVICE_ID_SI_5513 0x5513 #define PCI_DEVICE_ID_SI_5518 0x5518 @@ -683,10 +623,6 @@ #define PCI_DEVICE_ID_SI_5597 0x5597 #define PCI_DEVICE_ID_SI_5598 0x5598 #define PCI_DEVICE_ID_SI_5600 0x5600 -#define PCI_DEVICE_ID_SI_6300 0x6300 -#define PCI_DEVICE_ID_SI_6306 0x6306 -#define PCI_DEVICE_ID_SI_6326 0x6326 -#define PCI_DEVICE_ID_SI_7001 0x7001 #define PCI_DEVICE_ID_SI_7012 0x7012 #define PCI_DEVICE_ID_SI_7013 0x7013 #define PCI_DEVICE_ID_SI_7016 0x7016 @@ -707,14 +643,11 @@ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A #define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B -#define PCI_DEVICE_ID_HP_PCI_LBA 0x1054 -#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0 #define PCI_DEVICE_ID_HP_REO_IOC 0x10f1 #define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b #define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 #define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 -#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229 #define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a #define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e #define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c @@ -722,9 +655,7 @@ #define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290 #define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301 #define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a -#define PCI_DEVICE_ID_HP_CISS 0x3210 #define PCI_DEVICE_ID_HP_CISSA 0x3220 -#define PCI_DEVICE_ID_HP_CISSB 0x3222 #define PCI_DEVICE_ID_HP_CISSC 0x3230 #define PCI_DEVICE_ID_HP_CISSD 0x3238 #define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 @@ -732,8 +663,6 @@ #define PCI_VENDOR_ID_PCTECH 0x1042 #define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 #define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 -#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000 -#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010 #define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 #define PCI_VENDOR_ID_ASUSTEK 0x1043 @@ -743,24 +672,15 @@ #define PCI_DEVICE_ID_DPT 0xa400 #define PCI_VENDOR_ID_OPTI 0x1045 -#define PCI_DEVICE_ID_OPTI_92C178 0xc178 -#define PCI_DEVICE_ID_OPTI_82C557 0xc557 #define PCI_DEVICE_ID_OPTI_82C558 0xc558 #define PCI_DEVICE_ID_OPTI_82C621 0xc621 #define PCI_DEVICE_ID_OPTI_82C700 0xc700 -#define PCI_DEVICE_ID_OPTI_82C701 0xc701 -#define PCI_DEVICE_ID_OPTI_82C814 0xc814 -#define PCI_DEVICE_ID_OPTI_82C822 0xc822 -#define PCI_DEVICE_ID_OPTI_82C861 0xc861 #define PCI_DEVICE_ID_OPTI_82C825 0xd568 #define PCI_VENDOR_ID_ELSA 0x1048 #define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 #define PCI_DEVICE_ID_ELSA_QS3000 0x3000 -#define PCI_VENDOR_ID_SGS 0x104a -#define PCI_DEVICE_ID_SGS_2000 0x0008 -#define PCI_DEVICE_ID_SGS_1764 0x0009 #define PCI_VENDOR_ID_BUSLOGIC 0x104B #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 @@ -768,7 +688,6 @@ #define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 #define PCI_VENDOR_ID_TI 0x104c -#define PCI_DEVICE_ID_TI_TVP4010 0x3d04 #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 #define PCI_DEVICE_ID_TI_4450 0x8011 #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 @@ -802,14 +721,10 @@ #define PCI_DEVICE_ID_TI_X420 0xac8e #define PCI_VENDOR_ID_SONY 0x104d -#define PCI_DEVICE_ID_SONY_CXD3222 0x8039 -#define PCI_VENDOR_ID_OAK 0x104e -#define PCI_DEVICE_ID_OAK_OTI107 0x0107 /* Winbond have two vendor IDs! See 0x10ad as well */ #define PCI_VENDOR_ID_WINBOND2 0x1050 -#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 #define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a #define PCI_DEVICE_ID_WINBOND2_6692 0x6692 @@ -818,19 +733,15 @@ #define PCI_VENDOR_ID_EFAR 0x1055 #define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 -#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 -#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462 #define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 #define PCI_VENDOR_ID_MOTOROLA 0x1057 -#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507 #define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 #define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 #define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004 #define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 #define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 #define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 -#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806 #define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b #define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 @@ -841,33 +752,19 @@ #define PCI_DEVICE_ID_PROMISE_20262 0x4d38 #define PCI_DEVICE_ID_PROMISE_20263 0x0D38 #define PCI_DEVICE_ID_PROMISE_20268 0x4d68 -#define PCI_DEVICE_ID_PROMISE_20268R 0x6268 #define PCI_DEVICE_ID_PROMISE_20269 0x4d69 #define PCI_DEVICE_ID_PROMISE_20270 0x6268 #define PCI_DEVICE_ID_PROMISE_20271 0x6269 #define PCI_DEVICE_ID_PROMISE_20275 0x1275 #define PCI_DEVICE_ID_PROMISE_20276 0x5275 #define PCI_DEVICE_ID_PROMISE_20277 0x7275 -#define PCI_DEVICE_ID_PROMISE_5300 0x5300 -#define PCI_VENDOR_ID_N9 0x105d -#define PCI_DEVICE_ID_N9_I128 0x2309 -#define PCI_DEVICE_ID_N9_I128_2 0x2339 -#define PCI_DEVICE_ID_N9_I128_T2R 0x493d #define PCI_VENDOR_ID_UMC 0x1060 #define PCI_DEVICE_ID_UMC_UM8673F 0x0101 -#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 #define PCI_DEVICE_ID_UMC_UM8886BF 0x673a #define PCI_DEVICE_ID_UMC_UM8886A 0x886a -#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 -#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 -#define PCI_DEVICE_ID_UMC_UM9017F 0x9017 -#define PCI_DEVICE_ID_UMC_UM8886N 0xe886 -#define PCI_DEVICE_ID_UMC_UM8891N 0xe891 -#define PCI_VENDOR_ID_X 0x1061 -#define PCI_DEVICE_ID_X_AGX016 0x0001 #define PCI_VENDOR_ID_MYLEX 0x1069 #define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001 @@ -878,37 +775,26 @@ #define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 #define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166 -#define PCI_VENDOR_ID_PICOP 0x1066 -#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 -#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002 #define PCI_VENDOR_ID_APPLE 0x106b #define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 -#define PCI_DEVICE_ID_APPLE_GC 0x0002 #define PCI_DEVICE_ID_APPLE_HYDRA 0x000e #define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 -#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 -#define PCI_DEVICE_ID_APPLE_KEYLARGO 0x0022 #define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024 -#define PCI_DEVICE_ID_APPLE_KEYLARGO_P 0x0025 -#define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e -#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 #define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 #define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b -#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e #define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043 #define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b #define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c #define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050 #define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 -#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052 #define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058 #define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059 #define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 @@ -921,12 +807,9 @@ #define PCI_DEVICE_ID_YAMAHA_744 0x0010 #define PCI_DEVICE_ID_YAMAHA_754 0x0012 -#define PCI_VENDOR_ID_NEXGEN 0x1074 -#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 #define PCI_VENDOR_ID_QLOGIC 0x1077 #define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 -#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 #define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 #define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 #define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 @@ -944,32 +827,20 @@ #define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 #define PCI_DEVICE_ID_CYRIX_5520 0x0002 #define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 -#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101 #define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 #define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 #define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 -#define PCI_VENDOR_ID_LEADTEK 0x107d -#define PCI_DEVICE_ID_LEADTEK_805 0x0000 -#define PCI_VENDOR_ID_INTERPHASE 0x107e -#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004 -#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005 -#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008 #define PCI_VENDOR_ID_CONTAQ 0x1080 -#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 #define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 -#define PCI_VENDOR_ID_FOREX 0x1083 #define PCI_VENDOR_ID_OLICOM 0x108d -#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001 -#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011 #define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 #define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 #define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 -#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021 #define PCI_VENDOR_ID_SUN 0x108e #define PCI_DEVICE_ID_SUN_EBUS 0x1000 @@ -988,49 +859,31 @@ #define PCI_DEVICE_ID_SUN_CASSINI 0xabba #define PCI_VENDOR_ID_CMD 0x1095 -#define PCI_DEVICE_ID_CMD_640 0x0640 #define PCI_DEVICE_ID_CMD_643 0x0643 #define PCI_DEVICE_ID_CMD_646 0x0646 -#define PCI_DEVICE_ID_CMD_647 0x0647 #define PCI_DEVICE_ID_CMD_648 0x0648 #define PCI_DEVICE_ID_CMD_649 0x0649 -#define PCI_DEVICE_ID_CMD_670 0x0670 -#define PCI_DEVICE_ID_CMD_680 0x0680 #define PCI_DEVICE_ID_SII_680 0x0680 #define PCI_DEVICE_ID_SII_3112 0x3112 #define PCI_DEVICE_ID_SII_1210SA 0x0240 -#define PCI_VENDOR_ID_VISION 0x1098 -#define PCI_DEVICE_ID_VISION_QD8500 0x0001 -#define PCI_DEVICE_ID_VISION_QD8580 0x0002 #define PCI_VENDOR_ID_BROOKTREE 0x109e -#define PCI_DEVICE_ID_BROOKTREE_848 0x0350 -#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351 -#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e #define PCI_DEVICE_ID_BROOKTREE_878 0x0878 #define PCI_DEVICE_ID_BROOKTREE_879 0x0879 -#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474 -#define PCI_VENDOR_ID_SIERRA 0x10a8 -#define PCI_DEVICE_ID_SIERRA_STB 0x0000 #define PCI_VENDOR_ID_SGI 0x10a9 #define PCI_DEVICE_ID_SGI_IOC3 0x0003 #define PCI_DEVICE_ID_SGI_IOC4 0x100a #define PCI_VENDOR_ID_SGI_LITHIUM 0x1002 -#define PCI_VENDOR_ID_ACC 0x10aa -#define PCI_DEVICE_ID_ACC_2056 0x0000 #define PCI_VENDOR_ID_WINBOND 0x10ad -#define PCI_DEVICE_ID_WINBOND_83769 0x0001 #define PCI_DEVICE_ID_WINBOND_82C105 0x0105 #define PCI_DEVICE_ID_WINBOND_83C553 0x0565 -#define PCI_VENDOR_ID_DATABOOK 0x10b3 -#define PCI_DEVICE_ID_DATABOOK_87144 0xb106 #define PCI_VENDOR_ID_PLX 0x10b5 #define PCI_DEVICE_ID_PLX_R685 0x1030 @@ -1041,33 +894,19 @@ #define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 #define PCI_DEVICE_ID_PLX_R753 0x1152 #define PCI_DEVICE_ID_PLX_OLITEC 0x1187 -#define PCI_DEVICE_ID_PLX_9030 0x9030 #define PCI_DEVICE_ID_PLX_9050 0x9050 -#define PCI_DEVICE_ID_PLX_9060 0x9060 -#define PCI_DEVICE_ID_PLX_9060ES 0x906E -#define PCI_DEVICE_ID_PLX_9060SD 0x906D #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 #define PCI_VENDOR_ID_MADGE 0x10b6 #define PCI_DEVICE_ID_MADGE_MK2 0x0002 -#define PCI_DEVICE_ID_MADGE_C155S 0x1001 #define PCI_VENDOR_ID_3COM 0x10b7 #define PCI_DEVICE_ID_3COM_3C985 0x0001 #define PCI_DEVICE_ID_3COM_3C940 0x1700 #define PCI_DEVICE_ID_3COM_3C339 0x3390 #define PCI_DEVICE_ID_3COM_3C359 0x3590 -#define PCI_DEVICE_ID_3COM_3C590 0x5900 -#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 -#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 -#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 #define PCI_DEVICE_ID_3COM_3C940B 0x80eb -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 #define PCI_DEVICE_ID_3COM_3CR990 0x9900 #define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902 #define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903 @@ -1077,24 +916,11 @@ #define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909 #define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a -#define PCI_VENDOR_ID_SMC 0x10b8 -#define PCI_DEVICE_ID_SMC_EPIC100 0x0005 #define PCI_VENDOR_ID_AL 0x10b9 -#define PCI_DEVICE_ID_AL_M1445 0x1445 -#define PCI_DEVICE_ID_AL_M1449 0x1449 -#define PCI_DEVICE_ID_AL_M1451 0x1451 -#define PCI_DEVICE_ID_AL_M1461 0x1461 -#define PCI_DEVICE_ID_AL_M1489 0x1489 -#define PCI_DEVICE_ID_AL_M1511 0x1511 -#define PCI_DEVICE_ID_AL_M1513 0x1513 -#define PCI_DEVICE_ID_AL_M1521 0x1521 -#define PCI_DEVICE_ID_AL_M1523 0x1523 -#define PCI_DEVICE_ID_AL_M1531 0x1531 #define PCI_DEVICE_ID_AL_M1533 0x1533 #define PCI_DEVICE_ID_AL_M1535 0x1535 #define PCI_DEVICE_ID_AL_M1541 0x1541 -#define PCI_DEVICE_ID_AL_M1543 0x1543 #define PCI_DEVICE_ID_AL_M1563 0x1563 #define PCI_DEVICE_ID_AL_M1621 0x1621 #define PCI_DEVICE_ID_AL_M1631 0x1631 @@ -1107,49 +933,23 @@ #define PCI_DEVICE_ID_AL_M1681 0x1681 #define PCI_DEVICE_ID_AL_M1683 0x1683 #define PCI_DEVICE_ID_AL_M1689 0x1689 -#define PCI_DEVICE_ID_AL_M3307 0x3307 -#define PCI_DEVICE_ID_AL_M4803 0x5215 #define PCI_DEVICE_ID_AL_M5219 0x5219 #define PCI_DEVICE_ID_AL_M5228 0x5228 #define PCI_DEVICE_ID_AL_M5229 0x5229 -#define PCI_DEVICE_ID_AL_M5237 0x5237 -#define PCI_DEVICE_ID_AL_M5243 0x5243 #define PCI_DEVICE_ID_AL_M5451 0x5451 #define PCI_DEVICE_ID_AL_M7101 0x7101 -#define PCI_VENDOR_ID_MITSUBISHI 0x10ba -#define PCI_VENDOR_ID_SURECOM 0x10bd -#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34 #define PCI_VENDOR_ID_NEOMAGIC 0x10c8 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083 #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 #define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 -#define PCI_VENDOR_ID_ASP 0x10cd -#define PCI_DEVICE_ID_ASP_ABP940 0x1200 -#define PCI_DEVICE_ID_ASP_ABP940U 0x1300 -#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300 - -#define PCI_VENDOR_ID_MACRONIX 0x10d9 -#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512 -#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531 #define PCI_VENDOR_ID_TCONRAD 0x10da #define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 -#define PCI_VENDOR_ID_CERN 0x10dc -#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001 -#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002 -#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021 -#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022 #define PCI_VENDOR_ID_NVIDIA 0x10de #define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 @@ -1281,7 +1081,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 -#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 @@ -1332,24 +1131,13 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 #define PCI_VENDOR_ID_IMS 0x10e0 -#define PCI_DEVICE_ID_IMS_8849 0x8849 #define PCI_DEVICE_ID_IMS_TT128 0x9128 #define PCI_DEVICE_ID_IMS_TT3D 0x9135 -#define PCI_VENDOR_ID_TEKRAM2 0x10e1 -#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000 -#define PCI_VENDOR_ID_AMCC 0x10e8 -#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 -#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062 -#define PCI_DEVICE_ID_AMCC_S5933 0x807d -#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c #define PCI_VENDOR_ID_INTERG 0x10ea -#define PCI_DEVICE_ID_INTERG_1680 0x1680 #define PCI_DEVICE_ID_INTERG_1682 0x1682 #define PCI_DEVICE_ID_INTERG_2000 0x2000 #define PCI_DEVICE_ID_INTERG_2010 0x2010 @@ -1357,27 +1145,18 @@ #define PCI_DEVICE_ID_INTERG_5050 0x5050 #define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_DEVICE_ID_REALTEK_8029 0x8029 -#define PCI_DEVICE_ID_REALTEK_8129 0x8129 #define PCI_DEVICE_ID_REALTEK_8139 0x8139 -#define PCI_DEVICE_ID_REALTEK_8169 0x8169 #define PCI_VENDOR_ID_XILINX 0x10ee #define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 #define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1 #define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2 #define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3 -#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 -#define PCI_DEVICE_ID_TURBOPAM 0x4020 -#define PCI_VENDOR_ID_TRUEVISION 0x10fa -#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c #define PCI_VENDOR_ID_INIT 0x1101 -#define PCI_DEVICE_ID_INIT_320P 0x9100 -#define PCI_DEVICE_ID_INIT_360P 0x9500 #define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 @@ -1405,36 +1184,25 @@ #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 -#define PCI_DEVICE_ID_VIA_82C505 0x0505 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 #define PCI_DEVICE_ID_VIA_82C576 0x0576 -#define PCI_DEVICE_ID_VIA_82C585 0x0585 #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 -#define PCI_DEVICE_ID_VIA_82C595 0x0595 #define PCI_DEVICE_ID_VIA_82C596 0x0596 #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 #define PCI_DEVICE_ID_VIA_82C598_0 0x0598 #define PCI_DEVICE_ID_VIA_8601_0 0x0601 #define PCI_DEVICE_ID_VIA_8605_0 0x0605 -#define PCI_DEVICE_ID_VIA_82C680 0x0680 #define PCI_DEVICE_ID_VIA_82C686 0x0686 #define PCI_DEVICE_ID_VIA_82C691_0 0x0691 -#define PCI_DEVICE_ID_VIA_82C693 0x0693 -#define PCI_DEVICE_ID_VIA_82C693_1 0x0698 -#define PCI_DEVICE_ID_VIA_82C926 0x0926 #define PCI_DEVICE_ID_VIA_82C576_1 0x1571 -#define PCI_DEVICE_ID_VIA_82C595_97 0x1595 #define PCI_DEVICE_ID_VIA_82C586_2 0x3038 #define PCI_DEVICE_ID_VIA_82C586_3 0x3040 -#define PCI_DEVICE_ID_VIA_6305 0x3044 #define PCI_DEVICE_ID_VIA_82C596_3 0x3050 #define PCI_DEVICE_ID_VIA_82C596B_3 0x3051 #define PCI_DEVICE_ID_VIA_82C686_4 0x3057 #define PCI_DEVICE_ID_VIA_82C686_5 0x3058 #define PCI_DEVICE_ID_VIA_8233_5 0x3059 -#define PCI_DEVICE_ID_VIA_8233_7 0x3065 -#define PCI_DEVICE_ID_VIA_82C686_6 0x3068 #define PCI_DEVICE_ID_VIA_8233_0 0x3074 #define PCI_DEVICE_ID_VIA_8633_0 0x3091 #define PCI_DEVICE_ID_VIA_8367_0 0x3099 @@ -1452,38 +1220,23 @@ #define PCI_DEVICE_ID_VIA_XN266 0x3156 #define PCI_DEVICE_ID_VIA_8754C_0 0x3168 #define PCI_DEVICE_ID_VIA_8235 0x3177 -#define PCI_DEVICE_ID_VIA_P4N333 0x3178 #define PCI_DEVICE_ID_VIA_8385_0 0x3188 #define PCI_DEVICE_ID_VIA_8377_0 0x3189 #define PCI_DEVICE_ID_VIA_8378_0 0x3205 #define PCI_DEVICE_ID_VIA_8783_0 0x3208 -#define PCI_DEVICE_ID_VIA_P4M400 0x3209 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_3296_0 0x0296 -#define PCI_DEVICE_ID_VIA_86C100A 0x6100 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 -#define PCI_DEVICE_ID_VIA_8501_1 0x8501 -#define PCI_DEVICE_ID_VIA_82C597_1 0x8597 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 -#define PCI_DEVICE_ID_VIA_8601_1 0x8601 -#define PCI_DEVICE_ID_VIA_8505_1 0x8605 -#define PCI_DEVICE_ID_VIA_8633_1 0xB091 -#define PCI_DEVICE_ID_VIA_8367_1 0xB099 -#define PCI_DEVICE_ID_VIA_P4X266_1 0xB101 -#define PCI_DEVICE_ID_VIA_8615_1 0xB103 -#define PCI_DEVICE_ID_VIA_8361_1 0xB112 -#define PCI_DEVICE_ID_VIA_8235_1 0xB168 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 #define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 -#define PCI_VENDOR_ID_SMC2 0x1113 -#define PCI_DEVICE_ID_SMC2_1211TX 0x1211 #define PCI_VENDOR_ID_VORTEX 0x1119 #define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 @@ -1506,18 +1259,6 @@ #define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 #define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 #define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110 -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111 -#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112 -#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113 -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114 -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115 -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120 -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121 -#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122 -#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123 -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124 -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125 #define PCI_VENDOR_ID_EF 0x111a #define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 @@ -1529,21 +1270,15 @@ #define PCI_DEVICE_ID_IDT_IDT77201 0x0001 #define PCI_VENDOR_ID_FORE 0x1127 -#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 #define PCI_DEVICE_ID_FORE_PCA200E 0x0300 -#define PCI_VENDOR_ID_IMAGINGTECH 0x112f -#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 #define PCI_VENDOR_ID_PHILIPS 0x1131 -#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145 #define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 #define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730 #define PCI_VENDOR_ID_EICON 0x1133 -#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001 #define PCI_DEVICE_ID_EICON_DIVA20 0xe002 -#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003 #define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004 #define PCI_DEVICE_ID_EICON_DIVA201 0xe005 #define PCI_DEVICE_ID_EICON_DIVA202 0xe00b @@ -1555,35 +1290,17 @@ #define PCI_VENDOR_ID_ZIATECH 0x1138 #define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 -#define PCI_VENDOR_ID_CYCLONE 0x113c -#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001 -#define PCI_VENDOR_ID_ALLIANCE 0x1142 -#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210 -#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422 -#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424 -#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d #define PCI_VENDOR_ID_SYSKONNECT 0x1148 -#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000 #define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 #define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 #define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 #define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400 #define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500 -#define PCI_VENDOR_ID_VMIC 0x114a -#define PCI_DEVICE_ID_VMIC_VME 0x7587 #define PCI_VENDOR_ID_DIGI 0x114f -#define PCI_DEVICE_ID_DIGI_EPC 0x0002 -#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003 -#define PCI_DEVICE_ID_DIGI_XEM 0x0004 -#define PCI_DEVICE_ID_DIGI_XR 0x0005 -#define PCI_DEVICE_ID_DIGI_CX 0x0006 -#define PCI_DEVICE_ID_DIGI_XRJ 0x0009 -#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a -#define PCI_DEVICE_ID_DIGI_XR_920 0x0027 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070 #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 @@ -1593,23 +1310,15 @@ #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA #define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB -#define PCI_VENDOR_ID_MUTECH 0x1159 -#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 #define PCI_VENDOR_ID_XIRCOM 0x115d -#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003 #define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101 #define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103 -#define PCI_VENDOR_ID_RENDITION 0x1163 -#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 -#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 #define PCI_VENDOR_ID_SERVERWORKS 0x1166 #define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 -#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010 -#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 @@ -1619,13 +1328,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 -#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 -#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 -#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230 #define PCI_VENDOR_ID_SBE 0x1176 #define PCI_DEVICE_ID_SBE_WANXL100 0x0301 @@ -1636,17 +1339,12 @@ #define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102 #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103 #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105 -#define PCI_DEVICE_ID_TOSHIBA_601 0x0601 #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603 -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a #define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f #define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617 #define PCI_VENDOR_ID_TOSHIBA_2 0x102f -#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a #define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 -#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180 #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 @@ -1661,7 +1359,6 @@ #define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 #define PCI_VENDOR_ID_ARTOP 0x1191 -#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 #define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 #define PCI_DEVICE_ID_ARTOP_ATP860 0x0006 #define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 @@ -1674,16 +1371,11 @@ #define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040 #define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050 #define PCI_DEVICE_ID_ARTOP_8060 0x8060 -#define PCI_DEVICE_ID_ARTOP_AEC67160 0x8080 -#define PCI_DEVICE_ID_ARTOP_AEC67160_2 0x8081 -#define PCI_DEVICE_ID_ARTOP_AEC67162 0x808a #define PCI_VENDOR_ID_ZEITNET 0x1193 #define PCI_DEVICE_ID_ZEITNET_1221 0x0001 #define PCI_DEVICE_ID_ZEITNET_1225 0x0002 -#define PCI_VENDOR_ID_OMEGA 0x119b -#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221 #define PCI_VENDOR_ID_FUJITSU_ME 0x119e #define PCI_DEVICE_ID_FUJITSU_FS155 0x0001 @@ -1693,61 +1385,41 @@ #define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 #define PCI_VENDOR_ID_MARVELL 0x11ab -#define PCI_DEVICE_ID_MARVELL_GT64011 0x4146 -#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 #define PCI_DEVICE_ID_MARVELL_GT96100 0x9652 #define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653 -#define PCI_VENDOR_ID_LITEON 0x11ad -#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002 #define PCI_VENDOR_ID_V3 0x11b0 #define PCI_DEVICE_ID_V3_V960 0x0001 -#define PCI_DEVICE_ID_V3_V350 0x0001 -#define PCI_DEVICE_ID_V3_V961 0x0002 #define PCI_DEVICE_ID_V3_V351 0x0002 -#define PCI_VENDOR_ID_NP 0x11bc -#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001 #define PCI_VENDOR_ID_ATT 0x11c1 -#define PCI_DEVICE_ID_ATT_L56XMF 0x0440 #define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 -#define PCI_VENDOR_ID_NEC2 0x11c3 /* NEC (2nd) */ #define PCI_VENDOR_ID_SPECIALIX 0x11cb #define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 -#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000 #define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 #define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 -#define PCI_VENDOR_ID_AURAVISION 0x11d1 -#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7 #define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 #define PCI_DEVICE_ID_AD1889JS 0x1889 -#define PCI_VENDOR_ID_IKON 0x11d5 -#define PCI_DEVICE_ID_IKON_10115 0x0115 -#define PCI_DEVICE_ID_IKON_10117 0x0117 -#define PCI_VENDOR_ID_SEGA 0x11db #define PCI_DEVICE_ID_SEGA_BBA 0x1234 #define PCI_VENDOR_ID_ZORAN 0x11de #define PCI_DEVICE_ID_ZORAN_36057 0x6057 #define PCI_DEVICE_ID_ZORAN_36120 0x6120 -#define PCI_VENDOR_ID_KINETIC 0x11f4 -#define PCI_DEVICE_ID_KINETIC_2915 0x2915 #define PCI_VENDOR_ID_COMPEX 0x11f6 #define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 -#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 #define PCI_VENDOR_ID_RP 0x11fe #define PCI_DEVICE_ID_RP32INTF 0x0001 @@ -1761,7 +1433,6 @@ #define PCI_DEVICE_ID_RP16SNI 0x0009 #define PCI_DEVICE_ID_RPP4 0x000A #define PCI_DEVICE_ID_RPP8 0x000B -#define PCI_DEVICE_ID_RP8M 0x000C #define PCI_DEVICE_ID_RP4M 0x000D #define PCI_DEVICE_ID_RP2_232 0x000E #define PCI_DEVICE_ID_RP2_422 0x000F @@ -1805,10 +1476,7 @@ #define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005 #define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 -#define PCI_VENDOR_ID_SIGMADES 0x1236 -#define PCI_DEVICE_ID_SIGMADES_6425 0x6401 -#define PCI_VENDOR_ID_CCUBE 0x123f #define PCI_VENDOR_ID_AVM 0x1244 #define PCI_DEVICE_ID_AVM_B1 0x0700 @@ -1818,19 +1486,8 @@ #define PCI_DEVICE_ID_AVM_C2 0x1100 #define PCI_DEVICE_ID_AVM_T1 0x1200 -#define PCI_VENDOR_ID_DIPIX 0x1246 #define PCI_VENDOR_ID_STALLION 0x124d -#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000 -#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002 -#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003 - -#define PCI_VENDOR_ID_OPTIBASE 0x1255 -#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110 -#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210 -#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110 -#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120 -#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130 /* Allied Telesyn */ #define PCI_VENDOR_ID_AT 0x1259 @@ -1839,7 +1496,6 @@ #define PCI_VENDOR_ID_ESS 0x125d #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 -#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969 #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 #define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988 #define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989 @@ -1852,11 +1508,7 @@ #define PCI_VENDOR_ID_SATSAGEM 0x1267 #define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 -#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352 -#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b -#define PCI_VENDOR_ID_HUGHES 0x1273 -#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002 #define PCI_VENDOR_ID_ENSONIQ 0x1274 #define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 @@ -1877,13 +1529,10 @@ #define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 /* formerly Platform Tech */ -#define PCI_VENDOR_ID_ESS_OLD 0x1285 #define PCI_DEVICE_ID_ESS_ESS0100 0x0100 #define PCI_VENDOR_ID_ALTEON 0x12ae -#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001 -#define PCI_VENDOR_ID_USR 0x12B9 #define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001 @@ -1898,8 +1547,6 @@ #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B -#define PCI_VENDOR_ID_PICTUREL 0x12c5 -#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081 #define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 #define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 @@ -1921,8 +1568,6 @@ #define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8 #define PCI_DEVICE_ID_LML_33R10 0x8a02 -#define PCI_VENDOR_ID_CBOARDS 0x1307 -#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001 #define PCI_VENDOR_ID_SIIG 0x131f #define PCI_SUBVENDOR_ID_SIIG 0x131f @@ -1965,8 +1610,6 @@ #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 -#define PCI_VENDOR_ID_RADISYS 0x1331 -#define PCI_DEVICE_ID_RADISYS_ENP2611 0x0030 #define PCI_VENDOR_ID_DOMEX 0x134a #define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 @@ -1974,8 +1617,6 @@ #define PCI_VENDOR_ID_QUATECH 0x135C #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 -#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030 -#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040 #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 @@ -1994,7 +1635,6 @@ #define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106 #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 -#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109 #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 @@ -2008,12 +1648,9 @@ #define PCI_DEVICE_ID_LMC_SSI 0x0005 #define PCI_DEVICE_ID_LMC_T1 0x0006 -#define PCI_VENDOR_ID_MARIAN 0x1382 -#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048 #define PCI_VENDOR_ID_NETGEAR 0x1385 #define PCI_DEVICE_ID_NETGEAR_GA620 0x620a -#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a #define PCI_VENDOR_ID_APPLICOM 0x1389 #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 @@ -2036,9 +1673,6 @@ #define PCI_DEVICE_ID_MOXA_CP134U 0x1340 #define PCI_DEVICE_ID_MOXA_C168 0x1680 #define PCI_DEVICE_ID_MOXA_CP168U 0x1681 -#define PCI_DEVICE_ID_MOXA_CP204J 0x2040 -#define PCI_DEVICE_ID_MOXA_C218 0x2180 -#define PCI_DEVICE_ID_MOXA_C320 0x3200 #define PCI_VENDOR_ID_CCD 0x1397 #define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 @@ -2059,9 +1693,7 @@ #define PCI_VENDOR_ID_MICROGATE 0x13c0 #define PCI_DEVICE_ID_MICROGATE_USC 0x0010 -#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 -#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 #define PCI_VENDOR_ID_3WARE 0x13C1 #define PCI_DEVICE_ID_3WARE_1000 0x1000 @@ -2112,10 +1744,6 @@ #define PCI_VENDOR_ID_SAMSUNG 0x144d -#define PCI_VENDOR_ID_AIRONET 0x14b9 -#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001 -#define PCI_DEVICE_ID_AIRONET_4800 0x4500 // values switched? see -#define PCI_DEVICE_ID_AIRONET_4500 0x4800 // drivers/net/aironet4500_card.c #define PCI_VENDOR_ID_TITAN 0x14D2 #define PCI_DEVICE_ID_TITAN_010L 0x8001 @@ -2134,8 +1762,6 @@ #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 #define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 -#define PCI_VENDOR_ID_SIPACKETS 0x14d9 -#define PCI_DEVICE_ID_SP_HT 0x0010 #define PCI_VENDOR_ID_AFAVLAB 0x14db #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 @@ -2200,8 +1826,6 @@ #define PCI_VENDOR_ID_CHELSIO 0x1425 -#define PCI_VENDOR_ID_MIPS 0x153f -#define PCI_DEVICE_ID_SOC_IT 0x0001 #define PCI_VENDOR_ID_SYBA 0x1592 #define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 @@ -2221,15 +1845,7 @@ #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 #define PCI_VENDOR_ID_PDC 0x15e9 -#define PCI_DEVICE_ID_PDC_1841 0x1841 -#define PCI_VENDOR_ID_MACROLINK 0x15ed -#define PCI_DEVICE_ID_MACROLINK_MCCS8 0x1000 -#define PCI_DEVICE_ID_MACROLINK_MCCS 0x1001 -#define PCI_DEVICE_ID_MACROLINK_MCCS8H 0x1002 -#define PCI_DEVICE_ID_MACROLINK_MCCSH 0x1003 -#define PCI_DEVICE_ID_MACROLINK_MCCR8 0x2000 -#define PCI_DEVICE_ID_MACROLINK_MCCR 0x2001 #define PCI_VENDOR_ID_FARSITE 0x1619 #define PCI_DEVICE_ID_FARSITE_T2P 0x0400 @@ -2247,7 +1863,6 @@ #define PCI_DEVICE_ID_REVOLUTION 0x0044 #define PCI_VENDOR_ID_LINKSYS 0x1737 -#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 #define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 #define PCI_VENDOR_ID_ALTIMA 0x173b @@ -2262,7 +1877,6 @@ #define PCI_DEVICE_ID_HERC_WIN 0x5732 #define PCI_DEVICE_ID_HERC_UNI 0x5832 -#define PCI_VENDOR_ID_INFINICON 0x1820 #define PCI_VENDOR_ID_SITECOM 0x182d #define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069 @@ -2272,8 +1886,6 @@ #define PCI_VENDOR_ID_TDI 0x192E #define PCI_DEVICE_ID_TDI_EHCI 0x0101 -#define PCI_VENDOR_ID_SYMPHONY 0x1c1c -#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 @@ -2282,59 +1894,26 @@ #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 #define PCI_VENDOR_ID_3DLABS 0x3d3d -#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 -#define PCI_DEVICE_ID_3DLABS_500TX 0x0002 -#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003 -#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004 -#define PCI_DEVICE_ID_3DLABS_MX 0x0006 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 -#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 -#define PCI_VENDOR_ID_AVANCE 0x4005 -#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064 -#define PCI_DEVICE_ID_AVANCE_2302 0x2302 #define PCI_VENDOR_ID_AKS 0x416c #define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100 -#define PCI_DEVICE_ID_AKS_CPC 0x0200 -#define PCI_VENDOR_ID_REDCREEK 0x4916 -#define PCI_DEVICE_ID_RC45 0x1960 -#define PCI_VENDOR_ID_NETVIN 0x4a14 -#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 #define PCI_VENDOR_ID_S3 0x5333 -#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551 -#define PCI_DEVICE_ID_S3_ViRGE 0x5631 #define PCI_DEVICE_ID_S3_TRIO 0x8811 -#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812 -#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814 -#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d #define PCI_DEVICE_ID_S3_868 0x8880 -#define PCI_DEVICE_ID_S3_928 0x88b0 -#define PCI_DEVICE_ID_S3_864_1 0x88c0 -#define PCI_DEVICE_ID_S3_864_2 0x88c1 -#define PCI_DEVICE_ID_S3_964_1 0x88d0 -#define PCI_DEVICE_ID_S3_964_2 0x88d1 #define PCI_DEVICE_ID_S3_968 0x88f0 -#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901 -#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902 -#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01 -#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10 #define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25 -#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01 -#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02 -#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 #define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04 #define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 #define PCI_VENDOR_ID_DUNORD 0x5544 #define PCI_DEVICE_ID_DUNORD_I3000 0x0001 -#define PCI_VENDOR_ID_GENROCO 0x5555 -#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 #define PCI_VENDOR_ID_DCI 0x6666 #define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 @@ -2342,7 +1921,6 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 -#define PCI_DEVICE_ID_INTEL_21145 0x0039 #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 @@ -2351,30 +1929,17 @@ #define PCI_DEVICE_ID_INTEL_82375 0x0482 #define PCI_DEVICE_ID_INTEL_82424 0x0483 #define PCI_DEVICE_ID_INTEL_82378 0x0484 -#define PCI_DEVICE_ID_INTEL_82430 0x0486 -#define PCI_DEVICE_ID_INTEL_82434 0x04a3 #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 -#define PCI_DEVICE_ID_INTEL_82562ET 0x1031 -#define PCI_DEVICE_ID_INTEL_82801CAM 0x1038 #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 -#define PCI_DEVICE_ID_INTEL_82815_AB 0x1131 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 -#define PCI_DEVICE_ID_INTEL_82559ER 0x1209 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 -#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222 -#define PCI_DEVICE_ID_INTEL_7116 0x1223 #define PCI_DEVICE_ID_INTEL_7505_0 0x2550 -#define PCI_DEVICE_ID_INTEL_7505_1 0x2552 #define PCI_DEVICE_ID_INTEL_7205_0 0x255d -#define PCI_DEVICE_ID_INTEL_82596 0x1226 -#define PCI_DEVICE_ID_INTEL_82865 0x1227 -#define PCI_DEVICE_ID_INTEL_82557 0x1229 #define PCI_DEVICE_ID_INTEL_82437 0x122d #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e #define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 #define PCI_DEVICE_ID_INTEL_82371MX 0x1234 -#define PCI_DEVICE_ID_INTEL_82437MX 0x1235 #define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82380FB 0x124b #define PCI_DEVICE_ID_INTEL_82439 0x1250 @@ -2383,83 +1948,53 @@ #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 -#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 #define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 #define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416 #define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418 #define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 #define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421 -#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422 #define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423 #define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425 #define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426 #define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428 #define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440 -#define PCI_DEVICE_ID_INTEL_82801BA_1 0x2442 #define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443 -#define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444 #define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445 -#define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446 #define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448 -#define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449 #define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a #define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b #define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c #define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e #define PCI_DEVICE_ID_INTEL_82801E_0 0x2450 -#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452 -#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453 -#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459 #define PCI_DEVICE_ID_INTEL_82801E_11 0x245b -#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d -#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e #define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 -#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482 #define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 -#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484 #define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485 #define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486 -#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487 #define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a #define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b #define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c #define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 #define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1 -#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2 #define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 -#define PCI_DEVICE_ID_INTEL_82801DB_4 0x24c4 #define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 #define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 -#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7 #define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9 #define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca #define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb #define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc -#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd #define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0 #define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1 -#define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2 #define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3 -#define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4 #define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 #define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 -#define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7 #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db -#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd #define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 #define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 -#define PCI_DEVICE_ID_INTEL_ESB_3 0x25a3 -#define PCI_DEVICE_ID_INTEL_ESB_31 0x25b0 #define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 #define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6 -#define PCI_DEVICE_ID_INTEL_ESB_6 0x25a7 -#define PCI_DEVICE_ID_INTEL_ESB_7 0x25a9 -#define PCI_DEVICE_ID_INTEL_ESB_8 0x25aa #define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab -#define PCI_DEVICE_ID_INTEL_ESB_11 0x25ac -#define PCI_DEVICE_ID_INTEL_ESB_12 0x25ad -#define PCI_DEVICE_ID_INTEL_ESB_13 0x25ae #define PCI_DEVICE_ID_INTEL_82820_HB 0x2500 #define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501 #define PCI_DEVICE_ID_INTEL_82850_HB 0x2530 @@ -2469,7 +2004,6 @@ #define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 #define PCI_DEVICE_ID_INTEL_82865_IG 0x2572 #define PCI_DEVICE_ID_INTEL_82875_HB 0x2578 -#define PCI_DEVICE_ID_INTEL_82875_IG 0x257b #define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580 #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 @@ -2479,80 +2013,23 @@ #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 -#define PCI_DEVICE_ID_INTEL_ICH6_3 0x2651 -#define PCI_DEVICE_ID_INTEL_ICH6_4 0x2652 -#define PCI_DEVICE_ID_INTEL_ICH6_5 0x2653 -#define PCI_DEVICE_ID_INTEL_ICH6_6 0x2658 -#define PCI_DEVICE_ID_INTEL_ICH6_7 0x2659 -#define PCI_DEVICE_ID_INTEL_ICH6_8 0x265a -#define PCI_DEVICE_ID_INTEL_ICH6_9 0x265b -#define PCI_DEVICE_ID_INTEL_ICH6_10 0x265c -#define PCI_DEVICE_ID_INTEL_ICH6_11 0x2660 -#define PCI_DEVICE_ID_INTEL_ICH6_12 0x2662 -#define PCI_DEVICE_ID_INTEL_ICH6_13 0x2664 -#define PCI_DEVICE_ID_INTEL_ICH6_14 0x2666 -#define PCI_DEVICE_ID_INTEL_ICH6_15 0x2668 #define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a #define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d #define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e #define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f #define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670 -#define PCI_DEVICE_ID_INTEL_ESB2_1 0x2680 -#define PCI_DEVICE_ID_INTEL_ESB2_2 0x2681 -#define PCI_DEVICE_ID_INTEL_ESB2_3 0x2682 -#define PCI_DEVICE_ID_INTEL_ESB2_4 0x2683 -#define PCI_DEVICE_ID_INTEL_ESB2_5 0x2688 -#define PCI_DEVICE_ID_INTEL_ESB2_6 0x2689 -#define PCI_DEVICE_ID_INTEL_ESB2_7 0x268a -#define PCI_DEVICE_ID_INTEL_ESB2_8 0x268b -#define PCI_DEVICE_ID_INTEL_ESB2_9 0x268c -#define PCI_DEVICE_ID_INTEL_ESB2_10 0x2690 -#define PCI_DEVICE_ID_INTEL_ESB2_11 0x2692 -#define PCI_DEVICE_ID_INTEL_ESB2_12 0x2694 -#define PCI_DEVICE_ID_INTEL_ESB2_13 0x2696 #define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 -#define PCI_DEVICE_ID_INTEL_ESB2_15 0x2699 -#define PCI_DEVICE_ID_INTEL_ESB2_16 0x269a #define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b #define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e #define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 -#define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0 -#define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1 #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd -#define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4 -#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5 -#define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8 -#define PCI_DEVICE_ID_INTEL_ICH7_8 0x27c9 -#define PCI_DEVICE_ID_INTEL_ICH7_9 0x27ca -#define PCI_DEVICE_ID_INTEL_ICH7_10 0x27cb -#define PCI_DEVICE_ID_INTEL_ICH7_11 0x27cc -#define PCI_DEVICE_ID_INTEL_ICH7_12 0x27d0 -#define PCI_DEVICE_ID_INTEL_ICH7_13 0x27d2 -#define PCI_DEVICE_ID_INTEL_ICH7_14 0x27d4 -#define PCI_DEVICE_ID_INTEL_ICH7_15 0x27d6 -#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8 #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da -#define PCI_DEVICE_ID_INTEL_ICH7_18 0x27dc #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de #define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df -#define PCI_DEVICE_ID_INTEL_ICH7_22 0x27e0 -#define PCI_DEVICE_ID_INTEL_ICH7_23 0x27e2 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 -#define PCI_DEVICE_ID_INTEL_ESB2_19 0x3500 -#define PCI_DEVICE_ID_INTEL_ESB2_20 0x3501 -#define PCI_DEVICE_ID_INTEL_ESB2_21 0x3504 -#define PCI_DEVICE_ID_INTEL_ESB2_22 0x3505 -#define PCI_DEVICE_ID_INTEL_ESB2_23 0x350c -#define PCI_DEVICE_ID_INTEL_ESB2_24 0x350d -#define PCI_DEVICE_ID_INTEL_ESB2_25 0x3510 -#define PCI_DEVICE_ID_INTEL_ESB2_26 0x3511 -#define PCI_DEVICE_ID_INTEL_ESB2_27 0x3514 -#define PCI_DEVICE_ID_INTEL_ESB2_28 0x3515 -#define PCI_DEVICE_ID_INTEL_ESB2_29 0x3518 -#define PCI_DEVICE_ID_INTEL_ESB2_30 0x3519 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 @@ -2566,7 +2043,6 @@ #define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 #define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e -#define PCI_DEVICE_ID_INTEL_80310 0x530d #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 @@ -2591,22 +2067,15 @@ #define PCI_DEVICE_ID_INTEL_440MX_6 0x7196 #define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198 #define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199 -#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a #define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 -#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1 #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 -#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 -#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602 -#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 -#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca #define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_DEVICE_ID_INTEL_84460GX 0x84ea #define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500 -#define PCI_DEVICE_ID_INTEL_IXP2400 0x9001 #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 @@ -2619,7 +2088,6 @@ #define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003 #define PCI_VENDOR_ID_KTI 0x8e2e -#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 #define PCI_VENDOR_ID_ADAPTEC 0x9004 #define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 @@ -2627,7 +2095,6 @@ #define PCI_DEVICE_ID_ADAPTEC_38602 0x3860 #define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 #define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 -#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800 #define PCI_DEVICE_ID_ADAPTEC_3860 0x6038 #define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 #define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 @@ -2647,7 +2114,6 @@ #define PCI_DEVICE_ID_ADAPTEC_7886 0x8678 #define PCI_DEVICE_ID_ADAPTEC_7887 0x8778 #define PCI_DEVICE_ID_ADAPTEC_7888 0x8878 -#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78 #define PCI_VENDOR_ID_ADAPTEC2 0x9005 #define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 @@ -2667,8 +2133,6 @@ #define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf #define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503 -#define PCI_VENDOR_ID_ATRONICS 0x907f -#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 #define PCI_VENDOR_ID_HOLTEK 0x9412 #define PCI_DEVICE_ID_HOLTEK_6565 0x6565 @@ -2701,7 +2165,3 @@ #define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897 #define PCI_DEVICE_ID_RME_DIGI32_8 0x9898 -#define PCI_VENDOR_ID_ARK 0xedd8 -#define PCI_DEVICE_ID_ARK_STING 0xa091 -#define PCI_DEVICE_ID_ARK_STINGARK 0xa099 -#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 From 934199e95d6ac28f42686fe3009877eff33e06c3 Mon Sep 17 00:00:00 2001 From: linas Date: Wed, 28 Sep 2005 19:33:38 -0500 Subject: [PATCH 0784/1940] [PATCH] ppc64 PCI Hotplug: cleanup unsymmetric API routines This is a minor patch to the ppc64 PCI hotplug code; it makes the call to rpaphp_unconfig_pci_adapter() symmetric with respect to the call to rpaphp_config_pci_adapter(). I discussed this with John Rose, who had provided the last round of changes for these functions; he appearently had this patch but somehow failed to mail it out. Tested. (added/removed device). Signed-off-by: Linas Vepstas drivers/pci/hotplug/rpaphp.h | 3 ++- drivers/pci/hotplug/rpaphp_core.c | 5 ++++- drivers/pci/hotplug/rpaphp_pci.c | 11 +++-------- 3 files changed, 9 insertions(+), 10 deletions(-) --- drivers/pci/hotplug/rpaphp.h | 3 ++- drivers/pci/hotplug/rpaphp_core.c | 5 ++++- drivers/pci/hotplug/rpaphp_pci.c | 11 +++-------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 61d94d1e29cb..71ea5f9bb284 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -92,9 +92,10 @@ extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn); extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); -extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); + extern int rpaphp_config_pci_adapter(struct pci_bus *bus); +extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c830ff0acdc3..cf075c34b578 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -426,8 +426,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) dbg("DISABLING SLOT %s\n", slot->name); down(&rpaphp_sem); - retval = rpaphp_unconfig_pci_adapter(slot); + retval = rpaphp_unconfig_pci_adapter(slot->bus); up(&rpaphp_sem); + slot->state = NOT_CONFIGURED; + info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, + slot->name); exit: dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 49e4d10a6488..46c157d26a2f 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -319,20 +319,15 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) return; } -int rpaphp_unconfig_pci_adapter(struct slot *slot) +int rpaphp_unconfig_pci_adapter(struct pci_bus *bus) { struct pci_dev *dev, *tmp; - int retval = 0; - list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) { + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { rpaphp_eeh_remove_bus_device(dev); pci_remove_bus_device(dev); } - - slot->state = NOT_CONFIGURED; - info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, - slot->name); - return retval; + return 0; } static int setup_pci_hotplug_slot_info(struct slot *slot) From e3b1bd572f1cdb247bb4266a593b6894dc578d6a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 21 Sep 2005 22:26:31 +0200 Subject: [PATCH 0785/1940] [PATCH] PCI: Add quirk for SMBus on HP D530 One more SMBus unhiding quirk, this time for the HP D530. Requested and successfully tested by Ben Cranston. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e1bd169cf55c..ee1605906a3e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -950,6 +950,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) switch (dev->subsystem_device) { case 0x12bc: /* HP D330L */ + case 0x12bd: /* HP D530 */ asus_hides_smbus = 1; } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { From dbd7a78818d125a0ebd5507d4edb4dd5900006ab Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:36 -0700 Subject: [PATCH 0786/1940] [PATCH] shpchp: use the PCI core for hotplug resource management This patch converts the standard hotplug controller driver to use the PCI core for resource management. This eliminates a whole lot of duplicated code, and integrates shpchp in the system's normal PCI handling code. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 57 +- drivers/pci/hotplug/shpchp_core.c | 36 +- drivers/pci/hotplug/shpchp_ctrl.c | 1650 +----------------------- drivers/pci/hotplug/shpchp_pci.c | 482 +------ drivers/pci/hotplug/shpchp_sysfs.c | 121 +- drivers/pci/hotplug/shpchprm.h | 12 - drivers/pci/hotplug/shpchprm_acpi.c | 851 ------------ drivers/pci/hotplug/shpchprm_legacy.c | 294 ----- drivers/pci/hotplug/shpchprm_legacy.h | 113 -- drivers/pci/hotplug/shpchprm_nonacpi.c | 278 ---- drivers/pci/hotplug/shpchprm_nonacpi.h | 56 - 11 files changed, 181 insertions(+), 3769 deletions(-) delete mode 100644 drivers/pci/hotplug/shpchprm_legacy.h delete mode 100644 drivers/pci/hotplug/shpchprm_nonacpi.h diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index b7d1c61d6bbb..deea56c73cf2 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -63,14 +63,7 @@ struct pci_func { u8 switch_save; u8 presence_save; u8 pwr_save; - u32 base_length[0x06]; - u8 base_type[0x06]; - u16 reserved2; u32 config_space[0x20]; - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; struct pci_dev* pci_dev; }; @@ -96,12 +89,6 @@ struct slot { struct list_head slot_list; }; -struct pci_resource { - struct pci_resource * next; - u32 base; - u32 length; -}; - struct event_info { u32 event_type; u8 hp_slot; @@ -113,10 +100,6 @@ struct controller { void * hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; struct pci_dev *pci_dev; struct pci_bus *pci_bus; struct event_info event_queue[10]; @@ -139,20 +122,6 @@ struct controller { u16 vendor_id; }; -struct irq_mapping { - u8 barber_pole; - u8 valid_INT; - u8 interrupt[4]; -}; - -struct resource_lists { - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; - struct irq_mapping *irqs; -}; - /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 @@ -197,7 +166,6 @@ struct resource_lists { #define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n" #define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n" #define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n" -#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n" #define msg_button_on "PCI slot #%d - powering on due to button press.\n" #define msg_button_off "PCI slot #%d - powering off due to button press.\n" #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" @@ -207,7 +175,6 @@ struct resource_lists { extern void shpchp_create_ctrl_files (struct controller *ctrl); /* controller functions */ -extern int shpchprm_find_available_resources(struct controller *ctrl); extern int shpchp_event_start_thread(void); extern void shpchp_event_stop_thread(void); extern struct pci_func *shpchp_slot_create(unsigned char busnumber); @@ -220,19 +187,10 @@ extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id); extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id); extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); -/* resource functions */ -extern int shpchp_resource_sort_and_combine(struct pci_resource **head); - /* pci functions */ -extern int shpchp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); -/*extern int shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/ extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); -extern int shpchp_save_used_resources(struct controller *ctrl, struct pci_func * func, int flag); extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot); -extern void shpchp_destroy_board_resources(struct pci_func * func); -extern int shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources); -extern void shpchp_destroy_resource_list(struct resource_lists * resources); -extern int shpchp_configure_device(struct controller* ctrl, struct pci_func* func); +extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct pci_func* func); @@ -240,10 +198,6 @@ extern int shpchp_unconfigure_device(struct pci_func* func); extern struct controller *shpchp_ctrl_list; extern struct pci_func *shpchp_slot_list[256]; -/* These are added to support AMD shpc */ -extern u8 shpchp_nic_irq; -extern u8 shpchp_disk_irq; - struct ctrl_reg { volatile u32 base_offset; volatile u32 slot_avail1; @@ -398,15 +352,6 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) return retval; } -/* Puts node back in the resource list pointed to by head */ -static inline void return_resource(struct pci_resource **head, struct pci_resource *node) -{ - if (!node || !head) - return; - node->next = *head; - *head = node; -} - #define SLOT_NAME_SIZE 10 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 6f7d8a29957a..8f5da504df34 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -418,16 +418,8 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_ctrl_bus; } - /* Get IO, memory, and IRQ resources for new devices */ - rc = shpchprm_find_available_resources(ctrl); - ctrl->add_support = !rc; + ctrl->add_support = 1; - if (rc) { - dbg("shpchprm_find_available_resources = %#x\n", rc); - err("unable to locate PCI configuration resources for hot plug add.\n"); - goto err_out_free_ctrl_bus; - } - /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { @@ -497,18 +489,6 @@ static int shpc_start_thread(void) return retval; } -static inline void __exit -free_shpchp_res(struct pci_resource *res) -{ - struct pci_resource *tres; - - while (res) { - tres = res; - res = res->next; - kfree(tres); - } -} - static void __exit unload_shpchpd(void) { struct pci_func *next; @@ -522,11 +502,6 @@ static void __exit unload_shpchpd(void) while (ctrl) { cleanup_slots(ctrl); - free_shpchp_res(ctrl->io_head); - free_shpchp_res(ctrl->mem_head); - free_shpchp_res(ctrl->p_mem_head); - free_shpchp_res(ctrl->bus_head); - kfree (ctrl->pci_bus); dbg("%s: calling release_ctlr\n", __FUNCTION__); @@ -541,11 +516,6 @@ static void __exit unload_shpchpd(void) for (loop = 0; loop < 256; loop++) { next = shpchp_slot_list[loop]; while (next != NULL) { - free_shpchp_res(next->io_head); - free_shpchp_res(next->mem_head); - free_shpchp_res(next->p_mem_head); - free_shpchp_res(next->bus_head); - TempSlot = next; next = next->next; kfree(TempSlot); @@ -607,9 +577,7 @@ static int __init shpcd_init(void) if (retval) { shpchprm_cleanup(); shpchp_event_stop_thread(); - } else - shpchprm_print_pirt(); - + } return retval; } diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 91c9903e621f..aa507e453e49 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -38,13 +38,10 @@ #include #include #include +#include "../pci.h" #include "shpchp.h" #include "shpchprm.h" -static u32 configure_new_device(struct controller *ctrl, struct pci_func *func, - u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev); -static int configure_new_function( struct controller *ctrl, struct pci_func *func, - u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev); static void interrupt_event_handler(struct controller *ctrl); static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ @@ -52,9 +49,6 @@ static struct semaphore event_exit; /* guard ensure thread has exited before ca static int event_finished; static unsigned long pushbutton_pending; /* = 0 */ -u8 shpchp_disk_irq; -u8 shpchp_nic_irq; - u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; @@ -260,624 +254,6 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) return rc; } - -/* - * sort_by_size - * - * Sorts nodes on the list by their length. - * Smallest first. - * - */ -static int sort_by_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return(1); - - if (!((*head)->next)) - return(0); - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length > (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length > current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return(0); -} - - -/* - * sort_by_max_size - * - * Sorts nodes on the list by their length. - * Largest first. - * - */ -static int sort_by_max_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return(1); - - if (!((*head)->next)) - return(0); - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length < (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length < current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return(0); -} - - -/* - * do_pre_bridge_resource_split - * - * Returns zero or one node of resources that aren't in use - * - */ -static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment) -{ - struct pci_resource *prevnode = NULL; - struct pci_resource *node; - struct pci_resource *split_node; - u32 rc; - u32 temp_dword; - dbg("do_pre_bridge_resource_split\n"); - - if (!(*head) || !(*orig_head)) - return(NULL); - - rc = shpchp_resource_sort_and_combine(head); - - if (rc) - return(NULL); - - if ((*head)->base != (*orig_head)->base) - return(NULL); - - if ((*head)->length == (*orig_head)->length) - return(NULL); - - - /* If we got here, there the bridge requires some of the resource, but - * we may be able to split some off of the front - */ - node = *head; - - if (node->length & (alignment -1)) { - /* This one isn't an aligned length, so we'll make a new entry - * and split it up. - */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - temp_dword = (node->length | (alignment-1)) + 1 - alignment; - - split_node->base = node->base; - split_node->length = temp_dword; - - node->length -= temp_dword; - node->base += split_node->length; - - /* Put it in the list */ - *head = split_node; - split_node->next = node; - } - - if (node->length < alignment) { - return(NULL); - } - - /* Now unlink it */ - if (*head == node) { - *head = node->next; - node->next = NULL; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - node->next = NULL; - } - - return(node); -} - - -/* - * do_bridge_resource_split - * - * Returns zero or one node of resources that aren't in use - * - */ -static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment) -{ - struct pci_resource *prevnode = NULL; - struct pci_resource *node; - u32 rc; - u32 temp_dword; - - if (!(*head)) - return(NULL); - - rc = shpchp_resource_sort_and_combine(head); - - if (rc) - return(NULL); - - node = *head; - - while (node->next) { - prevnode = node; - node = node->next; - kfree(prevnode); - } - - if (node->length < alignment) { - kfree(node); - return(NULL); - } - - if (node->base & (alignment - 1)) { - /* Short circuit if adjusted size is too small */ - temp_dword = (node->base | (alignment-1)) + 1; - if ((node->length - (temp_dword - node->base)) < alignment) { - kfree(node); - return(NULL); - } - - node->length -= (temp_dword - node->base); - node->base = temp_dword; - } - - if (node->length & (alignment - 1)) { - /* There's stuff in use after this node */ - kfree(node); - return(NULL); - } - - return(node); -} - - -/* - * get_io_resource - * - * this function sorts the resource list by size and then - * returns the first node of "size" length that is not in the - * ISA aliasing window. If it finds a node larger than "size" - * it will split it up. - * - * size must be a power of two. - */ -static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node = NULL; - u32 temp_dword; - - if (!(*head)) - return(NULL); - - if ( shpchp_resource_sort_and_combine(head) ) - return(NULL); - - if ( sort_by_size(head) ) - return(NULL); - - for (node = *head; node; node = node->next) { - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - /* This one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_dword = (node->base | (size-1)) + 1; - - /*/ Short circuit if adjusted size is too small */ - if ((node->length - (temp_dword - node->base)) < size) - continue; - - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - split_node->base = node->base; - split_node->length = temp_dword - node->base; - node->base = temp_dword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - /* This one is longer than we need - so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - split_node->base = node->base + size; - split_node->length = node->length - size; - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - /* For IO make sure it's not in the ISA aliasing space */ - if (node->base & 0x300L) - continue; - - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - - return(node); -} - - -/* - * get_max_resource - * - * Gets the largest node that is at least "size" big from the - * list pointed to by head. It aligns the node on top and bottom - * to "size" alignment before returning it. - * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M - * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot. - */ -static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *max; - struct pci_resource *temp; - struct pci_resource *split_node; - u32 temp_dword; - u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 }; - int i; - - if (!(*head)) - return(NULL); - - if (shpchp_resource_sort_and_combine(head)) - return(NULL); - - if (sort_by_max_size(head)) - return(NULL); - - for (max = *head;max; max = max->next) { - - /* If not big enough we could probably just bail, - instead we'll continue to the next. */ - if (max->length < size) - continue; - - if (max->base & (size - 1)) { - /* This one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_dword = (max->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((max->length - (temp_dword - max->base)) < size) - continue; - - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - split_node->base = max->base; - split_node->length = temp_dword - max->base; - max->base = temp_dword; - max->length -= split_node->length; - - /* Put it next in the list */ - split_node->next = max->next; - max->next = split_node; - } - - if ((max->base + max->length) & (size - 1)) { - /* This one isn't end aligned properly at the top - so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - temp_dword = ((max->base + max->length) & ~(size - 1)); - split_node->base = temp_dword; - split_node->length = max->length + max->base - - split_node->base; - max->length -= split_node->length; - - /* Put it in the list */ - split_node->next = max->next; - max->next = split_node; - } - - /* Make sure it didn't shrink too much when we aligned it */ - if (max->length < size) - continue; - - for ( i = 0; max_size[i] > size; i++) { - if (max->length > max_size[i]) { - split_node = kmalloc(sizeof(*split_node), - GFP_KERNEL); - if (!split_node) - break; /* return (NULL); */ - split_node->base = max->base + max_size[i]; - split_node->length = max->length - max_size[i]; - max->length = max_size[i]; - /* Put it next in the list */ - split_node->next = max->next; - max->next = split_node; - break; - } - } - - /* Now take it out of the list */ - temp = (struct pci_resource*) *head; - if (temp == max) { - *head = max->next; - } else { - while (temp && temp->next != max) { - temp = temp->next; - } - - temp->next = max->next; - } - - max->next = NULL; - return(max); - } - - /* If we get here, we couldn't find one */ - return(NULL); -} - - -/* - * get_resource - * - * this function sorts the resource list by size and then - * returns the first node of "size" length. If it finds a node - * larger than "size" it will split it up. - * - * size must be a power of two. - */ -static struct pci_resource *get_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u32 temp_dword; - - if (!(*head)) - return(NULL); - - if ( shpchp_resource_sort_and_combine(head) ) - return(NULL); - - if ( sort_by_size(head) ) - return(NULL); - - for (node = *head; node; node = node->next) { - dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n", - __FUNCTION__, size, node, node->base, node->length); - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - dbg("%s: not aligned\n", __FUNCTION__); - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_dword = (node->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_dword - node->base)) < size) - continue; - - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - split_node->base = node->base; - split_node->length = temp_dword - node->base; - node->base = temp_dword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - dbg("%s: too big\n", __FUNCTION__); - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); - - if (!split_node) - return(NULL); - - split_node->base = node->base + size; - split_node->length = node->length - size; - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - dbg("%s: got one!!!\n", __FUNCTION__); - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - return(node); -} - - -/* - * shpchp_resource_sort_and_combine - * - * Sorts all of the nodes in the list in ascending order by - * their base addresses. Also does garbage collection by - * combining adjacent nodes. - * - * returns 0 if success - */ -int shpchp_resource_sort_and_combine(struct pci_resource **head) -{ - struct pci_resource *node1; - struct pci_resource *node2; - int out_of_order = 1; - - dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head); - - if (!(*head)) - return(1); - - dbg("*head->next = %p\n",(*head)->next); - - if (!(*head)->next) - return(0); /* only one item on the list, already sorted! */ - - dbg("*head->base = 0x%x\n",(*head)->base); - dbg("*head->next->base = 0x%x\n",(*head)->next->base); - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->base > (*head)->next->base)) { - node1 = *head; - (*head) = (*head)->next; - node1->next = (*head)->next; - (*head)->next = node1; - out_of_order++; - } - - node1 = (*head); - - while (node1->next && node1->next->next) { - if (node1->next->base > node1->next->next->base) { - out_of_order++; - node2 = node1->next; - node1->next = node1->next->next; - node1 = node1->next; - node2->next = node1->next; - node1->next = node2; - } else - node1 = node1->next; - } - } /* End of out_of_order loop */ - - node1 = *head; - - while (node1 && node1->next) { - if ((node1->base + node1->length) == node1->next->base) { - /* Combine */ - dbg("8..\n"); - node1->length += node1->next->length; - node2 = node1->next; - node1->next = node1->next->next; - kfree(node2); - } else - node1 = node1->next; - } - - return(0); -} - - /** * shpchp_slot_create - Creates a node and adds it to the proper bus. * @busnumber - bus where new node is to be located @@ -933,7 +309,6 @@ static int slot_remove(struct pci_func * old_slot) if (next == old_slot) { shpchp_slot_list[old_slot->bus] = old_slot->next; - shpchp_destroy_board_resources(old_slot); kfree(old_slot); return(0); } @@ -944,7 +319,6 @@ static int slot_remove(struct pci_func * old_slot) if (next->next == old_slot) { next->next = old_slot->next; - shpchp_destroy_board_resources(old_slot); kfree(old_slot); return(0); } else @@ -1120,12 +494,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) { u8 hp_slot; u8 slots_not_empty = 0; - int index; - u32 temp_register = 0xFFFFFFFF; - u32 retval, rc = 0; - struct pci_func *new_func = NULL; + u32 rc = 0; struct slot *p_slot; - struct resource_lists res_lists; enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed; u8 pi, mode; @@ -1328,135 +698,65 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) /* Check for a power fault */ if (func->status == 0xFF) { /* power fault occurred, but it was benign */ - temp_register = 0xFFFFFFFF; - dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register); + dbg("%s: power fault\n", __FUNCTION__); rc = POWER_FAILURE; func->status = 0; - } else { - /* Get vendor/device ID u32 */ - rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function), - PCI_VENDOR_ID, &temp_register); - dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc); - dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register); - - if (rc != 0) { - /* Something's wrong here */ - temp_register = 0xFFFFFFFF; - dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register); - } - /* Preset return code. It will be changed later if things go okay. */ - rc = NO_ADAPTER_PRESENT; + goto err_exit; } - /* All F's is an empty slot or an invalid board */ - if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */ - res_lists.io_head = ctrl->io_head; - res_lists.mem_head = ctrl->mem_head; - res_lists.p_mem_head = ctrl->p_mem_head; - res_lists.bus_head = ctrl->bus_head; - res_lists.irqs = NULL; - - rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0); - dbg("%s: back from configure_new_device\n", __FUNCTION__); - - ctrl->io_head = res_lists.io_head; - ctrl->mem_head = res_lists.mem_head; - ctrl->p_mem_head = res_lists.p_mem_head; - ctrl->bus_head = res_lists.bus_head; - - shpchp_resource_sort_and_combine(&(ctrl->mem_head)); - shpchp_resource_sort_and_combine(&(ctrl->p_mem_head)); - shpchp_resource_sort_and_combine(&(ctrl->io_head)); - shpchp_resource_sort_and_combine(&(ctrl->bus_head)); - - if (rc) { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->slot_disable(p_slot); - if (retval) { - err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - retval = p_slot->hpc_ops->check_cmd_status(ctrl); - if (retval) { - err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return retval; - } - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - return(rc); - } - shpchp_save_slot_config(ctrl, func); - - func->status = 0; - func->switch_save = 0x10; - func->is_a_board = 0x01; - func->pwr_save = 1; - - /* Next, we will instantiate the linux pci_dev structures - * (with appropriate driver notification, if already present) - */ - index = 0; - do { - new_func = shpchp_slot_find(ctrl->slot_bus, func->device, index++); - if (new_func && !new_func->pci_dev) { - dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__); - shpchp_configure_device(ctrl, new_func); - } - } while (new_func); - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - p_slot->hpc_ops->green_led_on(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - } else { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - rc = p_slot->hpc_ops->slot_disable(p_slot); - if (rc) { - err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return rc; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return rc; - } - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - return(rc); + if (shpchp_configure_device(p_slot)) { + err("Cannot add device at 0x%x:0x%x\n", p_slot->bus, + p_slot->device); + goto err_exit; } + + shpchp_save_slot_config(ctrl, func); + + func->status = 0; + func->switch_save = 0x10; + func->is_a_board = 0x01; + func->pwr_save = 1; + + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + p_slot->hpc_ops->green_led_on(p_slot); + + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return 0; + +err_exit: + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + /* turn off slot, turn on Amber LED, turn off Green LED */ + rc = p_slot->hpc_ops->slot_disable(p_slot); + if (rc) { + err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return rc; + } + /* Wait for the command to complete */ + wait_for_ctrl_irq (ctrl); + + rc = p_slot->hpc_ops->check_cmd_status(ctrl); + if (rc) { + err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return rc; + } + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + + return(rc); } @@ -1466,13 +766,9 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) */ static u32 remove_board(struct pci_func *func, struct controller *ctrl) { - int index; - u8 skip = 0; u8 device; u8 hp_slot; u32 rc; - struct resource_lists res_lists; - struct pci_func *temp_func; struct slot *p_slot; if (func == NULL) @@ -1488,27 +784,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); - if ((ctrl->add_support) && - !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) { - /* Here we check to see if we've saved any of the board's - * resources already. If so, we'll skip the attempt to - * determine what's being used. - */ - index = 0; - - temp_func = func; - - while ((temp_func = shpchp_slot_find(temp_func->bus, temp_func->device, index++))) { - if (temp_func->bus_head || temp_func->mem_head - || temp_func->p_mem_head || temp_func->io_head) { - skip = 1; - break; - } - } - - if (!skip) - rc = shpchp_save_used_resources(ctrl, func, DISABLE_CARD); - } /* Change status to shutdown */ if (func->is_a_board) func->status = 0x01; @@ -1551,26 +826,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) if (ctrl->add_support) { while (func) { - res_lists.io_head = ctrl->io_head; - res_lists.mem_head = ctrl->mem_head; - res_lists.p_mem_head = ctrl->p_mem_head; - res_lists.bus_head = ctrl->bus_head; - - dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus, - func->device, func->function); - - shpchp_return_board_resources(func, &res_lists); - - ctrl->io_head = res_lists.io_head; - ctrl->mem_head = res_lists.mem_head; - ctrl->p_mem_head = res_lists.p_mem_head; - ctrl->bus_head = res_lists.bus_head; - - shpchp_resource_sort_and_combine(&(ctrl->mem_head)); - shpchp_resource_sort_and_combine(&(ctrl->p_mem_head)); - shpchp_resource_sort_and_combine(&(ctrl->io_head)); - shpchp_resource_sort_and_combine(&(ctrl->bus_head)); - if (is_bridge(func)) { dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function); @@ -2050,798 +1305,3 @@ int shpchp_disable_slot (struct slot *p_slot) return rc; } - -/** - * configure_new_device - Configures the PCI header information of one board. - * - * @ctrl: pointer to controller structure - * @func: pointer to function structure - * @behind_bridge: 1 if this is a recursive call, 0 if not - * @resources: pointer to set of resource lists - * - * Returns 0 if success - * - */ -static u32 configure_new_device (struct controller * ctrl, struct pci_func * func, - u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev) -{ - u8 temp_byte, function, max_functions, stop_it; - int rc; - u32 ID; - struct pci_func *new_slot; - struct pci_bus lpci_bus, *pci_bus; - int index; - - new_slot = func; - - dbg("%s\n", __FUNCTION__); - memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - - /* Check for Multi-function device */ - rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte); - if (rc) { - dbg("%s: rc = %d\n", __FUNCTION__, rc); - return rc; - } - - if (temp_byte & 0x80) /* Multi-function device */ - max_functions = 8; - else - max_functions = 1; - - function = 0; - - do { - rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev); - - if (rc) { - dbg("configure_new_function failed %d\n",rc); - index = 0; - - while (new_slot) { - new_slot = shpchp_slot_find(new_slot->bus, new_slot->device, index++); - - if (new_slot) - shpchp_return_board_resources(new_slot, resources); - } - - return(rc); - } - - function++; - - stop_it = 0; - - /* The following loop skips to the next present function - * and creates a board structure - */ - - while ((function < max_functions) && (!stop_it)) { - pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); - - if (ID == 0xFFFFFFFF) { /* There's nothing there. */ - function++; - } else { /* There's something there */ - /* Setup slot structure. */ - new_slot = shpchp_slot_create(func->bus); - - if (new_slot == NULL) { - /* Out of memory */ - return(1); - } - - new_slot->bus = func->bus; - new_slot->device = func->device; - new_slot->function = function; - new_slot->is_a_board = 1; - new_slot->status = 0; - - stop_it++; - } - } - - } while (function < max_functions); - dbg("returning from configure_new_device\n"); - - return 0; -} - - -/* - * Configuration logic that involves the hotplug data structures and - * their bookkeeping - */ - - -/** - * configure_new_function - Configures the PCI header information of one device - * - * @ctrl: pointer to controller structure - * @func: pointer to function structure - * @behind_bridge: 1 if this is a recursive call, 0 if not - * @resources: pointer to set of resource lists - * - * Calls itself recursively for bridged devices. - * Returns 0 if success - * - */ -static int configure_new_function (struct controller * ctrl, struct pci_func * func, - u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev) -{ - int cloop; - u8 temp_byte; - u8 device; - u8 class_code; - u16 temp_word; - u32 rc; - u32 temp_register; - u32 base; - u32 ID; - unsigned int devfn; - struct pci_resource *mem_node; - struct pci_resource *p_mem_node; - struct pci_resource *io_node; - struct pci_resource *bus_node; - struct pci_resource *hold_mem_node; - struct pci_resource *hold_p_mem_node; - struct pci_resource *hold_IO_node; - struct pci_resource *hold_bus_node; - struct irq_mapping irqs; - struct pci_func *new_slot; - struct pci_bus lpci_bus, *pci_bus; - struct resource_lists temp_resources; -#if defined(CONFIG_X86_64) - u8 IRQ=0; -#endif - - memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - /* Check for Bridge */ - rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte); - if (rc) - return rc; - - if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */ - /* set Primary bus */ - dbg("set Primary bus = 0x%x\n", func->bus); - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus); - if (rc) - return rc; - - /* find range of busses to use */ - bus_node = get_max_resource(&resources->bus_head, 1L); - - /* If we don't have any busses to allocate, we can't continue */ - if (!bus_node) { - err("Got NO bus resource to use\n"); - return -ENOMEM; - } - dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length); - - /* set Secondary bus */ - temp_byte = (u8)bus_node->base; - dbg("set Secondary bus = 0x%x\n", temp_byte); - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte); - if (rc) - return rc; - - /* set subordinate bus */ - temp_byte = (u8)(bus_node->base + bus_node->length - 1); - dbg("set subordinate bus = 0x%x\n", temp_byte); - rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte); - if (rc) - return rc; - - /* Set HP parameters (Cache Line Size, Latency Timer) */ - rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE); - if (rc) - return rc; - - /* Setup the IO, memory, and prefetchable windows */ - - io_node = get_max_resource(&(resources->io_head), 0x1000L); - if (io_node) { - dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next); - } - - mem_node = get_max_resource(&(resources->mem_head), 0x100000L); - if (mem_node) { - dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next); - } - - if (resources->p_mem_head) - p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L); - else { - /* - * In some platform implementation, MEM and PMEM are not - * distinguished, and hence ACPI _CRS has only MEM entries - * for both MEM and PMEM. - */ - dbg("using MEM for PMEM\n"); - p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L); - } - if (p_mem_node) { - dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next); - } - - /* set up the IRQ info */ - if (!resources->irqs) { - irqs.barber_pole = 0; - irqs.interrupt[0] = 0; - irqs.interrupt[1] = 0; - irqs.interrupt[2] = 0; - irqs.interrupt[3] = 0; - irqs.valid_INT = 0; - } else { - irqs.barber_pole = resources->irqs->barber_pole; - irqs.interrupt[0] = resources->irqs->interrupt[0]; - irqs.interrupt[1] = resources->irqs->interrupt[1]; - irqs.interrupt[2] = resources->irqs->interrupt[2]; - irqs.interrupt[3] = resources->irqs->interrupt[3]; - irqs.valid_INT = resources->irqs->valid_INT; - } - - /* set up resource lists that are now aligned on top and bottom - * for anything behind the bridge. - */ - temp_resources.bus_head = bus_node; - temp_resources.io_head = io_node; - temp_resources.mem_head = mem_node; - temp_resources.p_mem_head = p_mem_node; - temp_resources.irqs = &irqs; - - /* Make copies of the nodes we are going to pass down so that - * if there is a problem,we can just use these to free resources - */ - hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); - hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); - hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); - hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL); - - if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) { - kfree(hold_bus_node); - kfree(hold_IO_node); - kfree(hold_mem_node); - kfree(hold_p_mem_node); - - return 1; - } - - memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource)); - - bus_node->base += 1; - bus_node->length -= 1; - bus_node->next = NULL; - - /* If we have IO resources copy them and fill in the bridge's - * IO range registers - */ - if (io_node) { - memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); - io_node->next = NULL; - - /* set IO base and Limit registers */ - RES_CHECK(io_node->base, 8); - temp_byte = (u8)(io_node->base >> 8); - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); - - RES_CHECK(io_node->base + io_node->length - 1, 8); - temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8); - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); - } else { - kfree(hold_IO_node); - hold_IO_node = NULL; - } - - /* If we have memory resources copy them and fill in the bridge's - * memory range registers. Otherwise, fill in the range - * registers with values that disable them. - */ - if (mem_node) { - memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); - mem_node->next = NULL; - - /* set Mem base and Limit registers */ - RES_CHECK(mem_node->base, 16); - temp_word = (u32)(mem_node->base >> 16); - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); - - RES_CHECK(mem_node->base + mem_node->length - 1, 16); - temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16); - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); - } else { - temp_word = 0xFFFF; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); - - temp_word = 0x0000; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); - - kfree(hold_mem_node); - hold_mem_node = NULL; - } - - /* If we have prefetchable memory resources copy them and - * fill in the bridge's memory range registers. Otherwise, - * fill in the range registers with values that disable them. - */ - if (p_mem_node) { - memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); - p_mem_node->next = NULL; - - /* set Pre Mem base and Limit registers */ - RES_CHECK(p_mem_node->base, 16); - temp_word = (u32)(p_mem_node->base >> 16); - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); - - RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16); - temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16); - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); - } else { - temp_word = 0xFFFF; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); - - temp_word = 0x0000; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); - - kfree(hold_p_mem_node); - hold_p_mem_node = NULL; - } - - /* Adjust this to compensate for extra adjustment in first loop */ - irqs.barber_pole--; - - rc = 0; - - /* Here we actually find the devices and configure them */ - for (device = 0; (device <= 0x1F) && !rc; device++) { - irqs.barber_pole = (irqs.barber_pole + 1) & 0x03; - - ID = 0xFFFFFFFF; - pci_bus->number = hold_bus_node->base; - pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), - PCI_VENDOR_ID, &ID); - pci_bus->number = func->bus; - - if (ID != 0xFFFFFFFF) { /* device Present */ - /* Setup slot structure. */ - new_slot = shpchp_slot_create(hold_bus_node->base); - - if (new_slot == NULL) { - /* Out of memory */ - rc = -ENOMEM; - continue; - } - - new_slot->bus = hold_bus_node->base; - new_slot->device = device; - new_slot->function = 0; - new_slot->is_a_board = 1; - new_slot->status = 0; - - rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device); - dbg("configure_new_device rc=0x%x\n",rc); - } /* End of IF (device in slot?) */ - } /* End of FOR loop */ - - if (rc) { - shpchp_destroy_resource_list(&temp_resources); - - return_resource(&(resources->bus_head), hold_bus_node); - return_resource(&(resources->io_head), hold_IO_node); - return_resource(&(resources->mem_head), hold_mem_node); - return_resource(&(resources->p_mem_head), hold_p_mem_node); - return(rc); - } - - /* save the interrupt routing information */ - if (resources->irqs) { - resources->irqs->interrupt[0] = irqs.interrupt[0]; - resources->irqs->interrupt[1] = irqs.interrupt[1]; - resources->irqs->interrupt[2] = irqs.interrupt[2]; - resources->irqs->interrupt[3] = irqs.interrupt[3]; - resources->irqs->valid_INT = irqs.valid_INT; - } else if (!behind_bridge) { - /* We need to hook up the interrupts here */ - for (cloop = 0; cloop < 4; cloop++) { - if (irqs.valid_INT & (0x01 << cloop)) { - rc = shpchp_set_irq(func->bus, func->device, - 0x0A + cloop, irqs.interrupt[cloop]); - if (rc) { - shpchp_destroy_resource_list (&temp_resources); - return_resource(&(resources->bus_head), hold_bus_node); - return_resource(&(resources->io_head), hold_IO_node); - return_resource(&(resources->mem_head), hold_mem_node); - return_resource(&(resources->p_mem_head), hold_p_mem_node); - return rc; - } - } - } /* end of for loop */ - } - - /* Return unused bus resources - * First use the temporary node to store information for the board - */ - if (hold_bus_node && bus_node && temp_resources.bus_head) { - hold_bus_node->length = bus_node->base - hold_bus_node->base; - - hold_bus_node->next = func->bus_head; - func->bus_head = hold_bus_node; - - temp_byte = (u8)(temp_resources.bus_head->base - 1); - - /* set subordinate bus */ - dbg("re-set subordinate bus = 0x%x\n", temp_byte); - rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte); - - if (temp_resources.bus_head->length == 0) { - kfree(temp_resources.bus_head); - temp_resources.bus_head = NULL; - } else { - dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n", - func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length); - return_resource(&(resources->bus_head), temp_resources.bus_head); - } - } - - /* If we have IO space available and there is some left, - * return the unused portion - */ - if (hold_IO_node && temp_resources.io_head) { - io_node = do_pre_bridge_resource_split(&(temp_resources.io_head), - &hold_IO_node, 0x1000); - - /* Check if we were able to split something off */ - if (io_node) { - hold_IO_node->base = io_node->base + io_node->length; - - RES_CHECK(hold_IO_node->base, 8); - temp_byte = (u8)((hold_IO_node->base) >> 8); - rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte); - - return_resource(&(resources->io_head), io_node); - } - - io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000); - - /* Check if we were able to split something off */ - if (io_node) { - /* First use the temporary node to store information for the board */ - hold_IO_node->length = io_node->base - hold_IO_node->base; - - /* If we used any, add it to the board's list */ - if (hold_IO_node->length) { - hold_IO_node->next = func->io_head; - func->io_head = hold_IO_node; - - RES_CHECK(io_node->base - 1, 8); - temp_byte = (u8)((io_node->base - 1) >> 8); - rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte); - - return_resource(&(resources->io_head), io_node); - } else { - /* it doesn't need any IO */ - temp_byte = 0x00; - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); - - return_resource(&(resources->io_head), io_node); - kfree(hold_IO_node); - } - } else { - /* it used most of the range */ - hold_IO_node->next = func->io_head; - func->io_head = hold_IO_node; - } - } else if (hold_IO_node) { - /* it used the whole range */ - hold_IO_node->next = func->io_head; - func->io_head = hold_IO_node; - } - - /* If we have memory space available and there is some left, - * return the unused portion - */ - if (hold_mem_node && temp_resources.mem_head) { - mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L); - - /* Check if we were able to split something off */ - if (mem_node) { - hold_mem_node->base = mem_node->base + mem_node->length; - - RES_CHECK(hold_mem_node->base, 16); - temp_word = (u32)((hold_mem_node->base) >> 16); - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word); - - return_resource(&(resources->mem_head), mem_node); - } - - mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L); - - /* Check if we were able to split something off */ - if (mem_node) { - /* First use the temporary node to store information for the board */ - hold_mem_node->length = mem_node->base - hold_mem_node->base; - - if (hold_mem_node->length) { - hold_mem_node->next = func->mem_head; - func->mem_head = hold_mem_node; - - /* configure end address */ - RES_CHECK(mem_node->base - 1, 16); - temp_word = (u32)((mem_node->base - 1) >> 16); - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); - - /* Return unused resources to the pool */ - return_resource(&(resources->mem_head), mem_node); - } else { - /* it doesn't need any Mem */ - temp_word = 0x0000; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); - - return_resource(&(resources->mem_head), mem_node); - kfree(hold_mem_node); - } - } else { - /* it used most of the range */ - hold_mem_node->next = func->mem_head; - func->mem_head = hold_mem_node; - } - } else if (hold_mem_node) { - /* it used the whole range */ - hold_mem_node->next = func->mem_head; - func->mem_head = hold_mem_node; - } - - /* If we have prefetchable memory space available and there is some - * left at the end, return the unused portion - */ - if (hold_p_mem_node && temp_resources.p_mem_head) { - p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), - &hold_p_mem_node, 0x100000L); - - /* Check if we were able to split something off */ - if (p_mem_node) { - hold_p_mem_node->base = p_mem_node->base + p_mem_node->length; - - RES_CHECK(hold_p_mem_node->base, 16); - temp_word = (u32)((hold_p_mem_node->base) >> 16); - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); - - return_resource(&(resources->p_mem_head), p_mem_node); - } - - p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L); - - /* Check if we were able to split something off */ - if (p_mem_node) { - /* First use the temporary node to store information for the board */ - hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base; - - /* If we used any, add it to the board's list */ - if (hold_p_mem_node->length) { - hold_p_mem_node->next = func->p_mem_head; - func->p_mem_head = hold_p_mem_node; - - RES_CHECK(p_mem_node->base - 1, 16); - temp_word = (u32)((p_mem_node->base - 1) >> 16); - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); - - return_resource(&(resources->p_mem_head), p_mem_node); - } else { - /* it doesn't need any PMem */ - temp_word = 0x0000; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); - - return_resource(&(resources->p_mem_head), p_mem_node); - kfree(hold_p_mem_node); - } - } else { - /* it used the most of the range */ - hold_p_mem_node->next = func->p_mem_head; - func->p_mem_head = hold_p_mem_node; - } - } else if (hold_p_mem_node) { - /* it used the whole range */ - hold_p_mem_node->next = func->p_mem_head; - func->p_mem_head = hold_p_mem_node; - } - - /* We should be configuring an IRQ and the bridge's base address - * registers if it needs them. Although we have never seen such - * a device - */ - - shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE); - - dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function); - } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) { - /* Standard device */ - u64 base64; - rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); - - if (class_code == PCI_BASE_CLASS_DISPLAY) - return (DEVICE_TYPE_NOT_SUPPORTED); - - /* Figure out IO and memory needs */ - for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) { - temp_register = 0xFFFFFFFF; - - rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); - rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register); - dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device, - func->function); - - if (!temp_register) - continue; - - base64 = 0L; - if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) { - /* Map IO */ - - /* set base = amount of IO space */ - base = temp_register & 0xFFFFFFFC; - base = ~base + 1; - - dbg("NEED IO length(0x%x)\n", base); - io_node = get_io_resource(&(resources->io_head),(ulong)base); - - /* allocate the resource to the board */ - if (io_node) { - dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length); - base = (u32)io_node->base; - io_node->next = func->io_head; - func->io_head = io_node; - } else { - err("Got NO IO resource(length=0x%x)\n", base); - return -ENOMEM; - } - } else { /* map MEM */ - int prefetchable = 1; - struct pci_resource **res_node = &func->p_mem_head; - char *res_type_str = "PMEM"; - u32 temp_register2; - - if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) { - prefetchable = 0; - res_node = &func->mem_head; - res_type_str++; - } - - base = temp_register & 0xFFFFFFF0; - base = ~base + 1; - - switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { - case PCI_BASE_ADDRESS_MEM_TYPE_32: - dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base); - - if (prefetchable && resources->p_mem_head) - mem_node=get_resource(&(resources->p_mem_head), (ulong)base); - else { - if (prefetchable) - dbg("using MEM for PMEM\n"); - mem_node=get_resource(&(resources->mem_head), (ulong)base); - } - - /* allocate the resource to the board */ - if (mem_node) { - base = (u32)mem_node->base; - mem_node->next = *res_node; - *res_node = mem_node; - dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base, - mem_node->length); - } else { - err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base); - return -ENOMEM; - } - break; - case PCI_BASE_ADDRESS_MEM_TYPE_64: - rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2); - dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2, - temp_register, base); - - if (prefetchable && resources->p_mem_head) - mem_node = get_resource(&(resources->p_mem_head), (ulong)base); - else { - if (prefetchable) - dbg("using MEM for PMEM\n"); - mem_node = get_resource(&(resources->mem_head), (ulong)base); - } - - /* allocate the resource to the board */ - if (mem_node) { - base64 = mem_node->base; - mem_node->next = *res_node; - *res_node = mem_node; - dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32), - (u32)base64, mem_node->length); - } else { - err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base); - return -ENOMEM; - } - break; - default: - dbg("reserved BAR type=0x%x\n", temp_register); - break; - } - - } - - if (base64) { - rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64); - cloop += 4; - base64 >>= 32; - - if (base64) { - dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64); - base64 = 0x0L; - } - - rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64); - } else { - rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base); - } - } /* End of base register loop */ - -#if defined(CONFIG_X86_64) - /* Figure out which interrupt pin this function uses */ - rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte); - - /* If this function needs an interrupt and we are behind a bridge - and the pin is tied to something that's alread mapped, - set this one the same - */ - if (temp_byte && resources->irqs && - (resources->irqs->valid_INT & - (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { - /* We have to share with something already set up */ - IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03]; - } else { - /* Program IRQ based on card type */ - rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); - - if (class_code == PCI_BASE_CLASS_STORAGE) { - IRQ = shpchp_disk_irq; - } else { - IRQ = shpchp_nic_irq; - } - } - - /* IRQ Line */ - rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ); - - if (!behind_bridge) { - rc = shpchp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ); - if (rc) - return(1); - } else { - /* TBD - this code may also belong in the other clause of this If statement */ - resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ; - resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03; - } -#endif - /* Disable ROM base Address */ - rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00); - - /* Set HP parameters (Cache Line Size, Latency Timer) */ - rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL); - if (rc) - return rc; - - shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL); - - dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function); - } /* End of Not-A-Bridge else */ - else { - /* It's some strange type of PCI adapter (Cardbus?) */ - return(DEVICE_TYPE_NOT_SUPPORTED); - } - - func->configured = 1; - - return 0; -} - diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index d867099114ec..89e404805777 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -37,46 +37,69 @@ #include #include "../pci.h" #include "shpchp.h" -#ifndef CONFIG_IA64 -#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */ -#endif -int shpchp_configure_device (struct controller* ctrl, struct pci_func* func) +int shpchp_configure_device(struct slot *p_slot) { - unsigned char bus; - struct pci_bus *child; - int num; + struct pci_dev *dev; + struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; + int num, fn; - if (func->pci_dev == NULL) - func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); - - /* Still NULL ? Well then scan for it ! */ - if (func->pci_dev == NULL) { - num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function)); - if (num) { - dbg("%s: subordiante %p number %x\n", __FUNCTION__, ctrl->pci_dev->subordinate, - ctrl->pci_dev->subordinate->number); - pci_bus_add_devices(ctrl->pci_dev->subordinate); - } - - func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); - if (func->pci_dev == NULL) { - dbg("ERROR: pci_dev still null\n"); - return 0; - } + dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0)); + if (dev) { + err("Device %s already exists at %x:%x, cannot hot-add\n", + pci_name(dev), p_slot->bus, p_slot->device); + return -EINVAL; } - if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); - child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); - pci_do_scan_bus(child); - + num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); + if (num == 0) { + err("No new device found\n"); + return -ENODEV; } + for (fn = 0; fn < 8; fn++) { + if (!(dev = pci_find_slot(p_slot->bus, + PCI_DEVFN(p_slot->device, fn)))) + continue; + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + err("Cannot hot-add display device %s\n", + pci_name(dev)); + continue; + } + if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { + /* Find an unused bus number for the new bridge */ + struct pci_bus *child; + unsigned char busnr, start = parent->secondary; + unsigned char end = parent->subordinate; + for (busnr = start; busnr <= end; busnr++) { + if (!pci_find_bus(pci_domain_nr(parent), + busnr)) + break; + } + if (busnr >= end) { + err("No free bus for hot-added bridge\n"); + continue; + } + child = pci_add_new_bus(parent, dev, busnr); + if (!child) { + err("Cannot add new bus for %s\n", + pci_name(dev)); + continue; + } + child->subordinate = pci_do_scan_bus(child); + pci_bus_size_bridges(child); + } + /* TBD: program firmware provided _HPP values */ + /* program_fw_provided_values(dev); */ + } + + pci_bus_assign_resources(parent); + pci_bus_add_devices(parent); + pci_enable_bridges(parent); return 0; } - int shpchp_unconfigure_device(struct pci_func* func) { int rc = 0; @@ -95,44 +118,6 @@ int shpchp_unconfigure_device(struct pci_func* func) return rc; } -/* - * shpchp_set_irq - * - * @bus_num: bus number of PCI device - * @dev_num: device number of PCI device - * @slot: pointer to u8 where slot number will be returned - */ -int shpchp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) -{ -#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64) - int rc; - u16 temp_word; - struct pci_dev fakedev; - struct pci_bus fakebus; - - fakedev.devfn = dev_num << 3; - fakedev.bus = &fakebus; - fakebus.number = bus_num; - dbg("%s: dev %d, bus %d, pin %d, num %d\n", - __FUNCTION__, dev_num, bus_num, int_pin, irq_num); - rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num); - dbg("%s: rc %d\n", __FUNCTION__, rc); - if (!rc) - return !rc; - - /* set the Edge Level Control Register (ELCR) */ - temp_word = inb(0x4d0); - temp_word |= inb(0x4d1) << 8; - - temp_word |= 0x01 << irq_num; - - /* This should only be for x86 as it sets the Edge Level Control Register */ - outb((u8) (temp_word & 0xFF), 0x4d0); - outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1); -#endif - return 0; -} - /* More PCI configuration routines; this time centered around hotplug controller */ @@ -447,364 +432,3 @@ int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot) return 0; } - -/* - * shpchp_save_used_resources - * - * Stores used resource information for existing boards. this is - * for boards that were in the system when this driver was loaded. - * this function is for hot plug ADD - * - * returns 0 if success - * if disable == 1(DISABLE_CARD), - * it loops for all functions of the slot and disables them. - * else, it just get resources of the function and return. - */ -int shpchp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable) -{ - u8 cloop; - u8 header_type; - u8 secondary_bus; - u8 temp_byte; - u16 command; - u16 save_command; - u16 w_base, w_length; - u32 temp_register; - u32 save_base; - u32 base, length; - u64 base64 = 0; - int index = 0; - unsigned int devfn; - struct pci_resource *mem_node = NULL; - struct pci_resource *p_mem_node = NULL; - struct pci_resource *t_mem_node; - struct pci_resource *io_node; - struct pci_resource *bus_node; - struct pci_bus lpci_bus, *pci_bus; - memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - - if (disable) - func = shpchp_slot_find(func->bus, func->device, index++); - - while ((func != NULL) && func->is_a_board) { - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - /* Save the command register */ - pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command); - - if (disable) { - /* disable card */ - command = 0x00; - pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); - } - - /* Check for Bridge */ - pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type); - - if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */ - dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n", - func->bus, func->device, save_command); - if (disable) { - /* Clear Bridge Control Register */ - command = 0x00; - pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command); - } - - pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); - pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte); - - bus_node = kmalloc(sizeof(struct pci_resource), - GFP_KERNEL); - if (!bus_node) - return -ENOMEM; - - bus_node->base = (ulong)secondary_bus; - bus_node->length = (ulong)(temp_byte - secondary_bus + 1); - - bus_node->next = func->bus_head; - func->bus_head = bus_node; - - /* Save IO base and Limit registers */ - pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte); - base = temp_byte; - pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte); - length = temp_byte; - - if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) { - io_node = kmalloc(sizeof(struct pci_resource), - GFP_KERNEL); - if (!io_node) - return -ENOMEM; - - io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8; - io_node->length = (ulong)(length - base + 0x10) << 8; - - io_node->next = func->io_head; - func->io_head = io_node; - } - - /* Save memory base and Limit registers */ - pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base); - pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); - - if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) { - mem_node = kmalloc(sizeof(struct pci_resource), - GFP_KERNEL); - if (!mem_node) - return -ENOMEM; - - mem_node->base = (ulong)w_base << 16; - mem_node->length = (ulong)(w_length - w_base + 0x10) << 16; - - mem_node->next = func->mem_head; - func->mem_head = mem_node; - } - /* Save prefetchable memory base and Limit registers */ - pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base); - pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); - - if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) { - p_mem_node = kmalloc(sizeof(struct pci_resource), - GFP_KERNEL); - if (!p_mem_node) - return -ENOMEM; - - p_mem_node->base = (ulong)w_base << 16; - p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16; - - p_mem_node->next = func->p_mem_head; - func->p_mem_head = p_mem_node; - } - } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { - dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n", - func->bus, func->device, save_command); - - /* Figure out IO and memory base lengths */ - for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) { - pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base); - - temp_register = 0xFFFFFFFF; - pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register); - pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register); - - if (!disable) - pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base); - - if (!temp_register) - continue; - - base = temp_register; - - if ((base & PCI_BASE_ADDRESS_SPACE_IO) && - (!disable || (save_command & PCI_COMMAND_IO))) { - /* IO base */ - /* set temp_register = amount of IO space requested */ - base = base & 0xFFFFFFFCL; - base = (~base) + 1; - - io_node = kmalloc(sizeof (struct pci_resource), - GFP_KERNEL); - if (!io_node) - return -ENOMEM; - - io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK; - io_node->length = (ulong)base; - dbg("sur adapter: IO bar=0x%x(length=0x%x)\n", - io_node->base, io_node->length); - - io_node->next = func->io_head; - func->io_head = io_node; - } else { /* map Memory */ - int prefetchable = 1; - /* struct pci_resources **res_node; */ - char *res_type_str = "PMEM"; - u32 temp_register2; - - t_mem_node = kmalloc(sizeof (struct pci_resource), - GFP_KERNEL); - if (!t_mem_node) - return -ENOMEM; - - if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) && - (!disable || (save_command & PCI_COMMAND_MEMORY))) { - prefetchable = 0; - mem_node = t_mem_node; - res_type_str++; - } else - p_mem_node = t_mem_node; - - base = base & 0xFFFFFFF0L; - base = (~base) + 1; - - switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { - case PCI_BASE_ADDRESS_MEM_TYPE_32: - if (prefetchable) { - p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK; - p_mem_node->length = (ulong)base; - dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", - res_type_str, - p_mem_node->base, - p_mem_node->length); - - p_mem_node->next = func->p_mem_head; - func->p_mem_head = p_mem_node; - } else { - mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK; - mem_node->length = (ulong)base; - dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", - res_type_str, - mem_node->base, - mem_node->length); - - mem_node->next = func->mem_head; - func->mem_head = mem_node; - } - break; - case PCI_BASE_ADDRESS_MEM_TYPE_64: - pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2); - base64 = temp_register2; - base64 = (base64 << 32) | save_base; - - if (temp_register2) { - dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n", - res_type_str, temp_register2, (u32)base64); - base64 &= 0x00000000FFFFFFFFL; - } - - if (prefetchable) { - p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK; - p_mem_node->length = base; - dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", - res_type_str, - p_mem_node->base, - p_mem_node->length); - - p_mem_node->next = func->p_mem_head; - func->p_mem_head = p_mem_node; - } else { - mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK; - mem_node->length = base; - dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", - res_type_str, - mem_node->base, - mem_node->length); - - mem_node->next = func->mem_head; - func->mem_head = mem_node; - } - cloop += 4; - break; - default: - dbg("asur: reserved BAR type=0x%x\n", - temp_register); - break; - } - } - } /* End of base register loop */ - } else { /* Some other unknown header type */ - dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n", - func->bus, func->device); - } - - /* find the next device in this slot */ - if (!disable) - break; - func = shpchp_slot_find(func->bus, func->device, index++); - } - - return 0; -} - -/** - * kfree_resource_list: release memory of all list members - * @res: resource list to free - */ -static inline void -return_resource_list(struct pci_resource **func, struct pci_resource **res) -{ - struct pci_resource *node; - struct pci_resource *t_node; - - node = *func; - *func = NULL; - while (node) { - t_node = node->next; - return_resource(res, node); - node = t_node; - } -} - -/* - * shpchp_return_board_resources - * - * this routine returns all resources allocated to a board to - * the available pool. - * - * returns 0 if success - */ -int shpchp_return_board_resources(struct pci_func * func, - struct resource_lists * resources) -{ - int rc; - dbg("%s\n", __FUNCTION__); - - if (!func) - return 1; - - return_resource_list(&(func->io_head),&(resources->io_head)); - return_resource_list(&(func->mem_head),&(resources->mem_head)); - return_resource_list(&(func->p_mem_head),&(resources->p_mem_head)); - return_resource_list(&(func->bus_head),&(resources->bus_head)); - - rc = shpchp_resource_sort_and_combine(&(resources->mem_head)); - rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head)); - rc |= shpchp_resource_sort_and_combine(&(resources->io_head)); - rc |= shpchp_resource_sort_and_combine(&(resources->bus_head)); - - return rc; -} - -/** - * kfree_resource_list: release memory of all list members - * @res: resource list to free - */ -static inline void -kfree_resource_list(struct pci_resource **r) -{ - struct pci_resource *res, *tres; - - res = *r; - *r = NULL; - - while (res) { - tres = res; - res = res->next; - kfree(tres); - } -} - -/** - * shpchp_destroy_resource_list: put node back in the resource list - * @resources: list to put nodes back - */ -void shpchp_destroy_resource_list(struct resource_lists *resources) -{ - kfree_resource_list(&(resources->io_head)); - kfree_resource_list(&(resources->mem_head)); - kfree_resource_list(&(resources->p_mem_head)); - kfree_resource_list(&(resources->bus_head)); -} - -/** - * shpchp_destroy_board_resources: put node back in the resource list - * @resources: list to put nodes back - */ -void shpchp_destroy_board_resources(struct pci_func * func) -{ - kfree_resource_list(&(func->io_head)); - kfree_resource_list(&(func->mem_head)); - kfree_resource_list(&(func->p_mem_head)); - kfree_resource_list(&(func->bus_head)); -} diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index c9445ebda5c7..b0e781dbcffb 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -40,43 +40,49 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf) { - struct pci_dev *pci_dev; - struct controller *ctrl; + struct pci_dev *pdev; char * out = buf; - int index; - struct pci_resource *res; + int index, busnr; + struct resource *res; + struct pci_bus *bus; - pci_dev = container_of (dev, struct pci_dev, dev); - ctrl = pci_get_drvdata(pci_dev); + pdev = container_of (dev, struct pci_dev, dev); + bus = pdev->subordinate; out += sprintf(buf, "Free resources: memory\n"); - index = 11; - res = ctrl->mem_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { + res = bus->resource[index]; + if (res && (res->flags & IORESOURCE_MEM) && + !(res->flags & IORESOURCE_PREFETCH)) { + out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "Free resources: prefetchable memory\n"); - index = 11; - res = ctrl->p_mem_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { + res = bus->resource[index]; + if (res && (res->flags & IORESOURCE_MEM) && + (res->flags & IORESOURCE_PREFETCH)) { + out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "Free resources: IO\n"); - index = 11; - res = ctrl->io_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { + res = bus->resource[index]; + if (res && (res->flags & IORESOURCE_IO)) { + out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "Free resources: bus numbers\n"); - index = 11; - res = ctrl->bus_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) { + if (!pci_find_bus(pci_domain_nr(bus), busnr)) + break; } + if (busnr < bus->subordinate) + out += sprintf(out, "start = %8.8x, length = %8.8x\n", + busnr, (bus->subordinate - busnr)); return out - buf; } @@ -84,16 +90,16 @@ static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) { - struct pci_dev *pci_dev; + struct pci_dev *pdev, *fdev; struct controller *ctrl; char * out = buf; int index; - struct pci_resource *res; + struct resource *res; struct pci_func *new_slot; struct slot *slot; - pci_dev = container_of (dev, struct pci_dev, dev); - ctrl = pci_get_drvdata(pci_dev); + pdev = container_of (dev, struct pci_dev, dev); + ctrl = pci_get_drvdata(pdev); slot=ctrl->slot; @@ -101,34 +107,47 @@ static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char new_slot = shpchp_slot_find(slot->bus, slot->device, 0); if (!new_slot) break; + fdev = new_slot->pci_dev; + if (!fdev) + break; out += sprintf(out, "assigned resources: memory\n"); - index = 11; - res = new_slot->mem_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index=0; index <= PCI_NUM_RESOURCES; index++) { + res = &(fdev->resource[index]); + if (res && (res->flags & IORESOURCE_MEM) && + !(res->flags & IORESOURCE_PREFETCH)) { + out += sprintf(out, + "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "assigned resources: prefetchable memory\n"); - index = 11; - res = new_slot->p_mem_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index=0; index <= PCI_NUM_RESOURCES; index++) { + res = &(fdev->resource[index]); + if (res && (res->flags & (IORESOURCE_MEM | + IORESOURCE_PREFETCH))) { + out += sprintf(out, + "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "assigned resources: IO\n"); - index = 11; - res = new_slot->io_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; + for (index=0; index <= PCI_NUM_RESOURCES; index++) { + res = &(fdev->resource[index]); + if (res && (res->flags & IORESOURCE_IO)) { + out += sprintf(out, + "start = %8.8lx, length = %8.8lx\n", + res->start, (res->end - res->start)); + } } out += sprintf(out, "assigned resources: bus numbers\n"); - index = 11; - res = new_slot->bus_head; - while (res && index--) { - out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length); - res = res->next; - } + if (fdev->subordinate) + out += sprintf(out, "start = %8.8x, length = %8.8x\n", + fdev->subordinate->secondary, + (fdev->subordinate->subordinate - + fdev->subordinate->secondary)); + else + out += sprintf(out, "start = %8.8x, length = %8.8x\n", + fdev->bus->number, 1); slot=slot->next; } diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h index 057b192ce589..df474b27d6e8 100644 --- a/drivers/pci/hotplug/shpchprm.h +++ b/drivers/pci/hotplug/shpchprm.h @@ -32,24 +32,12 @@ #ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY #include "shpchprm_legacy.h" -#else -#include "shpchprm_nonacpi.h" #endif int shpchprm_init(enum php_ctlr_type ct); void shpchprm_cleanup(void); -int shpchprm_print_pirt(void); -int shpchprm_find_available_resources(struct controller *ctrl); int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type); void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type); int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum); -#ifdef DEBUG -#define RES_CHECK(this, bits) \ - { if (((this) & (bits - 1))) \ - printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); } -#else -#define RES_CHECK(this, bits) -#endif - #endif /* _SHPCHPRM_H_ */ diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index d37b31658edf..3d2f9c5269c7 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -34,9 +34,6 @@ #include #include #include -#ifdef CONFIG_IA64 -#include -#endif #include #include #include @@ -75,10 +72,6 @@ struct acpi_php_slot { int dev; int fun; u32 sun; - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; void *slot_ops; /* _STA, _EJx, etc */ struct slot *slot; }; /* per func */ @@ -95,14 +88,6 @@ struct acpi_bridge { int bus; /* pdev->subordinate->number */ struct acpi__hpp *_hpp; struct acpi_php_slot *slots; - struct pci_resource *tmem_head; /* total from crs */ - struct pci_resource *tp_mem_head; /* total from crs */ - struct pci_resource *tio_head; /* total from crs */ - struct pci_resource *tbus_head; /* total from crs */ - struct pci_resource *mem_head; /* available */ - struct pci_resource *p_mem_head; /* available */ - struct pci_resource *io_head; /* available */ - struct pci_resource *bus_head; /* available */ int scanned; int type; }; @@ -252,485 +237,6 @@ static void acpi_run_oshp ( struct acpi_bridge *ab) return; } -static acpi_status acpi_evaluate_crs( - acpi_handle handle, - struct acpi_resource **retbuf - ) -{ - acpi_status status; - struct acpi_buffer crsbuf; - u8 *path_name = acpi_path_name(handle); - - crsbuf.length = 0; - crsbuf.pointer = NULL; - - status = acpi_get_current_resources (handle, &crsbuf); - - switch (status) { - case AE_BUFFER_OVERFLOW: - break; /* found */ - case AE_NOT_FOUND: - dbg("acpi_shpchprm:%s _CRS not found\n", path_name); - return status; - default: - err ("acpi_shpchprm:%s _CRS fail=0x%x\n", path_name, status); - return status; - } - - crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL); - if (!crsbuf.pointer) { - err ("acpi_shpchprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name); - return AE_NO_MEMORY; - } - - status = acpi_get_current_resources (handle, &crsbuf); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm: %s _CRS fail=0x%x.\n", path_name, status); - kfree(crsbuf.pointer); - return status; - } - - *retbuf = crsbuf.pointer; - - return status; -} - -static void free_pci_resource ( struct pci_resource *aprh) -{ - struct pci_resource *res, *next; - - for (res = aprh; res; res = next) { - next = res->next; - kfree(res); - } -} - -static void print_pci_resource ( struct pci_resource *aprh) -{ - struct pci_resource *res; - - for (res = aprh; res; res = res->next) - dbg(" base= 0x%x length= 0x%x\n", res->base, res->length); -} - -static void print_slot_resources( struct acpi_php_slot *aps) -{ - if (aps->bus_head) { - dbg(" BUS Resources:\n"); - print_pci_resource (aps->bus_head); - } - - if (aps->io_head) { - dbg(" IO Resources:\n"); - print_pci_resource (aps->io_head); - } - - if (aps->mem_head) { - dbg(" MEM Resources:\n"); - print_pci_resource (aps->mem_head); - } - - if (aps->p_mem_head) { - dbg(" PMEM Resources:\n"); - print_pci_resource (aps->p_mem_head); - } -} - -static void print_pci_resources( struct acpi_bridge *ab) -{ - if (ab->tbus_head) { - dbg(" Total BUS Resources:\n"); - print_pci_resource (ab->tbus_head); - } - if (ab->bus_head) { - dbg(" BUS Resources:\n"); - print_pci_resource (ab->bus_head); - } - - if (ab->tio_head) { - dbg(" Total IO Resources:\n"); - print_pci_resource (ab->tio_head); - } - if (ab->io_head) { - dbg(" IO Resources:\n"); - print_pci_resource (ab->io_head); - } - - if (ab->tmem_head) { - dbg(" Total MEM Resources:\n"); - print_pci_resource (ab->tmem_head); - } - if (ab->mem_head) { - dbg(" MEM Resources:\n"); - print_pci_resource (ab->mem_head); - } - - if (ab->tp_mem_head) { - dbg(" Total PMEM Resources:\n"); - print_pci_resource (ab->tp_mem_head); - } - if (ab->p_mem_head) { - dbg(" PMEM Resources:\n"); - print_pci_resource (ab->p_mem_head); - } - if (ab->_hpp) { - dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size); - dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer); - dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr); - dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr); - } -} - -static int shpchprm_delete_resource( - struct pci_resource **aprh, - ulong base, - ulong size) -{ - struct pci_resource *res; - struct pci_resource *prevnode; - struct pci_resource *split_node; - ulong tbase; - - shpchp_resource_sort_and_combine(aprh); - - for (res = *aprh; res; res = res->next) { - if (res->base > base) - continue; - - if ((res->base + res->length) < (base + size)) - continue; - - if (res->base < base) { - tbase = base; - - if ((res->length - (tbase - res->base)) < size) - continue; - - split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!split_node) - return -ENOMEM; - - split_node->base = res->base; - split_node->length = tbase - res->base; - res->base = tbase; - res->length -= split_node->length; - - split_node->next = res->next; - res->next = split_node; - } - - if (res->length >= size) { - split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!split_node) - return -ENOMEM; - - split_node->base = res->base + size; - split_node->length = res->length - size; - res->length = size; - - split_node->next = res->next; - res->next = split_node; - } - - if (*aprh == res) { - *aprh = res->next; - } else { - prevnode = *aprh; - while (prevnode->next != res) - prevnode = prevnode->next; - - prevnode->next = res->next; - } - res->next = NULL; - kfree(res); - break; - } - - return 0; -} - -static int shpchprm_delete_resources( - struct pci_resource **aprh, - struct pci_resource *this - ) -{ - struct pci_resource *res; - - for (res = this; res; res = res->next) - shpchprm_delete_resource(aprh, res->base, res->length); - - return 0; -} - -static int shpchprm_add_resource( - struct pci_resource **aprh, - ulong base, - ulong size) -{ - struct pci_resource *res; - - for (res = *aprh; res; res = res->next) { - if ((res->base + res->length) == base) { - res->length += size; - size = 0L; - break; - } - if (res->next == *aprh) - break; - } - - if (size) { - res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!res) { - err ("acpi_shpchprm: alloc for res fail\n"); - return -ENOMEM; - } - memset(res, 0, sizeof (struct pci_resource)); - - res->base = base; - res->length = size; - res->next = *aprh; - *aprh = res; - } - - return 0; -} - -static int shpchprm_add_resources( - struct pci_resource **aprh, - struct pci_resource *this - ) -{ - struct pci_resource *res; - int rc = 0; - - for (res = this; res && !rc; res = res->next) - rc = shpchprm_add_resource(aprh, res->base, res->length); - - return rc; -} - -static void acpi_parse_io ( - struct acpi_bridge *ab, - union acpi_resource_data *data - ) -{ - struct acpi_resource_io *dataio; - dataio = (struct acpi_resource_io *) data; - - dbg("Io Resource\n"); - dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10); - dbg(" Range minimum base: %08X\n", dataio->min_base_address); - dbg(" Range maximum base: %08X\n", dataio->max_base_address); - dbg(" Alignment: %08X\n", dataio->alignment); - dbg(" Range Length: %08X\n", dataio->range_length); -} - -static void acpi_parse_fixed_io ( - struct acpi_bridge *ab, - union acpi_resource_data *data - ) -{ - struct acpi_resource_fixed_io *datafio; - datafio = (struct acpi_resource_fixed_io *) data; - - dbg("Fixed Io Resource\n"); - dbg(" Range base address: %08X", datafio->base_address); - dbg(" Range length: %08X", datafio->range_length); -} - -static void acpi_parse_address16_32 ( - struct acpi_bridge *ab, - union acpi_resource_data *data, - acpi_resource_type id - ) -{ - /* - * acpi_resource_address16 == acpi_resource_address32 - * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data; - */ - struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data; - struct pci_resource **aprh, **tprh; - - if (id == ACPI_RSTYPE_ADDRESS16) - dbg("acpi_shpchprm:16-Bit Address Space Resource\n"); - else - dbg("acpi_shpchprm:32-Bit Address Space Resource\n"); - - switch (data32->resource_type) { - case ACPI_MEMORY_RANGE: - dbg(" Resource Type: Memory Range\n"); - aprh = &ab->mem_head; - tprh = &ab->tmem_head; - - switch (data32->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - dbg(" Type Specific: Noncacheable memory\n"); - break; - case ACPI_CACHABLE_MEMORY: - dbg(" Type Specific: Cacheable memory\n"); - break; - case ACPI_WRITE_COMBINING_MEMORY: - dbg(" Type Specific: Write-combining memory\n"); - break; - case ACPI_PREFETCHABLE_MEMORY: - aprh = &ab->p_mem_head; - dbg(" Type Specific: Prefetchable memory\n"); - break; - default: - dbg(" Type Specific: Invalid cache attribute\n"); - break; - } - - dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only"); - break; - - case ACPI_IO_RANGE: - dbg(" Resource Type: I/O Range\n"); - aprh = &ab->io_head; - tprh = &ab->tio_head; - - switch (data32->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - dbg(" Type Specific: Non-ISA Io Addresses\n"); - break; - case ACPI_ISA_ONLY_RANGES: - dbg(" Type Specific: ISA Io Addresses\n"); - break; - case ACPI_ENTIRE_RANGE: - dbg(" Type Specific: ISA and non-ISA Io Addresses\n"); - break; - default: - dbg(" Type Specific: Invalid range attribute\n"); - break; - } - break; - - case ACPI_BUS_NUMBER_RANGE: - dbg(" Resource Type: Bus Number Range(fixed)\n"); - /* fixup to be compatible with the rest of php driver */ - data32->min_address_range++; - data32->address_length--; - aprh = &ab->bus_head; - tprh = &ab->tbus_head; - break; - default: - dbg(" Resource Type: Invalid resource type. Exiting.\n"); - return; - } - - dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer"); - dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive"); - dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not"); - dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not"); - dbg(" Granularity: %08X\n", data32->granularity); - dbg(" Address range min: %08X\n", data32->min_address_range); - dbg(" Address range max: %08X\n", data32->max_address_range); - dbg(" Address translation offset: %08X\n", data32->address_translation_offset); - dbg(" Address Length: %08X\n", data32->address_length); - - if (0xFF != data32->resource_source.index) { - dbg(" Resource Source Index: %X\n", data32->resource_source.index); - /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */ - } - - shpchprm_add_resource(aprh, data32->min_address_range, data32->address_length); -} - -static acpi_status acpi_parse_crs( - struct acpi_bridge *ab, - struct acpi_resource *crsbuf - ) -{ - acpi_status status = AE_OK; - struct acpi_resource *resource = crsbuf; - u8 count = 0; - u8 done = 0; - - while (!done) { - dbg("acpi_shpchprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++); - switch (resource->id) { - case ACPI_RSTYPE_IRQ: - dbg("Irq -------- Resource\n"); - break; - case ACPI_RSTYPE_DMA: - dbg("DMA -------- Resource\n"); - break; - case ACPI_RSTYPE_START_DPF: - dbg("Start DPF -------- Resource\n"); - break; - case ACPI_RSTYPE_END_DPF: - dbg("End DPF -------- Resource\n"); - break; - case ACPI_RSTYPE_IO: - acpi_parse_io (ab, &resource->data); - break; - case ACPI_RSTYPE_FIXED_IO: - acpi_parse_fixed_io (ab, &resource->data); - break; - case ACPI_RSTYPE_VENDOR: - dbg("Vendor -------- Resource\n"); - break; - case ACPI_RSTYPE_END_TAG: - dbg("End_tag -------- Resource\n"); - done = 1; - break; - case ACPI_RSTYPE_MEM24: - dbg("Mem24 -------- Resource\n"); - break; - case ACPI_RSTYPE_MEM32: - dbg("Mem32 -------- Resource\n"); - break; - case ACPI_RSTYPE_FIXED_MEM32: - dbg("Fixed Mem32 -------- Resource\n"); - break; - case ACPI_RSTYPE_ADDRESS16: - acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16); - break; - case ACPI_RSTYPE_ADDRESS32: - acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32); - break; - case ACPI_RSTYPE_ADDRESS64: - info("Address64 -------- Resource unparsed\n"); - break; - case ACPI_RSTYPE_EXT_IRQ: - dbg("Ext Irq -------- Resource\n"); - break; - default: - dbg("Invalid -------- resource type 0x%x\n", resource->id); - break; - } - - resource = (struct acpi_resource *) ((char *)resource + resource->length); - } - - return status; -} - -static acpi_status acpi_get_crs( struct acpi_bridge *ab) -{ - acpi_status status; - struct acpi_resource *crsbuf; - - status = acpi_evaluate_crs(ab->handle, &crsbuf); - if (ACPI_SUCCESS(status)) { - status = acpi_parse_crs(ab, crsbuf); - kfree(crsbuf); - - shpchp_resource_sort_and_combine(&ab->bus_head); - shpchp_resource_sort_and_combine(&ab->io_head); - shpchp_resource_sort_and_combine(&ab->mem_head); - shpchp_resource_sort_and_combine(&ab->p_mem_head); - - shpchprm_add_resources (&ab->tbus_head, ab->bus_head); - shpchprm_add_resources (&ab->tio_head, ab->io_head); - shpchprm_add_resources (&ab->tmem_head, ab->mem_head); - shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head); - } - - return status; -} - /* find acpi_bridge downword from ab. */ static struct acpi_bridge * find_acpi_bridge_by_bus( @@ -1047,13 +553,6 @@ static struct acpi_bridge * add_host_bridge( ab->scanned = 0; ab->type = BRIDGE_TYPE_HOST; - /* get root pci bridge's current resources */ - status = acpi_get_crs(ab); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s evaluate _CRS fail=0x%x\n", path_name, status); - kfree(ab); - return NULL; - } build_a_bridge(ab, ab); return ab; @@ -1147,11 +646,6 @@ static void free_a_slot(struct acpi_php_slot *aps) { dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun); - free_pci_resource (aps->io_head); - free_pci_resource (aps->bus_head); - free_pci_resource (aps->mem_head); - free_pci_resource (aps->p_mem_head); - kfree(aps); } @@ -1176,15 +670,6 @@ static void free_a_bridge( struct acpi_bridge *ab) free_a_slot(aps); } - free_pci_resource (ab->io_head); - free_pci_resource (ab->tio_head); - free_pci_resource (ab->bus_head); - free_pci_resource (ab->tbus_head); - free_pci_resource (ab->mem_head); - free_pci_resource (ab->tmem_head); - free_pci_resource (ab->p_mem_head); - free_pci_resource (ab->tp_mem_head); - kfree(ab); } @@ -1234,47 +719,6 @@ static int get_number_of_slots ( return slot_num; } -static int print_acpi_resources (struct acpi_bridge *ab) -{ - struct acpi_php_slot *aps; - int i; - - switch (ab->type) { - case BRIDGE_TYPE_HOST: - dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle)); - break; - case BRIDGE_TYPE_P2P: - dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle)); - break; - }; - - print_pci_resources (ab); - - for ( i = -1, aps = ab->slots; aps; aps = aps->next) { - if (aps->dev == i) - continue; - dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun); - print_slot_resources(aps); - i = aps->dev; - } - - if (ab->child) - print_acpi_resources (ab->child); - - if (ab->next) - print_acpi_resources (ab->next); - - return 0; -} - -int shpchprm_print_pirt(void) -{ - dbg("SHPCHPRM ACPI Slots\n"); - if (acpi_bridges_head) - print_acpi_resources (acpi_bridges_head); - return 0; -} - static struct acpi_php_slot * get_acpi_slot ( struct acpi_bridge *ab, u32 sun @@ -1302,265 +746,6 @@ static struct acpi_php_slot * get_acpi_slot ( } -#if 0 -static void * shpchprm_get_slot(struct slot *slot) -{ - struct acpi_bridge *ab = acpi_bridges_head; - struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number); - - aps->slot = slot; - - dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun); - - return (void *)aps; -} -#endif - -static void shpchprm_dump_func_res( struct pci_func *fun) -{ - struct pci_func *func = fun; - - if (func->bus_head) { - dbg(": BUS Resources:\n"); - print_pci_resource (func->bus_head); - } - if (func->io_head) { - dbg(": IO Resources:\n"); - print_pci_resource (func->io_head); - } - if (func->mem_head) { - dbg(": MEM Resources:\n"); - print_pci_resource (func->mem_head); - } - if (func->p_mem_head) { - dbg(": PMEM Resources:\n"); - print_pci_resource (func->p_mem_head); - } -} - -static void shpchprm_dump_ctrl_res( struct controller *ctlr) -{ - struct controller *ctrl = ctlr; - - if (ctrl->bus_head) { - dbg(": BUS Resources:\n"); - print_pci_resource (ctrl->bus_head); - } - if (ctrl->io_head) { - dbg(": IO Resources:\n"); - print_pci_resource (ctrl->io_head); - } - if (ctrl->mem_head) { - dbg(": MEM Resources:\n"); - print_pci_resource (ctrl->mem_head); - } - if (ctrl->p_mem_head) { - dbg(": PMEM Resources:\n"); - print_pci_resource (ctrl->p_mem_head); - } -} - -static int shpchprm_get_used_resources ( - struct controller *ctrl, - struct pci_func *func - ) -{ - return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD); -} - -static int configure_existing_function( - struct controller *ctrl, - struct pci_func *func - ) -{ - int rc; - - /* see how much resources the func has used. */ - rc = shpchprm_get_used_resources (ctrl, func); - - if (!rc) { - /* subtract the resources used by the func from ctrl resources */ - rc = shpchprm_delete_resources (&ctrl->bus_head, func->bus_head); - rc |= shpchprm_delete_resources (&ctrl->io_head, func->io_head); - rc |= shpchprm_delete_resources (&ctrl->mem_head, func->mem_head); - rc |= shpchprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head); - if (rc) - warn("aCEF: cannot del used resources\n"); - } else - err("aCEF: cannot get used resources\n"); - - return rc; -} - -static int bind_pci_resources_to_slots ( struct controller *ctrl) -{ - struct pci_func *func, new_func; - int busn = ctrl->slot_bus; - int devn, funn; - u32 vid; - - for (devn = 0; devn < 32; devn++) { - for (funn = 0; funn < 8; funn++) { - /* - if (devn == ctrl->device && funn == ctrl->function) - continue; - */ - /* find out if this entry is for an occupied slot */ - vid = 0xFFFFFFFF; - pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid); - - if (vid != 0xFFFFFFFF) { - func = shpchp_slot_find(busn, devn, funn); - if (!func) { - memset(&new_func, 0, sizeof(struct pci_func)); - new_func.bus = busn; - new_func.device = devn; - new_func.function = funn; - new_func.is_a_board = 1; - configure_existing_function(ctrl, &new_func); - shpchprm_dump_func_res(&new_func); - } else { - configure_existing_function(ctrl, func); - shpchprm_dump_func_res(func); - } - dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - } - } - } - - return 0; -} - -static int bind_pci_resources( - struct controller *ctrl, - struct acpi_bridge *ab - ) -{ - int status = 0; - - if (ab->bus_head) { - dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus); - status = shpchprm_add_resources (&ctrl->bus_head, ab->bus_head); - if (shpchprm_delete_resources (&ab->bus_head, ctrl->bus_head)) - warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus); - if (status) { - err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status); - return status; - } - } else - info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus); - - if (ab->io_head) { - dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus); - status = shpchprm_add_resources (&ctrl->io_head, ab->io_head); - if (shpchprm_delete_resources (&ab->io_head, ctrl->io_head)) - warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus); - if (status) { - err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status); - return status; - } - } else - info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus); - - if (ab->mem_head) { - dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus); - status = shpchprm_add_resources (&ctrl->mem_head, ab->mem_head); - if (shpchprm_delete_resources (&ab->mem_head, ctrl->mem_head)) - warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus); - if (status) { - err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status); - return status; - } - } else - info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus); - - if (ab->p_mem_head) { - dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus); - status = shpchprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head); - if (shpchprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head)) - warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus); - if (status) { - err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status); - return status; - } - } else - info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus); - - return status; -} - -static int no_pci_resources( struct acpi_bridge *ab) -{ - return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head); -} - -static int find_pci_bridge_resources ( - struct controller *ctrl, - struct acpi_bridge *ab - ) -{ - int rc = 0; - struct pci_func func; - - memset(&func, 0, sizeof(struct pci_func)); - - func.bus = ab->pbus; - func.device = ab->pdevice; - func.function = ab->pfunction; - func.is_a_board = 1; - - /* Get used resources for this PCI bridge */ - rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD); - - ab->io_head = func.io_head; - ab->mem_head = func.mem_head; - ab->p_mem_head = func.p_mem_head; - ab->bus_head = func.bus_head; - if (ab->bus_head) - shpchprm_delete_resource(&ab->bus_head, ctrl->bus, 1); - - return rc; -} - -static int get_pci_resources_from_bridge( - struct controller *ctrl, - struct acpi_bridge *ab - ) -{ - int rc = 0; - - dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus); - - rc = find_pci_bridge_resources (ctrl, ab); - - shpchp_resource_sort_and_combine(&ab->bus_head); - shpchp_resource_sort_and_combine(&ab->io_head); - shpchp_resource_sort_and_combine(&ab->mem_head); - shpchp_resource_sort_and_combine(&ab->p_mem_head); - - shpchprm_add_resources (&ab->tbus_head, ab->bus_head); - shpchprm_add_resources (&ab->tio_head, ab->io_head); - shpchprm_add_resources (&ab->tmem_head, ab->mem_head); - shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head); - - return rc; -} - -static int get_pci_resources( - struct controller *ctrl, - struct acpi_bridge *ab - ) -{ - int rc = 0; - - if (no_pci_resources(ab)) { - dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus); - rc = get_pci_resources_from_bridge(ctrl, ab); - } - - return rc; -} - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { int offset = devnum - ctrl->slot_device_offset; @@ -1570,42 +755,6 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -/* - * Get resources for this ctrl. - * 1. get total resources from ACPI _CRS or bridge (this ctrl) - * 2. find used resources of existing adapters - * 3. subtract used resources from total resources - */ -int shpchprm_find_available_resources( struct controller *ctrl) -{ - int rc = 0; - struct acpi_bridge *ab; - - ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number); - if (!ab) { - err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number); - return -1; - } - if (no_pci_resources(ab)) { - rc = get_pci_resources(ctrl, ab); - if (rc) { - err("pfar:cannot get pci resources of PCI 0x%x.\n",ctrl->pci_dev->subordinate->number); - return -1; - } - } - - rc = bind_pci_resources(ctrl, ab); - dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number); - shpchprm_dump_ctrl_res(ctrl); - - bind_pci_resources_to_slots (ctrl); - - dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number); - shpchprm_dump_ctrl_res(ctrl); - - return rc; -} - int shpchprm_set_hpp( struct controller *ctrl, struct pci_func *func, diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index ba6c549c9b9d..6c27debe9522 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -34,25 +34,11 @@ #include #include #include -#ifdef CONFIG_IA64 -#include -#endif #include "shpchp.h" #include "shpchprm.h" -#include "shpchprm_legacy.h" - -static void __iomem *shpchp_rom_start; -static u16 unused_IRQ; void shpchprm_cleanup(void) { - if (shpchp_rom_start) - iounmap(shpchp_rom_start); -} - -int shpchprm_print_pirt(void) -{ - return 0; } int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) @@ -63,280 +49,6 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -/* Find the Hot Plug Resource Table in the specified region of memory */ -static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end) -{ - void __iomem *fp; - void __iomem *endp; - u8 temp1, temp2, temp3, temp4; - int status = 0; - - endp = (end - sizeof(struct hrt) + 1); - - for (fp = begin; fp <= endp; fp += 16) { - temp1 = readb(fp + SIG0); - temp2 = readb(fp + SIG1); - temp3 = readb(fp + SIG2); - temp4 = readb(fp + SIG3); - if (temp1 == '$' && temp2 == 'H' && temp3 == 'R' && temp4 == 'T') { - status = 1; - break; - } - } - - if (!status) - fp = NULL; - - dbg("Discovered Hotplug Resource Table at %p\n", fp); - return fp; -} - -/* - * shpchprm_find_available_resources - * - * Finds available memory, IO, and IRQ resources for programming - * devices which may be added to the system - * this function is for hot plug ADD! - * - * returns 0 if success - */ -int shpchprm_find_available_resources(struct controller *ctrl) -{ - u8 populated_slot; - u8 bridged_slot; - void __iomem *one_slot; - struct pci_func *func = NULL; - int i = 10, index = 0; - u32 temp_dword, rc; - ulong temp_ulong; - struct pci_resource *mem_node; - struct pci_resource *p_mem_node; - struct pci_resource *io_node; - struct pci_resource *bus_node; - void __iomem *rom_resource_table; - struct pci_bus lpci_bus, *pci_bus; - u8 cfgspc_irq, temp; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_rom_start + 0xffff); - dbg("rom_resource_table = %p\n", rom_resource_table); - if (rom_resource_table == NULL) - return -ENODEV; - - /* Sum all resources and setup resource maps */ - unused_IRQ = readl(rom_resource_table + UNUSED_IRQ); - dbg("unused_IRQ = %x\n", unused_IRQ); - - temp = 0; - while (unused_IRQ) { - if (unused_IRQ & 1) { - shpchp_disk_irq = temp; - break; - } - unused_IRQ = unused_IRQ >> 1; - temp++; - } - - dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq); - unused_IRQ = unused_IRQ >> 1; - temp++; - - while (unused_IRQ) { - if (unused_IRQ & 1) { - shpchp_nic_irq = temp; - break; - } - unused_IRQ = unused_IRQ >> 1; - temp++; - } - - dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq); - unused_IRQ = readl(rom_resource_table + PCIIRQ); - - temp = 0; - - pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq); - - if (!shpchp_nic_irq) { - shpchp_nic_irq = cfgspc_irq; - } - - if (!shpchp_disk_irq) { - shpchp_disk_irq = cfgspc_irq; - } - - dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq); - - one_slot = rom_resource_table + sizeof(struct hrt); - - i = readb(rom_resource_table + NUMBER_OF_ENTRIES); - dbg("number_of_entries = %d\n", i); - - if (!readb(one_slot + SECONDARY_BUS)) - return (1); - - dbg("dev|IO base|length|MEMbase|length|PM base|length|PB SB MB\n"); - - while (i && readb(one_slot + SECONDARY_BUS)) { - u8 dev_func = readb(one_slot + DEV_FUNC); - u8 primary_bus = readb(one_slot + PRIMARY_BUS); - u8 secondary_bus = readb(one_slot + SECONDARY_BUS); - u8 max_bus = readb(one_slot + MAX_BUS); - u16 io_base = readw(one_slot + IO_BASE); - u16 io_length = readw(one_slot + IO_LENGTH); - u16 mem_base = readw(one_slot + MEM_BASE); - u16 mem_length = readw(one_slot + MEM_LENGTH); - u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE); - u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH); - - dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n", - dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length, - primary_bus, secondary_bus, max_bus); - - /* If this entry isn't for our controller's bus, ignore it */ - if (primary_bus != ctrl->slot_bus) { - i--; - one_slot += sizeof(struct slot_rt); - continue; - } - /* find out if this entry is for an occupied slot */ - temp_dword = 0xFFFFFFFF; - pci_bus->number = primary_bus; - pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); - - dbg("temp_D_word = %x\n", temp_dword); - - if (temp_dword != 0xFFFFFFFF) { - index = 0; - func = shpchp_slot_find(primary_bus, dev_func >> 3, 0); - - while (func && (func->function != (dev_func & 0x07))) { - dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index); - func = shpchp_slot_find(primary_bus, dev_func >> 3, index++); - } - - /* If we can't find a match, skip this table entry */ - if (!func) { - i--; - one_slot += sizeof(struct slot_rt); - continue; - } - /* this may not work and shouldn't be used */ - if (secondary_bus != primary_bus) - bridged_slot = 1; - else - bridged_slot = 0; - - populated_slot = 1; - } else { - populated_slot = 0; - bridged_slot = 0; - } - dbg("slot populated =%s \n", populated_slot?"yes":"no"); - - /* If we've got a valid IO base, use it */ - - temp_ulong = io_base + io_length; - - if ((io_base) && (temp_ulong <= 0x10000)) { - io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!io_node) - return -ENOMEM; - - io_node->base = (ulong)io_base; - io_node->length = (ulong)io_length; - dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length); - - if (!populated_slot) { - io_node->next = ctrl->io_head; - ctrl->io_head = io_node; - } else { - io_node->next = func->io_head; - func->io_head = io_node; - } - } - - /* If we've got a valid memory base, use it */ - temp_ulong = mem_base + mem_length; - if ((mem_base) && (temp_ulong <= 0x10000)) { - mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!mem_node) - return -ENOMEM; - - mem_node->base = (ulong)mem_base << 16; - mem_node->length = (ulong)(mem_length << 16); - dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length); - - if (!populated_slot) { - mem_node->next = ctrl->mem_head; - ctrl->mem_head = mem_node; - } else { - mem_node->next = func->mem_head; - func->mem_head = mem_node; - } - } - - /* - * If we've got a valid prefetchable memory base, and - * the base + length isn't greater than 0xFFFF - */ - temp_ulong = pre_mem_base + pre_mem_length; - if ((pre_mem_base) && (temp_ulong <= 0x10000)) { - p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!p_mem_node) - return -ENOMEM; - - p_mem_node->base = (ulong)pre_mem_base << 16; - p_mem_node->length = (ulong)pre_mem_length << 16; - dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length); - - if (!populated_slot) { - p_mem_node->next = ctrl->p_mem_head; - ctrl->p_mem_head = p_mem_node; - } else { - p_mem_node->next = func->p_mem_head; - func->p_mem_head = p_mem_node; - } - } - - /* - * If we've got a valid bus number, use it - * The second condition is to ignore bus numbers on - * populated slots that don't have PCI-PCI bridges - */ - if (secondary_bus && (secondary_bus != primary_bus)) { - bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!bus_node) - return -ENOMEM; - - bus_node->base = (ulong)secondary_bus; - bus_node->length = (ulong)(max_bus - secondary_bus + 1); - dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length); - - if (!populated_slot) { - bus_node->next = ctrl->bus_head; - ctrl->bus_head = bus_node; - } else { - bus_node->next = func->bus_head; - func->bus_head = bus_node; - } - } - - i--; - one_slot += sizeof(struct slot_rt); - } - - /* If all of the following fail, we don't have any resources for hot plug add */ - rc = 1; - rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head)); - - return (rc); -} - int shpchprm_set_hpp( struct controller *ctrl, struct pci_func *func, @@ -413,12 +125,6 @@ void shpchprm_enable_card( static int legacy_shpchprm_init_pci(void) { - shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN); - if (!shpchp_rom_start) { - err("Could not ioremap memory region for ROM\n"); - return -EIO; - } - return 0; } diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h deleted file mode 100644 index 21bda74ddfa5..000000000000 --- a/drivers/pci/hotplug/shpchprm_legacy.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001 IBM Corp. - * Copyright (C) 2003-2004 Intel Corporation - * - * All rights reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to , - * - */ - -#ifndef _SHPCHPRM_LEGACY_H_ -#define _SHPCHPRM_LEGACY_H_ - -#define ROM_PHY_ADDR 0x0F0000 -#define ROM_PHY_LEN 0x00FFFF - -struct slot_rt { - u8 dev_func; - u8 primary_bus; - u8 secondary_bus; - u8 max_bus; - u16 io_base; - u16 io_length; - u16 mem_base; - u16 mem_length; - u16 pre_mem_base; - u16 pre_mem_length; -} __attribute__ ((packed)); - -/* offsets to the hotplug slot resource table registers based on the above structure layout */ -enum slot_rt_offsets { - DEV_FUNC = offsetof(struct slot_rt, dev_func), - PRIMARY_BUS = offsetof(struct slot_rt, primary_bus), - SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus), - MAX_BUS = offsetof(struct slot_rt, max_bus), - IO_BASE = offsetof(struct slot_rt, io_base), - IO_LENGTH = offsetof(struct slot_rt, io_length), - MEM_BASE = offsetof(struct slot_rt, mem_base), - MEM_LENGTH = offsetof(struct slot_rt, mem_length), - PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base), - PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length), -}; - -struct hrt { - char sig0; - char sig1; - char sig2; - char sig3; - u16 unused_IRQ; - u16 PCIIRQ; - u8 number_of_entries; - u8 revision; - u16 reserved1; - u32 reserved2; -} __attribute__ ((packed)); - -/* offsets to the hotplug resource table registers based on the above structure layout */ -enum hrt_offsets { - SIG0 = offsetof(struct hrt, sig0), - SIG1 = offsetof(struct hrt, sig1), - SIG2 = offsetof(struct hrt, sig2), - SIG3 = offsetof(struct hrt, sig3), - UNUSED_IRQ = offsetof(struct hrt, unused_IRQ), - PCIIRQ = offsetof(struct hrt, PCIIRQ), - NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries), - REVISION = offsetof(struct hrt, revision), - HRT_RESERVED1 = offsetof(struct hrt, reserved1), - HRT_RESERVED2 = offsetof(struct hrt, reserved2), -}; - -struct irq_info { - u8 bus, devfn; /* bus, device and function */ - struct { - u8 link; /* IRQ line ID, chipset dependent, 0=not routed */ - u16 bitmap; /* Available IRQs */ - } __attribute__ ((packed)) irq[4]; - u8 slot; /* slot number, 0=onboard */ - u8 rfu; -} __attribute__ ((packed)); - -struct irq_routing_table { - u32 signature; /* PIRQ_SIGNATURE should be here */ - u16 version; /* PIRQ_VERSION */ - u16 size; /* Table size in bytes */ - u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ - u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ - u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */ - u32 miniport_data; /* Crap */ - u8 rfu[11]; - u8 checksum; /* Modulo 256 checksum must give zero */ - struct irq_info slots[0]; -} __attribute__ ((packed)); - -#endif /* _SHPCHPRM_LEGACY_H_ */ diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c index 5f75ef7f3df2..9d4ccae5f78e 100644 --- a/drivers/pci/hotplug/shpchprm_nonacpi.c +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c @@ -34,23 +34,14 @@ #include #include #include -#ifdef CONFIG_IA64 -#include -#endif #include "shpchp.h" #include "shpchprm.h" -#include "shpchprm_nonacpi.h" void shpchprm_cleanup(void) { return; } -int shpchprm_print_pirt(void) -{ - return 0; -} - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { int offset = devnum - ctrl->slot_device_offset; @@ -60,275 +51,6 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -static void print_pci_resource ( struct pci_resource *aprh) -{ - struct pci_resource *res; - - for (res = aprh; res; res = res->next) - dbg(" base= 0x%x length= 0x%x\n", res->base, res->length); -} - - -static void phprm_dump_func_res( struct pci_func *fun) -{ - struct pci_func *func = fun; - - if (func->bus_head) { - dbg(": BUS Resources:\n"); - print_pci_resource (func->bus_head); - } - if (func->io_head) { - dbg(": IO Resources:\n"); - print_pci_resource (func->io_head); - } - if (func->mem_head) { - dbg(": MEM Resources:\n"); - print_pci_resource (func->mem_head); - } - if (func->p_mem_head) { - dbg(": PMEM Resources:\n"); - print_pci_resource (func->p_mem_head); - } -} - -static int phprm_get_used_resources ( - struct controller *ctrl, - struct pci_func *func - ) -{ - return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD); -} - -static int phprm_delete_resource( - struct pci_resource **aprh, - ulong base, - ulong size) -{ - struct pci_resource *res; - struct pci_resource *prevnode; - struct pci_resource *split_node; - ulong tbase; - - shpchp_resource_sort_and_combine(aprh); - - for (res = *aprh; res; res = res->next) { - if (res->base > base) - continue; - - if ((res->base + res->length) < (base + size)) - continue; - - if (res->base < base) { - tbase = base; - - if ((res->length - (tbase - res->base)) < size) - continue; - - split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!split_node) - return -ENOMEM; - - split_node->base = res->base; - split_node->length = tbase - res->base; - res->base = tbase; - res->length -= split_node->length; - - split_node->next = res->next; - res->next = split_node; - } - - if (res->length >= size) { - split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!split_node) - return -ENOMEM; - - split_node->base = res->base + size; - split_node->length = res->length - size; - res->length = size; - - split_node->next = res->next; - res->next = split_node; - } - - if (*aprh == res) { - *aprh = res->next; - } else { - prevnode = *aprh; - while (prevnode->next != res) - prevnode = prevnode->next; - - prevnode->next = res->next; - } - res->next = NULL; - kfree(res); - break; - } - - return 0; -} - - -static int phprm_delete_resources( - struct pci_resource **aprh, - struct pci_resource *this - ) -{ - struct pci_resource *res; - - for (res = this; res; res = res->next) - phprm_delete_resource(aprh, res->base, res->length); - - return 0; -} - - -static int configure_existing_function( - struct controller *ctrl, - struct pci_func *func - ) -{ - int rc; - - /* see how much resources the func has used. */ - rc = phprm_get_used_resources (ctrl, func); - - if (!rc) { - /* subtract the resources used by the func from ctrl resources */ - rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head); - rc |= phprm_delete_resources (&ctrl->io_head, func->io_head); - rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head); - rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head); - if (rc) - warn("aCEF: cannot del used resources\n"); - } else - err("aCEF: cannot get used resources\n"); - - return rc; -} - -static int bind_pci_resources_to_slots ( struct controller *ctrl) -{ - struct pci_func *func, new_func; - int busn = ctrl->slot_bus; - int devn, funn; - u32 vid; - - for (devn = 0; devn < 32; devn++) { - for (funn = 0; funn < 8; funn++) { - /* - if (devn == ctrl->device && funn == ctrl->function) - continue; - */ - /* find out if this entry is for an occupied slot */ - vid = 0xFFFFFFFF; - - pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid); - - if (vid != 0xFFFFFFFF) { - func = shpchp_slot_find(busn, devn, funn); - if (!func) { - memset(&new_func, 0, sizeof(struct pci_func)); - new_func.bus = busn; - new_func.device = devn; - new_func.function = funn; - new_func.is_a_board = 1; - configure_existing_function(ctrl, &new_func); - phprm_dump_func_res(&new_func); - } else { - configure_existing_function(ctrl, func); - phprm_dump_func_res(func); - } - dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - } - } - } - - return 0; -} - -static void phprm_dump_ctrl_res( struct controller *ctlr) -{ - struct controller *ctrl = ctlr; - - if (ctrl->bus_head) { - dbg(": BUS Resources:\n"); - print_pci_resource (ctrl->bus_head); - } - if (ctrl->io_head) { - dbg(": IO Resources:\n"); - print_pci_resource (ctrl->io_head); - } - if (ctrl->mem_head) { - dbg(": MEM Resources:\n"); - print_pci_resource (ctrl->mem_head); - } - if (ctrl->p_mem_head) { - dbg(": PMEM Resources:\n"); - print_pci_resource (ctrl->p_mem_head); - } -} - -/* - * phprm_find_available_resources - * - * Finds available memory, IO, and IRQ resources for programming - * devices which may be added to the system - * this function is for hot plug ADD! - * - * returns 0 if success - */ -int shpchprm_find_available_resources(struct controller *ctrl) -{ - struct pci_func func; - u32 rc; - - memset(&func, 0, sizeof(struct pci_func)); - - func.bus = ctrl->bus; - func.device = ctrl->device; - func.function = ctrl->function; - func.is_a_board = 1; - - /* Get resources for this PCI bridge */ - rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD); - dbg("%s: shpchp_save_used_resources rc = %d\n", __FUNCTION__, rc); - - if (func.mem_head) - func.mem_head->next = ctrl->mem_head; - ctrl->mem_head = func.mem_head; - - if (func.p_mem_head) - func.p_mem_head->next = ctrl->p_mem_head; - ctrl->p_mem_head = func.p_mem_head; - - if (func.io_head) - func.io_head->next = ctrl->io_head; - ctrl->io_head = func.io_head; - - if(func.bus_head) - func.bus_head->next = ctrl->bus_head; - ctrl->bus_head = func.bus_head; - if (ctrl->bus_head) - phprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1); - - dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus); - phprm_dump_ctrl_res(ctrl); - bind_pci_resources_to_slots (ctrl); - - dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus); - phprm_dump_ctrl_res(ctrl); - - - /* If all of the following fail, we don't have any resources for hot plug add */ - rc = 1; - rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head)); - - return (rc); -} - int shpchprm_set_hpp( struct controller *ctrl, struct pci_func *func, diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h deleted file mode 100644 index cddaaa5ee1b3..000000000000 --- a/drivers/pci/hotplug/shpchprm_nonacpi.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001 IBM Corp. - * Copyright (C) 2003-2004 Intel Corporation - * - * All rights reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to , - * - */ - -#ifndef _SHPCHPRM_NONACPI_H_ -#define _SHPCHPRM_NONACPI_H_ - -struct irq_info { - u8 bus, devfn; /* bus, device and function */ - struct { - u8 link; /* IRQ line ID, chipset dependent, 0=not routed */ - u16 bitmap; /* Available IRQs */ - } __attribute__ ((packed)) irq[4]; - u8 slot; /* slot number, 0=onboard */ - u8 rfu; -} __attribute__ ((packed)); - -struct irq_routing_table { - u32 signature; /* PIRQ_SIGNATURE should be here */ - u16 version; /* PIRQ_VERSION */ - u16 size; /* Table size in bytes */ - u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ - u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ - u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */ - u32 miniport_data; /* Crap */ - u8 rfu[11]; - u8 checksum; /* Modulo 256 checksum must give zero */ - struct irq_info slots[0]; -} __attribute__ ((packed)); - -#endif /* _SHPCHPRM_NONACPI_H_ */ From 7e88ed199689f333668b62348051202706b6a74a Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:37 -0700 Subject: [PATCH 0787/1940] [PATCH] shpchp: remove redundant display of PCI device resources Info about resources assigned to PCI devices is already available through sysfs and pci utilities. There's no need for shpchp to create another sysfs file to display the same information. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_sysfs.c | 68 ------------------------------ 1 file changed, 68 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index b0e781dbcffb..ce41719a88f7 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -88,75 +88,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev, *fdev; - struct controller *ctrl; - char * out = buf; - int index; - struct resource *res; - struct pci_func *new_slot; - struct slot *slot; - - pdev = container_of (dev, struct pci_dev, dev); - ctrl = pci_get_drvdata(pdev); - - slot=ctrl->slot; - - while (slot) { - new_slot = shpchp_slot_find(slot->bus, slot->device, 0); - if (!new_slot) - break; - fdev = new_slot->pci_dev; - if (!fdev) - break; - out += sprintf(out, "assigned resources: memory\n"); - for (index=0; index <= PCI_NUM_RESOURCES; index++) { - res = &(fdev->resource[index]); - if (res && (res->flags & IORESOURCE_MEM) && - !(res->flags & IORESOURCE_PREFETCH)) { - out += sprintf(out, - "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); - } - } - out += sprintf(out, "assigned resources: prefetchable memory\n"); - for (index=0; index <= PCI_NUM_RESOURCES; index++) { - res = &(fdev->resource[index]); - if (res && (res->flags & (IORESOURCE_MEM | - IORESOURCE_PREFETCH))) { - out += sprintf(out, - "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); - } - } - out += sprintf(out, "assigned resources: IO\n"); - for (index=0; index <= PCI_NUM_RESOURCES; index++) { - res = &(fdev->resource[index]); - if (res && (res->flags & IORESOURCE_IO)) { - out += sprintf(out, - "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); - } - } - out += sprintf(out, "assigned resources: bus numbers\n"); - if (fdev->subordinate) - out += sprintf(out, "start = %8.8x, length = %8.8x\n", - fdev->subordinate->secondary, - (fdev->subordinate->subordinate - - fdev->subordinate->secondary)); - else - out += sprintf(out, "start = %8.8x, length = %8.8x\n", - fdev->bus->number, 1); - slot=slot->next; - } - - return out - buf; -} -static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL); - void shpchp_create_ctrl_files (struct controller *ctrl) { device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); - device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev); } From 424600f9706b20a8a33ad928d3d0326bd88679bc Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:38 -0700 Subject: [PATCH 0788/1940] [PATCH] shpchp: reduce dependence on ACPI Reduce the SHPC hotplug driver's dependence on ACPI. We don't walk the acpi namespace anymore to build a list of bridges and devices. The remaining interaction with ACPI is to run the _OSHP method to transition control of hotplug hardware from system BIOS to the shpc hotplug driver, and to run the _HPP method to get hotplug device parameters like cache line size, latency timer and SERR/PERR enable from BIOS. Note that one of the side effects of this patch is that shpchp does not enable the hot-added device or its DMA bus mastering automatically now. It expects the device driver to do that. This may break some drivers and we will have to fix them as they are reported. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 12 + drivers/pci/hotplug/shpchp_core.c | 13 +- drivers/pci/hotplug/shpchp_ctrl.c | 1 - drivers/pci/hotplug/shpchp_hpc.c | 2 +- drivers/pci/hotplug/shpchp_pci.c | 52 +- drivers/pci/hotplug/shpchprm.h | 43 -- drivers/pci/hotplug/shpchprm_acpi.c | 794 ++----------------------- drivers/pci/hotplug/shpchprm_legacy.c | 97 +-- drivers/pci/hotplug/shpchprm_nonacpi.c | 108 +--- 9 files changed, 138 insertions(+), 984 deletions(-) delete mode 100644 drivers/pci/hotplug/shpchprm.h diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index deea56c73cf2..1b345ae81ddb 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -122,6 +122,13 @@ struct controller { u16 vendor_id; }; +struct hotplug_params { + u8 cache_line_size; + u8 latency_timer; + u8 enable_serr; + u8 enable_perr; +}; + /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 @@ -192,6 +199,11 @@ extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ct extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot); extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct pci_func* func); +extern void get_hp_hw_control_from_firmware(struct pci_dev *dev); +extern void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp); +extern int shpchprm_get_physical_slot_number(struct controller *ctrl, + u32 *sun, u8 busnum, u8 devnum); /* Global variables */ diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 8f5da504df34..e3c0c17295da 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -39,7 +39,6 @@ #include #include #include "shpchp.h" -#include "shpchprm.h" /* Global variables */ int shpchp_debug; @@ -566,16 +565,12 @@ static int __init shpcd_init(void) if (retval) goto error_hpc_init; - retval = shpchprm_init(PCI); - if (!retval) { - retval = pci_register_driver(&shpc_driver); - dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); - info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - } + retval = pci_register_driver(&shpc_driver); + dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); error_hpc_init: if (retval) { - shpchprm_cleanup(); shpchp_event_stop_thread(); } return retval; @@ -586,8 +581,6 @@ static void __exit shpcd_cleanup(void) dbg("unload_shpchpd()\n"); unload_shpchpd(); - shpchprm_cleanup(); - dbg("pci_unregister_driver\n"); pci_unregister_driver(&shpc_driver); diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index aa507e453e49..23dd61c4c66c 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -40,7 +40,6 @@ #include #include "../pci.h" #include "shpchp.h" -#include "shpchprm.h" static void interrupt_event_handler(struct controller *ctrl); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 8d98410bf1c0..d55a9a7f8d2b 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -1566,8 +1566,8 @@ int shpc_init(struct controller * ctrl, err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); goto abort_free_ctlr; } - /* Execute OSHP method here */ } + get_hp_hw_control_from_firmware(pdev); dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); /* Add this HPC instance into the HPC list */ diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 89e404805777..6209972313f3 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -38,6 +38,55 @@ #include "../pci.h" #include "shpchp.h" +void program_fw_provided_values(struct pci_dev *dev) +{ + u16 pci_cmd, pci_bctl; + struct pci_dev *cdev; + struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */ + + /* Program hpp values for this device */ + if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || + (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) + return; + + get_hp_params_from_firmware(dev, &hpp); + + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + if (hpp.enable_serr) + pci_cmd |= PCI_COMMAND_SERR; + else + pci_cmd &= ~PCI_COMMAND_SERR; + if (hpp.enable_perr) + pci_cmd |= PCI_COMMAND_PARITY; + else + pci_cmd &= ~PCI_COMMAND_PARITY; + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Program bridge control value and child devices */ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, + hpp.latency_timer); + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); + if (hpp.enable_serr) + pci_bctl |= PCI_BRIDGE_CTL_SERR; + else + pci_bctl &= ~PCI_BRIDGE_CTL_SERR; + if (hpp.enable_perr) + pci_bctl |= PCI_BRIDGE_CTL_PARITY; + else + pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); + if (dev->subordinate) { + list_for_each_entry(cdev, &dev->subordinate->devices, + bus_list) + program_fw_provided_values(cdev); + } + } +} + int shpchp_configure_device(struct slot *p_slot) { struct pci_dev *dev; @@ -90,8 +139,7 @@ int shpchp_configure_device(struct slot *p_slot) child->subordinate = pci_do_scan_bus(child); pci_bus_size_bridges(child); } - /* TBD: program firmware provided _HPP values */ - /* program_fw_provided_values(dev); */ + program_fw_provided_values(dev); } pci_bus_assign_resources(parent); diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h deleted file mode 100644 index df474b27d6e8..000000000000 --- a/drivers/pci/hotplug/shpchprm.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001 IBM Corp. - * Copyright (C) 2003-2004 Intel Corporation - * - * All rights reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to , - * - */ - -#ifndef _SHPCHPRM_H_ -#define _SHPCHPRM_H_ - -#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY -#include "shpchprm_legacy.h" -#endif - -int shpchprm_init(enum php_ctlr_type ct); -void shpchprm_cleanup(void); -int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type); -void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type); -int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum); - -#endif /* _SHPCHPRM_H_ */ diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 3d2f9c5269c7..3be518c7d47a 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -38,62 +38,11 @@ #include #include #include "shpchp.h" -#include "shpchprm.h" - -#define PCI_MAX_BUS 0x100 -#define ACPI_STA_DEVICE_PRESENT 0x01 #define METHOD_NAME__SUN "_SUN" #define METHOD_NAME__HPP "_HPP" #define METHOD_NAME_OSHP "OSHP" -#define PHP_RES_BUS 0xA0 -#define PHP_RES_IO 0xA1 -#define PHP_RES_MEM 0xA2 -#define PHP_RES_PMEM 0xA3 - -#define BRIDGE_TYPE_P2P 0x00 -#define BRIDGE_TYPE_HOST 0x01 - -/* this should go to drivers/acpi/include/ */ -struct acpi__hpp { - u8 cache_line_size; - u8 latency_timer; - u8 enable_serr; - u8 enable_perr; -}; - -struct acpi_php_slot { - struct acpi_php_slot *next; - struct acpi_bridge *bridge; - acpi_handle handle; - int seg; - int bus; - int dev; - int fun; - u32 sun; - void *slot_ops; /* _STA, _EJx, etc */ - struct slot *slot; -}; /* per func */ - -struct acpi_bridge { - struct acpi_bridge *parent; - struct acpi_bridge *next; - struct acpi_bridge *child; - acpi_handle handle; - int seg; - int pbus; /* pdev->bus->number */ - int pdevice; /* PCI_SLOT(pdev->devfn) */ - int pfunction; /* PCI_DEVFN(pdev->devfn) */ - int bus; /* pdev->subordinate->number */ - struct acpi__hpp *_hpp; - struct acpi_php_slot *slots; - int scanned; - int type; -}; - -static struct acpi_bridge *acpi_bridges_head; - static u8 * acpi_path_name( acpi_handle handle) { acpi_status status; @@ -109,82 +58,43 @@ static u8 * acpi_path_name( acpi_handle handle) return path_name; } -static void acpi_get__hpp ( struct acpi_bridge *ab); -static void acpi_run_oshp ( struct acpi_bridge *ab); - -static int acpi_add_slot_to_php_slots( - struct acpi_bridge *ab, - int bus_num, - acpi_handle handle, - u32 adr, - u32 sun - ) -{ - struct acpi_php_slot *aps; - static long samesun = -1; - - aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL); - if (!aps) { - err ("acpi_shpchprm: alloc for aps fail\n"); - return -1; - } - memset(aps, 0, sizeof(struct acpi_php_slot)); - - aps->handle = handle; - aps->bus = bus_num; - aps->dev = (adr >> 16) & 0xffff; - aps->fun = adr & 0xffff; - aps->sun = sun; - - aps->next = ab->slots; /* cling to the bridge */ - aps->bridge = ab; - ab->slots = aps; - - ab->scanned += 1; - if (!ab->_hpp) - acpi_get__hpp(ab); - - acpi_run_oshp(ab); - - if (sun != samesun) { - info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg, - aps->bus, aps->dev, aps->fun); - samesun = sun; - } - return 0; -} - -static void acpi_get__hpp ( struct acpi_bridge *ab) +static acpi_status +acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) { acpi_status status; u8 nui[4]; struct acpi_buffer ret_buf = { 0, NULL}; union acpi_object *ext_obj, *package; - u8 *path_name = acpi_path_name(ab->handle); + u8 *path_name = acpi_path_name(handle); int i, len = 0; /* get _hpp */ - status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); + status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); switch (status) { case AE_BUFFER_OVERFLOW: ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); if (!ret_buf.pointer) { - err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name); - return; + err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, + path_name); + return AE_NO_MEMORY; } - status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); + status = acpi_evaluate_object(handle, METHOD_NAME__HPP, + NULL, &ret_buf); if (ACPI_SUCCESS(status)) break; default: if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status); - return; + dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, + path_name, status); + return status; } } ext_obj = (union acpi_object *) ret_buf.pointer; if (ext_obj->type != ACPI_TYPE_PACKAGE) { - err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name); + err ("%s:%s _HPP obj not a package\n", __FUNCTION__, + path_name); + status = AE_ERROR; goto free_and_return; } @@ -197,553 +107,41 @@ static void acpi_get__hpp ( struct acpi_bridge *ab) nui[i] = (u8)ext_obj->integer.value; break; default: - err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name); + err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, + path_name); + status = AE_ERROR; goto free_and_return; } } - ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); - if (!ab->_hpp) { - err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); - goto free_and_return; - } - memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); + hpp->cache_line_size = nui[0]; + hpp->latency_timer = nui[1]; + hpp->enable_serr = nui[2]; + hpp->enable_perr = nui[3]; - ab->_hpp->cache_line_size = nui[0]; - ab->_hpp->latency_timer = nui[1]; - ab->_hpp->enable_serr = nui[2]; - ab->_hpp->enable_perr = nui[3]; - - dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size); - dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer); - dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr); - dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr); + dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); + dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); + dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); + dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); free_and_return: kfree(ret_buf.pointer); + return status; } -static void acpi_run_oshp ( struct acpi_bridge *ab) +static void acpi_run_oshp(acpi_handle handle) { acpi_status status; - u8 *path_name = acpi_path_name(ab->handle); + u8 *path_name = acpi_path_name(handle); /* run OSHP */ - status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL); + status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); if (ACPI_FAILURE(status)) { - err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); - } else - dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status); - return; -} - -/* find acpi_bridge downword from ab. */ -static struct acpi_bridge * -find_acpi_bridge_by_bus( - struct acpi_bridge *ab, - int seg, - int bus /* pdev->subordinate->number */ - ) -{ - struct acpi_bridge *lab = NULL; - - if (!ab) - return NULL; - - if ((ab->bus == bus) && (ab->seg == seg)) - return ab; - - if (ab->child) - lab = find_acpi_bridge_by_bus(ab->child, seg, bus); - - if (!lab) - if (ab->next) - lab = find_acpi_bridge_by_bus(ab->next, seg, bus); - - return lab; -} - -/* - * Build a device tree of ACPI PCI Bridges - */ -static void shpchprm_acpi_register_a_bridge ( - struct acpi_bridge **head, - struct acpi_bridge *pab, /* parent bridge to which child bridge is added */ - struct acpi_bridge *cab /* child bridge to add */ - ) -{ - struct acpi_bridge *lpab; - struct acpi_bridge *lcab; - - lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus); - if (!lpab) { - if (!(pab->type & BRIDGE_TYPE_HOST)) - warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus); - pab->next = *head; - *head = pab; - lpab = pab; - } - - if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab)) - return; - - lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus); - if (lcab) { - if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus)) - err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus); - return; - } else - lcab = cab; - - lcab->parent = lpab; - lcab->next = lpab->child; - lpab->child = lcab; -} - -static acpi_status shpchprm_acpi_build_php_slots_callback( - acpi_handle handle, - u32 Level, - void *context, - void **retval - ) -{ - ulong bus_num; - ulong seg_num; - ulong sun, adr; - ulong padr = 0; - acpi_handle phandle = NULL; - struct acpi_bridge *pab = (struct acpi_bridge *)context; - struct acpi_bridge *lab; - acpi_status status; - u8 *path_name = acpi_path_name(handle); - - /* get _SUN */ - status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun); - switch(status) { - case AE_NOT_FOUND: - return AE_OK; - default: - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status); - return status; - } - } - - /* get _ADR. _ADR must exist if _SUN exists */ - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status); - return status; - } - - dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr); - - status = acpi_get_parent(handle, &phandle); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status); - return (status); - } - - bus_num = pab->bus; - seg_num = pab->seg; - - if (pab->bus == bus_num) { - lab = pab; + err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, + status); } else { - dbg("WARN: pab is not parent\n"); - lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num); - if (!lab) { - dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun); - lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL); - if (!lab) { - err("acpi_shpchprm: alloc for ab fail\n"); - return AE_NO_MEMORY; - } - memset(lab, 0, sizeof(struct acpi_bridge)); - - lab->handle = phandle; - lab->pbus = pab->bus; - lab->pdevice = (int)(padr >> 16) & 0xffff; - lab->pfunction = (int)(padr & 0xffff); - lab->bus = (int)bus_num; - lab->scanned = 0; - lab->type = BRIDGE_TYPE_P2P; - - shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab); - } else - dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun); + dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); } - - acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun); - return (status); -} - -static int shpchprm_acpi_build_php_slots( - struct acpi_bridge *ab, - u32 depth - ) -{ - acpi_status status; - u8 *path_name = acpi_path_name(ab->handle); - - /* Walk down this pci bridge to get _SUNs if any behind P2P */ - status = acpi_walk_namespace ( ACPI_TYPE_DEVICE, - ab->handle, - depth, - shpchprm_acpi_build_php_slots_callback, - ab, - NULL ); - if (ACPI_FAILURE(status)) { - dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status); - return -1; - } - - return 0; -} - -static void build_a_bridge( - struct acpi_bridge *pab, - struct acpi_bridge *ab - ) -{ - u8 *path_name = acpi_path_name(ab->handle); - - shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab); - - switch (ab->type) { - case BRIDGE_TYPE_HOST: - dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n", - ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name); - break; - case BRIDGE_TYPE_P2P: - dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n", - ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name); - break; - }; - - /* build any immediate PHP slots under this pci bridge */ - shpchprm_acpi_build_php_slots(ab, 1); -} - -static struct acpi_bridge * add_p2p_bridge( - acpi_handle handle, - struct acpi_bridge *pab, /* parent */ - ulong adr - ) -{ - struct acpi_bridge *ab; - struct pci_dev *pdev; - ulong devnum, funcnum; - u8 *path_name = acpi_path_name(handle); - - ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL); - if (!ab) { - err("acpi_shpchprm: alloc for ab fail\n"); - return NULL; - } - memset(ab, 0, sizeof(struct acpi_bridge)); - - devnum = (adr >> 16) & 0xffff; - funcnum = adr & 0xffff; - - pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum)); - if (!pdev || !pdev->subordinate) { - err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name); - kfree(ab); - return NULL; - } - - ab->handle = handle; - ab->seg = pab->seg; - ab->pbus = pab->bus; /* or pdev->bus->number */ - ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */ - ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */ - ab->bus = pdev->subordinate->number; - ab->scanned = 0; - ab->type = BRIDGE_TYPE_P2P; - - dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n", - pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pab->bus, (u32)devnum, (u32)funcnum, path_name); - - build_a_bridge(pab, ab); - - return ab; -} - -static acpi_status scan_p2p_bridge( - acpi_handle handle, - u32 Level, - void *context, - void **retval - ) -{ - struct acpi_bridge *pab = (struct acpi_bridge *)context; - struct acpi_bridge *ab; - acpi_status status; - ulong adr = 0; - u8 *path_name = acpi_path_name(handle); - ulong devnum, funcnum; - struct pci_dev *pdev; - - /* get device, function */ - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr); - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) - err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status); - return AE_OK; - } - - devnum = (adr >> 16) & 0xffff; - funcnum = adr & 0xffff; - - pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum)); - if (!pdev) - return AE_OK; - if (!pdev->subordinate) - return AE_OK; - - ab = add_p2p_bridge(handle, pab, adr); - if (ab) { - status = acpi_walk_namespace ( ACPI_TYPE_DEVICE, - handle, - (u32)1, - scan_p2p_bridge, - ab, - NULL); - if (ACPI_FAILURE(status)) - dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status); - } - - return AE_OK; -} - -static struct acpi_bridge * add_host_bridge( - acpi_handle handle, - ulong segnum, - ulong busnum - ) -{ - ulong adr = 0; - acpi_status status; - struct acpi_bridge *ab; - u8 *path_name = acpi_path_name(handle); - - /* get device, function: host br adr is always 0000 though. */ - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status); - return NULL; - } - dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum, - (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name); - - ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL); - if (!ab) { - err("acpi_shpchprm: alloc for ab fail\n"); - return NULL; - } - memset(ab, 0, sizeof(struct acpi_bridge)); - - ab->handle = handle; - ab->seg = (int)segnum; - ab->bus = ab->pbus = (int)busnum; - ab->pdevice = (int)(adr >> 16) & 0xffff; - ab->pfunction = (int)(adr & 0xffff); - ab->scanned = 0; - ab->type = BRIDGE_TYPE_HOST; - - build_a_bridge(ab, ab); - - return ab; -} - -static acpi_status acpi_scan_from_root_pci_callback ( - acpi_handle handle, - u32 Level, - void *context, - void **retval - ) -{ - ulong segnum = 0; - ulong busnum = 0; - acpi_status status; - struct acpi_bridge *ab; - u8 *path_name = acpi_path_name(handle); - - /* get bus number of this pci root bridge */ - status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum); - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) { - err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status); - return status; - } - segnum = 0; - } - - /* get bus number of this pci root bridge */ - status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status); - return (status); - } - - ab = add_host_bridge(handle, segnum, busnum); - if (ab) { - status = acpi_walk_namespace ( ACPI_TYPE_DEVICE, - handle, - 1, - scan_p2p_bridge, - ab, - NULL); - if (ACPI_FAILURE(status)) - dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status); - } - - return AE_OK; -} - -static int shpchprm_acpi_scan_pci (void) -{ - acpi_status status; - - /* - * TBD: traverse LDM device tree with the help of - * unified ACPI augmented for php device population. - */ - status = acpi_get_devices ( PCI_ROOT_HID_STRING, - acpi_scan_from_root_pci_callback, - NULL, - NULL ); - if (ACPI_FAILURE(status)) { - err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status); - return -1; - } - - return 0; -} - -int shpchprm_init(enum php_ctlr_type ctlr_type) -{ - int rc; - - if (ctlr_type != PCI) - return -ENODEV; - - dbg("shpchprm ACPI init \n"); - acpi_bridges_head = NULL; - - /* construct PCI bus:device tree of acpi_handles */ - rc = shpchprm_acpi_scan_pci(); - if (rc) - return rc; - - dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success"); - return rc; -} - -static void free_a_slot(struct acpi_php_slot *aps) -{ - dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun); - - kfree(aps); -} - -static void free_a_bridge( struct acpi_bridge *ab) -{ - struct acpi_php_slot *aps, *next; - - switch (ab->type) { - case BRIDGE_TYPE_HOST: - dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n", - ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction); - break; - case BRIDGE_TYPE_P2P: - dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n", - ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction); - break; - }; - - /* free slots first */ - for (aps = ab->slots; aps; aps = next) { - next = aps->next; - free_a_slot(aps); - } - - kfree(ab); -} - -static void shpchprm_free_bridges ( struct acpi_bridge *ab) -{ - if (!ab) - return; - - if (ab->child) - shpchprm_free_bridges (ab->child); - - if (ab->next) - shpchprm_free_bridges (ab->next); - - free_a_bridge(ab); -} - -void shpchprm_cleanup(void) -{ - shpchprm_free_bridges (acpi_bridges_head); -} - -static int get_number_of_slots ( - struct acpi_bridge *ab, - int selfonly - ) -{ - struct acpi_php_slot *aps; - int prev_slot = -1; - int slot_num = 0; - - for ( aps = ab->slots; aps; aps = aps->next) - if (aps->dev != prev_slot) { - prev_slot = aps->dev; - slot_num++; - } - - if (ab->child) - slot_num += get_number_of_slots (ab->child, 0); - - if (selfonly) - return slot_num; - - if (ab->next) - slot_num += get_number_of_slots (ab->next, 0); - - return slot_num; -} - -static struct acpi_php_slot * get_acpi_slot ( - struct acpi_bridge *ab, - u32 sun - ) -{ - struct acpi_php_slot *aps = NULL; - - for ( aps = ab->slots; aps; aps = aps->next) - if (aps->sun == sun) - return aps; - - if (!aps && ab->child) { - aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun); - if (aps) - return aps; - } - - if (!aps && ab->next) { - aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun); - if (aps) - return aps; - } - - return aps; - } int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) @@ -755,108 +153,40 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -int shpchprm_set_hpp( - struct controller *ctrl, - struct pci_func *func, - u8 card_type - ) +void get_hp_hw_control_from_firmware(struct pci_dev *dev) { - struct acpi_bridge *ab; - struct pci_bus lpci_bus, *pci_bus; - int rc = 0; - unsigned int devfn; - u8 cls= 0x08; /* default cache line size */ - u8 lt = 0x40; /* default latency timer */ - u8 ep = 0; - u8 es = 0; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); - - if (ab) { - if (ab->_hpp) { - lt = (u8)ab->_hpp->latency_timer; - cls = (u8)ab->_hpp->cache_line_size; - ep = (u8)ab->_hpp->enable_perr; - es = (u8)ab->_hpp->enable_serr; - } else - dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function); - } else - dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function); - - - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - /* set subordinate Latency Timer */ - rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt); - } - - /* set base Latency Timer */ - rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt); - dbg(" set latency timer =0x%02x: %x\n", lt, rc); - - rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls); - dbg(" set cache_line_size=0x%02x: %x\n", cls, rc); - - return rc; + /* + * OSHP is an optional ACPI firmware control method. If present, + * we need to run it to inform BIOS that we will control SHPC + * hardware from now on. + */ + acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev)); + if (!handle) + return; + acpi_run_oshp(handle); } -void shpchprm_enable_card( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) { - u16 command, cmd, bcommand, bcmd; - struct pci_bus lpci_bus, *pci_bus; - struct acpi_bridge *ab; - unsigned int devfn; - int rc; + acpi_status status = AE_NOT_FOUND; + struct pci_dev *pdev = dev; - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command); - - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand); - } - - cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE - | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; - - ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); - if (ab) { - if (ab->_hpp) { - if (ab->_hpp->enable_perr) { - command |= PCI_COMMAND_PARITY; - bcommand |= PCI_BRIDGE_CTL_PARITY; - } else { - command &= ~PCI_COMMAND_PARITY; - bcommand &= ~PCI_BRIDGE_CTL_PARITY; - } - if (ab->_hpp->enable_serr) { - command |= PCI_COMMAND_SERR; - bcommand |= PCI_BRIDGE_CTL_SERR; - } else { - command &= ~PCI_COMMAND_SERR; - bcommand &= ~PCI_BRIDGE_CTL_SERR; - } - } else - dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function); - } else - dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function); - - if (command != cmd) { - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); - } - if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) { - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand); + /* + * _HPP settings apply to all child buses, until another _HPP is + * encountered. If we don't find an _HPP for the input pci dev, + * look for it in the parent device scope since that would apply to + * this pci dev. If we don't find any _HPP, use hardcoded defaults + */ + while (pdev && (ACPI_FAILURE(status))) { + acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); + if (!handle) + break; + status = acpi_run_hpp(handle, hpp); + if (!(pdev->bus->parent)) + break; + /* Check if a parent object supports _HPP */ + pdev = pdev->bus->parent->self; } } diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index 6c27debe9522..cfc6092e2afd 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -37,10 +37,6 @@ #include "shpchp.h" #include "shpchprm.h" -void shpchprm_cleanup(void) -{ -} - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { int offset = devnum - ctrl->slot_device_offset; @@ -49,97 +45,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -int shpchprm_set_hpp( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) { - u32 rc; - u8 temp_byte; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - temp_byte = 0x40; /* hard coded value for LT */ - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - /* set subordinate Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte); - if (rc) { - dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, - func->device, func->function); - return rc; - } - } - - /* set base Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte); - if (rc) { - dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - return rc; - } - - /* set Cache Line size */ - temp_byte = 0x08; /* hard coded value for CLS */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte); - if (rc) { - dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - } - - /* set enable_perr */ - /* set enable_serr */ - - return rc; + return; } -void shpchprm_enable_card( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_hw_control_from_firmware(struct pci_dev *dev) { - u16 command, bcommand; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - int rc; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command); - command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR - | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE - | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); - - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand); - bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR - | PCI_BRIDGE_CTL_NO_ISA; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand); - } + return; } -static int legacy_shpchprm_init_pci(void) -{ - return 0; -} - -int shpchprm_init(enum php_ctlr_type ctrl_type) -{ - int retval; - - switch (ctrl_type) { - case PCI: - retval = legacy_shpchprm_init_pci(); - break; - default: - retval = -ENODEV; - break; - } - - return retval; -} diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c index 9d4ccae5f78e..f36c188c23eb 100644 --- a/drivers/pci/hotplug/shpchprm_nonacpi.c +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c @@ -37,11 +37,6 @@ #include "shpchp.h" #include "shpchprm.h" -void shpchprm_cleanup(void) -{ - return; -} - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { int offset = devnum - ctrl->slot_device_offset; @@ -51,106 +46,13 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -int shpchprm_set_hpp( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) { - u32 rc; - u8 temp_byte; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - temp_byte = 0x40; /* hard coded value for LT */ - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - /* set subordinate Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte); - - if (rc) { - dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, - func->device, func->function); - return rc; - } - } - - /* set base Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte); - - if (rc) { - dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - return rc; - } - - /* set Cache Line size */ - temp_byte = 0x08; /* hard coded value for CLS */ - - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte); - - if (rc) { - dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - } - - /* set enable_perr */ - /* set enable_serr */ - - return rc; + return; } -void shpchprm_enable_card( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_hw_control_from_firmware(struct pci_dev *dev) { - u16 command, bcommand; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - int rc; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command); - - command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR - | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE - | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); - - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand); - - bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR - | PCI_BRIDGE_CTL_NO_ISA; - - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand); - } -} - -static int legacy_shpchprm_init_pci(void) -{ - return 0; -} - -int shpchprm_init(enum php_ctlr_type ctrl_type) -{ - int retval; - - switch (ctrl_type) { - case PCI: - retval = legacy_shpchprm_init_pci(); - break; - default: - retval = -ENODEV; - break; - } - - return retval; + return; } From 1410dc1cef1e2f5e90c1fcb97041f42e0eee35b4 Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:39 -0700 Subject: [PATCH 0789/1940] [PATCH] shpchp: detect SHPC capability before doing a lot of work The shpc driver registers its probe function for all pci-pci bridges in the system. Not all of them will be shpc capable, so look for this capability early in the probe function and return if there's no work to do on this bridge. The old shpc driver did some initialization work on all bridges before detecting that shpc is not supported and unwinds the work it's already done in that case. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index e3c0c17295da..3132d60a79f5 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -351,6 +351,17 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp return 0; } +static int is_shpc_capable(struct pci_dev *dev) +{ + if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == + PCI_DEVICE_ID_AMD_GOLAM_7450)) + return 1; + if (pci_find_capability(dev, PCI_CAP_ID_SHPC)) + return 1; + + return 0; +} + static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; @@ -359,6 +370,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int first_device_num; /* first PCI device number supported by this SHPC */ int num_ctlr_slots; /* number of slots supported by this SHPC */ + if (!is_shpc_capable(pdev)) + return -ENODEV; + ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); if (!ctrl) { err("%s : out of memory\n", __FUNCTION__); From 70b6091946ab486c4dab8abeb4a3fc2bf7d3e7fe Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:40 -0700 Subject: [PATCH 0790/1940] [PATCH] shpchp: dont save PCI config for hotplug slots/devices This patch eliminates saving the PCI config header for devices in hotplug capable slots. We now use the PCI core to get the specific parts of the config header as required. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 1 - drivers/pci/hotplug/shpchp_core.c | 7 - drivers/pci/hotplug/shpchp_ctrl.c | 48 +++-- drivers/pci/hotplug/shpchp_pci.c | 314 ------------------------------ 4 files changed, 32 insertions(+), 338 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 1b345ae81ddb..5e99260987e8 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -63,7 +63,6 @@ struct pci_func { u8 switch_save; u8 presence_save; u8 pwr_save; - u32 config_space[0x20]; struct pci_dev* pci_dev; }; diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 3132d60a79f5..5d4fc28969d0 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -424,13 +424,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) first_device_num = ctrl->slot_device_offset; num_ctlr_slots = ctrl->num_slots; - /* Store PCI Config Space for all devices on this bus */ - rc = shpchp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num); - if (rc) { - err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc); - goto err_out_free_ctrl_bus; - } - ctrl->add_support = 1; /* Setup the slot information structures */ diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 23dd61c4c66c..c55103f3cebd 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -328,21 +328,20 @@ static int slot_remove(struct pci_func * old_slot) /** * bridge_slot_remove - Removes a node from the linked list of slots. * @bridge: bridge to remove + * @secondaryBus: secondary PCI bus number for bridge being removed + * @subordinateBus: subordinate PCI bus number for bridge being removed * * Returns 0 if successful, !0 otherwise. */ -static int bridge_slot_remove(struct pci_func *bridge) +static int bridge_slot_remove(struct pci_func *bridge, u8 secondaryBus, + u8 subordinateBus) { - u8 subordinateBus, secondaryBus; u8 tempBus; struct pci_func *next; if (bridge == NULL) return(1); - secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF; - subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF; - for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { next = shpchp_slot_list[tempBus]; @@ -410,16 +409,23 @@ struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index) return(NULL); } -static int is_bridge(struct pci_func * func) +static int is_bridge(struct pci_func *func, struct controller *ctrl) { - /* Check the header type */ - if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01) + u8 hdr_type; + struct pci_bus *bus = ctrl->pci_dev->subordinate; + + /* + * Note: device may have just been hot-added and not yet scanned + * by the pci core, so its pci_dev structure may not exist yet + */ + pci_bus_read_config_byte(bus, PCI_DEVFN(func->device, func->function), + PCI_HEADER_TYPE, &hdr_type); + if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) return 1; else return 0; } - /* The following routines constitute the bulk of the hotplug controller logic */ @@ -709,8 +715,6 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) goto err_exit; } - shpchp_save_slot_config(ctrl, func); - func->status = 0; func->switch_save = 0x10; func->is_a_board = 0x01; @@ -769,10 +773,18 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) u8 hp_slot; u32 rc; struct slot *p_slot; + u8 secondary = 0, subordinate = 0; + int remove_bridge; if (func == NULL) return(1); + if ((remove_bridge = is_bridge(func, ctrl))) { + /* Stash away bus information before we destroy it */ + secondary = func->pci_dev->subordinate->secondary; + subordinate = func->pci_dev->subordinate->subordinate; + } + if (shpchp_unconfigure_device(func)) return(1); @@ -825,10 +837,11 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) if (ctrl->add_support) { while (func) { - if (is_bridge(func)) { + if (remove_bridge) { dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function); - bridge_slot_remove(func); + bridge_slot_remove(func, secondary, + subordinate); } else dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function); @@ -1185,9 +1198,12 @@ int shpchp_enable_slot (struct slot *p_slot) rc = board_added(func, p_slot->ctrl); if (rc) { - if (is_bridge(func)) - bridge_slot_remove(func); - else + if (is_bridge(func, p_slot->ctrl)) { + u8 secondary = func->pci_dev->subordinate->secondary; + u8 subordinate = + func->pci_dev->subordinate->subordinate; + bridge_slot_remove(func, secondary, subordinate); + } else slot_remove(func); /* Setup slot structure with entry for empty slot */ diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 6209972313f3..f51a97d7611f 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -166,317 +166,3 @@ int shpchp_unconfigure_device(struct pci_func* func) return rc; } -/* More PCI configuration routines; this time centered around hotplug controller */ - - -/* - * shpchp_save_config - * - * Reads configuration for all slots in a PCI bus and saves info. - * - * Note: For non-hot plug busses, the slot # saved is the device # - * - * returns 0 if success - */ -int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num) -{ - int rc; - u8 class_code; - u8 header_type; - u32 ID; - u8 secondary_bus; - struct pci_func *new_slot; - int sub_bus; - int FirstSupported; - int LastSupported; - int max_functions; - int function; - u8 DevError; - int device = 0; - int cloop = 0; - int stop_it; - int index; - int is_hot_plug = num_ctlr_slots || first_device_num; - struct pci_bus lpci_bus, *pci_bus; - - dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__, - num_ctlr_slots, first_device_num); - - memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - - dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__, - num_ctlr_slots, first_device_num); - - /* Decide which slots are supported */ - if (is_hot_plug) { - /********************************* - * is_hot_plug is the slot mask - *********************************/ - FirstSupported = first_device_num; - LastSupported = FirstSupported + num_ctlr_slots - 1; - } else { - FirstSupported = 0; - LastSupported = 0x1F; - } - - dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported, - LastSupported); - - /* Save PCI configuration space for all devices in supported slots */ - pci_bus->number = busnumber; - for (device = FirstSupported; device <= LastSupported; device++) { - ID = 0xFFFFFFFF; - rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), - PCI_VENDOR_ID, &ID); - - if (ID != 0xFFFFFFFF) { /* device in slot */ - rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), - 0x0B, &class_code); - if (rc) - return rc; - - rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), - PCI_HEADER_TYPE, &header_type); - if (rc) - return rc; - - dbg("class_code = %x, header_type = %x\n", class_code, header_type); - - /* If multi-function device, set max_functions to 8 */ - if (header_type & 0x80) - max_functions = 8; - else - max_functions = 1; - - function = 0; - - do { - DevError = 0; - - if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */ - /* Recurse the subordinate bus - * get the subordinate bus number - */ - rc = pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(device, function), - PCI_SECONDARY_BUS, &secondary_bus); - if (rc) { - return rc; - } else { - sub_bus = (int) secondary_bus; - - /* Save secondary bus cfg spc with this recursive call. */ - rc = shpchp_save_config(ctrl, sub_bus, 0, 0); - if (rc) - return rc; - } - } - - index = 0; - new_slot = shpchp_slot_find(busnumber, device, index++); - - dbg("new_slot = %p\n", new_slot); - - while (new_slot && (new_slot->function != (u8) function)) { - new_slot = shpchp_slot_find(busnumber, device, index++); - dbg("new_slot = %p\n", new_slot); - } - if (!new_slot) { - /* Setup slot structure. */ - new_slot = shpchp_slot_create(busnumber); - dbg("new_slot = %p\n", new_slot); - - if (new_slot == NULL) - return(1); - } - - new_slot->bus = (u8) busnumber; - new_slot->device = (u8) device; - new_slot->function = (u8) function; - new_slot->is_a_board = 1; - new_slot->switch_save = 0x10; - new_slot->pwr_save = 1; - /* In case of unsupported board */ - new_slot->status = DevError; - new_slot->pci_dev = pci_find_slot(new_slot->bus, - (new_slot->device << 3) | new_slot->function); - dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev); - - for (cloop = 0; cloop < 0x20; cloop++) { - rc = pci_bus_read_config_dword(pci_bus, - PCI_DEVFN(device, function), - cloop << 2, - (u32 *) &(new_slot->config_space [cloop])); - /* dbg("new_slot->config_space[%x] = %x\n", - cloop, new_slot->config_space[cloop]); */ - if (rc) - return rc; - } - - function++; - - stop_it = 0; - - /* this loop skips to the next present function - * reading in Class Code and Header type. - */ - - while ((function < max_functions)&&(!stop_it)) { - rc = pci_bus_read_config_dword(pci_bus, - PCI_DEVFN(device, function), - PCI_VENDOR_ID, &ID); - - if (ID == 0xFFFFFFFF) { /* nothing there. */ - function++; - dbg("Nothing there\n"); - } else { /* Something there */ - rc = pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(device, function), - 0x0B, &class_code); - if (rc) - return rc; - - rc = pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(device, function), - PCI_HEADER_TYPE, &header_type); - if (rc) - return rc; - - dbg("class_code = %x, header_type = %x\n", - class_code, header_type); - stop_it++; - } - } - - } while (function < max_functions); - /* End of IF (device in slot?) */ - } else if (is_hot_plug) { - /* Setup slot structure with entry for empty slot */ - new_slot = shpchp_slot_create(busnumber); - - if (new_slot == NULL) { - return(1); - } - dbg("new_slot = %p\n", new_slot); - - new_slot->bus = (u8) busnumber; - new_slot->device = (u8) device; - new_slot->function = 0; - new_slot->is_a_board = 0; - new_slot->presence_save = 0; - new_slot->switch_save = 0; - } - } /* End of FOR loop */ - - return(0); -} - - -/* - * shpchp_save_slot_config - * - * Saves configuration info for all PCI devices in a given slot - * including subordinate busses. - * - * returns 0 if success - */ -int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot) -{ - int rc; - u8 class_code; - u8 header_type; - u32 ID; - u8 secondary_bus; - int sub_bus; - int max_functions; - int function; - int cloop = 0; - int stop_it; - struct pci_bus lpci_bus, *pci_bus; - memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = new_slot->bus; - - ID = 0xFFFFFFFF; - - pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0), - PCI_VENDOR_ID, &ID); - - if (ID != 0xFFFFFFFF) { /* device in slot */ - pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), - 0x0B, &class_code); - - pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), - PCI_HEADER_TYPE, &header_type); - - if (header_type & 0x80) /* Multi-function device */ - max_functions = 8; - else - max_functions = 1; - - function = 0; - - do { - if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */ - /* Recurse the subordinate bus */ - pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(new_slot->device, function), - PCI_SECONDARY_BUS, &secondary_bus); - - sub_bus = (int) secondary_bus; - - /* Save the config headers for the secondary bus. */ - rc = shpchp_save_config(ctrl, sub_bus, 0, 0); - - if (rc) - return rc; - - } /* End of IF */ - - new_slot->status = 0; - - for (cloop = 0; cloop < 0x20; cloop++) { - pci_bus_read_config_dword(pci_bus, - PCI_DEVFN(new_slot->device, function), - cloop << 2, - (u32 *) &(new_slot->config_space [cloop])); - } - - function++; - - stop_it = 0; - - /* this loop skips to the next present function - * reading in the Class Code and the Header type. - */ - - while ((function < max_functions) && (!stop_it)) { - pci_bus_read_config_dword(pci_bus, - PCI_DEVFN(new_slot->device, function), - PCI_VENDOR_ID, &ID); - - if (ID == 0xFFFFFFFF) { /* nothing there. */ - function++; - } else { /* Something there */ - pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(new_slot->device, function), - 0x0B, &class_code); - - pci_bus_read_config_byte(pci_bus, - PCI_DEVFN(new_slot->device, function), - PCI_HEADER_TYPE, &header_type); - - stop_it++; - } - } - - } while (function < max_functions); - } /* End of IF (device in slot?) */ - else { - return 2; - } - - return 0; -} - From 2178bfad9ccb0cbeb79599dd1dc349dd4567aa49 Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:41 -0700 Subject: [PATCH 0791/1940] [PATCH] shpchp: remove redundant data structures State information is currently stored in per-slot as well as per-pci-function data structures in shpchp. There's a lot of overlap in the information kept, and some of it is never used. This patch consolidates the state information to per-slot and eliminates unused data structures. The biggest change is to eliminate the pci_func structure and the code around managing its lists. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 35 +-- drivers/pci/hotplug/shpchp_core.c | 20 -- drivers/pci/hotplug/shpchp_ctrl.c | 405 +++--------------------------- drivers/pci/hotplug/shpchp_pci.c | 27 +- 4 files changed, 63 insertions(+), 424 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 5e99260987e8..052c11f14a79 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -52,34 +52,18 @@ extern int shpchp_debug; #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) -struct pci_func { - struct pci_func *next; - u8 bus; - u8 device; - u8 function; - u8 is_a_board; - u16 status; - u8 configured; - u8 switch_save; - u8 presence_save; - u8 pwr_save; - struct pci_dev* pci_dev; -}; - #define SLOT_MAGIC 0x67267321 struct slot { u32 magic; struct slot *next; u8 bus; u8 device; + u16 status; u32 number; u8 is_a_board; - u8 configured; u8 state; - u8 switch_save; u8 presence_save; - u32 capabilities; - u16 reserved2; + u8 pwr_save; struct timer_list task_event; u8 hp_slot; struct controller *ctrl; @@ -106,19 +90,14 @@ struct controller { struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ u8 next_event; - u8 seg; u8 bus; u8 device; u8 function; - u8 rev; u8 slot_device_offset; u8 add_support; enum pci_bus_speed speed; u32 first_slot; /* First physical slot number */ u8 slot_bus; /* Bus where the slots handled by this controller sit */ - u8 push_flag; - u16 ctlrcap; - u16 vendor_id; }; struct hotplug_params { @@ -169,13 +148,9 @@ struct hotplug_params { * error Messages */ #define msg_initialization_err "Initialization failure, error=%d\n" -#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n" -#define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n" -#define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n" #define msg_button_on "PCI slot #%d - powering on due to button press.\n" #define msg_button_off "PCI slot #%d - powering off due to button press.\n" #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" -#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" /* sysfs functions for the hotplug controller info */ extern void shpchp_create_ctrl_files (struct controller *ctrl); @@ -183,8 +158,6 @@ extern void shpchp_create_ctrl_files (struct controller *ctrl); /* controller functions */ extern int shpchp_event_start_thread(void); extern void shpchp_event_stop_thread(void); -extern struct pci_func *shpchp_slot_create(unsigned char busnumber); -extern struct pci_func *shpchp_slot_find(unsigned char bus, unsigned char device, unsigned char index); extern int shpchp_enable_slot(struct slot *slot); extern int shpchp_disable_slot(struct slot *slot); @@ -195,9 +168,8 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); /* pci functions */ extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); -extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot); extern int shpchp_configure_device(struct slot *p_slot); -extern int shpchp_unconfigure_device(struct pci_func* func); +extern int shpchp_unconfigure_device(struct slot *p_slot); extern void get_hp_hw_control_from_firmware(struct pci_dev *dev); extern void get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp); @@ -207,7 +179,6 @@ extern int shpchprm_get_physical_slot_number(struct controller *ctrl, /* Global variables */ extern struct controller *shpchp_ctrl_list; -extern struct pci_func *shpchp_slot_list[256]; struct ctrl_reg { volatile u32 base_offset; diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 5d4fc28969d0..b54edccbf2cc 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -45,7 +45,6 @@ int shpchp_debug; int shpchp_poll_mode; int shpchp_poll_time; struct controller *shpchp_ctrl_list; /* = NULL */ -struct pci_func *shpchp_slot_list[256]; #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -475,7 +474,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static int shpc_start_thread(void) { - int loop; int retval = 0; dbg("Initialize + Start the notification/polling mechanism \n"); @@ -486,20 +484,11 @@ static int shpc_start_thread(void) return retval; } - dbg("Initialize slot lists\n"); - /* One slot list for each bus in the system */ - for (loop = 0; loop < 256; loop++) { - shpchp_slot_list[loop] = NULL; - } - return retval; } static void __exit unload_shpchpd(void) { - struct pci_func *next; - struct pci_func *TempSlot; - int loop; struct controller *ctrl; struct controller *tctrl; @@ -519,15 +508,6 @@ static void __exit unload_shpchpd(void) kfree(tctrl); } - for (loop = 0; loop < 256; loop++) { - next = shpchp_slot_list[loop]; - while (next != NULL) { - TempSlot = next; - next = next->next; - kfree(TempSlot); - } - } - /* Stop the notification mechanism */ shpchp_event_stop_thread(); diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index c55103f3cebd..b6fde3565e55 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -54,19 +54,16 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) struct slot *p_slot; u8 rc = 0; u8 getstatus; - struct pci_func *func; struct event_info *taskInfo; /* Attention Button Change */ dbg("shpchp: Attention button interrupt received.\n"); - func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0); - /* This is the structure that tells the worker thread what to do */ taskInfo = &(ctrl->event_queue[ctrl->next_event]); p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); ctrl->next_event = (ctrl->next_event + 1) % 10; @@ -111,14 +108,11 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) struct slot *p_slot; u8 rc = 0; u8 getstatus; - struct pci_func *func; struct event_info *taskInfo; /* Switch Change */ dbg("shpchp: Switch interrupt received.\n"); - func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0); - /* This is the structure that tells the worker thread * what to do */ @@ -128,19 +122,18 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) rc++; p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); dbg("%s: Card present %x Power status %x\n", __FUNCTION__, - func->presence_save, func->pwr_save); + p_slot->presence_save, p_slot->pwr_save); if (getstatus) { /* * Switch opened */ info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); - func->switch_save = 0; taskInfo->event_type = INT_SWITCH_OPEN; - if (func->pwr_save && func->presence_save) { + if (p_slot->pwr_save && p_slot->presence_save) { taskInfo->event_type = INT_POWER_FAULT; err("Surprise Removal of card\n"); } @@ -149,7 +142,6 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) * Switch closed */ info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); - func->switch_save = 0x10; taskInfo->event_type = INT_SWITCH_CLOSE; } @@ -165,14 +157,11 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) struct slot *p_slot; u8 rc = 0; /*u8 temp_byte;*/ - struct pci_func *func; struct event_info *taskInfo; /* Presence Change */ dbg("shpchp: Presence/Notify input change.\n"); - func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0); - /* This is the structure that tells the worker thread * what to do */ @@ -186,8 +175,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) /* * Save the presence state */ - p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); - if (func->presence_save) { + p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); + if (p_slot->presence_save) { /* * Card Present */ @@ -212,14 +201,11 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; - struct pci_func *func; struct event_info *taskInfo; /* Power fault */ dbg("shpchp: Power fault interrupt received.\n"); - func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0); - /* This is the structure that tells the worker thread * what to do */ @@ -235,7 +221,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) * Power fault Cleared */ info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); - func->status = 0x00; + p_slot->status = 0x00; taskInfo->event_type = INT_POWER_FAULT_CLEAR; } else { /* @@ -244,7 +230,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_POWER_FAULT; /* set power fault status for this board */ - func->status = 0xFF; + p_slot->status = 0xFF; info("power fault bit %x set\n", hp_slot); } if (rc) @@ -253,179 +239,6 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) return rc; } -/** - * shpchp_slot_create - Creates a node and adds it to the proper bus. - * @busnumber - bus where new node is to be located - * - * Returns pointer to the new node or NULL if unsuccessful - */ -struct pci_func *shpchp_slot_create(u8 busnumber) -{ - struct pci_func *new_slot; - struct pci_func *next; - - new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL); - - if (new_slot == NULL) { - return(new_slot); - } - - memset(new_slot, 0, sizeof(struct pci_func)); - - new_slot->next = NULL; - new_slot->configured = 1; - - if (shpchp_slot_list[busnumber] == NULL) { - shpchp_slot_list[busnumber] = new_slot; - } else { - next = shpchp_slot_list[busnumber]; - while (next->next != NULL) - next = next->next; - next->next = new_slot; - } - return(new_slot); -} - - -/* - * slot_remove - Removes a node from the linked list of slots. - * @old_slot: slot to remove - * - * Returns 0 if successful, !0 otherwise. - */ -static int slot_remove(struct pci_func * old_slot) -{ - struct pci_func *next; - - if (old_slot == NULL) - return(1); - - next = shpchp_slot_list[old_slot->bus]; - - if (next == NULL) { - return(1); - } - - if (next == old_slot) { - shpchp_slot_list[old_slot->bus] = old_slot->next; - kfree(old_slot); - return(0); - } - - while ((next->next != old_slot) && (next->next != NULL)) { - next = next->next; - } - - if (next->next == old_slot) { - next->next = old_slot->next; - kfree(old_slot); - return(0); - } else - return(2); -} - - -/** - * bridge_slot_remove - Removes a node from the linked list of slots. - * @bridge: bridge to remove - * @secondaryBus: secondary PCI bus number for bridge being removed - * @subordinateBus: subordinate PCI bus number for bridge being removed - * - * Returns 0 if successful, !0 otherwise. - */ -static int bridge_slot_remove(struct pci_func *bridge, u8 secondaryBus, - u8 subordinateBus) -{ - u8 tempBus; - struct pci_func *next; - - if (bridge == NULL) - return(1); - - for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { - next = shpchp_slot_list[tempBus]; - - while (!slot_remove(next)) { - next = shpchp_slot_list[tempBus]; - } - } - - next = shpchp_slot_list[bridge->bus]; - - if (next == NULL) { - return(1); - } - - if (next == bridge) { - shpchp_slot_list[bridge->bus] = bridge->next; - kfree(bridge); - return(0); - } - - while ((next->next != bridge) && (next->next != NULL)) { - next = next->next; - } - - if (next->next == bridge) { - next->next = bridge->next; - kfree(bridge); - return(0); - } else - return(2); -} - - -/** - * shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed - * @bus: bus to find - * @device: device to find - * @index: is 0 for first function found, 1 for the second... - * - * Returns pointer to the node if successful, %NULL otherwise. - */ -struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index) -{ - int found = -1; - struct pci_func *func; - - func = shpchp_slot_list[bus]; - - if ((func == NULL) || ((func->device == device) && (index == 0))) - return(func); - - if (func->device == device) - found++; - - while (func->next != NULL) { - func = func->next; - - if (func->device == device) - found++; - - if (found == index) - return(func); - } - - return(NULL); -} - -static int is_bridge(struct pci_func *func, struct controller *ctrl) -{ - u8 hdr_type; - struct pci_bus *bus = ctrl->pci_dev->subordinate; - - /* - * Note: device may have just been hot-added and not yet scanned - * by the pci core, so its pci_dev structure may not exist yet - */ - pci_bus_read_config_byte(bus, PCI_DEVFN(func->device, func->function), - PCI_HEADER_TYPE, &hdr_type); - if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) - return 1; - else - return 0; -} - /* The following routines constitute the bulk of the hotplug controller logic */ @@ -495,19 +308,20 @@ enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) * Configures board * */ -static u32 board_added(struct pci_func * func, struct controller * ctrl) +static u32 board_added(struct slot *p_slot) { u8 hp_slot; u8 slots_not_empty = 0; u32 rc = 0; - struct slot *p_slot; enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed; u8 pi, mode; + struct controller *ctrl = p_slot->ctrl; - p_slot = shpchp_find_slot(ctrl, func->device); - hp_slot = func->device - ctrl->slot_device_offset; + hp_slot = p_slot->device - ctrl->slot_device_offset; - dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); + dbg("%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n", + __FUNCTION__, p_slot->device, + ctrl->slot_device_offset, hp_slot); /* Wait for exclusive access to hardware */ down(&ctrl->crit_sect); @@ -699,13 +513,13 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) wait_for_ctrl_irq (ctrl); dbg("%s: after long_delay\n", __FUNCTION__); - dbg("%s: func status = %x\n", __FUNCTION__, func->status); + dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status); /* Check for a power fault */ - if (func->status == 0xFF) { + if (p_slot->status == 0xFF) { /* power fault occurred, but it was benign */ dbg("%s: power fault\n", __FUNCTION__); rc = POWER_FAILURE; - func->status = 0; + p_slot->status = 0; goto err_exit; } @@ -715,10 +529,9 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) goto err_exit; } - func->status = 0; - func->switch_save = 0x10; - func->is_a_board = 0x01; - func->pwr_save = 1; + p_slot->status = 0; + p_slot->is_a_board = 0x01; + p_slot->pwr_save = 1; /* Wait for exclusive access to hardware */ down(&ctrl->crit_sect); @@ -767,38 +580,23 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) * remove_board - Turns off slot and LED's * */ -static u32 remove_board(struct pci_func *func, struct controller *ctrl) +static u32 remove_board(struct slot *p_slot) { - u8 device; + struct controller *ctrl = p_slot->ctrl; u8 hp_slot; u32 rc; - struct slot *p_slot; - u8 secondary = 0, subordinate = 0; - int remove_bridge; - if (func == NULL) + if (shpchp_unconfigure_device(p_slot)) return(1); - if ((remove_bridge = is_bridge(func, ctrl))) { - /* Stash away bus information before we destroy it */ - secondary = func->pci_dev->subordinate->secondary; - subordinate = func->pci_dev->subordinate->subordinate; - } - - if (shpchp_unconfigure_device(func)) - return(1); - - device = func->device; - - hp_slot = func->device - ctrl->slot_device_offset; + hp_slot = p_slot->device - ctrl->slot_device_offset; p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); /* Change status to shutdown */ - if (func->is_a_board) - func->status = 0x01; - func->configured = 0; + if (p_slot->is_a_board) + p_slot->status = 0x01; /* Wait for exclusive access to hardware */ down(&ctrl->crit_sect); @@ -835,36 +633,8 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) /* Done with exclusive hardware access */ up(&ctrl->crit_sect); - if (ctrl->add_support) { - while (func) { - if (remove_bridge) { - dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, - func->device, func->function); - bridge_slot_remove(func, secondary, - subordinate); - } else - dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, - func->device, func->function); - slot_remove(func); - - func = shpchp_slot_find(ctrl->slot_bus, device, 0); - } - - /* Setup slot structure with entry for empty slot */ - func = shpchp_slot_create(ctrl->slot_bus); - - if (func == NULL) { - return(1); - } - - func->bus = ctrl->slot_bus; - func->device = device; - func->function = 0; - func->configured = 0; - func->switch_save = 0x10; - func->pwr_save = 0; - func->is_a_board = 0; - } + p_slot->pwr_save = 0; + p_slot->is_a_board = 0; return 0; } @@ -1006,7 +776,6 @@ static void interrupt_event_handler(struct controller *ctrl) { int loop = 0; int change = 1; - struct pci_func *func; u8 hp_slot; u8 getstatus; struct slot *p_slot; @@ -1021,11 +790,10 @@ static void interrupt_event_handler(struct controller *ctrl) ctrl->event_queue[loop].event_type); hp_slot = ctrl->event_queue[loop].hp_slot; - func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0); - p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - dbg("%s: hp_slot %d, func %p, p_slot %p\n", __FUNCTION__, hp_slot, func, p_slot); + dbg("%s: hp_slot %d, p_slot %p\n", + __FUNCTION__, hp_slot, p_slot); if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { dbg("%s: button cancel\n", __FUNCTION__); @@ -1147,13 +915,6 @@ int shpchp_enable_slot (struct slot *p_slot) { u8 getstatus = 0; int rc; - struct pci_func *func; - - func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); - if (!func) { - dbg("%s: Error! slot NULL\n", __FUNCTION__); - return -ENODEV; - } /* Check to see if (latch closed, card present, power off) */ down(&p_slot->ctrl->crit_sect); @@ -1177,75 +938,35 @@ int shpchp_enable_slot (struct slot *p_slot) } up(&p_slot->ctrl->crit_sect); - slot_remove(func); - - func = shpchp_slot_create(p_slot->bus); - if (func == NULL) - return -ENOMEM; - - func->bus = p_slot->bus; - func->device = p_slot->device; - func->function = 0; - func->configured = 0; - func->is_a_board = 1; + p_slot->is_a_board = 1; /* We have to save the presence info for these slots */ - p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); - p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save)); - dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save); + p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); + p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save)); + dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - func->switch_save = !getstatus? 0x10:0; - rc = board_added(func, p_slot->ctrl); + rc = board_added(p_slot); if (rc) { - if (is_bridge(func, p_slot->ctrl)) { - u8 secondary = func->pci_dev->subordinate->secondary; - u8 subordinate = - func->pci_dev->subordinate->subordinate; - bridge_slot_remove(func, secondary, subordinate); - } else - slot_remove(func); - - /* Setup slot structure with entry for empty slot */ - func = shpchp_slot_create(p_slot->bus); - if (func == NULL) - return -ENOMEM; /* Out of memory */ - - func->bus = p_slot->bus; - func->device = p_slot->device; - func->function = 0; - func->configured = 0; - func->is_a_board = 1; - - /* We have to save the presence info for these slots */ - p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_adapter_status(p_slot, + &(p_slot->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - func->switch_save = !getstatus? 0x10:0; } - if (p_slot) - update_slot_info(p_slot); - + update_slot_info(p_slot); return rc; } int shpchp_disable_slot (struct slot *p_slot) { - u8 class_code, header_type, BCR; - u8 index = 0; u8 getstatus = 0; u32 rc = 0; int ret = 0; - unsigned int devfn; - struct pci_bus *pci_bus; - struct pci_func *func; if (!p_slot->ctrl) return -ENODEV; - pci_bus = p_slot->ctrl->pci_dev->subordinate; - /* Check to see if (latch closed, card present, power on) */ down(&p_slot->ctrl->crit_sect); @@ -1269,54 +990,8 @@ int shpchp_disable_slot (struct slot *p_slot) } up(&p_slot->ctrl->crit_sect); - func = shpchp_slot_find(p_slot->bus, p_slot->device, index++); - - /* Make sure there are no video controllers here - * for all func of p_slot - */ - while (func && !rc) { - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - /* Check the Class Code */ - rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); - if (rc) - return -ENODEV; - - if (class_code == PCI_BASE_CLASS_DISPLAY) { - /* Display/Video adapter (not supported) */ - rc = REMOVE_NOT_SUPPORTED; - } else { - /* See if it's a bridge */ - rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); - if (rc) - return -ENODEV; - - /* If it's a bridge, check the VGA Enable bit */ - if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { - rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); - if (rc) - return -ENODEV; - - /* If the VGA Enable bit is set, remove isn't supported */ - if (BCR & PCI_BRIDGE_CTL_VGA) { - rc = REMOVE_NOT_SUPPORTED; - } - } - } - - func = shpchp_slot_find(p_slot->bus, p_slot->device, index++); - } - - func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); - if ((func != NULL) && !rc) { - rc = remove_board(func, p_slot->ctrl); - } else if (!rc) - rc = -ENODEV; - - if (p_slot) - update_slot_info(p_slot); - + rc = remove_board(p_slot); + update_slot_info(p_slot); return rc; } diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index f51a97d7611f..8f0a1667f2e6 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -148,20 +148,33 @@ int shpchp_configure_device(struct slot *p_slot) return 0; } -int shpchp_unconfigure_device(struct pci_func* func) +int shpchp_unconfigure_device(struct slot *p_slot) { int rc = 0; int j; + u8 bctl = 0; - dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, - func->device, func->function); + dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device); for (j=0; j<8 ; j++) { - struct pci_dev* temp = pci_find_slot(func->bus, - (func->device << 3) | j); - if (temp) { - pci_remove_bus_device(temp); + struct pci_dev* temp = pci_find_slot(p_slot->bus, + (p_slot->device << 3) | j); + if (!temp) + continue; + if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + err("Cannot remove display device %s\n", + pci_name(temp)); + continue; } + if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); + if (bctl & PCI_BRIDGE_CTL_VGA) { + err("Cannot remove display device %s\n", + pci_name(temp)); + continue; + } + } + pci_remove_bus_device(temp); } return rc; } From ee138334d5eb5ca662b2d69228420c1ccc051e0e Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:42 -0700 Subject: [PATCH 0792/1940] [PATCH] shpchp: miscellaneous cleanups Remove un-necessary header includes, remove dead code, remove some type casts, receive function return in the correct data type... Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 14 +-- drivers/pci/hotplug/shpchp_core.c | 12 +-- drivers/pci/hotplug/shpchp_ctrl.c | 31 +++--- drivers/pci/hotplug/shpchp_hpc.c | 126 ++++++------------------- drivers/pci/hotplug/shpchp_pci.c | 4 - drivers/pci/hotplug/shpchp_sysfs.c | 3 - drivers/pci/hotplug/shpchprm_acpi.c | 6 -- drivers/pci/hotplug/shpchprm_legacy.c | 4 - drivers/pci/hotplug/shpchprm_nonacpi.c | 3 - 9 files changed, 46 insertions(+), 157 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 052c11f14a79..ade8ec145e1e 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include "pci_hotplug.h" #if !defined(MODULE) @@ -80,7 +78,7 @@ struct event_info { struct controller { struct controller *next; struct semaphore crit_sect; /* critical section semaphore */ - void * hpc_ctlr_handle; /* HPC controller handle */ + struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; @@ -234,7 +232,7 @@ enum ctrl_offsets { SLOT11 = offsetof(struct ctrl_reg, slot11), SLOT12 = offsetof(struct ctrl_reg, slot12), }; -typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id); +typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); struct php_ctlr_state_s { struct php_ctlr_state_s *pnext; struct pci_dev *pci_dev; @@ -347,11 +345,7 @@ enum php_ctlr_type { ACPI }; -int shpc_init( struct controller *ctrl, struct pci_dev *pdev, - php_intr_callback_t attention_button_callback, - php_intr_callback_t switch_change_callback, - php_intr_callback_t presence_change_callback, - php_intr_callback_t power_fault_callback); +int shpc_init( struct controller *ctrl, struct pci_dev *pdev); int shpc_get_ctlr_slot_config( struct controller *ctrl, int *num_ctlr_slots, @@ -364,8 +358,6 @@ struct hpc_ops { int (*power_on_slot ) (struct slot *slot); int (*slot_enable ) (struct slot *slot); int (*slot_disable ) (struct slot *slot); - int (*enable_all_slots) (struct slot *slot); - int (*pwr_on_all_slots) (struct slot *slot); int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed); int (*get_power_status) (struct slot *slot, u8 *status); int (*get_attention_status) (struct slot *slot, u8 *status); diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index b54edccbf2cc..28ed2dc9388a 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -27,17 +27,11 @@ * */ -#include #include #include #include #include -#include -#include -#include #include -#include -#include #include "shpchp.h" /* Global variables */ @@ -381,11 +375,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dbg("DRV_thread pid = %d\n", current->pid); - rc = shpc_init(ctrl, pdev, - (php_intr_callback_t) shpchp_handle_attention_button, - (php_intr_callback_t) shpchp_handle_switch_change, - (php_intr_callback_t) shpchp_handle_presence_change, - (php_intr_callback_t) shpchp_handle_power_fault); + rc = shpc_init(ctrl, pdev); if (rc) { dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME); goto err_out_free_ctrl; diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b6fde3565e55..8541180781e1 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -27,15 +27,9 @@ * */ -#include #include #include #include -#include -#include -#include -#include -#include #include #include #include "../pci.h" @@ -242,9 +236,10 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) /* The following routines constitute the bulk of the hotplug controller logic */ -static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed) +static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, + enum pci_bus_speed speed) { - u32 rc = 0; + int rc = 0; dbg("%s: change to speed %d\n", __FUNCTION__, speed); down(&ctrl->crit_sect); @@ -266,10 +261,11 @@ static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum p return rc; } -static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, -enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) +static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, + u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, + enum pci_bus_speed msp) { - u32 rc = 0; + int rc = 0; if (flag != 0) { /* Other slots on the same bus are occupied */ if ( asp < bsp ) { @@ -308,11 +304,11 @@ enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) * Configures board * */ -static u32 board_added(struct slot *p_slot) +static int board_added(struct slot *p_slot) { u8 hp_slot; u8 slots_not_empty = 0; - u32 rc = 0; + int rc = 0; enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed; u8 pi, mode; struct controller *ctrl = p_slot->ctrl; @@ -580,11 +576,11 @@ static u32 board_added(struct slot *p_slot) * remove_board - Turns off slot and LED's * */ -static u32 remove_board(struct slot *p_slot) +static int remove_board(struct slot *p_slot) { struct controller *ctrl = p_slot->ctrl; u8 hp_slot; - u32 rc; + int rc; if (shpchp_unconfigure_device(p_slot)) return(1); @@ -961,7 +957,6 @@ int shpchp_enable_slot (struct slot *p_slot) int shpchp_disable_slot (struct slot *p_slot) { u8 getstatus = 0; - u32 rc = 0; int ret = 0; if (!p_slot->ctrl) @@ -990,8 +985,8 @@ int shpchp_disable_slot (struct slot *p_slot) } up(&p_slot->ctrl->crit_sect); - rc = remove_board(p_slot); + ret = remove_board(p_slot); update_slot_info(p_slot); - return rc; + return ret; } diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index d55a9a7f8d2b..d46a47603386 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -27,17 +27,10 @@ * */ -#include #include #include #include -#include -#include -#include -#include -#include #include -#include #include "shpchp.h" #ifdef DEBUG @@ -282,7 +275,7 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 cmd_status; int retval = 0; u16 temp_word; @@ -328,7 +321,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) static int hpc_check_cmd_status(struct controller *ctrl) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; u16 cmd_status; int retval = 0; @@ -368,7 +361,7 @@ static int hpc_check_cmd_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status; u8 atten_led_state; @@ -408,7 +401,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) static int hpc_get_power_status(struct slot * slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status; u8 slot_state; @@ -450,7 +443,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) static int hpc_get_latch_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status; @@ -473,7 +466,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) static int hpc_get_adapter_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status; u8 card_state; @@ -496,7 +489,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; DBG_ENTER_ROUTINE @@ -513,7 +506,7 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status, sec_bus_status; u8 m66_cap, pcix_cap, pi; @@ -594,7 +587,7 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 sec_bus_status; u8 pi; int retval = 0; @@ -623,7 +616,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) static int hpc_query_power_fault(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; u16 slot_status; u8 pwr_fault_state, status; @@ -647,7 +640,7 @@ static int hpc_query_power_fault(struct slot * slot) static int hpc_set_attention_status(struct slot *slot, u8 value) { - struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd = 0; int rc = 0; @@ -683,7 +676,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) static void hpc_set_green_led_on(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; if (!slot->ctrl->hpc_ctlr_handle) { @@ -705,7 +698,7 @@ static void hpc_set_green_led_on(struct slot *slot) static void hpc_set_green_led_off(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; if (!slot->ctrl->hpc_ctlr_handle) { @@ -727,7 +720,7 @@ static void hpc_set_green_led_off(struct slot *slot) static void hpc_set_green_led_blink(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; if (!slot->ctrl->hpc_ctlr_handle) { @@ -754,7 +747,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl, int *updown, /* physical_slot_num increament: 1 or -1 */ int *flags) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; DBG_ENTER_ROUTINE @@ -776,7 +769,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl, static void hpc_release_ctlr(struct controller *ctrl) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; struct php_ctlr_state_s *p, *p_prev; DBG_ENTER_ROUTINE @@ -828,7 +821,7 @@ DBG_LEAVE_ROUTINE static int hpc_power_on_slot(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; int retval = 0; @@ -859,7 +852,7 @@ static int hpc_power_on_slot(struct slot * slot) static int hpc_slot_enable(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; int retval = 0; @@ -890,7 +883,7 @@ static int hpc_slot_enable(struct slot * slot) static int hpc_slot_disable(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd; int retval = 0; @@ -920,51 +913,12 @@ static int hpc_slot_disable(struct slot * slot) return retval; } -static int hpc_enable_all_slots( struct slot *slot ) -{ - int retval = 0; - - DBG_ENTER_ROUTINE - - if (!slot->ctrl->hpc_ctlr_handle) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL); - if (retval) { - err("%s: Write command failed!\n", __FUNCTION__); - return -1; - } - - DBG_LEAVE_ROUTINE - - return retval; -} - -static int hpc_pwr_on_all_slots(struct slot *slot) -{ - int retval = 0; - - DBG_ENTER_ROUTINE - - retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL); - - if (retval) { - err("%s: Write command failed!\n", __FUNCTION__); - return -1; - } - - DBG_LEAVE_ROUTINE - return retval; -} - static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) { u8 slot_cmd; u8 pi; int retval = 0; - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; DBG_ENTER_ROUTINE @@ -1184,7 +1138,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; int retval = 0; u8 pi; @@ -1253,7 +1207,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; u16 sec_bus_status; int retval = 0; @@ -1367,8 +1321,6 @@ static struct hpc_ops shpchp_hpc_ops = { .power_on_slot = hpc_power_on_slot, .slot_enable = hpc_slot_enable, .slot_disable = hpc_slot_disable, - .enable_all_slots = hpc_enable_all_slots, - .pwr_on_all_slots = hpc_pwr_on_all_slots, .set_bus_speed_mode = hpc_set_bus_speed_mode, .set_attention_status = hpc_set_attention_status, .get_power_status = hpc_get_power_status, @@ -1391,12 +1343,7 @@ static struct hpc_ops shpchp_hpc_ops = { .check_cmd_status = hpc_check_cmd_status, }; -int shpc_init(struct controller * ctrl, - struct pci_dev * pdev, - php_intr_callback_t attention_button_callback, - php_intr_callback_t switch_change_callback, - php_intr_callback_t presence_change_callback, - php_intr_callback_t power_fault_callback) +int shpc_init(struct controller * ctrl, struct pci_dev * pdev) { struct php_ctlr_state_s *php_ctlr, *p; void *instance_id = ctrl; @@ -1405,7 +1352,6 @@ int shpc_init(struct controller * ctrl, static int first = 1; u32 shpc_cap_offset, shpc_base_offset; u32 tempdword, slot_reg; - u16 vendor_id, device_id; u8 i; DBG_ENTER_ROUTINE @@ -1422,21 +1368,8 @@ int shpc_init(struct controller * ctrl, php_ctlr->pci_dev = pdev; /* save pci_dev in context */ - rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); - dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id); - if (rc) { - err("%s: unable to read PCI configuration data\n", __FUNCTION__); - goto abort_free_ctlr; - } - - rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id); - dbg("%s: Device ID: %x\n",__FUNCTION__, device_id); - if (rc) { - err("%s: unable to read PCI configuration data\n", __FUNCTION__); - goto abort_free_ctlr; - } - - if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) { + if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == + PCI_DEVICE_ID_AMD_GOLAM_7450)) { shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */ } else { if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) { @@ -1514,11 +1447,10 @@ int shpc_init(struct controller * ctrl, php_ctlr->irq = pdev->irq; dbg("HPC interrupt = %d\n", php_ctlr->irq); - /* Save interrupt callback info */ - php_ctlr->attention_button_callback = attention_button_callback; - php_ctlr->switch_change_callback = switch_change_callback; - php_ctlr->presence_change_callback = presence_change_callback; - php_ctlr->power_fault_callback = power_fault_callback; + php_ctlr->attention_button_callback = shpchp_handle_attention_button, + php_ctlr->switch_change_callback = shpchp_handle_switch_change; + php_ctlr->presence_change_callback = shpchp_handle_presence_change; + php_ctlr->power_fault_callback = shpchp_handle_power_fault; php_ctlr->callback_instance_id = instance_id; /* Return PCI Controller Info */ diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 8f0a1667f2e6..b8e95acea3b6 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -27,13 +27,9 @@ * */ -#include #include #include #include -#include -#include -#include #include #include "../pci.h" #include "shpchp.h" diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index ce41719a88f7..807ef66899c7 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -26,12 +26,9 @@ * */ -#include #include #include #include -#include -#include #include #include "shpchp.h" diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 3be518c7d47a..17145e52223a 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -24,16 +24,10 @@ * */ -#include #include #include #include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index cfc6092e2afd..ed6c1254bf6f 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -27,15 +27,11 @@ * */ -#include #include #include #include #include -#include -#include #include "shpchp.h" -#include "shpchprm.h" int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c index f36c188c23eb..d70fe5408417 100644 --- a/drivers/pci/hotplug/shpchprm_nonacpi.c +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c @@ -32,10 +32,7 @@ #include #include #include -#include -#include #include "shpchp.h" -#include "shpchprm.h" int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { From 7c8942f993dc069db0e0327a343bbec8a6e96074 Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:43 -0700 Subject: [PATCH 0793/1940] [PATCH] shpchp: reduce debug message verbosity Reduce the number of debug messages generated if shpchp debug is enabled. I tried to restrict this to removing debug messages that are either early-driver-debug type messages, or print information that can be inferred through other debug prints. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 6 ---- drivers/pci/hotplug/shpchp_core.c | 8 ------ drivers/pci/hotplug/shpchp_ctrl.c | 11 -------- drivers/pci/hotplug/shpchp_hpc.c | 47 +++++-------------------------- 4 files changed, 7 insertions(+), 65 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index ade8ec145e1e..dae1543a4e28 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -293,12 +293,9 @@ static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) p_slot = ctrl->slot; - dbg("p_slot = %p\n", p_slot); - while (p_slot && (p_slot->device != device)) { tmp_slot = p_slot; p_slot = p_slot->next; - dbg("In while loop, p_slot = %p\n", p_slot); } if (p_slot == NULL) { err("ERROR: shpchp_find_slot device=0x%x\n", device); @@ -313,8 +310,6 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) DECLARE_WAITQUEUE(wait, current); int retval = 0; - dbg("%s : start\n",__FUNCTION__); - add_wait_queue(&ctrl->queue, &wait); if (!shpchp_poll_mode) { @@ -328,7 +323,6 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) if (signal_pending(current)) retval = -EINTR; - dbg("%s : end\n", __FUNCTION__); return retval; } diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 28ed2dc9388a..6a2b4a0193aa 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -105,8 +105,6 @@ static int init_slots(struct controller *ctrl) u32 slot_number, sun; int result = -ENOMEM; - dbg("%s\n",__FUNCTION__); - number_of_slots = ctrl->num_slots; slot_device = ctrl->slot_device_offset; slot_number = ctrl->first_slot; @@ -373,15 +371,12 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } memset(ctrl, 0, sizeof(struct controller)); - dbg("DRV_thread pid = %d\n", current->pid); - rc = shpc_init(ctrl, pdev); if (rc) { dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME); goto err_out_free_ctrl; } - dbg("%s: controller initialization success\n", __FUNCTION__); ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ pci_set_drvdata(pdev, ctrl); @@ -488,8 +483,6 @@ static void __exit unload_shpchpd(void) cleanup_slots(ctrl); kfree (ctrl->pci_bus); - - dbg("%s: calling release_ctlr\n", __FUNCTION__); ctrl->hpc_ops->release_ctlr(ctrl); tctrl = ctrl; @@ -558,7 +551,6 @@ static void __exit shpcd_cleanup(void) dbg("unload_shpchpd()\n"); unload_shpchpd(); - dbg("pci_unregister_driver\n"); pci_unregister_driver(&shpc_driver); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 8541180781e1..58619359ad08 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -505,9 +505,7 @@ static int board_added(struct slot *p_slot) up(&ctrl->crit_sect); /* Wait for ~1 second */ - dbg("%s: before long_delay\n", __FUNCTION__); wait_for_ctrl_irq (ctrl); - dbg("%s: after long_delay\n", __FUNCTION__); dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status); /* Check for a power fault */ @@ -666,13 +664,11 @@ static void shpchp_pushbutton_thread (unsigned long slot) p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (getstatus) { p_slot->state = POWEROFF_STATE; - dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); shpchp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; - dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); if (shpchp_enable_slot(p_slot)) { /* Wait for exclusive access to hardware */ @@ -734,7 +730,6 @@ int shpchp_event_start_thread (void) err ("Can't start up our event thread\n"); return -1; } - dbg("Our event thread pid = %d\n", pid); return 0; } @@ -742,9 +737,7 @@ int shpchp_event_start_thread (void) void shpchp_event_stop_thread (void) { event_finished = 1; - dbg("event_thread finish command given\n"); up(&event_semaphore); - dbg("wait for event_thread to exit\n"); down(&event_exit); } @@ -776,7 +769,6 @@ static void interrupt_event_handler(struct controller *ctrl) u8 getstatus; struct slot *p_slot; - dbg("%s:\n", __FUNCTION__); while (change) { change = 0; @@ -788,9 +780,6 @@ static void interrupt_event_handler(struct controller *ctrl) p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - dbg("%s: hp_slot %d, p_slot %p\n", - __FUNCTION__, hp_slot, p_slot); - if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { dbg("%s: button cancel\n", __FUNCTION__); del_timer(&p_slot->task_event); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index d46a47603386..40905a6c8094 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -313,7 +313,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) * command. */ writew(temp_word, php_ctlr->creg + CMD); - dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word); DBG_LEAVE_ROUTINE return retval; @@ -789,10 +788,8 @@ static void hpc_release_ctlr(struct controller *ctrl) } } if (php_ctlr->pci_dev) { - dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__); iounmap(php_ctlr->creg); release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0)); - dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__); php_ctlr->pci_dev = NULL; } @@ -1043,18 +1040,13 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) if (!intr_loc) return IRQ_NONE; - dbg("%s: shpc_isr proceeds\n", __FUNCTION__); dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); if(!shpchp_poll_mode) { /* Mask Global Interrupt Mask - see implementation note on p. 139 */ /* of SHPC spec rev 1.0*/ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: Before masking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); temp_dword |= 0x00000001; - dbg("%s: After masking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); intr_loc2 = readl(php_ctlr->creg + INTR_LOC); @@ -1068,11 +1060,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) * Detect bit in Controller SERR-INT register */ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: Before clearing CCIP, temp_dword = %x\n", - __FUNCTION__, temp_dword); temp_dword &= 0xfffeffff; - dbg("%s: After clearing CCIP, temp_dword = %x\n", - __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); wake_up_interruptible(&ctrl->queue); } @@ -1080,11 +1068,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) if ((intr_loc = (intr_loc >> 1)) == 0) { /* Unmask Global Interrupt Mask */ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); temp_dword &= 0xfffffffe; - dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); return IRQ_NONE; @@ -1094,11 +1078,9 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) /* To find out which slot has interrupt pending */ if ((intr_loc >> hp_slot) & 0x01) { temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot)); - dbg("%s: Slot %x with intr, temp_dword = %x\n", - __FUNCTION__, hp_slot, temp_dword); + dbg("%s: Slot %x with intr, slot register = %x\n", + __FUNCTION__, hp_slot, temp_dword); temp_byte = (temp_dword >> 16) & 0xFF; - dbg("%s: Slot with intr, temp_byte = %x\n", - __FUNCTION__, temp_byte); if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08)) schedule_flag += php_ctlr->switch_change_callback( hp_slot, php_ctlr->callback_instance_id); @@ -1114,8 +1096,6 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) /* Clear all slot events */ temp_dword = 0xe01f3fff; - dbg("%s: Clearing slot events, temp_dword = %x\n", - __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); intr_loc2 = readl(php_ctlr->creg + INTR_LOC); @@ -1125,11 +1105,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) if (!shpchp_poll_mode) { /* Unmask Global Interrupt Mask */ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); temp_dword &= 0xfffffffe; - dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); } @@ -1402,7 +1378,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) err("%s : pci_read_config_dword failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword); + dbg("%s: offset %d: value %x\n", __FUNCTION__,i, + tempdword); } } @@ -1411,13 +1388,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) first = 0; } - dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq); - for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) - if (pci_resource_len(pdev, rc) > 0) - dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc, - pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset); - info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); @@ -1437,7 +1407,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) goto abort_free_ctlr; } dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); - dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0)); init_MUTEX(&ctrl->crit_sect); /* Setup wait queue */ @@ -1445,8 +1414,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) /* Find the IRQ */ php_ctlr->irq = pdev->irq; - dbg("HPC interrupt = %d\n", php_ctlr->irq); - php_ctlr->attention_button_callback = shpchp_handle_attention_button, php_ctlr->switch_change_callback = shpchp_handle_switch_change; php_ctlr->presence_change_callback = shpchp_handle_presence_change; @@ -1488,7 +1455,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) if (rc) { info("Can't get msi for the hotplug controller\n"); info("Use INTx for the hotplug controller\n"); - dbg("%s: rc = %x\n", __FUNCTION__, rc); } else php_ctlr->irq = pdev->irq; @@ -1499,8 +1465,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) goto abort_free_ctlr; } } + dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__, + pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pdev->irq); get_hp_hw_control_from_firmware(pdev); - dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); /* Add this HPC instance into the HPC list */ spin_lock(&list_lock); @@ -1539,7 +1507,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); } - dbg("%s: Leaving shpc_init\n", __FUNCTION__); DBG_LEAVE_ROUTINE return 0; From c2608a111b621d5cf0e4c2876d79e67333ce5341 Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:44 -0700 Subject: [PATCH 0794/1940] [PATCH] shpchp: fix oops at driver unload At unload time, the shpchp driver does not remove sysfs files it had created in the driver's probe entry point. This patch fixes this problem. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 1 + drivers/pci/hotplug/shpchp_core.c | 1 + drivers/pci/hotplug/shpchp_sysfs.c | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index dae1543a4e28..abe2cf411e68 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -173,6 +173,7 @@ extern void get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp); extern int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum); +extern void shpchp_remove_ctrl_files(struct controller *ctrl); /* Global variables */ diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 6a2b4a0193aa..63628e01dd43 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -480,6 +480,7 @@ static void __exit unload_shpchpd(void) ctrl = shpchp_ctrl_list; while (ctrl) { + shpchp_remove_ctrl_files(ctrl); cleanup_slots(ctrl); kfree (ctrl->pci_bus); diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 807ef66899c7..f5cfbf2c047c 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -89,3 +89,8 @@ void shpchp_create_ctrl_files (struct controller *ctrl) { device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); } + +void shpchp_remove_ctrl_files(struct controller *ctrl) +{ + device_remove_file(&ctrl->pci_dev->dev, &dev_attr_ctrl); +} From d10211b278c70fbebb83fb9e4ee717ca13f69b2d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 15 Oct 2005 22:02:19 -0700 Subject: [PATCH 0795/1940] [PATCH] PCI: fix edac drivers for radisys 82600 borkage I told you that the pci_ids.h cleanup was a bad idea ;) Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 11fed60a928d..611e48a4e679 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1610,6 +1610,7 @@ #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 +#define PCI_VENDOR_ID_RADISYS 0x1331 #define PCI_VENDOR_ID_DOMEX 0x134a #define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 From a1720fdbd0f90e64668a59a304d01c5ba001b450 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 16 Oct 2005 21:31:36 +0100 Subject: [PATCH 0796/1940] [PATCH] PCI: Fixup PCI driver shutdown Add a warning to pci driver registration code so that we know whether we have drivers using the obsolete driver shutdown method. Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 0d0d533894e0..f906f1a8fe6a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -377,6 +377,10 @@ int pci_register_driver(struct pci_driver *drv) * the pci shutdown function, this test can go away. */ if (!drv->driver.shutdown) drv->driver.shutdown = pci_device_shutdown; + else + printk(KERN_WARNING "Warning: PCI driver %s has a struct " + "device_driver shutdown method, please update!\n", + drv->name); drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; From 5457b6a6013516a73b8f48ec1adb9984b577a5c1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 16 Oct 2005 21:32:46 +0100 Subject: [PATCH 0797/1940] [PATCH] PCI: Convert megaraid to use pci_driver shutdown method Convert megaraid to use pci_driver's shutdown method rather than the generic device_driver shutdown method. Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/megaraid/megaraid_mbox.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index d47be8e0ea3a..c9e743ba09ec 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -76,7 +76,7 @@ static void megaraid_exit(void); static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *); static void megaraid_detach_one(struct pci_dev *); -static void megaraid_mbox_shutdown(struct device *); +static void megaraid_mbox_shutdown(struct pci_dev *); static int megaraid_io_attach(adapter_t *); static void megaraid_io_detach(adapter_t *); @@ -369,9 +369,7 @@ static struct pci_driver megaraid_pci_driver_g = { .id_table = pci_id_table_g, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_detach_one), - .driver = { - .shutdown = megaraid_mbox_shutdown, - } + .shutdown = megaraid_mbox_shutdown, }; @@ -673,9 +671,9 @@ megaraid_detach_one(struct pci_dev *pdev) * Shutdown notification, perform flush cache */ static void -megaraid_mbox_shutdown(struct device *device) +megaraid_mbox_shutdown(struct pci_dev *pdev) { - adapter_t *adapter = pci_get_drvdata(to_pci_dev(device)); + adapter_t *adapter = pci_get_drvdata(pdev); static int counter; if (!adapter) { From 8e5dce35221850759671b2847a2e51030f7626bd Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Tue, 18 Oct 2005 17:21:40 -0700 Subject: [PATCH 0798/1940] [PATCH] acpiphp: allocate resources for adapters with bridges Allocate resources for adapters with bridges on them. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 424e7de181ae..8e21f6ab89a1 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list); static void handle_hotplug_event_bridge (acpi_handle, u32, void *); static void handle_hotplug_event_func (acpi_handle, u32, void *); +static void acpiphp_sanitize_bus(struct pci_bus *bus); +static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); + /* * initialization & terminatation routines @@ -796,8 +799,13 @@ static int enable_device(struct acpiphp_slot *slot) } } + pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); + acpiphp_sanitize_bus(bus); + pci_enable_bridges(bus); pci_bus_add_devices(bus); + acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus); + acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev)); /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { From f05aab8ef653abcbd454739264a9f5cf63f6f9f8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 Oct 2005 11:58:19 -0700 Subject: [PATCH 0799/1940] [PATCH] kernel-doc: fix PCI hotplug PCI hotplug.c: does not contain kernel-doc, so don't process it for now. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/kernel-api.tmpl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index d650ce36485f..4d9b66d8b4db 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -286,7 +286,9 @@ X!Edrivers/pci/search.c --> !Edrivers/pci/msi.c !Edrivers/pci/bus.c -!Edrivers/pci/hotplug.c + !Edrivers/pci/probe.c !Edrivers/pci/rom.c From 8f7020d36374dda9366fee1343f8eacfe8f5e641 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 Oct 2005 11:57:38 -0700 Subject: [PATCH 0800/1940] [PATCH] kernel-doc: PCI fixes PCI: add descriptions for missing function parameters. Eliminate all kernel-doc warnings here. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 2 ++ drivers/pci/pci-driver.c | 13 +++++++++---- drivers/pci/pci.c | 7 ++++--- drivers/pci/probe.c | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index ee8677bda950..a2033552423c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -575,6 +575,8 @@ static int msi_capability_init(struct pci_dev *dev) /** * msix_capability_init - configure device's MSI-X capability * @dev: pointer to the pci_dev data structure of MSI-X device function + * @entries: pointer to an array of struct msix_entry entries + * @nvec: number of @entries * * Setup the MSI-X capability structure of device function with a * single MSI-X vector. A return of zero indicates the successful setup of diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index f906f1a8fe6a..8972e6a3aac0 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -26,7 +26,10 @@ struct pci_dynid { #ifdef CONFIG_HOTPLUG /** - * store_new_id + * store_new_id - add a new PCI device ID to this driver and re-probe devices + * @driver: target device driver + * @buf: buffer for scanning device ID data + * @count: input size * * Adds a new dynamic pci device ID to this driver, * and causes the driver to probe for all devices again. @@ -194,8 +197,10 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, /** * __pci_device_probe() + * @drv: driver to call to check if it wants the PCI device + * @pci_dev: PCI device being probed * - * returns 0 on success, else error. + * returns 0 on success, else error. * side-effect: pci_dev->driver is set to drv when drv claims pci_dev. */ static int @@ -440,11 +445,11 @@ pci_dev_driver(const struct pci_dev *dev) /** * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure - * @ids: array of PCI device id structures to search in * @dev: the PCI device structure to match against + * @drv: the device driver to search for matching PCI device id structures * * Used by a driver to check whether a PCI device present in the - * system is in its list of supported devices.Returns the matching + * system is in its list of supported devices. Returns the matching * pci_device_id structure or %NULL if there is no match. */ static int pci_bus_match(struct device *dev, struct device_driver *drv) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 39bdb938521d..61b855c99e39 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -252,6 +252,8 @@ pci_restore_bars(struct pci_dev *dev) pci_update_resource(dev, &dev->resource[i], i); } +int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); + /** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to be suspended @@ -266,7 +268,6 @@ pci_restore_bars(struct pci_dev *dev) * -EIO if device does not support PCI PM. * 0 if we can successfully change the power state. */ -int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { @@ -808,8 +809,8 @@ pci_clear_mwi(struct pci_dev *dev) /** * pci_intx - enables/disables PCI INTx for device dev - * @dev: the PCI device to operate on - * @enable: boolean + * @pdev: the PCI device to operate on + * @enable: boolean: whether to enable or disable PCI INTx * * Enables/disables PCI INTx for device dev */ diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 005786416bb5..fce2cb2112d8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -669,6 +669,7 @@ static void pci_release_dev(struct device *dev) /** * pci_cfg_space_size - get the configuration space size of the PCI device. + * @dev: PCI device * * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices * have 4096 bytes. Even if the device is capable, that doesn't mean we can From 2f028234f2c7f31dc0ff0784e20f14be11f7035c Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 20 Oct 2005 09:55:32 +1000 Subject: [PATCH 0801/1940] [PATCH] pci_ids: cleanup comments pci_ids.h cleanup: convert // comment to /* comment */ Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 611e48a4e679..7d300f7469e3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -444,7 +444,7 @@ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251 #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 -#define PCI_VENDOR_ID_COMPEX2 0x101a // pci.ids says "AT&T GIS (NCR)" +#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */ #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 #define PCI_VENDOR_ID_WD 0x101c @@ -1158,10 +1158,10 @@ #define PCI_VENDOR_ID_INIT 0x1101 -#define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA +#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 -#define PCI_VENDOR_ID_ECTIVA 0x1102 // duplicate: CREATIVE +#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ #define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 #define PCI_VENDOR_ID_TTI 0x1103 @@ -1171,7 +1171,7 @@ #define PCI_DEVICE_ID_TTI_HPT302 0x0006 #define PCI_DEVICE_ID_TTI_HPT371 0x0007 #define PCI_DEVICE_ID_TTI_HPT374 0x0008 -#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 // apparently a 372N variant? +#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */ #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_8763_0 0x0198 From f8977d0a9b7ac84cfe700278a2ca64cb33c93a13 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 25 Oct 2005 10:28:42 -0700 Subject: [PATCH 0802/1940] [PATCH] PCI fixup for Toshiba laptops and ohci1394 This is a fix for a bug I see on my Toshiba laptop, where the ohci1394 controller gets initialized improperly. The patch adds two PCI fixups to arch/i386/pci/fixup.c, one that happens early on to cache the value of the PCI_CACHE_LINE_SIZE config register, and another that later restores the value, along with a valid IRQ number and some BAR values. I've tested it on my laptop, and it prevents me from running into what I consider to be a major bug: IRQ 11 is disabled by the IRQ debug code, causing my wireless to break. Thanks to Rob for the original patch to ohci1394.c and Stefan for lots of proofreading (and a last minute bug caught in review!) and additional information collection. I think the DMI system list is correct, but we may need to add some more PCI IDs to the PCI_FIXUP macros over time. Signed-off-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index 8e8e895e1b5a..330fd2b68075 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -2,6 +2,8 @@ * Exceptions for specific devices. Usually work-arounds for fatal design flaws. */ +#include +#include #include #include #include "pci.h" @@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); + +/* + * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. + * + * We pretend to bring them out of full D3 state, and restore the proper + * IRQ, PCI cache line size, and BARs, otherwise the device won't function + * properly. In some cases, the device will generate an interrupt on + * the wrong IRQ line, causing any devices sharing the the line it's + * *supposed* to use to be disabled by the kernel's IRQ debug code. + */ +static u16 toshiba_line_size; + +static struct dmi_system_id __devinit toshiba_ohci1394_dmi_table[] = { + { + .ident = "Toshiba PS5 based laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "PS5"), + }, + }, + { + .ident = "Toshiba PSM4 based laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"), + }, + }, + { } +}; + +static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev) +{ + if (!dmi_check_system(toshiba_ohci1394_dmi_table)) + return; /* only applies to certain Toshibas (so far) */ + + dev->current_state = PCI_D3cold; + pci_read_config_word(dev, PCI_CACHE_LINE_SIZE, &toshiba_line_size); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032, + pci_pre_fixup_toshiba_ohci1394); + +static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev) +{ + if (!dmi_check_system(toshiba_ohci1394_dmi_table)) + return; /* only applies to certain Toshibas (so far) */ + + /* Restore config space on Toshiba laptops */ + mdelay(10); + pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size); + pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + pci_resource_start(dev, 0)); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, + pci_resource_start(dev, 1)); +} +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, + pci_post_fixup_toshiba_ohci1394); From a74968f8c3b1166cfe0942901b56165f06ab6f60 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 28 Oct 2005 15:37:23 -0700 Subject: [PATCH 0803/1940] [IB] umad: Fix device lifetime problems Move ib_umad module to using cdev_alloc() and class_device_create() so that we can handle device lifetime properly. Now we can make sure we keep all of our data structures around until the last way to reach them is gone. Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 272 +++++++++++++++++------------ 1 file changed, 161 insertions(+), 111 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 17ec0a19dbc0..9e49816d7282 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -64,18 +64,39 @@ enum { IB_UMAD_MINOR_BASE = 0 }; -struct ib_umad_port { - int devnum; - struct cdev dev; - struct class_device class_dev; +/* + * Our lifetime rules for these structs are the following: each time a + * device special file is opened, we look up the corresponding struct + * ib_umad_port by minor in the umad_port[] table while holding the + * port_lock. If this lookup succeeds, we take a reference on the + * ib_umad_port's struct ib_umad_device while still holding the + * port_lock; if the lookup fails, we fail the open(). We drop these + * references in the corresponding close(). + * + * In addition to references coming from open character devices, there + * is one more reference to each ib_umad_device representing the + * module's reference taken when allocating the ib_umad_device in + * ib_umad_add_one(). + * + * When destroying an ib_umad_device, we clear all of its + * ib_umad_ports from umad_port[] while holding port_lock before + * dropping the module's reference to the ib_umad_device. This is + * always safe because any open() calls will either succeed and obtain + * a reference before we clear the umad_port[] entries, or fail after + * we clear the umad_port[] entries. + */ - int sm_devnum; - struct cdev sm_dev; - struct class_device sm_class_dev; +struct ib_umad_port { + struct cdev *dev; + struct class_device *class_dev; + + struct cdev *sm_dev; + struct class_device *sm_class_dev; struct semaphore sm_sem; struct ib_device *ib_dev; struct ib_umad_device *umad_dev; + int dev_num; u8 port_num; }; @@ -102,13 +123,25 @@ struct ib_umad_packet { struct ib_user_mad mad; }; +static struct class *umad_class; + static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE); -static spinlock_t map_lock; + +static DEFINE_SPINLOCK(port_lock); +static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS]; static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2); static void ib_umad_add_one(struct ib_device *device); static void ib_umad_remove_one(struct ib_device *device); +static void ib_umad_release_dev(struct kref *ref) +{ + struct ib_umad_device *dev = + container_of(ref, struct ib_umad_device, ref); + + kfree(dev); +} + static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent, struct ib_umad_packet *packet) @@ -534,13 +567,23 @@ static long ib_umad_ioctl(struct file *filp, unsigned int cmd, static int ib_umad_open(struct inode *inode, struct file *filp) { - struct ib_umad_port *port = - container_of(inode->i_cdev, struct ib_umad_port, dev); + struct ib_umad_port *port; struct ib_umad_file *file; + spin_lock(&port_lock); + port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; + if (port) + kref_get(&port->umad_dev->ref); + spin_unlock(&port_lock); + + if (!port) + return -ENXIO; + file = kzalloc(sizeof *file, GFP_KERNEL); - if (!file) + if (!file) { + kref_put(&port->umad_dev->ref, ib_umad_release_dev); return -ENOMEM; + } spin_lock_init(&file->recv_lock); init_rwsem(&file->agent_mutex); @@ -556,6 +599,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) static int ib_umad_close(struct inode *inode, struct file *filp) { struct ib_umad_file *file = filp->private_data; + struct ib_umad_device *dev = file->port->umad_dev; struct ib_umad_packet *packet, *tmp; int i; @@ -570,6 +614,8 @@ static int ib_umad_close(struct inode *inode, struct file *filp) kfree(file); + kref_put(&dev->ref, ib_umad_release_dev); + return 0; } @@ -586,30 +632,46 @@ static struct file_operations umad_fops = { static int ib_umad_sm_open(struct inode *inode, struct file *filp) { - struct ib_umad_port *port = - container_of(inode->i_cdev, struct ib_umad_port, sm_dev); + struct ib_umad_port *port; struct ib_port_modify props = { .set_port_cap_mask = IB_PORT_SM }; int ret; + spin_lock(&port_lock); + port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS]; + if (port) + kref_get(&port->umad_dev->ref); + spin_unlock(&port_lock); + + if (!port) + return -ENXIO; + if (filp->f_flags & O_NONBLOCK) { - if (down_trylock(&port->sm_sem)) - return -EAGAIN; + if (down_trylock(&port->sm_sem)) { + ret = -EAGAIN; + goto fail; + } } else { - if (down_interruptible(&port->sm_sem)) - return -ERESTARTSYS; + if (down_interruptible(&port->sm_sem)) { + ret = -ERESTARTSYS; + goto fail; + } } ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); if (ret) { up(&port->sm_sem); - return ret; + goto fail; } filp->private_data = port; return 0; + +fail: + kref_put(&port->umad_dev->ref, ib_umad_release_dev); + return ret; } static int ib_umad_sm_close(struct inode *inode, struct file *filp) @@ -623,6 +685,8 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); up(&port->sm_sem); + kref_put(&port->umad_dev->ref, ib_umad_release_dev); + return ret; } @@ -642,6 +706,9 @@ static ssize_t show_ibdev(struct class_device *class_dev, char *buf) { struct ib_umad_port *port = class_get_devdata(class_dev); + if (!port) + return -ENODEV; + return sprintf(buf, "%s\n", port->ib_dev->name); } static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); @@ -650,38 +717,13 @@ static ssize_t show_port(struct class_device *class_dev, char *buf) { struct ib_umad_port *port = class_get_devdata(class_dev); + if (!port) + return -ENODEV; + return sprintf(buf, "%d\n", port->port_num); } static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static void ib_umad_release_dev(struct kref *ref) -{ - struct ib_umad_device *dev = - container_of(ref, struct ib_umad_device, ref); - - kfree(dev); -} - -static void ib_umad_release_port(struct class_device *class_dev) -{ - struct ib_umad_port *port = class_get_devdata(class_dev); - - if (class_dev == &port->class_dev) { - cdev_del(&port->dev); - clear_bit(port->devnum, dev_map); - } else { - cdev_del(&port->sm_dev); - clear_bit(port->sm_devnum, dev_map); - } - - kref_put(&port->umad_dev->ref, ib_umad_release_dev); -} - -static struct class umad_class = { - .name = "infiniband_mad", - .release = ib_umad_release_port -}; - static ssize_t show_abi_version(struct class *class, char *buf) { return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION); @@ -691,89 +733,102 @@ static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); static int ib_umad_init_port(struct ib_device *device, int port_num, struct ib_umad_port *port) { - spin_lock(&map_lock); - port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); - if (port->devnum >= IB_UMAD_MAX_PORTS) { - spin_unlock(&map_lock); + spin_lock(&port_lock); + port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); + if (port->dev_num >= IB_UMAD_MAX_PORTS) { + spin_unlock(&port_lock); return -1; } - port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS); - if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) { - spin_unlock(&map_lock); - return -1; - } - set_bit(port->devnum, dev_map); - set_bit(port->sm_devnum, dev_map); - spin_unlock(&map_lock); + set_bit(port->dev_num, dev_map); + spin_unlock(&port_lock); port->ib_dev = device; port->port_num = port_num; init_MUTEX(&port->sm_sem); - cdev_init(&port->dev, &umad_fops); - port->dev.owner = THIS_MODULE; - kobject_set_name(&port->dev.kobj, "umad%d", port->devnum); - if (cdev_add(&port->dev, base_dev + port->devnum, 1)) + port->dev = cdev_alloc(); + if (!port->dev) return -1; - - port->class_dev.class = &umad_class; - port->class_dev.dev = device->dma_device; - port->class_dev.devt = port->dev.dev; - - snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum); - - if (class_device_register(&port->class_dev)) + port->dev->owner = THIS_MODULE; + port->dev->ops = &umad_fops; + kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num); + if (cdev_add(port->dev, base_dev + port->dev_num, 1)) goto err_cdev; - class_set_devdata(&port->class_dev, port); - kref_get(&port->umad_dev->ref); + port->class_dev = class_device_create(umad_class, port->dev->dev, + device->dma_device, + "umad%d", port->dev_num); + if (IS_ERR(port->class_dev)) + goto err_cdev; - if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev)) + if (class_device_create_file(port->class_dev, &class_device_attr_ibdev)) goto err_class; - if (class_device_create_file(&port->class_dev, &class_device_attr_port)) + if (class_device_create_file(port->class_dev, &class_device_attr_port)) goto err_class; - cdev_init(&port->sm_dev, &umad_sm_fops); - port->sm_dev.owner = THIS_MODULE; - kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS); - if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1)) - return -1; - - port->sm_class_dev.class = &umad_class; - port->sm_class_dev.dev = device->dma_device; - port->sm_class_dev.devt = port->sm_dev.dev; - - snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS); - - if (class_device_register(&port->sm_class_dev)) + port->sm_dev = cdev_alloc(); + if (!port->sm_dev) + goto err_class; + port->sm_dev->owner = THIS_MODULE; + port->sm_dev->ops = &umad_sm_fops; + kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num); + if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) goto err_sm_cdev; - class_set_devdata(&port->sm_class_dev, port); - kref_get(&port->umad_dev->ref); + port->sm_class_dev = class_device_create(umad_class, port->sm_dev->dev, + device->dma_device, + "issm%d", port->dev_num); + if (IS_ERR(port->sm_class_dev)) + goto err_sm_cdev; - if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev)) + class_set_devdata(port->class_dev, port); + class_set_devdata(port->sm_class_dev, port); + + if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev)) goto err_sm_class; - if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port)) + if (class_device_create_file(port->sm_class_dev, &class_device_attr_port)) goto err_sm_class; + spin_lock(&port_lock); + umad_port[port->dev_num] = port; + spin_unlock(&port_lock); + return 0; err_sm_class: - class_device_unregister(&port->sm_class_dev); + class_device_destroy(umad_class, port->sm_dev->dev); err_sm_cdev: - cdev_del(&port->sm_dev); + cdev_del(port->sm_dev); err_class: - class_device_unregister(&port->class_dev); + class_device_destroy(umad_class, port->dev->dev); err_cdev: - cdev_del(&port->dev); - clear_bit(port->devnum, dev_map); + cdev_del(port->dev); + clear_bit(port->dev_num, dev_map); return -1; } +static void ib_umad_kill_port(struct ib_umad_port *port) +{ + class_set_devdata(port->class_dev, NULL); + class_set_devdata(port->sm_class_dev, NULL); + + class_device_destroy(umad_class, port->dev->dev); + class_device_destroy(umad_class, port->sm_dev->dev); + + cdev_del(port->dev); + cdev_del(port->sm_dev); + + spin_lock(&port_lock); + umad_port[port->dev_num] = NULL; + spin_unlock(&port_lock); + + clear_bit(port->dev_num, dev_map); +} + static void ib_umad_add_one(struct ib_device *device) { struct ib_umad_device *umad_dev; @@ -809,10 +864,8 @@ static void ib_umad_add_one(struct ib_device *device) return; err: - while (--i >= s) { - class_device_unregister(&umad_dev->port[i - s].class_dev); - class_device_unregister(&umad_dev->port[i - s].sm_class_dev); - } + while (--i >= s) + ib_umad_kill_port(&umad_dev->port[i]); kref_put(&umad_dev->ref, ib_umad_release_dev); } @@ -825,10 +878,8 @@ static void ib_umad_remove_one(struct ib_device *device) if (!umad_dev) return; - for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) { - class_device_unregister(&umad_dev->port[i].class_dev); - class_device_unregister(&umad_dev->port[i].sm_class_dev); - } + for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) + ib_umad_kill_port(&umad_dev->port[i]); kref_put(&umad_dev->ref, ib_umad_release_dev); } @@ -837,8 +888,6 @@ static int __init ib_umad_init(void) { int ret; - spin_lock_init(&map_lock); - ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, "infiniband_mad"); if (ret) { @@ -846,13 +895,14 @@ static int __init ib_umad_init(void) goto out; } - ret = class_register(&umad_class); - if (ret) { + umad_class = class_create(THIS_MODULE, "infiniband_mad"); + if (IS_ERR(umad_class)) { + ret = PTR_ERR(umad_class); printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n"); goto out_chrdev; } - ret = class_create_file(&umad_class, &class_attr_abi_version); + ret = class_create_file(umad_class, &class_attr_abi_version); if (ret) { printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); goto out_class; @@ -867,7 +917,7 @@ static int __init ib_umad_init(void) return 0; out_class: - class_unregister(&umad_class); + class_destroy(umad_class); out_chrdev: unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); @@ -879,7 +929,7 @@ static int __init ib_umad_init(void) static void __exit ib_umad_cleanup(void) { ib_unregister_client(&umad_client); - class_unregister(&umad_class); + class_destroy(umad_class); unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); } From 70a30e16a8a9d22396a4d1e96af86e43594df584 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 28 Oct 2005 15:38:26 -0700 Subject: [PATCH 0804/1940] [IB] uverbs: Fix device lifetime problems Move ib_uverbs module to using cdev_alloc() and class_device_create() so that we can handle device lifetime properly. Now we can make sure we keep all of our data structures around until the last way to reach them is gone. Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs.h | 36 ++++- drivers/infiniband/core/uverbs_cmd.c | 38 +---- drivers/infiniband/core/uverbs_main.c | 205 +++++++++++++++++++------- 3 files changed, 183 insertions(+), 96 deletions(-) diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 63c8085c0c98..031cdf3c066d 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -39,20 +39,38 @@ #ifndef UVERBS_H #define UVERBS_H -/* Include device.h and fs.h until cdev.h is self-sufficient */ -#include -#include -#include #include #include #include #include +/* + * Our lifetime rules for these structs are the following: + * + * struct ib_uverbs_device: One reference is held by the module and + * released in ib_uverbs_remove_one(). Another reference is taken by + * ib_uverbs_open() each time the character special file is opened, + * and released in ib_uverbs_release_file() when the file is released. + * + * struct ib_uverbs_file: One reference is held by the VFS and + * released when the file is closed. Another reference is taken when + * an asynchronous event queue file is created and released when the + * event file is closed. + * + * struct ib_uverbs_event_file: One reference is held by the VFS and + * released when the file is closed. For asynchronous event files, + * another reference is held by the corresponding main context file + * and released when that file is closed. For completion event files, + * a reference is taken when a CQ is created that uses the file, and + * released when the CQ is destroyed. + */ + struct ib_uverbs_device { + struct kref ref; int devnum; - struct cdev dev; - struct class_device class_dev; + struct cdev *dev; + struct class_device *class_dev; struct ib_device *ib_dev; int num_comp_vectors; }; @@ -115,6 +133,12 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, void ib_uverbs_release_event_file(struct kref *ref); struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); +void ib_uverbs_release_ucq(struct ib_uverbs_file *file, + struct ib_uverbs_event_file *ev_file, + struct ib_ucq_object *uobj); +void ib_uverbs_release_uevent(struct ib_uverbs_file *file, + struct ib_uevent_object *uobj); + void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 14583bb6e2c0..8c89abc8c764 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -35,6 +35,7 @@ */ #include +#include #include @@ -114,7 +115,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, kref_get(&file->async_file->ref); kref_get(&file->ref); - file->ucontext = ucontext; + file->ucontext = ucontext; fd_install(resp.async_fd, filp); @@ -761,7 +762,6 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, struct ib_cq *cq; struct ib_ucq_object *uobj; struct ib_uverbs_event_file *ev_file; - struct ib_uverbs_event *evt, *tmp; u64 user_handle; int ret = -EINVAL; @@ -790,23 +790,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - if (ev_file) { - spin_lock_irq(&ev_file->lock); - list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { - list_del(&evt->list); - kfree(evt); - } - spin_unlock_irq(&ev_file->lock); - - kref_put(&ev_file->ref, ib_uverbs_release_event_file); - } - - spin_lock_irq(&file->async_file->lock); - list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) { - list_del(&evt->list); - kfree(evt); - } - spin_unlock_irq(&file->async_file->lock); + ib_uverbs_release_ucq(file, ev_file, uobj); resp.comp_events_reported = uobj->comp_events_reported; resp.async_events_reported = uobj->async_events_reported; @@ -1043,7 +1027,6 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, struct ib_uverbs_destroy_qp_resp resp; struct ib_qp *qp; struct ib_uevent_object *uobj; - struct ib_uverbs_event *evt, *tmp; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) @@ -1069,12 +1052,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - spin_lock_irq(&file->async_file->lock); - list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { - list_del(&evt->list); - kfree(evt); - } - spin_unlock_irq(&file->async_file->lock); + ib_uverbs_release_uevent(file, uobj); resp.events_reported = uobj->events_reported; @@ -1741,7 +1719,6 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, struct ib_uverbs_destroy_srq_resp resp; struct ib_srq *srq; struct ib_uevent_object *uobj; - struct ib_uverbs_event *evt, *tmp; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) @@ -1767,12 +1744,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, list_del(&uobj->uobject.list); up(&file->mutex); - spin_lock_irq(&file->async_file->lock); - list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { - list_del(&evt->list); - kfree(evt); - } - spin_unlock_irq(&file->async_file->lock); + ib_uverbs_release_uevent(file, uobj); resp.events_reported = uobj->events_reported; diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 251c752a7ae6..ac08d2c93ea1 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -63,6 +64,8 @@ enum { #define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR) +static struct class *uverbs_class; + DECLARE_MUTEX(ib_uverbs_idr_mutex); DEFINE_IDR(ib_uverbs_pd_idr); DEFINE_IDR(ib_uverbs_mr_idr); @@ -73,6 +76,7 @@ DEFINE_IDR(ib_uverbs_qp_idr); DEFINE_IDR(ib_uverbs_srq_idr); static spinlock_t map_lock; +static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, @@ -110,7 +114,54 @@ static struct vfsmount *uverbs_event_mnt; static void ib_uverbs_add_one(struct ib_device *device); static void ib_uverbs_remove_one(struct ib_device *device); -static int ib_dealloc_ucontext(struct ib_ucontext *context) +static void ib_uverbs_release_dev(struct kref *ref) +{ + struct ib_uverbs_device *dev = + container_of(ref, struct ib_uverbs_device, ref); + + kfree(dev); +} + +void ib_uverbs_release_ucq(struct ib_uverbs_file *file, + struct ib_uverbs_event_file *ev_file, + struct ib_ucq_object *uobj) +{ + struct ib_uverbs_event *evt, *tmp; + + if (ev_file) { + spin_lock_irq(&ev_file->lock); + list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { + list_del(&evt->list); + kfree(evt); + } + spin_unlock_irq(&ev_file->lock); + + kref_put(&ev_file->ref, ib_uverbs_release_event_file); + } + + spin_lock_irq(&file->async_file->lock); + list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) { + list_del(&evt->list); + kfree(evt); + } + spin_unlock_irq(&file->async_file->lock); +} + +void ib_uverbs_release_uevent(struct ib_uverbs_file *file, + struct ib_uevent_object *uobj) +{ + struct ib_uverbs_event *evt, *tmp; + + spin_lock_irq(&file->async_file->lock); + list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { + list_del(&evt->list); + kfree(evt); + } + spin_unlock_irq(&file->async_file->lock); +} + +static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, + struct ib_ucontext *context) { struct ib_uobject *uobj, *tmp; @@ -129,26 +180,36 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); + struct ib_uevent_object *uevent = + container_of(uobj, struct ib_uevent_object, uobject); idr_remove(&ib_uverbs_qp_idr, uobj->id); ib_destroy_qp(qp); list_del(&uobj->list); - kfree(container_of(uobj, struct ib_uevent_object, uobject)); + ib_uverbs_release_uevent(file, uevent); + kfree(uevent); } list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id); + struct ib_uverbs_event_file *ev_file = cq->cq_context; + struct ib_ucq_object *ucq = + container_of(uobj, struct ib_ucq_object, uobject); idr_remove(&ib_uverbs_cq_idr, uobj->id); ib_destroy_cq(cq); list_del(&uobj->list); - kfree(container_of(uobj, struct ib_ucq_object, uobject)); + ib_uverbs_release_ucq(file, ev_file, ucq); + kfree(ucq); } list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id); + struct ib_uevent_object *uevent = + container_of(uobj, struct ib_uevent_object, uobject); idr_remove(&ib_uverbs_srq_idr, uobj->id); ib_destroy_srq(srq); list_del(&uobj->list); - kfree(container_of(uobj, struct ib_uevent_object, uobject)); + ib_uverbs_release_uevent(file, uevent); + kfree(uevent); } /* XXX Free MWs */ @@ -187,6 +248,8 @@ static void ib_uverbs_release_file(struct kref *ref) container_of(ref, struct ib_uverbs_file, ref); module_put(file->device->ib_dev->owner); + kref_put(&file->device->ref, ib_uverbs_release_dev); + kfree(file); } @@ -552,36 +615,58 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) static int ib_uverbs_open(struct inode *inode, struct file *filp) { - struct ib_uverbs_device *dev = - container_of(inode->i_cdev, struct ib_uverbs_device, dev); + struct ib_uverbs_device *dev; struct ib_uverbs_file *file; + int ret; - if (!try_module_get(dev->ib_dev->owner)) - return -ENODEV; + spin_lock(&map_lock); + dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; + if (dev) + kref_get(&dev->ref); + spin_unlock(&map_lock); + + if (!dev) + return -ENXIO; + + if (!try_module_get(dev->ib_dev->owner)) { + ret = -ENODEV; + goto err; + } file = kmalloc(sizeof *file, GFP_KERNEL); if (!file) { - module_put(dev->ib_dev->owner); - return -ENOMEM; + ret = -ENOMEM; + goto err_module; } - file->device = dev; - file->ucontext = NULL; + file->device = dev; + file->ucontext = NULL; + file->async_file = NULL; kref_init(&file->ref); init_MUTEX(&file->mutex); filp->private_data = file; return 0; + +err_module: + module_put(dev->ib_dev->owner); + +err: + kref_put(&dev->ref, ib_uverbs_release_dev); + + return ret; } static int ib_uverbs_close(struct inode *inode, struct file *filp) { struct ib_uverbs_file *file = filp->private_data; - ib_dealloc_ucontext(file->ucontext); + ib_uverbs_cleanup_ucontext(file, file->ucontext); + + if (file->async_file) + kref_put(&file->async_file->ref, ib_uverbs_release_event_file); - kref_put(&file->async_file->ref, ib_uverbs_release_event_file); kref_put(&file->ref, ib_uverbs_release_file); return 0; @@ -610,8 +695,10 @@ static struct ib_client uverbs_client = { static ssize_t show_ibdev(struct class_device *class_dev, char *buf) { - struct ib_uverbs_device *dev = - container_of(class_dev, struct ib_uverbs_device, class_dev); + struct ib_uverbs_device *dev = class_get_devdata(class_dev); + + if (!dev) + return -ENODEV; return sprintf(buf, "%s\n", dev->ib_dev->name); } @@ -619,28 +706,15 @@ static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf) { - struct ib_uverbs_device *dev = - container_of(class_dev, struct ib_uverbs_device, class_dev); + struct ib_uverbs_device *dev = class_get_devdata(class_dev); + + if (!dev) + return -ENODEV; return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver); } static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); -static void ib_uverbs_release_class_dev(struct class_device *class_dev) -{ - struct ib_uverbs_device *dev = - container_of(class_dev, struct ib_uverbs_device, class_dev); - - cdev_del(&dev->dev); - clear_bit(dev->devnum, dev_map); - kfree(dev); -} - -static struct class uverbs_class = { - .name = "infiniband_verbs", - .release = ib_uverbs_release_class_dev -}; - static ssize_t show_abi_version(struct class *class, char *buf) { return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION); @@ -660,6 +734,8 @@ static void ib_uverbs_add_one(struct ib_device *device) memset(uverbs_dev, 0, sizeof *uverbs_dev); + kref_init(&uverbs_dev->ref); + spin_lock(&map_lock); uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) { @@ -672,40 +748,45 @@ static void ib_uverbs_add_one(struct ib_device *device) uverbs_dev->ib_dev = device; uverbs_dev->num_comp_vectors = 1; - if (device->mmap) - cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops); - else - cdev_init(&uverbs_dev->dev, &uverbs_fops); - uverbs_dev->dev.owner = THIS_MODULE; - kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum); - if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) + uverbs_dev->dev = cdev_alloc(); + if (!uverbs_dev->dev) goto err; - - uverbs_dev->class_dev.class = &uverbs_class; - uverbs_dev->class_dev.dev = device->dma_device; - uverbs_dev->class_dev.devt = uverbs_dev->dev.dev; - snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum); - if (class_device_register(&uverbs_dev->class_dev)) + uverbs_dev->dev->owner = THIS_MODULE; + uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; + kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum); + if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) goto err_cdev; - if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev)) + uverbs_dev->class_dev = class_device_create(uverbs_class, uverbs_dev->dev->dev, + device->dma_device, + "uverbs%d", uverbs_dev->devnum); + if (IS_ERR(uverbs_dev->class_dev)) + goto err_cdev; + + class_set_devdata(uverbs_dev->class_dev, uverbs_dev); + + if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev)) goto err_class; - if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_abi_version)) + if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version)) goto err_class; + spin_lock(&map_lock); + dev_table[uverbs_dev->devnum] = uverbs_dev; + spin_unlock(&map_lock); + ib_set_client_data(device, &uverbs_client, uverbs_dev); return; err_class: - class_device_unregister(&uverbs_dev->class_dev); + class_device_destroy(uverbs_class, uverbs_dev->dev->dev); err_cdev: - cdev_del(&uverbs_dev->dev); + cdev_del(uverbs_dev->dev); clear_bit(uverbs_dev->devnum, dev_map); err: - kfree(uverbs_dev); + kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); return; } @@ -716,7 +797,16 @@ static void ib_uverbs_remove_one(struct ib_device *device) if (!uverbs_dev) return; - class_device_unregister(&uverbs_dev->class_dev); + class_set_devdata(uverbs_dev->class_dev, NULL); + class_device_destroy(uverbs_class, uverbs_dev->dev->dev); + cdev_del(uverbs_dev->dev); + + spin_lock(&map_lock); + dev_table[uverbs_dev->devnum] = NULL; + spin_unlock(&map_lock); + + clear_bit(uverbs_dev->devnum, dev_map); + kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); } static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags, @@ -746,13 +836,14 @@ static int __init ib_uverbs_init(void) goto out; } - ret = class_register(&uverbs_class); - if (ret) { + uverbs_class = class_create(THIS_MODULE, "infiniband_verbs"); + if (IS_ERR(uverbs_class)) { + ret = PTR_ERR(uverbs_class); printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n"); goto out_chrdev; } - ret = class_create_file(&uverbs_class, &class_attr_abi_version); + ret = class_create_file(uverbs_class, &class_attr_abi_version); if (ret) { printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n"); goto out_class; @@ -786,7 +877,7 @@ static int __init ib_uverbs_init(void) unregister_filesystem(&uverbs_event_fs); out_class: - class_unregister(&uverbs_class); + class_destroy(uverbs_class); out_chrdev: unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); @@ -800,7 +891,7 @@ static void __exit ib_uverbs_cleanup(void) ib_unregister_client(&uverbs_client); mntput(uverbs_event_mnt); unregister_filesystem(&uverbs_event_fs); - class_unregister(&uverbs_class); + class_destroy(uverbs_class); unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); idr_destroy(&ib_uverbs_pd_idr); idr_destroy(&ib_uverbs_mr_idr); From 64a0c1c81e300f0f56f26604c81040784e3717f0 Mon Sep 17 00:00:00 2001 From: Ivan Skytte Jorgensen Date: Fri, 28 Oct 2005 15:39:02 -0700 Subject: [PATCH 0805/1940] [SCTP] Do not allow unprivileged programs initiating new associations on privileged ports. Signed-off-by: Ivan Skytte Jorgensen Signed-off-by: Sridhar Samudrala --- net/sctp/socket.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 97b556c1c450..b529af5e6f2a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1010,6 +1010,19 @@ static int __sctp_connect(struct sock* sk, err = -EAGAIN; goto out_free; } + } else { + /* + * If an unprivileged user inherits a 1-many + * style socket with open associations on a + * privileged port, it MAY be permitted to + * accept new associations, but it SHOULD NOT + * be permitted to open new associations. + */ + if (ep->base.bind_addr.port < PROT_SOCK && + !capable(CAP_NET_BIND_SERVICE)) { + err = -EACCES; + goto out_free; + } } scope = sctp_scope(&to); @@ -1515,6 +1528,19 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, err = -EAGAIN; goto out_unlock; } + } else { + /* + * If an unprivileged user inherits a one-to-many + * style socket with open associations on a privileged + * port, it MAY be permitted to accept new associations, + * but it SHOULD NOT be permitted to open new + * associations. + */ + if (ep->base.bind_addr.port < PROT_SOCK && + !capable(CAP_NET_BIND_SERVICE)) { + err = -EACCES; + goto out_unlock; + } } scope = sctp_scope(&to); From 4647722673994787bfa294a163fcb6955b93d417 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Thu, 27 Oct 2005 15:51:13 -0700 Subject: [PATCH 0806/1940] [SCSI] Fix issue reported by coverity in drivers/scsi/scsi_ioctl.c This patch attempts to fix an issue found in drivers/scsi/scsi_ioctl.c by Coverity. Error reported: CID: 3437 Checker: FORWARD_NULL (help) File: /export2/p4-coverity/mc2/linux26/drivers/scsi/scsi_ioctl.c Function: scsi_ioctl_send_command Description: Variable "buf" tracked as NULL was passed to a function that dereferences it. Patch description: buf can be NULL if inlen and outlen are both 0. This patch adds check if the length is non-zero before calling copy from/to user. Signed-off-by: Jayachandran C. Signed-off-by: James Bottomley --- drivers/scsi/scsi_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 26f5bc6d9c82..0bba7d8eebb0 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -278,7 +278,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, * Obtain the data to be sent to the device (if any). */ - if(copy_from_user(buf, cmd_in + cmdlen, inlen)) + if(inlen && copy_from_user(buf, cmd_in + cmdlen, inlen)) goto error; switch (opcode) { @@ -322,7 +322,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, if (copy_to_user(cmd_in, sense, sb_len)) result = -EFAULT; } else { - if (copy_to_user(cmd_in, buf, outlen)) + if (outlen && copy_to_user(cmd_in, buf, outlen)) result = -EFAULT; } From 80d904c43b11105c16395b240078ccc2f7ac6074 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Tue, 18 Oct 2005 17:11:16 -0700 Subject: [PATCH 0807/1940] [SCSI] sr: remove dead code This patch fixes an issue reported in drivers/scsi/sr.c by Coverity Error reported: Pointer returned from "scsi_cd" is never used Patch description: Remove the scsi_cd() call as it does not have any effect. Signed-off-by: Jayachandran C. Signed-off-by: James Bottomley --- drivers/scsi/sr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 9e267c6d3a43..3067e5a7b75e 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -456,7 +456,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) static int sr_block_open(struct inode *inode, struct file *file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); + struct scsi_cd *cd; int ret = 0; if(!(cd = scsi_cd_get(disk))) From 0e1f60609258e18ec0a0477c646101212822d387 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 28 Oct 2005 15:52:13 -0700 Subject: [PATCH 0808/1940] [IA64] fix warning unused variable `g' 4ac0068f44f192f2de95a7bb36df3e19767a45fb forgot to delete the declaration of this variable which is no longer used. Signed-off-by: Tony Luck --- arch/ia64/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 9a9c1bd01dbc..4b19d0410632 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -587,7 +587,7 @@ thread_matches (struct task_struct *thread, unsigned long addr) static struct task_struct * find_thread_for_addr (struct task_struct *child, unsigned long addr) { - struct task_struct *g, *p; + struct task_struct *p; struct mm_struct *mm; struct list_head *this, *next; int mm_users; From b6a1d5f88473138497d8694ddf174e8e91300068 Mon Sep 17 00:00:00 2001 From: "Martin J. Bligh" Date: Fri, 28 Oct 2005 15:14:44 -0700 Subject: [PATCH 0809/1940] [PATCH] e1000: remove warning about e1000_suspend e1000_suspend is only used under #ifdef CONFIG_PM. Move the declaration of it to be the same way, just like e1000_resume, otherwise gcc whines on compile. I offer as evidence: static struct pci_driver e1000_driver = { .name = e1000_driver_name, .id_table = e1000_pci_tbl, .probe = e1000_probe, .remove = __devexit_p(e1000_remove), /* Power Managment Hooks */ #ifdef CONFIG_PM .suspend = e1000_suspend, .resume = e1000_resume #endif }; Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6b72f6acdd54..a0023f357cb1 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4193,6 +4193,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) return 0; } +#ifdef CONFIG_PM static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -4289,7 +4290,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -#ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev) { From a1bfcd97414d3e9b3c96f27d9b1a1e76c9543ba6 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Fri, 28 Oct 2005 15:14:46 -0700 Subject: [PATCH 0810/1940] [PATCH] eepro.c: module_param_array cleanup num_params is unused (and unusable in this form). Signed-off-by: Florin Malita Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/eepro.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index dcb3028bb60f..1ce2c675b8a7 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1797,10 +1797,9 @@ MODULE_AUTHOR("Pascal Dupuis and others"); MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver"); MODULE_LICENSE("GPL"); -static int num_params; -module_param_array(io, int, &num_params, 0); -module_param_array(irq, int, &num_params, 0); -module_param_array(mem, int, &num_params, 0); +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(mem, int, NULL, 0); module_param(autodetect, int, 0); MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)"); MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); From 46e178535836dcd7ef92f179218628d101892c59 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 28 Oct 2005 15:14:47 -0700 Subject: [PATCH 0811/1940] [PATCH] b44: fix suspend/resume Fix suspend/resume on b44 by freeing/reacquiring irq. Otherwise it hangs on resume. Signed-off-by: Pavel Machek Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5485e3b1cd35..0ee3e27969c6 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2041,6 +2041,8 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) b44_free_rings(bp); spin_unlock_irq(&bp->lock); + + free_irq(dev->irq, dev); pci_disable_device(pdev); return 0; } @@ -2057,6 +2059,9 @@ static int b44_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; + if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev)) + printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); + spin_lock_irq(&bp->lock); b44_init_rings(bp); From a7ec15da65ab64c5f97beedc4ff21cf3e0ae71c0 Mon Sep 17 00:00:00 2001 From: Ravikiran G Thirumalai Date: Fri, 28 Oct 2005 15:14:49 -0700 Subject: [PATCH 0812/1940] [PATCH] e1000: use vmalloc_node() Allocate node local tx and rx descriptors for the e1000 driver Signed-off-by: Ravikiran Thirumalai Cc: Christoph Lameter Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index a0023f357cb1..d97ad89f5dd2 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1149,7 +1149,8 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter, int size; size = sizeof(struct e1000_buffer) * txdr->count; - txdr->buffer_info = vmalloc(size); + + txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus)); if(!txdr->buffer_info) { DPRINTK(PROBE, ERR, "Unable to allocate memory for the transmit descriptor ring\n"); @@ -1366,7 +1367,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter, int size, desc_len; size = sizeof(struct e1000_buffer) * rxdr->count; - rxdr->buffer_info = vmalloc(size); + rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus)); if (!rxdr->buffer_info) { DPRINTK(PROBE, ERR, "Unable to allocate memory for the receive descriptor ring\n"); From 63f57fb69b017230c77c40f1713e40885ae6d159 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 28 Oct 2005 15:14:51 -0700 Subject: [PATCH 0813/1940] [PATCH] revert "orinoco: Information leakage due to incorrect padding" Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/wireless/orinoco.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index d3d4ec9e242e..70a3477a2061 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -490,7 +490,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - /* Check packet length, pad short packets, round up odd length */ + /* Length of the packet body */ + /* FIXME: what if the skb is smaller than this? */ len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN); skb = skb_padto(skb, len); if (skb == NULL) @@ -547,7 +548,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) p = skb->data; } - err = hermes_bap_pwrite(hw, USER_BAP, p, data_len, + /* Round up for odd length packets */ + err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2), txfid, data_off); if (err) { printk(KERN_ERR "%s: Error %d writing packet to BAP\n", From 2c36ed22c6f64de94c6c3b7258dd7285bb093401 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 28 Oct 2005 15:14:52 -0700 Subject: [PATCH 0814/1940] [PATCH] Better fixup for the orinoco driver The latest kernel added a pretty ugly fix for the orinoco etherleak bug which contains bogus skb->len checks already done by the caller and causes copies of all odd sized frames (which are quite common) While the skb->len check should be ripped out the other fix is harder to do properly so I'm proposing for this the -mm tree only until next 2.6.x so that it gets tested. Instead of copying buffers around blindly this code implements a padding aware version of the hermes buffer writing function which does padding as the buffer is loaded and thus more cleanly and without bogus 1.5K copies. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/wireless/hermes.c | 38 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/hermes.h | 2 ++ drivers/net/wireless/orinoco.c | 11 ++++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c index eba0d9d2b7c5..579480dad374 100644 --- a/drivers/net/wireless/hermes.c +++ b/drivers/net/wireless/hermes.c @@ -444,6 +444,43 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len, return err; } +/* Write a block of data to the chip's buffer with padding if + * neccessary, via the BAP. Synchronization/serialization is the + * caller's problem. len must be even. + * + * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware + */ +int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len, + u16 id, u16 offset) +{ + int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; + int err = 0; + + if (len < 0 || len % 2 || data_len > len) + return -EINVAL; + + err = hermes_bap_seek(hw, bap, id, offset); + if (err) + goto out; + + /* Transfer all the complete words of data */ + hermes_write_words(hw, dreg, buf, data_len/2); + /* If there is an odd byte left over pad and transfer it */ + if (data_len & 1) { + u8 end[2]; + end[1] = 0; + end[0] = ((unsigned char *)buf)[data_len - 1]; + hermes_write_words(hw, dreg, end, 1); + data_len ++; + } + /* Now send zeros for the padding */ + if (data_len < len) + hermes_clear_words(hw, dreg, (len - data_len) / 2); + /* Complete */ + out: + return err; +} + /* Read a Length-Type-Value record from the card. * * If length is NULL, we ignore the length read from the card, and @@ -531,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate); EXPORT_SYMBOL(hermes_bap_pread); EXPORT_SYMBOL(hermes_bap_pwrite); +EXPORT_SYMBOL(hermes_bap_pwrite_pad); EXPORT_SYMBOL(hermes_read_ltv); EXPORT_SYMBOL(hermes_write_ltv); diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h index ad28e3294360..a6bd472d75d4 100644 --- a/drivers/net/wireless/hermes.h +++ b/drivers/net/wireless/hermes.h @@ -376,6 +376,8 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len, u16 id, u16 offset); int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len, u16 id, u16 offset); +int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, + unsigned data_len, unsigned len, u16 id, u16 offset); int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen, u16 *length, void *buf); int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 70a3477a2061..488ab06fb79f 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -542,14 +542,21 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_errors++; goto fail; } + /* Actual xfer length - allow for padding */ + len = ALIGN(data_len, 2); + if (len < ETH_ZLEN - ETH_HLEN) + len = ETH_ZLEN - ETH_HLEN; } else { /* IEEE 802.3 frame */ data_len = len + ETH_HLEN; data_off = HERMES_802_3_OFFSET; p = skb->data; + /* Actual xfer length - round up for odd length packets */ + len = ALIGN(data_len, 2); + if (len < ETH_ZLEN) + len = ETH_ZLEN; } - /* Round up for odd length packets */ - err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2), + err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len, txfid, data_off); if (err) { printk(KERN_ERR "%s: Error %d writing packet to BAP\n", From 977e74b5f60de3df9831897b726c16870878eee4 Mon Sep 17 00:00:00 2001 From: Ashutosh Naik Date: Fri, 28 Oct 2005 15:14:53 -0700 Subject: [PATCH 0815/1940] [PATCH] e1000: Fixes e1000_suspend warning when CONFIG_PM is not enabled drivers/net/e1000/e1000_main.c:3645: warning: `e1000_suspend' defined but not used Signed-off-by: Ashutosh Naik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index d97ad89f5dd2..efbbda7cbcbf 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -191,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); -static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); #ifdef CONFIG_PM +static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int e1000_resume(struct pci_dev *pdev); #endif From 4cce3390c998600f6648e075e475cf8f6dd8cebe Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 28 Oct 2005 16:38:15 -0700 Subject: [PATCH 0816/1940] [IB] fix up class_device_create() calls Fix class_device_create() calls to match the new prototype which takes a parent device pointer. Signed-off-by: Roland Dreier --- drivers/infiniband/core/user_mad.c | 4 ++-- drivers/infiniband/core/uverbs_main.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 9e49816d7282..97128e25f78b 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -755,7 +755,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, if (cdev_add(port->dev, base_dev + port->dev_num, 1)) goto err_cdev; - port->class_dev = class_device_create(umad_class, port->dev->dev, + port->class_dev = class_device_create(umad_class, NULL, port->dev->dev, device->dma_device, "umad%d", port->dev_num); if (IS_ERR(port->class_dev)) @@ -775,7 +775,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) goto err_sm_cdev; - port->sm_class_dev = class_device_create(umad_class, port->sm_dev->dev, + port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev, device->dma_device, "issm%d", port->dev_num); if (IS_ERR(port->sm_class_dev)) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index ac08d2c93ea1..0eb38f479b39 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -757,7 +757,8 @@ static void ib_uverbs_add_one(struct ib_device *device) if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) goto err_cdev; - uverbs_dev->class_dev = class_device_create(uverbs_class, uverbs_dev->dev->dev, + uverbs_dev->class_dev = class_device_create(uverbs_class, NULL, + uverbs_dev->dev->dev, device->dma_device, "uverbs%d", uverbs_dev->devnum); if (IS_ERR(uverbs_dev->class_dev)) From 72f30b6f2f5f68dd426e9fe83817b882c2d04e50 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 27 Sep 2005 10:19:39 -0700 Subject: [PATCH 0817/1940] [PATCH] USB: ehci.patch (earlier irq disable) This tweaks the EHCI reboot notifier to also halt the EHCI controller, and makes that halt code force IRQs off. Both should always have been done. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/host/ehci-hcd.c | 8 ++++++++ 1 file changed, 8 insertions(+) --- drivers/usb/host/ehci-hcd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f5eb9e7b5b18..b3eb02613bff 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *ehci) { u32 temp = readl (&ehci->regs->status); + /* disable any irqs left enabled by previous code */ + writel (0, &ehci->regs->intr_enable); + if ((temp & STS_HALT) != 0) return 0; @@ -335,12 +338,17 @@ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) #endif +/* Reboot notifiers kick in for silicon on any bus (not just pci, etc). + * This forcibly disables dma and IRQs, helping kexec and other cases + * where the next system software may expect clean state. + */ static int ehci_reboot (struct notifier_block *self, unsigned long code, void *null) { struct ehci_hcd *ehci; ehci = container_of (self, struct ehci_hcd, reboot_notifier); + (void) ehci_halt (ehci); /* make BIOS/etc use companion controller during reboot */ writel (0, &ehci->regs->configured_flag); From c9c7746dd333c12f482af2f1e63ea7eafc7cd529 Mon Sep 17 00:00:00 2001 From: Rui Santos Date: Fri, 23 Sep 2005 20:06:50 +0100 Subject: [PATCH 0818/1940] [PATCH] USB: ftdi: Artemis and ATIK based USB astronomical CCD cameras This patch enables direct kernel support for the Artemis and ATIK astronomical based USB CCD cameras. Since all communications with this camera are done via an FTDI 245BM chip, it was only needed to specify the ProductID and VendorID of all three devices. In what tests are concerned, data was transfered from and to the FTDI at the chips Top speed (360KB/s). Signed-off-by: Rui Santos Signed-off-by: Greg Kroah-Hartman drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) --- drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5a8631c8a4a7..8c12a0acf10d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -471,6 +471,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 2c35d74cc6d6..7c65d46c7598 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -198,6 +198,19 @@ /* an infrared receiver for user access control with IR tags */ #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ +/* + * Definitions for Artemis astronomical USB based cameras + * Check it at http://www.artemisccd.co.uk/ + */ +#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ + +/* + * Definitions for ATIK Instruments astronomical USB based cameras + * Check it at http://www.atik-instruments.com/ + */ +#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Camera */ +#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Camera */ + /* * Protego product ids */ From 8da608caa07d5c9745ec86bf7c25ad423352f9a4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0819/1940] [PATCH] USB: disable tasklet if rtl8150 device is removed while active. This fixes a oops seen in the wild. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/rtl8150.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index c3d4e3589e30..787dd3591d6a 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -909,6 +909,7 @@ static void rtl8150_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (dev) { set_bit(RTL8150_UNPLUG, &dev->flags); + tasklet_disable(&dev->tl); unregister_netdev(dev->netdev); unlink_all_urbs(dev); free_all_urbs(dev); From 094f1649577dfc7f2c7407a8380e05a506b31f7f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0820/1940] [PATCH] USB: add endpoint information to sysfs This patch adds endpoint information for both devices and interfaces to sysfs. Previously it was only possible to get the endpoint information from usbfs, and never possible to get any information on endpoint 0. Signed-off-by: Greg Kroah-Hartman drivers/usb/core/sysfs.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/usb.h | 4 2 files changed, 197 insertions(+), 2 deletions(-) --- drivers/usb/core/sysfs.c | 195 ++++++++++++++++++++++++++++++++++++++- include/linux/usb.h | 4 + 2 files changed, 197 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 00297f113849..eae413bf8c2a 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -22,6 +22,174 @@ #include "usb.h" +/* endpoint stuff */ +struct endpoint_attribute { + struct device_attribute dev_attr; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev; +}; +#define to_endpoint_attr(_dev_attr) \ + container_of(_dev_attr, struct endpoint_attribute, dev_attr) + +#define usb_ep_attr(field, format_string) \ +static ssize_t show_ep_##field(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); \ + \ + return sprintf(buf, format_string, endpoint_attr->endpoint->field); \ +} +usb_ep_attr(bLength, "%02x\n") +usb_ep_attr(bDescriptorType, "%02x\n") +usb_ep_attr(bEndpointAddress, "%02x\n") +usb_ep_attr(bmAttributes, "%02x\n") +usb_ep_attr(bInterval, "%02x\n") + +static ssize_t show_ep_wMaxPacketSize(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + + return sprintf(buf, "%04x\n", + le16_to_cpu(endpoint_attr->endpoint->wMaxPacketSize) & 0x07ff); +} + +static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + char *type = "unknown"; + + switch (endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + type = "Control"; + break; + case USB_ENDPOINT_XFER_ISOC: + type = "Isoc"; + break; + case USB_ENDPOINT_XFER_BULK: + type = "Bulk"; + break; + case USB_ENDPOINT_XFER_INT: + type = "Interrupt"; + break; + } + return sprintf(buf, "%s\n", type); +} + +static ssize_t show_ep_interval(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + struct usb_device *udev = endpoint_attr->udev; + struct usb_endpoint_descriptor *endpoint = endpoint_attr->endpoint; + char unit; + unsigned interval = 0; + unsigned in; + + in = (endpoint->bEndpointAddress & USB_DIR_IN); + + switch (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ + interval = endpoint->bInterval; + break; + case USB_ENDPOINT_XFER_ISOC: + interval = 1 << (endpoint->bInterval - 1); + break; + case USB_ENDPOINT_XFER_BULK: + if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ + interval = endpoint->bInterval; + break; + case USB_ENDPOINT_XFER_INT: + if (udev->speed == USB_SPEED_HIGH) { + interval = 1 << (endpoint->bInterval - 1); + } else + interval = endpoint->bInterval; + break; + } + interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; + if (interval % 1000) + unit = 'u'; + else { + unit = 'm'; + interval /= 1000; + } + + return sprintf(buf, "%d%cs\n", interval, unit); +} + +static ssize_t show_ep_direction(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + char *direction; + + if ((endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) + direction = "both"; + else if (endpoint_attr->endpoint->bEndpointAddress & USB_DIR_IN) + direction = "in"; + else + direction = "out"; + return sprintf(buf, "%s\n", direction); +} + +static struct endpoint_attribute *create_ep_attr(struct usb_endpoint_descriptor *endpoint, + struct usb_device *udev, char *name, + ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf)) +{ + struct endpoint_attribute *ep_attr; + + ep_attr = kzalloc(sizeof(*ep_attr), GFP_KERNEL); + if (ep_attr) { + ep_attr->endpoint = endpoint; + ep_attr->udev = udev; + ep_attr->dev_attr.attr.name = name; + ep_attr->dev_attr.attr.mode = 0444; + ep_attr->dev_attr.attr.owner = THIS_MODULE; + ep_attr->dev_attr.show = show; + } + return ep_attr; +} + +static void usb_create_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint, struct usb_device *udev) +{ + struct usb_endpoint_descriptor *ep; + + ep = &endpoint->desc; + + endpoint->attrs = kzalloc(sizeof(struct attribute *) * 10, GFP_KERNEL); + endpoint->attrs[0] = &(create_ep_attr(ep, udev, "direction", show_ep_direction)->dev_attr.attr); + endpoint->attrs[1] = &(create_ep_attr(ep, udev, "type", show_ep_type)->dev_attr.attr); + endpoint->attrs[2] = &(create_ep_attr(ep, udev, "bLength", show_ep_bLength)->dev_attr.attr); + endpoint->attrs[3] = &(create_ep_attr(ep, udev, "bDescriptorType", show_ep_bDescriptorType)->dev_attr.attr); + endpoint->attrs[4] = &(create_ep_attr(ep, udev, "bEndpointAddress", show_ep_bEndpointAddress)->dev_attr.attr); + endpoint->attrs[5] = &(create_ep_attr(ep, udev, "bmAttributes", show_ep_bmAttributes)->dev_attr.attr); + endpoint->attrs[6] = &(create_ep_attr(ep, udev, "wMaxPacketSize", show_ep_wMaxPacketSize)->dev_attr.attr); + endpoint->attrs[7] = &(create_ep_attr(ep, udev, "bInterval", show_ep_bInterval)->dev_attr.attr); + endpoint->attrs[8] = &(create_ep_attr(ep, udev, "interval", show_ep_interval)->dev_attr.attr); + endpoint->attrs[9] = NULL; + endpoint->num_attrs = 9; + + endpoint->attr_group = kzalloc(sizeof(*endpoint->attr_group), GFP_KERNEL); + endpoint->attr_name = kzalloc(10, GFP_KERNEL); + sprintf(endpoint->attr_name, "ep_%02x", endpoint->desc.bEndpointAddress); + + endpoint->attr_group->attrs = endpoint->attrs; + endpoint->attr_group->name = endpoint->attr_name; + sysfs_create_group(kobj, endpoint->attr_group); +} + +static void usb_remove_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint) +{ + int i; + + sysfs_remove_group(kobj, endpoint->attr_group); + kfree(endpoint->attr_group); + kfree(endpoint->attr_name); + for (i = 0; i < endpoint->num_attrs; ++i) + kfree(endpoint->attrs[i]); + kfree(endpoint->attrs); +} + /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ @@ -236,12 +404,14 @@ void usb_create_sysfs_dev_files (struct usb_device *udev) if (udev->serial) device_create_file (dev, &dev_attr_serial); device_create_file (dev, &dev_attr_configuration); + usb_create_ep_files(&dev->kobj, &udev->ep0, udev); } void usb_remove_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; + usb_remove_ep_files(&dev->kobj, &udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); if (udev->descriptor.iManufacturer) @@ -333,20 +503,41 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; +static void usb_create_intf_ep_files(struct usb_interface *intf) +{ + struct usb_host_interface *iface_desc; + int i; + + iface_desc = intf->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) + usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], + interface_to_usbdev(intf)); +} + +static void usb_remove_intf_ep_files(struct usb_interface *intf) +{ + struct usb_host_interface *iface_desc; + int i; + + iface_desc = intf->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) + usb_remove_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i]); +} + void usb_create_sysfs_intf_files (struct usb_interface *intf) { sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); if (intf->cur_altsetting->string) device_create_file(&intf->dev, &dev_attr_interface); - + usb_create_intf_ep_files(intf); } void usb_remove_sysfs_intf_files (struct usb_interface *intf) { + usb_remove_intf_ep_files(intf); sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); if (intf->cur_altsetting->string) device_remove_file(&intf->dev, &dev_attr_interface); - } diff --git a/include/linux/usb.h b/include/linux/usb.h index 8f731e8f2821..4512210e97e7 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -57,6 +57,10 @@ struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; + char *attr_name; + struct attribute_group *attr_group; + struct attribute **attrs; + int num_attrs; unsigned char *extra; /* Extra descriptors */ int extralen; From d6e5bcf4a7ebbe258124a931f1449338340a99b5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0821/1940] [PATCH] devfs: Remove the mode field from usb_class_driver as it's no longer needed Also fixes all drivers that set this field, and removes some other devfs specfic USB logic. Signed-off-by: Greg Kroah-Hartman drivers/usb/class/usblp.c | 3 +-- drivers/usb/core/file.c | 19 ++++--------------- drivers/usb/image/mdc800.c | 3 +-- drivers/usb/input/aiptek.c | 2 +- drivers/usb/input/hiddev.c | 3 +-- drivers/usb/media/dabusb.c | 3 +-- drivers/usb/misc/auerswald.c | 3 +-- drivers/usb/misc/idmouse.c | 5 ++--- drivers/usb/misc/legousbtower.c | 5 ++--- drivers/usb/misc/rio500.c | 3 +-- drivers/usb/misc/sisusbvga/sisusb.c | 5 ----- drivers/usb/misc/usblcd.c | 9 ++++----- drivers/usb/usb-skeleton.c | 3 +-- include/linux/usb.h | 7 ++----- 14 files changed, 22 insertions(+), 51 deletions(-) --- drivers/usb/class/usblp.c | 3 +-- drivers/usb/core/file.c | 19 ++++--------------- drivers/usb/image/mdc800.c | 3 +-- drivers/usb/input/aiptek.c | 2 +- drivers/usb/input/hiddev.c | 3 +-- drivers/usb/media/dabusb.c | 3 +-- drivers/usb/misc/auerswald.c | 3 +-- drivers/usb/misc/idmouse.c | 5 ++--- drivers/usb/misc/legousbtower.c | 5 ++--- drivers/usb/misc/rio500.c | 3 +-- drivers/usb/misc/sisusbvga/sisusb.c | 5 ----- drivers/usb/misc/usblcd.c | 9 ++++----- drivers/usb/usb-skeleton.c | 3 +-- include/linux/usb.h | 7 ++----- 14 files changed, 22 insertions(+), 51 deletions(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index e195709c9c7f..357e75335f17 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -844,9 +844,8 @@ static struct file_operations usblp_fops = { }; static struct usb_class_driver usblp_class = { - .name = "usb/lp%d", + .name = "lp%d", .fops = &usblp_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = USBLP_MINOR_BASE, }; diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 78cb4be9529f..e695308095ae 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -88,8 +87,6 @@ int usb_major_init(void) goto out; } - devfs_mk_dir("usb"); - out: return error; } @@ -97,7 +94,6 @@ int usb_major_init(void) void usb_major_cleanup(void) { class_destroy(usb_class); - devfs_remove("usb"); unregister_chrdev(USB_MAJOR, "usb"); } @@ -112,8 +108,7 @@ void usb_major_cleanup(void) * enabled, the minor number will be based on the next available free minor, * starting at the class_driver->minor_base. * - * This function also creates the devfs file for the usb device, if devfs - * is enabled, and creates a usb class device in the sysfs tree. + * This function also creates a usb class device in the sysfs tree. * * usb_deregister_dev() must be called when the driver is done with * the minor numbers given out by this function. @@ -162,11 +157,8 @@ int usb_register_dev(struct usb_interface *intf, intf->minor = minor; - /* handle the devfs registration */ - snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); - devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); - /* create a usb class device for this usb interface */ + snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); temp = strrchr(name, '/'); if (temp && (temp[1] != 0x00)) ++temp; @@ -179,7 +171,6 @@ int usb_register_dev(struct usb_interface *intf, spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - devfs_remove (name); retval = PTR_ERR(intf->class_dev); } exit: @@ -197,9 +188,8 @@ EXPORT_SYMBOL(usb_register_dev); * call to usb_register_dev() (usually when the device is disconnected * from the system.) * - * This function also cleans up the devfs file for the usb device, if devfs - * is enabled, and removes the usb class device from the sysfs tree. - * + * This function also removes the usb class device from the sysfs tree. + * * This should be called by all drivers that use the USB major number. */ void usb_deregister_dev(struct usb_interface *intf, @@ -222,7 +212,6 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - devfs_remove (name); class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); intf->class_dev = NULL; intf->minor = -1; diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a330a4b50e16..e4ec133ee74a 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -425,9 +425,8 @@ static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res) static struct usb_driver mdc800_usb_driver; static struct file_operations mdc800_device_ops; static struct usb_class_driver mdc800_class = { - .name = "usb/mdc800%d", + .name = "mdc800%d", .fops = &mdc800_device_ops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = MDC800_DEVICE_MINOR_BASE, }; diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 1c5205321d83..1c3b472a3bca 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -2154,7 +2154,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) * input_handles associated with this input device. * What identifies an evdev input_handler is that it begins * with 'event', continues with a digit, and that in turn - * is mapped to /{devfs}/input/eventN. + * is mapped to input/eventN. */ list_for_each_safe(node, next, &inputdev->h_list) { inputhandle = to_handle(node); diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index d32427818af7..440377c7a0da 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -732,9 +732,8 @@ static struct file_operations hiddev_fops = { }; static struct usb_class_driver hiddev_class = { - .name = "usb/hid/hiddev%d", + .name = "hiddev%d", .fops = &hiddev_fops, - .mode = S_IFCHR | S_IRUGO | S_IWUSR, .minor_base = HIDDEV_MINOR_BASE, }; diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 6ca2fae99d2d..27b23c55bbc7 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -707,9 +707,8 @@ static struct file_operations dabusb_fops = }; static struct usb_class_driver dabusb_class = { - .name = "usb/dabusb%d", + .name = "dabusb%d", .fops = &dabusb_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = DABUSB_MINOR, }; diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index ae4681f9f0ea..5f33f7c64885 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1873,9 +1873,8 @@ static struct file_operations auerswald_fops = }; static struct usb_class_driver auerswald_class = { - .name = "usb/auer%d", + .name = "auer%d", .fops = &auerswald_fops, - .mode = S_IFCHR | S_IRUGO | S_IWUGO, .minor_base = AUER_MINOR_BASE, }; diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 733acc213726..3944a55ed74c 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -105,11 +105,10 @@ static struct file_operations idmouse_fops = { .release = idmouse_release, }; -/* class driver information for devfs */ +/* class driver information */ static struct usb_class_driver idmouse_class = { - .name = "usb/idmouse%d", + .name = "idmouse%d", .fops = &idmouse_fops, - .mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */ .minor_base = USB_IDMOUSE_MINOR_BASE, }; diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 7d06105763d4..2703e205bc8f 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -271,12 +271,11 @@ static struct file_operations tower_fops = { /* * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with devfs and the driver core + * and to have the device registered with the driver core */ static struct usb_class_driver tower_class = { - .name = "usb/legousbtower%d", + .name = "legousbtower%d", .fops = &tower_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = LEGO_USB_TOWER_MINOR_BASE, }; diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 26f77e29c7a6..7d02d8ec6b1a 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -443,9 +443,8 @@ file_operations usb_rio_fops = { }; static struct usb_class_driver usb_rio_class = { - .name = "usb/rio500%d", + .name = "rio500%d", .fops = &usb_rio_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = RIO_MINOR, }; diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 39db3155723a..222ae9cd4c7c 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3239,12 +3239,7 @@ static struct file_operations usb_sisusb_fops = { }; static struct usb_class_driver usb_sisusb_class = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) - .name = "usb/sisusbvga%d", - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, -#else .name = "sisusbvga%d", -#endif .fops = &usb_sisusb_fops, .minor_base = SISUSB_MINOR }; diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 096ab3029676..85f3725334b0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -251,13 +251,12 @@ static struct file_operations lcd_fops = { }; /* - * * usb class driver info in order to get a minor number from the usb core, - * * and to have the device registered with devfs and the driver core - * */ + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ static struct usb_class_driver lcd_class = { - .name = "usb/lcd%d", + .name = "lcd%d", .fops = &lcd_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = USBLCD_MINOR, }; diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 353f24d45bc1..6c3a53f8f26c 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -223,9 +223,8 @@ static struct file_operations skel_fops = { * and to have the device registered with devfs and the driver core */ static struct usb_class_driver skel_class = { - .name = "usb/skel%d", + .name = "skel%d", .fops = &skel_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = USB_SKEL_MINOR_BASE, }; diff --git a/include/linux/usb.h b/include/linux/usb.h index 4512210e97e7..04502e183dd1 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -576,10 +576,8 @@ extern struct bus_type usb_bus_type; /** * struct usb_class_driver - identifies a USB driver that wants to use the USB major number - * @name: devfs name for this driver. Will also be used by the driver - * class code to create a usb class device. + * @name: the usb class device name for this driver. Will show up in sysfs. * @fops: pointer to the struct file_operations of this driver. - * @mode: the mode for the devfs file to be created for this driver. * @minor_base: the start of the minor range for this driver. * * This structure is used for the usb_register_dev() and @@ -589,8 +587,7 @@ extern struct bus_type usb_bus_type; struct usb_class_driver { char *name; struct file_operations *fops; - mode_t mode; - int minor_base; + int minor_base; }; /* From e639dd3f4edd4847d160899b19e95ee1a06a6dcb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0822/1940] [PATCH] USB: add more snooping hooks in devio.c Now we can log the urbs travelling through usbfs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 55 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index befe0c7f63d1..6c15dabcfc0b 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -279,6 +279,28 @@ static inline struct async *async_getpending(struct dev_state *ps, void __user * return NULL; } +static void snoop_urb(struct urb *urb, void __user *userurb) +{ + int j; + unsigned char *data = urb->transfer_buffer; + + if (!usbfs_snoop) + return; + + if (urb->pipe & USB_DIR_IN) + dev_info(&urb->dev->dev, "direction=IN\n"); + else + dev_info(&urb->dev->dev, "direction=OUT\n"); + dev_info(&urb->dev->dev, "userurb=%p\n", userurb); + dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", + urb->transfer_buffer_length); + dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); + dev_info(&urb->dev->dev, "data: "); + for (j = 0; j < urb->transfer_buffer_length; ++j) + printk ("%02x ", data[j]); + printk("\n"); +} + static void async_completed(struct urb *urb, struct pt_regs *regs) { struct async *as = (struct async *)urb->context; @@ -296,7 +318,9 @@ static void async_completed(struct urb *urb, struct pt_regs *regs) kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, as->euid); } - wake_up(&ps->wait); + snoop(&urb->dev->dev, "urb complete\n"); + snoop_urb(urb, as->userurb); + wake_up(&ps->wait); } static void destroy_async (struct dev_state *ps, struct list_head *list) @@ -601,7 +625,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) if (usbfs_snoop) { dev_info(&dev->dev, "control read: data "); for (j = 0; j < i; ++j) - printk ("%02x ", (unsigned char)(tbuf)[j]); + printk("%02x ", (unsigned char)(tbuf)[j]); printk("\n"); } if (copy_to_user(ctrl.data, tbuf, i)) { @@ -624,7 +648,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) if (usbfs_snoop) { dev_info(&dev->dev, "control write: data: "); for (j = 0; j < ctrl.wLength; ++j) - printk ("%02x ", (unsigned char)(tbuf)[j]); + printk("%02x ", (unsigned char)(tbuf)[j]); printk("\n"); } usb_unlock_device(dev); @@ -649,7 +673,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) unsigned int tmo, len1, pipe; int len2; unsigned char *tbuf; - int i, ret; + int i, j, ret; if (copy_from_user(&bulk, arg, sizeof(bulk))) return -EFAULT; @@ -674,10 +698,18 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) kfree(tbuf); return -EINVAL; } + snoop(&dev->dev, "bulk read: len=0x%02x timeout=%04d\n", + bulk.len, bulk.timeout); usb_unlock_device(dev); i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); usb_lock_device(dev); if (!i && len2) { + if (usbfs_snoop) { + dev_info(&dev->dev, "bulk read: data "); + for (j = 0; j < len2; ++j) + printk("%02x ", (unsigned char)(tbuf)[j]); + printk("\n"); + } if (copy_to_user(bulk.data, tbuf, len2)) { kfree(tbuf); return -EFAULT; @@ -690,6 +722,14 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) return -EFAULT; } } + snoop(&dev->dev, "bulk write: len=0x%02x timeout=%04d\n", + bulk.len, bulk.timeout); + if (usbfs_snoop) { + dev_info(&dev->dev, "bulk write: data: "); + for (j = 0; j < len1; ++j) + printk("%02x ", (unsigned char)(tbuf)[j]); + printk("\n"); + } usb_unlock_device(dev); i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); usb_lock_device(dev); @@ -835,7 +875,6 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) return status; } - static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, struct usbdevfs_iso_packet_desc __user *iso_frame_desc, void __user *arg) @@ -896,6 +935,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, kfree(dr); return -EFAULT; } + snoop(&ps->dev->dev, "control urb\n"); break; case USBDEVFS_URB_TYPE_BULK: @@ -910,6 +950,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EINVAL; if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) return -EFAULT; + snoop(&ps->dev->dev, "bulk urb\n"); break; case USBDEVFS_URB_TYPE_ISO: @@ -939,6 +980,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EINVAL; } uurb->buffer_length = totlen; + snoop(&ps->dev->dev, "iso urb\n"); break; case USBDEVFS_URB_TYPE_INTERRUPT: @@ -954,6 +996,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EINVAL; if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) return -EFAULT; + snoop(&ps->dev->dev, "interrupt urb\n"); break; default: @@ -1003,6 +1046,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EFAULT; } } + snoop(&as->urb->dev->dev, "submit urb\n"); + snoop_urb(as->urb, as->userurb); async_newpending(as); if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret); From 38ffdd62b0f466ef9126ac9f060ade5f218b4887 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Sat, 24 Sep 2005 13:10:16 -0700 Subject: [PATCH 0823/1940] [PATCH] ub: suppress gcc warnings for pointer casts When building on a 64-bit platform, gcc produces a warning "cast of a pointer to an integer of a different size". The scatterlist.offset on the LHS is unsigned int, so I used that originally. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman drivers/block/ub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- drivers/block/ub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index ed4d5006fe62..bfb23d543ff7 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1512,7 +1512,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scmd->nsg = 1; sg = &scmd->sgv[0]; sg->page = virt_to_page(sc->top_sense); - sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1); + sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1); sg->length = UB_SENSE_SIZE; scmd->len = UB_SENSE_SIZE; scmd->lun = cmd->lun; @@ -1891,7 +1891,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, cmd->nsg = 1; sg = &cmd->sgv[0]; sg->page = virt_to_page(p); - sg->offset = (unsigned int)p & (PAGE_SIZE-1); + sg->offset = (unsigned long)p & (PAGE_SIZE-1); sg->length = 8; cmd->len = 8; cmd->lun = lun; From 7586269c0b52970f60bb69fcb86e765fc1d72309 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 23 Sep 2005 17:14:37 -0700 Subject: [PATCH 0824/1940] [PATCH] USB: move handoff code This moves the PCI quirk handling for USB host controllers from the PCI directory to the USB directory. Follow-on patches will need to: (a) merge these copies with the originals in the HCD reset methods. they don't wholly agree, despite doing the very same thing; and (b) eventually change it so "usb-handoff" is the default, to help get more robust USB/BIOS/input/... interactions. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/Makefile | 2 drivers/pci/quirks.c | 253 --------------------------------------- drivers/usb/Makefile | 1 drivers/usb/host/Makefile | 5 drivers/usb/host/pci-quirks.c | 272 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 253 deletions(-) --- drivers/Makefile | 2 +- drivers/pci/quirks.c | 253 +------------------------------ drivers/usb/Makefile | 1 + drivers/usb/host/Makefile | 5 +- drivers/usb/host/pci-quirks.c | 272 ++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 253 deletions(-) create mode 100644 drivers/usb/host/pci-quirks.c diff --git a/drivers/Makefile b/drivers/Makefile index 1a109a6dd953..65670be6ff1a 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -5,7 +5,7 @@ # Rewritten to use lists instead of if-statements. # -obj-$(CONFIG_PCI) += pci/ +obj-$(CONFIG_PCI) += pci/ usb/ obj-$(CONFIG_PARISC) += parisc/ obj-y += video/ obj-$(CONFIG_ACPI) += acpi/ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ee1605906a3e..bbd9c2323d8c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -7,6 +7,9 @@ * * Copyright (c) 1999 Martin Mares * + * Init/reset quirks for USB host controllers should be in the + * USB quirks file, where their drivers can access reuse it. + * * The bridge optimization stuff has been removed. If you really * have a silly BIOS which is unable to set your host bridge right, * use the PowerTweak utility (see http://powertweak.sourceforge.net). @@ -644,28 +647,6 @@ static void quirk_via_irq(struct pci_dev *dev) } DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); -/* - * PIIX3 USB: We have to disable USB interrupts that are - * hardwired to PIRQD# and may be shared with an - * external device. - * - * Legacy Support Register (LEGSUP): - * bit13: USB PIRQ Enable (USBPIRQDEN), - * bit4: Trap/SMI On IRQ Enable (USBSMIEN). - * - * We mask out all r/wc bits, too. - */ -static void __devinit quirk_piix3_usb(struct pci_dev *dev) -{ - u16 legsup; - - pci_read_config_word(dev, 0xc0, &legsup); - legsup &= 0x50ef; - pci_write_config_word(dev, 0xc0, legsup); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); - /* * VIA VT82C598 has its device ID settable and many BIOSes * set it to the ID of VT82C597 for backward compatibility. @@ -1039,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(struct pci_dev *dev) pci_read_config_byte(dev, 0x77, &val); } - -#define UHCI_USBLEGSUP 0xc0 /* legacy support */ -#define UHCI_USBCMD 0 /* command register */ -#define UHCI_USBSTS 2 /* status register */ -#define UHCI_USBINTR 4 /* interrupt register */ -#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ -#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ -#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ -#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ -#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ - -#define OHCI_CONTROL 0x04 -#define OHCI_CMDSTATUS 0x08 -#define OHCI_INTRSTATUS 0x0c -#define OHCI_INTRENABLE 0x10 -#define OHCI_INTRDISABLE 0x14 -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ - -#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ -#define EHCI_USBCMD 0 /* command register */ -#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ -#define EHCI_USBSTS 4 /* status register */ -#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ -#define EHCI_USBINTR 8 /* interrupt register */ -#define EHCI_USBLEGSUP 0 /* legacy support register */ -#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ -#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ -#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ -#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ - -int usb_early_handoff __devinitdata = 0; -static int __init usb_handoff_early(char *str) -{ - usb_early_handoff = 1; - return 0; -} -__setup("usb-handoff", usb_handoff_early); - -static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) -{ - unsigned long base = 0; - int wait_time, delta; - u16 val, sts; - int i; - - for (i = 0; i < PCI_ROM_RESOURCE; i++) - if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { - base = pci_resource_start(pdev, i); - break; - } - - if (!base) - return; - - /* - * stop controller - */ - sts = inw(base + UHCI_USBSTS); - val = inw(base + UHCI_USBCMD); - val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); - outw(val, base + UHCI_USBCMD); - - /* - * wait while it stops if it was running - */ - if ((sts & UHCI_USBSTS_HALTED) == 0) - { - wait_time = 1000; - delta = 100; - - do { - outw(0x1f, base + UHCI_USBSTS); - udelay(delta); - wait_time -= delta; - val = inw(base + UHCI_USBSTS); - if (val & UHCI_USBSTS_HALTED) - break; - } while (wait_time > 0); - } - - /* - * disable interrupts & legacy support - */ - outw(0, base + UHCI_USBINTR); - outw(0x1f, base + UHCI_USBSTS); - pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); - if (val & 0xbf) - pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); - -} - -static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) -{ - void __iomem *base; - int wait_time; - - base = ioremap_nocache(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (base == NULL) return; - - if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { - wait_time = 500; /* 0.5 seconds */ - writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); - writel(OHCI_OCR, base + OHCI_CMDSTATUS); - while (wait_time > 0 && - readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { - wait_time -= 10; - msleep(10); - } - } - - /* - * disable interrupts - */ - writel(~(u32)0, base + OHCI_INTRDISABLE); - writel(~(u32)0, base + OHCI_INTRSTATUS); - - iounmap(base); -} - -static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) -{ - int wait_time, delta; - void __iomem *base, *op_reg_base; - u32 hcc_params, val, temp; - u8 cap_length; - - base = ioremap_nocache(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (base == NULL) return; - - cap_length = readb(base); - op_reg_base = base + cap_length; - hcc_params = readl(base + EHCI_HCC_PARAMS); - hcc_params = (hcc_params >> 8) & 0xff; - if (hcc_params) { - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - &val); - if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { - /* - * Ok, BIOS is in smm mode, try to hand off... - */ - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - &temp); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - temp | EHCI_USBLEGCTLSTS_SOOE); - val |= EHCI_USBLEGSUP_OS; - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - val); - - wait_time = 500; - do { - msleep(10); - wait_time -= 10; - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - &val); - } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); - if (!wait_time) { - /* - * well, possibly buggy BIOS... - */ - printk(KERN_WARNING "EHCI early BIOS handoff " - "failed (BIOS bug ?)\n"); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - EHCI_USBLEGSUP_OS); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - 0); - } - } - } - - /* - * halt EHCI & disable its interrupts in any case - */ - val = readl(op_reg_base + EHCI_USBSTS); - if ((val & EHCI_USBSTS_HALTED) == 0) { - val = readl(op_reg_base + EHCI_USBCMD); - val &= ~EHCI_USBCMD_RUN; - writel(val, op_reg_base + EHCI_USBCMD); - - wait_time = 2000; - delta = 100; - do { - writel(0x3f, op_reg_base + EHCI_USBSTS); - udelay(delta); - wait_time -= delta; - val = readl(op_reg_base + EHCI_USBSTS); - if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { - break; - } - } while (wait_time > 0); - } - writel(0, op_reg_base + EHCI_USBINTR); - writel(0x3f, op_reg_base + EHCI_USBSTS); - - iounmap(base); - - return; -} - - - -static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) -{ - if (!usb_early_handoff) - return; - - if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ - quirk_usb_handoff_uhci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ - quirk_usb_handoff_ohci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ - quirk_usb_disable_ehci(pdev); - } - - return; -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); - /* * ... This is further complicated by the fact that some SiS96x south * bridges pretend to be 85C503/5513 instead. In that case see if we diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index df014c2a7c54..aa554f9805ee 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_USB) += core/ obj-$(CONFIG_USB_MON) += mon/ +obj-$(CONFIG_PCI) += host/ obj-$(CONFIG_USB_EHCI_HCD) += host/ obj-$(CONFIG_USB_ISP116X_HCD) += host/ obj-$(CONFIG_USB_OHCI_HCD) += host/ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 350d14fc1cc9..58321d3f314c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -1,8 +1,9 @@ # -# Makefile for USB Host Controller Driver -# framework and drivers +# Makefile for USB Host Controller Drivers # +obj-$(CONFIG_PCI) += pci-quirks.o + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c new file mode 100644 index 000000000000..8ee5c3ed4cd6 --- /dev/null +++ b/drivers/usb/host/pci-quirks.c @@ -0,0 +1,272 @@ +/* + * This file contains code to reset and initialize USB host controllers. + * Some of it includes work-arounds for PCI hardware and BIOS quirks. + * It may need to run early during booting -- before USB would normally + * initialize -- to ensure that Linux doesn't use any legacy modes. + * + * Copyright (c) 1999 Martin Mares + * (and others) + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * PIIX3 USB: We have to disable USB interrupts that are + * hardwired to PIRQD# and may be shared with an + * external device. + * + * Legacy Support Register (LEGSUP): + * bit13: USB PIRQ Enable (USBPIRQDEN), + * bit4: Trap/SMI On IRQ Enable (USBSMIEN). + * + * We mask out all r/wc bits, too. + */ +static void __devinit quirk_piix3_usb(struct pci_dev *dev) +{ + u16 legsup; + + pci_read_config_word(dev, 0xc0, &legsup); + legsup &= 0x50ef; + pci_write_config_word(dev, 0xc0, legsup); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); + + +/* FIXME these should be the guts of hcd->reset() methods; resolve all + * the differences between this version and the HCD's version. + */ + +#define UHCI_USBLEGSUP 0xc0 /* legacy support */ +#define UHCI_USBCMD 0 /* command register */ +#define UHCI_USBSTS 2 /* status register */ +#define UHCI_USBINTR 4 /* interrupt register */ +#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ +#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ +#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ +#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ +#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ + +#define OHCI_CONTROL 0x04 +#define OHCI_CMDSTATUS 0x08 +#define OHCI_INTRSTATUS 0x0c +#define OHCI_INTRENABLE 0x10 +#define OHCI_INTRDISABLE 0x14 +#define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +#define OHCI_INTR_OC (1 << 30) /* ownership change */ + +#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ +#define EHCI_USBCMD 0 /* command register */ +#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ +#define EHCI_USBSTS 4 /* status register */ +#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ +#define EHCI_USBINTR 8 /* interrupt register */ +#define EHCI_USBLEGSUP 0 /* legacy support register */ +#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ +#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ +#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ +#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ + +int usb_early_handoff __devinitdata = 0; +static int __init usb_handoff_early(char *str) +{ + usb_early_handoff = 1; + return 0; +} +__setup("usb-handoff", usb_handoff_early); + +static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) +{ + unsigned long base = 0; + int wait_time, delta; + u16 val, sts; + int i; + + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { + base = pci_resource_start(pdev, i); + break; + } + + if (!base) + return; + + /* + * stop controller + */ + sts = inw(base + UHCI_USBSTS); + val = inw(base + UHCI_USBCMD); + val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); + outw(val, base + UHCI_USBCMD); + + /* + * wait while it stops if it was running + */ + if ((sts & UHCI_USBSTS_HALTED) == 0) + { + wait_time = 1000; + delta = 100; + + do { + outw(0x1f, base + UHCI_USBSTS); + udelay(delta); + wait_time -= delta; + val = inw(base + UHCI_USBSTS); + if (val & UHCI_USBSTS_HALTED) + break; + } while (wait_time > 0); + } + + /* + * disable interrupts & legacy support + */ + outw(0, base + UHCI_USBINTR); + outw(0x1f, base + UHCI_USBSTS); + pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); + if (val & 0xbf) + pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); + +} + +static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) +{ + void __iomem *base; + int wait_time; + + base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (base == NULL) return; + + if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + wait_time = 500; /* 0.5 seconds */ + writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); + writel(OHCI_OCR, base + OHCI_CMDSTATUS); + while (wait_time > 0 && + readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + wait_time -= 10; + msleep(10); + } + } + + /* + * disable interrupts + */ + writel(~(u32)0, base + OHCI_INTRDISABLE); + writel(~(u32)0, base + OHCI_INTRSTATUS); + + iounmap(base); +} + +static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) +{ + int wait_time, delta; + void __iomem *base, *op_reg_base; + u32 hcc_params, val, temp; + u8 cap_length; + + base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (base == NULL) return; + + cap_length = readb(base); + op_reg_base = base + cap_length; + hcc_params = readl(base + EHCI_HCC_PARAMS); + hcc_params = (hcc_params >> 8) & 0xff; + if (hcc_params) { + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + &val); + if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { + /* + * Ok, BIOS is in smm mode, try to hand off... + */ + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + &temp); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + temp | EHCI_USBLEGCTLSTS_SOOE); + val |= EHCI_USBLEGSUP_OS; + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + val); + + wait_time = 500; + do { + msleep(10); + wait_time -= 10; + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + &val); + } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); + if (!wait_time) { + /* + * well, possibly buggy BIOS... + */ + printk(KERN_WARNING "EHCI early BIOS handoff " + "failed (BIOS bug ?)\n"); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + EHCI_USBLEGSUP_OS); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + 0); + } + } + } + + /* + * halt EHCI & disable its interrupts in any case + */ + val = readl(op_reg_base + EHCI_USBSTS); + if ((val & EHCI_USBSTS_HALTED) == 0) { + val = readl(op_reg_base + EHCI_USBCMD); + val &= ~EHCI_USBCMD_RUN; + writel(val, op_reg_base + EHCI_USBCMD); + + wait_time = 2000; + delta = 100; + do { + writel(0x3f, op_reg_base + EHCI_USBSTS); + udelay(delta); + wait_time -= delta; + val = readl(op_reg_base + EHCI_USBSTS); + if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { + break; + } + } while (wait_time > 0); + } + writel(0, op_reg_base + EHCI_USBINTR); + writel(0x3f, op_reg_base + EHCI_USBSTS); + + iounmap(base); + + return; +} + + + +static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) +{ + if (!usb_early_handoff) + return; + + if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ + quirk_usb_handoff_uhci(pdev); + } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ + quirk_usb_handoff_ohci(pdev); + } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ + quirk_usb_disable_ehci(pdev); + } + + return; +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); From db69087437dd5135a9362da1c37fe072070e8f60 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:56:33 -0700 Subject: [PATCH 0825/1940] [PATCH] usb_interface power state This updates the handling of power state for USB interfaces. - Formalizes an existing invariant: interface "power state" is a boolean: ON when I/O is allowed, and FREEZE otherwise. It does so by defining some inlined helpers, then using them. - Adds a useful invariant: the only interfaces marked active are those bound to non-suspended drivers. Later patches build on this invariant. - Simplifies the interface driver API (and removes some error paths) by removing the requirement that they record power state changes during suspend and resume callbacks. Now usbcore does that. A few drivers were simplified to address that last change. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hub.c | 33 +++++++++------------ drivers/usb/core/message.c | 1 drivers/usb/core/usb.c | 65 +++++++++++++++++++++++++++++++++---------- drivers/usb/core/usb.h | 18 +++++++++++ drivers/usb/input/hid-core.c | 2 - drivers/usb/misc/usbtest.c | 10 ------ drivers/usb/net/pegasus.c | 2 - drivers/usb/net/usbnet.c | 2 - 8 files changed, 85 insertions(+), 48 deletions(-) --- drivers/usb/core/hub.c | 33 +++++++++--------- drivers/usb/core/message.c | 1 + drivers/usb/core/usb.c | 65 ++++++++++++++++++++++++++++-------- drivers/usb/core/usb.h | 18 ++++++++++ drivers/usb/input/hid-core.c | 2 -- drivers/usb/misc/usbtest.c | 10 ------ drivers/usb/net/pegasus.c | 2 -- drivers/usb/net/usbnet.c | 2 -- 8 files changed, 85 insertions(+), 48 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c3e2024c4347..61341d2f3c0e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1624,7 +1624,7 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, struct usb_driver *driver; intf = udev->actconfig->interface[i]; - if (state.event <= intf->dev.power.power_state.event) + if (!is_active(intf)) continue; if (!intf->dev.driver) continue; @@ -1632,11 +1632,12 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, if (driver->suspend) { status = driver->suspend(intf, state); - if (intf->dev.power.power_state.event != state.event - || status) + if (status == 0) + mark_quiesced(intf); + else dev_err(&intf->dev, - "suspend %d fail, code %d\n", - state.event, status); + "suspend error %d\n", + status); } /* only drivers with suspend() can ever resume(); @@ -1787,7 +1788,7 @@ static int finish_port_resume(struct usb_device *udev) struct usb_driver *driver; intf = udev->actconfig->interface[i]; - if (intf->dev.power.power_state.event == PM_EVENT_ON) + if (is_active(intf)) continue; if (!intf->dev.driver) { /* FIXME maybe force to alt 0 */ @@ -1800,12 +1801,14 @@ static int finish_port_resume(struct usb_device *udev) continue; /* can we do better than just logging errors? */ + mark_active(intf); status = driver->resume(intf); - if (intf->dev.power.power_state.event != PM_EVENT_ON - || status) + if (status < 0) { + mark_quiesced(intf); dev_dbg(&intf->dev, - "resume fail, state %d code %d\n", - intf->dev.power.power_state.event, status); + "resume error %d\n", + status); + } } status = 0; @@ -1952,7 +1955,7 @@ static int remote_wakeup(struct usb_device *udev) return status; } -static int hub_suspend(struct usb_interface *intf, pm_message_t state) +static int hub_suspend(struct usb_interface *intf, pm_message_t msg) { struct usb_hub *hub = usb_get_intfdata (intf); struct usb_device *hdev = hub->hdev; @@ -1970,14 +1973,13 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t state) if (!udev) continue; down(&udev->serialize); - status = __usb_suspend_device(udev, port1, state); + status = __usb_suspend_device(udev, port1, msg); up(&udev->serialize); if (status < 0) dev_dbg(&intf->dev, "suspend port %d --> %d\n", port1, status); } - intf->dev.power.power_state = state; return 0; } @@ -1988,9 +1990,6 @@ static int hub_resume(struct usb_interface *intf) unsigned port1; int status; - if (intf->dev.power.power_state.event == PM_EVENT_ON) - return 0; - for (port1 = 1; port1 <= hdev->maxchild; port1++) { struct usb_device *udev; u16 portstat, portchange; @@ -2024,8 +2023,6 @@ static int hub_resume(struct usb_interface *intf) } up(&udev->serialize); } - intf->dev.power.power_state = PMSG_ON; - hub->resume_root_hub = 0; hub_activate(hub); return 0; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f9a81e84dbdf..ebf59ea99263 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1393,6 +1393,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) intf->dev.dma_mask = dev->dev.dma_mask; intf->dev.release = release_interface; device_initialize (&intf->dev); + mark_quiesced(intf); sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", dev->bus->busnum, dev->devpath, configuration, diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4c57f3f649ed..6ecfdce4f848 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -107,10 +107,19 @@ static int usb_probe_interface(struct device *dev) id = usb_match_id (intf, driver->id_table); if (id) { dev_dbg (dev, "%s - got id\n", __FUNCTION__); + + /* Interface "power state" doesn't correspond to any hardware + * state whatsoever. We use it to record when it's bound to + * a driver that may start I/0: it's not frozen/quiesced. + */ + mark_active(intf); intf->condition = USB_INTERFACE_BINDING; error = driver->probe (intf, id); - intf->condition = error ? USB_INTERFACE_UNBOUND : - USB_INTERFACE_BOUND; + if (error) { + mark_quiesced(intf); + intf->condition = USB_INTERFACE_UNBOUND; + } else + intf->condition = USB_INTERFACE_BOUND; } return error; @@ -136,6 +145,7 @@ static int usb_unbind_interface(struct device *dev) 0); usb_set_intfdata(intf, NULL); intf->condition = USB_INTERFACE_UNBOUND; + mark_quiesced(intf); return 0; } @@ -299,6 +309,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, dev->driver = &driver->driver; usb_set_intfdata(iface, priv); iface->condition = USB_INTERFACE_BOUND; + mark_active(iface); /* if interface was already added, bind now; else let * the future device_add() bind it, bypassing probe() @@ -345,6 +356,7 @@ void usb_driver_release_interface(struct usb_driver *driver, dev->driver = NULL; usb_set_intfdata(iface, NULL); iface->condition = USB_INTERFACE_UNBOUND; + mark_quiesced(iface); } /** @@ -1404,8 +1416,9 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, static int usb_generic_suspend(struct device *dev, pm_message_t message) { - struct usb_interface *intf; - struct usb_driver *driver; + struct usb_interface *intf; + struct usb_driver *driver; + int status; if (dev->driver == &usb_generic_driver) return usb_suspend_device (to_usb_device(dev), message); @@ -1417,21 +1430,34 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message) intf = to_usb_interface(dev); driver = to_usb_driver(dev->driver); - /* there's only one USB suspend state */ - if (intf->dev.power.power_state.event) + /* with no hardware, USB interfaces only use FREEZE and ON states */ + if (!is_active(intf)) return 0; - if (driver->suspend) - return driver->suspend(intf, message); - return 0; + if (driver->suspend && driver->resume) { + status = driver->suspend(intf, message); + if (status) + dev_err(dev, "%s error %d\n", "suspend", status); + else + mark_quiesced(intf); + } else { + // FIXME else if there's no suspend method, disconnect... + dev_warn(dev, "no %s?\n", "suspend"); + status = 0; + } + return status; } static int usb_generic_resume(struct device *dev) { - struct usb_interface *intf; - struct usb_driver *driver; + struct usb_interface *intf; + struct usb_driver *driver; + int status; - /* devices resume through their hub */ + if (dev->power.power_state.event == PM_EVENT_ON) + return 0; + + /* devices resume through their hubs */ if (dev->driver == &usb_generic_driver) return usb_resume_device (to_usb_device(dev)); @@ -1442,8 +1468,19 @@ static int usb_generic_resume(struct device *dev) intf = to_usb_interface(dev); driver = to_usb_driver(dev->driver); - if (driver->resume) - return driver->resume(intf); + /* if driver was suspended, it has a resume method; + * however, sysfs can wrongly mark things as suspended + * (on the "no suspend method" FIXME path above) + */ + mark_active(intf); + if (driver->resume) { + status = driver->resume(intf); + if (status) { + dev_err(dev, "%s error %d\n", "resume", status); + mark_quiesced(intf); + } + } else + dev_warn(dev, "no %s?\n", "resume"); return 0; } diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index e6504f3370ad..3741a990403e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -28,6 +28,24 @@ extern void usb_major_cleanup(void); extern int usb_host_init(void); extern void usb_host_cleanup(void); +/* Interfaces and their "power state" are owned by usbcore */ + +static inline void mark_active(struct usb_interface *f) +{ + f->dev.power.power_state.event = PM_EVENT_ON; +} + +static inline void mark_quiesced(struct usb_interface *f) +{ + f->dev.power.power_state.event = PM_EVENT_FREEZE; +} + +static inline int is_active(struct usb_interface *f) +{ + return f->dev.power.power_state.event == PM_EVENT_ON; +} + + /* for labeling diagnostics */ extern const char *usbcore_name; diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 411a0645a7a3..f7fcce731f54 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1887,7 +1887,6 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) struct hid_device *hid = usb_get_intfdata (intf); usb_kill_urb(hid->urbin); - intf->dev.power.power_state = PMSG_SUSPEND; dev_dbg(&intf->dev, "suspend\n"); return 0; } @@ -1897,7 +1896,6 @@ static int hid_resume(struct usb_interface *intf) struct hid_device *hid = usb_get_intfdata (intf); int status; - intf->dev.power.power_state = PMSG_ON; if (hid->open) status = usb_submit_urb(hid->urbin, GFP_NOIO); else diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 54799eb0bc60..d055196533af 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1948,21 +1948,11 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) static int usbtest_suspend (struct usb_interface *intf, pm_message_t message) { - struct usbtest_dev *dev = usb_get_intfdata (intf); - - down (&dev->sem); - intf->dev.power.power_state = PMSG_SUSPEND; - up (&dev->sem); return 0; } static int usbtest_resume (struct usb_interface *intf) { - struct usbtest_dev *dev = usb_get_intfdata (intf); - - down (&dev->sem); - intf->dev.power.power_state = PMSG_ON; - up (&dev->sem); return 0; } diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 6a4ffe6c3977..537eb181d985 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -1384,7 +1384,6 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) usb_kill_urb(pegasus->rx_urb); usb_kill_urb(pegasus->intr_urb); } - intf->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -1392,7 +1391,6 @@ static int pegasus_resume (struct usb_interface *intf) { struct pegasus *pegasus = usb_get_intfdata(intf); - intf->dev.power.power_state = PMSG_ON; netif_device_attach (pegasus->net); if (netif_running(pegasus->net)) { pegasus->rx_urb->status = 0; diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index fce81d738933..74f05c9c84d5 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -1185,7 +1185,6 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) netif_device_detach (dev->net); (void) unlink_urbs (dev, &dev->rxq); (void) unlink_urbs (dev, &dev->txq); - intf->dev.power.power_state = PMSG_SUSPEND; return 0; } EXPORT_SYMBOL_GPL(usbnet_suspend); @@ -1194,7 +1193,6 @@ int usbnet_resume (struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - intf->dev.power.power_state = PMSG_ON; netif_device_attach (dev->net); tasklet_schedule (&dev->bh); return 0; From c9f89fa40cf274130b56475175a35af961d4b165 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:57:04 -0700 Subject: [PATCH 0826/1940] [PATCH] remove suspend-path recursion This patch removes some recursion in the CONFIG_USB_SUSPEND logic, which suspended children (of devices or hubs) that weren't already suspended. When it sees such cases, suspend now just fails cleanly. That logic was not needed during system-wide sleep state transitions; and given the current notions of how to manage selective suspend transitions, we don't want it there either. Where it was particularly handy was coping with various limitations of the sysfs "echo -n N > power/state" support. (These include assuming that "N" is always meaningful to the driver; and that drivers can only transition to state N from state zero.) Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 76 +++++++----------------------------------- 1 file changed, 12 insertions(+), 64 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 61341d2f3c0e..d3337d9c31dc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -453,6 +453,7 @@ static void hub_quiesce(struct usb_hub *hub) { /* stop khubd and related activity */ hub->quiescing = 1; + hub->activating = 0; usb_kill_urb(hub->urb); if (hub->has_indicators) cancel_delayed_work(&hub->leds); @@ -1613,68 +1614,21 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, return 0; } - /* suspend interface drivers; if this is a hub, it - * suspends the child devices - */ + /* all interfaces must already be suspended */ if (udev->actconfig) { int i; for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf; - struct usb_driver *driver; intf = udev->actconfig->interface[i]; - if (!is_active(intf)) - continue; - if (!intf->dev.driver) - continue; - driver = to_usb_driver(intf->dev.driver); - - if (driver->suspend) { - status = driver->suspend(intf, state); - if (status == 0) - mark_quiesced(intf); - else - dev_err(&intf->dev, - "suspend error %d\n", - status); - } - - /* only drivers with suspend() can ever resume(); - * and after power loss, even they won't. - * bus_rescan_devices() can rebind drivers later. - * - * FIXME the PM core self-deadlocks when unbinding - * drivers during suspend/resume ... everything grabs - * dpm_sem (not a spinlock, ugh). we want to unbind, - * since we know every driver's probe/disconnect works - * even for drivers that can't suspend. - */ - if (!driver->suspend || state.event > PM_EVENT_FREEZE) { -#if 1 - dev_warn(&intf->dev, "resume is unsafe!\n"); -#else - down_write(&usb_bus_type.rwsem); - device_release_driver(&intf->dev); - up_write(&usb_bus_type.rwsem); -#endif + if (is_active(intf)) { + dev_dbg(&intf->dev, "nyet suspended\n"); + return -EBUSY; } } } - /* - * FIXME this needs port power off call paths too, to help force - * USB into the "generic" PM model. At least for devices on - * ports that aren't using ganged switching (usually root hubs). - * - * NOTE: SRP-capable links should adopt more aggressive poweroff - * policies (when HNP doesn't apply) once we have mechanisms to - * turn power back on! (Likely not before 2.7...) - */ - if (state.event > PM_EVENT_FREEZE) { - dev_warn(&udev->dev, "no poweroff yet, suspending instead\n"); - } - /* "global suspend" of the HC-to-USB interface (root hub), or * "selective suspend" of just one hub-device link. */ @@ -1960,26 +1914,20 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) struct usb_hub *hub = usb_get_intfdata (intf); struct usb_device *hdev = hub->hdev; unsigned port1; - int status; - /* stop khubd and related activity */ - hub_quiesce(hub); - - /* then suspend every port */ + /* fail if children aren't already suspended */ for (port1 = 1; port1 <= hdev->maxchild; port1++) { struct usb_device *udev; udev = hdev->children [port1-1]; - if (!udev) - continue; - down(&udev->serialize); - status = __usb_suspend_device(udev, port1, msg); - up(&udev->serialize); - if (status < 0) - dev_dbg(&intf->dev, "suspend port %d --> %d\n", - port1, status); + if (udev && udev->state != USB_STATE_SUSPENDED) { + dev_dbg(&intf->dev, "port %d nyet suspended\n", port1); + return -EBUSY; + } } + /* stop khubd and related activity */ + hub_quiesce(hub); return 0; } From 390a8c345e6415cbf811232feedac70b56c9fc8d Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:57:27 -0700 Subject: [PATCH 0827/1940] [PATCH] remove usb_suspend_device() parameter This patch removes the extra usb_suspend_device() parameter. The original reason to pass that parameter was so that this routine could suspend any active children. A previous patch removed that functionality ... leaving no reason to pass the parameter. A close analogy is pci_set_power_state, which doesn't need a pm_message_t either. On the internal code path that comes through the driver model, the parameter is now used to distinguish cases where USB devices need to "freeze" but not suspend. It also checks for an error case that's accessible through sysfs: attempting to suspend a device before its interfaces (or for hubs, ports). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hub.c | 34 +++++++++++++++++++++------------- drivers/usb/core/usb.c | 23 +++++++++++++++++++++-- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- include/linux/usb.h | 2 +- 6 files changed, 46 insertions(+), 19 deletions(-) --- drivers/usb/core/hub.c | 34 +++++++++++++++++++++------------- drivers/usb/core/usb.c | 23 +++++++++++++++++++++-- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- include/linux/usb.h | 2 +- 6 files changed, 46 insertions(+), 19 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d3337d9c31dc..33127b828d60 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1323,11 +1323,9 @@ int usb_new_device(struct usb_device *udev) * (Includes HNP test device.) */ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { - static int __usb_suspend_device (struct usb_device *, - int port1, pm_message_t state); - err = __usb_suspend_device(udev, - udev->bus->otg_port, - PMSG_SUSPEND); + static int __usb_suspend_device(struct usb_device *, + int port1); + err = __usb_suspend_device(udev, udev->bus->otg_port); if (err < 0) dev_dbg(&udev->dev, "HNP fail, %d\n", err); } @@ -1517,7 +1515,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) /* FIXME let caller ask to power down the port: * - some devices won't enumerate without a VBUS power cycle * - SRP saves power that way - * - usb_suspend_device(dev, PMSG_SUSPEND) + * - ... new call, TBD ... * That's easy if this hub can switch power per-port, and * khubd reactivates the port later (timer, SRP, etc). * Powerdown must be optional, because of reset/DFU. @@ -1599,9 +1597,12 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, * Other than re-initializing the hub (plug/unplug, except for root hubs), * Linux (2.6) currently has NO mechanisms to initiate that: no khubd * timer, no SRP, no requests through sysfs. + * + * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when + * the root hub for their bus goes into global suspend ... so we don't + * (falsely) update the device power state to say it suspended. */ -static int __usb_suspend_device (struct usb_device *udev, int port1, - pm_message_t state) +static int __usb_suspend_device (struct usb_device *udev, int port1) { int status; @@ -1648,14 +1649,13 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, udev); if (status == 0) - udev->dev.power.power_state = state; + udev->dev.power.power_state = PMSG_SUSPEND; return status; } /** * usb_suspend_device - suspend a usb device * @udev: device that's no longer in active use - * @state: PMSG_SUSPEND to suspend * Context: must be able to sleep; device not locked * * Suspends a USB device that isn't in active use, conserving power. @@ -1664,13 +1664,16 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, * suspend by the host, using usb_resume_device(). It's also routine * to disconnect devices while they are suspended. * + * This only affects the USB hardware for a device; its interfaces + * (and, for hubs, child devices) must already have been suspended. + * * Suspending OTG devices may trigger HNP, if that's been enabled * between a pair of dual-role devices. That will change roles, such * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral. * * Returns 0 on success, else negative errno. */ -int usb_suspend_device(struct usb_device *udev, pm_message_t state) +int usb_suspend_device(struct usb_device *udev) { int port1, status; @@ -1678,12 +1681,15 @@ int usb_suspend_device(struct usb_device *udev, pm_message_t state) if (port1 < 0) return port1; - status = __usb_suspend_device(udev, port1, state); + status = __usb_suspend_device(udev, port1); usb_unlock_device(udev); return status; } /* + * If the USB "suspend" state is in use (rather than "global suspend"), + * many devices will be individually taken out of suspend state using + * special" resume" signaling. These routines kick in shortly after * hardware resume signaling is finished, either because of selective * resume (by host) or remote wakeup (by device) ... now see what changed * in the tree that's rooted at this device. @@ -1986,13 +1992,15 @@ void usb_resume_root_hub(struct usb_device *hdev) #else /* !CONFIG_USB_SUSPEND */ -int usb_suspend_device(struct usb_device *udev, pm_message_t state) +int usb_suspend_device(struct usb_device *udev) { + /* state does NOT lie by saying it's USB_STATE_SUSPENDED! */ return 0; } int usb_resume_device(struct usb_device *udev) { + udev->dev.power_state.event = PM_EVENT_ON; return 0; } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 6ecfdce4f848..e89dbd43e952 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1414,14 +1414,33 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } +static int verify_suspended(struct device *dev, void *unused) +{ + return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; +} + static int usb_generic_suspend(struct device *dev, pm_message_t message) { struct usb_interface *intf; struct usb_driver *driver; int status; - if (dev->driver == &usb_generic_driver) - return usb_suspend_device (to_usb_device(dev), message); + /* USB devices enter SUSPEND state through their hubs, but can be + * marked for FREEZE as soon as their children are already idled. + */ + if (dev->driver == &usb_generic_driver) { + if (dev->power.power_state.event == message.event) + return 0; + /* we need to rule out bogus requests through sysfs */ + status = device_for_each_child(dev, NULL, verify_suspended); + if (status) + return status; + if (message.event == PM_EVENT_FREEZE) { + dev->power.power_state = message; + return 0; + } + return usb_suspend_device (to_usb_device(dev)); + } if ((dev->driver == NULL) || (dev->driver_data == &usb_generic_driver_data)) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b3eb02613bff..513fccbb8e43 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -759,7 +759,7 @@ static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, message); + (void) usb_suspend_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); (void) ehci_hub_suspend (hcd); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 642f35068ce2..554d60282a9d 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1781,7 +1781,7 @@ static int isp116x_suspend(struct device *dev, pm_message_t state) VDBG("%s: state %x\n", __func__, state); - ret = usb_suspend_device(hcd->self.root_hub, state); + ret = usb_suspend_device(hcd->self.root_hub); if (!ret) { dev->power.power_state = state; INFO("%s suspended\n", hcd_name); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index eede6be098d2..41e85980fa7a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -119,7 +119,7 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, message); + (void) usb_suspend_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); diff --git a/include/linux/usb.h b/include/linux/usb.h index 04502e183dd1..25ec91ddcd04 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -976,7 +976,7 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, int timeout); /* selective suspend/resume */ -extern int usb_suspend_device(struct usb_device *dev, pm_message_t message); +extern int usb_suspend_device(struct usb_device *dev); extern int usb_resume_device(struct usb_device *dev); From dbc3887e7df4be78b33a83b97fde5d5f9a389859 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:57:36 -0700 Subject: [PATCH 0828/1940] [PATCH] remove duplicated resume path code This gets rid of some inconsistently duplicated logic to resume interfaces. Similar code was in both finish_port_resume() and in usb_generic_resume(). Now there is just one copy of that code, accessed regardless of whether CONFIG_USB_SUSPEND is enabled. Fault handling is also more consistent. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 33127b828d60..b2ae9b6ca4db 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1723,6 +1723,7 @@ static int finish_port_resume(struct usb_device *udev) status); else if (udev->actconfig) { unsigned i; + int (*resume)(struct device *); le16_to_cpus(&devstatus); if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { @@ -1741,35 +1742,11 @@ static int finish_port_resume(struct usb_device *udev) } /* resume interface drivers; if this is a hub, it - * resumes the child devices + * may have a child resume event to deal with soon */ - for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { - struct usb_interface *intf; - struct usb_driver *driver; - - intf = udev->actconfig->interface[i]; - if (is_active(intf)) - continue; - if (!intf->dev.driver) { - /* FIXME maybe force to alt 0 */ - continue; - } - driver = to_usb_driver(intf->dev.driver); - - /* bus_rescan_devices() may rebind drivers */ - if (!driver->resume) - continue; - - /* can we do better than just logging errors? */ - mark_active(intf); - status = driver->resume(intf); - if (status < 0) { - mark_quiesced(intf); - dev_dbg(&intf->dev, - "resume error %d\n", - status); - } - } + resume = udev->dev.bus->resume; + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) + (void) resume(&udev->actconfig->interface[i]->dev); status = 0; } else if (udev->devnum <= 0) { From 8ad7fe16df5e07320626be83fbba6d1c6bda5ec0 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:59:11 -0700 Subject: [PATCH 0829/1940] [PATCH] remove some USB_SUSPEND dependencies This simplifies some of the PM-related #ifdeffing by recognizing that USB_SUSPEND depends on PM. Also, OHCI drivers were often testing for USB_SUSPEND when they should have tested just PM. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hcd.c | 2 ++ drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 4 ++-- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- drivers/usb/host/ohci-ppc-soc.c | 4 ++-- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 3 +-- drivers/usb/host/ohci-sa1111.c | 2 +- 9 files changed, 12 insertions(+), 11 deletions(-) --- drivers/usb/core/hcd.c | 2 ++ drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 4 ++-- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- drivers/usb/host/ohci-ppc-soc.c | 4 ++-- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 3 +-- drivers/usb/host/ohci-sa1111.c | 2 +- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 14c47a10da86..5e8ade07d7f9 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1431,6 +1431,8 @@ hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep) /*-------------------------------------------------------------------------*/ +/* FIXME make this #ifdef CONFIG_PM ... update root hubs, retest */ + #ifdef CONFIG_USB_SUSPEND static int hcd_hub_suspend (struct usb_bus *bus) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f8da8c7af7c6..c26ab5f2a403 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -791,7 +791,7 @@ static void ohci_stop (struct usb_hcd *hcd) /* must not be called from interrupt context */ -#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) +#ifdef CONFIG_PM static int ohci_restart (struct ohci_hcd *ohci) { diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ce7b28da7a15..b96948ea3005 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -36,7 +36,7 @@ /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) +#ifdef CONFIG_PM #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) @@ -294,7 +294,7 @@ static void ohci_rh_resume (void *_hcd) ohci_dbg(ohci, "rh_resume ??\n"); } -#endif /* CONFIG_USB_SUSPEND || CONFIG_PM */ +#endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a574216625a0..e67c07dc426d 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -420,7 +420,7 @@ static const struct hc_driver ohci_omap_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 41e85980fa7a..0afa237b02ad 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -218,7 +218,7 @@ static const struct hc_driver ohci_pci_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 251533363028..ec20710e99fe 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -163,7 +163,7 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif @@ -196,7 +196,7 @@ static struct device_driver ohci_hcd_ppc_soc_driver = { .bus = &platform_bus_type, .probe = ohci_hcd_ppc_soc_drv_probe, .remove = ohci_hcd_ppc_soc_drv_remove, -#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) +#ifdef CONFIG_PM /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ #endif diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index f042261ecb8e..986c4f656e22 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -278,7 +278,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index da7d5478f74d..8cf12b2be2a3 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -448,8 +448,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { */ .hub_status_data = ohci_s3c2410_hub_status_data, .hub_control = ohci_s3c2410_hub_control, - -#if defined(CONFIG_USB_SUSPEND) && 0 +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 814d2be4ee7b..7dd1f410b7f1 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -235,7 +235,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif From e08fb39b771dd7dcba405669b5384fe9929e1caf Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Mon, 19 Sep 2005 09:40:24 -0700 Subject: [PATCH 0830/1940] [PATCH] USB: Fix usb hub build Signed-off-by: Matt Porter Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b2ae9b6ca4db..660064466791 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1977,7 +1977,7 @@ int usb_suspend_device(struct usb_device *udev) int usb_resume_device(struct usb_device *udev) { - udev->dev.power_state.event = PM_EVENT_ON; + udev->dev.power.power_state.event = PM_EVENT_ON; return 0; } From 8b4cd42134fbd3c9a9a5c3467d31717798219b1b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 16 Sep 2005 14:17:45 -0400 Subject: [PATCH 0831/1940] [PATCH] USB: UHCI: Remove unused fields and unneeded tests for NULL This patch (as562) removes from the uhci-hcd driver a few unused fields and some unnecessary tests against NULL and assignments to NULL. In fact it wasn't until fairly recently that the tests became unnecessary. Before last winter it was possible that the driver's stop() routine would get called even if the start() routine returned an error, but now that can't happen. Hence there's no longer any need to check for partial initialization. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 1 - drivers/usb/host/uhci-hcd.c | 44 ++++++++--------------------------- drivers/usb/host/uhci-hcd.h | 3 --- drivers/usb/host/uhci-q.c | 5 ---- 4 files changed, 10 insertions(+), 43 deletions(-) diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 4538a98b6f9d..04eddd7995c3 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *bu if (urbp->urb->status != -EINPROGRESS) out += sprintf(out, "Status=%d ", urbp->urb->status); - //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime); //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); count = 0; diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 0c024898cbea..17de9ee910f6 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -437,36 +437,18 @@ static void release_uhci(struct uhci_hcd *uhci) int i; for (i = 0; i < UHCI_NUM_SKELQH; i++) - if (uhci->skelqh[i]) { - uhci_free_qh(uhci, uhci->skelqh[i]); - uhci->skelqh[i] = NULL; - } + uhci_free_qh(uhci, uhci->skelqh[i]); - if (uhci->term_td) { - uhci_free_td(uhci, uhci->term_td); - uhci->term_td = NULL; - } + uhci_free_td(uhci, uhci->term_td); - if (uhci->qh_pool) { - dma_pool_destroy(uhci->qh_pool); - uhci->qh_pool = NULL; - } + dma_pool_destroy(uhci->qh_pool); - if (uhci->td_pool) { - dma_pool_destroy(uhci->td_pool); - uhci->td_pool = NULL; - } + dma_pool_destroy(uhci->td_pool); - if (uhci->fl) { - dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), - uhci->fl, uhci->fl->dma_handle); - uhci->fl = NULL; - } + dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), + uhci->fl, uhci->fl->dma_handle); - if (uhci->dentry) { - debugfs_remove(uhci->dentry); - uhci->dentry = NULL; - } + debugfs_remove(uhci->dentry); } static int uhci_reset(struct usb_hcd *hcd) @@ -690,31 +672,25 @@ static int uhci_start(struct usb_hcd *hcd) * error exits: */ err_alloc_skelqh: - for (i = 0; i < UHCI_NUM_SKELQH; i++) - if (uhci->skelqh[i]) { + for (i = 0; i < UHCI_NUM_SKELQH; i++) { + if (uhci->skelqh[i]) uhci_free_qh(uhci, uhci->skelqh[i]); - uhci->skelqh[i] = NULL; - } + } uhci_free_td(uhci, uhci->term_td); - uhci->term_td = NULL; err_alloc_term_td: dma_pool_destroy(uhci->qh_pool); - uhci->qh_pool = NULL; err_create_qh_pool: dma_pool_destroy(uhci->td_pool); - uhci->td_pool = NULL; err_create_td_pool: dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); - uhci->fl = NULL; err_alloc_fl: debugfs_remove(uhci->dentry); - uhci->dentry = NULL; err_create_debug_entry: return retval; diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 282f40b75881..1c161b4f5bcf 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -205,8 +205,6 @@ struct uhci_td { /* Software fields */ dma_addr_t dma_handle; - struct urb *urb; - struct list_head list; /* P: urb->lock */ struct list_head remove_list; /* P: uhci->td_remove_list_lock */ @@ -434,7 +432,6 @@ struct urb_priv { /* a control transfer, retrigger */ /* the status phase */ - unsigned long inserttime; /* In jiffies */ unsigned long fsbrtime; /* In jiffies */ struct list_head queue_list; /* P: uhci->frame_list_lock */ diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 4e0fbe2c1a9a..d54038211ca6 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -443,7 +443,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u memset((void *)urbp, 0, sizeof(*urbp)); - urbp->inserttime = jiffies; urbp->fsbrtime = jiffies; urbp->urb = urb; @@ -462,8 +461,6 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) { struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; - td->urb = urb; - list_add_tail(&td->list, &urbp->td_list); } @@ -473,8 +470,6 @@ static void uhci_remove_td_from_urb(struct uhci_td *td) return; list_del_init(&td->list); - - td->urb = NULL; } static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) From a1d59ce842a35b552f22868404e4e7c923242257 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 16 Sep 2005 14:22:51 -0400 Subject: [PATCH 0832/1940] [PATCH] USB: UHCI: Split apart the physical and logical framelist arrays This patch (as563) splits the physical and logical framelist arrays in uhci-hcd into two separate pieces. This will allow slightly better memory utilization, since each piece is no larger than a single page whereas before the whole thing was a little bigger than two pages. It also allows the logical array to be allocated in non-DMA-coherent memory. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 4 ++-- drivers/usb/host/uhci-hcd.c | 42 ++++++++++++++++++++++------------- drivers/usb/host/uhci-hcd.h | 6 ++++- drivers/usb/host/uhci-q.c | 20 ++++++++--------- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 04eddd7995c3..151154df37fa 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -445,11 +445,11 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) out += sprintf(out, "Frame List\n"); for (i = 0; i < UHCI_NUMFRAMES; ++i) { int shown = 0; - td = uhci->fl->frame_cpu[i]; + td = uhci->frame_cpu[i]; if (!td) continue; - if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) { + if (td->dma_handle != (dma_addr_t)uhci->frame[i]) { show_frame_num(); out += sprintf(out, " frame list does not match td->dma_handle!\n"); } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 17de9ee910f6..b44094fcd779 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -212,7 +212,7 @@ static void configure_hc(struct uhci_hcd *uhci) outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); /* Store the frame list base address */ - outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); + outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); /* Set the current frame number */ outw(uhci->frame_number, uhci->io_addr + USBFRNUM); @@ -445,8 +445,11 @@ static void release_uhci(struct uhci_hcd *uhci) dma_pool_destroy(uhci->td_pool); - dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), - uhci->fl, uhci->fl->dma_handle); + kfree(uhci->frame_cpu); + + dma_free_coherent(uhci_dev(uhci), + UHCI_NUMFRAMES * sizeof(*uhci->frame), + uhci->frame, uhci->frame_dma_handle); debugfs_remove(uhci->dentry); } @@ -527,7 +530,6 @@ static int uhci_start(struct usb_hcd *hcd) struct uhci_hcd *uhci = hcd_to_uhci(hcd); int retval = -EBUSY; int i; - dma_addr_t dma_handle; struct dentry *dentry; hcd->uses_new_polling = 1; @@ -561,17 +563,23 @@ static int uhci_start(struct usb_hcd *hcd) init_waitqueue_head(&uhci->waitqh); - uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl), - &dma_handle, 0); - if (!uhci->fl) { + uhci->frame = dma_alloc_coherent(uhci_dev(uhci), + UHCI_NUMFRAMES * sizeof(*uhci->frame), + &uhci->frame_dma_handle, 0); + if (!uhci->frame) { dev_err(uhci_dev(uhci), "unable to allocate " "consistent memory for frame list\n"); - goto err_alloc_fl; + goto err_alloc_frame; } + memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); - memset((void *)uhci->fl, 0, sizeof(*uhci->fl)); - - uhci->fl->dma_handle = dma_handle; + uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), + GFP_KERNEL); + if (!uhci->frame_cpu) { + dev_err(uhci_dev(uhci), "unable to allocate " + "memory for frame pointers\n"); + goto err_alloc_frame_cpu; + } uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), sizeof(struct uhci_td), 16, 0); @@ -654,7 +662,7 @@ static int uhci_start(struct usb_hcd *hcd) irq = 7; /* Only place we don't use the frame list routines */ - uhci->fl->frame[i] = UHCI_PTR_QH | + uhci->frame[i] = UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[irq]->dma_handle); } @@ -686,10 +694,14 @@ static int uhci_start(struct usb_hcd *hcd) dma_pool_destroy(uhci->td_pool); err_create_td_pool: - dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), - uhci->fl, uhci->fl->dma_handle); + kfree(uhci->frame_cpu); -err_alloc_fl: +err_alloc_frame_cpu: + dma_free_coherent(uhci_dev(uhci), + UHCI_NUMFRAMES * sizeof(*uhci->frame), + uhci->frame, uhci->frame_dma_handle); + +err_alloc_frame: debugfs_remove(uhci->dentry); err_create_debug_entry: diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 1c161b4f5bcf..b04d99df0a0e 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -359,7 +359,11 @@ struct uhci_hcd { struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ spinlock_t lock; - struct uhci_frame_list *fl; /* P: uhci->lock */ + + dma_addr_t frame_dma_handle; /* Hardware frame list */ + __le32 *frame; /* P: uhci->lock */ + void **frame_cpu; /* CPU's frame list */ + int fsbr; /* Full-speed bandwidth reclamation */ unsigned long fsbrtimeout; /* FSBR delay */ diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index d54038211ca6..51de06bc438d 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, td->frame = framenum; /* Is there a TD already mapped there? */ - if (uhci->fl->frame_cpu[framenum]) { + if (uhci->frame_cpu[framenum]) { struct uhci_td *ftd, *ltd; - ftd = uhci->fl->frame_cpu[framenum]; + ftd = uhci->frame_cpu[framenum]; ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); list_add_tail(&td->fl_list, &ftd->fl_list); @@ -101,10 +101,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, wmb(); ltd->link = cpu_to_le32(td->dma_handle); } else { - td->link = uhci->fl->frame[framenum]; + td->link = uhci->frame[framenum]; wmb(); - uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle); - uhci->fl->frame_cpu[framenum] = td; + uhci->frame[framenum] = cpu_to_le32(td->dma_handle); + uhci->frame_cpu[framenum] = td; } } @@ -114,16 +114,16 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) if (td->frame == -1 && list_empty(&td->fl_list)) return; - if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) { + if (td->frame != -1 && uhci->frame_cpu[td->frame] == td) { if (list_empty(&td->fl_list)) { - uhci->fl->frame[td->frame] = td->link; - uhci->fl->frame_cpu[td->frame] = NULL; + uhci->frame[td->frame] = td->link; + uhci->frame_cpu[td->frame] = NULL; } else { struct uhci_td *ntd; ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); - uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle); - uhci->fl->frame_cpu[td->frame] = ntd; + uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); + uhci->frame_cpu[td->frame] = ntd; } } else { struct uhci_td *ptd; From e9b7bd4ee7f6e3ee002dc72c5211cd97c7186d00 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:30:48 -0700 Subject: [PATCH 0833/1940] [PATCH] one less word in struct device This saves a word from "struct device" ... there's a refcounting mechanism stub that's rather ineffective (the values are never even tested!), which can safely be deleted. With this patch it uses normal device refcounting, so any potential users of the pm_parent mechanism will be more correct. (That mechanism is actually unusable for now though; it does nothing.) Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/base/power/main.c | 26 +++----------------------- include/linux/pm.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-) --- drivers/base/power/main.c | 26 +++----------------------- include/linux/pm.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 15e6a8f951f1..0d2e101e4f15 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -30,23 +30,6 @@ LIST_HEAD(dpm_off_irq); DECLARE_MUTEX(dpm_sem); DECLARE_MUTEX(dpm_list_sem); -/* - * PM Reference Counting. - */ - -static inline void device_pm_hold(struct device * dev) -{ - if (dev) - atomic_inc(&dev->power.pm_users); -} - -static inline void device_pm_release(struct device * dev) -{ - if (dev) - atomic_dec(&dev->power.pm_users); -} - - /** * device_pm_set_parent - Specify power dependency. * @dev: Device who needs power. @@ -62,10 +45,8 @@ static inline void device_pm_release(struct device * dev) void device_pm_set_parent(struct device * dev, struct device * parent) { - struct device * old_parent = dev->power.pm_parent; - device_pm_release(old_parent); - dev->power.pm_parent = parent; - device_pm_hold(parent); + put_device(dev->power.pm_parent); + dev->power.pm_parent = get_device(parent); } EXPORT_SYMBOL_GPL(device_pm_set_parent); @@ -75,7 +56,6 @@ int device_pm_add(struct device * dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); - atomic_set(&dev->power.pm_users, 0); down(&dpm_list_sem); list_add_tail(&dev->power.entry, &dpm_active); device_pm_set_parent(dev, dev->parent); @@ -91,7 +71,7 @@ void device_pm_remove(struct device * dev) dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); down(&dpm_list_sem); dpm_sysfs_remove(dev); - device_pm_release(dev->power.pm_parent); + put_device(dev->power.pm_parent); list_del_init(&dev->power.entry); up(&dpm_list_sem); } diff --git a/include/linux/pm.h b/include/linux/pm.h index 7897cf500c51..83bae1cbe55b 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -224,7 +224,6 @@ struct dev_pm_info { unsigned should_wakeup:1; pm_message_t prev_state; void * saved_state; - atomic_t pm_users; struct device * pm_parent; struct list_head entry; #endif From 7ff71d6adf81a43505b7cbaa034e4063d3439182 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Thu, 22 Sep 2005 22:31:15 -0700 Subject: [PATCH 0834/1940] [PATCH] EHCI, split out PCI glue This splits BIOS and PCI specific support out of ehci-hcd.c into ehci-pci.c. It follows the model already used in the OHCI driver so support for non-PCI EHCI controllers can be more easily added. Signed-off-by: Matt Porter Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/host/ehci-hcd.c | 543 ++++++-------------------------------------- drivers/usb/host/ehci-pci.c | 414 +++++++++++++++++++++++++++++++++ drivers/usb/host/ehci.h | 1 3 files changed, 492 insertions(+), 466 deletions(-) --- drivers/usb/host/ehci-hcd.c | 559 ++++++------------------------------ drivers/usb/host/ehci-pci.c | 414 ++++++++++++++++++++++++++ drivers/usb/host/ehci.h | 1 + 3 files changed, 500 insertions(+), 474 deletions(-) create mode 100644 drivers/usb/host/ehci-pci.c diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 513fccbb8e43..af3c05eb86fc 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -300,44 +300,6 @@ static void ehci_watchdog (unsigned long param) spin_unlock_irqrestore (&ehci->lock, flags); } -#ifdef CONFIG_PCI - -/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... - * off the controller (maybe it can boot from highspeed USB disks). - */ -static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) -{ - struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); - - /* always say Linux will own the hardware */ - pci_write_config_byte(pdev, where + 3, 1); - - /* maybe wait a while for BIOS to respond */ - if (cap & (1 << 16)) { - int msec = 5000; - - do { - msleep(10); - msec -= 10; - pci_read_config_dword(pdev, where, &cap); - } while ((cap & (1 << 16)) && msec); - if (cap & (1 << 16)) { - ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", - where, cap); - // some BIOS versions seem buggy... - // return 1; - ehci_warn (ehci, "continuing after BIOS bug...\n"); - /* disable all SMIs, and clear "BIOS owns" flag */ - pci_write_config_dword(pdev, where + 4, 0); - pci_write_config_byte(pdev, where + 2, 0); - } else - ehci_dbg(ehci, "BIOS handoff succeeded\n"); - } - return 0; -} - -#endif - /* Reboot notifiers kick in for silicon on any bus (not just pci, etc). * This forcibly disables dma and IRQs, helping kexec and other cases * where the next system software may expect clean state. @@ -371,156 +333,90 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) msleep(20); } +/*-------------------------------------------------------------------------*/ -/* called by khubd or root hub init threads */ - -static int ehci_hc_reset (struct usb_hcd *hcd) +/* + * ehci_work is called from some interrupts, timers, and so on. + * it calls driver completion functions, after dropping ehci->lock. + */ +static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) { - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 temp; - unsigned count = 256/4; + timer_action_done (ehci, TIMER_IO_WATCHDOG); + if (ehci->reclaim_ready) + end_unlink_async (ehci, regs); - spin_lock_init (&ehci->lock); + /* another CPU may drop ehci->lock during a schedule scan while + * it reports urb completions. this flag guards against bogus + * attempts at re-entrant schedule scanning. + */ + if (ehci->scanning) + return; + ehci->scanning = 1; + scan_async (ehci, regs); + if (ehci->next_uframe != -1) + scan_periodic (ehci, regs); + ehci->scanning = 0; - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); - dbg_hcs_params (ehci, "reset"); - dbg_hcc_params (ehci, "reset"); - - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = readl (&ehci->caps->hcs_params); - -#ifdef CONFIG_PCI - if (hcd->self.controller->bus == &pci_bus_type) { - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - - switch (pdev->vendor) { - case PCI_VENDOR_ID_TDI: - if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { - ehci->is_tdi_rh_tt = 1; - tdi_reset (ehci); - } - break; - case PCI_VENDOR_ID_AMD: - /* AMD8111 EHCI doesn't work, according to AMD errata */ - if (pdev->device == 0x7463) { - ehci_info (ehci, "ignoring AMD8111 (errata)\n"); - return -EIO; - } - break; - case PCI_VENDOR_ID_NVIDIA: - /* NVidia reports that certain chips don't handle - * QH, ITD, or SITD addresses above 2GB. (But TD, - * data buffer, and periodic schedule are normal.) - */ - switch (pdev->device) { - case 0x003c: /* MCP04 */ - case 0x005b: /* CK804 */ - case 0x00d8: /* CK8 */ - case 0x00e8: /* CK8S */ - if (pci_set_consistent_dma_mask(pdev, - DMA_31BIT_MASK) < 0) - ehci_warn (ehci, "can't enable NVidia " - "workaround for >2GB RAM\n"); - break; - } - break; - } - - /* optional debug port, normally in the first BAR */ - temp = pci_find_capability (pdev, 0x0a); - if (temp) { - pci_read_config_dword(pdev, temp, &temp); - temp >>= 16; - if ((temp & (3 << 13)) == (1 << 13)) { - temp &= 0x1fff; - ehci->debug = hcd->regs + temp; - temp = readl (&ehci->debug->control); - ehci_info (ehci, "debug port %d%s\n", - HCS_DEBUG_PORT(ehci->hcs_params), - (temp & DBGP_ENABLED) - ? " IN USE" - : ""); - if (!(temp & DBGP_ENABLED)) - ehci->debug = NULL; - } - } - - temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); - } else - temp = 0; - - /* EHCI 0.96 and later may have "extended capabilities" */ - while (temp && count--) { - u32 cap; - - pci_read_config_dword (to_pci_dev(hcd->self.controller), - temp, &cap); - ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); - switch (cap & 0xff) { - case 1: /* BIOS/SMM/... handoff */ - if (bios_handoff (ehci, temp, cap) != 0) - return -EOPNOTSUPP; - break; - case 0: /* illegal reserved capability */ - ehci_warn (ehci, "illegal capability!\n"); - cap = 0; - /* FALLTHROUGH */ - default: /* unknown */ - break; - } - temp = (cap >> 8) & 0xff; - } - if (!count) { - ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); - return -EIO; - } - if (ehci_is_TDI(ehci)) - ehci_reset (ehci); -#endif - - ehci_port_power (ehci, 0); - - /* at least the Genesys GL880S needs fixup here */ - temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); - temp &= 0x0f; - if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { - ehci_dbg (ehci, "bogus port configuration: " - "cc=%d x pcc=%d < ports=%d\n", - HCS_N_CC(ehci->hcs_params), - HCS_N_PCC(ehci->hcs_params), - HCS_N_PORTS(ehci->hcs_params)); - -#ifdef CONFIG_PCI - if (hcd->self.controller->bus == &pci_bus_type) { - struct pci_dev *pdev; - - pdev = to_pci_dev(hcd->self.controller); - switch (pdev->vendor) { - case 0x17a0: /* GENESYS */ - /* GL880S: should be PORTS=2 */ - temp |= (ehci->hcs_params & ~0xf); - ehci->hcs_params = temp; - break; - case PCI_VENDOR_ID_NVIDIA: - /* NF4: should be PCC=10 */ - break; - } - } -#endif - } - - /* force HC to halt state */ - return ehci_halt (ehci); + /* the IO watchdog guards against hardware or driver bugs that + * misplace IRQs, and should let us run completely without IRQs. + * such lossage has been observed on both VT6202 and VT8235. + */ + if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && + (ehci->async->qh_next.ptr != NULL || + ehci->periodic_sched != 0)) + timer_action (ehci, TIMER_IO_WATCHDOG); } -static int ehci_start (struct usb_hcd *hcd) +static void ehci_stop (struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + + ehci_dbg (ehci, "stop\n"); + + /* Turn off port power on all root hub ports. */ + ehci_port_power (ehci, 0); + + /* no more interrupts ... */ + del_timer_sync (&ehci->watchdog); + + spin_lock_irq(&ehci->lock); + if (HC_IS_RUNNING (hcd->state)) + ehci_quiesce (ehci); + + ehci_reset (ehci); + writel (0, &ehci->regs->intr_enable); + spin_unlock_irq(&ehci->lock); + + /* let companion controllers work when we aren't */ + writel (0, &ehci->regs->configured_flag); + unregister_reboot_notifier (&ehci->reboot_notifier); + + remove_debug_files (ehci); + + /* root hub is shut down separately (first, when possible) */ + spin_lock_irq (&ehci->lock); + if (ehci->async) + ehci_work (ehci, NULL); + spin_unlock_irq (&ehci->lock); + ehci_mem_cleanup (ehci); + +#ifdef EHCI_STATS + ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", + ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, + ehci->stats.lost_iaa); + ehci_dbg (ehci, "complete %ld unlink %ld\n", + ehci->stats.complete, ehci->stats.unlink); +#endif + + dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); +} + +static int ehci_run (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp; int retval; u32 hcc_params; - u8 sbrn = 0; int first; /* skip some things on restart paths */ @@ -559,27 +455,6 @@ static int ehci_start (struct usb_hcd *hcd) } writel (ehci->periodic_dma, &ehci->regs->frame_list); -#ifdef CONFIG_PCI - if (hcd->self.controller->bus == &pci_bus_type) { - struct pci_dev *pdev; - u16 port_wake; - - pdev = to_pci_dev(hcd->self.controller); - - /* Serial Bus Release Number is at PCI 0x60 offset */ - pci_read_config_byte(pdev, 0x60, &sbrn); - - /* port wake capability, reported by boot firmware */ - pci_read_config_word(pdev, 0x62, &port_wake); - hcd->can_wakeup = (port_wake & 1) != 0; - - /* help hc dma work well with cachelines */ - retval = pci_set_mwi(pdev); - if (retval) - ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); - } -#endif - /* * dedicate a qh for the async ring head, since we couldn't unlink * a 'real' qh without stopping the async schedule [4.8]. use it @@ -675,7 +550,7 @@ static int ehci_start (struct usb_hcd *hcd) temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, "USB %x.%x %s, EHCI %x.%02x, driver %s\n", - ((sbrn & 0xf0)>>4), (sbrn & 0x0f), + ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), first ? "initialized" : "restarted", temp >> 8, temp & 0xff, DRIVER_VERSION); @@ -687,188 +562,6 @@ static int ehci_start (struct usb_hcd *hcd) return 0; } -/* always called by thread; normally rmmod */ - -static void ehci_stop (struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - - ehci_dbg (ehci, "stop\n"); - - /* Turn off port power on all root hub ports. */ - ehci_port_power (ehci, 0); - - /* no more interrupts ... */ - del_timer_sync (&ehci->watchdog); - - spin_lock_irq(&ehci->lock); - if (HC_IS_RUNNING (hcd->state)) - ehci_quiesce (ehci); - - ehci_reset (ehci); - writel (0, &ehci->regs->intr_enable); - spin_unlock_irq(&ehci->lock); - - /* let companion controllers work when we aren't */ - writel (0, &ehci->regs->configured_flag); - unregister_reboot_notifier (&ehci->reboot_notifier); - - remove_debug_files (ehci); - - /* root hub is shut down separately (first, when possible) */ - spin_lock_irq (&ehci->lock); - if (ehci->async) - ehci_work (ehci, NULL); - spin_unlock_irq (&ehci->lock); - ehci_mem_cleanup (ehci); - -#ifdef EHCI_STATS - ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", - ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, - ehci->stats.lost_iaa); - ehci_dbg (ehci, "complete %ld unlink %ld\n", - ehci->stats.complete, ehci->stats.unlink); -#endif - - dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); -} - -static int ehci_get_frame (struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM - -/* suspend/resume, section 4.3 */ - -/* These routines rely on the bus (pci, platform, etc) - * to handle powerdown and wakeup, and currently also on - * transceivers that don't need any software attention to set up - * the right sort of wakeup. - */ - -static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) -{ - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - - if (time_before (jiffies, ehci->next_statechange)) - msleep (100); - -#ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub); -#else - usb_lock_device (hcd->self.root_hub); - (void) ehci_hub_suspend (hcd); - usb_unlock_device (hcd->self.root_hub); -#endif - - // save (PCI) FLADJ in case of Vaux power loss - // ... we'd only use it to handle clock skew - - return 0; -} - -static int ehci_resume (struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci (hcd); - unsigned port; - struct usb_device *root = hcd->self.root_hub; - int retval = -EINVAL; - - // maybe restore (PCI) FLADJ - - if (time_before (jiffies, ehci->next_statechange)) - msleep (100); - - /* If any port is suspended (or owned by the companion), - * we know we can/must resume the HC (and mustn't reset it). - */ - for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { - u32 status; - port--; - status = readl (&ehci->regs->port_status [port]); - if (!(status & PORT_POWER)) - continue; - if (status & (PORT_SUSPEND | PORT_OWNER)) { - down (&hcd->self.root_hub->serialize); - retval = ehci_hub_resume (hcd); - up (&hcd->self.root_hub->serialize); - break; - } - if (!root->children [port]) - continue; - dbg_port (ehci, __FUNCTION__, port + 1, status); - usb_set_device_state (root->children[port], - USB_STATE_NOTATTACHED); - } - - /* Else reset, to cope with power loss or flush-to-storage - * style "resume" having activated BIOS during reboot. - */ - if (port == 0) { - (void) ehci_halt (ehci); - (void) ehci_reset (ehci); - (void) ehci_hc_reset (hcd); - - /* emptying the schedule aborts any urbs */ - spin_lock_irq (&ehci->lock); - if (ehci->reclaim) - ehci->reclaim_ready = 1; - ehci_work (ehci, NULL); - spin_unlock_irq (&ehci->lock); - - /* restart; khubd will disconnect devices */ - retval = ehci_start (hcd); - - /* here we "know" root ports should always stay powered; - * but some controllers may lose all power. - */ - ehci_port_power (ehci, 1); - } - - return retval; -} - -#endif - -/*-------------------------------------------------------------------------*/ - -/* - * ehci_work is called from some interrupts, timers, and so on. - * it calls driver completion functions, after dropping ehci->lock. - */ -static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) -{ - timer_action_done (ehci, TIMER_IO_WATCHDOG); - if (ehci->reclaim_ready) - end_unlink_async (ehci, regs); - - /* another CPU may drop ehci->lock during a schedule scan while - * it reports urb completions. this flag guards against bogus - * attempts at re-entrant schedule scanning. - */ - if (ehci->scanning) - return; - ehci->scanning = 1; - scan_async (ehci, regs); - if (ehci->next_uframe != -1) - scan_periodic (ehci, regs); - ehci->scanning = 0; - - /* the IO watchdog guards against hardware or driver bugs that - * misplace IRQs, and should let us run completely without IRQs. - * such lossage has been observed on both VT6202 and VT8235. - */ - if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && - (ehci->async->qh_next.ptr != NULL || - ehci->periodic_sched != 0)) - timer_action (ehci, TIMER_IO_WATCHDOG); -} - /*-------------------------------------------------------------------------*/ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) @@ -1179,106 +872,24 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) return; } -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ehci_driver = { - .description = hcd_name, - .product_desc = "EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_hc_reset, - .start = ehci_start, -#ifdef CONFIG_PM - .suspend = ehci_suspend, - .resume = ehci_resume, -#endif - .stop = ehci_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .hub_suspend = ehci_hub_suspend, - .hub_resume = ehci_hub_resume, -}; +static int ehci_get_frame (struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; +} /*-------------------------------------------------------------------------*/ -/* EHCI 1.0 doesn't require PCI */ - -#ifdef CONFIG_PCI - -/* PCI driver selection metadata; PCI hotplugging uses this */ -static const struct pci_device_id pci_ids [] = { { - /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), - .driver_data = (unsigned long) &ehci_driver, - }, - { /* end: all zeroes */ } -}; -MODULE_DEVICE_TABLE (pci, pci_ids); - -/* pci driver glue; this is a "new style" PCI driver module */ -static struct pci_driver ehci_pci_driver = { - .name = (char *) hcd_name, - .id_table = pci_ids, - - .probe = usb_hcd_pci_probe, - .remove = usb_hcd_pci_remove, - -#ifdef CONFIG_PM - .suspend = usb_hcd_pci_suspend, - .resume = usb_hcd_pci_resume, -#endif -}; - -#endif /* PCI */ - - #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC MODULE_DESCRIPTION (DRIVER_INFO); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); -static int __init init (void) -{ - if (usb_disabled()) - return -ENODEV; +#ifdef CONFIG_PCI +#include "ehci-pci.c" +#endif - pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", - hcd_name, - sizeof (struct ehci_qh), sizeof (struct ehci_qtd), - sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); - - return pci_register_driver (&ehci_pci_driver); -} -module_init (init); - -static void __exit cleanup (void) -{ - pci_unregister_driver (&ehci_pci_driver); -} -module_exit (cleanup); +#if !defined(CONFIG_PCI) +#error "missing bus glue for ehci-hcd" +#endif diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c new file mode 100644 index 000000000000..66ebf75b2037 --- /dev/null +++ b/drivers/usb/host/ehci-pci.c @@ -0,0 +1,414 @@ +/* + * EHCI HCD (Host Controller Driver) PCI Bus Glue. + * + * Copyright (c) 2000-2004 by David Brownell + * + * 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 this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef CONFIG_PCI +#error "This file is PCI bus glue. CONFIG_PCI must be defined." +#endif + +/*-------------------------------------------------------------------------*/ + +/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... + * off the controller (maybe it can boot from highspeed USB disks). + */ +static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) +{ + struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); + + /* always say Linux will own the hardware */ + pci_write_config_byte(pdev, where + 3, 1); + + /* maybe wait a while for BIOS to respond */ + if (cap & (1 << 16)) { + int msec = 5000; + + do { + msleep(10); + msec -= 10; + pci_read_config_dword(pdev, where, &cap); + } while ((cap & (1 << 16)) && msec); + if (cap & (1 << 16)) { + ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", + where, cap); + // some BIOS versions seem buggy... + // return 1; + ehci_warn (ehci, "continuing after BIOS bug...\n"); + /* disable all SMIs, and clear "BIOS owns" flag */ + pci_write_config_dword(pdev, where + 4, 0); + pci_write_config_byte(pdev, where + 2, 0); + } else + ehci_dbg(ehci, "BIOS handoff succeeded\n"); + } + return 0; +} + +/* called by khubd or root hub init threads */ +static int ehci_pci_reset (struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + u32 temp; + unsigned count = 256/4; + + spin_lock_init (&ehci->lock); + + ehci->caps = hcd->regs; + ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); + dbg_hcs_params (ehci, "reset"); + dbg_hcc_params (ehci, "reset"); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = readl (&ehci->caps->hcs_params); + + if (hcd->self.controller->bus == &pci_bus_type) { + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + switch (pdev->vendor) { + case PCI_VENDOR_ID_TDI: + if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { + ehci->is_tdi_rh_tt = 1; + tdi_reset (ehci); + } + break; + case PCI_VENDOR_ID_AMD: + /* AMD8111 EHCI doesn't work, according to AMD errata */ + if (pdev->device == 0x7463) { + ehci_info (ehci, "ignoring AMD8111 (errata)\n"); + return -EIO; + } + break; + case PCI_VENDOR_ID_NVIDIA: + /* NVidia reports that certain chips don't handle + * QH, ITD, or SITD addresses above 2GB. (But TD, + * data buffer, and periodic schedule are normal.) + */ + switch (pdev->device) { + case 0x003c: /* MCP04 */ + case 0x005b: /* CK804 */ + case 0x00d8: /* CK8 */ + case 0x00e8: /* CK8S */ + if (pci_set_consistent_dma_mask(pdev, + DMA_31BIT_MASK) < 0) + ehci_warn (ehci, "can't enable NVidia " + "workaround for >2GB RAM\n"); + break; + } + break; + } + + /* optional debug port, normally in the first BAR */ + temp = pci_find_capability (pdev, 0x0a); + if (temp) { + pci_read_config_dword(pdev, temp, &temp); + temp >>= 16; + if ((temp & (3 << 13)) == (1 << 13)) { + temp &= 0x1fff; + ehci->debug = hcd->regs + temp; + temp = readl (&ehci->debug->control); + ehci_info (ehci, "debug port %d%s\n", + HCS_DEBUG_PORT(ehci->hcs_params), + (temp & DBGP_ENABLED) + ? " IN USE" + : ""); + if (!(temp & DBGP_ENABLED)) + ehci->debug = NULL; + } + } + + temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); + } else + temp = 0; + + /* EHCI 0.96 and later may have "extended capabilities" */ + while (temp && count--) { + u32 cap; + + pci_read_config_dword (to_pci_dev(hcd->self.controller), + temp, &cap); + ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); + switch (cap & 0xff) { + case 1: /* BIOS/SMM/... handoff */ + if (bios_handoff (ehci, temp, cap) != 0) + return -EOPNOTSUPP; + break; + case 0: /* illegal reserved capability */ + ehci_warn (ehci, "illegal capability!\n"); + cap = 0; + /* FALLTHROUGH */ + default: /* unknown */ + break; + } + temp = (cap >> 8) & 0xff; + } + if (!count) { + ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); + return -EIO; + } + if (ehci_is_TDI(ehci)) + ehci_reset (ehci); + + ehci_port_power (ehci, 0); + + /* at least the Genesys GL880S needs fixup here */ + temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); + temp &= 0x0f; + if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { + ehci_dbg (ehci, "bogus port configuration: " + "cc=%d x pcc=%d < ports=%d\n", + HCS_N_CC(ehci->hcs_params), + HCS_N_PCC(ehci->hcs_params), + HCS_N_PORTS(ehci->hcs_params)); + + if (hcd->self.controller->bus == &pci_bus_type) { + struct pci_dev *pdev; + + pdev = to_pci_dev(hcd->self.controller); + switch (pdev->vendor) { + case 0x17a0: /* GENESYS */ + /* GL880S: should be PORTS=2 */ + temp |= (ehci->hcs_params & ~0xf); + ehci->hcs_params = temp; + break; + case PCI_VENDOR_ID_NVIDIA: + /* NF4: should be PCC=10 */ + break; + } + } + } + + /* force HC to halt state */ + return ehci_halt (ehci); +} + +static int ehci_pci_start (struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + int result = 0; + + if (hcd->self.controller->bus == &pci_bus_type) { + struct pci_dev *pdev; + u16 port_wake; + + pdev = to_pci_dev(hcd->self.controller); + + /* Serial Bus Release Number is at PCI 0x60 offset */ + pci_read_config_byte(pdev, 0x60, &ehci->sbrn); + + /* port wake capability, reported by boot firmware */ + pci_read_config_word(pdev, 0x62, &port_wake); + hcd->can_wakeup = (port_wake & 1) != 0; + + /* help hc dma work well with cachelines */ + result = pci_set_mwi(pdev); + if (result) + ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); + } + + return ehci_run (hcd); +} + +/* always called by thread; normally rmmod */ + +static void ehci_pci_stop (struct usb_hcd *hcd) +{ + ehci_stop (hcd); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_PM + +/* suspend/resume, section 4.3 */ + +/* These routines rely on the bus (pci, platform, etc) + * to handle powerdown and wakeup, and currently also on + * transceivers that don't need any software attention to set up + * the right sort of wakeup. + */ + +static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + + if (time_before (jiffies, ehci->next_statechange)) + msleep (100); + +#ifdef CONFIG_USB_SUSPEND + (void) usb_suspend_device (hcd->self.root_hub); +#else + usb_lock_device (hcd->self.root_hub); + (void) ehci_hub_suspend (hcd); + usb_unlock_device (hcd->self.root_hub); +#endif + + // save (PCI) FLADJ in case of Vaux power loss + // ... we'd only use it to handle clock skew + + return 0; +} + +static int ehci_pci_resume (struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci (hcd); + unsigned port; + struct usb_device *root = hcd->self.root_hub; + int retval = -EINVAL; + + // maybe restore (PCI) FLADJ + + if (time_before (jiffies, ehci->next_statechange)) + msleep (100); + + /* If any port is suspended (or owned by the companion), + * we know we can/must resume the HC (and mustn't reset it). + */ + for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { + u32 status; + port--; + status = readl (&ehci->regs->port_status [port]); + if (!(status & PORT_POWER)) + continue; + if (status & (PORT_SUSPEND | PORT_OWNER)) { + down (&hcd->self.root_hub->serialize); + retval = ehci_hub_resume (hcd); + up (&hcd->self.root_hub->serialize); + break; + } + if (!root->children [port]) + continue; + dbg_port (ehci, __FUNCTION__, port + 1, status); + usb_set_device_state (root->children[port], + USB_STATE_NOTATTACHED); + } + + /* Else reset, to cope with power loss or flush-to-storage + * style "resume" having activated BIOS during reboot. + */ + if (port == 0) { + (void) ehci_halt (ehci); + (void) ehci_reset (ehci); + (void) ehci_pci_reset (hcd); + + /* emptying the schedule aborts any urbs */ + spin_lock_irq (&ehci->lock); + if (ehci->reclaim) + ehci->reclaim_ready = 1; + ehci_work (ehci, NULL); + spin_unlock_irq (&ehci->lock); + + /* restart; khubd will disconnect devices */ + retval = ehci_run (hcd); + + /* here we "know" root ports should always stay powered; + * but some controllers may lose all power. + */ + ehci_port_power (ehci, 1); + } + + return retval; +} +#endif + +static const struct hc_driver ehci_pci_hc_driver = { + .description = hcd_name, + .product_desc = "EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + /* + * basic lifecycle operations + */ + .reset = ehci_pci_reset, + .start = ehci_pci_start, +#ifdef CONFIG_PM + .suspend = ehci_pci_suspend, + .resume = ehci_pci_resume, +#endif + .stop = ehci_pci_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .hub_suspend = ehci_hub_suspend, + .hub_resume = ehci_hub_resume, +}; + +/*-------------------------------------------------------------------------*/ + +/* PCI driver selection metadata; PCI hotplugging uses this */ +static const struct pci_device_id pci_ids [] = { { + /* handle any USB 2.0 EHCI controller */ + PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), + .driver_data = (unsigned long) &ehci_pci_hc_driver, + }, + { /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE (pci, pci_ids); + +/* pci driver glue; this is a "new style" PCI driver module */ +static struct pci_driver ehci_pci_driver = { + .name = (char *) hcd_name, + .id_table = pci_ids, + + .probe = usb_hcd_pci_probe, + .remove = usb_hcd_pci_remove, + +#ifdef CONFIG_PM + .suspend = usb_hcd_pci_suspend, + .resume = usb_hcd_pci_resume, +#endif +}; + +static int __init ehci_hcd_pci_init (void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", + hcd_name, + sizeof (struct ehci_qh), sizeof (struct ehci_qtd), + sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); + + return pci_register_driver (&ehci_pci_driver); +} +module_init (ehci_hcd_pci_init); + +static void __exit ehci_hcd_pci_cleanup (void) +{ + pci_unregister_driver (&ehci_pci_driver); +} +module_exit (ehci_hcd_pci_cleanup); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f34a0516d35f..18e257c2bdb5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -97,6 +97,7 @@ struct ehci_hcd { /* one per controller */ #else # define COUNT(x) do {} while (0) #endif + u8 sbrn; /* packed release number */ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ From 9293677af3dace2645dec0d0808efa02d36bf47b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:32:11 -0700 Subject: [PATCH 0835/1940] [PATCH] all HCDs provide root hub suspend/resume methods This cleans up a small recent FIXME, ensuring that all the HCDs provide root hub suspend/resume methods. It also wraps the calls to those root suspend routines just like on the PCI "USB_SUSPEND not defined" cases, so non-PCI bus glue won't be as tempted to behave very differently. Several of the SOC based OHCI drivers forgot to list those methods; the patch also adds those missing declarations. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hcd.c | 42 +++++++++++++++++++++++++--------------- drivers/usb/host/ohci-au1xxx.c | 5 ++++ drivers/usb/host/ohci-lh7a404.c | 5 ++++ drivers/usb/host/ohci-pxa27x.c | 1 drivers/usb/host/ohci-s3c2410.c | 1 drivers/usb/host/ohci-sa1111.c | 1 6 files changed, 40 insertions(+), 15 deletions(-) --- drivers/usb/core/hcd.c | 44 +++++++++++++++++++++------------ drivers/usb/host/ohci-au1xxx.c | 5 ++++ drivers/usb/host/ohci-lh7a404.c | 5 ++++ drivers/usb/host/ohci-pxa27x.c | 1 + drivers/usb/host/ohci-s3c2410.c | 1 + drivers/usb/host/ohci-sa1111.c | 1 + 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 5e8ade07d7f9..375382f9d671 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1431,28 +1431,44 @@ hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep) /*-------------------------------------------------------------------------*/ -/* FIXME make this #ifdef CONFIG_PM ... update root hubs, retest */ - -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM static int hcd_hub_suspend (struct usb_bus *bus) { struct usb_hcd *hcd; + int status; hcd = container_of (bus, struct usb_hcd, self); - if (hcd->driver->hub_suspend) - return hcd->driver->hub_suspend (hcd); - return 0; + if (!hcd->driver->hub_suspend) + return -ENOENT; + hcd->state = HC_STATE_QUIESCING; + status = hcd->driver->hub_suspend (hcd); + if (status == 0) + hcd->state = HC_STATE_SUSPENDED; + else + dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n", + "suspend", status); + return status; } static int hcd_hub_resume (struct usb_bus *bus) { struct usb_hcd *hcd; + int status; hcd = container_of (bus, struct usb_hcd, self); - if (hcd->driver->hub_resume) - return hcd->driver->hub_resume (hcd); - return 0; + if (!hcd->driver->hub_resume) + return -ENOENT; + hcd->state = HC_STATE_RESUMING; + status = hcd->driver->hub_resume (hcd); + if (status == 0) + hcd->state = HC_STATE_RUNNING; + else { + dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n", + "resume", status); + usb_hc_died(hcd); + } + return status; } /** @@ -1473,14 +1489,10 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) usb_resume_root_hub (hcd->self.root_hub); spin_unlock_irqrestore (&hcd_root_hub_lock, flags); } - -#else -void usb_hcd_resume_root_hub (struct usb_hcd *hcd) -{ -} -#endif EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); +#endif + /*-------------------------------------------------------------------------*/ #ifdef CONFIG_USB_OTG @@ -1532,7 +1544,7 @@ static struct usb_operations usb_hcd_operations = { .buffer_alloc = hcd_buffer_alloc, .buffer_free = hcd_buffer_free, .disable = hcd_endpoint_disable, -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM .hub_suspend = hcd_hub_suspend, .hub_resume = hcd_hub_resume, #endif diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 3981bf15c8c7..550d67a554f6 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -214,6 +214,11 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, +#ifdef CONFIG_PM + .hub_suspend = ohci_hub_suspend, + .hub_resume = ohci_hub_resume, +#endif + .start_port_reset = ohci_start_port_reset, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 859aca7be753..71d975ae78bd 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -193,6 +193,11 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, +#ifdef CONFIG_PM + .hub_suspend = ohci_hub_suspend, + .hub_resume = ohci_hub_resume, +#endif + .start_port_reset = ohci_start_port_reset, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 986c4f656e22..2e7b48502a3d 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -282,6 +282,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif + .start_port_reset = ohci_start_port_reset, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 8cf12b2be2a3..922e2a6f46ef 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -452,6 +452,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif + .start_port_reset = ohci_start_port_reset, }; /* device driver */ diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 7dd1f410b7f1..13324b7f9c59 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -239,6 +239,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = { .hub_suspend = ohci_hub_suspend, .hub_resume = ohci_hub_resume, #endif + .start_port_reset = ohci_start_port_reset, }; /*-------------------------------------------------------------------------*/ From 979d5199fee9e80290ddeb532e5993bd15506712 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:32:24 -0700 Subject: [PATCH 0836/1940] [PATCH] root hub changes (lesser half) This patch collects various small updates related to root hubs, to shrink later patches which build on them. - For root hub suspend/resume support: * Make the existing usb_hcd_resume_root_hub() routine respect pmcore locking, exporting and using the dpm_runtime_resume() method. * Add a new usb_hcd_suspend_root_hub() to pair with that routine. (Essential to make OHCI autosuspend behave again...) * HC_SUSPENDED by itself only refers to the root hub's downstream ports. So let HCDs see root hub URBs unless the parent device is suspended. - Remove an assertion we no longer need (and now, also don't want). - Generic suspend/resume updates to work better with swsusp. * Ignore the FREEZE vs SUSPEND distinction for hardware; trying to use it breaks the swsusp snapshots it's supposed to help (sigh). * On resume, mark devices as resumed right away, but then do nothing else if the device is marked NOTATTACHED. These changes shouldn't be very noticable by themselves. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/base/power/runtime.c | 1 drivers/usb/core/hcd.c | 64 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/core/hcd.h | 1 drivers/usb/core/hub.c | 45 ++++++++++++++++++++++++------ drivers/usb/core/usb.c | 20 +++++++++---- drivers/usb/core/usb.h | 1 6 files changed, 111 insertions(+), 21 deletions(-) --- drivers/base/power/runtime.c | 1 + drivers/usb/core/hcd.c | 64 ++++++++++++++++++++++++++++++++---- drivers/usb/core/hcd.h | 1 + drivers/usb/core/hub.c | 45 ++++++++++++++++++++----- drivers/usb/core/usb.c | 20 +++++++---- drivers/usb/core/usb.h | 1 + 6 files changed, 111 insertions(+), 21 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index e8f0519f5dfa..adbc3148c039 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -36,6 +36,7 @@ void dpm_runtime_resume(struct device * dev) runtime_resume(dev); up(&dpm_sem); } +EXPORT_SYMBOL(dpm_runtime_resume); /** diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 375382f9d671..de59bb515315 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1143,10 +1143,20 @@ static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags) else switch (hcd->state) { case HC_STATE_RUNNING: case HC_STATE_RESUMING: +doit: usb_get_dev (urb->dev); list_add_tail (&urb->urb_list, &ep->urb_list); status = 0; break; + case HC_STATE_SUSPENDED: + /* HC upstream links (register access, wakeup signaling) can work + * even when the downstream links (and DMA etc) are quiesced; let + * usbcore talk to the root hub. + */ + if (hcd->self.controller->power.power_state.event == PM_EVENT_ON + && urb->dev->parent == NULL) + goto doit; + /* FALL THROUGH */ default: status = -ESHUTDOWN; break; @@ -1294,12 +1304,6 @@ static int hcd_unlink_urb (struct urb *urb, int status) goto done; } - /* running ~= hc unlink handshake works (irq, timer, etc) - * halted ~= no unlink handshake is needed - * suspended, resuming == should never happen - */ - WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT); - /* insist the urb is still queued */ list_for_each(tmp, &ep->urb_list) { if (tmp == &urb->urb_list) @@ -1459,6 +1463,8 @@ static int hcd_hub_resume (struct usb_bus *bus) hcd = container_of (bus, struct usb_hcd, self); if (!hcd->driver->hub_resume) return -ENOENT; + if (hcd->state == HC_STATE_RUNNING) + return 0; hcd->state = HC_STATE_RESUMING; status = hcd->driver->hub_resume (hcd); if (status == 0) @@ -1471,6 +1477,50 @@ static int hcd_hub_resume (struct usb_bus *bus) return status; } +/* + * usb_hcd_suspend_root_hub - HCD autosuspends downstream ports + * @hcd: host controller for this root hub + * + * This call arranges that usb_hcd_resume_root_hub() is safe to call later; + * that the HCD's root hub polling is deactivated; and that the root's hub + * driver is suspended. HCDs may call this to autosuspend when their root + * hub's downstream ports are all inactive: unpowered, disconnected, + * disabled, or suspended. + * + * The HCD will autoresume on device connect change detection (using SRP + * or a D+/D- pullup). The HCD also autoresumes on remote wakeup signaling + * from any ports that are suspended (if that is enabled). In most cases, + * overcurrent signaling (on powered ports) will also start autoresume. + * + * Always called with IRQs blocked. + */ +void usb_hcd_suspend_root_hub (struct usb_hcd *hcd) +{ + struct urb *urb; + + spin_lock (&hcd_root_hub_lock); + usb_suspend_root_hub (hcd->self.root_hub); + + /* force status urb to complete/unlink while suspended */ + if (hcd->status_urb) { + urb = hcd->status_urb; + urb->status = -ECONNRESET; + urb->hcpriv = NULL; + urb->actual_length = 0; + + del_timer (&hcd->rh_timer); + hcd->poll_pending = 0; + hcd->status_urb = NULL; + } else + urb = NULL; + spin_unlock (&hcd_root_hub_lock); + hcd->state = HC_STATE_SUSPENDED; + + if (urb) + usb_hcd_giveback_urb (hcd, urb, NULL); +} +EXPORT_SYMBOL_GPL(usb_hcd_suspend_root_hub); + /** * usb_hcd_resume_root_hub - called by HCD to resume its root hub * @hcd: host controller for this root hub @@ -1478,7 +1528,7 @@ static int hcd_hub_resume (struct usb_bus *bus) * The USB host controller calls this function when its root hub is * suspended (with the remote wakeup feature enabled) and a remote * wakeup request is received. It queues a request for khubd to - * resume the root hub. + * resume the root hub (that is, manage its downstream ports again). */ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) { diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1f1ed6211af8..eb21f13c5c74 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -355,6 +355,7 @@ extern long usb_calc_bus_time (int speed, int is_input, extern struct usb_bus *usb_alloc_bus (struct usb_operations *); +extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); extern void usb_set_device_state(struct usb_device *udev, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 660064466791..3c8d8d1f993c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -449,11 +449,18 @@ static void hub_power_on(struct usb_hub *hub) msleep(max(pgood_delay, (unsigned) 100)); } -static void hub_quiesce(struct usb_hub *hub) +static inline void __hub_quiesce(struct usb_hub *hub) { - /* stop khubd and related activity */ + /* (nonblocking) khubd and related activity won't re-trigger */ hub->quiescing = 1; hub->activating = 0; + hub->resume_root_hub = 0; +} + +static void hub_quiesce(struct usb_hub *hub) +{ + /* (blocking) stop khubd and related activity */ + __hub_quiesce(hub); usb_kill_urb(hub->urb); if (hub->has_indicators) cancel_delayed_work(&hub->leds); @@ -467,6 +474,7 @@ static void hub_activate(struct usb_hub *hub) hub->quiescing = 0; hub->activating = 1; + hub->resume_root_hub = 0; status = usb_submit_urb(hub->urb, GFP_NOIO); if (status < 0) dev_err(hub->intfdev, "activate --> %d\n", status); @@ -1959,6 +1967,18 @@ static int hub_resume(struct usb_interface *intf) return 0; } +void usb_suspend_root_hub(struct usb_device *hdev) +{ + struct usb_hub *hub = hdev_to_hub(hdev); + + /* This also makes any led blinker stop retriggering. We're called + * from irq, so the blinker might still be scheduled. Caller promises + * that the root hub status URB will be canceled. + */ + __hub_quiesce(hub); + mark_quiesced(to_usb_interface(hub->intfdev)); +} + void usb_resume_root_hub(struct usb_device *hdev) { struct usb_hub *hub = hdev_to_hub(hdev); @@ -2616,21 +2636,30 @@ static void hub_events(void) intf = to_usb_interface(hub->intfdev); hub_dev = &intf->dev; - dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", + i = hub->resume_root_hub; + + dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n", hdev->state, hub->descriptor ? hub->descriptor->bNbrPorts : 0, /* NOTE: expects max 15 ports... */ (u16) hub->change_bits[0], - (u16) hub->event_bits[0]); + (u16) hub->event_bits[0], + i ? ", resume root" : ""); usb_get_intf(intf); - i = hub->resume_root_hub; spin_unlock_irq(&hub_event_lock); - /* Is this is a root hub wanting to be resumed? */ - if (i) - usb_resume_device(hdev); + /* Is this is a root hub wanting to reactivate the downstream + * ports? If so, be sure the interface resumes even if its + * stub "device" node was never suspended. + */ + if (i) { + extern void dpm_runtime_resume(struct device *); + + dpm_runtime_resume(&hdev->dev); + dpm_runtime_resume(&intf->dev); + } /* Lock the device, then check to see if we were * disconnected while waiting for the lock to succeed. */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index e89dbd43e952..2493e7d9f5b3 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1427,6 +1427,7 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message) /* USB devices enter SUSPEND state through their hubs, but can be * marked for FREEZE as soon as their children are already idled. + * But those semantics are useless, so we equate the two (sigh). */ if (dev->driver == &usb_generic_driver) { if (dev->power.power_state.event == message.event) @@ -1435,10 +1436,6 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message) status = device_for_each_child(dev, NULL, verify_suspended); if (status) return status; - if (message.event == PM_EVENT_FREEZE) { - dev->power.power_state = message; - return 0; - } return usb_suspend_device (to_usb_device(dev)); } @@ -1471,14 +1468,22 @@ static int usb_generic_resume(struct device *dev) { struct usb_interface *intf; struct usb_driver *driver; + struct usb_device *udev; int status; if (dev->power.power_state.event == PM_EVENT_ON) return 0; + /* mark things as "on" immediately, no matter what errors crop up */ + dev->power.power_state.event = PM_EVENT_ON; + /* devices resume through their hubs */ - if (dev->driver == &usb_generic_driver) + if (dev->driver == &usb_generic_driver) { + udev = to_usb_device(dev); + if (udev->state == USB_STATE_NOTATTACHED) + return 0; return usb_resume_device (to_usb_device(dev)); + } if ((dev->driver == NULL) || (dev->driver_data == &usb_generic_driver_data)) @@ -1487,11 +1492,14 @@ static int usb_generic_resume(struct device *dev) intf = to_usb_interface(dev); driver = to_usb_driver(dev->driver); + udev = interface_to_usbdev(intf); + if (udev->state == USB_STATE_NOTATTACHED) + return 0; + /* if driver was suspended, it has a resume method; * however, sysfs can wrongly mark things as suspended * (on the "no suspend method" FIXME path above) */ - mark_active(intf); if (driver->resume) { status = driver->resume(intf); if (status) { diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3741a990403e..7add46ecc6a2 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -19,6 +19,7 @@ extern void usb_lock_all_devices(void); extern void usb_unlock_all_devices(void); extern void usb_kick_khubd(struct usb_device *dev); +extern void usb_suspend_root_hub(struct usb_device *hdev); extern void usb_resume_root_hub(struct usb_device *dev); extern int usb_hub_init(void); From f3f3253d644d36a2ea5464005a9c2cf28804d200 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:37:29 -0700 Subject: [PATCH 0837/1940] [PATCH] root hub updates (greater half) This patch associates hub suspend and resume logic (including for root hubs) with CONFIG_PM -- instead of CONFIG_USB_SUSPEND as before -- thereby unifying two troublesome versions of suspend logic into just one. It'll be easier to keep things right from now on. - Now usbcore _always_ calls hcd->hub_suspend as needed, instead of only when USB_SUSPEND is enabled: * Those root hub methods are now called from hub suspend/resume; no more skipping between layers during device suspend/resume; * It now handles cases allowed by sysfs or autosuspended root hubs, by forcing the hub interface to resume too. - All devices, including virtual root hubs, now get the same treatment on their resume paths ... including re-activating all their interfaces. Plus it gets rid of those stub copies of usb_{suspend,resume}_device(), and updates the Kconfig to match the new definition of USB_SUSPEND: it provides (a) selective suspend, downstream from hubs; and (b) remote wakeup, upstream from any device configuration which supports it. This calls for minor followup patches for most HCDs (and their PCI glue). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/Kconfig | 11 ++- drivers/usb/core/hub.c | 163 +++++++++++++++++++++++++---------------------- 2 files changed, 97 insertions(+), 77 deletions(-) --- drivers/usb/core/Kconfig | 11 ++- drivers/usb/core/hub.c | 163 +++++++++++++++++++++------------------ 2 files changed, 97 insertions(+), 77 deletions(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 1a9ff6184943..ff03184da403 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -61,14 +61,17 @@ config USB_DYNAMIC_MINORS If you are unsure about this, say N here. config USB_SUSPEND - bool "USB suspend/resume (EXPERIMENTAL)" + bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)" depends on USB && PM && EXPERIMENTAL help If you say Y here, you can use driver calls or the sysfs "power/state" file to suspend or resume individual USB - peripherals. There are many related features, such as - remote wakeup and driver-specific suspend processing, that - may not yet work as expected. + peripherals. + + Also, USB "remote wakeup" signaling is supported, whereby some + USB devices (like keyboards and network adapters) can wake up + their parent hub. That wakeup cascades up the USB tree, and + could wake the system from states like suspend-to-RAM. If you are unsure about this, say N here. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3c8d8d1f993c..6a601a4547e7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1612,7 +1612,7 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, */ static int __usb_suspend_device (struct usb_device *udev, int port1) { - int status; + int status = 0; /* caller owns the udev device lock */ if (port1 < 0) @@ -1638,21 +1638,10 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) } } - /* "global suspend" of the HC-to-USB interface (root hub), or - * "selective suspend" of just one hub-device link. + /* we only change a device's upstream USB link. + * root hubs have no upstream USB link. */ - if (!udev->parent) { - struct usb_bus *bus = udev->bus; - if (bus && bus->op->hub_suspend) { - status = bus->op->hub_suspend (bus); - if (status == 0) { - dev_dbg(&udev->dev, "usb suspend\n"); - usb_set_device_state(udev, - USB_STATE_SUSPENDED); - } - } else - status = -EOPNOTSUPP; - } else + if (udev->parent) status = hub_port_suspend(hdev_to_hub(udev->parent), port1, udev); @@ -1661,6 +1650,8 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) return status; } +#endif + /** * usb_suspend_device - suspend a usb device * @udev: device that's no longer in active use @@ -1683,6 +1674,7 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) */ int usb_suspend_device(struct usb_device *udev) { +#ifdef CONFIG_USB_SUSPEND int port1, status; port1 = locktree(udev); @@ -1692,8 +1684,14 @@ int usb_suspend_device(struct usb_device *udev) status = __usb_suspend_device(udev, port1); usb_unlock_device(udev); return status; +#else + /* NOTE: udev->state unchanged, it's not lying ... */ + udev->dev.power.power_state = PMSG_SUSPEND; + return 0; +#endif } + /* * If the USB "suspend" state is in use (rather than "global suspend"), * many devices will be individually taken out of suspend state using @@ -1702,13 +1700,13 @@ int usb_suspend_device(struct usb_device *udev) * resume (by host) or remote wakeup (by device) ... now see what changed * in the tree that's rooted at this device. */ -static int finish_port_resume(struct usb_device *udev) +static int finish_device_resume(struct usb_device *udev) { int status; u16 devstatus; /* caller owns the udev device lock */ - dev_dbg(&udev->dev, "usb resume\n"); + dev_dbg(&udev->dev, "finish resume\n"); /* usb ch9 identifies four variants of SUSPENDED, based on what * state the device resumes to. Linux currently won't see the @@ -1718,7 +1716,6 @@ static int finish_port_resume(struct usb_device *udev) usb_set_device_state(udev, udev->actconfig ? USB_STATE_CONFIGURED : USB_STATE_ADDRESS); - udev->dev.power.power_state = PMSG_ON; /* 10.5.4.5 says be sure devices in the tree are still there. * For now let's assume the device didn't go crazy on resume, @@ -1734,7 +1731,8 @@ static int finish_port_resume(struct usb_device *udev) int (*resume)(struct device *); le16_to_cpus(&devstatus); - if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { + if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) + && udev->parent) { status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_CLEAR_FEATURE, @@ -1764,6 +1762,8 @@ static int finish_port_resume(struct usb_device *udev) return status; } +#ifdef CONFIG_USB_SUSPEND + static int hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) { @@ -1809,7 +1809,7 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) /* TRSMRCY = 10 msec */ msleep(10); if (udev) - status = finish_port_resume(udev); + status = finish_device_resume(udev); } } if (status < 0) @@ -1818,7 +1818,7 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) return status; } -static int hub_resume (struct usb_interface *intf); +#endif /** * usb_resume_device - re-activate a suspended usb device @@ -1841,35 +1841,22 @@ int usb_resume_device(struct usb_device *udev) if (port1 < 0) return port1; - /* "global resume" of the HC-to-USB interface (root hub), or - * selective resume of one hub-to-device port - */ - if (!udev->parent) { - struct usb_bus *bus = udev->bus; - if (bus && bus->op->hub_resume) { - status = bus->op->hub_resume (bus); +#ifdef CONFIG_USB_SUSPEND + /* selective resume of one downstream hub-to-device port */ + if (udev->parent) { + if (udev->state == USB_STATE_SUSPENDED) { + // NOTE swsusp may bork us, device state being wrong... + // NOTE this fails if parent is also suspended... + status = hub_port_resume(hdev_to_hub(udev->parent), + port1, udev); } else - status = -EOPNOTSUPP; - if (status == 0) { - dev_dbg(&udev->dev, "usb resume\n"); - /* TRSMRCY = 10 msec */ - msleep(10); - usb_set_device_state (udev, USB_STATE_CONFIGURED); - udev->dev.power.power_state = PMSG_ON; - status = hub_resume (udev - ->actconfig->interface[0]); - } - } else if (udev->state == USB_STATE_SUSPENDED) { - // NOTE this fails if parent is also suspended... - status = hub_port_resume(hdev_to_hub(udev->parent), - port1, udev); - } else { - status = 0; - } - if (status < 0) { + status = 0; + } else +#endif + status = finish_device_resume(udev); + if (status < 0) dev_dbg(&udev->dev, "can't resume, status %d\n", status); - } usb_unlock_device(udev); @@ -1886,6 +1873,8 @@ static int remote_wakeup(struct usb_device *udev) { int status = 0; +#ifdef CONFIG_USB_SUSPEND + /* don't repeat RESUME sequence if this device * was already woken up by some other task */ @@ -1894,9 +1883,10 @@ static int remote_wakeup(struct usb_device *udev) dev_dbg(&udev->dev, "RESUME (wakeup)\n"); /* TRSMRCY = 10 msec */ msleep(10); - status = finish_port_resume(udev); + status = finish_device_resume(udev); } up(&udev->serialize); +#endif return status; } @@ -1911,12 +1901,32 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) struct usb_device *udev; udev = hdev->children [port1-1]; - if (udev && udev->state != USB_STATE_SUSPENDED) { + if (udev && (udev->dev.power.power_state.event + == PM_EVENT_ON +#ifdef CONFIG_USB_SUSPEND + || udev->state != USB_STATE_SUSPENDED +#endif + )) { dev_dbg(&intf->dev, "port %d nyet suspended\n", port1); return -EBUSY; } } + /* "global suspend" of the downstream HC-to-USB interface */ + if (!hdev->parent) { + struct usb_bus *bus = hdev->bus; + if (bus && bus->op->hub_suspend) { + int status = bus->op->hub_suspend (bus); + + if (status != 0) { + dev_dbg(&hdev->dev, "'global' suspend %d\n", + status); + return status; + } + } else + return -EOPNOTSUPP; + } + /* stop khubd and related activity */ hub_quiesce(hub); return 0; @@ -1926,9 +1936,36 @@ static int hub_resume(struct usb_interface *intf) { struct usb_device *hdev = interface_to_usbdev(intf); struct usb_hub *hub = usb_get_intfdata (intf); - unsigned port1; int status; + /* "global resume" of the downstream HC-to-USB interface */ + if (!hdev->parent) { + struct usb_bus *bus = hdev->bus; + if (bus && bus->op->hub_resume) { + status = bus->op->hub_resume (bus); + if (status) { + dev_dbg(&intf->dev, "'global' resume %d\n", + status); + return status; + } + } else + return -EOPNOTSUPP; + if (status == 0) { + /* TRSMRCY = 10 msec */ + msleep(10); + } + } + + hub_activate(hub); + + /* REVISIT: this recursion probably shouldn't exist. Remove + * this code sometime, after retesting with different root and + * external hubs. + */ +#ifdef CONFIG_USB_SUSPEND + { + unsigned port1; + for (port1 = 1; port1 <= hdev->maxchild; port1++) { struct usb_device *udev; u16 portstat, portchange; @@ -1953,7 +1990,7 @@ static int hub_resume(struct usb_interface *intf) if (portstat & USB_PORT_STAT_SUSPEND) status = hub_port_resume(hub, port1, udev); else { - status = finish_port_resume(udev); + status = finish_device_resume(udev); if (status < 0) { dev_dbg(&intf->dev, "resume port %d --> %d\n", port1, status); @@ -1962,8 +1999,8 @@ static int hub_resume(struct usb_interface *intf) } up(&udev->serialize); } - hub->resume_root_hub = 0; - hub_activate(hub); + } +#endif return 0; } @@ -1987,26 +2024,6 @@ void usb_resume_root_hub(struct usb_device *hdev) kick_khubd(hub); } -#else /* !CONFIG_USB_SUSPEND */ - -int usb_suspend_device(struct usb_device *udev) -{ - /* state does NOT lie by saying it's USB_STATE_SUSPENDED! */ - return 0; -} - -int usb_resume_device(struct usb_device *udev) -{ - udev->dev.power.power_state.event = PM_EVENT_ON; - return 0; -} - -#define hub_suspend NULL -#define hub_resume NULL -#define remote_wakeup(x) 0 - -#endif /* CONFIG_USB_SUSPEND */ - EXPORT_SYMBOL(usb_suspend_device); EXPORT_SYMBOL(usb_resume_device); From 5f827ea3c3820cd8e0a1a35e4d275c8b78ee94e1 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:38:16 -0700 Subject: [PATCH 0838/1940] [PATCH] usbcore PCI glue updates for PM This updates the PCI glue to address the new and simplified usbcore suspend semantics, where CONFIG_USB_SUSPEND becomes irrelevant to HCDs because hcd->hub_suspend() will always be called. - Removes now-unneeded recursion support - Go back to ignoring faults reported by the wakeup calls; we expect them to fail sometimes, and that's just fine. The PCI HCDs will need simple changes to catch up to this, like being able to ignore the setting of CONFIG_USB_SUSPEND. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hcd-pci.c | 106 +++++++++++++++++++++------------------------ drivers/usb/core/hcd.h | 6 +- 2 files changed, 53 insertions(+), 59 deletions(-) --- drivers/usb/core/hcd-pci.c | 106 +++++++++++++++++-------------------- drivers/usb/core/hcd.h | 6 +-- 2 files changed, 53 insertions(+), 59 deletions(-) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 6385d1a99b60..84d9e69329bb 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -30,6 +30,8 @@ #include #include #include + +#include "usb.h" #include "hcd.h" @@ -197,6 +199,26 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) hcd = pci_get_drvdata(dev); + /* Root hub suspend should have stopped all downstream traffic, + * and all bus master traffic. And done so for both the interface + * and the stub usb_device (which we check here). But maybe it + * didn't; writing sysfs power/state files ignores such rules... + * + * We must ignore the FREEZE vs SUSPEND distinction here, because + * otherwise the swsusp will save (and restore) garbage state. + */ + if (hcd->self.root_hub->dev.power.power_state.event == PM_EVENT_ON) + return -EBUSY; + + if (hcd->driver->suspend) { + retval = hcd->driver->suspend(hcd, message); + if (retval) { + dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", + retval); + goto done; + } + } + /* FIXME until the generic PM interfaces change a lot more, this * can't use PCI D1 and D2 states. For example, the confusion * between messages and states will need to vanish, and messages @@ -215,31 +237,13 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) */ has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); - switch (hcd->state) { - - /* entry if root hub wasn't yet suspended ... from sysfs, - * without autosuspend, or if USB_SUSPEND isn't configured. + /* Downstream ports from this root hub should already be quiesced, so + * there will be no DMA activity. Now we can shut down the upstream + * link (except maybe for PME# resume signaling) and enter some PCI + * low power state, if the hardware allows. */ - case HC_STATE_RUNNING: - hcd->state = HC_STATE_QUIESCING; - retval = hcd->driver->suspend (hcd, message); - if (retval) { - dev_dbg (hcd->self.controller, - "suspend fail, retval %d\n", - retval); - break; - } - hcd->state = HC_STATE_SUSPENDED; - /* FALLTHROUGH */ + if (hcd->state == HC_STATE_SUSPENDED) { - /* entry with CONFIG_USB_SUSPEND, or hcds that autosuspend: the - * controller and/or root hub will already have been suspended, - * but it won't be ready for a PCI resume call. - * - * FIXME only CONFIG_USB_SUSPEND guarantees hub_suspend() will - * have been called, otherwise root hub timers still run ... - */ - case HC_STATE_SUSPENDED: /* no DMA or IRQs except when HC is active */ if (dev->current_state == PCI_D0) { pci_save_state (dev); @@ -248,7 +252,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) if (!has_pci_pm) { dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n"); - break; + goto done; } /* NOTE: dev->current_state becomes nonzero only here, and @@ -259,28 +263,29 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) retval = pci_set_power_state (dev, PCI_D3hot); if (retval == 0) { dev_dbg (hcd->self.controller, "--> PCI D3\n"); - retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); - if (retval) - break; - retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); - } else if (retval < 0) { + + /* Ignore these return values. We rely on pci code to + * reject requests the hardware can't implement, rather + * than coding the same thing. + */ + (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); + (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); + } else { dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", retval); (void) usb_hcd_pci_resume (dev); - break; } - break; - default: + + } else { dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", hcd->state); WARN_ON(1); retval = -EINVAL; - break; } - /* update power_state **ONLY** to make sysfs happier */ +done: if (retval == 0) - dev->dev.power.power_state = message; + dev->dev.power.power_state = PMSG_SUSPEND; return retval; } EXPORT_SYMBOL (usb_hcd_pci_suspend); @@ -336,20 +341,9 @@ int usb_hcd_pci_resume (struct pci_dev *dev) dev->current_state); } #endif - retval = pci_enable_wake (dev, dev->current_state, 0); - if (retval) { - dev_err(hcd->self.controller, - "can't enable_wake to %d, %d!\n", - dev->current_state, retval); - return retval; - } - retval = pci_enable_wake (dev, PCI_D3cold, 0); - if (retval) { - dev_err(hcd->self.controller, - "can't enable_wake to %d, %d!\n", - PCI_D3cold, retval); - return retval; - } + /* yes, ignore these results too... */ + (void) pci_enable_wake (dev, dev->current_state, 0); + (void) pci_enable_wake (dev, PCI_D3cold, 0); } else { /* Same basic cases: clean (powered/not), dirty */ dev_dbg(hcd->self.controller, "PCI legacy resume\n"); @@ -371,17 +365,17 @@ int usb_hcd_pci_resume (struct pci_dev *dev) dev->dev.power.power_state = PMSG_ON; - hcd->state = HC_STATE_RESUMING; hcd->saw_irq = 0; - retval = hcd->driver->resume (hcd); - if (!HC_IS_RUNNING (hcd->state)) { - dev_dbg (hcd->self.controller, - "resume fail, retval %d\n", retval); - usb_hc_died (hcd); + if (hcd->driver->resume) { + retval = hcd->driver->resume(hcd); + if (retval) { + dev_err (hcd->self.controller, + "PCI post-resume error %d!\n", retval); + usb_hc_died (hcd); + } } - retval = pci_enable_device(dev); return retval; } EXPORT_SYMBOL (usb_hcd_pci_resume); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index eb21f13c5c74..74757fc1a99f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -182,12 +182,12 @@ struct hc_driver { int (*start) (struct usb_hcd *hcd); /* NOTE: these suspend/resume calls relate to the HC as - * a whole, not just the root hub; they're for bus glue. + * a whole, not just the root hub; they're for PCI bus glue. */ - /* called after all devices were suspended */ + /* called after suspending the hub, before entering D3 etc */ int (*suspend) (struct usb_hcd *hcd, pm_message_t message); - /* called before any devices get resumed */ + /* called after entering D0 (etc), before resuming the hub */ int (*resume) (struct usb_hcd *hcd); /* cleanly make HCD stop writing memory and doing I/O */ From f197b2c54b9d9a133a9a8ff92f35cadf8945ea14 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:42:53 -0700 Subject: [PATCH 0839/1940] [PATCH] OHCI PM updates This simplifies the OHCI root hub suspend logic: - Uses new usbcore root hub calls to make autosuspend work again: * Uses a newish usbcore root hub wakeup mechanism, making requests to khubd not keventd. * Uses an even newer sibling suspend hook. - Expect someone always made usbcore call ohci_hub_suspend() before bus glue fires; and that ohci_hub_resume() is only called after that bus glue ran. Previously, only CONFIG_USB_SUSPEND promised those things. (Includes updates to PCI and OMAP bus glue.) - Handle a not-noticed-before special case during resume from one of the swsusp snapshots when using "usb-handoff": the controller isn't left in RESET state. (A bug to fix in the usb-handoff code...) Also cleans up a minor debug printk glitch, and switches an mdelay over to an msleep (how did that stick around for so long?). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/host/ohci-dbg.c | 4 ---- drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 42 ++++++++++++------------------------------ drivers/usb/host/ohci-mem.c | 1 - drivers/usb/host/ohci-omap.c | 36 ++++++++++++------------------------ drivers/usb/host/ohci-pci.c | 40 ++++++++-------------------------------- drivers/usb/host/ohci.h | 1 - 7 files changed, 33 insertions(+), 93 deletions(-) --- drivers/usb/host/ohci-dbg.c | 4 ---- drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 42 +++++++++++------------------------- drivers/usb/host/ohci-mem.c | 1 - drivers/usb/host/ohci-omap.c | 36 +++++++++++-------------------- drivers/usb/host/ohci-pci.c | 40 +++++++--------------------------- drivers/usb/host/ohci.h | 1 - 7 files changed, 33 insertions(+), 93 deletions(-) diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 7924c74f958e..7bfffcbbd226 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) maybe_print_eds (controller, "donehead", ohci_readl (controller, ®s->donehead), next, size); - - /* broken fminterval means traffic won't flow! */ - ohci_dbg (controller, "fminterval %08x\n", - ohci_readl (controller, ®s->fminterval)); } #define dbg_port_sw(hc,num,value,next,size) \ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index c26ab5f2a403..5c0c6c8a7a82 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -723,7 +723,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ohci_vdbg (ohci, "resume detect\n"); ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); if (hcd->state != HC_STATE_QUIESCING) - schedule_work(&ohci->rh_resume); + usb_hcd_resume_root_hub(hcd); } if (ints & OHCI_INTR_WDH) { diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index b96948ea3005..39a60e731ec2 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -73,7 +73,6 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) ohci_dbg (ohci, "suspend root hub\n"); /* First stop any processing */ - hcd->state = HC_STATE_QUIESCING; if (ohci->hc_control & OHCI_SCHED_ENABLES) { int limit; @@ -108,7 +107,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) else ohci->hc_control &= ~OHCI_CTRL_RWE; - /* Suspend hub */ + /* Suspend hub ... this is the "global (to this bus) suspend" mode, + * which doesn't imply ports will first be individually suspended. + */ ohci->hc_control &= ~OHCI_CTRL_HCFS; ohci->hc_control |= OHCI_USB_SUSPEND; ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); @@ -118,8 +119,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) ohci->next_statechange = jiffies + msecs_to_jiffies (5); done: + /* external suspend vs self autosuspend ... same effect */ if (status == 0) - hcd->state = HC_STATE_SUSPENDED; + usb_hcd_suspend_root_hub(hcd); spin_unlock_irqrestore (&ohci->lock, flags); return status; } @@ -146,7 +148,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { - /* this can happen after suspend-to-disk */ + /* this can happen after resuming a swsusp snapshot */ if (hcd->state == HC_STATE_RESUMING) { ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", ohci->hc_control); @@ -169,11 +171,12 @@ static int ohci_hub_resume (struct usb_hcd *hcd) ohci_info (ohci, "wakeup\n"); break; case OHCI_USB_OPER: - ohci_dbg (ohci, "already resumed\n"); - status = 0; + /* this can happen after resuming a swsusp snapshot */ + ohci_dbg (ohci, "snapshot resume? reinit\n"); + status = -EBUSY; break; default: /* RESET, we lost power */ - ohci_dbg (ohci, "root hub hardware reset\n"); + ohci_dbg (ohci, "lost power\n"); status = -EBUSY; } spin_unlock_irq (&ohci->lock); @@ -198,8 +201,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) } /* Some controllers (lucent erratum) need extra-long delays */ - hcd->state = HC_STATE_RESUMING; - mdelay (20 /* usb 11.5.1.10 */ + 15); + msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); temp = ohci_readl (ohci, &ohci->regs->control); temp &= OHCI_CTRL_HCFS; @@ -273,27 +275,9 @@ static int ohci_hub_resume (struct usb_hcd *hcd) (void) ohci_readl (ohci, &ohci->regs->control); } - hcd->state = HC_STATE_RUNNING; return 0; } -static void ohci_rh_resume (void *_hcd) -{ - struct usb_hcd *hcd = _hcd; - - usb_lock_device (hcd->self.root_hub); - (void) ohci_hub_resume (hcd); - usb_unlock_device (hcd->self.root_hub); -} - -#else - -static void ohci_rh_resume (void *_hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (_hcd); - ohci_dbg(ohci, "rh_resume ??\n"); -} - #endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -367,7 +351,6 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) #ifdef CONFIG_PM /* save power by suspending idle root hubs; * INTR_RD wakes us when there's work - * NOTE: if we can do this, we don't need a root hub timer! */ if (can_suspend && !changed @@ -380,7 +363,6 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ) { ohci_vdbg (ohci, "autosuspend\n"); (void) ohci_hub_suspend (hcd); - hcd->state = HC_STATE_RUNNING; usb_unlock_device (hcd->self.root_hub); } #endif @@ -554,7 +536,7 @@ static int ohci_hub_control ( temp = RH_PS_POCI; if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) - schedule_work (&ohci->rh_resume); + usb_hcd_resume_root_hub(hcd); break; case USB_PORT_FEAT_C_SUSPEND: temp = RH_PS_PSSC; diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 9fb83dfb1eb4..bfbe328a4788 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) ohci->next_statechange = jiffies; spin_lock_init (&ohci->lock); INIT_LIST_HEAD (&ohci->pending); - INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); ohci->reboot_notifier.notifier_call = ohci_reboot; } diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index e67c07dc426d..b3498b9b965f 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -458,41 +458,29 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) static int ohci_omap_suspend(struct device *dev, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); - int status = -EINVAL; - down(&ohci_to_hcd(ohci)->self.root_hub->serialize); - status = ohci_hub_suspend(ohci_to_hcd(ohci)); - if (status == 0) { - omap_ohci_clock_power(0); - ohci_to_hcd(ohci)->self.root_hub->state = - USB_STATE_SUSPENDED; - ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; - dev->power.power_state = PMSG_SUSPEND; - } - up(&ohci_to_hcd(ohci)->self.root_hub->serialize); - return status; + if (time_before(jiffies, ohci->next_statechange)) + msleep(5); + ohci->next_statechange = jiffies; + + omap_ohci_clock_power(0); + ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; + dev->power.power_state = PMSG_SUSPEND; + return 0; } static int ohci_omap_resume(struct device *dev) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); - int status = 0; if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; + omap_ohci_clock_power(1); -#ifdef CONFIG_USB_SUSPEND - /* get extra cleanup even if remote wakeup isn't in use */ - status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); -#else - down(&ohci_to_hcd(ohci)->self.root_hub->serialize); - status = ohci_hub_resume(ohci_to_hcd(ohci)); - up(&ohci_to_hcd(ohci)->self.root_hub->serialize); -#endif - if (status == 0) - dev->power.power_state = PMSG_ON; - return status; + dev->power.power_state = PMSG_ON; + usb_hcd_resume_root_hub(dev_get_drvdata(dev)); + return 0; } #endif diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 0afa237b02ad..99a0ad41aec5 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -112,23 +112,13 @@ ohci_pci_start (struct usb_hcd *hcd) static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); + /* root hub was already suspended */ - /* suspend root hub, hoping it keeps power during suspend */ - if (time_before (jiffies, ohci->next_statechange)) - msleep (100); - -#ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub); -#else - usb_lock_device (hcd->self.root_hub); - (void) ohci_hub_suspend (hcd); - usb_unlock_device (hcd->self.root_hub); -#endif - - /* let things settle down a bit */ - msleep (100); - + /* FIXME these PMAC things get called in the wrong places. ASIC + * clocks should be turned off AFTER entering D3, and on BEFORE + * trying to enter D0. Evidently the PCI layer doesn't currently + * provide the right sort of platform hooks for this ... + */ #ifdef CONFIG_PPC_PMAC if (_machine == _MACH_Pmac) { struct device_node *of_node; @@ -145,9 +135,6 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) static int ohci_pci_resume (struct usb_hcd *hcd) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int retval = 0; - #ifdef CONFIG_PPC_PMAC if (_machine == _MACH_Pmac) { struct device_node *of_node; @@ -159,19 +146,8 @@ static int ohci_pci_resume (struct usb_hcd *hcd) } #endif /* CONFIG_PPC_PMAC */ - /* resume root hub */ - if (time_before (jiffies, ohci->next_statechange)) - msleep (100); -#ifdef CONFIG_USB_SUSPEND - /* get extra cleanup even if remote wakeup isn't in use */ - retval = usb_resume_device (hcd->self.root_hub); -#else - usb_lock_device (hcd->self.root_hub); - retval = ohci_hub_resume (hcd); - usb_unlock_device (hcd->self.root_hub); -#endif - - return retval; + usb_hcd_resume_root_hub(hcd); + return 0; } #endif /* CONFIG_PM */ diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 8a9b9d9209e9..caacf14371f5 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -389,7 +389,6 @@ struct ohci_hcd { unsigned long next_statechange; /* suspend/resume */ u32 fminterval; /* saved register */ - struct work_struct rh_resume; struct notifier_block reboot_notifier; unsigned long flags; /* for HC bugs */ From f2cb36c1df427431a8c6096b4ad113df767c1bd9 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:43:30 -0700 Subject: [PATCH 0840/1940] [PATCH] update PCI early-handoff handling for OHCI The PCI "early usb handoff" quirk logic didn't work like "ohci-hcd" ... This patch makes it do so by: - Resetting the controller after kicking BIOS off, matching the normal "chip in hardware reset" startup mode; - Reporting any BIOS that borks this simple handoff; it's likely got a few other surprises for us too. - Ignoring that handoff on HPPA; The diagnostic string is mostly shared with EHCI, saving a few bytes. Signed-off-by: Greg Kroah-Hartman drivers/usb/host/pci-quirks.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) --- drivers/usb/host/pci-quirks.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 8ee5c3ed4cd6..49f7381a6fd3 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -60,6 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, qui #define OHCI_INTRENABLE 0x10 #define OHCI_INTRDISABLE 0x14 #define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ #define OHCI_INTR_OC (1 << 30) /* ownership change */ @@ -140,13 +141,17 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; int wait_time; + u32 control; base = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (base == NULL) return; - if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { - wait_time = 500; /* 0.5 seconds */ +/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ +#ifndef __hppa__ + control = readl(base + OHCI_CONTROL); + if (control & OHCI_CTRL_IR) { + wait_time = 500; /* arbitrary; 5 seconds */ writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); writel(OHCI_OCR, base + OHCI_CMDSTATUS); while (wait_time > 0 && @@ -154,7 +159,15 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) wait_time -= 10; msleep(10); } + if (wait_time <= 0) + printk(KERN_WARNING "%s %s: early BIOS handoff " + "failed (BIOS bug ?)\n", + pdev->dev.bus_id, "OHCI"); + + /* reset controller, preserving RWC */ + writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); } +#endif /* * disable interrupts @@ -211,8 +224,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) /* * well, possibly buggy BIOS... */ - printk(KERN_WARNING "EHCI early BIOS handoff " - "failed (BIOS bug ?)\n"); + printk(KERN_WARNING "%s %s: early BIOS handoff " + "failed (BIOS bug ?)\n", + pdev->dev.bus_id, "EHCI"); pci_write_config_dword(pdev, hcc_params + EHCI_USBLEGSUP, EHCI_USBLEGSUP_OS); From a7f72abe8fac9b919135005e06216be8eef945a2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:44:56 -0700 Subject: [PATCH 0841/1940] [PATCH] UHCI PM updates This removes suspend and resume path recursion in UHCI. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/host/uhci-hcd.c | 9 --------- 1 file changed, 9 deletions(-) --- drivers/usb/host/uhci-hcd.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index b44094fcd779..34c9dbc6a156 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -762,11 +762,6 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) if (uhci->hc_inaccessible) /* Dead or already suspended */ goto done; -#ifndef CONFIG_USB_SUSPEND - /* Otherwise this would never happen */ - suspend_rh(uhci, UHCI_RH_SUSPENDED); -#endif - if (uhci->rh_state > UHCI_RH_SUSPENDED) { dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); hcd->state = HC_STATE_RUNNING; @@ -808,10 +803,6 @@ static int uhci_resume(struct usb_hcd *hcd) check_and_reset_hc(uhci); configure_hc(uhci); -#ifndef CONFIG_USB_SUSPEND - /* Otherwise this would never happen */ - wakeup_rh(uhci); -#endif if (uhci->rh_state == UHCI_RH_RESET) suspend_rh(uhci, UHCI_RH_SUSPENDED); From ccdcf77ae32e3d3347fdf3810b27f899e98c34fb Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:45:13 -0700 Subject: [PATCH 0842/1940] [PATCH] ISP116x PM updates This makes the isp116x driver stop using usb_suspend_device() and usb_resume_device() ... usbcore now calls to the root hub methods, removing the need for this. It also switches from keventd to khubd for remote wakeup. (Compile tested.) Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/host/isp116x-hcd.c | 29 ++++------------------------- drivers/usb/host/isp116x.h | 1 - 2 files changed, 4 insertions(+), 26 deletions(-) --- drivers/usb/host/isp116x-hcd.c | 29 ++++------------------------- drivers/usb/host/isp116x.h | 1 - 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 554d60282a9d..f68220fc53fd 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -638,7 +638,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) + msecs_to_jiffies(20) + 1); if (intstat & HCINT_RD) { DBG("---- remote wakeup\n"); - schedule_work(&isp116x->rh_resume); + usb_hcd_resume_root_hub(hcd); ret = IRQ_HANDLED; } irqstat &= ~HCuPINT_OPR; @@ -1263,22 +1263,12 @@ static int isp116x_hub_resume(struct usb_hcd *hcd) return 0; } -static void isp116x_rh_resume(void *_hcd) -{ - struct usb_hcd *hcd = _hcd; - - usb_resume_device(hcd->self.root_hub); -} #else #define isp116x_hub_suspend NULL #define isp116x_hub_resume NULL -static void isp116x_rh_resume(void *_hcd) -{ -} - #endif /*-----------------------------------------------------------------*/ @@ -1732,7 +1722,6 @@ static int __init isp116x_probe(struct device *dev) isp116x->addr_reg = addr_reg; spin_lock_init(&isp116x->lock); INIT_LIST_HEAD(&isp116x->async); - INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd); isp116x->board = dev->platform_data; if (!isp116x->board) { @@ -1777,16 +1766,10 @@ static int __init isp116x_probe(struct device *dev) static int isp116x_suspend(struct device *dev, pm_message_t state) { int ret = 0; - struct usb_hcd *hcd = dev_get_drvdata(dev); VDBG("%s: state %x\n", __func__, state); - ret = usb_suspend_device(hcd->self.root_hub); - if (!ret) { - dev->power.power_state = state; - INFO("%s suspended\n", hcd_name); - } else - ERR("%s suspend failed\n", hcd_name); + dev->power.power_state = state; return ret; } @@ -1797,15 +1780,11 @@ static int isp116x_suspend(struct device *dev, pm_message_t state) static int isp116x_resume(struct device *dev) { int ret = 0; - struct usb_hcd *hcd = dev_get_drvdata(dev); VDBG("%s: state %x\n", __func__, dev->power.power_state); - ret = usb_resume_device(hcd->self.root_hub); - if (!ret) { - dev->power.power_state = PMSG_ON; - VDBG("%s resumed\n", (char *)hcd_name); - } + dev->power.power_state = PMSG_ON; + return ret; } diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index 58873470dcf5..c6fec96785fe 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -253,7 +253,6 @@ static const int cc_to_error[16] = { struct isp116x { spinlock_t lock; - struct work_struct rh_resume; void __iomem *addr_reg; void __iomem *data_reg; From 5edbfb7c8af0577097dae87cdd4dfdba82bb9579 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:45:26 -0700 Subject: [PATCH 0843/1940] [PATCH] stop exporting two functions The way we're looking at USB suspend lately doesn't expect drivers to call usb_suspend_device() or usb_resume_device() directly; that'll be implicit when no interfaces are in use. This patch removes those APIs from visibility outside usbcore. Signed-off-by: David Brownell drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/usb.h | 4 ++++ include/linux/usb.h | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) --- drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/usb.h | 4 ++++ include/linux/usb.h | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6a601a4547e7..15db5e490aa2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1652,10 +1652,10 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) #endif -/** +/* * usb_suspend_device - suspend a usb device * @udev: device that's no longer in active use - * Context: must be able to sleep; device not locked + * Context: must be able to sleep; device not locked; pm locks held * * Suspends a USB device that isn't in active use, conserving power. * Devices may wake out of a suspend, if anything important happens, @@ -1820,10 +1820,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) #endif -/** +/* * usb_resume_device - re-activate a suspended usb device * @udev: device to re-activate - * Context: must be able to sleep; device not locked + * Context: must be able to sleep; device not locked; pm locks held * * This will re-activate the suspended device, increasing power usage * while letting drivers communicate again with its endpoints. @@ -2024,10 +2024,6 @@ void usb_resume_root_hub(struct usb_device *hdev) kick_khubd(hub); } -EXPORT_SYMBOL(usb_suspend_device); -EXPORT_SYMBOL(usb_resume_device); - - /* USB 2.0 spec, 7.1.7.3 / fig 7-29: * diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 7add46ecc6a2..4d59f6e07999 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -29,6 +29,10 @@ extern void usb_major_cleanup(void); extern int usb_host_init(void); extern void usb_host_cleanup(void); +extern int usb_suspend_device(struct usb_device *dev); +extern int usb_resume_device(struct usb_device *dev); + + /* Interfaces and their "power state" are owned by usbcore */ static inline void mark_active(struct usb_interface *f) diff --git a/include/linux/usb.h b/include/linux/usb.h index 25ec91ddcd04..207b1ad9d990 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -975,11 +975,6 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); -/* selective suspend/resume */ -extern int usb_suspend_device(struct usb_device *dev); -extern int usb_resume_device(struct usb_device *dev); - - /* wrappers around usb_control_msg() for the most common standard requests */ extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, unsigned char descindex, void *buf, int size); From b13296c6617f22e8c0174a7af32780617db0e680 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 27 Sep 2005 10:38:54 -0700 Subject: [PATCH 0844/1940] [PATCH] updates for "controller suspended" handling Reject URBs to _all_ devices when their host controllers are suspended; even root hub registers will be unavailable. Also, don't reject urbs to root hubs in other cases; the only upstream link is through that controller (on PCI or whatever SOC bus is in use). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hcd.c | 28 ++++++++++++---------------- drivers/usb/core/urb.c | 3 ++- 2 files changed, 14 insertions(+), 17 deletions(-) --- drivers/usb/core/hcd.c | 28 ++++++++++++---------------- drivers/usb/core/urb.c | 3 ++- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index de59bb515315..b7bb8dd1894a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -458,22 +458,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) default: /* non-generic request */ - if (HC_IS_SUSPENDED (hcd->state)) - status = -EAGAIN; - else { - switch (typeReq) { - case GetHubStatus: - case GetPortStatus: - len = 4; - break; - case GetHubDescriptor: - len = sizeof (struct usb_hub_descriptor); - break; - } - status = hcd->driver->hub_control (hcd, - typeReq, wValue, wIndex, - tbuf, wLength); + switch (typeReq) { + case GetHubStatus: + case GetPortStatus: + len = 4; + break; + case GetHubDescriptor: + len = sizeof (struct usb_hub_descriptor); + break; } + status = hcd->driver->hub_control (hcd, + typeReq, wValue, wIndex, + tbuf, wLength); break; error: /* "protocol stall" on error */ @@ -487,7 +483,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) "CTRL: TypeReq=0x%x val=0x%x " "idx=0x%x len=%d ==> %d\n", typeReq, wValue, wIndex, - wLength, urb->status); + wLength, status); } } if (len) { diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index b32898e0a27d..f2a1fed2a802 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -237,7 +237,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) (dev->state < USB_STATE_DEFAULT) || (!dev->bus) || (dev->devnum <= 0)) return -ENODEV; - if (dev->state == USB_STATE_SUSPENDED) + if (dev->bus->controller->power.power_state.event != PM_EVENT_ON + || dev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH; if (!(op = dev->bus->op) || !op->submit_urb) return -ENODEV; From d09d36a91c70cb3cc609d693bf6a7e7a266ff9e6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 26 Sep 2005 16:22:45 -0400 Subject: [PATCH 0845/1940] [PATCH] USB: usb_bulk_message() handles interrupts endpoints Because there is no bulk_interrupt_message() routine and no USBDEVFS_INTERRUPT ioctl, people have been forced to abuse the usb_bulk_message() routine and USBDEVFS_BULK by using them for interrupt transfers as well as bulk transfers. This patch (as567) formalizes this practice and adds code to usb_bulk_message() for detecting when the target is really an interrupt endpoint. If it is, the routine submits an interrupt URB (using the default interval) instead of a bulk URB. In theory this should help HCDs that don't like it when people try to mix transfer types, queuing both periodic and non-periodic types for the same endpoint. Not fully tested -- I don't have any programs that use USBDEVFS_BULK for interrupt transfers -- but it compiles okay and normal bulk messages work as well as before. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman drivers/usb/core/message.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) --- drivers/usb/core/message.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index ebf59ea99263..574d0d4b3401 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -187,21 +187,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u * If a thread in your driver uses this call, make sure your disconnect() * method can wait for it to complete. Since you don't have a handle on * the URB used, you can't cancel the request. + * + * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT + * ioctl, users are forced to abuse this routine by using it to submit + * URBs for interrupt endpoints. We will take the liberty of creating + * an interrupt URB (with the default interval) if the target is an + * interrupt endpoint. */ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout) { struct urb *urb; + struct usb_host_endpoint *ep; - if (len < 0) + ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out) + [usb_pipeendpoint(pipe)]; + if (!ep || len < 0) return -EINVAL; - urb=usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; - usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, - usb_api_blocking_completion, NULL); + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, usb_dev, pipe, data, len, + usb_api_blocking_completion, NULL, + ep->desc.bInterval); + } else + usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, + usb_api_blocking_completion, NULL); return usb_start_wait_urb(urb, timeout, actual_length); } From 8b262bd25580e165710e8a27df19cd60c2ef58a3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 26 Sep 2005 16:31:15 -0400 Subject: [PATCH 0846/1940] [PATCH] USB: UHCI: Spruce up some comments This patch (as570) changes some comments in the uhci-hcd header file and removes an unused declaration (something I forgot to erase in an earlier patch). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman drivers/usb/host/uhci-hcd.h | 91 +++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 42 deletions(-) --- drivers/usb/host/uhci-hcd.h | 91 ++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index b04d99df0a0e..e576db57a926 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -7,6 +7,7 @@ #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) #define PIPE_DEVEP_MASK 0x0007ff00 + /* * Universal Host Controller Interface data structures and defines */ @@ -82,15 +83,10 @@ #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ -struct uhci_frame_list { - __le32 frame[UHCI_NUMFRAMES]; - void *frame_cpu[UHCI_NUMFRAMES]; - - dma_addr_t dma_handle; -}; - -struct urb_priv; +/* + * Queue Headers + */ /* * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is @@ -116,13 +112,13 @@ struct uhci_qh { struct urb_priv *urbp; - struct list_head list; /* P: uhci->frame_list_lock */ - struct list_head remove_list; /* P: uhci->remove_list_lock */ + struct list_head list; + struct list_head remove_list; } __attribute__((aligned(16))); /* * We need a special accessor for the element pointer because it is - * subject to asynchronous updates by the controller + * subject to asynchronous updates by the controller. */ static __le32 inline qh_element(struct uhci_qh *qh) { __le32 element = qh->element; @@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { return element; } + +/* + * Transfer Descriptors + */ + /* * for TD : */ @@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) { * * That's silly, the hardware doesn't care. The hardware only cares that * the hardware words are 16-byte aligned, and we can have any amount of - * sw space after the TD entry as far as I can tell. - * - * But let's just go with the documentation, at least for 32-bit machines. - * On 64-bit machines we probably want to take advantage of the fact that - * hw doesn't really care about the size of the sw-only area. - * - * Alas, not anymore, we have more than 4 words for software, woops. - * Everything still works tho, surprise! -jerdfelt + * sw space after the TD entry. * * td->link points to either another TD (not necessarily for the same urb or - * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs) + * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). */ struct uhci_td { /* Hardware fields */ @@ -205,16 +199,16 @@ struct uhci_td { /* Software fields */ dma_addr_t dma_handle; - struct list_head list; /* P: urb->lock */ - struct list_head remove_list; /* P: uhci->td_remove_list_lock */ + struct list_head list; + struct list_head remove_list; int frame; /* for iso: what frame? */ - struct list_head fl_list; /* P: uhci->frame_list_lock */ + struct list_head fl_list; } __attribute__((aligned(16))); /* * We need a special accessor for the control/status word because it is - * subject to asynchronous updates by the controller + * subject to asynchronous updates by the controller. */ static u32 inline td_status(struct uhci_td *td) { __le32 status = td->status; @@ -224,6 +218,10 @@ static u32 inline td_status(struct uhci_td *td) { } +/* + * Skeleton Queue Headers + */ + /* * The UHCI driver places Interrupt, Control and Bulk into QH's both * to group together TD's for one transfer, and also to faciliate queuing @@ -254,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) { * * The terminating QH is used for 2 reasons: * - To place a terminating TD which is used to workaround a PIIX bug - * (see Intel errata for explanation) + * (see Intel errata for explanation), and * - To loop back to the full-speed control queue for full-speed bandwidth - * reclamation + * reclamation. * * Isochronous transfers are stored before the start of the skeleton * schedule and don't use QH's. While the UHCI spec doesn't forbid the - * use of QH's for Isochronous, it doesn't use them either. Since we don't - * need to use them either, we follow the spec diagrams in hope that it'll - * be more compatible with future UHCI implementations. + * use of QH's for Isochronous, it doesn't use them either. And the spec + * says that queues never advance on an error completion status, which + * makes them totally unsuitable for Isochronous transfers. */ #define UHCI_NUM_SKELQH 12 @@ -312,8 +310,13 @@ static inline int __interval_to_skel(int interval) return 0; /* int128 for 128-255 ms (Max.) */ } + /* - * States for the root hub. + * The UHCI controller and root hub + */ + +/* + * States for the root hub: * * To prevent "bouncing" in the presence of electrical noise, * when there are no devices attached we delay for 1 second in the @@ -324,7 +327,7 @@ static inline int __interval_to_skel(int interval) */ enum uhci_rh_state { /* In the following states the HC must be halted. - * These two must come first */ + * These two must come first. */ UHCI_RH_RESET, UHCI_RH_SUSPENDED, @@ -336,13 +339,13 @@ enum uhci_rh_state { UHCI_RH_SUSPENDING, /* In the following states it's an error if the HC is halted. - * These two must come last */ + * These two must come last. */ UHCI_RH_RUNNING, /* The normal state */ UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ }; /* - * This describes the full uhci information. + * The full UHCI controller information: */ struct uhci_hcd { @@ -361,7 +364,7 @@ struct uhci_hcd { spinlock_t lock; dma_addr_t frame_dma_handle; /* Hardware frame list */ - __le32 *frame; /* P: uhci->lock */ + __le32 *frame; void **frame_cpu; /* CPU's frame list */ int fsbr; /* Full-speed bandwidth reclamation */ @@ -387,22 +390,22 @@ struct uhci_hcd { unsigned long ports_timeout; /* Time to stop signalling */ /* Main list of URB's currently controlled by this HC */ - struct list_head urb_list; /* P: uhci->lock */ + struct list_head urb_list; /* List of QH's that are done, but waiting to be unlinked (race) */ - struct list_head qh_remove_list; /* P: uhci->lock */ + struct list_head qh_remove_list; unsigned int qh_remove_age; /* Age in frames */ /* List of TD's that are done, but waiting to be freed (race) */ - struct list_head td_remove_list; /* P: uhci->lock */ + struct list_head td_remove_list; unsigned int td_remove_age; /* Age in frames */ /* List of asynchronously unlinked URB's */ - struct list_head urb_remove_list; /* P: uhci->lock */ + struct list_head urb_remove_list; unsigned int urb_remove_age; /* Age in frames */ /* List of URB's awaiting completion callback */ - struct list_head complete_list; /* P: uhci->lock */ + struct list_head complete_list; int rh_numports; /* Number of root-hub ports */ @@ -421,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) + +/* + * Private per-URB data + */ struct urb_priv { struct list_head urb_list; struct urb *urb; struct uhci_qh *qh; /* QH for this URB */ - struct list_head td_list; /* P: urb->lock */ + struct list_head td_list; unsigned fsbr : 1; /* URB turned on FSBR */ unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ @@ -438,9 +445,10 @@ struct urb_priv { unsigned long fsbrtime; /* In jiffies */ - struct list_head queue_list; /* P: uhci->frame_list_lock */ + struct list_head queue_list; }; + /* * Locking in uhci.c * @@ -460,6 +468,5 @@ struct urb_priv { #define PCI_VENDOR_ID_GENESYS 0x17a0 #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 -#define PCI_DEVICE_ID_GL880S_EHCI 0x8084 #endif From dabb592816444fcba1a771e27d4f72a2b8218374 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 22 Sep 2005 23:55:22 -0700 Subject: [PATCH 0847/1940] [PATCH] USB: sisusb warning fix drivers/usb/misc/sisusbvga/sisusb.c: In function `sisusb_reset_text_mode': drivers/usb/misc/sisusbvga/sisusb.c:2461: warning: assignment discards qualifiers from pointer target type Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman drivers/usb/misc/sisusbvga/sisusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- drivers/usb/misc/sisusbvga/sisusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 222ae9cd4c7c..c946c9a538a0 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -2440,7 +2440,7 @@ int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) { int ret = 0, slot = sisusb->font_slot, i; - struct font_desc *myfont; + const struct font_desc *myfont; u8 *tempbuf; u16 *tempbufb; size_t written; From 22efcf4adec4262e0f49e6225f6cd070e4a85d20 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 26 Sep 2005 16:12:02 -0400 Subject: [PATCH 0848/1940] [PATCH] USB: File-Storage gadget: use the kthread API This patch (as566) converts the File-Storage gadget over to the kthread API. The new code doesn't use kthread_stop because the control thread needs to terminate asynchronously when it receives a signal. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman drivers/usb/gadget/file_storage.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) --- drivers/usb/gadget/file_storage.c | 32 +++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a41d9d4baee3..241c570e541c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -224,6 +224,7 @@ #include #include #include +#include #include #include #include @@ -669,7 +670,6 @@ struct fsg_dev { wait_queue_head_t thread_wqh; int thread_wakeup_needed; struct completion thread_notifier; - int thread_pid; struct task_struct *thread_task; sigset_t thread_signal_mask; @@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev *fsg) static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) { unsigned long flags; - struct task_struct *thread_task; /* Do nothing if a higher-priority exception is already in progress. * If a lower-or-equal priority exception is in progress, preempt it @@ -1093,9 +1092,9 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) if (fsg->state <= new_state) { fsg->exception_req_tag = fsg->ep0_req_tag; fsg->state = new_state; - thread_task = fsg->thread_task; - if (thread_task) - send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task); + if (fsg->thread_task) + send_sig_info(SIGUSR1, SEND_SIG_FORCED, + fsg->thread_task); } spin_unlock_irqrestore(&fsg->lock, flags); } @@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_) { struct fsg_dev *fsg = (struct fsg_dev *) fsg_; - fsg->thread_task = current; - - /* Release all our userspace resources */ - daemonize("file-storage-gadget"); - /* Allow the thread to be killed by a signal, but set the signal mask * to block everything but INT, TERM, KILL, and USR1. */ siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | @@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_) * that expects a __user pointer and it will work okay. */ set_fs(get_ds()); - /* Wait for the gadget registration to finish up */ - wait_for_completion(&fsg->thread_notifier); - /* The main loop */ while (fsg->state != FSG_STATE_TERMINATED) { if (exception_in_progress(fsg) || signal_pending(current)) { @@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_) spin_unlock_irq(&fsg->lock); } + spin_lock_irq(&fsg->lock); fsg->thread_task = NULL; - flush_signals(current); + spin_unlock_irq(&fsg->lock); /* In case we are exiting because of a signal, unregister the * gadget driver and close the backing file. */ @@ -3959,10 +3951,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) sprintf(&serial[i], "%02X", c); } - if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS | - CLONE_FILES))) < 0) + fsg->thread_task = kthread_create(fsg_main_thread, fsg, + "file-storage-gadget"); + if (IS_ERR(fsg->thread_task)) { + rc = PTR_ERR(fsg->thread_task); goto out; - fsg->thread_pid = rc; + } INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); @@ -3994,7 +3988,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", mod_data.removable, mod_data.can_stall, mod_data.buflen); - DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid); + DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); return 0; autoconf_fail: @@ -4093,7 +4087,7 @@ static int __init fsg_init(void) set_bit(REGISTERED, &fsg->atomic_bitflags); /* Tell the thread to start working */ - complete(&fsg->thread_notifier); + wake_up_process(fsg->thread_task); return 0; } module_init(fsg_init); From 74ad9bd2fcf0fa203655e0d904809b06c4202bf8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0849/1940] [PATCH] USB: make wHubCharacteristics __le16 to match other usb descriptor fields Also has the nice benefit of making sparc alignment issues go away. Thanks to David Miller for pointing out the problems here. Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hub.c | 22 ++++++++++++---------- drivers/usb/core/hub.h | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) --- drivers/usb/core/hub.c | 22 ++++++++++++---------- drivers/usb/core/hub.h | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 15db5e490aa2..e2802bf18095 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -436,9 +436,10 @@ static void hub_power_on(struct usb_hub *hub) { int port1; unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; + u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); /* if hub supports power switching, enable power on each port */ - if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) { + if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { dev_dbg(hub->intfdev, "enabling power on all ports\n"); for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) set_port_feature(hub->hdev, port1, @@ -525,6 +526,7 @@ static int hub_configure(struct usb_hub *hub, struct usb_device *hdev = hub->hdev; struct device *hub_dev = hub->intfdev; u16 hubstatus, hubchange; + u16 wHubCharacteristics; unsigned int pipe; int maxp, ret; char *message; @@ -570,9 +572,9 @@ static int hub_configure(struct usb_hub *hub, dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, (hdev->maxchild == 1) ? "" : "s"); - le16_to_cpus(&hub->descriptor->wHubCharacteristics); + wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); - if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) { + if (wHubCharacteristics & HUB_CHAR_COMPOUND) { int i; char portstr [USB_MAXCHILDREN + 1]; @@ -585,7 +587,7 @@ static int hub_configure(struct usb_hub *hub, } else dev_dbg(hub_dev, "standalone hub\n"); - switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) { + switch (wHubCharacteristics & HUB_CHAR_LPSM) { case 0x00: dev_dbg(hub_dev, "ganged power switching\n"); break; @@ -598,7 +600,7 @@ static int hub_configure(struct usb_hub *hub, break; } - switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { + switch (wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: dev_dbg(hub_dev, "global over-current protection\n"); break; @@ -638,7 +640,7 @@ static int hub_configure(struct usb_hub *hub, } /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ - switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { + switch (wHubCharacteristics & HUB_CHAR_TTTT) { case HUB_TTTT_8_BITS: if (hdev->descriptor.bDeviceProtocol != 0) { hub->tt.think_time = 666; @@ -668,7 +670,7 @@ static int hub_configure(struct usb_hub *hub, } /* probe() zeroes hub->indicator[] */ - if (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) { + if (wHubCharacteristics & HUB_CHAR_PORTIND) { hub->has_indicators = 1; dev_dbg(hub_dev, "Port indicators are supported\n"); } @@ -713,7 +715,7 @@ static int hub_configure(struct usb_hub *hub, (hubstatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good"); - if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) == 0) + if ((wHubCharacteristics & HUB_CHAR_OCPM) == 0) dev_dbg(hub_dev, "%sover-current condition exists\n", (hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); @@ -2432,6 +2434,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, { struct usb_device *hdev = hub->hdev; struct device *hub_dev = hub->intfdev; + u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); int status, i; dev_dbg (hub_dev, @@ -2469,8 +2472,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (!(portstatus & USB_PORT_STAT_CONNECTION)) { /* maybe switch power back on (e.g. root hub was reset) */ - if ((hub->descriptor->wHubCharacteristics - & HUB_CHAR_LPSM) < 2 + if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 && !(portstatus & (1 << USB_PORT_FEAT_POWER))) set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index e7fa9b5a521e..bf23f8978024 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -131,7 +131,7 @@ struct usb_hub_descriptor { __u8 bDescLength; __u8 bDescriptorType; __u8 bNbrPorts; - __u16 wHubCharacteristics; + __le16 wHubCharacteristics; __u8 bPwrOn2PwrGood; __u8 bHubContrCurrent; /* add 1 bit for hub status change; round to bytes */ From 207c47e1fbc8d51500997bfa67c26c00114fab04 Mon Sep 17 00:00:00 2001 From: Thomas Riewe Date: Thu, 29 Sep 2005 14:57:29 +0200 Subject: [PATCH 0850/1940] [PATCH] drivers/usb/serial/ftdi_sio: add PID/VID We would like to add a PID for the Pyramid Appliance Display, which works on USB via FTDI_SIO. Signed-off-by: Thomas Riewe Signed-off-by: Greg Kroah-Hartman drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 4 insertions(+) --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8c12a0acf10d..b713113c1650 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -411,6 +411,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, /* * These will probably use user-space drivers. Uncomment them if * you need them or use the user-specified vendor/product module diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 7c65d46c7598..ddb63df31ce6 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -342,6 +342,9 @@ #define EVOLUTION_VID 0xDEEE /* Vendor ID */ #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +/* Pyramid Computer GmbH */ +#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ From ddcad752f206be7a0091a041403c3188f2febd16 Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Mon, 3 Oct 2005 17:24:11 +0300 Subject: [PATCH 0851/1940] [PATCH] pegasus.h This one is a tiny patch adding one more device to the list. Please apply. :) Signed-off-by: Greg Kroah-Hartman drivers/usb/net/pegasus.h | 2 ++ 1 file changed, 2 insertions(+) --- drivers/usb/net/pegasus.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index b98f2a833442..9fbd59b55cb6 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h @@ -181,6 +181,8 @@ PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) From 521daed8db4443a1574a98fc3abae8e230f09eaa Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 2 Oct 2005 17:15:33 -0700 Subject: [PATCH 0852/1940] [PATCH] safe_serial: use preprocessor directive for error Use valid #preprocessor instruction to generate an error. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman drivers/usb/serial/safe_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- drivers/usb/serial/safe_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 96a17568cbf1..88bf14abfa7a 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -92,7 +92,7 @@ MODULE_DESCRIPTION (DRIVER_DESC); MODULE_LICENSE("GPL"); #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) -#abort "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" +#error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" #endif #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) From d40ece1dc8dcc89ab921755cbc93a5cfb46d0766 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 28 Sep 2005 18:06:04 +0200 Subject: [PATCH 0853/1940] [PATCH] USB: make usb storage note visible in Kconfig the following patch splits the NOTE: in the Device Drivers->USB submenu of Kconfig thus making the whole of it readable on 600x800 terminals. (Otherwise, the line was too big and disappeared into nowhere.) Signed-off-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- drivers/usb/storage/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index bb9819cc8826..1a9679f76f5a 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -2,7 +2,8 @@ # USB Storage driver configuration # -comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information" +comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'" +comment "may also be needed; see USB_STORAGE Help for more information" depends on USB config USB_STORAGE From a8798533c1f876b97566588cf2bf52458cb4a35d Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 29 Sep 2005 00:14:21 +0100 Subject: [PATCH 0854/1940] [PATCH] USB Storage: HP8200: Another device type detection fix There appears to be one more case where the HP8200 CD writer devices are detected as flash readers - when the USB cable is replugged after use, with the power cable still connected. Oddly enough, the identify device command appears to 'fall through' when the devices are in this state, the status register reading exactly the same opcode as the command (0xA1) that was just executed. I think it's safe to label this behaviour as specific to HP8200 devices, I can't get the flash devices to respond like this. This patch should solve the last of the HP8200 issues which have cropped up recently. Signed-off-by: Daniel Drake Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/shuttle_usbat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) --- drivers/usb/storage/shuttle_usbat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 356342c6e7a2..bd448d6c3185 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -855,15 +855,15 @@ static int usbat_identify_device(struct us_data *us, if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Check for error bit - if (status & 0x01) { - // Device is a CompactFlash reader/writer - US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); - info->devicetype = USBAT_DEV_FLASH; - } else { + // Check for error bit, or if the command 'fell through' + if (status == 0xA1 || !(status & 0x01)) { // Device is HP 8200 US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); info->devicetype = USBAT_DEV_HP8200; + } else { + // Device is a CompactFlash reader/writer + US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); + info->devicetype = USBAT_DEV_FLASH; } return USB_STOR_TRANSPORT_GOOD; From b7b1e65588b8576c66a429a2623c91504efcf751 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Fri, 30 Sep 2005 12:49:36 +0100 Subject: [PATCH 0855/1940] [PATCH] usb-storage: Some minor shuttle_usbat cleanups A while ago, Matthew Dharm wrote: > Looks good. Tho, I would like to see a future patch to do two things: > 1) Change comments from C++ style to C-style > 2) Make sure we're naming consistently everywhere SCM, USBAT, > USBAT-02 (most noticably needing fixing is the string used at > transport-selection time, but a sweep of all uses to be consistent > would be in order). Sorry for the long delay, here is a patch to address this. I also clarified some ATA/ATAPI wording + function names. Signed-off-by: Daniel Drake Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/shuttle_usbat.c | 306 ++++++++++++++++++++---------------- drivers/usb/storage/shuttle_usbat.h | 66 +++---- drivers/usb/storage/transport.h | 2 drivers/usb/storage/unusual_devs.h | 10 - drivers/usb/storage/usb.c | 4 5 files changed, 213 insertions(+), 175 deletions(-) --- drivers/usb/storage/shuttle_usbat.c | 306 ++++++++++++++++------------ drivers/usb/storage/shuttle_usbat.h | 66 +++--- drivers/usb/storage/transport.h | 2 +- drivers/usb/storage/unusual_devs.h | 10 +- drivers/usb/storage/usb.c | 4 +- 5 files changed, 213 insertions(+), 175 deletions(-) diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index bd448d6c3185..33c55a6261bb 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1,4 +1,4 @@ -/* Driver for SCM Microsystems USB-ATAPI cable +/* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable * * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ * @@ -67,10 +67,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); /* - * Convenience function to produce an ATAPI read/write sectors command + * Convenience function to produce an ATA read/write sectors command * Use cmd=0x20 for read, cmd=0x30 for write */ -static void usbat_pack_atapi_sector_cmd(unsigned char *buf, +static void usbat_pack_ata_sector_cmd(unsigned char *buf, unsigned char thistime, u32 sector, unsigned char cmd) { @@ -196,10 +196,12 @@ static int usbat_check_status(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; - if (*reply & 0x01 && *reply != 0x51) // error/check condition (0x51 is ok) + /* error/check condition (0x51 is ok) */ + if (*reply & 0x01 && *reply != 0x51) return USB_STOR_TRANSPORT_FAILED; - if (*reply & 0x20) // device fault + /* device fault */ + if (*reply & 0x20) return USB_STOR_TRANSPORT_FAILED; return USB_STOR_TRANSPORT_GOOD; @@ -222,29 +224,39 @@ static int usbat_set_shuttle_features(struct us_data *us, command[0] = 0x40; command[1] = USBAT_CMD_SET_FEAT; - // The only bit relevant to ATA access is bit 6 - // which defines 8 bit data access (set) or 16 bit (unset) + /* + * The only bit relevant to ATA access is bit 6 + * which defines 8 bit data access (set) or 16 bit (unset) + */ command[2] = epp_control; - // If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, - // ET1 and ET2 define an external event to be checked for on event of a - // _read_blocks or _write_blocks operation. The read/write will not take - // place unless the defined trigger signal is active. + /* + * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, + * ET1 and ET2 define an external event to be checked for on event of a + * _read_blocks or _write_blocks operation. The read/write will not take + * place unless the defined trigger signal is active. + */ command[3] = external_trigger; - // The resultant byte of the mask operation (see mask_byte) is compared for - // equivalence with this test pattern. If equal, the read/write will take - // place. + /* + * The resultant byte of the mask operation (see mask_byte) is compared for + * equivalence with this test pattern. If equal, the read/write will take + * place. + */ command[4] = test_pattern; - // This value is logically ANDed with the status register field specified - // in the read/write command. + /* + * This value is logically ANDed with the status register field specified + * in the read/write command. + */ command[5] = mask_byte; - // If ALQ is set in the qualifier, this field contains the address of the - // registers where the byte count should be read for transferring the data. - // If ALQ is not set, then this field contains the number of bytes to be - // transferred. + /* + * If ALQ is set in the qualifier, this field contains the address of the + * registers where the byte count should be read for transferring the data. + * If ALQ is not set, then this field contains the number of bytes to be + * transferred. + */ command[6] = subcountL; command[7] = subcountH; @@ -273,26 +285,26 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) if (result!=USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - if (*status & 0x01) { // check condition + if (*status & 0x01) { /* check condition */ result = usbat_read(us, USBAT_ATA, 0x10, status); return USB_STOR_TRANSPORT_FAILED; } - if (*status & 0x20) // device fault + if (*status & 0x20) /* device fault */ return USB_STOR_TRANSPORT_FAILED; - if ((*status & 0x80)==0x00) { // not busy + if ((*status & 0x80)==0x00) { /* not busy */ US_DEBUGP("Waited not busy for %d steps\n", i); return USB_STOR_TRANSPORT_GOOD; } if (i<500) - msleep(10); // 5 seconds + msleep(10); /* 5 seconds */ else if (i<700) - msleep(50); // 10 seconds + msleep(50); /* 10 seconds */ else if (i<1200) - msleep(100); // 50 seconds + msleep(100); /* 50 seconds */ else - msleep(1000); // X minutes + msleep(1000); /* X minutes */ } US_DEBUGP("Waited not busy for %d minutes, timing out.\n", @@ -412,9 +424,12 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, if (i==0) { cmdlen = 16; - // Write to multiple registers - // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here, - // but that's what came out of the trace every single time. + /* + * Write to multiple registers + * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is + * necessary here, but that's what came out of the + * trace every single time. + */ command[0] = 0x40; command[1] = access | USBAT_CMD_WRITE_REGS; command[2] = 0x07; @@ -426,7 +441,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, } else cmdlen = 8; - // Conditionally read or write blocks + /* Conditionally read or write blocks */ command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); command[cmdlen-7] = access | (direction==DMA_TO_DEVICE ? @@ -456,11 +471,6 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, } - - //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n", - // direction == DMA_TO_DEVICE ? "out" : "in", - // len, use_sg); - result = usb_stor_bulk_transfer_sg(us, pipe, content, len, use_sg, NULL); @@ -508,9 +518,9 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, if (result!=USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - if (*status & 0x01) // check condition + if (*status & 0x01) /* check condition */ return USB_STOR_TRANSPORT_FAILED; - if (*status & 0x20) // device fault + if (*status & 0x20) /* device fault */ return USB_STOR_TRANSPORT_FAILED; US_DEBUGP("Redoing %s\n", @@ -547,32 +557,32 @@ static int usbat_multiple_write(struct us_data *us, BUG_ON(num_registers > US_IOBUF_SIZE/2); - // Write to multiple registers, ATA access + /* Write to multiple registers, ATA access */ command[0] = 0x40; command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS; - // No relevance + /* No relevance */ command[2] = 0; command[3] = 0; command[4] = 0; command[5] = 0; - // Number of bytes to be transferred (incl. addresses and data) + /* Number of bytes to be transferred (incl. addresses and data) */ command[6] = LSB_of(num_registers*2); command[7] = MSB_of(num_registers*2); - // The setup command + /* The setup command */ result = usbat_execute_command(us, command, 8); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Create the reg/data, reg/data sequence + /* Create the reg/data, reg/data sequence */ for (i=0; isense_key = 0x02; @@ -795,11 +809,11 @@ static int usbat_flash_check_media(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; } - // Check for media change + /* Check for media change */ rc = usbat_flash_check_media_changed(uio); if (rc == USBAT_FLASH_MEDIA_CHANGED) { - // Reset and re-enable card detect + /* Reset and re-enable card detect */ rc = usbat_device_reset(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; @@ -855,13 +869,13 @@ static int usbat_identify_device(struct us_data *us, if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Check for error bit, or if the command 'fell through' + /* Check for error bit, or if the command 'fell through' */ if (status == 0xA1 || !(status & 0x01)) { - // Device is HP 8200 + /* Device is HP 8200 */ US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); info->devicetype = USBAT_DEV_HP8200; } else { - // Device is a CompactFlash reader/writer + /* Device is a CompactFlash reader/writer */ US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); info->devicetype = USBAT_DEV_FLASH; } @@ -916,7 +930,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, if (!reply) return USB_STOR_TRANSPORT_ERROR; - // ATAPI command : IDENTIFY DEVICE + /* ATA command : IDENTIFY DEVICE */ rc = usbat_multiple_write(us, registers, command, 3); if (rc != USB_STOR_XFER_GOOD) { US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n"); @@ -924,7 +938,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, goto leave; } - // Read device status + /* Read device status */ if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) { rc = USB_STOR_TRANSPORT_ERROR; goto leave; @@ -932,7 +946,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, msleep(100); - // Read the device identification data + /* Read the device identification data */ rc = usbat_read_block(us, reply, 512); if (rc != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -977,19 +991,23 @@ static int usbat_flash_read_data(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) return result; - // we're working in LBA mode. according to the ATA spec, - // we can support up to 28-bit addressing. I don't know if Jumpshot - // supports beyond 24-bit addressing. It's kind of hard to test - // since it requires > 8GB CF card. + /* + * we're working in LBA mode. according to the ATA spec, + * we can support up to 28-bit addressing. I don't know if Jumpshot + * supports beyond 24-bit addressing. It's kind of hard to test + * since it requires > 8GB CF card. + */ if (sector > 0x0FFFFFFF) return USB_STOR_TRANSPORT_ERROR; totallen = sectors * info->ssize; - // Since we don't read more than 64 KB at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we don't read more than 64 KB at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ alloclen = min(totallen, 65536u); buffer = kmalloc(alloclen, GFP_NOIO); @@ -997,27 +1015,29 @@ static int usbat_flash_read_data(struct us_data *us, return USB_STOR_TRANSPORT_ERROR; do { - // loop, never allocate or transfer more than 64k at once - // (min(128k, 255*info->ssize) is the real limit) + /* + * loop, never allocate or transfer more than 64k at once + * (min(128k, 255*info->ssize) is the real limit) + */ len = min(totallen, alloclen); thistime = (len / info->ssize) & 0xff; - // ATAPI command 0x20 (READ SECTORS) - usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x20); + /* ATA command 0x20 (READ SECTORS) */ + usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20); - // Write/execute ATAPI read command + /* Write/execute ATA read command */ result = usbat_multiple_write(us, registers, command, 7); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; - // Read the data we just requested + /* Read the data we just requested */ result = usbat_read_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; US_DEBUGP("usbat_flash_read_data: %d bytes\n", len); - // Store the data in the transfer buffer + /* Store the data in the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, us->srb, &sg_idx, &sg_offset, TO_XFER_BUF); @@ -1061,19 +1081,23 @@ static int usbat_flash_write_data(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) return result; - // we're working in LBA mode. according to the ATA spec, - // we can support up to 28-bit addressing. I don't know if Jumpshot - // supports beyond 24-bit addressing. It's kind of hard to test - // since it requires > 8GB CF card. + /* + * we're working in LBA mode. according to the ATA spec, + * we can support up to 28-bit addressing. I don't know if the device + * supports beyond 24-bit addressing. It's kind of hard to test + * since it requires > 8GB media. + */ if (sector > 0x0FFFFFFF) return USB_STOR_TRANSPORT_ERROR; totallen = sectors * info->ssize; - // Since we don't write more than 64 KB at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we don't write more than 64 KB at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ alloclen = min(totallen, 65536u); buffer = kmalloc(alloclen, GFP_NOIO); @@ -1081,24 +1105,26 @@ static int usbat_flash_write_data(struct us_data *us, return USB_STOR_TRANSPORT_ERROR; do { - // loop, never allocate or transfer more than 64k at once - // (min(128k, 255*info->ssize) is the real limit) + /* + * loop, never allocate or transfer more than 64k at once + * (min(128k, 255*info->ssize) is the real limit) + */ len = min(totallen, alloclen); thistime = (len / info->ssize) & 0xff; - // Get the data from the transfer buffer + /* Get the data from the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, us->srb, &sg_idx, &sg_offset, FROM_XFER_BUF); - // ATAPI command 0x30 (WRITE SECTORS) - usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x30); + /* ATA command 0x30 (WRITE SECTORS) */ + usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); - // Write/execute ATAPI write command + /* Write/execute ATA write command */ result = usbat_multiple_write(us, registers, command, 7); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; - // Write the data + /* Write the data */ result = usbat_write_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1169,42 +1195,44 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, srb->transfersize); } - // Since we only read in one block at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we only read in one block at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ len = (65535/srb->transfersize) * srb->transfersize; US_DEBUGP("Max read is %d bytes\n", len); len = min(len, srb->request_bufflen); buffer = kmalloc(len, GFP_NOIO); - if (buffer == NULL) // bloody hell! + if (buffer == NULL) /* bloody hell! */ return USB_STOR_TRANSPORT_FAILED; sector = short_pack(data[7+3], data[7+2]); sector <<= 16; sector |= short_pack(data[7+5], data[7+4]); transferred = 0; - sg_segment = 0; // for keeping track of where we are in - sg_offset = 0; // the scatter/gather list + sg_segment = 0; /* for keeping track of where we are in */ + sg_offset = 0; /* the scatter/gather list */ while (transferred != srb->request_bufflen) { if (len > srb->request_bufflen - transferred) len = srb->request_bufflen - transferred; - data[3] = len&0xFF; // (cylL) = expected length (L) - data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) + data[3] = len&0xFF; /* (cylL) = expected length (L) */ + data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ - // Fix up the SCSI command sector and num sectors + /* Fix up the SCSI command sector and num sectors */ - data[7+2] = MSB_of(sector>>16); // SCSI command sector + data[7+2] = MSB_of(sector>>16); /* SCSI command sector */ data[7+3] = LSB_of(sector>>16); data[7+4] = MSB_of(sector&0xFFFF); data[7+5] = LSB_of(sector&0xFFFF); if (data[7+0] == GPCMD_READ_CD) data[7+6] = 0; - data[7+7] = MSB_of(len / srb->transfersize); // SCSI command - data[7+8] = LSB_of(len / srb->transfersize); // num sectors + data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */ + data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */ result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, registers, data, 19, @@ -1217,16 +1245,16 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) break; - // Store the data in the transfer buffer + /* Store the data in the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, srb, &sg_segment, &sg_offset, TO_XFER_BUF); - // Update the amount transferred and the sector number + /* Update the amount transferred and the sector number */ transferred += len; sector += len / srb->transfersize; - } // while transferred != srb->request_bufflen + } /* while transferred != srb->request_bufflen */ kfree(buffer); return result; @@ -1237,7 +1265,7 @@ static int usbat_select_and_test_registers(struct us_data *us) int selector; unsigned char *status = us->iobuf; - // try device = master, then device = slave. + /* try device = master, then device = slave. */ for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != USB_STOR_XFER_GOOD) @@ -1298,7 +1326,7 @@ int init_usbat(struct us_data *us) memset(us->extra, 0, sizeof(struct usbat_info)); info = (struct usbat_info *) (us->extra); - // Enable peripheral control signals + /* Enable peripheral control signals */ rc = usbat_write_user_io(us, USBAT_UIO_OE1 | USBAT_UIO_OE0, USBAT_UIO_EPAD | USBAT_UIO_1); @@ -1337,7 +1365,7 @@ int init_usbat(struct us_data *us) US_DEBUGP("INIT 5\n"); - // Enable peripheral control signals and card detect + /* Enable peripheral control signals and card detect */ rc = usbat_device_enable_cdt(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; @@ -1364,7 +1392,7 @@ int init_usbat(struct us_data *us) US_DEBUGP("INIT 9\n"); - // At this point, we need to detect which device we are using + /* At this point, we need to detect which device we are using */ if (usbat_set_transport(us, info)) return USB_STOR_TRANSPORT_ERROR; @@ -1414,10 +1442,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; - data[3] = len&0xFF; // (cylL) = expected length (L) - data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) - data[5] = 0xB0; // (device sel) = slave - data[6] = 0xA0; // (command) = ATA PACKET COMMAND + data[3] = len&0xFF; /* (cylL) = expected length (L) */ + data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ + data[5] = 0xB0; /* (device sel) = slave */ + data[6] = 0xA0; /* (command) = ATA PACKET COMMAND */ for (i=7; i<19; i++) { registers[i] = 0x10; @@ -1466,13 +1494,15 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) return result; } - // Write the 12-byte command header. - - // If the command is BLANK then set the timer for 75 minutes. - // Otherwise set it for 10 minutes. - - // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW - // AT SPEED 4 IS UNRELIABLE!!! + /* + * Write the 12-byte command header. + * + * If the command is BLANK then set the timer for 75 minutes. + * Otherwise set it for 10 minutes. + * + * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW + * AT SPEED 4 IS UNRELIABLE!!! + */ if ( (result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12, @@ -1481,19 +1511,18 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) return result; } - // If there is response data to be read in - // then do it here. + /* If there is response data to be read in then do it here. */ if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { - // How many bytes to read in? Check cylL register + /* How many bytes to read in? Check cylL register */ if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != USB_STOR_XFER_GOOD) { return USB_STOR_TRANSPORT_ERROR; } - if (len > 0xFF) { // need to read cylH also + if (len > 0xFF) { /* need to read cylH also */ len = *status; if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != USB_STOR_XFER_GOOD) { @@ -1556,13 +1585,16 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec + /* hard coded 512 byte sectors as per ATA spec */ + info->ssize = 0x200; US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", info->sectors, info->ssize); - // build the reply - // note: must return the sector number of the last sector, - // *not* the total number of sectors + /* + * build the reply + * note: must return the sector number of the last sector, + * *not* the total number of sectors + */ ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); usb_stor_set_xfer_buf(ptr, 8, srb); @@ -1586,7 +1618,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == READ_12) { - // I don't think we'll ever see a READ_12 but support it anyway... + /* + * I don't think we'll ever see a READ_12 but support it anyway + */ block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); @@ -1608,7 +1642,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == WRITE_12) { - // I don't think we'll ever see a WRITE_12 but support it anyway... + /* + * I don't think we'll ever see a WRITE_12 but support it anyway + */ block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); @@ -1645,8 +1681,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { - // sure. whatever. not like we can stop the user from popping - // the media out of the device (no locking doors, etc) + /* + * sure. whatever. not like we can stop the user from popping + * the media out of the device (no locking doors, etc) + */ return USB_STOR_TRANSPORT_GOOD; } diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h index 5b8e867e2ae5..25e7d8b340b8 100644 --- a/drivers/usb/storage/shuttle_usbat.h +++ b/drivers/usb/storage/shuttle_usbat.h @@ -55,8 +55,8 @@ #define USBAT_UIO_WRITE 0 /* Qualifier bits */ -#define USBAT_QUAL_FCQ 0x20 // full compare -#define USBAT_QUAL_ALQ 0x10 // auto load subcount +#define USBAT_QUAL_FCQ 0x20 /* full compare */ +#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ /* USBAT Flash Media status types */ #define USBAT_FLASH_MEDIA_NONE 0 @@ -67,39 +67,39 @@ #define USBAT_FLASH_MEDIA_CHANGED 1 /* USBAT ATA registers */ -#define USBAT_ATA_DATA 0x10 // read/write data (R/W) -#define USBAT_ATA_FEATURES 0x11 // set features (W) -#define USBAT_ATA_ERROR 0x11 // error (R) -#define USBAT_ATA_SECCNT 0x12 // sector count (R/W) -#define USBAT_ATA_SECNUM 0x13 // sector number (R/W) -#define USBAT_ATA_LBA_ME 0x14 // cylinder low (R/W) -#define USBAT_ATA_LBA_HI 0x15 // cylinder high (R/W) -#define USBAT_ATA_DEVICE 0x16 // head/device selection (R/W) -#define USBAT_ATA_STATUS 0x17 // device status (R) -#define USBAT_ATA_CMD 0x17 // device command (W) -#define USBAT_ATA_ALTSTATUS 0x0E // status (no clear IRQ) (R) +#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ +#define USBAT_ATA_FEATURES 0x11 /* set features (W) */ +#define USBAT_ATA_ERROR 0x11 /* error (R) */ +#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ +#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ +#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ +#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ +#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ +#define USBAT_ATA_STATUS 0x17 /* device status (R) */ +#define USBAT_ATA_CMD 0x17 /* device command (W) */ +#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ /* USBAT User I/O Data registers */ -#define USBAT_UIO_EPAD 0x80 // Enable Peripheral Control Signals -#define USBAT_UIO_CDT 0x40 // Card Detect (Read Only) - // CDT = ACKD & !UI1 & !UI0 -#define USBAT_UIO_1 0x20 // I/O 1 -#define USBAT_UIO_0 0x10 // I/O 0 -#define USBAT_UIO_EPP_ATA 0x08 // 1=EPP mode, 0=ATA mode -#define USBAT_UIO_UI1 0x04 // Input 1 -#define USBAT_UIO_UI0 0x02 // Input 0 -#define USBAT_UIO_INTR_ACK 0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP) +#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ +#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ + /* CDT = ACKD & !UI1 & !UI0 */ +#define USBAT_UIO_1 0x20 /* I/O 1 */ +#define USBAT_UIO_0 0x10 /* I/O 0 */ +#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ +#define USBAT_UIO_UI1 0x04 /* Input 1 */ +#define USBAT_UIO_UI0 0x02 /* Input 0 */ +#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ /* USBAT User I/O Enable registers */ -#define USBAT_UIO_DRVRST 0x80 // Reset Peripheral -#define USBAT_UIO_ACKD 0x40 // Enable Card Detect -#define USBAT_UIO_OE1 0x20 // I/O 1 set=output/clr=input - // If ACKD=1, set OE1 to 1 also. -#define USBAT_UIO_OE0 0x10 // I/O 0 set=output/clr=input -#define USBAT_UIO_ADPRST 0x01 // Reset SCM chip +#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ +#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ +#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ + /* If ACKD=1, set OE1 to 1 also. */ +#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ +#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ /* USBAT Features */ -#define USBAT_FEAT_ETEN 0x80 // External trigger enable +#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ #define USBAT_FEAT_U1 0x08 #define USBAT_FEAT_U0 0x04 #define USBAT_FEAT_ET1 0x02 @@ -112,12 +112,12 @@ struct usbat_info { int devicetype; /* Used for Flash readers only */ - unsigned long sectors; // total sector count - unsigned long ssize; // sector size in bytes + unsigned long sectors; /* total sector count */ + unsigned long ssize; /* sector size in bytes */ unsigned char sense_key; - unsigned long sense_asc; // additional sense code - unsigned long sense_ascq; // additional sense code qualifier + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ }; #endif diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 8d9e0663f8fe..0a362cc781ad 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -50,7 +50,7 @@ #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ #define US_PR_BULK 0x50 /* bulk only */ #ifdef CONFIG_USB_STORAGE_USBAT -#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ +#define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ #endif #ifdef CONFIG_USB_STORAGE_SDDR09 #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b79dad1b598c..71d051d97b77 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -71,12 +71,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, "HP", "CD-Writer+ 8200e", - US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, "HP", "CD-Writer+ CD-4e", - US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), #endif /* Patch submitted by Mihnea-Costin Grigore */ @@ -333,9 +333,9 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, #ifdef CONFIG_USB_STORAGE_USBAT UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, - "SCM", - "SCM USBAT-02", - US_SC_SCSI, US_PR_SCM_ATAPI, init_usbat, + "Shuttle/SCM", + "USBAT-02", + US_SC_SCSI, US_PR_USBAT, init_usbat, US_FL_SINGLE_LUN), #endif diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index f9a9bfa1aef5..5164900e40c1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -555,8 +555,8 @@ static int get_transport(struct us_data *us) break; #ifdef CONFIG_USB_STORAGE_USBAT - case US_PR_SCM_ATAPI: - us->transport_name = "SCM/ATAPI"; + case US_PR_USBAT: + us->transport_name = "Shuttle USBAT"; us->transport = usbat_transport; us->transport_reset = usb_stor_CB_reset; us->max_lun = 1; From 094ec604721ed2a9a7ed6dfe40fd699b2f53a4c3 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Fri, 30 Sep 2005 12:58:13 +0100 Subject: [PATCH 0856/1940] [PATCH] usb-storage: Readd missing SDDR-05b unusual_devs entry Just noticed that the SDDR-05b entry is missing for the shuttle_usbat driver. Looking through BK history it was removed in this patch: http://linux.bkbits.net:8080/linux-2.6/gnupatch@42435730FZQ2XCA6Qv5GPGD4pC4laQ However, at merge time, it looks like the duplicate was already removed, compare these two revisions: http://linux.bkbits.net:8080/linux-2.6/anno/drivers/usb/storage/unusual_devs.h@1.152 http://linux.bkbits.net:8080/linux-2.6/anno/drivers/usb/storage/unusual_devs.h@1.153 Signed-off-by: Daniel Drake Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/unusual_devs.h | 8 ++++++++ 1 file changed, 8 insertions(+) --- drivers/usb/storage/unusual_devs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 71d051d97b77..ee9f0502e055 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -702,6 +702,14 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN ), +#ifdef CONFIG_USB_STORAGE_USBAT +UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, + "Sandisk", + "ImageMate SDDR-05b", + US_SC_SCSI, US_PR_USBAT, init_usbat, + US_FL_SINGLE_LUN ), +#endif + UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, "Sandisk", "ImageMate SDDR-12", From e4a16e0c10a272e53c4a129b155dd711196b1d93 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Fri, 30 Sep 2005 00:20:15 -0700 Subject: [PATCH 0857/1940] [PATCH] Add unusual_dev for iBeat This patch adds the US_FL_IGNORE_RESIDUE flag for the TrekStor i.Beat Joy 2.0. Original version of this patch was sent by Stefan Werner with test/rediff/etc. by me. Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ee9f0502e055..730ba8dde9bd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Reported by Stefan Werner */ +UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, + "TrekStor", + "i.Beat Joy 2.0", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", From 880a9b5e7f70632ab60131ce3027da1c63fcd39e Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Fri, 30 Sep 2005 00:27:36 -0700 Subject: [PATCH 0858/1940] [PATCH] Add unusual_devs for iPod Nano This adds US_FL_FIX_CAPACITY for yet _another_ entire block of Apple productIds. They really can't seem to get this right. This one is for the iPod Nano. Reported by Tyson Vinson . Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/unusual_devs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) --- drivers/usb/storage/unusual_devs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 730ba8dde9bd..a11701840262 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -605,6 +605,16 @@ UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* + * Reported by Tyson Vinson + * This particular productId is the iPod Nano + */ +UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999, + "Apple", + "iPod", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + #ifdef CONFIG_USB_STORAGE_JUMPSHOT UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, "Lexar", From 3f8c03ee05801bf8539dd136d9246a416c45052a Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Wed, 28 Sep 2005 21:30:12 +0200 Subject: [PATCH 0859/1940] [PATCH] usb/input/touchkit: add more device IDs add two more device IDs from eGalax' programming guide. thanks to Jonathan Hopper for pointing out. Signed-off-by: Daniel Ritz Signed-off-by: Greg Kroah-Hartman drivers/usb/input/touchkitusb.c | 2 ++ 1 file changed, 2 insertions(+) --- drivers/usb/input/touchkitusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 3766ccc271be..0043e6ebcd1f 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c @@ -75,7 +75,9 @@ struct touchkit_usb { static struct usb_device_id touchkit_devices[] = { {USB_DEVICE(0x3823, 0x0001)}, + {USB_DEVICE(0x0123, 0x0001)}, {USB_DEVICE(0x0eef, 0x0001)}, + {USB_DEVICE(0x0eef, 0x0002)}, {} }; From a922c68732725866c88457026cf06a7620846506 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Oct 2005 16:38:45 -0400 Subject: [PATCH 0860/1940] [PATCH] g_file_storage: fix obscure race condition This patch (as575) fixes an unlikely race in the g_file_storage driver. The problem can occur only when the driver is unbound before its initialization routine has finished. I also took the opportunity to replace kmalloc/memset with kzalloc. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 241c570e541c..86a6aeb9ed76 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -3823,12 +3823,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) /* Create the LUNs, open their backing files, and register the * LUN devices in sysfs. */ - fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL); + fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL); if (!fsg->luns) { rc = -ENOMEM; goto out; } - memset(fsg->luns, 0, i * sizeof(struct lun)); fsg->nluns = i; for (i = 0; i < fsg->nluns; ++i) { @@ -3989,6 +3988,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) mod_data.removable, mod_data.can_stall, mod_data.buflen); DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); + + set_bit(REGISTERED, &fsg->atomic_bitflags); + + /* Tell the thread to start working */ + wake_up_process(fsg->thread_task); return 0; autoconf_fail: @@ -4051,10 +4055,9 @@ static int __init fsg_alloc(void) { struct fsg_dev *fsg; - fsg = kmalloc(sizeof *fsg, GFP_KERNEL); + fsg = kzalloc(sizeof *fsg, GFP_KERNEL); if (!fsg) return -ENOMEM; - memset(fsg, 0, sizeof *fsg); spin_lock_init(&fsg->lock); init_rwsem(&fsg->filesem); init_waitqueue_head(&fsg->thread_wqh); @@ -4080,15 +4083,9 @@ static int __init fsg_init(void) if ((rc = fsg_alloc()) != 0) return rc; fsg = the_fsg; - if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) { + if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) fsg_free(fsg); - return rc; - } - set_bit(REGISTERED, &fsg->atomic_bitflags); - - /* Tell the thread to start working */ - wake_up_process(fsg->thread_task); - return 0; + return rc; } module_init(fsg_init); From bb200f6eac6372839921be1fe87c1f5c292a7bd6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Oct 2005 16:36:29 -0400 Subject: [PATCH 0861/1940] [PATCH] UHCI: unify BIOS handoff and driver reset code This patch (as574) updates the PCI BIOS usb-handoff code for UHCI controllers, making it work like the reset routines in uhci-hcd. This allows uhci-hcd to drop its own routines in favor of the new ones (code-sharing). Once the patch is merged we can turn the usb-handoff option on permanently, as far as UHCI is concerned. OHCI and EHCI may still have some issues. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 142 +++++++++++++++++++++++----------- drivers/usb/host/uhci-hcd.c | 76 +++--------------- 2 files changed, 106 insertions(+), 112 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 49f7381a6fd3..f7411ca48835 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -9,6 +9,12 @@ */ #include +#ifdef CONFIG_USB_DEBUG +#define DEBUG +#else +#undef DEBUG +#endif + #include #include #include @@ -46,13 +52,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, qui #define UHCI_USBLEGSUP 0xc0 /* legacy support */ #define UHCI_USBCMD 0 /* command register */ -#define UHCI_USBSTS 2 /* status register */ #define UHCI_USBINTR 4 /* interrupt register */ -#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ -#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ -#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ -#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ -#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ +#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ +#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ +#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */ +#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */ +#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */ +#define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */ +#define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */ #define OHCI_CONTROL 0x04 #define OHCI_CMDSTATUS 0x08 @@ -84,11 +91,90 @@ static int __init usb_handoff_early(char *str) } __setup("usb-handoff", usb_handoff_early); +/* + * Make sure the controller is completely inactive, unable to + * generate interrupts or do DMA. + */ +void uhci_reset_hc(struct pci_dev *pdev, unsigned long base) +{ + /* Turn off PIRQ enable and SMI enable. (This also turns off the + * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. + */ + pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC); + + /* Reset the HC - this will force us to get a + * new notification of any already connected + * ports due to the virtual disconnect that it + * implies. + */ + outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); + mb(); + udelay(5); + if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET) + dev_warn(&pdev->dev, "HCRESET not completed yet!\n"); + + /* Just to be safe, disable interrupt requests and + * make sure the controller is stopped. + */ + outw(0, base + UHCI_USBINTR); + outw(0, base + UHCI_USBCMD); +} +EXPORT_SYMBOL_GPL(uhci_reset_hc); + +/* + * Initialize a controller that was newly discovered or has just been + * resumed. In either case we can't be sure of its previous state. + * + * Returns: 1 if the controller was reset, 0 otherwise. + */ +int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) +{ + u16 legsup; + unsigned int cmd, intr; + + /* + * When restarting a suspended controller, we expect all the + * settings to be the same as we left them: + * + * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; + * Controller is stopped and configured with EGSM set; + * No interrupts enabled except possibly Resume Detect. + * + * If any of these conditions are violated we do a complete reset. + */ + pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); + if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { + dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", + __FUNCTION__, legsup); + goto reset_needed; + } + + cmd = inw(base + UHCI_USBCMD); + if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || + !(cmd & UHCI_USBCMD_EGSM)) { + dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", + __FUNCTION__, cmd); + goto reset_needed; + } + + intr = inw(base + UHCI_USBINTR); + if (intr & (~UHCI_USBINTR_RESUME)) { + dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", + __FUNCTION__, intr); + goto reset_needed; + } + return 0; + +reset_needed: + dev_dbg(&pdev->dev, "Performing full reset\n"); + uhci_reset_hc(pdev, base); + return 1; +} +EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); + static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) { unsigned long base = 0; - int wait_time, delta; - u16 val, sts; int i; for (i = 0; i < PCI_ROM_RESOURCE; i++) @@ -97,44 +183,8 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) break; } - if (!base) - return; - - /* - * stop controller - */ - sts = inw(base + UHCI_USBSTS); - val = inw(base + UHCI_USBCMD); - val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); - outw(val, base + UHCI_USBCMD); - - /* - * wait while it stops if it was running - */ - if ((sts & UHCI_USBSTS_HALTED) == 0) - { - wait_time = 1000; - delta = 100; - - do { - outw(0x1f, base + UHCI_USBSTS); - udelay(delta); - wait_time -= delta; - val = inw(base + UHCI_USBSTS); - if (val & UHCI_USBSTS_HALTED) - break; - } while (wait_time > 0); - } - - /* - * disable interrupts & legacy support - */ - outw(0, base + UHCI_USBINTR); - outw(0x1f, base + UHCI_USBSTS); - pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); - if (val & 0xbf) - pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); - + if (base) + uhci_check_and_reset_hc(pdev, base); } static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 34c9dbc6a156..6df555e3d97c 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -101,37 +101,16 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); #include "uhci-q.c" #include "uhci-hub.c" +extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); +extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); + /* - * Make sure the controller is completely inactive, unable to - * generate interrupts or do DMA. + * Finish up a host controller reset and update the recorded state. */ -static void reset_hc(struct uhci_hcd *uhci) +static void finish_reset(struct uhci_hcd *uhci) { int port; - /* Turn off PIRQ enable and SMI enable. (This also turns off the - * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. - */ - pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, - USBLEGSUP_RWC); - - /* Reset the HC - this will force us to get a - * new notification of any already connected - * ports due to the virtual disconnect that it - * implies. - */ - outw(USBCMD_HCRESET, uhci->io_addr + USBCMD); - mb(); - udelay(5); - if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET) - dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n"); - - /* Just to be safe, disable interrupt requests and - * make sure the controller is stopped. - */ - outw(0, uhci->io_addr + USBINTR); - outw(0, uhci->io_addr + USBCMD); - /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect * bits in the port status and control registers. * We have to clear them by hand. @@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uhci) */ static void hc_died(struct uhci_hcd *uhci) { - reset_hc(uhci); + uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); + finish_reset(uhci); uhci->hc_inaccessible = 1; } @@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhci) */ static void check_and_reset_hc(struct uhci_hcd *uhci) { - u16 legsup; - unsigned int cmd, intr; - - /* - * When restarting a suspended controller, we expect all the - * settings to be the same as we left them: - * - * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; - * Controller is stopped and configured with EGSM set; - * No interrupts enabled except possibly Resume Detect. - * - * If any of these conditions are violated we do a complete reset. - */ - pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); - if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { - dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", - __FUNCTION__, legsup); - goto reset_needed; - } - - cmd = inw(uhci->io_addr + USBCMD); - if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { - dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", - __FUNCTION__, cmd); - goto reset_needed; - } - - intr = inw(uhci->io_addr + USBINTR); - if (intr & (~USBINTR_RESUME)) { - dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", - __FUNCTION__, intr); - goto reset_needed; - } - return; - -reset_needed: - dev_dbg(uhci_dev(uhci), "Performing full reset\n"); - reset_hc(uhci); + if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr)) + finish_reset(uhci); } /* @@ -714,7 +658,7 @@ static void uhci_stop(struct usb_hcd *hcd) spin_lock_irq(&uhci->lock); if (!uhci->hc_inaccessible) - reset_hc(uhci); + hc_died(uhci); uhci_scan_schedule(uhci, NULL); spin_unlock_irq(&uhci->lock); From 0c0382e32d46f606951010b202382be14d180a17 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 13 Oct 2005 17:08:02 -0400 Subject: [PATCH 0862/1940] [PATCH] USB: Rename hcd->hub_suspend to hcd->bus_suspend This patch (as580) is perhaps the only result from the long discussion I had with David about his changes to the root-hub suspend/resume code. It renames the hub_suspend and hub_resume methods in struct usb_hcd to bus_suspend and bus_resume. These are more descriptive names, since the methods really do suspend or resume an entire USB bus, and less likely to be confused with the hub_suspend and hub_resume routines in hub.c. It also takes David's advice about removing the layer of bus glue, where those methods are called. And it implements a related change that David made to the other HCDs but forgot to put into dummy_hcd. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 16 ++++++---------- drivers/usb/core/hcd.h | 23 +++++++++++++++++------ drivers/usb/core/hub.c | 8 ++++---- drivers/usb/gadget/dummy_hcd.c | 22 ++++------------------ drivers/usb/host/ehci-hub.c | 8 ++++---- drivers/usb/host/ehci-pci.c | 4 ++-- drivers/usb/host/isp116x-hcd.c | 12 ++++++------ drivers/usb/host/ohci-au1xxx.c | 4 ++-- drivers/usb/host/ohci-hub.c | 6 +++--- drivers/usb/host/ohci-lh7a404.c | 4 ++-- drivers/usb/host/ohci-omap.c | 4 ++-- drivers/usb/host/ohci-pci.c | 4 ++-- drivers/usb/host/ohci-ppc-soc.c | 4 ++-- drivers/usb/host/ohci-pxa27x.c | 4 ++-- drivers/usb/host/ohci-s3c2410.c | 4 ++-- drivers/usb/host/ohci-sa1111.c | 4 ++-- drivers/usb/host/sl811-hcd.c | 16 ++++++++-------- drivers/usb/host/uhci-hcd.c | 4 ++-- 18 files changed, 72 insertions(+), 79 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index b7bb8dd1894a..9ad3912a5ed7 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1433,16 +1433,16 @@ hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep) #ifdef CONFIG_PM -static int hcd_hub_suspend (struct usb_bus *bus) +int hcd_bus_suspend (struct usb_bus *bus) { struct usb_hcd *hcd; int status; hcd = container_of (bus, struct usb_hcd, self); - if (!hcd->driver->hub_suspend) + if (!hcd->driver->bus_suspend) return -ENOENT; hcd->state = HC_STATE_QUIESCING; - status = hcd->driver->hub_suspend (hcd); + status = hcd->driver->bus_suspend (hcd); if (status == 0) hcd->state = HC_STATE_SUSPENDED; else @@ -1451,18 +1451,18 @@ static int hcd_hub_suspend (struct usb_bus *bus) return status; } -static int hcd_hub_resume (struct usb_bus *bus) +int hcd_bus_resume (struct usb_bus *bus) { struct usb_hcd *hcd; int status; hcd = container_of (bus, struct usb_hcd, self); - if (!hcd->driver->hub_resume) + if (!hcd->driver->bus_resume) return -ENOENT; if (hcd->state == HC_STATE_RUNNING) return 0; hcd->state = HC_STATE_RESUMING; - status = hcd->driver->hub_resume (hcd); + status = hcd->driver->bus_resume (hcd); if (status == 0) hcd->state = HC_STATE_RUNNING; else { @@ -1590,10 +1590,6 @@ static struct usb_operations usb_hcd_operations = { .buffer_alloc = hcd_buffer_alloc, .buffer_free = hcd_buffer_free, .disable = hcd_endpoint_disable, -#ifdef CONFIG_PM - .hub_suspend = hcd_hub_suspend, - .hub_resume = hcd_hub_resume, -#endif }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 74757fc1a99f..d8f0d29a45b7 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -154,10 +154,6 @@ struct usb_operations { void (*disable)(struct usb_device *udev, struct usb_host_endpoint *ep); - - /* global suspend/resume of bus */ - int (*hub_suspend)(struct usb_bus *); - int (*hub_resume)(struct usb_bus *); }; /* each driver provides one of these, and hardware init support */ @@ -212,8 +208,8 @@ struct hc_driver { int (*hub_control) (struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); - int (*hub_suspend)(struct usb_hcd *); - int (*hub_resume)(struct usb_hcd *); + int (*bus_suspend)(struct usb_hcd *); + int (*bus_resume)(struct usb_hcd *); int (*start_port_reset)(struct usb_hcd *, unsigned port_num); void (*hub_irq_enable)(struct usb_hcd *); /* Needed only if port-change IRQs are level-triggered */ @@ -379,6 +375,21 @@ extern int usb_find_interface_driver (struct usb_device *dev, #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) +#ifdef CONFIG_PM +extern int hcd_bus_suspend (struct usb_bus *bus); +extern int hcd_bus_resume (struct usb_bus *bus); +#else +static inline int hcd_bus_suspend(struct usb_bus *bus) +{ + return 0; +} + +static inline int hcd_bus_resume (struct usb_bus *bus) +{ + return 0; +} +#endif /* CONFIG_PM */ + /* * USB device fs stuff */ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e2802bf18095..273e6ccca213 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1917,8 +1917,8 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) /* "global suspend" of the downstream HC-to-USB interface */ if (!hdev->parent) { struct usb_bus *bus = hdev->bus; - if (bus && bus->op->hub_suspend) { - int status = bus->op->hub_suspend (bus); + if (bus) { + int status = hcd_bus_suspend (bus); if (status != 0) { dev_dbg(&hdev->dev, "'global' suspend %d\n", @@ -1943,8 +1943,8 @@ static int hub_resume(struct usb_interface *intf) /* "global resume" of the downstream HC-to-USB interface */ if (!hdev->parent) { struct usb_bus *bus = hdev->bus; - if (bus && bus->op->hub_resume) { - status = bus->op->hub_resume (bus); + if (bus) { + status = hcd_bus_resume (bus); if (status) { dev_dbg(&intf->dev, "'global' resume %d\n", status); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 503201764f6b..c605aaeed636 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1751,7 +1751,7 @@ static int dummy_hub_control ( return retval; } -static int dummy_hub_suspend (struct usb_hcd *hcd) +static int dummy_bus_suspend (struct usb_hcd *hcd) { struct dummy *dum = hcd_to_dummy (hcd); @@ -1762,7 +1762,7 @@ static int dummy_hub_suspend (struct usb_hcd *hcd) return 0; } -static int dummy_hub_resume (struct usb_hcd *hcd) +static int dummy_bus_resume (struct usb_hcd *hcd) { struct dummy *dum = hcd_to_dummy (hcd); @@ -1894,8 +1894,8 @@ static const struct hc_driver dummy_hcd = { .hub_status_data = dummy_hub_status, .hub_control = dummy_hub_control, - .hub_suspend = dummy_hub_suspend, - .hub_resume = dummy_hub_resume, + .bus_suspend = dummy_bus_suspend, + .bus_resume = dummy_bus_resume, }; static int dummy_hcd_probe (struct device *dev) @@ -1936,13 +1936,6 @@ static int dummy_hcd_suspend (struct device *dev, pm_message_t state) dev_dbg (dev, "%s\n", __FUNCTION__); hcd = dev_get_drvdata (dev); -#ifndef CONFIG_USB_SUSPEND - /* Otherwise this would never happen */ - usb_lock_device (hcd->self.root_hub); - dummy_hub_suspend (hcd); - usb_unlock_device (hcd->self.root_hub); -#endif - hcd->state = HC_STATE_SUSPENDED; return 0; } @@ -1955,13 +1948,6 @@ static int dummy_hcd_resume (struct device *dev) hcd = dev_get_drvdata (dev); hcd->state = HC_STATE_RUNNING; -#ifndef CONFIG_USB_SUSPEND - /* Otherwise this would never happen */ - usb_lock_device (hcd->self.root_hub); - dummy_hub_resume (hcd); - usb_unlock_device (hcd->self.root_hub); -#endif - usb_hcd_poll_rh_status (hcd); return 0; } diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 18d3f2270316..88cb4ada686e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -30,7 +30,7 @@ #ifdef CONFIG_PM -static int ehci_hub_suspend (struct usb_hcd *hcd) +static int ehci_bus_suspend (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int port; @@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) /* caller has locked the root hub, and should reset/reinit on error */ -static int ehci_hub_resume (struct usb_hcd *hcd) +static int ehci_bus_resume (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp; @@ -159,8 +159,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd) #else -#define ehci_hub_suspend NULL -#define ehci_hub_resume NULL +#define ehci_bus_suspend NULL +#define ehci_bus_resume NULL #endif /* CONFIG_PM */ diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 66ebf75b2037..8bbc8dfe19f3 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -363,8 +363,8 @@ static const struct hc_driver ehci_pci_hc_driver = { */ .hub_status_data = ehci_hub_status_data, .hub_control = ehci_hub_control, - .hub_suspend = ehci_hub_suspend, - .hub_resume = ehci_hub_resume, + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index f68220fc53fd..ddb8fc591466 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1160,7 +1160,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, #ifdef CONFIG_PM -static int isp116x_hub_suspend(struct usb_hcd *hcd) +static int isp116x_bus_suspend(struct usb_hcd *hcd) { struct isp116x *isp116x = hcd_to_isp116x(hcd); unsigned long flags; @@ -1200,7 +1200,7 @@ static int isp116x_hub_suspend(struct usb_hcd *hcd) return ret; } -static int isp116x_hub_resume(struct usb_hcd *hcd) +static int isp116x_bus_resume(struct usb_hcd *hcd) { struct isp116x *isp116x = hcd_to_isp116x(hcd); u32 val; @@ -1266,8 +1266,8 @@ static int isp116x_hub_resume(struct usb_hcd *hcd) #else -#define isp116x_hub_suspend NULL -#define isp116x_hub_resume NULL +#define isp116x_bus_suspend NULL +#define isp116x_bus_resume NULL #endif @@ -1626,8 +1626,8 @@ static struct hc_driver isp116x_hc_driver = { .hub_status_data = isp116x_hub_status_data, .hub_control = isp116x_hub_control, - .hub_suspend = isp116x_hub_suspend, - .hub_resume = isp116x_hub_resume, + .bus_suspend = isp116x_bus_suspend, + .bus_resume = isp116x_bus_resume, }; /*----------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 550d67a554f6..ac463c493035 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -215,8 +215,8 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 39a60e731ec2..e01e77bc324b 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hcd *, struct pt_regs *); static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); static int ohci_restart (struct ohci_hcd *ohci); -static int ohci_hub_suspend (struct usb_hcd *hcd) +static int ohci_bus_suspend (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int status = 0; @@ -135,7 +135,7 @@ static inline struct ed *find_head (struct ed *ed) } /* caller has locked the root hub */ -static int ohci_hub_resume (struct usb_hcd *hcd) +static int ohci_bus_resume (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); u32 temp, enables; @@ -362,7 +362,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) && usb_trylock_device (hcd->self.root_hub) ) { ohci_vdbg (ohci, "autosuspend\n"); - (void) ohci_hub_suspend (hcd); + (void) ohci_bus_suspend (hcd); usb_unlock_device (hcd->self.root_hub); } #endif diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 71d975ae78bd..e2ed55b69f86 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -194,8 +194,8 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index b3498b9b965f..982cdca22516 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -421,8 +421,8 @@ static const struct hc_driver ohci_omap_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 99a0ad41aec5..a8dde8b75691 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -195,8 +195,8 @@ static const struct hc_driver ohci_pci_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index ec20710e99fe..228845eb7eab 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -164,8 +164,8 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 2e7b48502a3d..d287dcccd415 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -279,8 +279,8 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 922e2a6f46ef..3225d455f459 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -449,8 +449,8 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { .hub_status_data = ohci_s3c2410_hub_status_data, .hub_control = ohci_s3c2410_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 13324b7f9c59..fb3221ebbb29 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -236,8 +236,8 @@ static const struct hc_driver ohci_sa1111_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index b5e7a478bc01..1e47c1f86e70 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1363,7 +1363,7 @@ sl811h_hub_control( #ifdef CONFIG_PM static int -sl811h_hub_suspend(struct usb_hcd *hcd) +sl811h_bus_suspend(struct usb_hcd *hcd) { // SOFs off DBG("%s\n", __FUNCTION__); @@ -1371,7 +1371,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd) } static int -sl811h_hub_resume(struct usb_hcd *hcd) +sl811h_bus_resume(struct usb_hcd *hcd) { // SOFs on DBG("%s\n", __FUNCTION__); @@ -1380,8 +1380,8 @@ sl811h_hub_resume(struct usb_hcd *hcd) #else -#define sl811h_hub_suspend NULL -#define sl811h_hub_resume NULL +#define sl811h_bus_suspend NULL +#define sl811h_bus_resume NULL #endif @@ -1623,8 +1623,8 @@ static struct hc_driver sl811h_hc_driver = { */ .hub_status_data = sl811h_hub_status_data, .hub_control = sl811h_hub_control, - .hub_suspend = sl811h_hub_suspend, - .hub_resume = sl811h_hub_resume, + .bus_suspend = sl811h_bus_suspend, + .bus_resume = sl811h_bus_resume, }; /*-------------------------------------------------------------------------*/ @@ -1791,7 +1791,7 @@ sl811h_suspend(struct device *dev, pm_message_t state) int retval = 0; if (state.event == PM_EVENT_FREEZE) - retval = sl811h_hub_suspend(hcd); + retval = sl811h_bus_suspend(hcd); else if (state.event == PM_EVENT_SUSPEND) port_power(sl811, 0); if (retval == 0) @@ -1816,7 +1816,7 @@ sl811h_resume(struct device *dev) } dev->power.power_state = PMSG_ON; - return sl811h_hub_resume(hcd); + return sl811h_bus_resume(hcd); } #else diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 6df555e3d97c..72cd1576d20c 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -804,8 +804,8 @@ static const struct hc_driver uhci_driver = { #ifdef CONFIG_PM .suspend = uhci_suspend, .resume = uhci_resume, - .hub_suspend = uhci_rh_suspend, - .hub_resume = uhci_rh_resume, + .bus_suspend = uhci_rh_suspend, + .bus_resume = uhci_rh_resume, #endif .stop = uhci_stop, From b81d34363c0b17c47f4ef63d5888c4f47f315d29 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 13 Oct 2005 17:00:24 -0400 Subject: [PATCH 0863/1940] [PATCH] UHCI: Improve handling of iso TDs The uhci-hcd driver is fairly lax about the way it handles isochronous transfers. This patch (as579) improves it in three respects: TDs for a new URB aren't added to the schedule until all of them have been allocated. This way there's no risk of the controller executing some of them when an allocation fails. TDs for an unlinked URB are removed from the schedule as soon as the URB is unlinked, rather than waiting until the URB is given back. This way there's no risk of the controller still executing a TD after the URB completes. The urb->error_count values are now reported correctly. Although since they aren't used in any drivers except for debug messages in the system log, probably nobody cares. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-q.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 51de06bc438d..7e46887d9e12 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -108,13 +108,16 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, } } -static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) +static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci, + struct uhci_td *td) { /* If it's not inserted, don't remove it */ - if (td->frame == -1 && list_empty(&td->fl_list)) + if (td->frame == -1) { + WARN_ON(!list_empty(&td->fl_list)); return; + } - if (td->frame != -1 && uhci->frame_cpu[td->frame] == td) { + if (uhci->frame_cpu[td->frame] == td) { if (list_empty(&td->fl_list)) { uhci->frame[td->frame] = td->link; uhci->frame_cpu[td->frame] = NULL; @@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) ptd->link = td->link; } - wmb(); - td->link = UHCI_PTR_TERM; - list_del_init(&td->fl_list); td->frame = -1; } +static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; + struct uhci_td *td; + + list_for_each_entry(td, &urbp->td_list, list) + uhci_remove_td_frame_list(uhci, td); + wmb(); +} + /* * Inserts a td list into qh. */ @@ -498,7 +508,6 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { uhci_remove_td_from_urb(td); - uhci_remove_td(uhci, td); list_add(&td->remove_list, &uhci->td_remove_list); } @@ -1068,6 +1077,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) struct uhci_td *td; int i, ret, frame; int status, destination; + struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; status = TD_CTRL_ACTIVE | TD_CTRL_IOS; destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); @@ -1076,11 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) if (ret) return ret; - frame = urb->start_frame; - for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) { - if (!urb->iso_frame_desc[i].length) - continue; - + for (i = 0; i < urb->number_of_packets; i++) { td = uhci_alloc_td(uhci); if (!td) return -ENOMEM; @@ -1091,8 +1097,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) if (i + 1 >= urb->number_of_packets) td->status |= cpu_to_le32(TD_CTRL_IOC); + } + frame = urb->start_frame; + list_for_each_entry(td, &urbp->td_list, list) { uhci_insert_td_frame_list(uhci, td, frame); + frame += urb->interval; } return -EINPROGRESS; @@ -1105,7 +1115,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) int status; int i, ret = 0; - urb->actual_length = 0; + urb->actual_length = urb->error_count = 0; i = 0; list_for_each_entry(td, &urbp->td_list, list) { @@ -1129,6 +1139,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) i++; } + unlink_isochronous_tds(uhci, urb); return ret; } @@ -1361,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) goto done; list_del_init(&urbp->urb_list); + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + unlink_isochronous_tds(uhci, urb); uhci_unlink_generic(uhci, urb); uhci_get_current_frame_number(uhci); From af64a5ebb817532965d18b792d6d74afecfb0bcf Mon Sep 17 00:00:00 2001 From: Henk Date: Wed, 12 Oct 2005 15:02:56 +0200 Subject: [PATCH 0864/1940] [PATCH] USB: Buffer overflow patch for Yealink driver Just a small patch that fixes a small parameter validation bug. drivers/usb/input/map_to_7segment.h: This patch fixes the broken parameter validation in the char to seg7 conversion. This could cause out-of-bounds memory references. MAINTAINERS: Yealink maintainer info now in sorted order. Documentation/input/yealink.txt: Added a Q&A section that answers some common questions. Signed-off-by: Henk Signed-off-by: Greg Kroah-Hartman 006491df1a13f85ad245d1039dfdf20e49c394fd --- Documentation/input/yealink.txt | 19 ++++++++++++++++--- MAINTAINERS | 12 ++++++------ drivers/usb/input/map_to_7segment.h | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt index 85f095a7ad04..0962c5c948be 100644 --- a/Documentation/input/yealink.txt +++ b/Documentation/input/yealink.txt @@ -2,7 +2,6 @@ Driver documentation for yealink usb-p1k phones 0. Status ~~~~~~~~~ - The p1k is a relatively cheap usb 1.1 phone with: - keyboard full support, yealink.ko / input event API - LCD full support, yealink.ko / sysfs API @@ -17,9 +16,8 @@ For vendor documentation see http://www.yealink.com 1. Compilation (stand alone version) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Currently only kernel 2.6.x.y versions are supported. -In order to build the yealink.ko module do: +In order to build the yealink.ko module do make @@ -28,6 +26,21 @@ the Makefile is pointing to the location where your kernel sources are located, default /usr/src/linux. +1.1 Troubleshooting +~~~~~~~~~~~~~~~~~~~ +Q: Module yealink compiled and installed without any problem but phone + is not initialized and does not react to any actions. +A: If you see something like: + hiddev0: USB HID v1.00 Device [Yealink Network Technology Ltd. VOIP USB Phone + in dmesg, it means that the hid driver has grabbed the device first. Try to + load module yealink before any other usb hid driver. Please see the + instructions provided by your distribution on module configuration. + +Q: Phone is working now (displays version and accepts keypad input) but I can't + find the sysfs files. +A: The sysfs files are located on the particular usb endpoint. On most + distributions you can do: "find /sys/ -name get_icons" for a hint. + 2. keyboard features ~~~~~~~~~~~~~~~~~~~~ diff --git a/MAINTAINERS b/MAINTAINERS index 3928dc7d6ea9..2868b2879755 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -116,12 +116,6 @@ M: ajk@iehk.rwth-aachen.de L: linux-hams@vger.kernel.org S: Maintained -YEALINK PHONE DRIVER -P: Henk Vergonet -M: Henk.Vergonet@gmail.com -L: usbb2k-api-dev@nongnu.org -S: Maintained - 8139CP 10/100 FAST ETHERNET DRIVER P: Jeff Garzik M: jgarzik@pobox.com @@ -2863,6 +2857,12 @@ M: jpr@f6fbb.org L: linux-hams@vger.kernel.org S: Maintained +YEALINK PHONE DRIVER +P: Henk Vergonet +M: Henk.Vergonet@gmail.com +L: usbb2k-api-dev@nongnu.org +S: Maintained + YMFPCI YAMAHA PCI SOUND (Use ALSA instead) P: Pete Zaitcev M: zaitcev@yahoo.com diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h index 52ff27f15127..a424094d9fe2 100644 --- a/drivers/usb/input/map_to_7segment.h +++ b/drivers/usb/input/map_to_7segment.h @@ -79,7 +79,7 @@ struct seg7_conversion_map { static inline int map_to_seg7(struct seg7_conversion_map *map, int c) { - return c & 0x7f ? map->table[c] : -EINVAL; + return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL; } #define SEG7_CONVERSION_MAP(_name, _map) \ From 1fcb4454cbada6dc495302172ac0412aa7d35fd4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 15 Oct 2005 22:03:30 -0700 Subject: [PATCH 0865/1940] [PATCH] usb doc: fix kernel-doc warning usb/core/buffer.c doesn't export any symbols, so it should use !I instead of !E to eliminate this warning message: Warning(/var/linsrc/linux-2614-rc4//drivers/usb/core/buffer.c): no structured comments found Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/usb.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl index 705c442c7bf4..15ce0f21e5e0 100644 --- a/Documentation/DocBook/usb.tmpl +++ b/Documentation/DocBook/usb.tmpl @@ -291,7 +291,7 @@ !Edrivers/usb/core/hcd.c !Edrivers/usb/core/hcd-pci.c -!Edrivers/usb/core/buffer.c +!Idrivers/usb/core/buffer.c From cb97c5c9d0789d65d7ec42a80946fa9eb2ec5182 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 16 Oct 2005 15:06:51 -0700 Subject: [PATCH 0866/1940] [PATCH] omap_udc dma off-by-one fix The change to make DMA work two bytes at a time omitted an important tweak that affects the file_storage gadget: it needs to recognize when the host writes an odd number of bytes. (The network layer ignores such extra bytes.) This patch resolves that issue by checking the relevant bit and adjusting the rx byte count, so that for example a legal 13 byte request doesn't morph into an illegal 14 byte one any more. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/omap_udc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b7885dc0f42f..de8a89ae4bc3 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -691,7 +691,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) } static void -finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status) +finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) { u16 count; @@ -699,6 +699,8 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status) ep->dma_counter = (u16) (req->req.dma + req->req.actual); count = dma_dest_len(ep, req->req.dma + req->req.actual); count += req->req.actual; + if (one) + count--; if (count <= req->req.length) req->req.actual = count; @@ -747,7 +749,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); - finish_out_dma(ep, req, 0); + finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB); } UDC_IRQ_SRC_REG = UDC_RXN_EOT; @@ -925,7 +927,7 @@ static void dma_channel_release(struct omap_ep *ep) while (UDC_RXDMA_CFG_REG & mask) udelay(10); if (req) - finish_out_dma(ep, req, -ECONNRESET); + finish_out_dma(ep, req, -ECONNRESET, 0); } omap_free_dma(ep->lch); ep->dma_channel = 0; From f37be9b9be3ebc02d2d075d7f53f7802f3e005db Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 17 Oct 2005 10:42:06 -0400 Subject: [PATCH 0867/1940] [PATCH] Fix hcd->state assignments in uhci-hcd This patch (as581) changes the assignments to hcd->state in the uhci-hcd driver. It fixes part of bugzilla entry #5227. The problem was revealed by David's large suite of USB suspend/resume patches; this patch should go to Linus at the same time those do. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 72cd1576d20c..d33ce3982a5f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -161,8 +161,8 @@ static void configure_hc(struct uhci_hcd *uhci) /* Set the current frame number */ outw(uhci->frame_number, uhci->io_addr + USBFRNUM); - /* Mark controller as running before we enable interrupts */ - uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; + /* Mark controller as not halted before we enable interrupts */ + uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; mb(); /* Enable PIRQ */ @@ -263,6 +263,7 @@ __acquires(uhci->lock) static void start_rh(struct uhci_hcd *uhci) { + uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; uhci->is_stopped = 0; smp_wmb(); @@ -708,7 +709,6 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) if (uhci->rh_state > UHCI_RH_SUSPENDED) { dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); - hcd->state = HC_STATE_RUNNING; rc = -EBUSY; goto done; }; From 4e67185a7ac3ecb1710e636e2f7e318e99298c7a Mon Sep 17 00:00:00 2001 From: Juha Yrj?l? Date: Sun, 16 Oct 2005 15:47:04 -0700 Subject: [PATCH 0868/1940] [PATCH] add usb transceiver set_suspend() method When a USB device is put into suspend mode, the current drawn from VBUS has to be less than 500 uA. Some transceivers need to be put into a special power-saving mode to accomplish this, and won't have a separate OTG driver handling that. This adds a suspend method to the "otg_transceiver" struct -- misnamed, it's not only for OTG -- and calls it from the OMAP UDC driver. Signed-off-by: Juha Yrj?l? Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/omap_udc.c | 4 ++++ include/linux/usb_otg.h | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index de8a89ae4bc3..b42799bc747a 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1788,8 +1788,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) udc->driver->suspend(&udc->gadget); spin_lock(&udc->lock); } + if (udc->transceiver) + otg_set_suspend(udc->transceiver, 1); } else { VDBG("resume\n"); + if (udc->transceiver) + otg_set_suspend(udc->transceiver, 0); if (udc->gadget.speed == USB_SPEED_FULL && udc->driver->resume) { spin_unlock(&udc->lock); diff --git a/include/linux/usb_otg.h b/include/linux/usb_otg.h index c6683146e9b0..f827f6e203c2 100644 --- a/include/linux/usb_otg.h +++ b/include/linux/usb_otg.h @@ -63,6 +63,10 @@ struct otg_transceiver { int (*set_power)(struct otg_transceiver *otg, unsigned mA); + /* for non-OTG B devices: set transceiver into suspend mode */ + int (*set_suspend)(struct otg_transceiver *otg, + int suspend); + /* for B devices only: start session with A-Host */ int (*start_srp)(struct otg_transceiver *otg); @@ -107,6 +111,15 @@ otg_set_power(struct otg_transceiver *otg, unsigned mA) return otg->set_power(otg, mA); } +static inline int +otg_set_suspend(struct otg_transceiver *otg, int suspend) +{ + if (otg->set_suspend != NULL) + return otg->set_suspend(otg, suspend); + else + return 0; +} + static inline int otg_start_srp(struct otg_transceiver *otg) { From a85ee6b50c8a1fca4034c8d6b21c91a8de171e01 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 10 Oct 2005 01:23:50 +0100 Subject: [PATCH 0869/1940] [PATCH] USB: S3C2410 OHCI - add driver owner field Initialise the .owner field of the driver with the module that owns it, to aid in linking drivers to modules. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-s3c2410.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 3225d455f459..fab420a2ce71 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -474,6 +474,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct device *dev) static struct device_driver ohci_hcd_s3c2410_driver = { .name = "s3c2410-ohci", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = ohci_hcd_s3c2410_drv_probe, .remove = ohci_hcd_s3c2410_drv_remove, From d0d5049fb02fc1082c17e08deecd6fed8db549b6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 10 Oct 2005 10:52:33 +0100 Subject: [PATCH 0870/1940] [PATCH] USB: gadget drivers - add .owner initialisation Ensure the the device_driver and usb_gadget_driver have their .owner fields initialised to associate the module owner to the driver. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/dummy_hcd.c | 2 ++ drivers/usb/gadget/ether.c | 1 + drivers/usb/gadget/file_storage.c | 1 + drivers/usb/gadget/goku_udc.c | 1 + drivers/usb/gadget/lh7a40x_udc.c | 1 + drivers/usb/gadget/net2280.c | 1 + drivers/usb/gadget/omap_udc.c | 1 + drivers/usb/gadget/pxa2xx_udc.c | 1 + drivers/usb/gadget/zero.c | 1 + 9 files changed, 10 insertions(+) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c605aaeed636..02106bebd5c1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -967,6 +967,7 @@ static int dummy_udc_resume (struct device *dev) static struct device_driver dummy_udc_driver = { .name = (char *) gadget_name, + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = dummy_udc_probe, .remove = dummy_udc_remove, @@ -1954,6 +1955,7 @@ static int dummy_hcd_resume (struct device *dev) static struct device_driver dummy_hcd_driver = { .name = (char *) driver_name, + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = dummy_hcd_probe, .remove = dummy_hcd_remove, diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f1024e804d5c..8f402f85e1ca 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2533,6 +2533,7 @@ static struct usb_gadget_driver eth_driver = { .driver = { .name = (char *) shortname, + .owner = THIS_MODULE, // .shutdown = ... // .suspend = ... // .resume = ... diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 86a6aeb9ed76..ea09aaa3cab6 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -4044,6 +4044,7 @@ static struct usb_gadget_driver fsg_driver = { .driver = { .name = (char *) shortname, + .owner = THIS_MODULE, // .release = ... // .suspend = ... // .resume = ... diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index b0f3cd63e3b9..654469778ab5 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1970,6 +1970,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); static struct pci_driver goku_pci_driver = { .name = (char *) driver_name, .id_table = pci_ids, + .owner = THIS_MODULE, .probe = goku_probe, .remove = goku_remove, diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 012d1e5f1524..9b3673904daf 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -2140,6 +2140,7 @@ static int lh7a40x_udc_remove(struct device *_dev) static struct device_driver udc_driver = { .name = (char *)driver_name, + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = lh7a40x_udc_probe, .remove = lh7a40x_udc_remove diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c32e1f7476da..0dc6bb00bf72 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2948,6 +2948,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); static struct pci_driver net2280_pci_driver = { .name = (char *) driver_name, .id_table = pci_ids, + .owner = THIS_MODULE, .probe = net2280_probe, .remove = net2280_remove, diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b42799bc747a..41c96b0afbb3 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2949,6 +2949,7 @@ static int omap_udc_resume(struct device *dev) static struct device_driver udc_driver = { .name = (char *) driver_name, + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = omap_udc_probe, .remove = __exit_p(omap_udc_remove), diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 647028590b23..f83a9262f953 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -2631,6 +2631,7 @@ static int pxa2xx_udc_resume(struct device *dev) static struct device_driver udc_driver = { .name = "pxa2xx-udc", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = pxa2xx_udc_probe, .shutdown = pxa2xx_udc_shutdown, diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index ec9c424f1d97..6c58636e914b 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -1302,6 +1302,7 @@ static struct usb_gadget_driver zero_driver = { .driver = { .name = (char *) shortname, + .owner = THIS_MODULE, // .shutdown = ... // .suspend = ... // .resume = ... From efa400db5332ba341cc354c9d8a5298ff57faa98 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 10 Oct 2005 02:32:15 +0100 Subject: [PATCH 0871/1940] [PATCH] USB: add owner initialisation to host drivers Add .owner initialisation to the device drivers in drivers/usb/host so that when built as module the device_driver refers to the owning module Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-pci.c | 1 + drivers/usb/host/ohci-au1xxx.c | 1 + drivers/usb/host/ohci-lh7a404.c | 1 + drivers/usb/host/ohci-omap.c | 1 + drivers/usb/host/ohci-pci.c | 1 + drivers/usb/host/ohci-ppc-soc.c | 1 + drivers/usb/host/sl811-hcd.c | 1 + drivers/usb/host/uhci-hcd.c | 1 + 8 files changed, 8 insertions(+) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 8bbc8dfe19f3..7872469ccbb1 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -383,6 +383,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); static struct pci_driver ehci_pci_driver = { .name = (char *) hcd_name, .id_table = pci_ids, + .owner = THIS_MODULE, .probe = usb_hcd_pci_probe, .remove = usb_hcd_pci_remove, diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index ac463c493035..a277e258eb6c 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -264,6 +264,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) static struct device_driver ohci_hcd_au1xxx_driver = { .name = "au1xxx-ohci", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = ohci_hcd_au1xxx_drv_probe, .remove = ohci_hcd_au1xxx_drv_remove, diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index e2ed55b69f86..238fa4ade615 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -244,6 +244,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct device *dev) static struct device_driver ohci_hcd_lh7a404_driver = { .name = "lh7a404-ohci", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = ohci_hcd_lh7a404_drv_probe, .remove = ohci_hcd_lh7a404_drv_remove, diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 982cdca22516..45efeed1fcc3 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -492,6 +492,7 @@ static int ohci_omap_resume(struct device *dev) */ static struct device_driver ohci_hcd_omap_driver = { .name = "ohci", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = ohci_hcd_omap_drv_probe, .remove = ohci_hcd_omap_drv_remove, diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a8dde8b75691..bf1d5ab4aa3a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -216,6 +216,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); static struct pci_driver ohci_pci_driver = { .name = (char *) hcd_name, .id_table = pci_ids, + .owner = THIS_MODULE, .probe = usb_hcd_pci_probe, .remove = usb_hcd_pci_remove, diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 228845eb7eab..4832e57ae579 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -193,6 +193,7 @@ static int ohci_hcd_ppc_soc_drv_remove(struct device *dev) static struct device_driver ohci_hcd_ppc_soc_driver = { .name = "ppc-soc-ohci", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = ohci_hcd_ppc_soc_drv_probe, .remove = ohci_hcd_ppc_soc_drv_remove, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 1e47c1f86e70..40169d9cf2b1 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1831,6 +1831,7 @@ sl811h_resume(struct device *dev) struct device_driver sl811h_driver = { .name = (char *) hcd_name, .bus = &platform_bus_type, + .owner = THIS_MODULE, .probe = sl811h_probe, .remove = __devexit_p(sl811h_remove), diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index d33ce3982a5f..15e0a511069b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -831,6 +831,7 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); static struct pci_driver uhci_pci_driver = { .name = (char *)hcd_name, .id_table = uhci_pci_ids, + .owner = THIS_MODULE, .probe = usb_hcd_pci_probe, .remove = usb_hcd_pci_remove, From 3e8a556a02d5aa16375d4d74aad0f67cd844c047 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 18 Oct 2005 10:08:31 -0400 Subject: [PATCH 0872/1940] [PATCH] Missing transfer_flags setting in usbtest This patch (as582) adds a missing transfer_flags setting to the usbtest driver. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index d055196533af..90a96257d6ce 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -983,6 +983,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) reqp->number = i % NUM_SUBCASES; reqp->expected = expected; u->setup_packet = (char *) &reqp->setup; + u->transfer_flags |= URB_NO_SETUP_DMA_MAP; u->context = &context; u->complete = ctrl_complete; From 4592bf5a22593704bb9e8c584a81bf6ca4f6cfec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0873/1940] [PATCH] USB: remove the global function usbdev_lookup_minor It's only used locally. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 34 +++++++++++++++++----------------- drivers/usb/core/usb.h | 1 - 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6c15dabcfc0b..9222b7a13430 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -517,6 +517,23 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig return ret; } +static struct usb_device *usbdev_lookup_minor(int minor) +{ + struct class_device *class_dev; + struct usb_device *dev = NULL; + + down(&usb_device_class->sem); + list_for_each_entry(class_dev, &usb_device_class->children, node) { + if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { + dev = class_dev->class_data; + break; + } + } + up(&usb_device_class->sem); + + return dev; +}; + /* * file operations */ @@ -1533,23 +1550,6 @@ struct file_operations usbfs_device_file_operations = { .release = usbdev_release, }; -struct usb_device *usbdev_lookup_minor(int minor) -{ - struct class_device *class_dev; - struct usb_device *dev = NULL; - - down(&usb_device_class->sem); - list_for_each_entry(class_dev, &usb_device_class->children, node) { - if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { - dev = class_dev->class_data; - break; - } - } - up(&usb_device_class->sem); - - return dev; -}; - void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 4d59f6e07999..3dc8096c0f92 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -64,7 +64,6 @@ extern int usbdev_init(void); extern void usbdev_cleanup(void); extern void usbdev_add(struct usb_device *dev); extern void usbdev_remove(struct usb_device *dev); -extern struct usb_device *usbdev_lookup_minor(int minor); struct dev_state { struct list_head list; /* state list */ From 3099e75a7ccc3c5b0a4cf988a76d9c4a7fa5e91a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0874/1940] [PATCH] USB: add notifier functions to the USB core for devices and busses This should let us get rid of all of the different hooks in the USB core for when something has changed. Also, some other parts of the kernel have wanted to know this kind of information at times. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Makefile | 2 +- drivers/usb/core/hcd.c | 2 + drivers/usb/core/hub.c | 3 + drivers/usb/core/notify.c | 120 ++++++++++++++++++++++++++++++++++++++ drivers/usb/core/usb.h | 6 ++ include/linux/usb.h | 8 +++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/core/notify.c diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index d5503cf0bf74..dd1c4d2a0c31 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -3,7 +3,7 @@ # usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ - config.o file.o buffer.o sysfs.o devio.o + config.o file.o buffer.o sysfs.o devio.o notify.o ifeq ($(CONFIG_PCI),y) usbcore-objs += hcd-pci.o diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9ad3912a5ed7..b700b6cdb683 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -792,6 +792,7 @@ static int usb_register_bus(struct usb_bus *bus) list_add (&bus->bus_list, &usb_bus_list); up (&usb_bus_list_lock); + usb_notify_add_bus(bus); usbfs_add_bus (bus); usbmon_notify_bus_add (bus); @@ -820,6 +821,7 @@ static void usb_deregister_bus (struct usb_bus *bus) list_del (&bus->bus_list); up (&usb_bus_list_lock); + usb_notify_remove_bus(bus); usbmon_notify_bus_remove (bus); usbfs_remove_bus (bus); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 273e6ccca213..4f1a8c8cf92b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1128,6 +1128,8 @@ void usb_disconnect(struct usb_device **pdev) */ usb_disable_device(udev, 0); + usb_notify_remove_device(udev); + /* Free the device number, remove the /proc/bus/usb entry and * the sysfs attributes, and delete the parent's children[] * (or root_hub) pointer. @@ -1371,6 +1373,7 @@ int usb_new_device(struct usb_device *udev) } /* USB device state == configured ... usable */ + usb_notify_add_device(udev); /* add a /proc/bus/usb entry */ usbdev_add(udev); diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c new file mode 100644 index 000000000000..37da059eced7 --- /dev/null +++ b/drivers/usb/core/notify.c @@ -0,0 +1,120 @@ +/* + * All the USB notify logic + * + * (C) Copyright 2005 Greg Kroah-Hartman + * + * notifier functions originally based on those in kernel/sys.c + * but fixed up to not be so broken. + * + */ + + +#include +#include +#include +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif +#include + +#include "usb.h" + + +static struct notifier_block *usb_notifier_list; +static DECLARE_MUTEX(usb_notifier_lock); + +static void usb_notifier_chain_register(struct notifier_block **list, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while (*list) { + if (n->priority > (*list)->priority) + break; + list = &((*list)->next); + } + n->next = *list; + *list = n; + up(&usb_notifier_lock); +} + +static void usb_notifier_chain_unregister(struct notifier_block **nl, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while ((*nl)!=NULL) { + if ((*nl)==n) { + *nl = n->next; + goto exit; + } + nl=&((*nl)->next); + } +exit: + up(&usb_notifier_lock); +} + +static int usb_notifier_call_chain(struct notifier_block **n, + unsigned long val, void *v) +{ + int ret=NOTIFY_DONE; + struct notifier_block *nb = *n; + + down(&usb_notifier_lock); + while (nb) { + ret = nb->notifier_call(nb,val,v); + if (ret&NOTIFY_STOP_MASK) { + goto exit; + } + nb = nb->next; + } +exit: + up(&usb_notifier_lock); + return ret; +} + +/** + * usb_register_notify - register a notifier callback whenever a usb change happens + * @nb: pointer to the notifier block for the callback events. + * + * These changes are either USB devices or busses being added or removed. + */ +void usb_register_notify(struct notifier_block *nb) +{ + usb_notifier_chain_register(&usb_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(usb_register_notify); + +/** + * usb_unregister_notify - unregister a notifier callback + * @nb: pointer to the notifier block for the callback events. + * + * usb_register_notifier() must have been previously called for this function + * to work properly. + */ +void usb_unregister_notify(struct notifier_block *nb) +{ + usb_notifier_chain_unregister(&usb_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(usb_unregister_notify); + + +void usb_notify_add_device(struct usb_device *udev) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); +} + +void usb_notify_remove_device(struct usb_device *udev) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); +} + +void usb_notify_add_bus(struct usb_bus *ubus) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); +} + +void usb_notify_remove_bus(struct usb_bus *ubus) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); +} diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3dc8096c0f92..811cf4482e0d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -80,3 +80,9 @@ struct dev_state { unsigned long ifclaimed; }; +/* internal notify stuff */ +extern void usb_notify_add_device(struct usb_device *udev); +extern void usb_notify_remove_device(struct usb_device *udev); +extern void usb_notify_add_bus(struct usb_bus *ubus); +extern void usb_notify_remove_bus(struct usb_bus *ubus); + diff --git a/include/linux/usb.h b/include/linux/usb.h index 207b1ad9d990..a2d923fd54f9 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1135,6 +1135,14 @@ usb_maxpacket(struct usb_device *udev, int pipe, int is_out) /* -------------------------------------------------------------------------- */ +/* Events from the usb core */ +#define USB_DEVICE_ADD 0x0001 +#define USB_DEVICE_REMOVE 0x0002 +#define USB_BUS_ADD 0x0003 +#define USB_BUS_REMOVE 0x0004 +extern void usb_register_notify(struct notifier_block *nb); +extern void usb_unregister_notify(struct notifier_block *nb); + #ifdef DEBUG #define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg) #else From a7b986b3e107727dd1c1af0ead0b5e52d7726db3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0875/1940] [PATCH] USB: convert usbfs/devio.c to use usb notifiers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 41 +++++++++++++++++++++++++++++++++------- drivers/usb/core/hub.c | 2 -- drivers/usb/core/usb.h | 2 -- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 9222b7a13430..2bd742ba812d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -1550,7 +1551,7 @@ struct file_operations usbfs_device_file_operations = { .release = usbdev_release, }; -void usbdev_add(struct usb_device *dev) +static void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); @@ -1561,11 +1562,29 @@ void usbdev_add(struct usb_device *dev) dev->class_dev->class_data = dev; } -void usbdev_remove(struct usb_device *dev) +static void usbdev_remove(struct usb_device *dev) { class_device_unregister(dev->class_dev); } +static int usbdev_notify(struct notifier_block *self, unsigned long action, + void *dev) +{ + switch (action) { + case USB_DEVICE_ADD: + usbdev_add(dev); + break; + case USB_DEVICE_REMOVE: + usbdev_remove(dev); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block usbdev_nb = { + .notifier_call = usbdev_notify, +}; + static struct cdev usb_device_cdev = { .kobj = {.name = "usb_device", }, .owner = THIS_MODULE, @@ -1585,24 +1604,32 @@ int __init usbdev_init(void) retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); if (retval) { err("unable to get usb_device major %d", USB_DEVICE_MAJOR); - unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); - goto out; + goto error_cdev; } usb_device_class = class_create(THIS_MODULE, "usb_device"); if (IS_ERR(usb_device_class)) { err("unable to register usb_device class"); retval = PTR_ERR(usb_device_class); - usb_device_class = NULL; - cdev_del(&usb_device_cdev); - unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); + goto error_class; } + usb_register_notify(&usbdev_nb); + out: return retval; + +error_class: + usb_device_class = NULL; + cdev_del(&usb_device_cdev); + +error_cdev: + unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); + goto out; } void usbdev_cleanup(void) { + usb_unregister_notify(&usbdev_nb); class_destroy(usb_device_class); cdev_del(&usb_device_cdev); unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4f1a8c8cf92b..a9d16aff5de5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1137,7 +1137,6 @@ void usb_disconnect(struct usb_device **pdev) dev_dbg (&udev->dev, "unregistering device\n"); release_address(udev); usbfs_remove_device(udev); - usbdev_remove(udev); usb_remove_sysfs_dev_files(udev); /* Avoid races with recursively_mark_NOTATTACHED() */ @@ -1376,7 +1375,6 @@ int usb_new_device(struct usb_device *udev) usb_notify_add_device(udev); /* add a /proc/bus/usb entry */ - usbdev_add(udev); usbfs_add_device(udev); return 0; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 811cf4482e0d..888dbe443695 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -62,8 +62,6 @@ extern void usbfs_conn_disc_event(void); extern int usbdev_init(void); extern void usbdev_cleanup(void); -extern void usbdev_add(struct usb_device *dev); -extern void usbdev_remove(struct usb_device *dev); struct dev_state { struct list_head list; /* state list */ From 54a5c4cd2e4ec0b27c2c3731727f52591456086c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0876/1940] [PATCH] USB: convert usbfs/inode.c to use usb notifiers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 2 -- drivers/usb/core/hcd.h | 10 --------- drivers/usb/core/hub.c | 3 --- drivers/usb/core/inode.c | 44 ++++++++++++++++++++++++++++------------ 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index b700b6cdb683..16790ad0e2e4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -793,7 +793,6 @@ static int usb_register_bus(struct usb_bus *bus) up (&usb_bus_list_lock); usb_notify_add_bus(bus); - usbfs_add_bus (bus); usbmon_notify_bus_add (bus); dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); @@ -823,7 +822,6 @@ static void usb_deregister_bus (struct usb_bus *bus) usb_notify_remove_bus(bus); usbmon_notify_bus_remove (bus); - usbfs_remove_bus (bus); clear_bit (bus->busnum, busmap.busmap); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index d8f0d29a45b7..cc33886260cd 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -400,23 +400,13 @@ static inline int hcd_bus_resume (struct usb_bus *bus) * these are expected to be called from the USB core/hub thread * with the kernel lock held */ -extern void usbfs_add_bus(struct usb_bus *bus); -extern void usbfs_remove_bus(struct usb_bus *bus); -extern void usbfs_add_device(struct usb_device *dev); -extern void usbfs_remove_device(struct usb_device *dev); extern void usbfs_update_special (void); - extern int usbfs_init(void); extern void usbfs_cleanup(void); #else /* CONFIG_USB_DEVICEFS */ -static inline void usbfs_add_bus(struct usb_bus *bus) {} -static inline void usbfs_remove_bus(struct usb_bus *bus) {} -static inline void usbfs_add_device(struct usb_device *dev) {} -static inline void usbfs_remove_device(struct usb_device *dev) {} static inline void usbfs_update_special (void) {} - static inline int usbfs_init(void) { return 0; } static inline void usbfs_cleanup(void) { } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a9d16aff5de5..6a2ebd89916f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1136,7 +1136,6 @@ void usb_disconnect(struct usb_device **pdev) */ dev_dbg (&udev->dev, "unregistering device\n"); release_address(udev); - usbfs_remove_device(udev); usb_remove_sysfs_dev_files(udev); /* Avoid races with recursively_mark_NOTATTACHED() */ @@ -1374,8 +1373,6 @@ int usb_new_device(struct usb_device *udev) /* USB device state == configured ... usable */ usb_notify_add_device(udev); - /* add a /proc/bus/usb entry */ - usbfs_add_device(udev); return 0; fail: diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index d07bba01995b..12f490fdee8f 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "usb.h" #include "hcd.h" @@ -619,7 +620,7 @@ void usbfs_update_special (void) } } -void usbfs_add_bus(struct usb_bus *bus) +static void usbfs_add_bus(struct usb_bus *bus) { struct dentry *parent; char name[8]; @@ -642,12 +643,9 @@ void usbfs_add_bus(struct usb_bus *bus) err ("error creating usbfs bus entry"); return; } - - usbfs_update_special(); - usbfs_conn_disc_event(); } -void usbfs_remove_bus(struct usb_bus *bus) +static void usbfs_remove_bus(struct usb_bus *bus) { if (bus->usbfs_dentry) { fs_remove_file (bus->usbfs_dentry); @@ -659,12 +657,9 @@ void usbfs_remove_bus(struct usb_bus *bus) remove_special_files(); num_buses = 0; } - - usbfs_update_special(); - usbfs_conn_disc_event(); } -void usbfs_add_device(struct usb_device *dev) +static void usbfs_add_device(struct usb_device *dev) { char name[8]; int i; @@ -690,12 +685,9 @@ void usbfs_add_device(struct usb_device *dev) } if (dev->usbfs_dentry->d_inode) dev->usbfs_dentry->d_inode->i_size = i_size; - - usbfs_update_special(); - usbfs_conn_disc_event(); } -void usbfs_remove_device(struct usb_device *dev) +static void usbfs_remove_device(struct usb_device *dev) { struct dev_state *ds; struct siginfo sinfo; @@ -716,10 +708,33 @@ void usbfs_remove_device(struct usb_device *dev) kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid); } } +} + +static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) +{ + switch (action) { + case USB_DEVICE_ADD: + usbfs_add_device(dev); + break; + case USB_DEVICE_REMOVE: + usbfs_remove_device(dev); + break; + case USB_BUS_ADD: + usbfs_add_bus(dev); + break; + case USB_BUS_REMOVE: + usbfs_remove_bus(dev); + } + usbfs_update_special(); usbfs_conn_disc_event(); + return NOTIFY_OK; } +static struct notifier_block usbfs_nb = { + .notifier_call = usbfs_notify, +}; + /* --------------------------------------------------------------------- */ static struct proc_dir_entry *usbdir = NULL; @@ -732,6 +747,8 @@ int __init usbfs_init(void) if (retval) return retval; + usb_register_notify(&usbfs_nb); + /* create mount point for usbfs */ usbdir = proc_mkdir("usb", proc_bus); @@ -740,6 +757,7 @@ int __init usbfs_init(void) void usbfs_cleanup(void) { + usb_unregister_notify(&usbfs_nb); unregister_filesystem(&usb_fs_type); if (usbdir) remove_proc_entry("usb", proc_bus); From 72adaa962741e8e910300b66bb123b1a9c31a8a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0877/1940] [PATCH] USB: convert usbmon to use usb notifiers This also removes 2 usbmon callbacks. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 2 -- drivers/usb/core/hcd.h | 16 ---------------- drivers/usb/mon/mon_main.c | 23 +++++++++++++++++++++-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 16790ad0e2e4..e8f2b8d8f14d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -793,7 +793,6 @@ static int usb_register_bus(struct usb_bus *bus) up (&usb_bus_list_lock); usb_notify_add_bus(bus); - usbmon_notify_bus_add (bus); dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); return 0; @@ -821,7 +820,6 @@ static void usb_deregister_bus (struct usb_bus *bus) up (&usb_bus_list_lock); usb_notify_remove_bus(bus); - usbmon_notify_bus_remove (bus); clear_bit (bus->busnum, busmap.busmap); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index cc33886260cd..a5d92943ff95 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -421,8 +421,6 @@ struct usb_mon_operations { void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); void (*urb_complete)(struct usb_bus *bus, struct urb *urb); /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ - void (*bus_add)(struct usb_bus *bus); - void (*bus_remove)(struct usb_bus *bus); }; extern struct usb_mon_operations *mon_ops; @@ -445,18 +443,6 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) if (bus->monitored) (*mon_ops->urb_complete)(bus, urb); } - -static inline void usbmon_notify_bus_add(struct usb_bus *bus) -{ - if (mon_ops) - (*mon_ops->bus_add)(bus); -} - -static inline void usbmon_notify_bus_remove(struct usb_bus *bus) -{ - if (mon_ops) - (*mon_ops->bus_remove)(bus); -} int usb_mon_register(struct usb_mon_operations *ops); void usb_mon_deregister(void); @@ -467,8 +453,6 @@ static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, int error) {} static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} -static inline void usbmon_notify_bus_add(struct usb_bus *bus) {} -static inline void usbmon_notify_bus_remove(struct usb_bus *bus) {} #endif /* CONFIG_USB_MON */ diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 508a21028db4..c34944c75047 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "usb_mon.h" #include "../core/hcd.h" @@ -205,6 +206,23 @@ static void mon_bus_remove(struct usb_bus *ubus) up(&mon_lock); } +static int mon_notify(struct notifier_block *self, unsigned long action, + void *dev) +{ + switch (action) { + case USB_BUS_ADD: + mon_bus_add(dev); + break; + case USB_BUS_REMOVE: + mon_bus_remove(dev); + } + return NOTIFY_OK; +} + +static struct notifier_block mon_nb = { + .notifier_call = mon_notify, +}; + /* * Ops */ @@ -212,8 +230,6 @@ static struct usb_mon_operations mon_ops_0 = { .urb_submit = mon_submit, .urb_submit_error = mon_submit_error, .urb_complete = mon_complete, - .bus_add = mon_bus_add, - .bus_remove = mon_bus_remove, }; /* @@ -329,6 +345,8 @@ static int __init mon_init(void) } // MOD_INC_USE_COUNT(which_module?); + usb_register_notify(&mon_nb); + down(&usb_bus_list_lock); list_for_each_entry (ubus, &usb_bus_list, bus_list) { mon_bus_init(mondir, ubus); @@ -342,6 +360,7 @@ static void __exit mon_exit(void) struct mon_bus *mbus; struct list_head *p; + usb_unregister_notify(&mon_nb); usb_mon_deregister(); down(&mon_lock); From c36fc889b5a4fd66cfd9ba80d9e038745d349567 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Mon, 17 Oct 2005 18:15:54 -0700 Subject: [PATCH 0878/1940] [PATCH] usb: Patch for USBDEVFS_IOCTL from 32-bit programs Dell supplied me with the following test: #include #include #include #include #include main(int argc,char*argv[]) { struct usbdevfs_hub_portinfo hubPortInfo = {0}; struct usbdevfs_ioctl command = {0}; command.ifno = 0; command.ioctl_code = USBDEVFS_HUB_PORTINFO; command.data = (void*)&hubPortInfo; int fd, ret; if(argc != 2) { fprintf(stderr,"Usage: %s /proc/bus/usb//\n",argv[0]); fprintf(stderr,"Example: %s /proc/bus/usb/001/001\n",argv[0]); exit(1); } errno = 0; fd = open(argv[1],O_RDWR); if(fd < 0) { perror("open failed:"); exit(errno); } errno = 0; ret = ioctl(fd,USBDEVFS_IOCTL,&command); printf("IOCTL return status:%d\n",ret); if(ret<0) { perror("IOCTL failed:"); close(fd); exit(3); } else { printf("IOCTL passed:Num of ports %d\n",hubPortInfo.nports); close(fd); exit(0); } return 0; } I have verified that it breaks if built in 32 bit mode on x86_64 and that the patch below fixes it. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 56 +++++++++++++++++++++++++++--------- fs/compat_ioctl.c | 1 + include/linux/usbdevice_fs.h | 7 +++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 2bd742ba812d..ffb2e242b100 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1301,23 +1301,20 @@ static int proc_releaseinterface(struct dev_state *ps, void __user *arg) return 0; } -static int proc_ioctl (struct dev_state *ps, void __user *arg) +static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) { - struct usbdevfs_ioctl ctrl; int size; void *buf = NULL; int retval = 0; struct usb_interface *intf = NULL; struct usb_driver *driver = NULL; - /* get input parameters and alloc buffer */ - if (copy_from_user(&ctrl, arg, sizeof (ctrl))) - return -EFAULT; - if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) { + /* alloc buffer */ + if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) { if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) return -ENOMEM; - if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) { - if (copy_from_user (buf, ctrl.data, size)) { + if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { + if (copy_from_user (buf, ctl->data, size)) { kfree(buf); return -EFAULT; } @@ -1333,9 +1330,9 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) if (ps->dev->state != USB_STATE_CONFIGURED) retval = -EHOSTUNREACH; - else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno))) + else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno))) retval = -EINVAL; - else switch (ctrl.ioctl_code) { + else switch (ctl->ioctl_code) { /* disconnect kernel driver from interface */ case USBDEVFS_DISCONNECT: @@ -1367,7 +1364,7 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) if (driver == NULL || driver->ioctl == NULL) { retval = -ENOTTY; } else { - retval = driver->ioctl (intf, ctrl.ioctl_code, buf); + retval = driver->ioctl (intf, ctl->ioctl_code, buf); if (retval == -ENOIOCTLCMD) retval = -ENOTTY; } @@ -1376,15 +1373,42 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) /* cleanup and return */ if (retval >= 0 - && (_IOC_DIR (ctrl.ioctl_code) & _IOC_READ) != 0 + && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0 && size > 0 - && copy_to_user (ctrl.data, buf, size) != 0) + && copy_to_user (ctl->data, buf, size) != 0) retval = -EFAULT; kfree(buf); return retval; } +static int proc_ioctl_default(struct dev_state *ps, void __user *arg) +{ + struct usbdevfs_ioctl ctrl; + + if (copy_from_user(&ctrl, arg, sizeof (ctrl))) + return -EFAULT; + return proc_ioctl(ps, &ctrl); +} + +#ifdef CONFIG_COMPAT +static int proc_ioctl_compat(struct dev_state *ps, void __user *arg) +{ + struct usbdevfs_ioctl32 __user *uioc; + struct usbdevfs_ioctl ctrl; + u32 udata; + + uioc = compat_ptr(arg); + if (get_user(ctrl.ifno, &uioc->ifno) || + get_user(ctrl.ioctl_code, &uioc->ioctl_code) || + __get_user(udata, &uioc->data)) + return -EFAULT; + ctrl.data = compat_ptr(udata); + + return proc_ioctl(ps, &ctrl); +} +#endif + /* * NOTE: All requests here that have interface numbers as parameters * are assuming that somehow the configuration has been prevented from @@ -1485,6 +1509,10 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ret = proc_reapurbnonblock_compat(ps, p); break; + case USBDEVFS_IOCTL32: + snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); + ret = proc_ioctl_compat(ps, p); + break; #endif case USBDEVFS_DISCARDURB: @@ -1519,7 +1547,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd case USBDEVFS_IOCTL: snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); - ret = proc_ioctl(ps, p); + ret = proc_ioctl_default(ps, p); break; } usb_unlock_device(dev); diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e28a74203f3b..a327e03753ac 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -3050,6 +3050,7 @@ HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) +COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) /* i2c */ HANDLE_IOCTL(I2C_FUNCS, w_long) HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h index 9facf733800c..8859f0b41543 100644 --- a/include/linux/usbdevice_fs.h +++ b/include/linux/usbdevice_fs.h @@ -140,6 +140,12 @@ struct usbdevfs_urb32 { compat_caddr_t usercontext; /* unused */ struct usbdevfs_iso_packet_desc iso_frame_desc[0]; }; + +struct usbdevfs_ioctl32 { + s32 ifno; + s32 ioctl_code; + compat_caddr_t data; +}; #endif #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) @@ -160,6 +166,7 @@ struct usbdevfs_urb32 { #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) #define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl) +#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32) #define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo) #define USBDEVFS_RESET _IO('U', 20) #define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int) From a6c82600d4058346ea6fd801bc21d7abcc1350d8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0879/1940] [PATCH] USB: delete the bluetty driver We have a real Bluetooth system in Linux, lets finally delete this driver as no one is using it (and if they are, they are using a closed source bluetooth stack, which I can't support anyway.) Marcel, you owe me a beer :) Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 - drivers/usb/Makefile | 1 - drivers/usb/class/Kconfig | 23 - drivers/usb/class/Makefile | 1 - drivers/usb/class/bluetty.c | 1279 ----------------------------------- 5 files changed, 1312 deletions(-) delete mode 100644 drivers/usb/class/bluetty.c diff --git a/MAINTAINERS b/MAINTAINERS index 2868b2879755..770155a01523 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2489,14 +2489,6 @@ L: linux-kernel@vger.kernel.org L: linux-usb-devel@lists.sourceforge.net S: Supported -USB BLUETOOTH TTY CONVERTER DRIVER -P: Greg Kroah-Hartman -M: greg@kroah.com -L: linux-usb-users@lists.sourceforge.net -L: linux-usb-devel@lists.sourceforge.net -S: Maintained -W: http://www.kroah.com/linux-usb/ - USB CDC ETHERNET DRIVER P: Greg Kroah-Hartman M: greg@kroah.com diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index aa554f9805ee..a50c2bc506f2 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -18,7 +18,6 @@ obj-$(CONFIG_ETRAX_USB_HOST) += host/ obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_AUDIO) += class/ -obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/ obj-$(CONFIG_USB_MIDI) += class/ obj-$(CONFIG_USB_PRINTER) += class/ diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 333e39bb105f..ef105a92a7bd 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig @@ -28,29 +28,6 @@ config USB_AUDIO To compile this driver as a module, choose M here: the module will be called audio. -comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem" - depends on USB && BT - -config USB_BLUETOOTH_TTY - tristate "USB Bluetooth TTY support" - depends on USB && BT=n - ---help--- - This driver implements a nonstandard tty interface to a Bluetooth - device that can be used only by specialized Bluetooth HCI software. - - Say Y here if you want to use OpenBT Bluetooth stack (available - at ), or other TTY based - Bluetooth stacks, and want to connect a USB Bluetooth device - to your computer's USB port. - - Do *not* enable this driver if you want to use generic Linux - Bluetooth support. - - If in doubt, say N here. - - To compile this driver as a module, choose M here: the - module will be called bluetty. - config USB_MIDI tristate "USB MIDI support" depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index 971e5497a3fd..229471247751 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile @@ -5,6 +5,5 @@ obj-$(CONFIG_USB_ACM) += cdc-acm.o obj-$(CONFIG_USB_AUDIO) += audio.o -obj-$(CONFIG_USB_BLUETOOTH_TTY) += bluetty.o obj-$(CONFIG_USB_MIDI) += usb-midi.o obj-$(CONFIG_USB_PRINTER) += usblp.o diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c deleted file mode 100644 index 524023327c49..000000000000 --- a/drivers/usb/class/bluetty.c +++ /dev/null @@ -1,1279 +0,0 @@ -/* - * bluetty.c Version 0.13 - * - * Copyright (C) 2000, 2001 Greg Kroah-Hartman - * Copyright (C) 2000 Mark Douglas Corner - * - * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B - * - * (2001/11/30) Version 0.13 gkh - * - added locking patch from Masoodur Rahman - * - removed active variable, as open_count will do. - * - * (2001/07/09) Version 0.12 gkh - * - removed in_interrupt() call, as it doesn't make sense to do - * that anymore. - * - * (2001/06/05) Version 0.11 gkh - * - Fixed problem with read urb status saying that we have shutdown, - * and that we shouldn't resubmit the urb. Patch from unknown. - * - * (2001/05/28) Version 0.10 gkh - * - Fixed problem with using data from userspace in the bluetooth_write - * function as found by the CHECKER project. - * - Added a buffer to the write_urb_pool which reduces the number of - * buffers being created and destroyed for ever write. Also cleans - * up the logic a bit. - * - Added a buffer to the control_urb_pool which fixes a memory leak - * when the device is removed from the system. - * - * (2001/05/28) Version 0.9 gkh - * Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback - * which was found by both the CHECKER project and Mikko Rahkonen. - * - * (08/04/2001) gb - * Identify version on module load. - * - * (2001/03/10) Version 0.8 gkh - * Fixed problem with not unlinking interrupt urb on device close - * and resubmitting the read urb on error with bluetooth struct. - * Thanks to Narayan Mohanram for the - * fixes. - * - * (11/29/2000) Version 0.7 gkh - * Fixed problem with overrunning the tty flip buffer. - * Removed unneeded NULL pointer initialization. - * - * (10/05/2000) Version 0.6 gkh - * Fixed bug with urb->dev not being set properly, now that the usb - * core needs it. - * Got a real major id number and name. - * - * (08/06/2000) Version 0.5 gkh - * Fixed problem of not resubmitting the bulk read urb if there is - * an error in the callback. Ericsson devices seem to need this. - * - * (07/11/2000) Version 0.4 gkh - * Fixed bug in disconnect for when we call tty_hangup - * Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not - * getting attached to the control urb properly. - * Fixed bug in bluetooth_write where we pay attention to the result - * of bluetooth_ctrl_msg. - * - * (08/03/2000) Version 0.3 gkh mdc - * Merged in Mark's changes to make the driver play nice with the Axis - * stack. - * Made the write bulk use an urb pool to enable larger transfers with - * fewer calls to the driver. - * Fixed off by one bug in acl pkt receive - * Made packet counters specific to each bluetooth device - * Added checks for zero length callbacks - * Added buffers for int and bulk packets. Had to do this otherwise - * packet types could intermingle. - * Made a control urb pool for the control messages. - * - * (07/11/2000) Version 0.2 gkh - * Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe - * function. - * - * (07/09/2000) Version 0.1 gkh - * Initial release. Has support for sending ACL data (which is really just - * a HCI frame.) Raw HCI commands and HCI events are not supported. - * A ioctl will probably be needed for the HCI commands and events in the - * future. All isoch endpoints are ignored at this time also. - * This driver should work for all currently shipping USB Bluetooth - * devices at this time :) - * - */ - -/* - * 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG -#include - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.13" -#define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner" -#define DRIVER_DESC "USB Bluetooth tty driver" - -/* define this if you have hardware that is not good */ -/*#define BTBUGGYHARDWARE */ - -/* Class, SubClass, and Protocol codes that describe a Bluetooth device */ -#define WIRELESS_CLASS_CODE 0xe0 -#define RF_SUBCLASS_CODE 0x01 -#define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE 0x01 - - -#define BLUETOOTH_TTY_MAJOR 216 /* real device node major id */ -#define BLUETOOTH_TTY_MINORS 256 /* whole lotta bluetooth devices */ - -#define USB_BLUETOOTH_MAGIC 0x6d02 /* magic number for bluetooth struct */ - -#define BLUETOOTH_CONTROL_REQUEST_TYPE 0x20 - -/* Bluetooth packet types */ -#define CMD_PKT 0x01 -#define ACL_PKT 0x02 -#define SCO_PKT 0x03 -#define EVENT_PKT 0x04 -#define ERROR_PKT 0x05 -#define NEG_PKT 0x06 - -/* Message sizes */ -#define MAX_EVENT_SIZE 0xFF -#define EVENT_HDR_SIZE 3 /* 2 for the header + 1 for the type indicator */ -#define EVENT_BUFFER_SIZE (MAX_EVENT_SIZE + EVENT_HDR_SIZE) - -#define MAX_ACL_SIZE 0xFFFF -#define ACL_HDR_SIZE 5 /* 4 for the header + 1 for the type indicator */ -#define ACL_BUFFER_SIZE (MAX_ACL_SIZE + ACL_HDR_SIZE) - -/* parity check flag */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - -#define CHAR2INT16(c1,c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff)) - -#define NUM_BULK_URBS 24 -#define NUM_CONTROL_URBS 16 - -struct usb_bluetooth { - int magic; - struct usb_device * dev; - struct tty_driver * tty_driver; /* the tty_driver for this device */ - struct tty_struct * tty; /* the corresponding tty for this port */ - - unsigned char minor; /* the starting minor number for this device */ - int throttle; /* throttled by tty layer */ - int open_count; - - __u8 control_out_bInterfaceNum; - struct urb * control_urb_pool[NUM_CONTROL_URBS]; - struct usb_ctrlrequest dr[NUM_CONTROL_URBS]; - - unsigned char * interrupt_in_buffer; - struct urb * interrupt_in_urb; - __u8 interrupt_in_endpointAddress; - __u8 interrupt_in_interval; - int interrupt_in_buffer_size; - - unsigned char * bulk_in_buffer; - struct urb * read_urb; - __u8 bulk_in_endpointAddress; - int bulk_in_buffer_size; - - int bulk_out_buffer_size; - __u8 bulk_out_endpointAddress; - - wait_queue_head_t write_wait; - - struct work_struct work; /* work queue entry for line discipline waking up */ - - unsigned int int_packet_pos; - unsigned char int_buffer[EVENT_BUFFER_SIZE]; - unsigned int bulk_packet_pos; - unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */ - struct semaphore lock; -}; - - -/* local function prototypes */ -static int bluetooth_open (struct tty_struct *tty, struct file *filp); -static void bluetooth_close (struct tty_struct *tty, struct file *filp); -static int bluetooth_write (struct tty_struct *tty, const unsigned char *buf, int count); -static int bluetooth_write_room (struct tty_struct *tty); -static int bluetooth_chars_in_buffer (struct tty_struct *tty); -static void bluetooth_throttle (struct tty_struct *tty); -static void bluetooth_unthrottle (struct tty_struct *tty); -static int bluetooth_ioctl (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -static void bluetooth_set_termios (struct tty_struct *tty, struct termios *old); - -static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs); -static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs); -static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs); -static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs); - -static int usb_bluetooth_probe (struct usb_interface *intf, - const struct usb_device_id *id); -static void usb_bluetooth_disconnect (struct usb_interface *intf); - - -static struct usb_device_id usb_bluetooth_ids [] = { - { USB_DEVICE_INFO(WIRELESS_CLASS_CODE, RF_SUBCLASS_CODE, BLUETOOTH_PROGRAMMING_PROTOCOL_CODE) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids); - -static struct usb_driver usb_bluetooth_driver = { - .owner = THIS_MODULE, - .name = "bluetty", - .probe = usb_bluetooth_probe, - .disconnect = usb_bluetooth_disconnect, - .id_table = usb_bluetooth_ids, -}; - -static struct tty_driver *bluetooth_tty_driver; -static struct usb_bluetooth *bluetooth_table[BLUETOOTH_TTY_MINORS]; - - -static inline int bluetooth_paranoia_check (struct usb_bluetooth *bluetooth, const char *function) -{ - if (!bluetooth) { - dbg("%s - bluetooth == NULL", function); - return -1; - } - if (bluetooth->magic != USB_BLUETOOTH_MAGIC) { - dbg("%s - bad magic number for bluetooth", function); - return -1; - } - - return 0; -} - - -static inline struct usb_bluetooth* get_usb_bluetooth (struct usb_bluetooth *bluetooth, const char *function) -{ - if (!bluetooth || - bluetooth_paranoia_check (bluetooth, function)) { - /* then say that we don't have a valid usb_bluetooth thing, which will - * end up generating -ENODEV return values */ - return NULL; - } - - return bluetooth; -} - - -static inline struct usb_bluetooth *get_bluetooth_by_index (int index) -{ - return bluetooth_table[index]; -} - - -static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, const unsigned char *buf, int len) -{ - struct urb *urb = NULL; - struct usb_ctrlrequest *dr = NULL; - int i; - int status; - - dbg ("%s", __FUNCTION__); - - /* try to find a free urb in our list */ - for (i = 0; i < NUM_CONTROL_URBS; ++i) { - if (bluetooth->control_urb_pool[i]->status != -EINPROGRESS) { - urb = bluetooth->control_urb_pool[i]; - dr = &bluetooth->dr[i]; - break; - } - } - if (urb == NULL) { - dbg ("%s - no free urbs", __FUNCTION__); - return -ENOMEM; - } - - /* keep increasing the urb transfer buffer to fit the size of the message */ - if (urb->transfer_buffer == NULL) { - urb->transfer_buffer = kmalloc (len, GFP_KERNEL); - if (urb->transfer_buffer == NULL) { - err ("%s - out of memory", __FUNCTION__); - return -ENOMEM; - } - } - if (urb->transfer_buffer_length < len) { - kfree(urb->transfer_buffer); - urb->transfer_buffer = kmalloc (len, GFP_KERNEL); - if (urb->transfer_buffer == NULL) { - err ("%s - out of memory", __FUNCTION__); - return -ENOMEM; - } - } - memcpy (urb->transfer_buffer, buf, len); - - dr->bRequestType= BLUETOOTH_CONTROL_REQUEST_TYPE; - dr->bRequest = request; - dr->wValue = cpu_to_le16((u16) value); - dr->wIndex = cpu_to_le16((u16) bluetooth->control_out_bInterfaceNum); - dr->wLength = cpu_to_le16((u16) len); - - usb_fill_control_urb (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0), - (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth); - - /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) - dbg("%s - usb_submit_urb(control) failed with status = %d", __FUNCTION__, status); - - return status; -} - - - - - -/***************************************************************************** - * Driver tty interface functions - *****************************************************************************/ -static int bluetooth_open (struct tty_struct *tty, struct file * filp) -{ - struct usb_bluetooth *bluetooth; - int result; - - dbg("%s", __FUNCTION__); - - /* initialize the pointer incase something fails */ - tty->driver_data = NULL; - - /* get the bluetooth object associated with this tty pointer */ - bluetooth = get_bluetooth_by_index (tty->index); - - if (bluetooth_paranoia_check (bluetooth, __FUNCTION__)) { - return -ENODEV; - } - - down (&bluetooth->lock); - - ++bluetooth->open_count; - if (bluetooth->open_count == 1) { - /* set up our structure making the tty driver remember our object, and us it */ - tty->driver_data = bluetooth; - bluetooth->tty = tty; - - /* force low_latency on so that our tty_push actually forces the data through, - * otherwise it is scheduled, and with high data rates (like with OHCI) data - * can get lost. */ - bluetooth->tty->low_latency = 1; - - /* Reset the packet position counters */ - bluetooth->int_packet_pos = 0; - bluetooth->bulk_packet_pos = 0; - -#ifndef BTBUGGYHARDWARE - /* Start reading from the device */ - usb_fill_bulk_urb (bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, - bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); - if (result) - dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result); -#endif - usb_fill_int_urb (bluetooth->interrupt_in_urb, bluetooth->dev, - usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), - bluetooth->interrupt_in_buffer, - bluetooth->interrupt_in_buffer_size, - bluetooth_int_callback, bluetooth, - bluetooth->interrupt_in_interval); - result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL); - if (result) - dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result); - } - - up(&bluetooth->lock); - - return 0; -} - - -static void bluetooth_close (struct tty_struct *tty, struct file * filp) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not opened", __FUNCTION__); - return; - } - - down (&bluetooth->lock); - - --bluetooth->open_count; - if (bluetooth->open_count <= 0) { - bluetooth->open_count = 0; - - /* shutdown any in-flight urbs that we know about */ - usb_kill_urb (bluetooth->read_urb); - usb_kill_urb (bluetooth->interrupt_in_urb); - } - up(&bluetooth->lock); -} - - -static int bluetooth_write (struct tty_struct * tty, const unsigned char *buf, int count) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - struct urb *urb = NULL; - unsigned char *temp_buffer = NULL; - const unsigned char *current_buffer; - unsigned char *urb_buffer; - int i; - int retval = 0; - - if (!bluetooth) { - return -ENODEV; - } - - dbg("%s - %d byte(s)", __FUNCTION__, count); - - if (!bluetooth->open_count) { - dbg ("%s - device not opened", __FUNCTION__); - return -EINVAL; - } - - if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); - return 0; - } - if (count == 1) { - dbg("%s - write request only included type %d", __FUNCTION__, buf[0]); - return 1; - } - -#ifdef DEBUG - printk (KERN_DEBUG __FILE__ ": %s - length = %d, data = ", __FUNCTION__, count); - for (i = 0; i < count; ++i) { - printk ("%.2x ", buf[i]); - } - printk ("\n"); -#endif - - current_buffer = buf; - - switch (*current_buffer) { - /* First byte indicates the type of packet */ - case CMD_PKT: - /* dbg("%s- Send cmd_pkt len:%d", __FUNCTION__, count);*/ - - retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, ¤t_buffer[1], count-1); - if (retval) { - goto exit; - } - retval = count; - break; - - case ACL_PKT: - ++current_buffer; - --count; - - urb_buffer = kmalloc (count, GFP_ATOMIC); - if (!urb_buffer) { - dev_err(&bluetooth->dev->dev, "out of memory\n"); - retval = -ENOMEM; - goto exit; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&bluetooth->dev->dev, "no more free urbs\n"); - kfree(urb_buffer); - retval = -ENOMEM; - goto exit; - } - memcpy (urb_buffer, current_buffer, count); - - /* build up our urb */ - usb_fill_bulk_urb(urb, bluetooth->dev, - usb_sndbulkpipe(bluetooth->dev, - bluetooth->bulk_out_endpointAddress), - urb_buffer, - count, - bluetooth_write_bulk_callback, - bluetooth); - - - /* send it down the pipe */ - retval = usb_submit_urb(urb, GFP_KERNEL); - if (retval) { - dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, retval); - goto exit; - } - - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ - usb_free_urb (urb); - retval = count + 1; - break; - - default : - dbg("%s - unsupported (at this time) write type", __FUNCTION__); - retval = -EINVAL; - break; - } - -exit: - kfree(temp_buffer); - - return retval; -} - - -static int bluetooth_write_room (struct tty_struct *tty) -{ - dbg("%s", __FUNCTION__); - - /* - * We really can take anything the user throws at us - * but let's pick a nice big number to tell the tty - * layer that we have lots of free space - */ - return 2048; -} - - -static int bluetooth_chars_in_buffer (struct tty_struct *tty) -{ - dbg("%s", __FUNCTION__); - - /* - * We can't really account for how much data we - * have sent out, but hasn't made it through to the - * device, so just tell the tty layer that everything - * is flushed. - */ - return 0; -} - - -static void bluetooth_throttle (struct tty_struct * tty) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return; - } - - dbg("%s unsupported (at this time)", __FUNCTION__); - - return; -} - - -static void bluetooth_unthrottle (struct tty_struct * tty) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return; - } - - dbg("%s unsupported (at this time)", __FUNCTION__); -} - - -static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return -ENODEV; - } - - dbg("%s - cmd 0x%.4x", __FUNCTION__, cmd); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return -ENODEV; - } - - /* FIXME!!! */ - return -ENOIOCTLCMD; -} - - -static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return; - } - - /* FIXME!!! */ - - return; -} - - -#ifdef BTBUGGYHARDWARE -void btusb_enable_bulk_read(struct tty_struct *tty){ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - int result; - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return; - } - - if (bluetooth->read_urb) { - usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); - if (result) - err ("%s - failed submitting read urb, error %d", __FUNCTION__, result); - } -} - -void btusb_disable_bulk_read(struct tty_struct *tty){ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); - - if (!bluetooth) { - return; - } - - dbg("%s", __FUNCTION__); - - if (!bluetooth->open_count) { - dbg ("%s - device not open", __FUNCTION__); - return; - } - - if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length)) - usb_kill_urb(bluetooth->read_urb); -} -#endif - - -/***************************************************************************** - * urb callback functions - *****************************************************************************/ - - -static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); - unsigned char *data = urb->transfer_buffer; - unsigned int i; - unsigned int count = urb->actual_length; - unsigned int packet_size; - int status; - - dbg("%s", __FUNCTION__); - - if (!bluetooth) { - dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); - return; - } - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (!count) { - dbg("%s - zero length int", __FUNCTION__); - goto exit; - } - - -#ifdef DEBUG - if (count) { - printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count); - for (i = 0; i < count; ++i) { - printk ("%.2x ", data[i]); - } - printk ("\n"); - } -#endif - -#ifdef BTBUGGYHARDWARE - if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) { - data += 2; - count -= 2; - } - if (count == 0) { - urb->actual_length = 0; - goto exit; - } -#endif - /* We add a packet type identifier to the beginning of each - HCI frame. This makes the data in the tty look like a - serial USB devices. Each HCI frame can be broken across - multiple URBs so we buffer them until we have a full hci - packet */ - - if (!bluetooth->int_packet_pos) { - bluetooth->int_buffer[0] = EVENT_PKT; - bluetooth->int_packet_pos++; - } - - if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) { - err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__); - bluetooth->int_packet_pos = 0; - goto exit; - } - - memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos], - urb->transfer_buffer, count); - bluetooth->int_packet_pos += count; - urb->actual_length = 0; - - if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE) - packet_size = bluetooth->int_buffer[2]; - else - goto exit; - - if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) { - err("%s - packet was too long", __FUNCTION__); - bluetooth->int_packet_pos = 0; - goto exit; - } - - if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) { - for (i = 0; i < bluetooth->int_packet_pos; ++i) { - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them */ - if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(bluetooth->tty); - } - tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0); - } - tty_flip_buffer_push(bluetooth->tty); - - bluetooth->int_packet_pos = 0; - } - -exit: - status = usb_submit_urb (urb, GFP_ATOMIC); - if (status) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, status); -} - - -static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); - - dbg("%s", __FUNCTION__); - - if (!bluetooth) { - dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); - return; - } - - if (urb->status) { - dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); - return; - } -} - - -static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); - unsigned char *data = urb->transfer_buffer; - unsigned int count = urb->actual_length; - unsigned int i; - unsigned int packet_size; - int result; - - - dbg("%s", __FUNCTION__); - - if (!bluetooth) { - dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); - return; - } - - if (urb->status) { - dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); - if (urb->status == -ENOENT) { - dbg("%s - URB canceled, won't reschedule", __FUNCTION__); - return; - } - goto exit; - } - - if (!count) { - dbg("%s - zero length read bulk", __FUNCTION__); - goto exit; - } - -#ifdef DEBUG - if (count) { - printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count); - for (i = 0; i < count; ++i) { - printk ("%.2x ", data[i]); - } - printk ("\n"); - } -#endif -#ifdef BTBUGGYHARDWARE - if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00) - && (data[2] == 0x00) && (data[3] == 0x00)) { - urb->actual_length = 0; - usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); - if (result) - err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); - - return; - } -#endif - /* We add a packet type identifier to the beginning of each - HCI frame. This makes the data in the tty look like a - serial USB devices. Each HCI frame can be broken across - multiple URBs so we buffer them until we have a full hci - packet */ - - if (!bluetooth->bulk_packet_pos) { - bluetooth->bulk_buffer[0] = ACL_PKT; - bluetooth->bulk_packet_pos++; - } - - if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) { - err("%s - exceeded ACL_BUFFER_SIZE", __FUNCTION__); - bluetooth->bulk_packet_pos = 0; - goto exit; - } - - memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos], - urb->transfer_buffer, count); - bluetooth->bulk_packet_pos += count; - urb->actual_length = 0; - - if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) { - packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]); - } else { - goto exit; - } - - if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) { - err("%s - packet was too long", __FUNCTION__); - bluetooth->bulk_packet_pos = 0; - goto exit; - } - - if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) { - for (i = 0; i < bluetooth->bulk_packet_pos; ++i) { - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ - if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(bluetooth->tty); - } - tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0); - } - tty_flip_buffer_push(bluetooth->tty); - bluetooth->bulk_packet_pos = 0; - } - -exit: - if (!bluetooth || !bluetooth->open_count) - return; - - usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); - if (result) - err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); - - return; -} - - -static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); - - dbg("%s", __FUNCTION__); - - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); - - if (!bluetooth) { - dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); - return; - } - - if (urb->status) { - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); - return; - } - - /* wake up our little function to let the tty layer know that something happened */ - schedule_work(&bluetooth->work); -} - - -static void bluetooth_softint(void *private) -{ - struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__); - - dbg("%s", __FUNCTION__); - - if (!bluetooth) - return; - - tty_wakeup(bluetooth->tty); -} - - -static int usb_bluetooth_probe (struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev (intf); - struct usb_bluetooth *bluetooth = NULL; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_endpoint_descriptor *interrupt_in_endpoint[8]; - struct usb_endpoint_descriptor *bulk_in_endpoint[8]; - struct usb_endpoint_descriptor *bulk_out_endpoint[8]; - int control_out_endpoint; - - int minor; - int buffer_size; - int i; - int num_interrupt_in = 0; - int num_bulk_in = 0; - int num_bulk_out = 0; - - interface = intf->cur_altsetting; - control_out_endpoint = interface->desc.bInterfaceNumber; - - /* find the endpoints that we need */ - for (i = 0; i < interface->desc.bNumEndpoints; ++i) { - endpoint = &interface->endpoint[i].desc; - - if ((endpoint->bEndpointAddress & 0x80) && - ((endpoint->bmAttributes & 3) == 0x02)) { - /* we found a bulk in endpoint */ - dbg("found bulk in"); - bulk_in_endpoint[num_bulk_in] = endpoint; - ++num_bulk_in; - } - - if (((endpoint->bEndpointAddress & 0x80) == 0x00) && - ((endpoint->bmAttributes & 3) == 0x02)) { - /* we found a bulk out endpoint */ - dbg("found bulk out"); - bulk_out_endpoint[num_bulk_out] = endpoint; - ++num_bulk_out; - } - - if ((endpoint->bEndpointAddress & 0x80) && - ((endpoint->bmAttributes & 3) == 0x03)) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in"); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; - } - } - - /* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */ - if ((num_bulk_in != 1) || - (num_bulk_out != 1) || - (num_interrupt_in != 1)) { - dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__); - return -EIO; - } - - info("USB Bluetooth converter detected"); - - for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor) - ; - if (bluetooth_table[minor]) { - err("No more free Bluetooth devices"); - return -ENODEV; - } - - if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) { - err("Out of memory"); - return -ENOMEM; - } - - memset(bluetooth, 0, sizeof(struct usb_bluetooth)); - - bluetooth->magic = USB_BLUETOOTH_MAGIC; - bluetooth->dev = dev; - bluetooth->minor = minor; - INIT_WORK(&bluetooth->work, bluetooth_softint, bluetooth); - init_MUTEX(&bluetooth->lock); - - /* record the interface number for the control out */ - bluetooth->control_out_bInterfaceNum = control_out_endpoint; - - /* create our control out urb pool */ - for (i = 0; i < NUM_CONTROL_URBS; ++i) { - struct urb *urb = usb_alloc_urb(0, GFP_KERNEL); - if (urb == NULL) { - err("No free urbs available"); - goto probe_error; - } - urb->transfer_buffer = NULL; - bluetooth->control_urb_pool[i] = urb; - } - - /* set up the endpoint information */ - endpoint = bulk_in_endpoint[0]; - bluetooth->read_urb = usb_alloc_urb (0, GFP_KERNEL); - if (!bluetooth->read_urb) { - err("No free urbs available"); - goto probe_error; - } - bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress; - bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); - if (!bluetooth->bulk_in_buffer) { - err("Couldn't allocate bulk_in_buffer"); - goto probe_error; - } - usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), - bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth); - - endpoint = bulk_out_endpoint[0]; - bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress; - bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; - - endpoint = interrupt_in_endpoint[0]; - bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!bluetooth->interrupt_in_urb) { - err("No free urbs available"); - goto probe_error; - } - bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress; - bluetooth->interrupt_in_interval = endpoint->bInterval; - bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); - if (!bluetooth->interrupt_in_buffer) { - err("Couldn't allocate interrupt_in_buffer"); - goto probe_error; - } - usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), - bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback, - bluetooth, endpoint->bInterval); - - /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */ - tty_register_device (bluetooth_tty_driver, minor, &intf->dev); - info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor); - - bluetooth_table[minor] = bluetooth; - - /* success */ - usb_set_intfdata (intf, bluetooth); - return 0; - -probe_error: - if (bluetooth->read_urb) - usb_free_urb (bluetooth->read_urb); - if (bluetooth->bulk_in_buffer) - kfree (bluetooth->bulk_in_buffer); - if (bluetooth->interrupt_in_urb) - usb_free_urb (bluetooth->interrupt_in_urb); - if (bluetooth->interrupt_in_buffer) - kfree (bluetooth->interrupt_in_buffer); - for (i = 0; i < NUM_CONTROL_URBS; ++i) - if (bluetooth->control_urb_pool[i]) { - if (bluetooth->control_urb_pool[i]->transfer_buffer) - kfree (bluetooth->control_urb_pool[i]->transfer_buffer); - usb_free_urb (bluetooth->control_urb_pool[i]); - } - - bluetooth_table[minor] = NULL; - - /* free up any memory that we allocated */ - kfree (bluetooth); - return -EIO; -} - - -static void usb_bluetooth_disconnect(struct usb_interface *intf) -{ - struct usb_bluetooth *bluetooth = usb_get_intfdata (intf); - int i; - - usb_set_intfdata (intf, NULL); - if (bluetooth) { - if ((bluetooth->open_count) && (bluetooth->tty)) - tty_hangup(bluetooth->tty); - - bluetooth->open_count = 0; - - if (bluetooth->read_urb) { - usb_kill_urb (bluetooth->read_urb); - usb_free_urb (bluetooth->read_urb); - } - if (bluetooth->bulk_in_buffer) - kfree (bluetooth->bulk_in_buffer); - - if (bluetooth->interrupt_in_urb) { - usb_kill_urb (bluetooth->interrupt_in_urb); - usb_free_urb (bluetooth->interrupt_in_urb); - } - if (bluetooth->interrupt_in_buffer) - kfree (bluetooth->interrupt_in_buffer); - - tty_unregister_device (bluetooth_tty_driver, bluetooth->minor); - - for (i = 0; i < NUM_CONTROL_URBS; ++i) { - if (bluetooth->control_urb_pool[i]) { - usb_kill_urb (bluetooth->control_urb_pool[i]); - if (bluetooth->control_urb_pool[i]->transfer_buffer) - kfree (bluetooth->control_urb_pool[i]->transfer_buffer); - usb_free_urb (bluetooth->control_urb_pool[i]); - } - } - - info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor); - - bluetooth_table[bluetooth->minor] = NULL; - - /* free up any memory that we allocated */ - kfree (bluetooth); - } else { - info("device disconnected"); - } -} - -static struct tty_operations bluetooth_ops = { - .open = bluetooth_open, - .close = bluetooth_close, - .write = bluetooth_write, - .write_room = bluetooth_write_room, - .ioctl = bluetooth_ioctl, - .set_termios = bluetooth_set_termios, - .throttle = bluetooth_throttle, - .unthrottle = bluetooth_unthrottle, - .chars_in_buffer = bluetooth_chars_in_buffer, -}; - -static int usb_bluetooth_init(void) -{ - int i; - int result; - - /* Initialize our global data */ - for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) { - bluetooth_table[i] = NULL; - } - - info ("USB Bluetooth support registered"); - - bluetooth_tty_driver = alloc_tty_driver(BLUETOOTH_TTY_MINORS); - if (!bluetooth_tty_driver) - return -ENOMEM; - - bluetooth_tty_driver->owner = THIS_MODULE; - bluetooth_tty_driver->driver_name = "usb-bluetooth"; - bluetooth_tty_driver->name = "ttyUB"; - bluetooth_tty_driver->devfs_name = "usb/ttub/"; - bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR; - bluetooth_tty_driver->minor_start = 0; - bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - bluetooth_tty_driver->subtype = SERIAL_TYPE_NORMAL; - bluetooth_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; - bluetooth_tty_driver->init_termios = tty_std_termios; - bluetooth_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty_set_operations(bluetooth_tty_driver, &bluetooth_ops); - if (tty_register_driver (bluetooth_tty_driver)) { - err("%s - failed to register tty driver", __FUNCTION__); - put_tty_driver(bluetooth_tty_driver); - return -1; - } - - /* register the USB driver */ - result = usb_register(&usb_bluetooth_driver); - if (result < 0) { - tty_unregister_driver(bluetooth_tty_driver); - put_tty_driver(bluetooth_tty_driver); - err("usb_register failed for the USB bluetooth driver. Error number %d", result); - return -1; - } - - info(DRIVER_DESC " " DRIVER_VERSION); - - return 0; -} - - -static void usb_bluetooth_exit(void) -{ - usb_deregister(&usb_bluetooth_driver); - tty_unregister_driver(bluetooth_tty_driver); - put_tty_driver(bluetooth_tty_driver); -} - - -module_init(usb_bluetooth_init); -module_exit(usb_bluetooth_exit); - -/* Module information */ -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_LICENSE("GPL"); - From ea65370d025f5005649e5cb37c4d025e92c6fc38 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0880/1940] [PATCH] USB Serial: rename usb_serial_device_type to usb_serial_driver I'm tired of trying to explain why a "device_type" is really a driver. This better describes exactly what this structure is. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 2 +- drivers/usb/serial/belkin_sa.c | 2 +- drivers/usb/serial/bus.c | 28 ++++++++++++------------- drivers/usb/serial/cp2101.c | 2 +- drivers/usb/serial/cyberjack.c | 2 +- drivers/usb/serial/cypress_m8.c | 4 ++-- drivers/usb/serial/digi_acceleport.c | 4 ++-- drivers/usb/serial/empeg.c | 2 +- drivers/usb/serial/ftdi_sio.c | 2 +- drivers/usb/serial/garmin_gps.c | 7 +------ drivers/usb/serial/generic.c | 2 +- drivers/usb/serial/hp4x.c | 2 +- drivers/usb/serial/io_tables.h | 6 +++--- drivers/usb/serial/io_ti.c | 4 ++-- drivers/usb/serial/ipaq.c | 2 +- drivers/usb/serial/ipw.c | 2 +- drivers/usb/serial/ir-usb.c | 2 +- drivers/usb/serial/keyspan.h | 8 +++---- drivers/usb/serial/keyspan_pda.c | 6 +++--- drivers/usb/serial/kl5kusb105.c | 2 +- drivers/usb/serial/kobil_sct.c | 2 +- drivers/usb/serial/mct_u232.c | 2 +- drivers/usb/serial/omninet.c | 2 +- drivers/usb/serial/option.c | 2 +- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/safe_serial.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 4 ++-- drivers/usb/serial/usb-serial.c | 30 +++++++++++++-------------- drivers/usb/serial/usb-serial.h | 28 ++++++++++++------------- drivers/usb/serial/visor.c | 6 +++--- drivers/usb/serial/whiteheat.c | 4 ++-- 31 files changed, 85 insertions(+), 90 deletions(-) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 926d4c2c1600..104c04385bb9 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -30,7 +30,7 @@ static struct usb_driver airprime_driver = { .id_table = id_table, }; -static struct usb_serial_device_type airprime_device = { +static struct usb_serial_driver airprime_device = { .owner = THIS_MODULE, .name = "airprime", .id_table = id_table, diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index abb1b2c543bb..6d84de40cb7b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -121,7 +121,7 @@ static struct usb_driver belkin_driver = { }; /* All of the device info needed for the serial converters */ -static struct usb_serial_device_type belkin_device = { +static struct usb_serial_driver belkin_device = { .owner = THIS_MODULE, .name = "Belkin / Peracom / GoHubs USB Serial Adapter", .short_name = "belkin", diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 2f612c2d894b..5a0bcd34bb6d 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -18,7 +18,7 @@ static int usb_serial_device_match (struct device *dev, struct device_driver *drv) { - struct usb_serial_device_type *driver; + struct usb_serial_driver *driver; const struct usb_serial_port *port; /* @@ -44,7 +44,7 @@ struct bus_type usb_serial_bus_type = { static int usb_serial_device_probe (struct device *dev) { - struct usb_serial_device_type *driver; + struct usb_serial_driver *driver; struct usb_serial_port *port; int retval = 0; int minor; @@ -80,7 +80,7 @@ static int usb_serial_device_probe (struct device *dev) static int usb_serial_device_remove (struct device *dev) { - struct usb_serial_device_type *driver; + struct usb_serial_driver *driver; struct usb_serial_port *port; int retval = 0; int minor; @@ -109,26 +109,26 @@ static int usb_serial_device_remove (struct device *dev) return retval; } -int usb_serial_bus_register(struct usb_serial_device_type *device) +int usb_serial_bus_register(struct usb_serial_driver *driver) { int retval; - if (device->short_name) - device->driver.name = (char *)device->short_name; + if (driver->short_name) + driver->driver.name = (char *)driver->short_name; else - device->driver.name = (char *)device->name; - device->driver.bus = &usb_serial_bus_type; - device->driver.probe = usb_serial_device_probe; - device->driver.remove = usb_serial_device_remove; - device->driver.owner = device->owner; + driver->driver.name = (char *)driver->name; + driver->driver.bus = &usb_serial_bus_type; + driver->driver.probe = usb_serial_device_probe; + driver->driver.remove = usb_serial_device_remove; + driver->driver.owner = driver->owner; - retval = driver_register(&device->driver); + retval = driver_register(&driver->driver); return retval; } -void usb_serial_bus_deregister(struct usb_serial_device_type *device) +void usb_serial_bus_deregister(struct usb_serial_driver *driver) { - driver_unregister (&device->driver); + driver_unregister(&driver->driver); } diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 97c78c21e8d1..0b45b58bef5f 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -73,7 +73,7 @@ static struct usb_driver cp2101_driver = { .id_table = id_table, }; -static struct usb_serial_device_type cp2101_device = { +static struct usb_serial_driver cp2101_device = { .owner = THIS_MODULE, .name = "CP2101", .id_table = id_table, diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index b5b431067b08..9f421a3c47e8 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -83,7 +83,7 @@ static struct usb_driver cyberjack_driver = { .id_table = id_table, }; -static struct usb_serial_device_type cyberjack_device = { +static struct usb_serial_driver cyberjack_device = { .owner = THIS_MODULE, .name = "Reiner SCT Cyberjack USB card reader", .short_name = "cyberjack", diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9ee1aaff2fcd..4fb8e59d1527 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -176,7 +176,7 @@ static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, u static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count); -static struct usb_serial_device_type cypress_earthmate_device = { +static struct usb_serial_driver cypress_earthmate_device = { .owner = THIS_MODULE, .name = "DeLorme Earthmate USB", .short_name = "earthmate", @@ -203,7 +203,7 @@ static struct usb_serial_device_type cypress_earthmate_device = { .write_int_callback = cypress_write_int_callback, }; -static struct usb_serial_device_type cypress_hidcom_device = { +static struct usb_serial_driver cypress_hidcom_device = { .owner = THIS_MODULE, .name = "HID->COM RS232 Adapter", .short_name = "cyphidcom", diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index a19a47f6cf12..66feb88b4316 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -503,7 +503,7 @@ static struct usb_driver digi_driver = { /* device info needed for the Digi serial converter */ -static struct usb_serial_device_type digi_acceleport_2_device = { +static struct usb_serial_driver digi_acceleport_2_device = { .owner = THIS_MODULE, .name = "Digi 2 port USB adapter", .short_name = "digi_2", @@ -530,7 +530,7 @@ static struct usb_serial_device_type digi_acceleport_2_device = { .shutdown = digi_shutdown, }; -static struct usb_serial_device_type digi_acceleport_4_device = { +static struct usb_serial_driver digi_acceleport_4_device = { .owner = THIS_MODULE, .name = "Digi 4 port USB adapter", .short_name = "digi_4", diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 8d562ab454a8..cbea8b38b60e 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -112,7 +112,7 @@ static struct usb_driver empeg_driver = { .id_table = id_table, }; -static struct usb_serial_device_type empeg_device = { +static struct usb_serial_driver empeg_device = { .owner = THIS_MODULE, .name = "Empeg", .id_table = id_table, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b713113c1650..529e1a7ccfa0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -562,7 +562,7 @@ static unsigned short int ftdi_232am_baud_to_divisor (int baud); static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); static __u32 ftdi_232bm_baud_to_divisor (int baud); -static struct usb_serial_device_type ftdi_sio_device = { +static struct usb_serial_driver ftdi_sio_device = { .owner = THIS_MODULE, .name = "FTDI USB Serial Device", .short_name = "ftdi_sio", diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 2ef614d5c8f2..7361194f1d66 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1468,13 +1468,8 @@ static void garmin_shutdown (struct usb_serial *serial) } - - - - - /* All of the device info needed */ -static struct usb_serial_device_type garmin_device = { +static struct usb_serial_driver garmin_device = { .owner = THIS_MODULE, .name = "Garmin GPS usb/tty", .short_name = "garmin_gps", diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 5f7d3193d355..7f567bf96549 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -36,7 +36,7 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ /* All of the device info needed for the Generic Serial Converter */ -struct usb_serial_device_type usb_serial_generic_device = { +struct usb_serial_driver usb_serial_generic_device = { .owner = THIS_MODULE, .name = "Generic", .short_name = "generic", diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 64d55fbd206e..b49469907a87 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -44,7 +44,7 @@ static struct usb_driver hp49gp_driver = { .id_table = id_table, }; -static struct usb_serial_device_type hp49gp_device = { +static struct usb_serial_driver hp49gp_device = { .owner = THIS_MODULE, .name = "HP4X", .id_table = id_table, diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index e7ffe02408bd..7314c04727fe 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -75,7 +75,7 @@ static struct usb_device_id id_table_combined [] = { MODULE_DEVICE_TABLE (usb, id_table_combined); -static struct usb_serial_device_type edgeport_2port_device = { +static struct usb_serial_driver edgeport_2port_device = { .owner = THIS_MODULE, .name = "Edgeport 2 port adapter", .short_name = "edgeport_2", @@ -103,7 +103,7 @@ static struct usb_serial_device_type edgeport_2port_device = { .write_bulk_callback = edge_bulk_out_data_callback, }; -static struct usb_serial_device_type edgeport_4port_device = { +static struct usb_serial_driver edgeport_4port_device = { .owner = THIS_MODULE, .name = "Edgeport 4 port adapter", .short_name = "edgeport_4", @@ -131,7 +131,7 @@ static struct usb_serial_device_type edgeport_4port_device = { .write_bulk_callback = edge_bulk_out_data_callback, }; -static struct usb_serial_device_type edgeport_8port_device = { +static struct usb_serial_driver edgeport_8port_device = { .owner = THIS_MODULE, .name = "Edgeport 8 port adapter", .short_name = "edgeport_8", diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index ebf9967f7c86..4328cc702ef7 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2982,7 +2982,7 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, } -static struct usb_serial_device_type edgeport_1port_device = { +static struct usb_serial_driver edgeport_1port_device = { .owner = THIS_MODULE, .name = "Edgeport TI 1 port adapter", .short_name = "edgeport_ti_1", @@ -3010,7 +3010,7 @@ static struct usb_serial_device_type edgeport_1port_device = { .write_bulk_callback = edge_bulk_out_callback, }; -static struct usb_serial_device_type edgeport_2port_device = { +static struct usb_serial_driver edgeport_2port_device = { .owner = THIS_MODULE, .name = "Edgeport TI 2 port adapter", .short_name = "edgeport_ti_2", diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index c05c2a2a0f31..9a79ad8d7a5f 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -547,7 +547,7 @@ static struct usb_driver ipaq_driver = { /* All of the device info needed for the Compaq iPAQ */ -static struct usb_serial_device_type ipaq_device = { +static struct usb_serial_driver ipaq_device = { .owner = THIS_MODULE, .name = "PocketPC PDA", .id_table = ipaq_id_table, diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 85e242459c27..04524d34de3b 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -443,7 +443,7 @@ static int ipw_disconnect(struct usb_serial_port *port) return 0; } -static struct usb_serial_device_type ipw_device = { +static struct usb_serial_driver ipw_device = { .owner = THIS_MODULE, .name = "IPWireless converter", .short_name = "ipw", diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 937b2fdd7171..ecfb2060ea0f 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -133,7 +133,7 @@ static struct usb_driver ir_driver = { }; -static struct usb_serial_device_type ir_device = { +static struct usb_serial_driver ir_device = { .owner = THIS_MODULE, .name = "IR Dongle", .id_table = id_table, diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index e9b45b768aca..97e7d9e53e39 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -570,7 +570,7 @@ static struct usb_device_id keyspan_4port_ids[] = { }; /* Structs for the devices, pre and post renumeration. */ -static struct usb_serial_device_type keyspan_pre_device = { +static struct usb_serial_driver keyspan_pre_device = { .owner = THIS_MODULE, .name = "Keyspan - (without firmware)", .short_name = "keyspan_no_firm", @@ -582,7 +582,7 @@ static struct usb_serial_device_type keyspan_pre_device = { .attach = keyspan_fake_startup, }; -static struct usb_serial_device_type keyspan_1port_device = { +static struct usb_serial_driver keyspan_1port_device = { .owner = THIS_MODULE, .name = "Keyspan 1 port adapter", .short_name = "keyspan_1", @@ -607,7 +607,7 @@ static struct usb_serial_device_type keyspan_1port_device = { .shutdown = keyspan_shutdown, }; -static struct usb_serial_device_type keyspan_2port_device = { +static struct usb_serial_driver keyspan_2port_device = { .owner = THIS_MODULE, .name = "Keyspan 2 port adapter", .short_name = "keyspan_2", @@ -632,7 +632,7 @@ static struct usb_serial_device_type keyspan_2port_device = { .shutdown = keyspan_shutdown, }; -static struct usb_serial_device_type keyspan_4port_device = { +static struct usb_serial_driver keyspan_4port_device = { .owner = THIS_MODULE, .name = "Keyspan 4 port adapter", .short_name = "keyspan_4", diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 635c384cb15a..8fad0e963dd3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -783,7 +783,7 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) } #ifdef KEYSPAN -static struct usb_serial_device_type keyspan_pda_fake_device = { +static struct usb_serial_driver keyspan_pda_fake_device = { .owner = THIS_MODULE, .name = "Keyspan PDA - (prerenumeration)", .short_name = "keyspan_pda_pre", @@ -797,7 +797,7 @@ static struct usb_serial_device_type keyspan_pda_fake_device = { #endif #ifdef XIRCOM -static struct usb_serial_device_type xircom_pgs_fake_device = { +static struct usb_serial_driver xircom_pgs_fake_device = { .owner = THIS_MODULE, .name = "Xircom / Entregra PGS - (prerenumeration)", .short_name = "xircom_no_firm", @@ -810,7 +810,7 @@ static struct usb_serial_device_type xircom_pgs_fake_device = { }; #endif -static struct usb_serial_device_type keyspan_pda_device = { +static struct usb_serial_driver keyspan_pda_device = { .owner = THIS_MODULE, .name = "Keyspan PDA", .short_name = "keyspan_pda", diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a11e829e38c8..be082706b952 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -123,7 +123,7 @@ static struct usb_driver kl5kusb105d_driver = { .id_table = id_table, }; -static struct usb_serial_device_type kl5kusb105d_device = { +static struct usb_serial_driver kl5kusb105d_device = { .owner = THIS_MODULE, .name = "KL5KUSB105D / PalmConnect", .short_name = "kl5kusb105d", diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index fe4c98a75171..94944340bb8d 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -105,7 +105,7 @@ static struct usb_driver kobil_driver = { }; -static struct usb_serial_device_type kobil_device = { +static struct usb_serial_driver kobil_device = { .owner = THIS_MODULE, .name = "KOBIL USB smart card terminal", .id_table = id_table, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 50b6369647d2..9470964316a7 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -132,7 +132,7 @@ static struct usb_driver mct_u232_driver = { .id_table = id_table_combined, }; -static struct usb_serial_device_type mct_u232_device = { +static struct usb_serial_driver mct_u232_device = { .owner = THIS_MODULE, .name = "MCT U232", .short_name = "mct_u232", diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 6a99ae192df1..53c0588877c0 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -88,7 +88,7 @@ static struct usb_driver omninet_driver = { }; -static struct usb_serial_device_type zyxel_omninet_device = { +static struct usb_serial_driver zyxel_omninet_device = { .owner = THIS_MODULE, .name = "ZyXEL - omni.net lcd plus usb", .short_name = "omninet", diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 4989e5740d18..6ec9266e2e96 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -105,7 +105,7 @@ static struct usb_driver option_driver = { /* The card has three separate interfaces, wich the serial driver * recognizes separately, thus num_port=1. */ -static struct usb_serial_device_type option_3port_device = { +static struct usb_serial_driver option_3port_device = { .owner = THIS_MODULE, .name = "Option 3G data card", .short_name = "option", diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 3cf245bdda54..7134648e078d 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -175,7 +175,7 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, /* All of the device info needed for the PL2303 SIO serial converter */ -static struct usb_serial_device_type pl2303_device = { +static struct usb_serial_driver pl2303_device = { .owner = THIS_MODULE, .name = "PL-2303", .id_table = id_table, diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 88bf14abfa7a..87871bb647df 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -397,7 +397,7 @@ static int safe_startup (struct usb_serial *serial) return 0; } -static struct usb_serial_device_type safe_device = { +static struct usb_serial_driver safe_device = { .owner = THIS_MODULE, .name = "Safe", .id_table = id_table, diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 59c88de3e7ae..f2efaf6f3d76 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -255,7 +255,7 @@ static struct usb_driver ti_usb_driver = { .id_table = ti_id_table_combined, }; -static struct usb_serial_device_type ti_1port_device = { +static struct usb_serial_driver ti_1port_device = { .owner = THIS_MODULE, .name = "TI USB 3410 1 port adapter", .id_table = ti_id_table_3410, @@ -282,7 +282,7 @@ static struct usb_serial_device_type ti_1port_device = { .write_bulk_callback = ti_bulk_out_callback, }; -static struct usb_serial_device_type ti_2port_device = { +static struct usb_serial_driver ti_2port_device = { .owner = THIS_MODULE, .name = "TI USB 5052 2 port adapter", .id_table = ti_id_table_5052, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index e77fbdfc782d..cf083da15eb4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -823,7 +823,7 @@ static void port_release(struct device *dev) static struct usb_serial * create_serial (struct usb_device *dev, struct usb_interface *interface, - struct usb_serial_device_type *type) + struct usb_serial_driver *driver) { struct usb_serial *serial; @@ -834,22 +834,22 @@ static struct usb_serial * create_serial (struct usb_device *dev, } memset (serial, 0, sizeof(*serial)); serial->dev = usb_get_dev(dev); - serial->type = type; + serial->type = driver; serial->interface = interface; kref_init(&serial->kref); return serial; } -static struct usb_serial_device_type *search_serial_device(struct usb_interface *iface) +static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) { struct list_head *p; const struct usb_device_id *id; - struct usb_serial_device_type *t; + struct usb_serial_driver *t; /* List trough know devices and see if the usb id matches */ list_for_each(p, &usb_serial_driver_list) { - t = list_entry(p, struct usb_serial_device_type, driver_list); + t = list_entry(p, struct usb_serial_driver, driver_list); id = usb_match_id(iface, t->id_table); if (id != NULL) { dbg("descriptor matches"); @@ -872,7 +872,7 @@ int usb_serial_probe(struct usb_interface *interface, struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS]; struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; - struct usb_serial_device_type *type = NULL; + struct usb_serial_driver *type = NULL; int retval; int minor; int buffer_size; @@ -1375,7 +1375,7 @@ module_exit(usb_serial_exit); } \ } while (0) -static void fixup_generic(struct usb_serial_device_type *device) +static void fixup_generic(struct usb_serial_driver *device) { set_to_generic_if_null(device, open); set_to_generic_if_null(device, write); @@ -1387,28 +1387,28 @@ static void fixup_generic(struct usb_serial_device_type *device) set_to_generic_if_null(device, shutdown); } -int usb_serial_register(struct usb_serial_device_type *new_device) +int usb_serial_register(struct usb_serial_driver *driver) { int retval; - fixup_generic(new_device); + fixup_generic(driver); /* Add this device to our list of devices */ - list_add(&new_device->driver_list, &usb_serial_driver_list); + list_add(&driver->driver_list, &usb_serial_driver_list); - retval = usb_serial_bus_register(new_device); + retval = usb_serial_bus_register(driver); if (retval) { - err("problem %d when registering driver %s", retval, new_device->name); - list_del(&new_device->driver_list); + err("problem %d when registering driver %s", retval, driver->name); + list_del(&driver->driver_list); } else - info("USB Serial support registered for %s", new_device->name); + info("USB Serial support registered for %s", driver->name); return retval; } -void usb_serial_deregister(struct usb_serial_device_type *device) +void usb_serial_deregister(struct usb_serial_driver *device) { info("USB Serial deregistering driver %s", device->name); list_del(&device->driver_list); diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 57f92f054c75..d6738b1b0429 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -143,7 +143,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void /** * usb_serial - structure used by the usb-serial core for a device * @dev: pointer to the struct usb_device for this device - * @type: pointer to the struct usb_serial_device_type for this device + * @type: pointer to the struct usb_serial_driver for this device * @interface: pointer to the struct usb_interface for this device * @minor: the starting minor number for this device * @num_ports: the number of ports this device has @@ -159,7 +159,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void */ struct usb_serial { struct usb_device * dev; - struct usb_serial_device_type * type; + struct usb_serial_driver * type; struct usb_interface * interface; unsigned char minor; unsigned char num_ports; @@ -188,11 +188,11 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) } /** - * usb_serial_device_type - a structure that defines a usb serial device - * @owner: pointer to the module that owns this device. - * @name: pointer to a string that describes this device. This string used + * usb_serial_driver - describes a usb serial driver + * @owner: pointer to the module that owns this driver. + * @name: pointer to a string that describes this driver. This string used * in the syslog messages when a device is inserted or removed. - * @short_name: a pointer to a string that describes this device in + * @short_name: a pointer to a string that describes this driver in * KOBJ_NAME_LEN characters or less. This is used for the sysfs interface * to describe the driver. * @id_table: pointer to a list of usb_device_id structures that define all @@ -221,13 +221,13 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) * @shutdown: pointer to the driver's shutdown function. This will be * called when the device is removed from the system. * - * This structure is defines a USB Serial device. It provides all of + * This structure is defines a USB Serial driver. It provides all of * the information that the USB serial core code needs. If the function * pointers are defined, then the USB serial core code will call them when * the corresponding tty port functions are called. If they are not * called, the generic serial function will be used instead. */ -struct usb_serial_device_type { +struct usb_serial_driver { struct module *owner; char *name; char *short_name; @@ -269,10 +269,10 @@ struct usb_serial_device_type { void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs); void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs); }; -#define to_usb_serial_driver(d) container_of(d, struct usb_serial_device_type, driver) +#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver) -extern int usb_serial_register(struct usb_serial_device_type *new_device); -extern void usb_serial_deregister(struct usb_serial_device_type *device); +extern int usb_serial_register(struct usb_serial_driver *driver); +extern void usb_serial_deregister(struct usb_serial_driver *driver); extern void usb_serial_port_softint(void *private); extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); @@ -303,10 +303,10 @@ extern void usb_serial_generic_shutdown (struct usb_serial *serial); extern int usb_serial_generic_register (int debug); extern void usb_serial_generic_deregister (void); -extern int usb_serial_bus_register (struct usb_serial_device_type *device); -extern void usb_serial_bus_deregister (struct usb_serial_device_type *device); +extern int usb_serial_bus_register (struct usb_serial_driver *device); +extern void usb_serial_bus_deregister (struct usb_serial_driver *device); -extern struct usb_serial_device_type usb_serial_generic_device; +extern struct usb_serial_driver usb_serial_generic_device; extern struct bus_type usb_serial_bus_type; extern struct tty_driver *usb_serial_tty_driver; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 31c57adcb623..825451b3788c 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -311,7 +311,7 @@ static struct usb_driver visor_driver = { }; /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ -static struct usb_serial_device_type handspring_device = { +static struct usb_serial_driver handspring_device = { .owner = THIS_MODULE, .name = "Handspring Visor / Palm OS", .short_name = "visor", @@ -339,7 +339,7 @@ static struct usb_serial_device_type handspring_device = { }; /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ -static struct usb_serial_device_type clie_5_device = { +static struct usb_serial_driver clie_5_device = { .owner = THIS_MODULE, .name = "Sony Clie 5.0", .short_name = "clie_5", @@ -367,7 +367,7 @@ static struct usb_serial_device_type clie_5_device = { }; /* device info for the Sony Clie OS version 3.5 */ -static struct usb_serial_device_type clie_3_5_device = { +static struct usb_serial_driver clie_3_5_device = { .owner = THIS_MODULE, .name = "Sony Clie 3.5", .short_name = "clie_3.5", diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index cf3bc30675a1..dc06664bfa0e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -156,7 +156,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port); static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs); static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); -static struct usb_serial_device_type whiteheat_fake_device = { +static struct usb_serial_driver whiteheat_fake_device = { .owner = THIS_MODULE, .name = "Connect Tech - WhiteHEAT - (prerenumeration)", .short_name = "whiteheatnofirm", @@ -169,7 +169,7 @@ static struct usb_serial_device_type whiteheat_fake_device = { .attach = whiteheat_firmware_attach, }; -static struct usb_serial_device_type whiteheat_device = { +static struct usb_serial_driver whiteheat_device = { .owner = THIS_MODULE, .name = "Connect Tech - WhiteHEAT", .short_name = "whiteheat", From 18fcac353fdc7cd072b0d24c8667042e675a4c11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0881/1940] [PATCH] USB Serial: get rid of the .owner field in usb_serial_driver Don't duplicate something that's already in struct driver. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 4 +++- drivers/usb/serial/belkin_sa.c | 4 +++- drivers/usb/serial/bus.c | 9 ++++----- drivers/usb/serial/cp2101.c | 4 +++- drivers/usb/serial/cyberjack.c | 4 +++- drivers/usb/serial/cypress_m8.c | 8 ++++++-- drivers/usb/serial/digi_acceleport.c | 8 ++++++-- drivers/usb/serial/empeg.c | 4 +++- drivers/usb/serial/ftdi_sio.c | 4 +++- drivers/usb/serial/garmin_gps.c | 4 +++- drivers/usb/serial/generic.c | 4 +++- drivers/usb/serial/hp4x.c | 4 +++- drivers/usb/serial/io_tables.h | 12 +++++++++--- drivers/usb/serial/io_ti.c | 8 ++++++-- drivers/usb/serial/ipaq.c | 4 +++- drivers/usb/serial/ipw.c | 4 +++- drivers/usb/serial/ir-usb.c | 4 +++- drivers/usb/serial/keyspan.h | 16 ++++++++++++---- drivers/usb/serial/keyspan_pda.c | 12 +++++++++--- drivers/usb/serial/kl5kusb105.c | 4 +++- drivers/usb/serial/kobil_sct.c | 4 +++- drivers/usb/serial/mct_u232.c | 4 +++- drivers/usb/serial/omninet.c | 4 +++- drivers/usb/serial/option.c | 4 +++- drivers/usb/serial/pl2303.c | 4 +++- drivers/usb/serial/safe_serial.c | 4 +++- drivers/usb/serial/ti_usb_3410_5052.c | 8 ++++++-- drivers/usb/serial/usb-serial.c | 22 +++++++++++----------- drivers/usb/serial/usb-serial.h | 5 +++-- drivers/usb/serial/visor.c | 12 +++++++++--- drivers/usb/serial/whiteheat.c | 8 ++++++-- 31 files changed, 144 insertions(+), 60 deletions(-) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 104c04385bb9..fbc5b9b44749 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -31,7 +31,9 @@ static struct usb_driver airprime_driver = { }; static struct usb_serial_driver airprime_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "airprime", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 6d84de40cb7b..4878961a0900 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -122,7 +122,9 @@ static struct usb_driver belkin_driver = { /* All of the device info needed for the serial converters */ static struct usb_serial_driver belkin_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Belkin / Peracom / GoHubs USB Serial Adapter", .short_name = "belkin", .id_table = id_table_combined, diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 5a0bcd34bb6d..b8364a8de7df 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -57,13 +57,13 @@ static int usb_serial_device_probe (struct device *dev) driver = port->serial->type; if (driver->port_probe) { - if (!try_module_get(driver->owner)) { + if (!try_module_get(driver->driver.owner)) { dev_err(dev, "module get failed, exiting\n"); retval = -EIO; goto exit; } retval = driver->port_probe (port); - module_put(driver->owner); + module_put(driver->driver.owner); if (retval) goto exit; } @@ -92,13 +92,13 @@ static int usb_serial_device_remove (struct device *dev) driver = port->serial->type; if (driver->port_remove) { - if (!try_module_get(driver->owner)) { + if (!try_module_get(driver->driver.owner)) { dev_err(dev, "module get failed, exiting\n"); retval = -EIO; goto exit; } retval = driver->port_remove (port); - module_put(driver->owner); + module_put(driver->driver.owner); } exit: minor = port->number; @@ -120,7 +120,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) driver->driver.bus = &usb_serial_bus_type; driver->driver.probe = usb_serial_device_probe; driver->driver.remove = usb_serial_device_remove; - driver->driver.owner = driver->owner; retval = driver_register(&driver->driver); diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 0b45b58bef5f..81dd720a122b 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -74,7 +74,9 @@ static struct usb_driver cp2101_driver = { }; static struct usb_serial_driver cp2101_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "CP2101", .id_table = id_table, .num_interrupt_in = 0, diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 9f421a3c47e8..3441bad74f7b 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -84,7 +84,9 @@ static struct usb_driver cyberjack_driver = { }; static struct usb_serial_driver cyberjack_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Reiner SCT Cyberjack USB card reader", .short_name = "cyberjack", .id_table = id_table, diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4fb8e59d1527..b4069af4d565 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -177,7 +177,9 @@ static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigne static struct usb_serial_driver cypress_earthmate_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "DeLorme Earthmate USB", .short_name = "earthmate", .id_table = id_table_earthmate, @@ -204,7 +206,9 @@ static struct usb_serial_driver cypress_earthmate_device = { }; static struct usb_serial_driver cypress_hidcom_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "HID->COM RS232 Adapter", .short_name = "cyphidcom", .id_table = id_table_cyphidcomrs232, diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 66feb88b4316..be9b495d2491 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -504,7 +504,9 @@ static struct usb_driver digi_driver = { /* device info needed for the Digi serial converter */ static struct usb_serial_driver digi_acceleport_2_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Digi 2 port USB adapter", .short_name = "digi_2", .id_table = id_table_2, @@ -531,7 +533,9 @@ static struct usb_serial_driver digi_acceleport_2_device = { }; static struct usb_serial_driver digi_acceleport_4_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Digi 4 port USB adapter", .short_name = "digi_4", .id_table = id_table_4, diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index cbea8b38b60e..3e6c4ba7667b 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -113,7 +113,9 @@ static struct usb_driver empeg_driver = { }; static struct usb_serial_driver empeg_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Empeg", .id_table = id_table, .num_interrupt_in = 0, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 529e1a7ccfa0..9d945de0acac 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -563,7 +563,9 @@ static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); static __u32 ftdi_232bm_baud_to_divisor (int baud); static struct usb_serial_driver ftdi_sio_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "FTDI USB Serial Device", .short_name = "ftdi_sio", .id_table = id_table_combined, diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 7361194f1d66..3fd98c00cd6a 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1470,7 +1470,9 @@ static void garmin_shutdown (struct usb_serial *serial) /* All of the device info needed */ static struct usb_serial_driver garmin_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Garmin GPS usb/tty", .short_name = "garmin_gps", .id_table = id_table, diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 7f567bf96549..779bea0c6242 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -37,7 +37,9 @@ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ /* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Generic", .short_name = "generic", .id_table = generic_device_ids, diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index b49469907a87..4f3cbc08c4ee 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -45,7 +45,9 @@ static struct usb_driver hp49gp_driver = { }; static struct usb_serial_driver hp49gp_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "HP4X", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 7314c04727fe..28fb0d42a166 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -76,7 +76,9 @@ static struct usb_device_id id_table_combined [] = { MODULE_DEVICE_TABLE (usb, id_table_combined); static struct usb_serial_driver edgeport_2port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Edgeport 2 port adapter", .short_name = "edgeport_2", .id_table = edgeport_2port_id_table, @@ -104,7 +106,9 @@ static struct usb_serial_driver edgeport_2port_device = { }; static struct usb_serial_driver edgeport_4port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Edgeport 4 port adapter", .short_name = "edgeport_4", .id_table = edgeport_4port_id_table, @@ -132,7 +136,9 @@ static struct usb_serial_driver edgeport_4port_device = { }; static struct usb_serial_driver edgeport_8port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Edgeport 8 port adapter", .short_name = "edgeport_8", .id_table = edgeport_8port_id_table, diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 4328cc702ef7..74228a072643 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2983,7 +2983,9 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, static struct usb_serial_driver edgeport_1port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Edgeport TI 1 port adapter", .short_name = "edgeport_ti_1", .id_table = edgeport_1port_id_table, @@ -3011,7 +3013,9 @@ static struct usb_serial_driver edgeport_1port_device = { }; static struct usb_serial_driver edgeport_2port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Edgeport TI 2 port adapter", .short_name = "edgeport_ti_2", .id_table = edgeport_2port_id_table, diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 9a79ad8d7a5f..9aedfb91b20c 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -548,7 +548,9 @@ static struct usb_driver ipaq_driver = { /* All of the device info needed for the Compaq iPAQ */ static struct usb_serial_driver ipaq_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "PocketPC PDA", .id_table = ipaq_id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 04524d34de3b..2ba69623ac05 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -444,7 +444,9 @@ static int ipw_disconnect(struct usb_serial_port *port) } static struct usb_serial_driver ipw_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "IPWireless converter", .short_name = "ipw", .id_table = usb_ipw_ids, diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index ecfb2060ea0f..bf079059819e 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -134,7 +134,9 @@ static struct usb_driver ir_driver = { static struct usb_serial_driver ir_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "IR Dongle", .id_table = id_table, .num_interrupt_in = 1, diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 97e7d9e53e39..124d46e76a2e 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -571,7 +571,9 @@ static struct usb_device_id keyspan_4port_ids[] = { /* Structs for the devices, pre and post renumeration. */ static struct usb_serial_driver keyspan_pre_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan - (without firmware)", .short_name = "keyspan_no_firm", .id_table = keyspan_pre_ids, @@ -583,7 +585,9 @@ static struct usb_serial_driver keyspan_pre_device = { }; static struct usb_serial_driver keyspan_1port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan 1 port adapter", .short_name = "keyspan_1", .id_table = keyspan_1port_ids, @@ -608,7 +612,9 @@ static struct usb_serial_driver keyspan_1port_device = { }; static struct usb_serial_driver keyspan_2port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan 2 port adapter", .short_name = "keyspan_2", .id_table = keyspan_2port_ids, @@ -633,7 +639,9 @@ static struct usb_serial_driver keyspan_2port_device = { }; static struct usb_serial_driver keyspan_4port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan 4 port adapter", .short_name = "keyspan_4", .id_table = keyspan_4port_ids, diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 8fad0e963dd3..389b7833e3ae 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -784,7 +784,9 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) #ifdef KEYSPAN static struct usb_serial_driver keyspan_pda_fake_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan PDA - (prerenumeration)", .short_name = "keyspan_pda_pre", .id_table = id_table_fake, @@ -798,7 +800,9 @@ static struct usb_serial_driver keyspan_pda_fake_device = { #ifdef XIRCOM static struct usb_serial_driver xircom_pgs_fake_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Xircom / Entregra PGS - (prerenumeration)", .short_name = "xircom_no_firm", .id_table = id_table_fake_xircom, @@ -811,7 +815,9 @@ static struct usb_serial_driver xircom_pgs_fake_device = { #endif static struct usb_serial_driver keyspan_pda_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Keyspan PDA", .short_name = "keyspan_pda", .id_table = id_table_std, diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index be082706b952..586108ce7897 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -124,7 +124,9 @@ static struct usb_driver kl5kusb105d_driver = { }; static struct usb_serial_driver kl5kusb105d_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "KL5KUSB105D / PalmConnect", .short_name = "kl5kusb105d", .id_table = id_table, diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 94944340bb8d..a9578e05b22f 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -106,7 +106,9 @@ static struct usb_driver kobil_driver = { static struct usb_serial_driver kobil_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "KOBIL USB smart card terminal", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 9470964316a7..7dcf91c5f83d 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -133,7 +133,9 @@ static struct usb_driver mct_u232_driver = { }; static struct usb_serial_driver mct_u232_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "MCT U232", .short_name = "mct_u232", .id_table = id_table_combined, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 53c0588877c0..f6327cc1b2e7 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -89,7 +89,9 @@ static struct usb_driver omninet_driver = { static struct usb_serial_driver zyxel_omninet_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "ZyXEL - omni.net lcd plus usb", .short_name = "omninet", .id_table = id_table, diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6ec9266e2e96..a2b5adf34868 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -106,7 +106,9 @@ static struct usb_driver option_driver = { * recognizes separately, thus num_port=1. */ static struct usb_serial_driver option_3port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Option 3G data card", .short_name = "option", .id_table = option_ids, diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 7134648e078d..beef3c4cee6e 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -176,7 +176,9 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, /* All of the device info needed for the PL2303 SIO serial converter */ static struct usb_serial_driver pl2303_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "PL-2303", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 87871bb647df..42a86ab689f4 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -398,7 +398,9 @@ static int safe_startup (struct usb_serial *serial) } static struct usb_serial_driver safe_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Safe", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index f2efaf6f3d76..eab8a6de0925 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -256,7 +256,9 @@ static struct usb_driver ti_usb_driver = { }; static struct usb_serial_driver ti_1port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "TI USB 3410 1 port adapter", .id_table = ti_id_table_3410, .num_interrupt_in = 1, @@ -283,7 +285,9 @@ static struct usb_serial_driver ti_1port_device = { }; static struct usb_serial_driver ti_2port_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "TI USB 5052 2 port adapter", .id_table = ti_id_table_5052, .num_interrupt_in = 1, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index cf083da15eb4..08f600327db4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -507,7 +507,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) /* lock this module before we call it * this may fail, which means we must bail out, * safe because we are called with BKL held */ - if (!try_module_get(serial->type->owner)) { + if (!try_module_get(serial->type->driver.owner)) { retval = -ENODEV; goto bailout_kref_put; } @@ -522,7 +522,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) return 0; bailout_module_put: - module_put(serial->type->owner); + module_put(serial->type->driver.owner); bailout_kref_put: kref_put(&serial->kref, destroy_serial); port->open_count = 0; @@ -553,7 +553,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) port->tty = NULL; } - module_put(port->serial->type->owner); + module_put(port->serial->type->driver.owner); } kref_put(&port->serial->kref, destroy_serial); @@ -718,8 +718,8 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int continue; length += sprintf (page+length, "%d:", i); - if (serial->type->owner) - length += sprintf (page+length, " module:%s", module_name(serial->type->owner)); + if (serial->type->driver.owner) + length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner)); length += sprintf (page+length, " name:\"%s\"", serial->type->name); length += sprintf (page+length, " vendor:%04x product:%04x", le16_to_cpu(serial->dev->descriptor.idVendor), @@ -900,7 +900,7 @@ int usb_serial_probe(struct usb_interface *interface, if (type->probe) { const struct usb_device_id *id; - if (!try_module_get(type->owner)) { + if (!try_module_get(type->driver.owner)) { dev_err(&interface->dev, "module get failed, exiting\n"); kfree (serial); return -EIO; @@ -908,7 +908,7 @@ int usb_serial_probe(struct usb_interface *interface, id = usb_match_id(interface, type->id_table); retval = type->probe(serial, id); - module_put(type->owner); + module_put(type->driver.owner); if (retval) { dbg ("sub driver rejected device"); @@ -1007,13 +1007,13 @@ int usb_serial_probe(struct usb_interface *interface, if (!num_ports) { /* if this device type has a calc_num_ports function, call it */ if (type->calc_num_ports) { - if (!try_module_get(type->owner)) { + if (!try_module_get(type->driver.owner)) { dev_err(&interface->dev, "module get failed, exiting\n"); kfree (serial); return -EIO; } num_ports = type->calc_num_ports (serial); - module_put(type->owner); + module_put(type->driver.owner); } if (!num_ports) num_ports = type->num_ports; @@ -1158,12 +1158,12 @@ int usb_serial_probe(struct usb_interface *interface, /* if this device type has an attach function, call it */ if (type->attach) { - if (!try_module_get(type->owner)) { + if (!try_module_get(type->driver.owner)) { dev_err(&interface->dev, "module get failed, exiting\n"); goto probe_error; } retval = type->attach (serial); - module_put(type->owner); + module_put(type->driver.owner); if (retval < 0) goto probe_error; if (retval > 0) { diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index d6738b1b0429..4ca5e0c05611 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -189,7 +189,6 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) /** * usb_serial_driver - describes a usb serial driver - * @owner: pointer to the module that owns this driver. * @name: pointer to a string that describes this driver. This string used * in the syslog messages when a device is inserted or removed. * @short_name: a pointer to a string that describes this driver in @@ -226,9 +225,11 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) * pointers are defined, then the USB serial core code will call them when * the corresponding tty port functions are called. If they are not * called, the generic serial function will be used instead. + * + * The driver.owner field should be set to the module owner of this driver. + * */ struct usb_serial_driver { - struct module *owner; char *name; char *short_name; const struct usb_device_id *id_table; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 825451b3788c..0ac0377e8683 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -312,7 +312,9 @@ static struct usb_driver visor_driver = { /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ static struct usb_serial_driver handspring_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Handspring Visor / Palm OS", .short_name = "visor", .id_table = id_table, @@ -340,7 +342,9 @@ static struct usb_serial_driver handspring_device = { /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ static struct usb_serial_driver clie_5_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Sony Clie 5.0", .short_name = "clie_5", .id_table = clie_id_5_table, @@ -368,7 +372,9 @@ static struct usb_serial_driver clie_5_device = { /* device info for the Sony Clie OS version 3.5 */ static struct usb_serial_driver clie_3_5_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Sony Clie 3.5", .short_name = "clie_3.5", .id_table = clie_id_3_5_table, diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index dc06664bfa0e..fb95a34a1cf7 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -157,7 +157,9 @@ static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs); static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); static struct usb_serial_driver whiteheat_fake_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Connect Tech - WhiteHEAT - (prerenumeration)", .short_name = "whiteheatnofirm", .id_table = id_table_prerenumeration, @@ -170,7 +172,9 @@ static struct usb_serial_driver whiteheat_fake_device = { }; static struct usb_serial_driver whiteheat_device = { - .owner = THIS_MODULE, + .driver = { + .owner = THIS_MODULE, + }, .name = "Connect Tech - WhiteHEAT", .short_name = "whiteheat", .id_table = id_table_std, From 502b95c1cc9e2c855a26f90fc999c5211b8ba957 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0882/1940] [PATCH] USB Serial: move old changelog comments out of source code Create a new file just for these things, as they just get in the way in the source files. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ChangeLog.old | 730 +++++++++++++++++++++++++++++++ drivers/usb/serial/io_edgeport.c | 219 ---------- drivers/usb/serial/pl2303.c | 23 +- drivers/usb/serial/usb-serial.c | 309 +------------ drivers/usb/serial/usb-serial.h | 44 +- drivers/usb/serial/visor.c | 131 +----- 6 files changed, 736 insertions(+), 720 deletions(-) create mode 100644 drivers/usb/serial/ChangeLog.old diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.old new file mode 100644 index 000000000000..c1b279939bbf --- /dev/null +++ b/drivers/usb/serial/ChangeLog.old @@ -0,0 +1,730 @@ +This is the contents of some of the drivers/usb/serial/ files that had old +changelog comments. They were quite old, and out of date, and we don't keep +them anymore, so I've put them here, away from the source files, in case +people still care to see them. + +- Greg Kroah-Hartman October 20, 2005 + +----------------------------------------------------------------------- +usb-serial.h Change Log comments: + + (03/26/2002) gkh + removed the port->tty check from port_paranoia_check() due to serial + consoles not having a tty device assigned to them. + + (12/03/2001) gkh + removed active from the port structure. + added documentation to the usb_serial_device_type structure + + (10/10/2001) gkh + added vendor and product to serial structure. Needed to determine device + owner when the device is disconnected. + + (05/30/2001) gkh + added sem to port structure and removed port_lock + + (10/05/2000) gkh + Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help + fix bug with urb->dev not being set properly, now that the usb core + needs it. + + (09/11/2000) gkh + Added usb_serial_debug_data function to help get rid of #DEBUG in the + drivers. + + (08/28/2000) gkh + Added port_lock to port structure. + + (08/08/2000) gkh + Added open_count to port structure. + + (07/23/2000) gkh + Added bulk_out_endpointAddress to port structure. + + (07/19/2000) gkh, pberger, and borchers + Modifications to allow usb-serial drivers to be modules. + +----------------------------------------------------------------------- +usb-serial.c Change Log comments: + + (12/10/2002) gkh + Split the ports off into their own struct device, and added a + usb-serial bus driver. + + (11/19/2002) gkh + removed a few #ifdefs for the generic code and cleaned up the failure + logic in initialization. + + (10/02/2002) gkh + moved the console code to console.c and out of this file. + + (06/05/2002) gkh + moved location of startup() call in serial_probe() until after all + of the port information and endpoints are initialized. This makes + things easier for some drivers. + + (04/10/2002) gkh + added serial_read_proc function which creates a + /proc/tty/driver/usb-serial file. + + (03/27/2002) gkh + Got USB serial console code working properly and merged into the main + version of the tree. Thanks to Randy Dunlap for the initial version + of this code, and for pushing me to finish it up. + The USB serial console works with any usb serial driver device. + + (03/21/2002) gkh + Moved all manipulation of port->open_count into the core. Now the + individual driver's open and close functions are called only when the + first open() and last close() is called. Making the drivers a bit + smaller and simpler. + Fixed a bug if a driver didn't have the owner field set. + + (02/26/2002) gkh + Moved all locking into the main serial_* functions, instead of having + the individual drivers have to grab the port semaphore. This should + reduce races. + Reworked the MOD_INC logic a bit to always increment and decrement, even + if the generic driver is being used. + + (10/10/2001) gkh + usb_serial_disconnect() now sets the serial->dev pointer is to NULL to + help prevent child drivers from accessing the device since it is now + gone. + + (09/13/2001) gkh + Moved generic driver initialize after we have registered with the USB + core. Thanks to Randy Dunlap for pointing this problem out. + + (07/03/2001) gkh + Fixed module paramater size. Thanks to John Brockmeyer for the pointer. + Fixed vendor and product getting defined through the MODULE_PARM macro + if the Generic driver wasn't compiled in. + Fixed problem with generic_shutdown() not being called for drivers that + don't have a shutdown() function. + + (06/06/2001) gkh + added evil hack that is needed for the prolific pl2303 device due to the + crazy way its endpoints are set up. + + (05/30/2001) gkh + switched from using spinlock to a semaphore, which fixes lots of problems. + + (04/08/2001) gb + Identify version on module load. + + 2001_02_05 gkh + Fixed buffer overflows bug with the generic serial driver. Thanks to + Todd Squires for fixing this. + + (01/10/2001) gkh + Fixed bug where the generic serial adaptor grabbed _any_ device that was + offered to it. + + (12/12/2000) gkh + Removed MOD_INC and MOD_DEC from poll and disconnect functions, and + moved them to the serial_open and serial_close functions. + Also fixed bug with there not being a MOD_DEC for the generic driver + (thanks to Gary Brubaker for finding this.) + + (11/29/2000) gkh + Small NULL pointer initialization cleanup which saves a bit of disk image + + (11/01/2000) Adam J. Richter + instead of using idVendor/idProduct pairs, usb serial drivers + now identify their hardware interest with usb_device_id tables, + which they usually have anyhow for use with MODULE_DEVICE_TABLE. + + (10/05/2000) gkh + Fixed bug with urb->dev not being set properly, now that the usb + core needs it. + + (09/11/2000) gkh + Removed DEBUG #ifdefs with call to usb_serial_debug_data + + (08/28/2000) gkh + Added port_lock to port structure. + Added locks for SMP safeness to generic driver + Fixed the ability to open a generic device's port more than once. + + (07/23/2000) gkh + Added bulk_out_endpointAddress to port structure. + + (07/19/2000) gkh, pberger, and borchers + Modifications to allow usb-serial drivers to be modules. + + (07/03/2000) gkh + Added more debugging to serial_ioctl call + + (06/25/2000) gkh + Changed generic_write_bulk_callback to not call wake_up_interruptible + directly, but to have port_softint do it at a safer time. + + (06/23/2000) gkh + Cleaned up debugging statements in a quest to find UHCI timeout bug. + + (05/22/2000) gkh + Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be + removed from the individual device source files. + + (05/03/2000) gkh + Added the Digi Acceleport driver from Al Borchers and Peter Berger. + + (05/02/2000) gkh + Changed devfs and tty register code to work properly now. This was based on + the ACM driver changes by Vojtech Pavlik. + + (04/27/2000) Ryan VanderBijl + Put calls to *_paranoia_checks into one function. + + (04/23/2000) gkh + Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. + Moved when the startup code printed out the devices that are supported. + + (04/19/2000) gkh + Added driver for ZyXEL omni.net lcd plus ISDN TA + Made startup info message specify which drivers were compiled in. + + (04/03/2000) gkh + Changed the probe process to remove the module unload races. + Changed where the tty layer gets initialized to have devfs work nicer. + Added initial devfs support. + + (03/26/2000) gkh + Split driver up into device specific pieces. + + (03/19/2000) gkh + Fixed oops that could happen when device was removed while a program + was talking to the device. + Removed the static urbs and now all urbs are created and destroyed + dynamically. + Reworked the internal interface. Now everything is based on the + usb_serial_port structure instead of the larger usb_serial structure. + This fixes the bug that a multiport device could not have more than + one port open at one time. + + (03/17/2000) gkh + Added config option for debugging messages. + Added patch for keyspan pda from Brian Warner. + + (03/06/2000) gkh + Added the keyspan pda code from Brian Warner + Moved a bunch of the port specific stuff into its own structure. This + is in anticipation of the true multiport devices (there's a bug if you + try to access more than one port of any multiport device right now) + + (02/21/2000) gkh + Made it so that any serial devices only have to specify which functions + they want to overload from the generic function calls (great, + inheritance in C, in a driver, just what I wanted...) + Added support for set_termios and ioctl function calls. No drivers take + advantage of this yet. + Removed the #ifdef MODULE, now there is no module specific code. + Cleaned up a few comments in usb-serial.h that were wrong (thanks again + to Miles Lott). + Small fix to get_free_serial. + + (02/14/2000) gkh + Removed the Belkin and Peracom functionality from the driver due to + the lack of support from the vendor, and me not wanting people to + accidenatly buy the device, expecting it to work with Linux. + Added read_bulk_callback and write_bulk_callback to the type structure + for the needs of the FTDI and WhiteHEAT driver. + Changed all reverences to FTDI to FTDI_SIO at the request of Bill + Ryder. + Changed the output urb size back to the max endpoint size to make + the ftdi_sio driver have it easier, and due to the fact that it didn't + really increase the speed any. + + (02/11/2000) gkh + Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a + patch from Miles Lott (milos@insync.net). + Fixed bug with not restoring the minor range that a device grabs, if + the startup function fails (thanks Miles for finding this). + + (02/05/2000) gkh + Added initial framework for the Keyspan PDA serial converter so that + Brian Warner has a place to put his code. + Made the ezusb specific functions generic enough that different + devices can use them (whiteheat and keyspan_pda both need them). + Split out a whole bunch of structure and other stuff to a separate + usb-serial.h file. + Made the Visor connection messages a little more understandable, now + that Miles Lott (milos@insync.net) has gotten the Generic channel to + work. Also made them always show up in the log file. + + (01/25/2000) gkh + Added initial framework for FTDI serial converter so that Bill Ryder + has a place to put his code. + Added the vendor specific info from Handspring. Now we can print out + informational debug messages as well as understand what is happening. + + (01/23/2000) gkh + Fixed problem of crash when trying to open a port that didn't have a + device assigned to it. Made the minor node finding a little smarter, + now it looks to find a continuous space for the new device. + + (01/21/2000) gkh + Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) + Fixed get_serial_by_minor which was all messed up for multi port + devices. Fixed multi port problem for generic devices. Now the number + of ports is determined by the number of bulk out endpoints for the + generic device. + + (01/19/2000) gkh + Removed lots of cruft that was around from the old (pre urb) driver + interface. + Made the serial_table dynamic. This should save lots of memory when + the number of minor nodes goes up to 256. + Added initial support for devices that have more than one port. + Added more debugging comments for the Visor, and added a needed + set_configuration call. + + (01/17/2000) gkh + Fixed the WhiteHEAT firmware (my processing tool had a bug) + and added new debug loader firmware for it. + Removed the put_char function as it isn't really needed. + Added visor startup commands as found by the Win98 dump. + + (01/13/2000) gkh + Fixed the vendor id for the generic driver to the one I meant it to be. + + (01/12/2000) gkh + Forget the version numbering...that's pretty useless... + Made the driver able to be compiled so that the user can select which + converter they want to use. This allows people who only want the Visor + support to not pay the memory size price of the WhiteHEAT. + Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) + grabbed the root hub. Not good. + + version 0.4.0 (01/10/2000) gkh + Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT + device. Added startup function to allow firmware to be downloaded to + a device if it needs to be. + Added firmware download logic to the WhiteHEAT device. + Started to add #defines to split up the different drivers for potential + configuration option. + + version 0.3.1 (12/30/99) gkh + Fixed problems with urb for bulk out. + Added initial support for multiple sets of endpoints. This enables + the Handspring Visor to be attached successfully. Only the first + bulk in / bulk out endpoint pair is being used right now. + + version 0.3.0 (12/27/99) gkh + Added initial support for the Handspring Visor based on a patch from + Miles Lott (milos@sneety.insync.net) + Cleaned up the code a bunch and converted over to using urbs only. + + version 0.2.3 (12/21/99) gkh + Added initial support for the Connect Tech WhiteHEAT converter. + Incremented the number of ports in expectation of getting the + WhiteHEAT to work properly (4 ports per connection). + Added notification on insertion and removal of what port the + device is/was connected to (and what kind of device it was). + + version 0.2.2 (12/16/99) gkh + Changed major number to the new allocated number. We're legal now! + + version 0.2.1 (12/14/99) gkh + Fixed bug that happens when device node is opened when there isn't a + device attached to it. Thanks to marek@webdesign.no for noticing this. + + version 0.2.0 (11/10/99) gkh + Split up internals to make it easier to add different types of serial + converters to the code. + Added a "generic" driver that gets it's vendor and product id + from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) + for the idea and sample code (from the usb scanner driver.) + Cleared up any licensing questions by releasing it under the GNU GPL. + + version 0.1.2 (10/25/99) gkh + Fixed bug in detecting device. + + version 0.1.1 (10/05/99) gkh + Changed the major number to not conflict with anything else. + + version 0.1 (09/28/99) gkh + Can recognize the two different devices and start up a read from + device when asked to. Writes also work. No control signals yet, this + all is vendor specific data (i.e. no spec), also no control for + different baud rates or other bit settings. + Currently we are using the same devid as the acm driver. This needs + to change. + +----------------------------------------------------------------------- +visor.c Change Log comments: + + (06/03/2003) Judd Montgomery + Added support for module parameter options for untested/unknown + devices. + + (03/09/2003) gkh + Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl + for the information. + + (03/05/2003) gkh + Think Treo support is now working. + + (04/03/2002) gkh + Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI + for the information. + + (03/27/2002) gkh + Removed assumptions that port->tty was always valid (is not true + for usb serial console devices.) + + (03/23/2002) gkh + Added support for the Palm i705 device, thanks to Thomas Riemer + for the information. + + (03/21/2002) gkh + Added support for the Palm m130 device, thanks to Udo Eisenbarth + for the information. + + (02/27/2002) gkh + Reworked the urb handling logic. We have no more pool, but dynamically + allocate the urb and the transfer buffer on the fly. In testing this + does not incure any measurable overhead. This also relies on the fact + that we have proper reference counting logic for urbs. + + (02/21/2002) SilaS + Added initial support for the Palm m515 devices. + + (02/14/2002) gkh + Added support for the Clie S-360 device. + + (12/18/2001) gkh + Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand + for the patch. + + (11/11/2001) gkh + Added support for the m125 devices, and added check to prevent oopses + for Clié devices that lie about the number of ports they have. + + (08/30/2001) gkh + Added support for the Clie devices, both the 3.5 and 4.0 os versions. + Many thanks to Daniel Burke, and Bryan Payne for helping with this. + + (08/23/2001) gkh + fixed a few potential bugs pointed out by Oliver Neukum. + + (05/30/2001) gkh + switched from using spinlock to a semaphore, which fixes lots of problems. + + (05/28/2000) gkh + Added initial support for the Palm m500 and Palm m505 devices. + + (04/08/2001) gb + Identify version on module load. + + (01/21/2000) gkh + Added write_room and chars_in_buffer, as they were previously using the + generic driver versions which is all wrong now that we are using an urb + pool. Thanks to Wolfgang Grandegger for pointing this out to me. + Removed count assignment in the write function, which was not needed anymore + either. Thanks to Al Borchers for pointing this out. + + (12/12/2000) gkh + Moved MOD_DEC to end of visor_close to be nicer, as the final write + message can sleep. + + (11/12/2000) gkh + Fixed bug with data being dropped on the floor by forcing tty->low_latency + to be on. Hopefully this fixes the OHCI issue! + + (11/01/2000) Adam J. Richter + usb_device_id table support + + (10/05/2000) gkh + Fixed bug with urb->dev not being set properly, now that the usb + core needs it. + + (09/11/2000) gkh + Got rid of always calling kmalloc for every urb we wrote out to the + device. + Added visor_read_callback so we can keep track of bytes in and out for + those people who like to know the speed of their device. + Removed DEBUG #ifdefs with call to usb_serial_debug_data + + (09/06/2000) gkh + Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_ + the host controller drivers set urb->dev = NULL when the urb is finished. + + (08/28/2000) gkh + Added locks for SMP safeness. + + (08/08/2000) gkh + Fixed endian problem in visor_startup. + Fixed MOD_INC and MOD_DEC logic and the ability to open a port more + than once. + + (07/23/2000) gkh + Added pool of write urbs to speed up transfers to the visor. + + (07/19/2000) gkh + Added module_init and module_exit functions to handle the fact that this + driver is a loadable module now. + + (07/03/2000) gkh + Added visor_set_ioctl and visor_set_termios functions (they don't do much + of anything, but are good for debugging.) + + (06/25/2000) gkh + Fixed bug in visor_unthrottle that should help with the disconnect in PPP + bug that people have been reporting. + + (06/23/2000) gkh + Cleaned up debugging statements in a quest to find UHCI timeout bug. + + (04/27/2000) Ryan VanderBijl + Fixed memory leak in visor_close + + (03/26/2000) gkh + Split driver up into device specific pieces. + +----------------------------------------------------------------------- +pl2303.c Change Log comments: + + 2002_Mar_26 gkh + allowed driver to work properly if there is no tty assigned to a port + (this happens for serial console devices.) + + 2001_Oct_06 gkh + Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it. + + 2001_Sep_19 gkh + Added break support. + + 2001_Aug_30 gkh + fixed oops in write_bulk_callback. + + 2001_Aug_28 gkh + reworked buffer logic to be like other usb-serial drivers. Hopefully + removing some reported problems. + + 2001_Jun_06 gkh + finished porting to 2.4 format. + + +----------------------------------------------------------------------- +io_edgeport.c Change Log comments: + + 2003_04_03 al borchers + - fixed a bug (that shows up with dosemu) where the tty struct is + used in a callback after it has been freed + + 2.3 2002_03_08 greg kroah-hartman + - fixed bug when multiple devices were attached at the same time. + + 2.2 2001_11_14 greg kroah-hartman + - fixed bug in edge_close that kept the port from being used more + than once. + - fixed memory leak on device removal. + - fixed potential double free of memory when command urb submitting + failed. + - other small cleanups when the device is removed + + 2.1 2001_07_09 greg kroah-hartman + - added support for TIOCMBIS and TIOCMBIC. + + (04/08/2001) gb + - Identify version on module load. + + 2.0 2001_03_05 greg kroah-hartman + - reworked entire driver to fit properly in with the other usb-serial + drivers. Occasional oopses still happen, but it's a good start. + + 1.2.3 (02/23/2001) greg kroah-hartman + - changed device table to work properly for 2.4.x final format. + - fixed problem with dropping data at high data rates. + + 1.2.2 (11/27/2000) greg kroah-hartman + - cleaned up more NTisms. + - Added device table for 2.4.0-test11 + + 1.2.1 (11/08/2000) greg kroah-hartman + - Started to clean up NTisms. + - Fixed problem with dev field of urb for kernels >= 2.4.0-test9 + + 1.2 (10/17/2000) David Iacovelli + Remove all EPIC code and GPL source + Fix RELEVANT_IFLAG macro to include flow control + changes port configuration changes. + Fix redefinition of SERIAL_MAGIC + Change all timeout values to 5 seconds + Tried to fix the UHCI multiple urb submission, but failed miserably. + it seems to work fine with OHCI. + ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must + find a way to work arount this UHCI bug ) + + 1.1 (10/11/2000) David Iacovelli + Fix XON/XOFF flow control to support both IXON and IXOFF + + 0.9.27 (06/30/2000) David Iacovelli + Added transmit queue and now allocate urb for command writes. + + 0.9.26 (06/29/2000) David Iacovelli + Add support for 80251 based edgeport + + 0.9.25 (06/27/2000) David Iacovelli + Do not close the port if it has multiple opens. + + 0.9.24 (05/26/2000) David Iacovelli + Add IOCTLs to support RXTX and JAVA POS + and first cut at running BlackBox Demo + + 0.9.23 (05/24/2000) David Iacovelli + Add IOCTLs to support RXTX and JAVA POS + + 0.9.22 (05/23/2000) David Iacovelli + fixed bug in enumeration. If epconfig turns on mapping by + path after a device is already plugged in, we now update + the mapping correctly + + 0.9.21 (05/16/2000) David Iacovelli + Added BlockUntilChaseResp() to also wait for txcredits + Updated the way we allocate and handle write URBs + Add debug code to dump buffers + + 0.9.20 (05/01/2000) David Iacovelli + change driver to use usb/tts/ + + 0.9.19 (05/01/2000) David Iacovelli + Update code to compile if DEBUG is off + + 0.9.18 (04/28/2000) David Iacovelli + cleanup and test tty_register with devfs + + 0.9.17 (04/27/2000) greg kroah-hartman + changed tty_register around to be like the way it + was before, but now it works properly with devfs. + + 0.9.16 (04/26/2000) david iacovelli + Fixed bug in GetProductInfo() + + 0.9.15 (04/25/2000) david iacovelli + Updated enumeration + + 0.9.14 (04/24/2000) david iacovelli + Removed all config/status IOCTLS and + converted to using /proc/edgeport + still playing with devfs + + 0.9.13 (04/24/2000) david iacovelli + Removed configuration based on ttyUSB0 + Added support for configuration using /prod/edgeport + first attempt at using devfs (not working yet!) + Added IOCTL to GetProductInfo() + Added support for custom baud rates + Add support for random port numbers + + 0.9.12 (04/18/2000) david iacovelli + added additional configuration IOCTLs + use ttyUSB0 for configuration + + 0.9.11 (04/17/2000) greg kroah-hartman + fixed module initialization race conditions. + made all urbs dynamically allocated. + made driver devfs compatible. now it only registers the tty device + when the device is actually plugged in. + + 0.9.10 (04/13/2000) greg kroah-hartman + added proc interface framework. + + 0.9.9 (04/13/2000) david iacovelli + added enumeration code and ioctls to configure the device + + 0.9.8 (04/12/2000) david iacovelli + Change interrupt read start when device is plugged in + and stop when device is removed + process interrupt reads when all ports are closed + (keep value of rxBytesAvail consistent with the edgeport) + set the USB_BULK_QUEUE flag so that we can shove a bunch + of urbs at once down the pipe + + 0.9.7 (04/10/2000) david iacovelli + start to add enumeration code. + generate serial number for epic devices + add support for kdb + + 0.9.6 (03/30/2000) david iacovelli + add IOCTL to get string, manufacture, and boot descriptors + + 0.9.5 (03/14/2000) greg kroah-hartman + more error checking added to SerialOpen to try to fix UHCI open problem + + 0.9.4 (03/09/2000) greg kroah-hartman + added more error checking to handle oops when data is hanging + around and tty is abruptly closed. + + 0.9.3 (03/09/2000) david iacovelli + Add epic support for xon/xoff chars + play with performance + + 0.9.2 (03/08/2000) greg kroah-hartman + changed most "info" calls to "dbg" + implemented flow control properly in the termios call + + 0.9.1 (03/08/2000) david iacovelli + added EPIC support + enabled bootloader update + + 0.9 (03/08/2000) greg kroah-hartman + Release to IO networks. + Integrated changes that David made + made getting urbs for writing SMP safe + + 0.8 (03/07/2000) greg kroah-hartman + Release to IO networks. + Fixed problems that were seen in code by David. + Now both Edgeport/4 and Edgeport/2 works properly. + Changed most of the functions to use port instead of serial. + + 0.7 (02/27/2000) greg kroah-hartman + Milestone 3 release. + Release to IO Networks + ioctl for waiting on line change implemented. + ioctl for getting statistics implemented. + multiport support working. + lsr and msr registers are now handled properly. + change break now hooked up and working. + support for all known Edgeport devices. + + 0.6 (02/22/2000) greg kroah-hartman + Release to IO networks. + CHASE is implemented correctly when port is closed. + SerialOpen now blocks correctly until port is fully opened. + + 0.5 (02/20/2000) greg kroah-hartman + Release to IO networks. + Known problems: + modem status register changes are not sent on to the user + CHASE is not implemented when the port is closed. + + 0.4 (02/16/2000) greg kroah-hartman + Second cut at the CeBit demo. + Doesn't leak memory on every write to the port + Still small leaks on startup. + Added support for Edgeport/2 and Edgeport/8 + + 0.3 (02/15/2000) greg kroah-hartman + CeBit demo release. + Force the line settings to 4800, 8, 1, e for the demo. + Warning! This version leaks memory like crazy! + + 0.2 (01/30/2000) greg kroah-hartman + Milestone 1 release. + Device is found by USB subsystem, enumerated, fimware is downloaded + and the descriptors are printed to the debug log, config is set, and + green light starts to blink. Open port works, and data can be sent + and received at the default settings of the UART. Loopback connector + and debug log confirms this. + + 0.1 (01/23/2000) greg kroah-hartman + Initial release to help IO Networks try to set up their test system. + Edgeport4 is recognized, firmware is downloaded, config is set so + device blinks green light every 3 sec. Port is bound, but opening, + closing, and sending data do not work properly. + + diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 04bfe279d763..dc4c498bd1ed 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -27,225 +27,6 @@ * Networks technical support, or Peter Berger , * or Al Borchers . * - * Version history: - * - * 2003_04_03 al borchers - * - fixed a bug (that shows up with dosemu) where the tty struct is - * used in a callback after it has been freed - * - * 2.3 2002_03_08 greg kroah-hartman - * - fixed bug when multiple devices were attached at the same time. - * - * 2.2 2001_11_14 greg kroah-hartman - * - fixed bug in edge_close that kept the port from being used more - * than once. - * - fixed memory leak on device removal. - * - fixed potential double free of memory when command urb submitting - * failed. - * - other small cleanups when the device is removed - * - * 2.1 2001_07_09 greg kroah-hartman - * - added support for TIOCMBIS and TIOCMBIC. - * - * (04/08/2001) gb - * - Identify version on module load. - * - * 2.0 2001_03_05 greg kroah-hartman - * - reworked entire driver to fit properly in with the other usb-serial - * drivers. Occasional oopses still happen, but it's a good start. - * - * 1.2.3 (02/23/2001) greg kroah-hartman - * - changed device table to work properly for 2.4.x final format. - * - fixed problem with dropping data at high data rates. - * - * 1.2.2 (11/27/2000) greg kroah-hartman - * - cleaned up more NTisms. - * - Added device table for 2.4.0-test11 - * - * 1.2.1 (11/08/2000) greg kroah-hartman - * - Started to clean up NTisms. - * - Fixed problem with dev field of urb for kernels >= 2.4.0-test9 - * - * 1.2 (10/17/2000) David Iacovelli - * Remove all EPIC code and GPL source - * Fix RELEVANT_IFLAG macro to include flow control - * changes port configuration changes. - * Fix redefinition of SERIAL_MAGIC - * Change all timeout values to 5 seconds - * Tried to fix the UHCI multiple urb submission, but failed miserably. - * it seems to work fine with OHCI. - * ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must - * find a way to work arount this UHCI bug ) - * - * 1.1 (10/11/2000) David Iacovelli - * Fix XON/XOFF flow control to support both IXON and IXOFF - * - * 0.9.27 (06/30/2000) David Iacovelli - * Added transmit queue and now allocate urb for command writes. - * - * 0.9.26 (06/29/2000) David Iacovelli - * Add support for 80251 based edgeport - * - * 0.9.25 (06/27/2000) David Iacovelli - * Do not close the port if it has multiple opens. - * - * 0.9.24 (05/26/2000) David Iacovelli - * Add IOCTLs to support RXTX and JAVA POS - * and first cut at running BlackBox Demo - * - * 0.9.23 (05/24/2000) David Iacovelli - * Add IOCTLs to support RXTX and JAVA POS - * - * 0.9.22 (05/23/2000) David Iacovelli - * fixed bug in enumeration. If epconfig turns on mapping by - * path after a device is already plugged in, we now update - * the mapping correctly - * - * 0.9.21 (05/16/2000) David Iacovelli - * Added BlockUntilChaseResp() to also wait for txcredits - * Updated the way we allocate and handle write URBs - * Add debug code to dump buffers - * - * 0.9.20 (05/01/2000) David Iacovelli - * change driver to use usb/tts/ - * - * 0.9.19 (05/01/2000) David Iacovelli - * Update code to compile if DEBUG is off - * - * 0.9.18 (04/28/2000) David Iacovelli - * cleanup and test tty_register with devfs - * - * 0.9.17 (04/27/2000) greg kroah-hartman - * changed tty_register around to be like the way it - * was before, but now it works properly with devfs. - * - * 0.9.16 (04/26/2000) david iacovelli - * Fixed bug in GetProductInfo() - * - * 0.9.15 (04/25/2000) david iacovelli - * Updated enumeration - * - * 0.9.14 (04/24/2000) david iacovelli - * Removed all config/status IOCTLS and - * converted to using /proc/edgeport - * still playing with devfs - * - * 0.9.13 (04/24/2000) david iacovelli - * Removed configuration based on ttyUSB0 - * Added support for configuration using /prod/edgeport - * first attempt at using devfs (not working yet!) - * Added IOCTL to GetProductInfo() - * Added support for custom baud rates - * Add support for random port numbers - * - * 0.9.12 (04/18/2000) david iacovelli - * added additional configuration IOCTLs - * use ttyUSB0 for configuration - * - * 0.9.11 (04/17/2000) greg kroah-hartman - * fixed module initialization race conditions. - * made all urbs dynamically allocated. - * made driver devfs compatible. now it only registers the tty device - * when the device is actually plugged in. - * - * 0.9.10 (04/13/2000) greg kroah-hartman - * added proc interface framework. - * - * 0.9.9 (04/13/2000) david iacovelli - * added enumeration code and ioctls to configure the device - * - * 0.9.8 (04/12/2000) david iacovelli - * Change interrupt read start when device is plugged in - * and stop when device is removed - * process interrupt reads when all ports are closed - * (keep value of rxBytesAvail consistent with the edgeport) - * set the USB_BULK_QUEUE flag so that we can shove a bunch - * of urbs at once down the pipe - * - * 0.9.7 (04/10/2000) david iacovelli - * start to add enumeration code. - * generate serial number for epic devices - * add support for kdb - * - * 0.9.6 (03/30/2000) david iacovelli - * add IOCTL to get string, manufacture, and boot descriptors - * - * 0.9.5 (03/14/2000) greg kroah-hartman - * more error checking added to SerialOpen to try to fix UHCI open problem - * - * 0.9.4 (03/09/2000) greg kroah-hartman - * added more error checking to handle oops when data is hanging - * around and tty is abruptly closed. - * - * 0.9.3 (03/09/2000) david iacovelli - * Add epic support for xon/xoff chars - * play with performance - * - * 0.9.2 (03/08/2000) greg kroah-hartman - * changed most "info" calls to "dbg" - * implemented flow control properly in the termios call - * - * 0.9.1 (03/08/2000) david iacovelli - * added EPIC support - * enabled bootloader update - * - * 0.9 (03/08/2000) greg kroah-hartman - * Release to IO networks. - * Integrated changes that David made - * made getting urbs for writing SMP safe - * - * 0.8 (03/07/2000) greg kroah-hartman - * Release to IO networks. - * Fixed problems that were seen in code by David. - * Now both Edgeport/4 and Edgeport/2 works properly. - * Changed most of the functions to use port instead of serial. - * - * 0.7 (02/27/2000) greg kroah-hartman - * Milestone 3 release. - * Release to IO Networks - * ioctl for waiting on line change implemented. - * ioctl for getting statistics implemented. - * multiport support working. - * lsr and msr registers are now handled properly. - * change break now hooked up and working. - * support for all known Edgeport devices. - * - * 0.6 (02/22/2000) greg kroah-hartman - * Release to IO networks. - * CHASE is implemented correctly when port is closed. - * SerialOpen now blocks correctly until port is fully opened. - * - * 0.5 (02/20/2000) greg kroah-hartman - * Release to IO networks. - * Known problems: - * modem status register changes are not sent on to the user - * CHASE is not implemented when the port is closed. - * - * 0.4 (02/16/2000) greg kroah-hartman - * Second cut at the CeBit demo. - * Doesn't leak memory on every write to the port - * Still small leaks on startup. - * Added support for Edgeport/2 and Edgeport/8 - * - * 0.3 (02/15/2000) greg kroah-hartman - * CeBit demo release. - * Force the line settings to 4800, 8, 1, e for the demo. - * Warning! This version leaks memory like crazy! - * - * 0.2 (01/30/2000) greg kroah-hartman - * Milestone 1 release. - * Device is found by USB subsystem, enumerated, fimware is downloaded - * and the descriptors are printed to the debug log, config is set, and - * green light starts to blink. Open port works, and data can be sent - * and received at the default settings of the UART. Loopback connector - * and debug log confirms this. - * - * 0.1 (01/23/2000) greg kroah-hartman - * Initial release to help IO Networks try to set up their test system. - * Edgeport4 is recognized, firmware is downloaded, config is set so - * device blinks green light every 3 sec. Port is bound, but opening, - * closing, and sending data do not work properly. - * */ #include diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index beef3c4cee6e..29719ceab19a 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -8,31 +8,10 @@ * * 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. + * the Free Software Foundation; either version 2 of the License. * * See Documentation/usb/usb-serial.txt for more information on using this driver * - * 2002_Mar_26 gkh - * allowed driver to work properly if there is no tty assigned to a port - * (this happens for serial console devices.) - * - * 2001_Oct_06 gkh - * Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it. - * - * 2001_Sep_19 gkh - * Added break support. - * - * 2001_Aug_30 gkh - * fixed oops in write_bulk_callback. - * - * 2001_Aug_28 gkh - * reworked buffer logic to be like other usb-serial drivers. Hopefully - * removing some reported problems. - * - * 2001_Jun_06 gkh - * finished porting to 2.4 format. - * */ #include diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 08f600327db4..fde09fba8790 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1,7 +1,7 @@ /* * USB Serial Converter driver * - * Copyright (C) 1999 - 2004 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2000 Peter Berger (pberger@brimson.com) * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) * @@ -9,316 +9,11 @@ * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. * - * This driver was originally based on the ACM driver by Armin Fuerst (which was + * This driver was originally based on the ACM driver by Armin Fuerst (which was * based on a driver by Brad Keryan) * * See Documentation/usb/usb-serial.txt for more information on using this driver * - * (12/10/2002) gkh - * Split the ports off into their own struct device, and added a - * usb-serial bus driver. - * - * (11/19/2002) gkh - * removed a few #ifdefs for the generic code and cleaned up the failure - * logic in initialization. - * - * (10/02/2002) gkh - * moved the console code to console.c and out of this file. - * - * (06/05/2002) gkh - * moved location of startup() call in serial_probe() until after all - * of the port information and endpoints are initialized. This makes - * things easier for some drivers. - * - * (04/10/2002) gkh - * added serial_read_proc function which creates a - * /proc/tty/driver/usb-serial file. - * - * (03/27/2002) gkh - * Got USB serial console code working properly and merged into the main - * version of the tree. Thanks to Randy Dunlap for the initial version - * of this code, and for pushing me to finish it up. - * The USB serial console works with any usb serial driver device. - * - * (03/21/2002) gkh - * Moved all manipulation of port->open_count into the core. Now the - * individual driver's open and close functions are called only when the - * first open() and last close() is called. Making the drivers a bit - * smaller and simpler. - * Fixed a bug if a driver didn't have the owner field set. - * - * (02/26/2002) gkh - * Moved all locking into the main serial_* functions, instead of having - * the individual drivers have to grab the port semaphore. This should - * reduce races. - * Reworked the MOD_INC logic a bit to always increment and decrement, even - * if the generic driver is being used. - * - * (10/10/2001) gkh - * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to - * help prevent child drivers from accessing the device since it is now - * gone. - * - * (09/13/2001) gkh - * Moved generic driver initialize after we have registered with the USB - * core. Thanks to Randy Dunlap for pointing this problem out. - * - * (07/03/2001) gkh - * Fixed module paramater size. Thanks to John Brockmeyer for the pointer. - * Fixed vendor and product getting defined through the MODULE_PARM macro - * if the Generic driver wasn't compiled in. - * Fixed problem with generic_shutdown() not being called for drivers that - * don't have a shutdown() function. - * - * (06/06/2001) gkh - * added evil hack that is needed for the prolific pl2303 device due to the - * crazy way its endpoints are set up. - * - * (05/30/2001) gkh - * switched from using spinlock to a semaphore, which fixes lots of problems. - * - * (04/08/2001) gb - * Identify version on module load. - * - * 2001_02_05 gkh - * Fixed buffer overflows bug with the generic serial driver. Thanks to - * Todd Squires for fixing this. - * - * (01/10/2001) gkh - * Fixed bug where the generic serial adaptor grabbed _any_ device that was - * offered to it. - * - * (12/12/2000) gkh - * Removed MOD_INC and MOD_DEC from poll and disconnect functions, and - * moved them to the serial_open and serial_close functions. - * Also fixed bug with there not being a MOD_DEC for the generic driver - * (thanks to Gary Brubaker for finding this.) - * - * (11/29/2000) gkh - * Small NULL pointer initialization cleanup which saves a bit of disk image - * - * (11/01/2000) Adam J. Richter - * instead of using idVendor/idProduct pairs, usb serial drivers - * now identify their hardware interest with usb_device_id tables, - * which they usually have anyhow for use with MODULE_DEVICE_TABLE. - * - * (10/05/2000) gkh - * Fixed bug with urb->dev not being set properly, now that the usb - * core needs it. - * - * (09/11/2000) gkh - * Removed DEBUG #ifdefs with call to usb_serial_debug_data - * - * (08/28/2000) gkh - * Added port_lock to port structure. - * Added locks for SMP safeness to generic driver - * Fixed the ability to open a generic device's port more than once. - * - * (07/23/2000) gkh - * Added bulk_out_endpointAddress to port structure. - * - * (07/19/2000) gkh, pberger, and borchers - * Modifications to allow usb-serial drivers to be modules. - * - * (07/03/2000) gkh - * Added more debugging to serial_ioctl call - * - * (06/25/2000) gkh - * Changed generic_write_bulk_callback to not call wake_up_interruptible - * directly, but to have port_softint do it at a safer time. - * - * (06/23/2000) gkh - * Cleaned up debugging statements in a quest to find UHCI timeout bug. - * - * (05/22/2000) gkh - * Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be - * removed from the individual device source files. - * - * (05/03/2000) gkh - * Added the Digi Acceleport driver from Al Borchers and Peter Berger. - * - * (05/02/2000) gkh - * Changed devfs and tty register code to work properly now. This was based on - * the ACM driver changes by Vojtech Pavlik. - * - * (04/27/2000) Ryan VanderBijl - * Put calls to *_paranoia_checks into one function. - * - * (04/23/2000) gkh - * Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. - * Moved when the startup code printed out the devices that are supported. - * - * (04/19/2000) gkh - * Added driver for ZyXEL omni.net lcd plus ISDN TA - * Made startup info message specify which drivers were compiled in. - * - * (04/03/2000) gkh - * Changed the probe process to remove the module unload races. - * Changed where the tty layer gets initialized to have devfs work nicer. - * Added initial devfs support. - * - * (03/26/2000) gkh - * Split driver up into device specific pieces. - * - * (03/19/2000) gkh - * Fixed oops that could happen when device was removed while a program - * was talking to the device. - * Removed the static urbs and now all urbs are created and destroyed - * dynamically. - * Reworked the internal interface. Now everything is based on the - * usb_serial_port structure instead of the larger usb_serial structure. - * This fixes the bug that a multiport device could not have more than - * one port open at one time. - * - * (03/17/2000) gkh - * Added config option for debugging messages. - * Added patch for keyspan pda from Brian Warner. - * - * (03/06/2000) gkh - * Added the keyspan pda code from Brian Warner - * Moved a bunch of the port specific stuff into its own structure. This - * is in anticipation of the true multiport devices (there's a bug if you - * try to access more than one port of any multiport device right now) - * - * (02/21/2000) gkh - * Made it so that any serial devices only have to specify which functions - * they want to overload from the generic function calls (great, - * inheritance in C, in a driver, just what I wanted...) - * Added support for set_termios and ioctl function calls. No drivers take - * advantage of this yet. - * Removed the #ifdef MODULE, now there is no module specific code. - * Cleaned up a few comments in usb-serial.h that were wrong (thanks again - * to Miles Lott). - * Small fix to get_free_serial. - * - * (02/14/2000) gkh - * Removed the Belkin and Peracom functionality from the driver due to - * the lack of support from the vendor, and me not wanting people to - * accidenatly buy the device, expecting it to work with Linux. - * Added read_bulk_callback and write_bulk_callback to the type structure - * for the needs of the FTDI and WhiteHEAT driver. - * Changed all reverences to FTDI to FTDI_SIO at the request of Bill - * Ryder. - * Changed the output urb size back to the max endpoint size to make - * the ftdi_sio driver have it easier, and due to the fact that it didn't - * really increase the speed any. - * - * (02/11/2000) gkh - * Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a - * patch from Miles Lott (milos@insync.net). - * Fixed bug with not restoring the minor range that a device grabs, if - * the startup function fails (thanks Miles for finding this). - * - * (02/05/2000) gkh - * Added initial framework for the Keyspan PDA serial converter so that - * Brian Warner has a place to put his code. - * Made the ezusb specific functions generic enough that different - * devices can use them (whiteheat and keyspan_pda both need them). - * Split out a whole bunch of structure and other stuff to a separate - * usb-serial.h file. - * Made the Visor connection messages a little more understandable, now - * that Miles Lott (milos@insync.net) has gotten the Generic channel to - * work. Also made them always show up in the log file. - * - * (01/25/2000) gkh - * Added initial framework for FTDI serial converter so that Bill Ryder - * has a place to put his code. - * Added the vendor specific info from Handspring. Now we can print out - * informational debug messages as well as understand what is happening. - * - * (01/23/2000) gkh - * Fixed problem of crash when trying to open a port that didn't have a - * device assigned to it. Made the minor node finding a little smarter, - * now it looks to find a continuous space for the new device. - * - * (01/21/2000) gkh - * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) - * Fixed get_serial_by_minor which was all messed up for multi port - * devices. Fixed multi port problem for generic devices. Now the number - * of ports is determined by the number of bulk out endpoints for the - * generic device. - * - * (01/19/2000) gkh - * Removed lots of cruft that was around from the old (pre urb) driver - * interface. - * Made the serial_table dynamic. This should save lots of memory when - * the number of minor nodes goes up to 256. - * Added initial support for devices that have more than one port. - * Added more debugging comments for the Visor, and added a needed - * set_configuration call. - * - * (01/17/2000) gkh - * Fixed the WhiteHEAT firmware (my processing tool had a bug) - * and added new debug loader firmware for it. - * Removed the put_char function as it isn't really needed. - * Added visor startup commands as found by the Win98 dump. - * - * (01/13/2000) gkh - * Fixed the vendor id for the generic driver to the one I meant it to be. - * - * (01/12/2000) gkh - * Forget the version numbering...that's pretty useless... - * Made the driver able to be compiled so that the user can select which - * converter they want to use. This allows people who only want the Visor - * support to not pay the memory size price of the WhiteHEAT. - * Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) - * grabbed the root hub. Not good. - * - * version 0.4.0 (01/10/2000) gkh - * Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT - * device. Added startup function to allow firmware to be downloaded to - * a device if it needs to be. - * Added firmware download logic to the WhiteHEAT device. - * Started to add #defines to split up the different drivers for potential - * configuration option. - * - * version 0.3.1 (12/30/99) gkh - * Fixed problems with urb for bulk out. - * Added initial support for multiple sets of endpoints. This enables - * the Handspring Visor to be attached successfully. Only the first - * bulk in / bulk out endpoint pair is being used right now. - * - * version 0.3.0 (12/27/99) gkh - * Added initial support for the Handspring Visor based on a patch from - * Miles Lott (milos@sneety.insync.net) - * Cleaned up the code a bunch and converted over to using urbs only. - * - * version 0.2.3 (12/21/99) gkh - * Added initial support for the Connect Tech WhiteHEAT converter. - * Incremented the number of ports in expectation of getting the - * WhiteHEAT to work properly (4 ports per connection). - * Added notification on insertion and removal of what port the - * device is/was connected to (and what kind of device it was). - * - * version 0.2.2 (12/16/99) gkh - * Changed major number to the new allocated number. We're legal now! - * - * version 0.2.1 (12/14/99) gkh - * Fixed bug that happens when device node is opened when there isn't a - * device attached to it. Thanks to marek@webdesign.no for noticing this. - * - * version 0.2.0 (11/10/99) gkh - * Split up internals to make it easier to add different types of serial - * converters to the code. - * Added a "generic" driver that gets it's vendor and product id - * from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) - * for the idea and sample code (from the usb scanner driver.) - * Cleared up any licensing questions by releasing it under the GNU GPL. - * - * version 0.1.2 (10/25/99) gkh - * Fixed bug in detecting device. - * - * version 0.1.1 (10/05/99) gkh - * Changed the major number to not conflict with anything else. - * - * version 0.1 (09/28/99) gkh - * Can recognize the two different devices and start up a read from - * device when asked to. Writes also work. No control signals yet, this - * all is vendor specific data (i.e. no spec), also no control for - * different baud rates or other bit settings. - * Currently we are using the same devid as the acm driver. This needs - * to change. - * */ #include diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 4ca5e0c05611..1cedc1999508 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -1,53 +1,13 @@ /* * USB Serial Converter driver * - * Copyright (C) 1999 - 2004 + * Copyright (C) 1999 - 2005 * Greg Kroah-Hartman (greg@kroah.com) * * 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. + * the Free Software Foundation; either version 2 of the License. * - * See Documentation/usb/usb-serial.txt for more information on using this driver - * - * (03/26/2002) gkh - * removed the port->tty check from port_paranoia_check() due to serial - * consoles not having a tty device assigned to them. - * - * (12/03/2001) gkh - * removed active from the port structure. - * added documentation to the usb_serial_device_type structure - * - * (10/10/2001) gkh - * added vendor and product to serial structure. Needed to determine device - * owner when the device is disconnected. - * - * (05/30/2001) gkh - * added sem to port structure and removed port_lock - * - * (10/05/2000) gkh - * Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help - * fix bug with urb->dev not being set properly, now that the usb core - * needs it. - * - * (09/11/2000) gkh - * Added usb_serial_debug_data function to help get rid of #DEBUG in the - * drivers. - * - * (08/28/2000) gkh - * Added port_lock to port structure. - * - * (08/08/2000) gkh - * Added open_count to port structure. - * - * (07/23/2000) gkh - * Added bulk_out_endpointAddress to port structure. - * - * (07/19/2000) gkh, pberger, and borchers - * Modifications to allow usb-serial drivers to be modules. - * - * */ diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 0ac0377e8683..39ad0cab8635 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -7,139 +7,10 @@ * * 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. + * the Free Software Foundation; either version 2 of the License. * * See Documentation/usb/usb-serial.txt for more information on using this driver * - * (06/03/2003) Judd Montgomery - * Added support for module parameter options for untested/unknown - * devices. - * - * (03/09/2003) gkh - * Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl - * for the information. - * - * (03/05/2003) gkh - * Think Treo support is now working. - * - * (04/03/2002) gkh - * Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI - * for the information. - * - * (03/27/2002) gkh - * Removed assumptions that port->tty was always valid (is not true - * for usb serial console devices.) - * - * (03/23/2002) gkh - * Added support for the Palm i705 device, thanks to Thomas Riemer - * for the information. - * - * (03/21/2002) gkh - * Added support for the Palm m130 device, thanks to Udo Eisenbarth - * for the information. - * - * (02/27/2002) gkh - * Reworked the urb handling logic. We have no more pool, but dynamically - * allocate the urb and the transfer buffer on the fly. In testing this - * does not incure any measurable overhead. This also relies on the fact - * that we have proper reference counting logic for urbs. - * - * (02/21/2002) SilaS - * Added initial support for the Palm m515 devices. - * - * (02/14/2002) gkh - * Added support for the Clie S-360 device. - * - * (12/18/2001) gkh - * Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand - * for the patch. - * - * (11/11/2001) gkh - * Added support for the m125 devices, and added check to prevent oopses - * for Clié devices that lie about the number of ports they have. - * - * (08/30/2001) gkh - * Added support for the Clie devices, both the 3.5 and 4.0 os versions. - * Many thanks to Daniel Burke, and Bryan Payne for helping with this. - * - * (08/23/2001) gkh - * fixed a few potential bugs pointed out by Oliver Neukum. - * - * (05/30/2001) gkh - * switched from using spinlock to a semaphore, which fixes lots of problems. - * - * (05/28/2000) gkh - * Added initial support for the Palm m500 and Palm m505 devices. - * - * (04/08/2001) gb - * Identify version on module load. - * - * (01/21/2000) gkh - * Added write_room and chars_in_buffer, as they were previously using the - * generic driver versions which is all wrong now that we are using an urb - * pool. Thanks to Wolfgang Grandegger for pointing this out to me. - * Removed count assignment in the write function, which was not needed anymore - * either. Thanks to Al Borchers for pointing this out. - * - * (12/12/2000) gkh - * Moved MOD_DEC to end of visor_close to be nicer, as the final write - * message can sleep. - * - * (11/12/2000) gkh - * Fixed bug with data being dropped on the floor by forcing tty->low_latency - * to be on. Hopefully this fixes the OHCI issue! - * - * (11/01/2000) Adam J. Richter - * usb_device_id table support - * - * (10/05/2000) gkh - * Fixed bug with urb->dev not being set properly, now that the usb - * core needs it. - * - * (09/11/2000) gkh - * Got rid of always calling kmalloc for every urb we wrote out to the - * device. - * Added visor_read_callback so we can keep track of bytes in and out for - * those people who like to know the speed of their device. - * Removed DEBUG #ifdefs with call to usb_serial_debug_data - * - * (09/06/2000) gkh - * Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_ - * the host controller drivers set urb->dev = NULL when the urb is finished. - * - * (08/28/2000) gkh - * Added locks for SMP safeness. - * - * (08/08/2000) gkh - * Fixed endian problem in visor_startup. - * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more - * than once. - * - * (07/23/2000) gkh - * Added pool of write urbs to speed up transfers to the visor. - * - * (07/19/2000) gkh - * Added module_init and module_exit functions to handle the fact that this - * driver is a loadable module now. - * - * (07/03/2000) gkh - * Added visor_set_ioctl and visor_set_termios functions (they don't do much - * of anything, but are good for debugging.) - * - * (06/25/2000) gkh - * Fixed bug in visor_unthrottle that should help with the disconnect in PPP - * bug that people have been reporting. - * - * (06/23/2000) gkh - * Cleaned up debugging statements in a quest to find UHCI timeout bug. - * - * (04/27/2000) Ryan VanderBijl - * Fixed memory leak in visor_close - * - * (03/26/2000) gkh - * Split driver up into device specific pieces. - * */ #include From 269bda1c123c7caf88e1deb2264f9086f0344192 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0883/1940] [PATCH] USB Serial: move name to driver structure This fixes up a lot of problems in sysfs with some of the usb serial drivers, they had incorrect driver names. Also saves a tiny ammount of memory. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 2 +- drivers/usb/serial/belkin_sa.c | 4 ++-- drivers/usb/serial/bus.c | 8 ++----- drivers/usb/serial/cp2101.c | 4 ++-- drivers/usb/serial/cyberjack.c | 4 ++-- drivers/usb/serial/cypress_m8.c | 8 +++---- drivers/usb/serial/digi_acceleport.c | 12 +++++------ drivers/usb/serial/empeg.c | 2 +- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/garmin_gps.c | 4 ++-- drivers/usb/serial/generic.c | 3 +-- drivers/usb/serial/hp4x.c | 4 ++-- drivers/usb/serial/io_tables.h | 12 +++++------ drivers/usb/serial/io_ti.c | 12 +++++------ drivers/usb/serial/ipaq.c | 3 ++- drivers/usb/serial/ipw.c | 4 ++-- drivers/usb/serial/ir-usb.c | 3 ++- drivers/usb/serial/keyspan.h | 16 +++++++------- drivers/usb/serial/keyspan_pda.c | 12 +++++------ drivers/usb/serial/kl5kusb105.c | 4 ++-- drivers/usb/serial/kobil_sct.c | 3 ++- drivers/usb/serial/mct_u232.c | 4 ++-- drivers/usb/serial/omninet.c | 4 ++-- drivers/usb/serial/option.c | 4 ++-- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/safe_serial.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 10 +++++---- drivers/usb/serial/usb-serial.c | 15 ++++++++------ drivers/usb/serial/usb-serial.h | 12 +++++------ drivers/usb/serial/visor.c | 18 ++++++++-------- drivers/usb/serial/whiteheat.c | 30 +++++++++++++-------------- 31 files changed, 115 insertions(+), 114 deletions(-) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index fbc5b9b44749..1f29d8837327 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -33,8 +33,8 @@ static struct usb_driver airprime_driver = { static struct usb_serial_driver airprime_device = { .driver = { .owner = THIS_MODULE, + .name = "airprime", }, - .name = "airprime", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 4878961a0900..84bc0ee4f061 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -124,9 +124,9 @@ static struct usb_driver belkin_driver = { static struct usb_serial_driver belkin_device = { .driver = { .owner = THIS_MODULE, + .name = "belkin", }, - .name = "Belkin / Peracom / GoHubs USB Serial Adapter", - .short_name = "belkin", + .description = "Belkin / Peracom / GoHubs USB Serial Adapter", .id_table = id_table_combined, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index b8364a8de7df..664139afcfa9 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -72,7 +72,7 @@ static int usb_serial_device_probe (struct device *dev) tty_register_device (usb_serial_tty_driver, minor, dev); dev_info(&port->serial->dev->dev, "%s converter now attached to ttyUSB%d\n", - driver->name, minor); + driver->description, minor); exit: return retval; @@ -104,7 +104,7 @@ static int usb_serial_device_remove (struct device *dev) minor = port->number; tty_unregister_device (usb_serial_tty_driver, minor); dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", - driver->name, minor); + driver->description, minor); return retval; } @@ -113,10 +113,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) { int retval; - if (driver->short_name) - driver->driver.name = (char *)driver->short_name; - else - driver->driver.name = (char *)driver->name; driver->driver.bus = &usb_serial_bus_type; driver->driver.probe = usb_serial_device_probe; driver->driver.remove = usb_serial_device_remove; diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 81dd720a122b..c5334dd89b12 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -67,7 +67,7 @@ MODULE_DEVICE_TABLE (usb, id_table); static struct usb_driver cp2101_driver = { .owner = THIS_MODULE, - .name = "CP2101", + .name = "cp2101", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, @@ -76,8 +76,8 @@ static struct usb_driver cp2101_driver = { static struct usb_serial_driver cp2101_device = { .driver = { .owner = THIS_MODULE, + .name = "cp2101", }, - .name = "CP2101", .id_table = id_table, .num_interrupt_in = 0, .num_bulk_in = 0, diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 3441bad74f7b..e581e4ae8483 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -86,9 +86,9 @@ static struct usb_driver cyberjack_driver = { static struct usb_serial_driver cyberjack_device = { .driver = { .owner = THIS_MODULE, + .name = "cyberjack", }, - .name = "Reiner SCT Cyberjack USB card reader", - .short_name = "cyberjack", + .description = "Reiner SCT Cyberjack USB card reader", .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index b4069af4d565..af9290ed257b 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -179,9 +179,9 @@ static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigne static struct usb_serial_driver cypress_earthmate_device = { .driver = { .owner = THIS_MODULE, + .name = "earthmate", }, - .name = "DeLorme Earthmate USB", - .short_name = "earthmate", + .description = "DeLorme Earthmate USB", .id_table = id_table_earthmate, .num_interrupt_in = 1, .num_interrupt_out = 1, @@ -208,9 +208,9 @@ static struct usb_serial_driver cypress_earthmate_device = { static struct usb_serial_driver cypress_hidcom_device = { .driver = { .owner = THIS_MODULE, + .name = "cyphidcom", }, - .name = "HID->COM RS232 Adapter", - .short_name = "cyphidcom", + .description = "HID->COM RS232 Adapter", .id_table = id_table_cyphidcomrs232, .num_interrupt_in = 1, .num_interrupt_out = 1, diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index be9b495d2491..dc74644a603d 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -505,10 +505,10 @@ static struct usb_driver digi_driver = { static struct usb_serial_driver digi_acceleport_2_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "digi_2", }, - .name = "Digi 2 port USB adapter", - .short_name = "digi_2", + .description = "Digi 2 port USB adapter", .id_table = id_table_2, .num_interrupt_in = 0, .num_bulk_in = 4, @@ -534,10 +534,10 @@ static struct usb_serial_driver digi_acceleport_2_device = { static struct usb_serial_driver digi_acceleport_4_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "digi_4", }, - .name = "Digi 4 port USB adapter", - .short_name = "digi_4", + .description = "Digi 4 port USB adapter", .id_table = id_table_4, .num_interrupt_in = 0, .num_bulk_in = 5, diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 3e6c4ba7667b..0b0546dcc7b9 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -115,8 +115,8 @@ static struct usb_driver empeg_driver = { static struct usb_serial_driver empeg_device = { .driver = { .owner = THIS_MODULE, + .name = "empeg", }, - .name = "Empeg", .id_table = id_table, .num_interrupt_in = 0, .num_bulk_in = 1, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9d945de0acac..77d54ac39a0e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -565,9 +565,9 @@ static __u32 ftdi_232bm_baud_to_divisor (int baud); static struct usb_serial_driver ftdi_sio_device = { .driver = { .owner = THIS_MODULE, + .name = "ftdi_sio", }, - .name = "FTDI USB Serial Device", - .short_name = "ftdi_sio", + .description = "FTDI USB Serial Device", .id_table = id_table_combined, .num_interrupt_in = 0, .num_bulk_in = 1, diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 3fd98c00cd6a..35820bda7ae1 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1472,9 +1472,9 @@ static void garmin_shutdown (struct usb_serial *serial) static struct usb_serial_driver garmin_device = { .driver = { .owner = THIS_MODULE, + .name = "garmin_gps", }, - .name = "Garmin GPS usb/tty", - .short_name = "garmin_gps", + .description = "Garmin GPS usb/tty", .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 779bea0c6242..8909208f506a 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -39,9 +39,8 @@ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ struct usb_serial_driver usb_serial_generic_device = { .driver = { .owner = THIS_MODULE, + .name = "generic", }, - .name = "Generic", - .short_name = "generic", .id_table = generic_device_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 4f3cbc08c4ee..8eadfb705601 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -38,7 +38,7 @@ MODULE_DEVICE_TABLE(usb, id_table); static struct usb_driver hp49gp_driver = { .owner = THIS_MODULE, - .name = "HP4X", + .name = "hp4X", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, @@ -47,8 +47,8 @@ static struct usb_driver hp49gp_driver = { static struct usb_serial_driver hp49gp_device = { .driver = { .owner = THIS_MODULE, + .name = "hp4X", }, - .name = "HP4X", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 28fb0d42a166..fad561c04c76 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); static struct usb_serial_driver edgeport_2port_device = { .driver = { .owner = THIS_MODULE, + .name = "edgeport_2", }, - .name = "Edgeport 2 port adapter", - .short_name = "edgeport_2", + .description = "Edgeport 2 port adapter", .id_table = edgeport_2port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -108,9 +108,9 @@ static struct usb_serial_driver edgeport_2port_device = { static struct usb_serial_driver edgeport_4port_device = { .driver = { .owner = THIS_MODULE, + .name = "edgeport_4", }, - .name = "Edgeport 4 port adapter", - .short_name = "edgeport_4", + .description = "Edgeport 4 port adapter", .id_table = edgeport_4port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -138,9 +138,9 @@ static struct usb_serial_driver edgeport_4port_device = { static struct usb_serial_driver edgeport_8port_device = { .driver = { .owner = THIS_MODULE, + .name = "edgeport_8", }, - .name = "Edgeport 8 port adapter", - .short_name = "edgeport_8", + .description = "Edgeport 8 port adapter", .id_table = edgeport_8port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 74228a072643..832b6d6734c0 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2984,10 +2984,10 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, static struct usb_serial_driver edgeport_1port_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "edgeport_ti_1", }, - .name = "Edgeport TI 1 port adapter", - .short_name = "edgeport_ti_1", + .description = "Edgeport TI 1 port adapter", .id_table = edgeport_1port_id_table, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -3014,10 +3014,10 @@ static struct usb_serial_driver edgeport_1port_device = { static struct usb_serial_driver edgeport_2port_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "edgeport_ti_2", }, - .name = "Edgeport TI 2 port adapter", - .short_name = "edgeport_ti_2", + .description = "Edgeport TI 2 port adapter", .id_table = edgeport_2port_id_table, .num_interrupt_in = 1, .num_bulk_in = 2, diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 9aedfb91b20c..1abaebe6dbc1 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -550,8 +550,9 @@ static struct usb_driver ipaq_driver = { static struct usb_serial_driver ipaq_device = { .driver = { .owner = THIS_MODULE, + .name = "ipaq", }, - .name = "PocketPC PDA", + .description = "PocketPC PDA", .id_table = ipaq_id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 2ba69623ac05..a02fada85362 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -446,9 +446,9 @@ static int ipw_disconnect(struct usb_serial_port *port) static struct usb_serial_driver ipw_device = { .driver = { .owner = THIS_MODULE, + .name = "ipw", }, - .name = "IPWireless converter", - .short_name = "ipw", + .description = "IPWireless converter", .id_table = usb_ipw_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index bf079059819e..19f329e9bdcf 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -136,8 +136,9 @@ static struct usb_driver ir_driver = { static struct usb_serial_driver ir_device = { .driver = { .owner = THIS_MODULE, + .name = "ir-usb", }, - .name = "IR Dongle", + .description = "IR Dongle", .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 124d46e76a2e..5cfc13b5e56f 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -573,9 +573,9 @@ static struct usb_device_id keyspan_4port_ids[] = { static struct usb_serial_driver keyspan_pre_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_no_firm", }, - .name = "Keyspan - (without firmware)", - .short_name = "keyspan_no_firm", + .description = "Keyspan - (without firmware)", .id_table = keyspan_pre_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -587,9 +587,9 @@ static struct usb_serial_driver keyspan_pre_device = { static struct usb_serial_driver keyspan_1port_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_1", }, - .name = "Keyspan 1 port adapter", - .short_name = "keyspan_1", + .description = "Keyspan 1 port adapter", .id_table = keyspan_1port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -614,9 +614,9 @@ static struct usb_serial_driver keyspan_1port_device = { static struct usb_serial_driver keyspan_2port_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_2", }, - .name = "Keyspan 2 port adapter", - .short_name = "keyspan_2", + .description = "Keyspan 2 port adapter", .id_table = keyspan_2port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -641,9 +641,9 @@ static struct usb_serial_driver keyspan_2port_device = { static struct usb_serial_driver keyspan_4port_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_4", }, - .name = "Keyspan 4 port adapter", - .short_name = "keyspan_4", + .description = "Keyspan 4 port adapter", .id_table = keyspan_4port_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 5, diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 389b7833e3ae..cd4f48bd83b6 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -786,9 +786,9 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) static struct usb_serial_driver keyspan_pda_fake_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_pda_pre", }, - .name = "Keyspan PDA - (prerenumeration)", - .short_name = "keyspan_pda_pre", + .description = "Keyspan PDA - (prerenumeration)", .id_table = id_table_fake, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -802,9 +802,9 @@ static struct usb_serial_driver keyspan_pda_fake_device = { static struct usb_serial_driver xircom_pgs_fake_device = { .driver = { .owner = THIS_MODULE, + .name = "xircom_no_firm", }, - .name = "Xircom / Entregra PGS - (prerenumeration)", - .short_name = "xircom_no_firm", + .description = "Xircom / Entregra PGS - (prerenumeration)", .id_table = id_table_fake_xircom, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -817,9 +817,9 @@ static struct usb_serial_driver xircom_pgs_fake_device = { static struct usb_serial_driver keyspan_pda_device = { .driver = { .owner = THIS_MODULE, + .name = "keyspan_pda", }, - .name = "Keyspan PDA", - .short_name = "keyspan_pda", + .description = "Keyspan PDA", .id_table = id_table_std, .num_interrupt_in = 1, .num_bulk_in = 0, diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 586108ce7897..a8951c0fd020 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -126,9 +126,9 @@ static struct usb_driver kl5kusb105d_driver = { static struct usb_serial_driver kl5kusb105d_device = { .driver = { .owner = THIS_MODULE, + .name = "kl5kusb105d", }, - .name = "KL5KUSB105D / PalmConnect", - .short_name = "kl5kusb105d", + .description = "KL5KUSB105D / PalmConnect", .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index a9578e05b22f..9456dd9dd136 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -108,8 +108,9 @@ static struct usb_driver kobil_driver = { static struct usb_serial_driver kobil_device = { .driver = { .owner = THIS_MODULE, + .name = "kobil", }, - .name = "KOBIL USB smart card terminal", + .description = "KOBIL USB smart card terminal", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 0, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 7dcf91c5f83d..ca5dbadb9b7e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -135,9 +135,9 @@ static struct usb_driver mct_u232_driver = { static struct usb_serial_driver mct_u232_device = { .driver = { .owner = THIS_MODULE, + .name = "mct_u232", }, - .name = "MCT U232", - .short_name = "mct_u232", + .description = "MCT U232", .id_table = id_table_combined, .num_interrupt_in = 2, .num_bulk_in = 0, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index f6327cc1b2e7..3caf97072ac0 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -91,9 +91,9 @@ static struct usb_driver omninet_driver = { static struct usb_serial_driver zyxel_omninet_device = { .driver = { .owner = THIS_MODULE, + .name = "omninet", }, - .name = "ZyXEL - omni.net lcd plus usb", - .short_name = "omninet", + .description = "ZyXEL - omni.net lcd plus usb", .id_table = id_table, .num_interrupt_in = 1, .num_bulk_in = 1, diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a2b5adf34868..7716000045b7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -108,9 +108,9 @@ static struct usb_driver option_driver = { static struct usb_serial_driver option_3port_device = { .driver = { .owner = THIS_MODULE, + .name = "option", }, - .name = "Option 3G data card", - .short_name = "option", + .description = "Option 3G data card", .id_table = option_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 29719ceab19a..f8f4e93e8c0b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -157,8 +157,8 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, static struct usb_serial_driver pl2303_device = { .driver = { .owner = THIS_MODULE, + .name = "pl2303", }, - .name = "PL-2303", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 42a86ab689f4..c22bdc0c4dfd 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -400,8 +400,8 @@ static int safe_startup (struct usb_serial *serial) static struct usb_serial_driver safe_device = { .driver = { .owner = THIS_MODULE, + .name = "safe_serial", }, - .name = "Safe", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index eab8a6de0925..205dbf7201da 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -257,9 +257,10 @@ static struct usb_driver ti_usb_driver = { static struct usb_serial_driver ti_1port_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "ti_usb_3410_5052_1", }, - .name = "TI USB 3410 1 port adapter", + .description = "TI USB 3410 1 port adapter", .id_table = ti_id_table_3410, .num_interrupt_in = 1, .num_bulk_in = 1, @@ -286,9 +287,10 @@ static struct usb_serial_driver ti_1port_device = { static struct usb_serial_driver ti_2port_device = { .driver = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .name = "ti_usb_3410_5052_2", }, - .name = "TI USB 5052 2 port adapter", + .description = "TI USB 5052 2 port adapter", .id_table = ti_id_table_5052, .num_interrupt_in = 1, .num_bulk_in = 2, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index fde09fba8790..13f6592be685 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -122,7 +122,7 @@ static void destroy_serial(struct kref *kref) serial = to_usb_serial(kref); - dbg ("%s - %s", __FUNCTION__, serial->type->name); + dbg("%s - %s", __FUNCTION__, serial->type->description); serial->type->shutdown(serial); @@ -415,7 +415,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int length += sprintf (page+length, "%d:", i); if (serial->type->driver.owner) length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner)); - length += sprintf (page+length, " name:\"%s\"", serial->type->name); + length += sprintf (page+length, " name:\"%s\"", serial->type->description); length += sprintf (page+length, " vendor:%04x product:%04x", le16_to_cpu(serial->dev->descriptor.idVendor), le16_to_cpu(serial->dev->descriptor.idProduct)); @@ -687,7 +687,7 @@ int usb_serial_probe(struct usb_interface *interface, #endif /* found all that we need */ - dev_info(&interface->dev, "%s converter detected\n", type->name); + dev_info(&interface->dev, "%s converter detected\n", type->description); #ifdef CONFIG_USB_SERIAL_GENERIC if (type == &usb_serial_generic_device) { @@ -1088,16 +1088,19 @@ int usb_serial_register(struct usb_serial_driver *driver) fixup_generic(driver); + if (!driver->description) + driver->description = driver->driver.name; + /* Add this device to our list of devices */ list_add(&driver->driver_list, &usb_serial_driver_list); retval = usb_serial_bus_register(driver); if (retval) { - err("problem %d when registering driver %s", retval, driver->name); + err("problem %d when registering driver %s", retval, driver->description); list_del(&driver->driver_list); } else - info("USB Serial support registered for %s", driver->name); + info("USB Serial support registered for %s", driver->description); return retval; } @@ -1105,7 +1108,7 @@ int usb_serial_register(struct usb_serial_driver *driver) void usb_serial_deregister(struct usb_serial_driver *device) { - info("USB Serial deregistering driver %s", device->name); + info("USB Serial deregistering driver %s", device->description); list_del(&device->driver_list); usb_serial_bus_deregister(device); } diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 1cedc1999508..238a5a871ed6 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -149,11 +149,8 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) /** * usb_serial_driver - describes a usb serial driver - * @name: pointer to a string that describes this driver. This string used + * @description: pointer to a string that describes this driver. This string used * in the syslog messages when a device is inserted or removed. - * @short_name: a pointer to a string that describes this driver in - * KOBJ_NAME_LEN characters or less. This is used for the sysfs interface - * to describe the driver. * @id_table: pointer to a list of usb_device_id structures that define all * of the devices this structure can support. * @num_interrupt_in: the number of interrupt in endpoints this device will @@ -187,11 +184,12 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) * called, the generic serial function will be used instead. * * The driver.owner field should be set to the module owner of this driver. - * + * The driver.name field should be set to the name of this driver (remember + * it will show up in sysfs, so it needs to be short and to the point. + * Useing the module name is a good idea.) */ struct usb_serial_driver { - char *name; - char *short_name; + const char *description; const struct usb_device_id *id_table; char num_interrupt_in; char num_interrupt_out; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 39ad0cab8635..baa2acb28bd8 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -185,9 +185,9 @@ static struct usb_driver visor_driver = { static struct usb_serial_driver handspring_device = { .driver = { .owner = THIS_MODULE, + .name = "visor", }, - .name = "Handspring Visor / Palm OS", - .short_name = "visor", + .description = "Handspring Visor / Palm OS", .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 2, @@ -215,9 +215,9 @@ static struct usb_serial_driver handspring_device = { static struct usb_serial_driver clie_5_device = { .driver = { .owner = THIS_MODULE, + .name = "clie_5", }, - .name = "Sony Clie 5.0", - .short_name = "clie_5", + .description = "Sony Clie 5.0", .id_table = clie_id_5_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 2, @@ -245,9 +245,9 @@ static struct usb_serial_driver clie_5_device = { static struct usb_serial_driver clie_3_5_device = { .driver = { .owner = THIS_MODULE, + .name = "clie_3.5", }, - .name = "Sony Clie 3.5", - .short_name = "clie_3.5", + .description = "Sony Clie 3.5", .id_table = clie_id_3_5_table, .num_interrupt_in = 0, .num_bulk_in = 1, @@ -659,7 +659,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i break; } dev_info(dev, "%s: port %d, is for %s use\n", - serial->type->name, + serial->type->description, connection_info->connections[i].port, string); } } @@ -668,11 +668,11 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i */ if (num_ports == 0 || num_ports > 2) { dev_warn (dev, "%s: No valid connect info available\n", - serial->type->name); + serial->type->description); num_ports = 2; } - dev_info(dev, "%s: Number of ports: %d\n", serial->type->name, + dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, num_ports); /* diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index fb95a34a1cf7..18c3183be769 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -159,9 +159,9 @@ static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); static struct usb_serial_driver whiteheat_fake_device = { .driver = { .owner = THIS_MODULE, + .name = "whiteheatnofirm", }, - .name = "Connect Tech - WhiteHEAT - (prerenumeration)", - .short_name = "whiteheatnofirm", + .description = "Connect Tech - WhiteHEAT - (prerenumeration)", .id_table = id_table_prerenumeration, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -174,9 +174,9 @@ static struct usb_serial_driver whiteheat_fake_device = { static struct usb_serial_driver whiteheat_device = { .driver = { .owner = THIS_MODULE, + .name = "whiteheat", }, - .name = "Connect Tech - WhiteHEAT", - .short_name = "whiteheat", + .description = "Connect Tech - WhiteHEAT", .id_table = id_table_std, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -386,10 +386,10 @@ static int whiteheat_attach (struct usb_serial *serial) usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS); if (ret) { - err("%s: Couldn't send command [%d]", serial->type->name, ret); + err("%s: Couldn't send command [%d]", serial->type->description, ret); goto no_firmware; } else if (alen != sizeof(command)) { - err("%s: Send command incomplete [%d]", serial->type->name, alen); + err("%s: Send command incomplete [%d]", serial->type->description, alen); goto no_firmware; } @@ -398,19 +398,19 @@ static int whiteheat_attach (struct usb_serial *serial) usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); if (ret) { - err("%s: Couldn't get results [%d]", serial->type->name, ret); + err("%s: Couldn't get results [%d]", serial->type->description, ret); goto no_firmware; } else if (alen != sizeof(result)) { - err("%s: Get results incomplete [%d]", serial->type->name, alen); + err("%s: Get results incomplete [%d]", serial->type->description, alen); goto no_firmware; } else if (result[0] != command[0]) { - err("%s: Command failed [%d]", serial->type->name, result[0]); + err("%s: Command failed [%d]", serial->type->description, result[0]); goto no_firmware; } hw_info = (struct whiteheat_hw_info *)&result[1]; - info("%s: Driver %s: Firmware v%d.%02d", serial->type->name, + info("%s: Driver %s: Firmware v%d.%02d", serial->type->description, DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); for (i = 0; i < serial->num_ports; i++) { @@ -418,7 +418,7 @@ static int whiteheat_attach (struct usb_serial *serial) info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); if (info == NULL) { - err("%s: Out of memory for port structures\n", serial->type->name); + err("%s: Out of memory for port structures\n", serial->type->description); goto no_private; } @@ -488,7 +488,7 @@ static int whiteheat_attach (struct usb_serial *serial) command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); if (command_info == NULL) { - err("%s: Out of memory for port structures\n", serial->type->name); + err("%s: Out of memory for port structures\n", serial->type->description); goto no_command_private; } @@ -505,9 +505,9 @@ static int whiteheat_attach (struct usb_serial *serial) no_firmware: /* Firmware likely not running */ - err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name); - err("%s: If the firmware is not running (status led not blinking)\n", serial->type->name); - err("%s: please contact support@connecttech.com\n", serial->type->name); + err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description); + err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description); + err("%s: please contact support@connecttech.com\n", serial->type->description); return -ENODEV; no_command_private: From 17a882fc0c91477b2582a6dfd4ca93ae7eb58cd3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0884/1940] [PATCH] USB Serial: remove driver version from a few drivers These numbers are pointless, as they have not been changed in _years_, so we should just remove them to stop pretending there is an actual "version number" for these drivers. This should also help reduce confusion when people try to ask for support of a specific driver version, as there has been no way to tell what they are talking about. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 4 +--- drivers/usb/serial/usb-serial.c | 6 ++---- drivers/usb/serial/visor.c | 3 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f8f4e93e8c0b..165c119bf10e 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -34,7 +34,6 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.12" #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" static int debug; @@ -1176,7 +1175,7 @@ static int __init pl2303_init (void) retval = usb_register(&pl2303_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + info(DRIVER_DESC); return 0; failed_usb_register: usb_serial_deregister(&pl2303_device); @@ -1196,7 +1195,6 @@ module_init(pl2303_init); module_exit(pl2303_exit); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 13f6592be685..0c4881d18cd5 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -37,7 +37,6 @@ /* * Version Information */ -#define DRIVER_VERSION "v2.0" #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" #define DRIVER_DESC "USB Serial Driver core" @@ -406,7 +405,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int char tmp[40]; dbg("%s", __FUNCTION__); - length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION); + length += sprintf (page, "usbserinfo:1.0 driver:2.0\n"); for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { serial = usb_serial_get_by_index(i); if (serial == NULL) @@ -1025,7 +1024,7 @@ static int __init usb_serial_init(void) goto exit_generic; } - info(DRIVER_DESC " " DRIVER_VERSION); + info(DRIVER_DESC); return result; @@ -1127,7 +1126,6 @@ EXPORT_SYMBOL_GPL(usb_serial_port_softint); /* Module information */ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_VERSION( DRIVER_VERSION ); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index baa2acb28bd8..a473c1c34559 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -32,7 +32,6 @@ /* * Version Information */ -#define DRIVER_VERSION "v2.1" #define DRIVER_AUTHOR "Greg Kroah-Hartman " #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" @@ -1002,7 +1001,7 @@ static int __init visor_init (void) retval = usb_register(&visor_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + info(DRIVER_DESC); return 0; failed_usb_register: From 7521803dcc0137668bb30483383092a647671d8b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0885/1940] [PATCH] USB: always export interface information for modalias This fixes a problem with some cdc acm devices that were not getting automatically loaded as the module alias was not being reported properly. This check was for back in the days when we only reported hotplug events for the main usb device, not the interfaces. We should always give the interface information for MODALIAS/modalias as it can be needed. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 33 +++++++++------------ drivers/usb/core/usb.c | 63 +++++++++++++++------------------------- 2 files changed, 36 insertions(+), 60 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index eae413bf8c2a..4bdbc9df6e03 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -462,30 +462,23 @@ static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, { struct usb_interface *intf; struct usb_device *udev; - int len; + struct usb_host_interface *alt; intf = to_usb_interface(dev); udev = interface_to_usbdev(intf); + alt = intf->cur_altsetting; - len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - le16_to_cpu(udev->descriptor.bcdDevice), - udev->descriptor.bDeviceClass, - udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol); - buf += len; - - if (udev->descriptor.bDeviceClass == 0) { - struct usb_host_interface *alt = intf->cur_altsetting; - - return len + sprintf(buf, "%02Xisc%02Xip%02X\n", - alt->desc.bInterfaceClass, - alt->desc.bInterfaceSubClass, - alt->desc.bInterfaceProtocol); - } else { - return len + sprintf(buf, "*isc*ip*\n"); - } + return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" + "ic%02Xisc%02Xip%02X\n", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + le16_to_cpu(udev->descriptor.bcdDevice), + udev->descriptor.bDeviceClass, + udev->descriptor.bDeviceSubClass, + udev->descriptor.bDeviceProtocol, + alt->desc.bInterfaceClass, + alt->desc.bInterfaceSubClass, + alt->desc.bInterfaceProtocol); } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2493e7d9f5b3..4eca4904938f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -569,6 +569,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, { struct usb_interface *intf; struct usb_device *usb_dev; + struct usb_host_interface *alt; int i = 0; int length = 0; @@ -585,7 +586,8 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, intf = to_usb_interface(dev); usb_dev = interface_to_usbdev (intf); - + alt = intf->cur_altsetting; + if (usb_dev->devnum < 0) { pr_debug ("usb %s: already deleted?\n", dev->bus_id); return -ENODEV; @@ -627,46 +629,27 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, usb_dev->descriptor.bDeviceProtocol)) return -ENOMEM; - if (usb_dev->descriptor.bDeviceClass == 0) { - struct usb_host_interface *alt = intf->cur_altsetting; + if (add_hotplug_env_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "INTERFACE=%d/%d/%d", + alt->desc.bInterfaceClass, + alt->desc.bInterfaceSubClass, + alt->desc.bInterfaceProtocol)) + return -ENOMEM; - /* 2.4 only exposed interface zero. in 2.5, hotplug - * agents are called for all interfaces, and can use - * $DEVPATH/bInterfaceNumber if necessary. - */ - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "INTERFACE=%d/%d/%d", - alt->desc.bInterfaceClass, - alt->desc.bInterfaceSubClass, - alt->desc.bInterfaceProtocol)) - return -ENOMEM; - - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", - le16_to_cpu(usb_dev->descriptor.idVendor), - le16_to_cpu(usb_dev->descriptor.idProduct), - le16_to_cpu(usb_dev->descriptor.bcdDevice), - usb_dev->descriptor.bDeviceClass, - usb_dev->descriptor.bDeviceSubClass, - usb_dev->descriptor.bDeviceProtocol, - alt->desc.bInterfaceClass, - alt->desc.bInterfaceSubClass, - alt->desc.bInterfaceProtocol)) - return -ENOMEM; - } else { - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*", - le16_to_cpu(usb_dev->descriptor.idVendor), - le16_to_cpu(usb_dev->descriptor.idProduct), - le16_to_cpu(usb_dev->descriptor.bcdDevice), - usb_dev->descriptor.bDeviceClass, - usb_dev->descriptor.bDeviceSubClass, - usb_dev->descriptor.bDeviceProtocol)) - return -ENOMEM; - } + if (add_hotplug_env_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", + le16_to_cpu(usb_dev->descriptor.idVendor), + le16_to_cpu(usb_dev->descriptor.idProduct), + le16_to_cpu(usb_dev->descriptor.bcdDevice), + usb_dev->descriptor.bDeviceClass, + usb_dev->descriptor.bDeviceSubClass, + usb_dev->descriptor.bDeviceProtocol, + alt->desc.bInterfaceClass, + alt->desc.bInterfaceSubClass, + alt->desc.bInterfaceProtocol)) + return -ENOMEM; envp[i] = NULL; From dcab4eaf77ccd8779c715da3c5db0a82874fa645 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Wed, 19 Oct 2005 11:32:14 -0400 Subject: [PATCH 0886/1940] [PATCH] USB: storage patch for LEICA camera On Tue, 18 Oct 2005, Simeon Simeonov wrote: > Attached is a patch that solves mounting problems for > LEICA D-LUX camera with FC4 2.6.13 kernel. > > Let me know if you have some questions. Looks okay to me. Given that the previous entry uses the full 0000 - 9999 range, I guess this one can also. The vendor name is a little odd (it will give us three different vendor names all in entries with the same vendor ID) but that doesn't really matter either. Signed-off-by: Alan Stern Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a11701840262..d0f6a7e2fe31 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -251,6 +251,13 @@ UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), +/* Reported by Simeon Simeonov */ +UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999, + "LEICA", + "D-LUX Camera", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), + /* Most of the following entries were developed with the help of * Shuttle/SCM directly. */ From 61eded6e06a1f4bdbf707b69da904ba9f3eb2f0a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 24 Oct 2005 22:37:20 +0200 Subject: [PATCH 0887/1940] [PATCH] USB: microtek patch to use kzalloc here is another one to use kzalloc. Please apply. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/microtek.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index c84e1486054f..c89d0769b3da 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -773,11 +773,10 @@ static int mts_usb_probe(struct usb_interface *intf, } - new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL); + new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); if (!new_desc) goto out; - memset(new_desc, 0, sizeof(*new_desc)); new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); if (!new_desc->urb) goto out_kfree; From f2d45cd976682a3566c8cf30cefe91eb43ab6005 Mon Sep 17 00:00:00 2001 From: Guillaume GOURAT / Date: Fri, 21 Oct 2005 14:01:35 +0200 Subject: [PATCH 0888/1940] [PATCH] USB: Kaweth.c udelay patch On some arch (like arm) udelay cannot be called with value greater that 2000. Signed-off-by: Guillaume GOURAT / guillaume.gourat@nexvision.fr Signed-off-by: Oliver Neukum --- drivers/usb/net/kaweth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index c82655d3d448..6bef1be6b36c 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -469,7 +469,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) 0, KAWETH_CONTROL_TIMEOUT); - udelay(10000); + mdelay(10); kaweth_dbg("kaweth_reset() returns %d.",result); From eb3c5ed8617d0aa67648cb7d1a486d14099129f2 Mon Sep 17 00:00:00 2001 From: David Eriksson Date: Tue, 18 Oct 2005 20:12:24 +0200 Subject: [PATCH 0889/1940] [PATCH] USB: Improving the set of vendor/product IDs in the ipaq driver This is a patch improving the set of vendor/product IDs used in the "ipaq" USB serial device driver. The patch size is because I sorted the ids this time, forgot about that last time. Changes: - Added vendor/product identifiers for Psion Teklogix devices - Restored Microsoft's identifier pair 045e/00ce - Sorted list of vendor/product identifiers Signed-off-by: David Eriksson Signed-off-by: Ganesh Varadarajan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 246 +++++++++++++++++++------------------- 1 file changed, 125 insertions(+), 121 deletions(-) diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 1abaebe6dbc1..d5d066488100 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -92,24 +92,7 @@ static void ipaq_destroy_lists(struct usb_serial_port *port); static struct usb_device_id ipaq_id_table [] = { /* The first entry is a placeholder for the insmod-specified device */ { USB_DEVICE(0x049F, 0x0003) }, - { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */ - { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */ - { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */ - { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */ - { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */ - { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */ - { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */ - { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */ - { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */ - { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */ { USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */ { USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */ { USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */ @@ -125,7 +108,13 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */ { USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */ { USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */ - { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */ + { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */ + { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */ + { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */ + { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */ + { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */ + { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */ + { USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */ { USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */ { USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */ { USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */ @@ -251,17 +240,81 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */ { USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */ { USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */ - { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ - { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */ + { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */ + { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */ + { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */ + { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ + { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ + { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ + { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ + { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ + { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ + { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ + { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ + { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ + { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */ + { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */ + { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */ + { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */ + { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */ + { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */ + { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */ + { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */ + { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */ + { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */ + { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */ + { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */ + { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */ + { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */ + { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */ + { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */ + { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */ + { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */ + { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */ + { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */ + { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */ + { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */ + { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */ + { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */ + { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */ + { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */ + { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */ + { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */ + { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */ + { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */ + { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */ + { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */ + { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */ + { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */ { USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */ { USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */ + { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */ { USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */ { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */ - { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */ { USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */ { USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */ { USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */ + { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */ + { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */ + { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */ + { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */ + { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */ + { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */ + { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */ + { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */ + { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */ + { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */ + { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */ + { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ + { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ @@ -422,116 +475,67 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */ { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */ { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */ - { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */ { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */ - { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */ - { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */ - { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */ - { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */ - { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */ - { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */ - { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ - { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ - { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ - { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ - { USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */ - { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */ - { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */ - { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ - { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ - { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */ - { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */ - { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */ - { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */ - { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */ - { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */ - { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ - { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */ - { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */ - { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */ - { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */ - { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */ - { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */ - { USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */ - { USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */ - { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */ - { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */ - { USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */ - { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */ - { USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */ - { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */ - { USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */ - { USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */ { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */ - { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ - { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */ - { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */ - { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */ - { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */ - { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */ - { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */ - { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */ - { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */ - { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */ - { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */ - { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */ - { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */ - { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */ - { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */ - { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */ - { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */ - { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */ - { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */ - { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */ - { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */ - { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */ - { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */ - { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */ + { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ + { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */ + { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */ + { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */ { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */ { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */ { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */ { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */ - { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */ + { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */ + { USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */ + { USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */ + { USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */ + { USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */ + { USB_DEVICE(0x1114, 0x0001) }, /* Psion Teklogix Sync 753x */ + { USB_DEVICE(0x1114, 0x0004) }, /* Psion Teklogix Sync netBookPro */ + { USB_DEVICE(0x1114, 0x0006) }, /* Psion Teklogix Sync 7525 */ + { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */ { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */ + { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */ + { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */ + { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */ + { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */ { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */ { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */ { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */ { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */ { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */ - { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */ - { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */ + { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */ + { USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */ + { USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */ + { USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */ + { USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */ + { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */ + { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */ + { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */ + { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */ + { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */ + { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */ + { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */ + { USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */ + { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */ + { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */ + { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */ + { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */ + { USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */ + { USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */ + { USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */ + { USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */ + { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ + { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ + { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ { } /* Terminating entry */ }; From 46f116eab81b21c6ae8c4f169498c632b1f94bf1 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 24 Oct 2005 22:42:35 +0200 Subject: [PATCH 0890/1940] [PATCH] USB: cdc-acm patch to use kzalloc another one to use kzalloc. Please apply. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 16ecad30e29c..1b4751412970 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -827,11 +827,10 @@ static int acm_probe (struct usb_interface *intf, return -ENODEV; } - if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) { - dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n"); + if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { + dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); goto alloc_fail; } - memset(acm, 0, sizeof(struct acm)); ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); readsize = le16_to_cpu(epread->wMaxPacketSize); From 478a3bab8c87a9ba4a4ba338314e32bb0c378e62 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 19 Oct 2005 12:52:02 -0400 Subject: [PATCH 0891/1940] [PATCH] USB: Always do usb-handoff This revised patch (as586b) makes usb-handoff permanently true and no longer a kernel boot parameter. It also removes the piix3_usb quirk code; that was nothing more than an early version of the USB handoff code (written at a time when Intel's PIIX3 was about the only motherboard with USB support). And it adds identifiers for the three PCI USB controller classes to pci_ids.h. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 2 - drivers/usb/host/pci-quirks.c | 46 ++------------------- include/asm-i386/mach-summit/mach_mpparse.h | 3 -- include/linux/pci_ids.h | 3 ++ 4 files changed, 6 insertions(+), 48 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 971589a9752d..90766b75d1b7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1517,8 +1517,6 @@ running once the system is up. uart6850= [HW,OSS] Format: , - usb-handoff [HW] Enable early USB BIOS -> OS handoff - usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index f7411ca48835..b7fd3f644e1e 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -23,33 +23,6 @@ #include -/* - * PIIX3 USB: We have to disable USB interrupts that are - * hardwired to PIRQD# and may be shared with an - * external device. - * - * Legacy Support Register (LEGSUP): - * bit13: USB PIRQ Enable (USBPIRQDEN), - * bit4: Trap/SMI On IRQ Enable (USBSMIEN). - * - * We mask out all r/wc bits, too. - */ -static void __devinit quirk_piix3_usb(struct pci_dev *dev) -{ - u16 legsup; - - pci_read_config_word(dev, 0xc0, &legsup); - legsup &= 0x50ef; - pci_write_config_word(dev, 0xc0, legsup); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); - - -/* FIXME these should be the guts of hcd->reset() methods; resolve all - * the differences between this version and the HCD's version. - */ - #define UHCI_USBLEGSUP 0xc0 /* legacy support */ #define UHCI_USBCMD 0 /* command register */ #define UHCI_USBINTR 4 /* interrupt register */ @@ -83,13 +56,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, qui #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ -int usb_early_handoff __devinitdata = 0; -static int __init usb_handoff_early(char *str) -{ - usb_early_handoff = 1; - return 0; -} -__setup("usb-handoff", usb_handoff_early); /* * Make sure the controller is completely inactive, unable to @@ -320,17 +286,11 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) { - if (!usb_early_handoff) - return; - - if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ + if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) quirk_usb_handoff_uhci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ + else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) quirk_usb_handoff_ohci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ + else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) quirk_usb_disable_ehci(pdev); - } - - return; } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h index 2b9e6d55bef1..1cce2b924a80 100644 --- a/include/asm-i386/mach-summit/mach_mpparse.h +++ b/include/asm-i386/mach-summit/mach_mpparse.h @@ -22,7 +22,6 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, { } -extern int usb_early_handoff; static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { @@ -32,7 +31,6 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, || !strncmp(productid, "RUTHLESS SMP", 12))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); - usb_early_handoff = 1; return 1; } return 0; @@ -46,7 +44,6 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); - usb_early_handoff = 1; return 1; } return 0; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7d300f7469e3..467a096c3b81 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -96,6 +96,9 @@ #define PCI_CLASS_SERIAL_ACCESS 0x0c01 #define PCI_CLASS_SERIAL_SSA 0x0c02 #define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 +#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 +#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 #define PCI_CLASS_SERIAL_FIBER 0x0c04 #define PCI_CLASS_SERIAL_SMBUS 0x0c05 From 423e489d704d05c6e8c2927fb1854db85914912a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 19 Oct 2005 13:06:13 -0400 Subject: [PATCH 0892/1940] [PATCH] hid-core: Add Clear-Halt on the Interrupt-in endpoint This patch (as577) adds a Clear-Halt call on the Interrupt-in endpoint during input device configuration. Without it my HP USB keyboard doesn't work. Vojtech says it's worth trying, since it might help with some recalcitrant devices. On the other hand, it might interfere with others. I'm submitting it so that it can get tested by a range of users. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index f7fcce731f54..79ddce4555ab 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1784,6 +1784,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); + /* May be needed for some devices */ + usb_clear_halt(hid->dev, hid->urbin->pipe); + return hid; fail: From b876aef7f890d8c59a45b78858a36cf60fddf522 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sun, 23 Oct 2005 19:38:56 -0700 Subject: [PATCH 0893/1940] [PATCH] PATCH: usb-storage: move GetMaxLUN later in time This patch is originally from Alan Stern (as557). It has been re-diffed against a current tree, and I also corrected a minor merging error. Some time ago we introduced a delay before device scanning, because many devices do not like to receive SCSI commands right after enumeration. Now it turns out there's a device that doesn't like to receive Get-Max-LUN right after enumeration either. Accordingly this patch delays the Get-Max-LUN request until the beginning of the scanning procedure. This fixes Bugzilla entry #5010. Three things are worth noting. First, I removed the locking code from usb_stor_acquire_resources. It's not needed, because the locking is to protect against disconnect events and acquire_resources is only called during probe (so the disconnect routine can't be called). Second, I initialized to 0 the buffer used for the Get-Max-LUN response. It's not really necessary, but it will prevent random values from showing up in the debugging log when the request fails. Third, I added a test against the SINGLE_LUN flag. This will allow us to use the flag to indicate Bulk-only devices that can't handle Get-Max-LUN. Signed-off-by: Alan Stern Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 1 + drivers/usb/storage/usb.c | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index c1ba5301ebfc..e89e945fc4a7 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -923,6 +923,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us) int result; /* issue the command */ + us->iobuf[0] = 0; result = usb_stor_control_msg(us, us->recv_ctrl_pipe, US_BULK_GET_MAX_LUN, USB_DIR_IN | USB_TYPE_CLASS | diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 5164900e40c1..92ee079d9172 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -747,25 +747,13 @@ static int usb_stor_acquire_resources(struct us_data *us) return -ENOMEM; } - /* Lock the device while we carry out the next two operations */ - down(&us->dev_semaphore); - - /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == US_PR_BULK) { - p = usb_stor_Bulk_max_lun(us); - if (p < 0) { - up(&us->dev_semaphore); - return p; - } - us->max_lun = p; - } - /* Just before we start our control thread, initialize * the device if it needs initialization */ - if (us->unusual_dev->initFunction) - us->unusual_dev->initFunction(us); - - up(&us->dev_semaphore); + if (us->unusual_dev->initFunction) { + p = us->unusual_dev->initFunction(us); + if (p) + return p; + } /* Start up our control thread */ p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); @@ -904,6 +892,14 @@ static int usb_stor_scan_thread(void * __us) /* If the device is still connected, perform the scanning */ if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + + /* For bulk-only devices, determine the max LUN value */ + if (us->protocol == US_PR_BULK && + !(us->flags & US_FL_SINGLE_LUN)) { + down(&us->dev_semaphore); + us->max_lun = usb_stor_Bulk_max_lun(us); + up(&us->dev_semaphore); + } scsi_scan_host(us_to_host(us)); printk(KERN_DEBUG "usb-storage: device scan complete\n"); From bbafa4668f37f5093a3ae2a8b0cbe327e24e12da Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sun, 23 Oct 2005 19:40:22 -0700 Subject: [PATCH 0894/1940] [PATCH] PATCH: usb-storage: allocate separate sense buffer This patch is from Alan Stern (as560). It has been rediffed against a current tree. This patch allocates a separate buffer for usb-storage to use when auto-sensing. Up to now we have been using the sense buffer embedded in a scsi_cmnd struct, which is dangerous on hosts that (a) don't do cache-coherent DMA or (b) have DMA alignment restrictions. Signed-off-by: Alan Stern Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 5 +++-- drivers/usb/storage/usb.c | 8 ++++++++ drivers/usb/storage/usb.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index e89e945fc4a7..7ca896a342e3 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* use the new buffer we have */ old_request_buffer = srb->request_buffer; - srb->request_buffer = srb->sense_buffer; + srb->request_buffer = us->sensebuf; /* set the buffer length for transfer */ old_request_bufflen = srb->request_bufflen; - srb->request_bufflen = 18; + srb->request_bufflen = US_SENSE_SIZE; /* set up for no scatter-gather use */ old_sg = srb->use_sg; @@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) temp_result = us->transport(us->srb, us); /* let's clean up right away */ + memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE); srb->resid = old_resid; srb->request_buffer = old_request_buffer; srb->request_bufflen = old_request_bufflen; diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 92ee079d9172..eb901817b7d2 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -467,6 +467,12 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) US_DEBUGP("I/O buffer allocation failed\n"); return -ENOMEM; } + + us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL); + if (!us->sensebuf) { + US_DEBUGP("Sense buffer allocation failed\n"); + return -ENOMEM; + } return 0; } @@ -800,6 +806,8 @@ static void dissociate_dev(struct us_data *us) { US_DEBUGP("-- %s\n", __FUNCTION__); + kfree(us->sensebuf); + /* Free the device-related DMA-mapped buffers */ if (us->cr) usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index a195adae57b6..dfa4dc71dd3e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS }; */ #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ +#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */ typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); typedef int (*trans_reset)(struct us_data*); @@ -168,6 +169,7 @@ struct us_data { struct usb_ctrlrequest *cr; /* control requests */ struct usb_sg_request current_sg; /* scatter-gather req. */ unsigned char *iobuf; /* I/O buffer */ + unsigned char *sensebuf; /* sense data buffer */ dma_addr_t cr_dma; /* buffer DMA addresses */ dma_addr_t iobuf_dma; From ce2596df79ddbac605a290f4c7cf011cb40524fc Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sun, 23 Oct 2005 19:41:39 -0700 Subject: [PATCH 0895/1940] [PATCH] PATCH: usb-storage: implement minimal PM This patch from Alan Stern started as as568. It has been rediffed against a current tree. This patch adds minimal suspend/resume support to usb-storage. Just enough for it to qualify as PM-aware. Signed-off-by: Alan Stern Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index eb901817b7d2..c1a902691bc6 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -111,11 +111,6 @@ static atomic_t total_threads = ATOMIC_INIT(0); static DECLARE_COMPLETION(threads_gone); -static int storage_probe(struct usb_interface *iface, - const struct usb_device_id *id); - -static void storage_disconnect(struct usb_interface *iface); - /* The entries in this table, except for final ones here * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, * line for line with the entries of us_unsuaul_dev_list[]. @@ -233,13 +228,40 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { NULL } }; -static struct usb_driver usb_storage_driver = { - .owner = THIS_MODULE, - .name = "usb-storage", - .probe = storage_probe, - .disconnect = storage_disconnect, - .id_table = storage_usb_ids, -}; + +#ifdef CONFIG_PM /* Minimal support for suspend and resume */ + +static int storage_suspend(struct usb_interface *iface, pm_message_t message) +{ + struct us_data *us = usb_get_intfdata(iface); + + /* Wait until no command is running */ + down(&us->dev_semaphore); + + US_DEBUGP("%s\n", __FUNCTION__); + iface->dev.power.power_state.event = message.event; + + /* When runtime PM is working, we'll set a flag to indicate + * whether we should autoresume when a SCSI request arrives. */ + + up(&us->dev_semaphore); + return 0; +} + +static int storage_resume(struct usb_interface *iface) +{ + struct us_data *us = usb_get_intfdata(iface); + + down(&us->dev_semaphore); + + US_DEBUGP("%s\n", __FUNCTION__); + iface->dev.power.power_state.event = PM_EVENT_ON; + + up(&us->dev_semaphore); + return 0; +} + +#endif /* CONFIG_PM */ /* * fill_inquiry_response takes an unsigned char array (which must @@ -1042,6 +1064,18 @@ static void storage_disconnect(struct usb_interface *intf) * Initialization and registration ***********************************************************************/ +static struct usb_driver usb_storage_driver = { + .owner = THIS_MODULE, + .name = "usb-storage", + .probe = storage_probe, + .disconnect = storage_disconnect, +#ifdef CONFIG_PM + .suspend = storage_suspend, + .resume = storage_resume, +#endif + .id_table = storage_usb_ids, +}; + static int __init usb_stor_init(void) { int retval; From 3f13e66e219238e025ff561d69826da9342c3f4a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sun, 23 Oct 2005 19:43:36 -0700 Subject: [PATCH 0896/1940] [PATCH] PATCH: usb-storage: use kthread API This patch is originally from Alan Stern (as569). It has been rediffed against a current tree. This patch converts usb-storage to use the kthread API for creating its control and scanning threads. The new code doesn't use kthread_stop because the threads need (or will need in the future) to exit asynchronously. Signed-off-by: Alan Stern Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 63 +++++++++++++-------------------------- drivers/usb/storage/usb.h | 3 -- 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c1a902691bc6..3847ebed2aa4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -310,22 +311,7 @@ static int usb_stor_control_thread(void * __us) struct us_data *us = (struct us_data *)__us; struct Scsi_Host *host = us_to_host(us); - lock_kernel(); - - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources. - */ - daemonize("usb-storage"); current->flags |= PF_NOFREEZE; - unlock_kernel(); - - /* acquire a reference to the host, so it won't be deallocated - * until we're ready to exit */ - scsi_host_get(host); - - /* signal that we've started the thread */ - complete(&(us->notify)); for(;;) { US_DEBUGP("*** thread sleeping.\n"); @@ -768,6 +754,7 @@ static int get_pipes(struct us_data *us) static int usb_stor_acquire_resources(struct us_data *us) { int p; + struct task_struct *th; us->current_urb = usb_alloc_urb(0, GFP_KERNEL); if (!us->current_urb) { @@ -784,17 +771,19 @@ static int usb_stor_acquire_resources(struct us_data *us) } /* Start up our control thread */ - p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); - if (p < 0) { + th = kthread_create(usb_stor_control_thread, us, "usb-storage"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start control thread\n"); - return p; + return PTR_ERR(th); } - us->pid = p; - atomic_inc(&total_threads); - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the control thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(us_to_host(us)); + atomic_inc(&total_threads); + wake_up_process(th); return 0; } @@ -890,21 +879,6 @@ static int usb_stor_scan_thread(void * __us) { struct us_data *us = (struct us_data *)__us; - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources. - */ - lock_kernel(); - daemonize("usb-stor-scan"); - unlock_kernel(); - - /* Acquire a reference to the host, so it won't be deallocated - * until we're ready to exit */ - scsi_host_get(us_to_host(us)); - - /* Signal that we've started the thread */ - complete(&(us->notify)); - printk(KERN_DEBUG "usb-storage: device found at %d\n", us->pusb_dev->devnum); @@ -949,6 +923,7 @@ static int storage_probe(struct usb_interface *intf, struct us_data *us; const int id_index = id - storage_usb_ids; int result; + struct task_struct *th; US_DEBUGP("USB Mass Storage device detected\n"); @@ -1029,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf, } /* Start up the thread for delayed SCSI-device scanning */ - result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); - if (result < 0) { + th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(us); + result = PTR_ERR(th); goto BadDevice; } - atomic_inc(&total_threads); - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the scanning thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(us_to_host(us)); + atomic_inc(&total_threads); + wake_up_process(th); return 0; diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index dfa4dc71dd3e..98b09711a739 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -161,9 +161,6 @@ struct us_data { struct scsi_cmnd *srb; /* current srb */ unsigned int tag; /* current dCBWTag */ - /* thread information */ - int pid; /* control thread */ - /* control and bulk communications data */ struct urb *current_urb; /* USB requests */ struct usb_ctrlrequest *cr; /* control requests */ From 72129cd6577793408ff546b0ddd5794c33f32399 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 25 Oct 2005 23:34:03 +0400 Subject: [PATCH 0897/1940] [PATCH] mdc800: remove embrions of C++ exceptions Signed-off-by: Alexey Dobriyan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/mdc800.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index e4ec133ee74a..1d973bcf56aa 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -975,13 +975,13 @@ static struct usb_driver mdc800_usb_driver = Init and Cleanup this driver (Main Functions) *************************************************************************/ -#define try(A) if (!(A)) goto cleanup_on_fail; - static int __init usb_mdc800_init (void) { int retval = -ENODEV; /* Allocate Memory */ - try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); + mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL); + if (!mdc800) + goto cleanup_on_fail; memset(mdc800, 0, sizeof(struct mdc800_data)); mdc800->dev = NULL; @@ -997,13 +997,25 @@ static int __init usb_mdc800_init (void) mdc800->downloaded = 0; mdc800->written = 0; - try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); - try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); - try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL)); + mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL); + if (!mdc800->irq_urb_buffer) + goto cleanup_on_fail; + mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL); + if (!mdc800->write_urb_buffer) + goto cleanup_on_fail; + mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL); + if (!mdc800->download_urb_buffer) + goto cleanup_on_fail; - try (mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL)); - try (mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL)); - try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL)); + mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL); + if (!mdc800->irq_urb) + goto cleanup_on_fail; + mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL); + if (!mdc800->download_urb) + goto cleanup_on_fail; + mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL); + if (!mdc800->write_urb) + goto cleanup_on_fail; /* Register the driver */ retval = usb_register(&mdc800_usb_driver); From e52783206ada0c0276c8dd74c0ecd0007ead7c00 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sun, 23 Oct 2005 23:52:39 -0700 Subject: [PATCH 0898/1940] [PATCH] USB Storage: Expand range of Freecom unusual_devs entry Freecom seems to be one of those vendors that can't get the GET CAPACITY thing right. This expands the US_FL_FIX_CAPACITY flag for the entire range of their fccd product line. This is based on a patch sent by Stuart Black . Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d0f6a7e2fe31..9e926a8f2116 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -756,7 +756,7 @@ UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, #endif /* Reported by Eero Volotinen */ -UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0406, 0x0406, +UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, "Freecom Technologies", "FHD-Classic", US_SC_DEVICE, US_PR_DEVICE, NULL, From be69e5b1900a19a545becda822b18d6f09168ba5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 25 Oct 2005 15:56:06 -0400 Subject: [PATCH 0899/1940] [PATCH] usbcore: Improve endpoint sysfs file handling This revised patch (as587b) improves the implementation of USB endpoint sysfs files. Instead of storing a whole bunch of attributes for every single endpoint, each endpoint now gets its own kobject and they can share a static list of attributes. The number of extra fields added to struct usb_host_endpoint has been reduced from 4 to 1. The bEndpointAddress field is retained even though it is redundant (it repeats the same information as the attributes' directory name). The code avoids calling kobject_register, to prevent generating unwanted hotplug events. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 227 ++++++++++++++++++++++----------------- include/linux/usb.h | 5 +- 2 files changed, 129 insertions(+), 103 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4bdbc9df6e03..f18317fb49ee 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -23,43 +23,56 @@ #include "usb.h" /* endpoint stuff */ -struct endpoint_attribute { - struct device_attribute dev_attr; - struct usb_endpoint_descriptor *endpoint; +struct ep_object { + struct usb_endpoint_descriptor *desc; struct usb_device *udev; + struct kobject kobj; }; -#define to_endpoint_attr(_dev_attr) \ - container_of(_dev_attr, struct endpoint_attribute, dev_attr) +#define to_ep_object(_kobj) \ + container_of(_kobj, struct ep_object, kobj) + +struct ep_attribute { + struct attribute attr; + ssize_t (*show)(struct usb_device *, + struct usb_endpoint_descriptor *, char *); +}; +#define to_ep_attribute(_attr) \ + container_of(_attr, struct ep_attribute, attr) + +#define EP_ATTR(_name) \ +struct ep_attribute ep_##_name = { \ + .attr = {.name = #_name, .owner = THIS_MODULE, \ + .mode = S_IRUGO}, \ + .show = show_ep_##_name} + +#define usb_ep_attr(field, format_string) \ +static ssize_t show_ep_##field(struct usb_device *udev, \ + struct usb_endpoint_descriptor *desc, \ + char *buf) \ +{ \ + return sprintf(buf, format_string, desc->field); \ +} \ +static EP_ATTR(field); -#define usb_ep_attr(field, format_string) \ -static ssize_t show_ep_##field(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); \ - \ - return sprintf(buf, format_string, endpoint_attr->endpoint->field); \ -} usb_ep_attr(bLength, "%02x\n") -usb_ep_attr(bDescriptorType, "%02x\n") usb_ep_attr(bEndpointAddress, "%02x\n") usb_ep_attr(bmAttributes, "%02x\n") usb_ep_attr(bInterval, "%02x\n") -static ssize_t show_ep_wMaxPacketSize(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); - return sprintf(buf, "%04x\n", - le16_to_cpu(endpoint_attr->endpoint->wMaxPacketSize) & 0x07ff); + le16_to_cpu(desc->wMaxPacketSize) & 0x07ff); } +static EP_ATTR(wMaxPacketSize); -static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_type(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); char *type = "unknown"; - switch (endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_CONTROL: type = "Control"; break; @@ -75,35 +88,34 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, c } return sprintf(buf, "%s\n", type); } +static EP_ATTR(type); -static ssize_t show_ep_interval(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_interval(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); - struct usb_device *udev = endpoint_attr->udev; - struct usb_endpoint_descriptor *endpoint = endpoint_attr->endpoint; char unit; unsigned interval = 0; unsigned in; - in = (endpoint->bEndpointAddress & USB_DIR_IN); + in = (desc->bEndpointAddress & USB_DIR_IN); - switch (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_CONTROL: if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ - interval = endpoint->bInterval; + interval = desc->bInterval; break; case USB_ENDPOINT_XFER_ISOC: - interval = 1 << (endpoint->bInterval - 1); + interval = 1 << (desc->bInterval - 1); break; case USB_ENDPOINT_XFER_BULK: - if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ - interval = endpoint->bInterval; + if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ + interval = desc->bInterval; break; case USB_ENDPOINT_XFER_INT: - if (udev->speed == USB_SPEED_HIGH) { - interval = 1 << (endpoint->bInterval - 1); - } else - interval = endpoint->bInterval; + if (udev->speed == USB_SPEED_HIGH) + interval = 1 << (desc->bInterval - 1); + else + interval = desc->bInterval; break; } interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; @@ -116,78 +128,95 @@ static ssize_t show_ep_interval(struct device *dev, struct device_attribute *att return sprintf(buf, "%d%cs\n", interval, unit); } +static EP_ATTR(interval); -static ssize_t show_ep_direction(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_direction(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); char *direction; - if ((endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_CONTROL) + if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) direction = "both"; - else if (endpoint_attr->endpoint->bEndpointAddress & USB_DIR_IN) + else if (desc->bEndpointAddress & USB_DIR_IN) direction = "in"; else direction = "out"; return sprintf(buf, "%s\n", direction); } +static EP_ATTR(direction); -static struct endpoint_attribute *create_ep_attr(struct usb_endpoint_descriptor *endpoint, - struct usb_device *udev, char *name, - ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf)) +static struct attribute *ep_attrs[] = { + &ep_bLength.attr, + &ep_bEndpointAddress.attr, + &ep_bmAttributes.attr, + &ep_bInterval.attr, + &ep_wMaxPacketSize.attr, + &ep_type.attr, + &ep_interval.attr, + &ep_direction.attr, + NULL, +}; + +static void ep_object_release(struct kobject *kobj) { - struct endpoint_attribute *ep_attr; + kfree(to_ep_object(kobj)); +} - ep_attr = kzalloc(sizeof(*ep_attr), GFP_KERNEL); - if (ep_attr) { - ep_attr->endpoint = endpoint; - ep_attr->udev = udev; - ep_attr->dev_attr.attr.name = name; - ep_attr->dev_attr.attr.mode = 0444; - ep_attr->dev_attr.attr.owner = THIS_MODULE; - ep_attr->dev_attr.show = show; +static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct ep_object *ep_obj = to_ep_object(kobj); + struct ep_attribute *ep_attr = to_ep_attribute(attr); + + return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf); +} + +static struct sysfs_ops ep_object_sysfs_ops = { + .show = ep_object_show, +}; + +static struct kobj_type ep_object_ktype = { + .release = ep_object_release, + .sysfs_ops = &ep_object_sysfs_ops, + .default_attrs = ep_attrs, +}; + +static void usb_create_ep_files(struct kobject *parent, + struct usb_host_endpoint *endpoint, + struct usb_device *udev) +{ + struct ep_object *ep_obj; + struct kobject *kobj; + + ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL); + if (!ep_obj) + return; + + ep_obj->desc = &endpoint->desc; + ep_obj->udev = udev; + + kobj = &ep_obj->kobj; + kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress); + kobj->parent = parent; + kobj->ktype = &ep_object_ktype; + + /* Don't use kobject_register, because it generates a hotplug event */ + kobject_init(kobj); + if (kobject_add(kobj) == 0) + endpoint->kobj = kobj; + else + kobject_put(kobj); +} + +static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) +{ + + if (endpoint->kobj) { + kobject_del(endpoint->kobj); + kobject_put(endpoint->kobj); + endpoint->kobj = NULL; } - return ep_attr; -} - -static void usb_create_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint, struct usb_device *udev) -{ - struct usb_endpoint_descriptor *ep; - - ep = &endpoint->desc; - - endpoint->attrs = kzalloc(sizeof(struct attribute *) * 10, GFP_KERNEL); - endpoint->attrs[0] = &(create_ep_attr(ep, udev, "direction", show_ep_direction)->dev_attr.attr); - endpoint->attrs[1] = &(create_ep_attr(ep, udev, "type", show_ep_type)->dev_attr.attr); - endpoint->attrs[2] = &(create_ep_attr(ep, udev, "bLength", show_ep_bLength)->dev_attr.attr); - endpoint->attrs[3] = &(create_ep_attr(ep, udev, "bDescriptorType", show_ep_bDescriptorType)->dev_attr.attr); - endpoint->attrs[4] = &(create_ep_attr(ep, udev, "bEndpointAddress", show_ep_bEndpointAddress)->dev_attr.attr); - endpoint->attrs[5] = &(create_ep_attr(ep, udev, "bmAttributes", show_ep_bmAttributes)->dev_attr.attr); - endpoint->attrs[6] = &(create_ep_attr(ep, udev, "wMaxPacketSize", show_ep_wMaxPacketSize)->dev_attr.attr); - endpoint->attrs[7] = &(create_ep_attr(ep, udev, "bInterval", show_ep_bInterval)->dev_attr.attr); - endpoint->attrs[8] = &(create_ep_attr(ep, udev, "interval", show_ep_interval)->dev_attr.attr); - endpoint->attrs[9] = NULL; - endpoint->num_attrs = 9; - - endpoint->attr_group = kzalloc(sizeof(*endpoint->attr_group), GFP_KERNEL); - endpoint->attr_name = kzalloc(10, GFP_KERNEL); - sprintf(endpoint->attr_name, "ep_%02x", endpoint->desc.bEndpointAddress); - - endpoint->attr_group->attrs = endpoint->attrs; - endpoint->attr_group->name = endpoint->attr_name; - sysfs_create_group(kobj, endpoint->attr_group); -} - -static void usb_remove_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint) -{ - int i; - - sysfs_remove_group(kobj, endpoint->attr_group); - kfree(endpoint->attr_group); - kfree(endpoint->attr_name); - for (i = 0; i < endpoint->num_attrs; ++i) - kfree(endpoint->attrs[i]); - kfree(endpoint->attrs); } /* Active configuration fields */ @@ -411,7 +440,7 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; - usb_remove_ep_files(&dev->kobj, &udev->ep0); + usb_remove_ep_files(&udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); if (udev->descriptor.iManufacturer) @@ -496,7 +525,7 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; -static void usb_create_intf_ep_files(struct usb_interface *intf) +static inline void usb_create_intf_ep_files(struct usb_interface *intf) { struct usb_host_interface *iface_desc; int i; @@ -504,17 +533,17 @@ static void usb_create_intf_ep_files(struct usb_interface *intf) iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], - interface_to_usbdev(intf)); + interface_to_usbdev(intf)); } -static void usb_remove_intf_ep_files(struct usb_interface *intf) +static inline void usb_remove_intf_ep_files(struct usb_interface *intf) { struct usb_host_interface *iface_desc; int i; iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) - usb_remove_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i]); + usb_remove_ep_files(&iface_desc->endpoint[i]); } void usb_create_sysfs_intf_files (struct usb_interface *intf) diff --git a/include/linux/usb.h b/include/linux/usb.h index a2d923fd54f9..465ff4585ca5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -57,10 +57,7 @@ struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; - char *attr_name; - struct attribute_group *attr_group; - struct attribute **attrs; - int num_attrs; + struct kobject *kobj; /* For sysfs info */ unsigned char *extra; /* Extra descriptors */ int extralen; From 0e6c8e8db508fcb292836b23d039649c5de29090 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 15:33:03 -0400 Subject: [PATCH 0900/1940] [PATCH] usbcore: endpoint attributes track altsetting changes This patch (as588) fixes the way endpoint attribute files are registered and unregistered. Now they will correctly track along with altsetting changes. This fixes bugzilla entry #5467. In a separate but related change, when a usb_reset_configuration call fails, the device state is not changed to USB_STATE_ADDRESS. In the first place, failure means that we don't know what the state is, not that we know the device is unconfigured. In the second place, doing this can potentially lead to a memory leak, since usbcore might not realize there still is a current configuration that needs to be destroyed. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 574d0d4b3401..5ad0d5e28119 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1149,6 +1149,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) */ /* prevent submissions using previous endpoint settings */ + if (device_is_registered(&iface->dev)) + usb_remove_sysfs_intf_files(iface); usb_disable_interface(dev, iface); iface->cur_altsetting = alt; @@ -1184,6 +1186,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) * (Likewise, EP0 never "halts" on well designed devices.) */ usb_enable_interface(dev, iface); + if (device_is_registered(&iface->dev)) + usb_create_sysfs_intf_files(iface); return 0; } @@ -1233,10 +1237,8 @@ int usb_reset_configuration(struct usb_device *dev) USB_REQ_SET_CONFIGURATION, 0, config->desc.bConfigurationValue, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (retval < 0) { - usb_set_device_state(dev, USB_STATE_ADDRESS); + if (retval < 0) return retval; - } dev->toggle[0] = dev->toggle[1] = 0; @@ -1245,6 +1247,8 @@ int usb_reset_configuration(struct usb_device *dev) struct usb_interface *intf = config->interface[i]; struct usb_host_interface *alt; + if (device_is_registered(&intf->dev)) + usb_remove_sysfs_intf_files(intf); alt = usb_altnum_to_altsetting(intf, 0); /* No altsetting 0? We'll assume the first altsetting. @@ -1257,6 +1261,8 @@ int usb_reset_configuration(struct usb_device *dev) intf->cur_altsetting = alt; usb_enable_interface(dev, intf); + if (device_is_registered(&intf->dev)) + usb_create_sysfs_intf_files(intf); } return 0; } From b724ae77969fd832be71419dca74bece9af287ff Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 15:36:00 -0400 Subject: [PATCH 0901/1940] [PATCH] usbcore: Wrap lines before column 80 I can't stand text lines that wrap-around in my 80-column windows. This patch (as589) makes cosmetic changes to a couple of source files. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 30 ++++++--- include/linux/usb.h | 132 +++++++++++++++++++++++++-------------- 2 files changed, 106 insertions(+), 56 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index f18317fb49ee..4cca77cf0c48 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -221,7 +221,8 @@ static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ -static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##field (struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ struct usb_host_config *actconfig; \ @@ -243,7 +244,8 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") usb_actconfig_attr (bmAttributes, 1, "%2x\n") usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") -static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_configuration_string(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_device *udev; struct usb_host_config *actconfig; @@ -266,7 +268,8 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); usb_actconfig_show(bConfigurationValue, 1, "%u\n"); static ssize_t -set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +set_bConfigurationValue (struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct usb_device *udev = udev = to_usb_device (dev); int config, value; @@ -284,7 +287,8 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, /* String fields */ #define usb_string_attr(name) \ -static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ int len; \ @@ -364,7 +368,8 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); /* Descriptor fields */ #define usb_descriptor_attr_le16(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_device *udev; \ \ @@ -380,7 +385,8 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") #define usb_descriptor_attr(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_device *udev; \ \ @@ -455,11 +461,13 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) /* Interface fields */ #define usb_intf_attr(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_interface *intf = to_usb_interface (dev); \ \ - return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \ + return sprintf (buf, format_string, \ + intf->cur_altsetting->desc.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); @@ -470,7 +478,8 @@ usb_intf_attr (bInterfaceClass, "%02x\n") usb_intf_attr (bInterfaceSubClass, "%02x\n") usb_intf_attr (bInterfaceProtocol, "%02x\n") -static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_interface_string(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_interface *intf; struct usb_device *udev; @@ -487,7 +496,8 @@ static ssize_t show_interface_string(struct device *dev, struct device_attribute } static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); -static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_modalias(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_interface *intf; struct usb_device *udev; diff --git a/include/linux/usb.h b/include/linux/usb.h index 465ff4585ca5..c500d6b5a16d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -137,7 +137,8 @@ struct usb_interface { * active alternate setting */ unsigned num_altsetting; /* number of alternate settings */ - int minor; /* minor number this interface is bound to */ + int minor; /* minor number this interface is + * bound to */ enum usb_interface_condition condition; /* state of binding */ struct device dev; /* interface specific device info */ struct class_device *class_dev; @@ -249,7 +250,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\ type,(void**)ptr) -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ struct usb_operations; @@ -269,7 +270,8 @@ struct usb_bus { unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ - int devnum_next; /* Next open device number in round-robin allocation */ + int devnum_next; /* Next open device number in + * round-robin allocation */ struct usb_devmap devmap; /* device address allocation map */ struct usb_operations *op; /* Operations (specific to the HC) */ @@ -290,15 +292,16 @@ struct usb_bus { struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ struct class_device *class_dev; /* class device for this bus */ - struct kref kref; /* handles reference counting this bus */ - void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ + struct kref kref; /* reference counting for this bus */ + void (*release)(struct usb_bus *bus); + #if defined(CONFIG_USB_MON) struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif }; -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* This is arbitrary. * From USB 2.0 spec Table 11-13, offset 7, a hub can @@ -327,7 +330,8 @@ struct usb_device { struct semaphore serialize; - unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ + unsigned int toggle[2]; /* one bit for each endpoint + * ([0] = IN, [1] = OUT) */ struct usb_device *parent; /* our hub, unless we're the root */ struct usb_bus *bus; /* Bus we're part of */ @@ -344,7 +348,7 @@ struct usb_device { char **rawdescriptors; /* Raw descriptors for each config */ - int have_langid; /* whether string_langid is valid yet */ + int have_langid; /* whether string_langid is valid */ int string_langid; /* language ID for strings */ char *product; @@ -441,22 +445,31 @@ extern struct usb_host_interface *usb_altnum_to_altsetting( * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are * high speed, and a different one if they are full or low speed. */ -static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) +static inline int usb_make_path (struct usb_device *dev, char *buf, + size_t size) { int actual; - actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath); + actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, + dev->devpath); return (actual >= (int)size) ? -1 : actual; } /*-------------------------------------------------------------------------*/ -#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) -#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) -#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) +#define USB_DEVICE_ID_MATCH_DEVICE \ + (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) +#define USB_DEVICE_ID_MATCH_DEV_RANGE \ + (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) +#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ + (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) #define USB_DEVICE_ID_MATCH_DEV_INFO \ - (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL) + (USB_DEVICE_ID_MATCH_DEV_CLASS | \ + USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \ + USB_DEVICE_ID_MATCH_DEV_PROTOCOL) #define USB_DEVICE_ID_MATCH_INT_INFO \ - (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL) + (USB_DEVICE_ID_MATCH_INT_CLASS | \ + USB_DEVICE_ID_MATCH_INT_SUBCLASS | \ + USB_DEVICE_ID_MATCH_INT_PROTOCOL) /** * USB_DEVICE - macro used to describe a specific usb device @@ -467,9 +480,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific device. */ #define USB_DEVICE(vend,prod) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod) + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \ + .idProduct = (prod) /** - * USB_DEVICE_VER - macro used to describe a specific usb device with a version range + * USB_DEVICE_VER - macro used to describe a specific usb device with a + * version range * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @lo: the bcdDevice_lo value @@ -479,7 +494,9 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific device, with a version range. */ #define USB_DEVICE_VER(vend,prod,lo,hi) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) + .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \ + .idVendor = (vend), .idProduct = (prod), \ + .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) /** * USB_DEVICE_INFO - macro used to describe a class of usb devices @@ -491,7 +508,8 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific class of devices. */ #define USB_DEVICE_INFO(cl,sc,pr) \ - .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr) + .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \ + .bDeviceSubClass = (sc), .bDeviceProtocol = (pr) /** * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces @@ -503,9 +521,10 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific class of interfaces. */ #define USB_INTERFACE_INFO(cl,sc,pr) \ - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \ + .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /** * struct usb_driver - identifies USB driver to usbcore @@ -558,7 +577,8 @@ struct usb_driver { void (*disconnect) (struct usb_interface *intf); - int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf); + int (*ioctl) (struct usb_interface *intf, unsigned int code, + void *buf); int (*suspend) (struct usb_interface *intf, pm_message_t message); int (*resume) (struct usb_interface *intf); @@ -601,7 +621,7 @@ extern void usb_deregister_dev(struct usb_interface *intf, extern int usb_disabled(void); -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* * URB support, for asynchronous request completions @@ -611,12 +631,14 @@ extern int usb_disabled(void); * urb->transfer_flags: */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ -#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ +#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame + * ignored */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ #define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */ #define URB_NO_FSBR 0x0020 /* UHCI-specific */ -#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ -#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ +#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ +#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt + * needed */ struct usb_iso_packet_descriptor { unsigned int offset; @@ -804,7 +826,8 @@ struct urb u8 reject; /* submissions will fail */ /* public, documented fields in the urb that can be used by drivers */ - struct list_head urb_list; /* list head for use by the urb owner */ + struct list_head urb_list; /* list head for use by the urb's + * current owner */ struct usb_device *dev; /* (in) pointer to associated device */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ @@ -817,14 +840,16 @@ struct urb dma_addr_t setup_dma; /* (in) dma addr for setup_packet */ int start_frame; /* (modify) start frame (ISO) */ int number_of_packets; /* (in) number of ISO packets */ - int interval; /* (modify) transfer interval (INT/ISO) */ + int interval; /* (modify) transfer interval + * (INT/ISO) */ int error_count; /* (return) number of ISO errors */ void *context; /* (in) context for completion */ usb_complete_t complete; /* (in) completion routine */ - struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */ + struct usb_iso_packet_descriptor iso_frame_desc[0]; + /* (in) ISO ONLY */ }; -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /** * usb_fill_control_urb - initializes a control urb @@ -1049,7 +1074,7 @@ void usb_sg_cancel (struct usb_sg_request *io); void usb_sg_wait (struct usb_sg_request *io); -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* * For various legacy reasons, Linux has a small cookie that's paired with @@ -1090,23 +1115,34 @@ void usb_sg_wait (struct usb_sg_request *io); /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) -#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep))) +#define usb_settoggle(dev, ep, out, bit) \ + ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ + ((bit) << (ep))) -static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint) +static inline unsigned int __create_pipe(struct usb_device *dev, + unsigned int endpoint) { return (dev->devnum << 8) | (endpoint << 15); } /* Create various pipes... */ -#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndctrlpipe(dev,endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvctrlpipe(dev,endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndisocpipe(dev,endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvisocpipe(dev,endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndbulkpipe(dev,endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvbulkpipe(dev,endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndintpipe(dev,endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvintpipe(dev,endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) /*-------------------------------------------------------------------------*/ @@ -1130,7 +1166,7 @@ usb_maxpacket(struct usb_device *udev, int pipe, int is_out) return le16_to_cpu(ep->desc.wMaxPacketSize); } -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* Events from the usb core */ #define USB_DEVICE_ADD 0x0001 @@ -1141,14 +1177,18 @@ extern void usb_register_notify(struct notifier_block *nb); extern void usb_unregister_notify(struct notifier_block *nb); #ifdef DEBUG -#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg) +#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ + __FILE__ , ## arg) #else #define dbg(format, arg...) do {} while (0) #endif -#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg) +#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ + __FILE__ , ## arg) +#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , \ + __FILE__ , ## arg) +#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , \ + __FILE__ , ## arg) #endif /* __KERNEL__ */ From 0a1ef3b5a765a6f20e7b8caf295aad3276243966 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 15:38:24 -0400 Subject: [PATCH 0902/1940] [PATCH] usbcore: Use kzalloc instead of kmalloc/memset This patch (as590) fixes up all the remaining places where usbcore can use kzalloc rather than kmalloc/memset. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 12 ++++-------- drivers/usb/core/devio.c | 4 ++-- drivers/usb/core/hcd.c | 3 +-- drivers/usb/core/hub.c | 4 +--- drivers/usb/core/message.c | 3 +-- drivers/usb/core/usb.c | 4 +--- 6 files changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 99595e07b653..63f374e62db2 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -188,10 +188,9 @@ static int usb_parse_interface(struct device *ddev, int cfgno, } len = sizeof(struct usb_host_endpoint) * num_ep; - alt->endpoint = kmalloc(len, GFP_KERNEL); + alt->endpoint = kzalloc(len, GFP_KERNEL); if (!alt->endpoint) return -ENOMEM; - memset(alt->endpoint, 0, len); /* Parse all the endpoint descriptors */ n = 0; @@ -353,10 +352,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx, } len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j; - config->intf_cache[i] = intfc = kmalloc(len, GFP_KERNEL); + config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL); if (!intfc) return -ENOMEM; - memset(intfc, 0, len); kref_init(&intfc->ref); } @@ -459,16 +457,14 @@ int usb_get_configuration(struct usb_device *dev) } length = ncfg * sizeof(struct usb_host_config); - dev->config = kmalloc(length, GFP_KERNEL); + dev->config = kzalloc(length, GFP_KERNEL); if (!dev->config) goto err2; - memset(dev->config, 0, length); length = ncfg * sizeof(char *); - dev->rawdescriptors = kmalloc(length, GFP_KERNEL); + dev->rawdescriptors = kzalloc(length, GFP_KERNEL); if (!dev->rawdescriptors) goto err2; - memset(dev->rawdescriptors, 0, length); buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); if (!buffer) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ffb2e242b100..942cd437dc48 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -210,10 +210,10 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l static struct async *alloc_async(unsigned int numisoframes) { unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor); - struct async *as = kmalloc(assize, GFP_KERNEL); + struct async *as = kzalloc(assize, GFP_KERNEL); + if (!as) return NULL; - memset(as, 0, assize); as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); if (!as->urb) { kfree(as); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e8f2b8d8f14d..61ef9943757e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -744,10 +744,9 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op) { struct usb_bus *bus; - bus = kmalloc (sizeof *bus, GFP_KERNEL); + bus = kzalloc (sizeof *bus, GFP_KERNEL); if (!bus) return NULL; - memset(bus, 0, sizeof(struct usb_bus)); usb_bus_init (bus); bus->op = op; return bus; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6a2ebd89916f..8ba5854e5387 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -865,14 +865,12 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) /* We found a hub */ dev_info (&intf->dev, "USB hub found\n"); - hub = kmalloc(sizeof(*hub), GFP_KERNEL); + hub = kzalloc(sizeof(*hub), GFP_KERNEL); if (!hub) { dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); return -ENOMEM; } - memset(hub, 0, sizeof(*hub)); - INIT_LIST_HEAD(&hub->event_list); hub->intfdev = &intf->dev; hub->hdev = hdev; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5ad0d5e28119..3519f317898e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1350,7 +1350,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) } for (; n < nintf; ++n) { - new_interfaces[n] = kmalloc( + new_interfaces[n] = kzalloc( sizeof(struct usb_interface), GFP_KERNEL); if (!new_interfaces[n]) { @@ -1391,7 +1391,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) struct usb_host_interface *alt; cp->interface[i] = intf = new_interfaces[i]; - memset(intf, 0, sizeof(*intf)); intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4eca4904938f..0eefff7bcb3c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -704,12 +704,10 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) { struct usb_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); - bus = usb_bus_get(bus); if (!bus) { kfree(dev); From 16f16d117c1eb99451e4c73c87546eef05c66790 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 15:41:19 -0400 Subject: [PATCH 0903/1940] [PATCH] USB: Fix maxpacket length for ep0 on root hubs This patch (as591) fixes a rather innocuous bug that has been around for quite a long time: Virtual root hubs should have a maxpacket length of 64 for endpoint 0. I didn't realize it was wrong until I started looking through the endpoint attribute files. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 61ef9943757e..6c7ca5b08cd6 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -130,7 +130,7 @@ static const u8 usb2_rh_dev_descriptor [18] = { 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 0x00, /* __u8 bDeviceSubClass; */ 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 0x00, 0x00, /* __le16 idVendor; */ 0x00, 0x00, /* __le16 idProduct; */ @@ -153,7 +153,7 @@ static const u8 usb11_rh_dev_descriptor [18] = { 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 0x00, /* __u8 bDeviceSubClass; */ 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 0x00, 0x00, /* __le16 idVendor; */ 0x00, 0x00, /* __le16 idProduct; */ From 4f62efe67f077db17dad03a1d4c9665000a3eb45 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 16:24:14 -0400 Subject: [PATCH 0904/1940] [PATCH] usbcore: Fix handling of sysfs strings and other attributes This patch (as592) makes a few small improvements to the way device strings are handled, and it fixes some bugs in a couple of other sysfs attribute routines. (Look at show_configuration_string() to see what I mean.) Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 10 ++++---- drivers/usb/core/hub.c | 22 ++++------------- drivers/usb/core/message.c | 48 ++++++++++++++++++++++++-------------- drivers/usb/core/sysfs.c | 36 ++++++++++++---------------- drivers/usb/core/usb.h | 1 + include/linux/usb.h | 10 ++++---- 6 files changed, 62 insertions(+), 65 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 63f374e62db2..993019500cc3 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -112,8 +112,12 @@ void usb_release_interface_cache(struct kref *ref) struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); int j; - for (j = 0; j < intfc->num_altsetting; j++) - kfree(intfc->altsetting[j].endpoint); + for (j = 0; j < intfc->num_altsetting; j++) { + struct usb_host_interface *alt = &intfc->altsetting[j]; + + kfree(alt->endpoint); + kfree(alt->string); + } kfree(intfc); } @@ -420,8 +424,6 @@ void usb_destroy_configuration(struct usb_device *dev) struct usb_host_config *cf = &dev->config[c]; kfree(cf->string); - cf->string = NULL; - for (i = 0; i < cf->desc.bNumInterfaces; i++) { if (cf->intf_cache[i]) kref_put(&cf->intf_cache[i]->ref, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8ba5854e5387..1bacb374b007 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1204,21 +1204,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) {} #endif -static void get_string(struct usb_device *udev, char **string, int index) -{ - char *buf; - - if (!index) - return; - buf = kmalloc(256, GFP_KERNEL); - if (!buf) - return; - if (usb_string(udev, index, buf, 256) > 0) - *string = buf; - else - kfree(buf); -} - #ifdef CONFIG_USB_OTG #include "otg_whitelist.h" @@ -1257,9 +1242,10 @@ int usb_new_device(struct usb_device *udev) } /* read the standard strings and cache them if present */ - get_string(udev, &udev->product, udev->descriptor.iProduct); - get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer); - get_string(udev, &udev->serial, udev->descriptor.iSerialNumber); + udev->product = usb_cache_string(udev, udev->descriptor.iProduct); + udev->manufacturer = usb_cache_string(udev, + udev->descriptor.iManufacturer); + udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); /* Tell the world! */ dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3519f317898e..644a3d4f12aa 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -787,6 +787,31 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) return err; } +/** + * usb_cache_string - read a string descriptor and cache it for later use + * @udev: the device whose string descriptor is being read + * @index: the descriptor index + * + * Returns a pointer to a kmalloc'ed buffer containing the descriptor string, + * or NULL if the index is 0 or the string could not be read. + */ +char *usb_cache_string(struct usb_device *udev, int index) +{ + char *buf; + char *smallbuf = NULL; + int len; + + if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) { + if ((len = usb_string(udev, index, buf, 256)) > 0) { + if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL) + return buf; + memcpy(smallbuf, buf, len); + } + kfree(buf); + } + return smallbuf; +} + /* * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) * @dev: the device whose device descriptor is being updated @@ -1008,8 +1033,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); usb_remove_sysfs_intf_files(interface); - kfree(interface->cur_altsetting->string); - interface->cur_altsetting->string = NULL; device_del (&interface->dev); } @@ -1422,12 +1445,9 @@ int usb_set_configuration(struct usb_device *dev, int configuration) } kfree(new_interfaces); - if ((cp->desc.iConfiguration) && - (cp->string == NULL)) { - cp->string = kmalloc(256, GFP_KERNEL); - if (cp->string) - usb_string(dev, cp->desc.iConfiguration, cp->string, 256); - } + if (cp->string == NULL) + cp->string = usb_cache_string(dev, + cp->desc.iConfiguration); /* Now that all the interfaces are set up, register them * to trigger binding of drivers to interfaces. probe() @@ -1437,13 +1457,12 @@ int usb_set_configuration(struct usb_device *dev, int configuration) */ for (i = 0; i < nintf; ++i) { struct usb_interface *intf = cp->interface[i]; - struct usb_interface_descriptor *desc; + struct usb_host_interface *alt = intf->cur_altsetting; - desc = &intf->altsetting [0].desc; dev_dbg (&dev->dev, "adding %s (config #%d, interface %d)\n", intf->dev.bus_id, configuration, - desc->bInterfaceNumber); + alt->desc.bInterfaceNumber); ret = device_add (&intf->dev); if (ret != 0) { dev_err(&dev->dev, @@ -1452,13 +1471,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ret); continue; } - if ((intf->cur_altsetting->desc.iInterface) && - (intf->cur_altsetting->string == NULL)) { - intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL); - if (intf->cur_altsetting->string) - usb_string(dev, intf->cur_altsetting->desc.iInterface, - intf->cur_altsetting->string, 256); - } usb_create_sysfs_intf_files (intf); } } diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cca77cf0c48..edd83e014452 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -249,18 +249,12 @@ static ssize_t show_configuration_string(struct device *dev, { struct usb_device *udev; struct usb_host_config *actconfig; - int len; udev = to_usb_device (dev); actconfig = udev->actconfig; if ((!actconfig) || (!actconfig->string)) return 0; - len = sprintf(buf, actconfig->string, PAGE_SIZE); - if (len < 0) - return 0; - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; + return sprintf(buf, "%s\n", actconfig->string); } static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); @@ -291,15 +285,9 @@ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ - int len; \ \ udev = to_usb_device (dev); \ - len = snprintf(buf, 256, "%s", udev->name); \ - if (len < 0) \ - return 0; \ - buf[len] = '\n'; \ - buf[len+1] = 0; \ - return len+1; \ + return sprintf(buf, "%s\n", udev->name); \ } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); @@ -449,11 +437,11 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) usb_remove_ep_files(&udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); - if (udev->descriptor.iManufacturer) + if (udev->manufacturer) device_remove_file(dev, &dev_attr_manufacturer); - if (udev->descriptor.iProduct) + if (udev->product) device_remove_file(dev, &dev_attr_product); - if (udev->descriptor.iSerialNumber) + if (udev->serial) device_remove_file(dev, &dev_attr_serial); device_remove_file (dev, &dev_attr_configuration); } @@ -535,7 +523,8 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; -static inline void usb_create_intf_ep_files(struct usb_interface *intf) +static inline void usb_create_intf_ep_files(struct usb_interface *intf, + struct usb_device *udev) { struct usb_host_interface *iface_desc; int i; @@ -543,7 +532,7 @@ static inline void usb_create_intf_ep_files(struct usb_interface *intf) iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], - interface_to_usbdev(intf)); + udev); } static inline void usb_remove_intf_ep_files(struct usb_interface *intf) @@ -558,11 +547,16 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf) void usb_create_sysfs_intf_files (struct usb_interface *intf) { + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_host_interface *alt = intf->cur_altsetting; + sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); - if (intf->cur_altsetting->string) + if (alt->string == NULL) + alt->string = usb_cache_string(udev, alt->desc.iInterface); + if (alt->string) device_create_file(&intf->dev, &dev_attr_interface); - usb_create_intf_ep_files(intf); + usb_create_intf_ep_files(intf, udev); } void usb_remove_sysfs_intf_files (struct usb_interface *intf) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 888dbe443695..1c4a68499dce 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -13,6 +13,7 @@ extern void usb_disable_device (struct usb_device *dev, int skip_ep0); extern int usb_get_device_descriptor(struct usb_device *dev, unsigned int size); +extern char *usb_cache_string(struct usb_device *udev, int index); extern int usb_set_configuration(struct usb_device *dev, int configuration); extern void usb_lock_all_devices(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index c500d6b5a16d..748d04385256 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -231,7 +231,7 @@ struct usb_interface_cache { struct usb_host_config { struct usb_config_descriptor desc; - char *string; + char *string; /* iConfiguration string, if present */ /* the interfaces associated with this configuration, * stored in no particular order */ struct usb_interface *interface[USB_MAXINTERFACES]; @@ -351,9 +351,11 @@ struct usb_device { int have_langid; /* whether string_langid is valid */ int string_langid; /* language ID for strings */ - char *product; - char *manufacturer; - char *serial; /* static strings from the device */ + /* static strings from the device */ + char *product; /* iProduct string, if present */ + char *manufacturer; /* iManufacturer string, if present */ + char *serial; /* iSerialNumber string, if present */ + struct list_head filelist; struct class_device *class_dev; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ From db2d55b7f7f11823b8d2e5f0c706c7a264320d1b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 23 Oct 2005 23:04:25 -0700 Subject: [PATCH 0905/1940] [PATCH] USB: fix pm patches with CONFIG_PM off part 1 With CONFIG_PM=n: drivers/built-in.o(.text+0x2a69c): In function `ohci_hub_control': drivers/usb/host/ohci-hub.c:539: undefined reference to `.usb_hcd_resume_root_hub' drivers/built-in.o(.text+0x2b920): In function `ohci_irq': drivers/usb/host/ohci-hcd.c:726: undefined reference to `.usb_hcd_resume_root_hub' Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index a5d92943ff95..24a62a2ff86d 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -351,9 +351,6 @@ extern long usb_calc_bus_time (int speed, int is_input, extern struct usb_bus *usb_alloc_bus (struct usb_operations *); -extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); -extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); - extern void usb_set_device_state(struct usb_device *udev, enum usb_device_state new_state); @@ -376,9 +373,21 @@ extern int usb_find_interface_driver (struct usb_device *dev, #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) #ifdef CONFIG_PM +extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); +extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); extern int hcd_bus_suspend (struct usb_bus *bus); extern int hcd_bus_resume (struct usb_bus *bus); #else +static inline void usb_hcd_suspend_root_hub(struct usb_hcd *hcd) +{ + return; +} + +static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) +{ + return; +} + static inline int hcd_bus_suspend(struct usb_bus *bus) { return 0; From 9a7834d06d553d02cc6e659e94772f69a8b5367f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 23 Oct 2005 23:02:20 -0700 Subject: [PATCH 0906/1940] [PATCH] USB: fix pm patches with CONFIG_PM off part 2 With CONFIG_PM=n: drivers/built-in.o(.text+0x1098c): In function `hub_thread': drivers/usb/core/hub.c:2673: undefined reference to `.dpm_runtime_resume' drivers/built-in.o(.text+0x10998):drivers/usb/core/hub.c:2674: undefined reference to `.dpm_runtime_resume' Please, never ever ever put extern decls into .c files. Use the darn header files :( Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/power.h | 13 ------------- drivers/usb/core/hub.c | 2 -- include/linux/pm.h | 13 +++++++++++++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 2e700d795cf1..fb3d35a9e101 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -67,9 +67,6 @@ extern int suspend_device(struct device *, pm_message_t); * runtime.c */ -extern int dpm_runtime_suspend(struct device *, pm_message_t); -extern void dpm_runtime_resume(struct device *); - #else /* CONFIG_PM */ @@ -82,14 +79,4 @@ static inline void device_pm_remove(struct device * dev) } -static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) -{ - return 0; -} - -static inline void dpm_runtime_resume(struct device * dev) -{ - -} - #endif diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1bacb374b007..9660a8909b7c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2652,8 +2652,6 @@ static void hub_events(void) * stub "device" node was never suspended. */ if (i) { - extern void dpm_runtime_resume(struct device *); - dpm_runtime_resume(&hdev->dev); dpm_runtime_resume(&intf->dev); } diff --git a/include/linux/pm.h b/include/linux/pm.h index 83bae1cbe55b..c61d5de837ef 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -243,6 +243,9 @@ extern int device_suspend(pm_message_t state); #define device_may_wakeup(dev) \ (device_can_wakeup(dev) && (dev)->power.should_wakeup) +extern int dpm_runtime_suspend(struct device *, pm_message_t); +extern void dpm_runtime_resume(struct device *); + #else /* !CONFIG_PM */ static inline int device_suspend(pm_message_t state) @@ -253,6 +256,16 @@ static inline int device_suspend(pm_message_t state) #define device_set_wakeup_enable(dev,val) do{}while(0) #define device_may_wakeup(dev) (0) +static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) +{ + return 0; +} + +static inline void dpm_runtime_resume(struct device * dev) +{ + +} + #endif /* changes to device_may_wakeup take effect on the next pm state change. From 46a0cf81828535fb3c200bc4fffdb8d69f4bf396 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 26 Oct 2005 19:42:53 +0200 Subject: [PATCH 0907/1940] [PATCH] USB: fix correct wording in drivers/usb/net/KConfig Signed-off-by: Koen Kooi --- drivers/usb/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index 8c010bb44eb8..efd6ca7e4ac5 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig @@ -294,7 +294,7 @@ config USB_NET_ZAURUS This also supports some related device firmware, as used in some PDAs from Olympus and some cell phones from Motorola. - If you install an alternate ROM image, such as the Linux 2.6 based + If you install an alternate image, such as the Linux 2.6 based versions of OpenZaurus, you should no longer need to support this protocol. Only the "eth-fd" or "net_fd" drivers in these devices really need this non-conformant variant of CDC Ethernet (or in From bde621854f1958a6000834c7c089b528118e5a9a Mon Sep 17 00:00:00 2001 From: Martin Hagelin Date: Wed, 26 Oct 2005 21:10:41 +0200 Subject: [PATCH 0908/1940] [PATCH] USB: add new device id to ftdi_sio module This is a patch to get the ELV FHZ1000 Home Automation control device to work with Linux. The patch adds a new device ID to the ftdi_sio driver. It is for kernel version 2.6.13.4. Signed-off-by: Martin Hagelin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 77d54ac39a0e..61204bf7cd78 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -412,6 +412,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, /* * These will probably use user-space drivers. Uncomment them if * you need them or use the user-specified vendor/product module @@ -429,7 +430,6 @@ static struct usb_device_id id_table_combined [] = { /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */ - /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */ From 50260b69bbec383058875de26dbde28b1a6f8d00 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH 0909/1940] [PATCH] USB: add nokia_dku2 driver This driver comes from the gnokii project. Was further cleaned up by me to match recent usb-serial core changes. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 9 ++ drivers/usb/serial/Makefile | 1 + drivers/usb/serial/nokia_dku2.c | 142 ++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 drivers/usb/serial/nokia_dku2.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 9438909e87a5..7b5e8e4ee2bb 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -394,6 +394,15 @@ config USB_SERIAL_MCT_U232 To compile this driver as a module, choose M here: the module will be called mct_u232. +config USB_SERIAL_NOKIA_DKU2 + tristate "USB Nokia DKU2 Driver" + depends on USB_SERIAL + help + Say Y here if you want to use a Nokia DKU2 device. + + To compile this driver as a module, choose M here: the + module will be called nokia_dku2. + config USB_SERIAL_PL2303 tristate "USB Prolific 2303 Single Port Serial Driver" depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 6c7cdcc99a9e..55fd461793b7 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o +obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2) += nokia_dku2.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTION) += option.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c new file mode 100644 index 000000000000..fad01bef3a64 --- /dev/null +++ b/drivers/usb/serial/nokia_dku2.c @@ -0,0 +1,142 @@ +/* + * Nokia DKU2 USB driver + * + * Copyright (C) 2004 + * Author: C Kemp + * + * This program is largely derived from work by the linux-usb group + * and associated source files. Please see the usb/serial files for + * individual credits and copyrights. + * + * 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. + * + * 20.09.2005 - Matthias Blaesing + * Added short name to device structure to make driver load into kernel 2.6.13 + * + * 20.09.2005 - Matthias Blaesing + * Added usb_deregister to exit code - to allow remove and reinsert of module + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "usb-serial.h" + + +#define NOKIA_VENDOR_ID 0x0421 +#define NOKIA7600_PRODUCT_ID 0x0400 +#define NOKIA6230_PRODUCT_ID 0x040f +#define NOKIA6170_PRODUCT_ID 0x0416 +#define NOKIA6670_PRODUCT_ID 0x041d +#define NOKIA6680_PRODUCT_ID 0x041e +#define NOKIA6230i_PRODUCT_ID 0x0428 + +#define NOKIA_AT_PORT 0x82 +#define NOKIA_FBUS_PORT 0x86 + +/* + * Version Information + */ +#define DRIVER_VERSION "v0.2" +#define DRIVER_AUTHOR "C Kemp" +#define DRIVER_DESC "Nokia DKU2 Driver" + +static struct usb_device_id id_table [] = { + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) }, + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) }, + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) }, + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) }, + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) }, + { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, id_table); + +/* The only thing which makes this device different from a generic + * device is that we have to set an alternative configuration to make + * the relevant endpoints available. In 2.6 this is really easy... */ +static int nokia_probe(struct usb_serial *serial, + const struct usb_device_id *id) +{ + int retval = -ENODEV; + + if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) { + /* the AT port */ + dev_info(&serial->dev->dev, "Nokia AT Port:\n"); + retval = 0; + } else if (serial->interface->num_altsetting == 2 && + serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) { + /* the FBUS port */ + dev_info(&serial->dev->dev, "Nokia FBUS Port:\n"); + usb_set_interface(serial->dev, 10, 1); + retval = 0; + } + + return retval; +} + +static struct usb_driver nokia_driver = { + .owner = THIS_MODULE, + .name = "nokia_dku2", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + +static struct usb_serial_driver nokia_serial_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "nokia_dku2", + }, + .description = "Nokia 7600/6230(i)/6170/66x0 DKU2 driver", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .probe = nokia_probe, +}; + +static int __init nokia_init(void) +{ + int retval; + + retval = usb_serial_register(&nokia_serial_driver); + if (retval) + return retval; + + retval = usb_register(&nokia_driver); + if (retval) { + usb_serial_deregister(&nokia_serial_driver); + return retval; + } + + info(DRIVER_VERSION " " DRIVER_AUTHOR); + info(DRIVER_DESC); + + return retval; +} + +static void __exit nokia_exit(void) +{ + usb_deregister(&nokia_driver); + usb_serial_deregister(&nokia_serial_driver); +} + +module_init(nokia_init); +module_exit(nokia_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); From ac01bbbd3b7ebfca64357aed12cf476b16abe3ce Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 Oct 2005 20:01:17 +0200 Subject: [PATCH 0910/1940] [SCSI] sas: add flag for locally attached PHYs Add a flag to mark a PHY as attached to the HBA as opposed to beeing on an expander. This is needed because various features are only supported on those. This is a crude hack, the proper fix would be to use different classes for host-attached vs expander phys. I'm looking into that. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 10 +++++++--- drivers/scsi/scsi_transport_sas.c | 3 +++ include/scsi/scsi_transport_sas.h | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 6512027bc69a..dcdf0380be86 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -760,7 +760,7 @@ mptsas_parse_device_info(struct sas_identify *identify, } static int mptsas_probe_one_phy(struct device *dev, - struct mptsas_phyinfo *phy_info, int index) + struct mptsas_phyinfo *phy_info, int index, int local) { struct sas_phy *port; int error; @@ -853,6 +853,9 @@ static int mptsas_probe_one_phy(struct device *dev, break; } + if (local) + port->local_attached = 1; + error = sas_phy_add(port); if (error) { sas_phy_free(port); @@ -918,7 +921,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) } mptsas_probe_one_phy(&ioc->sh->shost_gendev, - &port_info->phy_info[i], *index); + &port_info->phy_info[i], *index, 1); (*index)++; } @@ -989,7 +992,8 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index) } } - mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index); + mptsas_probe_one_phy(parent, &port_info->phy_info[i], + *index, 0); (*index)++; } diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 63445f90097e..f5618c1116f4 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -266,6 +266,9 @@ show_sas_phy_##field(struct class_device *cdev, char *buf) \ struct sas_internal *i = to_sas_internal(shost->transportt); \ int error; \ \ + if (!phy->local_attached) \ + return -EINVAL; \ + \ error = i->f->get_linkerrors(phy); \ if (error) \ return error; \ diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 38389d8dd56e..57eb68c6e9a7 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -56,6 +56,9 @@ struct sas_phy { enum sas_linkrate maximum_linkrate; u8 port_identifier; + /* internal state */ + unsigned int local_attached : 1; + /* link error statistics */ u32 invalid_dword_count; u32 running_disparity_error_count; From 07ba3a954714da10cbd3f6249d93ac2c1df72c4f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 Oct 2005 20:01:31 +0200 Subject: [PATCH 0911/1940] [SCSI] sas: add support for PHY resets Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 43 +++++++++++++++++++++++++++++-- include/scsi/scsi_transport_sas.h | 1 + 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index f5618c1116f4..0cc766a9aa65 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -34,7 +34,7 @@ #define SAS_HOST_ATTRS 0 -#define SAS_PORT_ATTRS 15 +#define SAS_PORT_ATTRS 17 #define SAS_RPORT_ATTRS 5 struct sas_internal { @@ -289,9 +289,39 @@ show_sas_device_type(struct class_device *cdev, char *buf) return snprintf(buf, 20, "none\n"); return get_sas_device_type_names(phy->identify.device_type, buf); } - static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); +static ssize_t do_sas_phy_reset(struct class_device *cdev, + size_t count, int hard_reset) +{ + struct sas_phy *phy = transport_class_to_phy(cdev); + struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); + struct sas_internal *i = to_sas_internal(shost->transportt); + int error; + + if (!phy->local_attached) + return -EINVAL; + + error = i->f->phy_reset(phy, hard_reset); + if (error) + return error; + return count; +}; + +static ssize_t store_sas_link_reset(struct class_device *cdev, + const char *buf, size_t count) +{ + return do_sas_phy_reset(cdev, count, 0); +} +static CLASS_DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset); + +static ssize_t store_sas_hard_reset(struct class_device *cdev, + const char *buf, size_t count) +{ + return do_sas_phy_reset(cdev, count, 1); +} +static CLASS_DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset); + sas_phy_protocol_attr(identify.initiator_port_protocols, initiator_port_protocols); sas_phy_protocol_attr(identify.target_port_protocols, @@ -725,6 +755,13 @@ static struct device *sas_target_parent(struct Scsi_Host *shost, i->phy_attrs[count] = &i->private_phy_attrs[count]; \ count++ +#define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ + i->private_phy_attrs[count] = class_device_attr_##field; \ + i->private_phy_attrs[count].attr.mode = S_IWUGO; \ + i->private_phy_attrs[count].show = NULL; \ + i->phy_attrs[count] = &i->private_phy_attrs[count]; \ + count++ + /** * sas_attach_transport -- instantiate SAS transport template @@ -781,6 +818,8 @@ sas_attach_transport(struct sas_function_template *ft) SETUP_PORT_ATTRIBUTE(running_disparity_error_count); SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); + SETUP_PORT_ATTRIBUTE_WRONLY(link_reset); + SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset); i->phy_attrs[count] = NULL; count = 0; diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 57eb68c6e9a7..b91400bfb02a 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -94,6 +94,7 @@ struct sas_rphy { /* The functions by which the transport class and the driver communicate */ struct sas_function_template { int (*get_linkerrors)(struct sas_phy *); + int (*phy_reset)(struct sas_phy *, int); }; From da4fa65596733914b3c21fdffa02593959c67f56 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 Oct 2005 20:01:42 +0200 Subject: [PATCH 0912/1940] [SCSI] mptsas: add support for PHY resets Support PHY resets in mptsas. Thanks to Eric for various bug fixes and improvements. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 12 +++++ drivers/message/fusion/mptsas.c | 88 ++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 75105277e22f..e705272bc37a 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -421,6 +421,17 @@ typedef struct _MPT_IOCTL { struct semaphore sem_ioc; } MPT_IOCTL; +#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */ +#define MPT_SAS_MGMT_STATUS_COMMAND_GOOD 0x10 /* Command Status GOOD */ +#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */ + +typedef struct _MPT_SAS_MGMT { + struct semaphore mutex; + struct completion done; + u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */ + u8 status; /* current command status */ +}MPT_SAS_MGMT; + /* * Event Structure and define */ @@ -604,6 +615,7 @@ typedef struct _MPT_ADAPTER struct list_head list; struct net_device *netdev; struct list_head sas_topology; + MPT_SAS_MGMT sas_mgmt; } MPT_ADAPTER; /* diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index dcdf0380be86..1c557a09b916 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -83,6 +83,7 @@ MODULE_PARM_DESC(mpt_pt_clear, static int mptsasDoneCtx = -1; static int mptsasTaskCtx = -1; static int mptsasInternalCtx = -1; /* Used only for internal commands */ +static int mptsasMgmtCtx = -1; /* @@ -359,9 +360,92 @@ static int mptsas_get_linkerrors(struct sas_phy *phy) return error; } +static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, + MPT_FRAME_HDR *reply) +{ + ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD; + if (reply != NULL) { + ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID; + memcpy(ioc->sas_mgmt.reply, reply, + min(ioc->reply_sz, 4 * reply->u.reply.MsgLength)); + } + complete(&ioc->sas_mgmt.done); + return 1; +} + +static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) +{ + MPT_ADAPTER *ioc = phy_to_ioc(phy); + SasIoUnitControlRequest_t *req; + SasIoUnitControlReply_t *reply; + MPT_FRAME_HDR *mf; + MPIHeader_t *hdr; + unsigned long timeleft; + int error = -ERESTARTSYS; + + /* not implemented for expanders */ + if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP) + return -ENXIO; + + if (down_interruptible(&ioc->sas_mgmt.mutex)) + goto out; + + mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); + if (!mf) { + error = -ENOMEM; + goto out_unlock; + } + + hdr = (MPIHeader_t *) mf; + req = (SasIoUnitControlRequest_t *)mf; + memset(req, 0, sizeof(SasIoUnitControlRequest_t)); + req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL; + req->MsgContext = hdr->MsgContext; + req->Operation = hard_reset ? + MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET; + req->PhyNum = phy->identify.phy_identifier; + + mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); + + timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, + 10 * HZ); + if (!timeleft) { + /* On timeout reset the board */ + mpt_free_msg_frame(ioc, mf); + mpt_HardResetHandler(ioc, CAN_SLEEP); + error = -ETIMEDOUT; + goto out_unlock; + } + + /* a reply frame is expected */ + if ((ioc->sas_mgmt.status & + MPT_IOCTL_STATUS_RF_VALID) == 0) { + error = -ENXIO; + goto out_unlock; + } + + /* process the completed Reply Message Frame */ + reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; + if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { + printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", + __FUNCTION__, + reply->IOCStatus, + reply->IOCLogInfo); + error = -ENXIO; + goto out_unlock; + } + + error = 0; + + out_unlock: + up(&ioc->sas_mgmt.mutex); + out: + return error; +} static struct sas_function_template mptsas_transport_functions = { .get_linkerrors = mptsas_get_linkerrors, + .phy_reset = mptsas_phy_reset, }; static struct scsi_transport_template *mptsas_transport_template; @@ -1105,6 +1189,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->unique_id = ioc->id; INIT_LIST_HEAD(&ioc->sas_topology); + init_MUTEX(&ioc->sas_mgmt.mutex); + init_completion(&ioc->sas_mgmt.done); /* Verify that we won't exceed the maximum * number of chain buffers @@ -1291,6 +1377,7 @@ mptsas_init(void) mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER); mptsasInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); + mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) { devtprintk((KERN_INFO MYNAM @@ -1314,6 +1401,7 @@ mptsas_exit(void) mpt_reset_deregister(mptsasDoneCtx); mpt_event_deregister(mptsasDoneCtx); + mpt_deregister(mptsasMgmtCtx); mpt_deregister(mptsasInternalCtx); mpt_deregister(mptsasTaskCtx); mpt_deregister(mptsasDoneCtx); From f9a2d2e0c89f73f0203fa796101089c2bce31974 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 Oct 2005 20:01:47 +0200 Subject: [PATCH 0913/1940] [SCSI] mptsas: white space fixes and version bump Various whitespace and comment fixes from Eric, aswell as a version bump. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 4 ++-- drivers/message/fusion/mptsas.c | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index e705272bc37a..e7efeb7740b9 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -77,8 +77,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.03.03" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03" +#define MPT_LINUX_VERSION_COMMON "3.03.04" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.04" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 1c557a09b916..e0a8bb8ba7d8 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -167,12 +167,12 @@ static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0) static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1) { printk("---- SAS PHY PAGE 1 ------------\n"); - printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount); - printk("Running Disparity Error Count=0x%x\n", + printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount); + printk("Running Disparity Error Count=0x%x\n", pg1->RunningDisparityErrorCount); - printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount); - printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount); - printk("\n"); + printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount); + printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount); + printk("\n"); } static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) @@ -188,8 +188,11 @@ static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); printk("Target ID=0x%X\n", pg0->TargetID); printk("Bus=0x%X\n", pg0->Bus); - printk("PhyNum=0x%X\n", pg0->PhyNum); - printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus)); + /* The PhyNum field specifies the PHY number of the parent + * device this device is linked to + */ + printk("Parent Phy Num=0x%X\n", pg0->PhyNum); + printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus)); printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)); printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags)); printk("Physical Port=0x%X\n", pg0->PhysicalPort); @@ -201,7 +204,7 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) printk("---- SAS EXPANDER PAGE 1 ------------\n"); printk("Physical Port=0x%X\n", pg1->PhysicalPort); - printk("PHY Identifier=0x%X\n", pg1->Phy); + printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier); printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate); printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate); printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate); From 91ca7b01ecc916632202180569a7ddbfccfc3f05 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 27 Oct 2005 16:03:37 -0700 Subject: [PATCH 0914/1940] [SCSI] Add an 'Issue LIP' device attribute in fc_transport class Ok, here's a patch to add such a common API for fc transport users. Relevant LLD changes (lpfc and qla2xxx) also present. Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 16 +++++----------- drivers/scsi/qla2xxx/qla_attr.c | 10 ++++++++++ drivers/scsi/qla2xxx/qla_os.c | 7 +++++++ drivers/scsi/scsi_transport_fc.c | 28 ++++++++++++++++++++++++++-- include/scsi/scsi_transport_fc.h | 2 ++ 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index acae7c48ef7d..445da1d0cc88 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) } -static ssize_t -lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) +static int +lpfc_issue_lip(struct Scsi_Host *host) { - struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; - int val = 0; LPFC_MBOXQ_t *pmboxq; int mbxstatus = MBXERR_ERROR; - if ((sscanf(buf, "%d", &val) != 1) || - (val != 1)) - return -EINVAL; - if ((phba->fc_flag & FC_OFFLINE_MODE) || (phba->hba_state != LPFC_HBA_READY)) return -EPERM; @@ -234,7 +228,7 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) if (mbxstatus == MBXERR_ERROR) return -EIO; - return strlen(buf); + return 0; } static ssize_t @@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, NULL); -static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip); static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, lpfc_board_online_show, lpfc_board_online_store); @@ -537,7 +530,6 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, &class_device_attr_management_version, - &class_device_attr_issue_lip, &class_device_attr_board_online, NULL, }; @@ -1234,6 +1226,8 @@ struct fc_function_template lpfc_transport_functions = { .get_starget_port_name = lpfc_get_starget_port_name, .show_starget_port_name = 1, + + .issue_fc_host_lip = lpfc_issue_lip, }; void diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 49696faa24fa..48e460eef05a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -503,6 +503,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) rport->dev_loss_tmo = ha->port_down_retry_count + 5; } +static int +qla2x00_issue_lip(struct Scsi_Host *shost) +{ + scsi_qla_host_t *ha = to_qla_host(shost); + + set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); + return 0; +} + struct fc_function_template qla2xxx_transport_functions = { .show_host_node_name = 1, @@ -526,6 +535,7 @@ struct fc_function_template qla2xxx_transport_functions = { .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, .show_rport_dev_loss_tmo = 1, + .issue_fc_host_lip = qla2x00_issue_lip, }; void diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d9eccdf4f403..b899282a856e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2141,6 +2141,12 @@ qla2x00_do_dpc(void *data) ha->host_no)); } + if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { + DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", + ha->host_no)); + qla2x00_loop_reset(ha); + } + if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { @@ -2442,6 +2448,7 @@ qla2x00_timer(scsi_qla_host_t *ha) /* Schedule the DPC routine if needed */ if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || + test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || start_dpc || test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 473a82d5e3e2..27702097b7fc 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -220,7 +220,7 @@ static void fc_rport_terminate(struct fc_rport *rport); */ #define FC_STARGET_NUM_ATTRS 3 #define FC_RPORT_NUM_ATTRS 9 -#define FC_HOST_NUM_ATTRS 15 +#define FC_HOST_NUM_ATTRS 16 struct fc_internal { struct scsi_transport_template t; @@ -713,9 +713,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ count++ #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ +{ \ i->private_host_attrs[count] = class_device_attr_host_##field; \ i->host_attrs[count] = &i->private_host_attrs[count]; \ - count++ + count++; \ +} /* Fixed Host Attributes */ @@ -853,6 +855,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR, show_fc_private_host_tgtid_bind_type, store_fc_private_host_tgtid_bind_type); +static ssize_t +store_fc_private_host_issue_lip(struct class_device *cdev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = transport_class_to_shost(cdev); + struct fc_internal *i = to_fc_internal(shost->transportt); + int ret; + + /* ignore any data value written to the attribute */ + if (i->f->issue_fc_host_lip) { + ret = i->f->issue_fc_host_lip(shost); + return ret ? ret: count; + } + + return -ENOENT; +} + +static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, + store_fc_private_host_issue_lip); + /* * Host Statistics Management */ @@ -1119,6 +1141,8 @@ fc_attach_transport(struct fc_function_template *ft) /* Transport-managed attributes */ SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); + if (ft->issue_fc_host_lip) + SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); BUG_ON(count > FC_HOST_NUM_ATTRS); diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index b0d445437372..4496b32972e5 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -384,6 +384,8 @@ struct fc_function_template { struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *); void (*reset_fc_host_stats)(struct Scsi_Host *); + int (*issue_fc_host_lip)(struct Scsi_Host *); + /* allocation lengths for host-specific data */ u32 dd_fcrport_size; From 13ec92b33e4f41b81b3a237ad1d9a588a81f2f03 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 24 Oct 2005 18:01:11 -0400 Subject: [PATCH 0915/1940] [SCSI] kill unused scsi_scan_single_target() Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 13 ------------- include/scsi/scsi_host.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index ce8456c3b718..e8f6fee34c94 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1451,19 +1451,6 @@ void scsi_scan_host(struct Scsi_Host *shost) } EXPORT_SYMBOL(scsi_scan_host); -/** - * scsi_scan_single_target - scan the given SCSI target - * @shost: adapter to scan - * @chan: channel to scan - * @id: target id to scan - **/ -void scsi_scan_single_target(struct Scsi_Host *shost, - unsigned int chan, unsigned int id) -{ - scsi_scan_host_selected(shost, chan, id, SCAN_WILD_CARD, 1); -} -EXPORT_SYMBOL(scsi_scan_single_target); - void scsi_forget_host(struct Scsi_Host *shost) { struct scsi_device *sdev; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index ea7ad7235397..ecd53d7872d2 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -638,8 +638,6 @@ extern void scsi_flush_work(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *); extern void scsi_scan_host(struct Scsi_Host *); -extern void scsi_scan_single_target(struct Scsi_Host *, unsigned int, - unsigned int); extern void scsi_rescan_device(struct device *); extern void scsi_remove_host(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); From 01d7b3b8d09ef78e2c835c03d97ea1d91c26e245 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 24 Oct 2005 18:03:34 -0400 Subject: [PATCH 0916/1940] [SCSI] introduce sfoo_printk, sfoo_id, sfoo_channel helpers New dev_printk wrappers, which allow us to shrink code, and eliminate direct references to host/channel/id/lun members: scmd_printk() Introduce wrappers for highly common idioms, which may also help us eliminate some ->{channel,id} references in the future: {scmd,sdev}_id() {scmd,sdev}_channel() The scmd_* wrappers are present in scsi/scsi_device.h because they all employ the dereference chain cmd->device->$member. We would prefer to use static inline functions rather than macros, but that would have a Rejections fixed up and Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 7f621ab2865d..85cfd88461c8 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -151,6 +151,9 @@ struct scsi_device { #define sdev_printk(prefix, sdev, fmt, a...) \ dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) +#define scmd_printk(prefix, scmd, fmt, a...) \ + dev_printk(prefix, &(scmd)->device->sdev_gendev, fmt, ##a) + /* * scsi_target: representation of a scsi target, for now, this is only * used for single_lun devices. If no one has active IO to the target, @@ -272,6 +275,19 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, struct scsi_sense_hdr *, int timeout, int retries); +static inline unsigned int sdev_channel(struct scsi_device *sdev) +{ + return sdev->channel; +} + +static inline unsigned int sdev_id(struct scsi_device *sdev) +{ + return sdev->id; +} + +#define scmd_id(scmd) sdev_id((scmd)->device) +#define scmd_channel(scmd) sdev_channel((scmd)->device) + static inline int scsi_device_online(struct scsi_device *sdev) { return sdev->sdev_state != SDEV_OFFLINE; From 3bf743e7c891d8be8295650b7a6a9b5af083b096 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 24 Oct 2005 18:04:06 -0400 Subject: [PATCH 0917/1940] [SCSI] use {sdev,scmd,starget,shost}_printk in generic code rejections fixed and Signed-off-by: James Bottomley --- drivers/scsi/scsi.c | 5 +++-- drivers/scsi/scsi_debug.c | 15 ++++++--------- drivers/scsi/scsi_error.c | 7 +++---- drivers/scsi/scsi_lib.c | 15 ++++++--------- drivers/scsi/scsi_scan.c | 17 +++++++++-------- drivers/scsi/sr.c | 10 +++++----- drivers/scsi/st.c | 3 +-- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 071d109b4b2a..0be60bba58d3 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -889,8 +889,9 @@ void scsi_finish_command(struct scsi_cmnd *cmd) if (SCSI_SENSE_VALID(cmd)) cmd->result |= (DRIVER_SENSE << 24); - SCSI_LOG_MLCOMPLETE(4, printk("Notifying upper driver of completion " - "for device %d %x\n", sdev->id, cmd->result)); + SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev, + "Notifying upper driver of completion " + "(result %x)\n", cmd->result)); /* * We can get here with use_sg=0, causing a panic in the upper level diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 322b5a41a36f..add190e22c0f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1008,8 +1008,7 @@ static void timer_intr_handler(unsigned long indx) static int scsi_debug_slave_alloc(struct scsi_device * sdp) { if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) - printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", - sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); + sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n"); return 0; } @@ -1018,8 +1017,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) struct sdebug_dev_info * devip; if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) - printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", - sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); + sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n"); if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; devip = devInfoReg(sdp); @@ -1036,8 +1034,7 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) (struct sdebug_dev_info *)sdp->hostdata; if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) - printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", - sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); + sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n"); if (devip) { /* make this slot avaliable for re-use */ devip->used = 0; @@ -1326,9 +1323,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd, if (scsi_result) { struct scsi_device * sdp = cmnd->device; - printk(KERN_INFO "scsi_debug: <%u %u %u %u> " - "non-zero result=0x%x\n", sdp->host->host_no, - sdp->channel, sdp->id, sdp->lun, scsi_result); + sdev_printk(KERN_INFO, sdp, + "non-zero result=0x%x\n", + scsi_result); } } if (cmnd && devip) { diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index dd6a9f61bdf1..f4da56a79ff6 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -673,10 +673,9 @@ static int scsi_eh_get_sense(struct list_head *work_q, SCSI_SENSE_VALID(scmd)) continue; - SCSI_LOG_ERROR_RECOVERY(2, printk("%s: requesting sense" - " for id: %d\n", - current->comm, - scmd->device->id)); + SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd, + "%s: requesting sense\n", + current->comm)); rtn = scsi_request_sense(scmd); if (rtn != SUCCESS) continue; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 19ac888001e6..e40c8b66da40 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -951,16 +951,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, return; } if (!(req->flags & REQ_QUIET)) - sdev_printk(KERN_INFO, - cmd->device, - "Device not ready.\n"); + scmd_printk(KERN_INFO, cmd, + "Device not ready.\n"); scsi_end_request(cmd, 0, this_count, 1); return; case VOLUME_OVERFLOW: if (!(req->flags & REQ_QUIET)) { - sdev_printk(KERN_INFO, - cmd->device, - "Volume overflow, CDB: "); + scmd_printk(KERN_INFO, cmd, + "Volume overflow, CDB: "); __scsi_print_command(cmd->data_cmnd); scsi_print_sense("", cmd); } @@ -981,9 +979,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, } if (result) { if (!(req->flags & REQ_QUIET)) { - sdev_printk(KERN_INFO, cmd->device, - "SCSI error: return code = 0x%x\n", - result); + scmd_printk(KERN_INFO, cmd, + "SCSI error: return code = 0x%x\n", result); if (driver_byte(result) & DRIVER_SENSE) scsi_print_sense("", cmd); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index e8f6fee34c94..7eb3a2d40dc5 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1189,9 +1189,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, num_luns = max_scsi_report_luns; } - SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUN scan of" - " host %d channel %d id %d\n", sdev->host->host_no, - sdev->channel, sdev->id)); + SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, + "scsi scan: REPORT LUN scan\n")); /* * Scan the luns in lun_data. The entry at offset 0 is really @@ -1230,9 +1229,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, /* * Got some results, but now none, abort. */ - printk(KERN_ERR "scsi: Unexpected response" - " from %s lun %d while scanning, scan" - " aborted\n", devname, lun); + sdev_printk(KERN_ERR, sdev, + "Unexpected response" + " from lun %d while scanning, scan" + " aborted\n", lun); break; } } @@ -1417,8 +1417,9 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, unsigned int id, unsigned int lun, int rescan) { - SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n", - __FUNCTION__, shost->host_no, channel, id, lun)); + SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost, + "%s: <%u:%u:%u>\n", + __FUNCTION__, channel, id, lun)); if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || ((id != SCAN_WILD_CARD) && (id > shost->max_id)) || diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 3067e5a7b75e..d68cea753bb2 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) } if (s_size != 512 && s_size != 1024 && s_size != 2048) { - sdev_printk(KERN_ERR, SCpnt->device, "bad sector size %d\n", s_size); + scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); return 0; } @@ -385,9 +385,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) size += sg[i].length; if (size != SCpnt->request_bufflen && SCpnt->use_sg) { - sdev_printk(KERN_ERR, SCpnt->device, - "mismatch count %d, bytes %d\n", - size, SCpnt->request_bufflen); + scmd_printk(KERN_ERR, SCpnt, + "mismatch count %d, bytes %d\n", + size, SCpnt->request_bufflen); if (SCpnt->request_bufflen > size) SCpnt->request_bufflen = SCpnt->bufflen = size; } @@ -398,7 +398,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) */ if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { - sdev_printk(KERN_NOTICE, SCpnt->device, "unaligned transfer\n"); + scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); return 0; } diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index dc5ffc16a252..2913f8792317 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3887,8 +3887,7 @@ static int st_probe(struct device *dev) if (SDp->type != TYPE_TAPE) return -ENODEV; if ((stp = st_incompatible(SDp))) { - sdev_printk(KERN_INFO, SDp, - "Found incompatible tape\n"); + sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n"); printk(KERN_INFO "st: The suggested driver is %s.\n", stp); return -ENODEV; } From 017560fca496f72ed9dd734ffde63ce39dfe0411 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 24 Oct 2005 18:04:36 -0400 Subject: [PATCH 0918/1940] [SCSI] use sfoo_printk() in drivers Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/3w-9xxx.c | 4 +- drivers/scsi/3w-xxxx.c | 4 +- drivers/scsi/53c700.c | 83 ++++++++++++++-------------- drivers/scsi/53c700.h | 8 ++- drivers/scsi/NCR5380.c | 9 ++- drivers/scsi/aha152x.c | 3 +- drivers/scsi/aha1542.c | 3 +- drivers/scsi/aic7xxx/aic79xx_osm.c | 28 +++------- drivers/scsi/aic7xxx/aic7xxx_osm.c | 22 ++------ drivers/scsi/atp870u.c | 7 +-- drivers/scsi/ch.c | 4 +- drivers/scsi/eata.c | 56 ++++++++----------- drivers/scsi/eata_pio.c | 21 +++++-- drivers/scsi/ibmmca.c | 5 +- drivers/scsi/ide-scsi.c | 2 +- drivers/scsi/in2000.c | 2 +- drivers/scsi/ipr.h | 5 +- drivers/scsi/megaraid/megaraid_sas.c | 5 +- drivers/scsi/osst.c | 2 +- drivers/scsi/tmscsim.c | 4 +- drivers/scsi/u14-34f.c | 32 +++++------ 21 files changed, 149 insertions(+), 160 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index a748fbfb6692..d06ee65d668d 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1732,7 +1732,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) tw_dev->num_resets++; - printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]); + sdev_printk(KERN_WARNING, SCpnt->device, + "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", + TW_DRIVER, 0x2c, SCpnt->cmnd[0]); /* Now reset the card and some of the device extension data */ if (twa_reset_device_extension(tw_dev, 0)) { diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index ae9e0203e9de..283f6d25892b 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -1432,7 +1432,9 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt) tw_dev->num_resets++; - printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]); + sdev_printk(KERN_WARNING, SCpnt->device, + "WARNING: Command (0x%x) timed out, resetting card.\n", + SCpnt->cmnd[0]); /* Now reset the card and some of the device extension data */ if (tw_reset_device_extension(tw_dev, 0)) { diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index a7620fc368e7..523d2a97fd27 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -128,6 +128,7 @@ #include #include #include +#include #include #include #include @@ -831,8 +832,8 @@ process_extended_message(struct Scsi_Host *host, } else { /* SDTR message out of the blue, reject it */ - printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n", - host->host_no); + shost_printk(KERN_WARNING, host, + "Unexpected SDTR msg\n"); hostdata->msgout[0] = A_REJECT_MSG; dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); script_patch_16(hostdata->script, MessageCount, 1); @@ -906,15 +907,17 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) { /* rejected our first simple tag message */ - printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun); + scmd_printk(KERN_WARNING, SCp, + "Rejected first tag queue attempt, turning off tag queueing\n"); /* we're done negotiating */ NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION); - hostdata->tag_negotiated &= ~(1<device->id); + hostdata->tag_negotiated &= ~(1<device->tagged_supported = 0; scsi_deactivate_tcq(SCp->device, host->cmd_per_lun); } else { - printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n", - host->host_no, pun, lun, + shost_printk(KERN_WARNING, host, + "(%d:%d) Unexpected REJECT Message %s\n", + pun, lun, NCR_700_phase[(dsps & 0xf00) >> 8]); /* however, just ignore it */ } @@ -983,7 +986,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, if(SCp->cmnd[0] == REQUEST_SENSE) { /* OOPS: bad device, returning another * contingent allegiance condition */ - printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun); + scmd_printk(KERN_ERR, SCp, + "broken device is looping in contingent allegiance: ignoring\n"); NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); } else { #ifdef NCR_DEBUG @@ -1047,12 +1051,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, // SCp->request_bufflen, // DMA_FROM_DEVICE); // if(((char *)SCp->request_buffer)[7] & 0x02) { - // printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun); - // hostdata->tag_negotiated |= (1<device->id); + // scmd_printk(KERN_INFO, SCp, + // "Enabling Tag Command Queuing\n"); + // hostdata->tag_negotiated |= (1<device, NCR_700_DEV_BEGIN_TAG_QUEUEING); // } else { // NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); - // hostdata->tag_negotiated &= ~(1<device->id); + // hostdata->tag_negotiated &= ~(1<status[0]); @@ -1060,11 +1065,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, } else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) { __u8 i = (dsps & 0xf00) >> 8; - printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n", - host->host_no, pun, lun, + scmd_printk(KERN_ERR, SCp, "UNEXPECTED PHASE %s (%s)\n", NCR_700_phase[i], sbcl_to_string(NCR_700_readb(host, SBCL_REG))); - printk(KERN_ERR " len = %d, cmd =", SCp->cmd_len); + scmd_printk(KERN_ERR, SCp, " len = %d, cmd =", + SCp->cmd_len); scsi_print_command(SCp); NCR_700_internal_bus_reset(host); @@ -1115,14 +1120,14 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, } slot = (struct NCR_700_command_slot *)SCp->host_scribble; - DEBUG(("53c700: %d:%d:%d, reselection is tag %d, slot %p(%d)\n", - host->host_no, SDp->id, SDp->lun, - hostdata->msgin[2], slot, slot->tag)); + DDEBUG(KERN_DEBUG, SDp, + "reselection is tag %d, slot %p(%d)\n", + hostdata->msgin[2], slot, slot->tag); } else { struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG); if(unlikely(SCp == NULL)) { - printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", - host->host_no, reselection_id, lun); + sdev_printk(KERN_ERR, SDp, + "no saved request for untagged cmd\n"); BUG(); } slot = (struct NCR_700_command_slot *)SCp->host_scribble; @@ -1764,17 +1769,15 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) * - The blk layer sent and untagged command */ if(NCR_700_get_depth(SCp->device) != 0 - && (!(hostdata->tag_negotiated & (1<device->id)) + && (!(hostdata->tag_negotiated & (1<request))) { - DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun, - NCR_700_get_depth(SCp->device))); + CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n", + NCR_700_get_depth(SCp->device)); return SCSI_MLQUEUE_DEVICE_BUSY; } if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) { - DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun, - NCR_700_get_depth(SCp->device))); + CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n", + NCR_700_get_depth(SCp->device)); return SCSI_MLQUEUE_DEVICE_BUSY; } NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1); @@ -1796,10 +1799,10 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) scsi_print_command(SCp); #endif if(blk_rq_tagged(SCp->request) - && (hostdata->tag_negotiated &(1<device->id)) == 0 + && (hostdata->tag_negotiated &(1<device) == NCR_700_START_TAG_NEGOTIATION) { - printk(KERN_ERR "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); - hostdata->tag_negotiated |= (1<device->id); + scmd_printk(KERN_ERR, SCp, "Enabling Tag Command Queuing\n"); + hostdata->tag_negotiated |= (1<device, NCR_700_DURING_TAG_NEGOTIATION); } @@ -1810,17 +1813,16 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) * FIXME: This will royally screw up on multiple LUN devices * */ if(!blk_rq_tagged(SCp->request) - && (hostdata->tag_negotiated &(1<device->id))) { - printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); - hostdata->tag_negotiated &= ~(1<device->id); + && (hostdata->tag_negotiated &(1<tag_negotiated &= ~(1<tag_negotiated &(1<device->id)) + if((hostdata->tag_negotiated &(1<device)) { slot->tag = SCp->request->tag; - DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag, - slot)); + CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n", + slot->tag, slot); } else { slot->tag = SCSI_NO_TAG; /* must populate current_cmnd for scsi_find_tag to work */ @@ -1920,8 +1922,8 @@ NCR_700_abort(struct scsi_cmnd * SCp) { struct NCR_700_command_slot *slot; - printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun); + scmd_printk(KERN_INFO, SCp, + "New error handler wants to abort command\n\t"); scsi_print_command(SCp); slot = (struct NCR_700_command_slot *)SCp->host_scribble; @@ -1954,8 +1956,8 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp) struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0]; - printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp); + scmd_printk(KERN_INFO, SCp, + "New error handler wants BUS reset, cmd %p\n\t", SCp); scsi_print_command(SCp); /* In theory, eh_complete should always be null because the @@ -1987,8 +1989,7 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp) STATIC int NCR_700_host_reset(struct scsi_cmnd * SCp) { - printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t", - SCp->device->host->host_no, SCp->device->id, SCp->device->lun); + scmd_printk(KERN_INFO, SCp, "New error handler wants HOST reset\n\t"); scsi_print_command(SCp); spin_lock_irq(SCp->device->host->host_lock); diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index e86012cf6ab7..362d78483d09 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h @@ -22,8 +22,14 @@ #ifdef NCR_700_DEBUG #define DEBUG(x) printk x +#define DDEBUG(prefix, sdev, fmt, a...) \ + sdev_printk(prefix, sdev, fmt, ##a) +#define CDEBUG(prefix, scmd, fmt, a...) \ + scmd_printk(prefix, scmd, fmt, ##a) #else -#define DEBUG(x) +#define DEBUG(x) do {} while (0) +#define DDEBUG(prefix, scmd, fmt, a...) do {} while (0) +#define CDEBUG(prefix, scmd, fmt, a...) do {} while (0) #endif /* The number of available command slots */ diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 23392ae7df8b..4368767929f6 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -2190,7 +2190,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { * If the watchdog timer fires, all future accesses to this * device will use the polled-IO. */ - printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun); + scmd_printk(KERN_INFO, cmd, + "switching to slow handshake\n"); cmd->device->borken = 1; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); sink = 1; @@ -2429,9 +2430,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { scsi_print_msg(extended_msg); printk("\n"); } else if (tmp != EXTENDED_MESSAGE) - printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun); + scmd_printk(KERN_INFO, cmd, + "rejecting unknown message %02x\n",tmp); else - printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun); + scmd_printk(KERN_INFO, cmd, + "rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]); msgout = MESSAGE_REJECT; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 630b11575230..9b7caf504a56 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -2921,8 +2921,7 @@ static void disp_enintr(struct Scsi_Host *shpnt) */ static void show_command(Scsi_Cmnd *ptr) { - printk(KERN_DEBUG "0x%08x: target=%d; lun=%d; cmnd=(", - (unsigned int) ptr, ptr->device->id, ptr->device->lun); + scmd_printk(KERN_DEBUG, ptr, "%p: cmnd=(", ptr); __scsi_print_command(ptr->cmnd); diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 9ec4641a6348..adda750412f2 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -1405,7 +1405,8 @@ static int aha1542_dev_reset(Scsi_Cmnd * SCpnt) */ aha1542_out(SCpnt->device->host->io_port, &ahacmd, 1); - printk(KERN_WARNING "aha1542.c: Trying device reset for target %d\n", SCpnt->device->id); + scmd_printk(KERN_WARNING, SCpnt, + "Trying device reset for target\n"); return SUCCESS; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 95c285cc83e4..5e023dca4e52 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -52,6 +52,7 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL; #include /* For fetching system memory size */ #include /* For block_size() */ #include /* For ssleep/msleep */ +#include /* * Bucket size for counting good commands in between bad ones. @@ -565,7 +566,7 @@ ahd_linux_slave_configure(struct scsi_device *sdev) ahd = *((struct ahd_softc **)sdev->host->hostdata); if (bootverbose) - printf("%s: Slave Configure %d\n", ahd_name(ahd), sdev->id); + sdev_printk(KERN_INFO, sdev, "Slave Configure\n"); ahd_linux_device_queue_depth(sdev); @@ -2067,9 +2068,8 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) wait = FALSE; ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - printf("%s:%d:%d:%d: Attempting to queue a%s message:", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun, + scmd_printk(KERN_INFO, cmd, + "Attempting to queue a%s message:", flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); printf("CDB:"); @@ -2093,9 +2093,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * No target device for this command exists, * so we must not still own the command. */ - printf("%s:%d:%d:%d: Is not an active device\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Is not an active device\n"); retval = SUCCESS; goto no_cmd; } @@ -2121,9 +2119,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) } if (pending_scb == NULL) { - printf("%s:%d:%d:%d: Command not found\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Command not found\n"); goto no_cmd; } @@ -2146,9 +2142,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) paused = TRUE; if ((pending_scb->flags & SCB_ACTIVE) == 0) { - printf("%s:%d:%d:%d: Command already completed\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Command already completed\n"); goto no_cmd; } @@ -2214,9 +2208,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) pending_scb->flags |= SCB_RECOVERY_SCB|flag; ahd_outb(ahd, MSG_OUT, HOST_MSG); ahd_outb(ahd, SCSISIGO, last_phase|ATNO); - printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n"); wait = TRUE; } else if (disconnected) { @@ -2277,9 +2269,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) printf("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { - printf("%s:%d:%d:%d: Unable to deliver message\n", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n"); retval = FAILED; goto done; } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 6ee1435d37fa..7074ab95d1cc 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -641,7 +641,7 @@ ahc_linux_slave_configure(struct scsi_device *sdev) ahc = *((struct ahc_softc **)sdev->host->hostdata); if (bootverbose) - printf("%s: Slave Configure %d\n", ahc_name(ahc), sdev->id); + sdev_printk(KERN_INFO, sdev, "Slave Configure\n"); ahc_linux_device_queue_depth(sdev); @@ -2117,9 +2117,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) wait = FALSE; ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - printf("%s:%d:%d:%d: Attempting to queue a%s message\n", - ahc_name(ahc), cmd->device->channel, - cmd->device->id, cmd->device->lun, + scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n", flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); printf("CDB:"); @@ -2183,9 +2181,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) } if (pending_scb == NULL) { - printf("%s:%d:%d:%d: Command not found\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Command not found\n"); goto no_cmd; } @@ -2207,9 +2203,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) paused = TRUE; if ((pending_scb->flags & SCB_ACTIVE) == 0) { - printf("%s:%d:%d:%d: Command already completed\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Command already completed\n"); goto no_cmd; } @@ -2276,9 +2270,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) pending_scb->flags |= SCB_RECOVERY_SCB|flag; ahc_outb(ahc, MSG_OUT, HOST_MSG); ahc_outb(ahc, SCSISIGO, last_phase|ATNO); - printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n"); wait = TRUE; } else if (disconnected) { @@ -2344,9 +2336,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) printf("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { - printf("%s:%d:%d:%d: Unable to deliver message\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n"); retval = FAILED; goto done; } diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a8cfbef304b5..b150bd8e254a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -297,11 +297,10 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *re } workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP - printk(KERN_DEBUG "Channel = %d ID = %d LUN = %d CDB",c,workreq->device->id,workreq->device->lun); - for(l=0;lcmd_len;l++) - { + scmd_printk(KERN_DEBUG, workreq, "CDB"); + for (l = 0; l < workreq->cmd_len; l++) printk(KERN_DEBUG " %x",workreq->cmnd[l]); - } + printk("\n"); #endif tmport = workport + 0x0f; diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index da6e51c7fe69..833241508070 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -940,9 +940,7 @@ static int ch_probe(struct device *dev) MKDEV(SCSI_CHANGER_MAJOR,ch->minor), dev, "s%s", ch->name); - printk(KERN_INFO "Attached scsi changer %s " - "at scsi%d, channel %d, id %d, lun %d\n", - ch->name, sd->host->host_no, sd->channel, sd->id, sd->lun); + sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); spin_lock(&ch_devlist_lock); list_add_tail(&ch->list,&ch_devlist); diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 3d13fdee4fc2..b45a4c730230 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -941,8 +941,6 @@ static int eata2x_slave_configure(struct scsi_device *dev) { int tqd, utqd; char *tag_suffix, *link_suffix; - struct Scsi_Host *shost = dev->host; - struct hostdata *ha = (struct hostdata *)shost->hostdata; utqd = MAX_CMD_PER_LUN; tqd = max_queue_depth; @@ -973,8 +971,8 @@ static int eata2x_slave_configure(struct scsi_device *dev) else link_suffix = ""; - printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", - ha->board_name, shost->host_no, dev->channel, dev->id, dev->lun, + sdev_printk(KERN_INFO, dev, + "cmds/lun %d%s%s.\n", dev->queue_depth, link_suffix, tag_suffix); return 0; @@ -1813,9 +1811,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index; if (do_trace) - printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", - ha->board_name, i, SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid); + scmd_printk(KERN_INFO, SCpnt, + "qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid); cpp->reqsen = 1; cpp->dispri = 1; @@ -1847,9 +1844,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { unmap_dma(i, ha); SCpnt->host_scribble = NULL; - printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", - ha->board_name, SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid); + scmd_printk(KERN_INFO, SCpnt, + "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); return 1; } @@ -1864,16 +1860,14 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) unsigned int i; if (SCarg->host_scribble == NULL) { - printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - ha->board_name, SCarg->device->channel, SCarg->device->id, - SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_INFO, SCarg, + "abort, pid %ld inactive.\n", SCarg->pid); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; - printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - ha->board_name, i, SCarg->device->channel, SCarg->device->id, - SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_WARNING, SCarg, + "abort, mbox %d, pid %ld.\n", i, SCarg->pid); if (i >= shost->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); @@ -1934,9 +1928,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) struct Scsi_Host *shost = SCarg->device->host; struct hostdata *ha = (struct hostdata *)shost->hostdata; - printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - ha->board_name, SCarg->device->channel, SCarg->device->id, - SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_INFO, SCarg, + "reset, enter, pid %ld.\n", SCarg->pid); spin_lock_irq(shost->host_lock); @@ -2253,12 +2246,11 @@ static int reorder(struct hostdata *ha, unsigned long cursec, k = il[n]; cpp = &ha->cp[k]; SCpnt = cpp->SCpnt; - printk - ("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld" + scmd_printk(KERN_INFO, SCpnt, + "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld" " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid, k, flushcount, + SCpnt->pid, k, flushcount, n_ready, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), @@ -2301,12 +2293,11 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, SCpnt = cpp->SCpnt; if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { - printk - ("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter" - " busy, will abort.\n", ha->board_name, + scmd_printk(KERN_INFO, SCpnt, + "%s, pid %ld, mbox %d, adapter" + " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid, k); + SCpnt->pid, k); ha->cp_stat[k] = ABORTING; continue; } @@ -2542,11 +2533,10 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) spp->adapter_status != ASST && ha->iocount <= 1000) || do_trace || msg_byte(spp->target_status)) #endif - printk("%s: ihdlr, mbox %2d, err 0x%x:%x," - " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", - ha->board_name, i, spp->adapter_status, spp->target_status, - SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid, reg, ha->iocount); + scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," + " pid %ld, reg 0x%x, count %d.\n", + i, spp->adapter_status, spp->target_status, + SCpnt->pid, reg, ha->iocount); unmap_dma(i, ha); diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 42c6e35f801c..23beb48c79c5 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -384,7 +384,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, cp->status = USED; /* claim free slot */ - DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->device->id, cmd->device->lun, y)); + DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, + "eata_pio_queue pid %ld, y %d\n", + cmd->pid, y)); cmd->scsi_done = (void *) done; @@ -427,7 +429,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) { cmd->result = DID_BUS_BUSY << 16; - printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->device->id, cmd->pid); + scmd_printk(KERN_NOTICE, cmd, + "eata_pio_queue pid %ld, HBA busy, " + "returning DID_BUS_BUSY, done.\n", cmd->pid); done(cmd); cp->status = FREE; return (0); @@ -440,7 +444,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA); - DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->device->id, cmd->device->lun, y, sh->irq)); + DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, + "Queued base %#.4lx pid: %ld " + "slot %d irq %d\n", (long) sh->base, cmd->pid, y, sh->irq)); return (0); } @@ -449,8 +455,9 @@ static int eata_pio_abort(struct scsi_cmnd *cmd) { uint loop = HZ; - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun)); - + DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, + "eata_pio_abort called pid: %ld\n", + cmd->pid)); while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) if (--loop == 0) { @@ -484,7 +491,9 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd) struct scsi_cmnd *sp; struct Scsi_Host *host = cmd->device->host; - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun)); + DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, + "eata_pio_reset called pid:%ld\n", + cmd->pid)); spin_lock_irq(host->host_lock); diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 19392f651272..887a5c3ded28 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -1860,7 +1860,10 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) next_ldn(host_index) = 7; if (current_ldn == next_ldn(host_index)) { /* One circle done ? */ /* no non-processing ldn found */ - printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" " On ldn 7-14 SCSI-commands everywhere in progress.\n" " Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->device->lun); + scmd_printk(KERN_WARNING, cmd, + "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" + " On ldn 7-14 SCSI-commands everywhere in progress.\n" + " Reporting DID_NO_CONNECT for device.\n"); cmd->result = DID_NO_CONNECT << 16; /* return no connect */ if (done) done(cmd); diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3d62c9bcbff7..01f8ebf8a42e 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -893,7 +893,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, idescsi_pc_t *pc = NULL; if (!drive) { - printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->device->id); + scmd_printk (KERN_ERR, cmd, "drive not present\n"); goto abort; } scsi = drive_to_idescsi(drive); diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index aed7e64865fa..fe387b5ce8bd 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -343,7 +343,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) instance = cmd->device->host; hostdata = (struct IN2000_hostdata *) instance->hostdata; - DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->device->id, cmd->cmnd[0], cmd->pid)) + DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->pid)) /* Set up a few fields in the Scsi_Cmnd structure for our own use: * - host_scribble is the pointer to the next cmd in the input queue diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index cbff3ea3cd89..8cf967108500 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1114,9 +1114,8 @@ struct ipr_ucode_image_header { #define ipr_warn(...) printk(KERN_WARNING IPR_NAME": "__VA_ARGS__) #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) -#define ipr_sdev_printk(level, sdev, fmt, ...) \ - printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, sdev->host->host_no, \ - sdev->channel, sdev->id, sdev->lun, ##__VA_ARGS__) +#define ipr_sdev_printk(level, sdev, fmt, args...) \ + sdev_printk(level, sdev, fmt, ## args) #define ipr_sdev_err(sdev, fmt, ...) \ ipr_sdev_printk(KERN_ERR, sdev, fmt, ##__VA_ARGS__) diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index c3f637395734..4245d05e628b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -758,9 +758,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; - printk(KERN_NOTICE "megasas: RESET -%ld cmd=%x \n", - scmd->serial_number, scmd->cmnd[0], scmd->device->channel, - scmd->device->id, scmd->device->lun); + scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n", + scmd->serial_number, scmd->cmnd[0]); if (instance->hw_crit_error) { printk(KERN_ERR "megasas: cannot recover from previous reset " diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index c1131c9cae64..011f3c8fe56f 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5819,7 +5819,7 @@ static int osst_probe(struct device *dev) } drive->number = devfs_register_tape(SDp->devfs_name); - dev_printk(KERN_INFO, &SDp->sdev_gendev, + sdev_printk(KERN_INFO, &SDp, "osst :I: Attached OnStream %.5s tape as %s\n", SDp->model, tape_name(tpnt)); diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 386bd6c67e73..91322aff241d 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -2085,8 +2085,8 @@ static int DC390_abort(struct scsi_cmnd *cmd) struct dc390_acb *pACB = (struct dc390_acb*) cmd->device->host->hostdata; struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata; - printk("DC390: Abort command (pid %li, Device %02i-%02i)\n", - cmd->pid, cmd->device->id, cmd->device->lun); + scmd_printk(KERN_WARNING, cmd, + "DC390: Abort command (pid %li)\n", cmd->pid); /* abort() is too stupid for already sent commands at the moment. * If it's called we are in trouble anyway, so let's dump some info diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index b0b6cdf02cbd..e778e17d57f0 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -726,8 +726,7 @@ static int u14_34f_slave_configure(struct scsi_device *dev) { else link_suffix = ""; - printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", - BN(j), host->host_no, dev->channel, dev->id, dev->lun, + sdev_printk(KERN_INFO, dev, "cmds/lun %d%s%s.\n", dev->queue_depth, link_suffix, tag_suffix); return FALSE; @@ -1319,8 +1318,8 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { unmap_dma(i, j); SCpnt->host_scribble = NULL; - printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", - BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid); + scmd_printk(KERN_INFO, SCpnt, + "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); return 1; } @@ -1340,14 +1339,14 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; if (SCarg->host_scribble == NULL) { - printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n", + SCarg->pid); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; - printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n", + i, SCarg->pid); if (i >= sh[j]->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); @@ -1405,8 +1404,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { struct scsi_cmnd *SCpnt; j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; - printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); + scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->pid); spin_lock_irq(sh[j]->host_lock); @@ -1709,9 +1707,10 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\ - " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k); + scmd_printk(KERN_INFO, SCpnt, + "%s, pid %ld, mbox %d, adapter" + " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), + SCpnt->pid, k); HD(j)->cp_stat[k] = ABORTING; continue; } @@ -1914,10 +1913,9 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { spp->adapter_status != ASST && HD(j)->iocount <= 1000) || do_trace || msg_byte(spp->target_status)) #endif - printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\ - " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", - BN(j), i, spp->adapter_status, spp->target_status, - SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, + scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\ + " pid %ld, reg 0x%x, count %d.\n", + i, spp->adapter_status, spp->target_status, SCpnt->pid, reg, HD(j)->iocount); unmap_dma(i, j); From 422c0d61d591cbfb70f029e13505fb437e169d68 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 24 Oct 2005 18:05:09 -0400 Subject: [PATCH 0919/1940] [SCSI] use scmd_id(), scmd_channel() throughout code Wrap a highly common idiom. Makes the code easier to read, helps pave the way for sdev->{id,channel} removal, and adds a token that can easily by grepped-for in the future. There are a couple sdev_id() and scmd_printk() updates thrown in as well. Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/53c700.c | 6 +++--- drivers/scsi/NCR5380.c | 12 ++++++------ drivers/scsi/NCR53C9x.c | 16 ++++++++-------- drivers/scsi/NCR53c406a.c | 2 +- drivers/scsi/a100u2w.c | 2 +- drivers/scsi/aacraid/aachba.c | 8 ++++---- drivers/scsi/aha1740.c | 2 +- drivers/scsi/aic7xxx/aic79xx_osm.c | 11 ++++++----- drivers/scsi/aic7xxx/aic7xxx_osm.c | 10 +++++----- drivers/scsi/atp870u.c | 22 +++++++++++----------- drivers/scsi/fd_mcs.c | 4 ++-- drivers/scsi/fdomain.c | 4 ++-- drivers/scsi/imm.c | 2 +- drivers/scsi/ips.c | 10 +++++----- drivers/scsi/ncr53c8xx.c | 8 ++++---- drivers/scsi/nsp32.c | 8 ++++---- drivers/scsi/pcmcia/nsp_cs.c | 10 +++++----- drivers/scsi/pcmcia/sym53c500_cs.c | 2 +- drivers/scsi/ppa.c | 2 +- drivers/scsi/psi240i.c | 2 +- drivers/scsi/qlogicfas408.c | 4 ++-- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/scsi_error.c | 16 +++++++++------- drivers/scsi/sym53c416.c | 2 +- drivers/scsi/u14-34f.c | 15 +++++++-------- 25 files changed, 92 insertions(+), 90 deletions(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 523d2a97fd27..e7ad269041a4 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1427,7 +1427,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp) * If a contingent allegiance condition exists, the device * will refuse all tags, so send the request sense as untagged * */ - if((hostdata->tag_negotiated & (1<device->id)) + if((hostdata->tag_negotiated & (1<tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); } @@ -1446,7 +1446,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp) script_patch_ID(hostdata->script, - Device_ID, 1<device->id); + Device_ID, 1<script, CommandAddress, slot->pCmd); @@ -2111,7 +2111,7 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type) /* shift back to the default unqueued number of commands * (the user can still raise this) */ scsi_deactivate_tcq(SDp, SDp->host->cmd_per_lun); - hostdata->tag_negotiated &= ~(1 << SDp->id); + hostdata->tag_negotiated &= ~(1 << sdev_id(SDp)); } else { /* Here, we cleared the negotiation flag above, so this * will force the driver to renegotiate */ diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 4368767929f6..cc9ecb35b412 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -1247,13 +1247,13 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd) case WRITE: case WRITE_6: case WRITE_10: - hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase); + hostdata->time_write[scmd_id(cmd)] += (jiffies - hostdata->timebase); hostdata->pendingw--; break; case READ: case READ_6: case READ_10: - hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase); + hostdata->time_read[scmd_id(cmd)] += (jiffies - hostdata->timebase); hostdata->pendingr--; break; } @@ -1385,7 +1385,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) * the host and target ID's on the SCSI bus. */ - NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id))); + NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd)))); /* * Raise ATN while SEL is true before BSY goes false from arbitration, @@ -1430,7 +1430,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) udelay(1); - dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->device->id)); + dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd))); /* * The SCSI specification calls for a 250 ms timeout for the actual @@ -1483,7 +1483,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - if (hostdata->targets_present & (1 << cmd->device->id)) { + if (hostdata->targets_present & (1 << scmd_id(cmd))) { printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no); if (hostdata->restart_select) printk(KERN_DEBUG "\trestart select\n"); @@ -1499,7 +1499,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); return 0; } - hostdata->targets_present |= (1 << cmd->device->id); + hostdata->targets_present |= (1 << scmd_id(cmd)); /* * Since we followed the SCSI spec, and raised ATN while SEL diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 6ceabbd42a3d..26146a4b67b8 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -936,7 +936,7 @@ static void esp_release_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; + struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)]; sp->SCp.ptr = ep->saved_ptr; sp->SCp.buffer = ep->saved_buffer; @@ -946,7 +946,7 @@ static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp) static void esp_save_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; + struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)]; ep->saved_ptr = sp->SCp.ptr; ep->saved_buffer = sp->SCp.buffer; @@ -1693,13 +1693,13 @@ static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs, if(esp->prev_soff != esp_dev->sync_max_offset || esp->prev_stp != esp_dev->sync_min_period || (esp->erev > esp100a && - esp->prev_cfg3 != esp->config3[sp->device->id])) { + esp->prev_cfg3 != esp->config3[scmd_id(sp)])) { esp->prev_soff = esp_dev->sync_max_offset; esp_write(eregs->esp_soff, esp->prev_soff); esp->prev_stp = esp_dev->sync_min_period; esp_write(eregs->esp_stp, esp->prev_stp); if(esp->erev > esp100a) { - esp->prev_cfg3 = esp->config3[sp->device->id]; + esp->prev_cfg3 = esp->config3[scmd_id(sp)]; esp_write(eregs->esp_cfg3, esp->prev_cfg3); } } @@ -2205,7 +2205,7 @@ static int esp_do_freebus(struct NCR_ESP *esp, struct ESP_regs *eregs) if(SCptr->SCp.Status != GOOD && SCptr->SCp.Status != CONDITION_GOOD && - ((1<device->id) & esp->targets_present) && + ((1<targets_present) && esp_dev->sync && esp_dev->sync_max_offset) { /* SCSI standard says that the synchronous capabilities * should be renegotiated at this point. Most likely @@ -2597,7 +2597,7 @@ static int esp_select_complete(struct NCR_ESP *esp, struct ESP_regs *eregs) */ if(esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) { /* target speaks... */ - esp->targets_present |= (1<device->id); + esp->targets_present |= (1<snip) @@ -3064,7 +3064,7 @@ static int check_multibyte_msg(struct NCR_ESP *esp, ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n", esp_dev->sync_max_offset, esp_dev->sync_min_period, - esp->config3[SCptr->device->id])); + esp->config3[scmd_id(SCptr)])); esp->snip = 0; } else if(esp_dev->sync_max_offset) { @@ -3621,7 +3621,7 @@ void esp_slave_destroy(Scsi_Device *SDptr) { struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata; - esp->targets_present &= ~(1 << SDptr->id); + esp->targets_present &= ~(1 << sdev_id(SDptr)); kfree(SDptr->hostdata); SDptr->hostdata = NULL; } diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index e1f2246ee7cd..135376992a57 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -710,7 +710,7 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) /* We are locked here already by the mid layer */ REG0; - outb(SCpnt->device->id, DEST_ID); /* set destination */ + outb(scmd_id(SCpnt), DEST_ID); /* set destination */ outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */ for (i = 0; i < SCpnt->cmd_len; i++) { diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index c34403c30483..9f45ae1745da 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -923,7 +923,7 @@ static int inia100_device_reset(struct scsi_cmnd * SCpnt) { /* I need Host Control Block Information */ ORC_HCS *pHCB; pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; - return orc_device_reset(pHCB, SCpnt, SCpnt->device->id); + return orc_device_reset(pHCB, SCpnt, scmd_id(SCpnt)); } diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index acc3d9209879..2a128a156aa1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1464,7 +1464,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * Test does not apply to ID 16, the pseudo id for the controller * itself. */ - if (scsicmd->device->id != host->this_id) { + if (scmd_id(scsicmd) != host->this_id) { if ((scsicmd->device->channel == 0) ){ if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ scsicmd->result = DID_NO_CONNECT << 16; @@ -1559,7 +1559,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * Set the Vendor, Product, and Revision Level * see: .c i.e. aac.c */ - if (scsicmd->device->id == host->this_id) { + if (scmd_id(scsicmd) == host->this_id) { setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); @@ -1949,7 +1949,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) * the channel is 2 */ } else if ((dev->raid_scsi_mode) && - (scsicmd->device->channel == 2)) { + (scmd_channel(scsicmd) == 2)) { scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; } else { @@ -1993,7 +1993,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) * the channel is 2 */ } else if ((dev->raid_scsi_mode) && - (scsicmd->device->channel == 2)) { + (scmd_channel(scsicmd) == 2)) { scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; } else { diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 73f33e716a0c..8f85dcc0e7fa 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -347,7 +347,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) { unchar direction; unchar *cmd = (unchar *) SCpnt->cmnd; - unchar target = SCpnt->device->id; + unchar target = scmd_id(SCpnt); struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host); unsigned long flags; void *buff = SCpnt->request_buffer; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 5e023dca4e52..cfb46c241b38 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -398,7 +398,7 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) /******************************** Macros **************************************/ #define BUILD_SCSIID(ahd, cmd) \ - ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) + (((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id) /* * Return a string describing the driver. @@ -685,7 +685,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd) ahd_name(ahd), cmd); #endif ahd_lock(ahd, &s); - found = ahd_reset_channel(ahd, cmd->device->channel + 'A', + found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A', /*initiate reset*/TRUE); ahd_unlock(ahd, &s); @@ -2110,8 +2110,9 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) /* Any SCB for this device will do for a target reset */ LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { - if (ahd_match_scb(ahd, pending_scb, cmd->device->id, - cmd->device->channel + 'A', + if (ahd_match_scb(ahd, pending_scb, + scmd_id(cmd), + scmd_channel(cmd) + 'A', CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR) == 0) break; @@ -2198,7 +2199,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) if (last_phase != P_BUSFREE && (SCB_GET_TAG(pending_scb) == active_scbptr || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahd, saved_scsiid) == cmd->device->id))) { + && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd)))) { /* * We're active on the bus, so assert ATN diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 7074ab95d1cc..1861407422e4 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -686,7 +686,7 @@ ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, u_int channel; ahc = *((struct ahc_softc **)sdev->host->hostdata); - channel = sdev->channel; + channel = sdev_channel(sdev); bh = scsi_bios_ptable(bdev); if (bh) { @@ -759,7 +759,7 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd) ahc = *(struct ahc_softc **)cmd->device->host->hostdata; ahc_lock(ahc, &flags); - found = ahc_reset_channel(ahc, cmd->device->channel + 'A', + found = ahc_reset_channel(ahc, scmd_channel(cmd) + 'A', /*initiate reset*/TRUE); ahc_unlock(ahc, &flags); @@ -2172,8 +2172,8 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) /* Any SCB for this device will do for a target reset */ LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (ahc_match_scb(ahc, pending_scb, cmd->device->id, - cmd->device->channel + 'A', + if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd), + scmd_channel(cmd) + 'A', CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR) == 0) break; @@ -2260,7 +2260,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) if (last_phase != P_BUSFREE && (pending_scb->hscb->tag == active_scb_index || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) { + && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) { /* * We're active on the bus, so assert ATN diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b150bd8e254a..5227a779c05c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -621,10 +621,10 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p, struct atp_unit *dev; struct Scsi_Host *host; - c = req_p->device->channel; + c = scmd_channel(req_p); req_p->sense_buffer[0]=0; req_p->resid = 0; - if (req_p->device->channel > 1) { + if (scmd_channel(req_p) > 1) { req_p->result = 0x00040000; done(req_p); #ifdef ED_DBGP @@ -639,7 +639,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p, m = 1; - m = m << req_p->device->id; + m = m << scmd_id(req_p); /* * Fake a timeout for missing targets @@ -757,9 +757,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->quhd[c] = 0; } workreq = dev->quereq[c][dev->quhd[c]]; - if (dev->id[c][workreq->device->id].curr_req == 0) { - dev->id[c][workreq->device->id].curr_req = workreq; - dev->last_cmd[c] = workreq->device->id; + if (dev->id[c][scmd_id(workreq)].curr_req == 0) { + dev->id[c][scmd_id(workreq)].curr_req = workreq; + dev->last_cmd[c] = scmd_id(workreq); goto cmd_subp; } dev->quhd[c] = j; @@ -786,16 +786,16 @@ static void send_s870(struct atp_unit *dev,unsigned char c) oktosend: #ifdef ED_DBGP printk("OK to Send\n"); - printk("CDB"); + scmd_printk(KERN_DEBUG, workreq, "CDB"); for(i=0;icmd_len;i++) { printk(" %x",workreq->cmnd[i]); } - printk("\nChannel = %d ID = %d LUN = %d\n",c,workreq->device->id,workreq->device->lun); + printk("\n"); #endif if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); - dev->r1f[c][workreq->device->id] = 0; + dev->r1f[c][scmd_id(workreq)] = 0; } if (workreq->cmnd[0] == READ_CAPACITY) { @@ -809,7 +809,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) tmport = workport + 0x1b; j = 0; - target_id = workreq->device->id; + target_id = scmd_id(workreq); /* * Wide ? @@ -3108,7 +3108,7 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) host = SCpnt->device->host; dev = (struct atp_unit *)&host->hostdata; - c=SCpnt->device->channel; + c = scmd_channel(SCpnt); printk(" atp870u: abort Channel = %x \n", c); printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index d59d449a9e4d..6d44602aae78 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -671,7 +671,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs) outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port); outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */ - outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port); + outb(adapter_mask | (1 << scmd_id(current_SC)), SCSI_Data_NoACK_port); /* Stop arbitration and enable parity */ outb(0x10 | PARITY_MASK, TMC_Cntl_port); @@ -683,7 +683,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs) status = inb(SCSI_Status_port); if (!(status & 0x01)) { /* Try again, for slow devices */ - if (fd_mcs_select(shpnt, current_SC->device->id)) { + if (fd_mcs_select(shpnt, scmd_id(current_SC))) { #if EVERY_ACCESS printk(" SFAIL "); #endif diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 3b2a5bf5c43e..7334244397d1 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -1154,7 +1154,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl); outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */ - outb(adapter_mask | (1 << current_SC->device->id), port_base + SCSI_Data_NoACK); + outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK); /* Stop arbitration and enable parity */ outb(0x10 | PARITY_MASK, port_base + TMC_Cntl); @@ -1166,7 +1166,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, status = inb(port_base + SCSI_Status); if (!(status & 0x01)) { /* Try again, for slow devices */ - if (fdomain_select( current_SC->device->id )) { + if (fdomain_select( scmd_id(current_SC) )) { #if EVERY_ACCESS printk( " SFAIL " ); #endif diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 65e845665b85..fc0f30ae0f77 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -830,7 +830,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd) /* Phase 2 - We are now talking to the scsi bus */ case 2: - if (!imm_select(dev, cmd->device->id)) { + if (!imm_select(dev, scmd_id(cmd))) { imm_fail(dev, DID_NO_CONNECT); return 0; } diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 4cdd891781b1..eeae7ccb0dd2 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1125,8 +1125,8 @@ ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *)) SC->device->channel, SC->device->id, SC->device->lun); /* Check for command to initiator IDs */ - if ((SC->device->channel > 0) - && (SC->device->id == ha->ha_id[SC->device->channel])) { + if ((scmd_channel(SC) > 0) + && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) { SC->result = DID_NO_CONNECT << 16; done(SC); @@ -2830,10 +2830,10 @@ ips_next(ips_ha_t * ha, int intr) p = ha->scb_waitlist.head; while ((p) && (scb = ips_getscb(ha))) { - if ((p->device->channel > 0) + if ((scmd_channel(p) > 0) && (ha-> - dcdb_active[p->device->channel - - 1] & (1 << p->device->id))) { + dcdb_active[scmd_channel(p) - + 1] & (1 << scmd_id(p)))) { ips_freescb(ha, scb); p = (Scsi_Cmnd *) p->host_scribble; continue; diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 9a4f576c0d5e..243470936fab 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -3669,7 +3669,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) /* ** select */ - cp->phys.select.sel_id = sdev->id; + cp->phys.select.sel_id = sdev_id(sdev); cp->phys.select.sel_scntl3 = tp->wval; cp->phys.select.sel_sxfer = tp->sval; /* @@ -4820,7 +4820,7 @@ static void ncr_set_sync_wide_status (struct ncb *np, u_char target) */ for (cp = np->ccb; cp; cp = cp->link_ccb) { if (!cp->cmd) continue; - if (cp->cmd->device->id != target) continue; + if (scmd_id(cp->cmd) != target) continue; #if 0 cp->sync_status = tp->sval; cp->wide_status = tp->wval; @@ -4844,7 +4844,7 @@ static void ncr_setsync (struct ncb *np, struct ccb *cp, u_char scntl3, u_char s u_char target = INB (nc_sdid) & 0x0f; u_char idiv; - BUG_ON(target != (cmd->device->id & 0xf)); + BUG_ON(target != (scmd_id(cmd) & 0xf)); tp = &np->target[target]; @@ -4902,7 +4902,7 @@ static void ncr_setwide (struct ncb *np, struct ccb *cp, u_char wide, u_char ack u_char scntl3; u_char sxfer; - BUG_ON(target != (cmd->device->id & 0xf)); + BUG_ON(target != (scmd_id(cmd) & 0xf)); tp = &np->target[target]; tp->widedone = wide+1; diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 6367f009cd74..e4ff4f00676d 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -481,7 +481,7 @@ static int nsp32_selection_autopara(struct scsi_cmnd *SCpnt) nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; unsigned int base = SCpnt->device->host->io_port; unsigned int host_id = SCpnt->device->host->this_id; - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); nsp32_autoparam *param = data->autoparam; unsigned char phase; int i, ret; @@ -612,7 +612,7 @@ static int nsp32_selection_autoscsi(struct scsi_cmnd *SCpnt) nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; unsigned int base = SCpnt->device->host->io_port; unsigned int host_id = SCpnt->device->host->this_id; - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); unsigned char phase; int status; unsigned short command = 0; @@ -973,7 +973,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ } /* check target ID is not same as this initiator ID */ - if (SCpnt->device->id == SCpnt->device->host->this_id) { + if (scmd_id(SCpnt) == SCpnt->device->host->this_id) { nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "terget==host???"); SCpnt->result = DID_BAD_TARGET << 16; done(SCpnt); @@ -1028,7 +1028,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ * (target don't have SDTR_DONE and SDTR_INITIATOR), sync * message SDTR is needed to do synchronous transfer. */ - target = &data->target[SCpnt->device->id]; + target = &data->target[scmd_id(SCpnt)]; data->cur_target = target; if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) { diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 3cd3b40b1a4c..3d2f71051fe5 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -201,7 +201,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) #ifdef NSP_DEBUG /*unsigned int host_id = SCpnt->device->host->this_id;*/ /*unsigned int base = SCpnt->device->host->io_port;*/ - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); #endif nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -373,7 +373,7 @@ static int nsphw_start_selection(Scsi_Cmnd *SCpnt) { unsigned int host_id = SCpnt->device->host->this_id; unsigned int base = SCpnt->device->host->io_port; - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; int time_out; unsigned char phase, arbit; @@ -452,7 +452,7 @@ static struct nsp_sync_table nsp_sync_table_20M[] = { */ static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) { - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); // unsigned char lun = SCpnt->device->lun; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; sync_data *sync = &(data->Sync[target]); @@ -677,7 +677,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt) target++; } - if (SCpnt->device->id != target) { + if (scmd_id(SCpnt) != target) { nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target); } @@ -912,7 +912,7 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt) static int nsp_nexus(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; - unsigned char target = SCpnt->device->id; + unsigned char target = scmd_id(SCpnt); // unsigned char lun = SCpnt->device->lun; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; sync_data *sync = &(data->Sync[target]); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index b4b3a1a8a0c7..98b64b2aa8ee 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -610,7 +610,7 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* We are locked here already by the mid layer */ REG0(port_base); - outb(SCpnt->device->id, port_base + DEST_ID); /* set destination */ + outb(scmd_id(SCpnt), port_base + DEST_ID); /* set destination */ outb(FLUSH_FIFO, port_base + CMD_REG); /* reset the fifos */ for (i = 0; i < SCpnt->cmd_len; i++) { diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index fafcf5d185e7..05347eed9dd5 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -740,7 +740,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd) } case 2: /* Phase 2 - We are now talking to the scsi bus */ - if (!ppa_select(dev, cmd->device->id)) { + if (!ppa_select(dev, scmd_id(cmd))) { ppa_fail(dev, DID_NO_CONNECT); return 0; } diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index 0f576d4ad0dd..4322c95c995c 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -659,7 +659,7 @@ static int Psi240i_BiosParam (struct scsi_device *sdev, struct block_device *dev { POUR_DEVICE pdev; - pdev = &(HOSTDATA(sdev->host)->device[sdev->id]); + pdev = &(HOSTDATA(sdev->host)->device[sdev_id(sdev)]); geom[0] = pdev->heads; geom[1] = pdev->sectors; diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index cb75e0b7baea..52fb2ec3da70 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -243,7 +243,7 @@ static void ql_icmd(Scsi_Cmnd * cmd) /**/ outb(qlcfg5, qbase + 5); /* select timer */ outb(qlcfg9 & 7, qbase + 9); /* prescaler */ /* outb(0x99, qbase + 5); */ - outb(cmd->device->id, qbase + 4); + outb(scmd_id(cmd), qbase + 4); for (i = 0; i < cmd->cmd_len; i++) outb(cmd->cmnd[i], qbase + 2); @@ -450,7 +450,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs) int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); - if (cmd->device->id == priv->qinitid) { + if (scmd_id(cmd) == priv->qinitid) { cmd->result = DID_BAD_TARGET << 16; done(cmd); return 0; diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index add190e22c0f..aadf051274fa 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -283,7 +283,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) unsigned char *cmd = (unsigned char *) SCpnt->cmnd; int block, upper_blk, num, k; int errsts = 0; - int target = SCpnt->device->id; + int target = scmd_id(SCpnt); struct sdebug_dev_info * devip = NULL; int inj_recovered = 0; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index f4da56a79ff6..0c5b02d4c7f8 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1033,7 +1033,8 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) if (!scmd->device->host->hostt->skip_settle_delay) ssleep(BUS_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); - scsi_report_bus_reset(scmd->device->host, scmd->device->channel); + scsi_report_bus_reset(scmd->device->host, + scmd_channel(scmd)); spin_unlock_irqrestore(scmd->device->host->host_lock, flags); } @@ -1061,7 +1062,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) if (!scmd->device->host->hostt->skip_settle_delay) ssleep(HOST_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); - scsi_report_bus_reset(scmd->device->host, scmd->device->channel); + scsi_report_bus_reset(scmd->device->host, + scmd_channel(scmd)); spin_unlock_irqrestore(scmd->device->host->host_lock, flags); } @@ -1091,7 +1093,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, for (channel = 0; channel <= shost->max_channel; channel++) { chan_scmd = NULL; list_for_each_entry(scmd, work_q, eh_entry) { - if (channel == scmd->device->channel) { + if (channel == scmd_channel(scmd)) { chan_scmd = scmd; break; /* @@ -1109,7 +1111,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, rtn = scsi_try_bus_reset(chan_scmd); if (rtn == SUCCESS) { list_for_each_entry_safe(scmd, next, work_q, eh_entry) { - if (channel == scmd->device->channel) + if (channel == scmd_channel(scmd)) if (!scsi_device_online(scmd->device) || !scsi_eh_tur(scmd)) scsi_eh_finish_cmd(scmd, @@ -1675,7 +1677,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) struct scsi_device *sdev; __shost_for_each_device(sdev, shost) { - if (channel == sdev->channel) { + if (channel == sdev_channel(sdev)) { sdev->was_reset = 1; sdev->expecting_cc_ua = 1; } @@ -1710,8 +1712,8 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) struct scsi_device *sdev; __shost_for_each_device(sdev, shost) { - if (channel == sdev->channel && - target == sdev->id) { + if (channel == sdev_channel(sdev) && + target == sdev_id(sdev)) { sdev->was_reset = 1; sdev->expecting_cc_ua = 1; } diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index ef19adc67eff..93dc7b665ccf 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c @@ -773,7 +773,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) current_command->SCp.Message = 0; spin_lock_irqsave(&sym53c416_lock, flags); - outb(SCpnt->device->id, base + DEST_BUS_ID); /* Set scsi id target */ + outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target */ outb(FLUSH_FIFO, base + COMMAND_REG); /* Flush SCSI and PIO FIFO's */ /* Write SCSI command into the SCSI fifo */ for(i = 0; i < SCpnt->cmd_len; i++) diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index e778e17d57f0..cfab8f197084 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -1822,7 +1822,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { /* If there was a bus reset, redo operation on each target */ else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK - && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel]) + && HD(j)->target_redo[scmd_id(SCpnt)][scmd_channel(SCpnt)]) status = DID_BUS_BUSY << 16; /* Works around a flaw in scsi.c */ @@ -1835,29 +1835,28 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { status = DID_OK << 16; if (tstatus == GOOD) - HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE; + HD(j)->target_redo[scmd_id(SCpnt)][scmd_channel(SCpnt)] = FALSE; if (spp->target_status && SCpnt->device->type == TYPE_DISK && (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) - printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ - "target_status 0x%x, sense key 0x%x.\n", BN(j), - SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, + scmd_printk(KERN_INFO, SCpnt, + "ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n", SCpnt->pid, spp->target_status, SCpnt->sense_buffer[2]); - HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; + HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0; if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; break; case ASST: /* Selection Time Out */ - if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) + if (HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] > 1) status = DID_ERROR << 16; else { status = DID_TIME_OUT << 16; - HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++; + HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)]++; } break; From 19a7b4aebf9ad435c69a7e39930338499af4d152 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Tue, 18 Oct 2005 12:03:35 -0400 Subject: [PATCH 0920/1940] [SCSI] update fc_transport for removal of block/unblock functions We recently went back to implement a board reset. When we perform the reset, we wanted to tear down the internal data structures and rebuild them. Unfortunately, when it came to the rport structure, things were odd. If we deleted them, the scsi targets and sdevs would be torn down. Not a good thing for a temporary reset. We could block the rports, but we either maintain the internal structures to keep the rport reference (perhaps even replicating what's in the transport), or we have to fatten the fc transport with new search routines to find the rport (and deal with a case of a dangling rport that the driver forgets). It dawned on me that we had actually reached this state incorrectly. When the fc transport first started, we did the block/unblock first, then added the rport interface. The purpose of block/unblock is to hide the temporary disappearance of the rport (e.g. being deleted, then readded). Why are we making the driver do the block/unblock ? We should be making the transport have only an rport add/delete, and the let the transport handle the block/unblock. So... This patch removes the existing fc_remote_port_block/unblock functions. It moves the block/unblock functionality into the fc_remote_port_add/delete functions. Updates for the lpfc driver are included. Qlogic driver updates are also enclosed, thanks to the contributions of Andrew Vasquez. [Note: the qla2xxx changes are relative to the scsi-misc-2.6 tree as of this morning - which does not include the recent patches sent by Andrew]. The zfcp driver does not use the block/unblock functions. One last comment: The resulting behavior feels very clean. The LLDD is concerned only with add/delete, which corresponds to the physical disappearance. However, the fact that the scsi target and sdevs are not immediately torn down after the LLDD calls delete causes an interesting scenario... the midlayer can call the xxx_slave_alloc and xxx_queuecommand functions with a sdev that is at the location the rport used to be. The driver must validate the device exists when it first enters these functions. In thinking about it, this has always been the case for the LLDD and these routines. The existing drivers already check for existence. However, this highlights that simple validation via data structure dereferencing needs to be watched. To deal with this, a new transport function, fc_remote_port_chkready() was created that LLDDs should call when they first enter these two routines. It validates the rport state, and returns a scsi result which could be returned. In addition to solving the above, it also creates consistent behavior from the LLDD's when the block and deletes are occuring. Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_hbadisc.c | 28 +- drivers/scsi/lpfc/lpfc_init.c | 19 -- drivers/scsi/lpfc/lpfc_scsi.c | 83 ++---- drivers/scsi/qla2xxx/qla_def.h | 3 + drivers/scsi/qla2xxx/qla_init.c | 26 +- drivers/scsi/qla2xxx/qla_os.c | 21 +- drivers/scsi/qla2xxx/qla_rscn.c | 3 +- drivers/scsi/scsi_transport_fc.c | 458 +++++++++++++++++++------------ include/scsi/scsi_transport_fc.h | 31 ++- 9 files changed, 390 insertions(+), 282 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 56052f4510c3..6c846ad373bc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1028,6 +1028,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, if (ndlp->nlp_type & NLP_FCP_INITIATOR) rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; + scsi_block_requests(phba->host); ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); if (!rport) { dev_printk(KERN_WARNING, &phba->pcidev->dev, @@ -1044,6 +1045,23 @@ lpfc_register_remote_port(struct lpfc_hba * phba, } rdata = rport->dd_data; rdata->pnode = ndlp; + scsi_unblock_requests(phba->host); + + return; +} + +static void +lpfc_unregister_remote_port(struct lpfc_hba * phba, + struct lpfc_nodelist * ndlp) +{ + struct fc_rport *rport = ndlp->rport; + struct lpfc_rport_data *rdata = rport->dd_data; + + ndlp->rport = NULL; + rdata->pnode = NULL; + scsi_block_requests(phba->host); + fc_remote_port_delete(rport); + scsi_unblock_requests(phba->host); return; } @@ -1260,7 +1278,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) * may have removed the remote port. */ if ((rport_del != none) && nlp->rport) - fc_remote_port_block(nlp->rport); + lpfc_unregister_remote_port(phba, nlp); if (rport_add != none) { /* @@ -1270,8 +1288,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) */ if (!nlp->rport) lpfc_register_remote_port(phba, nlp); - else - fc_remote_port_unblock(nlp->rport); /* * if we added to Mapped list, but the remote port @@ -1490,7 +1506,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) LPFC_MBOXQ_t *mb; LPFC_MBOXQ_t *nextmb; struct lpfc_dmabuf *mp; - struct fc_rport *rport; /* Cleanup node for NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, @@ -1507,10 +1522,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) * and flush cache's w/o generating flush errors. */ if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { - rport = ndlp->rport; - ndlp->rport = NULL; - fc_remote_port_unblock(rport); - fc_remote_port_delete(rport); + lpfc_unregister_remote_port(phba, ndlp); ndlp->nlp_sid = NLP_NO_SID; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0856ff7d3b33..25d55f40424f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -537,12 +537,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba) lpfc_offline(phba); - /* - * Restart all traffic to this host. Since the fc_transport - * block functions (future) were not called in lpfc_offline, - * don't call them here. - */ - scsi_unblock_requests(phba->host); } } @@ -1226,12 +1220,6 @@ lpfc_online(struct lpfc_hba * phba) phba->fc_flag &= ~FC_OFFLINE_MODE; spin_unlock_irq(phba->host->host_lock); - /* - * Restart all traffic to this host. Since the fc_transport block - * functions (future) were not called in lpfc_offline, don't call them - * here. - */ - scsi_unblock_requests(phba->host); return 0; } @@ -1249,13 +1237,6 @@ lpfc_offline(struct lpfc_hba * phba) if (phba->fc_flag & FC_OFFLINE_MODE) return 0; - /* - * Don't call the fc_transport block api (future). The device is - * going offline and causing a timer to fire in the midlayer is - * unproductive. Just block all new requests until the driver - * comes back online. - */ - scsi_block_requests(phba->host); psli = &phba->sli; pring = &psli->ring[psli->fcp_ring]; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b5ad1871d34b..c55ab1a630e5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -403,14 +403,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, break; } - if (pnode) { - if (pnode->nlp_state != NLP_STE_MAPPED_NODE) - cmd->result = ScsiResult(DID_BUS_BUSY, - SAM_STAT_BUSY); - } - else { - cmd->result = ScsiResult(DID_NO_CONNECT, 0); - } + if ((pnode == NULL ) + || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) + cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); } else { cmd->result = ScsiResult(DID_OK, 0); } @@ -539,7 +534,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, struct lpfc_rport_data *rdata = scsi_dev->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; - if ((ndlp == 0) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { + if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { return 0; } @@ -727,39 +722,23 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; struct lpfc_scsi_buf *lpfc_cmd = NULL; + struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; - int err = 0; + int err; - /* - * The target pointer is guaranteed not to be NULL because the driver - * only clears the device->hostdata field in lpfc_slave_destroy. This - * approach guarantees no further IO calls on this target. - */ - if (!ndlp) { - cmnd->result = ScsiResult(DID_NO_CONNECT, 0); + err = fc_remote_port_chkready(rport); + if (err) { + cmnd->result = err; goto out_fail_command; } /* - * A Fibre Channel target is present and functioning only when the node - * state is MAPPED. Any other state is a failure. + * Catch race where our node has transitioned, but the + * transport is still transitioning. */ - if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) { - if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) || - (ndlp->nlp_state == NLP_STE_UNUSED_NODE)) { - cmnd->result = ScsiResult(DID_NO_CONNECT, 0); - goto out_fail_command; - } - else if (ndlp->nlp_state == NLP_STE_NPR_NODE) { - cmnd->result = ScsiResult(DID_BUS_BUSY, 0); - goto out_fail_command; - } - /* - * The device is most likely recovered and the driver - * needs a bit more time to finish. Ask the midlayer - * to retry. - */ - goto out_host_busy; + if (!ndlp) { + cmnd->result = ScsiResult(DID_BUS_BUSY, 0); + goto out_fail_command; } list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); @@ -1163,44 +1142,16 @@ static int lpfc_slave_alloc(struct scsi_device *sdev) { struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0]; - struct lpfc_nodelist *ndlp = NULL; - int match = 0; struct lpfc_scsi_buf *scsi_buf = NULL; + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); uint32_t total = 0, i; uint32_t num_to_alloc = 0; unsigned long flags; - struct list_head *listp; - struct list_head *node_list[6]; - /* - * Store the target pointer in the scsi_device hostdata pointer provided - * the driver has already discovered the target id. - */ - - /* Search the nlp lists other than unmap_list for this target ID */ - node_list[0] = &phba->fc_npr_list; - node_list[1] = &phba->fc_nlpmap_list; - node_list[2] = &phba->fc_prli_list; - node_list[3] = &phba->fc_reglogin_list; - node_list[4] = &phba->fc_adisc_list; - node_list[5] = &phba->fc_plogi_list; - - for (i = 0; i < 6 && !match; i++) { - listp = node_list[i]; - if (list_empty(listp)) - continue; - list_for_each_entry(ndlp, listp, nlp_listp) { - if ((sdev->id == ndlp->nlp_sid) && ndlp->rport) { - match = 1; - break; - } - } - } - - if (!match) + if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - sdev->hostdata = ndlp->rport->dd_data; + sdev->hostdata = rport->dd_data; /* * Populate the cmds_per_lun count scsi_bufs into this host's globally diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index fc3234c3625b..7096945ea234 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1665,6 +1666,8 @@ typedef struct fc_port { struct fc_rport *rport; u32 supported_classes; + struct work_struct rport_add_work; + struct work_struct rport_del_work; } fc_port_t; /* diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index ce7e712ebe8d..290a6b92616c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1668,6 +1668,24 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) return (rval); } +static void +qla2x00_rport_add(void *data) +{ + fc_port_t *fcport = data; + + qla2x00_reg_remote_port(fcport->ha, fcport); +} + +static void +qla2x00_rport_del(void *data) +{ + fc_port_t *fcport = data; + + if (fcport->rport) + fc_remote_port_delete(fcport->rport); + fcport->rport = NULL; +} + /** * qla2x00_alloc_fcport() - Allocate a generic fcport. * @ha: HA context @@ -1693,6 +1711,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) atomic_set(&fcport->state, FCS_UNCONFIGURED); fcport->flags = FCF_RLC_SUPPORT; fcport->supported_classes = FC_COS_UNSPECIFIED; + INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); + INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); return (fcport); } @@ -2056,8 +2076,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) struct fc_rport *rport; if (fcport->rport) { - fc_remote_port_unblock(fcport->rport); - return; + fc_remote_port_delete(fcport->rport); + fcport->rport = NULL; } rport_ids.node_name = wwn_to_u64(fcport->node_name); @@ -2071,7 +2091,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) "Unable to allocate fc remote port!\n"); return; } - rport->dd_data = fcport; + *((fc_port_t **)rport->dd_data) = fcport; rport->supported_classes = fcport->supported_classes; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b899282a856e..c58c9d97b041 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -348,11 +348,13 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; int rval; - if (!fcport) { - cmd->result = DID_NO_CONNECT << 16; + rval = fc_remote_port_chkready(rport); + if (rval) { + cmd->result = rval; goto qc_fail_command; } @@ -401,11 +403,13 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; int rval; - if (!fcport) { - cmd->result = DID_NO_CONNECT << 16; + rval = fc_remote_port_chkready(rport); + if (rval) { + cmd->result = rval; goto qc24_fail_command; } @@ -1041,10 +1045,10 @@ qla2xxx_slave_alloc(struct scsi_device *sdev) { struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); - if (!rport) + if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - sdev->hostdata = rport->dd_data; + sdev->hostdata = *(fc_port_t **)rport->dd_data; return 0; } @@ -1636,7 +1640,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, int do_login) { if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) - fc_remote_port_block(fcport->rport); + schedule_work(&fcport->rport_del_work); + /* * We may need to retry the login, so don't change the state of the * port but do the retries. @@ -1697,7 +1702,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) continue; if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) - fc_remote_port_block(fcport->rport); + schedule_work(&fcport->rport_del_work); atomic_set(&fcport->state, FCS_DEVICE_LOST); } } diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index 3e53f62d640d..2c3342108dd8 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c @@ -320,8 +320,7 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat, fcport->flags &= ~FCF_FAILOVER_NEEDED; fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; atomic_set(&fcport->state, FCS_ONLINE); - if (fcport->rport) - fc_remote_port_unblock(fcport->rport); + schedule_work(&fcport->rport_add_work); } diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 27702097b7fc..ca098fc2a607 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -210,7 +210,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) #define FC_MGMTSRVR_PORTID 0x00000a -static void fc_timeout_blocked_rport(void *data); +static void fc_timeout_deleted_rport(void *data); static void fc_scsi_scan_rport(void *data); static void fc_rport_terminate(struct fc_rport *rport); @@ -384,7 +384,9 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \ struct fc_rport *rport = transport_class_to_rport(cdev); \ struct Scsi_Host *shost = rport_to_shost(rport); \ struct fc_internal *i = to_fc_internal(shost->transportt); \ - if (i->f->get_rport_##field) \ + if ((i->f->get_rport_##field) && \ + !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ + (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ i->f->get_rport_##field(rport); \ return snprintf(buf, sz, format_string, cast rport->field); \ } @@ -398,6 +400,9 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \ struct fc_rport *rport = transport_class_to_rport(cdev); \ struct Scsi_Host *shost = rport_to_shost(rport); \ struct fc_internal *i = to_fc_internal(shost->transportt); \ + if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ + (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ + return -EBUSY; \ val = simple_strtoul(buf, NULL, 0); \ i->f->set_rport_##field(rport, val); \ return count; \ @@ -500,7 +505,29 @@ static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO, /* Dynamic Remote Port Attributes */ -fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20); +/* + * dev_loss_tmo attribute + */ +fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) +static ssize_t +store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, + size_t count) +{ + int val; + struct fc_rport *rport = transport_class_to_rport(cdev); + struct Scsi_Host *shost = rport_to_shost(rport); + struct fc_internal *i = to_fc_internal(shost->transportt); + if ((rport->port_state == FC_PORTSTATE_BLOCKED) || + (rport->port_state == FC_PORTSTATE_NOTPRESENT)) + return -EBUSY; + val = simple_strtoul(buf, NULL, 0); + if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)) + return -EINVAL; + i->f->set_rport_dev_loss_tmo(rport, val); + return count; +} +static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, + show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo); /* Private Remote Port Attributes */ @@ -1214,6 +1241,25 @@ fc_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL(fc_remove_host); +/* + * fc_rport_tgt_remove - Removes the scsi target on the remote port + * @rport: The remote port to be operated on + */ +static void +fc_rport_tgt_remove(struct fc_rport *rport) +{ + struct Scsi_Host *shost = rport_to_shost(rport); + + scsi_target_unblock(&rport->dev); + + /* Stop anything on the workq */ + if (!cancel_delayed_work(&rport->dev_loss_work)) + flush_scheduled_work(); + scsi_flush_work(shost); + + scsi_remove_target(&rport->dev); +} + /** * fc_rport_create - allocates and creates a remote FC port. * @shost: scsi host the remote port is connected to. @@ -1260,7 +1306,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, rport->dd_data = &rport[1]; rport->channel = channel; - INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport); + INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); spin_lock_irqsave(shost->host_lock, flags); @@ -1352,17 +1398,93 @@ struct fc_rport * fc_remote_port_add(struct Scsi_Host *shost, int channel, struct fc_rport_identifiers *ids) { + struct fc_internal *fci = to_fc_internal(shost->transportt); struct fc_rport *rport; unsigned long flags; int match = 0; + /* + * Search the list of "active" rports, for an rport that has been + * deleted, but we've held off the real delete while the target + * is in a "blocked" state. + */ + spin_lock_irqsave(shost->host_lock, flags); + + list_for_each_entry(rport, &fc_host_rports(shost), peers) { + + if ((rport->port_state == FC_PORTSTATE_BLOCKED) && + (rport->channel == channel)) { + + switch (fc_host_tgtid_bind_type(shost)) { + case FC_TGTID_BIND_BY_WWPN: + case FC_TGTID_BIND_NONE: + if (rport->port_name == ids->port_name) + match = 1; + break; + case FC_TGTID_BIND_BY_WWNN: + if (rport->node_name == ids->node_name) + match = 1; + break; + case FC_TGTID_BIND_BY_ID: + if (rport->port_id == ids->port_id) + match = 1; + break; + } + + if (match) { + struct work_struct *work = + &rport->dev_loss_work; + + memcpy(&rport->node_name, &ids->node_name, + sizeof(rport->node_name)); + memcpy(&rport->port_name, &ids->port_name, + sizeof(rport->port_name)); + rport->port_id = ids->port_id; + + rport->port_state = FC_PORTSTATE_ONLINE; + rport->roles = ids->roles; + + spin_unlock_irqrestore(shost->host_lock, flags); + + if (fci->f->dd_fcrport_size) + memset(rport->dd_data, 0, + fci->f->dd_fcrport_size); + + /* + * If we were blocked, we were a target. + * If no longer a target, we leave the timer + * running in case the port changes roles + * prior to the timer expiring. If the timer + * fires, the target will be torn down. + */ + if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)) + return rport; + + /* restart the target */ + + /* + * Stop the target timer first. Take no action + * on the del_timer failure as the state + * machine state change will validate the + * transaction. + */ + if (!cancel_delayed_work(work)) + flush_scheduled_work(); + + /* initiate a scan of the target */ + scsi_queue_work(shost, &rport->scan_work); + + return rport; + } + } + } + + /* Search the bindings array */ if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { /* search for a matching consistent binding */ - spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry(rport, &fc_host_rport_bindings(shost), peers) { if (rport->channel != channel) @@ -1392,8 +1514,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } } - spin_unlock_irqrestore(shost->host_lock, flags); - if (match) { memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); @@ -1403,6 +1523,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, rport->roles = ids->roles; rport->port_state = FC_PORTSTATE_ONLINE; + spin_unlock_irqrestore(shost->host_lock, flags); + + if (fci->f->dd_fcrport_size) + memset(rport->dd_data, 0, + fci->f->dd_fcrport_size); + if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) /* initiate a scan of the target */ scsi_queue_work(shost, &rport->scan_work); @@ -1411,6 +1537,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } } + spin_unlock_irqrestore(shost->host_lock, flags); + /* No consistent binding found - create new remote port entry */ rport = fc_rport_create(shost, channel, ids); @@ -1418,25 +1546,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } EXPORT_SYMBOL(fc_remote_port_add); -/* - * fc_rport_tgt_remove - Removes the scsi target on the remote port - * @rport: The remote port to be operated on - */ -static void -fc_rport_tgt_remove(struct fc_rport *rport) -{ - struct Scsi_Host *shost = rport_to_shost(rport); - - scsi_target_unblock(&rport->dev); - - /* Stop anything on the workq */ - if (!cancel_delayed_work(&rport->dev_loss_work)) - flush_scheduled_work(); - scsi_flush_work(shost); - - scsi_remove_target(&rport->dev); -} - /* * fc_rport_terminate - this routine tears down and deallocates a remote port. * @rport: The remote port to be terminated @@ -1470,24 +1579,44 @@ fc_rport_terminate(struct fc_rport *rport) * The LLDD calls this routine to notify the transport that a remote * port is no longer part of the topology. Note: Although a port * may no longer be part of the topology, it may persist in the remote - * ports displayed by the fc_host. This is done so that target id - * mappings (managed via the remote port structures), are always visible - * as long as the mapping is valid, regardless of port state, + * ports displayed by the fc_host. We do this under 2 conditions: + * - If the port was a scsi target, we delay its deletion by "blocking" it. + * This allows the port to temporarily disappear, then reappear without + * disrupting the SCSI device tree attached to it. During the "blocked" + * period the port will still exist. + * - If the port was a scsi target and disappears for longer than we + * expect, we'll delete the port and the tear down the SCSI device tree + * attached to it. However, we want to semi-persist the target id assigned + * to that port if it eventually does exist. The port structure will + * remain (although with minimal information) so that the target id + * bindings remails. * * If the remote port is not an FCP Target, it will be fully torn down * and deallocated, including the fc_remote_port class device. * - * If the remote port is an FCP Target, the port structure will be - * marked as Not Present, but will remain as long as there is a valid - * SCSI target id mapping associated with the port structure. Validity - * is determined by the binding type. If binding by wwpn, then the port - * structure is always valid and will not be deallocated until the host - * is removed. If binding by wwnn, then the port structure is valid - * until another port with the same node name is found in the topology. - * If binding by port id (fc address), then the port structure is valid - * valid until another port with the same address is identified. + * If the remote port is an FCP Target, the port will be placed in a + * temporary blocked state. From the LLDD's perspective, the rport no + * longer exists. From the SCSI midlayer's perspective, the SCSI target + * exists, but all sdevs on it are blocked from further I/O. The following + * is then expected: + * If the remote port does not return (signaled by a LLDD call to + * fc_remote_port_add()) within the dev_loss_tmo timeout, then the + * scsi target is removed - killing all outstanding i/o and removing the + * scsi devices attached ot it. The port structure will be marked Not + * Present and be partially cleared, leaving only enough information to + * recognize the remote port relative to the scsi target id binding if + * it later appears. The port will remain as long as there is a valid + * binding (e.g. until the user changes the binding type or unloads the + * scsi host with the binding). * - * Called from interrupt or normal process context. + * If the remote port returns within the dev_loss_tmo value (and matches + * according to the target id binding type), the port structure will be + * reused. If it is no longer a SCSI target, the target will be torn + * down. If it continues to be a SCSI target, then the target will be + * unblocked (allowing i/o to be resumed), and a scan will be activated + * to ensure that all luns are detected. + * + * Called from normal process context only - cannot be called from interrupt. * * Notes: * This routine assumes no locks are held on entry. @@ -1495,53 +1624,20 @@ fc_rport_terminate(struct fc_rport *rport) void fc_remote_port_delete(struct fc_rport *rport) { - struct Scsi_Host *shost = rport_to_shost(rport); - unsigned long flags; + int timeout = rport->dev_loss_tmo; - /* If no scsi target id mapping or consistent binding type, delete it */ - if ((rport->scsi_target_id == -1) || - (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) { + /* If no scsi target id mapping, delete it */ + if (rport->scsi_target_id == -1) { fc_rport_terminate(rport); return; } - fc_rport_tgt_remove(rport); + scsi_target_block(&rport->dev); - spin_lock_irqsave(shost->host_lock, flags); - list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); - spin_unlock_irqrestore(shost->host_lock, flags); + /* cap the length the devices can be blocked until they are deleted */ + schedule_delayed_work(&rport->dev_loss_work, timeout * HZ); - /* - * Note: We do not remove or clear the hostdata area. This allows - * host-specific target data to persist along with the - * scsi_target_id. It's up to the host to manage it's hostdata area. - */ - - /* - * Reinitialize port attributes that may change if the port comes back. - */ - rport->maxframe_size = -1; - rport->supported_classes = FC_COS_UNSPECIFIED; - rport->roles = FC_RPORT_ROLE_UNKNOWN; - rport->port_state = FC_PORTSTATE_NOTPRESENT; - - /* remove the identifiers that aren't used in the consisting binding */ - switch (fc_host_tgtid_bind_type(shost)) { - case FC_TGTID_BIND_BY_WWPN: - rport->node_name = -1; - rport->port_id = -1; - break; - case FC_TGTID_BIND_BY_WWNN: - rport->port_name = -1; - rport->port_id = -1; - break; - case FC_TGTID_BIND_BY_ID: - rport->node_name = -1; - rport->port_name = -1; - break; - case FC_TGTID_BIND_NONE: /* to keep compiler happy */ - break; - } + rport->port_state = FC_PORTSTATE_BLOCKED; } EXPORT_SYMBOL(fc_remote_port_delete); @@ -1574,127 +1670,140 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) unsigned long flags; int create = 0; - rport->roles = roles; - spin_lock_irqsave(shost->host_lock, flags); - if ((rport->scsi_target_id == -1) && - (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { - rport->scsi_target_id = fc_host->next_target_id++; - create = 1; + if (roles & FC_RPORT_ROLE_FCP_TARGET) { + if (rport->scsi_target_id == -1) { + rport->scsi_target_id = fc_host->next_target_id++; + create = 1; + } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) + create = 1; } spin_unlock_irqrestore(shost->host_lock, flags); - if (create) + rport->roles = roles; + + if (create) { + /* + * There may have been a delete timer running on the + * port. Ensure that it is cancelled as we now know + * the port is an FCP Target. + * Note: we know the rport is exists and in an online + * state as the LLDD would not have had an rport + * reference to pass us. + * + * Take no action on the del_timer failure as the state + * machine state change will validate the + * transaction. + */ + if (!cancel_delayed_work(&rport->dev_loss_work)) + flush_scheduled_work(); + /* initiate a scan of the target */ scsi_queue_work(shost, &rport->scan_work); + } } EXPORT_SYMBOL(fc_remote_port_rolechg); /** - * fc_timeout_blocked_rport - Timeout handler for blocked remote port - * that fails to return in the alloted time. - * @data: scsi target that failed to reappear in the alloted time. + * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that + * was a SCSI target (thus was blocked), and failed + * to return in the alloted time. + * + * @data: rport target that failed to reappear in the alloted time. **/ static void -fc_timeout_blocked_rport(void *data) +fc_timeout_deleted_rport(void *data) { struct fc_rport *rport = (struct fc_rport *)data; + struct Scsi_Host *shost = rport_to_shost(rport); + unsigned long flags; - rport->port_state = FC_PORTSTATE_OFFLINE; + spin_lock_irqsave(shost->host_lock, flags); + + /* + * If the port is ONLINE, then it came back, but was no longer an + * FCP target. Thus we need to tear down the scsi_target on it. + */ + if (rport->port_state == FC_PORTSTATE_ONLINE) { + spin_unlock_irqrestore(shost->host_lock, flags); + + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target\n"); + + fc_rport_tgt_remove(rport); + + return; + } + + if (rport->port_state != FC_PORTSTATE_BLOCKED) { + spin_unlock_irqrestore(shost->host_lock, flags); + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: leaving target alone\n"); + return; + } + + if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) { + spin_unlock_irqrestore(shost->host_lock, flags); + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target\n"); + fc_rport_terminate(rport); + return; + } dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: removing target\n"); + "blocked FC remote port time out: removing target and " + "saving binding\n"); + + list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); + + /* + * Note: We do not remove or clear the hostdata area. This allows + * host-specific target data to persist along with the + * scsi_target_id. It's up to the host to manage it's hostdata area. + */ + + /* + * Reinitialize port attributes that may change if the port comes back. + */ + rport->maxframe_size = -1; + rport->supported_classes = FC_COS_UNSPECIFIED; + rport->roles = FC_RPORT_ROLE_UNKNOWN; + rport->port_state = FC_PORTSTATE_NOTPRESENT; + + /* remove the identifiers that aren't used in the consisting binding */ + switch (fc_host_tgtid_bind_type(shost)) { + case FC_TGTID_BIND_BY_WWPN: + rport->node_name = -1; + rport->port_id = -1; + break; + case FC_TGTID_BIND_BY_WWNN: + rport->port_name = -1; + rport->port_id = -1; + break; + case FC_TGTID_BIND_BY_ID: + rport->node_name = -1; + rport->port_name = -1; + break; + case FC_TGTID_BIND_NONE: /* to keep compiler happy */ + break; + } + + spin_unlock_irqrestore(shost->host_lock, flags); /* * As this only occurs if the remote port (scsi target) * went away and didn't come back - we'll remove * all attached scsi devices. */ - scsi_target_unblock(&rport->dev); - scsi_remove_target(&rport->dev); + fc_rport_tgt_remove(rport); } -/** - * fc_remote_port_block - temporarily block any scsi traffic to a remote port. - * @rport: remote port to be blocked. - * - * scsi lldd's with a FC transport call this routine to temporarily stop - * all scsi traffic to a remote port. If the port is not a SCSI target, - * no action is taken. If the port is a SCSI target, all attached devices - * are placed into a SDEV_BLOCK state and a timer is started. The timer is - * represents the maximum amount of time the port may be blocked. If the - * timer expires, the port is considered non-existent and the attached - * scsi devices will be removed. - * - * Called from interrupt or normal process context. - * - * Returns zero if successful or error if not - * - * Notes: - * This routine assumes no locks are held on entry. - * - * The timeout and timer types are extracted from the fc transport - * attributes from the caller's rport pointer. - **/ -int -fc_remote_port_block(struct fc_rport *rport) -{ - int timeout = rport->dev_loss_tmo; - struct work_struct *work = &rport->dev_loss_work; - - if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) - return -EINVAL; - - scsi_target_block(&rport->dev); - - /* cap the length the devices can be blocked */ - schedule_delayed_work(work, timeout * HZ); - - rport->port_state = FC_PORTSTATE_BLOCKED; - return 0; -} -EXPORT_SYMBOL(fc_remote_port_block); - -/** - * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port. - * @rport: remote port to be unblocked. - * - * scsi lld's with a FC transport call this routine to restart IO to all - * devices associated with the caller's scsi target following a fc_target_block - * request. Called from interrupt or normal process context. - * - * Notes: - * This routine assumes no locks are held on entry. - **/ - void -fc_remote_port_unblock(struct fc_rport *rport) -{ - struct work_struct *work = &rport->dev_loss_work; - struct Scsi_Host *shost = rport_to_shost(rport); - - /* - * Stop the target timer first. Take no action on the del_timer - * failure as the state machine state change will validate the - * transaction. - */ - if (!cancel_delayed_work(work)) - flush_scheduled_work(); - - if (rport->port_state == FC_PORTSTATE_OFFLINE) - /* - * initiate a scan of the target as the target has - * been torn down. - */ - scsi_queue_work(shost, &rport->scan_work); - else - scsi_target_unblock(&rport->dev); - - rport->port_state = FC_PORTSTATE_ONLINE; -} -EXPORT_SYMBOL(fc_remote_port_unblock); - /** * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. + * + * Will unblock the target (in case it went away and has now come back), + * then invoke a scan. + * * @data: remote port to be scanned. **/ static void @@ -1702,6 +1811,7 @@ fc_scsi_scan_rport(void *data) { struct fc_rport *rport = (struct fc_rport *)data; + scsi_target_unblock(&rport->dev); scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, SCAN_WILD_CARD, 1); } diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 4496b32972e5..319ff7a60dfe 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -28,6 +28,7 @@ #define SCSI_TRANSPORT_FC_H #include +#include struct scsi_transport_template; @@ -429,6 +430,34 @@ struct fc_function_template { }; +/** + * fc_remote_port_chkready - called to validate the remote port state + * prior to initiating io to the port. + * + * Returns a scsi result code that can be returned by the LLDD. + * + * @rport: remote port to be checked + **/ +static inline int +fc_remote_port_chkready(struct fc_rport *rport) +{ + int result; + + switch (rport->port_state) { + case FC_PORTSTATE_ONLINE: + result = 0; + break; + case FC_PORTSTATE_BLOCKED: + result = DID_BUS_BUSY << 16; + break; + default: + result = DID_NO_CONNECT << 16; + break; + } + return result; +} + + struct scsi_transport_template *fc_attach_transport( struct fc_function_template *); void fc_release_transport(struct scsi_transport_template *); @@ -437,8 +466,6 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, int channel, struct fc_rport_identifiers *ids); void fc_remote_port_delete(struct fc_rport *rport); void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles); -int fc_remote_port_block(struct fc_rport *rport); -void fc_remote_port_unblock(struct fc_rport *rport); int scsi_is_fc_rport(const struct device *); static inline u64 wwn_to_u64(u8 *wwn) From 4303fc6f055cf1a7ec63c3c3fd777b91b7d576f1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 28 Oct 2005 19:59:31 -0700 Subject: [PATCH 0921/1940] USB: fix up some odd parts due to partial merges Thanks to Andrew for doing the hard work on this. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 2 +- drivers/usb/host/ehci-pci.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9660a8909b7c..256d9f698715 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1674,7 +1674,7 @@ int usb_suspend_device(struct usb_device *udev) return 0; #endif } - +EXPORT_SYMBOL_GPL(usb_suspend_device); /* * If the USB "suspend" state is in use (rather than "global suspend"), diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7872469ccbb1..145008853966 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -252,7 +252,7 @@ static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) (void) usb_suspend_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); - (void) ehci_hub_suspend (hcd); + (void) ehci_bus_suspend (hcd); usb_unlock_device (hcd->self.root_hub); #endif @@ -285,7 +285,7 @@ static int ehci_pci_resume (struct usb_hcd *hcd) continue; if (status & (PORT_SUSPEND | PORT_OWNER)) { down (&hcd->self.root_hub->serialize); - retval = ehci_hub_resume (hcd); + retval = ehci_bus_resume (hcd); up (&hcd->self.root_hub->serialize); break; } From 9e3699ea7b8d63eabde7fefa9892e3a258c9c27d Mon Sep 17 00:00:00 2001 From: Lee Nicks Date: Fri, 28 Oct 2005 17:46:09 -0700 Subject: [PATCH 0922/1940] [PATCH] ppc: prevent GCC 4 from generating AltiVec instructions in kernel Depending on how GCC is built, GCC 4 may generate altivec instructions without user explicitly requesting vector operations in the code. Although this is a performance booster for user applications, it is a problem for kernel. This patch explicitly instruct GCC to NOT generate altivec instructions while building the kernel. Here are some test cases I ran. (1) build gcc 4.0.1 with '--with-cpu=7450 --enable-altivec --enable-cxx-flags=-mcpu=7450', and use this gcc to build kernel WITHOUT this kernel patch. Kernel fail to boot up on a 7450 board because of altivec instructions in kernel. (2) build gcc 4.0.1 with "--with-cpu=7450 --enable-altivec --enable-cxx-flags=-mcpu=7450", and use this gcc to build kernel WITH this kernel patch. Kernel boot up on a 7450 board without any problem. (3) build gcc 4.0.1 with "--with-cpu=750 --enable-cxx-flags=-mcpu=750", and use this gcc to build kernel with or without this kernel patch. Kernel boot up on a 7450 board without any problem. This patch should also work with GCC 3 or even earlier GCC 2.95.3. Signed-off-by: Lee Nicks Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/Makefile | 4 ++++ arch/ppc64/Makefile | 3 +++ 2 files changed, 7 insertions(+) diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 121d2347b89f..94d5716fa7c3 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -26,6 +26,10 @@ CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include AFLAGS += -Iarch/$(ARCH) CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \ -ffixed-r2 -mmultiple + +# No AltiVec instruction when building kernel +CFLAGS += $(call cc-option, -mno-altivec) + CPP = $(CC) -E $(CFLAGS) # Temporary hack until we have migrated to asm-powerpc LINUXINCLUDE += -Iarch/$(ARCH)/include diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 743f0dbdebf3..db1b25cdb5be 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -75,6 +75,9 @@ else CFLAGS += $(call cc-option,-mtune=power4) endif +# No AltiVec instruction when building kernel +CFLAGS += $(call cc-option, -mno-altivec) + # Enable unit-at-a-time mode when possible. It shrinks the # kernel considerably. CFLAGS += $(call cc-option,-funit-at-a-time) From e37b0c9670fed2264661ade1beb5c228dec29c96 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 28 Oct 2005 17:46:10 -0700 Subject: [PATCH 0923/1940] [PATCH] ppc32 8xx: use io accessor macros instead of direct memory reference Convert core 8xx drivers to use in_xxxbe/in_xxx macros instead of direct memory references. Other than making IO accesses explicit (which is a plus for readability), a common set of macros provides a unified place for the volatile flag to constraint compiler code reordering. There are several unlucky places at the moment which lack the volatile flag. Signed-off-by: Marcelo Tosatti Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/8xx_io/commproc.c | 20 ++++++++-------- arch/ppc/syslib/m8xx_setup.c | 45 ++++++++++++++++-------------------- arch/ppc/syslib/m8xx_wdt.c | 14 +++++------ arch/ppc/syslib/ppc8xx_pic.c | 17 ++++++-------- 4 files changed, 44 insertions(+), 52 deletions(-) diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 11726e2a4ec8..b42789f8eb76 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -73,7 +73,7 @@ cpm_mask_irq(unsigned int irq) { int cpm_vec = irq - CPM_IRQ_OFFSET; - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_vec); + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) & ~(1 << cpm_vec)); } static void @@ -81,7 +81,7 @@ cpm_unmask_irq(unsigned int irq) { int cpm_vec = irq - CPM_IRQ_OFFSET; - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_vec); + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) | (1 << cpm_vec)); } static void @@ -95,7 +95,7 @@ cpm_eoi(unsigned int irq) { int cpm_vec = irq - CPM_IRQ_OFFSET; - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << cpm_vec); + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr, (1 << cpm_vec)); } struct hw_interrupt_type cpm_pic = { @@ -133,7 +133,7 @@ m8xx_cpm_reset(void) * manual recommends it. * Bit 25, FAM can also be set to use FEC aggressive mode (860T). */ - imp->im_siu_conf.sc_sdcr = 1; + out_be32(&imp->im_siu_conf.sc_sdcr, 1), /* Reclaim the DP memory for our use. */ m8xx_cpm_dpinit(); @@ -178,10 +178,10 @@ cpm_interrupt_init(void) /* Initialize the CPM interrupt controller. */ - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr = + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) | - ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK; - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0; + ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK); + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, 0); /* install the CPM interrupt controller routines for the CPM * interrupt vectors @@ -198,7 +198,7 @@ cpm_interrupt_init(void) if (setup_irq(CPM_IRQ_OFFSET + CPMVEC_ERROR, &cpm_error_irqaction)) panic("Could not allocate CPM error IRQ!"); - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN; + out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr) | CICR_IEN); } /* @@ -212,8 +212,8 @@ cpm_get_irq(struct pt_regs *regs) /* Get the vector by setting the ACK bit and then reading * the register. */ - ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1; - cpm_vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr; + out_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr, 1); + cpm_vec = in_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr); cpm_vec >>= 11; return cpm_vec; diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index c88e2d4dceb7..a192719929d3 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c @@ -144,12 +144,12 @@ void __init m8xx_calibrate_decr(void) int freq, fp, divisor; /* Unlock the SCCR. */ - ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY; + out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY); /* Force all 8xx processors to use divide by 16 processor clock. */ - ((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000; - + out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr, + in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr)|0x02000000); /* Processor frequency is MHz. * The value 'fp' is the number of decrementer ticks per second. */ @@ -175,28 +175,24 @@ void __init m8xx_calibrate_decr(void) * we guarantee the registers are locked, then we unlock them * for our use. */ - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY; + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY); /* Disable the RTC one second and alarm interrupts. */ - ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &= - ~(RTCSC_SIE | RTCSC_ALE); + out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE)); /* Enable the RTC */ - ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |= - (RTCSC_RTF | RTCSC_RTE); + out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE)); /* Enabling the decrementer also enables the timebase interrupts * (or from the other point of view, to get decrementer interrupts * we have to enable the timebase). The decrementer interrupt * is wired into the vector table, nothing to do here for that. */ - ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr = - ((mk_int_int_mask(DEC_INTERRUPT) << 8) | - (TBSCR_TBF | TBSCR_TBE)); + out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE)); if (setup_irq(DEC_INTERRUPT, &tbint_irqaction)) panic("Could not allocate timer IRQ!"); @@ -216,9 +212,9 @@ void __init m8xx_calibrate_decr(void) static int m8xx_set_rtc_time(unsigned long time) { - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY; + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY); + out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time); + out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY); return(0); } @@ -226,7 +222,7 @@ static unsigned long m8xx_get_rtc_time(void) { /* Get time from the RTC. */ - return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc)); + return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc); } static void @@ -235,13 +231,13 @@ m8xx_restart(char *cmd) __volatile__ unsigned char dummy; local_irq_disable(); - ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080; + out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr) | 0x00000080); /* Clear the ME bit in MSR to cause checkstop on machine check */ mtmsr(mfmsr() & ~0x1000); - dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0]; + dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]); printk("Restart failed\n"); while(1); } @@ -306,8 +302,7 @@ m8xx_init_IRQ(void) i8259_init(0); /* The i8259 cascade interrupt must be level sensitive. */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &= - ~(0x80000000 >> ISA_BRIDGE_INT); + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel & ~(0x80000000 >> ISA_BRIDGE_INT))); if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction)) enable_irq(ISA_BRIDGE_INT); diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c index 2ddc857e7fc7..c5ac5ce5d7d2 100644 --- a/arch/ppc/syslib/m8xx_wdt.c +++ b/arch/ppc/syslib/m8xx_wdt.c @@ -29,8 +29,8 @@ void m8xx_wdt_reset(void) { volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; - imap->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */ - imap->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */ + out_be16(imap->im_siu_conf.sc_swsr, 0x556c); /* write magic1 */ + out_be16(imap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */ } static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) @@ -39,7 +39,7 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) m8xx_wdt_reset(); - imap->im_sit.sit_piscr |= PISCR_PS; /* clear irq */ + out_be16(imap->im_sit.sit_piscr, in_be16(imap->im_sit.sit_piscr | PISCR_PS)); /* clear irq */ return IRQ_HANDLED; } @@ -51,7 +51,7 @@ void __init m8xx_wdt_handler_install(bd_t * binfo) u32 sypcr; u32 pitrtclk; - sypcr = imap->im_siu_conf.sc_sypcr; + sypcr = in_be32(imap->im_siu_conf.sc_sypcr); if (!(sypcr & 0x04)) { printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", @@ -87,9 +87,9 @@ void __init m8xx_wdt_handler_install(bd_t * binfo) else pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2; - imap->im_sit.sit_pitc = pitc << 16; - imap->im_sit.sit_piscr = - (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE; + out_be32(imap->im_sit.sit_pitc, pitc << 16); + + out_be16(imap->im_sit.sit_piscr, (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE); if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction)) panic("m8xx_wdt: error setting up the watchdog irq!"); diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c index d3b01c6c97de..3e6f51a61d46 100644 --- a/arch/ppc/syslib/ppc8xx_pic.c +++ b/arch/ppc/syslib/ppc8xx_pic.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "ppc8xx_pic.h" @@ -29,8 +30,7 @@ static void m8xx_mask_irq(unsigned int irq_nr) word = irq_nr >> 5; ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = - ppc_cached_irq_mask[word]; + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]); } static void m8xx_unmask_irq(unsigned int irq_nr) @@ -41,8 +41,7 @@ static void m8xx_unmask_irq(unsigned int irq_nr) word = irq_nr >> 5; ppc_cached_irq_mask[word] |= (1 << (31-bit)); - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = - ppc_cached_irq_mask[word]; + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]); } static void m8xx_end_irq(unsigned int irq_nr) @@ -55,8 +54,7 @@ static void m8xx_end_irq(unsigned int irq_nr) word = irq_nr >> 5; ppc_cached_irq_mask[word] |= (1 << (31-bit)); - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = - ppc_cached_irq_mask[word]; + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]); } } @@ -69,9 +67,8 @@ static void m8xx_mask_and_ack(unsigned int irq_nr) word = irq_nr >> 5; ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = - ppc_cached_irq_mask[word]; - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit); + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]); + out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit)); } struct hw_interrupt_type ppc8xx_pic = { @@ -93,7 +90,7 @@ m8xx_get_irq(struct pt_regs *regs) /* For MPC8xx, read the SIVEC register and shift the bits down * to get the irq number. */ - irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26; + irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26; /* * When we read the sivec without an interrupt to process, we will From de957c89b7dadb3147e885d7b6eb9db73d0eea57 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 28 Oct 2005 17:46:13 -0700 Subject: [PATCH 0924/1940] [PATCH] MPC8xx PCMCIA driver Here is an uptodated version of the MPC8xx PCMCIA driver for v2.6, addressing comments by Jeff and Dominik: - use IO accessors instead of direct device memory referencing - avoid usage of non-standard "uint/uchar" data types - kill struct typedef's Will submit it for inclusion once v2.6.14 is out. Testing on 8xx platforms is more than welcome! Works like a charm on our custom hardware (CONFIG_PRxK). Cc: Dominik Brodowski Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/pcmcia/Kconfig | 10 + drivers/pcmcia/Makefile | 1 + drivers/pcmcia/m8xx_pcmcia.c | 1290 ++++++++++++++++++++++++++++++++++ 3 files changed, 1301 insertions(+) create mode 100644 drivers/pcmcia/m8xx_pcmcia.c diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 36cc9a96a338..ccf20039e909 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -154,6 +154,16 @@ config TCIC "Bridge" is the name used for the hardware inside your computer that PCMCIA cards are plugged into. If unsure, say N. +config PCMCIA_M8XX + tristate "MPC8xx PCMCIA support" + depends on PCMCIA && PPC + select PCCARD_NONSTATIC + help + Say Y here to include support for PowerPC 8xx series PCMCIA + controller. + + This driver is also available as a module called m8xx_pcmcia. + config HD64465_PCMCIA tristate "HD64465 host bridge support" depends on HD64465 && PCMCIA diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index a41fbb38fdcb..cb4861d9cb80 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_TCIC) += tcic.o +obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c new file mode 100644 index 000000000000..f8bed87cf2f1 --- /dev/null +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -0,0 +1,1290 @@ +/* + * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series. + * + * (C) 1999-2000 Magnus Damm + * (C) 2001-2002 Montavista Software, Inc. + * + * + * Support for two slots by Cyclades Corporation + * + * Further fixes, v2.6 kernel port + * + * + * "The ExCA standard specifies that socket controllers should provide + * two IO and five memory windows per socket, which can be independently + * configured and positioned in the host address space and mapped to + * arbitrary segments of card address space. " - David A Hinds. 1999 + * + * This controller does _not_ meet the ExCA standard. + * + * m8xx pcmcia controller brief info: + * + 8 windows (attrib, mem, i/o) + * + up to two slots (SLOT_A and SLOT_B) + * + inputpins, outputpins, event and mask registers. + * - no offset register. sigh. + * + * Because of the lacking offset register we must map the whole card. + * We assign each memory window PCMCIA_MEM_WIN_SIZE address space. + * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO + * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE. + * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE. + * They are maximum 64KByte each... + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +module_param(pc_debug, int, 0); +#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args); +#else +#define dprintk(args...) +#endif + +#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args) +#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args) + +static const char *version = "Version 0.06, Aug 2005"; +MODULE_LICENSE("Dual MPL/GPL"); + +#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) + +/* The RPX series use SLOT_B */ +#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE) +#define CONFIG_PCMCIA_SLOT_B +#define CONFIG_BD_IS_MHZ +#endif + +/* The ADS board use SLOT_A */ +#ifdef CONFIG_ADS +#define CONFIG_PCMCIA_SLOT_A +#define CONFIG_BD_IS_MHZ +#endif + +/* The FADS series are a mess */ +#ifdef CONFIG_FADS +#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821) +#define CONFIG_PCMCIA_SLOT_A +#else +#define CONFIG_PCMCIA_SLOT_B +#endif +#endif + +/* Cyclades ACS uses both slots */ +#ifdef CONFIG_PRxK +#define CONFIG_PCMCIA_SLOT_A +#define CONFIG_PCMCIA_SLOT_B +#endif + +#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */ + +#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B) + +#define PCMCIA_SOCKETS_NO 2 +/* We have only 8 windows, dualsocket support will be limited. */ +#define PCMCIA_MEM_WIN_NO 2 +#define PCMCIA_IO_WIN_NO 2 +#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B" + +#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B) + +#define PCMCIA_SOCKETS_NO 1 +/* full support for one slot */ +#define PCMCIA_MEM_WIN_NO 5 +#define PCMCIA_IO_WIN_NO 2 + +/* define _slot_ to be able to optimize macros */ + +#ifdef CONFIG_PCMCIA_SLOT_A +#define _slot_ 0 +#define PCMCIA_SLOT_MSG "SLOT_A" +#else +#define _slot_ 1 +#define PCMCIA_SLOT_MSG "SLOT_B" +#endif + +#else +#error m8xx_pcmcia: Bad configuration! +#endif + +/* ------------------------------------------------------------------------- */ + +#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */ +#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */ +#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */ + +#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */ + +/* ------------------------------------------------------------------------- */ + +/* 2.4.x and newer has this always in HZ */ +#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq)) + +static int pcmcia_schlvl = PCMCIA_SCHLVL; + +static spinlock_t events_lock = SPIN_LOCK_UNLOCKED; + + +#define PCMCIA_SOCKET_KEY_5V 1 +#define PCMCIA_SOCKET_KEY_LV 2 + +/* look up table for pgcrx registers */ +static u32 *m8xx_pgcrx[2] = { + &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra, + &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb +}; + +/* + * This structure is used to address each window in the PCMCIA controller. + * + * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly + * after pcmcia_win[n]... + */ + +struct pcmcia_win { + u32 br; + u32 or; +}; + +/* + * For some reason the hardware guys decided to make both slots share + * some registers. + * + * Could someone invent object oriented hardware ? + * + * The macros are used to get the right bit from the registers. + * SLOT_A : slot = 0 + * SLOT_B : slot = 1 + */ + +#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4)) +#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4)) +#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4)) +#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4)) + +#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4)) +#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4)) +#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4)) +#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4)) +#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4)) +#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4)) +#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4)) +#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4)) +#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4)) +#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4)) +#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4)) + +#define M8XX_PCMCIA_POR_VALID 0x00000001 +#define M8XX_PCMCIA_POR_WRPROT 0x00000002 +#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010 +#define M8XX_PCMCIA_POR_IO 0x00000018 +#define M8XX_PCMCIA_POR_16BIT 0x00000040 + +#define M8XX_PGCRX(slot) m8xx_pgcrx[slot] + +#define M8XX_PGCRX_CXOE 0x00000080 +#define M8XX_PGCRX_CXRESET 0x00000040 + +/* we keep one lookup table per socket to check flags */ + +#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */ + +struct event_table { + u32 regbit; + u32 eventbit; +}; + +struct socket_info { + void (*handler)(void *info, u32 events); + void *info; + + u32 slot; + + socket_state_t state; + struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO]; + struct pccard_io_map io_win[PCMCIA_IO_WIN_NO]; + struct event_table events[PCMCIA_EVENTS_MAX]; + struct pcmcia_socket socket; +}; + +static struct socket_info socket[PCMCIA_SOCKETS_NO]; + +/* + * Search this table to see if the windowsize is + * supported... + */ + +#define M8XX_SIZES_NO 32 + +static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = +{ + 0x00000001, 0x00000002, 0x00000008, 0x00000004, + 0x00000080, 0x00000040, 0x00000010, 0x00000020, + 0x00008000, 0x00004000, 0x00001000, 0x00002000, + 0x00000100, 0x00000200, 0x00000800, 0x00000400, + + 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x01000000, 0x02000000, 0xffffffff, 0x04000000, + 0x00010000, 0x00020000, 0x00080000, 0x00040000, + 0x00800000, 0x00400000, 0x00100000, 0x00200000 +}; + +/* ------------------------------------------------------------------------- */ + +static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs); + +#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */ + +/* ------------------------------------------------------------------------- */ +/* board specific stuff: */ +/* voltage_set(), hardware_enable() and hardware_disable() */ +/* ------------------------------------------------------------------------- */ +/* RPX Boards from Embedded Planet */ + +#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE) + +/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks. + * SYPCR is write once only, therefore must the slowest memory be faster + * than the bus monitor or we will get a machine check due to the bus timeout. + */ + +#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE" + +#undef PCMCIA_BMT_LIMIT +#define PCMCIA_BMT_LIMIT (6*8) + +static int voltage_set(int slot, int vcc, int vpp) +{ + u32 reg = 0; + + switch(vcc) { + case 0: break; + case 33: + reg |= BCSR1_PCVCTL4; + break; + case 50: + reg |= BCSR1_PCVCTL5; + break; + default: + return 1; + } + + switch(vpp) { + case 0: break; + case 33: + case 50: + if(vcc == vpp) + reg |= BCSR1_PCVCTL6; + else + return 1; + break; + case 120: + reg |= BCSR1_PCVCTL7; + default: + return 1; + } + + if(!((vcc == 50) || (vcc == 0))) + return 1; + + /* first, turn off all power */ + + out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7)); + + /* enable new powersettings */ + + out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg); + + return 0; +} + +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V +#define hardware_enable(_slot_) /* No hardware to enable */ +#define hardware_disable(_slot_) /* No hardware to disable */ + +#endif /* CONFIG_RPXCLASSIC */ + +/* FADS Boards from Motorola */ + +#if defined(CONFIG_FADS) + +#define PCMCIA_BOARD_MSG "FADS" + +static int voltage_set(int slot, int vcc, int vpp) +{ + u32 reg = 0; + + switch(vcc) { + case 0: + break; + case 33: + reg |= BCSR1_PCCVCC0; + break; + case 50: + reg |= BCSR1_PCCVCC1; + break; + default: + return 1; + } + + switch(vpp) { + case 0: + break; + case 33: + case 50: + if(vcc == vpp) + reg |= BCSR1_PCCVPP1; + else + return 1; + break; + case 120: + if ((vcc == 33) || (vcc == 50)) + reg |= BCSR1_PCCVPP0; + else + return 1; + default: + return 1; + } + + /* first, turn off all power */ + out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); + + /* enable new powersettings */ + out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg); + + return 0; +} + +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V + +static void hardware_enable(int slot) +{ + out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN); +} + +static void hardware_disable(int slot) +{ + out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN); +} + +#endif + +/* ------------------------------------------------------------------------- */ +/* Motorola MBX860 */ + +#if defined(CONFIG_MBX) + +#define PCMCIA_BOARD_MSG "MBX" + +static int voltage_set(int slot, int vcc, int vpp) +{ + u8 reg = 0; + + switch(vcc) { + case 0: + break; + case 33: + reg |= CSR2_VCC_33; + break; + case 50: + reg |= CSR2_VCC_50; + break; + default: + return 1; + } + + switch(vpp) { + case 0: + break; + case 33: + case 50: + if(vcc == vpp) + reg |= CSR2_VPP_VCC; + else + return 1; + break; + case 120: + if ((vcc == 33) || (vcc == 50)) + reg |= CSR2_VPP_12; + else + return 1; + default: + return 1; + } + + /* first, turn off all power */ + out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); + + /* enable new powersettings */ + out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg); + + return 0; +} + +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V +#define hardware_enable(_slot_) /* No hardware to enable */ +#define hardware_disable(_slot_) /* No hardware to disable */ + +#endif /* CONFIG_MBX */ + +#if defined(CONFIG_PRxK) +#include +extern volatile fpga_pc_regs *fpga_pc; + +#define PCMCIA_BOARD_MSG "MPC855T" + +static int voltage_set(int slot, int vcc, int vpp) +{ + u8 reg = 0; + u8 regread; + cpld_regs *ccpld = get_cpld(); + + switch(vcc) { + case 0: + break; + case 33: + reg |= PCMCIA_VCC_33; + break; + case 50: + reg |= PCMCIA_VCC_50; + break; + default: + return 1; + } + + switch(vpp) { + case 0: + break; + case 33: + case 50: + if(vcc == vpp) + reg |= PCMCIA_VPP_VCC; + else + return 1; + break; + case 120: + if ((vcc == 33) || (vcc == 50)) + reg |= PCMCIA_VPP_12; + else + return 1; + default: + return 1; + } + + reg = reg >> (slot << 2); + regread = in_8(&ccpld->fpga_pc_ctl); + if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) { + /* enable new powersettings */ + regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)); + out_8(&ccpld->fpga_pc_ctl, reg | regread); + msleep(100); + } + + return 0; +} + +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV +#define hardware_enable(_slot_) /* No hardware to enable */ +#define hardware_disable(_slot_) /* No hardware to disable */ + +#endif /* CONFIG_PRxK */ + +static void m8xx_shutdown(void) +{ + u32 m, i; + struct pcmcia_win *w; + + for(i = 0; i < PCMCIA_SOCKETS_NO; i++){ + w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i)); + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i)); + + /* turn off interrupt and disable CxOE */ + out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE); + + /* turn off memory windows */ + for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) { + out_be32(&w->or, 0); /* set to not valid */ + w++; + } + + /* turn off voltage */ + voltage_set(i, 0, 0); + + /* disable external hardware */ + hardware_disable(i); + } + + free_irq(pcmcia_schlvl, NULL); +} + +/* copied from tcic.c */ + +static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level) +{ + int ret = 0; + if (level == SUSPEND_SAVE_STATE) + ret = pcmcia_socket_dev_suspend(dev, state); + return ret; +} + +static int m8xx_drv_resume(struct device *dev, u32 level) +{ + int ret = 0; + if (level == RESUME_RESTORE_STATE) + ret = pcmcia_socket_dev_resume(dev); + return ret; +} + +static struct device_driver m8xx_driver = { + .name = "m8xx-pcmcia", + .bus = &platform_bus_type, + .suspend = m8xx_drv_suspend, + .resume = m8xx_drv_resume, +}; + +static struct platform_device m8xx_device = { + .name = "m8xx-pcmcia", + .id = 0, +}; + +static u32 pending_events[PCMCIA_SOCKETS_NO]; +static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED; + +static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + struct socket_info *s; + struct event_table *e; + unsigned int i, events, pscr, pipr, per; + + dprintk("Interrupt!\n"); + /* get interrupt sources */ + + pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr); + pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); + per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per); + + for(i = 0; i < PCMCIA_SOCKETS_NO; i++) { + s = &socket[i]; + e = &s->events[0]; + events = 0; + + while(e->regbit) { + if(pscr & e->regbit) + events |= e->eventbit; + + e++; + } + + /* + * report only if both card detect signals are the same + * not too nice done, + * we depend on that CD2 is the bit to the left of CD1... + */ + if(events & SS_DETECT) + if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^ + (pipr & M8XX_PCMCIA_CD1(i))) + { + events &= ~SS_DETECT; + } + +#ifdef PCMCIA_GLITCHY_CD + /* + * I've experienced CD problems with my ADS board. + * We make an extra check to see if there was a + * real change of Card detection. + */ + + if((events & SS_DETECT) && + ((pipr & + (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) && + (s->state.Vcc | s->state.Vpp)) { + events &= ~SS_DETECT; + /*printk( "CD glitch workaround - CD = 0x%08x!\n", + (pipr & (M8XX_PCMCIA_CD2(i) + | M8XX_PCMCIA_CD1(i))));*/ + } +#endif + + /* call the handler */ + + dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, " + "pipr = 0x%08x\n", + i, events, pscr, pipr); + + if(events) { + spin_lock(&pending_event_lock); + pending_events[i] |= events; + spin_unlock(&pending_event_lock); + /* + * Turn off RDY_L bits in the PER mask on + * CD interrupt receival. + * + * They can generate bad interrupts on the + * ACS4,8,16,32. - marcelo + */ + per &= ~M8XX_PCMCIA_RDY_L(0); + per &= ~M8XX_PCMCIA_RDY_L(1); + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per); + + if (events) + pcmcia_parse_events(&socket[i].socket, events); + } + } + + /* clear the interrupt sources */ + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr); + + dprintk("Interrupt done.\n"); + + return IRQ_HANDLED; +} + +static u32 m8xx_get_graycode(u32 size) +{ + u32 k; + + for(k = 0; k < M8XX_SIZES_NO; k++) + if(m8xx_size_to_gray[k] == size) + break; + + if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1)) + k = -1; + + return k; +} + +static u32 m8xx_get_speed(u32 ns, u32 is_io) +{ + u32 reg, clocks, psst, psl, psht; + + if(!ns) { + + /* + * We get called with IO maps setup to 0ns + * if not specified by the user. + * They should be 255ns. + */ + + if(is_io) + ns = 255; + else + ns = 100; /* fast memory if 0 */ + } + + /* + * In PSST, PSL, PSHT fields we tell the controller + * timing parameters in CLKOUT clock cycles. + * CLKOUT is the same as GCLK2_50. + */ + +/* how we want to adjust the timing - in percent */ + +#define ADJ 180 /* 80 % longer accesstime - to be sure */ + + clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000; + clocks = (clocks * ADJ) / (100*1000); + if(clocks >= PCMCIA_BMT_LIMIT) { + printk( "Max access time limit reached\n"); + clocks = PCMCIA_BMT_LIMIT-1; + } + + psst = clocks / 7; /* setup time */ + psht = clocks / 7; /* hold time */ + psl = (clocks * 5) / 7; /* strobe length */ + + psst += clocks - (psst + psht + psl); + + reg = psst << 12; + reg |= psl << 7; + reg |= psht << 16; + + return reg; +} + +static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value) +{ + int lsock = container_of(sock, struct socket_info, socket)->slot; + struct socket_info *s = &socket[lsock]; + unsigned int pipr, reg; + + pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); + + *value = ((pipr & (M8XX_PCMCIA_CD1(lsock) + | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0; + *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0; + + if (s->state.flags & SS_IOCARD) + *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0; + else { + *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0; + *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0; + *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0; + } + + if (s->state.Vcc | s->state.Vpp) + *value |= SS_POWERON; + + /* + * Voltage detection: + * This driver only supports 16-Bit pc-cards. + * Cardbus is not handled here. + * + * To determine what voltage to use we must read the VS1 and VS2 pin. + * Depending on what socket type is present, + * different combinations mean different things. + * + * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse + * + * 5V 5V, LV* NC NC 5V only 5V (if available) + * + * 5V 5V, LV* GND NC 5 or 3.3V as low as possible + * + * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible + * + * LV* 5V - - shall not fit into socket + * + * LV* LV* GND NC 3.3V only 3.3V + * + * LV* LV* NC GND x.xV x.xV (if avail.) + * + * LV* LV* GND GND 3.3 or x.xV as low as possible + * + * *LV means Low Voltage + * + * + * That gives us the following table: + * + * Socket VS1 VS2 Voltage + * + * 5V NC NC 5V + * 5V NC GND none (should not be possible) + * 5V GND NC >= 3.3V + * 5V GND GND >= x.xV + * + * LV NC NC 5V (if available) + * LV NC GND x.xV (if available) + * LV GND NC 3.3V + * LV GND GND >= x.xV + * + * So, how do I determine if I have a 5V or a LV + * socket on my board? Look at the socket! + * + * + * Socket with 5V key: + * ++--------------------------------------------+ + * || | + * || || + * || || + * | | + * +---------------------------------------------+ + * + * Socket with LV key: + * ++--------------------------------------------+ + * || | + * | || + * | || + * | | + * +---------------------------------------------+ + * + * + * With other words - LV only cards does not fit + * into the 5V socket! + */ + + /* read out VS1 and VS2 */ + + reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock)) + >> M8XX_PCMCIA_VS_SHIFT(lsock); + + if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) { + switch(reg) { + case 1: + *value |= SS_3VCARD; + break; /* GND, NC - 3.3V only */ + case 2: + *value |= SS_XVCARD; + break; /* NC. GND - x.xV only */ + }; + } + + dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value); + return 0; +} + +static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + int lsock = container_of(sock, struct socket_info, socket)->slot; + *state = socket[lsock].state; /* copy the whole structure */ + + dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " + "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags, + state->Vcc, state->Vpp, state->io_irq, state->csc_mask); + return 0; +} + +static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + int lsock = container_of(sock, struct socket_info, socket)->slot; + struct socket_info *s = &socket[lsock]; + struct event_table *e; + unsigned int reg; + unsigned long flags; + + dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, + state->Vcc, state->Vpp, state->io_irq, state->csc_mask); + + /* First, set voltage - bail out if invalid */ + if(voltage_set(lsock, state->Vcc, state->Vpp)) + return -EINVAL; + + /* Take care of reset... */ + if(state->flags & SS_RESET) + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */ + else + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET); + + /* ... and output enable. */ + + /* The CxOE signal is connected to a 74541 on the ADS. + I guess most other boards used the ADS as a reference. + I tried to control the CxOE signal with SS_OUTPUT_ENA, + but the reset signal seems connected via the 541. + If the CxOE is left high are some signals tristated and + no pullups are present -> the cards act wierd. + So right now the buffers are enabled if the power is on. */ + + if(state->Vcc || state->Vpp) + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */ + else + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE); + + /* + * We'd better turn off interrupts before + * we mess with the events-table.. + */ + + spin_lock_irqsave(&events_lock, flags); + + /* + * Play around with the interrupt mask to be able to + * give the events the generic pcmcia driver wants us to. + */ + + e = &s->events[0]; + reg = 0; + + if(state->csc_mask & SS_DETECT) { + e->eventbit = SS_DETECT; + reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock) + | M8XX_PCMCIA_CD1(lsock)); + e++; + } + if(state->flags & SS_IOCARD) { + /* + * I/O card + */ + if(state->csc_mask & SS_STSCHG) { + e->eventbit = SS_STSCHG; + reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock); + e++; + } + /* + * If io_irq is non-zero we should enable irq. + */ + if(state->io_irq) { + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24); + /* + * Strange thing here: + * The manual does not tell us which interrupt + * the sources generate. + * Anyhow, I found out that RDY_L generates IREQLVL. + * + * We use level triggerd interrupts, and they don't + * have to be cleared in PSCR in the interrupt handler. + */ + reg |= M8XX_PCMCIA_RDY_L(lsock); + } + else + out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff); + } + else { + /* + * Memory card + */ + if(state->csc_mask & SS_BATDEAD) { + e->eventbit = SS_BATDEAD; + reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock); + e++; + } + if(state->csc_mask & SS_BATWARN) { + e->eventbit = SS_BATWARN; + reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock); + e++; + } + /* What should I trigger on - low/high,raise,fall? */ + if(state->csc_mask & SS_READY) { + e->eventbit = SS_READY; + reg |= e->regbit = 0; //?? + e++; + } + } + + e->regbit = 0; /* terminate list */ + + /* + * Clear the status changed . + * Port A and Port B share the same port. + * Writing ones will clear the bits. + */ + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg); + + /* + * Write the mask. + * Port A and Port B share the same port. + * Need for read-modify-write. + * Ones will enable the interrupt. + */ + + /* + reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per + & M8XX_PCMCIA_MASK(lsock); + */ + + reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & + (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1)); + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg); + + spin_unlock_irqrestore(&events_lock, flags); + + /* copy the struct and modify the copy */ + + s->state = *state; + + return 0; +} + +static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) +{ + int lsock = container_of(sock, struct socket_info, socket)->slot; + + struct socket_info *s = &socket[lsock]; + struct pcmcia_win *w; + unsigned int reg, winnr; + +#define M8XX_SIZE (io->stop - io->start + 1) +#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start) + + dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, " + "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags, + io->speed, io->start, io->stop); + + if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff) + || (io->stop > 0xffff) || (io->stop < io->start)) + return -EINVAL; + + if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1) + return -EINVAL; + + if(io->flags & MAP_ACTIVE) { + + dprintk( "io->flags & MAP_ACTIVE\n"); + + winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) + + (lsock * PCMCIA_IO_WIN_NO) + io->map; + + /* setup registers */ + + w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; + w += winnr; + + out_be32(&w->or, 0); /* turn off window first */ + out_be32(&w->br, M8XX_BASE); + + reg <<= 27; + reg |= M8XX_PCMCIA_POR_IO |(lsock << 2); + + reg |= m8xx_get_speed(io->speed, 1); + + if(io->flags & MAP_WRPROT) + reg |= M8XX_PCMCIA_POR_WRPROT; + + /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/ + if(io->flags & MAP_16BIT) + reg |= M8XX_PCMCIA_POR_16BIT; + + if(io->flags & MAP_ACTIVE) + reg |= M8XX_PCMCIA_POR_VALID; + + out_be32(&w->or, reg); + + dprintk("Socket %u: Mapped io window %u at %#8.8x, " + "OR = %#8.8x.\n", lsock, io->map, w->br, w->or); + } else { + /* shutdown IO window */ + winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) + + (lsock * PCMCIA_IO_WIN_NO) + io->map; + + /* setup registers */ + + w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; + w += winnr; + + out_be32(&w->or, 0); /* turn off window */ + out_be32(&w->br, 0); /* turn off base address */ + + dprintk("Socket %u: Unmapped io window %u at %#8.8x, " + "OR = %#8.8x.\n", lsock, io->map, w->br, w->or); + } + + /* copy the struct and modify the copy */ + s->io_win[io->map] = *io; + s->io_win[io->map].flags &= (MAP_WRPROT + | MAP_16BIT + | MAP_ACTIVE); + dprintk("SetIOMap exit\n"); + + return 0; +} + +static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) +{ + int lsock = container_of(sock, struct socket_info, socket)->slot; + struct socket_info *s = &socket[lsock]; + struct pcmcia_win *w; + struct pccard_mem_map *old; + unsigned int reg, winnr; + + dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, " + "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, + mem->speed, mem->static_start, mem->card_start); + + if ((mem->map >= PCMCIA_MEM_WIN_NO) +// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE) + || (mem->card_start >= 0x04000000) + || (mem->static_start & 0xfff) /* 4KByte resolution */ + || (mem->card_start & 0xfff)) + return -EINVAL; + + if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) { + printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE); + return -EINVAL; + } + reg <<= 27; + + winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map; + + /* Setup the window in the pcmcia controller */ + + w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; + w += winnr; + + reg |= lsock << 2; + + reg |= m8xx_get_speed(mem->speed, 0); + + if(mem->flags & MAP_ATTRIB) + reg |= M8XX_PCMCIA_POR_ATTRMEM; + + if(mem->flags & MAP_WRPROT) + reg |= M8XX_PCMCIA_POR_WRPROT; + + if(mem->flags & MAP_16BIT) + reg |= M8XX_PCMCIA_POR_16BIT; + + if(mem->flags & MAP_ACTIVE) + reg |= M8XX_PCMCIA_POR_VALID; + + out_be32(&w->or, reg); + + dprintk("Socket %u: Mapped memory window %u at %#8.8x, " + "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or); + + if(mem->flags & MAP_ACTIVE) { + /* get the new base address */ + mem->static_start = PCMCIA_MEM_WIN_BASE + + (PCMCIA_MEM_WIN_SIZE * winnr) + + mem->card_start; + } + + dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, " + "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, + mem->speed, mem->static_start, mem->card_start); + + /* copy the struct and modify the copy */ + + old = &s->mem_win[mem->map]; + + *old = *mem; + old->flags &= (MAP_ATTRIB + | MAP_WRPROT + | MAP_16BIT + | MAP_ACTIVE); + + return 0; +} + +static int m8xx_sock_init(struct pcmcia_socket *sock) +{ + int i; + pccard_io_map io = { 0, 0, 0, 0, 1 }; + pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + + dprintk( "sock_init(%d)\n", s); + + m8xx_set_socket(sock, &dead_socket); + for (i = 0; i < PCMCIA_IO_WIN_NO; i++) { + io.map = i; + m8xx_set_io_map(sock, &io); + } + for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) { + mem.map = i; + m8xx_set_mem_map(sock, &mem); + } + + return 0; + +} + +static int m8xx_suspend(struct pcmcia_socket *sock) +{ + return m8xx_set_socket(sock, &dead_socket); +} + +static struct pccard_operations m8xx_services = { + .init = m8xx_sock_init, + .suspend = m8xx_suspend, + .get_status = m8xx_get_status, + .get_socket = m8xx_get_socket, + .set_socket = m8xx_set_socket, + .set_io_map = m8xx_set_io_map, + .set_mem_map = m8xx_set_mem_map, +}; + +static int __init m8xx_init(void) +{ + struct pcmcia_win *w; + unsigned int i,m; + + pcmcia_info("%s\n", version); + + if (driver_register(&m8xx_driver)) + return -1; + + pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG + " with IRQ %u.\n", pcmcia_schlvl); + + /* Configure Status change interrupt */ + + if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0, + "m8xx_pcmcia", NULL)) { + pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n", + pcmcia_schlvl); + return -1; + } + + w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, + M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)); + + out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, + in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & + ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1))); + +/* connect interrupt and disable CxOE */ + + out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); + out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); + +/* intialize the fixed memory windows */ + + for(i = 0; i < PCMCIA_SOCKETS_NO; i++){ + for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) { + out_be32(&w->br, PCMCIA_MEM_WIN_BASE + + (PCMCIA_MEM_WIN_SIZE + * (m + i * PCMCIA_MEM_WIN_NO))); + + out_be32(&w->or, 0); /* set to not valid */ + + w++; + } + } + +/* turn off voltage */ + voltage_set(0, 0, 0); + voltage_set(1, 0, 0); + +/* Enable external hardware */ + hardware_enable(0); + hardware_enable(1); + + platform_device_register(&m8xx_device); + + for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) { + socket[i].slot = i; + socket[i].socket.owner = THIS_MODULE; + socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP; + socket[i].socket.irq_mask = 0x000; + socket[i].socket.map_size = 0x1000; + socket[i].socket.io_offset = 0; + socket[i].socket.pci_irq = i ? 7 : 9; + socket[i].socket.ops = &m8xx_services; + socket[i].socket.resource_ops = &pccard_nonstatic_ops; + socket[i].socket.cb_dev = NULL; + socket[i].socket.dev.dev = &m8xx_device.dev; + } + + for (i = 0; i < PCMCIA_SOCKETS_NO; i++) + pcmcia_register_socket(&socket[i].socket); + + return 0; +} + +static void __exit m8xx_exit(void) +{ + int i; + + for (i = 0; i < PCMCIA_SOCKETS_NO; i++) + pcmcia_unregister_socket(&socket[i].socket); + + m8xx_shutdown(); + + platform_device_unregister(&m8xx_device); + driver_unregister(&m8xx_driver); +} + +module_init(m8xx_init); +module_exit(m8xx_exit); From d5f7b06b036afc2cb250decb2c76b7f82c5de639 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Fri, 28 Oct 2005 17:46:14 -0700 Subject: [PATCH 0925/1940] [PATCH] ppc32: Cleanup AMCC PPC44x eval board U-Boot support Cleanup PPC440 eval boards (bamboo, ebony, luan and ocotea) to better support U-Boot as bootloader. Signed-off-by: Stefan Roese Signed-off-by: Matt Porter Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/platforms/4xx/bamboo.c | 14 ++----------- arch/ppc/platforms/4xx/ebony.c | 13 ++---------- arch/ppc/platforms/4xx/luan.c | 13 ++---------- arch/ppc/platforms/4xx/ocotea.c | 31 +++++++++++------------------ arch/ppc/syslib/ibm44x_common.c | 35 ++++++++++++++++++++++++++++++++- arch/ppc/syslib/ibm44x_common.h | 3 ++- 6 files changed, 53 insertions(+), 56 deletions(-) diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c index 78a403b48dba..159b228eca1e 100644 --- a/arch/ppc/platforms/4xx/bamboo.c +++ b/arch/ppc/platforms/4xx/bamboo.c @@ -51,7 +51,7 @@ #include #include -bd_t __res; +extern bd_t __res; static struct ibm44x_clocks clocks __initdata; @@ -425,17 +425,7 @@ bamboo_setup_arch(void) void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - parse_bootinfo(find_bootinfo()); - - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) - __res = *(bd_t *)(r3 + KERNELBASE); - - - ibm44x_platform_init(); + ibm44x_platform_init(r3, r4, r5, r6, r7); ppc_md.setup_arch = bamboo_setup_arch; ppc_md.show_cpuinfo = bamboo_show_cpuinfo; diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c index d32ae112f639..64ebae19cdbb 100644 --- a/arch/ppc/platforms/4xx/ebony.c +++ b/arch/ppc/platforms/4xx/ebony.c @@ -54,7 +54,7 @@ #include #include -bd_t __res; +extern bd_t __res; static struct ibm44x_clocks clocks __initdata; @@ -317,16 +317,7 @@ ebony_setup_arch(void) void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - parse_bootinfo(find_bootinfo()); - - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) - __res = *(bd_t *)(r3 + KERNELBASE); - - ibm44x_platform_init(); + ibm44x_platform_init(r3, r4, r5, r6, r7); ppc_md.setup_arch = ebony_setup_arch; ppc_md.show_cpuinfo = ebony_show_cpuinfo; diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c index 16d953bda22c..d810b736d9bf 100644 --- a/arch/ppc/platforms/4xx/luan.c +++ b/arch/ppc/platforms/4xx/luan.c @@ -52,7 +52,7 @@ #include #include -bd_t __res; +extern bd_t __res; static struct ibm44x_clocks clocks __initdata; @@ -355,16 +355,7 @@ luan_setup_arch(void) void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - parse_bootinfo(find_bootinfo()); - - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) - __res = *(bd_t *)(r3 + KERNELBASE); - - ibm44x_platform_init(); + ibm44x_platform_init(r3, r4, r5, r6, r7); ppc_md.setup_arch = luan_setup_arch; ppc_md.show_cpuinfo = luan_show_cpuinfo; diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c index 506949c5dd29..73b2c98158f6 100644 --- a/arch/ppc/platforms/4xx/ocotea.c +++ b/arch/ppc/platforms/4xx/ocotea.c @@ -52,7 +52,7 @@ #include #include -bd_t __res; +extern bd_t __res; static struct ibm44x_clocks clocks __initdata; @@ -286,6 +286,15 @@ ocotea_setup_arch(void) ibm440gx_tah_enable(); + /* + * Determine various clocks. + * To be completely correct we should get SysClk + * from FPGA, because it can be changed by on-board switches + * --ebs + */ + ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); + ocp_sys_info.opb_bus_freq = clocks.opb; + /* Setup TODC access */ TODC_INIT(TODC_TYPE_DS1743, 0, @@ -324,25 +333,7 @@ static void __init ocotea_init(void) void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - parse_bootinfo(find_bootinfo()); - - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) - __res = *(bd_t *)(r3 + KERNELBASE); - - /* - * Determine various clocks. - * To be completely correct we should get SysClk - * from FPGA, because it can be changed by on-board switches - * --ebs - */ - ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); - ocp_sys_info.opb_bus_freq = clocks.opb; - - ibm44x_platform_init(); + ibm44x_platform_init(r3, r4, r5, r6, r7); ppc_md.setup_arch = ocotea_setup_arch; ppc_md.show_cpuinfo = ocotea_show_cpuinfo; diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c index 95e11f93c15d..5152c8e41340 100644 --- a/arch/ppc/syslib/ibm44x_common.c +++ b/arch/ppc/syslib/ibm44x_common.c @@ -27,9 +27,14 @@ #include #include #include +#include +#include #include +/* Global Variables */ +bd_t __res; + phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size) { phys_addr_t page_4gb = 0; @@ -150,8 +155,36 @@ static unsigned long __init ibm44x_find_end_of_memory(void) return mem_size; } -void __init ibm44x_platform_init(void) +void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) { + parse_bootinfo(find_bootinfo()); + + /* + * If we were passed in a board information, copy it into the + * residual data area. + */ + if (r3) + __res = *(bd_t *)(r3 + KERNELBASE); + +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } + ppc_md.init_IRQ = ppc4xx_pic_init; ppc_md.find_end_of_memory = ibm44x_find_end_of_memory; ppc_md.restart = ibm44x_restart; diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h index c16b6a5ac6ab..b25a8995e4e9 100644 --- a/arch/ppc/syslib/ibm44x_common.h +++ b/arch/ppc/syslib/ibm44x_common.h @@ -36,7 +36,8 @@ struct ibm44x_clocks { }; /* common 44x platform init */ -void ibm44x_platform_init(void) __init; +void ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) __init; /* initialize decrementer and tick-related variables */ void ibm44x_calibrate_decr(unsigned int freq) __init; From 434cc69fbb02dd7ca64c5029dc6a6f9636f77e02 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 28 Oct 2005 17:46:15 -0700 Subject: [PATCH 0926/1940] [PATCH] ppc32: #ifdef out ALTIVEC specific code in __switch_to #ifdef out an ALTIVEC specific tweak in __switch_to() Signed-off-by: Marcelo Tosatti Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/kernel/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 78ea10197a0b..cb1c7b92f8c6 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -347,11 +347,13 @@ struct task_struct *__switch_to(struct task_struct *prev, #endif /* CONFIG_SPE */ #endif /* CONFIG_SMP */ +#ifdef CONFIG_ALTIVEC /* Avoid the trap. On smp this this never happens since * we don't set last_task_used_altivec -- Cort */ if (new->thread.regs && last_task_used_altivec == new) new->thread.regs->msr |= MSR_VEC; +#endif #ifdef CONFIG_SPE /* Avoid the trap. On smp this this never happens since * we don't set last_task_used_spe From d49b340124a34fcb8bceda472558ccef7232c16f Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:17 -0700 Subject: [PATCH 0927/1940] [PATCH] ppc32: update xmon help text Mention a few more commands in xmon. System.map processing was replaced with kallsyms. Signed-off-by: Olaf Hering Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/xmon/xmon.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index be7869e39465..66bfaa3211a2 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -148,9 +148,14 @@ Commands:\n\ r print registers\n\ S print special registers\n\ t print backtrace\n\ - la lookup address in system.map\n\ - ls lookup symbol in system.map\n\ + la lookup address\n\ + ls lookup symbol\n\ + C checksum\n\ + p call function with arguments\n\ + T print time\n\ x exit monitor\n\ + zr reboot\n\ + zh halt\n\ "; static int xmon_trace[NR_CPUS]; From e83b860539d0ac1b3cff868178fa79c457e0c21f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 21 Oct 2005 18:00:48 +0900 Subject: [PATCH 0928/1940] [TCP]: fix tcp_tso_win_divisor documentation The default value for tcp_tso_win_divisor is 3. Signed-off-by: Akinobu Mita Signed-off-by: Arnaldo Carvalho de Melo --- Documentation/networking/ip-sysctl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index b433c8a27e2d..65895bb51414 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -309,7 +309,7 @@ tcp_tso_win_divisor - INTEGER can be consumed by a single TSO frame. The setting of this parameter is a choice between burstiness and building larger TSO frames. - Default: 8 + Default: 3 tcp_frto - BOOLEAN Enables F-RTO, an enhanced recovery algorithm for TCP retransmission From 360ac8e2f1a38c3497739636c3b702352d1ad0ae Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Oct 2005 15:03:41 -0700 Subject: [PATCH 0929/1940] [ETH]: ether address compare Expose faster ether compare for use by protocols and other driver. And change name to be more consistent with other ether address manipulation routines in same file Signed-off-by: Stephen Hemminger Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/etherdevice.h | 16 ++++++++++++++++ net/ethernet/eth.c | 17 ++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 4522c7186bf3..cc84934f9059 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -104,6 +104,22 @@ static inline void random_ether_addr(u8 *addr) addr [0] &= 0xfe; /* clear multicast bit */ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ } + +/** + * compare_ether_addr - Compare two Ethernet addresses + * @addr1: Pointer to a six-byte array containing the Ethernet address + * @addr2 Pointer other six-byte array containing the Ethernet address + * + * Compare two ethernet addresses, returns 0 if equal + */ +static inline unsigned compare_ether_addr(const u8 *_a, const u8 *_b) +{ + const u16 *a = (const u16 *) _a; + const u16 *b = (const u16 *) _b; + + BUILD_BUG_ON(ETH_ALEN != 6); + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; +} #endif /* __KERNEL__ */ #endif /* _LINUX_ETHERDEVICE_H */ diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 68a5ca866442..e24577367274 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *skb) return 0; } -static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b) -{ - const unsigned short *dest = (unsigned short *) __a; - const unsigned short *devaddr = (unsigned short *) __b; - unsigned int res; - - BUILD_BUG_ON(ETH_ALEN != 6); - res = ((dest[0] ^ devaddr[0]) | - (dest[1] ^ devaddr[1]) | - (dest[2] ^ devaddr[2])) != 0; - - return res; -} /* * Determine the packet's protocol ID. The rule here is that we @@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) eth = eth_hdr(skb); if (*eth->h_dest&1) { - if (!compare_eth_addr(eth->h_dest, dev->broadcast)) + if (!compare_ether_addr(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) */ else if(1 /*dev->flags&IFF_PROMISC*/) { - if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr))) + if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; } From 8b150478aeb1a8edb9015c2f7ac4da637ff65c45 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 28 Oct 2005 17:46:18 -0700 Subject: [PATCH 0930/1940] [PATCH] ppc: make phys_mem_access_prot() work with pfns instead of addresses Change the phys_mem_access_prot() function to take a pfn instead of an address. This allows mmap64() to work on /dev/mem for addresses above 4G on 32-bit architectures. We start with a pfn in mmap_mem(), so there's no need to convert to an address; in fact, it's actively bad, since the conversion can overflow when the address is above 4G. Similarly fix the ppc32 page_is_ram() function to avoid a conversion to an address by directly comparing to max_pfn. Working with max_pfn instead of high_memory fixes page_is_ram() to give the right answer for highmem pages. Signed-off-by: Roland Dreier Cc: Anton Blanchard Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/mm/mem.c | 6 +++--- arch/ppc/kernel/pci.c | 5 +++-- arch/ppc/mm/init.c | 10 ++++------ arch/ppc64/kernel/pci.c | 5 +++-- drivers/char/mem.c | 4 +--- drivers/video/fbmem.c | 2 +- include/asm-powerpc/machdep.h | 2 +- include/asm-ppc/machdep.h | 2 +- include/asm-ppc/pci.h | 2 +- include/asm-ppc/pgtable.h | 2 +- include/asm-ppc64/pci.h | 2 +- include/asm-ppc64/pgtable.h | 2 +- 12 files changed, 21 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 695db6a588ce..3ca331728d21 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -88,13 +88,13 @@ int page_is_ram(unsigned long pfn) } EXPORT_SYMBOL(page_is_ram); -pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) { if (ppc_md.phys_mem_access_prot) - return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); + return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot); - if (!page_is_ram(addr >> PAGE_SHIFT)) + if (!page_is_ram(pfn)) vma_prot = __pgprot(pgprot_val(vma_prot) | _PAGE_GUARDED | _PAGE_NO_CACHE); return vma_prot; diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index ad4ef2aaa6ab..e8f4e576750a 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1594,16 +1594,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, * above routine */ pgprot_t pci_phys_mem_access_prot(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t protection) { struct pci_dev *pdev = NULL; struct resource *found = NULL; unsigned long prot = pgprot_val(protection); + unsigned long offset = pfn << PAGE_SHIFT; int i; - if (page_is_ram(offset >> PAGE_SHIFT)) + if (page_is_ram(pfn)) return prot; prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index db94efd25369..99b48abd3296 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -637,18 +637,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, */ int page_is_ram(unsigned long pfn) { - unsigned long paddr = (pfn << PAGE_SHIFT); - - return paddr < __pa(high_memory); + return pfn < max_pfn; } -pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) { if (ppc_md.phys_mem_access_prot) - return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot); + return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot); - if (!page_is_ram(addr >> PAGE_SHIFT)) + if (!page_is_ram(pfn)) vma_prot = __pgprot(pgprot_val(vma_prot) | _PAGE_GUARDED | _PAGE_NO_CACHE); return vma_prot; diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index b2fb6746f00b..3d2106b022a1 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -726,16 +726,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, * above routine */ pgprot_t pci_phys_mem_access_prot(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t protection) { struct pci_dev *pdev = NULL; struct resource *found = NULL; unsigned long prot = pgprot_val(protection); + unsigned long offset = pfn << PAGE_SHIFT; int i; - if (page_is_ram(offset >> PAGE_SHIFT)) + if (page_is_ram(pfn)) return __pgprot(prot); prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index f182752fe918..9df928d4f68d 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -231,9 +231,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, static int mmap_mem(struct file * file, struct vm_area_struct * vma) { #if defined(__HAVE_PHYS_MEM_ACCESS_PROT) - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - - vma->vm_page_prot = phys_mem_access_prot(file, offset, + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); #elif defined(pgprot_noncached) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 70be7009f8af..ca02aa2bfcec 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -918,7 +918,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) } #endif #elif defined(__powerpc__) - vma->vm_page_prot = phys_mem_access_prot(file, off, + vma->vm_page_prot = phys_mem_access_prot(file, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot); #elif defined(__alpha__) diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 706508b1b04b..451b345cfc78 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -144,7 +144,7 @@ struct machdep_calls { /* Get access protection for /dev/mem */ pgprot_t (*phys_mem_access_prot)(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t vma_prot); diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 6c6d23abbe91..f01255bd1dc3 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -98,7 +98,7 @@ struct machdep_calls { /* Get access protection for /dev/mem */ pgprot_t (*phys_mem_access_prot)(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t vma_prot); diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 643740dd727b..61434edbad7b 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -126,7 +126,7 @@ extern void pcibios_add_platform_entries(struct pci_dev *dev); struct file; extern pgprot_t pci_phys_mem_access_prot(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t prot); diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index eee601bb9ada..b28a713ba862 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -705,7 +705,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty) #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED)) struct file; -extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot); #define __HAVE_PHYS_MEM_ACCESS_PROT diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index a88bbfc26967..342e2d755550 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -168,7 +168,7 @@ extern void pcibios_add_platform_entries(struct pci_dev *dev); struct file; extern pgprot_t pci_phys_mem_access_prot(struct file *file, - unsigned long offset, + unsigned long pfn, unsigned long size, pgprot_t prot); diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h index c83679c9d2b0..8cf5991540e3 100644 --- a/include/asm-ppc64/pgtable.h +++ b/include/asm-ppc64/pgtable.h @@ -471,7 +471,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty) #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED)) struct file; -extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot); #define __HAVE_PHYS_MEM_ACCESS_PROT From 35e95e63995f3e52178db4b769120ce60deb6b54 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:19 -0700 Subject: [PATCH 0931/1940] [PATCH] ppc32: nvram driver for chrp This implements a nvram acccess method, similar to arch/ppc64/kernel/pSeries_nvram.c tested on CHRP B50. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/chrp/Makefile | 1 + arch/powerpc/platforms/chrp/chrp.h | 12 ++++ arch/powerpc/platforms/chrp/nvram.c | 84 ++++++++++++++++++++++++++++ arch/powerpc/platforms/chrp/setup.c | 11 ++-- arch/ppc/platforms/Makefile | 3 + arch/ppc/platforms/chrp_nvram.c | 83 +++++++++++++++++++++++++++ arch/ppc/platforms/chrp_setup.c | 3 +- include/asm-ppc/system.h | 1 + 8 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 arch/powerpc/platforms/chrp/chrp.h create mode 100644 arch/powerpc/platforms/chrp/nvram.c create mode 100644 arch/ppc/platforms/chrp_nvram.c diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile index 1fde4e68414f..902feb1ac431 100644 --- a/arch/powerpc/platforms/chrp/Makefile +++ b/arch/powerpc/platforms/chrp/Makefile @@ -1,3 +1,4 @@ obj-y += setup.o time.o pegasos_eth.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_NVRAM) += nvram.o diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h new file mode 100644 index 000000000000..3a2057fa314a --- /dev/null +++ b/arch/powerpc/platforms/chrp/chrp.h @@ -0,0 +1,12 @@ +/* + * Declarations of CHRP platform-specific things. + */ + +extern void chrp_nvram_init(void); +extern void chrp_get_rtc_time(struct rtc_time *); +extern int chrp_set_rtc_time(struct rtc_time *); +extern void chrp_calibrate_decr(void); +extern long chrp_time_init(void); + +extern void chrp_find_bridges(void); +extern void chrp_event_scan(void); diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c new file mode 100644 index 000000000000..4ac7125aa09c --- /dev/null +++ b/arch/powerpc/platforms/chrp/nvram.c @@ -0,0 +1,84 @@ +/* + * c 2001 PPC 64 Team, IBM Corp + * + * 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. + * + * /dev/nvram driver for PPC + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "chrp.h" + +static unsigned int nvram_size; +static unsigned char nvram_buf[4]; +static DEFINE_SPINLOCK(nvram_lock); + +static unsigned char chrp_nvram_read(int addr) +{ + unsigned long done, flags; + unsigned char ret; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return 0xff; + } + spin_lock_irqsave(&nvram_lock, flags); + if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + ret = 0xff; + else + ret = nvram_buf[0]; + spin_unlock_irqrestore(&nvram_lock, flags); + + return ret; +} + +static void chrp_nvram_write(int addr, unsigned char val) +{ + unsigned long done, flags; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return; + } + spin_lock_irqsave(&nvram_lock, flags); + nvram_buf[0] = val; + if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr); + spin_unlock_irqrestore(&nvram_lock, flags); +} + +void __init chrp_nvram_init(void) +{ + struct device_node *nvram; + unsigned int *nbytes_p, proplen; + + nvram = of_find_node_by_type(NULL, "nvram"); + if (nvram == NULL) + return; + + nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + if (nbytes_p == NULL || proplen != sizeof(unsigned int)) + return; + + nvram_size = *nbytes_p; + + printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size); + of_node_put(nvram); + + ppc_md.nvram_read_val = chrp_nvram_read; + ppc_md.nvram_write_val = chrp_nvram_write; + + return; +} diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 5145990e6a01..ecd32d5d85f4 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -55,13 +55,8 @@ #include #include -void chrp_get_rtc_time(struct rtc_time *); -int chrp_set_rtc_time(struct rtc_time *); -void chrp_calibrate_decr(void); -long chrp_time_init(void); +#include "chrp.h" -void chrp_find_bridges(void); -void chrp_event_scan(void); void rtas_indicator_progress(char *, unsigned short); void btext_progress(char *, unsigned short); @@ -469,6 +464,10 @@ void __init chrp_init_IRQ(void) void __init chrp_init2(void) { +#ifdef CONFIG_NVRAM + chrp_nvram_init(); +#endif + request_region(0x20,0x20,"pic1"); request_region(0xa0,0x20,"pic2"); request_region(0x00,0x20,"dma1"); diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile index ff7452e5d8e5..7c5cdabf6f3c 100644 --- a/arch/ppc/platforms/Makefile +++ b/arch/ppc/platforms/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \ pmac_low_i2c.o pmac_cache.o obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ chrp_pegasos_eth.o +ifeq ($(CONFIG_PPC_CHRP),y) +obj-$(CONFIG_NVRAM) += chrp_nvram.o +endif obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o ifeq ($(CONFIG_PPC_PMAC),y) obj-$(CONFIG_NVRAM) += pmac_nvram.o diff --git a/arch/ppc/platforms/chrp_nvram.c b/arch/ppc/platforms/chrp_nvram.c new file mode 100644 index 000000000000..465ba9b090ef --- /dev/null +++ b/arch/ppc/platforms/chrp_nvram.c @@ -0,0 +1,83 @@ +/* + * c 2001 PPC 64 Team, IBM Corp + * + * 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. + * + * /dev/nvram driver for PPC + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static unsigned int nvram_size; +static unsigned char nvram_buf[4]; +static DEFINE_SPINLOCK(nvram_lock); + +static unsigned char chrp_nvram_read(int addr) +{ + unsigned long done, flags; + unsigned char ret; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return 0xff; + } + spin_lock_irqsave(&nvram_lock, flags); + if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + ret = 0xff; + else + ret = nvram_buf[0]; + spin_unlock_irqrestore(&nvram_lock, flags); + + return ret; +} + +static void chrp_nvram_write(int addr, unsigned char val) +{ + unsigned long done, flags; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return; + } + spin_lock_irqsave(&nvram_lock, flags); + nvram_buf[0] = val; + if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr); + spin_unlock_irqrestore(&nvram_lock, flags); +} + +void __init chrp_nvram_init(void) +{ + struct device_node *nvram; + unsigned int *nbytes_p, proplen; + + nvram = of_find_node_by_type(NULL, "nvram"); + if (nvram == NULL) + return; + + nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + if (nbytes_p == NULL || proplen != sizeof(unsigned int)) + return; + + nvram_size = *nbytes_p; + + printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size); + of_node_put(nvram); + + ppc_md.nvram_read_val = chrp_nvram_read; + ppc_md.nvram_write_val = chrp_nvram_write; + + return; +} diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index dad81ffd4013..f1b70ab3c6fd 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -454,8 +454,7 @@ void __init chrp_init2(void) { #ifdef CONFIG_NVRAM -// XX replace this in a more saner way -// pmac_nvram_init(); + chrp_nvram_init(); #endif request_region(0x20,0x20,"pic1"); diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index eb30c09516ae..bd99cb53a19f 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -70,6 +70,7 @@ extern void _set_L3CR(unsigned long); #endif extern void via_cuda_init(void); extern void pmac_nvram_init(void); +extern void chrp_nvram_init(void); extern void read_rtc_time(void); extern void pmac_find_display(void); extern void giveup_fpu(struct task_struct *); From dcb34abb4d9bae0588c5c11101ed6afcee71f895 Mon Sep 17 00:00:00 2001 From: "scwhab@suse.de" Date: Fri, 28 Oct 2005 17:46:20 -0700 Subject: [PATCH 0932/1940] [PATCH] Add modalias to macio sysfs attributes Provide a "compatible" entry in /sys/bus/macio/devices/*/ This can be used to load drivers via the modules.alias file. Signed-off-by: Olaf Hering Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/macintosh/macio_sysfs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 97d22bb4516a..7f7d4eaca870 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -39,6 +39,31 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) return length; } +static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct of_device *of; + char *compat; + int cplen; + int length; + + of = &to_macio_device (dev)->ofdev; + compat = (char *) get_property (of->node, "compatible", &cplen); + if (!compat) compat = "", cplen = 1; + length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type); + buf += length; + while (cplen > 0) { + int l; + length += sprintf (buf, "C%s", compat); + buf += length; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + } + + return length; +} + macio_config_of_attr (name, "%s\n"); macio_config_of_attr (type, "%s\n"); @@ -46,5 +71,6 @@ struct device_attribute macio_dev_attrs[] = { __ATTR_RO(name), __ATTR_RO(type), __ATTR_RO(compatible), + __ATTR_RO(modalias), __ATTR_NULL }; From 8c9795ba01d02b043ce2d9eeb0fa908c07e5fb42 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:21 -0700 Subject: [PATCH 0933/1940] [PATCH] Add modalias for pmac network drivers mesh, mac53c94 and airport already have an entry. Add the network drivers for pmac. Signed-off-by: Olaf Hering Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/net/bmac.c | 1 + drivers/net/mace.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 60dba4a1ca5c..0ee28899fb8d 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1658,6 +1658,7 @@ static struct of_device_id bmac_match[] = }, {}, }; +MODULE_DEVICE_TABLE (of, bmac_match); static struct macio_driver bmac_driver = { diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 81d0a26e4f41..f2fc1f26cd4b 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -1016,6 +1016,7 @@ static struct of_device_id mace_match[] = }, {}, }; +MODULE_DEVICE_TABLE (of, mace_match); static struct macio_driver mace_driver = { From dd03d25fac90ee6f394874fb4e6995866304e4ba Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Fri, 28 Oct 2005 17:46:25 -0700 Subject: [PATCH 0934/1940] [PATCH] chrp_pegasos_eth: Added Marvell Discovery II SRAM support Add proper entry to support the Marvell MV64361 (Marvell Discovery II) SRAM. This feature may be used by the mv643xx_eth driver. Signed-off-by: Nicolas DET Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/chrp/pegasos_eth.c | 124 ++++++++++++++++++++-- arch/ppc/platforms/chrp_pegasos_eth.c | 124 ++++++++++++++++++++-- 2 files changed, 236 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index cad5bfa153b2..a9052305c35d 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -17,7 +17,20 @@ #include #include -/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */ +#define PEGASOS2_MARVELL_REGBASE (0xf1000000) +#define PEGASOS2_MARVELL_REGSIZE (0x00004000) +#define PEGASOS2_SRAM_BASE (0xf2000000) +#define PEGASOS2_SRAM_SIZE (256*1024) + +#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) +#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) + + +#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) +#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) + +#undef BE_VERBOSE + static struct resource mv643xx_eth_shared_resources[] = { [0] = { .name = "ethernet shared base", @@ -44,7 +57,16 @@ static struct resource mv643xx_eth0_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth0_pd; + +static struct mv643xx_eth_platform_data eth0_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; static struct platform_device eth0_device = { .name = MV643XX_ETH_NAME, @@ -65,7 +87,15 @@ static struct resource mv643xx_eth1_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth1_pd; +static struct mv643xx_eth_platform_data eth1_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; static struct platform_device eth1_device = { .name = MV643XX_ETH_NAME, @@ -83,9 +113,62 @@ static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { ð1_device, }; +/***********/ +/***********/ +#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } +#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) -int -mv643xx_eth_add_pds(void) +static void __iomem *mv643xx_reg_base; + +static int Enable_SRAM(void) +{ + u32 ALong; + + if (mv643xx_reg_base == NULL) + mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, + PEGASOS2_MARVELL_REGSIZE); + + if (mv643xx_reg_base == NULL) + return -ENOMEM; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", + (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); +#endif + + MV_WRITE(MV64340_SRAM_CONFIG, 0); + + MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); + + MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); + ALong &= ~(1 << 19); + MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); + + ALong = 0x02; + ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; + MV_WRITE(MV643XX_ETH_BAR_4, ALong); + + MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); + + MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + ALong &= ~(1 << 4); + MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register unmapped\n"); + printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); +#endif + + iounmap(mv643xx_reg_base); + mv643xx_reg_base = NULL; + + return 1; +} + + +/***********/ +/***********/ +int mv643xx_eth_add_pds(void) { int ret = 0; static struct pci_device_id pci_marvell_mv64360[] = { @@ -93,9 +176,38 @@ mv643xx_eth_add_pds(void) { } }; +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init\n"); +#endif + if (pci_dev_present(pci_marvell_mv64360)) { - ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs)); + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + if ( Enable_SRAM() < 0) + { + eth0_pd.tx_sram_addr = 0; + eth0_pd.tx_sram_size = 0; + eth0_pd.rx_sram_addr = 0; + eth0_pd.rx_sram_size = 0; + + eth1_pd.tx_sram_addr = 0; + eth1_pd.tx_sram_size = 0; + eth1_pd.rx_sram_addr = 0; + eth1_pd.rx_sram_size = 0; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: Can't enable the " + "SRAM\n"); +#endif + } } + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init is over\n"); +#endif + return ret; } + device_initcall(mv643xx_eth_add_pds); diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c index cad5bfa153b2..a9052305c35d 100644 --- a/arch/ppc/platforms/chrp_pegasos_eth.c +++ b/arch/ppc/platforms/chrp_pegasos_eth.c @@ -17,7 +17,20 @@ #include #include -/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */ +#define PEGASOS2_MARVELL_REGBASE (0xf1000000) +#define PEGASOS2_MARVELL_REGSIZE (0x00004000) +#define PEGASOS2_SRAM_BASE (0xf2000000) +#define PEGASOS2_SRAM_SIZE (256*1024) + +#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) +#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) + + +#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) +#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) + +#undef BE_VERBOSE + static struct resource mv643xx_eth_shared_resources[] = { [0] = { .name = "ethernet shared base", @@ -44,7 +57,16 @@ static struct resource mv643xx_eth0_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth0_pd; + +static struct mv643xx_eth_platform_data eth0_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; static struct platform_device eth0_device = { .name = MV643XX_ETH_NAME, @@ -65,7 +87,15 @@ static struct resource mv643xx_eth1_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth1_pd; +static struct mv643xx_eth_platform_data eth1_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; static struct platform_device eth1_device = { .name = MV643XX_ETH_NAME, @@ -83,9 +113,62 @@ static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { ð1_device, }; +/***********/ +/***********/ +#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } +#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) -int -mv643xx_eth_add_pds(void) +static void __iomem *mv643xx_reg_base; + +static int Enable_SRAM(void) +{ + u32 ALong; + + if (mv643xx_reg_base == NULL) + mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, + PEGASOS2_MARVELL_REGSIZE); + + if (mv643xx_reg_base == NULL) + return -ENOMEM; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", + (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); +#endif + + MV_WRITE(MV64340_SRAM_CONFIG, 0); + + MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); + + MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); + ALong &= ~(1 << 19); + MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); + + ALong = 0x02; + ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; + MV_WRITE(MV643XX_ETH_BAR_4, ALong); + + MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); + + MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + ALong &= ~(1 << 4); + MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register unmapped\n"); + printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); +#endif + + iounmap(mv643xx_reg_base); + mv643xx_reg_base = NULL; + + return 1; +} + + +/***********/ +/***********/ +int mv643xx_eth_add_pds(void) { int ret = 0; static struct pci_device_id pci_marvell_mv64360[] = { @@ -93,9 +176,38 @@ mv643xx_eth_add_pds(void) { } }; +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init\n"); +#endif + if (pci_dev_present(pci_marvell_mv64360)) { - ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs)); + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + if ( Enable_SRAM() < 0) + { + eth0_pd.tx_sram_addr = 0; + eth0_pd.tx_sram_size = 0; + eth0_pd.rx_sram_addr = 0; + eth0_pd.rx_sram_size = 0; + + eth1_pd.tx_sram_addr = 0; + eth1_pd.tx_sram_size = 0; + eth1_pd.rx_sram_addr = 0; + eth1_pd.rx_sram_size = 0; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: Can't enable the " + "SRAM\n"); +#endif + } } + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init is over\n"); +#endif + return ret; } + device_initcall(mv643xx_eth_add_pds); From b37665e0ba1d3f05697bfae249b09a2e9cc95132 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Fri, 28 Oct 2005 17:46:27 -0700 Subject: [PATCH 0935/1940] [PATCH] ppc32: 85xx PHY Platform Update This patch updates the 85xx platform code to support the new PHY Layer. Signed-off-by: Andy Fleming Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/platforms/85xx/mpc8540_ads.c | 30 ++++--- arch/ppc/platforms/85xx/mpc8560_ads.c | 25 ++++-- arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 34 ++++---- arch/ppc/platforms/85xx/sbc8560.c | 22 +++-- arch/ppc/platforms/85xx/stx_gp3.c | 21 +++-- arch/ppc/syslib/mpc85xx_devices.c | 17 ++-- arch/ppc/syslib/mpc85xx_sys.c | 88 +++++++++++--------- include/asm-ppc/mpc85xx.h | 3 + include/linux/fsl_devices.h | 13 ++- 9 files changed, 153 insertions(+), 100 deletions(-) diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 7dc8a68acfd0..7e952c1228cb 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -52,6 +52,10 @@ #include +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; +static const char *GFAR_PHY_3 = "phy0:3"; + /* ************************************************************************ * * Setup the architecture @@ -63,6 +67,7 @@ mpc8540ads_setup_arch(void) bd_t *binfo = (bd_t *) __res; unsigned int freq; struct gianfar_platform_data *pdata; + struct gianfar_mdio_data *mdata; /* get the core frequency */ freq = binfo->bi_intfreq; @@ -89,34 +94,35 @@ mpc8540ads_setup_arch(void) invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif + /* setup the board related info for the MDIO bus */ + mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); + + mdata->irq[0] = MPC85xx_IRQ_EXT5; + mdata->irq[1] = MPC85xx_IRQ_EXT5; + mdata->irq[2] = -1; + mdata->irq[3] = MPC85xx_IRQ_EXT5; + mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; + /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 0; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 1; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { pdata->board_flags = 0; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 3; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_3; memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); } diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index 8841fd7da6ee..208433f1e93a 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -56,6 +56,10 @@ #include +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; +static const char *GFAR_PHY_3 = "phy0:3"; + /* ************************************************************************ * * Setup the architecture @@ -68,6 +72,7 @@ mpc8560ads_setup_arch(void) bd_t *binfo = (bd_t *) __res; unsigned int freq; struct gianfar_platform_data *pdata; + struct gianfar_mdio_data *mdata; cpm2_reset(); @@ -86,24 +91,28 @@ mpc8560ads_setup_arch(void) mpc85xx_setup_hose(); #endif + /* setup the board related info for the MDIO bus */ + mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); + + mdata->irq[0] = MPC85xx_IRQ_EXT5; + mdata->irq[1] = MPC85xx_IRQ_EXT5; + mdata->irq[2] = -1; + mdata->irq[3] = MPC85xx_IRQ_EXT5; + mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; + /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 0; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 1; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index eda659916f24..a21156967a5e 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -391,6 +391,9 @@ mpc85xx_cds_pcibios_fixup(void) TODC_ALLOC(); +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; + /* ************************************************************************ * * Setup the architecture @@ -402,6 +405,7 @@ mpc85xx_cds_setup_arch(void) bd_t *binfo = (bd_t *) __res; unsigned int freq; struct gianfar_platform_data *pdata; + struct gianfar_mdio_data *mdata; /* get the core frequency */ freq = binfo->bi_intfreq; @@ -445,44 +449,42 @@ mpc85xx_cds_setup_arch(void) invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif + /* setup the board related info for the MDIO bus */ + mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); + + mdata->irq[0] = MPC85xx_IRQ_EXT5; + mdata->irq[1] = MPC85xx_IRQ_EXT5; + mdata->irq[2] = -1; + mdata->irq[3] = -1; + mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; + /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 0; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 1; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 0; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 1; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index c76760a781c1..b4ee1707a836 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c @@ -91,6 +91,9 @@ sbc8560_early_serial_map(void) } #endif +static const char *GFAR_PHY_25 = "phy0:25"; +static const char *GFAR_PHY_26 = "phy0:26"; + /* ************************************************************************ * * Setup the architecture @@ -102,6 +105,7 @@ sbc8560_setup_arch(void) bd_t *binfo = (bd_t *) __res; unsigned int freq; struct gianfar_platform_data *pdata; + struct gianfar_mdio_data *mdata; /* get the core frequency */ freq = binfo->bi_intfreq; @@ -126,24 +130,26 @@ sbc8560_setup_arch(void) invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif + /* setup the board related info for the MDIO bus */ + mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); + + mdata->irq[25] = MPC85xx_IRQ_EXT6; + mdata->irq[26] = MPC85xx_IRQ_EXT7; + mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; + /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT6; - pdata->phyid = 25; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_25; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT7; - pdata->phyid = 26; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_26; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index 20940f4044f4..1e1b85f8193a 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c @@ -91,6 +91,9 @@ static u8 gp3_openpic_initsenses[] __initdata = { 0x0, /* External 11: */ }; +static const char *GFAR_PHY_2 = "phy0:2"; +static const char *GFAR_PHY_4 = "phy0:4"; + /* * Setup the architecture */ @@ -100,6 +103,7 @@ gp3_setup_arch(void) bd_t *binfo = (bd_t *) __res; unsigned int freq; struct gianfar_platform_data *pdata; + struct gianfar_mdio_data *mdata; cpm2_reset(); @@ -118,23 +122,26 @@ gp3_setup_arch(void) mpc85xx_setup_hose(); #endif + /* setup the board related info for the MDIO bus */ + mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); + + mdata->irq[2] = MPC85xx_IRQ_EXT5; + mdata->irq[4] = MPC85xx_IRQ_EXT5; + mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; + /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 2; - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_2; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 4; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; + pdata->bus_id = GFAR_PHY_4; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index bbc5ac0de878..2ede677a0a53 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c @@ -25,19 +25,20 @@ /* We use offsets for IORESOURCE_MEM since we do not know at compile time * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup */ +struct gianfar_mdio_data mpc85xx_mdio_pdata = { + .paddr = MPC85xx_MIIM_OFFSET, +}; static struct gianfar_platform_data mpc85xx_tsec1_pdata = { .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | FSL_GIANFAR_DEV_HAS_MULTI_INTR, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_tsec2_pdata = { .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | FSL_GIANFAR_DEV_HAS_MULTI_INTR, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_etsec1_pdata = { @@ -46,7 +47,6 @@ static struct gianfar_platform_data mpc85xx_etsec1_pdata = { FSL_GIANFAR_DEV_HAS_MULTI_INTR | FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_etsec2_pdata = { @@ -55,7 +55,6 @@ static struct gianfar_platform_data mpc85xx_etsec2_pdata = { FSL_GIANFAR_DEV_HAS_MULTI_INTR | FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_etsec3_pdata = { @@ -64,7 +63,6 @@ static struct gianfar_platform_data mpc85xx_etsec3_pdata = { FSL_GIANFAR_DEV_HAS_MULTI_INTR | FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_etsec4_pdata = { @@ -73,11 +71,10 @@ static struct gianfar_platform_data mpc85xx_etsec4_pdata = { FSL_GIANFAR_DEV_HAS_MULTI_INTR | FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, - .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; static struct gianfar_platform_data mpc85xx_fec_pdata = { - .phy_reg_addr = MPC85xx_ENET1_OFFSET, + .device_flags = 0, }; static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = { @@ -719,6 +716,12 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, }, + [MPC85xx_MDIO] = { + .name = "fsl-gianfar_mdio", + .id = 0, + .dev.platform_data = &mpc85xx_mdio_pdata, + .num_resources = 0, + }, }; static int __init mach_mpc85xx_fixup(struct platform_device *pdev) diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c index 6e3184ab354f..cb68d8c58348 100644 --- a/arch/ppc/syslib/mpc85xx_sys.c +++ b/arch/ppc/syslib/mpc85xx_sys.c @@ -24,19 +24,19 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "8540", .mask = 0xFFFF0000, .value = 0x80300000, - .num_devices = 10, + .num_devices = 11, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_FEC, MPC85xx_IIC1, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, - MPC85xx_PERFMON, MPC85xx_DUART, + MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_MDIO, }, }, { .ppc_sys_name = "8560", .mask = 0xFFFF0000, .value = 0x80700000, - .num_devices = 19, + .num_devices = 20, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1, @@ -45,14 +45,14 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1, MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3, - MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, + MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, MPC85xx_MDIO, }, }, { .ppc_sys_name = "8541", .mask = 0xFFFF0000, .value = 0x80720000, - .num_devices = 13, + .num_devices = 14, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1, @@ -60,13 +60,14 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8541E", .mask = 0xFFFF0000, .value = 0x807A0000, - .num_devices = 14, + .num_devices = 15, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1, @@ -74,13 +75,14 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8555", .mask = 0xFFFF0000, .value = 0x80710000, - .num_devices = 19, + .num_devices = 20, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1, @@ -91,13 +93,14 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, MPC85xx_CPM_USB, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8555E", .mask = 0xFFFF0000, .value = 0x80790000, - .num_devices = 20, + .num_devices = 21, .device_list = (enum ppc_sys_devices[]) { MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1, @@ -108,6 +111,7 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, MPC85xx_CPM_USB, + MPC85xx_MDIO, }, }, /* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */ @@ -115,104 +119,112 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "8548E", .mask = 0xFFFF00F0, .value = 0x80390010, - .num_devices = 13, + .num_devices = 14, .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8548", .mask = 0xFFFF00F0, .value = 0x80310010, - .num_devices = 12, - .device_list = (enum ppc_sys_devices[]) - { - MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, - MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, - MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, - MPC85xx_PERFMON, MPC85xx_DUART, - }, - }, - { - .ppc_sys_name = "8547E", - .mask = 0xFFFF00F0, - .value = 0x80390010, .num_devices = 13, .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, + MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + MPC85xx_MDIO, + }, + }, + { + .ppc_sys_name = "8547E", + .mask = 0xFFFF00F0, + .value = 0x80390010, + .num_devices = 14, + .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8547", .mask = 0xFFFF00F0, .value = 0x80310010, - .num_devices = 12, + .num_devices = 13, .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8545E", .mask = 0xFFFF00F0, .value = 0x80390010, - .num_devices = 11, + .num_devices = 12, .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8545", .mask = 0xFFFF00F0, .value = 0x80310010, - .num_devices = 10, - .device_list = (enum ppc_sys_devices[]) - { - MPC85xx_eTSEC1, MPC85xx_eTSEC2, - MPC85xx_IIC1, MPC85xx_IIC2, - MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, - MPC85xx_PERFMON, MPC85xx_DUART, - }, - }, - { - .ppc_sys_name = "8543E", - .mask = 0xFFFF00F0, - .value = 0x803A0010, .num_devices = 11, .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, + MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + MPC85xx_MDIO, + }, + }, + { + .ppc_sys_name = "8543E", + .mask = 0xFFFF00F0, + .value = 0x803A0010, + .num_devices = 12, + .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + MPC85xx_MDIO, }, }, { .ppc_sys_name = "8543", .mask = 0xFFFF00F0, .value = 0x80320010, - .num_devices = 10, + .num_devices = 11, .device_list = (enum ppc_sys_devices[]) { MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_IIC1, MPC85xx_IIC2, MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, MPC85xx_PERFMON, MPC85xx_DUART, + MPC85xx_MDIO, }, }, { /* default match */ diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h index 516984ee14b5..d98db980cd49 100644 --- a/include/asm-ppc/mpc85xx.h +++ b/include/asm-ppc/mpc85xx.h @@ -67,6 +67,8 @@ extern unsigned char __res[]; #define MPC85xx_DMA3_SIZE (0x00080) #define MPC85xx_ENET1_OFFSET (0x24000) #define MPC85xx_ENET1_SIZE (0x01000) +#define MPC85xx_MIIM_OFFSET (0x24520) +#define MPC85xx_MIIM_SIZE (0x00018) #define MPC85xx_ENET2_OFFSET (0x25000) #define MPC85xx_ENET2_SIZE (0x01000) #define MPC85xx_ENET3_OFFSET (0x26000) @@ -132,6 +134,7 @@ enum ppc_sys_devices { MPC85xx_eTSEC3, MPC85xx_eTSEC4, MPC85xx_IIC2, + MPC85xx_MDIO, }; /* Internal interrupts are all Level Sensitive, and Positive Polarity */ diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 70f54af87b9f..114d5d59f695 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -47,16 +47,21 @@ struct gianfar_platform_data { /* device specific information */ u32 device_flags; - u32 phy_reg_addr; /* board specific information */ u32 board_flags; - u32 phy_flags; - u32 phyid; - u32 interruptPHY; + const char *bus_id; u8 mac_addr[6]; }; +struct gianfar_mdio_data { + /* device specific information */ + u32 paddr; + + /* board specific information */ + int irq[32]; +}; + /* Flags related to gianfar device features */ #define FSL_GIANFAR_DEV_HAS_GIGABIT 0x00000001 #define FSL_GIANFAR_DEV_HAS_COALESCE 0x00000002 From 1461b4ea2bcdfb2a386ad3f3095eeb9d73e4bf55 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Fri, 28 Oct 2005 17:46:28 -0700 Subject: [PATCH 0936/1940] [PATCH] ppc32: ppc_sys fixes for 8xx and 82xx This patch fixes a numbers of issues regarding to that both 8xx and 82xx began to use ppc_sys model: - Platform is now identified by default deviceless SOC, if no BOARD_CHIP_NAME is specified in the bard-specific header. For the list of supported names refer to (arch/ppc/syslib/) mpc8xx_sys.c and mpc82xx_sys.c for 8xx and 82xx respectively. - Fixed a bug in identification by name - if the name was not found, it returned -1 instead of default deviceless ppc_spec. - fixed devices amount in the 8xx platform system descriptions Signed-off-by: Vitaly Bordug Signed-off-by: Marcelo Tosatti Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/platforms/fads.h | 2 ++ arch/ppc/platforms/mpc885ads.h | 2 ++ arch/ppc/syslib/m8260_setup.c | 4 ++++ arch/ppc/syslib/m8xx_setup.c | 2 ++ arch/ppc/syslib/mpc8xx_sys.c | 4 ++-- arch/ppc/syslib/ppc_sys.c | 3 +++ include/asm-ppc/cpm2.h | 3 +++ include/asm-ppc/mpc8260.h | 4 ++++ include/asm-ppc/mpc8xx.h | 4 ++++ 9 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h index b60c56450b67..a48fb8d723e4 100644 --- a/arch/ppc/platforms/fads.h +++ b/arch/ppc/platforms/fads.h @@ -25,6 +25,8 @@ #if defined(CONFIG_MPC86XADS) +#define BOARD_CHIP_NAME "MPC86X" + /* U-Boot maps BCSR to 0xff080000 */ #define BCSR_ADDR ((uint)0xff080000) diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h index eb386635b0fd..a80b7d116b49 100644 --- a/arch/ppc/platforms/mpc885ads.h +++ b/arch/ppc/platforms/mpc885ads.h @@ -88,5 +88,7 @@ #define SICR_ENET_MASK ((uint)0x00ff0000) #define SICR_ENET_CLKRT ((uint)0x002c0000) +#define BOARD_CHIP_NAME "MPC885" + #endif /* __ASM_MPC885ADS_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c index 8f80a42dfdb7..76a2aa4ce65e 100644 --- a/arch/ppc/syslib/m8260_setup.c +++ b/arch/ppc/syslib/m8260_setup.c @@ -62,6 +62,10 @@ m8260_setup_arch(void) if (initrd_start) ROOT_DEV = Root_RAM0; #endif + + identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME, + in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET)); + m82xx_board_setup(); } diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index a192719929d3..97ffbc70574f 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c @@ -399,6 +399,8 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, strcpy(cmd_line, (char *)(r6+KERNELBASE)); } + identify_ppc_sys_by_name(BOARD_CHIP_NAME); + ppc_md.setup_arch = m8xx_setup_arch; ppc_md.show_percpuinfo = m8xx_show_percpuinfo; ppc_md.init_IRQ = m8xx_init_IRQ; diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c index a532ccc861c0..3cc27d29e3af 100644 --- a/arch/ppc/syslib/mpc8xx_sys.c +++ b/arch/ppc/syslib/mpc8xx_sys.c @@ -24,7 +24,7 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "MPC86X", .mask = 0xFFFFFFFF, .value = 0x00000000, - .num_devices = 2, + .num_devices = 7, .device_list = (enum ppc_sys_devices[]) { MPC8xx_CPM_FEC1, @@ -40,7 +40,7 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "MPC885", .mask = 0xFFFFFFFF, .value = 0x00000000, - .num_devices = 3, + .num_devices = 8, .device_list = (enum ppc_sys_devices[]) { MPC8xx_CPM_FEC1, diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c index 52ba0c68078d..62ee86e80711 100644 --- a/arch/ppc/syslib/ppc_sys.c +++ b/arch/ppc/syslib/ppc_sys.c @@ -69,6 +69,9 @@ static int __init find_chip_by_name_and_id(char *name, u32 id) matched[j++] = i; i++; } + + ret = i; + if (j != 0) { for (i = 0; i < j; i++) { if ((ppc_sys_specs[matched[i]].mask & id) == diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index 9483d4bfacf7..43d2ebbc7748 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h @@ -1087,6 +1087,9 @@ typedef struct im_idma { #define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */ #define SCCR_PCIDF_SHIFT 3 +#ifndef CPM_IMMR_OFFSET +#define CPM_IMMR_OFFSET 0x101a8 +#endif #endif /* __CPM2__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h index 9694eca16e92..321452695039 100644 --- a/include/asm-ppc/mpc8260.h +++ b/include/asm-ppc/mpc8260.h @@ -92,6 +92,10 @@ enum ppc_sys_devices { extern unsigned char __res[]; #endif +#ifndef BOARD_CHIP_NAME +#define BOARD_CHIP_NAME "" +#endif + #endif /* CONFIG_8260 */ #endif /* !__ASM_PPC_MPC8260_H__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index 208a2e11daee..46f159cf589e 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -113,6 +113,10 @@ enum ppc_sys_devices { MPC8xx_CPM_USB, }; +#ifndef BOARD_CHIP_NAME +#define BOARD_CHIP_NAME "" +#endif + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_8xx */ #endif /* __CONFIG_8xx_DEFS */ From b1529871f4270d10a0d1a9c998be162f0123d8f1 Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Fri, 28 Oct 2005 17:46:30 -0700 Subject: [PATCH 0937/1940] [PATCH] mv643xx_eth_showsram: Added information message when using the SRAM Added information message when using the SRAM in mv643xx_eth_probe() Signed-off-by: Nicolas DET Signed-off-by: Sven Luther Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/net/mv643xx_eth.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 25c9a99c377b..8fbba21d975b 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1533,6 +1533,9 @@ static int mv643xx_eth_probe(struct device *ddev) printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name); #endif + if (mp->tx_sram_size > 0) + printk(KERN_NOTICE "%s: Using SRAM\n", dev->name); + return 0; out: From 9fcc2e8a752f7d3d889114221b67c459557823e9 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Thu, 27 Oct 2005 15:10:01 -0700 Subject: [PATCH 0938/1940] [IPV4]: Fix issue reported by Coverity in ipv4/fib_frontend.c fib_del_ifaddr() dereferences ifa->ifa_dev, so the code already assumes that ifa->ifa_dev is non-NULL, the check is unnecessary. Signed-off-by: Jayachandran C. Signed-off-by: Arnaldo Carvalho de Melo --- net/ipv4/fib_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index e61bc7177eb1..990633c09dfe 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -591,7 +591,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, break; case NETDEV_DOWN: fib_del_ifaddr(ifa); - if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) { + if (ifa->ifa_dev->ifa_list == NULL) { /* Last address was deleted from this interface. Disable IP. */ From 27ac801a2e513708e2da648722326349514976d5 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:35 -0700 Subject: [PATCH 0939/1940] [PATCH] ppc64 boot: remove include from lib/zlib_inflate/inflate.c There is no need to include module.h in inflate.c Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- lib/zlib_inflate/inflate.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c index 3d94cb90c1d3..31b9e9054bf7 100644 --- a/lib/zlib_inflate/inflate.c +++ b/lib/zlib_inflate/inflate.c @@ -3,7 +3,6 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -#include #include #include "infblock.h" #include "infutil.h" From 146c98782b57531ce6ba89dfa9d3771c0fd0a94d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:37 -0700 Subject: [PATCH 0940/1940] [PATCH] ppc64 boot: remove include from include/linux/zutil.h zutil.h does not need errno.h Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- include/linux/zutil.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/zutil.h b/include/linux/zutil.h index fdfd5ed41ec4..ee0c59cf2136 100644 --- a/include/linux/zutil.h +++ b/include/linux/zutil.h @@ -15,7 +15,6 @@ #include #include -#include #include typedef unsigned char uch; From 8afe31c9eb92389f091a40def9650278ca66befd Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:37 -0700 Subject: [PATCH 0941/1940] [PATCH] ppc64 boot: missing include for size_t string.h needs definition of size_t, but not the one from linux/include Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/string.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ppc64/boot/string.h b/arch/ppc64/boot/string.h index 9289258bcbd6..9fdff1cc0d70 100644 --- a/arch/ppc64/boot/string.h +++ b/arch/ppc64/boot/string.h @@ -1,5 +1,6 @@ #ifndef _PPC_BOOT_STRING_H_ #define _PPC_BOOT_STRING_H_ +#include extern char *strcpy(char *dest, const char *src); extern char *strncpy(char *dest, const char *src, size_t n); From 7054036fc526b741ba90ff1d077ac900362f30ed Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:38 -0700 Subject: [PATCH 0942/1940] [PATCH] ppc64 boot: remove zlib Switch ppc64 to the in-kernel zlib, it has less bugs than the current one. The code in arch/ppc64/boot is compiled as 32bit, so it can not use the includes from include/asm. Copy all zlib related header files and convert them with sed. Reduce the scratch size to 47k, check possible changes at runtime. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 33 +- arch/ppc64/boot/main.c | 82 +- arch/ppc64/boot/zlib.c | 2195 -------------------------------------- arch/ppc64/boot/zlib.h | 432 -------- 4 files changed, 44 insertions(+), 2698 deletions(-) delete mode 100644 arch/ppc64/boot/zlib.c delete mode 100644 arch/ppc64/boot/zlib.h diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 33fdc8710891..3c78d72a84bb 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -27,10 +27,41 @@ BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds OBJCOPYFLAGS := contents,alloc,load,readonly,data -src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c +zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h +zliblinuxheader := zlib.h zconf.h zutil.h + +$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) +#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) + +src-boot := crt0.S string.S prom.c main.c imagesize.c div64.S +src-boot += $(zlib) src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) +BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) + +quiet_cmd_copy_zlib = COPY $@ + cmd_copy_zlib = sed "s@__attribute_used__@@;s@]\+\).*@\"\1\"@" $< > $@ + +quiet_cmd_copy_zlibheader = COPY $@ + cmd_copy_zlibheader = sed "s@]\+\).*@\"\1\"@" $< > $@ +# stddef.h for NULL +quiet_cmd_copy_zliblinuxheader = COPY $@ + cmd_copy_zliblinuxheader = sed "s@@\"string.h\"@;s@@@;s@]\+\).*@\"\1\"@" $< > $@ + +$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlib) + +$(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlibheader) + +$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% + $(call cmd,copy_zliblinuxheader) + +clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) + + quiet_cmd_bootcc = BOOTCC $@ cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index f7ec19a2d0b0..0b95ccfb143c 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -26,12 +26,6 @@ extern void flush_cache(void *, unsigned long); #define RAM_END (512<<20) // Fixme: use OF */ #define ONE_MB 0x100000 -static char *avail_ram; -static char *begin_avail, *end_avail; -static char *avail_high; -static unsigned int heap_use; -static unsigned int heap_max; - extern char _start[]; extern char _end[]; extern char _vmlinux_start[]; @@ -50,7 +44,8 @@ static struct addr_range vmlinux = {0, 0, 0}; static struct addr_range vmlinuz = {0, 0, 0}; static struct addr_range initrd = {0, 0, 0}; -static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ +static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ + typedef void (*kernel_entry_t)( unsigned long, unsigned long, @@ -161,17 +156,12 @@ void start(unsigned long a1, unsigned long a2, void *promptr) /* Eventually gunzip the kernel */ if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { int len; - avail_ram = scratch; - begin_avail = avail_high = avail_ram; - end_avail = scratch + sizeof(scratch); printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); len = vmlinuz.size; gunzip((void *)vmlinux.addr, vmlinux.size, (unsigned char *)vmlinuz.addr, &len); printf("done 0x%lx bytes\n\r", len); - printf("0x%x bytes of heap consumed, max in use 0x%x\n\r", - (unsigned)(avail_high - begin_avail), heap_max); } else { memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); } @@ -225,64 +215,12 @@ void start(unsigned long a1, unsigned long a2, void *promptr) exit(); } -struct memchunk { - unsigned int size; - unsigned int pad; - struct memchunk *next; -}; - -static struct memchunk *freechunks; - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p; - struct memchunk **mpp, *mp; - - size *= items; - size = _ALIGN(size, sizeof(struct memchunk)); - heap_use += size; - if (heap_use > heap_max) - heap_max = heap_use; - for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { - if (mp->size == size) { - *mpp = mp->next; - return mp; - } - } - p = avail_ram; - avail_ram += size; - if (avail_ram > avail_high) - avail_high = avail_ram; - if (avail_ram > end_avail) { - printf("oops... out of memory\n\r"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ - struct memchunk *mp = addr; - - nb = _ALIGN(nb, sizeof(struct memchunk)); - heap_use -= nb; - if (avail_ram == addr + nb) { - avail_ram = addr; - return; - } - mp->size = nb; - mp->next = freechunks; - freechunks = mp; -} - #define HEAD_CRC 2 #define EXTRA_FIELD 4 #define ORIG_NAME 8 #define COMMENT 0x10 #define RESERVED 0xe0 -#define DEFLATED 8 - static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) { z_stream s; @@ -291,7 +229,7 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) /* skip header */ i = 10; flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { printf("bad gzipped data\n\r"); exit(); } @@ -310,9 +248,13 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) exit(); } - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); + if (zlib_inflate_workspacesize() > sizeof(scratch)) { + printf("gunzip needs more mem\n"); + exit(); + } + memset(&s, 0, sizeof(s)); + s.workspace = scratch; + r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { printf("inflateInit2 returned %d\n\r", r); exit(); @@ -321,12 +263,12 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); + r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { printf("inflate returned %d msg: %s\n\r", r, s.msg); exit(); } *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); + zlib_inflateEnd(&s); } diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c deleted file mode 100644 index 0d910cd2079d..000000000000 --- a/arch/ppc64/boot/zlib.c +++ /dev/null @@ -1,2195 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - - * - * - */ - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -extern void *memcpy(void *, const void *, unsigned long); -#define zmemcpy memcpy - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include "stdio.h" -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset( - z_stream *z -) -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd( - z_stream *z -) -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2( - z_stream *z, - int w -) -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit( - z_stream *z -) -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate( - z_stream *z, - int f -) -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp( - z_stream *z -) -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync( - z_stream *z -) -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset( - inflate_blocks_statef *s, - z_stream *z, - uLongf *c -) -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new( - z_stream *z, - check_func c, - uInt w -) -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks( - inflate_blocks_statef *s, - z_stream *z, - int r -) -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free( - inflate_blocks_statef *s, - z_stream *z, - uLongf *c -) -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory( - inflate_blocks_statef *s, - z_stream *z -) -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush( - inflate_blocks_statef *s -) -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build( - uIntf *b, /* code lengths in bits (all assumed <= BMAX) */ - uInt n, /* number of codes (assumed <= N_MAX) */ - uInt s, /* number of simple-valued codes (0..s-1) */ - uIntf *d, /* list of base values for non-simple codes */ - uIntf *e, /* list of extra bits for non-simple codes */ - inflate_huft * FAR *t, /* result: starting table */ - uIntf *m, /* maximum lookup bits, returns actual */ - z_stream *zs /* for zalloc function */ -) -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_DATA_ERROR; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits( - uIntf *c, /* 19 code lengths */ - uIntf *bb, /* bits tree desired/actual depth */ - inflate_huft * FAR *tb, /* bits tree result */ - z_stream *z /* for zfree function */ -) -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic( - uInt nl, /* number of literal/length codes */ - uInt nd, /* number of distance codes */ - uIntf *c, /* that many (total) code lengths */ - uIntf *bl, /* literal desired/actual bit depth */ - uIntf *bd, /* distance desired/actual bit depth */ - inflate_huft * FAR *tl, /* literal/length tree result */ - inflate_huft * FAR *td, /* distance tree result */ - z_stream *z /* for zfree function */ -) -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc( - voidpf q, /* opaque pointer (not used) */ - uInt n, /* number of items */ - uInt s /* size of item */ -) -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree( - voidpf q, - voidpf p, - uInt n -) -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed( - uIntf *bl, /* literal desired/actual bit depth */ - uIntf *bd, /* distance desired/actual bit depth */ - inflate_huft * FAR *tl, /* literal/length tree result */ - inflate_huft * FAR *td /* distance tree result */ -) -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free( - inflate_huft *t, /* table to free */ - z_stream *z /* for zfree function */ -) -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new( - uInt bl, - uInt bd, - inflate_huft *tl, - inflate_huft *td, - z_stream *z -) -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes( - inflate_blocks_statef *s, - z_stream *z, - int r -) -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free( - inflate_codes_statef *c, - z_stream *z -) -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush( - inflate_blocks_statef *s, - z_stream *z, - int r -) -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast( - uInt bl, - uInt bd, - inflate_huft *tl, - inflate_huft *td, - inflate_blocks_statef *s, - z_stream *z -) -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32( - uLong adler, - Bytef *buf, - uInt len -) -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff --git a/arch/ppc64/boot/zlib.h b/arch/ppc64/boot/zlib.h deleted file mode 100644 index f0b996c6864f..000000000000 --- a/arch/ppc64/boot/zlib.h +++ /dev/null @@ -1,432 +0,0 @@ -/* */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 960122== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1< Date: Fri, 28 Oct 2005 17:46:40 -0700 Subject: [PATCH 0943/1940] [PATCH] ppc64 boot: remove need for imagesize.c Compute the vmlinux size at runtime. Use Z_FULL_FLUSH instead of Z_FINISH, to extract only the ELF header and ELF program header. ->p_memsz is the required memory range for the executable, including bss ->p_filesz is the size of .text, .data and other runtime sections These values must be used for the claim call. All additional memory needed by the kernel is claimed in prom_init, remove the extra Mb. Pass the full memsize as target area to gunzip, otherwise not everything will be uncompressed. flush_cache has to flush all runtime sections, do not reduce the memrange by the ->p_offset value because its just that: an offset. Remove the Makefile code to produce an imagesize.c, its not needed anymore. Remove all FORCE flags, to not rebuild the zImage if vmlinux was not changed. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 32 ++++++---------- arch/ppc64/boot/main.c | 80 ++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 3c78d72a84bb..d79dfd60d8f8 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -34,7 +34,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) -src-boot := crt0.S string.S prom.c main.c imagesize.c div64.S +src-boot := crt0.S string.S prom.c main.c div64.S src-boot += $(zlib) src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) @@ -87,7 +87,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) hostprogs-y := addnote addRamDisk -targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \ +targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ @@ -100,9 +100,9 @@ quiet_cmd_ramdisk = RAMDISK $@ quiet_cmd_stripvm = STRIP $@ cmd_stripvm = $(STRIP) -s $< -o $@ -vmlinux.strip: vmlinux FORCE +vmlinux.strip: vmlinux $(call if_changed,stripvm) -$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE +$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz $(call if_changed,ramdisk) quiet_cmd_addsection = ADDSEC $@ @@ -110,48 +110,38 @@ quiet_cmd_addsection = ADDSEC $@ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) -quiet_cmd_imagesize = GENSIZE $@ - cmd_imagesize = ls -l vmlinux.strip | \ - awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \ - > $(obj)/imagesize.c && \ - $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ - awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c - quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(obj)/addnote $@ -$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE +$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % $(call if_changed,gzip) $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz cp -f $(obj)/ramdisk.image.gz $@ -$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE +$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz @touch $@ -$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE +$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c $(call if_changed_dep,bootcc) $(call cmd,addsection) $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE +$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(call cmd,bootld,$(obj-boot)) $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE +$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(call cmd,bootld,$(obj-boot)) -$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE +$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote @cp -f $< $@ $(call if_changed,addnote) -$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote @cp -f $< $@ $(call if_changed,addnote) -$(obj)/imagesize.c: vmlinux.strip - $(call cmd,imagesize) - install: $(CONFIGURE) $(BOOTIMAGE) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 0b95ccfb143c..7485dcbf80bc 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -32,8 +32,6 @@ extern char _vmlinux_start[]; extern char _vmlinux_end[]; extern char _initrd_start[]; extern char _initrd_end[]; -extern unsigned long vmlinux_filesize; -extern unsigned long vmlinux_memsize; struct addr_range { unsigned long addr; @@ -45,6 +43,7 @@ static struct addr_range vmlinuz = {0, 0, 0}; static struct addr_range initrd = {0, 0, 0}; static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ +static char elfheader[256]; typedef void (*kernel_entry_t)( unsigned long, @@ -78,6 +77,7 @@ static unsigned long try_claim(unsigned long size) void start(unsigned long a1, unsigned long a2, void *promptr) { unsigned long i; + int len; kernel_entry_t kernel_entry; Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; @@ -113,25 +113,45 @@ void start(unsigned long a1, unsigned long a2, void *promptr) claim_base = PROG_START; #endif - /* - * Now we try to claim some memory for the kernel itself - * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what - * our Makefile stuffs in is an image containing all sort of junk including - * an ELF header. We need to do some calculations here to find the right - * size... In practice we add 1Mb, that is enough, but we should really - * consider fixing the Makefile to put a _raw_ kernel in there ! - */ - vmlinux_memsize += ONE_MB; - printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); - vmlinux.addr = try_claim(vmlinux_memsize); + vmlinuz.addr = (unsigned long)_vmlinux_start; + vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); + + /* gunzip the ELF header of the kernel */ + if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { + len = vmlinuz.size; + gunzip(elfheader, sizeof(elfheader), + (unsigned char *)vmlinuz.addr, &len); + } else + memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader)); + + elf64 = (Elf64_Ehdr *)elfheader; + if ( elf64->e_ident[EI_MAG0] != ELFMAG0 || + elf64->e_ident[EI_MAG1] != ELFMAG1 || + elf64->e_ident[EI_MAG2] != ELFMAG2 || + elf64->e_ident[EI_MAG3] != ELFMAG3 || + elf64->e_ident[EI_CLASS] != ELFCLASS64 || + elf64->e_ident[EI_DATA] != ELFDATA2MSB || + elf64->e_type != ET_EXEC || + elf64->e_machine != EM_PPC64 ) + { + printf("Error: not a valid PPC64 ELF file!\n\r"); + exit(); + } + + elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + + (unsigned long)elf64->e_phoff); + for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) { + if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) + break; + } + vmlinux.size = (unsigned long)elf64ph->p_filesz; + vmlinux.memsize = (unsigned long)elf64ph->p_memsz; + printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); + vmlinux.addr = try_claim(vmlinux.memsize); if (vmlinux.addr == 0) { printf("Can't allocate memory for kernel image !\n\r"); exit(); } - vmlinuz.addr = (unsigned long)_vmlinux_start; - vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); - vmlinux.size = PAGE_ALIGN(vmlinux_filesize); - vmlinux.memsize = vmlinux_memsize; /* * Now we try to claim memory for the initrd (and copy it there) @@ -155,11 +175,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) /* Eventually gunzip the kernel */ if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { - int len; printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); len = vmlinuz.size; - gunzip((void *)vmlinux.addr, vmlinux.size, + gunzip((void *)vmlinux.addr, vmlinux.memsize, (unsigned char *)vmlinuz.addr, &len); printf("done 0x%lx bytes\n\r", len); } else { @@ -167,32 +186,11 @@ void start(unsigned long a1, unsigned long a2, void *promptr) } /* Skip over the ELF header */ - elf64 = (Elf64_Ehdr *)vmlinux.addr; - if ( elf64->e_ident[EI_MAG0] != ELFMAG0 || - elf64->e_ident[EI_MAG1] != ELFMAG1 || - elf64->e_ident[EI_MAG2] != ELFMAG2 || - elf64->e_ident[EI_MAG3] != ELFMAG3 || - elf64->e_ident[EI_CLASS] != ELFCLASS64 || - elf64->e_ident[EI_DATA] != ELFDATA2MSB || - elf64->e_type != ET_EXEC || - elf64->e_machine != EM_PPC64 ) - { - printf("Error: not a valid PPC64 ELF file!\n\r"); - exit(); - } - - elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + - (unsigned long)elf64->e_phoff); - for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) { - if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) - break; - } #ifdef DEBUG printf("... skipping 0x%lx bytes of ELF header\n\r", (unsigned long)elf64ph->p_offset); #endif vmlinux.addr += (unsigned long)elf64ph->p_offset; - vmlinux.size -= (unsigned long)elf64ph->p_offset; flush_cache((void *)vmlinux.addr, vmlinux.size); @@ -263,7 +261,7 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r = zlib_inflate(&s, Z_FINISH); + r = zlib_inflate(&s, Z_FULL_FLUSH); if (r != Z_OK && r != Z_STREAM_END) { printf("inflate returned %d msg: %s\n\r", r, s.msg); exit(); From 6bcc20b5ade6c8e9d9a0767090c65024047d91c4 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:41 -0700 Subject: [PATCH 0944/1940] [PATCH] ppc64 boot: move gunzip function before use Move the gunzip function up. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 115 ++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 7485dcbf80bc..d039c47f8e5a 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -17,7 +17,6 @@ #include "prom.h" #include "zlib.h" -static void gunzip(void *, int, unsigned char *, int *); extern void flush_cache(void *, unsigned long); @@ -56,6 +55,63 @@ typedef void (*kernel_entry_t)( unsigned long, static unsigned long claim_base; +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n\r"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n\r"); + exit(); + } + + if (zlib_inflate_workspacesize() > sizeof(scratch)) { + printf("gunzip needs more mem\n"); + exit(); + } + memset(&s, 0, sizeof(s)); + s.workspace = scratch; + r = zlib_inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n\r", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = zlib_inflate(&s, Z_FULL_FLUSH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n\r", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + zlib_inflateEnd(&s); +} + static unsigned long try_claim(unsigned long size) { unsigned long addr = 0; @@ -213,60 +269,3 @@ void start(unsigned long a1, unsigned long a2, void *promptr) exit(); } -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n\r"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n\r"); - exit(); - } - - if (zlib_inflate_workspacesize() > sizeof(scratch)) { - printf("gunzip needs more mem\n"); - exit(); - } - memset(&s, 0, sizeof(s)); - s.workspace = scratch; - r = zlib_inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n\r", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = zlib_inflate(&s, Z_FULL_FLUSH); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d msg: %s\n\r", r, s.msg); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - zlib_inflateEnd(&s); -} - From 83097c5d543894864a564cde6c27d4e523d67674 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:43 -0700 Subject: [PATCH 0945/1940] [PATCH] ppc64 boot: bootfiles depend on linker script bootfiles must be relinked if linker script changes Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d79dfd60d8f8..f8f35999e1a6 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -127,11 +127,11 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c $(call cmd,addsection) $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) +$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds $(call cmd,bootld,$(obj-boot)) $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) +$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds $(call cmd,bootld,$(obj-boot)) $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote From 06cf26beffc54bb43aebbefa60f84e0dffde3141 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:44 -0700 Subject: [PATCH 0946/1940] [PATCH] ppc64 boot: cleanup linker script Remove userland related stuff from ld.script, they are not required for zImage use wildcards for some sections. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/zImage.lds | 59 ++++---------------------------------- 1 file changed, 5 insertions(+), 54 deletions(-) diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds index 8fe5e7071f54..fb465a4d89b5 100644 --- a/arch/ppc64/boot/zImage.lds +++ b/arch/ppc64/boot/zImage.lds @@ -1,62 +1,19 @@ OUTPUT_ARCH(powerpc:common) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); -/* Do we need any of these for elf? - __DYNAMIC = 0; */ SECTIONS { - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .plt : { *(.plt) } .text : { *(.text) *(.fixup) - *(.got1) } - . = ALIGN(4096); _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(.rodata) - *(.rodata1) - } - .kstrtab : { *(.kstrtab) } - __vermagic : { *(__vermagic) } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - /* Read-write section, merged into data segment: */ . = ALIGN(4096); .data : { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS + *(.rodata*) + *(.data*) + *(.sdata*) + *(.got*) } . = ALIGN(4096); @@ -71,20 +28,14 @@ SECTIONS . = ALIGN(4096); _edata = .; - PROVIDE (edata = .); - - .fixup : { *(.fixup) } . = ALIGN(4096); __bss_start = .; .bss : { - *(.sbss) *(.scommon) - *(.dynbss) + *(.sbss) *(.bss) - *(COMMON) } . = ALIGN(4096); _end = . ; - PROVIDE (end = .); } From 9b0cbe97566dd7123eee0462d91703434fe61090 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:45 -0700 Subject: [PATCH 0947/1940] [PATCH] ppc64 boot: use memset to clear bss Use memset to clear bss, instead of own version. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/crt0.S | 19 ------------------- arch/ppc64/boot/main.c | 3 +++ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S index 3861e7f9cf19..da6618a865c9 100644 --- a/arch/ppc64/boot/crt0.S +++ b/arch/ppc64/boot/crt0.S @@ -25,24 +25,5 @@ _start: sync isync - ## Clear out the BSS as per ANSI C requirements - - lis r7,_end@ha - addi r7,r7,_end@l # r7 = &_end - lis r8,__bss_start@ha # - addi r8,r8,__bss_start@l # r8 = &_bss_start - - ## Determine how large an area, in number of words, to clear - - subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 - addi r7,r7,3 # r7 += 3 - srwi. r7,r7,2 # r7 = size in words. - beq 3f # If the size is zero, don't bother - addi r8,r8,-4 # r8 -= 4 - mtctr r7 # SPRN_CTR = number of words to clear - li r0,0 # r0 = 0 -2: stwu r0,4(r8) # Clear out a word - bdnz 2b # Keep clearing until done -3: b start diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index d039c47f8e5a..c2c1f3309113 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -26,6 +26,7 @@ extern void flush_cache(void *, unsigned long); #define ONE_MB 0x100000 extern char _start[]; +extern char __bss_start[]; extern char _end[]; extern char _vmlinux_start[]; extern char _vmlinux_end[]; @@ -138,6 +139,8 @@ void start(unsigned long a1, unsigned long a2, void *promptr) Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; + memset(__bss_start, 0, _end - __bss_start); + prom = (int (*)(void *)) promptr; chosen_handle = finddevice("/chosen"); if (chosen_handle == (void *) -1) From 844ae3a0d1638753802770cde881dff0e0704551 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:46 -0700 Subject: [PATCH 0948/1940] [PATCH] ppc64 boot: fix typo in asm comments Update comment in memcpy, r7 contains the byte count. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/string.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S index 7ade87ae7718..b1eeaed7db17 100644 --- a/arch/ppc64/boot/string.S +++ b/arch/ppc64/boot/string.S @@ -104,7 +104,7 @@ memmove: .globl memcpy memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ addi r6,r3,-4 addi r4,r4,-4 beq 2f /* if less than 8 bytes to do */ @@ -146,7 +146,7 @@ memcpy: .globl backwards_memcpy backwards_memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ add r6,r3,r5 add r4,r4,r5 beq 2f From afbe8c4bb0155f533d6e57edd269c93e2f23c2fa Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:47 -0700 Subject: [PATCH 0949/1940] [PATCH] ppc64 boot: remove global initializers No need to initialize global variables. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index c2c1f3309113..3304ed34c44b 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -38,9 +38,9 @@ struct addr_range { unsigned long size; unsigned long memsize; }; -static struct addr_range vmlinux = {0, 0, 0}; -static struct addr_range vmlinuz = {0, 0, 0}; -static struct addr_range initrd = {0, 0, 0}; +static struct addr_range vmlinux; +static struct addr_range vmlinuz; +static struct addr_range initrd; static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ static char elfheader[256]; From a4497235f00d811943831c9d76995d36c4ffab2d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:48 -0700 Subject: [PATCH 0950/1940] [PATCH] ppc64 boot: make the zImage relocateable Make the zImage relocateable. So yaboot could just load and run any ELF binary, without worrying about its load address. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 2 +- arch/ppc64/boot/crt0.S | 29 +++++++++++++++++++++++++++++ arch/ppc64/boot/zImage.lds | 4 +++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index f8f35999e1a6..9e19351f3dfa 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -22,7 +22,7 @@ HOSTCC := gcc -BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) +BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds OBJCOPYFLAGS := contents,alloc,load,readonly,data diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S index da6618a865c9..5788a453a7a2 100644 --- a/arch/ppc64/boot/crt0.S +++ b/arch/ppc64/boot/crt0.S @@ -14,9 +14,38 @@ .text .globl _start _start: + bl reloc_offset + +reloc_offset: + mflr r0 + lis r9,reloc_offset@ha + addi r9,r9,reloc_offset@l + subf. r0,r9,r0 + beq clear_caches + +reloc_got2: + lis r9,__got2_start@ha + addi r9,r9,__got2_start@l + lis r8,__got2_end@ha + addi r8,r8,__got2_end@l + subf. r8,r9,r8 + beq clear_caches + srwi. r8,r8,2 + mtctr r8 + add r9,r0,r9 +reloc_got2_loop: + lwz r8,0(r9) + add r8,r8,r0 + stw r8,0(r9) + addi r9,r9,4 + bdnz reloc_got2_loop + +clear_caches: lis r9,_start@h + add r9,r0,r9 lis r8,_etext@ha addi r8,r8,_etext@l + add r8,r0,r8 1: dcbf r0,r9 icbi r0,r9 addi r9,r9,0x20 diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds index fb465a4d89b5..79d62c733ec0 100644 --- a/arch/ppc64/boot/zImage.lds +++ b/arch/ppc64/boot/zImage.lds @@ -13,7 +13,9 @@ SECTIONS *(.rodata*) *(.data*) *(.sdata*) - *(.got*) + __got2_start = .; + *(.got2) + __got2_end = .; } . = ALIGN(4096); From 67a1b68263d58a3ed5ce024468606044a1561312 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:49 -0700 Subject: [PATCH 0951/1940] [PATCH] ppc64 boot: proof that reloc works To prove that the relocation works, move the crt0.o away from the beginning. Move linker options from command line into linker script. rename entry point because '_start' is referenced in printf output. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 4 ++-- arch/ppc64/boot/crt0.S | 4 ++-- arch/ppc64/boot/zImage.lds | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 9e19351f3dfa..301bc1536c49 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -24,7 +24,7 @@ HOSTCC := gcc BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc -BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds +BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds OBJCOPYFLAGS := contents,alloc,load,readonly,data zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c @@ -34,7 +34,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) -src-boot := crt0.S string.S prom.c main.c div64.S +src-boot := string.S prom.c main.c div64.S crt0.S src-boot += $(zlib) src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S index 5788a453a7a2..8bfdeaf3be83 100644 --- a/arch/ppc64/boot/crt0.S +++ b/arch/ppc64/boot/crt0.S @@ -12,8 +12,8 @@ #include "ppc_asm.h" .text - .globl _start -_start: + .globl _zimage_start +_zimage_start: bl reloc_offset reloc_offset: diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds index 79d62c733ec0..4b6bb3ffe3dc 100644 --- a/arch/ppc64/boot/zImage.lds +++ b/arch/ppc64/boot/zImage.lds @@ -1,6 +1,9 @@ OUTPUT_ARCH(powerpc:common) +ENTRY(_zimage_start) SECTIONS { + . = (4*1024*1024); + _start = .; .text : { *(.text) From 7e658118faa9faf71f8a8295cdaeb7ca71c04672 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:50 -0700 Subject: [PATCH 0952/1940] [PATCH] ppc64 boot: print firmware provided stackpointer Show firmware provided stackpointer during boot. This helps to find the "taboo" areas on the various boards. claim tends to fail for these memory areas, but some jokers return success anyway. Use %p to print the load address, its a pointer. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/crt0.S | 1 + arch/ppc64/boot/main.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S index 8bfdeaf3be83..9cc442263939 100644 --- a/arch/ppc64/boot/crt0.S +++ b/arch/ppc64/boot/crt0.S @@ -54,5 +54,6 @@ clear_caches: sync isync + mr r6,r1 b start diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 3304ed34c44b..c1dc876bccab 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -131,7 +131,7 @@ static unsigned long try_claim(unsigned long size) return addr; } -void start(unsigned long a1, unsigned long a2, void *promptr) +void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) { unsigned long i; int len; @@ -151,7 +151,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr) if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); - printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start); + printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); /* * The first available claim_base must be above the end of the From 08124f958997ac14bb2284af787752125a892e9f Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:51 -0700 Subject: [PATCH 0953/1940] [PATCH] ppc64: AC Power handling broken for desktops Currently, AC Power is 0 on a desktop G4. No batteries present should mean AC Power == 1. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/macintosh/apm_emu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c index 19d3e05d6825..e5a2bbf99399 100644 --- a/drivers/macintosh/apm_emu.c +++ b/drivers/macintosh/apm_emu.c @@ -430,8 +430,8 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length) -1: Unknown 8) min = minutes; sec = seconds */ - unsigned short ac_line_status = 0xff; - unsigned short battery_status = 0xff; + unsigned short ac_line_status; + unsigned short battery_status = 0; unsigned short battery_flag = 0xff; int percentage = -1; int time_units = -1; @@ -446,6 +446,7 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length) ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0); for (i=0; i Date: Fri, 28 Oct 2005 17:46:54 -0700 Subject: [PATCH 0954/1940] [PATCH] ppc64: compile nls_cp437 and nls_iso8859_1 into the kernel in defconfig compile nls_cp437 and nls_iso8859_1 into the kernel in defconfig. This is already enabled in pSeries_defconfig. Reason: if one just boots the new shiny zImage and the root filesystem is on a filesystem not readable by yaboot (like jfs, raid or lvm) upgrading the bootloader will fail because the FAT bootpartition can not be mounted. Signed-off-by: Olaf Hering Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index 37c157c93cef..e79fd60bc122 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig @@ -1318,7 +1318,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m @@ -1342,7 +1342,7 @@ CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m From 1eee4daa9940f7044806d83006051104cc8680b3 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:55 -0700 Subject: [PATCH 0955/1940] [PATCH] ppc64: reenable make install with defconfig 'make ARCH=ppc64 O=../O install' does not work with the defconfig. CONFIG_PPC_BPA is part of it, but the BPA bootimage variable is wrong: make[2]: *** No rule to make target `zImage', needed by `install'. Stop. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index db1b25cdb5be..fdbd6f44adc0 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -108,7 +108,7 @@ $(boottargets-y): vmlinux bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage bootimage-$(CONFIG_PPC_PMAC) := vmlinux bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage -bootimage-$(CONFIG_PPC_BPA) := zImage +bootimage-$(CONFIG_PPC_BPA) := $(boot)/zImage bootimage-$(CONFIG_PPC_ISERIES) := vmlinux BOOTIMAGE := $(bootimage-y) install: vmlinux From 18c5332bc17e75efdc02cc17410c647a627861f2 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:56 -0700 Subject: [PATCH 0956/1940] [PATCH] ppc64: change name of target file during make install 'make install' creates a /boot/zImage[.vmode] file when the defconfig is used. It uses the second arg as file content, which is the vmlinux, and the 5th arg as file name, which is the BOOTIMAGE name. A comment in an earlier patch to install.sh states that yaboot can not load a zImage+initrd combo. This was true in kernel 2.6.5 because it did use bi_recs to pass the initrd info. But this concept was always broken. Register r3 holds the initrd address and r4 holds the initrd size. This works with all kernel versions. The current code in main.c leaves r3 and r4 alone, so the kernel should be able to see and use the memory range with the initrd content. If one wants to rerun mkinitrd, it is currently hard to get the uname -r value for the installed zImage. Without this info, mkinitrd can not know what modules to use. This would be fixable by including the /proc/version output of the new kernel. But it is simpler to just use the plain vmlinux. So all this patch does is to write to /boot/vmlinux instead to /boot/zImage Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc64/boot/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh index cb2d6626b555..eacce9590816 100644 --- a/arch/ppc64/boot/install.sh +++ b/arch/ppc64/boot/install.sh @@ -28,7 +28,7 @@ if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}i # Default install # this should work for both the pSeries zImage and the iSeries vmlinux.sm -image_name=`basename $5` +image_name=`basename $2` if [ -f $4/$image_name ]; then mv $4/$image_name $4/$image_name.old From ea6526605a60cf9a6f758605f73062fac6d974cf Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 28 Oct 2005 17:46:57 -0700 Subject: [PATCH 0957/1940] [PATCH] ppc64: remove duplicate local variable in set_preferred_console remove duplicate local variable, saves 2 asm instructions. Signed-off-by: Olaf Hering Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup-common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index aa743a50a20a..1292460fcde2 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -361,7 +361,6 @@ static int __init set_preferred_console(void) if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { /* Host Virtual Serial Interface */ - int offset; switch (reg[0]) { case 0x30000000: offset = 0; From ffa27b6bc61c3be76a756100f777372768bcc3ab Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Fri, 28 Oct 2005 17:46:58 -0700 Subject: [PATCH 0958/1940] [PATCH] ppc64 memory model depends on NUMA Currently when we first select memory model (FLAT, DISCONTIG, SPARSE) then select whether the machine is NUMA. However NUMA systems may not be FLAT. This constraint it not honoured and we may configure a NUMA/FLAT system. Reorder the configuration such that we choose NUMA first which allows us to only list the memory models which are valid. We now default NUMA for known NUMA systems. Note that this new order also matches that used in x86. Signed-off-by: Andy Whitcroft Signed-off-by: Joel Schopp Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 13 +++++-------- arch/ppc64/Kconfig | 11 ++++------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c71ddc0c191a..967ecf92d6a7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -538,6 +538,11 @@ config IRQ_ALL_CPUS source "arch/powerpc/platforms/pseries/Kconfig" +config NUMA + bool "NUMA support" + depends on PPC64 + default y if SMP && PPC_PSERIES + config ARCH_SELECT_MEMORY_MODEL def_bool y depends on PPC64 @@ -554,10 +559,6 @@ config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on ARCH_DISCONTIGMEM_ENABLE -config ARCH_FLATMEM_ENABLE - def_bool y - depends on PPC64 - config ARCH_SPARSEMEM_ENABLE def_bool y depends on ARCH_DISCONTIGMEM_ENABLE @@ -581,10 +582,6 @@ config NODES_SPAN_OTHER_NODES def_bool y depends on NEED_MULTIPLE_NODES -config NUMA - bool "NUMA support" - default y if DISCONTIGMEM || SPARSEMEM - config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" depends on PPC64 && SMP diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index b889277ab7de..42677cc96508 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -248,6 +248,10 @@ config HMT This option enables hardware multithreading on RS64 cpus. pSeries systems p620 and p660 have such a cpu type. +config NUMA + bool "NUMA support" + default y if SMP && PPC_PSERIES + config ARCH_SELECT_MEMORY_MODEL def_bool y @@ -263,9 +267,6 @@ config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on ARCH_DISCONTIGMEM_ENABLE -config ARCH_FLATMEM_ENABLE - def_bool y - config ARCH_SPARSEMEM_ENABLE def_bool y depends on ARCH_DISCONTIGMEM_ENABLE @@ -288,10 +289,6 @@ config NODES_SPAN_OTHER_NODES def_bool y depends on NEED_MULTIPLE_NODES -config NUMA - bool "NUMA support" - default y if DISCONTIGMEM || SPARSEMEM - config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" depends on SMP From d3f67fbb96b827c1a6a7a82689e589865581155c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 29 Oct 2005 15:31:17 +1000 Subject: [PATCH 0959/1940] powerpc: Add -mno-altivec for ARCH=powerpc builds Signed-off-by: Paul Mackerras --- arch/powerpc/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 29cda0732703..2f4cce06a7e5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -93,6 +93,9 @@ else endif endif +# No AltiVec instruction when building kernel +CFLAGS += $(call cc-option,-mno-altivec) + # Enable unit-at-a-time mode when possible. It shrinks the # kernel considerably. CFLAGS += $(call cc-option,-funit-at-a-time) From 0cb7b2afd79c5715cbd1d4eee826571fb17fdd65 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 29 Oct 2005 22:07:56 +1000 Subject: [PATCH 0960/1940] powerpc: Merge maple support code to arch/powerpc/platforms/maple Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/Makefile | 1 + arch/powerpc/platforms/maple/Makefile | 1 + arch/powerpc/platforms/maple/maple.h | 12 ++++++++++++ .../maple_pci.c => powerpc/platforms/maple/pci.c} | 2 ++ .../platforms/maple/setup.c} | 11 +++-------- .../maple_time.c => powerpc/platforms/maple/time.c} | 2 ++ arch/ppc64/kernel/Makefile | 3 +-- 7 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 arch/powerpc/platforms/maple/Makefile create mode 100644 arch/powerpc/platforms/maple/maple.h rename arch/{ppc64/kernel/maple_pci.c => powerpc/platforms/maple/pci.c} (99%) rename arch/{ppc64/kernel/maple_setup.c => powerpc/platforms/maple/setup.c} (95%) rename arch/{ppc64/kernel/maple_time.c => powerpc/platforms/maple/time.c} (99%) diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 01723d491b5d..172c0db63504 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_85xx) += 85xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ +obj-$(CONFIG_PPC_MAPLE) += maple/ diff --git a/arch/powerpc/platforms/maple/Makefile b/arch/powerpc/platforms/maple/Makefile new file mode 100644 index 000000000000..1be1a993c5f5 --- /dev/null +++ b/arch/powerpc/platforms/maple/Makefile @@ -0,0 +1 @@ +obj-y += setup.o pci.o time.o diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h new file mode 100644 index 000000000000..0657c579b840 --- /dev/null +++ b/arch/powerpc/platforms/maple/maple.h @@ -0,0 +1,12 @@ +/* + * Declarations for maple-specific code. + * + * Maple is the name of a PPC970 evaluation board. + */ +extern int maple_set_rtc_time(struct rtc_time *tm); +extern void maple_get_rtc_time(struct rtc_time *tm); +extern unsigned long maple_get_boot_time(void); +extern void maple_calibrate_decr(void); +extern void maple_pci_init(void); +extern void maple_pcibios_fixup(void); +extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel); diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/powerpc/platforms/maple/pci.c similarity index 99% rename from arch/ppc64/kernel/maple_pci.c rename to arch/powerpc/platforms/maple/pci.c index 633324b5e61b..340c21caeae2 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -25,6 +25,8 @@ #include #include +#include "maple.h" + #ifdef DEBUG #define DBG(x...) printk(x) #else diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/powerpc/platforms/maple/setup.c similarity index 95% rename from arch/ppc64/kernel/maple_setup.c rename to arch/powerpc/platforms/maple/setup.c index a107ed69a355..7ece8983a105 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -1,5 +1,5 @@ /* - * arch/ppc64/kernel/maple_setup.c + * Maple (970 eval board) setup code * * (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org), * IBM Corp. @@ -62,19 +62,14 @@ #include #include +#include "maple.h" + #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else #define DBG(fmt...) #endif -extern int maple_set_rtc_time(struct rtc_time *tm); -extern void maple_get_rtc_time(struct rtc_time *tm); -extern unsigned long maple_get_boot_time(void); -extern void maple_calibrate_decr(void); -extern void maple_pci_init(void); -extern void maple_pcibios_fixup(void); -extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel); extern void generic_find_legacy_serial_ports(u64 *physport, unsigned int *default_speed); diff --git a/arch/ppc64/kernel/maple_time.c b/arch/powerpc/platforms/maple/time.c similarity index 99% rename from arch/ppc64/kernel/maple_time.c rename to arch/powerpc/platforms/maple/time.c index 445cb7470bf5..40fc07a8e606 100644 --- a/arch/ppc64/kernel/maple_time.c +++ b/arch/powerpc/platforms/maple/time.c @@ -36,6 +36,8 @@ #include #include +#include "maple.h" + #ifdef DEBUG #define DBG(x...) printk(x) #else diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 3cf7f3dab511..327c08ce4291 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -55,8 +55,7 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_PPC_PMAC) += udbg_scc.o -obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \ - udbg_16550.o +obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o ifdef CONFIG_SMP obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o From c1c3a554a32c3de1340887caa5729d67ed6684d6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 29 Oct 2005 22:08:55 +1000 Subject: [PATCH 0961/1940] powerpc: 32-bit needs cur_cpu_spec exported too Somehow we ended up with an #ifdef CONFIG_PPC64 around the export of cur_cpu_spec, but raid6 as a module needs it on ppc32 as well as ppc64. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1fb80baebc87..b91345fa0805 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -21,9 +21,7 @@ #include struct cpu_spec* cur_cpu_spec = NULL; -#ifdef CONFIG_PPC64 EXPORT_SYMBOL(cur_cpu_spec); -#endif /* NOTE: * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's From 3ee1fcac33eae824422b9b98d972a85e79672426 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 29 Oct 2005 22:10:38 +1000 Subject: [PATCH 0962/1940] powerpc: import a gfp_t fix to arch/powerpc/mm/pgtable_32.c This applies the same fix as Al Viro recently made to arch/ppc/mm/pgtable.c. Signed-off-by: Paul Mackerras --- arch/powerpc/mm/pgtable_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 5792e533916f..f54fb9d3927a 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -114,9 +114,9 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) struct page *ptepage; #ifdef CONFIG_HIGHPTE - int flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT; + gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT; #else - int flags = GFP_KERNEL | __GFP_REPEAT; + gfp_t flags = GFP_KERNEL | __GFP_REPEAT; #endif ptepage = alloc_pages(flags, 0); From eb66ce6333742e32825f0294310ff53e284fa828 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 29 Oct 2005 22:11:06 +1000 Subject: [PATCH 0963/1940] powerpc: Remove T command from xmon help text since it no longer exists Signed-off-by: Paul Mackerras --- arch/powerpc/xmon/xmon.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d0623e0fd8ee..1124f1146202 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -210,7 +210,6 @@ Commands:\n\ s single step\n\ S print special registers\n\ t print backtrace\n\ - T Enable/Disable PPCDBG flags\n\ x exit monitor and recover\n\ X exit monitor and dont recover\n" #ifdef CONFIG_PPC64 From fb31690fbac6f4055c1765522752e4746759f5de Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 13:15:10 +0100 Subject: [PATCH 0964/1940] [ARM] Ensure machine information structures aren't optimised away Since the machine information structures are now static, the compiler might optimise them away. Mark them with __attribute_used__ to prevent this occuring. Signed-off-by: Russell King --- include/asm-arm/mach/arch.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index 7273c6fd95b5..eb262e078c46 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -50,6 +50,7 @@ struct machine_desc { */ #define MACHINE_START(_type,_name) \ static const struct machine_desc __mach_desc_##_type \ + __attribute_used__ \ __attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \ .name = _name, From 8c18fe2562c45180c407872d05857c55c1e5e37b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 13:18:10 +0100 Subject: [PATCH 0965/1940] [ARM] Fix buggy __phys_to_pfn / __pfn_to_phys Macro arguments should _always_ be surrounded by parentheses when used to prevent unexpected problems with operator precedence. Signed-off-by: Russell King --- include/asm-arm/mach/map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h index 0619522bd926..b338936bde4f 100644 --- a/include/asm-arm/mach/map.h +++ b/include/asm-arm/mach/map.h @@ -27,8 +27,8 @@ struct meminfo; #define MT_ROM 6 #define MT_IXP2000_DEVICE 7 -#define __phys_to_pfn(paddr) (paddr >> PAGE_SHIFT) -#define __pfn_to_phys(pfn) (pfn << PAGE_SHIFT) +#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) +#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) extern void create_memmap_holes(struct meminfo *); extern void memtable_init(struct meminfo *); From affcd50546d4788b7849e2b2e2ec7bc50d64c5f8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sat, 29 Oct 2005 07:39:42 -0700 Subject: [PATCH 0966/1940] [IB] mthca: report asynchronous CQ events Implement reporting asynchronous CQ events in Mellanox HCA driver. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cq.c | 31 ++++++++++++++++++++++++- drivers/infiniband/hw/mthca/mthca_dev.h | 4 +++- drivers/infiniband/hw/mthca/mthca_eq.c | 4 +++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 8600b6c3e0c2..f98e23555826 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c @@ -208,7 +208,7 @@ static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, } } -void mthca_cq_event(struct mthca_dev *dev, u32 cqn) +void mthca_cq_completion(struct mthca_dev *dev, u32 cqn) { struct mthca_cq *cq; @@ -224,6 +224,35 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn) cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); } +void mthca_cq_event(struct mthca_dev *dev, u32 cqn, + enum ib_event_type event_type) +{ + struct mthca_cq *cq; + struct ib_event event; + + spin_lock(&dev->cq_table.lock); + + cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1)); + + if (cq) + atomic_inc(&cq->refcount); + spin_unlock(&dev->cq_table.lock); + + if (!cq) { + mthca_warn(dev, "Async event for bogus CQ %08x\n", cqn); + return; + } + + event.device = &dev->ib_dev; + event.event = event_type; + event.element.cq = &cq->ibcq; + if (cq->ibcq.event_handler) + cq->ibcq.event_handler(&event, cq->ibcq.cq_context); + + if (atomic_dec_and_test(&cq->refcount)) + wake_up(&cq->wait); +} + void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, struct mthca_srq *srq) { diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 7e68bd4a3780..e7e5d3b4f004 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -460,7 +460,9 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, struct mthca_cq *cq); void mthca_free_cq(struct mthca_dev *dev, struct mthca_cq *cq); -void mthca_cq_event(struct mthca_dev *dev, u32 cqn); +void mthca_cq_completion(struct mthca_dev *dev, u32 cqn); +void mthca_cq_event(struct mthca_dev *dev, u32 cqn, + enum ib_event_type event_type); void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, struct mthca_srq *srq); diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index e5a047a6dbeb..34d68e5a72d8 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -292,7 +292,7 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) case MTHCA_EVENT_TYPE_COMP: disarm_cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff; disarm_cq(dev, eq->eqn, disarm_cqn); - mthca_cq_event(dev, disarm_cqn); + mthca_cq_completion(dev, disarm_cqn); break; case MTHCA_EVENT_TYPE_PATH_MIG: @@ -364,6 +364,8 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) eqe->event.cq_err.syndrome == 1 ? "overrun" : "access violation", be32_to_cpu(eqe->event.cq_err.cqn) & 0xffffff); + mthca_cq_event(dev, be32_to_cpu(eqe->event.cq_err.cqn), + IB_EVENT_CQ_ERR); break; case MTHCA_EVENT_TYPE_EQ_OVERFLOW: From 80e23babfcf21a2dc726d3be00e06993f02f0274 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 29 Oct 2005 09:42:17 -0500 Subject: [PATCH 0967/1940] [SCSI] fix up mismerge in osst Signed-off-by: James Bottomley --- drivers/scsi/osst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 011f3c8fe56f..c65c418a7906 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5819,7 +5819,7 @@ static int osst_probe(struct device *dev) } drive->number = devfs_register_tape(SDp->devfs_name); - sdev_printk(KERN_INFO, &SDp, + sdev_printk(KERN_INFO, SDp, "osst :I: Attached OnStream %.5s tape as %s\n", SDp->model, tape_name(tpnt)); From 57725f0a94435355214977bb9b0e5089bba1b173 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 15:51:14 +0100 Subject: [PATCH 0968/1940] [ARM] Rename 'data' to 'plat' in sa1100 MTD map driver Signed-off-by: Russell King --- drivers/mtd/maps/sa1100-flash.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 6a8e0caf9fdc..1920bcbc05d7 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -130,7 +130,7 @@ struct sa_subdev_info { char name[16]; struct map_info map; struct mtd_info *mtd; - struct flash_platform_data *data; + struct flash_platform_data *plat; }; struct sa_info { @@ -143,7 +143,7 @@ struct sa_info { static void sa1100_set_vpp(struct map_info *map, int on) { struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map); - subdev->data->set_vpp(on); + subdev->plat->set_vpp(on); } static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) @@ -187,7 +187,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r goto out; } - if (subdev->data->set_vpp) + if (subdev->plat->set_vpp) subdev->map.set_vpp = sa1100_set_vpp; subdev->map.phys = phys; @@ -204,7 +204,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r * Now let's probe for the actual flash. Do it here since * specific machine settings might have been set above. */ - subdev->mtd = do_map_probe(subdev->data->map_name, &subdev->map); + subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map); if (subdev->mtd == NULL) { ret = -ENXIO; goto err; @@ -245,7 +245,7 @@ static void sa1100_destroy(struct sa_info *info) } static struct sa_info *__init -sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash) +sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) { struct sa_info *info; int nr, size, i, ret = 0; @@ -288,7 +288,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash subdev->map.name = subdev->name; sprintf(subdev->name, "sa1100-%d", i); - subdev->data = flash; + subdev->plat = plat; ret = sa1100_probe_subdev(subdev, res); if (ret) @@ -346,16 +346,16 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int __init sa1100_mtd_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct flash_platform_data *flash = pdev->dev.platform_data; + struct flash_platform_data *plat = pdev->dev.platform_data; struct mtd_partition *parts; const char *part_type = NULL; struct sa_info *info; int err, nr_parts = 0; - if (!flash) + if (!plat) return -ENODEV; - info = sa1100_setup_mtd(pdev, flash); + info = sa1100_setup_mtd(pdev, plat); if (IS_ERR(info)) { err = PTR_ERR(info); goto out; @@ -372,8 +372,8 @@ static int __init sa1100_mtd_probe(struct device *dev) } else #endif { - parts = flash->parts; - nr_parts = flash->nr_parts; + parts = plat->parts; + nr_parts = plat->nr_parts; part_type = "static"; } From 0d2ef7d73e0b5173af3940139569bebd2375f441 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 15:57:20 +0100 Subject: [PATCH 0969/1940] [ARM] Add support for init/exit methods in sa1100 MTD map driver Signed-off-by: Russell King --- drivers/mtd/maps/sa1100-flash.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 1920bcbc05d7..50a1d434906a 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -223,7 +223,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r return ret; } -static void sa1100_destroy(struct sa_info *info) +static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat) { int i; @@ -242,6 +242,9 @@ static void sa1100_destroy(struct sa_info *info) for (i = info->num_subdev - 1; i >= 0; i--) sa1100_destroy_subdev(&info->subdev[i]); kfree(info); + + if (plat->exit) + plat->exit(); } static struct sa_info *__init @@ -275,6 +278,12 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) memset(info, 0, size); + if (plat->init) { + ret = plat->init(); + if (ret) + goto err; + } + /* * Claim and then map the memory regions. */ @@ -336,7 +345,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) return info; err: - sa1100_destroy(info); + sa1100_destroy(info, plat); out: return ERR_PTR(ret); } @@ -397,8 +406,11 @@ static int __init sa1100_mtd_probe(struct device *dev) static int __exit sa1100_mtd_remove(struct device *dev) { struct sa_info *info = dev_get_drvdata(dev); + struct flash_platform_data *plat = dev->platform_data; + dev_set_drvdata(dev, NULL); - sa1100_destroy(info); + sa1100_destroy(info, plat); + return 0; } From ca61f10ab2b874b889e89d14ea09fae2dcccdca6 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 29 Oct 2005 10:01:24 -0500 Subject: [PATCH 0970/1940] [SCSI] remove broken driver cpqfc Hopefully there should be a brand new replacement driver for this heap of junk by the beginning of next year. Acked By: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 13 - drivers/scsi/Makefile | 3 - drivers/scsi/cpqfcTS.h | 19 - drivers/scsi/cpqfcTSchip.h | 238 -- drivers/scsi/cpqfcTScontrol.c | 2231 ----------- drivers/scsi/cpqfcTSi2c.c | 493 --- drivers/scsi/cpqfcTSinit.c | 2096 ----------- drivers/scsi/cpqfcTSioctl.h | 94 - drivers/scsi/cpqfcTSstructs.h | 1530 -------- drivers/scsi/cpqfcTStrigger.c | 33 - drivers/scsi/cpqfcTStrigger.h | 8 - drivers/scsi/cpqfcTSworker.c | 6516 --------------------------------- 12 files changed, 13274 deletions(-) delete mode 100644 drivers/scsi/cpqfcTS.h delete mode 100644 drivers/scsi/cpqfcTSchip.h delete mode 100644 drivers/scsi/cpqfcTScontrol.c delete mode 100644 drivers/scsi/cpqfcTSi2c.c delete mode 100644 drivers/scsi/cpqfcTSinit.c delete mode 100644 drivers/scsi/cpqfcTSioctl.h delete mode 100644 drivers/scsi/cpqfcTSstructs.h delete mode 100644 drivers/scsi/cpqfcTStrigger.c delete mode 100644 drivers/scsi/cpqfcTStrigger.h delete mode 100644 drivers/scsi/cpqfcTSworker.c diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 78c33180ebed..afeca325b4dc 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -620,19 +620,6 @@ config SCSI_OMIT_FLASHPOINT substantial, so users of MultiMaster Host Adapters may wish to omit it. -# -# This is marked broken because it uses over 4kB of stack in -# just two routines: -# 2076 CpqTsProcessIMQEntry -# 2052 PeekIMQEntry -# -config SCSI_CPQFCTS - tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support" - depends on PCI && SCSI && BROKEN - help - Say Y here to compile in support for the Compaq StorageWorks Fibre - Channel 64-bit/66Mhz Host Bus Adapter. - config SCSI_DMX3191D tristate "DMX3191D SCSI support" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 8dfb9884afe0..b88b8c455598 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -120,7 +120,6 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o obj-$(CONFIG_SCSI_FCAL) += fcal.o -obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_IPR) += ipr.o @@ -165,8 +164,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) zalon7xx-objs := zalon.o ncr53c8xx.o NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o -cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \ - cpqfcTSworker.o cpqfcTStrigger.o libata-objs := libata-core.o libata-scsi.o # Files generated that shall be removed upon make clean diff --git a/drivers/scsi/cpqfcTS.h b/drivers/scsi/cpqfcTS.h deleted file mode 100644 index 7ce53d88cb96..000000000000 --- a/drivers/scsi/cpqfcTS.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CPQFCTS_H -#define CPQFCTS_H -#include "cpqfcTSstructs.h" - -// These functions are required by the Linux SCSI layers -extern int cpqfcTS_detect(Scsi_Host_Template *); -extern int cpqfcTS_release(struct Scsi_Host *); -extern const char * cpqfcTS_info(struct Scsi_Host *); -extern int cpqfcTS_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); -extern int cpqfcTS_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); -extern int cpqfcTS_abort(Scsi_Cmnd *); -extern int cpqfcTS_reset(Scsi_Cmnd *, unsigned int); -extern int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd); -extern int cpqfcTS_eh_device_reset(Scsi_Cmnd *); -extern int cpqfcTS_biosparam(struct scsi_device *, struct block_device *, - sector_t, int[]); -extern int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg); - -#endif /* CPQFCTS_H */ diff --git a/drivers/scsi/cpqfcTSchip.h b/drivers/scsi/cpqfcTSchip.h deleted file mode 100644 index 14b83373861f..000000000000 --- a/drivers/scsi/cpqfcTSchip.h +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright(c) 2000, Compaq Computer Corporation - * Fibre Channel Host Bus Adapter - * 64-bit, 66MHz PCI - * Originally developed and tested on: - * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... - * SP# P225CXCBFIEL6T, Rev XC - * SP# 161290-001, Rev XD - * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 - * - * 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. - * Written by Don Zimmerman -*/ -#ifndef CPQFCTSCHIP_H -#define CPQFCTSCHIP_H -#ifndef TACHYON_CHIP_INC - -// FC-PH (Physical) specification levels for Login payloads -// NOTE: These are NOT strictly complied with by any FC vendors - -#define FC_PH42 0x08 -#define FC_PH43 0x09 -#define FC_PH3 0x20 - -#define TACHLITE_TS_RX_SIZE 1024 // max inbound frame size -// "I" prefix is for Include - -#define IVENDID 0x00 // word -#define IDEVID 0x02 -#define ITLCFGCMD 0x04 -#define IMEMBASE 0x18 // Tachyon -#define ITLMEMBASE 0x1C // Tachlite -#define IIOBASEL 0x10 // Tachyon I/O base address, lower 256 bytes -#define IIOBASEU 0x14 // Tachyon I/O base address, upper 256 bytes -#define ITLIOBASEL 0x14 // TachLite I/O base address, lower 256 bytes -#define ITLIOBASEU 0x18 // TachLite I/O base address, upper 256 bytes -#define ITLRAMBASE 0x20 // TL on-board RAM start -#define ISROMBASE 0x24 -#define IROMBASE 0x30 - -#define ICFGCMD 0x04 // PCI config - PCI config access (word) -#define ICFGSTAT 0x06 // PCI status (R - word) -#define IRCTR_WCTR 0x1F2 // ROM control / pre-fetch wait counter -#define IPCIMCTR 0x1F3 // PCI master control register -#define IINTPEND 0x1FD // Interrupt pending (I/O Upper - Tachyon & TL) -#define IINTEN 0x1FE // Interrupt enable (I/O Upper - Tachyon & TL) -#define IINTSTAT 0x1FF // Interrupt status (I/O Upper - Tachyon & TL) - -#define IMQ_BASE 0x80 -#define IMQ_LENGTH 0x84 -#define IMQ_CONSUMER_INDEX 0x88 -#define IMQ_PRODUCER_INDEX 0x8C // Tach copies its INDX to bits 0-7 of value - -/* -// IOBASE UPPER -#define SFSBQ_BASE 0x00 // single-frame sequences -#define SFSBQ_LENGTH 0x04 -#define SFSBQ_PRODUCER_INDEX 0x08 -#define SFSBQ_CONSUMER_INDEX 0x0C // (R) -#define SFS_BUFFER_LENGTH 0X10 - // SCSI-FCP hardware assists -#define SEST_BASE 0x40 // SSCI Exchange State Table -#define SEST_LENGTH 0x44 -#define SCSI_BUFFER_LENGTH 0x48 -#define SEST_LINKED_LIST 0x4C - -#define TACHYON_My_ID 0x6C -#define TACHYON_CONFIGURATION 0x84 // (R/W) reset val 2 -#define TACHYON_CONTROL 0x88 -#define TACHYON_STATUS 0x8C // (R) -#define TACHYON_FLUSH_SEST 0x90 // (R/W) -#define TACHYON_EE_CREDIT_TMR 0x94 // (R) -#define TACHYON_BB_CREDIT_TMR 0x98 // (R) -#define TACHYON_RCV_FRAME_ERR 0x9C // (R) -#define FRAME_MANAGER_CONFIG 0xC0 // (R/W) -#define FRAME_MANAGER_CONTROL 0xC4 -#define FRAME_MANAGER_STATUS 0xC8 // (R) -#define FRAME_MANAGER_ED_TOV 0xCC -#define FRAME_MANAGER_LINK_ERR1 0xD0 // (R) -#define FRAME_MANAGER_LINK_ERR2 0xD4 // (R) -#define FRAME_MANAGER_TIMEOUT2 0xD8 // (W) -#define FRAME_MANAGER_BB_CREDIT 0xDC // (R) -#define FRAME_MANAGER_WWN_HI 0xE0 // (R/W) -#define FRAME_MANAGER_WWN_LO 0xE4 // (R/W) -#define FRAME_MANAGER_RCV_AL_PA 0xE8 // (R) -#define FRAME_MANAGER_PRIMITIVE 0xEC // {K28.5} byte1 byte2 byte3 -*/ - -#define TL_MEM_ERQ_BASE 0x0 //ERQ Base -#define TL_IO_ERQ_BASE 0x0 //ERQ base - -#define TL_MEM_ERQ_LENGTH 0x4 //ERQ Length -#define TL_IO_ERQ_LENGTH 0x4 //ERQ Length - -#define TL_MEM_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register -#define TL_IO_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register - -#define TL_MEM_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register -#define TL_IO_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register - -#define TL_MEM_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index -#define TL_IO_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index - -#define TL_MEM_SFQ_BASE 0x50 //SFQ Base -#define TL_IO_SFQ_BASE 0x50 //SFQ base - -#define TL_MEM_SFQ_LENGTH 0x54 //SFQ Length -#define TL_IO_SFQ_LENGTH 0x54 //SFQ Length - -#define TL_MEM_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index -#define TL_IO_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index - -#define TL_MEM_IMQ_BASE 0x80 //IMQ Base -#define TL_IO_IMQ_BASE 0x80 //IMQ base - -#define TL_MEM_IMQ_LENGTH 0x84 //IMQ Length -#define TL_IO_IMQ_LENGTH 0x84 //IMQ Length - -#define TL_MEM_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index -#define TL_IO_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index - -#define TL_MEM_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register -#define TL_IO_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register - -#define TL_MEM_SEST_BASE 0x140 //SFQ Base -#define TL_IO_SEST_BASE 0x40 //SFQ base - -#define TL_MEM_SEST_LENGTH 0x144 //SFQ Length -#define TL_IO_SEST_LENGTH 0x44 //SFQ Length - -#define TL_MEM_SEST_LINKED_LIST 0x14C - -#define TL_MEM_SEST_SG_PAGE 0x168 // Extended Scatter/Gather page size - -#define TL_MEM_TACH_My_ID 0x16C -#define TL_IO_TACH_My_ID 0x6C //My AL_PA ID - -#define TL_MEM_TACH_CONFIG 0x184 //Tachlite Configuration register -#define TL_IO_CONFIG 0x84 //Tachlite Configuration register - -#define TL_MEM_TACH_CONTROL 0x188 //Tachlite Control register -#define TL_IO_CTR 0x88 //Tachlite Control register - -#define TL_MEM_TACH_STATUS 0x18C //Tachlite Status register -#define TL_IO_STAT 0x8C //Tachlite Status register - -#define TL_MEM_FM_CONFIG 0x1C0 //Frame Manager Configuration register -#define TL_IO_FM_CONFIG 0xC0 //Frame Manager Configuration register - -#define TL_MEM_FM_CONTROL 0x1C4 //Frame Manager Control -#define TL_IO_FM_CTL 0xC4 //Frame Manager Control - -#define TL_MEM_FM_STATUS 0x1C8 //Frame Manager Status -#define TL_IO_FM_STAT 0xC8 //Frame Manager Status - -#define TL_MEM_FM_LINK_STAT1 0x1D0 //Frame Manager Link Status 1 -#define TL_IO_FM_LINK_STAT1 0xD0 //Frame Manager Link Status 1 - -#define TL_MEM_FM_LINK_STAT2 0x1D4 //Frame Manager Link Status 2 -#define TL_IO_FM_LINK_STAT2 0xD4 //Frame Manager Link Status 2 - -#define TL_MEM_FM_TIMEOUT2 0x1D8 // (W) - -#define TL_MEM_FM_BB_CREDIT0 0x1DC - -#define TL_MEM_FM_WWN_HI 0x1E0 //Frame Manager World Wide Name High -#define TL_IO_FM_WWN_HI 0xE0 //Frame Manager World Wide Name High - -#define TL_MEM_FM_WWN_LO 0x1E4 //Frame Manager World Wide Name LOW -#define TL_IO_FM_WWN_LO 0xE4 //Frame Manager World Wide Name Low - -#define TL_MEM_FM_RCV_AL_PA 0x1E8 //Frame Manager AL_PA Received register -#define TL_IO_FM_ALPA 0xE8 //Frame Manager AL_PA Received register - -#define TL_MEM_FM_ED_TOV 0x1CC - -#define TL_IO_ROMCTR 0xFA //TL PCI ROM Control Register -#define TL_IO_PCIMCTR 0xFB //TL PCI Master Control Register -#define TL_IO_SOFTRST 0xFC //Tachlite Configuration register -#define TL_MEM_SOFTRST 0x1FC //Tachlite Configuration register - -// completion message types (bit 8 set means Interrupt generated) -// CM_Type -#define OUTBOUND_COMPLETION 0 -#define ERROR_IDLE_COMPLETION 0x01 -#define OUT_HI_PRI_COMPLETION 0x01 -#define INBOUND_MFS_COMPLETION 0x02 -#define INBOUND_000_COMPLETION 0x03 -#define INBOUND_SFS_COMPLETION 0x04 // Tachyon & TachLite -#define ERQ_FROZEN_COMPLETION 0x06 // TachLite -#define INBOUND_C1_TIMEOUT 0x05 -#define INBOUND_BUSIED_FRAME 0x06 -#define SFS_BUF_WARN 0x07 -#define FCP_FROZEN_COMPLETION 0x07 // TachLite -#define MFS_BUF_WARN 0x08 -#define IMQ_BUF_WARN 0x09 -#define FRAME_MGR_INTERRUPT 0x0A -#define READ_STATUS 0x0B -#define INBOUND_SCSI_DATA_COMPLETION 0x0C -#define INBOUND_FCP_XCHG_COMPLETION 0x0C // TachLite -#define INBOUND_SCSI_DATA_COMMAND 0x0D -#define BAD_SCSI_FRAME 0x0E -#define INB_SCSI_STATUS_COMPLETION 0x0F -#define BUFFER_PROCESSED_COMPLETION 0x11 - -// FC-AL (Tachyon) Loop Port State Machine defs -// (loop "Up" states) -#define MONITORING 0x0 -#define ARBITRATING 0x1 -#define ARBITRAT_WON 0x2 -#define OPEN 0x3 -#define OPENED 0x4 -#define XMITTD_CLOSE 0x5 -#define RCVD_CLOSE 0x6 -#define TRANSFER 0x7 - -// (loop "Down" states) -#define INITIALIZING 0x8 -#define O_I_INIT 0x9 -#define O_I_PROTOCOL 0xa -#define O_I_LIP_RCVD 0xb -#define HOST_CONTROL 0xc -#define LOOP_FAIL 0xd -// (no 0xe) -#define OLD_PORT 0xf - - - -#define TACHYON_CHIP_INC -#endif -#endif /* CPQFCTSCHIP_H */ diff --git a/drivers/scsi/cpqfcTScontrol.c b/drivers/scsi/cpqfcTScontrol.c deleted file mode 100644 index bd94c70f473d..000000000000 --- a/drivers/scsi/cpqfcTScontrol.c +++ /dev/null @@ -1,2231 +0,0 @@ -/* Copyright 2000, Compaq Computer Corporation - * Fibre Channel Host Bus Adapter - * 64-bit, 66MHz PCI - * Originally developed and tested on: - * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... - * SP# P225CXCBFIEL6T, Rev XC - * SP# 161290-001, Rev XD - * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 - * - * 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. - * Written by Don Zimmerman -*/ -/* These functions control the host bus adapter (HBA) hardware. The main chip - control takes place in the interrupt handler where we process the IMQ - (Inbound Message Queue). The IMQ is Tachyon's way of communicating FC link - events and state information to the driver. The Single Frame Queue (SFQ) - buffers incoming FC frames for processing by the driver. References to - "TL/TS UG" are for: - "HP HPFC-5100/5166 Tachyon TL/TS ICs User Guide", August 16, 1999, 1st Ed. - Hewlitt Packard Manual Part Number 5968-1083E. -*/ - -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) - -#include -#include -#include -#include // request_region() prototype -#include -#include // need "kfree" for ext. S/G pages -#include -#include -#include -#include -#include // struct pt_regs for IRQ handler & Port I/O -#include -#include - -#include "scsi.h" -#include // Scsi_Host definition for INT handler -#include "cpqfcTSchip.h" -#include "cpqfcTSstructs.h" - -//#define IMQ_DEBUG 1 - -static void fcParseLinkStatusCounters(TACHYON * fcChip); -static void CpqTsGetSFQEntry(TACHYON * fcChip, - USHORT pi, ULONG * buffr, BOOLEAN UpdateChip); - -static void -cpqfc_free_dma_consistent(CPQFCHBA *cpqfcHBAdata) -{ - // free up the primary EXCHANGES struct and Link Q - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - - if (fcChip->Exchanges != NULL) - pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_EXCHANGES), - fcChip->Exchanges, fcChip->exch_dma_handle); - fcChip->Exchanges = NULL; - if (cpqfcHBAdata->fcLQ != NULL) - pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_LINK_QUE), - cpqfcHBAdata->fcLQ, cpqfcHBAdata->fcLQ_dma_handle); - cpqfcHBAdata->fcLQ = NULL; -} - -// Note special requirements for Q alignment! (TL/TS UG pg. 190) -// We place critical index pointers at end of QUE elements to assist -// in non-symbolic (i.e. memory dump) debugging -// opcode defines placement of Queues (e.g. local/external RAM) - -int CpqTsCreateTachLiteQues( void* pHBA, int opcode) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - - int iStatus=0; - unsigned long ulAddr; - dma_addr_t ERQdma, IMQdma, SPQdma, SESTdma; - int i; - - // NOTE! fcMemManager() will return system virtual addresses. - // System (kernel) virtual addresses, though non-paged, still - // aren't physical addresses. Convert to PHYSICAL_ADDRESS for Tachyon's - // DMA use. - ENTER("CreateTachLiteQues"); - - - // Allocate primary EXCHANGES array... - fcChip->Exchanges = NULL; - cpqfcHBAdata->fcLQ = NULL; - - /* printk("Allocating %u for %u Exchanges ", - (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); */ - fcChip->Exchanges = pci_alloc_consistent(cpqfcHBAdata->PciDev, - sizeof(FC_EXCHANGES), &fcChip->exch_dma_handle); - /* printk("@ %p\n", fcChip->Exchanges); */ - - if( fcChip->Exchanges == NULL ) // fatal error!! - { - printk("pci_alloc_consistent failure on Exchanges: fatal error\n"); - return -1; - } - // zero out the entire EXCHANGE space - memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES)); - - - /* printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); */ - cpqfcHBAdata->fcLQ = pci_alloc_consistent(cpqfcHBAdata->PciDev, - sizeof( FC_LINK_QUE), &cpqfcHBAdata->fcLQ_dma_handle); - /* printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); */ - - if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!! - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("pci_alloc_consistent() failure on fc Link Que: fatal error\n"); - return -1; - } - // zero out the entire EXCHANGE space - memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE)); - - // Verify that basic Tach I/O registers are not NULL - if( !fcChip->Registers.ReMapMemBase ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("HBA base address NULL: fatal error\n"); - return -1; - } - - - // Initialize the fcMemManager memory pairs (stores allocated/aligned - // pairs for future freeing) - memset( cpqfcHBAdata->dynamic_mem, 0, sizeof(cpqfcHBAdata->dynamic_mem)); - - - // Allocate Tach's Exchange Request Queue (each ERQ entry 32 bytes) - - fcChip->ERQ = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - sizeof( TachLiteERQ ), 32*(ERQ_LEN), 0L, &ERQdma); - if( !fcChip->ERQ ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("pci_alloc_consistent/alignment failure on ERQ: fatal error\n"); - return -1; - } - fcChip->ERQ->length = ERQ_LEN-1; - ulAddr = (ULONG) ERQdma; -#if BITS_PER_LONG > 32 - if( (ulAddr >> 32) ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk(" FATAL! ERQ ptr %p exceeds Tachyon's 32-bit register size\n", - (void*)ulAddr); - return -1; // failed - } -#endif - fcChip->ERQ->base = (ULONG)ulAddr; // copy for quick reference - - - // Allocate Tach's Inbound Message Queue (32 bytes per entry) - - fcChip->IMQ = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - sizeof( TachyonIMQ ), 32*(IMQ_LEN), 0L, &IMQdma ); - if( !fcChip->IMQ ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("pci_alloc_consistent/alignment failure on IMQ: fatal error\n"); - return -1; - } - fcChip->IMQ->length = IMQ_LEN-1; - - ulAddr = IMQdma; -#if BITS_PER_LONG > 32 - if( (ulAddr >> 32) ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n", - (void*)ulAddr); - return -1; // failed - } -#endif - fcChip->IMQ->base = (ULONG)ulAddr; // copy for quick reference - - - // Allocate Tach's Single Frame Queue (64 bytes per entry) - fcChip->SFQ = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - sizeof( TachLiteSFQ ), 64*(SFQ_LEN),0L, &SPQdma ); - if( !fcChip->SFQ ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("pci_alloc_consistent/alignment failure on SFQ: fatal error\n"); - return -1; - } - fcChip->SFQ->length = SFQ_LEN-1; // i.e. Que length [# entries - - // min. 32; max. 4096 (0xffff)] - - ulAddr = SPQdma; -#if BITS_PER_LONG > 32 - if( (ulAddr >> 32) ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n", - (void*)ulAddr); - return -1; // failed - } -#endif - fcChip->SFQ->base = (ULONG)ulAddr; // copy for quick reference - - - // Allocate SCSI Exchange State Table; aligned nearest @sizeof - // power-of-2 boundary - // LIVE DANGEROUSLY! Assume the boundary for SEST mem will - // be on physical page (e.g. 4k) boundary. - /* printk("Allocating %u for TachSEST for %u Exchanges\n", - (ULONG)sizeof(TachSEST), TACH_SEST_LEN); */ - fcChip->SEST = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - sizeof(TachSEST), 4, 0L, &SESTdma ); -// sizeof(TachSEST), 64*TACH_SEST_LEN, 0L ); - if( !fcChip->SEST ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk("pci_alloc_consistent/alignment failure on SEST: fatal error\n"); - return -1; - } - - for( i=0; i < TACH_SEST_LEN; i++) // for each exchange - fcChip->SEST->sgPages[i] = NULL; - - fcChip->SEST->length = TACH_SEST_LEN; // e.g. DON'T subtract one - // (TL/TS UG, pg 153) - - ulAddr = SESTdma; -#if BITS_PER_LONG > 32 - if( (ulAddr >> 32) ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n", - (void*)ulAddr); - return -1; // failed - } -#endif - fcChip->SEST->base = (ULONG)ulAddr; // copy for quick reference - - - // Now that structures are defined, - // fill in Tachyon chip registers... - - // EEEEEEEE EXCHANGE REQUEST QUEUE - - writel( fcChip->ERQ->base, - (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE)); - - writel( fcChip->ERQ->length, - (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_LENGTH)); - - - fcChip->ERQ->producerIndex = 0L; - writel( fcChip->ERQ->producerIndex, - (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX)); - - - // NOTE! write consumer index last, since the write - // causes Tachyon to process the other registers - - ulAddr = ((unsigned long)&fcChip->ERQ->consumerIndex - - (unsigned long)fcChip->ERQ) + (unsigned long) ERQdma; - - // NOTE! Tachyon DMAs to the ERQ consumer Index host - // address; must be correctly aligned - writel( (ULONG)ulAddr, - (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_CONSUMER_INDEX_ADR)); - - - - // IIIIIIIIIIIII INBOUND MESSAGE QUEUE - // Tell Tachyon where the Que starts - - // set the Host's pointer for Tachyon to access - - /* printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base ); */ - writel( fcChip->IMQ->base, - (fcChip->Registers.ReMapMemBase + IMQ_BASE)); - - writel( fcChip->IMQ->length, - (fcChip->Registers.ReMapMemBase + IMQ_LENGTH)); - - writel( fcChip->IMQ->consumerIndex, - (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX)); - - - // NOTE: TachLite DMAs to the producerIndex host address - // must be correctly aligned with address bits 1-0 cleared - // Writing the BASE register clears the PI register, so write it last - ulAddr = ((unsigned long)&fcChip->IMQ->producerIndex - - (unsigned long)fcChip->IMQ) + (unsigned long) IMQdma; - -#if BITS_PER_LONG > 32 - if( (ulAddr >> 32) ) - { - cpqfc_free_dma_consistent(cpqfcHBAdata); - printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n", - (void*)ulAddr); - return -1; // failed - } -#endif -#if DBG - printk(" PI %Xh\n", (ULONG)ulAddr ); -#endif - writel( (ULONG)ulAddr, - (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX)); - - - - // SSSSSSSSSSSSSSS SINGLE FRAME SEQUENCE - // Tell TachLite where the Que starts - - writel( fcChip->SFQ->base, - (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_BASE)); - - writel( fcChip->SFQ->length, - (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_LENGTH)); - - - // tell TachLite where SEST table is & how long - writel( fcChip->SEST->base, - (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE)); - - /* printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n", - fcChip->SEST, fcChip->SEST->base, - fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); */ - - writel( fcChip->SEST->length, - (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH)); - - writel( (TL_EXT_SG_PAGE_COUNT-1), - (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_SG_PAGE)); - - - LEAVE("CreateTachLiteQues"); - - return iStatus; -} - - - -// function to return TachLite to Power On state -// 1st - reset tachyon ('SOFT' reset) -// others - future - -int CpqTsResetTachLite(void *pHBA, int type) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - ULONG ulBuff, i; - int ret_status=0; // def. success - - ENTER("ResetTach"); - - switch(type) - { - - case CLEAR_FCPORTS: - - // in case he was running previously, mask Tach's interrupt - writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN)); - - // de-allocate mem for any Logged in ports - // (e.g., our module is unloading) - // search the forward linked list, de-allocating - // the memory we allocated when the port was initially logged in - { - PFC_LOGGEDIN_PORT pLoggedInPort = fcChip->fcPorts.pNextPort; - PFC_LOGGEDIN_PORT ptr; -// printk("checking for allocated LoggedInPorts...\n"); - - while( pLoggedInPort ) - { - ptr = pLoggedInPort; - pLoggedInPort = ptr->pNextPort; -// printk("kfree(%p) on FC LoggedInPort port_id 0x%06lX\n", -// ptr, ptr->port_id); - kfree( ptr ); - } - } - // (continue resetting hardware...) - - case 1: // RESTART Tachyon (power-up state) - - // in case he was running previously, mask Tach's interrupt - writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN)); - // turn OFF laser (NOTE: laser is turned - // off during reset, because GPIO4 is cleared - // to 0 by reset action - see TLUM, sec 7.22) - // However, CPQ 64-bit HBAs have a "health - // circuit" which keeps laser ON for a brief - // period after it is turned off ( < 1s) - - fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0); - - - - // soft reset timing constraints require: - // 1. set RST to 1 - // 2. read SOFTRST register - // (128 times per R. Callison code) - // 3. clear PCI ints - // 4. clear RST to 0 - writel( 0xff000001L, - (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST)); - - for( i=0; i<128; i++) - ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST); - - // clear the soft reset - for( i=0; i<8; i++) - writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST)); - - - - // clear out our copy of Tach regs, - // because they must be invalid now, - // since TachLite reset all his regs. - CpqTsDestroyTachLiteQues(cpqfcHBAdata,0); // remove Host-based Que structs - cpqfcTSClearLinkStatusCounters(fcChip); // clear our s/w accumulators - // lower bits give GBIC info - fcChip->Registers.TYstatus.value = - readl( fcChip->Registers.TYstatus.address ); - break; - -/* - case 2: // freeze SCSI - case 3: // reset Outbound command que (ERQ) - case 4: // unfreeze OSM (Outbound Seq. Man.) 'er' - case 5: // report status - - break; -*/ - default: - ret_status = -1; // invalid option passed to RESET function - break; - } - LEAVE("ResetTach"); - return ret_status; -} - - - - - - -// 'addrBase' is IOBaseU for both TachLite and (older) Tachyon -int CpqTsLaserControl( void* addrBase, int opcode ) -{ - ULONG dwBuff; - - dwBuff = readl((addrBase + TL_MEM_TACH_CONTROL) ); // read TL Control reg - // (change only bit 4) - if( opcode == 1) - dwBuff |= ~0xffffffefL; // set - ON - else - dwBuff &= 0xffffffefL; // clear - OFF - writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL)); // write TL Control reg - return 0; -} - - - - - -// Use controller's "Options" field to determine loopback mode (if any) -// internal loopback (silicon - no GBIC) -// external loopback (GBIC - no FC loop) -// no loopback: L_PORT, external cable from GBIC required - -int CpqTsInitializeFrameManager( void *pChip, int opcode) -{ - PTACHYON fcChip; - int iStatus; - ULONG wwnLo, wwnHi; // for readback verification - - ENTER("InitializeFrameManager"); - fcChip = (PTACHYON)pChip; - if( !fcChip->Registers.ReMapMemBase ) // undefined controller? - return -1; - - // TL/TS UG, pg. 184 - // 0x0065 = 100ms for RT_TOV - // 0x01f5 = 500ms for ED_TOV - // 0x07D1 = 2000ms - fcChip->Registers.ed_tov.value = 0x006507D1; - writel( fcChip->Registers.ed_tov.value, - (fcChip->Registers.ed_tov.address)); - - - // Set LP_TOV to the FC-AL2 specified 2 secs. - // TL/TS UG, pg. 185 - writel( 0x07d00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2); - - - // Now try to read the WWN from the adapter's NVRAM - iStatus = CpqTsReadWriteWWN( fcChip, 1); // '1' for READ - - if( iStatus ) // NVRAM read failed? - { - printk(" WARNING! HBA NVRAM WWN read failed - make alias\n"); - // make up a WWN. If NULL or duplicated on loop, FC loop may hang! - - - fcChip->Registers.wwn_hi = (__u32)jiffies; - fcChip->Registers.wwn_hi |= 0x50000000L; - fcChip->Registers.wwn_lo = 0x44556677L; - } - - - writel( fcChip->Registers.wwn_hi, - fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI); - - writel( fcChip->Registers.wwn_lo, - fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO); - - - // readback for verification: - wwnHi = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI ); - - wwnLo = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO); - // test for correct chip register WRITE/READ - DEBUG_PCI( printk(" WWN %08X%08X\n", - fcChip->Registers.wwn_hi, fcChip->Registers.wwn_lo ) ); - - if( wwnHi != fcChip->Registers.wwn_hi || - wwnLo != fcChip->Registers.wwn_lo ) - { - printk( "cpqfcTS: WorldWideName register load failed\n"); - return -1; // FAILED! - } - - - - // set Frame Manager Initialize command - fcChip->Registers.FMcontrol.value = 0x06; - - // Note: for test/debug purposes, we may use "Hard" address, - // but we completely support "soft" addressing, including - // dynamically changing our address. - if( fcChip->Options.intLoopback == 1 ) // internal loopback - fcChip->Registers.FMconfig.value = 0x0f002080L; - else if( fcChip->Options.extLoopback == 1 ) // internal loopback - fcChip->Registers.FMconfig.value = 0x0f004080L; - else // L_Port - fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start) -// fcChip->Registers.FMconfig.value = 0x01000080L; // soft address (can't pick) -// fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start) - - // write config to FM - - if( !fcChip->Options.intLoopback && !fcChip->Options.extLoopback ) - // (also need LASER for real LOOP) - fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 1); // turn on LASER - - writel( fcChip->Registers.FMconfig.value, - fcChip->Registers.FMconfig.address); - - - // issue INITIALIZE command to FM - ACTION! - writel( fcChip->Registers.FMcontrol.value, - fcChip->Registers.FMcontrol.address); - - LEAVE("InitializeFrameManager"); - - return 0; -} - - - - - -// This "look ahead" function examines the IMQ for occurrence of -// "type". Returns 1 if found, 0 if not. -static int PeekIMQEntry( PTACHYON fcChip, ULONG type) -{ - ULONG CI = fcChip->IMQ->consumerIndex; - ULONG PI = fcChip->IMQ->producerIndex; // snapshot of IMQ indexes - - while( CI != PI ) - { // proceed with search - if( (++CI) >= IMQ_LEN ) CI = 0; // rollover check - - switch( type ) - { - case ELS_LILP_FRAME: - { - // first, we need to find an Inbound Completion message, - // If we find it, check the incoming frame payload (1st word) - // for LILP frame - if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 ) - { - TachFCHDR_GCMND* fchs; -#error This is too much stack - ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame - USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL); - - CpqTsGetSFQEntry( fcChip, - SFQpi, // SFQ producer ndx - ulFibreFrame, // contiguous dest. buffer - FALSE); // DON'T update chip--this is a "lookahead" - - fchs = (TachFCHDR_GCMND*)&ulFibreFrame; - if( fchs->pl[0] == ELS_LILP_FRAME) - { - return 1; // found the LILP frame! - } - else - { - // keep looking... - } - } - } - break; - - case OUTBOUND_COMPLETION: - if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x00 ) - { - - // any OCM errors? - if( fcChip->IMQ->QEntry[CI].word[2] & 0x7a000000L ) - return 1; // found OCM error - } - break; - - - - default: - break; - } - } - return 0; // failed to find "type" -} - - -static void SetTachTOV( CPQFCHBA* cpqfcHBAdata) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - - // TL/TS UG, pg. 184 - // 0x0065 = 100ms for RT_TOV - // 0x01f5 = 500ms for ED_TOV - // 0x07d1 = 2000ms for ED_TOV - - // SANMark Level 1 requires an "initialization backoff" - // (See "SANMark Test Suite Level 1": - // initialization_timeout.fcal.SANMark-1.fc) - // We have to use 2sec, 24sec, then 128sec when login/ - // port discovery processes fail to complete. - - // when port discovery completes (logins done), we set - // ED_TOV to 500ms -- this is the normal operational case - // On the first Link Down, we'll move to 2 secs (7D1 ms) - if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x1f5) - fcChip->Registers.ed_tov.value = 0x006507D1; - - // If we get another LST after we moved TOV to 2 sec, - // increase to 24 seconds (5DC1 ms) per SANMark! - else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x7D1) - fcChip->Registers.ed_tov.value = 0x00655DC1; - - // If we get still another LST, set the max TOV (Tachyon - // has only 16 bits for ms timer, so the max is 65.5 sec) - else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x5DC1) - fcChip->Registers.ed_tov.value = 0x0065FFFF; - - writel( fcChip->Registers.ed_tov.value, - (fcChip->Registers.ed_tov.address)); - // keep the same 2sec LP_TOV - writel( 0x07D00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2); -} - - -// The IMQ is an array with IMQ_LEN length, each element (QEntry) -// with eight 32-bit words. Tachyon PRODUCES a QEntry with each -// message it wants to send to the host. The host CONSUMES IMQ entries - -// This function copies the current -// (or oldest not-yet-processed) QEntry to -// the caller, clears/ re-enables the interrupt, and updates the -// (Host) Consumer Index. -// Return value: -// 0 message processed, none remain (producer and consumer -// indexes match) -// 1 message processed, more messages remain -// -1 no message processed - none were available to process -// Remarks: -// TL/TS UG specifices that the following actions for -// INTA_L handling: -// 1. read PCI Interrupt Status register (0xff) -// 2. all IMQ messages should be processed before writing the -// IMQ consumer index. - - -int CpqTsProcessIMQEntry(void *host) -{ - struct Scsi_Host *HostAdapter = (struct Scsi_Host *)host; - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - int iStatus; - USHORT i, RPCset, DPCset; - ULONG x_ID; - ULONG ulBuff, dwStatus; - TachFCHDR_GCMND* fchs; -#error This is too much stack - ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame - UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field - - ENTER("ProcessIMQEntry"); - - - // check TachLite's IMQ producer index - - // is a new message waiting for us? - // equal indexes means empty que - - if( fcChip->IMQ->producerIndex != fcChip->IMQ->consumerIndex ) - { // need to process message - - -#ifdef IMQ_DEBUG - printk("PI %X, CI %X type: %X\n", - fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex, - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type); -#endif - // Examine Completion Messages in IMQ - // what CM_Type? - switch( (UCHAR)(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type - & 0xffL) ) - { - case OUTBOUND_COMPLETION: - - // Remarks: - // x_IDs (OX_ID, RX_ID) are partitioned by SEST entries - // (starting at 0), and SFS entries (starting at - // SEST_LEN -- outside the SEST space). - // Psuedo code: - // x_ID (OX_ID or RX_ID) from message is Trans_ID or SEST index - // range check - x_ID - // if x_ID outside 'Transactions' length, error - exit - // if any OCM error, copy error status to Exchange slot - // if FCP ASSIST transaction (x_ID within SEST), - // call fcComplete (to App) - // ... - - - ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]; - x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID - // Range check CM OX/RX_ID value... - if( x_ID < TACH_MAX_XID ) // don't go beyond array space - { - - - if( ulBuff & 0x20000000L ) // RPC -Response Phase Complete? - RPCset = 1; // (SEST transactions only) - else - RPCset = 0; - - if( ulBuff & 0x40000000L ) // DPC -Data Phase Complete? - DPCset = 1; // (SEST transactions only) - else - DPCset = 0; - // set the status for this Outbound transaction's ID - dwStatus = 0L; - if( ulBuff & 0x10000000L ) // SPE? (SEST Programming Error) - dwStatus |= SESTPROG_ERR; - - ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2]; - if( ulBuff & 0x7a000000L ) // any other errs? - { - if( ulBuff & 0x40000000L ) - dwStatus |= INV_ENTRY; - if( ulBuff & 0x20000000L ) - dwStatus |= FRAME_TO; // FTO - if( ulBuff & 0x10000000L ) - dwStatus |= HOSTPROG_ERR; - if( ulBuff & 0x08000000L ) - dwStatus |= LINKFAIL_TX; - if( ulBuff & 0x02000000L ) - dwStatus |= ABORTSEQ_NOTIFY; // ASN - } - - - if( dwStatus ) // any errors? - { - // set the Outbound Completion status - Exchanges->fcExchange[ x_ID ].status |= dwStatus; - - // if this Outbound frame was for a SEST entry, automatically - // reque it in the case of LINKFAIL (it will restart on PDISC) - if( x_ID < TACH_SEST_LEN ) - { - - printk(" #OCM error %Xh x_ID %X# ", - dwStatus, x_ID); - - Exchanges->fcExchange[x_ID].timeOut = 30000; // seconds default - - - // We Q ABTS for each exchange. - // NOTE: We can get FRAME_TO on bad alpa (device gone). Since - // bad alpa is reported before FRAME_TO, examine the status - // flags to see if the device is removed. If so, DON'T - // post an ABTS, since it will be terminated by the bad alpa - // message. - if( dwStatus & FRAME_TO ) // check for device removed... - { - if( !(Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) ) - { - // presumes device is still there: send ABTS. - - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID); - } - } - else // Abort all other errors - { - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID); - } - - // if the HPE bit is set, we have to CLose the LOOP - // (see TL/TS UG, pg. 239) - - if( dwStatus &= HOSTPROG_ERR ) - // set CL bit (see TL/TS UG, pg. 172) - writel( 4, fcChip->Registers.FMcontrol.address); - } - } - // NOTE: we don't necessarily care about ALL completion messages... - // SCSI resp. complete OR - if( ((x_ID < TACH_SEST_LEN) && RPCset)|| - (x_ID >= TACH_SEST_LEN) ) // non-SCSI command - { - // exchange done; complete to upper levels with status - // (if necessary) and free the exchange slot - - - if( x_ID >= TACH_SEST_LEN ) // Link Service Outbound frame? - // A Request or Reply has been sent - { // signal waiting WorkerThread - - up( cpqfcHBAdata->TYOBcomplete); // frame is OUT of Tach - - // WorkerThread will complete Xchng - } - else // X_ID is for FCP assist (SEST) - { - // TBD (target mode) -// fcCompleteExchange( fcChip, x_ID); // TRE completed - } - } - } - else // ERROR CONDITION! bogus x_ID in completion message - { - - printk(" ProcessIMQ (OBCM) x_id out of range %Xh\n", x_ID); - - } - - - - // Load the Frame Manager's error counters. We check them here - // because presumably the link is up and healthy enough for the - // counters to be meaningful (i.e., don't check them while loop - // is initializing). - fcChip->Registers.FMLinkStatus1.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus1.address); - - fcChip->Registers.FMLinkStatus2.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus2.address); - - - fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators - break; - - - - case ERROR_IDLE_COMPLETION: // TachLite Error Idle... - - // We usually get this when the link goes down during heavy traffic. - // For now, presume that if SEST Exchanges are open, we will - // get this as our cue to INVALIDATE all SEST entries - // (and we OWN all the SEST entries). - // See TL/TS UG, pg. 53 - - for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++) - { - - // Does this VALid SEST entry need to be invalidated for Abort? - fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF; - } - - CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachyon, if Link OK - - break; - - - case INBOUND_SFS_COMPLETION: //0x04 - // NOTE! we must process this SFQ message to avoid SFQ filling - // up and stopping TachLite. Incoming commands are placed here, - // as well as 'unknown' frames (e.g. LIP loop position data) - // write this CM's producer index to global... - // TL/TS UG, pg 234: - // Type: 0 - reserved - // 1 - Unassisted FCP - // 2 - BAD FCP - // 3 - Unkown Frame - // 4-F reserved - - - fcChip->SFQ->producerIndex = (USHORT) - (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] & 0x0fffL); - - - ucInboundMessageType = 0; // default to useless frame - - // we can only process two Types: 1, Unassisted FCP, and 3, Unknown - // Also, we aren't interested in processing frame fragments - // so don't Que anything with 'LKF' bit set - if( !(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] - & 0x40000000) ) // 'LKF' link failure bit clear? - { - ucInboundMessageType = (UCHAR) // ICM DWord3, "Type" - (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] & 0x0fL); - } - else - { - fcChip->fcStats.linkFailRX++; -// printk("LKF (link failure) bit set on inbound message\n"); - } - - // clears SFQ entry from Tachyon buffer; copies to contiguous ulBuff - CpqTsGetSFQEntry( - fcChip, // i.e. this Device Object - (USHORT)fcChip->SFQ->producerIndex, // SFQ producer ndx - ulFibreFrame, TRUE); // contiguous destination buffer, update chip - - // analyze the incoming frame outside the INT handler... - // (i.e., Worker) - - if( ucInboundMessageType == 1 ) - { - fchs = (TachFCHDR_GCMND*)ulFibreFrame; // cast to examine IB frame - // don't fill up our Q with garbage - only accept FCP-CMND - // or XRDY frames - if( (fchs->d_id & 0xFF000000) == 0x06000000 ) // CMND - { - // someone sent us a SCSI command - -// fcPutScsiQue( cpqfcHBAdata, -// SFQ_UNASSISTED_FCP, ulFibreFrame); - } - else if( ((fchs->d_id & 0xFF000000) == 0x07000000) || // RSP (status) - (fchs->d_id & 0xFF000000) == 0x05000000 ) // XRDY - { - ULONG x_ID; - // Unfortunately, ABTS requires a Freeze on the chip so - // we can modify the shared memory SEST. When frozen, - // any received Exchange frames cannot be processed by - // Tachyon, so they will be dumped in here. It is too - // complex to attempt the reconstruct these frames in - // the correct Exchange context, so we simply seek to - // find status or transfer ready frames, and cause the - // exchange to complete with errors before the timeout - // expires. We use a Linux Scsi Cmnd result code that - // causes immediate retry. - - - // Do we have an open exchange that matches this s_id - // and ox_id? - for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++) - { - if( (fchs->s_id & 0xFFFFFF) == - (Exchanges->fcExchange[x_ID].fchs.d_id & 0xFFFFFF) - && - (fchs->ox_rx_id & 0xFFFF0000) == - (Exchanges->fcExchange[x_ID].fchs.ox_rx_id & 0xFFFF0000) ) - { - // printk(" #R/X frame x_ID %08X# ", fchs->ox_rx_id ); - // simulate the anticipated error - since the - // SEST was frozen, frames were lost... - Exchanges->fcExchange[ x_ID ].status |= SFQ_FRAME; - - // presumes device is still there: send ABTS. - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID); - break; // done - } - } - } - - } - - else if( ucInboundMessageType == 3) - { - // FC Link Service frames (e.g. PLOGI, ACC) come in here. - cpqfcTSPutLinkQue( cpqfcHBAdata, SFQ_UNKNOWN, ulFibreFrame); - - } - - else if( ucInboundMessageType == 2 ) // "bad FCP"? - { -#ifdef IMQ_DEBUG - printk("Bad FCP incoming frame discarded\n"); -#endif - } - - else // don't know this type - { -#ifdef IMQ_DEBUG - printk("Incoming frame discarded, type: %Xh\n", ucInboundMessageType); -#endif - } - - // Check the Frame Manager's error counters. We check them here - // because presumably the link is up and healthy enough for the - // counters to be meaningful (i.e., don't check them while loop - // is initializing). - fcChip->Registers.FMLinkStatus1.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus1.address); - - - fcChip->Registers.FMLinkStatus2.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus2.address); - - - break; - - - - - // We get this CM because we issued a freeze - // command to stop outbound frames. We issue the - // freeze command at Link Up time; when this message - // is received, the ERQ base can be switched and PDISC - // frames can be sent. - - - case ERQ_FROZEN_COMPLETION: // note: expect ERQ followed immediately - // by FCP when freezing TL - fcChip->Registers.TYstatus.value = // read what's frozen - readl(fcChip->Registers.TYstatus.address); - // (do nothing; wait for FCP frozen message) - break; - case FCP_FROZEN_COMPLETION: - - fcChip->Registers.TYstatus.value = // read what's frozen - readl(fcChip->Registers.TYstatus.address); - - // Signal the kernel thread to proceed with SEST modification - up( cpqfcHBAdata->TachFrozen); - - break; - - - - case INBOUND_C1_TIMEOUT: - case MFS_BUF_WARN: - case IMQ_BUF_WARN: - break; - - - - - - // In older Tachyons, we 'clear' the internal 'core' interrupt state - // by reading the FMstatus register. In newer TachLite (Tachyon), - // we must WRITE the register - // to clear the condition (TL/TS UG, pg 179) - case FRAME_MGR_INTERRUPT: - { - PFC_LOGGEDIN_PORT pLoggedInPort; - - fcChip->Registers.FMstatus.value = - readl( fcChip->Registers.FMstatus.address ); - - // PROBLEM: It is possible, especially with "dumb" hubs that - // don't automatically LIP on by-pass of ports that are going - // away, for the hub by-pass process to destroy critical - // ordered sets of a frame. The result of this is a hung LPSM - // (Loop Port State Machine), which on Tachyon results in a - // (default 2 sec) Loop State Timeout (LST) FM message. We - // want to avoid this relatively huge timeout by detecting - // likely scenarios which will result in LST. - // To do this, we could examine FMstatus for Loss of Synchronization - // and/or Elastic Store (ES) errors. Of these, Elastic Store is better - // because we get this indication more quickly than the LOS. - // Not all ES errors are harmfull, so we don't want to LIP on every - // ES. Instead, on every ES, detect whether our LPSM in in one - // of the LST states: ARBITRATING, OPEN, OPENED, XMITTED CLOSE, - // or RECEIVED CLOSE. (See TL/TS UG, pg. 181) - // If any of these LPSM states are detected - // in combination with the LIP while LDn is not set, - // send an FM init (LIP F7,F7 for loops)! - // It is critical to the physical link stability NOT to reset (LIP) - // more than absolutely necessary; this is a basic premise of the - // SANMark level 1 spec. - { - ULONG Lpsm = (fcChip->Registers.FMstatus.value & 0xF0) >>4; - - if( (fcChip->Registers.FMstatus.value & 0x400) // ElasticStore? - && - !(fcChip->Registers.FMstatus.value & 0x100) // NOT LDn - && - !(fcChip->Registers.FMstatus.value & 0x1000)) // NOT LF - { - if( (Lpsm != 0) || // not MONITORING? or - !(Lpsm & 0x8) )// not already offline? - { - // now check the particular LST states... - if( (Lpsm == ARBITRATING) || (Lpsm == OPEN) || - (Lpsm == OPENED) || (Lpsm == XMITTD_CLOSE) || - (Lpsm == RCVD_CLOSE) ) - { - // re-init the loop before it hangs itself! - printk(" #req FMinit on E-S: LPSM %Xh# ",Lpsm); - - - fcChip->fcStats.FMinits++; - writel( 6, fcChip->Registers.FMcontrol.address); // LIP - } - } - } - else if( fcChip->Registers.FMstatus.value & 0x40000 ) // LST? - { - printk(" #req FMinit on LST, LPSM %Xh# ",Lpsm); - - fcChip->fcStats.FMinits++; - writel( 6, fcChip->Registers.FMcontrol.address); // LIP - } - } - - - // clear only the 'interrupting' type bits for this REG read - writel( (fcChip->Registers.FMstatus.value & 0xff3fff00L), - fcChip->Registers.FMstatus.address); - - - // copy frame manager status to unused ULONG slot - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] = - fcChip->Registers.FMstatus.value; // (for debugging) - - - // Load the Frame Manager's error counters. We check them here - // because presumably the link is up and healthy enough for the - // counters to be meaningful (i.e., don't check them while loop - // is initializing). - fcChip->Registers.FMLinkStatus1.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus1.address); - - fcChip->Registers.FMLinkStatus2.value = // get TL's counter - readl(fcChip->Registers.FMLinkStatus2.address); - - // Get FM BB_Credit Zero Reg - does not clear on READ - fcChip->Registers.FMBB_CreditZero.value = // get TL's counter - readl(fcChip->Registers.FMBB_CreditZero.address); - - - - fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators - - - // LINK DOWN - - if( fcChip->Registers.FMstatus.value & 0x100L ) // Link DOWN bit - { - -#ifdef IMQ_DEBUG - printk("LinkDn\n"); -#endif - printk(" #LDn# "); - - fcChip->fcStats.linkDown++; - - SetTachTOV( cpqfcHBAdata); // must set according to SANMark - - // Check the ERQ - force it to be "empty" to prevent Tach - // from sending out frames before we do logins. - - - if( fcChip->ERQ->producerIndex != fcChip->ERQ->consumerIndex) - { -// printk("#ERQ PI != CI#"); - CpqTsFreezeTachlite( fcChip, 1); // freeze ERQ only - fcChip->ERQ->producerIndex = fcChip->ERQ->consumerIndex = 0; - writel( fcChip->ERQ->base, - (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE)); - // re-writing base forces ERQ PI to equal CI - - } - - // link down transition occurred -- port_ids can change - // on next LinkUp, so we must invalidate current logins - // (and any I/O in progress) until PDISC or PLOGI/PRLI - // completes - { - pLoggedInPort = &fcChip->fcPorts; - while( pLoggedInPort ) // for all ports which are expecting - // PDISC after the next LIP, set the - // logoutTimer - { - - if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec? - { - pLoggedInPort->LOGO_timer = 3; // we want 2 seconds - // but Timer granularity - // is 1 second - } - // suspend any I/O in progress until - // PDISC received... - pLoggedInPort->prli = FALSE; // block FCP-SCSI commands - - pLoggedInPort = pLoggedInPort->pNextPort; - } // ... all Previously known ports checked - } - - // since any hot plugging device may NOT support LILP frames - // (such as early Tachyon chips), clear this flag indicating - // we shouldn't use (our copy of) a LILP map. - // If we receive an LILP frame, we'll set it again. - fcChip->Options.LILPin = 0; // our LILPmap is invalid - cpqfcHBAdata->PortDiscDone = 0; // must re-validate FC ports! - - // also, we want to invalidate (i.e. INITIATOR_ABORT) any - // open Login exchanges, in case the LinkDown happened in the - // middle of logins. It's possible that some ports already - // ACCepted login commands which we have not processed before - // another LinkDown occurred. Any accepted Login exhanges are - // invalidated by LinkDown, even before they are acknowledged. - // It's also possible for a port to have a Queued Reply or Request - // for login which was interrupted by LinkDown; it may come later, - // but it will be unacceptable to us. - - // we must scan the entire exchange space, find every Login type - // originated by us, and abort it. This is NOT an abort due to - // timeout, so we don't actually send abort to the other port - - // we just complete it to free up the fcExchange slot. - - for( i=TACH_SEST_LEN; i< TACH_MAX_XID; i++) - { // looking for Extended Link Serv.Exchanges - if( Exchanges->fcExchange[i].type == ELS_PDISC || - Exchanges->fcExchange[i].type == ELS_PLOGI || - Exchanges->fcExchange[i].type == ELS_PRLI ) - { - // ABORT the exchange! -#ifdef IMQ_DEBUG - printk("Originator ABORT x_id %Xh, type %Xh, port_id %Xh on LDn\n", - i, Exchanges->fcExchange[i].type, - Exchanges->fcExchange[i].fchs.d_id); -#endif - - Exchanges->fcExchange[i].status |= INITIATOR_ABORT; - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // abort on LDn - } - } - - } - - // ################ LINK UP ################## - if( fcChip->Registers.FMstatus.value & 0x200L ) // Link Up bit - { // AL_PA could have changed - - // We need the following code, duplicated from LinkDn condition, - // because it's possible for the Tachyon to re-initialize (hard - // reset) without ever getting a LinkDn indication. - pLoggedInPort = &fcChip->fcPorts; - while( pLoggedInPort ) // for all ports which are expecting - // PDISC after the next LIP, set the - // logoutTimer - { - if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec? - { - pLoggedInPort->LOGO_timer = 3; // we want 2 seconds - // but Timer granularity - // is 1 second - - // suspend any I/O in progress until - // PDISC received... - - } - pLoggedInPort = pLoggedInPort->pNextPort; - } // ... all Previously known ports checked - - // CpqTs acquired AL_PA in register AL_PA (ACQ_ALPA) - fcChip->Registers.rcv_al_pa.value = - readl(fcChip->Registers.rcv_al_pa.address); - - // Now, if our acquired address is DIFFERENT from our - // previous one, we are not allow to do PDISC - we - // must go back to PLOGI, which will terminate I/O in - // progress for ALL logged in FC devices... - // (This is highly unlikely). - - if( (fcChip->Registers.my_al_pa & 0xFF) != - ((fcChip->Registers.rcv_al_pa.value >> 16) &0xFF) ) - { - -// printk(" #our HBA port_id changed!# "); // FC port_id changed!! - - pLoggedInPort = &fcChip->fcPorts; - while( pLoggedInPort ) // for all ports which are expecting - // PDISC after the next LIP, set the - // logoutTimer - { - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; - pLoggedInPort = pLoggedInPort->pNextPort; - } // ... all Previously known ports checked - - // when the port_id changes, we must terminate - // all open exchanges. - cpqfcTSTerminateExchange( cpqfcHBAdata, NULL, PORTID_CHANGED); - - } - - // Replace the entire 24-bit port_id. We only know the - // lower 8 bits (alpa) from Tachyon; if a FLOGI is done, - // we'll get the upper 16-bits from the FLOGI ACC frame. - // If someone plugs into Fabric switch, we'll do FLOGI and - // get full 24-bit port_id; someone could then remove and - // hot-plug us into a dumb hub. If we send a 24-bit PLOGI - // to a "private" loop device, it might blow up. - // Consequently, we force the upper 16-bits of port_id to - // be re-set on every LinkUp transition - fcChip->Registers.my_al_pa = - (fcChip->Registers.rcv_al_pa.value >> 16) & 0xFF; - - - // copy frame manager status to unused ULONG slot - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] = - fcChip->Registers.my_al_pa; // (for debugging) - - // for TachLite, we need to write the acquired al_pa - // back into the FMconfig register, because after - // first initialization, the AQ (prev. acq.) bit gets - // set, causing TL FM to use the AL_PA field in FMconfig. - // (In Tachyon, FM writes the acquired AL_PA for us.) - ulBuff = readl( fcChip->Registers.FMconfig.address); - ulBuff &= 0x00ffffffL; // mask out current al_pa - ulBuff |= ( fcChip->Registers.my_al_pa << 24 ); // or in acq. al_pa - fcChip->Registers.FMconfig.value = ulBuff; // copy it back - writel( fcChip->Registers.FMconfig.value, // put in TachLite - fcChip->Registers.FMconfig.address); - - -#ifdef IMQ_DEBUG - printk("#LUp %Xh, FMstat 0x%08X#", - fcChip->Registers.my_al_pa, fcChip->Registers.FMstatus.value); -#endif - - // also set the WRITE-ONLY My_ID Register (for Fabric - // initialization) - writel( fcChip->Registers.my_al_pa, - fcChip->Registers.ReMapMemBase +TL_MEM_TACH_My_ID); - - - fcChip->fcStats.linkUp++; - - // reset TL statistics counters - // (we ignore these error counters - // while link is down) - ulBuff = // just reset TL's counter - readl( fcChip->Registers.FMLinkStatus1.address); - - ulBuff = // just reset TL's counter - readl( fcChip->Registers.FMLinkStatus2.address); - - // for initiator, need to start verifying ports (e.g. PDISC) - - - - - - - CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachlite, if Link OK - - // Tachyon creates an interesting problem for us on LILP frames. - // Instead of writing the incoming LILP frame into the SFQ before - // indicating LINK UP (the actual order of events), Tachyon tells - // us LINK UP, and later us the LILP. So we delay, then examine the - // IMQ for an Inbound CM (x04); if found, we can set - // LINKACTIVE after processing the LILP. Otherwise, just proceed. - // Since Tachyon imposes this time delay (and doesn't tell us - // what it is), we have to impose a delay before "Peeking" the IMQ - // for Tach hardware (DMA) delivery. - // Processing LILP is required by SANMark - udelay( 1000); // microsec delay waiting for LILP (if it comes) - if( PeekIMQEntry( fcChip, ELS_LILP_FRAME) ) - { // found SFQ LILP, which will post LINKACTIVE -// printk("skipping LINKACTIVE post\n"); - - } - else - cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, ulFibreFrame); - } - - - - // ******* Set Fabric Login indication ******** - if( fcChip->Registers.FMstatus.value & 0x2000 ) - { - printk(" #Fabric# "); - fcChip->Options.fabric = 1; - } - else - fcChip->Options.fabric = 0; - - - - // ******* LIP(F8,x) or BAD AL_PA? ******** - if( fcChip->Registers.FMstatus.value & 0x30000L ) - { - // copy the error AL_PAs - fcChip->Registers.rcv_al_pa.value = - readl(fcChip->Registers.rcv_al_pa.address); - - // Bad AL_PA? - if( fcChip->Registers.FMstatus.value & 0x10000L ) - { - PFC_LOGGEDIN_PORT pLoggedInPort; - - // copy "BAD" al_pa field - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] = - (fcChip->Registers.rcv_al_pa.value & 0xff00L) >> 8; - - pLoggedInPort = fcFindLoggedInPort( fcChip, - NULL, // DON'T search Scsi Nexus - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1], // port id - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - if( pLoggedInPort ) - { - // Just in case we got this BAD_ALPA because a device - // quietly disappeared (can happen on non-managed hubs such - // as the Vixel Rapport 1000), - // do an Implicit Logout. We never expect this on a Logged - // in port (but do expect it on port discovery). - // (As a reasonable alternative, this could be changed to - // simply start the implicit logout timer, giving the device - // several seconds to "come back".) - // - printk(" #BAD alpa %Xh# ", - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]); - cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort); - } - } - // LIP(f8,x)? - if( fcChip->Registers.FMstatus.value & 0x20000L ) - { - // for debugging, copy al_pa field - fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] = - (fcChip->Registers.rcv_al_pa.value & 0xffL); - // get the other port's al_pa - // (one that sent LIP(F8,?) ) - } - } - - // Elastic store err - if( fcChip->Registers.FMstatus.value & 0x400L ) - { - // don't count e-s if loop is down! - if( !(USHORT)(fcChip->Registers.FMstatus.value & 0x80) ) - fcChip->fcStats.e_stores++; - - } - } - break; - - - case INBOUND_FCP_XCHG_COMPLETION: // 0x0C - - // Remarks: - // On Tachlite TL/TS, we get this message when the data phase - // of a SEST inbound transfer is complete. For example, if a WRITE command - // was received with OX_ID 0, we might respond with XFER_RDY with - // RX_ID 8001. This would start the SEST controlled data phases. When - // all data frames are received, we get this inbound completion. This means - // we should send a status frame to complete the status phase of the - // FCP-SCSI exchange, using the same OX_ID,RX_ID that we used for data - // frames. - // See Outbound CM discussion of x_IDs - // Psuedo Code - // Get SEST index (x_ID) - // x_ID out of range, return (err condition) - // set status bits from 2nd dword - // free transactionID & SEST entry - // call fcComplete with transactionID & status - - ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0]; - x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID - // (mask out MSB "direction" bit) - // Range check CM OX/RX_ID value... - if( x_ID < TACH_SEST_LEN ) // don't go beyond SEST array space - { - -//#define FCP_COMPLETION_DBG 1 -#ifdef FCP_COMPLETION_DBG - printk(" FCP_CM x_ID %Xh, status %Xh, Cmnd %p\n", - x_ID, ulBuff, Exchanges->fcExchange[x_ID].Cmnd); -#endif - if( ulBuff & 0x08000000L ) // RPC -Response Phase Complete - or - - // time to send response frame? - RPCset = 1; // (SEST transaction) - else - RPCset = 0; - // set the status for this Inbound SCSI transaction's ID - dwStatus = 0L; - if( ulBuff & 0x70000000L ) // any errs? - { - - if( ulBuff & 0x40000000L ) - dwStatus |= LINKFAIL_RX; - - if( ulBuff & 0x20000000L ) - dwStatus |= COUNT_ERROR; - - if( ulBuff & 0x10000000L ) - dwStatus |= OVERFLOW; - } - - - // FCP transaction done - copy status - Exchanges->fcExchange[ x_ID ].status = dwStatus; - - - // Did the exchange get an FCP-RSP response frame? - // (Note the little endian/big endian FC payload difference) - - if( RPCset ) // SEST transaction Response frame rec'd - { - // complete the command in our driver... - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev,fcChip, x_ID); - - } // end "RPCset" - - else // ("target" logic) - { - // Tachlite says all data frames have been received - now it's time - // to analyze data transfer (successful?), then send a response - // frame for this exchange - - ulFibreFrame[0] = x_ID; // copy for later reference - - // if this was a TWE, we have to send satus response - if( Exchanges->fcExchange[ x_ID].type == SCSI_TWE ) - { -// fcPutScsiQue( cpqfcHBAdata, -// NEED_FCP_RSP, ulFibreFrame); // (ulFibreFrame not used here) - } - } - } - else // ERROR CONDITION! bogus x_ID in completion message - { - printk("IN FCP_XCHG: bad x_ID: %Xh\n", x_ID); - } - - break; - - - - - case INBOUND_SCSI_DATA_COMMAND: - case BAD_SCSI_FRAME: - case INB_SCSI_STATUS_COMPLETION: - case BUFFER_PROCESSED_COMPLETION: - break; - } - - // Tachyon is producing; - // we are consuming - fcChip->IMQ->consumerIndex++; // increment OUR consumerIndex - if( fcChip->IMQ->consumerIndex >= IMQ_LEN)// check for rollover - fcChip->IMQ->consumerIndex = 0L; // reset it - - - if( fcChip->IMQ->producerIndex == fcChip->IMQ->consumerIndex ) - { // all Messages are processed - - iStatus = 0; // no more messages to process - - } - else - iStatus = 1; // more messages to process - - // update TachLite's ConsumerIndex... (clears INTA_L) - // NOTE: according to TL/TS UG, the - // "host must return completion messages in sequential order". - // Does this mean one at a time, in the order received? We - // presume so. - - writel( fcChip->IMQ->consumerIndex, - (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX)); - -#if IMQ_DEBUG - printk("Process IMQ: writing consumer ndx %d\n ", - fcChip->IMQ->consumerIndex); - printk("PI %X, CI %X\n", - fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex ); -#endif - - - - } - else - { - // hmmm... why did we get interrupted/called with no message? - iStatus = -1; // nothing to process -#if IMQ_DEBUG - printk("Process IMQ: no message PI %Xh CI %Xh", - fcChip->IMQ->producerIndex, - fcChip->IMQ->consumerIndex); -#endif - } - - LEAVE("ProcessIMQEntry"); - - return iStatus; -} - - - - - -// This routine initializes Tachyon according to the following -// options (opcode1): -// 1 - RESTART Tachyon, simulate power on condition by shutting -// down laser, resetting the hardware, de-allocating all buffers; -// continue -// 2 - Config Tachyon / PCI registers; -// continue -// 3 - Allocating memory and setting Tachyon queues (write Tachyon regs); -// continue -// 4 - Config frame manager registers, initialize, turn on laser -// -// Returns: -// -1 on fatal error -// 0 on success - -int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - ULONG ulBuff; - UCHAR bBuff; - int iStatus=-1; // assume failure - - ENTER("InitializeTachLite"); - - // verify board's base address (sanity check) - - if( !fcChip->Registers.ReMapMemBase) // NULL address for card? - return -1; // FATAL error! - - - - switch( opcode1 ) - { - case 1: // restore hardware to power-on (hard) restart - - - iStatus = fcChip->ResetTachyon( - cpqfcHBAdata, opcode2); // laser off, reset hardware - // de-allocate aligned buffers - - -/* TBD // reset FC link Q (producer and consumer = 0) - fcLinkQReset(cpqfcHBAdata); - -*/ - - if( iStatus ) - break; - - case 2: // Config PCI/Tachyon registers - // NOTE: For Tach TL/TS, bit 31 must be set to 1. For TS chips, a read - // of bit 31 indicates state of M66EN signal; if 1, chip may run at - // 33-66MHz (see TL/TS UG, pg 159) - - ulBuff = 0x80000000; // TachLite Configuration Register - - writel( ulBuff, fcChip->Registers.TYconfig.address); -// ulBuff = 0x0147L; // CpqTs PCI CFGCMD register -// WritePCIConfiguration( fcChip->Backplane.bus, -// fcChip->Backplane.slot, TLCFGCMD, ulBuff, 4); -// ulBuff = 0x0L; // test! -// ReadPCIConfiguration( fcChip->Backplane.bus, -// fcChip->Backplane.slot, TLCFGCMD, &ulBuff, 4); - - // read back for reference... - fcChip->Registers.TYconfig.value = - readl( fcChip->Registers.TYconfig.address ); - - // what is the PCI bus width? - pci_read_config_byte( cpqfcHBAdata->PciDev, - 0x43, // PCIMCTR offset - &bBuff); - - fcChip->Registers.PCIMCTR = bBuff; - - // set string identifying the chip on the circuit board - - fcChip->Registers.TYstatus.value = - readl( fcChip->Registers.TYstatus.address); - - { -// Now that we are supporting multiple boards, we need to change -// this logic to check for PCI vendor/device IDs... -// for now, quick & dirty is simply checking Chip rev - - ULONG RevId = (fcChip->Registers.TYstatus.value &0x3E0)>>5; - UCHAR Minor = (UCHAR)(RevId & 0x3); - UCHAR Major = (UCHAR)((RevId & 0x1C) >>2); - - /* printk(" HBA Tachyon RevId %d.%d\n", Major, Minor); */ - if( (Major == 1) && (Minor == 2) ) - { - sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12); - - } - else if( (Major == 1) && (Minor == 3) ) - { - sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS13); - } - else if( (Major == 2) && (Minor == 1) ) - { - sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21); - } - else - sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN); - } - - - - case 3: // allocate mem, set Tachyon Que registers - iStatus = CpqTsCreateTachLiteQues( cpqfcHBAdata, opcode2); - - if( iStatus ) - break; - - // now that the Queues exist, Tach can DMA to them, so - // we can begin processing INTs - // INTEN register - enable INT (TachLite interrupt) - writeb( 0x1F, fcChip->Registers.ReMapMemBase + IINTEN); - - // Fall through - case 4: // Config Fame Manager, Init Loop Command, laser on - - // L_PORT or loopback - // depending on Options - iStatus = CpqTsInitializeFrameManager( fcChip,0 ); - if( iStatus ) - { - // failed to initialize Frame Manager - break; - } - - default: - break; - } - LEAVE("InitializeTachLite"); - - return iStatus; -} - - - - -// Depending on the type of platform memory allocation (e.g. dynamic), -// it's probably best to free memory in opposite order as it was allocated. -// Order of allocation: see other function - - -int CpqTsDestroyTachLiteQues( void *pHBA, int opcode) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - USHORT i, iStatus=0; - void* vPtr; // mem Align manager sets this to the freed address on success - unsigned long ulPtr; // for 64-bit pointer cast (e.g. Alpa machine) - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - PSGPAGES j, next; - - ENTER("DestroyTachLiteQues"); - - if( fcChip->SEST ) - { - // search out and free Pool for Extended S/G list pages - - for( i=0; i < TACH_SEST_LEN; i++) // for each exchange - { - // It's possible that extended S/G pages were allocated, mapped, and - // not cleared due to error conditions or O/S driver termination. - // Make sure they're all gone. - if (Exchanges->fcExchange[i].Cmnd != NULL) - cpqfc_pci_unmap(cpqfcHBAdata->PciDev, Exchanges->fcExchange[i].Cmnd, - fcChip, i); // undo DMA mappings. - - for (j=fcChip->SEST->sgPages[i] ; j != NULL ; j = next) { - next = j->next; - kfree(j); - } - fcChip->SEST->sgPages[i] = NULL; - } - ulPtr = (unsigned long)fcChip->SEST; - vPtr = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - 0,0, (ULONG)ulPtr, NULL ); // 'free' mem - fcChip->SEST = 0L; // null invalid ptr - if( !vPtr ) - { - printk("SEST mem not freed\n"); - iStatus = -1; - } - } - - if( fcChip->SFQ ) - { - - ulPtr = (unsigned long)fcChip->SFQ; - vPtr = fcMemManager( cpqfcHBAdata->PciDev, - &cpqfcHBAdata->dynamic_mem[0], - 0,0, (ULONG)ulPtr, NULL ); // 'free' mem - fcChip->SFQ = 0L; // null invalid ptr - if( !vPtr ) - { - printk("SFQ mem not freed\n"); - iStatus = -2; - } - } - - - if( fcChip->IMQ ) - { - // clear Indexes to show empty Queue - fcChip->IMQ->producerIndex = 0; - fcChip->IMQ->consumerIndex = 0; - - ulPtr = (unsigned long)fcChip->IMQ; - vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0], - 0,0, (ULONG)ulPtr, NULL ); // 'free' mem - fcChip->IMQ = 0L; // null invalid ptr - if( !vPtr ) - { - printk("IMQ mem not freed\n"); - iStatus = -3; - } - } - - if( fcChip->ERQ ) // release memory blocks used by the queues - { - ulPtr = (unsigned long)fcChip->ERQ; - vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0], - 0,0, (ULONG)ulPtr, NULL ); // 'free' mem - fcChip->ERQ = 0L; // null invalid ptr - if( !vPtr ) - { - printk("ERQ mem not freed\n"); - iStatus = -4; - } - } - - // free up the primary EXCHANGES struct and Link Q - cpqfc_free_dma_consistent(cpqfcHBAdata); - - LEAVE("DestroyTachLiteQues"); - - return iStatus; // non-zero (failed) if any memory not freed -} - - - - - -// The SFQ is an array with SFQ_LEN length, each element (QEntry) -// with eight 32-bit words. TachLite places incoming FC frames (i.e. -// a valid FC frame with our AL_PA ) in contiguous SFQ entries -// and sends a completion message telling the host where the frame is -// in the que. -// This function copies the current (or oldest not-yet-processed) QEntry to -// a caller's contiguous buffer and updates the Tachyon chip's consumer index -// -// NOTE: -// An FC frame may consume one or many SFQ entries. We know the total -// length from the completion message. The caller passes a buffer large -// enough for the complete message (max 2k). - -static void CpqTsGetSFQEntry( - PTACHYON fcChip, - USHORT producerNdx, - ULONG *ulDestPtr, // contiguous destination buffer - BOOLEAN UpdateChip) -{ - ULONG total_bytes=0; - ULONG consumerIndex = fcChip->SFQ->consumerIndex; - - // check passed copy of SFQ producer index - - // is a new message waiting for us? - // equal indexes means SFS is copied - - while( producerNdx != consumerIndex ) - { // need to process message - total_bytes += 64; // maintain count to prevent writing past buffer - // don't allow copies over Fibre Channel defined length! - if( total_bytes <= 2048 ) - { - memcpy( ulDestPtr, - &fcChip->SFQ->QEntry[consumerIndex], - 64 ); // each SFQ entry is 64 bytes - ulDestPtr += 16; // advance pointer to next 64 byte block - } - // Tachyon is producing, - // and we are consuming - - if( ++consumerIndex >= SFQ_LEN)// check for rollover - consumerIndex = 0L; // reset it - } - - // if specified, update the Tachlite chip ConsumerIndex... - if( UpdateChip ) - { - fcChip->SFQ->consumerIndex = consumerIndex; - writel( fcChip->SFQ->consumerIndex, - fcChip->Registers.SFQconsumerIndex.address); - } -} - - - -// TachLite routinely freezes it's core ques - Outbound FIFO, Inbound FIFO, -// and Exchange Request Queue (ERQ) on error recover - -// (e.g. whenever a LIP occurs). Here -// we routinely RESUME by clearing these bits, but only if the loop is up -// to avoid ERROR IDLE messages forever. - -void CpqTsUnFreezeTachlite( void *pChip, int type ) -{ - PTACHYON fcChip = (PTACHYON)pChip; - fcChip->Registers.TYcontrol.value = - readl(fcChip->Registers.TYcontrol.address); - - // (bit 4 of value is GBIC LASER) - // if we 'unfreeze' the core machines before the loop is healthy - // (i.e. FLT, OS, LS failure bits set in FMstatus) - // we can get 'error idle' messages forever. Verify that - // FMstatus (Link Status) is OK before unfreezing. - - if( !(fcChip->Registers.FMstatus.value & 0x07000000L) && // bits clear? - !(fcChip->Registers.FMstatus.value & 0x80 )) // Active LPSM? - { - fcChip->Registers.TYcontrol.value &= ~0x300L; // clear FEQ, FFA - if( type == 1 ) // unfreeze ERQ only - { -// printk("Unfreezing ERQ\n"); - fcChip->Registers.TYcontrol.value |= 0x10000L; // set REQ - } - else // unfreeze both ERQ and FCP-ASSIST (SEST) - { -// printk("Unfreezing ERQ & FCP-ASSIST\n"); - - // set ROF, RIF, REQ - resume Outbound FCP, Inbnd FCP, ERQ - fcChip->Registers.TYcontrol.value |= 0x70000L; // set ROF, RIF, REQ - } - - writel( fcChip->Registers.TYcontrol.value, - fcChip->Registers.TYcontrol.address); - - } - // readback for verify (TachLite still frozen?) - fcChip->Registers.TYstatus.value = - readl(fcChip->Registers.TYstatus.address); -} - - -// Whenever an FC Exchange Abort is required, we must manipulate the -// Host/Tachyon shared memory SEST table. Before doing this, we -// must freeze Tachyon, which flushes certain buffers and ensure we -// can manipulate the SEST without contention. -// This freeze function will result in FCP & ERQ FROZEN completion -// messages (per argument "type"). - -void CpqTsFreezeTachlite( void *pChip, int type ) -{ - PTACHYON fcChip = (PTACHYON)pChip; - fcChip->Registers.TYcontrol.value = - readl(fcChip->Registers.TYcontrol.address); - - //set FFA, FEQ - freezes SCSI assist and ERQ - if( type == 1) // freeze ERQ only - fcChip->Registers.TYcontrol.value |= 0x100L; // (bit 4 is laser) - else // freeze both FCP assists (SEST) and ERQ - fcChip->Registers.TYcontrol.value |= 0x300L; // (bit 4 is laser) - - writel( fcChip->Registers.TYcontrol.value, - fcChip->Registers.TYcontrol.address); - -} - - - - -// TL has two Frame Manager Link Status Registers, with three 8-bit -// fields each. These eight bit counters are cleared after each read, -// so we define six 32-bit accumulators for these TL counters. This -// function breaks out each 8-bit field and adds the value to the existing -// sum. (s/w counters cleared independently) - -void fcParseLinkStatusCounters(PTACHYON fcChip) -{ - UCHAR bBuff; - ULONG ulBuff; - - -// The BB0 timer usually increments when TL is initialized, resulting -// in an initially bogus count. If our own counter is ZERO, it means we -// are reading this thing for the first time, so we ignore the first count. -// Also, reading the register does not clear it, so we have to keep an -// additional static counter to detect rollover (yuk). - - if( fcChip->fcStats.lastBB0timer == 0L) // TL was reset? (ignore 1st values) - { - // get TL's register counter - the "last" count - fcChip->fcStats.lastBB0timer = - fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL; - } - else // subsequent pass - check for rollover - { - // "this" count - ulBuff = fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL; - if( fcChip->fcStats.lastBB0timer > ulBuff ) // rollover happened - { - // counter advanced to max... - fcChip->fcStats.BB0_Timer += (0x00FFFFFFL - fcChip->fcStats.lastBB0timer); - fcChip->fcStats.BB0_Timer += ulBuff; // plus some more - - - } - else // no rollover -- more counts or no change - { - fcChip->fcStats.BB0_Timer += (ulBuff - fcChip->fcStats.lastBB0timer); - - } - - fcChip->fcStats.lastBB0timer = ulBuff; - } - - - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 24); - fcChip->fcStats.LossofSignal += bBuff; - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 16); - fcChip->fcStats.BadRXChar += bBuff; - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 8); - fcChip->fcStats.LossofSync += bBuff; - - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 24); - fcChip->fcStats.Rx_EOFa += bBuff; - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 16); - fcChip->fcStats.Dis_Frm += bBuff; - - bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 8); - fcChip->fcStats.Bad_CRC += bBuff; -} - - -void cpqfcTSClearLinkStatusCounters(PTACHYON fcChip) -{ - ENTER("ClearLinkStatusCounters"); - memset( &fcChip->fcStats, 0, sizeof( FCSTATS)); - LEAVE("ClearLinkStatusCounters"); - -} - - - - -// The following function reads the I2C hardware to get the adapter's -// World Wide Name (WWN). -// If the WWN is "500805f1fadb43e8" (as printed on the card), the -// Tachyon WWN_hi (32-bit) register is 500805f1, and WWN_lo register -// is fadb43e8. -// In the NVRAM, the bytes appear as: -// [2d] .. -// [2e] .. -// [2f] 50 -// [30] 08 -// [31] 05 -// [32] f1 -// [33] fa -// [34] db -// [35] 43 -// [36] e8 -// -// In the Fibre Channel (Big Endian) format, the FC-AL LISM frame will -// be correctly loaded by Tachyon silicon. In the login payload, bytes -// must be correctly swapped for Big Endian format. - -int CpqTsReadWriteWWN( PVOID pChip, int Read) -{ - PTACHYON fcChip = (PTACHYON)pChip; -#define NVRAM_SIZE 512 - unsigned short i, count = NVRAM_SIZE; - UCHAR nvRam[NVRAM_SIZE], WWNbuf[8]; - ULONG ulBuff; - int iStatus=-1; // assume failure - int WWNoffset; - - ENTER("ReadWriteWWN"); - // Now try to read the WWN from the adapter's NVRAM - - if( Read ) // READing NVRAM WWN? - { - ulBuff = cpqfcTS_ReadNVRAM( fcChip->Registers.TYstatus.address, - fcChip->Registers.TYcontrol.address, - count, &nvRam[0] ); - - if( ulBuff ) // NVRAM read successful? - { - iStatus = 0; // success! - - // for engineering/ prototype boards, the data may be - // invalid (GIGO, usually all "FF"); this prevents the - // parse routine from working correctly, which means - // nothing will be written to our passed buffer. - - WWNoffset = cpqfcTS_GetNVRAM_data( WWNbuf, nvRam ); - - if( !WWNoffset ) // uninitialized NVRAM -- copy bytes directly - { - printk( "CAUTION: Copying NVRAM data on fcChip\n"); - for( i= 0; i < 8; i++) - WWNbuf[i] = nvRam[i +0x2f]; // dangerous! some formats won't work - } - - fcChip->Registers.wwn_hi = 0L; - fcChip->Registers.wwn_lo = 0L; - for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM - { - ulBuff = 0L; - ulBuff = (ULONG)(WWNbuf[i]) << (8 * (3-i)); - fcChip->Registers.wwn_hi |= ulBuff; - } - for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM - { - ulBuff = 0L; - ulBuff = (ULONG)(WWNbuf[i+4]) << (8 * (3-i)); - fcChip->Registers.wwn_lo |= ulBuff; - } - } // done reading - else - { - - printk( "cpqfcTS: NVRAM read failed\n"); - - } - } - - else // WRITE - { - - // NOTE: WRITE not supported & not used in released driver. - - - printk("ReadWriteNRAM: can't write NVRAM; aborting write\n"); - } - - LEAVE("ReadWriteWWN"); - return iStatus; -} - - - - - -// The following function reads or writes the entire "NVRAM" contents of -// the I2C hardware (i.e. the NM24C03). Note that HP's 5121A (TS 66Mhz) -// adapter does not use the NM24C03 chip, so this function only works on -// Compaq's adapters. - -int CpqTsReadWriteNVRAM( PVOID pChip, PVOID buf, int Read) -{ - PTACHYON fcChip = (PTACHYON)pChip; -#define NVRAM_SIZE 512 - ULONG ulBuff; - UCHAR *ucPtr = buf; // cast caller's void ptr to UCHAR array - int iStatus=-1; // assume failure - - - if( Read ) // READing NVRAM? - { - ulBuff = cpqfcTS_ReadNVRAM( // TRUE on success - fcChip->Registers.TYstatus.address, - fcChip->Registers.TYcontrol.address, - 256, // bytes to write - ucPtr ); // source ptr - - - if( ulBuff ) - iStatus = 0; // success - else - { -#ifdef DBG - printk( "CAUTION: NVRAM read failed\n"); -#endif - } - } // done reading - - else // WRITING NVRAM - { - - printk("cpqfcTS: WRITE of FC Controller's NVRAM disabled\n"); - } - - return iStatus; -} diff --git a/drivers/scsi/cpqfcTSi2c.c b/drivers/scsi/cpqfcTSi2c.c deleted file mode 100644 index b38a6a9a55a3..000000000000 --- a/drivers/scsi/cpqfcTSi2c.c +++ /dev/null @@ -1,493 +0,0 @@ -/* Copyright(c) 2000, Compaq Computer Corporation - * Fibre Channel Host Bus Adapter - * 64-bit, 66MHz PCI - * Originally developed and tested on: - * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... - * SP# P225CXCBFIEL6T, Rev XC - * SP# 161290-001, Rev XD - * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 - * - * 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. - * Written by Don Zimmerman -*/ -// These functions control the NVRAM I2C hardware on -// non-intelligent Fibre Host Adapters. -// The primary purpose is to read the HBA's NVRAM to get adapter's -// manufactured WWN to copy into Tachyon chip registers -// Orignal source author unknown - -#include -enum boolean { FALSE, TRUE } ; - - -#ifndef UCHAR -typedef __u8 UCHAR; -#endif -#ifndef BOOLEAN -typedef __u8 BOOLEAN; -#endif -#ifndef USHORT -typedef __u16 USHORT; -#endif -#ifndef ULONG -typedef __u32 ULONG; -#endif - - -#include -#include -#include -#include -#include // struct pt_regs for IRQ handler & Port I/O - -#include "cpqfcTSchip.h" - -static void tl_i2c_tx_byte( void* GPIOout, UCHAR data ); -/*static BOOLEAN tl_write_i2c_page_portion( void* GPIOin, void* GPIOout, - USHORT startOffset, // e.g. 0x2f for WWN start - USHORT count, - UCHAR *buf ); -*/ - -// -// Tachlite GPIO2, GPIO3 (I2C) DEFINES -// The NVRAM chip NM24C03 defines SCL (serial clock) and SDA (serial data) -// GPIO2 drives SDA, and GPIO3 drives SCL -// -// Since Tachlite inverts the state of the GPIO 0-3 outputs, SET writes 0 -// and clear writes 1. The input lines (read in TL status) is NOT inverted -// This really helps confuse the code and debugging. - -#define SET_DATA_HI 0x0 -#define SET_DATA_LO 0x8 -#define SET_CLOCK_HI 0x0 -#define SET_CLOCK_LO 0x4 - -#define SENSE_DATA_HI 0x8 -#define SENSE_DATA_LO 0x0 -#define SENSE_CLOCK_HI 0x4 -#define SENSE_CLOCK_LO 0x0 - -#define SLAVE_READ_ADDRESS 0xA1 -#define SLAVE_WRITE_ADDRESS 0xA0 - - -static void i2c_delay(ULONG mstime); -static void tl_i2c_clock_pulse( UCHAR , void* GPIOout); -static UCHAR tl_read_i2c_data( void* ); - - -//----------------------------------------------------------------------------- -// -// Name: I2C_RX_ACK -// -// This routine receives an acknowledge over the I2C bus. -// -//----------------------------------------------------------------------------- -static unsigned short tl_i2c_rx_ack( void* GPIOin, void* GPIOout ) -{ - unsigned long value; - - // do clock pulse, let data line float high - tl_i2c_clock_pulse( SET_DATA_HI, GPIOout ); - - // slave must drive data low for acknowledge - value = tl_read_i2c_data( GPIOin); - if (value & SENSE_DATA_HI ) - return( FALSE ); - - return( TRUE ); -} -//----------------------------------------------------------------------------- -// -// Name: READ_I2C_REG -// -// This routine reads the I2C control register using the global -// IO address stored in gpioreg. -// -//----------------------------------------------------------------------------- -static UCHAR tl_read_i2c_data( void* gpioreg ) -{ - return( (UCHAR)(readl( gpioreg ) & 0x08L) ); // GPIO3 -} -//----------------------------------------------------------------------------- -// -// Name: WRITE_I2C_REG -// -// This routine writes the I2C control register using the global -// IO address stored in gpioreg. -// In Tachlite, we don't want to modify other bits in TL Control reg. -// -//----------------------------------------------------------------------------- -static void tl_write_i2c_reg( void* gpioregOUT, UCHAR value ) -{ - ULONG temp; - - // First read the register and clear out the old bits - temp = readl( gpioregOUT ) & 0xfffffff3L; - - // Now or in the new data and send it back out - writel( temp | value, gpioregOUT); -} -//----------------------------------------------------------------------------- -// -// Name: I2C_TX_START -// -// This routine transmits a start condition over the I2C bus. -// 1. Set SCL (clock, GPIO2) HIGH, set SDA (data, GPIO3) HIGH, -// wait 5us to stabilize. -// 2. With SCL still HIGH, drive SDA low. The low transition marks -// the start condition to NM24Cxx (the chip) -// NOTE! In TL control reg., output 1 means chip sees LOW -// -//----------------------------------------------------------------------------- -static unsigned short tl_i2c_tx_start( void* GPIOin, void* GPIOout ) -{ - unsigned short i; - ULONG value; - - if ( !(tl_read_i2c_data(GPIOin) & SENSE_DATA_HI)) - { - // start with clock high, let data float high - tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI ); - - // keep sending clock pulses if slave is driving data line - for (i = 0; i < 10; i++) - { - tl_i2c_clock_pulse( SET_DATA_HI, GPIOout ); - - if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI ) - break; - } - - // if he's still driving data low after 10 clocks, abort - value = tl_read_i2c_data( GPIOin ); // read status - if (!(value & 0x08) ) - return( FALSE ); - } - - - // To START, bring data low while clock high - tl_write_i2c_reg( GPIOout, SET_CLOCK_HI | SET_DATA_LO ); - - i2c_delay(0); - - return( TRUE ); // TX start successful -} -//----------------------------------------------------------------------------- -// -// Name: I2C_TX_STOP -// -// This routine transmits a stop condition over the I2C bus. -// -//----------------------------------------------------------------------------- - -static unsigned short tl_i2c_tx_stop( void* GPIOin, void* GPIOout ) -{ - int i; - - for (i = 0; i < 10; i++) - { - // Send clock pulse, drive data line low - tl_i2c_clock_pulse( SET_DATA_LO, GPIOout ); - - // To STOP, bring data high while clock high - tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI ); - - // Give the data line time to float high - i2c_delay(0); - - // If slave is driving data line low, there's a problem; retry - if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI ) - return( TRUE ); // TX STOP successful! - } - - return( FALSE ); // error -} -//----------------------------------------------------------------------------- -// -// Name: I2C_TX_uchar -// -// This routine transmits a byte across the I2C bus. -// -//----------------------------------------------------------------------------- -static void tl_i2c_tx_byte( void* GPIOout, UCHAR data ) -{ - UCHAR bit; - - for (bit = 0x80; bit; bit >>= 1) - { - if( data & bit ) - tl_i2c_clock_pulse( (UCHAR)SET_DATA_HI, GPIOout); - else - tl_i2c_clock_pulse( (UCHAR)SET_DATA_LO, GPIOout); - } -} -//----------------------------------------------------------------------------- -// -// Name: I2C_RX_uchar -// -// This routine receives a byte across the I2C bus. -// -//----------------------------------------------------------------------------- -static UCHAR tl_i2c_rx_byte( void* GPIOin, void* GPIOout ) -{ - UCHAR bit; - UCHAR data = 0; - - - for (bit = 0x80; bit; bit >>= 1) { - // do clock pulse, let data line float high - tl_i2c_clock_pulse( SET_DATA_HI, GPIOout ); - - // read data line - if ( tl_read_i2c_data( GPIOin) & 0x08 ) - data |= bit; - } - - return (data); -} -//***************************************************************************** -//***************************************************************************** -// Function: read_i2c_nvram -// Arguments: UCHAR count number of bytes to read -// UCHAR *buf area to store the bytes read -// Returns: 0 - failed -// 1 - success -//***************************************************************************** -//***************************************************************************** -unsigned long cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count, - UCHAR *buf ) -{ - unsigned short i; - - if( !( tl_i2c_tx_start(GPIOin, GPIOout) )) - return FALSE; - - // Select the NVRAM for "dummy" write, to set the address - tl_i2c_tx_byte( GPIOout , SLAVE_WRITE_ADDRESS ); - if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) ) - return( FALSE ); - - // Now send the address where we want to start reading - tl_i2c_tx_byte( GPIOout , 0 ); - if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) ) - return( FALSE ); - - // Send a repeated start condition and select the - // slave for reading now. - if( tl_i2c_tx_start(GPIOin, GPIOout) ) - tl_i2c_tx_byte( GPIOout, SLAVE_READ_ADDRESS ); - - if ( !tl_i2c_rx_ack(GPIOin, GPIOout) ) - return( FALSE ); - - // this loop will now read out the data and store it - // in the buffer pointed to by buf - for ( i=0; i> 3; - if (name == 0x0F) - done = TRUE; - } - else - { - name = z & 0x7F; - len = 3 + data_ptr[i+1] + (data_ptr[i+2] << 8); - - switch (name) - { - case 0x0D: - // - j = i + 3; - // - if ( data_ptr[j] == 0x3b ) { - len = 6; - break; - } - - while ( j<(i+len) ) { - sub_name = (data_ptr[j] & 0x3f); - sub_len = data_ptr[j+1] + - (data_ptr[j+2] << 8); - ptr_inc = sub_len + 3; - switch (sub_name) - { - case 0x3C: - memcpy( wwnbuf, &data_ptr[j+3], 8); - iReturn = j+3; - break; - default: - break; - } - j += ptr_inc; - } - break; - default: - break; - } - } - // - i += len; - } // end while - return iReturn; -} - - - - - -// define a short 5 micro sec delay, and longer (ms) delay - -static void i2c_delay(ULONG mstime) -{ - ULONG i; - -// NOTE: we only expect to use these delays when reading -// our adapter's NVRAM, which happens only during adapter reset. -// Delay technique from "Linux Device Drivers", A. Rubini -// (1st Ed.) pg 137. - -// printk(" delay %lx ", mstime); - if( mstime ) // ms delay? - { - // delay technique - for( i=0; i < mstime; i++) - udelay(1000); // 1ms per loop - - } - else // 5 micro sec delay - - udelay( 5 ); // micro secs - -// printk("done\n"); -} - - - diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c deleted file mode 100644 index 3fda8d455c5b..000000000000 --- a/drivers/scsi/cpqfcTSinit.c +++ /dev/null @@ -1,2096 +0,0 @@ -/* Copyright(c) 2000, Compaq Computer Corporation - * Fibre Channel Host Bus Adapter - * 64-bit, 66MHz PCI - * Originally developed and tested on: - * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... - * SP# P225CXCBFIEL6T, Rev XC - * SP# 161290-001, Rev XD - * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 - * - * 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. - * Written by Don Zimmerman - * IOCTL and procfs added by Jouke Numan - * SMP testing by Chel Van Gennip - * - * portions copied from: - * QLogic CPQFCTS SCSI-FCP - * Written by Erik H. Moe, ehm@cris.com - * Copyright 1995, Erik H. Moe - * Renamed and updated to 1.3.x by Michael Griffith - * Chris Loveland to support the isp2100 and isp2200 -*/ - - -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // request_region() prototype -#include - -#include -#include // ioctl related -#include -#include -#include "scsi.h" -#include -#include -#include "cpqfcTSchip.h" -#include "cpqfcTSstructs.h" -#include "cpqfcTStrigger.h" - -#include "cpqfcTS.h" - -/* Embedded module documentation macros - see module.h */ -MODULE_AUTHOR("Compaq Computer Corporation"); -MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA v. 2.5.4"); -MODULE_LICENSE("GPL"); - -int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, unsigned int reset_flags); - -// This struct was originally defined in -// /usr/src/linux/include/linux/proc_fs.h -// since it's only partially implemented, we only use first -// few fields... -// NOTE: proc_fs changes in 2.4 kernel - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27) -static struct proc_dir_entry proc_scsi_cpqfcTS = -{ - PROC_SCSI_CPQFCTS, // ushort low_ino (enumerated list) - 7, // ushort namelen - DEV_NAME, // const char* name - S_IFDIR | S_IRUGO | S_IXUGO, // mode_t mode - 2 // nlink_t nlink - // etc. ... -}; - - -#endif - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) -# define CPQFC_DECLARE_COMPLETION(x) DECLARE_COMPLETION(x) -# define CPQFC_WAITING waiting -# define CPQFC_COMPLETE(x) complete(x) -# define CPQFC_WAIT_FOR_COMPLETION(x) wait_for_completion(x); -#else -# define CPQFC_DECLARE_COMPLETION(x) DECLARE_MUTEX_LOCKED(x) -# define CPQFC_WAITING sem -# define CPQFC_COMPLETE(x) up(x) -# define CPQFC_WAIT_FOR_COMPLETION(x) down(x) -#endif - -static int cpqfc_alloc_private_data_pool(CPQFCHBA *hba); - -/* local function to load our per-HBA (local) data for chip - registers, FC link state, all FC exchanges, etc. - - We allocate space and compute address offsets for the - most frequently accessed addresses; others (like World Wide - Name) are not necessary. -*/ -static void Cpqfc_initHBAdata(CPQFCHBA *cpqfcHBAdata, struct pci_dev *PciDev ) -{ - - cpqfcHBAdata->PciDev = PciDev; // copy PCI info ptr - - // since x86 port space is 64k, we only need the lower 16 bits - cpqfcHBAdata->fcChip.Registers.IOBaseL = - PciDev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; - - cpqfcHBAdata->fcChip.Registers.IOBaseU = - PciDev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK; - - // 32-bit memory addresses - cpqfcHBAdata->fcChip.Registers.MemBase = - PciDev->resource[3].start & PCI_BASE_ADDRESS_MEM_MASK; - - cpqfcHBAdata->fcChip.Registers.ReMapMemBase = - ioremap( PciDev->resource[3].start & PCI_BASE_ADDRESS_MEM_MASK, - 0x200); - - cpqfcHBAdata->fcChip.Registers.RAMBase = - PciDev->resource[4].start; - - cpqfcHBAdata->fcChip.Registers.SROMBase = // NULL for HP TS adapter - PciDev->resource[5].start; - - // now the Tachlite chip registers - // the REGISTER struct holds both the physical address & last - // written value (some TL registers are WRITE ONLY) - - cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_SFQ_CONSUMER_INDEX; - - cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX; - - // TL Frame Manager - cpqfcHBAdata->fcChip.Registers.FMconfig.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONFIG; - cpqfcHBAdata->fcChip.Registers.FMcontrol.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONTROL; - cpqfcHBAdata->fcChip.Registers.FMstatus.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_STATUS; - cpqfcHBAdata->fcChip.Registers.FMLinkStatus1.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT1; - cpqfcHBAdata->fcChip.Registers.FMLinkStatus2.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT2; - cpqfcHBAdata->fcChip.Registers.FMBB_CreditZero.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_BB_CREDIT0; - - // TL Control Regs - cpqfcHBAdata->fcChip.Registers.TYconfig.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONFIG; - cpqfcHBAdata->fcChip.Registers.TYcontrol.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONTROL; - cpqfcHBAdata->fcChip.Registers.TYstatus.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_STATUS; - cpqfcHBAdata->fcChip.Registers.rcv_al_pa.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_RCV_AL_PA; - cpqfcHBAdata->fcChip.Registers.ed_tov.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_ED_TOV; - - - cpqfcHBAdata->fcChip.Registers.INTEN.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTEN; - cpqfcHBAdata->fcChip.Registers.INTPEND.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTPEND; - cpqfcHBAdata->fcChip.Registers.INTSTAT.address = - cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTSTAT; - - DEBUG_PCI(printk(" cpqfcHBAdata->fcChip.Registers. :\n")); - DEBUG_PCI(printk(" IOBaseL = %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseL)); - DEBUG_PCI(printk(" IOBaseU = %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseU)); - - /* printk(" ioremap'd Membase: %p\n", cpqfcHBAdata->fcChip.Registers.ReMapMemBase); */ - - DEBUG_PCI(printk(" SFQconsumerIndex.address = %p\n", - cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address)); - DEBUG_PCI(printk(" ERQproducerIndex.address = %p\n", - cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address)); - DEBUG_PCI(printk(" TYconfig.address = %p\n", - cpqfcHBAdata->fcChip.Registers.TYconfig.address)); - DEBUG_PCI(printk(" FMconfig.address = %p\n", - cpqfcHBAdata->fcChip.Registers.FMconfig.address)); - DEBUG_PCI(printk(" FMcontrol.address = %p\n", - cpqfcHBAdata->fcChip.Registers.FMcontrol.address)); - - // set default options for FC controller (chip) - cpqfcHBAdata->fcChip.Options.initiator = 1; // default: SCSI initiator - cpqfcHBAdata->fcChip.Options.target = 0; // default: SCSI target - cpqfcHBAdata->fcChip.Options.extLoopback = 0;// default: no loopback @GBIC - cpqfcHBAdata->fcChip.Options.intLoopback = 0;// default: no loopback inside chip - - // set highest and lowest FC-PH version the adapter/driver supports - // (NOT strict compliance) - cpqfcHBAdata->fcChip.highest_FCPH_ver = FC_PH3; - cpqfcHBAdata->fcChip.lowest_FCPH_ver = FC_PH43; - - // set function points for this controller / adapter - cpqfcHBAdata->fcChip.ResetTachyon = CpqTsResetTachLite; - cpqfcHBAdata->fcChip.FreezeTachyon = CpqTsFreezeTachlite; - cpqfcHBAdata->fcChip.UnFreezeTachyon = CpqTsUnFreezeTachlite; - cpqfcHBAdata->fcChip.CreateTachyonQues = CpqTsCreateTachLiteQues; - cpqfcHBAdata->fcChip.DestroyTachyonQues = CpqTsDestroyTachLiteQues; - cpqfcHBAdata->fcChip.InitializeTachyon = CpqTsInitializeTachLite; - cpqfcHBAdata->fcChip.LaserControl = CpqTsLaserControl; - cpqfcHBAdata->fcChip.ProcessIMQEntry = CpqTsProcessIMQEntry; - cpqfcHBAdata->fcChip.InitializeFrameManager = CpqTsInitializeFrameManager; - cpqfcHBAdata->fcChip.ReadWriteWWN = CpqTsReadWriteWWN; - cpqfcHBAdata->fcChip.ReadWriteNVRAM = CpqTsReadWriteNVRAM; - - if (cpqfc_alloc_private_data_pool(cpqfcHBAdata) != 0) { - printk(KERN_WARNING - "cpqfc: unable to allocate pool for passthru ioctls. " - "Passthru ioctls disabled.\n"); - } -} - - -/* (borrowed from linux/drivers/scsi/hosts.c) */ -static void launch_FCworker_thread(struct Scsi_Host *HostAdapter) -{ - DECLARE_MUTEX_LOCKED(sem); - - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - - ENTER("launch_FC_worker_thread"); - - cpqfcHBAdata->notify_wt = &sem; - - /* must unlock before kernel_thread(), for it may cause a reschedule. */ - spin_unlock_irq(HostAdapter->host_lock); - kernel_thread((int (*)(void *))cpqfcTSWorkerThread, - (void *) HostAdapter, 0); - /* - * Now wait for the kernel error thread to initialize itself - - */ - down (&sem); - spin_lock_irq(HostAdapter->host_lock); - cpqfcHBAdata->notify_wt = NULL; - - LEAVE("launch_FC_worker_thread"); - -} - - -/* "Entry" point to discover if any supported PCI - bus adapter can be found -*/ -/* We're supporting: - * Compaq 64-bit, 66MHz HBA with Tachyon TS - * Agilent XL2 - * HP Tachyon - */ -#define HBA_TYPES 3 - -#ifndef PCI_DEVICE_ID_COMPAQ_ -#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc -#endif - -static struct SupportedPCIcards cpqfc_boards[] __initdata = { - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TACHYON}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_TACHLITE}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_TACHYON}, -}; - - -int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate) -{ - int NumberOfAdapters=0; // how many of our PCI adapters are found? - struct pci_dev *PciDev = NULL; - struct Scsi_Host *HostAdapter = NULL; - CPQFCHBA *cpqfcHBAdata = NULL; - struct timer_list *cpqfcTStimer = NULL; - int i; - - ENTER("cpqfcTS_detect"); - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27) - ScsiHostTemplate->proc_dir = &proc_scsi_cpqfcTS; -#else - ScsiHostTemplate->proc_name = "cpqfcTS"; -#endif - - for( i=0; i < HBA_TYPES; i++) - { - // look for all HBAs of each type - - while((PciDev = pci_find_device(cpqfc_boards[i].vendor_id, - cpqfc_boards[i].device_id, PciDev))) - { - - if (pci_enable_device(PciDev)) { - printk(KERN_ERR - "cpqfc: can't enable PCI device at %s\n", pci_name(PciDev)); - goto err_continue; - } - - if (pci_set_dma_mask(PciDev, CPQFCTS_DMA_MASK) != 0) { - printk(KERN_WARNING - "cpqfc: HBA cannot support required DMA mask, skipping.\n"); - goto err_disable_dev; - } - - // NOTE: (kernel 2.2.12-32) limits allocation to 128k bytes... - /* printk(" scsi_register allocating %d bytes for FC HBA\n", - (ULONG)sizeof(CPQFCHBA)); */ - - HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) ); - - if(HostAdapter == NULL) { - printk(KERN_WARNING - "cpqfc: can't register SCSI HBA, skipping.\n"); - goto err_disable_dev; - } - DEBUG_PCI( printk(" HBA found!\n")); - DEBUG_PCI( printk(" HostAdapter->PciDev->irq = %u\n", PciDev->irq) ); - DEBUG_PCI(printk(" PciDev->baseaddress[0]= %lx\n", - PciDev->resource[0].start)); - DEBUG_PCI(printk(" PciDev->baseaddress[1]= %lx\n", - PciDev->resource[1].start)); - DEBUG_PCI(printk(" PciDev->baseaddress[2]= %lx\n", - PciDev->resource[2].start)); - DEBUG_PCI(printk(" PciDev->baseaddress[3]= %lx\n", - PciDev->resource[3].start)); - - HostAdapter->irq = PciDev->irq; // copy for Scsi layers - - // HP Tachlite uses two (255-byte) ranges of Port I/O (lower & upper), - // for a total I/O port address space of 512 bytes. - // mask out the I/O port address (lower) & record - HostAdapter->io_port = (unsigned int) - PciDev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; - HostAdapter->n_io_port = 0xff; - - // i.e., expect 128 targets (arbitrary number), while the - // RA-4000 supports 32 LUNs - HostAdapter->max_id = 0; // incremented as devices log in - HostAdapter->max_lun = CPQFCTS_MAX_LUN; // LUNs per FC device - HostAdapter->max_channel = CPQFCTS_MAX_CHANNEL; // multiple busses? - - // get the pointer to our HBA specific data... (one for - // each HBA on the PCI bus(ses)). - cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - - // make certain our data struct is clear - memset( cpqfcHBAdata, 0, sizeof( CPQFCHBA ) ); - - - // initialize our HBA info - cpqfcHBAdata->HBAnum = NumberOfAdapters; - - cpqfcHBAdata->HostAdapter = HostAdapter; // back ptr - Cpqfc_initHBAdata( cpqfcHBAdata, PciDev ); // fill MOST fields - - cpqfcHBAdata->HBAnum = NumberOfAdapters; - spin_lock_init(&cpqfcHBAdata->hba_spinlock); - - // request necessary resources and check for conflicts - if( request_irq( HostAdapter->irq, - cpqfcTS_intr_handler, - SA_INTERRUPT | SA_SHIRQ, - DEV_NAME, - HostAdapter) ) - { - printk(KERN_WARNING "cpqfc: IRQ %u already used\n", HostAdapter->irq); - goto err_unregister; - } - - // Since we have two 256-byte I/O port ranges (upper - // and lower), check them both - if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, - 0xff, DEV_NAME ) ) - { - printk(KERN_WARNING "cpqfc: address in use: %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseU); - goto err_free_irq; - } - - if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, - 0xff, DEV_NAME ) ) - { - printk(KERN_WARNING "cpqfc: address in use: %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseL); - goto err_release_region_U; - } - - // OK, we have grabbed everything we need now. - DEBUG_PCI(printk(" Reserved 255 I/O addresses @ %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseL )); - DEBUG_PCI(printk(" Reserved 255 I/O addresses @ %x\n", - cpqfcHBAdata->fcChip.Registers.IOBaseU )); - - - - // start our kernel worker thread - - spin_lock_irq(HostAdapter->host_lock); - launch_FCworker_thread(HostAdapter); - - - // start our TimerTask... - - cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer; - - init_timer( cpqfcTStimer); // Linux clears next/prev values - cpqfcTStimer->expires = jiffies + HZ; // one second - cpqfcTStimer->data = (unsigned long)cpqfcHBAdata; // this adapter - cpqfcTStimer->function = cpqfcTSheartbeat; // handles timeouts, housekeeping - - add_timer( cpqfcTStimer); // give it to Linux - - - // now initialize our hardware... - if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) { - printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n"); - goto err_release_region_L; - } - - cpqfcHBAdata->fcStatsTime = jiffies; // (for FC Statistics delta) - - // give our HBA time to initialize and login current devices... - { - // The Brocade switch (e.g. 2400, 2010, etc.) as of March 2000, - // has the following algorithm for FL_Port startup: - // Time(sec) Action - // 0: Device Plugin and LIP(F7,F7) transmission - // 1.0 LIP incoming - // 1.027 LISA incoming, no CLS! (link not up) - // 1.028 NOS incoming (switch test for N_Port) - // 1.577 ED_TOV expired, transmit LIPs again - // 3.0 LIP(F8,F7) incoming (switch passes Tach Prim.Sig) - // 3.028 LILP received, link up, FLOGI starts - // slowest(worst) case, measured on 1Gb Finisar GT analyzer - - unsigned long stop_time; - - spin_unlock_irq(HostAdapter->host_lock); - stop_time = jiffies + 4*HZ; - while ( time_before(jiffies, stop_time) ) - schedule(); // (our worker task needs to run) - - } - - spin_lock_irq(HostAdapter->host_lock); - NumberOfAdapters++; - spin_unlock_irq(HostAdapter->host_lock); - - continue; - -err_release_region_L: - release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff ); -err_release_region_U: - release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff ); -err_free_irq: - free_irq( HostAdapter->irq, HostAdapter); -err_unregister: - scsi_unregister( HostAdapter); -err_disable_dev: - pci_disable_device( PciDev ); -err_continue: - continue; - } // end of while() - } - - LEAVE("cpqfcTS_detect"); - - return NumberOfAdapters; -} - -#ifdef SUPPORT_RESET -static void my_ioctl_done (Scsi_Cmnd * SCpnt) -{ - struct request * req; - - req = SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (req->CPQFC_WAITING != NULL) - CPQFC_COMPLETE(req->CPQFC_WAITING); -} -#endif - -static int cpqfc_alloc_private_data_pool(CPQFCHBA *hba) -{ - hba->private_data_bits = NULL; - hba->private_data_pool = NULL; - hba->private_data_bits = - kmalloc(((CPQFC_MAX_PASSTHRU_CMDS+BITS_PER_LONG-1) / - BITS_PER_LONG)*sizeof(unsigned long), - GFP_KERNEL); - if (hba->private_data_bits == NULL) - return -1; - memset(hba->private_data_bits, 0, - ((CPQFC_MAX_PASSTHRU_CMDS+BITS_PER_LONG-1) / - BITS_PER_LONG)*sizeof(unsigned long)); - hba->private_data_pool = kmalloc(sizeof(cpqfc_passthru_private_t) * - CPQFC_MAX_PASSTHRU_CMDS, GFP_KERNEL); - if (hba->private_data_pool == NULL) { - kfree(hba->private_data_bits); - hba->private_data_bits = NULL; - return -1; - } - return 0; -} - -static void cpqfc_free_private_data_pool(CPQFCHBA *hba) -{ - kfree(hba->private_data_bits); - kfree(hba->private_data_pool); -} - -int is_private_data_of_cpqfc(CPQFCHBA *hba, void *pointer) -{ - /* Is pointer within our private data pool? - We use Scsi_Request->upper_private_data (normally - reserved for upper layer drivers, e.g. the sg driver) - We check to see if the pointer is ours by looking at - its address. Is this ok? Hmm, it occurs to me that - a user app might do something bad by using sg to send - a cpqfc passthrough ioctl with upper_data_private - forged to be somewhere in our pool..., though they'd - normally have to be root already to do this. */ - - return (pointer != NULL && - pointer >= (void *) hba->private_data_pool && - pointer < (void *) hba->private_data_pool + - sizeof(*hba->private_data_pool) * - CPQFC_MAX_PASSTHRU_CMDS); -} - -cpqfc_passthru_private_t *cpqfc_alloc_private_data(CPQFCHBA *hba) -{ - int i; - - do { - i = find_first_zero_bit(hba->private_data_bits, - CPQFC_MAX_PASSTHRU_CMDS); - if (i == CPQFC_MAX_PASSTHRU_CMDS) - return NULL; - } while ( test_and_set_bit(i & (BITS_PER_LONG - 1), - hba->private_data_bits+(i/BITS_PER_LONG)) != 0); - return &hba->private_data_pool[i]; -} - -void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data) -{ - int i; - i = data - hba->private_data_pool; - clear_bit(i&(BITS_PER_LONG-1), - hba->private_data_bits+(i/BITS_PER_LONG)); -} - -int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg) -{ - int result = 0; - struct Scsi_Host *HostAdapter = ScsiDev->host; - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - PFC_LOGGEDIN_PORT pLoggedInPort = NULL; - struct scsi_cmnd *DumCmnd; - int i, j; - VENDOR_IOCTL_REQ ioc; - cpqfc_passthru_t *vendor_cmd; - Scsi_Device *SDpnt; - Scsi_Request *ScsiPassThruReq; - cpqfc_passthru_private_t *privatedata; - - ENTER("cpqfcTS_ioctl "); - - // printk("ioctl CMND %d", Cmnd); - switch (Cmnd) { - // Passthrough provides a mechanism to bypass the RAID - // or other controller and talk directly to the devices - // (e.g. physical disk drive) - // Passthrough commands, unfortunately, tend to be vendor - // specific; this is tailored to COMPAQ's RAID (RA4x00) - case CPQFCTS_SCSI_PASSTHRU: - { - void *buf = NULL; // for kernel space buffer for user data - - /* Check that our pool got allocated ok. */ - if (cpqfcHBAdata->private_data_pool == NULL) - return -ENOMEM; - - if( !arg) - return -EINVAL; - - // must be super user to send stuff directly to the - // controller and/or physical drives... - if( !capable(CAP_SYS_RAWIO) ) - return -EPERM; - - // copy the caller's struct to our space. - if( copy_from_user( &ioc, arg, sizeof( VENDOR_IOCTL_REQ))) - return( -EFAULT); - - vendor_cmd = ioc.argp; // i.e., CPQ specific command struct - - // If necessary, grab a kernel/DMA buffer - if( vendor_cmd->len) - { - buf = kmalloc( vendor_cmd->len, GFP_KERNEL); - if( !buf) - return -ENOMEM; - } - // Now build a Scsi_Request to pass down... - ScsiPassThruReq = scsi_allocate_request(ScsiDev, GFP_KERNEL); - if (ScsiPassThruReq == NULL) { - kfree(buf); - return -ENOMEM; - } - ScsiPassThruReq->upper_private_data = - cpqfc_alloc_private_data(cpqfcHBAdata); - if (ScsiPassThruReq->upper_private_data == NULL) { - kfree(buf); - scsi_release_request(ScsiPassThruReq); // "de-allocate" - return -ENOMEM; - } - - if (vendor_cmd->rw_flag == VENDOR_WRITE_OPCODE) { - if (vendor_cmd->len) { // Need data from user? - if (copy_from_user(buf, vendor_cmd->bufp, - vendor_cmd->len)) { - kfree(buf); - cpqfc_free_private_data(cpqfcHBAdata, - ScsiPassThruReq->upper_private_data); - scsi_release_request(ScsiPassThruReq); - return( -EFAULT); - } - } - ScsiPassThruReq->sr_data_direction = DMA_TO_DEVICE; - } else if (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) { - ScsiPassThruReq->sr_data_direction = DMA_FROM_DEVICE; - } else - // maybe this means a bug in the user app - ScsiPassThruReq->sr_data_direction = DMA_BIDIRECTIONAL; - - ScsiPassThruReq->sr_cmd_len = 0; // set correctly by scsi_do_req() - ScsiPassThruReq->sr_sense_buffer[0] = 0; - ScsiPassThruReq->sr_sense_buffer[2] = 0; - - // We copy the scheme used by sd.c:spinup_disk() to submit commands - // to our own HBA. We do this in order to stall the - // thread calling the IOCTL until it completes, and use - // the same "_quecommand" function for synchronizing - // FC Link events with our "worker thread". - - privatedata = ScsiPassThruReq->upper_private_data; - privatedata->bus = vendor_cmd->bus; - privatedata->pdrive = vendor_cmd->pdrive; - - // eventually gets us to our own _quecommand routine - scsi_wait_req(ScsiPassThruReq, - &vendor_cmd->cdb[0], buf, vendor_cmd->len, - 10*HZ, // timeout - 1); // retries - result = ScsiPassThruReq->sr_result; - - // copy any sense data back to caller - if( result != 0 ) - { - memcpy( vendor_cmd->sense_data, // see struct def - size=40 - ScsiPassThruReq->sr_sense_buffer, - sizeof(ScsiPassThruReq->sr_sense_buffer) < - sizeof(vendor_cmd->sense_data) ? - sizeof(ScsiPassThruReq->sr_sense_buffer) : - sizeof(vendor_cmd->sense_data) - ); - } - SDpnt = ScsiPassThruReq->sr_device; - /* upper_private_data is already freed in call_scsi_done() */ - scsi_release_request(ScsiPassThruReq); // "de-allocate" - ScsiPassThruReq = NULL; - - // need to pass data back to user (space)? - if( (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) && - vendor_cmd->len ) - if( copy_to_user( vendor_cmd->bufp, buf, vendor_cmd->len)) - result = -EFAULT; - - kfree(buf); - - return result; - } - - case CPQFCTS_GETPCIINFO: - { - cpqfc_pci_info_struct pciinfo; - - if( !arg) - return -EINVAL; - - - - pciinfo.bus = cpqfcHBAdata->PciDev->bus->number; - pciinfo.dev_fn = cpqfcHBAdata->PciDev->devfn; - pciinfo.board_id = cpqfcHBAdata->PciDev->device | - (cpqfcHBAdata->PciDev->vendor <<16); - - if(copy_to_user( arg, &pciinfo, sizeof(cpqfc_pci_info_struct))) - return( -EFAULT); - return 0; - } - - case CPQFCTS_GETDRIVVER: - { - DriverVer_type DriverVer = - CPQFCTS_DRIVER_VER( VER_MAJOR,VER_MINOR,VER_SUBMINOR); - - if( !arg) - return -EINVAL; - - if(copy_to_user( arg, &DriverVer, sizeof(DriverVer))) - return( -EFAULT); - return 0; - } - - - - case CPQFC_IOCTL_FC_TARGET_ADDRESS: - // can we find an FC device mapping to this SCSI target? -/* DumCmnd.channel = ScsiDev->channel; */ // For searching -/* DumCmnd.target = ScsiDev->id; */ -/* DumCmnd.lun = ScsiDev->lun; */ - - DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL); - if (!DumCmnd) - return -ENOMEM; - - pLoggedInPort = fcFindLoggedInPort( fcChip, - DumCmnd, // search Scsi Nexus - 0, // DON'T search linked list for FC port id - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - scsi_put_command (DumCmnd); - if (pLoggedInPort == NULL) { - result = -ENXIO; - break; - } - result = access_ok(VERIFY_WRITE, arg, sizeof(Scsi_FCTargAddress)) ? 0 : -EFAULT; - if (result) break; - - put_user(pLoggedInPort->port_id, - &((Scsi_FCTargAddress *) arg)->host_port_id); - - for( i=3,j=0; i>=0; i--) // copy the LOGIN port's WWN - put_user(pLoggedInPort->u.ucWWN[i], - &((Scsi_FCTargAddress *) arg)->host_wwn[j++]); - for( i=7; i>3; i--) // copy the LOGIN port's WWN - put_user(pLoggedInPort->u.ucWWN[i], - &((Scsi_FCTargAddress *) arg)->host_wwn[j++]); - break; - - - case CPQFC_IOCTL_FC_TDR: - - result = cpqfcTS_TargetDeviceReset( ScsiDev, 0); - - break; - - - - - default: - result = -EINVAL; - break; - } - - LEAVE("cpqfcTS_ioctl"); - return result; -} - - -/* "Release" the Host Bus Adapter... - disable interrupts, stop the HBA, release the interrupt, - and free all resources */ - -int cpqfcTS_release(struct Scsi_Host *HostAdapter) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - - - ENTER("cpqfcTS_release"); - - DEBUG_PCI( printk(" cpqfcTS: delete timer...\n")); - del_timer( &cpqfcHBAdata->cpqfcTStimer); - - // disable the hardware... - DEBUG_PCI( printk(" disable hardware, destroy queues, free mem\n")); - cpqfcHBAdata->fcChip.ResetTachyon( cpqfcHBAdata, CLEAR_FCPORTS); - - // kill kernel thread - if( cpqfcHBAdata->worker_thread ) // (only if exists) - { - DECLARE_MUTEX_LOCKED(sem); // synchronize thread kill - - cpqfcHBAdata->notify_wt = &sem; - DEBUG_PCI( printk(" killing kernel thread\n")); - send_sig( SIGKILL, cpqfcHBAdata->worker_thread, 1); - down( &sem); - cpqfcHBAdata->notify_wt = NULL; - - } - - cpqfc_free_private_data_pool(cpqfcHBAdata); - // free Linux resources - DEBUG_PCI( printk(" cpqfcTS: freeing resources...\n")); - free_irq( HostAdapter->irq, HostAdapter); - scsi_unregister( HostAdapter); - release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff); - release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff); - /* we get "vfree: bad address" executing this - need to investigate... - if( (void*)((unsigned long)cpqfcHBAdata->fcChip.Registers.MemBase) != - cpqfcHBAdata->fcChip.Registers.ReMapMemBase) - vfree( cpqfcHBAdata->fcChip.Registers.ReMapMemBase); -*/ - pci_disable_device( cpqfcHBAdata->PciDev); - - LEAVE("cpqfcTS_release"); - return 0; -} - - -const char * cpqfcTS_info(struct Scsi_Host *HostAdapter) -{ - static char buf[300]; - CPQFCHBA *cpqfcHBA; - int BusSpeed, BusWidth; - - // get the pointer to our Scsi layer HBA buffer - cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata; - - BusWidth = (cpqfcHBA->fcChip.Registers.PCIMCTR &0x4) > 0 ? - 64 : 32; - - if( cpqfcHBA->fcChip.Registers.TYconfig.value & 0x80000000) - BusSpeed = 66; - else - BusSpeed = 33; - - sprintf(buf, -"%s: WWN %08X%08X\n on PCI bus %d device 0x%02x irq %d IObaseL 0x%x, MEMBASE 0x%x\nPCI bus width %d bits, bus speed %d MHz\nFCP-SCSI Driver v%d.%d.%d", - cpqfcHBA->fcChip.Name, - cpqfcHBA->fcChip.Registers.wwn_hi, - cpqfcHBA->fcChip.Registers.wwn_lo, - cpqfcHBA->PciDev->bus->number, - cpqfcHBA->PciDev->device, - HostAdapter->irq, - cpqfcHBA->fcChip.Registers.IOBaseL, - cpqfcHBA->fcChip.Registers.MemBase, - BusWidth, - BusSpeed, - VER_MAJOR, VER_MINOR, VER_SUBMINOR -); - - - cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[ strlen(buf)]); - cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]); - return buf; -} - -// -// /proc/scsi support. The following routines allow us to do 'normal' -// sprintf like calls to return the currently requested piece (buflenght -// chars, starting at bufoffset) of the file. Although procfs allows for -// a 1 Kb bytes overflow after te supplied buffer, I consider it bad -// programming to use it to make programming a little simpler. This piece -// of coding is borrowed from ncr53c8xx.c with some modifications -// -struct info_str -{ - char *buffer; // Pointer to output buffer - int buflength; // It's length - int bufoffset; // File offset corresponding with buf[0] - int buffillen; // Current filled length - int filpos; // Current file offset -}; - -static void copy_mem_info(struct info_str *info, char *data, int datalen) -{ - - if (info->filpos < info->bufoffset) { // Current offset before buffer offset - if (info->filpos + datalen <= info->bufoffset) { - info->filpos += datalen; // Discard if completely before buffer - return; - } else { // Partial copy, set to begin - data += (info->bufoffset - info->filpos); - datalen -= (info->bufoffset - info->filpos); - info->filpos = info->bufoffset; - } - } - - info->filpos += datalen; // Update current offset - - if (info->buffillen == info->buflength) // Buffer full, discard - return; - - if (info->buflength - info->buffillen < datalen) // Overflows buffer ? - datalen = info->buflength - info->buffillen; - - memcpy(info->buffer + info->buffillen, data, datalen); - info->buffillen += datalen; -} - -static int copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[400]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - return len; -} - - -// Routine to get data for /proc RAM filesystem -// -int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, - int inout) -{ - struct scsi_cmnd *DumCmnd; - struct scsi_device *ScsiDev; - int Chan, Targ, i; - struct info_str info; - CPQFCHBA *cpqfcHBA; - PTACHYON fcChip; - PFC_LOGGEDIN_PORT pLoggedInPort; - char buf[81]; - - if (inout) return -EINVAL; - - // get the pointer to our Scsi layer HBA buffer - cpqfcHBA = (CPQFCHBA *)host->hostdata; - fcChip = &cpqfcHBA->fcChip; - - *start = buffer; - - info.buffer = buffer; - info.buflength = length; - info.bufoffset = offset; - info.filpos = 0; - info.buffillen = 0; - copy_info(&info, "Driver version = %d.%d.%d", VER_MAJOR, VER_MINOR, VER_SUBMINOR); - cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[0]); - cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]); - copy_info(&info, "%s\n", buf); - -#define DISPLAY_WWN_INFO -#ifdef DISPLAY_WWN_INFO - ScsiDev = scsi_get_host_dev (host); - if (!ScsiDev) - return -ENOMEM; - DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL); - if (!DumCmnd) { - scsi_free_host_dev (ScsiDev); - return -ENOMEM; - } - copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n"); - for ( Chan=0; Chan <= host->max_channel; Chan++) { - DumCmnd->device->channel = Chan; - for (Targ=0; Targ <= host->max_id; Targ++) { - DumCmnd->device->id = Targ; - if ((pLoggedInPort = fcFindLoggedInPort( fcChip, - DumCmnd, // search Scsi Nexus - 0, // DON'T search list for FC port id - NULL, // DON'T search list for FC WWN - NULL))){ // DON'T care about end of list - copy_info(&info, "Host: scsi%d Channel: %02d TargetId: %02d -> WWN: ", - host->host_no, Chan, Targ); - for( i=3; i>=0; i--) // copy the LOGIN port's WWN - copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]); - for( i=7; i>3; i--) // copy the LOGIN port's WWN - copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]); - copy_info(&info, " port_id: %06X\n", pLoggedInPort->port_id); - } - } - } - - scsi_put_command (DumCmnd); - scsi_free_host_dev (ScsiDev); -#endif - - - - - -// Unfortunately, the proc_info buffer isn't big enough -// for everything we would like... -// For FC stats, compile this and turn off WWN stuff above -//#define DISPLAY_FC_STATS -#ifdef DISPLAY_FC_STATS -// get the Fibre Channel statistics - { - int DeltaSecs = (jiffies - cpqfcHBA->fcStatsTime) / HZ; - int days,hours,minutes,secs; - - days = DeltaSecs / (3600*24); // days - hours = (DeltaSecs% (3600*24)) / 3600; // hours - minutes = (DeltaSecs%3600 /60); // minutes - secs = DeltaSecs%60; // secs -copy_info( &info, "Fibre Channel Stats (time dd:hh:mm:ss %02u:%02u:%02u:%02u\n", - days, hours, minutes, secs); - } - - cpqfcHBA->fcStatsTime = jiffies; // (for next delta) - - copy_info( &info, " LinkUp %9u LinkDown %u\n", - fcChip->fcStats.linkUp, fcChip->fcStats.linkDown); - - copy_info( &info, " Loss of Signal %9u Loss of Sync %u\n", - fcChip->fcStats.LossofSignal, fcChip->fcStats.LossofSync); - - copy_info( &info, " Discarded Frames %9u Bad CRC Frame %u\n", - fcChip->fcStats.Dis_Frm, fcChip->fcStats.Bad_CRC); - - copy_info( &info, " TACH LinkFailTX %9u TACH LinkFailRX %u\n", - fcChip->fcStats.linkFailTX, fcChip->fcStats.linkFailRX); - - copy_info( &info, " TACH RxEOFa %9u TACH Elastic Store %u\n", - fcChip->fcStats.Rx_EOFa, fcChip->fcStats.e_stores); - - copy_info( &info, " BufferCreditWait %9uus TACH FM Inits %u\n", - fcChip->fcStats.BB0_Timer*10, fcChip->fcStats.FMinits ); - - copy_info( &info, " FC-2 Timeouts %9u FC-2 Logouts %u\n", - fcChip->fcStats.timeouts, fcChip->fcStats.logouts); - - copy_info( &info, " FC-2 Aborts %9u FC-4 Aborts %u\n", - fcChip->fcStats.FC2aborted, fcChip->fcStats.FC4aborted); - - // clear the counters - cpqfcTSClearLinkStatusCounters( fcChip); -#endif - - return info.buffillen; -} - - -#if DEBUG_CMND - -UCHAR *ScsiToAscii( UCHAR ScsiCommand) -{ - -/*++ - -Routine Description: - - Converts a SCSI command to a text string for debugging purposes. - - -Arguments: - - ScsiCommand -- hex value SCSI Command - - -Return Value: - - An ASCII, null-terminated string if found, else returns NULL. - -Original code from M. McGowen, Compaq ---*/ - - - switch (ScsiCommand) - { - case 0x00: - return( "Test Unit Ready" ); - - case 0x01: - return( "Rezero Unit or Rewind" ); - - case 0x02: - return( "Request Block Address" ); - - case 0x03: - return( "Requese Sense" ); - - case 0x04: - return( "Format Unit" ); - - case 0x05: - return( "Read Block Limits" ); - - case 0x07: - return( "Reassign Blocks" ); - - case 0x08: - return( "Read (6)" ); - - case 0x0a: - return( "Write (6)" ); - - case 0x0b: - return( "Seek (6)" ); - - case 0x12: - return( "Inquiry" ); - - case 0x15: - return( "Mode Select (6)" ); - - case 0x16: - return( "Reserve" ); - - case 0x17: - return( "Release" ); - - case 0x1a: - return( "ModeSen(6)" ); - - case 0x1b: - return( "Start/Stop Unit" ); - - case 0x1c: - return( "Receive Diagnostic Results" ); - - case 0x1d: - return( "Send Diagnostic" ); - - case 0x25: - return( "Read Capacity" ); - - case 0x28: - return( "Read (10)" ); - - case 0x2a: - return( "Write (10)" ); - - case 0x2b: - return( "Seek (10)" ); - - case 0x2e: - return( "Write and Verify" ); - - case 0x2f: - return( "Verify" ); - - case 0x34: - return( "Pre-Fetch" ); - - case 0x35: - return( "Synchronize Cache" ); - - case 0x37: - return( "Read Defect Data (10)" ); - - case 0x3b: - return( "Write Buffer" ); - - case 0x3c: - return( "Read Buffer" ); - - case 0x3e: - return( "Read Long" ); - - case 0x3f: - return( "Write Long" ); - - case 0x41: - return( "Write Same" ); - - case 0x4c: - return( "Log Select" ); - - case 0x4d: - return( "Log Sense" ); - - case 0x56: - return( "Reserve (10)" ); - - case 0x57: - return( "Release (10)" ); - - case 0xa0: - return( "ReportLuns" ); - - case 0xb7: - return( "Read Defect Data (12)" ); - - case 0xca: - return( "Peripheral Device Addressing SCSI Passthrough" ); - - case 0xcb: - return( "Compaq Array Firmware Passthrough" ); - - default: - return( NULL ); - } - -} // end ScsiToAscii() - -void cpqfcTS_print_scsi_cmd(Scsi_Cmnd * cmd) -{ - -printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", - ScsiToAscii( cmd->cmnd[0]), cmd->channel, cmd->target, cmd->lun, cmd->cmd_len); - -if( cmd->cmnd[0] == 0) // Test Unit Ready? -{ - int i; - - printk("Cmnd->request_bufflen = 0x%X, ->use_sg = %d, ->bufflen = %d\n", - cmd->request_bufflen, cmd->use_sg, cmd->bufflen); - printk("Cmnd->request_buffer = %p, ->sglist_len = %d, ->buffer = %p\n", - cmd->request_buffer, cmd->sglist_len, cmd->buffer); - for (i = 0; i < cmd->cmd_len; i++) - printk("0x%02x ", cmd->cmnd[i]); - printk("\n"); -} - -} - -#endif /* DEBUG_CMND */ - - - - -static void QueCmndOnBoardLock( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd) -{ - int i; - - for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++) - { // find spare slot - if( cpqfcHBAdata->BoardLockCmnd[i] == NULL ) - { - cpqfcHBAdata->BoardLockCmnd[i] = Cmnd; -// printk(" BoardLockCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n", -// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun); - break; - } - } - if( i >= CPQFCTS_REQ_QUEUE_LEN) - { - printk(" cpqfcTS WARNING: Lost Cmnd %p on BoardLock Q full!", Cmnd); - } - -} - - -static void QueLinkDownCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd) -{ - int indx; - - // Remember the command ptr so we can return; we'll complete when - // the device comes back, causing immediate retry - for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++)//, SCptr++) - { - if( cpqfcHBAdata->LinkDnCmnd[indx] == NULL ) // available? - { -#ifdef DUMMYCMND_DBG - printk(" @add Cmnd %p to LnkDnCmnd[%d]@ ", Cmnd,indx); -#endif - cpqfcHBAdata->LinkDnCmnd[indx] = Cmnd; - break; - } - } - - if( indx >= CPQFCTS_REQ_QUEUE_LEN ) // no space for Cmnd?? - { - // this will result in an _abort call later (with possible trouble) - printk("no buffer for LinkDnCmnd!! %p\n", Cmnd); - } -} - - - - - -// The file says not to call scsi_done from -// inside _queuecommand, so we'll do it from the heartbeat timer -// (clarification: Turns out it's ok to call scsi_done from queuecommand -// for cases that don't go to the hardware like scsi cmds destined -// for LUNs we know don't exist, so this code might be simplified...) - -static void QueBadTargetCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd) -{ - int i; - // printk(" can't find target %d\n", Cmnd->target); - - for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++) - { // find spare slot - if( cpqfcHBAdata->BadTargetCmnd[i] == NULL ) - { - cpqfcHBAdata->BadTargetCmnd[i] = Cmnd; -// printk(" BadTargetCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n", -// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun); - break; - } - } -} - - -// This is the "main" entry point for Linux Scsi commands -- -// it all starts here. - -int cpqfcTS_queuecommand(Scsi_Cmnd *Cmnd, void (* done)(Scsi_Cmnd *)) -{ - struct Scsi_Host *HostAdapter = Cmnd->device->host; - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - TachFCHDR_GCMND fchs; // only use for FC destination id field - PFC_LOGGEDIN_PORT pLoggedInPort; - ULONG ulStatus, SESTtype; - LONG ExchangeID; - - - - - ENTER("cpqfcTS_queuecommand"); - - PCI_TRACEO( (ULONG)Cmnd, 0x98) - - - Cmnd->scsi_done = done; -#ifdef DEBUG_CMND - cpqfcTS_print_scsi_cmd( Cmnd); -#endif - - // prevent board contention with kernel thread... - - if( cpqfcHBAdata->BoardLock ) - { -// printk(" @BrdLck Hld@ "); - QueCmndOnBoardLock( cpqfcHBAdata, Cmnd); - } - - else - { - - // in the current system (2.2.12), this routine is called - // after spin_lock_irqsave(), so INTs are disabled. However, - // we might have something pending in the LinkQ, which - // might cause the WorkerTask to run. In case that - // happens, make sure we lock it out. - - - - PCI_TRACE( 0x98) - CPQ_SPINLOCK_HBA( cpqfcHBAdata) - PCI_TRACE( 0x98) - - // can we find an FC device mapping to this SCSI target? - pLoggedInPort = fcFindLoggedInPort( fcChip, - Cmnd, // search Scsi Nexus - 0, // DON'T search linked list for FC port id - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - if( pLoggedInPort == NULL ) // not found! - { -// printk(" @Q bad targ cmnd %p@ ", Cmnd); - QueBadTargetCmnd( cpqfcHBAdata, Cmnd); - } - else if (Cmnd->device->lun >= CPQFCTS_MAX_LUN) - { - printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->device->lun); - QueBadTargetCmnd( cpqfcHBAdata, Cmnd); - } - - else // we know what FC device to send to... - { - - // does this device support FCP target functions? - // (determined by PRLI field) - - if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) ) - { - printk(" Doesn't support TARGET functions port_id %Xh\n", - pLoggedInPort->port_id ); - QueBadTargetCmnd( cpqfcHBAdata, Cmnd); - } - - // In this case (previous login OK), the device is temporarily - // unavailable waiting for re-login, in which case we expect it - // to be back in between 25 - 500ms. - // If the FC port doesn't log back in within several seconds - // (i.e. implicit "logout"), or we get an explicit logout, - // we set "device_blocked" in Scsi_Device struct; in this - // case 30 seconds will elapse before Linux/Scsi sends another - // command to the device. - else if( pLoggedInPort->prli != TRUE ) - { -// printk("Device (Chnl/Target %d/%d) invalid PRLI, port_id %06lXh\n", -// Cmnd->channel, Cmnd->target, pLoggedInPort->port_id); - QueLinkDownCmnd( cpqfcHBAdata, Cmnd); -// Need to use "blocked" flag?? -// Cmnd->device->device_blocked = TRUE; // just let it timeout - } - else // device supports TARGET functions, and is logged in... - { - // (context of fchs is to "reply" to...) - fchs.s_id = pLoggedInPort->port_id; // destination FC address - - // what is the data direction? For data TO the device, - // we need IWE (Intiator Write Entry). Otherwise, IRE. - - if( Cmnd->cmnd[0] == WRITE_10 || - Cmnd->cmnd[0] == WRITE_6 || - Cmnd->cmnd[0] == WRITE_BUFFER || - Cmnd->cmnd[0] == VENDOR_WRITE_OPCODE || // CPQ specific - Cmnd->cmnd[0] == MODE_SELECT ) - { - SESTtype = SCSI_IWE; // data from HBA to Device - } - else - SESTtype = SCSI_IRE; // data from Device to HBA - - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - SESTtype, // e.g. Initiator Read Entry (IRE) - &fchs, // we are originator; only use d_id - Cmnd, // Linux SCSI command (with scatter/gather list) - &ExchangeID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup? - - { - if( cpqfcHBAdata->BoardLock ) - { - TriggerHBA( fcChip->Registers.ReMapMemBase, 0); - printk(" @bl! %d, xID %Xh@ ", current->pid, ExchangeID); - } - - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID ); - if( !ulStatus ) - { - PCI_TRACEO( ExchangeID, 0xB8) - // submitted to Tach's Outbound Que (ERQ PI incremented) - // waited for completion for ELS type (Login frames issued - // synchronously) - } - else - // check reason for Exchange not being started - we might - // want to Queue and start later, or fail with error - { - printk("quecommand: cpqfcTSStartExchange failed: %Xh\n", ulStatus ); - } - } // end good BuildExchange status - - else // SEST table probably full -- why? hardware hang? - { - printk("quecommand: cpqfcTSBuildExchange faild: %Xh\n", ulStatus); - } - } // end can't do FCP-SCSI target functions - } // end can't find target (FC device) - - CPQ_SPINUNLOCK_HBA( cpqfcHBAdata) - } - - PCI_TRACEO( (ULONG)Cmnd, 0x9C) - LEAVE("cpqfcTS_queuecommand"); - return 0; -} - - -// Entry point for upper Scsi layer intiated abort. Typically -// this is called if the command (for hard disk) fails to complete -// in 30 seconds. This driver intends to complete all disk commands -// within Exchange ".timeOut" seconds (now 7) with target status, or -// in case of ".timeOut" expiration, a DID_SOFT_ERROR which causes -// immediate retry. -// If any disk commands get the _abort call, except for the case that -// the physical device was removed or unavailable due to hardware -// errors, it should be considered a driver error and reported to -// the author. - -int cpqfcTS_abort(Scsi_Cmnd *Cmnd) -{ -// printk(" cpqfcTS_abort called?? \n"); - return 0; -} - -int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd) -{ - - struct Scsi_Host *HostAdapter = Cmnd->device->host; - // get the pointer to our Scsi layer HBA buffer - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - int i; - ENTER("cpqfcTS_eh_abort"); - - Cmnd->result = DID_ABORT <<16; // assume we'll find it - - printk(" @Linux _abort Scsi_Cmnd %p ", Cmnd); - // See if we can find a Cmnd pointer that matches... - // The most likely case is we accepted the command - // from Linux Scsi (e.g. ceated a SEST entry) and it - // got lost somehow. If we can't find any reference - // to the passed pointer, we can only presume it - // got completed as far as our driver is concerned. - // If we found it, we will try to abort it through - // common mechanism. If FC ABTS is successful (ACC) - // or is rejected (RJT) by target, we will call - // Scsi "done" quickly. Otherwise, the ABTS will timeout - // and we'll call "done" later. - - // Search the SEST exchanges for a matching Cmnd ptr. - for( i=0; i< TACH_SEST_LEN; i++) - { - if( Exchanges->fcExchange[i].Cmnd == Cmnd ) - { - - // found it! - printk(" x_ID %Xh, type %Xh\n", i, Exchanges->fcExchange[i].type); - - Exchanges->fcExchange[i].status = INITIATOR_ABORT; // seconds default - Exchanges->fcExchange[i].timeOut = 10; // seconds default (changed later) - - // Since we need to immediately return the aborted Cmnd to Scsi - // upper layers, we can't make future reference to any of its - // fields (e.g the Nexus). - - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i); - - break; - } - } - - if( i >= TACH_SEST_LEN ) // didn't find Cmnd ptr in chip's SEST? - { - // now search our non-SEST buffers (i.e. Cmnd waiting to - // start on the HBA or waiting to complete with error for retry). - - // first check BadTargetCmnd - for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++) - { - if( cpqfcHBAdata->BadTargetCmnd[i] == Cmnd ) - { - cpqfcHBAdata->BadTargetCmnd[i] = NULL; - printk("in BadTargetCmnd Q\n"); - goto Done; // exit - } - } - - // if not found above... - - for( i=0; i < CPQFCTS_REQ_QUEUE_LEN; i++) - { - if( cpqfcHBAdata->LinkDnCmnd[i] == Cmnd ) - { - cpqfcHBAdata->LinkDnCmnd[i] = NULL; - printk("in LinkDnCmnd Q\n"); - goto Done; - } - } - - - for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++) - { // find spare slot - if( cpqfcHBAdata->BoardLockCmnd[i] == Cmnd ) - { - cpqfcHBAdata->BoardLockCmnd[i] = NULL; - printk("in BoardLockCmnd Q\n"); - goto Done; - } - } - - Cmnd->result = DID_ERROR <<16; // Hmmm... - printk("Not found! "); -// panic("_abort"); - } - -Done: - -// panic("_abort"); - LEAVE("cpqfcTS_eh_abort"); - return 0; // (see scsi.h) -} - - -// FCP-SCSI Target Device Reset -// See dpANS Fibre Channel Protocol for SCSI -// X3.269-199X revision 12, pg 25 - -#ifdef SUPPORT_RESET - -int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, - unsigned int reset_flags) -{ - int timeout = 10*HZ; - int retries = 1; - char scsi_cdb[12]; - int result; - Scsi_Cmnd * SCpnt; - Scsi_Device * SDpnt; - -// FIXME, cpqfcTS_TargetDeviceReset needs to be fixed -// similarly to how the passthrough ioctl was fixed -// around the 2.5.30 kernel. Scsi_Cmnd replaced with -// Scsi_Request, etc. -// For now, so people don't fall into a hole... - - // printk(" ENTERING cpqfcTS_TargetDeviceReset() - flag=%d \n",reset_flags); - - if (ScsiDev->host->eh_active) return FAILED; - - memset( scsi_cdb, 0, sizeof( scsi_cdb)); - - scsi_cdb[0] = RELEASE; - - SCpnt = scsi_get_command(ScsiDev, GFP_KERNEL); - { - CPQFC_DECLARE_COMPLETION(wait); - - SCpnt->SCp.buffers_residual = FCP_TARGET_RESET; - - // FIXME: this would panic, SCpnt->request would be NULL. - SCpnt->request->CPQFC_WAITING = &wait; - scsi_do_cmd(SCpnt, scsi_cdb, NULL, 0, my_ioctl_done, timeout, retries); - CPQFC_WAIT_FOR_COMPLETION(&wait); - SCpnt->request->CPQFC_WAITING = NULL; - } - - - if(driver_byte(SCpnt->result) != 0) - switch(SCpnt->sense_buffer[2] & 0xf) { - case ILLEGAL_REQUEST: - if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0; - else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n"); - break; - case NOT_READY: // This happens if there is no disc in drive - if(dev->removable && (cmd[0] != TEST_UNIT_READY)){ - printk(KERN_INFO "Device not ready. Make sure there is a disc in the drive.\n"); - break; - } - case UNIT_ATTENTION: - if (dev->removable){ - dev->changed = 1; - SCpnt->result = 0; // This is no longer considered an error - // gag this error, VFS will log it anyway /axboe - // printk(KERN_INFO "Disc change detected.\n"); - break; - }; - default: // Fall through for non-removable media - printk("SCSI error: host %d id %d lun %d return code = %x\n", - dev->host->host_no, - dev->id, - dev->lun, - SCpnt->result); - printk("\tSense class %x, sense error %x, extended sense %x\n", - sense_class(SCpnt->sense_buffer[0]), - sense_error(SCpnt->sense_buffer[0]), - SCpnt->sense_buffer[2] & 0xf); - - }; - result = SCpnt->result; - - SDpnt = SCpnt->device; - scsi_put_command(SCpnt); - SCpnt = NULL; - - // printk(" LEAVING cpqfcTS_TargetDeviceReset() - return SUCCESS \n"); - return SUCCESS; -} - -#else -int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, - unsigned int reset_flags) -{ - return -ENOTSUPP; -} - -#endif /* SUPPORT_RESET */ - -int cpqfcTS_eh_device_reset(Scsi_Cmnd *Cmnd) -{ - int retval; - Scsi_Device *SDpnt = Cmnd->device; - // printk(" ENTERING cpqfcTS_eh_device_reset() \n"); - spin_unlock_irq(Cmnd->device->host->host_lock); - retval = cpqfcTS_TargetDeviceReset( SDpnt, 0); - spin_lock_irq(Cmnd->device->host->host_lock); - return retval; -} - - -int cpqfcTS_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags) -{ - - ENTER("cpqfcTS_reset"); - - LEAVE("cpqfcTS_reset"); - return SCSI_RESET_ERROR; /* Bus Reset Not supported */ -} - -/* This function determines the bios parameters for a given - harddisk. These tend to be numbers that are made up by the - host adapter. Parameters: - size, device number, list (heads, sectors,cylinders). - (from hosts.h) -*/ - -int cpqfcTS_biosparam(struct scsi_device *sdev, struct block_device *n, - sector_t capacity, int ip[]) -{ - int size = capacity; - - ENTER("cpqfcTS_biosparam"); - ip[0] = 64; - ip[1] = 32; - ip[2] = size >> 11; - - if( ip[2] > 1024 ) - { - ip[0] = 255; - ip[1] = 63; - ip[2] = size / (ip[0] * ip[1]); - } - - LEAVE("cpqfcTS_biosparam"); - return 0; -} - - - -irqreturn_t cpqfcTS_intr_handler( int irq, - void *dev_id, - struct pt_regs *regs) -{ - - unsigned long flags, InfLoopBrk=0; - struct Scsi_Host *HostAdapter = dev_id; - CPQFCHBA *cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata; - int MoreMessages = 1; // assume we have something to do - UCHAR IntPending; - int handled = 0; - - ENTER("intr_handler"); - spin_lock_irqsave( HostAdapter->host_lock, flags); - // is this our INT? - IntPending = readb( cpqfcHBA->fcChip.Registers.INTPEND.address); - - // broken boards can generate messages forever, so - // prevent the infinite loop -#define INFINITE_IMQ_BREAK 10000 - if( IntPending ) - { - handled = 1; - // mask our HBA interrupts until we handle it... - writeb( 0, cpqfcHBA->fcChip.Registers.INTEN.address); - - if( IntPending & 0x4) // "INT" - Tach wrote to IMQ - { - while( (++InfLoopBrk < INFINITE_IMQ_BREAK) && (MoreMessages ==1) ) - { - MoreMessages = CpqTsProcessIMQEntry( HostAdapter); // ret 0 when done - } - if( InfLoopBrk >= INFINITE_IMQ_BREAK ) - { - printk("WARNING: Compaq FC adapter generating excessive INTs -REPLACE\n"); - printk("or investigate alternate causes (e.g. physical FC layer)\n"); - } - - else // working normally - re-enable INTs and continue - writeb( 0x1F, cpqfcHBA->fcChip.Registers.INTEN.address); - - } // (...ProcessIMQEntry() clears INT by writing IMQ consumer) - else // indications of errors or problems... - // these usually indicate critical system hardware problems. - { - if( IntPending & 0x10 ) - printk(" cpqfcTS adapter external memory parity error detected\n"); - if( IntPending & 0x8 ) - printk(" cpqfcTS adapter PCI master address crossed 45-bit boundary\n"); - if( IntPending & 0x2 ) - printk(" cpqfcTS adapter DMA error detected\n"); - if( IntPending & 0x1 ) { - UCHAR IntStat; - printk(" cpqfcTS adapter PCI error detected\n"); - IntStat = readb( cpqfcHBA->fcChip.Registers.INTSTAT.address); - printk("cpqfc: ISR = 0x%02x\n", IntStat); - if (IntStat & 0x1) { - __u16 pcistat; - /* read the pci status register */ - pci_read_config_word(cpqfcHBA->PciDev, 0x06, &pcistat); - printk("PCI status register is 0x%04x\n", pcistat); - if (pcistat & 0x8000) printk("Parity Error Detected.\n"); - if (pcistat & 0x4000) printk("Signalled System Error\n"); - if (pcistat & 0x2000) printk("Received Master Abort\n"); - if (pcistat & 0x1000) printk("Received Target Abort\n"); - if (pcistat & 0x0800) printk("Signalled Target Abort\n"); - } - if (IntStat & 0x4) printk("(INT)\n"); - if (IntStat & 0x8) - printk("CRS: PCI master address crossed 46 bit bouandary\n"); - if (IntStat & 0x10) printk("MRE: external memory parity error.\n"); - } - } - } - spin_unlock_irqrestore( HostAdapter->host_lock, flags); - LEAVE("intr_handler"); - return IRQ_RETVAL(handled); -} - - - - -int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]) -{ - // Verify GBIC type (if any) and correct Tachyon Port State Machine - // (GBIC) module definition is: - // GPIO1, GPIO0, GPIO4 for MD2, MD1, MD0. The input states appear - // to be inverted -- i.e., a setting of 111 is read when there is NO - // GBIC present. The Module Def (MD) spec says 000 is "no GBIC" - // Hard code the bit states to detect Copper, - // Long wave (single mode), Short wave (multi-mode), and absent GBIC - - ULONG ulBuff; - - sprintf( cErrorString, "\nGBIC detected: "); - - ulBuff = fcChip->Registers.TYstatus.value & 0x13; - switch( ulBuff ) - { - case 0x13: // GPIO4, GPIO1, GPIO0 = 111; no GBIC! - sprintf( &cErrorString[ strlen( cErrorString)], - "NONE! "); - return FALSE; - - - case 0x11: // Copper GBIC detected - sprintf( &cErrorString[ strlen( cErrorString)], - "Copper. "); - break; - - case 0x10: // Long-wave (single mode) GBIC detected - sprintf( &cErrorString[ strlen( cErrorString)], - "Long-wave. "); - break; - case 0x1: // Short-wave (multi mode) GBIC detected - sprintf( &cErrorString[ strlen( cErrorString)], - "Short-wave. "); - break; - default: // unknown GBIC - presumably it will work (?) - sprintf( &cErrorString[ strlen( cErrorString)], - "Unknown. "); - - break; - } // end switch GBIC detection - - return TRUE; -} - - - - - - -int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]) -{ - // Tachyon's Frame Manager LPSM in LinkDown state? - // (For non-loop port, check PSM instead.) - // return string with state and FALSE is Link Down - - int LinkUp; - - if( fcChip->Registers.FMstatus.value & 0x80 ) - LinkUp = FALSE; - else - LinkUp = TRUE; - - sprintf( &cErrorString[ strlen( cErrorString)], - " LPSM %Xh ", - (fcChip->Registers.FMstatus.value >>4) & 0xf ); - - - switch( fcChip->Registers.FMstatus.value & 0xF0) - { - // bits set in LPSM - case 0x10: - sprintf( &cErrorString[ strlen( cErrorString)], "ARB"); - break; - case 0x20: - sprintf( &cErrorString[ strlen( cErrorString)], "ARBwon"); - break; - case 0x30: - sprintf( &cErrorString[ strlen( cErrorString)], "OPEN"); - break; - case 0x40: - sprintf( &cErrorString[ strlen( cErrorString)], "OPENed"); - break; - case 0x50: - sprintf( &cErrorString[ strlen( cErrorString)], "XmitCLS"); - break; - case 0x60: - sprintf( &cErrorString[ strlen( cErrorString)], "RxCLS"); - break; - case 0x70: - sprintf( &cErrorString[ strlen( cErrorString)], "Xfer"); - break; - case 0x80: - sprintf( &cErrorString[ strlen( cErrorString)], "Init"); - break; - case 0x90: - sprintf( &cErrorString[ strlen( cErrorString)], "O-IInitFin"); - break; - case 0xa0: - sprintf( &cErrorString[ strlen( cErrorString)], "O-IProtocol"); - break; - case 0xb0: - sprintf( &cErrorString[ strlen( cErrorString)], "O-ILipRcvd"); - break; - case 0xc0: - sprintf( &cErrorString[ strlen( cErrorString)], "HostControl"); - break; - case 0xd0: - sprintf( &cErrorString[ strlen( cErrorString)], "LoopFail"); - break; - case 0xe0: - sprintf( &cErrorString[ strlen( cErrorString)], "Offline"); - break; - case 0xf0: - sprintf( &cErrorString[ strlen( cErrorString)], "OldPort"); - break; - case 0: - default: - sprintf( &cErrorString[ strlen( cErrorString)], "Monitor"); - break; - - } - - return LinkUp; -} - - - - -#include "linux/slab.h" - -// Dynamic memory allocation alignment routines -// HP's Tachyon Fibre Channel Controller chips require -// certain memory queues and register pointers to be aligned -// on various boundaries, usually the size of the Queue in question. -// Alignment might be on 2, 4, 8, ... or even 512 byte boundaries. -// Since most O/Ss don't allow this (usually only Cache aligned - -// 32-byte boundary), these routines provide generic alignment (after -// O/S allocation) at any boundary, and store the original allocated -// pointer for deletion (O/S free function). Typically, we expect -// these functions to only be called at HBA initialization and -// removal time (load and unload times) -// ALGORITHM notes: -// Memory allocation varies by compiler and platform. In the worst case, -// we are only assured BYTE alignment, but in the best case, we can -// request allocation on any desired boundary. Our strategy: pad the -// allocation request size (i.e. waste memory) so that we are assured -// of passing desired boundary near beginning of contiguous space, then -// mask out lower address bits. -// We define the following algorithm: -// allocBoundary - compiler/platform specific address alignment -// in number of bytes (default is single byte; i.e. 1) -// n_alloc - number of bytes application wants @ aligned address -// ab - alignment boundary, in bytes (e.g. 4, 32, ...) -// t_alloc - total allocation needed to ensure desired boundary -// mask - to clear least significant address bits for boundary -// Compute: -// t_alloc = n_alloc + (ab - allocBoundary) -// allocate t_alloc bytes @ alloc_address -// mask = NOT (ab - 1) -// (e.g. if ab=32 _0001 1111 -> _1110 0000 -// aligned_address = alloc_address & mask -// set n_alloc bytes to 0 -// return aligned_address (NULL if failed) -// -// If u32_AlignedAddress is non-zero, then search for BaseAddress (stored -// from previous allocation). If found, invoke call to FREE the memory. -// Return NULL if BaseAddress not found - -// we need about 8 allocations per HBA. Figuring at most 10 HBAs per server -// size the dynamic_mem array at 80. - -void* fcMemManager( struct pci_dev *pdev, ALIGNED_MEM *dynamic_mem, - ULONG n_alloc, ULONG ab, ULONG u32_AlignedAddress, - dma_addr_t *dma_handle) -{ - USHORT allocBoundary=1; // compiler specific - worst case 1 - // best case - replace malloc() call - // with function that allocates exactly - // at desired boundary - - unsigned long ulAddress; - ULONG t_alloc, i; - void *alloc_address = 0; // def. error code / address not found - LONG mask; // must be 32-bits wide! - - ENTER("fcMemManager"); - if( u32_AlignedAddress ) // are we freeing existing memory? - { -// printk(" freeing AlignedAddress %Xh\n", u32_AlignedAddress); - for( i=0; i // timer declaration in our host data -#include -#include -#include "cpqfcTSioctl.h" - -#define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \ - for( wait_time=jiffies + (secs*HZ); \ - time_before(jiffies, wait_time) ;) ; } - -#define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -// don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c -#define VER_MAJOR 2 -#define VER_MINOR 5 -#define VER_SUBMINOR 4 - -// Macros for kernel (esp. SMP) tracing using a PCI analyzer -// (e.g. x86). -//#define PCI_KERNEL_TRACE -#ifdef PCI_KERNEL_TRACE -#define PCI_TRACE(x) inl( fcChip->Registers.IOBaseL +x); -#define PCI_TRACEO(x,y) outl( x, (fcChip->Registers.IOBaseL +y)); -#else - -#define PCI_TRACE(x) -#define PCI_TRACEO(x,y) -#endif - - -//#define DEBUG_CMND 1 // debug output for Linux Scsi CDBs -//#define DUMMYCMND_DBG 1 - -//#define DEBUG_CPQFCTS 1 -//#undef DEBUG_CPQFCTS -#ifdef DEBUG_CPQFCTS -#define ENTER(x) printk("cpqfcts : entering %s()\n", x); -#define LEAVE(x) printk("cpqfcts : leaving %s()\n", x); -#define DEBUG(x) x -#else -#define ENTER(x) -#define LEAVE(x) -#define DEBUG(x) -#endif /* DEBUG_CPQFCTS */ - -//#define DEBUG_CPQFCTS_PCI 1 -//#undef DEBUG_CPQFCTS_PCI -#if DEBUG_CPQFCTS_PCI -#define DEBUG_PCI(x) x -#else -#define DEBUG_PCI(x) -#endif /* DEBUG_CPQFCTS_PCI */ - -#define STACHLITE66_TS12 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2" -#define STACHLITE66_TS13 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3" -#define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??" -#define SAGILENT_XL2_21 "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1" - -// PDA is Peripheral Device Address, VSA is Volume Set Addressing -// Linux SCSI parameters -#define CPQFCTS_MAX_TARGET_ID 64 - -// Note, changing CPQFCTS_MAX_LUN to less than 32 (e.g, 8) will result in -// strange behavior if a box with more than, e.g. 8, is on the loop. -#define CPQFCTS_MAX_LUN 32 // The RA-4x00 supports 32 (Linux SCSI supports 8) -#define CPQFCTS_MAX_CHANNEL 0 // One FC port on cpqfcTS HBA - -#define CPQFCTS_CMD_PER_LUN 15 // power of 2 -1, must be >0 -#define CPQFCTS_REQ_QUEUE_LEN (TACH_SEST_LEN/2) // must be < TACH_SEST_LEN - -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#ifndef DECLARE_MUTEX_LOCKED -#define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED -#endif - -#define DEV_NAME "cpqfcTS" - -struct SupportedPCIcards -{ - __u16 vendor_id; - __u16 device_id; -}; - -// nn:nn denotes bit field - // TachyonHeader struct def. - // the fields shared with ODB - // need to have same value - - - - -#ifndef BYTE -//typedef UCHAR BYTE; -typedef __u8 BYTE; -#endif -#ifndef UCHAR -typedef __u8 UCHAR; -#endif -#ifndef LONG -typedef __s32 LONG; -#endif -#ifndef ULONG -typedef __u32 ULONG; -#endif -#ifndef PVOID -typedef void * PVOID; -#endif -#ifndef USHORT -typedef __u16 USHORT; -#endif -#ifndef BOOLEAN -typedef __u8 BOOLEAN; -#endif - - -// macro for FC-PH reject codes -// payload format for LS_RJT (FC payloads are big endian): -// byte 0 1 2 3 (MSB) -// DWORD 0 01 00 00 00 -// DWORD 1 resvd code expl. vendor - -#define LS_RJT_REASON( code, expl) (( code<<8) | (expl <<16)) - - -#define TachLiteSTATUS 0x12 - -// Fibre Channel EXCHANGE status codes for Tachyon chips/ driver software -// 32-bit ERROR word defines -#define INVALID_ARGS 0x1 -#define LNKDWN_OSLS 0x2 -#define LNKDWN_LASER 0x4 -#define OUTQUE_FULL 0x8 -#define DRIVERQ_FULL 0x10 -#define SEST_FULL 0x20 -#define BAD_ALPA 0x40 -#define OVERFLOW 0x80 // inbound CM -#define COUNT_ERROR 0x100 // inbound CM -#define LINKFAIL_RX 0x200 // inbound CM -#define ABORTSEQ_NOTIFY 0x400 // outbound CM -#define LINKFAIL_TX 0x800 // outbound CM -#define HOSTPROG_ERR 0x1000 // outbound CM -#define FRAME_TO 0x2000 // outbound CM -#define INV_ENTRY 0x4000 // outbound CM -#define SESTPROG_ERR 0x8000 // outbound CM -#define OUTBOUND_TIMEOUT 0x10000L // timeout waiting for Tachyon outbound CM -#define INITIATOR_ABORT 0x20000L // initiator exchange timeout or O/S ABORT -#define MEMPOOL_FAIL 0x40000L // O/S memory pool allocation failed -#define FC2_TIMEOUT 0x80000L // driver timeout for lost frames -#define TARGET_ABORT 0x100000L // ABTS received from FC port -#define EXCHANGE_QUEUED 0x200000L // e.g. Link State was LDn on fcStart -#define PORTID_CHANGED 0x400000L // fc Port address changed -#define DEVICE_REMOVED 0x800000L // fc Port address changed -// Several error scenarios result in SEST Exchange frames -// unexpectedly arriving in the SFQ -#define SFQ_FRAME 0x1000000L // SFQ frames from open Exchange - -// Maximum number of Host Bus Adapters (HBA) / controllers supported -// only important for mem allocation dimensions - increase as necessary - -#define MAX_ADAPTERS 8 -#define MAX_RX_PAYLOAD 1024 // hardware dependent max frame payload -// Tach header struc defines -#define SOFi3 0x7 -#define SOFf 0x8 -#define SOFn3 0xB -#define EOFn 0x5 -#define EOFt 0x6 - -// FCP R_CTL defines -#define FCP_CMND 0x6 -#define FCP_XFER_RDY 0x5 -#define FCP_RSP 0x7 -#define FCP_RESPONSE 0x777 // (arbitrary #) -#define NEED_FCP_RSP 0x77 // (arbitrary #) -#define FCP_DATA 0x1 - -#define RESET_TACH 0x100 // Reset Tachyon/TachLite -#define SCSI_IWE 0x2000 // initiator write entry (for SEST) -#define SCSI_IRE 0x3000 // initiator read entry (for SEST) -#define SCSI_TRE 0x400 // target read entry (for SEST) -#define SCSI_TWE 0x500 // target write entry (for SEST) -#define TOGGLE_LASER 0x800 -#define LIP 0x900 -#define CLEAR_FCPORTS 99 // (arbitrary #) free mem for Logged in ports -#define FMINIT 0x707 // (arbitrary) for Frame Manager Init command - -// BLS == Basic Link Service -// ELS == Extended Link Service -#define BLS_NOP 4 -#define BLS_ABTS 0x10 // FC-PH Basic Link Service Abort Sequence -#define BLS_ABTS_ACC 0x100 // FC-PH Basic Link Service Abort Sequence Accept -#define BLS_ABTS_RJT 0x101 // FC-PH Basic Link Service Abort Sequence Reject -#define ELS_PLOGI 0x03 // FC-PH Port Login (arbitrary assign) -#define ELS_SCR 0x70 // (arb assign) State Change Registration (Fabric) -#define FCS_NSR 0x72 // (arb assign) Name Service Request (Fabric) -#define ELS_FLOGI 0x44 // (arb assign) Fabric Login -#define ELS_FDISC 0x41 // (arb assign) Fabric Discovery (Login) -#define ELS_PDISC 0x50 // FC-PH2 Port Discovery -#define ELS_ABTX 0x06 // FC-PH Abort Exchange -#define ELS_LOGO 0x05 // FC-PH Port Logout -#define ELS_PRLI 0x20 // FCP-SCSI Process Login -#define ELS_PRLO 0x21 // FCP-SCSI Process Logout -#define ELS_LOGO_ACC 0x07 // {FC-PH} Port Logout Accept -#define ELS_PLOGI_ACC 0x08 // {FC-PH} Port Login Accept -#define ELS_ACC 0x18 // {FC-PH} (generic) ACCept -#define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept -#define ELS_RJT 0x1000000 -#define SCSI_REPORT_LUNS 0x0A0 -#define FCP_TARGET_RESET 0x200 - -#define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame - -#define SFQ_UNASSISTED_FCP 1 // ICM, DWord3, "Type" unassisted FCP -#define SFQ_UNKNOWN 0x31 // (arbitrary) ICM, DWord3, "Type" unknown - -// these "LINK" bits refer to loop or non-loop -#define LINKACTIVE 0x2 // fcLinkQ type - LINK UP Tachyon FM 'Lup' bit set -#define LINKDOWN 0xf2 // fcLinkQ type - LINK DOWN Tachyon FM 'Ldn' bit set - -//#define VOLUME_SET_ADDRESSING 1 // "channel" or "bus" 1 - -typedef struct // 32 bytes hdr ONLY (e.g. FCP_DATA buffer for SEST) -{ - ULONG reserved; // dword 0 (don't use) - ULONG sof_eof; - ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID - ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID - ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL - ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT - ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID - ULONG ro; // dword 7 - relative offset -} TachFCHDR; - - // NOTE!! the following struct MUST be 64 bytes. -typedef struct // 32 bytes hdr + 32 bytes payload -{ - ULONG reserved; // dword 0 (don't use - must clear to 0) - ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp - ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID - ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID - ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL - ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT - ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID - ULONG ro; // dword 7 - relative offset -//--------- - __u32 pl[8]; // dwords 8-15 frame data payload -} TachFCHDR_CMND; - - -typedef struct // 32 bytes hdr + 120 bytes payload -{ - ULONG reserved; // dword 0 (don't use - must clear to 0) - ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp - ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID - ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID - ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL - ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT - ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID - ULONG ro; // dword 7 - relative offset -//--------- - __u32 pl[30]; // largest necessary payload (for LOGIN cmnds) -} TachFCHDR_GCMND; - -typedef struct // 32 bytes hdr + 64 bytes payload -{ - ULONG reserved; // dword 0 (don't use) - ULONG sof_eof; - ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID - ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID - ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL - ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT - ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID - ULONG ro; // dword 7 - relative offset -//--------- - __u32 pl[18]; // payload for FCP-RSP (response buffer) RA-4x00 is 72bytes -} TachFCHDR_RSP; - - - - - - -// Inbound Message Queue structures... -typedef struct // each entry 8 words (32 bytes) -{ - ULONG type; // IMQ completion message types - ULONG word[7]; // remainder of structure - // interpreted by IMQ type -} TachyonIMQE; - - -// Queues for TachLite not in original Tachyon -// ERQ - Exchange Request Queue (for outbound commands) -// SFQ - Single Frame Queue (for incoming frames) - - // Define Tachyon Outbound Command Que - // (Since many Tachyon registers are Read - // only, maintain copies for debugging) - // most Tach ques need power-of-2 sizes, - // where registers are loaded with po2 -1 -#define TACH_SEST_LEN 512 // TachLite SEST - -#define ELS_EXCHANGES 64 // e.g. PLOGI, RSCN, ... -// define the total number of outstanding (simultaneous) exchanges -#define TACH_MAX_XID (TACH_SEST_LEN + ELS_EXCHANGES) // ELS exchanges - -#define ERQ_LEN 128 // power of 2, max 4096 - -// Inbound Message Queue structures... -#define IMQ_LEN 512 // minimum 4 entries [(power of 2) - 1] -typedef struct // 8 words - 32 bytes -{ - TachyonIMQE QEntry[IMQ_LEN]; - ULONG producerIndex; // IMQ Producer Index register - // @32 byte align - ULONG consumerIndex; // Consumer Index register (in Tachyon) - ULONG length; // Length register - ULONG base; -} TachyonIMQ; // @ 32 * IMQ_LEN align - - - -typedef struct // inbound completion message -{ - ULONG Type; - ULONG Index; - ULONG TransferLength; -} TachyonInbCM; - - - -// arbitrary numeric tags for TL structures -#define TL_FCHS 1 // TachLite Fibre Channel Header Structure -#define TL_IWE 2 // initiator write entry (for SEST) -#define TL_TWE 3 // target write entry (for SEST) -#define TL_IRE 4 // initiator read entry (for SEST) -#define TL_TRE 5 // target read entry (for SEST) -#define TL_IRB 6 // I/O request block - - // for INCOMING frames -#define SFQ_LEN 32 // minimum 32 entries, max 4096 - -typedef struct // Single Frame Que -{ - TachFCHDR_CMND QEntry[SFQ_LEN]; // must be 64 bytes!! - ULONG producerIndex; // IMQ Producer Index register - // @32 byte align - ULONG consumerIndex; // Consumer Index register (in Tachyon) - ULONG length; // Length register - ULONG base; -} TachLiteSFQ; - - -typedef struct // I/O Request Block flags -{ - UCHAR BRD : 1; - UCHAR : 1; // reserved - UCHAR SFA : 1; - UCHAR DNC : 1; - UCHAR DIN : 1; - UCHAR DCM : 1; - UCHAR CTS : 1; - UCHAR SBV : 1; // IRB entry valid - IRB'B' only -} IRBflags; - -typedef struct // I/O Request Block -{ // Request 'A' - ULONG Req_A_SFS_Len; // total frame len (hdr + payload), min 32 - ULONG Req_A_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent) - ULONG Req_A_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa) - ULONG Req_A_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST - // Request 'B' - ULONG Req_B_SFS_Len; // total frame len (hdr + payload), min 32 - ULONG Req_B_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent) - ULONG Req_B_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa) - ULONG Req_B_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST -} TachLiteIRB; - - -typedef struct // TachLite placeholder for IRBs -{ // aligned @sizeof(ERQ) for TachLite - // MAX commands is sum of SEST len and ERQ - // we know that each SEST entry requires an - // IRB (ERQ) entry; in addition, we provide - // ERQ_LEN - TachLiteIRB QEntry[ERQ_LEN]; // Base register; entries 32 bytes ea. - ULONG consumerIndex; // Consumer Index register - ULONG producerIndex; // ERQ Producer Index register - ULONG length; // Length register - ULONG base; // copy of base ptr for debug - // struct is sized for largest expected cmnd (LOGIN) -} TachLiteERQ; - -// for now, just 32 bit DMA, eventually 40something, with code changes -#define CPQFCTS_DMA_MASK ((unsigned long) (0x00000000FFFFFFFF)) - -#define TL_MAX_SG_ELEM_LEN 0x7ffff // Max buffer length a single S/G entry - // may represent (a hardware limitation). The - // only reason to ever change this is if you - // want to exercise very-hard-to-reach code in - // cpqfcTSworker.c:build_SEST_sglist(). - -#define TL_DANGER_SGPAGES 7 // arbitrary high water mark for # of S/G pages - // we must exceed to elicit a warning indicative - // of EXTREMELY large data transfers or - // EXTREME memory fragmentation. - // (means we just used up 2048 S/G elements, - // Never seen this is real life, only in - // testing with tricked up driver.) - -#define TL_EXT_SG_PAGE_COUNT 256 // Number of Extended Scatter/Gather a/l PAIRS - // Tachyon register (IOBaseU 0x68) - // power-of-2 value ONLY! 4 min, 256 max - - // byte len is #Pairs * 2 ULONG/Pair * 4 bytes/ULONG -#define TL_EXT_SG_PAGE_BYTELEN (TL_EXT_SG_PAGE_COUNT *2 *4) - - - -// SEST entry types: IWE, IRE, TWE, TRE -typedef struct -{ - ULONG Hdr_Len; - ULONG Hdr_Addr; - ULONG RSP_Len; - ULONG RSP_Addr; - ULONG Buff_Off; -#define USES_EXTENDED_SGLIST(this_sest, x_ID) \ - (!((this_sest)->u[ x_ID ].IWE.Buff_Off & 0x80000000)) - ULONG Link; - ULONG RX_ID; - ULONG Data_Len; - ULONG Exp_RO; - ULONG Exp_Byte_Cnt; - // --- extended/local Gather Len/Address pairs - ULONG GLen1; - ULONG GAddr1; - ULONG GLen2; - ULONG GAddr2; - ULONG GLen3; - ULONG GAddr3; -} TachLiteIWE; - - -typedef struct -{ - ULONG Seq_Accum; - ULONG reserved; // must clear to 0 - ULONG RSP_Len; - ULONG RSP_Addr; - ULONG Buff_Off; - ULONG Buff_Index; // ULONG 5 - ULONG Exp_RO; - ULONG Byte_Count; - ULONG reserved_; // ULONG 8 - ULONG Exp_Byte_Cnt; - // --- extended/local Scatter Len/Address pairs - ULONG SLen1; - ULONG SAddr1; - ULONG SLen2; - ULONG SAddr2; - ULONG SLen3; - ULONG SAddr3; -} TachLiteIRE; - - -typedef struct // Target Write Entry -{ - ULONG Seq_Accum; // dword 0 - ULONG reserved; // dword 1 must clear to 0 - ULONG Remote_Node_ID; - ULONG reserved1; // dword 3 must clear to 0 - ULONG Buff_Off; - ULONG Buff_Index; // ULONG 5 - ULONG Exp_RO; - ULONG Byte_Count; - ULONG reserved_; // ULONG 8 - ULONG Exp_Byte_Cnt; - // --- extended/local Scatter Len/Address pairs - ULONG SLen1; - ULONG SAddr1; - ULONG SLen2; - ULONG SAddr2; - ULONG SLen3; - ULONG SAddr3; -} TachLiteTWE; - -typedef struct -{ - ULONG Hdr_Len; - ULONG Hdr_Addr; - ULONG RSP_Len; // DWord 2 - ULONG RSP_Addr; - ULONG Buff_Off; - ULONG Buff_Index; // DWord 5 - ULONG reserved; - ULONG Data_Len; - ULONG reserved_; - ULONG reserved__; - // --- extended/local Gather Len/Address pairs - ULONG GLen1; // DWord A - ULONG GAddr1; - ULONG GLen2; - ULONG GAddr2; - ULONG GLen3; - ULONG GAddr3; -} TachLiteTRE; - -typedef struct ext_sg_page_ptr_t *PSGPAGES; -typedef struct ext_sg_page_ptr_t -{ - unsigned char page[TL_EXT_SG_PAGE_BYTELEN * 2]; // 2x for alignment - dma_addr_t busaddr; // need the bus addresses and - unsigned int maplen; // lengths for later pci unmapping. - PSGPAGES next; -} SGPAGES; // linked list of S/G pairs, by Exchange - -typedef struct // SCSI Exchange State Table -{ - union // Entry can be IWE, IRE, TWE, TRE - { // 64 bytes per entry - TachLiteIWE IWE; - TachLiteIRE IRE; - TachLiteTWE TWE; - TachLiteTRE TRE; - } u[TACH_SEST_LEN]; - - TachFCHDR DataHDR[TACH_SEST_LEN]; // for SEST FCP_DATA frame hdr (no pl) - TachFCHDR_RSP RspHDR[TACH_SEST_LEN]; // space for SEST FCP_RSP frame - PSGPAGES sgPages[TACH_SEST_LEN]; // head of linked list of Pool-allocations - ULONG length; // Length register - ULONG base; // copy of base ptr for debug -} TachSEST; - - - -typedef struct // each register has it's own address - // and value (used for write-only regs) -{ - void* address; - volatile ULONG value; -} FCREGISTER; - -typedef struct // Host copy - TachLite Registers -{ - ULONG IOBaseL, IOBaseU; // I/O port lower and upper TL register addresses - ULONG MemBase; // memory mapped register addresses - void* ReMapMemBase; // O/S VM reference for MemBase - ULONG wwn_hi; // WWN is set once at startup - ULONG wwn_lo; - ULONG my_al_pa; // al_pa received after LIP() - ULONG ROMCTR; // flags for on-board RAM/ROM - ULONG RAMBase; // on-board RAM (i.e. some Tachlites) - ULONG SROMBase; // on-board EEPROM (some Tachlites) - ULONG PCIMCTR; // PCI Master Control Reg (has bus width) - - FCREGISTER INTEN; // copy of interrupt enable mask - FCREGISTER INTPEND; // interrupt pending - FCREGISTER INTSTAT; // interrupt status - FCREGISTER SFQconsumerIndex; - FCREGISTER ERQproducerIndex; - FCREGISTER TYconfig; // TachYon (chip level) - FCREGISTER TYcontrol; - FCREGISTER TYstatus; - FCREGISTER FMconfig; // Frame Manager (FC loop level) - FCREGISTER FMcontrol; - FCREGISTER FMstatus; - FCREGISTER FMLinkStatus1; - FCREGISTER FMLinkStatus2; - FCREGISTER FMBB_CreditZero; - FCREGISTER status; - FCREGISTER ed_tov; // error detect time-out value - FCREGISTER rcv_al_pa; // received arb. loop physical address - FCREGISTER primitive; // e.g. LIP(), OPN(), ... -} TL_REGISTERS; - - - -typedef struct -{ - ULONG ok; - ULONG invalidArgs; - ULONG linkDown; - ULONG linkUp; - ULONG outQueFull; - ULONG SESTFull; - ULONG hpe; // host programming err (from Tach) - ULONG FC4aborted; // aborts from Application or upper driver layer - ULONG FC2aborted; // aborts from our driver's timeouts - ULONG timeouts; // our driver timeout (on individual exchanges) - ULONG logouts; // explicit - sent LOGO; implicit - device removed - ULONG retries; - ULONG linkFailTX; - ULONG linkFailRX; - ULONG CntErrors; // byte count expected != count received (typ. SEST) - ULONG e_stores; // elastic store errs - ULONG resets; // hard or soft controller resets - ULONG FMinits; // TACH Frame Manager Init (e.g. LIPs) - ULONG lnkQueFull; // too many LOGIN, loop commands - ULONG ScsiQueFull; // too many FCP-SCSI inbound frames - ULONG LossofSignal; // FM link status 1 regs - ULONG BadRXChar; // FM link status 1 regs - ULONG LossofSync; // FM link status 1 regs - ULONG Rx_EOFa; // FM link status 2 regs (received EOFa) - ULONG Dis_Frm; // FM link status 2 regs (discarded frames) - ULONG Bad_CRC; // FM link status 2 regs - ULONG BB0_Timer; // FM BB_Credit Zero Timer Reg - ULONG loopBreaks; // infinite loop exits - ULONG lastBB0timer; // static accum. buffer needed by Tachlite -} FCSTATS; - - -typedef struct // Config Options -{ // LS Bit first - USHORT : 1; // bit0: - USHORT flogi : 1; // bit1: We sent FLOGI - wait for Fabric logins - USHORT fabric: 1; // bit2: Tachyon detected Fabric (FM stat LG) - USHORT LILPin: 1; // bit3: We can use an FC-AL LILP frame - USHORT target: 1; // bit4: this Port has SCSI target capability - USHORT initiator: 1; // bit5: this Port has SCSI initiator capability - USHORT extLoopback: 1; // bit6: loopback at GBIC - USHORT intLoopback: 1; // bit7: loopback in HP silicon - USHORT : 1; // bit8: - USHORT : 1; // bit9: - USHORT : 1; // bit10: - USHORT : 1; // bit11: - USHORT : 1; // bit12: - USHORT : 1; // bit13: - USHORT : 1; // bit14: - USHORT : 1; // bit15: -} FC_OPTIONS; - - - -typedef struct dyn_mem_pair -{ - void *BaseAllocated; // address as allocated from O/S; - unsigned long AlignedAddress; // aligned address (used by Tachyon DMA) - dma_addr_t dma_handle; - size_t size; -} ALIGNED_MEM; - - - - -// these structs contain only CRUCIAL (stuff we actually use) parameters -// from FC-PH(n) logins. (Don't save entire LOGIN payload to save mem.) - -// Implicit logout happens when the loop goes down - we require PDISC -// to restore. Explicit logout is when WE decide never to talk to someone, -// or when a target refuses to talk to us, i.e. sends us a LOGO frame or -// LS_RJT reject in response to our PLOGI request. - -#define IMPLICIT_LOGOUT 1 -#define EXPLICIT_LOGOUT 2 - -typedef struct -{ - UCHAR channel; // SCSI "bus" - UCHAR target; - UCHAR InqDeviceType; // byte 0 from SCSI Inquiry response - UCHAR VolumeSetAddressing; // FCP-SCSI LUN coding (40h for VSA) - UCHAR LunMasking; // True if selective presentation supported - UCHAR lun[CPQFCTS_MAX_LUN]; -} SCSI_NEXUS; - - -typedef struct -{ - union - { - UCHAR ucWWN[8]; // a FC 64-bit World Wide Name/ PortID of target - // addressing of single target on single loop... - u64 liWWN; - } u; - - ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa) - -#define REPORT_LUNS_PL 256 - UCHAR ReportLunsPayload[REPORT_LUNS_PL]; - - SCSI_NEXUS ScsiNexus; // LUNs per FC device - - ULONG LOGO_counter; // might try several times before logging out for good - ULONG LOGO_timer; // after LIP, ports expecting PDISC must time-out and - // LOGOut if successful PDISC not completed in 2 secs - - ULONG concurrent_seq; // must be 1 or greater - ULONG rx_data_size; // e.g. 128, 256, 1024, 2048 per FC-PH spec - ULONG BB_credit; - ULONG EE_credit; - - ULONG fcp_info; // from PRLI (i.e. INITIATOR/ TARGET flags) - // flags for login process - BOOLEAN Originator; // Login sequence Originated (if false, we - // responded to another port's login sequence) - BOOLEAN plogi; // PLOGI frame ACCepted (originated or responded) - BOOLEAN pdisc; // PDISC frame was ORIGINATED (self-login logic) - BOOLEAN prli; // PRLI frame ACCepted (originated or responded) - BOOLEAN flogi; // FLOGI frame ACCepted (originated or responded) - BOOLEAN logo; // port permanently logged out (invalid login param) - BOOLEAN flogiReq; // Fabric login required (set in LIP process) - UCHAR highest_ver; - UCHAR lowest_ver; - - - // when the "target" (actually FC Port) is waiting for login - // (e.g. after Link reset), set the device_blocked bit; - // after Port completes login, un-block target. - UCHAR device_blocked; // see Scsi_Device struct - - // define singly-linked list of logged-in ports - // once a port_id is identified, it is remembered, - // even if the port is removed indefinitely - PVOID pNextPort; // actually, type PFC_LOGGEDIN_PORT; void for Compiler - -} FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT; - - - -// This serves as the ESB (Exchange Status Block), -// and has timeout counter; used for ABORTs -typedef struct -{ // FC-1 X_IDs - ULONG type; // ELS_PLOGI, SCSI_IWE, ... (0 if free) - PFC_LOGGEDIN_PORT pLoggedInPort; // FC device on other end of Exchange - Scsi_Cmnd *Cmnd; // Linux SCSI command packet includes S/G list - ULONG timeOut; // units of ??, DEC by driver, Abort when 0 - ULONG reTries; // need one or more retries? - ULONG status; // flags indicating errors (0 if none) - TachLiteIRB IRB; // I/O Request Block, gets copied to ERQ - TachFCHDR_GCMND fchs; // location of IRB's Req_A_SFS_Addr -} FC_EXCHANGE, *PFC_EXCHANGE; - -// Unfortunately, Linux limits our kmalloc() allocations to 128k. -// Because of this and the fact that our ScsiRegister allocation -// is also constrained, we move this large structure out for -// allocation after Scsi Register. -// (In other words, this cumbersome indirection is necessary -// because of kernel memory allocation constraints!) - -typedef struct // we will allocate this dynamically -{ - FC_EXCHANGE fcExchange[ TACH_MAX_XID ]; -} FC_EXCHANGES; - - - - - - - - - - - -typedef struct -{ - char Name[64]; // name of controller ("HP Tachlite TL Rev2.0, 33MHz, 64bit bus") - //PVOID pAdapterDevExt; // back pointer to device object/extension - ULONG ChipType; // local numeric key for Tachyon Type / Rev. - ULONG status; // our Driver - logical status - - TL_REGISTERS Registers; // reg addresses & host memory copies - // FC-4 mapping of 'transaction' to X_IDs - UCHAR LILPmap[32*4]; // Loop Position Map of ALPAs (late FC-AL only) - FC_OPTIONS Options; // e.g. Target, Initiator, loopback... - UCHAR highest_FCPH_ver; // FC-PH version limits - UCHAR lowest_FCPH_ver; // FC-PH version limits - - FC_EXCHANGES *Exchanges; - ULONG fcLsExchangeLRU; // Least Recently Used counter (Link Service) - ULONG fcSestExchangeLRU; // Least Recently Used counter (FCP-SCSI) - FC_LOGGEDIN_PORT fcPorts; // linked list of every FC port ever seen - FCSTATS fcStats; // FC comm err counters - - // Host memory QUEUE pointers - TachLiteERQ *ERQ; // Exchange Request Que - TachyonIMQ *IMQ; // Inbound Message Que - TachLiteSFQ *SFQ; // Single Frame Queue - TachSEST *SEST; // SCSI Exchange State Table - - dma_addr_t exch_dma_handle; - - // these function pointers are for "generic" functions, which are - // replaced with Host Bus Adapter types at - // runtime. - int (*CreateTachyonQues)( void* , int); - int (*DestroyTachyonQues)( void* , int); - int (*LaserControl)(void*, int ); // e.g. On/Off - int (*ResetTachyon)(void*, int ); - void (*FreezeTachyon)(void*, int ); - void (*UnFreezeTachyon)(void*, int ); - int (*InitializeTachyon)(void*, int, int ); - int (*InitializeFrameManager)(void*, int ); - int (*ProcessIMQEntry)(void*); - int (*ReadWriteWWN)(void*, int ReadWrite); - int (*ReadWriteNVRAM)(void*, void*, int ReadWrite); - -} TACHYON, *PTACHYON; - - -void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip); - -int CpqTsCreateTachLiteQues( void* pHBA, int opcode); -int CpqTsDestroyTachLiteQues( void* , int); -int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2); - -int CpqTsProcessIMQEntry(void* pHBA); -int CpqTsResetTachLite(void *pHBA, int type); -void CpqTsFreezeTachlite(void *pHBA, int type); -void CpqTsUnFreezeTachlite(void *pHBA, int type); -int CpqTsInitializeFrameManager(void *pHBA, int); -int CpqTsLaserControl( void* addrBase, int opcode ); -int CpqTsReadWriteWWN(void*, int ReadWrite); -int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite); - -void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter); -void cpqfcTSWorkerThread( void *host); - -int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf ); -ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count, - UCHAR *buf ); - -BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout, - USHORT startOffset, // e.g. 0x2f for WWN start - USHORT count, - UCHAR *buf ); - - -// define misc functions -int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]); -int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]); -void* fcMemManager( struct pci_dev *pdev, - ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab, - ULONG ulAlignedAddress, dma_addr_t *dma_handle); - -void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt); - -//ULONG virt_to_phys( PVOID virtaddr ); - - -// Linux interrupt handler -irqreturn_t cpqfcTS_intr_handler( int irq,void *dev_id,struct pt_regs *regs); -void cpqfcTSheartbeat( unsigned long ptr ); - - - -// The biggest Q element we deal with is Aborts - we -// need 4 bytes for x_ID, and a Scsi_Cmnd (~284 bytes) -//#define LINKQ_ITEM_SIZE ((4+sizeof(Scsi_Cmnd)+3)/4) -#define LINKQ_ITEM_SIZE (3*16) -typedef struct -{ - ULONG Type; // e.g. LINKUP, SFQENTRY, PDISC, BLS_ABTS, ... - ULONG ulBuff[ LINKQ_ITEM_SIZE ]; -} LINKQ_ITEM; - -#define FC_LINKQ_DEPTH TACH_MAX_XID -typedef struct -{ - ULONG producer; - ULONG consumer; // when producer equals consumer, Q empty - - LINKQ_ITEM Qitem[ FC_LINKQ_DEPTH ]; - -} FC_LINK_QUE, *PFC_LINK_QUE; - - - // DPC routines post to here on Inbound SCSI frames - // User thread processes -#define FC_SCSIQ_DEPTH 32 - -typedef struct -{ - int Type; // e.g. SCSI - ULONG ulBuff[ 3*16 ]; -} SCSIQ_ITEM; - -typedef struct -{ - ULONG producer; - ULONG consumer; // when producer equals consumer, Q empty - - SCSIQ_ITEM Qitem[ FC_SCSIQ_DEPTH ]; - -} FC_SCSI_QUE, *PFC_SCSI_QUE; - -typedef struct { - /* This is tacked on to a Scsi_Request in upper_private_data - for pasthrough ioctls, as a place to hold data that can't - be stashed anywhere else in the Scsi_Request. We differentiate - this from _real_ upper_private_data by checking if the virt addr - is within our special pool. */ - ushort bus; - ushort pdrive; -} cpqfc_passthru_private_t; - -#define CPQFC_MAX_PASSTHRU_CMDS 100 - -#define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST - -// Linux space allocated per HBA (chip state, etc.) -typedef struct -{ - struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct - - TACHYON fcChip; // All Tachyon registers, Queues, functions - ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS]; - - struct pci_dev *PciDev; - dma_addr_t fcLQ_dma_handle; - - Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn - // (for Acceptable targets) - Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full - - Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets - - u_char HBAnum; // 0-based host number - - - struct timer_list cpqfcTStimer; // FC utility timer for implicit - // logouts, FC protocol timeouts, etc. - int fcStatsTime; // Statistics delta reporting time - - struct task_struct *worker_thread; // our kernel thread - int PortDiscDone; // set by SendLogins(), cleared by LDn - - struct semaphore *TachFrozen; - struct semaphore *TYOBcomplete; // handshake for Tach outbound frames - struct semaphore *fcQueReady; // FibreChannel work for our kernel thread - struct semaphore *notify_wt; // synchronizes kernel thread kill - struct semaphore *BoardLock; - - PFC_LINK_QUE fcLQ; // the WorkerThread operates on this - - spinlock_t hba_spinlock; // held/released by WorkerThread - cpqfc_passthru_private_t *private_data_pool; - unsigned long *private_data_bits; - -} CPQFCHBA; - -#define CPQ_SPINLOCK_HBA( x ) spin_lock(&x->hba_spinlock); -#define CPQ_SPINUNLOCK_HBA(x) spin_unlock(&x->hba_spinlock); - - - -void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata, - PFC_LOGGEDIN_PORT pFcPort); - - -void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int ); - -PFC_LOGGEDIN_PORT fcPortLoggedIn( - CPQFCHBA *cpqfcHBAdata, - TachFCHDR_GCMND* fchs, - BOOLEAN, - BOOLEAN); -void fcProcessLoggedIn( - CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs); - - -ULONG cpqfcTSBuildExchange( - CPQFCHBA *cpqfcHBAdata, - ULONG type, // e.g. PLOGI - TachFCHDR_GCMND* InFCHS, // incoming FCHS - void *Data, // the CDB, scatter/gather, etc. - LONG *ExchangeID ); // allocated exchange ID - -ULONG cpqfcTSStartExchange( - CPQFCHBA *cpqfcHBAdata, - LONG ExchangeID ); - -void cpqfcTSCompleteExchange( - struct pci_dev *pcidev, - PTACHYON fcChip, - ULONG exchange_ID); - - -PFC_LOGGEDIN_PORT fcFindLoggedInPort( - PTACHYON fcChip, - Scsi_Cmnd *Cmnd, // (We want the channel/target/lun Nexus from Cmnd) - ULONG port_id, // search linked list for al_pa, or - UCHAR wwn[8], // search linked list for WWN, or... - PFC_LOGGEDIN_PORT *pLastLoggedInPort -); - -void cpqfcTSPutLinkQue( - CPQFCHBA *cpqfcHBAdata, - int Type, - void *QueContent); - -void fcPutScsiQue( - CPQFCHBA *cpqfcHBAdata, - int Type, - void *QueContent); - -void fcLinkQReset( - CPQFCHBA *); -void fcScsiQReset( - CPQFCHBA *); -void fcSestReset( - CPQFCHBA *); - -void cpqfc_pci_unmap(struct pci_dev *pcidev, - Scsi_Cmnd *cmd, - PTACHYON fcChip, - ULONG x_ID); - -extern const UCHAR valid_al_pa[]; -extern const int number_of_al_pa; - -#define FCP_RESID_UNDER 0x80000 -#define FCP_RESID_OVER 0x40000 -#define FCP_SNS_LEN_VALID 0x20000 -#define FCP_RSP_LEN_VALID 0x10000 - -// RSP_CODE definitions (dpANS Fibre Channel Protocol for SCSI, pg 34) -#define FCP_DATA_LEN_NOT_BURST_LEN 0x1000000 -#define FCP_CMND_FIELD_INVALID 0x2000000 -#define FCP_DATA_RO_NOT_XRDY_RO 0x3000000 -#define FCP_TASKFUNCTION_NS 0x4000000 -#define FCP_TASKFUNCTION_FAIL 0x5000000 - -// FCP-SCSI response status struct -typedef struct // see "TachFCHDR_RSP" definition - 64 bytes -{ - __u32 reserved; - __u32 reserved1; - __u32 fcp_status; // field validity and SCSI status - __u32 fcp_resid; - __u32 fcp_sns_len; // length of FCP_SNS_INFO field - __u32 fcp_rsp_len; // length of FCP_RSP_INFO field (expect 8) - __u32 fcp_rsp_info; // 4 bytes of FCP protocol response information - __u32 fcp_rsp_info2; // (4 more bytes, since most implementations use 8) - __u8 fcp_sns_info[36]; // bytes for SCSI sense (ASC, ASCQ) - -} FCP_STATUS_RESPONSE, *PFCP_STATUS_RESPONSE; - - -// Fabric State Change Registration -typedef struct scrpl -{ - __u32 command; - __u32 function; -} SCR_PL; - -// Fabric Name Service Request -typedef struct nsrpl -{ - __u32 CT_Rev; // (& IN_ID) WORD 0 - __u32 FCS_Type; // WORD 1 - __u32 Command_code; // WORD 2 - __u32 reason_code; // WORD 3 - __u32 FCP; // WORD 4 (lower byte) - -} NSR_PL; - - - -// "FC.H" -#define MAX_RX_SIZE 0x800 // Max Receive Buffer Size is 2048 -#define MIN_RX_SIZE 0x100 // Min Size is 256, per FC-PLDA Spec -#define MAX_TARGET_RXIDS SEST_DEPTH -#define TARGET_RX_SIZE SEST_BUFFER_LENGTH - -#define CLASS_1 0x01 -#define CLASS_2 0x02 -#define CLASS_3 0x03 - -#define FC_PH42 0x08 -#define FC_PH43 0x09 -#define FC_PH3 0x20 - -#define RR_TOV 2 // Minimum Time for target to wait for - // PDISC after a LIP. -#define E_D_TOV 2 // Minimum Time to wait for Sequence - // Completion. -#define R_A_TOV 0 // Minimum Time for Target to wait - // before reclaiming resources. -// -// R_CTL Field -// -// Routing Bits (31-28) -// -#define FC4_DEVICE_DATA 0x00000000 -#define EXT_LINK_DATA 0x20000000 -#define FC4_LINK_DATA 0x30000000 -#define VIDEO_DATA 0x40000000 -#define BASIC_LINK_DATA 0x80000000 -#define LINK_CONTROL 0xC0000000 -#define ROUTING_MASK 0xF0000000 - -// -// Information Bits (27-24) -// -#define UNCAT_INFORMATION 0x00000000 -#define SOLICITED_DATA 0x01000000 -#define UNSOLICITED_CONTROL 0x02000000 -#define SOLICITED_CONTROL 0x03000000 -#define UNSOLICITED_DATA 0x04000000 -#define DATA_DESCRIPTOR 0x05000000 -#define UNSOLICITED_COMMAND 0x06000000 -#define COMMAND_STATUS 0x07000000 -#define INFO_MASK 0x0F000000 -// -// (Link Control Codes) -// -#define ACK_1 0x00000000 -#define ACK_0_OR_N 0x01000000 -#define P_RJT 0x02000000 -#define F_RJT 0x03000000 -#define P_BSY 0x04000000 -#define FABRIC_BUSY_TO_DF 0x05000000 // Fabric Busy to Data Frame -#define FABRIC_BUSY_TO_LC 0x06000000 // Fabric Busy to Link Ctl Frame -#define LINK_CREDIT_RESET 0x07000000 -// -// (Link Service Command Codes) -// -//#define LS_RJT 0x01000000 // LS Reject - -#define LS_ACC 0x02000000 // LS Accept -#define LS_PLOGI 0x03000000 // N_PORT Login -#define LS_FLOGI 0x04000000 // F_PORT Login -#define LS_LOGO 0x05000000 // Logout -#define LS_ABTX 0x06000000 // Abort Exchange -#define LS_RCS 0x07000000 // Read Connection Status -#define LS_RES 0x08000000 // Read Exchange Status -#define LS_RSS 0x09000000 // Read Sequence Status -#define LS_RSI 0x0A000000 // Request Seq Initiative -#define LS_ESTS 0x0B000000 // Establish Steaming -#define LS_ESTC 0x0C000000 // Estimate Credit -#define LS_ADVC 0x0D000000 // Advice Credit -#define LS_RTV 0x0E000000 // Read Timeout Value -#define LS_RLS 0x0F000000 // Read Link Status -#define LS_ECHO 0x10000000 // Echo -#define LS_TEST 0x11000000 // Test -#define LS_RRQ 0x12000000 // Reinstate Rec. Qual. -#define LS_PRLI 0x20000000 // Process Login -#define LS_PRLO 0x21000000 // Process Logout -#define LS_TPRLO 0x24000000 // 3rd Party Process Logout -#define LS_PDISC 0x50000000 // Process Discovery -#define LS_FDISC 0x51000000 // Fabric Discovery -#define LS_ADISC 0x52000000 // Discover Address -#define LS_RNC 0x53000000 // Report Node Capability -#define LS_SCR 0x62000000 // State Change Registration -#define LS_MASK 0xFF000000 - -// -// TYPE Bit Masks -// -#define BASIC_LINK_SERVICE 0x00000000 -#define EXT_LINK_SERVICE 0x01000000 - -#define LLC 0x04000000 -#define LLC_SNAP 0x05000000 -#define SCSI_FCP 0x08000000 -#define SCSI_GPP 0x09000000 -#define IPI3_MASTER 0x11000000 -#define IPI3_SLAVE 0x12000000 -#define IPI3_PEER 0x13000000 -#define CP_IPI3_MASTER 0x15000000 -#define CP_IPI3_SLAVE 0x16000000 -#define CP_IPI3_PEER 0x17000000 -#define SBCCS_CHANNEL 0x19000000 -#define SBCCS_CONTROL 0x1A000000 -#define FIBRE_SERVICES 0x20000000 -#define FC_FG 0x21000000 -#define FC_XS 0x22000000 -#define FC_AL 0x23000000 -#define SNMP 0x24000000 -#define HIPPI_FP 0x40000000 -#define TYPE_MASK 0xFF000000 - -typedef struct { - UCHAR seq_id_valid; - UCHAR seq_id; - USHORT reserved; // 2 bytes reserved - ULONG ox_rx_id; - USHORT low_seq_cnt; - USHORT high_seq_cnt; -} BA_ACC_PAYLOAD; - -typedef struct { - UCHAR reserved; - UCHAR reason_code; - UCHAR reason_explain; - UCHAR vendor_unique; -} BA_RJT_PAYLOAD; - - -typedef struct { - ULONG command_code; - ULONG sid; - USHORT ox_id; - USHORT rx_id; -} RRQ_MESSAGE; - -typedef struct { - ULONG command_code; - UCHAR vendor; - UCHAR explain; - UCHAR reason; - UCHAR reserved; -} REJECT_MESSAGE; - - -#define N_OR_F_PORT 0x1000 -#define RANDOM_RELATIVE_OFFSET 0x4000 -#define CONTINUOSLY_INCREASING 0x8000 - -#define CLASS_VALID 0x8000 -#define INTERMIX_MODE 0x4000 -#define TRANSPARENT_STACKED 0x2000 -#define LOCKDOWN_STACKED 0x1000 -#define SEQ_DELIVERY 0x800 - -#define XID_NOT_SUPPORTED 0x00 -#define XID_SUPPORTED 0x4000 -#define XID_REQUIRED 0xC000 - -#define ASSOCIATOR_NOT_SUPPORTED 0x00 -#define ASSOCIATOR_SUPPORTED 0x1000 -#define ASSOCIATOR_REQUIRED 0x3000 - -#define INIT_ACK0_SUPPORT 0x800 -#define INIT_ACKN_SUPPORT 0x400 - -#define RECIP_ACK0_SUPPORT 0x8000 -#define RECIP_ACKN_SUPPORT 0x4000 - -#define X_ID_INTERLOCK 0x2000 - -#define ERROR_POLICY 0x1800 // Error Policy Supported -#define ERROR_DISCARD 0x00 // Only Discard Supported -#define ERROR_DISC_PROCESS 0x02 // Discard and process supported - -#define NODE_ID 0x01 -#define IEEE_EXT 0x20 - -// -// Categories Supported Per Sequence -// -#define CATEGORIES_PER_SEQUENCE 0x300 -#define ONE_CATEGORY_SEQUENCE 0x00 // 1 Category per Sequence -#define TWO_CATEGORY_SEQUENCE 0x01 // 2 Categories per Sequence -#define MANY_CATEGORY_SEQUENCE 0x03 // > 2 Categories/Sequence - -typedef struct { - - USHORT initiator_control; - USHORT service_options; - - USHORT rx_data_size; - USHORT recipient_control; - - USHORT ee_credit; - USHORT concurrent_sequences; - - USHORT reserved; - USHORT open_sequences; - -} CLASS_PARAMETERS; - -typedef struct { - ULONG login_cmd; - // - // Common Service Parameters - // - struct { - - USHORT bb_credit; - UCHAR lowest_ver; - UCHAR highest_ver; - - USHORT bb_rx_size; - USHORT common_features; - - USHORT rel_offset; - USHORT concurrent_seq; - - - ULONG e_d_tov; - } cmn_services; - - // - // Port Name - // - UCHAR port_name[8]; - - // - // Node/Fabric Name - // - UCHAR node_name[8]; - - // - // Class 1, 2 and 3 Service Parameters - // - CLASS_PARAMETERS class1; - CLASS_PARAMETERS class2; - CLASS_PARAMETERS class3; - - ULONG reserved[4]; - - // - // Vendor Version Level - // - UCHAR vendor_id[2]; - UCHAR vendor_version[6]; - ULONG buffer_size; - USHORT rxid_start; - USHORT total_rxids; -} LOGIN_PAYLOAD; - - -typedef struct -{ - ULONG cmd; // 4 bytes - UCHAR n_port_identifier[3]; - UCHAR reserved; - UCHAR port_name[8]; -} LOGOUT_PAYLOAD; - - -// -// PRLI Request Service Parameter Defines -// -#define PRLI_ACC 0x01 -#define PRLI_REQ 0x02 -#define ORIG_PROCESS_ASSOC_VALID 0x8000 -#define RESP_PROCESS_ASSOC_VALID 0x4000 -#define ESTABLISH_PAIR 0x2000 -#define DATA_OVERLAY_ALLOWED 0x40 -#define INITIATOR_FUNCTION 0x20 -#define TARGET_FUNCTION 0x10 -#define CMD_DATA_MIXED 0x08 -#define DATA_RESP_MIXED 0x04 -#define READ_XFER_RDY 0x02 -#define WRITE_XFER_RDY 0x01 - -#define RESPONSE_CODE_MASK 0xF00 -#define REQUEST_EXECUTED 0x100 -#define NO_RESOURCES 0x200 -#define INIT_NOT_COMPLETE 0x300 -#define IMAGE_DOES_NOT_EXIST 0x400 -#define BAD_PREDEFINED_COND 0x500 -#define REQ_EXEC_COND 0x600 -#define NO_MULTI_PAGE 0x700 - -typedef struct { - USHORT payload_length; - UCHAR page_length; - UCHAR cmd; - - - ULONG valid; - - ULONG orig_process_associator; - - ULONG resp_process_associator; - - ULONG fcp_info; -} PRLI_REQUEST; - -typedef struct { - - USHORT payload_length; - UCHAR page_length; - UCHAR cmd; - - ULONG valid; - ULONG orig_process_associator; - - ULONG resp_process_associator; - ULONG reserved; -} PRLO_REQUEST; - -typedef struct { - ULONG cmd; - - ULONG hard_address; - - UCHAR port_name[8]; - - UCHAR node_name[8]; - - ULONG s_id; -} ADISC_PAYLOAD; - -struct ext_sg_entry_t { - __u32 len:18; /* buffer length, bits 0-17 */ - __u32 uba:13; /* upper bus address bits 18-31 */ - __u32 lba; /* lower bus address bits 0-31 */ -}; - - -// J. McCarty's LINK.H -// -// LS_RJT Reason Codes -// - -#define INVALID_COMMAND_CODE 0x01 -#define LOGICAL_ERROR 0x03 -#define LOGICAL_BUSY 0x05 -#define PROTOCOL_ERROR 0x07 -#define UNABLE_TO_PERFORM 0x09 -#define COMMAND_NOT_SUPPORTED 0x0B -#define LS_VENDOR_UNIQUE 0xFF - -// -// LS_RJT Reason Codes Explanations -// -#define NO_REASON 0x00 -#define OPTIONS_ERROR 0x01 -#define INITIATOR_CTL_ERROR 0x03 -#define RECIPIENT_CTL_ERROR 0x05 -#define DATA_FIELD_SIZE_ERROR 0x07 -#define CONCURRENT_SEQ_ERROR 0x09 -#define CREDIT_ERROR 0x0B -#define INVALID_PORT_NAME 0x0D -#define INVALID_NODE_NAME 0x0E -#define INVALID_CSP 0x0F // Invalid Service Parameters -#define INVALID_ASSOC_HDR 0x11 // Invalid Association Header -#define ASSOC_HDR_REQUIRED 0x13 // Association Header Required -#define LS_INVALID_S_ID 0x15 -#define INVALID_OX_RX_ID 0x17 // Invalid OX_ID RX_ID Combination -#define CMD_IN_PROCESS 0x19 -#define INVALID_IDENTIFIER 0x1F // Invalid N_PORT Identifier -#define INVALID_SEQ_ID 0x21 -#define ABT_INVALID_XCHNG 0x23 // Attempt to Abort an invalid Exchange -#define ABT_INACTIVE_XCHNG 0x25 // Attempt to Abort an inactive Exchange -#define NEED_REC_QUAL 0x27 // Recovery Qualifier required -#define NO_LOGIN_RESOURCES 0x29 // No resources to support login -#define NO_DATA 0x2A // Unable to supply requested data -#define REQUEST_NOT_SUPPORTED 0x2C // Request Not Supported - -// -// Link Control Codes -// - -// -// P_BSY Action Codes -// -#define SEQUENCE_TERMINATED 0x01000000 -#define SEQUENCE_ACTIVE 0x02000000 - -// -// P_BSY Reason Codes -// -#define PHYS_NPORT_BUSY 0x010000 -#define NPORT_RESOURCE_BUSY 0x020000 - -// -// P_RJT, F_RJT Action Codes -// - -#define RETRYABLE_ERROR 0x01000000 -#define NON_RETRYABLE_ERROR 0x02000000 - -// -// P_RJT, F_RJT Reason Codes -// -#define INVALID_D_ID 0x010000 -#define INVALID_S_ID 0x020000 -#define NPORT_NOT_AVAIL_TMP 0x030000 -#define NPORT_NOT_AVAIL_PERM 0x040000 -#define CLASS_NOT_SUPPORTED 0x050000 -#define USAGE_ERROR 0x060000 -#define TYPE_NOT_SUPPORTED 0x070000 -#define INVAL_LINK_CONTROL 0x080000 -#define INVAL_R_CTL 0x090000 -#define INVAL_F_CTL 0x0A0000 -#define INVAL_OX_ID 0x0B0000 -#define INVAL_RX_ID 0x0C0000 -#define INVAL_SEQ_ID 0x0D0000 -#define INVAL_DF_CTL 0x0E0000 -#define INVAL_SEQ_CNT 0x0F0000 -#define INVAL_PARAMS 0x100000 -#define EXCHANGE_ERROR 0x110000 -#define LS_PROTOCOL_ERROR 0x120000 -#define INCORRECT_LENGTH 0x130000 -#define UNEXPECTED_ACK 0x140000 -#define LOGIN_REQ 0x160000 -#define EXCESSIVE_SEQ 0x170000 -#define NO_EXCHANGE 0x180000 -#define SEC_HDR_NOT_SUPPORTED 0x190000 -#define NO_FABRIC 0x1A0000 -#define P_VENDOR_UNIQUE 0xFF0000 - -// -// BA_RJT Reason Codes -// -#define BA_INVALID_COMMAND 0x00010000 -#define BA_LOGICAL_ERROR 0x00030000 -#define BA_LOGICAL_BUSY 0x00050000 -#define BA_PROTOCOL_ERROR 0x00070000 -#define BA_UNABLE_TO_PERFORM 0x00090000 - -// -// BA_RJT Reason Explanation Codes -// -#define BA_NO_REASON 0x00000000 -#define BA_INVALID_OX_RX 0x00000300 -#define BA_SEQUENCE_ABORTED 0x00000500 - - - -#endif /* CPQFCTSSTRUCTS_H */ - diff --git a/drivers/scsi/cpqfcTStrigger.c b/drivers/scsi/cpqfcTStrigger.c deleted file mode 100644 index dbb7e65159a0..000000000000 --- a/drivers/scsi/cpqfcTStrigger.c +++ /dev/null @@ -1,33 +0,0 @@ -// Routine to trigger Finisar GTA analyzer. Runs of GPIO2 -// NOTE: DEBUG ONLY! Could interfere with FCMNGR/Miniport operation -// since it writes directly to the Tachyon board. This function -// developed for Compaq HBA Tachyon TS v1.2 (Rev X5 PCB) - -#include "cpqfcTStrigger.h" -#if TRIGGERABLE_HBA - -#include -#include -#include -#include -#include - -void TriggerHBA( void* IOBaseUpper, int Print) -{ - __u32 long value; - - // get initial value in hopes of not modifying any other GPIO line - IOBaseUpper += 0x188; // TachTL/TS Control reg - - value = readl( IOBaseUpper); - // set HIGH to trigger external analyzer (tested on Dolche Finisar 1Gb GTA) - // The Finisar anaylzer triggers on low-to-high TTL transition - value |= 0x01; // set bit 0 - - writel( value, IOBaseUpper); - - if( Print) - printk( " -GPIO0 set- "); -} - -#endif diff --git a/drivers/scsi/cpqfcTStrigger.h b/drivers/scsi/cpqfcTStrigger.h deleted file mode 100644 index c961792e6be0..000000000000 --- a/drivers/scsi/cpqfcTStrigger.h +++ /dev/null @@ -1,8 +0,0 @@ -// don't do this unless you have the right hardware! -#define TRIGGERABLE_HBA 0 -#if TRIGGERABLE_HBA -void TriggerHBA( void*, int); -#else -#define TriggerHBA(x, y) -#endif - diff --git a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c deleted file mode 100644 index d822ddcc52b2..000000000000 --- a/drivers/scsi/cpqfcTSworker.c +++ /dev/null @@ -1,6516 +0,0 @@ -/* Copyright(c) 2000, Compaq Computer Corporation - * Fibre Channel Host Bus Adapter - * 64-bit, 66MHz PCI - * Originally developed and tested on: - * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... - * SP# P225CXCBFIEL6T, Rev XC - * SP# 161290-001, Rev XD - * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 - * - * 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. - * Written by Don Zimmerman -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) - -#include -#include -#include - -#include "scsi.h" -#include // struct Scsi_Host definition for T handler -#include "cpqfcTSchip.h" -#include "cpqfcTSstructs.h" -#include "cpqfcTStrigger.h" - -//#define LOGIN_DBG 1 - -// REMARKS: -// Since Tachyon chips may be permitted to wait from 500ms up to 2 sec -// to empty an outgoing frame from its FIFO to the Fibre Channel stream, -// we cannot do everything we need to in the interrupt handler. Specifically, -// every time a link re-init (e.g. LIP) takes place, all SCSI I/O has to be -// suspended until the login sequences have been completed. Login commands -// are frames just like SCSI commands are frames; they are subject to the same -// timeout issues and delays. Also, various specs provide up to 2 seconds for -// devices to log back in (i.e. respond with ACC to a login frame), so I/O to -// that device has to be suspended. -// A serious problem here occurs on highly loaded FC-AL systems. If our FC port -// has a low priority (e.g. high arbitrated loop physical address, alpa), and -// some other device is hogging bandwidth (permissible under FC-AL), we might -// time out thinking the link is hung, when it's simply busy. Many such -// considerations complicate the design. Although Tachyon assumes control -// (in silicon) for many link-specific issues, the Linux driver is left with the -// rest, which turns out to be a difficult, time critical chore. - -// These "worker" functions will handle things like FC Logins; all -// processes with I/O to our device must wait for the Login to complete -// and (if successful) I/O to resume. In the event of a malfunctioning or -// very busy loop, it may take hundreds of millisecs or even seconds to complete -// a frame send. We don't want to hang up the entire server (and all -// processes which don't depend on Fibre) during this wait. - -// The Tachyon chip can have around 30,000 I/O operations ("exchanges") -// open at one time. However, each exchange must be initiated -// synchronously (i.e. each of the 30k I/O had to be started one at a -// time by sending a starting frame via Tachyon's outbound que). - -// To accommodate kernel "module" build, this driver limits the exchanges -// to 256, because of the contiguous physical memory limitation of 128M. - -// Typical FC Exchanges are opened presuming the FC frames start without errors, -// while Exchange completion is handled in the interrupt handler. This -// optimizes performance for the "everything's working" case. -// However, when we have FC related errors or hot plugging of FC ports, we pause -// I/O and handle FC-specific tasks in the worker thread. These FC-specific -// functions will handle things like FC Logins and Aborts. As the Login sequence -// completes to each and every target, I/O can resume to that target. - -// Our kernel "worker thread" must share the HBA with threads calling -// "queuecommand". We define a "BoardLock" semaphore which indicates -// to "queuecommand" that the HBA is unavailable, and Cmnds are added to a -// board lock Q. When the worker thread finishes with the board, the board -// lock Q commands are completed with status causing immediate retry. -// Typically, the board is locked while Logins are in progress after an -// FC Link Down condition. When Cmnds are re-queued after board lock, the -// particular Scsi channel/target may or may not have logged back in. When -// the device is waiting for login, the "prli" flag is clear, in which case -// commands are passed to a Link Down Q. Whenever the login finally completes, -// the LinkDown Q is completed, again with status causing immediate retry. -// When FC devices are logged in, we build and start FC commands to the -// devices. - -// NOTE!! As of May 2000, kernel 2.2.14, the error recovery logic for devices -// that never log back in (e.g. physically removed) is NOT completely -// understood. I've still seen instances of system hangs on failed Write -// commands (possibly from the ext2 layer?) on device removal. Such special -// cases need to be evaluated from a system/application view - e.g., how -// exactly does the system want me to complete commands when the device is -// physically removed?? - -// local functions - -static void SetLoginFields( - PFC_LOGGEDIN_PORT pLoggedInPort, - TachFCHDR_GCMND* fchs, - BOOLEAN PDisc, - BOOLEAN Originator); - -static void AnalyzeIncomingFrame( - CPQFCHBA *cpqfcHBAdata, - ULONG QNdx ); - -static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds ); - -static int verify_PLOGI( PTACHYON fcChip, - TachFCHDR_GCMND* fchs, ULONG* reject_explain); -static int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain); - -static void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type); -static void BuildLinkServicePayload( - PTACHYON fcChip, ULONG type, void* payload); - -static void UnblockScsiDevice( struct Scsi_Host *HostAdapter, - PFC_LOGGEDIN_PORT pLoggedInPort); - -static void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID); - -static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata); - -static void RevalidateSEST( struct Scsi_Host *HostAdapter, - PFC_LOGGEDIN_PORT pLoggedInPort); - -static void IssueReportLunsCommand( - CPQFCHBA* cpqfcHBAdata, - TachFCHDR_GCMND* fchs); - -// (see scsi_error.c comments on kernel task creation) - -void cpqfcTSWorkerThread( void *host) -{ - struct Scsi_Host *HostAdapter = (struct Scsi_Host*)host; - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; -#ifdef PCI_KERNEL_TRACE - PTACHYON fcChip = &cpqfcHBAdata->fcChip; -#endif - DECLARE_MUTEX_LOCKED(fcQueReady); - DECLARE_MUTEX_LOCKED(fcTYOBcomplete); - DECLARE_MUTEX_LOCKED(TachFrozen); - DECLARE_MUTEX_LOCKED(BoardLock); - - ENTER("WorkerThread"); - - lock_kernel(); - daemonize("cpqfcTS_wt_%d", HostAdapter->host_no); - siginitsetinv(¤t->blocked, SHUTDOWN_SIGS); - - - cpqfcHBAdata->fcQueReady = &fcQueReady; // primary wait point - cpqfcHBAdata->TYOBcomplete = &fcTYOBcomplete; - cpqfcHBAdata->TachFrozen = &TachFrozen; - - - cpqfcHBAdata->worker_thread = current; - - unlock_kernel(); - - if( cpqfcHBAdata->notify_wt != NULL ) - up( cpqfcHBAdata->notify_wt); // OK to continue - - while(1) - { - unsigned long flags; - - down_interruptible( &fcQueReady); // wait for something to do - - if (signal_pending(current) ) - break; - - PCI_TRACE( 0x90) - // first, take the IO lock so the SCSI upper layers can't call - // into our _quecommand function (this also disables INTs) - spin_lock_irqsave( HostAdapter->host_lock, flags); // STOP _que function - PCI_TRACE( 0x90) - - CPQ_SPINLOCK_HBA( cpqfcHBAdata) - // next, set this pointer to indicate to the _quecommand function - // that the board is in use, so it should que the command and - // immediately return (we don't actually require the semaphore function - // in this driver rev) - - cpqfcHBAdata->BoardLock = &BoardLock; - - PCI_TRACE( 0x90) - - // release the IO lock (and re-enable interrupts) - spin_unlock_irqrestore( HostAdapter->host_lock, flags); - - // disable OUR HBA interrupt (keep them off as much as possible - // during error recovery) - disable_irq( cpqfcHBAdata->HostAdapter->irq); - - // OK, let's process the Fibre Channel Link Q and do the work - cpqfcTS_WorkTask( HostAdapter); - - // hopefully, no more "work" to do; - // re-enable our INTs for "normal" completion processing - enable_irq( cpqfcHBAdata->HostAdapter->irq); - - - cpqfcHBAdata->BoardLock = NULL; // allow commands to be queued - CPQ_SPINUNLOCK_HBA( cpqfcHBAdata) - - - // Now, complete any Cmnd we Q'd up while BoardLock was held - - CompleteBoardLockCmnd( cpqfcHBAdata); - - - } - // hopefully, the signal was for our module exit... - if( cpqfcHBAdata->notify_wt != NULL ) - up( cpqfcHBAdata->notify_wt); // yep, we're outta here -} - - -// Freeze Tachyon routine. -// If Tachyon is already frozen, return FALSE -// If Tachyon is not frozen, call freeze function, return TRUE -// -static BOOLEAN FreezeTach( CPQFCHBA *cpqfcHBAdata) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - BOOLEAN FrozeTach = FALSE; - // It's possible that the chip is already frozen; if so, - // "Freezing" again will NOT! generate another Freeze - // Completion Message. - - if( (fcChip->Registers.TYstatus.value & 0x70000) != 0x70000) - { // (need to freeze...) - fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists - - // 2. Get Tach freeze confirmation - // (synchronize SEST manipulation with Freeze Completion Message) - // we need INTs on so semaphore can be set. - enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Semaphore - down_interruptible( cpqfcHBAdata->TachFrozen); // wait for INT handler sem. - // can we TIMEOUT semaphore wait?? TBD - disable_irq( cpqfcHBAdata->HostAdapter->irq); - - FrozeTach = TRUE; - } // (else, already frozen) - - return FrozeTach; -} - - - - -// This is the kernel worker thread task, which processes FC -// tasks which were queued by the Interrupt handler or by -// other WorkTask functions. - -#define DBG 1 -//#undef DBG -void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG QconsumerNdx; - LONG ExchangeID; - ULONG ulStatus=0; - TachFCHDR_GCMND fchs; - PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ; - - ENTER("WorkTask"); - - // copy current index to work on - QconsumerNdx = fcLQ->consumer; - - PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x90) - - - // NOTE: when this switch completes, we will "consume" the Que item -// printk("Que type %Xh\n", fcLQ->Qitem[QconsumerNdx].Type); - switch( fcLQ->Qitem[QconsumerNdx].Type ) - { - // incoming frame - link service (ACC, UNSOL REQ, etc.) - // or FCP-SCSI command - case SFQ_UNKNOWN: - AnalyzeIncomingFrame( cpqfcHBAdata, QconsumerNdx ); - - break; - - - - case EXCHANGE_QUEUED: // an Exchange (i.e. FCP-SCSI) was previously - // Queued because the link was down. The - // heartbeat timer detected it and Queued it here. - // We attempt to start it again, and if - // successful we clear the EXCHANGE_Q flag. - // If the link doesn't come up, the Exchange - // will eventually time-out. - - ExchangeID = (LONG) // x_ID copied from DPC timeout function - fcLQ->Qitem[QconsumerNdx].ulBuff[0]; - - // It's possible that a Q'd exchange could have already - // been started by other logic (e.g. ABTS process) - // Don't start if already started (Q'd flag clear) - - if( Exchanges->fcExchange[ExchangeID].status & EXCHANGE_QUEUED ) - { -// printk(" *Start Q'd x_ID %Xh: type %Xh ", -// ExchangeID, Exchanges->fcExchange[ExchangeID].type); - - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID); - if( !ulStatus ) - { -// printk("success* "); - } - else - { -#ifdef DBG - - if( ulStatus == EXCHANGE_QUEUED) - printk("Queued* "); - else - printk("failed* "); - -#endif - } - } - break; - - - case LINKDOWN: - // (lots of things already done in INT handler) future here? - break; - - - case LINKACTIVE: // Tachyon set the Lup bit in FM status - // NOTE: some misbehaving FC ports (like Tach2.1) - // can re-LIP immediately after a LIP completes. - - // if "initiator", need to verify LOGs with ports -// printk("\n*LNKUP* "); - - if( fcChip->Options.initiator ) - SendLogins( cpqfcHBAdata, NULL ); // PLOGI or PDISC, based on fcPort data - // if SendLogins successfully completes, PortDiscDone - // will be set. - - - // If SendLogins was successful, then we expect to get incoming - // ACCepts or REJECTs, which are handled below. - - break; - - // LinkService and Fabric request/reply processing - case ELS_FDISC: // need to send Fabric Discovery (Login) - case ELS_FLOGI: // need to send Fabric Login - case ELS_SCR: // need to send State Change Registration - case FCS_NSR: // need to send Name Service Request - case ELS_PLOGI: // need to send PLOGI - case ELS_ACC: // send generic ACCept - case ELS_PLOGI_ACC: // need to send ELS ACCept frame to recv'd PLOGI - case ELS_PRLI_ACC: // need to send ELS ACCept frame to recv'd PRLI - case ELS_LOGO: // need to send ELS LOGO (logout) - case ELS_LOGO_ACC: // need to send ELS ACCept frame to recv'd PLOGI - case ELS_RJT: // ReJecT reply - case ELS_PRLI: // need to send ELS PRLI - - -// printk(" *ELS %Xh* ", fcLQ->Qitem[QconsumerNdx].Type); - // if PortDiscDone is not set, it means the SendLogins routine - // failed to complete -- assume that LDn occurred, so login frames - // are invalid - if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn - { - printk("Discard Q'd ELS login frame\n"); - break; - } - - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - fcLQ->Qitem[QconsumerNdx].Type, // e.g. PLOGI - (TachFCHDR_GCMND*) - fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs - NULL, // no data (no scatter/gather list) - &ExchangeID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup? - { - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID ); - if( !ulStatus ) - { - // submitted to Tach's Outbound Que (ERQ PI incremented) - // waited for completion for ELS type (Login frames issued - // synchronously) - } - else - // check reason for Exchange not being started - we might - // want to Queue and start later, or fail with error - { - - } - } - - else // Xchange setup failed... - printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus ); - - break; - - case SCSI_REPORT_LUNS: - // pass the incoming frame (actually, it's a PRLI frame) - // so we can send REPORT_LUNS, in order to determine VSA/PDU - // FCP-SCSI Lun address mode - IssueReportLunsCommand( cpqfcHBAdata, (TachFCHDR_GCMND*) - fcLQ->Qitem[QconsumerNdx].ulBuff); - - break; - - - - - case BLS_ABTS: // need to ABORT one or more exchanges - { - LONG x_ID = fcLQ->Qitem[QconsumerNdx].ulBuff[0]; - BOOLEAN FrozeTach = FALSE; - - if ( x_ID >= TACH_SEST_LEN ) // (in)sanity check - { -// printk( " cpqfcTS ERROR! BOGUS x_ID %Xh", x_ID); - break; - } - - - if( Exchanges->fcExchange[ x_ID].Cmnd == NULL ) // should be RARE - { -// printk(" ABTS %Xh Scsi Cmnd null! ", x_ID); - - break; // nothing to abort! - } - -//#define ABTS_DBG -#ifdef ABTS_DBG - printk("INV SEST[%X] ", x_ID); - if( Exchanges->fcExchange[x_ID].status & FC2_TIMEOUT) - { - printk("FC2TO"); - } - if( Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT) - { - printk("IA"); - } - if( Exchanges->fcExchange[x_ID].status & PORTID_CHANGED) - { - printk("PORTID"); - } - if( Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) - { - printk("DEVRM"); - } - if( Exchanges->fcExchange[x_ID].status & LINKFAIL_TX) - { - printk("LKF"); - } - if( Exchanges->fcExchange[x_ID].status & FRAME_TO) - { - printk("FRMTO"); - } - if( Exchanges->fcExchange[x_ID].status & ABORTSEQ_NOTIFY) - { - printk("ABSQ"); - } - if( Exchanges->fcExchange[x_ID].status & SFQ_FRAME) - { - printk("SFQFR"); - } - - if( Exchanges->fcExchange[ x_ID].type == 0x2000) - printk(" WR"); - else if( Exchanges->fcExchange[ x_ID].type == 0x3000) - printk(" RD"); - else if( Exchanges->fcExchange[ x_ID].type == 0x10) - printk(" ABTS"); - else - printk(" %Xh", Exchanges->fcExchange[ x_ID].type); - - if( !(Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT)) - { - printk(" Cmd %p, ", - Exchanges->fcExchange[ x_ID].Cmnd); - - printk(" brd/chn/trg/lun %d/%d/%d/%d port_id %06X\n", - cpqfcHBAdata->HBAnum, - Exchanges->fcExchange[ x_ID].Cmnd->channel, - Exchanges->fcExchange[ x_ID].Cmnd->target, - Exchanges->fcExchange[ x_ID].Cmnd->lun, - Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF); - } - else // assume that Cmnd ptr is invalid on _abort() - { - printk(" Cmd ptr invalid\n"); - } - -#endif - - - // Steps to ABORT a SEST exchange: - // 1. Freeze TL SCSI assists & ERQ (everything) - // 2. Receive FROZEN inbound CM (must succeed!) - // 3. Invalidate x_ID SEST entry - // 4. Resume TL SCSI assists & ERQ (everything) - // 5. Build/start on exchange - change "type" to BLS_ABTS, - // timeout to X sec (RA_TOV from PLDA is actually 0) - // 6. Set Exchange Q'd status if ABTS cannot be started, - // or simply complete Exchange in "Terminate" condition - - PCI_TRACEO( x_ID, 0xB4) - - // 1 & 2 . Freeze Tach & get confirmation of freeze - FrozeTach = FreezeTach( cpqfcHBAdata); - - // 3. OK, Tachyon is frozen, so we can invalidate SEST exchange. - // FC2_TIMEOUT means we are originating the abort, while - // TARGET_ABORT means we are ACCepting an abort. - // LINKFAIL_TX, ABORTSEQ_NOFITY, INV_ENTRY or FRAME_TO are - // all from Tachyon: - // Exchange was corrupted by LDn or other FC physical failure - // INITIATOR_ABORT means the upper layer driver/application - // requested the abort. - - - - // clear bit 31 (VALid), to invalidate & take control from TL - fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF; - - - // examine and Tach's "Linked List" for IWEs that - // received (nearly) simultaneous transfer ready (XRDY) - // repair linked list if necessary (TBD!) - // (If we ignore the "Linked List", we will time out - // WRITE commands where we received the FCP-SCSI XFRDY - // frame (because Tachyon didn't processes it). Linked List - // management should be done as an optimization. - -// readl( fcChip->Registers.ReMapMemBase+TL_MEM_SEST_LINKED_LIST )); - - - - - // 4. Resume all Tachlite functions (for other open Exchanges) - // as quickly as possible to allow other exchanges to other ports - // to resume. Freezing Tachyon may cause cascading errors, because - // any received SEST frame cannot be processed by the SEST. - // Don't "unfreeze" unless Link is operational - if( FrozeTach ) // did we just freeze it (above)? - fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists - - - PCI_TRACEO( x_ID, 0xB4) - - // Note there is no confirmation that the chip is "unfrozen". Also, - // if the Link is down when unfreeze is called, it has no effect. - // Chip will unfreeze when the Link is back up. - - // 5. Now send out Abort commands if possible - // Some Aborts can't be "sent" (Port_id changed or gone); - // if the device is gone, there is no port_id to send the ABTS to. - - if( !(Exchanges->fcExchange[ x_ID].status & PORTID_CHANGED) - && - !(Exchanges->fcExchange[ x_ID].status & DEVICE_REMOVED) ) - { - Exchanges->fcExchange[ x_ID].type = BLS_ABTS; - fchs.s_id = Exchanges->fcExchange[ x_ID].fchs.d_id; - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - BLS_ABTS, - &fchs, // (uses only s_id) - NULL, // (no scatter/gather list for ABTS) - &x_ID );// ABTS on this Exchange ID - - if( !ulStatus ) // Exchange setup build OK? - { - - // ABTS may be needed because an Exchange was corrupted - // by a Link disruption. If the Link is UP, we can - // presume that this ABTS can start immediately; otherwise, - // set Que'd status so the Login functions - // can restart it when the FC physical Link is restored - if( ((fcChip->Registers.FMstatus.value &0xF0) &0x80)) // loop init? - { -// printk(" *set Q status x_ID %Xh on LDn* ", x_ID); - Exchanges->fcExchange[ x_ID].status |= EXCHANGE_QUEUED; - } - - else // what FC device (port_id) does the Cmd belong to? - { - PFC_LOGGEDIN_PORT pLoggedInPort = - Exchanges->fcExchange[ x_ID].pLoggedInPort; - - // if Port is logged in, we might start the abort. - - if( (pLoggedInPort != NULL) - && - (pLoggedInPort->prli == TRUE) ) - { - // it's possible that an Exchange has already been Queued - // to start after Login completes. Check and don't - // start it (again) here if Q'd status set -// printk(" ABTS xchg %Xh ", x_ID); - if( Exchanges->fcExchange[x_ID].status & EXCHANGE_QUEUED) - { -// printk("already Q'd "); - } - else - { -// printk("starting "); - - fcChip->fcStats.FC2aborted++; - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID ); - if( !ulStatus ) - { - // OK - // submitted to Tach's Outbound Que (ERQ PI incremented) - } - else - { -/* printk("ABTS exchange start failed -status %Xh, x_ID %Xh ", - ulStatus, x_ID); -*/ - } - } - } - else - { -/* printk(" ABTS NOT starting xchg %Xh, %p ", - x_ID, pLoggedInPort); - if( pLoggedInPort ) - printk("prli %d ", pLoggedInPort->prli); -*/ - } - } - } - else // what the #@! - { // how do we fail to build an Exchange for ABTS?? - printk("ABTS exchange build failed -status %Xh, x_ID %Xh\n", - ulStatus, x_ID); - } - } - else // abort without ABTS -- just complete exchange/Cmnd to Linux - { -// printk(" *Terminating x_ID %Xh on %Xh* ", -// x_ID, Exchanges->fcExchange[x_ID].status); - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, x_ID); - - } - } // end of ABTS case - break; - - - - case BLS_ABTS_ACC: // need to ACCept one ABTS - // (NOTE! this code not updated for Linux yet..) - - - printk(" *ABTS_ACC* "); - // 1. Freeze TL - - fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists - - memcpy( // copy the incoming ABTS frame - &fchs, - fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs - sizeof( fchs)); - - // 3. OK, Tachyon is frozen so we can invalidate SEST entry - // (if necessary) - // Status FC2_TIMEOUT means we are originating the abort, while - // TARGET_ABORT means we are ACCepting an abort - - ExchangeID = fchs.ox_rx_id & 0x7FFF; // RX_ID for exchange -// printk("ABTS ACC for Target ExchangeID %Xh\n", ExchangeID); - - - // sanity check on received ExchangeID - if( Exchanges->fcExchange[ ExchangeID].status == TARGET_ABORT ) - { - // clear bit 31 (VALid), to invalidate & take control from TL -// printk("Invalidating SEST exchange %Xh\n", ExchangeID); - fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len &= 0x7FFFFFFF; - } - - - // 4. Resume all Tachlite functions (for other open Exchanges) - // as quickly as possible to allow other exchanges to other ports - // to resume. Freezing Tachyon for too long may royally screw - // up everything! - fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists - - // Note there is no confirmation that the chip is "unfrozen". Also, - // if the Link is down when unfreeze is called, it has no effect. - // Chip will unfreeze when the Link is back up. - - // 5. Now send out Abort ACC reply for this exchange - Exchanges->fcExchange[ ExchangeID].type = BLS_ABTS_ACC; - - fchs.s_id = Exchanges->fcExchange[ ExchangeID].fchs.d_id; - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - BLS_ABTS_ACC, - &fchs, - NULL, // no data (no scatter/gather list) - &ExchangeID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup? - { - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID ); - if( !ulStatus ) - { - // submitted to Tach's Outbound Que (ERQ PI incremented) - // waited for completion for ELS type (Login frames issued - // synchronously) - } - else - // check reason for Exchange not being started - we might - // want to Queue and start later, or fail with error - { - - } - } - break; - - - case BLS_ABTS_RJT: // need to ReJecT one ABTS; reject implies the - // exchange doesn't exist in the TARGET context. - // ExchangeID has to come from LinkService space. - - printk(" *ABTS_RJT* "); - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - BLS_ABTS_RJT, - (TachFCHDR_GCMND*) - fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs - NULL, // no data (no scatter/gather list) - &ExchangeID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup OK? - { - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID ); - // If it fails, we aren't required to retry. - } - if( ulStatus ) - { - printk("Failed to send BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID); - } - else - { - printk("Sent BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID); - - } - - break; - - - - default: - break; - } // end switch -//doNothing: - // done with this item - now set the NEXT index - - if( QconsumerNdx+1 >= FC_LINKQ_DEPTH ) // rollover test - { - fcLQ->consumer = 0; - } - else - { - fcLQ->consumer++; - } - - PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x94) - - LEAVE("WorkTask"); - return; -} - - - - -// When Tachyon reports link down, bad al_pa, or Link Service (e.g. Login) -// commands come in, post to the LinkQ so that action can be taken outside the -// interrupt handler. -// This circular Q works like Tachyon's que - the producer points to the next -// (unused) entry. Called by Interrupt handler, WorkerThread, Timer -// sputlinkq -void cpqfcTSPutLinkQue( CPQFCHBA *cpqfcHBAdata, - int Type, - void *QueContent) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; -// FC_EXCHANGES *Exchanges = fcChip->Exchanges; - PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ; - ULONG ndx; - - ENTER("cpqfcTSPutLinkQ"); - - ndx = fcLQ->producer; - - ndx += 1; // test for Que full - - - - if( ndx >= FC_LINKQ_DEPTH ) // rollover test - ndx = 0; - - if( ndx == fcLQ->consumer ) // QUE full test - { - // QUE was full! lost LK command (fatal to logic) - fcChip->fcStats.lnkQueFull++; - - printk("*LinkQ Full!*"); - TriggerHBA( fcChip->Registers.ReMapMemBase, 1); -/* - { - int i; - printk("LinkQ PI %d, CI %d\n", fcLQ->producer, - fcLQ->consumer); - - for( i=0; i< FC_LINKQ_DEPTH; ) - { - printk(" [%d]%Xh ", i, fcLQ->Qitem[i].Type); - if( (++i %8) == 0) printk("\n"); - } - - } -*/ - printk( "cpqfcTS: WARNING!! PutLinkQue - FULL!\n"); // we're hung - } - else // QUE next element - { - // Prevent certain multiple (back-to-back) requests. - // This is important in that we don't want to issue multiple - // ABTS for the same Exchange, or do multiple FM inits, etc. - // We can never be sure of the timing of events reported to - // us by Tach's IMQ, which can depend on system/bus speeds, - // FC physical link circumstances, etc. - - if( (fcLQ->producer != fcLQ->consumer) - && - (Type == FMINIT) ) - { - LONG lastNdx; // compute previous producer index - if( fcLQ->producer) - lastNdx = fcLQ->producer- 1; - else - lastNdx = FC_LINKQ_DEPTH-1; - - - if( fcLQ->Qitem[lastNdx].Type == FMINIT) - { -// printk(" *skip FMINIT Q post* "); -// goto DoneWithPutQ; - } - - } - - // OK, add the Q'd item... - - fcLQ->Qitem[fcLQ->producer].Type = Type; - - memcpy( - fcLQ->Qitem[fcLQ->producer].ulBuff, - QueContent, - sizeof(fcLQ->Qitem[fcLQ->producer].ulBuff)); - - fcLQ->producer = ndx; // increment Que producer - - // set semaphore to wake up Kernel (worker) thread - // - up( cpqfcHBAdata->fcQueReady ); - } - -//DoneWithPutQ: - - LEAVE("cpqfcTSPutLinkQ"); -} - - - - -// reset device ext FC link Q -void cpqfcTSLinkQReset( CPQFCHBA *cpqfcHBAdata) - -{ - PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ; - fcLQ->producer = 0; - fcLQ->consumer = 0; - -} - - - - - -// When Tachyon gets an unassisted FCP-SCSI frame, post here so -// an arbitrary context thread (e.g. IOCTL loopback test function) -// can process it. - -// (NOTE: Not revised for Linux) -// This Q works like Tachyon's que - the producer points to the next -// (unused) entry. -void cpqfcTSPutScsiQue( CPQFCHBA *cpqfcHBAdata, - int Type, - void *QueContent) -{ -// CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; -// PTACHYON fcChip = &cpqfcHBAdata->fcChip; - -// ULONG ndx; - -// ULONG *pExchangeID; -// LONG ExchangeID; - -/* - KeAcquireSpinLockAtDpcLevel( &pDevExt->fcScsiQueLock); - ndx = pDevExt->fcScsiQue.producer + 1; // test for Que full - - if( ndx >= FC_SCSIQ_DEPTH ) // rollover test - ndx = 0; - - if( ndx == pDevExt->fcScsiQue.consumer ) // QUE full test - { - // QUE was full! lost LK command (fatal to logic) - fcChip->fcStats.ScsiQueFull++; -#ifdef DBG - printk( "fcPutScsiQue - FULL!\n"); -#endif - - } - else // QUE next element - { - pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].Type = Type; - - if( Type == FCP_RSP ) - { - // this TL inbound message type means that a TL SEST exchange has - // copied an FCP response frame into a buffer pointed to by the SEST - // entry. That buffer is allocated in the SEST structure at ->RspHDR. - // Copy the RspHDR for use by the Que handler. - pExchangeID = (ULONG *)QueContent; - - memcpy( - pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff, - &fcChip->SEST->RspHDR[ *pExchangeID ], - sizeof(pDevExt->fcScsiQue.Qitem[0].ulBuff)); // (any element for size) - - } - else - { - memcpy( - pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff, - QueContent, - sizeof(pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff)); - } - - pDevExt->fcScsiQue.producer = ndx; // increment Que - - - KeSetEvent( &pDevExt->TYIBscsi, // signal any waiting thread - 0, // no priority boost - FALSE ); // no waiting later for this event - } - KeReleaseSpinLockFromDpcLevel( &pDevExt->fcScsiQueLock); -*/ -} - - - - - - - -static void ProcessELS_Request( CPQFCHBA*,TachFCHDR_GCMND*); - -static void ProcessELS_Reply( CPQFCHBA*,TachFCHDR_GCMND*); - -static void ProcessFCS_Reply( CPQFCHBA*,TachFCHDR_GCMND*); - -void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata, - PFC_LOGGEDIN_PORT pFcPort) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - - if( pFcPort->port_id != 0xFFFC01 ) // don't care about Fabric - { - fcChip->fcStats.logouts++; - printk("cpqfcTS: Implicit logout of WWN %08X%08X, port_id %06X\n", - (ULONG)pFcPort->u.liWWN, - (ULONG)(pFcPort->u.liWWN >>32), - pFcPort->port_id); - - // Terminate I/O with this (Linux) Scsi target - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pFcPort->ScsiNexus, - DEVICE_REMOVED); - } - - // Do an "implicit logout" - we can't really Logout the device - // (i.e. with LOGOut Request) because of port_id confusion - // (i.e. the Other port has no port_id). - // A new login for that WWN will have to re-write port_id (0 invalid) - pFcPort->port_id = 0; // invalid! - pFcPort->pdisc = FALSE; - pFcPort->prli = FALSE; - pFcPort->plogi = FALSE; - pFcPort->flogi = FALSE; - pFcPort->LOGO_timer = 0; - pFcPort->device_blocked = TRUE; // block Scsi Requests - pFcPort->ScsiNexus.VolumeSetAddressing=0; -} - - -// On FC-AL, there is a chance that a previously known device can -// be quietly removed (e.g. with non-managed hub), -// while a NEW device (with different WWN) took the same alpa or -// even 24-bit port_id. This chance is unlikely but we must always -// check for it. -static void TestDuplicatePortId( CPQFCHBA* cpqfcHBAdata, - PFC_LOGGEDIN_PORT pLoggedInPort) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - // set "other port" at beginning of fcPorts list - PFC_LOGGEDIN_PORT pOtherPortWithPortId = fcChip->fcPorts.pNextPort; - while( pOtherPortWithPortId ) - { - if( (pOtherPortWithPortId->port_id == - pLoggedInPort->port_id) - && - (pOtherPortWithPortId != pLoggedInPort) ) - { - // trouble! (Implicitly) Log the other guy out - printk(" *port_id %Xh is duplicated!* ", - pOtherPortWithPortId->port_id); - cpqfcTSImplicitLogout( cpqfcHBAdata, pOtherPortWithPortId); - } - pOtherPortWithPortId = pOtherPortWithPortId->pNextPort; - } -} - - - - - - -// Dynamic Memory Allocation for newly discovered FC Ports. -// For simplicity, maintain fcPorts structs for ALL -// for discovered devices, including those we never do I/O with -// (e.g. Fabric addresses) - -static PFC_LOGGEDIN_PORT CreateFcPort( - CPQFCHBA* cpqfcHBAdata, - PFC_LOGGEDIN_PORT pLastLoggedInPort, - TachFCHDR_GCMND* fchs, - LOGIN_PAYLOAD* plogi) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - PFC_LOGGEDIN_PORT pNextLoggedInPort = NULL; - int i; - - - printk("cpqfcTS: New FC port %06Xh WWN: ", fchs->s_id); - for( i=3; i>=0; i--) // copy the LOGIN port's WWN - printk("%02X", plogi->port_name[i]); - for( i=7; i>3; i--) // copy the LOGIN port's WWN - printk("%02X", plogi->port_name[i]); - - - // allocate mem for new port - // (these are small and rare allocations...) - pNextLoggedInPort = kmalloc( sizeof( FC_LOGGEDIN_PORT), GFP_ATOMIC ); - - - // allocation succeeded? Fill out NEW PORT - if( pNextLoggedInPort ) - { - // clear out any garbage (sometimes exists) - memset( pNextLoggedInPort, 0, sizeof( FC_LOGGEDIN_PORT)); - - - // If we login to a Fabric, we don't want to treat it - // as a SCSI device... - if( (fchs->s_id & 0xFFF000) != 0xFFF000) - { - int i; - - // create a unique "virtual" SCSI Nexus (for now, just a - // new target ID) -- we will update channel/target on REPORT_LUNS - // special case for very first SCSI target... - if( cpqfcHBAdata->HostAdapter->max_id == 0) - { - pNextLoggedInPort->ScsiNexus.target = 0; - fcChip->fcPorts.ScsiNexus.target = -1; // don't use "stub" - } - else - { - pNextLoggedInPort->ScsiNexus.target = - cpqfcHBAdata->HostAdapter->max_id; - } - - // initialize the lun[] Nexus struct for lun masking - for( i=0; i< CPQFCTS_MAX_LUN; i++) - pNextLoggedInPort->ScsiNexus.lun[i] = 0xFF; // init to NOT USED - - pNextLoggedInPort->ScsiNexus.channel = 0; // cpqfcTS has 1 FC port - - printk(" SCSI Chan/Trgt %d/%d", - pNextLoggedInPort->ScsiNexus.channel, - pNextLoggedInPort->ScsiNexus.target); - - // tell Scsi layers about the new target... - cpqfcHBAdata->HostAdapter->max_id++; -// printk("HostAdapter->max_id = %d\n", -// cpqfcHBAdata->HostAdapter->max_id); - } - else - { - // device is NOT SCSI (in case of Fabric) - pNextLoggedInPort->ScsiNexus.target = -1; // invalid - } - - // create forward link to new port - pLastLoggedInPort->pNextPort = pNextLoggedInPort; - printk("\n"); - - } - return pNextLoggedInPort; // NULL on allocation failure -} // end NEW PORT (WWN) logic - - - -// For certain cases, we want to terminate exchanges without -// sending ABTS to the device. Examples include when an FC -// device changed it's port_id after Loop re-init, or when -// the device sent us a logout. In the case of changed port_id, -// we want to complete the command and return SOFT_ERROR to -// force a re-try. In the case of LOGOut, we might return -// BAD_TARGET if the device is really gone. -// Since we must ensure that Tachyon is not operating on the -// exchange, we have to freeze the chip -// sterminateex -void cpqfcTSTerminateExchange( - CPQFCHBA* cpqfcHBAdata, SCSI_NEXUS *ScsiNexus, int TerminateStatus) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG x_ID; - - if( ScsiNexus ) - { -// printk("TerminateExchange: ScsiNexus chan/target %d/%d\n", -// ScsiNexus->channel, ScsiNexus->target); - - } - - for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++) - { - if( Exchanges->fcExchange[x_ID].type ) // in use? - { - if( ScsiNexus == NULL ) // our HBA changed - term. all - { - Exchanges->fcExchange[x_ID].status = TerminateStatus; - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); - } - else - { - // If a device, according to WWN, has been removed, it's - // port_id may be used by another working device, so we - // have to terminate by SCSI target, NOT port_id. - if( Exchanges->fcExchange[x_ID].Cmnd) // Cmnd in progress? - { - if( (Exchanges->fcExchange[x_ID].Cmnd->device->id == ScsiNexus->target) - && - (Exchanges->fcExchange[x_ID].Cmnd->device->channel == ScsiNexus->channel)) - { - Exchanges->fcExchange[x_ID].status = TerminateStatus; - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); // timed-out - } - } - - // (in case we ever need it...) - // all SEST structures have a remote node ID at SEST DWORD 2 - // if( (fcChip->SEST->u[ x_ID ].TWE.Remote_Node_ID >> 8) - // == port_id) - } - } - } -} - - -static void ProcessELS_Request( - CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; -// FC_EXCHANGES *Exchanges = fcChip->Exchanges; -// ULONG ox_id = (fchs->ox_rx_id >>16); - PFC_LOGGEDIN_PORT pLoggedInPort=NULL, pLastLoggedInPort; - BOOLEAN NeedReject = FALSE; - ULONG ls_reject_code = 0; // default don'n know?? - - - // Check the incoming frame for a supported ELS type - switch( fchs->pl[0] & 0xFFFF) - { - case 0x0050: // PDISC? - - // Payload for PLOGI and PDISC is identical (request & reply) - if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload? - { - LOGIN_PAYLOAD logi; // FC-PH Port Login - - // PDISC payload OK. If critical login fields - // (e.g. WWN) matches last login for this port_id, - // we may resume any prior exchanges - // with the other port - - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi)); - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - 0, // don't search linked list for port_id - &logi.port_name[0], // search linked list for WWN - &pLastLoggedInPort); // must return non-NULL; when a port_id - // is not found, this pointer marks the - // end of the singly linked list - - if( pLoggedInPort != NULL) // WWN found (prior login OK) - { - - if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id) - { - // Yes. We were expecting PDISC? - if( pLoggedInPort->pdisc ) - { - // Yes; set fields accordingly. (PDISC, not Originator) - SetLoginFields( pLoggedInPort, fchs, TRUE, FALSE); - - // send 'ACC' reply - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC) - fchs ); - - // OK to resume I/O... - } - else - { - printk("Not expecting PDISC (pdisc=FALSE)\n"); - NeedReject = TRUE; - // set reject reason code - ls_reject_code = - LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR); - } - } - else - { - if( pLoggedInPort->port_id != 0) - { - printk("PDISC PortID change: old %Xh, new %Xh\n", - pLoggedInPort->port_id, fchs->s_id &0xFFFFFF); - } - NeedReject = TRUE; - // set reject reason code - ls_reject_code = - LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR); - - } - } - else - { - printk("PDISC Request from unknown WWN\n"); - NeedReject = TRUE; - - // set reject reason code - ls_reject_code = - LS_RJT_REASON( LOGICAL_ERROR, INVALID_PORT_NAME); - } - - } - else // Payload unacceptable - { - printk("payload unacceptable\n"); - NeedReject = TRUE; // reject code already set - - } - - if( NeedReject) - { - ULONG port_id; - // The PDISC failed. Set login struct flags accordingly, - // terminate any I/O to this port, and Q a PLOGI - if( pLoggedInPort ) - { - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; - pLoggedInPort->plogi = FALSE; - - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, PORTID_CHANGED); - port_id = pLoggedInPort->port_id; - } - else - { - port_id = fchs->s_id &0xFFFFFF; - } - fchs->reserved = ls_reject_code; // borrow this (unused) field - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs ); - } - - break; - - - - case 0x0003: // PLOGI? - - // Payload for PLOGI and PDISC is identical (request & reply) - if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload? - { - LOGIN_PAYLOAD logi; // FC-PH Port Login - BOOLEAN NeedReject = FALSE; - - // PDISC payload OK. If critical login fields - // (e.g. WWN) matches last login for this port_id, - // we may resume any prior exchanges - // with the other port - - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi)); - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - 0, // don't search linked list for port_id - &logi.port_name[0], // search linked list for WWN - &pLastLoggedInPort); // must return non-NULL; when a port_id - // is not found, this pointer marks the - // end of the singly linked list - - if( pLoggedInPort == NULL) // WWN not found -New Port - { - pLoggedInPort = CreateFcPort( - cpqfcHBAdata, - pLastLoggedInPort, - fchs, - &logi); - if( pLoggedInPort == NULL ) - { - printk(" cpqfcTS: New port allocation failed - lost FC device!\n"); - // Now Q a LOGOut Request, since we won't be talking to that device - - NeedReject = TRUE; - - // set reject reason code - ls_reject_code = - LS_RJT_REASON( LOGICAL_ERROR, NO_LOGIN_RESOURCES); - - } - } - if( !NeedReject ) - { - - // OK - we have valid fcPort ptr; set fields accordingly. - // (not PDISC, not Originator) - SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE); - - // send 'ACC' reply - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC) - fchs ); - } - } - else // Payload unacceptable - { - printk("payload unacceptable\n"); - NeedReject = TRUE; // reject code already set - } - - if( NeedReject) - { - // The PDISC failed. Set login struct flags accordingly, - // terminate any I/O to this port, and Q a PLOGI - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; - pLoggedInPort->plogi = FALSE; - - fchs->reserved = ls_reject_code; // borrow this (unused) field - - // send 'RJT' reply - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs ); - } - - // terminate any exchanges with this device... - if( pLoggedInPort ) - { - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, PORTID_CHANGED); - } - break; - - - - case 0x1020: // PRLI? - { - BOOLEAN NeedReject = TRUE; - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - (fchs->s_id & 0xFFFFFF), // search linked list for port_id - NULL, // DON'T search linked list for WWN - NULL); // don't care - - if( pLoggedInPort == NULL ) - { - // huh? - printk(" Unexpected PRLI Request -not logged in!\n"); - - // set reject reason code - ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR); - - // Q a LOGOut here? - } - else - { - // verify the PRLI ACC payload - if( !verify_PRLI( fchs, &ls_reject_code) ) - { - // PRLI Reply is acceptable; were we expecting it? - if( pLoggedInPort->plogi ) - { - // yes, we expected the PRLI ACC (not PDISC; not Originator) - SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE); - - // Q an ACCept Reply - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_PRLI_ACC, - fchs ); - - NeedReject = FALSE; - } - else - { - // huh? - printk(" (unexpected) PRLI REQEST with plogi FALSE\n"); - - // set reject reason code - ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR); - - // Q a LOGOut here? - - } - } - else - { - printk(" PRLI REQUEST payload failed verify\n"); - // (reject code set by "verify") - - // Q a LOGOut here? - } - } - - if( NeedReject ) - { - // Q a ReJecT Reply with reason code - fchs->reserved = ls_reject_code; - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_RJT, // Q Type - fchs ); - } - } - break; - - - - - case 0x0005: // LOGOut? - { - // was this LOGOUT because we sent a ELS_PDISC to an FC device - // with changed (or new) port_id, or does the port refuse - // to communicate to us? - // We maintain a logout counter - if we get 3 consecutive LOGOuts, - // give up! - LOGOUT_PAYLOAD logo; - BOOLEAN GiveUpOnDevice = FALSE; - ULONG ls_reject_code = 0; - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logo, sizeof(logo)); - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - 0, // don't search linked list for port_id - &logo.port_name[0], // search linked list for WWN - NULL); // don't care about end of list - - if( pLoggedInPort ) // found the device? - { - // Q an ACC reply - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_LOGO_ACC, // Q Type - fchs ); // device to respond to - - // set login struct fields (LOGO_counter increment) - SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE); - - // are we an Initiator? - if( fcChip->Options.initiator) - { - // we're an Initiator, so check if we should - // try (another?) login - - // Fabrics routinely log out from us after - // getting device info - don't try to log them - // back in. - if( (fchs->s_id & 0xFFF000) == 0xFFF000 ) - { - ; // do nothing - } - else if( pLoggedInPort->LOGO_counter <= 3) - { - // try (another) login (PLOGI request) - - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_PLOGI, // Q Type - fchs ); - - // Terminate I/O with "retry" potential - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, - PORTID_CHANGED); - } - else - { - printk(" Got 3 LOGOuts - terminating comm. with port_id %Xh\n", - fchs->s_id &&0xFFFFFF); - GiveUpOnDevice = TRUE; - } - } - else - { - GiveUpOnDevice = TRUE; - } - - - if( GiveUpOnDevice == TRUE ) - { - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, - DEVICE_REMOVED); - } - } - else // we don't know this WWN! - { - // Q a ReJecT Reply with reason code - fchs->reserved = ls_reject_code; - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_RJT, // Q Type - fchs ); - } - } - break; - - - - - // FABRIC only case - case 0x0461: // ELS RSCN (Registered State Change Notification)? - { - int Ports; - int i; - __u32 Buff; - // Typically, one or more devices have been added to or dropped - // from the Fabric. - // The format of this frame is defined in FC-FLA (Rev 2.7, Aug 1997) - // The first 32-bit word has a 2-byte Payload Length, which - // includes the 4 bytes of the first word. Consequently, - // this PL len must never be less than 4, must be a multiple of 4, - // and has a specified max value 256. - // (Endianess!) - Ports = ((fchs->pl[0] >>24) - 4) / 4; - Ports = Ports > 63 ? 63 : Ports; - - printk(" RSCN ports: %d\n", Ports); - if( Ports <= 0 ) // huh? - { - // ReJecT the command - fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM, 0); - - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_RJT, // Q Type - fchs ); - - break; - } - else // Accept the command - { - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_ACC, // Q Type - fchs ); - } - - // Check the "address format" to determine action. - // We have 3 cases: - // 0 = Port Address; 24-bit address of affected device - // 1 = Area Address; MS 16 bits valid - // 2 = Domain Address; MS 8 bits valid - for( i=0; ipl[i+1],(UCHAR*)&Buff, 4); - switch( Buff & 0xFF000000) - { - - case 0: // Port Address? - - case 0x01000000: // Area Domain? - case 0x02000000: // Domain Address - // For example, "port_id" 0x201300 - // OK, let's try a Name Service Request (Query) - fchs->s_id = 0xFFFFFC; // Name Server Address - cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs); - - break; - - - default: // huh? new value on version change? - break; - } - } - } - break; - - - - - default: // don't support this request (yet) - // set reject reason code - fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM, - REQUEST_NOT_SUPPORTED); - - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_RJT, // Q Type - fchs ); - break; - } -} - - -static void ProcessELS_Reply( - CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG ox_id = (fchs->ox_rx_id >>16); - ULONG ls_reject_code; - PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort; - - // If this is a valid reply, then we MUST have sent a request. - // Verify that we can find a valid request OX_ID corresponding to - // this reply - - - if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0) - { - printk(" *Discarding ACC/RJT frame, xID %04X/%04X* ", - ox_id, fchs->ox_rx_id & 0xffff); - goto Quit; // exit this routine - } - - - // Is the reply a RJT (reject)? - if( (fchs->pl[0] & 0xFFFFL) == 0x01) // Reject reply? - { -// ****** REJECT REPLY ******** - switch( Exchanges->fcExchange[ox_id].type ) - { - - case ELS_FDISC: // we sent out Fabric Discovery - case ELS_FLOGI: // we sent out FLOGI - - printk("RJT received on Fabric Login from %Xh, reason %Xh\n", - fchs->s_id, fchs->pl[1]); - - break; - - default: - break; - } - - goto Done; - } - - // OK, we have an ACCept... - // What's the ACC type? (according to what we sent) - switch( Exchanges->fcExchange[ox_id].type ) - { - - case ELS_PLOGI: // we sent out PLOGI - if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) - { - LOGIN_PAYLOAD logi; // FC-PH Port Login - - // login ACC payload acceptable; search for WWN in our list - // of fcPorts - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi)); - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - 0, // don't search linked list for port_id - &logi.port_name[0], // search linked list for WWN - &pLastLoggedInPort); // must return non-NULL; when a port_id - // is not found, this pointer marks the - // end of the singly linked list - - if( pLoggedInPort == NULL) // WWN not found - new port - { - - pLoggedInPort = CreateFcPort( - cpqfcHBAdata, - pLastLoggedInPort, - fchs, - &logi); - - if( pLoggedInPort == NULL ) - { - printk(" cpqfcTS: New port allocation failed - lost FC device!\n"); - // Now Q a LOGOut Request, since we won't be talking to that device - - goto Done; // exit with error! dropped login frame - } - } - else // WWN was already known. Ensure that any open - // exchanges for this WWN are terminated. - // NOTE: It's possible that a device can change its - // 24-bit port_id after a Link init or Fabric change - // (e.g. LIP or Fabric RSCN). In that case, the old - // 24-bit port_id may be duplicated, or no longer exist. - { - - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, PORTID_CHANGED); - } - - // We have an fcPort struct - set fields accordingly - // not PDISC, originator - SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE); - - // We just set a "port_id"; is it duplicated? - TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort); - - // For Fabric operation, we issued PLOGI to 0xFFFFFC - // so we can send SCR (State Change Registration) - // Check for this special case... - if( fchs->s_id == 0xFFFFFC ) - { - // PLOGI ACC was a Fabric response... issue SCR - fchs->s_id = 0xFFFFFD; // address for SCR - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_SCR, fchs); - } - - else - { - // Now we need a PRLI to enable FCP-SCSI operation - // set flags and Q up a ELS_PRLI - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PRLI, fchs); - } - } - else - { - // login payload unacceptable - reason in ls_reject_code - // Q up a Logout Request - printk("Login Payload unacceptable\n"); - - } - break; - - - // PDISC logic very similar to PLOGI, except we never want - // to allocate mem for "new" port, and we set flags differently - // (might combine later with PLOGI logic for efficiency) - case ELS_PDISC: // we sent out PDISC - if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) - { - LOGIN_PAYLOAD logi; // FC-PH Port Login - BOOLEAN NeedLogin = FALSE; - - // login payload acceptable; search for WWN in our list - // of (previously seen) fcPorts - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi)); - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - 0, // don't search linked list for port_id - &logi.port_name[0], // search linked list for WWN - &pLastLoggedInPort); // must return non-NULL; when a port_id - // is not found, this pointer marks the - // end of the singly linked list - - if( pLoggedInPort != NULL) // WWN found? - { - // WWN has same port_id as last login? (Of course, a properly - // working FC device should NEVER ACCept a PDISC if it's - // port_id changed, but check just in case...) - if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id) - { - // Yes. We were expecting PDISC? - if( pLoggedInPort->pdisc ) - { - int i; - - - // PDISC expected -- set fields. (PDISC, Originator) - SetLoginFields( pLoggedInPort, fchs, TRUE, TRUE); - - // We are ready to resume FCP-SCSI to this device... - // Do we need to start anything that was Queued? - - for( i=0; i< TACH_SEST_LEN; i++) - { - // see if any exchange for this PDISC'd port was queued - if( ((fchs->s_id &0xFFFFFF) == - (Exchanges->fcExchange[i].fchs.d_id & 0xFFFFFF)) - && - (Exchanges->fcExchange[i].status & EXCHANGE_QUEUED)) - { - fchs->reserved = i; // copy ExchangeID -// printk(" *Q x_ID %Xh after PDISC* ",i); - - cpqfcTSPutLinkQue( cpqfcHBAdata, EXCHANGE_QUEUED, fchs ); - } - } - - // Complete commands Q'd while we were waiting for Login - - UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort); - } - else - { - printk("Not expecting PDISC (pdisc=FALSE)\n"); - NeedLogin = TRUE; - } - } - else - { - printk("PDISC PortID change: old %Xh, new %Xh\n", - pLoggedInPort->port_id, fchs->s_id &0xFFFFFF); - NeedLogin = TRUE; - - } - } - else - { - printk("PDISC ACC from unknown WWN\n"); - NeedLogin = TRUE; - } - - if( NeedLogin) - { - - // The PDISC failed. Set login struct flags accordingly, - // terminate any I/O to this port, and Q a PLOGI - if( pLoggedInPort ) // FC device previously known? - { - - cpqfcTSPutLinkQue( cpqfcHBAdata, - ELS_LOGO, // Q Type - fchs ); // has port_id to send to - - // There are a variety of error scenarios which can result - // in PDISC failure, so as a catchall, add the check for - // duplicate port_id. - TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort); - -// TriggerHBA( fcChip->Registers.ReMapMemBase, 0); - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; - pLoggedInPort->plogi = FALSE; - - cpqfcTSTerminateExchange( cpqfcHBAdata, - &pLoggedInPort->ScsiNexus, PORTID_CHANGED); - } - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs ); - } - } - else - { - // login payload unacceptable - reason in ls_reject_code - // Q up a Logout Request - printk("ERROR: Login Payload unacceptable!\n"); - - } - - break; - - - - case ELS_PRLI: // we sent out PRLI - - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search Scsi Nexus - (fchs->s_id & 0xFFFFFF), // search linked list for port_id - NULL, // DON'T search linked list for WWN - NULL); // don't care - - if( pLoggedInPort == NULL ) - { - // huh? - printk(" Unexpected PRLI ACCept frame!\n"); - - // Q a LOGOut here? - - goto Done; - } - - // verify the PRLI ACC payload - if( !verify_PRLI( fchs, &ls_reject_code) ) - { - // PRLI Reply is acceptable; were we expecting it? - if( pLoggedInPort->plogi ) - { - // yes, we expected the PRLI ACC (not PDISC; Originator) - SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE); - - // OK, let's send a REPORT_LUNS command to determine - // whether VSA or PDA FCP-LUN addressing is used. - - cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs ); - - // It's possible that a device we were talking to changed - // port_id, and has logged back in. This function ensures - // that I/O will resume. - UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort); - - } - else - { - // huh? - printk(" (unexpected) PRLI ACCept with plogi FALSE\n"); - - // Q a LOGOut here? - goto Done; - } - } - else - { - printk(" PRLI ACCept payload failed verify\n"); - - // Q a LOGOut here? - } - - break; - - case ELS_FLOGI: // we sent out FLOGI (Fabric Login) - - // update the upper 16 bits of our port_id in Tachyon - // the switch adds those upper 16 bits when responding - // to us (i.e. we are the destination_id) - fcChip->Registers.my_al_pa = (fchs->d_id & 0xFFFFFF); - writel( fcChip->Registers.my_al_pa, - fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID); - - // now send out a PLOGI to the well known port_id 0xFFFFFC - fchs->s_id = 0xFFFFFC; - cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs); - - break; - - - case ELS_FDISC: // we sent out FDISC (Fabric Discovery (Login)) - - printk( " ELS_FDISC success "); - break; - - - case ELS_SCR: // we sent out State Change Registration - // now we can issue Name Service Request to find any - // Fabric-connected devices we might want to login to. - - - fchs->s_id = 0xFFFFFC; // Name Server Address - cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs); - - - break; - - - default: - printk(" *Discarding unknown ACC frame, xID %04X/%04X* ", - ox_id, fchs->ox_rx_id & 0xffff); - break; - } - - -Done: - // Regardless of whether the Reply is valid or not, the - // the exchange is done - complete - cpqfcTSCompleteExchange(cpqfcHBAdata->PciDev, fcChip, (fchs->ox_rx_id >>16)); - -Quit: - return; -} - - - - - - -// **************** Fibre Channel Services ************** -// This is where we process the Directory (Name) Service Reply -// to know which devices are on the Fabric - -static void ProcessFCS_Reply( - CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG ox_id = (fchs->ox_rx_id >>16); -// ULONG ls_reject_code; -// PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort; - - // If this is a valid reply, then we MUST have sent a request. - // Verify that we can find a valid request OX_ID corresponding to - // this reply - - if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0) - { - printk(" *Discarding Reply frame, xID %04X/%04X* ", - ox_id, fchs->ox_rx_id & 0xffff); - goto Quit; // exit this routine - } - - - // OK, we were expecting it. Now check to see if it's a - // "Name Service" Reply, and if so force a re-validation of - // Fabric device logins (i.e. Start the login timeout and - // send PDISC or PLOGI) - // (Endianess Byte Swap?) - if( fchs->pl[1] == 0x02FC ) // Name Service - { - // got a new (or NULL) list of Fabric attach devices... - // Invalidate current logins - - PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts; - while( pLoggedInPort ) // for all ports which are expecting - // PDISC after the next LIP, set the - // logoutTimer - { - - if( (pLoggedInPort->port_id & 0xFFFF00) // Fabric device? - && - (pLoggedInPort->port_id != 0xFFFFFC) ) // NOT the F_Port - { - pLoggedInPort->LOGO_timer = 6; // what's the Fabric timeout?? - // suspend any I/O in progress until - // PDISC received... - pLoggedInPort->prli = FALSE; // block FCP-SCSI commands - } - - pLoggedInPort = pLoggedInPort->pNextPort; - } - - if( fchs->pl[2] == 0x0280) // ACCept? - { - // Send PLOGI or PDISC to these Fabric devices - SendLogins( cpqfcHBAdata, &fchs->pl[4] ); - } - - - // As of this writing, the only reason to reject is because NO - // devices are left on the Fabric. We already started - // "logged out" timers; if the device(s) don't come - // back, we'll do the implicit logout in the heart beat - // timer routine - else // ReJecT - { - // this just means no Fabric device is visible at this instant - } - } - - // Regardless of whether the Reply is valid or not, the - // the exchange is done - complete - cpqfcTSCompleteExchange(cpqfcHBAdata->PciDev, fcChip, (fchs->ox_rx_id >>16)); - -Quit: - return; -} - - - - - - - -static void AnalyzeIncomingFrame( - CPQFCHBA *cpqfcHBAdata, - ULONG QNdx ) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ; - TachFCHDR_GCMND* fchs = - (TachFCHDR_GCMND*)fcLQ->Qitem[QNdx].ulBuff; -// ULONG ls_reject_code; // reason for rejecting login - LONG ExchangeID; -// FC_LOGGEDIN_PORT *pLoggedInPort; - BOOLEAN AbortAccept; - - ENTER("AnalyzeIncomingFrame"); - - - - switch( fcLQ->Qitem[QNdx].Type) // FCP or Unknown - { - - case SFQ_UNKNOWN: // unknown frame (e.g. LIP position frame, NOP, etc.) - - - // ********* FC-4 Device Data/ Fibre Channel Service ************* - if( ((fchs->d_id &0xF0000000) == 0) // R_CTL (upper nibble) 0x0? - && - (fchs->f_ctl & 0x20000000) ) // TYPE 20h is Fibre Channel Service - { - - // ************** FCS Reply ********************** - - if( (fchs->d_id & 0xff000000L) == 0x03000000L) // (31:23 R_CTL) - { - ProcessFCS_Reply( cpqfcHBAdata, fchs ); - - } // end of FCS logic - - } - - - // *********** Extended Link Service ************** - - else if( fchs->d_id & 0x20000000 // R_CTL 0x2? - && - (fchs->f_ctl & 0x01000000) ) // TYPE = 1 - { - - // these frames are either a response to - // something we sent (0x23) or "unsolicited" - // frames (0x22). - - - // **************Extended Link REPLY ********************** - // R_CTL Solicited Control Reply - - if( (fchs->d_id & 0xff000000L) == 0x23000000L) // (31:23 R_CTL) - { - - ProcessELS_Reply( cpqfcHBAdata, fchs ); - - } // end of "R_CTL Solicited Control Reply" - - - - - // **************Extended Link REQUEST ********************** - // (unsolicited commands from another port or task...) - - // R_CTL Ext Link REQUEST - else if( (fchs->d_id & 0xff000000L) == 0x22000000L && - (fchs->ox_rx_id != 0xFFFFFFFFL) ) // (ignore LIP frame) - { - - - - ProcessELS_Request( cpqfcHBAdata, fchs ); - - } - - - - // ************** LILP ********************** - else if( (fchs->d_id & 0xff000000L) == 0x22000000L && - (fchs->ox_rx_id == 0xFFFFFFFFL)) // (e.g., LIP frames) - - { - // SANMark specifies that when available, we must use - // the LILP frame to determine which ALPAs to send Port Discovery - // to... - - if( fchs->pl[0] == 0x0711L) // ELS_PLOGI? - { -// UCHAR *ptr = (UCHAR*)&fchs->pl[1]; -// printk(" %d ALPAs found\n", *ptr); - memcpy( fcChip->LILPmap, &fchs->pl[1], 32*4); // 32 DWORDs - fcChip->Options.LILPin = 1; // our LILPmap is valid! - // now post to make Port Discovery happen... - cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, fchs); - } - } - } - - - // ***************** BASIC LINK SERVICE ***************** - - else if( fchs->d_id & 0x80000000 // R_CTL: - && // Basic Link Service Request - !(fchs->f_ctl & 0xFF000000) ) // type=0 for BLS - { - - // Check for ABTS (Abort Sequence) - if( (fchs->d_id & 0x8F000000) == 0x81000000) - { - // look for OX_ID, S_ID pair that matches in our - // fcExchanges table; if found, reply with ACCept and complete - // the exchange - - // Per PLDA, an ABTS is sent by an initiator; therefore - // assume that if we have an exhange open to the port who - // sent ABTS, it will be the d_id of what we sent. - for( ExchangeID = 0, AbortAccept=FALSE; - ExchangeID < TACH_SEST_LEN; ExchangeID++) - { - // Valid "target" exchange 24-bit port_id matches? - // NOTE: For the case of handling Intiator AND Target - // functions on the same chip, we can have TWO Exchanges - // with the same OX_ID -- OX_ID/FFFF for the CMND, and - // OX_ID/RX_ID for the XRDY or DATA frame(s). Ideally, - // we would like to support ABTS from Initiators or Targets, - // but it's not clear that can be supported on Tachyon for - // all cases (requires more investigation). - - if( (Exchanges->fcExchange[ ExchangeID].type == SCSI_TWE || - Exchanges->fcExchange[ ExchangeID].type == SCSI_TRE) - && - ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) == - (fchs->s_id & 0xFFFFFF)) ) - { - - // target xchnge port_id matches -- how about OX_ID? - if( (Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id &0xFFFF0000) - == (fchs->ox_rx_id & 0xFFFF0000) ) - // yes! post ACCept response; will be completed by fcStart - { - Exchanges->fcExchange[ ExchangeID].status = TARGET_ABORT; - - // copy (add) rx_id field for simplified ACCept reply - fchs->ox_rx_id = - Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id; - - cpqfcTSPutLinkQue( cpqfcHBAdata, - BLS_ABTS_ACC, // Q Type - fchs ); // void QueContent - AbortAccept = TRUE; - printk("ACCepting ABTS for x_ID %8.8Xh, SEST pair %8.8Xh\n", - fchs->ox_rx_id, Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id); - break; // ABTS can affect only ONE exchange -exit loop - } - } - } // end of FOR loop - if( !AbortAccept ) // can't ACCept ABTS - send Reject - { - printk("ReJecTing: can't find ExchangeID %8.8Xh for ABTS command\n", - fchs->ox_rx_id); - if( Exchanges->fcExchange[ ExchangeID].type - && - !(fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len - & 0x80000000)) - { - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID); - } - else - { - printk("Unexpected ABTS ReJecT! SEST[%X] Dword 0: %Xh\n", - ExchangeID, fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len); - } - } - } - - // Check for BLS {ABTS? (Abort Sequence)} ACCept - else if( (fchs->d_id & 0x8F000000) == 0x84000000) - { - // target has responded with ACC for our ABTS; - // complete the indicated exchange with ABORTED status - // Make no checks for correct RX_ID, since - // all we need to conform ABTS ACC is the OX_ID. - // Verify that the d_id matches! - - ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC -// printk("ABTS ACC x_ID 0x%04X 0x%04X, status %Xh\n", -// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff, -// Exchanges->fcExchange[ExchangeID].status); - - - - if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense - { - // Does "target" exchange 24-bit port_id match? - // (See "NOTE" above for handling Intiator AND Target in - // the same device driver) - // First, if this is a target response, then we originated - // (initiated) it with BLS_ABTS: - - if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS) - - && - // Second, does the source of this ACC match the destination - // of who we originally sent it to? - ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) == - (fchs->s_id & 0xFFFFFF)) ) - { - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID ); - } - } - } - // Check for BLS {ABTS? (Abort Sequence)} ReJecT - else if( (fchs->d_id & 0x8F000000) == 0x85000000) - { - // target has responded with RJT for our ABTS; - // complete the indicated exchange with ABORTED status - // Make no checks for correct RX_ID, since - // all we need to conform ABTS ACC is the OX_ID. - // Verify that the d_id matches! - - ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC -// printk("BLS_ABTS RJT on Exchange 0x%04X 0x%04X\n", -// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff); - - if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense - { - // Does "target" exchange 24-bit port_id match? - // (See "NOTE" above for handling Intiator AND Target in - // the same device driver) - // First, if this is a target response, then we originated - // (initiated) it with BLS_ABTS: - - if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS) - - && - // Second, does the source of this ACC match the destination - // of who we originally sent it to? - ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) == - (fchs->s_id & 0xFFFFFF)) ) - { - // YES! NOTE: There is a bug in CPQ's RA-4000 box - // where the "reason code" isn't returned in the payload - // For now, simply presume the reject is because the target - // already completed the exchange... - -// printk("complete x_ID %Xh on ABTS RJT\n", ExchangeID); - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID ); - } - } - } // end of ABTS check - } // end of Basic Link Service Request - break; - - default: - printk("AnalyzeIncomingFrame: unknown type: %Xh(%d)\n", - fcLQ->Qitem[QNdx].Type, - fcLQ->Qitem[QNdx].Type); - break; - } -} - - -// Function for Port Discovery necessary after every FC -// initialization (e.g. LIP). -// Also may be called if from Fabric Name Service logic. - -static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds ) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG ulStatus=0; - TachFCHDR_GCMND fchs; // copy fields for transmission - int i; - ULONG loginType; - LONG ExchangeID; - PFC_LOGGEDIN_PORT pLoggedInPort; - __u32 PortIds[ number_of_al_pa]; - int NumberOfPorts=0; - - // We're going to presume (for now) that our limit of Fabric devices - // is the same as the number of alpa on a private loop (126 devices). - // (Of course this could be changed to support however many we have - // memory for). - memset( &PortIds[0], 0, sizeof(PortIds)); - - // First, check if this login is for our own Link Initialization - // (e.g. LIP on FC-AL), or if we have knowledge of Fabric devices - // from a switch. If we are logging into Fabric devices, we'll - // have a non-NULL FabricPortId pointer - - if( FabricPortIds != NULL) // may need logins - { - int LastPort=FALSE; - i = 0; - while( !LastPort) - { - // port IDs From NSR payload; byte swap needed? - BigEndianSwap( (UCHAR*)FabricPortIds, (UCHAR*)&PortIds[i], 4); - -// printk("FPortId[%d] %Xh ", i, PortIds[i]); - if( PortIds[i] & 0x80000000) - LastPort = TRUE; - - PortIds[i] &= 0xFFFFFF; // get 24-bit port_id - // some non-Fabric devices (like the Crossroads Fibre/Scsi bridge) - // erroneously use ALPA 0. - if( PortIds[i] ) // need non-zero port_id... - i++; - - if( i >= number_of_al_pa ) // (in)sanity check - break; - FabricPortIds++; // next... - } - - NumberOfPorts = i; -// printk("NumberOf Fabric ports %d", NumberOfPorts); - } - - else // need to send logins on our "local" link - { - - // are we a loop port? If so, check for reception of LILP frame, - // and if received use it (SANMark requirement) - if( fcChip->Options.LILPin ) - { - int j=0; - // sanity check on number of ALPAs from LILP frame... - // For format of LILP frame, see FC-AL specs or - // "Fibre Channel Bench Reference", J. Stai, 1995 (ISBN 1-879936-17-8) - // First byte is number of ALPAs - i = fcChip->LILPmap[0] >= (32*4) ? 32*4 : fcChip->LILPmap[0]; - NumberOfPorts = i; -// printk(" LILP alpa count %d ", i); - while( i > 0) - { - PortIds[j] = fcChip->LILPmap[1+ j]; - j++; i--; - } - } - else // have to send login to everybody - { - int j=0; - i = number_of_al_pa; - NumberOfPorts = i; - while( i > 0) - { - PortIds[j] = valid_al_pa[j]; // all legal ALPAs - j++; i--; - } - } - } - - - // Now we have a copy of the port_ids (and how many)... - for( i = 0; i < NumberOfPorts; i++) - { - // 24-bit FC Port ID - fchs.s_id = PortIds[i]; // note: only 8-bits used for ALPA - - - // don't log into ourselves (Linux Scsi disk scan will stop on - // no TARGET support error on us, and quit trying for rest of devices) - if( (fchs.s_id & 0xFF ) == (fcChip->Registers.my_al_pa & 0xFF) ) - continue; - - // fabric login needed? - if( (fchs.s_id == 0) || - (fcChip->Options.fabric == 1) ) - { - fcChip->Options.flogi = 1; // fabric needs longer for login - // Do we need FLOGI or FDISC? - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search SCSI Nexus - 0xFFFFFC, // search linked list for Fabric port_id - NULL, // don't search WWN - NULL); // (don't care about end of list) - - if( pLoggedInPort ) // If found, we have prior experience with - // this port -- check whether PDISC is needed - { - if( pLoggedInPort->flogi ) - { - // does the switch support FDISC?? (FLOGI for now...) - loginType = ELS_FLOGI; // prior FLOGI still valid - } - else - loginType = ELS_FLOGI; // expired FLOGI - } - else // first FLOGI? - loginType = ELS_FLOGI; - - - fchs.s_id = 0xFFFFFE; // well known F_Port address - - // Fabrics are not required to support FDISC, and - // it's not clear if that helps us anyway, since - // we'll want a Name Service Request to re-verify - // visible devices... - // Consequently, we always want our upper 16 bit - // port_id to be zero (we'll be rejected if we - // use our prior port_id if we've been plugged into - // a different switch port). - // Trick Tachyon to send to ALPA 0 (see TL/TS UG, pg 87) - // If our ALPA is 55h for instance, we want the FC frame - // s_id to be 0x000055, while Tach's my_al_pa register - // must be 0x000155, to force an OPN at ALPA 0 - // (the Fabric port) - fcChip->Registers.my_al_pa &= 0xFF; // only use ALPA for FLOGI - writel( fcChip->Registers.my_al_pa | 0x0100, - fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID); - } - - else // not FLOGI... - { - // should we send PLOGI or PDISC? Check if any prior port_id - // (e.g. alpa) completed a PLOGI/PRLI exchange by checking - // the pdisc flag. - - pLoggedInPort = fcFindLoggedInPort( - fcChip, - NULL, // don't search SCSI Nexus - fchs.s_id, // search linked list for al_pa - NULL, // don't search WWN - NULL); // (don't care about end of list) - - - - if( pLoggedInPort ) // If found, we have prior experience with - // this port -- check whether PDISC is needed - { - if( pLoggedInPort->pdisc ) - { - loginType = ELS_PDISC; // prior PLOGI and PRLI maybe still valid - - } - else - loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC - } - else // never talked to this port_id before - loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC - } - - - - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - loginType, // e.g. PLOGI - &fchs, // no incoming frame (we are originator) - NULL, // no data (no scatter/gather list) - &ExchangeID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup OK? - { - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID ); - if( !ulStatus ) - { - // submitted to Tach's Outbound Que (ERQ PI incremented) - // waited for completion for ELS type (Login frames issued - // synchronously) - - if( loginType == ELS_PDISC ) - { - // now, we really shouldn't Revalidate SEST exchanges until - // we get an ACC reply from our target and verify that - // the target address/WWN is unchanged. However, when a fast - // target gets the PDISC, they can send SEST Exchange data - // before we even get around to processing the PDISC ACC. - // Consequently, we lose the I/O. - // To avoid this, go ahead and Revalidate when the PDISC goes - // out, anticipating that the ACC will be truly acceptable - // (this happens 99.9999....% of the time). - // If we revalidate a SEST write, and write data goes to a - // target that is NOT the one we originated the WRITE to, - // that target is required (FCP-SCSI specs, etc) to discard - // our WRITE data. - - // Re-validate SEST entries (Tachyon hardware assists) - RevalidateSEST( cpqfcHBAdata->HostAdapter, pLoggedInPort); - //TriggerHBA( fcChip->Registers.ReMapMemBase, 1); - } - } - else // give up immediately on error - { -#ifdef LOGIN_DBG - printk("SendLogins: fcStartExchange failed: %Xh\n", ulStatus ); -#endif - break; - } - - - if( fcChip->Registers.FMstatus.value & 0x080 ) // LDn during Port Disc. - { - ulStatus = LNKDWN_OSLS; -#ifdef LOGIN_DBG - printk("SendLogins: PortDisc aborted (LDn) @alpa %Xh\n", fchs.s_id); -#endif - break; - } - // Check the exchange for bad status (i.e. FrameTimeOut), - // and complete on bad status (most likely due to BAD_ALPA) - // on LDn, DPC function may already complete (ABORT) a started - // exchange, so check type first (type = 0 on complete). - if( Exchanges->fcExchange[ExchangeID].status ) - { -#ifdef LOGIN_DBG - printk("completing x_ID %X on status %Xh\n", - ExchangeID, Exchanges->fcExchange[ExchangeID].status); -#endif - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID); - } - } - else // Xchange setup failed... - { -#ifdef LOGIN_DBG - printk("FC: cpqfcTSBuildExchange failed: %Xh\n", ulStatus ); -#endif - break; - } - } - if( !ulStatus ) - { - // set the event signifying that all ALPAs were sent out. -#ifdef LOGIN_DBG - printk("SendLogins: PortDiscDone\n"); -#endif - cpqfcHBAdata->PortDiscDone = 1; - - - // TL/TS UG, pg. 184 - // 0x0065 = 100ms for RT_TOV - // 0x01f5 = 500ms for ED_TOV - fcChip->Registers.ed_tov.value = 0x006501f5L; - writel( fcChip->Registers.ed_tov.value, - (fcChip->Registers.ed_tov.address)); - - // set the LP_TOV back to ED_TOV (i.e. 500 ms) - writel( 0x00000010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2); - } - else - { - printk("SendLogins: failed at xchng %Xh, alpa %Xh, status %Xh\n", - ExchangeID, fchs.s_id, ulStatus); - } - LEAVE("SendLogins"); - -} - - -// for REPORT_LUNS documentation, see "In-Depth Exploration of Scsi", -// D. Deming, 1994, pg 7-19 (ISBN 1-879936-08-9) -static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd) -{ - struct Scsi_Host *HostAdapter = Cmnd->device->host; - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - PFC_LOGGEDIN_PORT pLoggedInPort; - int LunListLen=0; - int i; - ULONG x_ID = 0xFFFFFFFF; - UCHAR *ucBuff = Cmnd->request_buffer; - -// printk("cpqfcTS: ReportLunsDone \n"); - // first, we need to find the Exchange for this command, - // so we can find the fcPort struct to make the indicated - // changes. - for( i=0; i< TACH_SEST_LEN; i++) - { - if( Exchanges->fcExchange[i].type // exchange defined? - && - (Exchanges->fcExchange[i].Cmnd == Cmnd) ) // matches? - - { - x_ID = i; // found exchange! - break; - } - } - if( x_ID == 0xFFFFFFFF) - { -// printk("cpqfcTS: ReportLuns failed - no FC Exchange\n"); - goto Done; // Report Luns FC Exchange gone; - // exchange probably Terminated by Implicit logout - } - - - // search linked list for the port_id we sent INQUIRY to - pLoggedInPort = fcFindLoggedInPort( fcChip, - NULL, // DON'T search Scsi Nexus (we will set it) - Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF, - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - if( !pLoggedInPort ) - { -// printk("cpqfcTS: ReportLuns failed - device gone\n"); - goto Done; // error! can't find logged in Port - } - LunListLen = ucBuff[3]; - LunListLen += ucBuff[2]>>8; - - if( !LunListLen ) // failed - { - // generically speaking, a soft error means we should retry... - if( (Cmnd->result >> 16) == DID_SOFT_ERROR ) - { - if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) && - (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset" - { - TachFCHDR_GCMND *fchs = &Exchanges->fcExchange[ x_ID].fchs; - // did we fail because of "check condition, device reset?" - // e.g. the device was reset (i.e., at every power up) - // retry the Report Luns - - // who are we sending it to? - // we know this because we have a copy of the command - // frame from the original Report Lun command - - // switch the d_id/s_id fields, because the Exchange Build - // context is "reply to source". - - fchs->s_id = fchs->d_id; // (temporarily re-use the struct) - cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs ); - } - } - else // probably, the device doesn't support Report Luns - pLoggedInPort->ScsiNexus.VolumeSetAddressing = 0; - } - else // we have LUN info - check VSA mode - { - // for now, assume all LUNs will have same addr mode - // for VSA, payload byte 8 will be 0x40; otherwise, 0 - pLoggedInPort->ScsiNexus.VolumeSetAddressing = ucBuff[8]; - - // Since we got a Report Luns answer, set lun masking flag - pLoggedInPort->ScsiNexus.LunMasking = 1; - - if( LunListLen > 8*CPQFCTS_MAX_LUN) // We expect CPQFCTS_MAX_LUN max - LunListLen = 8*CPQFCTS_MAX_LUN; - -/* - printk("Device WWN %08X%08X Reports Luns @: ", - (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF), - (ULONG)(pLoggedInPort->u.liWWN>>32)); - - for( i=8; iScsiNexus.lun[j] != 0xFF ) - { - AppendLunList = 1; - break; - } - } - if( AppendLunList ) - { - int k; - int FreeLunIndex; -// printk("cpqfcTS: AppendLunList\n"); - - // If we get a new Report Luns, we cannot change - // any existing LUN mapping! (Only additive entry) - // For all LUNs in ReportLun list - // if RL lun != ScsiNexus lun - // if RL lun present in ScsiNexus lun[], continue - // else find ScsiNexus lun[]==FF and add, continue - - for( i=8, j=0; iScsiNexus.lun[j] != ucBuff[i+1] ) - { - // something changed from the last Report Luns - printk(" cpqfcTS: Report Lun change!\n"); - for( k=0, FreeLunIndex=CPQFCTS_MAX_LUN; - k < CPQFCTS_MAX_LUN; k++) - { - if( pLoggedInPort->ScsiNexus.lun[k] == 0xFF) - { - FreeLunIndex = k; - break; - } - if( pLoggedInPort->ScsiNexus.lun[k] == ucBuff[i+1] ) - break; // we already masked this lun - } - if( k >= CPQFCTS_MAX_LUN ) - { - printk(" no room for new LUN %d\n", ucBuff[i+1]); - } - else if( k == FreeLunIndex ) // need to add LUN - { - pLoggedInPort->ScsiNexus.lun[k] = ucBuff[i+1]; -// printk("add [%d]->%02d\n", k, pLoggedInPort->ScsiNexus.lun[k]); - - } - else - { - // lun already known - } - break; - } - } - // print out the new list... - for( j=0; j< CPQFCTS_MAX_LUN; j++) - { - if( pLoggedInPort->ScsiNexus.lun[j] == 0xFF) - break; // done -// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]); - } - } - else - { -// printk("Linux SCSI LUNs[] -> Device LUNs: "); - // first time - this is easy - for( i=8, j=0; iScsiNexus.lun[j] = ucBuff[i+1]; -// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]); - } -// printk("\n"); - } - } - } - -Done: ; -} - -extern int is_private_data_of_cpqfc(CPQFCHBA *hba, void * pointer); -extern void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data); - -static void -call_scsi_done(Scsi_Cmnd *Cmnd) -{ - CPQFCHBA *hba; - hba = (CPQFCHBA *) Cmnd->device->host->hostdata; - // Was this command a cpqfc passthru ioctl ? - if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL && - Cmnd->device->host->hostdata != NULL && - is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata, - Cmnd->sc_request->upper_private_data)) { - cpqfc_free_private_data(hba, - Cmnd->sc_request->upper_private_data); - Cmnd->sc_request->upper_private_data = NULL; - Cmnd->result &= 0xff00ffff; - Cmnd->result |= (DID_PASSTHROUGH << 16); // prevents retry - } - if (Cmnd->scsi_done != NULL) - (*Cmnd->scsi_done)(Cmnd); -} - -// After successfully getting a "Process Login" (PRLI) from an -// FC port, we want to Discover the LUNs so that we know the -// addressing type (e.g., FCP-SCSI Volume Set Address, Peripheral -// Unit Device), and whether SSP (Selective Storage Presentation or -// Lun Masking) has made the LUN numbers non-zero based or -// non-contiguous. To remain backward compatible with the SCSI-2 -// driver model, which expects a contiguous LUNs starting at 0, -// will use the ReportLuns info to map from "device" to "Linux" -// LUNs. -static void IssueReportLunsCommand( - CPQFCHBA* cpqfcHBAdata, - TachFCHDR_GCMND* fchs) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - PFC_LOGGEDIN_PORT pLoggedInPort; - struct scsi_cmnd *Cmnd = NULL; - struct scsi_device *ScsiDev = NULL; - LONG x_ID; - ULONG ulStatus; - UCHAR *ucBuff; - - if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn - { - printk("Discard Q'd ReportLun command\n"); - goto Done; - } - - // find the device (from port_id) we're talking to - pLoggedInPort = fcFindLoggedInPort( fcChip, - NULL, // DON'T search Scsi Nexus - fchs->s_id & 0xFFFFFF, - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - if( pLoggedInPort ) // we'd BETTER find it! - { - - - if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) ) - goto Done; // forget it - FC device not a "target" - - - ScsiDev = scsi_get_host_dev (cpqfcHBAdata->HostAdapter); - if (!ScsiDev) - goto Done; - - Cmnd = scsi_get_command (ScsiDev, GFP_KERNEL); - if (!Cmnd) - goto Done; - - ucBuff = pLoggedInPort->ReportLunsPayload; - - memset( ucBuff, 0, REPORT_LUNS_PL); - - Cmnd->scsi_done = ScsiReportLunsDone; - - Cmnd->request_buffer = pLoggedInPort->ReportLunsPayload; - Cmnd->request_bufflen = REPORT_LUNS_PL; - - Cmnd->cmnd[0] = 0xA0; - Cmnd->cmnd[8] = REPORT_LUNS_PL >> 8; - Cmnd->cmnd[9] = (UCHAR)REPORT_LUNS_PL; - Cmnd->cmd_len = 12; - - Cmnd->device->channel = pLoggedInPort->ScsiNexus.channel; - Cmnd->device->id = pLoggedInPort->ScsiNexus.target; - - - ulStatus = cpqfcTSBuildExchange( - cpqfcHBAdata, - SCSI_IRE, - fchs, - Cmnd, // buffer for Report Lun data - &x_ID );// fcController->fcExchanges index, -1 if failed - - if( !ulStatus ) // Exchange setup? - { - ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID ); - if( !ulStatus ) - { - // submitted to Tach's Outbound Que (ERQ PI incremented) - // waited for completion for ELS type (Login frames issued - // synchronously) - } - else - // check reason for Exchange not being started - we might - // want to Queue and start later, or fail with error - { - - } - } - - else // Xchange setup failed... - printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus ); - } - else // like, we just got a PRLI ACC, and now the port is gone? - { - printk(" can't send ReportLuns - no login for port_id %Xh\n", - fchs->s_id & 0xFFFFFF); - } - - - -Done: - - if (Cmnd) - scsi_put_command (Cmnd); - if (ScsiDev) - scsi_free_host_dev (ScsiDev); -} - - - - - - - -static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata) -{ - int i; - for( i = CPQFCTS_REQ_QUEUE_LEN-1; i>= 0; i--) - { - if( cpqfcHBAdata->BoardLockCmnd[i] != NULL ) - { - Scsi_Cmnd *Cmnd = cpqfcHBAdata->BoardLockCmnd[i]; - cpqfcHBAdata->BoardLockCmnd[i] = NULL; - Cmnd->result = (DID_SOFT_ERROR << 16); // ask for retry -// printk(" BoardLockCmnd[%d] %p Complete, chnl/target/lun %d/%d/%d\n", -// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun); - call_scsi_done(Cmnd); - } - } -} - - - - - - -// runs every 1 second for FC exchange timeouts and implicit FC device logouts - -void cpqfcTSheartbeat( unsigned long ptr ) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)ptr; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts; - ULONG i; - unsigned long flags; - DECLARE_MUTEX_LOCKED(BoardLock); - - PCI_TRACE( 0xA8) - - if( cpqfcHBAdata->BoardLock) // Worker Task Running? - goto Skip; - - // STOP _que function - spin_lock_irqsave( cpqfcHBAdata->HostAdapter->host_lock, flags); - - PCI_TRACE( 0xA8) - - - cpqfcHBAdata->BoardLock = &BoardLock; // stop Linux SCSI command queuing - - // release the IO lock (and re-enable interrupts) - spin_unlock_irqrestore( cpqfcHBAdata->HostAdapter->host_lock, flags); - - // Ensure no contention from _quecommand or Worker process - CPQ_SPINLOCK_HBA( cpqfcHBAdata) - - PCI_TRACE( 0xA8) - - - disable_irq( cpqfcHBAdata->HostAdapter->irq); // our IRQ - - // Complete the "bad target" commands (normally only used during - // initialization, since we aren't supposed to call "scsi_done" - // inside the queuecommand() function). (this is overly contorted, - // scsi_done can be safely called from queuecommand for - // this bad target case. May want to simplify this later) - - for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++) - { - if( cpqfcHBAdata->BadTargetCmnd[i] ) - { - Scsi_Cmnd *Cmnd = cpqfcHBAdata->BadTargetCmnd[i]; - cpqfcHBAdata->BadTargetCmnd[i] = NULL; - Cmnd->result = (DID_BAD_TARGET << 16); - call_scsi_done(Cmnd); - } - else - break; - } - - - // logged in ports -- re-login check (ports required to verify login with - // PDISC after LIP within 2 secs) - - // prevent contention - while( pLoggedInPort ) // for all ports which are expecting - // PDISC after the next LIP, check to see if - // time is up! - { - // Important: we only detect "timeout" condition on TRANSITION - // from non-zero to zero - if( pLoggedInPort->LOGO_timer ) // time-out "armed"? - { - if( !(--pLoggedInPort->LOGO_timer) ) // DEC from 1 to 0? - { - // LOGOUT time! Per PLDA, PDISC hasn't complete in 2 secs, so - // issue LOGO request and destroy all I/O with other FC port(s). - -/* - printk(" ~cpqfcTS heartbeat: LOGOut!~ "); - printk("Linux SCSI Chanl/Target %d/%d (port_id %06Xh) WWN %08X%08X\n", - pLoggedInPort->ScsiNexus.channel, - pLoggedInPort->ScsiNexus.target, - pLoggedInPort->port_id, - (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF), - (ULONG)(pLoggedInPort->u.liWWN>>32)); - -*/ - cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort); - - } - // else simply decremented - maybe next time... - } - pLoggedInPort = pLoggedInPort->pNextPort; - } - - - - - - // ************ FC EXCHANGE TIMEOUT CHECK ************** - - for( i=0; i< TACH_MAX_XID; i++) - { - if( Exchanges->fcExchange[i].type ) // exchange defined? - { - - if( !Exchanges->fcExchange[i].timeOut ) // time expired - { - // Set Exchange timeout status - Exchanges->fcExchange[i].status |= FC2_TIMEOUT; - - if( i >= TACH_SEST_LEN ) // Link Service Exchange - { - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // Don't "abort" LinkService - } - - else // SEST Exchange TO -- may post ABTS to Worker Thread Que - { - // (Make sure we don't keep timing it out; let other functions - // complete it or set the timeOut as needed) - Exchanges->fcExchange[i].timeOut = 30000; // seconds default - - if( Exchanges->fcExchange[i].type - & - (BLS_ABTS | BLS_ABTS_ACC ) ) - { - // For BLS_ABTS*, an upper level might still have - // an outstanding command waiting for low-level completion. - // Also, in the case of a WRITE, we MUST get confirmation - // of either ABTS ACC or RJT before re-using the Exchange. - // It's possible that the RAID cache algorithm can hang - // if we fail to complete a WRITE to a LBA, when a READ - // comes later to that same LBA. Therefore, we must - // ensure that the target verifies receipt of ABTS for - // the exchange - - printk("~TO Q'd ABTS (x_ID %Xh)~ ", i); -// TriggerHBA( fcChip->Registers.ReMapMemBase); - - // On timeout of a ABTS exchange, check to - // see if the FC device has a current valid login. - // If so, restart it. - pLoggedInPort = fcFindLoggedInPort( fcChip, - Exchanges->fcExchange[i].Cmnd, // find Scsi Nexus - 0, // DON'T search linked list for FC port id - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - // device exists? - if( pLoggedInPort ) // device exists? - { - if( pLoggedInPort->prli ) // logged in for FCP-SCSI? - { - // attempt to restart the ABTS - printk(" ~restarting ABTS~ "); - cpqfcTSStartExchange( cpqfcHBAdata, i ); - - } - } - } - else // not an ABTS - { - - // We expect the WorkerThread to change the xchng type to - // abort and set appropriate timeout. - cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i ); // timed-out - } - } - } - else // time not expired... - { - // decrement timeout: 1 or more seconds left - --Exchanges->fcExchange[i].timeOut; - } - } - } - - - enable_irq( cpqfcHBAdata->HostAdapter->irq); - - - CPQ_SPINUNLOCK_HBA( cpqfcHBAdata) - - cpqfcHBAdata->BoardLock = NULL; // Linux SCSI commands may be queued - - // Now, complete any Cmnd we Q'd up while BoardLock was held - - CompleteBoardLockCmnd( cpqfcHBAdata); - - - // restart the timer to run again (1 sec later) -Skip: - mod_timer( &cpqfcHBAdata->cpqfcTStimer, jiffies + HZ); - - PCI_TRACEO( i, 0xA8) - return; -} - - -// put valid FC-AL physical address in spec order -static const UCHAR valid_al_pa[]={ - 0xef, 0xe8, 0xe4, 0xe2, - 0xe1, 0xE0, 0xDC, 0xDA, - 0xD9, 0xD6, 0xD5, 0xD4, - 0xD3, 0xD2, 0xD1, 0xCe, - 0xCd, 0xCc, 0xCb, 0xCa, - 0xC9, 0xC7, 0xC6, 0xC5, - 0xC3, 0xBc, 0xBa, 0xB9, - 0xB6, 0xB5, 0xB4, 0xB3, - 0xB2, 0xB1, 0xae, 0xad, - 0xAc, 0xAb, 0xAa, 0xA9, - - 0xA7, 0xA6, 0xA5, 0xA3, - 0x9f, 0x9e, 0x9d, 0x9b, - 0x98, 0x97, 0x90, 0x8f, - 0x88, 0x84, 0x82, 0x81, - 0x80, 0x7c, 0x7a, 0x79, - 0x76, 0x75, 0x74, 0x73, - 0x72, 0x71, 0x6e, 0x6d, - 0x6c, 0x6b, 0x6a, 0x69, - 0x67, 0x66, 0x65, 0x63, - 0x5c, 0x5a, 0x59, 0x56, - - 0x55, 0x54, 0x53, 0x52, - 0x51, 0x4e, 0x4d, 0x4c, - 0x4b, 0x4a, 0x49, 0x47, - 0x46, 0x45, 0x43, 0x3c, - 0x3a, 0x39, 0x36, 0x35, - 0x34, 0x33, 0x32, 0x31, - 0x2e, 0x2d, 0x2c, 0x2b, - 0x2a, 0x29, 0x27, 0x26, - 0x25, 0x23, 0x1f, 0x1E, - 0x1d, 0x1b, 0x18, 0x17, - - 0x10, 0x0f, 8, 4, 2, 1 }; // ALPA 0 (Fabric) is special case - -const int number_of_al_pa = (sizeof(valid_al_pa) ); - - - -// this function looks up an al_pa from the table of valid al_pa's -// we decrement from the last decimal loop ID, because soft al_pa -// (our typical case) are assigned with highest priority (and high al_pa) -// first. See "In-Depth FC-AL", R. Kembel pg. 38 -// INPUTS: -// al_pa - 24 bit port identifier (8 bit al_pa on private loop) -// RETURN: -// Loop ID - serves are index to array of logged in ports -// -1 - invalid al_pa (not all 8 bit values are legal) - -#if (0) -static int GetLoopID( ULONG al_pa ) -{ - int i; - - for( i = number_of_al_pa -1; i >= 0; i--) // dec. - { - if( valid_al_pa[i] == (UCHAR)al_pa ) // take lowest 8 bits - return i; // success - found valid al_pa; return decimal LoopID - } - return -1; // failed - not found -} -#endif - -extern cpqfc_passthru_private_t *cpqfc_private(Scsi_Request *sr); - -// Search the singly (forward) linked list "fcPorts" looking for -// either the SCSI target (if != -1), port_id (if not NULL), -// or WWN (if not null), in that specific order. -// If we find a SCSI nexus (from Cmnd arg), set the SCp.phase -// field according to VSA or PDU -// RETURNS: -// Ptr to logged in port struct if found -// (NULL if not found) -// pLastLoggedInPort - ptr to last struct (for adding new ones) -// -PFC_LOGGEDIN_PORT fcFindLoggedInPort( - PTACHYON fcChip, - Scsi_Cmnd *Cmnd, // search linked list for Scsi Nexus (channel/target/lun) - ULONG port_id, // search linked list for al_pa, or - UCHAR wwn[8], // search linked list for WWN, or... - PFC_LOGGEDIN_PORT *pLastLoggedInPort ) - -{ - PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts; - BOOLEAN target_id_valid=FALSE; - BOOLEAN port_id_valid=FALSE; - BOOLEAN wwn_valid=FALSE; - int i; - - - if( Cmnd != NULL ) - target_id_valid = TRUE; - - else if( port_id ) // note! 24-bit NULL address is illegal - port_id_valid = TRUE; - - else - { - if( wwn ) // non-null arg? (OK to pass NULL when not searching WWN) - { - for( i=0; i<8; i++) // valid WWN passed? NULL WWN invalid - { - if( wwn[i] != 0 ) - wwn_valid = TRUE; // any non-zero byte makes (presumably) valid - } - } - } - // check other options ... - - - // In case multiple search options are given, we use a priority - // scheme: - // While valid pLoggedIn Ptr - // If port_id is valid - // if port_id matches, return Ptr - // If wwn is valid - // if wwn matches, return Ptr - // Next Ptr in list - // - // Return NULL (not found) - - - while( pLoggedInPort ) // NULL marks end of list (1st ptr always valid) - { - if( pLastLoggedInPort ) // caller's pointer valid? - *pLastLoggedInPort = pLoggedInPort; // end of linked list - - if( target_id_valid ) - { - // check Linux Scsi Cmnd for channel/target Nexus match - // (all luns are accessed through matching "pLoggedInPort") - if( (pLoggedInPort->ScsiNexus.target == Cmnd->device->id) - && - (pLoggedInPort->ScsiNexus.channel == Cmnd->device->channel)) - { - // For "passthru" modes, the IOCTL caller is responsible - // for setting the FCP-LUN addressing - if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL && - Cmnd->device->host->hostdata != NULL && - is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata, - Cmnd->sc_request->upper_private_data)) { - /* This is a passthru... */ - cpqfc_passthru_private_t *pd; - pd = Cmnd->sc_request->upper_private_data; - Cmnd->SCp.phase = pd->bus; - // Cmnd->SCp.have_data_in = pd->pdrive; - Cmnd->SCp.have_data_in = Cmnd->device->lun; - } else { - /* This is not a passthru... */ - - // set the FCP-LUN addressing type - Cmnd->SCp.phase = pLoggedInPort->ScsiNexus.VolumeSetAddressing; - - // set the Device Type we got from the snooped INQUIRY string - Cmnd->SCp.Message = pLoggedInPort->ScsiNexus.InqDeviceType; - - // handle LUN masking; if not "default" (illegal) lun value, - // the use it. These lun values are set by a successful - // Report Luns command - if( pLoggedInPort->ScsiNexus.LunMasking == 1) - { - if (Cmnd->device->lun > sizeof(pLoggedInPort->ScsiNexus.lun)) - return NULL; - // we KNOW all the valid LUNs... 0xFF is invalid! - Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun]; - if (pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun] == 0xFF) - return NULL; - // printk("xlating lun %d to 0x%02x\n", Cmnd->lun, - // pLoggedInPort->ScsiNexus.lun[Cmnd->lun]); - } - else - Cmnd->SCp.have_data_in = Cmnd->device->lun; // Linux & target luns match - } - break; // found it! - } - } - - if( port_id_valid ) // look for alpa first - { - if( pLoggedInPort->port_id == port_id ) - break; // found it! - } - if( wwn_valid ) // look for wwn second - { - - if( !memcmp( &pLoggedInPort->u.ucWWN[0], &wwn[0], 8)) - { - // all 8 bytes of WWN match - break; // found it! - } - } - - pLoggedInPort = pLoggedInPort->pNextPort; // try next port - } - - return pLoggedInPort; -} - - - - -// -// We need to examine the SEST table and re-validate -// any open Exchanges for this LoggedInPort -// To make Tachyon pay attention, Freeze FCP assists, -// set VAL bits, Unfreeze FCP assists -static void RevalidateSEST( struct Scsi_Host *HostAdapter, - PFC_LOGGEDIN_PORT pLoggedInPort) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG x_ID; - BOOLEAN TachFroze = FALSE; - - - // re-validate any SEST exchanges that are permitted - // to survive the link down (e.g., good PDISC performed) - for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++) - { - - // If the SEST entry port_id matches the pLoggedInPort, - // we need to re-validate - if( (Exchanges->fcExchange[ x_ID].type == SCSI_IRE) - || - (Exchanges->fcExchange[ x_ID].type == SCSI_IWE)) - { - - if( (Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF) // (24-bit port ID) - == pLoggedInPort->port_id) - { -// printk(" re-val xID %Xh ", x_ID); - if( !TachFroze ) // freeze if not already frozen - TachFroze |= FreezeTach( cpqfcHBAdata); - fcChip->SEST->u[ x_ID].IWE.Hdr_Len |= 0x80000000; // set VAL bit - } - } - } - - if( TachFroze) - { - fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists - } -} - - -// Complete an Linux Cmnds that we Queued because -// our FC link was down (cause immediate retry) - -static void UnblockScsiDevice( struct Scsi_Host *HostAdapter, - PFC_LOGGEDIN_PORT pLoggedInPort) -{ - CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; - Scsi_Cmnd* *SCptr = &cpqfcHBAdata->LinkDnCmnd[0]; - Scsi_Cmnd *Cmnd; - int indx; - - - - // if the device was previously "blocked", make sure - // we unblock it so Linux SCSI will resume - - pLoggedInPort->device_blocked = FALSE; // clear our flag - - // check the Link Down command ptr buffer; - // we can complete now causing immediate retry - for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++, SCptr++) - { - if( *SCptr != NULL ) // scsi command to complete? - { -#ifdef DUMMYCMND_DBG - printk("complete Cmnd %p in LinkDnCmnd[%d]\n", *SCptr,indx); -#endif - Cmnd = *SCptr; - - - // Are there any Q'd commands for this target? - if( (Cmnd->device->id == pLoggedInPort->ScsiNexus.target) - && - (Cmnd->device->channel == pLoggedInPort->ScsiNexus.channel) ) - { - Cmnd->result = (DID_SOFT_ERROR <<16); // force retry - if( Cmnd->scsi_done == NULL) - { - printk("LinkDnCmnd scsi_done ptr null, port_id %Xh\n", - pLoggedInPort->port_id); - } - else - call_scsi_done(Cmnd); - *SCptr = NULL; // free this slot for next use - } - } - } -} - - -//#define WWN_DBG 1 - -static void SetLoginFields( - PFC_LOGGEDIN_PORT pLoggedInPort, - TachFCHDR_GCMND* fchs, - BOOLEAN PDisc, - BOOLEAN Originator) -{ - LOGIN_PAYLOAD logi; // FC-PH Port Login - PRLI_REQUEST prli; // copy for BIG ENDIAN switch - int i; -#ifdef WWN_DBG - ULONG ulBuff; -#endif - - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi)); - - pLoggedInPort->Originator = Originator; - pLoggedInPort->port_id = fchs->s_id & 0xFFFFFF; - - switch( fchs->pl[0] & 0xffff ) - { - case 0x00000002: // PLOGI or PDISC ACCept? - if( PDisc ) // PDISC accept - goto PDISC_case; - - case 0x00000003: // ELS_PLOGI or ELS_PLOGI_ACC - - // Login BB_credit typically 0 for Tachyons - pLoggedInPort->BB_credit = logi.cmn_services.bb_credit; - - // e.g. 128, 256, 1024, 2048 per FC-PH spec - // We have to use this when setting up SEST Writes, - // since that determines frame size we send. - pLoggedInPort->rx_data_size = logi.class3.rx_data_size; - pLoggedInPort->plogi = TRUE; - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; // ELS_PLOGI resets - pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets - pLoggedInPort->logo = FALSE; // ELS_PLOGI resets - pLoggedInPort->LOGO_counter = 0;// ELS_PLOGI resets - pLoggedInPort->LOGO_timer = 0;// ELS_PLOGI resets - - // was this PLOGI to a Fabric? - if( pLoggedInPort->port_id == 0xFFFFFC ) // well know address - pLoggedInPort->flogi = TRUE; - - - for( i=0; i<8; i++) // copy the LOGIN port's WWN - pLoggedInPort->u.ucWWN[i] = logi.port_name[i]; - -#ifdef WWN_DBG - ulBuff = (ULONG)pLoggedInPort->u.liWWN; - if( pLoggedInPort->Originator) - printk("o"); - else - printk("r"); - printk("PLOGI port_id %Xh, WWN %08X", - pLoggedInPort->port_id, ulBuff); - - ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32); - printk("%08Xh fcPort %p\n", ulBuff, pLoggedInPort); -#endif - break; - - - - - case 0x00000005: // ELS_LOGO (logout) - - - pLoggedInPort->plogi = FALSE; - pLoggedInPort->pdisc = FALSE; - pLoggedInPort->prli = FALSE; // ELS_PLOGI resets - pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets - pLoggedInPort->logo = TRUE; // ELS_PLOGI resets - pLoggedInPort->LOGO_counter++; // ELS_PLOGI resets - pLoggedInPort->LOGO_timer = 0; -#ifdef WWN_DBG - ulBuff = (ULONG)pLoggedInPort->u.liWWN; - if( pLoggedInPort->Originator) - printk("o"); - else - printk("r"); - printk("LOGO port_id %Xh, WWN %08X", - pLoggedInPort->port_id, ulBuff); - - ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32); - printk("%08Xh\n", ulBuff); -#endif - break; - - - -PDISC_case: - case 0x00000050: // ELS_PDISC or ELS_PDISC_ACC - pLoggedInPort->LOGO_timer = 0; // stop the time-out - - pLoggedInPort->prli = TRUE; // ready to accept FCP-SCSI I/O - - - -#ifdef WWN_DBG - ulBuff = (ULONG)pLoggedInPort->u.liWWN; - if( pLoggedInPort->Originator) - printk("o"); - else - printk("r"); - printk("PDISC port_id %Xh, WWN %08X", - pLoggedInPort->port_id, ulBuff); - - ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32); - printk("%08Xh\n", ulBuff); -#endif - - - - break; - - - - case 0x1020L: // PRLI? - case 0x1002L: // PRLI ACCept? - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli)); - - pLoggedInPort->fcp_info = prli.fcp_info; // target/initiator flags - pLoggedInPort->prli = TRUE; // PLOGI resets, PDISC doesn't - - pLoggedInPort->pdisc = TRUE; // expect to send (or receive) PDISC - // next time - pLoggedInPort->LOGO_timer = 0; // will be set next LinkDown -#ifdef WWN_DBG - ulBuff = (ULONG)pLoggedInPort->u.liWWN; - if( pLoggedInPort->Originator) - printk("o"); - else - printk("r"); - printk("PRLI port_id %Xh, WWN %08X", - pLoggedInPort->port_id, ulBuff); - - ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32); - printk("%08Xh\n", ulBuff); -#endif - - break; - - } - - return; -} - - - - - - -static void BuildLinkServicePayload( PTACHYON fcChip, ULONG type, void* payload) -{ - LOGIN_PAYLOAD *plogi; // FC-PH Port Login - LOGIN_PAYLOAD PlogiPayload; // copy for BIG ENDIAN switch - PRLI_REQUEST *prli; // FCP-SCSI Process Login - PRLI_REQUEST PrliPayload; // copy for BIG ENDIAN switch - LOGOUT_PAYLOAD *logo; - LOGOUT_PAYLOAD LogoutPayload; -// PRLO_REQUEST *prlo; -// PRLO_REQUEST PrloPayload; - REJECT_MESSAGE rjt, *prjt; - - memset( &PlogiPayload, 0, sizeof( PlogiPayload)); - plogi = &PlogiPayload; // load into stack buffer, - // then BIG-ENDIAN switch a copy to caller - - - switch( type ) // payload type can be ELS_PLOGI, ELS_PRLI, ADISC, ... - { - case ELS_FDISC: - case ELS_FLOGI: - case ELS_PLOGI_ACC: // FC-PH PORT Login Accept - case ELS_PLOGI: // FC-PH PORT Login - case ELS_PDISC: // FC-PH2 Port Discovery - same payload as ELS_PLOGI - plogi->login_cmd = LS_PLOGI; - if( type == ELS_PDISC) - plogi->login_cmd = LS_PDISC; - else if( type == ELS_PLOGI_ACC ) - plogi->login_cmd = LS_ACC; - - plogi->cmn_services.bb_credit = 0x00; - plogi->cmn_services.lowest_ver = fcChip->lowest_FCPH_ver; - plogi->cmn_services.highest_ver = fcChip->highest_FCPH_ver; - plogi->cmn_services.bb_rx_size = TACHLITE_TS_RX_SIZE; - plogi->cmn_services.common_features = CONTINUOSLY_INCREASING | - RANDOM_RELATIVE_OFFSET; - - // fill in with World Wide Name based Port Name - 8 UCHARs - // get from Tach registers WWN hi & lo - LoadWWN( fcChip, plogi->port_name, 0); - // fill in with World Wide Name based Node/Fabric Name - 8 UCHARs - // get from Tach registers WWN hi & lo - LoadWWN( fcChip, plogi->node_name, 1); - - // For Seagate Drives. - // - plogi->cmn_services.common_features |= 0x800; - plogi->cmn_services.rel_offset = 0xFE; - plogi->cmn_services.concurrent_seq = 1; - plogi->class1.service_options = 0x00; - plogi->class2.service_options = 0x00; - plogi->class3.service_options = CLASS_VALID; - plogi->class3.initiator_control = 0x00; - plogi->class3.rx_data_size = MAX_RX_PAYLOAD; - plogi->class3.recipient_control = - ERROR_DISCARD | ONE_CATEGORY_SEQUENCE; - plogi->class3.concurrent_sequences = 1; - plogi->class3.open_sequences = 1; - plogi->vendor_id[0] = 'C'; plogi->vendor_id[1] = 'Q'; - plogi->vendor_version[0] = 'C'; plogi->vendor_version[1] = 'Q'; - plogi->vendor_version[2] = ' '; plogi->vendor_version[3] = '0'; - plogi->vendor_version[4] = '0'; plogi->vendor_version[5] = '0'; - - - // FLOGI specific fields... (see FC-FLA, Rev 2.7, Aug 1999, sec 5.1) - if( (type == ELS_FLOGI) || (type == ELS_FDISC) ) - { - if( type == ELS_FLOGI ) - plogi->login_cmd = LS_FLOGI; - else - plogi->login_cmd = LS_FDISC; - - plogi->cmn_services.lowest_ver = 0x20; - plogi->cmn_services.common_features = 0x0800; - plogi->cmn_services.rel_offset = 0; - plogi->cmn_services.concurrent_seq = 0; - - plogi->class3.service_options = 0x8800; - plogi->class3.rx_data_size = 0; - plogi->class3.recipient_control = 0; - plogi->class3.concurrent_sequences = 0; - plogi->class3.open_sequences = 0; - } - - // copy back to caller's buff, w/ BIG ENDIAN swap - BigEndianSwap( (UCHAR*)&PlogiPayload, payload, sizeof(PlogiPayload)); - break; - - - case ELS_ACC: // generic Extended Link Service ACCept - plogi->login_cmd = LS_ACC; - // copy back to caller's buff, w/ BIG ENDIAN swap - BigEndianSwap( (UCHAR*)&PlogiPayload, payload, 4); - break; - - - - case ELS_SCR: // Fabric State Change Registration - { - SCR_PL scr; // state change registration - - memset( &scr, 0, sizeof(scr)); - - scr.command = LS_SCR; // 0x62000000 - // see FC-FLA, Rev 2.7, Table A.22 (pg 82) - scr.function = 3; // 1 = Events detected by Fabric - // 2 = N_Port detected registration - // 3 = Full registration - - // copy back to caller's buff, w/ BIG ENDIAN swap - BigEndianSwap( (UCHAR*)&scr, payload, sizeof(SCR_PL)); - } - - break; - - - case FCS_NSR: // Fabric Name Service Request - { - NSR_PL nsr; // Name Server Req. payload - - memset( &nsr, 0, sizeof(NSR_PL)); - - // see Brocade Fabric Programming Guide, - // Rev 1.3, pg 4-44 - nsr.CT_Rev = 0x01000000; - nsr.FCS_Type = 0xFC020000; - nsr.Command_code = 0x01710000; - nsr.FCP = 8; - - // copy back to caller's buff, w/ BIG ENDIAN swap - BigEndianSwap( (UCHAR*)&nsr, payload, sizeof(NSR_PL)); - } - - break; - - - - - case ELS_LOGO: // FC-PH PORT LogOut - logo = &LogoutPayload; // load into stack buffer, - // then BIG-ENDIAN switch a copy to caller - logo->cmd = LS_LOGO; - // load the 3 UCHARs of the node name - // (if private loop, upper two UCHARs 0) - logo->reserved = 0; - - logo->n_port_identifier[0] = (UCHAR)(fcChip->Registers.my_al_pa); - logo->n_port_identifier[1] = - (UCHAR)(fcChip->Registers.my_al_pa>>8); - logo->n_port_identifier[2] = - (UCHAR)(fcChip->Registers.my_al_pa>>16); - // fill in with World Wide Name based Port Name - 8 UCHARs - // get from Tach registers WWN hi & lo - LoadWWN( fcChip, logo->port_name, 0); - - BigEndianSwap( (UCHAR*)&LogoutPayload, - payload, sizeof(LogoutPayload) ); // 16 UCHAR struct - break; - - - case ELS_LOGO_ACC: // Logout Accept (FH-PH pg 149, table 74) - logo = &LogoutPayload; // load into stack buffer, - // then BIG-ENDIAN switch a copy to caller - logo->cmd = LS_ACC; - BigEndianSwap( (UCHAR*)&LogoutPayload, payload, 4 ); // 4 UCHAR cmnd - break; - - - case ELS_RJT: // ELS_RJT link service reject (FH-PH pg 155) - - prjt = (REJECT_MESSAGE*)payload; // pick up passed data - rjt.command_code = ELS_RJT; - // reverse fields, because of Swap that follows... - rjt.vendor = prjt->reserved; // vendor specific - rjt.explain = prjt->reason; // - rjt.reason = prjt->explain; // - rjt.reserved = prjt->vendor; // - // BIG-ENDIAN switch a copy to caller - BigEndianSwap( (UCHAR*)&rjt, payload, 8 ); // 8 UCHAR cmnd - break; - - - - - - case ELS_PRLI_ACC: // Process Login ACCept - case ELS_PRLI: // Process Login - case ELS_PRLO: // Process Logout - memset( &PrliPayload, 0, sizeof( PrliPayload)); - prli = &PrliPayload; // load into stack buffer, - - if( type == ELS_PRLI ) - prli->cmd = 0x20; // Login - else if( type == ELS_PRLO ) - prli->cmd = 0x21; // Logout - else if( type == ELS_PRLI_ACC ) - { - prli->cmd = 0x02; // Login ACCept - prli->valid = REQUEST_EXECUTED; - } - - - prli->valid |= SCSI_FCP | ESTABLISH_PAIR; - prli->fcp_info = READ_XFER_RDY; - prli->page_length = 0x10; - prli->payload_length = 20; - // Can be initiator AND target - - if( fcChip->Options.initiator ) - prli->fcp_info |= INITIATOR_FUNCTION; - if( fcChip->Options.target ) - prli->fcp_info |= TARGET_FUNCTION; - - BigEndianSwap( (UCHAR*)&PrliPayload, payload, prli->payload_length); - break; - - - - default: // no can do - programming error - printk(" BuildLinkServicePayload unknown!\n"); - break; - } -} - -// loads 8 UCHARs for PORT name or NODE name base on -// controller's WWN. -void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type) -{ - UCHAR* bPtr, i; - - switch( type ) - { - case 0: // Port_Name - bPtr = (UCHAR*)&fcChip->Registers.wwn_hi; - for( i =0; i<4; i++) - dest[i] = *bPtr++; - bPtr = (UCHAR*)&fcChip->Registers.wwn_lo; - for( i =4; i<8; i++) - dest[i] = *bPtr++; - break; - case 1: // Node/Fabric _Name - bPtr = (UCHAR*)&fcChip->Registers.wwn_hi; - for( i =0; i<4; i++) - dest[i] = *bPtr++; - bPtr = (UCHAR*)&fcChip->Registers.wwn_lo; - for( i =4; i<8; i++) - dest[i] = *bPtr++; - break; - } - -} - - - -// We check the Port Login payload for required values. Note that -// ELS_PLOGI and ELS_PDISC (Port DISCover) use the same payload. - - -int verify_PLOGI( PTACHYON fcChip, - TachFCHDR_GCMND* fchs, - ULONG* reject_explain) -{ - LOGIN_PAYLOAD login; - - // source, dest, len (should be mult. of 4) - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&login, sizeof(login)); - - // check FC version - // if other port's highest supported version - // is less than our lowest, and - // if other port's lowest - if( login.cmn_services.highest_ver < fcChip->lowest_FCPH_ver || - login.cmn_services.lowest_ver > fcChip->highest_FCPH_ver ) - { - *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR); - return LOGICAL_ERROR; - } - - // Receive Data Field Size must be >=128 - // per FC-PH - if (login.cmn_services.bb_rx_size < 128) - { - *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, DATA_FIELD_SIZE_ERROR); - return LOGICAL_ERROR; - } - - // Only check Class 3 params - if( login.class3.service_options & CLASS_VALID) - { - if (login.class3.rx_data_size < 128) - { - *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INVALID_CSP); - return LOGICAL_ERROR; - } - if( login.class3.initiator_control & XID_REQUIRED) - { - *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INITIATOR_CTL_ERROR); - return LOGICAL_ERROR; - } - } - return 0; // success -} - - - - -int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain) -{ - PRLI_REQUEST prli; // buffer for BIG ENDIAN - - // source, dest, len (should be mult. of 4) - BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli)); - - if( prli.fcp_info == 0 ) // i.e., not target or initiator? - { - *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR); - return LOGICAL_ERROR; - } - - return 0; // success -} - - -// SWAP UCHARs as required by Fibre Channel (i.e. BIG ENDIAN) -// INPUTS: -// source - ptr to LITTLE ENDIAN ULONGS -// cnt - number of UCHARs to switch (should be mult. of ULONG) -// OUTPUTS: -// dest - ptr to BIG ENDIAN copy -// RETURN: -// none -// -void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt) -{ - int i,j; - - source+=3; // start at MSB of 1st ULONG - for( j=0; j < cnt; j+=4, source+=4, dest+=4) // every ULONG - { - for( i=0; i<4; i++) // every UCHAR in ULONG - *(dest+i) = *(source-i); - } -} - - - - -// Build FC Exchanges............ - -static void buildFCPstatus( - PTACHYON fcChip, - ULONG ExchangeID); - -static LONG FindFreeExchange( PTACHYON fcChip, ULONG type ); - -static ULONG build_SEST_sgList( - struct pci_dev *pcidev, - ULONG *SESTalPairStart, - Scsi_Cmnd *Cmnd, - ULONG *sgPairs, - PSGPAGES *sgPages_head // link list of TL Ext. S/G pages from O/S Pool -); - -static int build_FCP_payload( Scsi_Cmnd *Cmnd, - UCHAR* payload, ULONG type, ULONG fcp_dl ); - - -/* - IRB - ERQ __________________ - | | / | Req_A_SFS_Len | ____________________ - |----------| / | Req_A_SFS_Addr |------->| Reserved | - | IRB | / | Req_A_D_ID | | SOF EOF TimeStamp | - |-----------/ | Req_A_SEST_Index |-+ | R_CTL | D_ID | - | IRB | | Req_B... | | | CS_CTL| S_ID | - |-----------\ | | | | TYPE | F_CTL | - | IRB | \ | | | | SEQ_ID | SEQ_CNT | - |----------- \ | | +-->+--| OX_ID | RX_ID | - | | \ |__________________| | | RO | - | | pl (payload/cmnd) | - | | ..... | - | |___________________| - | - | -+-------------------------------------------+ -| -| -| e.g. IWE -| SEST __________________ for FCP_DATA -| | | / | | Hdr_Len | ____________________ -| |----------| / | Hdr_Addr_Addr |------->| Reserved | -| | [0] | / |Remote_ID| RSP_Len| | SOF EOF TimeStamp | -| |-----------/ | RSP_Addr |---+ | R_CTL | D_ID | -+-> [1] | | | Buff_Off | | | CS_CTL| S_ID | - |-----------\ |BuffIndex| Link | | | TYPE | F_CTL | - | [2] | \ | Rsvd | RX_ID | | | SEQ_ID | SEQ_CNT | - |----------- \ | Data_Len | | | OX_ID | RX_ID | - | ... | \ | Exp_RO | | | RO | - |----------| | Exp_Byte_Cnt | | |___________________| - | SEST_LEN | +--| Len | | - |__________| | | Address | | - | | ... | | for FCP_RSP - | |__________________| | ____________________ - | +----| Reserved | - | | SOF EOF TimeStamp | - | | R_CTL | D_ID | - | | CS_CTL| S_ID | - +--- local or extended | .... | - scatter/gather lists - defining upper-layer - data (e.g. from user's App) - - -*/ -// All TachLite commands must start with a SFS (Single Frame Sequence) -// command. In the simplest case (a NOP Basic Link command), -// only one frame header and ERQ entry is required. The most complex -// case is the SCSI assisted command, which requires an ERQ entry, -// SEST entry, and several frame headers and data buffers all -// logically linked together. -// Inputs: -// cpqfcHBAdata - controller struct -// type - PLOGI, SCSI_IWE, etc. -// InFCHS - Incoming Tachlite FCHS which prompted this exchange -// (only s_id set if we are originating) -// Data - PVOID to data struct consistent with "type" -// fcExchangeIndex - pointer to OX/RD ID value of built exchange -// Return: -// fcExchangeIndex - OX/RD ID value if successful -// 0 - success -// INVALID_ARGS - NULL/ invalid passed args -// BAD_ALPA - Bad source al_pa address -// LNKDWN_OSLS - Link Down (according to this controller) -// OUTQUE_FULL - Outbound Que full -// DRIVERQ_FULL - controller's Exchange array full -// SEST_FULL - SEST table full -// -// Remarks: -// Psuedo code: -// Check for NULL pointers / bad args -// Build outgoing FCHS - the header/payload struct -// Build IRB (for ERQ entry) -// if SCSI command, build SEST entry (e.g. IWE, TRE,...) -// return success - -//sbuildex -ULONG cpqfcTSBuildExchange( - CPQFCHBA *cpqfcHBAdata, - ULONG type, // e.g. PLOGI - TachFCHDR_GCMND* InFCHS, // incoming FCHS - void *Data, // the CDB, scatter/gather, etc. - LONG *fcExchangeIndex ) // points to allocated exchange, -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG ulStatus = 0; // assume OK - USHORT ox_ID, rx_ID=0xFFFF; - ULONG SfsLen=0L; - TachLiteIRB* pIRB; - IRBflags IRB_flags; - UCHAR *pIRB_flags = (UCHAR*)&IRB_flags; - TachFCHDR_GCMND* CMDfchs; - TachFCHDR* dataHDR; // 32 byte HEADER ONLY FCP-DATA buffer - TachFCHDR_RSP* rspHDR; // 32 byte header + RSP payload - Scsi_Cmnd *Cmnd = (Scsi_Cmnd*)Data; // Linux Scsi CDB, S/G, ... - TachLiteIWE* pIWE; - TachLiteIRE* pIRE; - TachLiteTWE* pTWE; - TachLiteTRE* pTRE; - ULONG fcp_dl; // total byte length of DATA transferred - ULONG fl; // frame length (FC frame size, 128, 256, 512, 1024) - ULONG sgPairs; // number of valid scatter/gather pairs - int FCP_SCSI_command; - BA_ACC_PAYLOAD *ba_acc; - BA_RJT_PAYLOAD *ba_rjt; - - // check passed ARGS - if( !fcChip->ERQ ) // NULL ptr means uninitialized Tachlite chip - return INVALID_ARGS; - - - if( type == SCSI_IRE || - type == SCSI_TRE || - type == SCSI_IWE || - type == SCSI_TWE) - FCP_SCSI_command = 1; - - else - FCP_SCSI_command = 0; - - - // for commands that pass payload data (e.g. SCSI write) - // examine command struct - verify that the - // length of s/g buffers is adequate for total payload - // length (end of list is NULL address) - - if( FCP_SCSI_command ) - { - if( Data ) // must have data descriptor (S/G list -- at least - // one address with at least 1 byte of data) - { - // something to do (later)? - } - - else - return INVALID_ARGS; // invalid DATA ptr - } - - - - // we can build an Exchange for later Queuing (on the TL chip) - // if an empty slot is available in the DevExt for this controller - // look for available Exchange slot... - - if( type != FCP_RESPONSE && - type != BLS_ABTS && - type != BLS_ABTS_ACC ) // already have Exchange slot! - *fcExchangeIndex = FindFreeExchange( fcChip, type ); - - if( *fcExchangeIndex != -1 ) // Exchange is available? - { - // assign tmp ptr (shorthand) - CMDfchs = &Exchanges->fcExchange[ *fcExchangeIndex].fchs; - - if( Cmnd != NULL ) // (necessary for ABTS cases) - { - Exchanges->fcExchange[ *fcExchangeIndex].Cmnd = Cmnd; // Linux Scsi - Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort = - fcFindLoggedInPort( fcChip, - Exchanges->fcExchange[ *fcExchangeIndex].Cmnd, // find Scsi Nexus - 0, // DON'T search linked list for FC port id - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - } - - - // Build the command frame header (& data) according - // to command type - - // fields common for all SFS frame types - CMDfchs->reserved = 0L; // must clear - CMDfchs->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; LCr=0, no TS - - // get the destination port_id from incoming FCHS - // (initialized before calling if we're Originator) - // Frame goes to port it was from - the source_id - - CMDfchs->d_id = InFCHS->s_id &0xFFFFFF; // destination (add R_CTL later) - CMDfchs->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0 - - - // now enter command-specific fields - switch( type ) - { - - case BLS_NOP: // FC defined basic link service command NO-OP - // ensure unique X_IDs! (use tracking function) - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 32L; // add len to LSB (header only - no payload) - - // TYPE[31-24] 00 Basic Link Service - // f_ctl[23:0] exchg originator, 1st seq, xfer S.I. - CMDfchs->d_id |= 0x80000000L; // R_CTL = 80 for NOP (Basic Link Ser.) - CMDfchs->f_ctl = 0x00310000L; // xchng originator, 1st seq,.... - CMDfchs->seq_cnt = 0x0L; - CMDfchs->ox_rx_id = 0xFFFF; // RX_ID for now; OX_ID on start - CMDfchs->ro = 0x0L; // relative offset (n/a) - CMDfchs->pl[0] = 0xaabbccddL; // words 8-15 frame data payload (n/a) - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // seconds - // (NOP should complete ~instantly) - break; - - - - - case BLS_ABTS_ACC: // Abort Sequence ACCept - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload) - - CMDfchs->d_id |= 0x84000000L; // R_CTL = 84 for BASIC ACCept - // TYPE[31-24] 00 Basic Link Service - // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I. - CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI - // CMDfchs->seq_id & count might be set from DataHdr? - CMDfchs->ro = 0x0L; // relative offset (n/a) - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds - // (Timeout in case of weird error) - - // now set the ACCept payload... - ba_acc = (BA_ACC_PAYLOAD*)&CMDfchs->pl[0]; - memset( ba_acc, 0, sizeof( BA_ACC_PAYLOAD)); - // Since PLDA requires (only) entire Exchange aborts, we don't need - // to worry about what the last sequence was. - - // We expect that a "target" task is accepting the abort, so we - // can use the OX/RX ID pair - ba_acc->ox_rx_id = CMDfchs->ox_rx_id; - - // source, dest, #bytes - BigEndianSwap((UCHAR *)&CMDfchs->ox_rx_id, (UCHAR *)&ba_acc->ox_rx_id, 4); - - ba_acc->low_seq_cnt = 0; - ba_acc->high_seq_cnt = 0xFFFF; - - - break; - - - case BLS_ABTS_RJT: // Abort Sequence ACCept - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload) - - CMDfchs->d_id |= 0x85000000L; // R_CTL = 85 for BASIC ReJecT - // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I. - // TYPE[31-24] 00 Basic Link Service - CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI - // CMDfchs->seq_id & count might be set from DataHdr? - CMDfchs->ro = 0x0L; // relative offset (n/a) - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds - // (Timeout in case of weird error) - - CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // copy from sender! - - // now set the ReJecT payload... - ba_rjt = (BA_RJT_PAYLOAD*)&CMDfchs->pl[0]; - memset( ba_rjt, 0, sizeof( BA_RJT_PAYLOAD)); - - // We expect that a "target" task couldn't find the Exhange in the - // array of active exchanges, so we use a new LinkService X_ID. - // See Reject payload description in FC-PH (Rev 4.3), pg. 140 - ba_rjt->reason_code = 0x09; // "unable to perform command request" - ba_rjt->reason_explain = 0x03; // invalid OX/RX ID pair - - - break; - - - case BLS_ABTS: // FC defined basic link service command ABTS - // Abort Sequence - - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 32L; // add len to LSB (header only - no payload) - - // TYPE[31-24] 00 Basic Link Service - // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I. - CMDfchs->d_id |= 0x81000000L; // R_CTL = 81 for ABTS - CMDfchs->f_ctl = 0x00110000L; // xchnge originator, last seq, xfer SI - // CMDfchs->seq_id & count might be set from DataHdr? - CMDfchs->ro = 0x0L; // relative offset (n/a) - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds - // (ABTS must timeout when responder is gone) - break; - - - - case FCS_NSR: // Fabric Name Service Request - Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2; - - - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds - // OX_ID, linked to Driver Transaction ID - // (fix-up at Queing time) - CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify - // OX_ID set at ERQueing time - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += (32L + sizeof(NSR_PL)); // add len (header & NSR payload) - - CMDfchs->d_id |= 0x02000000L; // R_CTL = 02 for - - // Name Service Request: Unsolicited - // TYPE[31-24] 01 Extended Link Service - // f_ctl[23:0] exchg originator, 1st seq, xfer S.I. - CMDfchs->f_ctl = 0x20210000L; - // OX_ID will be fixed-up at Tachyon enqueing time - CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt - CMDfchs->ro = 0x0L; // relative offset (n/a) - - BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]); - - - - - - - break; - - - - - case ELS_PLOGI: // FC-PH extended link service command Port Login - // (May, 2000) - // NOTE! This special case facilitates SANMark testing. The SANMark - // test script for initialization-timeout.fcal.SANMark-1.fc - // "eats" the OPN() primitive without issuing an R_RDY, causing - // Tachyon to report LST (loop state timeout), which causes a - // LIP. To avoid this, simply send out the frame (i.e. assuming a - // buffer credit of 1) without waiting for R_RDY. Many FC devices - // (other than Tachyon) have been doing this for years. We don't - // ever want to do this for non-Link Service frames unless the - // other device really did report non-zero login BB credit (i.e. - // in the PLOGI ACCept frame). -// CMDfchs->sof_eof |= 0x00000400L; // LCr=1 - - case ELS_FDISC: // Fabric Discovery (Login) - case ELS_FLOGI: // Fabric Login - case ELS_SCR: // Fabric State Change Registration - case ELS_LOGO: // FC-PH extended link service command Port Logout - case ELS_PDISC: // FC-PH extended link service cmnd Port Discovery - case ELS_PRLI: // FC-PH extended link service cmnd Process Login - - Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2; - - - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds - // OX_ID, linked to Driver Transaction ID - // (fix-up at Queing time) - CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify - // OX_ID set at ERQueing time - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - if( type == ELS_LOGO ) - SfsLen += (32L + 16L); // add len (header & PLOGI payload) - else if( type == ELS_PRLI ) - SfsLen += (32L + 20L); // add len (header & PRLI payload) - else if( type == ELS_SCR ) - SfsLen += (32L + sizeof(SCR_PL)); // add len (header & SCR payload) - else - SfsLen += (32L + 116L); // add len (header & PLOGI payload) - - CMDfchs->d_id |= 0x22000000L; // R_CTL = 22 for - - // Extended Link_Data: Unsolicited Control - // TYPE[31-24] 01 Extended Link Service - // f_ctl[23:0] exchg originator, 1st seq, xfer S.I. - CMDfchs->f_ctl = 0x01210000L; - // OX_ID will be fixed-up at Tachyon enqueing time - CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt - CMDfchs->ro = 0x0L; // relative offset (n/a) - - BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]); - - break; - - - - case ELS_LOGO_ACC: // FC-PH extended link service logout accept - case ELS_RJT: // extended link service reject (add reason) - case ELS_ACC: // ext. link service generic accept - case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC) - case ELS_PRLI_ACC: // ext. link service process login accept - - - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // assume done - // ensure unique X_IDs! (use tracking function) - // OX_ID from initiator cmd - ox_ID = (USHORT)(InFCHS->ox_rx_id >> 16); - rx_ID = 0xFFFF; // RX_ID, linked to Driver Exchange ID - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (not SEST index) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - if( type == ELS_RJT ) - { - SfsLen += (32L + 8L); // add len (header + payload) - - // ELS_RJT reason codes (utilize unused "reserved" field) - CMDfchs->pl[0] = 1; - CMDfchs->pl[1] = InFCHS->reserved; - - } - else if( (type == ELS_LOGO_ACC) || (type == ELS_ACC) ) - SfsLen += (32L + 4L); // add len (header + payload) - else if( type == ELS_PLOGI_ACC ) - SfsLen += (32L + 116L); // add len (header + payload) - else if( type == ELS_PRLI_ACC ) - SfsLen += (32L + 20L); // add len (header + payload) - - CMDfchs->d_id |= 0x23000000L; // R_CTL = 23 for - - // Extended Link_Data: Control Reply - // TYPE[31-24] 01 Extended Link Service - // f_ctl[23:0] exchg responder, last seq, e_s, tsi - CMDfchs->f_ctl = 0x01990000L; - CMDfchs->seq_cnt = 0x0L; - CMDfchs->ox_rx_id = 0L; // clear - CMDfchs->ox_rx_id = ox_ID; // load upper 16 bits - CMDfchs->ox_rx_id <<= 16; // shift them - - CMDfchs->ro = 0x0L; // relative offset (n/a) - - BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]); - - break; - - - // Fibre Channel SCSI 'originator' sequences... - // (originator means 'initiator' in FCP-SCSI) - - case SCSI_IWE: // TachLite Initiator Write Entry - { - PFC_LOGGEDIN_PORT pLoggedInPort = - Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort; - - Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1; - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // FC2 timeout - - // first, build FCP_CMND - // unique X_ID fix-ups in StartExchange - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index) - - // NOTE: unlike FC LinkService login frames, normal - // SCSI commands are sent without outgoing verification - IRB_flags.DCM = 1; // Disable completion message for Cmnd frame - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 64L; // add len to LSB (header & CMND payload) - - CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command - - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] exchg originator, 1st seq, xfer S.I. - // valid RO - CMDfchs->f_ctl = 0x08210008L; - CMDfchs->seq_cnt = 0x0L; - CMDfchs->ox_rx_id = 0L; // clear for now (-or- in later) - CMDfchs->ro = 0x0L; // relative offset (n/a) - - // now, fill out FCP-DATA header - // (use buffer inside SEST object) - dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ]; - dataHDR->reserved = 0L; // must clear - dataHDR->sof_eof = 0x75002000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS - dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA - dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0 - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] xfer S.I.| valid RO - dataHDR->f_ctl = 0x08010008L; - dataHDR->seq_cnt = 0x02000000L; // sequence ID: df_ctl : seqence count - dataHDR->ox_rx_id = 0L; // clear; fix-up dataHDR fields later - dataHDR->ro = 0x0L; // relative offset (n/a) - - // Now setup the SEST entry - pIWE = &fcChip->SEST->u[ *fcExchangeIndex ].IWE; - - // fill out the IWE: - - // VALid entry:Dir outbound:DCM:enable CM:enal INT: FC frame len - pIWE->Hdr_Len = 0x8e000020L; // data frame Len always 32 bytes - - - // from login parameters with other port, what's the largest frame - // we can send? - if( pLoggedInPort == NULL) - { - ulStatus = INVALID_ARGS; // failed! give up - break; - } - if( pLoggedInPort->rx_data_size >= 2048) - fl = 0x00020000; // 2048 code (only support 1024!) - else if( pLoggedInPort->rx_data_size >= 1024) - fl = 0x00020000; // 1024 code - else if( pLoggedInPort->rx_data_size >= 512) - fl = 0x00010000; // 512 code - else - fl = 0; // 128 bytes -- should never happen - - - pIWE->Hdr_Len |= fl; // add xmit FC frame len for data phase - pIWE->Hdr_Addr = fcChip->SEST->base + - ((unsigned long)&fcChip->SEST->DataHDR[*fcExchangeIndex] - - (unsigned long)fcChip->SEST); - - pIWE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame) - pIWE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID - - memset( &fcChip->SEST->RspHDR[ *fcExchangeIndex].pl, 0, - sizeof( FCP_STATUS_RESPONSE) ); // clear out previous status - - pIWE->RSP_Addr = fcChip->SEST->base + - ((unsigned long)&fcChip->SEST->RspHDR[*fcExchangeIndex] - - (unsigned long)fcChip->SEST); - - // Do we need local or extended gather list? - // depends on size - we can handle 3 len/addr pairs - // locally. - - fcp_dl = build_SEST_sgList( - cpqfcHBAdata->PciDev, - &pIWE->GLen1, - Cmnd, // S/G list - &sgPairs, // return # of pairs in S/G list (from "Data" descriptor) - &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later) - - if( !fcp_dl ) // error building S/G list? - { - ulStatus = MEMPOOL_FAIL; - break; // give up - } - - // Now that we know total data length in - // the passed S/G buffer, set FCP CMND frame - build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl ); - - - - if( sgPairs > 3 ) // need extended s/g list - pIWE->Buff_Off = 0x78000000L; // extended data | (no offset) - else // local data pointers (in SEST) - pIWE->Buff_Off = 0xf8000000L; // local data | (no offset) - - // ULONG 5 - pIWE->Link = 0x0000ffffL; // Buff_Index | Link - - pIWE->RX_ID = 0x0L; // DWord 6: RX_ID set by target XFER_RDY - - // DWord 7 - pIWE->Data_Len = 0L; // TL enters rcv'd XFER_RDY BURST_LEN - pIWE->Exp_RO = 0L; // DWord 8 - // DWord 9 - pIWE->Exp_Byte_Cnt = fcp_dl; // sum of gather buffers - } - break; - - - - - - case SCSI_IRE: // TachLite Initiator Read Entry - - if( Cmnd->timeout != 0) - { -// printk("Cmnd->timeout %d\n", Cmnd->timeout); - // per Linux Scsi - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = Cmnd->timeout; - } - else // use our best guess, based on FC & device - { - - if( Cmnd->SCp.Message == 1 ) // Tape device? (from INQUIRY) - { - // turn off our timeouts (for now...) - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 0xFFFFFFFF; - } - else - { - Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1; - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // per SCSI req. - } - } - - - // first, build FCP_CMND - - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index) - // NOTE: unlike FC LinkService login frames, - // normal SCSI commands are sent "open loop" - IRB_flags.DCM = 1; // Disable completion message for Cmnd frame - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += 64L; // add len to LSB (header & CMND payload) - - CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command - - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] exchg originator, 1st seq, xfer S.I. - // valid RO - CMDfchs->f_ctl = 0x08210008L; - CMDfchs->seq_cnt = 0x0L; - // x_ID & data direction bit set later - CMDfchs->ox_rx_id = 0xFFFF; // clear - CMDfchs->ro = 0x0L; // relative offset (n/a) - - - - // Now setup the SEST entry - pIRE = &fcChip->SEST->u[ *fcExchangeIndex ].IRE; - - // fill out the IRE: - // VALid entry:Dir outbound:enable CM:enal INT: - pIRE->Seq_Accum = 0xCE000000L; // VAL,DIR inbound,DCM| INI,DAT,RSP - - pIRE->reserved = 0L; - pIRE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame) - pIRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID - - pIRE->RSP_Addr = fcChip->SEST->base + - ((unsigned long)&fcChip->SEST->RspHDR[*fcExchangeIndex] - - (unsigned long)fcChip->SEST); - - // Do we need local or extended gather list? - // depends on size - we can handle 3 len/addr pairs - // locally. - - fcp_dl = build_SEST_sgList( - cpqfcHBAdata->PciDev, - &pIRE->SLen1, - Cmnd, // SCSI command Data desc. with S/G list - &sgPairs, // return # of pairs in S/G list (from "Data" descriptor) - &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later) - - - if( !fcp_dl ) // error building S/G list? - { - // It is permissible to have a ZERO LENGTH Read command. - // If there is the case, simply set fcp_dl (and Exp_Byte_Cnt) - // to 0 and continue. - if( Cmnd->request_bufflen == 0 ) - { - fcp_dl = 0; // no FC DATA frames expected - - } - else - { - ulStatus = MEMPOOL_FAIL; - break; // give up - } - } - - // now that we know the S/G length, build CMND payload - build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl ); - - - if( sgPairs > 3 ) // need extended s/g list - pIRE->Buff_Off = 0x00000000; // DWord 4: extended s/g list, no offset - else - pIRE->Buff_Off = 0x80000000; // local data, no offset - - pIRE->Buff_Index = 0x0L; // DWord 5: Buff_Index | Reserved - - pIRE->Exp_RO = 0x0L; // DWord 6: Expected Rel. Offset - - pIRE->Byte_Count = 0; // DWord 7: filled in by TL on err - pIRE->reserved_ = 0; // DWord 8: reserved - // NOTE: 0 length READ is OK. - pIRE->Exp_Byte_Cnt = fcp_dl;// DWord 9: sum of scatter buffers - - break; - - - - - // Fibre Channel SCSI 'responder' sequences... - // (originator means 'target' in FCP-SCSI) - case SCSI_TWE: // TachLite Target Write Entry - - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req. - - // first, build FCP_CMND - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (XFER_RDY) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload) - - CMDfchs->d_id |= (0x05000000L); // R_CTL = 5 for XFER_RDY - - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] exchg responder, 1st seq, xfer S.I. - // valid RO - CMDfchs->f_ctl = 0x08810008L; - CMDfchs->seq_cnt = 0x01000000; // sequence ID: df_ctl: sequence count - // use originator (other port's) OX_ID - CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // we want upper 16 bits - CMDfchs->ro = 0x0L; // relative offset (n/a) - - // now, fill out FCP-RSP header - // (use buffer inside SEST object) - - rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ]; - rspHDR->reserved = 0L; // must clear - rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS - rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP - rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0 - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] responder|last seq| xfer S.I. - rspHDR->f_ctl = 0x08910000L; - rspHDR->seq_cnt = 0x03000000; // sequence ID - rspHDR->ox_rx_id = InFCHS->ox_rx_id; // gives us OX_ID - rspHDR->ro = 0x0L; // relative offset (n/a) - - - // Now setup the SEST entry - - pTWE = &fcChip->SEST->u[ *fcExchangeIndex ].TWE; - - // fill out the TWE: - - // VALid entry:Dir outbound:enable CM:enal INT: - pTWE->Seq_Accum = 0xC4000000L; // upper word flags - pTWE->reserved = 0L; - pTWE->Remote_Node_ID = 0L; // no more auto RSP frame! (TL/TS change) - pTWE->Remote_Node_ID |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID - - - // Do we need local or extended gather list? - // depends on size - we can handle 3 len/addr pairs - // locally. - - fcp_dl = build_SEST_sgList( - cpqfcHBAdata->PciDev, - &pTWE->SLen1, - Cmnd, // S/G list - &sgPairs, // return # of pairs in S/G list (from "Data" descriptor) - &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later) - - - if( !fcp_dl ) // error building S/G list? - { - ulStatus = MEMPOOL_FAIL; - break; // give up - } - - // now that we know the S/G length, build CMND payload - build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl ); - - - if( sgPairs > 3 ) // need extended s/g list - pTWE->Buff_Off = 0x00000000; // extended s/g list, no offset - else - pTWE->Buff_Off = 0x80000000; // local data, no offset - - pTWE->Buff_Index = 0; // Buff_Index | Link - pTWE->Exp_RO = 0; - pTWE->Byte_Count = 0; // filled in by TL on err - pTWE->reserved_ = 0; - pTWE->Exp_Byte_Cnt = fcp_dl;// sum of scatter buffers - - break; - - - - - - - case SCSI_TRE: // TachLite Target Read Entry - - // It doesn't make much sense for us to "time-out" a READ, - // but we'll use it for design consistency and internal error recovery. - Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req. - - // I/O request block settings... - *pIRB_flags = 0; // clear IRB flags - // check PRLI (process login) info - // to see if Initiator Requires XFER_RDY - // if not, don't send one! - // { PRLI check...} - IRB_flags.SFA = 0; // don't send XFER_RDY - start data - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload) - - - - // now, fill out FCP-DATA header - // (use buffer inside SEST object) - dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ]; - - dataHDR->reserved = 0L; // must clear - dataHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS,noLCr,no TS - dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA - dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0 - - - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] exchg responder, not 1st seq, xfer S.I. - // valid RO - dataHDR->f_ctl = 0x08810008L; - dataHDR->seq_cnt = 0x01000000; // sequence ID (no XRDY) - dataHDR->ox_rx_id = InFCHS->ox_rx_id & 0xFFFF0000; // we want upper 16 bits - dataHDR->ro = 0x0L; // relative offset (n/a) - - // now, fill out FCP-RSP header - // (use buffer inside SEST object) - rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ]; - - rspHDR->reserved = 0L; // must clear - rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS - rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP - rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0 - // TYPE[31-24] 8 for FCP SCSI - // f_ctl[23:0] responder|last seq| xfer S.I. - rspHDR->f_ctl = 0x08910000L; - rspHDR->seq_cnt = 0x02000000; // sequence ID: df_ctl: sequence count - - rspHDR->ro = 0x0L; // relative offset (n/a) - - - // Now setup the SEST entry - pTRE = &fcChip->SEST->u[ *fcExchangeIndex ].TRE; - - - // VALid entry:Dir outbound:enable CM:enal INT: - pTRE->Hdr_Len = 0x86010020L; // data frame Len always 32 bytes - pTRE->Hdr_Addr = // bus address of dataHDR; - fcChip->SEST->base + - ((unsigned long)&fcChip->SEST->DataHDR[ *fcExchangeIndex ] - - (unsigned long)fcChip->SEST); - - pTRE->RSP_Len = 64L; // hdr+data (TL assisted RSP frame) - pTRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID - pTRE->RSP_Addr = // bus address of rspHDR - fcChip->SEST->base + - ((unsigned long)&fcChip->SEST->RspHDR[ *fcExchangeIndex ] - - (unsigned long)fcChip->SEST); - - // Do we need local or extended gather list? - // depends on size - we can handle 3 len/addr pairs - // locally. - - fcp_dl = build_SEST_sgList( - cpqfcHBAdata->PciDev, - &pTRE->GLen1, - Cmnd, // S/G list - &sgPairs, // return # of pairs in S/G list (from "Data" descriptor) - &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later) - - - if( !fcp_dl ) // error building S/G list? - { - ulStatus = MEMPOOL_FAIL; - break; // give up - } - - // no payload or command to build -- READ doesn't need XRDY - - - if( sgPairs > 3 ) // need extended s/g list - pTRE->Buff_Off = 0x78000000L; // extended data | (no offset) - else // local data pointers (in SEST) - pTRE->Buff_Off = 0xf8000000L; // local data | (no offset) - - // ULONG 5 - pTRE->Buff_Index = 0L; // Buff_Index | reserved - pTRE->reserved = 0x0L; // DWord 6 - - // DWord 7: NOTE: zero length will - // hang TachLite! - pTRE->Data_Len = fcp_dl; // e.g. sum of scatter buffers - - pTRE->reserved_ = 0L; // DWord 8 - pTRE->reserved__ = 0L; // DWord 9 - - break; - - - - - - - - case FCP_RESPONSE: - // Target response frame: this sequence uses an OX/RX ID - // pair from a completed SEST exchange. We built most - // of the response frame when we created the TWE/TRE. - - *pIRB_flags = 0; // clear IRB flags - IRB_flags.SFA = 1; // send SFS (RSP) - SfsLen = *pIRB_flags; - - SfsLen <<= 24; // shift flags to MSB - SfsLen += sizeof(TachFCHDR_RSP);// add SFS len (header & RSP payload) - - - Exchanges->fcExchange[ *fcExchangeIndex].type = - FCP_RESPONSE; // change Exchange type to "response" phase - - // take advantage of prior knowledge of OX/RX_ID pair from - // previous XFER outbound frame (still in fchs of exchange) - fcChip->SEST->RspHDR[ *fcExchangeIndex ].ox_rx_id = - CMDfchs->ox_rx_id; - - // Check the status of the DATA phase of the exchange so we can report - // status to the initiator - buildFCPstatus( fcChip, *fcExchangeIndex); // set RSP payload fields - - memcpy( - CMDfchs, // re-use same XFER fchs for Response frame - &fcChip->SEST->RspHDR[ *fcExchangeIndex ], - sizeof( TachFCHDR_RSP )); - - - break; - - default: - printk("cpqfcTS: don't know how to build FC type: %Xh(%d)\n", type,type); - break; - - } - - - - if( !ulStatus) // no errors above? - { - // FCHS is built; now build IRB - - // link the just built FCHS (the "command") to the IRB entry - // for this Exchange. - pIRB = &Exchanges->fcExchange[ *fcExchangeIndex].IRB; - - // len & flags according to command type above - pIRB->Req_A_SFS_Len = SfsLen; // includes IRB flags & len - pIRB->Req_A_SFS_Addr = // TL needs physical addr of frame to send - fcChip->exch_dma_handle + (unsigned long)CMDfchs - - (unsigned long)Exchanges; - - pIRB->Req_A_SFS_D_ID = CMDfchs->d_id << 8; // Dest_ID must be consistent! - - // Exchange is complete except for "fix-up" fields to be set - // at Tachyon Queuing time: - // IRB->Req_A_Trans_ID (OX_ID/ RX_ID): - // for SEST entry, lower bits correspond to actual FC Exchange ID - // fchs->OX_ID or RX_ID - } - else - { -#ifdef DBG - printk( "FC Error: SEST build Pool Allocation failed\n"); -#endif - // return resources... - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, *fcExchangeIndex); // SEST build failed - } - } - else // no Exchanges available - { - ulStatus = SEST_FULL; - printk( "FC Error: no fcExchanges available\n"); - } - return ulStatus; -} - - - - - - -// set RSP payload fields -static void buildFCPstatus( PTACHYON fcChip, ULONG ExchangeID) -{ - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ExchangeID]; // shorthand - PFCP_STATUS_RESPONSE pFcpStatus; - - memset( &fcChip->SEST->RspHDR[ ExchangeID ].pl, 0, - sizeof( FCP_STATUS_RESPONSE) ); - if( pExchange->status ) // something wrong? - { - pFcpStatus = (PFCP_STATUS_RESPONSE) // cast RSP buffer for this xchng - &fcChip->SEST->RspHDR[ ExchangeID ].pl; - if( pExchange->status & COUNT_ERROR ) - { - - // set FCP response len valid (so we can report count error) - pFcpStatus->fcp_status |= FCP_RSP_LEN_VALID; - pFcpStatus->fcp_rsp_len = 0x04000000; // 4 byte len (BIG Endian) - - pFcpStatus->fcp_rsp_info = FCP_DATA_LEN_NOT_BURST_LEN; // RSP_CODE - } - } -} - - -static dma_addr_t -cpqfc_pci_map_sg_page( - struct pci_dev *pcidev, - ULONG *hw_paddr, // where to put phys addr for HW use - void *sgp_vaddr, // the virtual address of the sg page - dma_addr_t *umap_paddr, // where to put phys addr for unmap - unsigned int *maplen, // where to store sg entry length - int PairCount) // number of sg pairs used in the page. -{ - unsigned long aligned_addr = (unsigned long) sgp_vaddr; - - *maplen = PairCount * 8; - aligned_addr += TL_EXT_SG_PAGE_BYTELEN; - aligned_addr &= ~(TL_EXT_SG_PAGE_BYTELEN -1); - - *umap_paddr = pci_map_single(pcidev, (void *) aligned_addr, - *maplen, PCI_DMA_TODEVICE); - *hw_paddr = (ULONG) *umap_paddr; - -# if BITS_PER_LONG > 32 - if( *umap_paddr >>32 ) { - printk("cqpfcTS:Tach SG DMA addr %p>32 bits\n", - (void*)umap_paddr); - return 0; - } -# endif - return *umap_paddr; -} - -static void -cpqfc_undo_SEST_mappings(struct pci_dev *pcidev, - unsigned long contigaddr, int len, int dir, - struct scatterlist *sgl, int use_sg, - PSGPAGES *sgPages_head, - int allocated_pages) -{ - PSGPAGES i, next; - - if (contigaddr != (unsigned long) NULL) - pci_unmap_single(pcidev, contigaddr, len, dir); - - if (sgl != NULL) - pci_unmap_sg(pcidev, sgl, use_sg, dir); - - for (i=*sgPages_head; i != NULL ;i = next) - { - pci_unmap_single(pcidev, i->busaddr, i->maplen, - PCI_DMA_TODEVICE); - i->busaddr = (dma_addr_t) NULL; - i->maplen = 0L; - next = i->next; - kfree(i); - } - *sgPages_head = NULL; -} - -// This routine builds scatter/gather lists into SEST entries -// INPUTS: -// SESTalPair - SEST address @DWordA "Local Buffer Length" -// sgList - Scatter/Gather linked list of Len/Address data buffers -// OUTPUT: -// sgPairs - number of valid address/length pairs -// Remarks: -// The SEST data buffer pointers only depend on number of -// length/ address pairs, NOT on the type (IWE, TRE,...) -// Up to 3 pairs can be referenced in the SEST - more than 3 -// require this Extended S/G list page. The page holds 4, 8, 16... -// len/addr pairs, per Scatter/Gather List Page Length Reg. -// TachLite allows pages to be linked to any depth. - -//#define DBG_SEST_SGLIST 1 // for printing out S/G pairs with Ext. pages - -static int ap_hi_water = TL_DANGER_SGPAGES; - -static ULONG build_SEST_sgList( - struct pci_dev *pcidev, - ULONG *SESTalPairStart, // the 3 len/address buffers in SEST - Scsi_Cmnd *Cmnd, - ULONG *sgPairs, - PSGPAGES *sgPages_head) // link list of TL Ext. S/G pages from O/S Pool - -{ - ULONG i, AllocatedPages=0; // Tach Ext. S/G page allocations - ULONG* alPair = SESTalPairStart; - ULONG* ext_sg_page_phys_addr_place = NULL; - int PairCount; - unsigned long ulBuff, contigaddr; - ULONG total_data_len=0; // (in bytes) - ULONG bytes_to_go = Cmnd->request_bufflen; // total xfer (S/G sum) - ULONG thisMappingLen; - struct scatterlist *sgl = NULL; // S/G list (Linux format) - int sg_count, totalsgs; - dma_addr_t busaddr; - unsigned long thislen, offset; - PSGPAGES *sgpage = sgPages_head; - PSGPAGES prev_page = NULL; - -# define WE_HAVE_SG_LIST (sgl != (unsigned long) NULL) - contigaddr = (unsigned long) NULL; - - if( !Cmnd->use_sg ) // no S/G list? - { - if (bytes_to_go <= TL_MAX_SG_ELEM_LEN) - { - *sgPairs = 1; // use "local" S/G pair in SEST entry - // (for now, ignore address bits above #31) - - *alPair++ = bytes_to_go; // bits 18-0, length - - if (bytes_to_go != 0) { - contigaddr = ulBuff = pci_map_single(pcidev, - Cmnd->request_buffer, - Cmnd->request_bufflen, - Cmnd->sc_data_direction); - // printk("ms %p ", ulBuff); - } - else { - // No data transfer, (e.g.: Test Unit Ready) - // printk("btg=0 "); - *sgPairs = 0; - memset(alPair, 0, sizeof(*alPair)); - return 0; - } - -# if BITS_PER_LONG > 32 - if( ulBuff >>32 ) { - printk("FATAL! Tachyon DMA address %p " - "exceeds 32 bits\n", (void*)ulBuff ); - return 0; - } -# endif - *alPair = (ULONG)ulBuff; - return bytes_to_go; - } - else // We have a single large (too big) contiguous buffer. - { // We will have to break it up. We'll use the scatter - // gather code way below, but use contigaddr instead - // of sg_dma_addr(). (this is a very rare case). - - unsigned long btg; - contigaddr = pci_map_single(pcidev, Cmnd->request_buffer, - Cmnd->request_bufflen, - Cmnd->sc_data_direction); - - // printk("contigaddr = %p, len = %d\n", - // (void *) contigaddr, bytes_to_go); - totalsgs = 0; - for (btg = bytes_to_go; btg > 0; ) { - btg -= ( btg > TL_MAX_SG_ELEM_LEN ? - TL_MAX_SG_ELEM_LEN : btg ); - totalsgs++; - } - sgl = NULL; - *sgPairs = totalsgs; - } - } - else // we do have a scatter gather list - { - // [TBD - update for Linux to support > 32 bits addressing] - // since the format for local & extended S/G lists is different, - // check if S/G pairs exceeds 3. - // *sgPairs = Cmnd->use_sg; Nope, that's wrong. - - sgl = (struct scatterlist*)Cmnd->request_buffer; - sg_count = pci_map_sg(pcidev, sgl, Cmnd->use_sg, - Cmnd->sc_data_direction); - if( sg_count <= 3 ) { - - // we need to be careful here that no individual mapping - // is too large, and if any is, that breaking it up - // doesn't push us over 3 sgs, or, if it does, that we - // handle that case. Tachyon can take 0x7FFFF bits for length, - // but sg structure uses "unsigned int", on the face of it, - // up to 0xFFFFFFFF or even more. - - int i; - unsigned long thislen; - - totalsgs = 0; - for (i=0;i= TL_MAX_SG_ELEM_LEN) { - totalsgs++; - thislen -= TL_MAX_SG_ELEM_LEN; - } - if (thislen > 0) totalsgs++; - } - *sgPairs = totalsgs; - } else totalsgs = 999; // as a first estimate, definitely >3, - - // if (totalsgs != sg_count) - // printk("totalsgs = %d, sgcount=%d\n",totalsgs,sg_count); - } - - if( totalsgs <= 3 ) // can (must) use "local" SEST list - { - while( bytes_to_go) - { - offset = 0L; - - if ( WE_HAVE_SG_LIST ) - thisMappingLen = sg_dma_len(sgl); - else // or contiguous buffer? - thisMappingLen = bytes_to_go; - - while (thisMappingLen > 0) - { - thislen = thisMappingLen > TL_MAX_SG_ELEM_LEN ? - TL_MAX_SG_ELEM_LEN : thisMappingLen; - bytes_to_go = bytes_to_go - thislen; - - // we have L/A pair; L = thislen, A = physicalAddress - // load into SEST... - - total_data_len += thislen; - *alPair = thislen; // bits 18-0, length - - alPair++; - - if ( WE_HAVE_SG_LIST ) - ulBuff = sg_dma_address(sgl) + offset; - else - ulBuff = contigaddr + offset; - - offset += thislen; - -# if BITS_PER_LONG > 32 - if( ulBuff >>32 ) { - printk("cqpfcTS: 2Tach DMA address %p > 32 bits\n", - (void*)ulBuff ); - printk("%s = %p, offset = %ld\n", - WE_HAVE_SG_LIST ? "ulBuff" : "contigaddr", - WE_HAVE_SG_LIST ? (void *) ulBuff : (void *) contigaddr, - offset); - return 0; - } -# endif - *alPair++ = (ULONG)ulBuff; // lower 32 bits (31-0) - thisMappingLen -= thislen; - } - - if ( WE_HAVE_SG_LIST ) ++sgl; // next S/G pair - else if (bytes_to_go != 0) printk("BTG not zero!\n"); - -# ifdef DBG_SEST_SGLIST - printk("L=%d ", thisMappingLen); - printk("btg=%d ", bytes_to_go); -# endif - - } - // printk("i:%d\n", *sgPairs); - } - else // more than 3 pairs requires Extended S/G page (Pool Allocation) - { - // clear out SEST DWORDs (local S/G addr) C-F (A-B set in following logic) - for( i=2; i<6; i++) - alPair[i] = 0; - - PairCount = TL_EXT_SG_PAGE_COUNT; // forces initial page allocation - totalsgs = 0; - while( bytes_to_go ) - { - // Per SEST format, we can support 524287 byte lengths per - // S/G pair. Typical user buffers are 4k, and very rarely - // exceed 12k due to fragmentation of physical memory pages. - // However, on certain O/S system (not "user") buffers (on platforms - // with huge memories), it's possible to exceed this - // length in a single S/G address/len mapping, so we have to handle - // that. - - offset = 0L; - if ( WE_HAVE_SG_LIST ) - thisMappingLen = sg_dma_len(sgl); - else - thisMappingLen = bytes_to_go; - - while (thisMappingLen > 0) - { - thislen = thisMappingLen > TL_MAX_SG_ELEM_LEN ? - TL_MAX_SG_ELEM_LEN : thisMappingLen; - // printk("%d/%d/%d\n", thislen, thisMappingLen, bytes_to_go); - - // should we load into "this" extended S/G page, or allocate - // new page? - - if( PairCount >= TL_EXT_SG_PAGE_COUNT ) - { - // Now, we have to map the previous page, (triggering buffer bounce) - // The first time thru the loop, there won't be a previous page. - if (prev_page != NULL) // is there a prev page? - { - // this code is normally kind of hard to trigger, - // you have to use up more than 256 scatter gather - // elements to get here. Cranking down TL_MAX_SG_ELEM_LEN - // to an absurdly low value (128 bytes or so) to artificially - // break i/o's into a zillion pieces is how I tested it. - busaddr = cpqfc_pci_map_sg_page(pcidev, - ext_sg_page_phys_addr_place, - prev_page->page, - &prev_page->busaddr, - &prev_page->maplen, - PairCount); - } - // Allocate the TL Extended S/G list page. We have - // to allocate twice what we want to ensure required TL alignment - // (Tachlite TL/TS User Man. Rev 6.0, p 168) - // We store the original allocated PVOID so we can free later - *sgpage = kmalloc( sizeof(SGPAGES), GFP_ATOMIC); - if ( ! *sgpage ) - { - printk("cpqfc: Allocation failed @ %d S/G page allocations\n", - AllocatedPages); - total_data_len = 0; // failure!! Ext. S/G is All-or-none affair - - // unmap the previous mappings, if any. - - cpqfc_undo_SEST_mappings(pcidev, contigaddr, - Cmnd->request_bufflen, - Cmnd->sc_data_direction, - sgl, Cmnd->use_sg, sgPages_head, AllocatedPages+1); - - // FIXME: testing shows that if we get here, - // it's bad news. (this has been this way for a long - // time though, AFAIK. Not that that excuses it.) - - return 0; // give up (and probably hang the system) - } - // clear out memory we just allocated - memset( (*sgpage)->page,0,TL_EXT_SG_PAGE_BYTELEN*2); - (*sgpage)->next = NULL; - (*sgpage)->busaddr = (dma_addr_t) NULL; - (*sgpage)->maplen = 0L; - - // align the memory - TL requires sizeof() Ext. S/G page alignment. - // We doubled the actual required size so we could mask off LSBs - // to get desired offset - - ulBuff = (unsigned long) (*sgpage)->page; - ulBuff += TL_EXT_SG_PAGE_BYTELEN; - ulBuff &= ~(TL_EXT_SG_PAGE_BYTELEN -1); - - // set pointer, in SEST if first Ext. S/G page, or in last pair - // of linked Ext. S/G pages... (Only 32-bit PVOIDs, so just - // load lower 32 bits) - // NOTE: the Len field must be '0' if this is the first Ext. S/G - // pointer in SEST, and not 0 otherwise (we know thislen != 0). - - *alPair = (alPair != SESTalPairStart) ? thislen : 0; - -# ifdef DBG_SEST_SGLIST - printk("PairCount %d @%p even %Xh, ", - PairCount, alPair, *alPair); -# endif - - // Save the place where we need to store the physical - // address of this scatter gather page which we get when we map it - // (and mapping we can do only after we fill it in.) - alPair++; // next DWORD, will contain phys addr of the ext page - ext_sg_page_phys_addr_place = alPair; - - // Now, set alPair = the virtual addr of the (Extended) S/G page - // which will accept the Len/ PhysicalAddress pairs - alPair = (ULONG *) ulBuff; - - AllocatedPages++; - if (AllocatedPages >= ap_hi_water) - { - // This message should rarely, if ever, come out. - // Previously (cpqfc version <= 2.0.5) the driver would - // just puke if more than 4 SG pages were used, and nobody - // ever complained about that. This only comes out if - // more than 8 pages are used. - - printk(KERN_WARNING - "cpqfc: Possible danger. %d scatter gather pages used.\n" - "cpqfc: detected seemingly extreme memory " - "fragmentation or huge data transfers.\n", - AllocatedPages); - ap_hi_water = AllocatedPages+1; - } - - PairCount = 1; // starting new Ext. S/G page - prev_page = (*sgpage); // remember this page, for next time thru - sgpage = &((*sgpage)->next); - } // end of new TL Ext. S/G page allocation - - *alPair = thislen; // bits 18-0, length (range check above) - -# ifdef DBG_SEST_SGLIST - printk("PairCount %d @%p, even %Xh, ", PairCount, alPair, *alPair); -# endif - - alPair++; // next DWORD, physical address - - if ( WE_HAVE_SG_LIST ) - ulBuff = sg_dma_address(sgl) + offset; - else - ulBuff = contigaddr + offset; - offset += thislen; - -# if BITS_PER_LONG > 32 - if( ulBuff >>32 ) - { - printk("cqpfcTS: 1Tach DMA address %p > 32 bits\n", (void*)ulBuff ); - printk("%s = %p, offset = %ld\n", - WE_HAVE_SG_LIST ? "ulBuff" : "contigaddr", - WE_HAVE_SG_LIST ? (void *) ulBuff : (void *) contigaddr, - offset); - return 0; - } -# endif - - *alPair = (ULONG) ulBuff; // lower 32 bits (31-0) - -# ifdef DBG_SEST_SGLIST - printk("odd %Xh\n", *alPair); -# endif - alPair++; // next DWORD, next address/length pair - - PairCount++; // next Length/Address pair - - // if (PairCount > pc_hi_water) - // { - // printk("pc hi = %d ", PairCount); - // pc_hi_water = PairCount; - // } - bytes_to_go -= thislen; - total_data_len += thislen; - thisMappingLen -= thislen; - totalsgs++; - } // while (thisMappingLen > 0) - if ( WE_HAVE_SG_LIST ) sgl++; // next S/G pair - } // while (bytes_to_go) - - // printk("Totalsgs=%d\n", totalsgs); - *sgPairs = totalsgs; - - // PCI map (and bounce) the last (and usually only) extended SG page - busaddr = cpqfc_pci_map_sg_page(pcidev, - ext_sg_page_phys_addr_place, - prev_page->page, - &prev_page->busaddr, - &prev_page->maplen, - PairCount); - } - return total_data_len; -} - - - -// The Tachlite SEST table is referenced to OX_ID (or RX_ID). To optimize -// performance and debuggability, we index the Exchange structure to FC X_ID -// This enables us to build exchanges for later en-queing to Tachyon, -// provided we have an open X_ID slot. At Tachyon queing time, we only -// need an ERQ slot; then "fix-up" references in the -// IRB, FCHS, etc. as needed. -// RETURNS: -// 0 if successful -// non-zero on error -//sstartex -ULONG cpqfcTSStartExchange( - CPQFCHBA *cpqfcHBAdata, - LONG ExchangeID ) -{ - PTACHYON fcChip = &cpqfcHBAdata->fcChip; - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ ExchangeID ]; // shorthand - USHORT producer, consumer; - ULONG ulStatus=0; - short int ErqIndex; - BOOLEAN CompleteExchange = FALSE; // e.g. ACC replies are complete - BOOLEAN SestType=FALSE; - ULONG InboundData=0; - - // We will manipulate Tachlite chip registers here to successfully - // start exchanges. - - // Check that link is not down -- we can't start an exchange on a - // down link! - - if( fcChip->Registers.FMstatus.value & 0x80) // LPSM offline? - { -printk("fcStartExchange: PSM offline (%Xh), x_ID %Xh, type %Xh, port_id %Xh\n", - fcChip->Registers.FMstatus.value & 0xFF, - ExchangeID, - pExchange->type, - pExchange->fchs.d_id); - - if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame? - { - // Our most popular LinkService commands are port discovery types - // (PLOGI/ PDISC...), which are implicitly nullified by Link Down - // events, so it makes no sense to Que them. However, ABTS should - // be queued, since exchange sequences are likely destroyed by - // Link Down events, and we want to notify other ports of broken - // sequences by aborting the corresponding exchanges. - if( pExchange->type != BLS_ABTS ) - { - ulStatus = LNKDWN_OSLS; - goto Done; - // don't Que most LinkServ exchanges on LINK DOWN - } - } - - printk("fcStartExchange: Que x_ID %Xh, type %Xh\n", - ExchangeID, pExchange->type); - pExchange->status |= EXCHANGE_QUEUED; - ulStatus = EXCHANGE_QUEUED; - goto Done; - } - - // Make sure ERQ has available space. - - producer = (USHORT)fcChip->ERQ->producerIndex; // copies for logical arith. - consumer = (USHORT)fcChip->ERQ->consumerIndex; - producer++; // We are testing for full que by incrementing - - if( producer >= ERQ_LEN ) // rollover condition? - producer = 0; - if( consumer != producer ) // ERQ not full? - { - // ****************** Need Atomic access to chip registers!!******** - - // remember ERQ PI for copying IRB - ErqIndex = (USHORT)fcChip->ERQ->producerIndex; - fcChip->ERQ->producerIndex = producer; // this is written to Tachyon - // we have an ERQ slot! If SCSI command, need SEST slot - // otherwise we are done. - - // Note that Tachyon requires that bit 15 of the OX_ID or RX_ID be - // set according to direction of data to/from Tachyon for SEST assists. - // For consistency, enforce this rule for Link Service (non-SEST) - // exchanges as well. - - // fix-up the X_ID field in IRB - pExchange->IRB.Req_A_Trans_ID = ExchangeID & 0x7FFF; // 15-bit field - - // fix-up the X_ID field in fchs -- depends on Originator or Responder, - // outgoing or incoming data? - switch( pExchange->type ) - { - // ORIGINATOR types... we're setting our OX_ID and - // defaulting the responder's RX_ID to 0xFFFF - - case SCSI_IRE: - // Requirement: set MSB of x_ID for Incoming TL data - // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50) - InboundData = 0x8000; - - case SCSI_IWE: - SestType = TRUE; - pExchange->fchs.ox_rx_id = (ExchangeID | InboundData); - pExchange->fchs.ox_rx_id <<= 16; // MSW shift - pExchange->fchs.ox_rx_id |= 0xffff; // add default RX_ID - - // now fix-up the Data HDR OX_ID (TL automatically does rx_id) - // (not necessary for IRE -- data buffer unused) - if( pExchange->type == SCSI_IWE) - { - fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id = - pExchange->fchs.ox_rx_id; - - } - - break; - - - case FCS_NSR: // ext. link service Name Service Request - case ELS_SCR: // ext. link service State Change Registration - case ELS_FDISC:// ext. link service login - case ELS_FLOGI:// ext. link service login - case ELS_LOGO: // FC-PH extended link service logout - case BLS_NOP: // Basic link service No OPeration - case ELS_PLOGI:// ext. link service login (PLOGI) - case ELS_PDISC:// ext. link service login (PDISC) - case ELS_PRLI: // ext. link service process login - - pExchange->fchs.ox_rx_id = ExchangeID; - pExchange->fchs.ox_rx_id <<= 16; // MSW shift - pExchange->fchs.ox_rx_id |= 0xffff; // and RX_ID - - break; - - - - - // RESPONDER types... we must set our RX_ID while preserving - // sender's OX_ID - // outgoing (or no) data - case ELS_RJT: // extended link service reject - case ELS_LOGO_ACC: // FC-PH extended link service logout accept - case ELS_ACC: // ext. generic link service accept - case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC) - case ELS_PRLI_ACC: // ext. link service process login accept - - CompleteExchange = TRUE; // Reply (ACC or RJT) is end of exchange - pExchange->fchs.ox_rx_id |= (ExchangeID & 0xFFFF); - - break; - - - // since we are a Responder, OX_ID should already be set by - // cpqfcTSBuildExchange(). We need to -OR- in RX_ID - case SCSI_TWE: - SestType = TRUE; - // Requirement: set MSB of x_ID for Incoming TL data - // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50) - - pExchange->fchs.ox_rx_id &= 0xFFFF0000; // clear RX_ID - // Requirement: set MSB of RX_ID for Incoming TL data - // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50) - pExchange->fchs.ox_rx_id |= (ExchangeID | 0x8000); - break; - - - case SCSI_TRE: - SestType = TRUE; - - // there is no XRDY for SEST target read; the data - // header needs to be updated. Also update the RSP - // exchange IDs for the status frame, in case it is sent automatically - fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id |= ExchangeID; - fcChip->SEST->RspHDR[ ExchangeID ].ox_rx_id = - fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id; - - // for easier FCP response logic (works for TWE and TRE), - // copy exchange IDs. (Not needed if TRE 'RSP' bit set) - pExchange->fchs.ox_rx_id = - fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id; - - break; - - - case FCP_RESPONSE: // using existing OX_ID/ RX_ID pair, - // start SFS FCP-RESPONSE frame - // OX/RX_ID should already be set! (See "fcBuild" above) - CompleteExchange = TRUE; // RSP is end of FCP-SCSI exchange - - - break; - - - case BLS_ABTS_RJT: // uses new RX_ID, since SEST x_ID non-existent - case BLS_ABTS_ACC: // using existing OX_ID/ RX_ID pair from SEST entry - CompleteExchange = TRUE; // ACC or RJT marks end of FCP-SCSI exchange - case BLS_ABTS: // using existing OX_ID/ RX_ID pair from SEST entry - - - break; - - - default: - printk("Error on fcStartExchange: undefined type %Xh(%d)\n", - pExchange->type, pExchange->type); - return INVALID_ARGS; - } - - - // X_ID fields are entered -- copy IRB to Tachyon's ERQ - - - memcpy( - &fcChip->ERQ->QEntry[ ErqIndex ], // dest. - &pExchange->IRB, - 32); // fixed (hardware) length! - - PCI_TRACEO( ExchangeID, 0xA0) - - // ACTION! May generate INT and IMQ entry - writel( fcChip->ERQ->producerIndex, - fcChip->Registers.ERQproducerIndex.address); - - - if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame? - { - - // wait for completion! (TDB -- timeout and chip reset) - - - PCI_TRACEO( ExchangeID, 0xA4) - - enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Sem. - - down_interruptible( cpqfcHBAdata->TYOBcomplete); - - disable_irq( cpqfcHBAdata->HostAdapter->irq); - PCI_TRACE( 0xA4) - - // On login exchanges, BAD_ALPA (non-existent port_id) results in - // FTO (Frame Time Out) on the Outbound Completion message. - // If we got an FTO status, complete the exchange (free up slot) - if( CompleteExchange || // flag from Reply frames - pExchange->status ) // typically, can get FRAME_TO - { - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID); - } - } - - else // SEST Exchange - { - ulStatus = 0; // ship & pray success (e.g. FCP-SCSI) - - if( CompleteExchange ) // by Type of exchange (e.g. end-of-xchng) - { - cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID); - } - - else - pExchange->status &= ~EXCHANGE_QUEUED; // clear ExchangeQueued flag - - } - } - - - else // ERQ 'producer' = 'consumer' and QUE is full - { - ulStatus = OUTQUE_FULL; // Outbound (ERQ) Que full - } - -Done: - PCI_TRACE( 0xA0) - return ulStatus; -} - - - - - -// Scan fcController->fcExchanges array for a usuable index (a "free" -// exchange). -// Inputs: -// fcChip - pointer to TachLite chip structure -// Return: -// index - exchange array element where exchange can be built -// -1 - exchange array is full -// REMARKS: -// Although this is a (yuk!) linear search, we presume -// that the system will complete exchanges about as quickly as -// they are submitted. A full Exchange array (and hence, max linear -// search time for free exchange slot) almost guarantees a Fibre problem -// of some sort. -// In the interest of making exchanges easier to debug, we want a LRU -// (Least Recently Used) scheme. - - -static LONG FindFreeExchange( PTACHYON fcChip, ULONG type ) -{ - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - ULONG i; - ULONG ulStatus=-1; // assume failure - - - if( type == SCSI_IRE || - type == SCSI_TRE || - type == SCSI_IWE || - type == SCSI_TWE) - { - // SCSI type - X_IDs should be from 0 to TACH_SEST_LEN-1 - if( fcChip->fcSestExchangeLRU >= TACH_SEST_LEN) // rollover? - fcChip->fcSestExchangeLRU = 0; - i = fcChip->fcSestExchangeLRU; // typically it's already free! - - if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element - { - ulStatus = 0; // success! - } - - else - { // YUK! we need to do a linear search for free element. - // Fragmentation of the fcExchange array is due to excessively - // long completions or timeouts. - - while( TRUE ) - { - if( ++i >= TACH_SEST_LEN ) // rollover check - i = 0; // beginning of SEST X_IDs - -// printk( "looping for SCSI xchng ID: i=%d, type=%Xh\n", -// i, Exchanges->fcExchange[i].type); - - if( Exchanges->fcExchange[i].type == 0 ) // "free"? - { - ulStatus = 0; // success! - break; - } - if( i == fcChip->fcSestExchangeLRU ) // wrapped-around array? - { - printk( "SEST X_ID space full\n"); - break; // failed - prevent inf. loop - } - } - } - fcChip->fcSestExchangeLRU = i + 1; // next! (rollover check next pass) - } - - - - else // Link Service type - X_IDs should be from TACH_SEST_LEN - // to TACH_MAX_XID - { - if( fcChip->fcLsExchangeLRU >= TACH_MAX_XID || // range check - fcChip->fcLsExchangeLRU < TACH_SEST_LEN ) // (e.g. startup) - fcChip->fcLsExchangeLRU = TACH_SEST_LEN; - - i = fcChip->fcLsExchangeLRU; // typically it's already free! - if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element - { - ulStatus = 0; // success! - } - - else - { // YUK! we need to do a linear search for free element - // Fragmentation of the fcExchange array is due to excessively - // long completions or timeouts. - - while( TRUE ) - { - if( ++i >= TACH_MAX_XID ) // rollover check - i = TACH_SEST_LEN;// beginning of Link Service X_IDs - -// printk( "looping for xchng ID: i=%d, type=%Xh\n", -// i, Exchanges->fcExchange[i].type); - - if( Exchanges->fcExchange[i].type == 0 ) // "free"? - { - ulStatus = 0; // success! - break; - } - if( i == fcChip->fcLsExchangeLRU ) // wrapped-around array? - { - printk( "LinkService X_ID space full\n"); - break; // failed - prevent inf. loop - } - } - } - fcChip->fcLsExchangeLRU = i + 1; // next! (rollover check next pass) - - } - - if( !ulStatus ) // success? - Exchanges->fcExchange[i].type = type; // allocate it. - - else - i = -1; // error - all exchanges "open" - - return i; -} - -static void -cpqfc_pci_unmap_extended_sg(struct pci_dev *pcidev, - PTACHYON fcChip, - ULONG x_ID) -{ - // Unmaps the memory regions used to hold the scatter gather lists - - PSGPAGES i; - - // Were there any such regions needing unmapping? - if (! USES_EXTENDED_SGLIST(fcChip->SEST, x_ID)) - return; // No such regions, we're outta here. - - // for each extended scatter gather region needing unmapping... - for (i=fcChip->SEST->sgPages[x_ID] ; i != NULL ; i = i->next) - pci_unmap_single(pcidev, i->busaddr, i->maplen, - PCI_DMA_TODEVICE); -} - -// Called also from cpqfcTScontrol.o, so can't be static -void -cpqfc_pci_unmap(struct pci_dev *pcidev, - Scsi_Cmnd *cmd, - PTACHYON fcChip, - ULONG x_ID) -{ - // Undo the DMA mappings - if (cmd->use_sg) { // Used scatter gather list for data buffer? - cpqfc_pci_unmap_extended_sg(pcidev, fcChip, x_ID); - pci_unmap_sg(pcidev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); - // printk("umsg %d\n", cmd->use_sg); - } - else if (cmd->request_bufflen) { - // printk("ums %p ", fcChip->SEST->u[ x_ID ].IWE.GAddr1); - pci_unmap_single(pcidev, fcChip->SEST->u[ x_ID ].IWE.GAddr1, - cmd->request_bufflen, - cmd->sc_data_direction); - } -} - -// We call this routine to free an Exchange for any reason: -// completed successfully, completed with error, aborted, etc. - -// returns FALSE if Exchange failed and "retry" is acceptable -// returns TRUE if Exchange was successful, or retry is impossible -// (e.g. port/device gone). -//scompleteexchange - -void cpqfcTSCompleteExchange( - struct pci_dev *pcidev, - PTACHYON fcChip, - ULONG x_ID) -{ - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - int already_unmapped = 0; - - if( x_ID < TACH_SEST_LEN ) // SEST-based (or LinkServ for FCP exchange) - { - if( Exchanges->fcExchange[ x_ID ].Cmnd == NULL ) // what#@! - { -// TriggerHBA( fcChip->Registers.ReMapMemBase, 0); - printk(" x_ID %Xh, type %Xh, NULL ptr!\n", x_ID, - Exchanges->fcExchange[ x_ID ].type); - - goto CleanUpSestResources; // this path should be very rare. - } - - // we have Linux Scsi Cmnd ptr..., now check our Exchange status - // to decide how to complete this SEST FCP exchange - - if( Exchanges->fcExchange[ x_ID ].status ) // perhaps a Tach indicated problem, - // or abnormal exchange completion - { - // set FCP Link statistics - - if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT) - fcChip->fcStats.timeouts++; - if( Exchanges->fcExchange[ x_ID ].status & INITIATOR_ABORT) - fcChip->fcStats.FC4aborted++; - if( Exchanges->fcExchange[ x_ID ].status & COUNT_ERROR) - fcChip->fcStats.CntErrors++; - if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX) - fcChip->fcStats.linkFailTX++; - if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_RX) - fcChip->fcStats.linkFailRX++; - if( Exchanges->fcExchange[ x_ID ].status & OVERFLOW) - fcChip->fcStats.CntErrors++; - - // First, see if the Scsi upper level initiated an ABORT on this - // exchange... - if( Exchanges->fcExchange[ x_ID ].status == INITIATOR_ABORT ) - { - printk(" DID_ABORT, x_ID %Xh, Cmnd %p ", - x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); - goto CleanUpSestResources; // (we don't expect Linux _aborts) - } - - // Did our driver timeout the Exchange, or did Tachyon indicate - // a failure during transmission? Ask for retry with "SOFT_ERROR" - else if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT) - { -// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n", -// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16); - } - - // Did frame(s) for an open exchange arrive in the SFQ, - // meaning the SEST was unable to process them? - else if( Exchanges->fcExchange[ x_ID ].status & SFQ_FRAME) - { -// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n", -// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16); - } - - // Did our driver timeout the Exchange, or did Tachyon indicate - // a failure during transmission? Ask for retry with "SOFT_ERROR" - else if( - (Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX) || - (Exchanges->fcExchange[ x_ID ].status & PORTID_CHANGED) || - (Exchanges->fcExchange[ x_ID ].status & FRAME_TO) || - (Exchanges->fcExchange[ x_ID ].status & INV_ENTRY) || - (Exchanges->fcExchange[ x_ID ].status & ABORTSEQ_NOTIFY) ) - - - { -// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n", -// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16); - - - } - - // e.g., a LOGOut happened, or device never logged back in. - else if( Exchanges->fcExchange[ x_ID ].status & DEVICE_REMOVED) - { -// printk(" *LOGOut or timeout on login!* "); - // trigger? -// TriggerHBA( fcChip->Registers.ReMapMemBase, 0); - - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_BAD_TARGET <<16); - } - - - // Did Tachyon indicate a CNT error? We need further analysis - // to determine if the exchange is acceptable - else if( Exchanges->fcExchange[ x_ID ].status == COUNT_ERROR) - { - UCHAR ScsiStatus; - FCP_STATUS_RESPONSE *pFcpStatus = - (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl; - - ScsiStatus = pFcpStatus->fcp_status >>24; - - // If the command is a SCSI Read/Write type, we don't tolerate - // count errors of any kind; assume the count error is due to - // a dropped frame and ask for retry... - - if(( (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x8) || - (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x28) || - (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0xA) || - (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x2A) ) - && - ScsiStatus == 0 ) - { - // ask for retry -/* printk("COUNT_ERROR retry, x_ID %Xh, status %Xh, Cmnd %p\n", - x_ID, Exchanges->fcExchange[ x_ID ].status, - Exchanges->fcExchange[ x_ID ].Cmnd);*/ - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16); - } - - else // need more analysis - { - cpqfcTSCheckandSnoopFCP(fcChip, x_ID); // (will set ->result) - } - } - - // default: NOTE! We don't ever want to get here. Getting here - // implies something new is happening that we've never had a test - // case for. Need code maintenance! Return "ERROR" - else - { - unsigned int stat = Exchanges->fcExchange[ x_ID ].status; - printk("DEFAULT result %Xh, x_ID %Xh, Cmnd %p", - Exchanges->fcExchange[ x_ID ].status, x_ID, - Exchanges->fcExchange[ x_ID ].Cmnd); - - if (stat & INVALID_ARGS) printk(" INVALID_ARGS "); - if (stat & LNKDWN_OSLS) printk(" LNKDWN_OSLS "); - if (stat & LNKDWN_LASER) printk(" LNKDWN_LASER "); - if (stat & OUTQUE_FULL) printk(" OUTQUE_FULL "); - if (stat & DRIVERQ_FULL) printk(" DRIVERQ_FULL "); - if (stat & SEST_FULL) printk(" SEST_FULL "); - if (stat & BAD_ALPA) printk(" BAD_ALPA "); - if (stat & OVERFLOW) printk(" OVERFLOW "); - if (stat & COUNT_ERROR) printk(" COUNT_ERROR "); - if (stat & LINKFAIL_RX) printk(" LINKFAIL_RX "); - if (stat & ABORTSEQ_NOTIFY) printk(" ABORTSEQ_NOTIFY "); - if (stat & LINKFAIL_TX) printk(" LINKFAIL_TX "); - if (stat & HOSTPROG_ERR) printk(" HOSTPROG_ERR "); - if (stat & FRAME_TO) printk(" FRAME_TO "); - if (stat & INV_ENTRY) printk(" INV_ENTRY "); - if (stat & SESTPROG_ERR) printk(" SESTPROG_ERR "); - if (stat & OUTBOUND_TIMEOUT) printk(" OUTBOUND_TIMEOUT "); - if (stat & INITIATOR_ABORT) printk(" INITIATOR_ABORT "); - if (stat & MEMPOOL_FAIL) printk(" MEMPOOL_FAIL "); - if (stat & FC2_TIMEOUT) printk(" FC2_TIMEOUT "); - if (stat & TARGET_ABORT) printk(" TARGET_ABORT "); - if (stat & EXCHANGE_QUEUED) printk(" EXCHANGE_QUEUED "); - if (stat & PORTID_CHANGED) printk(" PORTID_CHANGED "); - if (stat & DEVICE_REMOVED) printk(" DEVICE_REMOVED "); - if (stat & SFQ_FRAME) printk(" SFQ_FRAME "); - printk("\n"); - - Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_ERROR <<16); - } - } - else // definitely no Tach problem, but perhaps an FCP problem - { - // set FCP Link statistic - fcChip->fcStats.ok++; - cpqfcTSCheckandSnoopFCP( fcChip, x_ID); // (will set ->result) - } - - cpqfc_pci_unmap(pcidev, Exchanges->fcExchange[x_ID].Cmnd, - fcChip, x_ID); // undo DMA mappings. - already_unmapped = 1; - - // OK, we've set the Scsi "->result" field, so proceed with calling - // Linux Scsi "done" (if not NULL), and free any kernel memory we - // may have allocated for the exchange. - - PCI_TRACEO( (ULONG)Exchanges->fcExchange[x_ID].Cmnd, 0xAC); - // complete the command back to upper Scsi drivers - if( Exchanges->fcExchange[ x_ID ].Cmnd->scsi_done != NULL) - { - // Calling "done" on an Linux _abort() aborted - // Cmnd causes a kernel panic trying to re-free mem. - // Actually, we shouldn't do anything with an _abort CMND - if( Exchanges->fcExchange[ x_ID ].Cmnd->result != (DID_ABORT<<16) ) - { - PCI_TRACE(0xAC) - call_scsi_done(Exchanges->fcExchange[ x_ID ].Cmnd); - } - else - { -// printk(" not calling scsi_done on x_ID %Xh, Cmnd %p\n", -// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); - } - } - else{ - printk(" x_ID %Xh, type %Xh, Cdb0 %Xh\n", x_ID, - Exchanges->fcExchange[ x_ID ].type, - Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0]); - printk(" cpqfcTS: Null scsi_done function pointer!\n"); - } - - - // Now, clean up non-Scsi_Cmnd items... -CleanUpSestResources: - - if (!already_unmapped) - cpqfc_pci_unmap(pcidev, Exchanges->fcExchange[x_ID].Cmnd, - fcChip, x_ID); // undo DMA mappings. - - // Was an Extended Scatter/Gather page allocated? We know - // this by checking DWORD 4, bit 31 ("LOC") of SEST entry - if( !(fcChip->SEST->u[ x_ID ].IWE.Buff_Off & 0x80000000)) - { - PSGPAGES p, next; - - // extended S/G list was used -- Free the allocated ext. S/G pages - for (p = fcChip->SEST->sgPages[x_ID]; p != NULL; p = next) { - next = p->next; - kfree(p); - } - fcChip->SEST->sgPages[x_ID] = NULL; - } - - Exchanges->fcExchange[ x_ID ].Cmnd = NULL; - } // Done with FCP (SEST) exchanges - - - // the remaining logic is common to ALL Exchanges: - // FCP(SEST) and LinkServ. - - Exchanges->fcExchange[ x_ID ].type = 0; // there -- FREE! - Exchanges->fcExchange[ x_ID ].status = 0; - - PCI_TRACEO( x_ID, 0xAC) - - - return; -} // (END of CompleteExchange function) - - - - -// Unfortunately, we must snoop all command completions in -// order to manipulate certain return fields, and take note of -// device types, etc., to facilitate the Fibre-Channel to SCSI -// "mapping". -// (Watch for BIG Endian confusion on some payload fields) -void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID) -{ - FC_EXCHANGES *Exchanges = fcChip->Exchanges; - Scsi_Cmnd *Cmnd = Exchanges->fcExchange[ x_ID].Cmnd; - FCP_STATUS_RESPONSE *pFcpStatus = - (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl; - UCHAR ScsiStatus; - - ScsiStatus = pFcpStatus->fcp_status >>24; - -#ifdef FCP_COMPLETION_DBG - printk("ScsiStatus = 0x%X\n", ScsiStatus); -#endif - - // First, check FCP status - if( pFcpStatus->fcp_status & FCP_RSP_LEN_VALID ) - { - // check response code (RSP_CODE) -- most popular is bad len - // 1st 4 bytes of rsp info -- only byte 3 interesting - if( pFcpStatus->fcp_rsp_info & FCP_DATA_LEN_NOT_BURST_LEN ) - { - - // do we EVER get here? - printk("cpqfcTS: FCP data len not burst len, x_ID %Xh\n", x_ID); - } - } - - // for now, go by the ScsiStatus, and manipulate certain - // commands when necessary... - if( ScsiStatus == 0) // SCSI status byte "good"? - { - Cmnd->result = 0; // everything's OK - - if( (Cmnd->cmnd[0] == INQUIRY)) - { - UCHAR *InquiryData = Cmnd->request_buffer; - PFC_LOGGEDIN_PORT pLoggedInPort; - - // We need to manipulate INQUIRY - // strings for COMPAQ RAID controllers to force - // Linux to scan additional LUNs. Namely, set - // the Inquiry string byte 2 (ANSI-approved version) - // to 2. - - if( !memcmp( &InquiryData[8], "COMPAQ", 6 )) - { - InquiryData[2] = 0x2; // claim SCSI-2 compliance, - // so multiple LUNs may be scanned. - // (no SCSI-2 problems known in CPQ) - } - - // snoop the Inquiry to detect Disk, Tape, etc. type - // (search linked list for the port_id we sent INQUIRY to) - pLoggedInPort = fcFindLoggedInPort( fcChip, - NULL, // DON'T search Scsi Nexus (we will set it) - Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF, - NULL, // DON'T search linked list for FC WWN - NULL); // DON'T care about end of list - - if( pLoggedInPort ) - { - pLoggedInPort->ScsiNexus.InqDeviceType = InquiryData[0]; - } - else - { - printk("cpqfcTS: can't find LoggedIn FC port %06X for INQUIRY\n", - Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF); - } - } - } - - - // Scsi Status not good -- pass it back to caller - - else - { - Cmnd->result = ScsiStatus; // SCSI status byte is 1st - - // check for valid "sense" data - - if( pFcpStatus->fcp_status & FCP_SNS_LEN_VALID ) - { // limit Scsi Sense field length! - int SenseLen = pFcpStatus->fcp_sns_len >>24; // (BigEndian) lower byte - - SenseLen = SenseLen > sizeof( Cmnd->sense_buffer) ? - sizeof( Cmnd->sense_buffer) : SenseLen; - - -#ifdef FCP_COMPLETION_DBG - printk("copy sense_buffer %p, len %d, result %Xh\n", - Cmnd->sense_buffer, SenseLen, Cmnd->result); -#endif - - // NOTE: There is some dispute over the FCP response - // format. Most FC devices assume that FCP_RSP_INFO - // is 8 bytes long, in spite of the fact that FCP_RSP_LEN - // is (virtually) always 0 and the field is "invalid". - // Some other devices assume that - // the FCP_SNS_INFO begins after FCP_RSP_LEN bytes (i.e. 0) - // when the FCP_RSP is invalid (this almost appears to be - // one of those "religious" issues). - // Consequently, we test the usual position of FCP_SNS_INFO - // for 7Xh, since the SCSI sense format says the first - // byte ("error code") should be 0x70 or 0x71. In practice, - // we find that every device does in fact have 0x70 or 0x71 - // in the first byte position, so this test works for all - // FC devices. - // (This logic is especially effective for the CPQ/DEC HSG80 - // & HSG60 controllers). - - if( (pFcpStatus->fcp_sns_info[0] & 0x70) == 0x70 ) - memcpy( Cmnd->sense_buffer, - &pFcpStatus->fcp_sns_info[0], SenseLen); - else - { - unsigned char *sbPtr = - (unsigned char *)&pFcpStatus->fcp_sns_info[0]; - sbPtr -= 8; // back up 8 bytes hoping to find the - // start of the sense buffer - memcpy( Cmnd->sense_buffer, sbPtr, SenseLen); - } - - // in the special case of Device Reset, tell upper layer - // to immediately retry (with SOFT_ERROR status) - // look for Sense Key Unit Attention (0x6) with ASC Device - // Reset (0x29) - // printk("SenseLen %d, Key = 0x%X, ASC = 0x%X\n", - // SenseLen, Cmnd->sense_buffer[2], - // Cmnd->sense_buffer[12]); - if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) && - (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset" - { - Cmnd->result |= (DID_SOFT_ERROR << 16); // "Host" status byte 3rd - } - - // check for SenseKey "HARDWARE ERROR", ASC InternalTargetFailure - else if( ((Cmnd->sense_buffer[2] & 0xF) == 0x4) && // "hardware error" - (Cmnd->sense_buffer[12] == 0x44) ) // Addtl. Sense Code - { -// printk("HARDWARE_ERROR, Channel/Target/Lun %d/%d/%d\n", -// Cmnd->channel, Cmnd->target, Cmnd->lun); - Cmnd->result |= (DID_ERROR << 16); // "Host" status byte 3rd - } - - } // (end of sense len valid) - - // there is no sense data to help out Linux's Scsi layers... - // We'll just return the Scsi status and hope he will "do the - // right thing" - else - { - // as far as we know, the Scsi status is sufficient - Cmnd->result |= (DID_OK << 16); // "Host" status byte 3rd - } - } -} - - - -//PPPPPPPPPPPPPPPPPPPPPPPPP PAYLOAD PPPPPPPPP -// build data PAYLOAD; SCSI FCP_CMND I.U. -// remember BIG ENDIAN payload - DWord values must be byte-reversed -// (hence the affinity for byte pointer building). - -static int build_FCP_payload( Scsi_Cmnd *Cmnd, - UCHAR* payload, ULONG type, ULONG fcp_dl ) -{ - int i; - - - switch( type) - { - - case SCSI_IWE: - case SCSI_IRE: - // 8 bytes FCP_LUN - // Peripheral Device or Volume Set addressing, and LUN mapping - // When the FC port was looked up, we copied address mode - // and any LUN mask to the scratch pad SCp.phase & .mode - - *payload++ = (UCHAR)Cmnd->SCp.phase; - - // Now, because of "lun masking" - // (aka selective storage presentation), - // the contiguous Linux Scsi lun number may not match the - // device's lun number, so we may have to "map". - - *payload++ = (UCHAR)Cmnd->SCp.have_data_in; - - // We don't know of anyone in the FC business using these - // extra "levels" of addressing. In fact, confusion still exists - // just using the FIRST level... ;-) - - *payload++ = 0; // 2nd level addressing - *payload++ = 0; - *payload++ = 0; // 3rd level addressing - *payload++ = 0; - *payload++ = 0; // 4th level addressing - *payload++ = 0; - - // 4 bytes Control Field FCP_CNTL - *payload++ = 0; // byte 0: (MSB) reserved - *payload++ = 0; // byte 1: task codes - - // byte 2: task management flags - // another "use" of the spare field to accomplish TDR - // note combination needed - if( (Cmnd->cmnd[0] == RELEASE) && - (Cmnd->SCp.buffers_residual == FCP_TARGET_RESET) ) - { - Cmnd->cmnd[0] = 0; // issue "Test Unit Ready" for TDR - *payload++ = 0x20; // target device reset bit - } - else - *payload++ = 0; // no TDR - // byte 3: (LSB) execution management codes - // bit 0 write, bit 1 read (don't set together) - - if( fcp_dl != 0 ) - { - if( type == SCSI_IWE ) // WRITE - *payload++ = 1; - else // READ - *payload++ = 2; - } - else - { - // On some devices, if RD or WR bits are set, - // and fcp_dl is 0, they will generate an error on the command. - // (i.e., if direction is specified, they insist on a length). - *payload++ = 0; // no data (necessary for CPQ) - } - - - // NOTE: clean this up if/when MAX_COMMAND_SIZE is increased to 16 - // FCP_CDB allows 16 byte SCSI command descriptor blk; - // Linux SCSI CDB array is MAX_COMMAND_SIZE (12 at this time...) - for( i=0; (i < Cmnd->cmd_len) && i < MAX_COMMAND_SIZE; i++) - *payload++ = Cmnd->cmnd[i]; - - // if( Cmnd->cmd_len == 16 ) - // { - // memcpy( payload, &Cmnd->SCp.buffers_residual, 4); - // } - payload+= (16 - i); - - // FCP_DL is largest number of expected data bytes - // per CDB (i.e. read/write command) - *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL - *payload++ = (UCHAR)(fcp_dl >>16); - *payload++ = (UCHAR)(fcp_dl >>8); - *payload++ = (UCHAR)fcp_dl; // (LSB) - break; - - case SCSI_TWE: // need FCP_XFER_RDY - *payload++ = 0; // (4 bytes) DATA_RO (MSB byte 0) - *payload++ = 0; - *payload++ = 0; - *payload++ = 0; // LSB (byte 3) - // (4 bytes) BURST_LEN - // size of following FCP_DATA payload - *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL - *payload++ = (UCHAR)(fcp_dl >>16); - *payload++ = (UCHAR)(fcp_dl >>8); - *payload++ = (UCHAR)fcp_dl; // (LSB) - // 4 bytes RESERVED - *payload++ = 0; - *payload++ = 0; - *payload++ = 0; - *payload++ = 0; - break; - - default: - break; - } - - return 0; -} - From 822e5e72697ce06e4425c17d161b0482c7d9b6d4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 16:03:24 +0100 Subject: [PATCH 0971/1940] [ARM] Fix MTD device/partition destruction We should not delete MTD partitions when we registered a MTD device. Signed-off-by: Russell King --- drivers/mtd/maps/sa1100-flash.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 50a1d434906a..c38c2c311b8e 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -137,6 +137,7 @@ struct sa_info { struct mtd_partition *parts; struct mtd_info *mtd; int num_subdev; + unsigned int nr_parts; struct sa_subdev_info subdev[0]; }; @@ -228,8 +229,12 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla int i; if (info->mtd) { - del_mtd_partitions(info->mtd); - + if (info->nr_parts == 0) + del_mtd_device(info->mtd); +#ifdef CONFIG_MTD_PARTITIONS + else + del_mtd_partitions(info->mtd); +#endif #ifdef CONFIG_MTD_CONCAT if (info->mtd != info->subdev[0].mtd) mtd_concat_destroy(info->mtd); @@ -396,6 +401,8 @@ static int __init sa1100_mtd_probe(struct device *dev) add_mtd_partitions(info->mtd, parts, nr_parts); } + info->nr_parts = nr_parts; + dev_set_drvdata(dev, info); err = 0; From 14e66f767f5e8d023e098b475dc24ddc9a5dbdfd Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 16:08:31 +0100 Subject: [PATCH 0972/1940] [ARM] Allow MTD device name to be passed via platform data Allow SA1100 devices to pass the name of the flash device to the SA1100 map driver. Signed-off-by: Russell King --- arch/arm/mach-sa1100/generic.c | 2 ++ drivers/mtd/maps/sa1100-flash.c | 6 +++--- include/asm-arm/mach/flash.h | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 93619497779c..f94b0fbcdcc8 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "generic.h" @@ -283,6 +284,7 @@ static struct platform_device sa11x0mtd_device = { void sa11x0_set_flash_data(struct flash_platform_data *flash, struct resource *res, int nr) { + flash->name = "sa1100"; sa11x0mtd_device.dev.platform_data = flash; sa11x0mtd_device.resource = res; sa11x0mtd_device.num_resources = nr; diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index c38c2c311b8e..acf01ef9b575 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -301,7 +301,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) break; subdev->map.name = subdev->name; - sprintf(subdev->name, "sa1100-%d", i); + sprintf(subdev->name, "%s-%d", plat->name, i); subdev->plat = plat; ret = sa1100_probe_subdev(subdev, res); @@ -323,7 +323,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) * otherwise fail. Either way, it'll be called "sa1100". */ if (info->num_subdev == 1) { - strcpy(info->subdev[0].name, "sa1100"); + strcpy(info->subdev[0].name, plat->name); info->mtd = info->subdev[0].mtd; ret = 0; } else if (info->num_subdev > 1) { @@ -336,7 +336,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) cdev[i] = info->subdev[i].mtd; info->mtd = mtd_concat_create(cdev, info->num_subdev, - "sa1100"); + plat->name); if (info->mtd == NULL) ret = -ENXIO; #else diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h index a92887d4b2cb..cd57436d9874 100644 --- a/include/asm-arm/mach/flash.h +++ b/include/asm-arm/mach/flash.h @@ -14,6 +14,7 @@ struct mtd_partition; /* * map_name: the map probe function name + * name: flash device name (eg, as used with mtdparts=) * width: width of mapped device * init: method called at driver/device initialisation * exit: method called at driver/device removal @@ -23,6 +24,7 @@ struct mtd_partition; */ struct flash_platform_data { const char *map_name; + const char *name; unsigned int width; int (*init)(void); void (*exit)(void); From 433c357956b5a9da79d42d9128dcacc32929f2dd Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:28:56 -0400 Subject: [PATCH 0973/1940] [SCSI] lpfc: Cleanup code in lpfc_get_stats(). Cleanup white spaces in argument calls & initializations, prune if statements, remove casting and remove redundant if checks. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 445da1d0cc88..a69013a9c39a 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -223,7 +223,7 @@ lpfc_issue_lip(struct Scsi_Host *host) if (mbxstatus == MBX_TIMEOUT) pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; else - mempool_free( pmboxq, phba->mbox_mem_pool); + mempool_free(pmboxq, phba->mbox_mem_pool); if (mbxstatus == MBXERR_ERROR) return -EIO; @@ -984,7 +984,7 @@ lpfc_get_stats(struct Scsi_Host *shost) struct fc_host_statistics *hs = &phba->link_stats; LPFC_MBOXQ_t *pmboxq; MAILBOX_t *pmb; - int rc=0; + int rc = 0; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) @@ -997,18 +997,16 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->context1 = NULL; if ((phba->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){ + (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - } else + else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (pmboxq) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else - mempool_free( pmboxq, phba->mbox_mem_pool); - } + if (rc == MBX_TIMEOUT) + pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + else + mempool_free(pmboxq, phba->mbox_mem_pool); return NULL; } @@ -1019,24 +1017,22 @@ lpfc_get_stats(struct Scsi_Host *shost) hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt; hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256); - memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); + memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); pmb->mbxCommand = MBX_READ_LNK_STAT; pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; if ((phba->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) { + (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - } else + else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (pmboxq) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else - mempool_free( pmboxq, phba->mbox_mem_pool); - } + if (rc == MBX_TIMEOUT) + pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + else + mempool_free( pmboxq, phba->mbox_mem_pool); return NULL; } From 183e1a349466a1b90430a58f3efad25a3e555cb2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 16:09:59 +0100 Subject: [PATCH 0974/1940] [ARM] Add support for SA1100 Jornada flash device support This got dropped from the SA1100 flash driver a while back and never added to the platform support file. Add it back. Signed-off-by: Russell King --- arch/arm/mach-sa1100/jornada720.c | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 9c363bfcf310..89af0c831e8f 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -16,6 +18,7 @@ #include #include +#include #include #include @@ -108,6 +111,66 @@ static void __init jornada720_map_io(void) sa1100_register_uart(1, 1); } +static struct mtd_partition jornada720_partitions[] = { + { + .name = "JORNADA720 boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "JORNADA720 kernel", + .size = 0x000c0000, + .offset = 0x00040000, + }, { + .name = "JORNADA720 params", + .size = 0x00040000, + .offset = 0x00100000, + }, { + .name = "JORNADA720 initrd", + .size = 0x00100000, + .offset = 0x00140000, + }, { + .name = "JORNADA720 root cramfs", + .size = 0x00300000, + .offset = 0x00240000, + }, { + .name = "JORNADA720 usr cramfs", + .size = 0x00800000, + .offset = 0x00540000, + }, { + .name = "JORNADA720 usr local", + .size = 0, /* will expand to the end of the flash */ + .offset = 0x00d00000, + } +}; + +static void jornada720_set_vpp(int vpp) +{ + if (vpp) + PPSR |= 0x80; + else + PPSR &= ~0x80; + PPDR |= 0x80; +} + +static struct flash_platform_data jornada720_flash_data = { + .map_name = "cfi_probe", + .set_vpp = jornada720_set_vpp, + .parts = jornada720_partitions, + .nr_parts = ARRAY_SIZE(jornada720_partitions), +}; + +static struct resource jornada720_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static void __init jornada720_mach_init(void) +{ + sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1); +} + MACHINE_START(JORNADA720, "HP Jornada 720") /* Maintainer: Michael Gernoth */ .phys_ram = 0xc0000000, @@ -117,4 +180,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720") .map_io = jornada720_map_io, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, + .init_machine = jornada720_mach_init, MACHINE_END From 964b77e77666fbe9f2ca02e87c6adce0cd209971 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:01 -0400 Subject: [PATCH 0975/1940] [SCSI] lpfc: Update to Emulex hba model names Update adapter names to match Emulex naming conventions. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 25d55f40424f..ba4573912c02 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -766,10 +766,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) { lpfc_vpd_t *vp; uint32_t id; + uint8_t hdrtype; char str[16]; vp = &phba->vpd; pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id); + pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); switch ((id >> 16) & 0xffff) { case PCI_DEVICE_ID_FIREFLY: @@ -797,7 +799,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) strcpy(str, "LP9802 2"); break; case PCI_DEVICE_ID_THOR: - strcpy(str, "LP10000 2"); + if (hdrtype == 0x80) + strcpy(str, "LP10000DC 2"); + else + strcpy(str, "LP10000 2"); break; case PCI_DEVICE_ID_VIPER: strcpy(str, "LPX1000 10"); @@ -806,10 +811,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) strcpy(str, "LP982 2"); break; case PCI_DEVICE_ID_TFLY: - strcpy(str, "LP1050 2"); + if (hdrtype == 0x80) + strcpy(str, "LP1050DC 2"); + else + strcpy(str, "LP1050 2"); break; case PCI_DEVICE_ID_HELIOS: - strcpy(str, "LP11000 4"); + if (hdrtype == 0x80) + strcpy(str, "LP11002 4"); + else + strcpy(str, "LP11000 4"); break; case PCI_DEVICE_ID_BMID: strcpy(str, "LP1150 4"); @@ -818,13 +829,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) strcpy(str, "LP111 4"); break; case PCI_DEVICE_ID_ZEPHYR: - strcpy(str, "LP11000e 4"); + if (hdrtype == 0x80) + strcpy(str, "LPe11002 4"); + else + strcpy(str, "LPe11000 4"); break; case PCI_DEVICE_ID_ZMID: - strcpy(str, "LP1150e 4"); + strcpy(str, "LPe1150 4"); break; case PCI_DEVICE_ID_ZSMB: - strcpy(str, "LP111e 4"); + strcpy(str, "LPe111 4"); break; case PCI_DEVICE_ID_LP101: strcpy(str, "LP101 2"); From 755c0d06c58f7b84e9798365f806dadfef8c1839 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:06 -0400 Subject: [PATCH 0976/1940] [SCSI] lpfc: Return -EINVAL, -EPERM, and -EIO instead of 0 from sysfs callbacks Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index a69013a9c39a..45c2ba7e94c2 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -245,8 +245,6 @@ lpfc_board_online_show(struct class_device *cdev, char *buf) struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; - if (!phba) return 0; - if (phba->fc_flag & FC_OFFLINE_MODE) return snprintf(buf, PAGE_SIZE, "0\n"); else @@ -263,7 +261,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, int val=0, status=0; if (sscanf(buf, "%d", &val) != 1) - return 0; + return -EINVAL; init_completion(&online_compl); @@ -277,7 +275,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, if (!status) return strlen(buf); else - return 0; + return -EIO; } @@ -293,7 +291,7 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ return snprintf(buf, PAGE_SIZE, "%d\n",\ phba->cfg_##attr);\ }\ - return 0;\ + return -EPERM;\ } #define lpfc_param_store(attr, minval, maxval) \ @@ -308,13 +306,11 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ if (sscanf(buf, "0x%x", &val) != 1)\ if (sscanf(buf, "%d", &val) != 1)\ return -EINVAL;\ - if (phba){\ - if (val >= minval && val <= maxval) {\ - phba->cfg_##attr = val;\ - return strlen(buf);\ - }\ + if (val >= minval && val <= maxval) {\ + phba->cfg_##attr = val;\ + return strlen(buf);\ }\ - return 0;\ + return -EINVAL;\ } #define LPFC_ATTR_R_NOINIT(name, desc) \ From 7bcbb7527fb2f06b6500f6ee3e7f750a0ed0239c Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:13 -0400 Subject: [PATCH 0977/1940] [SCSI] lpfc: Add range checking for attributes passed as options at load time. Reuse macros defined for sysfs store callbacks in the initialization code in order to enforce the same range checking. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 110 ++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 45c2ba7e94c2..fd5132d62ed2 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -286,45 +286,69 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ struct Scsi_Host *host = class_to_shost(cdev);\ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ int val = 0;\ - if (phba){\ - val = phba->cfg_##attr;\ - return snprintf(buf, PAGE_SIZE, "%d\n",\ - phba->cfg_##attr);\ - }\ - return -EPERM;\ + val = phba->cfg_##attr;\ + return snprintf(buf, PAGE_SIZE, "%d\n",\ + phba->cfg_##attr);\ } -#define lpfc_param_store(attr, minval, maxval) \ +#define lpfc_param_init(attr, default, minval, maxval) \ +static int \ +lpfc_##attr##_init(struct lpfc_hba *phba, int val) \ +{ \ + if (val >= minval && val <= maxval) {\ + phba->cfg_##attr = val;\ + return 0;\ + }\ + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \ + "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", \ + phba->brd_no, val); \ + phba->cfg_##attr = default;\ + return -EINVAL;\ +} + +#define lpfc_param_set(attr, default, minval, maxval) \ +static int \ +lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ +{ \ + if (val >= minval && val <= maxval) {\ + phba->cfg_##attr = val;\ + return 0;\ + }\ + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \ + "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\ + "allowed range is ["#minval", "#maxval"]\n", \ + phba->brd_no, val); \ + return -EINVAL;\ +} + +#define lpfc_param_store(attr) \ static ssize_t \ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ { \ struct Scsi_Host *host = class_to_shost(cdev);\ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ - int val = 0;\ - if (!isdigit(buf[0]))\ - return -EINVAL;\ - if (sscanf(buf, "0x%x", &val) != 1)\ - if (sscanf(buf, "%d", &val) != 1)\ - return -EINVAL;\ - if (val >= minval && val <= maxval) {\ - phba->cfg_##attr = val;\ + int val=0;\ + if (sscanf(buf, "%d", &val) != 1)\ + return -EPERM;\ + if (lpfc_##attr##_set(phba, val) == 0) \ return strlen(buf);\ - }\ - return -EINVAL;\ + else \ + return -EINVAL;\ } -#define LPFC_ATTR_R_NOINIT(name, desc) \ -extern int lpfc_##name;\ +#define LPFC_ATTR(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ -lpfc_param_show(name)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) +lpfc_param_init(name, defval, minval, maxval) #define LPFC_ATTR_R(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_param_show(name)\ +lpfc_param_init(name, defval, minval, maxval)\ static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \ @@ -332,7 +356,9 @@ static int lpfc_##name = defval;\ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_param_show(name)\ -lpfc_param_store(name, minval, maxval)\ +lpfc_param_init(name, defval, minval, maxval)\ +lpfc_param_set(name, defval, minval, maxval)\ +lpfc_param_store(name)\ static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ lpfc_##name##_show, lpfc_##name##_store) @@ -464,14 +490,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); # is 0. Default value of cr_count is 1. The cr_count feature is disabled if # cr_delay is set to 0. */ -static int lpfc_cr_delay = 0; -module_param(lpfc_cr_delay, int , 0); -MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an " +LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an" "interrupt response is generated"); -static int lpfc_cr_count = 1; -module_param(lpfc_cr_count, int, 0); -MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an " +LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an" "interrupt response is generated"); /* @@ -487,9 +509,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); # Specifies the maximum number of ELS cmds we can have outstanding (for # discovery). Value range is [1,64]. Default value = 32. */ -static int lpfc_discovery_threads = 32; -module_param(lpfc_discovery_threads, int, 0); -MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands " +LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands" "during discovery"); /* @@ -1225,20 +1245,20 @@ struct fc_function_template lpfc_transport_functions = { void lpfc_get_cfgparam(struct lpfc_hba *phba) { - phba->cfg_log_verbose = lpfc_log_verbose; - phba->cfg_cr_delay = lpfc_cr_delay; - phba->cfg_cr_count = lpfc_cr_count; - phba->cfg_lun_queue_depth = lpfc_lun_queue_depth; - phba->cfg_fcp_class = lpfc_fcp_class; - phba->cfg_use_adisc = lpfc_use_adisc; - phba->cfg_ack0 = lpfc_ack0; - phba->cfg_topology = lpfc_topology; - phba->cfg_scan_down = lpfc_scan_down; - phba->cfg_nodev_tmo = lpfc_nodev_tmo; - phba->cfg_link_speed = lpfc_link_speed; - phba->cfg_fdmi_on = lpfc_fdmi_on; - phba->cfg_discovery_threads = lpfc_discovery_threads; - phba->cfg_max_luns = lpfc_max_luns; + lpfc_log_verbose_init(phba, lpfc_log_verbose); + lpfc_cr_delay_init(phba, lpfc_cr_delay); + lpfc_cr_count_init(phba, lpfc_cr_count); + lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); + lpfc_fcp_class_init(phba, lpfc_fcp_class); + lpfc_use_adisc_init(phba, lpfc_use_adisc); + lpfc_ack0_init(phba, lpfc_ack0); + lpfc_topology_init(phba, lpfc_topology); + lpfc_scan_down_init(phba, lpfc_scan_down); + lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); + lpfc_link_speed_init(phba, lpfc_link_speed); + lpfc_fdmi_on_init(phba, lpfc_fdmi_on); + lpfc_discovery_threads_init(phba, lpfc_discovery_threads); + lpfc_max_luns_init(phba, lpfc_max_luns); /* * The total number of segments is the configuration value plus 2 From 13bfb34c10fae6016710f5f070043c8b94b40583 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 16:14:08 +0100 Subject: [PATCH 0978/1940] [ARM] Fix Assabet reboot with SA1100 MTD map driver Unfortunately, some devices forgot to reset the flash on reboot. Arrange for the map driver to suspend & resume the flash to ensure that it is in a sane state before rebooting. Signed-off-by: Russell King --- drivers/mtd/maps/sa1100-flash.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index acf01ef9b575..c81bec7b14d5 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -440,9 +440,17 @@ static int sa1100_mtd_resume(struct device *dev) info->mtd->resume(info->mtd); return 0; } + +static void sa1100_mtd_shutdown(struct device *dev) +{ + struct sa_info *info = dev_get_drvdata(dev); + if (info && info->mtd->suspend(info->mtd) == 0) + info->mtd->resume(info->mtd); +} #else #define sa1100_mtd_suspend NULL #define sa1100_mtd_resume NULL +#define sa1100_mtd_shutdown NULL #endif static struct device_driver sa1100_mtd_driver = { @@ -452,6 +460,7 @@ static struct device_driver sa1100_mtd_driver = { .remove = __exit_p(sa1100_mtd_remove), .suspend = sa1100_mtd_suspend, .resume = sa1100_mtd_resume, + .shutdown = sa1100_mtd_shutdown, }; static int __init sa1100_mtd_init(void) From 09703d38d47d2b4ff769269ffe01c9aa340e3c8b Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:21 -0400 Subject: [PATCH 0979/1940] [SCSI] lpfc: Fix comments for nodev_tmo Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index fd5132d62ed2..98326811739a 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -434,7 +434,7 @@ LPFC_ATTR_R(scan_down, 1, 0, 1, /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear -# until the timer expires. Value range is [0,255]. Default value is 20. +# until the timer expires. Value range is [0,255]. Default value is 30. # NOTE: this MUST be less then the SCSI Layer command timeout - 1. */ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, From f91b392c4d20fcd2684587c0a091123c0409959c Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:28 -0400 Subject: [PATCH 0980/1940] [SCSI] lpfc: Fix for "Unknown IOCB command Data: x0 x3 x0 x0" Fix for "Unknown IOCB command Data: x0 x3 x0 x0" messages and inability to see devices On some platforms, the host-memory based ring mgmt area was not zero. Also, driver wasn't manipulating the entire 32bits of the ring pointers. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 1 + drivers/scsi/lpfc/lpfc_mbox.c | 7 ++++++- drivers/scsi/lpfc/lpfc_sli.c | 6 +++--- drivers/scsi/lpfc/lpfc_sli.h | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ba4573912c02..e591611f98e2 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1429,6 +1429,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (!phba->slim2p) goto out_iounmap; + memset(phba->slim2p, 0, SLI2_SLIM_SIZE); /* Initialize the SLI Layer to run with lpfc HBAs. */ lpfc_sli_setup(phba); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 73eb89f91593..31c20cc00609 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -531,6 +531,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) size_t offset; struct lpfc_hgp hgp; void __iomem *to_slim; + int i; memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); mb->mbxCommand = MBX_CONFIG_PORT; @@ -587,7 +588,11 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) /* write HGP data to SLIM at the required longword offset */ memset(&hgp, 0, sizeof(struct lpfc_hgp)); to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t)); - lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp)); + + for (i=0; i < phba->sli.num_rings; i++) { + lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp)); + to_slim += sizeof (struct lpfc_hgp); + } /* Setup Port Group ring pointer */ offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port - diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e74e224fd77c..71ff2b6a642f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -335,7 +335,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, * driver will put a command into. */ pring->cmdidx = pring->next_cmdidx; - writeb(pring->cmdidx, phba->MBslimaddr + writel(pring->cmdidx, phba->MBslimaddr + (SLIMOFF + (pring->ringno * 2)) * 4); } @@ -1033,7 +1033,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, to_slim = phba->MBslimaddr + (SLIMOFF + (pring->ringno * 2) + 1) * 4; - writeb(pring->rspidx, to_slim); + writel(pring->rspidx, to_slim); if (pring->rspidx == portRspPut) portRspPut = le32_to_cpu(pgp->rspPutInx); @@ -1147,7 +1147,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, to_slim = phba->MBslimaddr + (SLIMOFF + (pring->ringno * 2) + 1) * 4; - writeb(pring->rspidx, to_slim); + writel(pring->rspidx, to_slim); if (list_empty(&(pring->iocb_continueq))) { list_add(&rspiocbp->list, &(pring->iocb_continueq)); diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 6c74f3c85ff7..2d5b0670415c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -125,10 +125,10 @@ struct lpfc_sli_ring { uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */ uint32_t next_cmdidx; /* next_cmd index */ + uint32_t rspidx; /* current index in response ring */ + uint32_t cmdidx; /* current index in command ring */ uint8_t rsvd; uint8_t ringno; /* ring number */ - uint8_t rspidx; /* current index in response ring */ - uint8_t cmdidx; /* current index in command ring */ uint16_t numCiocb; /* number of command iocb's per ring */ uint16_t numRiocb; /* number of rsp iocb's per ring */ From 93a20f74450ca3402b3ba89fb490114cf6f2d353 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:32 -0400 Subject: [PATCH 0981/1940] [SCSI] lpfc: Restore HEX safe bahavior of the sysfs xxx_store functions. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 39 ++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 98326811739a..89e8222bc7cc 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -291,6 +291,18 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ phba->cfg_##attr);\ } +#define lpfc_param_hex_show(attr) \ +static ssize_t \ +lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +{ \ + struct Scsi_Host *host = class_to_shost(cdev);\ + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ + int val = 0;\ + val = phba->cfg_##attr;\ + return snprintf(buf, PAGE_SIZE, "%#x\n",\ + phba->cfg_##attr);\ +} + #define lpfc_param_init(attr, default, minval, maxval) \ static int \ lpfc_##attr##_init(struct lpfc_hba *phba, int val) \ @@ -329,8 +341,10 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ struct Scsi_Host *host = class_to_shost(cdev);\ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ int val=0;\ - if (sscanf(buf, "%d", &val) != 1)\ - return -EPERM;\ + if (!isdigit(buf[0]))\ + return -EINVAL;\ + if (sscanf(buf, "%i", &val) != 1)\ + return -EINVAL;\ if (lpfc_##attr##_set(phba, val) == 0) \ return strlen(buf);\ else \ @@ -362,6 +376,25 @@ lpfc_param_store(name)\ static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ lpfc_##name##_show, lpfc_##name##_store) +#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_param_hex_show(name)\ +lpfc_param_init(name, defval, minval, maxval)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) + +#define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \ +static int lpfc_##name = defval;\ +module_param(lpfc_##name, int, 0);\ +MODULE_PARM_DESC(lpfc_##name, desc);\ +lpfc_param_hex_show(name)\ +lpfc_param_init(name, defval, minval, maxval)\ +lpfc_param_set(name, defval, minval, maxval)\ +lpfc_param_store(name)\ +static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) + static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); @@ -403,7 +436,7 @@ static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, # LOG_LIBDFC 0x2000 LIBDFC events # LOG_ALL_MSG 0xffff LOG all messages */ -LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); +LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); /* # lun_queue_depth: This parameter is used to limit the number of outstanding From 21568f5387636fe2bfb9ee42383d76de11ed99c7 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:36 -0400 Subject: [PATCH 0982/1940] [SCSI] lpfc: Remove RPI hash from the driver Table was not providing a lot of value and injected a couple of errors. Removed it and made functionality inline. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 4 -- drivers/scsi/lpfc/lpfc_crtn.h | 4 -- drivers/scsi/lpfc/lpfc_disc.h | 1 - drivers/scsi/lpfc/lpfc_hbadisc.c | 87 ++++++------------------------ drivers/scsi/lpfc/lpfc_nportdisc.c | 9 ---- 5 files changed, 15 insertions(+), 90 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index adb95674823f..3062b39fbdb9 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -267,10 +267,6 @@ struct lpfc_hba { struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */ uint32_t nport_event_cnt; /* timestamp for nlplist entry */ -#define LPFC_RPI_HASH_SIZE 64 -#define LPFC_RPI_HASH_FUNC(x) ((x) & (0x3f)) - /* ptr to active D_ID / RPIs */ - struct lpfc_nodelist *fc_nlplookup[LPFC_RPI_HASH_SIZE]; uint32_t wwnn[2]; uint32_t RandomData[7]; diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index bd5135d3eee4..ffc58f9a5a59 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -62,10 +62,6 @@ void lpfc_disc_timeout(unsigned long); void lpfc_scan_timeout(unsigned long); struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); -struct lpfc_nodelist *lpfc_findnode_remove_rpi(struct lpfc_hba * phba, - uint16_t rpi); -void lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, - uint16_t rpi); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); int lpfc_do_work(void *); diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 098b8b45c7f1..084e7628ce17 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -70,7 +70,6 @@ struct lpfc_nodelist { struct timer_list nlp_tmofunc; /* Used for nodev tmo */ struct fc_rport *rport; /* Corresponding FC transport port structure */ - struct lpfc_nodelist *nlp_rpi_hash_next; struct lpfc_hba *nlp_phba; struct lpfc_work_evt nodev_timeout_evt; struct lpfc_work_evt els_retry_evt; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 6c846ad373bc..cd06d4c471ac 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -890,10 +890,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) pmb->context1 = NULL; - if (ndlp->nlp_rpi != 0) - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); ndlp->nlp_rpi = mb->un.varWords[0]; - lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi); ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); @@ -981,10 +978,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) pmb->context1 = NULL; - if (ndlp->nlp_rpi != 0) - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); ndlp->nlp_rpi = mb->un.varWords[0]; - lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi); ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); @@ -1488,7 +1482,6 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) if (rc == MBX_NOT_FINISHED) mempool_free( mbox, phba->mbox_mem_pool); } - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); lpfc_no_rpi(phba, ndlp); ndlp->nlp_rpi = 0; return 1; @@ -2434,10 +2427,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) pmb->context1 = NULL; - if (ndlp->nlp_rpi != 0) - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); ndlp->nlp_rpi = mb->un.varWords[0]; - lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi); ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); @@ -2463,75 +2453,28 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) } /* - * This routine looks up the ndlp hash - * table for the given RPI. If rpi found + * This routine looks up the ndlp lists + * for the given RPI. If rpi found * it return the node list pointer - * else return 0. + * else return NULL. */ struct lpfc_nodelist * lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) { - struct lpfc_nodelist *ret; + struct lpfc_nodelist *ndlp; + struct list_head * lists[]={&phba->fc_nlpunmap_list, + &phba->fc_nlpmap_list, + &phba->fc_plogi_list, + &phba->fc_adisc_list, + &phba->fc_reglogin_list}; + int i; - ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)]; - while ((ret != 0) && (ret->nlp_rpi != rpi)) { - ret = ret->nlp_rpi_hash_next; - } - return ret; -} + for (i = 0; i < ARRAY_SIZE(lists); i++ ) + list_for_each_entry(ndlp, lists[i], nlp_listp) + if (ndlp->nlp_rpi == rpi) + return (ndlp); -/* - * This routine looks up the ndlp hash table for the - * given RPI. If rpi found it return the node list - * pointer else return 0 after deleting the entry - * from hash table. - */ -struct lpfc_nodelist * -lpfc_findnode_remove_rpi(struct lpfc_hba * phba, uint16_t rpi) -{ - struct lpfc_nodelist *ret, *temp;; - - ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)]; - if (ret == 0) - return NULL; - - if (ret->nlp_rpi == rpi) { - phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)] = - ret->nlp_rpi_hash_next; - ret->nlp_rpi_hash_next = NULL; - return ret; - } - - while ((ret->nlp_rpi_hash_next != 0) && - (ret->nlp_rpi_hash_next->nlp_rpi != rpi)) { - ret = ret->nlp_rpi_hash_next; - } - - if (ret->nlp_rpi_hash_next != 0) { - temp = ret->nlp_rpi_hash_next; - ret->nlp_rpi_hash_next = temp->nlp_rpi_hash_next; - temp->nlp_rpi_hash_next = NULL; - return temp; - } else { - return NULL; - } -} - -/* - * This routine adds the node list entry to the - * ndlp hash table. - */ -void -lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, - uint16_t rpi) -{ - - uint32_t index; - - index = LPFC_RPI_HASH_FUNC(rpi); - ndlp->nlp_rpi_hash_next = phba->fc_nlplookup[index]; - phba->fc_nlplookup[index] = ndlp; - return; + return NULL; } void diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9b35eaac781d..9a58de876d40 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1086,11 +1086,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, return (ndlp->nlp_state); } - if (ndlp->nlp_rpi != 0) - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); - ndlp->nlp_rpi = mb->un.varWords[0]; - lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi); /* Only if we are not a fabric nport do we issue PRLI */ if (!(ndlp->nlp_type & NLP_FABRIC)) { @@ -1593,12 +1589,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, pmb = (LPFC_MBOXQ_t *) arg; mb = &pmb->mb; - /* save rpi */ - if (ndlp->nlp_rpi != 0) - lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi); - ndlp->nlp_rpi = mb->un.varWords[0]; - lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi); return (ndlp->nlp_state); } From 931db7d6880027bb2b6b0cb78a488ab1486e28b7 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 29 Oct 2005 16:28:26 +0100 Subject: [PATCH 0983/1940] [ARM] 3050/1: remove ixp2000_reg_write erratum #66 workaround Patch from Lennert Buytenhek The workaround that we do for avoiding triggering ixp2400 erratum #66 involves mapping I/O pages using XCB=101 instead of XCB=000 so that we prevent the I/O signal to the gasket from being asserted (which can cause data corruption.) But XCB=101 mappings are write-buffered while mappings using XCB=000 are not, which is why if we use XCB=101 mappings we do a readback for every CSR store in an attempt to make sure that the store has been pushed out of the xscale core and the gasket. Unfortunately, there are two issues with this: - we do a readback for every CSR store, which is wrong, because the register we are writing to might have unwanted side-effects on read, for example, in the case of the scratchpad ring enqueue/dequeue registers; and - the readback is totally ineffective in the way we currently do it, because we just issue a load but do not issue any instruction that depends on the return value of that load, so the xscale core does not wait for the load to complete before continuing. See this linux-arm-kernel mailing list post for further information: http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2005-September/031314.html This means that my ixp2400 boxes have been running for many months without a working readback in ixp2000_reg_write, without any apparent adverse effects. Two of them have been running for a week now with the actual readback deleted from ixp2000_reg_write, also without any apparent ill effects. So, because in its current form it does more harm than good, the readback in ixp2000_reg_write should simply be killed, as the patch below does. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp2000/platform.h | 29 ------------------------- 1 file changed, 29 deletions(-) diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index abdcf51bd283..aabeef2454dd 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h @@ -15,39 +15,10 @@ #ifndef __ASSEMBLY__ -/* - * The IXP2400 B0 silicon contains an erratum (#66) that causes writes - * to on-chip I/O register to not complete fully. What this means is - * that if you have a write to on-chip I/O followed by a back-to-back - * read or write, the first write will happen twice. OR...if it's - * not a back-to-back transaction, the read or write will generate - * incorrect data. - * - * The official work around for this is to set the on-chip I/O regions - * as XCB=101 and then force a read-back from the register. - * - */ -#if defined(CONFIG_ARCH_ENP2611) || defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401) - -#include /* Pickup local_irq_ functions */ - -static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) -{ - unsigned long dummy; - unsigned long flags; - - local_irq_save(flags); - *((volatile unsigned long *)reg) = val; - barrier(); - dummy = *((volatile unsigned long *)reg); - local_irq_restore(flags); -} -#else static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) { *((volatile unsigned long *)reg) = val; } -#endif /* IXDP2400 || IXDP2401 */ #define ixp2000_reg_read(reg) (*((volatile unsigned long *)reg)) /* From ecbea7a2dae94092db9566bcd1f38535e9b3cde9 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 29 Oct 2005 16:28:27 +0100 Subject: [PATCH 0984/1940] [ARM] 3051/1: turn ixp2000_reg_read into an inline function Patch from Lennert Buytenhek Turn ixp2000_reg_read into an inline function. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp2000/platform.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index aabeef2454dd..6e5b6a955abe 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h @@ -15,11 +15,15 @@ #ifndef __ASSEMBLY__ +static inline unsigned long ixp2000_reg_read(volatile void *reg) +{ + return *((volatile unsigned long *)reg); +} + static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) { *((volatile unsigned long *)reg) = val; } -#define ixp2000_reg_read(reg) (*((volatile unsigned long *)reg)) /* * Boards may multiplex different devices on the 2nd channel of From b4a1f67fbfb848ded8cf0c6c305224534144ab2d Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 29 Oct 2005 16:28:28 +0100 Subject: [PATCH 0985/1940] [ARM] 3053/1: introduce ixp2000_reg_wrb (ixp2000_reg_write plus readback) Patch from Lennert Buytenhek Introduce ixp2000_reg_wrb, which is a variant of ixp2000_reg_write that does a readback from the target register, to make sure that the write has been flushed out of the write buffer. Unlike the previous (ineffective) readback in ixp2000_reg_write, this readback is followed by an instruction that depends on the value of the readback so that the CPU actually stalls until the readback has completed. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp2000/platform.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index 6e5b6a955abe..a66317ab2071 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h @@ -25,6 +25,31 @@ static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) *((volatile unsigned long *)reg) = val; } +/* + * On the IXP2400, we can't use XCB=000 due to chip bugs. We use + * XCB=101 instead, but that makes all I/O accesses bufferable. This + * is not a problem in general, but we do have to be slightly more + * careful because I/O writes are no longer automatically flushed out + * of the write buffer. + * + * In cases where we want to make sure that a write has been flushed + * out of the write buffer before we proceed, for example when masking + * a device interrupt before re-enabling IRQs in CPSR, we can use this + * function, ixp2000_reg_wrb, which performs a write, a readback, and + * issues a dummy instruction dependent on the value of the readback + * (mov rX, rX) to make sure that the readback has completed before we + * continue. + */ +static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val) +{ + unsigned long dummy; + + *((volatile unsigned long *)reg) = val; + + dummy = *((volatile unsigned long *)reg); + __asm__ __volatile__("mov %0, %0" : "+r" (dummy)); +} + /* * Boards may multiplex different devices on the 2nd channel of * the slowport interface that each need different configuration From 1a47ebc0d971fbc47cd859a09956f7c7d001f5fd Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 29 Oct 2005 16:28:29 +0100 Subject: [PATCH 0986/1940] [ARM] 3059/1: fix XIP support Patch from Nicolas Pitre Fix XIP support after recent bootmem code refactoring. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mm/init.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index f4496813615a..fd079ff1fc53 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -363,20 +363,16 @@ static void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); -#ifdef CONFIG_XIP_KERNEL -#error needs fixing - p->pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PMD_MASK); - p->virtual = (unsigned long)&_stext & PMD_MASK; - p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; - p->type = MT_ROM; - p ++; -#endif - /* * Clear out all the mappings below the kernel image. - * FIXME: what about XIP? */ - for (addr = 0; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) pmd_clear(pmd_off_k(addr)); /* @@ -435,6 +431,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc) for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) pmd_clear(pmd_off_k(addr)); + /* + * Map the kernel if it is XIP. + * It is always first in the modulearea. + */ +#ifdef CONFIG_XIP_KERNEL + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK); + map.virtual = MODULE_START; + map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK; + map.type = MT_ROM; + create_mapping(&map); +#endif + /* * Map the cache flushing regions. */ From 604a3e3042eb89ffaa4f735ef9208281aae786c7 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 29 Oct 2005 10:28:33 -0500 Subject: [PATCH 0987/1940] [SCSI] lpfc: Fix for "command completion for iotax x?? not found" From: James Smart There were scenarios where the error handlers could reuse an iotag value of an active io. Remove all possibility of this by pre-assigning iotag resources to command resources. Signed-off-by: James Smart Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_ct.c | 9 +- drivers/scsi/lpfc/lpfc_els.c | 30 ++-- drivers/scsi/lpfc/lpfc_hbadisc.c | 7 +- drivers/scsi/lpfc/lpfc_init.c | 17 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 12 +- drivers/scsi/lpfc/lpfc_scsi.c | 27 +-- drivers/scsi/lpfc/lpfc_sli.c | 279 +++++++++++++---------------- drivers/scsi/lpfc/lpfc_sli.h | 8 + 9 files changed, 186 insertions(+), 205 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ffc58f9a5a59..25f2650f098c 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -143,6 +143,8 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); int lpfc_mem_alloc(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *); +void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); +uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); int lpfc_sli_hba_setup(struct lpfc_hba *); int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1280f0e54636..40c34a30a94a 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -235,7 +235,6 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, if (geniocb == NULL) return 1; - memset(geniocb, 0, sizeof (struct lpfc_iocbq)); icmd = &geniocb->iocb; icmd->un.genreq64.bdl.ulpIoTag32 = 0; @@ -279,7 +278,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { - list_add_tail(&geniocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, geniocb); spin_unlock_irq(phba->host->host_lock); return 1; } @@ -487,7 +486,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); - list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return; } @@ -526,7 +525,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); - list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return; } @@ -735,7 +734,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); - list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return; } diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 63caf7fe9725..e931ae6e7464 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -122,7 +122,6 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, if (elsiocb == NULL) return NULL; - memset(elsiocb, 0, sizeof (struct lpfc_iocbq)); icmd = &elsiocb->iocb; /* fill in BDEs for command */ @@ -133,7 +132,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, if (pcmd) kfree(pcmd); - list_add_tail(&elsiocb->list, lpfc_iocb_list); + spin_lock_irq(phba->host->host_lock); + lpfc_sli_release_iocbq(phba, elsiocb); + spin_unlock_irq(phba->host->host_lock); return NULL; } @@ -150,7 +151,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, kfree(prsp); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); kfree(pcmd); - list_add_tail(&elsiocb->list, lpfc_iocb_list); + spin_lock_irq(phba->host->host_lock); + lpfc_sli_release_iocbq(phba, elsiocb); + spin_unlock_irq(phba->host->host_lock); return NULL; } INIT_LIST_HEAD(&prsp->list); @@ -164,7 +167,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pbuflist->phys); if (pbuflist == 0 || pbuflist->virt == 0) { - list_add_tail(&elsiocb->list, lpfc_iocb_list); + spin_lock_irq(phba->host->host_lock); + lpfc_sli_release_iocbq(phba, elsiocb); + spin_unlock_irq(phba->host->host_lock); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); lpfc_mbuf_free(phba, prsp->virt, prsp->phys); kfree(pcmd); @@ -596,10 +601,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&iocb->list, - &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); } } } @@ -1713,7 +1716,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) kfree(buf_ptr); } spin_lock_irq(phba->host->host_lock); - list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, elsiocb); spin_unlock_irq(phba->host->host_lock); return 0; } @@ -2929,9 +2932,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) spin_unlock_irq(phba->host->host_lock); (piocb->iocb_cmpl) (phba, piocb, piocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&piocb->list, &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, piocb); } if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { phba->els_tmofunc.expires = jiffies + HZ * timeout; @@ -2996,7 +2998,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) spin_lock_irq(phba->host->host_lock); } else - list_add_tail(&piocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, piocb); } list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { @@ -3033,7 +3035,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) spin_lock_irq(phba->host->host_lock); } else - list_add_tail(&piocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, piocb); } spin_unlock_irq(phba->host->host_lock); return; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index cd06d4c471ac..259eeb161b82 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1445,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) iocb, iocb); spin_lock_irq(phba->host-> host_lock); - } else { - list_add_tail(&iocb->list, - &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, + iocb); } } spin_unlock_irq(phba->host->host_lock); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e591611f98e2..59e244f04c32 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -886,7 +886,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, pring->missbufcnt = cnt; return cnt; } - memset(iocb, 0, sizeof (struct lpfc_iocbq)); icmd = &iocb->iocb; /* 2 buffers can be posted per command */ @@ -899,7 +898,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, if (mp1) kfree(mp1); spin_lock_irq(phba->host->host_lock); - list_add_tail(&iocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, iocb); spin_unlock_irq(phba->host->host_lock); pring->missbufcnt = cnt; return cnt; @@ -918,7 +917,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, lpfc_mbuf_free(phba, mp1->virt, mp1->phys); kfree(mp1); spin_lock_irq(phba->host->host_lock); - list_add_tail(&iocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, iocb); spin_unlock_irq(phba->host->host_lock); pring->missbufcnt = cnt; return cnt; @@ -955,7 +954,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, kfree(mp2); cnt++; } - list_add_tail(&iocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, iocb); pring->missbufcnt = cnt; spin_unlock_irq(phba->host->host_lock); return cnt; @@ -1328,6 +1327,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) unsigned long bar0map_len, bar2map_len; int error = -ENODEV, retval; int i; + uint16_t iotag; if (pci_enable_device(pdev)) goto out; @@ -1452,6 +1452,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) } memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq)); + iotag = lpfc_sli_next_iotag(phba, iocbq_entry); + if (iotag == 0) { + kfree (iocbq_entry); + printk(KERN_ERR "%s: failed to allocate IOTAG. " + "Unloading driver.\n", + __FUNCTION__); + error = -ENOMEM; + goto out_free_iocbq; + } spin_lock_irq(phba->host->host_lock); list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); phba->total_iocbq_bufs++; diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9a58de876d40..507a6af56f42 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -187,10 +187,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&iocb->list, - &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); break; } } @@ -232,10 +230,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&iocb->list, - &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); break; } } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c55ab1a630e5..51c6b677490c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -56,6 +56,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) struct ulp_bde64 *bpl; IOCB_t *iocb; dma_addr_t pdma_phys; + uint16_t iotag; psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); if (!psb) @@ -79,6 +80,15 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) /* Initialize virtual ptrs to dma_buf region. */ memset(psb->data, 0, phba->cfg_sg_dma_buf_size); + /* Allocate iotag for psb->cur_iocbq. */ + iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq); + if (iotag == 0) { + pci_pool_free(phba->lpfc_scsi_dma_buf_pool, + psb->data, psb->dma_handle); + kfree (psb); + return NULL; + } + psb->fcp_cmnd = psb->data; psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) + @@ -626,7 +636,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); if (!iocbqrsp) return FAILED; - memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq)); iocbq->iocb_flag |= LPFC_IO_POLL; ret = lpfc_sli_issue_iocb_wait_high_priority(phba, @@ -655,8 +664,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) lpfc_cmd->pCmd->device->id, lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT); - /* Return response IOCB to free list. */ - list_add_tail(&iocbqrsp->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, iocbqrsp); return ret; } @@ -818,9 +826,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) list_del_init(&iocb->list); pring->txq_cnt--; - if (!iocb->iocb_cmpl) { - list_add_tail(&iocb->list, lpfc_iocb_list); - } + if (!iocb->iocb_cmpl) + lpfc_sli_release_iocbq(phba, iocb); else { cmd->ulpStatus = IOSTAT_LOCAL_REJECT; cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; @@ -834,8 +841,6 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) if (abtsiocb == NULL) return FAILED; - memset(abtsiocb, 0, sizeof (struct lpfc_iocbq)); - /* * The scsi command was not in the txq. Check the txcmplq and if it is * found, send an abort to the FW. @@ -861,7 +866,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { - list_add_tail(&abtsiocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, abtsiocb); ret = IOCB_ERROR; break; } @@ -964,8 +969,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (iocbqrsp == NULL) goto out_free_scsi_buf; - memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq)); - iocbq->iocb_flag |= LPFC_IO_POLL; iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; @@ -1011,7 +1014,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) phba->brd_no, cnt); } - list_add_tail(&iocbqrsp->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, iocbqrsp); out_free_scsi_buf: lpfc_printf_log(phba, KERN_ERR, LOG_FCP, diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 71ff2b6a642f..a8097e6c9dce 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -65,6 +65,18 @@ typedef enum _lpfc_iocb_type { LPFC_ABORT_IOCB } lpfc_iocb_type; +void +lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) +{ + size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb); + + /* + * Clean all volatile data fields, preserve iotag and node struct. + */ + memset((char*)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean); + list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); +} + /* * Translate the iocb command to an iocb command type used to decide the final * disposition of each completed IOCB. @@ -265,41 +277,69 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return iocb; } -static uint32_t -lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) +uint16_t +lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) { - uint32_t search_start; + struct lpfc_iocbq ** new_arr; + struct lpfc_iocbq ** old_arr; + size_t new_len; + struct lpfc_sli *psli = &phba->sli; + uint16_t iotag; - if (pring->fast_lookup == NULL) { - pring->iotag_ctr++; - if (pring->iotag_ctr >= pring->iotag_max) - pring->iotag_ctr = 1; - return pring->iotag_ctr; + spin_lock_irq(phba->host->host_lock); + iotag = psli->last_iotag; + if(++iotag < psli->iocbq_lookup_len) { + psli->last_iotag = iotag; + psli->iocbq_lookup[iotag] = iocbq; + spin_unlock_irq(phba->host->host_lock); + iocbq->iotag = iotag; + return iotag; + } + else if (psli->iocbq_lookup_len < (0xffff + - LPFC_IOCBQ_LOOKUP_INCREMENT)) { + new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT; + spin_unlock_irq(phba->host->host_lock); + new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *), + GFP_KERNEL); + if (new_arr) { + memset((char *)new_arr, 0, + new_len * sizeof (struct lpfc_iocbq *)); + spin_lock_irq(phba->host->host_lock); + old_arr = psli->iocbq_lookup; + if (new_len <= psli->iocbq_lookup_len) { + /* highly unprobable case */ + kfree(new_arr); + iotag = psli->last_iotag; + if(++iotag < psli->iocbq_lookup_len) { + psli->last_iotag = iotag; + psli->iocbq_lookup[iotag] = iocbq; + spin_unlock_irq(phba->host->host_lock); + iocbq->iotag = iotag; + return iotag; + } + spin_unlock_irq(phba->host->host_lock); + return 0; + } + if (psli->iocbq_lookup) + memcpy(new_arr, old_arr, + ((psli->last_iotag + 1) * + sizeof (struct lpfc_iocbq *))); + psli->iocbq_lookup = new_arr; + psli->iocbq_lookup_len = new_len; + psli->last_iotag = iotag; + psli->iocbq_lookup[iotag] = iocbq; + spin_unlock_irq(phba->host->host_lock); + iocbq->iotag = iotag; + kfree(old_arr); + return iotag; + } } - search_start = pring->iotag_ctr; + lpfc_printf_log(phba, KERN_ERR,LOG_SLI, + "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n", + phba->brd_no, psli->last_iotag); - do { - pring->iotag_ctr++; - if (pring->iotag_ctr >= pring->fast_iotag) - pring->iotag_ctr = 1; - - if (*(pring->fast_lookup + pring->iotag_ctr) == NULL) - return pring->iotag_ctr; - - } while (pring->iotag_ctr != search_start); - - /* - * Outstanding I/O count for ring is at max - */ - lpfc_printf_log(phba, - KERN_ERR, - LOG_SLI, - "%d:0318 Outstanding I/O count for ring %d is at max x%x\n", - phba->brd_no, - pring->ringno, - pring->fast_iotag); - return (0); + return 0; } static void @@ -307,10 +347,9 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, IOCB_t *iocb, struct lpfc_iocbq *nextiocb) { /* - * Allocate and set up an iotag + * Set up an iotag */ - nextiocb->iocb.ulpIoTag = - lpfc_sli_next_iotag(phba, &phba->sli.ring[phba->sli.fcp_ring]); + nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0; /* * Issue iocb command to adapter @@ -326,9 +365,8 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, */ if (nextiocb->iocb_cmpl) lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb); - else { - list_add_tail(&nextiocb->list, &phba->lpfc_iocb_list); - } + else + lpfc_sli_release_iocbq(phba, nextiocb); /* * Let the HBA know what IOCB slot will be the next one the @@ -752,80 +790,28 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } static struct lpfc_iocbq * -lpfc_sli_txcmpl_ring_search_slow(struct lpfc_sli_ring * pring, - struct lpfc_iocbq * prspiocb) +lpfc_sli_iocbq_lookup(struct lpfc_hba * phba, + struct lpfc_sli_ring * pring, + struct lpfc_iocbq * prspiocb) { - IOCB_t *icmd = NULL; - IOCB_t *irsp = NULL; - struct lpfc_iocbq *cmd_iocb; - struct lpfc_iocbq *iocb, *next_iocb; - uint16_t iotag; - - irsp = &prspiocb->iocb; - iotag = irsp->ulpIoTag; - cmd_iocb = NULL; - - /* Search through txcmpl from the begining */ - list_for_each_entry_safe(iocb, next_iocb, &(pring->txcmplq), list) { - icmd = &iocb->iocb; - if (iotag == icmd->ulpIoTag) { - /* Found a match. */ - cmd_iocb = iocb; - list_del(&iocb->list); - pring->txcmplq_cnt--; - break; - } - } - - return (cmd_iocb); -} - -static struct lpfc_iocbq * -lpfc_sli_txcmpl_ring_iotag_lookup(struct lpfc_hba * phba, - struct lpfc_sli_ring * pring, - struct lpfc_iocbq * prspiocb) -{ - IOCB_t *irsp = NULL; struct lpfc_iocbq *cmd_iocb = NULL; uint16_t iotag; - if (unlikely(pring->fast_lookup == NULL)) - return NULL; + iotag = prspiocb->iocb.ulpIoTag; - /* Use fast lookup based on iotag for completion */ - irsp = &prspiocb->iocb; - iotag = irsp->ulpIoTag; - if (iotag < pring->fast_iotag) { - cmd_iocb = *(pring->fast_lookup + iotag); - *(pring->fast_lookup + iotag) = NULL; - if (cmd_iocb) { - list_del(&cmd_iocb->list); - pring->txcmplq_cnt--; - return cmd_iocb; - } else { - /* - * This is clearly an error. A ring that uses iotags - * should never have a interrupt for a completion that - * is not on the ring. Return NULL and log a error. - */ - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0327 Rsp ring %d error - command " - "completion for iotag x%x not found\n", - phba->brd_no, pring->ringno, iotag); - return NULL; - } + if (iotag != 0 && iotag <= phba->sli.last_iotag) { + cmd_iocb = phba->sli.iocbq_lookup[iotag]; + list_del(&cmd_iocb->list); + pring->txcmplq_cnt--; + return cmd_iocb; } - /* - * Rsp ring get: iotag greater then - * configured max wd0 . This is an - * error. Just return NULL. - */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0317 Rsp ring %d get: iotag x%x greater then " - "configured max x%x wd0 x%x\n", - phba->brd_no, pring->ringno, iotag, pring->fast_iotag, - *(((uint32_t *) irsp) + 7)); + "%d:0317 iotag x%x is out off " + "range: max iotag x%x wd0 x%x\n", + phba->brd_no, iotag, + phba->sli.last_iotag, + *(((uint32_t *) &prspiocb->iocb) + 7)); return NULL; } @@ -839,7 +825,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, /* Based on the iotag field, get the cmd IOCB from the txcmplq */ spin_lock_irqsave(phba->host->host_lock, iflag); - cmdiocbp = lpfc_sli_txcmpl_ring_search_slow(pring, saveq); + cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq); if (cmdiocbp) { if (cmdiocbp->iocb_cmpl) { /* @@ -861,9 +847,8 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); spin_lock_irqsave(phba->host->host_lock, iflag); } - } else { - list_add_tail(&cmdiocbp->list, &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, cmdiocbp); } else { /* * Unknown initiating command based on the response iotag. @@ -990,9 +975,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, break; } - cmdiocbq = lpfc_sli_txcmpl_ring_iotag_lookup(phba, - pring, - &rspiocbq); + cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, + &rspiocbq); if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { spin_unlock_irqrestore( phba->host->host_lock, iflag); @@ -1213,8 +1197,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, } else if (type == LPFC_ABORT_IOCB) { if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && ((cmdiocbp = - lpfc_sli_txcmpl_ring_search_slow(pring, - saveq)))) { + lpfc_sli_iocbq_lookup(phba, pring, + saveq)))) { /* Call the specified completion routine */ if (cmdiocbp->iocb_cmpl) { @@ -1226,10 +1210,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, spin_lock_irqsave( phba->host->host_lock, iflag); - } else { - list_add_tail(&cmdiocbp->list, - lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, + cmdiocbp); } } else if (type == LPFC_UNKNOWN_IOCB) { if (irsp->ulpCommand == CMD_ADAPTER_MSG) { @@ -1264,12 +1247,12 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, next_iocb, &saveq->list, list) { - list_add_tail(&rspiocbp->list, - lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, + rspiocbp); } } - list_add_tail(&saveq->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, saveq); } } @@ -1314,7 +1297,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) struct lpfc_iocbq *iocb, *next_iocb; IOCB_t *icmd = NULL, *cmd = NULL; int errcnt; - uint16_t iotag; errcnt = 0; @@ -1331,9 +1313,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&iocb->list, &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); } pring->txq_cnt = 0; INIT_LIST_HEAD(&(pring->txq)); @@ -1343,13 +1324,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) cmd = &iocb->iocb; /* - * Imediate abort of IOCB, clear fast_lookup entry, - * if any, deque and call compl + * Imediate abort of IOCB, deque and call compl */ - iotag = cmd->ulpIoTag; - if (iotag && pring->fast_lookup && - (iotag < pring->fast_iotag)) - pring->fast_lookup[iotag] = NULL; list_del_init(&iocb->list); pring->txcmplq_cnt--; @@ -1360,9 +1336,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irq(phba->host->host_lock); - } else { - list_add_tail(&iocb->list, &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); } INIT_LIST_HEAD(&pring->txcmplq); @@ -2147,6 +2122,10 @@ lpfc_sli_setup(struct lpfc_hba *phba) psli->next_ring = LPFC_FCP_NEXT_RING; psli->ip_ring = LPFC_IP_RING; + psli->iocbq_lookup = NULL; + psli->iocbq_lookup_len = 0; + psli->last_iotag = 0; + for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; switch (i) { @@ -2222,7 +2201,7 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) { struct lpfc_sli *psli; struct lpfc_sli_ring *pring; - int i, cnt; + int i; psli = &phba->sli; spin_lock_irq(phba->host->host_lock); @@ -2238,19 +2217,6 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) INIT_LIST_HEAD(&pring->txcmplq); INIT_LIST_HEAD(&pring->iocb_continueq); INIT_LIST_HEAD(&pring->postbufq); - cnt = pring->fast_iotag; - spin_unlock_irq(phba->host->host_lock); - if (cnt) { - pring->fast_lookup = - kmalloc(cnt * sizeof (struct lpfc_iocbq *), - GFP_KERNEL); - if (pring->fast_lookup == 0) { - return (0); - } - memset((char *)pring->fast_lookup, 0, - cnt * sizeof (struct lpfc_iocbq *)); - } - spin_lock_irq(phba->host->host_lock); } spin_unlock_irq(phba->host->host_lock); return (1); @@ -2292,10 +2258,8 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) flags); (iocb->iocb_cmpl) (phba, iocb, iocb); spin_lock_irqsave(phba->host->host_lock, flags); - } else { - list_add_tail(&iocb->list, - &phba->lpfc_iocb_list); - } + } else + lpfc_sli_release_iocbq(phba, iocb); } INIT_LIST_HEAD(&(pring->txq)); @@ -2436,7 +2400,7 @@ lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, kfree(buf_ptr); } - list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, cmdiocb); return; } @@ -2454,7 +2418,6 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list); if (abtsiocbp == NULL) return 0; - memset(abtsiocbp, 0, sizeof (struct lpfc_iocbq)); iabt = &abtsiocbp->iocb; icmd = &cmdiocb->iocb; @@ -2473,7 +2436,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl; break; default: - list_add_tail(&abtsiocbp->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, abtsiocbp); return 0; } @@ -2485,7 +2448,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, iabt->ulpCommand = CMD_ABORT_MXRI64_CN; if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) { - list_add_tail(&abtsiocbp->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, abtsiocbp); return 0; } @@ -2563,7 +2526,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { spin_lock_irq(phba->host->host_lock); - list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return; } @@ -2604,7 +2567,6 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, errcnt++; continue; } - memset(abtsiocb, 0, sizeof (struct lpfc_iocbq)); abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext; @@ -2621,7 +2583,7 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0); if (ret_val == IOCB_ERROR) { - list_add_tail(&abtsiocb->list, lpfc_iocb_list); + lpfc_sli_release_iocbq(phba, abtsiocb); errcnt++; continue; } @@ -2635,8 +2597,9 @@ lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, struct lpfc_iocbq * queue1, struct lpfc_iocbq * queue2) { - if (queue1->context2 && queue2) - memcpy(queue1->context2, queue2, sizeof (struct lpfc_iocbq)); + struct lpfc_iocbq *save_iocbq = queue1->context2; + if (save_iocbq && queue2) + memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb)); /* The waiter is looking for LPFC_IO_HIPRI bit to be set as a signal to wake up */ diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 2d5b0670415c..5d8911de4faa 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -33,6 +33,9 @@ typedef enum _lpfc_ctx_cmd { struct lpfc_iocbq { /* lpfc_iocbqs are used in double linked lists */ struct list_head list; + uint16_t iotag; /* pre-assigned IO tag */ + uint16_t rsvd1; + IOCB_t iocb; /* IOCB cmd */ uint8_t retry; /* retry counter for IOCB cmd - if needed */ uint8_t iocb_flag; @@ -200,6 +203,11 @@ struct lpfc_sli { cmd */ uint32_t *MBhostaddr; /* virtual address for mbox cmds */ + +#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024 + struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ + size_t iocbq_lookup_len; /* current lengs of the array */ + uint16_t last_iotag; /* last allocated IOTAG */ }; /* Given a pointer to the start of the ring, and the slot number of From 68876920f442912c94f749bc337c888696cb9ed0 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:47 -0400 Subject: [PATCH 0988/1940] [SCSI] lpfc: Replace lpfc_sli_issue_iocb_wait_high_priority Replace lpfc_sli_issue_iocb_wait_high_priority with lpfc_sli_issue_iocb_wait. Simplify code paths, as there really wasn't a "priority" Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_crtn.h | 14 ++-- drivers/scsi/lpfc/lpfc_scsi.c | 19 ++--- drivers/scsi/lpfc/lpfc_sli.c | 137 +++++++++++++++++++--------------- drivers/scsi/lpfc/lpfc_sli.h | 9 +-- 4 files changed, 89 insertions(+), 90 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 25f2650f098c..e16025d76aa2 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -180,15 +180,11 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout); -int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, - struct lpfc_sli_ring * pring, - struct lpfc_iocbq * piocb, - uint32_t flag, - struct lpfc_iocbq * prspiocbq, - uint32_t timeout); -void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, - struct lpfc_iocbq * queue1, - struct lpfc_iocbq * queue2); +int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, + struct lpfc_sli_ring * pring, + struct lpfc_iocbq * piocb, + struct lpfc_iocbq * prspiocbq, + uint32_t timeout); void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 51c6b677490c..c993069a6500 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -637,12 +637,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) if (!iocbqrsp) return FAILED; - iocbq->iocb_flag |= LPFC_IO_POLL; - ret = lpfc_sli_issue_iocb_wait_high_priority(phba, - &phba->sli.ring[phba->sli.fcp_ring], - iocbq, SLI_IOCB_HIGH_PRIORITY, - iocbqrsp, - lpfc_cmd->timeout); + ret = lpfc_sli_issue_iocb_wait(phba, + &phba->sli.ring[phba->sli.fcp_ring], + iocbq, iocbqrsp, lpfc_cmd->timeout); if (ret != IOCB_SUCCESS) { lpfc_cmd->status = IOSTAT_DRIVER_REJECT; ret = FAILED; @@ -922,7 +919,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; - struct lpfc_sli *psli = &phba->sli; struct lpfc_scsi_buf *lpfc_cmd = NULL; struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; @@ -969,12 +965,9 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (iocbqrsp == NULL) goto out_free_scsi_buf; - iocbq->iocb_flag |= LPFC_IO_POLL; - iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; - - ret = lpfc_sli_issue_iocb_wait_high_priority(phba, - &phba->sli.ring[psli->fcp_ring], - iocbq, 0, iocbqrsp, 60); + ret = lpfc_sli_issue_iocb_wait(phba, + &phba->sli.ring[phba->sli.fcp_ring], + iocbq, iocbqrsp, lpfc_cmd->timeout); if (ret == IOCB_SUCCESS) ret = SUCCESS; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a8097e6c9dce..e09398dbe779 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -839,9 +839,6 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, spin_lock_irqsave(phba->host->host_lock, iflag); } else { - if (cmdiocbp->iocb_flag & LPFC_IO_POLL) - rc = 0; - spin_unlock_irqrestore(phba->host->host_lock, iflag); (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); @@ -874,6 +871,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, saveq->iocb.ulpContext); } } + spin_unlock_irqrestore(phba->host->host_lock, iflag); return rc; } @@ -2592,84 +2590,99 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return errcnt; } -void -lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba, - struct lpfc_iocbq * queue1, - struct lpfc_iocbq * queue2) +static void +lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, + struct lpfc_iocbq *cmdiocbq, + struct lpfc_iocbq *rspiocbq) { - struct lpfc_iocbq *save_iocbq = queue1->context2; - if (save_iocbq && queue2) - memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb)); + wait_queue_head_t *pdone_q; + unsigned long iflags; - /* The waiter is looking for LPFC_IO_HIPRI bit to be set - as a signal to wake up */ - queue1->iocb_flag |= LPFC_IO_HIPRI; + spin_lock_irqsave(phba->host->host_lock, iflags); + cmdiocbq->iocb_flag |= LPFC_IO_WAKE; + if (cmdiocbq->context2 && rspiocbq) + memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, + &rspiocbq->iocb, sizeof(IOCB_t)); + + pdone_q = cmdiocbq->context_un.wait_queue; + spin_unlock_irqrestore(phba->host->host_lock, iflags); + if (pdone_q) + wake_up(pdone_q); return; } +/* + * Issue the caller's iocb and wait for its completion, but no longer than the + * caller's timeout. Note that iocb_flags is cleared before the + * lpfc_sli_issue_call since the wake routine sets a unique value and by + * definition this is a wait function. + */ int -lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba, - struct lpfc_sli_ring * pring, - struct lpfc_iocbq * piocb, - uint32_t flag, - struct lpfc_iocbq * prspiocbq, - uint32_t timeout) +lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, + struct lpfc_sli_ring * pring, + struct lpfc_iocbq * piocb, + struct lpfc_iocbq * prspiocbq, + uint32_t timeout) { - int j, delay_time, retval = IOCB_ERROR; - - /* The caller must left context1 empty. */ - if (piocb->context_un.hipri_wait_queue != 0) { - return IOCB_ERROR; - } + DECLARE_WAIT_QUEUE_HEAD(done_q); + long timeleft, timeout_req = 0; + int retval = IOCB_SUCCESS; /* - * If the caller has provided a response iocbq buffer, context2 must - * be NULL or its an error. + * If the caller has provided a response iocbq buffer, then context2 + * is NULL or its an error. */ - if (prspiocbq && piocb->context2) { - return IOCB_ERROR; + if (prspiocbq) { + if (piocb->context2) + return IOCB_ERROR; + piocb->context2 = prspiocbq; } - piocb->context2 = prspiocbq; + piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait; + piocb->context_un.wait_queue = &done_q; + piocb->iocb_flag &= ~LPFC_IO_WAKE; - /* Setup callback routine and issue the command. */ - piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; - retval = lpfc_sli_issue_iocb(phba, pring, piocb, - flag | SLI_IOCB_HIGH_PRIORITY); - if (retval != IOCB_SUCCESS) { - piocb->context2 = NULL; - return IOCB_ERROR; - } + retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0); + if (retval == IOCB_SUCCESS) { + timeout_req = timeout * HZ; + spin_unlock_irq(phba->host->host_lock); + timeleft = wait_event_timeout(done_q, + piocb->iocb_flag & LPFC_IO_WAKE, + timeout_req); + spin_lock_irq(phba->host->host_lock); - /* - * This high-priority iocb was sent out-of-band. Poll for its - * completion rather than wait for a signal. Note that the host_lock - * is held by the midlayer and must be released here to allow the - * interrupt handlers to complete the IO and signal this routine via - * the iocb_flag. - * Also, the delay_time is computed to be one second longer than - * the scsi command timeout to give the FW time to abort on - * timeout rather than the driver just giving up. Typically, - * the midlayer does not specify a time for this command so the - * driver is free to enforce its own timeout. - */ - - delay_time = ((timeout + 1) * 1000) >> 6; - retval = IOCB_ERROR; - spin_unlock_irq(phba->host->host_lock); - for (j = 0; j < 64; j++) { - msleep(delay_time); - if (piocb->iocb_flag & LPFC_IO_HIPRI) { - piocb->iocb_flag &= ~LPFC_IO_HIPRI; - retval = IOCB_SUCCESS; - break; + if (timeleft == 0) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "%d:0329 IOCB wait timeout error - no " + "wake response Data x%x\n", + phba->brd_no, timeout); + retval = IOCB_TIMEDOUT; + } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "%d:0330 IOCB wake NOT set, " + "Data x%x x%lx\n", phba->brd_no, + timeout, (timeleft / jiffies)); + retval = IOCB_TIMEDOUT; + } else { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "%d:0331 IOCB wake signaled\n", + phba->brd_no); } + } else { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "%d:0332 IOCB wait issue failed, Data x%x\n", + phba->brd_no, retval); + retval = IOCB_ERROR; } - spin_lock_irq(phba->host->host_lock); - piocb->context2 = NULL; + if (prspiocbq) + piocb->context2 = NULL; + + piocb->context_un.wait_queue = NULL; + piocb->iocb_cmpl = NULL; return retval; } + int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout) diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 5d8911de4faa..9f1b85bed5a7 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -39,10 +39,8 @@ struct lpfc_iocbq { IOCB_t iocb; /* IOCB cmd */ uint8_t retry; /* retry counter for IOCB cmd - if needed */ uint8_t iocb_flag; -#define LPFC_IO_POLL 1 /* Polling mode iocb */ -#define LPFC_IO_LIBDFC 2 /* libdfc iocb */ -#define LPFC_IO_WAIT 4 -#define LPFC_IO_HIPRI 8 /* High Priority Queue signal flag */ +#define LPFC_IO_LIBDFC 1 /* libdfc iocb */ +#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ uint8_t abort_count; uint8_t rsvd2; @@ -51,8 +49,7 @@ struct lpfc_iocbq { void *context2; /* caller context information */ void *context3; /* caller context information */ union { - wait_queue_head_t *hipri_wait_queue; /* High Priority Queue wait - queue */ + wait_queue_head_t *wait_queue; struct lpfc_iocbq *rsp_iocb; struct lpfcMboxq *mbox; } context_un; From a784efbff725b7f4893a8835ac7232c0e00d24e4 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:51 -0400 Subject: [PATCH 0989/1940] [SCSI] lpfc: Adjust lpfc_scsi_buf allocation Adjust lpfc_scsi_buf allocation to account for lun_queue_depth and error handling Under high load and high duress, the error handler could steal some command resources from the normal i/o path. Rework to allocate additional resources to avoid this scneario. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c993069a6500..b903d3b7b730 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1152,24 +1152,33 @@ lpfc_slave_alloc(struct scsi_device *sdev) /* * Populate the cmds_per_lun count scsi_bufs into this host's globally * available list of scsi buffers. Don't allocate more than the - * HBA limit conveyed to the midlayer via the host structure. Note - * that this list of scsi bufs exists for the lifetime of the driver. + * HBA limit conveyed to the midlayer via the host structure. The + * formula accounts for the lun_queue_depth + error handlers + 1 + * extra. This list of scsi bufs exists for the lifetime of the driver. */ total = phba->total_scsi_bufs; - num_to_alloc = LPFC_CMD_PER_LUN; + num_to_alloc = phba->cfg_lun_queue_depth + 2; if (total >= phba->cfg_hba_queue_depth) { - printk(KERN_WARNING "%s, At config limitation of " - "%d allocated scsi_bufs\n", __FUNCTION__, total); + lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, + "%d:0704 At limitation of %d preallocated " + "command buffers\n", phba->brd_no, total); return 0; } else if (total + num_to_alloc > phba->cfg_hba_queue_depth) { + lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, + "%d:0705 Allocation request of %d command " + "buffers will exceed max of %d. Reducing " + "allocation request to %d.\n", phba->brd_no, + num_to_alloc, phba->cfg_hba_queue_depth, + (phba->cfg_hba_queue_depth - total)); num_to_alloc = phba->cfg_hba_queue_depth - total; } for (i = 0; i < num_to_alloc; i++) { scsi_buf = lpfc_get_scsi_buf(phba); if (!scsi_buf) { - printk(KERN_ERR "%s, failed to allocate " - "scsi_buf\n", __FUNCTION__); + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "%d:0706 Failed to allocate command " + "buffer\n", phba->brd_no); break; } From 4a0dfcdefb1cc81c0920dc98fbb82bb57326b16d Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:29:56 -0400 Subject: [PATCH 0990/1940] [SCSI] lpfc: Remove unneeded IOCB_t * cast Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e09398dbe779..b53ed3abc6c9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -936,7 +936,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, * structure. The copy involves a byte-swap since the * network byte order and pci byte orders are different. */ - entry = (IOCB_t *) IOCB_ENTRY(pring->rspringaddr, pring->rspidx); + entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); lpfc_sli_pcimem_bcopy((uint32_t *) entry, (uint32_t *) &rspiocbq.iocb, sizeof (IOCB_t)); From 0bd4ca25ad2ace4aa717c83dbd4ed21c53c953cb Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:30:02 -0400 Subject: [PATCH 0991/1940] [SCSI] lpfc: Fix eh_ return codes for commands Return FAILED from eh_ routines if command(s) is(are) not completed There were scenarios where we may have returned from the error handlers prior to all affected commands being flushed to the midlayer. Add changes to ensure this doesn't happen. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_ct.c | 5 +- drivers/scsi/lpfc/lpfc_els.c | 6 +- drivers/scsi/lpfc/lpfc_init.c | 5 +- drivers/scsi/lpfc/lpfc_scsi.c | 253 ++++++++++++++-------------------- drivers/scsi/lpfc/lpfc_sli.c | 103 +++++++------- drivers/scsi/lpfc/lpfc_sli.h | 1 + 7 files changed, 156 insertions(+), 218 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e16025d76aa2..d527d05a607f 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -143,6 +143,7 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); int lpfc_mem_alloc(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *); +struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); int lpfc_sli_hba_setup(struct lpfc_hba *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 40c34a30a94a..7f427f9c4688 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -224,13 +224,12 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; IOCB_t *icmd; - struct lpfc_iocbq *geniocb = NULL; + struct lpfc_iocbq *geniocb; /* Allocate buffer for command iocb */ spin_lock_irq(phba->host->host_lock); - list_remove_head(lpfc_iocb_list, geniocb, struct lpfc_iocbq, list); + geniocb = lpfc_sli_get_iocbq(phba); spin_unlock_irq(phba->host->host_lock); if (geniocb == NULL) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e931ae6e7464..08a0c00cfc30 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -102,9 +102,8 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) { - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; struct lpfc_sli_ring *pring; - struct lpfc_iocbq *elsiocb = NULL; + struct lpfc_iocbq *elsiocb; struct lpfc_dmabuf *pcmd, *prsp, *pbuflist; struct ulp_bde64 *bpl; IOCB_t *icmd; @@ -114,10 +113,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, if (phba->hba_state < LPFC_LINK_UP) return NULL; - /* Allocate buffer for command iocb */ spin_lock_irq(phba->host->host_lock); - list_remove_head(lpfc_iocb_list, elsiocb, struct lpfc_iocbq, list); + elsiocb = lpfc_sli_get_iocbq(phba); spin_unlock_irq(phba->host->host_lock); if (elsiocb == NULL) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 59e244f04c32..27390aa0858b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -870,8 +870,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, int type) { IOCB_t *icmd; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; - struct lpfc_iocbq *iocb = NULL; + struct lpfc_iocbq *iocb; struct lpfc_dmabuf *mp1, *mp2; cnt += pring->missbufcnt; @@ -880,7 +879,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, while (cnt > 0) { /* Allocate buffer for command iocb */ spin_lock_irq(phba->host->host_lock); - list_remove_head(lpfc_iocb_list, iocb, struct lpfc_iocbq, list); + iocb = lpfc_sli_get_iocbq(phba); spin_unlock_irq(phba->host->host_lock); if (iocb == NULL) { pring->missbufcnt = cnt; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b903d3b7b730..c34d3cf4f19c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -50,7 +50,7 @@ * and the BPL BDE is setup in the IOCB. */ static struct lpfc_scsi_buf * -lpfc_get_scsi_buf(struct lpfc_hba * phba) +lpfc_new_scsi_buf(struct lpfc_hba * phba) { struct lpfc_scsi_buf *psb; struct ulp_bde64 *bpl; @@ -88,6 +88,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) kfree (psb); return NULL; } + psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; psb->fcp_cmnd = psb->data; psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); @@ -135,11 +136,19 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) return psb; } -static void -lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb) +struct lpfc_scsi_buf* +lpfc_sli_get_scsi_buf(struct lpfc_hba * phba) { - struct lpfc_hba *phba = psb->scsi_hba; + struct lpfc_scsi_buf * lpfc_cmd = NULL; + struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; + list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); + return lpfc_cmd; +} + +static void +lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) +{ /* * There are only two special cases to consider. (1) the scsi command * requested scatter-gather usage or (2) the scsi command allocated @@ -157,6 +166,7 @@ lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb) } } + psb->pCmd = NULL; list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); } @@ -431,12 +441,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, *lp, *(lp + 3), cmd->retries, cmd->resid); } - spin_lock_irqsave(phba->host->host_lock, iflag); - lpfc_free_scsi_buf(lpfc_cmd); - cmd->host_scribble = NULL; - spin_unlock_irqrestore(phba->host->host_lock, iflag); - cmd->scsi_done(cmd); + + spin_lock_irqsave(phba->host->host_lock, iflag); + lpfc_release_scsi_buf(phba, lpfc_cmd); + spin_unlock_irqrestore(phba->host->host_lock, iflag); } static void @@ -623,8 +632,7 @@ static int lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) { struct lpfc_iocbq *iocbq; - struct lpfc_iocbq *iocbqrsp = NULL; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; + struct lpfc_iocbq *iocbqrsp; int ret; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); @@ -633,7 +641,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) lpfc_cmd->scsi_hba = phba; iocbq = &lpfc_cmd->cur_iocbq; - list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); + iocbqrsp = lpfc_sli_get_iocbq(phba); + if (!iocbqrsp) return FAILED; @@ -652,44 +661,10 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) lpfc_cmd->status = IOSTAT_DRIVER_REJECT; } - /* - * All outstanding txcmplq I/Os should have been aborted by the target. - * Unfortunately, some targets do not abide by this forcing the driver - * to double check. - */ - lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], - lpfc_cmd->pCmd->device->id, - lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT); - lpfc_sli_release_iocbq(phba, iocbqrsp); return ret; } -static void -lpfc_scsi_cmd_iocb_cleanup (struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, - struct lpfc_iocbq *pIocbOut) -{ - unsigned long iflag; - struct lpfc_scsi_buf *lpfc_cmd = - (struct lpfc_scsi_buf *) pIocbIn->context1; - - spin_lock_irqsave(phba->host->host_lock, iflag); - lpfc_free_scsi_buf(lpfc_cmd); - spin_unlock_irqrestore(phba->host->host_lock, iflag); -} - -static void -lpfc_scsi_cmd_iocb_cmpl_aborted(struct lpfc_hba *phba, - struct lpfc_iocbq *pIocbIn, - struct lpfc_iocbq *pIocbOut) -{ - struct scsi_cmnd *ml_cmd = - ((struct lpfc_scsi_buf *) pIocbIn->context1)->pCmd; - - lpfc_scsi_cmd_iocb_cleanup (phba, pIocbIn, pIocbOut); - ml_cmd->host_scribble = NULL; -} - const char * lpfc_info(struct Scsi_Host *host) { @@ -726,9 +701,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) struct lpfc_sli *psli = &phba->sli; struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; - struct lpfc_scsi_buf *lpfc_cmd = NULL; + struct lpfc_scsi_buf *lpfc_cmd; struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); - struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; int err; err = fc_remote_port_chkready(rport); @@ -745,8 +719,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) cmnd->result = ScsiResult(DID_BUS_BUSY, 0); goto out_fail_command; } - - list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); + lpfc_cmd = lpfc_sli_get_scsi_buf (phba); if (lpfc_cmd == NULL) { printk(KERN_WARNING "%s: No buffer available - list empty, " "total count %d\n", __FUNCTION__, phba->total_scsi_bufs); @@ -776,7 +749,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) return 0; out_host_busy_free_buf: - lpfc_free_scsi_buf(lpfc_cmd); + lpfc_release_scsi_buf(phba, lpfc_cmd); cmnd->host_scribble = NULL; out_host_busy: return SCSI_MLQUEUE_HOST_BUSY; @@ -792,116 +765,92 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) struct lpfc_hba *phba = (struct lpfc_hba *)cmnd->device->host->hostdata[0]; struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; - struct lpfc_iocbq *iocb, *next_iocb; - struct lpfc_iocbq *abtsiocb = NULL; + struct lpfc_iocbq *iocb; + struct lpfc_iocbq *abtsiocb; struct lpfc_scsi_buf *lpfc_cmd; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; IOCB_t *cmd, *icmd; - unsigned long snum; - unsigned int id, lun; unsigned int loop_count = 0; - int ret = IOCB_SUCCESS; + int ret = SUCCESS; + + + lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; + BUG_ON(!lpfc_cmd); /* - * If the host_scribble data area is NULL, then the driver has already - * completed this command, but the midlayer did not see the completion - * before the eh fired. Just return SUCCESS. + * If pCmd field of the corresponding lpfc_scsi_buf structure + * points to a different SCSI command, then the driver has + * already completed this command, but the midlayer did not + * see the completion before the eh fired. Just return + * SUCCESS. */ - lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; - if (!lpfc_cmd) - return SUCCESS; + iocb = &lpfc_cmd->cur_iocbq; + if (lpfc_cmd->pCmd != cmnd) + goto out; - /* save these now since lpfc_cmd can be freed */ - id = lpfc_cmd->pCmd->device->id; - lun = lpfc_cmd->pCmd->device->lun; - snum = lpfc_cmd->pCmd->serial_number; - - list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { - cmd = &iocb->iocb; - if (iocb->context1 != lpfc_cmd) - continue; - - list_del_init(&iocb->list); - pring->txq_cnt--; - if (!iocb->iocb_cmpl) - lpfc_sli_release_iocbq(phba, iocb); - else { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - lpfc_scsi_cmd_iocb_cmpl_aborted(phba, iocb, iocb); - } + BUG_ON(iocb->context1 != lpfc_cmd); + abtsiocb = lpfc_sli_get_iocbq(phba); + if (abtsiocb == NULL) { + ret = FAILED; goto out; } - list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq, list); - if (abtsiocb == NULL) - return FAILED; - /* - * The scsi command was not in the txq. Check the txcmplq and if it is - * found, send an abort to the FW. + * The scsi command can not be in txq and it is in flight because the + * pCmd is still pointig at the SCSI command we have to abort. There + * is no need to search the txcmplq. Just send an abort to the FW. */ - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - if (iocb->context1 != lpfc_cmd) - continue; - iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl_aborted; - cmd = &iocb->iocb; - icmd = &abtsiocb->iocb; - icmd->un.acxri.abortType = ABORT_TYPE_ABTS; - icmd->un.acxri.abortContextTag = cmd->ulpContext; - icmd->un.acxri.abortIoTag = cmd->ulpIoTag; + cmd = &iocb->iocb; + icmd = &abtsiocb->iocb; + icmd->un.acxri.abortType = ABORT_TYPE_ABTS; + icmd->un.acxri.abortContextTag = cmd->ulpContext; + icmd->un.acxri.abortIoTag = cmd->ulpIoTag; - icmd->ulpLe = 1; - icmd->ulpClass = cmd->ulpClass; - if (phba->hba_state >= LPFC_LINK_UP) - icmd->ulpCommand = CMD_ABORT_XRI_CN; - else - icmd->ulpCommand = CMD_CLOSE_XRI_CN; + icmd->ulpLe = 1; + icmd->ulpClass = cmd->ulpClass; + if (phba->hba_state >= LPFC_LINK_UP) + icmd->ulpCommand = CMD_ABORT_XRI_CN; + else + icmd->ulpCommand = CMD_CLOSE_XRI_CN; - abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; - if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == - IOCB_ERROR) { - lpfc_sli_release_iocbq(phba, abtsiocb); - ret = IOCB_ERROR; + abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; + if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { + lpfc_sli_release_iocbq(phba, abtsiocb); + ret = FAILED; + goto out; + } + + /* Wait for abort to complete */ + while (lpfc_cmd->pCmd == cmnd) + { + spin_unlock_irq(phba->host->host_lock); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(LPFC_ABORT_WAIT*HZ); + spin_lock_irq(phba->host->host_lock); + if (++loop_count + > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT) break; - } + } - /* Wait for abort to complete */ - while (cmnd->host_scribble) - { - spin_unlock_irq(phba->host->host_lock); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(LPFC_ABORT_WAIT*HZ); - spin_lock_irq(phba->host->host_lock); - if (++loop_count - > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT) - break; - } - - if(cmnd->host_scribble) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d:0748 abort handler timed " - "out waiting for abort to " - "complete. Data: " - "x%x x%x x%x x%lx\n", - phba->brd_no, ret, id, lun, snum); - cmnd->host_scribble = NULL; - iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cleanup; - ret = IOCB_ERROR; - } - - break; + if (lpfc_cmd->pCmd == cmnd) { + ret = FAILED; + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "%d:0748 abort handler timed out waiting for " + "abort to complete: ret %#x, ID %d, LUN %d, " + "snum %#lx\n", + phba->brd_no, ret, cmnd->device->id, + cmnd->device->lun, cmnd->serial_number); } out: lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, - "%d:0749 SCSI layer issued abort device " - "Data: x%x x%x x%x x%lx\n", - phba->brd_no, ret, id, lun, snum); + "%d:0749 SCSI layer issued abort device: ret %#x, " + "ID %d, LUN %d, snum %#lx\n", + phba->brd_no, ret, cmnd->device->id, + cmnd->device->lun, cmnd->serial_number); - return ret == IOCB_SUCCESS ? SUCCESS : FAILED; + return ret; } static int @@ -919,10 +868,8 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; - struct lpfc_scsi_buf *lpfc_cmd = NULL; - struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; - struct lpfc_iocbq *iocbq, *iocbqrsp = NULL; + struct lpfc_scsi_buf *lpfc_cmd; + struct lpfc_iocbq *iocbq, *iocbqrsp; struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_nodelist *pnode = rdata->pnode; int ret = FAILED; @@ -946,7 +893,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) break; } - list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); + lpfc_cmd = lpfc_sli_get_scsi_buf (phba); if (lpfc_cmd == NULL) goto out; @@ -961,7 +908,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) iocbq = &lpfc_cmd->cur_iocbq; /* get a buffer for this IOCB command response */ - list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); + iocbqrsp = lpfc_sli_get_iocbq(phba); if (iocbqrsp == NULL) goto out_free_scsi_buf; @@ -1002,9 +949,10 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) } if (cnt) { - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0719 LUN Reset I/O flush failure: cnt x%x\n", phba->brd_no, cnt); + ret = FAILED; } lpfc_sli_release_iocbq(phba, iocbqrsp); @@ -1016,7 +964,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) phba->brd_no, lpfc_cmd->pCmd->device->id, lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status, lpfc_cmd->result); - lpfc_free_scsi_buf(lpfc_cmd); + lpfc_release_scsi_buf(phba, lpfc_cmd); out: return ret; } @@ -1044,10 +992,9 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) int ret = FAILED, i, err_count = 0; int cnt, loopcnt; unsigned int midlayer_id = 0; - struct lpfc_scsi_buf * lpfc_cmd = NULL; - struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; + struct lpfc_scsi_buf * lpfc_cmd; - list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); + lpfc_cmd = lpfc_sli_get_scsi_buf (phba); if (lpfc_cmd == NULL) goto out; @@ -1111,10 +1058,12 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) phba->brd_no, cnt, i); } - if (!err_count) + if (cnt == 0) ret = SUCCESS; + else + ret = FAILED; - lpfc_free_scsi_buf(lpfc_cmd); + lpfc_release_scsi_buf(phba, lpfc_cmd); lpfc_printf_log(phba, KERN_ERR, LOG_FCP, @@ -1174,7 +1123,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) } for (i = 0; i < num_to_alloc; i++) { - scsi_buf = lpfc_get_scsi_buf(phba); + scsi_buf = lpfc_new_scsi_buf(phba); if (!scsi_buf) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0706 Failed to allocate command " diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index b53ed3abc6c9..508710001ed6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -65,6 +65,16 @@ typedef enum _lpfc_iocb_type { LPFC_ABORT_IOCB } lpfc_iocb_type; +struct lpfc_iocbq * +lpfc_sli_get_iocbq(struct lpfc_hba * phba) +{ + struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; + struct lpfc_iocbq * iocbq = NULL; + + list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list); + return iocbq; +} + void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) { @@ -1055,7 +1065,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, struct lpfc_iocbq *next_iocb; struct lpfc_iocbq *cmdiocbp; struct lpfc_iocbq *saveq; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; uint8_t iocb_cmd_type; lpfc_iocb_type type; @@ -1097,7 +1106,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, } rmb(); - lpfc_iocb_list = &phba->lpfc_iocb_list; while (pring->rspidx != portRspPut) { /* * Build a completion list and call the appropriate handler. @@ -1113,8 +1121,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, * received. */ entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); - list_remove_head(lpfc_iocb_list, rspiocbp, struct lpfc_iocbq, - list); + rspiocbp = lpfc_sli_get_iocbq(phba); if (rspiocbp == NULL) { printk(KERN_ERR "%s: out of buffers! Failing " "completion.\n", __FUNCTION__); @@ -2407,13 +2414,12 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, struct lpfc_iocbq * cmdiocb) { - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; - struct lpfc_iocbq *abtsiocbp = NULL; + struct lpfc_iocbq *abtsiocbp; IOCB_t *icmd = NULL; IOCB_t *iabt = NULL; /* issue ABTS for this IOCB based on iotag */ - list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list); + abtsiocbp = lpfc_sli_get_iocbq(phba); if (abtsiocbp == NULL) return 0; @@ -2454,28 +2460,37 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, } static int -lpfc_sli_validate_iocb_cmd(struct lpfc_scsi_buf *lpfc_cmd, uint16_t tgt_id, - uint64_t lun_id, struct lpfc_iocbq *iocb, - uint32_t ctx, lpfc_ctx_cmd ctx_cmd) +lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, + uint64_t lun_id, uint32_t ctx, + lpfc_ctx_cmd ctx_cmd) { + struct lpfc_scsi_buf *lpfc_cmd; + struct scsi_cmnd *cmnd; int rc = 1; - if (lpfc_cmd == NULL) + if (!(iocbq->iocb_flag & LPFC_IO_FCP)) + return rc; + + lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); + cmnd = lpfc_cmd->pCmd; + + if (cmnd == NULL) return rc; switch (ctx_cmd) { case LPFC_CTX_LUN: - if ((lpfc_cmd->pCmd->device->id == tgt_id) && - (lpfc_cmd->pCmd->device->lun == lun_id)) + if ((cmnd->device->id == tgt_id) && + (cmnd->device->lun == lun_id)) rc = 0; break; case LPFC_CTX_TGT: - if (lpfc_cmd->pCmd->device->id == tgt_id) + if (cmnd->device->id == tgt_id) rc = 0; break; case LPFC_CTX_CTX: - if (iocb->iocb.ulpContext == ctx) + if (iocbq->iocb.ulpContext == ctx) rc = 0; + break; case LPFC_CTX_HOST: rc = 0; break; @@ -2492,30 +2507,17 @@ int lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) { - struct lpfc_iocbq *iocb, *next_iocb; - IOCB_t *cmd = NULL; - struct lpfc_scsi_buf *lpfc_cmd; - int sum = 0, ret_val = 0; + struct lpfc_iocbq *iocbq; + int sum, i; - /* Next check the txcmplq */ - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - cmd = &iocb->iocb; + for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; - /* Must be a FCP command */ - if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) && - (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) && - (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) { - continue; - } - - /* context1 MUST be a struct lpfc_scsi_buf */ - lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1); - ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id, - NULL, 0, ctx_cmd); - if (ret_val != 0) - continue; - sum++; + if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, + 0, ctx_cmd) == 0) + sum++; } + return sum; } @@ -2534,38 +2536,27 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, uint16_t tgt_id, uint64_t lun_id, uint32_t ctx, lpfc_ctx_cmd abort_cmd) { - struct lpfc_iocbq *iocb, *next_iocb; - struct lpfc_iocbq *abtsiocb = NULL; - struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; + struct lpfc_iocbq *iocbq; + struct lpfc_iocbq *abtsiocb; IOCB_t *cmd = NULL; - struct lpfc_scsi_buf *lpfc_cmd; int errcnt = 0, ret_val = 0; + int i; - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - cmd = &iocb->iocb; + for (i = 1; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; - /* Must be a FCP command */ - if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) && - (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) && - (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) { - continue; - } - - /* context1 MUST be a struct lpfc_scsi_buf */ - lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1); - ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id, - iocb, ctx, abort_cmd); - if (ret_val != 0) + if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, + 0, abort_cmd) != 0) continue; /* issue ABTS for this IOCB based on iotag */ - list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq, - list); + abtsiocb = lpfc_sli_get_iocbq(phba); if (abtsiocb == NULL) { errcnt++; continue; } + cmd = &iocbq->iocb; abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext; abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag; diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 9f1b85bed5a7..b7a9f970f565 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -41,6 +41,7 @@ struct lpfc_iocbq { uint8_t iocb_flag; #define LPFC_IO_LIBDFC 1 /* libdfc iocb */ #define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ +#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ uint8_t abort_count; uint8_t rsvd2; From c514e58cb8eac0d21f4ab5011df75a09eb5edd50 Mon Sep 17 00:00:00 2001 From: Kenneth Tan Date: Sat, 29 Oct 2005 16:32:14 +0100 Subject: [PATCH 0992/1940] [ARM] 3022/1: Missing peripheral devices memory mapping definition for IXP46X processor Patch from Kenneth Tan Defining IXP46X peripheral devices memory mapping definitions that have been missed out: o Peripheral virtual base address is being adjusted to allow more headroom to add extra peripheral device addresses o Peripheral size is being increased to address the above needs o Virtual address of expansion bus and PCI configuration register needs to be adjusted as new peripheral device memory space is overlapping with their virtual address space Signed-off-by: Kenneth Tan Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp4xx/ixp4xx-regs.h | 73 +++++++++++++++-------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h index 004696a95bdb..2b149ed59149 100644 --- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h +++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h @@ -36,11 +36,11 @@ * * 0x6000000 0x00004000 ioremap'd QMgr * - * 0xC0000000 0x00001000 0xffbfe000 PCI CFG + * 0xC0000000 0x00001000 0xffbff000 PCI CFG * - * 0xC4000000 0x00001000 0xffbfd000 EXP CFG + * 0xC4000000 0x00001000 0xffbfe000 EXP CFG * - * 0xC8000000 0x0000C000 0xffbf2000 On-Chip Peripherals + * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals */ /* @@ -52,22 +52,22 @@ * Expansion BUS Configuration registers */ #define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) -#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFD000) +#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFE000) #define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) /* * PCI Config registers */ #define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) -#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFE000) +#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFF000) #define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) /* * Peripheral space */ #define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) -#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000) -#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000) +#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBEB000) +#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) /* * Debug UART @@ -115,25 +115,48 @@ /* * Peripheral Space Register Region Base Addresses */ -#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000) -#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000) -#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000) -#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000) -#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000) -#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000) -#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000) -#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000) -#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000) +#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000) +#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000) +#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000) +#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000) +#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000) +#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000) +#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000) +#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000) +#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000) +#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000) +#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000) +#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000) +/* ixp46X only */ +#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000) +#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000) +#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000) +#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000) +#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000) +#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000) +#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000) -#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000) -#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000) -#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000) -#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000) -#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000) -#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000) -#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000) -#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000) -#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000) + +#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000) +#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000) +#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000) +#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000) +#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000) +#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000) +#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000) +#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000) +#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000) +#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000) +#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000) +#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000) +/* ixp46X only */ +#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000) +#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000) +#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000) +#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000) +#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000) +#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000) +#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000) /* * Constants to make it easy to access Interrupt Controller registers From 73797e31b5b07c8a53afd19d8a382625bcd32005 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:30:05 -0400 Subject: [PATCH 0993/1940] [SCSI] lpfc 8.1.0 : Add owner field to struct pci_driver Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 27390aa0858b..4e04470321a2 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1706,6 +1706,7 @@ MODULE_DEVICE_TABLE(pci, lpfc_id_table); static struct pci_driver lpfc_driver = { .name = LPFC_DRIVER_NAME, + .owner = THIS_MODULE, .id_table = lpfc_id_table, .probe = lpfc_pci_probe_one, .remove = __devexit_p(lpfc_pci_remove_one), From eb66fff7d94199f80378bc0b51a06e62ce379b53 Mon Sep 17 00:00:00 2001 From: "James.Smart@Emulex.Com" Date: Fri, 28 Oct 2005 20:30:10 -0400 Subject: [PATCH 0994/1940] [SCSI] lpfc: Change version number to 8.1.0 Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 7e6747b06f90..4f0466fbd5f2 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.0.30" +#define LPFC_DRIVER_VERSION "8.1.0" #define LPFC_DRIVER_NAME "lpfc" From a3632fa3ecefe50d88fc70af90610f79b99e0715 Mon Sep 17 00:00:00 2001 From: Jack Hammer Date: Tue, 25 Oct 2005 14:13:03 -0400 Subject: [PATCH 0995/1940] [SCSI] ips: Fix up for correct scatter/gather processing Added kmap_atomic/kunmap_atomic. Added protection of KM_IRQ0 slot with local_irq_save(), local_irq_restore(), and comments. Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 49 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index eeae7ccb0dd2..0a252e7aca6e 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -219,15 +219,12 @@ module_param(ips, charp, 0); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) #include #include "sd.h" -#define IPS_SG_ADDRESS(sg) ((sg)->address) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) #ifndef __devexit_p #define __devexit_p(x) x #endif #else -#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ - page_address((sg)->page)+(sg)->offset : NULL) #define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0) #define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0) #endif @@ -1605,6 +1602,8 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, static int ips_is_passthru(Scsi_Cmnd * SC) { + unsigned long flags; + METHOD_TRACE("ips_is_passthru", 1); if (!SC) @@ -1622,10 +1621,20 @@ ips_is_passthru(Scsi_Cmnd * SC) return 1; else if (SC->use_sg) { struct scatterlist *sg = SC->request_buffer; - char *buffer = IPS_SG_ADDRESS(sg); + char *buffer; + + /* kmap_atomic() ensures addressability of the user buffer.*/ + /* local_irq_save() protects the KM_IRQ0 address slot. */ + local_irq_save(flags); + buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; if (buffer && buffer[0] == 'C' && buffer[1] == 'O' && - buffer[2] == 'P' && buffer[3] == 'P') + buffer[2] == 'P' && buffer[3] == 'P') { + kunmap_atomic(buffer - sg->offset, KM_IRQ0); + local_irq_restore(flags); return 1; + } + kunmap_atomic(buffer - sg->offset, KM_IRQ0); + local_irq_restore(flags); } } return 0; @@ -3656,14 +3665,21 @@ ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned int i; unsigned int min_cnt, xfer_cnt; char *cdata = (char *) data; + unsigned char *buffer; + unsigned long flags; struct scatterlist *sg = scmd->request_buffer; for (i = 0, xfer_cnt = 0; (i < scmd->use_sg) && (xfer_cnt < count); i++) { - if (!IPS_SG_ADDRESS(&sg[i])) - return; min_cnt = min(count - xfer_cnt, sg[i].length); - memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt], - min_cnt); + + /* kmap_atomic() ensures addressability of the data buffer.*/ + /* local_irq_save() protects the KM_IRQ0 address slot. */ + local_irq_save(flags); + buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset; + memcpy(buffer, &cdata[xfer_cnt], min_cnt); + kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); + local_irq_restore(flags); + xfer_cnt += min_cnt; } @@ -3688,14 +3704,21 @@ ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int i; unsigned int min_cnt, xfer_cnt; char *cdata = (char *) data; + unsigned char *buffer; + unsigned long flags; struct scatterlist *sg = scmd->request_buffer; for (i = 0, xfer_cnt = 0; (i < scmd->use_sg) && (xfer_cnt < count); i++) { - if (!IPS_SG_ADDRESS(&sg[i])) - return; min_cnt = min(count - xfer_cnt, sg[i].length); - memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]), - min_cnt); + + /* kmap_atomic() ensures addressability of the data buffer.*/ + /* local_irq_save() protects the KM_IRQ0 address slot. */ + local_irq_save(flags); + buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset; + memcpy(&cdata[xfer_cnt], buffer, min_cnt); + kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); + local_irq_restore(flags); + xfer_cnt += min_cnt; } From 47e627ce83b6df9f4bb8e4b0a4dde1c5d7a4c929 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 29 Oct 2005 18:18:42 +0900 Subject: [PATCH 0996/1940] [PATCH] blk: fix merge bug in as-iosched as-iosched deals with aliased requests differently from other ioscheds. It links together aliased requests using rq->queuelist instead of spilling alises to dispatch queue like other ioscheds do. Requests linked in this way cannot be merged. Unfortunately, generic q->last_merge handling patch didn't take this into account and q->last_merge could be set to an aliased request resulting in Badness, corrupt list and eventually panic. This explicitly marks aliased requests to be unmergeable. Signed-off-by: Tejun Heo Signed-off-by: Linus Torvalds --- drivers/block/as-iosched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c index 4081c36c8c19..564172234819 100644 --- a/drivers/block/as-iosched.c +++ b/drivers/block/as-iosched.c @@ -1344,6 +1344,7 @@ as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alia * Don't want to have to handle merges. */ as_del_arq_hash(arq); + arq->request->flags |= REQ_NOMERGE; } /* From 8d027de54c77d38eedc9b331c7a2a39807d34691 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sat, 29 Oct 2005 19:37:40 +0400 Subject: [PATCH 0997/1940] [PATCH] fix ->signal->live leak in copy_process() exit_signal() (called from copy_process's error path) should decrement ->signal->live, otherwise forking process will miss 'group_dead' in do_exit(). Signed-off-by: Oleg Nesterov Signed-off-by: Linus Torvalds --- kernel/signal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/signal.c b/kernel/signal.c index f2b96b08fb44..6904bbbfe116 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -406,6 +406,8 @@ void __exit_signal(struct task_struct *tsk) void exit_signal(struct task_struct *tsk) { + atomic_dec(&tsk->signal->live); + write_lock_irq(&tasklist_lock); __exit_signal(tsk); write_unlock_irq(&tasklist_lock); From 7533624527b9afa5585ca43ba534758052d848e5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 06:36:27 +0100 Subject: [PATCH 0998/1940] [PATCH] s2io iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/s2io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index d303d162974f..62d5041845e3 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3045,7 +3045,7 @@ int s2io_set_swapper(nic_t * sp) int wait_for_msix_trans(nic_t *nic, int i) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int ret = 0, cnt = 0; @@ -3066,7 +3066,7 @@ int wait_for_msix_trans(nic_t *nic, int i) void restore_xmsi_data(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int i; @@ -3084,7 +3084,7 @@ void restore_xmsi_data(nic_t *nic) void store_xmsi_data(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64, addr, data; int i; @@ -3107,7 +3107,7 @@ void store_xmsi_data(nic_t *nic) int s2io_enable_msi(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u16 msi_ctrl, msg_val; struct config_param *config = &nic->config; struct net_device *dev = nic->dev; @@ -3157,7 +3157,7 @@ int s2io_enable_msi(nic_t *nic) int s2io_enable_msi_x(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 tx_mat, rx_mat; u16 msi_control; /* Temp variable */ int ret, i, j, msix_indx = 1; From 4b4a5eaedfc098d825d4c34cad1f1115802512b7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 06:38:44 +0100 Subject: [PATCH 0999/1940] [PATCH] sata_sil24 iomem annotations and fixes trivial iomem annotations + missing memcpy_fromio() caught by those Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/scsi/sata_sil24.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 32d730bd5bb6..51855d3bac64 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -220,8 +220,8 @@ struct sil24_port_priv { /* ap->host_set->private_data */ struct sil24_host_priv { - void *host_base; /* global controller control (128 bytes @BAR0) */ - void *port_base; /* port registers (4 * 8192 bytes @BAR2) */ + void __iomem *host_base; /* global controller control (128 bytes @BAR0) */ + void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */ }; static u8 sil24_check_status(struct ata_port *ap); @@ -349,10 +349,12 @@ static struct ata_port_info sil24_port_info[] = { static inline void sil24_update_tf(struct ata_port *ap) { struct sil24_port_priv *pp = ap->private_data; - void *port = (void *)ap->ioaddr.cmd_addr; - struct sil24_prb *prb = port; + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; + struct sil24_prb __iomem *prb = port; + u8 fis[6 * 4]; - ata_tf_from_fis(prb->fis, &pp->tf); + memcpy_fromio(fis, prb->fis, 6 * 4); + ata_tf_from_fis(fis, &pp->tf); } static u8 sil24_check_status(struct ata_port *ap) @@ -376,9 +378,9 @@ static int sil24_scr_map[] = { static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) { - void *scr_addr = (void *)ap->ioaddr.scr_addr; + void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { - void *addr; + void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; return readl(scr_addr + sil24_scr_map[sc_reg] * 4); } @@ -387,9 +389,9 @@ static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { - void *scr_addr = (void *)ap->ioaddr.scr_addr; + void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { - void *addr; + void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); } @@ -454,7 +456,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) static int sil24_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void *port = (void *)ap->ioaddr.cmd_addr; + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block); @@ -467,7 +469,7 @@ static void sil24_irq_clear(struct ata_port *ap) /* unused */ } -static int __sil24_reset_controller(void *port) +static int __sil24_reset_controller(void __iomem *port) { int cnt; u32 tmp; @@ -493,7 +495,7 @@ static void sil24_reset_controller(struct ata_port *ap) { printk(KERN_NOTICE DRV_NAME " ata%u: resetting controller...\n", ap->id); - if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr)) + if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr)) printk(KERN_ERR DRV_NAME " ata%u: failed to reset controller\n", ap->id); } @@ -527,7 +529,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); struct sil24_port_priv *pp = ap->private_data; - void *port = (void *)ap->ioaddr.cmd_addr; + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; u32 irq_stat, cmd_err, sstatus, serror; irq_stat = readl(port + PORT_IRQ_STAT); @@ -574,7 +576,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) static inline void sil24_host_intr(struct ata_port *ap) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - void *port = (void *)ap->ioaddr.cmd_addr; + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; u32 slot_stat; slot_stat = readl(port + PORT_SLOT_STAT); @@ -689,7 +691,8 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_port_info *pinfo = &sil24_port_info[board_id]; struct ata_probe_ent *probe_ent = NULL; struct sil24_host_priv *hpriv = NULL; - void *host_base = NULL, *port_base = NULL; + void __iomem *host_base = NULL; + void __iomem *port_base = NULL; int i, rc; if (!printed_version++) @@ -771,7 +774,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) writel(0, host_base + HOST_CTRL); for (i = 0; i < probe_ent->n_ports; i++) { - void *port = port_base + i * PORT_REGS_SIZE; + void __iomem *port = port_base + i * PORT_REGS_SIZE; unsigned long portu = (unsigned long)port; u32 tmp; int cnt; From 2d3c0b7bedfd7a8e1870a046a434bd467e7c5349 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 06:46:03 +0100 Subject: [PATCH 1000/1940] [PATCH] missing include in infiniband use of IS_ERR/PTR_ERR in infiniband/core/agent.c, without a portable chain of includes pulling err.h (breaks on a bunch of platforms). Signed-off-by: Al Viro Acked-by: Roland Dreier Signed-off-by: Linus Torvalds --- drivers/infiniband/core/agent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index c5f3cfec942a..86d72fab37b0 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -39,6 +39,7 @@ #ifndef __AGENT_H_ #define __AGENT_H_ +#include #include extern int ib_agent_port_open(struct ib_device *device, int port_num); From f6b52e85a5d022008fe9f99eab7c9f41f155e3cd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 07:06:59 +0100 Subject: [PATCH 1001/1940] [PATCH] arguments out of order in class_device_create() call (s390) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/s390/char/vmlogrdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a107fec4457a..b2d75de144c6 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -787,8 +787,8 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { return ret; } priv->class_device = class_device_create( - NULL, vmlogrdr_class, + NULL, MKDEV(vmlogrdr_major, priv->minor_num), dev, "%s", dev->bus_id ); From 9d86b7d37018c917837477dd4501d44bf8f3f98c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 07:08:49 +0100 Subject: [PATCH 1002/1940] [PATCH] missing bits in sparkspkr conversion Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/input/misc/sparcspkr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 5778220a18d2..29d97b12be7a 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -143,7 +143,7 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev) sparcspkr_dev->name = "Sparc ISA Speaker"; sparcspkr_dev->event = isa_spkr_event; - input_register_device(&sparcspkr_dev); + input_register_device(sparcspkr_dev); return 0; } From 943eae03143790c71cf42fe13529f1b74ceb0266 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 07:32:07 +0100 Subject: [PATCH 1003/1940] [PATCH] missing exports of do_settimeofday() variants frv, sh64, ia64 and sparc64 do not have do_settimeofday() exported (the last two are using variant in kernel/time.c). Exports added to match the rest of architectures. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/frv/kernel/time.c | 1 + arch/sh64/kernel/time.c | 1 + kernel/time.c | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index 8d6558b00e44..f43b734482e3 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c @@ -221,6 +221,7 @@ int do_settimeofday(struct timespec *tv) clock_was_set(); return 0; } +EXPORT_SYMBOL(do_settimeofday); /* * Scheduler clock - returns current time in nanosec units. diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c index f4a62a10053c..43e395a14f49 100644 --- a/arch/sh64/kernel/time.c +++ b/arch/sh64/kernel/time.c @@ -253,6 +253,7 @@ int do_settimeofday(struct timespec *tv) return 0; } +EXPORT_SYMBOL(do_settimeofday); static int set_rtc_time(unsigned long nowtime) { diff --git a/kernel/time.c b/kernel/time.c index 40c2410ac99a..a3c2100470e1 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -532,6 +532,7 @@ int do_settimeofday (struct timespec *tv) clock_was_set(); return 0; } +EXPORT_SYMBOL(do_settimeofday); void do_gettimeofday (struct timeval *tv) { From 32b32c2c3566b206988fa30336ec6534759823b5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 11:49:33 +0100 Subject: [PATCH 1004/1940] [PATCH] amikbd fix it's input_allocate_device(), not input_dev_allocate()... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/input/keyboard/amikbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 3d63bc1ad322..4c8fb1f8631f 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -199,7 +199,7 @@ static int __init amikbd_init(void) if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) return -EBUSY; - amikbd_dev = input_dev_allocate(); + amikbd_dev = input_allocate_device(); if (!amikbd_dev) { printk(KERN_ERR "amikbd: not enough memory for input device\n"); release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); From 018a2cdf1e633497bb4f01eb86a7cbffa611776d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 11:56:13 +0100 Subject: [PATCH 1005/1940] [PATCH] idmouse cleanup and overflow fix switched to simple_read_from_buffer(), killed broken use of min(). Incidentally, that use of min() had been fixed once, only to be reintroduced in commit 4244f72436ab77c3c29a6447af81734ab3925d85: [PATCH] USB: upgrade of the idmouse driver [snip] - if (count > IMGSIZE - *ppos) - count = IMGSIZE - *ppos; + count = min ((loff_t)count, IMGSIZE - (*ppos)); Note the lovely use of cast to shut the warning about misuse of min() up... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/misc/idmouse.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 3944a55ed74c..1dc3e0f73014 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -319,20 +319,8 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count return -ENODEV; } - if (*ppos >= IMGSIZE) { - up (&dev->sem); - return 0; - } - - count = min ((loff_t)count, IMGSIZE - (*ppos)); - - if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) { - result = -EFAULT; - } else { - result = count; - *ppos += count; - } - + result = simple_read_from_buffer(buffer, count, ppos, + dev->bulk_in_buffer, IMGSIZE); /* unlock the device */ up(&dev->sem); return result; From a6e0eb3791dcefc6dd4db53a23de5cfb18fe9a97 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 12:02:00 +0100 Subject: [PATCH 1006/1940] [PATCH] bluetooth hidp is broken on s390 Bluetooth HIDP selects INPUT and it really needs it to be there - module depends on input core. And input core is never built on s390... Marked as broken on s390, for now; if somebody has better ideas, feel free to fix it and remove dependency... Signed-off-by: Al Viro Acked-by: Marcel Holtmann Signed-off-by: Linus Torvalds --- net/bluetooth/hidp/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 4e958f7d9418..edfea772fb67 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig @@ -1,6 +1,6 @@ config BT_HIDP tristate "HIDP protocol support" - depends on BT && BT_L2CAP + depends on BT && BT_L2CAP && (BROKEN || !S390) select INPUT help HIDP (Human Interface Device Protocol) is a transport layer From 942b6f62164cf8822dd03b1569777f4663d1abd7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 29 Oct 2005 12:07:11 +0100 Subject: [PATCH 1007/1940] [PATCH] type fix in arm/boot/compressed/misc.c spot the typo... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/arm/boot/compressed/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 23434b56786a..50f13eec6cd7 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -30,7 +30,7 @@ unsigned int __machine_arch_type; #define putstr icedcc_putstr #define putc icedcc_putc -extern void idedcc_putc(int ch); +extern void icedcc_putc(int ch); static void icedcc_putstr(const char *ptr) From ac19bff25b6834d858274406a686f2227dd8489d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 29 Oct 2005 13:58:21 -0400 Subject: [PATCH 1008/1940] [libata] ensure ->tf_read() hook reads Status and Error registers We want ->tf_read() to get a complete snapshot of all taskfile registers, without requiring the callers to manually call ata_chk_status() and ata_chk_err() themselves. This also fixes a minor bug in sata_vsc where the lower bits of the feature register were incorrectly placed in the HOB (high order bits) portion of struct ata_taskfile. --- drivers/scsi/libata-core.c | 4 ++++ drivers/scsi/pdc_adma.c | 2 +- drivers/scsi/sata_qstor.c | 2 +- drivers/scsi/sata_svw.c | 22 ++++++++++++++++------ drivers/scsi/sata_vsc.c | 20 ++++++++++++++------ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index f53d7b8ac33f..56c81f0aa1d9 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -370,6 +370,8 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; + tf->command = ata_check_status(ap); + tf->feature = ata_chk_err(ap); tf->nsect = inb(ioaddr->nsect_addr); tf->lbal = inb(ioaddr->lbal_addr); tf->lbam = inb(ioaddr->lbam_addr); @@ -402,6 +404,8 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; + tf->command = ata_check_status(ap); + tf->feature = ata_chk_err(ap); tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 7999817915c3..af99feb9d237 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -490,7 +490,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) if (qc && (!(qc->tf.ctl & ATA_NIEN))) { /* check main status, clearing INTRQ */ - u8 status = ata_chk_status(ap); + u8 status = ata_check_status(ap); if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 250dafa6bc36..1aaf3304d397 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -433,7 +433,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) if (qc && (!(qc->tf.ctl & ATA_NIEN))) { /* check main status, clearing INTRQ */ - u8 status = ata_chk_status(ap); + u8 status = ata_check_status(ap); if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index e0f9570bc6dd..46208f52d0e1 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c @@ -84,6 +84,8 @@ /* Port stride */ #define K2_SATA_PORT_OFFSET 0x100 +static u8 k2_stat_check_status(struct ata_port *ap); + static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { @@ -136,16 +138,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - u16 nsect, lbal, lbam, lbah; + u16 nsect, lbal, lbam, lbah, feature; - nsect = tf->nsect = readw(ioaddr->nsect_addr); - lbal = tf->lbal = readw(ioaddr->lbal_addr); - lbam = tf->lbam = readw(ioaddr->lbam_addr); - lbah = tf->lbah = readw(ioaddr->lbah_addr); + tf->command = k2_stat_check_status(ap); tf->device = readw(ioaddr->device_addr); + feature = readw(ioaddr->error_addr); + nsect = readw(ioaddr->nsect_addr); + lbal = readw(ioaddr->lbal_addr); + lbam = readw(ioaddr->lbam_addr); + lbah = readw(ioaddr->lbah_addr); + + tf->feature = feature; + tf->nsect = nsect; + tf->lbal = lbal; + tf->lbam = lbam; + tf->lbah = lbah; if (tf->flags & ATA_TFLAG_LBA48) { - tf->hob_feature = readw(ioaddr->error_addr) >> 8; + tf->hob_feature = feature >> 8; tf->hob_nsect = nsect >> 8; tf->hob_lbal = lbal >> 8; tf->hob_lbam = lbam >> 8; diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 5af05fdf8544..54273e0063c7 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -153,16 +153,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - u16 nsect, lbal, lbam, lbah; + u16 nsect, lbal, lbam, lbah, feature; - nsect = tf->nsect = readw(ioaddr->nsect_addr); - lbal = tf->lbal = readw(ioaddr->lbal_addr); - lbam = tf->lbam = readw(ioaddr->lbam_addr); - lbah = tf->lbah = readw(ioaddr->lbah_addr); + tf->command = ata_check_status(ap); tf->device = readw(ioaddr->device_addr); + feature = readw(ioaddr->error_addr); + nsect = readw(ioaddr->nsect_addr); + lbal = readw(ioaddr->lbal_addr); + lbam = readw(ioaddr->lbam_addr); + lbah = readw(ioaddr->lbah_addr); + + tf->feature = feature; + tf->nsect = nsect; + tf->lbal = lbal; + tf->lbam = lbam; + tf->lbah = lbah; if (tf->flags & ATA_TFLAG_LBA48) { - tf->hob_feature = readb(ioaddr->error_addr); + tf->hob_feature = feature >> 8; tf->hob_nsect = nsect >> 8; tf->hob_lbal = lbal >> 8; tf->hob_lbam = lbam >> 8; From d052d1beff706920e82c5d55006b08e256b5df09 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Oct 2005 19:07:23 +0100 Subject: [PATCH 1009/1940] Create platform_device.h to contain all the platform device details. Convert everyone who uses platform_bus_type to include linux/platform_device.h. Signed-off-by: Russell King Acked-by: Greg Kroah-Hartman --- arch/arm/common/locomo.c | 2 +- arch/arm/common/sa1111.c | 2 +- arch/arm/common/scoop.c | 2 +- arch/arm/mach-aaec2000/core.c | 2 +- arch/arm/mach-h720x/h7202-eval.c | 2 +- arch/arm/mach-imx/generic.c | 2 +- arch/arm/mach-imx/mx1ads.c | 1 + arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-iop3xx/iop321-setup.c | 2 +- arch/arm/mach-iop3xx/iop331-setup.c | 2 +- arch/arm/mach-ixp2000/enp2611.c | 2 +- arch/arm/mach-ixp2000/ixdp2x00.c | 2 +- arch/arm/mach-ixp2000/ixdp2x01.c | 2 +- arch/arm/mach-ixp4xx/common.c | 1 + arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 2 +- arch/arm/mach-omap1/board-h2.c | 2 +- arch/arm/mach-omap1/board-h3.c | 2 +- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/board-netstar.c | 2 +- arch/arm/mach-omap1/board-osk.c | 2 +- arch/arm/mach-omap1/board-perseus2.c | 2 +- arch/arm/mach-omap1/board-voiceblue.c | 2 +- arch/arm/mach-omap1/devices.c | 2 +- arch/arm/mach-pxa/corgi.c | 2 +- arch/arm/mach-pxa/corgi_lcd.c | 2 +- arch/arm/mach-pxa/corgi_ssp.c | 2 +- arch/arm/mach-pxa/generic.c | 2 +- arch/arm/mach-pxa/idp.c | 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/spitz.c | 2 +- arch/arm/mach-s3c2410/clock.c | 2 +- arch/arm/mach-s3c2410/cpu.c | 2 +- arch/arm/mach-s3c2410/devs.c | 2 +- arch/arm/mach-s3c2410/devs.h | 1 + arch/arm/mach-s3c2410/mach-anubis.c | 2 +- arch/arm/mach-s3c2410/mach-bast.c | 2 +- arch/arm/mach-s3c2410/mach-h1940.c | 1 + arch/arm/mach-s3c2410/mach-n30.c | 2 +- arch/arm/mach-s3c2410/mach-nexcoder.c | 2 +- arch/arm/mach-s3c2410/mach-otom.c | 2 +- arch/arm/mach-s3c2410/mach-rx3715.c | 1 + arch/arm/mach-s3c2410/mach-smdk2410.c | 1 + arch/arm/mach-s3c2410/mach-smdk2440.c | 1 + arch/arm/mach-s3c2410/s3c2410.c | 2 +- arch/arm/mach-s3c2410/s3c2440.c | 2 +- arch/arm/mach-sa1100/badge4.c | 2 +- arch/arm/mach-sa1100/cerf.c | 2 +- arch/arm/mach-sa1100/collie.c | 2 +- arch/arm/mach-sa1100/generic.c | 1 + arch/arm/mach-sa1100/jornada720.c | 2 +- arch/arm/mach-sa1100/neponset.c | 2 +- arch/arm/mach-sa1100/pleb.c | 2 +- arch/arm/mach-sa1100/simpad.c | 2 +- arch/arm/mach-versatile/core.c | 1 + arch/arm/plat-omap/usb.c | 2 +- arch/m32r/kernel/setup_m32700ut.c | 2 +- arch/m32r/kernel/setup_mappi.c | 2 +- arch/m32r/kernel/setup_mappi2.c | 2 +- arch/m32r/kernel/setup_mappi3.c | 2 +- arch/m32r/kernel/setup_opsput.c | 2 +- arch/mips/au1000/common/platform.c | 2 +- arch/ppc/platforms/4xx/ibm440ep.c | 1 + arch/ppc/platforms/4xx/ibmstb4.c | 1 + arch/ppc/platforms/4xx/redwood5.c | 2 +- arch/ppc/platforms/4xx/redwood6.c | 2 +- arch/ppc/platforms/chrp_pegasos_eth.c | 2 +- arch/ppc/platforms/cpci690.c | 1 + arch/ppc/platforms/ev64260.c | 1 + arch/ppc/platforms/ev64360.c | 1 + arch/ppc/platforms/hdpu.c | 1 + arch/ppc/platforms/katana.c | 1 + arch/ppc/platforms/radstone_ppc7d.c | 1 + arch/ppc/syslib/mpc52xx_devices.c | 1 + arch/ppc/syslib/mv64x60.c | 1 + arch/ppc/syslib/pq2_devices.c | 2 +- arch/sh/boards/superh/microdev/setup.c | 2 +- arch/um/drivers/net_kern.c | 1 + arch/um/drivers/ubd_kern.c | 1 + arch/xtensa/platform-iss/network.c | 1 + drivers/base/platform.c | 2 +- drivers/block/floppy.c | 2 +- drivers/char/s3c2410-rtc.c | 2 +- drivers/char/sonypi.c | 1 + drivers/char/tb0219.c | 2 +- drivers/char/vr41xx_giu.c | 2 +- drivers/char/vr41xx_rtc.c | 2 +- drivers/char/watchdog/mpcore_wdt.c | 2 +- drivers/char/watchdog/mv64x60_wdt.c | 2 ++ drivers/char/watchdog/s3c2410_wdt.c | 2 +- drivers/eisa/virtual_root.c | 2 +- drivers/firmware/dcdbas.c | 2 +- drivers/firmware/dell_rbu.c | 2 +- drivers/hwmon/hdaps.c | 2 +- drivers/i2c/busses/i2c-iop3xx.c | 2 +- drivers/i2c/busses/i2c-isa.c | 1 + drivers/i2c/busses/i2c-ixp2000.c | 2 +- drivers/i2c/busses/i2c-ixp4xx.c | 2 +- drivers/i2c/busses/i2c-mpc.c | 2 ++ drivers/i2c/busses/i2c-mv64xxx.c | 2 ++ drivers/i2c/busses/i2c-pxa.c | 1 + drivers/i2c/busses/i2c-s3c2410.c | 2 +- drivers/i2c/chips/isp1301_omap.c | 2 +- drivers/i2c/i2c-core.c | 1 + drivers/i2c/i2c-dev.c | 1 + drivers/input/keyboard/corgikbd.c | 2 +- drivers/input/keyboard/spitzkbd.c | 2 +- drivers/input/serio/ct82c710.c | 1 + drivers/input/serio/i8042.c | 1 + drivers/input/serio/maceps2.c | 2 +- drivers/input/serio/q40kbd.c | 1 + drivers/input/serio/rpckbd.c | 1 + drivers/input/touchscreen/corgi_ts.c | 2 +- drivers/mfd/mcp-sa11x0.c | 2 +- drivers/misc/hdpuftrs/hdpu_cpustate.c | 2 +- drivers/misc/hdpuftrs/hdpu_nexus.c | 2 +- drivers/mmc/pxamci.c | 2 +- drivers/mmc/wbsd.c | 2 +- drivers/mtd/maps/bast-flash.c | 2 +- drivers/mtd/maps/integrator-flash.c | 2 +- drivers/mtd/maps/ixp2000.c | 2 +- drivers/mtd/maps/ixp4xx.c | 2 +- drivers/mtd/maps/omap_nor.c | 2 +- drivers/mtd/maps/plat-ram.c | 2 +- drivers/mtd/maps/sa1100-flash.c | 2 +- drivers/mtd/nand/s3c2410.c | 2 +- drivers/net/depca.c | 2 +- drivers/net/dm9000.c | 1 + drivers/net/gianfar.c | 2 +- drivers/net/gianfar_mii.c | 1 + drivers/net/irda/pxaficp_ir.c | 1 + drivers/net/irda/sa1100_ir.c | 2 +- drivers/net/irda/smsc-ircc2.c | 1 + drivers/net/jazzsonic.c | 2 +- drivers/net/macsonic.c | 2 +- drivers/net/mipsnet.c | 1 + drivers/net/mv643xx_eth.c | 2 ++ drivers/net/smc91x.c | 2 +- drivers/net/tokenring/proteon.c | 1 + drivers/net/tokenring/skisa.c | 1 + drivers/pcmcia/au1000_generic.c | 2 +- drivers/pcmcia/hd64465_ss.c | 2 +- drivers/pcmcia/i82365.c | 2 +- drivers/pcmcia/m32r_cfc.c | 2 +- drivers/pcmcia/m32r_pcc.c | 2 +- drivers/pcmcia/omap_cf.c | 2 +- drivers/pcmcia/pxa2xx_base.c | 1 + drivers/pcmcia/pxa2xx_mainstone.c | 2 +- drivers/pcmcia/pxa2xx_sharpsl.c | 2 +- drivers/pcmcia/sa1100_generic.c | 1 + drivers/pcmcia/tcic.c | 2 +- drivers/pcmcia/vrc4171_card.c | 1 + drivers/scsi/hosts.c | 1 + drivers/serial/8250.c | 2 +- drivers/serial/imx.c | 2 +- drivers/serial/mpc52xx_uart.c | 2 +- drivers/serial/mpsc.c | 2 ++ drivers/serial/pxa.c | 2 +- drivers/serial/s3c2410.c | 2 +- drivers/serial/sa1100.c | 2 +- drivers/serial/vr41xx_siu.c | 2 +- drivers/usb/gadget/dummy_hcd.c | 2 +- drivers/usb/gadget/lh7a40x_udc.c | 2 ++ drivers/usb/gadget/omap_udc.c | 2 +- drivers/usb/gadget/pxa2xx_udc.c | 2 +- drivers/usb/host/isp116x-hcd.c | 1 + drivers/usb/host/ohci-au1xxx.c | 2 ++ drivers/usb/host/ohci-lh7a404.c | 2 ++ drivers/usb/host/ohci-omap.c | 2 ++ drivers/usb/host/ohci-ppc-soc.c | 2 ++ drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 2 ++ drivers/usb/host/sl811-hcd.c | 1 + drivers/usb/host/sl811_cs.c | 1 + drivers/video/acornfb.c | 2 +- drivers/video/arcfb.c | 1 + drivers/video/backlight/corgi_bl.c | 2 +- drivers/video/dnfb.c | 2 ++ drivers/video/epson1355fb.c | 2 ++ drivers/video/gbefb.c | 2 +- drivers/video/imxfb.c | 2 +- drivers/video/pxafb.c | 2 +- drivers/video/q40fb.c | 1 + drivers/video/s1d13xxxfb.c | 2 +- drivers/video/s3c2410fb.c | 1 + drivers/video/sa1100fb.c | 2 +- drivers/video/sgivwfb.c | 2 ++ drivers/video/vesafb.c | 2 ++ drivers/video/vfb.c | 2 ++ drivers/video/w100fb.c | 2 +- include/asm-ppc/ppc_sys.h | 2 +- include/linux/device.h | 26 ------------------------ include/linux/serial_8250.h | 2 +- sound/arm/pxa2xx-ac97.c | 2 +- sound/core/init.c | 2 ++ 198 files changed, 214 insertions(+), 158 deletions(-) diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 5cdb4122f057..ad55680726ed 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 21e2a518ad3a..174aa86ee816 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index e8356b76d7c6..68b06d16f253 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -11,7 +11,7 @@ * */ -#include +#include #include #include diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 0c53dab80905..4e706d9ad368 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index db9078ad008c..d75c8221d2a5 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index cb14b0682cef..60e2361e98e8 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -22,7 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include +#include #include #include #include diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 4cbdc1fe04b1..708e1b3faa14 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index f368b85f0447..1f9061ca7ef4 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index aa34c58b96c4..93f7ccb22c27 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index bb5091223b63..80770233b8d4 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index a2533c3ab42f..53f60614498b 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 9aa54de44740..643f5e1c3d93 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 8b4a839b6279..05dfcb48c2b6 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index fee1d7b73503..b21249908ae4 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 6c396447c4e0..f3c687cf0071 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index a20eabc132b0..4eb962fdb3a8 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index d46a70063b0c..4ee6bd8a50b8 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 2798613696fa..fc824361430d 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index fd9183ff2ed5..a2eac853b2da 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index d904e643f5ec..c851c2e4dfcb 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 21103df50415..a88524e7c315 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 2ba26e239108..354b157acb3a 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index bf30b1acda0b..3f018b296861 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index e8b3981444cd..3c5d901efeaa 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 60c8b9d8bb9c..247147f29b93 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c index 370df113dc06..54162ba95414 100644 --- a/arch/arm/mach-pxa/corgi_lcd.c +++ b/arch/arm/mach-pxa/corgi_lcd.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 136c269db0b7..591e5f32dbec 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 3248bc9b9495..afd5063b0ebe 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 01a83ab09ac3..7de159e2ab42 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index beccf455f796..1f6857d7747d 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index a48c64026e1f..887a8cb7b721 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -14,7 +14,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index f25638810017..86326307ab9f 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -16,7 +16,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 09a5d593f04b..c722a9a91fcc 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index d0ab428c2d7d..4182ddf330da 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index 8b3d5dc35de5..82e8253b1fa0 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c index ca366e9e264d..687fe371369d 100644 --- a/arch/arm/mach-s3c2410/cpu.c +++ b/arch/arm/mach-s3c2410/cpu.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 08bc7d95a45d..f58406e6ef5a 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h index d6328f96728b..52c4bab5c761 100644 --- a/arch/arm/mach-s3c2410/devs.h +++ b/arch/arm/mach-s3c2410/devs.h @@ -15,6 +15,7 @@ * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv */ #include +#include extern struct platform_device *s3c24xx_uart_devs[]; diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 5ae80f4e3e67..8390b685c2b6 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index c1b5c63ec24a..0b71c896bbd1 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 7efeaaad2361..0aa8760598f7 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 5c0f2b091f95..378d640ab00b 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c index c22f8216032d..42b0eeff2e0f 100644 --- a/arch/arm/mach-s3c2410/mach-nexcoder.c +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index ad1459e402e2..a2eb9ed48fcd 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 22d9e070fd68..8f2a90bf940b 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 2eda55a6b678..2c91965ee1c8 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 6950e61b7914..d666c621ad06 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index a8bf5ec82602..0a2013a76549 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c index 833fa36bce05..4d63e7133b48 100644 --- a/arch/arm/mach-s3c2410/s3c2440.c +++ b/arch/arm/mach-s3c2410/s3c2440.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index c92cebff7f8e..edccd5eb06be 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 23cb74885275..508593722bc7 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 7fd6e29c36b7..522abc036d3a 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 93619497779c..976380bde417 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 9c363bfcf310..9fb65cffa578 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 052e4caedb89..69f1970646c6 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index e17b58fb9c9c..58c18f9e9b7b 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index cfb6658e5cdf..439ddc9b06d6 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 7e4bdd07f4af..a1ca46630dda 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index 14a836d7ac25..205e2d0b826d 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index 708634b685e4..cb76916b014d 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index 4e709809efc5..501d798cf050 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index a1d801598aa4..7f2db5bfd626 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index a76412e883e8..9c79341a7b45 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index d7b7ec6d30f8..1fbb140854e7 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 0776b2db5641..3c778d0f58a6 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -7,7 +7,7 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#include +#include #include #include #include diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c index 4712de8ff80f..65ac0b9c2d05 100644 --- a/arch/ppc/platforms/4xx/ibm440ep.c +++ b/arch/ppc/platforms/4xx/ibm440ep.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c index d90627b68faa..7e33bb635443 100644 --- a/arch/ppc/platforms/4xx/ibmstb4.c +++ b/arch/ppc/platforms/4xx/ibmstb4.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c index bee8b4ac8afd..611ac861804d 100644 --- a/arch/ppc/platforms/4xx/redwood5.c +++ b/arch/ppc/platforms/4xx/redwood5.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c index 8b1012994dfc..b13116691289 100644 --- a/arch/ppc/platforms/4xx/redwood6.c +++ b/arch/ppc/platforms/4xx/redwood6.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c index cad5bfa153b2..d1af11c73ea1 100644 --- a/arch/ppc/platforms/chrp_pegasos_eth.c +++ b/arch/ppc/platforms/chrp_pegasos_eth.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c index f64ac2acb603..6ca7bcac9474 100644 --- a/arch/ppc/platforms/cpci690.c +++ b/arch/ppc/platforms/cpci690.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c index aa50637a5cfb..32358b3fb236 100644 --- a/arch/ppc/platforms/ev64260.c +++ b/arch/ppc/platforms/ev64260.c @@ -33,6 +33,7 @@ #include #include #include +#include #if !defined(CONFIG_SERIAL_MPSC_CONSOLE) #include #include diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c index 9811a8a52c25..4e6cc64b3efd 100644 --- a/arch/ppc/platforms/ev64360.c +++ b/arch/ppc/platforms/ev64360.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_BOOTIMG #include #endif diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c index ff3796860123..0f07e963de3c 100644 --- a/arch/ppc/platforms/hdpu.c +++ b/arch/ppc/platforms/hdpu.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index 2b53afae0e9c..beb617141456 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef CONFIG_BOOTIMG #include #endif diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 0376c8cff5d1..7e65b7f1f626 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c index ad5182efca1d..da3c74bfdc92 100644 --- a/arch/ppc/syslib/mpc52xx_devices.c +++ b/arch/ppc/syslib/mpc52xx_devices.c @@ -15,6 +15,7 @@ #include #include +#include #include #include diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 4849850a59ed..1227521c0da2 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c index 1d3869768f96..61668aad86e2 100644 --- a/arch/ppc/syslib/pq2_devices.c +++ b/arch/ppc/syslib/pq2_devices.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index c18919941ec0..1c1d65fb12df 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 1495007bf6c0..721e2601a75d 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -20,6 +20,7 @@ #include "linux/ctype.h" #include "linux/bootmem.h" #include "linux/ethtool.h" +#include "linux/platform_device.h" #include "asm/uaccess.h" #include "user_util.h" #include "kern_util.h" diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f73134333f64..b2c86257b0f8 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -35,6 +35,7 @@ #include "linux/blkpg.h" #include "linux/genhd.h" #include "linux/spinlock.h" +#include "linux/platform_device.h" #include "asm/segment.h" #include "asm/uaccess.h" #include "asm/irq.h" diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 498d7dced1f4..0682ffd38175 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -33,6 +33,7 @@ #include #include #include +#include #include diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 75ce8711bca5..95f2af322c8f 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -10,7 +10,7 @@ * information. */ -#include +#include #include #include #include diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 00895477155e..5eadbb9d4d71 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -177,7 +177,7 @@ static int print_unex = 1; #include #include #include -#include +#include #include /* for invalidate_buffers() */ /* diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c index 887b8b2d7882..d724c0de4f28 100644 --- a/drivers/char/s3c2410-rtc.c +++ b/drivers/char/s3c2410-rtc.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index f86c15587238..d05067dcea01 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index eb7058cbf015..24355b23b2ca 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include #include diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 683278bc5241..94641085faf8 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include #include diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c index a6dbe4da030c..5e3292df69d8 100644 --- a/drivers/char/vr41xx_rtc.c +++ b/drivers/char/vr41xx_rtc.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include #include diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c index 75ca84ed4adf..47a5f6ab4879 100644 --- a/drivers/char/watchdog/mpcore_wdt.c +++ b/drivers/char/watchdog/mpcore_wdt.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c index 6d3ff0836c44..04e0d7e9680d 100644 --- a/drivers/char/watchdog/mv64x60_wdt.c +++ b/drivers/char/watchdog/mv64x60_wdt.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index b732020acadb..e7e20a6d64b0 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c index 15677f20bd85..0f97a0cb0ff4 100644 --- a/drivers/eisa/virtual_root.c +++ b/drivers/eisa/virtual_root.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 955537fe9958..8ed6ddbb9c5d 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -20,7 +20,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 4f4ba9b6d182..125929c9048f 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 0015da5668a1..1e5dfc7805e2 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 9888fae1f37a..13752bcb2afd 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 4fdc02411609..03672c9ca409 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -38,6 +38,7 @@ #include #include #include +#include static u32 isa_func(struct i2c_adapter *adapter); diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 42016ee6ef13..64552a376f2d 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 69303ab65e04..cc652c350814 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 8491633005b8..65b939a059e9 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -19,6 +19,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index d0d2a6f1386e..6b48027b2ee3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -17,6 +17,8 @@ #include #include #include +#include + #include /* Register defines */ diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 44b595d90a4a..67ccbea24ba4 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 6ced28e90070..a1268e534254 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index eaa4742e04fa..9dbb72fffbe2 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 02e335a04f09..82ea1b7ec914 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index ea14c8f1c82b..8af0bd1424d2 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -34,6 +34,7 @@ #include #include #include +#include #include static struct i2c_client i2cdev_client_template; diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 3210d298b3bc..d00d14bb637a 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -12,7 +12,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index cee9c734a048..0fa38a559cdf 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -12,7 +12,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index dd0f5bd90241..4da6c86b5d76 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -37,6 +37,7 @@ #include #include #include +#include #include diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 4bc40f159996..01e186422021 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index 9880fc145d90..d857f7081adb 100644 --- a/drivers/input/serio/maceps2.c +++ b/drivers/input/serio/maceps2.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 46093c507988..b44d255596c2 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 106f5eefd89a..52c49258f8a4 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 0ba3e6562bff..15e88eeae8d6 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -11,7 +11,7 @@ #include -#include +#include #include #include #include diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 720e7a326308..7daa0ed7331c 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 46de5c940555..9c4dd682ac74 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index c203b27269ea..165f3405df27 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -21,7 +21,7 @@ #include #include -#include +#include static int hdpu_nexus_probe(struct device *ddev); static int hdpu_nexus_remove(struct device *ddev); diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index 8eba373d42d7..4da4a98bd590 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 3ace875decc4..942668e93a74 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c index 0ba0ff7d43b9..5f248ebe68e0 100644 --- a/drivers/mtd/maps/bast-flash.c +++ b/drivers/mtd/maps/bast-flash.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index e39a98a0171c..d14a0185b8f4 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index a9f86c7fbd52..6815baee89d7 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 3fcc32884074..06e1c7fffed3 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index b17bca657daf..9c9f4116e50a 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c @@ -30,7 +30,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #include #include #include diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 118b04544cad..e751e05fcc65 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 6a8e0caf9fdc..66b4c2780adc 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index b47ebcb31e0f..bf2325df80c7 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/net/depca.c b/drivers/net/depca.c index c4aa5fe2840e..4d26e5e7d18b 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -254,7 +254,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index abce1f730d00..c0af6fb1fbba 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index ae5a2ed3b264..962580f2c4ab 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -81,7 +81,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index 1eca1dbca7f1..5a74d3d3dbe1 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index aef80f5e7c9c..9571145c2090 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 06883309916d..76e0b9fb5e96 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index bbac720cca63..424515d35932 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 8423cb6875f0..a74a5cfaf5bc 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 405e18365ede..e9c999d7eb39 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index f79f7ee72ab8..bbffb585b3b3 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 25c9a99c377b..6fe948c10e72 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -39,6 +39,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 0ddaa611cc61..901c960d342a 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -77,7 +77,7 @@ static const char version[] = #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index eb1423ede75c..d04c918ebef8 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -29,6 +29,7 @@ static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n #include #include #include +#include #include #include diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index 3c7c66204f74..72cf708396be 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c @@ -36,6 +36,7 @@ static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n"; #include #include #include +#include #include #include diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index d90a634cebf5..f591839ab9cd 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index b57a0b98b4d6..561706ba4499 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 4a41f67d185d..7ce455d01cc9 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index c6ed70ea4812..2c22b4b3619d 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 3397ff28de6a..356a6fb416a1 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 2558c3cc91ec..47b5ade95bde 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index c2a12d53f6c7..7fa18fb814bc 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index bbe69b07ce50..5209d8c7764f 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index a1178a600e3c..b54a8b8c0fca 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index b768fa81f043..122fb29b1e34 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index f158b67f6610..e31263864377 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 3d2dca675e02..38a028c725d4 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -24,6 +24,7 @@ #include #include #include +#include #include diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index f24d84538fd5..71dd1ebbe58f 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index afb7ddf200e0..f47d2c454e33 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 5b3933b0c997..b9a1f523c9a8 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 8a79968f8ce1..0dd08a09e7e6 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -45,7 +45,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index efe79b1fd431..f4c709bc464b 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -52,6 +52,8 @@ * 4) AFAICT, hardware flow control isn't supported by the controller --MAG. */ +#include + #include "mpsc.h" /* diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 8cc4cedadd99..16b2f9417af9 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 06a17dff1a73..036792328d49 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -63,7 +63,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index c4a789e6af44..ed618cc7ae96 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 2b623ab0e36e..01696b3e3f61 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -26,7 +26,7 @@ #endif #include -#include +#include #include #include #include diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 02106bebd5c1..975ace3f5b1e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -50,7 +50,7 @@ #include #include #include - +#include #include #include diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 9b3673904daf..bc6269f10cbb 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -21,6 +21,8 @@ * */ +#include + #include "lh7a40x_udc.h" //#define DEBUG printk diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 41c96b0afbb3..387692a3611e 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index f83a9262f953..ee9cd7869d92 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index ddb8fc591466..f9c3f5b8dd1c 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index a277e258eb6c..f0c78cf14b6c 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -18,6 +18,8 @@ * This file is licenced under the GPL. */ +#include + #include #define USBH_ENABLE_BE (1<<0) diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 238fa4ade615..336c766c6e29 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -16,6 +16,8 @@ * This file is licenced under the GPL. */ +#include + #include diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 45efeed1fcc3..277bcb902d3b 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -14,6 +14,8 @@ * This file is licenced under the GPL. */ +#include + #include #include #include diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 4832e57ae579..92cf6f4a1374 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -14,6 +14,8 @@ * This file is licenced under the GPL. */ +#include + /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index d287dcccd415..5181999c56c9 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -19,7 +19,7 @@ * This file is licenced under the GPL. */ -#include +#include #include #include #include diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index fab420a2ce71..ee1fc605b402 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -19,6 +19,8 @@ * This file is licenced under the GPL. */ +#include + #include #include #include diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 40169d9cf2b1..5607c0ae6835 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 38aebe361ca1..e73faf831b24 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index f02965f39501..9b6a39348f81 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index d28457e0c063..126daff1c848 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -47,6 +47,7 @@ #include #include #include +#include #include diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 1991fdb32dfb..4867498f68e8 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c index 1dbb82dca40b..1785686a7f11 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/dnfb.c @@ -6,6 +6,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 116e808d71cd..7363d0b25fdf 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -54,6 +54,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index d3c1922cb13a..fc0a1beef968 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 0b9301facbd3..64d9bcc38da3 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 6206da9dd5da..efd9333b05c2 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index 162012bb9264..8416b2e2b501 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index cb2f7a1de947..f4437430dc5f 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 3862d3cb1fb2..3cef90456a4b 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 78e5f194b0df..3d35b28aaac7 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -173,7 +173,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 8413907b379a..cf5106eab2d5 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -18,6 +18,8 @@ #include #include #include +#include + #include #include diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index b1243da55fc5..3cc23106641d 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -19,6 +19,8 @@ #include #include #include +#include + #include